xfreerdp: added X11 Window wrapper
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Tue, 9 Aug 2011 02:24:12 +0000 (22:24 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Tue, 9 Aug 2011 02:24:12 +0000 (22:24 -0400)
client/X11/CMakeLists.txt
client/X11/xf_event.c
client/X11/xf_keyboard.c
client/X11/xf_window.c [new file with mode: 0644]
client/X11/xf_window.h [new file with mode: 0644]
client/X11/xfreerdp.c
client/X11/xfreerdp.h

index 9723325..93e1836 100644 (file)
@@ -28,6 +28,8 @@ add_executable(xfreerdp
        xf_event.h
        xf_keyboard.c
        xf_keyboard.h
+       xf_window.c
+       xf_window.h
        xfreerdp.c
        xfreerdp.h)
 
index 1596d0e..f2fe7ef 100644 (file)
@@ -34,13 +34,13 @@ boolean xf_event_Expose(xfInfo* xfi, XEvent* event)
        int cx;
        int cy;
 
-       if (event->xexpose.window == xfi->window)
+       if (event->xexpose.window == xfi->window->handle)
        {
                x = event->xexpose.x;
                y = event->xexpose.y;
                cx = event->xexpose.width;
                cy = event->xexpose.height;
-               XCopyArea(xfi->display, xfi->primary, xfi->window, xfi->gc_default, x, y, cx, cy, x, y);
+               XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc_default, x, y, cx, cy, x, y);
        }
 
        return True;
@@ -48,7 +48,7 @@ boolean xf_event_Expose(xfInfo* xfi, XEvent* event)
 
 boolean xf_event_VisibilityNotify(xfInfo* xfi, XEvent* event)
 {
-       if (event->xvisibility.window == xfi->window)
+       if (event->xvisibility.window == xfi->window->handle)
                xfi->unobscured = event->xvisibility.state == VisibilityUnobscured;
 
        return True;
@@ -60,7 +60,7 @@ boolean xf_event_MotionNotify(xfInfo* xfi, XEvent* event)
 
        input = xfi->instance->input;
 
-       if (event->xmotion.window == xfi->window)
+       if (event->xmotion.window == xfi->window->handle)
        {
                if (xfi->mouse_motion != True)
                {
@@ -72,7 +72,7 @@ boolean xf_event_MotionNotify(xfInfo* xfi, XEvent* event)
        }
 
        if (xfi->fullscreen)
-               XSetInputFocus(xfi->display, xfi->window, RevertToPointerRoot, CurrentTime);
+               XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime);
 
        return True;
 }
@@ -85,7 +85,7 @@ boolean xf_event_ButtonPress(xfInfo* xfi, XEvent* event)
 
        input = xfi->instance->input;
 
