diff --git a/xrdp/Makefile b/xrdp/Makefile index 9bc95767..c6f5eafd 100644 --- a/xrdp/Makefile +++ b/xrdp/Makefile @@ -1,8 +1,8 @@ -XRDPOBJ = xrdp.o os_calls.o xrdp_tcp.o xrdp_iso.o xrdp_mcs.o xrdp_sec.o xrdp_rdp.o \ - xrdp_process.o xrdp_listen.o xrdp_orders.o xrdp_bitmap.o xrdp_wm.o \ - xrdp_painter.o xrdp_list.o xrdp_region.o xrdp_cache.o xrdp_font.o \ - funcs.o +XRDPOBJ = xrdp.o os_calls.o xrdp_tcp.o xrdp_iso.o xrdp_mcs.o xrdp_sec.o \ + xrdp_rdp.o xrdp_process.o xrdp_listen.o xrdp_orders.o \ + xrdp_bitmap.o xrdp_wm.o xrdp_painter.o xrdp_list.o \ + xrdp_region.o xrdp_cache.o xrdp_font.o funcs.o #CFLAGS = -Wall -O2 -DXRDP_DEBUG CFLAGS = -Wall -O2 LDFLAGS = -L /usr/gnu/lib diff --git a/xrdp/funcs.c b/xrdp/funcs.c index de367201..66229604 100644 --- a/xrdp/funcs.c +++ b/xrdp/funcs.c @@ -268,3 +268,47 @@ char get_char_from_scan_code(int device_flags, int scan_code, int* keys, } return rv; } + +/*****************************************************************************/ +/* add a ch at index position in text, index starts at 0 */ +/* if index = -1 add it to the end */ +int add_char_at(char* text, char ch, int index) +{ + int len; + int i; + + len = g_strlen(text); + if (index >= len || index < 0) + { + text[len] = ch; + text[len + 1] = 0; + return 0; + } + for (i = len - 1; i >= index; i--) + text[i + 1] = text[i]; + text[i + 1] = ch; + text[len + 1] = 0; + return 0; +} + +/*****************************************************************************/ +/* remove a ch at index position in text, index starts at 0 */ +/* if index = -1 remove it from the end */ +int remove_char_at(char* text, int index) +{ + int len; + int i; + + len = g_strlen(text); + if (len <= 0) + return 0; + if (index >= len - 1 || index < 0) + { + text[len - 1] = 0; + return 0; + } + for (i = index; i < len - 1; i++) + text[i] = text[i + 1]; + text[len - 1] = 0; + return 0; +} diff --git a/xrdp/os_calls.c b/xrdp/os_calls.c index a9663a00..bed917c3 100644 --- a/xrdp/os_calls.c +++ b/xrdp/os_calls.c @@ -55,7 +55,7 @@ static int g_term = 0; #ifdef MEMLEAK static int g_memsize = 0; static int g_memid = 0; -struct xrdp_list* g_memlist = 0; +static struct xrdp_list* g_memlist = 0; #endif /*****************************************************************************/ @@ -254,9 +254,9 @@ int g_tcp_set_non_blocking(int sck) #ifdef _WIN32 i = 1; - ioctlsocket(sck, FIONBIO, &i); -#else - i = fcntl(sck, F_GETFL); + ioctlsocket(sck, FIONBIO, &i); +#else + i = fcntl(sck, F_GETFL); i = i | O_NONBLOCK; fcntl(sck, F_SETFL, i); #endif @@ -633,6 +633,16 @@ char* g_strcpy(char* dest, char* src) return strcpy(dest, src); } +/*****************************************************************************/ +char* g_strncpy(char* dest, char* src, int len) +{ + char* rv; + + rv = strncpy(dest, src, len); + dest[len] = 0; + return rv; +} + /*****************************************************************************/ char* g_strcat(char* dest, char* src) { diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 59d3b80e..966d60e5 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -36,45 +36,7 @@ #include "parse.h" #include "xrdp_types.h" #include "constants.h" -/* check for debug */ -#ifdef XRDP_DEBUG -#define DEBUG(args) g_printf args; -#else -#define DEBUG(args) -#endif -/* other macros */ -#define MIN(x1, x2) ((x1) < (x2) ? (x1) : (x2)) -#define MAX(x1, x2) ((x1) > (x2) ? (x1) : (x2)) -#define HIWORD(in) (((in) & 0xffff0000) >> 16) -#define LOWORD(in) ((in) & 0x0000ffff) -#define MAKELONG(hi, lo) ((((hi) & 0xffff) << 16) | ((lo) & 0xffff)) -#define MAKERECT(r, x, y, cx, cy) \ -{ (r).left = x; (r).top = y; (r).right = (x) + (cx); (r).bottom = (y) + (cy); } -#define ISRECTEMPTY(r) (((r).right <= (r).left) || ((r).bottom <= (r).top)) -#define RECTOFFSET(r, dx, dy) \ -{ (r).left += dx; (r).top += dy; (r).right += dx; (r).bottom += dy; } -#define GETPIXEL8(d, x, y, w) (*(((unsigned char*)d) + ((y) * (w) + (x)))) -#define GETPIXEL16(d, x, y, w) (*(((unsigned short*)d) + ((y) * (w) + (x)))) -#define GETPIXEL32(d, x, y, w) (*(((unsigned long*)d) + ((y) * (w) + (x)))) -#define SETPIXEL8(d, x, y, w, v) \ -(*(((unsigned char*)d) + ((y) * (w) + (x))) = (v)) -#define SETPIXEL16(d, x, y, w, v) \ -(*(((unsigned short*)d) + ((y) * (w) + (x))) = (v)) -#define SETPIXEL32(d, x, y, w, v) \ -(*(((unsigned long*)d) + ((y) * (w) + (x))) = (v)) -#define COLOR15(r, g, b) ((((r) >> 3) << 10) | (((g) >> 3) << 5) | ((b) >> 3)) -#define COLOR16(r, g, b) ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3)) -#define COLOR24(r, g, b) ((r) | ((g) << 8) | ((b) << 16)) -/* font macros */ -#define FONT_DATASIZE(f) ((((f)->height * (((f)->width + 7) / 8)) + 3) & ~3); - -#ifdef _WIN32 -#define THREAD_RV unsigned long -#define THREAD_CC __stdcall -#else -#define THREAD_RV void* -#define THREAD_CC -#endif +#include "xrdp_defines.h" /* os_calls.c */ int g_init_system(void); @@ -128,6 +90,7 @@ int g_file_seek(int fd, int offset); int g_file_lock(int fd, int start, int len); int g_strlen(char* text); char* g_strcpy(char* dest, char* src); +char* g_strncpy(char* dest, char* src, int len); char* g_strcat(char* dest, char* src); /* xrdp_tcp.c */ @@ -330,3 +293,6 @@ int rect_intersect(struct xrdp_rect* in1, struct xrdp_rect* in2, int check_bounds(struct xrdp_bitmap* b, int* x, int* y, int* cx, int* cy); char get_char_from_scan_code(int device_flags, int scan_code, int* keys, int caps_lock, int num_lock, int scroll_lock); +int add_char_at(char* text, char ch, int index); +int remove_char_at(char* text, int index); + diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c index 75555080..2b5b9a50 100644 --- a/xrdp/xrdp_bitmap.c +++ b/xrdp/xrdp_bitmap.c @@ -359,6 +359,7 @@ int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect) struct xrdp_rect r1; struct xrdp_rect r2; struct xrdp_painter* painter; + char text[256]; if (self == 0) /* if no bitmap */ return 0; @@ -533,6 +534,20 @@ int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect) /* draw text */ painter->fg_color = self->wm->black; xrdp_painter_draw_text(painter, self, 4, 2, self->caption); + /* draw xor box */ + if (self->parent != 0) + { + if (self->parent->focused_control == self) + { + g_strncpy(text, self->caption, self->edit_pos); + w = xrdp_painter_text_width(painter, text); + painter->fg_color = self->wm->black; + painter->rop = 0x5a; + xrdp_painter_fill_rect(painter, self, 4 + w, 3, 2, self->height - 6); + } + } + /* reset rop back */ + painter->rop = 0xcc; } else if (self->type == WND_TYPE_LABEL) /* 6 */ { @@ -569,11 +584,13 @@ int xrdp_bitmap_def_proc(struct xrdp_bitmap* self, int msg, int param1, int param2) { char c; - char a[2]; int n; int i; int shift; + int ext; + int scan_code; struct xrdp_bitmap* b; + struct xrdp_bitmap* focus_out_control; if (self == 0) return 0; @@ -583,7 +600,8 @@ int xrdp_bitmap_def_proc(struct xrdp_bitmap* self, int msg, { if (msg == WM_KEYDOWN) { - if (param1 == 15) /* tab */ + scan_code = param1 % 128; + if (scan_code == 15) /* tab */ { /* move to next tab stop */ shift = self->wm->keys[42] || self->wm->keys[54]; @@ -609,7 +627,10 @@ int xrdp_bitmap_def_proc(struct xrdp_bitmap* self, int msg, n--; if (b->tab_stop) { + focus_out_control = self->focused_control; self->focused_control = b; + xrdp_bitmap_invalidate(focus_out_control, 0); + xrdp_bitmap_invalidate(b, 0); break; } if (shift) @@ -637,26 +658,87 @@ int xrdp_bitmap_def_proc(struct xrdp_bitmap* self, int msg, { if (msg == WM_KEYDOWN) { - if (param1 == 14) /* backspace */ + scan_code = param1 % 128; + ext = param2 & 0x0100; + /* left or up arrow */ + if ((scan_code == 75 || scan_code == 72) && + (ext || self->wm->num_lock == 0)) + { + if (self->edit_pos > 0) + { + self->edit_pos--; + xrdp_bitmap_invalidate(self, 0); + } + } + /* right or down arrow */ + else if ((scan_code == 77 || scan_code == 80) && + (ext || self->wm->num_lock == 0)) + { + if (self->edit_pos < g_strlen(self->caption)) + { + self->edit_pos++; + xrdp_bitmap_invalidate(self, 0); + } + } + /* backspace */ + else if (scan_code == 14) + { + n = g_strlen(self->caption); + if (n > 0) + { + if (self->edit_pos > 0) + { + self->edit_pos--; + remove_char_at(self->caption, self->edit_pos); + xrdp_bitmap_invalidate(self, 0); + } + } + } + /* delete */ + else if (scan_code == 83 && + (ext || self->wm->num_lock == 0)) { n = g_strlen(self->caption); if (n > 0) { - self->caption[n - 1] = 0; + if (self->edit_pos < n) + { + remove_char_at(self->caption, self->edit_pos); + xrdp_bitmap_invalidate(self, 0); + } + } + } + /* end */ + else if (scan_code == 79 && + (ext || self->wm->num_lock == 0)) + { + n = g_strlen(self->caption); + if (self->edit_pos < n) + { + self->edit_pos = n; + xrdp_bitmap_invalidate(self, 0); + } + } + /* home */ + else if (scan_code == 71 && + (ext || self->wm->num_lock == 0)) + { + if (self->edit_pos > 0) + { + self->edit_pos = 0; xrdp_bitmap_invalidate(self, 0); } } else { - c = get_char_from_scan_code(param2, param1, self->wm->keys, + c = get_char_from_scan_code(param2, scan_code, self->wm->keys, self->wm->caps_lock, self->wm->num_lock, self->wm->scroll_lock); if (c != 0) { - a[0] = c; - a[1] = 0; - g_strcat(self->caption, a); + add_char_at(self->caption, c, self->edit_pos); + self->edit_pos++; xrdp_bitmap_invalidate(self, 0); } } diff --git a/xrdp/xrdp_painter.c b/xrdp/xrdp_painter.c index 9ea7d46a..b3508fff 100644 --- a/xrdp/xrdp_painter.c +++ b/xrdp/xrdp_painter.c @@ -347,7 +347,7 @@ int xrdp_painter_text_width(struct xrdp_painter* self, char* text) len = g_strlen(text); for (index = 0; index < len; index++) { - font_item = self->font->font_items + text[index]; + font_item = self->font->font_items + (unsigned char)text[index]; rv = rv + font_item->incby; } return rv; @@ -365,7 +365,7 @@ int xrdp_painter_text_height(struct xrdp_painter* self, char* text) len = g_strlen(text); for (index = 0; index < len; index++) { - font_item = self->font->font_items + text[index]; + font_item = self->font->font_items + (unsigned char)text[index]; rv = MAX(rv, font_item->height); } return rv; @@ -412,7 +412,7 @@ int xrdp_painter_draw_text(struct xrdp_painter* self, data = (char*)g_malloc(len * 4, 1); for (index = 0; index < len; index++) { - font_item = font->font_items + text[index]; + font_item = font->font_items + (unsigned char)text[index]; i = xrdp_cache_add_char(self->wm->cache, font_item); f = HIWORD(i); c = LOWORD(i); diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index 4bed6cbe..41757b11 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -369,31 +369,39 @@ struct xrdp_painter /* window or bitmap */ struct xrdp_bitmap { - int type; /* 0 = bitmap 1 = window 2 = screen 3 = button 4 = image 5 = edit 6 = label */ - int state; /* for button 0 = normal 1 = down */ - int id; - char* data; + /* 0 = bitmap 1 = window 2 = screen 3 = button 4 = image 5 = edit + 6 = label */ + int type; int width; int height; + struct xrdp_wm* wm; + /* msg 1 = click 2 = mouse move 3 = paint 100 = modal result */ + /* see messages in constants.h */ + int (*notify)(struct xrdp_bitmap* wnd, struct xrdp_bitmap* sender, + int msg, int param1, int param2); + /* for bitmap */ int bpp; + int line_size; /* in bytes */ + char* data; + /* for all but bitmap */ int left; int top; + int cursor; int bg_color; - int line_size; /* in bytes */ - int focused; int tab_stop; + int focused; + int id; char caption[256]; + /* for window or screen */ struct xrdp_bitmap* modal_dialog; struct xrdp_bitmap* focused_control; struct xrdp_bitmap* owner; /* window that created us */ struct xrdp_bitmap* parent; /* window contained in */ struct xrdp_list* child_list; - struct xrdp_wm* wm; - int cursor; + /* for edit */ int edit_pos; - /* msg 1 = click 2 = mouse move 3 = paint 100 = modal result */ - int (*notify)(struct xrdp_bitmap* wnd, struct xrdp_bitmap* sender, - int msg, int param1, int param2); + /* for button */ + int state; /* for button 0 = normal 1 = down */ }; /* font */ diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index e1bdd6b4..5c07fd55 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -16,7 +16,6 @@ xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2004 - xrdp: A Remote Desktop Protocol server. simple window manager */ @@ -469,7 +468,7 @@ int xrdp_wm_init(struct xrdp_wm* self) self->login_window->top = self->screen->height / 2 - self->login_window->height / 2; self->login_window->notify = xrdp_wm_login_notify; - strcpy(self->login_window->caption, "Logon to xrdp"); + g_strcpy(self->login_window->caption, "Logon to xrdp"); /* image */ but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE); @@ -861,6 +860,7 @@ int xrdp_wm_mouse_move(struct xrdp_wm* self, int x, int y) int xrdp_wm_mouse_click(struct xrdp_wm* self, int x, int y, int but, int down) { struct xrdp_bitmap* control; + struct xrdp_bitmap* focus_out_control; struct xrdp_bitmap* wnd; int newx; int newy; @@ -903,7 +903,12 @@ int xrdp_wm_mouse_click(struct xrdp_wm* self, int x, int y, int but, int down) if (control == wnd) wnd->focused_control = 0; else + { + focus_out_control = wnd->focused_control; wnd->focused_control = control; + xrdp_bitmap_invalidate(focus_out_control, 0); + } + xrdp_bitmap_invalidate(control, 0); if (wnd->modal_dialog != 0) /* if window has a modal dialog */ return 0; }