diff --git a/xrdp/constants.h b/xrdp/constants.h index 5fc18107..981ce611 100644 --- a/xrdp/constants.h +++ b/xrdp/constants.h @@ -406,6 +406,7 @@ #define WND_TYPE_IMAGE 4 #define WND_TYPE_EDIT 5 #define WND_TYPE_LABEL 6 +#define WND_TYPE_COMBO 7 /* button states */ #define BUTTON_STATE_UP 0 diff --git a/xrdp/os_calls.c b/xrdp/os_calls.c index bed917c3..2b55bec0 100644 --- a/xrdp/os_calls.c +++ b/xrdp/os_calls.c @@ -52,6 +52,10 @@ static pthread_mutex_t g_term_mutex = PTHREAD_MUTEX_INITIALIZER; #endif static int g_term = 0; +#ifdef MEMLEAK +#include "xrdp.h" +#endif + #ifdef MEMLEAK static int g_memsize = 0; static int g_memid = 0; @@ -648,3 +652,17 @@ char* g_strcat(char* dest, char* src) { return strcat(dest, src); } + +/*****************************************************************************/ +char* g_strdup(char* in) +{ + int len; + char* p; + + if (in == 0) + return 0; + len = g_strlen(in); + p = (char*)g_malloc(len + 1, 0); + g_strcpy(p, in); + return p; +} diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 966d60e5..59b9f6b4 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -92,6 +92,7 @@ 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); +char* g_strdup(char* in); /* xrdp_tcp.c */ struct xrdp_tcp* xrdp_tcp_create(struct xrdp_iso* owner); diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c index 3b076c2d..90460385 100644 --- a/xrdp/xrdp_bitmap.c +++ b/xrdp/xrdp_bitmap.c @@ -17,6 +17,9 @@ Copyright (C) Jay Sorg 2004 bitmap, drawable + this is a object that can be drawn on with a painter + all windows, bitmaps, even the screen are of this type + maybe it should be called xrdp_drawable */ @@ -41,9 +44,16 @@ struct xrdp_bitmap* xrdp_bitmap_create(int width, int height, int bpp, case 15: Bpp = 2; break; case 16: Bpp = 2; break; } - self->data = (char*)g_malloc(width * height * Bpp, 1); - self->child_list = xrdp_list_create(); + if (self->type == WND_TYPE_SCREEN || self->type == WND_TYPE_BITMAP) + self->data = (char*)g_malloc(width * height * Bpp, 1); + if (self->type != WND_TYPE_BITMAP) + self->child_list = xrdp_list_create(); self->line_size = ((width + 3) & ~3) * Bpp; + if (self->type == WND_TYPE_COMBO) + { + self->string_list = xrdp_list_create(); + self->string_list->auto_free = 1; + } return self; } @@ -68,9 +78,13 @@ void xrdp_bitmap_delete(struct xrdp_bitmap* self) if (self->wm->button_down == self) self->wm->button_down = 0; } - for (i = 0; i < self->child_list->count; i++) - xrdp_bitmap_delete((struct xrdp_bitmap*)self->child_list->items[i]); - xrdp_list_delete(self->child_list); + if (self->child_list != 0) + { + for (i = 0; i < self->child_list->count; i++) + xrdp_bitmap_delete((struct xrdp_bitmap*)self->child_list->items[i]); + xrdp_list_delete(self->child_list); + } + xrdp_list_delete(self->string_list); g_free(self->data); g_free(self); } @@ -380,6 +394,70 @@ int xrdp_bitmap_draw_focus_box(struct xrdp_bitmap* self, return 0; } +/*****************************************************************************/ +/* x and y are in relation to self for 0, 0 is the top left of the control */ +int xrdp_bitmap_draw_button(struct xrdp_bitmap* self, + struct xrdp_painter* painter, + int x, int y, int w, int h, + int down) +{ + if (down) + { + /* gray box */ + painter->fg_color = self->wm->grey; + xrdp_painter_fill_rect(painter, self, x, y, w, h); + /* black top line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, x, y, w, 1); + /* black left line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, x, y, 1, h); + /* dark grey top line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, x + 1, y + 1, w - 2, 1); + /* dark grey left line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, x + 1, y + 1, 1, h - 2); + /* dark grey bottom line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, x + 1, y + (h - 2), w - 1, 1); + /* dark grey right line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, x + (w - 2), y + 1, 1, h - 1); + /* black bottom line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, x, y + (h - 1), w, 1); + /* black right line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, x + (w - 1), y, 1, h); + } + else + { + /* gray box */ + painter->fg_color = self->wm->grey; + xrdp_painter_fill_rect(painter, self, x, y, w, h); + /* white top line */ + painter->fg_color = self->wm->white; + xrdp_painter_fill_rect(painter, self, x, y, w, 1); + /* white left line */ + painter->fg_color = self->wm->white; + xrdp_painter_fill_rect(painter, self, x, y, 1, h); + /* dark grey bottom line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, x + 1, y + (h - 2), w - 1, 1); + /* dark grey right line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, (x + w) - 2, y + 1, 1, h - 1); + /* black bottom line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, x, y + (h - 1), w, 1); + /* black right line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, x + (w - 1), y, 1, h); + } + return 0; +} + /*****************************************************************************/ /* nil for rect means the whole thing */ /* returns error */ @@ -388,6 +466,8 @@ int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect) int i; int w; int h; + int x; + int y; struct xrdp_bitmap* b; struct xrdp_rect r1; struct xrdp_rect r2; @@ -465,29 +545,8 @@ int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect) { if (self->state == BUTTON_STATE_UP) /* 0 */ { - /* gray box */ - painter->fg_color = self->wm->grey; - xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height); - /* white top line */ - painter->fg_color = self->wm->white; - xrdp_painter_fill_rect(painter, self, 0, 0, self->width, 1); - /* white left line */ - painter->fg_color = self->wm->white; - xrdp_painter_fill_rect(painter, self, 0, 0, 1, self->height); - /* dark grey bottom line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, 1, self->height - 2, - self->width - 1, 1); - /* dark grey right line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, self->width - 2, 1, - 1, self->height - 1); - /* black bottom line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, 0, self->height - 1, self->width, 1); - /* black right line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, self->width - 1, 0, 1, self->height); + xrdp_bitmap_draw_button(self, painter, 0, 0, + self->width, self->height, 0); w = xrdp_painter_text_width(painter, self->caption); h = xrdp_painter_text_height(painter, self->caption); painter->font->color = self->wm->black; @@ -501,35 +560,8 @@ int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect) } else if (self->state == BUTTON_STATE_DOWN) /* 1 */ { - /* gray box */ - painter->fg_color = self->wm->grey; - xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height); - /* black top line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, 0, 0, self->width, 1); - /* black left line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, 0, 0, 1, self->height); - /* dark grey top line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 2, 1); - /* dark grey left line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, 1, 1, 1, self->height - 2); - /* dark grey bottom line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, 1, self->height - 2, - self->width - 1, 1); - /* dark grey right line */ - painter->fg_color = self->wm->dark_grey; - xrdp_painter_fill_rect(painter, self, self->width - 2, 1, - 1, self->height - 1); - /* black bottom line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, 0, self->height - 1, self->width, 1); - /* black right line */ - painter->fg_color = self->wm->black; - xrdp_painter_fill_rect(painter, self, self->width - 1, 0, 1, self->height); + xrdp_bitmap_draw_button(self, painter, 0, 0, + self->width, self->height, 1); w = xrdp_painter_text_width(painter, self->caption); h = xrdp_painter_text_height(painter, self->caption); painter->font->color = self->wm->black; @@ -611,6 +643,56 @@ int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect) painter->font->color = self->wm->black; xrdp_painter_draw_text(painter, self, 0, 0, self->caption); } + else if (self->type == WND_TYPE_COMBO) /* 7 combo box */ + { + /* draw gray box */ + painter->fg_color = self->wm->grey; + xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height); + /* white background */ + painter->fg_color = self->wm->white; + xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 3, + self->height - 3); + if (self->parent->focused_control == self) + { + painter->fg_color = self->wm->dark_blue; + xrdp_painter_fill_rect(painter, self, 3, 3, (self->width - 6) - 18, + self->height - 5); + } + /* dark grey top line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, 0, 0, self->width, 1); + /* dark grey left line */ + painter->fg_color = self->wm->dark_grey; + xrdp_painter_fill_rect(painter, self, 0, 0, 1, self->height); + /* white bottom line */ + painter->fg_color = self->wm->white; + xrdp_painter_fill_rect(painter, self, 0, self->height- 1, self->width, 1); + /* white right line */ + painter->fg_color = self->wm->white; + xrdp_painter_fill_rect(painter, self, self->width - 1, 0, 1, self->height); + /* black left line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, 1, 1, 1, self->height - 2); + /* black top line */ + painter->fg_color = self->wm->black; + xrdp_painter_fill_rect(painter, self, 1, 1, self->width - 2, 1); + /* draw text */ + if (self->parent->focused_control == self) + painter->font->color = self->wm->white; + else + painter->font->color = self->wm->black; + xrdp_painter_draw_text(painter, self, 4, 2, + (char*)xrdp_list_get_item(self->string_list, self->item_index)); + /* draw button on right */ + x = self->width - 20; + y = 2; + w = (self->width - x) - 2; + h = self->height - 4; + if (self->state == BUTTON_STATE_UP) /* 0 */ + xrdp_bitmap_draw_button(self, painter, x, y, w, h, 0); + else + xrdp_bitmap_draw_button(self, painter, x, y, w, h, 1); + } /* notify */ if (self->notify != 0) self->notify(self, self, WM_PAINT, (int)painter, 0); /* 3 */ @@ -801,5 +883,33 @@ int xrdp_bitmap_def_proc(struct xrdp_bitmap* self, int msg, } } } + else if (self->type == WND_TYPE_COMBO) + { + if (msg == WM_KEYDOWN) + { + 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->item_index > 0) + { + self->item_index--; + 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->item_index + 1) < self->string_list->count) + { + self->item_index++; + xrdp_bitmap_invalidate(self, 0); + } + } + } + } return 0; } diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index 0428684a..9133236a 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -294,6 +294,7 @@ struct xrdp_wm int grey; int dark_grey; int blue; + int dark_blue; int white; int red; int green; @@ -315,6 +316,7 @@ struct xrdp_wm struct xrdp_bitmap* focused_window; /* cursor */ int current_cursor; + /* keyboard info */ int keys[256]; /* key states 0 up 1 down*/ int caps_lock; int scroll_lock; @@ -370,7 +372,7 @@ struct xrdp_painter struct xrdp_bitmap { /* 0 = bitmap 1 = window 2 = screen 3 = button 4 = image 5 = edit - 6 = label */ + 6 = label 7 = combo */ int type; int width; int height; @@ -400,8 +402,11 @@ struct xrdp_bitmap /* for edit */ int edit_pos; int password_char; - /* for button */ + /* for button or combo */ int state; /* for button 0 = normal 1 = down */ + /* for combo */ + struct xrdp_list* string_list; + int item_index; }; /* font */ diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index d4514c3b..48e6b589 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -422,6 +422,7 @@ int xrdp_wm_init(struct xrdp_wm* self) if (self->screen->bpp == 8) { /* rgb */ + self->palette[249] = 0x0000007f; self->palette[250] = 0x00ff0000; self->palette[251] = 0x0000ff00; self->palette[252] = 0x00c0c0c0; @@ -432,6 +433,7 @@ int xrdp_wm_init(struct xrdp_wm* self) self->grey = 252; self->dark_grey = 253; self->blue = 254; + self->dark_blue = 249; self->white = 255; self->red = 250; self->green = 251; @@ -444,6 +446,7 @@ int xrdp_wm_init(struct xrdp_wm* self) self->grey = COLOR15(0xc0, 0xc0, 0xc0); self->dark_grey = COLOR15(0x80, 0x80, 0x80); self->blue = COLOR15(0x00, 0x00, 0xff); + self->dark_blue = COLOR15(0x00, 0x00, 0x7f); self->white = COLOR15(0xff, 0xff, 0xff); self->red = COLOR15(0xff, 0x00, 0x00); self->green = COLOR15(0x00, 0xff, 0x00); @@ -454,6 +457,7 @@ int xrdp_wm_init(struct xrdp_wm* self) self->grey = COLOR16(0xc0, 0xc0, 0xc0); self->dark_grey = COLOR16(0x80, 0x80, 0x80); self->blue = COLOR16(0x00, 0x00, 0xff); + self->dark_blue = COLOR16(0x00, 0x00, 0x7f); self->white = COLOR16(0xff, 0xff, 0xff); self->red = COLOR16(0xff, 0x00, 0x00); self->green = COLOR16(0x00, 0xff, 0x00); @@ -464,6 +468,7 @@ int xrdp_wm_init(struct xrdp_wm* self) self->grey = COLOR24(0xc0, 0xc0, 0xc0); self->dark_grey = COLOR24(0x80, 0x80, 0x80); self->blue = COLOR24(0x00, 0x00, 0xff); + self->dark_blue = COLOR24(0x00, 0x00, 0x7f); self->white = COLOR24(0xff, 0xff, 0xff); self->red = COLOR24(0xff, 0x00, 0x00); self->green = COLOR24(0x00, 0xff, 0x00); @@ -549,6 +554,31 @@ int xrdp_wm_init(struct xrdp_wm* self) but->tab_stop = 1; but->password_char = '*'; + /* label */ + but = xrdp_bitmap_create(60, 20, self->screen->bpp, WND_TYPE_LABEL); + xrdp_list_add_item(self->login_window->child_list, (int)but); + but->parent = self->login_window; + but->owner = self->login_window; + but->wm = self; + but->left = 155; + but->top = 110; + g_strcpy(but->caption, "Module"); + + /* combo */ + but = xrdp_bitmap_create(140, 20, self->screen->bpp, WND_TYPE_COMBO); + xrdp_list_add_item(self->login_window->child_list, (int)but); + but->parent = self->login_window; + but->owner = self->login_window; + but->wm = self; + but->left = 220; + but->top = 110; + but->id = 6; + but->tab_stop = 1; + xrdp_list_add_item(but->string_list, (int)g_strdup("X11 Session")); + xrdp_list_add_item(but->string_list, (int)g_strdup("VNC")); + xrdp_list_add_item(but->string_list, (int)g_strdup("Desktop")); + xrdp_list_add_item(but->string_list, (int)g_strdup("Test")); + /* button */ but = xrdp_bitmap_create(60, 25, self->screen->bpp, WND_TYPE_BUTTON); xrdp_list_add_item(self->login_window->child_list, (int)but); @@ -927,8 +957,9 @@ int xrdp_wm_mouse_click(struct xrdp_wm* self, int x, int y, int but, int down) xrdp_bitmap_invalidate(control, 0); } } - if (control->type == WND_TYPE_BUTTON && but == 1 && - !down && self->button_down == control) + if ((control->type == WND_TYPE_BUTTON || + control->type == WND_TYPE_COMBO) && + but == 1 && !down && self->button_down == control) { /* if clicking up on a button that was clicked down */ self->button_down = 0; control->state = 0; @@ -938,8 +969,10 @@ int xrdp_wm_mouse_click(struct xrdp_wm* self, int x, int y, int but, int down) /* control can be invalid after this */ control->parent->notify(control->owner, control, 1, x, y); } - else if (control->type == WND_TYPE_BUTTON && but == 1 && down) - { /* if clicking down on a button */ + else if ((control->type == WND_TYPE_BUTTON || + control->type == WND_TYPE_COMBO) && + but == 1 && down) + { /* if clicking down on a button or combo */ self->button_down = control; control->state = 1; xrdp_bitmap_invalidate(control, 0);