static const char* get_shm_id()
{
static char shm_id[64];
- snprintf(shm_id, sizeof(shm_id), "com.freerdp.xfreerpd.tsmf_%016X", GetCurrentProcessId());
+ snprintf(shm_id, sizeof(shm_id), "com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId());
return shm_id;
}
static const size_t password_size = 512;
-void xf_transform_window(xfContext *xfc)
+void xf_transform_window(xfContext* xfc)
{
int ret;
int w;
}
}
-void xf_draw_screen_scaled(xfContext *xfc, int x, int y, int w, int h, BOOL scale)
+void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h, BOOL scale)
{
#ifdef WITH_XRENDER
XTransform transform;
XRenderPictureAttributes pa;
XRenderPictFormat *picFormat;
XRectangle xr;
+
picFormat = XRenderFindStandardFormat(xfc->display, PictStandardRGB24);
+
pa.subwindow_mode = IncludeInferiors;
primaryPicture = XRenderCreatePicture(xfc->display, xfc->primary, picFormat, CPSubwindowMode, &pa);
windowPicture = XRenderCreatePicture(xfc->display, xfc->window->handle, picFormat, CPSubwindowMode, &pa);
+
transform.matrix[0][0] = XDoubleToFixed(1);
transform.matrix[0][1] = XDoubleToFixed(0);
transform.matrix[0][2] = XDoubleToFixed(0);
transform.matrix[2][0] = XDoubleToFixed(0);
transform.matrix[2][1] = XDoubleToFixed(0);
transform.matrix[2][2] = XDoubleToFixed(xfc->settings->ScalingFactor);
+
if ((w != 0) && (h != 0))
{
- if (scale == TRUE)
+ if (scale)
{
xr.x = x * xfc->settings->ScalingFactor;
xr.y = y * xfc->settings->ScalingFactor;
xr.width = w;
xr.height = h;
}
+
XRenderSetPictureClipRectangles(xfc->display, primaryPicture, 0, 0, &xr, 1);
}
+
XRenderSetPictureTransform(xfc->display, primaryPicture, &transform);
XRenderComposite(xfc->display, PictOpSrc, primaryPicture, 0, windowPicture, 0, 0, 0, 0, xfc->offset_x, xfc->offset_y, xfc->currentWidth, xfc->currentHeight);
XRenderFreePicture(xfc->display, primaryPicture);
#endif
}
-void xf_sw_begin_paint(rdpContext *context)
+void xf_sw_begin_paint(rdpContext* context)
{
rdpGdi* gdi = context->gdi;
gdi->primary->hdc->hwnd->invalid->null = 1;
gdi->primary->hdc->hwnd->ninvalid = 0;
}
-void xf_sw_end_paint(rdpContext *context)
+void xf_sw_end_paint(rdpContext* context)
{
int i;
INT32 x, y;
xf_unlock_x11(xfc, TRUE);
}
-void xf_hw_begin_paint(rdpContext *context)
+void xf_hw_begin_paint(rdpContext* context)
{
xfContext* xfc = (xfContext*) context;
xfc->hdc->hwnd->invalid->null = 1;
xfc->hdc->hwnd->ninvalid = 0;
}
-void xf_hw_end_paint(rdpContext *context)
+void xf_hw_end_paint(rdpContext* context)
{
INT32 x, y;
UINT32 w, h;
}
}
-void xf_hw_desktop_resize(rdpContext *context)
+void xf_hw_desktop_resize(rdpContext* context)
{
BOOL same;
- rdpSettings *settings;
- xfContext *xfc = (xfContext *) context;
- settings = xfc->instance->settings;
+ rdpSettings* settings;
+ xfContext* xfc = (xfContext*) context;
+ settings = xfc->settings;
xf_lock_x11(xfc, TRUE);
BOOL xf_get_fds(freerdp *instance, void **rfds, int *rcount, void **wfds, int *wcount)
{
- xfContext *xfc = (xfContext *) instance->context;
+ xfContext* xfc = (xfContext*) instance->context;
rfds[*rcount] = (void *)(long)(xfc->xfds);
(*rcount)++;
return TRUE;
}
-BOOL xf_process_x_events(freerdp *instance)
+BOOL xf_process_x_events(freerdp* instance)
{
BOOL status;
XEvent xevent;
int pending_status;
- xfContext *xfc = (xfContext *) instance->context;
+ xfContext* xfc = (xfContext*) instance->context;
+
status = TRUE;
pending_status = TRUE;
- while(pending_status)
+
+ while (pending_status)
{
xf_lock_x11(xfc, FALSE);
pending_status = XPending(xfc->display);
xf_unlock_x11(xfc, FALSE);
+
if (pending_status)
{
ZeroMemory(&xevent, sizeof(xevent));
XNextEvent(xfc->display, &xevent);
+
status = xf_event_process(instance, &xevent);
+
if (!status)
return status;
}
return status;
}
-void xf_create_window(xfContext *xfc)
+void xf_create_window(xfContext* xfc)
{
XEvent xevent;
int width, height;
- char *windowTitle;
+ char* windowTitle;
+
ZeroMemory(&xevent, sizeof(xevent));
+
width = xfc->width;
height = xfc->height;
+
if (!xfc->remote_app)
{
xfc->attribs.background_pixel = BlackPixelOfScreen(xfc->screen);
xfc->attribs.colormap = xfc->colormap;
xfc->attribs.bit_gravity = NorthWestGravity;
xfc->attribs.win_gravity = NorthWestGravity;
- if (xfc->instance->settings->WindowTitle)
+
+ if (xfc->settings->WindowTitle)
+ {
+ windowTitle = _strdup(xfc->settings->WindowTitle);
+ }
+ else if (xfc->settings->ServerPort == 3389)
{
- windowTitle = _strdup(xfc->instance->settings->WindowTitle);
+ windowTitle = malloc(1 + sizeof("FreeRDP: ") + strlen(xfc->settings->ServerHostname));
+ sprintf(windowTitle, "FreeRDP: %s", xfc->settings->ServerHostname);
}
else
- if (xfc->instance->settings->ServerPort == 3389)
- {
- windowTitle = malloc(1 + sizeof("FreeRDP: ") + strlen(xfc->instance->settings->ServerHostname));
- sprintf(windowTitle, "FreeRDP: %s", xfc->instance->settings->ServerHostname);
- }
- else
- {
- windowTitle = malloc(1 + sizeof("FreeRDP: ") + strlen(xfc->instance->settings->ServerHostname) + sizeof(":00000"));
- sprintf(windowTitle, "FreeRDP: %s:%i", xfc->instance->settings->ServerHostname, xfc->instance->settings->ServerPort);
- }
+ {
+ windowTitle = malloc(1 + sizeof("FreeRDP: ") + strlen(xfc->settings->ServerHostname) + sizeof(":00000"));
+ sprintf(windowTitle, "FreeRDP: %s:%i", xfc->settings->ServerHostname, xfc->settings->ServerPort);
+ }
+
xfc->window = xf_CreateDesktopWindow(xfc, windowTitle, width, height, xfc->settings->Decorations);
+
free(windowTitle);
+
if (xfc->fullscreen)
xf_SetWindowFullscreen(xfc, xfc->window, xfc->fullscreen);
+
xfc->unobscured = (xevent.xvisibility.state == VisibilityUnobscured);
XSetWMProtocols(xfc->display, xfc->window->handle, &(xfc->WM_DELETE_WINDOW), 1);
xfc->drawable = xfc->window->handle;
{
Pixmap contents = 0;
WindowStateChangeEventArgs e;
+
xf_lock_x11(xfc, TRUE);
+
contents = XCreatePixmap(xfc->display, xfc->window->handle, xfc->width, xfc->height, xfc->depth);
+
XCopyArea(xfc->display, xfc->primary, contents, xfc->gc, 0, 0, xfc->width, xfc->height, 0, 0);
XDestroyWindow(xfc->display, xfc->window->handle);
+
xfc->fullscreen = (xfc->fullscreen) ? FALSE : TRUE;
+
xf_create_window(xfc);
+
XCopyArea(xfc->display, contents, xfc->primary, xfc->gc, 0, 0, xfc->width, xfc->height, 0, 0);
XFreePixmap(xfc->display, contents);
+
xf_unlock_x11(xfc, TRUE);
+
EventArgsInit(&e, "xfreerdp");
e.state = xfc->fullscreen ? FREERDP_WINDOW_STATE_FULLSCREEN : 0;
PubSub_OnWindowStateChange(((rdpContext *) xfc)->pubSub, xfc, &e);
int xf_encomsp_participant_created(EncomspClientContext* context, ENCOMSP_PARTICIPANT_CREATED_PDU* participantCreated)
{
-#if 0
- xfContext* xfc = (xfContext*) context->custom;
-
- WLog_INFO(TAG, "ParticipantCreated: ParticipantId: %d GroupId: %d Flags: 0x%04X xfc: %p",
- (int) participantCreated->ParticipantId, (int) participantCreated->GroupId,
- (int) participantCreated->Flags, xfc);
-#endif
-
return 1;
}
xfc->encomsp = NULL;
}
-void xf_lock_x11(xfContext *xfc, BOOL display)
+void xf_lock_x11(xfContext* xfc, BOOL display)
{
if (!xfc->UseXThreads)
{
}
}
-void xf_unlock_x11(xfContext *xfc, BOOL display)
+void xf_unlock_x11(xfContext* xfc, BOOL display)
{
if (!xfc->UseXThreads)
{
}
}
-BOOL xf_get_pixmap_info(xfContext *xfc)
+BOOL xf_get_pixmap_info(xfContext* xfc)
{
int i;
int vi_count;
XPixmapFormatValues *pf;
XPixmapFormatValues *pfs;
XWindowAttributes window_attributes;
+
pfs = XListPixmapFormats(xfc->display, &pf_count);
- if (pfs == NULL)
+ if (!pfs)
{
WLog_ERR(TAG, "XListPixmapFormats failed");
return 1;
vis = XGetVisualInfo(xfc->display, VisualClassMask | VisualScreenMask, &template, &vi_count);
- if (vis == NULL)
+ if (!vis)
{
WLog_ERR(TAG, "XGetVisualInfo failed");
return FALSE;
static int (*_def_error_handler)(Display *, XErrorEvent *);
-int xf_error_handler(Display *d, XErrorEvent *ev)
+int xf_error_handler(Display* d, XErrorEvent* ev)
{
char buf[256];
+
int do_abort = TRUE;
XGetErrorText(d, ev->error_code, buf, sizeof(buf));
- WLog_ERR(TAG, "%s", buf);
+
+ WLog_ERR(TAG, "%s", buf);
+
if (do_abort)
abort();
+
_def_error_handler(d, ev);
+
return FALSE;
}
-int _xf_error_handler(Display *d, XErrorEvent *ev)
+int _xf_error_handler(Display* d, XErrorEvent* ev)
{
/*
* ungrab the keyboard, in case a debugger is running in
return xf_error_handler(d, ev);
}
-static void xf_post_disconnect(freerdp *instance)
+static void xf_post_disconnect(freerdp* instance)
{
- xfContext *xfc = (xfContext *) instance->context;
- assert(NULL != instance);
- assert(NULL != xfc);
- assert(NULL != instance->settings);
+ xfContext* xfc;
+
+ if (!instance || !instance->context || !instance->settings)
+ return;
+
+ xfc = (xfContext*) instance->context;
+
if (xfc->mutex)
{
WaitForSingleObject(xfc->mutex, INFINITE);
CloseHandle(xfc->mutex);
xfc->mutex = NULL;
}
+
xf_monitors_free(xfc, instance->settings);
}
XkbBell(xfc->display, None, 100, 0);
}
-void xf_check_extensions(xfContext *context)
+void xf_check_extensions(xfContext* context)
{
int xkb_opcode, xkb_event, xkb_error;
int xkb_major = XkbMajorVersion;
int xkb_minor = XkbMinorVersion;
+
if (XkbLibraryVersion( &xkb_major, &xkb_minor ) && XkbQueryExtension(context->display, &xkb_opcode, &xkb_event,
&xkb_error, &xkb_major, &xkb_minor))
{
// FIXME: seems this callback may be called when 'username' is not known.
// But it doesn't do anything to fix it...
*password = malloc(password_size * sizeof(char));
+
if (freerdp_passphrase_read("Password: ", *password, password_size, instance->settings->CredentialsFromStdin) == NULL)
return FALSE;
+
return TRUE;
}
* @param fingerprint
* @return TRUE if the certificate is trusted. FALSE otherwise.
*/
-BOOL xf_verify_certificate(freerdp *instance, char *subject, char *issuer, char *fingerprint)
+BOOL xf_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint)
{
char answer;
+
WLog_INFO(TAG, "Certificate details:");
WLog_INFO(TAG, "\tSubject: %s", subject);
WLog_INFO(TAG, "\tIssuer: %s", issuer);
WLog_INFO(TAG, "The above X.509 certificate could not be verified, possibly because you do not have "
"the CA certificate in your certificate store, or the certificate has expired. "
"Please look at the documentation on how to create local certificate store for a private CA.");
- while(1)
+
+ while (1)
{
WLog_INFO(TAG, "Do you trust the above certificate? (Y/N) ");
answer = fgetc(stdin);
+
if (feof(stdin))
{
WLog_INFO(TAG, "Error: Could not read answer from stdin.");
WLog_INFO(TAG, "");
return FALSE;
}
+
if (answer == 'y' || answer == 'Y')
{
return TRUE;
}
- else
- if (answer == 'n' || answer == 'N')
- {
- break;
- }
+ else if (answer == 'n' || answer == 'N')
+ {
+ break;
+ }
+
WLog_INFO(TAG, "");
}
+
return FALSE;
}
-int xf_logon_error_info(freerdp *instance, UINT32 data, UINT32 type)
+int xf_logon_error_info(freerdp* instance, UINT32 data, UINT32 type)
{
- xfContext *xfc = (xfContext *) instance->context;
+ xfContext* xfc = (xfContext*) instance->context;
xf_rail_disable_remoteapp_mode(xfc);
return 1;
}
-void xf_window_free(xfContext *xfc)
+void xf_window_free(xfContext* xfc)
{
rdpContext* context = (rdpContext*) xfc;
if (xfc->window)
{
- xf_DestroyWindow(xfc, xfc->window);
+ xf_DestroyDesktopWindow(xfc, xfc->window);
xfc->window = NULL;
}
context->cache = NULL;
}
- if (context->rail)
- {
- rail_free(context->rail);
- context->rail = NULL;
- }
-
if (xfc->hdc)
{
gdi_DeleteDC(xfc->hdc);
void* xf_input_thread(void *arg)
{
- xfContext *xfc;
+ xfContext* xfc;
HANDLE event;
XEvent xevent;
wMessageQueue *queue;
int pending_status = 1;
int process_status = 1;
- freerdp *instance = (freerdp *) arg;
+ freerdp *instance = (freerdp*) arg;
assert(NULL != instance);
xfc = (xfContext *) instance->context;
assert(NULL != xfc);
if (pending_status)
{
xf_lock_x11(xfc, FALSE);
+
ZeroMemory(&xevent, sizeof(xevent));
XNextEvent(xfc->display, &xevent);
+
process_status = xf_event_process(instance, &xevent);
+
xf_unlock_x11(xfc, FALSE);
if (!process_status)
void* xf_channels_thread(void *arg)
{
int status;
- xfContext *xfc;
+ xfContext* xfc;
HANDLE event;
rdpChannels *channels;
freerdp *instance = (freerdp *) arg;
return NULL;
}
-BOOL xf_auto_reconnect(freerdp *instance)
+BOOL xf_auto_reconnect(freerdp* instance)
{
- xfContext *xfc = (xfContext *) instance->context;
+ xfContext* xfc = (xfContext*) instance->context;
UINT32 num_retries = 0;
UINT32 max_retries = instance->settings->AutoReconnectMaxRetries;
+
/* Only auto reconnect on network disconnects. */
if (freerdp_error_info(instance) != 0)
return FALSE;
+
/* A network disconnect was detected */
WLog_INFO(TAG, "Network disconnect!");
+
if (!instance->settings->AutoReconnectionEnabled)
{
/* No auto-reconnect - just quit */
return FALSE;
}
+
/* Perform an auto-reconnect. */
- for(;;)
+ for (;;)
{
/* Quit retrying if max retries has been exceeded */
if (num_retries++ >= max_retries)
{
return FALSE;
}
+
/* Attempt the next reconnect */
WLog_INFO(TAG, "Attempting reconnect (%u of %u)", num_retries, max_retries);
if (freerdp_reconnect(instance))
}
sleep(5);
}
+
WLog_ERR(TAG, "Maximum reconnect retries exceeded");
+
return FALSE;
}
{
int i;
int fds;
- xfContext *xfc;
+ xfContext* xfc;
int max_fds;
int rcount;
int wcount;
ZeroMemory(wfds, sizeof(wfds));
ZeroMemory(&timeout, sizeof(struct timeval));
status = freerdp_connect(instance);
- xfc = (xfContext *) instance->context;
+ xfc = (xfContext*) instance->context;
assert(NULL != xfc);
+
/* Connection succeeded. --authonly ? */
if (instance->settings->AuthenticationOnly)
{
WLog_ERR(TAG, "Authentication only, exit status %d", !status);
ExitThread(exit_code);
}
+
if (!status)
{
if (xfc->mutex)
CloseHandle(xfc->mutex);
xfc->mutex = NULL;
}
+
xf_monitors_free(xfc, instance->settings);
exit_code = XF_EXIT_CONN_FAILED;
ExitThread(exit_code);
}
+
channels = instance->context->channels;
settings = instance->context->settings;
async_input = settings->AsyncInput;
{
input_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_input_thread, instance, 0, NULL);
}
+
if (async_channels)
{
channels_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) xf_channels_thread, instance, 0, NULL);
}
- while(!xfc->disconnect && !freerdp_shall_disconnect(instance))
+
+ while (!xfc->disconnect && !freerdp_shall_disconnect(instance))
{
rcount = 0;
wcount = 0;
if (reason == 0 || (reason >= XF_EXIT_PARSE_ARGUMENTS && reason <= XF_EXIT_CONN_FAILED))
return reason;
/* License error set */
- else
- if (reason >= 0x100 && reason <= 0x10A)
- reason -= 0x100 + XF_EXIT_LICENSE_INTERNAL;
+ else if (reason >= 0x100 && reason <= 0x10A)
+ reason -= 0x100 + XF_EXIT_LICENSE_INTERNAL;
/* RDP protocol error set */
- else
- if (reason >= 0x10c9 && reason <= 0x1193)
- reason = XF_EXIT_RDP;
+ else if (reason >= 0x10c9 && reason <= 0x1193)
+ reason = XF_EXIT_RDP;
/* There's no need to test protocol-independent codes: they match */
- else
- if (!(reason <= 0xB))
- reason = XF_EXIT_UNKNOWN;
+ else if (!(reason <= 0xB))
+ reason = XF_EXIT_UNKNOWN;
+
return reason;
}
-void xf_TerminateEventHandler(rdpContext *context, TerminateEventArgs *e)
+void xf_TerminateEventHandler(rdpContext* context, TerminateEventArgs* e)
{
- wMessageQueue *queue;
- xfContext *xfc = (xfContext *) context;
+ wMessageQueue* queue;
+
+ xfContext* xfc = (xfContext*) context;
+
if (context->settings->AsyncInput)
{
queue = freerdp_get_message_queue(context->instance, FREERDP_INPUT_MESSAGE_QUEUE);
+
if (queue)
MessageQueue_PostQuit(queue, 0);
}
}
}
-static void xf_ScalingFactorChangeEventHandler(rdpContext *context, ScalingFactorChangeEventArgs *e)
+static void xf_ScalingFactorChangeEventHandler(rdpContext* context, ScalingFactorChangeEventArgs* e)
{
xfContext* xfc = (xfContext*) context;
}
-static int xfreerdp_client_start(rdpContext *context)
+static int xfreerdp_client_start(rdpContext* context)
{
xfContext* xfc = (xfContext *) context;
rdpSettings* settings = context->settings;
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <freerdp/locale/keyboard.h>
#include <freerdp/log.h>
+#include <freerdp/locale/keyboard.h>
#include "xf_rail.h"
#include "xf_window.h"
}
else
{
- xfWindow* xfw;
rdpWindow* window;
+ xfAppWindow* appWindow;
rdpRail* rail = ((rdpContext*) xfc)->rail;
window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window);
if (window)
{
- xfw = (xfWindow*) window->extra;
- xf_UpdateWindowArea(xfc, xfw, x, y, w, h);
+ appWindow = (xfAppWindow*) window->extra;
+ xf_UpdateWindowArea(xfc, appWindow, x, y, w, h);
}
}
input->MouseEvent(input, PTR_FLAGS_MOVE, x, y);
- if (xfc->fullscreen)
+ if (xfc->fullscreen && !app)
{
XSetInputFocus(xfc->display, xfc->window->handle, RevertToPointerRoot, CurrentTime);
}
xfc->focused = TRUE;
- if (xfc->mouse_active && (!app))
+ if (xfc->mouse_active && !app)
XGrabKeyboard(xfc->display, xfc->window->handle, TRUE, GrabModeAsync, GrabModeAsync, CurrentTime);
if (app)
{
- xf_rail_send_activate(xfc, event->xany.window, TRUE);
-
- rdpWindow* window;
- rdpRail* rail = ((rdpContext*) xfc)->rail;
-
- window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window);
-
- /* Update the server with any window changes that occurred while the window was not focused. */
- if (window)
- xf_rail_adjust_position(xfc, window);
+ 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);
+
+ /* Update the server with any window changes that occurred while the window was not focused. */
+ if (window)
+ {
+ appWindow = (xfAppWindow*) window->extra;
+ xf_rail_adjust_position(xfc, appWindow);
+ }
}
xf_keyboard_focus_in(xfc);
{
/* keep track of which window has focus so that we can apply pointer updates */
- xfWindow* xfw;
rdpWindow* window;
+ xfAppWindow* appWindow;
rdpRail* rail = ((rdpContext*) xfc)->rail;
+
window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window);
if (window)
{
- xfw = (xfWindow*) window->extra;
- xfc->window = xfw;
+ appWindow = (xfAppWindow*) window->extra;
+ xfc->appWindow = appWindow;
}
}
static BOOL xf_event_ConfigureNotify(xfContext* xfc, XEvent* event, BOOL app)
{
- rdpWindow* window;
- rdpRail* rail = ((rdpContext*) xfc)->rail;
+ rdpWindow* window;
+ rdpRail* rail = ((rdpContext*) xfc)->rail;
- if (!xfc->remote_app || !rail)
- return TRUE;
+ if (!app || !rail)
+ return TRUE;
- window = window_list_get_by_extra_id(rail->list, (void*) event->xconfigure.window);
+ window = window_list_get_by_extra_id(rail->list, (void*) event->xconfigure.window);
- if (window)
- {
- xfWindow* xfw;
- Window childWindow;
- xfw = (xfWindow*) window->extra;
+ if (window)
+ {
+ Window childWindow;
+ xfAppWindow* appWindow;
- /*
- * ConfigureNotify coordinates are expressed relative to the window parent.
- * Translate these to root window coordinates.
- */
+ appWindow = (xfAppWindow*) window->extra;
- XTranslateCoordinates(xfc->display, xfw->handle,
- RootWindowOfScreen(xfc->screen),
- 0, 0, &xfw->left, &xfw->top, &childWindow);
+ /*
+ * ConfigureNotify coordinates are expressed relative to the window parent.
+ * Translate these to root window coordinates.
+ */
+
+ XTranslateCoordinates(xfc->display, appWindow->handle,
+ RootWindowOfScreen(xfc->screen),
+ 0, 0, &appWindow->x, &appWindow->y, &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;
+ appWindow->width = event->xconfigure.width;
+ appWindow->height = event->xconfigure.height;
/*
- * Additonal checks for not in a local move and not ignoring configure to send
+ * Additional 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
- * send to server yet(ie. resizing using window decoration).
+ * send to server yet (i.e. resizing using window decoration).
* The server will be updated when the window gets refocused.
*/
- if (app && xfw->decorations)
+ if (appWindow->decorations)
{
/* moving resizing using window decoration */
- xf_rail_adjust_position(xfc, window);
- window->windowOffsetX = xfw->left;
+
+ xf_rail_adjust_position(xfc, appWindow);
+
+ window->windowOffsetX = appWindow->x;
window->visibleOffsetX = window->windowOffsetX;
- window->windowOffsetY = xfw->top;
+ window->windowOffsetY = appWindow->y;
window->visibleOffsetY = window->windowOffsetY;
- window->windowWidth = xfw->width;
- window->windowHeight = xfw->height;
+ window->windowWidth = appWindow->width;
+ window->windowHeight = appWindow->height;
}
else
{
- if (app && (!event->xconfigure.send_event || xfc->window->local_move.state == LMS_NOT_ACTIVE)
- && !xfw->rail_ignore_configure && xfc->focused)
- xf_rail_adjust_position(xfc, window);
+ if ((!event->xconfigure.send_event || appWindow->local_move.state == LMS_NOT_ACTIVE)
+ && !appWindow->rail_ignore_configure && xfc->focused)
+ xf_rail_adjust_position(xfc, appWindow);
}
- }
+ }
- return TRUE;
+ return TRUE;
}
static BOOL xf_event_MapNotify(xfContext* xfc, XEvent* event, BOOL app)
*/
//xf_rail_send_client_system_command(xfc, window->windowId, SC_RESTORE);
- xfWindow* xfw = (xfWindow*) window->extra;
- xfw->is_mapped = TRUE;
+ xfAppWindow* appWindow = (xfAppWindow*) window->extra;
+ appWindow->is_mapped = TRUE;
}
}
if (window)
{
- xfWindow* xfw = (xfWindow*) window->extra;
- xfw->is_mapped = FALSE;
+ xfAppWindow* appWindow = (xfAppWindow*) window->extra;
+ appWindow->is_mapped = FALSE;
}
}
if (app)
{
rdpWindow* window;
+ xfAppWindow* appWindow;
window = xf_rdpWindowFromWindow(xfc, event->xproperty.window);
if (!window)
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)))
}
- if (maxVert && maxHorz && !minimized && (xfc->window->rail_state != WINDOW_SHOW_MAXIMIZED))
+ if (maxVert && maxHorz && !minimized && (appWindow->rail_state != WINDOW_SHOW_MAXIMIZED))
{
- xfc->window->rail_state = WINDOW_SHOW_MAXIMIZED;
+ appWindow->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))
+ else if (minimized && (appWindow->rail_state != WINDOW_SHOW_MINIMIZED))
{
- xfc->window->rail_state = WINDOW_SHOW_MINIMIZED;
+ appWindow->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))
+ else if (!minimized && !maxVert && !maxHorz && (appWindow->rail_state != WINDOW_SHOW))
{
- xfc->window->rail_state = WINDOW_SHOW;
+ appWindow->rail_state = WINDOW_SHOW;
xf_rail_send_client_system_command(xfc, window->windowId, SC_RESTORE);
}
}
return TRUE;
}
-static BOOL xf_event_suppress_events(xfContext* xfc, rdpWindow* window, XEvent*event)
+static BOOL xf_event_suppress_events(xfContext* xfc, xfAppWindow* appWindow, XEvent* event)
{
if (!xfc->remote_app)
return FALSE;
- switch (xfc->window->local_move.state)
+ switch (appWindow->local_move.state)
{
case LMS_NOT_ACTIVE:
/* No local move in progress, nothing to do */
/* Prevent Configure from happening during indeterminant state of Horz or Vert Max only */
- if ( (event->type == ConfigureNotify) && xfc->window->rail_ignore_configure)
+ if ((event->type == ConfigureNotify) && appWindow->rail_ignore_configure)
{
- xfc->window->rail_ignore_configure = FALSE;
+ appWindow->rail_ignore_configure = FALSE;
return TRUE;
}
case LMS_STARTING:
/* Local move initiated by RDP server, but we have not yet seen any updates from the X server */
- switch(event->type)
+ switch (event->type)
{
case ConfigureNotify:
/* Starting to see move events from the X server. Local move is now in progress. */
- xfc->window->local_move.state = LMS_ACTIVE;
+ appWindow->local_move.state = LMS_ACTIVE;
/* Allow these events to be processed during move to keep our state up to date. */
break;
case LMS_ACTIVE:
/* Local move is in progress */
- switch(event->type)
+ switch (event->type)
{
case ConfigureNotify:
case VisibilityNotify:
break;
default:
/* Any other event terminates move */
- xf_rail_end_local_move(xfc, window);
+ xf_rail_end_local_move(xfc, appWindow);
break;
}
break;
if (window)
{
/* Update "current" window for cursor change orders */
- xfc->window = (xfWindow*) window->extra;
+ xfc->appWindow = (xfAppWindow*) window->extra;
- if (xf_event_suppress_events(xfc, window, event))
+ if (xf_event_suppress_events(xfc, xfc->appWindow, event))
return TRUE;
}
}
case MotionNotify:
status = xf_event_MotionNotify(xfc, event, xfc->remote_app);
break;
+
case ButtonPress:
status = xf_event_ButtonPress(xfc, event, xfc->remote_app);
break;
return FALSE;
keysymMask = xf_keyboard_get_keymask(xfc, keysym);
+
if (!keysymMask)
{
return FALSE;
}
+
return XkbLockModifiers(xfc->display, XkbUseCoreKbd, keysymMask, on ? keysymMask : 0);
}
{
input = xfc->instance->input;
syncFlags = xf_keyboard_get_toggle_keys_state(xfc);
- XQueryPointer(xfc->display, xfc->window->handle, &wdummy, &wdummy, &mouseX, &mouseY, &dummy, &dummy, &state);
+
+ if (!xfc->remote_app)
+ {
+ XQueryPointer(xfc->display, xfc->window->handle, &wdummy, &wdummy,
+ &mouseX, &mouseY, &dummy, &dummy, &state);
+ }
+ else
+ {
+ XQueryPointer(xfc->display, DefaultRootWindow(xfc->display),
+ &wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
+ }
+
input->FocusInEvent(input, syncFlags, mouseX, mouseY);
}
}
{
xfc->remote_app = TRUE;
xfc->drawable = DefaultRootWindow(xfc->display);
- xf_DestroyWindow(xfc, xfc->window);
+ xf_DestroyDesktopWindow(xfc, xfc->window);
xfc->window = NULL;
}
}
{
int index;
int count;
- xfWindow* xfw = NULL;
RECTANGLE_16 updateRect;
RECTANGLE_16 windowRect;
ULONG_PTR* pKeys = NULL;
- xfRailWindow* railWindow;
+ xfAppWindow* appWindow;
const RECTANGLE_16* extents;
REGION16 windowInvalidRegion;
for (index = 0; index < count; index++)
{
- railWindow = (xfRailWindow*) HashTable_GetItemValue(xfc->railWindows, (void*) pKeys[index]);
+ appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, (void*) pKeys[index]);
- if (railWindow)
+ if (appWindow)
{
- windowRect.left = railWindow->x;
- windowRect.top = railWindow->y;
- windowRect.right = railWindow->x + railWindow->width;
- windowRect.bottom = railWindow->y + railWindow->height;
+ windowRect.left = appWindow->x;
+ windowRect.top = appWindow->y;
+ windowRect.right = appWindow->x + appWindow->width;
+ windowRect.bottom = appWindow->y + appWindow->height;
region16_clear(&windowInvalidRegion);
region16_intersect_rect(&windowInvalidRegion, invalidRegion, &windowRect);
{
extents = region16_extents(&windowInvalidRegion);
- updateRect.left = extents->left - railWindow->x;
- updateRect.top = extents->top - railWindow->y;
- updateRect.right = extents->right - railWindow->x;
- updateRect.bottom = extents->bottom - railWindow->y;
+ updateRect.left = extents->left - appWindow->x;
+ updateRect.top = extents->top - appWindow->y;
+ updateRect.right = extents->right - appWindow->x;
+ updateRect.bottom = extents->bottom - appWindow->y;
- if (xfw)
+ if (appWindow)
{
- xf_UpdateWindowArea(xfc, xfw, updateRect.left, updateRect.top,
+ xf_UpdateWindowArea(xfc, appWindow, updateRect.left, updateRect.top,
updateRect.right - updateRect.left,
updateRect.bottom - updateRect.top);
}
void xf_rail_paint(xfContext* xfc, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom)
{
rdpRail* rail;
- xfWindow* xfw;
rdpWindow* window;
+ xfAppWindow* appWindow;
BOOL intersect;
UINT32 iwidth, iheight;
INT32 ileft, itop;
while (window_list_has_next(rail->list))
{
window = window_list_get_next(rail->list);
- xfw = (xfWindow*) window->extra;
+ appWindow = (xfAppWindow*) window->extra;
/* RDP can have zero width or height windows. X cannot, so we ignore these. */
if (intersect)
{
- xf_UpdateWindowArea(xfc, xfw, ileft - wleft, itop - wtop, iwidth, iheight);
+ xf_UpdateWindowArea(xfc, appWindow, ileft - wleft, itop - wtop, iwidth, iheight);
}
}
}
static void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window)
{
xfContext* xfc;
- xfWindow* xfw;
+ xfAppWindow* appWindow;
+
xfc = (xfContext*) rail->extra;
xf_rail_enable_remoteapp_mode(xfc);
- xfw = xf_CreateWindow(xfc, window, window->windowOffsetX, window->windowOffsetY,
+ appWindow = xf_CreateWindow(xfc, window, window->windowOffsetX, window->windowOffsetY,
window->windowWidth, window->windowHeight, window->windowId);
- xf_SetWindowStyle(xfc, xfw, window->style, window->extendedStyle);
- xf_SetWindowText(xfc, xfw, window->title);
- window->extra = (void*) xfw;
- window->extraId = (void*) xfw->handle;
+ xf_SetWindowStyle(xfc, appWindow, window->style, window->extendedStyle);
+ xf_SetWindowText(xfc, appWindow, window->title);
+
+ window->extra = (void*) appWindow;
+ window->extraId = (void*) appWindow->handle;
}
static void xf_rail_MoveWindow(rdpRail* rail, rdpWindow* window)
{
xfContext* xfc;
- xfWindow* xfw;
+ xfAppWindow* appWindow;
+
xfc = (xfContext*) rail->extra;
- xfw = (xfWindow*) window->extra;
+ appWindow = (xfAppWindow*) window->extra;
/*
* 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 (xfw->rail_state == WINDOW_SHOW_MINIMIZED)
+ if (appWindow->rail_state == WINDOW_SHOW_MINIMIZED)
return;
/* Do nothing if window is already in the correct position */
- if (xfw->left == window->visibleOffsetX &&
- xfw->top == window->visibleOffsetY &&
- xfw->width == window->windowWidth &&
- xfw->height == window->windowHeight)
+ if (appWindow->x == window->visibleOffsetX &&
+ appWindow->y == window->visibleOffsetY &&
+ appWindow->width == window->windowWidth &&
+ appWindow->height == window->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, xfw, 0, 0, window->windowWidth, window->windowHeight);
+ xf_UpdateWindowArea(xfc, appWindow, 0, 0, window->windowWidth, window->windowHeight);
return;
}
- xf_MoveWindow(xfc, xfw, window->visibleOffsetX, window->visibleOffsetY,
+ xf_MoveWindow(xfc, appWindow, window->visibleOffsetX, window->visibleOffsetY,
window->windowWidth, window->windowHeight);
}
static void xf_rail_ShowWindow(rdpRail* rail, rdpWindow* window, BYTE state)
{
xfContext* xfc;
- xfWindow* xfw;
+ xfAppWindow* appWindow;
+
xfc = (xfContext*) rail->extra;
- xfw = (xfWindow*) window->extra;
- xf_ShowWindow(xfc, xfw, state);
+ appWindow = (xfAppWindow*) window->extra;
+
+ xf_ShowWindow(xfc, appWindow, state);
}
static void xf_rail_SetWindowText(rdpRail* rail, rdpWindow* window)
{
xfContext* xfc;
- xfWindow* xfw;
+ xfAppWindow* appWindow;
+
xfc = (xfContext*) rail->extra;
- xfw = (xfWindow*) window->extra;
- xf_SetWindowText(xfc, xfw, window->title);
+ appWindow = (xfAppWindow*) window->extra;
+
+ xf_SetWindowText(xfc, appWindow, window->title);
}
static void xf_rail_SetWindowIcon(rdpRail* rail, rdpWindow* window, rdpIcon* icon)
{
xfContext* xfc;
- xfWindow* xfw;
+ xfAppWindow* appWindow;
+
xfc = (xfContext*) rail->extra;
- xfw = (xfWindow*) window->extra;
+ appWindow = (xfAppWindow*) window->extra;
icon->extra = freerdp_icon_convert(icon->entry->bitsColor, NULL, icon->entry->bitsMask,
icon->entry->width, icon->entry->height, icon->entry->bpp, rail->clrconv);
- xf_SetWindowIcon(xfc, xfw, icon);
+ xf_SetWindowIcon(xfc, appWindow, icon);
}
static void xf_rail_SetWindowRects(rdpRail* rail, rdpWindow* window)
{
xfContext* xfc;
- xfWindow* xfw;
+ xfAppWindow* appWindow;
+
xfc = (xfContext*) rail->extra;
- xfw = (xfWindow*) window->extra;
+ appWindow = (xfAppWindow*) window->extra;
- xf_SetWindowRects(xfc, xfw, window->windowRects, window->numWindowRects);
+ xf_SetWindowRects(xfc, appWindow, window->windowRects, window->numWindowRects);
}
static void xf_rail_SetWindowVisibilityRects(rdpRail* rail, rdpWindow* window)
{
- xfWindow* xfw;
xfContext* xfc;
+ xfAppWindow* appWindow;
+
xfc = (xfContext*) rail->extra;
- xfw = (xfWindow*) window->extra;
- xf_SetWindowVisibilityRects(xfc, xfw, window->windowRects, window->numWindowRects);
+ appWindow = (xfAppWindow*) window->extra;
+
+ xf_SetWindowVisibilityRects(xfc, appWindow, window->windowRects, window->numWindowRects);
}
static void xf_rail_DestroyWindow(rdpRail* rail, rdpWindow* window)
{
- xfWindow* xfw;
xfContext* xfc;
+ xfAppWindow* appWindow;
+
xfc = (xfContext*) rail->extra;
- xfw = (xfWindow*) window->extra;
- xf_DestroyWindow(xfc, xfw);
+ appWindow = (xfAppWindow*) window->extra;
+
+ xf_DestroyWindow(xfc, appWindow);
}
void xf_rail_DesktopNonMonitored(rdpRail* rail, rdpWindow* window)
{
- xfContext* xfc;
- xfc = (xfContext*) rail->extra;
+ xfContext* xfc = (xfContext*) rail->extra;
xf_rail_disable_remoteapp_mode(xfc);
}
* 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)
+void xf_rail_adjust_position(xfContext* xfc, xfAppWindow* appWindow)
{
- xfWindow* xfw;
+ rdpWindow* window;
RAIL_WINDOW_MOVE_ORDER windowMove;
- xfw = (xfWindow*) window->extra;
+ window = appWindow->window;
- if (! xfw->is_mapped || xfw->local_move.state != LMS_NOT_ACTIVE)
+ 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 (xfw->left != window->visibleOffsetX ||
- xfw->top != window->visibleOffsetY ||
- xfw->width != window->windowWidth ||
- xfw->height != window->windowHeight)
+ 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,
* 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 + (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;
+ 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, rdpWindow* window)
+void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow)
{
int x, y;
int child_x;
int child_y;
- xfWindow* xfw;
+ rdpWindow* window;
unsigned int mask;
Window root_window;
Window child_window;
- RAIL_WINDOW_MOVE_ORDER window_move;
+ RAIL_WINDOW_MOVE_ORDER windowMove;
rdpInput* input = xfc->instance->input;
- xfw = (xfWindow*) window->extra;
+ window = appWindow->window;
/*
* Although the rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY,
/*
* For keyboard moves send and explicit update to RDP server
*/
- 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; /* In the update to RDP the position is one past the window */
- window_move.bottom = window_move.top + xfw->height;
+ 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, &window_move);
+ xfc->rail->ClientWindowMove(xfc->rail, &windowMove);
/*
* 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);
+ 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 ((xfw->local_move.direction != _NET_WM_MOVERESIZE_MOVE_KEYBOARD) &&
- (xfw->local_move.direction != _NET_WM_MOVERESIZE_SIZE_KEYBOARD))
+ 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);
}
* 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;
+ 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
static void xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState)
{
- xfRailWindow* railWindow = NULL;
+ xfAppWindow* railWindow = NULL;
xfContext* xfc = (xfContext*) context;
UINT32 fieldFlags = orderInfo->fieldFlags;
if (fieldFlags & WINDOW_ORDER_STATE_NEW)
{
- railWindow = (xfRailWindow*) calloc(1, sizeof(xfRailWindow));
+ railWindow = (xfAppWindow*) calloc(1, sizeof(xfAppWindow));
if (!railWindow)
return;
}
else
{
- railWindow = (xfRailWindow*) HashTable_GetItemValue(xfc->railWindows,
+ railWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
(void*) (UINT_PTR) orderInfo->windowId);
}
static void xf_rail_window_delete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo)
{
- xfRailWindow* railWindow = NULL;
+ xfAppWindow* railWindow = NULL;
xfContext* xfc = (xfContext*) context;
- railWindow = (xfRailWindow*) HashTable_GetItemValue(xfc->railWindows,
+ railWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
(void*) (UINT_PTR) orderInfo->windowId);
if (!railWindow)
static void xf_rail_window_icon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* windowIcon)
{
BOOL bigIcon;
- xfRailWindow* railWindow;
+ xfAppWindow* railWindow;
xfContext* xfc = (xfContext*) context;
- railWindow = (xfRailWindow*) HashTable_GetItemValue(xfc->railWindows,
+ railWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
(void*) (UINT_PTR) orderInfo->windowId);
if (!railWindow)
static int xf_rail_server_local_move_size(RailClientContext* context, RAIL_LOCALMOVESIZE_ORDER* localMoveSize)
{
rdpRail* rail;
- xfWindow* window;
int x = 0, y = 0;
int direction = 0;
Window child_window;
rdpWindow* rail_window;
+ xfAppWindow* appWindow;
xfContext* xfc = (xfContext*) context->custom;
rail = ((rdpContext*) xfc)->rail;
if (!rail_window)
return -1;
- window = (xfWindow*) rail_window->extra;
+ appWindow = (xfAppWindow*) rail_window->extra;
switch (localMoveSize->moveSizeType)
{
case RAIL_WMSZ_MOVE:
direction = _NET_WM_MOVERESIZE_MOVE;
- XTranslateCoordinates(xfc->display, window->handle,
+ XTranslateCoordinates(xfc->display, appWindow->handle,
RootWindowOfScreen(xfc->screen),
localMoveSize->posX, localMoveSize->posY, &x, &y, &child_window);
break;
if (localMoveSize->isMoveSizeStart)
{
- xf_StartLocalMoveSize(xfc, window, direction, x, y);
+ xf_StartLocalMoveSize(xfc, appWindow, direction, x, y);
}
else
{
- xf_EndLocalMoveSize(xfc, window);
+ xf_EndLocalMoveSize(xfc, appWindow);
}
return 1;
static int xf_rail_server_min_max_info(RailClientContext* context, RAIL_MINMAXINFO_ORDER* minMaxInfo)
{
rdpRail* rail;
- xfWindow* window;
+ xfAppWindow* appWindow;
rdpWindow* rail_window;
xfContext* xfc = (xfContext*) context->custom;
if (!rail_window)
return -1;
- window = (xfWindow*) rail_window->extra;
+ appWindow = (xfAppWindow*) rail_window->extra;
- xf_SetWindowMinMaxInfo(xfc, window,
+ xf_SetWindowMinMaxInfo(xfc, appWindow,
minMaxInfo->maxWidth, minMaxInfo->maxHeight,
minMaxInfo->maxPosX, minMaxInfo->maxPosY,
minMaxInfo->minTrackWidth, minMaxInfo->minTrackHeight,
#include "xf_client.h"
#include "xfreerdp.h"
-struct xf_rail_window
-{
- xfContext* xfc;
-
- UINT32 id;
- DWORD dwStyle;
- DWORD dwExStyle;
-
- int x;
- int y;
- 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;
-
#include <freerdp/client/rail.h>
void xf_rail_paint(xfContext* xfc, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom);
void xf_rail_send_client_system_command(xfContext* xfc, UINT32 windowId, UINT16 command);
void xf_rail_send_activate(xfContext* xfc, Window xwindow, BOOL enabled);
-void xf_rail_adjust_position(xfContext* xfc, rdpWindow* window);
-void xf_rail_end_local_move(xfContext* xfc, rdpWindow* window);
+void xf_rail_adjust_position(xfContext* xfc, xfAppWindow* appWindow);
+void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow);
void xf_rail_enable_remoteapp_mode(xfContext* xfc);
void xf_rail_disable_remoteapp_mode(xfContext* xfc);
#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
-
#include "FreeRDP_Icon_256px.h"
#define xf_icon_prop FreeRDP_Icon_256px_prop
XA_ATOM, 32, PropModeReplace, (BYTE*) &window_state, 2);
}
-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))
- {
- /*
- * Tooltips and menu items should be unmanaged windows
- * (called "override redirect" in X windows parlance)
- * If they are managed, there are issues with window focus that
- * cause the windows to behave improperly. For example, a mouse
- * press will dismiss a drop-down menu because the RDP server
- * sees that as a focus out event from the window owning the
- * dropdown.
- */
- XSetWindowAttributes attrs;
- attrs.override_redirect = True;
- XChangeWindowAttributes(xfc->display, window->handle, CWOverrideRedirect, &attrs);
- window->is_transient = TRUE;
- xf_SetWindowUnlisted(xfc, window->handle);
- window_type = xfc->_NET_WM_WINDOW_TYPE_POPUP;
- }
- /*
- * TOPMOST window that is not a toolwindow is treated like a regular window(ie. task manager).
- * Want to do this here, since the window may have type WS_POPUP
- */
- else if (ex_style & WS_EX_TOPMOST)
- {
- window_type = xfc->_NET_WM_WINDOW_TYPE_NORMAL;
- }
- else if (style & WS_POPUP)
- {
- /* 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->handle);
- }
- else
- {
- XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_WINDOW_TYPE,
- XA_ATOM, 32, PropModeReplace, (BYTE*) &window_type, 1);
- }
-}
-
-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, Window window, pid_t pid)
{
Atom am_wm_pid;
am_wm_pid = XInternAtom(xfc->display, "_NET_WM_PID", False);
- XChangeProperty(xfc->display, window->handle, am_wm_pid, XA_CARDINAL,
+ XChangeProperty(xfc->display, window, am_wm_pid, XA_CARDINAL,
32, PropModeReplace, (BYTE*) &pid, 1);
}
static const char* get_shm_id()
{
static char shm_id[64];
- snprintf(shm_id, sizeof(shm_id), "com.freerdp.xfreerpd.tsmf_%016X", GetCurrentProcessId());
+ snprintf(shm_id, sizeof(shm_id), "com.freerdp.xfreerdp.tsmf_%016X", GetCurrentProcessId());
return shm_id;
}
window->height = height;
window->fullscreen = FALSE;
window->decorations = decorations;
- window->local_move.state = LMS_NOT_ACTIVE;
window->is_mapped = FALSE;
window->is_transient = FALSE;
xf_ResizeDesktopWindow(xfc, window, width, height);
xf_SetWindowDecorations(xfc, window->handle, decorations);
- xf_SetWindowPID(xfc, window, 0);
+ xf_SetWindowPID(xfc, window->handle, 0);
input_mask =
KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
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).
+ * 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->settings->RemoteApplicationMode)
}
}
+void xf_DestroyDesktopWindow(xfContext* xfc, xfWindow* window)
+{
+ if (!window)
+ return;
+
+ if (xfc->window == window)
+ xfc->window = NULL;
+
+ if (window->gc)
+ XFreeGC(xfc->display, window->gc);
+
+ if (window->handle)
+ {
+ XUnmapWindow(xfc->display, window->handle);
+ XDestroyWindow(xfc->display, window->handle);
+ }
+
+ if (window->xfwin)
+ munmap(0, sizeof(*window->xfwin));
+
+ if (window->shmid >= 0)
+ close(window->shmid);
+
+ shm_unlink(get_shm_id());
+
+ window->xfwin = (Window*) -1;
+ window->shmid = -1;
+
+ free(window);
+}
+
+void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UINT32 ex_style)
+{
+ Atom window_type;
+
+ if (/*(ex_style & WS_EX_TOPMOST) ||*/ (ex_style & WS_EX_TOOLWINDOW))
+ {
+ /*
+ * Tooltips and menu items should be unmanaged windows
+ * (called "override redirect" in X windows parlance)
+ * If they are managed, there are issues with window focus that
+ * cause the windows to behave improperly. For example, a mouse
+ * press will dismiss a drop-down menu because the RDP server
+ * sees that as a focus out event from the window owning the
+ * dropdown.
+ */
+ XSetWindowAttributes attrs;
+ attrs.override_redirect = True;
+ XChangeWindowAttributes(xfc->display, appWindow->handle, CWOverrideRedirect, &attrs);
+ appWindow->is_transient = TRUE;
+ xf_SetWindowUnlisted(xfc, appWindow->handle);
+ window_type = xfc->_NET_WM_WINDOW_TYPE_POPUP;
+ }
+ /*
+ * TOPMOST window that is not a tool window is treated like a regular window (i.e. task manager).
+ * Want to do this here, since the window may have type WS_POPUP
+ */
+ else if (ex_style & WS_EX_TOPMOST)
+ {
+ window_type = xfc->_NET_WM_WINDOW_TYPE_NORMAL;
+ }
+ else if (style & WS_POPUP)
+ {
+ /* this includes dialogs, popups, etc, that need to be full-fledged windows */
+ appWindow->is_transient = TRUE;
+ window_type = xfc->_NET_WM_WINDOW_TYPE_DIALOG;
+
+ xf_SetWindowUnlisted(xfc, appWindow->handle);
+ }
+ else
+ {
+ XChangeProperty(xfc->display, appWindow->handle, xfc->_NET_WM_WINDOW_TYPE,
+ XA_ATOM, 32, PropModeReplace, (BYTE*) &window_type, 1);
+ }
+}
+
+void xf_SetWindowText(xfContext* xfc, xfAppWindow* appWindow, char* name)
+{
+ XStoreName(xfc->display, appWindow->handle, name);
+}
+
void xf_FixWindowCoordinates(xfContext* xfc, int* x, int* y, int* width, int* height)
{
int vscreen_width;
}
}
-char rail_window_class[] = "RAIL:00000000";
-
-xfWindow* xf_CreateWindow(xfContext* xfc, rdpWindow* wnd, int x, int y, int width, int height, UINT32 id)
+xfAppWindow* xf_CreateWindow(xfContext* xfc, rdpWindow* wnd, int x, int y, int width, int height, UINT32 id)
{
XGCValues gcv;
int input_mask;
- xfWindow* window;
+ xfAppWindow* appWindow;
XWMHints* InputModeHint;
XClassHint* class_hints;
- window = (xfWindow*) calloc(1, sizeof(xfWindow));
+ appWindow = (xfAppWindow*) calloc(1, sizeof(xfAppWindow));
+
+ if (!appWindow)
+ return NULL;
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;
+ 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
*/
- window->decorations = (wnd->extendedStyle & WS_EX_DECORATIONS) ? TRUE : FALSE;
- window->fullscreen = FALSE;
- window->window = wnd;
- window->local_move.state = LMS_NOT_ACTIVE;
- window->is_mapped = FALSE;
- 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,
+ appWindow->decorations = (wnd->extendedStyle & WS_EX_DECORATIONS) ? TRUE : FALSE;
+ appWindow->fullscreen = FALSE;
+ appWindow->window = wnd;
+ appWindow->local_move.state = LMS_NOT_ACTIVE;
+ appWindow->is_mapped = FALSE;
+ appWindow->is_transient = FALSE;
+ appWindow->rail_state = 0;
+ 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);
+ if (!appWindow->handle)
+ return NULL;
+
ZeroMemory(&gcv, sizeof(gcv));
- window->gc = XCreateGC(xfc->display, window->handle, GCGraphicsExposures, &gcv);
+ appWindow->gc = XCreateGC(xfc->display, appWindow->handle, GCGraphicsExposures, &gcv);
class_hints = XAllocClassHint();
}
else
{
- class = malloc(sizeof(rail_window_class));
- snprintf(class, sizeof(rail_window_class), "RAIL:%08X", id);
+ class = malloc(sizeof("RAIL:00000000"));
+ snprintf(class, sizeof("RAIL:00000000"), "RAIL:%08X", id);
class_hints->res_class = class;
}
class_hints->res_name = "RAIL";
- XSetClassHint(xfc->display, window->handle, class_hints);
+ XSetClassHint(xfc->display, appWindow->handle, class_hints);
XFree(class_hints);
if (class)
InputModeHint->flags = (1L << 0);
InputModeHint->input = True;
- XSetWMHints(xfc->display, window->handle, InputModeHint);
+ XSetWMHints(xfc->display, appWindow->handle, InputModeHint);
XFree(InputModeHint);
- XSetWMProtocols(xfc->display, window->handle, &(xfc->WM_DELETE_WINDOW), 1);
+ XSetWMProtocols(xfc->display, appWindow->handle, &(xfc->WM_DELETE_WINDOW), 1);
input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask |
ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
SubstructureRedirectMask | FocusChangeMask | PropertyChangeMask |
ColormapChangeMask | OwnerGrabButtonMask;
- XSelectInput(xfc->display, window->handle, input_mask);
+ XSelectInput(xfc->display, appWindow->handle, input_mask);
- 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);
+ xf_SetWindowDecorations(xfc, appWindow->handle, appWindow->decorations);
+ xf_SetWindowStyle(xfc, appWindow, wnd->style, wnd->extendedStyle);
+ xf_SetWindowPID(xfc, appWindow->handle, 0);
+ xf_ShowWindow(xfc, appWindow, WINDOW_SHOW);
- XClearWindow(xfc->display, window->handle);
- XMapWindow(xfc->display, window->handle);
+ XClearWindow(xfc->display, appWindow->handle);
+ XMapWindow(xfc->display, appWindow->handle);
/* Move doesn't seem to work until window is mapped. */
- xf_MoveWindow(xfc, window, x, y, width, height);
+ xf_MoveWindow(xfc, appWindow, x, y, width, height);
- return window;
+ return appWindow;
}
-void xf_SetWindowMinMaxInfo(xfContext* xfc, xfWindow* window,
+void xf_SetWindowMinMaxInfo(xfContext* xfc, xfAppWindow* appWindow,
int maxWidth, int maxHeight, int maxPosX, int maxPosY,
int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight)
{
size_hints->max_height = maxTrackHeight;
/* to speedup window drawing we need to select optimal value for sizing step. */
size_hints->width_inc = size_hints->height_inc = 1;
- XSetWMNormalHints(xfc->display, window->handle, size_hints);
+ XSetWMNormalHints(xfc->display, appWindow->handle, size_hints);
XFree(size_hints);
}
}
-void xf_StartLocalMoveSize(xfContext* xfc, xfWindow* window, int direction, int x, int y)
+void xf_StartLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow, int direction, int x, int y)
{
- if (window->local_move.state != LMS_NOT_ACTIVE)
+ if (appWindow->local_move.state != LMS_NOT_ACTIVE)
return;
/*
* Save original mouse location relative to root. This will be needed
* to end local move to RDP server and/or X server
*/
- window->local_move.root_x = x;
- window->local_move.root_y = y;
- window->local_move.state = LMS_STARTING;
- window->local_move.direction = direction;
+ appWindow->local_move.root_x = x;
+ appWindow->local_move.root_y = y;
+ appWindow->local_move.state = LMS_STARTING;
+ appWindow->local_move.direction = direction;
XUngrabPointer(xfc->display, CurrentTime);
- xf_SendClientEvent(xfc, window->handle,
+ xf_SendClientEvent(xfc, appWindow->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 */
1); /* 1 == application request per extended ICCM */
}
-void xf_EndLocalMoveSize(xfContext* xfc, xfWindow* window)
+void xf_EndLocalMoveSize(xfContext* xfc, xfAppWindow* appWindow)
{
- if (window->local_move.state == LMS_NOT_ACTIVE)
+ if (appWindow->local_move.state == LMS_NOT_ACTIVE)
return;
- if (window->local_move.state == LMS_STARTING)
+ if (appWindow->local_move.state == LMS_STARTING)
{
/*
* The move never was property started. This can happen due to race
* 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->handle,
+ xf_SendClientEvent(xfc, appWindow->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 */
+ appWindow->local_move.root_x, /* x relative to root window */
+ appWindow->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;
+ appWindow->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, xfAppWindow* appWindow, int x, int y, int width, int height)
{
BOOL resize = FALSE;
if ((width * height) < 1)
return;
- if ((window->width != width) || (window->height != height))
+ if ((appWindow->width != width) || (appWindow->height != height))
resize = TRUE;
- if (window->local_move.state == LMS_STARTING ||
- window->local_move.state == LMS_ACTIVE)
+ if (appWindow->local_move.state == LMS_STARTING ||
+ appWindow->local_move.state == LMS_ACTIVE)
return;
- window->left = x;
- window->top = y;
- window->right = x + width - 1;
- window->bottom = y + height - 1;
- window->width = width;
- window->height = height;
+ appWindow->x = x;
+ appWindow->y = y;
+ appWindow->width = width;
+ appWindow->height = height;
if (resize)
- XMoveResizeWindow(xfc->display, window->handle, x, y, width, height);
+ XMoveResizeWindow(xfc->display, appWindow->handle, x, y, width, height);
else
- XMoveWindow(xfc->display, window->handle, x, y);
+ XMoveWindow(xfc->display, appWindow->handle, x, y);
- xf_UpdateWindowArea(xfc, window, 0, 0, width, height);
+ xf_UpdateWindowArea(xfc, appWindow, 0, 0, width, height);
}
-void xf_ShowWindow(xfContext* xfc, xfWindow* window, BYTE state)
+void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state)
{
switch (state)
{
case WINDOW_HIDE:
- XWithdrawWindow(xfc->display, window->handle, xfc->screen_number);
+ XWithdrawWindow(xfc->display, appWindow->handle, xfc->screen_number);
break;
case WINDOW_SHOW_MINIMIZED:
- XIconifyWindow(xfc->display, window->handle, xfc->screen_number);
+ XIconifyWindow(xfc->display, appWindow->handle, xfc->screen_number);
break;
case WINDOW_SHOW_MAXIMIZED:
/* Set the window as maximized */
- xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4, 1,
+ xf_SendClientEvent(xfc, appWindow->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);
/*
* 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)
- xf_UpdateWindowArea(xfc, window, 0, 0, window->window->windowWidth, window->window->windowHeight);
+ if (appWindow->rail_state == WINDOW_SHOW_MAXIMIZED)
+ xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->window->windowWidth, appWindow->window->windowHeight);
break;
case WINDOW_SHOW:
/* Ensure the window is not maximized */
- xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4, 0,
+ xf_SendClientEvent(xfc, appWindow->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);
/*
* 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)
- window->rail_ignore_configure = TRUE;
+ if (appWindow->rail_state == WINDOW_SHOW_MAXIMIZED)
+ appWindow->rail_ignore_configure = TRUE;
- if (window->is_transient)
- xf_SetWindowUnlisted(xfc, window->handle);
+ if (appWindow->is_transient)
+ xf_SetWindowUnlisted(xfc, appWindow->handle);
break;
}
/* Save the current rail state of this window */
- window->rail_state = state;
+ appWindow->rail_state = state;
XFlush(xfc->display);
}
-void xf_SetWindowIcon(xfContext* xfc, xfWindow* window, rdpIcon* icon)
+void xf_SetWindowIcon(xfContext* xfc, xfAppWindow* appWindow, rdpIcon* icon)
{
int x, y;
int pixels;
}
}
- XChangeProperty(xfc->display, window->handle, xfc->_NET_WM_ICON, XA_CARDINAL, 32,
+ XChangeProperty(xfc->display, appWindow->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, xfAppWindow* appWindow, RECTANGLE_16* rects, int nrects)
{
int i;
XRectangle* xrects;
if (nrects < 1)
return;
- xrects = malloc(sizeof(XRectangle) * nrects);
+ xrects = (XRectangle*) calloc(nrects, sizeof(XRectangle));
for (i = 0; i < nrects; i++)
{
}
#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);
+ XShapeCombineRectangles(xfc->display, appWindow->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0);
#endif
+
free(xrects);
}
-void xf_SetWindowVisibilityRects(xfContext* xfc, xfWindow* window, RECTANGLE_16 *rects, int nrects)
+void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rects, int nrects)
{
int i;
XRectangle* xrects;
if (nrects < 1)
return;
- xrects = malloc(sizeof(XRectangle) * nrects);
+ xrects = (XRectangle*) calloc(nrects, sizeof(XRectangle));
for (i = 0; i < nrects; i++)
{
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);
+ XShapeCombineRectangles(xfc->display, appWindow->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, xfAppWindow* appWindow, int x, int y, int width, int height)
{
int ax, ay;
rdpWindow* wnd;
- wnd = window->window;
-
- /* RemoteApp mode uses visibleOffset instead of windowOffset */
+ wnd = appWindow->window;
- if (!xfc->remote_app)
- {
- ax = x + wnd->windowOffsetX;
- ay = y + wnd->windowOffsetY;
-
- if (ax + width > wnd->windowOffsetX + wnd->windowWidth)
- width = (wnd->windowOffsetX + wnd->windowWidth - 1) - ax;
- if (ay + height > wnd->windowOffsetY + wnd->windowHeight)
- height = (wnd->windowOffsetY + wnd->windowHeight - 1) - ay;
- }
- else
- {
- ax = x + wnd->visibleOffsetX;
- ay = y + wnd->visibleOffsetY;
+ ax = x + wnd->visibleOffsetX;
+ ay = y + wnd->visibleOffsetY;
- if (ax + width > wnd->visibleOffsetX + wnd->windowWidth)
- width = (wnd->visibleOffsetX + wnd->windowWidth - 1) - ax;
- if (ay + height > wnd->visibleOffsetY + wnd->windowHeight)
- height = (wnd->visibleOffsetY + wnd->windowHeight - 1) - ay;
- }
+ if (ax + width > wnd->visibleOffsetX + wnd->windowWidth)
+ width = (wnd->visibleOffsetX + wnd->windowWidth - 1) - ax;
+ if (ay + height > wnd->visibleOffsetY + wnd->windowHeight)
+ height = (wnd->visibleOffsetY + wnd->windowHeight - 1) - ay;
- WaitForSingleObject(xfc->mutex, INFINITE);
+ xf_lock_x11(xfc, TRUE);
if (xfc->settings->SoftwareGdi)
{
- XPutImage(xfc->display, xfc->primary, window->gc, xfc->image,
- ax, ay, ax, ay, width, height);
+ XPutImage(xfc->display, xfc->primary, appWindow->gc, xfc->image,
+ ax, ay, ax, ay, width, height);
}
- XCopyArea(xfc->display, xfc->primary, window->handle, window->gc,
- ax, ay, width, height, x, y);
+ XCopyArea(xfc->display, xfc->primary, appWindow->handle, appWindow->gc,
+ ax, ay, width, height, x, y);
XFlush(xfc->display);
- ReleaseMutex(xfc->mutex);
+
+ xf_unlock_x11(xfc, TRUE);
}
-void xf_DestroyWindow(xfContext* xfc, xfWindow* window)
+void xf_DestroyWindow(xfContext* xfc, xfAppWindow* appWindow)
{
- if (!window)
+ if (!appWindow)
return;
- if (xfc->window == window)
- xfc->window = NULL;
-
- if (window->gc)
- XFreeGC(xfc->display, window->gc);
+ if (appWindow->gc)
+ XFreeGC(xfc->display, appWindow->gc);
- if (window->handle)
+ if (appWindow->handle)
{
- XUnmapWindow(xfc->display, window->handle);
- XDestroyWindow(xfc->display, window->handle);
+ XUnmapWindow(xfc->display, appWindow->handle);
+ XDestroyWindow(xfc->display, appWindow->handle);
}
- if (window->xfwin)
- munmap(0, sizeof(*window->xfwin));
+ if (appWindow->xfwin)
+ munmap(0, sizeof(*appWindow->xfwin));
- if (window->shmid >= 0)
- close(window->shmid);
+ if (appWindow->shmid >= 0)
+ close(appWindow->shmid);
shm_unlink(get_shm_id());
- window->xfwin = (Window*) -1;
- window->shmid = -1;
+ appWindow->xfwin = (Window*) -1;
+ appWindow->shmid = -1;
- free(window);
+ free(appWindow);
}
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);
+ return window_list_get_by_extra_id(rail->list, (void*) (long) wnd);
}
}
#include <freerdp/freerdp.h>
+typedef struct xf_app_window xfAppWindow;
+
typedef struct xf_localmove xfLocalMove;
typedef struct xf_window xfWindow;
BOOL decorations;
BOOL is_mapped;
BOOL is_transient;
+};
+
+struct xf_app_window
+{
+ xfContext* xfc;
+ rdpWindow* window;
+
+ int x;
+ int y;
+ int width;
+ int height;
+
+ 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;
xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width, int height, BOOL decorations);
void xf_ResizeDesktopWindow(xfContext* xfc, xfWindow* window, int width, int height);
+void xf_DestroyDesktopWindow(xfContext* xfc, xfWindow* window);
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, ...);
-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,
+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);
+void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state);
+void xf_SetWindowIcon(xfContext* xfc, xfAppWindow* appWindow, rdpIcon* icon);
+void xf_SetWindowRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rects, int nrects);
+void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rects, int nrects);
+void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UINT32 ex_style);
+void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height);
+void xf_DestroyWindow(xfContext* xfc, xfAppWindow* appWindow);
+void xf_SetWindowMinMaxInfo(xfContext* xfc, xfAppWindow* appWindow,
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_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);
#endif /* __XF_WINDOW_H */
BOOL unobscured;
BOOL debug;
xfWindow* window;
+ xfAppWindow* appWindow;
xfPointer* pointer;
xfWorkArea workArea;
int current_desktop;