author | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
---|---|---|
committer | kergoth <kergoth> | 2002-01-25 22:14:26 (UTC) |
commit | 15318cad33835e4e2dc620d033e43cd930676cdd (patch) (unidiff) | |
tree | c2fa0399a2c47fda8e2cd0092c73a809d17f68eb /noncore/comm/keypebble/krfbdecoder.cpp | |
download | opie-15318cad33835e4e2dc620d033e43cd930676cdd.zip opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2 |
Initial revision
Diffstat (limited to 'noncore/comm/keypebble/krfbdecoder.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/comm/keypebble/krfbdecoder.cpp | 839 |
1 files changed, 839 insertions, 0 deletions
diff --git a/noncore/comm/keypebble/krfbdecoder.cpp b/noncore/comm/keypebble/krfbdecoder.cpp new file mode 100644 index 0000000..174dd7b --- a/dev/null +++ b/noncore/comm/keypebble/krfbdecoder.cpp | |||
@@ -0,0 +1,839 @@ | |||
1 | #include "krfbconnection.h" | ||
2 | #include "krfboptions.h" | ||
3 | #include "krfbserverinfo.h" | ||
4 | #include "krfbdecoder.h" | ||
5 | #include "krfbbuffer.h" | ||
6 | |||
7 | #include <qpe/qpeapplication.h> | ||
8 | |||
9 | #include <qpixmap.h> | ||
10 | #include <qsocket.h> | ||
11 | #include <qevent.h> | ||
12 | #include <qstring.h> | ||
13 | #include <qclipboard.h> | ||
14 | |||
15 | #include <assert.h> | ||
16 | |||
17 | // | ||
18 | // Endian stuff | ||
19 | // | ||
20 | #ifndef KDE_USE_FINAL | ||
21 | const int endianTest = 1; | ||
22 | #endif | ||
23 | |||
24 | #define Swap16IfLE(s) \ | ||
25 | (*(char *)&endianTest ? ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) : (s)) | ||
26 | |||
27 | #define Swap32IfLE(l) \ | ||
28 | (*(char *)&endianTest ? ((((l) & 0xff000000) >> 24) | \ | ||
29 | (((l) & 0x00ff0000) >> 8) | \ | ||
30 | (((l) & 0x0000ff00) << 8) | \ | ||
31 | (((l) & 0x000000ff) << 24)) : (l)) | ||
32 | |||
33 | // | ||
34 | // The lengths of the messages we need to wait for | ||
35 | // | ||
36 | const int ServerInitLength = 24; | ||
37 | const int UpdateHeaderLength = 4; | ||
38 | const int RectHeaderLength = 12; | ||
39 | const int RectChunkSize = 4; | ||
40 | const int CopyRectPosLength = 4; | ||
41 | const int ServerCutLenLength = 7; | ||
42 | |||
43 | // | ||
44 | // Client -> Server Message Identifiers | ||
45 | // | ||
46 | static CARD8 SetPixelFormatId = 0; | ||
47 | //static CARD8 FixColourMapEntriesId = 1; // Not used | ||
48 | static CARD8 SetEncodingsId = 2; | ||
49 | static CARD8 UpdateRequestId = 3; | ||
50 | static CARD8 KeyEventId = 4; | ||
51 | static CARD8 PointerEventId = 5; | ||
52 | static CARD8 ClientCutTextId = 6; | ||
53 | |||
54 | // | ||
55 | // Server -> Client Message Identifiers | ||
56 | // | ||
57 | static CARD8 UpdateId = 0; | ||
58 | static CARD8 BellId = 2; | ||
59 | static CARD8 ServerCutId = 3; | ||
60 | |||
61 | // | ||
62 | // Encoding identifiers | ||
63 | // | ||
64 | static CARD32 RawEncoding = Swap32IfLE( 0 ); | ||
65 | static CARD32 CopyRectEncoding = Swap32IfLE(1 ); | ||
66 | static CARD32 RreEncoding = Swap32IfLE( 2 ); | ||
67 | static CARD32 CorreEncoding = Swap32IfLE( 4 ); | ||
68 | static CARD32 HexTileEncoding = Swap32IfLE( 5 ); | ||
69 | |||
70 | static struct { | ||
71 | int keysym; | ||
72 | int keycode; | ||
73 | } keyMap[] = { | ||
74 | { 0xff08, Qt::Key_Backspace }, | ||
75 | { 0xff09, Qt::Key_Tab }, | ||
76 | { 0xff0d, Qt::Key_Return }, | ||
77 | { 0xff1b, Qt::Key_Escape }, | ||
78 | { 0xff63, Qt::Key_Insert }, | ||
79 | { 0xffff, Qt::Key_Delete }, | ||
80 | { 0xff50, Qt::Key_Home }, | ||
81 | { 0xff57, Qt::Key_End }, | ||
82 | { 0xff55, Qt::Key_Prior }, | ||
83 | { 0xff56, Qt::Key_Next }, | ||
84 | { 0xff51, Qt::Key_Left }, | ||
85 | { 0xff52, Qt::Key_Up }, | ||
86 | { 0xff53, Qt::Key_Right }, | ||
87 | { 0xff54, Qt::Key_Down }, | ||
88 | { 0xffbe, Qt::Key_F1 }, | ||
89 | { 0xffbf, Qt::Key_F2 }, | ||
90 | { 0xffc0, Qt::Key_F3 }, | ||
91 | { 0xffc1, Qt::Key_F4 }, | ||
92 | { 0xffc2, Qt::Key_F5 }, | ||
93 | { 0xffc3, Qt::Key_F6 }, | ||
94 | { 0xffc4, Qt::Key_F7 }, | ||
95 | { 0xffc5, Qt::Key_F8 }, | ||
96 | { 0xffc6, Qt::Key_F9 }, | ||
97 | { 0xffc7, Qt::Key_F10 }, | ||
98 | { 0xffc8, Qt::Key_F11 }, | ||
99 | { 0xffc9, Qt::Key_F12 }, | ||
100 | { 0xffe1, Qt::Key_Shift }, | ||
101 | { 0xffe2, Qt::Key_Shift }, | ||
102 | { 0xffe3, Qt::Key_Control }, | ||
103 | { 0xffe4, Qt::Key_Control }, | ||
104 | { 0xffe7, Qt::Key_Meta }, | ||
105 | { 0xffe8, Qt::Key_Meta }, | ||
106 | { 0xffe9, Qt::Key_Alt }, | ||
107 | { 0xffea, Qt::Key_Alt }, | ||
108 | { 0, 0 } | ||
109 | }; | ||
110 | |||
111 | |||
112 | KRFBDecoder::KRFBDecoder( KRFBConnection *con ) | ||
113 | : QObject( con, "RFB Decoder" ) | ||
114 | { | ||
115 | assert( con ); | ||
116 | assert( con->state() == KRFBConnection::Connected ); | ||
117 | |||
118 | this->con = con; | ||
119 | this->buf = 0; | ||
120 | this->info = 0; | ||
121 | this->format = 0; | ||
122 | this->buttonMask = 0; | ||
123 | currentState = Idle; | ||
124 | } | ||
125 | |||
126 | KRFBDecoder::~KRFBDecoder() | ||
127 | { | ||
128 | if ( info ) | ||
129 | delete info; | ||
130 | if ( format ) | ||
131 | delete format; | ||
132 | } | ||
133 | |||
134 | void KRFBDecoder::start() | ||
135 | { | ||
136 | sendClientInit(); | ||
137 | } | ||
138 | |||
139 | void KRFBDecoder::sendClientInit() | ||
140 | { | ||
141 | con->write( &( con->options()->shared ), 1 ); | ||
142 | |||
143 | // Wait for server init | ||
144 | qWarning( "Waiting for server init" ); | ||
145 | |||
146 | static QString statusMsg = tr( "Waiting for server initialisation..." ); | ||
147 | emit status( statusMsg ); | ||
148 | |||
149 | currentState = AwaitingServerInit; | ||
150 | connect( con, SIGNAL( gotEnoughData() ), SLOT( gotServerInit() ) ); | ||
151 | con->waitForData( ServerInitLength ); | ||
152 | } | ||
153 | |||
154 | void KRFBDecoder::gotServerInit() | ||
155 | { | ||
156 | qWarning( "Got server init" ); | ||
157 | disconnect( con, SIGNAL( gotEnoughData() ), this, SLOT( gotServerInit() ) ); | ||
158 | |||
159 | if ( info ) | ||
160 | delete info; | ||
161 | info = new KRFBServerInfo; | ||
162 | CHECK_PTR( info ); | ||
163 | |||
164 | con->read( &(info->width), 2 ); | ||
165 | info->width = Swap16IfLE( info->width ); | ||
166 | con->read( &info->height, 2 ); | ||
167 | info->height = Swap16IfLE( info->height ); | ||
168 | |||
169 | con->read( &(info->bpp), 1 ); | ||
170 | con->read( &(info->depth), 1 ); | ||
171 | con->read( &(info->bigEndian), 1 ); | ||
172 | con->read( &(info->trueColor), 1 ); | ||
173 | |||
174 | con->read( &(info->redMax), 2 ); | ||
175 | info->redMax = Swap16IfLE( info->redMax ); | ||
176 | con->read( &(info->greenMax), 2 ); | ||
177 | info->greenMax = Swap16IfLE( info->greenMax ); | ||
178 | con->read( &(info->blueMax), 2 ); | ||
179 | info->blueMax = Swap16IfLE( info->blueMax ); | ||
180 | |||
181 | con->read( &(info->redShift), 1 ); | ||
182 | con->read( &(info->greenShift), 1 ); | ||
183 | con->read( &(info->blueShift), 1 ); | ||
184 | |||
185 | con->read( info->padding, 3 ); | ||
186 | |||
187 | con->read( &(info->nameLength), 4 ); | ||
188 | info->nameLength = Swap32IfLE( info->nameLength ); | ||
189 | |||
190 | qWarning( "Width = %d, Height = %d", info->width, info->height ); | ||
191 | qWarning( "Bpp = %d, Depth = %d, Big = %d, True = %d", | ||
192 | info->bpp, info->depth, info->bigEndian, info->trueColor ); | ||
193 | qWarning( "RedMax = %d, GreenMax = %d, BlueMax = %d", | ||
194 | info->redMax, info->greenMax, info->blueMax ); | ||
195 | qWarning( "RedShift = %d, GreenShift = %d, BlueShift = %d", | ||
196 | info->redShift, info->greenShift,info-> blueShift ); | ||
197 | |||
198 | buf->resize( info->width, info->height ); | ||
199 | |||
200 | // Wait for desktop name | ||
201 | qWarning( "Waiting for desktop name" ); | ||
202 | |||
203 | static QString statusMsg = tr( "Waiting for desktop name..." ); | ||
204 | emit status( statusMsg ); | ||
205 | |||
206 | currentState = AwaitingDesktopName; | ||
207 | connect( con, SIGNAL( gotEnoughData() ), SLOT( gotDesktopName() ) ); | ||
208 | con->waitForData( info->nameLength ); | ||
209 | } | ||
210 | |||
211 | void KRFBDecoder::gotDesktopName() | ||
212 | { | ||
213 | assert( info ); | ||
214 | assert( currentState == AwaitingDesktopName ); | ||
215 | |||
216 | qWarning( "Got desktop name" ); | ||
217 | |||
218 | disconnect( con, SIGNAL( gotEnoughData() ), | ||
219 | this, SLOT( gotDesktopName() ) ); | ||
220 | |||
221 | char *buf = new char[ info->nameLength + 1 ]; | ||
222 | CHECK_PTR( buf ); | ||
223 | |||
224 | con->read( buf, info->nameLength ); | ||
225 | buf[ info->nameLength ] = '\0'; | ||
226 | info->name = buf; | ||
227 | |||
228 | qWarning( "Desktop: %s", info->name.latin1() ); | ||
229 | |||
230 | delete buf; | ||
231 | |||
232 | // Get the format we'll really use and tell the server | ||
233 | decidePixelFormat(); | ||
234 | sendPixelFormat(); | ||
235 | sendAllowedEncodings(); | ||
236 | currentState = Idle; | ||
237 | |||
238 | QString msg; | ||
239 | msg = tr( "Connected to %1" ); | ||
240 | msg = msg.arg( info->name ); | ||
241 | emit status( msg ); | ||
242 | |||
243 | sendUpdateRequest( false ); | ||
244 | } | ||
245 | |||
246 | void KRFBDecoder::decidePixelFormat() | ||
247 | { | ||
248 | assert( info ); | ||
249 | |||
250 | if ( format ) | ||
251 | delete format; | ||
252 | format = new KRFBPixelFormat; | ||
253 | CHECK_PTR( format ); | ||
254 | |||
255 | // What depth do we want? | ||
256 | // | ||
257 | // We'll use the minimum of the remote and local depths, UNLESS an | ||
258 | // eight bit session has been specifically requested by the user. | ||
259 | int screenDepth = QPixmap::defaultDepth(); | ||
260 | int bestDepth = ( screenDepth > info->depth ) ? info->depth : screenDepth; | ||
261 | int chosenDepth; | ||
262 | |||
263 | if ( con->options()->colors256 ) | ||
264 | chosenDepth = 8; | ||
265 | else | ||
266 | chosenDepth = bestDepth; | ||
267 | |||
268 | qWarning( "Screen depth=%d, server depth=%d, best depth=%d, " \ | ||
269 | "eight bit %d, chosenDepth=%d", | ||
270 | screenDepth, | ||
271 | info->depth, | ||
272 | bestDepth, | ||
273 | con->options()->colors256, chosenDepth ); | ||
274 | |||
275 | format->depth = chosenDepth; | ||
276 | |||
277 | // If we're using the servers native depth | ||
278 | if ( chosenDepth == info->depth ) { | ||
279 | // Use the servers native format | ||
280 | format->bpp = info->bpp; | ||
281 | // format->bigEndian = info->bigEndian; | ||
282 | format->bigEndian = true; | ||
283 | format->trueColor = info->trueColor; | ||
284 | format->redMax = info->redMax; | ||
285 | format->greenMax = info->greenMax; | ||
286 | format->blueMax = info->blueMax; | ||
287 | format->redShift = info->redShift; | ||
288 | format->greenShift = info->greenShift; | ||
289 | format->blueShift = info->blueShift; | ||
290 | } | ||
291 | else { | ||
292 | if ( chosenDepth == 8 ) { | ||
293 | format->bpp = 8; | ||
294 | format->bigEndian = true; | ||
295 | format->trueColor = true; | ||
296 | format->redMax = 7; | ||
297 | format->greenMax = 7; | ||
298 | format->blueMax = 3; | ||
299 | format->redShift = 0; | ||
300 | format->greenShift = 3; | ||
301 | format->blueShift = 6; | ||
302 | } | ||
303 | } | ||
304 | |||
305 | format->redMax = Swap16IfLE( format->redMax ); | ||
306 | format->greenMax = Swap16IfLE( format->greenMax ); | ||
307 | format->blueMax = Swap16IfLE( format->blueMax ); | ||
308 | } | ||
309 | |||
310 | void KRFBDecoder::sendPixelFormat() | ||
311 | { | ||
312 | static char padding[3]; | ||
313 | con->write( &SetPixelFormatId, 1 ); | ||
314 | con->write( padding, 3 ); | ||
315 | |||
316 | con->write( &(format->bpp), 1 ); | ||
317 | con->write( &(format->depth), 1 ); | ||
318 | con->write( &(format->bigEndian), 1 ); | ||
319 | con->write( &(format->trueColor), 1 ); | ||
320 | |||
321 | con->write( &(format->redMax), 2 ); | ||
322 | con->write( &(format->greenMax), 2 ); | ||
323 | con->write( &(format->blueMax), 2 ); | ||
324 | |||
325 | con->write( &(format->redShift), 1 ); | ||
326 | con->write( &(format->greenShift), 1 ); | ||
327 | con->write( &(format->blueShift), 1 ); | ||
328 | con->write( format->padding, 3 ); // Padding | ||
329 | } | ||
330 | |||
331 | void KRFBDecoder::sendAllowedEncodings() | ||
332 | { | ||
333 | static CARD8 padding[1]; | ||
334 | con->write( &SetEncodingsId, 1 ); | ||
335 | con->write( padding, 1 ); | ||
336 | |||
337 | static CARD16 noEncodings = con->options()->encodings(); | ||
338 | noEncodings = Swap16IfLE( noEncodings ); | ||
339 | con->write( &noEncodings, 2 ); | ||
340 | |||
341 | if ( con->options()->corre ) | ||
342 | con->write( &CorreEncoding, 4 ); | ||
343 | if ( con->options()->hexTile ) | ||
344 | con->write( &HexTileEncoding, 4 ); | ||
345 | if ( con->options()->rre ) | ||
346 | con->write( &RreEncoding, 4 ); | ||
347 | if ( con->options()->copyrect ) | ||
348 | con->write( &CopyRectEncoding, 4 ); | ||
349 | // We always support this | ||
350 | con->write( &RawEncoding, 4 ); | ||
351 | } | ||
352 | |||
353 | void KRFBDecoder::sendUpdateRequest( bool incremental ) | ||
354 | { | ||
355 | if ( currentState != Idle ) | ||
356 | return; | ||
357 | |||
358 | con->write( &UpdateRequestId, 1 ); | ||
359 | con->write( &incremental, 1 ); | ||
360 | |||
361 | static CARD16 x = 0, y = 0; | ||
362 | static CARD16 w = Swap16IfLE( info->width ); | ||
363 | static CARD16 h = Swap16IfLE( info->height ); | ||
364 | |||
365 | con->write( &x, 2 ); | ||
366 | con->write( &y, 2 ); | ||
367 | con->write( &w, 2 ); | ||
368 | con->write( &h, 2 ); | ||
369 | |||
370 | // Now wait for the update | ||
371 | currentState = AwaitingUpdate; | ||
372 | connect( con, SIGNAL( gotEnoughData() ), SLOT( gotUpdateHeader() ) ); | ||
373 | con->waitForData( UpdateHeaderLength ); | ||
374 | } | ||
375 | |||
376 | void KRFBDecoder::gotUpdateHeader() | ||
377 | { | ||
378 | assert( currentState == AwaitingUpdate ); | ||
379 | |||
380 | // qWarning( "Got update header" ); | ||
381 | |||
382 | disconnect( con, SIGNAL( gotEnoughData() ), | ||
383 | this, SLOT( gotUpdateHeader() ) ); | ||
384 | |||
385 | CARD8 msgType; | ||
386 | con->read( &msgType, 1 ); | ||
387 | |||
388 | if ( msgType != UpdateId ) { | ||
389 | // We might have a bell or server cut | ||
390 | if ( msgType == ServerCutId ) { | ||
391 | oldState = currentState; | ||
392 | gotServerCut(); | ||
393 | } | ||
394 | else if ( msgType == BellId ) { | ||
395 | oldState = currentState; | ||
396 | gotBell(); | ||
397 | } | ||
398 | else { | ||
399 | int msg = msgType; | ||
400 | QString protocolError = tr( "Protocol Error: Message Id %1 was " | ||
401 | "found when expecting an update " | ||
402 | "message." ).arg( msg ); | ||
403 | currentState = Error; | ||
404 | emit error( protocolError ); | ||
405 | } | ||
406 | return; | ||
407 | } | ||
408 | |||
409 | CARD8 padding; | ||
410 | con->read( &padding, 1 ); | ||
411 | |||
412 | con->read( &noRects, 2 ); | ||
413 | noRects = Swap16IfLE( noRects ); | ||
414 | |||
415 | // qWarning( "Expecting %d rects", noRects ); | ||
416 | |||
417 | // Now wait for the data | ||
418 | currentState = AwaitingRectHeader; | ||
419 | connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRectHeader() ) ); | ||
420 | con->waitForData( RectHeaderLength ); | ||
421 | } | ||
422 | |||
423 | void KRFBDecoder::gotRectHeader() | ||
424 | { | ||
425 | assert( currentState == AwaitingRectHeader ); | ||
426 | |||
427 | // qWarning( "Got rect header" ); | ||
428 | |||
429 | disconnect( con, SIGNAL( gotEnoughData() ), | ||
430 | this, SLOT( gotRectHeader() ) ); | ||
431 | |||
432 | con->read( &x, 2 ); | ||
433 | x = Swap16IfLE( x ); | ||
434 | con->read( &y, 2 ); | ||
435 | y = Swap16IfLE( y ); | ||
436 | |||
437 | con->read( &w, 2 ); | ||
438 | w = Swap16IfLE( w ); | ||
439 | con->read( &h, 2 ); | ||
440 | h = Swap16IfLE( h ); | ||
441 | |||
442 | con->read( &encoding, 4 ); | ||
443 | |||
444 | // CARD32 encodingLocal = Swap32IfLE( encoding ); | ||
445 | // qWarning( "Rect: x=%d, y= %d, w=%d, h=%d, encoding=%ld", | ||
446 | // x, y, w, h, encodingLocal ); | ||
447 | |||
448 | // | ||
449 | // Each encoding needs to be handled differently. Some require | ||
450 | // waiting for more data, but others like a copyrect do not. | ||
451 | // Our constants have already been byte swapped, so we use | ||
452 | // the remote value as is. | ||
453 | // | ||
454 | if ( encoding == RawEncoding ) { | ||
455 | // qWarning( "Raw encoding" ); | ||
456 | handleRawRect(); | ||
457 | } | ||
458 | else if ( encoding == CopyRectEncoding ) { | ||
459 | // qWarning( "CopyRect encoding" ); | ||
460 | handleCopyRect(); | ||
461 | } | ||
462 | else if ( encoding == RreEncoding ) { | ||
463 | qWarning( "RRE encoding" ); | ||
464 | handleRRERect(); | ||
465 | } | ||
466 | else if ( encoding == CorreEncoding ) { | ||
467 | qWarning( "CoRRE encoding" ); | ||
468 | handleCoRRERect(); | ||
469 | } | ||
470 | else if ( encoding == HexTileEncoding ) { | ||
471 | qWarning( "HexTile encoding" ); | ||
472 | handleHexTileRect(); | ||
473 | } | ||
474 | else { | ||
475 | int msg = Swap32IfLE( encoding ); | ||
476 | QString protocolError = tr( "Protocol Error: An unknown encoding was " | ||
477 | "used by the server %1" ).arg( msg ); | ||
478 | currentState = Error; | ||
479 | qWarning( "Unknown encoding, %d", msg ); | ||
480 | emit error( protocolError ); | ||
481 | return; | ||
482 | } | ||
483 | } | ||
484 | |||
485 | // | ||
486 | // Raw Encoding | ||
487 | // | ||
488 | |||
489 | void KRFBDecoder::handleRawRect() | ||
490 | { | ||
491 | // We need something a bit cleverer here to handle large | ||
492 | // rectanges nicely. The chunking should be based on the | ||
493 | // overall size (but has to be in complete lines). | ||
494 | |||
495 | // qWarning( "Handling a raw rect chunk" ); | ||
496 | |||
497 | // CARD32 lineCount = w * format->bpp / 8; | ||
498 | |||
499 | if ( h > RectChunkSize ) { | ||
500 | // if ( con->sock->size() / lineCount ) { | ||
501 | // getRawRectChunk( con->sock->size() / lineCount ); | ||
502 | // } | ||
503 | // else { | ||
504 | getRawRectChunk( RectChunkSize ); | ||
505 | // } | ||
506 | } | ||
507 | else { | ||
508 | getRawRectChunk( h ); | ||
509 | } | ||
510 | } | ||
511 | |||
512 | void KRFBDecoder::getRawRectChunk( int lines ) | ||
513 | { | ||
514 | this->lines = lines; | ||
515 | CARD32 count = lines * w * format->bpp / 8; | ||
516 | |||
517 | // Wait for server init | ||
518 | // qWarning( "Waiting for raw rect chunk, %ld", count ); | ||
519 | |||
520 | currentState = AwaitingRawRectChunk; | ||
521 | connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRawRectChunk() ) ); | ||
522 | con->waitForData( count ); | ||
523 | } | ||
524 | |||
525 | void KRFBDecoder::gotRawRectChunk() | ||
526 | { | ||
527 | assert( currentState == AwaitingRawRectChunk ); | ||
528 | |||
529 | disconnect( con, SIGNAL( gotEnoughData() ), | ||
530 | this, SLOT( gotRawRectChunk() ) ); | ||
531 | |||
532 | // qWarning( "Got raw rect chunk" ); | ||
533 | |||
534 | // | ||
535 | // Read the rect data and copy it to the buffer. | ||
536 | // | ||
537 | |||
538 | // TODO: Replace this! | ||
539 | int count = lines * w * format->bpp / 8; | ||
540 | char *hack = new char[ count ]; | ||
541 | con->read( hack, count ); | ||
542 | buf->drawRawRectChunk( hack, x, y, w, lines ); | ||
543 | delete hack; | ||
544 | // /TODO: | ||
545 | |||
546 | h = h - lines; | ||
547 | y = y + lines; | ||
548 | |||
549 | if ( h > 0 ) { | ||
550 | handleRawRect(); | ||
551 | } | ||
552 | else { | ||
553 | noRects--; | ||
554 | |||
555 | // qWarning( "There are %d rects left", noRects ); | ||
556 | |||
557 | if ( noRects ) { | ||
558 | currentState = AwaitingRectHeader; | ||
559 | connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRectHeader() ) ); | ||
560 | con->waitForData( RectHeaderLength ); | ||
561 | } | ||
562 | else | ||
563 | currentState = Idle; | ||
564 | } | ||
565 | } | ||
566 | |||
567 | // | ||
568 | // Copy Rectangle Encoding | ||
569 | // | ||
570 | |||
571 | void KRFBDecoder::handleCopyRect() | ||
572 | { | ||
573 | currentState = AwaitingCopyRectPos; | ||
574 | connect( con, SIGNAL( gotEnoughData() ), SLOT( gotCopyRectPos() ) ); | ||
575 | con->waitForData( CopyRectPosLength ); | ||
576 | } | ||
577 | |||
578 | void KRFBDecoder::gotCopyRectPos() | ||
579 | { | ||
580 | disconnect( con, SIGNAL( gotEnoughData() ), | ||
581 | this, SLOT( gotCopyRectPos() ) ); | ||
582 | |||
583 | CARD16 srcX; | ||
584 | CARD16 srcY; | ||
585 | |||
586 | con->read( &srcX, 2 ); | ||
587 | con->read( &srcY, 2 ); | ||
588 | |||
589 | srcX = Swap16IfLE( srcX ); | ||
590 | srcY = Swap16IfLE( srcY ); | ||
591 | |||
592 | buf->copyRect( srcX, srcY, x, y, w, h ); | ||
593 | |||
594 | noRects--; | ||
595 | |||
596 | // qWarning( "There are %d rects left", noRects ); | ||
597 | |||
598 | if ( noRects ) { | ||
599 | currentState = AwaitingRectHeader; | ||
600 | connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRectHeader() ) ); | ||
601 | con->waitForData( RectHeaderLength ); | ||
602 | } | ||
603 | else | ||
604 | currentState = Idle; | ||
605 | } | ||
606 | |||
607 | void KRFBDecoder::handleRRERect() | ||
608 | { | ||
609 | qWarning( "RRE not implemented" ); | ||
610 | } | ||
611 | |||
612 | void KRFBDecoder::handleCoRRERect() | ||
613 | { | ||
614 | qWarning( "CoRRE not implemented" ); | ||
615 | } | ||
616 | |||
617 | void KRFBDecoder::handleHexTileRect() | ||
618 | { | ||
619 | qWarning( "HexTile not implemented" ); | ||
620 | } | ||
621 | |||
622 | void KRFBDecoder::sendMouseEvent( QMouseEvent *e ) | ||
623 | { | ||
624 | // Deal with the buttons | ||
625 | if ( e->type() != QEvent::MouseMove ) { | ||
626 | buttonMask = 0; | ||
627 | if ( e->type() == QEvent::MouseButtonPress ) { | ||
628 | if ( e->button() & LeftButton ) | ||
629 | buttonMask |= 0x01; | ||
630 | if ( e->button() & MidButton ) | ||
631 | buttonMask |= 0x04; | ||
632 | if ( e->button() & RightButton ) | ||
633 | buttonMask |= 0x02; | ||
634 | } | ||
635 | else if ( e->type() == QEvent::MouseButtonRelease ) { | ||
636 | if ( e->button() & LeftButton ) | ||
637 | buttonMask &= 0x06; | ||
638 | if ( e->button() & MidButton ) | ||
639 | buttonMask |= 0x03; | ||
640 | if ( e->button() & RightButton ) | ||
641 | buttonMask |= 0x05; | ||
642 | } | ||
643 | } | ||
644 | |||
645 | CARD16 x = Swap16IfLE( e->x() ); | ||
646 | CARD16 y = Swap16IfLE( e->y() ); | ||
647 | |||
648 | con->write( &PointerEventId, 1 ); | ||
649 | con->write( &buttonMask, 1 ); | ||
650 | con->write( &x, 2 ); | ||
651 | con->write( &y, 2 ); | ||
652 | } | ||
653 | |||
654 | |||
655 | void KRFBDecoder::sendCutEvent( const QString &unicode ) | ||
656 | { | ||
657 | // | ||
658 | // Warning: There is a bug in the RFB protocol because there is no way to find | ||
659 | // out the codepage in use on the remote machine. This could be fixed by requiring | ||
660 | // the remote server to use utf8 etc. but for now we have to assume they're the | ||
661 | // same. I've reported this problem to the ORL guys, but they apparantly have no | ||
662 | // immediate plans to fix the issue. :-( (rich) | ||
663 | // | ||
664 | |||
665 | CARD8 padding[3]; | ||
666 | QCString text = unicode.local8Bit(); | ||
667 | CARD32 length = text.length(); | ||
668 | length = Swap32IfLE( length ); | ||
669 | |||
670 | con->write( &ClientCutTextId, 1 ); | ||
671 | con->write( &padding, 3 ); | ||
672 | con->write( &length, 4 ); | ||
673 | con->write( text.data(), length ); | ||
674 | } | ||
675 | |||
676 | void KRFBDecoder::gotServerCut() | ||
677 | { | ||
678 | qWarning( "Got server cut" ); | ||
679 | |||
680 | currentState = AwaitingServerCutLength; | ||
681 | connect( con, SIGNAL( gotEnoughData() ), SLOT( gotServerCutLength() ) ); | ||
682 | con->waitForData( ServerCutLenLength ); | ||
683 | } | ||
684 | |||
685 | void KRFBDecoder::gotServerCutLength() | ||
686 | { | ||
687 | assert( currentState = AwaitingServerCutLength ); | ||
688 | disconnect( con, SIGNAL( gotEnoughData() ), | ||
689 | this, SLOT( gotServerCutLength() ) ); | ||
690 | |||
691 | CARD8 padding[3]; | ||
692 | con->read( padding, 3 ); | ||
693 | |||
694 | con->read( &serverCutTextLen, 4 ); | ||
695 | serverCutTextLen = Swap32IfLE( serverCutTextLen ); | ||
696 | |||
697 | currentState = AwaitingServerCutText; | ||
698 | connect( con, SIGNAL( gotEnoughData() ), SLOT( gotServerCutText() ) ); | ||
699 | con->waitForData( serverCutTextLen ); | ||
700 | } | ||
701 | |||
702 | void KRFBDecoder::gotServerCutText() | ||
703 | { | ||
704 | assert( currentState = AwaitingServerCutText ); | ||
705 | |||
706 | disconnect( con, SIGNAL( gotEnoughData() ), | ||
707 | this, SLOT( gotServerCutText() ) ); | ||
708 | |||
709 | // | ||
710 | // Warning: There is a bug in the RFB protocol because there is no way to find | ||
711 | // out the codepage in use on the remote machine. This could be fixed by requiring | ||
712 | // the remote server to use utf8 etc. but for now we have to assume they're the | ||
713 | // same. I've reported this problem to the ORL guys, but they apparantly have no | ||
714 | // immediate plans to fix the issue. :-( (rich) | ||
715 | // | ||
716 | |||
717 | char *cutbuf = new char[ serverCutTextLen + 1 ]; | ||
718 | CHECK_PTR( cutbuf ); | ||
719 | |||
720 | con->read( cutbuf, serverCutTextLen ); | ||
721 | cutbuf[ serverCutTextLen ] = '\0'; | ||
722 | |||
723 | qWarning( "Server cut: %s", cutbuf ); | ||
724 | |||
725 | QString cutText( cutbuf ); // DANGER!! | ||
726 | qApp->clipboard()->setText( cutText ); | ||
727 | |||
728 | delete cutbuf; | ||
729 | |||
730 | // Now wait for the update (again) | ||
731 | if ( oldState == AwaitingUpdate ) { | ||
732 | currentState = AwaitingUpdate; | ||
733 | connect( con, SIGNAL( gotEnoughData() ), SLOT( gotUpdateHeader() ) ); | ||
734 | con->waitForData( UpdateHeaderLength ); | ||
735 | } | ||
736 | else if ( oldState == Idle ) { | ||
737 | currentState = Idle; | ||
738 | } | ||
739 | else { | ||
740 | qWarning( "Async handled in weird state" ); | ||
741 | currentState = oldState; | ||
742 | }; | ||
743 | } | ||
744 | |||
745 | void KRFBDecoder::gotBell() | ||
746 | { | ||
747 | qWarning( "Got server bell" ); | ||
748 | buf->soundBell(); | ||
749 | |||
750 | // Now wait for the update (again) | ||
751 | if ( oldState == AwaitingUpdate ) { | ||
752 | currentState = AwaitingUpdate; | ||
753 | connect( con, SIGNAL( gotEnoughData() ), SLOT( gotUpdateHeader() ) ); | ||
754 | con->waitForData( UpdateHeaderLength ); | ||
755 | } | ||
756 | else if ( oldState == Idle ) { | ||
757 | currentState = Idle; | ||
758 | } | ||
759 | else { | ||
760 | qWarning( "Async handled in weird state" ); | ||
761 | currentState = oldState; | ||
762 | }; | ||
763 | } | ||
764 | |||
765 | void KRFBDecoder::sendKeyPressEvent( QKeyEvent *event ) | ||
766 | { | ||
767 | int key; | ||
768 | key = toKeySym( event ); | ||
769 | if ( key ) { | ||
770 | key = Swap32IfLE( key ); | ||
771 | |||
772 | CARD8 mask = true; | ||
773 | |||
774 | CARD16 padding = 0; | ||
775 | con->write( &KeyEventId, 1 ); | ||
776 | con->write( &mask, 1 ); | ||
777 | con->write( &padding, 2 ); | ||
778 | con->write( &key, 4 ); | ||
779 | } | ||
780 | } | ||
781 | |||
782 | void KRFBDecoder::sendKeyReleaseEvent( QKeyEvent *event ) | ||
783 | { | ||
784 | int key; | ||
785 | key = toKeySym( event ); | ||
786 | if ( key ) { | ||
787 | key = Swap32IfLE( key ); | ||
788 | |||
789 | CARD8 mask = false; | ||
790 | |||
791 | CARD16 padding = 0; | ||
792 | con->write( &KeyEventId, 1 ); | ||
793 | con->write( &mask, 1 ); | ||
794 | con->write( &padding, 2 ); | ||
795 | con->write( &key, 4 ); | ||
796 | } | ||
797 | } | ||
798 | |||
799 | int KRFBDecoder::toKeySym( QKeyEvent *k ) | ||
800 | { | ||
801 | int ke = 0; | ||
802 | |||
803 | ke = k->ascii(); | ||
804 | // Markus: Crappy hack. I dont know why lower case letters are | ||
805 | // not defined in qkeydefs.h. The key() for e.g. 'l' == 'L'. | ||
806 | // This sucks. :-( | ||
807 | |||
808 | if ( (ke == 'a') || (ke == 'b') || (ke == 'c') || (ke == 'd') | ||
809 | || (ke == 'e') || (ke == 'f') || (ke == 'g') || (ke == 'h') | ||
810 | || (ke == 'i') || (ke == 'j') || (ke == 'k') || (ke == 'l') | ||
811 | || (ke == 'm') || (ke == 'n') || (ke == 'o') || (ke == 'p') | ||
812 | || (ke == 'q') || (ke == 'r') || (ke == 's') || (ke == 't') | ||
813 | || (ke == 'u') || (ke == 'v') ||( ke == 'w') || (ke == 'x') | ||
814 | || (ke == 'y') || (ke == 'z') ) { | ||
815 | ke = k->key(); | ||
816 | ke = ke + 0x20; | ||
817 | return ke; | ||
818 | } | ||
819 | |||
820 | // qkeydefs = xkeydefs! :-) | ||
821 | if ( ( k->key() >= 0x0a0 ) && k->key() <= 0x0ff ) | ||
822 | return k->key(); | ||
823 | |||
824 | if ( ( k->key() >= 0x20 ) && ( k->key() <= 0x7e ) ) | ||
825 | return k->key(); | ||
826 | |||
827 | // qkeydefs != xkeydefs! :-( | ||
828 | // This is gonna suck :-( | ||
829 | |||
830 | int i = 0; | ||
831 | while ( keyMap[i].keycode ) { | ||
832 | if ( k->key() == keyMap[i].keycode ) | ||
833 | return keyMap[i].keysym; | ||
834 | i++; | ||
835 | } | ||
836 | |||
837 | return 0; | ||
838 | } | ||
839 | |||