xfreerdp: remove backbuffer window in RemoteApp mode
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 18 Aug 2011 05:16:49 +0000 (01:16 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 18 Aug 2011 05:16:49 +0000 (01:16 -0400)
client/X11/xf_event.c
client/X11/xf_keyboard.c
client/X11/xf_rail.c
client/X11/xf_window.c
client/X11/xf_window.h
client/X11/xfreerdp.c
client/X11/xfreerdp.h

index 1f87222..7296fea 100644 (file)
@@ -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:
index d9e8e5b..b6831ba 100644 (file)
@@ -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;
 }
index 8bf9ec9..da58a87 100644 (file)
@@ -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);
+               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->window->handle, xfw->handle, xfw->gc,
+               XCopyArea(xfi->display, xfi->primary, xfw->handle, xfw->gc,
                                window->windowOffsetX, window->windowOffsetY,
-                               window->windowWidth, window->windowHeight,
-                               0, 0);
+                               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)
index 8a4b2ee..e638dc5 100644 (file)
@@ -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)
index d01daf7..773a041 100644 (file)
@@ -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);
index 814bfcf..930ab9e 100644 (file)
@@ -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);
-       }
-       while (xevent.type != VisibilityNotify);
+               xfi->window = desktop_create(xfi, "xfreerdp");
 
-       xfi->unobscured = (xevent.xvisibility.state == VisibilityUnobscured);
-       memset(&gcv, 0, sizeof(gcv));
+               window_show_decorations(xfi, xfi->window, xfi->decoration);
+               window_fullscreen(xfi, xfi->window, xfi->fullscreen);
 
-       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);
+               /* wait for VisibilityNotify */
+               do
+               {
+                       XMaskEvent(xfi->display, VisibilityChangeMask, &xevent);
+               }
+               while (xevent.type != VisibilityNotify);
+
+               xfi->unobscured = (xevent.xvisibility.state == VisibilityUnobscured);
 
-       if (!xfi->gc)
-               xfi->gc = XCreateGC(xfi->display, xfi->window->handle, GCGraphicsExposures, &gcv);
+               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);
+       }
 
-       if (!xfi->primary)
-               xfi->primary = XCreatePixmap(xfi->display, xfi->window->handle, xfi->width, xfi->height, xfi->depth);
+       memset(&gcv, 0, sizeof(gcv));
+       xfi->modifier_map = XGetModifierMapping(xfi->display);
 
-       xfi->drawing = xfi->primary;
+       xfi->gc = XCreateGC(xfi->display, DefaultRootWindow(xfi->display), GCGraphicsExposures, &gcv);
+       xfi->primary = XCreatePixmap(xfi->display, DefaultRootWindow(xfi->display), xfi->width, xfi->height, xfi->depth);
 
-       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;
 
index ee8ebc1..66c0e93 100644 (file)
@@ -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;