/[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 851 - (show annotations)
Sun Mar 13 06:38:42 2005 UTC (19 years, 3 months ago) by jsorg71
File size: 67470 byte(s)
year change

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 #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_MW->setCursor((int)10); /* Qt::BlankCursor */
774 g_SocketNotifier = new QSocketNotifier(g_global_sock,
775 QSocketNotifier::Read,
776 g_MW);
777 g_MW->connect(g_SocketNotifier, SIGNAL(activated(int)), g_MW,
778 SLOT(dataReceived()));
779 if (g_fullscreen)
780 {
781 Desktop = g_App->desktop();
782 dw = Desktop->width();
783 dh = Desktop->height();
784 if (dw == g_client_width && dh == g_client_height)
785 g_MW->resize(g_client_width - 4, g_client_height - 4);
786 g_SV->showFullScreen();
787 }
788 delete d;
789 }
790 else // cancel clicked
791 {
792 delete d;
793 g_SV->close();
794 }
795 }
796
797 /******************************************************************************/
798 QMyMainWindow::QMyMainWindow() : QWidget(g_SV->viewport())
799 {
800 PopupMenu = new QPopupMenu(this);
801 PopupMenu->insertItem("Right click", 1, 0);
802 PopupMenu->insertItem("Toggle fullscreen", 2, 1);
803 PopupMenu->insertItem("Reset keyboard", 3, 2);
804 PopupMenu->insertItem("Double click", 4, 3);
805 connect(PopupMenu, SIGNAL(activated(int)), this, SLOT(MemuClicked(int)));
806 }
807
808 /******************************************************************************/
809 QMyMainWindow::~QMyMainWindow()
810 {
811 delete PopupMenu;
812 }
813
814 /******************************************************************************/
815 int rd(double in)
816 {
817 return (int)(in + 0.50);
818 }
819
820 /******************************************************************************/
821 int c2sx(int cx)
822 {
823 double sx;
824
825 sx = (double)g_client_width / (double)g_width;
826 return rd(cx / sx);
827 }
828
829 /******************************************************************************/
830 int c2sy(int cy)
831 {
832 double sy;
833
834 sy = (double)g_client_height / (double)g_height;
835 return rd(cy / sy);
836 }
837
838 /******************************************************************************/
839 void QMyMainWindow::timerEvent(QTimerEvent * e)
840 {
841 QWidget::timerEvent(e);
842 if (e->timerId() == timer_id)
843 {
844 // send mouse up
845 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1,
846 rd(c2sx(mx)), rd(c2sy(my)));
847 // if in fullscreen, take it out or the menu won't work
848 if (g_fullscreen)
849 {
850 g_fullscreen = 0;
851 g_SV->showNormal();
852 g_SV->showMaximized();
853 }
854 else
855 PopupMenu->popup(mapToGlobal(QPoint(mx, my)));
856 }
857 killTimer(timer_id);
858 }
859
860 /******************************************************************************/
861 void QMyMainWindow::MemuClicked(int MenuID)
862 {
863 QWidget * Desktop;
864 int dw;
865 int dh;
866
867 if (MenuID == 1) // right click
868 {
869 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON2,
870 rd(c2sx(mx)), rd(c2sy(my)));
871 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON2,
872 rd(c2sx(mx)), rd(c2sy(my)));
873 }
874 else if (MenuID == 2) // toggle full screen
875 {
876 g_fullscreen = ~g_fullscreen;
877 if (g_fullscreen)
878 {
879 Desktop = g_App->desktop();
880 dw = Desktop->width();
881 dh = Desktop->height();
882 if (dw == g_client_width && dh == g_client_height)
883 g_MW->resize(g_client_width - 4, g_client_height - 4);
884 g_SV->showFullScreen();
885 }
886 else
887 {
888 g_SV->showNormal();
889 g_SV->showMaximized();
890 g_MW->resize(g_client_width, g_client_height);
891 }
892 }
893 else if (MenuID == 3) // reset keyboard
894 {
895 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, 0x2a, 0); // shift
896 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, 0x1d, 0); // control
897 rdp_send_input(0, RDP_INPUT_SCANCODE, RDP_KEYRELEASE, 0x38, 0); // alt
898 }
899 else if (MenuID == 4) // double click
900 {
901 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON1,
902 rd(c2sx(mx)), rd(c2sy(my)));
903 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1,
904 rd(c2sx(mx)), rd(c2sy(my)));
905 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON1,
906 rd(c2sx(mx)), rd(c2sy(my)));
907 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1,
908 rd(c2sx(mx)), rd(c2sy(my)));
909 }
910 }
911
912 /******************************************************************************/
913 void QMyMainWindow::mouseMoveEvent(QMouseEvent* e)
914 {
915 int x, y;
916
917 x = e->x();
918 y = e->y();
919 if (timer_id)
920 {
921 x = x - mx;
922 y = y - my;
923 if (x < -10 || x > 10 || y < -10 || y > 10)
924 {
925 killTimer(timer_id);
926 timer_id = 0;
927 }
928 }
929 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE, c2sx(e->x()),
930 c2sy(e->y()));
931 }
932
933 /******************************************************************************/
934 void QMyMainWindow::mousePressEvent(QMouseEvent* e)
935 {
936 timer_id = startTimer(1000);
937 mx = e->x();
938 my = e->y();
939 if (e->button() == LeftButton)
940 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON1,
941 c2sx(e->x()), c2sy(e->y()));
942 else if (e->button() == RightButton)
943 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON2,
944 c2sx(e->x()), c2sy(e->y()));
945 else if (e->button() == MidButton)
946 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_DOWN | MOUSE_FLAG_BUTTON3,
947 c2sx(e->x()), c2sy(e->y()));
948 }
949
950 /******************************************************************************/
951 void QMyMainWindow::mouseReleaseEvent(QMouseEvent* e)
952 {
953 killTimer(timer_id);
954 timer_id = 0;
955 if (e->button() == LeftButton)
956 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1, c2sx(e->x()),
957 c2sy(e->y()));
958 else if (e->button() == RightButton)
959 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON2, c2sx(e->x()),
960 c2sy(e->y()));
961 else if (e->button() == MidButton)
962 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON3, c2sx(e->x()),
963 c2sy(e->y()));
964 }
965
966 /******************************************************************************/
967 void QMyMainWindow::wheelEvent(QWheelEvent* e)
968 {
969 if (e->delta() > 0)
970 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON4, c2sx(e->x()),
971 c2sy(e->y()));
972 else if (e->delta() < 0)
973 rdp_send_input(0, RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON5, c2sx(e->x()),
974 c2sy(e->y()));
975 }
976
977 #define NOT(x) (~x)
978
979 /******************************************************************************/
980 int rop(int rop, int src, int dst)
981 {
982 switch (rop)
983 {
984 case 0x0: return 0;
985 case 0x1: return NOT (src | dst);
986 case 0x2: return NOT (src) & dst;
987 case 0x3: return NOT (src);
988 case 0x4: return src & NOT (dst);
989 case 0x5: return NOT (dst);
990 case 0x6: return src ^ dst;
991 case 0x7: return NOT (src & dst);
992 case 0x8: return src & dst;
993 case 0x9: return NOT (src) ^ dst;
994 case 0xa: return dst;
995 case 0xb: return NOT (src) | dst;
996 case 0xc: return src;
997 case 0xd: return src | NOT (dst);
998 case 0xe: return src | dst;
999 case 0xf: return NOT (0);
1000 }
1001 return dst;
1002 }
1003
1004 /*****************************************************************************/
1005 int get_pixel(int x, int y)
1006 {
1007 if (x >= 0 && x < g_width && y >= 0 && y < g_height)
1008 {
1009 if (g_server_bpp == 8)
1010 return GETPIXEL8(g_BS, x, y, g_width);
1011 else if (g_server_bpp == 16)
1012 return GETPIXEL16(g_BS, x, y, g_width);
1013 else if (g_server_bpp == 24)
1014 return GETPIXEL32(g_BS, x, y, g_width);
1015 else
1016 return 0;
1017 }
1018 else
1019 return 0;
1020 }
1021
1022 /******************************************************************************/
1023 void set_pixel(int x, int y, int pixel, int op = 0xc)
1024 {
1025 int p;
1026
1027 if (x >= g_clipx && x < (g_clipx + g_clipcx) &&
1028 y >= g_clipy && y < (g_clipy + g_clipcy))
1029 {
1030 if (x >= 0 && x < g_width && y >= 0 && y < g_height)
1031 {
1032 if (op == 0xc)
1033 {
1034 if (g_server_bpp == 8)
1035 {
1036 SETPIXEL8(g_BS, x, y, g_width, pixel);
1037 }
1038 else if (g_server_bpp == 16)
1039 {
1040 SETPIXEL16(g_BS, x, y, g_width, pixel);
1041 }
1042 else if (g_server_bpp == 24)
1043 {
1044 SETPIXEL32(g_BS, x, y, g_width, pixel);
1045 }
1046 }
1047 else
1048 {
1049 if (g_server_bpp == 8)
1050 {
1051 p = GETPIXEL8(g_BS, x, y, g_width);
1052 p = rop(op, pixel, p);
1053 SETPIXEL8(g_BS, x, y, g_width, p);
1054 }
1055 else if (g_server_bpp == 16)
1056 {
1057 p = GETPIXEL16(g_BS, x, y, g_width);
1058 p = rop(op, pixel, p);
1059 SETPIXEL16(g_BS, x, y, g_width, p);
1060 }
1061 else if (g_server_bpp == 24)
1062 {
1063 p = GETPIXEL32(g_BS, x, y, g_width);
1064 p = rop(op, pixel, p);
1065 SETPIXEL32(g_BS, x, y, g_width, p);
1066 }
1067 }
1068 }
1069 }
1070 }
1071
1072 /******************************************************************************/
1073 // adjust coordinates for cliping rect
1074 bool WarpCoords(int * x, int * y, int * cx, int * cy, int * srcx, int * srcy)
1075 {
1076 int dx, dy;
1077 QRect InRect(*x, *y, *cx, *cy);
1078 QRect OutRect;
1079 QRect CRect(g_clipx, g_clipy, g_clipcx, g_clipcy);
1080 OutRect = InRect.intersect(CRect);
1081 if (OutRect.isEmpty())
1082 return false;
1083 dx = OutRect.x() - InRect.x();
1084 dy = OutRect.y() - InRect.y();
1085 *x = OutRect.x();
1086 *y = OutRect.y();
1087 *cx = OutRect.width();
1088 *cy = OutRect.height();
1089 if (srcx != NULL)
1090 *srcx = *srcx + dx;
1091 if (srcy != NULL)
1092 *srcy = *srcy + dy;
1093 return true;
1094 }
1095
1096 /******************************************************************************/
1097 void QMyMainWindow::paintEvent(QPaintEvent * pe)
1098 {
1099 QImage * Image;
1100 QPainter * Painter;
1101 QRect Rect;
1102 int i, j, w, h, l, t, pixel, r, g, b;
1103 uint8 * data;
1104 double sx, sy;
1105
1106 Image = 0;
1107 data = 0;
1108 if (!testWFlags(WRepaintNoErase))
1109 setWFlags(WRepaintNoErase);
1110 if (g_CM != NULL || g_server_bpp > 8)
1111 {
1112 sx = (double)g_client_width / (double)g_width;
1113 sy = (double)g_client_height / (double)g_height;
1114 Rect = pe->rect();
1115 l = rd(Rect.left() / sx);
1116 t = rd(Rect.top() / sy);
1117 w = rd(Rect.width() / sx);
1118 h = rd(Rect.height() / sy);
1119 if (w > 0 && h > 0)
1120 {
1121 if (g_server_bpp == 8 && g_CM->NumColors > 0)
1122 {
1123 w = (w + 3) & ~3;
1124 data = (uint8*)xmalloc(w * h);
1125 for (i = 0; i < h; i++)
1126 for (j = 0; j < w; j++)
1127 data[i * w + j] = GETPIXEL8(g_BS, l + j, t + i, g_width);
1128 Image = new QImage(data, w, h, 8,(QRgb*)g_CM->RGBColors,
1129 g_CM->NumColors, QImage::IgnoreEndian);
1130 }
1131 else if (g_server_bpp == 16)
1132 {
1133 w = (w + 3) & ~3;
1134 data = (uint8*)xmalloc(w * h * 4);
1135 for (i = 0; i < h; i++)
1136 for (j = 0; j < w; j++)
1137 {
1138 pixel = GETPIXEL16(g_BS, l + j, t + i, g_width);
1139 r = ((pixel >> 8) & 0xf8) | ((pixel >> 13) & 0x7);
1140 g = ((pixel >> 3) & 0xfc) | ((pixel >> 9) & 0x3);
1141 b = ((pixel << 3) & 0xf8) | ((pixel >> 2) & 0x7);
1142 pixel = ((r << 16) | (g << 8) | b);
1143 SETPIXEL32(data, j, i, w, pixel);
1144 }
1145 Image = new QImage(data, w, h, 32, NULL,
1146 0, QImage::IgnoreEndian);
1147 }
1148 else if (g_server_bpp == 24)
1149 {
1150 w = (w + 3) & ~3;
1151 data = (uint8*)xmalloc(w * h * 4);
1152 for (i = 0; i < h; i++)
1153 for (j = 0; j < w; j++)
1154 {
1155 pixel = GETPIXEL32(g_BS, l + j, t + i, g_width);
1156 r = (pixel >> 0) & 0xff;
1157 g = (pixel >> 8) & 0xff;
1158 b = (pixel >> 16) & 0xff;
1159 pixel = ((r << 16) | (g << 8) | b);
1160 SETPIXEL32(data, j, i, w, pixel);
1161 }
1162 Image = new QImage(data, w, h, 32, NULL,
1163 0, QImage::IgnoreEndian);
1164 }
1165 if (Image != 0)
1166 {
1167 Painter = new QPainter(this);
1168 Painter->scale(sx, sy);
1169 Painter->drawImage(l, t, *Image, 0, 0, w, h);
1170 delete Painter;
1171 delete Image;
1172 }
1173 xfree(data);
1174 }
1175 }
1176 }
1177
1178 /******************************************************************************/
1179 void QMyMainWindow::closeEvent(QCloseEvent * e)
1180 {
1181 e->accept();
1182 }
1183
1184 /******************************************************************************/
1185 void QMyMainWindow::dataReceived()
1186 {
1187 if (!rdp_loop(&g_deactivated, &g_ext_disc_reason))
1188 g_SV->close();
1189 #ifdef WITH_RDPSND
1190 if (g_dsp_busy)
1191 {
1192 if (g_SoundNotifier == 0)
1193 {
1194 g_SoundNotifier = new QSocketNotifier(g_dsp_fd, QSocketNotifier::Write,
1195 g_MW);
1196 g_MW->connect(g_SoundNotifier, SIGNAL(activated(int)), g_MW,
1197 SLOT(soundSend()));
1198 }
1199 else
1200 {
1201 if (!g_SoundNotifier->isEnabled())
1202 g_SoundNotifier->setEnabled(true);
1203 }
1204 }
1205 #endif
1206 }
1207
1208 /******************************************************************************/
1209 void QMyMainWindow::soundSend()
1210 {
1211 g_SoundNotifier->setEnabled(false);
1212 #ifdef WITH_RDPSND
1213 wave_out_play();
1214 if (g_dsp_busy)
1215 g_SoundNotifier->setEnabled(true);
1216 #endif
1217 }
1218
1219 /******************************************************************************/
1220 void redraw(int x, int y, int cx, int cy)
1221 {
1222 double sx, sy;
1223
1224 if (WarpCoords(&x, &y, &cx, &cy, NULL, NULL))
1225 {
1226 sx = (double)g_client_width / (double)g_width;
1227 sy = (double)g_client_height / (double)g_height;
1228 x = rd(x * sx);
1229 y = rd(y * sy);
1230 cx = rd(cx * sx);
1231 cy = rd(cy * sy);
1232 g_MW->update(x, y, cx, cy);
1233 }
1234 }
1235
1236 /******************************************************************************/
1237 /* Returns 0 after user quit, 1 otherwise */
1238 int ui_select(int rdp_socket)
1239 {
1240 if (g_global_sock == 0)
1241 g_global_sock = rdp_socket;
1242 return 1;
1243 }
1244
1245 /******************************************************************************/
1246 void ui_move_pointer(int /*x*/, int /*y*/)
1247 {
1248 }
1249
1250 /******************************************************************************/
1251 void ui_set_null_cursor(void)
1252 {
1253 }
1254
1255 /******************************************************************************/
1256 HBITMAP ui_create_bitmap(int width, int height, uint8 * data)
1257 {
1258 struct bitmap * the_bitmap;
1259 uint8 * bitmap_data;
1260 int i, j;
1261 int r, g, b, pixel;
1262
1263 bitmap_data = (uint8*)xmalloc(width * height * 4);
1264 the_bitmap = (struct bitmap*)xmalloc(sizeof(struct bitmap));
1265 the_bitmap->w = width;
1266 the_bitmap->h = height;
1267 the_bitmap->data = bitmap_data;
1268 if (g_server_bpp == 8)
1269 {
1270 for (i = 0; i < height; i++)
1271 for (j = 0; j < width; j++)
1272 bitmap_data[i * width + j] = data[i * width + j];
1273 }
1274 else if (g_server_bpp == 16)
1275 {
1276 for (i = 0; i < height; i++)
1277 for (j = 0; j < width; j++)
1278 *(((uint16*)bitmap_data) + (i * width + j)) =
1279 *(((uint16*)data) + (i * width + j));
1280 }
1281 else if (g_server_bpp == 24)
1282 {
1283 for (i = 0; i < height; i++)
1284 for (j = 0; j < width; j++)
1285 {
1286 r = data[(i * width + j) * 3 + 0];
1287 g = data[(i * width + j) * 3 + 1];
1288 b = data[(i * width + j) * 3 + 2];
1289 pixel = (r << 16) | (g << 8) | b;
1290 SETPIXEL32(bitmap_data, j, i, width, pixel);
1291 }
1292 }
1293 return the_bitmap;
1294 }
1295
1296 /******************************************************************************/
1297 void ui_paint_bitmap(int x, int y, int cx, int cy, int width,
1298 int height, uint8 * data)
1299 {
1300 int i, j;
1301 int r, g, b, pixel;
1302
1303 if (g_server_bpp == 8)
1304 {
1305 for (i = 0; i < cy; i++)
1306 for (j = 0; j < cx; j++)
1307 if (i < height)
1308 if (j < width)
1309 set_pixel(x + j, y + i, data[i * width + j]);
1310 }
1311 else if (g_server_bpp == 16)
1312 {
1313 for (i = 0; i < cy; i++)
1314 for (j = 0; j < cx; j++)
1315 if (i < height)
1316 if (j < width)
1317 set_pixel(x + j, y + i, *(((uint16*)data) + (i * width + j)));
1318 }
1319 else if (g_server_bpp == 24)
1320 {
1321 for (i = 0; i < cy; i++)
1322 for (j = 0; j < cx; j++)
1323 if (i < height)
1324 if (j < width)
1325 {
1326 r = data[(i * width + j) * 3 + 0];
1327 g = data[(i * width + j) * 3 + 1];
1328 b = data[(i * width + j) * 3 + 2];
1329 pixel = (r << 16) | (g << 8) | b;
1330 set_pixel(x + j, y + i, pixel);
1331 }
1332 }
1333 redraw(x, y, cx, cy);
1334 }
1335
1336 /******************************************************************************/
1337 void ui_destroy_bitmap(HBITMAP bmp)
1338 {
1339 struct bitmap* the_bitmap;
1340
1341 the_bitmap = (struct bitmap*)bmp;
1342 if (the_bitmap != NULL)
1343 {
1344 if (the_bitmap->data != NULL)
1345 xfree(the_bitmap->data);
1346 xfree(the_bitmap);
1347 }
1348 }
1349
1350 /******************************************************************************/
1351 bool is_pixel_on(uint8 * data, int x, int y, int width, int bpp)
1352 {
1353 int start, shift;
1354
1355 if (bpp == 1)
1356 {
1357 width = (width + 7) / 8;
1358 start = (y * width) + x / 8;
1359 shift = x % 8;
1360 return (data[start] & (0x80 >> shift)) != 0;
1361 }
1362 else if (bpp == 8)
1363 return data[y * width + x] != 0;
1364 else
1365 return false;
1366 }
1367
1368 /******************************************************************************/
1369 void set_pixel_on(uint8 * data, int x, int y, int width, int bpp, uint8 pixel)
1370 {
1371 if (bpp == 8)
1372 data[y * width + x] = pixel;
1373 }
1374
1375 /******************************************************************************/
1376 HGLYPH ui_create_glyph(int width, int height, uint8 * data)
1377 {
1378 int i, j;
1379 uint8* glyph_data;
1380 struct bitmap* the_glyph;
1381
1382 glyph_data = (uint8*)xmalloc(width * height);
1383 the_glyph = (struct bitmap*)xmalloc(sizeof(struct bitmap));
1384 the_glyph->w = width;
1385 the_glyph->h = height;
1386 the_glyph->data = glyph_data;
1387 memset(glyph_data, 0, width * height);
1388 for (i = 0; i < height; i++)
1389 for (j = 0; j < width; j++)
1390 if (is_pixel_on(data, j, i, width, 1))
1391 set_pixel_on(glyph_data, j, i, width, 8, 255);
1392 return the_glyph;
1393 }
1394
1395 /******************************************************************************/
1396 void ui_destroy_glyph(HGLYPH glyph)
1397 {
1398 struct bitmap* the_glyph;
1399
1400 the_glyph = (struct bitmap*)glyph;
1401 if (the_glyph != NULL)
1402 {
1403 if (the_glyph->data != NULL)
1404 xfree(the_glyph->data);
1405 xfree(the_glyph);
1406 }
1407 }
1408
1409 /******************************************************************************/
1410 HCURSOR ui_create_cursor(uint32 x, uint32 y,
1411 int width, int height,
1412 uint8 * andmask, uint8 * xormask)
1413 {
1414 return (void*)1;
1415 }
1416
1417 /******************************************************************************/
1418 void ui_set_cursor(HCURSOR /*cursor*/)
1419 {
1420 }
1421
1422 /*****************************************************************************/
1423 uint16 ui_get_numlock_state(uint32 state)
1424 {
1425 return 0;
1426 }
1427
1428 /*****************************************************************************/
1429 unsigned int read_keyboard_state(void)
1430 {
1431 return 0;
1432 }
1433
1434 /*****************************************************************************/
1435 void ui_resize_window(void)
1436 {
1437 }
1438
1439 /******************************************************************************/
1440 void ui_destroy_cursor(HCURSOR /*cursor*/)
1441 {
1442 }
1443
1444 /******************************************************************************/
1445 HCOLOURMAP ui_create_colourmap(COLOURMAP * colours)
1446 {
1447 int i;
1448 int x;
1449 uint8 r, g, b;
1450 i = 0;
1451 while (i < colours->ncolours && i < 256)
1452 {
1453 r = colours->colours[i].red;
1454 g = colours->colours[i].green;
1455 b = colours->colours[i].blue;
1456 x = (r << 16) | (g << 8) | b;
1457 g_CM->RGBColors[i] = x;
1458 i++;
1459 }
1460 g_CM->NumColors = colours->ncolours;
1461 return g_CM;
1462 }
1463
1464 /******************************************************************************/
1465 void ui_set_colourmap(HCOLOURMAP map)
1466 {
1467 }
1468
1469 /******************************************************************************/
1470 void ui_destroy_colourmap(HCOLOURMAP map)
1471 {
1472 }
1473
1474 /******************************************************************************/
1475 void ui_begin_update(void)
1476 {
1477 }
1478
1479 /******************************************************************************/
1480 void ui_end_update(void)
1481 {
1482 }
1483
1484 /******************************************************************************/
1485 void ui_set_clip(int x, int y, int cx, int cy)
1486 {
1487 g_clipx = x;
1488 g_clipy = y;
1489 g_clipcx = cx;
1490 g_clipcy = cy;
1491 }
1492
1493 /******************************************************************************/
1494 void ui_reset_clip(void)
1495 {
1496 g_clipx = 0;
1497 g_clipy = 0;
1498 g_clipcx = g_width;
1499 g_clipcy = g_height;
1500 }
1501
1502 /******************************************************************************/
1503 void ui_bell(void)
1504 {
1505 g_App->beep();
1506 }
1507
1508 /******************************************************************************/
1509 void ui_destblt(uint8 opcode, int x, int y, int cx, int cy)
1510 {
1511 int i, j;
1512
1513
1514 if (opcode == 0x0) /* black */
1515 {
1516 for (i = 0; i < cy; i++)
1517 for (j = 0; j < cx; j++)
1518 set_pixel(x + j, y + i, 0, 0xc);
1519 }
1520 else if (opcode == 0xf) /* white */
1521 {
1522 for (i = 0; i < cy; i++)
1523 for (j = 0; j < cx; j++)
1524 set_pixel(x + j, y + i, 0xffffff, 0xc);
1525 }
1526 else
1527 {
1528 for (i = 0; i < cy; i++)
1529 for (j = 0; j < cx; j++)
1530 set_pixel(x + j, y + i, get_pixel(x + j, y + i), opcode);
1531 }
1532 redraw(x, y, cx, cy);
1533 }
1534
1535 /******************************************************************************/
1536 // does not repaint
1537 void fill_rect(int x, int y, int cx, int cy, int colour, int opcode = 0xc)
1538 {
1539 int i, j;
1540
1541 if (x + cx > g_width)
1542 cx = g_width - x;
1543 if (y + cy > g_height)
1544 cy = g_height - y;
1545 #ifdef QT_OPTI
1546 if (opcode == 0xc) /* optimize */
1547 {
1548 if (WarpCoords(&x, &y, &cx, &cy, 0, 0))
1549 {
1550 if (g_server_bpp == 8)
1551 {
1552 for (i = 0; i < cy; i++)
1553 for (j = 0; j < cx; j++)
1554 SETPIXEL8(g_BS, x + j, y + i, g_width, colour);
1555 }
1556 else if (g_server_bpp == 16)
1557 {
1558 for (i = 0; i < cy; i++)
1559 for (j = 0; j < cx; j++)
1560 SETPIXEL16(g_BS, x + j, y + i, g_width, colour);
1561 }
1562 else if (g_server_bpp == 24)
1563 {
1564 for (i = 0; i < cy; i++)
1565 for (j = 0; j < cx; j++)
1566 SETPIXEL32(g_BS, x + j, y + i, g_width, colour);
1567 }
1568 }
1569 }
1570 else
1571 #endif
1572 {
1573 for (i = 0; i < cy; i++)
1574 for (j = 0; j < cx; j++)
1575 set_pixel(x + j, y + i, colour, opcode);
1576 }
1577 }
1578
1579 /******************************************************************************/
1580 void ui_rect(int x, int y, int cx, int cy, int colour)
1581 {
1582 fill_rect(x, y, cx, cy, colour);
1583 redraw(x, y, cx, cy);
1584 }
1585
1586 /******************************************************************************/
1587 void ui_patblt(uint8 opcode, int x, int y, int cx, int cy,
1588 BRUSH * brush, int bgcolour, int fgcolour)
1589 {
1590 int i, j;
1591 uint8 ipattern[8];
1592
1593 switch (brush->style)
1594 {
1595 case 0:
1596 fill_rect(x, y, cx, cy, fgcolour, opcode);
1597 break;
1598 case 3:
1599 for (i = 0; i < 8; i++)
1600 ipattern[i] = ~brush->pattern[7 - i];
1601 for (i = 0; i < cy; i++)
1602 for (j = 0; j < cx; j++)
1603 if (is_pixel_on(ipattern, (x + j + brush->xorigin) % 8,
1604 (y + i + brush->yorigin) % 8, 8, 1))
1605 set_pixel(x + j, y + i, fgcolour, opcode);
1606 else
1607 set_pixel(x + j, y + i, bgcolour, opcode);
1608 break;
1609 }
1610 redraw(x, y, cx, cy);
1611 }
1612
1613 /******************************************************************************/
1614 void ui_screenblt(uint8 opcode, int x, int y, int cx, int cy,
1615 int srcx, int srcy)
1616 {
1617 int i, j, pixel;
1618 uint8 * temp;
1619
1620 temp = (uint8*)xmalloc(cx * cy * 4);
1621 #ifdef QT_OPTI
1622 if (opcode == 0xc)
1623 {
1624 if (WarpCoords(&x, &y, &cx, &cy, &srcx, &srcy))
1625 {
1626 if (g_server_bpp == 8)
1627 {
1628 for (i = 0; i < cy; i++)
1629 for (j = 0; j < cx; j++)
1630 {
1631 pixel = GETPIXEL8(g_BS, srcx + j, srcy + i, g_width);
1632 SETPIXEL8(temp, j, i, cx, pixel);
1633 }
1634 for (i = 0; i < cy; i++)
1635 for (j = 0; j < cx; j++)
1636 {
1637 pixel = GETPIXEL8(temp, j, i, cx);
1638 SETPIXEL8(g_BS, x + j, y + i, g_width, pixel);
1639 }
1640 }
1641 else if (g_server_bpp == 16)
1642 {
1643 for (i = 0; i < cy; i++)
1644 for (j = 0; j < cx; j++)
1645 {
1646 pixel = GETPIXEL16(g_BS, srcx + j, srcy + i, g_width);
1647 SETPIXEL16(temp, j, i, cx, pixel);
1648 }
1649 for (i = 0; i < cy; i++)
1650 for (j = 0; j < cx; j++)
1651 {
1652 pixel = GETPIXEL16(temp, j, i, cx);
1653 SETPIXEL16(g_BS, x + j, y + i, g_width, pixel);
1654 }
1655 }
1656 else if (g_server_bpp == 24)
1657 {
1658 for (i = 0; i < cy; i++)
1659 for (j = 0; j < cx; j++)
1660 {
1661 pixel = GETPIXEL32(g_BS, srcx + j, srcy + i, g_width);
1662 SETPIXEL32(temp, j, i, cx, pixel);
1663 }
1664 for (i = 0; i < cy; i++)
1665 for (j = 0; j < cx; j++)
1666 {
1667 pixel = GETPIXEL32(temp, j, i, cx);
1668 SETPIXEL32(g_BS, x + j, y + i, g_width, pixel);
1669 }
1670 }
1671 }
1672 }
1673 else
1674 #endif
1675 {
1676 if (g_server_bpp == 8)
1677 {
1678 for (i = 0; i < cy; i++)
1679 for (j = 0; j < cx; j++)
1680 temp[i * cx + j] = get_pixel(srcx + j, srcy + i);
1681 for (i = 0; i < cy; i++)
1682 for (j = 0; j < cx; j++)
1683 set_pixel(x + j, y + i, temp[i * cx + j], opcode);
1684 }
1685 else if (g_server_bpp == 16)
1686 {
1687 for (i = 0; i < cy; i++)
1688 for (j = 0; j < cx; j++)
1689 {
1690 pixel = get_pixel(srcx + j, srcy + i);
1691 SETPIXEL16(temp, j, i, cx, pixel);
1692 }
1693 for (i = 0; i < cy; i++)
1694 for (j = 0; j < cx; j++)
1695 {
1696 pixel = GETPIXEL16(temp, j, i, cx);
1697 set_pixel(x + j, y + i, pixel, opcode);
1698 }
1699 }
1700 else if (g_server_bpp == 24)
1701 {
1702 for (i = 0; i < cy; i++)
1703 for (j = 0; j < cx; j++)
1704 *(((uint32*)temp) + (i * cx + j)) = get_pixel(srcx + j, srcy + i);
1705 for (i = 0; i < cy; i++)
1706 for (j = 0; j < cx; j++)
1707 set_pixel(x + j, y + i, *(((uint32*)temp) + (i * cx + j)), opcode);
1708 }
1709 }
1710 xfree(temp);
1711 redraw(x, y, cx, cy);
1712 }
1713
1714 /******************************************************************************/
1715 void ui_memblt(uint8 opcode, int x, int y, int cx, int cy,
1716 HBITMAP src, int srcx, int srcy)
1717 {
1718 int i, j, p;
1719 struct bitmap * the_bitmap;
1720
1721 the_bitmap = (struct bitmap*)src;
1722 if (the_bitmap == NULL)
1723 return;
1724 #ifdef QT_OPTI
1725 if (opcode == 0xc) /* optimize */
1726 {
1727 if (WarpCoords(&x, &y, &cx, &cy, &srcx, &srcy))
1728 {
1729 if (g_server_bpp == 8)
1730 {
1731 for (i = 0; i < cy; i++)
1732 for (j = 0; j < cx; j++)
1733 {
1734 p = GETPIXEL8(the_bitmap->data, srcx + j, srcy + i, the_bitmap->w);
1735 SETPIXEL8(g_BS, x + j, y + i, g_width, p);
1736 }
1737 }
1738 else if (g_server_bpp == 16)
1739 {
1740 for (i = 0; i < cy; i++)
1741 for (j = 0; j < cx; j++)
1742 {
1743 p = GETPIXEL16(the_bitmap->data, srcx + j, srcy + i, the_bitmap->w);
1744 SETPIXEL16(g_BS, x + j, y + i, g_width, p);
1745 }
1746 }
1747 else if (g_server_bpp == 24)
1748 {
1749 for (i = 0; i < cy; i++)
1750 for (j = 0; j < cx; j++)
1751 {
1752 p = GETPIXEL32(the_bitmap->data, srcx + j, srcy + i, the_bitmap->w);
1753 SETPIXEL32(g_BS, x + j, y + i, g_width, p);
1754 }
1755 }
1756 }
1757 }
1758 else
1759 #endif
1760 {
1761 if (g_server_bpp == 8)
1762 {
1763 for (i = 0; i < cy; i++)
1764 for (j = 0; j < cx; j++)
1765 if ((i + srcy) < the_bitmap->h && (j + srcx) < the_bitmap->w)
1766 set_pixel(x + j, y + i,
1767 the_bitmap->data[(i + srcy) * the_bitmap->w + (j + srcx)],
1768 opcode);
1769 }
1770 else if (g_server_bpp == 16)
1771 {
1772 for (i = 0; i < cy; i++)
1773 for (j = 0; j < cx; j++)
1774 if ((i + srcy) < the_bitmap->h && (j + srcx) < the_bitmap->w)
1775 set_pixel(x + j, y + i,
1776 *(((uint16*)the_bitmap->data) + ((i + srcy) * the_bitmap->w + (j + srcx))),
1777 opcode);
1778 }
1779 else if (g_server_bpp == 24)
1780 {
1781 for (i = 0; i < cy; i++)
1782 for (j = 0; j < cx; j++)
1783 if ((i + srcy) < the_bitmap->h && (j + srcx) < the_bitmap->w)
1784 set_pixel(x + j, y + i,
1785 *(((uint32*)the_bitmap->data) + ((i + srcy) * the_bitmap->w + (j + srcx))),
1786 opcode);
1787 }
1788 }
1789 redraw(x, y, cx, cy);
1790 }
1791
1792 /******************************************************************************/
1793 // not used
1794 void ui_triblt(uint8 opcode, int x, int y, int cx, int cy,
1795 HBITMAP src, int srcx, int srcy, BRUSH * brush,
1796 int bgcolour, int fgcolour)
1797 {
1798 }
1799
1800 /******************************************************************************/
1801 /* Bresenham's line drawing algorithm */
1802 void ui_line(uint8 opcode, int startx, int starty, int endx,
1803 int endy, PEN * pen)
1804 {
1805 int dx, dy, incx, incy, dpr, dpru, p, left, top, right, bottom;
1806
1807 if (startx > endx)
1808 {
1809 dx = startx - endx;
1810 incx = -1;
1811 left = endx;
1812 right = startx;
1813 }
1814 else
1815 {
1816 dx = endx - startx;
1817 incx = 1;
1818 left = startx;
1819 right = endx;
1820 }
1821 if (starty > endy)
1822 {
1823 dy = starty - endy;
1824 incy = -1;
1825 top = endy;
1826 bottom = starty;
1827 }
1828 else
1829 {
1830 dy = endy - starty;
1831 incy = 1;
1832 top = starty;
1833 bottom = endy;
1834 }
1835 if (dx >= dy)
1836 {
1837 dpr = dy << 1;
1838 dpru = dpr - (dx << 1);
1839 p = dpr - dx;
1840 for (; dx >= 0; dx--)
1841 {
1842 set_pixel(startx, starty, pen->colour, opcode);
1843 if (p > 0)
1844 {
1845 startx += incx;
1846 starty += incy;
1847 p += dpru;
1848 }
1849 else
1850 {
1851 startx += incx;
1852 p += dpr;
1853 }
1854 }
1855 }
1856 else
1857 {
1858 dpr = dx << 1;
1859 dpru = dpr - (dy << 1);
1860 p = dpr - dy;
1861 for (; dy >= 0; dy--)
1862 {
1863 set_pixel(startx, starty, pen->colour, opcode);
1864 if (p > 0)
1865 {
1866 startx += incx;
1867 starty += incy;
1868 p += dpru;
1869 }
1870 else
1871 {
1872 starty += incy;
1873 p += dpr;
1874 }
1875 }
1876 }
1877 redraw(left, top, (right - left) + 1, (bottom - top) + 1);
1878 }
1879
1880 /******************************************************************************/
1881 void draw_glyph (int x, int y, HGLYPH glyph, int fgcolour)
1882 {
1883 struct bitmap *the_glyph;
1884 int i, j;
1885
1886 the_glyph = (struct bitmap*)glyph;
1887 if (the_glyph == NULL)
1888 return;
1889 for (i = 0; i < the_glyph->h; i++)
1890 for (j = 0; j < the_glyph->w; j++)
1891 if (is_pixel_on(the_glyph->data, j, i, the_glyph->w, 8))
1892 set_pixel(x + j, y + i, fgcolour);
1893 }
1894
1895 #define DO_GLYPH(ttext,idx) \
1896 {\
1897 glyph = cache_get_font (font, ttext[idx]);\
1898 if (!(flags & TEXT2_IMPLICIT_X))\
1899 {\
1900 xyoffset = ttext[++idx];\
1901 if ((xyoffset & 0x80))\
1902 {\
1903 if (flags & TEXT2_VERTICAL) \
1904 y += ttext[idx+1] | (ttext[idx+2] << 8);\
1905 else\
1906 x += ttext[idx+1] | (ttext[idx+2] << 8);\
1907 idx += 2;\
1908 }\
1909 else\
1910 {\
1911 if (flags & TEXT2_VERTICAL) \
1912 y += xyoffset;\
1913 else\
1914 x += xyoffset;\
1915 }\
1916 }\
1917 if (glyph != NULL)\
1918 {\
1919 draw_glyph (x + glyph->offset, y + glyph->baseline, glyph->pixmap, fgcolour);\
1920 if (flags & TEXT2_IMPLICIT_X)\
1921 x += glyph->width;\
1922 }\
1923 }
1924
1925 /******************************************************************************/
1926 void ui_draw_text(uint8 font, uint8 flags, int mixmode,
1927 int x, int y, int clipx, int clipy,
1928 int clipcx, int clipcy, int boxx,
1929 int boxy, int boxcx, int boxcy, int bgcolour,
1930 int fgcolour, uint8 * text, uint8 length)
1931 {
1932 FONTGLYPH * glyph;
1933 int i, j, xyoffset;
1934 DATABLOB * entry;
1935
1936 if (boxx + boxcx > g_width)
1937 boxcx = g_width - boxx;
1938 if (boxy + boxcy > g_height)
1939 boxcy = g_height - boxy;
1940
1941 if (boxcx > 1)
1942 fill_rect(boxx, boxy, boxcx, boxcy, bgcolour);
1943 else if (mixmode == MIX_OPAQUE)
1944 fill_rect(clipx, clipy, clipcx, clipcy, bgcolour);
1945
1946 /* Paint text, character by character */
1947 for (i = 0; i < length;)
1948 {
1949 switch (text[i])
1950 {
1951 case 0xff:
1952 if (i + 2 < length)
1953 cache_put_text(text[i + 1], text, text[i + 2]);
1954 else
1955 {
1956 error("this shouldn't be happening\n");
1957 exit(1);
1958 }
1959 /* this will move pointer from start to first character after FF command */
1960 length -= i + 3;
1961 text = &(text[i + 3]);
1962 i = 0;
1963 break;
1964
1965 case 0xfe:
1966 entry = cache_get_text(text[i + 1]);
1967 if (entry != NULL)
1968 {
1969 if ((((uint8 *) (entry->data))[1] == 0) && (!(flags & TEXT2_IMPLICIT_X)))
1970 {
1971 if (flags & TEXT2_VERTICAL)
1972 y += text[i + 2];
1973 else
1974 x += text[i + 2];
1975 }
1976 for (j = 0; j < entry->size; j++)
1977 DO_GLYPH(((uint8 *) (entry->data)), j);
1978 }
1979 if (i + 2 < length)
1980 i += 3;
1981 else
1982 i += 2;
1983 length -= i;
1984 /* this will move pointer from start to first character after FE command */
1985 text = &(text[i]);
1986 i = 0;
1987 break;
1988
1989 default:
1990 DO_GLYPH(text, i);
1991 i++;
1992 break;
1993 }
1994 }
1995 if (boxcx > 1)
1996 redraw(boxx, boxy, boxcx, boxcy);
1997 else
1998 redraw(clipx, clipy, clipcx, clipcy);
1999 }
2000
2001 /******************************************************************************/
2002 void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy)
2003 {
2004 uint8 * data;
2005 int i, j, Bpp, pixel;
2006
2007 Bpp = 4;
2008 switch (g_server_bpp)
2009 {
2010 case 8: Bpp = 1; break;
2011 case 15: Bpp = 2; break;
2012 case 16: Bpp = 2; break;
2013 }
2014 data = (uint8*)xmalloc(cx * cy * Bpp);
2015 if (g_server_bpp == 8)
2016 {
2017 for (i = 0; i < cy; i++)
2018 for (j = 0; j < cx; j++)
2019 {
2020 pixel = get_pixel(x + j, y + i);
2021 SETPIXEL8(data, j, i, cx, pixel);
2022 }
2023 }
2024 else if (g_server_bpp == 16)
2025 {
2026 for (i = 0; i < cy; i++)
2027 for (j = 0; j < cx; j++)
2028 {
2029 pixel = get_pixel(x + j, y + i);
2030 SETPIXEL16(data, j, i, cx, pixel);
2031 }
2032 }
2033 else if (g_server_bpp == 24)
2034 {
2035 for (i = 0; i < cy; i++)
2036 for (j = 0; j < cx; j++)
2037 *(((uint32*)data) + (i * cx + j)) = get_pixel(x + j, y + i);
2038 }
2039 offset *= Bpp;
2040 cache_put_desktop(offset, cx, cy, cx * Bpp, Bpp, data);
2041 xfree(data);
2042 }
2043
2044 /******************************************************************************/
2045 void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy)
2046 {
2047 uint8 * data;
2048 int i, j;
2049 int Bpp;
2050
2051 Bpp = 4;
2052 switch (g_server_bpp)
2053 {
2054 case 8: Bpp = 1; break;
2055 case 15: Bpp = 2; break;
2056 case 16: Bpp = 2; break;
2057 }
2058 offset *= Bpp;
2059 data = cache_get_desktop(offset, cx, cy, Bpp);
2060 if (g_server_bpp == 8)
2061 {
2062 for (i = 0; i < cy; i++)
2063 for (j = 0; j < cx; j++)
2064 set_pixel(x + j, y + i, data[i * cx + j]);
2065 }
2066 else if (g_server_bpp == 16)
2067 {
2068 for (i = 0; i < cy; i++)
2069 for (j = 0; j < cx; j++)
2070 set_pixel(x + j, y + i, *(((uint16*)data) + (i * cx + j)));
2071 }
2072 else if (g_server_bpp == 24)
2073 {
2074 for (i = 0; i < cy; i++)
2075 for (j = 0; j < cx; j++)
2076 set_pixel(x + j, y + i, *(((uint32*)data) + (i * cx + j)));
2077 }
2078 redraw(x, y, cx, cy);
2079 }
2080
2081 /*****************************************************************************/
2082 void* xrealloc(void * in_val, int size)
2083 {
2084 if (size < 1)
2085 size = 1;
2086 return realloc(in_val, size);
2087 }
2088
2089 /*****************************************************************************/
2090 void* xmalloc(int size)
2091 {
2092 return malloc(size);
2093 }
2094
2095 /*****************************************************************************/
2096 void xfree(void * in_val)
2097 {
2098 if (in_val != NULL)
2099 free(in_val);
2100 }
2101
2102 /*****************************************************************************/
2103 void warning(char * format, ...)
2104 {
2105 va_list ap;
2106
2107 fprintf(stderr, "WARNING: ");
2108 va_start(ap, format);
2109 vfprintf(stderr, format, ap);
2110 va_end(ap);
2111 }
2112
2113 /*****************************************************************************/
2114 void unimpl(char * format, ...)
2115 {
2116 va_list ap;
2117
2118 fprintf(stderr, "NOT IMPLEMENTED: ");
2119 va_start(ap, format);
2120 vfprintf(stderr, format, ap);
2121 va_end(ap);
2122 }
2123
2124 /*****************************************************************************/
2125 void error(char * format, ...)
2126 {
2127 va_list ap;
2128
2129 fprintf(stderr, "ERROR: ");
2130 va_start(ap, format);
2131 vfprintf(stderr, format, ap);
2132 va_end(ap);
2133 }
2134
2135 /*****************************************************************************/
2136 BOOL rd_pstcache_mkdir(void)
2137 {
2138 return 0;
2139 }
2140
2141 /*****************************************************************************/
2142 int rd_open_file(char * filename)
2143 {
2144 return 0;
2145 }
2146
2147 /*****************************************************************************/
2148 void rd_close_file(int fd)
2149 {
2150 return;
2151 }
2152
2153 /*****************************************************************************/
2154 int rd_read_file(int fd, void * ptr, int len)
2155 {
2156 return 0;
2157 }
2158
2159 /*****************************************************************************/
2160 int rd_write_file(int fd, void * ptr, int len)
2161 {
2162 return 0;
2163 }
2164
2165 /*****************************************************************************/
2166 int rd_lseek_file(int fd, int offset)
2167 {
2168 return 0;
2169 }
2170
2171 /*****************************************************************************/
2172 BOOL rd_lock_file(int fd, int start, int len)
2173 {
2174 return False;
2175 }
2176
2177 /*****************************************************************************/
2178 int load_licence(uint8 ** data)
2179 {
2180 return 0;
2181 }
2182
2183 /*****************************************************************************/
2184 void save_licence(uint8 * data, int length)
2185 {
2186 }
2187
2188 /*****************************************************************************/
2189 void generate_random(uint8 * random)
2190 {
2191 QFile File("/dev/random");
2192 File.open(IO_ReadOnly);
2193 if (File.readBlock((char*)random, 32) == 32)
2194 return;
2195 warning("no /dev/random\n");
2196 memcpy(random, "12345678901234567890123456789012", 32);
2197 }
2198
2199 /*****************************************************************************/
2200 /* produce a hex dump */
2201 void hexdump(uint8 * p, uint32 len)
2202 {
2203 uint8 * line = p;
2204 int i, thisline;
2205 uint32 offset = 0;
2206
2207 while (offset < len)
2208 {
2209 printf("%04x ", offset);
2210 thisline = len - offset;
2211 if (thisline > 16)
2212 thisline = 16;
2213
2214 for (i = 0; i < thisline; i++)
2215 printf("%02x ", line[i]);
2216
2217 for (; i < 16; i++)
2218 printf(" ");
2219
2220 for (i = 0; i < thisline; i++)
2221 printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
2222
2223 printf("\n");
2224 offset += thisline;
2225 line += thisline;
2226 }
2227 }
2228
2229 /*****************************************************************************/
2230 void get_username_and_hostname(void)
2231 {
2232 char fullhostname[64];
2233 char * p;
2234 struct passwd * pw;
2235
2236 STRNCPY(g_username, "unknown", sizeof(g_username));
2237 STRNCPY(g_hostname, "unknown", sizeof(g_hostname));
2238 pw = getpwuid(getuid());
2239 if (pw != NULL && pw->pw_name != NULL)
2240 {
2241 STRNCPY(g_username, pw->pw_name, sizeof(g_username));
2242 }
2243 if (gethostname(fullhostname, sizeof(fullhostname)) != -1)
2244 {
2245 p = strchr(fullhostname, '.');
2246 if (p != NULL)
2247 *p = 0;
2248 STRNCPY(g_hostname, fullhostname, sizeof(g_hostname));
2249 }
2250 }
2251
2252 /*****************************************************************************/
2253 void out_params(void)
2254 {
2255 fprintf(stderr, "qterdesktop: A Remote Desktop Protocol client.\n");
2256 fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2004 Matt Chapman.\n");
2257 fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
2258 fprintf(stderr, "Usage: qterdesktop [options] server\n");
2259 fprintf(stderr, " -g: desktop geometry (WxH)\n");
2260 fprintf(stderr, " -4: use RDP version 4\n");
2261 fprintf(stderr, " -5: use RDP version 5 (default)\n");
2262 fprintf(stderr, " -t: tcp port)\n");
2263 fprintf(stderr, " -a: connection colour depth\n");
2264
2265 fprintf(stderr, " -u: user name\n");
2266 fprintf(stderr, " -d: domain\n");
2267 fprintf(stderr, " -s: shell\n");
2268 fprintf(stderr, " -c: working directory\n");
2269 fprintf(stderr, " -p: password (- to prompt)\n");
2270 fprintf(stderr, " -n: client hostname\n");
2271 fprintf(stderr, " -f: full screen\n");
2272
2273 fprintf(stderr, "\n");
2274 }
2275
2276 /*****************************************************************************/
2277 int parse_parameters(int in_argc, char ** in_argv)
2278 {
2279 int i;
2280 char * p;
2281
2282 for (i = 1; i < in_argc; i++)
2283 {
2284 strcpy(g_server, in_argv[i]);
2285 if (strcmp(in_argv[i], "-h") == 0)
2286 {
2287 out_params();
2288 return 0;
2289 }
2290 else if (strcmp(in_argv[i], "-g") == 0)
2291 {
2292 g_width = strtol(in_argv[i + 1], &p, 10);
2293 if (*p == 'x')
2294 g_height = strtol(p + 1, &p, 10);
2295 if (*p == '-')
2296 g_client_width = strtol(p + 1, &p, 10);
2297 else
2298 {
2299 g_client_width = g_width;
2300 g_client_height = g_height;
2301 }
2302 if (*p == 'x')
2303 g_client_height = strtol(p + 1, NULL, 10);
2304 g_width = (g_width + 3) & ~3;
2305 g_height = (g_height + 3) & ~3;
2306 g_client_width = (g_client_width + 3) & ~3;
2307 g_client_height = (g_client_height + 3) & ~3;
2308 //printf("%d %d %d %d\n", g_width, g_height, g_client_width, g_client_height);
2309 }
2310 else if (strcmp(in_argv[i], "-4") == 0)
2311 g_use_rdp5 = 0;
2312 else if (strcmp(in_argv[i], "-5") == 0)
2313 g_use_rdp5 = 1;
2314 else if (strcmp(in_argv[i], "-a") == 0)
2315 {
2316 g_server_bpp = strtol(in_argv[i + 1], &p, 10);
2317 if (g_server_bpp != 8 &&
2318 g_server_bpp != 16 && g_server_bpp != 24)
2319 {
2320 error("invalid bpp\n");
2321 return 0;
2322 }
2323 }
2324 else if (strcmp(in_argv[i], "-t") == 0)
2325 g_tcp_port_rdp = strtol(in_argv[i + 1], &p, 10);
2326
2327 else if (strcmp(in_argv[i], "-u") == 0)
2328 {
2329 STRNCPY(g_username, in_argv[i + 1], sizeof(g_username));
2330 }
2331 else if (strcmp(in_argv[i], "-d") == 0)
2332 {
2333 STRNCPY(g_domain, in_argv[i + 1], sizeof(g_domain));
2334 }
2335 else if (strcmp(in_argv[i], "-s") == 0)
2336 {
2337 STRNCPY(g_shell, in_argv[i + 1], sizeof(g_shell));
2338 }
2339 else if (strcmp(in_argv[i], "-c") == 0)
2340 {
2341 STRNCPY(g_directory, in_argv[i + 1], sizeof(g_directory));
2342 }
2343 else if (strcmp(in_argv[i], "-p") == 0)
2344 {
2345 STRNCPY(g_password, in_argv[i + 1], sizeof(g_password));
2346 g_flags |= RDP_LOGON_AUTO;
2347 }
2348 else if (strcmp(in_argv[i], "-n") == 0)
2349 {
2350 STRNCPY(g_hostname, in_argv[i + 1], sizeof(g_hostname));
2351 }
2352 else if (strcmp(in_argv[i], "-f") == 0)
2353 {
2354 g_fullscreen = 1;
2355 }
2356 }
2357 return 1;
2358 }
2359
2360 /******************************************************************************/
2361 int param_connect(void)
2362 {
2363 QWidget * Desktop;
2364 int dw, dh;
2365
2366 #ifdef WITH_RDPSND
2367 rdpsnd_init();
2368 #endif
2369 if (rdp_connect(g_server, g_flags, g_domain, g_password, g_shell,
2370 g_directory))
2371 {
2372 g_BS = (uint8*)xmalloc(g_width * g_height * 4);
2373 memset(g_BS, 0, g_width * g_height * 4);
2374 g_clipx = 0;
2375 g_clipy = 0;
2376 g_clipcx = g_width;
2377 g_clipcy = g_height;
2378 g_CM = (QColorMap*)xmalloc(sizeof(struct QColorMap));
2379 memset(g_CM, 0, sizeof(struct QColorMap));
2380 g_CM->NumColors = 256;
2381 g_MW = new QMyMainWindow();
2382 g_MW->resize(g_client_width, g_client_height);
2383 g_MW->show();
2384 g_SV->addChild(g_MW);
2385 g_MW->setMouseTracking(true);
2386 g_SocketNotifier = new QSocketNotifier(g_global_sock,
2387 QSocketNotifier::Read,
2388 g_MW);
2389 g_MW->connect(g_SocketNotifier, SIGNAL(activated(int)), g_MW,
2390 SLOT(dataReceived()));
2391 if (g_fullscreen)
2392 {
2393 Desktop = g_App->desktop();
2394 dw = Desktop->width();
2395 dh = Desktop->height();
2396 if (dw == g_client_width && dh == g_client_height)
2397 g_MW->resize(g_client_width - 4, g_client_height - 4);
2398 g_SV->showFullScreen();
2399 }
2400 g_MW->setCursor((int)10); /* Qt::BlankCursor */
2401 g_App->exec();
2402 }
2403 return 0;
2404 }
2405
2406 /******************************************************************************/
2407 int main(int argc, char ** argv)
2408 {
2409 #ifdef SHARP
2410 g_App = new QPEApplication(argc, argv);
2411 #else
2412 //g_App = new QApplication(argc, argv, QApplication::GuiServer);
2413 g_App = new QApplication(argc, argv);
2414 #endif
2415 g_SV = new QMyScrollView();
2416 g_App->setMainWidget(g_SV);
2417 g_SV->showMaximized();
2418 if (argc > 1)
2419 {
2420 get_username_and_hostname();
2421 if (parse_parameters(argc, argv))
2422 param_connect();
2423 }
2424 else
2425 {
2426 g_SV->timer_id = g_SV->startTimer(1000); /* one sec delay, then dialog */
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