summaryrefslogtreecommitdiff
path: root/noncore/comm/keypebble/krfbdecoder.cpp
Unidiff
Diffstat (limited to 'noncore/comm/keypebble/krfbdecoder.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/comm/keypebble/krfbdecoder.cpp839
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
21const 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//
36const int ServerInitLength = 24;
37const int UpdateHeaderLength = 4;
38const int RectHeaderLength = 12;
39const int RectChunkSize = 4;
40const int CopyRectPosLength = 4;
41const int ServerCutLenLength = 7;
42
43//
44// Client -> Server Message Identifiers
45//
46static CARD8 SetPixelFormatId = 0;
47//static CARD8 FixColourMapEntriesId = 1; // Not used
48static CARD8 SetEncodingsId = 2;
49static CARD8 UpdateRequestId = 3;
50static CARD8 KeyEventId = 4;
51static CARD8 PointerEventId = 5;
52static CARD8 ClientCutTextId = 6;
53
54//
55// Server -> Client Message Identifiers
56//
57static CARD8 UpdateId = 0;
58static CARD8 BellId = 2;
59static CARD8 ServerCutId = 3;
60
61//
62// Encoding identifiers
63//
64static CARD32 RawEncoding = Swap32IfLE( 0 );
65static CARD32 CopyRectEncoding = Swap32IfLE(1 );
66static CARD32 RreEncoding = Swap32IfLE( 2 );
67static CARD32 CorreEncoding = Swap32IfLE( 4 );
68static CARD32 HexTileEncoding = Swap32IfLE( 5 );
69
70static 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
112KRFBDecoder::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
126KRFBDecoder::~KRFBDecoder()
127{
128 if ( info )
129 delete info;
130 if ( format )
131 delete format;
132}
133
134void KRFBDecoder::start()
135{
136 sendClientInit();
137}
138
139void 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
154void 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
211void 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
246void 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
310void 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
331void 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
353void 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
376void 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
423void 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
489void 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
512void 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
525void 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
571void KRFBDecoder::handleCopyRect()
572{
573 currentState = AwaitingCopyRectPos;
574 connect( con, SIGNAL( gotEnoughData() ), SLOT( gotCopyRectPos() ) );
575 con->waitForData( CopyRectPosLength );
576}
577
578void 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
607void KRFBDecoder::handleRRERect()
608{
609 qWarning( "RRE not implemented" );
610}
611
612void KRFBDecoder::handleCoRRERect()
613{
614 qWarning( "CoRRE not implemented" );
615}
616
617void KRFBDecoder::handleHexTileRect()
618{
619 qWarning( "HexTile not implemented" );
620}
621
622void 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
655void 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
676void 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
685void 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
702void 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
745void 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
765void 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
782void 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
799int 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