From 3fa7d4a3d4d2c1892392160be4b4785bc8ff6bf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 18 Aug 2011 01:16:49 -0400 Subject: [PATCH] xfreerdp: remove backbuffer window in RemoteApp mode --- client/X11/xf_event.c | 71 ++++++++++++++++++++++++++++++---------- client/X11/xf_keyboard.c | 7 ++-- client/X11/xf_rail.c | 14 +++++--- client/X11/xf_window.c | 21 ++++++++++-- client/X11/xf_window.h | 2 +- client/X11/xfreerdp.c | 70 +++++++++++++++++---------------------- client/X11/xfreerdp.h | 5 --- 7 files changed, 116 insertions(+), 74 deletions(-) diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index 1f872222c..7296feaed 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -29,18 +29,37 @@ void xf_send_mouse_motion_event(rdpInput* input, boolean down, uint32 button, ui boolean xf_event_Expose(xfInfo* xfi, XEvent* event, boolean app) { - int x; - int y; - int cx; - int cy; + int x, y; + int cx, cy; - if (event->xexpose.window == xfi->window->handle) + if (app != True) { x = event->xexpose.x; y = event->xexpose.y; cx = event->xexpose.width; cy = event->xexpose.height; - XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc_default, x, y, cx, cy, x, y); + XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, cx, cy, x, y); + } + else + { + xfWindow* xfw; + rdpWindow* window; + + window = window_list_get_by_extra_id(xfi->rail->list, (void*) event->xany.window); + + if (window != NULL) + { + xfw = (xfWindow*) window->extra; + + XPutImage(xfi->display, xfi->primary, xfw->gc, xfi->image, + window->windowOffsetX, window->windowOffsetY, + window->windowOffsetX, window->windowOffsetY, + window->windowWidth, window->windowHeight); + + XCopyArea(xfi->display, xfi->primary, xfw->handle, xfw->gc, + window->windowOffsetX, window->windowOffsetY, + window->windowWidth, window->windowHeight, 0, 0); + } } return True; @@ -48,7 +67,7 @@ boolean xf_event_Expose(xfInfo* xfi, XEvent* event, boolean app) boolean xf_event_VisibilityNotify(xfInfo* xfi, XEvent* event, boolean app) { - if (event->xvisibility.window == xfi->window->handle) + if (app != True) xfi->unobscured = event->xvisibility.state == VisibilityUnobscured; return True; @@ -60,7 +79,7 @@ boolean xf_event_MotionNotify(xfInfo* xfi, XEvent* event, boolean app) input = xfi->instance->input; - if (event->xmotion.window == xfi->window->handle) + if (app != True) { if (xfi->mouse_motion != True) { @@ -69,10 +88,10 @@ boolean xf_event_MotionNotify(xfInfo* xfi, XEvent* event, boolean app) } input->MouseEvent(input, PTR_FLAGS_MOVE, event->xmotion.x, event->xmotion.y); - } - if (xfi->fullscreen) - XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime); + if (xfi->fullscreen) + XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime); + } return True; } @@ -258,7 +277,7 @@ boolean xf_event_FocusIn(xfInfo* xfi, XEvent* event, boolean app) xfi->focused = True; - if (xfi->mouse_active) + if (xfi->mouse_active && (app != True)) XGrabKeyboard(xfi->display, xfi->window->handle, True, GrabModeAsync, GrabModeAsync, CurrentTime); xf_kbd_focus_in(xfi); @@ -309,13 +328,16 @@ boolean xf_event_ClientMessage(xfInfo* xfi, XEvent* event, boolean app) boolean xf_event_EnterNotify(xfInfo* xfi, XEvent* event, boolean app) { - xfi->mouse_active = True; + if (app != True) + { + xfi->mouse_active = True; - if (xfi->fullscreen) - XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime); + if (xfi->fullscreen) + XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime); - if (xfi->focused) - XGrabKeyboard(xfi->display, xfi->window->handle, True, GrabModeAsync, GrabModeAsync, CurrentTime); + if (xfi->focused) + XGrabKeyboard(xfi->display, xfi->window->handle, True, GrabModeAsync, GrabModeAsync, CurrentTime); + } return True; } @@ -328,14 +350,26 @@ boolean xf_event_LeaveNotify(xfInfo* xfi, XEvent* event, boolean app) return True; } +boolean xf_event_ConfigureNotify(xfInfo* xfi, XEvent* event, boolean app) +{ + return True; +} + boolean xf_event_process(freerdp* instance, XEvent* event) { boolean app = False; boolean status = True; xfInfo* xfi = GET_XFI(instance); - if (event->xany.window != xfi->window->handle) + if (xfi->remote_app == True) + { app = True; + } + else + { + if (event->xany.window != xfi->window->handle) + app = True; + } switch (event->type) { @@ -390,6 +424,7 @@ boolean xf_event_process(freerdp* instance, XEvent* event) break; case ConfigureNotify: + status = xf_event_ConfigureNotify(xfi, event, app); break; case MapNotify: diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index d9e8e5bf5..b6831ba3b 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -103,11 +103,14 @@ void xf_kbd_send_key(xfInfo* xfi, boolean down, uint8 keycode) int xf_kbd_read_keyboard_state(xfInfo* xfi) { int dummy; - uint32 state; Window wdummy; + uint32 state = 0; - XQueryPointer(xfi->display, xfi->window->handle, + if (xfi->remote_app != True) + { + XQueryPointer(xfi->display, xfi->window->handle, &wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state); + } return state; } diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index 8bf9ec9e1..da58a8733 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -34,12 +34,14 @@ void xf_rail_paint(xfInfo* xfi, rdpRail* rail) window = window_list_get_next(rail->list); xfw = (xfWindow*) window->extra; - //printf("painting window 0x%08X\n", window->windowId); - - XCopyArea(xfi->display, xfi->window->handle, xfw->handle, xfw->gc, + XPutImage(xfi->display, xfi->primary, xfw->gc, xfi->image, window->windowOffsetX, window->windowOffsetY, - window->windowWidth, window->windowHeight, - 0, 0); + window->windowOffsetX, window->windowOffsetY, + window->windowWidth, window->windowHeight); + + XCopyArea(xfi->display, xfi->primary, xfw->handle, xfw->gc, + window->windowOffsetX, window->windowOffsetY, + window->windowWidth, window->windowHeight, 0, 0); XFlush(xfi->display); } @@ -73,6 +75,8 @@ void xf_rail_MoveWindow(rdpRail* rail, rdpWindow* window) window->windowOffsetX + xfi->workArea.x, window->windowOffsetY + xfi->workArea.y, window->windowWidth, window->windowHeight); + + XFlush(xfi->display); } void xf_rail_DestroyWindow(rdpRail* rail, rdpWindow* window) diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index 8a4b2ee3b..e638dc559 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -116,8 +116,6 @@ boolean window_GetWorkArea(xfInfo* xfi) xfi->workArea.height = plong[xfi->current_desktop * 4 + 3]; xfree(prop); - printf("x:%d y:%d w:%d h:%d\n", xfi->workArea.x, xfi->workArea.y, xfi->workArea.width, xfi->workArea.height); - return True; } @@ -148,7 +146,7 @@ void window_show_decorations(xfInfo* xfi, xfWindow* window, boolean show) window->decorations = show; } -xfWindow* window_create(xfInfo* xfi, char* name) +xfWindow* desktop_create(xfInfo* xfi, char* name) { xfWindow* window; @@ -272,6 +270,7 @@ xfWindow* xf_CreateWindow(xfInfo* xfi, int x, int y, int width, int height, char void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height) { + XSizeHints* size_hints; XWindowChanges changes; changes.x = x; @@ -280,6 +279,22 @@ void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int h changes.height = height; XConfigureWindow(xfi->display, window->handle, CWX | CWY | CWWidth | CWHeight, &changes); + + window->width = width; + window->height = height; + XFreePixmap(xfi->display, window->surface); + window->surface = XCreatePixmap(xfi->display, window->handle, window->width, window->height, xfi->depth); + + size_hints = XAllocSizeHints(); + + if (size_hints) + { + size_hints->flags = PMinSize | PMaxSize; + size_hints->min_width = size_hints->max_width = window->width; + size_hints->min_height = size_hints->max_height = window->height; + XSetWMNormalHints(xfi->display, window->handle, size_hints); + XFree(size_hints); + } } void xf_DestroyWindow(xfInfo* xfi, xfWindow* window) diff --git a/client/X11/xf_window.h b/client/X11/xf_window.h index d01daf7ab..773a04120 100644 --- a/client/X11/xf_window.h +++ b/client/X11/xf_window.h @@ -45,7 +45,7 @@ boolean window_GetWorkArea(xfInfo* xfi); void window_fullscreen(xfInfo* xfi, xfWindow* window, boolean fullscreen); void window_show_decorations(xfInfo* xfi, xfWindow* window, boolean show); -xfWindow* window_create(xfInfo* xfi, char* name); +xfWindow* desktop_create(xfInfo* xfi, char* name); xfWindow* xf_CreateWindow(xfInfo* xfi, int x, int y, int width, int height, char* name); void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height); diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index 814bfcf49..930ab9e73 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -71,12 +71,16 @@ void xf_end_paint(rdpUpdate* update) w = gdi->primary->hdc->hwnd->invalid->w; h = gdi->primary->hdc->hwnd->invalid->h; - XPutImage(xfi->display, xfi->primary, xfi->gc_default, xfi->image, x, y, x, y, w, h); - XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc_default, x, y, w, h, x, y); - XFlush(xfi->display); - - if (xfi->remote_app == True) + if (xfi->remote_app != True) + { + XPutImage(xfi->display, xfi->primary, xfi->gc, xfi->image, x, y, x, y, w, h); + XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y); + XFlush(xfi->display); + } + else + { xf_rail_paint(xfi, update->rail); + } } boolean xf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount) @@ -283,39 +287,35 @@ boolean xf_post_connect(freerdp* instance) xfi->attribs.override_redirect = xfi->fullscreen; xfi->attribs.colormap = xfi->colormap; - xfi->window = window_create(xfi, "xfreerdp"); - - window_show_decorations(xfi, xfi->window, xfi->decoration); - window_fullscreen(xfi, xfi->window, xfi->fullscreen); - - /* wait for VisibilityNotify */ - do + if (xfi->remote_app != True) { - XMaskEvent(xfi->display, VisibilityChangeMask, &xevent); + xfi->window = desktop_create(xfi, "xfreerdp"); + + window_show_decorations(xfi, xfi->window, xfi->decoration); + window_fullscreen(xfi, xfi->window, xfi->fullscreen); + + /* wait for VisibilityNotify */ + do + { + XMaskEvent(xfi->display, VisibilityChangeMask, &xevent); + } + while (xevent.type != VisibilityNotify); + + xfi->unobscured = (xevent.xvisibility.state == VisibilityUnobscured); + + protocol_atom = XInternAtom(xfi->display, "WM_PROTOCOLS", True); + kill_atom = XInternAtom(xfi->display, "WM_DELETE_WINDOW", True); + XSetWMProtocols(xfi->display, xfi->window->handle, &kill_atom, 1); } - while (xevent.type != VisibilityNotify); - xfi->unobscured = (xevent.xvisibility.state == VisibilityUnobscured); memset(&gcv, 0, sizeof(gcv)); + xfi->modifier_map = XGetModifierMapping(xfi->display); - protocol_atom = XInternAtom(xfi->display, "WM_PROTOCOLS", True); - kill_atom = XInternAtom(xfi->display, "WM_DELETE_WINDOW", True); - XSetWMProtocols(xfi->display, xfi->window->handle, &kill_atom, 1); + xfi->gc = XCreateGC(xfi->display, DefaultRootWindow(xfi->display), GCGraphicsExposures, &gcv); + xfi->primary = XCreatePixmap(xfi->display, DefaultRootWindow(xfi->display), xfi->width, xfi->height, xfi->depth); - if (!xfi->gc) - xfi->gc = XCreateGC(xfi->display, xfi->window->handle, GCGraphicsExposures, &gcv); - - if (!xfi->primary) - xfi->primary = XCreatePixmap(xfi->display, xfi->window->handle, xfi->width, xfi->height, xfi->depth); - - xfi->drawing = xfi->primary; - - xfi->bitmap_mono = XCreatePixmap(xfi->display, xfi->window->handle, 8, 8, 1); - xfi->gc_mono = XCreateGC(xfi->display, xfi->bitmap_mono, GCGraphicsExposures, &gcv); - xfi->gc_default = XCreateGC(xfi->display, xfi->window->handle, GCGraphicsExposures, &gcv); XSetForeground(xfi->display, xfi->gc, BlackPixelOfScreen(xfi->screen)); XFillRectangle(xfi->display, xfi->primary, xfi->gc, 0, 0, xfi->width, xfi->height); - xfi->modifier_map = XGetModifierMapping(xfi->display); xfi->image = XCreateImage(xfi->display, xfi->visual, xfi->depth, ZPixmap, 0, (char*) gdi->primary_buffer, gdi->width, gdi->height, xfi->scanline_pad, 0); @@ -399,16 +399,6 @@ void xf_window_free(xfInfo* xfi) XFreeModifiermap(xfi->modifier_map); xfi->modifier_map = 0; - XFreeGC(xfi->display, xfi->gc_default); - xfi->gc_default = 0; - - XFreeGC(xfi->display, xfi->gc_mono); - xfi->gc_mono = 0; - - /* Note: valgrind reports this at lost no matter what */ - XFreePixmap(xfi->display, xfi->bitmap_mono); - xfi->bitmap_mono = 0; - XFreeGC(xfi->display, xfi->gc); xfi->gc = 0; diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index ee8ebc10e..66c0e937d 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -57,7 +57,6 @@ struct xf_info Screen* screen; XImage* image; Pixmap primary; - Drawable drawing; Visual* visual; Display* display; Colormap colormap; @@ -74,10 +73,6 @@ struct xf_info boolean remote_app; rdpRail* rail; - GC gc_mono; - GC gc_default; - Pixmap bitmap_mono; - boolean focused; boolean mouse_active; boolean mouse_motion;