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