diff options
author | Jim Grandy <jgrandy@authentic8.com> | 2013-06-30 12:36:01 -0700 |
---|---|---|
committer | Jim Grandy <jgrandy@authentic8.com> | 2013-08-22 12:49:40 -0700 |
commit | dfe5911b5552fb9faaf94e998b019727a32ca21d (patch) | |
tree | 2afa7b431fda83ad7a5f665a5162245648c8db6d /sesman | |
parent | b8388a65a2d561c23cc08613d1c4d7cf5dbb96d0 (diff) | |
download | xrdp-proprietary-dfe5911b5552fb9faaf94e998b019727a32ca21d.tar.gz xrdp-proprietary-dfe5911b5552fb9faaf94e998b019727a32ca21d.zip |
Hand-apply patches (rail improvements) from Authentic8 branch: 507694d, 0e21d45, 44447d5, e452e4f, 3d05576, dd69d8f
Diffstat (limited to 'sesman')
-rw-r--r-- | sesman/chansrv/chansrv.c | 41 | ||||
-rw-r--r-- | sesman/chansrv/chansrv.h | 1 | ||||
-rw-r--r-- | sesman/chansrv/rail.c | 171 | ||||
-rw-r--r-- | sesman/chansrv/rail.h | 1 | ||||
-rw-r--r-- | sesman/chansrv/xcommon.c | 4 |
5 files changed, 204 insertions, 14 deletions
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index 388d0273..db26958a 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -230,6 +230,31 @@ send_channel_data(int chan_id, char *data, int size) /*****************************************************************************/ /* returns error */ +int APP_CC +send_rail_drawing_orders(char* data, int size) +{ + LOGM((LOG_LEVEL_DEBUG, "chansrv::send_rail_drawing_orders: size %d", size)); + + struct stream* s; + int error; + + s = trans_get_out_s(g_con_trans, 8192); + out_uint32_le(s, 0); /* version */ + out_uint32_le(s, 8 + 8 + size); /* size */ + out_uint32_le(s, 10); /* msg id */ + out_uint32_le(s, 8 + size); /* size */ + out_uint8a(s, data, size); + s_mark_end(s); + error = trans_force_write(g_con_trans); + if (error != 0) + { + return 1; + } + return 0; +} + +/*****************************************************************************/ +/* returns error */ static int APP_CC send_init_response_message(void) { @@ -504,6 +529,19 @@ process_message_channel_data(struct stream *s) /*****************************************************************************/ /* returns error */ static int APP_CC +process_message_channel_rail_title_request(struct stream* s) +{ + int window_id; + LOG(10, ("process_message_channel_rail_title_request:")); + + in_uint32_le(s, window_id); + rail_request_title(window_id); + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC process_message_channel_data_response(struct stream *s) { LOG(10, ("process_message_channel_data_response:")); @@ -558,6 +596,9 @@ process_message(void) case 7: /* channel data response */ rv = process_message_channel_data_response(s); break; + case 9: + rv = process_message_channel_rail_title_request(s); + break; default: LOGM((LOG_LEVEL_ERROR, "process_message: error in process_message ", "unknown msg %d", id)); diff --git a/sesman/chansrv/chansrv.h b/sesman/chansrv/chansrv.h index bca30ca4..1754bbb0 100644 --- a/sesman/chansrv/chansrv.h +++ b/sesman/chansrv/chansrv.h @@ -55,6 +55,7 @@ struct xrdp_api_data }; int APP_CC send_channel_data(int chan_id, char *data, int size); +int APP_CC send_rail_drawing_orders(char* data, int size); int APP_CC main_cleanup(void); int APP_CC find_empty_slot_in_dvc_channels(); struct xrdp_api_data * APP_CC struct_from_dvc_chan_id(tui32 dvc_chan_id); diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c index cfa3c5de..a84c68b6 100644 --- a/sesman/chansrv/rail.c +++ b/sesman/chansrv/rail.c @@ -41,6 +41,8 @@ extern Screen *g_screen; /* in xcommon.c */ extern Window g_root_window; /* in xcommon.c */ extern Atom g_wm_delete_window_atom; /* in xcommon.c */ extern Atom g_wm_protocols_atom; /* in xcommon.c */ +extern Atom g_utf8_string; /* in xcommon.c */ +extern Atom g_net_wm_name; /* in xcommon.c */ int g_rail_up = 0; @@ -270,6 +272,25 @@ rail_process_exec(struct stream *s, int size) return 0; } +/******************************************************************************/ +static int APP_CC +rail_close_window(int window_id) +{ + XEvent ce; + + LOG(0, ("chansrv::rail_close_window:")); + g_memset(&ce, 0, sizeof(ce)); + ce.xclient.type = ClientMessage; + ce.xclient.message_type = g_wm_protocols_atom; + ce.xclient.display = g_display; + ce.xclient.window = window_id; + ce.xclient.format = 32; + ce.xclient.data.l[0] = g_wm_delete_window_atom; + ce.xclient.data.l[1] = CurrentTime; + XSendEvent(g_display, window_id, False, NoEventMask, &ce); + return 0; +} + /*****************************************************************************/ static int APP_CC rail_process_activate(struct stream *s, int size) @@ -288,8 +309,15 @@ rail_process_activate(struct stream *s, int size) XRaiseWindow(g_display, window_id); LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id)); XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime); - } + } else { + XWindowAttributes window_attributes; + XGetWindowAttributes(g_display, window_id, &window_attributes); + if (window_attributes.override_redirect) { + LOG(10, (" dismiss popup window 0x%8.8x", window_id)); + rail_close_window(window_id); + } + } return 0; } @@ -307,21 +335,25 @@ rail_process_system_param(struct stream *s, int size) /******************************************************************************/ static int APP_CC -rail_close_window(int window_id) +rail_minmax_window(int window_id, int max) { - XEvent ce; + LOG(10, ("chansrv::rail_minmax_window 0x%8.8x:", window_id)); + if (max) + { + + } else { + XUnmapWindow(g_display, window_id); + LOG(10, (" XUnmapWindow")); + } +} - LOG(0, ("chansrv::rail_close_window:")); - g_memset(&ce, 0, sizeof(ce)); - ce.xclient.type = ClientMessage; - ce.xclient.message_type = g_wm_protocols_atom; - ce.xclient.display = g_display; - ce.xclient.window = window_id; - ce.xclient.format = 32; - ce.xclient.data.l[0] = g_wm_delete_window_atom; - ce.xclient.data.l[1] = CurrentTime; - XSendEvent(g_display, window_id, False, NoEventMask, &ce); - return 0; +/*****************************************************************************/ +static int APP_CC +rail_restore_window(int window_id) +{ + LOG(10, ("chansrv::rail_restore_window 0x%8.8x:", window_id)); + LOG(10, (" XMapWindow")); + XMapWindow(g_display, window_id); } /*****************************************************************************/ @@ -345,6 +377,7 @@ rail_process_system_command(struct stream *s, int size) break; case SC_MINIMIZE: LOG(10, (" window_id 0x%8.8x SC_MINIMIZE", window_id)); + rail_minmax_window(window_id, 0); break; case SC_MAXIMIZE: LOG(10, (" window_id 0x%8.8x SC_MAXIMIZE", window_id)); @@ -358,6 +391,7 @@ rail_process_system_command(struct stream *s, int size) break; case SC_RESTORE: LOG(10, (" window_id 0x%8.8x SC_RESTORE", window_id)); + rail_restore_window(window_id); break; case SC_DEFAULT: LOG(10, (" window_id 0x%8.8x SC_DEFAULT", window_id)); @@ -589,6 +623,89 @@ rail_data_in(struct stream *s, int chan_id, int chan_flags, int length, } /*****************************************************************************/ +int APP_CC +rail_get_property(Display *display, Window target, Atom type, Atom property, + unsigned char** data, unsigned long* count) { + Atom atom_return; + int size; + unsigned long nitems, bytes_left; + + int ret = XGetWindowProperty(display, target, property, + 0l, 1l, False, + type, &atom_return, &size, + &nitems, &bytes_left, data); + if (ret != Success || nitems < 1) + { + return 0; + } + + if (bytes_left != 0) + { + XFree(*data); + unsigned long remain = ((size / 8) * nitems) + bytes_left; + ret = XGetWindowProperty(g_display, target, + property, 0l, remain, False, + type, &atom_return, &size, + &nitems, &bytes_left, data); + if (ret != Success) + { + return 1; + } + } + + *count = nitems; + return 0; +} + +/*****************************************************************************/ +const int APP_CC +rail_send_win_text(Display *disp, Window win) { + unsigned char *data = 0; + unsigned long nitems = 0; + struct stream* s; + + rail_get_property(disp, win, g_utf8_string, g_net_wm_name, + &data, &nitems); + if (nitems == 0) + { + /* _NET_WM_NAME isn't set, use WM_NAME (XFetchName) instead */ + XFetchName(disp, win, (char **)&data); + } + + if (data) + { + int i = 0; + for (;;i++) + { + if (data[i] == '\0') + { + break; + } + } + LOG(10, ("rail_send_win_text: 0x%8.8x text 0x%x size %d", win, data, i)); + make_stream(s); + init_stream(s, 1024); + + out_uint32_le(s, 2); /* update title info */ + out_uint32_le(s, win); /* window id */ + out_uint32_le(s, i); /* title size */ + out_uint8a(s, data, i); /* title */ + s_mark_end(s); + send_rail_drawing_orders(s->data, (int)(s->end - s->data)); + free_stream(s); + XFree(data); + } + return 0; +} + +/*****************************************************************************/ +int APP_CC +rail_request_title(int window_id) +{ + return rail_send_win_text(g_display, (Window)window_id); +} + +/*****************************************************************************/ /* returns 0, event handled, 1 unhandled */ int APP_CC rail_xevent(void *xevent) @@ -596,6 +713,14 @@ rail_xevent(void *xevent) XEvent *lxevent; XWindowChanges xwc; int rv; + int nchildren_return = 0; + Window root_return; + Window parent_return; + Window *children_return; + Window wreturn; + int revert_to; + XWindowAttributes wnd_attributes; + char* prop_name; LOG(10, ("chansrv::rail_xevent:")); @@ -609,6 +734,17 @@ rail_xevent(void *xevent) switch (lxevent->type) { + case PropertyNotify: + prop_name = XGetAtomName(g_display, lxevent->xproperty.atom); + LOG(10, (" got PropertyNotify window_id 0x%8.8x %s", + lxevent->xproperty.window, prop_name)); + if (strcmp(prop_name, "WM_NAME") == 0 || + strcmp(prop_name, "_NEW_WM_NAME") == 0) + { + rail_send_win_text(g_display, lxevent->xproperty.window); + rv = 0; + } + break; case ConfigureRequest: LOG(10, (" got ConfigureRequest window_id 0x%8.8x", lxevent->xconfigurerequest.window)); g_memset(&xwc, 0, sizeof(xwc)); @@ -626,6 +762,13 @@ rail_xevent(void *xevent) rv = 0; break; + case CreateNotify: + LOG(10, (" got CreateNotify")); + XSelectInput(g_display, lxevent->xcreatewindow.window, + PropertyChangeMask | StructureNotifyMask); + v = 0; + break; + case MapRequest: LOG(10, (" got MapRequest")); XMapWindow(g_display, lxevent->xmaprequest.window); diff --git a/sesman/chansrv/rail.h b/sesman/chansrv/rail.h index 7dbcbc5a..50bbfd36 100644 --- a/sesman/chansrv/rail.h +++ b/sesman/chansrv/rail.h @@ -31,5 +31,6 @@ rail_data_in(struct stream* s, int chan_id, int chan_flags, int length, int total_length); int APP_CC rail_xevent(void* xevent); +int APP_CC rail_request_title(int window_id); #endif diff --git a/sesman/chansrv/xcommon.c b/sesman/chansrv/xcommon.c index c5a91cae..8fd8e741 100644 --- a/sesman/chansrv/xcommon.c +++ b/sesman/chansrv/xcommon.c @@ -40,6 +40,8 @@ int g_screen_num = 0; Window g_root_window = 0; Atom g_wm_delete_window_atom = 0; Atom g_wm_protocols_atom = 0; +Atom g_utf8_string = 0; +Atom g_net_wm_name = 0; /*****************************************************************************/ static int DEFAULT_CC @@ -117,6 +119,8 @@ xcommon_init(void) g_wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", 0); g_wm_protocols_atom = XInternAtom(g_display, "WM_PROTOCOLS", 0); + g_utf8_string = XInternAtom(g_display, "UTF8_STRIING", 0); + g_net_wm_name = XInternAtom(g_display, "_NET_WM_NAME", 0); return 0; } |