xfreerdp: prepare RAIL migration away from libfreerdp-rail

This commit is contained in:
Marc-André Moreau 2014-11-12 16:42:32 -05:00
parent 734b30a5fd
commit abf6d4f71e
5 changed files with 625 additions and 326 deletions

View File

@ -208,15 +208,12 @@ static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app)
}
else
{
rdpWindow* window;
xfAppWindow* appWindow;
rdpRail* rail = ((rdpContext*) xfc)->rail;
window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window);
appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);
if (window)
if (appWindow)
{
appWindow = (xfAppWindow*) window->extra;
xf_UpdateWindowArea(xfc, appWindow, x, y, w, h);
}
}
@ -246,7 +243,7 @@ BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window win
if (app)
{
/* make sure window exists */
if (!xf_rdpWindowFromWindow(xfc, window))
if (!xf_AppWindowFromX11Window(xfc, window))
return TRUE;
/* Translate to desktop coordinates */
@ -351,7 +348,7 @@ BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window win
if (app)
{
/* make sure window exists */
if (!xf_rdpWindowFromWindow(xfc, window))
if (!xf_AppWindowFromX11Window(xfc, window))
return TRUE;
/* Translate to desktop coordinates */
@ -398,7 +395,6 @@ BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window w
rdpInput* input;
Window childWindow;
flags = 0;
wheel = FALSE;
extended = FALSE;
@ -442,7 +438,7 @@ BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window w
if (app)
{
/* make sure window exists */
if (!xf_rdpWindowFromWindow(xfc, window))
if (!xf_AppWindowFromX11Window(xfc, window))
return TRUE;
/* Translate to desktop coordinates */
@ -523,18 +519,15 @@ static BOOL xf_event_FocusIn(xfContext* xfc, XEvent* event, BOOL app)
if (app)
{
rdpWindow* window;
xfAppWindow* appWindow;
rdpRail* rail = ((rdpContext*) xfc)->rail;
xf_rail_send_activate(xfc, event->xany.window, TRUE);
window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window);
appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);
/* Update the server with any window changes that occurred while the window was not focused. */
if (window)
if (appWindow)
{
appWindow = (xfAppWindow*) window->extra;
xf_rail_adjust_position(xfc, appWindow);
}
}
@ -582,15 +575,13 @@ static BOOL xf_event_ClientMessage(xfContext* xfc, XEvent* event, BOOL app)
{
if (app)
{
DEBUG_X11("RAIL window closed");
rdpWindow* window;
rdpRail* rail = ((rdpContext*) xfc)->rail;
xfAppWindow* appWindow;
window = window_list_get_by_extra_id(rail->list, (void*) event->xclient.window);
appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);
if (window)
if (appWindow)
{
xf_rail_send_client_system_command(xfc, window->windowId, SC_CLOSE);
xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_CLOSE);
}
return TRUE;
@ -619,17 +610,14 @@ static BOOL xf_event_EnterNotify(xfContext* xfc, XEvent* event, BOOL app)
}
else
{
xfAppWindow* appWindow;
appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);
/* keep track of which window has focus so that we can apply pointer updates */
rdpWindow* window;
xfAppWindow* appWindow;
rdpRail* rail = ((rdpContext*) xfc)->rail;
window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window);
if (window)
if (appWindow)
{
appWindow = (xfAppWindow*) window->extra;
xfc->appWindow = appWindow;
}
}
@ -650,21 +638,16 @@ static BOOL xf_event_LeaveNotify(xfContext* xfc, XEvent* event, BOOL app)
static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app)
{
rdpWindow* window;
rdpRail* rail = ((rdpContext*) xfc)->rail;
Window childWindow;
xfAppWindow* appWindow;
if (!app || !rail)
if (!app)
return TRUE;
window = window_list_get_by_extra_id(rail->list, (void*) event->xconfigure.window);
appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);
if (window)
if (appWindow)
{
Window childWindow;
xfAppWindow* appWindow;
appWindow = (xfAppWindow*) window->extra;
/*
* ConfigureNotify coordinates are expressed relative to the window parent.
* Translate these to root window coordinates.
@ -689,12 +672,18 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app)
xf_rail_adjust_position(xfc, appWindow);
window->windowOffsetX = appWindow->x;
window->visibleOffsetX = window->windowOffsetX;
window->windowOffsetY = appWindow->y;
window->visibleOffsetY = window->windowOffsetY;
window->windowWidth = appWindow->width;
window->windowHeight = appWindow->height;
#ifdef OLD_X11_RAIL
{
rdpWindow* window = appWindow->window;
window->windowOffsetX = appWindow->x;
window->visibleOffsetX = window->windowOffsetX;
window->windowOffsetY = appWindow->y;
window->visibleOffsetY = window->windowOffsetY;
window->windowWidth = appWindow->width;
window->windowHeight = appWindow->height;
}
#endif
}
else
{
@ -711,9 +700,8 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app)
static BOOL xf_event_MapNotify(xfContext* xfc, XEvent* event, BOOL app)
{
RECTANGLE_16 rect;
rdpWindow* window;
xfAppWindow* appWindow;
rdpUpdate* update = xfc->instance->update;
rdpRail* rail = ((rdpContext*) xfc)->rail;
if (!app)
{
@ -726,9 +714,9 @@ static BOOL xf_event_MapNotify(xfContext* xfc, XEvent* event, BOOL app)
}
else
{
window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window);
appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);
if (window)
if (appWindow)
{
/* local restore event */
@ -737,8 +725,7 @@ static BOOL xf_event_MapNotify(xfContext* xfc, XEvent* event, BOOL app)
* that is minimized back to the maximized state
*/
//xf_rail_send_client_system_command(xfc, window->windowId, SC_RESTORE);
xfAppWindow* appWindow = (xfAppWindow*) window->extra;
//xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE);
appWindow->is_mapped = TRUE;
}
}
@ -748,9 +735,8 @@ static BOOL xf_event_MapNotify(xfContext* xfc, XEvent* event, BOOL app)
static BOOL xf_event_UnmapNotify(xfContext* xfc, XEvent* event, BOOL app)
{
rdpWindow* window;
xfAppWindow* appWindow;
rdpUpdate* update = xfc->instance->update;
rdpRail* rail = ((rdpContext*) xfc)->rail;
xf_keyboard_release_all_keypress(xfc);
@ -760,11 +746,10 @@ static BOOL xf_event_UnmapNotify(xfContext* xfc, XEvent* event, BOOL app)
}
else
{
window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window);
appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);
if (window)
if (appWindow)
{
xfAppWindow* appWindow = (xfAppWindow*) window->extra;
appWindow->is_mapped = FALSE;
}
}
@ -782,15 +767,12 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, XEvent* event, BOOL app)
if (app)
{
rdpWindow* window;
xfAppWindow* appWindow;
window = xf_rdpWindowFromWindow(xfc, event->xproperty.window);
appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);
if (!window)
if (!appWindow)
return TRUE;
appWindow = (xfAppWindow*) window->extra;
if ((((Atom) event->xproperty.atom == xfc->_NET_WM_STATE) && (event->xproperty.state != PropertyDelete)) ||
(((Atom) event->xproperty.atom == xfc->WM_STATE) && (event->xproperty.state != PropertyDelete)))
@ -830,7 +812,8 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, XEvent* event, BOOL app)
if ((Atom) event->xproperty.atom == xfc->WM_STATE)
{
status = xf_GetWindowProperty(xfc, event->xproperty.window, xfc->WM_STATE, 1, &nitems, &bytes, &prop);
status = xf_GetWindowProperty(xfc, event->xproperty.window,
xfc->WM_STATE, 1, &nitems, &bytes, &prop);
if (status)
{
@ -843,22 +826,21 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, XEvent* event, BOOL app)
XFree(prop);
}
}
if (maxVert && maxHorz && !minimized && (appWindow->rail_state != WINDOW_SHOW_MAXIMIZED))
{
appWindow->rail_state = WINDOW_SHOW_MAXIMIZED;
xf_rail_send_client_system_command(xfc, window->windowId, SC_MAXIMIZE);
xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_MAXIMIZE);
}
else if (minimized && (appWindow->rail_state != WINDOW_SHOW_MINIMIZED))
{
appWindow->rail_state = WINDOW_SHOW_MINIMIZED;
xf_rail_send_client_system_command(xfc, window->windowId, SC_MINIMIZE);
xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_MINIMIZE);
}
else if (!minimized && !maxVert && !maxHorz && (appWindow->rail_state != WINDOW_SHOW))
{
appWindow->rail_state = WINDOW_SHOW;
xf_rail_send_client_system_command(xfc, window->windowId, SC_RESTORE);
xf_rail_send_client_system_command(xfc, appWindow->windowId, SC_RESTORE);
}
}
}
@ -948,20 +930,19 @@ static BOOL xf_event_suppress_events(xfContext* xfc, xfAppWindow* appWindow, XEv
BOOL xf_event_process(freerdp* instance, XEvent* event)
{
BOOL status = TRUE;
rdpWindow* window;
xfAppWindow* appWindow;
xfContext* xfc = (xfContext*) instance->context;
rdpRail* rail = ((rdpContext*) xfc)->rail;
if (xfc->remote_app)
{
window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window);
appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);
if (window)
if (appWindow)
{
/* Update "current" window for cursor change orders */
xfc->appWindow = (xfAppWindow*) window->extra;
xfc->appWindow = appWindow;
if (xf_event_suppress_events(xfc, xfc->appWindow, event))
if (xf_event_suppress_events(xfc, appWindow, event))
return TRUE;
}
}

