/[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 796 - (show annotations)
Fri Nov 5 03:13:33 2004 UTC (19 years, 6 months ago) by jsorg71
File size: 67439 byte(s)
screenblt optimize

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

  ViewVC Help
Powered by ViewVC 1.1.26