1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
4 Copyright (C) Jay Sorg 2006
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.
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.
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 extern char g_username
[];
26 extern char g_hostname
[];
27 extern char g_servername
[];
28 extern char g_password
[];
29 extern char g_shell
[];
30 extern char g_directory
[];
31 extern char g_domain
[];
35 extern int g_server_depth
;
36 extern int g_tcp_port_rdp
; /* in tcp.c */
37 extern int pal_entries
[];
39 static HWND g_Wnd
= 0;
40 static HINSTANCE g_Instance
= 0;
41 static HCURSOR g_cursor
= 0;
42 static int g_block
= 0;
43 static int g_xoff
= 0; /* offset from window to client coords */
44 static int g_yoff
= 0;
45 static int g_xscroll
= 0; /* current scroll position */
46 static int g_yscroll
= 0;
47 static int g_screen_width
= 0;
48 static int g_screen_height
= 0;
49 static int g_wnd_cwidth
= 0; /* set from WM_SIZE */
50 static int g_wnd_cheight
= 0;
51 static int g_fullscreen
= 0;
52 static int g_workarea
= 0;
53 static int g_mousex
= 0; /* in client coords */
54 static int g_mousey
= 0;
55 //static int g_width_height_set = 0;
57 static int g_clip_left
= 0;
58 static int g_clip_top
= 0;
59 static int g_clip_right
= 800;
60 static int g_clip_bottom
= 600;
61 static RECT g_wnd_clip
; /* this client area of whats actually visible */
62 /* set from WM_SIZE */
64 /*****************************************************************************/
66 str_to_uni(TCHAR
* sizex
, char * size1
)
72 for (i
= 0; i
< len
; i
++)
79 /*****************************************************************************/
81 uni_to_str(char * sizex
, TCHAR
* size1
)
87 for (i
= 0; i
< len
; i
++)
89 sizex
[i
] = (char)size1
[i
];
94 /*****************************************************************************/
95 /* returns non zero if it processed something */
108 /* see if there really is data */
110 FD_SET((unsigned int)g_tcp_sck
, &rfds
);
111 ZeroMemory(&tm
, sizeof(tm
));
112 count
= select(g_tcp_sck
+ 1, &rfds
, 0, 0, &tm
);
129 /*****************************************************************************/
135 #else /* WITH_DEBUG */
139 str_to_uni(lmsg
, msg
);
140 str_to_uni(ltitle
, "Error");
141 MessageBox(g_Wnd
, lmsg
, ltitle
, MB_OK
);
142 #endif /* WITH_DEBUG */
145 /*****************************************************************************/
147 get_scan_code_from_ascii(int code
)
154 case 0x30: rv
= 0x0b; break; // 0
155 case 0x31: rv
= 0x02; break; // 1
156 case 0x32: rv
= 0x03; break; // 2
157 case 0x33: rv
= 0x04; break; // 3
158 case 0x34: rv
= 0x05; break; // 4
159 case 0x35: rv
= 0x06; break; // 5
160 case 0x36: rv
= 0x07; break; // 6
161 case 0x37: rv
= 0x08; break; // 7
162 case 0x38: rv
= 0x09; break; // 8
163 case 0x39: rv
= 0x0a; break; // 9
165 case 0xbd: rv
= 0x0c; break; // -
166 case 0xbb: rv
= 0x0d; break; // =
167 case 0x08: rv
= 0x0e; break; // backspace
168 case 0x09: rv
= 0x0f; break; // tab
169 case 0xdb: rv
= 0x1b; break; // ]
170 case 0xdd: rv
= 0x1a; break; // [
171 case 0x14: rv
= 0x3a; break; // capslock
172 case 0xba: rv
= 0x27; break; // ;
173 case 0xde: rv
= 0x28; break; // '
174 case 0x10: rv
= 0x2a; break; // shift
175 case 0xbc: rv
= 0x33; break; // ,
176 case 0xbe: rv
= 0x34; break; // .
177 case 0xbf: rv
= 0x35; break; // /
178 case 0x0d: rv
= 0x1c; break; // enter
179 case 0x27: rv
= 0x4d; break; // arrow right
180 case 0x25: rv
= 0x4b; break; // arrow left
181 case 0x26: rv
= 0x48; break; // arrow up
182 case 0x28: rv
= 0x50; break; // arrow down
183 case 0x20: rv
= 0x39; break; // space
184 case 0xdc: rv
= 0x2b; break; // backslash
185 case 0xc0: rv
= 0x29; break; // `
186 case 0x11: rv
= 0x1d; break; // ctl
188 case 0x41: rv
= 0x1e; break; // a
189 case 0x42: rv
= 0x30; break; // b
190 case 0x43: rv
= 0x2e; break; // c
191 case 0x44: rv
= 0x20; break; // d
192 case 0x45: rv
= 0x12; break; // e
193 case 0x46: rv
= 0x21; break; // f
194 case 0x47: rv
= 0x22; break; // g
195 case 0x48: rv
= 0x23; break; // h
196 case 0x49: rv
= 0x17; break; // i
197 case 0x4a: rv
= 0x24; break; // j
198 case 0x4b: rv
= 0x25; break; // k
199 case 0x4c: rv
= 0x26; break; // l
200 case 0x4d: rv
= 0x32; break; // m
201 case 0x4e: rv
= 0x31; break; // n
202 case 0x4f: rv
= 0x18; break; // o
203 case 0x50: rv
= 0x19; break; // p
204 case 0x51: rv
= 0x10; break; // q
205 case 0x52: rv
= 0x13; break; // r
206 case 0x53: rv
= 0x1f; break; // s
207 case 0x54: rv
= 0x14; break; // t
208 case 0x55: rv
= 0x16; break; // u
209 case 0x56: rv
= 0x2f; break; // v
210 case 0x57: rv
= 0x11; break; // w
211 case 0x58: rv
= 0x2d; break; // x
212 case 0x59: rv
= 0x15; break; // y
213 case 0x5a: rv
= 0x2c; break; // z
218 /*****************************************************************************/
220 mi_scroll(int dx
, int dy
)
224 rgn
= CreateRectRgn(0, 0, 0, 0);
225 ScrollWindowEx(g_Wnd
, dx
, dy
, 0, 0, rgn
, 0, SW_ERASE
);
226 InvalidateRgn(g_Wnd
, rgn
, 0);
230 /*****************************************************************************/
232 mi_read_keyboard_state(void)
238 keydata
= GetKeyState(VK_SCROLL
);
239 if (keydata
& 0x0001)
243 keydata
= GetKeyState(VK_NUMLOCK
);
244 if (keydata
& 0x0001)
248 keydata
= GetKeyState(VK_CAPITAL
);
249 if (keydata
& 0x0001)
256 /*****************************************************************************/
258 mi_check_modifier(void)
262 code
= mi_read_keyboard_state();
263 ui_set_modifier_state(code
);
266 /*****************************************************************************/
268 handle_WM_SETCURSOR(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
270 if (g_mousex
>= g_wnd_clip
.left
&&
271 g_mousey
>= g_wnd_clip
.top
&&
272 g_mousex
< g_wnd_clip
.right
&&
273 g_mousey
< g_wnd_clip
.bottom
)
277 /* need default behavoir here */
278 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
281 /*****************************************************************************/
283 handle_WM_NCHITTEST(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
287 pt
.x
= LOWORD(lParam
);
288 pt
.y
= HIWORD(lParam
);
289 if (ScreenToClient(g_Wnd
, &pt
))
294 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
297 /*****************************************************************************/
299 handle_WM_MOUSEMOVE(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
301 g_mousex
= LOWORD(lParam
);
302 g_mousey
= HIWORD(lParam
);
303 ui_mouse_move(g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
);
307 /*****************************************************************************/
309 handle_WM_LBUTTONDOWN(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
311 g_mousex
= LOWORD(lParam
);
312 g_mousey
= HIWORD(lParam
);
313 ui_mouse_button(1, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 1);
317 /*****************************************************************************/
319 handle_WM_LBUTTONUP(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
321 g_mousex
= LOWORD(lParam
);
322 g_mousey
= HIWORD(lParam
);
323 ui_mouse_button(1, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 0);
327 /*****************************************************************************/
329 handle_WM_RBUTTONDOWN(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
331 g_mousex
= LOWORD(lParam
);
332 g_mousey
= HIWORD(lParam
);
333 ui_mouse_button(2, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 1);
337 /*****************************************************************************/
339 handle_WM_RBUTTONUP(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
341 g_mousex
= LOWORD(lParam
);
342 g_mousey
= HIWORD(lParam
);
343 ui_mouse_button(2, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 0);
347 /*****************************************************************************/
349 handle_WM_MBUTTONDOWN(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
351 g_mousex
= LOWORD(lParam
);
352 g_mousey
= HIWORD(lParam
);
353 ui_mouse_button(3, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 1);
357 /*****************************************************************************/
359 handle_WM_MBUTTONUP(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
361 g_mousex
= LOWORD(lParam
);
362 g_mousey
= HIWORD(lParam
);
363 ui_mouse_button(3, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 0);
367 /*****************************************************************************/
369 handle_WM_MOUSEWHEEL(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
373 delta
= ((signed short)HIWORD(wParam
)); /* GET_WHEEL_DELTA_WPARAM(wParam); */
376 ui_mouse_button(4, 0, 0, 1);
377 ui_mouse_button(4, 0, 0, 0);
381 ui_mouse_button(5, 0, 0, 1);
382 ui_mouse_button(5, 0, 0, 0);
387 /*****************************************************************************/
389 handle_WM_KEY(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
395 ext
= HIWORD(lParam
);
397 down
= !(ext
& 0x8000);
401 scancode
= get_scan_code_from_ascii(wParam
);
404 if (scancode
== 0x0045) /* num lock */
410 ui_key_down(scancode
, ext
);
414 ui_key_up(scancode
, ext
);
419 /*****************************************************************************/
421 handle_WM_PAINT(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
427 BeginPaint(hWnd
, &ps
);
428 /* paint the area outside the rdp screen with one colour */
430 rect
.left
= UI_MAX(rect
.left
, g_width
);
431 if (!IsRectEmpty(&rect
))
433 brush
= CreateSolidBrush(RGB(0, 0, 255));
434 FillRect(ps
.hdc
, &rect
, brush
);
438 rect
.top
= UI_MAX(rect
.top
, g_height
);
439 if (!IsRectEmpty(&rect
))
441 brush
= CreateSolidBrush(RGB(0, 0, 255));
442 FillRect(ps
.hdc
, &rect
, brush
);
447 ui_invalidate(rect
.left
+ g_xscroll
,
448 rect
.top
+ g_yscroll
,
449 (rect
.right
- rect
.left
) + 1,
450 (rect
.bottom
- rect
.top
) + 1);
454 /*****************************************************************************/
456 handle_WM_SIZE(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
461 if (wParam
== SIZE_MINIMIZED
)
463 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
465 g_wnd_cwidth
= LOWORD(lParam
); /* client width / height */
466 g_wnd_cheight
= HIWORD(lParam
);
469 g_wnd_clip
.right
= g_wnd_clip
.left
+ g_wnd_cwidth
;
470 g_wnd_clip
.bottom
= g_wnd_clip
.top
+ g_wnd_cheight
;
471 if (g_wnd_cwidth
< g_width
|| g_wnd_cheight
< g_height
)
473 SetScrollRange(g_Wnd
, SB_HORZ
, 0, g_width
- g_wnd_cwidth
, 1);
474 SetScrollRange(g_Wnd
, SB_VERT
, 0, g_height
- g_wnd_cheight
, 1);
476 oldxscroll
= g_xscroll
;
477 oldyscroll
= g_yscroll
;
478 if (g_wnd_cwidth
>= g_width
)
484 g_xscroll
= UI_MIN(g_xscroll
, g_width
- g_wnd_cwidth
);
486 if (g_wnd_cheight
>= g_height
)
492 g_yscroll
= UI_MIN(g_yscroll
, g_height
- g_wnd_cheight
);
494 mi_scroll(oldxscroll
- g_xscroll
, oldyscroll
- g_yscroll
);
495 if (wParam
== SIZE_RESTORED
|| wParam
== SIZE_MAXIMIZED
)
497 /* check the caps, num, and scroll lock here */
503 /*****************************************************************************/
505 handle_WM_SIZING(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
512 prect
= (LPRECT
) lParam
; /* total window rect */
513 width
= (prect
->right
- prect
->left
) - (g_xoff
* 2);
514 height
= (prect
->bottom
- prect
->top
) - (g_yoff
+ g_xoff
);
515 if (height
< g_height
|| width
< g_width
)
517 style
= GetWindowLongPtr(g_Wnd
, GWL_STYLE
);
518 if (!(style
& WS_HSCROLL
))
520 style
|= WS_HSCROLL
| WS_VSCROLL
;
521 SetWindowLongPtr(g_Wnd
, GWL_STYLE
, style
);
524 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
525 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
528 else if (height
>= g_height
&& width
>= g_width
)
530 style
= GetWindowLongPtr(g_Wnd
, GWL_STYLE
);
531 if (style
& WS_HSCROLL
)
533 style
&= ~WS_HSCROLL
;
534 style
&= ~WS_VSCROLL
;
535 SetWindowLongPtr(g_Wnd
, GWL_STYLE
, style
);
543 /*****************************************************************************/
545 handle_WM_HSCROLL(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
550 code
= (int) LOWORD(wParam
); /* scroll bar value */
551 if (code
== SB_LINELEFT
)
553 oldxscroll
= g_xscroll
;
555 g_xscroll
= UI_MAX(g_xscroll
, 0);
556 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
557 mi_scroll(oldxscroll
- g_xscroll
, 0);
559 else if (code
== SB_LINERIGHT
)
561 oldxscroll
= g_xscroll
;
563 g_xscroll
= UI_MIN(g_xscroll
, g_width
- g_wnd_cwidth
);
564 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
565 mi_scroll(oldxscroll
- g_xscroll
, 0);
567 else if (code
== SB_PAGELEFT
)
569 oldxscroll
= g_xscroll
;
570 g_xscroll
-= g_wnd_cwidth
/ 2;
571 g_xscroll
= UI_MAX(g_xscroll
, 0);
572 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
573 mi_scroll(oldxscroll
- g_xscroll
, 0);
575 else if (code
== SB_PAGERIGHT
)
577 oldxscroll
= g_xscroll
;
578 g_xscroll
+= g_wnd_cwidth
/ 2;
579 g_xscroll
= UI_MIN(g_xscroll
, g_width
- g_wnd_cwidth
);
580 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
581 mi_scroll(oldxscroll
- g_xscroll
, 0);
583 else if (code
== SB_BOTTOM
)
585 oldxscroll
= g_xscroll
;
586 g_xscroll
= g_width
- g_wnd_cwidth
;
587 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
588 mi_scroll(oldxscroll
- g_xscroll
, 0);
590 else if (code
== SB_TOP
)
592 oldxscroll
= g_xscroll
;
594 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
595 mi_scroll(oldxscroll
- g_xscroll
, 0);
597 else if (code
== SB_THUMBPOSITION
)
599 oldxscroll
= g_xscroll
;
600 g_xscroll
= (signed short) HIWORD(wParam
);
601 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
602 mi_scroll(oldxscroll
- g_xscroll
, 0);
607 /*****************************************************************************/
609 handle_WM_VSCROLL(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
614 code
= (int) LOWORD(wParam
); /* scroll bar value */
615 if (code
== SB_LINELEFT
)
617 oldyscroll
= g_yscroll
;
619 g_yscroll
= UI_MAX(g_yscroll
, 0);
620 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
621 mi_scroll(0, oldyscroll
- g_yscroll
);
623 else if (code
== SB_LINERIGHT
)
625 oldyscroll
= g_yscroll
;
627 g_yscroll
= UI_MIN(g_yscroll
, g_height
- g_wnd_cheight
);
628 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
629 mi_scroll(0, oldyscroll
- g_yscroll
);
631 else if (code
== SB_PAGELEFT
)
633 oldyscroll
= g_yscroll
;
634 g_yscroll
-= g_wnd_cheight
/ 2;
635 g_yscroll
= UI_MAX(g_yscroll
, 0);
636 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
637 mi_scroll(0, oldyscroll
- g_yscroll
);
639 else if (code
== SB_PAGERIGHT
)
641 oldyscroll
= g_yscroll
;
642 g_yscroll
+= g_wnd_cheight
/ 2;
643 g_yscroll
= UI_MIN(g_yscroll
, g_height
- g_wnd_cheight
);
644 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
645 mi_scroll(0, oldyscroll
- g_yscroll
);
647 else if (code
== SB_BOTTOM
)
649 oldyscroll
= g_yscroll
;
650 g_yscroll
= g_height
- g_wnd_cheight
;
651 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
652 mi_scroll(0, oldyscroll
- g_yscroll
);
654 else if (code
== SB_TOP
)
656 oldyscroll
= g_yscroll
;
658 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
659 mi_scroll(0, oldyscroll
- g_yscroll
);
661 else if (code
== SB_THUMBPOSITION
)
663 oldyscroll
= g_yscroll
;
664 g_yscroll
= (signed short) HIWORD(wParam
);
665 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
666 mi_scroll(0, oldyscroll
- g_yscroll
);
672 /*****************************************************************************/
674 WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
679 return handle_WM_SETCURSOR(hWnd
, message
, wParam
, lParam
);
680 case 0x0084: /* WinCE don't have this WM_NCHITTEST: */
681 return handle_WM_NCHITTEST(hWnd
, message
, wParam
, lParam
);
683 return handle_WM_MOUSEMOVE(hWnd
, message
, wParam
, lParam
);
685 return handle_WM_LBUTTONDOWN(hWnd
, message
, wParam
, lParam
);
687 return handle_WM_LBUTTONUP(hWnd
, message
, wParam
, lParam
);
689 return handle_WM_RBUTTONDOWN(hWnd
, message
, wParam
, lParam
);
691 return handle_WM_RBUTTONUP(hWnd
, message
, wParam
, lParam
);
693 return handle_WM_MBUTTONDOWN(hWnd
, message
, wParam
, lParam
);
695 return handle_WM_MBUTTONUP(hWnd
, message
, wParam
, lParam
);
696 /* some windows compilers don't have these defined like vc6 */
697 case 0x020a: /* WM_MOUSEWHEEL: */
698 return handle_WM_MOUSEWHEEL(hWnd
, message
, wParam
, lParam
);
703 return handle_WM_KEY(hWnd
, message
, wParam
, lParam
);
710 return handle_WM_PAINT(hWnd
, message
, wParam
, lParam
);
719 return handle_WM_SIZE(hWnd
, message
, wParam
, lParam
);
720 case 532: /* not defined in wince WM_SIZING: */
721 return handle_WM_SIZING(hWnd
, message
, wParam
, lParam
);
723 return handle_WM_HSCROLL(hWnd
, message
, wParam
, lParam
);
725 return handle_WM_VSCROLL(hWnd
, message
, wParam
, lParam
);
728 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
730 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
735 /*****************************************************************************/
741 rgn
= CreateRectRgn(g_clip_left
+ g_xoff
- g_xscroll
,
742 g_clip_top
+ g_yoff
- g_yscroll
,
743 g_clip_right
+ g_xoff
- g_xscroll
,
744 g_clip_bottom
+ g_yoff
- g_yscroll
);
745 SelectClipRgn(dc
, rgn
);
746 IntersectClipRect(dc
, g_wnd_clip
.left
+ g_xoff
, g_wnd_clip
.top
+ g_yoff
,
747 g_wnd_clip
.right
+ g_xoff
, g_wnd_clip
.bottom
+ g_yoff
);
751 /*****************************************************************************/
752 /* returns non zero if ok */
754 mi_create_window(void)
758 TCHAR classname
[512];
766 if (g_Wnd
!= 0 || g_Instance
!= 0)
770 g_Instance
= GetModuleHandle(NULL
);
771 ZeroMemory(&wc
, sizeof(wc
));
772 wc
.lpfnWndProc
= WndProc
; /* points to window procedure */
773 /* name of window class */
774 str_to_uni(classname
, "rdesktop");
775 wc
.lpszClassName
= classname
;
776 str_to_uni(caption
, "ReactOS Remote Desktop");
777 wc
.hIcon
= LoadIcon(g_Instance
,
778 MAKEINTRESOURCE(IDI_MSTSC
));
779 /* Register the window class. */
780 if (!RegisterClass(&wc
))
782 return 0; /* Failed to register window class */
785 rc
.right
= rc
.left
+ UI_MIN(g_width
, g_screen_width
);
787 rc
.bottom
= rc
.top
+ UI_MIN(g_height
, g_screen_height
);
795 style
= WS_OVERLAPPED
| WS_CAPTION
| WS_POPUP
| WS_MINIMIZEBOX
|
796 WS_SYSMENU
| WS_SIZEBOX
| WS_MAXIMIZEBOX
;
798 if (g_screen_width
< g_width
|| g_screen_height
< g_height
)
800 style
|= WS_HSCROLL
| WS_VSCROLL
;
802 AdjustWindowRectEx(&rc
, style
, 0, 0);
805 w
= rc
.right
- rc
.left
;
806 h
= rc
.bottom
- rc
.top
;
808 g_Wnd
= CreateWindow(wc
.lpszClassName
, caption
,
810 (HWND
) NULL
, (HMENU
) NULL
, g_Instance
,
814 g_clip_right
= g_clip_left
+ g_width
;
815 g_clip_bottom
= g_clip_top
+ g_height
;
818 ShowWindow(g_Wnd
, SW_SHOWMAXIMIZED
);
822 ShowWindow(g_Wnd
, SW_SHOWNORMAL
);
826 WSAAsyncSelect(g_tcp_sck
, g_Wnd
, WM_APP
+ 1, FD_READ
);
827 SetTimer(g_Wnd
, 1, 333, 0);
832 /*****************************************************************************/
838 while (GetMessage(&msg
, NULL
, 0, 0))
840 TranslateMessage(&msg
);
841 DispatchMessage(&msg
);
846 /*****************************************************************************/
848 mi_warning(char * msg
)
852 /*****************************************************************************/
854 mi_show_error(char * caption
)
859 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
860 NULL
, GetLastError(), MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
861 (LPTSTR
) &lpMsgBuf
, 0, NULL
);
864 #else /* WITH_DEBUG */
865 str_to_uni(lcaption
, caption
);
866 MessageBox(g_Wnd
, (LPTSTR
) lpMsgBuf
, lcaption
,
867 MB_OK
| MB_ICONINFORMATION
);
868 #endif /* WITH_DEBUG */
872 /*****************************************************************************/
874 mi_paint_rect(char * data
, int width
, int height
, int x
, int y
, int cx
, int cy
)
891 ZeroMemory(&bi
, sizeof(bi
));
892 bi
.bmiHeader
.biSize
= sizeof(bi
.bmiHeader
);
893 bi
.bmiHeader
.biWidth
= width
;
894 bi
.bmiHeader
.biHeight
= -height
;
895 bi
.bmiHeader
.biPlanes
= 1;
896 bi
.bmiHeader
.biBitCount
= 32;
897 bi
.bmiHeader
.biCompression
= BI_RGB
;
898 maindc
= GetWindowDC(g_Wnd
);
899 bitmap
= CreateDIBSection(maindc
, &bi
, DIB_RGB_COLORS
, (void **) &bits
, 0, 0);
902 mi_show_error("CreateDIBSection failed");
905 if (g_server_depth
== 8)
907 for (i
= cy
- 1; i
>= 0; i
--)
909 for (j
= cx
- 1; j
>= 0; j
--)
911 colour
= ((unsigned char*)data
)[i
* cx
+ j
];
912 red
= (pal_entries
[colour
& 0xff] & 0xff0000) >> 16;
913 green
= (pal_entries
[colour
& 0xff] & 0xff00) >> 8;
914 blue
= pal_entries
[colour
& 0xff] & 0xff;
915 MAKE_COLOUR32(colour
, red
, green
, blue
);
916 ((unsigned int*)bits
)[i
* cx
+ j
] = colour
;
920 else if (g_server_depth
== 15)
922 for (i
= cy
- 1; i
>= 0; i
--)
924 for (j
= cx
- 1; j
>= 0; j
--)
926 colour
= ((unsigned short*)data
)[i
* cx
+ j
];
927 SPLIT_COLOUR15(colour
, red
, green
, blue
);
928 MAKE_COLOUR32(colour
, red
, green
, blue
);
929 ((unsigned int*)bits
)[i
* cx
+ j
] = colour
;
933 else if (g_server_depth
== 16)
935 for (i
= cy
- 1; i
>= 0; i
--)
937 for (j
= cx
- 1; j
>= 0; j
--)
939 colour
= ((unsigned short*)data
)[i
* cx
+ j
];
940 SPLIT_COLOUR16(colour
, red
, green
, blue
);
941 MAKE_COLOUR32(colour
, red
, green
, blue
);
942 ((unsigned int*)bits
)[i
* cx
+ j
] = colour
;
946 else if (g_server_depth
== 24)
948 for (i
= cy
- 1; i
>= 0; i
--)
950 for (j
= cx
- 1; j
>= 0; j
--)
952 index
= (i
* cx
+ j
) * 3;
953 red
= ((unsigned char*)data
)[index
+ 2];
954 green
= ((unsigned char*)data
)[index
+ 1];
955 blue
= ((unsigned char*)data
)[index
];
956 MAKE_COLOUR32(colour
, red
, green
, blue
);
957 ((unsigned int*)bits
)[i
* cx
+ j
] = colour
;
961 else if (g_server_depth
== 32)
963 memcpy(bits
, data
, cx
*cy
*4);
965 dc
= CreateCompatibleDC(maindc
);
968 mi_show_error("CreateCompatibleDC failed");
970 save
= SelectObject(dc
, bitmap
);
971 rgn
= mi_clip(maindc
);
972 BitBlt(maindc
, x
+ g_xoff
- g_xscroll
, y
+ g_yoff
- g_yscroll
, cx
, cy
, dc
,
974 SelectObject(dc
, save
);
975 DeleteObject(bitmap
);
977 ReleaseDC(g_Wnd
, maindc
);
983 GetPortNumber(PCHAR szAddress
)
986 INT iPort
= TCP_PORT_RDP
;
988 szPort
= strtok(szAddress
, ":");
992 szPort
= strtok(NULL
, ":");
996 iPort
= atoi(szPort
);
998 if (iPort
<= 0 || iPort
> 0xFFFF)
999 iPort
= TCP_PORT_RDP
;
1007 SetDomainAndUsername(PCHAR pName
)
1012 strcpy(g_domain
, "");
1013 strcpy(g_username
, "");
1015 pDomain
= strtok(pName
, "\\");
1020 pUsername
= strtok(NULL
, "\\");
1022 if(pUsername
== NULL
)
1024 strcpy(g_username
, pDomain
);
1028 strcpy(g_username
, pUsername
);
1029 strcpy(g_domain
, pDomain
);
1034 ParseCommandLine(LPWSTR lpCmdLine
,
1035 PRDPSETTINGS pRdpSettings
,
1038 LPWSTR lpStr
= lpCmdLine
;
1039 WCHAR szSeps
[] = L
"/";
1045 if (*lpCmdLine
!= L
'/')
1047 LoadRdpSettingsFromFile(pRdpSettings
, lpCmdLine
);
1051 /* default to screen size, 16bpp */
1052 SetIntegerToSettings(pRdpSettings
, L
"session bpp", 16);
1053 SetIntegerToSettings(pRdpSettings
, L
"desktopwidth", GetSystemMetrics(SM_CXSCREEN
));
1054 SetIntegerToSettings(pRdpSettings
, L
"desktopheight", GetSystemMetrics(SM_CYSCREEN
));
1056 lpToken
= wcstok(lpStr
, szSeps
);
1059 if (wcsncmp(lpToken
, L
"edit", 4) == 0)
1062 LoadRdpSettingsFromFile(pRdpSettings
, lpToken
);
1067 if (*lpToken
== L
'v')
1070 SetStringToSettings(pRdpSettings
, L
"full address", lpToken
);
1072 else if (*lpToken
== L
'w')
1075 SetIntegerToSettings(pRdpSettings
, L
"desktopwidth", _wtoi(lpToken
));
1077 else if (*lpToken
== L
'h')
1080 SetIntegerToSettings(pRdpSettings
, L
"desktopheight", _wtoi(lpToken
));
1082 else if (*lpToken
== L
'f')
1084 SetIntegerToSettings(pRdpSettings
, L
"screen mode id", 2);
1087 lpToken
= wcstok(NULL
, szSeps
);
1094 /*****************************************************************************/
1096 wWinMain(HINSTANCE hInstance
,
1097 HINSTANCE hPrevInstance
,
1101 PRDPSETTINGS pRdpSettings
;
1105 if (WSAStartup(MAKEWORD(2, 0), &d
) == 0)
1107 pRdpSettings
= HeapAlloc(GetProcessHeap(),
1109 sizeof(RDPSETTINGS
));
1112 pRdpSettings
->pSettings
= NULL
;
1113 pRdpSettings
->NumSettings
= 0;
1115 if (InitRdpSettings(pRdpSettings
))
1117 BOOL bSkipDlg
= FALSE
;
1120 ParseCommandLine(lpCmdLine
, pRdpSettings
,&bSkipDlg
);
1122 LoadRdpSettingsFromFile(pRdpSettings
, NULL
);
1124 if (bSkipDlg
|| OpenRDPConnectDialog(hInstance
,
1127 char szValue
[MAXVALUE
];
1129 uni_to_str(szValue
, GetStringFromSettings(pRdpSettings
, L
"full address"));
1131 /* GetPortNumber also removes possible trailing port number from address */
1132 g_tcp_port_rdp
= GetPortNumber(szValue
);
1133 strcpy(g_servername
, szValue
);
1134 uni_to_str(szValue
, GetStringFromSettings(pRdpSettings
, L
"username"));
1135 SetDomainAndUsername(szValue
);
1136 strcpy(g_password
, "");
1137 strcpy(g_hostname
, tcp_get_address());
1138 g_server_depth
= GetIntegerFromSettings(pRdpSettings
, L
"session bpp");
1139 g_screen_width
= GetSystemMetrics(SM_CXSCREEN
);
1140 g_screen_height
= GetSystemMetrics(SM_CYSCREEN
);
1141 g_width
= GetIntegerFromSettings(pRdpSettings
, L
"desktopwidth");
1142 g_height
= GetIntegerFromSettings(pRdpSettings
, L
"desktopheight");
1143 if (GetIntegerFromSettings(pRdpSettings
, L
"screen mode id") == 2)
1151 g_xoff
= GetSystemMetrics(SM_CXEDGE
) * 2;
1152 g_yoff
= GetSystemMetrics(SM_CYCAPTION
) + GetSystemMetrics(SM_CYEDGE
) * 2;
1159 HeapFree(GetProcessHeap(),
1161 pRdpSettings
->pSettings
);
1164 HeapFree(GetProcessHeap(),
1176 /*****************************************************************************/
1178 mi_begin_update(void)
1182 /*****************************************************************************/
1188 /*****************************************************************************/
1190 mi_fill_rect(int x
, int y
, int cx
, int cy
, int colour
)
1200 if (g_server_depth
== 8)
1202 red
= (pal_entries
[colour
& 0xff] & 0xff0000) >> 16;
1203 green
= (pal_entries
[colour
& 0xff] & 0xff00) >> 8;
1204 blue
= pal_entries
[colour
& 0xff] & 0xff;
1206 else if (g_server_depth
== 15)
1208 SPLIT_COLOUR15(colour
, red
, green
, blue
);
1210 else if (g_server_depth
== 16)
1212 SPLIT_COLOUR16(colour
, red
, green
, blue
);
1214 else if (g_server_depth
== 24 || g_server_depth
== 32)
1216 red
= (colour
>>16)&0xff;
1217 green
= (colour
>>8)&0xff;
1220 maindc
= GetWindowDC(g_Wnd
);
1221 rgn
= mi_clip(maindc
);
1222 brush
= CreateSolidBrush(RGB(red
, green
, blue
));
1223 rect
.left
= x
+ g_xoff
- g_xscroll
;
1224 rect
.top
= y
+ g_yoff
- g_yscroll
;
1225 rect
.right
= rect
.left
+ cx
;
1226 rect
.bottom
= rect
.top
+ cy
;
1227 FillRect(maindc
, &rect
, brush
);
1228 DeleteObject(brush
);
1229 ReleaseDC(g_Wnd
, maindc
);
1233 /*****************************************************************************/
1235 mi_line(int x1
, int y1
, int x2
, int y2
, int colour
)
1245 if (g_server_depth
== 8)
1247 red
= (pal_entries
[colour
& 0xff] & 0xff0000) >> 16;
1248 green
= (pal_entries
[colour
& 0xff] & 0xff00) >> 8;
1249 blue
= pal_entries
[colour
& 0xff] & 0xff;
1251 else if (g_server_depth
== 15)
1253 SPLIT_COLOUR15(colour
, red
, green
, blue
);
1255 else if (g_server_depth
== 16)
1257 SPLIT_COLOUR16(colour
, red
, green
, blue
);
1259 else if (g_server_depth
== 24 || g_server_depth
== 32)
1261 red
= (colour
>>16)&0xff;
1262 green
= (colour
>>8)&0xff;
1265 maindc
= GetWindowDC(g_Wnd
);
1266 rgn
= mi_clip(maindc
);
1267 pen
= CreatePen(PS_SOLID
, 0, RGB(red
, green
, blue
));
1268 save
= SelectObject(maindc
, pen
);
1269 MoveToEx(maindc
, x1
+ g_xoff
- g_xscroll
, y1
+ g_yoff
- g_yscroll
, 0);
1270 LineTo(maindc
, x2
+ g_xoff
- g_xscroll
, y2
+ g_yoff
- g_yscroll
);
1271 SelectObject(maindc
, save
);
1273 ReleaseDC(g_Wnd
, maindc
);
1277 /*****************************************************************************/
1279 mi_screen_copy(int x
, int y
, int cx
, int cy
, int srcx
, int srcy
)
1285 int ok_to_ScrollWindowEx
;
1287 ok_to_ScrollWindowEx
= 1;
1289 if (!ok_to_ScrollWindowEx
)
1291 rgn
= CreateRectRgn(x
- g_xscroll
, y
- g_yscroll
,
1292 (x
- g_xscroll
) + cx
,
1293 (y
- g_yscroll
) + cy
);
1294 InvalidateRgn(g_Wnd
, rgn
, 0);
1299 /* this is all in client coords */
1300 rect
.left
= srcx
- g_xscroll
;
1301 rect
.top
= srcy
- g_yscroll
;
1302 rect
.right
= rect
.left
+ cx
;
1303 rect
.bottom
= rect
.top
+ cy
;
1304 clip_rect
.left
= g_clip_left
- g_xscroll
;
1305 clip_rect
.top
= g_clip_top
- g_yscroll
;
1306 clip_rect
.right
= g_clip_right
- g_xscroll
;
1307 clip_rect
.bottom
= g_clip_bottom
- g_yscroll
;
1308 if (IntersectRect(&draw_rect
, &clip_rect
, &g_wnd_clip
))
1310 rgn
= CreateRectRgn(0, 0, 0, 0);
1311 ScrollWindowEx(g_Wnd
, x
- srcx
, y
- srcy
, &rect
, &draw_rect
,
1313 InvalidateRgn(g_Wnd
, rgn
, 0);
1319 /*****************************************************************************/
1321 mi_set_clip(int x
, int y
, int cx
, int cy
)
1325 g_clip_right
= g_clip_left
+ cx
;
1326 g_clip_bottom
= g_clip_top
+ cy
;
1329 /*****************************************************************************/
1335 g_clip_right
= g_clip_left
+ g_width
;
1336 g_clip_bottom
= g_clip_top
+ g_height
;
1339 /*****************************************************************************/
1341 mi_create_cursor(unsigned int x
, unsigned int y
,
1342 int width
, int height
,
1343 unsigned char * andmask
, unsigned char * xormask
)
1347 hCur
= CreateCursor(g_Instance
, x
, y
, width
, height
, andmask
, xormask
);
1350 hCur
= LoadCursor(NULL
, IDC_ARROW
);
1355 /*****************************************************************************/
1357 mi_destroy_cursor(void * cursor
)
1359 if (g_cursor
== cursor
)
1363 DestroyCursor(cursor
);
1366 /*****************************************************************************/
1368 mi_set_cursor(void * cursor
)
1371 SetCursor(g_cursor
);
1374 /*****************************************************************************/
1376 mi_set_null_cursor(void)