summaryrefslogtreecommitdiffstats
path: root/uirdesktop/win32.c
diff options
context:
space:
mode:
Diffstat (limited to 'uirdesktop/win32.c')
-rwxr-xr-xuirdesktop/win32.c1733
1 files changed, 1733 insertions, 0 deletions
diff --git a/uirdesktop/win32.c b/uirdesktop/win32.c
new file mode 100755
index 00000000..75862216
--- /dev/null
+++ b/uirdesktop/win32.c
@@ -0,0 +1,1733 @@
+/* -*- c-basic-offset: 8 -*-
+ rdesktop: A Remote Desktop Protocol client.
+ win32 calls
+ Copyright (C) Jay Sorg 2006
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef _WIN32_WCE
+#define MYWINCE
+#endif
+
+#include <winsock2.h> /* winsock2.h first */
+#include <windows.h>
+#ifdef MYWINCE
+#include <aygshell.h> /* aygshell.lib */
+#endif /* MYWINCE */
+#include <winuser.h>
+#include <stdio.h>
+#include "uimain.h"
+
+extern char g_username[];
+extern char g_hostname[];
+extern char g_servername[];
+extern char g_password[];
+extern char g_shell[];
+extern char g_directory[];
+extern char g_domain[];
+extern int g_width;
+extern int g_height;
+extern int g_tcp_sck;
+extern int g_server_depth;
+extern int g_tcp_port_rdp; /* in tcp.c */
+extern int pal_entries[];
+extern char * g_bs;
+extern int g_bs_bpp;
+extern int g_bs_Bpp;
+
+static HWND g_Wnd = 0;
+static HINSTANCE g_Instance = 0;
+static HCURSOR g_cursor = 0;
+static HBITMAP g_bs_bitmap = 0;
+static int g_block = 0;
+static int g_xoff = 0; /* offset from window to client coords */
+static int g_yoff = 0;
+static int g_xscroll = 0; /* current scroll position */
+static int g_yscroll = 0;
+static int g_screen_width = 0;
+static int g_screen_height = 0;
+static int g_wnd_cwidth = 0; /* set from WM_SIZE */
+static int g_wnd_cheight = 0;
+static int g_fullscreen = 0;
+static int g_workarea = 0;
+static int g_mousex = 0; /* in client coords */
+static int g_mousey = 0;
+static int g_width_height_set = 0;
+
+static int g_clip_left = 0;
+static int g_clip_top = 0;
+static int g_clip_right = 800;
+static int g_clip_bottom = 600;
+static RECT g_wnd_clip; /* this client area of whats actually visable */
+ /* set from WM_SIZE */
+#ifdef MYWINCE
+static int g_sip_up = 0;
+#endif
+
+/*****************************************************************************/
+static void
+str_to_uni(TCHAR * sizex, char * size1)
+{
+ int len;
+ int i;
+
+ len = strlen(size1);
+ for (i = 0; i < len; i++)
+ {
+ sizex[i] = size1[i];
+ }
+ sizex[len] = 0;
+}
+
+/*****************************************************************************/
+/* returns non zero if it processed something */
+static int
+check_sck(void)
+{
+ fd_set rfds;
+ struct timeval tm;
+ int count;
+ int rv;
+
+ rv = 0;
+ if (g_block == 0)
+ {
+ g_block = 1;
+ /* see if there really is data */
+ FD_ZERO(&rfds);
+ FD_SET((unsigned int)g_tcp_sck, &rfds);
+ ZeroMemory(&tm, sizeof(tm));
+ count = select(g_tcp_sck + 1, &rfds, 0, 0, &tm);
+ if (count > 0)
+ {
+ if (ui_read_wire())
+ {
+ rv = 1;
+ }
+ else
+ {
+ PostQuitMessage(0);
+ }
+ }
+ g_block = 0;
+ }
+ return rv;
+}
+
+/*****************************************************************************/
+void
+mi_error(char * msg)
+{
+#ifdef WITH_DEBUG
+ printf(msg);
+#else /* WITH_DEBUG */
+ TCHAR lmsg[512];
+ TCHAR ltitle[512];
+
+ str_to_uni(lmsg, msg);
+ str_to_uni(ltitle, "Error");
+ MessageBox(g_Wnd, lmsg, ltitle, MB_OK);
+#endif /* WITH_DEBUG */
+}
+
+/*****************************************************************************/
+static int
+get_scan_code_from_ascii(int code)
+{
+ int rv;
+
+ rv = 0;
+ switch (code & 0xff)
+ {
+ case 0x30: rv = 0x0b; break; // 0
+ case 0x31: rv = 0x02; break; // 1
+ case 0x32: rv = 0x03; break; // 2
+ case 0x33: rv = 0x04; break; // 3
+ case 0x34: rv = 0x05; break; // 4
+ case 0x35: rv = 0x06; break; // 5
+ case 0x36: rv = 0x07; break; // 6
+ case 0x37: rv = 0x08; break; // 7
+ case 0x38: rv = 0x09; break; // 8
+ case 0x39: rv = 0x0a; break; // 9
+
+ case 0xbd: rv = 0x0c; break; // -
+ case 0xbb: rv = 0x0d; break; // =
+ case 0x08: rv = 0x0e; break; // backspace
+ case 0x09: rv = 0x0f; break; // tab
+ case 0xdb: rv = 0x1b; break; // ]
+ case 0xdd: rv = 0x1a; break; // [
+ case 0x14: rv = 0x3a; break; // capslock
+ case 0xba: rv = 0x27; break; // ;
+ case 0xde: rv = 0x28; break; // '
+ case 0x10: rv = 0x2a; break; // shift
+ case 0xbc: rv = 0x33; break; // ,
+ case 0xbe: rv = 0x34; break; // .
+ case 0xbf: rv = 0x35; break; // /
+ case 0x0d: rv = 0x1c; break; // enter
+ case 0x27: rv = 0x4d; break; // arrow right
+ case 0x25: rv = 0x4b; break; // arrow left
+ case 0x26: rv = 0x48; break; // arrow up
+ case 0x28: rv = 0x50; break; // arrow down
+ case 0x20: rv = 0x39; break; // space
+ case 0xdc: rv = 0x2b; break; // backslash
+ case 0xc0: rv = 0x29; break; // `
+ case 0x11: rv = 0x1d; break; // ctl
+
+ case 0x41: rv = 0x1e; break; // a
+ case 0x42: rv = 0x30; break; // b
+ case 0x43: rv = 0x2e; break; // c
+ case 0x44: rv = 0x20; break; // d
+ case 0x45: rv = 0x12; break; // e
+ case 0x46: rv = 0x21; break; // f
+ case 0x47: rv = 0x22; break; // g
+ case 0x48: rv = 0x23; break; // h
+ case 0x49: rv = 0x17; break; // i
+ case 0x4a: rv = 0x24; break; // j
+ case 0x4b: rv = 0x25; break; // k
+ case 0x4c: rv = 0x26; break; // l
+ case 0x4d: rv = 0x32; break; // m
+ case 0x4e: rv = 0x31; break; // n
+ case 0x4f: rv = 0x18; break; // o
+ case 0x50: rv = 0x19; break; // p
+ case 0x51: rv = 0x10; break; // q
+ case 0x52: rv = 0x13; break; // r
+ case 0x53: rv = 0x1f; break; // s
+ case 0x54: rv = 0x14; break; // t
+ case 0x55: rv = 0x16; break; // u
+ case 0x56: rv = 0x2f; break; // v
+ case 0x57: rv = 0x11; break; // w
+ case 0x58: rv = 0x2d; break; // x
+ case 0x59: rv = 0x15; break; // y
+ case 0x5a: rv = 0x2c; break; // z
+ }
+ return rv;
+}
+
+/*****************************************************************************/
+static void
+mi_scroll(int dx, int dy)
+{
+ HRGN rgn;
+
+ rgn = CreateRectRgn(0, 0, 0, 0);
+ ScrollWindowEx(g_Wnd, dx, dy, 0, 0, rgn, 0, SW_ERASE);
+ InvalidateRgn(g_Wnd, rgn, 0);
+ DeleteObject(rgn);
+}
+
+/*****************************************************************************/
+int
+mi_read_keyboard_state(void)
+{
+ short keydata;
+ int code;
+
+ code = 0;
+ keydata = GetKeyState(VK_SCROLL);
+ if (keydata & 0x0001)
+ {
+ code |= 1;
+ }
+ keydata = GetKeyState(VK_NUMLOCK);
+ if (keydata & 0x0001)
+ {
+ code |= 2;
+ }
+ keydata = GetKeyState(VK_CAPITAL);
+ if (keydata & 0x0001)
+ {
+ code |= 4;
+ }
+ return code;
+}
+
+/*****************************************************************************/
+static void
+mi_check_modifier(void)
+{
+ int code;
+
+ code = mi_read_keyboard_state();
+ ui_set_modifier_state(code);
+}
+
+/*****************************************************************************/
+static LRESULT
+handle_WM_SETCURSOR(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ if (g_mousex >= g_wnd_clip.left &&
+ g_mousey >= g_wnd_clip.top &&
+ g_mousex < g_wnd_clip.right &&
+ g_mousey < g_wnd_clip.bottom)
+ {
+ SetCursor(g_cursor);
+ }
+ /* need default behavoir here */
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+/*****************************************************************************/
+static LRESULT
+handle_WM_NCHITTEST(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ POINT pt;
+
+ pt.x = LOWORD(lParam);
+ pt.y = HIWORD(lParam);
+ if (ScreenToClient(g_Wnd, &pt))
+ {
+ g_mousex = pt.x;
+ g_mousey = pt.y;
+ }
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+/*****************************************************************************/
+static LRESULT
+handle_WM_MOUSEMOVE(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ g_mousex = LOWORD(lParam);
+ g_mousey = HIWORD(lParam);
+ ui_mouse_move(g_mousex + g_xscroll, g_mousey + g_yscroll);
+ return 0;
+}
+
+/*****************************************************************************/
+static LRESULT
+handle_WM_LBUTTONDOWN(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ g_mousex = LOWORD(lParam);
+ g_mousey = HIWORD(lParam);
+ ui_mouse_button(1, g_mousex + g_xscroll, g_mousey + g_yscroll, 1);
+ return 0;
+}
+
+/*****************************************************************************/
+static LRESULT
+handle_WM_LBUTTONUP(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ g_mousex = LOWORD(lParam);
+ g_mousey = HIWORD(lParam);
+ ui_mouse_button(1, g_mousex + g_xscroll, g_mousey + g_yscroll, 0);
+ return 0;
+}
+
+/*****************************************************************************/
+static LRESULT
+handle_WM_RBUTTONDOWN(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ g_mousex = LOWORD(lParam);
+ g_mousey = HIWORD(lParam);
+ ui_mouse_button(2, g_mousex + g_xscroll, g_mousey + g_yscroll, 1);
+ return 0;
+}
+
+/*****************************************************************************/
+static LRESULT
+handle_WM_RBUTTONUP(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ g_mousex = LOWORD(lParam);
+ g_mousey = HIWORD(lParam);
+ ui_mouse_button(2, g_mousex + g_xscroll, g_mousey + g_yscroll, 0);
+ return 0;
+}
+
+/*****************************************************************************/
+static LRESULT
+handle_WM_MBUTTONDOWN(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ g_mousex = LOWORD(lParam);
+ g_mousey = HIWORD(lParam);
+ ui_mouse_button(3, g_mousex + g_xscroll, g_mousey + g_yscroll, 1);
+ return 0;
+}
+
+/*****************************************************************************/
+static LRESULT
+handle_WM_MBUTTONUP(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ g_mousex = LOWORD(lParam);
+ g_mousey = HIWORD(lParam);
+ ui_mouse_button(3, g_mousex + g_xscroll, g_mousey + g_yscroll, 0);
+ return 0;
+}
+
+/*****************************************************************************/
+static LRESULT
+handle_WM_MOUSEWHEEL(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ int delta;
+
+ delta = ((signed short)HIWORD(wParam)); /* GET_WHEEL_DELTA_WPARAM(wParam); */
+ if (delta > 0)
+ {
+ ui_mouse_button(4, 0, 0, 1);
+ ui_mouse_button(4, 0, 0, 0);
+ }
+ else
+ {
+ ui_mouse_button(5, 0, 0, 1);
+ ui_mouse_button(5, 0, 0, 0);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static LRESULT
+handle_WM_KEY(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ int scancode;
+ int ext;
+ int down;
+
+ ext = HIWORD(lParam);
+ scancode = ext;
+ down = !(ext & 0x8000);
+ scancode &= 0xff;
+ if (scancode == 0)
+ {
+ scancode = get_scan_code_from_ascii(wParam);
+ }
+ ext &= 0x0100;
+ if (scancode == 0x0045) /* num lock */
+ {
+ ext &= ~0x0100;
+ }
+ if (down)
+ {
+ ui_key_down(scancode, ext);
+ }
+ else
+ {
+ ui_key_up(scancode, ext);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static LRESULT
+handle_WM_PAINT(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ PAINTSTRUCT ps;
+ RECT rect;
+ HBRUSH brush;
+
+ BeginPaint(hWnd, &ps);
+ /* paint the area outside the rdp screen with one colour */
+ rect = ps.rcPaint;
+ rect.left = UI_MAX(rect.left, g_width);
+ if (!IsRectEmpty(&rect))
+ {
+ brush = CreateSolidBrush(RGB(0, 0, 255));
+ FillRect(ps.hdc, &rect, brush);
+ DeleteObject(brush);
+ }
+ rect = ps.rcPaint;
+ rect.top = UI_MAX(rect.top, g_height);
+ if (!IsRectEmpty(&rect))
+ {
+ brush = CreateSolidBrush(RGB(0, 0, 255));
+ FillRect(ps.hdc, &rect, brush);
+ DeleteObject(brush);
+ }
+ rect = ps.rcPaint;
+ EndPaint(hWnd, &ps);
+ ui_invalidate(rect.left + g_xscroll,
+ rect.top + g_yscroll,
+ (rect.right - rect.left) + 1,
+ (rect.bottom - rect.top) + 1);
+ return 0;
+}
+
+/*****************************************************************************/
+static LRESULT
+handle_WM_SIZE(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ int oldxscroll;
+ int oldyscroll;
+
+ if (wParam == SIZE_MINIMIZED)
+ {
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ }
+ g_wnd_cwidth = LOWORD(lParam); /* client width / height */
+ g_wnd_cheight = HIWORD(lParam);
+ g_wnd_clip.left = 0;
+ g_wnd_clip.top = 0;
+ g_wnd_clip.right = g_wnd_clip.left + g_wnd_cwidth;
+ g_wnd_clip.bottom = g_wnd_clip.top + g_wnd_cheight;
+ if (g_wnd_cwidth < g_width || g_wnd_cheight < g_height)
+ {
+ SetScrollRange(g_Wnd, SB_HORZ, 0, g_width - g_wnd_cwidth, 1);
+ SetScrollRange(g_Wnd, SB_VERT, 0, g_height - g_wnd_cheight, 1);
+ }
+ oldxscroll = g_xscroll;
+ oldyscroll = g_yscroll;
+ if (g_wnd_cwidth >= g_width)
+ {
+ g_xscroll = 0;
+ }
+ else
+ {
+ g_xscroll = UI_MIN(g_xscroll, g_width - g_wnd_cwidth);
+ }
+ if (g_wnd_cheight >= g_height)
+ {
+ g_yscroll = 0;
+ }
+ else
+ {
+ g_yscroll = UI_MIN(g_yscroll, g_height - g_wnd_cheight);
+ }
+ mi_scroll(oldxscroll - g_xscroll, oldyscroll - g_yscroll);
+ if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED)
+ {
+ /* check the caps, num, and scroll lock here */
+ mi_check_modifier();
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static LRESULT
+handle_WM_SIZING(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LPRECT prect;
+ int width;
+ int height;
+ int style;
+
+ prect = (LPRECT) lParam; /* total window rect */
+ width = (prect->right - prect->left) - (g_xoff * 2);
+ height = (prect->bottom - prect->top) - (g_yoff + g_xoff);
+ if (height < g_height || width < g_width)
+ {
+ style = GetWindowLong(g_Wnd, GWL_STYLE);
+ if (!(style & WS_HSCROLL))
+ {
+ style |= WS_HSCROLL | WS_VSCROLL;
+ SetWindowLong(g_Wnd, GWL_STYLE, style);
+ g_xscroll = 0;
+ g_yscroll = 0;
+ SetScrollPos(g_Wnd, SB_HORZ, g_xscroll, 1);
+ SetScrollPos(g_Wnd, SB_VERT, g_yscroll, 1);
+ }
+ }
+ else if (height >= g_height && width >= g_width)
+ {
+ style = GetWindowLong(g_Wnd, GWL_STYLE);
+ if (style & WS_HSCROLL)
+ {
+ style &= ~WS_HSCROLL;
+ style &= ~WS_VSCROLL;
+ SetWindowLong(g_Wnd, GWL_STYLE, style);
+ g_xscroll = 0;
+ g_yscroll = 0;
+ }
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static LRESULT
+handle_WM_HSCROLL(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ int code;
+ int oldxscroll;
+
+ code = (int) LOWORD(wParam); /* scroll bar value */
+ if (code == SB_LINELEFT)
+ {
+ oldxscroll = g_xscroll;
+ g_xscroll--;
+ g_xscroll = UI_MAX(g_xscroll, 0);
+ SetScrollPos(g_Wnd, SB_HORZ, g_xscroll, 1);
+ mi_scroll(oldxscroll - g_xscroll, 0);
+ }
+ else if (code == SB_LINERIGHT)
+ {
+ oldxscroll = g_xscroll;
+ g_xscroll++;
+ g_xscroll = UI_MIN(g_xscroll, g_width - g_wnd_cwidth);
+ SetScrollPos(g_Wnd, SB_HORZ, g_xscroll, 1);
+ mi_scroll(oldxscroll - g_xscroll, 0);
+ }
+ else if (code == SB_PAGELEFT)
+ {
+ oldxscroll = g_xscroll;
+ g_xscroll -= g_wnd_cwidth / 2;
+ g_xscroll = UI_MAX(g_xscroll, 0);
+ SetScrollPos(g_Wnd, SB_HORZ, g_xscroll, 1);
+ mi_scroll(oldxscroll - g_xscroll, 0);
+ }
+ else if (code == SB_PAGERIGHT)
+ {
+ oldxscroll = g_xscroll;
+ g_xscroll += g_wnd_cwidth / 2;
+ g_xscroll = UI_MIN(g_xscroll, g_width - g_wnd_cwidth);
+ SetScrollPos(g_Wnd, SB_HORZ, g_xscroll, 1);
+ mi_scroll(oldxscroll - g_xscroll, 0);
+ }
+ else if (code == SB_BOTTOM)
+ {
+ oldxscroll = g_xscroll;
+ g_xscroll = g_width - g_wnd_cwidth;
+ SetScrollPos(g_Wnd, SB_HORZ, g_xscroll, 1);
+ mi_scroll(oldxscroll - g_xscroll, 0);
+ }
+ else if (code == SB_TOP)
+ {
+ oldxscroll = g_xscroll;
+ g_xscroll = 0;
+ SetScrollPos(g_Wnd, SB_HORZ, g_xscroll, 1);
+ mi_scroll(oldxscroll - g_xscroll, 0);
+ }
+ else if (code == SB_THUMBPOSITION)
+ {
+ oldxscroll = g_xscroll;
+ g_xscroll = (signed short) HIWORD(wParam);
+ SetScrollPos(g_Wnd, SB_HORZ, g_xscroll, 1);
+ mi_scroll(oldxscroll - g_xscroll, 0);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static LRESULT
+handle_WM_VSCROLL(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ int code;
+ int oldyscroll;
+
+ code = (int) LOWORD(wParam); /* scroll bar value */
+ if (code == SB_LINELEFT)
+ {
+ oldyscroll = g_yscroll;
+ g_yscroll--;
+ g_yscroll = UI_MAX(g_yscroll, 0);
+ SetScrollPos(g_Wnd, SB_VERT, g_yscroll, 1);
+ mi_scroll(0, oldyscroll - g_yscroll);
+ }
+ else if (code == SB_LINERIGHT)
+ {
+ oldyscroll = g_yscroll;
+ g_yscroll++;
+ g_yscroll = UI_MIN(g_yscroll, g_height - g_wnd_cheight);
+ SetScrollPos(g_Wnd, SB_VERT, g_yscroll, 1);
+ mi_scroll(0, oldyscroll - g_yscroll);
+ }
+ else if (code == SB_PAGELEFT)
+ {
+ oldyscroll = g_yscroll;
+ g_yscroll -= g_wnd_cheight / 2;
+ g_yscroll = UI_MAX(g_yscroll, 0);
+ SetScrollPos(g_Wnd, SB_VERT, g_yscroll, 1);
+ mi_scroll(0, oldyscroll - g_yscroll);
+ }
+ else if (code == SB_PAGERIGHT)
+ {
+ oldyscroll = g_yscroll;
+ g_yscroll += g_wnd_cheight / 2;
+ g_yscroll = UI_MIN(g_yscroll, g_height - g_wnd_cheight);
+ SetScrollPos(g_Wnd, SB_VERT, g_yscroll, 1);
+ mi_scroll(0, oldyscroll - g_yscroll);
+ }
+ else if (code == SB_BOTTOM)
+ {
+ oldyscroll = g_yscroll;
+ g_yscroll = g_height - g_wnd_cheight;
+ SetScrollPos(g_Wnd, SB_VERT, g_yscroll, 1);
+ mi_scroll(0, oldyscroll - g_yscroll);
+ }
+ else if (code == SB_TOP)
+ {
+ oldyscroll = g_yscroll;
+ g_yscroll = 0;
+ SetScrollPos(g_Wnd, SB_VERT, g_yscroll, 1);
+ mi_scroll(0, oldyscroll - g_yscroll);
+ }
+ else if (code == SB_THUMBPOSITION)
+ {
+ oldyscroll = g_yscroll;
+ g_yscroll = (signed short) HIWORD(wParam);
+ SetScrollPos(g_Wnd, SB_VERT, g_yscroll, 1);
+ mi_scroll(0, oldyscroll - g_yscroll);
+ }
+ return 0;
+}
+
+#ifdef MYWINCE
+/*****************************************************************************/
+static LRESULT
+handle_WM_SETTINGCHANGE(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ SIPINFO si;
+ SHMENUBARINFO mb;
+ int x;
+ int y;
+ int w;
+ int h;
+ int style;
+
+ ZeroMemory(&si, sizeof(SIPINFO));
+ si.cbSize = sizeof(SIPINFO);
+ SHSipInfo(SPI_GETSIPINFO, lParam, &si, 0);
+ x = si.rcVisibleDesktop.left;
+ y = si.rcVisibleDesktop.top;
+ w = si.rcVisibleDesktop.right - x;
+ h = si.rcVisibleDesktop.bottom - y;
+ /* get rid of menu */
+ DestroyWindow(SHFindMenuBar(g_Wnd));
+ if (si.fdwFlags & SIPF_ON)
+ {
+ g_sip_up = 1; /* used for WM_SETFOCUS */
+ ZeroMemory(&mb, sizeof(SHMENUBARINFO));
+ mb.cbSize = sizeof(SHMENUBARINFO);
+ mb.hwndParent = g_Wnd;
+ mb.dwFlags = SHCMBF_EMPTYBAR;
+ SHCreateMenuBar(&mb);
+ MoveWindow(g_Wnd, x, y, w, h, FALSE);
+ SHFullScreen(g_Wnd, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON |
+ SHFS_SHOWSTARTICON);
+ }
+ else
+ {
+ g_sip_up = 0;
+ if (g_fullscreen)
+ {
+ MoveWindow(g_Wnd, 0, 0, g_screen_width, g_screen_height, FALSE);
+ }
+ else
+ {
+ MoveWindow(g_Wnd, x, y, w, h, FALSE);
+ }
+ if ((g_fullscreen && g_width <= g_screen_width &&
+ g_height <= g_screen_height) ||
+ (!g_fullscreen && g_width <= w && g_height <= h))
+ {
+ style = GetWindowLong(g_Wnd, GWL_STYLE);
+ if (style & WS_HSCROLL)
+ {
+ style &= ~WS_HSCROLL;
+ style &= ~WS_VSCROLL;
+ SetWindowLong(g_Wnd, GWL_STYLE, style);
+ g_xscroll = 0;
+ g_yscroll = 0;
+ }
+ }
+ if (g_fullscreen)
+ {
+ SHFullScreen(g_Wnd, SHFS_HIDETASKBAR | SHFS_SHOWSIPBUTTON |
+ SHFS_SHOWSTARTICON);
+ }
+ else
+ {
+ SHFullScreen(g_Wnd, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON |
+ SHFS_SHOWSTARTICON);
+ }
+ }
+ return 0;
+}
+#endif /* MYWINCE */
+
+/*****************************************************************************/
+LRESULT CALLBACK
+WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_SETCURSOR:
+ return handle_WM_SETCURSOR(hWnd, message, wParam, lParam);
+ case 0x0084: /* WinCE don't have this WM_NCHITTEST: */
+ return handle_WM_NCHITTEST(hWnd, message, wParam, lParam);
+ case WM_MOUSEMOVE:
+ return handle_WM_MOUSEMOVE(hWnd, message, wParam, lParam);
+ case WM_LBUTTONDOWN:
+ return handle_WM_LBUTTONDOWN(hWnd, message, wParam, lParam);
+ case WM_LBUTTONUP:
+ return handle_WM_LBUTTONUP(hWnd, message, wParam, lParam);
+ case WM_RBUTTONDOWN:
+ return handle_WM_RBUTTONDOWN(hWnd, message, wParam, lParam);
+ case WM_RBUTTONUP:
+ return handle_WM_RBUTTONUP(hWnd, message, wParam, lParam);
+ case WM_MBUTTONDOWN:
+ return handle_WM_MBUTTONDOWN(hWnd, message, wParam, lParam);
+ case WM_MBUTTONUP:
+ return handle_WM_MBUTTONUP(hWnd, message, wParam, lParam);
+ /* some windows compilers don't have these defined like vc6 */
+ case 0x020a: /* WM_MOUSEWHEEL: */
+ return handle_WM_MOUSEWHEEL(hWnd, message, wParam, lParam);
+ case WM_KEYDOWN:
+ case WM_KEYUP:
+ case WM_SYSKEYDOWN:
+ case WM_SYSKEYUP:
+ return handle_WM_KEY(hWnd, message, wParam, lParam);
+ case WM_CHAR:
+ case WM_DEADCHAR:
+ case WM_SYSCHAR:
+ case WM_SYSDEADCHAR:
+ break;
+ case WM_PAINT:
+ return handle_WM_PAINT(hWnd, message, wParam, lParam);
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+ case WM_APP + 1:
+ case WM_TIMER:
+ check_sck();
+ break;
+ case WM_SIZE:
+ return handle_WM_SIZE(hWnd, message, wParam, lParam);
+ case 532: /* not defined in wince WM_SIZING: */
+ return handle_WM_SIZING(hWnd, message, wParam, lParam);
+ case WM_HSCROLL:
+ return handle_WM_HSCROLL(hWnd, message, wParam, lParam);
+ case WM_VSCROLL:
+ return handle_WM_VSCROLL(hWnd, message, wParam, lParam);
+#ifdef MYWINCE
+ case WM_SETTINGCHANGE:
+ return handle_WM_SETTINGCHANGE(hWnd, message, wParam, lParam);
+#endif /* MYWINCE */
+ case WM_SETFOCUS:
+ mi_check_modifier();
+#ifdef MYWINCE
+ if (g_sip_up)
+ {
+ SHSipPreference(hWnd, SIP_UP);
+ }
+#endif
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ default:
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static HRGN
+mi_clip(HDC dc)
+{
+ HRGN rgn;
+
+ rgn = CreateRectRgn(g_clip_left + g_xoff - g_xscroll,
+ g_clip_top + g_yoff - g_yscroll,
+ g_clip_right + g_xoff - g_xscroll,
+ g_clip_bottom + g_yoff - g_yscroll);
+ SelectClipRgn(dc, rgn);
+ IntersectClipRect(dc, g_wnd_clip.left + g_xoff, g_wnd_clip.top + g_yoff,
+ g_wnd_clip.right + g_xoff, g_wnd_clip.bottom + g_yoff);
+ return rgn;
+}
+
+/*****************************************************************************/
+static void
+mi_show_error(char * caption)
+{
+ LPVOID lpMsgBuf;
+ TCHAR lcaption[512];
+
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf, 0, NULL);
+#ifdef WITH_DEBUG
+ printf(lpMsgBuf);
+#else /* WITH_DEBUG */
+ str_to_uni(lcaption, caption);
+ MessageBox(g_Wnd, (LPTSTR) lpMsgBuf, lcaption,
+ MB_OK | MB_ICONINFORMATION);
+#endif /* WITH_DEBUG */
+ LocalFree(lpMsgBuf);
+}
+
+/*****************************************************************************/
+void
+mi_invalidate(int x, int y, int cx, int cy)
+{
+ HDC dc;
+ HDC maindc;
+ HGDIOBJ save;
+ HRGN rgn;
+ int dstx;
+ int dsty;
+
+ maindc = GetWindowDC(g_Wnd);
+ dc = CreateCompatibleDC(maindc);
+ if (dc == 0)
+ {
+ mi_show_error("CreateCompatibleDC failed in mi_invalidate");
+ }
+ save = SelectObject(dc, g_bs_bitmap);
+ dstx = (x + g_xoff) - g_xscroll;
+ dsty = (y + g_yoff) - g_yscroll;
+ rgn = mi_clip(maindc);
+ BitBlt(maindc, dstx, dsty, cx, cy, dc, x, y, SRCCOPY);
+ SelectObject(dc, save);
+ DeleteDC(dc);
+ ReleaseDC(g_Wnd, maindc);
+ DeleteObject(rgn);
+}
+
+/*****************************************************************************/
+int
+mi_create_bs(void)
+{
+ HBITMAP bitmap;
+ BITMAPINFO bi;
+ HDC maindc;
+
+ ZeroMemory(&bi, sizeof(bi));
+ bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
+ bi.bmiHeader.biWidth = g_width;
+ bi.bmiHeader.biHeight = -g_height;
+ bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biBitCount = 32;
+ bi.bmiHeader.biCompression = BI_RGB;
+ maindc = GetWindowDC(g_Wnd);
+ g_bs_bitmap = CreateDIBSection(maindc, &bi, DIB_RGB_COLORS, (void **) &g_bs, 0, 0);
+ ReleaseDC(g_Wnd, maindc);
+ g_bs_bpp = 32;
+ g_bs_Bpp = 4;
+ if (g_bs_bitmap != 0)
+ {
+ //FillMemory(g_bs, g_width * g_height * 4, 0xff);
+ ZeroMemory(g_bs, g_width * g_height * 4);
+ UpdateWindow(g_Wnd);
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns non zero if ok */
+int
+mi_create_window(void)
+{
+ RECT rc;
+ WNDCLASS wc;
+ TCHAR classname[512];
+ TCHAR caption[512];
+ DWORD style;
+ int x;
+ int y;
+ int w;
+ int h;
+
+ if (g_Wnd != 0 || g_Instance != 0)
+ {
+ return 0;
+ }
+ g_Instance = GetModuleHandle(NULL);
+ ZeroMemory(&wc, sizeof(wc));
+ wc.lpfnWndProc = WndProc; /* points to window procedure */
+ /* name of window class */
+ str_to_uni(classname, "rdesktop");
+ wc.lpszClassName = classname;
+ str_to_uni(caption, "WinRDesktop");
+ /* Register the window class. */
+ if (!RegisterClass(&wc))
+ {
+ return 0; /* Failed to register window class */
+ }
+ rc.left = 0;
+ rc.right = rc.left + UI_MIN(g_width, g_screen_width);
+ rc.top = 0;
+ rc.bottom = rc.top + UI_MIN(g_height, g_screen_height);
+#ifdef MYWINCE
+ SHInitExtraControls();
+ x = CW_USEDEFAULT;
+ y = CW_USEDEFAULT;
+ w = CW_USEDEFAULT;
+ h = CW_USEDEFAULT;
+ style = WS_VISIBLE;
+ if (g_fullscreen)
+ {
+ x = 0;
+ y = 0;
+ w = g_screen_width;
+ h = g_screen_height;
+ }
+#else /* MYWINCE */
+ if (g_fullscreen)
+ {
+ style = WS_POPUP;
+ }
+ else
+ {
+ style = WS_OVERLAPPED | WS_CAPTION | WS_POPUP | WS_MINIMIZEBOX |
+ WS_SYSMENU | WS_SIZEBOX | WS_MAXIMIZEBOX;
+ }
+ if (g_screen_width < g_width || g_screen_height < g_height)
+ {
+ style |= WS_HSCROLL | WS_VSCROLL;
+ }
+ AdjustWindowRectEx(&rc, style, 0, 0);
+ x = CW_USEDEFAULT;
+ y = CW_USEDEFAULT;
+ w = rc.right - rc.left;
+ h = rc.bottom - rc.top;
+#endif /* MYWINCE */
+ g_Wnd = CreateWindow(wc.lpszClassName, caption,
+ style, x, y, w, h,
+ (HWND) NULL, (HMENU) NULL, g_Instance,
+ (LPVOID) NULL);
+ g_clip_left = 0;
+ g_clip_top = 0;
+ g_clip_right = g_clip_left + g_width;
+ g_clip_bottom = g_clip_top + g_height;
+ if (g_workarea)
+ {
+ ShowWindow(g_Wnd, SW_SHOWMAXIMIZED);
+ }
+ else
+ {
+ ShowWindow(g_Wnd, SW_SHOWNORMAL);
+ }
+
+#ifdef MYWINCE
+ if (g_fullscreen)
+ {
+ SHFullScreen(g_Wnd, SHFS_HIDETASKBAR | SHFS_SHOWSIPBUTTON |
+ SHFS_SHOWSTARTICON);
+ }
+ else
+ {
+ SHFullScreen(g_Wnd, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON |
+ SHFS_SHOWSTARTICON);
+ }
+#endif /* MYWINCE */
+
+ /* WinCE doesn't have WSAAsyncSelect */
+#ifdef MYWINCE
+ SetTimer(g_Wnd, 1, 1000 / 60, 0); /* 60 per second */
+#else /* MYWINCE */
+ WSAAsyncSelect(g_tcp_sck, g_Wnd, WM_APP + 1, FD_READ);
+ SetTimer(g_Wnd, 1, 333, 0);
+#endif /* MYWINCE */
+ return 1;
+}
+
+/*****************************************************************************/
+int
+mi_main_loop(void)
+{
+ MSG msg;
+
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ return msg.wParam;
+}
+
+/*****************************************************************************/
+void
+mi_warning(char * msg)
+{
+}
+
+/*****************************************************************************/
+void
+mi_paint_rect(char * data, int width, int height, int x, int y, int cx, int cy)
+{
+ HBITMAP bitmap;
+ BITMAPINFO bi;
+ HDC dc;
+ HDC maindc;
+ HGDIOBJ save;
+ HRGN rgn;
+ void * bits;
+ int i;
+ int j;
+ int colour;
+ int red;
+ int green;
+ int blue;
+
+ ZeroMemory(&bi, sizeof(bi));
+ bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
+ bi.bmiHeader.biWidth = width;
+ bi.bmiHeader.biHeight = -height;
+ bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biBitCount = 32;
+ bi.bmiHeader.biCompression = BI_RGB;
+ maindc = GetWindowDC(g_Wnd);
+ bitmap = CreateDIBSection(maindc, &bi, DIB_RGB_COLORS, (void **) &bits, 0, 0);
+ if (bitmap == 0)
+ {
+ mi_show_error("CreateDIBSection failed");
+ }
+
+ if (g_server_depth == 8)
+ {
+ for (i = cy - 1; i >= 0; i--)
+ {
+ for (j = cx - 1; j >= 0; j--)
+ {
+ colour = ((unsigned char*)data)[i * cx + j];
+ red = (pal_entries[colour & 0xff] & 0xff0000) >> 16;
+ green = (pal_entries[colour & 0xff] & 0xff00) >> 8;
+ blue = pal_entries[colour & 0xff] & 0xff;
+ MAKE_COLOUR32(colour, red, green, blue);
+ ((unsigned int*)bits)[i * cx + j] = colour;
+ }
+ }
+ }
+ else if (g_server_depth == 15)
+ {
+ for (i = cy - 1; i >= 0; i--)
+ {
+ for (j = cx - 1; j >= 0; j--)
+ {
+ colour = ((unsigned short*)data)[i * cx + j];
+ SPLIT_COLOUR15(colour, red, green, blue);
+ MAKE_COLOUR32(colour, red, green, blue);
+ ((unsigned int*)bits)[i * cx + j] = colour;
+ }
+ }
+ }
+ else if (g_server_depth == 16)
+ {
+ for (i = cy - 1; i >= 0; i--)
+ {
+ for (j = cx - 1; j >= 0; j--)
+ {
+ colour = ((unsigned short*)data)[i * cx + j];
+ SPLIT_COLOUR16(colour, red, green, blue);
+ MAKE_COLOUR32(colour, red, green, blue);
+ ((unsigned int*)bits)[i * cx + j] = colour;
+ }
+ }
+ }
+ dc = CreateCompatibleDC(maindc);
+ if (dc == 0)
+ {
+ mi_show_error("CreateCompatibleDC failed");
+ }
+ save = SelectObject(dc, bitmap);
+ rgn = mi_clip(maindc);
+ BitBlt(maindc, x + g_xoff - g_xscroll, y + g_yoff - g_yscroll, cx, cy, dc,
+ 0, 0, SRCCOPY);
+ SelectObject(dc, save);
+ DeleteObject(bitmap);
+ DeleteDC(dc);
+ ReleaseDC(g_Wnd, maindc);
+ DeleteObject(rgn);
+
+}
+
+/*****************************************************************************/
+static int
+mi_process_a_param(char * param1, int state)
+{
+ char * p;
+
+ if (state == 0)
+ {
+ if (strcmp(param1, "-g") == 0 || strcmp(param1, "geometry") == 0)
+ {
+ state = 1;
+ }
+ if (strcmp(param1, "-t") == 0 || strcmp(param1, "port") == 0)
+ {
+ state = 2;
+ }
+ if (strcmp(param1, "-a") == 0 || strcmp(param1, "bpp") == 0)
+ {
+ state = 3;
+ }
+ if (strcmp(param1, "-f") == 0 || strcmp(param1, "fullscreen") == 0)
+ {
+ g_fullscreen = 1;
+ }
+ if (strcmp(param1, "-u") == 0 || strcmp(param1, "username") == 0)
+ {
+ state = 5;
+ }
+ if (strcmp(param1, "-p") == 0 || strcmp(param1, "password") == 0)
+ {
+ state = 6;
+ }
+ if (strcmp(param1, "-d") == 0 || strcmp(param1, "domain") == 0)
+ {
+ state = 7;
+ }
+ if (strcmp(param1, "-s") == 0 || strcmp(param1, "shell") == 0)
+ {
+ state = 8;
+ }
+ if (strcmp(param1, "-c") == 0 || strcmp(param1, "directory") == 0)
+ {
+ state = 9;
+ }
+ if (strcmp(param1, "-n") == 0 || strcmp(param1, "hostname") == 0)
+ {
+ state = 10;
+ }
+ }
+ else
+ {
+ if (state == 1) /* -g */
+ {
+ state = 0;
+ if (strcmp(param1, "workarea") == 0)
+ {
+ g_workarea = 1;
+ return state;
+ }
+ g_width = strtol(param1, &p, 10);
+ if (g_width <= 0)
+ {
+ mi_error("invalid geometry\r\n");
+ }
+ if (*p == 'x')
+ {
+ g_height = strtol(p + 1, &p, 10);
+ }
+ if (g_height <= 0)
+ {
+ mi_error("invalid geometry\r\n");
+ }
+ g_width_height_set = 1;
+ }
+ if (state == 2) /* -t */
+ {
+ state = 0;
+ g_tcp_port_rdp = atol(param1);
+ }
+ if (state == 3) /* -a */
+ {
+ state = 0;
+ g_server_depth = atol(param1);
+ if (g_server_depth != 8 && g_server_depth != 15 &&
+ g_server_depth != 16 && g_server_depth != 24)
+ {
+ mi_error("invalid server bpp\r\n");
+ }
+ }
+ if (state == 5) /* -u */
+ {
+ state = 0;
+ strcpy(g_username, param1);
+ }
+ if (state == 6) /* -p */
+ {
+ state = 0;
+ strcpy(g_password, param1);
+ }
+ if (state == 7) /* -d */
+ {
+ state = 0;
+ strcpy(g_domain, param1);
+ }
+ if (state == 8) /* -s */
+ {
+ state = 0;
+ strcpy(g_shell, param1);
+ }
+ if (state == 9) /* -c */
+ {
+ state = 0;
+ strcpy(g_directory, param1);
+ }
+ if (state == 10) /* -n */
+ {
+ state = 0;
+ strcpy(g_hostname, param1);
+ }
+ }
+ return state;
+}
+
+/*****************************************************************************/
+static int
+mi_post_param(void)
+{
+ /* after parameters */
+ if (g_fullscreen)
+ {
+ g_xoff = 0;
+ g_yoff = 0;
+ if (!g_width_height_set)
+ {
+ g_width = g_screen_width;
+ g_height = g_screen_height;
+ }
+ }
+ else if (g_workarea)
+ {
+#ifdef MYWINCE
+ g_xoff = 0;
+ g_yoff = 0;
+ g_width = g_screen_width;
+ g_height = g_screen_height - 26; /* start menu size is 26 */
+#else /* MYWINCE */
+ g_xoff = GetSystemMetrics(SM_CXEDGE) * 2;
+ g_yoff = GetSystemMetrics(SM_CYCAPTION) +
+ GetSystemMetrics(SM_CYEDGE) * 2;
+ g_width = g_screen_width;
+ g_height = g_screen_height;
+ g_height = (g_height - g_yoff) - g_xoff - 20; /* todo */
+#endif /* MYWINCE */
+ g_width_height_set = 1;
+ }
+ else
+ {
+#ifdef MYWINCE
+ g_xoff = 0;
+ g_yoff = 0;
+#else /* MYWINCE */
+ g_xoff = GetSystemMetrics(SM_CXEDGE) * 2;
+ g_yoff = GetSystemMetrics(SM_CYCAPTION) +
+ GetSystemMetrics(SM_CYEDGE) * 2;
+#endif /* MYWINCE */
+ }
+ g_width = g_width & (~3);
+ return 1;
+}
+
+/*****************************************************************************/
+static int
+mi_check_config_file(void)
+{
+ HANDLE fd;
+ DWORD count;
+ TCHAR filename[256];
+ char buffer[256];
+ char vname[256];
+ char value[256];
+ int index;
+ int mode;
+ int vnameindex;
+ int valueindex;
+ int state;
+ int rv;
+
+ rv = 0;
+ mode = 0;
+ vnameindex = 0;
+ valueindex = 0;
+ vname[vnameindex] = 0;
+ value[valueindex] = 0;
+#ifdef MYWINCE
+ str_to_uni(filename, "\\My Documents\\winrdesktop.ini");
+#else /* MYWINCE */
+ str_to_uni(filename, ".\\winrdesktop.ini");
+#endif /* MYWINCE */
+ fd = CreateFile(filename, GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ count = 255;
+ while (ReadFile(fd, buffer, count, &count, NULL))
+ {
+ if (count == 0)
+ {
+ break;
+ }
+ buffer[count] = 0;
+ index = 0;
+ while (index < (int) count)
+ {
+ if (buffer[index] == '=')
+ {
+ mode = 1;
+ }
+ else if (buffer[index] == 10 || buffer[index] == 13)
+ {
+ mode = 0;
+ vname[vnameindex] = 0;
+ value[valueindex] = 0;
+ if (strlen(vname) > 0 || strlen(value) > 0)
+ {
+ if (strcmp(vname, "server") == 0)
+ {
+ strcpy(g_servername, value);
+ rv = 1;
+ }
+ else
+ {
+ state = mi_process_a_param(vname, 0);
+ mi_process_a_param(value, state);
+ }
+ }
+ vnameindex = 0;
+ valueindex = 0;
+ }
+ else if (mode == 0)
+ {
+ vname[vnameindex] = buffer[index];
+ vnameindex++;
+ }
+ else
+ {
+ value[valueindex] = buffer[index];
+ valueindex++;
+ }
+ index++;
+ }
+ count = 255;
+ }
+ CloseHandle(fd);
+ if (rv)
+ {
+ mi_post_param();
+ }
+ return rv;
+}
+
+/*****************************************************************************/
+/* process the command line parameters */
+/* returns boolean, non zero is ok */
+static int
+mi_process_cl(LPTSTR lpCmdLine)
+{
+ char param[256];
+ char param1[256];
+#ifndef MYWINCE
+ TCHAR l_username[256];
+#endif
+ DWORD size;
+ int len;
+ int i;
+ int i1;
+ int state;
+
+ strcpy(g_hostname, "test");
+ strcpy(g_username, "pda");
+ /* get username and convert it from unicode */
+ size = 255;
+#ifndef MYWINCE
+ /* WinCE doesn't have GetUserName */
+ if (GetUserName(l_username, &size))
+ {
+ for (i = size; i >= 0; i--)
+ {
+ g_username[i] = (char) l_username[i];
+ }
+ g_username[size] = 0;
+ }
+ else
+ {
+ mi_show_error("GetUserName");
+ }
+#endif /* MYWINCE */
+ /* get computer name */
+ if (gethostname(g_hostname, 255) != 0)
+ {
+ mi_show_error("gethostname");
+ }
+ /* defaults */
+ strcpy(g_servername, "127.0.0.1");
+ g_server_depth = 8;
+ g_screen_width = GetSystemMetrics(SM_CXSCREEN);
+ g_screen_height = GetSystemMetrics(SM_CYSCREEN);
+ /* process parameters */
+ i1 = 0;
+ state = 0;
+ len = lstrlen(lpCmdLine);
+ if (len == 0)
+ {
+ return mi_check_config_file();
+ }
+ for (i = 0; i < len; i++)
+ {
+ if (lpCmdLine[i] != 32 && lpCmdLine[i] != 9) /* space or tab */
+ {
+ param[i1] = (char) lpCmdLine[i];
+ i1++;
+ }
+ else
+ {
+ param[i1] = 0;
+ i1 = 0;
+ strcpy(param1, param);
+ state = mi_process_a_param(param1, state);
+ strcpy(g_servername, param1);
+ }
+ }
+ if (i1 > 0)
+ {
+ param[i1] = 0;
+ strcpy(param1, param);
+ state = mi_process_a_param(param1, state);
+ strcpy(g_servername, param1);
+ }
+ if (state == 0)
+ {
+ mi_post_param();
+ }
+ return (state == 0);
+}
+
+/*****************************************************************************/
+/* display the command line options available */
+static void
+mi_show_params(void)
+{
+ char text1[512 * 4];
+ TCHAR textx[512 * 4];
+ TCHAR lcaption[64];
+
+ strcpy(text1, "");
+ strcat(text1, "WinRDesktop - an RDP client based on rdesktop\r\n");
+ strcat(text1, "You can't run this application without " );
+ strcat(text1, "correct parameters\r\n");
+ strcat(text1, "\r\n");
+ strcat(text1, "command line options\r\n");
+ strcat(text1, "\r\n");
+ strcat(text1, "WinRDesktop [-g widthxheight] [-t port] [-a bpp]\r\n");
+ strcat(text1, " [-f] [-u username] [-p password] [-d domain]\r\n");
+ strcat(text1, " [-s shell] [-c working directory] [-n host name]\r\n");
+ strcat(text1, " server-name-or-ip\r\n");
+ strcat(text1, "\r\n");
+ strcat(text1, "You can use a config file in the current directory\r\n");
+ strcat(text1, "called WinRDesktop.ini\r\n");
+ strcat(text1, "The file should look like this...\r\n");
+ strcat(text1, "[main]\r\n");
+ strcat(text1, "server=192.168.1.1\r\n");
+ strcat(text1, "port=3389\r\n");
+ strcat(text1, "username=user1\r\n");
+ strcat(text1, "password=password1\r\n");
+ strcat(text1, "bpp=16\r\n");
+ strcat(text1, "geometry=800x600\r\n");
+#ifdef WITH_DEBUG
+ printf(text1);
+#else /* WITH_DEBUG */
+ str_to_uni(lcaption, "WinRDesktop");
+ str_to_uni(textx, text1);
+ MessageBox(g_Wnd, textx, lcaption, MB_OK);
+#endif /* WITH_DEBUG */
+}
+
+#ifdef WITH_DEBUG
+/*****************************************************************************/
+int
+main(int argc, char ** argv)
+{
+ WSADATA d;
+
+ WSAStartup(MAKEWORD(2, 0), &d);
+ if (!mi_process_cl(argv[0]))
+ {
+ mi_show_params();
+ WSACleanup();
+ return 0;
+ }
+ return ui_main();
+}
+#else /* WITH_DEBUG */
+/*****************************************************************************/
+int WINAPI
+WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
+ LPTSTR lpCmdLine, int nCmdShow)
+{
+ WSADATA d;
+
+ WSAStartup(MAKEWORD(2, 0), &d);
+ if (!mi_process_cl(lpCmdLine))
+ {
+ mi_show_params();
+ WSACleanup();
+ return 0;
+ }
+ return ui_main();
+}
+#endif /* WITH_DEBUG */
+
+/*****************************************************************************/
+void
+mi_begin_update(void)
+{
+}
+
+/*****************************************************************************/
+void
+mi_end_update(void)
+{
+}
+
+/*****************************************************************************/
+void
+mi_fill_rect(int x, int y, int cx, int cy, int colour)
+{
+ HBRUSH brush;
+ RECT rect;
+ HDC maindc;
+ HRGN rgn;
+ int red;
+ int green;
+ int blue;
+
+ red = (colour & 0xff0000) >> 16;
+ green = (colour & 0xff00) >> 8;
+ blue = colour & 0xff;
+ maindc = GetWindowDC(g_Wnd);
+ rgn = mi_clip(maindc);
+ brush = CreateSolidBrush(RGB(red, green, blue));
+ rect.left = x + g_xoff - g_xscroll;
+ rect.top = y + g_yoff - g_yscroll;
+ rect.right = rect.left + cx;
+ rect.bottom = rect.top + cy;
+ FillRect(maindc, &rect, brush);
+ DeleteObject(brush);
+ ReleaseDC(g_Wnd, maindc);
+ DeleteObject(rgn);
+}
+
+/*****************************************************************************/
+void
+mi_line(int x1, int y1, int x2, int y2, int colour)
+{
+ HPEN pen;
+ HDC maindc;
+ HGDIOBJ save;
+ HRGN rgn;
+ int red;
+ int green;
+ int blue;
+
+ red = (colour & 0xff0000) >> 16;
+ green = (colour & 0xff00) >> 8;
+ blue = colour & 0xff;
+ maindc = GetWindowDC(g_Wnd);
+ rgn = mi_clip(maindc);
+ pen = CreatePen(PS_SOLID, 0, RGB(red, green, blue));
+ save = SelectObject(maindc, pen);
+ MoveToEx(maindc, x1 + g_xoff - g_xscroll, y1 + g_yoff - g_yscroll, 0);
+ LineTo(maindc, x2 + g_xoff - g_xscroll, y2 + g_yoff - g_yscroll);
+ SelectObject(maindc, save);
+ DeleteObject(pen);
+ ReleaseDC(g_Wnd, maindc);
+ DeleteObject(rgn);
+}
+
+/*****************************************************************************/
+void
+mi_screen_copy(int x, int y, int cx, int cy, int srcx, int srcy)
+{
+ RECT rect;
+ RECT clip_rect;
+ RECT draw_rect;
+ HRGN rgn;
+ int ok_to_ScrollWindowEx;
+
+ /* WinCE can't scroll in 2 directions at once */
+#ifdef MYWINCE
+ ok_to_ScrollWindowEx = cx == 0 || cy == 0;
+#else /* MYWINCE */
+ ok_to_ScrollWindowEx = 1;
+#endif /* MYWINCE */
+ if (!ok_to_ScrollWindowEx)
+ {
+ rgn = CreateRectRgn(x - g_xscroll, y - g_yscroll,
+ (x - g_xscroll) + cx,
+ (y - g_yscroll) + cy);
+ InvalidateRgn(g_Wnd, rgn, 0);
+ DeleteObject(rgn);
+ }
+ else
+ {
+ /* this is all in client coords */
+ rect.left = srcx - g_xscroll;
+ rect.top = srcy - g_yscroll;
+ rect.right = rect.left + cx;
+ rect.bottom = rect.top + cy;
+ clip_rect.left = g_clip_left - g_xscroll;
+ clip_rect.top = g_clip_top - g_yscroll;
+ clip_rect.right = g_clip_right - g_xscroll;
+ clip_rect.bottom = g_clip_bottom - g_yscroll;
+ if (IntersectRect(&draw_rect, &clip_rect, &g_wnd_clip))
+ {
+ rgn = CreateRectRgn(0, 0, 0, 0);
+ ScrollWindowEx(g_Wnd, x - srcx, y - srcy, &rect, &draw_rect,
+ rgn, 0, SW_ERASE);
+ InvalidateRgn(g_Wnd, rgn, 0);
+ DeleteObject(rgn);
+ }
+ }
+}
+
+/*****************************************************************************/
+void
+mi_set_clip(int x, int y, int cx, int cy)
+{
+ g_clip_left = x;
+ g_clip_top = y;
+ g_clip_right = g_clip_left + cx;
+ g_clip_bottom = g_clip_top + cy;
+}
+
+/*****************************************************************************/
+void
+mi_reset_clip(void)
+{
+ g_clip_left = 0;
+ g_clip_top = 0;
+ g_clip_right = g_clip_left + g_width;
+ g_clip_bottom = g_clip_top + g_height;
+}
+
+/*****************************************************************************/
+void *
+mi_create_cursor(unsigned int x, unsigned int y,
+ int width, int height,
+ unsigned char * andmask, unsigned char * xormask)
+{
+#ifdef MYWINCE
+ return (void *) 1;
+#else /* MYWINCE */
+ HCURSOR hCur;
+
+ hCur = CreateCursor(g_Instance, x, y, width, height, andmask, xormask);
+ if (hCur == 0)
+ {
+ hCur = LoadCursor(NULL, IDC_ARROW);
+ }
+ return hCur;
+#endif /* MYWINCE */
+}
+
+/*****************************************************************************/
+void
+mi_destroy_cursor(void * cursor)
+{
+#ifdef MYWINCE
+#else /* MYWINCE */
+ if (g_cursor == cursor)
+ {
+ g_cursor = 0;
+ }
+ DestroyCursor(cursor);
+#endif /* MYWINCE */
+}
+
+/*****************************************************************************/
+void
+mi_set_cursor(void * cursor)
+{
+#ifdef MYWINCE
+#else /* MYWINCE */
+ g_cursor = cursor;
+ SetCursor(g_cursor);
+#endif /* MYWINCE */
+}
+
+/*****************************************************************************/
+void
+mi_set_null_cursor(void)
+{
+}
+