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
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <winsock2.h> /* winsock2.h first */
24 //FIXME: remove eventually
31 extern char g_username
[];
32 extern char g_hostname
[];
33 extern char g_servername
[];
34 extern char g_password
[];
35 extern char g_shell
[];
36 extern char g_directory
[];
37 extern char g_domain
[];
41 extern int g_server_depth
;
42 extern int g_tcp_port_rdp
; /* in tcp.c */
43 extern int pal_entries
[];
45 static HWND g_Wnd
= 0;
46 static HINSTANCE g_Instance
= 0;
47 static HCURSOR g_cursor
= 0;
48 static int g_block
= 0;
49 static int g_xoff
= 0; /* offset from window to client coords */
50 static int g_yoff
= 0;
51 static int g_xscroll
= 0; /* current scroll position */
52 static int g_yscroll
= 0;
53 static int g_screen_width
= 0;
54 static int g_screen_height
= 0;
55 static int g_wnd_cwidth
= 0; /* set from WM_SIZE */
56 static int g_wnd_cheight
= 0;
57 static int g_fullscreen
= 0;
58 static int g_workarea
= 0;
59 static int g_mousex
= 0; /* in client coords */
60 static int g_mousey
= 0;
61 //static int g_width_height_set = 0;
63 static int g_clip_left
= 0;
64 static int g_clip_top
= 0;
65 static int g_clip_right
= 800;
66 static int g_clip_bottom
= 600;
67 static RECT g_wnd_clip
; /* this client area of whats actually visable */
68 /* set from WM_SIZE */
70 /*****************************************************************************/
72 str_to_uni(TCHAR
* sizex
, char * size1
)
78 for (i
= 0; i
< len
; i
++)
85 /*****************************************************************************/
87 uni_to_str(char * sizex
, TCHAR
* size1
)
93 for (i
= 0; i
< len
; i
++)
95 sizex
[i
] = (char)size1
[i
];
100 /*****************************************************************************/
101 /* returns non zero if it processed something */
114 /* see if there really is data */
116 FD_SET((unsigned int)g_tcp_sck
, &rfds
);
117 ZeroMemory(&tm
, sizeof(tm
));
118 count
= select(g_tcp_sck
+ 1, &rfds
, 0, 0, &tm
);
135 /*****************************************************************************/
141 #else /* WITH_DEBUG */
145 str_to_uni(lmsg
, msg
);
146 str_to_uni(ltitle
, "Error");
147 MessageBox(g_Wnd
, lmsg
, ltitle
, MB_OK
);
148 #endif /* WITH_DEBUG */
151 /*****************************************************************************/
153 get_scan_code_from_ascii(int code
)
160 case 0x30: rv
= 0x0b; break; // 0
161 case 0x31: rv
= 0x02; break; // 1
162 case 0x32: rv
= 0x03; break; // 2
163 case 0x33: rv
= 0x04; break; // 3
164 case 0x34: rv
= 0x05; break; // 4
165 case 0x35: rv
= 0x06; break; // 5
166 case 0x36: rv
= 0x07; break; // 6
167 case 0x37: rv
= 0x08; break; // 7
168 case 0x38: rv
= 0x09; break; // 8
169 case 0x39: rv
= 0x0a; break; // 9
171 case 0xbd: rv
= 0x0c; break; // -
172 case 0xbb: rv
= 0x0d; break; // =
173 case 0x08: rv
= 0x0e; break; // backspace
174 case 0x09: rv
= 0x0f; break; // tab
175 case 0xdb: rv
= 0x1b; break; // ]
176 case 0xdd: rv
= 0x1a; break; // [
177 case 0x14: rv
= 0x3a; break; // capslock
178 case 0xba: rv
= 0x27; break; // ;
179 case 0xde: rv
= 0x28; break; // '
180 case 0x10: rv
= 0x2a; break; // shift
181 case 0xbc: rv
= 0x33; break; // ,
182 case 0xbe: rv
= 0x34; break; // .
183 case 0xbf: rv
= 0x35; break; // /
184 case 0x0d: rv
= 0x1c; break; // enter
185 case 0x27: rv
= 0x4d; break; // arrow right
186 case 0x25: rv
= 0x4b; break; // arrow left
187 case 0x26: rv
= 0x48; break; // arrow up
188 case 0x28: rv
= 0x50; break; // arrow down
189 case 0x20: rv
= 0x39; break; // space
190 case 0xdc: rv
= 0x2b; break; // backslash
191 case 0xc0: rv
= 0x29; break; // `
192 case 0x11: rv
= 0x1d; break; // ctl
194 case 0x41: rv
= 0x1e; break; // a
195 case 0x42: rv
= 0x30; break; // b
196 case 0x43: rv
= 0x2e; break; // c
197 case 0x44: rv
= 0x20; break; // d
198 case 0x45: rv
= 0x12; break; // e
199 case 0x46: rv
= 0x21; break; // f
200 case 0x47: rv
= 0x22; break; // g
201 case 0x48: rv
= 0x23; break; // h
202 case 0x49: rv
= 0x17; break; // i
203 case 0x4a: rv
= 0x24; break; // j
204 case 0x4b: rv
= 0x25; break; // k
205 case 0x4c: rv
= 0x26; break; // l
206 case 0x4d: rv
= 0x32; break; // m
207 case 0x4e: rv
= 0x31; break; // n
208 case 0x4f: rv
= 0x18; break; // o
209 case 0x50: rv
= 0x19; break; // p
210 case 0x51: rv
= 0x10; break; // q
211 case 0x52: rv
= 0x13; break; // r
212 case 0x53: rv
= 0x1f; break; // s
213 case 0x54: rv
= 0x14; break; // t
214 case 0x55: rv
= 0x16; break; // u
215 case 0x56: rv
= 0x2f; break; // v
216 case 0x57: rv
= 0x11; break; // w
217 case 0x58: rv
= 0x2d; break; // x
218 case 0x59: rv
= 0x15; break; // y
219 case 0x5a: rv
= 0x2c; break; // z
224 /*****************************************************************************/
226 mi_scroll(int dx
, int dy
)
230 rgn
= CreateRectRgn(0, 0, 0, 0);
231 ScrollWindowEx(g_Wnd
, dx
, dy
, 0, 0, rgn
, 0, SW_ERASE
);
232 InvalidateRgn(g_Wnd
, rgn
, 0);
236 /*****************************************************************************/
238 mi_read_keyboard_state(void)
244 keydata
= GetKeyState(VK_SCROLL
);
245 if (keydata
& 0x0001)
249 keydata
= GetKeyState(VK_NUMLOCK
);
250 if (keydata
& 0x0001)
254 keydata
= GetKeyState(VK_CAPITAL
);
255 if (keydata
& 0x0001)
262 /*****************************************************************************/
264 mi_check_modifier(void)
268 code
= mi_read_keyboard_state();
269 ui_set_modifier_state(code
);
272 /*****************************************************************************/
274 handle_WM_SETCURSOR(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
276 if (g_mousex
>= g_wnd_clip
.left
&&
277 g_mousey
>= g_wnd_clip
.top
&&
278 g_mousex
< g_wnd_clip
.right
&&
279 g_mousey
< g_wnd_clip
.bottom
)
283 /* need default behavoir here */
284 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
287 /*****************************************************************************/
289 handle_WM_NCHITTEST(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
293 pt
.x
= LOWORD(lParam
);
294 pt
.y
= HIWORD(lParam
);
295 if (ScreenToClient(g_Wnd
, &pt
))
300 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
303 /*****************************************************************************/
305 handle_WM_MOUSEMOVE(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
307 g_mousex
= LOWORD(lParam
);
308 g_mousey
= HIWORD(lParam
);
309 ui_mouse_move(g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
);
313 /*****************************************************************************/
315 handle_WM_LBUTTONDOWN(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
317 g_mousex
= LOWORD(lParam
);
318 g_mousey
= HIWORD(lParam
);
319 ui_mouse_button(1, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 1);
323 /*****************************************************************************/
325 handle_WM_LBUTTONUP(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
327 g_mousex
= LOWORD(lParam
);
328 g_mousey
= HIWORD(lParam
);
329 ui_mouse_button(1, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 0);
333 /*****************************************************************************/
335 handle_WM_RBUTTONDOWN(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
337 g_mousex
= LOWORD(lParam
);
338 g_mousey
= HIWORD(lParam
);
339 ui_mouse_button(2, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 1);
343 /*****************************************************************************/
345 handle_WM_RBUTTONUP(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
347 g_mousex
= LOWORD(lParam
);
348 g_mousey
= HIWORD(lParam
);
349 ui_mouse_button(2, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 0);
353 /*****************************************************************************/
355 handle_WM_MBUTTONDOWN(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
357 g_mousex
= LOWORD(lParam
);
358 g_mousey
= HIWORD(lParam
);
359 ui_mouse_button(3, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 1);
363 /*****************************************************************************/
365 handle_WM_MBUTTONUP(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
367 g_mousex
= LOWORD(lParam
);
368 g_mousey
= HIWORD(lParam
);
369 ui_mouse_button(3, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 0);
373 /*****************************************************************************/
375 handle_WM_MOUSEWHEEL(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
379 delta
= ((signed short)HIWORD(wParam
)); /* GET_WHEEL_DELTA_WPARAM(wParam); */
382 ui_mouse_button(4, 0, 0, 1);
383 ui_mouse_button(4, 0, 0, 0);
387 ui_mouse_button(5, 0, 0, 1);
388 ui_mouse_button(5, 0, 0, 0);
393 /*****************************************************************************/
395 handle_WM_KEY(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
401 ext
= HIWORD(lParam
);
403 down
= !(ext
& 0x8000);
407 scancode
= get_scan_code_from_ascii(wParam
);
410 if (scancode
== 0x0045) /* num lock */
416 ui_key_down(scancode
, ext
);
420 ui_key_up(scancode
, ext
);
425 /*****************************************************************************/
427 handle_WM_PAINT(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
433 BeginPaint(hWnd
, &ps
);
434 /* paint the area outside the rdp screen with one colour */
436 rect
.left
= UI_MAX(rect
.left
, g_width
);
437 if (!IsRectEmpty(&rect
))
439 brush
= CreateSolidBrush(RGB(0, 0, 255));
440 FillRect(ps
.hdc
, &rect
, brush
);
444 rect
.top
= UI_MAX(rect
.top
, g_height
);
445 if (!IsRectEmpty(&rect
))
447 brush
= CreateSolidBrush(RGB(0, 0, 255));
448 FillRect(ps
.hdc
, &rect
, brush
);
453 ui_invalidate(rect
.left
+ g_xscroll
,
454 rect
.top
+ g_yscroll
,
455 (rect
.right
- rect
.left
) + 1,
456 (rect
.bottom
- rect
.top
) + 1);
460 /*****************************************************************************/
462 handle_WM_SIZE(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
467 if (wParam
== SIZE_MINIMIZED
)
469 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
471 g_wnd_cwidth
= LOWORD(lParam
); /* client width / height */
472 g_wnd_cheight
= HIWORD(lParam
);
475 g_wnd_clip
.right
= g_wnd_clip
.left
+ g_wnd_cwidth
;
476 g_wnd_clip
.bottom
= g_wnd_clip
.top
+ g_wnd_cheight
;
477 if (g_wnd_cwidth
< g_width
|| g_wnd_cheight
< g_height
)
479 SetScrollRange(g_Wnd
, SB_HORZ
, 0, g_width
- g_wnd_cwidth
, 1);
480 SetScrollRange(g_Wnd
, SB_VERT
, 0, g_height
- g_wnd_cheight
, 1);
482 oldxscroll
= g_xscroll
;
483 oldyscroll
= g_yscroll
;
484 if (g_wnd_cwidth
>= g_width
)
490 g_xscroll
= UI_MIN(g_xscroll
, g_width
- g_wnd_cwidth
);
492 if (g_wnd_cheight
>= g_height
)
498 g_yscroll
= UI_MIN(g_yscroll
, g_height
- g_wnd_cheight
);
500 mi_scroll(oldxscroll
- g_xscroll
, oldyscroll
- g_yscroll
);
501 if (wParam
== SIZE_RESTORED
|| wParam
== SIZE_MAXIMIZED
)
503 /* check the caps, num, and scroll lock here */
509 /*****************************************************************************/
511 handle_WM_SIZING(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
518 prect
= (LPRECT
) lParam
; /* total window rect */
519 width
= (prect
->right
- prect
->left
) - (g_xoff
* 2);
520 height
= (prect
->bottom
- prect
->top
) - (g_yoff
+ g_xoff
);
521 if (height
< g_height
|| width
< g_width
)
523 style
= GetWindowLong(g_Wnd
, GWL_STYLE
);
524 if (!(style
& WS_HSCROLL
))
526 style
|= WS_HSCROLL
| WS_VSCROLL
;
527 SetWindowLong(g_Wnd
, GWL_STYLE
, style
);
530 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
531 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
534 else if (height
>= g_height
&& width
>= g_width
)
536 style
= GetWindowLong(g_Wnd
, GWL_STYLE
);
537 if (style
& WS_HSCROLL
)
539 style
&= ~WS_HSCROLL
;
540 style
&= ~WS_VSCROLL
;
541 SetWindowLong(g_Wnd
, GWL_STYLE
, style
);
549 /*****************************************************************************/
551 handle_WM_HSCROLL(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
556 code
= (int) LOWORD(wParam
); /* scroll bar value */
557 if (code
== SB_LINELEFT
)
559 oldxscroll
= g_xscroll
;
561 g_xscroll
= UI_MAX(g_xscroll
, 0);
562 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
563 mi_scroll(oldxscroll
- g_xscroll
, 0);
565 else if (code
== SB_LINERIGHT
)
567 oldxscroll
= g_xscroll
;
569 g_xscroll
= UI_MIN(g_xscroll
, g_width
- g_wnd_cwidth
);
570 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
571 mi_scroll(oldxscroll
- g_xscroll
, 0);
573 else if (code
== SB_PAGELEFT
)
575 oldxscroll
= g_xscroll
;
576 g_xscroll
-= g_wnd_cwidth
/ 2;
577 g_xscroll
= UI_MAX(g_xscroll
, 0);
578 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
579 mi_scroll(oldxscroll
- g_xscroll
, 0);
581 else if (code
== SB_PAGERIGHT
)
583 oldxscroll
= g_xscroll
;
584 g_xscroll
+= g_wnd_cwidth
/ 2;
585 g_xscroll
= UI_MIN(g_xscroll
, g_width
- g_wnd_cwidth
);
586 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
587 mi_scroll(oldxscroll
- g_xscroll
, 0);
589 else if (code
== SB_BOTTOM
)
591 oldxscroll
= g_xscroll
;
592 g_xscroll
= g_width
- g_wnd_cwidth
;
593 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
594 mi_scroll(oldxscroll
- g_xscroll
, 0);
596 else if (code
== SB_TOP
)
598 oldxscroll
= g_xscroll
;
600 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
601 mi_scroll(oldxscroll
- g_xscroll
, 0);
603 else if (code
== SB_THUMBPOSITION
)
605 oldxscroll
= g_xscroll
;
606 g_xscroll
= (signed short) HIWORD(wParam
);
607 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
608 mi_scroll(oldxscroll
- g_xscroll
, 0);
613 /*****************************************************************************/
615 handle_WM_VSCROLL(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
620 code
= (int) LOWORD(wParam
); /* scroll bar value */
621 if (code
== SB_LINELEFT
)
623 oldyscroll
= g_yscroll
;
625 g_yscroll
= UI_MAX(g_yscroll
, 0);
626 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
627 mi_scroll(0, oldyscroll
- g_yscroll
);
629 else if (code
== SB_LINERIGHT
)
631 oldyscroll
= g_yscroll
;
633 g_yscroll
= UI_MIN(g_yscroll
, g_height
- g_wnd_cheight
);
634 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
635 mi_scroll(0, oldyscroll
- g_yscroll
);
637 else if (code
== SB_PAGELEFT
)
639 oldyscroll
= g_yscroll
;
640 g_yscroll
-= g_wnd_cheight
/ 2;
641 g_yscroll
= UI_MAX(g_yscroll
, 0);
642 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
643 mi_scroll(0, oldyscroll
- g_yscroll
);
645 else if (code
== SB_PAGERIGHT
)
647 oldyscroll
= g_yscroll
;
648 g_yscroll
+= g_wnd_cheight
/ 2;
649 g_yscroll
= UI_MIN(g_yscroll
, g_height
- g_wnd_cheight
);
650 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
651 mi_scroll(0, oldyscroll
- g_yscroll
);
653 else if (code
== SB_BOTTOM
)
655 oldyscroll
= g_yscroll
;
656 g_yscroll
= g_height
- g_wnd_cheight
;
657 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
658 mi_scroll(0, oldyscroll
- g_yscroll
);
660 else if (code
== SB_TOP
)
662 oldyscroll
= g_yscroll
;
664 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
665 mi_scroll(0, oldyscroll
- g_yscroll
);
667 else if (code
== SB_THUMBPOSITION
)
669 oldyscroll
= g_yscroll
;
670 g_yscroll
= (signed short) HIWORD(wParam
);
671 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
672 mi_scroll(0, oldyscroll
- g_yscroll
);
678 /*****************************************************************************/
680 WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
685 return handle_WM_SETCURSOR(hWnd
, message
, wParam
, lParam
);
686 case 0x0084: /* WinCE don't have this WM_NCHITTEST: */
687 return handle_WM_NCHITTEST(hWnd
, message
, wParam
, lParam
);
689 return handle_WM_MOUSEMOVE(hWnd
, message
, wParam
, lParam
);
691 return handle_WM_LBUTTONDOWN(hWnd
, message
, wParam
, lParam
);
693 return handle_WM_LBUTTONUP(hWnd
, message
, wParam
, lParam
);
695 return handle_WM_RBUTTONDOWN(hWnd
, message
, wParam
, lParam
);
697 return handle_WM_RBUTTONUP(hWnd
, message
, wParam
, lParam
);
699 return handle_WM_MBUTTONDOWN(hWnd
, message
, wParam
, lParam
);
701 return handle_WM_MBUTTONUP(hWnd
, message
, wParam
, lParam
);
702 /* some windows compilers don't have these defined like vc6 */
703 case 0x020a: /* WM_MOUSEWHEEL: */
704 return handle_WM_MOUSEWHEEL(hWnd
, message
, wParam
, lParam
);
709 return handle_WM_KEY(hWnd
, message
, wParam
, lParam
);
716 return handle_WM_PAINT(hWnd
, message
, wParam
, lParam
);
725 return handle_WM_SIZE(hWnd
, message
, wParam
, lParam
);
726 case 532: /* not defined in wince WM_SIZING: */
727 return handle_WM_SIZING(hWnd
, message
, wParam
, lParam
);
729 return handle_WM_HSCROLL(hWnd
, message
, wParam
, lParam
);
731 return handle_WM_VSCROLL(hWnd
, message
, wParam
, lParam
);
734 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
736 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
741 /*****************************************************************************/
747 rgn
= CreateRectRgn(g_clip_left
+ g_xoff
- g_xscroll
,
748 g_clip_top
+ g_yoff
- g_yscroll
,
749 g_clip_right
+ g_xoff
- g_xscroll
,
750 g_clip_bottom
+ g_yoff
- g_yscroll
);
751 SelectClipRgn(dc
, rgn
);
752 IntersectClipRect(dc
, g_wnd_clip
.left
+ g_xoff
, g_wnd_clip
.top
+ g_yoff
,
753 g_wnd_clip
.right
+ g_xoff
, g_wnd_clip
.bottom
+ g_yoff
);
757 /*****************************************************************************/
758 /* returns non zero if ok */
760 mi_create_window(void)
764 TCHAR classname
[512];
772 if (g_Wnd
!= 0 || g_Instance
!= 0)
776 g_Instance
= GetModuleHandle(NULL
);
777 ZeroMemory(&wc
, sizeof(wc
));
778 wc
.lpfnWndProc
= WndProc
; /* points to window procedure */
779 /* name of window class */
780 str_to_uni(classname
, "rdesktop");
781 wc
.lpszClassName
= classname
;
782 str_to_uni(caption
, "ReactOS Remote Desktop");
783 wc
.hIcon
= LoadIcon(g_Instance
,
784 MAKEINTRESOURCE(IDI_MSTSC
));
785 /* Register the window class. */
786 if (!RegisterClass(&wc
))
788 return 0; /* Failed to register window class */
791 rc
.right
= rc
.left
+ UI_MIN(g_width
, g_screen_width
);
793 rc
.bottom
= rc
.top
+ UI_MIN(g_height
, g_screen_height
);
801 style
= WS_OVERLAPPED
| WS_CAPTION
| WS_POPUP
| WS_MINIMIZEBOX
|
802 WS_SYSMENU
| WS_SIZEBOX
| WS_MAXIMIZEBOX
;
804 if (g_screen_width
< g_width
|| g_screen_height
< g_height
)
806 style
|= WS_HSCROLL
| WS_VSCROLL
;
808 AdjustWindowRectEx(&rc
, style
, 0, 0);
811 w
= rc
.right
- rc
.left
;
812 h
= rc
.bottom
- rc
.top
;
814 g_Wnd
= CreateWindow(wc
.lpszClassName
, caption
,
816 (HWND
) NULL
, (HMENU
) NULL
, g_Instance
,
820 g_clip_right
= g_clip_left
+ g_width
;
821 g_clip_bottom
= g_clip_top
+ g_height
;
824 ShowWindow(g_Wnd
, SW_SHOWMAXIMIZED
);
828 ShowWindow(g_Wnd
, SW_SHOWNORMAL
);
832 WSAAsyncSelect(g_tcp_sck
, g_Wnd
, WM_APP
+ 1, FD_READ
);
833 SetTimer(g_Wnd
, 1, 333, 0);
838 /*****************************************************************************/
844 while (GetMessage(&msg
, NULL
, 0, 0))
846 TranslateMessage(&msg
);
847 DispatchMessage(&msg
);
852 /*****************************************************************************/
854 mi_warning(char * msg
)
858 /*****************************************************************************/
860 mi_show_error(char * caption
)
865 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
866 NULL
, GetLastError(), MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
867 (LPTSTR
) &lpMsgBuf
, 0, NULL
);
870 #else /* WITH_DEBUG */
871 str_to_uni(lcaption
, caption
);
872 MessageBox(g_Wnd
, (LPTSTR
) lpMsgBuf
, lcaption
,
873 MB_OK
| MB_ICONINFORMATION
);
874 #endif /* WITH_DEBUG */
878 /*****************************************************************************/
880 mi_paint_rect(char * data
, int width
, int height
, int x
, int y
, int cx
, int cy
)
896 ZeroMemory(&bi
, sizeof(bi
));
897 bi
.bmiHeader
.biSize
= sizeof(bi
.bmiHeader
);
898 bi
.bmiHeader
.biWidth
= width
;
899 bi
.bmiHeader
.biHeight
= -height
;
900 bi
.bmiHeader
.biPlanes
= 1;
901 bi
.bmiHeader
.biBitCount
= 32;
902 bi
.bmiHeader
.biCompression
= BI_RGB
;
903 maindc
= GetWindowDC(g_Wnd
);
904 bitmap
= CreateDIBSection(maindc
, &bi
, DIB_RGB_COLORS
, (void **) &bits
, 0, 0);
907 mi_show_error("CreateDIBSection failed");
910 if (g_server_depth
== 8)
912 for (i
= cy
- 1; i
>= 0; i
--)
914 for (j
= cx
- 1; j
>= 0; j
--)
916 colour
= ((unsigned char*)data
)[i
* cx
+ j
];
917 red
= (pal_entries
[colour
& 0xff] & 0xff0000) >> 16;
918 green
= (pal_entries
[colour
& 0xff] & 0xff00) >> 8;
919 blue
= pal_entries
[colour
& 0xff] & 0xff;
920 MAKE_COLOUR32(colour
, red
, green
, blue
);
921 ((unsigned int*)bits
)[i
* cx
+ j
] = colour
;
925 else if (g_server_depth
== 15)
927 for (i
= cy
- 1; i
>= 0; i
--)
929 for (j
= cx
- 1; j
>= 0; j
--)
931 colour
= ((unsigned short*)data
)[i
* cx
+ j
];
932 SPLIT_COLOUR15(colour
, red
, green
, blue
);
933 MAKE_COLOUR32(colour
, red
, green
, blue
);
934 ((unsigned int*)bits
)[i
* cx
+ j
] = colour
;
938 else if (g_server_depth
== 16)
940 for (i
= cy
- 1; i
>= 0; i
--)
942 for (j
= cx
- 1; j
>= 0; j
--)
944 colour
= ((unsigned short*)data
)[i
* cx
+ j
];
945 SPLIT_COLOUR16(colour
, red
, green
, blue
);
946 MAKE_COLOUR32(colour
, red
, green
, blue
);
947 ((unsigned int*)bits
)[i
* cx
+ j
] = colour
;
951 dc
= CreateCompatibleDC(maindc
);
954 mi_show_error("CreateCompatibleDC failed");
956 save
= SelectObject(dc
, bitmap
);
957 rgn
= mi_clip(maindc
);
958 BitBlt(maindc
, x
+ g_xoff
- g_xscroll
, y
+ g_yoff
- g_yscroll
, cx
, cy
, dc
,
960 SelectObject(dc
, save
);
961 DeleteObject(bitmap
);
963 ReleaseDC(g_Wnd
, maindc
);
970 ParseCommandLine(LPWSTR lpCmdLine
,
971 PRDPSETTINGS pRdpSettings
,
974 LPWSTR lpStr
= lpCmdLine
;
975 WCHAR szSeps
[] = L
"/";
981 if (*lpCmdLine
!= L
'/')
983 LoadRdpSettingsFromFile(pRdpSettings
, lpCmdLine
);
987 /* default to 16bpp */
988 SetIntegerToSettings(pRdpSettings
, L
"session bpp", 16);
990 lpToken
= wcstok(lpStr
, szSeps
);
993 if (wcsncmp(lpToken
, L
"edit", 4) == 0)
996 LoadRdpSettingsFromFile(pRdpSettings
, lpToken
);
1001 if (*lpToken
== L
'v')
1004 SetStringToSettings(pRdpSettings
, L
"full address", lpToken
);
1006 else if (*lpToken
== L
'w')
1009 SetIntegerToSettings(pRdpSettings
, L
"desktopwidth", _wtoi(lpToken
));
1011 else if (*lpToken
== L
'h')
1014 SetIntegerToSettings(pRdpSettings
, L
"desktopheight", _wtoi(lpToken
));
1017 lpToken
= wcstok(NULL
, szSeps
);
1024 /*****************************************************************************/
1026 wWinMain(HINSTANCE hInstance
,
1027 HINSTANCE hPrevInstance
,
1031 PRDPSETTINGS pRdpSettings
;
1035 if (WSAStartup(MAKEWORD(2, 0), &d
) == 0)
1037 pRdpSettings
= HeapAlloc(GetProcessHeap(),
1039 sizeof(RDPSETTINGS
));
1042 pRdpSettings
->pSettings
= NULL
;
1043 pRdpSettings
->NumSettings
= 0;
1045 if (InitRdpSettings(pRdpSettings
))
1047 BOOL bSkipDlg
= FALSE
;
1050 ParseCommandLine(lpCmdLine
, pRdpSettings
,&bSkipDlg
);
1052 LoadRdpSettingsFromFile(pRdpSettings
, NULL
);
1054 if (bSkipDlg
|| OpenRDPConnectDialog(hInstance
,
1057 char szValue
[MAXVALUE
];
1059 uni_to_str(szValue
, GetStringFromSettings(pRdpSettings
, L
"full address"));
1061 strcpy(g_servername
, szValue
);
1063 strcpy(g_username
, "");
1064 strcpy(g_password
, "");
1065 g_server_depth
= GetIntegerFromSettings(pRdpSettings
, L
"session bpp");
1066 if (g_server_depth
> 16) g_server_depth
= 16; /* hack, we don't support 24bpp yet */
1067 g_width
= GetIntegerFromSettings(pRdpSettings
, L
"desktopwidth");
1068 g_height
= GetIntegerFromSettings(pRdpSettings
, L
"desktopheight");
1069 g_screen_width
= GetSystemMetrics(SM_CXSCREEN
);
1070 g_screen_height
= GetSystemMetrics(SM_CYSCREEN
);
1071 g_xoff
= GetSystemMetrics(SM_CXEDGE
) * 2;
1072 g_yoff
= GetSystemMetrics(SM_CYCAPTION
) + GetSystemMetrics(SM_CYEDGE
) * 2;
1078 HeapFree(GetProcessHeap(),
1080 pRdpSettings
->pSettings
);
1083 HeapFree(GetProcessHeap(),
1095 /*****************************************************************************/
1097 mi_begin_update(void)
1101 /*****************************************************************************/
1107 /*****************************************************************************/
1109 mi_fill_rect(int x
, int y
, int cx
, int cy
, int colour
)
1119 if (g_server_depth
== 8)
1121 red
= (pal_entries
[colour
& 0xff] & 0xff0000) >> 16;
1122 green
= (pal_entries
[colour
& 0xff] & 0xff00) >> 8;
1123 blue
= pal_entries
[colour
& 0xff] & 0xff;
1125 else if (g_server_depth
== 15)
1127 SPLIT_COLOUR15(colour
, red
, green
, blue
);
1129 else if (g_server_depth
== 16)
1131 SPLIT_COLOUR16(colour
, red
, green
, blue
);
1139 maindc
= GetWindowDC(g_Wnd
);
1140 rgn
= mi_clip(maindc
);
1141 brush
= CreateSolidBrush(RGB(red
, green
, blue
));
1142 rect
.left
= x
+ g_xoff
- g_xscroll
;
1143 rect
.top
= y
+ g_yoff
- g_yscroll
;
1144 rect
.right
= rect
.left
+ cx
;
1145 rect
.bottom
= rect
.top
+ cy
;
1146 FillRect(maindc
, &rect
, brush
);
1147 DeleteObject(brush
);
1148 ReleaseDC(g_Wnd
, maindc
);
1152 /*****************************************************************************/
1154 mi_line(int x1
, int y1
, int x2
, int y2
, int colour
)
1164 if (g_server_depth
== 8)
1166 red
= (pal_entries
[colour
& 0xff] & 0xff0000) >> 16;
1167 green
= (pal_entries
[colour
& 0xff] & 0xff00) >> 8;
1168 blue
= pal_entries
[colour
& 0xff] & 0xff;
1170 else if (g_server_depth
== 15)
1172 SPLIT_COLOUR15(colour
, red
, green
, blue
);
1174 else if (g_server_depth
== 16)
1176 SPLIT_COLOUR16(colour
, red
, green
, blue
);
1184 maindc
= GetWindowDC(g_Wnd
);
1185 rgn
= mi_clip(maindc
);
1186 pen
= CreatePen(PS_SOLID
, 0, RGB(red
, green
, blue
));
1187 save
= SelectObject(maindc
, pen
);
1188 MoveToEx(maindc
, x1
+ g_xoff
- g_xscroll
, y1
+ g_yoff
- g_yscroll
, 0);
1189 LineTo(maindc
, x2
+ g_xoff
- g_xscroll
, y2
+ g_yoff
- g_yscroll
);
1190 SelectObject(maindc
, save
);
1192 ReleaseDC(g_Wnd
, maindc
);
1196 /*****************************************************************************/
1198 mi_screen_copy(int x
, int y
, int cx
, int cy
, int srcx
, int srcy
)
1204 int ok_to_ScrollWindowEx
;
1206 ok_to_ScrollWindowEx
= 1;
1208 if (!ok_to_ScrollWindowEx
)
1210 rgn
= CreateRectRgn(x
- g_xscroll
, y
- g_yscroll
,
1211 (x
- g_xscroll
) + cx
,
1212 (y
- g_yscroll
) + cy
);
1213 InvalidateRgn(g_Wnd
, rgn
, 0);
1218 /* this is all in client coords */
1219 rect
.left
= srcx
- g_xscroll
;
1220 rect
.top
= srcy
- g_yscroll
;
1221 rect
.right
= rect
.left
+ cx
;
1222 rect
.bottom
= rect
.top
+ cy
;
1223 clip_rect
.left
= g_clip_left
- g_xscroll
;
1224 clip_rect
.top
= g_clip_top
- g_yscroll
;
1225 clip_rect
.right
= g_clip_right
- g_xscroll
;
1226 clip_rect
.bottom
= g_clip_bottom
- g_yscroll
;
1227 if (IntersectRect(&draw_rect
, &clip_rect
, &g_wnd_clip
))
1229 rgn
= CreateRectRgn(0, 0, 0, 0);
1230 ScrollWindowEx(g_Wnd
, x
- srcx
, y
- srcy
, &rect
, &draw_rect
,
1232 InvalidateRgn(g_Wnd
, rgn
, 0);
1238 /*****************************************************************************/
1240 mi_set_clip(int x
, int y
, int cx
, int cy
)
1244 g_clip_right
= g_clip_left
+ cx
;
1245 g_clip_bottom
= g_clip_top
+ cy
;
1248 /*****************************************************************************/
1254 g_clip_right
= g_clip_left
+ g_width
;
1255 g_clip_bottom
= g_clip_top
+ g_height
;
1258 /*****************************************************************************/
1260 mi_create_cursor(unsigned int x
, unsigned int y
,
1261 int width
, int height
,
1262 unsigned char * andmask
, unsigned char * xormask
)
1266 hCur
= CreateCursor(g_Instance
, x
, y
, width
, height
, andmask
, xormask
);
1269 hCur
= LoadCursor(NULL
, IDC_ARROW
);
1274 /*****************************************************************************/
1276 mi_destroy_cursor(void * cursor
)
1278 if (g_cursor
== cursor
)
1282 DestroyCursor(cursor
);
1285 /*****************************************************************************/
1287 mi_set_cursor(void * cursor
)
1290 SetCursor(g_cursor
);
1293 /*****************************************************************************/
1295 mi_set_null_cursor(void)