xfreerdp: cleanup xf_window.c, xf_rail.c

This commit is contained in:
Marc-André Moreau 2014-11-11 20:26:47 -05:00
parent d955851052
commit fb5e33440c
5 changed files with 670 additions and 345 deletions

View File

@ -85,12 +85,6 @@ const char* const X11_EVENT_STRINGS[] =
#define DEBUG_X11(fmt, ...) do { } while (0)
#endif
#ifdef WITH_DEBUG_X11_LOCAL_MOVESIZE
#define DEBUG_X11_LMS(fmt, ...) WLog_DBG(TAG, fmt, ## __VA_ARGS__)
#else
#define DEBUG_X11_LMS(fmt, ...) do { } while (0)
#endif
int xf_event_action_script_init(xfContext* xfc)
{
int exitCode;
@ -109,7 +103,7 @@ int xf_event_action_script_init(xfContext* xfc)
if (actionScript < 0)
return -1;
while (fgets(buffer, sizeof(buffer), actionScript) != NULL)
while (fgets(buffer, sizeof(buffer), actionScript))
{
strtok(buffer, "\n");
xevent = _strdup(buffer);
@ -174,7 +168,7 @@ int xf_event_execute_action_script(xfContext* xfc, XEvent* event)
if (actionScript < 0)
return -1;
while (fgets(buffer, sizeof(buffer), actionScript) != NULL)
while (fgets(buffer, sizeof(buffer), actionScript))
{
strtok(buffer, "\n");
}
@ -218,8 +212,7 @@ static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app)
rdpWindow* window;
rdpRail* rail = ((rdpContext*) xfc)->rail;
window = window_list_get_by_extra_id(rail->list,
(void*) event->xexpose.window);
window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window);
if (window)
{
@ -253,10 +246,8 @@ 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) == 0)
{
if (!xf_rdpWindowFromWindow(xfc, window))
return TRUE;
}
/* Translate to desktop coordinates */
XTranslateCoordinates(xfc->display, window,
@ -360,10 +351,9 @@ 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) == 0)
{
if (!xf_rdpWindowFromWindow(xfc, window))
return TRUE;
}
/* Translate to desktop coordinates */
XTranslateCoordinates(xfc->display, window,
RootWindowOfScreen(xfc->screen),
@ -452,10 +442,9 @@ 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) == NULL)
{
if (!xf_rdpWindowFromWindow(xfc, window))
return TRUE;
}
/* Translate to desktop coordinates */
XTranslateCoordinates(xfc->display, window,
RootWindowOfScreen(xfc->screen),
@ -541,8 +530,8 @@ static BOOL xf_event_FocusIn(xfContext* xfc, XEvent* event, BOOL app)
window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window);
/* Update the server with any window changes that occured while the window was not focused. */
if (window != NULL)
/* Update the server with any window changes that occurred while the window was not focused. */
if (window)
xf_rail_adjust_position(xfc, window);
}
@ -595,7 +584,7 @@ static BOOL xf_event_ClientMessage(xfContext* xfc, XEvent* event, BOOL app)
window = window_list_get_by_extra_id(rail->list, (void*) event->xclient.window);
if (window != NULL)
if (window)
{
xf_rail_send_client_system_command(xfc, window->windowId, SC_CLOSE);
}
@ -633,7 +622,7 @@ static BOOL xf_event_EnterNotify(xfContext* xfc, XEvent* event, BOOL app)
rdpRail* rail = ((rdpContext*) xfc)->rail;
window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window);
if (window != NULL)
if (window)
{
xfw = (xfWindow*) window->extra;
xfc->window = xfw;
@ -659,21 +648,12 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app)
rdpWindow* window;
rdpRail* rail = ((rdpContext*) xfc)->rail;
if (!xfc->remote_app || !rail)
return TRUE;
/* This is for resizing the window by dragging the border
if (xfc->width != event->xconfigure.width)
{
xfc->settings->ScalingFactor = (double) event->xconfigure.width / (double) xfc->originalWidth;
xfc->currentWidth = event->xconfigure.width;
xfc->currentHeight = event->xconfigure.width;
xf_draw_screen_scaled(xfc);
}
*/
window = window_list_get_by_extra_id(rail->list, (void*) event->xconfigure.window);
if (window != NULL)
if (window)
{
xfWindow* xfw;
Window childWindow;
@ -688,18 +668,11 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app)
RootWindowOfScreen(xfc->screen),
0, 0, &xfw->left, &xfw->top, &childWindow);
xfw->width = event->xconfigure.width;
xfw->height = event->xconfigure.height;
xfw->right = xfw->left + xfw->width - 1;
xfw->bottom = xfw->top + xfw->height - 1;
DEBUG_X11_LMS("window=0x%X rc={l=%d t=%d r=%d b=%d} w=%u h=%u send_event=%d",
(UINT32) xfw->handle, xfw->left, xfw->top, xfw->right, xfw->bottom,
xfw->width, xfw->height, event->xconfigure.send_event);
/*
* Additonal checks for not in a local move and not ignoring configure to send
* position update to server, also should the window not be focused then do not
@ -726,7 +699,7 @@ static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app)
}
return True;
return TRUE;
}
static BOOL xf_event_MapNotify(xfContext* xfc, XEvent* event, BOOL app)
@ -749,7 +722,7 @@ static BOOL xf_event_MapNotify(xfContext* xfc, XEvent* event, BOOL app)
{
window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window);
if (window != NULL)
if (window)
{
/* local restore event */
@ -783,7 +756,7 @@ static BOOL xf_event_UnmapNotify(xfContext* xfc, XEvent* event, BOOL app)
{
window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window);
if (window != NULL)
if (window)
{
xfWindow* xfw = (xfWindow*) window->extra;
xfw->is_mapped = FALSE;
@ -807,7 +780,7 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, XEvent* event, BOOL app)
window = xf_rdpWindowFromWindow(xfc, event->xproperty.window);
if (window == NULL)
if (!window)
return TRUE;
if ((((Atom) event->xproperty.atom == xfc->_NET_WM_STATE) && (event->xproperty.state != PropertyDelete)) ||
@ -827,36 +800,30 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, XEvent* event, BOOL app)
status = xf_GetWindowProperty(xfc, event->xproperty.window,
xfc->_NET_WM_STATE, 12, &nitems, &bytes, &prop);
if (!status)
if (status)
{
DEBUG_X11_LMS("No return _NET_WM_STATE, window is not maximized");
}
for (i = 0; i < nitems; i++)
{
if ((Atom) ((UINT16**) prop)[i] == XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False))
{
maxVert = TRUE;
}
for (i = 0; i < nitems; i++)
{
if ((Atom) ((UINT16**) prop)[i] == XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False))
{
maxVert = TRUE;
}
if ((Atom) ((UINT16**) prop)[i] == XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False))
{
maxHorz = TRUE;
if ((Atom) ((UINT16**) prop)[i] == XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False))
{
maxHorz = TRUE;
}
}
XFree(prop);
}
XFree(prop);
}
if ((Atom) event->xproperty.atom == xfc->WM_STATE)
{
status = xf_GetWindowProperty(xfc, event->xproperty.window, xfc->WM_STATE, 1, &nitems, &bytes, &prop);
if (!status)
{
DEBUG_X11_LMS("No return WM_STATE, window is not minimized");
}
else
if (status)
{
/* If the window is in the iconic state */
if (((UINT32) *prop == 3))
@ -871,19 +838,16 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, XEvent* event, BOOL app)
if (maxVert && maxHorz && !minimized && (xfc->window->rail_state != WINDOW_SHOW_MAXIMIZED))
{
DEBUG_X11_LMS("Send SC_MAXIMIZE command to rail server.");
xfc->window->rail_state = WINDOW_SHOW_MAXIMIZED;
xf_rail_send_client_system_command(xfc, window->windowId, SC_MAXIMIZE);
}
else if (minimized && (xfc->window->rail_state != WINDOW_SHOW_MINIMIZED))
{
DEBUG_X11_LMS("Send SC_MINIMIZE command to rail server.");
xfc->window->rail_state = WINDOW_SHOW_MINIMIZED;
xf_rail_send_client_system_command(xfc, window->windowId, SC_MINIMIZE);
}
else if (!minimized && !maxVert && !maxHorz && (xfc->window->rail_state != WINDOW_SHOW))
{
DEBUG_X11_LMS("Send SC_RESTORE command to rail server");
xfc->window->rail_state = WINDOW_SHOW;
xf_rail_send_client_system_command(xfc, window->windowId, SC_RESTORE);
}
@ -907,7 +871,6 @@ static BOOL xf_event_suppress_events(xfContext* xfc, rdpWindow* window, XEvent*e
if ( (event->type == ConfigureNotify) && xfc->window->rail_ignore_configure)
{
DEBUG_X11_LMS("ConfigureNotify Event Ignored");
xfc->window->rail_ignore_configure = FALSE;
return TRUE;
}
@ -958,7 +921,6 @@ static BOOL xf_event_suppress_events(xfContext* xfc, rdpWindow* window, XEvent*e
/* Keep us up to date on position */
break;
default:
DEBUG_X11_LMS("Event Type to break LMS: %s", X11_EVENT_STRINGS[event->type]);
/* Any other event terminates move */
xf_rail_end_local_move(xfc, window);
break;

View File

@ -86,6 +86,7 @@ void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion)
{
int index;
int count;
xfWindow* xfw = NULL;
RECTANGLE_16 updateRect;
RECTANGLE_16 windowRect;
ULONG_PTR* pKeys = NULL;
@ -120,7 +121,12 @@ void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion)
updateRect.right = extents->right - railWindow->x;
updateRect.bottom = extents->bottom - railWindow->y;
//InvalidateRect(railWindow->hWnd, &updateRect, FALSE);
if (xfw)
{
xf_UpdateWindowArea(xfc, xfw, updateRect.left, updateRect.top,
updateRect.right - updateRect.left,
updateRect.bottom - updateRect.top);
}
}
}
}
@ -140,6 +146,26 @@ 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);
@ -175,12 +201,7 @@ void xf_rail_paint(xfContext* xfc, INT32 uleft, INT32 utop, UINT32 uright, UINT3
}
}
void xf_rail_DesktopNonMonitored(rdpRail* rail, rdpWindow* window)
{
xfContext* xfc;
xfc = (xfContext*) rail->extra;
xf_rail_disable_remoteapp_mode(xfc);
}
#if 1
static void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window)
{
@ -291,6 +312,13 @@ static void xf_rail_DestroyWindow(rdpRail* rail, rdpWindow* window)
xf_DestroyWindow(xfc, xfw);
}
void xf_rail_DesktopNonMonitored(rdpRail* rail, rdpWindow* window)
{
xfContext* xfc;
xfc = (xfContext*) rail->extra;
xf_rail_disable_remoteapp_mode(xfc);
}
void xf_rail_register_callbacks(xfContext* xfc, rdpRail* rail)
{
rail->extra = (void*) xfc;
@ -305,6 +333,8 @@ 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;
@ -342,7 +372,7 @@ void xf_rail_send_client_system_command(xfContext* xfc, UINT32 windowId, UINT16
void xf_rail_adjust_position(xfContext* xfc, rdpWindow* window)
{
xfWindow* xfw;
RAIL_WINDOW_MOVE_ORDER window_move;
RAIL_WINDOW_MOVE_ORDER windowMove;
xfw = (xfWindow*) window->extra;
@ -374,17 +404,17 @@ void xf_rail_adjust_position(xfContext* xfc, rdpWindow* window)
* but our local window is based on the visibleOffset since using the windowOffset
* can result in blank areas for a maximized window
*/
window_move.windowId = window->windowId;
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)
*/
window_move.left = offsetX + window->windowOffsetX + (xfw->left - window->visibleOffsetX);
window_move.top = offsetY + window->windowOffsetY + (xfw->top - window->visibleOffsetY);
window_move.right = window_move.left + xfw->width;
window_move.bottom = window_move.top + xfw->height;
windowMove.left = offsetX + window->windowOffsetX + (xfw->left - window->visibleOffsetX);
windowMove.top = offsetY + window->windowOffsetY + (xfw->top - window->visibleOffsetY);
windowMove.right = windowMove.left + xfw->width;
windowMove.bottom = windowMove.top + xfw->height;
xfc->rail->ClientWindowMove(xfc->rail, &window_move);
xfc->rail->ClientWindowMove(xfc->rail, &windowMove);
}
}
@ -460,6 +490,260 @@ void xf_rail_end_local_move(xfContext* xfc, rdpWindow* window)
xfw->local_move.state = LMS_TERMINATING;
}
#if 0
/* RemoteApp Core Protocol Extension */
static void xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState)
{
xfRailWindow* railWindow = NULL;
xfContext* xfc = (xfContext*) context;
UINT32 fieldFlags = orderInfo->fieldFlags;
if (fieldFlags & WINDOW_ORDER_STATE_NEW)
{
railWindow = (xfRailWindow*) calloc(1, sizeof(xfRailWindow));
if (!railWindow)
return;
railWindow->xfc = xfc;
railWindow->id = orderInfo->windowId;
railWindow->dwStyle = windowState->style;
railWindow->dwExStyle = windowState->extendedStyle;
railWindow->x = windowState->windowOffsetX;
railWindow->y = windowState->windowOffsetY;
railWindow->width = windowState->windowWidth;
railWindow->height = windowState->windowHeight;
if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
{
char* title = NULL;
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
windowState->titleInfo.length / 2, &title, 0, NULL, NULL);
railWindow->title = title;
}
else
{
railWindow->title = _strdup("RdpRailWindow");
}
railWindow->xfw = xf_CreateWindow(xfc, railWindow, railWindow->x, railWindow->y,
railWindow->width, railWindow->height, railWindow->id);
HashTable_Add(xfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId, (void*) railWindow);
return;
}
else
{
railWindow = (xfRailWindow*) HashTable_GetItemValue(xfc->railWindows,
(void*) (UINT_PTR) orderInfo->windowId);
}
if (!railWindow)
return;
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;
}
if (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
{
railWindow->width = windowState->windowWidth;
railWindow->height = windowState->windowHeight;
}
}
if (fieldFlags & WINDOW_ORDER_FIELD_OWNER)
{
}
if (fieldFlags & WINDOW_ORDER_FIELD_STYLE)
{
railWindow->dwStyle = windowState->style;
railWindow->dwExStyle = windowState->extendedStyle;
}
if (fieldFlags & WINDOW_ORDER_FIELD_SHOW)
{
}
if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
{
char* title = NULL;
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
windowState->titleInfo.length / 2, &title, 0, NULL, NULL);
free(railWindow->title);
railWindow->title = title;
}
if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
{
}
if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
{
}
if (fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
{
}
if (fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
{
}
if (fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
{
}
if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
{
}
if (fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
{
}
if (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
{
}
}
static void xf_rail_window_delete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo)
{
xfRailWindow* railWindow = NULL;
xfContext* xfc = (xfContext*) context;
railWindow = (xfRailWindow*) HashTable_GetItemValue(xfc->railWindows,
(void*) (UINT_PTR) orderInfo->windowId);
if (!railWindow)
return;
HashTable_Remove(xfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId);
free(railWindow);
}
static void xf_rail_window_icon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* windowIcon)
{
BOOL bigIcon;
xfRailWindow* railWindow;
xfContext* xfc = (xfContext*) context;
railWindow = (xfRailWindow*) HashTable_GetItemValue(xfc->railWindows,
(void*) (UINT_PTR) orderInfo->windowId);
if (!railWindow)
return;
bigIcon = (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_BIG) ? TRUE : FALSE;
}
static void xf_rail_window_cached_icon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* windowCachedIcon)
{
}
static void xf_rail_notify_icon_common(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState)
{
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION)
{
}
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
{
}
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
{
}
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE)
{
}
if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
{
//ICON_INFO* iconInfo = &(notifyIconState->icon);
}
if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
{
}
}
static void xf_rail_notify_icon_create(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState)
{
xf_rail_notify_icon_common(context, orderInfo, notifyIconState);
}
static void xf_rail_notify_icon_update(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState)
{
xf_rail_notify_icon_common(context, orderInfo, notifyIconState);
}
static void xf_rail_notify_icon_delete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo)
{
}
static void xf_rail_monitored_desktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitoredDesktop)
{
}
static void xf_rail_non_monitored_desktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo)
{
}
void xf_rail_register_update_callbacks(rdpUpdate* update)
{
rdpWindowUpdate* window = update->window;
window->WindowCreate = xf_rail_window_common;
window->WindowUpdate = xf_rail_window_common;
window->WindowDelete = xf_rail_window_delete;
window->WindowIcon = xf_rail_window_icon;
window->WindowCachedIcon = xf_rail_window_cached_icon;
window->NotifyIconCreate = xf_rail_notify_icon_create;
window->NotifyIconUpdate = xf_rail_notify_icon_update;
window->NotifyIconDelete = xf_rail_notify_icon_delete;
window->MonitoredDesktop = xf_rail_monitored_desktop;
window->NonMonitoredDesktop = xf_rail_non_monitored_desktop;
}
#endif
/* RemoteApp Virtual Channel Extension */
static int xf_rail_server_execute_result(RailClientContext* context, RAIL_EXEC_RESULT_ORDER* execResult)
@ -706,19 +990,18 @@ int xf_rail_init(xfContext* xfc, RailClientContext* rail)
xf_rail_register_callbacks(xfc, context->rail);
if (1)
{
rail->custom = (void*) xfc;
//xf_rail_register_update_callbacks(context->update);
rail->ServerExecuteResult = xf_rail_server_execute_result;
rail->ServerSystemParam = xf_rail_server_system_param;
rail->ServerHandshake = xf_rail_server_handshake;
rail->ServerHandshakeEx = xf_rail_server_handshake_ex;
rail->ServerLocalMoveSize = xf_rail_server_local_move_size;
rail->ServerMinMaxInfo = xf_rail_server_min_max_info;
rail->ServerLanguageBarInfo = xf_rail_server_language_bar_info;
rail->ServerGetAppIdResponse = xf_rail_server_get_appid_response;
}
rail->custom = (void*) xfc;
rail->ServerExecuteResult = xf_rail_server_execute_result;
rail->ServerSystemParam = xf_rail_server_system_param;
rail->ServerHandshake = xf_rail_server_handshake;
rail->ServerHandshakeEx = xf_rail_server_handshake_ex;
rail->ServerLocalMoveSize = xf_rail_server_local_move_size;
rail->ServerMinMaxInfo = xf_rail_server_min_max_info;
rail->ServerLanguageBarInfo = xf_rail_server_language_bar_info;
rail->ServerGetAppIdResponse = xf_rail_server_get_appid_response;
return 1;
}