-       if (event->xbutton.window == xfi->window)
+       if (event->xbutton.window == xfi->window->handle)
        {
                x = 0;
                y = 0;
@@ -144,7 +144,7 @@ boolean xf_event_ButtonRelease(xfInfo* xfi, XEvent* event)
 
        input = xfi->instance->input;
 
-       if (event->xbutton.window == xfi->window)
+       if (event->xbutton.window == xfi->window->handle)
        {
                flags = 0;
 
@@ -221,7 +221,7 @@ boolean xf_event_FocusIn(xfInfo* xfi, XEvent* event)
        xfi->focused = True;
 
        if (xfi->mouse_active)
-               XGrabKeyboard(xfi->display, xfi->window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
+               XGrabKeyboard(xfi->display, xfi->window->handle, True, GrabModeAsync, GrabModeAsync, CurrentTime);
 
        xf_kbd_focus_in(xfi);
 
@@ -274,10 +274,10 @@ boolean xf_event_EnterNotify(xfInfo* xfi, XEvent* event)
        xfi->mouse_active = True;
 
        if (xfi->fullscreen)
-               XSetInputFocus(xfi->display, xfi->window, RevertToPointerRoot, CurrentTime);
+               XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime);
 
        if (xfi->focused)
-               XGrabKeyboard(xfi->display, xfi->window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
+               XGrabKeyboard(xfi->display, xfi->window->handle, True, GrabModeAsync, GrabModeAsync, CurrentTime);
 
        return True;
 }
index eac3d43..fe904be 100644 (file)
@@ -106,7 +106,7 @@ int xf_kbd_read_keyboard_state(xfInfo* xfi)
        uint32 state;
        Window wdummy;
 
-       XQueryPointer(xfi->display, xfi->window,
+       XQueryPointer(xfi->display, xfi->window->handle,
                        &wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state);
 
        return state;
diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c
new file mode 100644 (file)
index 0000000..ae607e9
--- /dev/null
@@ -0,0 +1,135 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * X11 Windows
+ *
+ * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <X11/Xutil.h>
+
+#include "xf_window.h"
+
+#define MWM_HINTS_DECORATIONS          (1L << 1)
+#define PROP_MOTIF_WM_HINTS_ELEMENTS   5
+
+struct _PropMotifWmHints
+{
+       uint32 flags;
+       uint32 functions;
+       uint32 decorations;
+       sint32 inputMode;
+       uint32 status;
+};
+typedef struct _PropMotifWmHints PropMotifWmHints;
+
+void window_fullscreen(xfInfo* xfi, xfWindow* window, boolean fullscreen)
+{
+       if (fullscreen)
+       {
+               if (window->decorations)
+                       window_show_decorations(xfi, window, False);
+
+               XSetInputFocus(xfi->display, window->handle, RevertToParent, CurrentTime);
+               window->fullscreen = True;
+       }
+}
+
+void window_show_decorations(xfInfo* xfi, xfWindow* window, boolean show)
+{
+       Atom atom;
+       PropMotifWmHints hints;
+
+       hints.decorations = 0;
+       hints.flags = MWM_HINTS_DECORATIONS;
+
+       atom = XInternAtom(xfi->display, "_MOTIF_WM_HINTS", False);
+
+       if (!atom)
+       {
+               printf("window_show_decorations: failed to obtain atom _MOTIF_WM_HINTS\n");
+               return;
+       }
+       else
+       {
+               if (show != True)
+               {
+                       XChangeProperty(xfi->display, window->handle, atom, atom, 32,
+                               PropModeReplace, (uint8*) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
+               }
+       }
+
+       window->decorations = False;
+}
+
+xfWindow* window_create(xfInfo* xfi, char* name)
+{
+       xfWindow* window;
+
+       window = (xfWindow*) xzalloc(sizeof(xfWindow));
+
+       if (window != NULL)
+       {
+               int input_mask;
+               XSizeHints* size_hints;
+               XClassHint* class_hints;
+
+               window->decorations = True;
+               window->fullscreen = False;
+
+               window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen),
+                       0, 0, xfi->width, xfi->height, 0, xfi->depth, InputOutput, xfi->visual,
+                       CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
+                       CWBorderPixel, &xfi->attribs);
+
+               class_hints = XAllocClassHint();
+
+               if (class_hints != NULL)
+               {
+                       if (name != NULL)
+                               class_hints->res_name = name;
+
+                       class_hints->res_class = "freerdp";
+                       XSetClassHint(xfi->display, window->handle, class_hints);
+                       XFree(class_hints);
+               }
+
+               size_hints = XAllocSizeHints();
+
+               if (size_hints)
+               {
+                       size_hints->flags = PMinSize | PMaxSize;
+                       size_hints->min_width = size_hints->max_width = xfi->width;
+                       size_hints->min_height = size_hints->max_height = xfi->height;
+                       XSetWMNormalHints(xfi->display, window->handle, size_hints);
+                       XFree(size_hints);
+               }
+
+               input_mask =
+                       KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
+                       VisibilityChangeMask | FocusChangeMask | StructureNotifyMask |
+                       PointerMotionMask | ExposureMask;
+
+               XSelectInput(xfi->display, window->handle, input_mask);
+               XMapWindow(xfi->display, window->handle);
+       }
+
+       return window;
+}
+
+void window_destroy(xfInfo* xfi, xfWindow* window)
+{
+       XDestroyWindow(xfi->display, window->handle);
+       xfree(window);
+}
diff --git a/client/X11/xf_window.h b/client/X11/xf_window.h
new file mode 100644 (file)
index 0000000..b8e564a
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Client
+ * X11 Windows
+ *
+ * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __XF_WINDOW_H
+#define __XF_WINDOW_H
+
+#include <X11/Xlib.h>
+#include <freerdp/freerdp.h>
+#include <freerdp/utils/memory.h>
+
+typedef struct xf_window xfWindow;
+
+#include "xfreerdp.h"
+
+struct xf_window
+{
+       int width;
+       int height;
+       Window handle;
+       boolean fullscreen;
+       boolean decorations;
+};
+
+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);
+void window_destroy(xfInfo* xfi, xfWindow* window);
+
+#endif /* __XF_WINDOW_H */
index a10d9fb..8c3e86b 100644 (file)
 
 #include "xfreerdp.h"
 
-#define MWM_HINTS_DECORATIONS   (1L << 1)
-#define PROP_MOTIF_WM_HINTS_ELEMENTS    5
-
-struct _PropMotifWmHints
-{
-       uint32 flags;
-       uint32 functions;
-       uint32 decorations;
-       sint32 inputMode;
-       uint32 status;
-};
-typedef struct _PropMotifWmHints PropMotifWmHints;
-
 freerdp_sem g_sem;
 static int g_thread_count = 0;
 
@@ -82,7 +69,7 @@ void xf_end_paint(rdpUpdate* update)
        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, xfi->gc_default, x, y, w, h, x, y);
