/[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

Annotation of /sourceforge.net/trunk/rdesktop/uiports/qtewin.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

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

  ViewVC Help
Powered by ViewVC 1.1.26