/** * 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, rdpWindow* window) { xfWindow* xfw; rdpChannels* channels; RAIL_WINDOW_MOVE_ORDER window_move; xfw = (xfWindow*) window->extra; channels = ((rdpContext*) xfc)->channels; if (! xfw->is_mapped || xfw->local_move.state != LMS_NOT_ACTIVE) return; /* If current window position disagrees with RDP window position, send update to RDP server */ if ( xfw->left != window->visibleOffsetX || xfw->top != window->visibleOffsetY || xfw->width != window->windowWidth || xfw->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 */ window_move.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; DEBUG_X11_LMS("window=0x%X 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) xfw->handle, window_move.left, window_move.top, window_move.right, window_move.bottom, xfw->width, xfw->height, window->windowId, window->windowOffsetX, window->windowOffsetY, window->windowWidth, window->windowHeight); xf_send_rail_client_event(channels, RailChannel_ClientWindowMove, &window_move); } }
void xf_rail_send_client_system_command(xfContext* xfc, UINT32 windowId, UINT16 command) { rdpChannels* channels; RAIL_SYSCOMMAND_ORDER syscommand; channels = ((rdpContext*) xfc)->channels; syscommand.windowId = windowId; syscommand.command = command; xf_send_rail_client_event(channels, RailChannel_ClientSystemCommand, &syscommand); }
void xf_rail_send_client_system_command(xfInfo* xfi, uint32 windowId, uint16 command) { rdpChanMan* chanman; RAIL_SYSCOMMAND_ORDER syscommand; chanman = GET_CHANMAN(xfi->instance); syscommand.windowId = windowId; syscommand.command = command; xf_send_rail_client_event(chanman, RDP_EVENT_TYPE_RAIL_CLIENT_SYSCOMMAND, &syscommand); }
void xf_rail_send_client_system_command(xfInfo* xfi, uint32 windowId, uint16 command) { rdpChannels* channels; RAIL_SYSCOMMAND_ORDER syscommand; channels = xfi->_context->channels; syscommand.windowId = windowId; syscommand.command = command; xf_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_SYSCOMMAND, &syscommand); }
void xf_process_rail_get_sysparams_event(xfContext* xfc, rdpChannels* channels, wMessage* event) { RAIL_SYSPARAM_ORDER* sysparam; sysparam = (RAIL_SYSPARAM_ORDER*) event->wParam; sysparam->workArea.left = xfc->workArea.x; sysparam->workArea.top = xfc->workArea.y; sysparam->workArea.right = xfc->workArea.x + xfc->workArea.width; sysparam->workArea.bottom = xfc->workArea.y + xfc->workArea.height; sysparam->taskbarPos.left = 0; sysparam->taskbarPos.top = 0; sysparam->taskbarPos.right = 0; sysparam->taskbarPos.bottom = 0; sysparam->dragFullWindows = FALSE; xf_send_rail_client_event(channels, RailChannel_ClientSystemParam, sysparam); }
void xf_rail_send_windowmove(xfInfo* xfi, uint32 windowId, uint32 left, uint32 top, uint32 right, uint32 bottom) { rdpChanMan* chanman; RAIL_WINDOW_MOVE_ORDER window_move; chanman = GET_CHANMAN(xfi->instance); window_move.windowId = windowId; window_move.left = left; window_move.top = top; window_move.right = right; window_move.bottom = bottom; xf_send_rail_client_event(chanman, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &window_move); }
void xf_rail_send_activate(xfInfo* xfi, Window xwindow, boolean enabled) { rdpChanMan* chanman; rdpWindow* rail_window; RAIL_ACTIVATE_ORDER activate; chanman = GET_CHANMAN(xfi->instance); rail_window = window_list_get_by_extra_id(xfi->rail->list, (void*)xwindow); if (rail_window == NULL) return; activate.windowId = rail_window->windowId; activate.enabled = enabled; xf_send_rail_client_event(chanman, RDP_EVENT_TYPE_RAIL_CLIENT_ACTIVATE, &activate); }
void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled) { rdpRail* rail; rdpChannels* channels; rdpWindow* rail_window; RAIL_ACTIVATE_ORDER activate; rail = ((rdpContext*) xfc)->rail; channels = ((rdpContext*) xfc)->channels; rail_window = window_list_get_by_extra_id(rail->list, (void*) xwindow); if (rail_window == NULL) return; activate.windowId = rail_window->windowId; activate.enabled = enabled; xf_send_rail_client_event(channels, RailChannel_ClientActivate, &activate); }
void xf_rail_end_local_move(xfInfo* xfi, rdpWindow *window) { xfWindow* xfw; rdpChannels* channels; RAIL_WINDOW_MOVE_ORDER window_move; int x,y; rdpInput* input = xfi->instance->input; xfw = (xfWindow*) window->extra; channels = xfi->_context->channels; // Send RDP client event to inform RDP server window_move.windowId = window->windowId; window_move.left = xfw->left; window_move.top = xfw->top; window_move.right = xfw->right + 1; // In the update to RDP the position is one past the window window_move.bottom = xfw->bottom + 1; DEBUG_X11_LMS("window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d", (uint32) xfw->handle, xfw->left, xfw->top, xfw->right, xfw->bottom, xfw->width, xfw->height); xf_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &window_move); // Send synthetic button up event to the RDP server. This is per the RDP spec to // indicate a local move has finished. x = xfw->left + xfw->local_move.window_x; y = xfw->top + xfw->local_move.window_y; 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 = xfw->left; window->windowOffsetY = xfw->top; window->windowWidth = xfw->width; window->windowHeight = xfw->height; xfw->local_move.state = LMS_TERMINATING; }
void xf_process_rail_get_sysparams_event(xfInfo* xfi, rdpChanMan* chanman, RDP_EVENT* event) { RAIL_SYSPARAM_ORDER* sysparam; sysparam = (RAIL_SYSPARAM_ORDER*) event->user_data; sysparam->workArea.left = xfi->workArea.x; sysparam->workArea.top = xfi->workArea.y; sysparam->workArea.right = xfi->workArea.x + xfi->workArea.width; sysparam->workArea.bottom = xfi->workArea.y + xfi->workArea.height; sysparam->taskbarPos.left = 0; sysparam->taskbarPos.top = 0; sysparam->taskbarPos.right = 0; sysparam->taskbarPos.bottom = 0; sysparam->dragFullWindows = False; xf_send_rail_client_event(chanman, RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS, sysparam); }
void xf_rail_send_activate(xfInfo* xfi, Window xwindow, tbool enabled) { rdpRail* rail; rdpChannels* channels; rdpWindow* rail_window; RAIL_ACTIVATE_ORDER activate; rail = xfi->_context->rail; channels = xfi->_context->channels; rail_window = window_list_get_by_extra_id(rail->list, (void*) xwindow); if (rail_window == NULL) return; activate.windowId = rail_window->windowId; activate.enabled = enabled; xf_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_ACTIVATE, &activate); }
/** * 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(xfInfo* xfi, rdpWindow *window) { xfWindow* xfw; rdpChannels* channels; RAIL_WINDOW_MOVE_ORDER window_move; xfw = (xfWindow*) window->extra; channels = xfi->_context->channels; if (! xfw->is_mapped || xfw->local_move.state != LMS_NOT_ACTIVE) return; // If current window position disagrees with RDP window position, send // update to RDP server if ( xfw->left != window->windowOffsetX || xfw->top != window->windowOffsetY || xfw->width != window->windowWidth || xfw->height != window->windowHeight) { window_move.windowId = window->windowId; window_move.left = xfw->left; window_move.top = xfw->top; window_move.right = xfw->right; window_move.bottom = xfw->bottom; DEBUG_X11_LMS("window=0x%X 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) xfw->handle, xfw->left, xfw->top, xfw->right, xfw->bottom, xfw->width, xfw->height, window->windowId, window->windowOffsetX, window->windowOffsetY, window->windowWidth, window->windowHeight); xf_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &window_move); } }
void xf_rail_end_local_move(xfContext* xfc, rdpWindow* window) { xfWindow* xfw; rdpChannels* channels; RAIL_WINDOW_MOVE_ORDER window_move; rdpInput* input = xfc->instance->input; int x,y; Window root_window; Window child_window; unsigned int mask; int child_x; int child_y; xfw = (xfWindow*) window->extra; channels = ((rdpContext*) xfc)->channels; DEBUG_X11_LMS("window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d", (UINT32) xfw->handle, xfw->left, xfw->top, xfw->right, xfw->bottom, xfw->width, xfw->height); /* * 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 */ window_move.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; /* In the update to RDP the position is one past the window */ window_move.bottom = window_move.top + xfw->height; xf_send_rail_client_event(channels, RailChannel_ClientWindowMove, &window_move); /* * Simulate button up at new position to end the local move (per RDP spec) */ XQueryPointer(xfc->display, xfw->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 ((xfw->local_move.direction != _NET_WM_MOVERESIZE_MOVE_KEYBOARD) && (xfw->local_move.direction != _NET_WM_MOVERESIZE_SIZE_KEYBOARD)) { input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y); DEBUG_X11_LMS("Mouse coordinates. x= %i, y= %i", 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 + (xfw->left - window->visibleOffsetX); window->windowOffsetY = offsetY + window->windowOffsetY + (xfw->top - window->visibleOffsetY); window->windowWidth = xfw->width; window->windowHeight = xfw->height; xfw->local_move.state = LMS_TERMINATING; }