summaryrefslogtreecommitdiffstats
path: root/sesman
diff options
context:
space:
mode:
authorJim Grandy <jgrandy@authentic8.com>2013-06-30 12:36:01 -0700
committerJim Grandy <jgrandy@authentic8.com>2013-08-22 12:49:40 -0700
commitdfe5911b5552fb9faaf94e998b019727a32ca21d (patch)
tree2afa7b431fda83ad7a5f665a5162245648c8db6d /sesman
parentb8388a65a2d561c23cc08613d1c4d7cf5dbb96d0 (diff)
downloadxrdp-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.c41
-rw-r--r--sesman/chansrv/chansrv.h1
-rw-r--r--sesman/chansrv/rail.c171
-rw-r--r--sesman/chansrv/rail.h1
-rw-r--r--sesman/chansrv/xcommon.c4
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;
}