mirror of https://github.com/FreeRDP/FreeRDP
xfreerdp: prepare RAIL migration away from libfreerdp-rail
This commit is contained in:
parent
734b30a5fd
commit
abf6d4f71e
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue