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

Compare commits

...

112 Commits

Author SHA1 Message Date
Script Kiddy
0772af984d SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.8/kdenetwork/krfb/; revision=1283061
2012-03-01 13:27:37 +00:00
Script Kiddy
1f1aa58026 SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.8/kdenetwork/krfb/; revision=1282828
2012-02-28 19:48:31 +00:00
Script Kiddy
daaa7b45a6 SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.8/kdenetwork/krfb/; revision=1278111
2012-02-04 14:38:52 +00:00
Script Kiddy
8bcbb2de9a SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.8/kdenetwork/krfb/; revision=1274995
2012-01-21 09:24:40 +00:00
Script Kiddy
08f5308e7e SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.8/kdenetwork/krfb/; revision=1273878
2012-01-16 08:31:12 +00:00
Script Kiddy
a5eed055d8 SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.8/kdenetwork/krfb/; revision=1272965
2012-01-10 14:52:11 +00:00
Script Kiddy
3e9b02243f SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.8/kdenetwork/krfb/; revision=1272712
2012-01-09 07:33:12 +00:00
Script Kiddy
067dc983e1 SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.8/kdenetwork/krfb/; revision=1272036
2012-01-06 07:40:13 +00:00
Script Kiddy
9f1da938ae SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.8/kdenetwork/krfb/; revision=1271534
2012-01-04 08:32:26 +00:00
Script Kiddy
3faf49f1d0 SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.8/kdenetwork/krfb/; revision=1271263
2012-01-03 15:53:41 +00:00
Script Kiddy
3b7b7950af SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.8/kdenetwork/krfb/; revision=1270267
2011-12-23 09:35:52 +00:00
Script Kiddy
6d52dc072e SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.8/kdenetwork/krfb/; revision=1269984
2011-12-22 10:45:27 +00:00
Script Kiddy
b6f30a98fa SVN_SILENT made messages (.desktop file)
svn path=/branches/KDE/4.8/kdenetwork/krfb/; revision=1269761
2011-12-21 09:00:10 +00:00
Script Kiddy
4bd481ad54 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1269556
2011-12-20 15:27:06 +00:00
Script Kiddy
e72807e225 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1269365
2011-12-19 14:37:25 +00:00
Script Kiddy
51c54d7dd8 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1269089
2011-12-18 08:53:31 +00:00
Script Kiddy
e270fb9186 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1268924
2011-12-17 08:47:34 +00:00
Script Kiddy
f13c451752 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1268358
2011-12-12 07:37:04 +00:00
Script Kiddy
e00ee00314 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1268260
2011-12-11 07:38:59 +00:00
Script Kiddy
e45bad0e33 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1267705
2011-12-08 08:04:59 +00:00
Script Kiddy
bdb22dca4d SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1267618
2011-12-07 08:23:58 +00:00
Script Kiddy
bfa0444be7 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1267365
2011-12-06 16:02:51 +00:00
Script Kiddy
8a82a27da8 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1266435
2011-11-29 15:49:52 +00:00
Ralf Jung
5097a44442 krfb actually requires Xtst to be built
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1263324
2011-11-09 19:29:05 +00:00
Script Kiddy
b24786205f SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1262529
2011-11-04 08:48:25 +00:00
George Kiagiadakis
9f56633c0b Sync with libvncserver from git (git describe version: 0.9.8-10-g17ce0c5).
My patches in this local fork have been merged upstream, but they
have been merged after 0.9.8 and 0.9.9 hasn't been released yet,
so we cannot yet switch back to finding libvncserver externally.

So I am syncing now with basically what is 0.9.8 + my patches and a few bugfixes.

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1258493
2011-10-11 19:12:14 +00:00
Script Kiddy
7c061ccbf1 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1256082
2011-09-28 06:29:47 +00:00
George Kiagiadakis
e69fc2b61f Fix compilation with telepathy tubes.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1254094
2011-09-17 16:13:19 +00:00
Script Kiddy
dda89a146f SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1249564
2011-08-26 06:56:30 +00:00
Script Kiddy
ff967c23c1 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1248865
2011-08-22 07:37:33 +00:00
Script Kiddy
672311ccea SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1247595
2011-08-16 13:22:20 +00:00
Laurent Montel
2b938c712e normalize signals/slots
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1243993
2011-07-30 12:19:38 +00:00
Script Kiddy
5fd621abc9 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1242912
2011-07-24 07:37:49 +00:00
Script Kiddy
59183f3c69 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1241619
2011-07-15 07:33:43 +00:00
Script Kiddy
33cc068753 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1239971
2011-07-06 08:57:13 +00:00
Script Kiddy
f6d4256f5d SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1235120
2011-06-04 08:17:18 +00:00
Script Kiddy
324f029f10 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1232057
2011-05-15 08:04:05 +00:00
Script Kiddy
c2c6d43299 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1231187
2011-05-10 10:07:34 +00:00
Script Kiddy
1c9189bf50 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1230988
2011-05-09 07:48:38 +00:00
Script Kiddy
705ddc2c07 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1230856
2011-05-08 07:44:07 +00:00
George Kiagiadakis
5c9a3528b6 Do not crash if the framebuffer plugin cannot be loaded.
BUG: 272290

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1230289
2011-05-03 12:36:52 +00:00
Script Kiddy
ba554fe831 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1224665
2011-03-13 07:15:28 +00:00
Script Kiddy
cb5f243262 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1224140
2011-03-08 08:29:16 +00:00
Script Kiddy
f947f69bfb SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1222893
2011-02-27 07:17:42 +00:00
Florian Reinhard
0eb7e1c502 Port krdc,krfb to telepathy-qt4-0.5.x
Reviewed-by: George Kiagiadakis <kiagiadakis.george@gmail.com>Reviewed-by:

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1221586
2011-02-19 10:43:43 +00:00
Script Kiddy
86c5ea3905 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1217717
2011-01-28 07:17:28 +00:00
Script Kiddy
78ec1e53c8 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1217412
2011-01-27 06:14:35 +00:00
Script Kiddy
e8da15b195 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1213675
2011-01-11 09:14:38 +00:00
André Wöbbeking
423c87c382 -pedantic
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1213250
2011-01-09 20:11:44 +00:00
Laurent Montel
60e66e16a0 Fix mem leak
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1212554
2011-01-07 12:33:37 +00:00
Script Kiddy
d93b3faf39 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1206623
2010-12-15 05:56:22 +00:00
Dirk Mueller
8a2549b757 fix format string escaping
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1202686
2010-12-01 22:14:18 +00:00
Maciej Mrozowski
6e0024e7b3 krfb: a little cleanup in CMake:
- remove stray OpenSLP references
- remove no longer used srvloc variable references

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1201535
2010-11-28 03:00:09 +00:00
Maciej Mrozowski
d55fe89023 Fix automagic zlib and jpeg dependencies.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1201534
2010-11-28 02:50:53 +00:00
George Kiagiadakis
527910e277 It's strings.h, not string.h
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1197023
2010-11-14 16:55:01 +00:00
George Kiagiadakis
b116adb5d9 Use relative path for including libvncserver's rfb.h.
Fixes build failure on solaris and makes kdevelop's parser work correctly.

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1197010
2010-11-14 16:45:04 +00:00
George Kiagiadakis
edac882b43 Include <string.h> for bzero(), to fix build failure on solaris.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1197003
2010-11-14 16:37:41 +00:00
George Kiagiadakis
aa9cf0bdb8 Fix rfbProcessNewConnection to return some value instead of void.
BUG: 256891

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1196995
2010-11-14 16:13:43 +00:00
George Kiagiadakis
eee9c34020 Include the local rfb headers to avoid build errors in case libvncserver is also installed in the system location.
BUG: 256642

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1196901
2010-11-14 10:30:36 +00:00
George Kiagiadakis
14525564ac Compile TubesConnectionDialog only if we are building with telepathy support.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1196673
2010-11-13 21:16:48 +00:00
George Kiagiadakis
19699557db Do not install library development symlink.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195582
2010-11-11 14:59:43 +00:00
George Kiagiadakis
28506ebe7d Restore krfb's window state (including its visibility state) on session restore.
BUG: 253072

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195503
2010-11-11 10:42:06 +00:00
George Kiagiadakis
1af586747d Make the main dialog a KXmlGuiWindow.
BUG: 180942
BUG: 171059

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195493
2010-11-11 10:21:48 +00:00
Dario Freddi
8825c4cddc Make building tubes support an experimental option, disabled by default.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195363
2010-11-10 22:25:36 +00:00
George Kiagiadakis
7bd681fd44 Cache the remote address string in the client.
This is because we need to use it as the client's name even after
the client has been disconnected and the socket is closed.

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195307
2010-11-10 19:47:36 +00:00
George Kiagiadakis
bed6c11c35 Enable desktop control by default if the user has selected that in the config.
This is useful for the cases where the user has selected not to be
asked about new connections. Other cases are not affected.

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195302
2010-11-10 19:38:28 +00:00
George Kiagiadakis
7e94d6349c Make it possible to deselect the askOnConnect option without having to check the allowUninvitedConnections.
BUG: 233214

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195301
2010-11-10 19:29:51 +00:00
George Kiagiadakis
301fd72d19 Use KDE_VERSION_STRING for krfb's version.
There is no point in having a separate version, which has been "1.0" for years.

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195297
2010-11-10 19:09:19 +00:00
George Kiagiadakis
2a533c7140 Remove unused FindLibVNCServer.cmake.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195296
2010-11-10 19:03:22 +00:00
George Kiagiadakis
1f408749b7 Modify the connection dialog to show a different message for telepathy tubes clients.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195295
2010-11-10 18:57:39 +00:00
George Kiagiadakis
0ea0b3418c Show actions for controlling the clients in the tray menu. BUG: 210699
This currently includes a "disconnect" action and a toggle action
for enabling/disabling input devices control, which was there previously
but applied only to one client. With the current design every client gets
its own control actions.

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195294
2010-11-10 18:57:37 +00:00
George Kiagiadakis
76de39285b RfbClient: make setControlEnabled() a slot and update() a private method.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195293
2010-11-10 18:57:35 +00:00
George Kiagiadakis
25f4383a51 Fix the broken clients design.
Currently clients are not connected immediately because the user needs
to be notified and take action upon the connection request. This makes
the design of the RfbClient class a bit strange. This new approach
applies tp-qt4's PendingOperation design to RfbClients. New connections
create a PendingRfbClient that internally handles the user notification
and the RfbClient object is only created when the user has accepted the
connection.

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195292
2010-11-10 18:57:32 +00:00
George Kiagiadakis
cda3a0b972 Design fixes: move the event handling back to the RfbClient and improve password handling.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195291
2010-11-10 18:57:29 +00:00
George Kiagiadakis
62e5eacbe7 const-ify RfbClient::name()
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195290
2010-11-10 18:57:26 +00:00
George Kiagiadakis
a615da21f9 Cleanup and update authors/credits in main() and add Collabora's copyright.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195289
2010-11-10 18:57:24 +00:00
George Kiagiadakis
10d6dd4717 Fix memory corruption bug.
This bug occured when a second telepathy tubes client was connected after
the first one had disconnected and the channel (thus, the screen too)
had been destroyed.

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195288
2010-11-10 18:57:23 +00:00
George Kiagiadakis
486b16c357 Change the way rfb events are handled so that they are properly integrated with the Qt event mechanism.
Changes include:
- Use a QSocketNotifier on each rfb socket that we know about, so
  that we don't have to poll the sockets using a timer.
- Use a server registration mechanism in RfbServerManager so that
  the manager can update all the servers at once and delete them
  properly before shutting down.
- Send updates to the clients periodically from the server manager
  and start/stop the update timer when clients connect/disconnect.
  This makes cpu usage drop dramatically when krfb is idle listening
  for incoming connections.
- Let RfbServer handle the screen pointer.
- Other minor adjustments (sorry for not making a separate commit)

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195287
2010-11-10 18:57:20 +00:00
George Kiagiadakis
8126d36f15 Split two event-loop related functions out of the rfbProcessEvents() mechanism.
This is required to be able to do proper event loop integration with Qt.
Idea was taken from vino's libvncserver fork.

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195286
2010-11-10 18:57:17 +00:00
George Kiagiadakis
78b649f39f Prefer the local rfb/rfb.h header now.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195285
2010-11-10 18:57:15 +00:00
George Kiagiadakis
cf0548f348 Fix compilation in c89 mode.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195284
2010-11-10 18:57:13 +00:00
George Kiagiadakis
fac983d5a4 Import a fork of libvncserver 0.9.7.
This is currently required to be able to split off the event processing code
in small functions so that it is possible to integrate libvncserver's event
loop code with Qt's event loop properly. This is also what vino does; the whole
event loop integration idea was taken from there.

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195283
2010-11-10 18:57:07 +00:00
George Kiagiadakis
8ffe4d2ded Fix remote cursor not working. BUG: 207706
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195282
2010-11-10 18:56:59 +00:00
George Kiagiadakis
5dd01e87b6 Do not require a password in tube connections.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195281
2010-11-10 18:56:57 +00:00
George Kiagiadakis
f19f108a4e Fix the socket helper port functions.
The returned port needs conversion from network byte
order to host byte order before it can be used.

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195280
2010-11-10 18:56:55 +00:00
George Kiagiadakis
4742556c51 Implement telepathy tubes support.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195279
2010-11-10 18:56:53 +00:00
George Kiagiadakis
bed6086fe7 Do not free the cursor when freeing a screen.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195278
2010-11-10 18:56:50 +00:00
George Kiagiadakis
2c5cbc755e Refactor the whole system for handling servers and clients.
The new design is very similar to the old one, it's just a bit
more clean imho. Known regression is that the invitations server
is no longer updated when the setting to require a password or not
is changed - I will fix that later.

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195277
2010-11-10 18:56:47 +00:00
George Kiagiadakis
fb4b28b250 Refactor the events handling code.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195267
2010-11-10 17:49:01 +00:00
George Kiagiadakis
cbb9102445 Make the about dialog non-modal so that it doesn't freeze the image on the remote side.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195266
2010-11-10 17:48:59 +00:00
George Kiagiadakis
897734b4d6 Remove more unused stuff from the TrayIcon.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195265
2010-11-10 17:48:57 +00:00
George Kiagiadakis
83ac8619ed Remove the unused action to show the manage invitations dialog from the tray icon.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1195264
2010-11-10 17:48:54 +00:00
Pavel Heimlich
0230d66584 need strings.h for bzero. Fixes build with Sun Studio
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1190402
2010-10-27 14:42:10 +00:00
George Goldberg
c74886dfe7 Apply KDELibs code style with astyle to clear up the mess that was there before.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1189254
2010-10-24 11:21:53 +00:00
George Goldberg
ff019b99cd Reorganise krfb codebase to make it easier to work with.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1189252
2010-10-24 11:21:41 +00:00
George Goldberg
4f78b51022 Fix all the #includes to not be complete chaos.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1189037
2010-10-23 19:30:42 +00:00
George Goldberg
29d9b92b06 Make a wrapper for rfb.h to workaround the problems with TRUE and FALSE being redefined.
Fixes the last of gkiagia's review comments.

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1189036
2010-10-23 19:30:38 +00:00
George Goldberg
87f1f85913 Remove unused KRfbServerPrivate class.
Fixes one of gkiagia's review comments.

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1189035
2010-10-23 19:30:36 +00:00
George Goldberg
cc1f23f23e checkPassword() is not needed by the AbstractConnectionController, so move it to KRfbConnectionController and make it static.
Fixes one of gkiagia's review comments.

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1189034
2010-10-23 19:30:35 +00:00
George Goldberg
a8da333e3b Make RFB server and COnnectionCOntroller classes abstract and make one implementation of them for the standard rfb use case.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1189033
2010-10-23 19:30:32 +00:00
George Goldberg
47e2db27de KrfbServer is now no longer a singleton.
This means that theoretically we can have more than one actual rfb server running at once.
In practice, some work is still needed like making KrfbServer and ConnectionController into abstract base classes
that the normal rfb server and the tubes rfb server can inherit from.
The configuration also needs fixing to apply to individual servers, not all of them.

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1189032
2010-10-23 19:30:29 +00:00
Laurent Montel
893afe07eb Install as programs
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1187755
2010-10-20 11:41:29 +00:00
David Faure
b0c10700e8 Make executable the Type=Application .desktop files we install,
so that they can be used even from a KDE running in another prefix (http://markmail.org/message/4p3krovtnzwx35zd)

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1182577
2010-10-05 00:54:04 +00:00
George Goldberg
410567156d Fix out-of-kdenetwork build to actually work.
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1180685
2010-09-28 15:42:17 +00:00
Script Kiddy
739c655ec7 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1180160
2010-09-27 08:20:45 +00:00
Script Kiddy
7fa12d44dd SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1174792
2010-09-13 08:29:34 +00:00
Albert Astals Cid
62df847d4f do not rely on extract-messages.sh doing the work for us
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1166377
2010-08-21 16:54:07 +00:00
Script Kiddy
e16b1c0007 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1166284
2010-08-21 12:09:56 +00:00
George Goldberg
51ffeee4ce Fix build on Solaris due to missing include.
Thanks to tropikhajma for the patch.

BUG:243863

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1164726
2010-08-17 14:51:51 +00:00
George Goldberg
ebbaa32be7 Fix shift modifier key not working when pressed on remote keyboard.
Patch by Dariusz Mikulski.

BUG:182073

svn path=/trunk/KDE/kdenetwork/krfb/; revision=1164722
2010-08-17 14:37:40 +00:00
Script Kiddy
f4e9a6446a SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1150501
2010-07-16 06:36:00 +00:00
Script Kiddy
c6a6483e08 SVN_SILENT made messages (.desktop file)
svn path=/trunk/KDE/kdenetwork/krfb/; revision=1144031
2010-06-29 10:28:32 +00:00
146 changed files with 33730 additions and 2939 deletions

View File

@@ -1,15 +1,23 @@
project(krfb)
if(NOT INSIDE_KDENETWORK)
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/../cmake/modules ${CMAKE_MODULE_PATH})
message("Not building inside KDENetwork, loading KDE CMake Macros.")
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH})
find_package(KDE4 REQUIRED)
include(KDE4Defaults)
include(MacroLibrary)
include(CheckSymbolExists)
find_package(LibVNCServer)
macro_optional_find_package(LibVNCServer)
if (BUILD_EXPERIMENTAL_TUBES_SUPPORT)
message(WARNING "You enabled experimental Tubes support. Expect breakage!!")
macro_optional_find_package(TelepathyQt4)
macro_log_feature(TELEPATHY_QT4_FOUND "telepathy-qt4" "Telepathy Qt Bindings" "http://telepathy.freedesktop.org" FALSE "0.18" "Needed to build Telepathy Tubes support.")
endif (BUILD_EXPERIMENTAL_TUBES_SUPPORT)
set(CMAKE_REQUIRED_DEFINITIONS ${_KDE_PLATFORM_DEFINITIONS})
@@ -17,115 +25,26 @@ if(NOT INSIDE_KDENETWORK)
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES})
endif(NOT INSIDE_KDENETWORK)
check_symbol_exists(rfbInitServer "rfb/rfb.h" HAVE_LIBVNCSERVER)
macro_bool_to_01(X11_Xdamage_FOUND HAVE_XDAMAGE)
macro_bool_to_01(X11_XShm_FOUND HAVE_XSHM)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-krfb.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-krfb.h )
include_directories(${CMAKE_CURRENT_BINARY_DIR}) # for config-krfb.h
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)
if(NOT X11_XTest_FOUND)
macro_log_feature(X11_XTest_FOUND "libXtst" "X11 Testing Resource extension library" "http://xorg.freedesktop.org" FALSE "" "useful for automated testing of X clients.")
message(FATAL_ERROR "krfb requires the libXtst (http://xorg.freedesktop.org) to be built")
endif(NOT X11_XTest_FOUND)
endif(Q_WS_X11)
#add_subdirectory(kinetd)
#add_subdirectory(kcm_krfb)
if (HAVE_LIBVNCSERVER)
#####################################
# First target: libkrfb - a library
# for linking plugins against.
set (krfbprivate_SRCS
framebuffer.cpp
framebufferplugin.cpp
)
kde4_add_library (krfbprivate
SHARED
${krfbprivate_SRCS}
)
target_link_libraries (krfbprivate
${QT_QTCORE_LIBRARY}
${QT_QTGUI_LIBRARY}
${X11_X11_LIB}
${LIBVNCSERVER_LIBRARIES}
)
set_target_properties (krfbprivate PROPERTIES
VERSION ${GENERIC_LIB_VERSION}
SOVERSION ${GENERIC_LIB_VERSION}
)
install (TARGETS krfbprivate
${INSTALL_TARGETS_DEFAULT_ARGS}
)
install (FILES
krfb-framebuffer.desktop
DESTINATION ${SERVICETYPES_INSTALL_DIR}
)
#####################################
# Build the plugins
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(libvncserver)
add_subdirectory(krfb)
add_subdirectory (framebuffers)
#####################################
# Second target: krfb - the app
# itself.
set(krfb_SRCS
main.cpp
trayicon.cpp
krfbserver.cpp
manageinvitationsdialog.cpp
invitationmanager.cpp
invitedialog.cpp
invitation.cpp
connectiondialog.cpp
personalinvitedialog.cpp
connectioncontroller.cpp
events.cpp
framebuffermanager.cpp
)
kde4_add_kcfg_files(krfb_SRCS krfbconfig.kcfgc)
kde4_add_ui_files(krfb_SRCS connectionwidget.ui
manageinvitations.ui
personalinvitewidget.ui
invitewidget.ui
configtcp.ui
configsecurity.ui
)
kde4_add_executable(krfb ${krfb_SRCS})
target_link_libraries(krfb
krfbprivate
${JPEG_LIBRARIES}
${LIBVNCSERVER_LIBRARIES}
${X11_Xext_LIB}
${X11_X11_LIB}
${X11_Xdamage_LIB}
${QT_QTNETWORK_LIBRARY}
${KDE4_KDNSSD_LIBS}
${KDE4_KDEUI_LIBS}
)
if(X11_XTest_FOUND)
target_link_libraries(krfb ${X11_XTest_LIB})
endif(X11_XTest_FOUND)
install(TARGETS krfb ${INSTALL_TARGETS_DEFAULT_ARGS})
########### install files ###############
install(FILES krfb.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
install(FILES krfb.notifyrc DESTINATION ${DATA_INSTALL_DIR}/krfb)
endif (HAVE_LIBVNCSERVER)
if (NOT INSIDE_KDENETWORK)
macro_display_feature_log()
endif ()

View File

@@ -0,0 +1,22 @@
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,39 @@
# Try to find the Qt4 binding of the Telepathy library
# TELEPATHY_QT4_FOUND - system has TelepathyQt4
# TELEPATHY_QT4_INCLUDE_DIR - the TelepathyQt4 include directory
# TELEPATHY_QT4_LIBRARIES - Link these to use TelepathyQt4
# Copyright (c) 2008, Allen Winter <winter@kde.org>
# Copyright (c) 2009, Andre Moreira Magalhaes <andrunko@gmail.com>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
set(TELEPATHY_QT4_FIND_REQUIRED ${TelepathyQt4_FIND_REQUIRED})
if(TELEPATHY_QT4_INCLUDE_DIR AND TELEPATHY_QT4_LIBRARIES)
# Already in cache, be silent
set(TELEPATHY_QT4_FIND_QUIETLY TRUE)
endif(TELEPATHY_QT4_INCLUDE_DIR AND TELEPATHY_QT4_LIBRARIES)
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_TELEPATHY_QT4 QUIET TelepathyQt4>=0.1.8)
endif(PKG_CONFIG_FOUND)
find_path(TELEPATHY_QT4_INCLUDE_DIR
NAMES TelepathyQt4/Types
HINTS
${PC_TELEPATHY_QT4_INCLUDEDIR}
${PC_TELEPATHY_QT4_INCLUDE_DIRS}
)
find_library(TELEPATHY_QT4_LIBRARIES
NAMES telepathy-qt4
HINTS
${PC_TELEPATHY_QT4_LIBDIR}
${PC_TELEPATHY_QT4_LIBRARY_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(TELEPATHY_QT4 DEFAULT_MSG
TELEPATHY_QT4_LIBRARIES TELEPATHY_QT4_INCLUDE_DIR)

View File

@@ -1,253 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
(C) 2001-2003 by Tim Jansen <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.
*/
#include "connectioncontroller.h"
#include "connectioncontroller.moc"
#include <QX11Info>
#include <QHostInfo>
#include <QApplication>
#include <QDesktopWidget>
#include <QTcpSocket>
#include <QTimer>
#include <KConfig>
#include <KGlobal>
#include <KUser>
#include <KNotification>
#include <KLocale>
#include <KDebug>
#include "invitationmanager.h"
#include "connectiondialog.h"
#include "events.h"
#include "krfbserver.h"
#include "krfbconfig.h"
#include <X11/Xutil.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
static QString peerAddress(int sock) {
const int ADDR_SIZE = 50;
struct sockaddr sa;
socklen_t salen = sizeof(struct sockaddr);
if (getpeername(sock, &sa, &salen) == 0) {
if (sa.sa_family == AF_INET) {
struct sockaddr_in *si = (struct sockaddr_in *)&sa;
return QString(inet_ntoa(si->sin_addr));
}
if (sa.sa_family == AF_INET6) {
char inetbuf[ADDR_SIZE];
inet_ntop(sa.sa_family, &sa, inetbuf, ADDR_SIZE);
return QString(inetbuf);
}
return QString("not a network address");
}
return QString("unable to determine...");
}
static void clientGoneHook(rfbClientPtr cl)
{
ConnectionController *cc = static_cast<ConnectionController *>(cl->clientData);
cc->handleClientGone();
}
static bool checkPassword(const QString &p, unsigned char *ochallenge, const char *response, int len)
{
if ((len == 0) && (p.length() == 0)) {
return true;
}
char passwd[MAXPWLEN];
unsigned char challenge[CHALLENGESIZE];
memcpy(challenge, ochallenge, CHALLENGESIZE);
bzero(passwd, MAXPWLEN);
if (!p.isNull()) {
strncpy(passwd, p.toLatin1(),
(MAXPWLEN <= p.length()) ? MAXPWLEN : p.length());
}
rfbEncryptBytes(challenge, passwd);
return memcmp(challenge, response, len) == 0;
}
ConnectionController::ConnectionController(struct _rfbClientRec *_cl, KrfbServer * parent)
: QObject(parent), cl(_cl)
{
cl->clientData = (void*)this;
}
ConnectionController::~ConnectionController()
{
}
enum rfbNewClientAction ConnectionController::handleNewClient()
{
kDebug();
bool askOnConnect = KrfbConfig::askOnConnect();
bool allowUninvited = KrfbConfig::allowUninvitedConnections();
remoteIp = peerAddress(cl->sock);
if (!allowUninvited && InvitationManager::self()->activeInvitations() == 0) {
KNotification::event("UnexpectedConnection",
i18n("Refused uninvited connection attempt from %1",
remoteIp));
return RFB_CLIENT_REFUSE;
}
// In the remaining cases, the connection will be at least partially established, so we need
// the clientGoneHook to be called when the connection ends.
cl->clientGoneHook = clientGoneHook;
if (!askOnConnect) {
KNotification::event("NewConnectionAutoAccepted",
i18n("Accepted uninvited connection from %1",
remoteIp));
emit sessionEstablished(remoteIp);
return RFB_CLIENT_ACCEPT;
}
KNotification::event("NewConnectionOnHold",
i18n("Received connection from %1, on hold (waiting for confirmation)",
remoteIp));
ConnectionDialog *dialog = new ConnectionDialog(0);
dialog->setRemoteHost(remoteIp);
dialog->setAllowRemoteControl(KrfbConfig::allowDesktopControl());
connect(dialog, SIGNAL(okClicked()), SLOT(dialogAccepted()));
connect(dialog, SIGNAL(cancelClicked()), SLOT(dialogRejected()));
dialog->show();
return RFB_CLIENT_ON_HOLD;
}
bool ConnectionController::handleCheckPassword(rfbClientPtr cl, const char *response, int len)
{
bool allowUninvited = KrfbConfig::allowUninvitedConnections();
QString password = KrfbConfig::uninvitedConnectionPassword();
bool authd = false;
kDebug() << "about to start autentication";
if (allowUninvited) {
authd = checkPassword(password, cl->authChallenge, response, len);
}
if (!authd) {
QList<Invitation> invlist = InvitationManager::self()->invitations();
foreach(const Invitation &it, invlist) {
kDebug() << "checking password";
if (checkPassword(it.password(), cl->authChallenge, response, len) && 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",
remoteIp));
} else {
KNotification::event("InvalidPassword",
i18n("Failed login attempt from %1: wrong password",
remoteIp));
}
return false;
}
return true;
}
void ConnectionController::handleKeyEvent(bool down, rfbKeySym keySym)
{
if (controlEnabled) {
KeyboardEvent ev(down, keySym);
ev.exec();
}
}
void ConnectionController::handlePointerEvent(int bm, int x, int y)
{
if (controlEnabled) {
PointerEvent ev(bm, x, y);
ev.exec();
}
}
void ConnectionController::handleClientGone()
{
emit clientDisconnected(this);
kDebug() << "client gone";
deleteLater();
}
void ConnectionController::clipboardToServer(const QString &s)
{
ClipboardEvent ev(this, s);
ev.exec();
}
void ConnectionController::dialogAccepted()
{
ConnectionDialog *dialog = qobject_cast<ConnectionDialog*>(sender());
if (!dialog) {
kWarning() << "Wrong type of sender.";
return;
}
// rfbStartOnHoldClient(cl);
cl->onHold = false;
setControlEnabled(dialog->cbAllowRemoteControl->isChecked());
setControlCanBeEnabled(dialog->cbAllowRemoteControl->isChecked());
emit sessionEstablished(remoteIp);
}
void ConnectionController::dialogRejected()
{
kDebug() << "refused connection";
rfbRefuseOnHoldClient(cl);
}
void ConnectionController::setControlEnabled(bool enable)
{
controlEnabled = enable;
}
void ConnectionController::setControlCanBeEnabled(bool canBeEnabled)
{
m_controlCanBeEnabled = canBeEnabled;
}
bool ConnectionController::controlCanBeEnabled() const
{
return m_controlCanBeEnabled;
}

View File

@@ -1,68 +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 CONNECTIONCONTROLLER_H
#define CONNECTIONCONTROLLER_H
#include <QObject>
#include <rfb/rfb.h>
class KrfbServer;
/**
@author Alessandro Praduroux <pradu@pradu.it>
*/
class ConnectionController : public QObject
{
Q_OBJECT
public:
ConnectionController(struct _rfbClientRec *_cl, KrfbServer *parent);
~ConnectionController();
bool handleCheckPassword(rfbClientPtr cl, const char *response, int len);
void handleNegotiationFinished(struct _rfbClientRec *cl);
void handleKeyEvent(bool down , rfbKeySym keySym );
void handlePointerEvent( int bm, int x, int y);
void handleClientGone();
void clipboardToServer(const QString &);
enum rfbNewClientAction handleNewClient();
void setControlEnabled(bool enable);
void setControlCanBeEnabled(bool canBeEnabled);
bool controlCanBeEnabled() const;
Q_SIGNALS:
void sessionEstablished(QString);
void notification(QString, QString);
void clientDisconnected(ConnectionController *);
protected Q_SLOTS:
void dialogAccepted();
void dialogRejected();
private:
QString remoteIp;
struct _rfbClientRec *cl;
bool controlEnabled;
bool m_controlCanBeEnabled;
/*
int fd;
KrfbServer *server;
rfbScreenInfoPtr screen;
rfbClientPtr client;
QTcpSocket *tcpConn;
*/
};
#endif

View File

@@ -1,71 +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 "connectiondialog.h"
#include <QCheckBox>
#include <QLabel>
#include <KIconLoader>
#include <KLocale>
#include <KStandardGuiItem>
ConnectionDialog::ConnectionDialog( QWidget *parent )
: KDialog( parent )
{
setCaption(i18n("New Connection"));
setButtons(Ok|Cancel);
setDefaultButton(Cancel);
setModal(true);
setMinimumSize(500, 200);
m_connectWidget = new QWidget( this );
setupUi(m_connectWidget);
pixmapLabel->setPixmap(KIcon("krfb").pixmap(128));
KGuiItem accept = KStandardGuiItem::ok();
accept.setText( i18n( "Accept Connection" ) );
setButtonGuiItem(Ok, accept);
KGuiItem refuse = KStandardGuiItem::cancel();
refuse.setText( i18n( "Refuse Connection" ) );
setButtonGuiItem(Cancel, refuse);
setMainWidget( m_connectWidget );
}
void ConnectionDialog::setRemoteHost( const QString &host )
{
remoteHost->setText( host );
}
void ConnectionDialog::setAllowRemoteControl( bool b )
{
cbAllowRemoteControl->setChecked( b );
cbAllowRemoteControl->setVisible(b);
}
bool ConnectionDialog::allowRemoteControl()
{
return cbAllowRemoteControl->isChecked();
}
#include "connectiondialog.moc"

View File

@@ -1,197 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
(C) 2001-2003 by Tim Jansen <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.
*/
#include "events.h"
#include <QApplication>
#include <QX11Info>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/extensions/XTest.h>
Display *KeyboardEvent::dpy;
signed char KeyboardEvent::modifiers[0x100];
KeyCode KeyboardEvent::keycodes[0x100];
KeyCode KeyboardEvent::leftShiftCode;
KeyCode KeyboardEvent::rightShiftCode;
KeyCode KeyboardEvent::altGrCode;
const int KeyboardEvent::LEFTSHIFT = 1;
const int KeyboardEvent::RIGHTSHIFT = 2;
const int KeyboardEvent::ALTGR = 4;
char KeyboardEvent::ModifierState;
bool KeyboardEvent::initDone = false;
KeyboardEvent::KeyboardEvent(bool d, KeySym k)
: down(d), keySym(k)
{
initKeycodes();
}
void KeyboardEvent::initKeycodes()
{
if (initDone) return;
initDone = true;
KeySym key,*keymap;
int i,j,minkey,maxkey,syms_per_keycode;
dpy = QX11Info::display();
memset(modifiers,-1,sizeof(modifiers));
XDisplayKeycodes(dpy,&minkey,&maxkey);
Q_ASSERT(minkey >= 8);
Q_ASSERT(maxkey < 256);
keymap = (KeySym*) XGetKeyboardMapping(dpy, minkey,
(maxkey - minkey + 1),
&syms_per_keycode);
Q_ASSERT(keymap);
for (i = minkey; i <= maxkey; i++) {
for (j=0; j<syms_per_keycode; j++) {
key = keymap[(i-minkey)*syms_per_keycode+j];
if (key>=' ' && key<0x100 && i==XKeysymToKeycode(dpy,key)) {
keycodes[key]=i;
modifiers[key]=j;
}
}
}
leftShiftCode = XKeysymToKeycode(dpy, XK_Shift_L);
rightShiftCode = XKeysymToKeycode(dpy, XK_Shift_R);
altGrCode = XKeysymToKeycode(dpy, XK_Mode_switch);
XFree ((char *)keymap);
}
/* this function adjusts the modifiers according to mod (as from modifiers) and ModifierState */
void KeyboardEvent::tweakModifiers(signed char mod, bool down)
{
bool isShift = ModifierState & (LEFTSHIFT|RIGHTSHIFT);
if(mod < 0)
return;
if(isShift && mod != 1) {
if(ModifierState & LEFTSHIFT) {
XTestFakeKeyEvent(dpy, leftShiftCode,
!down, CurrentTime);
}
if(ModifierState & RIGHTSHIFT) {
XTestFakeKeyEvent(dpy, rightShiftCode,
!down, CurrentTime);
}
}
if(!isShift && mod==1) {
XTestFakeKeyEvent(dpy, leftShiftCode,
down, CurrentTime);
}
if((ModifierState&ALTGR) && mod != 2) {
XTestFakeKeyEvent(dpy, altGrCode,
!down, CurrentTime);
}
if(!(ModifierState&ALTGR) && mod==2) {
XTestFakeKeyEvent(dpy, altGrCode,
down, CurrentTime);
}
}
void KeyboardEvent::exec() {
#define ADJUSTMOD(sym,state) \
if(keySym==sym) { if(down) ModifierState|=state; else ModifierState&=~state; }
ADJUSTMOD(XK_Shift_L,LEFTSHIFT);
ADJUSTMOD(XK_Shift_R,RIGHTSHIFT);
ADJUSTMOD(XK_Mode_switch,ALTGR);
if(keySym>=' ' && keySym<0x100) {
KeyCode k;
if (down) {
tweakModifiers(modifiers[keySym],True);
}
k = keycodes[keySym];
if (k != NoSymbol) {
XTestFakeKeyEvent(dpy, k, down, CurrentTime);
}
if (down) {
tweakModifiers(modifiers[keySym],False);
}
} else {
KeyCode k = XKeysymToKeycode(dpy, keySym );
if (k != NoSymbol) {
XTestFakeKeyEvent(dpy, k, down, CurrentTime);
}
}
}
bool PointerEvent::initialized = false;
Display *PointerEvent::dpy;
int PointerEvent::buttonMask = 0;
PointerEvent::PointerEvent(int b, int _x, int _y)
: button_mask(b),x(_x),y(_y)
{
if (!initialized) {
initialized = true;
dpy = QX11Info::display();
buttonMask = 0;
}
}
void PointerEvent::exec() {
QDesktopWidget *desktopWidget = QApplication::desktop();
int screen = desktopWidget->screenNumber();
if (screen < 0)
screen = 0;
XTestFakeMotionEvent(dpy, screen, x, y, CurrentTime);
for(int i = 0; i < 5; i++) {
if ((buttonMask&(1<<i))!=(button_mask&(1<<i))) {
XTestFakeButtonEvent(dpy,
i+1,
(button_mask&(1<<i))?True:False,
CurrentTime);
}
}
buttonMask = button_mask;
}
ClipboardEvent::ClipboardEvent(ConnectionController *c, const QString &ctext)
:controller(c),text(ctext)
{
}
void ClipboardEvent::exec()
{
#if 0
if ((controller->lastClipboardDirection == ConnectionController::LAST_SYNC_TO_CLIENT) &&
(controller->lastClipboardText == text)) {
return;
}
controller->lastClipboardDirection = ConnectionController::LAST_SYNC_TO_SERVER;
controller->lastClipboardText = text;
controller->clipboard->setText(text, QClipboard::Clipboard);
controller->clipboard->setText(text, QClipboard::Selection);
#endif
}
VNCEvent::~ VNCEvent()
{
}

View File

@@ -1,70 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
(C) 2001-2003 by Tim Jansen <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 EVENTS_H
#define EVENTS_H
#include <QDesktopWidget>
#include <QEvent>
#include <QString>
#include <X11/Xlib.h>
class ConnectionController;
class QCursor;
class VNCEvent {
public:
virtual void exec() = 0;
virtual ~VNCEvent();
};
class KeyboardEvent : public VNCEvent {
bool down;
KeySym keySym;
static Display *dpy;
static signed char modifiers[0x100];
static KeyCode keycodes[0x100], leftShiftCode, rightShiftCode, altGrCode;
static const int LEFTSHIFT;
static const int RIGHTSHIFT;
static const int ALTGR;
static char ModifierState;
static bool initDone;
static void tweakModifiers(signed char mod, bool down);
public:
static void initKeycodes();
KeyboardEvent(bool d, KeySym k);
virtual void exec();
};
class PointerEvent : public VNCEvent {
int button_mask, x, y;
static bool initialized;
static Display *dpy;
static int buttonMask;
public:
PointerEvent(int b, int _x, int _y);
virtual void exec();
};
class ClipboardEvent : public VNCEvent {
ConnectionController *controller;
QString text;
public:
ClipboardEvent(ConnectionController *c, const QString &text);
virtual void exec();
};
#endif

View File

@@ -2,29 +2,38 @@
Encoding=UTF-8
Comment=Qt based Framebuffer for KRfb.
Comment[ast]=Esquema Qt de buffer pa 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[cs]=Framebuffer založený na Qt pro KRfb.
Comment[da]=Qt-baseret framebuffer til KRfb.
Comment[de]=Qt-basierter Framebuffer für KRfb
Comment[el]=Μνήμη εξόδου βίντεο καρέ με βάση το Qt για το KRfb.
Comment[en_GB]=Qt based Framebuffer for KRfb.
Comment[es]=Esquema Qt de buffer para KRfb
Comment[es]=Memoria intermedia de vídeo basada en Qt para KRfb.
Comment[et]=KRfb Qt põhine kaadripuhver
Comment[eu]=Qt-n oinarritutako KRfb-ren irteerako bideoa
Comment[fi]=QT-perustainen Kehyspuskuri KRfb:lle
Comment[fr]=Sortie vidéo basée sur Qt pour KRfb.
Comment[fr]=Sortie vidéo fondée sur Qt pour KRfb.
Comment[ga]=Maolán fráma le haghaidh KRfb, bunaithe ar Qt.
Comment[gl]=Framebuffer baseado en Qt para KRfb.
Comment[hr]=Međuspremnik okvira baziran na Qt-u za KRfb.
Comment[hu]=Qt-alapú framebuffer a Krfb-hez.
Comment[ia]=Framebuffer basate sur Qt per KRfb
Comment[it]=Framebuffer basato su Qt per KRfb.
Comment[kk]=Qt негіздеген KRfb-нің кадр буфері.
Comment[km]=Framebuffer មាន​មូលដ្ឋាន​លើ Qt សម្រាប់ KRfb 
Comment[ko]=KRfb를 위한 Qt 기반 프레임버퍼.
Comment[lt]=Qt pagrindu veikiantis Framebuffer skirtas KRfb.
Comment[lv]=Qt balstīts kadrbuferis priekš KRfb.
Comment[nb]=Qt-basert rammebuffer for KRfb.
Comment[nds]=Op Qt opbuut Bildpuffer för KRfb
Comment[nl]=Op Qt gebaseerd framebuffer voor KRfb.
Comment[nn]=Qt basert framebuffer for KRfb.
Comment[pl]=Bufor ramki na podstawie Qt dla KRfb.
Comment[pt]='Framebuffer' baseado no Qt para o KRfb.
Comment[pt_BR]=Framebuffer baseado no Qt para o KRfb.
Comment[si]=KRfb සඳහා Qt මත පදනම් වූ රාමු බෆරය
Comment[sk]=Framebuffer založený na Qt pre KRfb.
Comment[sl]=Slikovni medpomnilnik za KRFB, ki temelji na Qt
Comment[sr]=Кадробафер за КРФБ на основу КуТу
@@ -39,29 +48,38 @@ 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[bs]=Qt-ov kadrobafer za KRFB
Name[ca]=«Framebuffer» Qt per al KRfb.
Name[ca@valencia]=«Framebuffer» 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 Framebuffer for KRfb
Name[en_GB]=Qt Framebuffer for KRfb
Name[es]=Esquema Qt de buffer para KRfb
Name[es]=Memoria intermedia de vídeo Qt para KRfb
Name[et]=KRfb Qt kaadripuhver
Name[eu]=KRfb-ren Qt-ko irteerako bideoa
Name[fi]=QT-kehyspuskuri KRfb:lle
Name[fr]=Sortie vidéo Qt pour KRfb
Name[ga]=Maolán fráma Qt le haghaidh KRfb
Name[gl]=Framebuffer de Qt para KRfb
Name[hr]=Qt Framebuffer za KRfb
Name[hu]=Qt framebuffer a Krfb-hez
Name[ia]=Framebuffer Qt per KRfb
Name[it]=Framebuffer Qt per KRfb
Name[kk]=Qt KRfb кадр буфері
Name[km]=Qt Framebuffer សម្រាប់for KRfb
Name[ko]=KRfb를 위한 Qt 프레임버퍼
Name[lt]=Qt Framebufferis skirtas KRfb
Name[lv]=Qt kadrbuferis priekš KRfb.
Name[nb]=Qt rammebuffer for KRfb
Name[nds]=Qt-Bildpuffer för KRfb
Name[nl]=Qt-framebuffer voor KRfb
Name[nn]=Qt-framebuffer 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[si]=KRfb සඳහා වන Qt රාමුබෆරය
Name[sk]=Qt Framebuffer pre KRfb
Name[sl]=Slikovni medpomnilnik Qt za KRFB
Name[sr]=КуТ‑ов кадробафер за КРФБ

View File

@@ -19,7 +19,7 @@
const int UPDATE_TIME = 500;
QtFrameBuffer::QtFrameBuffer(WId id, QObject *parent)
: FrameBuffer(id, parent)
: FrameBuffer(id, parent)
{
fbImage = QPixmap::grabWindow(win).toImage();
fb = new char[fbImage.numBytes()];
@@ -49,7 +49,7 @@ int QtFrameBuffer::width()
return fbImage.width();
}
void QtFrameBuffer::getServerFormat(rfbPixelFormat& format)
void QtFrameBuffer::getServerFormat(rfbPixelFormat &format)
{
format.bitsPerPixel = 32;
format.depth = 32;
@@ -80,12 +80,12 @@ void QtFrameBuffer::updateFrameBuffer()
map.fill(0);
for (int x = 0; x < imgSize.width(); x++) {
for (int y = 0; y < imgSize.height(); y++) {
if (img.pixel(x,y) != fbImage.pixel(x,y)) {
map.setPixel(x,y,1);
}
}
}
for (int y = 0; y < imgSize.height(); y++) {
if (img.pixel(x, y) != fbImage.pixel(x, y)) {
map.setPixel(x, y, 1);
}
}
}
QRegion r(QBitmap::fromImage(map));
tiles = tiles + r.rects();
@@ -94,7 +94,7 @@ void QtFrameBuffer::updateFrameBuffer()
tiles.append(img.rect());
#endif
memcpy(fb, (const char*)img.bits(), img.numBytes());
memcpy(fb, (const char *)img.bits(), img.numBytes());
fbImage = img;
}

