xref: /reactos/base/applications/mstsc/win32.c (revision c2c66aff)
1*c2c66affSColin Finck /* -*- c-basic-offset: 8 -*-
2*c2c66affSColin Finck    rdesktop: A Remote Desktop Protocol client.
3*c2c66affSColin Finck    win32 calls
4*c2c66affSColin Finck    Copyright (C) Jay Sorg 2006
5*c2c66affSColin Finck 
6*c2c66affSColin Finck    This program is free software; you can redistribute it and/or modify
7*c2c66affSColin Finck    it under the terms of the GNU General Public License as published by
8*c2c66affSColin Finck    the Free Software Foundation; either version 2 of the License, or
9*c2c66affSColin Finck    (at your option) any later version.
10*c2c66affSColin Finck 
11*c2c66affSColin Finck    This program is distributed in the hope that it will be useful,
12*c2c66affSColin Finck    but WITHOUT ANY WARRANTY; without even the implied warranty of
13*c2c66affSColin Finck    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*c2c66affSColin Finck    GNU General Public License for more details.
15*c2c66affSColin Finck 
16*c2c66affSColin Finck    You should have received a copy of the GNU General Public License along
17*c2c66affSColin Finck    with this program; if not, write to the Free Software Foundation, Inc.,
18*c2c66affSColin Finck    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*c2c66affSColin Finck */
20*c2c66affSColin Finck 
21*c2c66affSColin Finck #include "precomp.h"
22*c2c66affSColin Finck 
23*c2c66affSColin Finck #include "uimain.h"
24*c2c66affSColin Finck 
25*c2c66affSColin Finck extern char g_username[];
26*c2c66affSColin Finck extern char g_hostname[];
27*c2c66affSColin Finck extern char g_servername[];
28*c2c66affSColin Finck extern char g_password[];
29*c2c66affSColin Finck extern char g_shell[];
30*c2c66affSColin Finck extern char g_directory[];
31*c2c66affSColin Finck extern char g_domain[];
32*c2c66affSColin Finck extern int g_width;
33*c2c66affSColin Finck extern int g_height;
34*c2c66affSColin Finck extern int g_tcp_sck;
35*c2c66affSColin Finck extern int g_server_depth;
36*c2c66affSColin Finck extern int g_tcp_port_rdp; /* in tcp.c */
37*c2c66affSColin Finck extern int pal_entries[];
38*c2c66affSColin Finck 
39*c2c66affSColin Finck static HWND g_Wnd = 0;
40*c2c66affSColin Finck static HINSTANCE g_Instance = 0;
41*c2c66affSColin Finck static HCURSOR g_cursor = 0;
42*c2c66affSColin Finck static int g_block = 0;
43*c2c66affSColin Finck static int g_xoff = 0; /* offset from window to client coords */
44*c2c66affSColin Finck static int g_yoff = 0;
45*c2c66affSColin Finck static int g_xscroll = 0; /* current scroll position */
46*c2c66affSColin Finck static int g_yscroll = 0;
47*c2c66affSColin Finck static int g_screen_width = 0;
48*c2c66affSColin Finck static int g_screen_height = 0;
49*c2c66affSColin Finck static int g_wnd_cwidth = 0; /* set from WM_SIZE */
50*c2c66affSColin Finck static int g_wnd_cheight = 0;
51*c2c66affSColin Finck static int g_fullscreen = 0;
52*c2c66affSColin Finck static int g_workarea = 0;
53*c2c66affSColin Finck static int g_mousex = 0; /* in client coords */
54*c2c66affSColin Finck static int g_mousey = 0;
55*c2c66affSColin Finck //static int g_width_height_set = 0;
56*c2c66affSColin Finck 
57*c2c66affSColin Finck static int g_clip_left = 0;
58*c2c66affSColin Finck static int g_clip_top = 0;
59*c2c66affSColin Finck static int g_clip_right = 800;
60*c2c66affSColin Finck static int g_clip_bottom = 600;
61*c2c66affSColin Finck static RECT g_wnd_clip; /* this client area of whats actually visible */
62*c2c66affSColin Finck                         /* set from WM_SIZE */
63*c2c66affSColin Finck 
64*c2c66affSColin Finck /*****************************************************************************/
65*c2c66affSColin Finck static void
str_to_uni(TCHAR * sizex,char * size1)66*c2c66affSColin Finck str_to_uni(TCHAR * sizex, char * size1)
67*c2c66affSColin Finck {
68*c2c66affSColin Finck   int len;
69*c2c66affSColin Finck   int i;
70*c2c66affSColin Finck 
71*c2c66affSColin Finck   len = strlen(size1);
72*c2c66affSColin Finck   for (i = 0; i < len; i++)
73*c2c66affSColin Finck   {
74*c2c66affSColin Finck     sizex[i] = size1[i];
75*c2c66affSColin Finck   }
76*c2c66affSColin Finck   sizex[len] = 0;
77*c2c66affSColin Finck }
78*c2c66affSColin Finck 
79*c2c66affSColin Finck /*****************************************************************************/
80*c2c66affSColin Finck static void
uni_to_str(char * sizex,TCHAR * size1)81*c2c66affSColin Finck uni_to_str(char * sizex, TCHAR * size1)
82*c2c66affSColin Finck {
83*c2c66affSColin Finck   int len;
84*c2c66affSColin Finck   int i;
85*c2c66affSColin Finck 
86*c2c66affSColin Finck   len = lstrlen(size1);
87*c2c66affSColin Finck   for (i = 0; i < len; i++)
88*c2c66affSColin Finck   {
89*c2c66affSColin Finck     sizex[i] = (char)size1[i];
90*c2c66affSColin Finck   }
91*c2c66affSColin Finck   sizex[len] = 0;
92*c2c66affSColin Finck }
93*c2c66affSColin Finck 
94*c2c66affSColin Finck /*****************************************************************************/
95*c2c66affSColin Finck /* returns non zero if it processed something */
96*c2c66affSColin Finck static int
check_sck(void)97*c2c66affSColin Finck check_sck(void)
98*c2c66affSColin Finck {
99*c2c66affSColin Finck   fd_set rfds;
100*c2c66affSColin Finck   struct timeval tm;
101*c2c66affSColin Finck   int count;
102*c2c66affSColin Finck   int rv;
103*c2c66affSColin Finck 
104*c2c66affSColin Finck   rv = 0;
105*c2c66affSColin Finck   if (g_block == 0)
106*c2c66affSColin Finck   {
107*c2c66affSColin Finck     g_block = 1;
108*c2c66affSColin Finck     /* see if there really is data */
109*c2c66affSColin Finck     FD_ZERO(&rfds);
110*c2c66affSColin Finck     FD_SET((unsigned int)g_tcp_sck, &rfds);
111*c2c66affSColin Finck     ZeroMemory(&tm, sizeof(tm));
112*c2c66affSColin Finck     count = select(g_tcp_sck + 1, &rfds, 0, 0, &tm);
113*c2c66affSColin Finck     if (count > 0)
114*c2c66affSColin Finck     {
115*c2c66affSColin Finck       if (ui_read_wire())
116*c2c66affSColin Finck       {
117*c2c66affSColin Finck         rv = 1;
118*c2c66affSColin Finck       }
119*c2c66affSColin Finck       else
120*c2c66affSColin Finck       {
121*c2c66affSColin Finck         PostQuitMessage(0);
122*c2c66affSColin Finck       }
123*c2c66affSColin Finck     }
124*c2c66affSColin Finck     g_block = 0;
125*c2c66affSColin Finck   }
126*c2c66affSColin Finck   return rv;
127*c2c66affSColin Finck }
128*c2c66affSColin Finck 
129*c2c66affSColin Finck /*****************************************************************************/
130*c2c66affSColin Finck void
mi_error(char * msg)131*c2c66affSColin Finck mi_error(char * msg)
132*c2c66affSColin Finck {
133*c2c66affSColin Finck #ifdef WITH_DEBUG
134*c2c66affSColin Finck   printf(msg);
135*c2c66affSColin Finck #else /* WITH_DEBUG */
136*c2c66affSColin Finck   TCHAR lmsg[512];
137*c2c66affSColin Finck   TCHAR ltitle[512];
138*c2c66affSColin Finck 
139*c2c66affSColin Finck   str_to_uni(lmsg, msg);
140*c2c66affSColin Finck   str_to_uni(ltitle, "Error");
141*c2c66affSColin Finck   MessageBox(g_Wnd, lmsg, ltitle, MB_OK);
142*c2c66affSColin Finck #endif /* WITH_DEBUG */
143*c2c66affSColin Finck }
144*c2c66affSColin Finck 
145*c2c66affSColin Finck /*****************************************************************************/
146*c2c66affSColin Finck static int
get_scan_code_from_ascii(int code)147*c2c66affSColin Finck get_scan_code_from_ascii(int code)
148*c2c66affSColin Finck {
149*c2c66affSColin Finck   int rv;
150*c2c66affSColin Finck 
151*c2c66affSColin Finck   rv = 0;
152*c2c66affSColin Finck   switch (code & 0xff)
153*c2c66affSColin Finck   {
154*c2c66affSColin Finck     case 0x30: rv = 0x0b; break; // 0
155*c2c66affSColin Finck     case 0x31: rv = 0x02; break; // 1
156*c2c66affSColin Finck     case 0x32: rv = 0x03; break; // 2
157*c2c66affSColin Finck     case 0x33: rv = 0x04; break; // 3
158*c2c66affSColin Finck     case 0x34: rv = 0x05; break; // 4
159*c2c66affSColin Finck     case 0x35: rv = 0x06; break; // 5
160*c2c66affSColin Finck     case 0x36: rv = 0x07; break; // 6
161*c2c66affSColin Finck     case 0x37: rv = 0x08; break; // 7
162*c2c66affSColin Finck     case 0x38: rv = 0x09; break; // 8
163*c2c66affSColin Finck     case 0x39: rv = 0x0a; break; // 9
164*c2c66affSColin Finck 
165*c2c66affSColin Finck     case 0xbd: rv = 0x0c; break; // -
166*c2c66affSColin Finck     case 0xbb: rv = 0x0d; break; // =
167*c2c66affSColin Finck     case 0x08: rv = 0x0e; break; // backspace
168*c2c66affSColin Finck     case 0x09: rv = 0x0f; break; // tab
169*c2c66affSColin Finck     case 0xdb: rv = 0x1b; break; // ]
170*c2c66affSColin Finck     case 0xdd: rv = 0x1a; break; // [
171*c2c66affSColin Finck     case 0x14: rv = 0x3a; break; // capslock
172*c2c66affSColin Finck     case 0xba: rv = 0x27; break; // ;
173*c2c66affSColin Finck     case 0xde: rv = 0x28; break; // '
174*c2c66affSColin Finck     case 0x10: rv = 0x2a; break; // shift
175*c2c66affSColin Finck     case 0xbc: rv = 0x33; break; // ,
176*c2c66affSColin Finck     case 0xbe: rv = 0x34; break; // .
177*c2c66affSColin Finck     case 0xbf: rv = 0x35; break; // /
178*c2c66affSColin Finck     case 0x0d: rv = 0x1c; break; // enter
179*c2c66affSColin Finck     case 0x27: rv = 0x4d; break; // arrow right
180*c2c66affSColin Finck     case 0x25: rv = 0x4b; break; // arrow left
181*c2c66affSColin Finck     case 0x26: rv = 0x48; break; // arrow up
182*c2c66affSColin Finck     case 0x28: rv = 0x50; break; // arrow down
183*c2c66affSColin Finck     case 0x20: rv = 0x39; break; // space
184*c2c66affSColin Finck     case 0xdc: rv = 0x2b; break; // backslash
185*c2c66affSColin Finck     case 0xc0: rv = 0x29; break; // `
186*c2c66affSColin Finck     case 0x11: rv = 0x1d; break; // ctl
187*c2c66affSColin Finck 
188*c2c66affSColin Finck     case 0x41: rv = 0x1e; break; // a
189*c2c66affSColin Finck     case 0x42: rv = 0x30; break; // b
190*c2c66affSColin Finck     case 0x43: rv = 0x2e; break; // c
191*c2c66affSColin Finck     case 0x44: rv = 0x20; break; // d
192*c2c66affSColin Finck     case 0x45: rv = 0x12; break; // e
193*c2c66affSColin Finck     case 0x46: rv = 0x21; break; // f
194*c2c66affSColin Finck     case 0x47: rv = 0x22; break; // g
195*c2c66affSColin Finck     case 0x48: rv = 0x23; break; // h
196*c2c66affSColin Finck     case 0x49: rv = 0x17; break; // i
197*c2c66affSColin Finck     case 0x4a: rv = 0x24; break; // j
198*c2c66affSColin Finck     case 0x4b: rv = 0x25; break; // k
199*c2c66affSColin Finck     case 0x4c: rv = 0x26; break; // l
200*c2c66affSColin Finck     case 0x4d: rv = 0x32; break; // m
201*c2c66affSColin Finck     case 0x4e: rv = 0x31; break; // n
202*c2c66affSColin Finck     case 0x4f: rv = 0x18; break; // o
203*c2c66affSColin Finck     case 0x50: rv = 0x19; break; // p
204*c2c66affSColin Finck     case 0x51: rv = 0x10; break; // q
205*c2c66affSColin Finck     case 0x52: rv = 0x13; break; // r
206*c2c66affSColin Finck     case 0x53: rv = 0x1f; break; // s
207*c2c66affSColin Finck     case 0x54: rv = 0x14; break; // t
208*c2c66affSColin Finck     case 0x55: rv = 0x16; break; // u
209*c2c66affSColin Finck     case 0x56: rv = 0x2f; break; // v
210*c2c66affSColin Finck     case 0x57: rv = 0x11; break; // w
211*c2c66affSColin Finck     case 0x58: rv = 0x2d; break; // x
212*c2c66affSColin Finck     case 0x59: rv = 0x15; break; // y
213*c2c66affSColin Finck     case 0x5a: rv = 0x2c; break; // z
214*c2c66affSColin Finck   }
215*c2c66affSColin Finck   return rv;
216*c2c66affSColin Finck }
217*c2c66affSColin Finck 
218*c2c66affSColin Finck /*****************************************************************************/
219*c2c66affSColin Finck static void
mi_scroll(int dx,int dy)220*c2c66affSColin Finck mi_scroll(int dx, int dy)
221*c2c66affSColin Finck {
222*c2c66affSColin Finck   HRGN rgn;
223*c2c66affSColin Finck 
224*c2c66affSColin Finck   rgn = CreateRectRgn(0, 0, 0, 0);
225*c2c66affSColin Finck   ScrollWindowEx(g_Wnd, dx, dy, 0, 0, rgn, 0, SW_ERASE);
226*c2c66affSColin Finck   InvalidateRgn(g_Wnd, rgn, 0);
227*c2c66affSColin Finck   DeleteObject(rgn);
228*c2c66affSColin Finck }
229*c2c66affSColin Finck 
230*c2c66affSColin Finck /*****************************************************************************/
231*c2c66affSColin Finck int
mi_read_keyboard_state(void)232*c2c66affSColin Finck mi_read_keyboard_state(void)
233*c2c66affSColin Finck {
234*c2c66affSColin Finck   short keydata;
235*c2c66affSColin Finck   int code;
236*c2c66affSColin Finck 
237*c2c66affSColin Finck   code = 0;
238*c2c66affSColin Finck   keydata = GetKeyState(VK_SCROLL);
239*c2c66affSColin Finck   if (keydata & 0x0001)
240*c2c66affSColin Finck   {
241*c2c66affSColin Finck     code |= 1;
242*c2c66affSColin Finck   }
243*c2c66affSColin Finck   keydata = GetKeyState(VK_NUMLOCK);
244*c2c66affSColin Finck   if (keydata & 0x0001)
245*c2c66affSColin Finck   {
246*c2c66affSColin Finck     code |= 2;
247*c2c66affSColin Finck   }
248*c2c66affSColin Finck   keydata = GetKeyState(VK_CAPITAL);
249*c2c66affSColin Finck   if (keydata & 0x0001)
250*c2c66affSColin Finck   {
251*c2c66affSColin Finck     code |= 4;
252*c2c66affSColin Finck   }
253*c2c66affSColin Finck   return code;
254*c2c66affSColin Finck }
255*c2c66affSColin Finck 
256*c2c66affSColin Finck /*****************************************************************************/
257*c2c66affSColin Finck static void
mi_check_modifier(void)258*c2c66affSColin Finck mi_check_modifier(void)
259*c2c66affSColin Finck {
260*c2c66affSColin Finck   int code;
261*c2c66affSColin Finck 
262*c2c66affSColin Finck   code = mi_read_keyboard_state();
263*c2c66affSColin Finck   ui_set_modifier_state(code);
264*c2c66affSColin Finck }
265*c2c66affSColin Finck 
266*c2c66affSColin Finck /*****************************************************************************/
267*c2c66affSColin Finck static LRESULT
handle_WM_SETCURSOR(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)268*c2c66affSColin Finck handle_WM_SETCURSOR(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
269*c2c66affSColin Finck {
270*c2c66affSColin Finck   if (g_mousex >= g_wnd_clip.left &&
271*c2c66affSColin Finck       g_mousey >= g_wnd_clip.top &&
272*c2c66affSColin Finck       g_mousex < g_wnd_clip.right &&
273*c2c66affSColin Finck       g_mousey < g_wnd_clip.bottom)
274*c2c66affSColin Finck   {
275*c2c66affSColin Finck     SetCursor(g_cursor);
276*c2c66affSColin Finck   }
277*c2c66affSColin Finck   /* need default behavoir here */
278*c2c66affSColin Finck   return DefWindowProc(hWnd, message, wParam, lParam);
279*c2c66affSColin Finck }
280*c2c66affSColin Finck 
281*c2c66affSColin Finck /*****************************************************************************/
282*c2c66affSColin Finck static LRESULT
handle_WM_NCHITTEST(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)283*c2c66affSColin Finck handle_WM_NCHITTEST(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
284*c2c66affSColin Finck {
285*c2c66affSColin Finck   POINT pt;
286*c2c66affSColin Finck 
287*c2c66affSColin Finck   pt.x = LOWORD(lParam);
288*c2c66affSColin Finck   pt.y = HIWORD(lParam);
289*c2c66affSColin Finck   if (ScreenToClient(g_Wnd, &pt))
290*c2c66affSColin Finck   {
291*c2c66affSColin Finck     g_mousex = pt.x;
292*c2c66affSColin Finck     g_mousey = pt.y;
293*c2c66affSColin Finck   }
294*c2c66affSColin Finck   return DefWindowProc(hWnd, message, wParam, lParam);
295*c2c66affSColin Finck }
296*c2c66affSColin Finck 
297*c2c66affSColin Finck /*****************************************************************************/
298*c2c66affSColin Finck static LRESULT
handle_WM_MOUSEMOVE(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)299*c2c66affSColin Finck handle_WM_MOUSEMOVE(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
300*c2c66affSColin Finck {
301*c2c66affSColin Finck   g_mousex = LOWORD(lParam);
302*c2c66affSColin Finck   g_mousey = HIWORD(lParam);
303*c2c66affSColin Finck   ui_mouse_move(g_mousex + g_xscroll, g_mousey + g_yscroll);
304*c2c66affSColin Finck   return 0;
305*c2c66affSColin Finck }
306*c2c66affSColin Finck 
307*c2c66affSColin Finck /*****************************************************************************/
308*c2c66affSColin Finck static LRESULT
handle_WM_LBUTTONDOWN(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)309*c2c66affSColin Finck handle_WM_LBUTTONDOWN(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
310*c2c66affSColin Finck {
311*c2c66affSColin Finck   g_mousex = LOWORD(lParam);
312*c2c66affSColin Finck   g_mousey = HIWORD(lParam);
313*c2c66affSColin Finck   ui_mouse_button(1, g_mousex + g_xscroll, g_mousey + g_yscroll, 1);
314*c2c66affSColin Finck   return 0;
315*c2c66affSColin Finck }
316*c2c66affSColin Finck 
317*c2c66affSColin Finck /*****************************************************************************/
318*c2c66affSColin Finck static LRESULT
handle_WM_LBUTTONUP(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)319*c2c66affSColin Finck handle_WM_LBUTTONUP(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
320*c2c66affSColin Finck {
321*c2c66affSColin Finck   g_mousex = LOWORD(lParam);
322*c2c66affSColin Finck   g_mousey = HIWORD(lParam);
323*c2c66affSColin Finck   ui_mouse_button(1, g_mousex + g_xscroll, g_mousey + g_yscroll, 0);
324*c2c66affSColin Finck   return 0;
325*c2c66affSColin Finck }
326*c2c66affSColin Finck 
327*c2c66affSColin Finck /*****************************************************************************/
328*c2c66affSColin Finck static LRESULT
handle_WM_RBUTTONDOWN(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)329*c2c66affSColin Finck handle_WM_RBUTTONDOWN(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
330*c2c66affSColin Finck {
331*c2c66affSColin Finck   g_mousex = LOWORD(lParam);
332*c2c66affSColin Finck   g_mousey = HIWORD(lParam);
333*c2c66affSColin Finck   ui_mouse_button(2, g_mousex + g_xscroll, g_mousey + g_yscroll, 1);
334*c2c66affSColin Finck   return 0;
335*c2c66affSColin Finck }
336*c2c66affSColin Finck 
337*c2c66affSColin Finck /*****************************************************************************/
338*c2c66affSColin Finck static LRESULT
handle_WM_RBUTTONUP(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)339*c2c66affSColin Finck handle_WM_RBUTTONUP(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
340*c2c66affSColin Finck {
341*c2c66affSColin Finck   g_mousex = LOWORD(lParam);
342*c2c66affSColin Finck   g_mousey = HIWORD(lParam);
343*c2c66affSColin Finck   ui_mouse_button(2, g_mousex + g_xscroll, g_mousey + g_yscroll, 0);
344*c2c66affSColin Finck   return 0;
345*c2c66affSColin Finck }
346*c2c66affSColin Finck 
347*c2c66affSColin Finck /*****************************************************************************/
348*c2c66affSColin Finck static LRESULT
handle_WM_MBUTTONDOWN(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)349*c2c66affSColin Finck handle_WM_MBUTTONDOWN(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
350*c2c66affSColin Finck {
351*c2c66affSColin Finck   g_mousex = LOWORD(lParam);
352*c2c66affSColin Finck   g_mousey = HIWORD(lParam);
353*c2c66affSColin Finck   ui_mouse_button(3, g_mousex + g_xscroll, g_mousey + g_yscroll, 1);
354*c2c66affSColin Finck   return 0;
355*c2c66affSColin Finck }
356*c2c66affSColin Finck 
357*c2c66affSColin Finck /*****************************************************************************/
358*c2c66affSColin Finck static LRESULT
handle_WM_MBUTTONUP(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)359*c2c66affSColin Finck handle_WM_MBUTTONUP(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
360*c2c66affSColin Finck {
361*c2c66affSColin Finck   g_mousex = LOWORD(lParam);
362*c2c66affSColin Finck   g_mousey = HIWORD(lParam);
363*c2c66affSColin Finck   ui_mouse_button(3, g_mousex + g_xscroll, g_mousey + g_yscroll, 0);
364*c2c66affSColin Finck   return 0;
365*c2c66affSColin Finck }
366*c2c66affSColin Finck 
367*c2c66affSColin Finck /*****************************************************************************/
368*c2c66affSColin Finck static LRESULT
handle_WM_MOUSEWHEEL(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)369*c2c66affSColin Finck handle_WM_MOUSEWHEEL(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
370*c2c66affSColin Finck {
371*c2c66affSColin Finck   int delta;
372*c2c66affSColin Finck 
373*c2c66affSColin Finck   delta = ((signed short)HIWORD(wParam)); /* GET_WHEEL_DELTA_WPARAM(wParam); */
374*c2c66affSColin Finck   if (delta > 0)
375*c2c66affSColin Finck   {
376*c2c66affSColin Finck     ui_mouse_button(4, 0, 0, 1);
377*c2c66affSColin Finck     ui_mouse_button(4, 0, 0, 0);
378*c2c66affSColin Finck   }
379*c2c66affSColin Finck   else
380*c2c66affSColin Finck   {
381*c2c66affSColin Finck     ui_mouse_button(5, 0, 0, 1);
382*c2c66affSColin Finck     ui_mouse_button(5, 0, 0, 0);
383*c2c66affSColin Finck   }
384*c2c66affSColin Finck   return 0;
385*c2c66affSColin Finck }
386*c2c66affSColin Finck 
387*c2c66affSColin Finck /*****************************************************************************/
388*c2c66affSColin Finck static LRESULT
handle_WM_KEY(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)389*c2c66affSColin Finck handle_WM_KEY(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
390*c2c66affSColin Finck {
391*c2c66affSColin Finck   int scancode;
392*c2c66affSColin Finck   int ext;
393*c2c66affSColin Finck   int down;
394*c2c66affSColin Finck 
395*c2c66affSColin Finck   ext = HIWORD(lParam);
396*c2c66affSColin Finck   scancode = ext;
397*c2c66affSColin Finck   down = !(ext & 0x8000);
398*c2c66affSColin Finck   scancode &= 0xff;
399*c2c66affSColin Finck   if (scancode == 0)
400*c2c66affSColin Finck   {
401*c2c66affSColin Finck     scancode = get_scan_code_from_ascii(wParam);
402*c2c66affSColin Finck   }
403*c2c66affSColin Finck   ext &= 0x0100;
404*c2c66affSColin Finck   if (scancode == 0x0045) /* num lock */
405*c2c66affSColin Finck   {
406*c2c66affSColin Finck     ext &= ~0x0100;
407*c2c66affSColin Finck   }
408*c2c66affSColin Finck   if (down)
409*c2c66affSColin Finck   {
410*c2c66affSColin Finck     ui_key_down(scancode, ext);
411*c2c66affSColin Finck   }
412*c2c66affSColin Finck   else
413*c2c66affSColin Finck   {
414*c2c66affSColin Finck     ui_key_up(scancode, ext);
415*c2c66affSColin Finck   }
416*c2c66affSColin Finck   return 0;
417*c2c66affSColin Finck }
418*c2c66affSColin Finck 
419*c2c66affSColin Finck /*****************************************************************************/
420*c2c66affSColin Finck static LRESULT
handle_WM_PAINT(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)421*c2c66affSColin Finck handle_WM_PAINT(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
422*c2c66affSColin Finck {
423*c2c66affSColin Finck   PAINTSTRUCT ps;
424*c2c66affSColin Finck   RECT rect;
425*c2c66affSColin Finck   HBRUSH brush;
426*c2c66affSColin Finck 
427*c2c66affSColin Finck   BeginPaint(hWnd, &ps);
428*c2c66affSColin Finck   /* paint the area outside the rdp screen with one colour */
429*c2c66affSColin Finck   rect = ps.rcPaint;
430*c2c66affSColin Finck   rect.left = UI_MAX(rect.left, g_width);
431*c2c66affSColin Finck   if (!IsRectEmpty(&rect))
432*c2c66affSColin Finck   {
433*c2c66affSColin Finck     brush = CreateSolidBrush(RGB(0, 0, 255));
434*c2c66affSColin Finck     FillRect(ps.hdc, &rect, brush);
435*c2c66affSColin Finck     DeleteObject(brush);
436*c2c66affSColin Finck   }
437*c2c66affSColin Finck   rect = ps.rcPaint;
438*c2c66affSColin Finck   rect.top = UI_MAX(rect.top, g_height);
439*c2c66affSColin Finck   if (!IsRectEmpty(&rect))
440*c2c66affSColin Finck   {
441*c2c66affSColin Finck     brush = CreateSolidBrush(RGB(0, 0, 255));
442*c2c66affSColin Finck     FillRect(ps.hdc, &rect, brush);
443*c2c66affSColin Finck     DeleteObject(brush);
444*c2c66affSColin Finck   }
445*c2c66affSColin Finck   rect = ps.rcPaint;
446*c2c66affSColin Finck   EndPaint(hWnd, &ps);
447*c2c66affSColin Finck   ui_invalidate(rect.left + g_xscroll,
448*c2c66affSColin Finck                 rect.top + g_yscroll,
449*c2c66affSColin Finck                 (rect.right - rect.left) + 1,
450*c2c66affSColin Finck                 (rect.bottom - rect.top) + 1);
451*c2c66affSColin Finck   return 0;
452*c2c66affSColin Finck }
453*c2c66affSColin Finck 
454*c2c66affSColin Finck /*****************************************************************************/
455*c2c66affSColin Finck static LRESULT
handle_WM_SIZE(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)456*c2c66affSColin Finck handle_WM_SIZE(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
457*c2c66affSColin Finck {
458*c2c66affSColin Finck   int oldxscroll;
459*c2c66affSColin Finck   int oldyscroll;
460*c2c66affSColin Finck 
461*c2c66affSColin Finck   if (wParam == SIZE_MINIMIZED)
462*c2c66affSColin Finck   {
463*c2c66affSColin Finck     return DefWindowProc(hWnd, message, wParam, lParam);
464*c2c66affSColin Finck   }
465*c2c66affSColin Finck   g_wnd_cwidth = LOWORD(lParam); /* client width / height */
466*c2c66affSColin Finck   g_wnd_cheight = HIWORD(lParam);
467*c2c66affSColin Finck   g_wnd_clip.left = 0;
468*c2c66affSColin Finck   g_wnd_clip.top = 0;
469*c2c66affSColin Finck   g_wnd_clip.right = g_wnd_clip.left + g_wnd_cwidth;
470*c2c66affSColin Finck   g_wnd_clip.bottom = g_wnd_clip.top + g_wnd_cheight;
471*c2c66affSColin Finck   if (g_wnd_cwidth < g_width || g_wnd_cheight < g_height)
472*c2c66affSColin Finck   {
473*c2c66affSColin Finck     SetScrollRange(g_Wnd, SB_HORZ, 0, g_width - g_wnd_cwidth, 1);
474*c2c66affSColin Finck     SetScrollRange(g_Wnd, SB_VERT, 0, g_height - g_wnd_cheight, 1);
475*c2c66affSColin Finck   }
476*c2c66affSColin Finck   oldxscroll = g_xscroll;
477*c2c66affSColin Finck   oldyscroll = g_yscroll;
478*c2c66affSColin Finck   if (g_wnd_cwidth >= g_width)
479*c2c66affSColin Finck   {
480*c2c66affSColin Finck     g_xscroll = 0;
481*c2c66affSColin Finck   }
482*c2c66affSColin Finck   else
483*c2c66affSColin Finck   {
484*c2c66affSColin Finck     g_xscroll = UI_MIN(g_xscroll, g_width - g_wnd_cwidth);
485*c2c66affSColin Finck   }
486*c2c66affSColin Finck   if (g_wnd_cheight >= g_height)
487*c2c66affSColin Finck   {
488*c2c66affSColin Finck     g_yscroll = 0;
489*c2c66affSColin Finck   }
490*c2c66affSColin Finck   else
491*c2c66affSColin Finck   {
492*c2c66affSColin Finck     g_yscroll = UI_MIN(g_yscroll, g_height - g_wnd_cheight);
493*c2c66affSColin Finck   }
494*c2c66affSColin Finck   mi_scroll(oldxscroll - g_xscroll, oldyscroll - g_yscroll);
495*c2c66affSColin Finck   if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED)
496*c2c66affSColin Finck   {
497*c2c66affSColin Finck     /* check the caps, num, and scroll lock here */
498*c2c66affSColin Finck     mi_check_modifier();
499*c2c66affSColin Finck   }
500*c2c66affSColin Finck   return 0;
501*c2c66affSColin Finck }
502*c2c66affSColin Finck 
503*c2c66affSColin Finck /*****************************************************************************/
504*c2c66affSColin Finck static LRESULT
handle_WM_SIZING(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)505*c2c66affSColin Finck handle_WM_SIZING(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
506*c2c66affSColin Finck {
507*c2c66affSColin Finck   LPRECT prect;
508*c2c66affSColin Finck   int width;
509*c2c66affSColin Finck   int height;
510*c2c66affSColin Finck   int style;
511*c2c66affSColin Finck 
512*c2c66affSColin Finck   prect = (LPRECT) lParam; /* total window rect */
513*c2c66affSColin Finck   width = (prect->right - prect->left) - (g_xoff * 2);
514*c2c66affSColin Finck   height = (prect->bottom - prect->top) - (g_yoff + g_xoff);
515*c2c66affSColin Finck   if (height < g_height || width < g_width)
516*c2c66affSColin Finck   {
517*c2c66affSColin Finck     style = GetWindowLongPtr(g_Wnd, GWL_STYLE);
518*c2c66affSColin Finck     if (!(style & WS_HSCROLL))
519*c2c66affSColin Finck     {
520*c2c66affSColin Finck       style |= WS_HSCROLL | WS_VSCROLL;
521*c2c66affSColin Finck       SetWindowLongPtr(g_Wnd, GWL_STYLE, style);
522*c2c66affSColin Finck       g_xscroll = 0;
523*c2c66affSColin Finck       g_yscroll = 0;
524*c2c66affSColin Finck       SetScrollPos(g_Wnd, SB_HORZ, g_xscroll, 1);
525*c2c66affSColin Finck       SetScrollPos(g_Wnd, SB_VERT, g_yscroll, 1);
526*c2c66affSColin Finck     }
527*c2c66affSColin Finck   }
528*c2c66affSColin Finck   else if (height >= g_height && width >= g_width)
529*c2c66affSColin Finck   {
530*c2c66affSColin Finck     style = GetWindowLongPtr(g_Wnd, GWL_STYLE);
531*c2c66affSColin Finck     if (style & WS_HSCROLL)
532*c2c66affSColin Finck     {
533*c2c66affSColin Finck       style &= ~WS_HSCROLL;
534*c2c66affSColin Finck       style &= ~WS_VSCROLL;
535*c2c66affSColin Finck       SetWindowLongPtr(g_Wnd, GWL_STYLE, style);
536*c2c66affSColin Finck       g_xscroll = 0;
537*c2c66affSColin Finck       g_yscroll = 0;
538*c2c66affSColin Finck     }
539*c2c66affSColin Finck   }
540*c2c66affSColin Finck   return 0;
541*c2c66affSColin Finck }
542*c2c66affSColin Finck 
543*c2c66affSColin Finck /*****************************************************************************/
544*c2c66affSColin Finck static LRESULT
handle_WM_HSCROLL(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)545*c2c66affSColin Finck handle_WM_HSCROLL(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
546*c2c66affSColin Finck {
547*c2c66affSColin Finck   int code;
548*c2c66affSColin Finck   int oldxscroll;
549*c2c66affSColin Finck 
550*c2c66affSColin Finck   code = (int) LOWORD(wParam); /* scroll bar value */
551*c2c66affSColin Finck   if (code == SB_LINELEFT)
552*c2c66affSColin Finck   {
553*c2c66affSColin Finck     oldxscroll = g_xscroll;
554*c2c66affSColin Finck     g_xscroll--;
555*c2c66affSColin Finck     g_xscroll = UI_MAX(g_xscroll, 0);
556*c2c66affSColin Finck     SetScrollPos(g_Wnd, SB_HORZ, g_xscroll, 1);
557*c2c66affSColin Finck     mi_scroll(oldxscroll - g_xscroll, 0);
558*c2c66affSColin Finck   }
559*c2c66affSColin Finck   else if (code == SB_LINERIGHT)
560*c2c66affSColin Finck   {
561*c2c66affSColin Finck     oldxscroll = g_xscroll;
562*c2c66affSColin Finck     g_xscroll++;
563*c2c66affSColin Finck     g_xscroll = UI_MIN(g_xscroll, g_width - g_wnd_cwidth);
564*c2c66affSColin Finck     SetScrollPos(g_Wnd, SB_HORZ, g_xscroll, 1);
565*c2c66affSColin Finck     mi_scroll(oldxscroll - g_xscroll, 0);
566*c2c66affSColin Finck   }
567*c2c66affSColin Finck   else if (code == SB_PAGELEFT)
568*c2c66affSColin Finck   {
569*c2c66affSColin Finck     oldxscroll = g_xscroll;
570*c2c66affSColin Finck     g_xscroll -= g_wnd_cwidth / 2;
571*c2c66affSColin Finck     g_xscroll = UI_MAX(g_xscroll, 0);
572*c2c66affSColin Finck     SetScrollPos(g_Wnd, SB_HORZ, g_xscroll, 1);
573*c2c66affSColin Finck     mi_scroll(oldxscroll - g_xscroll, 0);
574*c2c66affSColin Finck   }
575*c2c66affSColin Finck   else if (code == SB_PAGERIGHT)
576*c2c66affSColin Finck   {
577*c2c66affSColin Finck     oldxscroll = g_xscroll;
578*c2c66affSColin Finck     g_xscroll += g_wnd_cwidth / 2;
579*c2c66affSColin Finck     g_xscroll = UI_MIN(g_xscroll, g_width - g_wnd_cwidth);
580*c2c66affSColin Finck     SetScrollPos(g_Wnd, SB_HORZ, g_xscroll, 1);
581*c2c66affSColin Finck     mi_scroll(oldxscroll - g_xscroll, 0);
582*c2c66affSColin Finck   }
583*c2c66affSColin Finck   else if (code == SB_BOTTOM)
584*c2c66affSColin Finck   {
585*c2c66affSColin Finck     oldxscroll = g_xscroll;
586*c2c66affSColin Finck     g_xscroll = g_width - g_wnd_cwidth;
587*c2c66affSColin Finck     SetScrollPos(g_Wnd, SB_HORZ, g_xscroll, 1);
588*c2c66affSColin Finck     mi_scroll(oldxscroll - g_xscroll, 0);
589*c2c66affSColin Finck   }
590*c2c66affSColin Finck   else if (code == SB_TOP)
591*c2c66affSColin Finck   {
592*c2c66affSColin Finck     oldxscroll = g_xscroll;
593*c2c66affSColin Finck     g_xscroll = 0;
594*c2c66affSColin Finck     SetScrollPos(g_Wnd, SB_HORZ, g_xscroll, 1);
595*c2c66affSColin Finck     mi_scroll(oldxscroll - g_xscroll, 0);
596*c2c66affSColin Finck   }
597*c2c66affSColin Finck   else if (code == SB_THUMBPOSITION)
598*c2c66affSColin Finck   {
599*c2c66affSColin Finck     oldxscroll = g_xscroll;
600*c2c66affSColin Finck     g_xscroll = (signed short) HIWORD(wParam);
601*c2c66affSColin Finck     SetScrollPos(g_Wnd, SB_HORZ, g_xscroll, 1);
602*c2c66affSColin Finck     mi_scroll(oldxscroll - g_xscroll, 0);
603*c2c66affSColin Finck   }
604*c2c66affSColin Finck   return 0;
605*c2c66affSColin Finck }
606*c2c66affSColin Finck 
607*c2c66affSColin Finck /*****************************************************************************/
608*c2c66affSColin Finck static LRESULT
handle_WM_VSCROLL(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)609*c2c66affSColin Finck handle_WM_VSCROLL(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
610*c2c66affSColin Finck {
611*c2c66affSColin Finck   int code;
612*c2c66affSColin Finck   int oldyscroll;
613*c2c66affSColin Finck 
614*c2c66affSColin Finck   code = (int) LOWORD(wParam); /* scroll bar value */
615*c2c66affSColin Finck   if (code == SB_LINELEFT)
616*c2c66affSColin Finck   {
617*c2c66affSColin Finck     oldyscroll = g_yscroll;
618*c2c66affSColin Finck     g_yscroll--;
619*c2c66affSColin Finck     g_yscroll = UI_MAX(g_yscroll, 0);
620*c2c66affSColin Finck     SetScrollPos(g_Wnd, SB_VERT, g_yscroll, 1);
621*c2c66affSColin Finck     mi_scroll(0, oldyscroll - g_yscroll);
622*c2c66affSColin Finck   }
623*c2c66affSColin Finck   else if (code == SB_LINERIGHT)
624*c2c66affSColin Finck   {
625*c2c66affSColin Finck     oldyscroll = g_yscroll;
626*c2c66affSColin Finck     g_yscroll++;
627*c2c66affSColin Finck     g_yscroll = UI_MIN(g_yscroll, g_height - g_wnd_cheight);
628*c2c66affSColin Finck     SetScrollPos(g_Wnd, SB_VERT, g_yscroll, 1);
629*c2c66affSColin Finck     mi_scroll(0, oldyscroll - g_yscroll);
630*c2c66affSColin Finck   }
631*c2c66affSColin Finck   else if (code == SB_PAGELEFT)
632*c2c66affSColin Finck   {
633*c2c66affSColin Finck     oldyscroll = g_yscroll;
634*c2c66affSColin Finck     g_yscroll -= g_wnd_cheight / 2;
635*c2c66affSColin Finck     g_yscroll = UI_MAX(g_yscroll, 0);
636*c2c66affSColin Finck     SetScrollPos(g_Wnd, SB_VERT, g_yscroll, 1);
637*c2c66affSColin Finck     mi_scroll(0, oldyscroll - g_yscroll);
638*c2c66affSColin Finck   }
639*c2c66affSColin Finck   else if (code == SB_PAGERIGHT)
640*c2c66affSColin Finck   {
641*c2c66affSColin Finck     oldyscroll = g_yscroll;
642*c2c66affSColin Finck     g_yscroll += g_wnd_cheight / 2;
643*c2c66affSColin Finck     g_yscroll = UI_MIN(g_yscroll, g_height - g_wnd_cheight);
644*c2c66affSColin Finck     SetScrollPos(g_Wnd, SB_VERT, g_yscroll, 1);
645*c2c66affSColin Finck     mi_scroll(0, oldyscroll - g_yscroll);
646*c2c66affSColin Finck   }
647*c2c66affSColin Finck   else if (code == SB_BOTTOM)
648*c2c66affSColin Finck   {
649*c2c66affSColin Finck     oldyscroll = g_yscroll;
650*c2c66affSColin Finck     g_yscroll = g_height - g_wnd_cheight;
651*c2c66affSColin Finck     SetScrollPos(g_Wnd, SB_VERT, g_yscroll, 1);
652*c2c66affSColin Finck     mi_scroll(0, oldyscroll - g_yscroll);
653*c2c66affSColin Finck   }
654*c2c66affSColin Finck   else if (code == SB_TOP)
655*c2c66affSColin Finck   {
656*c2c66affSColin Finck     oldyscroll = g_yscroll;
657*c2c66affSColin Finck     g_yscroll = 0;
658*c2c66affSColin Finck     SetScrollPos(g_Wnd, SB_VERT, g_yscroll, 1);
659*c2c66affSColin Finck     mi_scroll(0, oldyscroll - g_yscroll);
660*c2c66affSColin Finck   }
661*c2c66affSColin Finck   else if (code == SB_THUMBPOSITION)
662*c2c66affSColin Finck   {
663*c2c66affSColin Finck     oldyscroll = g_yscroll;
664*c2c66affSColin Finck     g_yscroll = (signed short) HIWORD(wParam);
665*c2c66affSColin Finck     SetScrollPos(g_Wnd, SB_VERT, g_yscroll, 1);
666*c2c66affSColin Finck     mi_scroll(0, oldyscroll - g_yscroll);
667*c2c66affSColin Finck   }
668*c2c66affSColin Finck   return 0;
669*c2c66affSColin Finck }
670*c2c66affSColin Finck 
671*c2c66affSColin Finck 
672*c2c66affSColin Finck /*****************************************************************************/
673*c2c66affSColin Finck LRESULT CALLBACK
WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)674*c2c66affSColin Finck WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
675*c2c66affSColin Finck {
676*c2c66affSColin Finck   switch (message)
677*c2c66affSColin Finck   {
678*c2c66affSColin Finck     case WM_SETCURSOR:
679*c2c66affSColin Finck       return handle_WM_SETCURSOR(hWnd, message, wParam, lParam);
680*c2c66affSColin Finck     case 0x0084: /* WinCE don't have this WM_NCHITTEST: */
681*c2c66affSColin Finck       return handle_WM_NCHITTEST(hWnd, message, wParam, lParam);
682*c2c66affSColin Finck     case WM_MOUSEMOVE:
683*c2c66affSColin Finck       return handle_WM_MOUSEMOVE(hWnd, message, wParam, lParam);
684*c2c66affSColin Finck     case WM_LBUTTONDOWN:
685*c2c66affSColin Finck       return handle_WM_LBUTTONDOWN(hWnd, message, wParam, lParam);
686*c2c66affSColin Finck     case WM_LBUTTONUP:
687*c2c66affSColin Finck       return handle_WM_LBUTTONUP(hWnd, message, wParam, lParam);
688*c2c66affSColin Finck     case WM_RBUTTONDOWN:
689*c2c66affSColin Finck       return handle_WM_RBUTTONDOWN(hWnd, message, wParam, lParam);
690*c2c66affSColin Finck     case WM_RBUTTONUP:
691*c2c66affSColin Finck       return handle_WM_RBUTTONUP(hWnd, message, wParam, lParam);
692*c2c66affSColin Finck     case WM_MBUTTONDOWN:
693*c2c66affSColin Finck       return handle_WM_MBUTTONDOWN(hWnd, message, wParam, lParam);
694*c2c66affSColin Finck     case WM_MBUTTONUP:
695*c2c66affSColin Finck       return handle_WM_MBUTTONUP(hWnd, message, wParam, lParam);
696*c2c66affSColin Finck     /* some windows compilers don't have these defined like vc6 */
697*c2c66affSColin Finck     case 0x020a: /* WM_MOUSEWHEEL: */
698*c2c66affSColin Finck       return handle_WM_MOUSEWHEEL(hWnd, message, wParam, lParam);
699*c2c66affSColin Finck     case WM_KEYDOWN:
700*c2c66affSColin Finck     case WM_KEYUP:
701*c2c66affSColin Finck     case WM_SYSKEYDOWN:
702*c2c66affSColin Finck     case WM_SYSKEYUP:
703*c2c66affSColin Finck       return handle_WM_KEY(hWnd, message, wParam, lParam);
704*c2c66affSColin Finck     case WM_CHAR:
705*c2c66affSColin Finck     case WM_DEADCHAR:
706*c2c66affSColin Finck     case WM_SYSCHAR:
707*c2c66affSColin Finck     case WM_SYSDEADCHAR:
708*c2c66affSColin Finck       break;
709*c2c66affSColin Finck     case WM_PAINT:
710*c2c66affSColin Finck       return handle_WM_PAINT(hWnd, message, wParam, lParam);
711*c2c66affSColin Finck     case WM_DESTROY:
712*c2c66affSColin Finck       PostQuitMessage(0);
713*c2c66affSColin Finck       break;
714*c2c66affSColin Finck     case WM_APP + 1:
715*c2c66affSColin Finck     case WM_TIMER:
716*c2c66affSColin Finck       check_sck();
717*c2c66affSColin Finck       break;
718*c2c66affSColin Finck     case WM_SIZE:
719*c2c66affSColin Finck       return handle_WM_SIZE(hWnd, message, wParam, lParam);
720*c2c66affSColin Finck     case 532: /* not defined in wince WM_SIZING: */
721*c2c66affSColin Finck       return handle_WM_SIZING(hWnd, message, wParam, lParam);
722*c2c66affSColin Finck     case WM_HSCROLL:
723*c2c66affSColin Finck       return handle_WM_HSCROLL(hWnd, message, wParam, lParam);
724*c2c66affSColin Finck     case WM_VSCROLL:
725*c2c66affSColin Finck       return handle_WM_VSCROLL(hWnd, message, wParam, lParam);
726*c2c66affSColin Finck     case WM_SETFOCUS:
727*c2c66affSColin Finck       mi_check_modifier();
728*c2c66affSColin Finck       return DefWindowProc(hWnd, message, wParam, lParam);
729*c2c66affSColin Finck     default:
730*c2c66affSColin Finck       return DefWindowProc(hWnd, message, wParam, lParam);
731*c2c66affSColin Finck   }
732*c2c66affSColin Finck   return 0;
733*c2c66affSColin Finck }
734*c2c66affSColin Finck 
735*c2c66affSColin Finck /*****************************************************************************/
736*c2c66affSColin Finck static HRGN
mi_clip(HDC dc)737*c2c66affSColin Finck mi_clip(HDC dc)
738*c2c66affSColin Finck {
739*c2c66affSColin Finck   HRGN rgn;
740*c2c66affSColin Finck 
741*c2c66affSColin Finck   rgn = CreateRectRgn(g_clip_left + g_xoff - g_xscroll,
742*c2c66affSColin Finck                       g_clip_top + g_yoff - g_yscroll,
743*c2c66affSColin Finck                       g_clip_right + g_xoff - g_xscroll,
744*c2c66affSColin Finck                       g_clip_bottom + g_yoff - g_yscroll);
745*c2c66affSColin Finck   SelectClipRgn(dc, rgn);
746*c2c66affSColin Finck   IntersectClipRect(dc, g_wnd_clip.left + g_xoff, g_wnd_clip.top + g_yoff,
747*c2c66affSColin Finck                     g_wnd_clip.right + g_xoff, g_wnd_clip.bottom + g_yoff);
748*c2c66affSColin Finck   return rgn;
749*c2c66affSColin Finck }
750*c2c66affSColin Finck 
751*c2c66affSColin Finck /*****************************************************************************/
752*c2c66affSColin Finck /* returns non zero if ok */
753*c2c66affSColin Finck int
mi_create_window(void)754*c2c66affSColin Finck mi_create_window(void)
755*c2c66affSColin Finck {
756*c2c66affSColin Finck   RECT rc;
757*c2c66affSColin Finck   WNDCLASS wc;
758*c2c66affSColin Finck   TCHAR classname[512];
759*c2c66affSColin Finck   TCHAR caption[512];
760*c2c66affSColin Finck   DWORD style;
761*c2c66affSColin Finck   int x;
762*c2c66affSColin Finck   int y;
763*c2c66affSColin Finck   int w;
764*c2c66affSColin Finck   int h;
765*c2c66affSColin Finck 
766*c2c66affSColin Finck   if (g_Wnd != 0 || g_Instance != 0)
767*c2c66affSColin Finck   {
768*c2c66affSColin Finck     return 0;
769*c2c66affSColin Finck   }
770*c2c66affSColin Finck   g_Instance = GetModuleHandle(NULL);
771*c2c66affSColin Finck   ZeroMemory(&wc, sizeof(wc));
772*c2c66affSColin Finck   wc.lpfnWndProc = WndProc; /* points to window procedure */
773*c2c66affSColin Finck   /* name of window class */
774*c2c66affSColin Finck   str_to_uni(classname, "rdesktop");
775*c2c66affSColin Finck   wc.lpszClassName = classname;
776*c2c66affSColin Finck   str_to_uni(caption, "ReactOS Remote Desktop");
777*c2c66affSColin Finck   wc.hIcon = LoadIcon(g_Instance,
778*c2c66affSColin Finck                       MAKEINTRESOURCE(IDI_MSTSC));
779*c2c66affSColin Finck   /* Register the window class. */
780*c2c66affSColin Finck   if (!RegisterClass(&wc))
781*c2c66affSColin Finck   {
782*c2c66affSColin Finck     return 0; /* Failed to register window class */
783*c2c66affSColin Finck   }
784*c2c66affSColin Finck   rc.left = 0;
785*c2c66affSColin Finck   rc.right = rc.left + UI_MIN(g_width, g_screen_width);
786*c2c66affSColin Finck   rc.top = 0;
787*c2c66affSColin Finck   rc.bottom = rc.top + UI_MIN(g_height, g_screen_height);
788*c2c66affSColin Finck 
789*c2c66affSColin Finck   if (g_fullscreen)
790*c2c66affSColin Finck   {
791*c2c66affSColin Finck     style = WS_POPUP;
792*c2c66affSColin Finck   }
793*c2c66affSColin Finck   else
794*c2c66affSColin Finck   {
795*c2c66affSColin Finck     style = WS_OVERLAPPED | WS_CAPTION | WS_POPUP | WS_MINIMIZEBOX |
796*c2c66affSColin Finck             WS_SYSMENU | WS_SIZEBOX | WS_MAXIMIZEBOX;
797*c2c66affSColin Finck   }
798*c2c66affSColin Finck   if (g_screen_width < g_width || g_screen_height < g_height)
799*c2c66affSColin Finck   {
800*c2c66affSColin Finck     style |= WS_HSCROLL | WS_VSCROLL;
801*c2c66affSColin Finck   }
802*c2c66affSColin Finck   AdjustWindowRectEx(&rc, style, 0, 0);
803*c2c66affSColin Finck   x = CW_USEDEFAULT;
804*c2c66affSColin Finck   y = CW_USEDEFAULT;
805*c2c66affSColin Finck   w = rc.right - rc.left;
806*c2c66affSColin Finck   h = rc.bottom - rc.top;
807*c2c66affSColin Finck 
808*c2c66affSColin Finck   g_Wnd = CreateWindow(wc.lpszClassName, caption,
809*c2c66affSColin Finck                        style, x, y, w, h,
810*c2c66affSColin Finck                        (HWND) NULL, (HMENU) NULL, g_Instance,
811*c2c66affSColin Finck                        (LPVOID) NULL);
812*c2c66affSColin Finck   g_clip_left = 0;
813*c2c66affSColin Finck   g_clip_top = 0;
814*c2c66affSColin Finck   g_clip_right = g_clip_left + g_width;
815*c2c66affSColin Finck   g_clip_bottom = g_clip_top + g_height;
816*c2c66affSColin Finck   if (g_workarea)
817*c2c66affSColin Finck   {
818*c2c66affSColin Finck     ShowWindow(g_Wnd, SW_SHOWMAXIMIZED);
819*c2c66affSColin Finck   }
820*c2c66affSColin Finck   else
821*c2c66affSColin Finck   {
822*c2c66affSColin Finck     ShowWindow(g_Wnd, SW_SHOWNORMAL);
823*c2c66affSColin Finck   }
824*c2c66affSColin Finck   UpdateWindow(g_Wnd);
825*c2c66affSColin Finck 
826*c2c66affSColin Finck   WSAAsyncSelect(g_tcp_sck, g_Wnd, WM_APP + 1, FD_READ);
827*c2c66affSColin Finck   SetTimer(g_Wnd, 1, 333, 0);
828*c2c66affSColin Finck 
829*c2c66affSColin Finck   return 1;
830*c2c66affSColin Finck }
831*c2c66affSColin Finck 
832*c2c66affSColin Finck /*****************************************************************************/
833*c2c66affSColin Finck int
mi_main_loop(void)834*c2c66affSColin Finck mi_main_loop(void)
835*c2c66affSColin Finck {
836*c2c66affSColin Finck   MSG msg;
837*c2c66affSColin Finck 
838*c2c66affSColin Finck   while (GetMessage(&msg, NULL, 0, 0))
839*c2c66affSColin Finck   {
840*c2c66affSColin Finck     TranslateMessage(&msg);
841*c2c66affSColin Finck     DispatchMessage(&msg);
842*c2c66affSColin Finck   }
843*c2c66affSColin Finck   return msg.wParam;
844*c2c66affSColin Finck }
845*c2c66affSColin Finck 
846*c2c66affSColin Finck /*****************************************************************************/
847*c2c66affSColin Finck void
mi_warning(char * msg)848*c2c66affSColin Finck mi_warning(char * msg)
849*c2c66affSColin Finck {
850*c2c66affSColin Finck }
851*c2c66affSColin Finck 
852*c2c66affSColin Finck /*****************************************************************************/
853*c2c66affSColin Finck static void
mi_show_error(char * caption)854*c2c66affSColin Finck mi_show_error(char * caption)
855*c2c66affSColin Finck {
856*c2c66affSColin Finck   LPVOID lpMsgBuf;
857*c2c66affSColin Finck   TCHAR lcaption[512];
858*c2c66affSColin Finck 
859*c2c66affSColin Finck   FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
860*c2c66affSColin Finck                 NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
861*c2c66affSColin Finck                 (LPTSTR) &lpMsgBuf, 0, NULL);
862*c2c66affSColin Finck #ifdef WITH_DEBUG
863*c2c66affSColin Finck   printf(lpMsgBuf);
864*c2c66affSColin Finck #else /* WITH_DEBUG */
865*c2c66affSColin Finck   str_to_uni(lcaption, caption);
866*c2c66affSColin Finck   MessageBox(g_Wnd, (LPTSTR) lpMsgBuf, lcaption,
867*c2c66affSColin Finck              MB_OK | MB_ICONINFORMATION);
868*c2c66affSColin Finck #endif /* WITH_DEBUG */
869*c2c66affSColin Finck   LocalFree(lpMsgBuf);
870*c2c66affSColin Finck }
871*c2c66affSColin Finck 
872*c2c66affSColin Finck /*****************************************************************************/
873*c2c66affSColin Finck void
mi_paint_rect(char * data,int width,int height,int x,int y,int cx,int cy)874*c2c66affSColin Finck mi_paint_rect(char * data, int width, int height, int x, int y, int cx, int cy)
875*c2c66affSColin Finck {
876*c2c66affSColin Finck   HBITMAP bitmap;
877*c2c66affSColin Finck   BITMAPINFO bi;
878*c2c66affSColin Finck   HDC dc;
879*c2c66affSColin Finck   HDC maindc;
880*c2c66affSColin Finck   HGDIOBJ save;
881*c2c66affSColin Finck   HRGN rgn;
882*c2c66affSColin Finck   void * bits;
883*c2c66affSColin Finck   int i;
884*c2c66affSColin Finck   int j;
885*c2c66affSColin Finck   int colour;
886*c2c66affSColin Finck   int red;
887*c2c66affSColin Finck   int green;
888*c2c66affSColin Finck   int blue;
889*c2c66affSColin Finck   int index;
890*c2c66affSColin Finck 
891*c2c66affSColin Finck   ZeroMemory(&bi, sizeof(bi));
892*c2c66affSColin Finck   bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
893*c2c66affSColin Finck   bi.bmiHeader.biWidth = width;
894*c2c66affSColin Finck   bi.bmiHeader.biHeight = -height;
895*c2c66affSColin Finck   bi.bmiHeader.biPlanes = 1;
896*c2c66affSColin Finck   bi.bmiHeader.biBitCount = 32;
897*c2c66affSColin Finck   bi.bmiHeader.biCompression = BI_RGB;
898*c2c66affSColin Finck   maindc = GetWindowDC(g_Wnd);
899*c2c66affSColin Finck   bitmap = CreateDIBSection(maindc, &bi, DIB_RGB_COLORS, (void **) &bits, 0, 0);
900*c2c66affSColin Finck   if (bitmap == 0)
901*c2c66affSColin Finck   {
902*c2c66affSColin Finck     mi_show_error("CreateDIBSection failed");
903*c2c66affSColin Finck   }
904*c2c66affSColin Finck 
905*c2c66affSColin Finck   if (g_server_depth == 8)
906*c2c66affSColin Finck   {
907*c2c66affSColin Finck     for (i = cy - 1; i >= 0; i--)
908*c2c66affSColin Finck     {
909*c2c66affSColin Finck       for (j = cx - 1; j >= 0; j--)
910*c2c66affSColin Finck       {
911*c2c66affSColin Finck         colour = ((unsigned char*)data)[i * cx + j];
912*c2c66affSColin Finck         red = (pal_entries[colour & 0xff] & 0xff0000) >> 16;
913*c2c66affSColin Finck         green = (pal_entries[colour & 0xff] & 0xff00) >> 8;
914*c2c66affSColin Finck         blue = pal_entries[colour & 0xff] & 0xff;
915*c2c66affSColin Finck         MAKE_COLOUR32(colour, red, green, blue);
916*c2c66affSColin Finck         ((unsigned int*)bits)[i * cx + j] = colour;
917*c2c66affSColin Finck       }
918*c2c66affSColin Finck     }
919*c2c66affSColin Finck   }
920*c2c66affSColin Finck   else if (g_server_depth == 15)
921*c2c66affSColin Finck   {
922*c2c66affSColin Finck     for (i = cy - 1; i >= 0; i--)
923*c2c66affSColin Finck     {
924*c2c66affSColin Finck       for (j = cx - 1; j >= 0; j--)
925*c2c66affSColin Finck       {
926*c2c66affSColin Finck         colour = ((unsigned short*)data)[i * cx + j];
927*c2c66affSColin Finck         SPLIT_COLOUR15(colour, red, green, blue);
928*c2c66affSColin Finck         MAKE_COLOUR32(colour, red, green, blue);
929*c2c66affSColin Finck         ((unsigned int*)bits)[i * cx + j] = colour;
930*c2c66affSColin Finck       }
931*c2c66affSColin Finck     }
932*c2c66affSColin Finck   }
933*c2c66affSColin Finck   else if (g_server_depth == 16)
934*c2c66affSColin Finck   {
935*c2c66affSColin Finck     for (i = cy - 1; i >= 0; i--)
936*c2c66affSColin Finck     {
937*c2c66affSColin Finck       for (j = cx - 1; j >= 0; j--)
938*c2c66affSColin Finck       {
939*c2c66affSColin Finck         colour = ((unsigned short*)data)[i * cx + j];
940*c2c66affSColin Finck         SPLIT_COLOUR16(colour, red, green, blue);
941*c2c66affSColin Finck         MAKE_COLOUR32(colour, red, green, blue);
942*c2c66affSColin Finck         ((unsigned int*)bits)[i * cx + j] = colour;
943*c2c66affSColin Finck       }
944*c2c66affSColin Finck     }
945*c2c66affSColin Finck   }
946*c2c66affSColin Finck   else if (g_server_depth == 24)
947*c2c66affSColin Finck   {
948*c2c66affSColin Finck     for (i = cy - 1; i >= 0; i--)
949*c2c66affSColin Finck     {
950*c2c66affSColin Finck       for (j = cx - 1; j >= 0; j--)
951*c2c66affSColin Finck       {
952*c2c66affSColin Finck         index = (i * cx + j) * 3;
953*c2c66affSColin Finck         red = ((unsigned char*)data)[index + 2];
954*c2c66affSColin Finck         green = ((unsigned char*)data)[index + 1];
955*c2c66affSColin Finck         blue = ((unsigned char*)data)[index];
956*c2c66affSColin Finck         MAKE_COLOUR32(colour, red, green, blue);
957*c2c66affSColin Finck         ((unsigned int*)bits)[i * cx + j] = colour;
958*c2c66affSColin Finck       }
959*c2c66affSColin Finck     }
960*c2c66affSColin Finck   }
961*c2c66affSColin Finck   else if (g_server_depth == 32)
962*c2c66affSColin Finck   {
963*c2c66affSColin Finck     memcpy(bits, data, cx*cy*4);
964*c2c66affSColin Finck   }
965*c2c66affSColin Finck   dc = CreateCompatibleDC(maindc);
966*c2c66affSColin Finck   if (dc == 0)
967*c2c66affSColin Finck   {
968*c2c66affSColin Finck     mi_show_error("CreateCompatibleDC failed");
969*c2c66affSColin Finck   }
970*c2c66affSColin Finck   save = SelectObject(dc, bitmap);
971*c2c66affSColin Finck   rgn = mi_clip(maindc);
972*c2c66affSColin Finck   BitBlt(maindc, x + g_xoff - g_xscroll, y + g_yoff - g_yscroll, cx, cy, dc,
973*c2c66affSColin Finck          0, 0, SRCCOPY);
974*c2c66affSColin Finck   SelectObject(dc, save);
975*c2c66affSColin Finck   DeleteObject(bitmap);
976*c2c66affSColin Finck   DeleteDC(dc);
977*c2c66affSColin Finck   ReleaseDC(g_Wnd, maindc);
978*c2c66affSColin Finck   DeleteObject(rgn);
979*c2c66affSColin Finck 
980*c2c66affSColin Finck }
981*c2c66affSColin Finck 
982*c2c66affSColin Finck static INT
GetPortNumber(PCHAR szAddress)983*c2c66affSColin Finck GetPortNumber(PCHAR szAddress)
984*c2c66affSColin Finck {
985*c2c66affSColin Finck     PCHAR szPort;
986*c2c66affSColin Finck     INT iPort = TCP_PORT_RDP;
987*c2c66affSColin Finck 
988*c2c66affSColin Finck     szPort = strtok(szAddress, ":");
989*c2c66affSColin Finck 
990*c2c66affSColin Finck     if (szPort != NULL)
991*c2c66affSColin Finck     {
992*c2c66affSColin Finck         szPort = strtok(NULL, ":");
993*c2c66affSColin Finck 
994*c2c66affSColin Finck         if (szPort != NULL)
995*c2c66affSColin Finck         {
996*c2c66affSColin Finck             iPort = atoi(szPort);
997*c2c66affSColin Finck 
998*c2c66affSColin Finck             if (iPort <= 0 || iPort > 0xFFFF)
999*c2c66affSColin Finck                 iPort = TCP_PORT_RDP;
1000*c2c66affSColin Finck         }
1001*c2c66affSColin Finck     }
1002*c2c66affSColin Finck 
1003*c2c66affSColin Finck     return iPort;
1004*c2c66affSColin Finck }
1005*c2c66affSColin Finck 
1006*c2c66affSColin Finck static VOID
SetDomainAndUsername(PCHAR pName)1007*c2c66affSColin Finck SetDomainAndUsername(PCHAR pName)
1008*c2c66affSColin Finck {
1009*c2c66affSColin Finck     PCHAR pDomain;
1010*c2c66affSColin Finck     PCHAR pUsername;
1011*c2c66affSColin Finck 
1012*c2c66affSColin Finck     strcpy(g_domain, "");
1013*c2c66affSColin Finck     strcpy(g_username, "");
1014*c2c66affSColin Finck 
1015*c2c66affSColin Finck     pDomain = strtok(pName, "\\");
1016*c2c66affSColin Finck 
1017*c2c66affSColin Finck     if(pDomain == NULL)
1018*c2c66affSColin Finck         return;
1019*c2c66affSColin Finck 
1020*c2c66affSColin Finck     pUsername = strtok(NULL, "\\");
1021*c2c66affSColin Finck 
1022*c2c66affSColin Finck     if(pUsername == NULL)
1023*c2c66affSColin Finck     {
1024*c2c66affSColin Finck         strcpy(g_username, pDomain);
1025*c2c66affSColin Finck         return;
1026*c2c66affSColin Finck     }
1027*c2c66affSColin Finck 
1028*c2c66affSColin Finck     strcpy(g_username, pUsername);
1029*c2c66affSColin Finck     strcpy(g_domain, pDomain);
1030*c2c66affSColin Finck     return;
1031*c2c66affSColin Finck }
1032*c2c66affSColin Finck 
1033*c2c66affSColin Finck static BOOL
ParseCommandLine(LPWSTR lpCmdLine,PRDPSETTINGS pRdpSettings,BOOL * bSkipDlg)1034*c2c66affSColin Finck ParseCommandLine(LPWSTR lpCmdLine,
1035*c2c66affSColin Finck                  PRDPSETTINGS pRdpSettings,
1036*c2c66affSColin Finck                  BOOL *bSkipDlg)
1037*c2c66affSColin Finck {
1038*c2c66affSColin Finck     LPWSTR lpStr = lpCmdLine;
1039*c2c66affSColin Finck     WCHAR szSeps[] = L"/";
1040*c2c66affSColin Finck     LPWSTR lpToken;
1041*c2c66affSColin Finck     BOOL bRet = TRUE;
1042*c2c66affSColin Finck 
1043*c2c66affSColin Finck     *bSkipDlg = TRUE;
1044*c2c66affSColin Finck 
1045*c2c66affSColin Finck     if (*lpCmdLine != L'/')
1046*c2c66affSColin Finck     {
1047*c2c66affSColin Finck         LoadRdpSettingsFromFile(pRdpSettings, lpCmdLine);
1048*c2c66affSColin Finck     }
1049*c2c66affSColin Finck     else
1050*c2c66affSColin Finck     {
1051*c2c66affSColin Finck         /* default to screen size, 16bpp */
1052*c2c66affSColin Finck         SetIntegerToSettings(pRdpSettings, L"session bpp", 16);
1053*c2c66affSColin Finck         SetIntegerToSettings(pRdpSettings, L"desktopwidth", GetSystemMetrics(SM_CXSCREEN));
1054*c2c66affSColin Finck         SetIntegerToSettings(pRdpSettings, L"desktopheight", GetSystemMetrics(SM_CYSCREEN));
1055*c2c66affSColin Finck 
1056*c2c66affSColin Finck         lpToken = wcstok(lpStr, szSeps);
1057*c2c66affSColin Finck         while (lpToken)
1058*c2c66affSColin Finck         {
1059*c2c66affSColin Finck             if (wcsncmp(lpToken, L"edit", 4) == 0)
1060*c2c66affSColin Finck             {
1061*c2c66affSColin Finck                 lpToken += 5;
1062*c2c66affSColin Finck                 LoadRdpSettingsFromFile(pRdpSettings, lpToken);
1063*c2c66affSColin Finck                 *bSkipDlg = FALSE;
1064*c2c66affSColin Finck                 break;
1065*c2c66affSColin Finck             }
1066*c2c66affSColin Finck 
1067*c2c66affSColin Finck             if (*lpToken == L'v')
1068*c2c66affSColin Finck             {
1069*c2c66affSColin Finck                 lpToken += 2;
1070*c2c66affSColin Finck                 SetStringToSettings(pRdpSettings, L"full address", lpToken);
1071*c2c66affSColin Finck             }
1072*c2c66affSColin Finck             else if (*lpToken == L'w')
1073*c2c66affSColin Finck             {
1074*c2c66affSColin Finck                 lpToken += 2;
1075*c2c66affSColin Finck                 SetIntegerToSettings(pRdpSettings, L"desktopwidth", _wtoi(lpToken));
1076*c2c66affSColin Finck             }
1077*c2c66affSColin Finck             else if (*lpToken == L'h')
1078*c2c66affSColin Finck             {
1079*c2c66affSColin Finck                 lpToken += 2;
1080*c2c66affSColin Finck                 SetIntegerToSettings(pRdpSettings, L"desktopheight", _wtoi(lpToken));
1081*c2c66affSColin Finck             }
1082*c2c66affSColin Finck             else if (*lpToken == L'f')
1083*c2c66affSColin Finck             {
1084*c2c66affSColin Finck                 SetIntegerToSettings(pRdpSettings, L"screen mode id", 2);
1085*c2c66affSColin Finck             }
1086*c2c66affSColin Finck 
1087*c2c66affSColin Finck             lpToken = wcstok(NULL, szSeps);
1088*c2c66affSColin Finck         }
1089*c2c66affSColin Finck     }
1090*c2c66affSColin Finck 
1091*c2c66affSColin Finck     return bRet;
1092*c2c66affSColin Finck }
1093*c2c66affSColin Finck 
1094*c2c66affSColin Finck /*****************************************************************************/
1095*c2c66affSColin Finck int WINAPI
wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPWSTR lpCmdLine,int nCmdShow)1096*c2c66affSColin Finck wWinMain(HINSTANCE hInstance,
1097*c2c66affSColin Finck          HINSTANCE hPrevInstance,
1098*c2c66affSColin Finck          LPWSTR lpCmdLine,
1099*c2c66affSColin Finck          int nCmdShow)
1100*c2c66affSColin Finck {
1101*c2c66affSColin Finck     PRDPSETTINGS pRdpSettings;
1102*c2c66affSColin Finck     WSADATA d;
1103*c2c66affSColin Finck     int ret = 1;
1104*c2c66affSColin Finck 
1105*c2c66affSColin Finck     if (WSAStartup(MAKEWORD(2, 0), &d) == 0)
1106*c2c66affSColin Finck     {
1107*c2c66affSColin Finck         pRdpSettings = HeapAlloc(GetProcessHeap(),
1108*c2c66affSColin Finck                                  0,
1109*c2c66affSColin Finck                                  sizeof(RDPSETTINGS));
1110*c2c66affSColin Finck         if (pRdpSettings)
1111*c2c66affSColin Finck         {
1112*c2c66affSColin Finck             pRdpSettings->pSettings = NULL;
1113*c2c66affSColin Finck             pRdpSettings->NumSettings = 0;
1114*c2c66affSColin Finck 
1115*c2c66affSColin Finck             if (InitRdpSettings(pRdpSettings))
1116*c2c66affSColin Finck             {
1117*c2c66affSColin Finck                 BOOL bSkipDlg = FALSE;
1118*c2c66affSColin Finck 
1119*c2c66affSColin Finck                 if (*lpCmdLine)
1120*c2c66affSColin Finck                     ParseCommandLine(lpCmdLine, pRdpSettings,&bSkipDlg);
1121*c2c66affSColin Finck                 else
1122*c2c66affSColin Finck                     LoadRdpSettingsFromFile(pRdpSettings, NULL);
1123*c2c66affSColin Finck 
1124*c2c66affSColin Finck                 if (bSkipDlg || OpenRDPConnectDialog(hInstance,
1125*c2c66affSColin Finck                                                       pRdpSettings))
1126*c2c66affSColin Finck                 {
1127*c2c66affSColin Finck                     char szValue[MAXVALUE];
1128*c2c66affSColin Finck                     DWORD dwSize = MAXVALUE;
1129*c2c66affSColin Finck 
1130*c2c66affSColin Finck                     uni_to_str(szValue, GetStringFromSettings(pRdpSettings, L"full address"));
1131*c2c66affSColin Finck 
1132*c2c66affSColin Finck                     /* GetPortNumber also removes possible trailing port number from address */
1133*c2c66affSColin Finck                     g_tcp_port_rdp = GetPortNumber(szValue);
1134*c2c66affSColin Finck                     strcpy(g_servername, szValue);
1135*c2c66affSColin Finck                     uni_to_str(szValue, GetStringFromSettings(pRdpSettings, L"username"));
1136*c2c66affSColin Finck                     SetDomainAndUsername(szValue);
1137*c2c66affSColin Finck                     strcpy(g_password, "");
1138*c2c66affSColin Finck                     if (GetComputerNameA(szValue, &dwSize))
1139*c2c66affSColin Finck                         strcpy(g_hostname, szValue);
1140*c2c66affSColin Finck                     else
1141*c2c66affSColin Finck                         strcpy(g_hostname, tcp_get_address());
1142*c2c66affSColin Finck                     g_server_depth = GetIntegerFromSettings(pRdpSettings, L"session bpp");
1143*c2c66affSColin Finck                     g_screen_width = GetSystemMetrics(SM_CXSCREEN);
1144*c2c66affSColin Finck                     g_screen_height = GetSystemMetrics(SM_CYSCREEN);
1145*c2c66affSColin Finck                     g_width = GetIntegerFromSettings(pRdpSettings, L"desktopwidth");
1146*c2c66affSColin Finck                     g_height = GetIntegerFromSettings(pRdpSettings, L"desktopheight");
1147*c2c66affSColin Finck                     if (GetIntegerFromSettings(pRdpSettings, L"screen mode id") == 2)
1148*c2c66affSColin Finck                     {
1149*c2c66affSColin Finck                         g_fullscreen = 1;
1150*c2c66affSColin Finck                         g_xoff = 0;
1151*c2c66affSColin Finck                         g_yoff = 0;
1152*c2c66affSColin Finck                     }
1153*c2c66affSColin Finck                     else
1154*c2c66affSColin Finck                     {
1155*c2c66affSColin Finck                         g_xoff = GetSystemMetrics(SM_CXEDGE) * 2;
1156*c2c66affSColin Finck                         g_yoff = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYEDGE) * 2;
1157*c2c66affSColin Finck                     }
1158*c2c66affSColin Finck 
1159*c2c66affSColin Finck                     ui_main();
1160*c2c66affSColin Finck                     ret = 0;
1161*c2c66affSColin Finck                 }
1162*c2c66affSColin Finck 
1163*c2c66affSColin Finck                 HeapFree(GetProcessHeap(),
1164*c2c66affSColin Finck                          0,
1165*c2c66affSColin Finck                          pRdpSettings->pSettings);
1166*c2c66affSColin Finck             }
1167*c2c66affSColin Finck 
1168*c2c66affSColin Finck             HeapFree(GetProcessHeap(),
1169*c2c66affSColin Finck                      0,
1170*c2c66affSColin Finck                      pRdpSettings);
1171*c2c66affSColin Finck       }
1172*c2c66affSColin Finck 
1173*c2c66affSColin Finck         WSACleanup();
1174*c2c66affSColin Finck     }
1175*c2c66affSColin Finck 
1176*c2c66affSColin Finck   return ret;
1177*c2c66affSColin Finck }
1178*c2c66affSColin Finck 
1179*c2c66affSColin Finck 
1180*c2c66affSColin Finck /*****************************************************************************/
1181*c2c66affSColin Finck void
mi_begin_update(void)1182*c2c66affSColin Finck mi_begin_update(void)
1183*c2c66affSColin Finck {
1184*c2c66affSColin Finck }
1185*c2c66affSColin Finck 
1186*c2c66affSColin Finck /*****************************************************************************/
1187*c2c66affSColin Finck void
mi_end_update(void)1188*c2c66affSColin Finck mi_end_update(void)
1189*c2c66affSColin Finck {
1190*c2c66affSColin Finck }
1191*c2c66affSColin Finck 
1192*c2c66affSColin Finck /*****************************************************************************/
1193*c2c66affSColin Finck void
mi_fill_rect(int x,int y,int cx,int cy,int colour)1194*c2c66affSColin Finck mi_fill_rect(int x, int y, int cx, int cy, int colour)
1195*c2c66affSColin Finck {
1196*c2c66affSColin Finck   HBRUSH brush;
1197*c2c66affSColin Finck   RECT rect;
1198*c2c66affSColin Finck   HDC maindc;
1199*c2c66affSColin Finck   HRGN rgn;
1200*c2c66affSColin Finck   int red;
1201*c2c66affSColin Finck   int green;
1202*c2c66affSColin Finck   int blue;
1203*c2c66affSColin Finck 
1204*c2c66affSColin Finck   if (g_server_depth == 8)
1205*c2c66affSColin Finck   {
1206*c2c66affSColin Finck     red = (pal_entries[colour & 0xff] & 0xff0000) >> 16;
1207*c2c66affSColin Finck     green = (pal_entries[colour & 0xff] & 0xff00) >> 8;
1208*c2c66affSColin Finck     blue = pal_entries[colour & 0xff] & 0xff;
1209*c2c66affSColin Finck   }
1210*c2c66affSColin Finck   else if (g_server_depth == 15)
1211*c2c66affSColin Finck   {
1212*c2c66affSColin Finck     SPLIT_COLOUR15(colour, red, green, blue);
1213*c2c66affSColin Finck   }
1214*c2c66affSColin Finck   else if (g_server_depth == 16)
1215*c2c66affSColin Finck   {
1216*c2c66affSColin Finck     SPLIT_COLOUR16(colour, red, green, blue);
1217*c2c66affSColin Finck   }
1218*c2c66affSColin Finck   else if (g_server_depth == 24 || g_server_depth == 32)
1219*c2c66affSColin Finck   {
1220*c2c66affSColin Finck     red = (colour>>16)&0xff;
1221*c2c66affSColin Finck     green = (colour>>8)&0xff;
1222*c2c66affSColin Finck     blue =  colour&0xff;
1223*c2c66affSColin Finck   }
1224*c2c66affSColin Finck   maindc = GetWindowDC(g_Wnd);
1225*c2c66affSColin Finck   rgn = mi_clip(maindc);
1226*c2c66affSColin Finck   brush = CreateSolidBrush(RGB(red, green, blue));
1227*c2c66affSColin Finck   rect.left = x + g_xoff - g_xscroll;
1228*c2c66affSColin Finck   rect.top = y + g_yoff - g_yscroll;
1229*c2c66affSColin Finck   rect.right = rect.left + cx;
1230*c2c66affSColin Finck   rect.bottom = rect.top + cy;
1231*c2c66affSColin Finck   FillRect(maindc, &rect, brush);
1232*c2c66affSColin Finck   DeleteObject(brush);
1233*c2c66affSColin Finck   ReleaseDC(g_Wnd, maindc);
1234*c2c66affSColin Finck   DeleteObject(rgn);
1235*c2c66affSColin Finck }
1236*c2c66affSColin Finck 
1237*c2c66affSColin Finck /*****************************************************************************/
1238*c2c66affSColin Finck void
mi_line(int x1,int y1,int x2,int y2,int colour)1239*c2c66affSColin Finck mi_line(int x1, int y1, int x2, int y2, int colour)
1240*c2c66affSColin Finck {
1241*c2c66affSColin Finck   HPEN pen;
1242*c2c66affSColin Finck   HDC maindc;
1243*c2c66affSColin Finck   HGDIOBJ save;
1244*c2c66affSColin Finck   HRGN rgn;
1245*c2c66affSColin Finck   int red;
1246*c2c66affSColin Finck   int green;
1247*c2c66affSColin Finck   int blue;
1248*c2c66affSColin Finck 
1249*c2c66affSColin Finck   if (g_server_depth == 8)
1250*c2c66affSColin Finck   {
1251*c2c66affSColin Finck     red = (pal_entries[colour & 0xff] & 0xff0000) >> 16;
1252*c2c66affSColin Finck     green = (pal_entries[colour & 0xff] & 0xff00) >> 8;
1253*c2c66affSColin Finck     blue = pal_entries[colour & 0xff] & 0xff;
1254*c2c66affSColin Finck   }
1255*c2c66affSColin Finck   else if (g_server_depth == 15)
1256*c2c66affSColin Finck   {
1257*c2c66affSColin Finck     SPLIT_COLOUR15(colour, red, green, blue);
1258*c2c66affSColin Finck   }
1259*c2c66affSColin Finck   else if (g_server_depth == 16)
1260*c2c66affSColin Finck   {
1261*c2c66affSColin Finck     SPLIT_COLOUR16(colour, red, green, blue);
1262*c2c66affSColin Finck   }
1263*c2c66affSColin Finck   else if (g_server_depth == 24 || g_server_depth == 32)
1264*c2c66affSColin Finck   {
1265*c2c66affSColin Finck     red = (colour>>16)&0xff;
1266*c2c66affSColin Finck     green = (colour>>8)&0xff;
1267*c2c66affSColin Finck     blue =  colour&0xff;
1268*c2c66affSColin Finck   }
1269*c2c66affSColin Finck   maindc = GetWindowDC(g_Wnd);
1270*c2c66affSColin Finck   rgn = mi_clip(maindc);
1271*c2c66affSColin Finck   pen = CreatePen(PS_SOLID, 0, RGB(red, green, blue));
1272*c2c66affSColin Finck   save = SelectObject(maindc, pen);
1273*c2c66affSColin Finck   MoveToEx(maindc, x1 + g_xoff - g_xscroll, y1 + g_yoff - g_yscroll, 0);
1274*c2c66affSColin Finck   LineTo(maindc, x2 + g_xoff - g_xscroll, y2 + g_yoff - g_yscroll);
1275*c2c66affSColin Finck   SelectObject(maindc, save);
1276*c2c66affSColin Finck   DeleteObject(pen);
1277*c2c66affSColin Finck   ReleaseDC(g_Wnd, maindc);
1278*c2c66affSColin Finck   DeleteObject(rgn);
1279*c2c66affSColin Finck }
1280*c2c66affSColin Finck 
1281*c2c66affSColin Finck /*****************************************************************************/
1282*c2c66affSColin Finck void
mi_screen_copy(int x,int y,int cx,int cy,int srcx,int srcy)1283*c2c66affSColin Finck mi_screen_copy(int x, int y, int cx, int cy, int srcx, int srcy)
1284*c2c66affSColin Finck {
1285*c2c66affSColin Finck   RECT rect;
1286*c2c66affSColin Finck   RECT clip_rect;
1287*c2c66affSColin Finck   RECT draw_rect;
1288*c2c66affSColin Finck   HRGN rgn;
1289*c2c66affSColin Finck   int ok_to_ScrollWindowEx;
1290*c2c66affSColin Finck 
1291*c2c66affSColin Finck   ok_to_ScrollWindowEx = 1;
1292*c2c66affSColin Finck 
1293*c2c66affSColin Finck   if (!ok_to_ScrollWindowEx)
1294*c2c66affSColin Finck   {
1295*c2c66affSColin Finck     rgn = CreateRectRgn(x - g_xscroll, y - g_yscroll,
1296*c2c66affSColin Finck                         (x - g_xscroll) + cx,
1297*c2c66affSColin Finck                         (y - g_yscroll) + cy);
1298*c2c66affSColin Finck     InvalidateRgn(g_Wnd, rgn, 0);
1299*c2c66affSColin Finck     DeleteObject(rgn);
1300*c2c66affSColin Finck   }
1301*c2c66affSColin Finck   else
1302*c2c66affSColin Finck   {
1303*c2c66affSColin Finck     /* this is all in client coords */
1304*c2c66affSColin Finck     rect.left = srcx - g_xscroll;
1305*c2c66affSColin Finck     rect.top = srcy - g_yscroll;
1306*c2c66affSColin Finck     rect.right = rect.left + cx;
1307*c2c66affSColin Finck     rect.bottom = rect.top + cy;
1308*c2c66affSColin Finck     clip_rect.left = g_clip_left - g_xscroll;
1309*c2c66affSColin Finck     clip_rect.top = g_clip_top - g_yscroll;
1310*c2c66affSColin Finck     clip_rect.right = g_clip_right - g_xscroll;
1311*c2c66affSColin Finck     clip_rect.bottom = g_clip_bottom - g_yscroll;
1312*c2c66affSColin Finck     if (IntersectRect(&draw_rect, &clip_rect, &g_wnd_clip))
1313*c2c66affSColin Finck     {
1314*c2c66affSColin Finck       rgn = CreateRectRgn(0, 0, 0, 0);
1315*c2c66affSColin Finck       ScrollWindowEx(g_Wnd, x - srcx, y - srcy, &rect, &draw_rect,
1316*c2c66affSColin Finck                      rgn, 0, SW_ERASE);
1317*c2c66affSColin Finck       InvalidateRgn(g_Wnd, rgn, 0);
1318*c2c66affSColin Finck       DeleteObject(rgn);
1319*c2c66affSColin Finck     }
1320*c2c66affSColin Finck   }
1321*c2c66affSColin Finck }
1322*c2c66affSColin Finck 
1323*c2c66affSColin Finck /*****************************************************************************/
1324*c2c66affSColin Finck void
mi_set_clip(int x,int y,int cx,int cy)1325*c2c66affSColin Finck mi_set_clip(int x, int y, int cx, int cy)
1326*c2c66affSColin Finck {
1327*c2c66affSColin Finck   g_clip_left = x;
1328*c2c66affSColin Finck   g_clip_top = y;
1329*c2c66affSColin Finck   g_clip_right = g_clip_left + cx;
1330*c2c66affSColin Finck   g_clip_bottom = g_clip_top + cy;
1331*c2c66affSColin Finck }
1332*c2c66affSColin Finck 
1333*c2c66affSColin Finck /*****************************************************************************/
1334*c2c66affSColin Finck void
mi_reset_clip(void)1335*c2c66affSColin Finck mi_reset_clip(void)
1336*c2c66affSColin Finck {
1337*c2c66affSColin Finck   g_clip_left = 0;
1338*c2c66affSColin Finck   g_clip_top = 0;
1339*c2c66affSColin Finck   g_clip_right = g_clip_left + g_width;
1340*c2c66affSColin Finck   g_clip_bottom = g_clip_top + g_height;
1341*c2c66affSColin Finck }
1342*c2c66affSColin Finck 
1343*c2c66affSColin Finck /*****************************************************************************/
1344*c2c66affSColin Finck void *
mi_create_cursor(unsigned int x,unsigned int y,int width,int height,unsigned char * andmask,unsigned char * xormask)1345*c2c66affSColin Finck mi_create_cursor(unsigned int x, unsigned int y,
1346*c2c66affSColin Finck                  int width, int height,
1347*c2c66affSColin Finck                  unsigned char * andmask, unsigned char * xormask)
1348*c2c66affSColin Finck {
1349*c2c66affSColin Finck   HCURSOR hCur;
1350*c2c66affSColin Finck 
1351*c2c66affSColin Finck   hCur = CreateCursor(g_Instance, x, y, width, height, andmask, xormask);
1352*c2c66affSColin Finck   if (hCur == 0)
1353*c2c66affSColin Finck   {
1354*c2c66affSColin Finck     hCur = LoadCursor(NULL, IDC_ARROW);
1355*c2c66affSColin Finck   }
1356*c2c66affSColin Finck   return hCur;
1357*c2c66affSColin Finck }
1358*c2c66affSColin Finck 
1359*c2c66affSColin Finck /*****************************************************************************/
1360*c2c66affSColin Finck void
mi_destroy_cursor(void * cursor)1361*c2c66affSColin Finck mi_destroy_cursor(void * cursor)
1362*c2c66affSColin Finck {
1363*c2c66affSColin Finck   if (g_cursor == cursor)
1364*c2c66affSColin Finck   {
1365*c2c66affSColin Finck     g_cursor = 0;
1366*c2c66affSColin Finck   }
1367*c2c66affSColin Finck   DestroyCursor(cursor);
1368*c2c66affSColin Finck }
1369*c2c66affSColin Finck 
1370*c2c66affSColin Finck /*****************************************************************************/
1371*c2c66affSColin Finck void
mi_set_cursor(void * cursor)1372*c2c66affSColin Finck mi_set_cursor(void * cursor)
1373*c2c66affSColin Finck {
1374*c2c66affSColin Finck   g_cursor = cursor;
1375*c2c66affSColin Finck   SetCursor(g_cursor);
1376*c2c66affSColin Finck }
1377*c2c66affSColin Finck 
1378*c2c66affSColin Finck /*****************************************************************************/
1379*c2c66affSColin Finck void
mi_set_null_cursor(void)1380*c2c66affSColin Finck mi_set_null_cursor(void)
1381*c2c66affSColin Finck {
1382*c2c66affSColin Finck }
1383*c2c66affSColin Finck 
1384