/[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 900 - (show annotations)
Sun May 1 00:14:20 2005 UTC (19 years ago) by jdmeijer
File size: 47411 byte(s)
add additional compression flag

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26