View File

@ -81,6 +81,272 @@ void xf_rail_disable_remoteapp_mode(xfContext* xfc)
}
}
void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled)
{
rdpRail* rail;
rdpWindow* rail_window;
RAIL_ACTIVATE_ORDER activate;
rail = ((rdpContext*) xfc)->rail;
rail_window = window_list_get_by_extra_id(rail->list, (void*) xwindow);
if (!rail_window)
return;
activate.windowId = rail_window->windowId;
activate.enabled = enabled;
xfc->rail->ClientActivate(xfc->rail, &activate);
}
void xf_rail_send_client_system_command(xfContext* xfc, UINT32 windowId, UINT16 command)
{
RAIL_SYSCOMMAND_ORDER syscommand;
syscommand.windowId = windowId;
syscommand.command = command;
xfc->rail->ClientSystemCommand(xfc->rail, &syscommand);
}
/**
* The position of the X window can become out of sync with the RDP window
* if the X window is moved locally by the window manager. In this event
* send an update to the RDP server informing it of the new window position
* and size.
*/
void xf_rail_adjust_position(xfContext* xfc, xfAppWindow* appWindow)
{
#ifdef OLD_X11_RAIL
rdpWindow* window;
RAIL_WINDOW_MOVE_ORDER windowMove;
window = appWindow->window;
if (!appWindow->is_mapped || appWindow->local_move.state != LMS_NOT_ACTIVE)
return;
/* If current window position disagrees with RDP window position, send update to RDP server */
if (appWindow->x != window->visibleOffsetX ||
appWindow->y != window->visibleOffsetY ||
appWindow->width != window->windowWidth ||
appWindow->height != window->windowHeight)
{
/*
* Although the rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY,
* we can only send unsigned integers to the rail server. Therefore, we always bring negative coordinates up to 0
* when attempting to adjust the rail window.
*/
UINT32 offsetX = 0;
UINT32 offsetY = 0;
if (window->windowOffsetX < 0)
offsetX = offsetX - window->windowOffsetX;
if (window->windowOffsetY < 0)
offsetY = offsetY - window->windowOffsetY;
/*
* windowOffset corresponds to the window location on the rail server
* but our local window is based on the visibleOffset since using the windowOffset
* can result in blank areas for a maximized window
*/
windowMove.windowId = window->windowId;
/*
* Calculate new offsets for the rail server window
* Negative offset correction + rail server window offset + (difference in visibleOffset and new window local offset)
*/
windowMove.left = offsetX + window->windowOffsetX + (appWindow->x - window->visibleOffsetX);
windowMove.top = offsetY + window->windowOffsetY + (appWindow->y - window->visibleOffsetY);
windowMove.right = windowMove.left + appWindow->width;
windowMove.bottom = windowMove.top + appWindow->height;
xfc->rail->ClientWindowMove(xfc->rail, &windowMove);
}
#else
UINT32 offsetX = 0;
UINT32 offsetY = 0;
RAIL_WINDOW_MOVE_ORDER windowMove;
if (!appWindow->is_mapped || appWindow->local_move.state != LMS_NOT_ACTIVE)
return;
/* If current window position disagrees with RDP window position, send update to RDP server */
if (appWindow->x != appWindow->visibleOffsetX ||
appWindow->y != appWindow->visibleOffsetY ||
appWindow->width != appWindow->windowWidth ||
appWindow->height != appWindow->windowHeight)
{
/*
* Although the rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY,
* we can only send unsigned integers to the rail server. Therefore, we always bring negative coordinates up to 0
* when attempting to adjust the rail window.
*/
if (appWindow->windowOffsetX < 0)
offsetX = offsetX - appWindow->windowOffsetX;
if (appWindow->windowOffsetY < 0)
offsetY = offsetY - appWindow->windowOffsetY;
/*
* windowOffset corresponds to the window location on the rail server
* but our local window is based on the visibleOffset since using the windowOffset
* can result in blank areas for a maximized window
*/
windowMove.windowId = appWindow->windowId;
/*
* Calculate new offsets for the rail server window
* Negative offset correction + rail server window offset + (difference in visibleOffset and new window local offset)
*/
windowMove.left = offsetX + appWindow->windowOffsetX + (appWindow->x - appWindow->visibleOffsetX);
windowMove.top = offsetY + appWindow->windowOffsetY + (appWindow->y - appWindow->visibleOffsetY);
windowMove.right = windowMove.left + appWindow->width;
windowMove.bottom = windowMove.top + appWindow->height;
xfc->rail->ClientWindowMove(xfc->rail, &windowMove);
}
#endif
}
void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow)
{
#ifdef OLD_X11_RAIL
int x, y;
int child_x;
int child_y;
rdpWindow* window;
unsigned int mask;
Window root_window;
Window child_window;
RAIL_WINDOW_MOVE_ORDER windowMove;
rdpInput* input = xfc->instance->input;
window = appWindow->window;
/*
* Although the rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY,
* we can only send unsigned integers to the rail server. Therefore, we always bring negative coordinates up to 0 when
* attempting to adjust the rail window.
*/
UINT32 offsetX = 0;
UINT32 offsetY = 0;
if (window->windowOffsetX < 0)
offsetX = offsetX - window->windowOffsetX;
if (window->windowOffsetY < 0)
offsetY = offsetY - window->windowOffsetY;
/*
* For keyboard moves send and explicit update to RDP server
*/
windowMove.windowId = window->windowId;
/*
* Calculate new offsets for the rail server window
* Negative offset correction + rail server window offset + (difference in visibleOffset and new window local offset)
*/
windowMove.left = offsetX + window->windowOffsetX + (appWindow->x - window->visibleOffsetX);
windowMove.top = offsetY + window->windowOffsetY + (appWindow->y - window->visibleOffsetY);
windowMove.right = windowMove.left + appWindow->width; /* In the update to RDP the position is one past the window */
windowMove.bottom = windowMove.top + appWindow->height;
xfc->rail->ClientWindowMove(xfc->rail, &windowMove);
/*
* Simulate button up at new position to end the local move (per RDP spec)
*/
XQueryPointer(xfc->display, appWindow->handle,
&root_window, &child_window, &x, &y, &child_x, &child_y, &mask);
input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y);
/* only send the mouse coordinates if not a keyboard move or size */
if ((appWindow->local_move.direction != _NET_WM_MOVERESIZE_MOVE_KEYBOARD) &&
(appWindow->local_move.direction != _NET_WM_MOVERESIZE_SIZE_KEYBOARD))
{
input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y);
}
/*
* Proactively update the RAIL window dimensions. There is a race condition where
* we can start to receive GDI orders for the new window dimensions before we
* receive the RAIL ORDER for the new window size. This avoids that race condition.
*/
window->windowOffsetX = offsetX + window->windowOffsetX + (appWindow->x - window->visibleOffsetX);
window->windowOffsetY = offsetY + window->windowOffsetY + (appWindow->y - window->visibleOffsetY);
window->windowWidth = appWindow->width;
window->windowHeight = appWindow->height;
appWindow->local_move.state = LMS_TERMINATING;
#else
int x, y;
int child_x;
int child_y;
UINT32 offsetX = 0;
UINT32 offsetY = 0;
unsigned int mask;
Window root_window;
Window child_window;
RAIL_WINDOW_MOVE_ORDER windowMove;
rdpInput* input = xfc->instance->input;
/*
* Although the rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY,
* we can only send unsigned integers to the rail server. Therefore, we always bring negative coordinates up to 0 when
* attempting to adjust the rail window.
*/
if (appWindow->windowOffsetX < 0)
offsetX = offsetX - appWindow->windowOffsetX;
if (appWindow->windowOffsetY < 0)
offsetY = offsetY - appWindow->windowOffsetY;
/*
* For keyboard moves send and explicit update to RDP server
*/
windowMove.windowId = appWindow->windowId;
/*
* Calculate new offsets for the rail server window
* Negative offset correction + rail server window offset + (difference in visibleOffset and new window local offset)
*/
windowMove.left = offsetX + appWindow->windowOffsetX + (appWindow->x - appWindow->visibleOffsetX);
windowMove.top = offsetY + appWindow->windowOffsetY + (appWindow->y - appWindow->visibleOffsetY);
windowMove.right = windowMove.left + appWindow->width; /* In the update to RDP the position is one past the window */
windowMove.bottom = windowMove.top + appWindow->height;
xfc->rail->ClientWindowMove(xfc->rail, &windowMove);
/*
* Simulate button up at new position to end the local move (per RDP spec)
*/
XQueryPointer(xfc->display, appWindow->handle,
&root_window, &child_window, &x, &y, &child_x, &child_y, &mask);
input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y);
/* only send the mouse coordinates if not a keyboard move or size */
if ((appWindow->local_move.direction != _NET_WM_MOVERESIZE_MOVE_KEYBOARD) &&
(appWindow->local_move.direction != _NET_WM_MOVERESIZE_SIZE_KEYBOARD))
{
input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y);
}
/*
* Proactively update the RAIL window dimensions. There is a race condition where
* we can start to receive GDI orders for the new window dimensions before we
* receive the RAIL ORDER for the new window size. This avoids that race condition.
*/
appWindow->windowOffsetX = offsetX + appWindow->windowOffsetX + (appWindow->x - appWindow->visibleOffsetX);
appWindow->windowOffsetY = offsetY + appWindow->windowOffsetY + (appWindow->y - appWindow->visibleOffsetY);
appWindow->windowWidth = appWindow->width;
appWindow->windowHeight = appWindow->height;
appWindow->local_move.state = LMS_TERMINATING;
#endif
}
void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion)
{
int index;
@ -134,6 +400,22 @@ void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion)
void xf_rail_paint(xfContext* xfc, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom)
{
#ifndef OLD_X11_RAIL
REGION16 invalidRegion;
RECTANGLE_16 invalidRect;
invalidRect.left = uleft;
invalidRect.top = utop;
invalidRect.right = uright;
invalidRect.bottom = ubottom;
region16_init(&invalidRegion);
region16_union_rect(&invalidRegion, &invalidRegion, &invalidRect);
xf_rail_invalidate_region(xfc, &invalidRegion);
region16_uninit(&invalidRegion);
#else
rdpRail* rail;
rdpWindow* window;
xfAppWindow* appWindow;
@ -144,26 +426,6 @@ void xf_rail_paint(xfContext* xfc, INT32 uleft, INT32 utop, UINT32 uright, UINT3
INT32 wleft, wtop;
UINT32 wright, wbottom;
if (0)
{
REGION16 invalidRegion;
RECTANGLE_16 invalidRect;
invalidRect.left = uleft;
invalidRect.top = utop;
invalidRect.right = uright;
invalidRect.bottom = ubottom;
region16_init(&invalidRegion);
region16_union_rect(&invalidRegion, &invalidRegion, &invalidRect);
xf_rail_invalidate_region(xfc, &invalidRegion);
region16_uninit(&invalidRegion);
return;
}
rail = ((rdpContext*) xfc)->rail;
window_list_rewind(rail->list);
@ -197,9 +459,10 @@ void xf_rail_paint(xfContext* xfc, INT32 uleft, INT32 utop, UINT32 uright, UINT3
xf_UpdateWindowArea(xfc, appWindow, ileft - wleft, itop - wtop, iwidth, iheight);
}
}
#endif
}
#if 1
#ifdef OLD_X11_RAIL
static void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window)
{
@ -343,189 +606,33 @@ void xf_rail_register_callbacks(xfContext* xfc, rdpRail* rail)
rail->rail_DesktopNonMonitored = xf_rail_DesktopNonMonitored;
}
#endif
void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled)
{
rdpRail* rail;
rdpWindow* rail_window;
RAIL_ACTIVATE_ORDER activate;
rail = ((rdpContext*) xfc)->rail;
rail_window = window_list_get_by_extra_id(rail->list, (void*) xwindow);
if (!rail_window)
return;
activate.windowId = rail_window->windowId;
activate.enabled = enabled;
xfc->rail->ClientActivate(xfc->rail, &activate);
}
void xf_rail_send_client_system_command(xfContext* xfc, UINT32 windowId, UINT16 command)
{
RAIL_SYSCOMMAND_ORDER syscommand;
syscommand.windowId = windowId;
syscommand.command = command;
xfc->rail->ClientSystemCommand(xfc->rail, &syscommand);
}
/**
* The position of the X window can become out of sync with the RDP window
* if the X window is moved locally by the window manager. In this event
* send an update to the RDP server informing it of the new window position
* and size.
*/
void xf_rail_adjust_position(xfContext* xfc, xfAppWindow* appWindow)
{
rdpWindow* window;
RAIL_WINDOW_MOVE_ORDER windowMove;
window = appWindow->window;
if (!appWindow->is_mapped || appWindow->local_move.state != LMS_NOT_ACTIVE)
return;
/* If current window position disagrees with RDP window position, send update to RDP server */
if (appWindow->x != window->visibleOffsetX ||
appWindow->y != window->visibleOffsetY ||
appWindow->width != window->windowWidth ||
appWindow->height != window->windowHeight)
{
/*
* Although the rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY,
* we can only send unsigned integers to the rail server. Therefore, we always bring negative coordinates up to 0
* when attempting to adjust the rail window.
*/
UINT32 offsetX = 0;
UINT32 offsetY = 0;
if (window->windowOffsetX < 0)
offsetX = offsetX - window->windowOffsetX;
if (window->windowOffsetY < 0)
offsetY = offsetY - window->windowOffsetY;
/*
* windowOffset corresponds to the window location on the rail server
* but our local window is based on the visibleOffset since using the windowOffset
* can result in blank areas for a maximized window
*/
windowMove.windowId = window->windowId;
/*
* Calculate new offsets for the rail server window
* Negative offset correction + rail server window offset + (difference in visibleOffset and new window local offset)
*/
windowMove.left = offsetX + window->windowOffsetX + (appWindow->x - window->visibleOffsetX);
windowMove.top = offsetY + window->windowOffsetY + (appWindow->y - window->visibleOffsetY);
windowMove.right = windowMove.left + appWindow->width;
windowMove.bottom = windowMove.top + appWindow->height;
xfc->rail->ClientWindowMove(xfc->rail, &windowMove);
}
}
void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow)
{
int x, y;
int child_x;
int child_y;
rdpWindow* window;
unsigned int mask;
Window root_window;
Window child_window;
RAIL_WINDOW_MOVE_ORDER windowMove;
rdpInput* input = xfc->instance->input;
window = appWindow->window;
/*
* Although the rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY,
* we can only send unsigned integers to the rail server. Therefore, we always bring negative coordinates up to 0 when
* attempting to adjust the rail window.
*/
UINT32 offsetX = 0;
UINT32 offsetY = 0;
if (window->windowOffsetX < 0)
offsetX = offsetX - window->windowOffsetX;
if (window->windowOffsetY < 0)
offsetY = offsetY - window->windowOffsetY;
/*
* For keyboard moves send and explicit update to RDP server
*/
windowMove.windowId = window->windowId;
/*
* Calculate new offsets for the rail server window
* Negative offset correction + rail server window offset + (difference in visibleOffset and new window local offset)
*/
windowMove.left = offsetX + window->windowOffsetX + (appWindow->x - window->visibleOffsetX);
windowMove.top = offsetY + window->windowOffsetY + (appWindow->y - window->visibleOffsetY);
windowMove.right = windowMove.left + appWindow->width; /* In the update to RDP the position is one past the window */
windowMove.bottom = windowMove.top + appWindow->height;
xfc->rail->ClientWindowMove(xfc->rail, &windowMove);
/*
* Simulate button up at new position to end the local move (per RDP spec)
*/
XQueryPointer(xfc->display, appWindow->handle,
&root_window, &child_window, &x, &y, &child_x, &child_y, &mask);
input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y);
/* only send the mouse coordinates if not a keyboard move or size */
if ((appWindow->local_move.direction != _NET_WM_MOVERESIZE_MOVE_KEYBOARD) &&
(appWindow->local_move.direction != _NET_WM_MOVERESIZE_SIZE_KEYBOARD))
{
input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y);
}
/*
* Proactively update the RAIL window dimensions. There is a race condition where
* we can start to receive GDI orders for the new window dimensions before we
* receive the RAIL ORDER for the new window size. This avoids that race condition.
*/
window->windowOffsetX = offsetX + window->windowOffsetX + (appWindow->x - window->visibleOffsetX);
window->windowOffsetY = offsetY + window->windowOffsetY + (appWindow->y - window->visibleOffsetY);
window->windowWidth = appWindow->width;
window->windowHeight = appWindow->height;
appWindow->local_move.state = LMS_TERMINATING;
}
#if 0
#else
/* RemoteApp Core Protocol Extension */
static void xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState)
{
xfAppWindow* railWindow = NULL;
xfAppWindow* appWindow = NULL;
xfContext* xfc = (xfContext*) context;
UINT32 fieldFlags = orderInfo->fieldFlags;
if (fieldFlags & WINDOW_ORDER_STATE_NEW)
{
railWindow = (xfAppWindow*) calloc(1, sizeof(xfAppWindow));
appWindow = (xfAppWindow*) calloc(1, sizeof(xfAppWindow));
if (!railWindow)
if (!appWindow)
return;
railWindow->xfc = xfc;
appWindow->xfc = xfc;
railWindow->id = orderInfo->windowId;
railWindow->dwStyle = windowState->style;
railWindow->dwExStyle = windowState->extendedStyle;
appWindow->windowId = orderInfo->windowId;
appWindow->dwStyle = windowState->style;
appWindow->dwExStyle = windowState->extendedStyle;
railWindow->x = windowState->windowOffsetX;
railWindow->y = windowState->windowOffsetY;
railWindow->width = windowState->windowWidth;
railWindow->height = windowState->windowHeight;
appWindow->x = appWindow->windowOffsetX = windowState->windowOffsetX;
appWindow->y = appWindow->windowOffsetY = windowState->windowOffsetY;
appWindow->width = appWindow->windowWidth = windowState->windowWidth;
appWindow->height = appWindow->windowHeight = windowState->windowHeight;
if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
{
@ -534,59 +641,60 @@ static void xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
windowState->titleInfo.length / 2, &title, 0, NULL, NULL);
railWindow->title = title;
appWindow->title = title;
}
else
{
railWindow->title = _strdup("RdpRailWindow");
appWindow->title = _strdup("RdpRailWindow");
}
railWindow->xfw = xf_CreateWindow(xfc, railWindow, railWindow->x, railWindow->y,
railWindow->width, railWindow->height, railWindow->id);
xf_AppWindowInit(xfc, appWindow);
HashTable_Add(xfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId, (void*) railWindow);
HashTable_Add(xfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId, (void*) appWindow);
return;
}
else
{
railWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
(void*) (UINT_PTR) orderInfo->windowId);
}
if (!railWindow)
if (!appWindow)
return;
/* Update Parameters */
if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
(fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE))
{
if (fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
{
railWindow->x = windowState->windowOffsetX;
railWindow->y = windowState->windowOffsetY;
appWindow->x = appWindow->windowOffsetX = windowState->windowOffsetX;
appWindow->y = appWindow->windowOffsetY = windowState->windowOffsetY;
}
if (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
{
railWindow->width = windowState->windowWidth;
railWindow->height = windowState->windowHeight;
appWindow->width = appWindow->windowWidth = windowState->windowWidth;
appWindow->height = appWindow->windowHeight = windowState->windowHeight;
}
}
if (fieldFlags & WINDOW_ORDER_FIELD_OWNER)
{
appWindow->ownerWindowId = windowState->ownerWindowId;
}
if (fieldFlags & WINDOW_ORDER_FIELD_STYLE)
{
railWindow->dwStyle = windowState->style;
railWindow->dwExStyle = windowState->extendedStyle;
appWindow->dwStyle = windowState->style;
appWindow->dwExStyle = windowState->extendedStyle;
}
if (fieldFlags & WINDOW_ORDER_FIELD_SHOW)
{
appWindow->showState = windowState->showState;
}
if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
@ -596,65 +704,155 @@ static void xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
windowState->titleInfo.length / 2, &title, 0, NULL, NULL);
free(railWindow->title);
railWindow->title = title;
free(appWindow->title);
appWindow->title = title;
}
if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
{
appWindow->clientOffsetX = windowState->clientOffsetX;
appWindow->clientOffsetY = windowState->clientOffsetY;
}
if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
{
appWindow->clientAreaWidth = windowState->clientAreaWidth;
appWindow->clientAreaHeight = windowState->clientAreaHeight;
}
if (fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
{
}
if (fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
{
}
if (fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
{
appWindow->windowClientDeltaX = windowState->windowClientDeltaX;
appWindow->windowClientDeltaY = windowState->windowClientDeltaY;
}
if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
{
if (appWindow->windowRects)
{
free(appWindow->windowRects);
appWindow->windowRects = NULL;
}
appWindow->numWindowRects = windowState->numWindowRects;
if (appWindow->numWindowRects)
{
appWindow->windowRects = (RECTANGLE_16*) calloc(appWindow->numWindowRects, sizeof(RECTANGLE_16));
if (!appWindow->windowRects)
return;
CopyMemory(appWindow->windowRects, windowState->windowRects,
appWindow->numWindowRects * sizeof(RECTANGLE_16));
}
}
if (fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
{
appWindow->visibleOffsetX = windowState->visibleOffsetX;
appWindow->visibleOffsetY = windowState->visibleOffsetY;
}
if (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
{
if (appWindow->visibilityRects)
{
free(appWindow->visibilityRects);
appWindow->visibilityRects = NULL;
}
appWindow->numVisibilityRects = windowState->numVisibilityRects;
if (appWindow->numVisibilityRects)
{
appWindow->visibilityRects = (RECTANGLE_16*) calloc(appWindow->numVisibilityRects, sizeof(RECTANGLE_16));
if (!appWindow->visibilityRects)
return;
CopyMemory(appWindow->visibilityRects, windowState->visibilityRects,
appWindow->numVisibilityRects * sizeof(RECTANGLE_16));
}
}
/* Update Window */
if (fieldFlags & WINDOW_ORDER_FIELD_STYLE)
{
}
if (fieldFlags & WINDOW_ORDER_FIELD_SHOW)
{
xf_ShowWindow(xfc, appWindow, appWindow->showState);
}
if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
{
xf_SetWindowText(xfc, appWindow, appWindow->title);
}
if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
(fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE))
{
/*
* The rail server like to set the window to a small size when it is minimized even though it is hidden
* in some cases this can cause the window not to restore back to its original size. Therefore we don't
* update our local window when that rail window state is minimized
*/
if (appWindow->rail_state == WINDOW_SHOW_MINIMIZED)
return;
/* Do nothing if window is already in the correct position */
if (appWindow->x == appWindow->visibleOffsetX &&
appWindow->y == appWindow->visibleOffsetY &&
appWindow->width == appWindow->windowWidth &&
appWindow->height == appWindow->windowHeight)
{
/*
* Just ensure entire window area is updated to handle cases where we
* have drawn locally before getting new bitmap from the server
*/
xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, appWindow->windowHeight);
return;
}
xf_MoveWindow(xfc, appWindow, appWindow->visibleOffsetX, appWindow->visibleOffsetY,
appWindow->windowWidth, appWindow->windowHeight);
}
if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
{
xf_SetWindowRects(xfc, appWindow, appWindow->windowRects, appWindow->numWindowRects);
}
if (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
{
xf_SetWindowVisibilityRects(xfc, appWindow, appWindow->visibilityRects, appWindow->numVisibilityRects);
}
}
static void xf_rail_window_delete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo)
{
xfAppWindow* railWindow = NULL;
xfAppWindow* appWindow = NULL;
xfContext* xfc = (xfContext*) context;
railWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
(void*) (UINT_PTR) orderInfo->windowId);
if (!railWindow)
if (!appWindow)
return;
HashTable_Remove(xfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId);
free(railWindow);
xf_DestroyWindow(xfc, appWindow);
free(appWindow->title);
free(appWindow->windowRects);
free(appWindow->visibilityRects);
free(appWindow);
}
static void xf_rail_window_icon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* windowIcon)
@ -701,7 +899,7 @@ static void xf_rail_notify_icon_common(rdpContext* context, WINDOW_ORDER_INFO* o
if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
{
//ICON_INFO* iconInfo = &(notifyIconState->icon);
}
if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
@ -997,9 +1195,11 @@ int xf_rail_init(xfContext* xfc, RailClientContext* rail)
context->rail = rail_new(context->settings);
rail_register_update_callbacks(context->rail, context->update);
#ifdef OLD_X11_RAIL
xf_rail_register_callbacks(xfc, context->rail);
//xf_rail_register_update_callbacks(context->update);
#else
xf_rail_register_update_callbacks(context->update);
#endif
rail->custom = (void*) xfc;
@ -1012,6 +1212,8 @@ int xf_rail_init(xfContext* xfc, RailClientContext* rail)
rail->ServerLanguageBarInfo = xf_rail_server_language_bar_info;
rail->ServerGetAppIdResponse = xf_rail_server_get_appid_response;
xfc->railWindows = HashTable_New(TRUE);
return 1;
}
@ -1031,5 +1233,11 @@ int xf_rail_uninit(xfContext* xfc, RailClientContext* rail)
context->rail = NULL;
}
if (xfc->railWindows)
{
HashTable_Free(xfc->railWindows);
xfc->railWindows = NULL;
}
return 1;
}

