1734 lines
43 KiB
C
Executable File
1734 lines
43 KiB
C
Executable File
/* -*- 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, 1000 / 60, 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)
|
|
{
|
|
}
|
|
|