PageRenderTime 66ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/uiports/qtewin.cpp

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