View File

@ -25,10 +25,9 @@
struct xf_rail_window
{
xfContext* wfc;
HWND hWnd;
xfContext* xfc;
UINT32 id;
DWORD dwStyle;
DWORD dwExStyle;
@ -37,6 +36,18 @@ struct xf_rail_window
int width;
int height;
char* title;
GC gc;
int shmid;
Window handle;
Window* xfwin;
BOOL fullscreen;
BOOL decorations;
BOOL is_mapped;
BOOL is_transient;
xfLocalMove local_move;
BYTE rail_state;
BOOL rail_ignore_configure;
};
typedef struct xf_rail_window xfRailWindow;

View File

@ -111,7 +111,7 @@ typedef struct _PropMotifWmHints PropMotifWmHints;
/**
* Post an event from the client to the X server
*/
void xf_SendClientEvent(xfContext *xfc, xfWindow *window, Atom atom, unsigned int numArgs, ...)
void xf_SendClientEvent(xfContext* xfc, Window window, Atom atom, unsigned int numArgs, ...)
{
XEvent xevent;
unsigned int i;
@ -119,127 +119,161 @@ void xf_SendClientEvent(xfContext *xfc, xfWindow *window, Atom atom, unsigned in
va_start(argp, numArgs);
ZeroMemory(&xevent, sizeof(XEvent));
xevent.xclient.type = ClientMessage;
xevent.xclient.serial = 0;
xevent.xclient.send_event = False;
xevent.xclient.display = xfc->display;
xevent.xclient.window = window->handle;
xevent.xclient.window = window;
xevent.xclient.message_type = atom;
xevent.xclient.format = 32;
for(i=0; i<numArgs; i++)
for (i=0; i<numArgs; i++)
{
xevent.xclient.data.l[i] = va_arg(argp, int);
}
DEBUG_X11("Send ClientMessage Event: wnd=0x%04X", (unsigned int) xevent.xclient.window);
XSendEvent(xfc->display, RootWindowOfScreen(xfc->screen), False,
SubstructureRedirectMask | SubstructureNotifyMask, &xevent);
XSync(xfc->display, False);
va_end(argp);
}
void xf_SetWindowFullscreen(xfContext *xfc, xfWindow *window, BOOL fullscreen)
void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
{
if(fullscreen)
if (fullscreen)
{
rdpSettings *settings = xfc->instance->settings;
xf_SetWindowDecorations(xfc, window, FALSE);
XMoveResizeWindow(xfc->display, window->handle, settings->DesktopPosX, settings->DesktopPosY, window->width, window->height);
rdpSettings* settings = xfc->settings;
xf_SetWindowDecorations(xfc, window->handle, FALSE);
XMoveResizeWindow(xfc->display, window->handle,
settings->DesktopPosX, settings->DesktopPosY, window->width, window->height);
XMapRaised(xfc->display, window->handle);
window->fullscreen = TRUE;
}
}
/* http://tronche.com/gui/x/xlib/window-information/XGetWindowProperty.html */
BOOL xf_GetWindowProperty(xfContext *xfc, Window window, Atom property, int length,
unsigned long *nitems, unsigned long *bytes, BYTE **prop)
BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property, int length,
unsigned long* nitems, unsigned long* bytes, BYTE** prop)
{
int status;
Atom actual_type;
int actual_format;
if(property == None)
if (property == None)
return FALSE;
status = XGetWindowProperty(xfc->display, window,
property, 0, length, FALSE, AnyPropertyType,
&actual_type, &actual_format, nitems, bytes, prop);
if(status != Success)
property, 0, length, FALSE, AnyPropertyType,
&actual_type, &actual_format, nitems, bytes, prop);
if (status != Success)
return FALSE;
if(actual_type == None)
if (actual_type == None)
{
WLog_ERR(TAG, "Property %lu does not exist", property);
return FALSE;
}
return TRUE;
}
BOOL xf_GetCurrentDesktop(xfContext *xfc)
BOOL xf_GetCurrentDesktop(xfContext* xfc)
{
BOOL status;
unsigned long nitems;
unsigned long bytes;
unsigned char *prop;
status = xf_GetWindowProperty(xfc, DefaultRootWindow(xfc->display),
xfc->_NET_CURRENT_DESKTOP, 1, &nitems, &bytes, &prop);
if(!status)
xfc->_NET_CURRENT_DESKTOP, 1, &nitems, &bytes, &prop);
if (!status)
return FALSE;
xfc->current_desktop = (int) *prop;
free(prop);
return TRUE;
}
BOOL xf_GetWorkArea(xfContext *xfc)
BOOL xf_GetWorkArea(xfContext* xfc)
{
long *plong;
BOOL status;
unsigned long nitems;
unsigned long bytes;
unsigned char *prop;
status = xf_GetCurrentDesktop(xfc);
if(status != TRUE)
if (!status)
return FALSE;
status = xf_GetWindowProperty(xfc, DefaultRootWindow(xfc->display),
xfc->_NET_WORKAREA, 32 * 4, &nitems, &bytes, &prop);
if(status != TRUE)
xfc->_NET_WORKAREA, 32 * 4, &nitems, &bytes, &prop);
if (!status)
return FALSE;
if((xfc->current_desktop * 4 + 3) >= nitems)
if ((xfc->current_desktop * 4 + 3) >= nitems)
{
free(prop);
return FALSE;
}
plong = (long *) prop;
plong = (long*) prop;
xfc->workArea.x = plong[xfc->current_desktop * 4 + 0];
xfc->workArea.y = plong[xfc->current_desktop * 4 + 1];
xfc->workArea.width = plong[xfc->current_desktop * 4 + 2];
xfc->workArea.height = plong[xfc->current_desktop * 4 + 3];
free(prop);
return TRUE;
}
void xf_SetWindowDecorations(xfContext *xfc, xfWindow *window, BOOL show)
void xf_SetWindowDecorations(xfContext* xfc, Window window, BOOL show)
{
PropMotifWmHints hints;
hints.decorations = (show) ? MWM_DECOR_ALL : 0;
hints.functions = MWM_FUNC_ALL ;
hints.flags = MWM_HINTS_DECORATIONS | MWM_HINTS_FUNCTIONS;
hints.inputMode = 0;
hints.status = 0;
XChangeProperty(xfc->display, window->handle, xfc->_MOTIF_WM_HINTS, xfc->_MOTIF_WM_HINTS, 32,
PropModeReplace, (BYTE *) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
XChangeProperty(xfc->display, window, xfc->_MOTIF_WM_HINTS, xfc->_MOTIF_WM_HINTS, 32,
PropModeReplace, (BYTE*) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
}
void xf_SetWindowUnlisted(xfContext *xfc, xfWindow *window)
void xf_SetWindowUnlisted(xfContext* xfc, Window window)
{
Atom window_state[2];
window_state[0] = xfc->_NET_WM_STATE_SKIP_PAGER;
window_state[1] = xfc->_NET_WM_STATE_SKIP_TASKBAR;
XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_STATE,
XA_ATOM, 32, PropModeReplace, (BYTE *) &window_state, 2);
XChangeProperty(xfc->display, window, xfc->_NET_WM_STATE,
XA_ATOM, 32, PropModeReplace, (BYTE*) &window_state, 2);
}
void xf_SetWindowStyle(xfContext *xfc, xfWindow *window, UINT32 style, UINT32 ex_style)
void xf_SetWindowStyle(xfContext* xfc, xfWindow* window, UINT32 style, UINT32 ex_style)
{
Atom window_type;
if(/*(ex_style & WS_EX_TOPMOST) ||*/ (ex_style & WS_EX_TOOLWINDOW))
if (/*(ex_style & WS_EX_TOPMOST) ||*/ (ex_style & WS_EX_TOOLWINDOW))
{
/*
* Tooltips and menu items should be unmanaged windows
@ -254,7 +288,7 @@ void xf_SetWindowStyle(xfContext *xfc, xfWindow *window, UINT32 style, UINT32 ex
attrs.override_redirect = True;
XChangeWindowAttributes(xfc->display, window->handle, CWOverrideRedirect, &attrs);
window->is_transient = TRUE;
xf_SetWindowUnlisted(xfc, window);
xf_SetWindowUnlisted(xfc, window->handle);
window_type = xfc->_NET_WM_WINDOW_TYPE_POPUP;
}
/*
@ -270,40 +304,47 @@ void xf_SetWindowStyle(xfContext *xfc, xfWindow *window, UINT32 style, UINT32 ex
/* this includes dialogs, popups, etc, that need to be full-fledged windows */
window->is_transient = TRUE;
window_type = xfc->_NET_WM_WINDOW_TYPE_DIALOG;
xf_SetWindowUnlisted(xfc, window);
xf_SetWindowUnlisted(xfc, window->handle);
}
else
{
XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_WINDOW_TYPE,
XA_ATOM, 32, PropModeReplace, (BYTE *) &window_type, 1);
XA_ATOM, 32, PropModeReplace, (BYTE*) &window_type, 1);
}
}
void xf_SetWindowText(xfContext *xfc, xfWindow *window, char *name)
void xf_SetWindowText(xfContext* xfc, xfWindow* window, char* name)
{
XStoreName(xfc->display, window->handle, name);
}
static void xf_SetWindowPID(xfContext *xfc, xfWindow *window, pid_t pid)
static void xf_SetWindowPID(xfContext* xfc, xfWindow* window, pid_t pid)
{
Atom am_wm_pid;
if(!pid)
if (!pid)
pid = getpid();
am_wm_pid = XInternAtom(xfc->display, "_NET_WM_PID", False);
XChangeProperty(xfc->display, window->handle, am_wm_pid, XA_CARDINAL,
32, PropModeReplace, (unsigned char *)&pid, 1);
32, PropModeReplace, (BYTE*) &pid, 1);
}
static const char *get_shm_id()
static const char* get_shm_id()
{
static char shm_id[64];
snprintf(shm_id, sizeof(shm_id), "com.freerdp.xfreerpd.tsmf_%016X", GetCurrentProcessId());
return shm_id;
}
xfWindow* xf_CreateDesktopWindow(xfContext *xfc, char *name, int width, int height, BOOL decorations)
xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char *name, int width, int height, BOOL decorations)
{
xfWindow* window;
XEvent xevent;
xfWindow* window;
rdpSettings* settings;
window = (xfWindow*) calloc(1, sizeof(xfWindow));
settings = xfc->instance->settings;
@ -311,7 +352,8 @@ xfWindow* xf_CreateDesktopWindow(xfContext *xfc, char *name, int width, int heig
if (window)
{
int input_mask;
XClassHint *class_hints;
XClassHint* class_hints;
window->width = width;
window->height = height;
window->fullscreen = FALSE;
@ -319,10 +361,12 @@ xfWindow* xf_CreateDesktopWindow(xfContext *xfc, char *name, int width, int heig
window->local_move.state = LMS_NOT_ACTIVE;
window->is_mapped = FALSE;
window->is_transient = FALSE;
window->handle = XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen),
xfc->workArea.x, xfc->workArea.y, xfc->workArea.width, xfc->workArea.height, 0, xfc->depth, InputOutput, xfc->visual,
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
CWBorderPixel | CWWinGravity | CWBitGravity, &xfc->attribs);
xfc->workArea.x, xfc->workArea.y, xfc->workArea.width, xfc->workArea.height,
0, xfc->depth, InputOutput, xfc->visual,
CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
CWBorderPixel | CWWinGravity | CWBitGravity, &xfc->attribs);
window->shmid = shm_open(get_shm_id(), O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE);
@ -355,8 +399,8 @@ xfWindow* xf_CreateDesktopWindow(xfContext *xfc, char *name, int width, int heig
{
class_hints->res_name = "xfreerdp";
if (xfc->instance->settings->WmClass)
class_hints->res_class = xfc->instance->settings->WmClass;
if (xfc->settings->WmClass)
class_hints->res_class = xfc->settings->WmClass;
else
class_hints->res_class = "xfreerdp";
@ -365,7 +409,7 @@ xfWindow* xf_CreateDesktopWindow(xfContext *xfc, char *name, int width, int heig
}
xf_ResizeDesktopWindow(xfc, window, width, height);
xf_SetWindowDecorations(xfc, window, decorations);
xf_SetWindowDecorations(xfc, window->handle, decorations);
xf_SetWindowPID(xfc, window, 0);
input_mask =
@ -377,7 +421,7 @@ xfWindow* xf_CreateDesktopWindow(xfContext *xfc, char *name, int width, int heig
input_mask |= EnterWindowMask | LeaveWindowMask;
XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_ICON, XA_CARDINAL, 32,
PropModeReplace, (BYTE *) xf_icon_prop, ARRAYSIZE(xf_icon_prop));
PropModeReplace, (BYTE*) xf_icon_prop, ARRAYSIZE(xf_icon_prop));
if (xfc->settings->ParentWindowId)
XReparentWindow(xfc->display, window->handle, (Window) xfc->settings->ParentWindowId, 0, 0);
@ -385,7 +429,9 @@ xfWindow* xf_CreateDesktopWindow(xfContext *xfc, char *name, int width, int heig
XSelectInput(xfc->display, window->handle, input_mask);
XClearWindow(xfc->display, window->handle);
XMapWindow(xfc->display, window->handle);
xf_input_init(xfc, window->handle);
/*
* NOTE: This must be done here to handle reparenting the window,
* so that we don't miss the event and hang waiting for the next one
@ -394,69 +440,74 @@ xfWindow* xf_CreateDesktopWindow(xfContext *xfc, char *name, int width, int heig
{
XMaskEvent(xfc->display, VisibilityChangeMask, &xevent);
}
while(xevent.type != VisibilityNotify);
while (xevent.type != VisibilityNotify);
/*
* The XCreateWindow call will start the window in the upper-left corner of our current
* monitor instead of the upper-left monitor for remote app mode(which uses all monitors).
* This extra call after the window is mapped will position the login window correctly
*/
if (xfc->instance->settings->RemoteApplicationMode)
if (xfc->settings->RemoteApplicationMode)
{
XMoveWindow(xfc->display, window->handle, 0, 0);
}
else if(settings->DesktopPosX || settings->DesktopPosY)
else if (settings->DesktopPosX || settings->DesktopPosY)
{
XMoveWindow(xfc->display, window->handle, settings->DesktopPosX, settings->DesktopPosY);
}
}
xf_SetWindowText(xfc, window, name);
XStoreName(xfc->display, window->handle, name);
return window;
}
void xf_ResizeDesktopWindow(xfContext *xfc, xfWindow *window, int width, int height)
void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, int height)
{
XSizeHints *size_hints;
XSizeHints* size_hints;
size_hints = XAllocSizeHints();
if(size_hints)
if (size_hints)
{
size_hints->flags = PMinSize | PMaxSize;
size_hints->min_width = size_hints->max_width = xfc->width;
size_hints->min_height = size_hints->max_height = xfc->height;
XSetWMNormalHints(xfc->display, window->handle, size_hints);
XResizeWindow(xfc->display, window->handle, xfc->width, xfc->height);
XFree(size_hints);
}
}
void xf_FixWindowCoordinates(xfContext *xfc, int *x, int *y, int *width, int *height)
void xf_FixWindowCoordinates(xfContext* xfc, int* x, int* y, int* width, int* height)
{
int vscreen_width;
int vscreen_height;
vscreen_width = xfc->vscreen.area.right - xfc->vscreen.area.left + 1;
vscreen_height = xfc->vscreen.area.bottom - xfc->vscreen.area.top + 1;
if(*width < 1)
if (*width < 1)
{
*width = 1;
}
if(*height < 1)
if (*height < 1)
{
*height = 1;
}
if(*x < xfc->vscreen.area.left)
if (*x < xfc->vscreen.area.left)
{
*width += *x;
*x = xfc->vscreen.area.left;
}
if(*y < xfc->vscreen.area.top)
if (*y < xfc->vscreen.area.top)
{
*height += *y;
*y = xfc->vscreen.area.top;
}
if(*width > vscreen_width)
if (*width > vscreen_width)
{
*width = vscreen_width;
}
if(*height > vscreen_height)
if (*height > vscreen_height)
{
*height = vscreen_height;
}
@ -464,22 +515,25 @@ void xf_FixWindowCoordinates(xfContext *xfc, int *x, int *y, int *width, int *he
char rail_window_class[] = "RAIL:00000000";
xfWindow *xf_CreateWindow(xfContext *xfc, rdpWindow *wnd, int x, int y, int width, int height, UINT32 id)
xfWindow* xf_CreateWindow(xfContext* xfc, rdpWindow* wnd, int x, int y, int width, int height, UINT32 id)
{
XGCValues gcv;
int input_mask;
xfWindow *window;
XWMHints *InputModeHint;
XClassHint *class_hints;
window = (xfWindow *) malloc(sizeof(xfWindow));
ZeroMemory(window, sizeof(xfWindow));
xfWindow* window;
XWMHints* InputModeHint;
XClassHint* class_hints;
window = (xfWindow*) calloc(1, sizeof(xfWindow));
xf_FixWindowCoordinates(xfc, &x, &y, &width, &height);
window->left = x;
window->top = y;
window->right = x + width - 1;
window->bottom = y + height - 1;
window->width = width;
window->height = height;
/*
* WS_EX_DECORATIONS is used by XRDP and instructs
* the client to use local window decorations
@ -492,21 +546,23 @@ xfWindow *xf_CreateWindow(xfContext *xfc, rdpWindow *wnd, int x, int y, int widt
window->is_transient = FALSE;
window->rail_state = 0;
window->rail_ignore_configure = FALSE;
window->handle = XCreateWindow(xfc->display, RootWindowOfScreen(xfc->screen),
x, y, window->width, window->height, 0, xfc->depth, InputOutput, xfc->visual,
0, &xfc->attribs);
DEBUG_X11_LMS("Create window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d rdp=0x%X",
(UINT32) window->handle, window->left, window->top, window->right, window->bottom,
window->width, window->height, wnd->windowId);
x, y, window->width, window->height, 0, xfc->depth,
InputOutput, xfc->visual, 0, &xfc->attribs);
ZeroMemory(&gcv, sizeof(gcv));
window->gc = XCreateGC(xfc->display, window->handle, GCGraphicsExposures, &gcv);
class_hints = XAllocClassHint();
if(class_hints)
if (class_hints)
{
char *class = NULL;
if(xfc->instance->settings->WmClass != NULL)
char* class = NULL;
if (xfc->settings->WmClass)
{
class_hints->res_class = xfc->instance->settings->WmClass;
class_hints->res_class = xfc->settings->WmClass;
}
else
{
@ -514,19 +570,25 @@ xfWindow *xf_CreateWindow(xfContext *xfc, rdpWindow *wnd, int x, int y, int widt
snprintf(class, sizeof(rail_window_class), "RAIL:%08X", id);
class_hints->res_class = class;
}
class_hints->res_name = "RAIL";
XSetClassHint(xfc->display, window->handle, class_hints);
XFree(class_hints);
if(class)
if (class)
free(class);
}
/* Set the input mode hint for the WM */
InputModeHint = XAllocWMHints();
InputModeHint->flags = (1L << 0);
InputModeHint->input = True;
XSetWMHints(xfc->display, window->handle, InputModeHint);
XFree(InputModeHint);
XSetWMProtocols(xfc->display, window->handle, &(xfc->WM_DELETE_WINDOW), 1);
input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask |
ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
PointerMotionMask | Button1MotionMask | Button2MotionMask |
@ -535,25 +597,31 @@ xfWindow *xf_CreateWindow(xfContext *xfc, rdpWindow *wnd, int x, int y, int widt
VisibilityChangeMask | StructureNotifyMask | SubstructureNotifyMask |
SubstructureRedirectMask | FocusChangeMask | PropertyChangeMask |
ColormapChangeMask | OwnerGrabButtonMask;
XSelectInput(xfc->display, window->handle, input_mask);
xf_SetWindowDecorations(xfc, window, window->decorations);
xf_SetWindowDecorations(xfc, window->handle, window->decorations);
xf_SetWindowStyle(xfc, window, wnd->style, wnd->extendedStyle);
xf_SetWindowPID(xfc, window, 0);
xf_ShowWindow(xfc, window, WINDOW_SHOW);
XClearWindow(xfc->display, window->handle);
XMapWindow(xfc->display, window->handle);
/* Move doesn't seem to work until window is mapped. */
xf_MoveWindow(xfc, window, x, y, width, height);
return window;
}
void xf_SetWindowMinMaxInfo(xfContext *xfc, xfWindow *window,
int maxWidth, int maxHeight, int maxPosX, int maxPosY,
int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight)
void xf_SetWindowMinMaxInfo(xfContext* xfc, xfWindow* window,
int maxWidth, int maxHeight, int maxPosX, int maxPosY,
int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight)
{
XSizeHints *size_hints;
XSizeHints* size_hints;
size_hints = XAllocSizeHints();
if(size_hints)
if (size_hints)
{
size_hints->flags = PMinSize | PMaxSize | PResizeInc;
size_hints->min_width = minTrackWidth;
@ -567,17 +635,11 @@ void xf_SetWindowMinMaxInfo(xfContext *xfc, xfWindow *window,
}
}
void xf_StartLocalMoveSize(xfContext *xfc, xfWindow *window, int direction, int x, int y)
void xf_StartLocalMoveSize(xfContext* xfc, xfWindow* window, int direction, int x, int y)
{
if(window->local_move.state != LMS_NOT_ACTIVE)
if (window->local_move.state != LMS_NOT_ACTIVE)
return;
DEBUG_X11_LMS("direction=%d window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d "
"RDP=0x%X rc={l=%d t=%d} w=%d h=%d mouse_x=%d mouse_y=%d",
direction, (UINT32) window->handle,
window->left, window->top, window->right, window->bottom,
window->width, window->height, window->window->windowId,
window->window->windowOffsetX, window->window->windowOffsetY,
window->window->windowWidth, window->window->windowHeight, x, y);
/*
* Save original mouse location relative to root. This will be needed
* to end local move to RDP server and/or X server
@ -586,29 +648,25 @@ void xf_StartLocalMoveSize(xfContext *xfc, xfWindow *window, int direction, int
window->local_move.root_y = y;
window->local_move.state = LMS_STARTING;
window->local_move.direction = direction;
XUngrabPointer(xfc->display, CurrentTime);
xf_SendClientEvent(xfc, window,
xfc->_NET_WM_MOVERESIZE, /* request X window manager to initiate a local move */
5, /* 5 arguments to follow */
x, /* x relative to root window */
y, /* y relative to root window */
direction, /* extended ICCM direction flag */
1, /* simulated mouse button 1 */
1); /* 1 == application request per extended ICCM */
xf_SendClientEvent(xfc, window->handle,
xfc->_NET_WM_MOVERESIZE, /* request X window manager to initiate a local move */
5, /* 5 arguments to follow */
x, /* x relative to root window */
y, /* y relative to root window */
direction, /* extended ICCM direction flag */
1, /* simulated mouse button 1 */
1); /* 1 == application request per extended ICCM */
}
void xf_EndLocalMoveSize(xfContext *xfc, xfWindow *window)
void xf_EndLocalMoveSize(xfContext* xfc, xfWindow* window)
{
DEBUG_X11_LMS("state=%d window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d "
"RDP=0x%X rc={l=%d t=%d} w=%d h=%d",
window->local_move.state,
(UINT32) window->handle, window->left, window->top, window->right, window->bottom,
window->width, window->height, window->window->windowId,
window->window->windowOffsetX, window->window->windowOffsetY,
window->window->windowWidth, window->window->windowHeight);
if(window->local_move.state == LMS_NOT_ACTIVE)
if (window->local_move.state == LMS_NOT_ACTIVE)
return;
if(window->local_move.state == LMS_STARTING)
if (window->local_move.state == LMS_STARTING)
{
/*
* The move never was property started. This can happen due to race
@ -616,97 +674,100 @@ void xf_EndLocalMoveSize(xfContext *xfc, xfWindow *window)
* RDP server for local moves. We must cancel the X window manager move.
* Per ICCM, the X client can ask to cancel an active move.
*/
xf_SendClientEvent(xfc, window,
xfc->_NET_WM_MOVERESIZE, /* request X window manager to abort a local move */
5, /* 5 arguments to follow */
window->local_move.root_x, /* x relative to root window */
window->local_move.root_y, /* y relative to root window */
_NET_WM_MOVERESIZE_CANCEL, /* extended ICCM direction flag */
1, /* simulated mouse button 1 */
1); /* 1 == application request per extended ICCM */
xf_SendClientEvent(xfc, window->handle,
xfc->_NET_WM_MOVERESIZE, /* request X window manager to abort a local move */
5, /* 5 arguments to follow */
window->local_move.root_x, /* x relative to root window */
window->local_move.root_y, /* y relative to root window */
_NET_WM_MOVERESIZE_CANCEL, /* extended ICCM direction flag */
1, /* simulated mouse button 1 */
1); /* 1 == application request per extended ICCM */
}
window->local_move.state = LMS_NOT_ACTIVE;
}
void xf_MoveWindow(xfContext *xfc, xfWindow *window, int x, int y, int width, int height)
void xf_MoveWindow(xfContext* xfc, xfWindow* window, int x, int y, int width, int height)
{
BOOL resize = FALSE;
if((width * height) < 1)
if ((width * height) < 1)
return;
if((window->width != width) || (window->height != height))
if ((window->width != width) || (window->height != height))
resize = TRUE;
if(window->local_move.state == LMS_STARTING ||
if (window->local_move.state == LMS_STARTING ||
window->local_move.state == LMS_ACTIVE)
return;
DEBUG_X11_LMS("window=0x%X rc={l=%d t=%d r=%d b=%d} w=%u h=%u "
"new rc={l=%d t=%d r=%d b=%d} w=%u h=%u"
" RDP=0x%X rc={l=%d t=%d} w=%d h=%d",
(UINT32) window->handle, window->left, window->top,
window->right, window->bottom, window->width, window->height,
x, y, x + width -1, y + height -1, width, height,
window->window->windowId,
window->window->windowOffsetX, window->window->windowOffsetY,
window->window->windowWidth, window->window->windowHeight);
window->left = x;
window->top = y;
window->right = x + width - 1;
window->bottom = y + height - 1;
window->width = width;
window->height = height;
if(resize)
if (resize)
XMoveResizeWindow(xfc->display, window->handle, x, y, width, height);
else
XMoveWindow(xfc->display, window->handle, x, y);
xf_UpdateWindowArea(xfc, window, 0, 0, width, height);
}
void xf_ShowWindow(xfContext *xfc, xfWindow *window, BYTE state)
void xf_ShowWindow(xfContext* xfc, xfWindow* window, BYTE state)
{
switch(state)
switch (state)
{
case WINDOW_HIDE:
XWithdrawWindow(xfc->display, window->handle, xfc->screen_number);
break;
case WINDOW_SHOW_MINIMIZED:
XIconifyWindow(xfc->display, window->handle, xfc->screen_number);
break;
case WINDOW_SHOW_MAXIMIZED:
/* Set the window as maximized */
xf_SendClientEvent(xfc, window, xfc->_NET_WM_STATE, 4, 1,
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False),
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), 0);
xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4, 1,
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False),
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), 0);
/*
* This is a workaround for the case where the window is maximized locally before the rail server is told to maximize
* the window, this appears to be a race condition where the local window with incomplete data and once the window is
* actually maximized on the server - an update of the new areas may not happen. So, we simply to do a full update of
* the entire window once the rail server notifies us that the window is now maximized.
*/
if(window->rail_state == WINDOW_SHOW_MAXIMIZED)
if (window->rail_state == WINDOW_SHOW_MAXIMIZED)
xf_UpdateWindowArea(xfc, window, 0, 0, window->window->windowWidth, window->window->windowHeight);
break;
case WINDOW_SHOW:
/* Ensure the window is not maximized */
xf_SendClientEvent(xfc, window, xfc->_NET_WM_STATE, 4, 0,
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False),
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), 0);
xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4, 0,
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False),
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), 0);
/*
* Ignore configure requests until both the Maximized properties have been processed
* to prevent condition where WM overrides size of request due to one or both of these properties
* still being set - which causes a position adjustment to be sent back to the server
* thus causing the window to not return to its original size
*/
if(window->rail_state == WINDOW_SHOW_MAXIMIZED)
if (window->rail_state == WINDOW_SHOW_MAXIMIZED)
window->rail_ignore_configure = TRUE;
if(window->is_transient)
xf_SetWindowUnlisted(xfc, window);
if (window->is_transient)
xf_SetWindowUnlisted(xfc, window->handle);
break;
}
/* Save the current rail state of this window */
window->rail_state = state;
XFlush(xfc->display);
}
void xf_SetWindowIcon(xfContext *xfc, xfWindow *window, rdpIcon *icon)
void xf_SetWindowIcon(xfContext* xfc, xfWindow* window, rdpIcon* icon)
{
int x, y;
int pixels;
@ -714,36 +775,74 @@ void xf_SetWindowIcon(xfContext *xfc, xfWindow *window, rdpIcon *icon)
long *propdata;
long *dstp;
UINT32 *srcp;
if(!icon->big)
if (!icon->big)
return;
pixels = icon->entry->width * icon->entry->height;
propsize = 2 + pixels;
propdata = malloc(propsize * sizeof(long));
propdata[0] = icon->entry->width;
propdata[1] = icon->entry->height;
dstp = &(propdata[2]);
srcp = (UINT32 *) icon->extra;
for(y = 0; y < icon->entry->height; y++)
srcp = (UINT32*) icon->extra;
for (y = 0; y < icon->entry->height; y++)
{
for(x = 0; x < icon->entry->width; x++)
for (x = 0; x < icon->entry->width; x++)
{
*dstp++ = *srcp++;
}
}
XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_ICON, XA_CARDINAL, 32,
PropModeReplace, (BYTE *) propdata, propsize);
XFlush(xfc->display);
free(propdata);
}
void xf_SetWindowRects(xfContext *xfc, xfWindow *window, RECTANGLE_16 *rects, int nrects)
void xf_SetWindowRects(xfContext* xfc, xfWindow* window, RECTANGLE_16* rects, int nrects)
{
int i;
XRectangle *xrects;
if(nrects == 0)
XRectangle* xrects;
if (nrects < 1)
return;
xrects = malloc(sizeof(XRectangle) * nrects);
for(i = 0; i < nrects; i++)
for (i = 0; i < nrects; i++)
{
xrects[i].x = rects[i].left;
xrects[i].y = rects[i].top;
xrects[i].width = rects[i].right - rects[i].left;
xrects[i].height = rects[i].bottom - rects[i].top;
}
#ifdef WITH_XEXT
/*
* This is currently unsupported with the new logic to handle window placement with VisibleOffset variables
*
* Marc: enabling it works, and is required for round corners.
*/
XShapeCombineRectangles(xfc->display, window->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0);
#endif
free(xrects);
}
void xf_SetWindowVisibilityRects(xfContext* xfc, xfWindow* window, RECTANGLE_16 *rects, int nrects)
{
int i;
XRectangle* xrects;
if (nrects < 1)
return;
xrects = malloc(sizeof(XRectangle) * nrects);
for (i = 0; i < nrects; i++)
{
xrects[i].x = rects[i].left;
xrects[i].y = rects[i].top;
@ -761,83 +860,52 @@ void xf_SetWindowRects(xfContext *xfc, xfWindow *window, RECTANGLE_16 *rects, in
free(xrects);
}
void xf_SetWindowVisibilityRects(xfContext *xfc, xfWindow *window, RECTANGLE_16 *rects, int nrects)
{
int i;
XRectangle *xrects;
if(nrects == 0)
return;
xrects = malloc(sizeof(XRectangle) * nrects);
for(i = 0; i < nrects; i++)
{
xrects[i].x = rects[i].left;
xrects[i].y = rects[i].top;
xrects[i].width = rects[i].right - rects[i].left;
xrects[i].height = rects[i].bottom - rects[i].top;
}
#ifdef WITH_XEXT
/*
* This is currently unsupported with the new logic to handle window placement with VisibleOffset variables
*
* Marc: enabling it works, and is required for round corners.
*/
XShapeCombineRectangles(xfc->display, window->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0);
#endif
free(xrects);
}
void xf_UpdateWindowArea(xfContext *xfc, xfWindow *window, int x, int y, int width, int height)
void xf_UpdateWindowArea(xfContext* xfc, xfWindow* window, int x, int y, int width, int height)
{
int ax, ay;
rdpWindow *wnd;
rdpWindow* wnd;
wnd = window->window;
/* RemoteApp mode uses visibleOffset instead of windowOffset */
if(!xfc->remote_app)
if (!xfc->remote_app)
{
ax = x + wnd->windowOffsetX;
ay = y + wnd->windowOffsetY;
if(ax + width > wnd->windowOffsetX + wnd->windowWidth)
if (ax + width > wnd->windowOffsetX + wnd->windowWidth)
width = (wnd->windowOffsetX + wnd->windowWidth - 1) - ax;
if(ay + height > wnd->windowOffsetY + wnd->windowHeight)
if (ay + height > wnd->windowOffsetY + wnd->windowHeight)
height = (wnd->windowOffsetY + wnd->windowHeight - 1) - ay;
}
else
{
ax = x + wnd->visibleOffsetX;
ay = y + wnd->visibleOffsetY;
if(ax + width > wnd->visibleOffsetX + wnd->windowWidth)
if (ax + width > wnd->visibleOffsetX + wnd->windowWidth)
width = (wnd->visibleOffsetX + wnd->windowWidth - 1) - ax;
if(ay + height > wnd->visibleOffsetY + wnd->windowHeight)
if (ay + height > wnd->visibleOffsetY + wnd->windowHeight)
height = (wnd->visibleOffsetY + wnd->windowHeight - 1) - ay;
}
WaitForSingleObject(xfc->mutex, INFINITE);
if(xfc->settings->SoftwareGdi)
if (xfc->settings->SoftwareGdi)
{
XPutImage(xfc->display, xfc->primary, window->gc, xfc->image,
ax, ay, ax, ay, width, height);
}
XCopyArea(xfc->display, xfc->primary, window->handle, window->gc,
ax, ay, width, height, x, y);
XFlush(xfc->display);
ReleaseMutex(xfc->mutex);
}
BOOL xf_IsWindowBorder(xfContext *xfc, xfWindow *xfw, int x, int y)
{
rdpWindow *wnd;
BOOL clientArea = FALSE;
BOOL windowArea = FALSE;
wnd = xfw->window;
if(((x > wnd->clientOffsetX) && (x < wnd->clientOffsetX + wnd->clientAreaWidth)) &&
((y > wnd->clientOffsetY) && (y < wnd->clientOffsetY + wnd->clientAreaHeight)))
clientArea = TRUE;
if(((x > wnd->windowOffsetX) && (x < wnd->windowOffsetX + wnd->windowWidth)) &&
((y > wnd->windowOffsetY) && (y < wnd->windowOffsetY + wnd->windowHeight)))
windowArea = TRUE;
return (windowArea && !(clientArea));
}
void xf_DestroyWindow(xfContext *xfc, xfWindow *window)
void xf_DestroyWindow(xfContext* xfc, xfWindow* window)
{
if (!window)
return;
@ -868,17 +936,20 @@ void xf_DestroyWindow(xfContext *xfc, xfWindow *window)
free(window);
}
rdpWindow *xf_rdpWindowFromWindow(xfContext *xfc, Window wnd)
rdpWindow* xf_rdpWindowFromWindow(xfContext* xfc, Window wnd)
{
rdpRail *rail;
if(xfc)
rdpRail* rail;
if (xfc)
{
if(wnd)
if (wnd)
{
rail = ((rdpContext *) xfc)->rail;
if(rail)
return window_list_get_by_extra_id(rail->list, (void *)(long) wnd);
rail = ((rdpContext*) xfc)->rail;
if (rail)
return window_list_get_by_extra_id(rail->list, (void*)(long) wnd);
}
}
return NULL;
}

View File

@ -54,9 +54,9 @@ enum xf_localmove_state
struct xf_localmove
{
int root_x; // relative to root
int root_x;
int root_y;
int window_x; // relative to window
int window_x;
int window_y;
enum xf_localmove_state state;
int direction;
@ -73,10 +73,10 @@ struct xf_window
int height;
int shmid;
Window handle;
Window *xfwin;
Window* xfwin;
rdpWindow* window;
BOOL fullscreen;
BOOL decorations;
rdpWindow *window;
BOOL is_mapped;
BOOL is_transient;
xfLocalMove local_move;
@ -84,39 +84,37 @@ struct xf_window
BOOL rail_ignore_configure;
};
void xf_ewmhints_init(xfContext *xfc);
void xf_ewmhints_init(xfContext* xfc);
BOOL xf_GetCurrentDesktop(xfContext *xfc);
BOOL xf_GetWorkArea(xfContext *xfc);
BOOL xf_GetCurrentDesktop(xfContext* xfc);
BOOL xf_GetWorkArea(xfContext* xfc);
void xf_SetWindowFullscreen(xfContext *xfc, xfWindow *window, BOOL fullscreen);
void xf_SetWindowDecorations(xfContext *xfc, xfWindow *window, BOOL show);
void xf_SetWindowUnlisted(xfContext *xfc, xfWindow *window);
void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen);
void xf_SetWindowDecorations(xfContext* xfc, Window window, BOOL show);
void xf_SetWindowUnlisted(xfContext* xfc, Window window);
xfWindow *xf_CreateDesktopWindow(xfContext *xfc, char *name, int width, int height, BOOL decorations);
void xf_ResizeDesktopWindow(xfContext *xfc, xfWindow *window, int width, int height);
xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int height, BOOL decorations);
void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, int height);
xfWindow *xf_CreateWindow(xfContext *xfc, rdpWindow *wnd, int x, int y, int width, int height, UINT32 id);
void xf_SetWindowText(xfContext *xfc, xfWindow *window, char *name);
void xf_MoveWindow(xfContext *xfc, xfWindow *window, int x, int y, int width, int height);
void xf_ShowWindow(xfContext *xfc, xfWindow *window, BYTE state);
void xf_SetWindowIcon(xfContext *xfc, xfWindow *window, rdpIcon *icon);
void xf_SetWindowRects(xfContext *xfc, xfWindow *window, RECTANGLE_16 *rects, int nrects);
void xf_SetWindowVisibilityRects(xfContext *xfc, xfWindow *window, RECTANGLE_16 *rects, int nrects);
void xf_SetWindowStyle(xfContext *xfc, xfWindow *window, UINT32 style, UINT32 ex_style);
void xf_UpdateWindowArea(xfContext *xfc, xfWindow *window, int x, int y, int width, int height);
BOOL xf_IsWindowBorder(xfContext *xfc, xfWindow *xfw, int x, int y);
void xf_DestroyWindow(xfContext *xfc, xfWindow *window);
rdpWindow *xf_rdpWindowFromWindow(xfContext *xfc, Window wnd);
BOOL xf_GetWindowProperty(xfContext* xfc, Window window, Atom property, int length,
unsigned long* nitems, unsigned long* bytes, BYTE** prop);
void xf_SendClientEvent(xfContext* xfc, Window window, Atom atom, unsigned int numArgs, ...);
BOOL xf_GetWindowProperty(xfContext *xfc, Window window, Atom property, int length,
unsigned long *nitems, unsigned long *bytes, BYTE **prop);
void xf_SetWindowMinMaxInfo(xfContext *xfc, xfWindow *window, int maxWidth, int maxHeight,
int maxPosX, int maxPosY, int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight);
void xf_StartLocalMoveSize(xfContext *xfc, xfWindow *window, int direction, int x, int y);
void xf_EndLocalMoveSize(xfContext *xfc, xfWindow *window);
void xf_SendClientEvent(xfContext *xfc, xfWindow *window, Atom atom, unsigned int numArgs, ...);
xfWindow* xf_CreateWindow(xfContext* xfc, rdpWindow* wnd, int x, int y, int width, int height, UINT32 id);
void xf_SetWindowText(xfContext* xfc, xfWindow* window, char* name);
void xf_MoveWindow(xfContext* xfc, xfWindow* window, int x, int y, int width, int height);
void xf_ShowWindow(xfContext* xfc, xfWindow* window, BYTE state);
void xf_SetWindowIcon(xfContext* xfc, xfWindow* window, rdpIcon* icon);
void xf_SetWindowRects(xfContext* xfc, xfWindow* window, RECTANGLE_16* rects, int nrects);
void xf_SetWindowVisibilityRects(xfContext* xfc, xfWindow* window, RECTANGLE_16* rects, int nrects);
void xf_SetWindowStyle(xfContext* xfc, xfWindow* window, UINT32 style, UINT32 ex_style);
void xf_UpdateWindowArea(xfContext* xfc, xfWindow* window, int x, int y, int width, int height);
void xf_DestroyWindow(xfContext* xfc, xfWindow* window);
void xf_SetWindowMinMaxInfo(xfContext* xfc, xfWindow* window,
int maxWidth, int maxHeight, int maxPosX, int maxPosY,
int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight);
void xf_StartLocalMoveSize(xfContext* xfc, xfWindow* window, int direction, int x, int y);
void xf_EndLocalMoveSize(xfContext* xfc, xfWindow* window);
rdpWindow* xf_rdpWindowFromWindow(xfContext* xfc, Window wnd);
#endif /* __XF_WINDOW_H */