+       XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc_default, x, y, w, h, x, y);
        XFlush(xfi->display);
 }
 
@@ -176,7 +163,7 @@ void xf_toggle_fullscreen(xfInfo* xfi)
 {
        Pixmap contents = 0;
 
-       contents = XCreatePixmap(xfi->display, xfi->window, xfi->width, xfi->height, xfi->depth);
+       contents = XCreatePixmap(xfi->display, xfi->window->handle, xfi->width, xfi->height, xfi->depth);
        XCopyArea(xfi->display, xfi->primary, contents, xfi->gc, 0, 0, xfi->width, xfi->height, 0, 0);
 
        //xf_destroy_window(xfi);
@@ -262,7 +249,6 @@ boolean xf_post_connect(freerdp* instance)
        Atom protocol_atom;
        XSizeHints *size_hints;
        XClassHint *class_hints;
-       XSetWindowAttributes attribs;
 
        xfi = GET_XFI(instance);
        SET_XFI(instance->update, xfi);
@@ -279,71 +265,16 @@ boolean xf_post_connect(freerdp* instance)
        xfi->width = xfi->fullscreen ? WidthOfScreen(xfi->screen) : gdi->width;
        xfi->height = xfi->fullscreen ? HeightOfScreen(xfi->screen) : gdi->height;
 
-       attribs.background_pixel = BlackPixelOfScreen(xfi->screen);
-       attribs.border_pixel = WhitePixelOfScreen(xfi->screen);
-       attribs.backing_store = xfi->primary ? NotUseful : Always;
-       attribs.override_redirect = xfi->fullscreen;
-       attribs.colormap = xfi->colormap;
-
-       xfi->window = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen),
-               0, 0, xfi->width, xfi->height, 0, xfi->depth, InputOutput, xfi->visual,
-               CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap |
-               CWBorderPixel, &attribs);
-
-       class_hints = XAllocClassHint();
-
-       if (class_hints != NULL)
-       {
-               class_hints->res_name = "xfreerdp";
-               class_hints->res_class = "freerdp";
-               XSetClassHint(xfi->display, xfi->window, class_hints);
-               XFree(class_hints);
-       }
-
-       size_hints = XAllocSizeHints();
-
-       if (size_hints)
-       {
-               size_hints->flags = PMinSize | PMaxSize;
-               size_hints->min_width = size_hints->max_width = xfi->width;
-               size_hints->min_height = size_hints->max_height = xfi->height;
-               XSetWMNormalHints(xfi->display, xfi->window, size_hints);
-               XFree(size_hints);
-       }
-
-       input_mask =
-               KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
-               VisibilityChangeMask | FocusChangeMask | StructureNotifyMask |
-               PointerMotionMask | ExposureMask;
+       xfi->attribs.background_pixel = BlackPixelOfScreen(xfi->screen);
+       xfi->attribs.border_pixel = WhitePixelOfScreen(xfi->screen);
+       xfi->attribs.backing_store = xfi->primary ? NotUseful : Always;
+       xfi->attribs.override_redirect = xfi->fullscreen;
+       xfi->attribs.colormap = xfi->colormap;
 