View File

@ -49,6 +49,7 @@
#include "xf_input.h"
#endif
#include "xf_rail.h"
#include "xf_input.h"
#define TAG CLIENT_TAG("x11")
@ -536,33 +537,17 @@ void xf_FixWindowCoordinates(xfContext* xfc, int* x, int* y, int* width, int* he
}
}
xfAppWindow* xf_CreateWindow(xfContext* xfc, rdpWindow* wnd, int x, int y, int width, int height, UINT32 id)
int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow)
{
XGCValues gcv;
int input_mask;
xfAppWindow* appWindow;
XWMHints* InputModeHint;
XClassHint* class_hints;
appWindow = (xfAppWindow*) calloc(1, sizeof(xfAppWindow));
xf_FixWindowCoordinates(xfc, &appWindow->x, &appWindow->y, &appWindow->width, &appWindow->height);
if (!appWindow)
return NULL;
xf_FixWindowCoordinates(xfc, &x, &y, &width, &height);
appWindow->x = x;
appWindow->y = y;
appWindow->width = width;
appWindow->height = height;
/*
* WS_EX_DECORATIONS is used by XRDP and instructs
* the client to use local window decorations
*/
appWindow->decorations = (wnd->extendedStyle & WS_EX_DECORATIONS) ? TRUE : FALSE;
appWindow->decorations = FALSE;
appWindow->fullscreen = FALSE;
appWindow->window = wnd;
appWindow->local_move.state = LMS_NOT_ACTIVE;
appWindow->is_mapped = FALSE;
appWindow->is_transient = FALSE;
@ -570,11 +555,11 @@ xfAppWindow* xf_CreateWindow(xfContext* xfc, rdpWindow* wnd, int x, int y, int w
appWindow->rail_ignore_configure = FALSE;
appWindow->handle = XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen),
x, y, appWindow->width, appWindow->height, 0, xfc->depth,
InputOutput, xfc->visual, 0, &xfc->attribs);
appWindow->x, appWindow->y, appWindow->width, appWindow->height,
0, xfc->depth, InputOutput, xfc->visual, 0, &xfc->attribs);
if (!appWindow->handle)
return NULL;
return -1;
ZeroMemory(&gcv, sizeof(gcv));
appWindow->gc = XCreateGC(xfc->display, appWindow->handle, GCGraphicsExposures, &gcv);
@ -592,7 +577,7 @@ xfAppWindow* xf_CreateWindow(xfContext* xfc, rdpWindow* wnd, int x, int y, int w
else
{
class = malloc(sizeof("RAIL:00000000"));
snprintf(class, sizeof("RAIL:00000000"), "RAIL:%08X", id);
snprintf(class, sizeof("RAIL:00000000"), "RAIL:%08X", appWindow->windowId);
class_hints->res_class = class;
}
@ -626,7 +611,7 @@ xfAppWindow* xf_CreateWindow(xfContext* xfc, rdpWindow* wnd, int x, int y, int w
XSelectInput(xfc->display, appWindow->handle, input_mask);
xf_SetWindowDecorations(xfc, appWindow->handle, appWindow->decorations);
xf_SetWindowStyle(xfc, appWindow, wnd->style, wnd->extendedStyle);
xf_SetWindowStyle(xfc, appWindow, appWindow->dwStyle, appWindow->dwExStyle);
xf_SetWindowPID(xfc, appWindow->handle, 0);
xf_ShowWindow(xfc, appWindow, WINDOW_SHOW);
@ -634,7 +619,35 @@ xfAppWindow* xf_CreateWindow(xfContext* xfc, rdpWindow* wnd, int x, int y, int w
XMapWindow(xfc->display, appWindow->handle);
/* Move doesn't seem to work until window is mapped. */
xf_MoveWindow(xfc, appWindow, x, y, width, height);
xf_MoveWindow(xfc, appWindow, appWindow->x, appWindow->y, appWindow->width, appWindow->height);
return 1;
}
xfAppWindow* xf_CreateWindow(xfContext* xfc, rdpWindow* wnd, int x, int y, int width, int height, UINT32 id)
{
xfAppWindow* appWindow;
appWindow = (xfAppWindow*) calloc(1, sizeof(xfAppWindow));
if (!appWindow)
return NULL;
#ifdef OLD_X11_RAIL
appWindow->window = wnd;
#endif
appWindow->windowId = id;
appWindow->dwStyle = wnd->style;
appWindow->dwExStyle = wnd->extendedStyle;
appWindow->x = x;
appWindow->y = y;
appWindow->width = width;
appWindow->height = height;
xf_AppWindowInit(xfc, appWindow);
return appWindow;
}
@ -763,7 +776,13 @@ void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state)
* the entire window once the rail server notifies us that the window is now maximized.
*/
if (appWindow->rail_state == WINDOW_SHOW_MAXIMIZED)
{
#ifdef OLD_X11_RAIL
xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->window->windowWidth, appWindow->window->windowHeight);
#else
xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->width, appWindow->height);
#endif
}
break;
case WINDOW_SHOW:
@ -878,6 +897,7 @@ void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, RECTANG
void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height)
{
#ifdef OLD_X11_RAIL
int ax, ay;
rdpWindow* wnd;
@ -905,6 +925,32 @@ void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, i
XFlush(xfc->display);
xf_unlock_x11(xfc, TRUE);
#else
int ax, ay;
ax = x + appWindow->visibleOffsetX;
ay = y + appWindow->visibleOffsetY;
if (ax + width > appWindow->visibleOffsetX + appWindow->width)
width = (appWindow->visibleOffsetX + appWindow->width - 1) - ax;
if (ay + height > appWindow->visibleOffsetY + appWindow->height)
height = (appWindow->visibleOffsetY + appWindow->height - 1) - ay;
xf_lock_x11(xfc, TRUE);
if (xfc->settings->SoftwareGdi)
{
XPutImage(xfc->display, xfc->primary, appWindow->gc, xfc->image,
ax, ay, ax, ay, width, height);
}
XCopyArea(xfc->display, xfc->primary, appWindow->handle, appWindow->gc,
ax, ay, width, height, x, y);
XFlush(xfc->display);
xf_unlock_x11(xfc, TRUE);
#endif
}
void xf_DestroyWindow(xfContext* xfc, xfAppWindow* appWindow)
@ -935,8 +981,9 @@ void xf_DestroyWindow(xfContext* xfc, xfAppWindow* appWindow)
free(appWindow);
}
rdpWindow* xf_rdpWindowFromWindow(xfContext* xfc, Window wnd)
xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd)
{
#ifdef OLD_X11_RAIL
rdpRail* rail;
if (xfc)
@ -946,9 +993,39 @@ rdpWindow* xf_rdpWindowFromWindow(xfContext* xfc, Window wnd)
rail = ((rdpContext*) xfc)->rail;
if (rail)
return window_list_get_by_extra_id(rail->list, (void*) (long) wnd);
{
rdpWindow* window;
window = (rdpWindow*) window_list_get_by_extra_id(rail->list, (void*) (long) wnd);
if (!window)
return NULL;
return (xfAppWindow*) window->extra;
}
}
}
#else
int index;
int count;
ULONG_PTR* pKeys = NULL;
xfAppWindow* appWindow;
count = HashTable_GetKeys(xfc->railWindows, &pKeys);
for (index = 0; index < count; index++)
{
appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, (void*) pKeys[index]);
if (appWindow->handle == wnd)
{
free(pKeys);
return appWindow;
}
}
free(pKeys);
#endif
return NULL;
}

