/[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 1395 - (show annotations)
Sat Feb 10 08:03:18 2007 UTC (17 years, 4 months ago) by jsorg71
File size: 48154 byte(s)
RD_ prefix and copyright year update

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26