Hand-apply patches (rail) from Authentic8: b01207f b9807e9 42f0128 0f0750c aef2dce
This commit is contained in:
parent
9775bfd611
commit
3401febd26
@ -19,9 +19,15 @@
|
||||
/*
|
||||
window manager info
|
||||
http://www.freedesktop.org/wiki/Specifications/wm-spec
|
||||
|
||||
rail
|
||||
[MS-RDPERP]: Remote Desktop Protocol:
|
||||
Remote Programs Virtual Channel Extension
|
||||
http://msdn.microsoft.com/en-us/library/cc242568(v=prot.20).aspx
|
||||
*/
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include "chansrv.h"
|
||||
#include "rail.h"
|
||||
#include "xcommon.h"
|
||||
@ -46,6 +52,8 @@ extern Atom g_utf8_string; /* in xcommon.c */
|
||||
extern Atom g_net_wm_name; /* in xcommon.c */
|
||||
extern Atom g_wm_state; /* in xcommon.c */
|
||||
|
||||
static Atom g_rwd_atom = 0;
|
||||
|
||||
int g_rail_up = 0;
|
||||
|
||||
/* for rail_is_another_wm_running */
|
||||
@ -53,6 +61,23 @@ static int g_rail_running = 1;
|
||||
/* list of valid rail windows */
|
||||
static struct list* g_window_list = 0;
|
||||
|
||||
/* used in valid field of struct rail_window_data */
|
||||
#define RWD_X (1 << 0)
|
||||
#define RWD_Y (1 << 1)
|
||||
#define RWD_WIDTH (1 << 2)
|
||||
#define RWD_HEIGHT (1 << 3)
|
||||
#define RWD_TITLE (1 << 4)
|
||||
|
||||
struct rail_window_data
|
||||
{
|
||||
int valid; /* bits for which fields are valid */
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
char title[64]; /* first 64 bytes of title for compare */
|
||||
};
|
||||
|
||||
/* Indicates a Client Execute PDU from client to server. */
|
||||
#define TS_RAIL_ORDER_EXEC 0x0001
|
||||
/* Indicates a Client Activate PDU from client to server. */
|
||||
@ -125,6 +150,70 @@ static int APP_CC rail_win_set_state(Window win, unsigned long state);
|
||||
static int APP_CC rail_show_window(Window window_id, int show_state);
|
||||
static int APP_CC rail_win_send_text(Window win);
|
||||
|
||||
/*****************************************************************************/
|
||||
static struct rail_window_data* APP_CC
|
||||
rail_get_window_data(Window window)
|
||||
{
|
||||
int bytes;
|
||||
Atom actual_type_return;
|
||||
int actual_format_return;
|
||||
unsigned long nitems_return;
|
||||
unsigned long bytes_after_return;
|
||||
unsigned char* prop_return;
|
||||
struct rail_window_data* rv;
|
||||
|
||||
LOG(10, ("chansrv::rail_get_window_data:"));
|
||||
rv = 0;
|
||||
actual_type_return = 0;
|
||||
actual_format_return = 0;
|
||||
nitems_return = 0;
|
||||
prop_return = 0;
|
||||
bytes = sizeof(struct rail_window_data);
|
||||
XGetWindowProperty(g_display, window, g_rwd_atom, 0, bytes, 0,
|
||||
XA_STRING, &actual_type_return,
|
||||
&actual_format_return, &nitems_return,
|
||||
&bytes_after_return, &prop_return);
|
||||
if (prop_return == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (nitems_return == bytes)
|
||||
{
|
||||
rv = (struct rail_window_data*)prop_return;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int APP_CC
|
||||
rail_set_window_data(Window window, struct rail_window_data* rwd)
|
||||
{
|
||||
int bytes;
|
||||
|
||||
bytes = sizeof(struct rail_window_data);
|
||||
XChangeProperty(g_display, window, g_rwd_atom, XA_STRING, 8,
|
||||
PropModeReplace, (unsigned char*)rwd, bytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* get the rail window data, if not exist, try to create it and return */
|
||||
static struct rail_window_data* APP_CC
|
||||
rail_get_window_data_safe(Window window)
|
||||
{
|
||||
struct rail_window_data* rv;
|
||||
|
||||
rv = rail_get_window_data(window);
|
||||
if (rv != 0)
|
||||
{
|
||||
return rv;
|
||||
}
|
||||
rv = g_malloc(sizeof(struct rail_window_data), 1);
|
||||
rail_set_window_data(window, rv);
|
||||
g_free(rv);
|
||||
return rail_get_window_data(window);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int APP_CC
|
||||
is_window_valid_child_of_root(unsigned int window_id)
|
||||
@ -226,6 +315,7 @@ rail_init(void)
|
||||
g_window_list = list_create();
|
||||
rail_send_init();
|
||||
g_rail_up = 1;
|
||||
g_rwd_atom = XInternAtom(g_display, "XRDP_RAIL_WINDOW_DATA", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -363,7 +453,7 @@ rail_simulate_mouse_click(int button)
|
||||
|
||||
XFlush(g_display);
|
||||
|
||||
usleep(100000);
|
||||
g_sleep(100);
|
||||
|
||||
event.type = ButtonRelease;
|
||||
event.xbutton.state = 0x100;
|
||||
@ -777,16 +867,30 @@ rail_process_window_move(struct stream *s, int size)
|
||||
int top;
|
||||
int right;
|
||||
int bottom;
|
||||
tsi16 si16;
|
||||
struct rail_window_data* rwd;
|
||||
|
||||
LOG(10, ("chansrv::rail_process_window_move:"));
|
||||
in_uint32_le(s, window_id);
|
||||
in_uint16_le(s, left);
|
||||
in_uint16_le(s, top);
|
||||
in_uint16_le(s, right);
|
||||
in_uint16_le(s, bottom);
|
||||
in_uint16_le(s, si16);
|
||||
left = si16;
|
||||
in_uint16_le(s, si16);
|
||||
top = si16;
|
||||
in_uint16_le(s, si16);
|
||||
right = si16;
|
||||
in_uint16_le(s, si16);
|
||||
bottom = si16;
|
||||
LOG(10, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d",
|
||||
window_id, left, top, right, bottom, right - left, bottom - top));
|
||||
XMoveResizeWindow(g_display, window_id, left, top, right - left, bottom - top);
|
||||
rwd = (struct rail_window_data*)
|
||||
g_malloc(sizeof(struct rail_window_data), 1);
|
||||
rwd->x = left;
|
||||
rwd->y = top;
|
||||
rwd->width = right - left;
|
||||
rwd->height = bottom - top;
|
||||
rail_set_window_data(window_id, rwd);
|
||||
g_free(rwd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -799,13 +903,16 @@ rail_process_local_move_size(struct stream *s, int size)
|
||||
int move_size_type;
|
||||
int pos_x;
|
||||
int pos_y;
|
||||
tsi16 si16;
|
||||
|
||||
LOG(10, ("chansrv::rail_process_local_move_size:"));
|
||||
in_uint32_le(s, window_id);
|
||||
in_uint16_le(s, is_move_size_start);
|
||||
in_uint16_le(s, move_size_type);
|
||||
in_uint16_le(s, pos_x);
|
||||
in_uint16_le(s, pos_y);
|
||||
in_uint16_le(s, si16);
|
||||
pos_x = si16;
|
||||
in_uint16_le(s, si16);
|
||||
pos_y = si16;
|
||||
LOG(10, (" window_id 0x%8.8x is_move_size_start %d move_size_type %d "
|
||||
"pos_x %d pos_y %d", window_id, is_move_size_start, move_size_type,
|
||||
pos_x, pos_y));
|
||||
@ -840,11 +947,14 @@ rail_process_sys_menu(struct stream *s, int size)
|
||||
int window_id;
|
||||
int left;
|
||||
int top;
|
||||
tsi16 si16;
|
||||
|
||||
LOG(10, ("chansrv::rail_process_sys_menu:"));
|
||||
in_uint32_le(s, window_id);
|
||||
in_uint16_le(s, left);
|
||||
in_uint16_le(s, top);
|
||||
in_uint16_le(s, si16);
|
||||
left = si16;
|
||||
in_uint16_le(s, si16);
|
||||
top = si16;
|
||||
LOG(10, (" window_id 0x%8.8x left %d top %d", window_id, left, top));
|
||||
return 0;
|
||||
}
|
||||
@ -959,14 +1069,37 @@ rail_data_in(struct stream *s, int chan_id, int chan_flags, int length,
|
||||
/*****************************************************************************/
|
||||
/* returns 0, event handled, 1 unhandled */
|
||||
static int APP_CC
|
||||
rail_win_send_text(Window win) {
|
||||
rail_win_send_text(Window win)
|
||||
{
|
||||
char* data = 0;
|
||||
struct stream* s;
|
||||
int len = 0;
|
||||
int flags;
|
||||
struct rail_window_data* rwd;
|
||||
|
||||
len = rail_win_get_text(win, &data);
|
||||
|
||||
rwd = rail_get_window_data_safe(win);
|
||||
if (rwd != 0)
|
||||
{
|
||||
if (data != 0)
|
||||
{
|
||||
if (rwd->valid & RWD_TITLE)
|
||||
{
|
||||
if (g_strncmp(rwd->title, data, 63) == 0)
|
||||
{
|
||||
LOG(0, ("chansrv::rail_win_send_text: skipping, title not changed"));
|
||||
XFree(data);
|
||||
XFree(rwd);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(0, ("chansrv::rail_win_send_text: error rail_get_window_data_safe failed"));
|
||||
return 1;
|
||||
}
|
||||
if (data && len > 0) {
|
||||
LOG(10, ("chansrv::rail_win_send_text: 0x%8.8x text %s length %d",
|
||||
win, data, len));
|
||||
@ -982,7 +1115,12 @@ rail_win_send_text(Window win) {
|
||||
send_rail_drawing_orders(s->data, (int)(s->end - s->data));
|
||||
free_stream(s);
|
||||
XFree(data);
|
||||
/* update rail window data */
|
||||
rwd->valid |= RWD_TITLE;
|
||||
g_strncpy(rwd->title, data, 63);
|
||||
rail_set_window_data(win, rwd);
|
||||
}
|
||||
XFree(rwd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1048,10 +1186,17 @@ rail_create_window(Window window_id, Window parent_id)
|
||||
int flags;
|
||||
int index;
|
||||
Window transient_for = 0;
|
||||
struct rail_window_data* rwd;
|
||||
struct stream* s;
|
||||
|
||||
LOG(10, ("chansrv::rail_create_window 0x%8.8x", window_id));
|
||||
|
||||
rwd = rail_get_window_data_safe(window_id);
|
||||
if (rwd == 0)
|
||||
{
|
||||
LOG(0, ("chansrv::rail_create_window: error rail_get_window_data_safe failed"));
|
||||
return 0;
|
||||
}
|
||||
XGetGeometry(g_display, window_id, &root, &x, &y, &width, &height,
|
||||
&border, &depth);
|
||||
XGetWindowAttributes(g_display, window_id, &attributes);
|
||||
@ -1109,11 +1254,15 @@ rail_create_window(Window window_id, Window parent_id)
|
||||
{
|
||||
out_uint16_le(s, title_size); /* title_size */
|
||||
out_uint8a(s, title_bytes, title_size); /* title */
|
||||
rwd->valid |= RWD_TITLE;
|
||||
g_strncpy(rwd->title, title_bytes, 63);
|
||||
}
|
||||
else
|
||||
{
|
||||
out_uint16_le(s, 5); /* title_size */
|
||||
out_uint8a(s, "title", 5); /* title */
|
||||
rwd->valid |= RWD_TITLE;
|
||||
rwd->title[0] = 0;
|
||||
}
|
||||
LOG(10, (" set title info %d", title_size));
|
||||
flags |= WINDOW_ORDER_FIELD_TITLE;
|
||||
@ -1162,6 +1311,201 @@ rail_create_window(Window window_id, Window parent_id)
|
||||
send_rail_drawing_orders(s->data, (int)(s->end - s->data));
|
||||
free_stream(s);
|
||||
XFree(title_bytes);
|
||||
rail_set_window_data(window_id, rwd);
|
||||
XFree(rwd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns 0, event handled, 1 unhandled */
|
||||
int APP_CC
|
||||
rail_configure_request_window(XConfigureRequestEvent* config)
|
||||
{
|
||||
int num_window_rects = 1;
|
||||
int num_visibility_rects = 1;
|
||||
int i = 0;
|
||||
int flags;
|
||||
int index;
|
||||
int window_id;
|
||||
int mask;
|
||||
int resized = 0;
|
||||
struct rail_window_data* rwd;
|
||||
|
||||
struct stream* s;
|
||||
|
||||
window_id = config->window;
|
||||
mask = config->value_mask;
|
||||
LOG(10, ("chansrv::rail_configure_request_window: mask %d", mask));
|
||||
rwd = rail_get_window_data(window_id);
|
||||
if (rwd == 0)
|
||||
{
|
||||
rwd = (struct rail_window_data*)g_malloc(sizeof(struct rail_window_data), 1);
|
||||
rwd->x = config->x;
|
||||
rwd->y = config->y;
|
||||
rwd->width = config->width;
|
||||
rwd->height = config->height;
|
||||
rwd->valid |= RWD_X | RWD_Y | RWD_WIDTH | RWD_HEIGHT;
|
||||
rail_set_window_data(window_id, rwd);
|
||||
g_free(rwd);
|
||||
return 0;
|
||||
}
|
||||
if (!resized)
|
||||
{
|
||||
if (mask & CWX)
|
||||
{
|
||||
if (rwd->valid & RWD_X)
|
||||
{
|
||||
if (rwd->x != config->x)
|
||||
{
|
||||
resized = 1;
|
||||
rwd->x = config->x;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resized = 1;
|
||||
rwd->x = config->x;
|
||||
rwd->valid |= RWD_X;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!resized)
|
||||
{
|
||||
if (mask & CWY)
|
||||
{
|
||||
if (rwd->valid & RWD_Y)
|
||||
{
|
||||
if (rwd->y != config->y)
|
||||
{
|
||||
resized = 1;
|
||||
rwd->y = config->y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resized = 1;
|
||||
rwd->y = config->y;
|
||||
rwd->valid |= RWD_Y;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!resized)
|
||||
{
|
||||
if (mask & CWWidth)
|
||||
{
|
||||
if (rwd->valid & RWD_WIDTH)
|
||||
{
|
||||
if (rwd->width != config->width)
|
||||
{
|
||||
resized = 1;
|
||||
rwd->width = config->width;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resized = 1;
|
||||
rwd->width = config->width;
|
||||
rwd->valid |= RWD_WIDTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!resized)
|
||||
{
|
||||
if (mask & CWHeight)
|
||||
{
|
||||
if (rwd->valid & RWD_HEIGHT)
|
||||
{
|
||||
if (rwd->height != config->height)
|
||||
{
|
||||
resized = 1;
|
||||
rwd->height = config->height;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resized = 1;
|
||||
rwd->height = config->height;
|
||||
rwd->valid |= RWD_HEIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (resized)
|
||||
{
|
||||
rail_set_window_data(window_id, rwd);
|
||||
XFree(rwd);
|
||||
}
|
||||
else
|
||||
{
|
||||
XFree(rwd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG(10, ("chansrv::rail_configure_request_window: 0x%8.8x", window_id));
|
||||
|
||||
|
||||
LOG(10, (" x %d y %d width %d height %d border_width %d", config->x,
|
||||
config->y, config->width, config->height, config->border_width));
|
||||
|
||||
index = list_index_of(g_window_list, window_id);
|
||||
if (index == -1)
|
||||
{
|
||||
/* window isn't mapped yet */
|
||||
LOG(0, ("chansrv::rail_configure_request_window: window not mapped"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
flags = WINDOW_ORDER_TYPE_WINDOW;
|
||||
|
||||
make_stream(s);
|
||||
init_stream(s, 1024);
|
||||
|
||||
out_uint32_le(s, 10); /* configure_window */
|
||||
out_uint32_le(s, window_id); /* window_id */
|
||||
|
||||
out_uint32_le(s, 0); /* client_offset_x */
|
||||
out_uint32_le(s, 0); /* client_offset_y */
|
||||
flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET;
|
||||
out_uint32_le(s, config->width); /* client_area_width */
|
||||
out_uint32_le(s, config->height); /* client_area_height */
|
||||
flags |= WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE;
|
||||
out_uint32_le(s, 0); /* rp_content */
|
||||
out_uint32_le(s, g_root_window); /* root_parent_handle */
|
||||
flags |= WINDOW_ORDER_FIELD_ROOT_PARENT;
|
||||
out_uint32_le(s, config->x); /* window_offset_x */
|
||||
out_uint32_le(s, config->y); /* window_offset_y */
|
||||
flags |= WINDOW_ORDER_FIELD_WND_OFFSET;
|
||||
out_uint32_le(s, 0); /* window_client_delta_x */
|
||||
out_uint32_le(s, 0); /* window_client_delta_y */
|
||||
flags |= WINDOW_ORDER_FIELD_WND_CLIENT_DELTA;
|
||||
out_uint32_le(s, config->width); /* window_width */
|
||||
out_uint32_le(s, config->height); /* window_height */
|
||||
flags |= WINDOW_ORDER_FIELD_WND_SIZE;
|
||||
out_uint16_le(s, num_window_rects); /* num_window_rects */
|
||||
for (i = 0; i < num_window_rects; i++)
|
||||
{
|
||||
out_uint16_le(s, 0); /* left */
|
||||
out_uint16_le(s, 0); /* top */
|
||||
out_uint16_le(s, config->width); /* right */
|
||||
out_uint16_le(s, config->height); /* bottom */
|
||||
}
|
||||
flags |= WINDOW_ORDER_FIELD_WND_RECTS;
|
||||
out_uint32_le(s, config->x); /* visible_offset_x */
|
||||
out_uint32_le(s, config->y); /* visible_offset_y */
|
||||
flags |= WINDOW_ORDER_FIELD_VIS_OFFSET;
|
||||
out_uint16_le(s, num_visibility_rects); /* num_visibility_rects */
|
||||
for (i = 0; i < num_visibility_rects; i++)
|
||||
{
|
||||
out_uint16_le(s, 0); /* left */
|
||||
out_uint16_le(s, 0); /* top */
|
||||
out_uint16_le(s, config->width); /* right */
|
||||
out_uint16_le(s, config->height); /* bottom */
|
||||
}
|
||||
flags |= WINDOW_ORDER_FIELD_VISIBILITY;
|
||||
out_uint32_le(s, flags); /*flags*/
|
||||
|
||||
s_mark_end(s);
|
||||
send_rail_drawing_orders(s->data, (int)(s->end - s->data));
|
||||
free_stream(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1170,10 +1514,6 @@ rail_create_window(Window window_id, Window parent_id)
|
||||
int APP_CC
|
||||
rail_configure_window(XConfigureEvent *config)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
tui32 width;
|
||||
tui32 height;
|
||||
int num_window_rects = 1;
|
||||
int num_visibility_rects = 1;
|
||||
int i = 0;
|
||||
@ -1195,7 +1535,7 @@ rail_configure_window(XConfigureEvent *config)
|
||||
if (index == -1)
|
||||
{
|
||||
/* window isn't mapped yet */
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
flags = WINDOW_ORDER_TYPE_WINDOW;
|
||||
@ -1259,6 +1599,7 @@ int APP_CC
|
||||
rail_xevent(void *xevent)
|
||||
{
|
||||
XEvent *lxevent;
|
||||
XEvent lastevent;
|
||||
XWindowChanges xwc;
|
||||
int rv;
|
||||
int index;
|
||||
@ -1308,6 +1649,7 @@ rail_xevent(void *xevent)
|
||||
lxevent->xconfigurerequest.window,
|
||||
lxevent->xconfigurerequest.value_mask,
|
||||
&xwc);
|
||||
rail_configure_request_window(&(lxevent->xconfigurerequest));
|
||||
rv = 0;
|
||||
break;
|
||||
|
||||
@ -1375,13 +1717,25 @@ rail_xevent(void *xevent)
|
||||
case ConfigureNotify:
|
||||
LOG(10, (" got ConfigureNotify 0x%8.8x event 0x%8.8x", lxevent->xconfigure.window,
|
||||
lxevent->xconfigure.event));
|
||||
#if 0
|
||||
if (lxevent->xconfigure.window != lxevent->xconfigure.event &&
|
||||
!lxevent->xconfigure.override_redirect)
|
||||
rv = 0;
|
||||
if (lxevent->xconfigure.event != lxevent->xconfigure.window ||
|
||||
lxevent->xconfigure.override_redirect)
|
||||
{
|
||||
rail_configure_window(&lxevent->xconfigure);
|
||||
rv = 0;
|
||||
break;
|
||||
}
|
||||
/* skip dup ConfigureNotify */
|
||||
while (XCheckTypedWindowEvent(g_display,
|
||||
lxevent->xconfigure.window,
|
||||
ConfigureNotify, &lastevent))
|
||||
{
|
||||
if (lastevent.xconfigure.event == lastevent.xconfigure.window &&
|
||||
lxevent->xconfigure.override_redirect == 0)
|
||||
{
|
||||
lxevent = &lastevent;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
rail_configure_window(&(lxevent->xconfigure));
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user