View File

@ -86,12 +86,42 @@ struct xf_window
struct xf_app_window
{
xfContext* xfc;
#ifdef OLD_X11_RAIL
rdpWindow* window;
#endif
int x;
int y;
int width;
int height;
char* title;
UINT32 windowId;
UINT32 ownerWindowId;
UINT32 dwStyle;
UINT32 dwExStyle;
UINT32 showState;
UINT32 clientOffsetX;
UINT32 clientOffsetY;
UINT32 clientAreaWidth;
UINT32 clientAreaHeight;
UINT32 windowOffsetX;
UINT32 windowOffsetY;
UINT32 windowClientDeltaX;
UINT32 windowClientDeltaY;
UINT32 windowWidth;
UINT32 windowHeight;
UINT32 numWindowRects;
RECTANGLE_16* windowRects;
UINT32 visibleOffsetX;
UINT32 visibleOffsetY;
UINT32 numVisibilityRects;
RECTANGLE_16* visibilityRects;
GC gc;
int shmid;
@ -123,6 +153,7 @@ BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property, int leng
unsigned long* nitems, unsigned long* bytes, BYTE** prop);
void xf_SendClientEvent(xfContext* xfc, Window window, Atom atom, unsigned int numArgs, ...);
int xf_AppWindowInit(xfContext* xfc, xfAppWindow* appWindow);
xfAppWindow* xf_CreateWindow(xfContext* xfc, rdpWindow* wnd, int x, int y, int width, int height, UINT32 id);
void xf_SetWindowText(xfContext* xfc, xfAppWindow* appWindow, char* name);
void xf_MoveWindow(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height);
@ -138,6 +169,6 @@ void xf_SetWindowMinMaxInfo(xfContext* xfc, xfAppWindow* appWindow,
int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight);
void xf_StartLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow, int direction, int x, int y);
void xf_EndLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow);
rdpWindow* xf_rdpWindowFromWindow(xfContext* xfc, Window wnd);
xfAppWindow* xf_AppWindowFromX11Window(xfContext* xfc, Window wnd);
#endif /* __XF_WINDOW_H */

View File

@ -24,6 +24,8 @@ typedef struct xf_context xfContext;
#include <freerdp/api.h>
#define OLD_X11_RAIL 1
#include "xf_window.h"
#include "xf_monitor.h"
#include "xf_channels.h"