-       XSelectInput(xfi->display, xfi->window, input_mask);
-       XMapWindow(xfi->display, xfi->window);
+       xfi->window = window_create(xfi, "xfreerdp");
 
-       if (xfi->decoration == False)
-       {
-               Atom atom;
-               PropMotifWmHints hints;
-
-               hints.decorations = 0;
-               hints.flags = MWM_HINTS_DECORATIONS;
-
-               atom = XInternAtom(xfi->display, "_MOTIF_WM_HINTS", False);
-
-               if (!atom)
-               {
-                       printf("xf_post_connect: failed to obtain atom _MOTIF_WM_HINTS\n");
-               }
-               else
-               {
-                       XChangeProperty(xfi->display, xfi->window, atom, atom, 32,
-                                       PropModeReplace, (uint8*) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
-               }
-       }
-
-       if (xfi->fullscreen)
-       {
-               XSetInputFocus(xfi->display, xfi->window, RevertToParent, CurrentTime);
-       }
+       window_show_decorations(xfi, xfi->window, xfi->decoration);
+       window_fullscreen(xfi, xfi->window, xfi->fullscreen);
 
        /* wait for VisibilityNotify */
        do
@@ -357,19 +288,19 @@ boolean xf_post_connect(freerdp* instance)
 
        protocol_atom = XInternAtom(xfi->display, "WM_PROTOCOLS", True);
        kill_atom = XInternAtom(xfi->display, "WM_DELETE_WINDOW", True);
-       XSetWMProtocols(xfi->display, xfi->window, &kill_atom, 1);
+       XSetWMProtocols(xfi->display, xfi->window->handle, &kill_atom, 1);
 
        if (!xfi->gc)
-               xfi->gc = XCreateGC(xfi->display, xfi->window, GCGraphicsExposures, &gcv);
+               xfi->gc = XCreateGC(xfi->display, xfi->window->handle, GCGraphicsExposures, &gcv);
 
        if (!xfi->primary)
-               xfi->primary = XCreatePixmap(xfi->display, xfi->window, xfi->width, xfi->height, xfi->depth);
+               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, 8, 8, 1);
+       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, 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);
@@ -451,8 +382,8 @@ void xf_window_free(xfInfo* xfi)
        XFreeGC(xfi->display, xfi->gc);
        xfi->gc = 0;
 
-       XDestroyWindow(xfi->display, xfi->window);
-       xfi->window = 0;
+       window_destroy(xfi, xfi->window);
+       xfi->window = NULL;
 
        if (xfi->primary)
        {
index b5ac4ff..6034df5 100644 (file)
 #include <freerdp/freerdp.h>
 #include <freerdp/chanman.h>
 
+typedef struct xf_info xfInfo;
+
+#include "xf_window.h"
+
 #define SET_XFI(_instance, _xfi) (_instance)->param1 = _xfi
 #define GET_XFI(_instance) ((xfInfo*) ((_instance)->param1))
 
@@ -39,7 +43,6 @@ struct xf_info
        int depth;
        int width;
        int height;
-       Window window;
        Screen* screen;
        XImage* image;
        Pixmap primary;
@@ -54,6 +57,7 @@ struct xf_info
        boolean unobscured;
        boolean decoration;
        freerdp* instance;
+       xfWindow* window;
 
        GC gc_mono;
        GC gc_default;
@@ -66,8 +70,8 @@ struct xf_info
        uint32 keyboard_layout_id;
        boolean pressed_keys[256];
        XModifierKeymap* modifier_map;
+       XSetWindowAttributes attribs;
 };
-typedef struct xf_info xfInfo;
 
 void xf_toggle_fullscreen(xfInfo* xfi);