summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xrdp/constants.h25
-rw-r--r--xrdp/funcs.c10
-rw-r--r--xrdp/xrdp.h6
-rw-r--r--xrdp/xrdp_bitmap.c114
-rw-r--r--xrdp/xrdp_types.h8
-rw-r--r--xrdp/xrdp_wm.c126
6 files changed, 253 insertions, 36 deletions
diff --git a/xrdp/constants.h b/xrdp/constants.h
index 981ce611..dd5ec02f 100644
--- a/xrdp/constants.h
+++ b/xrdp/constants.h
@@ -399,20 +399,23 @@
#define RDP_ORDER_BMPCACHE2 5
/* drawable types */
-#define WND_TYPE_BITMAP 0
-#define WND_TYPE_WND 1
-#define WND_TYPE_SCREEN 2
-#define WND_TYPE_BUTTON 3
-#define WND_TYPE_IMAGE 4
-#define WND_TYPE_EDIT 5
-#define WND_TYPE_LABEL 6
-#define WND_TYPE_COMBO 7
+#define WND_TYPE_BITMAP 0
+#define WND_TYPE_WND 1
+#define WND_TYPE_SCREEN 2
+#define WND_TYPE_BUTTON 3
+#define WND_TYPE_IMAGE 4
+#define WND_TYPE_EDIT 5
+#define WND_TYPE_LABEL 6
+#define WND_TYPE_COMBO 7
+#define WND_TYPE_SPECIAL 8
/* button states */
#define BUTTON_STATE_UP 0
#define BUTTON_STATE_DOWN 1
/* messages */
-#define WM_PAINT 3
-#define WM_KEYDOWN 15
-#define WM_KEYUP 16
+#define WM_PAINT 3
+#define WM_KEYDOWN 15
+#define WM_KEYUP 16
+#define WM_MOUSEMOVE 100
+#define WM_LBUTTONUP 101
diff --git a/xrdp/funcs.c b/xrdp/funcs.c
index 66229604..8d379fea 100644
--- a/xrdp/funcs.c
+++ b/xrdp/funcs.c
@@ -312,3 +312,13 @@ int remove_char_at(char* text, int index)
text[len - 1] = 0;
return 0;
}
+
+/*****************************************************************************/
+int set_string(char** in_str, char* in)
+{
+ if (in_str == 0)
+ return 0;
+ g_free(*in_str);
+ *in_str = g_strdup(in);
+ return 0;
+}
diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h
index 59b9f6b4..47cc710d 100644
--- a/xrdp/xrdp.h
+++ b/xrdp/xrdp.h
@@ -209,6 +209,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);
int xrdp_wm_key(struct xrdp_wm* self, int device_flags, int scan_code);
int xrdp_wm_key_sync(struct xrdp_wm* self, int device_flags, int key_flags);
+int xrdp_wm_pu(struct xrdp_wm* self, struct xrdp_bitmap* control);
/* xrdp_process.c */
struct xrdp_process* xrdp_process_create(struct xrdp_listen* owner);
@@ -246,6 +247,10 @@ int xrdp_bitmap_compare(struct xrdp_bitmap* self, struct xrdp_bitmap* b);
int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect);
int xrdp_bitmap_def_proc(struct xrdp_bitmap* self, int msg,
int param1, int param2);
+int xrdp_bitmap_to_screenx(struct xrdp_bitmap* self, int x);
+int xrdp_bitmap_to_screeny(struct xrdp_bitmap* self, int y);
+int xrdp_bitmap_from_screenx(struct xrdp_bitmap* self, int x);
+int xrdp_bitmap_from_screeny(struct xrdp_bitmap* self, int y);
/* xrdp_painter.c */
struct xrdp_painter* xrdp_painter_create(struct xrdp_wm* wn);
@@ -296,4 +301,5 @@ 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);
+int set_string(char** in_str, char* in);
diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c
index 90460385..b7e18599 100644
--- a/xrdp/xrdp_bitmap.c
+++ b/xrdp/xrdp_bitmap.c
@@ -77,6 +77,8 @@ void xrdp_bitmap_delete(struct xrdp_bitmap* self)
self->wm->dragging_window = 0;
if (self->wm->button_down == self)
self->wm->button_down = 0;
+ if (self->wm->popup_wnd == self)
+ self->wm->popup_wnd = 0;
}
if (self->child_list != 0)
{
@@ -473,6 +475,7 @@ int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect)
struct xrdp_rect r2;
struct xrdp_painter* painter;
char text[256];
+ char* p;
if (self == 0) /* if no bitmap */
return 0;
@@ -693,6 +696,32 @@ int xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect)
else
xrdp_bitmap_draw_button(self, painter, x, y, w, h, 1);
}
+ else if (self->type == WND_TYPE_SPECIAL) /* 8 special */
+ {
+ painter->fg_color = self->wm->white;
+ xrdp_painter_fill_rect(painter, self, 0, 0, self->width, self->height);
+ /* draw the list items */
+ if (self->popped_from != 0)
+ {
+ y = 0;
+ for (i = 0; i < self->popped_from->string_list->count; i++)
+ {
+ p = (char*)xrdp_list_get_item(self->popped_from->string_list, i);
+ h = xrdp_painter_text_height(painter, p);
+ self->item_height = h;
+ if (i == self->item_index)
+ {
+ painter->fg_color = self->wm->blue;
+ xrdp_painter_fill_rect(painter, self, 0, y, self->width, h);
+ painter->font->color = self->wm->white;
+ }
+ else
+ painter->font->color = self->wm->black;
+ xrdp_painter_draw_text(painter, self, 2, y, p);
+ y = y + h;
+ }
+ }
+ }
/* notify */
if (self->notify != 0)
self->notify(self, self, WM_PAINT, (int)painter, 0); /* 3 */
@@ -911,5 +940,90 @@ int xrdp_bitmap_def_proc(struct xrdp_bitmap* self, int msg,
}
}
}
+ else if (self->type == WND_TYPE_SPECIAL)
+ {
+ if (msg == WM_MOUSEMOVE)
+ {
+ if (self->item_height > 0 && self->popped_from != 0)
+ {
+ i = param2;
+ i = i / self->item_height;
+ if (i != self->item_index &&
+ i < self->popped_from->string_list->count)
+ {
+ self->item_index = i;
+ xrdp_bitmap_invalidate(self, 0);
+ }
+ }
+ }
+ else if (msg == WM_LBUTTONUP)
+ {
+ if (self->popped_from != 0)
+ {
+ self->popped_from->item_index = self->item_index;
+ xrdp_bitmap_invalidate(self->popped_from, 0);
+ }
+ }
+ }
return 0;
}
+
+/*****************************************************************************/
+/* convert the controls coords to screen coords */
+int xrdp_bitmap_to_screenx(struct xrdp_bitmap* self, int x)
+{
+ int i;
+
+ i = x;
+ while (self != 0)
+ {
+ i = i + self->left;
+ self = self->parent;
+ }
+ return i;
+}
+
+/*****************************************************************************/
+/* convert the controls coords to screen coords */
+int xrdp_bitmap_to_screeny(struct xrdp_bitmap* self, int y)
+{
+ int i;
+
+ i = y;
+ while (self != 0)
+ {
+ i = i + self->top;
+ self = self->parent;
+ }
+ return i;
+}
+
+/*****************************************************************************/
+/* convert the screen coords to controls coords */
+int xrdp_bitmap_from_screenx(struct xrdp_bitmap* self, int x)
+{
+ int i;
+
+ i = x;
+ while (self != 0)
+ {
+ i = i - self->left;
+ self = self->parent;
+ }
+ return i;
+}
+
+/*****************************************************************************/
+/* convert the screen coords to controls coords */
+int xrdp_bitmap_from_screeny(struct xrdp_bitmap* self, int y)
+{
+ int i;
+
+ i = y;
+ while (self != 0)
+ {
+ i = i - self->top;
+ self = self->parent;
+ }
+ return i;
+}
diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h
index 9133236a..d8763a2b 100644
--- a/xrdp/xrdp_types.h
+++ b/xrdp/xrdp_types.h
@@ -312,6 +312,8 @@ struct xrdp_wm
struct xrdp_bitmap* dragging_window;
/* the down(clicked) button */
struct xrdp_bitmap* button_down;
+ /* popup for combo box */
+ struct xrdp_bitmap* popup_wnd;
/* focused window */
struct xrdp_bitmap* focused_window;
/* cursor */
@@ -372,7 +374,7 @@ struct xrdp_painter
struct xrdp_bitmap
{
/* 0 = bitmap 1 = window 2 = screen 3 = button 4 = image 5 = edit
- 6 = label 7 = combo */
+ 6 = label 7 = combo 8 = special */
int type;
int width;
int height;
@@ -406,7 +408,11 @@ struct xrdp_bitmap
int state; /* for button 0 = normal 1 = down */
/* for combo */
struct xrdp_list* string_list;
+ /* for combo or popup */
int item_index;
+ /* for popup */
+ struct xrdp_bitmap* popped_from;
+ int item_height;
};
/* font */
diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c
index 48e6b589..904445dc 100644
--- a/xrdp/xrdp_wm.c
+++ b/xrdp/xrdp_wm.c
@@ -574,10 +574,10 @@ int xrdp_wm_init(struct xrdp_wm* self)
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"));
+ xrdp_list_add_item(but->string_list, (int)g_strdup("VNC"));
+ xrdp_list_add_item(but->string_list, (int)g_strdup("X11"));
+ xrdp_list_add_item(but->string_list, (int)g_strdup("Console"));
/* button */
but = xrdp_bitmap_create(60, 25, self->screen->bpp, WND_TYPE_BUTTON);
@@ -892,6 +892,9 @@ int xrdp_wm_mouse_move(struct xrdp_wm* self, int x, int y)
xrdp_set_cursor(self, b->cursor);
self->current_cursor = b->cursor;
}
+ xrdp_bitmap_def_proc(b, WM_MOUSEMOVE,
+ xrdp_bitmap_from_screenx(b, x),
+ xrdp_bitmap_from_screeny(b, y));
if (self->button_down == 0)
if (b->notify != 0)
b->notify(b->owner, b, 2, x, y);
@@ -902,6 +905,28 @@ int xrdp_wm_mouse_move(struct xrdp_wm* self, int x, int y)
}
/*****************************************************************************/
+int xrdp_wm_clear_popup(struct xrdp_wm* self)
+{
+ int i;
+ struct xrdp_rect rect;
+ //struct xrdp_bitmap* b;
+
+ //b = 0;
+ if (self->popup_wnd != 0)
+ {
+ //b = self->popup_wnd->popped_from;
+ i = xrdp_list_index_of(self->screen->child_list, (int)self->popup_wnd);
+ xrdp_list_remove_item(self->screen->child_list, i);
+ MAKERECT(rect, self->popup_wnd->left, self->popup_wnd->top,
+ self->popup_wnd->width, self->popup_wnd->height);
+ xrdp_bitmap_invalidate(self->screen, &rect);
+ xrdp_bitmap_delete(self->popup_wnd);
+ }
+ //xrdp_wm_set_focused(self, b->parent);
+ return 0;
+}
+
+/*****************************************************************************/
int xrdp_wm_mouse_click(struct xrdp_wm* self, int x, int y, int but, int down)
{
struct xrdp_bitmap* control;
@@ -941,6 +966,22 @@ int xrdp_wm_mouse_click(struct xrdp_wm* self, int x, int y, int but, int down)
}
wnd = 0;
control = xrdp_wm_at_pos(self->screen, x, y, &wnd);
+ if (self->popup_wnd != 0)
+ {
+ if (self->popup_wnd == control && !down)
+ {
+ xrdp_bitmap_def_proc(self->popup_wnd, WM_LBUTTONUP, x, y);
+ xrdp_wm_clear_popup(self);
+ self->button_down = 0;
+ return 0;
+ }
+ else if (self->popup_wnd != control && down)
+ {
+ xrdp_wm_clear_popup(self);
+ self->button_down = 0;
+ return 0;
+ }
+ }
if (control != 0)
{
if (wnd != 0)
@@ -976,31 +1017,36 @@ int xrdp_wm_mouse_click(struct xrdp_wm* self, int x, int y, int but, int down)
self->button_down = control;
control->state = 1;
xrdp_bitmap_invalidate(control, 0);
+ if (control->type == WND_TYPE_COMBO)
+ xrdp_wm_pu(self, control);
}
else if (but == 1 && down)
{
- xrdp_wm_set_focused(self, wnd);
- if (control->type == WND_TYPE_WND && y < (control->top + 21))
- { /* if dragging */
- if (self->dragging) /* rarely happens */
- {
- newx = self->draggingx - self->draggingdx;
- newy = self->draggingy - self->draggingdy;
- if (self->draggingxorstate)
- xrdp_wm_xor_pat(self, newx, newy,
- self->draggingcx, self->draggingcy);
- self->draggingxorstate = 0;
+ if (self->popup_wnd == 0)
+ {
+ xrdp_wm_set_focused(self, wnd);
+ if (control->type == WND_TYPE_WND && y < (control->top + 21))
+ { /* if dragging */
+ if (self->dragging) /* rarely happens */
+ {
+ newx = self->draggingx - self->draggingdx;
+ newy = self->draggingy - self->draggingdy;
+ if (self->draggingxorstate)
+ xrdp_wm_xor_pat(self, newx, newy,
+ self->draggingcx, self->draggingcy);
+ self->draggingxorstate = 0;
+ }
+ self->dragging = 1;
+ self->dragging_window = control;
+ self->draggingorgx = control->left;
+ self->draggingorgy = control->top;
+ self->draggingx = x;
+ self->draggingy = y;
+ self->draggingdx = x - control->left;
+ self->draggingdy = y - control->top;
+ self->draggingcx = control->width;
+ self->draggingcy = control->height;
}
- self->dragging = 1;
- self->dragging_window = control;
- self->draggingorgx = control->left;
- self->draggingorgy = control->top;
- self->draggingx = x;
- self->draggingy = y;
- self->draggingdx = x - control->left;
- self->draggingdy = y - control->top;
- self->draggingcx = control->width;
- self->draggingcy = control->height;
}
}
}
@@ -1018,6 +1064,11 @@ int xrdp_wm_key(struct xrdp_wm* self, int device_flags, int scan_code)
{
int msg;
+ if (self->popup_wnd != 0)
+ {
+ xrdp_wm_clear_popup(self);
+ return 0;
+ }
if (device_flags & 0x8000) /* key up */
{
self->keys[scan_code % 128] = 0;
@@ -1057,3 +1108,30 @@ int xrdp_wm_key_sync(struct xrdp_wm* self, int device_flags, int key_flags)
self->caps_lock = 1;
return 0;
}
+
+/*****************************************************************************/
+int xrdp_wm_pu(struct xrdp_wm* self, struct xrdp_bitmap* control)
+{
+ int x;
+ int y;
+
+ if (self == 0)
+ return 0;
+ if (control == 0)
+ return 0;
+ self->popup_wnd = xrdp_bitmap_create(control->width, 100,
+ self->screen->bpp,
+ WND_TYPE_SPECIAL);
+ self->popup_wnd->popped_from = control;
+ self->popup_wnd->parent = self->screen;
+ self->popup_wnd->owner = self->screen;
+ self->popup_wnd->wm = self;
+ x = xrdp_bitmap_to_screenx(control, 0);
+ y = xrdp_bitmap_to_screeny(control, 0);
+ self->popup_wnd->left = x;
+ self->popup_wnd->top = y + control->height;
+ self->popup_wnd->item_index = control->item_index;
+ xrdp_list_insert_item(self->screen->child_list, 0, (int)self->popup_wnd);
+ xrdp_bitmap_invalidate(self->popup_wnd, 0);
+ return 0;
+}