/[rdesktop]/sourceforge.net/trunk/rdesktop/uiports/qtewin.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/qtewin.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 882 - (show annotations)
Tue Apr 5 03:22:15 2005 UTC (19 years, 2 months ago) by jsorg71
File size: 69162 byte(s)
added makefile_qte and new ui functions

1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 User interface services - QT Emb 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 //#define SHARP
22
23 #ifdef SHARP
24 #include <qpe/qpeapplication.h>
25 #else
26 #include <qapplication.h>
27 #endif
28 #include <qcursor.h>
29 #include <qmainwindow.h>
30 #include <qwidget.h>
31 #include <qpainter.h>
32 #include <qimage.h>
33 #include <qsocketnotifier.h>
34 #include <qscrollview.h>
35 #include <qmessagebox.h>
36 #include <qpushbutton.h>
37 #include <qlineedit.h>
38 #include <qcombobox.h>
39 #include <qlabel.h>
40 #include <qfile.h>
41 #include <qcheckbox.h>
42 #include <qpopupmenu.h>
43
44 #include <stdlib.h>
45 #include <stdarg.h> // va_list va_start va_end
46 #include <unistd.h> // gethostname
47 #include <pwd.h> // getpwuid
48
49 #include "../rdesktop.h"
50 #include "qtewin.h"
51
52 #define QT_OPTI
53
54 extern int g_tcp_port_rdp;
55 int g_encryption = 1;
56 int g_bitmap_cache = 1;
57 int g_bitmap_cache_persist_enable = 0;
58 int g_bitmap_cache_precache = 1;
59 int g_use_rdp5 = 1;
60 int g_desktop_save = 1;
61 int g_bitmap_compression = 1;
62 int g_polygon_ellipse_orders = 0;
63 int g_rdp5_performanceflags = 0;
64 int g_console_session = 0;
65 int g_keylayout = 0x409; /* Defaults to US keyboard layout */
66 int g_width = 640;
67 int g_height = 480;
68 int g_server_bpp = 8;
69 char g_hostname[16] = "";
70 char g_username[100] = "";
71
72 #ifdef WITH_RDPSND
73 extern int g_dsp_busy;
74 extern int g_dsp_fd;
75 int g_rdpsnd = 0;
76 static QSocketNotifier * g_SoundNotifier = 0;
77 #endif
78
79 /* types */
80 struct QColorMap
81 {
82 uint32 RGBColors[256];
83 uint32 NumColors;
84 };
85
86 struct bitmap
87 {
88 int w;
89 int h;
90 uint8 * data;
91 };
92
93 static int g_client_width = 640;
94 static int g_client_height = 480;
95 static uint32 g_flags = RDP_LOGON_NORMAL;
96 static char g_server[64] = "";
97 static char g_domain[16] = "";
98 static char g_password[16] = "";
99 static char g_shell[128] = "";
100 static char g_directory[32] = "";
101 static int g_fullscreen = 0;
102 static int g_global_sock = 0;
103 static int g_deactivated = 0;
104 static uint32 g_ext_disc_reason = 0;
105
106 static QSocketNotifier * g_SocketNotifier = 0;
107 #ifdef SHARP
108 static QPEApplication * g_App = 0;
109 #else
110 static QApplication * g_App = 0;
111 #endif
112 static QMyMainWindow * g_MW = 0;
113 static QMyScrollView * g_SV = 0;
114 static struct QColorMap * g_CM = 0;
115 static uint8 * g_BS = 0; /* the screen data */
116 static int g_clipx = 0;
117 static int g_clipy = 0;
118 static int g_clipcx = 0;
119 static int g_clipcy = 0;
120
121 #define BPP ((g_server_bpp + 7) / 8)
122 #define GETPIXEL8(d, x, y, w) (*(((uint8*)d) + ((y) * (w) + (x))))
123 #define GETPIXEL16(d, x, y, w) (*(((uint16*)d) + ((y) * (w) + (x))))
124 #define GETPIXEL32(d, x, y, w) (*(((uint32*)d) + ((y) * (w) + (x))))
125 #define SETPIXEL8(d, x, y, w, v) *(((uint8*)d) + ((y) * (w) + (x))) = v
126 #define SETPIXEL16(d, x, y, w, v) *(((uint16*)d) + ((y) * (w) + (x))) = v
127 #define SETPIXEL32(d, x, y, w, v) *(((uint32*)d) + ((y) * (w) + (x))) = v
128
129 /******************************************************************************/
130 void CleanString(QString * Item)
131 {
132 int i;
133
134 i = Item->length() - 1;
135 while (i >= 0)
136 {
137 if (Item->at(i) == 10 || Item->at(i) == 13)
138 {
139 Item->remove(i, 1);
140 }
141 i--;
142 }
143 }
144
145 /******************************************************************************/
146 QMyDialog::QMyDialog(QWidget * parent) : QDialog(parent, "Settings", true)
147 {
148 int i, j;
149 char * home;
150 char Text[256];
151 QString Line;
152 QString ItemName;
153 QString ItemValue;
154
155 // resize dialog
156 resize(230, 270);
157 // main list box
158 ListBox = new QListBox(this);
159 ListBox->move(10, 10);
160 ListBox->resize(200, 100);
161 connect(ListBox, SIGNAL(selectionChanged()), this, SLOT(ListBoxChanged()));
162 connect(ListBox, SIGNAL(selected(int)), this, SLOT(ListBoxSelected(int)));
163 // server
164 Label1 = new QLabel(this);
165 Label1->setText("Server Desc");
166 Label1->move(10, 120);
167 Label1->resize(100, 20);
168 ServerNameEdit = new QLineEdit(this);
169 ServerNameEdit->move(75, 120);
170 ServerNameEdit->resize(100, 20);
171 // username
172 Label2 = new QLabel(this);
173 Label2->setText("User Name");
174 Label2->move(10, 150);
175 Label2->resize(100, 20);
176 UserNameEdit = new QLineEdit(this);
177 UserNameEdit->move(75, 150);
178 UserNameEdit->resize(100, 20);
179 // ip
180 Label3 = new QLabel(this);
181 Label3->setText("Server IP");
182 Label3->move(10, 180);
183 Label3->resize(100, 20);
184 IPEdit = new QLineEdit(this);
185 IPEdit->move(75, 180);
186 IPEdit->resize(100, 20);
187 // width and height
188 WidthHeightBox = new QComboBox(this);
189 WidthHeightBox->move(10, 210);
190 WidthHeightBox->resize(100, 20);
191 WidthHeightBox->insertItem("240x320");
192 WidthHeightBox->insertItem("640x480");
193 WidthHeightBox->insertItem("800x600");
194 connect(WidthHeightBox, SIGNAL(activated(int)), this, SLOT(ComboChanged(int)));
195 WidthHeightBox->setCurrentItem(1);
196 WidthEdit = new QLineEdit(this);
197 WidthEdit->move(110, 210);
198 WidthEdit->resize(30, 20);
199 WidthEdit->setText("800");
200 HeightEdit = new QLineEdit(this);
201 HeightEdit->move(140, 210);
202 HeightEdit->resize(30, 20);
203 HeightEdit->setText("600");
204 // add to list button
205 AddButton = new QPushButton(this);
206 AddButton->move(180, 120);
207 AddButton->resize(50, 20);
208 AddButton->setText("Add");
209 connect(AddButton, SIGNAL(clicked()), this, SLOT(AddClicked()));
210 // change list item button
211 EditButton = new QPushButton(this);
212 EditButton->move(180, 140);
213 EditButton->resize(50, 20);
214 EditButton->setText("Edit");
215 connect(EditButton, SIGNAL(clicked()), this, SLOT(EditClicked()));
216 // save to file button
217 SaveButton = new QPushButton(this);
218 SaveButton->move(180, 160);
219 SaveButton->resize(50, 20);
220 SaveButton->setText("Save");
221 connect(SaveButton, SIGNAL(clicked()), this, SLOT(SaveClicked()));
222 // remove an item button
223 RemoveButton = new QPushButton(this);
224 RemoveButton->move(180, 180);
225 RemoveButton->resize(50, 20);
226 RemoveButton->setText("Remove");
227 connect(RemoveButton, SIGNAL(clicked()), this, SLOT(RemoveClicked()));
228 // full screen check box
229 FullScreenCheckBox = new QCheckBox(this, "Full Screen");
230 FullScreenCheckBox->setText("Full Screen");
231 FullScreenCheckBox->move(10, 230);
232 // ok button
233 OKButton = new QPushButton(this);
234 OKButton->setText("OK");
235 OKButton->move(100, 240);
236 OKButton->resize(50, 20);
237 connect(OKButton, SIGNAL(clicked()), this, SLOT(OKClicked()));
238 // cancel button
239 CancelButton = new QPushButton(this);
240 CancelButton->setText("Cancel");
241 CancelButton->move(160, 240);
242 CancelButton->resize(50, 20);
243 connect(CancelButton, SIGNAL(clicked()), this, SLOT(CancelClicked()));
244
245 for (i = 0; i < 10; i++)
246 {
247 ConnectionList[i] = new QMyConnectionItem;
248 ConnectionList[i]->ServerName = "";
249 ConnectionList[i]->UserName = "";
250 ConnectionList[i]->ServerIP = "";
251 ConnectionList[i]->Width = 0;
252 ConnectionList[i]->Height = 0;
253 ConnectionList[i]->FullScreen = 0;
254 }
255 home = getenv("HOME");
256 if (home != NULL)
257 {
258 sprintf(Text, "%s/rdesktop.ini", home);
259 QFile * File = new QFile(Text);
260 if (File->open(IO_ReadOnly))
261 {
262 i = -1;
263 while (!File->atEnd())
264 {
265 File->readLine(Line, 255);
266 j = Line.find("=");
267 if (j > 0)
268 {
269 ItemName = Line.mid(0, j);
270 CleanString(&ItemName);
271 ItemValue = Line.mid(j + 1);
272 CleanString(&ItemValue);
273 if (ItemName == "Server")
274 {
275 i++;
276 ConnectionList[i]->ServerName = ItemValue;
277 ListBox->insertItem(ItemValue);
278 }
279 else if (ItemName == "UserName")
280 ConnectionList[i]->UserName = ItemValue;
281 else if (ItemName == "Width")
282 ConnectionList[i]->Width = ItemValue.toInt();
283 else if (ItemName == "Height")
284 ConnectionList[i]->Height = ItemValue.toInt();
285 else if (ItemName == "IP")
286 ConnectionList[i]->ServerIP = ItemValue;
287 else if (ItemName == "FullScreen")
288 ConnectionList[i]->FullScreen = (ItemValue != "0");
289 }
290 }
291 }
292 delete File;
293 }
294 }
295
296 /******************************************************************************/
297 QMyDialog::~QMyDialog()
298 {
299 QMyConnectionItem * Item;
300 int i;
301
302 for (i = 0; i < 10; i++)
303 {
304 Item = ConnectionList[i];
305 delete Item;
306 }
307 }
308
309 /******************************************************************************/
310 void QMyDialog::ComboChanged(int index)
311 {
312 if (index == 0)
313 {
314 WidthEdit->setText("240");
315 HeightEdit->setText("320");
316 }
317 if (index == 1)
318 {
319 WidthEdit->setText("640");
320 HeightEdit->setText("480");
321 }
322 else if (index == 2)
323 {
324 WidthEdit->setText("800");
325 HeightEdit->setText("600");
326 }
327 }
328
329 /******************************************************************************/
330 void QMyDialog::OKClicked()
331 {
332 ServerName = ServerNameEdit->text();
333 UserName = UserNameEdit->text();
334 Width = WidthEdit->text().toInt();
335 Height = HeightEdit->text().toInt();
336 ServerIP = IPEdit->text();
337 FullScreen = FullScreenCheckBox->isChecked();
338 done(1);
339 }
340
341 /******************************************************************************/
342 void QMyDialog::CancelClicked()
343 {
344 done(0);
345 }
346
347 /******************************************************************************/
348 void QMyDialog::AddClicked()
349 {
350 int i;
351 QMyConnectionItem * Item;
352
353 i = ListBox->count();
354 if (i < 10)
355 {
356 ListBox->insertItem(ServerNameEdit->text());
357 Item = ConnectionList[i];
358 Item->ServerName = ServerNameEdit->text();
359 Item->UserName = UserNameEdit->text();
360 Item->Width = WidthEdit->text().toInt();
361 Item->Height = HeightEdit->text().toInt();
362 Item->ServerIP = IPEdit->text();
363 Item->FullScreen = FullScreenCheckBox->isChecked();
364 }
365 }
366
367 /******************************************************************************/
368 void QMyDialog::EditClicked()
369 {
370 int i;
371 QMyConnectionItem * Item;
372
373 i = ListBox->currentItem();
374 if (i >= 0)
375 {
376 Item = ConnectionList[i];
377 Item->ServerName = ServerNameEdit->text();
378 Item->UserName = UserNameEdit->text();
379 Item->Width = WidthEdit->text().toInt();
380 Item->Height = HeightEdit->text().toInt();
381 Item->ServerIP = IPEdit->text();
382 Item->FullScreen = FullScreenCheckBox->isChecked();
383 ListBox->changeItem(ServerNameEdit->text(), i);
384 }
385 }
386
387 /******************************************************************************/
388 void WriteString(QFile* File, QString* Line)
389 {
390 File->writeBlock((const char*)(*Line), Line->length());
391 }
392
393 /******************************************************************************/
394 void QMyDialog::SaveClicked()
395 {
396 int i, j;
397 QMyConnectionItem * Item;
398 QString Line;
399 char * home;
400 char Text[256];
401 QFile* File;
402
403 home = getenv("HOME");
404 if (home != NULL)
405 {
406 sprintf(Text, "%s/rdesktop.ini", home);
407 File = new QFile(Text);
408 if (File->open(IO_Truncate | IO_ReadWrite))
409 {
410 i = ListBox->count();
411 for (j = 0; j < i; j++)
412 {
413 Item = ConnectionList[j];
414 Line = "Server=";
415 Line += Item->ServerName;
416 Line += (char)10;
417 WriteString(File, &Line);
418 Line = "UserName=";
419 Line += Item->UserName;
420 Line += (char)10;
421 WriteString(File, &Line);
422 Line = "Width=";
423 sprintf(Text, "%d", Item->Width);
424 Line += Text;
425 Line += (char)10;
426 WriteString(File, &Line);
427 Line = "Height=";
428 sprintf(Text, "%d", Item->Height);
429 Line += Text;
430 Line += (char)10;
431 WriteString(File, &Line);
432 Line = "IP=";
433 Line += Item->ServerIP;
434 Line += (char)10;
435 WriteString(File, &Line);
436 Line = "FullScreen=";
437 if (Item->FullScreen)
438 Line += "1";
439 else
440 Line += "0";
441 Line += (char)10;
442 WriteString(File, &Line);
443 }
444 }
445 File->flush();
446 File->close();
447 delete File;
448 }
449 }
450
451 /******************************************************************************/
452 void QMyDialog::RemoveClicked()
453 {
454 int i, j, c;
455 QMyConnectionItem * Item1;
456 QMyConnectionItem * Item2;
457
458 i = ListBox->currentItem();
459 if (i >= 0)
460 {
461 c = ListBox->count();
462 for (j = i; j < c - 1; j++)
463 {
464 Item1 = ConnectionList[i];
465 Item2 = ConnectionList[i + 1];
466 Item1->ServerName = Item2->ServerName;
467 Item1->UserName = Item2->UserName;
468 Item1->Width = Item2->Width;
469 Item1->Height = Item2->Height;
470 Item1->ServerIP = Item2->ServerIP;
471 Item1->FullScreen = Item2->FullScreen;
472 }
473 ListBox->removeItem(i);
474 }
475 }
476
477 /******************************************************************************/
478 void QMyDialog::ListBoxChanged()
479 {
480 int i;
481 QMyConnectionItem * Item;
482 char Text[100];
483
484 i = ListBox->currentItem();
485 if (i >= 0 && i < 10)
486 {
487 Item = ConnectionList[i];
488 ServerNameEdit->setText(Item->ServerName);
489 UserNameEdit->setText(Item->UserName);
490 sprintf(Text, "%d", Item->Width);
491 WidthEdit->setText(Text);
492 sprintf(Text, "%d", Item->Height);
493 HeightEdit->setText(Text);
494 IPEdit->setText(Item->ServerIP);
495 FullScreenCheckBox->setChecked(Item->FullScreen != 0);
496 }
497 }
498
499 /******************************************************************************/
500 void QMyDialog::ListBoxSelected(int /*index*/)
501 {
502 }
503
504 /******************************************************************************/
505 void GetScanCode(QKeyEvent * e, int * ScanCode, int * code)
506 {
507 int key;
508 int mod;
509 int ascii;
510
511 key = e->key();
512 mod = e->state();
513 ascii = e->ascii();
514
515 *ScanCode = 0;
516 *code = mod; // 8 shift, 16 control, 32 alt
517
518 switch (key)
519 {
520 case 4096: // esc
521 case 4097: // tab
522 case 4099: // backspace
523 case 4100: // enter
524 case 4101: // enter
525 case 4103: // delete
526 ascii = 0;
527 }
528
529 if (ascii == 0)
530 {
531 switch (key)
532 {
533 case 4096: *ScanCode = 0x01; break; // esc
534 case 4097: *ScanCode = 0x0f; break; // tab
535 case 4099: *ScanCode = 0x0e; break; // backspace
536 case 4100: *ScanCode = 0x1c; break; // enter
537 case 4101: *ScanCode = 0x1c; break; // enter
538 case 4112: *ScanCode = 0xc7; break; // home
539 case 4113: *ScanCode = 0xcf; break; // end
540 case 4102: *ScanCode = 0xd2; break; // insert
541 case 4103: *ScanCode = 0xd3; break; // delete
542 case 4118: *ScanCode = 0xc9; break; // page up
543 case 4119: *ScanCode = 0xd1; break; // page down
544 case 4117: *ScanCode = 0xd0; break; // down arrow
545 case 4115: *ScanCode = 0xc8; break; // up arrow
546 case 4114: *ScanCode = 0xcb; break; // left arrow
547 case 4116: *ScanCode = 0xcd; break; // right arrow
548 case 4128: *ScanCode = 0x2a; break; // shift
549 case 4131: *ScanCode = 0x38; break; // alt
550 case 4129: *ScanCode = 0x1d; break; // ctrl
551 }
552 if (*ScanCode != 0)
553 return;
554 }
555
556 switch (ascii)
557 {
558 // first row
559 case 'q': *ScanCode = 0x10; break;
560 case 'Q': *ScanCode = 0x10; *code |= 8; break;
561 case '1': *ScanCode = 0x02; break;
562 case 'w': *ScanCode = 0x11; break;
563 case 'W': *ScanCode = 0x11; *code |= 8; break;
564 case '2': *ScanCode = 0x03; break;
565 case 'e': *ScanCode = 0x12; break;
566 case 'E': *ScanCode = 0x12; *code |= 8; break;
567 case '3': *ScanCode = 0x04; break;
568 case 'r': *ScanCode = 0x13; break;
569 case 'R': *ScanCode = 0x13; *code |= 8; break;
570 case '4': *ScanCode = 0x05; break;
571 case 't': *ScanCode = 0x14; break;
572 case 'T': *ScanCode = 0x14; *code |= 8; break;
573 case '5': *ScanCode = 0x06; break;
574 case 'y': *ScanCode = 0x15; break;
575 case 'Y': *ScanCode = 0x15; *code |= 8; break;
576 case '6': *ScanCode = 0x07; break;
577 case 'u': *ScanCode = 0x16; break;
578 case 'U': *ScanCode = 0x16; *code |= 8; break;
579 case '7': *ScanCode = 0x08; break;
580 case 'i': *ScanCode = 0x17; break;
581 case 'I': *ScanCode = 0x17; *code |= 8; break;
582 case '8': *ScanCode = 0x09; break;
583 case 'o': *ScanCode = 0x18; break;
584 case 'O': *ScanCode = 0x18; *code |= 8; break;
585 case '9': *ScanCode = 0x0a; break;
586 case 'p': *ScanCode = 0x19; break;
587 case 'P': *ScanCode = 0x19; *code |= 8; break;
588 case '0': *ScanCode = 0x0b; break;
589 // second row
590 case 'a': *ScanCode = 0x1e; break;
591 case 'A': *ScanCode = 0x1e; *code |= 8; break;
592 case '!': *ScanCode = 0x02; *code |= 8; break;
593 case 's': *ScanCode = 0x1f; break;
594 case 'S': *ScanCode = 0x1f; *code |= 8; break;
595 case '@': *ScanCode = 0x03; *code |= 8; break;
596 case 'd': *ScanCode = 0x20; break;
597 case 'D': *ScanCode = 0x20; *code |= 8; break;
598 case '#': *ScanCode = 0x04; *code |= 8; break;
599 case 'f': *ScanCode = 0x21; break;
600 case 'F': *ScanCode = 0x21; *code |= 8; break;
601 case '$': *ScanCode = 0x05; *code |= 8; break;
602 case 'g': *ScanCode = 0x22; break;
603 case 'G': *ScanCode = 0x22; *code |= 8; break;
604 case '%': *ScanCode = 0x06; *code |= 8; break;
605 case 'h': *ScanCode = 0x23; break;
606 case 'H': *ScanCode = 0x23; *code |= 8; break;
607 case '_': *ScanCode = 0x0c; *code |= 8; break;
608 case 'j': *ScanCode = 0x24; break;
609 case 'J': *ScanCode = 0x24; *code |= 8; break;
610 case '&': *ScanCode = 0x08; *code |= 8; break;
611 case 'k': *ScanCode = 0x25; break;
612 case 'K': *ScanCode = 0x25; *code |= 8; break;
613 case '*': *ScanCode = 0x09; *code |= 8; break;
614 case 'l': *ScanCode = 0x26; break;
615 case 'L': *ScanCode = 0x26; *code |= 8; break;
616 case '(': *ScanCode = 0x0a; *code |= 8; break;
617 // case 8: *ScanCode = 0x0e; break; // backspace
618 // third row
619 case 'z': *ScanCode = 0x2c; break;
620 case 'Z': *ScanCode = 0x2c; *code |= 8; break;
621 case 'x': *ScanCode = 0x2d; break;
622 case 'X': *ScanCode = 0x2d; *code |= 8; break;
623 case 'c': *ScanCode = 0x2e; break;
624 case 'C': *ScanCode = 0x2e; *code |= 8; break;
625 case 'v': *ScanCode = 0x2f; break;
626 case 'V': *ScanCode = 0x2f; *code |= 8; break;
627 case 'b': *ScanCode = 0x30; break;
628 case 'B': *ScanCode = 0x30; *code |= 8; break;
629 case '-': *ScanCode = 0x0c; break;
630 case 'n': *ScanCode = 0x31; break;
631 case 'N': *ScanCode = 0x31; *code |= 8; break;
632 case '+': *ScanCode = 0x0d; *code |= 8; break;
633 case 'm': *ScanCode = 0x32; break;
634 case 'M': *ScanCode = 0x32; *code |= 8; break;
635 case '=': *ScanCode = 0x0d; break;
636 case ',': *ScanCode = 0x33; break;
637 case ';': *ScanCode = 0x27; break;
638 case ')': *ScanCode = 0x0b; *code |= 8; break;
639 // fourth row
640 // case 9: *ScanCode = 0x0f; break; // tab
641 case '/': *ScanCode = 0x35; break;
642 case '?': *ScanCode = 0x35; *code |= 8; break;
643 case ' ': *ScanCode = 0x39; break;
644 case '\'': *ScanCode = 0x28; break;
645 case '"': *ScanCode = 0x28; *code |= 8; break;
646 case '~': *ScanCode = 0x29; *code |= 8; break;
647 case '.': *ScanCode = 0x34; break;
648 case ':': *ScanCode = 0x27; *code |= 8; break;
649 case '<': *ScanCode = 0x33; *code |= 8; break;
650 // case 13: *ScanCode = 0x1c; break; // enter
651 case '>': *ScanCode = 0x34; *code |= 8; break;
652 // others
653 // case 27: *ScanCode = 0x01; break; // esc
654 case '`': *ScanCode = 0x29; break;
655 case '^': *ScanCode = 0x07; *code |= 8; break;
656 case '[': *ScanCode = 0x1a; break;
657 case '{': *ScanCode = 0x1a; *code |= 8; break;
658 case ']': *ScanCode = 0x1b; break;
659 case '}': *ScanCode = 0x1b; *code |= 8; break;
660 case '\\': *ScanCode = 0x2b; break;
661 case '|': *ScanCode = 0x2b; *code |= 8; break;
662 // ctrl keys
663 case 1: *ScanCode = 0x1e; *code |= 16; break; // a
664 case 2: *ScanCode = 0x30; *code |= 16; break; // b
665 }
666
667 if (*ScanCode == 0 && key < 3000)
668 printf("unknown key %d mod %d ascii %d\n", key, mod, ascii);
669
670 }
671
672 /******************************************************************************/
673 QMyScrollView::QMyScrollView() : QScrollView()
674 {
675 }
676
677 /******************************************************************************/
678 QMyScrollView::~QMyScrollView()
679 {
680 }
681
682 /******************************************************************************/
683 void QMyScrollView::keyPressEvent(QKeyEvent* e)
684 {
685 int ScanCode, code;
686 GetScanCode(e, &ScanCode, &code);
687 if (ScanCode != 0)
688 {
689 if (code & 8) // send shift
690 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x2a, 0);
691 if (code & 16) // send control
692 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x1d, 0);
693 if (code & 32) // send alt
694 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x38, 0);
695 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYPRESS, ScanCode, 0);
696 e->accept();
697 }
698 }
699
700 /******************************************************************************/
701 void QMyScrollView::keyReleaseEvent(QKeyEvent* e)
702 {
703 int ScanCode, code;
704 GetScanCode(e, &ScanCode, &code);
705 if (ScanCode != 0)
706 {
707 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, ScanCode, 0);
708 if (code & 8) // send shift
709 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, 0x2a, 0);
710 if (code & 16) // send control
711 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, 0x1d, 0);
712 if (code & 32) // send alt
713 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, 0x38, 0);
714 e->accept();
715 }
716 }
717
718 /******************************************************************************/
719 void QMyScrollView::showEvent(QShowEvent* e)
720 {
721 QScrollView::showEvent(e);
722 }
723
724 /******************************************************************************/
725 void QMyScrollView::show()
726 {
727 QScrollView::show();
728 }
729
730 /******************************************************************************/
731 void QMyScrollView::polish()
732 {
733 QScrollView::polish();
734 }
735
736 /******************************************************************************/
737 void QMyScrollView::timerEvent(QTimerEvent * e)
738 {
739 QMyDialog * d;
740 QWidget * Desktop;
741 int dw;
742 int dh;
743
744 QScrollView::timerEvent(e);
745 killTimer(timer_id);
746 d = new QMyDialog(this);
747 if (d->exec() == 1) // ok clicked
748 {
749 g_width = d->Width;
750 g_height = d->Height;
751 g_client_width = g_width;
752 g_client_height = g_height;
753 g_fullscreen = d->FullScreen;
754 sprintf(g_server, "%s", (const char*)d->ServerIP);
755 sprintf(g_username, "%s", (const char*)d->UserName);
756 #ifdef WITH_RDPSND
757 // init sound
758 if (g_rdpsnd)
759 {
760 rdpsnd_init();
761 }
762 #endif
763 if (!rdp_connect(g_server, g_flags, g_domain, g_password, g_shell,
764 g_directory))
765 {
766 delete d;
767 g_SV->close();
768 return;
769 }
770 g_BS = (uint8*)xmalloc(g_width * g_height * 4);
771 memset(g_BS, 0, g_width * g_height * 4);
772 g_clipx = 0;
773 g_clipy = 0;
774 g_clipcx = g_width;
775 g_clipcy = g_height;
776 g_CM = (QColorMap*)xmalloc(sizeof(struct QColorMap));
777 memset(g_CM, 0, sizeof(struct QColorMap));
778 g_CM->NumColors = 256;
779 g_MW = new QMyMainWindow();
780 g_MW->resize(g_client_width, g_client_height);
781 g_MW->show();
782 g_SV->addChild(g_MW);
783 g_MW->setMouseTracking(true);
784 g_MW->setCursor((int)10); /* Qt::BlankCursor */
785 g_SocketNotifier = new QSocketNotifier(g_global_sock,
786 QSocketNotifier::Read,
787 g_MW);
788 g_MW->connect(g_SocketNotifier, SIGNAL(activated(int)), g_MW,
789 SLOT(dataReceived()));
790 if (g_fullscreen)
791 {
792 Desktop = g_App->desktop();
793 dw = Desktop->width();
794 dh = Desktop->height();
795 if (dw == g_client_width && dh == g_client_height)
796 {
797 g_MW->resize(g_client_width - 4, g_client_height - 4);
798 }
799 g_SV->showFullScreen();
800 }
801 delete d;
802 }
803 else // cancel clicked
804 {
805 delete d;
806 g_SV->close();
807 }
808 }
809
810 /******************************************************************************/
811 QMyMainWindow::QMyMainWindow() : QWidget(g_SV->viewport())
812 {
813 PopupMenu = new QPopupMenu(this);
814 PopupMenu->insertItem("Right click", 1, 0);
815 PopupMenu->insertItem("Toggle fullscreen", 2, 1);
816 PopupMenu->insertItem("Reset keyboard", 3, 2);
817 PopupMenu->insertItem("Double click", 4, 3);
818 connect(PopupMenu, SIGNAL(activated(int)), this, SLOT(MemuClicked(int)));
819 }
820
821 /******************************************************************************/
822 QMyMainWindow::~QMyMainWindow()
823 {
824 delete PopupMenu;
825 }
826
827 /******************************************************************************/
828 int rd(double in)
829 {
830 return (int)(in + 0.50);
831 }
832
833 /******************************************************************************/
834 int c2sx(int cx)
835 {
836 double sx;
837
838 sx = (double)g_client_width / (double)g_width;
839 return rd(cx / sx);
840 }
841
842 /******************************************************************************/
843 int c2sy(int cy)
844 {
845 double sy;
846
847 sy = (double)g_client_height / (double)g_height;
848 return rd(cy / sy);
849 }
850
851 /******************************************************************************/
852 void QMyMainWindow::timerEvent(QTimerEvent * e)
853 {
854 QWidget::timerEvent(e);
855 if (e->timerId() == timer_id)
856 {
857 // send mouse up
858 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1,
859 rd(c2sx(mx)), rd(c2sy(my)));
860 // if in fullscreen, take it out or the menu won't work
861 if (g_fullscreen)
862 {
863 g_fullscreen = 0;
864 g_SV->showNormal();
865 g_SV->showMaximized();
866 }
867 else
868 PopupMenu->popup(mapToGlobal(QPoint(mx, my)));
869 }
870 killTimer(timer_id);
871 }
872
873 /******************************************************************************/
874 void QMyMainWindow::MemuClicked(int MenuID)
875 {
876 QWidget * Desktop;
877 int dw;
878 int dh;
879
880 if (MenuID == 1) // right click
881 {
882 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON2,
883 rd(c2sx(mx)), rd(c2sy(my)));
884 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON2,
885 rd(c2sx(mx)), rd(c2sy(my)));
886 }
887 else if (MenuID == 2) // toggle full screen
888 {
889 g_fullscreen = ~g_fullscreen;
890 if (g_fullscreen)
891 {
892 Desktop = g_App->desktop();
893 dw = Desktop->width();
894 dh = Desktop->height();
895 if (dw == g_client_width && dh == g_client_height)
896 g_MW->resize(g_client_width - 4, g_client_height - 4);
897 g_SV->showFullScreen();
898 }
899 else
900 {
901 g_SV->showNormal();
902 g_SV->showMaximized();
903 g_MW->resize(g_client_width, g_client_height);
904 }
905 }
906 else if (MenuID == 3) // reset keyboard
907 {
908 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, 0x2a, 0); // shift
909 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, 0x1d, 0); // control
910 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, 0x38, 0); // alt
911 }
912 else if (MenuID == 4) // double click
913 {
914 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON1,
915 rd(c2sx(mx)), rd(c2sy(my)));
916 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1,
917 rd(c2sx(mx)), rd(c2sy(my)));
918 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON1,
919 rd(c2sx(mx)), rd(c2sy(my)));
920 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1,
921 rd(c2sx(mx)), rd(c2sy(my)));
922 }
923 }
924
925 /******************************************************************************/
926 void QMyMainWindow::mouseMoveEvent(QMouseEvent* e)
927 {
928 int x, y;
929
930 x = e->x();
931 y = e->y();
932 if (timer_id)
933 {
934 x = x - mx;
935 y = y - my;
936 if (x < -10 || x > 10 || y < -10 || y > 10)
937 {
938 killTimer(timer_id);
939 timer_id = 0;
940 }
941 }
942 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE, c2sx(e->x()),
943 c2sy(e->y()));
944 }
945
946 /******************************************************************************/
947 void QMyMainWindow::mousePressEvent(QMouseEvent* e)
948 {
949 timer_id = startTimer(1000);
950 mx = e->x();
951 my = e->y();
952 if (e->button() == LeftButton)
953 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON1,
954 c2sx(e->x()), c2sy(e->y()));
955 else if (e->button() == RightButton)
956 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON2,
957 c2sx(e->x()), c2sy(e->y()));
958 else if (e->button() == MidButton)
959 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON3,
960 c2sx(e->x()), c2sy(e->y()));
961 }
962
963 /******************************************************************************/
964 void QMyMainWindow::mouseReleaseEvent(QMouseEvent* e)
965 {
966 killTimer(timer_id);
967 timer_id = 0;
968 if (e->button() == LeftButton)
969 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1, c2sx(e->x()),
970 c2sy(e->y()));
971 else if (e->button() == RightButton)
972 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON2, c2sx(e->x()),
973 c2sy(e->y()));
974 else if (e->button() == MidButton)
975 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON3, c2sx(e->x()),
976 c2sy(e->y()));
977 }
978
979 /******************************************************************************/
980 void QMyMainWindow::wheelEvent(QWheelEvent* e)
981 {
982 if (e->delta() > 0)
983 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON4, c2sx(e->x()),
984 c2sy(e->y()));
985 else if (e->delta() < 0)
986 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON5, c2sx(e->x()),
987 c2sy(e->y()));
988 }
989
990 #define NOT(x) (~x)
991
992 /******************************************************************************/
993 int rop(int rop, int src, int dst)
994 {
995 switch (rop)
996 {
997 case 0x0: return 0;
998 case 0x1: return NOT (src | dst);
999 case 0x2: return NOT (src) & dst;
1000 case 0x3: return NOT (src);
1001 case 0x4: return src & NOT (dst);
1002 case 0x5: return NOT (dst);
1003 case 0x6: return src ^ dst;
1004 case 0x7: return NOT (src & dst);
1005 case 0x8: return src & dst;
1006 case 0x9: return NOT (src) ^ dst;
1007 case 0xa: return dst;
1008 case 0xb: return NOT (src) | dst;
1009 case 0xc: return src;
1010 case 0xd: return src | NOT (dst);
1011 case 0xe: return src | dst;
1012 case 0xf: return NOT (0);
1013 }
1014 return dst;
1015 }
1016
1017 /*****************************************************************************/
1018 int get_pixel(int x, int y)
1019 {
1020 if (x >= 0 && x < g_width && y >= 0 && y < g_height)
1021 {
1022 if (g_server_bpp == 8)
1023 return GETPIXEL8(g_BS, x, y, g_width);
1024 else if (g_server_bpp == 16)
1025 return GETPIXEL16(g_BS, x, y, g_width);
1026 else if (g_server_bpp == 24)
1027 return GETPIXEL32(g_BS, x, y, g_width);
1028 else
1029 return 0;
1030 }
1031 else
1032 return 0;
1033 }
1034
1035 /******************************************************************************/
1036 void set_pixel(int x, int y, int pixel, int op = 0xc)
1037 {
1038 int p;
1039
1040 if (x >= g_clipx && x < (g_clipx + g_clipcx) &&
1041 y >= g_clipy && y < (g_clipy + g_clipcy))
1042 {
1043 if (x >= 0 && x < g_width && y >= 0 && y < g_height)
1044 {
1045 if (op == 0xc)
1046 {
1047 if (g_server_bpp == 8)
1048 {
1049 SETPIXEL8(g_BS, x, y, g_width, pixel);
1050 }
1051 else if (g_server_bpp == 16)
1052 {
1053 SETPIXEL16(g_BS, x, y, g_width, pixel);
1054 }
1055 else if (g_server_bpp == 24)
1056 {
1057 SETPIXEL32(g_BS, x, y, g_width, pixel);
1058 }
1059 }
1060 else
1061 {
1062 if (g_server_bpp == 8)
1063 {
1064 p = GETPIXEL8(g_BS, x, y, g_width);
1065 p = rop(op, pixel, p);
1066 SETPIXEL8(g_BS, x, y, g_width, p);
1067 }
1068 else if (g_server_bpp == 16)
1069 {
1070 p = GETPIXEL16(g_BS, x, y, g_width);
1071 p = rop(op, pixel, p);
1072 SETPIXEL16(g_BS, x, y, g_width, p);
1073 }
1074 else if (g_server_bpp == 24)
1075 {
1076 p = GETPIXEL32(g_BS, x, y, g_width);
1077 p = rop(op, pixel, p);
1078 SETPIXEL32(g_BS, x, y, g_width, p);
1079 }
1080 }
1081 }
1082 }
1083 }
1084
1085 /******************************************************************************/
1086 // adjust coordinates for cliping rect
1087 bool WarpCoords(int * x, int * y, int * cx, int * cy, int * srcx, int * srcy)
1088 {
1089 int dx, dy;
1090 QRect InRect(*x, *y, *cx, *cy);
1091 QRect OutRect;
1092 QRect CRect(g_clipx, g_clipy, g_clipcx, g_clipcy);
1093 OutRect = InRect.intersect(CRect);
1094 if (OutRect.isEmpty())
1095 return false;
1096 dx = OutRect.x() - InRect.x();
1097 dy = OutRect.y() - InRect.y();
1098 *x = OutRect.x();
1099 *y = OutRect.y();
1100 *cx = OutRect.width();
1101 *cy = OutRect.height();
1102 if (srcx != NULL)
1103 *srcx = *srcx + dx;
1104 if (srcy != NULL)
1105 *srcy = *srcy + dy;
1106 return true;
1107 }
1108
1109 /******************************************************************************/
1110 void QMyMainWindow::paintEvent(QPaintEvent * pe)
1111 {
1112 QImage * Image;
1113 QPainter * Painter;
1114 QRect Rect;
1115 int i, j, w, h, l, t, pixel, r, g, b;
1116 uint8 * data;
1117 double sx, sy;
1118
1119 Image = 0;
1120 data = 0;
1121 if (!testWFlags(WRepaintNoErase))
1122 setWFlags(WRepaintNoErase);
1123 if (g_CM != NULL || g_server_bpp > 8)
1124 {
1125 sx = (double)g_client_width / (double)g_width;
1126 sy = (double)g_client_height / (double)g_height;
1127 Rect = pe->rect();
1128 l = rd(Rect.left() / sx);
1129 t = rd(Rect.top() / sy);
1130 w = rd(Rect.width() / sx);
1131 h = rd(Rect.height() / sy);
1132 if (w > 0 && h > 0)
1133 {
1134 if (g_server_bpp == 8 && g_CM->NumColors > 0)
1135 {
1136 w = (w + 3) & ~3;
1137 data = (uint8*)xmalloc(w * h);
1138 for (i = 0; i < h; i++)
1139 for (j = 0; j < w; j++)
1140 data[i * w + j] = GETPIXEL8(g_BS, l + j, t + i, g_width);
1141 Image = new QImage(data, w, h, 8,(QRgb*)g_CM->RGBColors,
1142 g_CM->NumColors, QImage::IgnoreEndian);
1143 }
1144 else if (g_server_bpp == 16)
1145 {
1146 w = (w + 3) & ~3;
1147 data = (uint8*)xmalloc(w * h * 4);
1148 for (i = 0; i < h; i++)
1149 for (j = 0; j < w; j++)
1150 {
1151 pixel = GETPIXEL16(g_BS, l + j, t + i, g_width);
1152 r = ((pixel >> 8) & 0xf8) | ((pixel >> 13) & 0x7);
1153 g = ((pixel >> 3) & 0xfc) | ((pixel >> 9) & 0x3);
1154 b = ((pixel << 3) & 0xf8) | ((pixel >> 2) & 0x7);
1155 pixel = ((r << 16) | (g << 8) | b);
1156 SETPIXEL32(data, j, i, w, pixel);
1157 }
1158 Image = new QImage(data, w, h, 32, NULL,
1159 0, QImage::IgnoreEndian);
1160 }
1161 else if (g_server_bpp == 24)
1162 {
1163 w = (w + 3) & ~3;
1164 data = (uint8*)xmalloc(w * h * 4);
1165 for (i = 0; i < h; i++)
1166 for (j = 0; j < w; j++)
1167 {
1168 pixel = GETPIXEL32(g_BS, l + j, t + i, g_width);
1169 r = (pixel >> 0) & 0xff;
1170 g = (pixel >> 8) & 0xff;
1171 b = (pixel >> 16) & 0xff;
1172 pixel = ((r << 16) | (g << 8) | b);
1173 SETPIXEL32(data, j, i, w, pixel);
1174 }
1175 Image = new QImage(data, w, h, 32, NULL,
1176 0, QImage::IgnoreEndian);
1177 }
1178 if (Image != 0)
1179 {
1180 Painter = new QPainter(this);
1181 Painter->scale(sx, sy);
1182 Painter->drawImage(l, t, *Image, 0, 0, w, h);
1183 delete Painter;
1184 delete Image;
1185 }
1186 xfree(data);
1187 }
1188 }
1189 }
1190
1191 /******************************************************************************/
1192 void QMyMainWindow::closeEvent(QCloseEvent * e)
1193 {
1194 e->accept();
1195 }
1196
1197 /******************************************************************************/
1198 void QMyMainWindow::dataReceived()
1199 {
1200 if (!rdp_loop(&g_deactivated, &g_ext_disc_reason))
1201 g_SV->close();
1202 #ifdef WITH_RDPSND
1203 if (g_dsp_busy)
1204 {
1205 if (g_SoundNotifier == 0)
1206 {
1207 g_SoundNotifier = new QSocketNotifier(g_dsp_fd, QSocketNotifier::Write,
1208 g_MW);
1209 g_MW->connect(g_SoundNotifier, SIGNAL(activated(int)), g_MW,
1210 SLOT(soundSend()));
1211 }
1212 else
1213 {
1214 if (!g_SoundNotifier->isEnabled())
1215 g_SoundNotifier->setEnabled(true);
1216 }
1217 }
1218 #endif
1219 }
1220
1221 /******************************************************************************/
1222 void QMyMainWindow::soundSend()
1223 {
1224 #ifdef WITH_RDPSND
1225 g_SoundNotifier->setEnabled(false);
1226 wave_out_play();
1227 if (g_dsp_busy)
1228 {
1229 g_SoundNotifier->setEnabled(true);
1230 }
1231 #endif
1232 }
1233
1234 /******************************************************************************/
1235 void redraw(int x, int y, int cx, int cy)
1236 {
1237 double sx, sy;
1238
1239 if (WarpCoords(&x, &y, &cx, &cy, NULL, NULL))
1240 {
1241 sx = (double)g_client_width / (double)g_width;
1242 sy = (double)g_client_height / (double)g_height;
1243 x = rd(x * sx);
1244 y = rd(y * sy);
1245 cx = rd(cx * sx);
1246 cy = rd(cy * sy);
1247 g_MW->update(x, y, cx, cy);
1248 }
1249 }
1250
1251 /******************************************************************************/
1252 /* Returns 0 after user quit, 1 otherwise */
1253 int ui_select(int rdp_socket)
1254 {
1255 if (g_global_sock == 0)
1256 g_global_sock = rdp_socket;
1257 return 1;
1258 }
1259
1260 /******************************************************************************/
1261 void ui_move_pointer(int /*x*/, int /*y*/)
1262 {
1263 }
1264
1265 /******************************************************************************/
1266 void ui_set_null_cursor(void)
1267 {
1268 }
1269
1270 /******************************************************************************/
1271 HBITMAP ui_create_bitmap(int width, int height, uint8 * data)
1272 {
1273 struct bitmap * the_bitmap;
1274 uint8 * bitmap_data;
1275 int i, j;
1276 int r, g, b, pixel;
1277
1278 bitmap_data = (uint8*)xmalloc(width * height * 4);
1279 the_bitmap = (struct bitmap*)xmalloc(sizeof(struct bitmap));
1280 the_bitmap->w = width;
1281 the_bitmap->h = height;
1282 the_bitmap->data = bitmap_data;
1283 if (g_server_bpp == 8)
1284 {
1285 for (i = 0; i < height; i++)
1286 for (j = 0; j < width; j++)
1287 bitmap_data[i * width + j] = data[i * width + j];
1288 }
1289 else if (g_server_bpp == 16)
1290 {
1291 for (i = 0; i < height; i++)
1292 for (j = 0; j < width; j++)
1293 *(((uint16*)bitmap_data) + (i * width + j)) =
1294 *(((uint16*)data) + (i * width + j));
1295 }
1296 else if (g_server_bpp == 24)
1297 {
1298 for (i = 0; i < height; i++)
1299 for (j = 0; j < width; j++)
1300 {
1301 r = data[(i * width + j) * 3 + 0];
1302 g = data[(i * width + j) * 3 + 1];
1303 b = data[(i * width + j) * 3 + 2];
1304 pixel = (r << 16) | (g << 8) | b;
1305 SETPIXEL32(bitmap_data, j, i, width, pixel);
1306 }
1307 }
1308 return the_bitmap;
1309 }
1310
1311 /******************************************************************************/
1312 void ui_paint_bitmap(int x, int y, int cx, int cy, int width,
1313 int height, uint8 * data)
1314 {
1315 int i, j;
1316 int r, g, b, pixel;
1317
1318 if (g_server_bpp == 8)
1319 {
1320 for (i = 0; i < cy; i++)
1321 for (j = 0; j < cx; j++)
1322 if (i < height)
1323 if (j < width)
1324 set_pixel(x + j, y + i, data[i * width + j]);
1325 }
1326 else if (g_server_bpp == 16)
1327 {
1328 for (i = 0; i < cy; i++)
1329 for (j = 0; j < cx; j++)
1330 if (i < height)
1331 if (j < width)
1332 set_pixel(x + j, y + i, *(((uint16*)data) + (i * width + j)));
1333 }
1334 else if (g_server_bpp == 24)
1335 {
1336 for (i = 0; i < cy; i++)
1337 for (j = 0; j < cx; j++)
1338 if (i < height)
1339 if (j < width)
1340 {
1341 r = data[(i * width + j) * 3 + 0];
1342 g = data[(i * width + j) * 3 + 1];
1343 b = data[(i * width + j) * 3 + 2];
1344 pixel = (r << 16) | (g << 8) | b;
1345 set_pixel(x + j, y + i, pixel);
1346 }
1347 }
1348 redraw(x, y, cx, cy);
1349 }
1350
1351 /******************************************************************************/
1352 void ui_destroy_bitmap(HBITMAP bmp)
1353 {
1354 struct bitmap* the_bitmap;
1355
1356 the_bitmap = (struct bitmap*)bmp;
1357 if (the_bitmap != NULL)
1358 {
1359 if (the_bitmap->data != NULL)
1360 xfree(the_bitmap->data);
1361 xfree(the_bitmap);
1362 }
1363 }
1364
1365 /******************************************************************************/
1366 bool is_pixel_on(uint8 * data, int x, int y, int width, int bpp)
1367 {
1368 int start, shift;
1369
1370 if (bpp == 1)
1371 {
1372 width = (width + 7) / 8;
1373 start = (y * width) + x / 8;
1374 shift = x % 8;
1375 return (data[start] & (0x80 >> shift)) != 0;
1376 }
1377 else if (bpp == 8)
1378 return data[y * width + x] != 0;
1379 else
1380 return false;
1381 }
1382
1383 /******************************************************************************/
1384 void set_pixel_on(uint8 * data, int x, int y, int width, int bpp, uint8 pixel)
1385 {
1386 if (bpp == 8)
1387 data[y * width + x] = pixel;
1388 }
1389
1390 /******************************************************************************/
1391 HGLYPH ui_create_glyph(int width, int height, uint8 * data)
1392 {
1393 int i, j;
1394 uint8* glyph_data;
1395 struct bitmap* the_glyph;
1396
1397 glyph_data = (uint8*)xmalloc(width * height);
1398 the_glyph = (struct bitmap*)xmalloc(sizeof(struct bitmap));
1399 the_glyph->w = width;
1400 the_glyph->h = height;
1401 the_glyph->data = glyph_data;
1402 memset(glyph_data, 0, width * height);
1403 for (i = 0; i < height; i++)
1404 for (j = 0; j < width; j++)
1405 if (is_pixel_on(data, j, i, width, 1))
1406 set_pixel_on(glyph_data, j, i, width, 8, 255);
1407 return the_glyph;
1408 }
1409
1410 /******************************************************************************/
1411 void ui_destroy_glyph(HGLYPH glyph)
1412 {
1413 struct bitmap* the_glyph;
1414
1415 the_glyph = (struct bitmap*)glyph;
1416 if (the_glyph != NULL)
1417 {
1418 if (the_glyph->data != NULL)
1419 xfree(the_glyph->data);
1420 xfree(the_glyph);
1421 }
1422 }
1423
1424 /******************************************************************************/
1425 HCURSOR ui_create_cursor(uint32 x, uint32 y,
1426 int width, int height,
1427 uint8 * andmask, uint8 * xormask)
1428 {
1429 return (void*)1;
1430 }
1431
1432 /******************************************************************************/
1433 void ui_set_cursor(HCURSOR /*cursor*/)
1434 {
1435 }
1436
1437 /*****************************************************************************/
1438 uint16 ui_get_numlock_state(uint32 state)
1439 {
1440 return 0;
1441 }
1442
1443 /*****************************************************************************/
1444 unsigned int read_keyboard_state(void)
1445 {
1446 return 0;
1447 }
1448
1449 /*****************************************************************************/
1450 void ui_resize_window(void)
1451 {
1452 }
1453
1454 /*****************************************************************************/
1455 void ui_polygon(uint8 opcode, uint8 fillmode, POINT * point, int npoints,
1456 BRUSH * brush, int bgcolour, int fgcolour)
1457 {
1458 }
1459
1460 /*****************************************************************************/
1461 /* todo, use qt function for this (QPainter::drawPolyline) */
1462 void ui_polyline(uint8 opcode, POINT * points, int npoints, PEN * pen)
1463 {
1464 int i, x, y, dx, dy;
1465
1466 if (npoints > 0)
1467 {
1468 x = points[0].x;
1469 y = points[0].y;
1470 for (i = 1; i < npoints; i++)
1471 {
1472 dx = points[i].x;
1473 dy = points[i].y;
1474 ui_line(opcode, x, y, x + dx, y + dy, pen);
1475 x = x + dx;
1476 y = y + dy;
1477 }
1478 }
1479 }
1480
1481 /*****************************************************************************/
1482 void ui_ellipse(uint8 opcode, uint8 fillmode,
1483 int x, int y, int cx, int cy,
1484 BRUSH * brush, int bgcolour, int fgcolour)
1485 {
1486 }
1487
1488 /******************************************************************************/
1489 void ui_destroy_cursor(HCURSOR /*cursor*/)
1490 {
1491 }
1492
1493 /******************************************************************************/
1494 HCOLOURMAP ui_create_colourmap(COLOURMAP * colours)
1495 {
1496 int i;
1497 int x;
1498 uint8 r, g, b;
1499 i = 0;
1500 while (i < colours->ncolours && i < 256)
1501 {
1502 r = colours->colours[i].red;
1503 g = colours->colours[i].green;
1504 b = colours->colours[i].blue;
1505 x = (r << 16) | (g << 8) | b;
1506 g_CM->RGBColors[i] = x;
1507 i++;
1508 }
1509 g_CM->NumColors = colours->ncolours;
1510 return g_CM;
1511 }
1512
1513 /******************************************************************************/
1514 void ui_set_colourmap(HCOLOURMAP map)
1515 {
1516 }
1517
1518 /******************************************************************************/
1519 void ui_destroy_colourmap(HCOLOURMAP map)
1520 {
1521 }
1522
1523 /******************************************************************************/
1524 void ui_begin_update(void)
1525 {
1526 }
1527
1528 /******************************************************************************/
1529 void ui_end_update(void)
1530 {
1531 }
1532
1533 /******************************************************************************/
1534 void ui_set_clip(int x, int y, int cx, int cy)
1535 {
1536 g_clipx = x;
1537 g_clipy = y;
1538 g_clipcx = cx;
1539 g_clipcy = cy;
1540 }
1541
1542 /******************************************************************************/
1543 void ui_reset_clip(void)
1544 {
1545 g_clipx = 0;
1546 g_clipy = 0;
1547 g_clipcx = g_width;
1548 g_clipcy = g_height;
1549 }
1550
1551 /******************************************************************************/
1552 void ui_bell(void)
1553 {
1554 g_App->beep();
1555 }
1556
1557 /******************************************************************************/
1558 void ui_destblt(uint8 opcode, int x, int y, int cx, int cy)
1559 {
1560 int i, j;
1561
1562
1563 if (opcode == 0x0) /* black */
1564 {
1565 for (i = 0; i < cy; i++)
1566 for (j = 0; j < cx; j++)
1567 set_pixel(x + j, y + i, 0, 0xc);
1568 }
1569 else if (opcode == 0xf) /* white */
1570 {
1571 for (i = 0; i < cy; i++)
1572 for (j = 0; j < cx; j++)
1573 set_pixel(x + j, y + i, 0xffffff, 0xc);
1574 }
1575 else
1576 {
1577 for (i = 0; i < cy; i++)
1578 for (j = 0; j < cx; j++)
1579 set_pixel(x + j, y + i, get_pixel(x + j, y + i), opcode);
1580 }
1581 redraw(x, y, cx, cy);
1582 }
1583
1584 /******************************************************************************/
1585 // does not repaint
1586 void fill_rect(int x, int y, int cx, int cy, int colour, int opcode = 0xc)
1587 {
1588 int i, j;
1589
1590 if (x + cx > g_width)
1591 cx = g_width - x;
1592 if (y + cy > g_height)
1593 cy = g_height - y;
1594 #ifdef QT_OPTI
1595 if (opcode == 0xc) /* optimize */
1596 {
1597 if (WarpCoords(&x, &y, &cx, &cy, 0, 0))
1598 {
1599 if (g_server_bpp == 8)
1600 {
1601 for (i = 0; i < cy; i++)
1602 for (j = 0; j < cx; j++)
1603 SETPIXEL8(g_BS, x + j, y + i, g_width, colour);
1604 }
1605 else if (g_server_bpp == 16)
1606 {
1607 for (i = 0; i < cy; i++)
1608 for (j = 0; j < cx; j++)
1609 SETPIXEL16(g_BS, x + j, y + i, g_width, colour);
1610 }
1611 else if (g_server_bpp == 24)
1612 {
1613 for (i = 0; i < cy; i++)
1614 for (j = 0; j < cx; j++)
1615 SETPIXEL32(g_BS, x + j, y + i, g_width, colour);
1616 }
1617 }
1618 }
1619 else
1620 #endif
1621 {
1622 for (i = 0; i < cy; i++)
1623 for (j = 0; j < cx; j++)
1624 set_pixel(x + j, y + i, colour, opcode);
1625 }
1626 }
1627
1628 /******************************************************************************/
1629 void ui_rect(int x, int y, int cx, int cy, int colour)
1630 {
1631 fill_rect(x, y, cx, cy, colour);
1632 redraw(x, y, cx, cy);
1633 }
1634
1635 /******************************************************************************/
1636 void ui_patblt(uint8 opcode, int x, int y, int cx, int cy,
1637 BRUSH * brush, int bgcolour, int fgcolour)
1638 {
1639 int i, j;
1640 uint8 ipattern[8];
1641
1642 switch (brush->style)
1643 {
1644 case 0:
1645 fill_rect(x, y, cx, cy, fgcolour, opcode);
1646 break;
1647 case 3:
1648 for (i = 0; i < 8; i++)
1649 ipattern[i] = ~brush->pattern[7 - i];
1650 for (i = 0; i < cy; i++)
1651 for (j = 0; j < cx; j++)
1652 if (is_pixel_on(ipattern, (x + j + brush->xorigin) % 8,
1653 (y + i + brush->yorigin) % 8, 8, 1))
1654 set_pixel(x + j, y + i, fgcolour, opcode);
1655 else
1656 set_pixel(x + j, y + i, bgcolour, opcode);
1657 break;
1658 }
1659 redraw(x, y, cx, cy);
1660 }
1661
1662 /******************************************************************************/
1663 void ui_screenblt(uint8 opcode, int x, int y, int cx, int cy,
1664 int srcx, int srcy)
1665 {
1666 int i, j, pixel;
1667 uint8 * temp;
1668
1669 temp = (uint8*)xmalloc(cx * cy * 4);
1670 #ifdef QT_OPTI
1671 if (opcode == 0xc)
1672 {
1673 if (WarpCoords(&x, &y, &cx, &cy, &srcx, &srcy))
1674 {
1675 if (g_server_bpp == 8)
1676 {
1677 for (i = 0; i < cy; i++)
1678 for (j = 0; j < cx; j++)
1679 {
1680 pixel = GETPIXEL8(g_BS, srcx + j, srcy + i, g_width);
1681 SETPIXEL8(temp, j, i, cx, pixel);
1682 }
1683 for (i = 0; i < cy; i++)
1684 for (j = 0; j < cx; j++)
1685 {
1686 pixel = GETPIXEL8(temp, j, i, cx);
1687 SETPIXEL8(g_BS, x + j, y + i, g_width, pixel);
1688 }
1689 }
1690 else if (g_server_bpp == 16)
1691 {
1692 for (i = 0; i < cy; i++)
1693 for (j = 0; j < cx; j++)
1694 {
1695 pixel = GETPIXEL16(g_BS, srcx + j, srcy + i, g_width);
1696 SETPIXEL16(temp, j, i, cx, pixel);
1697 }
1698 for (i = 0; i < cy; i++)
1699 for (j = 0; j < cx; j++)
1700 {
1701 pixel = GETPIXEL16(temp, j, i, cx);
1702 SETPIXEL16(g_BS, x + j, y + i, g_width, pixel);
1703 }
1704 }
1705 else if (g_server_bpp == 24)
1706 {
1707 for (i = 0; i < cy; i++)
1708 for (j = 0; j < cx; j++)
1709 {
1710 pixel = GETPIXEL32(g_BS, srcx + j, srcy + i, g_width);
1711 SETPIXEL32(temp, j, i, cx, pixel);
1712 }
1713 for (i = 0; i < cy; i++)
1714 for (j = 0; j < cx; j++)
1715 {
1716 pixel = GETPIXEL32(temp, j, i, cx);
1717 SETPIXEL32(g_BS, x + j, y + i, g_width, pixel);
1718 }
1719 }
1720 }
1721 }
1722 else
1723 #endif
1724 {
1725 if (g_server_bpp == 8)
1726 {
1727 for (i = 0; i < cy; i++)
1728 for (j = 0; j < cx; j++)
1729 temp[i * cx + j] = get_pixel(srcx + j, srcy + i);
1730 for (i = 0; i < cy; i++)
1731 for (j = 0; j < cx; j++)
1732 set_pixel(x + j, y + i, temp[i * cx + j], opcode);
1733 }
1734 else if (g_server_bpp == 16)
1735 {
1736 for (i = 0; i < cy; i++)
1737 for (j = 0; j < cx; j++)
1738 {
1739 pixel = get_pixel(srcx + j, srcy + i);
1740 SETPIXEL16(temp, j, i, cx, pixel);
1741 }
1742 for (i = 0; i < cy; i++)
1743 for (j = 0; j < cx; j++)
1744 {
1745 pixel = GETPIXEL16(temp, j, i, cx);
1746 set_pixel(x + j, y + i, pixel, opcode);
1747 }
1748 }
1749 else if (g_server_bpp == 24)
1750 {
1751 for (i = 0; i < cy; i++)
1752 for (j = 0; j < cx; j++)
1753 *(((uint32*)temp) + (i * cx + j)) = get_pixel(srcx + j, srcy + i);
1754 for (i = 0; i < cy; i++)
1755 for (j = 0; j < cx; j++)
1756 set_pixel(x + j, y + i, *(((uint32*)temp) + (i * cx + j)), opcode);
1757 }
1758 }
1759 xfree(temp);
1760 redraw(x, y, cx, cy);
1761 }
1762
1763 /******************************************************************************/
1764 void ui_memblt(uint8 opcode, int x, int y, int cx, int cy,
1765 HBITMAP src, int srcx, int srcy)
1766 {
1767 int i, j, p;
1768 struct bitmap * the_bitmap;
1769
1770 the_bitmap = (struct bitmap*)src;
1771 if (the_bitmap == NULL)
1772 return;
1773 #ifdef QT_OPTI
1774 if (opcode == 0xc) /* optimize */
1775 {
1776 if (WarpCoords(&x, &y, &cx, &cy, &srcx, &srcy))
1777 {
1778 if (g_server_bpp == 8)
1779 {
1780 for (i = 0; i < cy; i++)
1781 for (j = 0; j < cx; j++)
1782 {
1783 p = GETPIXEL8(the_bitmap->data, srcx + j, srcy + i, the_bitmap->w);
1784 SETPIXEL8(g_BS, x + j, y + i, g_width, p);
1785 }
1786 }
1787 else if (g_server_bpp == 16)
1788 {
1789 for (i = 0; i < cy; i++)
1790 for (j = 0; j < cx; j++)
1791 {
1792 p = GETPIXEL16(the_bitmap->data, srcx + j, srcy + i, the_bitmap->w);
1793 SETPIXEL16(g_BS, x + j, y + i, g_width, p);
1794 }
1795 }
1796 else if (g_server_bpp == 24)
1797 {
1798 for (i = 0; i < cy; i++)
1799 for (j = 0; j < cx; j++)
1800 {
1801 p = GETPIXEL32(the_bitmap->data, srcx + j, srcy + i, the_bitmap->w);
1802 SETPIXEL32(g_BS, x + j, y + i, g_width, p);
1803 }
1804 }
1805 }
1806 }
1807 else
1808 #endif
1809 {
1810 if (g_server_bpp == 8)
1811 {
1812 for (i = 0; i < cy; i++)
1813 for (j = 0; j < cx; j++)
1814 if ((i + srcy) < the_bitmap->h && (j + srcx) < the_bitmap->w)
1815 set_pixel(x + j, y + i,
1816 the_bitmap->data[(i + srcy) * the_bitmap->w + (j + srcx)],
1817 opcode);
1818 }
1819 else if (g_server_bpp == 16)
1820 {
1821 for (i = 0; i < cy; i++)
1822 for (j = 0; j < cx; j++)
1823 if ((i + srcy) < the_bitmap->h && (j + srcx) < the_bitmap->w)
1824 set_pixel(x + j, y + i,
1825 *(((uint16*)the_bitmap->data) + ((i + srcy) * the_bitmap->w + (j + srcx))),
1826 opcode);
1827 }
1828 else if (g_server_bpp == 24)
1829 {
1830 for (i = 0; i < cy; i++)
1831 for (j = 0; j < cx; j++)
1832 if ((i + srcy) < the_bitmap->h && (j + srcx) < the_bitmap->w)
1833 set_pixel(x + j, y + i,
1834 *(((uint32*)the_bitmap->data) + ((i + srcy) * the_bitmap->w + (j + srcx))),
1835 opcode);
1836 }
1837 }
1838 redraw(x, y, cx, cy);
1839 }
1840
1841 /******************************************************************************/
1842 // not used
1843 void ui_triblt(uint8 opcode, int x, int y, int cx, int cy,
1844 HBITMAP src, int srcx, int srcy, BRUSH * brush,
1845 int bgcolour, int fgcolour)
1846 {
1847 }
1848
1849 /******************************************************************************/
1850 /* Bresenham's line drawing algorithm */
1851 void ui_line(uint8 opcode, int startx, int starty, int endx,
1852 int endy, PEN * pen)
1853 {
1854 int dx, dy, incx, incy, dpr, dpru, p, left, top, right, bottom;
1855
1856 if (startx > endx)
1857 {
1858 dx = startx - endx;
1859 incx = -1;
1860 left = endx;
1861 right = startx;
1862 }
1863 else
1864 {
1865 dx = endx - startx;
1866 incx = 1;
1867 left = startx;
1868 right = endx;
1869 }
1870 if (starty > endy)
1871 {
1872 dy = starty - endy;
1873 incy = -1;
1874 top = endy;
1875 bottom = starty;
1876 }
1877 else
1878 {
1879 dy = endy - starty;
1880 incy = 1;
1881 top = starty;
1882 bottom = endy;
1883 }
1884 if (dx >= dy)
1885 {
1886 dpr = dy << 1;
1887 dpru = dpr - (dx << 1);
1888 p = dpr - dx;
1889 for (; dx >= 0; dx--)
1890 {
1891 set_pixel(startx, starty, pen->colour, opcode);
1892 if (p > 0)
1893 {
1894 startx += incx;
1895 starty += incy;
1896 p += dpru;
1897 }
1898 else
1899 {
1900 startx += incx;
1901 p += dpr;
1902 }
1903 }
1904 }
1905 else
1906 {
1907 dpr = dx << 1;
1908 dpru = dpr - (dy << 1);
1909 p = dpr - dy;
1910 for (; dy >= 0; dy--)
1911 {
1912 set_pixel(startx, starty, pen->colour, opcode);
1913 if (p > 0)
1914 {
1915 startx += incx;
1916 starty += incy;
1917 p += dpru;
1918 }
1919 else
1920 {
1921 starty += incy;
1922 p += dpr;
1923 }
1924 }
1925 }
1926 redraw(left, top, (right - left) + 1, (bottom - top) + 1);
1927 }
1928
1929 /******************************************************************************/
1930 void draw_glyph (int x, int y, HGLYPH glyph, int fgcolour)
1931 {
1932 struct bitmap *the_glyph;
1933 int i, j;
1934
1935 the_glyph = (struct bitmap*)glyph;
1936 if (the_glyph == NULL)
1937 return;
1938 for (i = 0; i < the_glyph->h; i++)
1939 for (j = 0; j < the_glyph->w; j++)
1940 if (is_pixel_on(the_glyph->data, j, i, the_glyph->w, 8))
1941 set_pixel(x + j, y + i, fgcolour);
1942 }
1943
1944 #define DO_GLYPH(ttext,idx) \
1945 {\
1946 glyph = cache_get_font (font, ttext[idx]);\
1947 if (!(flags & TEXT2_IMPLICIT_X))\
1948 {\
1949 xyoffset = ttext[++idx];\
1950 if ((xyoffset & 0x80))\
1951 {\
1952 if (flags & TEXT2_VERTICAL) \
1953 y += ttext[idx+1] | (ttext[idx+2] << 8);\
1954 else\
1955 x += ttext[idx+1] | (ttext[idx+2] << 8);\
1956 idx += 2;\
1957 }\
1958 else\
1959 {\
1960 if (flags & TEXT2_VERTICAL) \
1961 y += xyoffset;\
1962 else\
1963 x += xyoffset;\
1964 }\
1965 }\
1966 if (glyph != NULL)\
1967 {\
1968 draw_glyph (x + glyph->offset, y + glyph->baseline, glyph->pixmap, fgcolour);\
1969 if (flags & TEXT2_IMPLICIT_X)\
1970 x += glyph->width;\
1971 }\
1972 }
1973
1974 /******************************************************************************/
1975 //*****************************************************************************
1976 void ui_draw_text(uint8 font, uint8 flags, uint8 opcode, int mixmode,
1977 int x, int y, int clipx, int clipy,
1978 int clipcx, int clipcy, int boxx,
1979 int boxy, int boxcx, int boxcy, BRUSH * brush,
1980 int bgcolour, int fgcolour, uint8 * text, uint8 length)
1981 {
1982 FONTGLYPH * glyph;
1983 int i, j, xyoffset;
1984 DATABLOB * entry;
1985
1986 if (boxx + boxcx > g_width)
1987 boxcx = g_width - boxx;
1988 if (boxy + boxcy > g_height)
1989 boxcy = g_height - boxy;
1990
1991 if (boxcx > 1)
1992 fill_rect(boxx, boxy, boxcx, boxcy, bgcolour);
1993 else if (mixmode == MIX_OPAQUE)
1994 fill_rect(clipx, clipy, clipcx, clipcy, bgcolour);
1995
1996 /* Paint text, character by character */
1997 for (i = 0; i < length;)
1998 {
1999 switch (text[i])
2000 {
2001 case 0xff:
2002 if (i + 2 < length)
2003 cache_put_text(text[i + 1], text, text[i + 2]);
2004 else
2005 {
2006 error("this shouldn't be happening\n");
2007 exit(1);
2008 }
2009 /* this will move pointer from start to first character after FF command */
2010 length -= i + 3;
2011 text = &(text[i + 3]);
2012 i = 0;
2013 break;
2014
2015 case 0xfe:
2016 entry = cache_get_text(text[i + 1]);
2017 if (entry != NULL)
2018 {
2019 if ((((uint8 *) (entry->data))[1] == 0) && (!(flags & TEXT2_IMPLICIT_X)))
2020 {
2021 if (flags & TEXT2_VERTICAL)
2022 y += text[i + 2];
2023 else
2024 x += text[i + 2];
2025 }
2026 for (j = 0; j < entry->size; j++)
2027 DO_GLYPH(((uint8 *) (entry->data)), j);
2028 }
2029 if (i + 2 < length)
2030 i += 3;
2031 else
2032 i += 2;
2033 length -= i;
2034 /* this will move pointer from start to first character after FE command */
2035 text = &(text[i]);
2036 i = 0;
2037 break;
2038
2039 default:
2040 DO_GLYPH(text, i);
2041 i++;
2042 break;
2043 }
2044 }
2045 if (boxcx > 1)
2046 redraw(boxx, boxy, boxcx, boxcy);
2047 else
2048 redraw(clipx, clipy, clipcx, clipcy);
2049 }
2050
2051 /******************************************************************************/
2052 void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
2053 {
2054 uint8 * data;
2055 int i, j, Bpp, pixel;
2056
2057 Bpp = 4;
2058 switch (g_server_bpp)
2059 {
2060 case 8: Bpp = 1; break;
2061 case 15: Bpp = 2; break;
2062 case 16: Bpp = 2; break;
2063 }
2064 data = (uint8*)xmalloc(cx * cy * Bpp);
2065 if (g_server_bpp == 8)
2066 {
2067 for (i = 0; i < cy; i++)
2068 for (j = 0; j < cx; j++)
2069 {
2070 pixel = get_pixel(x + j, y + i);
2071 SETPIXEL8(data, j, i, cx, pixel);
2072 }
2073 }
2074 else if (g_server_bpp == 16)
2075 {
2076 for (i = 0; i < cy; i++)
2077 for (j = 0; j < cx; j++)
2078 {
2079 pixel = get_pixel(x + j, y + i);
2080 SETPIXEL16(data, j, i, cx, pixel);
2081 }
2082 }
2083 else if (g_server_bpp == 24)
2084 {
2085 for (i = 0; i < cy; i++)
2086 for (j = 0; j < cx; j++)
2087 *(((uint32*)data) + (i * cx + j)) = get_pixel(x + j, y + i);
2088 }
2089 offset *= Bpp;
2090 cache_put_desktop(offset, cx, cy, cx * Bpp, Bpp, data);
2091 xfree(data);
2092 }
2093
2094 /******************************************************************************/
2095 void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
2096 {
2097 uint8 * data;
2098 int i, j;
2099 int Bpp;
2100
2101 Bpp = 4;
2102 switch (g_server_bpp)
2103 {
2104 case 8: Bpp = 1; break;
2105 case 15: Bpp = 2; break;
2106 case 16: Bpp = 2; break;
2107 }
2108 offset *= Bpp;
2109 data = cache_get_desktop(offset, cx, cy, Bpp);
2110 if (g_server_bpp == 8)
2111 {
2112 for (i = 0; i < cy; i++)
2113 for (j = 0; j < cx; j++)
2114 set_pixel(x + j, y + i, data[i * cx + j]);
2115 }
2116 else if (g_server_bpp == 16)
2117 {
2118 for (i = 0; i < cy; i++)
2119 for (j = 0; j < cx; j++)
2120 set_pixel(x + j, y + i, *(((uint16*)data) + (i * cx + j)));
2121 }
2122 else if (g_server_bpp == 24)
2123 {
2124 for (i = 0; i < cy; i++)
2125 for (j = 0; j < cx; j++)
2126 set_pixel(x + j, y + i, *(((uint32*)data) + (i * cx + j)));
2127 }
2128 redraw(x, y, cx, cy);
2129 }
2130
2131 /*****************************************************************************/
2132 void * xrealloc(void * in_val, int size)
2133 {
2134 if (size < 1)
2135 {
2136 size = 1;
2137 }
2138 return realloc(in_val, size);
2139 }
2140
2141 /*****************************************************************************/
2142 void * xmalloc(int size)
2143 {
2144 return malloc(size);
2145 }
2146
2147 /*****************************************************************************/
2148 void xfree(void * in_val)
2149 {
2150 if (in_val != NULL)
2151 {
2152 free(in_val);
2153 }
2154 }
2155
2156 /*****************************************************************************/
2157 void warning(char * format, ...)
2158 {
2159 va_list ap;
2160
2161 fprintf(stderr, "WARNING: ");
2162 va_start(ap, format);
2163 vfprintf(stderr, format, ap);
2164 va_end(ap);
2165 }
2166
2167 /*****************************************************************************/
2168 void unimpl(char * format, ...)
2169 {
2170 va_list ap;
2171
2172 fprintf(stderr, "NOT IMPLEMENTED: ");
2173 va_start(ap, format);
2174 vfprintf(stderr, format, ap);
2175 va_end(ap);
2176 }
2177
2178 /*****************************************************************************/
2179 void error(char * format, ...)
2180 {
2181 va_list ap;
2182
2183 fprintf(stderr, "ERROR: ");
2184 va_start(ap, format);
2185 vfprintf(stderr, format, ap);
2186 va_end(ap);
2187 }
2188
2189 /*****************************************************************************/
2190 BOOL rd_pstcache_mkdir(void)
2191 {
2192 return 0;
2193 }
2194
2195 /*****************************************************************************/
2196 int rd_open_file(char * filename)
2197 {
2198 return 0;
2199 }
2200
2201 /*****************************************************************************/
2202 void rd_close_file(int fd)
2203 {
2204 return;
2205 }
2206
2207 /*****************************************************************************/
2208 int rd_read_file(int fd, void * ptr, int len)
2209 {
2210 return 0;
2211 }
2212
2213 /*****************************************************************************/
2214 int rd_write_file(int fd, void * ptr, int len)
2215 {
2216 return 0;
2217 }
2218
2219 /*****************************************************************************/
2220 int rd_lseek_file(int fd, int offset)
2221 {
2222 return 0;
2223 }
2224
2225 /*****************************************************************************/
2226 BOOL rd_lock_file(int fd, int start, int len)
2227 {
2228 return False;
2229 }
2230
2231 /*****************************************************************************/
2232 int load_licence(uint8 ** data)
2233 {
2234 return 0;
2235 }
2236
2237 /*****************************************************************************/
2238 void save_licence(uint8 * data, int length)
2239 {
2240 }
2241
2242 /*****************************************************************************/
2243 void generate_random(uint8 * random)
2244 {
2245 QFile File("/dev/random");
2246 File.open(IO_ReadOnly);
2247 if (File.readBlock((char*)random, 32) == 32)
2248 {
2249 return;
2250 }
2251 warning("no /dev/random\n");
2252 memcpy(random, "12345678901234567890123456789012", 32);
2253 }
2254
2255 /*****************************************************************************/
2256 /* produce a hex dump */
2257 void hexdump(uint8 * p, uint32 len)
2258 {
2259 uint8 * line = p;
2260 int i, thisline;
2261 uint32 offset = 0;
2262
2263 while (offset < len)
2264 {
2265 printf("%04x ", offset);
2266 thisline = len - offset;
2267 if (thisline > 16)
2268 {
2269 thisline = 16;
2270 }
2271 for (i = 0; i < thisline; i++)
2272 {
2273 printf("%02x ", line[i]);
2274 }
2275 for (; i < 16; i++)
2276 {
2277 printf(" ");
2278 }
2279 for (i = 0; i < thisline; i++)
2280 {
2281 printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
2282 }
2283 printf("\n");
2284 offset += thisline;
2285 line += thisline;
2286 }
2287 }
2288
2289 /*****************************************************************************/
2290 void get_username_and_hostname(void)
2291 {
2292 char fullhostname[64];
2293 char * p;
2294 struct passwd * pw;
2295
2296 STRNCPY(g_username, "unknown", sizeof(g_username));
2297 STRNCPY(g_hostname, "unknown", sizeof(g_hostname));
2298 pw = getpwuid(getuid());
2299 if (pw != NULL && pw->pw_name != NULL)
2300 {
2301 STRNCPY(g_username, pw->pw_name, sizeof(g_username));
2302 }
2303 if (gethostname(fullhostname, sizeof(fullhostname)) != -1)
2304 {
2305 p = strchr(fullhostname, '.');
2306 if (p != NULL)
2307 {
2308 *p = 0;
2309 }
2310 STRNCPY(g_hostname, fullhostname, sizeof(g_hostname));
2311 }
2312 }
2313
2314 /*****************************************************************************/
2315 void out_params(void)
2316 {
2317 fprintf(stderr, "qterdesktop: A Remote Desktop Protocol client.\n");
2318 fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2004 Matt Chapman.\n");
2319 fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
2320 fprintf(stderr, "Usage: qterdesktop [options] server\n");
2321 fprintf(stderr, " -g: desktop geometry (WxH)\n");
2322 fprintf(stderr, " -4: use RDP version 4\n");
2323 fprintf(stderr, " -5: use RDP version 5 (default)\n");
2324 fprintf(stderr, " -t: tcp port)\n");
2325 fprintf(stderr, " -a: connection colour depth\n");
2326 fprintf(stderr, " -u: user name\n");
2327 fprintf(stderr, " -d: domain\n");
2328 fprintf(stderr, " -s: shell\n");
2329 fprintf(stderr, " -c: working directory\n");
2330 fprintf(stderr, " -p: password (- to prompt)\n");
2331 fprintf(stderr, " -n: client hostname\n");
2332 fprintf(stderr, " -f: full screen\n");
2333 fprintf(stderr, " -r sound: enable sound\n");
2334 fprintf(stderr, "\n");
2335 }
2336
2337 /*****************************************************************************/
2338 int parse_parameters(int in_argc, char ** in_argv)
2339 {
2340 int i;
2341 char * p;
2342
2343 for (i = 1; i < in_argc; i++)
2344 {
2345 strcpy(g_server, in_argv[i]);
2346 if (strcmp(in_argv[i], "-h") == 0)
2347 {
2348 out_params();
2349 return 0;
2350 }
2351 else if (strcmp(in_argv[i], "-g") == 0)
2352 {
2353 g_width = strtol(in_argv[i + 1], &p, 10);
2354 if (*p == 'x')
2355 {
2356 g_height = strtol(p + 1, &p, 10);
2357 }
2358 if (*p == '-')
2359 {
2360 g_client_width = strtol(p + 1, &p, 10);
2361 }
2362 else
2363 {
2364 g_client_width = g_width;
2365 g_client_height = g_height;
2366 }
2367 if (*p == 'x')
2368 {
2369 g_client_height = strtol(p + 1, NULL, 10);
2370 }
2371 g_width = (g_width + 3) & ~3;
2372 g_height = (g_height + 3) & ~3;
2373 g_client_width = (g_client_width + 3) & ~3;
2374 g_client_height = (g_client_height + 3) & ~3;
2375 i++;
2376 }
2377 else if (strcmp(in_argv[i], "-4") == 0)
2378 {
2379 g_use_rdp5 = 0;
2380 }
2381 else if (strcmp(in_argv[i], "-5") == 0)
2382 {
2383 g_use_rdp5 = 1;
2384 }
2385 else if (strcmp(in_argv[i], "-a") == 0)
2386 {
2387 g_server_bpp = strtol(in_argv[i + 1], &p, 10);
2388 if (g_server_bpp != 8 &&
2389 g_server_bpp != 16 && g_server_bpp != 24)
2390 {
2391 error("invalid bpp\n");
2392 return 0;
2393 }
2394 i++;
2395 }
2396 else if (strcmp(in_argv[i], "-t") == 0)
2397 {
2398 g_tcp_port_rdp = strtol(in_argv[i + 1], &p, 10);
2399 i++;
2400 }
2401 else if (strcmp(in_argv[i], "-u") == 0)
2402 {
2403 STRNCPY(g_username, in_argv[i + 1], sizeof(g_username));
2404 i++;
2405 }
2406 else if (strcmp(in_argv[i], "-d") == 0)
2407 {
2408 STRNCPY(g_domain, in_argv[i + 1], sizeof(g_domain));
2409 i++;
2410 }
2411 else if (strcmp(in_argv[i], "-s") == 0)
2412 {
2413 STRNCPY(g_shell, in_argv[i + 1], sizeof(g_shell));
2414 i++;
2415 }
2416 else if (strcmp(in_argv[i], "-c") == 0)
2417 {
2418 STRNCPY(g_directory, in_argv[i + 1], sizeof(g_directory));
2419 i++;
2420 }
2421 else if (strcmp(in_argv[i], "-p") == 0)
2422 {
2423 STRNCPY(g_password, in_argv[i + 1], sizeof(g_password));
2424 g_flags |= RDP_LOGON_AUTO;
2425 i++;
2426 }
2427 else if (strcmp(in_argv[i], "-n") == 0)
2428 {
2429 STRNCPY(g_hostname, in_argv[i + 1], sizeof(g_hostname));
2430 i++;
2431 }
2432 else if (strcmp(in_argv[i], "-f") == 0)
2433 {
2434 g_fullscreen = 1;
2435 }
2436 else if (strcmp(in_argv[i], "-r") == 0)
2437 {
2438 if (strcmp(in_argv[i + 1], "sound") == 0)
2439 {
2440 #ifdef WITH_RDPSND
2441 g_rdpsnd = 1;
2442 #endif
2443 }
2444 i++;
2445 }
2446 }
2447 return 1;
2448 }
2449
2450 /******************************************************************************/
2451 int param_connect(void)
2452 {
2453 QWidget * Desktop;
2454 int dw, dh;
2455
2456 #ifdef WITH_RDPSND
2457 // init sound
2458 if (g_rdpsnd)
2459 {
2460 rdpsnd_init();
2461 }
2462 #endif
2463 if (rdp_connect(g_server, g_flags, g_domain, g_password, g_shell,
2464 g_directory))
2465 {
2466 g_BS = (uint8*)xmalloc(g_width * g_height * 4);
2467 memset(g_BS, 0, g_width * g_height * 4);
2468 g_clipx = 0;
2469 g_clipy = 0;
2470 g_clipcx = g_width;
2471 g_clipcy = g_height;
2472 g_CM = (QColorMap*)xmalloc(sizeof(struct QColorMap));
2473 memset(g_CM, 0, sizeof(struct QColorMap));
2474 g_CM->NumColors = 256;
2475 g_MW = new QMyMainWindow();
2476 g_MW->resize(g_client_width, g_client_height);
2477 g_MW->show();
2478 g_SV->addChild(g_MW);
2479 g_MW->setMouseTracking(true);
2480 g_SocketNotifier = new QSocketNotifier(g_global_sock,
2481 QSocketNotifier::Read,
2482 g_MW);
2483 g_MW->connect(g_SocketNotifier, SIGNAL(activated(int)), g_MW,
2484 SLOT(dataReceived()));
2485 if (g_fullscreen)
2486 {
2487 Desktop = g_App->desktop();
2488 dw = Desktop->width();
2489 dh = Desktop->height();
2490 if (dw == g_client_width && dh == g_client_height)
2491 {
2492 g_MW->resize(g_client_width - 4, g_client_height - 4);
2493 }
2494 g_SV->showFullScreen();
2495 }
2496 g_MW->setCursor((int)10); /* Qt::BlankCursor */
2497 g_App->exec();
2498 }
2499 return 0;
2500 }
2501
2502 /******************************************************************************/
2503 int main(int argc, char ** argv)
2504 {
2505 #ifdef SHARP
2506 g_App = new QPEApplication(argc, argv);
2507 #else
2508 g_App = new QApplication(argc, argv, QApplication::GuiServer);
2509 //g_App = new QApplication(argc, argv);
2510 #endif
2511 g_SV = new QMyScrollView();
2512 g_App->setMainWidget(g_SV);
2513 g_SV->showMaximized();
2514 if (argc > 1)
2515 {
2516 get_username_and_hostname();
2517 if (parse_parameters(argc, argv))
2518 {
2519 param_connect();
2520 }
2521 }
2522 else
2523 {
2524 g_SV->timer_id = g_SV->startTimer(1000); /* one sec delay, then dialog */
2525 g_App->exec();
2526 }
2527 delete g_SV;
2528 delete g_App;
2529 xfree(g_CM);
2530 xfree(g_BS);
2531 return 0;
2532 }

  ViewVC Help
Powered by ViewVC 1.1.26