View File

@@ -15,11 +15,11 @@
class QTimer;
/**
@author Alessandro Praduroux <pradu@pradu.it>
@author Alessandro Praduroux <pradu@pradu.it>
*/
class QtFrameBuffer : public FrameBuffer
{
Q_OBJECT
Q_OBJECT
public:
explicit QtFrameBuffer(WId id, QObject *parent = 0);
@@ -29,7 +29,7 @@ public:
virtual int height();
virtual int width();
virtual int paddedWidth();
virtual void getServerFormat(rfbPixelFormat& format);
virtual void getServerFormat(rfbPixelFormat &format);
virtual void startMonitor();
virtual void stopMonitor();

View File

@@ -26,7 +26,7 @@
QtFrameBufferPlugin::QtFrameBufferPlugin(QObject *parent, const QVariantList &args)
: FrameBufferPlugin(parent, args)
: FrameBufferPlugin(parent, args)
{
}

View File

@@ -2,29 +2,38 @@
Encoding=UTF-8
Comment=X11 XDamage/XShm based Framebuffer for KRfb.
Comment[ast]=Esquema de buffer pa KRfb basáu en XDamage/XShm
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[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.
Comment[el]=Μνήμη εξόδου βίντεο καρέ με βάση το X11 XDamage/XShm για το KRfb.
Comment[en_GB]=X11 XDamage/XShm based Framebuffer for KRfb.
Comment[es]=Esquema de buffer para KRfb basado en XDamage/XShm
Comment[es]=Memoria intermedia de vídeo basada en X11 Damage/XShm para KRfb.
Comment[et]=KRfb X11 XDamage/XShm põhine kaadripuhver
Comment[eu]=X11 XDamage/XShm oinarritutako KRfb-ren irteerako bideoa.
Comment[fi]=X11 XDamage/XShm-perustainen kehyspuskui KRfb:lle.
Comment[fr]=Sortie vidéo basée sur X11 XDamage / XShm pour KRfb.
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[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.
Comment[it]=Framebuffer basato su XDamage/XShm di X11 per KRfb.
Comment[kk]=X11 XDamage/XShm негіздеген KRfb кадр буфері.
Comment[km]=X11 XDamage/XShm based Framebuffer សម្រាប់ KRfb 
Comment[ko]=KRfb를 위한 X11 XDamage/XShm 기반 프레임버퍼.
Comment[lt]=X11 XDamage/XShm paremtas Framebuffer skirtas KRfb.
Comment[lv]=X11 XDamage/XShm balstīts kadrbuferis priekš KRfb.
Comment[nb]=Rammebuffer for KRfb basert på X11 XDamage/XShm.
Comment[nds]=Op X11-XDamage/-XShm opbuut Bildpuffer för KRfb
Comment[nl]=Op X11 XDamage/XShm gebaseerd framebuffer voor KRfb.
Comment[nn]=X11 XDamage/XShm basert framebuffer for KRfb.
Comment[pl]=Bufor ramki na podstawie X11 XDamage/XShm dla KRfb.
Comment[pt]='Framebuffer' baseado no XDamage/XShm do X11 para o KRfb.
Comment[pt_BR]=Framebuffer baseado no XDamage/XShm do X11 para o KRfb.
Comment[si]=KRfb සඳහා වන රාමු බෆරය මත පදනම් වූ X11 XDamage/XShm.
Comment[sk]=Framebuffer založený na X11 XDamage/XShm pre KRfb.
Comment[sl]=Slikovni medpomnilnik za KRFB, ki temelji na X11 XDamage/XShm
Comment[sr]=Кадробафер за КРФБ на основу Икс‑демиџа/Икс‑схма у Иксу11.
@@ -39,29 +48,38 @@ 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[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[cs]=X11 Framebuffer pro KRfb
Name[da]=X11-framebuffer til KRfb
Name[de]=X11-Framebuffer für KRfb
Name[el]=X11 Framebuffer for KRfb
Name[en_GB]=X11 Framebuffer for KRfb
Name[es]=Buffer de X11 para KRfb
Name[es]=Memoria intermedia de vídeo X11 para KRfb
Name[et]=KRfb X11 kaadripuhver
Name[eu]=KRfb-ren X11-ko irteerako bideoa
Name[fi]=X11-kehyspuskuri KRfb:lle
Name[fr]=Sortie vidéo X11 pour KRfb
Name[ga]=Maolán fráma X11 le haghaidh KRfb
Name[gl]=Framebuffer de X11 para KRfb
Name[hr]=Međuspremnik okvira X11 za KRfb
Name[hu]=X11 framebuffer a Krfb-hez
Name[ia]=Framebuffer X11 per KRfb
Name[it]=Framebuffer X11 per KRfb
Name[kk]=X11 KRfb кадр буфері
Name[km]=X11 Framebuffer សម្រាប់ KRfb
Name[ko]=KRfb를 위한 X11 프레임버퍼
Name[lt]=X11 Framebuffer skirtas KRfb
Name[lv]=X11 kadrbuferis priekš KRfb
Name[nb]=X11 rammebuffer for KRfb
Name[nds]=X11-Bildpuffer för KRfb
Name[nl]=X11 framebuffer voor KRfb
Name[nn]=X11-framebuffer 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[si]=KRfb සඳහා X11 රාමු බෆරය
Name[sk]=X11 Framebuffer pre KRfb
Name[sl]=Slikovni medpomnilnik X11 za KRFB
Name[sr]=Икс11 кадробафер за КРФБ.

View File

@@ -32,7 +32,8 @@
#include <X11/extensions/XShm.h>
#endif
class X11FrameBuffer::P {
class X11FrameBuffer::P
{
public:
#ifdef HAVE_XDAMAGE
@@ -50,8 +51,8 @@ public:
bool running;
};
X11FrameBuffer::X11FrameBuffer(WId id, QObject* parent)
:FrameBuffer(id, parent), d(new X11FrameBuffer::P)
X11FrameBuffer::X11FrameBuffer(WId id, QObject *parent)
: FrameBuffer(id, parent), d(new X11FrameBuffer::P)
{
#ifdef HAVE_XSHM
d->useShm = XShmQueryExtension(QX11Info::display());
@@ -68,10 +69,11 @@ X11FrameBuffer::X11FrameBuffer(WId id, QObject* parent)
QApplication::desktop()->height(),
AllPlanes,
ZPixmap);
if (d->useShm) {
#ifdef HAVE_XSHM
d->updateTile = XShmCreateImage(QX11Info::display(),
DefaultVisual( QX11Info::display(), 0 ),
DefaultVisual(QX11Info::display(), 0),
d->framebufferImage->bits_per_pixel,
ZPixmap,
NULL,
@@ -83,7 +85,7 @@ X11FrameBuffer::X11FrameBuffer(WId id, QObject* parent)
IPC_CREAT | 0777);
d->shminfo.shmaddr = d->updateTile->data = (char *)
shmat(d->shminfo.shmid, 0, 0);
shmat(d->shminfo.shmid, 0, 0);
d->shminfo.readOnly = False;
XShmAttach(QX11Info::display(), &d->shminfo);
@@ -91,11 +93,12 @@ X11FrameBuffer::X11FrameBuffer(WId id, QObject* parent)
} 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;
<< ", depth: " << d->framebufferImage->depth
<< ", padded width: " << d->framebufferImage->bytes_per_line
<< " (sent: " << d->framebufferImage->width * 4 << ")"
<< endl;
fb = d->framebufferImage->data;
#ifdef HAVE_XDAMAGE
@@ -142,14 +145,14 @@ int X11FrameBuffer::paddedWidth()
return d->framebufferImage->bytes_per_line;
}
void X11FrameBuffer::getServerFormat(rfbPixelFormat& format)
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 ) {
if (format.bitsPerPixel == 8) {
format.redShift = 0;
format.greenShift = 3;
format.blueShift = 6;
@@ -158,24 +161,33 @@ void X11FrameBuffer::getServerFormat(rfbPixelFormat& format)
format.blueMax = 3;
} else {
format.redShift = 0;
if ( d->framebufferImage->red_mask )
while ( ! ( d->framebufferImage->red_mask & (1 << format.redShift) ) )
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) ) )
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) ) )
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)
void X11FrameBuffer::handleXDamage(XEvent *event)
{
#ifdef HAVE_XDAMAGE
XDamageNotifyEvent *dev = (XDamageNotifyEvent *)event;
@@ -189,118 +201,141 @@ void X11FrameBuffer::handleXDamage(XEvent * event)
}
void X11FrameBuffer::cleanupRects() {
void X11FrameBuffer::cleanupRects()
{
QList<QRect> cpy = tiles;
bool inserted = false;
tiles.clear();
// kDebug() << "before cleanup: " << cpy.size();
foreach (const QRect &r, cpy) {
foreach(const QRect & r, cpy) {
if (tiles.size() > 0) {
for(int i = 0; i < tiles.size(); i++) {
// kDebug() << r << tiles[i];
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];
// kDebug() << "merged into " << tiles[i];
}
}
if (!inserted) {
tiles.append(r);
// kDebug() << "appended " << r;
// kDebug() << "appended " << r;
}
} else {
// kDebug() << "appended " << r;
// 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){
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){
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() {
void X11FrameBuffer::acquireEvents()
{
XEvent ev;
while (XCheckTypedEvent(QX11Info::display(), d->xdamageBaseEvent+XDamageNotify, &ev)) {
while (XCheckTypedEvent(QX11Info::display(), d->xdamageBaseEvent + XDamageNotify, &ev)) {
handleXDamage(&ev);
}
XDamageSubtract(QX11Info::display(),d->damage, None, None);
XDamageSubtract(QX11Info::display(), d->damage, None, None);
}
QList< QRect > X11FrameBuffer::modifiedTiles()
{
QList<QRect> ret;
if (!d->running) return 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) {
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) {
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) {
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 *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) {
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()
);
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;
@@ -313,7 +348,7 @@ void X11FrameBuffer::startMonitor()
d->running = true;
#ifdef HAVE_XDAMAGE
d->damage = XDamageCreate(QX11Info::display(), win, XDamageReportRawRectangles);
XDamageSubtract(QX11Info::display(),d->damage, None, None);
XDamageSubtract(QX11Info::display(), d->damage, None, None);
#endif
}
@@ -321,14 +356,14 @@ void X11FrameBuffer::stopMonitor()
{
d->running = false;
#ifdef HAVE_XDAMAGE
XDamageDestroy(QX11Info::display(),d->damage);
XDamageDestroy(QX11Info::display(), d->damage);
#endif
}
EvWidget::EvWidget(X11FrameBuffer * x11fb)
:QWidget(0), fb(x11fb)
EvWidget::EvWidget(X11FrameBuffer *x11fb)
: QWidget(0), fb(x11fb)
{
#ifdef HAVE_XDAMAGE
int er;
@@ -336,13 +371,15 @@ EvWidget::EvWidget(X11FrameBuffer * x11fb)
#endif
}
bool EvWidget::x11Event(XEvent * event)
bool EvWidget::x11Event(XEvent *event)
{
#ifdef HAVE_XDAMAGE
if (event->type == xdamageBaseEvent+XDamageNotify) {
if (event->type == xdamageBaseEvent + XDamageNotify) {
fb->handleXDamage(event);
return true;
}
#endif
return false;
}

View File

@@ -14,14 +14,15 @@
class X11FrameBuffer;
class EvWidget: public QWidget {
class EvWidget: public QWidget
{
Q_OBJECT
public:
EvWidget(X11FrameBuffer *x11fb);
protected:
bool x11Event ( XEvent * event );
bool x11Event(XEvent *event);
private:
X11FrameBuffer *fb;
@@ -29,13 +30,13 @@ private:
};
/**
@author Alessandro Praduroux <pradu@pradu.it>
@author Alessandro Praduroux <pradu@pradu.it>
*/
class X11FrameBuffer : public FrameBuffer
{
Q_OBJECT
Q_OBJECT
public:
X11FrameBuffer(WId id, QObject* parent = 0);
X11FrameBuffer(WId id, QObject *parent = 0);
~X11FrameBuffer();
@@ -44,18 +45,18 @@ public:
virtual int height();
virtual int width();
virtual int paddedWidth();
virtual void getServerFormat(rfbPixelFormat& format);
virtual void getServerFormat(rfbPixelFormat &format);
virtual void startMonitor();
virtual void stopMonitor();
void handleXDamage( XEvent *event);
void handleXDamage(XEvent *event);
private:
void cleanupRects();
void acquireEvents();
class P;
P * const d;
P *const d;
};
#endif

View File

@@ -26,7 +26,7 @@
X11FrameBufferPlugin::X11FrameBufferPlugin(QObject *parent, const QVariantList &args)
: FrameBufferPlugin(parent, args)
: FrameBufferPlugin(parent, args)
{
}

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.h>
#include <klocale.h>
#include <KStandardGuiItem>
#include <QtGui/QLabel>
#include <QtGui/QPushButton>
#include <QtGui/QToolTip>
#include <QtGui/QCursor>
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,6 +1,6 @@
include_directories(${CMAKE_BINARY_DIR}/krfb/krfb/ ${CMAKE_SOURCE_DIR}/krfb/srvloc/)
include_directories(${CMAKE_BINARY_DIR}/krfb/krfb)
set(kcm_krfb_PART_SRCS kcm_krfb.cpp ${srvloc_SRCS} ${krfbconfig_SRCS})
set(kcm_krfb_PART_SRCS kcm_krfb.cpp ${krfbconfig_SRCS})
kde4_add_ui3_files(kcm_krfb_PART_SRCS configurationwidget.ui)
kde4_add_ui3_files(kcm_krfb_PART_SRCS
@@ -10,7 +10,7 @@ kde4_add_ui3_files(kcm_krfb_PART_SRCS
kde4_add_plugin(kcm_krfb ${kcm_krfb_PART_SRCS})
target_link_libraries(kcm_krfb ${KDE4_KDECORE_LIBS} ${KDE4_KDE3SUPPORT_LIBS} ${SLP_LIBRARIES})
target_link_libraries(kcm_krfb ${KDE4_KDECORE_LIBS} ${KDE4_KDE3SUPPORT_LIBS})
install(TARGETS kcm_krfb DESTINATION ${PLUGIN_INSTALL_DIR})

View File

@@ -1,2 +1,3 @@
#! /bin/sh
$EXTRACTRC *.ui >> rc.cpp
$XGETTEXT *.cpp -o $podir/kcm_krfb.pot

View File

@@ -39,128 +39,142 @@
typedef KGenericFactory<KcmKRfb, QWidget> KcmKRfbFactory;
K_EXPORT_COMPONENT_FACTORY( krfb, KcmKRfbFactory( "kcm_krfb" ) )
K_EXPORT_COMPONENT_FACTORY(krfb, KcmKRfbFactory("kcm_krfb"))
KcmKRfb::KcmKRfb(QWidget *p, const QStringList &) :
KCModule(KcmKRfbFactory::componentData(), p),
m_configuration(KRFB_CONFIGURATION_MODE) {
KCModule(KcmKRfbFactory::componentData(), p),
m_configuration(KRFB_CONFIGURATION_MODE)
{
KGlobal::locale()->insertCatalog("krfb");
m_confWidget = new ConfigurationWidget(this);
KGlobal::locale()->insertCatalog("krfb");
m_confWidget = new ConfigurationWidget(this);
QVBoxLayout *l = new QVBoxLayout(this);
l->setSpacing(KDialog::spacingHint());
l->setMargin(0);
l->add(m_confWidget);
QVBoxLayout *l = new QVBoxLayout(this);
l->setSpacing(KDialog::spacingHint());
l->setMargin(0);
l->add(m_confWidget);
setButtons(Default|Apply|Default);
setButtons(Default | Apply | Default);
KAboutData* about = new KAboutData( "kcm_krfb", 0, ki18n("Desktop Sharing Control Module"),
VERSION,
ki18n("Configure desktop sharing"), KAboutData::License_GPL,
ki18n("(c) 2002, Tim Jansen\n"),
KLocalizedString(), "http://www.tjansen.de/krfb", "tim@tjansen.de");
about->addAuthor(ki18n("Tim Jansen"), KLocalizedString(), "tim@tjansen.de");
setAboutData( about );
KAboutData *about = new KAboutData("kcm_krfb", 0, ki18n("Desktop Sharing Control Module"),
VERSION,
ki18n("Configure desktop sharing"), KAboutData::License_GPL,
ki18n("(c) 2002, Tim Jansen\n"),
KLocalizedString(), "http://www.tjansen.de/krfb", "tim@tjansen.de");
about->addAuthor(ki18n("Tim Jansen"), KLocalizedString(), "tim@tjansen.de");
setAboutData(about);
load();
load();
connect(m_confWidget->passwordInput, SIGNAL(textChanged(const QString&)), SLOT(configChanged()) );
connect(m_confWidget->allowUninvitedCB, SIGNAL(clicked()), SLOT(configChanged()) );
connect(m_confWidget->enableSLPCB, SIGNAL(clicked()), SLOT(configChanged()) );
connect(m_confWidget->confirmConnectionsCB, SIGNAL(clicked()), SLOT(configChanged()) );
connect(m_confWidget->allowDesktopControlCB, SIGNAL(clicked()), SLOT(configChanged()) );
connect(m_confWidget->autoPortCB, SIGNAL(clicked()), SLOT(configChanged()) );
connect(m_confWidget->portInput, SIGNAL(valueChanged(int)), SLOT(configChanged()) );
connect((QObject*)m_confWidget->manageInvitations, SIGNAL(clicked()),
&m_configuration, SLOT(showManageInvitationsDialog()) );
connect(&m_configuration, SIGNAL(invitationNumChanged(int)),
this, SLOT(setInvitationNum(int)));
setInvitationNum(m_configuration.invitations().size());
connect(m_confWidget->disableBackgroundCB, SIGNAL(clicked()), SLOT(configChanged()) );
connect(m_confWidget->passwordInput, SIGNAL(textChanged(QString)), SLOT(configChanged()));
connect(m_confWidget->allowUninvitedCB, SIGNAL(clicked()), SLOT(configChanged()));
connect(m_confWidget->enableSLPCB, SIGNAL(clicked()), SLOT(configChanged()));
connect(m_confWidget->confirmConnectionsCB, SIGNAL(clicked()), SLOT(configChanged()));
connect(m_confWidget->allowDesktopControlCB, SIGNAL(clicked()), SLOT(configChanged()));
connect(m_confWidget->autoPortCB, SIGNAL(clicked()), SLOT(configChanged()));
connect(m_confWidget->portInput, SIGNAL(valueChanged(int)), SLOT(configChanged()));
connect((QObject *)m_confWidget->manageInvitations, SIGNAL(clicked()),
&m_configuration, SLOT(showManageInvitationsDialog()));
connect(&m_configuration, SIGNAL(invitationNumChanged(int)),
this, SLOT(setInvitationNum(int)));
setInvitationNum(m_configuration.invitations().size());
connect(m_confWidget->disableBackgroundCB, SIGNAL(clicked()), SLOT(configChanged()));
}
void KcmKRfb::configChanged() {
emit changed(true);
void KcmKRfb::configChanged()
{
emit changed(true);
}
void KcmKRfb::setInvitationNum(int num) {
if (num == 0)
m_confWidget->invitationNumLabel->setText(i18n("You have no open invitation."));
else
m_confWidget->invitationNumLabel->setText(i18n("Open invitations: %1", num));
void KcmKRfb::setInvitationNum(int num)
{
if (num == 0) {
m_confWidget->invitationNumLabel->setText(i18n("You have no open invitation."));
} else {
m_confWidget->invitationNumLabel->setText(i18n("Open invitations: %1", num));
}
}
void KcmKRfb::checkKInetd(bool &kinetdAvailable, bool &krfbAvailable) {
kinetdAvailable = false;
krfbAvailable = false;
//TODO verify it when kinetd will port
QDBusInterface kinetd("org.kde.kded", "/modules/kinetd", "org.kde.kinetd");
QDBusReply<bool> reply = kinetd.call("isInstalled","krfb");
if(!reply.isValid())
return;
krfbAvailable = reply;
kinetdAvailable=true;
void KcmKRfb::checkKInetd(bool &kinetdAvailable, bool &krfbAvailable)
{
kinetdAvailable = false;
krfbAvailable = false;
//TODO verify it when kinetd will port
QDBusInterface kinetd("org.kde.kded", "/modules/kinetd", "org.kde.kinetd");
QDBusReply<bool> reply = kinetd.call("isInstalled", "krfb");
if (!reply.isValid()) {
return;
}
krfbAvailable = reply;
kinetdAvailable = true;
}
void KcmKRfb::load() {
bool kinetdAvailable, krfbAvailable;
checkKInetd(kinetdAvailable, krfbAvailable);
void KcmKRfb::load()
{
bool kinetdAvailable, krfbAvailable;
checkKInetd(kinetdAvailable, krfbAvailable);
m_confWidget->allowUninvitedCB->setChecked(m_configuration.allowUninvitedConnections());
m_confWidget->enableSLPCB->setChecked(m_configuration.enableSLP());
m_confWidget->confirmConnectionsCB->setChecked(m_configuration.askOnConnect());
m_confWidget->allowDesktopControlCB->setChecked(m_configuration.allowDesktopControl());
m_confWidget->passwordInput->setText(m_configuration.password());
m_confWidget->autoPortCB->setChecked(m_configuration.preferredPort()<0);
m_confWidget->portInput->setValue(m_configuration.preferredPort()> 0 ?
m_configuration.preferredPort() : 5900);
m_confWidget->disableBackgroundCB->setChecked(m_configuration.disableBackground());
emit changed(false);
m_confWidget->allowUninvitedCB->setChecked(m_configuration.allowUninvitedConnections());
m_confWidget->enableSLPCB->setChecked(m_configuration.enableSLP());
m_confWidget->confirmConnectionsCB->setChecked(m_configuration.askOnConnect());
m_confWidget->allowDesktopControlCB->setChecked(m_configuration.allowDesktopControl());
m_confWidget->passwordInput->setText(m_configuration.password());
m_confWidget->autoPortCB->setChecked(m_configuration.preferredPort() < 0);
m_confWidget->portInput->setValue(m_configuration.preferredPort() > 0 ?
m_configuration.preferredPort() : 5900);
m_confWidget->disableBackgroundCB->setChecked(m_configuration.disableBackground());
emit changed(false);
}
void KcmKRfb::save() {
void KcmKRfb::save()
{
m_configuration.update();
bool allowUninvited = m_confWidget->allowUninvitedCB->isChecked();
m_configuration.setAllowUninvited(allowUninvited);
m_configuration.setEnableSLP(m_confWidget->enableSLPCB->isChecked());
m_configuration.setAskOnConnect(m_confWidget->confirmConnectionsCB->isChecked());
m_configuration.setAllowDesktopControl(m_confWidget->allowDesktopControlCB->isChecked());
m_configuration.setPassword(m_confWidget->passwordInput->text());
if (m_confWidget->autoPortCB->isChecked())
m_configuration.setPreferredPort(-1);
else
m_configuration.setPreferredPort(m_confWidget->portInput->value());
m_configuration.setDisableBackground(m_confWidget->disableBackgroundCB->isChecked());
m_configuration.save();
m_configuration.update();
bool allowUninvited = m_confWidget->allowUninvitedCB->isChecked();
m_configuration.setAllowUninvited(allowUninvited);
m_configuration.setEnableSLP(m_confWidget->enableSLPCB->isChecked());
m_configuration.setAskOnConnect(m_confWidget->confirmConnectionsCB->isChecked());
m_configuration.setAllowDesktopControl(m_confWidget->allowDesktopControlCB->isChecked());
m_configuration.setPassword(m_confWidget->passwordInput->text());
if (m_confWidget->autoPortCB->isChecked()) {
m_configuration.setPreferredPort(-1);
} else {
m_configuration.setPreferredPort(m_confWidget->portInput->value());
}
m_configuration.setDisableBackground(m_confWidget->disableBackgroundCB->isChecked());
m_configuration.save();
#if 0
kapp->dcopClient()->emitDCOPSignal("KRFB::ConfigChanged", "KRFB_ConfigChanged()", QByteArray());
kapp->dcopClient()->emitDCOPSignal("KRFB::ConfigChanged", "KRFB_ConfigChanged()", QByteArray());
#endif
emit changed(false);
emit changed(false);
}
void KcmKRfb::defaults() {
bool kinetdAvailable, krfbAvailable;
checkKInetd(kinetdAvailable, krfbAvailable);
void KcmKRfb::defaults()
{
bool kinetdAvailable, krfbAvailable;
checkKInetd(kinetdAvailable, krfbAvailable);
m_confWidget->allowUninvitedCB->setChecked(false);
m_confWidget->enableSLPCB->setChecked(true);
m_confWidget->confirmConnectionsCB->setChecked(false);
m_confWidget->allowDesktopControlCB->setChecked(false);
m_confWidget->passwordInput->setText("");
m_confWidget->autoPortCB->setChecked(true);
m_confWidget->portInput->setValue(5900);
m_confWidget->disableBackgroundCB->setChecked(false);
emit changed(true);
m_confWidget->allowUninvitedCB->setChecked(false);
m_confWidget->enableSLPCB->setChecked(true);
m_confWidget->confirmConnectionsCB->setChecked(false);
m_confWidget->allowDesktopControlCB->setChecked(false);
m_confWidget->passwordInput->setText("");
m_confWidget->autoPortCB->setChecked(true);
m_confWidget->portInput->setValue(5900);
m_confWidget->disableBackgroundCB->setChecked(false);
emit changed(true);
}
QString KcmKRfb::quickHelp() const
{
return i18n("<h1>Desktop Sharing</h1> This module allows you to configure"
" the KDE desktop sharing.");
return i18n("<h1>Desktop Sharing</h1> This module allows you to configure"
" the KDE desktop sharing.");
}

View File

@@ -27,22 +27,23 @@
#include "configurationwidget.h"
#include "../krfb/configuration.h"
class KcmKRfb : public KCModule {
Q_OBJECT
class KcmKRfb : public KCModule
{
Q_OBJECT
private:
Configuration m_configuration;
ConfigurationWidget *m_confWidget;
void checkKInetd(bool&, bool&);
Configuration m_configuration;
ConfigurationWidget *m_confWidget;
void checkKInetd(bool &, bool &);
public:
KcmKRfb(QWidget *p, const QStringList &);
KcmKRfb(QWidget *p, const QStringList &);
void load();
void save();
void defaults();
QString quickHelp() const;
void load();
void save();
void defaults();
QString quickHelp() const;
private slots:
void setInvitationNum(int num);
void configChanged();
void setInvitationNum(int num);
void configChanged();
};

View File

@@ -14,9 +14,10 @@ Name=Desktop Sharing
Name[af]=Werkskerm Deeling
Name[ar]=مشاركة سطح المكتب
Name[ast]=Escritoriu compartiu
Name[bg]=Споделяне на работното място
Name[bg]=Споделяне на работния плот
Name[bn]=ডেস্কটপ ভাগাভাগি
Name[br]=Rannañ ar vurev
Name[bs]=Dijeljenje radne površine
Name[ca]=Compartició de l'escriptori
Name[ca@valencia]=Compartició de l'escriptori
Name[cs]=Sdílení pracovní plochy
@@ -39,6 +40,7 @@ Name[hi]=डेस्कटॉप साझेदारी
Name[hne]=डेस्कटाप साझेदारी
Name[hr]=Dijeljenje radne površine
Name[hu]=Munkaasztal-megosztás
Name[ia]=Compartir de scriptorio
Name[is]=Skjáborðamiðlun
Name[it]=Condivisione del desktop
Name[ja]=デスクトップ共有
@@ -58,10 +60,11 @@ Name[nn]=Skrivebordsdeling
Name[pa]=ਡੈਸਕਟਾਪ ਸ਼ੇਅਰਿੰਗ
Name[pl]=Współdzielenie pulpitu
Name[pt]=Partilha do Ecrã
Name[pt_BR]=Compartilhamento do Desktop
Name[pt_BR]=Compartilhamento do área de trabalho
Name[ro]=Partajare birou
Name[ru]=Общий рабочий стол
Name[se]=Čállinbeavdejuohkkin
Name[si]=වැඩතල හවුල්
Name[sk]=Zdieľanie pracovnej plochy
Name[sl]=Deljenje namizja
Name[sr]=Дељење површи
@@ -73,6 +76,7 @@ Name[ta]=பணிமேடை பகிர்வு
Name[tg]=Истифодабарии муштараки Мизи корӣ
Name[th]=ใช้งานพื้นที่ทำงานร่วมกัน
Name[tr]=Masaüstü Paylaşımı
Name[ug]=ئۈستەلئۈستىنى ھەمبەھىرلەش
Name[uk]=Спільні стільниці
Name[vi]=Chia sẻ màn hình nền
Name[xh]=Ukwehlulelana kwe Desktop
@@ -85,9 +89,10 @@ Comment=Configure Desktop Sharing
Comment[af]=Konfigureer Werkskerm Deeling
Comment[ar]=تعديل مشاركة سطح المكتب
Comment[ast]=Configura'l to escritoriu compartíu
Comment[bg]=Настройване споделянето на работното място
Comment[bg]=Настройки на споделянето на работния плот
Comment[bn]=ডেস্কটপ ভাগাভাগি কনফিগার করুন
Comment[br]=Kefluniañ rannañ ar vurev
Comment[bs]=Podešavanje dijeljenja površine
Comment[ca]=Lupa de l'escriptori
Comment[ca@valencia]=Lupa de l'escriptori
Comment[cs]=Nastavit sdílení pracovní plochy
@@ -110,6 +115,7 @@ Comment[hi]=डेस्कटॉप साझेदारी कॉन्फ़
Comment[hne]=डेस्कटाप साझेदारी कान्फिगर करव
Comment[hr]=Podešavanje dijeljenja radne površine
Comment[hu]=A munkaasztal-megosztás beállításai
Comment[ia]=Configura le compartir de scriptorio
Comment[is]=Stilla skjáborðsmiðlun
Comment[it]=Configura condivisione del desktop
Comment[ja]=デスクトップ共有の設定
@@ -129,10 +135,11 @@ Comment[nn]=Set opp skrivebordsdeling
Comment[pa]=ਡੈਸਕਟਾਪ ਸ਼ੇਅਰਿੰਗ ਸੰਰਚਨਾ
Comment[pl]=Konfiguracja współdzielenia pulpitu
Comment[pt]=Configurar a Partilha do Ecrã
Comment[pt_BR]=Configurar compartilhamento da área de trabalho
Comment[pt_BR]=Configura o compartilhamento da área de trabalho
Comment[ro]=Configurează partajarea biroului
Comment[ru]=Параметры общего рабочего стола
Comment[se]=Heivet čállinbeavdejuohkkima
Comment[si]=වැඩතල හවුල් සකසන්න
Comment[sk]=Nastavenie zdieľania pracovnej plochy
Comment[sl]=Nastavi deljenje namizja
Comment[sr]=Подешавање дељења површи
@@ -152,47 +159,35 @@ Comment[zh_CN]=配置桌面共享
Comment[zh_HK]=設定桌面分享
Comment[zh_TW]=設定桌面分享
X-KDE-Keywords=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited
X-KDE-Keywords[bg]=Keywords=споделяне, работно, място, десктоп, покана, връзка, desktop sharing, krfb, vnc, sharing, krdc, remote desktop connection, invitation, port, slp, uninvited
X-KDE-Keywords[ca]=compartició de l'escriptori,krfb,vnc,compartir,krdc,connexió a l'escriptori remot,invitació,port,slp,no invitat
X-KDE-Keywords[cs]=sdílení plochy,krfb,vnc,sdílení,rdp,krdc,připojení vzdálené plochy,pozvánka,port,slp
X-KDE-Keywords[cy]=rhannu penbwrdd,krfb,vnc,rhannu,rdp,krdc,cysylltiad penbwrdd pell,gwahoddiad,porth,slp,heb wahoddiad
X-KDE-Keywords[da]=desktopdeling,krfb,vnc,deling,krdc,ekstern desktopforbindelse,invitation,port,slp,ikke inviteret
X-KDE-Keywords[de]=Arbeitsfläche freigeben,krfb,VNC,freigeben,krdc,Entfernte Arbeitsfläche,Einladung,Port,slp,uneingeladen,rdp,remote desktop
X-KDE-Keywords[el]=κοινή χρήση επιφάνειας εργασίας,krfb,vnc,κοινή χρήση,krdc,σύνδεση σε απομακρυσμένη επιφάνεια εργασίας,πρόσκληση,θύρα,slp,απρόσκλητο
X-KDE-Keywords[es]=escritorio compartido,krfb,vnc,compartir,rdp,krdc, conexión escritorio remoto,invitación,puerto,slp,no invitado
X-KDE-Keywords[ca]=compartició d'escriptori,krfb,vnc,compartició,krdc,connexió d'escriptori remot,invitació,port,slp,no invitat
X-KDE-Keywords[ca@valencia]=compartició d'escriptori,krfb,vnc,compartició,krdc,connexió d'escriptori remot,invitació,port,slp,no invitat
X-KDE-Keywords[da]=skrivebordsdeling,krfb,vnc,deling,krdc,remote desktop,fjernskrivebord,invitation,port,slp,uinviteret
X-KDE-Keywords[de]=freigabe der arbeitsfläche,krfb,vnc,freigabe,krdc,fernwartung,einladung,port,slp
X-KDE-Keywords[el]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited
X-KDE-Keywords[es]=compartición de escritorio,krfb,vnc,compartición,krdc,conexión de escritorio en remoto,invitación,puerto,slp,no invitado
X-KDE-Keywords[et]=töölaua jagamine,krfb,vnc,jagamine,rdp,krdc,kaugtöölaua ühendus,rdp,kutse,port,slp,kutsumata
X-KDE-Keywords[eu]=mahaigain partekatzea,krfb,vnc,partekatzea,krdc,urruneko mahaigain konexioa,gonbidapena,ataka,slp,gonbidapen gabea
X-KDE-Keywords[fa]=اشتراک رومیزی، krfb، vnc، اتصال رومیزی راه دور، دعوت، درگاه، slp، دعوت‌نشده
X-KDE-Keywords[fi]=työpöydän jakaminen,krfb,vnc,jakaminen,krdc,etätyöpöytäyhteys, kutsu,portti,slp,kutsumaton, työpöytä
X-KDE-Keywords[fr]=partage de bureau,krfb,vnc,partage,rdp,krdc,connexion à un bureau distant,invitation,port,slp,non invité
X-KDE-Keywords[gl]=compartilla de escritorio, vnc, compartir, krdc, conexón ao escritorio remoto, invitación, porto, slt, convidado, compartillar
X-KDE-Keywords[he]=שיתוף שולחן עבודה,שיתוף,חיבור לשולחן עבודה מרוחק,desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection, invitation, port, slp, uninvited
X-KDE-Keywords[hu]=munkaasztal-megosztás,krfb,vnc,megosztás,krdc,csatlakozás távoli munkaasztalhoz,meghívás,port,slp,meghívás nélkül
X-KDE-Keywords[is]=skjáborðsmiðlun,miðlun,krfb,vnc,rdp,krdc,fjarvinnsla,remote desktop connection,rdp
X-KDE-Keywords[fr]=partage de bureau,krfb,vnc,partage,krdc,connexion à un bureau distant,invitation,port,slp,non-invité
X-KDE-Keywords[hu]=asztalmegosztás,krfb,vnc,megosztás,krdc,távoliasztal-kapcsolat,meghívás,port,slp,meghívatlan
X-KDE-Keywords[ia]=compartir de scriptorio,krfb.vnc,compartir,krdc,connexion de scriptorio remote,invitation,porto,slp,non invitate
X-KDE-Keywords[it]=condivisione desktop,krfb,vnc,condivisione,krdc,connessione desktop remoto,invito,porta,slp,non invitato
X-KDE-Keywords[ja]=デスクトップ共有,krfb,vnc,共有,rdp,krdc,リモートデスクトップ接続,招待,ポート,slp,uninvited
X-KDE-Keywords[km]=ការ​ចែក​រំលែក​ផ្ទៃតុ,krfb,vnc,ការ​ចែក​រំលែក,krdc,ការ​តភ្ជាប់​ផ្ទៃ​តុ​ពី​ចម្ងាយ,អញ្ជើញ,ច្រក,slp,មិន​បានអញ្ជើញ
X-KDE-Keywords[lt]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,dalinimasis darbastaliu,nutolusio darbastalio prijungimas,kvietimas,ryšys,nekviestas,jungtis,prievadas,dalintis,pasidalinti,jungimasis,prisijungti,kviesti
X-KDE-Keywords[mk]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,делење на површината,krfb,vnc,делење,krdc,поврзување со оддалечена површина,покана,порта,slp,непоканет
X-KDE-Keywords[ms]= perkongsian ruang kerja, sambungan, liang, desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited
X-KDE-Keywords[nb]=skrivebordsdeling,krfb,vnc,deling,krdc,tilkobling til fjernt skrivebord,invitasjon,port,slp,ikke invitert
X-KDE-Keywords[nds]=schriefdisch,freegeven,freegaav,krfb,vnc,delen,krdc,feern Schriefdisch,verbinnen,inladen,port,slp,nich inlaadt
X-KDE-Keywords[ne]=डेस्कटप साझेदारी,krfb,vnc,साझेदारी,krdc, टाढाको डेस्कटप जडान,निमन्त्रणा,पोर्ट,slp,निमन्त्रणा नगरिएको
X-KDE-Keywords[nl]=desktop sharing,krfb,vnc,sharing,rdp,krdc,remote desktop connection,uitnodiging,slp,rdp,verbinding, bureaublad delen,bureaublad op afstand
X-KDE-Keywords[nn]=skrivebordsdeling,krfb,vnc,deling,krdc,nettverksskrivebord,invitasjon,port,slp,ikkje invitert
X-KDE-Keywords[pl]=współdzielenie pulpitu,krfb,vnc,współdzielenie,rdp,krdc,zdalne połączenie, zdalne biurko, zdalny pulpit, zaproszenie,port,slp
X-KDE-Keywords[pt]=partilha do ecrã,krfb,vnc,partilha,krdc,ligação a um ecrã remoto,convite,porto,slp,sem convite
X-KDE-Keywords[pt_BR]=compartilhamento de desktop,krfb,vnc,compartilhamento,krdc,conexão a desktop remoto,convite,porta,slp,não convidado
X-KDE-Keywords[sl]=namizje,souporaba,krfb,vnc,krdc,povezava oddaljenega namizja, povabilo,port,slp,nepovabljen
X-KDE-Keywords[sr]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,радна површина,дељење,позив,порт,непозван,удаљено
X-KDE-Keywords[sr@latin]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,radna površina,deljenje,poziv,port,nepozvan,udaljeno
X-KDE-Keywords[sv]=dela skrivbord,krfb,vnc,dela,krdc,fjärrskrivbordsanslutning,inbjudan,port,slp
X-KDE-Keywords[ta]=பணிமேடை பகிர்வு,krfb,vnc,பகிர்வு,krdc,தொலை பணிமேடை இணைப்பு,அழைப்பிதழ், துறை, slp, uninvited
X-KDE-Keywords[tr]=masaüstü paylaşımı,krfb,vnc,paylaşım,krdc,uzak masaüstü bağlantısı,davet,port,slp
X-KDE-Keywords[uk]=спільні стільниці,krfb,vnc,спільний,rdp,krdc,з'єднання віддаленої стільниці,запрошення,rdp,slp,без запрошення
X-KDE-Keywords[vi]=chia sẻ màn hình,krfb,vnc,chia sẻ,krdc,màn hình ở xa kết nối,mời kết nối,cổng,slp,không được mời
X-KDE-Keywords[kk]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited
X-KDE-Keywords[km]=ការ​ចែក​រំលែក​ផ្ទៃតុ,krfb,vnc,ការ​ចែក​រំលែក,krdc,ការ​តភ្ជាប់​ផ្ទៃ​តុ​ពី​ចម្ងាយ,​ការ​អញ្ជើញ,ច្រក,slp,មិន​ត្រូវ​បានអញ្ជើញ
X-KDE-Keywords[ko]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,데스크톱,공유,원격 데스크톱,포트
X-KDE-Keywords[nb]=skrivebordsdeling,krfb,vnc,deling,krdc,tilkoblng til annet skrivebord,invitasjon,port,slp,ikke invitert
X-KDE-Keywords[nds]=Schriefdischfreegaav,krfb,vnc,Freegaav,Verbinnen na feern Schriefdisch,Inladen,Port,Koppelsteed,slp,nich inlaadt
X-KDE-Keywords[nl]=delen van bureaublad,krfb,vnc,delen,krdc,verbinding naar bureaublad op afstand,invitatie,poort,slp,ongenodigd
X-KDE-Keywords[pl]=współdzielenie pulpitu,krfb,vnc,współdzielenie,krdc,podłączenie zdalnego pulpitu,zaproszenie,port,slp,niezaproszony
X-KDE-Keywords[pt]=partilha do ecrã,krfb,vnc,partilha,krdc,ligação ecrã remoto,convite,porto,slp,sem convite
X-KDE-Keywords[pt_BR]=compartilhamento da área de trabalho,krfb,vnc,compartilhar,krdc,conexão à área de trabalho remota,convite,porta,desconvidar
X-KDE-Keywords[sk]=zdieľanie plochy,krfb,vnc,zdieľanie,krdc,vzdialené pripojenie plochy,pozvanie,port,slp,nepozvaný
X-KDE-Keywords[sr]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,дељење површи,КРФБ,ВНЦ,дељење,КРДЦ,удаљена површ,позивница,порт,СЛП,непозван
X-KDE-Keywords[sr@ijekavian]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,дељење површи,КРФБ,ВНЦ,дељење,КРДЦ,удаљена површ,позивница,порт,СЛП,непозван
X-KDE-Keywords[sr@ijekavianlatin]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,deljenje površi,KRFB,VNC,deljenje,KRDC,udaljena površ,pozivnica,port,SLP,nepozvan
X-KDE-Keywords[sr@latin]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,deljenje površi,KRFB,VNC,deljenje,KRDC,udaljena površ,pozivnica,port,SLP,nepozvan
X-KDE-Keywords[sv]=dela skrivbord,krfb,vnc,dela,krdc,fjärrskrivbordsanslutning,inbjudan,port,slp,oinbjuden
X-KDE-Keywords[uk]=krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,спільне використання,керування,оприлюднення,віддалене з’єднання,запрошення,порт,небажане
X-KDE-Keywords[x-test]=xxdesktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvitedxx
X-KDE-Keywords[zh_CN]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,桌面共享,共享,远程桌面连接,邀请,端口,邀请
X-KDE-Keywords[zh_TW]=desktop sharing,krfb,vnc,sharing,rdp,krdc,remote desktop connection,rdp,桌面分享,分享,遠端桌面連線,invitation,port,slp,uninvited
X-KDE-Keywords[zh_CN]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited,桌面共享,共享,远程桌面,远程桌面连接,邀请,端口,取消邀请
X-KDE-Keywords[zh_TW]=desktop sharing,krfb,vnc,sharing,krdc,remote desktop connection,invitation,port,slp,uninvited
Categories=Qt;KDE;X-KDE-settings-network;Settings;

View File

@@ -1,10 +1,6 @@
include_directories( ${CMAKE_SOURCE_DIR}/krfb/srvloc )
########### next target ###############
set(kded_kinetd_PART_SRCS kinetd.cpp ${srvloc_SRCS})
set(kded_kinetd_PART_SRCS kinetd.cpp)
message(STATUS "Port to krfb DBUS")
# kde4_add_dcop_skels(kded_kinetd_PART_SRCS kinetd.h )
@@ -12,7 +8,7 @@ message(STATUS "Port to krfb DBUS")
kde4_add_plugin(kded_kinetd ${kded_kinetd_PART_SRCS})
target_link_libraries(kded_kinetd ${KDE4_KIO_LIBS} ${KDE4_KDNSSD_LIBS} ${SLP_LIBRARIES})
target_link_libraries(kded_kinetd ${KDE4_KIO_LIBS} ${KDE4_KDNSSD_LIBS})
install(TARGETS kded_kinetd DESTINATION ${PLUGIN_INSTALL_DIR})
@@ -22,7 +18,3 @@ install(TARGETS kded_kinetd DESTINATION ${PLUGIN_INSTALL_DIR})
install(FILES kinetd.notifyrc DESTINATION ${DATA_INSTALL_DIR}/krfb)
install(FILES kinetdmodule.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR})
install(FILES kinetd.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kded)

File diff suppressed because it is too large Load Diff

View File

@@ -10,9 +10,10 @@ Name=KDE Internet Daemon
Name[af]=Kde Internet Bediener
Name[ar]=كيدي إنترنت مراقب
Name[ast]=Degorriu d'Internet de KDE
Name[bg]=Интернет демон
Name[bg]=Интернет демон (KDE)
Name[bn]=কে-ডি-ই ইন্টারনেট ডিমন
Name[br]=Diaoul kenrouedad KDE
Name[bs]=KDE-ov Internet Demon
Name[ca]=Dimoni d'Internet per al KDE
Name[ca@valencia]=Dimoni d'Internet per al KDE
Name[cs]=KDE Internet démon
@@ -24,7 +25,7 @@ Name[en_GB]=KDE Internet Dæmon
Name[eo]=KDE interreta demono
Name[es]=Demonio de Internet de KDE
Name[et]=KDE internetideemon
Name[eu]=KDE interneteko daemona
Name[eu]=KDEren interneteko daemona
Name[fa]=شبح اینترنتی KDE
Name[fi]=KDE:n Internet-palvelin
Name[fr]=Démon Internet de KDE
@@ -35,6 +36,7 @@ Name[hi]=केडीई इंटरनेट डेमन
Name[hne]=केडीई इंटरनेट डेमन
Name[hr]=KDE Internet Daemon
Name[hu]=KDE internetes szolgáltatás
Name[ia]=Demone Internet de KDE
Name[is]=KDE Internetþjónn
Name[it]=Demone Internet di KDE
Name[ja]=KDE インターネットデーモン
@@ -52,14 +54,16 @@ Name[ne]=केडीई इन्टरनेट डेइमोन
Name[nl]=KDE Internet Daemon
Name[nn]=KDE-Internett-teneste
Name[pa]=KDE ਇੰਟਰਨੈੱਟ ਡੈਮਨ
Name[pl]=Internet/sieć
Name[pl]=Demon internetowy dla KDE
Name[pt]=Servidor de Internet do KDE
Name[pt_BR]=Servidor de Internet do KDE
Name[ro]=Demon de Internet KDE
Name[ru]=Доступ к Интернету
Name[se]=KDE-Interneahtta-duogášprográmma
Name[si]=KDE ජාල ඩීමනය
Name[sk]=KDE Internet démon
Name[sl]=Internetni strežnik za KDE
Name[sq]=KDE Internet Daemon
Name[sr]=КДЕ‑ов интернет демон
Name[sr@ijekavian]=КДЕ‑ов интернет демон
Name[sr@ijekavianlatin]=KDEov internet demon
@@ -81,8 +85,9 @@ Name[zh_TW]=KDE Internet 伺服程式
Comment=An Internet daemon that starts network services on demand
Comment[ar]=رقيب الإنترنت بدأ خدمة الشبكة على الرقيب
Comment[ast]=Un degorriu d'Internet qu'entama los servicios de rede baxo demanda
Comment[bg]=Интернет демон, който служи за стартиране на мрежови услуги при поискване
Comment[bg]=Интернет демон, който зарежда мрежови услуги при поискване
Comment[bn]=একটি ইন্টারনেট ডিমন যে চাহিদা ভিত্তিক নেটওয়ার্ক সার্ভিস আরম্ভ করে
Comment[bs]=Internet daemon koji pokreće mrežne servise po zahtijevu
Comment[ca]=Un dimoni d'Internet que arrenca els serveis de xarxa sota demanda
Comment[ca@valencia]=Un dimoni d'Internet que arrenca els serveis de xarxa sota demanda
Comment[cs]=Internetový démon spouštějící síťové služby na požádání
@@ -94,7 +99,7 @@ Comment[en_GB]=An Internet dæmon that starts network services on demand
Comment[eo]=Interreta demono kiu lanĉas retajn servojn laŭ bezono
Comment[es]=Un demonio de Internet que inicia los servicios de red a demanda
Comment[et]=Internetideemon, mis käivitab nõudmisel võrguteenused
Comment[eu]=Sare zerbitzuak eskatzean abiarazten dituen Interneteko daemona
Comment[eu]=Sareko zerbitzuak eskatzean abiarazten dituen Interneteko daemona
Comment[fa]=یک شبح اینترنتی که خدمات شبکه را بر اساس تقاضا آغاز می‌کند
Comment[fi]=Internet-palvelin, joka käynnistää verkkopalveluita
Comment[fr]=Un démon Internet qui démarre le service réseau à la demande
@@ -105,6 +110,7 @@ Comment[hi]=एक इंटरनेट डेमन जो मांग पर
Comment[hne]=एक इंटरनेट डेमन जऊन मांग मं नेटवर्क सेवा चालू करथे
Comment[hr]=Internet daemon koji pokreće mrežne usluge kada su zatražene
Comment[hu]=A hálózati szolgáltatások vezérlését biztosító program
Comment[ia]=Un demone internet que starta servicios de rete sur requesta
Comment[is]=Internetþjónn sem ræsir tengingar við Internetið eftir þörfum
Comment[it]=Un demone Internet che avvia i servizi di rete a richiesta
Comment[ja]=要求時にネットワークサービスを起動するインターネットデーモン
@@ -122,23 +128,24 @@ Comment[ne]=एउटा इन्टरनेट डेइमोन जसल
Comment[nl]=Een internetdaemon die netwerkdiensten op afroep start
Comment[nn]=Internett-teneste som startar nettverkstenester når dei trengst
Comment[pa]=ਇੱਕ ਇੰਟਰਨੈੱਟ ਡੈਮਨ, ਜੋ ਕਿ ਲੋੜ ਪੈਣ ਉੱਤੇ ਨੈੱਟਵਰਕ ਸਰਵਿਸਾਂ ਸ਼ੁਰੂ ਕਰਦੀ ਹੈ।
Comment[pl]=Uruchamianie usług na żądanie
Comment[pl]=Demon internetowy, który uruchamia usługi sieciowe na żądanie
Comment[pt]=Um servidor da Internet que inicia os serviços de rede a pedido
Comment[pt_BR]=Um servidor Internet que inicia os serviços de rede por demanda
Comment[ro]=Un demon de Internet ce pornește serviciile de rețea la cerere
Comment[ru]=Служба установления подключения при запросе сетевых ресурсов
Comment[se]=Interneahtta-duogášprográmma mii álggaha fierpmádatbálvalusaid go dárbbašuvvo
Comment[si]=ඉල්ලුම පරිදි ජාල සේවා ආරම්භ කරන අන්තර්ජාල ඩීමනය
Comment[sk]=Internetový démon, ktorý spúšťa sieťové služby na požiadanie
Comment[sl]=Internetni strežnik, ki zažene omrežne storitve na zahtevo
Comment[sr]=Интернет демон који покреће мрежне сервисе по захтеву
Comment[sr@ijekavian]=Интернет демон који покреће мрежне сервисе по захтеву
Comment[sr@ijekavianlatin]=Internet demon koji pokreće mrežne servise po zahtevu
Comment[sr@ijekavian]=Интернет демон који покреће мрежне сервисе по захтјеву
Comment[sr@ijekavianlatin]=Internet demon koji pokreće mrežne servise po zahtjevu
Comment[sr@latin]=Internet demon koji pokreće mrežne servise po zahtevu
Comment[sv]=Internetdemon som startar nätverkstjänster vid behov
Comment[ta]=ஒரு இணைய டேமொன், டேமொன் பிணைய சேவையை ஆரம்பிக்கிறது
Comment[tg]=Азозили шабакавие, ки хидматрасони шабакавиро бо дархост сар медиҳад
Comment[th]=ดมอนอินเทอร์เน็ตซึ่งจะเริ่มทำงานบริการเครือข่ายเมื่อมีความต้องการใช้
Comment[tr]=Başlangıçta ağ servisleri tarafından istenen internet hayalet programı
Comment[tr]=Başlangıçta ağ servisleri tarafından istenen Internet hayalet programı
Comment[uk]=Фонова служба Інтернет, що запускає служби мережі при запиті
Comment[uz]=Talab qilinganda tarmoq xizmatlarini ishga tushuruvchi Internet demoni
Comment[uz@cyrillic]=Талаб қилинганда тармоқ хизматларини ишга тушурувчи Интернет демони

View File

@@ -31,168 +31,170 @@
#include <q3ptrlist.h>
#include "kserviceregistry.h"
class PortListener : public QObject {
Q_OBJECT
class PortListener : public QObject
{
Q_OBJECT
private:
bool m_valid;
QString m_serviceName;
QString m_serviceURL, m_serviceAttributes;
QStringList m_registeredServiceURLs;
QString m_dnssdName, m_dnssdType;
QMap<QString,QString> m_dnssdData;
int m_serviceLifetime;
int m_port;
int m_portBase, m_autoPortRange;
int m_defaultPortBase, m_defaultAutoPortRange;
bool m_multiInstance;
QString m_execPath;
QString m_argument;
bool m_enabled;
bool m_serviceRegistered, m_registerService;
bool m_dnssdRegister, m_dnssdRegistered;
QDateTime m_expirationTime;
QDateTime m_slpLifetimeEnd;
QString m_uuid;
bool m_valid;
QString m_serviceName;
QString m_serviceURL, m_serviceAttributes;
QStringList m_registeredServiceURLs;
QString m_dnssdName, m_dnssdType;
QMap<QString, QString> m_dnssdData;
int m_serviceLifetime;
int m_port;
int m_portBase, m_autoPortRange;
int m_defaultPortBase, m_defaultAutoPortRange;
bool m_multiInstance;
QString m_execPath;
QString m_argument;
bool m_enabled;
bool m_serviceRegistered, m_registerService;
bool m_dnssdRegister, m_dnssdRegistered;
QDateTime m_expirationTime;
QDateTime m_slpLifetimeEnd;
QString m_uuid;
KNetwork::KServerSocket *m_socket;
K3Process m_process;
KNetwork::KServerSocket *m_socket;
K3Process m_process;
KConfig *m_config;
KServiceRegistry *m_srvreg;
DNSSD::PublicService *m_dnssdreg;
KConfig *m_config;
KServiceRegistry *m_srvreg;
DNSSD::PublicService *m_dnssdreg;
void freePort();
void loadConfig(KService::Ptr s);
void setEnabledInternal(bool e, const QDateTime &ex);
void dnssdRegister(bool enabled);
void setServiceRegistrationEnabledInternal(bool enabled);
void freePort();
void loadConfig(KService::Ptr s);
void setEnabledInternal(bool e, const QDateTime &ex);
void dnssdRegister(bool enabled);
void setServiceRegistrationEnabledInternal(bool enabled);
public:
PortListener(KService::Ptr s, KConfig *c, KServiceRegistry *srvreg);
~PortListener();
PortListener(KService::Ptr s, KConfig *c, KServiceRegistry *srvreg);
~PortListener();
bool acquirePort();
bool isValid();
QString name();
void setEnabled(bool enabled);
void setEnabled(const QDateTime &expiration);
void setServiceRegistrationEnabled(bool enabled);
bool isServiceRegistrationEnabled();
QDateTime expiration();
QDateTime serviceLifetimeEnd();
bool isEnabled();
int port();
QStringList processServiceTemplate(const QString &a);
bool setPort(int port = -1, int autoProbeRange = 1);
void refreshRegistration();
bool acquirePort();
bool isValid();
QString name();
void setEnabled(bool enabled);
void setEnabled(const QDateTime &expiration);
void setServiceRegistrationEnabled(bool enabled);
bool isServiceRegistrationEnabled();
QDateTime expiration();
QDateTime serviceLifetimeEnd();
bool isEnabled();
int port();
QStringList processServiceTemplate(const QString &a);
bool setPort(int port = -1, int autoProbeRange = 1);
void refreshRegistration();
private slots:
void accepted(KSocket*);
void accepted(KSocket *);
};
class KInetD : public KDEDModule {
Q_OBJECT
class KInetD : public KDEDModule
{
Q_OBJECT
public slots:
/**
* Returns a list of all registered services in KInetd.
* To add a service you need to add a .desktop file with
* the servicetype "KInetDModule" into the services director
* (see kinetdmodule.desktop in servicetypes dir).
* @return a list with the names of all services
*/
QStringList services();
/**
* Returns a list of all registered services in KInetd.
* To add a service you need to add a .desktop file with
* the servicetype "KInetDModule" into the services director
* (see kinetdmodule.desktop in servicetypes dir).
* @return a list with the names of all services
*/
QStringList services();
/**
* Returns true if the service exists and is available.
* @param service name of a service as specified in its .desktop file
* @return true if a service with the given name exists and is enabled
*/
bool isEnabled(QString service);
/**
* Returns true if the service exists and is available.
* @param service name of a service as specified in its .desktop file
* @return true if a service with the given name exists and is enabled
*/
bool isEnabled(QString service);
/**
* Enables or disabled the given service. Ignored if the given service
* does not exist.
* @param service name of a service as specified in its .desktop file
* @param enable true to enable, false to disable.
*/
void setEnabled(QString service, bool enable);
/**
* Enables or disabled the given service. Ignored if the given service
* does not exist.
* @param service name of a service as specified in its .desktop file
* @param enable true to enable, false to disable.
*/
void setEnabled(QString service, bool enable);
/**
* Enables the given service until the given time. Ignored if the given
* service does not exist.
* @param service name of a service as specified in its .desktop file
* @param expiration the time the service will be disabled at
*/
void setEnabled(QString service, QDateTime expiration);
/**
* Enables the given service until the given time. Ignored if the given
* service does not exist.
* @param service name of a service as specified in its .desktop file
* @param expiration the time the service will be disabled at
*/
void setEnabled(QString service, QDateTime expiration);
/**
* Returns the port of the service, or -1 if not listening.
* @param service name of a service as specified in its .desktop file
* @return the port or -1 if no port used or service does not exist
*/
int port(QString service);
/**
* Returns the port of the service, or -1 if not listening.
* @param service name of a service as specified in its .desktop file
* @return the port or -1 if no port used or service does not exist
*/
int port(QString service);
/**
* Sets the port of the service, and possibly a range of ports to try.
* It will return true if a port could be found. If it did not find one
* but is enabled it will start a timer that probes that port every 30s.
* @param service name of a service as specified in its .desktop file
* @param port the first port number to try or -1 to restore defaults
* @param autoPortRange the number of ports to try
* @return true if a port could be found or service is disabled, false
* otherwise.
*/
bool setPort(QString service, int port = -1, int autoPortRange = 1);
/**
* Sets the port of the service, and possibly a range of ports to try.
* It will return true if a port could be found. If it did not find one
* but is enabled it will start a timer that probes that port every 30s.
* @param service name of a service as specified in its .desktop file
* @param port the first port number to try or -1 to restore defaults
* @param autoPortRange the number of ports to try
* @return true if a port could be found or service is disabled, false
* otherwise.
*/
bool setPort(QString service, int port = -1, int autoPortRange = 1);
/**
* Tests whether the given service is installed..
* @param service name of a service as specified in its .desktop file
* @return true if installed, false otherwise
*/
bool isInstalled(QString service);
/**
* Tests whether the given service is installed..
* @param service name of a service as specified in its .desktop file
* @return true if installed, false otherwise
*/
bool isInstalled(QString service);
/**
* Enables or disables the SLP registration. Ignored if the service does
* not have a service URL. If the service is disabled the service will
* registered as soon as it is enabled.
* @param service name of a service as specified in its .desktop file
* @param enable true to enable, false to disable.
*/
void setServiceRegistrationEnabled(QString service, bool enabled);
/**
* Enables or disables the SLP registration. Ignored if the service does
* not have a service URL. If the service is disabled the service will
* registered as soon as it is enabled.
* @param service name of a service as specified in its .desktop file
* @param enable true to enable, false to disable.
*/
void setServiceRegistrationEnabled(QString service, bool enabled);
/**
* Returns true if service registration for the given service is enabled.
* Note that this does not mean that the service is currently registered,
* because the service may be disabled.
* @param service name of a service as specified in its .desktop file
* @return true if service registration is enabled
*/
bool isServiceRegistrationEnabled(QString service);
/**
* Returns true if service registration for the given service is enabled.
* Note that this does not mean that the service is currently registered,
* because the service may be disabled.
* @param service name of a service as specified in its .desktop file
* @return true if service registration is enabled
*/
bool isServiceRegistrationEnabled(QString service);
private:
QDateTime getNextExpirationTime();
void setPortRetryTimer(bool retry);
void setReregistrationTimer();
private:
QDateTime getNextExpirationTime();
void setPortRetryTimer(bool retry);
void setReregistrationTimer();
KConfig *m_config;
KServiceRegistry *m_srvreg;
Q3PtrList<PortListener> m_portListeners;
QTimer m_expirationTimer;
QTimer m_portRetryTimer;
QTimer m_reregistrationTimer;
KConfig *m_config;
KServiceRegistry *m_srvreg;
Q3PtrList<PortListener> m_portListeners;
QTimer m_expirationTimer;
QTimer m_portRetryTimer;
QTimer m_reregistrationTimer;
private slots:
void setExpirationTimer();
void expirationTimer();
void portRetryTimer();
void reregistrationTimer();
private slots:
void setExpirationTimer();
void expirationTimer();
void portRetryTimer();
void reregistrationTimer();
public:
KInetD(QObject* parent, const QList<QVariant>&);
virtual ~KInetD();
void loadServiceList();
PortListener *getListenerByName(QString name);
public:
KInetD(QObject *parent, const QList<QVariant>&);
virtual ~KInetD();
void loadServiceList();
PortListener *getListenerByName(QString name);
};

View File

@@ -3,8 +3,10 @@ IconName=kinetd
Comment=KInetD
Comment[ar]=KInetD
Comment[ast]=KInetD
Comment[bg]=KInetD
Comment[bn]=কে-আইনেট-ডি
Comment[br]=KInetD
Comment[bs]=KInetD
Comment[ca]=KInetD
Comment[ca@valencia]=KInetD
Comment[cs]=KInetD
@@ -26,6 +28,7 @@ Comment[hi]=के-इनिट-डी
Comment[hne]=के-इनिट-डी
Comment[hr]=KInetD
Comment[hu]=KInetD
Comment[ia]=KInetD
Comment[is]=KInetD
Comment[it]=KInetD
Comment[ja]=KInetD
@@ -47,8 +50,10 @@ Comment[pt]=KInetD
Comment[pt_BR]=KInetD
Comment[ro]=KInetD
Comment[ru]=KInetD
Comment[si]=KInetD
Comment[sk]=KInetD
Comment[sl]=KInetD
Comment[sq]=KInetD
Comment[sr]=КинетД
Comment[sr@ijekavian]=КинетД
Comment[sr@ijekavianlatin]=KInetD
@@ -58,6 +63,7 @@ Comment[ta]=KInetD
Comment[tg]=KInetD
Comment[tr]=KInetD
Comment[uk]=KInetD
Comment[wa]=KInetD
Comment[xh]=KInetD
Comment[x-test]=xxKInetDxx
Comment[zh_CN]=KInetD
@@ -68,8 +74,10 @@ Comment[zh_TW]=KInetD
Name=IncomingConnection
Name[ar]=اتصال وارد
Name[ast]=Conexón entrante
Name[bg]=Входяща връзка
Name[bn]=অন্তর্মুখী সংযোগ
Name[br]=Kevreadenn resev
Name[bs]=Dolazna veza
Name[ca]=Connexió entrant
Name[ca@valencia]=Connexió entrant
Name[cs]=Příchozí spojení
@@ -91,6 +99,7 @@ Name[hi]=आवक-कनेक्शन
Name[hne]=आवक-कनेक्सन
Name[hr]=DolaznaVeza
Name[hu]=Bejövő kapcsolat
Name[ia]=Connexion in arrivata
Name[is]=IncomingConnection
Name[it]=Connessioni in entrata
Name[ja]=外部からの接続
@@ -112,6 +121,7 @@ Name[pt]=IncomingConnection
Name[pt_BR]=Conexões de entrada
Name[ro]=ConexiuneDeIntrare
Name[ru]=Входящее соединение
Name[si]=පැමිණෙන සබැඳිය
Name[sk]=Prichádzajúce pripojenie
Name[sl]=Prejeta povezava
Name[sr]=Долазна веза
@@ -133,7 +143,9 @@ Comment=Received incoming connection
Comment[af]=Ontvang inkomende verbinding
Comment[ar]=تلقي اتصال وارد
Comment[ast]=Recibida conexón entrante
Comment[bg]=Получана е входяща връзка
Comment[bn]=অন্তর্মুখী সংযোগ গ্রহণ করল
Comment[bs]=Primljena dolazeća veza
Comment[ca]=Rebuda connexió entrant
Comment[ca@valencia]=Rebuda connexió entrant
Comment[cs]=Obdrženo příchozí spojení
@@ -155,6 +167,7 @@ Comment[hi]=आवक कनेक्शन प्राप्त
Comment[hne]=आवक कनेक्सन प्राप्त
Comment[hr]=Primio dolaznu vezu
Comment[hu]=Csatlakozási kérés érkezett
Comment[ia]=Connexion in arrivata recipite
Comment[is]=Tók á móti uppkalli
Comment[it]=Ricevuta connessione in entrata
Comment[ja]=外部からの接続がありました
@@ -176,6 +189,7 @@ Comment[pt]=Foi recebida uma ligação
Comment[pt_BR]=Recebendo conexão de entrada
Comment[ro]=Conexiune de intrare recepționată
Comment[ru]=Входящее соединение завершилось успешно
Comment[si]=ලැබුනු පැමිණෙන සබැඳිය
Comment[sk]=Prijaté prichádzajúce pripojenie
Comment[sl]=Prejeta je prihajajoča povezava
Comment[sr]=Примљена је долазна веза
@@ -199,6 +213,7 @@ Name=ProcessFailed
Name[ar]=فشلت العملية
Name[ast]=Procesu fallíu
Name[bn]=প্রসেস ব্যর্থ
Name[bs]=Neuspio proces
Name[ca]=Procés erroni
Name[ca@valencia]=Procés erroni
Name[cs]=Proces selhal
@@ -220,6 +235,7 @@ Name[hi]=प्रक्रिया-असफल
Name[hne]=काम-फेल
Name[hr]=ProcesNeuspješan
Name[hu]=Hibás folyamat
Name[ia]=Processo falleva
Name[is]=ProcessFailed
Name[it]=Processo non riuscito
Name[ja]=プロセス失敗
@@ -241,11 +257,12 @@ Name[pt]=ProcessFailed
Name[pt_BR]=Falha de processo
Name[ro]=ProcesEșuat
Name[ru]=Ошибка процесса
Name[si]=සැකසුම අසාර්ථකයි
Name[sk]=Proces zlyhal
Name[sl]=Proces ni uspel
Name[sr]=Процес није успео
Name[sr@ijekavian]=Процес није успео
Name[sr@ijekavianlatin]=Proces nije uspeo
Name[sr@ijekavian]=Процес није успио
Name[sr@ijekavianlatin]=Proces nije uspio
Name[sr@latin]=Proces nije uspeo
Name[sv]=Process misslyckades
Name[ta]=செயல் தோல்வியுற்றது
@@ -263,6 +280,7 @@ Comment[af]=Kon nie roep proses na handvatsel verbinding
Comment[ar]= لا يمكن نداء الإجراء إلى مؤشر الاتصال
Comment[ast]=Nun puede llamase a un procesu pa remanar la conexón
Comment[bn]=সংযোগ পরিচালনা করতে প্রসেস শুরু করতে পারল না
Comment[bs]=Nisam mogao da pozovem proces da opsluži vezu
Comment[ca]=No es pot cridar al procés per a manejar la connexió
Comment[ca@valencia]=No es pot cridar al procés per a manejar la connexió
Comment[cs]=Nelze spustit proces k obsluze spojení
@@ -284,6 +302,7 @@ Comment[hi]=कनेक्शन हैंडल करने के लिए
Comment[hne]=कनेक्सन हेंडल करे बर काम काल नइ कर सकिस
Comment[hr]=Nisam mogao pozvati proces za kontrolu veze
Comment[hu]=A kapcsolat kezelése nem sikerült
Comment[ia]=Il non pote appellar processo pro manear connexion
Comment[is]=Gat ekki kallað á forrit til að höndla tengingu
Comment[it]=Impossibile richiamare il processo per gestire la connessione
Comment[ja]=接続を扱うプロセスを呼び出せません
@@ -304,6 +323,7 @@ Comment[pt]=Não foi possível invocar o processo para lidar com as ligações
Comment[pt_BR]=Não foi possível chamar o processo de controle da conexão
Comment[ro]=Procesul ce manipulează conexiunea nu a putut fi apelat
Comment[ru]=Не удаётся запустить процесс обработки соединения
Comment[si]=සබඳතාව හැසිරවීම සඳහා සැකසීම නොකැඳවන්න
Comment[sk]=Nepodarilo sa spustiť proces na spracovanie pripojenia
Comment[sl]=Ni možno poklicati procesa za upravljanje s povezavo
Comment[sr]=Нисам могао да позовем процес да опслужи везу

View File

@@ -9,6 +9,7 @@ Name[ast]=Triba de módulu KInetD
Name[bg]=Модул на KInetD
Name[bn]=কে-আইনেট-ডি মডিউল ধরন
Name[br]=Seurt ar mollad KInetD
Name[bs]=Vrsta modula KInetD-a
Name[ca]=Tipus de mòdul del KInetD
Name[ca@valencia]=Tipus de mòdul del KInetD
Name[cs]=Typ modulu KInetD
@@ -21,7 +22,7 @@ Name[eo]=KInetD modulotipo
Name[es]=Tipo de módulo KInetD
Name[et]=KInetD mooduli tüüp
Name[eu]=KInetD modulu mota
Name[fa]=نوع پیمانۀ KInetD
Name[fa]=نوع پیمانه KInetD
Name[fi]=KInetD-moduulityyppi
Name[fr]=Type de module de KInetD
Name[ga]=Cineál Modúil KInetD
@@ -31,6 +32,7 @@ Name[hi]=के-इनिट-डी मॉड्यूल प्रकार
Name[hne]=के-इनिट-डी माड्यूल किसम
Name[hr]=Tip KInetD Modula
Name[hu]=KInetD modultípus
Name[ia]=Typo de modulo KInetD
Name[is]=KInetD Module tegund
Name[it]=Tipo di modulo KInetD
Name[ja]=KInetD モジュールタイプ
@@ -54,6 +56,7 @@ Name[pt_BR]=Módulo KInetD
Name[ro]=Tip modul KInetD
Name[ru]=Модуль KInetD
Name[se]=KInetD-moduvlašládja
Name[si]=KInetD මොඩියුල වර්‍ගය
Name[sk]=Typ modulu KInetD
Name[sl]=Vrsta modula KInetD
Name[sr]=Врста модула КинетД‑а
@@ -63,7 +66,7 @@ Name[sr@latin]=Vrsta modula KInetDa
Name[sv]=Kinetd-modultyp
Name[ta]=KInetD கூறு வகை
Name[tg]=Навъи Модули KInetD
Name[tr]=KDED Modül Türü
Name[tr]=KInetD Modül Türü
Name[uk]=Тип модулю KinetD
Name[vi]=Kiểu môđun KInetD
Name[xh]=Udidi Lomqongo womlinganiselo we KInetD

144
krfb/CMakeLists.txt Normal file
View File

@@ -0,0 +1,144 @@
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config-krfb.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/config-krfb.h
)
#####################################
# First target: libkrfbprivate - a library
# for linking plugins against.
set (krfbprivate_SRCS
framebuffer.cpp
framebufferplugin.cpp
)
kde4_add_library (krfbprivate
SHARED
${krfbprivate_SRCS}
)
target_link_libraries (krfbprivate
${QT_QTCORE_LIBRARY}
${QT_QTGUI_LIBRARY}
${X11_X11_LIB}
)
set_target_properties (krfbprivate PROPERTIES
VERSION ${GENERIC_LIB_VERSION}
SOVERSION ${GENERIC_LIB_VERSION}
)
install (TARGETS krfbprivate
${INSTALL_TARGETS_DEFAULT_ARGS}
LIBRARY NAMELINK_SKIP
)
install (FILES
krfb-framebuffer.desktop
DESTINATION ${SERVICETYPES_INSTALL_DIR}
)
#####################################
# Second target: krfb - the app
# itself.
if(BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
add_definitions(-DKRFB_WITH_TELEPATHY_TUBES)
include_directories(${TELEPATHY_QT4_INCLUDE_DIR})
endif(BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
set (krfb_SRCS
connectiondialog.cpp
events.cpp
framebuffermanager.cpp
invitation.cpp
invitedialog.cpp
invitationmanager.cpp
main.cpp
manageinvitationsdialog.cpp
personalinvitedialog.cpp
sockethelpers.cpp
trayicon.cpp
rfbservermanager.cpp
rfbserver.cpp
rfbclient.cpp
invitationsrfbserver.cpp
invitationsrfbclient.cpp
)
if (BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
set (krfb_SRCS
${krfb_SRCS}
tubesrfbserver.cpp
tubesrfbclient.cpp
tubesclienthandler.cpp
)
endif (BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
kde4_add_kcfg_files (krfb_SRCS
krfbconfig.kcfgc
)
kde4_add_ui_files (krfb_SRCS
ui/configtcp.ui
ui/configsecurity.ui
ui/connectionwidget.ui
ui/invitewidget.ui
ui/manageinvitations.ui
ui/personalinvitewidget.ui
)
if (BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
kde4_add_ui_files(krfb_SRCS ui/tubesconnectionwidget.ui)
endif(BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
kde4_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}
)
if (BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
target_link_libraries(krfb
${TELEPATHY_QT4_LIBRARIES}
)
endif (BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
if (X11_XTest_FOUND)
target_link_libraries (krfb
${X11_XTest_LIB}
)
endif (X11_XTest_FOUND)
install (TARGETS krfb
${INSTALL_TARGETS_DEFAULT_ARGS}
)
if (BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_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 (BUILD_EXPERIMENTAL_TUBES_SUPPORT AND TELEPATHY_QT4_FOUND)
########### install files ###############
install (PROGRAMS krfb.desktop
DESTINATION ${XDG_APPS_INSTALL_DIR}
)
install (FILES krfb.notifyrc
DESTINATION ${DATA_INSTALL_DIR}/krfb
)

View File

@@ -1,2 +1,3 @@
#! /bin/sh
$EXTRACTRC ui/*.ui *.kcfg >> rc.cpp
$XGETTEXT *.cpp -o $podir/krfb.pot

88
krfb/connectiondialog.cpp Normal file
View File

@@ -0,0 +1,88 @@
/* This file is part of the KDE project
Copyright (C) 2010 Collabora Ltd <info@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
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 "connectiondialog.h"
#include <KIconLoader>
#include <KLocale>
#include <KStandardGuiItem>
#include <QtGui/QCheckBox>
#include <QtGui/QLabel>
template <typename UI>
ConnectionDialog<UI>::ConnectionDialog(QWidget *parent)
: KDialog(parent)
{
setCaption(i18n("New Connection"));
setButtons(Ok | Cancel);
setDefaultButton(Cancel);
setModal(true);
setMinimumSize(500, 200);
m_connectWidget = new QWidget(this);
m_ui.setupUi(m_connectWidget);
m_ui.pixmapLabel->setPixmap(KIcon("krfb").pixmap(128));
KGuiItem accept = KStandardGuiItem::ok();
accept.setText(i18n("Accept Connection"));
setButtonGuiItem(Ok, accept);
KGuiItem refuse = KStandardGuiItem::cancel();
refuse.setText(i18n("Refuse Connection"));
setButtonGuiItem(Cancel, refuse);
setMainWidget(m_connectWidget);
}
//**********
InvitationsConnectionDialog::InvitationsConnectionDialog(QWidget *parent)
: ConnectionDialog<Ui::ConnectionWidget>(parent)
{
}
void InvitationsConnectionDialog::setRemoteHost(const QString &host)
{
m_ui.remoteHost->setText(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"

82
krfb/connectiondialog.h Normal file
View File

@@ -0,0 +1,82 @@
/* This file is part of the KDE project
Copyright (C) 2010 Collabora Ltd <info@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
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 CONNECTIONDIALOG_H
#define CONNECTIONDIALOG_H
#include "ui_connectionwidget.h"
#include <KDialog>
template <typename UI>
class ConnectionDialog : public KDialog
{
public:
ConnectionDialog(QWidget *parent);
~ConnectionDialog() {};
void setAllowRemoteControl(bool b);
bool allowRemoteControl();
protected:
QWidget *m_connectWidget;
UI m_ui;
};
template <typename UI>
void ConnectionDialog<UI>::setAllowRemoteControl(bool b)
{
m_ui.cbAllowRemoteControl->setChecked(b);
m_ui.cbAllowRemoteControl->setVisible(b);
}
template <typename UI>
bool ConnectionDialog<UI>::allowRemoteControl()
{
return m_ui.cbAllowRemoteControl->isChecked();
}
//*********
class InvitationsConnectionDialog : public ConnectionDialog<Ui::ConnectionWidget>
{
Q_OBJECT
public:
InvitationsConnectionDialog(QWidget *parent);
void setRemoteHost(const QString & host);
};
//*********
#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

200
krfb/events.cpp Normal file
View File

@@ -0,0 +1,200 @@
/*
This file is part of the KDE project
Copyright (C) 2010 Collabora Ltd.
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2001-2003 by Tim Jansen <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.
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 "events.h"
#include <QtGui/QApplication>
#include <QtGui/QX11Info>
#include <QtGui/QDesktopWidget>
#include <KGlobal>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/extensions/XTest.h>
enum {
LEFTSHIFT = 1,
RIGHTSHIFT = 2,
ALTGR = 4
};
class EventData
{
public:
EventData();
//keyboard
Display *dpy;
signed char modifiers[0x100];
KeyCode keycodes[0x100];
KeyCode leftShiftCode;
KeyCode rightShiftCode;
KeyCode altGrCode;
char modifierState;
//mouse
int buttonMask;
private:
void init();
};
K_GLOBAL_STATIC(EventData, data)
EventData::EventData()
{
init();
}
void EventData::init()
{
dpy = QX11Info::display();
buttonMask = 0;
//initialize keycodes
KeySym key, *keymap;
int i, j, minkey, maxkey, syms_per_keycode;
memset(modifiers, -1, sizeof(modifiers));
XDisplayKeycodes(dpy, &minkey, &maxkey);
Q_ASSERT(minkey >= 8);
Q_ASSERT(maxkey < 256);
keymap = (KeySym *) XGetKeyboardMapping(dpy, minkey,
(maxkey - minkey + 1),
&syms_per_keycode);
Q_ASSERT(keymap);
for (i = minkey; i <= maxkey; i++) {
for (j = 0; j < syms_per_keycode; j++) {
key = keymap[(i-minkey)*syms_per_keycode+j];
if (key >= ' ' && key < 0x100 && i == XKeysymToKeycode(dpy, key)) {
keycodes[key] = i;
modifiers[key] = j;
}
}
}
leftShiftCode = XKeysymToKeycode(dpy, XK_Shift_L);
rightShiftCode = XKeysymToKeycode(dpy, XK_Shift_R);
altGrCode = XKeysymToKeycode(dpy, XK_Mode_switch);
XFree((char *)keymap);
}
/* this function adjusts the modifiers according to mod (as from modifiers) and data->modifierState */
static void tweakModifiers(signed char mod, bool down)
{
bool isShift = data->modifierState & (LEFTSHIFT | RIGHTSHIFT);
if (mod < 0) {
return;
}
if (isShift && mod != 1) {
if (data->modifierState & LEFTSHIFT) {
XTestFakeKeyEvent(data->dpy, data->leftShiftCode,
down, CurrentTime);
}
if (data->modifierState & RIGHTSHIFT) {
XTestFakeKeyEvent(data->dpy, data->rightShiftCode,
down, CurrentTime);
}
}
if (!isShift && mod == 1) {
XTestFakeKeyEvent(data->dpy, data->leftShiftCode,
down, CurrentTime);
}
if ((data->modifierState & ALTGR) && mod != 2) {
XTestFakeKeyEvent(data->dpy, data->altGrCode,
!down, CurrentTime);
}
if (!(data->modifierState & ALTGR) && mod == 2) {
XTestFakeKeyEvent(data->dpy, data->altGrCode,
down, CurrentTime);
}
}
void EventHandler::handleKeyboard(bool down, rfbKeySym keySym)
{
#define ADJUSTMOD(sym,state) \
if(keySym==sym) { if(down) data->modifierState|=state; else data->modifierState&=~state; }
ADJUSTMOD(XK_Shift_L, LEFTSHIFT);
ADJUSTMOD(XK_Shift_R, RIGHTSHIFT);
ADJUSTMOD(XK_Mode_switch, ALTGR);
if (keySym >= ' ' && keySym < 0x100) {
KeyCode k;
if (down) {
tweakModifiers(data->modifiers[keySym], True);
}
k = data->keycodes[keySym];
if (k != NoSymbol) {
XTestFakeKeyEvent(data->dpy, k, down, CurrentTime);
}
if (down) {
tweakModifiers(data->modifiers[keySym], False);
}
} else {
KeyCode k = XKeysymToKeycode(data->dpy, keySym);
if (k != NoSymbol) {
XTestFakeKeyEvent(data->dpy, k, down, CurrentTime);
}
}
}
void EventHandler::handlePointer(int buttonMask, int x, int y)
{
QDesktopWidget *desktopWidget = QApplication::desktop();
int screen = desktopWidget->screenNumber();
if (screen < 0) {
screen = 0;
}
XTestFakeMotionEvent(data->dpy, screen, x, y, CurrentTime);
for (int i = 0; i < 5; i++) {
if ((data->buttonMask&(1 << i)) != (buttonMask&(1 << i))) {
XTestFakeButtonEvent(data->dpy,
i + 1,
(buttonMask&(1 << i)) ? True : False,
CurrentTime);
}
}
data->buttonMask = buttonMask;
}

37
krfb/events.h Normal file
View File

@@ -0,0 +1,37 @@
/*
This file is part of the KDE project
Copyright (C) 2010 Collabora Ltd.
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2001-2003 by Tim Jansen <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.
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 EVENTS_H
#define EVENTS_H
#include "rfb.h"
class EventHandler
{
public:
static void handleKeyboard(bool down, rfbKeySym key);
static void handlePointer(int buttonMask, int x, int y);
};
#endif

View File

@@ -8,15 +8,14 @@
*/
#include "framebuffer.h"
#include "framebuffer.moc"
#include <config-krfb.h>
#include "config-krfb.h"
#include <X11/Xutil.h>
FrameBuffer::FrameBuffer(WId id, QObject *parent)
: QObject(parent), win(id)
: QObject(parent), win(id)
{
}
@@ -25,7 +24,7 @@ FrameBuffer::~FrameBuffer()
delete fb;
}
char * FrameBuffer::data()
char *FrameBuffer::data()
{
return fb;
}
@@ -69,3 +68,6 @@ void FrameBuffer::stopMonitor()
{
}
#include "framebuffer.moc"

View File

@@ -10,28 +10,29 @@
#ifndef FRAMEBUFFER_H
#define FRAMEBUFFER_H
#include <QObject>
#include <QRect>
#include <QList>
#include <QWidget>
#include "rfb.h"
#include <kdemacros.h>
#include <rfb/rfb.h>
#include <QtCore/QObject>
#include <QtCore/QRect>
#include <QtCore/QList>
#include <QtGui/QWidget>
class FrameBuffer;
/**
@author Alessandro Praduroux <pradu@pradu.it>
@author Alessandro Praduroux <pradu@pradu.it>
*/
class KDE_EXPORT FrameBuffer : public QObject
{
Q_OBJECT
Q_OBJECT
public:
explicit FrameBuffer(WId id, QObject *parent = 0);
virtual ~FrameBuffer();
char * data();
char *data();
virtual QList<QRect> modifiedTiles();
virtual int paddedWidth();

View File

@@ -64,25 +64,26 @@ void FrameBufferManager::loadPlugins()
KService::List offers = KServiceTypeTrader::self()->query("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();
for (iter = offers.constBegin(); iter < offers.constEnd(); ++iter) {
QString error;
KService::Ptr service = *iter;
KPluginFactory *factory = KPluginLoader(service->library()).factory();
if (!factory) {
kWarning() << "KPluginFactory could not load the plugin:" << service->library();
continue;
}
FrameBufferPlugin *plugin = factory->create<FrameBufferPlugin>(this);
FrameBufferPlugin *plugin = factory->create<FrameBufferPlugin>(this);
if (plugin) {
kDebug() << "Loaded plugin:" << service->name();
m_plugins.insert(service->library(), plugin);
} else {
kDebug() << error;
}
if (plugin) {
kDebug() << "Loaded plugin:" << service->name();
m_plugins.insert(service->library(), plugin);
} else {
kDebug() << error;
}
}
}
@@ -104,7 +105,8 @@ QSharedPointer<FrameBuffer> FrameBufferManager::frameBuffer(WId id)
}
// We don't already have that frame buffer.
QMap<QString, FrameBufferPlugin*>::const_iterator iter = m_plugins.constBegin();
QMap<QString, FrameBufferPlugin *>::const_iterator iter = m_plugins.constBegin();
while (iter != m_plugins.constEnd()) {
if (iter.key() == KrfbConfig::preferredFrameBufferPlugin()) {

View File

@@ -29,6 +29,7 @@
#include <QtCore/QObject>
#include <QtCore/QSharedPointer>
#include <QtCore/QWeakPointer>
#include <QtGui/QWidget>
class FrameBufferPlugin;
@@ -53,7 +54,7 @@ private:
void loadPlugins();
QMap<QString, FrameBufferPlugin*> m_plugins;
QMap<QString, FrameBufferPlugin *> m_plugins;
QMap<WId, QWeakPointer<FrameBuffer> > m_frameBuffers;
};

View File

@@ -23,7 +23,7 @@
#include "framebuffer.h"
FrameBufferPlugin::FrameBufferPlugin(QObject *parent, const QVariantList &)
: QObject(parent)
: QObject(parent)
{
}

View File

@@ -24,6 +24,7 @@
#include <kdemacros.h>
#include <QtCore/QVariantList>
#include <QtGui/QWidget>
class FrameBuffer;

View File

@@ -21,35 +21,45 @@
// 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;
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);
m_password = readableRandomString(4) + '-' + readableRandomString(3);
m_creationTime = QDateTime::currentDateTime();
m_expirationTime = QDateTime::currentDateTime().addSecs(INVITATION_DURATION);
}
Invitation::Invitation(const Invitation &x)
@@ -57,47 +67,54 @@ Invitation::Invitation(const Invitation &x)
{
}
Invitation::Invitation(const KConfigGroup &config) {
m_password = KStringHandler::obscure(config.readEntry("password", QString()));
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());
m_creationTime = config.readEntry("creation", QDateTime());
m_expirationTime = config.readEntry("expiration", QDateTime());
}
Invitation::~Invitation() {
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;
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
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;
QString Invitation::password() const
{
return m_password;
}
QDateTime Invitation::expirationTime() const {
return m_expirationTime;
QDateTime Invitation::expirationTime() const
{
return m_expirationTime;
}
QDateTime Invitation::creationTime() const {
return m_creationTime;
QDateTime Invitation::creationTime() const
{
return m_creationTime;
}
bool Invitation::isValid() const {
return m_expirationTime > QDateTime::currentDateTime();
bool Invitation::isValid() const
{
return m_expirationTime > QDateTime::currentDateTime();
}
bool Invitation::operator ==(const Invitation & ot)
bool Invitation::operator ==(const Invitation &ot)
{
return m_creationTime == ot.m_creationTime && m_password == ot.m_password;
}

View File

@@ -20,33 +20,33 @@
#include <KApplication>
#include <KConfig>
#include <QObject>
#include <QDateTime>
#include <QtCore/QDateTime>
#include <QtCore/QObject>
const int INVITATION_DURATION = 60 * 60;
const int INVITATION_DURATION = 60*60;
class Invitation {
class Invitation
{
public:
Invitation();
~Invitation();
Invitation(const KConfigGroup &config);
Invitation(const Invitation &x);
Invitation &operator= (const Invitation&x);
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;
QString password() const;
QDateTime expirationTime() const;
QDateTime creationTime() const;
bool isValid() const;
void save(KConfigGroup &config) const;
void save(KConfigGroup &config) const;
private:
QString m_password;
QDateTime m_creationTime;
QDateTime m_expirationTime;
QString m_password;
QDateTime m_creationTime;
QDateTime m_expirationTime;
};

View File

@@ -13,7 +13,7 @@
#include <KConfig>
#include <KGlobal>
#include <QTimer>
#include <QtCore/QTimer>
class InvitationManagerPrivate
{
@@ -23,7 +23,8 @@ public:
K_GLOBAL_STATIC(InvitationManagerPrivate, invitationManagerPrivate)
InvitationManager * InvitationManager::self() {
InvitationManager *InvitationManager::self()
{
return &invitationManagerPrivate->instance;
}
@@ -33,7 +34,7 @@ InvitationManager::InvitationManager()
QTimer *refreshTimer = new QTimer(this);
connect(refreshTimer, SIGNAL(timeout()), SLOT(loadInvitations()));
refreshTimer->start(1000*60);
refreshTimer->start(1000 * 60);
}
@@ -42,14 +43,16 @@ InvitationManager::~InvitationManager()
}
void InvitationManager::invalidateOldInvitations() {
void InvitationManager::invalidateOldInvitations()
{
int invNum = invitationList.size();
while(invNum--) {
while (invNum--) {
if (!invitationList[invNum].isValid()) {
invitationList.removeAt(invNum);
}
}
saveInvitations();
}
@@ -60,15 +63,17 @@ void InvitationManager::loadInvitations()
KSharedConfigPtr conf = KGlobal::config();
KConfigGroup invitationConfig(conf, "Invitations");
int numInv = invitationConfig.readEntry("invitation_num",0);
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());
}
@@ -94,11 +99,13 @@ void InvitationManager::saveInvitations()
KSharedConfigPtr conf = KGlobal::config();
KConfigGroup invitationConfig(conf, "Invitations");
int invNum = invitationList.size();
invitationConfig.writeEntry("invitation_num",invNum);
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();
}
@@ -108,7 +115,7 @@ int InvitationManager::activeInvitations()
return invitationList.size();
}
void InvitationManager::removeInvitation(const Invitation & inv)
void InvitationManager::removeInvitation(const Invitation &inv)
{
invitationList.removeAll(inv);
saveInvitations();

View File

@@ -9,19 +9,19 @@
#ifndef INVITATIONMANAGER_H
#define INVITATIONMANAGER_H
#include <QObject>
#include <QList>
#include "invitation.h"
#include <QtCore/QList>
#include <QtCore/QObject>
class InvitationManagerPrivate;
/**
@author Alessandro Praduroux <pradu@pradu.it>
@author Alessandro Praduroux <pradu@pradu.it>
*/
class InvitationManager : public QObject
{
Q_OBJECT
friend class InvitationManagerPrivate;
Q_OBJECT
friend class InvitationManagerPrivate;
public:
static InvitationManager *self();

View File

@@ -0,0 +1,112 @@
/*
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>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2001-2003 by Tim Jansen <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.
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 "invitationsrfbclient.h"
#include "invitationmanager.h"
#include "krfbconfig.h"
#include "sockethelpers.h"
#include "connectiondialog.h"
#include <KNotification>
#include <KLocale>
bool InvitationsRfbClient::checkPassword(const QByteArray & encryptedPassword)
{
bool allowUninvited = KrfbConfig::allowUninvitedConnections();
QByteArray password = KrfbConfig::uninvitedConnectionPassword().toLocal8Bit();
bool authd = false;
kDebug() << "about to start autentication";
if (allowUninvited) {
authd = vncAuthCheckPassword(password, encryptedPassword);
}
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;
}
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()) {
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));
InvitationsConnectionDialog *dialog = new InvitationsConnectionDialog(0);
dialog->setRemoteHost(host);
dialog->setAllowRemoteControl(KrfbConfig::allowDesktopControl());
connect(dialog, SIGNAL(okClicked()), SLOT(dialogAccepted()));
connect(dialog, SIGNAL(cancelClicked()), SLOT(reject()));
dialog->show();
}
}
void PendingInvitationsRfbClient::dialogAccepted()
{
InvitationsConnectionDialog *dialog = qobject_cast<InvitationsConnectionDialog *>(sender());
Q_ASSERT(dialog);
InvitationsRfbClient *client = new InvitationsRfbClient(m_rfbClient, parent());
client->setControlEnabled(dialog->allowRemoteControl());
accept(client);
}
#include "invitationsrfbclient.moc"

View File

@@ -0,0 +1,48 @@
/*
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 INVITATIONSRFBCLIENT_H
#define INVITATIONSRFBCLIENT_H
#include "rfbclient.h"
class InvitationsRfbClient : public RfbClient
{
public:
InvitationsRfbClient(rfbClientPtr client, QObject* parent = 0)
: RfbClient(client, parent) {}
protected:
virtual bool checkPassword(const QByteArray & encryptedPassword);
};
class PendingInvitationsRfbClient : public PendingRfbClient
{
Q_OBJECT
public:
PendingInvitationsRfbClient(rfbClientPtr client, QObject *parent = 0)
: PendingRfbClient(client, parent) {}
protected Q_SLOTS:
virtual void processNewClient();
private Q_SLOTS:
void dialogAccepted();
};
#endif // INVITATIONSRFBCLIENT_H

View File

@@ -0,0 +1,71 @@
/*
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>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2001-2003 by Tim Jansen <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.
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 "invitationsrfbserver.h"
#include "invitationsrfbclient.h"
#include "krfbconfig.h"
#include "rfbservermanager.h"
#include <QtCore/QTimer>
#include <QtGui/QApplication>
#include <QtNetwork/QHostInfo>
#include <KNotification>
#include <KLocale>
#include <KMessageBox>
#include <KUser>
#include <DNSSD/PublicService>
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()));
}
PendingRfbClient* InvitationsRfbServer::newClient(rfbClientPtr client)
{
return new PendingInvitationsRfbClient(client, this);
}
void InvitationsRfbServer::startAndCheck()
{
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();
}
//disconnect when qApp quits
connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(stop()));
}
}
#include "invitationsrfbserver.moc"

View File

@@ -0,0 +1,43 @@
/*
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>
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.
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 INVITATIONSRFBSERVER_H
#define INVITATIONSRFBSERVER_H
#include "rfbserver.h"
class InvitationsRfbServer : public RfbServer
{
Q_OBJECT
public:
static void init();
protected:
InvitationsRfbServer() : RfbServer(0) {}
virtual PendingRfbClient* newClient(rfbClientPtr client);
private Q_SLOTS:
void startAndCheck();
private:
Q_DISABLE_COPY(InvitationsRfbServer)
};
#endif // INVITATIONSRFBSERVER_H

87
krfb/invitedialog.cpp Normal file
View File

@@ -0,0 +1,87 @@
/* 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

@@ -28,28 +28,28 @@ class QWidget;
class InviteDialog : public KDialog, public Ui::InviteWidget
{
Q_OBJECT
Q_OBJECT
public:
InviteDialog( QWidget *parent );
public:
InviteDialog(QWidget *parent);
~InviteDialog() {}
void enableInviteButton( bool enable );
void enableInviteButton(bool enable);
public Q_SLOTS:
void setInviteCount( int count );
public Q_SLOTS:
void setInviteCount(int count);
void showWhatsthis();
signals:
signals:
void createInviteClicked();
void emailInviteClicked();
void manageInviteClicked();
void configureClicked();
protected Q_SLOTS:
protected Q_SLOTS:
void slotUser1();
protected:
protected:
QWidget *m_inviteWidget;
};

View File

@@ -4,31 +4,41 @@ X-KDE-ServiceType=krfb/framebuffer
Comment=Frame Buffer plugins for KRfb
Comment[ast]=Complementu de buffer pa KRfb
Comment[bs]=Priključci framebafera za KRfb
Comment[ca]=Connectors de «framebuffer» per al KRfb.
Comment[ca@valencia]=Connectors de «framebuffer» per al KRfb.
Comment[cs]=Moduly Frame bufferu pro KRfb
Comment[da]=Framebuffer-plugins til KRfb
Comment[de]=Framebuffer-Module für KRfb
Comment[el]=Πρόσθετα μνήμης εξόδου βίντεο καρέ για το KRfb
Comment[en_GB]=Frame Buffer plugins for KRfb
Comment[es]=Complemento de buffer para KRfb
Comment[es]=Complementos de memoria intermedia de vídeo para KRfb
Comment[et]=KRfb kaadripuhvri plugin
Comment[eu]=Irteerako bideoaren pluginak KRfb-rentzako
Comment[fi]=Kehyspuskuriliitännäinen kohteelle KRfb
Comment[fr]=Modules 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[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
Comment[it]=Estensioni del framebuffer per KRfb
Comment[ja]=KRfb
Comment[kk]=KRfb кадр буфер плагині
Comment[km]= Frame Buffer KRfb
Comment[ko]=KRfb
Comment[lt]=Frame Buffer priedai skirti KRfb
Comment[lv]=Kadru bufera sprudņi priekš KRfb
Comment[nb]=Rammebuffer-programtillegg for KRfb
Comment[nds]=Bildpuffer-Modulen för KRfb
Comment[nl]=Framebuffer-plugins voor KRfb
Comment[nn]=Framebuffer-tillegg KRfb
Comment[pa]=KRfb
Comment[pl]=Wtyczki buforów ramek dla KRfb
Comment[pt]='Plugins' de 'framebuffers' para o KRfb
Comment[pt_BR]=Plug-ins de framebuffers para o KRfb
Comment[ru]=Модуль буфера кадров для KRfb
Comment[si]=KRfb
Comment[sk]=Frame Buffer modul pre KRfb
Comment[sl]=Vstavki slikovnih medpomnilnikov za KRFB
Comment[sr]=Прикључци кадробафера за КРФБ

13
krfb.desktop → krfb/krfb.desktop Normal file → Executable file
View File

@@ -11,6 +11,7 @@ Name[ast]=Krfb
Name[bg]=Krfb
Name[bn]=---ি
Name[br]=Krfb
Name[bs]=Krfb
Name[ca]=Krfb
Name[ca@valencia]=Krfb
Name[cs]=Krfb
@@ -31,6 +32,7 @@ Name[hi]=केआरएफबी
Name[hne]=
Name[hr]=Krfb
Name[hu]=Krfb
Name[ia]=Krfb
Name[is]=Krfb
Name[it]=Krfb
Name[ja]=Krfb
@@ -51,14 +53,17 @@ Name[pt]=Krfb
Name[pt_BR]=Krfb
Name[ro]=Krfb
Name[ru]=Krfb
Name[si]=Krfb
Name[sk]=Krfb
Name[sl]=Krfb
Name[sq]=Krfb
Name[sr]=КРФБ
Name[sr@ijekavian]=КРФБ
Name[sr@ijekavianlatin]=KRFB
Name[sr@latin]=KRFB
Name[sv]=Krfb
Name[tr]=Krfb
Name[ug]=Krfb
Name[uk]=Krfb
Name[uz]=Krfb
Name[uz@cyrillic]=Krfb
@@ -66,13 +71,14 @@ Name[vi]=Krfb
Name[x-test]=xxKrfbxx
Name[zh_CN]=Krfb
Name[zh_HK]=Krfb
Name[zh_TW]=Krfb
Name[zh_TW]=_Krfb
GenericName=Desktop Sharing
GenericName[ar]=مشاركة سطح المكتب
GenericName[ast]=Escritoriu compartíu
GenericName[bg]=Споделяне на работното място
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[cs]=Sdílení pracovní plochy
@@ -95,6 +101,7 @@ GenericName[hi]=डेस्कटॉप साझेदारी
GenericName[hne]=
GenericName[hr]=Dijeljenje radne površine
GenericName[hu]=Munkaasztal-megosztás
GenericName[ia]=Compartir de scriptorio
GenericName[is]=Skjáborðsmiðlun
GenericName[it]=Condivisione del desktop
GenericName[ja]=
@@ -115,6 +122,7 @@ GenericName[pt]=Partilha do Ecrã
GenericName[pt_BR]=Compartilhamento de ambiente de trabalho
GenericName[ro]=Partajare birou
GenericName[ru]=Общий рабочий стол
GenericName[si]=
GenericName[sk]=Zdieľanie pracovnej plochy
GenericName[sl]=Deljenje namizja
GenericName[sr]=Дељење површи
@@ -124,6 +132,7 @@ GenericName[sr@latin]=Deljenje površi
GenericName[sv]=Dela ut skrivbordet
GenericName[th]=
GenericName[tr]=Masaüstü Paylaşımı
GenericName[ug]=ئۈستەلئۈستىنى ھەمبەھىرلەش
GenericName[uk]=Спільні стільниці
GenericName[uz]=Ish stoli bilan boʻlishish
GenericName[uz@cyrillic]=Иш столи билан бўлишиш

View File

@@ -4,8 +4,10 @@ Comment=Desktop Sharing
Comment[af]=Werkskerm Deeling
Comment[ar]=مشاركة سطح المكتب
Comment[ast]=Escritoriu compartíu
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[cs]=Sdílení pracovní plochy
@@ -27,6 +29,7 @@ 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]=デスクトップ共有
@@ -48,6 +51,7 @@ 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]=Deljenje namizja
Comment[sr]=Дељење површи
@@ -59,6 +63,7 @@ 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
@@ -70,6 +75,8 @@ Comment[zh_TW]=桌面分享
Name=User Accepts Connection
Name[ar]=المستخدم يقبل الاتصال
Name[ast]=L'usuariu aceuta la conexón
Name[bg]=Потребителят приема връзката
Name[bs]=Korisnik prihvata vezu
Name[ca]=L'usuari accepta la connexió
Name[ca@valencia]=L'usuari accepta la connexió
Name[cs]=Uživatel přijímá spojení
@@ -89,6 +96,7 @@ Name[hi]=उपयोक्ता ने कनेक्शन स्वीक
Name[hne]=कमइया हर कनेक्सन स्वीकारा
Name[hr]=Korisnik prihvaća vezu
Name[hu]=A felhasználó engedélyezi a csatlakozást
Name[ia]=Usator da acceptation a connexion
Name[is]=Notandi samþykkir tengingar
Name[it]=L'utente accetta la connessione
Name[ja]=ユーザが接続を許可
@@ -108,6 +116,7 @@ Name[pt]=O Utilizador Aceita a Ligação
Name[pt_BR]=O usuário aceita a conexão
Name[ro]=Utilizatorul acceptă conexiunea
Name[ru]=Пользователь принимает соединения
Name[si]=සබැඳිය පරිශීලකයා තහවුරු කරයි
Name[sk]=Užívateľ akceptuje pripojenie
Name[sl]=Uporabnik sprejel povezavo
Name[sr]=Корисник прихвата везу
@@ -125,7 +134,9 @@ Comment=User accepts connection
Comment[af]=Gebruiker aanvaar verbinding
Comment[ar]=المستخدم يقبل الاتصال
Comment[ast]=L'usuariu aceuta la conexón
Comment[bg]=Потребителят приема връзката
Comment[bn]=ব্যবহারকারী সংযোগ গ্রহণ করে
Comment[bs]=Korisnik prihvata vezu
Comment[ca]=L'usuari accepta la connexió
Comment[ca@valencia]=L'usuari accepta la connexió
Comment[cs]=Uživatel přijímá spojení
@@ -147,6 +158,7 @@ Comment[hi]=उपयोक्ता ने कनेक्शन स्वी
Comment[hne]=कमइया हर कनेक्सन स्वीकारा
Comment[hr]=Korisnik prihvaća vezu
Comment[hu]=A felhasználó engedélyezi a csatlakozást
Comment[ia]=Usator da acceptation a connexion
Comment[is]=Notandi samþykkir tengingu
Comment[it]=L'utente accetta la connessione
Comment[ja]=ユーザが接続を許可
@@ -168,6 +180,7 @@ Comment[pt]=O utilizador aceita a ligação
Comment[pt_BR]=O usuário aceita a conexão
Comment[ro]=Utilizatorul acceptă conexiunea
Comment[ru]=Пользователь принимает соединения
Comment[si]=සබැඳිය පරිශීලකයා තහවුරු කරයි
Comment[sk]=Užívateľ akceptuje pripojenie
Comment[sl]=Uporabnik sprejel povezavo
Comment[sr]=Корисник прихвата везу
@@ -191,6 +204,8 @@ Action=Popup
Name=User Refuses Connection
Name[ar]=المستخدم يرفض الاتصال
Name[ast]=L'usuariu refuga la conexón
Name[bg]=Потребителят отказва връзката
Name[bs]=Korisnik odbija vezu
Name[ca]=L'usuari refusa la connexió
Name[ca@valencia]=L'usuari refusa la connexió
Name[cs]=Uživatel odmítá spojení
@@ -210,6 +225,7 @@ Name[hi]=उपयोक्ता ने कनेक्शन अस्वी
Name[hne]=कमइया हर कनेक्सन अस्वीकारा
Name[hr]=Korisnik odbija vezu
Name[hu]=A felhasználó elutasítja a csatlakozást
Name[ia]=Usator refuta connexion
Name[is]=Notandi hafnar tengingum
Name[it]=L'utente rifiuta la connessione
Name[ja]=ユーザが接続を拒否
@@ -229,6 +245,7 @@ Name[pt]=O Utilizador Recusa a Ligação
Name[pt_BR]=O usuário rejeita a conexão
Name[ro]=Utilizatorul refuză conexiunea
Name[ru]=Пользователь отклоняет соединения
Name[si]=සබැඳිය පරිශීලකයා තහවුරු නොකරයි
Name[sk]=Užívateľ odmieta pripojenie
Name[sl]=Uporabnik zavrnil povezavo
Name[sr]=Корисник одбија везу
@@ -246,7 +263,9 @@ Comment=User refuses connection
Comment[af]=Gebruiker weier verbinding
Comment[ar]=المستخدم يرفض الاتصال
Comment[ast]=L'usuariu refuga la conexón
Comment[bg]=Потребителят отказва връзката
Comment[bn]=ব্যবহারকারী সংযোগ অস্বীকার করে
Comment[bs]=Korisnik odbija vezu
Comment[ca]=L'usuari refusa la connexió
Comment[ca@valencia]=L'usuari refusa la connexió
Comment[cs]=Uživatel odmítá spojení
@@ -268,6 +287,7 @@ Comment[hi]=उपयोक्ता ने कनेक्शन अस्व
Comment[hne]=कमइया हर कनेक्सन अस्वीकारा
Comment[hr]=Korisnik odbija vezu
Comment[hu]=A felhasználó elutasítja a csatlakozást
Comment[ia]=Usator refuta connexion
Comment[is]=Notandi hafnar tengingu
Comment[it]=L'utente rifiuta la connessione
Comment[ja]=ユーザが接続を拒否
@@ -289,6 +309,7 @@ Comment[pt]=O utilizador recusa a ligação
Comment[pt_BR]=O usuário rejeita a conexão
Comment[ro]=Utilizatorul refuză conexiunea
Comment[ru]=Пользователь отклоняет соединения
Comment[si]=සබැඳිය පරිශීලකයා තහවුරු නොකරයි
Comment[sk]=Užívateľ odmieta pripojenie
Comment[sl]=Uporabnik zavrnil povezavo
Comment[sr]=Корисник одбија везу
@@ -312,6 +333,8 @@ Action=Popup
Name=Connection Closed
Name[ar]=الاتصال أغلق
Name[ast]=Conexón zarrada
Name[bg]=Връзката е прекъсната
Name[bs]=Konekcija zatvorena
Name[ca]=Connexió tancada
Name[ca@valencia]=Connexió tancada
Name[cs]=Spojení ukončeno
@@ -331,6 +354,7 @@ Name[hi]=कनेक्शन बन्द
Name[hne]=कनेक्सन बन्द
Name[hr]=Veza prekinuta
Name[hu]=A kapcsolat megszűnt
Name[ia]=Connexion claudite
Name[is]=Tengingu lokað
Name[it]=Connessione chiusa
Name[ja]=接続切断
@@ -351,8 +375,10 @@ Name[pt]=Ligação Fechada
Name[pt_BR]=Conexão encerrada
Name[ro]=Conexiune închisă
Name[ru]=Соединение закрыто
Name[sk]=Pripojenie ukončené
Name[si]=සබඳතාව වසා දැමිනි
Name[sk]=Pripojenie bolo ukončené
Name[sl]=Povezava zaprta
Name[sq]=Lidhja u Mbyll
Name[sr]=Веза затворена
Name[sr@ijekavian]=Веза затворена
Name[sr@ijekavianlatin]=Veza zatvorena
@@ -368,8 +394,10 @@ Comment=Connection closed
Comment[af]=Verbinding gesluit
Comment[ar]=تمّ غلق الاتصال
Comment[ast]=Conexón zarrada
Comment[bg]=Връзката е прекъсната
Comment[bn]=সংযোগ বন্ধ করা হল
Comment[br]=Serret eo ar gevreadenn
Comment[bs]=Veza je zatvorena
Comment[ca]=Connexió tancada
Comment[ca@valencia]=Connexió tancada
Comment[cs]=Spojení ukončeno
@@ -391,6 +419,7 @@ Comment[hi]=कनेक्शन बन्द
Comment[hne]=कनेक्सन बन्द
Comment[hr]=Veza prekinuta
Comment[hu]=A kapcsolat megszűnt
Comment[ia]=Connexion claudite
Comment[is]=Tengingu lokað
Comment[it]=Connessione chiusa
Comment[ja]=接続が閉じられました
@@ -412,8 +441,10 @@ Comment[pt]=A ligação foi encerrada
Comment[pt_BR]=Conexão encerrada
Comment[ro]=Conexiune închisă
Comment[ru]=Соединение закрыто
Comment[sk]=Pripojenie ukončené
Comment[si]=සබඳතාව වසාදැමිනි
Comment[sk]=Pripojenie bolo ukončené
Comment[sl]=Povezava zaprta
Comment[sq]=Lidhja u mbyll
Comment[sr]=Веза је затворена
Comment[sr@ijekavian]=Веза је затворена
Comment[sr@ijekavianlatin]=Veza je zatvorena
@@ -423,6 +454,7 @@ Comment[ta]=இணைப்புகள் மூடப்பட்டது
Comment[tg]=Пайвастшавӣ пӯшида аст
Comment[th]=การเชื่อมต่อยุติ
Comment[tr]=Bağlantı kapatıldı
Comment[ug]=باغلىنىش تاقالدى
Comment[uk]=З'єднання закрито
Comment[uz]=Aloqa uzildi
Comment[uz@cyrillic]=Алоқа узилди
@@ -437,6 +469,8 @@ Action=Popup
Name=Invalid Password
Name[ar]=كلمة المرور غير صحيحة
Name[ast]=Contraseña incorreuta
Name[bg]=Неправилна парола
Name[bs]=Neispravna šifra
Name[ca]=Contrasenya no vàlida
Name[ca@valencia]=Contrasenya no vàlida
Name[cs]=Neplatné heslo
@@ -456,6 +490,7 @@ Name[hi]=अवैध पासवर्ड
Name[hne]=अवैध पासवर्ड
Name[hr]=Nevažeća zaporka
Name[hu]=Érvénytelen jelszó
Name[ia]=Contrasigno invalide
Name[is]=Ógilt lykilorð
Name[it]=Password non valida
Name[ja]=無効なパスワード
@@ -475,8 +510,10 @@ Name[pt]=Senha Inválida
Name[pt_BR]=Senha inválida
Name[ro]=Parolă nevalidă
Name[ru]=Неверный пароль
Name[si]=වැරදි මුරපදය
Name[sk]=Neplatné heslo
Name[sl]=Neveljavno geslo
Name[sq]=Fjalëkalim i Pavlefshëm
Name[sr]=Неисправна лозинка
Name[sr@ijekavian]=Неисправна лозинка
Name[sr@ijekavianlatin]=Neispravna lozinka
@@ -484,7 +521,9 @@ Name[sr@latin]=Neispravna lozinka
Name[sv]=Ogiltigt lösenord
Name[th]=รหัสผ่านไม่ถูกต้อง
Name[tr]=Geçersiz Parola
Name[ug]=ئىناۋەتسىز ئىم
Name[uk]=Неправильний пароль
Name[wa]=Sicret nén valåbe
Name[x-test]=xxInvalid Passwordxx
Name[zh_CN]=无效密码
Name[zh_TW]=不正確的密碼
@@ -492,8 +531,10 @@ Comment=Invalid password
Comment[af]=Ongeldige wagwoord
Comment[ar]=كلمة المرور غير صحيحة
Comment[ast]=Contraseña incorreuta
Comment[bg]=Неправилна парола
Comment[bn]=অবৈধ পাসওয়ার্ড
Comment[br]=Tremenger siek
Comment[bs]=Neispravna šifra
Comment[ca]=Contrasenya no vàlida
Comment[ca@valencia]=Contrasenya no vàlida
Comment[cs]=Neplatné heslo
@@ -515,6 +556,7 @@ Comment[hi]=अवैध पासवर्ड
Comment[hne]=अवैध पासवर्ड
Comment[hr]=Nevažeća šifra
Comment[hu]=Érvénytelen jelszó
Comment[ia]=Contrasigno invalide
Comment[is]=Lykilorð ógilt
Comment[it]=Password non valida
Comment[ja]=無効なパスワード
@@ -538,8 +580,10 @@ Comment[pt]=A senha é inválida
Comment[pt_BR]=Senha inválida
Comment[ro]=Parolă nevalidă
Comment[ru]=Неверный пароль
Comment[si]=වැරදි මුරපදය
Comment[sk]=Neplatné heslo
Comment[sl]=Neveljavno geslo
Comment[sq]=Fjalëkalim i pavlefshëm
Comment[sr]=Неисправна лозинка
Comment[sr@ijekavian]=Неисправна лозинка
Comment[sr@ijekavianlatin]=Neispravna lozinka
@@ -549,6 +593,7 @@ Comment[ta]=செல்லாத கடவுச்சொல்
Comment[tg]=Гузарвожаи нодуруст
Comment[th]=รหัสผ่านไม่ถูกต้อง
Comment[tr]=Geçersiz parola
Comment[ug]=ئىناۋەتسىز ئىم
Comment[uk]=Неправильний пароль
Comment[uz]=Maxfiy soʻz haqiqiy emas
Comment[uz@cyrillic]=Махфий сўз ҳақиқий эмас
@@ -564,6 +609,8 @@ Action=Popup
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
Name[ca@valencia]=Contrasenya de les invitacions no vàlides
Name[cs]=Neplatné hesla výzev
@@ -574,7 +621,7 @@ Name[en_GB]=Invalid Password Invitations
Name[eo]=Nevalidaj pasvortaj invitoj
Name[es]=Contraseñas de invitaciones incorrectas
Name[et]=Kutsutu vale parool
Name[eu]=Baliogabeko pasahitz gonbidapena
Name[eu]=Gonbitearen pasahitza baliogabea
Name[fi]=Virheellinen salasana kutsuun
Name[fr]=Invitations de mot de passe non valables
Name[ga]=Cuirí Neamhbhailí Focal Faire
@@ -583,12 +630,13 @@ Name[hi]=अवैध पासवर्ड निमंत्रण
Name[hne]=अवैध पासवर्ड निमंत्रन
Name[hr]=Pozivnice s nevažećim zaporkama
Name[hu]=Érvénytelen jelszavas meghívó
Name[ia]=Invitationes de contrasigno invalide
Name[is]=Ógild lykilorðsboð
Name[it]=Password di invito non valida
Name[ja]=招待に対する無効なパスワード
Name[kk]=Жарамсыз паролімен шақыру
Name[km]=ការ​អញ្ជើញ​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ
Name[ko]=잘못된 비밀번호 초대장
Name[ko]=잘못된 호 초대장
Name[lt]=Neteisingas kvietimo slaptažodis
Name[lv]=Nepareiza parole ar ielūgumu
Name[ml]=അസാധുവായ അടയാളവാക്ക് ക്ഷണങ്ങള്‍
@@ -602,6 +650,7 @@ Name[pt]=Convites de Senha Inválidos
Name[pt_BR]=Avisos de senha inválida
Name[ro]=Parolă nevalidă Invitații
Name[ru]=Неверный пароль приглашения
Name[si]=වැරදි මුරපද ආරාධනාවක්
Name[sk]=Neplatné heslo pozvánky
Name[sl]=Povabila z neveljavnimi gesli
Name[sr]=Неисправна лозинка позивнице
@@ -619,7 +668,9 @@ 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[bg]=Поканената страна изпрати неправилна парола. Връзката е отказана.
Comment[bn]=আমন্ত্রিত দল একটি অবৈধ পাসওয়ার্ড পাঠাল। সংযোগ অস্বীকার করা হল।
Comment[bs]=Pozvana strana je poslala pogrešnu šifru. Veza je odbijena.
Comment[ca]=La part invitada ha enviat una contrasenya no vàlida. Connexió refusada.
Comment[ca@valencia]=La part invitada ha enviat una contrasenya no vàlida. Connexió refusada.
Comment[cs]=Pozvaná strana poslala neplatné heslo. Spojení odmítnuto.
@@ -631,7 +682,7 @@ Comment[en_GB]=The invited party sent an invalid password. Connection refused.
Comment[eo]=La invitita kliento sendis nevalidan pasvorton. Konekto rifuzita.
Comment[es]=El invitado envió una contraseña incorrecta. Conexión rechazada.
Comment[et]=Kutsutu saatis vigase parooli. Ühendusest keelduti.
Comment[eu]=Gonbidatutako parekoak baliogabeko pasahitza bidali du. Konexioa ukatu da.
Comment[eu]=Gonbidatutako parekoak baliogabeko pasahitza bidali du. Konexioa ukatuta.
Comment[fi]=Kutsuttu taho lähetti virheellisen salasanan. Yhteys hylättiin.
Comment[fr]=La partie invitée a envoyé un mot de passe non valable. Connexion refusée.
Comment[ga]=Sheol an duine le cuireadh focal faire neamhbhailí. Diúltaíodh an ceangal.
@@ -641,12 +692,13 @@ Comment[hi]=निमंत्रित पार्टी ने अवैध
Comment[hne]=निमंत्रित पार्टी हर अवैध पासवर्ड भेजिस. कनेक्सन अस्वीकृत.
Comment[hr]=Stranka koju ste pozvali je poslala nevažeću šifru. Veza odbijena.
Comment[hu]=A meghívott fél érvénytelen jelszót küldött. A csatlakozási kérés elutasítva.
Comment[ia]=Le partita invitate inviava un contrasigno invalide. Connexion refusate.
Comment[is]=Boðinn aðili sendi ógilt lykilorð. Tengingu hafnað
Comment[it]=La parte invitata ha inviato una password non valida. Connessione rifiutata.
Comment[ja]=招待された人が無効なパスワードを送ってきました。接続を拒否しました。
Comment[kk]=Шқырылған жақ дұрыс емес парольді жіберді. Қосылымдан бас тартылды..
Comment[km]=ភាគី​ដែល​បាន​អញ្ជើញ បាន​ផ្ញើ​ពាក្យ​សម្ងាត់​មិន​ត្រឹមត្រូវ ។ ការ​តភ្ជាប់​ត្រូវ​បាន​បដិសេធ ។
Comment[ko]=초대한 사람이 잘못된 비밀번호를 보냈습니다. 연결이 잘못되었습니다.
Comment[ko]=초대한 사람이 잘못된 호를 보냈습니다. 연결이 잘못되었습니다.
Comment[lt]=Pakviestoji pusė atsiuntė neteisingą slaptažodį. Ryšys nutrauktas.
Comment[lv]=Ielūgtā persona nosūtīja nepareizu paroli. Savienojums noraidīts.
Comment[mk]=Поканетата страна испрати невалидна лозинка. Поврзувањето е одбиено.
@@ -660,8 +712,9 @@ Comment[pl]=Z drugiej strony podano błędne hasło. Połączenie odrzucone.
Comment[pt]=O utilizador convidado enviou uma senha inválida. A ligação foi recusada.
Comment[pt_BR]=A parte "convidada" enviou uma senha inválida. Conexão recusada.
Comment[ro]=Partea care invită a trimis o parolă nevalidă. Conexiune refuzată.
Comment[ru]=Приглашенный пользователь ввёл неверный пароль. Соединение отклонено.
Comment[sk]=Pozvaná strana poslala neplatné heslo. Pripojenie odmietnuté.
Comment[ru]=Приглашённый пользователь ввёл неправильный пароль. Соединение отклонено.
Comment[si]=ආරාධිත පාර්‍ශවය වැරදි මුරපදයක් එවන ලද බැවින් සබඳතාව ප්‍රතික්‍ෂේප විය.
Comment[sk]=Pozvaná strana poslala neplatné heslo. Pripojenie bolo odmietnuté.
Comment[sl]=Povabljena stranka je poslala neveljavno geslo. Povezava zavrnjena.
Comment[sr]=Позвана страна је послала погрешну лозинку. Веза је одбијена.
Comment[sr@ijekavian]=Позвана страна је послала погрешну лозинку. Веза је одбијена.
@@ -671,7 +724,7 @@ Comment[sv]=Den inbjudna personen skickade ett ogiltigt lösenord. Anslutning v
Comment[ta]=அழைத்த நபர் தவறான கடவுச்சொல்லை அனுப்பியுள்ளார். இணைப்பு நிராகரிக்கப்பட்டது.
Comment[tg]=Корванди дурдаст гузарвожаи нодурустро фиристод. Пайвастшавӣ манъ шудааст.
Comment[th]=ผู้เข้าร่วมการเชิญชวนส่งรหัสผ่านมาไม่ถูกต้อง ทำการปฏิเสธการเชื่อมต่อ
Comment[tr]=Davet edilenden gönderilmiş geçersiz parola. Bağlantı rededildi.
Comment[tr]=Davet edilenden gönderilmiş geçersiz parola. Bağlantı reddedildi.
Comment[uk]=Запрошений учасник надіслав некоректний пароль. У з’єднанні відмовлено.
Comment[xh]=Umhlangano omenyiweyo uthumele igama lokugqitha elisebenzayo. Uxhulumano lwa liwe.
Comment[x-test]=xxThe invited party sent an invalid password. Connection refused.xx
@@ -684,6 +737,8 @@ Action=Popup
Name=New Connection on Hold
Name[ar]=اتصال جديد على التوقف
Name[ast]=Conexón nueva a la espera
Name[bg]=Изчакване на новата връзка
Name[bs]=Nova veza je na čekanju
Name[ca]=Nova connexió en espera
Name[ca@valencia]=Nova connexió en espera
Name[cs]=Nové spojení pozdrženo
@@ -703,9 +758,10 @@ Name[hi]=नया कनेक्शन होल्ड पर रखा
Name[hne]=नवा कनेक्सन होल्ड मं रखा
Name[hr]=Nova veza na čekanju
Name[hu]=Új kapcsolat tartva
Name[ia]=Nove connexion in pausa
Name[is]=Ný tenging á bið
Name[it]=Nuova connessione in attesa
Name[ja]=保留中の新接続
Name[ja]=保留中の新しい接続
Name[kk]=Жаңа қосылым күтілуде
Name[km]=ការ​តភ្ជាប់​ថ្មី កំពុង​ស្ថិត​នៅ​ក្នុង​ការ​រង់ចាំ
Name[ko]=새 연결 대기 중
@@ -722,7 +778,8 @@ Name[pt]=Ligação Nova em Espera
Name[pt_BR]=Nova conexão ativa
Name[ro]=Conexiune nouă în așteptare
Name[ru]=Новое соединение приостановлено
Name[sk]=Nové pripojenie pozdržané
Name[si]=නව සබඳතාවක් රඳවා ඇත
Name[sk]=Nové pripojenie bolo pozdržané
Name[sl]=Nova povezava na čakanju
Name[sr]=Нова веза је на чекању
Name[sr@ijekavian]=Нова веза је на чекању
@@ -739,7 +796,9 @@ 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[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[cs]=Vyžadováno spojení, uživatel musí přijmout
@@ -751,7 +810,7 @@ Comment[en_GB]=Connection requested, user must accept
Comment[eo]=Konekto pridemandita, la uzanto devas akcepti
Comment[es]=Conexión solicitada, el usuario debe aceptarla
Comment[et]=Nõutakse ühendust, kasutaja peab seda lubama
Comment[eu]=Konexioa eskatu da, erabiltzaileak onartu behar du
Comment[eu]=Konexioa eskatuta, erabiltzaileak onartu behar du
Comment[fi]=Pyydettiin yhteyttä, käyttäjän tulee hyväksyä
Comment[fr]=Connexion demandée, l'utilisateur doit accepter
Comment[ga]=Ceangal iarrtha; ní mór don úsáideoir glacadh leis
@@ -761,6 +820,7 @@ Comment[hi]=कनेक्शन निवेदित. उपयोक्त
Comment[hne]=कनेक्सन निवेदित. कमइया ल स्वीकार होना चाही
Comment[hr]=Veza je zatražena, korisnik mora prihvatiti
Comment[hu]=Csatlakozási kérés, a felhasználónak el kell fogadnia
Comment[ia]=Connexion requirite, usator debe dar acceptation
Comment[is]=Beiðni um tengingu, notandi verður að samþykkja
Comment[it]=Connessione richiesta, l'utente deve accettare
Comment[ja]=接続が要求されています。ユーザが許可しなければなりません。
@@ -782,7 +842,8 @@ Comment[pt]=Foi pedida uma ligação que o utilizador deverá aceitar
Comment[pt_BR]=Conexão requisitada; o usuário deve aceitar
Comment[ro]=Conexiune cerută, utilizatorul trebuie să accepte
Comment[ru]=Запрос на соединение, требуется подтверждение пользователя
Comment[sk]=Vyžiadané pripojenie, užívateľ musí akceptovať
Comment[si]=සබඳතාව ඉල්ලා ඇත, පරිශීලක තහවුරු කල යුතුයි
Comment[sk]=Vyžiadané pripojenie, užívateľ ho musí akceptovať
Comment[sl]=Povezava zahtevana, uporabnik mora sprejeti
Comment[sr]=Захтевана је веза, корисник мора да је прихвати
Comment[sr@ijekavian]=Захтијевана је веза, корисник мора да је прихвати
@@ -805,6 +866,8 @@ Action=Popup
Name=New Connection Auto Accepted
Name[ar]=اتصال جديد مقبول تلقائيا
Name[ast]=Conexón nueva aceutada automáticamente
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[cs]=Nové spojení automaticky přijato
@@ -815,7 +878,7 @@ Name[en_GB]=New Connection Auto Accepted
Name[eo]=Nova konekto aŭtomate akceptita
Name[es]=Conexión nueva aceptada automáticamente
Name[et]=Uue ühendusega automaatselt nõus
Name[eu]=Konexio berria auto-onartu da
Name[eu]=Konexio berria automatikoki onartuta
Name[fi]=Uusi yhteys hyväksyttiin automaattisesti
Name[fr]=Nouvelle connexion auto-acceptée
Name[ga]=Ceangal nua bunaithe go huathoibríoch
@@ -824,9 +887,10 @@ Name[hi]=नय कनेक्शन स्वचालित स्वीक
Name[hne]=नय कनेक्सन अपने अपन स्वीकारा
Name[hr]=Nova veza automatski prihvaćena
Name[hu]=Új kapcsolat automatikusan engedélyezve
Name[ia]=Nove connexion con acceptation automatic
Name[is]=Ný tenging sjálfvirkt samþykkt
Name[it]=Nuova connessione accettata automaticamente
Name[ja]=新接続の自動受け入れ
Name[ja]=新しい接続の自動受け入れ
Name[kk]=Жаңа қосылым автоқабылданды
Name[km]=បាន​ទទួល​យក​ការ​តភ្ជាប់​ថ្មី​ដោយ​ស្វ័យ​ប្រវត្តិ
Name[ko]=새 연결 자동 수락
@@ -843,7 +907,8 @@ Name[pt]=Nova Ligação Aceite Automaticamente
Name[pt_BR]=Nova conexão com aceitação automática
Name[ro]=Conexiune nouă acceptată automat
Name[ru]=Новое соединение принимается автоматически
Name[sk]=Nové pripojenie automaticky akceptované
Name[si]=නව සබඳතාව ස්වයංක්‍රීයව පිළිගැණිනි
Name[sk]=Nové pripojenie bolo automaticky akceptované
Name[sl]=Nova povezava samodejno sprejeta
Name[sr]=Нова веза је аутоматски прихваћена
Name[sr@ijekavian]=Нова веза је аутоматски прихваћена
@@ -860,7 +925,9 @@ Comment=New connection automatically established
Comment[af]=Nuwe verbinding automaties vasgestel
Comment[ar]=اتصال جديد مفعل تلقائيا
Comment[ast]=Conexón nueva afitada automáticamente
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[cs]=Automaticky navázáno nové spojení
@@ -872,7 +939,7 @@ Comment[en_GB]=New connection automatically established
Comment[eo]=Nova konekto aŭtomate establita
Comment[es]=Conexión nueva establecida automáticamente
Comment[et]=Uus ühendus automaatselt loodud
Comment[eu]=Konexio berria automatikoki ezarri da
Comment[eu]=Konexio berria automatikoki ezarrita
Comment[fi]=Uusi yhteys muodostettiin automaattisesti
Comment[fr]=Nouvelle connexion établie automatiquement
Comment[ga]=Ceangal nua bunaithe go huathoibríoch
@@ -882,9 +949,10 @@ Comment[hi]=नया कनेक्शन स्वचलित स्था
Comment[hne]=नवा कनेक्सन अपने अपन स्थापित
Comment[hr]=Nova veza automatski prihvaćena
Comment[hu]=Automatikusan létrejött egy új kapcsolat
Comment[ia]=Nove connexion establite automaticamente
Comment[is]=Nýjar tengingar sjálfkrafa samþykktar
Comment[it]=Nuova connessione stabilita automaticamente
Comment[ja]=新接続を自動的に確立しました
Comment[ja]=新しい接続を自動的に確立しました
Comment[kk]=Жаңа қосылым автоматты түрде орнатылды
Comment[km]=បាន​បង្កើត​ការ​ត​ភ្ជាប់​ថ្មី​ដោយ​ស្វ័យ​ប្រវត្តិ
Comment[ko]=새 연결이 자동으로 성립됨
@@ -903,7 +971,8 @@ Comment[pt]=Foi estabelecida automaticamente uma nova ligação
Comment[pt_BR]=Nova conexão estabelecida automaticamente
Comment[ro]=Conexiune nouă stabilită automat
Comment[ru]=Новое соединение устанавливается автоматически
Comment[sk]=Nové pripojenie automaticky vytvorené
Comment[si]=නව සබඳතාව ස්වයංක්‍රීයව සැකසිනි
Comment[sk]=Nové pripojenie bolo automaticky nadviazané
Comment[sl]=Nova povezava samodejno vzpostavljena
Comment[sr]=Нова веза је аутоматски успостављена
Comment[sr@ijekavian]=Нова веза је аутоматски успостављена
@@ -926,6 +995,8 @@ Action=Popup
Name=Too Many Connections
Name[ar]=اتصالات عديدة
Name[ast]=Abondes conexones
Name[bg]=Твърде много връзки
Name[bs]=Previše veza
Name[ca]=Massa connexions
Name[ca@valencia]=Massa connexions
Name[cs]=Příliš mnoho spojení
@@ -945,6 +1016,7 @@ Name[hi]=बहुत सारे कनेक्शन
Name[hne]=बहुत अकन कनेक्सन
Name[hr]=Previše veza
Name[hu]=Túl sok kapcsolat
Name[ia]=Nimie connexiones
Name[is]=Of margar tengingar
Name[it]=Troppe connessioni
Name[ja]=多すぎる接続
@@ -964,6 +1036,7 @@ Name[pt]=Demasiadas Ligações
Name[pt_BR]=Conexões em excesso
Name[ro]=Prea multe conexiuni
Name[ru]=Слишком много соединений
Name[si]=වඩා වැඩි සබඳතා ගණනක්
Name[sk]=Príliš veľa pripojení
Name[sl]=Preveč povezav
Name[sr]=Исувише веза
@@ -981,8 +1054,10 @@ Comment=Busy, connection refused
Comment[af]=Besig, verbinding geweier
Comment[ar]=مشغول، الإتصال رفض
Comment[ast]=Ocupáu, conexón refugada
Comment[bg]=Заето. Връзката е отказана.
Comment[bn]=ব্যস্ত, সংযোগ অস্বীকার করল
Comment[br]=Dalc'het, kevreadenn disteuleret
Comment[bs]=Zauzeto, veza je odbijena
Comment[ca]=Ocupat, connexió refusada
Comment[ca@valencia]=Ocupat, connexió refusada
Comment[cs]=Zaneprázdněn, spojení odmítnuto
@@ -1004,6 +1079,7 @@ Comment[hi]=व्यस्त, कनेक्शन अस्वीकृत
Comment[hne]=व्यस्त, कनेक्सन अस्वीकृत
Comment[hr]=Zauzeto, veza odbijena
Comment[hu]=A csatlakozási kérés elutasítva túlterhelés miatt
Comment[ia]=Occupate, connexion refusate
Comment[is]=Uptekinn, tengingu hafnað
Comment[it]=Occupato, connessione rifiutata
Comment[ja]=ビジーです、接続を拒否しました
@@ -1025,7 +1101,8 @@ Comment[pt]=Ocupado, pelo a ligação foi recusada
Comment[pt_BR]=Ocupado; conexão recusada
Comment[ro]=Ocupat, conexiune refuzată
Comment[ru]=Занят, соединение отклонено
Comment[sk]=Zaneprázdnený, pripojenie odmietnuté
Comment[si]=කාර්‍යබහුලයි, සබඳතාව නොපිළිගැණිනි
Comment[sk]=Zaneprázdnený, pripojenie bolo odmietnuté
Comment[sl]=Zaposlen, povezava zavrnjena
Comment[sr]=Заузето, веза је одбијена
Comment[sr@ijekavian]=Заузето, веза је одбијена
@@ -1035,7 +1112,7 @@ Comment[sv]=Upptagen, anslutning vägras
Comment[ta]=வேலையில் உள்ளது, இணைப்பு நிராகரிக்கப்பட்டது
Comment[tg]=Банд, пайвастшавӣ рад гардидааст
Comment[th]=ยังไม่ว่าง ทำการปฏิเสธการเชื่อมต่อ
Comment[tr]=Meşgul, bağlantı rededildi
Comment[tr]=Meşgul, bağlantı reddedildi
Comment[uk]=Зайнято, у з’єднанні відмовлено
Comment[uz]=Band, aloqa rad etildi
Comment[uz@cyrillic]=Банд, алоқа рад этилди
@@ -1050,6 +1127,8 @@ Action=Popup
Name=Unexpected Connection
Name[ar]=الاتصال غير متوقّع
Name[ast]=Conexón inesperada
Name[bg]=Неочаквана връзка
Name[bs]=Neočekivana veza
Name[ca]=Connexió inesperada
Name[ca@valencia]=Connexió inesperada
Name[cs]=Neočekávané spojení
@@ -1069,6 +1148,7 @@ Name[hi]=अप्रत्याशित कनेक्शन
Name[hne]=अप्रत्यासित कनेक्सन
Name[hr]=Neočekivana veza
Name[hu]=Nem várt kapcsolat
Name[ia]=Connexion impreviste
Name[is]=Óvænt Tenging
Name[it]=Connessione inattesa
Name[ja]=予期しない接続
@@ -1088,8 +1168,10 @@ Name[pt]=Ligação Inesperada
Name[pt_BR]=Conexão inesperada
Name[ro]=Conexiune neașteptată
Name[ru]=Неожиданное соединение
Name[si]=බලාපොරොත්තු රහිත සබඳතාවක්
Name[sk]=Neočakávané pripojenie
Name[sl]=Nepričakovana povezava
Name[sq]=Lidhje e Papritur
Name[sr]=Неочекивана веза
Name[sr@ijekavian]=Неочекивана веза
Name[sr@ijekavianlatin]=Neočekivana veza
@@ -1097,6 +1179,7 @@ Name[sr@latin]=Neočekivana veza
Name[sv]=Oväntad anslutning
Name[th]=เกิดการเชื่อมต่อที่ไม่คาดคิด
Name[tr]=Beklenmeyen Bağlantı
Name[ug]=كۈتۈلمىگەن باغلىنىش
Name[uk]=Неочікуване з’єднання
Name[x-test]=xxUnexpected Connectionxx
Name[zh_CN]=未预料的连接
@@ -1105,7 +1188,9 @@ Comment=Received unexpected connection, abort
Comment[af]=Ontvang onverwagte verbinding, staak
Comment[ar]=استقبال اتصال غير متوقع، إنهاء
Comment[ast]=Recibióse 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[cs]=Obdrženo neočekávané spojení, přerušeno
@@ -1117,7 +1202,7 @@ Comment[en_GB]=Received unexpected connection, abort
Comment[eo]=Ricevis neatenditan konekton, ĉesi
Comment[es]=Recibida conexión inesperada, interrumpir
Comment[et]=Saadi ootamatu ühendus, loobuti
Comment[eu]=Ustegabeko konexioa jaso da, abortatzen
Comment[eu]=Ustekabeko konexioa jaso da, abortatzen
Comment[fi]=Vastaanotettiin odottamaton yhteys, lopeta
Comment[fr]=Reçu une connexion inattendue, interruption
Comment[ga]=Fuarthas ceangal gan choinne, á thobscor
@@ -1127,6 +1212,7 @@ Comment[hi]=अप्रत्याशित कनेक्शन प्रा
Comment[hne]=अप्रत्यासित कनेक्सन प्राप्त. छोड़ा
Comment[hr]=Primio sam neočekivanu vezu, prekid
Comment[hu]=Nem várt csatlakozási kérés érkezett, megszakítás
Comment[ia]=On recipeva connexion impreviste, aborta
Comment[is]=Tók á móti óvæntri tengingu, hætti
Comment[it]=Ricevuta connessione inattesa, terminata
Comment[ja]=予期しない接続を受信しました。廃棄します。
@@ -1147,6 +1233,7 @@ Comment[pt]=Foi recebida uma ligação inesperada, pelo que foi interrompida
Comment[pt_BR]=Conexão recebida inesperadamente; abortar
Comment[ro]=Conexiune neașteptată recepționată, abandonare
Comment[ru]=Получено неожиданное соединение. Отключение
Comment[si]=බලාපොරොත්තු රහිත සබඳතාවක් ලැබිනි, පිටවෙමින්
Comment[sk]=Prijaté neočakávané pripojenie, prerušené
Comment[sl]=Prejeta nepričakovana povezava, prekinjeno
Comment[sr]=Примљена је неочекивана веза, прекидам
@@ -1157,7 +1244,7 @@ Comment[sv]=Tog emot oväntad anslutning, avbryter
Comment[ta]=எதிர்பாராத இணைப்பு, நிறுத்தப்பட்டது
Comment[tg]=Пайвастшавии ғайричашмдош қабул гардид, кандашавӣ
Comment[th]=ได้รับการเชื่อมต่อมาอย่างไม่คาดคิด ทำการยกเลิก
Comment[tr]=Babul edilmiş beklenmedik bağlantı, durdur
Comment[tr]=Beklenmeyen bir bağlantı alındı, vazgeçiliyor
Comment[uk]=Отримано з’єднання, яке не очікувалось, припиняється
Comment[xh]=Ufumene uxhulumaniso olungalindelekanga, lahla
Comment[x-test]=xxReceived unexpected connection, abortxx

View File

@@ -0,0 +1,7 @@
[org.freedesktop.Telepathy.Client]
Interfaces=org.freedesktop.Telepathy.Client.Handler;
[org.freedesktop.Telepathy.Client.Handler.HandlerChannelFilter 0]
org.freedesktop.Telepathy.Channel.ChannelType s=org.freedesktop.Telepathy.Channel.Type.StreamTube
org.freedesktop.Telepathy.Channel.Type.StreamTube.Service s=rfb
org.freedesktop.Telepathy.Channel.Requested b=true

130
krfb/main.cpp Normal file
View File

@@ -0,0 +1,130 @@
/***************************************************************************
main.cpp
-------------------
begin : Sat Dec 8 03:23:02 CET 2001
copyright : (C) 2001-2003 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. *
* *
***************************************************************************/
#include "manageinvitationsdialog.h"
#include "trayicon.h"
#include "invitationsrfbserver.h"
#include <KAboutApplicationDialog>
#include <KAboutData>
#include <KAction>
#include <KApplication>
#include <KCmdLineArgs>
#include <KDebug>
#include <KLocale>
#include <KMessageBox>
#include <KNotification>
#include <QtGui/QPixmap>
#include <QtGui/qwindowdefs.h>
#ifdef KRFB_WITH_TELEPATHY_TUBES
# include "tubesclienthandler.h"
# include <TelepathyQt4/ClientRegistrar>
#endif
#include <signal.h>
#include <X11/extensions/XTest.h>
static const char description[] = I18N_NOOP("VNC-compatible server to share "
"KDE desktops");
static bool checkX11Capabilities()
{
int bp1, bp2, majorv, minorv;
Bool r = XTestQueryExtension(QX11Info::display(), &bp1, &bp2,
&majorv, &minorv);
if ((!r) || (((majorv * 1000) + minorv) < 2002)) {
KMessageBox::error(0,
i18n("Your X11 Server does not support the required XTest extension "
"version 2.2. Sharing your desktop is not possible."),
i18n("Desktop Sharing Error"));
return false;
}
return true;
}
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"
"(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"),
"george.goldberg@collabora.co.uk");
aboutData.addAuthor(ki18n("George Kiagiadakis"),
KLocalizedString(),
"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 "
"protocol design"));
KCmdLineArgs::init(argc, argv, &aboutData);
KCmdLineOptions options;
options.add("nodialog", ki18n("Do not show the invitations management dialog at startup"));
KCmdLineArgs::addCmdLineOptions(options);
KApplication app;
app.setQuitOnLastWindowClosed(false);
if (!checkX11Capabilities()) {
return 1;
}
//init the core
InvitationsRfbServer::init();
#ifdef KRFB_WITH_TELEPATHY_TUBES
Tp::ClientRegistrarPtr clientRegistrar = Tp::ClientRegistrar::create();
clientRegistrar->registerClient(Tp::AbstractClientPtr(new TubesClientHandler),
"krfb_rfb_handler");
#endif
//init the GUI
ManageInvitationsDialog invitationsDialog;
TrayIcon trayicon(&invitationsDialog);
if (app.isSessionRestored() && KMainWindow::canBeRestored(1)) {
invitationsDialog.restore(1, false);
} else if (KCmdLineArgs::parsedArgs()->isSet("dialog")) {
invitationsDialog.show();
}
sigset_t sigs;
sigemptyset(&sigs);
sigaddset(&sigs, SIGPIPE);
sigprocmask(SIG_BLOCK, &sigs, 0);
return app.exec();
}

View File

@@ -0,0 +1,253 @@
/* 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

@@ -10,15 +10,16 @@
#ifndef MANAGEINVITATIONSDIALOG_H
#define MANAGEINVITATIONSDIALOG_H
#include <KDialog>
#include "ui_manageinvitations.h"
#include <KXmlGuiWindow>
/**
@author Alessandro Praduroux <pradu@pradu.it>
@author Alessandro Praduroux <pradu@pradu.it>
*/
class ManageInvitationsDialog : public KDialog, private Ui::ManageInvitationsDialog
class ManageInvitationsDialog : public KXmlGuiWindow
{
Q_OBJECT
Q_OBJECT
public:
ManageInvitationsDialog(QWidget *parent = 0);
@@ -34,8 +35,12 @@ public Q_SLOTS:
void deleteCurrent();
void selectionChanged();
private:
protected:
virtual void readProperties(const KConfigGroup & group);
virtual void saveProperties(KConfigGroup & group);
private:
Ui::ManageInvitationsDialog m_ui;
};
#endif

View File

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

86
krfb/pendingrfbclient.cpp Normal file
View File

@@ -0,0 +1,86 @@
/*
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();
}

46
krfb/pendingrfbclient.h Normal file
View File

@@ -0,0 +1,46 @@
/*
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

@@ -0,0 +1,105 @@
/* 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 display 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

@@ -20,21 +20,23 @@
#ifndef PERSONALINVITEDIALOG_H
#define PERSONALINVITEDIALOG_H
#include <qdatetime.h>
#include <KDialog>
#include "ui_personalinvitewidget.h"
#include <KDialog>
#include <QtCore/QDateTime>
class QWidget;
class PersonalInviteDialog : public KDialog, public Ui::PersonalInviteWidget
{
Q_OBJECT
public:
PersonalInviteDialog( QWidget *parent );
PersonalInviteDialog(QWidget *parent);
virtual ~PersonalInviteDialog() {}
void setHost( const QString &host, uint port );
void setPassword( const QString &passwd );
void setExpiration( const QDateTime &expire );
void setHost(const QString &host, uint port);
void setPassword(const QString &passwd);
void setExpiration(const QDateTime &expire);
public Q_SLOTS:
void showWhatsthis(const QString &);

15
krfb/rfb.h Normal file
View File

@@ -0,0 +1,15 @@
/**
* This file should always be included instead of <rfb/rfb.h> because otherwise it's redefinition
* of TRUE and FALSE plays havoc with other things.
*/
#ifndef KRFB_RFB_H
#define KRFB_RFB_H
#include "../libvncserver/rfb/rfb.h"
#undef TRUE
#undef FALSE
#endif // Header guard

232
krfb/rfbclient.cpp Normal file
View File

@@ -0,0 +1,232 @@
/*
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>
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.
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 "rfbclient.h"
#include "connectiondialog.h"
#include "krfbconfig.h"
#include "sockethelpers.h"
#include "events.h"
#include <QtCore/QSocketNotifier>
#include <KDebug>
#include <KNotification>
#include <poll.h>
#include <strings.h> //for bzero()
struct RfbClient::Private
{
Private(rfbClientPtr client) :
controlEnabled(KrfbConfig::allowDesktopControl()),
client(client)
{}
bool controlEnabled;
rfbClientPtr client;
QSocketNotifier *notifier;
QString remoteAddressString;
};
RfbClient::RfbClient(rfbClientPtr client, QObject* parent)
: QObject(parent), d(new Private(client))
{
d->remoteAddressString = peerAddress(d->client->sock) + ":" +
QString::number(peerPort(d->client->sock));
d->notifier = new QSocketNotifier(client->sock, QSocketNotifier::Read, this);
d->notifier->setEnabled(false);
connect(d->notifier, SIGNAL(activated(int)), this, SLOT(onSocketActivated()));
}
RfbClient::~RfbClient()
{
kDebug();
delete d;
}
QString RfbClient::name() const
{
return d->remoteAddressString;
}
//static
bool RfbClient::controlCanBeEnabled()
{
return KrfbConfig::allowDesktopControl();
}
bool RfbClient::controlEnabled() const
{
return d->controlEnabled;
}
void RfbClient::setControlEnabled(bool enabled)
{
if (controlCanBeEnabled() && d->controlEnabled != enabled) {
d->controlEnabled = enabled;
Q_EMIT controlEnabledChanged(enabled);
}
}
bool RfbClient::isOnHold() const
{
return d->client->onHold ? true : false;
}
void RfbClient::setOnHold(bool onHold)
{
if (isOnHold() != onHold) {
d->client->onHold = onHold;
d->notifier->setEnabled(!onHold);
Q_EMIT holdStatusChanged(onHold);
}
}
void RfbClient::closeConnection()
{
d->notifier->setEnabled(false);
rfbCloseClient(d->client);
rfbClientConnectionGone(d->client);
}
void RfbClient::handleKeyboardEvent(bool down, rfbKeySym keySym)
{
if (d->controlEnabled) {
EventHandler::handleKeyboard(down, keySym);
}
}
void RfbClient::handleMouseEvent(int buttonMask, int x, int y)
{
if (d->controlEnabled) {
EventHandler::handlePointer(buttonMask, x, 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.
//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) {
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) {
kDebug() << "disconnected from socket signal";
d->notifier->setEnabled(false);
rfbClientConnectionGone(d->client);
break;
}
}
}
void RfbClient::update()
{
rfbUpdateClient(d->client);
//This is how we handle disconnection.
//if rfbUpdateClient() finds out that it can't write to 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) {
kDebug() << "disconnected during update";
d->notifier->setEnabled(false);
rfbClientConnectionGone(d->client);
}
}
//*************
PendingRfbClient::PendingRfbClient(rfbClientPtr client, QObject *parent)
: QObject(parent), m_rfbClient(client)
{
kDebug();
QMetaObject::invokeMethod(this, "processNewClient", Qt::QueuedConnection);
}
PendingRfbClient::~PendingRfbClient()
{
kDebug();
}
void PendingRfbClient::accept(RfbClient *newClient)
{
kDebug() << "accepted connection";
m_rfbClient->clientData = newClient;
newClient->setOnHold(false);
Q_EMIT finished(newClient);
deleteLater();
}
static void clientGoneHookNoop(rfbClientPtr cl) { Q_UNUSED(cl); }
void PendingRfbClient::reject()
{
kDebug() << "refused connection";
//override the clientGoneHook that was previously set by RfbServer
m_rfbClient->clientGoneHook = clientGoneHookNoop;
rfbCloseClient(m_rfbClient);
rfbClientConnectionGone(m_rfbClient);
Q_EMIT finished(NULL);
deleteLater();
}
#include "rfbclient.moc"

105
krfb/rfbclient.h Normal file
View File

@@ -0,0 +1,105 @@
/*
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>
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.
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 RFBCLIENT_H
#define RFBCLIENT_H
#include "rfb.h"
#include <QtCore/QObject>
class RfbClient : public QObject
{
Q_OBJECT
Q_PROPERTY(bool controlEnabled READ controlEnabled WRITE setControlEnabled NOTIFY controlEnabledChanged)
Q_PROPERTY(bool onHold READ isOnHold WRITE setOnHold NOTIFY holdStatusChanged)
public:
RfbClient(rfbClientPtr client, QObject *parent = 0);
virtual ~RfbClient();
/** Returns a name for the client, to be shown to the user */
virtual QString name() const;
static bool controlCanBeEnabled();
bool controlEnabled() const;
bool isOnHold() const;
public Q_SLOTS:
void setControlEnabled(bool enabled);
void setOnHold(bool onHold);
void closeConnection();
Q_SIGNALS:
void controlEnabledChanged(bool enabled);
void holdStatusChanged(bool onHold);
protected:
friend class RfbServer; //the following event handling methods are called by RfbServer
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();
private:
///called by RfbServerManager to send framebuffer updates
///and check for possible disconnection
void update();
friend class RfbServerManager;
struct Private;
Private *const d;
};
class PendingRfbClient : public QObject
{
Q_OBJECT
public:
PendingRfbClient(rfbClientPtr client, QObject *parent = 0);
virtual ~PendingRfbClient();
Q_SIGNALS:
void finished(RfbClient *client);
protected Q_SLOTS:
virtual void processNewClient() = 0;
void accept(RfbClient *newClient);
void reject();
protected:
rfbClientPtr m_rfbClient;
};
#endif // RFBCLIENT_H

268
krfb/rfbserver.cpp Normal file
View File

@@ -0,0 +1,268 @@
/*
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>
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.
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 "rfbserver.h"
#include "rfbservermanager.h"
#include <QtCore/QSocketNotifier>
#include <KDebug>
struct RfbServer::Private
{
QByteArray listeningAddress;
int listeningPort;
bool passwordRequired;
rfbScreenInfoPtr screen;
QSocketNotifier *notifier;
};
RfbServer::RfbServer(QObject *parent)
: QObject(parent), d(new Private)
{
d->listeningAddress = "0.0.0.0";
d->listeningPort = 0;
d->passwordRequired = true;
d->screen = NULL;
d->notifier = NULL;
RfbServerManager::instance()->registerServer(this);
}
RfbServer::~RfbServer()
{
stop();
if (d->screen) {
rfbScreenCleanup(d->screen);
}
delete d;
RfbServerManager::instance()->unregisterServer(this);
}
QByteArray RfbServer::listeningAddress() const
{
return d->listeningAddress;
}
int RfbServer::listeningPort() const
{
return d->listeningPort;
}
bool RfbServer::passwordRequired() const
{
return d->passwordRequired;
}
void RfbServer::setListeningAddress(const QByteArray& address)
{
d->listeningAddress = address;
}
void RfbServer::setListeningPort(int port)
{
d->listeningPort = port;
}
void RfbServer::setPasswordRequired(bool passwordRequired)
{
d->passwordRequired = passwordRequired;
}
bool RfbServer::start()
{
if (!d->screen) {
d->screen = RfbServerManager::instance()->newScreen();
if (!d->screen) {
return false;
}
// server hooks
d->screen->screenData = this;
d->screen->newClientHook = newClientHook;
d->screen->kbdAddEvent = keyboardHook;
d->screen->ptrAddEvent = pointerHook;
d->screen->passwordCheck = passwordCheck;
d->screen->setXCutText = clipboardHook;
} else {
//if we already have a screen, stop listening first
rfbShutdownServer(d->screen, false);
}
if (listeningAddress() != "0.0.0.0") {
strncpy(d->screen->thisHost, listeningAddress().data(), 254);
}
if (listeningPort() == 0) {
d->screen->autoPort = 1;
}
d->screen->port = listeningPort();
// Disable/Enable password checking
if (passwordRequired()) {
d->screen->authPasswdData = (void *)1;
} else {
d->screen->authPasswdData = (void *)0;
}
kDebug() << "Starting server. Listen port:" << listeningPort()
<< "Listen Address:" << listeningAddress()
<< "Password enabled:" << passwordRequired();
rfbInitServer(d->screen);
if (!rfbIsActive(d->screen)) {
kDebug() << "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()));
return true;
}
void RfbServer::stop(bool disconnectClients)
{
if (d->screen) {
rfbShutdownServer(d->screen, disconnectClients);
if (d->notifier) {
d->notifier->setEnabled(false);
d->notifier->deleteLater();
d->notifier = NULL;
}
}
}
void RfbServer::updateScreen(const QList<QRect> & modifiedTiles)
{
if (d->screen) {
QList<QRect>::const_iterator it = modifiedTiles.constBegin();
for(; it != modifiedTiles.constEnd(); ++it) {
rfbMarkRectAsModified(d->screen, it->x(), it->y(), it->right(), it->bottom());
}
}
}
/*
* Code copied from vino's bundled libvncserver:
* Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved.
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
* License: GPL v2 or later
*/
void krfb_rfbSetCursorPosition(rfbScreenInfoPtr screen, rfbClientPtr client, int x, int y)
{
rfbClientIteratorPtr iterator;
rfbClientPtr cl;
if (x == screen->cursorX || y == screen->cursorY)
return;
LOCK(screen->cursorMutex);
screen->cursorX = x;
screen->cursorY = y;
UNLOCK(screen->cursorMutex);
/* Inform all clients about this cursor movement. */
iterator = rfbGetClientIterator(screen);
while ((cl = rfbClientIteratorNext(iterator)) != NULL) {
cl->cursorWasMoved = TRUE;
}
rfbReleaseClientIterator(iterator);
/* The cursor was moved by this client, so don't send CursorPos. */
if (client) {
client->cursorWasMoved = FALSE;
}
}
void RfbServer::updateCursorPosition(const QPoint & position)
{
if (d->screen) {
krfb_rfbSetCursorPosition(d->screen, NULL, position.x(), position.y());
}
}
void RfbServer::onListenSocketActivated()
{
rfbProcessNewConnection(d->screen);
}
void RfbServer::pendingClientFinished(RfbClient *client)
{
kDebug();
if (client) {
RfbServerManager::instance()->addClient(client);
}
}
//static
rfbNewClientAction RfbServer::newClientHook(rfbClientPtr cl)
{
kDebug() << "New client";
RfbServer *server = static_cast<RfbServer*>(cl->screen->screenData);
PendingRfbClient *pendingClient = server->newClient(cl);
connect(pendingClient, SIGNAL(finished(RfbClient*)),
server, SLOT(pendingClientFinished(RfbClient*)));
cl->clientGoneHook = clientGoneHook;
return RFB_CLIENT_ON_HOLD;
}
//static
void RfbServer::clientGoneHook(rfbClientPtr cl)
{
kDebug() << "client gone";
RfbClient *client = static_cast<RfbClient*>(cl->clientData);
RfbServerManager::instance()->removeClient(client);
client->deleteLater();
}
//static
rfbBool RfbServer::passwordCheck(rfbClientPtr cl, const char *encryptedPassword, int len)
{
RfbClient *client = static_cast<RfbClient*>(cl->clientData);
return client->checkPassword(QByteArray::fromRawData(encryptedPassword, len));
}
//static
void RfbServer::keyboardHook(rfbBool down, rfbKeySym keySym, rfbClientPtr cl)
{
RfbClient *client = static_cast<RfbClient*>(cl->clientData);
client->handleKeyboardEvent(down ? true : false, keySym);
}
//static
void RfbServer::pointerHook(int bm, int x, int y, rfbClientPtr cl)
{
RfbClient *client = static_cast<RfbClient*>(cl->clientData);
client->handleMouseEvent(bm, x, y);
}
//static
void RfbServer::clipboardHook(char *str, int len, rfbClientPtr cl)
{
//TODO implement me
}
#include "rfbserver.moc"

71
krfb/rfbserver.h Normal file
View File

@@ -0,0 +1,71 @@
/*
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>
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.
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 RFBSERVER_H
#define RFBSERVER_H
#include "rfb.h"
#include "rfbclient.h"
#include <QtCore/QRect>
class RfbServer : public QObject
{
Q_OBJECT
public:
RfbServer(QObject *parent = 0);
virtual ~RfbServer();
QByteArray listeningAddress() const;
int listeningPort() const;
bool passwordRequired() const;
void setListeningAddress(const QByteArray & address);
void setListeningPort(int port);
void setPasswordRequired(bool passwordRequired);
public Q_SLOTS:
bool start();
void stop(bool disconnectClients = true);
void updateScreen(const QList<QRect> & modifiedTiles);
void updateCursorPosition(const QPoint & position);
private Q_SLOTS:
void onListenSocketActivated();
void pendingClientFinished(RfbClient *client);
protected:
virtual PendingRfbClient *newClient(rfbClientPtr client) = 0;
private:
static rfbNewClientAction newClientHook(rfbClientPtr cl);
static void clientGoneHook(rfbClientPtr cl);
static rfbBool passwordCheck(rfbClientPtr cl, const char *encryptedPassword, int len);
static void keyboardHook(rfbBool down, rfbKeySym keySym, rfbClientPtr cl);
static void pointerHook(int bm, int x, int y, rfbClientPtr cl);
static void clipboardHook(char *str, int len, rfbClientPtr cl);
Q_DISABLE_COPY(RfbServer)
struct Private;
Private *const d;
};
#endif // RFBSERVER_H

235
krfb/rfbservermanager.cpp Normal file
View File

@@ -0,0 +1,235 @@
/*
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>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2001-2003 by Tim Jansen <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.
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 "rfbservermanager.h"
#include "rfbserver.h"
#include "framebuffer.h"
#include "framebuffermanager.h"
#include "sockethelpers.h"
#include "krfbconfig.h"
#include <QtCore/QTimer>
#include <QtGui/QApplication>
#include <QtGui/QDesktopWidget>
#include <QtNetwork/QHostInfo>
#include <KGlobal>
#include <KDebug>
#include <KLocale>
#include <KUser>
#include <KNotification>
static const char *cur =
" "
" x "
" xx "
" xxx "
" xxxx "
" xxxxx "
" xxxxxx "
" xxxxxxx "
" xxxxxxxx "
" xxxxxxxxx "
" xxxxxxxxxx "
" xxxxx "
" xx xxx "
" x xxx "
" xxx "
" xxx "
" xxx "
" xxx "
" ";
static const char *mask =
"xx "
"xxx "
"xxxx "
"xxxxx "
"xxxxxx "
"xxxxxxx "
"xxxxxxxx "
"xxxxxxxxx "
"xxxxxxxxxx "
"xxxxxxxxxxx "
"xxxxxxxxxxxx "
"xxxxxxxxxx "
"xxxxxxxx "
"xxxxxxxx "
"xx xxxxx "
" xxxxx "
" xxxxx "
" xxxxx "
" xxx ";
struct RfbServerManagerStatic
{
RfbServerManager server;
};
K_GLOBAL_STATIC(RfbServerManagerStatic, s_instance)
RfbServerManager* RfbServerManager::instance()
{
return &s_instance->server;
}
struct RfbServerManager::Private
{
QSharedPointer<FrameBuffer> fb;
rfbCursorPtr myCursor;
QByteArray desktopName;
QTimer rfbUpdateTimer;
QSet<RfbServer*> servers;
QSet<RfbClient*> clients;
};
RfbServerManager::RfbServerManager()
: QObject(), d(new Private)
{
init();
}
RfbServerManager::~RfbServerManager()
{
delete d;
}
void RfbServerManager::init()
{
kDebug();
d->fb = FrameBufferManager::instance()->frameBuffer(QApplication::desktop()->winId());
d->myCursor = rfbMakeXCursor(19, 19, (char *) cur, (char *) mask);
d->myCursor->cleanup = false;
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()));
}
void RfbServerManager::updateScreens()
{
QList<QRect> rects = d->fb->modifiedTiles();
QPoint currentCursorPos = QCursor::pos();
Q_FOREACH(RfbServer *server, d->servers) {
server->updateScreen(rects);
server->updateCursorPosition(currentCursorPos);
}
//update() might disconnect some of the clients, which will synchronously
//call the removeClient() method and will change d->clients, so we need
//to copy the set here to avoid problems.
QSet<RfbClient*> clients = d->clients;
Q_FOREACH(RfbClient *client, clients) {
client->update();
}
}
void RfbServerManager::cleanup()
{
kDebug();
//copy because d->servers is going to be modified while we delete the servers
QSet<RfbServer*> servers = d->servers;
Q_FOREACH(RfbServer *server, servers) {
delete server;
}
Q_ASSERT(d->servers.isEmpty());
Q_ASSERT(d->clients.isEmpty());
d->myCursor->cleanup = true;
rfbFreeCursor(d->myCursor);
d->fb.clear();
}
void RfbServerManager::registerServer(RfbServer* server)
{
d->servers.insert(server);
}
void RfbServerManager::unregisterServer(RfbServer* server)
{
d->servers.remove(server);
}
rfbScreenInfoPtr RfbServerManager::newScreen()
{
rfbScreenInfoPtr screen = NULL;
if (!d->fb.isNull()) {
int w = d->fb->width();
int h = d->fb->height();
int depth = d->fb->depth();
int bpp = depth >> 3;
if (bpp != 1 && bpp != 2 && bpp != 4) {
bpp = 4;
}
kDebug() << "bpp: " << bpp;
rfbLogEnable(0);
screen = rfbGetScreen(0, 0, w, h, 8, 3, bpp);
screen->paddedWidthInBytes = d->fb->paddedWidth();
d->fb->getServerFormat(screen->serverFormat);
screen->frameBuffer = d->fb->data();
screen->desktopName = d->desktopName.constData();
screen->cursor = d->myCursor;
}
return screen;
}
void RfbServerManager::addClient(RfbClient* cc)
{
if (d->clients.size() == 0) {
kDebug() << "Starting framebuffer monitor";
d->fb->startMonitor();
d->rfbUpdateTimer.start(50);
}
d->clients.insert(cc);
KNotification::event("UserAcceptsConnection",
i18n("The remote user %1 is now connected.", cc->name()));
Q_EMIT clientConnected(cc);
}
void RfbServerManager::removeClient(RfbClient* cc)
{
d->clients.remove(cc);
if (d->clients.size() == 0) {
kDebug() << "Stopping framebuffer monitor";
d->fb->stopMonitor();
d->rfbUpdateTimer.stop();
}
KNotification::event("ConnectionClosed", i18n("The remote user %1 disconnected.", cc->name()));
Q_EMIT clientDisconnected(cc);
}
#include "rfbservermanager.moc"

65
krfb/rfbservermanager.h Normal file
View File

@@ -0,0 +1,65 @@
/*
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>
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.
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 RFBSERVERMANAGER_H
#define RFBSERVERMANAGER_H
#include "rfb.h"
#include <QtCore/QObject>
class RfbClient;
class RfbServerManagerStatic;
class RfbServer;
class RfbServerManager : public QObject
{
Q_OBJECT
public:
static RfbServerManager *instance();
Q_SIGNALS:
void clientConnected(RfbClient *cc);
void clientDisconnected(RfbClient *cc);
private Q_SLOTS:
void init();
void updateScreens();
void cleanup();
private:
void registerServer(RfbServer *server);
void unregisterServer(RfbServer *server);
rfbScreenInfoPtr newScreen();
void addClient(RfbClient *cc);
void removeClient(RfbClient *cc);
RfbServerManager();
virtual ~RfbServerManager();
Q_DISABLE_COPY(RfbServerManager)
friend class RfbServer;
friend class RfbServerManagerStatic;
struct Private;
Private *const d;
};
#endif // RFBSERVERMANAGER_H

106
krfb/sockethelpers.cpp Normal file
View File

@@ -0,0 +1,106 @@
/* 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>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2001-2003 by Tim Jansen <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.
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 "sockethelpers.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
QString peerAddress(int sock)
{
const int ADDR_SIZE = 50;
struct sockaddr sa;
socklen_t salen = sizeof(struct sockaddr);
if (getpeername(sock, &sa, &salen) == 0) {
if (sa.sa_family == AF_INET) {
struct sockaddr_in *si = (struct sockaddr_in *)&sa;
return QString(inet_ntoa(si->sin_addr));
}
if (sa.sa_family == AF_INET6) {
char inetbuf[ADDR_SIZE];
inet_ntop(sa.sa_family, &sa, inetbuf, ADDR_SIZE);
return QString(inetbuf);
}
return QString("not a network address");
}
return QString("unable to determine...");
}
unsigned short peerPort(int sock)
{
struct sockaddr sa;
socklen_t salen = sizeof(struct sockaddr);
if (getpeername(sock, &sa, &salen) == 0) {
struct sockaddr_in *si = (struct sockaddr_in *)&sa;
return ntohs(si->sin_port);
}
return 0;
}
QString localAddress(int sock)
{
const int ADDR_SIZE = 50;
struct sockaddr sa;
socklen_t salen = sizeof(struct sockaddr);
if (getsockname(sock, &sa, &salen) == 0) {
if (sa.sa_family == AF_INET) {
struct sockaddr_in *si = (struct sockaddr_in *)&sa;
return QString(inet_ntoa(si->sin_addr));
}
if (sa.sa_family == AF_INET6) {
char inetbuf[ADDR_SIZE];
inet_ntop(sa.sa_family, &sa, inetbuf, ADDR_SIZE);
return QString(inetbuf);
}
return QString("not a network address");
}
return QString("unable to determine...");
}
unsigned short localPort(int sock)
{
struct sockaddr sa;
socklen_t salen = sizeof(struct sockaddr);
if (getsockname(sock, &sa, &salen) == 0) {
struct sockaddr_in *si = (struct sockaddr_in *)&sa;
return ntohs(si->sin_port);
}
return 0;
}

View File

@@ -1,5 +1,8 @@
/* This file is part of the KDE project
Copyright (C) 2004 Nadeem Hasan <nhasan@kde.org>
Copyright (C) 2009 Collabora Ltd <info@collabora.co.uk>
@author George Goldberg <george.goldberg@collabora.co.uk>
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
Copyright (C) 2001-2003 by Tim Jansen <tim@tjansen.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
@@ -17,29 +20,11 @@
Boston, MA 02110-1301, USA.
*/
#ifndef CONNECTIONDIALOG_H
#define CONNECTIONDIALOG_H
#include <QtCore/QString>
#include <KDialog>
#include "ui_connectionwidget.h"
QString peerAddress(int sock);
unsigned short peerPort(int sock);
class QWidget;
class ConnectionDialog : public KDialog, public Ui::ConnectionWidget
{
Q_OBJECT
public:
ConnectionDialog( QWidget *parent );
~ConnectionDialog() {};
void setRemoteHost( const QString &host );
void setAllowRemoteControl( bool b );
bool allowRemoteControl();
protected:
QWidget *m_connectWidget;
};
#endif // CONNECTIONDIALOG_H
QString localAddress(int sock);
unsigned short localPort(int sock);

153
krfb/trayicon.cpp Normal file
View File

@@ -0,0 +1,153 @@
/*
Copyright (C) 2010 Collabora Ltd <info@collabora.co.uk>
@author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
Copyright (C) 2001-2002 Tim Jansen <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.
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 "trayicon.h"
#include "invitedialog.h"
#include "manageinvitationsdialog.h"
#include "rfbservermanager.h"
#include "rfbclient.h"
#include <KAboutApplicationDialog>
#include <KActionCollection>
#include <KDialog>
#include <KGlobal>
#include <KLocale>
#include <KMenu>
#include <KStandardAction>
#include <KDebug>
class ClientActions
{
public:
ClientActions(RfbClient *client, KMenu *menu, QAction *before);
virtual ~ClientActions();
private:
KMenu *m_menu;
QAction *m_title;
QAction *m_disconnectAction;
QAction *m_enableControlAction;
QAction *m_separator;
};
ClientActions::ClientActions(RfbClient* client, KMenu* menu, QAction* before)
: m_menu(menu)
{
m_title = m_menu->addTitle(client->name(), before);
m_disconnectAction = new KAction(i18n("Disconnect"), m_menu);
m_menu->insertAction(before, m_disconnectAction);
QObject::connect(m_disconnectAction, SIGNAL(triggered()), client, SLOT(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)));
} else {
m_enableControlAction = NULL;
}
m_separator = m_menu->insertSeparator(before);
}
ClientActions::~ClientActions()
{
kDebug();
m_menu->removeAction(m_title);
delete m_title;
m_menu->removeAction(m_disconnectAction);
delete m_disconnectAction;
if (m_enableControlAction) {
m_menu->removeAction(m_enableControlAction);
delete m_enableControlAction;
}
m_menu->removeAction(m_separator);
delete m_separator;
}
//**********
TrayIcon::TrayIcon(QWidget *mainWindow)
: KStatusNotifierItem(mainWindow)
{
setIconByPixmap(KIcon("krfb").pixmap(22, 22, KIcon::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*)));
m_aboutAction = KStandardAction::aboutApp(this, SLOT(showAbout()), actionCollection());
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()));
setStatus(KStatusNotifierItem::Active);
} else { //Nth client connected, N != 1
setToolTipTitle(i18n("Desktop Sharing - connected"));
}
m_clientActions[client] = new ClientActions(client, contextMenu(), m_aboutAction);
}
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));
setToolTipTitle(i18n("Desktop Sharing - disconnected"));
setStatus(KStatusNotifierItem::Passive);
} else if (m_clientActions.size() == 1) { //clients number dropped back to 1
RfbClient *client = m_clientActions.constBegin().key();
setToolTipTitle(i18n("Desktop Sharing - connected with %1", client->name()));
}
}
void TrayIcon::showAbout()
{
KDialog *dlg = new KAboutApplicationDialog(KGlobal::mainComponent().aboutData());
dlg->setAttribute(Qt::WA_DeleteOnClose, true);
dlg->show();
}
#include "trayicon.moc"

View File

@@ -18,44 +18,32 @@
#ifndef TRAYICON_H
#define TRAYICON_H
#include <kpassivepopup.h>
#include <KActionCollection>
#include <KStatusNotifierItem>
#include <KToggleAction>
#include <kstatusnotifieritem.h>
class KDialog;
class RfbClient;
class ClientActions;
/**
* Implements the trayicon.
* @author Tim Jansen
*/
class TrayIcon : public KStatusNotifierItem {
Q_OBJECT
class TrayIcon : public KStatusNotifierItem
{
Q_OBJECT
public:
TrayIcon(KDialog*);
~TrayIcon();
signals:
void disconnectedMessageDisplayed();
void enableDesktopControl(bool);
void quitApp();
TrayIcon(QWidget *mainWindow);
public Q_SLOTS:
void prepareQuit();
void showConnectedMessage(const QString &host);
void showDisconnectedMessage();
void setDesktopControlSetting(bool);
void showManageInvitations();
void onClientConnected(RfbClient *client);
void onClientDisconnected(RfbClient *client);
void showAbout();
private:
KAction* manageInvitationsAction;
KAction* aboutAction;
KToggleAction* enableControlAction;
bool quitting;
KAction *m_aboutAction;
QHash<RfbClient*, ClientActions*> m_clientActions;
};
#endif

View File

@@ -0,0 +1,95 @@
/* 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 "tubesclienthandler.h"
#include "tubesrfbserver.h"
#include <TelepathyQt4/ChannelClassSpecList>
#include <TelepathyQt4/Constants>
#include <TelepathyQt4/Debug>
#include <KDebug>
using namespace Tp;
static inline Tp::ChannelClassSpecList channelClassSpecList()
{
Tp::ChannelClassSpec spec = Tp::ChannelClassSpec();
spec.setChannelType(TP_QT4_IFACE_CHANNEL_TYPE_STREAM_TUBE);
spec.setTargetHandleType(Tp::HandleTypeContact);
spec.setRequested(true);
spec.setProperty(QString(TP_QT4_IFACE_CHANNEL_TYPE_STREAM_TUBE) + ".Service", QVariant("rfb"));
return Tp::ChannelClassSpecList() << spec;
}
TubesClientHandler::TubesClientHandler()
: AbstractClientHandler(channelClassSpecList())
{
kDebug();
Tp::enableDebug(false);
Tp::enableWarnings(true);
/* Registering telepathy types */
registerTypes();
}
TubesClientHandler::~TubesClientHandler()
{
kDebug();
}
bool TubesClientHandler::bypassApproval() const
{
// Don't bypass approval of channels.
return false;
}
void TubesClientHandler::handleChannels(const Tp::MethodInvocationContextPtr<> &context,
const Tp::AccountPtr &account,
const Tp::ConnectionPtr &connection,
const QList<Tp::ChannelPtr> &channels,
const QList<Tp::ChannelRequestPtr> &requestsSatisfied,
const QDateTime &userActionTime,
const Tp::AbstractClientHandler::HandlerInfo &handlerInfo)
{
kDebug();
Q_UNUSED(account);
Q_UNUSED(connection);
Q_UNUSED(requestsSatisfied);
Q_UNUSED(userActionTime);
Q_UNUSED(handlerInfo);
foreach(const Tp::ChannelPtr &channel, channels) {
kDebug() << "Incoming channel: " << channel;
QVariantMap properties = channel->immutableProperties();
if (properties[TELEPATHY_INTERFACE_CHANNEL ".ChannelType"] ==
TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAM_TUBE) {
kDebug() << "Channel is a stream tube. Handling: " << channel;
new TubesRfbServer(channel);
}
}
context->setFinished();
}

45
krfb/tubesclienthandler.h Normal file
View File

@@ -0,0 +1,45 @@
/* 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_TUBESCLIENTHANDLER_H
#define KRFB_TUBESCLIENTHANDLER_H
#include <TelepathyQt4/AbstractClientHandler>
class TubesClientHandler : public Tp::AbstractClientHandler
{
public:
TubesClientHandler();
virtual ~TubesClientHandler();
virtual bool bypassApproval() const;
virtual void handleChannels(const Tp::MethodInvocationContextPtr<> &context,
const Tp::AccountPtr &account,
const Tp::ConnectionPtr &connection,
const QList<Tp::ChannelPtr> &channels,
const QList<Tp::ChannelRequestPtr> &requestsSatisfied,
const QDateTime &userActionTime,
const Tp::AbstractClientHandler::HandlerInfo &handlerInfo);
};
#endif // Header guard

85
krfb/tubesrfbclient.cpp Normal file
View File

@@ -0,0 +1,85 @@
/*
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"

58
krfb/tubesrfbclient.h Normal file
View File

@@ -0,0 +1,58 @@
/*
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 <TelepathyQt4/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

294
krfb/tubesrfbserver.cpp Normal file
View File

@@ -0,0 +1,294 @@
/*
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 "tubesrfbserver.h"
#include "tubesrfbclient.h"
#include "sockethelpers.h"
#include <QtGui/QApplication>
#include <KDebug>
#include <KMessageBox>
#include <KLocale>
#include <TelepathyQt4/Connection>
#include <TelepathyQt4/Contact>
#include <TelepathyQt4/ContactManager>
#include <TelepathyQt4/PendingContacts>
#include <TelepathyQt4/PendingOperation>
#include <TelepathyQt4/PendingReady>
/* workaround for QtDBus bug */
struct StreamTubeAddress
{
QString address;
uint port;
};
Q_DECLARE_METATYPE(StreamTubeAddress);
//Marshall the StreamTubeAddress data into a D-Bus argument
QDBusArgument &operator<<(QDBusArgument &argument,
const StreamTubeAddress &streamTubeAddress)
{
argument.beginStructure();
argument << streamTubeAddress.address << streamTubeAddress.port;
argument.endStructure();
return argument;
}
// Retrieve the StreamTubeAddress data from the D-Bus argument
const QDBusArgument &operator>>(const QDBusArgument &argument,
StreamTubeAddress &streamTubeAddress)
{
argument.beginStructure();
argument >> streamTubeAddress.address >> streamTubeAddress.port;
argument.endStructure();
return argument;
}
//**************
struct TubesRfbServer::Private
{
Tp::ChannelPtr channel;
QHash<int, Tp::ContactPtr> contactsPerPort;
QHash<int, PendingTubesRfbClient*> clientsPerPort;
};
TubesRfbServer::TubesRfbServer(const Tp::ChannelPtr & channel, QObject *parent)
: RfbServer(parent), d(new Private)
{
kDebug() << "starting ";
/* Registering struct containing the tube address */
qDBusRegisterMetaType<StreamTubeAddress>();
d->channel = channel;
connect(d->channel->becomeReady(),
SIGNAL(finished(Tp::PendingOperation*)),
SLOT(onChannelReady(Tp::PendingOperation*)));
setListeningPort(6789);
setListeningAddress("127.0.0.1"); // Listen only on the loopback network interface
setPasswordRequired(false);
}
TubesRfbServer::~TubesRfbServer()
{
kDebug();
delete d;
}
PendingRfbClient* TubesRfbServer::newClient(rfbClientPtr client)
{
kDebug() << "new tubes client";
PendingTubesRfbClient *c = new PendingTubesRfbClient(client, this);
int port = peerPort(client->sock);
d->clientsPerPort[port] = c;
if (d->contactsPerPort.contains(port)) {
kDebug() << "already have a contact";
c->setContact(d->contactsPerPort[port]);
}
return c;
}
/************************** TP TUBES CODE ************************************/
void TubesRfbServer::close()
{
kDebug();
d->channel->requestClose();
}
void TubesRfbServer::cleanup()
{
kDebug();
d->clientsPerPort.clear();
d->contactsPerPort.clear();
stop();
deleteLater();
}
void TubesRfbServer::onChannelReady(Tp::PendingOperation *op)
{
kDebug();
if (op->isError()) {
kWarning() << "Getting channel ready faied:" << op->errorName() << op->errorMessage();
KMessageBox::error(QApplication::activeWindow(),
i18n("An error occurred sharing your desktop."),
i18n("Error"));
cleanup();
return;
}
Tp::Contacts contacts = d->channel->groupContacts();
Tp::ContactManagerPtr contactManager = d->channel->connection()->contactManager();
if (!contactManager) {
kWarning() << "Invalid Contact Manager.";
KMessageBox::error(QApplication::activeWindow(),
i18n("An unknown error occurred sharing your desktop."),
i18n("Error"));
close();
return;
}
Tp::Features features;
features << Tp::Contact::FeatureAlias;
connect(contactManager->upgradeContacts(contacts.toList(), features),
SIGNAL(finished(Tp::PendingOperation*)),
SLOT(onContactsUpgraded(Tp::PendingOperation*)));
}
void TubesRfbServer::onContactsUpgraded(Tp::PendingOperation *op)
{
kDebug();
if (op->isError()) {
kWarning() << "Upgrading contacts failed:" << op->errorName() << op->errorMessage();
KMessageBox::error(QApplication::activeWindow(),
i18n("An unknown error occurred sharing your desktop."),
i18n("Error"));
close();
return;
}
offerTube();
}
void TubesRfbServer::offerTube()
{
kDebug() << "Channel is ready!";
//start the rfb server
if (!start()) {
kWarning() << "Could not start rfb server";
KMessageBox::error(QApplication::activeWindow(),
i18n("Failed to activate the rfb server."),
i18n("Error"));
close();
return;
}
connect(d->channel.data(),
SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)),
SLOT(onChannelInvalidated(Tp::DBusProxy*, const QString&,
const QString&)));
/* Interface used to control the tube state */
Tp::Client::ChannelInterfaceTubeInterface *tubeInterface = d->channel->interface<Tp::Client::ChannelInterfaceTubeInterface>();
/* Interface used to control stream tube */
Tp::Client::ChannelTypeStreamTubeInterface *streamTubeInterface = d->channel->interface<Tp::Client::ChannelTypeStreamTubeInterface>();
if (streamTubeInterface && tubeInterface) {
kDebug() << "Offering tube";
connect(tubeInterface,
SIGNAL(TubeChannelStateChanged(uint)),
SLOT(onTubeStateChanged(uint)));
// Offer the stream tube
StreamTubeAddress streamTubeAddress;
streamTubeAddress.address = listeningAddress();
streamTubeAddress.port = listeningPort();
kDebug() << "Offering:" << streamTubeAddress.port << streamTubeAddress.address;
QDBusVariant address;
address.setVariant(qVariantFromValue(streamTubeAddress));
QDBusPendingReply<> ret = streamTubeInterface->Offer(
uint(Tp::SocketAddressTypeIPv4),
address,
uint(Tp::SocketAccessControlPort),
QVariantMap());
connect(new QDBusPendingCallWatcher(ret, this), SIGNAL(finished(QDBusPendingCallWatcher*)),
SLOT(onOfferTubeFinished(QDBusPendingCallWatcher*)));
connect(streamTubeInterface,
SIGNAL(NewRemoteConnection(uint,QDBusVariant,uint)),
SLOT(onNewRemoteConnection(uint,QDBusVariant,uint)));
}
}
void TubesRfbServer::onOfferTubeFinished(QDBusPendingCallWatcher *watcher)
{
QDBusPendingReply<void> reply = *watcher;
if (reply.isError()) {
kWarning() << "Offer tube failed:" << reply.error();
if (reply.error().name() == TELEPATHY_ERROR_NOT_AVAILABLE) {
KMessageBox::error(QApplication::activeWindow(),
i18n("An error occurred sharing your desktop. The person you are "
"trying to share your desktop with does not have the required "
"software installed to access it."),
i18n("Error"));
} else {
KMessageBox::error(QApplication::activeWindow(),
i18n("An unknown error occurred sharing your desktop."),
i18n("Error"));
}
} else {
kDebug() << "Offer Tube succeeded.";
}
}
void TubesRfbServer::onTubeStateChanged(uint state)
{
kDebug() << "Tube state changed:" << state;
}
void TubesRfbServer::onNewRemoteConnection(uint handle, QDBusVariant connectionParam, uint connectionId)
{
Q_UNUSED(connectionId);
QVariant v = connectionParam.variant();
kDebug() << "variant:" << v;
StreamTubeAddress ipv4address = qdbus_cast<StreamTubeAddress>(v);
kDebug() << "NewRemoteConnection: port:" << ipv4address.port << ipv4address.address;
Q_FOREACH(const Tp::ContactPtr & c, d->channel->groupContacts()) {
if (c->handle().value(0) == handle) {
d->contactsPerPort[ipv4address.port] = c;
if (d->clientsPerPort.contains(ipv4address.port)) {
kDebug() << "client already exists";
d->clientsPerPort[ipv4address.port]->setContact(c);
}
break;
}
}
}
void TubesRfbServer::onChannelInvalidated(Tp::DBusProxy *proxy,
const QString &errorName, const QString &errorMessage)
{
Q_UNUSED(proxy);
kDebug() << "Tube channel invalidated:" << errorName << errorMessage;
cleanup();
}
#include "tubesrfbserver.moc"

52
krfb/tubesrfbserver.h Normal file
View File

@@ -0,0 +1,52 @@
/*
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/>.
*/
#ifndef TUBESRFBSERVER_H
#define TUBESRFBSERVER_H
#include "rfbserver.h"
#include <TelepathyQt4/Channel>
class TubesRfbServer : public RfbServer
{
Q_OBJECT
public:
TubesRfbServer(const Tp::ChannelPtr & channel, QObject* parent = 0);
virtual ~TubesRfbServer();
virtual PendingRfbClient* newClient(rfbClientPtr client);
private Q_SLOTS:
void close();
void cleanup();
void onChannelReady(Tp::PendingOperation *op);
void onContactsUpgraded(Tp::PendingOperation *op);
void offerTube();
void onOfferTubeFinished(QDBusPendingCallWatcher *watcher);
void onTubeStateChanged(uint state);
void onNewRemoteConnection(uint handle, QDBusVariant connectionParam, uint connectionId);
void onChannelInvalidated(Tp::DBusProxy *proxy,
const QString &errorName,
const QString &errorMessage);
private:
struct Private;
Private *const d;
};
#endif // TUBESRFBSERVER_H

View File

@@ -12,9 +12,15 @@
</property>
<layout class="QVBoxLayout">
<item>
<widget class="QCheckBox" name="kcfg_allowUninvitedConnections">
<widget class="QCheckBox" name="kcfg_askOnConnect">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Allow uninvited connections</string>
<string>Ask before accepting connections</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
@@ -29,15 +35,9 @@
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_askOnConnect">
<property name="enabled">
<bool>false</bool>
</property>
<widget class="QCheckBox" name="kcfg_allowUninvitedConnections">
<property name="text">
<string>Ask before accepting connections</string>
</property>
<property name="checked">
<bool>true</bool>
<string>Allow uninvited connections</string>
</property>
</widget>
</item>
@@ -88,22 +88,6 @@
</customwidgets>
<resources/>
<connections>
<connection>
<sender>kcfg_allowUninvitedConnections</sender>
<signal>toggled(bool)</signal>
<receiver>kcfg_askOnConnect</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>22</x>
<y>24</y>
</hint>
<hint type="destinationlabel">
<x>29</x>
<y>80</y>
</hint>
</hints>
</connection>
<connection>
<sender>kcfg_allowUninvitedConnections</sender>
<signal>toggled(bool)</signal>

View File

@@ -0,0 +1,114 @@
<?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,322 +0,0 @@
/* This file is part of the KDE project
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
(C) 2001-2003 by Tim Jansen <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.
*/
#include "krfbserver.h"
#include "krfbserver.moc"
#include <QTcpServer>
#include <QTcpSocket>
#include <QTimer>
#include <QHostInfo>
#include <QApplication>
#include <QDesktopWidget>
#include <QPointer>
#include <KGlobal>
#include <KUser>
#include <KLocale>
#include <KDebug>
#include <KMessageBox>
#include <dnssd/publicservice.h>
#include "connectioncontroller.h"
#include "framebuffer.h"
#include "framebuffermanager.h"
#include "krfbconfig.h"
#include "invitationmanager.h"
#include <X11/Xutil.h>
#include <X11/extensions/XTest.h>
static const char* cur=
" "
" x "
" xx "
" xxx "
" xxxx "
" xxxxx "
" xxxxxx "
" xxxxxxx "
" xxxxxxxx "
" xxxxxxxxx "
" xxxxxxxxxx "
" xxxxx "
" xx xxx "
" x xxx "
" xxx "
" xxx "
" xxx "
" xxx "
" ";
static const char* mask=
"xx "
"xxx "
"xxxx "
"xxxxx "
"xxxxxx "
"xxxxxxx "
"xxxxxxxx "
"xxxxxxxxx "
"xxxxxxxxxx "
"xxxxxxxxxxx "
"xxxxxxxxxxxx "
"xxxxxxxxxx "
"xxxxxxxx "
"xxxxxxxx "
"xx xxxxx "
" xxxxx "
" xxxxx "
" xxxxx "
" xxx ";
static rfbCursorPtr myCursor;
static enum rfbNewClientAction newClientHook(struct _rfbClientRec *cl)
{
KrfbServer *server = KrfbServer::self();
return server->handleNewClient(cl);
}
static rfbBool passwordCheck(rfbClientPtr cl,
const char* encryptedPassword,
int len)
{
ConnectionController *cc = static_cast<ConnectionController *>(cl->clientData);
return cc->handleCheckPassword(cl, encryptedPassword, len);
}
static void keyboardHook(rfbBool down, rfbKeySym keySym, rfbClientPtr cl)
{
ConnectionController *cc = static_cast<ConnectionController *>(cl->clientData);
cc->handleKeyEvent(down ? true : false, keySym);
}
static void pointerHook(int bm, int x, int y, rfbClientPtr cl)
{
ConnectionController *cc = static_cast<ConnectionController *>(cl->clientData);
cc->handlePointerEvent(bm, x, y);
}
static void clipboardHook(char* str,int len, rfbClientPtr cl)
{
ConnectionController *cc = static_cast<ConnectionController *>(cl->clientData);
cc->clipboardToServer(QString::fromUtf8(str, len));
}
class KrfbServer::KrfbServerP {
public:
KrfbServerP() : screen(0), numClients(0) {};
QSharedPointer<FrameBuffer> fb;
QList< QPointer<ConnectionController> > controllers;
rfbScreenInfoPtr screen;
int numClients;
QByteArray desktopName;
QTimer rfbProcessEventTimer;
};
class KrfbServerPrivate
{
public:
KrfbServer instance;
};
K_GLOBAL_STATIC(KrfbServerPrivate, krfbServerPrivate)
KrfbServer * KrfbServer::self() {
return &krfbServerPrivate->instance;
}
KrfbServer::KrfbServer()
:d(new KrfbServerP)
{
kDebug() << "starting ";
d->fb = FrameBufferManager::instance()->frameBuffer(QApplication::desktop()->winId());
QTimer::singleShot(0, this, SLOT(startListening()));
connect(InvitationManager::self(), SIGNAL(invitationNumChanged(int)),SLOT(updatePassword()));
}
KrfbServer::~KrfbServer()
{
delete d;
}
void KrfbServer::startListening()
{
rfbScreenInfoPtr screen;
int port = KrfbConfig::port();
int w = d->fb->width();
int h = d->fb->height();
int depth = d->fb->depth();
int bpp = depth >> 3;
if (bpp != 1 && bpp != 2 && bpp != 4) bpp = 4;
kDebug() << "bpp: " << bpp;
rfbLogEnable(0);
screen = rfbGetScreen(0, 0, w, h, 8, 3, bpp);
screen->paddedWidthInBytes = d->fb->paddedWidth();
d->fb->getServerFormat(screen->serverFormat);
screen->frameBuffer = d->fb->data();
d->screen = screen;
screen->autoPort = 0;
screen->port = port;
// server hooks
screen->newClientHook = newClientHook;
screen->kbdAddEvent = keyboardHook;
screen->ptrAddEvent = pointerHook;
screen->newClientHook = newClientHook;
screen->passwordCheck = passwordCheck;
screen->setXCutText = clipboardHook;
d->desktopName = i18n("%1@%2 (shared desktop)", KUser().loginName(), QHostInfo::localHostName()).toLatin1();
screen->desktopName = d->desktopName.constData();
if (!myCursor) {
myCursor = rfbMakeXCursor(19, 19, (char*) cur, (char*) mask);
}
screen->cursor = myCursor;
// configure passwords and desktop control here
updateSettings();
rfbInitServer(screen);
if (!rfbIsActive(screen)) {
KMessageBox::error(0,i18n("Address already in use"),"krfb");
shutdown();
qApp->quit();
return;
};
if (KrfbConfig::publishService()) {
DNSSD::PublicService *service = new DNSSD::PublicService(i18n("%1@%2 (shared desktop)", KUser().loginName(), QHostInfo::localHostName()),"_rfb._tcp",port);
service->publishAsync();
}
/* Integrate the rfb event mechanism with qt's event loop.
* Call processRfbEvents() every time the qt event loop is run,
* so that it also processes and delivers rfb events and call
* shutdown() when QApplication exits to shutdown the rfb server
* before the X11 connection goes down.
*/
connect(&d->rfbProcessEventTimer, SIGNAL(timeout()), SLOT(processRfbEvents()));
connect(qApp, SIGNAL(aboutToQuit()), SLOT(shutdown()));
d->rfbProcessEventTimer.start(0);
}
void KrfbServer::processRfbEvents()
{
foreach(const QRect &r, d->fb->modifiedTiles()) {
rfbMarkRectAsModified(d->screen, r.x(), r.y(), r.right(), r.bottom());
}
rfbProcessEvents(d->screen, 100);
}
void KrfbServer::shutdown()
{
rfbShutdownServer(d->screen, true);
// framebuffer has to be deleted before X11 connection goes down
d->fb.clear();
}
void KrfbServer::enableDesktopControl(bool enable)
{
foreach (QPointer<ConnectionController> ptr, d->controllers) {
if (ptr) {
if (ptr->controlCanBeEnabled()) {
ptr->setControlEnabled(enable);
}
}
}
}
enum rfbNewClientAction KrfbServer::handleNewClient(struct _rfbClientRec * cl)
{
ConnectionController *cc = new ConnectionController(cl, this);
if (d->numClients++ == 0)
d->fb->startMonitor();
d->controllers.append(cc);
cc->setControlEnabled(KrfbConfig::allowDesktopControl());
cc->setControlCanBeEnabled(KrfbConfig::allowDesktopControl());
connect(cc, SIGNAL(sessionEstablished(QString)), SIGNAL(sessionEstablished(QString)));
connect(cc, SIGNAL(clientDisconnected(ConnectionController *)),SLOT(clientDisconnected(ConnectionController *)));
return cc->handleNewClient();
}
void KrfbServer::updateSettings()
{
enableDesktopControl(KrfbConfig::allowDesktopControl());
updatePassword();
}
void KrfbServer::updatePassword()
{
if (!d->screen) return;
QString pw = KrfbConfig::uninvitedConnectionPassword();
kDebug() << "password: " << pw << " allow " <<
KrfbConfig::allowUninvitedConnections() <<
" invitations " << InvitationManager::self()->activeInvitations() << endl;
if (pw.isEmpty() && InvitationManager::self()->activeInvitations() == 0) {
kDebug() << "no password from now on";
d->screen->authPasswdData = (void *)0;
} else {
kDebug() << "Ask for password to accept connections";
d->screen->authPasswdData = (void *)1;
}
}
bool KrfbServer::checkX11Capabilities() {
int bp1, bp2, majorv, minorv;
Bool r = XTestQueryExtension(QX11Info::display(), &bp1, &bp2,
&majorv, &minorv);
if ((!r) || (((majorv*1000)+minorv) < 2002)) {
KMessageBox::error(0,
i18n("Your X11 Server does not support the required XTest extension version 2.2. Sharing your desktop is not possible."),
i18n("Desktop Sharing Error"));
return false;
}
return true;
}
void KrfbServer::clientDisconnected(ConnectionController *cc)
{
kDebug() << "clients--: " << d->numClients;
if (!--d->numClients) {
d->fb->stopMonitor();
kDebug() << "stopMonitor: d->numClients = " << d->numClients;
}
disconnect(cc, SIGNAL(clientDisconnected(ConnectionController*)),this, SLOT(clientDisconnected(ConnectionController*)));
Q_EMIT sessionFinished();
}

View File

@@ -1,59 +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 KRFBSERVER_H
#define KRFBSERVER_H
#include <QObject>
#include <rfb/rfb.h>
class ConnectionController;
/**
This class implements the listening server for the RFB protocol.
@author Alessandro Praduroux <pradu@pradu.it>
*/
class KrfbServer : public QObject
{
Q_OBJECT
friend class KrfbServerPrivate;
public:
static KrfbServer *self();
~KrfbServer();
enum rfbNewClientAction handleNewClient(struct _rfbClientRec *cl);
bool checkX11Capabilities();
signals:
void sessionEstablished(QString);
void sessionFinished();
void desktopControlSettingChanged(bool);
public Q_SLOTS:
void startListening();
void processRfbEvents();
void shutdown();
void enableDesktopControl(bool);
void updateSettings();
void updatePassword();
void clientDisconnected(ConnectionController *);
private:
KrfbServer();
static KrfbServer *_self;
class KrfbServerP;
KrfbServerP * const d;
};
#endif

132
libvncserver/CMakeLists.txt Normal file
View File

@@ -0,0 +1,132 @@
# 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}
)

375
libvncserver/auth.c Normal file
View File

@@ -0,0 +1,375 @@
/*
* 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;
}

213
libvncserver/cargs.c Normal file
View File

@@ -0,0 +1,213 @@
/*
* 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;
}

342
libvncserver/corre.c Normal file
View File

@@ -0,0 +1,342 @@
/*
* 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;
}

756
libvncserver/cursor.c Normal file
View File

@@ -0,0 +1,756 @@
/*
* 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);
}

38
libvncserver/cutpaste.c Normal file
View File

@@ -0,0 +1,38 @@
/*
* 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);
}

436
libvncserver/d3des.c Normal file
View File

@@ -0,0 +1,436 @@
/*
* 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
**********************************************************************/

56
libvncserver/d3des.h Normal file
View File

@@ -0,0 +1,56 @@
#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

61
libvncserver/draw.c Normal file
View File

@@ -0,0 +1,61 @@
#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);
}
}

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