~ubuntu-branches/debian/lenny/italc/lenny

« back to all changes in this revision

Viewing changes to master/italc/src/rfb_connection.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Patrick Winnertz
  • Date: 2008-06-17 13:46:54 UTC
  • mfrom: (1.2.1 upstream) (4.1.1 gutsy)
  • Revision ID: james.westby@ubuntu.com-20080617134654-cl0gi4u524cv1ici
Tags: 1:1.0.9~rc3-1
* Package new upstream version
  - upstream ported the code to qt4.4 (Closes: #481974)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * rfb_protocol.cpp - class rfbConnection, an implementation of the RFB-protocol, used by VNC servers
3
 
 *
4
 
 * iTALC
5
 
 * Copyright (c) 2004-2005 Tobias Doerffel <tobias@doerffel.de>
6
 
 *
7
 
 * This program is free software; you can redistribute it and/or
8
 
 * modify it under the terms of the GNU General Public
9
 
 * License as published by the Free Software Foundation; either
10
 
 * version 2 of the License, or (at your option) any later version.
11
 
 *
12
 
 * This program is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 
 * General Public License for more details.
16
 
 *
17
 
 * You should have received a copy of the GNU General Public
18
 
 * License along with this program (see COPYING); if not, write to the
19
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20
 
 * Boston, MA 02111-1307, USA.
21
 
 *
22
 
 */
23
 
 
24
 
#ifdef HAVE_CONFIG_H
25
 
#include <config.h>
26
 
#endif
27
 
 
28
 
#include <cstring>
29
 
#ifdef HAVE_NETDB_H
30
 
#include <netdb.h>
31
 
#endif
32
 
#ifdef HAVE_FCNTL_H
33
 
#include <fcntl.h>
34
 
#endif
35
 
#ifdef HAVE_NETINET_TCP_H
36
 
#include <netinet/tcp.h>
37
 
#endif
38
 
#ifdef HAVE_UNISTD_H
39
 
#include <unistd.h>
40
 
#endif
41
 
#ifdef HAVE_SYS_SOCKET_H
42
 
#include <sys/socket.h>
43
 
#endif
44
 
 
45
 
#include <cerrno>
46
 
 
47
 
#include <qfileinfo.h>
48
 
#include <qmessagebox.h>
49
 
#include <qdir.h>
50
 
#if QT_VERSION >= 0x030200
51
 
#include <qsplashscreen.h>
52
 
#endif
53
 
 
54
 
#include "rfb_connection.h"
55
 
#include "system_environment.h"
56
 
#include "qimage_manips.h"
57
 
#include "rsa_crypt_lib.h"
58
 
#include "italc.h"
59
 
#include "paths.h"
60
 
 
61
 
#include "rfb_connection.moc"
62
 
 
63
 
 
64
 
int endian_test = 1;
65
 
 
66
 
const char * RFBP_VERSION_FORMAT = "RFB %03d.%03d\n";
67
 
//const int MAX_READ_RETRIES = 1024;
68
 
 
69
 
 
70
 
const s_rfb_pixel_format rfbConnection::s_localDisplayFormat =
71
 
{
72
 
        32,             // bit per pixel
73
 
        32,             // depth
74
 
        FALSE,          // big endian
75
 
        1,              // true color
76
 
        255,            // red max
77
 
        255,            // green max
78
 
        255,            // blue max
79
 
        16,             // red shift
80
 
        8,              // green shift
81
 
        0,              // blue shift,
82
 
        0, 0            // only for padding
83
 
} ;
84
 
 
85
 
 
86
 
 
87
 
#ifdef RSA_CRYPT_AVAILABLE
88
 
RSA * rfbConnection::s_privateKey = NULL;
89
 
#endif
90
 
 
91
 
 
92
 
void rfbConnection::initializeAuthentication( void )
93
 
{
94
 
#ifdef RSA_CRYPT_AVAILABLE
95
 
        if( italc::ensureConfigPathExists() == FALSE )
96
 
        {
97
 
                qFatal( "Could not read/write or create directory " + QString( ITALC_CONFIG_PATH ) + "! For running iTALC, make sure you have "
98
 
                        "write-access to your home-directory and to " + QString( ITALC_CONFIG_PATH ) + " (if already existing)." );
99
 
        }
100
 
        const QString PRIV_KEY_FILE = QDir::home().absPath() + "/"+ITALC_CONFIG_PATH+"/id_rsa";
101
 
        const QString PUB_KEY_FILE = PRIV_KEY_FILE + ".public";
102
 
 
103
 
        s_privateKey = readPrivateKey( PRIV_KEY_FILE );
104
 
        if( s_privateKey == NULL )
105
 
        {
106
 
                // generate 1024bit RSA-key and save it
107
 
                s_privateKey = rsaGeneratePrivateKey( 1024 );
108
 
                writePrivateKey( s_privateKey, PRIV_KEY_FILE );
109
 
 
110
 
                // derive public key from private key and save it
111
 
                RSA * pub_key = publicKeyFromPrivateKey( s_privateKey );
112
 
                writePublicKey( pub_key, PUB_KEY_FILE );
113
 
                RSA_free( pub_key );
114
 
#if QT_VERSION >= 0x030200
115
 
                if( splashScreen != NULL )
116
 
                {
117
 
                        splashScreen->hide();
118
 
                }
119
 
#endif
120
 
                QMessageBox::information( NULL, tr( "New key-pair generated" ), tr( "No authentication-keys were found or your old ones "
121
 
                                                                                        "contained errors, so a new key-pair has been "
122
 
                                                                                        "generated.\nPlease ask your administrator for "
123
 
                                                                                        "distributing your public key. Otherwise you won't "
124
 
                                                                                        "be able to access clients." ), QMessageBox::Ok );
125
 
        }
126
 
#endif
127
 
}
128
 
 
129
 
 
130
 
 
131
 
 
132
 
// normal ctor
133
 
rfbConnection::rfbConnection( const QString & _host_ip ) :
134
 
        QObject(),
135
 
        m_connected( FALSE ),
136
 
        m_hostIP( _host_ip ),
137
 
        m_user( "" ),
138
 
        m_gotInvitationResult( FALSE ),
139
 
        m_invitationOk( FALSE ),
140
 
        m_sock( -1 ),
141
 
        m_clientScreen(),
142
 
        m_scaledClientScreen(),
143
 
        m_destImgSize( 640, 480 ),
144
 
        m_bufOutPtr( m_buf ),
145
 
        m_buffered( 0 )
146
 
{
147
 
#ifdef HAVE_LIBZ
148
 
        m_zlibStreamActive[0] = m_zlibStreamActive[1] = m_zlibStreamActive[2] = m_zlibStreamActive[3] = FALSE;
149
 
#endif
150
 
}
151
 
 
152
 
 
153
 
 
154
 
/*
155
 
// copy ctor for using data frome existing connection
156
 
rfbConnection::rfbConnection( const rfbConnection & _rc ) :
157
 
        QObject(),
158
 
        m_connected( FALSE ),
159
 
        m_hostIP( _rc.m_hostIP ),
160
 
        m_user( "" ),
161
 
        m_gotInvitationResult( FALSE ),
162
 
        m_invitationOk( FALSE ),
163
 
        m_sock( -1 ),
164
 
        m_clientScreen(),
165
 
        m_scaledClientScreen(),
166
 
        m_destImgSize( 640, 480 ),
167
 
        m_bufOutPtr( m_buf ),
168
 
        m_buffered( 0 )
169
 
{
170
 
        m_zlibStreamActive[0] = m_zlibStreamActive[1] = m_zlibStreamActive[2] = m_zlibStreamActive[3] = FALSE;
171
 
}
172
 
*/
173
 
 
174
 
 
175
 
 
176
 
rfbConnection::~rfbConnection()
177
 
{
178
 
        closeConnection();
179
 
}
180
 
 
181
 
 
182
 
 
183
 
 
184
 
bool rfbConnection::openConnection( void )
185
 
{
186
 
        closeConnection ();
187
 
 
188
 
        if( systemEnvironment::hostAvailable( m_hostIP ) == FALSE )
189
 
        {
190
 
                return( FALSE );
191
 
        }
192
 
 
193
 
        in_addr_t host;
194
 
        if( !stringToIPAddr( m_hostIP.ascii(), &host ) )
195
 
        {
196
 
                printf( "Couldn't convert '%s' to host address\n", m_hostIP.ascii() );
197
 
                return( FALSE );
198
 
        }
199
 
 
200
 
        m_sock = connectToTCPAddr( host, VNC_SERVER_PORT_OFFSET );
201
 
 
202
 
        if( m_sock < 0 )
203
 
        {
204
 
                //printf("Unable to connect to VNC server on client %s\n", m_hostIP.ascii());
205
 
                return( FALSE );
206
 
        }
207
 
 
208
 
        if( fcntl( m_sock, F_SETFL, O_NONBLOCK ) < 0 )
209
 
        {
210
 
                printf( "Error while setting non-blocking\n" );
211
 
                return( FALSE );
212
 
        }
213
 
 
214
 
 
215
 
        char protocol_version[13];
216
 
        int major, minor;
217
 
        Q_UINT32 auth_scheme, reason_len;
218
 
        char * reason;
219
 
        s_rfb_client_init_msg ci;
220
 
        
221
 
        if( !readFromServer( protocol_version, RFBP_VERSION_MESSAGE_LEN ) )
222
 
        {
223
 
                return( FALSE );
224
 
        }
225
 
        
226
 
        protocol_version[RFBP_VERSION_MESSAGE_LEN] = 0;
227
 
 
228
 
        if( sscanf( protocol_version, RFBP_VERSION_FORMAT, &major, &minor ) != 2 )
229
 
        {
230
 
                printf( "Not a valid VNC server\n" );
231
 
                return( FALSE);
232
 
        }
233
 
 
234
 
        //printf ("VNC server supports protocol version %d.%d (viewer %d.%d)\n", major, minor, RFBP_MAJOR_VERSION, RFBP_MINOR_VERSION);
235
 
 
236
 
        //major = RFBP_MAJOR_VERSION;
237
 
        //minor = RFBP_MINOR_VERSION;
238
 
 
239
 
        //sprintf (protocol_version, protocol_version, major, minor);
240
 
 
241
 
        if( !writeToServer( protocol_version, RFBP_VERSION_MESSAGE_LEN ) )
242
 
        {
243
 
                return( FALSE );
244
 
        }
245
 
 
246
 
 
247
 
        if( !readFromServer( (char *)&auth_scheme, sizeof( Q_UINT32 ) ) )
248
 
        {
249
 
                return( FALSE );
250
 
        }
251
 
 
252
 
        auth_scheme = Swap32IfLE( auth_scheme );
253
 
 
254
 
        switch( auth_scheme )
255
 
        {
256
 
                case RFB_CONNECTION_FAILED:
257
 
                        if( !readFromServer( (char *)&reason_len, sizeof( Q_UINT32 ) ) )
258
 
                        {
259
 
                                return( FALSE );
260
 
                        }
261
 
                        reason_len = Swap32IfLE( reason_len );
262
 
 
263
 
                        reason = new char[reason_len];
264
 
 
265
 
                        if( readFromServer( reason, reason_len ) )
266
 
                        {
267
 
                                printf( "VNC connection failed: %.*s\n", (int) reason_len, reason );
268
 
                        }
269
 
                        delete reason;
270
 
                        return( FALSE );
271
 
 
272
 
                case RFB_NO_AUTHENTICATION:
273
 
                        //printf ("No authentication needed\n");
274
 
                        break;
275
 
#ifdef RSA_CRYPT_AVAILABLE
276
 
                case RFB_VNC_CHALL_RESP_AUTHENTICATION:
277
 
                {
278
 
                        // send user-name to server (server has to encrypt data with the appropriate key)
279
 
                        s_rfb_authentication ra;
280
 
                        QString user_name = getenv( "USER" );
281
 
 
282
 
                        ra.user_name_len = Swap16IfLE( user_name.length()+1 );
283
 
                        if( !writeToServer( (const char*) &ra, sizeof( ra ) ) )
284
 
                                return( FALSE );
285
 
                        if( !writeToServer( user_name.ascii(), user_name.length()+1 ) )
286
 
                                return( FALSE );
287
 
 
288
 
                        // challenge-response-authentication
289
 
                        int ecs = RSA_size( s_privateKey );
290
 
                        char * encrypted_challenge = new char[ecs];
291
 
                        if( !readFromServer( encrypted_challenge, ecs ) )
292
 
                        {
293
 
                                return( FALSE );
294
 
                        }
295
 
 
296
 
                        char * decrypted_response = new char[DEFAULT_CHALLENGE_SIZE];
297
 
                        
298
 
                        int bytes = RSA_private_decrypt( ecs, (unsigned char *)encrypted_challenge, (unsigned char *)decrypted_response, s_privateKey, RSA_PKCS1_PADDING );
299
 
                        // TODO: add error handling if bytes != DEFAULT_CHALLENGE_SIZE
300
 
 
301
 
                        if( !writeToServer( decrypted_response, DEFAULT_CHALLENGE_SIZE ) )
302
 
                        {
303
 
                                return( FALSE );
304
 
                        }
305
 
                        delete[] encrypted_challenge;
306
 
                        delete[] decrypted_response;
307
 
                        Q_UINT32 auth_result;
308
 
                        if( !readFromServer( (char *)& auth_result, 4 ) )
309
 
                        {
310
 
                                return( FALSE );
311
 
                        }
312
 
                        auth_result = Swap32IfLE( auth_result );
313
 
                        switch( auth_result )
314
 
                        {
315
 
                                case RFB_AUTH_OK:
316
 
                                        //printf( "VNC authentication succeeded\n" );
317
 
                                        break;
318
 
                                case RFB_AUTH_FAILED:
319
 
                                        printf( "VNC authentication failed\n" );
320
 
                                        return( FALSE );
321
 
                                case RFB_AUTH_TOO_MANY:
322
 
                                        printf( "VNC authentication failed - too many tries\n" );
323
 
                                        return( FALSE );
324
 
                                default:
325
 
                                        printf( "Unknown VNC authentication result: %d\n", (int) auth_result );
326
 
                                        return( FALSE );
327
 
                        }
328
 
                        break;
329
 
                }
330
 
#endif
331
 
                default:
332
 
                        printf( "Unknown authentication scheme from VNC server: %d\n",(int) auth_scheme );
333
 
                        return( FALSE);
334
 
        }
335
 
 
336
 
        ci.shared = TRUE;
337
 
 
338
 
        if( !writeToServer( (char *) &ci, sizeof( ci ) ) )
339
 
        {
340
 
                return( FALSE );
341
 
        }
342
 
 
343
 
        if( !readFromServer( (char *)&m_si, sizeof( m_si ) ) )
344
 
        {
345
 
                return( FALSE );
346
 
        }
347
 
 
348
 
        m_si.framebuffer_width = Swap16IfLE( m_si.framebuffer_width );
349
 
        m_si.framebuffer_height = Swap16IfLE( m_si.framebuffer_height );
350
 
        m_si.format.red_max = Swap16IfLE( m_si.format.red_max );
351
 
        m_si.format.green_max = Swap16IfLE( m_si.format.green_max );
352
 
        m_si.format.blue_max = Swap16IfLE( m_si.format.blue_max );
353
 
        m_si.name_length = Swap32IfLE( m_si.name_length );
354
 
 
355
 
        char desktop_name[m_si.name_length+1];
356
 
 
357
 
        if( !readFromServer( desktop_name, m_si.name_length ) )
358
 
        {
359
 
                return( FALSE );
360
 
        }
361
 
 
362
 
        //desktop_name[m_si.name_length] = 0;
363
 
 
364
 
        //printf ("Desktop name: \"%s\"\n",desktop_name);
365
 
        //printf ("Connected to VNC server, using protocol version %d.%d\n", RFBP_MAJOR_VERSION, RFBP_MINOR_VERSION);
366
 
 
367
 
        //printf(stderr,"VNC server default format:\n");
368
 
        //PrintPixelFormat(&m_si.format);
369
 
 
370
 
        s_rfb_set_pixel_format_msg spf;
371
 
 
372
 
        spf.type = RFB_SET_PIXEL_FORMAT;
373
 
        spf.format = s_localDisplayFormat;
374
 
        spf.format.red_max = Swap16IfLE(spf.format.red_max);
375
 
        spf.format.green_max = Swap16IfLE(spf.format.green_max);
376
 
        spf.format.blue_max = Swap16IfLE(spf.format.blue_max);
377
 
 
378
 
        if( !writeToServer( (char *) &spf, sizeof( s_rfb_set_pixel_format_msg ) ) )
379
 
        {
380
 
                return( FALSE );
381
 
        }
382
 
 
383
 
 
384
 
        char m_buf[sizeof(s_rfb_set_pixel_format_msg) + MAX_ENCODINGS * sizeof(Q_UINT32)];
385
 
        s_rfb_set_encodings_msg * se = (s_rfb_set_encodings_msg *) m_buf;
386
 
        se->type = RFB_SET_ENCODINGS;
387
 
        se->n_encodings = 0;
388
 
 
389
 
        Q_UINT32 * encs = (Q_UINT32 *)(&m_buf[sizeof(s_rfb_set_encodings_msg)]);
390
 
 
391
 
        encs[se->n_encodings++] = Swap32IfLE( RFB_ENCODING_TIGHT );
392
 
        encs[se->n_encodings++] = Swap32IfLE( RFB_ENCODING_CORRE );
393
 
        encs[se->n_encodings++] = Swap32IfLE( RFB_ENCODIG_RRE );
394
 
        encs[se->n_encodings++] = Swap32IfLE( RFB_ENCODING_COPYRECT );
395
 
 
396
 
#ifdef HAVE_LIBZ
397
 
        encs[se->n_encodings++] = Swap32IfLE( RFB_ENCODING_COMPRESS_LEVEL_0+4 );
398
 
#ifdef HAVE_LIBJPEG
399
 
        encs[se->n_encodings++] = Swap32IfLE( RFB_ENCODING_QUALITY_LEVEL_0+4 );
400
 
#endif
401
 
#endif
402
 
        //encs[se->n_encodings++] = Swap32IfLE(RFB_ENCODING_LAST_RECT);
403
 
 
404
 
 
405
 
        unsigned int len = sizeof( s_rfb_set_encodings_msg ) + se->n_encodings * sizeof( Q_UINT32 );
406
 
 
407
 
        se->n_encodings = Swap16IfLE( se->n_encodings );
408
 
 
409
 
        if( !writeToServer( m_buf, len ) )
410
 
        {
411
 
                return( FALSE );
412
 
        }
413
 
 
414
 
        //printf ("Pixel-format and encodings sucessfully setup...\n");
415
 
 
416
 
        m_clientScreen = QImage( m_si.framebuffer_width, m_si.framebuffer_height, s_localDisplayFormat.depth );
417
 
 
418
 
        sendFramebufferUpdateRequest();
419
 
        m_connected = TRUE;
420
 
 
421
 
 
422
 
        return( TRUE );
423
 
 
424
 
}
425
 
 
426
 
 
427
 
 
428
 
 
429
 
void rfbConnection::closeConnection( void )
430
 
{
431
 
        m_bufOutPtr = m_buf;
432
 
        m_buffered = 0;
433
 
#ifdef HAVE_LIBZ
434
 
        m_zlibStreamActive[0] = m_zlibStreamActive[1] = m_zlibStreamActive[2] = m_zlibStreamActive[3] = FALSE;
435
 
#endif
436
 
        if( m_sock != -1 )
437
 
        {
438
 
                close( m_sock );
439
 
        }
440
 
        m_sock = -1;
441
 
 
442
 
        m_connected = FALSE;
443
 
 
444
 
        m_user = "";
445
 
 
446
 
}
447
 
 
448
 
 
449
 
 
450
 
 
451
 
bool rfbConnection::resetConnection( const QString & _new_host_ip )
452
 
{
453
 
        closeConnection ();
454
 
 
455
 
        if( _new_host_ip != "" )
456
 
                m_hostIP = _new_host_ip;
457
 
 
458
 
        return( openConnection() );
459
 
}
460
 
 
461
 
 
462
 
 
463
 
 
464
 
bool rfbConnection::dataFromServer( void )
465
 
{
466
 
        fd_set fds;
467
 
        struct timeval tv;
468
 
/*      tv.tv_sec = 0;
469
 
        tv.tv_usec = 10000;     // timeout = 10ms*/
470
 
        tv.tv_sec = 1;          // timeout = 1 s
471
 
        tv.tv_usec = 0;
472
 
        FD_ZERO( &fds );
473
 
        FD_SET( m_sock, &fds );
474
 
        if( select( m_sock+1, &fds, NULL, NULL, &tv ) <= 0 )
475
 
        {
476
 
                return( FALSE );
477
 
        }
478
 
 
479
 
        return( TRUE );
480
 
}
481
 
 
482
 
 
483
 
 
484
 
 
485
 
bool rfbConnection::readFromServer( char * _out, unsigned int _n )
486
 
{
487
 
        if( _n <= m_buffered )
488
 
        {
489
 
                memcpy( _out, m_bufOutPtr, _n );
490
 
                m_bufOutPtr += _n;
491
 
                m_buffered -= _n;
492
 
                return( TRUE );
493
 
        }
494
 
 
495
 
        if( m_buffered )
496
 
        {
497
 
                memcpy( _out, m_bufOutPtr, m_buffered );
498
 
                _out += m_buffered;
499
 
                _n -= m_buffered;
500
 
        }
501
 
 
502
 
        m_bufOutPtr = m_buf;
503
 
        m_buffered = 0;
504
 
 
505
 
        int retries = 0;
506
 
 
507
 
        if( _n <= INTERNAL_READ_BUF_SIZE )
508
 
        {
509
 
                while( m_buffered < _n )
510
 
                {
511
 
                        int i = read( m_sock, m_buf+m_buffered, INTERNAL_READ_BUF_SIZE-m_buffered );
512
 
                        if( i <= 0 )
513
 
                        {
514
 
                                if( i < 0 )
515
 
                                {
516
 
                                        if( ( errno == EWOULDBLOCK || errno == EAGAIN )/* && ++retries < MAX_READ_RETRIES*/ )
517
 
                                        {
518
 
                                                //QApplication::eventLoop()->processEvents (QEventLoop::AllEvents, MAX_EVENT_PROC_TIME);
519
 
                                                i = 0;
520
 
                                        }
521
 
                                        else
522
 
                                        {
523
 
                                                printf( "readFromServer: read(...) failed\n" );
524
 
                                                closeConnection();
525
 
                                                return( FALSE );
526
 
                                        }
527
 
                                }
528
 
                                else
529
 
                                {
530
 
                                        printf( "VNC server closed connection\n" );
531
 
                                        closeConnection();
532
 
                                        return( FALSE );
533
 
                                }
534
 
                        }
535
 
                        m_buffered += i;
536
 
                }
537
 
 
538
 
                memcpy( _out, m_bufOutPtr, _n );
539
 
                m_bufOutPtr += _n;
540
 
                m_buffered -= _n;
541
 
        }
542
 
        else
543
 
        {
544
 
                while( _n > 0 )
545
 
                {
546
 
                        int i = read( m_sock, _out, _n );
547
 
                        if( i <= 0 )
548
 
                        {
549
 
                                if( i < 0 )
550
 
                                {
551
 
                                        if( ( errno == EWOULDBLOCK || errno == EAGAIN )/* && ++retries < MAX_READ_RETRIES*/ )
552
 
                                        {
553
 
                                                //QApplication::eventLoop()->processEvents (QEventLoop::AllEvents, MAX_EVENT_PROC_TIME);
554
 
                                                i = 0;
555
 
                                        }
556
 
                                        else
557
 
                                        {
558
 
                                                printf( "readFromServer: read(...) failed\n" );
559
 
                                                closeConnection();
560
 
                                                return( FALSE );
561
 
                                        }
562
 
                                }
563
 
                                else
564
 
                                {
565
 
                                        printf( "VNC server closed connection\n" );
566
 
                                        closeConnection();
567
 
                                        return( FALSE );
568
 
                                }
569
 
                        }
570
 
                        _out += i;
571
 
                        _n -= i;
572
 
                }
573
 
        }
574
 
 
575
 
        return( TRUE );
576
 
}
577
 
 
578
 
 
579
 
 
580
 
 
581
 
bool rfbConnection::writeToServer( const char * _buf, unsigned int _n )
582
 
{
583
 
        unsigned int i = 0;
584
 
        while( i < _n )
585
 
        {
586
 
                int j = write( m_sock, _buf + i, _n - i );
587
 
                if( j <= 0 )
588
 
                {
589
 
                        printf( "error while writing!\n" );
590
 
                        if( j < 0 )
591
 
                        {
592
 
                                if( errno == EWOULDBLOCK || errno == EAGAIN )
593
 
                                {
594
 
                                        fd_set fds;
595
 
                                        FD_ZERO( &fds );
596
 
                                        FD_SET( m_sock, &fds );
597
 
                                        if( select( m_sock+1, NULL, &fds, NULL, NULL ) <= 0 )
598
 
                                        {
599
 
                                                printf( "writeToServer: select(..) failed\n" );
600
 
                                                closeConnection();
601
 
                                                return( FALSE );
602
 
                                        }
603
 
                                        j = 0;
604
 
                                }
605
 
                                else
606
 
                                {
607
 
                                        printf( "writeToServer: write(..) failed (j < 0)\n" );
608
 
                                        closeConnection();
609
 
                                        return( FALSE );
610
 
                                }
611
 
                        }
612
 
                        else
613
 
                        {
614
 
                                printf( "writeToServer: write(..) failed (j == 0)\n" );
615
 
                                closeConnection();
616
 
                                return( FALSE );
617
 
                        }
618
 
                }
619
 
                i += j;
620
 
        }
621
 
 
622
 
        return( TRUE );
623
 
}
624
 
 
625
 
 
626
 
 
627
 
 
628
 
long rfbConnection::readCompactLen( void )
629
 
{
630
 
        Q_UINT8 b;
631
 
 
632
 
        if( !readFromServer( (char *)&b, sizeof( b ) ) )
633
 
        {
634
 
                return( -1 );
635
 
        }
636
 
 
637
 
        long len = (int)b & 0x7F;
638
 
        if( b & 0x80 )
639
 
        {
640
 
                if( !readFromServer( (char *)&b, sizeof( b ) ) )
641
 
                {
642
 
                        return( -1 );
643
 
                }
644
 
                len |= ((int)b & 0x7F) << 7;
645
 
                if( b & 0x80 )
646
 
                {
647
 
                        if( !readFromServer( (char *)&b, 1 ) )
648
 
                        {
649
 
                                return( -1 );
650
 
                        }
651
 
                        len |= ((int)b & 0xFF) << 14;
652
 
                }
653
 
        }
654
 
 
655
 
        return( len );
656
 
}
657
 
 
658
 
 
659
 
 
660
 
 
661
 
bool rfbConnection::sendFramebufferUpdateRequest( void )
662
 
{
663
 
        return( sendFramebufferUpdateRequest( 0, 0, m_si.framebuffer_width, m_si.framebuffer_height, FALSE ) );
664
 
}
665
 
 
666
 
 
667
 
 
668
 
 
669
 
bool rfbConnection::sendIncrementalFramebufferUpdateRequest( void )
670
 
{
671
 
        return( sendFramebufferUpdateRequest( 0, 0, m_si.framebuffer_width, m_si.framebuffer_height, TRUE ) );
672
 
}
673
 
 
674
 
 
675
 
 
676
 
 
677
 
bool rfbConnection::sendFramebufferUpdateRequest( Q_UINT16 _x, Q_UINT16 _y, Q_UINT16 _w, Q_UINT16 _h, bool _incremental )
678
 
{
679
 
        s_rfb_framebuffer_update_request_msg fur;
680
 
 
681
 
        fur.type = RFB_FRAMEBUFFER_UPDATE_REQUEST;
682
 
        fur.incremental = (_incremental == TRUE)? 1 : 0;
683
 
        fur.x = Swap16IfLE( _x );
684
 
        fur.y = Swap16IfLE( _y );
685
 
        fur.w = Swap16IfLE( _w );
686
 
        fur.h = Swap16IfLE( _h );
687
 
 
688
 
        return( writeToServer( (char *) &fur, sizeof( fur ) ) );
689
 
}
690
 
 
691
 
 
692
 
 
693
 
 
694
 
bool rfbConnection::sendPointerEvent( Q_UINT16 _x, Q_UINT16 _y, Q_UINT16 _button_mask )
695
 
{
696
 
        s_rfb_pointer_event_msg pe;
697
 
 
698
 
        pe.type = RFB_POINTER_EVENT;
699
 
        pe.button_mask = _button_mask;
700
 
        //if (_x < 0) _x = 0;
701
 
        //if (_y < 0) _y = 0;
702
 
        pe.x = Swap16IfLE( _x );
703
 
        pe.y = Swap16IfLE( _y );
704
 
 
705
 
        return( writeToServer( (char *) &pe, sizeof( pe ) ) );
706
 
}
707
 
 
708
 
 
709
 
 
710
 
 
711
 
bool rfbConnection::sendKeyEvent( Q_UINT32 key, bool down )
712
 
{
713
 
        s_rfb_key_event_msg ke;
714
 
 
715
 
        ke.type = RFB_KEY_EVENT;
716
 
        ke.down = (down == TRUE)? 1 : 0;
717
 
        ke.key = Swap32IfLE( key );
718
 
 
719
 
        return( writeToServer( (char *) &ke, sizeof( ke ) ) );
720
 
}
721
 
 
722
 
 
723
 
 
724
 
 
725
 
bool rfbConnection::sendGetUserRequest( void )
726
 
{
727
 
        if( !connected() )
728
 
        {
729
 
                return( FALSE );
730
 
        }
731
 
 
732
 
        s_rfb_get_user_msg gu;
733
 
        gu.cmd = RFB_ITALC_TO_SERVER_REQUEST;
734
 
        gu.italc_cmd = ITALC_GET_USER;
735
 
 
736
 
        return( writeToServer( (char *) &gu, sizeof( gu ) ) );
737
 
}
738
 
 
739
 
 
740
 
 
741
 
 
742
 
bool rfbConnection::execCmds( const QString & _cmd )
743
 
{
744
 
        if( !connected() )
745
 
        {
746
 
                return( FALSE );
747
 
        }
748
 
 
749
 
        s_rfb_exec_cmds_msg ec;
750
 
        ec.cmd = RFB_ITALC_TO_SERVER_REQUEST;
751
 
        ec.italc_cmd = ITALC_EXEC_CMDS;
752
 
        ec.cmd_len = Swap16IfLE( _cmd.length()+1 );
753
 
 
754
 
        if( !writeToServer( (char *) &ec, sizeof( ec ) ) )
755
 
        {
756
 
                printf( "Could not send ITALC_EXEC_CMDS-request to client\n" );
757
 
                return( FALSE);
758
 
        }
759
 
 
760
 
        return( writeToServer( _cmd.ascii(), _cmd.length()+1 ) );
761
 
}
762
 
 
763
 
 
764
 
 
765
 
 
766
 
bool rfbConnection::startDemo( const QString & _master_ip, bool _full_screen )
767
 
{
768
 
        if( !connected() )
769
 
        {
770
 
                return( FALSE );
771
 
        }
772
 
 
773
 
        s_rfb_start_demo_msg sd;
774
 
        sd.cmd = RFB_ITALC_TO_SERVER_REQUEST;
775
 
        sd.italc_cmd = ITALC_START_DEMO;
776
 
        sd.fullscreen = (_full_screen)? !0 : 0;
777
 
        sd.demo_master_ip_len = Swap16IfLE( _master_ip.length()+1 );
778
 
        if( !writeToServer( (char *) &sd, sizeof( sd ) ) )
779
 
        {
780
 
                printf( "Could not send ITALC_START_DEMO-request to client\n" );
781
 
                return( FALSE );
782
 
        }
783
 
 
784
 
        return( writeToServer( _master_ip.ascii(), _master_ip.length()+1 ) );
785
 
}
786
 
 
787
 
 
788
 
 
789
 
 
790
 
bool rfbConnection::stopDemo( void )
791
 
{
792
 
        if( !connected() )
793
 
        {
794
 
                return( FALSE );
795
 
        }
796
 
 
797
 
        s_rfb_stop_demo_msg sd;
798
 
        sd.cmd = RFB_ITALC_TO_SERVER_REQUEST;
799
 
        sd.italc_cmd = ITALC_STOP_DEMO;
800
 
 
801
 
        return( writeToServer( (char *) &sd, sizeof( sd ) ) );
802
 
}
803
 
 
804
 
 
805
 
 
806
 
 
807
 
bool rfbConnection::lockDisplay( void )
808
 
{
809
 
        if( !connected() )
810
 
        {
811
 
                return( FALSE );
812
 
        }
813
 
 
814
 
        s_rfb_lock_display_msg ld;
815
 
        ld.cmd = RFB_ITALC_TO_SERVER_REQUEST;
816
 
        ld.italc_cmd = ITALC_LOCK_DISPLAY;
817
 
 
818
 
        return( writeToServer( (char *) &ld, sizeof( ld ) ) );
819
 
}
820
 
 
821
 
 
822
 
 
823
 
 
824
 
bool rfbConnection::unlockDisplay( void )
825
 
{
826
 
        if( !connected() )
827
 
                return( FALSE );
828
 
 
829
 
        s_rfb_unlock_display_msg ud;
830
 
        ud.cmd = RFB_ITALC_TO_SERVER_REQUEST;
831
 
        ud.italc_cmd = ITALC_UNLOCK_DISPLAY;
832
 
 
833
 
        return( writeToServer( (char *) &ud, sizeof( ud ) ) );
834
 
}
835
 
 
836
 
 
837
 
 
838
 
 
839
 
bool rfbConnection::sendMessage( const QString & _msg )
840
 
{
841
 
        if( !connected() )
842
 
        {
843
 
                return( FALSE );
844
 
        }
845
 
 
846
 
        s_rfb_send_msg_msg sm;
847
 
        sm.cmd = RFB_ITALC_TO_SERVER_REQUEST;
848
 
        sm.italc_cmd = ITALC_SEND_MSG;
849
 
        sm.msg_len = Swap16IfLE( _msg.length()+1 );
850
 
 
851
 
        if( !writeToServer( (char *) &sm, sizeof( sm ) ) )
852
 
        {
853
 
                printf( "Could not send ITALC_SEND_MSG-request to client\n" );
854
 
                return( FALSE );
855
 
        }
856
 
 
857
 
        return( writeToServer( _msg.ascii(), _msg.length()+1 ) );
858
 
}
859
 
 
860
 
 
861
 
 
862
 
 
863
 
bool rfbConnection::postFile( const QString & _fname )
864
 
{
865
 
/*
866
 
        if (!connected() || QFileInfo(_fname).exists() == FALSE || QFileInfo(_fname).isReadable() == FALSE)
867
 
                return (FALSE);
868
 
 
869
 
        Q_UINT32 fsize = QFileInfo(_fname).size();
870
 
        if (fsize == 0)
871
 
                return (FALSE);
872
 
 
873
 
        QString realFileName = QFileInfo(_fname).fileName();
874
 
 
875
 
        s_rfb_post_file_msg pf;
876
 
        pf.cmd = RFB_ITALC_TO_SERVER_REQUEST;
877
 
        pf.italc_cmd = ITALC_POST_FILE_REQ;
878
 
        pf.fname_len = Swap16IfLE(realFileName.length()+1);
879
 
        pf.fsize = Swap32IfLE(fsize);
880
 
 
881
 
        if (!writeToServer((char *) &pf, sizeof(pf))) {
882
 
                printf ("Could not send ITALC_POST_FILE_REQ-request to client\n");
883
 
                return (FALSE);
884
 
        }
885
 
 
886
 
        if (!writeToServer(realFileName.ascii(), realFileName.length()+1)) {
887
 
                printf ("Could not send file-name to client\n");
888
 
                return (FALSE);
889
 
        }
890
 
 
891
 
        QFile f (_fname);
892
 
        f.open (IO_ReadOnly);
893
 
        Q_UINT32 processed = 0;
894
 
 
895
 
        while (processed < fsize) {
896
 
                const int BUF_SIZE = 1024;
897
 
                char m_buffer[BUF_SIZE];
898
 
                Q_LONG read = f.readBlock (m_buffer, BUF_SIZE);
899
 
                if (read > 0) {
900
 
                        if (!writeToServer(m_buffer, read)) {
901
 
                                printf ("Could not send file-content to client (%d of %d bytes already sent)\n", (int) processed, (int) fsize);
902
 
                                return (FALSE);
903
 
                        }
904
 
                        processed += read;
905
 
                } else if (read < 0) {
906
 
                        printf ("An error occured while reading file (%d of %d bytes already sent)\n", (int) processed, (int) fsize);
907
 
                        return (FALSE);
908
 
                }
909
 
                usleep(25);     // avoid m_buffer-overflow in client's TCP/IP-m_buffer...
910
 
        }
911
 
 
912
 
        return (TRUE);
913
 
*/
914
 
}
915
 
 
916
 
 
917
 
 
918
 
 
919
 
bool rfbConnection::getFile( const QString & _nfilter )
920
 
{
921
 
/*      if (!connected())
922
 
                return (FALSE);
923
 
 
924
 
        s_rfb_get_file_msg gf;
925
 
        gf.cmd = RFB_ITALC_TO_SERVER_REQUEST;
926
 
        gf.italc_cmd = ITALC_GET_FILE;
927
 
        gf.fmask_len = Swap16IfLE(_nfilter.length()+1);
928
 
 
929
 
        if (!writeToServer((char *) &gf, sizeof(gf))) {
930
 
                printf ("Could not send ITALC_GET_FILE-request to client\n");
931
 
                return (FALSE);
932
 
        }
933
 
 
934
 
        return (writeToServer(_nfilter.ascii(), _nfilter.length()+1));
935
 
*/
936
 
}
937
 
 
938
 
 
939
 
 
940
 
 
941
 
bool rfbConnection::inviteForSupport( const QString & _user_name )
942
 
{
943
 
        if( !connected() )
944
 
        {
945
 
                return( FALSE );
946
 
        }
947
 
 
948
 
        s_rfb_invite_support_msg is;
949
 
        is.cmd = RFB_ITALC_TO_SERVER_REQUEST;
950
 
        is.italc_cmd = ITALC_INVITE_SUPPORT;
951
 
        is.uname_len = Swap16IfLE( _user_name.length()+1 );
952
 
 
953
 
        if( !writeToServer( (char *) &is, sizeof( is ) ) )
954
 
        {
955
 
                printf( "Could not send ITALC_INVITE_SUPPORT-request to client\n" );
956
 
                return( FALSE );
957
 
        }
958
 
 
959
 
        if( !writeToServer( _user_name.ascii(), _user_name.length()+1 ) )
960
 
        {
961
 
                printf( "Could not write user-name to client\n" );
962
 
                return( FALSE );
963
 
        }
964
 
 
965
 
        m_gotInvitationResult = FALSE;
966
 
        m_invitationOk = FALSE;
967
 
 
968
 
        while( m_gotInvitationResult == FALSE && handleServerMessages( FALSE ) == TRUE )
969
 
        {
970
 
        }
971
 
 
972
 
        // return result, if error occured while handling server-messages, m_invitationOk is untouched -> FALSE
973
 
        return( m_invitationOk );
974
 
}
975
 
 
976
 
 
977
 
 
978
 
 
979
 
bool rfbConnection::handleServerMessages( bool _send_screen_update )
980
 
{
981
 
        u_rfb_server_to_client_msg msg;
982
 
 
983
 
        while( dataFromServer() == TRUE )
984
 
        {
985
 
 
986
 
        if( !readFromServer( (char *) &msg, sizeof( Q_UINT8 ) ) )
987
 
        {
988
 
                printf( "Reading of message-type failed\n" );
989
 
                return( FALSE );
990
 
        }
991
 
 
992
 
        switch( msg.type )
993
 
        {
994
 
                case RFB_SET_COLORMAP_ENTRIES:
995
 
                        printf( "Got signal for setting colormap entries. Ignoring.\n" );
996
 
                        break;
997
 
 
998
 
                case RFB_FRAMEBUFFER_UPDATE:
999
 
                {
1000
 
                        if( !readFromServer( ( (char *)&msg.fu ) + 1, sizeof( s_rfb_framebuffer_update_msg )- 1 ) )
1001
 
                        {
1002
 
                                return( FALSE );
1003
 
                        }
1004
 
 
1005
 
                        msg.fu.n_rects = Swap16IfLE( msg.fu.n_rects );
1006
 
 
1007
 
                        s_rfb_framebuffer_update_rect_header rect;
1008
 
                        for( Q_UINT16 i = 0; i < msg.fu.n_rects; i++ )
1009
 
                        {
1010
 
                                if( !readFromServer( (char *)&rect, sizeof( s_rfb_framebuffer_update_rect_header ) ) )
1011
 
                                {
1012
 
                                        return( FALSE );
1013
 
                                }
1014
 
 
1015
 
                                rect.r.x = Swap16IfLE( rect.r.x );
1016
 
                                rect.r.y = Swap16IfLE( rect.r.y );
1017
 
                                rect.r.w = Swap16IfLE( rect.r.w );
1018
 
                                rect.r.h = Swap16IfLE( rect.r.h );
1019
 
 
1020
 
                                rect.encoding = Swap32IfLE( rect.encoding );
1021
 
                                if( rect.encoding == RFB_ENCODING_LAST_RECT )
1022
 
                                {
1023
 
                                        break;
1024
 
                                }
1025
 
 
1026
 
                                if( ( rect.r.x + rect.r.w > m_si.framebuffer_width ) ||
1027
 
                                    ( rect.r.y + rect.r.h > m_si.framebuffer_height ) )
1028
 
                                {
1029
 
                                        printf( "Rect too large: %dx%d at (%d, %d)\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y );
1030
 
                                        return( FALSE );
1031
 
                                }
1032
 
 
1033
 
                                if( ( rect.r.h * rect.r.w ) == 0 )
1034
 
                                {
1035
 
                                        printf( "Zero size rect - ignoring\n" );
1036
 
                                        continue;
1037
 
                                }
1038
 
 
1039
 
                                switch( rect.encoding )
1040
 
                                {
1041
 
                                        case RFB_ENCODIG_RAW:
1042
 
                                        {
1043
 
                                                Q_UINT16 bytes_per_line = rect.r.w * (s_localDisplayFormat.bits_per_pixel/8);
1044
 
                                                Q_UINT16 lines_to_read = (Q_UINT16) (BUFFER_SIZE / bytes_per_line);
1045
 
                                                while( rect.r.h > 0 )
1046
 
                                                {
1047
 
                                                        if( lines_to_read > rect.r.h )
1048
 
                                                        {
1049
 
                                                                lines_to_read = rect.r.h;
1050
 
                                                        }
1051
 
                                                        if( !readFromServer( m_buffer, bytes_per_line * lines_to_read ) )
1052
 
                                                        {
1053
 
                                                                return (FALSE);
1054
 
                                                        }
1055
 
                                                        QRgb * src = (QRgb *) m_buffer;
1056
 
                                                        Q_UINT16 x2 = rect.r.x+rect.r.w;
1057
 
                                                        for( Q_UINT16 y = 0; y < lines_to_read; y++ )
1058
 
                                                        {
1059
 
                                                                QRgb * dest = (QRgb *)m_clientScreen.scanLine( rect.r.y+y );
1060
 
                                                                for( Q_UINT16 x = rect.r.x; x < x2; ++x )
1061
 
                                                                {
1062
 
                                                                        dest[x] = *src;
1063
 
                                                                        ++src;
1064
 
                                                                }
1065
 
                                                        }
1066
 
                                                        rect.r.h -= lines_to_read;
1067
 
                                                        rect.r.y += lines_to_read;
1068
 
                                                }
1069
 
                                                break;
1070
 
                                        }
1071
 
                                        case RFB_ENCODING_COPYRECT:
1072
 
                                        {
1073
 
                                                s_rfb_copy_rect cr;
1074
 
                                                if( !readFromServer( (char *) &cr, sizeof( s_rfb_copy_rect ) ) )
1075
 
                                                {
1076
 
                                                        return( FALSE );
1077
 
                                                }
1078
 
                                                cr.src_x = Swap16IfLE( cr.src_x );
1079
 
                                                cr.src_y = Swap16IfLE( cr.src_y );
1080
 
 
1081
 
                                                copyExistingRect( m_clientScreen, cr.src_x, cr.src_y, rect.r.w, rect.r.h, rect.r.x, rect.r.y );
1082
 
                                                printf( "copy rect - should not occur!!\n" );
1083
 
                                                break;
1084
 
                                        }
1085
 
                                        case RFB_ENCODIG_RRE:
1086
 
                                        {
1087
 
                                                if( !handleRRE( rect.r.x, rect.r.y, rect.r.w, rect.r.h ) )
1088
 
                                                {
1089
 
                                                        return( FALSE );
1090
 
                                                }
1091
 
                                                break;
1092
 
                                        }
1093
 
                                        case RFB_ENCODING_CORRE:
1094
 
                                        {
1095
 
                                                if( !handleCoRRE( rect.r.x, rect.r.y, rect.r.w, rect.r.h ) )
1096
 
                                                {
1097
 
                                                        return( FALSE );
1098
 
                                                }
1099
 
                                                break;
1100
 
                                        }
1101
 
#ifdef HAVE_LIBZ
1102
 
#ifdef HAVE_LIBJPEG
1103
 
                                        case RFB_ENCODING_TIGHT:
1104
 
                                        {
1105
 
                                                if( !handleTight( rect.r.x, rect.r.y, rect.r.w, rect.r.h ) )
1106
 
                                                {
1107
 
                                                                return( FALSE );
1108
 
                                                }
1109
 
                                                break;
1110
 
                                        }
1111
 
#endif
1112
 
#endif
1113
 
                                        default:
1114
 
                                                printf( "Unknown rect encoding %d\n", (int) rect.encoding );
1115
 
                                                return( FALSE);
1116
 
                                }
1117
 
                        }
1118
 
 
1119
 
                        if( m_destImgSize.width() > 0 && m_destImgSize.height() > 0 )
1120
 
                        {
1121
 
                                // first create temporary image whose size matches destination-image-size
1122
 
                                QImage temporary_image = QImage( m_destImgSize, s_localDisplayFormat.depth );
1123
 
                                // now scale the image and store the output to temporary_image
1124
 
                                fastScaleImage( m_clientScreen, temporary_image );
1125
 
                                // now copy temporary_image to scaled client-screen
1126
 
                                //qApp->lock();
1127
 
                                m_scaledClientScreen = temporary_image;
1128
 
                                //qApp->unlock();
1129
 
                        }
1130
 
                        break;
1131
 
                }
1132
 
                case RFB_BELL:
1133
 
                        // FIXME: bell-action
1134
 
                        break;
1135
 
 
1136
 
                case RFB_SERVER_CUT_TEXT:
1137
 
                {
1138
 
                        if( !readFromServer( ( (char *) &msg ) + 1, sizeof( s_rfb_server_cut_text_msg ) - 1 ) )
1139
 
                        {
1140
 
                                return( FALSE );
1141
 
                        }
1142
 
                        msg.sct.length = Swap32IfLE( msg.sct.length );
1143
 
                        char server_cut_text[msg.sct.length+1];
1144
 
                        if( !readFromServer( server_cut_text, msg.sct.length ) )
1145
 
                        {
1146
 
                                return( FALSE );
1147
 
                        }
1148
 
                        //server_cut_text[msg.sct.length] = 0;
1149
 
                        //printf ("Server-Cut-Text: %s\n", server_cut_text);
1150
 
                        break;
1151
 
                }
1152
 
 
1153
 
                case RFB_SERVER_TO_ITALC_RESPONSE:
1154
 
                {
1155
 
                        s_rfb_server_response sr;
1156
 
                        if( !readFromServer( (char *) &sr.italc_cmd, sizeof( sr.italc_cmd ) ) )
1157
 
                        {
1158
 
                                return( FALSE );
1159
 
                        }
1160
 
                        switch( sr.cmd )
1161
 
                        {
1162
 
                                case ITALC_POST_USER:
1163
 
                                {
1164
 
                                        if( !readFromServer( ( (char *) &sr ) + 2, sizeof( s_rfb_post_user_msg )-2 ) )
1165
 
                                        {
1166
 
                                                return( FALSE );
1167
 
                                        }
1168
 
                                        sr.post_user_msg.user_name_len = Swap16IfLE( sr.post_user_msg.user_name_len );
1169
 
                                        char * user_name = new char[sr.post_user_msg.user_name_len];
1170
 
                                        if( !readFromServer( user_name, sr.post_user_msg.user_name_len ) )
1171
 
                                        {
1172
 
                                                delete[] user_name;
1173
 
                                                return( FALSE );
1174
 
                                        }
1175
 
                                        m_user = user_name;
1176
 
                                        delete[] user_name;
1177
 
                                        break;
1178
 
                                }
1179
 
                                case ITALC_INVITATION_RESULT:
1180
 
                                {
1181
 
                                        if( !readFromServer( ( (char *) &sr ) + 2, sizeof( s_rfb_invitation_result_msg ) - 2 ) )
1182
 
                                        {
1183
 
                                                return( FALSE );
1184
 
                                        }
1185
 
                                        m_invitationOk = sr.invitation_result_msg.inv_accepted;
1186
 
                                        m_gotInvitationResult = TRUE;
1187
 
                                        break;
1188
 
                                }
1189
 
/*                              case ITALC_POST_FILE_RESP: {
1190
 
                                        if (!readFromServer(((char *) &sr)+2, sizeof(s_rfb_post_file_msg)-2))
1191
 
                                                return (FALSE);
1192
 
                                        sr.post_file_msg.fname_len = Swap16IfLE(sr.post_file_msg.fname_len);
1193
 
                                        sr.post_file_msg.fsize = Swap32IfLE(sr.post_file_msg.fsize);
1194
 
                                        char * file_name = new char[sr.post_file_msg.fname_len];
1195
 
                                        if (!readFromServer(file_name, sr.post_file_msg.fname_len)) {
1196
 
                                                delete[] file_name;
1197
 
                                                return (FALSE);
1198
 
                                        }
1199
 
                                        system ("mkdir -p ~/collected_files/"+m_user);
1200
 
                                        int fd = open(QString(getenv("HOME"))+"/collected_files/"+m_user+"/"+QFileInfo(file_name).fileName(), O_CREAT|O_WRONLY, 0666);
1201
 
                                        Q_UINT32 total_bytes = sr.post_file_msg.fsize;
1202
 
                                        Q_UINT32 bytes_done = 0;
1203
 
                                        while (bytes_done < total_bytes) {
1204
 
                                                char m_buffer[BUFFER_SIZE];
1205
 
                                                Q_UINT32 bytes_todo = BUFFER_SIZE;
1206
 
                                                if (total_bytes - bytes_done < bytes_todo)
1207
 
                                                        bytes_todo = total_bytes - bytes_done;
1208
 
                                                if (!readFromServer(m_buffer, bytes_todo)) {
1209
 
                                                        close (fd);
1210
 
                                                        delete[] file_name;
1211
 
                                                        return (FALSE);
1212
 
                                                }
1213
 
                                                if (fd > 0)
1214
 
                                                        write(fd, m_buffer, bytes_todo);
1215
 
                                                bytes_done += bytes_todo;
1216
 
                                        }
1217
 
                                        close (fd);
1218
 
                                        delete[] file_name;
1219
 
                                        break;
1220
 
                                }*/
1221
 
                                default:
1222
 
                                        printf( "Unknown server response %d\n", (int) sr.cmd );
1223
 
                                        return( FALSE );
1224
 
                        }
1225
 
                        break;
1226
 
                }
1227
 
 
1228
 
                default:
1229
 
                        printf( "Unknown message type %d from VNC server. Closing connection. Will re-open it later.\n", msg.type );
1230
 
                        closeConnection();
1231
 
                        return( FALSE );
1232
 
        }
1233
 
 
1234
 
        }       // end while( ... )
1235
 
 
1236
 
 
1237
 
        if( _send_screen_update )
1238
 
        {
1239
 
                if( !sendIncrementalFramebufferUpdateRequest() )
1240
 
                {
1241
 
                        return( FALSE );
1242
 
                }
1243
 
        }
1244
 
 
1245
 
        return( TRUE );
1246
 
}
1247
 
 
1248
 
 
1249
 
 
1250
 
 
1251
 
 
1252
 
 
1253
 
 
1254
 
 
1255
 
 
1256
 
// ========================================================================================================================
1257
 
// functions for network-IO
1258
 
// ========================================================================================================================
1259
 
 
1260
 
 
1261
 
int rfbConnection::connectToTCPAddr( in_addr_t _host, int _port )
1262
 
{
1263
 
        struct sockaddr_in addr;
1264
 
        int one = 1;
1265
 
 
1266
 
        addr.sin_family = AF_INET;
1267
 
        addr.sin_port = htons(_port);
1268
 
        addr.sin_addr.s_addr = _host;
1269
 
        int m_sock = socket(AF_INET, SOCK_STREAM, 0);
1270
 
        if( m_sock < 0 )
1271
 
        {
1272
 
                printf( "connectToTCPAdress: socket(...) failed\n" );
1273
 
                return( -1 );
1274
 
        }
1275
 
 
1276
 
        if( ::connect( m_sock, ( struct sockaddr * )&addr, sizeof( addr ) ) < 0 )
1277
 
        {
1278
 
                //printf ("connectToTCPAdress: connect(...) failed\n");
1279
 
                close( m_sock );
1280
 
                return( -1 );
1281
 
        }
1282
 
 
1283
 
        if( setsockopt( m_sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof( one ) ) < 0 )
1284
 
        {
1285
 
                printf( "connectToTCPAdress: setsockopt(...) failed\n" );
1286
 
                close( m_sock );
1287
 
                return( -1 );
1288
 
        }
1289
 
 
1290
 
        return( m_sock );
1291
 
}
1292
 
 
1293
 
 
1294
 
 
1295
 
 
1296
 
 
1297
 
 
1298
 
bool rfbConnection::stringToIPAddr( const QString & _host, in_addr_t * _addr )
1299
 
{
1300
 
        if( _host == "" )
1301
 
        {
1302
 
                *_addr = 0;     // local
1303
 
                return( TRUE );
1304
 
        }
1305
 
 
1306
 
        *_addr = inet_addr( _host.ascii() );
1307
 
 
1308
 
        if( *_addr != (in_addr_t) -1 )
1309
 
        {
1310
 
                return( TRUE );
1311
 
        }
1312
 
 
1313
 
        struct hostent * hp = gethostbyname( _host.ascii() );
1314
 
 
1315
 
        if( hp )
1316
 
        {
1317
 
                *_addr = *(in_addr_t *)hp->h_addr;
1318
 
                return( TRUE );
1319
 
        }
1320
 
 
1321
 
        return( FALSE );
1322
 
}
1323
 
 
1324
 
 
1325
 
 
1326
 
 
1327
 
// ========================================================================================================================
1328
 
// functions for decoding rects
1329
 
// ========================================================================================================================
1330
 
 
1331
 
 
1332
 
bool rfbConnection::handleCoRRE( Q_UINT16 rx, Q_UINT16 ry, Q_UINT16 rw, Q_UINT16 rh )
1333
 
{
1334
 
        s_rfb_RRE_header hdr;
1335
 
 
1336
 
        if( !readFromServer( (char *) &hdr, sizeof( s_rfb_RRE_header ) ) )
1337
 
        {
1338
 
                return( FALSE );
1339
 
        }
1340
 
 
1341
 
        hdr.n_subrects = Swap32IfLE( hdr.n_subrects );
1342
 
 
1343
 
        QRgb pix;
1344
 
        if( !readFromServer( (char *) &pix, sizeof( pix ) ) )
1345
 
        {
1346
 
                return( FALSE );
1347
 
        }
1348
 
 
1349
 
        fillRect( m_clientScreen, rx, ry, rw, rh, pix );
1350
 
 
1351
 
        if( !readFromServer( m_buffer, hdr.n_subrects * ( sizeof( s_rfb_CoRRE_rectangle ) + sizeof( Q_UINT32 ) ) ) )
1352
 
        {
1353
 
                return( FALSE );
1354
 
        }
1355
 
 
1356
 
        Q_UINT8 * ptr = (Q_UINT8 *) m_buffer;
1357
 
 
1358
 
        for( Q_UINT32 i = 0; i < hdr.n_subrects; i++ )
1359
 
        {
1360
 
                pix = *(QRgb *) ptr;
1361
 
                ptr += sizeof( pix );
1362
 
                Q_UINT8 x = *ptr++;
1363
 
                Q_UINT8 y = *ptr++;
1364
 
                Q_UINT8 w = *ptr++;
1365
 
                Q_UINT8 h = *ptr++;
1366
 
                fillRect( m_clientScreen, rx+x, ry+y, w, h, pix );
1367
 
        }
1368
 
 
1369
 
        return( TRUE );
1370
 
}
1371
 
 
1372
 
 
1373
 
 
1374
 
bool rfbConnection::handleRRE( Q_UINT16, Q_UINT16, Q_UINT16, Q_UINT16 )
1375
 
{
1376
 
        printf ("Fatal: Got RRE-encoded rect. Can't decode.\n");
1377
 
        return( TRUE );
1378
 
}
1379
 
 
1380
 
 
1381
 
#ifdef HAVE_LIBZ
1382
 
 
1383
 
#define TIGHT_MIN_TO_COMPRESS 12
1384
 
 
1385
 
 
1386
 
#define RGB_TO_PIXEL(r,g,b)                                                                     \
1387
 
  (((Q_UINT32)(r) & s_localDisplayFormat.red_max) << s_localDisplayFormat.red_shift |           \
1388
 
   ((Q_UINT32)(g) & s_localDisplayFormat.green_max) << s_localDisplayFormat.green_shift |       \
1389
 
   ((Q_UINT32)(b) & s_localDisplayFormat.blue_max) << s_localDisplayFormat.blue_shift)
1390
 
 
1391
 
 
1392
 
 
1393
 
// type declarations
1394
 
 
1395
 
typedef void (rfbConnection:: *filterPtr) (Q_UINT16, Q_UINT32 *);
1396
 
 
1397
 
 
1398
 
 
1399
 
// Definitions
1400
 
 
1401
 
bool rfbConnection::handleTight( Q_UINT16 rx, Q_UINT16 ry, Q_UINT16 rw, Q_UINT16 rh )
1402
 
{
1403
 
        QRgb fill_color;
1404
 
        Q_UINT8 comp_ctl;
1405
 
 
1406
 
        if( !readFromServer( (char *) &comp_ctl, 1 ) )
1407
 
        {
1408
 
                return( FALSE );
1409
 
        }
1410
 
 
1411
 
        // Flush zlib streams if we are told by the server to do so.
1412
 
        for( Q_UINT8 stream_id = 0; stream_id < 4; stream_id++ )
1413
 
        {
1414
 
                if( ( comp_ctl & 1 ) && m_zlibStreamActive[stream_id] )
1415
 
                {
1416
 
                        if( inflateEnd( &m_zlibStream[stream_id] ) != Z_OK && m_zlibStream[stream_id].msg != NULL )
1417
 
                        {
1418
 
                                printf( "inflateEnd: %s\n", m_zlibStream[stream_id].msg );
1419
 
                        }
1420
 
                        m_zlibStreamActive[stream_id] = FALSE;
1421
 
                }
1422
 
                comp_ctl >>= 1;
1423
 
        }
1424
 
 
1425
 
        // Handle solid rectangles.
1426
 
        if( comp_ctl == RFB_TIGHT_FILL )
1427
 
        {
1428
 
                if( !readFromServer( (char*)&fill_color, sizeof( fill_color ) ) )
1429
 
                {
1430
 
                        return( FALSE );
1431
 
                }
1432
 
                fillRect( m_clientScreen, rx, ry, rw, rh, fill_color );
1433
 
                return( TRUE );
1434
 
        }
1435
 
 
1436
 
        if( comp_ctl == RFB_TIGHT_JPEG )
1437
 
        {
1438
 
#ifdef HAVE_LIBJPEG
1439
 
                return( decompressJpegRect( rx, ry, rw, rh ) );
1440
 
#else
1441
 
                return ( -1 );
1442
 
#endif
1443
 
        }
1444
 
 
1445
 
 
1446
 
        // Quit on unsupported subencoding value.
1447
 
        if( comp_ctl > RFB_TIGHT_MAX_SUBENCODING )
1448
 
        {
1449
 
                printf( "Tight encoding: bad subencoding value received.\n" );
1450
 
                return( FALSE );
1451
 
        }
1452
 
 
1453
 
        // Here primary compression mode handling begins.
1454
 
        // Data was processed with optional filter + zlib compression.
1455
 
        filterPtr filter_function;
1456
 
        Q_UINT8 bits_pixel;
1457
 
 
1458
 
        // First, we should identify a filter to use.
1459
 
        if( ( comp_ctl & RFB_TIGHT_EXPLICIT_FILTER ) != 0 )
1460
 
        {
1461
 
                Q_UINT8 filter_id;
1462
 
                if( !readFromServer( (char*) &filter_id, 1 ) )
1463
 
                {
1464
 
                        return( FALSE );
1465
 
                }
1466
 
 
1467
 
                switch( filter_id )
1468
 
                {
1469
 
                        case RFB_TIGHT_FILTER_COPY:
1470
 
                                filter_function = &rfbConnection::filterCopy;
1471
 
                                bits_pixel = initFilterCopy( rw, rh );
1472
 
                                break;
1473
 
                        case RFB_TIGHT_FILTER_PALETTE:
1474
 
                                filter_function = &rfbConnection::filterPalette;
1475
 
                                bits_pixel = initFilterPalette( rw, rh );
1476
 
                                break;
1477
 
                        case RFB_TIGHT_FILTER_GRADIENT:
1478
 
                                filter_function = &rfbConnection::filterGradient;
1479
 
                                bits_pixel = initFilterGradient( rw, rh );
1480
 
                                break;
1481
 
                        default:
1482
 
                                printf( "Tight encoding: unknown filter code received.\n" );
1483
 
                                return( FALSE );
1484
 
                }
1485
 
        }
1486
 
        else
1487
 
        {
1488
 
                filter_function = &rfbConnection::filterCopy;
1489
 
                bits_pixel = initFilterCopy( rw, rh );
1490
 
        }
1491
 
        if( bits_pixel == 0 )
1492
 
        {
1493
 
                printf( "Tight encoding: error receiving palette.\n" );
1494
 
                return( FALSE );
1495
 
        }
1496
 
 
1497
 
 
1498
 
        // Determine if the data should be decompressed or just copied.
1499
 
        Q_UINT16 row_size = ( rw * bits_pixel + 7 ) / 8;
1500
 
        if( rh * row_size < TIGHT_MIN_TO_COMPRESS )
1501
 
        {
1502
 
                if( !readFromServer( (char*)m_buffer, rh * row_size ) )
1503
 
                {
1504
 
                        return( FALSE );
1505
 
                }
1506
 
 
1507
 
                QRgb * buffer2 = (QRgb *) &m_buffer[TIGHT_MIN_TO_COMPRESS * 4];
1508
 
                ( this->*( filter_function ) )( rh, (Q_UINT32 *)buffer2 );
1509
 
                copyRect( m_clientScreen, rx, ry, rw, rh, buffer2 );
1510
 
                return( TRUE );
1511
 
        }
1512
 
 
1513
 
        // Read the length (1..3 bytes) of compressed data following.
1514
 
        int compressed_len = (int)readCompactLen();
1515
 
        if( compressed_len <= 0 )
1516
 
        {
1517
 
                printf( "Incorrect data received from the server.\n" );
1518
 
                return( FALSE );
1519
 
        }
1520
 
 
1521
 
 
1522
 
        // Now let's initialize compression stream if needed. */
1523
 
        Q_UINT8 stream_id = comp_ctl & 0x03;
1524
 
        z_streamp zs = &m_zlibStream[stream_id];
1525
 
        if( !m_zlibStreamActive[stream_id] )
1526
 
        {
1527
 
                zs->zalloc = Z_NULL;
1528
 
                zs->zfree = Z_NULL;
1529
 
                zs->opaque = Z_NULL;
1530
 
                int err = inflateInit( zs );
1531
 
                if( err != Z_OK )
1532
 
                {
1533
 
                        if( zs->msg != NULL )
1534
 
                        {
1535
 
                                printf( "InflateInit error: %s.\n", zs->msg );
1536
 
                        }
1537
 
                        return( FALSE );
1538
 
                }
1539
 
                m_zlibStreamActive[stream_id] = TRUE;
1540
 
        }
1541
 
 
1542
 
 
1543
 
        // Read, decode and draw actual pixel data in a loop. */
1544
 
        int buffer_size = BUFFER_SIZE * bits_pixel / ( bits_pixel+32 ) & 0xFFFFFFFC;
1545
 
        if( row_size > buffer_size )
1546
 
        {
1547
 
                // Should be impossible when BUFFER_SIZE >= 16384
1548
 
                printf( "Internal error: incorrect m_buffer size.\n" );
1549
 
                return( FALSE );
1550
 
        }
1551
 
        QRgb * buffer2 = (QRgb *) &m_buffer[buffer_size];
1552
 
 
1553
 
 
1554
 
        Q_UINT16 rows_processed = 0;
1555
 
        int extra_bytes = 0;
1556
 
        int portion_len;
1557
 
 
1558
 
        while( compressed_len > 0 )
1559
 
        {
1560
 
                if( compressed_len > ZLIB_BUFFER_SIZE ) 
1561
 
                {
1562
 
                        portion_len = ZLIB_BUFFER_SIZE;
1563
 
                }
1564
 
                else
1565
 
                {
1566
 
                        portion_len = compressed_len;
1567
 
                }
1568
 
 
1569
 
                if( !readFromServer( (char*)m_zlibBuffer, portion_len ) )
1570
 
                {
1571
 
                        return( FALSE );
1572
 
                }
1573
 
 
1574
 
                compressed_len -= portion_len;
1575
 
 
1576
 
                zs->next_in = (Bytef *)m_zlibBuffer;
1577
 
                zs->avail_in = portion_len;
1578
 
 
1579
 
                do
1580
 
                {
1581
 
                        zs->next_out = (Bytef *) &m_buffer[extra_bytes];
1582
 
                        zs->avail_out = buffer_size - extra_bytes;
1583
 
 
1584
 
                        int err = inflate(zs, Z_SYNC_FLUSH);
1585
 
                        if( err == Z_BUF_ERROR )   // Input exhausted -- no problem.
1586
 
                        {
1587
 
                                break;
1588
 
                        }
1589
 
                        if( err != Z_OK && err != Z_STREAM_END )
1590
 
                        {
1591
 
                                if( zs->msg != NULL )
1592
 
                                {
1593
 
                                        printf( "Inflate error: %s.\n", zs->msg );
1594
 
                                }
1595
 
                                else
1596
 
                                {
1597
 
                                        printf( "Inflate error: %d.\n", err );
1598
 
                                }
1599
 
                                return( FALSE );
1600
 
                        }
1601
 
 
1602
 
                        Q_UINT16 num_rows = (Q_UINT16)( ( buffer_size - zs->avail_out ) / (int)row_size );
1603
 
 
1604
 
                        ( this->*( filter_function ) )( num_rows, (Q_UINT32 *)buffer2 );
1605
 
                        extra_bytes = buffer_size - zs->avail_out - num_rows * row_size;
1606
 
                        if( extra_bytes > 0 )
1607
 
                        {
1608
 
                                memcpy( m_buffer, &m_buffer[num_rows * row_size], extra_bytes );
1609
 
                        }
1610
 
 
1611
 
                        copyRect( m_clientScreen, rx, ry+rows_processed, rw, num_rows, buffer2 );
1612
 
                        rows_processed += num_rows;
1613
 
                }
1614
 
                while( zs->avail_out == 0 );
1615
 
        }
1616
 
 
1617
 
        if( rows_processed != rh )
1618
 
        {
1619
 
                printf( "Incorrect number of scan lines after decompression.\n" );
1620
 
                return( FALSE );
1621
 
        }
1622
 
 
1623
 
        return( TRUE );
1624
 
}
1625
 
 
1626
 
 
1627
 
 
1628
 
/*----------------------------------------------------------------------------
1629
 
 *
1630
 
 * Filter stuff.
1631
 
 *
1632
 
 */
1633
 
 
1634
 
Q_UINT8 rfbConnection::initFilterCopy( Q_UINT16 rw, Q_UINT16/* rh*/ )
1635
 
{
1636
 
        m_rectWidth = rw;
1637
 
 
1638
 
        return( 32 );
1639
 
}
1640
 
 
1641
 
 
1642
 
 
1643
 
 
1644
 
void rfbConnection::filterCopy( Q_UINT16 num_rows, Q_UINT32 * dst )
1645
 
{
1646
 
        memcpy( dst, m_buffer, num_rows * m_rectWidth * sizeof( Q_UINT32 ) );
1647
 
}
1648
 
 
1649
 
 
1650
 
 
1651
 
 
1652
 
Q_UINT8 rfbConnection::initFilterGradient( Q_UINT16 rw, Q_UINT16/* rh*/ )
1653
 
{
1654
 
        m_rectWidth = rw;
1655
 
        memset( m_tightPrevRow, 0, rw * 3 * sizeof( Q_UINT16 ) );
1656
 
 
1657
 
        return( sizeof( QRgb ) );
1658
 
}
1659
 
 
1660
 
 
1661
 
 
1662
 
 
1663
 
void rfbConnection::filterGradient( Q_UINT16 num_rows, Q_UINT32 * dst )
1664
 
{
1665
 
        Q_UINT32 * src = (Q_UINT32 *) m_buffer;
1666
 
        Q_UINT16 * that_row = (Q_UINT16 *) m_tightPrevRow;
1667
 
        Q_UINT16 this_row[2048*3];
1668
 
        Q_UINT16 pix[3];
1669
 
        Q_UINT16 max[3] = { s_localDisplayFormat.red_max, s_localDisplayFormat.green_max, s_localDisplayFormat.blue_max } ;
1670
 
        Q_UINT8 shift[3] = { s_localDisplayFormat.red_shift, s_localDisplayFormat.green_shift, s_localDisplayFormat.blue_shift } ;
1671
 
        Q_INT16 est[3];
1672
 
 
1673
 
 
1674
 
        for( Q_UINT16 y = 0; y < num_rows; y++ )
1675
 
        {
1676
 
                // First pixel in a row
1677
 
                for( Q_UINT8 c = 0; c < 3; c++ )
1678
 
                {
1679
 
                        pix[c] = (Q_UINT16)((src[y*m_rectWidth] >> shift[c]) + that_row[c] & max[c]);
1680
 
                        this_row[c] = pix[c];
1681
 
                }
1682
 
                dst[y*m_rectWidth] = RGB_TO_PIXEL(pix[0], pix[1], pix[2]);
1683
 
                // Remaining pixels of a row 
1684
 
                for( Q_UINT16 x = 1; x < m_rectWidth; x++ )
1685
 
                {
1686
 
                        for( Q_UINT8 c = 0; c < 3; c++ )
1687
 
                        {
1688
 
                                est[c] = (Q_INT16)that_row[x*3+c] + (Q_INT16)pix[c] - (Q_INT16)that_row[(x-1)*3+c];
1689
 
                                if( est[c] > (Q_INT16)max[c] )
1690
 
                                {
1691
 
                                        est[c] = (Q_INT16)max[c];
1692
 
                                }
1693
 
                                else if( est[c] < 0 )
1694
 
                                {
1695
 
                                        est[c] = 0;
1696
 
                                }
1697
 
                                pix[c] = (Q_UINT16)((src[y*m_rectWidth+x] >> shift[c]) + est[c] & max[c]);
1698
 
                                this_row[x*3+c] = pix[c];
1699
 
                        }
1700
 
                        dst[y*m_rectWidth+x] = RGB_TO_PIXEL( pix[0], pix[1], pix[2] );
1701
 
                }
1702
 
                memcpy( that_row, this_row, m_rectWidth * 3 * sizeof( Q_UINT16 ) );
1703
 
        }
1704
 
}
1705
 
 
1706
 
 
1707
 
 
1708
 
 
1709
 
Q_UINT8 rfbConnection::initFilterPalette( Q_UINT16 rw, Q_UINT16/* rh*/ )
1710
 
{
1711
 
        Q_UINT8 num_colors;
1712
 
 
1713
 
        m_rectWidth = rw;
1714
 
 
1715
 
        if( !readFromServer( (char*)&num_colors, sizeof( num_colors ) ) )
1716
 
        {
1717
 
                return( 0 );
1718
 
        }
1719
 
 
1720
 
        m_rectColors = (Q_UINT16) num_colors;
1721
 
        if( ++m_rectColors < 2 )
1722
 
        {
1723
 
                return( 0 );
1724
 
        }
1725
 
 
1726
 
        if( !readFromServer( (char*)&m_tightPalette, m_rectColors * sizeof( Q_UINT32 ) ) )
1727
 
        {
1728
 
                return( 0 );
1729
 
        }
1730
 
 
1731
 
        return( ( m_rectColors == 2 ) ? 1 : 8 );
1732
 
}
1733
 
 
1734
 
 
1735
 
 
1736
 
 
1737
 
void rfbConnection::filterPalette( Q_UINT16 num_rows, Q_UINT32 * dst )
1738
 
{
1739
 
        Q_UINT8 * src = (Q_UINT8 *)m_buffer;
1740
 
        Q_UINT32 * palette = (Q_UINT32 *) m_tightPalette;
1741
 
 
1742
 
        if( m_rectColors == 2 )
1743
 
        {
1744
 
                const Q_UINT16 w = (m_rectWidth + 7) / 8;
1745
 
                for( Q_UINT16 y = 0; y < num_rows; y++ )
1746
 
                {
1747
 
                        const Q_UINT32 base = y*m_rectWidth;
1748
 
                        for( Q_UINT16 x = 0; x < m_rectWidth/8; x++ )
1749
 
                        {
1750
 
                                for( Q_INT8 b = 7; b >= 0; b-- )
1751
 
                                {
1752
 
                                        dst[base+x*8+7-b] = palette[src[y*w+x] >> b & 1];
1753
 
                                }
1754
 
                        }
1755
 
                        for( Q_INT8 b = 7; b >= 8 - m_rectWidth % 8; b-- )
1756
 
                        {
1757
 
                                dst[base+m_rectWidth+7-b] = palette[src[y*w+m_rectWidth/8] >> b & 1];
1758
 
                        }
1759
 
                }
1760
 
        }
1761
 
        else
1762
 
        {
1763
 
                for( Q_UINT16 y = 0; y < num_rows; y++ )
1764
 
                {
1765
 
                        const Q_UINT32 base = y*m_rectWidth;
1766
 
                        for( Q_UINT16 x = 0; x < m_rectWidth; x++ )
1767
 
                        {
1768
 
                                dst[base+x] = palette[(int)src[base+x]];
1769
 
                        }
1770
 
                }
1771
 
        }
1772
 
}
1773
 
 
1774
 
 
1775
 
#ifdef HAVE_LIBJPEG
1776
 
/*----------------------------------------------------------------------------
1777
 
 *
1778
 
 * JPEG decompression.
1779
 
 *
1780
 
 */
1781
 
 
1782
 
 
1783
 
void jpegInitSource( jpeglib::j_decompress_ptr )
1784
 
{
1785
 
}
1786
 
 
1787
 
 
1788
 
 
1789
 
 
1790
 
jpeglib::boolean jpegFillInputBuffer( jpeglib::j_decompress_ptr )
1791
 
{
1792
 
        printf( "ERROR: jpegFillInputBuffer(...) called (not implemented, because it should not be needed\n" );
1793
 
        return( 0 );
1794
 
}
1795
 
 
1796
 
 
1797
 
 
1798
 
 
1799
 
void jpegSkipInputData( jpeglib::j_decompress_ptr, long )
1800
 
{
1801
 
        printf( "ERROR: jpegSkipInputData(...) called (not implemented, because it should not be needed\n" );
1802
 
}
1803
 
 
1804
 
 
1805
 
 
1806
 
 
1807
 
void jpegTermSource( jpeglib::j_decompress_ptr )
1808
 
{
1809
 
}
1810
 
 
1811
 
 
1812
 
 
1813
 
using jpeglib::jpeg_decompress_struct;
1814
 
 
1815
 
bool rfbConnection::decompressJpegRect( Q_UINT16 x, Q_UINT16 y, Q_UINT16 w, Q_UINT16 h )
1816
 
{
1817
 
        int compressed_len = (int) readCompactLen();
1818
 
        if( compressed_len <= 0 )
1819
 
        {
1820
 
                printf( "Incorrect data received from the server.\n" );
1821
 
                return( FALSE );
1822
 
        }
1823
 
 
1824
 
        Q_UINT8 compressed_data[compressed_len];
1825
 
 
1826
 
        if( !readFromServer( (char*)compressed_data, compressed_len ) )
1827
 
        {
1828
 
                return( FALSE );
1829
 
        }
1830
 
 
1831
 
        struct jpeglib::jpeg_error_mgr jerr;
1832
 
        struct jpeglib::jpeg_decompress_struct cinfo;
1833
 
        cinfo.err = jpeglib::jpeg_std_error( &jerr );
1834
 
        jpeglib::jpeg_create_decompress( &cinfo );
1835
 
 
1836
 
        //jpegSetSrcManager (&cinfo, compressed_data, compressed_len);
1837
 
        m_jpegSrcManager.init_source = jpegInitSource;
1838
 
        m_jpegSrcManager.fill_input_buffer = jpegFillInputBuffer;
1839
 
        m_jpegSrcManager.skip_input_data = jpegSkipInputData;
1840
 
        m_jpegSrcManager.resync_to_restart = jpeglib::jpeg_resync_to_restart;
1841
 
        m_jpegSrcManager.term_source = jpegTermSource;
1842
 
        m_jpegSrcManager.next_input_byte = (jpeglib::JOCTET *) compressed_data;
1843
 
        m_jpegSrcManager.bytes_in_buffer = (size_t) compressed_len;
1844
 
 
1845
 
        cinfo.src = &m_jpegSrcManager;
1846
 
 
1847
 
 
1848
 
        jpeglib::jpeg_read_header( &cinfo, TRUE );
1849
 
        cinfo.out_color_space = jpeglib::JCS_RGB;
1850
 
 
1851
 
        jpeglib::jpeg_start_decompress( &cinfo );
1852
 
        if( cinfo.output_width != w || cinfo.output_height != h || cinfo.output_components != 3 )
1853
 
        {
1854
 
                printf( "Tight Encoding: Wrong JPEG data received.\n" );
1855
 
                jpeglib::jpeg_destroy_decompress( &cinfo );
1856
 
                return( FALSE );
1857
 
        }
1858
 
 
1859
 
        jpeglib::JSAMPROW row_pointer[1];
1860
 
        row_pointer[0] = (jpeglib::JSAMPROW) m_buffer;
1861
 
        int dy = 0;
1862
 
        while( cinfo.output_scanline < cinfo.output_height )
1863
 
        {
1864
 
                jpeglib::jpeg_read_scanlines( &cinfo, row_pointer, 1 );
1865
 
                Q_UINT32 * pixel_ptr = (Q_UINT32 *) &m_buffer[BUFFER_SIZE / 2];
1866
 
                for( Q_UINT16 dx = 0; dx < w; dx++ )
1867
 
                {
1868
 
                        *pixel_ptr++ = RGB_TO_PIXEL( m_buffer[dx*3], m_buffer[dx*3+1], m_buffer[dx*3+2] );
1869
 
                }
1870
 
                copyRect( m_clientScreen, x, y+dy, w, 1, (QRgb *) &m_buffer[BUFFER_SIZE / 2] );
1871
 
                dy++;
1872
 
        }
1873
 
 
1874
 
        jpeglib::jpeg_finish_decompress( &cinfo );
1875
 
 
1876
 
        jpeglib::jpeg_destroy_decompress( &cinfo );
1877
 
 
1878
 
        return( TRUE );
1879
 
}
1880
 
 
1881
 
#endif  /* LIBJPEG */
1882
 
 
1883
 
#endif  /* LIBZ */
1884
 
 
1885
 
 
1886
 
 
1887
 
 
1888
 
 
1889
 
 
1890
 
// this is an optimized version of Qt's smoothScale... the adventage is, that I could remove all code, dealing with
1891
 
// alpha-layers. The second thing is, that this code will be optimized for use on CPU with MMX and SSE. The Qt libraries
1892
 
// are per default compiled for i586 only...
1893
 
void fastScaleImage( const QImage & src, QImage & dst )
1894
 
{
1895
 
        QRgb * xelrow = NULL;
1896
 
        QRgb * tempxelrow = NULL;
1897
 
        Q_UINT16 rowswritten = 0;
1898
 
        const uchar maxval = 255;
1899
 
 
1900
 
        Q_UINT16 cols = src.width();
1901
 
        Q_UINT16 rows = src.height();
1902
 
        Q_UINT16 newcols = dst.width();
1903
 
        Q_UINT16 newrows = dst.height();
1904
 
 
1905
 
        long SCALE;
1906
 
        long HALFSCALE;
1907
 
 
1908
 
        if( cols > 4096 )
1909
 
        {
1910
 
                SCALE = 4096;
1911
 
                HALFSCALE = 2048;
1912
 
        }
1913
 
        else
1914
 
        {
1915
 
                Q_UINT16 fac = 4096;
1916
 
                while( cols * fac > 4096 )
1917
 
                {
1918
 
                        fac /= 2;
1919
 
                }
1920
 
                SCALE = fac * cols;
1921
 
                HALFSCALE = fac * cols / 2;
1922
 
        }
1923
 
 
1924
 
        long sxscale = (long)( (double) newcols / (double) cols * SCALE );
1925
 
        long syscale = (long)( (double) newrows / (double) rows * SCALE );
1926
 
 
1927
 
        if( newrows != rows )   // shortcut Y scaling if possible
1928
 
                tempxelrow = new QRgb[cols];
1929
 
 
1930
 
        long * rs = new long[cols];
1931
 
        long * gs = new long[cols];
1932
 
        long * bs = new long[cols];
1933
 
        Q_UINT16 rowsread = 0;
1934
 
        register long fracrowleft = syscale;
1935
 
        register Q_UINT16 needtoreadrow = 1;
1936
 
 
1937
 
        for( Q_UINT16 col = 0; col < cols; ++col )
1938
 
        {
1939
 
                rs[col] = gs[col] = bs[col] = HALFSCALE;
1940
 
        }
1941
 
 
1942
 
        register long fracrowtofill = SCALE;
1943
 
        register QRgb * xP;
1944
 
        register QRgb * nxP;
1945
 
 
1946
 
        for( Q_UINT16 row = 0; row < newrows; ++row )
1947
 
        {
1948
 
                // First scale Y from xelrow into tempxelrow.
1949
 
                if( newrows == rows )
1950
 
                {
1951
 
                        // shortcut Y scaling if possible 
1952
 
                        tempxelrow = xelrow = (QRgb*)src.scanLine( rowsread++ );
1953
 
                }
1954
 
                else
1955
 
                {
1956
 
                        while( fracrowleft < fracrowtofill )
1957
 
                        {
1958
 
                                if( needtoreadrow && rowsread < rows )
1959
 
                                {
1960
 
                                        xelrow = (QRgb*)src.scanLine( rowsread++ );
1961
 
                                }
1962
 
                                xP = xelrow;
1963
 
                                for( Q_UINT16 col = 0; col < cols; ++col, ++xP )
1964
 
                                {
1965
 
                                        rs[col] += fracrowleft * qRed( *xP );
1966
 
                                        gs[col] += fracrowleft * qGreen( *xP );
1967
 
                                        bs[col] += fracrowleft * qBlue( *xP );
1968
 
                                }
1969
 
                                fracrowtofill -= fracrowleft;
1970
 
                                fracrowleft = syscale;
1971
 
                                needtoreadrow = 1;
1972
 
                        }
1973
 
                        // Now fracrowleft is >= fracrowtofill, so we can produce a row.
1974
 
                        if( needtoreadrow && rowsread < rows )
1975
 
                        {
1976
 
                                xelrow = (QRgb*)src.scanLine( rowsread++ );
1977
 
                                needtoreadrow = 0;
1978
 
                        }
1979
 
                        xP = xelrow;
1980
 
                        nxP = tempxelrow;
1981
 
                        for( Q_UINT16 col = 0; col < cols; ++col, ++xP, ++nxP )
1982
 
                        {
1983
 
                                register long r, g, b;
1984
 
                                r = rs[col] + fracrowtofill * qRed( *xP );
1985
 
                                g = gs[col] + fracrowtofill * qGreen( *xP );
1986
 
                                b = bs[col] + fracrowtofill * qBlue( *xP );
1987
 
 
1988
 
                                r /= SCALE;
1989
 
                                if( r > maxval )
1990
 
                                {
1991
 
                                        r = maxval;
1992
 
                                }
1993
 
 
1994
 
                                g /= SCALE;
1995
 
                                if( g > maxval )
1996
 
                                {
1997
 
                                        g = maxval;
1998
 
                                }
1999
 
 
2000
 
                                b /= SCALE;
2001
 
                                if( b > maxval )
2002
 
                                {
2003
 
                                        b = maxval;
2004
 
                                }
2005
 
 
2006
 
                                *nxP = qRgb( (int)r, (int)g, (int)b );
2007
 
                                rs[col] = gs[col] = bs[col] = HALFSCALE;
2008
 
                        }
2009
 
                        fracrowleft -= fracrowtofill;
2010
 
                        if( fracrowleft == 0 )
2011
 
                        {
2012
 
                                fracrowleft = syscale;
2013
 
                                needtoreadrow = 1;
2014
 
                        }
2015
 
                        fracrowtofill = SCALE;
2016
 
                }
2017
 
 
2018
 
                // Now scale X from tempxelrow into dst and write it out.
2019
 
                if( newcols == cols )
2020
 
                {
2021
 
                        // shortcut X scaling if possible
2022
 
                        memcpy( dst.scanLine(rowswritten++), tempxelrow, newcols*4 );
2023
 
                }
2024
 
                else
2025
 
                {
2026
 
                        register long r, g, b;
2027
 
                        register long fraccoltofill, fraccolleft = 0;
2028
 
                        register Q_UINT16 needcol;
2029
 
 
2030
 
                        nxP = (QRgb*)dst.scanLine( rowswritten++ );
2031
 
                        fraccoltofill = SCALE;
2032
 
                        r = g = b = HALFSCALE;
2033
 
                        needcol = 0;
2034
 
                        xP = tempxelrow;
2035
 
                        for( Q_UINT16 col = 0; col < cols; ++col, ++xP )
2036
 
                        {
2037
 
                                fraccolleft = sxscale;
2038
 
                                while( fraccolleft >= fraccoltofill )
2039
 
                                {
2040
 
                                        if( needcol )
2041
 
                                        {
2042
 
                                                ++nxP;
2043
 
                                                r = g = b = HALFSCALE;
2044
 
                                        }
2045
 
                                        r += fraccoltofill * qRed( *xP );
2046
 
                                        g += fraccoltofill * qGreen( *xP );
2047
 
                                        b += fraccoltofill * qBlue( *xP );
2048
 
 
2049
 
                                        r /= SCALE;
2050
 
                                        if( r > maxval )
2051
 
                                        {
2052
 
                                                r = maxval;
2053
 
                                        }
2054
 
 
2055
 
                                        g /= SCALE;
2056
 
                                        if( g > maxval )
2057
 
                                        {
2058
 
                                                g = maxval;
2059
 
                                        }
2060
 
 
2061
 
                                        b /= SCALE;
2062
 
                                        if( b > maxval )
2063
 
                                        {
2064
 
                                                b = maxval;
2065
 
                                        }
2066
 
 
2067
 
                                        *nxP = qRgb( (int)r, (int)g, (int)b );
2068
 
                                        fraccolleft -= fraccoltofill;
2069
 
                                        fraccoltofill = SCALE;
2070
 
                                        needcol = 1;
2071
 
                                }
2072
 
                                if( fraccolleft > 0 )
2073
 
                                {
2074
 
                                        if( needcol )
2075
 
                                        {
2076
 
                                                ++nxP;
2077
 
                                                r = g = b = HALFSCALE;
2078
 
                                                needcol = 0;
2079
 
                                        }
2080
 
                                        r += fraccolleft * qRed( *xP );
2081
 
                                        g += fraccolleft * qGreen( *xP );
2082
 
                                        b += fraccolleft * qBlue( *xP );
2083
 
                                        fraccoltofill -= fraccolleft;
2084
 
                                }
2085
 
                        }
2086
 
                        if( fraccoltofill > 0 )
2087
 
                        {
2088
 
                                --xP;
2089
 
                                r += fraccoltofill * qRed( *xP );
2090
 
                                g += fraccoltofill * qGreen( *xP );
2091
 
                                b += fraccoltofill * qBlue( *xP );
2092
 
                        }
2093
 
                        if( !needcol )
2094
 
                        {
2095
 
                                r /= SCALE;
2096
 
                                if( r > maxval )
2097
 
                                {
2098
 
                                        r = maxval;
2099
 
                                }
2100
 
 
2101
 
                                g /= SCALE;
2102
 
                                if( g > maxval )
2103
 
                                {
2104
 
                                        g = maxval;
2105
 
                                }
2106
 
 
2107
 
                                b /= SCALE;
2108
 
                                if( b > maxval )
2109
 
                                {
2110
 
                                        b = maxval;
2111
 
                                }
2112
 
 
2113
 
                                *nxP = qRgb( (int)r, (int)g, (int)b );
2114
 
                        }
2115
 
                }
2116
 
        }
2117
 
 
2118
 
        if( newrows != rows && tempxelrow )// Robust, tempxelrow might be 0 one day
2119
 
        {
2120
 
                delete[] tempxelrow;
2121
 
        }
2122
 
        if( rs )                        // Robust, rs might be 0 one day
2123
 
        {
2124
 
                delete[] rs;
2125
 
        }
2126
 
        if( gs )                        // Robust, gs might be 0 one day
2127
 
        {
2128
 
                delete[] gs;
2129
 
        }
2130
 
        if( bs )                        // Robust, bs might be 0 one day
2131
 
        {
2132
 
                delete[] bs;
2133
 
        }
2134
 
}