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.
21 //#include <winsock2.h> /* winsock2.h first */
24 extern char g_username
[];
25 extern char g_hostname
[];
26 extern char g_servername
[];
27 extern char g_password
[];
28 extern char g_shell
[];
29 extern char g_directory
[];
30 extern char g_domain
[];
34 extern int g_server_depth
;
35 extern int g_tcp_port_rdp
; /* in tcp.c */
36 extern int pal_entries
[];
38 static HWND g_Wnd
= 0;
39 static HINSTANCE g_Instance
= 0;
40 static HCURSOR g_cursor
= 0;
41 static int g_block
= 0;
42 static int g_xoff
= 0; /* offset from window to client coords */
43 static int g_yoff
= 0;
44 static int g_xscroll
= 0; /* current scroll position */
45 static int g_yscroll
= 0;
46 static int g_screen_width
= 0;
47 static int g_screen_height
= 0;
48 static int g_wnd_cwidth
= 0; /* set from WM_SIZE */
49 static int g_wnd_cheight
= 0;
50 static int g_fullscreen
= 0;
51 static int g_workarea
= 0;
52 static int g_mousex
= 0; /* in client coords */
53 static int g_mousey
= 0;
54 //static int g_width_height_set = 0;
56 static int g_clip_left
= 0;
57 static int g_clip_top
= 0;
58 static int g_clip_right
= 800;
59 static int g_clip_bottom
= 600;
60 static RECT g_wnd_clip
; /* this client area of whats actually visable */
61 /* set from WM_SIZE */
63 /*****************************************************************************/
65 str_to_uni(TCHAR
* sizex
, char * size1
)
71 for (i
= 0; i
< len
; i
++)
78 /*****************************************************************************/
80 uni_to_str(char * sizex
, TCHAR
* size1
)
86 for (i
= 0; i
< len
; i
++)
88 sizex
[i
] = (char)size1
[i
];
93 /*****************************************************************************/
94 /* returns non zero if it processed something */
107 /* see if there really is data */
109 FD_SET((unsigned int)g_tcp_sck
, &rfds
);
110 ZeroMemory(&tm
, sizeof(tm
));
111 count
= select(g_tcp_sck
+ 1, &rfds
, 0, 0, &tm
);
128 /*****************************************************************************/
134 #else /* WITH_DEBUG */
138 str_to_uni(lmsg
, msg
);
139 str_to_uni(ltitle
, "Error");
140 MessageBox(g_Wnd
, lmsg
, ltitle
, MB_OK
);
141 #endif /* WITH_DEBUG */
144 /*****************************************************************************/
146 get_scan_code_from_ascii(int code
)
153 case 0x30: rv
= 0x0b; break; // 0
154 case 0x31: rv
= 0x02; break; // 1
155 case 0x32: rv
= 0x03; break; // 2
156 case 0x33: rv
= 0x04; break; // 3
157 case 0x34: rv
= 0x05; break; // 4
158 case 0x35: rv
= 0x06; break; // 5
159 case 0x36: rv
= 0x07; break; // 6
160 case 0x37: rv
= 0x08; break; // 7
161 case 0x38: rv
= 0x09; break; // 8
162 case 0x39: rv
= 0x0a; break; // 9
164 case 0xbd: rv
= 0x0c; break; // -
165 case 0xbb: rv
= 0x0d; break; // =
166 case 0x08: rv
= 0x0e; break; // backspace
167 case 0x09: rv
= 0x0f; break; // tab
168 case 0xdb: rv
= 0x1b; break; // ]
169 case 0xdd: rv
= 0x1a; break; // [
170 case 0x14: rv
= 0x3a; break; // capslock
171 case 0xba: rv
= 0x27; break; // ;
172 case 0xde: rv
= 0x28; break; // '
173 case 0x10: rv
= 0x2a; break; // shift
174 case 0xbc: rv
= 0x33; break; // ,
175 case 0xbe: rv
= 0x34; break; // .
176 case 0xbf: rv
= 0x35; break; // /
177 case 0x0d: rv
= 0x1c; break; // enter
178 case 0x27: rv
= 0x4d; break; // arrow right
179 case 0x25: rv
= 0x4b; break; // arrow left
180 case 0x26: rv
= 0x48; break; // arrow up
181 case 0x28: rv
= 0x50; break; // arrow down
182 case 0x20: rv
= 0x39; break; // space
183 case 0xdc: rv
= 0x2b; break; // backslash
184 case 0xc0: rv
= 0x29; break; // `
185 case 0x11: rv
= 0x1d; break; // ctl
187 case 0x41: rv
= 0x1e; break; // a
188 case 0x42: rv
= 0x30; break; // b
189 case 0x43: rv
= 0x2e; break; // c
190 case 0x44: rv
= 0x20; break; // d
191 case 0x45: rv
= 0x12; break; // e
192 case 0x46: rv
= 0x21; break; // f
193 case 0x47: rv
= 0x22; break; // g
194 case 0x48: rv
= 0x23; break; // h
195 case 0x49: rv
= 0x17; break; // i
196 case 0x4a: rv
= 0x24; break; // j
197 case 0x4b: rv
= 0x25; break; // k
198 case 0x4c: rv
= 0x26; break; // l
199 case 0x4d: rv
= 0x32; break; // m
200 case 0x4e: rv
= 0x31; break; // n
201 case 0x4f: rv
= 0x18; break; // o
202 case 0x50: rv
= 0x19; break; // p
203 case 0x51: rv
= 0x10; break; // q
204 case 0x52: rv
= 0x13; break; // r
205 case 0x53: rv
= 0x1f; break; // s
206 case 0x54: rv
= 0x14; break; // t
207 case 0x55: rv
= 0x16; break; // u
208 case 0x56: rv
= 0x2f; break; // v
209 case 0x57: rv
= 0x11; break; // w
210 case 0x58: rv
= 0x2d; break; // x
211 case 0x59: rv
= 0x15; break; // y
212 case 0x5a: rv
= 0x2c; break; // z
217 /*****************************************************************************/
219 mi_scroll(int dx
, int dy
)
223 rgn
= CreateRectRgn(0, 0, 0, 0);
224 ScrollWindowEx(g_Wnd
, dx
, dy
, 0, 0, rgn
, 0, SW_ERASE
);
225 InvalidateRgn(g_Wnd
, rgn
, 0);
229 /*****************************************************************************/
231 mi_read_keyboard_state(void)
237 keydata
= GetKeyState(VK_SCROLL
);
238 if (keydata
& 0x0001)
242 keydata
= GetKeyState(VK_NUMLOCK
);
243 if (keydata
& 0x0001)
247 keydata
= GetKeyState(VK_CAPITAL
);
248 if (keydata
& 0x0001)
255 /*****************************************************************************/
257 mi_check_modifier(void)
261 code
= mi_read_keyboard_state();
262 ui_set_modifier_state(code
);
265 /*****************************************************************************/
267 handle_WM_SETCURSOR(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
269 if (g_mousex
>= g_wnd_clip
.left
&&
270 g_mousey
>= g_wnd_clip
.top
&&
271 g_mousex
< g_wnd_clip
.right
&&
272 g_mousey
< g_wnd_clip
.bottom
)
276 /* need default behavoir here */
277 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
280 /*****************************************************************************/
282 handle_WM_NCHITTEST(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
286 pt
.x
= LOWORD(lParam
);
287 pt
.y
= HIWORD(lParam
);
288 if (ScreenToClient(g_Wnd
, &pt
))
293 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
296 /*****************************************************************************/
298 handle_WM_MOUSEMOVE(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
300 g_mousex
= LOWORD(lParam
);
301 g_mousey
= HIWORD(lParam
);
302 ui_mouse_move(g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
);
306 /*****************************************************************************/
308 handle_WM_LBUTTONDOWN(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
310 g_mousex
= LOWORD(lParam
);
311 g_mousey
= HIWORD(lParam
);
312 ui_mouse_button(1, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 1);
316 /*****************************************************************************/
318 handle_WM_LBUTTONUP(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
320 g_mousex
= LOWORD(lParam
);
321 g_mousey
= HIWORD(lParam
);
322 ui_mouse_button(1, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 0);
326 /*****************************************************************************/
328 handle_WM_RBUTTONDOWN(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
330 g_mousex
= LOWORD(lParam
);
331 g_mousey
= HIWORD(lParam
);
332 ui_mouse_button(2, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 1);
336 /*****************************************************************************/
338 handle_WM_RBUTTONUP(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
340 g_mousex
= LOWORD(lParam
);
341 g_mousey
= HIWORD(lParam
);
342 ui_mouse_button(2, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 0);
346 /*****************************************************************************/
348 handle_WM_MBUTTONDOWN(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
350 g_mousex
= LOWORD(lParam
);
351 g_mousey
= HIWORD(lParam
);
352 ui_mouse_button(3, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 1);
356 /*****************************************************************************/
358 handle_WM_MBUTTONUP(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
360 g_mousex
= LOWORD(lParam
);
361 g_mousey
= HIWORD(lParam
);
362 ui_mouse_button(3, g_mousex
+ g_xscroll
, g_mousey
+ g_yscroll
, 0);
366 /*****************************************************************************/
368 handle_WM_MOUSEWHEEL(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
372 delta
= ((signed short)HIWORD(wParam
)); /* GET_WHEEL_DELTA_WPARAM(wParam); */
375 ui_mouse_button(4, 0, 0, 1);
376 ui_mouse_button(4, 0, 0, 0);
380 ui_mouse_button(5, 0, 0, 1);
381 ui_mouse_button(5, 0, 0, 0);
386 /*****************************************************************************/
388 handle_WM_KEY(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
394 ext
= HIWORD(lParam
);
396 down
= !(ext
& 0x8000);
400 scancode
= get_scan_code_from_ascii(wParam
);
403 if (scancode
== 0x0045) /* num lock */
409 ui_key_down(scancode
, ext
);
413 ui_key_up(scancode
, ext
);
418 /*****************************************************************************/
420 handle_WM_PAINT(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
426 BeginPaint(hWnd
, &ps
);
427 /* paint the area outside the rdp screen with one colour */
429 rect
.left
= UI_MAX(rect
.left
, g_width
);
430 if (!IsRectEmpty(&rect
))
432 brush
= CreateSolidBrush(RGB(0, 0, 255));
433 FillRect(ps
.hdc
, &rect
, brush
);
437 rect
.top
= UI_MAX(rect
.top
, g_height
);
438 if (!IsRectEmpty(&rect
))
440 brush
= CreateSolidBrush(RGB(0, 0, 255));
441 FillRect(ps
.hdc
, &rect
, brush
);
446 ui_invalidate(rect
.left
+ g_xscroll
,
447 rect
.top
+ g_yscroll
,
448 (rect
.right
- rect
.left
) + 1,
449 (rect
.bottom
- rect
.top
) + 1);
453 /*****************************************************************************/
455 handle_WM_SIZE(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
460 if (wParam
== SIZE_MINIMIZED
)
462 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
464 g_wnd_cwidth
= LOWORD(lParam
); /* client width / height */
465 g_wnd_cheight
= HIWORD(lParam
);
468 g_wnd_clip
.right
= g_wnd_clip
.left
+ g_wnd_cwidth
;
469 g_wnd_clip
.bottom
= g_wnd_clip
.top
+ g_wnd_cheight
;
470 if (g_wnd_cwidth
< g_width
|| g_wnd_cheight
< g_height
)
472 SetScrollRange(g_Wnd
, SB_HORZ
, 0, g_width
- g_wnd_cwidth
, 1);
473 SetScrollRange(g_Wnd
, SB_VERT
, 0, g_height
- g_wnd_cheight
, 1);
475 oldxscroll
= g_xscroll
;
476 oldyscroll
= g_yscroll
;
477 if (g_wnd_cwidth
>= g_width
)
483 g_xscroll
= UI_MIN(g_xscroll
, g_width
- g_wnd_cwidth
);
485 if (g_wnd_cheight
>= g_height
)
491 g_yscroll
= UI_MIN(g_yscroll
, g_height
- g_wnd_cheight
);
493 mi_scroll(oldxscroll
- g_xscroll
, oldyscroll
- g_yscroll
);
494 if (wParam
== SIZE_RESTORED
|| wParam
== SIZE_MAXIMIZED
)
496 /* check the caps, num, and scroll lock here */
502 /*****************************************************************************/
504 handle_WM_SIZING(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
511 prect
= (LPRECT
) lParam
; /* total window rect */
512 width
= (prect
->right
- prect
->left
) - (g_xoff
* 2);
513 height
= (prect
->bottom
- prect
->top
) - (g_yoff
+ g_xoff
);
514 if (height
< g_height
|| width
< g_width
)
516 style
= GetWindowLongPtr(g_Wnd
, GWL_STYLE
);
517 if (!(style
& WS_HSCROLL
))
519 style
|= WS_HSCROLL
| WS_VSCROLL
;
520 SetWindowLongPtr(g_Wnd
, GWL_STYLE
, style
);
523 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
524 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
527 else if (height
>= g_height
&& width
>= g_width
)
529 style
= GetWindowLongPtr(g_Wnd
, GWL_STYLE
);
530 if (style
& WS_HSCROLL
)
532 style
&= ~WS_HSCROLL
;
533 style
&= ~WS_VSCROLL
;
534 SetWindowLongPtr(g_Wnd
, GWL_STYLE
, style
);
542 /*****************************************************************************/
544 handle_WM_HSCROLL(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
549 code
= (int) LOWORD(wParam
); /* scroll bar value */
550 if (code
== SB_LINELEFT
)
552 oldxscroll
= g_xscroll
;
554 g_xscroll
= UI_MAX(g_xscroll
, 0);
555 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
556 mi_scroll(oldxscroll
- g_xscroll
, 0);
558 else if (code
== SB_LINERIGHT
)
560 oldxscroll
= g_xscroll
;
562 g_xscroll
= UI_MIN(g_xscroll
, g_width
- g_wnd_cwidth
);
563 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
564 mi_scroll(oldxscroll
- g_xscroll
, 0);
566 else if (code
== SB_PAGELEFT
)
568 oldxscroll
= g_xscroll
;
569 g_xscroll
-= g_wnd_cwidth
/ 2;
570 g_xscroll
= UI_MAX(g_xscroll
, 0);
571 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
572 mi_scroll(oldxscroll
- g_xscroll
, 0);
574 else if (code
== SB_PAGERIGHT
)
576 oldxscroll
= g_xscroll
;
577 g_xscroll
+= g_wnd_cwidth
/ 2;
578 g_xscroll
= UI_MIN(g_xscroll
, g_width
- g_wnd_cwidth
);
579 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
580 mi_scroll(oldxscroll
- g_xscroll
, 0);
582 else if (code
== SB_BOTTOM
)
584 oldxscroll
= g_xscroll
;
585 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_TOP
)
591 oldxscroll
= g_xscroll
;
593 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
594 mi_scroll(oldxscroll
- g_xscroll
, 0);
596 else if (code
== SB_THUMBPOSITION
)
598 oldxscroll
= g_xscroll
;
599 g_xscroll
= (signed short) HIWORD(wParam
);
600 SetScrollPos(g_Wnd
, SB_HORZ
, g_xscroll
, 1);
601 mi_scroll(oldxscroll
- g_xscroll
, 0);
606 /*****************************************************************************/
608 handle_WM_VSCROLL(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
613 code
= (int) LOWORD(wParam
); /* scroll bar value */
614 if (code
== SB_LINELEFT
)
616 oldyscroll
= g_yscroll
;
618 g_yscroll
= UI_MAX(g_yscroll
, 0);
619 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
620 mi_scroll(0, oldyscroll
- g_yscroll
);
622 else if (code
== SB_LINERIGHT
)
624 oldyscroll
= g_yscroll
;
626 g_yscroll
= UI_MIN(g_yscroll
, g_height
- g_wnd_cheight
);
627 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
628 mi_scroll(0, oldyscroll
- g_yscroll
);
630 else if (code
== SB_PAGELEFT
)
632 oldyscroll
= g_yscroll
;
633 g_yscroll
-= g_wnd_cheight
/ 2;
634 g_yscroll
= UI_MAX(g_yscroll
, 0);
635 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
636 mi_scroll(0, oldyscroll
- g_yscroll
);
638 else if (code
== SB_PAGERIGHT
)
640 oldyscroll
= g_yscroll
;
641 g_yscroll
+= g_wnd_cheight
/ 2;
642 g_yscroll
= UI_MIN(g_yscroll
, g_height
- g_wnd_cheight
);
643 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
644 mi_scroll(0, oldyscroll
- g_yscroll
);
646 else if (code
== SB_BOTTOM
)
648 oldyscroll
= g_yscroll
;
649 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_TOP
)
655 oldyscroll
= g_yscroll
;
657 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
658 mi_scroll(0, oldyscroll
- g_yscroll
);
660 else if (code
== SB_THUMBPOSITION
)
662 oldyscroll
= g_yscroll
;
663 g_yscroll
= (signed short) HIWORD(wParam
);
664 SetScrollPos(g_Wnd
, SB_VERT
, g_yscroll
, 1);
665 mi_scroll(0, oldyscroll
- g_yscroll
);
671 /*****************************************************************************/
673 WndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
678 return handle_WM_SETCURSOR(hWnd
, message
, wParam
, lParam
);
679 case 0x0084: /* WinCE don't have this WM_NCHITTEST: */
680 return handle_WM_NCHITTEST(hWnd
, message
, wParam
, lParam
);
682 return handle_WM_MOUSEMOVE(hWnd
, message
, wParam
, lParam
);
684 return handle_WM_LBUTTONDOWN(hWnd
, message
, wParam
, lParam
);
686 return handle_WM_LBUTTONUP(hWnd
, message
, wParam
, lParam
);
688 return handle_WM_RBUTTONDOWN(hWnd
, message
, wParam
, lParam
);
690 return handle_WM_RBUTTONUP(hWnd
, message
, wParam
, lParam
);
692 return handle_WM_MBUTTONDOWN(hWnd
, message
, wParam
, lParam
);
694 return handle_WM_MBUTTONUP(hWnd
, message
, wParam
, lParam
);
695 /* some windows compilers don't have these defined like vc6 */
696 case 0x020a: /* WM_MOUSEWHEEL: */
697 return handle_WM_MOUSEWHEEL(hWnd
, message
, wParam
, lParam
);
702 return handle_WM_KEY(hWnd
, message
, wParam
, lParam
);
709 return handle_WM_PAINT(hWnd
, message
, wParam
, lParam
);
718 return handle_WM_SIZE(hWnd
, message
, wParam
, lParam
);
719 case 532: /* not defined in wince WM_SIZING: */
720 return handle_WM_SIZING(hWnd
, message
, wParam
, lParam
);
722 return handle_WM_HSCROLL(hWnd
, message
, wParam
, lParam
);
724 return handle_WM_VSCROLL(hWnd
, message
, wParam
, lParam
);
727 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
729 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
734 /*****************************************************************************/
740 rgn
= CreateRectRgn(g_clip_left
+ g_xoff
- g_xscroll
,
741 g_clip_top
+ g_yoff
- g_yscroll
,
742 g_clip_right
+ g_xoff
- g_xscroll
,
743 g_clip_bottom
+ g_yoff
- g_yscroll
);
744 SelectClipRgn(dc
, rgn
);
745 IntersectClipRect(dc
, g_wnd_clip
.left
+ g_xoff
, g_wnd_clip
.top
+ g_yoff
,
746 g_wnd_clip
.right
+ g_xoff
, g_wnd_clip
.bottom
+ g_yoff
);
750 /*****************************************************************************/
751 /* returns non zero if ok */
753 mi_create_window(void)
757 TCHAR classname
[512];
765 if (g_Wnd
!= 0 || g_Instance
!= 0)
769 g_Instance
= GetModuleHandle(NULL
);
770 ZeroMemory(&wc
, sizeof(wc
));
771 wc
.lpfnWndProc
= WndProc
; /* points to window procedure */
772 /* name of window class */
773 str_to_uni(classname
, "rdesktop");
774 wc
.lpszClassName
= classname
;
775 str_to_uni(caption
, "ReactOS Remote Desktop");
776 wc
.hIcon
= LoadIcon(g_Instance
,
777 MAKEINTRESOURCE(IDI_MSTSC
));
778 /* Register the window class. */
779 if (!RegisterClass(&wc
))
781 return 0; /* Failed to register window class */
784 rc
.right
= rc
.left
+ UI_MIN(g_width
, g_screen_width
);
786 rc
.bottom
= rc
.top
+ UI_MIN(g_height
, g_screen_height
);
794 style
= WS_OVERLAPPED
| WS_CAPTION
| WS_POPUP
| WS_MINIMIZEBOX
|
795 WS_SYSMENU
| WS_SIZEBOX
| WS_MAXIMIZEBOX
;
797 if (g_screen_width
< g_width
|| g_screen_height
< g_height
)
799 style
|= WS_HSCROLL
| WS_VSCROLL
;
801 AdjustWindowRectEx(&rc
, style
, 0, 0);
804 w
= rc
.right
- rc
.left
;
805 h
= rc
.bottom
- rc
.top
;
807 g_Wnd
= CreateWindow(wc
.lpszClassName
, caption
,
809 (HWND
) NULL
, (HMENU
) NULL
, g_Instance
,
813 g_clip_right
= g_clip_left
+ g_width
;
814 g_clip_bottom
= g_clip_top
+ g_height
;
817 ShowWindow(g_Wnd
, SW_SHOWMAXIMIZED
);
821 ShowWindow(g_Wnd
, SW_SHOWNORMAL
);
825 WSAAsyncSelect(g_tcp_sck
, g_Wnd
, WM_APP
+ 1, FD_READ
);
826 SetTimer(g_Wnd
, 1, 333, 0);
831 /*****************************************************************************/
837 while (GetMessage(&msg
, NULL
, 0, 0))
839 TranslateMessage(&msg
);
840 DispatchMessage(&msg
);
845 /*****************************************************************************/
847 mi_warning(char * msg
)
851 /*****************************************************************************/
853 mi_show_error(char * caption
)
858 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
859 NULL
, GetLastError(), MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
860 (LPTSTR
) &lpMsgBuf
, 0, NULL
);
863 #else /* WITH_DEBUG */
864 str_to_uni(lcaption
, caption
);
865 MessageBox(g_Wnd
, (LPTSTR
) lpMsgBuf
, lcaption
,
866 MB_OK
| MB_ICONINFORMATION
);
867 #endif /* WITH_DEBUG */
871 /*****************************************************************************/
873 mi_paint_rect(char * data
, int width
, int height
, int x
, int y
, int cx
, int cy
)
889 ZeroMemory(&bi
, sizeof(bi
));
890 bi
.bmiHeader
.biSize
= sizeof(bi
.bmiHeader
);
891 bi
.bmiHeader
.biWidth
= width
;
892 bi
.bmiHeader
.biHeight
= -height
;
893 bi
.bmiHeader
.biPlanes
= 1;
894 bi
.bmiHeader
.biBitCount
= 32;
895 bi
.bmiHeader
.biCompression
= BI_RGB
;
896 maindc
= GetWindowDC(g_Wnd
);
897 bitmap
= CreateDIBSection(maindc
, &bi
, DIB_RGB_COLORS
, (void **) &bits
, 0, 0);
900 mi_show_error("CreateDIBSection failed");
903 if (g_server_depth
== 8)
905 for (i
= cy
- 1; i
>= 0; i
--)
907 for (j
= cx
- 1; j
>= 0; j
--)
909 colour
= ((unsigned char*)data
)[i
* cx
+ j
];
910 red
= (pal_entries
[colour
& 0xff] & 0xff0000) >> 16;
911 green
= (pal_entries
[colour
& 0xff] & 0xff00) >> 8;
912 blue
= pal_entries
[colour
& 0xff] & 0xff;
913 MAKE_COLOUR32(colour
, red
, green
, blue
);
914 ((unsigned int*)bits
)[i
* cx
+ j
] = colour
;
918 else if (g_server_depth
== 15)
920 for (i
= cy
- 1; i
>= 0; i
--)
922 for (j
= cx
- 1; j
>= 0; j
--)
924 colour
= ((unsigned short*)data
)[i
* cx
+ j
];
925 SPLIT_COLOUR15(colour
, red
, green
, blue
);
926 MAKE_COLOUR32(colour
, red
, green
, blue
);
927 ((unsigned int*)bits
)[i
* cx
+ j
] = colour
;
931 else if (g_server_depth
== 16)
933 for (i
= cy
- 1; i
>= 0; i
--)
935 for (j
= cx
- 1; j
>= 0; j
--)
937 colour
= ((unsigned short*)data
)[i
* cx
+ j
];
938 SPLIT_COLOUR16(colour
, red
, green
, blue
);
939 MAKE_COLOUR32(colour
, red
, green
, blue
);
940 ((unsigned int*)bits
)[i
* cx
+ j
] = colour
;
944 dc
= CreateCompatibleDC(maindc
);
947 mi_show_error("CreateCompatibleDC failed");
949 save
= SelectObject(dc
, bitmap
);
950 rgn
= mi_clip(maindc
);
951 BitBlt(maindc
, x
+ g_xoff
- g_xscroll
, y
+ g_yoff
- g_yscroll
, cx
, cy
, dc
,
953 SelectObject(dc
, save
);
954 DeleteObject(bitmap
);
956 ReleaseDC(g_Wnd
, maindc
);
962 GetPortNumber(PCHAR szAddress
)
965 INT iPort
= TCP_PORT_RDP
;
967 szPort
= strtok(szAddress
, ":");
971 szPort
= strtok(NULL
, ":");
975 iPort
= atoi(szPort
);
977 if (iPort
<= 0 || iPort
> 0xFFFF)
978 iPort
= TCP_PORT_RDP
;
986 SetDomainAndUsername(PCHAR pName
)
991 strcpy(g_domain
, "");
992 strcpy(g_username
, "");
994 pDomain
= strtok(pName
, "\\");
999 pUsername
= strtok(NULL
, "\\");
1001 if(pUsername
== NULL
)
1003 strcpy(g_username
, pDomain
);
1007 strcpy(g_username
, pUsername
);
1008 strcpy(g_domain
, pDomain
);
1013 ParseCommandLine(LPWSTR lpCmdLine
,
1014 PRDPSETTINGS pRdpSettings
,
1017 LPWSTR lpStr
= lpCmdLine
;
1018 WCHAR szSeps
[] = L
"/";
1024 if (*lpCmdLine
!= L
'/')
1026 LoadRdpSettingsFromFile(pRdpSettings
, lpCmdLine
);
1030 /* default to screen size, 16bpp */
1031 SetIntegerToSettings(pRdpSettings
, L
"session bpp", 16);
1032 SetIntegerToSettings(pRdpSettings
, L
"desktopwidth", GetSystemMetrics(SM_CXSCREEN
));
1033 SetIntegerToSettings(pRdpSettings
, L
"desktopheight", GetSystemMetrics(SM_CYSCREEN
));
1035 lpToken
= wcstok(lpStr
, szSeps
);
1038 if (wcsncmp(lpToken
, L
"edit", 4) == 0)
1041 LoadRdpSettingsFromFile(pRdpSettings
, lpToken
);
1046 if (*lpToken
== L
'v')
1049 SetStringToSettings(pRdpSettings
, L
"full address", lpToken
);
1051 else if (*lpToken
== L
'w')
1054 SetIntegerToSettings(pRdpSettings
, L
"desktopwidth", _wtoi(lpToken
));
1056 else if (*lpToken
== L
'h')
1059 SetIntegerToSettings(pRdpSettings
, L
"desktopheight", _wtoi(lpToken
));
1061 else if (*lpToken
== L
'f')
1063 SetIntegerToSettings(pRdpSettings
, L
"screen mode id", 2);
1066 lpToken
= wcstok(NULL
, szSeps
);
1073 /*****************************************************************************/
1075 wWinMain(HINSTANCE hInstance
,
1076 HINSTANCE hPrevInstance
,
1080 PRDPSETTINGS pRdpSettings
;
1084 if (WSAStartup(MAKEWORD(2, 0), &d
) == 0)
1086 pRdpSettings
= HeapAlloc(GetProcessHeap(),
1088 sizeof(RDPSETTINGS
));
1091 pRdpSettings
->pSettings
= NULL
;
1092 pRdpSettings
->NumSettings
= 0;
1094 if (InitRdpSettings(pRdpSettings
))
1096 BOOL bSkipDlg
= FALSE
;
1099 ParseCommandLine(lpCmdLine
, pRdpSettings
,&bSkipDlg
);
1101 LoadRdpSettingsFromFile(pRdpSettings
, NULL
);
1103 if (bSkipDlg
|| OpenRDPConnectDialog(hInstance
,
1106 char szValue
[MAXVALUE
];
1108 uni_to_str(szValue
, GetStringFromSettings(pRdpSettings
, L
"full address"));
1110 /* GetPortNumber also removes possible trailing port number from address */
1111 g_tcp_port_rdp
= GetPortNumber(szValue
);
1112 strcpy(g_servername
, szValue
);
1113 uni_to_str(szValue
, GetStringFromSettings(pRdpSettings
, L
"username"));
1114 SetDomainAndUsername(szValue
);
1115 strcpy(g_password
, "");
1116 g_server_depth
= GetIntegerFromSettings(pRdpSettings
, L
"session bpp");
1117 if (g_server_depth
> 16) g_server_depth
= 16; /* hack, we don't support 24bpp yet */
1118 g_screen_width
= GetSystemMetrics(SM_CXSCREEN
);
1119 g_screen_height
= GetSystemMetrics(SM_CYSCREEN
);
1120 g_width
= GetIntegerFromSettings(pRdpSettings
, L
"desktopwidth");
1121 g_height
= GetIntegerFromSettings(pRdpSettings
, L
"desktopheight");
1122 if (GetIntegerFromSettings(pRdpSettings
, L
"screen mode id") == 2)
1130 g_xoff
= GetSystemMetrics(SM_CXEDGE
) * 2;
1131 g_yoff
= GetSystemMetrics(SM_CYCAPTION
) + GetSystemMetrics(SM_CYEDGE
) * 2;
1138 HeapFree(GetProcessHeap(),
1140 pRdpSettings
->pSettings
);
1143 HeapFree(GetProcessHeap(),
1155 /*****************************************************************************/
1157 mi_begin_update(void)
1161 /*****************************************************************************/
1167 /*****************************************************************************/
1169 mi_fill_rect(int x
, int y
, int cx
, int cy
, int colour
)
1179 if (g_server_depth
== 8)
1181 red
= (pal_entries
[colour
& 0xff] & 0xff0000) >> 16;
1182 green
= (pal_entries
[colour
& 0xff] & 0xff00) >> 8;
1183 blue
= pal_entries
[colour
& 0xff] & 0xff;
1185 else if (g_server_depth
== 15)
1187 SPLIT_COLOUR15(colour
, red
, green
, blue
);
1189 else if (g_server_depth
== 16)
1191 SPLIT_COLOUR16(colour
, red
, green
, blue
);
1199 maindc
= GetWindowDC(g_Wnd
);
1200 rgn
= mi_clip(maindc
);
1201 brush
= CreateSolidBrush(RGB(red
, green
, blue
));
1202 rect
.left
= x
+ g_xoff
- g_xscroll
;
1203 rect
.top
= y
+ g_yoff
- g_yscroll
;
1204 rect
.right
= rect
.left
+ cx
;
1205 rect
.bottom
= rect
.top
+ cy
;
1206 FillRect(maindc
, &rect
, brush
);
1207 DeleteObject(brush
);
1208 ReleaseDC(g_Wnd
, maindc
);
1212 /*****************************************************************************/
1214 mi_line(int x1
, int y1
, int x2
, int y2
, int colour
)
1224 if (g_server_depth
== 8)
1226 red
= (pal_entries
[colour
& 0xff] & 0xff0000) >> 16;
1227 green
= (pal_entries
[colour
& 0xff] & 0xff00) >> 8;
1228 blue
= pal_entries
[colour
& 0xff] & 0xff;
1230 else if (g_server_depth
== 15)
1232 SPLIT_COLOUR15(colour
, red
, green
, blue
);
1234 else if (g_server_depth
== 16)
1236 SPLIT_COLOUR16(colour
, red
, green
, blue
);
1244 maindc
= GetWindowDC(g_Wnd
);
1245 rgn
= mi_clip(maindc
);
1246 pen
= CreatePen(PS_SOLID
, 0, RGB(red
, green
, blue
));
1247 save
= SelectObject(maindc
, pen
);
1248 MoveToEx(maindc
, x1
+ g_xoff
- g_xscroll
, y1
+ g_yoff
- g_yscroll
, 0);
1249 LineTo(maindc
, x2
+ g_xoff
- g_xscroll
, y2
+ g_yoff
- g_yscroll
);
1250 SelectObject(maindc
, save
);
1252 ReleaseDC(g_Wnd
, maindc
);
1256 /*****************************************************************************/
1258 mi_screen_copy(int x
, int y
, int cx
, int cy
, int srcx
, int srcy
)
1264 int ok_to_ScrollWindowEx
;
1266 ok_to_ScrollWindowEx
= 1;
1268 if (!ok_to_ScrollWindowEx
)
1270 rgn
= CreateRectRgn(x
- g_xscroll
, y
- g_yscroll
,
1271 (x
- g_xscroll
) + cx
,
1272 (y
- g_yscroll
) + cy
);
1273 InvalidateRgn(g_Wnd
, rgn
, 0);
1278 /* this is all in client coords */
1279 rect
.left
= srcx
- g_xscroll
;
1280 rect
.top
= srcy
- g_yscroll
;
1281 rect
.right
= rect
.left
+ cx
;
1282 rect
.bottom
= rect
.top
+ cy
;
1283 clip_rect
.left
= g_clip_left
- g_xscroll
;
1284 clip_rect
.top
= g_clip_top
- g_yscroll
;
1285 clip_rect
.right
= g_clip_right
- g_xscroll
;
1286 clip_rect
.bottom
= g_clip_bottom
- g_yscroll
;
1287 if (IntersectRect(&draw_rect
, &clip_rect
, &g_wnd_clip
))
1289 rgn
= CreateRectRgn(0, 0, 0, 0);
1290 ScrollWindowEx(g_Wnd
, x
- srcx
, y
- srcy
, &rect
, &draw_rect
,
1292 InvalidateRgn(g_Wnd
, rgn
, 0);
1298 /*****************************************************************************/
1300 mi_set_clip(int x
, int y
, int cx
, int cy
)
1304 g_clip_right
= g_clip_left
+ cx
;
1305 g_clip_bottom
= g_clip_top
+ cy
;
1308 /*****************************************************************************/
1314 g_clip_right
= g_clip_left
+ g_width
;
1315 g_clip_bottom
= g_clip_top
+ g_height
;
1318 /*****************************************************************************/
1320 mi_create_cursor(unsigned int x
, unsigned int y
,
1321 int width
, int height
,
1322 unsigned char * andmask
, unsigned char * xormask
)
1326 hCur
= CreateCursor(g_Instance
, x
, y
, width
, height
, andmask
, xormask
);
1329 hCur
= LoadCursor(NULL
, IDC_ARROW
);
1334 /*****************************************************************************/
1336 mi_destroy_cursor(void * cursor
)
1338 if (g_cursor
== cursor
)
1342 DestroyCursor(cursor
);
1345 /*****************************************************************************/
1347 mi_set_cursor(void * cursor
)
1350 SetCursor(g_cursor
);
1353 /*****************************************************************************/
1355 mi_set_null_cursor(void)