1
0
mirror of https://github.com/KDE/krfb synced 2026-07-02 00:01:18 -07:00

Compare commits

...

146 Commits

Author SHA1 Message Date
l10n daemon script
7968886f15 GIT_SILENT made messages (after extraction) 2017-11-04 05:24:10 +01:00
l10n daemon script
786fb279f1 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-10-11 10:17:37 +02:00
l10n daemon script
c0dbc82627 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-09-04 06:13:03 +02:00
l10n daemon script
4f0ca5a73d GIT_SILENT made messages (after extraction) 2017-09-04 05:25:18 +02:00
l10n daemon script
eb6bc85a6a GIT_SILENT made messages (after extraction) 2017-08-10 05:32:06 +02:00
Alexey Min
69aa649d9c Add settings page allowing user to change framebuffer plugin
Added a new page to config dialog: "Screen capture", allowing to choose a framebuffer plugin.
Added a brief description about xcb and qt plugins.
Changed an icon for first tab "Network" to more appropriate one.
Code is prepared to expect "x11" as preferredFramebufferPlugin and automatically change this setting to "xcb".
Do not hardcode possible list of framebuffer plugins in combobox, but instead find actual available plugins at runtime.
If preferred plugin has changed in settings, inform user that krfb needs to be restarted to apply changes.

Differential Revision: https://phabricator.kde.org/D6319
2017-08-08 05:34:56 +05:00
Luigi Toscano
1fb61059a7 Merge remote-tracking branch 'origin/Applications/17.04' 2017-07-15 15:28:38 +02:00
l10n daemon script
0689b72f38 GIT_SILENT made messages (after extraction) 2017-07-04 05:16:00 +02:00
l10n daemon script
4564c91b64 GIT_SILENT made messages (after extraction) 2017-07-04 03:06:55 +02:00
l10n daemon script
01ec550abf GIT_SILENT made messages (after extraction) 2017-07-01 03:13:36 +02:00
l10n daemon script
47c40225fd SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-06-20 05:48:45 +02:00
Albert Astals Cid
f131f7ddba Remove old X11 plugin
It wasn't being compiled anyway
2017-06-15 23:24:45 +02:00
Alexey Min
b2cb3e8204 Implement XCB framebuffer plugin (port from x11)
Previously used x11 plugin does not compile with Qt5, because Qt5 does
not use Xlib, it uses xcb. Rewrite screen capture plugin from Xlib to
xcb.

I made xcb libs compile required dependency, but availability of X
shared memory extension is checked at runtime. It is used to effectively
get image pixels data, instead of transfering 8Mb over the wire. Xdamage
is used to limit image getting operations only within actually changed
rectangles of screen.

BUG: 377998

Tested on single-monitor system and dual-monitor, where primary monitor
does not start at (0,0) coordinate. Image transfer works fine.
Dual-monitor only has problems with receiving mouse cursor position and
clicks, but this should be fixed outside of framebuffer plugin.

Differential Revision: https://phabricator.kde.org/D5211
2017-06-15 23:21:58 +02:00
l10n daemon script
c92ef2f230 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-06-11 04:37:36 +02:00
l10n daemon script
b2fe612ec4 GIT_SILENT made messages (after extraction) 2017-06-11 03:09:33 +02:00
Christoph Feck
831ec6c9be Fix SPDX license ID 2017-06-09 03:57:04 +02:00
l10n daemon script
4b01a1cac7 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-04-23 04:05:02 +02:00
l10n daemon script
09b643f5cb GIT_SILENT made messages (after extraction) 2017-04-23 02:49:04 +02:00
l10n daemon script
77ef270323 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-04-14 03:58:43 +02:00
l10n daemon script
e487c45f34 GIT_SILENT made messages (after extraction) 2017-04-12 02:47:34 +02:00
l10n daemon script
2a60739a16 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-04-09 05:12:08 +02:00
l10n daemon script
8eecd9097e SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-04-09 04:03:05 +02:00
l10n daemon script
e3b9a0b30a GIT_SILENT made messages (after extraction) 2017-04-03 04:24:46 +02:00
Albert Astals Cid
6561a9db15 Merge remote-tracking branch 'origin/Applications/17.04' 2017-03-24 00:21:50 +01:00
Albert Astals Cid
c0ceb8a83d Set default framebuffer plugin to "qt" instead of "x11"
Make default "qt" framebuffer plugin instead of "x11". Workaround for bug https://bugs.kde.org/show_bug.cgi?id=356782
Not a proper fix, ideally "x11" plugin needs to be fixed.

REVIEW: 129721
BUGS: 356782
2017-03-24 00:20:12 +01:00
Albert Astals Cid
f107a73d28 Merge remote-tracking branch 'origin/Applications/17.04' 2017-03-24 00:12:20 +01:00
Alexey Min
4974154cc3 Qt framebuffer plugin: Do not use deprecated QPixmap::grabWindow(), use QScreen::grabWindow() instead
REVIEW: 129722
2017-03-24 00:11:49 +01:00
l10n daemon script
05dc124c8b GIT_SILENT made messages (after extraction) 2017-03-23 04:53:39 +01:00
l10n daemon script
b960bb4ba4 GIT_SILENT made messages (after extraction) 2017-03-20 02:42:32 +01:00
Adriaan de Groot
f702422c9d Drop duplicate linking to libvncserver.
Summary:
The duplicate link may also be missing necessary -L flags,
so it causes linker errors when libvncserver is installed
in unusual places (while ${LIBVNCSERVER_LIBRARIES} DTRT).

Reviewers: sitter, apol, ltoscano, heikobecker

Reviewed By: sitter

Differential Revision: https://phabricator.kde.org/D5018
2017-03-12 22:31:30 +01:00
l10n daemon script
27e48f1114 GIT_SILENT made messages (after extraction) 2017-02-26 04:01:20 +01:00
l10n daemon script
9e77d1f5ac SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-02-23 06:16:56 +01:00
l10n daemon script
c12697e23f GIT_SILENT made messages (after extraction) 2017-02-23 04:14:39 +01:00
l10n daemon script
3ce5047a6f GIT_SILENT made messages (after extraction) 2017-02-19 03:57:26 +01:00
l10n daemon script
60b6f7b86b GIT_SILENT made messages (after extraction) 2017-02-14 09:13:43 +01:00
l10n daemon script
b1f1a2f8d6 GIT_SILENT made messages (after extraction) 2017-02-12 03:54:12 +01:00
l10n daemon script
ee863548d9 GIT_SILENT made messages (after extraction) 2017-02-09 03:58:33 +01:00
l10n daemon script
ccc9ed069f GIT_SILENT made messages (after extraction) 2017-02-07 08:59:20 +01:00
l10n daemon script
8c7138b592 GIT_SILENT made messages (after extraction) 2017-02-05 04:04:34 +01:00
Luigi Toscano
364cee9ba2 It is not just for a specific type of desktop 2017-02-04 16:33:57 +01:00
l10n daemon script
215d20c004 GIT_SILENT made messages (after extraction) 2017-02-04 04:00:01 +01:00
l10n daemon script
315b401227 GIT_SILENT made messages (after extraction) 2017-02-03 04:13:35 +01:00
l10n daemon script
9289a22d8a SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-02-02 05:57:39 +01:00
Harald Sitter
d529e22430 add appdata 2017-02-01 19:32:55 +01:00
Harald Sitter
b6fbb67af1 Merge branch 'Applications/16.12' 2017-02-01 19:13:02 +01:00
Harald Sitter
da4de72d55 set a comment
appstream uses Comment for a summary when no appdata is present. without
a comment/summary no appdata will be available at all rendering the app
unavailable in software stores

recycle genericname to avoid excess l10n work
2017-02-01 19:12:59 +01:00
l10n daemon script
b3e1624469 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-01-28 08:14:37 +01:00
l10n daemon script
aa80d3915d SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-01-28 06:35:16 +01:00
Heiko Becker
0b210563cb Merge remote-tracking branch 'origin/Applications/16.12' 2017-01-11 20:21:12 +01:00
Heiko Becker
b4713d4755 Silence CMake policy CMP0063 warning
...by adding the NO_POLICY_SCOPE flag as recommended by ECM's
documentation.
2017-01-11 20:18:38 +01:00
l10n daemon script
34d9387aa0 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-01-05 05:56:47 +01:00
l10n daemon script
eb7caf8594 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-01-04 06:14:48 +01:00
l10n daemon script
e761ee832e SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2017-01-03 12:34:42 +01:00
l10n daemon script
699d7f9a27 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2016-12-20 13:09:16 +01:00
l10n daemon script
43083c52dc SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2016-12-17 05:50:49 +01:00
l10n daemon script
903692c299 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2016-12-02 05:49:11 +01:00
l10n daemon script
2885bf2c5a SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2016-12-02 04:33:40 +01:00
l10n daemon script
6544fd56e9 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2016-11-30 04:27:39 +01:00
l10n daemon script
3fc2398707 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2016-11-25 05:01:57 +01:00
l10n daemon script
c1efd7158f SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2016-11-23 04:21:36 +01:00
l10n daemon script
cbc43a390f SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2016-11-22 06:10:53 +01:00
l10n daemon script
631d3c85ac SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2016-11-15 10:19:57 +00:00
l10n daemon script
ae15751847 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2016-10-24 09:34:05 +00:00
Tomaz Canabrava
f1a3e2b31c Needed to simplify the creation of reviews via the rbt tool.
Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
2016-10-10 16:25:17 +02:00
l10n daemon script
b95a5b285d SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2016-09-14 09:19:50 +00:00
l10n daemon script
0ee5738bf5 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2016-09-09 09:26:52 +00:00
Tomaz Canabrava
5195783757 Fix build by undefining the max macro
The max macro was being defined in the c++ namespace,
conflicting with the max C++ function call, breaking the
build.

Signed-off-by: Tomaz Canabrava <tomaz.canabrava@gmail.com>
2016-08-19 12:43:24 -03:00
Yuri Chornoivan
1b6702167d Fix minor glitches 2016-07-29 19:45:30 +03:00
Burkhard Lück
8b7fcb023d Update KRFB docbook to 16.08
Update to reflect changes in
https://git.reviewboard.kde.org/r/115499
Krfb modified to move away from invite-model, and modeled as a service that can be started/stopped.

remove unused entities, pngs + appendix
new screenshots
remove krfb/ui/invitewidget.ui - unused
REVIEW:128528
2016-07-29 06:59:12 +02:00
l10n daemon script
65595722bd SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2016-01-23 10:35:57 +00:00
l10n daemon script
916ffb525a SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2016-01-07 10:10:04 +00:00
Albert Astals Cid
ee5cb9eaf5 Merge remote-tracking branch 'origin/Applications/15.12' 2016-01-07 00:33:40 +01:00
Albert Astals Cid
ecb9fb8ee0 Make translations work
Call KLocalizedString::setApplicationDomain
2016-01-07 00:31:40 +01:00
Albert Astals Cid
2c317584b9 Remove useless I18N_NOOP 2016-01-07 00:30:12 +01:00
l10n daemon script
c98d1d7676 SVN_SILENT made messages (.desktop file) 2015-12-30 12:15:07 +00:00
l10n daemon script
def5195e63 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-12-30 09:33:48 +00:00
l10n daemon script
510e5f8d52 SVN_SILENT made messages (.desktop file) 2015-12-29 13:51:44 +00:00
l10n daemon script
964386e2a6 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-12-29 11:26:11 +00:00
l10n daemon script
0d500c00ba SVN_SILENT made messages (.desktop file) 2015-12-17 12:27:46 +00:00
l10n daemon script
07439f6408 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-12-17 09:32:43 +00:00
l10n daemon script
aa0e358136 SVN_SILENT made messages (.desktop file) 2015-12-13 11:50:46 +00:00
l10n daemon script
7c175bbc6e SVN_SILENT made messages (.desktop file) 2015-12-09 12:00:52 +00:00
l10n daemon script
405bec30f6 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-12-09 09:08:00 +00:00
l10n daemon script
464cbd8573 SVN_SILENT made messages (.desktop file) 2015-11-26 18:11:03 +00:00
l10n daemon script
c1904c41c7 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-11-26 15:56:42 +00:00
Jeremy Whiting
17752eba7c Merge branch 'Applications/15.12' 2015-11-23 12:22:39 -07:00
Jeremy Whiting
f4b4fe0f34 Fix launching the application from KDE menu and krunner
Patch from Antonio Rojas <arojas@archlinux.org>
REVIEW:126142
BUG:355776
2015-11-23 12:20:59 -07:00
l10n daemon script
ac6f4ca3ed SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-11-17 13:00:54 +00:00
l10n daemon script
d2d49abf23 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-11-11 10:33:20 +00:00
l10n daemon script
396e277113 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-11-07 21:16:29 +00:00
l10n daemon script
ab7ed1c006 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-11-04 17:14:10 +00:00
l10n daemon script
1c9db8798e SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-11-03 15:56:52 +00:00
l10n daemon script
a2b1c5e0b5 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-11-02 11:08:45 +00:00
l10n daemon script
f95fafe5a7 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-11-01 10:43:24 +00:00
l10n daemon script
3a9f58f12e SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-10-25 10:39:56 +00:00
l10n daemon script
74b4d19a35 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-10-18 11:02:35 +00:00
l10n daemon script
c0f1b1ebb4 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-10-17 12:43:21 +00:00
l10n daemon script
d306c6c73d SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-10-16 10:30:41 +00:00
Rohan Garg
8d1abb3a8f Fix build 2015-10-15 15:51:31 +02:00
Rohan Garg
f15490d58a Merge branch 'master' into frameworks 2015-10-15 15:38:37 +02:00
Rohan Garg
c83182f8d3 Allow krfb to store the fact that it was enabled the last time it was started 2015-10-15 15:36:38 +02:00
Rohan Garg
e0dc5b3a51 Allow krfb to start minimized, this is useful when autostarting krfb. 2015-10-15 15:36:19 +02:00
Rohan Garg
5948ee69c2 Allow for krfb to be started without a wallet.
krfb will store obscured passwords in a regular text
files in this mode.
2015-10-15 15:35:21 +02:00
Albert Astals Cid
e443b13227 virtual -> override
And a class that is really a struct
2015-10-10 13:27:49 +02:00
Albert Astals Cid
ff2d0d999d stop calls are always with true, remove param 2015-10-10 13:16:13 +02:00
Albert Astals Cid
0b9ed26137 Use new connect syntax
And a few warning fixes
2015-10-10 13:12:07 +02:00
Jeremy Whiting
05b6105be8 Fix connections to QDialog subclass signals. 2015-10-10 05:07:43 -06:00
Jeremy Whiting
6d5e2bc356 Remove telepathy tubes and contact list support. 2015-09-17 17:44:07 -06:00
Jeremy Whiting
10176b9e01 Port from KServiceTypeTrader, etc. to new json style plugins.
Finish porting away from KDELibs4Support.
Changed preferred framebuffer config to use plugin ids defaulting to x11.
2015-09-16 20:55:30 -06:00
Jeremy Whiting
9bb8e28eeb Remove unneccesarry TODO comment and commented out code. 2015-09-11 13:51:52 -06:00
Jeremy Whiting
56e1804b23 Port from K4AboutData to KAboutData, KCmdLineArgs to QCmdLineArgs and add about dialog 2015-09-11 13:47:10 -06:00
Jeremy Whiting
82707732d3 Port from KDialog to QDialog and KPushButton to QPushButton. 2015-09-11 13:13:13 -06:00
Jeremy Whiting
e63fb3f0b1 Port away from KLocale and kdemacros 2015-09-11 13:01:02 -06:00
Jeremy Whiting
a45aa4a16b Port from KIcon to QIcon. 2015-09-11 12:32:54 -06:00
Jeremy Whiting
535e474cbd Reenable finding telepathyqt and ktp and remove our local FindKTp.cmake. 2015-09-10 14:27:07 -06:00
Jeremy Whiting
2448d9e944 Update docbook to 4.5 dtd. 2015-09-09 17:52:54 -06:00
Jeremy Whiting
74683e0a02 Rename .desktop to org.kde.krfb.desktop. 2015-09-09 17:50:57 -06:00
Jeremy Whiting
87f2742fcc Add feature_summary 2015-09-09 17:44:49 -06:00
Jeremy Whiting
6306bf85cf Initial port to Qt5/KF5.
Fixed FindLibVNCServer to use CheckStructHasMember.
Ported from kDebug to qDebug
Runs and seems to work, but probably missed some things.
2015-09-06 15:31:29 -06:00
David Faure
cb43be430c set cmake_min_req to match kdelibs policy and enable newer cmake policies 2015-07-29 08:34:24 +02:00
l10n daemon script
97beca4d9c SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2015-05-25 04:27:43 +00:00
l10n daemon script
ad800f12fc SVN_SILENT made messages (.desktop file) 2015-02-21 04:45:26 +00:00
Albert Astals Cid
9db3ae6629 Merge remote-tracking branch 'origin/KDE/4.14'
Conflicts:
	libvncserver/lzoconf.h
	libvncserver/lzodefs.h
	libvncserver/minilzo.c
	libvncserver/minilzo.h
2014-09-11 00:49:42 +02:00
Jonathan Liu
b6b20c84e8 Fix crash on quit if KDE wallet subsystem is disabled
REVIEW: 120097
2014-09-11 00:47:46 +02:00
Martin T. H. Sandsmark
0bff5df104 Update LZO to version 2.07 in libvncserver.
Temporary fix for CVE-2014-4607 for 4.14. For next release we rely on
the external libvncserver.
2014-07-31 20:20:32 +02:00
Johannes Huber
1c85dc7d85 CVE-2014-4607: Unbundle libvncserver
http://seclists.org/oss-sec/2014/q2/676

REVIEW: 119548
2014-07-31 18:15:25 +02:00
l10n daemon script
83767fea93 SVN_SILENT made messages (.desktop file) 2014-07-25 05:40:37 +00:00
l10n daemon script
8597d3c4a7 SVN_SILENT made messages (.desktop file) 2014-07-24 04:53:26 +00:00
Pino Toscano
fd9f566d0b fixuifiles 2014-04-15 23:12:33 +02:00
Amandeep Singh
2eb0a2a9d2 Making main-widget flexible in size 2014-04-06 10:24:40 +05:30
Amandeep Singh
85e13b7908 Publish service on local network depending on config 2014-04-06 10:24:35 +05:30
Amandeep Singh
ad79d51e8b Fix: KRFB crashes when closed during pending connection 2014-04-06 10:24:29 +05:30
Amandeep Singh
a1de26dde7 Fixed dialog parents and Stopping server on delete 2014-04-06 10:24:25 +05:30
Amandeep Singh
f074491e60 Show KDE Telepathy contacts if available
Optional dependency on KTP. If available contacts with rfb capability
shown in list view.
2014-04-06 10:24:21 +05:30
Amandeep Singh
2e35cd2e08 Adding message dialogs to UI 2014-04-06 10:24:18 +05:30
Amandeep Singh
6eefee2677 Remove unused files 2014-04-06 10:23:52 +05:30
Amandeep Singh
e452d68f05 Add bidirectional text-clipboard support 2014-04-06 10:23:47 +05:30
Amandeep Singh
c558eaf9b6 Save password in KWallet & settings to config file
Fall back to config file if KWallet not available
2014-04-06 10:23:41 +05:30
Amandeep Singh
db5c2528cd Fix crash in krfb
Krfb crashes on quit, if any client is connected
due to a rfbClientConnectionGone call missing
2014-04-06 10:23:38 +05:30
Amandeep Singh
c87064a797 Prompt User only when client is authenticated
FIXED: Krfb prompts user about incoming connection before authentication
ADDED: Krfb prompts user depending upon password used by client
2014-04-06 10:23:34 +05:30
Amandeep Singh
c5c415c042 Unattended Access mode added
Remote user can connect without confirmation on
providing correct unattended mode password.
2014-04-06 10:23:30 +05:30
Amandeep Singh
f64abc21ce krfb moved away from invitation based model
-Allow user to start/stop the service as needeed
-Allow user to change & view password in main UI
-Legitimate incoming requests accepted
2014-04-06 10:23:26 +05:30
Amandeep Singh
f0714d9b30 rfbInitSockets returns only if socket is READY
TODO: Server not started, All Incoming requests will fail
2014-04-06 10:23:18 +05:30
Amandeep Singh
45edf9d0ed Removing Invitations related files
TODO: Server not started, All Incoming requests will fail
2014-04-06 10:23:15 +05:30
Amandeep Singh
7714a2a7f6 Adding new front end user interface
TODO: Server not started, All Incoming requests will fail
2014-04-06 10:23:11 +05:30
Amandeep Singh
debffc2e10 Krfb now runs as KUniqueApplication 2014-04-06 10:22:44 +05:30
137 changed files with 3101 additions and 32187 deletions

4
.reviewboardrc Normal file
View File

@@ -0,0 +1,4 @@
REPOSITORY = "git://anongit.kde.org/krfb"
REVIEWBOARD_URL = "https://git.reviewboard.kde.org"
TARGET_PEOPLE = "whiting"

View File

@@ -1,42 +1,66 @@
cmake_minimum_required(VERSION 2.8.12)
project(krfb)
if(NOT INSIDE_KDENETWORK)
message("Not building inside KDENetwork, loading KDE CMake Macros.")
include(FeatureSummary)
find_package(Qt5 REQUIRED COMPONENTS Core DBus Widgets X11Extras)
find_package(KDE4 REQUIRED)
find_package(ECM 1.7.0 NO_MODULE REQUIRED)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
include(KDE4Defaults)
include(MacroLibrary)
include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings NO_POLICY_SCOPE)
include(ECMInstallIcons)
include(ECMAddAppIcon)
include(CheckIncludeFile)
include(CheckIncludeFiles)
include(CheckSymbolExists)
include(CheckFunctionExists)
include(CheckLibraryExists)
include(CheckPrototypeExists)
include(CheckTypeSize)
find_package(KF5 REQUIRED COMPONENTS
I18n
Completion
Config
CoreAddons
Crash
DBusAddons
DNSSD
DocTools
Notifications
Wallet
WidgetsAddons
XmlGui
)
set(CMAKE_REQUIRED_DEFINITIONS ${_KDE4_PLATFORM_DEFINITIONS})
if(WIN32)
set(CMAKE_REQUIRED_LIBRARIES ${KDEWIN32_LIBRARIES})
set(CMAKE_REQUIRED_INCLUDES ${KDEWIN32_INCLUDES})
endif(WIN32)
add_definitions(${QT_DEFINITIONS} ${QT_QTDBUS_DEFINITIONS} ${KDE4_DEFINITIONS})
add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES})
endif(NOT INSIDE_KDENETWORK)
find_package(X11 REQUIRED)
macro_optional_find_package(TelepathyQt4)
macro_log_feature(TelepathyQt4_FOUND "telepathy-qt" "Telepathy Qt Bindings" "http://telepathy.freedesktop.org" FALSE "0.9" "Needed to build Telepathy Tubes support.")
find_package(XCB REQUIRED COMPONENTS
XCB
RENDER
SHAPE
XFIXES
DAMAGE
SHM
IMAGE
)
if(WIN32)
set(CMAKE_REQUIRED_LIBRARIES ${KDEWIN32_LIBRARIES})
set(CMAKE_REQUIRED_INCLUDES ${KDEWIN32_INCLUDES})
endif(WIN32)
add_definitions(${QT_DEFINITIONS} ${QT_QTDBUS_DEFINITIONS})
add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} )
set(CMAKE_MODULE_PATH
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules"
${CMAKE_MODULE_PATH}
)
find_package(LibVNCServer REQUIRED)
macro_bool_to_01(X11_Xdamage_FOUND HAVE_XDAMAGE)
macro_bool_to_01(X11_XShm_FOUND HAVE_XSHM)
include_directories ("${CMAKE_CURRENT_BINARY_DIR}/krfb"
"${CMAKE_CURRENT_SOURCE_DIR}/krfb"
"${CMAKE_CURRENT_SOURCE_DIR}/krfb/ui"
"${CMAKE_CURRENT_SOURCE_DIR}/libvncserver/"
"${CMAKE_CURRENT_BINARY_DIR}/libvncserver/"
)
if(Q_WS_X11)
@@ -45,11 +69,8 @@ if(Q_WS_X11)
endif(NOT X11_XTest_FOUND)
endif(Q_WS_X11)
add_subdirectory(libvncserver)
add_subdirectory(krfb)
add_subdirectory (framebuffers)
add_subdirectory(framebuffers)
add_subdirectory(doc)
if (NOT INSIDE_KDENETWORK)
macro_display_feature_log()
endif ()
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)

View File

@@ -0,0 +1,41 @@
# cmake macro to test LIBVNCSERVER LIB
# Copyright (c) 2006, Alessandro Praduroux <pradu@pradu.it>
# Copyright (c) 2007, Urs Wolfer <uwolfer @ kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
INCLUDE(CheckStructHasMember)
IF (LIBVNCSERVER_INCLUDE_DIR AND LIBVNCSERVER_LIBRARIES)
# Already in cache, be silent
SET(LIBVNCSERVER_FIND_QUIETLY TRUE)
ENDIF (LIBVNCSERVER_INCLUDE_DIR AND LIBVNCSERVER_LIBRARIES)
FIND_PATH(LIBVNCSERVER_INCLUDE_DIR rfb/rfb.h)
FIND_LIBRARY(LIBVNCSERVER_LIBRARIES NAMES vncserver libvncserver)
# libvncserver and libvncclient are in the same package, so it does
# not make sense to add a new cmake script for finding libvncclient.
# instead just find the libvncclient also in this file.
FIND_PATH(LIBVNCCLIENT_INCLUDE_DIR rfb/rfbclient.h)
FIND_LIBRARY(LIBVNCCLIENT_LIBRARIES NAMES vncclient libvncclient)
IF (LIBVNCSERVER_INCLUDE_DIR AND LIBVNCSERVER_LIBRARIES)
SET(CMAKE_REQUIRED_INCLUDES "${LIBVNCSERVER_INCLUDE_DIR}" "${CMAKE_REQUIRED_INCLUDES}")
CHECK_STRUCT_HAS_MEMBER("struct _rfbClient" GotXCutText rfb/rfbclient.h LIBVNCSERVER_FOUND)
ENDIF (LIBVNCSERVER_INCLUDE_DIR AND LIBVNCSERVER_LIBRARIES)
IF (LIBVNCSERVER_FOUND)
IF (NOT LIBVNCSERVER_FIND_QUIETLY)
MESSAGE(STATUS "Found LibVNCServer: ${LIBVNCSERVER_LIBRARIES}")
ENDIF (NOT LIBVNCSERVER_FIND_QUIETLY)
ELSE (LIBVNCSERVER_FOUND)
IF (LIBVNCSERVER_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could NOT find acceptable version of LibVNCServer (version 0.9 or later required).")
ENDIF (LIBVNCSERVER_FIND_REQUIRED)
ENDIF (LIBVNCSERVER_FOUND)
MARK_AS_ADVANCED(LIBVNCSERVER_INCLUDE_DIR LIBVNCSERVER_LIBRARIES)

View File

@@ -1,2 +1,2 @@
########### install files ###############
kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR krfb)
kdoctools_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR krfb)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

View File

@@ -1,22 +1,11 @@
<?xml version="1.0" ?>
<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN" "dtd/kdex.dtd" [
<!ENTITY kappname "&krfb;">
<!ENTITY package "kdenetwork">
<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN" "dtd/kdedbx45.dtd" [
<!ENTITY % addindex "IGNORE">
<!ENTITY % English "INCLUDE"> <!-- ONLY If you are writing non-English
original documentation, change
the language here -->
<!-- Do not define any other entities; instead, use the entities
from entities/general.entities and $LANG/user.entities. -->
<!ENTITY % English "INCLUDE">
]>
<!-- Based on kdoctemplate v0.9 January 10 2003 -->
<book id="krfb" lang="&language;">
<!-- This header contains all of the meta-information for the document such
as Authors, publish date, the abstract, and Keywords -->
<bookinfo>
<title>The &krfb; Handbook</title>
@@ -32,21 +21,11 @@ as Authors, publish date, the abstract, and Keywords -->
<year>2003</year>
<holder>&Brad.Hards;</holder>
</copyright>
<!-- Translators: put here the copyright notice of the translation -->
<legalnotice>&FDLNotice;</legalnotice>
<!-- Date and version information of the documentation
Don't forget to include this last date and this last revision number, we
need them for translation coordination !
Please respect the format of the date (YYYY-MM-DD) and of the version
(V.MM.LL), it could be used by automation scripts.
Do NOT change these in the translation. -->
<date>2013-06-19</date>
<releaseinfo>&kde; 4.11</releaseinfo>
<!-- Abstract about this handbook -->
<date>2016-07-25</date>
<releaseinfo>5.0 (Applications 16.08)</releaseinfo>
<abstract>
<para>
@@ -56,10 +35,6 @@ view or even control the desktop.
</para>
</abstract>
<!-- This is a set of Keywords for indexing by search engines.
Please at least include KDE, the KDE package it is in, the name
of your application, and a few relevant keywords. -->
<keywordset>
<keyword>KDE</keyword>
<keyword>kdenetwork</keyword>
@@ -75,23 +50,9 @@ Please at least include KDE, the KDE package it is in, the name
</bookinfo>
<!-- The contents of the documentation begin here. Label
each chapter so with the id attribute. This is necessary for two reasons: it
allows you to easily reference the chapter from other chapters of your
document, and if there is no ID, the name of the generated HTML files will vary
from time to time making it hard to manage for maintainers and for the CVS
system. Any chapter labelled (OPTIONAL) may be left out at the author's
discretion. Other chapters should not be left out in order to maintain a
consistent documentation style across all KDE apps. -->
<chapter id="introduction">
<title>Introduction</title>
<!-- The introduction chapter contains a brief introduction for the
application that explains what it does and where to report
problems. Basically a long version of the abstract. Don't include a
revision history. (see installation appendix comment) -->
<para>
&krfb; is a server application that allows you to share your current
session with a user on another machine, who can use a <acronym>VNC</acronym> client to
@@ -165,10 +126,8 @@ use &krfb; over other links, but performance is unlikely to be as good.
<chapter id="using-krfb">
<title>Using &krfb;</title>
<!-- This chapter should tell the user how to use your app. You should use as
many sections (Chapter, Sect1, Sect3, etc...) as is necessary to fully document
your application. -->
<sect1 id="main-windw">
<title>&krfb; Main Window</title>
<para>
It is very easy to use &krfb; - it has a simple interface, as shown in
the screenshot below.
@@ -189,64 +148,69 @@ the screenshot below.
</para>
<para>
When you want to allow someone to access your desktop, you can create
an personal invitation using the <guibutton>New Personal
Invitation...</guibutton> button, which will bring up a window
containing the information needed to access your desktop. An example
is shown below.
When you want to allow someone to access your desktop, you have to
enable the checkbox <guilabel>Enable Desktop Sharing</guilabel>,
which will start the server.
</para>
<sect2 id="connection-details">
<title>Connection Details</title>
<para>
The <guilabel>Address</guilabel> contains the address of your
computer and the port number, separated by a colon.
The address is just a hint - you can use any address that can
reach your computer. &krfb; tries to guess your address from your
network configuration, but does not always succeed in doing so.
If your computer is behind a firewall it may have a different
address or be unreachable for other computers.
</para>
<para>
You can change the port on the <guilabel>Network</guilabel>
page in the configuration dialog.
</para>
<para>
The next field is prefilled with an automatically generated password.
Click in the icon at the right of the field to change the password.
</para>
</sect2>
<sect2 id="unattended-access">
<title>Unattended Access</title>
<para>
Any remote user with the desktop sharing password will have to be authenticated.
If unattended access is activated, and the remote user provides the password
for unattended mode, desktop sharing access will be granted without explicit
confirmation.
</para>
<para>
By default the password for this mode is empty, to change that click on
the button and enter a password.
</para>
<para>
If unattended access is allowed, then you should probably specify a
password.
</para>
<para>
<screenshot>
<screeninfo>Example &krfb; personal invitation</screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="personal_invitation.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Example &krfb; personal invitation</phrase>
</textobject>
</mediaobject>
</screenshot>
If the machine is a server and you are using &krfb; for remote
administration, you probably want to use unattended access.
</para>
<para>
To increase security, the invitation is only valid for an
hour after it is created, and of course the person connecting has to
have the correct password.
</para>
</sect2>
<sect2 id="transfer-login-information">
<title>Transfer Login Information</title>
<para>
Since you may want to invite someone to access your desktop by email,
&krfb; can create invitations as email messages. You can create such
an invitation using the <guibutton>New Email Invitation...</guibutton>
button on the &krfb; main window. This will usually bring up an email
message that looks like the following, ready for you to type in the
email address of the person you are sending the invitation to.
</para>
<para>
<screenshot>
<screeninfo>Example &krfb; email invitation</screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="email_invitation.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Example &krfb; email invitation</phrase>
</textobject>
</mediaobject>
</screenshot>
</para>
<warning>
<para>
&krfb; will warn you about the security implications of sending this
information across an insecure link. You must heed those warnings.
&krfb; has no invitation feature any more as in previous versions.
So you have to transfer the login information yourself using email
or a personal invitation.
</para>
<para>
If you cannot encrypt the email (or otherwise secure the link),
sending invitations by email is a very serious security risk, since
sending a password by email is a very serious security risk, since
anyone can read the password and address from the email as it passes
over the network. This means that they can potentially take control of
your machine.
@@ -255,33 +219,32 @@ your machine.
If you cannot encrypt the email message, it may be better to use a
personal invitation, telephone the person you are giving access to,
verify the identity of that person, and provide the required
invitation information that way.
information that way.
</para>
</warning>
<sect1 id="krfb-managing-invitations">
<title>Managing &krfb; invitations</title>
<note>
<para>
Having created an invitation (either a personal invitation or one that
was sent by email), &krfb; main window allows you to delete existing
invitations. To just delete one of the invitations, select it with the
mouse (it should become highlighted), and then select
the <guibutton>Delete</guibutton>. To delete all invitations, just
select the <guibutton>Delete All</guibutton> button.
&krfb; uses the normal <acronym>RFB</acronym> password system, which does not transfer
your password in the clear across the network. Instead, it uses a
challenge-response system. This is reasonably secure, as long as the
password is securely guarded.
</para>
</note>
</sect1>
</sect2>
<sect1 id="krfb-qit">
<sect2 id="krfb-qqit">
<title>Quit &krfb;</title>
<para>
If you close the &krfb; main window the server keeps running, which is
indicated by an icon in the system tray.
To stop &krfb; right click on the icon in the systems tray and select
If you close the &krfb; main window by clicking on the window close icon or using the
shortcut <keycombo action="simul">&Alt;<keycap>F4</keycap></keycombo> the server
keeps running, which is indicated by an icon in the system tray.
To stop &krfb; either use <menuchoice><guimenu>File</guimenu><guimenuitem>Quit</guimenuitem></menuchoice>
in the main window or right click on the icon in the system tray and select
<guimenuitem>Quit</guimenuitem>.
</para>
</sect2>
</sect1>
@@ -290,7 +253,7 @@ To stop &krfb; right click on the icon in the systems tray and select
<para>
In addition to the main &krfb; interface shown and described above,
you can also control &krfb; using the
<guibutton>Configure...</guibutton> on the &krfb; main window. The &krfb;
<guimenuitem>Configure...</guimenuitem> on the &krfb; main window. The &krfb;
configuration has two pages, as shown in the screenshot below:
</para>
@@ -314,8 +277,8 @@ The <guilabel>Network</guilabel> page allows control over the port that
</para>
<para>
The <guilabel>Announce service on the network</guilabel> checkbox
controls whether &krfb; announces invitations over the network using
The <guilabel>Announce service on the local network</guilabel> checkbox
controls whether &krfb; announces the service over the local network using
Service Location Protocol. This is normally a good idea, but only
works really well with a Service Location Protocol aware client, such
as &krdc;.
@@ -323,8 +286,8 @@ as &krdc;.
<para>
If you select the <guilabel>Use default port</guilabel> checkbox,
then &krfb; will locate a suitable port, and invitations will match
this port. If you deselect this checkbox, you can specify a particular
then &krfb; will locate a suitable port.
If you deselect this checkbox, you can specify a particular
port. Specifying a particular port may be useful if you are using
port-forwarding on the firewall. Note that if Service Location
Protocol is turned on, this will automatically deal with identifying
@@ -332,8 +295,8 @@ the correct port.
</para>
<para>
The <guilabel>Security</guilabel> page allows you configure settings
related to access to the &krfb; server.
The <guilabel>Security</guilabel> page allows you to configure whether the
person connecting to the &krfb; server can control the desktop, or only view.
</para>
<para>
@@ -350,41 +313,15 @@ related to access to the &krfb; server.
</screenshot>
</para>
<para>
The <guilabel>Allow uninvited connections</guilabel> check box controls
whether &krfb; allows connection without an invitation. If uninvited
connections are allowed, then you should probably specify a
password. You can also use the check boxes here to choose whether you
have to confirm the connection before it proceeds, and whether the
person connecting can control the desktop, or only view.
</para>
<para>
If the machine is a workstation, and you choose to allow uninvited
connections, you probably want to select the <guilabel>Ask
before accepting connections </guilabel>. Conversely, if the
machine is a server and you are using &krfb; for remote
administration, you probably want to deselect this option.
</para>
<note>
<para>
&krfb; uses the normal <acronym>RFB</acronym> password system, which does not transfer
your password in the clear across the network. Instead, it uses a
challenge-response system. This is reasonably secure, as long as the
password is securely guarded.
</para>
</note>
</sect1>
<sect1 id="krfb-connection">
<title>What happens when someone connects to &krfb;</title>
<title>Connecting to &krfb;</title>
<para>
When someone connects to &krfb; on your machine, you will get a pop-up
notification that looks like the following screenshot, unless you are
accepting uninvited connections without warning.
accepting unattended access without confirmation.
</para>
<para>
<screenshot>
@@ -402,8 +339,8 @@ accepting uninvited connections without warning.
<para>
If you <guibutton>Accept Connection</guibutton>, the client can
proceed to authenticate (which requires the correct password for a
personal invitation or email invitation). If you <guibutton>Refuse
proceed to authenticate, which requires the correct password for a
login. If you <guibutton>Refuse
Connection</guibutton>, then the attempt to connect will be terminated.
</para>
@@ -413,23 +350,11 @@ mouse</guilabel> check box determines whether this client can only
observe, or can take control of your machine.
</para>
<para>
If the client connection is successful, and used the password from a
personal invitation or email invitation, then that invitation is
deleted and cannot be used again. You will also get a small pop-up
window in the dock, that shows that the connection has been made.
</para>
</sect1>
</chapter>
<chapter id="credits">
<!-- Include credits for the programmers, documentation writers, and
contributors here. The license for your software should then be included below
the credits with a reference to the appropriate license file included in the KDE
distribution. -->
<title>Credits and License</title>
<para>
@@ -458,33 +383,6 @@ Documentation Copyright &copy; 2003 &Brad.Hards; &Brad.Hards.mail;
</chapter>
<appendix id="installation">
<title>Installation</title>
<sect1 id="getting-krfb">
<title>How to obtain &krfb;</title>
<!-- This first entity contains boiler plate for applications that are
part of KDE CVS. You should remove it if you are releasing your
application -->
&install.intro.documentation;
</sect1>
<sect1 id="compilation">
<title>Compilation and Installation</title>
<!-- This entity contains the boilerplate text for standard -->
<!-- compilation instructions. If your application requires any -->
<!-- special handling, remove it, and replace with your own text. -->
&install.compile.documentation;
</sect1>
</appendix>
&documentation.index;
</book>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

@@ -1,3 +1,5 @@
add_subdirectory (qt)
add_subdirectory (x11)
if (${XCB_DAMAGE_FOUND} AND ${XCB_SHM_FOUND} AND ${XCB_IMAGE_FOUND})
add_subdirectory (xcb)
endif()

View File

@@ -7,22 +7,18 @@ set (krfb_framebuffer_qt_SRCS
qtframebufferplugin.cpp
)
kde4_add_plugin (krfb_framebuffer_qt
add_library(krfb_framebuffer_qt
MODULE
${krfb_framebuffer_qt_SRCS}
)
target_link_libraries (krfb_framebuffer_qt
${QT_QTCORE_LIBRARY}
${QT_QTGUI_LIBRARY}
${KDE4_KDEUI_LIBS}
Qt5::Core
Qt5::Gui
KF5::CoreAddons
krfbprivate
)
install (TARGETS krfb_framebuffer_qt
DESTINATION ${PLUGIN_INSTALL_DIR}
DESTINATION ${PLUGIN_INSTALL_DIR}/krfb
)
install (FILES krfb_framebuffer_qt.desktop
DESTINATION ${SERVICES_INSTALL_DIR}
)

View File

@@ -1,11 +1,11 @@
[Desktop Entry]
Encoding=UTF-8
Comment=Qt based Framebuffer for KRfb.
Comment[ast]=Esquema Qt de buffer pa KRfb
Comment[ast]=Búfer de cuadros basáu en Qt pa KRfb.
Comment[bg]=Основан на Qt фреймбуфер за KRfb.
Comment[bs]=Kadrobafer za KRfb na osnovu Qt
Comment[ca]=«Framebuffer» basat en Qt per al KRfb.
Comment[ca@valencia]=«Framebuffer» basat en Qt per al KRfb.
Comment[bs]=Kadrobafer za KRfb na osnovu Qt.
Comment[ca]=«Framebuffer» basat en les Qt per al KRfb.
Comment[ca@valencia]=«Framebuffer» basat en les Qt per al KRfb.
Comment[cs]=Framebuffer založený na Qt pro KRfb.
Comment[da]=Qt-baseret framebuffer til KRfb.
Comment[de]=Qt-basierter Framebuffer für KRfb
@@ -49,11 +49,11 @@ Comment[x-test]=xxQt based Framebuffer for KRfb.xx
Comment[zh_CN]=基于 Qt 的 KRfb 帧缓冲机制
Comment[zh_TW]=KRfb 的 Qt-based Framebuffer
Name=Qt Framebuffer for KRfb
Name[ast]=Esquema Qt de buffer pa KRfb
Name[ast]=Búfer de cuadros Qt pa KRfb
Name[bg]=Qt фреймбуфер за KRfb
Name[bs]=Qt-ov kadrobafer za KRFB
Name[ca]=«Framebuffer» Qt per al KRfb.
Name[ca@valencia]=«Framebuffer» Qt per al KRfb.
Name[ca]=«Framebuffer» de les Qt per al KRfb.
Name[ca@valencia]=«Framebuffer» de les Qt per al KRfb.
Name[cs]=Qt Framebuffer pro KRfb
Name[da]=Qt-framebuffer til KRfb
Name[de]=Qt-Framebuffer für KRfb

View File

@@ -0,0 +1,81 @@
{
"Encoding": "UTF-8",
"KPlugin": {
"Description": "Qt based Framebuffer for KRfb.",
"Description[ast]": "Búfer de cuadros basáu en Qt pa KRfb.",
"Description[ca@valencia]": "«Framebuffer» basat en les Qt per al KRfb.",
"Description[ca]": "«Framebuffer» basat en les Qt per al KRfb.",
"Description[cs]": "Framebuffer založený na Qt pro KRfb.",
"Description[da]": "Qt-baseret framebuffer til KRfb.",
"Description[de]": "Qt-basierter Framebuffer für KRfb",
"Description[el]": "Μνήμη ανανέωσης βίντεο με βάση τhn Qt για το KRfb.",
"Description[es]": "Framebuffer basado en Qt para KRfb.",
"Description[et]": "KRfb Qt põhine kaadripuhver",
"Description[fi]": "QT-perustainen Kehyspuskuri KRfb:lle",
"Description[fr]": "Tampon d'images utilisant Qt pour KRfb.",
"Description[gl]": "Framebuffer baseado en Qt para KRfb.",
"Description[ia]": "Framebuffer basate sur Qt per KRfb",
"Description[it]": "Framebuffer basato su Qt per KRfb.",
"Description[ko]": "KRfb용 Qt 기반 프레임버퍼입니다.",
"Description[nl]": "Op Qt gebaseerd framebuffer voor KRfb.",
"Description[nn]": "Qt-basert biletbuffer for KRfb.",
"Description[pl]": "Bufor ramki na podstawie Qt dla KRfb.",
"Description[pt]": "'Framebuffer' baseado no Qt para o KRfb.",
"Description[pt_BR]": "Framebuffer baseado no Qt para o KRfb.",
"Description[ru]": "Буфер кадров для KRfb на базе Qt",
"Description[sk]": "Framebuffer založený na Qt pre KRfb.",
"Description[sl]": "Slikovni medpomnilnik za KRfb, ki temelji na Qt",
"Description[sr@ijekavian]": "Кадробафер за КРФБ на основу КуТу",
"Description[sr@ijekavianlatin]": "Kadrobafer za KRFB na osnovu Qtu",
"Description[sr@latin]": "Kadrobafer za KRFB na osnovu Qtu",
"Description[sr]": "Кадробафер за КРФБ на основу КуТу",
"Description[sv]": "X11-rambuffert för Krfb.",
"Description[tr]": "KRfb için Qt tabanlı Çerçeve tamponu.",
"Description[uk]": "Заснований на Qt буфер кадрів для KRfb.",
"Description[x-test]": "xxQt based Framebuffer for KRfb.xx",
"Description[zh_CN]": "KRfb 的基于 Qt 的帧缓冲。",
"Description[zh_TW]": "KRfb 的 Qt-based Framebuffer",
"EnabledByDefault": true,
"Id": "qt",
"License": "GPL",
"Name": "Qt Framebuffer for KRfb",
"Name[ast]": "Búfer de cuadros Qt pa KRfb",
"Name[ca@valencia]": "«Framebuffer» de les Qt per al KRfb.",
"Name[ca]": "«Framebuffer» de les Qt per al KRfb.",
"Name[cs]": "Qt Framebuffer pro KRfb",
"Name[da]": "Qt-framebuffer til KRfb",
"Name[de]": "Qt-Framebuffer für KRfb",
"Name[el]": "Μνήμη ανανέωσης βίντεο Qt για το KRfb",
"Name[es]": "Framebuffer de Qt para KRfb",
"Name[et]": "KRfb Qt kaadripuhver",
"Name[fi]": "QT-kehyspuskuri KRfb:lle",
"Name[fr]": "Tampon d'images Qt pour KRfb",
"Name[gl]": "Framebuffer de Qt para KRfb",
"Name[ia]": "Framebuffer Qt per KRfb",
"Name[it]": "Framebuffer Qt per KRfb",
"Name[ko]": "KRfb용 Qt 프레임버퍼",
"Name[nl]": "Qt-framebuffer voor KRfb",
"Name[nn]": "Qt-biletbuffer for KRfb",
"Name[pl]": "Bufor ramki Qt dla KRfb",
"Name[pt]": "'Framebuffer' do Qt para o KRfb",
"Name[pt_BR]": "Framebuffer do Qt para o KRfb",
"Name[ru]": "Буфер кадров Qt для KRfb",
"Name[sk]": "Qt Framebuffer pre KRfb",
"Name[sl]": "Slikovni medpomnilnik Qt za KRfb",
"Name[sr@ijekavian]": "КуТ‑ов кадробафер за КРФБ",
"Name[sr@ijekavianlatin]": "Qtov kadrobafer za KRFB",
"Name[sr@latin]": "Qtov kadrobafer za KRFB",
"Name[sr]": "КуТ‑ов кадробафер за КРФБ",
"Name[sv]": "X11-rambuffert för Krfb",
"Name[tr]": "KRfb için Qt Çerçeve tamponu",
"Name[uk]": "Буфер кадрів на Qt для KRfb",
"Name[x-test]": "xxQt Framebuffer for KRfbxx",
"Name[zh_CN]": "KRfb 的 Qt 帧缓冲",
"Name[zh_TW]": "Krfb 的 Qt Framebuffer",
"ServiceTypes": [
"krfb/framebuffer"
],
"Version": "0.1",
"Website": "http://www.kde.org"
}
}

View File

@@ -14,6 +14,8 @@
#include <QRegion>
#include <QPixmap>
#include <QBitmap>
#include <QGuiApplication>
#include <QScreen>
const int UPDATE_TIME = 500;
@@ -21,16 +23,25 @@ const int UPDATE_TIME = 500;
QtFrameBuffer::QtFrameBuffer(WId id, QObject *parent)
: FrameBuffer(id, parent)
{
fbImage = QPixmap::grabWindow(win).toImage();
fb = new char[fbImage.numBytes()];
QScreen *screen = QGuiApplication::primaryScreen();
if (screen) {
primaryScreen = screen;
fbImage = screen->grabWindow(win).toImage();
fb = new char[fbImage.byteCount()];
} else {
fb = Q_NULLPTR;
primaryScreen = Q_NULLPTR;
}
t = new QTimer(this);
connect(t, SIGNAL(timeout()), SLOT(updateFrameBuffer()));
connect(t, &QTimer::timeout, this, &QtFrameBuffer::updateFrameBuffer);
}
QtFrameBuffer::~QtFrameBuffer()
{
delete [] fb;
if (fb)
delete [] fb;
fb = 0;
}
@@ -66,7 +77,9 @@ void QtFrameBuffer::getServerFormat(rfbPixelFormat &format)
void QtFrameBuffer::updateFrameBuffer()
{
QImage img = QPixmap::grabWindow(win).toImage();
if (!fb || !primaryScreen) return;
QImage img = primaryScreen->grabWindow(win).toImage();
#if 0 // This is actually slower than updating the whole desktop...
QSize imgSize = img.size();
@@ -74,8 +87,6 @@ void QtFrameBuffer::updateFrameBuffer()
// fbImage is the previous version of the image,
// img is the current one
#if 0 // This is actually slower than updating the whole desktop...
QImage map(imgSize, QImage::Format_Mono);
map.fill(0);
@@ -94,7 +105,7 @@ void QtFrameBuffer::updateFrameBuffer()
tiles.append(img.rect());
#endif
memcpy(fb, (const char *)img.bits(), img.numBytes());
memcpy(fb, (const char *)img.bits(), img.byteCount());
fbImage = img;
}

View File

@@ -14,6 +14,7 @@
#include "framebuffer.h"
class QTimer;
class QScreen;
/**
@author Alessandro Praduroux <pradu@pradu.it>
*/
@@ -25,13 +26,13 @@ public:
~QtFrameBuffer();
virtual int depth();
virtual int height();
virtual int width();
virtual int paddedWidth();
virtual void getServerFormat(rfbPixelFormat &format);
virtual void startMonitor();
virtual void stopMonitor();
int depth() override;
int height() override;
int width() override;
int paddedWidth() override;
void getServerFormat(rfbPixelFormat &format) override;
void startMonitor() override;
void stopMonitor() override;
public Q_SLOTS:
void updateFrameBuffer();
@@ -39,6 +40,7 @@ public Q_SLOTS:
private:
QImage fbImage;
QTimer *t;
QScreen *primaryScreen;
};
#endif

View File

@@ -22,8 +22,10 @@
#include "qtframebuffer.h"
#include <KGenericFactory>
#include <KPluginFactory>
K_PLUGIN_FACTORY_WITH_JSON(QtFrameBufferPluginFactory, "krfb_framebuffer_qt.json",
registerPlugin<QtFrameBufferPlugin>();)
QtFrameBufferPlugin::QtFrameBufferPlugin(QObject *parent, const QVariantList &args)
: FrameBufferPlugin(parent, args)
@@ -39,9 +41,5 @@ FrameBuffer *QtFrameBufferPlugin::frameBuffer(WId id)
return new QtFrameBuffer(id);
}
K_PLUGIN_FACTORY(factory, registerPlugin<QtFrameBufferPlugin>();) \
K_EXPORT_PLUGIN(factory("krfb_framebuffer_qt"))
#include "qtframebufferplugin.moc"

View File

@@ -23,9 +23,7 @@
#include "framebufferplugin.h"
#include <kdemacros.h>
#include <QtGui/QWidget>
#include <QWidget>
class FrameBuffer;
@@ -37,7 +35,7 @@ public:
QtFrameBufferPlugin(QObject *parent, const QVariantList &args);
virtual ~QtFrameBufferPlugin();
virtual FrameBuffer *frameBuffer(WId id);
FrameBuffer *frameBuffer(WId id) override;
private:
Q_DISABLE_COPY(QtFrameBufferPlugin)

View File

@@ -1,31 +0,0 @@
include_directories (${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
set (krfb_framebuffer_x11_SRCS
x11framebuffer.cpp
x11framebufferplugin.cpp
)
kde4_add_plugin (krfb_framebuffer_x11
${krfb_framebuffer_x11_SRCS}
)
target_link_libraries (krfb_framebuffer_x11
${KDE4_KDEUI_LIBS}
${QT_QTCORE_LIBRARY}
${QT_QTGUI_LIBRARY}
${X11_X11_LIB}
${X11_Xdamage_LIB}
${X11_Xext_LIB}
krfbprivate
)
install (TARGETS krfb_framebuffer_x11
DESTINATION ${PLUGIN_INSTALL_DIR}
)
install (FILES krfb_framebuffer_x11.desktop
DESTINATION ${SERVICES_INSTALL_DIR}
)

View File

@@ -1,388 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#include "x11framebuffer.h"
#include "x11framebuffer.moc"
#include <config-krfb.h>
#include <QX11Info>
#include <QApplication>
#include <QDesktopWidget>
#include <KApplication>
#include <KDebug>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#ifdef HAVE_XDAMAGE
#include <X11/extensions/Xdamage.h>
#endif
#ifdef HAVE_XSHM
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
#endif
class X11FrameBuffer::P
{
public:
#ifdef HAVE_XDAMAGE
Damage damage;
#endif
#ifdef HAVE_XSHM
XShmSegmentInfo shminfo;
#endif
XImage *framebufferImage;
XImage *updateTile;
EvWidget *ev;
bool useShm;
int xdamageBaseEvent;
bool running;
};
X11FrameBuffer::X11FrameBuffer(WId id, QObject *parent)
: FrameBuffer(id, parent), d(new X11FrameBuffer::P)
{
#ifdef HAVE_XSHM
d->useShm = XShmQueryExtension(QX11Info::display());
kDebug() << "shm: " << d->useShm;
#else
d->useShm = false;
#endif
d->running = false;
d->framebufferImage = XGetImage(QX11Info::display(),
id,
0,
0,
QApplication::desktop()->width(), //arg, must get a widget ???
QApplication::desktop()->height(),
AllPlanes,
ZPixmap);
if (d->useShm) {
#ifdef HAVE_XSHM
d->updateTile = XShmCreateImage(QX11Info::display(),
DefaultVisual(QX11Info::display(), 0),
d->framebufferImage->bits_per_pixel,
ZPixmap,
NULL,
&d->shminfo,
32,
32);
d->shminfo.shmid = shmget(IPC_PRIVATE,
d->updateTile->bytes_per_line * d->updateTile->height,
IPC_CREAT | 0777);
d->shminfo.shmaddr = d->updateTile->data = (char *)
shmat(d->shminfo.shmid, 0, 0);
d->shminfo.readOnly = False;
XShmAttach(QX11Info::display(), &d->shminfo);
#endif
} else {
;
}
kDebug() << "Got image. bpp: " << d->framebufferImage->bits_per_pixel
<< ", depth: " << d->framebufferImage->depth
<< ", padded width: " << d->framebufferImage->bytes_per_line
<< " (sent: " << d->framebufferImage->width * 4 << ")"
<< endl;
fb = d->framebufferImage->data;
#ifdef HAVE_XDAMAGE
d->ev = new EvWidget(this);
kapp->installX11EventFilter(d->ev);
#endif
}
X11FrameBuffer::~X11FrameBuffer()
{
XDestroyImage(d->framebufferImage);
#ifdef HAVE_XDAMAGE
kapp->removeX11EventFilter(d->ev);
#endif
#ifdef HAVE_XSHM
XShmDetach(QX11Info::display(), &d->shminfo);
XDestroyImage(d->updateTile);
shmdt(d->shminfo.shmaddr);
shmctl(d->shminfo.shmid, IPC_RMID, 0);
#endif
delete d;
fb = 0; // already deleted by XDestroyImage
}
int X11FrameBuffer::depth()
{
return d->framebufferImage->depth;
}
int X11FrameBuffer::height()
{
return d->framebufferImage->height;
}
int X11FrameBuffer::width()
{
return d->framebufferImage->width;
}
int X11FrameBuffer::paddedWidth()
{
return d->framebufferImage->bytes_per_line;
}
void X11FrameBuffer::getServerFormat(rfbPixelFormat &format)
{
format.bitsPerPixel = d->framebufferImage->bits_per_pixel;
format.depth = d->framebufferImage->depth;
format.trueColour = true;
format.bigEndian = ((d->framebufferImage->bitmap_bit_order == MSBFirst) ? true : false);
if (format.bitsPerPixel == 8) {
format.redShift = 0;
format.greenShift = 3;
format.blueShift = 6;
format.redMax = 7;
format.greenMax = 7;
format.blueMax = 3;
} else {
format.redShift = 0;
if (d->framebufferImage->red_mask)
while (!(d->framebufferImage->red_mask & (1 << format.redShift))) {
format.redShift++;
}
format.greenShift = 0;
if (d->framebufferImage->green_mask)
while (!(d->framebufferImage->green_mask & (1 << format.greenShift))) {
format.greenShift++;
}
format.blueShift = 0;
if (d->framebufferImage->blue_mask)
while (!(d->framebufferImage->blue_mask & (1 << format.blueShift))) {
format.blueShift++;
}
format.redMax = d->framebufferImage->red_mask >> format.redShift;
format.greenMax = d->framebufferImage->green_mask >> format.greenShift;
format.blueMax = d->framebufferImage->blue_mask >> format.blueShift;
}
}
void X11FrameBuffer::handleXDamage(XEvent *event)
{
#ifdef HAVE_XDAMAGE
XDamageNotifyEvent *dev = (XDamageNotifyEvent *)event;
QRect r(dev->area.x, dev->area.y, dev->area.width, dev->area.height);
tiles.append(r);
/*if (!dev->more) {
XDamageSubtract(QX11Info::display(),d->damage, None, None);
}*/
#endif
}
void X11FrameBuffer::cleanupRects()
{
QList<QRect> cpy = tiles;
bool inserted = false;
tiles.clear();
// kDebug() << "before cleanup: " << cpy.size();
foreach(const QRect & r, cpy) {
if (tiles.size() > 0) {
for (int i = 0; i < tiles.size(); i++) {
// kDebug() << r << tiles[i];
if (r.intersects(tiles[i])) {
tiles[i] |= r;
inserted = true;
break;
// kDebug() << "merged into " << tiles[i];
}
}
if (!inserted) {
tiles.append(r);
// kDebug() << "appended " << r;
}
} else {
// kDebug() << "appended " << r;
tiles.append(r);
}
}
for (int i = 0; i < tiles.size(); i++) {
tiles[i].adjust(-30, -30, 30, 30);
if (tiles[i].top() < 0) {
tiles[i].setTop(0);
}
if (tiles[i].left() < 0) {
tiles[i].setLeft(0);
}
if (tiles[i].bottom() > d->framebufferImage->height) {
tiles[i].setBottom(d->framebufferImage->height);
}
if (tiles[i].right() > d->framebufferImage->width) {
tiles[i].setRight(d->framebufferImage->width);
}
}
// kDebug() << "after cleanup: " << tiles.size();
}
void X11FrameBuffer::acquireEvents()
{
XEvent ev;
while (XCheckTypedEvent(QX11Info::display(), d->xdamageBaseEvent + XDamageNotify, &ev)) {
handleXDamage(&ev);
}
XDamageSubtract(QX11Info::display(), d->damage, None, None);
}
QList< QRect > X11FrameBuffer::modifiedTiles()
{
QList<QRect> ret;
if (!d->running) {
return ret;
}
kapp->processEvents(); // try to make sure every damage event goes trough;
cleanupRects();
QRect gl;
//d->useShm = false;
if (tiles.size() > 0) {
if (d->useShm) {
#ifdef HAVE_XSHM
foreach(const QRect & r, tiles) {
// kDebug() << r;
gl |= r;
int y = r.y();
int x = r.x();
while (x < r.right()) {
while (y < r.bottom()) {
if (y + d->updateTile->height > d->framebufferImage->height) {
y = d->framebufferImage->height - d->updateTile->height;
}
if (x + d->updateTile->width > d->framebufferImage->width) {
x = d->framebufferImage->width - d->updateTile->width;
}
// kDebug() << "x: " << x << " (" << r.x() << ") y: " << y << " (" << r.y() << ") " << r;
XShmGetImage(QX11Info::display(), win, d->updateTile, x, y, AllPlanes);
int pxsize = d->framebufferImage->bits_per_pixel / 8;
char *dest = fb + ((d->framebufferImage->bytes_per_line * y) + (x * pxsize));
char *src = d->updateTile->data;
for (int i = 0; i < d->updateTile->height; i++) {
memcpy(dest, src, d->updateTile->bytes_per_line);
dest += d->framebufferImage->bytes_per_line;
src += d->updateTile->bytes_per_line;
}
y += d->updateTile->height;
}
x += d->updateTile->width;
y = r.y();
}
}
#endif
} else {
foreach(const QRect & r, tiles) {
XGetSubImage(QX11Info::display(),
win,
r.left(),
r.top(),
r.width(),
r.height(),
AllPlanes,
ZPixmap,
d->framebufferImage,
r.left(),
r.top()
);
}
}
}
// kDebug() << "tot: " << gl;
// kDebug() << tiles.size();
ret = tiles;
tiles.clear();
return ret;
}
void X11FrameBuffer::startMonitor()
{
d->running = true;
#ifdef HAVE_XDAMAGE
d->damage = XDamageCreate(QX11Info::display(), win, XDamageReportRawRectangles);
XDamageSubtract(QX11Info::display(), d->damage, None, None);
#endif
}
void X11FrameBuffer::stopMonitor()
{
d->running = false;
#ifdef HAVE_XDAMAGE
XDamageDestroy(QX11Info::display(), d->damage);
#endif
}
EvWidget::EvWidget(X11FrameBuffer *x11fb)
: QWidget(0), fb(x11fb)
{
#ifdef HAVE_XDAMAGE
int er;
XDamageQueryExtension(QX11Info::display(), &xdamageBaseEvent, &er);
#endif
}
bool EvWidget::x11Event(XEvent *event)
{
#ifdef HAVE_XDAMAGE
if (event->type == xdamageBaseEvent + XDamageNotify) {
fb->handleXDamage(event);
return true;
}
#endif
return false;
}

View File

@@ -1,62 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#ifndef KRFB_FRAMEBUFFER_X11_X11FRAMEBUFFER_H
#define KRFB_FRAMEBUFFER_X11_X11FRAMEBUFFER_H
#include <framebuffer.h>
#include <QWidget>
class X11FrameBuffer;
class EvWidget: public QWidget
{
Q_OBJECT
public:
EvWidget(X11FrameBuffer *x11fb);
protected:
bool x11Event(XEvent *event);
private:
X11FrameBuffer *fb;
int xdamageBaseEvent;
};
/**
@author Alessandro Praduroux <pradu@pradu.it>
*/
class X11FrameBuffer : public FrameBuffer
{
Q_OBJECT
public:
X11FrameBuffer(WId id, QObject *parent = 0);
~X11FrameBuffer();
virtual QList<QRect> modifiedTiles();
virtual int depth();
virtual int height();
virtual int width();
virtual int paddedWidth();
virtual void getServerFormat(rfbPixelFormat &format);
virtual void startMonitor();
virtual void stopMonitor();
void handleXDamage(XEvent *event);
private:
void cleanupRects();
void acquireEvents();
class P;
P *const d;
};
#endif

View File

@@ -1,47 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2009 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "x11framebufferplugin.h"
#include "x11framebuffer.h"
#include <KGenericFactory>
X11FrameBufferPlugin::X11FrameBufferPlugin(QObject *parent, const QVariantList &args)
: FrameBufferPlugin(parent, args)
{
}
X11FrameBufferPlugin::~X11FrameBufferPlugin()
{
}
FrameBuffer *X11FrameBufferPlugin::frameBuffer(WId id)
{
return new X11FrameBuffer(id);
}
K_PLUGIN_FACTORY(factory, registerPlugin<X11FrameBufferPlugin>();) \
K_EXPORT_PLUGIN(factory("krfb_framebuffer_x11"))
#include "x11framebufferplugin.moc"

View File

@@ -1,48 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2009 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KRFB_FRAMEBUFFER_X11_X11FRAMEBUFFERPLUGIN_H
#define KRFB_FRAMEBUFFER_X11_X11FRAMEBUFFERPLUGIN_H
#include "framebufferplugin.h"
#include <kdemacros.h>
#include <QtGui/QWidget>
class FrameBuffer;
class X11FrameBufferPlugin : public FrameBufferPlugin
{
Q_OBJECT
public:
X11FrameBufferPlugin(QObject *parent, const QVariantList &args);
virtual ~X11FrameBufferPlugin();
virtual FrameBuffer *frameBuffer(WId id);
private:
Q_DISABLE_COPY(X11FrameBufferPlugin)
};
#endif // Header guard

View File

@@ -0,0 +1,28 @@
include_directories (${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
set (krfb_framebuffer_xcb_SRCS
xcb_framebufferplugin.cpp
xcb_framebuffer.cpp
)
add_library(krfb_framebuffer_xcb MODULE ${krfb_framebuffer_xcb_SRCS})
target_link_libraries (krfb_framebuffer_xcb
Qt5::Core
Qt5::Gui
XCB::XCB
XCB::RENDER
XCB::SHAPE
XCB::XFIXES
XCB::DAMAGE
XCB::SHM
XCB::IMAGE
KF5::CoreAddons
krfbprivate
)
install (TARGETS krfb_framebuffer_xcb
DESTINATION ${PLUGIN_INSTALL_DIR}/krfb
)

View File

@@ -1,11 +1,11 @@
[Desktop Entry]
Encoding=UTF-8
Comment=X11 XDamage/XShm based Framebuffer for KRfb.
Comment[ast]=Esquema de buffer pa KRfb basáu en XDamage/XShm
Comment[ast]=Búfer de cuadros basáu en XDamage/XShm de X11 pa KRfb.
Comment[bg]=Основан на X11 XDamage/XShm фреймбуфер за KRfb.
Comment[bs]=X11 XDamage/XShm baziran framebafer za KRfb.
Comment[ca]=«Framebuffer» basat en XDamage/XShmQt de l'X11 per al KRfb.
Comment[ca@valencia]=«Framebuffer» basat en XDamage/XShmQt de l'X11 per al KRfb.
Comment[ca]=«Framebuffer» basat en XDamage/XShmQt del X11 per al KRfb.
Comment[ca@valencia]=«Framebuffer» basat en XDamage/XShmQt del X11 per al KRfb.
Comment[cs]=Framebuffer založený na X11 XDamage/XShm pro KRfb.
Comment[da]=X11 XDamage/XShm-baseret framebuffer til KRfb.
Comment[de]=X11 XDamage/XShm-basierter Framebuffer für KRfb.
@@ -17,7 +17,7 @@ Comment[eu]=X11 XDamage/XShm oinarritutako KRfb-ren irteerako bideoa.
Comment[fi]=X11 XDamage/XShm-perustainen kehyspuskui KRfb:lle.
Comment[fr]=Sortie vidéo fondée sur X11 « XDamage / XShm » pour Krfb.
Comment[ga]=Maolán fráma le haghaidh KRfb, bunaithe ar X11 XDamage/XShm
Comment[gl]=Framebuffer baseado en Xll XDamage/Xshm para XRfb.
Comment[gl]=Framebuffer baseado en X11 XDamage/Xshm para XRfb.
Comment[hr]=Međuspreminik okvira baziran na X11 XDamage/XShm za KRfb.
Comment[hu]=X11 XDamage/XShm-alapú framebuffer a Krfb-hez.
Comment[ia]=Framebuffer basate sur X11 XDamage/XShm per KRfb.
@@ -49,11 +49,11 @@ Comment[x-test]=xxX11 XDamage/XShm based Framebuffer for KRfb.xx
Comment[zh_CN]= X11 XDamage/XShm KRfb
Comment[zh_TW]=KRfb X11 XDamage/XShm based Framebuffer
Name=X11 Framebuffer for KRfb
Name[ast]=Buffer de X11 pa KRfb
Name[ast]=Búfer de cuadros de X11 pa KRfb
Name[bg]=X11 фреймбуфер за KRfb
Name[bs]=X11 frame bafer za KRfb
Name[ca]=«Framebuffer» de l'X11 per al KRfb.
Name[ca@valencia]=«Framebuffer» de l'X11 per al KRfb.
Name[ca]=«Framebuffer» del X11 per al KRfb.
Name[ca@valencia]=«Framebuffer» del X11 per al KRfb.
Name[cs]=X11 Framebuffer pro KRfb
Name[da]=X11-framebuffer til KRfb
Name[de]=X11-Framebuffer für KRfb
@@ -99,8 +99,8 @@ Name[zh_TW]=KRfb 的 X11 Framebuffer
Type=Service
ServiceTypes=krfb/framebuffer
X-KDE-Library=krfb_framebuffer_x11
X-KDE-PluginInfo-Name=x11
X-KDE-Library=krfb_framebuffer_xcb
X-KDE-PluginInfo-Name=xcb
X-KDE-PluginInfo-Version=0.1
X-KDE-PluginInfo-Website=http://www.kde.org
X-KDE-PluginInfo-License=GPL

View File

@@ -0,0 +1,81 @@
{
"Encoding": "UTF-8",
"KPlugin": {
"Description": "X11 XDamage/XShm based Framebuffer for KRfb.",
"Description[ast]": "Búfer de cuadros basáu en XDamage/XShm de X11 pa KRfb.",
"Description[ca@valencia]": "«Framebuffer» basat en XDamage/XShmQt del X11 per al KRfb.",
"Description[ca]": "«Framebuffer» basat en XDamage/XShmQt del X11 per al KRfb.",
"Description[cs]": "Framebuffer založený na X11 XDamage/XShm pro KRfb.",
"Description[da]": "X11 XDamage/XShm-baseret framebuffer til KRfb.",
"Description[de]": "X11 XDamage/XShm-basierter Framebuffer für KRfb.",
"Description[el]": "Μνήμη ανανέωσης βίντεο με βάση το X11 XDamage/XShm για το KRfb.",
"Description[es]": "Framebuffer basado en XDamage/XShm de X11 para KRfb.",
"Description[et]": "KRfb X11 XDamage/XShm põhine kaadripuhver",
"Description[fi]": "X11 XDamage/XShm-perustainen kehyspuskui KRfb:lle.",
"Description[fr]": "Tampon d'images utilisant XDamage/XShm de X11 pour KRfb.",
"Description[gl]": "Framebuffer baseado en X11 XDamage/Xshm para XRfb.",
"Description[ia]": "Framebuffer basate sur X11 XDamage/XShm per KRfb.",
"Description[it]": "Framebuffer basato su XDamage/XShm di X11 per KRfb.",
"Description[ko]": "KRfb용 X11 XDamage/XShm 기반 프레임버퍼입니다.",
"Description[nl]": "Op X11 XDamage/XShm gebaseerd framebuffer voor KRfb.",
"Description[nn]": "X11 XDamage/XShm-basert biletbuffer for KRfb.",
"Description[pl]": "Bufor ramki na podstawie X11 XDamage/XShm dla KRfb.",
"Description[pt]": "'Framebuffer' do X11, baseado no XDamage/XShm, para o KRfb.",
"Description[pt_BR]": "Framebuffer baseado no XDamage/XShm do X11 para o KRfb.",
"Description[ru]": "Буфер кадров для KRfb на базе X11 XDamage/XShm",
"Description[sk]": "Framebuffer založený na X11 XDamage/XShm pre KRfb.",
"Description[sl]": "Slikovni medpomnilnik za KRfb, ki temelji na X11 XDamage/XShm",
"Description[sr@ijekavian]": "Кадробафер за КРФБ на основу Икс‑демиџа/Икс‑схма у Иксу11.",
"Description[sr@ijekavianlatin]": "Kadrobafer za KRFB na osnovu XDamagea/XShma u X11.",
"Description[sr@latin]": "Kadrobafer za KRFB na osnovu XDamagea/XShma u X11.",
"Description[sr]": "Кадробафер за КРФБ на основу Икс‑демиџа/Икс‑схма у Иксу11.",
"Description[sv]": "X11 XDamage/XShm-baserad rambuffert för Krfb.",
"Description[tr]": "KRfb için X11 XDamage/XShm tabanlı Çerçeve tamponu.",
"Description[uk]": "Заснований на XDamage/XShm X11 буфер кадрів для KRfb.",
"Description[x-test]": "xxX11 XDamage/XShm based Framebuffer for KRfb.xx",
"Description[zh_CN]": "KRfb 的基于 X11 XDamage/XShm 的帧缓冲。",
"Description[zh_TW]": "KRfb 的 X11 XDamage/XShm based Framebuffer",
"EnabledByDefault": true,
"Id": "xcb",
"License": "GPL",
"Name": "X11 Framebuffer for KRfb",
"Name[ast]": "Búfer de cuadros de X11 pa KRfb",
"Name[ca@valencia]": "«Framebuffer» del X11 per al KRfb.",
"Name[ca]": "«Framebuffer» del X11 per al KRfb.",
"Name[cs]": "X11 Framebuffer pro KRfb",
"Name[da]": "X11-framebuffer til KRfb",
"Name[de]": "X11-Framebuffer für KRfb",
"Name[el]": "Μνήμη ανανέωσης βίντεο X11 για το KRfb.",
"Name[es]": "Framebuffer X11 para KRfb",
"Name[et]": "KRfb X11 kaadripuhver",
"Name[fi]": "X11-kehyspuskuri KRfb:lle",
"Name[fr]": "Tampon d'images X11 pour KRfb",
"Name[gl]": "Framebuffer de X11 para KRfb",
"Name[ia]": "Framebuffer X11 per KRfb",
"Name[it]": "Framebuffer X11 per KRfb",
"Name[ko]": "KRfb용 X11 프레임버퍼",
"Name[nl]": "X11 framebuffer voor KRfb",
"Name[nn]": "X11-biletbuffer for KRfb",
"Name[pl]": "Bufor ramki X11 dla KRfb",
"Name[pt]": "'Framebuffer' do X11 para o KRfb",
"Name[pt_BR]": "Framebuffer do X11 para o KRfb",
"Name[ru]": "Буфер кадров X11 для KRfb",
"Name[sk]": "X11 Framebuffer pre KRfb",
"Name[sl]": "Slikovni medpomnilnik X11 za KRfb",
"Name[sr@ijekavian]": "Икс11 кадробафер за КРФБ.",
"Name[sr@ijekavianlatin]": "X11 kadrobafer za KRFB.",
"Name[sr@latin]": "X11 kadrobafer za KRFB.",
"Name[sr]": "Икс11 кадробафер за КРФБ.",
"Name[sv]": "X11-rambuffert för Krfb",
"Name[tr]": "KRfb için X11 Çerçeve tamponu",
"Name[uk]": "Буфер кадрів X11 для KRfb",
"Name[x-test]": "xxX11 Framebuffer for KRfbxx",
"Name[zh_CN]": "XRfb 的 X11 帧缓冲",
"Name[zh_TW]": "KRfb 的 X11 Framebuffer",
"ServiceTypes": [
"krfb/framebuffer"
],
"Version": "0.1",
"Website": "http://www.kde.org"
}
}

View File

@@ -0,0 +1,685 @@
/* This file is part of the KDE project
Copyright (C) 2017 Alexey Min <alexey.min@gmail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#include "xcb_framebuffer.h"
#include "xcb_framebuffer.moc"
#include <xcb/xcb.h>
#include <xcb/xproto.h>
#include <xcb/damage.h>
#include <xcb/shm.h>
#include <xcb/xcb_image.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <QX11Info>
#include <QCoreApplication>
#include <QGuiApplication>
#include <QScreen>
#include <QAbstractNativeEventFilter>
#include <QDebug>
class KrfbXCBEventFilter: public QAbstractNativeEventFilter
{
public:
KrfbXCBEventFilter(XCBFrameBuffer *owner);
public:
virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result);
public:
int xdamageBaseEvent;
int xdamageBaseError;
int xshmBaseEvent;
int xshmBaseError;
bool xshmAvail;
XCBFrameBuffer *fb_owner;
};
KrfbXCBEventFilter::KrfbXCBEventFilter(XCBFrameBuffer *owner):
xdamageBaseEvent(0), xdamageBaseError(0),
xshmBaseEvent(0), xshmBaseError(0), xshmAvail(false),
fb_owner(owner)
{
const xcb_query_extension_reply_t *xdamage_data = xcb_get_extension_data(
QX11Info::connection(), &xcb_damage_id);
if (xdamage_data) {
// also query extension version!
// ATTENTION: if we don't do that, xcb_damage_create() will always FAIL!
xcb_damage_query_version_reply_t *xdamage_version = xcb_damage_query_version_reply(
QX11Info::connection(),
xcb_damage_query_version(
QX11Info::connection(),
XCB_DAMAGE_MAJOR_VERSION,
XCB_DAMAGE_MINOR_VERSION),
NULL);
if (!xdamage_version) {
qWarning() << "xcb framebuffer: ERROR: Failed to get XDamage extension version!\n";
return;
}
#ifdef _DEBUG
qDebug() << "xcb framebuffer: XDamage extension version:" <<
xdamage_version->major_version << "." << xdamage_version->minor_version;
#endif
free(xdamage_version);
xdamageBaseEvent = xdamage_data->first_event;
xdamageBaseError = xdamage_data->first_error;
// XShm presence is optional. If it is present, all image getting
// operations will be faster, without XShm it will only be slower.
const xcb_query_extension_reply_t *xshm_data = xcb_get_extension_data(
QX11Info::connection(), &xcb_shm_id);
if (xshm_data) {
xshmAvail = true;
xshmBaseEvent = xshm_data->first_event;
xshmBaseError = xshm_data->first_error;
} else {
xshmAvail = false;
qWarning() << "xcb framebuffer: WARNING: XSHM extension not available!";
}
} else {
// if there is no xdamage available, this plugin can be considered useless anyway.
// you can use just qt framebuffer plugin instead...
qWarning() << "xcb framebuffer: ERROR: no XDamage extension available. I am useless.";
qWarning() << "xcb framebuffer: use qt framebuffer plugin instead.";
}
}
bool KrfbXCBEventFilter::nativeEventFilter(const QByteArray &eventType,
void *message, long *result) {
Q_UNUSED(result); // "result" is only used on windows
if (xdamageBaseEvent == 0) return false; // no xdamage extension
if (eventType == "xcb_generic_event_t") {
xcb_generic_event_t* ev = static_cast<xcb_generic_event_t *>(message);
if ((ev->response_type & 0x7F) == (xdamageBaseEvent + XCB_DAMAGE_NOTIFY)) {
// this is xdamage notification
this->fb_owner->handleXDamageNotify(ev);
return true; // filter out this event, stop its processing
}
}
// continue event processing
return false;
}
class XCBFrameBuffer::P {
public:
xcb_damage_damage_t damage;
xcb_shm_segment_info_t shminfo;
xcb_screen_t *rootScreen; // X screen info (all monitors)
xcb_image_t *framebufferImage;
xcb_image_t *updateTile;
KrfbXCBEventFilter *x11EvtFilter;
bool running;
QRect area; // capture area, primary monitor coordinates
};
static xcb_screen_t *get_xcb_screen(xcb_connection_t *conn, int screen_num) {
xcb_screen_t *screen = NULL;
xcb_screen_iterator_t screens_iter = xcb_setup_roots_iterator(xcb_get_setup(conn));
for (; screens_iter.rem; --screen_num, xcb_screen_next(&screens_iter))
if (screen_num == 0)
screen = screens_iter.data;
return screen;
}
XCBFrameBuffer::XCBFrameBuffer(WId winid, QObject *parent):
FrameBuffer(winid, parent), d(new XCBFrameBuffer::P)
{
d->running = false;
d->damage = XCB_NONE;
d->framebufferImage = Q_NULLPTR;
d->shminfo.shmaddr = Q_NULLPTR;
d->shminfo.shmid = XCB_NONE;
d->shminfo.shmseg = XCB_NONE;
d->updateTile = Q_NULLPTR;
d->area.setRect(0, 0, 0, 0);
d->x11EvtFilter = new KrfbXCBEventFilter(this);
d->rootScreen = get_xcb_screen(QX11Info::connection(), QX11Info::appScreen());
this->fb = Q_NULLPTR;
QScreen *primaryScreen = QGuiApplication::primaryScreen();
if (primaryScreen) {
qDebug() << "xcb framebuffer: Primary screen: " << primaryScreen->name()
<< ", geometry: " << primaryScreen->geometry()
<< ", depth: " << primaryScreen->depth();
//
d->area = primaryScreen->geometry();
} else {
qWarning() << "xcb framebuffer: ERROR: Failed to get application's primary screen info!";
return;
}
d->framebufferImage = xcb_image_get(QX11Info::connection(),
this->win,
d->area.left(),
d->area.top(),
d->area.width(),
d->area.height(),
0xFFFFFFFF, // == Xlib: AllPlanes ((unsigned long)~0L)
XCB_IMAGE_FORMAT_Z_PIXMAP);
if (d->framebufferImage) {
#ifdef _DEBUG
qDebug() << "xcb framebuffer: Got primary screen image. bpp: " << d->framebufferImage->bpp
<< ", size (" << d->framebufferImage->width << d->framebufferImage->height << ")"
<< ", depth: " << d->framebufferImage->depth
<< ", padded width: " << d->framebufferImage->stride;
#endif
this->fb = (char *)d->framebufferImage->data;
} else {
qWarning() << "xcb framebuffer: ERROR: Failed to get primary screen image!";
return;
}
// all XShm operations should take place only if Xshm extension was loaded
if (d->x11EvtFilter->xshmAvail) {
// Create xcb_image_t structure, but do not automatically allocate memory
// for image data storage - it will be allocated as shared memory.
// "If base == 0 and bytes == ~0 and data == 0, no storage will be auto-allocated."
// Width and height of the image = size of the capture area.
d->updateTile = xcb_image_create_native(
QX11Info::connection(),
d->area.width(), // width
d->area.height(), // height
XCB_IMAGE_FORMAT_Z_PIXMAP, // image format
d->rootScreen->root_depth, // depth
NULL, // base address = 0
(uint32_t)~0, // bytes = 0xffffffff
NULL); // data = 0
if (d->updateTile) {
#ifdef _DEBUG
qDebug() << "xcb framebuffer: Successfully created new empty image in native format";
qDebug() << " size: " << d->updateTile->width << "x" << d->updateTile->height
<< "(stride: " << d->updateTile->stride << ")";
qDebug() << " bpp, depth: " << d->updateTile->bpp << d->updateTile->depth; // 32, 24
qDebug() << " addr of base, data: " << d->updateTile->base << (void *)d->updateTile->data;
qDebug() << " size: " << d->updateTile->size;
qDebug() << " image byte order = " << d->updateTile->byte_order; // == 0 .._LSB_FIRST
qDebug() << " image bit order = " << d->updateTile->bit_order; // == 1 .._MSB_FIRST
qDebug() << " image plane_mask = " << d->updateTile->plane_mask; // == 16777215 == 0x00FFFFFF
#endif
// allocate shared memory block only once, make its size large enough
// to fit whole capture area (d->area rect)
// so, we get as many bytes as needed for image (updateTile->size)
d->shminfo.shmid = shmget(IPC_PRIVATE, d->updateTile->size, IPC_CREAT | 0777);
// attached shared memory address is stored both in shminfo structure and in xcb_image_t->data
d->shminfo.shmaddr = (uint8_t *)shmat(d->shminfo.shmid, NULL, 0);
d->updateTile->data = d->shminfo.shmaddr;
// we keep updateTile->base == NULL here, so xcb_image_destroy() will not attempt
// to free this block, just in case.
// attach this shm segment also to X server
d->shminfo.shmseg = xcb_generate_id(QX11Info::connection());
xcb_shm_attach(QX11Info::connection(), d->shminfo.shmseg, d->shminfo.shmid, 0);
#ifdef _DEBUG
qDebug() << " shm id: " << d->shminfo.shmseg << ", addr: " << (void *)d->shminfo.shmaddr;
#endif
// will return 1 on success (yes!)
int shmget_res = xcb_image_shm_get(
QX11Info::connection(),
this->win,
d->updateTile,
d->shminfo,
d->area.left(), // x
d->area.top(), // y (size taken from image structure itself)?
0xFFFFFFFF);
if (shmget_res == 0) {
// error! shared mem not working?
// will not use shared mem! detach and cleanup
xcb_shm_detach(QX11Info::connection(), d->shminfo.shmseg);
shmdt(d->shminfo.shmaddr);
shmctl(d->shminfo.shmid, IPC_RMID, 0); // mark shm segment as removed
d->x11EvtFilter->xshmAvail = false;
d->shminfo.shmaddr = Q_NULLPTR;
d->shminfo.shmid = XCB_NONE;
d->shminfo.shmseg = XCB_NONE;
qWarning() << "xcb framebuffer: ERROR: xcb_image_shm_get() result: " << shmget_res;
}
// image is freed, and recreated again for every new damage rectangle
// data was allocated manually and points to shared mem;
// tell xcb_image_destroy() do not free image data
d->updateTile->data = NULL;
xcb_image_destroy(d->updateTile);
d->updateTile = NULL;
}
}
#ifdef _DEBUG
qDebug() << "xcb framebuffer: XCBFrameBuffer(), xshm base event = " << d->x11EvtFilter->xshmBaseEvent
<< ", xshm base error = " << d->x11EvtFilter->xdamageBaseError
<< ", xdamage base event = " << d->x11EvtFilter->xdamageBaseEvent
<< ", xdamage base error = " << d->x11EvtFilter->xdamageBaseError;
#endif
QCoreApplication::instance()->installNativeEventFilter(d->x11EvtFilter);
}
XCBFrameBuffer::~XCBFrameBuffer() {
// first - uninstall x11 event filter
QCoreApplication::instance()->removeNativeEventFilter(d->x11EvtFilter);
//
if (d->framebufferImage) {
xcb_image_destroy(d->framebufferImage);
fb = Q_NULLPTR; // image data was already destroyed by above call
}
if (d->x11EvtFilter->xshmAvail) {
// detach shared memory
if (d->shminfo.shmseg != XCB_NONE)
xcb_shm_detach(QX11Info::connection(), d->shminfo.shmseg); // detach from X server
if (d->shminfo.shmaddr)
shmdt(d->shminfo.shmaddr); // detach addr from our address space
if (d->shminfo.shmid != XCB_NONE)
shmctl(d->shminfo.shmid, IPC_RMID, 0); // mark shm segment as removed
}
// and delete image used for shared mem
if (d->updateTile) {
d->updateTile->base = NULL;
d->updateTile->data = NULL;
xcb_image_destroy(d->updateTile);
}
// we don't use d->x11EvtFilter anymore, can delete it now
if (d->x11EvtFilter) {
delete d->x11EvtFilter;
}
delete d;
}
int XCBFrameBuffer::depth() {
if (d->framebufferImage) {
return d->framebufferImage->depth;
}
return 0;
}
int XCBFrameBuffer::height() {
if (d->framebufferImage) {
return d->framebufferImage->height;
}
return 0;
}
int XCBFrameBuffer::width() {
if (d->framebufferImage) {
return d->framebufferImage->width;
}
return 0;
}
int XCBFrameBuffer::paddedWidth() {
if (d->framebufferImage) {
return d->framebufferImage->stride;
}
return 0;
}
void XCBFrameBuffer::getServerFormat(rfbPixelFormat &format) {
if (!d->framebufferImage) return;
// get information about XCB visual params
xcb_visualtype_t *root_visualtype = NULL; // visual info
if (d->rootScreen) {
xcb_visualid_t root_visual = d->rootScreen->root_visual;
xcb_depth_iterator_t depth_iter;
// To get the xcb_visualtype_t structure, it's a bit less easy.
// You have to get the xcb_screen_t structure that you want, get its
// root_visual member, then iterate over the xcb_depth_t's and the
// xcb_visualtype_t's, and compare the xcb_visualid_t of these
// xcb_visualtype_ts: with root_visual
depth_iter = xcb_screen_allowed_depths_iterator(d->rootScreen);
for (; depth_iter.rem; xcb_depth_next(&depth_iter)) {
xcb_visualtype_iterator_t visual_iter;
visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
for (; visual_iter.rem; xcb_visualtype_next(&visual_iter)) {
if (root_visual == visual_iter.data->visual_id) {
root_visualtype = visual_iter.data;
break;
}
}
}
}
// fill in format common info
format.bitsPerPixel = d->framebufferImage->bpp;
format.depth = d->framebufferImage->depth;
format.trueColour = true; // not using color palettes
format.bigEndian = false; // always false for ZPIXMAP format!
// information about pixels layout
if (root_visualtype) {
uint16_t pixelmaxValue = (1 << root_visualtype->bits_per_rgb_value) - 1;
#ifdef _DEBUG
qDebug("xcb framebuffer: Got info about root visual:\n"
" bits per rgb value: %d\n"
" red mask: %08x\n"
" green mask: %08x\n"
" blue mask: %08x\n"
" pixelMaxValue = %d\n",
(int)root_visualtype->bits_per_rgb_value,
root_visualtype->red_mask,
root_visualtype->green_mask,
root_visualtype->blue_mask,
(int)pixelmaxValue);
#endif
// calculate shifts
format.redShift = 0;
format.redMax = pixelmaxValue;
if (root_visualtype->red_mask) {
while (!(root_visualtype->red_mask & (1 << format.redShift))) {
format.redShift++;
}
}
format.greenShift = 0;
format.greenMax = pixelmaxValue;
if (root_visualtype->green_mask) {
while (!(root_visualtype->green_mask & (1 << format.greenShift))) {
format.greenShift++;
}
}
format.blueShift = 0;
format.blueMax = pixelmaxValue;
if (root_visualtype->blue_mask) {
while (!(root_visualtype->blue_mask & (1 << format.blueShift))) {
format.blueShift++;
}
}
#ifdef _DEBUG
qDebug() << " Calculated redShift =" << (int)format.redShift;
qDebug() << " Calculated greenShift =" << (int)format.greenShift;
qDebug() << " Calculated blueShift =" << (int)format.blueShift;
#endif
} else {
// some kind of fallback (unlikely code execution will go this way)
// idea taken from qt framefuffer sources
if (format.bitsPerPixel == 8) {
format.redShift = 0;
format.greenShift = 3;
format.blueShift = 6;
format.redMax = 7;
format.greenMax = 7;
format.blueMax = 3;
} else if (format.bitsPerPixel == 16) {
// TODO: 16 bits per pixel format ??
// what format of pixels does X server use for 16-bpp?
} else if (format.bitsPerPixel == 32) {
format.redMax = 0xff;
format.greenMax = 0xff;
format.blueMax = 0xff;
if (format.bigEndian) {
format.redShift = 0;
format.greenShift = 8;
format.blueShift = 16;
} else {
format.redShift = 16;
format.greenShift = 8;
format.blueShift = 0;
}
}
}
}
/**
* This function contents was taken from X11 framebuffer source code.
* It simply several intersecting rectangles into one bigger rect.
* Non-intersecting rects are treated as different rects and exist
* separately in this->tiles QList.
*/
void XCBFrameBuffer::cleanupRects() {
QList<QRect> cpy = tiles;
bool inserted = false;
tiles.clear();
QListIterator<QRect> iter(cpy);
while (iter.hasNext()) {
const QRect &r = iter.next();
// skip rects not intersecting with primary monitor
if (!r.intersects(d->area)) continue;
// only take intersection of this rect with primary monitor rect
QRect ri = r.intersected(d->area);
if (tiles.size() > 0) {
for (int i = 0; i < tiles.size(); i++) {
// if current rect has intersection with tiles[i], unite them
if (ri.intersects(tiles[i])) {
tiles[i] |= ri;
inserted = true;
break;
}
}
if (!inserted) {
// else, append to list as different rect
tiles.append(ri);
}
} else {
// tiles list is empty, append first item
tiles.append(ri);
}
}
// increase all rectangles size by 30 pixels each side.
// limit coordinates to primary monitor boundaries.
for (int i = 0; i < tiles.size(); i++) {
tiles[i].adjust(-30, -30, 30, 30);
if (tiles[i].top() < d->area.top()) {
tiles[i].setTop(d->area.top());
}
if (tiles[i].bottom() > d->area.bottom()) {
tiles[i].setBottom(d->area.bottom());
}
//
if (tiles[i].left() < d->area.left()) {
tiles[i].setLeft(d->area.left());
}
if (tiles[i].right() > d->area.right()) {
tiles[i].setRight(d->area.right());
}
// move update rects so that they are positioned relative to
// framebuffer image, not whole screen
tiles[i].moveTo(tiles[i].left() - d->area.left(),
tiles[i].top() - d->area.top());
}
}
/**
* This function is called by RfbServerManager::updateScreens()
* approximately every 50ms (!!), driven by QTimer to get all
* modified rectangles on the screen
*/
QList<QRect> XCBFrameBuffer::modifiedTiles() {
QList<QRect> ret;
if (!d->running) {
return ret;
}
cleanupRects();
if (tiles.size() > 0) {
if (d->x11EvtFilter->xshmAvail) {
// loop over all damage rectangles gathered up to this time
QListIterator<QRect> iter(tiles);
//foreach(const QRect &r, tiles) {
while (iter.hasNext()) {
const QRect &r = iter.next();
// get image data into shared memory segment
// now rects are positioned relative to framebufferImage,
// but we need to get image from the whole screen, so
// translate whe coordinates
xcb_shm_get_image_cookie_t sgi_cookie = xcb_shm_get_image(
QX11Info::connection(),
this->win,
d->area.left() + r.left(),
d->area.top() + r.top(),
r.width(),
r.height(),
0xFFFFFFFF,
XCB_IMAGE_FORMAT_Z_PIXMAP,
d->shminfo.shmseg,
0);
xcb_shm_get_image_reply_t *sgi_reply = xcb_shm_get_image_reply(
QX11Info::connection(), sgi_cookie, NULL);
if (sgi_reply) {
// create temporary image to get update rect contents into
d->updateTile = xcb_image_create_native(
QX11Info::connection(),
r.width(),
r.height(),
XCB_IMAGE_FORMAT_Z_PIXMAP,
d->rootScreen->root_depth,
NULL, // base == 0
(uint32_t)~0, // bytes == ~0
NULL);
if (d->updateTile) {
d->updateTile->data = d->shminfo.shmaddr;
// copy pixels from this damage rectangle image
// to our total framebuffer image
int pxsize = d->framebufferImage->bpp / 8;
char *dest = fb + ((d->framebufferImage->stride * r.top()) + (r.left() * pxsize));
char *src = (char *)d->updateTile->data;
for (int i = 0; i < d->updateTile->height; i++) {
memcpy(dest, src, d->updateTile->stride); // copy whole row of pixels
dest += d->framebufferImage->stride;
src += d->updateTile->stride;
}
// delete temporary image
d->updateTile->data = NULL;
xcb_image_destroy(d->updateTile);
d->updateTile = NULL;
}
free(sgi_reply);
}
} // foreach
} else {
// not using shared memory
// will use just xcb_image_get() and copy pixels
foreach(const QRect &r, tiles) {
// I did not find XGetSubImage() analog in XCB!!
// need function that copies pixels from one image to another
xcb_image_t *damagedImage = xcb_image_get(
QX11Info::connection(),
this->win,
r.left(),
r.top(),
r.width(),
r.height(),
0xFFFFFFFF, // AllPlanes
XCB_IMAGE_FORMAT_Z_PIXMAP);
// manually copy pixels
int pxsize = d->framebufferImage->bpp / 8;
char *dest = fb + ((d->framebufferImage->stride * r.top()) + (r.left() * pxsize));
char *src = (char *)damagedImage->data;
// loop every row in damaged image
for (int i = 0; i < damagedImage->height; i++) {
// copy whole row of pixels from src image to dest
memcpy(dest, src, damagedImage->stride);
dest += d->framebufferImage->stride; // move 1 row down in dest
src += damagedImage->stride; // move 1 row down in src
}
//
xcb_image_destroy(damagedImage);
}
}
} // if (tiles.size() > 0)
ret = tiles;
tiles.clear();
// ^^ If we clear here all our known "damage areas", then we can also clear
// damaged area for xdamage? No, we don't need to in our case
// (XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES report mode)
//xcb_damage_subtract(QX11Info::connection(), d->damage, XCB_NONE, XCB_NONE);
return ret;
}
void XCBFrameBuffer::startMonitor() {
if (d->running) return;
d->running = true;
d->damage = xcb_generate_id(QX11Info::connection());
xcb_damage_create(QX11Info::connection(), d->damage, this->win,
XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES);
// (currently) we do not call xcb_damage_subtract() EVER, because
// RAW rectangles are reported. every time some area of the screen
// was changed, we get only that rectangle
//xcb_damage_subtract(QX11Info::connection(), d->damage, XCB_NONE, XCB_NONE);
}
void XCBFrameBuffer::stopMonitor() {
if (!d->running) return;
d->running = false;
xcb_damage_destroy(QX11Info::connection(), d->damage);
}
// void XCBFrameBuffer::acquireEvents() {} // this function was totally unused
// in X11 framebuffer, but it was the only function where XDamageSubtract() was called?
// Also it had a blocking event loop like:
//
// XEvent ev;
// while (XCheckTypedEvent(QX11Info::display(), d->xdamageBaseEvent + XDamageNotify, &ev)) {
// handleXDamage(&ev);
// }
// XDamageSubtract(QX11Info::display(), d->damage, None, None);
//
// This loop takes all available Xdamage events from queue, and ends if there are no
// more such events in input queue.
void XCBFrameBuffer::handleXDamageNotify(xcb_generic_event_t *xevent) {
xcb_damage_notify_event_t *xdevt = (xcb_damage_notify_event_t *)xevent;
QRect r((int)xdevt->area.x, (int)xdevt->area.y,
(int)xdevt->area.width, (int)xdevt->area.height);
this->tiles.append(r);
}

View File

@@ -0,0 +1,48 @@
/* This file is part of the KDE project
Copyright (C) 2017 Alexey Min <alexey.min@gmail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#ifndef KRFB_FRAMEBUFFER_XCB_XCB_FRAMEBUFFER_H
#define KRFB_FRAMEBUFFER_XCB_XCB_FRAMEBUFFER_H
#include "framebuffer.h"
#include <QWidget>
#include <xcb/xcb.h>
/**
@author Alexey Min <alexey.min@gmail.com>
*/
class XCBFrameBuffer: public FrameBuffer
{
Q_OBJECT
public:
XCBFrameBuffer(WId winid, QObject *parent = 0);
~XCBFrameBuffer();
public:
QList<QRect> modifiedTiles() Q_DECL_OVERRIDE;
int depth() Q_DECL_OVERRIDE;
int height() Q_DECL_OVERRIDE;
int width() Q_DECL_OVERRIDE;
int paddedWidth() Q_DECL_OVERRIDE;
void getServerFormat(rfbPixelFormat &format) Q_DECL_OVERRIDE;
void startMonitor() Q_DECL_OVERRIDE;
void stopMonitor() Q_DECL_OVERRIDE;
public:
void handleXDamageNotify(xcb_generic_event_t *xevent);
private:
void cleanupRects();
class P;
P *const d;
};
#endif

View File

@@ -0,0 +1,46 @@
/* This file is part of the KDE project
@author Alexey Min <alexey.min@gmail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "xcb_framebufferplugin.h"
#include "xcb_framebuffer.h"
#include <KPluginFactory>
K_PLUGIN_FACTORY_WITH_JSON(XCBFrameBufferPluginFactory, "krfb_framebuffer_xcb.json",
registerPlugin<XCBFrameBufferPlugin>();)
XCBFrameBufferPlugin::XCBFrameBufferPlugin(QObject *parent, const QVariantList &args)
: FrameBufferPlugin(parent, args)
{
}
XCBFrameBufferPlugin::~XCBFrameBufferPlugin()
{
}
FrameBuffer *XCBFrameBufferPlugin::frameBuffer(WId id)
{
return new XCBFrameBuffer(id);
}
#include "xcb_framebufferplugin.moc"

View File

@@ -0,0 +1,45 @@
/* This file is part of the KDE project
@author Alexey Min <alexey.min@gmail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KRFB_FRAMEBUFFER_XCB_XCBFRAMEBUFFERPLUGIN_H
#define KRFB_FRAMEBUFFER_XCB_XCBFRAMEBUFFERPLUGIN_H
#include "framebufferplugin.h"
#include <QWidget>
class FrameBuffer;
class XCBFrameBufferPlugin: public FrameBufferPlugin
{
Q_OBJECT
public:
XCBFrameBufferPlugin(QObject *parent, const QVariantList &args);
virtual ~XCBFrameBufferPlugin();
FrameBuffer *frameBuffer(WId id) override;
private:
Q_DISABLE_COPY(XCBFrameBufferPlugin)
};
#endif // Header guard

3
krfb.kdev4 Normal file
View File

@@ -0,0 +1,3 @@
[Project]
Manager=KDevCMakeManager
Name=krfb

View File

@@ -2,6 +2,8 @@ configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config-krfb.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/config-krfb.h
)
include(GenerateExportHeader)
#####################################
# First target: libkrfbprivate - a library
# for linking plugins against.
@@ -11,20 +13,23 @@ set (krfbprivate_SRCS
framebufferplugin.cpp
)
kde4_add_library (krfbprivate
add_library (krfbprivate
SHARED
${krfbprivate_SRCS}
)
generate_export_header(krfbprivate BASE_NAME krfbprivate)
target_link_libraries (krfbprivate
${QT_QTCORE_LIBRARY}
${QT_QTGUI_LIBRARY}
Qt5::Core
Qt5::Widgets
Qt5::X11Extras
${X11_X11_LIB}
${LIBVNCSERVER_LIBRARIES}
)
set_target_properties (krfbprivate PROPERTIES
VERSION ${GENERIC_LIB_VERSION}
SOVERSION ${GENERIC_LIB_VERSION}
VERSION 5
SOVERSION 5.0
)
install (TARGETS krfbprivate
@@ -41,21 +46,12 @@ install (FILES
# Second target: krfb - the app
# itself.
if(TelepathyQt4_FOUND)
add_definitions(-DKRFB_WITH_TELEPATHY_TUBES)
include_directories(${TELEPATHY_QT4_INCLUDE_DIR})
endif()
set (krfb_SRCS
connectiondialog.cpp
events.cpp
framebuffermanager.cpp
invitation.cpp
invitedialog.cpp
invitationmanager.cpp
main.cpp
manageinvitationsdialog.cpp
personalinvitedialog.cpp
mainwindow.cpp
sockethelpers.cpp
trayicon.cpp
rfbservermanager.cpp
@@ -65,53 +61,41 @@ set (krfb_SRCS
invitationsrfbclient.cpp
)
if(TelepathyQt4_FOUND)
set (krfb_SRCS
${krfb_SRCS}
tubesrfbserver.cpp
tubesrfbclient.cpp
)
endif()
kde4_add_kcfg_files (krfb_SRCS
kconfig_add_kcfg_files (krfb_SRCS
krfbconfig.kcfgc
)
kde4_add_ui_files (krfb_SRCS
ki18n_wrap_ui (krfb_SRCS
ui/configtcp.ui
ui/configsecurity.ui
ui/configframebuffer.ui
ui/connectionwidget.ui
ui/invitewidget.ui
ui/manageinvitations.ui
ui/personalinvitewidget.ui
ui/mainwidget.ui
)
if(TelepathyQt4_FOUND)
kde4_add_ui_files(krfb_SRCS ui/tubesconnectionwidget.ui)
endif()
kde4_add_executable (krfb
add_executable (krfb
${krfb_SRCS}
)
target_link_libraries (krfb
krfbprivate
vncserver
${JPEG_LIBRARIES}
${X11_Xext_LIB}
${X11_X11_LIB}
${X11_Xdamage_LIB}
${QT_QTNETWORK_LIBRARY}
${KDE4_KDNSSD_LIBS}
${KDE4_KDEUI_LIBS}
Qt5::Network
KF5::Completion
KF5::CoreAddons
KF5::DBusAddons
KF5::DNSSD
KF5::I18n
KF5::Notifications
KF5::Wallet
KF5::WidgetsAddons
KF5::XmlGui
${LIBVNCSERVER_LIBRARIES}
)
if(TelepathyQt4_FOUND)
target_link_libraries(krfb
${TELEPATHY_QT4_LIBRARIES}
)
endif()
if (X11_XTest_FOUND)
target_link_libraries (krfb
${X11_XTest_LIB}
@@ -122,21 +106,16 @@ install (TARGETS krfb
${INSTALL_TARGETS_DEFAULT_ARGS}
)
if(TelepathyQt4_FOUND)
configure_file(org.freedesktop.Telepathy.Client.krfb_rfb_handler.service.in
org.freedesktop.Telepathy.Client.krfb_rfb_handler.service)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.freedesktop.Telepathy.Client.krfb_rfb_handler.service
DESTINATION ${DBUS_SERVICES_INSTALL_DIR})
install(FILES krfb_rfb_handler.client DESTINATION ${CMAKE_INSTALL_PREFIX}/share/telepathy/clients/)
endif()
########### install files ###############
install (PROGRAMS krfb.desktop
install (PROGRAMS org.kde.krfb.desktop
DESTINATION ${XDG_APPS_INSTALL_DIR}
)
install(FILES org.kde.krfb.appdata.xml
DESTINATION ${KDE_INSTALL_METAINFODIR}
)
install (FILES krfb.notifyrc
DESTINATION ${DATA_INSTALL_DIR}/krfb
)

View File

@@ -21,20 +21,33 @@
#include "connectiondialog.h"
#include <KIconLoader>
#include <KLocale>
#include <KStandardGuiItem>
#include <QCheckBox>
#include <QIcon>
#include <QtGui/QCheckBox>
#include <QtGui/QLabel>
#include <KLocalizedString>
#include <KStandardGuiItem>
#include <KConfigGroup>
#include <QDialogButtonBox>
#include <QPushButton>
#include <KGuiItem>
#include <QVBoxLayout>
template <typename UI>
ConnectionDialog<UI>::ConnectionDialog(QWidget *parent)
: KDialog(parent)
: QDialog(parent)
{
setCaption(i18n("New Connection"));
setButtons(Ok | Cancel);
setDefaultButton(Cancel);
setWindowTitle(i18n("New Connection"));
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
QWidget *mainWidget = new QWidget(this);
QVBoxLayout *mainLayout = new QVBoxLayout;
setLayout(mainLayout);
mainLayout->addWidget(mainWidget);
QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
okButton->setDefault(true);
okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
connect(buttonBox, &QDialogButtonBox::accepted, this, &ConnectionDialog<UI>::accept);
connect(buttonBox, &QDialogButtonBox::rejected, this, &ConnectionDialog<UI>::reject);
buttonBox->button(QDialogButtonBox::Cancel)->setDefault(true);
setModal(true);
setMinimumSize(500, 200);
@@ -42,17 +55,18 @@ ConnectionDialog<UI>::ConnectionDialog(QWidget *parent)
m_connectWidget = new QWidget(this);
m_ui.setupUi(m_connectWidget);
m_ui.pixmapLabel->setPixmap(KIcon("krfb").pixmap(128));
m_ui.pixmapLabel->setPixmap(QIcon::fromTheme("krfb").pixmap(128));
KGuiItem accept = KStandardGuiItem::ok();
accept.setText(i18n("Accept Connection"));
setButtonGuiItem(Ok, accept);
KGuiItem::assign(okButton, accept);
KGuiItem refuse = KStandardGuiItem::cancel();
refuse.setText(i18n("Refuse Connection"));
setButtonGuiItem(Cancel, refuse);
KGuiItem::assign(buttonBox->button(QDialogButtonBox::Cancel), refuse);
setMainWidget(m_connectWidget);
mainLayout->addWidget(m_connectWidget);
mainLayout->addWidget(buttonBox);
}
//**********
@@ -69,20 +83,4 @@ void InvitationsConnectionDialog::setRemoteHost(const QString &host)
//**********
#ifdef KRFB_WITH_TELEPATHY_TUBES
TubesConnectionDialog::TubesConnectionDialog(QWidget *parent)
: ConnectionDialog<Ui::TubesConnectionWidget>(parent)
{
}
void TubesConnectionDialog::setContactName(const QString & name)
{
QString txt = i18n("You have requested to share your desktop with %1. If you proceed, "
"you will allow the remote user to watch your desktop.", name);
m_ui.mainTextLabel->setText(txt);
}
#endif // KRFB_WITH_TELEPATHY_TUBES
#include "connectiondialog.moc"

View File

@@ -23,10 +23,10 @@
#define CONNECTIONDIALOG_H
#include "ui_connectionwidget.h"
#include <KDialog>
#include <QDialog>
template <typename UI>
class ConnectionDialog : public KDialog
class ConnectionDialog : public QDialog
{
public:
ConnectionDialog(QWidget *parent);
@@ -65,18 +65,5 @@ public:
//*********
#ifdef KRFB_WITH_TELEPATHY_TUBES
# include "ui_tubesconnectionwidget.h"
class TubesConnectionDialog : public ConnectionDialog<Ui::TubesConnectionWidget>
{
Q_OBJECT
public:
TubesConnectionDialog(QWidget *parent);
void setContactName(const QString & name);
};
#endif // KRFB_WITH_TELEPATHY_TUBES
#endif // CONNECTIONDIALOG_H

View File

@@ -24,10 +24,10 @@
#include "events.h"
#include <QtGui/QApplication>
#include <QtGui/QX11Info>
#include <QtGui/QDesktopWidget>
#include <KGlobal>
#include <QApplication>
#include <QX11Info>
#include <QDesktopWidget>
#include <QGlobalStatic>
#include <X11/Xutil.h>
#include <X11/keysym.h>
@@ -60,7 +60,7 @@ private:
void init();
};
K_GLOBAL_STATIC(EventData, data)
Q_GLOBAL_STATIC(EventData, data)
EventData::EventData()
{

View File

@@ -12,19 +12,19 @@
#include "rfb.h"
#include <kdemacros.h>
#include "krfbprivate_export.h"
#include <QtCore/QObject>
#include <QtCore/QRect>
#include <QtCore/QList>
#include <QWidget>
#include <QtGui/QWidget>
class FrameBuffer;
/**
@author Alessandro Praduroux <pradu@pradu.it>
*/
class KDE_EXPORT FrameBuffer : public QObject
class KRFBPRIVATE_EXPORT FrameBuffer : public QObject
{
Q_OBJECT
public:

View File

@@ -23,9 +23,12 @@
#include "framebufferplugin.h"
#include "krfbconfig.h"
#include <KDebug>
#include <KGlobal>
#include <KServiceTypeTrader>
#include <QDebug>
#include <QGlobalStatic>
#include <KPluginFactory>
#include <KPluginLoader>
#include <KPluginMetaData>
#include <QtCore/QSharedPointer>
@@ -35,71 +38,75 @@ public:
FrameBufferManager instance;
};
K_GLOBAL_STATIC(FrameBufferManagerStatic, frameBufferManagerStatic)
Q_GLOBAL_STATIC(FrameBufferManagerStatic, frameBufferManagerStatic)
FrameBufferManager::FrameBufferManager()
{
kDebug();
//qDebug();
loadPlugins();
}
FrameBufferManager::~FrameBufferManager()
{
kDebug();
//qDebug();
}
FrameBufferManager *FrameBufferManager::instance()
{
kDebug();
//qDebug();
return &frameBufferManagerStatic->instance;
}
void FrameBufferManager::loadPlugins()
{
kDebug();
//qDebug();
// Load the all the plugin factories here, for use later.
KService::List offers = KServiceTypeTrader::self()->query("krfb/framebuffer");
const QVector<KPluginMetaData> plugins = KPluginLoader::findPlugins(QStringLiteral("krfb"), [](const KPluginMetaData & md) {
return md.serviceTypes().contains(QStringLiteral("krfb/framebuffer"));
});
KService::List::const_iterator iter;
for (iter = offers.constBegin(); iter < offers.constEnd(); ++iter) {
QString error;
KService::Ptr service = *iter;
KPluginFactory *factory = KPluginLoader(service->library()).factory();
QVectorIterator<KPluginMetaData> i(plugins);
i.toBack();
QSet<QString> unique;
while (i.hasPrevious()) {
const KPluginMetaData &data = i.previous();
// only load plugins once, even if found multiple times!
if (unique.contains(data.name()))
continue;
KPluginFactory *factory = KPluginLoader(data.fileName()).factory();
if (!factory) {
kWarning() << "KPluginFactory could not load the plugin:" << service->library();
continue;
qDebug() << "KPluginFactory could not load the plugin:" << data.fileName();
} else {
qDebug() << "found plugin at " << data.fileName();
}
FrameBufferPlugin *plugin = factory->create<FrameBufferPlugin>(this);
if (plugin) {
kDebug() << "Loaded plugin:" << service->name();
m_plugins.insert(service->library(), plugin);
m_plugins.insert(data.pluginId(), plugin);
qDebug() << "Loaded plugin with name " << data.pluginId();
} else {
kDebug() << error;
qDebug() << "unable to load pluign for " << data.fileName();
}
unique.insert (data.name());
}
}
QSharedPointer<FrameBuffer> FrameBufferManager::frameBuffer(WId id)
{
kDebug();
//qDebug();
// See if there is still an existing framebuffer to this WId.
if (m_frameBuffers.contains(id)) {
QWeakPointer<FrameBuffer> weakFrameBuffer = m_frameBuffers.value(id);
if (weakFrameBuffer) {
kDebug() << "Found cached frame buffer.";
//qDebug() << "Found cached frame buffer.";
return weakFrameBuffer.toStrongRef();
} else {
kDebug() << "Found deleted cached frame buffer. Don't use.";
//qDebug() << "Found deleted cached frame buffer. Don't use.";
m_frameBuffers.remove(id);
}
}
@@ -110,7 +117,7 @@ QSharedPointer<FrameBuffer> FrameBufferManager::frameBuffer(WId id)
while (iter != m_plugins.constEnd()) {
if (iter.key() == KrfbConfig::preferredFrameBufferPlugin()) {
kDebug() << "Using FrameBuffer:" << KrfbConfig::preferredFrameBufferPlugin();
qDebug() << "Using FrameBuffer:" << KrfbConfig::preferredFrameBufferPlugin();
QSharedPointer<FrameBuffer> frameBuffer(iter.value()->frameBuffer(id));
@@ -125,7 +132,7 @@ QSharedPointer<FrameBuffer> FrameBufferManager::frameBuffer(WId id)
}
// No valid framebuffer plugin found.
kDebug() << "No valid framebuffer found. returning null.";
qDebug() << "No valid framebuffer found. returning null.";
return QSharedPointer<FrameBuffer>();
}

View File

@@ -23,19 +23,19 @@
#include "framebuffer.h"
#include <kdemacros.h>
#include "krfbprivate_export.h"
#include <QtCore/QMap>
#include <QtCore/QObject>
#include <QtCore/QSharedPointer>
#include <QtCore/QWeakPointer>
#include <QtGui/QWidget>
#include <QWidget>
class FrameBufferPlugin;
class KPluginFactory;
class KDE_EXPORT FrameBufferManager : public QObject
class KRFBPRIVATE_EXPORT FrameBufferManager : public QObject
{
Q_OBJECT
friend class FrameBufferManagerStatic;

View File

@@ -21,15 +21,15 @@
#ifndef LIB_KRFB_FRAMEBUFFERPLUGIN_H
#define LIB_KRFB_FRAMEBUFFERPLUGIN_H
#include <kdemacros.h>
#include "krfbprivate_export.h"
#include <QtCore/QVariantList>
#include <QWidget>
#include <QtGui/QWidget>
class FrameBuffer;
class KDE_EXPORT FrameBufferPlugin : public QObject
class KRFBPRIVATE_EXPORT FrameBufferPlugin : public QObject
{
Q_OBJECT
@@ -40,6 +40,5 @@ public:
virtual FrameBuffer *frameBuffer(WId id) = 0;
};
#endif // Header guard

View File

@@ -1,120 +0,0 @@
/***************************************************************************
Copyright 2002 Tim Jansen <tim@tjansen.de>
Copyright 2002 Stefan Taferner <taferner@kde.org>
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "invitation.h"
#include <KConfigGroup>
#include <KDebug>
#include <KRandom>
#include <KStringHandler>
// a random string that doesn't contain i, I, o, O, 1, 0
// based on KRandom::randomString()
static QString readableRandomString(int length)
{
QString str;
while (length) {
int r = KRandom::random() % 62;
r += 48;
if (r > 57) {
r += 7;
}
if (r > 90) {
r += 6;
}
char c = char(r);
if ((c == 'i') ||
(c == 'I') ||
(c == '1') ||
(c == 'o') ||
(c == 'O') ||
(c == '0')) {
continue;
}
str += c;
length--;
}
return str;
}
Invitation::Invitation()
{
m_password = readableRandomString(4) + '-' + readableRandomString(3);
m_creationTime = QDateTime::currentDateTime();
m_expirationTime = QDateTime::currentDateTime().addSecs(INVITATION_DURATION);
}
Invitation::Invitation(const Invitation &x)
: m_password(x.m_password), m_creationTime(x.m_creationTime), m_expirationTime(x.m_expirationTime)
{
}
Invitation::Invitation(const KConfigGroup &config)
{
m_password = KStringHandler::obscure(config.readEntry("password", QString()));
kDebug() << "read: " << config.readEntry("password", QString()) << " = " << m_password;
m_creationTime = config.readEntry("creation", QDateTime());
m_expirationTime = config.readEntry("expiration", QDateTime());
}
Invitation::~Invitation()
{
}
Invitation &Invitation::operator= (const Invitation &x)
{
m_password = x.m_password;
m_creationTime = x.m_creationTime;
m_expirationTime = x.m_expirationTime;
return *this;
}
void Invitation::save(KConfigGroup &config) const
{
config.writeEntry("password", KStringHandler::obscure(m_password));
config.writeEntry("creation", m_creationTime);
config.writeEntry("expiration", m_expirationTime);
}
QString Invitation::password() const
{
return m_password;
}
QDateTime Invitation::expirationTime() const
{
return m_expirationTime;
}
QDateTime Invitation::creationTime() const
{
return m_creationTime;
}
bool Invitation::isValid() const
{
return m_expirationTime > QDateTime::currentDateTime();
}
bool Invitation::operator ==(const Invitation &ot)
{
return m_creationTime == ot.m_creationTime && m_password == ot.m_password;
}

View File

@@ -1,53 +0,0 @@
/***************************************************************************
invitation.h
-------------------
begin : Sat Mar 30 2002
copyright : (C) 2002 by Tim Jansen
email : tim@tjansen.de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef INVITATION_H
#define INVITATION_H
#include <KApplication>
#include <KConfig>
#include <QtCore/QDateTime>
#include <QtCore/QObject>
const int INVITATION_DURATION = 60 * 60;
class Invitation
{
public:
Invitation();
~Invitation();
Invitation(const KConfigGroup &config);
Invitation(const Invitation &x);
Invitation &operator= (const Invitation &x);
bool operator == (const Invitation &ot);
QString password() const;
QDateTime expirationTime() const;
QDateTime creationTime() const;
bool isValid() const;
void save(KConfigGroup &config) const;
private:
QString m_password;
QDateTime m_creationTime;
QDateTime m_expirationTime;
};
#endif

View File

@@ -1,130 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#include "invitationmanager.h"
#include "invitationmanager.moc"
#include <KConfigGroup>
#include <KConfig>
#include <KGlobal>
#include <QtCore/QTimer>
class InvitationManagerPrivate
{
public:
InvitationManager instance;
};
K_GLOBAL_STATIC(InvitationManagerPrivate, invitationManagerPrivate)
InvitationManager *InvitationManager::self()
{
return &invitationManagerPrivate->instance;
}
InvitationManager::InvitationManager()
{
loadInvitations();
QTimer *refreshTimer = new QTimer(this);
connect(refreshTimer, SIGNAL(timeout()), SLOT(loadInvitations()));
refreshTimer->start(1000 * 60);
}
InvitationManager::~InvitationManager()
{
}
void InvitationManager::invalidateOldInvitations()
{
int invNum = invitationList.size();
while (invNum--) {
if (!invitationList[invNum].isValid()) {
invitationList.removeAt(invNum);
}
}
saveInvitations();
}
void InvitationManager::loadInvitations()
{
int invNum = invitationList.size();
KSharedConfigPtr conf = KGlobal::config();
KConfigGroup invitationConfig(conf, "Invitations");
int numInv = invitationConfig.readEntry("invitation_num", 0);
invitationList.clear();
for (int i = 0; i < numInv; i++) {
KConfigGroup ic(conf, QString("Invitation_%1").arg(i));
invitationList.append(Invitation(ic));
}
invalidateOldInvitations();
if (numInv != invNum) {
emit invitationNumChanged(invitationList.size());
}
}
Invitation InvitationManager::addInvitation()
{
Invitation i;
invitationList.append(i);
emit invitationNumChanged(invitationList.size());
saveInvitations();
return i;
}
const QList< Invitation > & InvitationManager::invitations()
{
return invitationList;
}
void InvitationManager::saveInvitations()
{
KSharedConfigPtr conf = KGlobal::config();
KConfigGroup invitationConfig(conf, "Invitations");
int invNum = invitationList.size();
invitationConfig.writeEntry("invitation_num", invNum);
for (int i = 0; i < invNum; i++) {
KConfigGroup ic(conf, QString("Invitation_%1").arg(i));
invitationList[i].save(ic);
}
conf->sync();
}
int InvitationManager::activeInvitations()
{
invalidateOldInvitations();
return invitationList.size();
}
void InvitationManager::removeInvitation(const Invitation &inv)
{
invitationList.removeAll(inv);
saveInvitations();
emit invitationNumChanged(invitationList.size());
}
void InvitationManager::removeAllInvitations()
{
invitationList.clear();
saveInvitations();
emit invitationNumChanged(invitationList.size());
}

View File

@@ -1,58 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#ifndef INVITATIONMANAGER_H
#define INVITATIONMANAGER_H
#include "invitation.h"
#include <QtCore/QList>
#include <QtCore/QObject>
class InvitationManagerPrivate;
/**
@author Alessandro Praduroux <pradu@pradu.it>
*/
class InvitationManager : public QObject
{
Q_OBJECT
friend class InvitationManagerPrivate;
public:
static InvitationManager *self();
~InvitationManager();
Invitation addInvitation();
int activeInvitations();
void removeInvitation(const Invitation &inv);
void removeAllInvitations();
const QList<Invitation> &invitations();
signals:
void invitationNumChanged(int);
public Q_SLOTS:
void loadInvitations();
void saveInvitations();
private:
void invalidateOldInvitations();
InvitationManager();
static InvitationManager *_self;
QList<Invitation> invitationList;
};
#endif

View File

@@ -18,72 +18,63 @@
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rfb.h"
#include "invitationsrfbclient.h"
#include "invitationmanager.h"
#include "invitationsrfbserver.h"
#include "krfbconfig.h"
#include "sockethelpers.h"
#include "connectiondialog.h"
#include <KNotification>
#include <KLocale>
#include <KLocalizedString>
bool InvitationsRfbClient::checkPassword(const QByteArray & encryptedPassword)
#include <QDebug>
#include <QtCore/QSocketNotifier>
#include <poll.h>
#include <KConfigGroup>
struct PendingInvitationsRfbClient::Private
{
bool allowUninvited = KrfbConfig::allowUninvitedConnections();
QByteArray password = KrfbConfig::uninvitedConnectionPassword().toLocal8Bit();
Private(rfbClientPtr client) :
client(client),
askOnConnect(true)
{}
bool authd = false;
kDebug() << "about to start autentication";
rfbClientPtr client;
QSocketNotifier *notifier;
bool askOnConnect;
};
if (allowUninvited) {
authd = vncAuthCheckPassword(password, encryptedPassword);
}
static void clientGoneHookNoop(rfbClientPtr cl) { Q_UNUSED(cl); }
if (!authd) {
QList<Invitation> invlist = InvitationManager::self()->invitations();
foreach(const Invitation & it, invlist) {
kDebug() << "checking password";
if (vncAuthCheckPassword(it.password().toLocal8Bit(), encryptedPassword)
&& it.isValid())
{
authd = true;
InvitationManager::self()->removeInvitation(it);
break;
}
}
}
if (!authd) {
if (InvitationManager::self()->invitations().size() > 0) {
KNotification::event("InvalidPasswordInvitations",
i18n("Failed login attempt from %1: wrong password", name()));
} else {
KNotification::event("InvalidPassword",
i18n("Failed login attempt from %1: wrong password", name()));
}
return false;
}
return true;
PendingInvitationsRfbClient::PendingInvitationsRfbClient(rfbClientPtr client, QObject *parent) :
PendingRfbClient(client, parent),
d(new Private(client))
{
d->client->clientGoneHook = clientGoneHookNoop;
d->notifier = new QSocketNotifier(client->sock, QSocketNotifier::Read, this);
d->notifier->setEnabled(true);
connect(d->notifier, &QSocketNotifier::activated,
this, &PendingInvitationsRfbClient::onSocketActivated);
}
PendingInvitationsRfbClient::~PendingInvitationsRfbClient()
{
delete d;
}
void PendingInvitationsRfbClient::processNewClient()
{
QString host = peerAddress(m_rfbClient->sock) + ":" + QString::number(peerPort(m_rfbClient->sock));
bool allowUninvited = KrfbConfig::allowUninvitedConnections();
if (!allowUninvited && InvitationManager::self()->activeInvitations() == 0) {
KNotification::event("UnexpectedConnection",
i18n("Refused uninvited connection attempt from %1", host));
reject();
} else if (!KrfbConfig::askOnConnect()) {
if (d->askOnConnect == false) {
KNotification::event("NewConnectionAutoAccepted",
i18n("Accepted connection from %1", host));
accept(new InvitationsRfbClient(m_rfbClient, parent()));
} else {
KNotification::event("NewConnectionOnHold",
i18n("Received connection from %1, on hold (waiting for confirmation)",
host));
@@ -92,13 +83,63 @@ void PendingInvitationsRfbClient::processNewClient()
dialog->setRemoteHost(host);
dialog->setAllowRemoteControl(KrfbConfig::allowDesktopControl());
connect(dialog, SIGNAL(okClicked()), SLOT(dialogAccepted()));
connect(dialog, SIGNAL(cancelClicked()), SLOT(reject()));
connect(dialog, &InvitationsConnectionDialog::accepted, this, &PendingInvitationsRfbClient::dialogAccepted);
connect(dialog, &InvitationsConnectionDialog::rejected, this, &PendingInvitationsRfbClient::reject);
dialog->show();
}
}
void PendingInvitationsRfbClient::onSocketActivated()
{
//Process not only one, but all pending messages.
//poll() idea/code copied from vino:
// Copyright (C) 2003 Sun Microsystems, Inc.
// License: GPL v2 or later
struct pollfd pollfd = { d->client->sock, POLLIN|POLLPRI, 0 };
while(poll(&pollfd, 1, 0) == 1) {
if(d->client->state == rfbClientRec::RFB_INITIALISATION) {
d->notifier->setEnabled(false);
//Client is Authenticated
processNewClient();
break;
}
rfbProcessClientMessage(d->client);
//This is how we handle disconnection.
//if rfbProcessClientMessage() finds out that it can't read the socket,
//it closes it and sets it to -1. So, we just have to check this here
//and call rfbClientConnectionGone() if necessary. This will call
//the clientGoneHook which in turn will remove this RfbClient instance
//from the server manager and will call deleteLater() to delete it
if (d->client->sock == -1) {
qDebug() << "disconnected from socket signal";
d->notifier->setEnabled(false);
rfbClientConnectionGone(d->client);
break;
}
}
}
bool PendingInvitationsRfbClient::checkPassword(const QByteArray & encryptedPassword)
{
QByteArray password ;
qDebug() << "about to start autentication";
if(InvitationsRfbServer::instance->allowUnattendedAccess() && vncAuthCheckPassword(
InvitationsRfbServer::instance->unattendedPassword().toLocal8Bit(),
encryptedPassword) ) {
d->askOnConnect = false;
return true;
}
return vncAuthCheckPassword(
InvitationsRfbServer::instance->desktopPassword().toLocal8Bit(),
encryptedPassword);
}
void PendingInvitationsRfbClient::dialogAccepted()
{
InvitationsConnectionDialog *dialog = qobject_cast<InvitationsConnectionDialog *>(sender());

View File

@@ -25,9 +25,6 @@ class InvitationsRfbClient : public RfbClient
public:
InvitationsRfbClient(rfbClientPtr client, QObject* parent = 0)
: RfbClient(client, parent) {}
protected:
virtual bool checkPassword(const QByteArray & encryptedPassword);
};
@@ -35,14 +32,20 @@ class PendingInvitationsRfbClient : public PendingRfbClient
{
Q_OBJECT
public:
PendingInvitationsRfbClient(rfbClientPtr client, QObject *parent = 0)
: PendingRfbClient(client, parent) {}
PendingInvitationsRfbClient(rfbClientPtr client, QObject *parent = 0);
virtual ~PendingInvitationsRfbClient();
protected Q_SLOTS:
virtual void processNewClient();
void processNewClient() override;
virtual void onSocketActivated();
bool checkPassword(const QByteArray & encryptedPassword) override;
private Q_SLOTS:
void dialogAccepted();
private:
struct Private;
Private* const d;
};
#endif // INVITATIONSRFBCLIENT_H

View File

@@ -23,22 +23,129 @@
#include "krfbconfig.h"
#include "rfbservermanager.h"
#include <QtCore/QTimer>
#include <QtGui/QApplication>
#include <QApplication>
#include <QtNetwork/QHostInfo>
#include <KNotification>
#include <KLocale>
#include <KMessageBox>
#include <KUser>
#include <DNSSD/PublicService>
#include <QDebug>
#include <KLocalizedString>
#include <KUser>
#include <KRandom>
#include <KStringHandler>
#include <KWallet/KWallet>
#include <dnssd/publicservice.h>
using KWallet::Wallet;
//static
InvitationsRfbServer *InvitationsRfbServer::instance;
//static
void InvitationsRfbServer::init()
{
InvitationsRfbServer *server;
server = new InvitationsRfbServer;
server->setListeningPort(KrfbConfig::port());
server->setListeningAddress("0.0.0.0"); // Listen on all available network addresses
server->setPasswordRequired(true);
QTimer::singleShot(0, server, SLOT(startAndCheck()));
instance = new InvitationsRfbServer;
instance->m_publicService = new KDNSSD::PublicService(
i18n("%1@%2 (shared desktop)",
KUser().loginName(),
QHostInfo::localHostName()),
"_rfb._tcp",
KrfbConfig::port());
instance->setListeningAddress("0.0.0.0");
instance->setListeningPort(KrfbConfig::port());
instance->setPasswordRequired(true);
if (KrfbConfig::noWallet()) {
instance->walletOpened(false);
}
else {
instance->m_wallet = Wallet::openWallet(
Wallet::NetworkWallet(), 0, Wallet::Asynchronous);
if(instance->m_wallet) {
connect(instance->m_wallet, &KWallet::Wallet::walletOpened,
instance, &InvitationsRfbServer::walletOpened);
}
}
}
const QString& InvitationsRfbServer::desktopPassword() const
{
return m_desktopPassword;
}
void InvitationsRfbServer::setDesktopPassword(const QString& password)
{
m_desktopPassword = password;
}
const QString& InvitationsRfbServer::unattendedPassword() const
{
return m_unattendedPassword;
}
void InvitationsRfbServer::setUnattendedPassword(const QString& password)
{
m_unattendedPassword = password;
}
bool InvitationsRfbServer::allowUnattendedAccess() const
{
return m_allowUnattendedAccess;
}
bool InvitationsRfbServer::start()
{
if(RfbServer::start()) {
if(KrfbConfig::publishService())
m_publicService->publishAsync();
return true;
}
return false;
}
void InvitationsRfbServer::stop()
{
if(m_publicService->isPublished())
m_publicService->stop();
RfbServer::stop();
}
void InvitationsRfbServer::toggleUnattendedAccess(bool allow)
{
m_allowUnattendedAccess = allow;
}
InvitationsRfbServer::InvitationsRfbServer()
{
m_desktopPassword = readableRandomString(4)+"-"+readableRandomString(3);
m_unattendedPassword = readableRandomString(4)+"-"+readableRandomString(3);
KConfigGroup krfbConfig(KSharedConfig::openConfig(),"Security");
m_allowUnattendedAccess = krfbConfig.readEntry(
"allowUnattendedAccess", QVariant(false)).toBool();
}
InvitationsRfbServer::~InvitationsRfbServer()
{
stop();
KConfigGroup krfbConfig(KSharedConfig::openConfig(),"Security");
krfbConfig.writeEntry("allowUnattendedAccess",m_allowUnattendedAccess);
if(!KrfbConfig::noWallet()) {
if (m_wallet && m_wallet->isOpen()) {
if( (m_wallet->currentFolder()=="krfb") ||
((m_wallet->hasFolder("krfb") || m_wallet->createFolder("krfb")) &&
m_wallet->setFolder("krfb")) ) {
m_wallet->writePassword("desktopSharingPassword",m_desktopPassword);
m_wallet->writePassword("unattendedAccessPassword",m_unattendedPassword);
}
}
} else {
krfbConfig.writeEntry("desktopPassword",
KStringHandler::obscure(m_desktopPassword));
krfbConfig.writeEntry("unattendedPassword",
KStringHandler::obscure(m_unattendedPassword));
krfbConfig.writeEntry("allowUnattendedAccess",
m_allowUnattendedAccess);
}
}
PendingRfbClient* InvitationsRfbServer::newClient(rfbClientPtr client)
@@ -46,26 +153,75 @@ PendingRfbClient* InvitationsRfbServer::newClient(rfbClientPtr client)
return new PendingInvitationsRfbClient(client, this);
}
void InvitationsRfbServer::startAndCheck()
void InvitationsRfbServer::walletOpened(bool opened)
{
if (!start()) {
KMessageBox::error(0, i18n("Failed to start the krfb server. Invitation-based sharing "
"will not work. Try setting another port in the settings and "
"restart krfb."));
} else {
//publish service
if (KrfbConfig::publishService()) {
DNSSD::PublicService *service = new DNSSD::PublicService(i18n("%1@%2 (shared desktop)",
KUser().loginName(),
QHostInfo::localHostName()),
"_rfb._tcp",
listeningPort());
service->publishAsync();
QString desktopPassword;
QString unattendedPassword;
Q_ASSERT(m_wallet);
if( opened &&
( m_wallet->hasFolder("krfb") || m_wallet->createFolder("krfb") ) &&
m_wallet->setFolder("krfb") ) {
if(m_wallet->readPassword("desktopSharingPassword", desktopPassword)==0 &&
!desktopPassword.isEmpty()) {
m_desktopPassword = desktopPassword;
emit passwordChanged(m_desktopPassword);
}
if(m_wallet->readPassword("unattendedAccessPassword", unattendedPassword)==0 &&
!unattendedPassword.isEmpty()) {
m_unattendedPassword = unattendedPassword;
}
} else {
qDebug() << "Could not open KWallet, Falling back to config file";
KConfigGroup krfbConfig(KSharedConfig::openConfig(),"Security");
desktopPassword = KStringHandler::obscure(krfbConfig.readEntry(
"desktopPassword", QString()));
if(!desktopPassword.isEmpty()) {
m_desktopPassword = desktopPassword;
emit passwordChanged(m_desktopPassword);
}
unattendedPassword = KStringHandler::obscure(krfbConfig.readEntry(
"unattendedPassword", QString()));
if(!unattendedPassword.isEmpty()) {
m_unattendedPassword = unattendedPassword;
}
//disconnect when qApp quits
connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(stop()));
}
}
// a random string that doesn't contain i, I, o, O, 1, l, 0
// based on KRandom::randomString()
QString InvitationsRfbServer::readableRandomString(int length)
{
QString str;
while (length) {
int r = KRandom::random() % 62;
r += 48;
if (r > 57) {
r += 7;
}
if (r > 90) {
r += 6;
}
char c = char(r);
if ((c == 'i') ||
(c == 'I') ||
(c == '1') ||
(c == 'l') ||
(c == 'o') ||
(c == 'O') ||
(c == '0')) {
continue;
}
str += c;
length--;
}
return str;
}
#include "invitationsrfbserver.moc"

View File

@@ -22,21 +22,51 @@
#include "rfbserver.h"
namespace KWallet {
class Wallet;
}
namespace KDNSSD {
class PublicService;
}
class InvitationsRfbServer : public RfbServer
{
Q_OBJECT
public:
static InvitationsRfbServer *instance;
static void init();
protected:
InvitationsRfbServer() : RfbServer(0) {}
const QString& desktopPassword() const;
void setDesktopPassword(const QString&);
const QString& unattendedPassword() const;
void setUnattendedPassword(const QString&);
bool allowUnattendedAccess() const;
virtual PendingRfbClient* newClient(rfbClientPtr client);
Q_SIGNALS:
void passwordChanged(const QString&);
public Q_SLOTS:
bool start() override;
void stop() override;
void toggleUnattendedAccess(bool allow);
protected:
InvitationsRfbServer();
virtual ~InvitationsRfbServer();
PendingRfbClient* newClient(rfbClientPtr client) override;
private Q_SLOTS:
void startAndCheck();
void walletOpened(bool);
private:
KDNSSD::PublicService *m_publicService;
bool m_allowUnattendedAccess;
QString m_desktopPassword;
QString m_unattendedPassword;
KWallet::Wallet *m_wallet;
QString readableRandomString(int);
Q_DISABLE_COPY(InvitationsRfbServer)
};

View File

@@ -1,87 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Nadeem Hasan <nhasan@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "invitedialog.h"
#include <KIconLoader>
#include <KLocale>
#include <KStandardGuiItem>
#include <QtGui/QCursor>
#include <QtGui/QLabel>
#include <QtGui/QPushButton>
#include <QtGui/QToolTip>
InviteDialog::InviteDialog(QWidget *parent)
: KDialog(parent)
{
setCaption(i18n("Invitation"));
setButtons(User1 | Close | Help);
setHelp(QString(), "krfb");
setDefaultButton(NoDefault);
setMinimumSize(500, 300);
m_inviteWidget = new QWidget(this);
setupUi(m_inviteWidget);
pixmapLabel->setPixmap(KIcon("krfb").pixmap(128));
setMainWidget(m_inviteWidget);
setButtonGuiItem(User1, KStandardGuiItem::configure());
connect(btnCreateInvite, SIGNAL(clicked()),
SIGNAL(createInviteClicked()));
connect(btnEmailInvite, SIGNAL(clicked()),
SIGNAL(emailInviteClicked()));
connect(btnManageInvite, SIGNAL(clicked()),
SIGNAL(manageInviteClicked()));
connect(helpLabel, SIGNAL(linkActivated(QString)),
SLOT(showWhatsthis()));
}
void InviteDialog::slotUser1()
{
emit configureClicked();
}
void InviteDialog::enableInviteButton(bool enable)
{
btnCreateInvite->setEnabled(enable);
}
void InviteDialog::setInviteCount(int count)
{
btnManageInvite->setText(
i18n("&Manage Invitations (%1)...", count));
}
void InviteDialog::showWhatsthis()
{
QToolTip::showText(QCursor::pos(),
i18n("An invitation creates a one-time password that allows the receiver to connect to your desktop.\n"
"It is valid for only one successful connection and will expire after an hour if it has not been used. \n"
"When somebody connects to your computer a dialog will appear and ask you for permission.\n "
"The connection will not be established before you accept it. In this dialog you can also\n restrict "
"the other person to view your desktop only, without the ability to move your\n mouse pointer or press "
"keys.\nIf you want to create a permanent password for Desktop Sharing, allow 'Uninvited Connections' \n"
"in the configuration."));
}
#include "invitedialog.moc"

View File

@@ -1,57 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Nadeem Hasan <nhasan@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef INVITEDIALOG_H
#define INVITEDIALOG_H
#include "ui_invitewidget.h"
#include <KDialog>
class QWidget;
class InviteDialog : public KDialog, public Ui::InviteWidget
{
Q_OBJECT
public:
InviteDialog(QWidget *parent);
~InviteDialog() {}
void enableInviteButton(bool enable);
public Q_SLOTS:
void setInviteCount(int count);
void showWhatsthis();
signals:
void createInviteClicked();
void emailInviteClicked();
void manageInviteClicked();
void configureClicked();
protected Q_SLOTS:
void slotUser1();
protected:
QWidget *m_inviteWidget;
};
#endif // INVITEDIALOG_H

View File

@@ -3,7 +3,7 @@ Type=ServiceType
X-KDE-ServiceType=krfb/framebuffer
Comment=Frame Buffer plugins for KRfb
Comment[ast]=Complementu de buffer pa KRfb
Comment[ast]=Complementos del búfer de cuadros pa KRfb
Comment[bg]=Приставки за фреймбуфер за KRfb
Comment[bs]=Priključci framebafera za KRfb
Comment[ca]=Connectors de «framebuffer» per al KRfb.
@@ -19,7 +19,7 @@ Comment[eu]=Irteerako bideoaren pluginak KRfb-rentzako
Comment[fi]=Kehyspuskuriliitännäinen kohteelle KRfb
Comment[fr]=Modules externes de sortie vidéo pour Krfb
Comment[ga]=Breiseáin Mhaoláin Fráma le haghaidh KRfb
Comment[gl]=Engadido de frame buffer para KRfb
Comment[gl]=Complementos de búfer de fotograma para KRfb
Comment[hr]=Priključci za međuspremnike okvira za KRfb
Comment[hu]=Framebuffer bővítmények a Krfb-hez
Comment[ia]=Plug-ins de Frame Buffer per KRfb
@@ -28,7 +28,7 @@ Comment[ja]=KRfb の フレームバッファプラグイン
Comment[kk]=KRfb кадр буфер плагині
Comment[km]=កម្មវិធី​ជំនួយ​ Frame Buffer សម្រាប់ KRfb
Comment[ko]=KRfb 프레임버퍼 플러그인
Comment[lt]=Frame Buffer priedai skirti KRfb
Comment[lt]=Frame Buffer papildiniai skirti KRfb
Comment[lv]=Kadru bufera sprudņi priekš KRfb
Comment[nb]=Rammebuffer-programtillegg for KRfb
Comment[nds]=Bildpuffer-Modulen för KRfb

View File

@@ -0,0 +1,39 @@
{
"KPlugin": {
"Description": "Frame Buffer plugins for KRfb",
"Description[ast]": "Complementos del búfer de cuadros pa KRfb",
"Description[ca@valencia]": "Connectors de «framebuffer» per al KRfb.",
"Description[ca]": "Connectors de «framebuffer» per al KRfb.",
"Description[cs]": "Moduly Frame bufferu pro KRfb",
"Description[da]": "Framebuffer-plugins til KRfb",
"Description[de]": "Framebuffer-Module für KRfb",
"Description[el]": "Πρόσθετα μνήμης ανανέωσης βίντεο καρέ για το KRfb",
"Description[es]": "Complementos de framebuffer para KRfb",
"Description[et]": "KRfb kaadripuhvri pluginad",
"Description[fi]": "Kehyspuskuriliitännäinen kohteelle KRfb",
"Description[fr]": "Modules de tampons d'image pour KRfb",
"Description[gl]": "Complemento de búfer de fotograma para KRfb",
"Description[ia]": "Plug-ins de Frame Buffer per KRfb",
"Description[it]": "Estensioni del framebuffer per KRfb",
"Description[ko]": "KRfb 프레임버퍼 플러그인",
"Description[nl]": "Framebuffer-plugins voor KRfb",
"Description[nn]": "Biletbuffer-tillegg KRfb",
"Description[pl]": "Wtyczki buforów ramek dla KRfb",
"Description[pt]": "'Plugins' do 'Framebuffer' para o KRfb",
"Description[pt_BR]": "Plugins de framebuffers para o KRfb",
"Description[ru]": "Модули буфера кадров для KRfb",
"Description[sk]": "Frame Buffer modul pre KRfb",
"Description[sl]": "Vstavki slikovnih medpomnilnikov za KRfb",
"Description[sr@ijekavian]": "Прикључци кадробафера за КРФБ",
"Description[sr@ijekavianlatin]": "Priključci kadrobafera za KRFB",
"Description[sr@latin]": "Priključci kadrobafera za KRFB",
"Description[sr]": "Прикључци кадробафера за КРФБ",
"Description[sv]": "Insticksprogram med rambuffert för Krfb",
"Description[tr]": "KRfb için Çerçeve Tamponu eklentileri",
"Description[uk]": "Додатки буфера кадрів для KRfb",
"Description[x-test]": "xxFrame Buffer plugins for KRfbxx",
"Description[zh_CN]": "KRfb 的帧缓冲插件",
"Description[zh_TW]": "KRfb 的 Frame Buffer 外掛程式"
},
"X-KDE-ServiceType": "krfb/framebuffer"
}

View File

@@ -3,6 +3,12 @@
"http://www.kde.org/standards/kcfg/1.0/kcfg.xsd">
<kcfg>
<kcfgfile />
<group name="MainWindow">
<entry name="startMinimized" type="Bool">
<label>Start minimized</label>
<default>false</default>
</entry>
</group>
<group name="TCP">
<entry name="useDefaultPort" type="Bool">
<label>Use the default port for VNC (5900)</label>
@@ -18,26 +24,29 @@
</entry>
</group>
<group name="Security">
<entry name="noWallet" type="Bool">
<label>Do not store passwords in KWallet</label>
<default>false</default>
</entry>
<entry name="allowDesktopControl" type="Bool">
<label>Allow remote connections to manage the desktop.</label>
<default>true</default>
</entry>
<entry name="askOnConnect" type="Bool">
<label>Ask before allowing a remote connection.</label>
<default>true</default>
</entry>
<entry name="allowUninvitedConnections" type="Bool">
<entry name="allowUnattendedAccess" type="Bool">
<label>Allow connections without an invitation.</label>
<default>false</default>
</entry>
<entry name="uninvitedConnectionPassword" type="String">
<entry name="unattendedAccessPassword" type="String">
<label>Password for uninvited connections.</label>
</entry>
<entry name="desktopSharingPassword" type="String">
<label>Password for uninvited connections.</label>
</entry>
</group>
<group name="FrameBuffer">
<entry name="preferredFrameBufferPlugin" type="String">
<label>Preferred Frame Buffer Plugin</label>
<default>krfb_framebuffer_x11</default>
<default>xcb</default>
</entry>
</group>
</kcfg>

View File

@@ -3,13 +3,13 @@ IconName=krfb
Comment=Desktop Sharing
Comment[af]=Werkskerm Deeling
Comment[ar]=مشاركة سطح المكتب
Comment[ast]=Escritoriu compartíu
Comment[ast]=Compartición d'escritoriu
Comment[bg]=Споделяне на работния плот
Comment[bn]=ডেস্কটপ ভাগাভাগি
Comment[br]=Rannañ ar vurev
Comment[bs]=Dijeljenje radne površine
Comment[ca]=Compartició de l'escriptori
Comment[ca@valencia]=Compartició de l'escriptori
Comment[ca]=Compartir l'escriptori
Comment[ca@valencia]=Compartir l'escriptori
Comment[cs]=Sdílení pracovní plochy
Comment[cy]=Rhannu Penbwrdd
Comment[da]=Skrivebordsdeling
@@ -36,7 +36,7 @@ Comment[ja]=デスクトップ共有
Comment[kk]=Үстелді ортақтастыру
Comment[km]=ការ​ចែក​រំលែក​ផ្ទែ​តុ
Comment[ko]=데스크톱 공유
Comment[lt]=Dalinimasis darbastaliu
Comment[lt]=Dalinimasis darbalaukiu
Comment[lv]=Darbvirsmas koplietošana
Comment[mk]=Делење на работната површина
Comment[ml]=പണിയിടം പങ്കുവെക്കല്‍
@@ -358,7 +358,7 @@ Name[eu]=Konexioa itxi da
Name[fi]=Yhteys suljettu
Name[fr]=Connexion fermée
Name[ga]=Ceangal Dúnta
Name[gl]=Conexión fechada
Name[gl]=Conexión pechada
Name[hi]=कनेक्शन बन्द
Name[hne]=कनेक्सन बन्द
Name[hr]=Veza prekinuta
@@ -404,7 +404,7 @@ Name[zh_TW]=連線已關閉
Comment=Connection closed
Comment[af]=Verbinding gesluit
Comment[ar]=تمّ غلق الاتصال
Comment[ast]=Conexón zarrada
Comment[ast]=Zarróse la conexón
Comment[bg]=Връзката е прекъсната
Comment[bn]=সংযোগ বন্ধ করা হল
Comment[br]=Serret eo ar gevreadenn
@@ -424,7 +424,7 @@ Comment[eu]=Konexioa itxi da
Comment[fi]=Yhteys suljettu
Comment[fr]=Connexion fermée
Comment[ga]=Ceangal dúnta
Comment[gl]=A conexión está fechada
Comment[gl]=A conexión está pechada
Comment[he]=החיבור נסגר
Comment[hi]=कनेक्शन बन्द
Comment[hne]=कनेक्सन बन्द
@@ -480,7 +480,7 @@ Action=Popup
[Event/InvalidPassword]
Name=Invalid Password
Name[ar]=كلمة المرور غير صحيحة
Name[ast]=Contraseña incorreuta
Name[ast]=Contraseña non válida
Name[bg]=Неправилна парола
Name[bs]=Neispravna šifra
Name[ca]=Contrasenya no vàlida
@@ -543,7 +543,7 @@ Name[zh_TW]=不正確的密碼
Comment=Invalid password
Comment[af]=Ongeldige wagwoord
Comment[ar]=كلمة المرور غير صحيحة
Comment[ast]=Contraseña incorreuta
Comment[ast]=La contraseña nun ye válida
Comment[bg]=Неправилна парола
Comment[bn]=অবৈধ পাসওয়ার্ড
Comment[br]=Tremenger siek
@@ -622,7 +622,6 @@ Action=Popup
[Event/InvalidPasswordInvitations]
Name=Invalid Password Invitations
Name[ar]=كلمة المرور الدعوات غير صحيحة
Name[ast]=Contraseñas d'invitaciones incorreutes
Name[bg]=Неправилна парола за покана
Name[bs]=Neispravna šifra pozivnice
Name[ca]=Contrasenya de les invitacions no vàlides
@@ -683,7 +682,7 @@ Name[zh_TW]=不合法的密碼邀請
Comment=The invited party sent an invalid password. Connection refused.
Comment[af]=Die uitgenooi party gestuur 'n ongeldige wagwoord. Verbinding geweier.
Comment[ar]=المدعو أرسل كلمة مرور غير صحيحة. رفض الإتصال.
Comment[ast]=L'invitáu unvió una contraseña incorreuta. Conexón refugada.
Comment[ast]=La parte invitada unvió una contraseña non válida. Refugóse la conexón.
Comment[bg]=Поканената страна изпрати неправилна парола. Връзката е отказана.
Comment[bn]=আমন্ত্রিত দল একটি অবৈধ পাসওয়ার্ড পাঠাল। সংযোগ অস্বীকার করা হল।
Comment[bs]=Pozvana strana je poslala pogrešnu šifru. Veza je odbijena.
@@ -753,11 +752,11 @@ Action=Popup
[Event/NewConnectionOnHold]
Name=New Connection on Hold
Name[ar]=اتصال جديد على التوقف
Name[ast]=Conexón nueva a la espera
Name[ast]=Conexón nueva n'espera
Name[bg]=Изчакване на новата връзка
Name[bs]=Nova veza je na čekanju
Name[ca]=Nova connexió en espera
Name[ca@valencia]=Nova connexió en espera
Name[ca]=Connexió nova en espera
Name[ca@valencia]=Connexió nova en espera
Name[cs]=Nové spojení pozdrženo
Name[da]=Ny forbindelse sat til at vente
Name[de]=Neue Verbindung wartet
@@ -813,12 +812,12 @@ Name[zh_TW]=新連線等待處理
Comment=Connection requested, user must accept
Comment[af]=Verbinding versoekte, gebruiker moet aanvaar
Comment[ar]=الاتصال طلب، يجب موافقة المستخدم
Comment[ast]=Conexón solicitada, l'usuario tien d'aceutala
Comment[ast]=Solicitóse la conexón, l'usuariu ha aceutar
Comment[bg]=Поискана е връзка, следва потребителят да приеме
Comment[bn]=সংযোগ অনুরোধ করা হল, ব্যবহারকারীকে অবশ্যই স্বীকার করতে হবে
Comment[bs]=Veza je zahtijevana, korinik mora da je prihvati
Comment[ca]=Connexió sol·licitada, l'usuari ha d'acceptar-la
Comment[ca@valencia]=Connexió sol·licitada, l'usuari ha d'acceptar-la
Comment[ca]=Connexió sol·licitada, l'usuari l'ha d'acceptar
Comment[ca@valencia]=Connexió sol·licitada, l'usuari l'ha d'acceptar
Comment[cs]=Vyžadováno spojení, uživatel musí přijmout
Comment[cy]=Cais wedi'i wneud am gysylltiad,rhaid i'r ddefnyddiwr ei dderbyn
Comment[da]=Forbindelse forespurgt, bruger skal acceptere
@@ -884,11 +883,11 @@ Action=Popup
[Event/NewConnectionAutoAccepted]
Name=New Connection Auto Accepted
Name[ar]=اتصال جديد مقبول تلقائيا
Name[ast]=Conexón nueva aceutada automáticamente
Name[ast]=Conexón nueva auto-aceutada
Name[bg]=Автоматично приемане на новата връзка
Name[bs]=Nova veza je automatski prihvaćena
Name[ca]=Nova connexió acceptada automàticament
Name[ca@valencia]=Nova connexió acceptada automàticament
Name[ca]=Connexió nova acceptada automàticament
Name[ca@valencia]=Connexió nova acceptada automàticament
Name[cs]=Nové spojení automaticky přijato
Name[da]=Ny forbindelse automatisk accepteret
Name[de]=Neue Verbindung automatisch angenommen
@@ -944,12 +943,12 @@ Name[zh_TW]=新連線自動接受
Comment=New connection automatically established
Comment[af]=Nuwe verbinding automaties vasgestel
Comment[ar]=اتصال جديد مفعل تلقائيا
Comment[ast]=Conexón nueva afitada automáticamente
Comment[ast]=Afitóse automáticamente la conexón nueva
Comment[bg]=Новата връзка е автоматично приета
Comment[bn]=নতুন সংযোগ স্বয়ংক্রীয়ভাবে স্থাপন করা হল
Comment[bs]=Nova veza je automatski uspostavljena
Comment[ca]=Nova connexió establerta automàticament
Comment[ca@valencia]=Nova connexió establerta automàticament
Comment[ca]=Connexió nova establerta automàticament
Comment[ca@valencia]=Connexió nova establida automàticament
Comment[cs]=Automaticky navázáno nové spojení
Comment[cy]=Sefydlwyd cysylltiad newydd yn awtomatig
Comment[da]=Ny forbindelse automatisk etableret
@@ -1015,7 +1014,7 @@ Action=Popup
[Event/TooManyConnections]
Name=Too Many Connections
Name[ar]=اتصالات عديدة
Name[ast]=Abondes conexones
Name[ast]=Milenta conexones
Name[bg]=Твърде много връзки
Name[bs]=Previše veza
Name[ca]=Massa connexions
@@ -1075,7 +1074,7 @@ Name[zh_TW]=太多連線
Comment=Busy, connection refused
Comment[af]=Besig, verbinding geweier
Comment[ar]=مشغول، الإتصال رفض
Comment[ast]=Ocupáu, conexón refugada
Comment[ast]=Ocupáu, refugóse la conexón
Comment[bg]=Заето. Връзката е отказана.
Comment[bn]=ব্যস্ত, সংযোগ অস্বীকার করল
Comment[br]=Dalc'het, kevreadenn disteuleret
@@ -1210,12 +1209,12 @@ Name[zh_TW]=未知的連線
Comment=Received unexpected connection, abort
Comment[af]=Ontvang onverwagte verbinding, staak
Comment[ar]=استقبال اتصال غير متوقع، إنهاء
Comment[ast]=Recibióse conexón inesperada, albortando
Comment[ast]=Recibióse una conexón inesperada, albortando
Comment[bg]=Получена е неочаквана връзка. Прекъсване.
Comment[bn]=অপ্রত্যাশিত সংযোগ গ্রহণ করল, বাতিল করুন
Comment[bs]=Primljena je neočekivana veza, prekini
Comment[ca]=Rebuda una connexió inesperada, avortant
Comment[ca@valencia]=Rebuda una connexió inesperada, avortant
Comment[ca]=S'ha rebut una connexió inesperada, avortant
Comment[ca@valencia]=S'ha rebut una connexió inesperada, avortant
Comment[cs]=Obdrženo neočekávané spojení, přerušeno
Comment[cy]=Derbynwyd cysylltiad annisgwyl,terfynu
Comment[da]=Modtog uventet forbindelse, afbrød

View File

@@ -15,32 +15,29 @@
* *
***************************************************************************/
#include "manageinvitationsdialog.h"
#include "mainwindow.h"
#include "trayicon.h"
#include "invitationsrfbserver.h"
#include "krfbconfig.h"
#include <KAboutApplicationDialog>
#include <KAboutData>
#include <KAction>
#include <KApplication>
#include <KCmdLineArgs>
#include <KDebug>
#include <KLocale>
#include <KDBusService>
#include <KLocalizedString>
#include <KMessageBox>
#include <KNotification>
#include <QtGui/QPixmap>
#include <QtGui/qwindowdefs.h>
#ifdef KRFB_WITH_TELEPATHY_TUBES
# include "tubesrfbserver.h"
#endif
#include <QDebug>
#include <QPixmap>
#include <qwindowdefs.h>
#include <QX11Info>
#include <signal.h>
#include <X11/extensions/XTest.h>
#include <QCommandLineParser>
#include <QCommandLineOption>
static const char KRFB_VERSION[] = "5.0";
static const char description[] = I18N_NOOP("VNC-compatible server to share "
"KDE desktops");
"desktops");
static bool checkX11Capabilities()
{
@@ -59,62 +56,90 @@ static bool checkX11Capabilities()
return true;
}
static void checkOldX11PluginConfig() {
if (KrfbConfig::preferredFrameBufferPlugin() == QStringLiteral("x11")) {
qDebug() << "Detected deprecated configuration: preferredFrameBufferPlugin = x11";
KConfigSkeletonItem *config_item = KrfbConfig::self()->findItem(
QStringLiteral("preferredFrameBufferPlugin"));
if (config_item) {
config_item->setProperty(QStringLiteral("xcb"));
KrfbConfig::self()->save();
qDebug() << " Fixed preferredFrameBufferPlugin from x11 to xcb.";
}
}
}
int main(int argc, char *argv[])
{
KAboutData aboutData("krfb", 0, ki18n("Desktop Sharing"), KDE_VERSION_STRING,
ki18n(description), KAboutData::License_GPL,
ki18n("(c) 2009-2010, Collabora Ltd.\n"
QApplication app(argc, argv);
KLocalizedString::setApplicationDomain("krfb");
KAboutData aboutData("krfb",
i18n("Desktop Sharing"),
KRFB_VERSION,
i18n(description),
KAboutLicense::GPL,
i18n("(c) 2009-2010, Collabora Ltd.\n"
"(c) 2007, Alessandro Praduroux\n"
"(c) 2001-2003, Tim Jansen\n"
"(c) 2001, Johannes E. Schindelin\n"
"(c) 2000-2001, Const Kaplinsky\n"
"(c) 2000, Tridia Corporation\n"
"(c) 1999, AT&T Laboratories Boston\n"));
aboutData.addAuthor(ki18n("George Goldberg"),
ki18n("Telepathy tubes support"),
aboutData.addAuthor(i18n("George Goldberg"),
i18n("Telepathy tubes support"),
"george.goldberg@collabora.co.uk");
aboutData.addAuthor(ki18n("George Kiagiadakis"),
KLocalizedString(),
aboutData.addAuthor(i18n("George Kiagiadakis"),
QString(),
"george.kiagiadakis@collabora.co.uk");
aboutData.addAuthor(ki18n("Alessandro Praduroux"), ki18n("KDE4 porting"), "pradu@pradu.it");
aboutData.addAuthor(ki18n("Tim Jansen"), ki18n("Original author"), "tim@tjansen.de");
aboutData.addCredit(ki18n("Johannes E. Schindelin"),
ki18n("libvncserver"));
aboutData.addCredit(ki18n("Const Kaplinsky"),
ki18n("TightVNC encoder"));
aboutData.addCredit(ki18n("Tridia Corporation"),
ki18n("ZLib encoder"));
aboutData.addCredit(ki18n("AT&T Laboratories Boston"),
ki18n("original VNC encoders and "
aboutData.addAuthor(i18n("Alessandro Praduroux"), i18n("KDE4 porting"), "pradu@pradu.it");
aboutData.addAuthor(i18n("Tim Jansen"), i18n("Original author"), "tim@tjansen.de");
aboutData.addCredit(i18n("Johannes E. Schindelin"),
i18n("libvncserver"));
aboutData.addCredit(i18n("Const Kaplinsky"),
i18n("TightVNC encoder"));
aboutData.addCredit(i18n("Tridia Corporation"),
i18n("ZLib encoder"));
aboutData.addCredit(i18n("AT&T Laboratories Boston"),
i18n("original VNC encoders and "
"protocol design"));
KCmdLineArgs::init(argc, argv, &aboutData);
QCommandLineParser parser;
KAboutData::setApplicationData(aboutData);
parser.addVersionOption();
parser.addHelpOption();
aboutData.setupCommandLine(&parser);
parser.process(app);
aboutData.processCommandLine(&parser);
KCmdLineOptions options;
options.add("nodialog", ki18n("Do not show the invitations management dialog at startup"));
KCmdLineArgs::addCmdLineOptions(options);
KDBusService service(KDBusService::Unique, &app);
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("nodialog"), i18n("Do not show the invitations management dialog at startup")));
KApplication app;
app.setQuitOnLastWindowClosed(false);
if (!checkX11Capabilities()) {
return 1;
}
// upgrade the configuration
checkOldX11PluginConfig();
//init the core
InvitationsRfbServer::init();
#ifdef KRFB_WITH_TELEPATHY_TUBES
TubesRfbServer::init();
#endif
//init the GUI
ManageInvitationsDialog invitationsDialog;
TrayIcon trayicon(&invitationsDialog);
MainWindow mainWindow;
TrayIcon trayicon(&mainWindow);
if (app.isSessionRestored() && KMainWindow::canBeRestored(1)) {
invitationsDialog.restore(1, false);
} else if (KCmdLineArgs::parsedArgs()->isSet("dialog")) {
invitationsDialog.show();
if (KrfbConfig::startMinimized()) {
mainWindow.hide();
} else if (app.isSessionRestored() && KMainWindow::canBeRestored(1)) {
mainWindow.restore(1, false);
} else if (!parser.isSet("nodialog")) {
mainWindow.show();
}
sigset_t sigs;
@@ -124,4 +149,3 @@ int main(int argc, char *argv[])
return app.exec();
}

266
krfb/mainwindow.cpp Normal file
View File

@@ -0,0 +1,266 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2013 Amandeep Singh <aman.dedman@gmail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#include "mainwindow.h"
#include "invitationsrfbserver.h"
#include "krfbconfig.h"
#include "ui_configtcp.h"
#include "ui_configsecurity.h"
#include "ui_configframebuffer.h"
#include <KConfigDialog>
#include <KLocalizedString>
#include <KMessageBox>
#include <KStandardAction>
#include <KActionCollection>
#include <KLineEdit>
#include <KNewPasswordDialog>
#include <KPluginLoader>
#include <KPluginMetaData>
#include <QIcon>
#include <QWidget>
#include <QLineEdit>
#include <QComboBox>
#include <QSizePolicy>
#include <QVector>
#include <QSet>
#include <QtNetwork/QNetworkInterface>
class TCP: public QWidget, public Ui::TCP
{
public:
TCP(QWidget *parent = 0) : QWidget(parent) {
setupUi(this);
}
};
class Security: public QWidget, public Ui::Security
{
public:
Security(QWidget *parent = 0) : QWidget(parent) {
setupUi(this);
}
};
class ConfigFramebuffer: public QWidget, public Ui::Framebuffer
{
public:
ConfigFramebuffer(QWidget *parent = 0) : QWidget(parent) {
setupUi(this);
// hide the line edit with framebuffer string
kcfg_preferredFrameBufferPlugin->hide();
// fill drop-down combo with a list of real existing plugins
this->fillFrameBuffersCombo();
// initialize combo with currently configured framebuffer plugin
cb_preferredFrameBufferPlugin->setCurrentText(KrfbConfig::preferredFrameBufferPlugin());
// connect signals between combo<->lineedit
// if we change selection in combo, lineedit is updated
QObject::connect(cb_preferredFrameBufferPlugin, &QComboBox::currentTextChanged,
kcfg_preferredFrameBufferPlugin, &QLineEdit::setText);
}
void fillFrameBuffersCombo() {
const QVector<KPluginMetaData> plugins = KPluginLoader::findPlugins(
QStringLiteral("krfb"), [](const KPluginMetaData & md) {
return md.serviceTypes().contains(QStringLiteral("krfb/framebuffer"));
});
QSet<QString> unique;
QVectorIterator<KPluginMetaData> i(plugins);
i.toBack();
while (i.hasPrevious()) {
const KPluginMetaData &metadata = i.previous();
if (unique.contains(metadata.pluginId())) continue;
cb_preferredFrameBufferPlugin->addItem(metadata.pluginId());
unique.insert(metadata.pluginId());
}
}
};
MainWindow::MainWindow(QWidget *parent)
: KXmlGuiWindow(parent)
{
setAttribute(Qt::WA_DeleteOnClose, false);
m_passwordEditable = false;
m_passwordLineEdit = new KLineEdit(this);
m_passwordLineEdit->setVisible(false);
m_passwordLineEdit->setAlignment(Qt::AlignHCenter);
QWidget *mainWidget = new QWidget;
m_ui.setupUi(mainWidget);
m_ui.krfbIconLabel->setPixmap(QIcon::fromTheme("krfb").pixmap(128));
m_ui.enableUnattendedCheckBox->setChecked(
InvitationsRfbServer::instance->allowUnattendedAccess());
setCentralWidget(mainWidget);
connect(m_ui.passwordEditButton, &QToolButton::clicked,
this, &MainWindow::editPassword);
connect(m_ui.enableSharingCheckBox, &QCheckBox::toggled,
this, &MainWindow::toggleDesktopSharing);
connect(m_ui.enableUnattendedCheckBox, &QCheckBox::toggled,
InvitationsRfbServer::instance, &InvitationsRfbServer::toggleUnattendedAccess);
connect(m_ui.unattendedPasswordButton, &QPushButton::clicked,
this, &MainWindow::editUnattendedPassword);
connect(m_ui.addressAboutButton, &QToolButton::clicked,
this, &MainWindow::aboutConnectionAddress);
connect(m_ui.unattendedAboutButton, &QToolButton::clicked,
this, &MainWindow::aboutUnattendedMode);
connect(InvitationsRfbServer::instance, &InvitationsRfbServer::passwordChanged,
this, &MainWindow::passwordChanged);
// Figure out the address
int port = KrfbConfig::port();
QList<QNetworkInterface> interfaceList = QNetworkInterface::allInterfaces();
foreach(const QNetworkInterface & interface, interfaceList) {
if(interface.flags() & QNetworkInterface::IsLoopBack)
continue;
if(interface.flags() & QNetworkInterface::IsRunning &&
!interface.addressEntries().isEmpty())
m_ui.addressDisplayLabel->setText(QString("%1 : %2")
.arg(interface.addressEntries().first().ip().toString())
.arg(port));
}
//Figure out the password
m_ui.passwordDisplayLabel->setText(
InvitationsRfbServer::instance->desktopPassword());
KStandardAction::quit(QCoreApplication::instance(), SLOT(quit()), actionCollection());
KStandardAction::preferences(this, SLOT(showConfiguration()), actionCollection());
setupGUI();
if (KrfbConfig::allowDesktopControl()) {
m_ui.enableSharingCheckBox->setChecked(true);
}
setAutoSaveSettings();
}
MainWindow::~MainWindow()
{
}
void MainWindow::editPassword()
{
if(m_passwordEditable) {
m_passwordEditable = false;
m_ui.passwordEditButton->setIcon(QIcon::fromTheme("document-properties"));
m_ui.passwordGridLayout->removeWidget(m_passwordLineEdit);
InvitationsRfbServer::instance->setDesktopPassword(
m_passwordLineEdit->text());
m_ui.passwordDisplayLabel->setText(
InvitationsRfbServer::instance->desktopPassword());
m_passwordLineEdit->setVisible(false);
} else {
m_passwordEditable = true;
m_ui.passwordEditButton->setIcon(QIcon::fromTheme("document-save"));
m_ui.passwordGridLayout->addWidget(m_passwordLineEdit,0,0);
m_passwordLineEdit->setText(
InvitationsRfbServer::instance->desktopPassword());
m_passwordLineEdit->setVisible(true);
m_passwordLineEdit->setFocus(Qt::MouseFocusReason);
}
}
void MainWindow::editUnattendedPassword()
{
KNewPasswordDialog dialog(this);
dialog.setPrompt(i18n("Enter a new password for Unattended Access"));
if(dialog.exec()) {
InvitationsRfbServer::instance->setUnattendedPassword(dialog.password());
}
}
void MainWindow::toggleDesktopSharing(bool enable)
{
if(enable) {
if(!InvitationsRfbServer::instance->start()) {
KMessageBox::error(this,
i18n("Failed to start the krfb server. Desktop sharing "
"will not work. Try setting another port in the settings "
"and restart krfb."));
}
} else {
InvitationsRfbServer::instance->stop();
if(m_passwordEditable) {
m_passwordEditable = false;
m_passwordLineEdit->setVisible(false);
m_ui.passwordEditButton->setIcon(QIcon::fromTheme("document-properties"));
}
}
}
void MainWindow::passwordChanged(const QString& password)
{
m_passwordLineEdit->setText(password);
m_ui.passwordDisplayLabel->setText(password);
}
void MainWindow::aboutConnectionAddress()
{
KMessageBox::about(this,
i18n("This field contains the address of your computer and the port number, separated by a colon.\n\nThe address is just a hint - you can use any address that can reach your computer.\n\nDesktop Sharing tries to guess your address from your network configuration, but does not always succeed in doing so.\n\nIf your computer is behind a firewall it may have a different address or be unreachable for other computers."),
i18n("KDE Desktop Sharing"));
}
void MainWindow::aboutUnattendedMode()
{
KMessageBox::about(this,
i18n("Any remote user with normal desktop sharing password will have to be authenticated.\n\nIf unattended access is on, and the remote user provides unattended mode password, desktop sharing access will be granted without explicit confirmation."),
i18n("KDE Desktop Sharing"));
}
void MainWindow::showConfiguration()
{
static QString s_prevFramebufferPlugin;
// ^^ needs to be static, because lambda will be called long time
// after showConfiguration() ends, so auto variable would go out of scope
// save previously selected framebuffer plugin config
s_prevFramebufferPlugin = KrfbConfig::preferredFrameBufferPlugin();
if (KConfigDialog::showDialog("settings")) {
return;
}
KConfigDialog *dialog = new KConfigDialog(this, "settings", KrfbConfig::self());
dialog->addPage(new TCP, i18n("Network"), "network-wired");
dialog->addPage(new Security, i18n("Security"), "security-high");
dialog->addPage(new ConfigFramebuffer, i18n("Screen capture"), "video-display");
dialog->show();
connect(dialog, &KConfigDialog::settingsChanged, [this] () {
// check if framebuffer plugin config has changed
if (s_prevFramebufferPlugin != KrfbConfig::preferredFrameBufferPlugin()) {
KMessageBox::information(this, i18n("To apply framebuffer plugin setting, "
"you need to restart the program."));
}
});
}
void MainWindow::readProperties(const KConfigGroup& group)
{
if (group.readEntry("Visible", true)) {
show();
}
KMainWindow::readProperties(group);
}
void MainWindow::saveProperties(KConfigGroup& group)
{
group.writeEntry("Visible", isVisible());
KMainWindow::saveProperties(group);
}
#include "mainwindow.moc"

49
krfb/mainwindow.h Normal file
View File

@@ -0,0 +1,49 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2013 Amandeep Singh <aman.dedman@gmail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#ifndef MANAGEINVITATIONSDIALOG_H
#define MANAGEINVITATIONSDIALOG_H
#include "ui_mainwidget.h"
#include <KXmlGuiWindow>
class KLineEdit;
class MainWindow : public KXmlGuiWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
public Q_SLOTS:
void showConfiguration();
protected:
void readProperties(const KConfigGroup & group) override;
void saveProperties(KConfigGroup & group) override;
private Q_SLOTS:
void editPassword();
void editUnattendedPassword();
void toggleDesktopSharing(bool enable);
void passwordChanged(const QString&);
void aboutConnectionAddress();
void aboutUnattendedMode();
private:
Ui::MainWidget m_ui;
bool m_passwordEditable;
KLineEdit *m_passwordLineEdit;
};
#endif

View File

@@ -1,253 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#include "manageinvitationsdialog.h"
#include "invitationmanager.h"
#include "invitation.h"
#include "krfbconfig.h"
#include "personalinvitedialog.h"
#include "ui_configtcp.h"
#include "ui_configsecurity.h"
#include <KConfigDialog>
#include <KGlobal>
#include <KIconLoader>
#include <KLocale>
#include <KMessageBox>
#include <KStandardGuiItem>
#include <KSystemTimeZone>
#include <KToolInvocation>
#include <KStandardAction>
#include <KActionCollection>
#include <QtGui/QWidget>
#include <QtGui/QToolTip>
#include <QtGui/QCursor>
#include <QtCore/QDateTime>
#include <QtNetwork/QNetworkInterface>
class TCP: public QWidget, public Ui::TCP
{
public:
TCP(QWidget *parent = 0) : QWidget(parent) {
setupUi(this);
}
};
class Security: public QWidget, public Ui::Security
{
public:
Security(QWidget *parent = 0) : QWidget(parent) {
setupUi(this);
}
};
ManageInvitationsDialog::ManageInvitationsDialog(QWidget *parent)
: KXmlGuiWindow(parent)
{
setAttribute(Qt::WA_DeleteOnClose, false);
QWidget *mainWidget = new QWidget;
m_ui.setupUi(mainWidget);
m_ui.pixmapLabel->setPixmap(KIcon("krfb").pixmap(128));
setCentralWidget(mainWidget);
connect(m_ui.helpLabel, SIGNAL(linkActivated(QString)), SLOT(showWhatsthis()));
connect(m_ui.newPersonalInvitationButton, SIGNAL(clicked()), SLOT(inviteManually()));
connect(m_ui.newEmailInvitationButton, SIGNAL(clicked()), SLOT(inviteByMail()));
connect(InvitationManager::self(), SIGNAL(invitationNumChanged(int)), SLOT(reloadInvitations()));
connect(m_ui.deleteAllButton, SIGNAL(clicked()), SLOT(deleteAll()));
connect(m_ui.deleteOneButton, SIGNAL(clicked()), SLOT(deleteCurrent()));
connect(m_ui.invitationWidget, SIGNAL(itemSelectionChanged()), SLOT(selectionChanged()));
KStandardAction::quit(QCoreApplication::instance(), SLOT(quit()), actionCollection());
KStandardAction::preferences(this, SLOT(showConfiguration()), actionCollection());
setupGUI(QSize(550, 330));
setAutoSaveSettings();
reloadInvitations();
}
ManageInvitationsDialog::~ManageInvitationsDialog()
{
}
void ManageInvitationsDialog::showWhatsthis()
{
QToolTip::showText(QCursor::pos(),
i18n("An invitation creates a one-time password that allows the receiver to connect to your desktop.\n"
"It is valid for only one successful connection and will expire after an hour if it has not been used. \n"
"When somebody connects to your computer a dialog will appear and ask you for permission.\n"
"The connection will not be established before you accept it. In this dialog you can also\nrestrict "
"the other person to view your desktop only, without the ability to move your\nmouse pointer or press "
"keys.\nIf you want to create a permanent password for Desktop Sharing, allow 'Uninvited Connections' \n"
"in the configuration."));
}
void ManageInvitationsDialog::inviteManually()
{
Invitation inv = InvitationManager::self()->addInvitation();
PersonalInviteDialog *pid = new PersonalInviteDialog(this);
pid->setPassword(inv.password());
pid->setExpiration(inv.expirationTime());
pid->show();
}
void ManageInvitationsDialog::inviteByMail()
{
int r = KMessageBox::warningContinueCancel(this,
i18n("When sending an invitation by email, note that everybody who reads this email "
"will be able to connect to your computer for one hour, or until the first "
"successful connection took place, whichever comes first. \n"
"You should either encrypt the email or at least send it only in a "
"secure network, but not over the Internet."),
i18n("Send Invitation via Email"),
KStandardGuiItem::cont(),
KStandardGuiItem::cancel(),
"showEmailInvitationWarning");
if (r == KMessageBox::Cancel) {
return;
}
QList<QNetworkInterface> ifl = QNetworkInterface::allInterfaces();
QString host;
int port = KrfbConfig::port();
foreach(const QNetworkInterface & nif, ifl) {
if (nif.flags() & QNetworkInterface::IsLoopBack) {
continue;
}
if (nif.flags() & QNetworkInterface::IsRunning) {
if (!nif.addressEntries().isEmpty()) {
host = nif.addressEntries()[0].ip().toString();
}
}
}
Invitation inv = InvitationManager::self()->addInvitation();
KUrl invUrl(QString("vnc://invitation:%1@%2:%3").arg(inv.password()).arg(host).arg(port));
KToolInvocation::invokeMailer(QString(), QString(), QString(),
i18n("Desktop Sharing (VNC) invitation"),
ki18n("You have been invited to a VNC session. If you have the KDE Remote "
"Desktop Connection installed, just click on the link below.\n\n"
"%1\n\n"
"Otherwise you can use any VNC client with the following parameters:\n\n"
"Host: %2:%3\n"
"Password: %4\n\n"
"For security reasons this invitation will expire at %5 (%6).")
.subs(invUrl.url())
.subs(host)
.subs(QString::number(port))
.subs(inv.password())
.subs(KGlobal::locale()->formatDateTime(inv.expirationTime()))
.subs(KSystemTimeZones::local().name())
.toString());
}
void ManageInvitationsDialog::reloadInvitations()
{
m_ui.invitationWidget->clear();
KLocale *loc = KGlobal::locale();
foreach(const Invitation & inv, InvitationManager::self()->invitations()) {
QStringList strs;
strs << loc->formatDateTime(inv.creationTime()) << loc->formatDateTime(inv.expirationTime());
QTreeWidgetItem *it = new QTreeWidgetItem(strs);
m_ui.invitationWidget->addTopLevelItem(it);
it->setData(0, Qt::UserRole + 1, inv.creationTime());
}
m_ui.invitationWidget->resizeColumnToContents(0);
m_ui.deleteAllButton->setEnabled(InvitationManager::self()->activeInvitations() > 0);
}
void ManageInvitationsDialog::showConfiguration()
{
if (KConfigDialog::showDialog("settings")) {
return;
}
KConfigDialog *dialog = new KConfigDialog(this, "settings", KrfbConfig::self());
dialog->addPage(new TCP, i18n("Network"), "network-workgroup");
dialog->addPage(new Security, i18n("Security"), "security-high");
dialog->setHelp(QString(), "krfb");
dialog->show();
}
void ManageInvitationsDialog::deleteAll()
{
if (KMessageBox::warningContinueCancel(this,
i18n("<qt>Are you sure you want to delete all invitations?</qt>"),
i18n("Confirm delete Invitations"),
KStandardGuiItem::ok(),
KStandardGuiItem::cancel(),
QString("krfbdeleteallinv")) !=
KMessageBox::Continue) {
return;
}
InvitationManager::self()->removeAllInvitations();
}
void ManageInvitationsDialog::deleteCurrent()
{
if (KMessageBox::warningContinueCancel(this,
i18n("<qt>Are you sure you want to delete this invitation?</qt>"),
i18n("Confirm delete Invitations"),
KStandardGuiItem::ok(),
KStandardGuiItem::cancel(),
QString("krfbdeleteoneinv")) !=
KMessageBox::Continue) {
return;
}
// disable updates while deleting items, otherwise the list would invalidate itself
disconnect(InvitationManager::self(), SIGNAL(invitationNumChanged(int)),
this, SLOT(reloadInvitations()));
QList<QTreeWidgetItem *> itl = m_ui.invitationWidget->selectedItems();
foreach(QTreeWidgetItem * itm, itl) {
foreach(const Invitation & inv, InvitationManager::self()->invitations()) {
if (inv.creationTime() == itm->data(0, Qt::UserRole + 1)) {
InvitationManager::self()->removeInvitation(inv);
}
}
}
// update it manually
reloadInvitations();
connect(InvitationManager::self(), SIGNAL(invitationNumChanged(int)),
SLOT(reloadInvitations()));
}
void ManageInvitationsDialog::selectionChanged()
{
m_ui.deleteOneButton->setEnabled(m_ui.invitationWidget->selectedItems().size() > 0);
}
void ManageInvitationsDialog::readProperties(const KConfigGroup& group)
{
if (group.readEntry("Visible", true)) {
show();
}
KMainWindow::readProperties(group);
}
void ManageInvitationsDialog::saveProperties(KConfigGroup& group)
{
group.writeEntry("Visible", isVisible());
KMainWindow::saveProperties(group);
}
#include "manageinvitationsdialog.moc"

View File

@@ -1,46 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
*/
#ifndef MANAGEINVITATIONSDIALOG_H
#define MANAGEINVITATIONSDIALOG_H
#include "ui_manageinvitations.h"
#include <KXmlGuiWindow>
/**
@author Alessandro Praduroux <pradu@pradu.it>
*/
class ManageInvitationsDialog : public KXmlGuiWindow
{
Q_OBJECT
public:
ManageInvitationsDialog(QWidget *parent = 0);
~ManageInvitationsDialog();
public Q_SLOTS:
void showWhatsthis();
void inviteManually();
void inviteByMail();
void reloadInvitations();
void showConfiguration();
void deleteAll();
void deleteCurrent();
void selectionChanged();
protected:
virtual void readProperties(const KConfigGroup & group);
virtual void saveProperties(KConfigGroup & group);
private:
Ui::ManageInvitationsDialog m_ui;
};
#endif

View File

@@ -1,3 +0,0 @@
[D-BUS Service]
Name=org.freedesktop.Telepathy.Client.krfb_rfb_handler
Exec=@CMAKE_INSTALL_PREFIX@/bin/krfb --nodialog

View File

@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<component type="desktop">
<id>org.kde.krfb.desktop</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-2.0+</project_license>
<name>Krfb</name>
<name xml:lang="ast">Krfb</name>
<name xml:lang="ca">Krfb</name>
<name xml:lang="ca-valencia">Krfb</name>
<name xml:lang="cs">Krfb</name>
<name xml:lang="de">Krfb</name>
<name xml:lang="el">Krfb</name>
<name xml:lang="en-GB">Krfb</name>
<name xml:lang="es">Krfb</name>
<name xml:lang="fr">Krfb</name>
<name xml:lang="gl">Krfb</name>
<name xml:lang="it">Krfb</name>
<name xml:lang="nl">Krfb</name>
<name xml:lang="pl">Krfb</name>
<name xml:lang="pt">Krfb</name>
<name xml:lang="pt-BR">Krfb</name>
<name xml:lang="sk">Krfb</name>
<name xml:lang="sl">Krfb</name>
<name xml:lang="sr">КРФБ</name>
<name xml:lang="sr-Latn">KRFB</name>
<name xml:lang="sr-ijekavian">КРФБ</name>
<name xml:lang="sr-ijekavianlatin">KRFB</name>
<name xml:lang="sv">Krfb</name>
<name xml:lang="tr">Krfb</name>
<name xml:lang="uk">Krfb</name>
<name xml:lang="x-test">xxKrfbxx</name>
<name xml:lang="zh-CN">Krfb</name>
<summary>Desktop sharing</summary>
<summary xml:lang="ast">Compartición d'escritoriu</summary>
<summary xml:lang="ca">Compartició de l'escriptori</summary>
<summary xml:lang="ca-valencia">Compartició de l'escriptori</summary>
<summary xml:lang="cs">Sdílení pracovní plochy</summary>
<summary xml:lang="de">Freigabe der Arbeitsfläche</summary>
<summary xml:lang="el">Κοινή χρήση επιφάνειας εργασίας</summary>
<summary xml:lang="en-GB">Desktop sharing</summary>
<summary xml:lang="es">Compartir el escritorio</summary>
<summary xml:lang="fr">Partage de bureau</summary>
<summary xml:lang="gl">Compartición do escritorio</summary>
<summary xml:lang="it">Condivisione del desktop</summary>
<summary xml:lang="nl">Bureaublad delen</summary>
<summary xml:lang="pl">Współdzielenie pulpitu</summary>
<summary xml:lang="pt">Partilha do ecrã</summary>
<summary xml:lang="pt-BR">Compartilhamento de tela</summary>
<summary xml:lang="sk">Zdieľanie pracovnej plochy</summary>
<summary xml:lang="sl">Souporaba namizja</summary>
<summary xml:lang="sr">Дељење површи</summary>
<summary xml:lang="sr-Latn">Deljenje površi</summary>
<summary xml:lang="sr-ijekavian">Дељење површи</summary>
<summary xml:lang="sr-ijekavianlatin">Deljenje površi</summary>
<summary xml:lang="sv">Skrivbordsdelning</summary>
<summary xml:lang="tr">Masaüstü paylaşımı</summary>
<summary xml:lang="uk">Спільне користування стільницею</summary>
<summary xml:lang="x-test">xxDesktop sharingxx</summary>
<summary xml:lang="zh-CN">桌面共享</summary>
<description>
<p>Krfb Desktop Sharing is a server application that allows you to share your current session with a user on another machine, who can use a VNC client to view or even control the desktop.</p>
<p xml:lang="ca">El Krfb és una aplicació de servidor que permet compartir la vostra sessió actual amb un usuari en una altra màquina, la qual pot emprar un client VNC per veure o controlar l'escriptori.</p>
<p xml:lang="ca-valencia">El Krfb és una aplicació de servidor que permet compartir la vostra sessió actual amb un usuari en una altra màquina, la qual pot emprar un client VNC per veure o controlar l'escriptori.</p>
<p xml:lang="de">Krfb ist eine Serveranwendung, welche die gemeinsame Benutzung der aktuellen Sitzung mit einem Benutzer auf einem anderen Rechner ermöglicht, der mit Hilfe eines VNC-Programms den Bildschirminhalt sehen oder sogar die Arbeitsfläche bedienen kann.</p>
<p xml:lang="el">Η κοινή χρήση επιφάνειας εργασίας Krfb είναι μια εφαρμογή εξυπηρετητή που σας επιτρέπει να μοιράζεστε την τρέχουσα συνεδρία σας με έναν χρήστη σε άλλο μηχάνημα, ο οποίος μπορεί να χρησιμοποιεί έναν πελάτη VNC για να παρακολουθεί ή και να ελέγχει την επιφάνεια εργασίας σας.</p>
<p xml:lang="en-GB">Krfb Desktop Sharing is a server application that allows you to share your current session with a user on another machine, who can use a VNC client to view or even control the desktop.</p>
<p xml:lang="es">Krfb para compartir el escritorio es una aplicación de servidor que le permite compartir su sesión actual con un usuario de otra máquina, que puede usar un cliente VNC para ver e incluso controlar su escritorio.</p>
<p xml:lang="fr">Le partage de bureau Krfb est une application de serveur qui vous permet de partager votre session courante avec un utilisateur sur une autre machine, qui peut utiliser un client VNC pour afficher et même contrôler le bureau.</p>
<p xml:lang="gl">Krfb é un aplicativo de servidor que permite compartir a sesión actual cun usuario que está noutro equipo, que pode usar un cliente VNC para ver ou mesmo controlar o escritorio.</p>
<p xml:lang="it">Condivisione del desktop Krfb è un'applicazione server che permette di condividere la sessione attuale con un utente su un'altra macchina, che potrà usare un client VNC per visualizzare ed anche controllare il desktop.</p>
<p xml:lang="nl">Bureaublad delen is een server-applicatie die u in staat stelt uw huidige sessie te delen met een gebruiker op een andere machine, die een VNC-client kan gebruiken om uw bureaublad te bekijken of zelfs te besturen.</p>
<p xml:lang="pl">Współdzielenie pulpitu Krfb jest aplikacją serwerową, która umożliwia współdzielenie twojej bieżącej sesji z użytkownikiem na innym komputerze, który może użyć klienta VNC do oglądania,a a nawet sterowania twoim pulpitem.</p>
<p xml:lang="pt">A Partilha de Ecrã Krfb é uma aplicação de servidor que lhe permite partilhar a sua sessão actual com um utilizador noutra máquina, o qual poderá usar um cliente de VNC para ver ou mesmo controlar o ambiente de trabalho.</p>
<p xml:lang="sk">Krfb je serverová aplikácia, ktorá vám umožní zdieľať vaše aktuálne sedenie s používateľom na inom stroji, ktorý môže používať VNC klienta na pripojenie alebo ovládanie stanice.</p>
<p xml:lang="sl">Souporaba namizja Krfb je strežniški program, ki vam dovoli, da delite vašo trenutno sejo z uporabnikom na drugem računalniku, ki ima odjemalec VNC. Uporabnik lahko gleda ali celo nadzira namizje.</p>
<p xml:lang="sr">КРФБ је серверски програм за дељење површи, којим можете да поделите своју текућу сесију са корисником на другој машини. Удаљени корисник може да употреби неки ВНЦ клијент за гледање површи, па чак и управљање њоме.</p>
<p xml:lang="sr-Latn">KRFB je serverski program za deljenje površi, kojim možete da podelite svoju tekuću sesiju sa korisnikom na drugoj mašini. Udaljeni korisnik može da upotrebi neki VNC klijent za gledanje površi, pa čak i upravljanje njome.</p>
<p xml:lang="sr-ijekavian">КРФБ је серверски програм за дељење површи, којим можете да поделите своју текућу сесију са корисником на другој машини. Удаљени корисник може да употреби неки ВНЦ клијент за гледање површи, па чак и управљање њоме.</p>
<p xml:lang="sr-ijekavianlatin">KRFB je serverski program za deljenje površi, kojim možete da podelite svoju tekuću sesiju sa korisnikom na drugoj mašini. Udaljeni korisnik može da upotrebi neki VNC klijent za gledanje površi, pa čak i upravljanje njome.</p>
<p xml:lang="sv">Krfb-skrivbordsdelning är ett serverprogram som gör det möjligt att dela aktuell session med en användare på en annan dator, som kan använda en VNC-klient för att betrakta eller till och med kontrollera skrivbordet.</p>
<p xml:lang="tr">Krfb Masaüstü Paylaşımı, mevcut oturumu masaüstünü görüntülemek veya kontrol etmek için, VNC istemcisi kullanan başka bir makinedeki, kullanıcıyla paylaşmanızı sağlayan bir sunucu uygulamasıdır.</p>
<p xml:lang="uk">Програма для спільного використання стільниці Krfb — це серверна програма, яка надає вам змогу розділити ваш поточний сеанс роботи з користувачем, який працює на іншому комп’ютері, так, щоб цей користувач зміг скористатися клієнтом VNC для перегляду або навіть керування вашою стільницею.</p>
<p xml:lang="x-test">xxKrfb Desktop Sharing is a server application that allows you to share your current session with a user on another machine, who can use a VNC client to view or even control the desktop.xx</p>
<p xml:lang="zh-CN">Krfb 桌面共享是一个可以让您与另一个在其他机器上的用户共享当前会话的服务器程序,他可以使用 VNC 客户端来查看甚至控制桌面。</p>
</description>
<url type="homepage">https://www.kde.org</url>
<url type="bugtracker">https://bugs.kde.org</url>
<url type="donation">https://www.kde.org/community/donations</url>
<screenshots>
<screenshot type="default">
<image>
https://cdn.kde.org/screenshots/krfb/krfb.png
</image>
</screenshot>
</screenshots>
<provides>
<binary>krfb</binary>
</provides>
<project_group>KDE</project_group>
</component>

View File

@@ -1,8 +1,9 @@
# KDE Config File
[Desktop Entry]
Type=Application
Exec=krfb -caption %c %i
Exec=krfb -qwindowtitle %c %i
Icon=krfb
X-DBUS-StartupType=Unique
X-DocPath=krfb/index.html
Terminal=false
Name=Krfb
@@ -75,13 +76,13 @@ Name[zh_HK]=Krfb
Name[zh_TW]=_Krfb
GenericName=Desktop Sharing
GenericName[ar]=مشاركة سطح المكتب
GenericName[ast]=Escritoriu compartíu
GenericName[ast]=Compartición d'escritoriu
GenericName[bg]=Споделяне на работния плот
GenericName[bn]= ি
GenericName[br]=Rannañ ar vurev
GenericName[bs]=Dijeljenje radne površine
GenericName[ca]=Compartició de l'escriptori
GenericName[ca@valencia]=Compartició de l'escriptori
GenericName[ca]=Compartir l'escriptori
GenericName[ca@valencia]=Compartir l'escriptori
GenericName[cs]=Sdílení pracovní plochy
GenericName[cy]=Rhannu Penbwrdd
GenericName[da]=Skrivebordsdeling
@@ -109,7 +110,7 @@ GenericName[ja]=デスクトップ共有
GenericName[kk]=Үстелді ортақтастыру
GenericName[km]=
GenericName[ko]=
GenericName[lt]=Dalinimasis darbastaliu
GenericName[lt]=Dalinimasis darbalaukiu
GenericName[lv]=Darbvirsmas koplietošana
GenericName[ml]=ിി
GenericName[mr]=
@@ -143,4 +144,76 @@ GenericName[x-test]=xxDesktop Sharingxx
GenericName[zh_CN]=
GenericName[zh_HK]=
GenericName[zh_TW]=
Comment=Desktop Sharing
Comment[af]=Werkskerm Deeling
Comment[ar]=مشاركة سطح المكتب
Comment[ast]=Compartición d'escritoriu
Comment[bg]=Споделяне на работния плот
Comment[bn]= ি
Comment[br]=Rannañ ar vurev
Comment[bs]=Dijeljenje radne površine
Comment[ca]=Compartir l'escriptori
Comment[ca@valencia]=Compartir l'escriptori
Comment[cs]=Sdílení pracovní plochy
Comment[cy]=Rhannu Penbwrdd
Comment[da]=Skrivebordsdeling
Comment[de]=Arbeitsflächen-Freigabe
Comment[el]=Κοινή χρήση επιφάνειας εργασίας
Comment[en_GB]=Desktop Sharing
Comment[eo]=Tabula komunigado
Comment[es]=Escritorio compartido
Comment[et]=Töölaua jagamine
Comment[eu]=Mahaigaina partekatzea
Comment[fi]=Työpöydän jakaminen
Comment[fr]=Partage de bureaux
Comment[ga]=Roinnt Deisce
Comment[gl]=Compartición do escritorio
Comment[he]=שיתוף שולחנות עבודה
Comment[hi]=
Comment[hne]=
Comment[hr]=Dijeljenje radne površine
Comment[hu]=Munkaasztal-megosztás
Comment[ia]=Compartir de scriptorio
Comment[is]=Skjáborðamiðlun
Comment[it]=Condivisione del desktop
Comment[ja]=
Comment[kk]=Үстелді ортақтастыру
Comment[km]=
Comment[ko]=
Comment[lt]=Dalinimasis darbalaukiu
Comment[lv]=Darbvirsmas koplietošana
Comment[mk]=Делење на работната површина
Comment[ml]=ിി
Comment[mr]=
Comment[ms]=Perkongsian Ruang Kerja
Comment[nb]=Delte skrivebord
Comment[nds]=Schriefdisch-Freegaav
Comment[nl]=Bureaublad delen
Comment[nn]=Skrivebordsdeling
Comment[pa]= ਿ
Comment[pl]=Współdzielenie pulpitu
Comment[pt]=Partilha do Ecrã
Comment[pt_BR]=Compartilhamento do ambiente de trabalho
Comment[ro]=Partajare birou
Comment[ru]=Параметры общего рабочего стола
Comment[si]=
Comment[sk]=Zdieľanie pracovnej plochy
Comment[sl]=Souporaba namizja
Comment[sr]=Дељење површи
Comment[sr@ijekavian]=Дијељење површи
Comment[sr@ijekavianlatin]=Dijeljenje površi
Comment[sr@latin]=Deljenje površi
Comment[sv]=Dela ut skrivbordet
Comment[ta]=ி ி
Comment[tg]=Истифодаи Муштараки Мизи Корӣ
Comment[th]=
Comment[tr]=Masaüstü Paylaşımı
Comment[ug]=ئۈستەلئۈستىنى ھەمبەھىرلەش
Comment[uk]=Спільні стільниці
Comment[xh]=Ulwahlulelano lwe Desktop
Comment[x-test]=xxDesktop Sharingxx
Comment[zh_CN]=
Comment[zh_HK]=
Comment[zh_TW]=
Categories=Qt;KDE;System;Network;RemoteAccess;
X-DBUS-ServiceName=org.kde.krfb

View File

@@ -1,86 +0,0 @@
/*
Copyright (C) 2010 Collabora Ltd. <info@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pendingrfbclient.h"
#include "connectiondialog.h"
#include "krfbconfig.h"
#include <KDebug>
#include <KNotification>
PendingRfbClient::PendingRfbClient(rfbClientPtr client, QObject *parent)
: QObject(parent), m_client(0), m_rfbClient(client)
{
QMetaObject::invokeMethod(this, "processNewClient", Qt::QueuedConnection);
}
void PendingRfbClient::accept()
{
kDebug() << "accepted connection";
Q_ASSERT(m_client);
m_client->setOnHold(false);
Q_EMIT finished(m_client);
deleteLater();
}
void PendingRfbClient::reject()
{
kDebug() << "refused connection";
rfbCloseClient(m_rfbClient);
rfbClientConnectionGone(m_rfbClient);
Q_EMIT finished(NULL);
deleteLater();
}
void PendingRfbClient::showUserConfirmationDialog()
{
kDebug();
Q_ASSERT(m_client);
if (!KrfbConfig::askOnConnect()) {
KNotification::event("NewConnectionAutoAccepted",
i18n("Accepted connection from %1", m_client->name()));
accept();
} else {
KNotification::event("NewConnectionOnHold",
i18n("Received connection from %1, on hold (waiting for confirmation)",
m_client->name()));
ConnectionDialog *dialog = new ConnectionDialog(0);
dialog->setRemoteHost(m_client->name());
dialog->setAllowRemoteControl(KrfbConfig::allowDesktopControl());
connect(dialog, SIGNAL(okClicked()), SLOT(dialogAccepted()));
connect(dialog, SIGNAL(cancelClicked()), SLOT(dialogRejected()));
dialog->show();
}
}
void PendingRfbClient::dialogAccepted()
{
ConnectionDialog *dialog = qobject_cast<ConnectionDialog *>(sender());
Q_ASSERT(dialog);
m_client->setControlEnabled(dialog->cbAllowRemoteControl->isChecked());
accept();
}
void PendingRfbClient::dialogRejected()
{
reject();
}

View File

@@ -1,46 +0,0 @@
/*
Copyright (C) 2010 Collabora Ltd. <info@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PENDINGRFBCLIENT_H
#define PENDINGRFBCLIENT_H
#include "rfbclient.h"
#include <QtCore/QObject>
class PendingRfbClient : public QObject
{
Q_OBJECT
public:
PendingRfbClient(rfbClientPtr client, QObject* parent = 0);
Q_SIGNALS:
void finished(RfbClient *client);
protected Q_SLOTS:
virtual void processNewClient() = 0;
void showUserConfirmationDialog();
void accept();
void reject();
protected:
RfbClient *m_client;
rfbClientPtr m_rfbClient;
};
#endif // PENDINGRFBCLIENT_H

View File

@@ -1,105 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Nadeem Hasan <nhasan@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "personalinvitedialog.h"
#include "krfbconfig.h"
#include <KIconLoader>
#include <KLocale>
#include <QtGui/QLabel>
#include <QtGui/QToolTip>
#include <QtNetwork/QNetworkInterface>
PersonalInviteDialog::PersonalInviteDialog(QWidget *parent)
: KDialog(parent)
{
setCaption(i18n("Personal Invitation"));
setButtons(Close);
setDefaultButton(Close);
setModal(true);
setMinimumSize(500, 250);
int port = KrfbConfig::port();
m_inviteWidget = new QWidget(this);
setupUi(m_inviteWidget);
pixmapLabel->setPixmap(KIcon("krfb").pixmap(128));
QList<QNetworkInterface> ifl = QNetworkInterface::allInterfaces();
foreach(const QNetworkInterface & nif, ifl) {
if (nif.flags() & QNetworkInterface::IsLoopBack) {
continue;
}
if (nif.flags() & QNetworkInterface::IsRunning && !nif.addressEntries().isEmpty()) {
hostLabel->setText(QString("%1:%2").arg(nif.addressEntries().first().ip().toString()).arg(port));
}
}
connect(mainTextLabel, SIGNAL(linkActivated(QString)),
SLOT(showWhatsthis(QString)));
connect(hostHelpLabel, SIGNAL(linkActivated(QString)),
SLOT(showWhatsthis(QString)));
setMainWidget(m_inviteWidget);
}
void PersonalInviteDialog::setHost(const QString &host, uint port)
{
hostLabel->setText(QString("%1:%2")
.arg(host).arg(port));
}
void PersonalInviteDialog::setPassword(const QString &passwd)
{
passwordLabel->setText(passwd);
}
void PersonalInviteDialog::setExpiration(const QDateTime &expire)
{
expirationLabel->setText(expire.toString(Qt::LocalDate));
}
void PersonalInviteDialog::showWhatsthis(const QString &link)
{
if (link == "htc") {
QToolTip::showText(QCursor::pos(),
i18n("Desktop Sharing uses the VNC protocol. You can use any VNC client to connect. \n"
"In KDE the client is called 'Remote Desktop Connection'. Enter the host information\n"
"into the client and it will connect.."));
} else if (link == "help") {
QToolTip::showText(QCursor::pos(),
i18n("This field contains the address of your computer and the port number, separated by a colon.\n"
"The address is just a hint - you can use any address that can reach your computer. \n"
"Desktop Sharing tries to guess your address from your network configuration, but does\n"
"not always succeed in doing so. If your computer is behind a firewall it may have a\n"
"different address or be unreachable for other computers."));
}
}
#include "personalinvitedialog.moc"

View File

@@ -1,49 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2004 Nadeem Hasan <nhasan@kde.org>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef PERSONALINVITEDIALOG_H
#define PERSONALINVITEDIALOG_H
#include "ui_personalinvitewidget.h"
#include <KDialog>
#include <QtCore/QDateTime>
class QWidget;
class PersonalInviteDialog : public KDialog, public Ui::PersonalInviteWidget
{
Q_OBJECT
public:
PersonalInviteDialog(QWidget *parent);
virtual ~PersonalInviteDialog() {}
void setHost(const QString &host, uint port);
void setPassword(const QString &passwd);
void setExpiration(const QDateTime &expire);
public Q_SLOTS:
void showWhatsthis(const QString &);
protected:
QWidget *m_inviteWidget;
};
#endif // PERSONALINVITEDIALOG_H

View File

@@ -6,7 +6,11 @@
#ifndef KRFB_RFB_H
#define KRFB_RFB_H
#include "../libvncserver/rfb/rfb.h"
#include "rfb/rfb.h"
#ifdef max
#undef max
#endif
#undef TRUE
#undef FALSE

View File

@@ -23,8 +23,7 @@
#include "sockethelpers.h"
#include "events.h"
#include <QtCore/QSocketNotifier>
#include <KDebug>
#include <KNotification>
#include <QDebug>
#include <poll.h>
#include <strings.h> //for bzero()
@@ -49,12 +48,12 @@ RfbClient::RfbClient(rfbClientPtr client, QObject* parent)
d->notifier = new QSocketNotifier(client->sock, QSocketNotifier::Read, this);
d->notifier->setEnabled(false);
connect(d->notifier, SIGNAL(activated(int)), this, SLOT(onSocketActivated()));
connect(d->notifier, &QSocketNotifier::activated, this, &RfbClient::onSocketActivated);
}
RfbClient::~RfbClient()
{
kDebug();
//qDebug();
delete d;
}
@@ -103,6 +102,11 @@ void RfbClient::closeConnection()
rfbClientConnectionGone(d->client);
}
rfbClientPtr RfbClient::getRfbClientPtr()
{
return d->client;
}
void RfbClient::handleKeyboardEvent(bool down, rfbKeySym keySym)
{
if (d->controlEnabled) {
@@ -117,34 +121,6 @@ void RfbClient::handleMouseEvent(int buttonMask, int x, int y)
}
}
bool RfbClient::checkPassword(const QByteArray & encryptedPassword)
{
Q_UNUSED(encryptedPassword);
return d->client->screen->authPasswdData == (void*)0;
}
bool RfbClient::vncAuthCheckPassword(const QByteArray& password, const QByteArray& encryptedPassword) const
{
if (password.isEmpty() && encryptedPassword.isEmpty()) {
return true;
}
char passwd[MAXPWLEN];
unsigned char challenge[CHALLENGESIZE];
memcpy(challenge, d->client->authChallenge, CHALLENGESIZE);
bzero(passwd, MAXPWLEN);
if (!password.isEmpty()) {
strncpy(passwd, password,
(MAXPWLEN <= password.size()) ? MAXPWLEN : password.size());
}
rfbEncryptBytes(challenge, passwd);
return memcmp(challenge, encryptedPassword, encryptedPassword.size()) == 0;
}
void RfbClient::onSocketActivated()
{
//Process not only one, but all pending messages.
@@ -163,7 +139,7 @@ void RfbClient::onSocketActivated()
//the clientGoneHook which in turn will remove this RfbClient instance
//from the server manager and will call deleteLater() to delete it
if (d->client->sock == -1) {
kDebug() << "disconnected from socket signal";
//qDebug() << "disconnected from socket signal";
d->notifier->setEnabled(false);
rfbClientConnectionGone(d->client);
break;
@@ -182,7 +158,7 @@ void RfbClient::update()
//the clientGoneHook which in turn will remove this RfbClient instance
//from the server manager and will call deleteLater() to delete it
if (d->client->sock == -1) {
kDebug() << "disconnected during update";
//qDebug() << "disconnected during update";
d->notifier->setEnabled(false);
rfbClientConnectionGone(d->client);
}
@@ -193,18 +169,15 @@ void RfbClient::update()
PendingRfbClient::PendingRfbClient(rfbClientPtr client, QObject *parent)
: QObject(parent), m_rfbClient(client)
{
kDebug();
QMetaObject::invokeMethod(this, "processNewClient", Qt::QueuedConnection);
m_rfbClient->clientData = this;
}
PendingRfbClient::~PendingRfbClient()
{
kDebug();
}
{}
void PendingRfbClient::accept(RfbClient *newClient)
{
kDebug() << "accepted connection";
//qDebug() << "accepted connection";
m_rfbClient->clientData = newClient;
newClient->setOnHold(false);
@@ -217,7 +190,7 @@ static void clientGoneHookNoop(rfbClientPtr cl) { Q_UNUSED(cl); }
void PendingRfbClient::reject()
{
kDebug() << "refused connection";
//qDebug() << "refused connection";
//override the clientGoneHook that was previously set by RfbServer
m_rfbClient->clientGoneHook = clientGoneHookNoop;
@@ -228,5 +201,32 @@ void PendingRfbClient::reject()
deleteLater();
}
bool PendingRfbClient::checkPassword(const QByteArray & encryptedPassword)
{
Q_UNUSED(encryptedPassword);
return m_rfbClient->screen->authPasswdData == (void*)0;
}
bool PendingRfbClient::vncAuthCheckPassword(const QByteArray& password, const QByteArray& encryptedPassword) const
{
if (password.isEmpty() && encryptedPassword.isEmpty()) {
return true;
}
char passwd[MAXPWLEN];
unsigned char challenge[CHALLENGESIZE];
memcpy(challenge, m_rfbClient->authChallenge, CHALLENGESIZE);
bzero(passwd, MAXPWLEN);
if (!password.isEmpty()) {
strncpy(passwd, password,
(MAXPWLEN <= password.size()) ? MAXPWLEN : password.size());
}
rfbEncryptBytes(challenge, passwd);
return memcmp(challenge, encryptedPassword, encryptedPassword.size()) == 0;
}
#include "rfbclient.moc"

View File

@@ -51,23 +51,10 @@ Q_SIGNALS:
protected:
friend class RfbServer; //the following event handling methods are called by RfbServer
rfbClientPtr getRfbClientPtr();
virtual void handleKeyboardEvent(bool down, rfbKeySym keySym);
virtual void handleMouseEvent(int buttonMask, int x, int y);
/** This method is supposed to check if the provided \a encryptedPassword
* matches the criteria for authenticating the client.
* The default implementation returns false if a password is required.
* Reimplement to do more useful stuff.
*/
virtual bool checkPassword(const QByteArray & encryptedPassword);
/** This method checks if the \a encryptedPassword that was sent from the remote
* user matches the \a password that you have specified localy to be the password
* for this connection. This assumes that the standard VNC authentication mechanism
* is used. Returns true if the password matches or false otherwise.
*/
bool vncAuthCheckPassword(const QByteArray & password, const QByteArray & encryptedPassword) const;
private Q_SLOTS:
void onSocketActivated();
@@ -99,6 +86,23 @@ protected Q_SLOTS:
void reject();
protected:
friend class RfbServer; //Following two methods are handled by RfbServer
/** This method is supposed to check if the provided \a encryptedPassword
* matches the criteria for authenticating the client.
* The default implementation returns false if a password is required.
* Reimplement to do more useful stuff.
*/
virtual bool checkPassword(const QByteArray & encryptedPassword);
/** This method checks if the \a encryptedPassword that was sent from the remote
* user matches the \a password that you have specified localy to be the password
* for this connection. This assumes that the standard VNC authentication mechanism
* is used. Returns true if the password matches or false otherwise.
*/
bool vncAuthCheckPassword(const QByteArray & password, const QByteArray & encryptedPassword) const;
rfbClientPtr m_rfbClient;
};

View File

@@ -20,7 +20,9 @@
#include "rfbserver.h"
#include "rfbservermanager.h"
#include <QtCore/QSocketNotifier>
#include <KDebug>
#include <QApplication>
#include <QClipboard>
#include <QDebug>
struct RfbServer::Private
{
@@ -45,7 +47,6 @@ RfbServer::RfbServer(QObject *parent)
RfbServer::~RfbServer()
{
stop();
if (d->screen) {
rfbScreenCleanup(d->screen);
}
@@ -89,6 +90,7 @@ bool RfbServer::start()
if (!d->screen) {
d->screen = RfbServerManager::instance()->newScreen();
if (!d->screen) {
qDebug() << "Unable to get rbfserver screen";
return false;
}
@@ -121,29 +123,31 @@ bool RfbServer::start()
d->screen->authPasswdData = (void *)0;
}
kDebug() << "Starting server. Listen port:" << listeningPort()
qDebug() << "Starting server. Listen port:" << listeningPort()
<< "Listen Address:" << listeningAddress()
<< "Password enabled:" << passwordRequired();
rfbInitServer(d->screen);
if (!rfbIsActive(d->screen)) {
kDebug() << "Failed to start server";
qDebug() << "Failed to start server";
rfbShutdownServer(d->screen, false);
return false;
};
d->notifier = new QSocketNotifier(d->screen->listenSock, QSocketNotifier::Read, this);
d->notifier->setEnabled(true);
connect(d->notifier, SIGNAL(activated(int)), this, SLOT(onListenSocketActivated()));
connect(d->notifier, &QSocketNotifier::activated, this, &RfbServer::onListenSocketActivated);
connect(QApplication::clipboard(), &QClipboard::dataChanged,
this, &RfbServer::krfbSendServerCutText);
return true;
}
void RfbServer::stop(bool disconnectClients)
void RfbServer::stop()
{
if (d->screen) {
rfbShutdownServer(d->screen, disconnectClients);
rfbShutdownServer(d->screen, true);
if (d->notifier) {
d->notifier->setEnabled(false);
d->notifier->deleteLater();
@@ -184,13 +188,13 @@ void krfb_rfbSetCursorPosition(rfbScreenInfoPtr screen, rfbClientPtr client, int
/* Inform all clients about this cursor movement. */
iterator = rfbGetClientIterator(screen);
while ((cl = rfbClientIteratorNext(iterator)) != NULL) {
cl->cursorWasMoved = TRUE;
cl->cursorWasMoved = true;
}
rfbReleaseClientIterator(iterator);
/* The cursor was moved by this client, so don't send CursorPos. */
if (client) {
client->cursorWasMoved = FALSE;
client->cursorWasMoved = false;
}
}
@@ -201,6 +205,15 @@ void RfbServer::updateCursorPosition(const QPoint & position)
}
}
void RfbServer::krfbSendServerCutText()
{
if(d->screen) {
QString text = QApplication::clipboard()->text();
rfbSendServerCutText(d->screen,
text.toLocal8Bit().data(),text.length());
}
}
void RfbServer::onListenSocketActivated()
{
rfbProcessNewConnection(d->screen);
@@ -208,30 +221,30 @@ void RfbServer::onListenSocketActivated()
void RfbServer::pendingClientFinished(RfbClient *client)
{
kDebug();
//qDebug();
if (client) {
RfbServerManager::instance()->addClient(client);
client->getRfbClientPtr()->clientGoneHook = clientGoneHook;
}
}
//static
rfbNewClientAction RfbServer::newClientHook(rfbClientPtr cl)
{
kDebug() << "New client";
//qDebug() << "New client";
RfbServer *server = static_cast<RfbServer*>(cl->screen->screenData);
PendingRfbClient *pendingClient = server->newClient(cl);
connect(pendingClient, SIGNAL(finished(RfbClient*)),
server, SLOT(pendingClientFinished(RfbClient*)));
connect(pendingClient, &PendingRfbClient::finished,
server, &RfbServer::pendingClientFinished);
cl->clientGoneHook = clientGoneHook;
return RFB_CLIENT_ON_HOLD;
}
//static
void RfbServer::clientGoneHook(rfbClientPtr cl)
{
kDebug() << "client gone";
//qDebug() << "client gone";
RfbClient *client = static_cast<RfbClient*>(cl->clientData);
RfbServerManager::instance()->removeClient(client);
@@ -241,7 +254,8 @@ void RfbServer::clientGoneHook(rfbClientPtr cl)
//static
rfbBool RfbServer::passwordCheck(rfbClientPtr cl, const char *encryptedPassword, int len)
{
RfbClient *client = static_cast<RfbClient*>(cl->clientData);
PendingRfbClient *client = static_cast<PendingRfbClient*>(cl->clientData);
Q_ASSERT(client);
return client->checkPassword(QByteArray::fromRawData(encryptedPassword, len));
}
@@ -260,9 +274,9 @@ void RfbServer::pointerHook(int bm, int x, int y, rfbClientPtr cl)
}
//static
void RfbServer::clipboardHook(char *str, int len, rfbClientPtr cl)
void RfbServer::clipboardHook(char *str, int len, rfbClientPtr /*cl*/)
{
//TODO implement me
QApplication::clipboard()->setText(QString::fromLocal8Bit(str,len));
}
#include "rfbserver.moc"

View File

@@ -40,13 +40,14 @@ public:
void setPasswordRequired(bool passwordRequired);
public Q_SLOTS:
bool start();
void stop(bool disconnectClients = true);
virtual bool start();
virtual void stop();
void updateScreen(const QList<QRect> & modifiedTiles);
void updateCursorPosition(const QPoint & position);
private Q_SLOTS:
void krfbSendServerCutText();
void onListenSocketActivated();
void pendingClientFinished(RfbClient *client);

View File

@@ -25,12 +25,13 @@
#include "sockethelpers.h"
#include "krfbconfig.h"
#include <QtCore/QTimer>
#include <QtGui/QApplication>
#include <QtGui/QDesktopWidget>
#include <QApplication>
#include <QDesktopWidget>
#include <QGlobalStatic>
#include <QtNetwork/QHostInfo>
#include <KGlobal>
#include <KDebug>
#include <KLocale>
#include <QDebug>
#include <KLocalizedString>
#include <KUser>
#include <KNotification>
@@ -82,7 +83,7 @@ struct RfbServerManagerStatic
RfbServerManager server;
};
K_GLOBAL_STATIC(RfbServerManagerStatic, s_instance)
Q_GLOBAL_STATIC(RfbServerManagerStatic, s_instance)
RfbServerManager* RfbServerManager::instance()
{
@@ -114,7 +115,7 @@ RfbServerManager::~RfbServerManager()
void RfbServerManager::init()
{
kDebug();
//qDebug();
d->fb = FrameBufferManager::instance()->frameBuffer(QApplication::desktop()->winId());
d->myCursor = rfbMakeXCursor(19, 19, (char *) cur, (char *) mask);
@@ -122,8 +123,8 @@ void RfbServerManager::init()
d->desktopName = QString("%1@%2 (shared desktop)") //FIXME check if we can use utf8
.arg(KUser().loginName(),QHostInfo::localHostName()).toLatin1();
connect(&d->rfbUpdateTimer, SIGNAL(timeout()), SLOT(updateScreens()));
connect(qApp, SIGNAL(aboutToQuit()), SLOT(cleanup()));
connect(&d->rfbUpdateTimer, &QTimer::timeout, this, &RfbServerManager::updateScreens);
connect(qApp, &QApplication::aboutToQuit, this, &RfbServerManager::cleanup);
}
void RfbServerManager::updateScreens()
@@ -147,7 +148,7 @@ void RfbServerManager::updateScreens()
void RfbServerManager::cleanup()
{
kDebug();
//qDebug();
//copy because d->servers is going to be modified while we delete the servers
QSet<RfbServer*> servers = d->servers;
@@ -187,7 +188,7 @@ rfbScreenInfoPtr RfbServerManager::newScreen()
bpp = 4;
}
kDebug() << "bpp: " << bpp;
//qDebug() << "bpp: " << bpp;
rfbLogEnable(0);
@@ -206,7 +207,7 @@ rfbScreenInfoPtr RfbServerManager::newScreen()
void RfbServerManager::addClient(RfbClient* cc)
{
if (d->clients.size() == 0) {
kDebug() << "Starting framebuffer monitor";
//qDebug() << "Starting framebuffer monitor";
d->fb->startMonitor();
d->rfbUpdateTimer.start(50);
}
@@ -222,7 +223,7 @@ void RfbServerManager::removeClient(RfbClient* cc)
{
d->clients.remove(cc);
if (d->clients.size() == 0) {
kDebug() << "Stopping framebuffer monitor";
//qDebug() << "Stopping framebuffer monitor";
d->fb->stopMonitor();
d->rfbUpdateTimer.stop();
}

View File

@@ -24,7 +24,7 @@
#include <QtCore/QObject>
class RfbClient;
class RfbServerManagerStatic;
struct RfbServerManagerStatic;
class RfbServer;
class RfbServerManager : public QObject
@@ -56,7 +56,7 @@ private:
Q_DISABLE_COPY(RfbServerManager)
friend class RfbServer;
friend class RfbServerManagerStatic;
friend struct RfbServerManagerStatic;
struct Private;
Private *const d;

View File

@@ -18,54 +18,55 @@
*/
#include "trayicon.h"
#include "invitedialog.h"
#include "manageinvitationsdialog.h"
#include "mainwindow.h"
#include "rfbservermanager.h"
#include "rfbclient.h"
#include <QIcon>
#include <QMenu>
#include <KAboutApplicationDialog>
#include <KActionCollection>
#include <KDialog>
#include <KGlobal>
#include <KLocale>
#include <KMenu>
#include <QDialog>
#include <KHelpMenu>
#include <KLocalizedString>
#include <KStandardAction>
#include <KDebug>
#include <KToggleAction>
#include <KConfigGroup>
class ClientActions
{
public:
ClientActions(RfbClient *client, KMenu *menu, QAction *before);
ClientActions(RfbClient *client, QMenu *menu, QAction *before);
virtual ~ClientActions();
private:
KMenu *m_menu;
QMenu *m_menu;
QAction *m_title;
QAction *m_disconnectAction;
QAction *m_enableControlAction;
QAction *m_separator;
};
ClientActions::ClientActions(RfbClient* client, KMenu* menu, QAction* before)
ClientActions::ClientActions(RfbClient* client, QMenu* menu, QAction* before)
: m_menu(menu)
{
m_title = m_menu->addTitle(client->name(), before);
m_title = m_menu->insertSection(before, client->name());
m_disconnectAction = new KAction(i18n("Disconnect"), m_menu);
m_disconnectAction = new QAction(i18n("Disconnect"), m_menu);
m_menu->insertAction(before, m_disconnectAction);
QObject::connect(m_disconnectAction, SIGNAL(triggered()), client, SLOT(closeConnection()));
QObject::connect(m_disconnectAction, &QAction::triggered, client, &RfbClient::closeConnection);
if (client->controlCanBeEnabled()) {
m_enableControlAction = new KToggleAction(i18n("Enable Remote Control"), m_menu);
m_enableControlAction->setChecked(client->controlEnabled());
m_menu->insertAction(before, m_enableControlAction);
QObject::connect(m_enableControlAction, SIGNAL(triggered(bool)),
client, SLOT(setControlEnabled(bool)));
QObject::connect(client, SIGNAL(controlEnabledChanged(bool)),
m_enableControlAction, SLOT(setChecked(bool)));
QObject::connect(m_enableControlAction, &KToggleAction::triggered,
client, &RfbClient::setControlEnabled);
QObject::connect(client, &RfbClient::controlEnabledChanged,
m_enableControlAction, &KToggleAction::setChecked);
} else {
m_enableControlAction = NULL;
}
@@ -75,8 +76,6 @@ ClientActions::ClientActions(RfbClient* client, KMenu* menu, QAction* before)
ClientActions::~ClientActions()
{
kDebug();
m_menu->removeAction(m_title);
delete m_title;
@@ -97,24 +96,22 @@ ClientActions::~ClientActions()
TrayIcon::TrayIcon(QWidget *mainWindow)
: KStatusNotifierItem(mainWindow)
{
setIconByPixmap(KIcon("krfb").pixmap(22, 22, KIcon::Disabled));
setIconByPixmap(QIcon::fromTheme("krfb").pixmap(22, 22, QIcon::Disabled));
setToolTipTitle(i18n("Desktop Sharing - disconnected"));
setCategory(KStatusNotifierItem::ApplicationStatus);
connect(RfbServerManager::instance(), SIGNAL(clientConnected(RfbClient*)),
this, SLOT(onClientConnected(RfbClient*)));
connect(RfbServerManager::instance(), SIGNAL(clientDisconnected(RfbClient*)),
this, SLOT(onClientDisconnected(RfbClient*)));
connect(RfbServerManager::instance(), &RfbServerManager::clientConnected,
this, &TrayIcon::onClientConnected);
connect(RfbServerManager::instance(), &RfbServerManager::clientDisconnected,
this, &TrayIcon::onClientDisconnected);
m_aboutAction = KStandardAction::aboutApp(this, SLOT(showAbout()), actionCollection());
m_aboutAction = KStandardAction::aboutApp(this, SLOT(showAbout()), this);
contextMenu()->addAction(m_aboutAction);
}
void TrayIcon::onClientConnected(RfbClient* client)
{
kDebug();
if (m_clientActions.isEmpty()) { //first client connected
setIconByName("krfb");
setToolTipTitle(i18n("Desktop Sharing - connected with %1", client->name()));
@@ -128,13 +125,11 @@ void TrayIcon::onClientConnected(RfbClient* client)
void TrayIcon::onClientDisconnected(RfbClient* client)
{
kDebug();
ClientActions *actions = m_clientActions.take(client);
delete actions;
if (m_clientActions.isEmpty()) {
setIconByPixmap(KIcon("krfb").pixmap(22, 22, KIcon::Disabled));
setIconByPixmap(QIcon::fromTheme("krfb").pixmap(22, 22, QIcon::Disabled));
setToolTipTitle(i18n("Desktop Sharing - disconnected"));
setStatus(KStatusNotifierItem::Passive);
} else if (m_clientActions.size() == 1) { //clients number dropped back to 1
@@ -145,9 +140,8 @@ void TrayIcon::onClientDisconnected(RfbClient* client)
void TrayIcon::showAbout()
{
KDialog *dlg = new KAboutApplicationDialog(KGlobal::mainComponent().aboutData());
dlg->setAttribute(Qt::WA_DeleteOnClose, true);
dlg->show();
KHelpMenu menu;
menu.aboutApplication();
}
#include "trayicon.moc"

View File

@@ -19,9 +19,7 @@
#define TRAYICON_H
#include <KStatusNotifierItem>
#include <KToggleAction>
class KDialog;
class RfbClient;
class ClientActions;
@@ -42,7 +40,7 @@ public Q_SLOTS:
void showAbout();
private:
KAction *m_aboutAction;
QAction *m_aboutAction;
QHash<RfbClient*, ClientActions*> m_clientActions;
};

View File

@@ -1,85 +0,0 @@
/*
Copyright (C) 2009-2010 Collabora Ltd. <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tubesrfbclient.h"
#include "krfbconfig.h"
#include "connectiondialog.h"
#include <KNotification>
#include <KLocale>
QString TubesRfbClient::name() const
{
return m_contact->alias();
}
void PendingTubesRfbClient::setContact(const Tp::ContactPtr & contact)
{
m_contact = contact;
if (m_processNewClientCalled) {
//processNewClient has already been called, so we need to act here
showConfirmationDialog();
}
}
void PendingTubesRfbClient::processNewClient()
{
if (!m_contact) {
//no associated contact yet, hold.
m_processNewClientCalled = true; //act when a contact is set
} else {
//we have a contact, begin handling
showConfirmationDialog();
}
}
void PendingTubesRfbClient::showConfirmationDialog()
{
QString name = m_contact->alias();
if (!KrfbConfig::askOnConnect()) {
KNotification::event("NewConnectionAutoAccepted",
i18n("Accepted connection from %1", name));
accept(new TubesRfbClient(m_rfbClient, m_contact, parent()));
} else {
KNotification::event("NewConnectionOnHold",
i18n("Received connection from %1, on hold (waiting for confirmation)",
name));
TubesConnectionDialog *dialog = new TubesConnectionDialog(0);
dialog->setContactName(name);
dialog->setAllowRemoteControl(KrfbConfig::allowDesktopControl());
connect(dialog, SIGNAL(okClicked()), SLOT(dialogAccepted()));
connect(dialog, SIGNAL(cancelClicked()), SLOT(reject()));
dialog->show();
}
}
void PendingTubesRfbClient::dialogAccepted()
{
TubesConnectionDialog *dialog = qobject_cast<TubesConnectionDialog *>(sender());
Q_ASSERT(dialog);
TubesRfbClient *client = new TubesRfbClient(m_rfbClient, m_contact, parent());
client->setControlEnabled(dialog->allowRemoteControl());
accept(client);
}
#include "tubesrfbclient.moc"

View File

@@ -1,58 +0,0 @@
/*
Copyright (C) 2010 Collabora Ltd. <info@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TUBESRFBCLIENT_H
#define TUBESRFBCLIENT_H
#include "rfbclient.h"
#include <TelepathyQt/Contact>
class TubesRfbClient : public RfbClient
{
public:
TubesRfbClient(rfbClientPtr client, const Tp::ContactPtr & contact, QObject* parent = 0)
: RfbClient(client, parent), m_contact(contact) {}
virtual QString name() const;
private:
Tp::ContactPtr m_contact;
};
class PendingTubesRfbClient : public PendingRfbClient
{
Q_OBJECT
public:
PendingTubesRfbClient(rfbClientPtr client, QObject* parent = 0)
: PendingRfbClient(client, parent), m_processNewClientCalled(false) {}
void setContact(const Tp::ContactPtr & contact);
protected Q_SLOTS:
virtual void processNewClient();
private Q_SLOTS:
void showConfirmationDialog();
void dialogAccepted();
private:
Tp::ContactPtr m_contact;
bool m_processNewClientCalled;
};
#endif // TUBESRFBCLIENT_H

View File

@@ -1,198 +0,0 @@
/*
Copyright (C) 2009-2011 Collabora Ltd. <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tubesrfbserver.h"
#include "tubesrfbclient.h"
#include "sockethelpers.h"
#include <KDebug>
#include <KRandom>
#include <TelepathyQt/Debug>
#include <TelepathyQt/Contact>
#include <TelepathyQt/AccountFactory>
#include <TelepathyQt/ConnectionFactory>
#include <TelepathyQt/ContactFactory>
#include <TelepathyQt/ChannelFactory>
#include <TelepathyQt/OutgoingStreamTubeChannel>
#include <TelepathyQt/StreamTubeServer>
struct TubesRfbServer::Private
{
Tp::StreamTubeServerPtr stubeServer;
QHash<quint16, Tp::ContactPtr> contactsPerPort;
QHash<quint16, PendingTubesRfbClient*> clientsPerPort;
};
void TubesRfbServer::init()
{
new TubesRfbServer();
//RfbServerManager takes care of deletion
}
TubesRfbServer::TubesRfbServer(QObject *parent)
: RfbServer(parent), d(new Private)
{
kDebug() << "starting";
Tp::enableDebug(true);
Tp::enableWarnings(true);
Tp::registerTypes();
Tp::AccountFactoryPtr accountFactory = Tp::AccountFactory::create(
QDBusConnection::sessionBus(), Tp::Account::FeatureCore);
Tp::ConnectionFactoryPtr connectionFactory = Tp::ConnectionFactory::create(
QDBusConnection::sessionBus(), Tp::Connection::FeatureCore);
Tp::ChannelFactoryPtr channelFactory = Tp::ChannelFactory::create(
QDBusConnection::sessionBus());
Tp::ContactFactoryPtr contactFactory = Tp::ContactFactory::create(
Tp::Contact::FeatureAlias);
d->stubeServer = Tp::StreamTubeServer::create(
QStringList() << QLatin1String("rfb"),
QStringList(),
QLatin1String("krfb_rfb_handler"),
true,
accountFactory,
connectionFactory,
channelFactory,
contactFactory);
connect(d->stubeServer.data(),
SIGNAL(tubeRequested(Tp::AccountPtr,Tp::OutgoingStreamTubeChannelPtr,
QDateTime,Tp::ChannelRequestHints)),
SLOT(onTubeRequested()));
connect(d->stubeServer.data(),
SIGNAL(tubeClosed(Tp::AccountPtr,Tp::OutgoingStreamTubeChannelPtr,QString,QString)),
SLOT(onTubeClosed()));
connect(d->stubeServer.data(),
SIGNAL(newTcpConnection(QHostAddress,quint16,Tp::AccountPtr,
Tp::ContactPtr,Tp::OutgoingStreamTubeChannelPtr)),
SLOT(onNewTcpConnection(QHostAddress,quint16,Tp::AccountPtr,
Tp::ContactPtr,Tp::OutgoingStreamTubeChannelPtr)));
connect(d->stubeServer.data(),
SIGNAL(tcpConnectionClosed(QHostAddress,quint16,Tp::AccountPtr,Tp::ContactPtr,
QString,QString,Tp::OutgoingStreamTubeChannelPtr)),
SLOT(onTcpConnectionClosed(QHostAddress,quint16,Tp::AccountPtr,Tp::ContactPtr,
QString,QString,Tp::OutgoingStreamTubeChannelPtr)));
// Pick a random port in the private range (4915265535)
setListeningPort((KRandom::random() % 16383) + 49152);
// Listen only on the loopback network interface
setListeningAddress("127.0.0.1");
setPasswordRequired(false);
QTimer::singleShot(0, this, SLOT(startAndCheck()));
}
TubesRfbServer::~TubesRfbServer()
{
kDebug();
delete d;
}
void TubesRfbServer::startAndCheck()
{
if (!start()) {
//try a few times with different ports
bool ok = false;
for (int i=0; !ok && i<5; i++) {
setListeningPort((KRandom::random() % 16383) + 49152);
ok = start();
}
if (!ok) {
kError() << "Failed to start tubes rfb server";
return;
}
}
//TODO listeningAddress() should be a QHostAddress
d->stubeServer->exportTcpSocket(QHostAddress(QString::fromAscii(listeningAddress())),
listeningPort());
}
void TubesRfbServer::onTubeRequested()
{
kDebug() << "Got a tube";
}
void TubesRfbServer::onTubeClosed()
{
kDebug() << "tube closed";
}
void TubesRfbServer::onNewTcpConnection(const QHostAddress & sourceAddress,
quint16 sourcePort,
const Tp::AccountPtr & account,
const Tp::ContactPtr & contact,
const Tp::OutgoingStreamTubeChannelPtr & tube)
{
Q_UNUSED(account);
Q_UNUSED(tube);
kDebug() << "CM signaled tube connection from" << sourceAddress << ":" << sourcePort;
d->contactsPerPort[sourcePort] = contact;
if (d->clientsPerPort.contains(sourcePort)) {
kDebug() << "client already exists";
d->clientsPerPort[sourcePort]->setContact(contact);
}
}
void TubesRfbServer::onTcpConnectionClosed(const QHostAddress& sourceAddress,
quint16 sourcePort,
const Tp::AccountPtr& account,
const Tp::ContactPtr& contact,
const QString& error,
const QString& message,
const Tp::OutgoingStreamTubeChannelPtr& tube)
{
Q_UNUSED(account);
Q_UNUSED(contact);
Q_UNUSED(tube);
kDebug() << "Connection from" << sourceAddress << ":" << sourcePort << "closed."
<< error << message;
d->clientsPerPort.remove(sourcePort);
d->contactsPerPort.remove(sourcePort);
}
PendingRfbClient* TubesRfbServer::newClient(rfbClientPtr client)
{
PendingTubesRfbClient *c = new PendingTubesRfbClient(client, this);
quint16 port = peerPort(client->sock);
kDebug() << "new tube client on port" << port;
d->clientsPerPort[port] = c;
if (d->contactsPerPort.contains(port)) {
kDebug() << "already have a contact";
c->setContact(d->contactsPerPort[port]);
}
return c;
}
#include "tubesrfbserver.moc"

View File

@@ -1,66 +0,0 @@
/*
Copyright (C) 2009-2011 Collabora Ltd. <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TUBESRFBSERVER_H
#define TUBESRFBSERVER_H
#include "rfbserver.h"
#include <QtNetwork/QHostAddress>
#include <TelepathyQt/Types>
class TubesRfbServer : public RfbServer
{
Q_OBJECT
public:
static void init();
virtual ~TubesRfbServer();
protected:
TubesRfbServer(QObject *parent = 0);
virtual PendingRfbClient* newClient(rfbClientPtr client);
private Q_SLOTS:
void startAndCheck();
void onTubeRequested();
void onTubeClosed();
void onNewTcpConnection(
const QHostAddress &sourceAddress,
quint16 sourcePort,
const Tp::AccountPtr &account,
const Tp::ContactPtr &contact,
const Tp::OutgoingStreamTubeChannelPtr &tube);
void onTcpConnectionClosed(
const QHostAddress &sourceAddress,
quint16 sourcePort,
const Tp::AccountPtr &account,
const Tp::ContactPtr &contact,
const QString &error,
const QString &message,
const Tp::OutgoingStreamTubeChannelPtr &tube);
private:
struct Private;
Private *const d;
};
#endif // TUBESRFBSERVER_H

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Framebuffer</class>
<widget class="QWidget" name="Framebuffer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>418</width>
<height>186</height>
</rect>
</property>
<property name="windowTitle">
<string>Framebuffer</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Preferred frameb&amp;uffer plugin:</string>
</property>
<property name="buddy">
<cstring>cb_preferredFrameBufferPlugin</cstring>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cb_preferredFrameBufferPlugin">
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="kcfg_preferredFrameBufferPlugin"/>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="helpText">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;When using x11, &lt;span style=&quot; font-weight:600;&quot;&gt;xcb&lt;/span&gt; plugin should be preferred, because it is more performant.&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;qt&lt;/span&gt; plugin is a safe fallback, if for some reason others don't work. But also it is very slow.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>5</number>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>63</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<tabstops>
<tabstop>cb_preferredFrameBufferPlugin</tabstop>
<tabstop>kcfg_preferredFrameBufferPlugin</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -11,19 +11,6 @@
</rect>
</property>
<layout class="QVBoxLayout">
<item>
<widget class="QCheckBox" name="kcfg_askOnConnect">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Ask before accepting connections</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_allowDesktopControl">
<property name="text">
@@ -34,36 +21,6 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_allowUninvitedConnections">
<property name="text">
<string>Allow uninvited connections</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Uninvited connections password:</string>
</property>
<property name="buddy">
<cstring>kcfg_uninvitedConnectionPassword</cstring>
</property>
</widget>
</item>
<item>
<widget class="KLineEdit" name="kcfg_uninvitedConnectionPassword">
<property name="enabled">
<bool>false</bool>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
@@ -79,46 +36,6 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KLineEdit</class>
<extends>QLineEdit</extends>
<header>klineedit.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>kcfg_allowUninvitedConnections</sender>
<signal>toggled(bool)</signal>
<receiver>kcfg_uninvitedConnectionPassword</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>98</x>
<y>21</y>
</hint>
<hint type="destinationlabel">
<x>192</x>
<y>137</y>
</hint>
</hints>
</connection>
<connection>
<sender>kcfg_allowUninvitedConnections</sender>
<signal>toggled(bool)</signal>
<receiver>label</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>117</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>120</x>
<y>94</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>

View File

@@ -1,171 +0,0 @@
<ui version="4.0" >
<class>InviteWidget</class>
<widget class="QWidget" name="InviteWidget" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>603</width>
<height>364</height>
</rect>
</property>
<layout class="QHBoxLayout" >
<item>
<widget class="QLabel" name="pixmapLabel" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>128</width>
<height>128</height>
</size>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" >
<item>
<widget class="QLabel" name="TextLabel2" >
<property name="font" >
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text" >
<string>Welcome to KDE Desktop Sharing</string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="helpLabel" >
<property name="text" >
<string>KDE Desktop Sharing allows you to invite somebody at a remote location to watch and possibly control your desktop. &lt;a href="whatsthis">More about invitations...&lt;/a></string>
</property>
<property name="textFormat" >
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap" >
<bool>true</bool>
</property>
<property name="textInteractionFlags" >
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" >
<size>
<width>215</width>
<height>101</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" >
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<size>
<width>90</width>
<height>26</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" >
<item>
<widget class="QPushButton" name="btnCreateInvite" >
<property name="toolTip" >
<string/>
</property>
<property name="whatsThis" >
<string>Create a new invitation and display the connection data. Use this option if you want to invite somebody personally, for example, to give the connection data over the phone.</string>
</property>
<property name="text" >
<string>Create &amp;Personal Invitation...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnEmailInvite" >
<property name="whatsThis" >
<string>This button will start your email application with a pre-configured text that explains to the recipient how to connect to your computer. </string>
</property>
<property name="text" >
<string>Invite via &amp;Email...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnManageInvite" >
<property name="text" >
<string>&amp;Manage Invitations (%1)...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<size>
<width>90</width>
<height>26</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>24</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

532
krfb/ui/mainwidget.ui Normal file
View File

@@ -0,0 +1,532 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWidget</class>
<widget class="QWidget" name="MainWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>340</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>600</width>
<height>340</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="krfbIconLabel">
<property name="minimumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="rightLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<item>
<widget class="QLabel" name="titleLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>400</width>
<height>20</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>40</height>
</size>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="whatsThis">
<string>KDE Desktop Sharing</string>
</property>
<property name="text">
<string>KDE Desktop Sharing</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="aboutLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>400</width>
<height>40</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>80</height>
</size>
</property>
<property name="whatsThis">
<string>KDE Desktop Sharing</string>
</property>
<property name="text">
<string>KDE Desktop Sharing allows you to grant permission to someone at a remote location for viewing and possibly controlling your desktop.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="enableSharingCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>400</width>
<height>20</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>40</height>
</size>
</property>
<property name="whatsThis">
<string>Starts/Stops Remote Desktop Sharing</string>
</property>
<property name="text">
<string>&amp;Enable Desktop Sharing</string>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="detailsGroupBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="title">
<string>Connection Details</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="addressFormLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<property name="formAlignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<item row="0" column="0">
<widget class="QLabel" name="addressLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;Address</string>
</property>
<property name="buddy">
<cstring>addressAboutButton</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QGridLayout" name="addressGridLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<item row="0" column="1">
<widget class="QToolButton" name="addressAboutButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="whatsThis">
<string>More about this address</string>
</property>
<property name="text">
<string>About</string>
</property>
<property name="icon">
<iconset theme="help-about">
<normaloff/>
</iconset>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="addressDisplayLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="whatsThis">
<string>Address required by remote users to connect to your desktop. Click about button on the right for more info.</string>
</property>
<property name="text">
<string>127.0.0.1 : 5900</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QFormLayout" name="passwordFormLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<property name="formAlignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<item row="0" column="0">
<widget class="QLabel" name="passwordLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;Password</string>
</property>
<property name="buddy">
<cstring>passwordEditButton</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QGridLayout" name="passwordGridLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<item row="0" column="1">
<widget class="QToolButton" name="passwordEditButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="whatsThis">
<string>Edit/Save Desktop Sharing Password</string>
</property>
<property name="text">
<string>Edit</string>
</property>
<property name="icon">
<iconset theme="document-edit">
<normaloff/>
</iconset>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="passwordDisplayLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="whatsThis">
<string>Password required by remote users to connect to your desktop. Click the edit button on the right to change password.</string>
</property>
<property name="text">
<string>TemporaryPassword</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="unattendedGroupBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="whatsThis">
<string>Unattended Access allows a remote user with the password to gain control to your desktop without your explicit confirmation.</string>
</property>
<property name="title">
<string>Unattended Access</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="unattendedDetailsLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>10</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>10</number>
</property>
<item>
<widget class="QLabel" name="unattendedAboutLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>80</height>
</size>
</property>
<property name="whatsThis">
<string>Unattended Access allows a remote user with the password to gain control to your desktop without your explicit confirmation. Click &quot;About&quot; button on right to know more.</string>
</property>
<property name="text">
<string>Unattended Access allows a remote user with the password to gain control to your desktop without your explicit confirmation.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="unattendedAboutButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="whatsThis">
<string>Know more about Unattended Access</string>
</property>
<property name="text">
<string>About</string>
</property>
<property name="icon">
<iconset theme="help-about">
<normaloff/>
</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="unattendedSettingsLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>10</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>10</number>
</property>
<item>
<widget class="QCheckBox" name="enableUnattendedCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>80</height>
</size>
</property>
<property name="whatsThis">
<string>Starts/Stops unattended access to your desktop. Click on button on right to change password, and &quot;About&quot; button to know more.</string>
</property>
<property name="text">
<string>Enable &amp;Unattended Access</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="unattendedPasswordButton">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>320</width>
<height>80</height>
</size>
</property>
<property name="whatsThis">
<string>Change password for Unattended Access</string>
</property>
<property name="text">
<string>&amp;Change Unattended Password</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="tpContactsLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
</layout>
</item>
</layout>
</widget>
<customwidgets>
</customwidgets>
<tabstops>
<tabstop>enableSharingCheckBox</tabstop>
<tabstop>addressAboutButton</tabstop>
<tabstop>passwordEditButton</tabstop>
<tabstop>enableUnattendedCheckBox</tabstop>
<tabstop>unattendedPasswordButton</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>enableSharingCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>detailsGroupBox</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>382</x>
<y>87</y>
</hint>
<hint type="destinationlabel">
<x>245</x>
<y>140</y>
</hint>
</hints>
</connection>
<connection>
<sender>enableSharingCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>unattendedGroupBox</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>320</x>
<y>76</y>
</hint>
<hint type="destinationlabel">
<x>325</x>
<y>214</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -1,190 +0,0 @@
<ui version="4.0" >
<class>ManageInvitationsDialog</class>
<widget class="QWidget" name="ManageInvitationsDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>550</width>
<height>337</height>
</rect>
</property>
<property name="windowTitle" >
<string>Manage Invitations - Desktop Sharing</string>
</property>
<layout class="QGridLayout" >
<item row="0" column="1" colspan="2" >
<widget class="QLabel" name="TextLabel2" >
<property name="font" >
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text" >
<string>Welcome to KDE Desktop Sharing</string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2" >
<widget class="QLabel" name="helpLabel" >
<property name="text" >
<string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
p, li { white-space: pre-wrap; }
&lt;/style>&lt;/head>&lt;body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;">
&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">KDE Desktop Sharing allows you to invite somebody at a remote location to watch and possibly control your desktop. &lt;a href="whatsthis">More about invitations...&lt;/a>&lt;/p>&lt;/body>&lt;/html></string>
</property>
<property name="textFormat" >
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap" >
<bool>true</bool>
</property>
<property name="openExternalLinks" >
<bool>false</bool>
</property>
<property name="textInteractionFlags" >
<set>Qt::LinksAccessibleByMouse</set>
</property>
</widget>
</item>
<item rowspan="3" row="2" column="0" >
<widget class="QLabel" name="pixmapLabel" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Maximum" hsizetype="Maximum" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>128</width>
<height>128</height>
</size>
</property>
</widget>
</item>
<item rowspan="5" row="2" column="1" >
<widget class="QTreeWidget" name="invitationWidget" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="alternatingRowColors" >
<bool>true</bool>
</property>
<property name="rootIsDecorated" >
<bool>false</bool>
</property>
<property name="allColumnsShowFocus" >
<bool>true</bool>
</property>
<column>
<property name="text" >
<string>Creation Time</string>
</property>
</column>
<column>
<property name="text" >
<string>Expire Time</string>
</property>
</column>
</widget>
</item>
<item row="2" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<size>
<width>155</width>
<height>62</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="2" >
<widget class="QPushButton" name="newPersonalInvitationButton" >
<property name="toolTip" >
<string>Create a new personal invitation...</string>
</property>
<property name="whatsThis" >
<string>Click this button to create a new personal invitation.</string>
</property>
<property name="text" >
<string>New &amp;Personal Invitation...</string>
</property>
</widget>
</item>
<item row="4" column="2" >
<widget class="QPushButton" name="newEmailInvitationButton" >
<property name="toolTip" >
<string>Send a new invitation via email...</string>
</property>
<property name="whatsThis" >
<string>Click this button to send a new invitation via email.</string>
</property>
<property name="text" >
<string>&amp;New Email Invitation...</string>
</property>
</widget>
</item>
<item row="5" column="2" >
<widget class="QPushButton" name="deleteAllButton" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="toolTip" >
<string>Delete all invitations</string>
</property>
<property name="whatsThis" >
<string>Deletes all open invitations.</string>
</property>
<property name="text" >
<string>Delete All</string>
</property>
</widget>
</item>
<item row="6" column="2" >
<widget class="QPushButton" name="deleteOneButton" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="toolTip" >
<string>Delete the selected invitation</string>
</property>
<property name="whatsThis" >
<string>Delete the selected invitation. The invited person will not be able to connect using this invitation anymore.</string>
</property>
<property name="text" >
<string>&amp;Delete</string>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>invitationWidget</tabstop>
<tabstop>newPersonalInvitationButton</tabstop>
<tabstop>newEmailInvitationButton</tabstop>
<tabstop>deleteAllButton</tabstop>
<tabstop>deleteOneButton</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -1,205 +0,0 @@
<ui version="4.0" >
<class>PersonalInviteWidget</class>
<widget class="QWidget" name="PersonalInviteWidget" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>567</width>
<height>324</height>
</rect>
</property>
<layout class="QHBoxLayout" >
<item>
<widget class="QLabel" name="pixmapLabel" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize" >
<size>
<width>128</width>
<height>128</height>
</size>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" >
<item>
<widget class="QLabel" name="mainTextLabel" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Minimum" hsizetype="Expanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy" >
<enum>Qt::NoFocus</enum>
</property>
<property name="text" >
<string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
p, li { white-space: pre-wrap; }
&lt;/style>&lt;/head>&lt;body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;">
&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">&lt;span style=" font-weight:600;">Personal Invitation&lt;/span>&lt;/p>
&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Give the information below to the person that you want to invite (&lt;a href="htc">how to connect&lt;/a>). Note that everybody who gets the password can connect, so be careful.&lt;/p>&lt;/body>&lt;/html></string>
</property>
<property name="wordWrap" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>21</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="kActiveLabel5" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Minimum" hsizetype="MinimumExpanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text" >
<string>&lt;b>Host:&lt;/b></string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QLabel" name="hostLabel" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Minimum" hsizetype="MinimumExpanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy" >
<enum>Qt::NoFocus</enum>
</property>
<property name="textInteractionFlags" >
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::NoTextInteraction|Qt::TextBrowserInteraction|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="0" column="2" >
<widget class="QLabel" name="hostHelpLabel" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Minimum" hsizetype="MinimumExpanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text" >
<string>&lt;html>&lt;head>&lt;meta name="qrichtext" content="1" />&lt;style type="text/css">
p, li { white-space: pre-wrap; }
&lt;/style>&lt;/head>&lt;body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;">
&lt;p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">&lt;a href="help">Help&lt;/a>&lt;/p>&lt;/body>&lt;/html></string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="kActiveLabel6" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Minimum" hsizetype="MinimumExpanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text" >
<string>&lt;b>Password:&lt;/b></string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QLabel" name="passwordLabel" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Minimum" hsizetype="MinimumExpanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy" >
<enum>Qt::NoFocus</enum>
</property>
<property name="textInteractionFlags" >
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::NoTextInteraction|Qt::TextBrowserInteraction|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="kActiveLabel7" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Minimum" hsizetype="MinimumExpanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text" >
<string>&lt;b>Expiration time:&lt;/b></string>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLabel" name="expirationLabel" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Minimum" hsizetype="MinimumExpanding" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy" >
<enum>Qt::NoFocus</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>65</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -1,114 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TubesConnectionWidget</class>
<widget class="QWidget" name="TubesConnectionWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>162</height>
</rect>
</property>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel" name="pixmapLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout">
<item>
<widget class="QLabel" name="TextLabel5">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>13</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Confirmation</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="indent">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="mainTextLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="lineWidth">
<number>-1</number>
</property>
<property name="midLineWidth">
<number>5</number>
</property>
<property name="text">
<string/>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>0</number>
</property>
<property name="indent">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbAllowRemoteControl">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="whatsThis">
<string>If you turn this option on, the remote user can enter keystrokes and use your mouse pointer. This gives them full control over your computer, so be careful. When the option is disabled the remote user can only watch your screen.</string>
</property>
<property name="text">
<string>Allow remote user to &amp;control keyboard and mouse</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -1,132 +0,0 @@
# Striped down version of libvncserver's original CMakeLists.txt
project(LibVNCServer)
include(CheckFunctionExists)
include(CheckIncludeFile)
include(CheckTypeSize)
include(TestBigEndian)
include(MacroBoolTo01)
set(FULL_PACKAGE_NAME "Krfb LibVNCServer")
set(PACKAGE_VERSION "0.9.8-10-g17ce0c5")
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
macro_optional_find_package(ZLIB)
macro_log_feature(ZLIB_FOUND "ZLib" "The Zlib compression library" "http://www.zlib.net" FALSE "" "Used by the vncserver library.")
macro_optional_find_package(JPEG)
macro_log_feature(JPEG_FOUND "LibJPEG" "The JPEG library" "" FALSE "" "Used by the vncserver library")
macro_bool_to_01(ZLIB_FOUND LIBVNCSERVER_HAVE_LIBZ)
macro_bool_to_01(JPEG_FOUND LIBVNCSERVER_HAVE_LIBJPEG)
option(LIBVNCSERVER_ALLOW24BPP "Allow 24 bpp" ON)
# if(GNUTLS_FOUND)
# set(LIBVNCSERVER_WITH_CLIENT_TLS 1)
# endif(GNUTLS_FOUND)
# if(LIBGCRYPT_LIBRARIES)
# message(STATUS "Found libgcrypt: ${LIBGCRYPT_LIBRARIES}")
# set(LIBVNCSERVER_WITH_CLIENT_GCRYPT 1)
# endif(LIBGCRYPT_LIBRARIES)
check_include_file("fcntl.h" LIBVNCSERVER_HAVE_FCNTL_H)
check_include_file("netinet/in.h" LIBVNCSERVER_HAVE_NETINET_IN_H)
check_include_file("sys/socket.h" LIBVNCSERVER_HAVE_SYS_SOCKET_H)
check_include_file("sys/stat.h" LIBVNCSERVER_HAVE_SYS_STAT_H)
check_include_file("sys/time.h" LIBVNCSERVER_HAVE_SYS_TIME_H)
check_include_file("sys/types.h" LIBVNCSERVER_HAVE_SYS_TYPES_H)
check_include_file("sys/wait.h" LIBVNCSERVER_HAVE_SYS_WAIT_H)
check_include_file("unistd.h" LIBVNCSERVER_HAVE_UNISTD_H)
# headers needed for check_type_size()
check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
check_include_file("stdint.h" HAVE_STDINT_H)
check_include_file("stddef.h" HAVE_STDDEF_H)
check_include_file("sys/types.h" HAVE_SYS_TYPES_H)
check_function_exists(gettimeofday LIBVNCSERVER_HAVE_GETTIMEOFDAY)
macro_bool_to_01(CMAKE_USE_PTHREADS_INIT LIBVNCSERVER_HAVE_LIBPTHREAD)
if(LIBVNCSERVER_HAVE_SYS_SOCKET_H)
# socklen_t
list(APPEND CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h")
endif(LIBVNCSERVER_HAVE_SYS_SOCKET_H)
if(HAVE_ARPA_INET_H)
# in_addr_t
list(APPEND CMAKE_EXTRA_INCLUDE_FILES "arpa/inet.h")
endif(HAVE_ARPA_INET_H)
check_type_size(pid_t LIBVNCSERVER_PID_T)
check_type_size(size_t LIBVNCSERVER_SIZE_T)
check_type_size(socklen_t LIBVNCSERVER_SOCKLEN_T)
check_type_size(in_addr_t LIBVNCSERVER_IN_ADDR_T)
if(NOT HAVE_LIBVNCSERVER_IN_ADDR_T)
set(LIBVNCSERVER_NEED_INADDR_T 1)
endif(NOT HAVE_LIBVNCSERVER_IN_ADDR_T)
test_big_endian(LIBVNCSERVER_WORDS_BIGENDIAN)
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/libvncserver-config.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/libvncserver-config.h
)
set(LIBVNCSERVER_SOURCES
main.c
rfbserver.c
rfbregion.c
auth.c
sockets.c
stats.c
corre.c
hextile.c
rre.c
translate.c
cutpaste.c
httpd.c
cursor.c
font.c
draw.c
selbox.c
d3des.c
vncauth.c
cargs.c
minilzo.c
ultra.c
scale.c
)
if(ZLIB_FOUND)
add_definitions(-DLIBVNCSERVER_HAVE_LIBZ)
include_directories(${ZLIB_INCLUDE_DIR})
set(LIBVNCSERVER_SOURCES
${LIBVNCSERVER_SOURCES}
zlib.c
zrle.c
zrleoutstream.c
zrlepalettehelper.c
)
endif(ZLIB_FOUND)
if(JPEG_FOUND)
add_definitions(-DLIBVNCSERVER_HAVE_LIBJPEG)
include_directories(${JPEG_INCLUDE_DIR})
set(LIBVNCSERVER_SOURCES
${LIBVNCSERVER_SOURCES}
tight.c
)
endif(JPEG_FOUND)
add_library(vncserver STATIC ${LIBVNCSERVER_SOURCES})
if(WIN32)
set(ADDITIONAL_LIBS ws2_32)
endif(WIN32)
target_link_libraries(vncserver
${ADDITIONAL_LIBS}
${ZLIB_LIBRARIES}
${JPEG_LIBRARIES}
)

View File

@@ -1,375 +0,0 @@
/*
* auth.c - deal with authentication.
*
* This file implements the VNC authentication protocol when setting up an RFB
* connection.
*/
/*
* Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* All Rights Reserved.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "rfb/rfb.h"
/* RFB 3.8 clients are well informed */
void rfbClientSendString(rfbClientPtr cl, const char *reason);
/*
* Handle security types
*/
static rfbSecurityHandler* securityHandlers = NULL;
/*
* This method registers a list of new security types.
* It avoids same security type getting registered multiple times.
* The order is not preserved if multiple security types are
* registered at one-go.
*/
void
rfbRegisterSecurityHandler(rfbSecurityHandler* handler)
{
rfbSecurityHandler *head = securityHandlers, *next = NULL;
if(handler == NULL)
return;
next = handler->next;
while(head != NULL) {
if(head == handler) {
rfbRegisterSecurityHandler(next);
return;
}
head = head->next;
}
handler->next = securityHandlers;
securityHandlers = handler;
rfbRegisterSecurityHandler(next);
}
/*
* This method unregisters a list of security types.
* These security types won't be available for any new
* client connection.
*/
void
rfbUnregisterSecurityHandler(rfbSecurityHandler* handler)
{
rfbSecurityHandler *cur = NULL, *pre = NULL;
if(handler == NULL)
return;
if(securityHandlers == handler) {
securityHandlers = securityHandlers->next;
rfbUnregisterSecurityHandler(handler->next);
return;
}
cur = pre = securityHandlers;
while(cur) {
if(cur == handler) {
pre->next = cur->next;
break;
}
pre = cur;
cur = cur->next;
}
rfbUnregisterSecurityHandler(handler->next);
}
/*
* Send the authentication challenge.
*/
static void
rfbVncAuthSendChallenge(rfbClientPtr cl)
{
/* 4 byte header is alreay sent. Which is rfbSecTypeVncAuth
(same as rfbVncAuth). Just send the challenge. */
rfbRandomBytes(cl->authChallenge);
if (rfbWriteExact(cl, (char *)cl->authChallenge, CHALLENGESIZE) < 0) {
rfbLogPerror("rfbAuthNewClient: write");
rfbCloseClient(cl);
return;
}
/* Dispatch client input to rfbVncAuthProcessResponse. */
cl->state = RFB_AUTHENTICATION;
}
/*
* Send the NO AUTHENTICATION. SCARR
*/
static void
rfbVncAuthNone(rfbClientPtr cl)
{
uint32_t authResult;
if (cl->protocolMajorVersion==3 && cl->protocolMinorVersion > 7) {
rfbLog("rfbProcessClientSecurityType: returning securityResult for client rfb version >= 3.8\n");
authResult = Swap32IfLE(rfbVncAuthOK);
if (rfbWriteExact(cl, (char *)&authResult, 4) < 0) {
rfbLogPerror("rfbAuthProcessClientMessage: write");
rfbCloseClient(cl);
return;
}
}
cl->state = RFB_INITIALISATION;
return;
}
/*
* Advertise the supported security types (protocol 3.7). Here before sending
* the list of security types to the client one more security type is added
* to the list if primaryType is not set to rfbSecTypeInvalid. This security
* type is the standard vnc security type which does the vnc authentication
* or it will be security type for no authentication.
* Different security types will be added by applications using this library.
*/
static rfbSecurityHandler VncSecurityHandlerVncAuth = {
rfbSecTypeVncAuth,
rfbVncAuthSendChallenge,
NULL
};
static rfbSecurityHandler VncSecurityHandlerNone = {
rfbSecTypeNone,
rfbVncAuthNone,
NULL
};
static void
rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
{
/* The size of the message is the count of security types +1,
* since the first byte is the number of types. */
int size = 1;
rfbSecurityHandler* handler;
#define MAX_SECURITY_TYPES 255
uint8_t buffer[MAX_SECURITY_TYPES+1];
/* Fill in the list of security types in the client structure. (NOTE: Not really in the client structure) */
switch (primaryType) {
case rfbSecTypeNone:
rfbRegisterSecurityHandler(&VncSecurityHandlerNone);
break;
case rfbSecTypeVncAuth:
rfbRegisterSecurityHandler(&VncSecurityHandlerVncAuth);
break;
}
for (handler = securityHandlers;
handler && size<MAX_SECURITY_TYPES; handler = handler->next) {
buffer[size] = handler->type;
size++;
}
buffer[0] = (unsigned char)size-1;
/* Send the list. */
if (rfbWriteExact(cl, (char *)buffer, size) < 0) {
rfbLogPerror("rfbSendSecurityTypeList: write");
rfbCloseClient(cl);
return;
}
/*
* if count is 0, we need to send the reason and close the connection.
*/
if(size <= 1) {
/* This means total count is Zero and so reason msg should be sent */
/* The execution should never reach here */
char* reason = "No authentication mode is registered!";
rfbClientSendString(cl, reason);
return;
}
/* Dispatch client input to rfbProcessClientSecurityType. */
cl->state = RFB_SECURITY_TYPE;
}
/*
* Tell the client what security type will be used (protocol 3.3).
*/
static void
rfbSendSecurityType(rfbClientPtr cl, int32_t securityType)
{
uint32_t value32;
/* Send the value. */
value32 = Swap32IfLE(securityType);
if (rfbWriteExact(cl, (char *)&value32, 4) < 0) {
rfbLogPerror("rfbSendSecurityType: write");
rfbCloseClient(cl);
return;
}
/* Decide what to do next. */
switch (securityType) {
case rfbSecTypeNone:
/* Dispatch client input to rfbProcessClientInitMessage. */
cl->state = RFB_INITIALISATION;
break;
case rfbSecTypeVncAuth:
/* Begin the standard VNC authentication procedure. */
rfbVncAuthSendChallenge(cl);
break;
default:
/* Impossible case (hopefully). */
rfbLogPerror("rfbSendSecurityType: assertion failed");
rfbCloseClient(cl);
}
}
/*
* rfbAuthNewClient is called right after negotiating the protocol
* version. Depending on the protocol version, we send either a code
* for authentication scheme to be used (protocol 3.3), or a list of
* possible "security types" (protocol 3.7).
*/
void
rfbAuthNewClient(rfbClientPtr cl)
{
int32_t securityType = rfbSecTypeInvalid;
if (!cl->screen->authPasswdData || cl->reverseConnection) {
/* chk if this condition is valid or not. */
securityType = rfbSecTypeNone;
} else if (cl->screen->authPasswdData) {
securityType = rfbSecTypeVncAuth;
}
if (cl->protocolMajorVersion==3 && cl->protocolMinorVersion < 7)
{
/* Make sure we use only RFB 3.3 compatible security types. */
if (securityType == rfbSecTypeInvalid) {
rfbLog("VNC authentication disabled - RFB 3.3 client rejected\n");
rfbClientConnFailed(cl, "Your viewer cannot handle required "
"authentication methods");
return;
}
rfbSendSecurityType(cl, securityType);
} else {
/* Here it's ok when securityType is set to rfbSecTypeInvalid. */
rfbSendSecurityTypeList(cl, securityType);
}
}
/*
* Read the security type chosen by the client (protocol 3.7).
*/
void
rfbProcessClientSecurityType(rfbClientPtr cl)
{
int n;
uint8_t chosenType;
rfbSecurityHandler* handler;
/* Read the security type. */
n = rfbReadExact(cl, (char *)&chosenType, 1);
if (n <= 0) {
if (n == 0)
rfbLog("rfbProcessClientSecurityType: client gone\n");
else
rfbLogPerror("rfbProcessClientSecurityType: read");
rfbCloseClient(cl);
return;
}
/* Make sure it was present in the list sent by the server. */
for (handler = securityHandlers; handler; handler = handler->next) {
if (chosenType == handler->type) {
rfbLog("rfbProcessClientSecurityType: executing handler for type %d\n", chosenType);
handler->handler(cl);
return;
}
}
rfbLog("rfbProcessClientSecurityType: wrong security type (%d) requested\n", chosenType);
rfbCloseClient(cl);
}
/*
* rfbAuthProcessClientMessage is called when the client sends its
* authentication response.
*/
void
rfbAuthProcessClientMessage(rfbClientPtr cl)
{
int n;
uint8_t response[CHALLENGESIZE];
uint32_t authResult;
if ((n = rfbReadExact(cl, (char *)response, CHALLENGESIZE)) <= 0) {
if (n != 0)
rfbLogPerror("rfbAuthProcessClientMessage: read");
rfbCloseClient(cl);
return;
}
if(!cl->screen->passwordCheck(cl,(const char*)response,CHALLENGESIZE)) {
rfbErr("rfbAuthProcessClientMessage: password check failed\n");
authResult = Swap32IfLE(rfbVncAuthFailed);
if (rfbWriteExact(cl, (char *)&authResult, 4) < 0) {
rfbLogPerror("rfbAuthProcessClientMessage: write");
}
/* support RFB 3.8 clients, they expect a reason *why* it was disconnected */
if (cl->protocolMinorVersion > 7) {
rfbClientSendString(cl, "password check failed!");
}
else
rfbCloseClient(cl);
return;
}
authResult = Swap32IfLE(rfbVncAuthOK);
if (rfbWriteExact(cl, (char *)&authResult, 4) < 0) {
rfbLogPerror("rfbAuthProcessClientMessage: write");
rfbCloseClient(cl);
return;
}
cl->state = RFB_INITIALISATION;
}

View File

@@ -1,213 +0,0 @@
/*
* This parses the command line arguments. It was seperated from main.c by
* Justin Dearing <jdeari01@longisland.poly.edu>.
*/
/*
* LibVNCServer (C) 2001 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* Original OSXvnc (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc (C) 1999 AT&T Laboratories Cambridge.
* All Rights Reserved.
*
* see GPL (latest version) for full details
*/
#include "rfb/rfb.h"
extern int rfbStringToAddr(char *str, in_addr_t *iface);
void
rfbUsage(void)
{
rfbProtocolExtension* extension;
fprintf(stderr, "-rfbport port TCP port for RFB protocol\n");
fprintf(stderr, "-rfbwait time max time in ms to wait for RFB client\n");
fprintf(stderr, "-rfbauth passwd-file use authentication on RFB protocol\n"
" (use 'storepasswd' to create a password file)\n");
fprintf(stderr, "-rfbversion 3.x Set the version of the RFB we choose to advertise\n");
fprintf(stderr, "-permitfiletransfer permit file transfer support\n");
fprintf(stderr, "-passwd plain-password use authentication \n"
" (use plain-password as password, USE AT YOUR RISK)\n");
fprintf(stderr, "-deferupdate time time in ms to defer updates "
"(default 40)\n");
fprintf(stderr, "-deferptrupdate time time in ms to defer pointer updates"
" (default none)\n");
fprintf(stderr, "-desktop name VNC desktop name (default \"LibVNCServer\")\n");
fprintf(stderr, "-alwaysshared always treat new clients as shared\n");
fprintf(stderr, "-nevershared never treat new clients as shared\n");
fprintf(stderr, "-dontdisconnect don't disconnect existing clients when a "
"new non-shared\n"
" connection comes in (refuse new connection "
"instead)\n");
fprintf(stderr, "-httpdir dir-path enable http server using dir-path home\n");
fprintf(stderr, "-httpport portnum use portnum for http connection\n");
fprintf(stderr, "-enablehttpproxy enable http proxy support\n");
fprintf(stderr, "-progressive height enable progressive updating for slow links\n");
fprintf(stderr, "-listen ipaddr listen for connections only on network interface with\n");
fprintf(stderr, " addr ipaddr. '-listen localhost' and hostname work too.\n");
for(extension=rfbGetExtensionIterator();extension;extension=extension->next)
if(extension->usage)
extension->usage();
rfbReleaseExtensionIterator();
}
/* purges COUNT arguments from ARGV at POSITION and decrements ARGC.
POSITION points to the first non purged argument afterwards. */
void rfbPurgeArguments(int* argc,int* position,int count,char *argv[])
{
int amount=(*argc)-(*position)-count;
if(amount)
memmove(argv+(*position),argv+(*position)+count,sizeof(char*)*amount);
(*argc)-=count;
}
rfbBool
rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[])
{
int i,i1;
if(!argc) return TRUE;
for (i = i1 = 1; i < *argc;) {
if (strcmp(argv[i], "-help") == 0) {
rfbUsage();
return FALSE;
} else if (strcmp(argv[i], "-rfbport") == 0) { /* -rfbport port */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->port = atoi(argv[++i]);
} else if (strcmp(argv[i], "-rfbwait") == 0) { /* -rfbwait ms */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->maxClientWait = atoi(argv[++i]);
} else if (strcmp(argv[i], "-rfbauth") == 0) { /* -rfbauth passwd-file */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->authPasswdData = argv[++i];
} else if (strcmp(argv[i], "-permitfiletransfer") == 0) { /* -permitfiletransfer */
rfbScreen->permitFileTransfer = TRUE;
} else if (strcmp(argv[i], "-rfbversion") == 0) { /* -rfbversion 3.6 */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
sscanf(argv[++i],"%d.%d", &rfbScreen->protocolMajorVersion, &rfbScreen->protocolMinorVersion);
} else if (strcmp(argv[i], "-passwd") == 0) { /* -passwd password */
char **passwds = malloc(sizeof(char**)*2);
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
passwds[0] = argv[++i];
passwds[1] = NULL;
rfbScreen->authPasswdData = (void*)passwds;
rfbScreen->passwordCheck = rfbCheckPasswordByList;
} else if (strcmp(argv[i], "-deferupdate") == 0) { /* -deferupdate milliseconds */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->deferUpdateTime = atoi(argv[++i]);
} else if (strcmp(argv[i], "-deferptrupdate") == 0) { /* -deferptrupdate milliseconds */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->deferPtrUpdateTime = atoi(argv[++i]);
} else if (strcmp(argv[i], "-desktop") == 0) { /* -desktop desktop-name */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->desktopName = argv[++i];
} else if (strcmp(argv[i], "-alwaysshared") == 0) {
rfbScreen->alwaysShared = TRUE;
} else if (strcmp(argv[i], "-nevershared") == 0) {
rfbScreen->neverShared = TRUE;
} else if (strcmp(argv[i], "-dontdisconnect") == 0) {
rfbScreen->dontDisconnect = TRUE;
} else if (strcmp(argv[i], "-httpdir") == 0) { /* -httpdir directory-path */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->httpDir = argv[++i];
} else if (strcmp(argv[i], "-httpport") == 0) { /* -httpport portnum */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->httpPort = atoi(argv[++i]);
} else if (strcmp(argv[i], "-enablehttpproxy") == 0) {
rfbScreen->httpEnableProxyConnect = TRUE;
} else if (strcmp(argv[i], "-progressive") == 0) { /* -httpport portnum */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
rfbScreen->progressiveSliceHeight = atoi(argv[++i]);
} else if (strcmp(argv[i], "-listen") == 0) { /* -listen ipaddr */
if (i + 1 >= *argc) {
rfbUsage();
return FALSE;
}
if (! rfbStringToAddr(argv[++i], &(rfbScreen->listenInterface))) {
return FALSE;
}
} else {
rfbProtocolExtension* extension;
int handled=0;
for(extension=rfbGetExtensionIterator();handled==0 && extension;
extension=extension->next)
if(extension->processArgument)
handled = extension->processArgument(*argc - i, argv + i);
rfbReleaseExtensionIterator();
if(handled==0) {
i++;
i1=i;
continue;
}
i+=handled-1;
}
/* we just remove the processed arguments from the list */
rfbPurgeArguments(argc,&i1,i-i1+1,argv);
i=i1;
}
return TRUE;
}
rfbBool
rfbProcessSizeArguments(int* width,int* height,int* bpp,int* argc, char *argv[])
{
int i,i1;
if(!argc) return TRUE;
for (i = i1 = 1; i < *argc-1;) {
if (strcmp(argv[i], "-bpp") == 0) {
*bpp = atoi(argv[++i]);
} else if (strcmp(argv[i], "-width") == 0) {
*width = atoi(argv[++i]);
} else if (strcmp(argv[i], "-height") == 0) {
*height = atoi(argv[++i]);
} else {
i++;
i1=i;
continue;
}
rfbPurgeArguments(argc,&i1,i-i1,argv);
i=i1;
}
return TRUE;
}

View File

@@ -1,342 +0,0 @@
/*
* corre.c
*
* Routines to implement Compact Rise-and-Run-length Encoding (CoRRE). This
* code is based on krw's original javatel rfbserver.
*/
/*
* Copyright (C) 2002 RealVNC Ltd.
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* All Rights Reserved.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "rfb/rfb.h"
/*
* cl->beforeEncBuf contains pixel data in the client's format.
* cl->afterEncBuf contains the RRE encoded version. If the RRE encoded version is
* larger than the raw data or if it exceeds cl->afterEncBufSize then
* raw encoding is used instead.
*/
static int subrectEncode8(rfbClientPtr cl, uint8_t *data, int w, int h);
static int subrectEncode16(rfbClientPtr cl, uint16_t *data, int w, int h);
static int subrectEncode32(rfbClientPtr cl, uint32_t *data, int w, int h);
static uint32_t getBgColour(char *data, int size, int bpp);
static rfbBool rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl, int x, int y,
int w, int h);
/*
* rfbSendRectEncodingCoRRE - send an arbitrary size rectangle using CoRRE
* encoding.
*/
rfbBool
rfbSendRectEncodingCoRRE(rfbClientPtr cl,
int x,
int y,
int w,
int h)
{
if (h > cl->correMaxHeight) {
return (rfbSendRectEncodingCoRRE(cl, x, y, w, cl->correMaxHeight) &&
rfbSendRectEncodingCoRRE(cl, x, y + cl->correMaxHeight, w,
h - cl->correMaxHeight));
}
if (w > cl->correMaxWidth) {
return (rfbSendRectEncodingCoRRE(cl, x, y, cl->correMaxWidth, h) &&
rfbSendRectEncodingCoRRE(cl, x + cl->correMaxWidth, y,
w - cl->correMaxWidth, h));
}
rfbSendSmallRectEncodingCoRRE(cl, x, y, w, h);
return TRUE;
}
/*
* rfbSendSmallRectEncodingCoRRE - send a small (guaranteed < 256x256)
* rectangle using CoRRE encoding.
*/
static rfbBool
rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl,
int x,
int y,
int w,
int h)
{
rfbFramebufferUpdateRectHeader rect;
rfbRREHeader hdr;
int nSubrects;
int i;
char *fbptr = (cl->scaledScreen->frameBuffer + (cl->scaledScreen->paddedWidthInBytes * y)
+ (x * (cl->scaledScreen->bitsPerPixel / 8)));
int maxRawSize = (cl->scaledScreen->width * cl->scaledScreen->height
* (cl->format.bitsPerPixel / 8));
if (cl->beforeEncBufSize < maxRawSize) {
cl->beforeEncBufSize = maxRawSize;
if (cl->beforeEncBuf == NULL)
cl->beforeEncBuf = (char *)malloc(cl->beforeEncBufSize);
else
cl->beforeEncBuf = (char *)realloc(cl->beforeEncBuf, cl->beforeEncBufSize);
}
if (cl->afterEncBufSize < maxRawSize) {
cl->afterEncBufSize = maxRawSize;
if (cl->afterEncBuf == NULL)
cl->afterEncBuf = (char *)malloc(cl->afterEncBufSize);
else
cl->afterEncBuf = (char *)realloc(cl->afterEncBuf, cl->afterEncBufSize);
}
(*cl->translateFn)(cl->translateLookupTable,&(cl->screen->serverFormat),
&cl->format, fbptr, cl->beforeEncBuf,
cl->scaledScreen->paddedWidthInBytes, w, h);
switch (cl->format.bitsPerPixel) {
case 8:
nSubrects = subrectEncode8(cl, (uint8_t *)cl->beforeEncBuf, w, h);
break;
case 16:
nSubrects = subrectEncode16(cl, (uint16_t *)cl->beforeEncBuf, w, h);
break;
case 32:
nSubrects = subrectEncode32(cl, (uint32_t *)cl->beforeEncBuf, w, h);
break;
default:
rfbLog("getBgColour: bpp %d?\n",cl->format.bitsPerPixel);
return FALSE;
}
if (nSubrects < 0) {
/* RRE encoding was too large, use raw */
return rfbSendRectEncodingRaw(cl, x, y, w, h);
}
rfbStatRecordEncodingSent(cl,rfbEncodingCoRRE,
sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + cl->afterEncBufLen,
sz_rfbFramebufferUpdateRectHeader + w * h * (cl->format.bitsPerPixel / 8));
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader
> UPDATE_BUF_SIZE)
{
if (!rfbSendUpdateBuf(cl))
return FALSE;
}
rect.r.x = Swap16IfLE(x);
rect.r.y = Swap16IfLE(y);
rect.r.w = Swap16IfLE(w);
rect.r.h = Swap16IfLE(h);
rect.encoding = Swap32IfLE(rfbEncodingCoRRE);
memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,
sz_rfbFramebufferUpdateRectHeader);
cl->ublen += sz_rfbFramebufferUpdateRectHeader;
hdr.nSubrects = Swap32IfLE(nSubrects);
memcpy(&cl->updateBuf[cl->ublen], (char *)&hdr, sz_rfbRREHeader);
cl->ublen += sz_rfbRREHeader;
for (i = 0; i < cl->afterEncBufLen;) {
int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen;
if (i + bytesToCopy > cl->afterEncBufLen) {
bytesToCopy = cl->afterEncBufLen - i;
}
memcpy(&cl->updateBuf[cl->ublen], &cl->afterEncBuf[i], bytesToCopy);
cl->ublen += bytesToCopy;
i += bytesToCopy;
if (cl->ublen == UPDATE_BUF_SIZE) {
if (!rfbSendUpdateBuf(cl))
return FALSE;
}
}
return TRUE;
}
/*
* subrectEncode() encodes the given multicoloured rectangle as a background
* colour overwritten by single-coloured rectangles. It returns the number
* of subrectangles in the encoded buffer, or -1 if subrect encoding won't
* fit in the buffer. It puts the encoded rectangles in cl->afterEncBuf. The
* single-colour rectangle partition is not optimal, but does find the biggest
* horizontal or vertical rectangle top-left anchored to each consecutive
* coordinate position.
*
* The coding scheme is simply [<bgcolour><subrect><subrect>...] where each
* <subrect> is [<colour><x><y><w><h>].
*/
#define DEFINE_SUBRECT_ENCODE(bpp) \
static int \
subrectEncode##bpp(rfbClientPtr client, uint##bpp##_t *data, int w, int h) { \
uint##bpp##_t cl; \
rfbCoRRERectangle subrect; \
int x,y; \
int i,j; \
int hx=0,hy,vx=0,vy; \
int hyflag; \
uint##bpp##_t *seg; \
uint##bpp##_t *line; \
int hw,hh,vw,vh; \
int thex,they,thew,theh; \
int numsubs = 0; \
int newLen; \
uint##bpp##_t bg = (uint##bpp##_t)getBgColour((char*)data,w*h,bpp); \
\
*((uint##bpp##_t*)client->afterEncBuf) = bg; \
\
client->afterEncBufLen = (bpp/8); \
\
for (y=0; y<h; y++) { \
line = data+(y*w); \
for (x=0; x<w; x++) { \
if (line[x] != bg) { \
cl = line[x]; \
hy = y-1; \
hyflag = 1; \
for (j=y; j<h; j++) { \
seg = data+(j*w); \
if (seg[x] != cl) {break;} \
i = x; \
while ((seg[i] == cl) && (i < w)) i += 1; \
i -= 1; \
if (j == y) vx = hx = i; \
if (i < vx) vx = i; \
if ((hyflag > 0) && (i >= hx)) {hy += 1;} else {hyflag = 0;} \
} \
vy = j-1; \
\
/* We now have two possible subrects: (x,y,hx,hy) and (x,y,vx,vy) \
* We'll choose the bigger of the two. \
*/ \
hw = hx-x+1; \
hh = hy-y+1; \
vw = vx-x+1; \
vh = vy-y+1; \
\
thex = x; \
they = y; \
\
if ((hw*hh) > (vw*vh)) { \
thew = hw; \
theh = hh; \
} else { \
thew = vw; \
theh = vh; \
} \
\
subrect.x = thex; \
subrect.y = they; \
subrect.w = thew; \
subrect.h = theh; \
\
newLen = client->afterEncBufLen + (bpp/8) + sz_rfbCoRRERectangle; \
if ((newLen > (w * h * (bpp/8))) || (newLen > client->afterEncBufSize)) \
return -1; \
\
numsubs += 1; \
*((uint##bpp##_t*)(client->afterEncBuf + client->afterEncBufLen)) = cl; \
client->afterEncBufLen += (bpp/8); \
memcpy(&client->afterEncBuf[client->afterEncBufLen],&subrect,sz_rfbCoRRERectangle); \
client->afterEncBufLen += sz_rfbCoRRERectangle; \
\
/* \
* Now mark the subrect as done. \
*/ \
for (j=they; j < (they+theh); j++) { \
for (i=thex; i < (thex+thew); i++) { \
data[j*w+i] = bg; \
} \
} \
} \
} \
} \
\
return numsubs; \
}
DEFINE_SUBRECT_ENCODE(8)
DEFINE_SUBRECT_ENCODE(16)
DEFINE_SUBRECT_ENCODE(32)
/*
* getBgColour() gets the most prevalent colour in a byte array.
*/
static uint32_t
getBgColour(char *data, int size, int bpp)
{
#define NUMCLRS 256
static int counts[NUMCLRS];
int i,j,k;
int maxcount = 0;
uint8_t maxclr = 0;
if (bpp != 8) {
if (bpp == 16) {
return ((uint16_t *)data)[0];
} else if (bpp == 32) {
return ((uint32_t *)data)[0];
} else {
rfbLog("getBgColour: bpp %d?\n",bpp);
return 0;
}
}
for (i=0; i<NUMCLRS; i++) {
counts[i] = 0;
}
for (j=0; j<size; j++) {
k = (int)(((uint8_t *)data)[j]);
if (k >= NUMCLRS) {
rfbLog("getBgColour: unusual colour = %d\n", k);
return 0;
}
counts[k] += 1;
if (counts[k] > maxcount) {
maxcount = counts[k];
maxclr = ((uint8_t *)data)[j];
}
}
return maxclr;
}

View File

@@ -1,756 +0,0 @@
/*
* cursor.c - support for cursor shape updates.
*/
/*
* Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved.
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "rfb/rfb.h"
#include "rfb/rfbregion.h"
#include "private.h"
void rfbScaledScreenUpdate(rfbScreenInfoPtr screen, int x1, int y1, int x2, int y2);
/*
* Send cursor shape either in X-style format or in client pixel format.
*/
rfbBool
rfbSendCursorShape(rfbClientPtr cl)
{
rfbCursorPtr pCursor;
rfbFramebufferUpdateRectHeader rect;
rfbXCursorColors colors;
int saved_ublen;
int bitmapRowBytes, maskBytes, dataBytes;
int i, j;
uint8_t *bitmapData;
uint8_t bitmapByte;
/* TODO: scale the cursor data to the correct size */
pCursor = cl->screen->getCursorPtr(cl);
/*if(!pCursor) return TRUE;*/
if (cl->useRichCursorEncoding) {
if(pCursor && !pCursor->richSource)
rfbMakeRichCursorFromXCursor(cl->screen,pCursor);
rect.encoding = Swap32IfLE(rfbEncodingRichCursor);
} else {
if(pCursor && !pCursor->source)
rfbMakeXCursorFromRichCursor(cl->screen,pCursor);
rect.encoding = Swap32IfLE(rfbEncodingXCursor);
}
/* If there is no cursor, send update with empty cursor data. */
if ( pCursor && pCursor->width == 1 &&
pCursor->height == 1 &&
pCursor->mask[0] == 0 ) {
pCursor = NULL;
}
if (pCursor == NULL) {
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE ) {
if (!rfbSendUpdateBuf(cl))
return FALSE;
}
rect.r.x = rect.r.y = 0;
rect.r.w = rect.r.h = 0;
memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,
sz_rfbFramebufferUpdateRectHeader);
cl->ublen += sz_rfbFramebufferUpdateRectHeader;
if (!rfbSendUpdateBuf(cl))
return FALSE;
return TRUE;
}
/* Calculate data sizes. */
bitmapRowBytes = (pCursor->width + 7) / 8;
maskBytes = bitmapRowBytes * pCursor->height;
dataBytes = (cl->useRichCursorEncoding) ?
(pCursor->width * pCursor->height *
(cl->format.bitsPerPixel / 8)) : maskBytes;
/* Send buffer contents if needed. */
if ( cl->ublen + sz_rfbFramebufferUpdateRectHeader +
sz_rfbXCursorColors + maskBytes + dataBytes > UPDATE_BUF_SIZE ) {
if (!rfbSendUpdateBuf(cl))
return FALSE;
}
if ( cl->ublen + sz_rfbFramebufferUpdateRectHeader +
sz_rfbXCursorColors + maskBytes + dataBytes > UPDATE_BUF_SIZE ) {
return FALSE; /* FIXME. */
}
saved_ublen = cl->ublen;
/* Prepare rectangle header. */
rect.r.x = Swap16IfLE(pCursor->xhot);
rect.r.y = Swap16IfLE(pCursor->yhot);
rect.r.w = Swap16IfLE(pCursor->width);
rect.r.h = Swap16IfLE(pCursor->height);
memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,sz_rfbFramebufferUpdateRectHeader);
cl->ublen += sz_rfbFramebufferUpdateRectHeader;
/* Prepare actual cursor data (depends on encoding used). */
if (!cl->useRichCursorEncoding) {
/* XCursor encoding. */
colors.foreRed = (char)(pCursor->foreRed >> 8);
colors.foreGreen = (char)(pCursor->foreGreen >> 8);
colors.foreBlue = (char)(pCursor->foreBlue >> 8);
colors.backRed = (char)(pCursor->backRed >> 8);
colors.backGreen = (char)(pCursor->backGreen >> 8);
colors.backBlue = (char)(pCursor->backBlue >> 8);
memcpy(&cl->updateBuf[cl->ublen], (char *)&colors, sz_rfbXCursorColors);
cl->ublen += sz_rfbXCursorColors;
bitmapData = (uint8_t *)pCursor->source;
for (i = 0; i < pCursor->height; i++) {
for (j = 0; j < bitmapRowBytes; j++) {
bitmapByte = bitmapData[i * bitmapRowBytes + j];
cl->updateBuf[cl->ublen++] = (char)bitmapByte;
}
}
} else {
/* RichCursor encoding. */
int bpp1=cl->screen->serverFormat.bitsPerPixel/8,
bpp2=cl->format.bitsPerPixel/8;
(*cl->translateFn)(cl->translateLookupTable,
&(cl->screen->serverFormat),
&cl->format, (char*)pCursor->richSource,
&cl->updateBuf[cl->ublen],
pCursor->width*bpp1, pCursor->width, pCursor->height);
cl->ublen += pCursor->width*bpp2*pCursor->height;
}
/* Prepare transparency mask. */
bitmapData = (uint8_t *)pCursor->mask;
for (i = 0; i < pCursor->height; i++) {
for (j = 0; j < bitmapRowBytes; j++) {
bitmapByte = bitmapData[i * bitmapRowBytes + j];
cl->updateBuf[cl->ublen++] = (char)bitmapByte;
}
}
/* Send everything we have prepared in the cl->updateBuf[]. */
rfbStatRecordEncodingSent(cl, (cl->useRichCursorEncoding ? rfbEncodingRichCursor : rfbEncodingXCursor),
sz_rfbFramebufferUpdateRectHeader + (cl->ublen - saved_ublen), sz_rfbFramebufferUpdateRectHeader + (cl->ublen - saved_ublen));
if (!rfbSendUpdateBuf(cl))
return FALSE;
return TRUE;
}
/*
* Send cursor position (PointerPos pseudo-encoding).
*/
rfbBool
rfbSendCursorPos(rfbClientPtr cl)
{
rfbFramebufferUpdateRectHeader rect;
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) {
if (!rfbSendUpdateBuf(cl))
return FALSE;
}
rect.encoding = Swap32IfLE(rfbEncodingPointerPos);
rect.r.x = Swap16IfLE(cl->screen->cursorX);
rect.r.y = Swap16IfLE(cl->screen->cursorY);
rect.r.w = 0;
rect.r.h = 0;
memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,
sz_rfbFramebufferUpdateRectHeader);
cl->ublen += sz_rfbFramebufferUpdateRectHeader;
rfbStatRecordEncodingSent(cl, rfbEncodingPointerPos, sz_rfbFramebufferUpdateRectHeader, sz_rfbFramebufferUpdateRectHeader);
if (!rfbSendUpdateBuf(cl))
return FALSE;
return TRUE;
}
/* conversion routine for predefined cursors in LSB order */
unsigned char rfbReverseByte[0x100] = {
/* copied from Xvnc/lib/font/util/utilbitmap.c */
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
};
void rfbConvertLSBCursorBitmapOrMask(int width,int height,unsigned char* bitmap)
{
int i,t=(width+7)/8*height;
for(i=0;i<t;i++)
bitmap[i]=rfbReverseByte[(int)bitmap[i]];
}
/* Cursor creation. You "paint" a cursor and let these routines do the work */
rfbCursorPtr rfbMakeXCursor(int width,int height,char* cursorString,char* maskString)
{
int i,j,w=(width+7)/8;
rfbCursorPtr cursor = (rfbCursorPtr)calloc(1,sizeof(rfbCursor));
char* cp;
unsigned char bit;
cursor->cleanup=TRUE;
cursor->width=width;
cursor->height=height;
/*cursor->backRed=cursor->backGreen=cursor->backBlue=0xffff;*/
cursor->foreRed=cursor->foreGreen=cursor->foreBlue=0xffff;
cursor->source = (unsigned char*)calloc(w,height);
cursor->cleanupSource = TRUE;
for(j=0,cp=cursorString;j<height;j++)
for(i=0,bit=0x80;i<width;i++,bit=(bit&1)?0x80:bit>>1,cp++)
if(*cp!=' ') cursor->source[j*w+i/8]|=bit;
if(maskString) {
cursor->mask = (unsigned char*)calloc(w,height);
for(j=0,cp=maskString;j<height;j++)
for(i=0,bit=0x80;i<width;i++,bit=(bit&1)?0x80:bit>>1,cp++)
if(*cp!=' ') cursor->mask[j*w+i/8]|=bit;
} else
cursor->mask = (unsigned char*)rfbMakeMaskForXCursor(width,height,(char*)cursor->source);
cursor->cleanupMask = TRUE;
return(cursor);
}
char* rfbMakeMaskForXCursor(int width,int height,char* source)
{
int i,j,w=(width+7)/8;
char* mask=(char*)calloc(w,height);
unsigned char c;
for(j=0;j<height;j++)
for(i=w-1;i>=0;i--) {
c=source[j*w+i];
if(j>0) c|=source[(j-1)*w+i];
if(j<height-1) c|=source[(j+1)*w+i];
if(i>0 && (c&0x80))
mask[j*w+i-1]|=0x01;
if(i<w-1 && (c&0x01))
mask[j*w+i+1]|=0x80;
mask[j*w+i]|=(c<<1)|c|(c>>1);
}
return(mask);
}
/* this function dithers the alpha using Floyd-Steinberg */
char* rfbMakeMaskFromAlphaSource(int width,int height,unsigned char* alphaSource)
{
int* error=(int*)calloc(sizeof(int),width);
int i,j,currentError=0,maskStride=(width+7)/8;
unsigned char* result=(unsigned char*)calloc(maskStride,height);
for(j=0;j<height;j++)
for(i=0;i<width;i++) {
int right,middle,left;
currentError+=alphaSource[i+width*j]+error[i];
if(currentError<0x80) {
/* set to transparent */
/* alpha was treated as 0 */
} else {
/* set to solid */
result[i/8+j*maskStride]|=(0x100>>(i&7));
/* alpha was treated as 0xff */
currentError-=0xff;
}
/* propagate to next row */
right=currentError/16;
middle=currentError*5/16;
left=currentError*3/16;
currentError-=right+middle+left;
error[i]=right;
if(i>0) {
error[i-1]=middle;
if(i>1)
error[i-2]=left;
}
}
free(error);
return (char *) result;
}
void rfbFreeCursor(rfbCursorPtr cursor)
{
if(cursor) {
if(cursor->cleanupRichSource && cursor->richSource)
free(cursor->richSource);
if(cursor->cleanupRichSource && cursor->alphaSource)
free(cursor->alphaSource);
if(cursor->cleanupSource && cursor->source)
free(cursor->source);
if(cursor->cleanupMask && cursor->mask)
free(cursor->mask);
if(cursor->cleanup)
free(cursor);
else {
cursor->cleanup=cursor->cleanupSource=cursor->cleanupMask
=cursor->cleanupRichSource=FALSE;
cursor->source=cursor->mask=cursor->richSource=NULL;
cursor->alphaSource=NULL;
}
}
}
/* background and foregroud colour have to be set beforehand */
void rfbMakeXCursorFromRichCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor)
{
rfbPixelFormat* format=&rfbScreen->serverFormat;
int i,j,w=(cursor->width+7)/8,bpp=format->bitsPerPixel/8,
width=cursor->width*bpp;
uint32_t background;
char *back=(char*)&background;
unsigned char bit;
int interp = 0, db = 0;
if(cursor->source && cursor->cleanupSource)
free(cursor->source);
cursor->source=(unsigned char*)calloc(w,cursor->height);
cursor->cleanupSource=TRUE;
if(format->bigEndian) {
back+=4-bpp;
}
/* all zeros means we should interpolate to black+white ourselves */
if (!cursor->backRed && !cursor->backGreen && !cursor->backBlue &&
!cursor->foreRed && !cursor->foreGreen && !cursor->foreBlue) {
if (format->trueColour && (bpp == 1 || bpp == 2 || bpp == 4)) {
interp = 1;
cursor->foreRed = cursor->foreGreen = cursor->foreBlue = 0xffff;
}
}
background = ((format->redMax * cursor->backRed) / 0xffff) << format->redShift |
((format->greenMax * cursor->backGreen) / 0xffff) << format->greenShift |
((format->blueMax * cursor->backBlue) / 0xffff) << format->blueShift;
#define SETRGB(u) \
r = (255 * (((format->redMax << format->redShift) & (*u)) >> format->redShift)) / format->redMax; \
g = (255 * (((format->greenMax << format->greenShift) & (*u)) >> format->greenShift)) / format->greenMax; \
b = (255 * (((format->blueMax << format->blueShift) & (*u)) >> format->blueShift)) / format->blueMax;
if (db) fprintf(stderr, "interp: %d\n", interp);
for(j=0;j<cursor->height;j++) {
for(i=0,bit=0x80;i<cursor->width;i++,bit=(bit&1)?0x80:bit>>1) {
if (interp) {
int r = 0, g = 0, b = 0, grey;
unsigned char *p = cursor->richSource+j*width+i*bpp;
if (bpp == 1) {
unsigned char* uc = (unsigned char*) p;
SETRGB(uc);
} else if (bpp == 2) {
unsigned short* us = (unsigned short*) p;
SETRGB(us);
} else if (bpp == 4) {
unsigned int* ui = (unsigned int*) p;
SETRGB(ui);
}
grey = (r + g + b) / 3;
if (grey >= 128) {
cursor->source[j*w+i/8]|=bit;
if (db) fprintf(stderr, "1");
} else {
if (db) fprintf(stderr, "0");
}
} else if(memcmp(cursor->richSource+j*width+i*bpp, back, bpp)) {
cursor->source[j*w+i/8]|=bit;
}
}
if (db) fprintf(stderr, "\n");
}
}
void rfbMakeRichCursorFromXCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor)
{
rfbPixelFormat* format=&rfbScreen->serverFormat;
int i,j,w=(cursor->width+7)/8,bpp=format->bitsPerPixel/8;
uint32_t background,foreground;
char *back=(char*)&background,*fore=(char*)&foreground;
unsigned char *cp;
unsigned char bit;
if(cursor->richSource && cursor->cleanupRichSource)
free(cursor->richSource);
cp=cursor->richSource=(unsigned char*)calloc(cursor->width*bpp,cursor->height);
cursor->cleanupRichSource=TRUE;
if(format->bigEndian) {
back+=4-bpp;
fore+=4-bpp;
}
background=cursor->backRed<<format->redShift|
cursor->backGreen<<format->greenShift|cursor->backBlue<<format->blueShift;
foreground=cursor->foreRed<<format->redShift|
cursor->foreGreen<<format->greenShift|cursor->foreBlue<<format->blueShift;
for(j=0;j<cursor->height;j++)
for(i=0,bit=0x80;i<cursor->width;i++,bit=(bit&1)?0x80:bit>>1,cp+=bpp)
if(cursor->source[j*w+i/8]&bit) memcpy(cp,fore,bpp);
else memcpy(cp,back,bpp);
}
/* functions to draw/hide cursor directly in the frame buffer */
void rfbHideCursor(rfbClientPtr cl)
{
rfbScreenInfoPtr s=cl->screen;
rfbCursorPtr c=s->cursor;
int j,x1,x2,y1,y2,bpp=s->serverFormat.bitsPerPixel/8,
rowstride=s->paddedWidthInBytes;
LOCK(s->cursorMutex);
if(!c) {
UNLOCK(s->cursorMutex);
return;
}
/* restore what is under the cursor */
x1=cl->cursorX-c->xhot;
x2=x1+c->width;
if(x1<0) x1=0;
if(x2>=s->width) x2=s->width-1;
x2-=x1; if(x2<=0) {
UNLOCK(s->cursorMutex);
return;
}
y1=cl->cursorY-c->yhot;
y2=y1+c->height;
if(y1<0) y1=0;
if(y2>=s->height) y2=s->height-1;
y2-=y1; if(y2<=0) {
UNLOCK(s->cursorMutex);
return;
}
/* get saved data */
for(j=0;j<y2;j++)
memcpy(s->frameBuffer+(y1+j)*rowstride+x1*bpp,
s->underCursorBuffer+j*x2*bpp,
x2*bpp);
/* Copy to all scaled versions */
rfbScaledScreenUpdate(s, x1, y1, x1+x2, y1+y2);
UNLOCK(s->cursorMutex);
}
void rfbShowCursor(rfbClientPtr cl)
{
rfbScreenInfoPtr s=cl->screen;
rfbCursorPtr c=s->cursor;
int i,j,x1,x2,y1,y2,i1,j1,bpp=s->serverFormat.bitsPerPixel/8,
rowstride=s->paddedWidthInBytes,
bufSize,w;
rfbBool wasChanged=FALSE;
if(!c) return;
LOCK(s->cursorMutex);
bufSize=c->width*c->height*bpp;
w=(c->width+7)/8;
if(s->underCursorBufferLen<bufSize) {
if(s->underCursorBuffer!=NULL)
free(s->underCursorBuffer);
s->underCursorBuffer=malloc(bufSize);
s->underCursorBufferLen=bufSize;
}
/* save what is under the cursor */
i1=j1=0; /* offset in cursor */
x1=cl->cursorX-c->xhot;
x2=x1+c->width;
if(x1<0) { i1=-x1; x1=0; }
if(x2>=s->width) x2=s->width-1;
x2-=x1; if(x2<=0) {
UNLOCK(s->cursorMutex);
return; /* nothing to do */
}
y1=cl->cursorY-c->yhot;
y2=y1+c->height;
if(y1<0) { j1=-y1; y1=0; }
if(y2>=s->height) y2=s->height-1;
y2-=y1; if(y2<=0) {
UNLOCK(s->cursorMutex);
return; /* nothing to do */
}
/* save data */
for(j=0;j<y2;j++) {
char* dest=s->underCursorBuffer+j*x2*bpp;
const char* src=s->frameBuffer+(y1+j)*rowstride+x1*bpp;
unsigned int count=x2*bpp;
if(wasChanged || memcmp(dest,src,count)) {
wasChanged=TRUE;
memcpy(dest,src,count);
}
}
if(!c->richSource)
rfbMakeRichCursorFromXCursor(s,c);
if (c->alphaSource) {
int rmax, rshift;
int gmax, gshift;
int bmax, bshift;
int amax = 255; /* alphaSource is always 8bits of info per pixel */
unsigned int rmask, gmask, bmask;
rmax = s->serverFormat.redMax;
gmax = s->serverFormat.greenMax;
bmax = s->serverFormat.blueMax;
rshift = s->serverFormat.redShift;
gshift = s->serverFormat.greenShift;
bshift = s->serverFormat.blueShift;
rmask = (rmax << rshift);
gmask = (gmax << gshift);
bmask = (bmax << bshift);
for(j=0;j<y2;j++) {
for(i=0;i<x2;i++) {
/*
* we loop over the whole cursor ignoring c->mask[],
* using the extracted alpha value instead.
*/
char *dest;
unsigned char *src, *aptr;
unsigned int val, dval, sval;
int rdst, gdst, bdst; /* fb RGB */
int asrc, rsrc, gsrc, bsrc; /* rich source ARGB */
dest = s->frameBuffer + (j+y1)*rowstride + (i+x1)*bpp;
src = c->richSource + (j+j1)*c->width*bpp + (i+i1)*bpp;
aptr = c->alphaSource + (j+j1)*c->width + (i+i1);
asrc = *aptr;
if (!asrc) {
continue;
}
if (bpp == 1) {
dval = *((unsigned char*) dest);
sval = *((unsigned char*) src);
} else if (bpp == 2) {
dval = *((unsigned short*) dest);
sval = *((unsigned short*) src);
} else if (bpp == 3) {
unsigned char *dst = (unsigned char *) dest;
dval = 0;
dval |= ((*(dst+0)) << 0);
dval |= ((*(dst+1)) << 8);
dval |= ((*(dst+2)) << 16);
sval = 0;
sval |= ((*(src+0)) << 0);
sval |= ((*(src+1)) << 8);
sval |= ((*(src+2)) << 16);
} else if (bpp == 4) {
dval = *((unsigned int*) dest);
sval = *((unsigned int*) src);
} else {
continue;
}
/* extract dest and src RGB */
rdst = (dval & rmask) >> rshift; /* fb */
gdst = (dval & gmask) >> gshift;
bdst = (dval & bmask) >> bshift;
rsrc = (sval & rmask) >> rshift; /* richcursor */
gsrc = (sval & gmask) >> gshift;
bsrc = (sval & bmask) >> bshift;
/* blend in fb data. */
if (! c->alphaPreMultiplied) {
rsrc = (asrc * rsrc)/amax;
gsrc = (asrc * gsrc)/amax;
bsrc = (asrc * bsrc)/amax;
}
rdst = rsrc + ((amax - asrc) * rdst)/amax;
gdst = gsrc + ((amax - asrc) * gdst)/amax;
bdst = bsrc + ((amax - asrc) * bdst)/amax;
val = 0;
val |= (rdst << rshift);
val |= (gdst << gshift);
val |= (bdst << bshift);
/* insert the cooked pixel into the fb */
memcpy(dest, &val, bpp);
}
}
} else {
/* now the cursor has to be drawn */
for(j=0;j<y2;j++)
for(i=0;i<x2;i++)
if((c->mask[(j+j1)*w+(i+i1)/8]<<((i+i1)&7))&0x80)
memcpy(s->frameBuffer+(j+y1)*rowstride+(i+x1)*bpp,
c->richSource+(j+j1)*c->width*bpp+(i+i1)*bpp,bpp);
}
/* Copy to all scaled versions */
rfbScaledScreenUpdate(s, x1, y1, x1+x2, y1+y2);
UNLOCK(s->cursorMutex);
}
/*
* If enableCursorShapeUpdates is FALSE, and the cursor is hidden, make sure
* that if the frameBuffer was transmitted with a cursor drawn, then that
* region gets redrawn.
*/
void rfbRedrawAfterHideCursor(rfbClientPtr cl,sraRegionPtr updateRegion)
{
rfbScreenInfoPtr s = cl->screen;
rfbCursorPtr c = s->cursor;
if(c) {
int x,y,x2,y2;
x = cl->cursorX-c->xhot;
y = cl->cursorY-c->yhot;
x2 = x+c->width;
y2 = y+c->height;
if(sraClipRect2(&x,&y,&x2,&y2,0,0,s->width,s->height)) {
sraRegionPtr rect;
rect = sraRgnCreateRect(x,y,x2,y2);
if(updateRegion) {
sraRgnOr(updateRegion,rect);
} else {
LOCK(cl->updateMutex);
sraRgnOr(cl->modifiedRegion,rect);
UNLOCK(cl->updateMutex);
}
sraRgnDestroy(rect);
}
}
}
#ifdef DEBUG
static void rfbPrintXCursor(rfbCursorPtr cursor)
{
int i,i1,j,w=(cursor->width+7)/8;
unsigned char bit;
for(j=0;j<cursor->height;j++) {
for(i=0,i1=0,bit=0x80;i1<cursor->width;i1++,i+=(bit&1)?1:0,bit=(bit&1)?0x80:bit>>1)
if(cursor->source[j*w+i]&bit) putchar('#'); else putchar(' ');
putchar(':');
for(i=0,i1=0,bit=0x80;i1<cursor->width;i1++,i+=(bit&1)?1:0,bit=(bit&1)?0x80:bit>>1)
if(cursor->mask[j*w+i]&bit) putchar('#'); else putchar(' ');
putchar('\n');
}
}
#endif
void rfbSetCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr c)
{
rfbClientIteratorPtr iterator;
rfbClientPtr cl;
LOCK(rfbScreen->cursorMutex);
if(rfbScreen->cursor) {
iterator=rfbGetClientIterator(rfbScreen);
while((cl=rfbClientIteratorNext(iterator)))
if(!cl->enableCursorShapeUpdates)
rfbRedrawAfterHideCursor(cl,NULL);
rfbReleaseClientIterator(iterator);
if(rfbScreen->cursor->cleanup)
rfbFreeCursor(rfbScreen->cursor);
}
rfbScreen->cursor = c;
iterator=rfbGetClientIterator(rfbScreen);
while((cl=rfbClientIteratorNext(iterator))) {
cl->cursorWasChanged = TRUE;
if(!cl->enableCursorShapeUpdates)
rfbRedrawAfterHideCursor(cl,NULL);
}
rfbReleaseClientIterator(iterator);
UNLOCK(rfbScreen->cursorMutex);
}

View File

@@ -1,38 +0,0 @@
/*
* cutpaste.c - routines to deal with cut & paste buffers / selection.
*/
/*
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* All Rights Reserved.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "rfb/rfb.h"
/*
* rfbSetXCutText sets the cut buffer to be the given string. We also clear
* the primary selection. Ideally we'd like to set it to the same thing, but I
* can't work out how to do that without some kind of helper X client.
*/
void rfbGotXCutText(rfbScreenInfoPtr rfbScreen, char *str, int len)
{
rfbSendServerCutText(rfbScreen, str, len);
}

View File

@@ -1,436 +0,0 @@
/*
* This is D3DES (V5.09) by Richard Outerbridge with the double and
* triple-length support removed for use in VNC. Also the bytebit[] array
* has been reversed so that the most significant bit in each byte of the
* key is ignored, not the least significant.
*
* These changes are:
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/* D3DES (V5.09) -
*
* A portable, public domain, version of the Data Encryption Standard.
*
* Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
* Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
* code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
* Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
* for humouring me on.
*
* Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
* (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
*/
#include "d3des.h"
static void scrunch(unsigned char *, unsigned long *);
static void unscrun(unsigned long *, unsigned char *);
static void desfunc(unsigned long *, unsigned long *);
static void cookey(unsigned long *);
static unsigned long KnL[32] = { 0L };
/*
static unsigned long KnR[32] = { 0L };
static unsigned long Kn3[32] = { 0L };
static unsigned char Df_Key[24] = {
0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 };
*/
static unsigned short bytebit[8] = {
01, 02, 04, 010, 020, 040, 0100, 0200 };
static unsigned long bigbyte[24] = {
0x800000L, 0x400000L, 0x200000L, 0x100000L,
0x80000L, 0x40000L, 0x20000L, 0x10000L,
0x8000L, 0x4000L, 0x2000L, 0x1000L,
0x800L, 0x400L, 0x200L, 0x100L,
0x80L, 0x40L, 0x20L, 0x10L,
0x8L, 0x4L, 0x2L, 0x1L };
/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
static unsigned char pc1[56] = {
56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 };
static unsigned char totrot[16] = {
1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };
static unsigned char pc2[48] = {
13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
void rfbDesKey(unsigned char *key,
int edf)
{
register int i, j, l, m, n;
unsigned char pc1m[56], pcr[56];
unsigned long kn[32];
for ( j = 0; j < 56; j++ ) {
l = pc1[j];
m = l & 07;
pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
}
for( i = 0; i < 16; i++ ) {
if( edf == DE1 ) m = (15 - i) << 1;
else m = i << 1;
n = m + 1;
kn[m] = kn[n] = 0L;
for( j = 0; j < 28; j++ ) {
l = j + totrot[i];
if( l < 28 ) pcr[j] = pc1m[l];
else pcr[j] = pc1m[l - 28];
}
for( j = 28; j < 56; j++ ) {
l = j + totrot[i];
if( l < 56 ) pcr[j] = pc1m[l];
else pcr[j] = pc1m[l - 28];
}
for( j = 0; j < 24; j++ ) {
if( pcr[pc2[j]] ) kn[m] |= bigbyte[j];
if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j];
}
}
cookey(kn);
return;
}
static void cookey(register unsigned long *raw1)
{
register unsigned long *cook, *raw0;
unsigned long dough[32];
register int i;
cook = dough;
for( i = 0; i < 16; i++, raw1++ ) {
raw0 = raw1++;
*cook = (*raw0 & 0x00fc0000L) << 6;
*cook |= (*raw0 & 0x00000fc0L) << 10;
*cook |= (*raw1 & 0x00fc0000L) >> 10;
*cook++ |= (*raw1 & 0x00000fc0L) >> 6;
*cook = (*raw0 & 0x0003f000L) << 12;
*cook |= (*raw0 & 0x0000003fL) << 16;
*cook |= (*raw1 & 0x0003f000L) >> 4;
*cook++ |= (*raw1 & 0x0000003fL);
}
rfbUseKey(dough);
return;
}
void rfbCPKey(register unsigned long *into)
{
register unsigned long *from, *endp;
from = KnL, endp = &KnL[32];
while( from < endp ) *into++ = *from++;
return;
}
void rfbUseKey(register unsigned long *from)
{
register unsigned long *to, *endp;
to = KnL, endp = &KnL[32];
while( to < endp ) *to++ = *from++;
return;
}
void rfbDes(unsigned char *inblock,
unsigned char *outblock)
{
unsigned long work[2];
scrunch(inblock, work);
desfunc(work, KnL);
unscrun(work, outblock);
return;
}
static void scrunch(register unsigned char *outof,
register unsigned long *into)
{
*into = (*outof++ & 0xffL) << 24;
*into |= (*outof++ & 0xffL) << 16;
*into |= (*outof++ & 0xffL) << 8;
*into++ |= (*outof++ & 0xffL);
*into = (*outof++ & 0xffL) << 24;
*into |= (*outof++ & 0xffL) << 16;
*into |= (*outof++ & 0xffL) << 8;
*into |= (*outof & 0xffL);
return;
}
static void unscrun(register unsigned long *outof,
register unsigned char *into)
{
*into++ = (unsigned char)((*outof >> 24) & 0xffL);
*into++ = (unsigned char)((*outof >> 16) & 0xffL);
*into++ = (unsigned char)((*outof >> 8) & 0xffL);
*into++ = (unsigned char)( *outof++ & 0xffL);
*into++ = (unsigned char)((*outof >> 24) & 0xffL);
*into++ = (unsigned char)((*outof >> 16) & 0xffL);
*into++ = (unsigned char)((*outof >> 8) & 0xffL);
*into = (unsigned char)( *outof & 0xffL);
return;
}
static unsigned long SP1[64] = {
0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
static unsigned long SP2[64] = {
0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
static unsigned long SP3[64] = {
0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
static unsigned long SP4[64] = {
0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
static unsigned long SP5[64] = {
0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
static unsigned long SP6[64] = {
0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
static unsigned long SP7[64] = {
0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
static unsigned long SP8[64] = {
0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
static void desfunc(register unsigned long *block,
register unsigned long *keys)
{
register unsigned long fval, work, right, leftt;
register int round;
leftt = block[0];
right = block[1];
work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
right ^= work;
leftt ^= (work << 4);
work = ((leftt >> 16) ^ right) & 0x0000ffffL;
right ^= work;
leftt ^= (work << 16);
work = ((right >> 2) ^ leftt) & 0x33333333L;
leftt ^= work;
right ^= (work << 2);
work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
leftt ^= work;
right ^= (work << 8);
right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
work = (leftt ^ right) & 0xaaaaaaaaL;
leftt ^= work;
right ^= work;
leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;
for( round = 0; round < 8; round++ ) {
work = (right << 28) | (right >> 4);
work ^= *keys++;
fval = SP7[ work & 0x3fL];
fval |= SP5[(work >> 8) & 0x3fL];
fval |= SP3[(work >> 16) & 0x3fL];
fval |= SP1[(work >> 24) & 0x3fL];
work = right ^ *keys++;
fval |= SP8[ work & 0x3fL];
fval |= SP6[(work >> 8) & 0x3fL];
fval |= SP4[(work >> 16) & 0x3fL];
fval |= SP2[(work >> 24) & 0x3fL];
leftt ^= fval;
work = (leftt << 28) | (leftt >> 4);
work ^= *keys++;
fval = SP7[ work & 0x3fL];
fval |= SP5[(work >> 8) & 0x3fL];
fval |= SP3[(work >> 16) & 0x3fL];
fval |= SP1[(work >> 24) & 0x3fL];
work = leftt ^ *keys++;
fval |= SP8[ work & 0x3fL];
fval |= SP6[(work >> 8) & 0x3fL];
fval |= SP4[(work >> 16) & 0x3fL];
fval |= SP2[(work >> 24) & 0x3fL];
right ^= fval;
}
right = (right << 31) | (right >> 1);
work = (leftt ^ right) & 0xaaaaaaaaL;
leftt ^= work;
right ^= work;
leftt = (leftt << 31) | (leftt >> 1);
work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
right ^= work;
leftt ^= (work << 8);
work = ((leftt >> 2) ^ right) & 0x33333333L;
right ^= work;
leftt ^= (work << 2);
work = ((right >> 16) ^ leftt) & 0x0000ffffL;
leftt ^= work;
right ^= (work << 16);
work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
leftt ^= work;
right ^= (work << 4);
*block++ = right;
*block = leftt;
return;
}
/* Validation sets:
*
* Single-length key, single-length plaintext -
* Key : 0123 4567 89ab cdef
* Plain : 0123 4567 89ab cde7
* Cipher : c957 4425 6a5e d31d
*
* Double-length key, single-length plaintext -
* Key : 0123 4567 89ab cdef fedc ba98 7654 3210
* Plain : 0123 4567 89ab cde7
* Cipher : 7f1d 0a77 826b 8aff
*
* Double-length key, double-length plaintext -
* Key : 0123 4567 89ab cdef fedc ba98 7654 3210
* Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
* Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7
*
* Triple-length key, single-length plaintext -
* Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
* Plain : 0123 4567 89ab cde7
* Cipher : de0b 7c06 ae5e 0ed5
*
* Triple-length key, double-length plaintext -
* Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
* Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
* Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5
*
* d3des V5.0a rwo 9208.07 18:44 Graven Imagery
**********************************************************************/

View File

@@ -1,56 +0,0 @@
#ifndef D3DES_H
#define D3DES_H
/*
* This is D3DES (V5.09) by Richard Outerbridge with the double and
* triple-length support removed for use in VNC.
*
* These changes are:
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/* d3des.h -
*
* Headers and defines for d3des.c
* Graven Imagery, 1992.
*
* Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge
* (GEnie : OUTER; CIS : [71755,204])
*/
#define EN0 0 /* MODE == encrypt */
#define DE1 1 /* MODE == decrypt */
extern void rfbDesKey(unsigned char *, int);
/* hexkey[8] MODE
* Sets the internal key register according to the hexadecimal
* key contained in the 8 bytes of hexkey, according to the DES,
* for encryption or decryption according to MODE.
*/
extern void rfbUseKey(unsigned long *);
/* cookedkey[32]
* Loads the internal key register with the data in cookedkey.
*/
extern void rfbCPKey(unsigned long *);
/* cookedkey[32]
* Copies the contents of the internal key register into the storage
* located at &cookedkey[0].
*/
extern void rfbDes(unsigned char *, unsigned char *);
/* from[8] to[8]
* Encrypts/Decrypts (according to the key currently loaded in the
* internal key register) one block of eight bytes at address 'from'
* into the block at address 'to'. They can be the same.
*/
/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery
********************************************************************/
#endif

View File

@@ -1,61 +0,0 @@
#include "rfb/rfb.h"
void rfbFillRect(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,rfbPixel col)
{
int rowstride = s->paddedWidthInBytes, bpp = s->bitsPerPixel>>3;
int i,j;
char* colour=(char*)&col;
if(!rfbEndianTest)
colour += 4-bpp;
for(j=y1;j<y2;j++)
for(i=x1;i<x2;i++)
memcpy(s->frameBuffer+j*rowstride+i*bpp,colour,bpp);
rfbMarkRectAsModified(s,x1,y1,x2,y2);
}
#define SETPIXEL(x,y) \
memcpy(s->frameBuffer+(y)*rowstride+(x)*bpp,colour,bpp)
void rfbDrawPixel(rfbScreenInfoPtr s,int x,int y,rfbPixel col)
{
int rowstride = s->paddedWidthInBytes, bpp = s->bitsPerPixel>>3;
char* colour=(char*)&col;
if(!rfbEndianTest)
colour += 4-bpp;
SETPIXEL(x,y);
rfbMarkRectAsModified(s,x,y,x+1,y+1);
}
void rfbDrawLine(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,rfbPixel col)
{
int rowstride = s->paddedWidthInBytes, bpp = s->bitsPerPixel>>3;
int i;
char* colour=(char*)&col;
if(!rfbEndianTest)
colour += 4-bpp;
#define SWAPPOINTS { i=x1; x1=x2; x2=i; i=y1; y1=y2; y2=i; }
if(abs(x1-x2)<abs(y1-y2)) {
if(y1>y2)
SWAPPOINTS
for(i=y1;i<=y2;i++)
SETPIXEL(x1+(i-y1)*(x2-x1)/(y2-y1),i);
/* TODO: Maybe make this more intelligently? */
if(x2<x1) { i=x1; x1=x2; x2=i; }
rfbMarkRectAsModified(s,x1,y1,x2+1,y2+1);
} else {
if(x1>x2)
SWAPPOINTS
else if(x1==x2) {
rfbDrawPixel(s,x1,y1,col);
return;
}
for(i=x1;i<=x2;i++)
SETPIXEL(i,y1+(i-x1)*(y2-y1)/(x2-x1));
if(y2<y1) { i=y1; y1=y2; y2=i; }
rfbMarkRectAsModified(s,x1,y1,x2+1,y2+1);
}
}

View File

@@ -1,196 +0,0 @@
#include "rfb/rfb.h"
int rfbDrawChar(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,
int x,int y,unsigned char c,rfbPixel col)
{
int i,j,width,height;
unsigned char* data=font->data+font->metaData[c*5];
unsigned char d=*data;
int rowstride=rfbScreen->paddedWidthInBytes;
int bpp=rfbScreen->serverFormat.bitsPerPixel/8;
char *colour=(char*)&col;
if(!rfbEndianTest)
colour += 4-bpp;
width=font->metaData[c*5+1];
height=font->metaData[c*5+2];
x+=font->metaData[c*5+3];
y+=-font->metaData[c*5+4]-height+1;
for(j=0;j<height;j++) {
for(i=0;i<width;i++) {
if((i&7)==0) {
d=*data;
data++;
}
if(d&0x80 && y+j >= 0 && y+j < rfbScreen->height &&
x+i >= 0 && x+i < rfbScreen->width)
memcpy(rfbScreen->frameBuffer+(y+j)*rowstride+(x+i)*bpp,colour,bpp);
d<<=1;
}
/* if((i&7)!=0) data++; */
}
return(width);
}
void rfbDrawString(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,
int x,int y,const char* string,rfbPixel colour)
{
while(*string) {
x+=rfbDrawChar(rfbScreen,font,x,y,*string,colour);
string++;
}
}
/* TODO: these two functions need to be more efficient */
/* if col==bcol, assume transparent background */
int rfbDrawCharWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,
int x,int y,unsigned char c,
int x1,int y1,int x2,int y2,
rfbPixel col,rfbPixel bcol)
{
int i,j,width,height;
unsigned char* data=font->data+font->metaData[c*5];
unsigned char d;
int rowstride=rfbScreen->paddedWidthInBytes;
int bpp=rfbScreen->serverFormat.bitsPerPixel/8,extra_bytes=0;
char* colour=(char*)&col;
char* bcolour=(char*)&bcol;
if(!rfbEndianTest) {
colour+=4-bpp;
bcolour+=4-bpp;
}
width=font->metaData[c*5+1];
height=font->metaData[c*5+2];
x+=font->metaData[c*5+3];
y+=-font->metaData[c*5+4]-height+1;
/* after clipping, x2 will be count of bytes between rows,
* x1 start of i, y1 start of j, width and height will be adjusted. */
if(y1>y) { y1-=y; data+=(width+7)/8; height-=y1; y+=y1; } else y1=0;
if(x1>x) { x1-=x; data+=x1; width-=x1; x+=x1; extra_bytes+=x1/8; } else x1=0;
if(y2<y+height) height-=y+height-y2;
if(x2<x+width) { extra_bytes+=(x1+width)/8-(x+width-x2+7)/8; width-=x+width-x2; }
d=*data;
for(j=y1;j<height;j++) {
if((x1&7)!=0)
d=data[-1]; /* TODO: check if in this case extra_bytes is correct! */
for(i=x1;i<width;i++) {
if((i&7)==0) {
d=*data;
data++;
}
/* if(x+i>=x1 && x+i<x2 && y+j>=y1 && y+j<y2) */ {
if(d&0x80) {
memcpy(rfbScreen->frameBuffer+(y+j)*rowstride+(x+i)*bpp,
colour,bpp);
} else if(bcol!=col) {
memcpy(rfbScreen->frameBuffer+(y+j)*rowstride+(x+i)*bpp,
bcolour,bpp);
}
}
d<<=1;
}
/* if((i&7)==0) data++; */
data += extra_bytes;
}
return(width);
}
void rfbDrawStringWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,
int x,int y,const char* string,
int x1,int y1,int x2,int y2,
rfbPixel colour,rfbPixel backColour)
{
while(*string) {
x+=rfbDrawCharWithClip(rfbScreen,font,x,y,*string,x1,y1,x2,y2,
colour,backColour);
string++;
}
}
int rfbWidthOfString(rfbFontDataPtr font,const char* string)
{
int i=0;
while(*string) {
i+=font->metaData[*string*5+1];
string++;
}
return(i);
}
int rfbWidthOfChar(rfbFontDataPtr font,unsigned char c)
{
return(font->metaData[c*5+1]+font->metaData[c*5+3]);
}
void rfbFontBBox(rfbFontDataPtr font,unsigned char c,int* x1,int* y1,int* x2,int* y2)
{
*x1+=font->metaData[c*5+3];
*y1+=-font->metaData[c*5+4]-font->metaData[c*5+2]+1;
*x2=*x1+font->metaData[c*5+1]+1;
*y2=*y1+font->metaData[c*5+2]+1;
}
#ifndef INT_MAX
#define INT_MAX 0x7fffffff
#endif
void rfbWholeFontBBox(rfbFontDataPtr font,
int *x1, int *y1, int *x2, int *y2)
{
int i;
int* m=font->metaData;
(*x1)=(*y1)=INT_MAX; (*x2)=(*y2)=1-(INT_MAX);
for(i=0;i<256;i++) {
if(m[i*5+1]-m[i*5+3]>(*x2))
(*x2)=m[i*5+1]-m[i*5+3];
if(-m[i*5+2]+m[i*5+4]<(*y1))
(*y1)=-m[i*5+2]+m[i*5+4];
if(m[i*5+3]<(*x1))
(*x1)=m[i*5+3];
if(-m[i*5+4]>(*y2))
(*y2)=-m[i*5+4];
}
(*x2)++;
(*y2)++;
}
rfbFontDataPtr rfbLoadConsoleFont(char *filename)
{
FILE *f=fopen(filename,"rb");
rfbFontDataPtr p;
int i;
if(!f) return NULL;
p=(rfbFontDataPtr)malloc(sizeof(rfbFontData));
p->data=(unsigned char*)malloc(4096);
if(1!=fread(p->data,4096,1,f)) {
free(p->data);
free(p);
return NULL;
}
fclose(f);
p->metaData=(int*)malloc(256*5*sizeof(int));
for(i=0;i<256;i++) {
p->metaData[i*5+0]=i*16; /* offset */
p->metaData[i*5+1]=8; /* width */
p->metaData[i*5+2]=16; /* height */
p->metaData[i*5+3]=0; /* xhot */
p->metaData[i*5+4]=0; /* yhot */
}
return(p);
}
void rfbFreeFont(rfbFontDataPtr f)
{
free(f->data);
free(f->metaData);
free(f);
}

View File

@@ -1,342 +0,0 @@
/*
* hextile.c
*
* Routines to implement Hextile Encoding
*/
/*
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
* All Rights Reserved.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "rfb/rfb.h"
static rfbBool sendHextiles8(rfbClientPtr cl, int x, int y, int w, int h);
static rfbBool sendHextiles16(rfbClientPtr cl, int x, int y, int w, int h);
static rfbBool sendHextiles32(rfbClientPtr cl, int x, int y, int w, int h);
/*
* rfbSendRectEncodingHextile - send a rectangle using hextile encoding.
*/
rfbBool
rfbSendRectEncodingHextile(rfbClientPtr cl,
int x,
int y,
int w,
int h)
{
rfbFramebufferUpdateRectHeader rect;
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) {
if (!rfbSendUpdateBuf(cl))
return FALSE;
}
rect.r.x = Swap16IfLE(x);
rect.r.y = Swap16IfLE(y);
rect.r.w = Swap16IfLE(w);
rect.r.h = Swap16IfLE(h);
rect.encoding = Swap32IfLE(rfbEncodingHextile);
memcpy(&cl->updateBuf[cl->ublen], (char *)&rect,
sz_rfbFramebufferUpdateRectHeader);
cl->ublen += sz_rfbFramebufferUpdateRectHeader;
rfbStatRecordEncodingSent(cl, rfbEncodingHextile,
sz_rfbFramebufferUpdateRectHeader,
sz_rfbFramebufferUpdateRectHeader + w * (cl->format.bitsPerPixel / 8) * h);
switch (cl->format.bitsPerPixel) {
case 8:
return sendHextiles8(cl, x, y, w, h);
case 16:
return sendHextiles16(cl, x, y, w, h);
case 32:
return sendHextiles32(cl, x, y, w, h);
}
rfbLog("rfbSendRectEncodingHextile: bpp %d?\n", cl->format.bitsPerPixel);
return FALSE;
}
#define PUT_PIXEL8(pix) (cl->updateBuf[cl->ublen++] = (pix))
#define PUT_PIXEL16(pix) (cl->updateBuf[cl->ublen++] = ((char*)&(pix))[0], \
cl->updateBuf[cl->ublen++] = ((char*)&(pix))[1])
#define PUT_PIXEL32(pix) (cl->updateBuf[cl->ublen++] = ((char*)&(pix))[0], \
cl->updateBuf[cl->ublen++] = ((char*)&(pix))[1], \
cl->updateBuf[cl->ublen++] = ((char*)&(pix))[2], \
cl->updateBuf[cl->ublen++] = ((char*)&(pix))[3])
#define DEFINE_SEND_HEXTILES(bpp) \
\
\
static rfbBool subrectEncode##bpp(rfbClientPtr cli, uint##bpp##_t *data, \
int w, int h, uint##bpp##_t bg, uint##bpp##_t fg, rfbBool mono);\
static void testColours##bpp(uint##bpp##_t *data, int size, rfbBool *mono, \
rfbBool *solid, uint##bpp##_t *bg, uint##bpp##_t *fg); \
\
\
/* \
* rfbSendHextiles \
*/ \
\
static rfbBool \
sendHextiles##bpp(rfbClientPtr cl, int rx, int ry, int rw, int rh) { \
int x, y, w, h; \
int startUblen; \
char *fbptr; \
uint##bpp##_t bg = 0, fg = 0, newBg, newFg; \
rfbBool mono, solid; \
rfbBool validBg = FALSE; \
rfbBool validFg = FALSE; \
uint##bpp##_t clientPixelData[16*16*(bpp/8)]; \
\
for (y = ry; y < ry+rh; y += 16) { \
for (x = rx; x < rx+rw; x += 16) { \
w = h = 16; \
if (rx+rw - x < 16) \
w = rx+rw - x; \
if (ry+rh - y < 16) \
h = ry+rh - y; \
\
if ((cl->ublen + 1 + (2 + 16 * 16) * (bpp/8)) > \
UPDATE_BUF_SIZE) { \
if (!rfbSendUpdateBuf(cl)) \
return FALSE; \
} \
\
fbptr = (cl->scaledScreen->frameBuffer + (cl->scaledScreen->paddedWidthInBytes * y) \
+ (x * (cl->scaledScreen->bitsPerPixel / 8))); \
\
(*cl->translateFn)(cl->translateLookupTable, &(cl->screen->serverFormat), \
&cl->format, fbptr, (char *)clientPixelData, \
cl->scaledScreen->paddedWidthInBytes, w, h); \
\
startUblen = cl->ublen; \
cl->updateBuf[startUblen] = 0; \
cl->ublen++; \
rfbStatRecordEncodingSentAdd(cl, rfbEncodingHextile, 1); \
\
testColours##bpp(clientPixelData, w * h, \
&mono, &solid, &newBg, &newFg); \
\
if (!validBg || (newBg != bg)) { \
validBg = TRUE; \
bg = newBg; \
cl->updateBuf[startUblen] |= rfbHextileBackgroundSpecified; \
PUT_PIXEL##bpp(bg); \
} \
\
if (solid) { \
continue; \
} \
\
cl->updateBuf[startUblen] |= rfbHextileAnySubrects; \
\
if (mono) { \
if (!validFg || (newFg != fg)) { \
validFg = TRUE; \
fg = newFg; \
cl->updateBuf[startUblen] |= rfbHextileForegroundSpecified; \
PUT_PIXEL##bpp(fg); \
} \
} else { \
validFg = FALSE; \
cl->updateBuf[startUblen] |= rfbHextileSubrectsColoured; \
} \
\
if (!subrectEncode##bpp(cl, clientPixelData, w, h, bg, fg, mono)) { \
/* encoding was too large, use raw */ \
validBg = FALSE; \
validFg = FALSE; \
cl->ublen = startUblen; \
cl->updateBuf[cl->ublen++] = rfbHextileRaw; \
(*cl->translateFn)(cl->translateLookupTable, \
&(cl->screen->serverFormat), &cl->format, fbptr, \
(char *)clientPixelData, \
cl->scaledScreen->paddedWidthInBytes, w, h); \
\
memcpy(&cl->updateBuf[cl->ublen], (char *)clientPixelData, \
w * h * (bpp/8)); \
\
cl->ublen += w * h * (bpp/8); \
rfbStatRecordEncodingSentAdd(cl, rfbEncodingHextile, \
w * h * (bpp/8)); \
} \
} \
} \
\
return TRUE; \
} \
\
\
static rfbBool \
subrectEncode##bpp(rfbClientPtr cl, uint##bpp##_t *data, int w, int h, \
uint##bpp##_t bg, uint##bpp##_t fg, rfbBool mono) \
{ \
uint##bpp##_t cl2; \
int x,y; \
int i,j; \
int hx=0,hy,vx=0,vy; \
int hyflag; \
uint##bpp##_t *seg; \
uint##bpp##_t *line; \
int hw,hh,vw,vh; \
int thex,they,thew,theh; \
int numsubs = 0; \
int newLen; \
int nSubrectsUblen; \
\
nSubrectsUblen = cl->ublen; \
cl->ublen++; \
rfbStatRecordEncodingSentAdd(cl, rfbEncodingHextile, 1); \
\
for (y=0; y<h; y++) { \
line = data+(y*w); \
for (x=0; x<w; x++) { \
if (line[x] != bg) { \
cl2 = line[x]; \
hy = y-1; \
hyflag = 1; \
for (j=y; j<h; j++) { \
seg = data+(j*w); \
if (seg[x] != cl2) {break;} \
i = x; \
while ((seg[i] == cl2) && (i < w)) i += 1; \
i -= 1; \
if (j == y) vx = hx = i; \
if (i < vx) vx = i; \
if ((hyflag > 0) && (i >= hx)) { \
hy += 1; \
} else { \
hyflag = 0; \
} \
} \
vy = j-1; \
\
/* We now have two possible subrects: (x,y,hx,hy) and \
* (x,y,vx,vy). We'll choose the bigger of the two. \
*/ \
hw = hx-x+1; \
hh = hy-y+1; \
vw = vx-x+1; \
vh = vy-y+1; \
\
thex = x; \
they = y; \
\
if ((hw*hh) > (vw*vh)) { \
thew = hw; \
theh = hh; \
} else { \
thew = vw; \
theh = vh; \
} \
\
if (mono) { \
newLen = cl->ublen - nSubrectsUblen + 2; \
} else { \
newLen = cl->ublen - nSubrectsUblen + bpp/8 + 2; \
} \
\
if (newLen > (w * h * (bpp/8))) \
return FALSE; \
\
numsubs += 1; \
\
if (!mono) PUT_PIXEL##bpp(cl2); \
\
cl->updateBuf[cl->ublen++] = rfbHextilePackXY(thex,they); \
cl->updateBuf[cl->ublen++] = rfbHextilePackWH(thew,theh); \
rfbStatRecordEncodingSentAdd(cl, rfbEncodingHextile, 1); \
\
/* \
* Now mark the subrect as done. \
*/ \
for (j=they; j < (they+theh); j++) { \
for (i=thex; i < (thex+thew); i++) { \
data[j*w+i] = bg; \
} \
} \
} \
} \
} \
\
cl->updateBuf[nSubrectsUblen] = numsubs; \
\
return TRUE; \
} \
\
\
/* \
* testColours() tests if there are one (solid), two (mono) or more \
* colours in a tile and gets a reasonable guess at the best background \
* pixel, and the foreground pixel for mono. \
*/ \
\
static void \
testColours##bpp(uint##bpp##_t *data, int size, rfbBool *mono, rfbBool *solid, \
uint##bpp##_t *bg, uint##bpp##_t *fg) { \
uint##bpp##_t colour1 = 0, colour2 = 0; \
int n1 = 0, n2 = 0; \
*mono = TRUE; \
*solid = TRUE; \
\
for (; size > 0; size--, data++) { \
\
if (n1 == 0) \
colour1 = *data; \
\
if (*data == colour1) { \
n1++; \
continue; \
} \
\
if (n2 == 0) { \
*solid = FALSE; \
colour2 = *data; \
} \
\
if (*data == colour2) { \
n2++; \
continue; \
} \
\
*mono = FALSE; \
break; \
} \
\
if (n1 > n2) { \
*bg = colour1; \
*fg = colour2; \
} else { \
*bg = colour2; \
*fg = colour1; \
} \
}
DEFINE_SEND_HEXTILES(8)
DEFINE_SEND_HEXTILES(16)
DEFINE_SEND_HEXTILES(32)

View File

@@ -1,600 +0,0 @@
/*
* httpd.c - a simple HTTP server
*/
/*
* Copyright (C) 2002 RealVNC Ltd.
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include "rfb/rfb.h"
#include <ctype.h>
#ifdef LIBVNCSERVER_HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef LIBVNCSERVER_HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <errno.h>
#ifdef WIN32
#include <winsock.h>
#define close closesocket
#else
#ifdef LIBVNCSERVER_HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef LIBVNCSERVER_HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef LIBVNCSERVER_HAVE_NETINET_IN_H
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <arpa/inet.h>
#endif
#include <pwd.h>
#endif
#ifdef USE_LIBWRAP
#include <tcpd.h>
#endif
#define connection_close
#ifndef connection_close
#define NOT_FOUND_STR "HTTP/1.0 404 Not found\r\n\r\n" \
"<HEAD><TITLE>File Not Found</TITLE></HEAD>\n" \
"<BODY><H1>File Not Found</H1></BODY>\n"
#define INVALID_REQUEST_STR "HTTP/1.0 400 Invalid Request\r\n\r\n" \
"<HEAD><TITLE>Invalid Request</TITLE></HEAD>\n" \
"<BODY><H1>Invalid request</H1></BODY>\n"
#define OK_STR "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"
#else
#define NOT_FOUND_STR "HTTP/1.0 404 Not found\r\nConnection: close\r\n\r\n" \
"<HEAD><TITLE>File Not Found</TITLE></HEAD>\n" \
"<BODY><H1>File Not Found</H1></BODY>\n"
#define INVALID_REQUEST_STR "HTTP/1.0 400 Invalid Request\r\nConnection: close\r\n\r\n" \
"<HEAD><TITLE>Invalid Request</TITLE></HEAD>\n" \
"<BODY><H1>Invalid request</H1></BODY>\n"
#define OK_STR "HTTP/1.0 200 OK\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n"
#endif
static void httpProcessInput(rfbScreenInfoPtr screen);
static rfbBool compareAndSkip(char **ptr, const char *str);
static rfbBool parseParams(const char *request, char *result, int max_bytes);
static rfbBool validateString(char *str);
#define BUF_SIZE 32768
static char buf[BUF_SIZE];
static size_t buf_filled=0;
/*
* httpInitSockets sets up the TCP socket to listen for HTTP connections.
*/
void
rfbHttpInitSockets(rfbScreenInfoPtr rfbScreen)
{
if (rfbScreen->httpInitDone)
return;
rfbScreen->httpInitDone = TRUE;
if (!rfbScreen->httpDir)
return;
if (rfbScreen->httpPort == 0) {
rfbScreen->httpPort = rfbScreen->port-100;
}
rfbLog("Listening for HTTP connections on TCP port %d\n", rfbScreen->httpPort);
rfbLog(" URL http://%s:%d\n",rfbScreen->thisHost,rfbScreen->httpPort);
if ((rfbScreen->httpListenSock =
rfbListenOnTCPPort(rfbScreen->httpPort, rfbScreen->listenInterface)) < 0) {
rfbLogPerror("ListenOnTCPPort");
return;
}
/*AddEnabledDevice(httpListenSock);*/
}
void rfbHttpShutdownSockets(rfbScreenInfoPtr rfbScreen) {
if(rfbScreen->httpSock>-1) {
close(rfbScreen->httpSock);
FD_CLR(rfbScreen->httpSock,&rfbScreen->allFds);
rfbScreen->httpSock=-1;
}
}
/*
* httpCheckFds is called from ProcessInputEvents to check for input on the
* HTTP socket(s). If there is input to process, httpProcessInput is called.
*/
void
rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen)
{
int nfds;
fd_set fds;
struct timeval tv;
struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
if (!rfbScreen->httpDir)
return;
if (rfbScreen->httpListenSock < 0)
return;
FD_ZERO(&fds);
FD_SET(rfbScreen->httpListenSock, &fds);
if (rfbScreen->httpSock >= 0) {
FD_SET(rfbScreen->httpSock, &fds);
}
tv.tv_sec = 0;
tv.tv_usec = 0;
nfds = select(max(rfbScreen->httpSock,rfbScreen->httpListenSock) + 1, &fds, NULL, NULL, &tv);
if (nfds == 0) {
return;
}
if (nfds < 0) {
#ifdef WIN32
errno = WSAGetLastError();
#endif
if (errno != EINTR)
rfbLogPerror("httpCheckFds: select");
return;
}
if ((rfbScreen->httpSock >= 0) && FD_ISSET(rfbScreen->httpSock, &fds)) {
httpProcessInput(rfbScreen);
}
if (FD_ISSET(rfbScreen->httpListenSock, &fds)) {
if (rfbScreen->httpSock >= 0) close(rfbScreen->httpSock);
if ((rfbScreen->httpSock = accept(rfbScreen->httpListenSock,
(struct sockaddr *)&addr, &addrlen)) < 0) {
rfbLogPerror("httpCheckFds: accept");
return;
}
#ifdef USE_LIBWRAP
if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
STRING_UNKNOWN)) {
rfbLog("Rejected HTTP connection from client %s\n",
inet_ntoa(addr.sin_addr));
close(rfbScreen->httpSock);
rfbScreen->httpSock=-1;
return;
}
#endif
if(!rfbSetNonBlocking(rfbScreen->httpSock)) {
close(rfbScreen->httpSock);
rfbScreen->httpSock=-1;
return;
}
/*AddEnabledDevice(httpSock);*/
}
}
static void
httpCloseSock(rfbScreenInfoPtr rfbScreen)
{
close(rfbScreen->httpSock);
rfbScreen->httpSock = -1;
buf_filled = 0;
}
static rfbClientRec cl;
/*
* httpProcessInput is called when input is received on the HTTP socket.
*/
static void
httpProcessInput(rfbScreenInfoPtr rfbScreen)
{
struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
char fullFname[512];
char params[1024];
char *ptr;
char *fname;
unsigned int maxFnameLen;
FILE* fd;
rfbBool performSubstitutions = FALSE;
char str[256+32];
#ifndef WIN32
char* user=getenv("USER");
#endif
cl.sock=rfbScreen->httpSock;
if (strlen(rfbScreen->httpDir) > 255) {
rfbErr("-httpd directory too long\n");
httpCloseSock(rfbScreen);
return;
}
strcpy(fullFname, rfbScreen->httpDir);
fname = &fullFname[strlen(fullFname)];
maxFnameLen = 511 - strlen(fullFname);
buf_filled=0;
/* Read data from the HTTP client until we get a complete request. */
while (1) {
ssize_t got;
if (buf_filled > sizeof (buf)) {
rfbErr("httpProcessInput: HTTP request is too long\n");
httpCloseSock(rfbScreen);
return;
}
got = read (rfbScreen->httpSock, buf + buf_filled,
sizeof (buf) - buf_filled - 1);
if (got <= 0) {
if (got == 0) {
rfbErr("httpd: premature connection close\n");
} else {
#ifdef WIN32
errno=WSAGetLastError();
#endif
if (errno == EAGAIN) {
return;
}
rfbLogPerror("httpProcessInput: read");
}
httpCloseSock(rfbScreen);
return;
}
buf_filled += got;
buf[buf_filled] = '\0';
/* Is it complete yet (is there a blank line)? */
if (strstr (buf, "\r\r") || strstr (buf, "\n\n") ||
strstr (buf, "\r\n\r\n") || strstr (buf, "\n\r\n\r"))
break;
}
/* Process the request. */
if(rfbScreen->httpEnableProxyConnect) {
const static char* PROXY_OK_STR = "HTTP/1.0 200 OK\r\nContent-Type: octet-stream\r\nPragma: no-cache\r\n\r\n";
if(!strncmp(buf, "CONNECT ", 8)) {
if(atoi(strchr(buf, ':')+1)!=rfbScreen->port) {
rfbErr("httpd: CONNECT format invalid.\n");
rfbWriteExact(&cl,INVALID_REQUEST_STR, strlen(INVALID_REQUEST_STR));
httpCloseSock(rfbScreen);
return;
}
/* proxy connection */
rfbLog("httpd: client asked for CONNECT\n");
rfbWriteExact(&cl,PROXY_OK_STR,strlen(PROXY_OK_STR));
rfbNewClientConnection(rfbScreen,rfbScreen->httpSock);
rfbScreen->httpSock = -1;
return;
}
if (!strncmp(buf, "GET ",4) && !strncmp(strchr(buf,'/'),"/proxied.connection HTTP/1.", 27)) {
/* proxy connection */
rfbLog("httpd: client asked for /proxied.connection\n");
rfbWriteExact(&cl,PROXY_OK_STR,strlen(PROXY_OK_STR));
rfbNewClientConnection(rfbScreen,rfbScreen->httpSock);
rfbScreen->httpSock = -1;
return;
}
}
if (strncmp(buf, "GET ", 4)) {
rfbErr("httpd: no GET line\n");
httpCloseSock(rfbScreen);
return;
} else {
/* Only use the first line. */
buf[strcspn(buf, "\n\r")] = '\0';
}
if (strlen(buf) > maxFnameLen) {
rfbErr("httpd: GET line too long\n");
httpCloseSock(rfbScreen);
return;
}
if (sscanf(buf, "GET %s HTTP/1.", fname) != 1) {
rfbErr("httpd: couldn't parse GET line\n");
httpCloseSock(rfbScreen);
return;
}
if (fname[0] != '/') {
rfbErr("httpd: filename didn't begin with '/'\n");
rfbWriteExact(&cl, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
httpCloseSock(rfbScreen);
return;
}
if (strchr(fname+1, '/') != NULL) {
rfbErr("httpd: asking for file in other directory\n");
rfbWriteExact(&cl, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
httpCloseSock(rfbScreen);
return;
}
getpeername(rfbScreen->httpSock, (struct sockaddr *)&addr, &addrlen);
rfbLog("httpd: get '%s' for %s\n", fname+1,
inet_ntoa(addr.sin_addr));
/* Extract parameters from the URL string if necessary */
params[0] = '\0';
ptr = strchr(fname, '?');
if (ptr != NULL) {
*ptr = '\0';
if (!parseParams(&ptr[1], params, 1024)) {
params[0] = '\0';
rfbErr("httpd: bad parameters in the URL\n");
}
}
/* If we were asked for '/', actually read the file index.vnc */
if (strcmp(fname, "/") == 0) {
strcpy(fname, "/index.vnc");
rfbLog("httpd: defaulting to '%s'\n", fname+1);
}
/* Substitutions are performed on files ending .vnc */
if (strlen(fname) >= 4 && strcmp(&fname[strlen(fname)-4], ".vnc") == 0) {
performSubstitutions = TRUE;
}
/* Open the file */
if ((fd = fopen(fullFname, "r")) == 0) {
rfbLogPerror("httpProcessInput: open");
rfbWriteExact(&cl, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
httpCloseSock(rfbScreen);
return;
}
rfbWriteExact(&cl, OK_STR, strlen(OK_STR));
while (1) {
int n = fread(buf, 1, BUF_SIZE-1, fd);
if (n < 0) {
rfbLogPerror("httpProcessInput: read");
fclose(fd);
httpCloseSock(rfbScreen);
return;
}
if (n == 0)
break;
if (performSubstitutions) {
/* Substitute $WIDTH, $HEIGHT, etc with the appropriate values.
This won't quite work properly if the .vnc file is longer than
BUF_SIZE, but it's reasonable to assume that .vnc files will
always be short. */
char *ptr = buf;
char *dollar;
buf[n] = 0; /* make sure it's null-terminated */
while ((dollar = strchr(ptr, '$'))!=NULL) {
rfbWriteExact(&cl, ptr, (dollar - ptr));
ptr = dollar;
if (compareAndSkip(&ptr, "$WIDTH")) {
sprintf(str, "%d", rfbScreen->width);
rfbWriteExact(&cl, str, strlen(str));
} else if (compareAndSkip(&ptr, "$HEIGHT")) {
sprintf(str, "%d", rfbScreen->height);
rfbWriteExact(&cl, str, strlen(str));
} else if (compareAndSkip(&ptr, "$APPLETWIDTH")) {
sprintf(str, "%d", rfbScreen->width);
rfbWriteExact(&cl, str, strlen(str));
} else if (compareAndSkip(&ptr, "$APPLETHEIGHT")) {
sprintf(str, "%d", rfbScreen->height + 32);
rfbWriteExact(&cl, str, strlen(str));
} else if (compareAndSkip(&ptr, "$PORT")) {
sprintf(str, "%d", rfbScreen->port);
rfbWriteExact(&cl, str, strlen(str));
} else if (compareAndSkip(&ptr, "$DESKTOP")) {
rfbWriteExact(&cl, rfbScreen->desktopName, strlen(rfbScreen->desktopName));
} else if (compareAndSkip(&ptr, "$DISPLAY")) {
sprintf(str, "%s:%d", rfbScreen->thisHost, rfbScreen->port-5900);
rfbWriteExact(&cl, str, strlen(str));
} else if (compareAndSkip(&ptr, "$USER")) {
#ifndef WIN32
if (user) {
rfbWriteExact(&cl, user,
strlen(user));
} else
#endif
rfbWriteExact(&cl, "?", 1);
} else if (compareAndSkip(&ptr, "$PARAMS")) {
if (params[0] != '\0')
rfbWriteExact(&cl, params, strlen(params));
} else {
if (!compareAndSkip(&ptr, "$$"))
ptr++;
if (rfbWriteExact(&cl, "$", 1) < 0) {
fclose(fd);
httpCloseSock(rfbScreen);
return;
}
}
}
if (rfbWriteExact(&cl, ptr, (&buf[n] - ptr)) < 0)
break;
} else {
/* For files not ending .vnc, just write out the buffer */
if (rfbWriteExact(&cl, buf, n) < 0)
break;
}
}
fclose(fd);
httpCloseSock(rfbScreen);
}
static rfbBool
compareAndSkip(char **ptr, const char *str)
{
if (strncmp(*ptr, str, strlen(str)) == 0) {
*ptr += strlen(str);
return TRUE;
}
return FALSE;
}
/*
* Parse the request tail after the '?' character, and format a sequence
* of <param> tags for inclusion into an HTML page with embedded applet.
*/
static rfbBool
parseParams(const char *request, char *result, int max_bytes)
{
char param_request[128];
char param_formatted[196];
const char *tail;
char *delim_ptr;
char *value_str;
int cur_bytes, len;
result[0] = '\0';
cur_bytes = 0;
tail = request;
for (;;) {
/* Copy individual "name=value" string into a buffer */
delim_ptr = strchr((char *)tail, '&');
if (delim_ptr == NULL) {
if (strlen(tail) >= sizeof(param_request)) {
return FALSE;
}
strcpy(param_request, tail);
} else {
len = delim_ptr - tail;
if (len >= sizeof(param_request)) {
return FALSE;
}
memcpy(param_request, tail, len);
param_request[len] = '\0';
}
/* Split the request into parameter name and value */
value_str = strchr(&param_request[1], '=');
if (value_str == NULL) {
return FALSE;
}
*value_str++ = '\0';
if (strlen(value_str) == 0) {
return FALSE;
}
/* Validate both parameter name and value */
if (!validateString(param_request) || !validateString(value_str)) {
return FALSE;
}
/* Prepare HTML-formatted representation of the name=value pair */
len = sprintf(param_formatted,
"<PARAM NAME=\"%s\" VALUE=\"%s\">\n",
param_request, value_str);
if (cur_bytes + len + 1 > max_bytes) {
return FALSE;
}
strcat(result, param_formatted);
cur_bytes += len;
/* Go to the next parameter */
if (delim_ptr == NULL) {
break;
}
tail = delim_ptr + 1;
}
return TRUE;
}
/*
* Check if the string consists only of alphanumeric characters, '+'
* signs, underscores, and dots. Replace all '+' signs with spaces.
*/
static rfbBool
validateString(char *str)
{
char *ptr;
for (ptr = str; *ptr != '\0'; ptr++) {
if (!isalnum(*ptr) && *ptr != '_' && *ptr != '.') {
if (*ptr == '+') {
*ptr = ' ';
} else {
return FALSE;
}
}
}
return TRUE;
}

View File

@@ -1,95 +0,0 @@
#ifndef _RFB_RFBCONFIG_H
#define _RFB_RFBCONFIG_H
/* rfb/rfbconfig.h. Generated automatically by cmake. */
/* Enable 24 bit per pixel in native framebuffer */
#cmakedefine LIBVNCSERVER_ALLOW24BPP 1
/* work around when write() returns ENOENT but does not mean it */
#cmakedefine LIBVNCSERVER_ENOENT_WORKAROUND 1
/* Define to 1 if you have the <fcntl.h> header file. */
#cmakedefine LIBVNCSERVER_HAVE_FCNTL_H 1
/* Define to 1 if you have the `gettimeofday' function. */
#cmakedefine LIBVNCSERVER_HAVE_GETTIMEOFDAY 1
/* Define to 1 if you have the `jpeg' library (-ljpeg). */
#cmakedefine LIBVNCSERVER_HAVE_LIBJPEG 1
/* Define to 1 if you have the `pthread' library (-lpthread). */
#cmakedefine LIBVNCSERVER_HAVE_LIBPTHREAD 1
/* Define to 1 if you have the `z' library (-lz). */
#cmakedefine LIBVNCSERVER_HAVE_LIBZ 1
/* Define to 1 if you have the <netinet/in.h> header file. */
#cmakedefine LIBVNCSERVER_HAVE_NETINET_IN_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#cmakedefine LIBVNCSERVER_HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#cmakedefine LIBVNCSERVER_HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#cmakedefine LIBVNCSERVER_HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#cmakedefine LIBVNCSERVER_HAVE_SYS_TYPES_H 1
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#cmakedefine LIBVNCSERVER_HAVE_SYS_WAIT_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine LIBVNCSERVER_HAVE_UNISTD_H 1
/* Need a typedef for in_addr_t */
#cmakedefine LIBVNCSERVER_NEED_INADDR_T 1
/* Define to the full name and version of this package. */
#define LIBVNCSERVER_PACKAGE_STRING "@FULL_PACKAGE_NAME@ @PACKAGE_VERSION@"
/* Define to the version of this package. */
#define LIBVNCSERVER_PACKAGE_VERSION "@PACKAGE_VERSION@"
/* Define to 1 if libgcrypt is present */
#cmakedefine LIBVNCSERVER_WITH_CLIENT_GCRYPT 1
/* Define to 1 if GnuTLS is present */
#cmakedefine LIBVNCSERVER_WITH_CLIENT_TLS 1
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
#cmakedefine LIBVNCSERVER_WORDS_BIGENDIAN 1
/* Define to empty if `const' does not conform to ANSI C. */
#cmakedefine const @CMAKE_CONST@
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#cmakedefine inline @CMAKE_INLINE@
#endif
/* Define to `int' if <sys/types.h> does not define. */
#cmakedefine HAVE_LIBVNCSERVER_PID_T 1
#ifndef HAVE_LIBVNCSERVER_PID_T
typedef int pid_t;
#endif
/* The type for size_t */
#cmakedefine HAVE_LIBVNCSERVER_SIZE_T 1
#ifndef HAVE_LIBVNCSERVER_SIZE_T
typedef int size_t;
#endif
/* The type for socklen */
#cmakedefine HAVE_LIBVNCSERVER_SOCKLEN_T 1
#ifndef HAVE_LIBVNCSERVER_SOCKLEN_T
typedef int socklen_t;
#endif
/* once: _RFB_RFBCONFIG_H */
#endif

View File

@@ -1,419 +0,0 @@
/* lzoconf.h -- configuration for the LZO real-time data compression library
This file is part of the LZO real-time data compression library.
Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
The LZO library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
The LZO library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the LZO library; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Markus F.X.J. Oberhumer
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/lzo/
*/
#ifndef __LZOCONF_H_INCLUDED
#define __LZOCONF_H_INCLUDED 1
#define LZO_VERSION 0x2040
#define LZO_VERSION_STRING "2.04"
#define LZO_VERSION_DATE "Oct 31 2010"
/* internal Autoconf configuration file - only used when building LZO */
#if defined(LZO_HAVE_CONFIG_H)
# include <config.h>
#endif
#include <limits.h>
#include <stddef.h>
/***********************************************************************
// LZO requires a conforming <limits.h>
************************************************************************/
#if !defined(CHAR_BIT) || (CHAR_BIT != 8)
# error "invalid CHAR_BIT"
#endif
#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX)
# error "check your compiler installation"
#endif
#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1)
# error "your limits.h macros are broken"
#endif
/* get OS and architecture defines */
#ifndef __LZODEFS_H_INCLUDED
#include "lzodefs.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/***********************************************************************
// some core defines
************************************************************************/
#if !defined(LZO_UINT32_C)
# if (UINT_MAX < LZO_0xffffffffL)
# define LZO_UINT32_C(c) c ## UL
# else
# define LZO_UINT32_C(c) ((c) + 0U)
# endif
#endif
/* memory checkers */
#if !defined(__LZO_CHECKER)
# if defined(__BOUNDS_CHECKING_ON)
# define __LZO_CHECKER 1
# elif defined(__CHECKER__)
# define __LZO_CHECKER 1
# elif defined(__INSURE__)
# define __LZO_CHECKER 1
# elif defined(__PURIFY__)
# define __LZO_CHECKER 1
# endif
#endif
/***********************************************************************
// integral and pointer types
************************************************************************/
/* lzo_uint should match size_t */
#if !defined(LZO_UINT_MAX)
# if defined(LZO_ABI_LLP64) /* WIN64 */
# if defined(LZO_OS_WIN64)
typedef unsigned __int64 lzo_uint;
typedef __int64 lzo_int;
# else
typedef unsigned long long lzo_uint;
typedef long long lzo_int;
# endif
# define LZO_UINT_MAX 0xffffffffffffffffull
# define LZO_INT_MAX 9223372036854775807LL
# define LZO_INT_MIN (-1LL - LZO_INT_MAX)
# elif defined(LZO_ABI_IP32L64) /* MIPS R5900 */
typedef unsigned int lzo_uint;
typedef int lzo_int;
# define LZO_UINT_MAX UINT_MAX
# define LZO_INT_MAX INT_MAX
# define LZO_INT_MIN INT_MIN
# elif (ULONG_MAX >= LZO_0xffffffffL)
typedef unsigned long lzo_uint;
typedef long lzo_int;
# define LZO_UINT_MAX ULONG_MAX
# define LZO_INT_MAX LONG_MAX
# define LZO_INT_MIN LONG_MIN
# else
# error "lzo_uint"
# endif
#endif
/* Integral types with 32 bits or more. */
#if !defined(LZO_UINT32_MAX)
# if (UINT_MAX >= LZO_0xffffffffL)
typedef unsigned int lzo_uint32;
typedef int lzo_int32;
# define LZO_UINT32_MAX UINT_MAX
# define LZO_INT32_MAX INT_MAX
# define LZO_INT32_MIN INT_MIN
# elif (ULONG_MAX >= LZO_0xffffffffL)
typedef unsigned long lzo_uint32;
typedef long lzo_int32;
# define LZO_UINT32_MAX ULONG_MAX
# define LZO_INT32_MAX LONG_MAX
# define LZO_INT32_MIN LONG_MIN
# else
# error "lzo_uint32"
# endif
#endif
/* The larger type of lzo_uint and lzo_uint32. */
#if (LZO_UINT_MAX >= LZO_UINT32_MAX)
# define lzo_xint lzo_uint
#else
# define lzo_xint lzo_uint32
#endif
/* Memory model that allows to access memory at offsets of lzo_uint. */
#if !defined(__LZO_MMODEL)
# if (LZO_UINT_MAX <= UINT_MAX)
# define __LZO_MMODEL /*empty*/
# elif defined(LZO_HAVE_MM_HUGE_PTR)
# define __LZO_MMODEL_HUGE 1
# define __LZO_MMODEL __huge
# else
# define __LZO_MMODEL /*empty*/
# endif
#endif
/* no typedef here because of const-pointer issues */
#define lzo_bytep unsigned char __LZO_MMODEL *
#define lzo_charp char __LZO_MMODEL *
#define lzo_voidp void __LZO_MMODEL *
#define lzo_shortp short __LZO_MMODEL *
#define lzo_ushortp unsigned short __LZO_MMODEL *
#define lzo_uint32p lzo_uint32 __LZO_MMODEL *
#define lzo_int32p lzo_int32 __LZO_MMODEL *
#define lzo_uintp lzo_uint __LZO_MMODEL *
#define lzo_intp lzo_int __LZO_MMODEL *
#define lzo_xintp lzo_xint __LZO_MMODEL *
#define lzo_voidpp lzo_voidp __LZO_MMODEL *
#define lzo_bytepp lzo_bytep __LZO_MMODEL *
/* deprecated - use 'lzo_bytep' instead of 'lzo_byte *' */
#define lzo_byte unsigned char __LZO_MMODEL
typedef int lzo_bool;
/***********************************************************************
// function types
************************************************************************/
/* name mangling */
#if !defined(__LZO_EXTERN_C)
# ifdef __cplusplus
# define __LZO_EXTERN_C extern "C"
# else
# define __LZO_EXTERN_C extern
# endif
#endif
/* calling convention */
#if !defined(__LZO_CDECL)
# define __LZO_CDECL __lzo_cdecl
#endif
/* DLL export information */
#if !defined(__LZO_EXPORT1)
# define __LZO_EXPORT1 /*empty*/
#endif
#if !defined(__LZO_EXPORT2)
# define __LZO_EXPORT2 /*empty*/
#endif
/* __cdecl calling convention for public C and assembly functions */
#if !defined(LZO_PUBLIC)
# define LZO_PUBLIC(_rettype) __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL
#endif
#if !defined(LZO_EXTERN)
# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype)
#endif
#if !defined(LZO_PRIVATE)
# define LZO_PRIVATE(_rettype) static _rettype __LZO_CDECL
#endif
/* function types */
typedef int
(__LZO_CDECL *lzo_compress_t) ( const lzo_bytep src, lzo_uint src_len,
lzo_bytep dst, lzo_uintp dst_len,
lzo_voidp wrkmem );
typedef int
(__LZO_CDECL *lzo_decompress_t) ( const lzo_bytep src, lzo_uint src_len,
lzo_bytep dst, lzo_uintp dst_len,
lzo_voidp wrkmem );
typedef int
(__LZO_CDECL *lzo_optimize_t) ( lzo_bytep src, lzo_uint src_len,
lzo_bytep dst, lzo_uintp dst_len,
lzo_voidp wrkmem );
typedef int
(__LZO_CDECL *lzo_compress_dict_t)(const lzo_bytep src, lzo_uint src_len,
lzo_bytep dst, lzo_uintp dst_len,
lzo_voidp wrkmem,
const lzo_bytep dict, lzo_uint dict_len );
typedef int
(__LZO_CDECL *lzo_decompress_dict_t)(const lzo_bytep src, lzo_uint src_len,
lzo_bytep dst, lzo_uintp dst_len,
lzo_voidp wrkmem,
const lzo_bytep dict, lzo_uint dict_len );
/* Callback interface. Currently only the progress indicator ("nprogress")
* is used, but this may change in a future release. */
struct lzo_callback_t;
typedef struct lzo_callback_t lzo_callback_t;
#define lzo_callback_p lzo_callback_t __LZO_MMODEL *
/* malloc & free function types */
typedef lzo_voidp (__LZO_CDECL *lzo_alloc_func_t)
(lzo_callback_p self, lzo_uint items, lzo_uint size);
typedef void (__LZO_CDECL *lzo_free_func_t)
(lzo_callback_p self, lzo_voidp ptr);
/* a progress indicator callback function */
typedef void (__LZO_CDECL *lzo_progress_func_t)
(lzo_callback_p, lzo_uint, lzo_uint, int);
struct lzo_callback_t
{
/* custom allocators (set to 0 to disable) */
lzo_alloc_func_t nalloc; /* [not used right now] */
lzo_free_func_t nfree; /* [not used right now] */
/* a progress indicator callback function (set to 0 to disable) */
lzo_progress_func_t nprogress;
/* NOTE: the first parameter "self" of the nalloc/nfree/nprogress
* callbacks points back to this struct, so you are free to store
* some extra info in the following variables. */
lzo_voidp user1;
lzo_xint user2;
lzo_xint user3;
};
/***********************************************************************
// error codes and prototypes
************************************************************************/
/* Error codes for the compression/decompression functions. Negative
* values are errors, positive values will be used for special but
* normal events.
*/
#define LZO_E_OK 0
#define LZO_E_ERROR (-1)
#define LZO_E_OUT_OF_MEMORY (-2) /* [not used right now] */
#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */
#define LZO_E_INPUT_OVERRUN (-4)
#define LZO_E_OUTPUT_OVERRUN (-5)
#define LZO_E_LOOKBEHIND_OVERRUN (-6)
#define LZO_E_EOF_NOT_FOUND (-7)
#define LZO_E_INPUT_NOT_CONSUMED (-8)
#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */
#ifndef lzo_sizeof_dict_t
# define lzo_sizeof_dict_t ((unsigned)sizeof(lzo_bytep))
#endif
/* lzo_init() should be the first function you call.
* Check the return code !
*
* lzo_init() is a macro to allow checking that the library and the
* compiler's view of various types are consistent.
*/
#define lzo_init() __lzo_init_v2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\
(int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\
(int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\
(int)sizeof(lzo_callback_t))
LZO_EXTERN(int) __lzo_init_v2(unsigned,int,int,int,int,int,int,int,int,int);
/* version functions (useful for shared libraries) */
LZO_EXTERN(unsigned) lzo_version(void);
LZO_EXTERN(const char *) lzo_version_string(void);
LZO_EXTERN(const char *) lzo_version_date(void);
LZO_EXTERN(const lzo_charp) _lzo_version_string(void);
LZO_EXTERN(const lzo_charp) _lzo_version_date(void);
/* string functions */
LZO_EXTERN(int)
lzo_memcmp(const lzo_voidp a, const lzo_voidp b, lzo_uint len);
LZO_EXTERN(lzo_voidp)
lzo_memcpy(lzo_voidp dst, const lzo_voidp src, lzo_uint len);
LZO_EXTERN(lzo_voidp)
lzo_memmove(lzo_voidp dst, const lzo_voidp src, lzo_uint len);
LZO_EXTERN(lzo_voidp)
lzo_memset(lzo_voidp buf, int c, lzo_uint len);
/* checksum functions */
LZO_EXTERN(lzo_uint32)
lzo_adler32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len);
LZO_EXTERN(lzo_uint32)
lzo_crc32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len);
LZO_EXTERN(const lzo_uint32p)
lzo_get_crc32_table(void);
/* misc. */
LZO_EXTERN(int) _lzo_config_check(void);
typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u;
typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u;
typedef union { void *vp; lzo_bytep bp; lzo_uint u; lzo_uint32 u32; unsigned long l; } lzo_align_t;
/* align a char pointer on a boundary that is a multiple of 'size' */
LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size);
#define LZO_PTR_ALIGN_UP(p,size) \
((p) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(p),(lzo_uint)(size)))
/***********************************************************************
// deprecated macros - only for backward compatibility with LZO v1.xx
************************************************************************/
#if defined(LZO_CFG_COMPAT)
#define __LZOCONF_H 1
#if defined(LZO_ARCH_I086)
# define __LZO_i386 1
#elif defined(LZO_ARCH_I386)
# define __LZO_i386 1
#endif
#if defined(LZO_OS_DOS16)
# define __LZO_DOS 1
# define __LZO_DOS16 1
#elif defined(LZO_OS_DOS32)
# define __LZO_DOS 1
#elif defined(LZO_OS_WIN16)
# define __LZO_WIN 1
# define __LZO_WIN16 1
#elif defined(LZO_OS_WIN32)
# define __LZO_WIN 1
#endif
#define __LZO_CMODEL /*empty*/
#define __LZO_DMODEL /*empty*/
#define __LZO_ENTRY __LZO_CDECL
#define LZO_EXTERN_CDECL LZO_EXTERN
#define LZO_ALIGN LZO_PTR_ALIGN_UP
#define lzo_compress_asm_t lzo_compress_t
#define lzo_decompress_asm_t lzo_decompress_t
#endif /* LZO_CFG_COMPAT */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* already included */
/* vim:set ts=4 et: */

Some files were not shown because too many files have changed in this diff Show More