/[rdesktop]/sourceforge.net/trunk/rdesktop/uiports/qtwin.cpp
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /sourceforge.net/trunk/rdesktop/uiports/qtwin.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 877 - (show annotations)
Sun Apr 3 05:40:15 2005 UTC (19 years, 3 months ago) by jsorg71
File size: 46167 byte(s)
added more command line options

1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 User interface services - QT Window System
4 Copyright (C) Jay Sorg 2004-2005
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "../rdesktop.h"
22
23 #include <qapplication.h>
24 #include <qmainwindow.h>
25 #include <qwidget.h>
26 #include <qpainter.h>
27 #include <qpixmap.h>
28 #include <qbrush.h>
29 #include <qimage.h>
30 #include <qbitmap.h>
31 #include <qcursor.h>
32 #include <qsocketnotifier.h>
33 #include <qscrollview.h>
34 #include <qfile.h>
35
36 #include "qtwin.h"
37
38 #include <unistd.h> // gethostname
39 #include <pwd.h> // getpwuid
40 #include <stdarg.h> // va_list va_start va_end
41
42 #include <errno.h>
43 #include <fcntl.h>
44
45 /* rdesktop globals */
46 extern int g_tcp_port_rdp;
47 int g_use_rdp5 = 1;
48 char g_hostname[16];
49 char g_username[64];
50 int g_height = 600;
51 int g_width = 800;
52 int g_server_bpp = 8;
53 int g_encryption = 1;
54 int g_desktop_save = 1;
55 int g_polygon_ellipse_orders = 0;
56 int g_bitmap_cache = 1;
57 int g_bitmap_cache_persist_enable = False;
58 int g_bitmap_cache_precache = True;
59 int g_bitmap_compression = 1;
60 int g_rdp5_performanceflags = 0;
61 int g_console_session = 0;
62 int g_keylayout = 0x409; /* Defaults to US keyboard layout */
63
64 /* hack globals */
65 static int g_argc = 0;
66 static char ** g_argv = 0;
67 static int g_UpAndRunning = 0;
68 static int g_sock = 0;
69 static int g_deactivated = 0;
70 static uint32 g_ext_disc_reason = 0;
71 static char g_servername[128];
72 static char g_title[128] = "";
73 static int g_flags = RDP_LOGON_NORMAL;
74
75 /* qt globals */
76 static QSocketNotifier * g_SocketNotifier;
77 static QApplication * g_App;
78 static QMyMainWindow * g_MW;
79 static QMyScrollView * g_SV;
80 static QPixmap * g_BS;
81 static QPixmap * g_DS;
82 static QPainter * g_P1;
83 static QPainter * g_P2;
84 static QColor g_Color1;
85 static QColor g_Color2;
86
87 struct QColorMap
88 {
89 uint32 RGBColors[256];
90 int NumColors;
91 };
92 static struct QColorMap * g_CM = 0;
93 static QRegion * g_ClipRect;
94
95 static Qt::RasterOp g_OpCodes[16] = {
96 Qt::ClearROP, // BLACKNESS 0
97 Qt::NorROP, // NOTSRCERASE DSon
98 Qt::NotAndROP, // DSna
99 Qt::NotCopyROP, // NOTSRCCOPY Sn
100 Qt::AndNotROP, // SRCERASE SDna
101 Qt::NotROP, // DSTINVERT Dn
102 Qt::XorROP, // SRCINVERT DSx
103 Qt::NandROP, // DSan
104 Qt::AndROP, // SRCAND DSa
105 Qt::NotXorROP, // DSxn
106 Qt::NopROP, // D
107 Qt::NotOrROP, // MERGEPAINT DSno
108 Qt::CopyROP, // SRCCOPY S
109 Qt::OrNotROP, // SDno
110 Qt::OrROP, // SRCPAINT DSo
111 Qt::SetROP}; // WHITENESS 1
112
113 //*****************************************************************************
114 uint32 Color15to32(uint32 InColor)
115 {
116 uint32 r, g, b;
117
118 r = (InColor & 0x7c00) >> 10;
119 r = (r * 0xff) / 0x1f;
120 g = (InColor & 0x03e0) >> 5;
121 g = (g * 0xff) / 0x1f;
122 b = (InColor & 0x001f);
123 b = (b * 0xff) / 0x1f;
124 return (r << 16) | (g << 8) | b;
125 }
126
127 //*****************************************************************************
128 uint32 Color16to32(uint32 InColor)
129 {
130 uint32 r, g, b;
131
132 r = (InColor & 0xf800) >> 11;
133 r = (r * 0xff) / 0x1f;
134 g = (InColor & 0x07e0) >> 5;
135 g = (g * 0xff) / 0x3f;
136 b = (InColor & 0x001f);
137 b = (b * 0xff) / 0x1f;
138 return (r << 16) | (g << 8) | b;
139 }
140
141 //*****************************************************************************
142 uint32 Color24to32(uint32 InColor)
143 {
144 return ((InColor & 0x00ff0000) >> 16) |
145 ((InColor & 0x000000ff) << 16) |
146 (InColor & 0x0000ff00);
147 }
148
149 //*****************************************************************************
150 void SetColorx(QColor * Color, uint32 InColor)
151 {
152 switch (g_server_bpp)
153 {
154 case 8:
155 if (g_CM == NULL || InColor > 255)
156 {
157 Color->setRgb(0);
158 return;
159 }
160 Color->setRgb(g_CM->RGBColors[InColor]);
161 break;
162 case 15:
163 Color->setRgb(Color15to32(InColor));
164 break;
165 case 16:
166 Color->setRgb(Color16to32(InColor));
167 break;
168 case 24:
169 Color->setRgb(Color24to32(InColor));
170 break;
171 default:
172 Color->setRgb(0);
173 }
174 }
175
176 //*****************************************************************************
177 void SetOpCode(int opcode)
178 {
179 if (opcode >= 0 && opcode < 16)
180 {
181 Qt::RasterOp op = g_OpCodes[opcode];
182 if (op != Qt::CopyROP)
183 {
184 g_P1->setRasterOp(op);
185 g_P2->setRasterOp(op);
186 }
187 }
188 }
189
190 //*****************************************************************************
191 void ResetOpCode(int opcode)
192 {
193 if (opcode >= 0 && opcode < 16)
194 {
195 Qt::RasterOp op = g_OpCodes[opcode];
196 if (op != Qt::CopyROP)
197 {
198 g_P1->setRasterOp(Qt::CopyROP);
199 g_P2->setRasterOp(Qt::CopyROP);
200 }
201 }
202 }
203
204 /*****************************************************************************/
205 QMyMainWindow::QMyMainWindow(): QWidget()
206 {
207 }
208
209 /*****************************************************************************/
210 QMyMainWindow::~QMyMainWindow()
211 {
212 }
213
214 //*****************************************************************************
215 void QMyMainWindow::mouseMoveEvent(QMouseEvent * e)
216 {
217 if (!g_UpAndRunning)
218 {
219 return;
220 }
221 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE, e->x(), e->y());
222 }
223
224 //*****************************************************************************
225 void QMyMainWindow::mousePressEvent(QMouseEvent * e)
226 {
227 if (!g_UpAndRunning)
228 {
229 return;
230 }
231 if (e->button() == LeftButton)
232 {
233 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON1,
234 e->x(), e->y());
235 }
236 else if (e->button() == RightButton)
237 {
238 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON2,
239 e->x(), e->y());
240 }
241 else if (e->button() == MidButton)
242 {
243 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON3,
244 e->x(), e->y());
245 }
246 }
247
248 //*****************************************************************************
249 void QMyMainWindow::mouseReleaseEvent(QMouseEvent * e)
250 {
251 if (!g_UpAndRunning)
252 {
253 return;
254 }
255 if (e->button() == LeftButton)
256 {
257 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1, e->x(), e->y());
258 }
259 else if (e->button() == RightButton)
260 {
261 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON2, e->x(), e->y());
262 }
263 else if (e->button() == MidButton)
264 {
265 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON3, e->x(), e->y());
266 }
267 }
268
269 //*****************************************************************************
270 void QMyMainWindow::wheelEvent(QWheelEvent * e)
271 {
272 if (!g_UpAndRunning)
273 {
274 return;
275 }
276 if (e->delta() > 0)
277 {
278 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON4, e->x(), e->y());
279 }
280 else if (e->delta() < 0)
281 {
282 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON5, e->x(), e->y());
283 }
284 }
285
286 //*****************************************************************************
287 int GetScanCode(QKeyEvent* e)
288 {
289 int Key = e->key();
290 int ScanCode = 0;
291 Qt::ButtonState bs = e->state();
292 if (!(bs & Qt::ShiftButton)) // shift is not down
293 {
294 if (Key == 42) // *
295 return 0x37;
296 if (Key == 43) // +
297 return 0x4e;
298 }
299 switch (Key)
300 {
301 case 4100: ScanCode = 0x1c; break; // enter
302 case 4101: ScanCode = 0x1c; break;
303 case 4117: ScanCode = 0xd0; break; // down arrow
304 case 4115: ScanCode = 0xc8; break; // up arrow
305 case 4114: ScanCode = 0xcb; break; // left arrow
306 case 4116: ScanCode = 0xcd; break; // right arrow
307 case 4112: ScanCode = 0xc7; break; // home
308 case 4113: ScanCode = 0xcf; break; // end
309 case 4102: ScanCode = 0xd2; break; // insert
310 case 4103: ScanCode = 0xd3; break; // delete
311 case 4118: ScanCode = 0xc9; break; // page up
312 case 4119: ScanCode = 0xd1; break; // page down
313 case 4143: ScanCode = 0x00; break; // num lock
314 case 47: ScanCode = 0x35; break; // /
315 case 42: ScanCode = 0x37; break; // *
316 case 45: ScanCode = 0x0c; break; // -
317 case 95: ScanCode = 0x0c; break; // _
318 case 43: ScanCode = 0x0d; break; // +
319 case 46: ScanCode = 0x34; break; // .
320 case 48: ScanCode = 0x0b; break; // 0
321 case 41: ScanCode = 0x0b; break; // )
322 case 49: ScanCode = 0x02; break; // 1
323 case 33: ScanCode = 0x02; break; // !
324 case 50: ScanCode = 0x03; break; // 2
325 case 64: ScanCode = 0x03; break; // @
326 case 51: ScanCode = 0x04; break; // 3
327 case 35: ScanCode = 0x04; break; // #
328 case 52: ScanCode = 0x05; break; // 4
329 case 36: ScanCode = 0x05; break; // $
330 case 53: ScanCode = 0x06; break; // 5
331 case 37: ScanCode = 0x06; break; // %
332 case 54: ScanCode = 0x07; break; // 6
333 case 94: ScanCode = 0x07; break; // ^
334 case 55: ScanCode = 0x08; break; // 7
335 case 38: ScanCode = 0x08; break; // &
336 case 56: ScanCode = 0x09; break; // 8
337 case 57: ScanCode = 0x0a; break; // 9
338 case 40: ScanCode = 0x0a; break; // (
339 case 61: ScanCode = 0x0d; break; // =
340 case 65: ScanCode = 0x1e; break; // a
341 case 66: ScanCode = 0x30; break; // b
342 case 67: ScanCode = 0x2e; break; // c
343 case 68: ScanCode = 0x20; break; // d
344 case 69: ScanCode = 0x12; break; // e
345 case 70: ScanCode = 0x21; break; // f
346 case 71: ScanCode = 0x22; break; // g
347 case 72: ScanCode = 0x23; break; // h
348 case 73: ScanCode = 0x17; break; // i
349 case 74: ScanCode = 0x24; break; // j
350 case 75: ScanCode = 0x25; break; // k
351 case 76: ScanCode = 0x26; break; // l
352 case 77: ScanCode = 0x32; break; // m
353 case 78: ScanCode = 0x31; break; // n
354 case 79: ScanCode = 0x18; break; // o
355 case 80: ScanCode = 0x19; break; // p
356 case 81: ScanCode = 0x10; break; // q
357 case 82: ScanCode = 0x13; break; // r
358 case 83: ScanCode = 0x1f; break; // s
359 case 84: ScanCode = 0x14; break; // t
360 case 85: ScanCode = 0x16; break; // u
361 case 86: ScanCode = 0x2f; break; // v
362 case 87: ScanCode = 0x11; break; // w
363 case 88: ScanCode = 0x2d; break; // x
364 case 89: ScanCode = 0x15; break; // y
365 case 90: ScanCode = 0x2c; break; // z
366 case 32: ScanCode = 0x39; break; // space
367 case 44: ScanCode = 0x33; break; // ,
368 case 60: ScanCode = 0x33; break; // <
369 case 62: ScanCode = 0x34; break; // >
370 case 63: ScanCode = 0x35; break; // ?
371 case 92: ScanCode = 0x2b; break; // backslash
372 case 124: ScanCode = 0x2b; break; // bar
373 case 4097: ScanCode = 0x0f; break; // tab
374 case 4132: ScanCode = 0x3a; break; // caps lock
375 case 4096: ScanCode = 0x01; break; // esc
376 case 59: ScanCode = 0x27; break; // ;
377 case 58: ScanCode = 0x27; break; // :
378 case 39: ScanCode = 0x28; break; // '
379 case 34: ScanCode = 0x28; break; // "
380 case 91: ScanCode = 0x1a; break; // [
381 case 123: ScanCode = 0x1a; break; // {
382 case 93: ScanCode = 0x1b; break; // ]
383 case 125: ScanCode = 0x1b; break; // }
384 case 4144: ScanCode = 0x3b; break; // f1
385 case 4145: ScanCode = 0x3c; break; // f2
386 case 4146: ScanCode = 0x3d; break; // f3
387 case 4147: ScanCode = 0x3e; break; // f4
388 case 4148: ScanCode = 0x3f; break; // f5
389 case 4149: ScanCode = 0x40; break; // f6
390 case 4150: ScanCode = 0x41; break; // f7
391 case 4151: ScanCode = 0x42; break; // f8
392 case 4152: ScanCode = 0x43; break; // f9
393 case 4153: ScanCode = 0x44; break; // f10
394 case 4154: ScanCode = 0x57; break; // f11
395 case 4155: ScanCode = 0x58; break; // f12
396 case 4128: ScanCode = 0x2a; break; // shift
397 case 4131: ScanCode = 0x38; break; // alt
398 case 4129: ScanCode = 0x1d; break; // ctrl
399 case 96: ScanCode = 0x29; break; // `
400 case 126: ScanCode = 0x29; break; // ~
401 case 4099: ScanCode = 0x0e; break; // backspace
402 }
403 // if (ScanCode == 0)
404 // printf("key %d scancode %d\n", Key, ScanCode);
405 return ScanCode;
406 }
407
408 //*****************************************************************************
409 void QMyMainWindow::keyPressEvent(QKeyEvent* e)
410 {
411 if (!g_UpAndRunning)
412 return;
413 int ScanCode = GetScanCode(e);
414 if (ScanCode != 0)
415 {
416 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYPRESS, ScanCode, 0);
417 e->accept();
418 }
419 }
420
421 //*****************************************************************************
422 void QMyMainWindow::keyReleaseEvent(QKeyEvent* e)
423 {
424 if (!g_UpAndRunning)
425 {
426 return;
427 }
428 int ScanCode = GetScanCode(e);
429 if (ScanCode != 0)
430 {
431 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, ScanCode, 0);
432 e->accept();
433 }
434 }
435
436 //*****************************************************************************
437 void QMyMainWindow::paintEvent(QPaintEvent * pe)
438 {
439 QRect Rect;
440
441 Rect = pe->rect();
442 bitBlt(this, Rect.left(), Rect.top(), g_BS, Rect.left(), Rect.top(),
443 Rect.width(), Rect.height());
444 }
445
446 //*****************************************************************************
447 void QMyMainWindow::closeEvent(QCloseEvent * e)
448 {
449 e->accept();
450 }
451
452 //*****************************************************************************
453 bool QMyMainWindow::event(QEvent * e)
454 {
455 return QWidget::event(e);
456 }
457
458 //*****************************************************************************
459 void QMyMainWindow::dataReceived()
460 {
461 if (!rdp_loop(&g_deactivated, &g_ext_disc_reason))
462 {
463 g_SV->close();
464 }
465 }
466
467 //*****************************************************************************
468 void QMyScrollView::keyPressEvent(QKeyEvent * e)
469 {
470 g_MW->keyPressEvent(e);
471 }
472
473 //*****************************************************************************
474 void QMyScrollView::keyReleaseEvent(QKeyEvent * e)
475 {
476 g_MW->keyReleaseEvent(e);
477 }
478
479
480 //*****************************************************************************
481 void ui_begin_update(void)
482 {
483 g_P1->begin(g_MW);
484 g_P2->begin(g_BS);
485 }
486
487 //*****************************************************************************
488 void ui_end_update(void)
489 {
490 g_P1->end();
491 g_P2->end();
492 }
493
494 /*****************************************************************************/
495 int ui_init(void)
496 {
497 g_App = new QApplication(g_argc, g_argv);
498 return 1;
499 }
500
501 /*****************************************************************************/
502 void ui_deinit(void)
503 {
504 delete g_App;
505 }
506
507 /*****************************************************************************/
508 int ui_create_window(void)
509 {
510 int w, h;
511 QPainter * painter;
512 QWidget * desktop;
513
514 g_MW = new QMyMainWindow();
515 g_SV = new QMyScrollView();
516 g_SV->addChild(g_MW);
517 g_BS = new QPixmap(g_width, g_height);
518 painter = new QPainter(g_BS);
519 painter->fillRect(0, 0, g_width, g_height, QBrush(QColor("white")));
520 painter->fillRect(0, 0, g_width, g_height, QBrush(QBrush::CrossPattern));
521 delete painter;
522 g_DS = new QPixmap(480, 480);
523 g_P1 = new QPainter();
524 g_P2 = new QPainter();
525 g_ClipRect = new QRegion(0, 0, g_width, g_height);
526 desktop = QApplication::desktop();
527 w = desktop->width(); // returns screen width
528 h = desktop->height(); // returns screen height
529 g_MW->resize(g_width, g_height);
530 if (w < g_width || h < g_height)
531 {
532 g_SV->resize(w, h);
533 }
534 else
535 {
536 g_SV->resize(g_width + 4, g_height + 4);
537 }
538 g_SV->setMaximumWidth(g_width + 4);
539 g_SV->setMaximumHeight(g_height + 4);
540 g_App->setMainWidget(g_SV);
541 g_SV->show();
542 g_MW->setMouseTracking(true);
543 if (g_title[0] != 0)
544 {
545 g_SV->setCaption(g_title);
546 }
547
548 /* XGrayKey(0, 64, AnyModifie, SV->winId(), 0, GrabModeAsync, GrabModeAsync);
549 XGrayKey(0, 113, AnyModifie, SV->winId(), 0, GrabModeAsync, GrabModeAsync);
550 XGrayKey(0, 37, AnyModifie, SV-winId(), 0, GrabModeAsync, GrabModeAsync);
551 XGrayKey(0, 109, AnyModifie, SV->winId(), 0, GrabModeAsync, GrabModeAsync);
552 XGrayKey(0, 115, AnyModifie, SV->winId(), 0, GrabModeAsync, GrabModeAsync);
553 XGrayKey(0, 116, AnyModifie, SV->winId(), 0, GrabModeAsync, GrabModeAsync);
554 XGrayKey(0, 117, AnyModifie, SV->winId(), 0, GrabModeAsync, GrabModeAsync);
555 XGrayKey(0, 62, AnyModifie, SV->winId(), 0, GrabModeAsync, GrabModeAsync);
556 XGrayKey(0, 50, AnyModifie, SV->winId(), 0, GrabModeAsync, GrabModeAsync);*/
557
558 return 1;
559 }
560
561 //*****************************************************************************
562 void ui_main_loop(void)
563 {
564 // connect
565 if (!rdp_connect(g_servername, g_flags, "", "", "", ""))
566 {
567 return;
568 }
569 // start notifier
570 g_SocketNotifier = new QSocketNotifier(g_sock, QSocketNotifier::Read, g_MW);
571 g_MW->connect(g_SocketNotifier, SIGNAL(activated(int)),
572 g_MW, SLOT(dataReceived()));
573 g_UpAndRunning = 1;
574 // app main loop
575 g_App->exec();
576 }
577
578 //*****************************************************************************
579 void ui_destroy_window(void)
580 {
581 delete g_MW;
582 delete g_SV;
583 delete g_BS;
584 delete g_DS;
585 delete g_P1;
586 delete g_P2;
587 delete g_ClipRect;
588 }
589
590 /*****************************************************************************/
591 void ui_bell(void)
592 {
593 }
594
595 /*****************************************************************************/
596 int ui_select(int in_val)
597 {
598 if (g_sock == 0)
599 {
600 g_sock = in_val;
601 }
602 return 1;
603 }
604
605 /*****************************************************************************/
606 void ui_destroy_cursor(void * cursor)
607 {
608 QCursor * Cursor;
609 Cursor = (QCursor*)cursor;
610 if (Cursor != NULL)
611 {
612 delete Cursor;
613 }
614 }
615
616 /*****************************************************************************/
617 void* ui_create_glyph(int width, int height, uint8 * data)
618 {
619 QBitmap * Bitmap;
620 Bitmap = new QBitmap(width, height, data);
621 Bitmap->setMask(*Bitmap);
622 return (HGLYPH)Bitmap;
623 }
624
625 /*****************************************************************************/
626 void ui_destroy_glyph(void * glyph)
627 {
628 QBitmap* Bitmap;
629 Bitmap = (QBitmap*)glyph;
630 delete Bitmap;
631 }
632
633 /*****************************************************************************/
634 void ui_destroy_bitmap(void * bmp)
635 {
636 QPixmap * Pixmap;
637 Pixmap = (QPixmap*)bmp;
638 delete Pixmap;
639 }
640
641 /*****************************************************************************/
642 void ui_reset_clip(void)
643 {
644 g_P1->setClipRect(0, 0, g_width, g_height);
645 g_P2->setClipRect(0, 0, g_width, g_height);
646 delete g_ClipRect;
647 g_ClipRect = new QRegion(0, 0, g_width, g_height);
648 }
649
650 /*****************************************************************************/
651 void ui_set_clip(int x, int y, int cx, int cy)
652 {
653 g_P1->setClipRect(x, y, cx, cy);
654 g_P2->setClipRect(x, y, cx, cy);
655 delete g_ClipRect;
656 g_ClipRect = new QRegion(x, y, cx, cy);
657 }
658
659 /*****************************************************************************/
660 void * ui_create_colourmap(COLOURMAP * colours)
661 {
662 QColorMap* LCM;
663 int i, r, g, b;
664 LCM = (QColorMap*)malloc(sizeof(QColorMap));
665 memset(LCM, 0, sizeof(QColorMap));
666 i = 0;
667 while (i < colours->ncolours && i < 256)
668 {
669 r = colours->colours[i].red;
670 g = colours->colours[i].green;
671 b = colours->colours[i].blue;
672 LCM->RGBColors[i] = (r << 16) | (g << 8) | b;
673 i++;
674 }
675 LCM->NumColors = colours->ncolours;
676 return LCM;
677 }
678
679 //*****************************************************************************
680 // todo, does this leak at end of program
681 void ui_destroy_colourmap(HCOLOURMAP map)
682 {
683 QColorMap * LCM;
684 LCM = (QColorMap*)map;
685 if (LCM == NULL)
686 return;
687 free(LCM);
688 }
689
690 /*****************************************************************************/
691 void ui_set_colourmap(void * map)
692 {
693 // destoy old colormap
694 ui_destroy_colourmap(g_CM);
695 g_CM = (QColorMap*)map;
696 }
697
698 /*****************************************************************************/
699 HBITMAP ui_create_bitmap(int width, int height, uint8 * data)
700 {
701 QImage * Image = NULL;
702 QPixmap * Pixmap;
703 uint32 * d = NULL;
704 uint16 * s;
705 int i;
706
707 switch (g_server_bpp)
708 {
709 case 8:
710 Image = new QImage(data, width, height, 8, (QRgb*)&g_CM->RGBColors,
711 g_CM->NumColors, QImage::IgnoreEndian);
712 break;
713 case 15:
714 d = (uint32*)malloc(width * height * 4);
715 s = (uint16*)data;
716 for (i = 0; i < width * height; i++)
717 {
718 d[i] = Color15to32(s[i]);
719 }
720 Image = new QImage((uint8*)d, width, height, 32, NULL,
721 0, QImage::IgnoreEndian);
722 break;
723 case 16:
724 d = (uint32*)malloc(width * height * 4);
725 s = (uint16*)data;
726 for (i = 0; i < width * height; i++)
727 {
728 d[i] = Color16to32(s[i]);
729 }
730 Image = new QImage((uint8*)d, width, height, 32, NULL,
731 0, QImage::IgnoreEndian);
732 break;
733 case 24:
734 d = (uint32*)malloc(width * height * 4);
735 memset(d, 0, width * height * 4);
736 for (i = 0; i < width * height; i++)
737 {
738 memcpy(d + i, data + i * 3, 3);
739 }
740 Image = new QImage((uint8*)d, width, height, 32, NULL,
741 0, QImage::IgnoreEndian);
742 break;
743 }
744 if (Image == NULL)
745 {
746 return NULL;
747 }
748 Pixmap = new QPixmap();
749 Pixmap->convertFromImage(*Image);
750 delete Image;
751 if (d != NULL)
752 {
753 free(d);
754 }
755 return (HBITMAP)Pixmap;
756 }
757
758 //******************************************************************************
759 // adjust coordinates for cliping rect
760 int WarpCoords(int * x, int * y, int * cx, int * cy, int * srcx, int * srcy)
761 {
762 int dx, dy;
763 QRect InRect(*x, *y, *cx, *cy);
764 QRect OutRect;
765 QRect CRect = g_ClipRect->boundingRect();
766 OutRect = InRect.intersect(CRect);
767 if (OutRect.isEmpty())
768 {
769 return False;
770 }
771 dx = OutRect.x() - InRect.x();
772 dy = OutRect.y() - InRect.y();
773 *x = OutRect.x();
774 *y = OutRect.y();
775 *cx = OutRect.width();
776 *cy = OutRect.height();
777 *srcx = *srcx + dx;
778 *srcy = *srcy + dy;
779 return True;
780 }
781
782 //******************************************************************************
783 // needed because bitBlt don't seem to care about clipping rects
784 // also has 2 dsts and src can be null
785 void bitBltClip(QPaintDevice * dst1, QPaintDevice * dst2, int dx, int dy,
786 QPaintDevice * src, int sx, int sy, int sw, int sh,
787 Qt::RasterOp rop, bool im)
788 {
789 if (WarpCoords(&dx, &dy, &sw, &sh, &sx, &sy))
790 {
791 if (dst1 != NULL)
792 {
793 if (src == NULL)
794 {
795 bitBlt(dst1, dx, dy, dst1, sx, sy, sw, sh, rop, im);
796 }
797 else
798 {
799 bitBlt(dst1, dx, dy, src, sx, sy, sw, sh, rop, im);
800 }
801 }
802 if (dst2 != NULL)
803 {
804 if (src == NULL)
805 {
806 bitBlt(dst2, dx, dy, dst2, sx, sy, sw, sh, rop, im);
807 }
808 else
809 {
810 bitBlt(dst2, dx, dy, src, sx, sy, sw, sh, rop, im);
811 }
812 }
813 }
814 }
815
816 #define DO_GLYPH(ttext,idx) \
817 { \
818 glyph = cache_get_font (font, ttext[idx]); \
819 if (!(flags & TEXT2_IMPLICIT_X)) \
820 { \
821 xyoffset = ttext[++idx]; \
822 if ((xyoffset & 0x80)) \
823 { \
824 if (flags & TEXT2_VERTICAL) \
825 y += ttext[idx+1] | (ttext[idx+2] << 8); \
826 else \
827 x += ttext[idx+1] | (ttext[idx+2] << 8); \
828 idx += 2; \
829 } \
830 else \
831 { \
832 if (flags & TEXT2_VERTICAL) \
833 y += xyoffset; \
834 else \
835 x += xyoffset; \
836 } \
837 } \
838 if (glyph != NULL) \
839 { \
840 g_P2->drawPixmap(x + glyph->offset, y + glyph->baseline, \
841 *((QBitmap*)glyph->pixmap)); \
842 if (flags & TEXT2_IMPLICIT_X) \
843 x += glyph->width; \
844 } \
845 }
846
847 //*****************************************************************************
848 void ui_draw_text(uint8 font, uint8 flags, uint8 opcode, int mixmode,
849 int x, int y, int clipx, int clipy,
850 int clipcx, int clipcy, int boxx,
851 int boxy, int boxcx, int boxcy, BRUSH * brush,
852 int bgcolour, int fgcolour, uint8 * text, uint8 length)
853 {
854 FONTGLYPH * glyph;
855 int i, j, xyoffset;
856 DATABLOB * entry;
857
858 SetColorx(&g_Color1, fgcolour);
859 SetColorx(&g_Color2, bgcolour);
860 g_P2->setBackgroundColor(g_Color2);
861 g_P2->setPen(g_Color1);
862 if (boxcx > 1)
863 {
864 g_P2->fillRect(boxx, boxy, boxcx, boxcy, QBrush(g_Color2));
865 }
866 else if (mixmode == MIX_OPAQUE)
867 {
868 g_P2->fillRect(clipx, clipy, clipcx, clipcy, QBrush(g_Color2));
869 }
870
871 /* Paint text, character by character */
872 for (i = 0; i < length;)
873 {
874 switch (text[i])
875 {
876 case 0xff:
877 if (i + 2 < length)
878 {
879 cache_put_text(text[i + 1], text, text[i + 2]);
880 }
881 else
882 {
883 error("this shouldn't be happening\n");
884 exit(1);
885 }
886 /* this will move pointer from start to first character after FF
887 command */
888 length -= i + 3;
889 text = &(text[i + 3]);
890 i = 0;
891 break;
892
893 case 0xfe:
894 entry = cache_get_text(text[i + 1]);
895 if (entry != NULL)
896 {
897 if ((((uint8 *) (entry->data))[1] == 0) &&
898 (!(flags & TEXT2_IMPLICIT_X)))
899 {
900 if (flags & TEXT2_VERTICAL)
901 {
902 y += text[i + 2];
903 }
904 else
905 {
906 x += text[i + 2];
907 }
908 }
909 for (j = 0; j < entry->size; j++)
910 {
911 DO_GLYPH(((uint8 *) (entry->data)), j);
912 }
913 }
914 if (i + 2 < length)
915 {
916 i += 3;
917 }
918 else
919 {
920 i += 2;
921 }
922 length -= i;
923 /* this will move pointer from start to first character after FE
924 command */
925 text = &(text[i]);
926 i = 0;
927 break;
928
929 default:
930 DO_GLYPH(text, i);
931 i++;
932 break;
933 }
934 }
935 if (boxcx > 1)
936 {
937 bitBltClip(g_MW, NULL, boxx, boxy, g_BS, boxx, boxy, boxcx, boxcy,
938 Qt::CopyROP, true);
939 }
940 else
941 {
942 bitBltClip(g_MW, NULL, clipx, clipy, g_BS, clipx, clipy, clipcx,
943 clipcy, Qt::CopyROP, true);
944 }
945 }
946
947 /*****************************************************************************/
948 void ui_line(uint8 opcode, int startx, int starty, int endx, int endy,
949 PEN * pen)
950 {
951 SetColorx(&g_Color1, pen->colour);
952 SetOpCode(opcode);
953 g_P1->setPen(g_Color1);
954 g_P1->moveTo(startx, starty);
955 g_P1->lineTo(endx, endy);
956 g_P2->setPen(g_Color1);
957 g_P2->moveTo(startx, starty);
958 g_P2->lineTo(endx, endy);
959 ResetOpCode(opcode);
960 }
961
962 /*****************************************************************************/
963 // not used
964 void ui_triblt(uint8 opcode, int x, int y, int cx, int cy,
965 HBITMAP src, int srcx, int srcy,
966 BRUSH* brush, int bgcolour, int fgcolour)
967 {
968 }
969
970 /*****************************************************************************/
971 void ui_memblt(uint8 opcode, int x, int y, int cx, int cy,
972 HBITMAP src, int srcx, int srcy)
973 {
974 QPixmap* Pixmap;
975 Pixmap = (QPixmap*)src;
976 if (Pixmap != NULL)
977 {
978 SetOpCode(opcode);
979 g_P1->drawPixmap(x, y, *Pixmap, srcx, srcy, cx, cy);
980 g_P2->drawPixmap(x, y, *Pixmap, srcx, srcy, cx, cy);
981 ResetOpCode(opcode);
982 }
983 }
984
985 //******************************************************************************
986 void CommonDeskSave(QPixmap* Pixmap1, QPixmap* Pixmap2, int Offset, int x,
987 int y, int cx, int cy, int dir)
988 {
989 int lx;
990 int ly;
991 int x1;
992 int y1;
993 int width;
994 int lcx;
995 int right;
996 int bottom;
997 lx = Offset % 480;
998 ly = Offset / 480;
999 y1 = y;
1000 right = x + cx;
1001 bottom = y + cy;
1002 while (y1 < bottom)
1003 {
1004 x1 = x;
1005 lcx = cx;
1006 while (x1 < right)
1007 {
1008 width = 480 - lx;
1009 if (width > lcx)
1010 width = lcx;
1011 if (dir == 0)
1012 bitBlt(Pixmap1, lx, ly, Pixmap2, x1, y1, width, 1, Qt::CopyROP, true);
1013 else
1014 bitBlt(Pixmap2, x1, y1, Pixmap1, lx, ly, width, 1, Qt::CopyROP, true);
1015 lx = lx + width;
1016 if (lx >= 480)
1017 {
1018 lx = 0;
1019 ly++;
1020 if (ly >= 480)
1021 ly = 0;
1022 }
1023 lcx = lcx - width;
1024 x1 = x1 + width;
1025 }
1026 y1++;
1027 }
1028 }
1029
1030 /*****************************************************************************/
1031 void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
1032 {
1033 QPixmap * Pixmap;
1034
1035 Pixmap = new QPixmap(cx, cy);
1036 CommonDeskSave(g_DS, Pixmap, offset, 0, 0, cx, cy, 1);
1037 bitBltClip(g_MW, g_BS, x, y, Pixmap, 0, 0, cx, cy, Qt::CopyROP, true);
1038 delete Pixmap;
1039 }
1040
1041 /*****************************************************************************/
1042 void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
1043 {
1044 CommonDeskSave(g_DS, g_BS, offset, x, y, cx, cy, 0);
1045 }
1046
1047 /*****************************************************************************/
1048 void ui_rect(int x, int y, int cx, int cy, int colour)
1049 {
1050 SetColorx(&g_Color1, colour);
1051 g_P1->fillRect(x, y, cx, cy, QBrush(g_Color1));
1052 g_P2->fillRect(x, y, cx, cy, QBrush(g_Color1));
1053 }
1054
1055 /*****************************************************************************/
1056 void ui_screenblt(uint8 opcode, int x, int y, int cx, int cy,
1057 int srcx, int srcy)
1058 {
1059 SetOpCode(opcode);
1060 bitBltClip(g_MW, g_BS, x, y, NULL, srcx, srcy, cx, cy, Qt::CopyROP, true);
1061 ResetOpCode(opcode);
1062 }
1063
1064 /*****************************************************************************/
1065 void ui_patblt(uint8 opcode, int x, int y, int cx, int cy,
1066 BRUSH* brush, int bgcolour, int fgcolour)
1067 {
1068 QBitmap* Bitmap;
1069 QBrush* Brush;
1070 uint8 ipattern[8], i;
1071 SetOpCode(opcode);
1072 switch (brush->style)
1073 {
1074 case 0:
1075 SetColorx(&g_Color1, fgcolour);
1076 g_P2->fillRect(x, y, cx, cy, QBrush(g_Color1));
1077 break;
1078 case 3:
1079 SetColorx(&g_Color1, fgcolour);
1080 SetColorx(&g_Color2, bgcolour);
1081 for (i = 0; i != 8; i++)
1082 {
1083 ipattern[7 - i] = ~brush->pattern[i];
1084 }
1085 Bitmap = new QBitmap(8, 8, ipattern);
1086 Brush = new QBrush(g_Color1, *Bitmap);
1087 g_P2->setBackgroundMode(Qt::OpaqueMode);
1088 g_P2->setBrushOrigin(brush->xorigin, brush->yorigin);
1089 g_P2->setBackgroundColor(g_Color2);
1090 g_P2->fillRect(x, y, cx, cy, *Brush);
1091 delete Brush;
1092 delete Bitmap;
1093 g_P2->setBackgroundMode(Qt::TransparentMode);
1094 g_P2->setBrushOrigin(0, 0);
1095 break;
1096 }
1097 ResetOpCode(opcode);
1098 bitBltClip(g_MW, NULL, x, y, g_BS, x, y, cx, cy, Qt::CopyROP, true);
1099 }
1100
1101 /*****************************************************************************/
1102 void ui_destblt(uint8 opcode, int x, int y, int cx, int cy)
1103 {
1104 SetOpCode(opcode);
1105 g_P1->fillRect(x, y, cx, cy, QBrush(QColor("black")));
1106 g_P2->fillRect(x, y, cx, cy, QBrush(QColor("black")));
1107 ResetOpCode(opcode);
1108 }
1109
1110 /*****************************************************************************/
1111 void ui_move_pointer(int x, int y)
1112 {
1113 }
1114
1115 /*****************************************************************************/
1116 void ui_set_null_cursor(void)
1117 {
1118 g_MW->setCursor(10); // Qt::BlankCursor
1119 }
1120
1121 /*****************************************************************************/
1122 void ui_paint_bitmap(int x, int y, int cx, int cy,
1123 int width, int height, uint8* data)
1124 {
1125 QImage * Image = NULL;
1126 QPixmap * Pixmap;
1127 uint32 * d = NULL;
1128 uint16 * s;
1129 int i;
1130
1131 switch (g_server_bpp)
1132 {
1133 case 8:
1134 Image = new QImage(data, width, height, 8, (QRgb*)&g_CM->RGBColors,
1135 g_CM->NumColors, QImage::IgnoreEndian);
1136 break;
1137 case 15:
1138 d = (uint32*)malloc(width * height * 4);
1139 s = (uint16*)data;
1140 for (i = 0; i < width * height; i++)
1141 {
1142 d[i] = Color15to32(s[i]);
1143 }
1144 Image = new QImage((uint8*)d, width, height, 32, NULL,
1145 0, QImage::IgnoreEndian);
1146 break;
1147 case 16:
1148 d = (uint32*)malloc(width * height * 4);
1149 s = (uint16*)data;
1150 for (i = 0; i < width * height; i++)
1151 {
1152 d[i] = Color16to32(s[i]);
1153 }
1154 Image = new QImage((uint8*)d, width, height, 32, NULL,
1155 0, QImage::IgnoreEndian);
1156 break;
1157 case 24:
1158 d = (uint32*)malloc(width * height * 4);
1159 memset(d, 0, width * height * 4);
1160 for (i = 0; i < width * height; i++)
1161 {
1162 memcpy(d + i, data + i * 3, 3);
1163 }
1164 Image = new QImage((uint8*)d, width, height, 32, NULL,
1165 0, QImage::IgnoreEndian);
1166 break;
1167 }
1168 if (Image == NULL)
1169 {
1170 return;
1171 }
1172 Pixmap = new QPixmap();
1173 Pixmap->convertFromImage(*Image);
1174 g_P1->drawPixmap(x, y, *Pixmap, 0, 0, cx, cy);
1175 g_P2->drawPixmap(x, y, *Pixmap, 0, 0, cx, cy);
1176 delete Image;
1177 delete Pixmap;
1178 if (d != NULL)
1179 {
1180 free(d);
1181 }
1182 }
1183
1184 //******************************************************************************
1185 int Is24On(uint8* Data, int X, int Y)
1186 {
1187 uint8 R, G, B;
1188 int Start;
1189 Start = Y * 32 * 3 + X * 3;
1190 R = Data[Start];
1191 G = Data[Start + 1];
1192 B = Data[Start + 2];
1193 return !((R == 0) && (G == 0) && (B == 0));
1194 }
1195
1196 //******************************************************************************
1197 int Is1On(uint8* Data, int X, int Y)
1198 {
1199 int Start;
1200 int Shift;
1201 Start = (Y * 32) / 8 + X / 8;
1202 Shift = X % 8;
1203 return (Data[Start] & (0x80 >> Shift)) == 0;
1204 }
1205
1206 //******************************************************************************
1207 void Set1(uint8* Data, int X, int Y)
1208 {
1209 int Start;
1210 int Shift;
1211 Start = (Y * 32) / 8 + X / 8;
1212 Shift = X % 8;
1213 Data[Start] = Data[Start] | (0x80 >> Shift);
1214 }
1215
1216 //******************************************************************************
1217 void FlipOver(uint8* Data)
1218 {
1219 uint8 AData[128];
1220 int Index;
1221 memcpy(AData, Data, 128);
1222 for (Index = 0; Index <= 31; Index++)
1223 {
1224 Data[127 - (Index * 4 + 3)] = AData[Index * 4];
1225 Data[127 - (Index * 4 + 2)] = AData[Index * 4 + 1];
1226 Data[127 - (Index * 4 + 1)] = AData[Index * 4 + 2];
1227 Data[127 - Index * 4] = AData[Index * 4 + 3];
1228 }
1229 }
1230
1231 /*****************************************************************************/
1232 void ui_set_cursor(HCURSOR cursor)
1233 {
1234 QCursor* Cursor;
1235 Cursor = (QCursor*)cursor;
1236 if (Cursor != NULL)
1237 g_MW->setCursor(*Cursor);
1238 }
1239
1240 /*****************************************************************************/
1241 HCURSOR ui_create_cursor(unsigned int x, unsigned int y,
1242 int width, int height,
1243 uint8* andmask, uint8* xormask)
1244 {
1245 uint8 AData[128];
1246 uint8 AMask[128];
1247 QBitmap* DataBitmap;
1248 QBitmap* MaskBitmap;
1249 QCursor* Cursor;
1250 int I1, I2, BOn, MOn;
1251
1252 if (width != 32 || height != 32)
1253 {
1254 return 0;
1255 }
1256 memset(AData, 0, 128);
1257 memset(AMask, 0, 128);
1258 for (I1 = 0; I1 <= 31; I1++)
1259 {
1260 for (I2 = 0; I2 <= 31; I2++)
1261 {
1262 MOn = Is24On(xormask, I1, I2);
1263 BOn = Is1On(andmask, I1, I2);
1264 if (BOn ^ MOn) // xor
1265 {
1266 Set1(AData, I1, I2);
1267 if (!MOn)
1268 {
1269 Set1(AMask, I1, I2);
1270 }
1271 }
1272 if (MOn)
1273 {
1274 Set1(AMask, I1, I2);
1275 }
1276 }
1277 }
1278 FlipOver(AData);
1279 FlipOver(AMask);
1280 DataBitmap = new QBitmap(32, 32, AData);
1281 MaskBitmap = new QBitmap(32, 32, AMask);
1282 Cursor = new QCursor(*DataBitmap, *MaskBitmap, x, y);
1283 delete DataBitmap;
1284 delete MaskBitmap;
1285 return Cursor;
1286 }
1287
1288 /*****************************************************************************/
1289 uint16 ui_get_numlock_state(uint32 state)
1290 {
1291 return 0;
1292 }
1293
1294 /*****************************************************************************/
1295 uint32 read_keyboard_state(void)
1296 {
1297 return 0;
1298 }
1299
1300 /*****************************************************************************/
1301 void ui_resize_window(void)
1302 {
1303 }
1304
1305 /*****************************************************************************/
1306 void ui_polygon(uint8 opcode, uint8 fillmode, POINT * point, int npoints,
1307 BRUSH * brush, int bgcolour, int fgcolour)
1308 {
1309 }
1310
1311 /*****************************************************************************/
1312 /* todo, use qt function for this (QPainter::drawPolyline) */
1313 void ui_polyline(uint8 opcode, POINT * points, int npoints, PEN * pen)
1314 {
1315 int i, x, y, dx, dy;
1316
1317 if (npoints > 0)
1318 {
1319 x = points[0].x;
1320 y = points[0].y;
1321 for (i = 1; i < npoints; i++)
1322 {
1323 dx = points[i].x;
1324 dy = points[i].y;
1325 ui_line(opcode, x, y, x + dx, y + dy, pen);
1326 x = x + dx;
1327 y = y + dy;
1328 }
1329 }
1330 }
1331
1332 /*****************************************************************************/
1333 void ui_ellipse(uint8 opcode, uint8 fillmode,
1334 int x, int y, int cx, int cy,
1335 BRUSH * brush, int bgcolour, int fgcolour)
1336 {
1337 }
1338
1339 /*****************************************************************************/
1340 void generate_random(uint8 * random)
1341 {
1342 QFile File("/dev/random");
1343 File.open(IO_ReadOnly);
1344 if (File.readBlock((char*)random, 32) == 32)
1345 {
1346 return;
1347 }
1348 warning("no /dev/random\n");
1349 memcpy(random, "12345678901234567890123456789012", 32);
1350 }
1351
1352 /*****************************************************************************/
1353 void save_licence(uint8 * data, int length)
1354 {
1355 char * home, * path, * tmppath;
1356 int fd;
1357
1358 home = getenv("HOME");
1359 if (home == NULL)
1360 {
1361 return;
1362 }
1363 path = (char *) xmalloc(strlen(home) + strlen(g_hostname) +
1364 sizeof("/.rdesktop/licence."));
1365 sprintf(path, "%s/.rdesktop", home);
1366 if ((mkdir(path, 0700) == -1) && errno != EEXIST)
1367 {
1368 perror(path);
1369 return;
1370 }
1371 /* write licence to licence.hostname.new, then atomically rename to
1372 licence.hostname */
1373 sprintf(path, "%s/.rdesktop/licence.%s", home, g_hostname);
1374 tmppath = (char *) xmalloc(strlen(path) + sizeof(".new"));
1375 strcpy(tmppath, path);
1376 strcat(tmppath, ".new");
1377 fd = open(tmppath, O_WRONLY | O_CREAT | O_TRUNC, 0600);
1378 if (fd == -1)
1379 {
1380 perror(tmppath);
1381 return;
1382 }
1383 if (write(fd, data, length) != length)
1384 {
1385 perror(tmppath);
1386 unlink(tmppath);
1387 }
1388 else if (rename(tmppath, path) == -1)
1389 {
1390 perror(path);
1391 unlink(tmppath);
1392 }
1393 close(fd);
1394 xfree(tmppath);
1395 xfree(path);
1396 }
1397
1398 /*****************************************************************************/
1399 int load_licence(uint8 ** data)
1400 {
1401 char * home, * path;
1402 struct stat st;
1403 int fd, length;
1404
1405 home = getenv("HOME");
1406 if (home == NULL)
1407 {
1408 return -1;
1409 }
1410 path = (char *) xmalloc(strlen(home) + strlen(g_hostname) +
1411 sizeof("/.rdesktop/licence."));
1412 sprintf(path, "%s/.rdesktop/licence.%s", home, g_hostname);
1413 fd = open(path, O_RDONLY);
1414 if (fd == -1)
1415 {
1416 return -1;
1417 }
1418 if (fstat(fd, &st))
1419 {
1420 return -1;
1421 }
1422 *data = (uint8 *) xmalloc(st.st_size);
1423 length = read(fd, *data, st.st_size);
1424 close(fd);
1425 xfree(path);
1426 return length;
1427 }
1428
1429 /*****************************************************************************/
1430 void* xrealloc(void * in_val, int size)
1431 {
1432 return realloc(in_val, size);
1433 }
1434
1435 /*****************************************************************************/
1436 void* xmalloc(int size)
1437 {
1438 return malloc(size);
1439 }
1440
1441 /*****************************************************************************/
1442 void xfree(void * in_val)
1443 {
1444 if (in_val != NULL)
1445 {
1446 free(in_val);
1447 }
1448 }
1449
1450 /*****************************************************************************/
1451 void warning(char * format, ...)
1452 {
1453 va_list ap;
1454
1455 fprintf(stderr, "WARNING: ");
1456 va_start(ap, format);
1457 vfprintf(stderr, format, ap);
1458 va_end(ap);
1459 }
1460
1461 /*****************************************************************************/
1462 void unimpl(char * format, ...)
1463 {
1464 va_list ap;
1465
1466 fprintf(stderr, "NOT IMPLEMENTED: ");
1467 va_start(ap, format);
1468 vfprintf(stderr, format, ap);
1469 va_end(ap);
1470 }
1471
1472 /*****************************************************************************/
1473 void error(char * format, ...)
1474 {
1475 va_list ap;
1476
1477 fprintf(stderr, "ERROR: ");
1478 va_start(ap, format);
1479 vfprintf(stderr, format, ap);
1480 va_end(ap);
1481 }
1482
1483 /*****************************************************************************/
1484 void out_params(void)
1485 {
1486 fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
1487 fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2005 Matt Chapman.\n");
1488 fprintf(stderr, "QT uiport by Jay Sorg\n");
1489 fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
1490 fprintf(stderr, "Usage: qtrdesktop [options] server\n");
1491 fprintf(stderr, " -g: desktop geometry (WxH)\n");
1492 fprintf(stderr, " -4: use RDP version 4\n");
1493 fprintf(stderr, " -5: use RDP version 5 (default)\n");
1494 fprintf(stderr, " -t: tcp port)\n");
1495 fprintf(stderr, " -a: connection colour depth\n");
1496 fprintf(stderr, " -T: window title\n");
1497 fprintf(stderr, " -P: use persistent bitmap caching\n");
1498 fprintf(stderr, " -0: attach to console\n");
1499 fprintf(stderr, " -z: enable rdp compression\n");
1500 fprintf(stderr, "\n");
1501 }
1502
1503 /*****************************************************************************/
1504 /* produce a hex dump */
1505 void hexdump(uint8 * p, uint32 len)
1506 {
1507 uint8 * line = p;
1508 int i, thisline;
1509 uint32 offset = 0;
1510
1511 while (offset < len)
1512 {
1513 printf("%04x ", offset);
1514 thisline = len - offset;
1515 if (thisline > 16)
1516 {
1517 thisline = 16;
1518 }
1519 for (i = 0; i < thisline; i++)
1520 {
1521 printf("%02x ", line[i]);
1522 }
1523 for (; i < 16; i++)
1524 {
1525 printf(" ");
1526 }
1527 for (i = 0; i < thisline; i++)
1528 {
1529 printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
1530 }
1531 printf("\n");
1532 offset += thisline;
1533 line += thisline;
1534 }
1535 }
1536
1537 /*****************************************************************************/
1538 int rd_pstcache_mkdir(void)
1539 {
1540 char * home;
1541 char bmpcache_dir[256];
1542
1543 home = getenv("HOME");
1544 if (home == NULL)
1545 {
1546 return False;
1547 }
1548 sprintf(bmpcache_dir, "%s/%s", home, ".rdesktop");
1549 if ((mkdir(bmpcache_dir, S_IRWXU) == -1) && errno != EEXIST)
1550 {
1551 perror(bmpcache_dir);
1552 return False;
1553 }
1554 sprintf(bmpcache_dir, "%s/%s", home, ".rdesktop/cache");
1555 if ((mkdir(bmpcache_dir, S_IRWXU) == -1) && errno != EEXIST)
1556 {
1557 perror(bmpcache_dir);
1558 return False;
1559 }
1560 return True;
1561 }
1562
1563 /*****************************************************************************/
1564 int rd_open_file(char * filename)
1565 {
1566 char * home;
1567 char fn[256];
1568 int fd;
1569
1570 home = getenv("HOME");
1571 if (home == NULL)
1572 {
1573 return -1;
1574 }
1575 sprintf(fn, "%s/.rdesktop/%s", home, filename);
1576 fd = open(fn, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
1577 if (fd == -1)
1578 {
1579 perror(fn);
1580 }
1581 return fd;
1582 }
1583
1584 /*****************************************************************************/
1585 void rd_close_file(int fd)
1586 {
1587 close(fd);
1588 }
1589
1590 /*****************************************************************************/
1591 int rd_read_file(int fd, void * ptr, int len)
1592 {
1593 return read(fd, ptr, len);
1594 }
1595
1596 /*****************************************************************************/
1597 int rd_write_file(int fd, void * ptr, int len)
1598 {
1599 return write(fd, ptr, len);
1600 }
1601
1602 /*****************************************************************************/
1603 int rd_lseek_file(int fd, int offset)
1604 {
1605 return lseek(fd, offset, SEEK_SET);
1606 }
1607
1608 /*****************************************************************************/
1609 int rd_lock_file(int fd, int start, int len)
1610 {
1611 struct flock lock;
1612
1613 lock.l_type = F_WRLCK;
1614 lock.l_whence = SEEK_SET;
1615 lock.l_start = start;
1616 lock.l_len = len;
1617 if (fcntl(fd, F_SETLK, &lock) == -1)
1618 {
1619 return False;
1620 }
1621 return True;
1622 }
1623
1624 /*****************************************************************************/
1625 void get_username_and_hostname(void)
1626 {
1627 char fullhostname[64];
1628 char * p;
1629 struct passwd * pw;
1630
1631 STRNCPY(g_username, "unknown", sizeof(g_username));
1632 STRNCPY(g_hostname, "unknown", sizeof(g_hostname));
1633 pw = getpwuid(getuid());
1634 if (pw != NULL && pw->pw_name != NULL)
1635 {
1636 STRNCPY(g_username, pw->pw_name, sizeof(g_username));
1637 }
1638 if (gethostname(fullhostname, sizeof(fullhostname)) != -1)
1639 {
1640 p = strchr(fullhostname, '.');
1641 if (p != NULL)
1642 {
1643 *p = 0;
1644 }
1645 STRNCPY(g_hostname, fullhostname, sizeof(g_hostname));
1646 }
1647 }
1648
1649 /*****************************************************************************/
1650 int parse_parameters(int in_argc, char ** in_argv)
1651 {
1652 int i;
1653 char * p;
1654
1655 if (in_argc <= 1)
1656 {
1657 out_params();
1658 return 0;
1659 }
1660 g_argc = in_argc;
1661 g_argv = in_argv;
1662 for (i = 1; i < in_argc; i++)
1663 {
1664 strcpy(g_servername, in_argv[i]);
1665 if (strcmp(in_argv[i], "-g") == 0)
1666 {
1667 g_width = strtol(in_argv[i + 1], &p, 10);
1668 if (g_width <= 0)
1669 {
1670 error("invalid geometry\n");
1671 return 0;
1672 }
1673 if (*p == 'x')
1674 {
1675 g_height = strtol(p + 1, NULL, 10);
1676 }
1677 if (g_height <= 0)
1678 {
1679 error("invalid geometry\n");
1680 return 0;
1681 }
1682 g_width = (g_width + 3) & ~3;
1683 }
1684 else if (strcmp(in_argv[i], "-T") == 0)
1685 {
1686 strcpy(g_title, in_argv[i + 1]);
1687 }
1688 else if (strcmp(in_argv[i], "-4") == 0)
1689 {
1690 g_use_rdp5 = 0;
1691 }
1692 else if (strcmp(in_argv[i], "-5") == 0)
1693 {
1694 g_use_rdp5 = 1;
1695 }
1696 else if (strcmp(in_argv[i], "-a") == 0)
1697 {
1698 g_server_bpp = strtol(in_argv[i + 1], &p, 10);
1699 if (g_server_bpp != 8 && g_server_bpp != 15 &&
1700 g_server_bpp != 16 && g_server_bpp != 24)
1701 {
1702 error("invalid bpp\n");
1703 return 0;
1704 }
1705 }
1706 else if (strcmp(in_argv[i], "-t") == 0)
1707 {
1708 g_tcp_port_rdp = strtol(in_argv[i + 1], &p, 10);
1709 }
1710 else if (strcmp(in_argv[i], "-P") == 0)
1711 {
1712 g_bitmap_cache_persist_enable = 1;
1713 }
1714 else if (strcmp(in_argv[i], "-0") == 0)
1715 {
1716 g_console_session = 1;
1717 }
1718 else if (strcmp(in_argv[i], "-z") == 0)
1719 {
1720 g_flags |= RDP_COMPRESSION;
1721 }
1722 }
1723 return 1;
1724 }
1725
1726 /*****************************************************************************/
1727 int main(int in_argc, char** in_argv)
1728 {
1729 get_username_and_hostname();
1730 if (!parse_parameters(in_argc, in_argv))
1731 {
1732 return 0;
1733 }
1734 if (!ui_init())
1735 {
1736 return 1;
1737 }
1738 if (!ui_create_window())
1739 {
1740 return 1;
1741 }
1742 ui_main_loop();
1743 ui_destroy_window();
1744 ui_deinit();
1745 return 0;
1746 }

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26