Floatbar self contained.
authorArmin Novak <armin.novak@thincast.com>
Thu, 15 Nov 2018 13:42:31 +0000 (14:42 +0100)
committerArmin Novak <armin.novak@thincast.com>
Fri, 7 Dec 2018 14:22:28 +0000 (15:22 +0100)
client/X11/xf_client.c
client/X11/xf_event.c
client/X11/xf_floatbar.c
client/X11/xf_floatbar.h
client/X11/xf_window.c
client/X11/xfreerdp.h
client/common/cmdline.c
client/common/cmdline.h
include/freerdp/settings.h

index 8323c78..d6bb2a8 100644 (file)
@@ -1164,7 +1164,6 @@ static BOOL xf_pre_connect(freerdp* instance)
        xfc->decorations = settings->Decorations;
        xfc->grab_keyboard = settings->GrabKeyboard;
        xfc->fullscreen_toggle = settings->ToggleFullscreen;
-       xfc->floatbar = settings->Floatbar;
        xf_button_map_init(xfc);
        return TRUE;
 }
@@ -1546,9 +1545,7 @@ static DWORD WINAPI xf_client_thread(LPVOID param)
                        nCount += tmp;
                }
 
-               if (xfc->floatbar && xfc->fullscreen && !xfc->remote_app)
-                       xf_floatbar_hide_and_show(xfc);
-
+               xf_floatbar_hide_and_show(xfc->window->floatbar);
                waitStatus = WaitForMultipleObjects(nCount, handles, FALSE, INFINITE);
 
                if (waitStatus == WAIT_FAILED)
index 061a879..c900e62 100644 (file)
@@ -367,9 +367,7 @@ static BOOL xf_event_MotionNotify(xfContext* xfc, XEvent* event, BOOL app)
        if (xfc->use_xinput)
                return TRUE;
 
-       if(xfc->floatbar && !(app))
-               xf_floatbar_set_root_y(xfc, event->xmotion.y);
-
+       xf_floatbar_set_root_y(xfc->window->floatbar, event->xmotion.y);
        return xf_generic_MotionNotify(xfc, event->xmotion.x, event->xmotion.y,
                                       event->xmotion.state, event->xmotion.window, app);
 }
@@ -1018,9 +1016,9 @@ BOOL xf_event_process(freerdp* instance, XEvent* event)
                }
        }
 
-       if (xfc->floatbar && xf_floatbar_check_event(xfc, event))
+       if (xf_floatbar_check_event(xfc->window->floatbar, event))
        {
-               xf_floatbar_event_process(xfc, event);
+               xf_floatbar_event_process(xfc->window->floatbar, event);
                return TRUE;
        }
 
index f25b4df..5188c0f 100644 (file)
@@ -57,6 +57,8 @@
 #define XF_FLOATBAR_BUTTON_MINIMIZE 3
 #define XF_FLOATBAR_BUTTON_LOCKED      4
 
+typedef BOOL(*OnClick)(xfFloatbar*);
+
 typedef struct xf_floatbar_button xfFloatbarButton;
 
 struct xf_floatbar
@@ -71,6 +73,11 @@ struct xf_floatbar
        bool locked;
        xfFloatbarButton* buttons[4];
        Window handle;
+       BOOL hasCursor;
+       xfContext* xfc;
+       DWORD flags;
+       BOOL created;
+       Window root_window;
 };
 
 struct xf_floatbar_button
@@ -84,43 +91,70 @@ struct xf_floatbar_button
        Window handle;
 };
 
-static void xf_floatbar_button_onclick_close(xfContext* xfc)
+static xfFloatbarButton* xf_floatbar_new_button(xfFloatbar* floatbar, int type);
+
+static BOOL xf_floatbar_button_onclick_close(xfFloatbar* floatbar)
 {
-       freerdp_abort_connect(xfc->context.instance);
+       if (!floatbar)
+               return FALSE;
+
+       return freerdp_abort_connect(floatbar->xfc->context.instance);
 }
 
-static void xf_floatbar_button_onclick_minimize(xfContext* xfc)
+static BOOL xf_floatbar_button_onclick_minimize(xfFloatbar* floatbar)
 {
+       xfContext* xfc;
+
+       if (!floatbar || !floatbar->xfc)
+               return FALSE;
+
+       xfc = floatbar->xfc;
        xf_SetWindowMinimized(xfc, xfc->window);
+       return TRUE;
 }
 
-static void xf_floatbar_button_onclick_restore(xfContext* xfc)
+static BOOL xf_floatbar_button_onclick_restore(xfFloatbar* floatbar)
 {
-       xf_toggle_fullscreen(xfc);
+       if (!floatbar)
+               return FALSE;
+
+       xf_toggle_fullscreen(floatbar->xfc);
+       return TRUE;
 }
 
-static void xf_floatbar_button_onclick_locked(xfContext* xfc)
+static BOOL xf_floatbar_button_onclick_locked(xfFloatbar* floatbar)
 {
-       xfFloatbar* floatbar;
-       floatbar = xfc->window->floatbar;
+       if (!floatbar)
+               return FALSE;
+
        floatbar->locked = (floatbar->locked) ? FALSE : TRUE;
+       return xf_floatbar_hide_and_show(floatbar);
 }
 
-void xf_floatbar_set_root_y(xfContext* xfc, int y)
+BOOL xf_floatbar_set_root_y(xfFloatbar* floatbar, int y)
 {
-       xfFloatbar* floatbar;
-       floatbar = xfc->window->floatbar;
+       if (!floatbar)
+               return FALSE;
+
        floatbar->last_motion_y_root = y;
+       return TRUE;
 }
 
-void xf_floatbar_hide_and_show(xfContext* xfc)
+BOOL xf_floatbar_hide_and_show(xfFloatbar* floatbar)
 {
-       xfFloatbar* floatbar;
-       floatbar = xfc->window->floatbar;
+       xfContext* xfc;
+
+       if (!floatbar || !floatbar->xfc)
+               return FALSE;
+
+       if (!floatbar->created)
+               return TRUE;
+
+       xfc = floatbar->xfc;
 
        if (!floatbar->locked)
        {
-               if ((floatbar->mode == 0) && (floatbar->last_motion_y_root > 10) &&
+               if ((floatbar->mode == XF_FLOATBAR_MODE_NONE) && (floatbar->last_motion_y_root > 10) &&
                    (floatbar->y > (FLOATBAR_HEIGHT * -1)))
                {
                        floatbar->y = floatbar->y - 1;
@@ -132,16 +166,70 @@ void xf_floatbar_hide_and_show(xfContext* xfc)
                        XMoveWindow(xfc->display, floatbar->handle, floatbar->x, floatbar->y);
                }
        }
+
+       return TRUE;
 }
 
-void xf_floatbar_toggle_visibility(xfContext* xfc, bool visible)
+static BOOL create_floatbar(xfFloatbar* floatbar)
+{
+       xfContext* xfc;
+       Status status;
+       XWindowAttributes attr;
+
+       if (floatbar->created)
+               return TRUE;
+
+       xfc = floatbar->xfc;
+       status = XGetWindowAttributes(xfc->display, floatbar->root_window, &attr);
+       floatbar->x = attr.x + attr.width / 2 - FLOATBAR_DEFAULT_WIDTH / 2;
+       floatbar->y = 0;
+
+       if (((floatbar->flags & 0x0004) == 0) && !floatbar->locked)
+               floatbar->y = -FLOATBAR_HEIGHT + 1;
+
+       floatbar->handle = XCreateWindow(xfc->display, floatbar->root_window,
+                                        floatbar->x, 0, FLOATBAR_DEFAULT_WIDTH,
+                                        FLOATBAR_HEIGHT, 0,
+                                        CopyFromParent, InputOutput, CopyFromParent, 0, NULL);
+       floatbar->width = FLOATBAR_DEFAULT_WIDTH;
+       floatbar->height = FLOATBAR_HEIGHT;
+       floatbar->mode = XF_FLOATBAR_MODE_NONE;
+       floatbar->buttons[0] = xf_floatbar_new_button(floatbar, XF_FLOATBAR_BUTTON_CLOSE);
+       floatbar->buttons[1] = xf_floatbar_new_button(floatbar, XF_FLOATBAR_BUTTON_RESTORE);
+       floatbar->buttons[2] = xf_floatbar_new_button(floatbar, XF_FLOATBAR_BUTTON_MINIMIZE);
+       floatbar->buttons[3] = xf_floatbar_new_button(floatbar, XF_FLOATBAR_BUTTON_LOCKED);
+       XSelectInput(xfc->display, floatbar->handle, ExposureMask | ButtonPressMask | ButtonReleaseMask |
+                    PointerMotionMask | FocusChangeMask | LeaveWindowMask | EnterWindowMask | StructureNotifyMask |
+                    PropertyChangeMask);
+       floatbar->created = TRUE;
+       return TRUE;
+}
+
+BOOL xf_floatbar_toggle_fullscreen(xfFloatbar* floatbar, bool fullscreen)
 {
-       xfFloatbar* floatbar;
        int i, size;
-       floatbar = xfc->window->floatbar;
+       bool visible = False;
+       xfContext* xfc;
+
+       if (!floatbar || !floatbar->xfc)
+               return FALSE;
+
+       xfc = floatbar->xfc;
+
+       /* Only visible if enabled */
+       if (floatbar->flags & 0x0001)
+       {
+               /* Visible if fullscreen and flag visible in fullscreen mode */
+               visible |= ((floatbar->flags & 0x0010) != 0) && fullscreen;
+               /* Visible if window and flag visible in window mode */
+               visible |= ((floatbar->flags & 0x0020) != 0) && !fullscreen;
+       }
 
        if (visible)
        {
+               if (!create_floatbar(floatbar))
+                       return FALSE;
+
                XMapWindow(xfc->display, floatbar->handle);
                size = ARRAYSIZE(floatbar->buttons);
 
@@ -149,15 +237,23 @@ void xf_floatbar_toggle_visibility(xfContext* xfc, bool visible)
                {
                        XMapWindow(xfc->display, floatbar->buttons[i]->handle);
                }
+
+               /* If default is hidden (and not sticky) don't show on fullscreen state changes */
+               if (((floatbar->flags & 0x0004) == 0) && !floatbar->locked)
+                       floatbar->y = -FLOATBAR_HEIGHT + 1;
+
+               xf_floatbar_hide_and_show(floatbar);
        }
-       else
+       else if (floatbar->created)
        {
                XUnmapSubwindows(xfc->display, floatbar->handle);
                XUnmapWindow(xfc->display, floatbar->handle);
        }
+
+       return TRUE;
 }
 
-static xfFloatbarButton* xf_floatbar_new_button(xfContext* xfc, xfFloatbar* floatbar, int type)
+xfFloatbarButton* xf_floatbar_new_button(xfFloatbar* floatbar, int type)
 {
        xfFloatbarButton* button;
        button = (xfFloatbarButton*) calloc(1, sizeof(xfFloatbarButton));
@@ -191,74 +287,67 @@ static xfFloatbarButton* xf_floatbar_new_button(xfContext* xfc, xfFloatbar* floa
 
        button->y = 0;
        button->focus = FALSE;
-       button->handle = XCreateWindow(xfc->display, floatbar->handle, button->x, 0, FLOATBAR_BUTTON_WIDTH,
+       button->handle = XCreateWindow(floatbar->xfc->display, floatbar->handle, button->x, 0,
+                                      FLOATBAR_BUTTON_WIDTH,
                                       FLOATBAR_BUTTON_WIDTH, 0, CopyFromParent, InputOutput, CopyFromParent, 0, NULL);
-       XSelectInput(xfc->display, button->handle, ExposureMask | ButtonPressMask | ButtonReleaseMask |
+       XSelectInput(floatbar->xfc->display, button->handle,
+                    ExposureMask | ButtonPressMask | ButtonReleaseMask |
                     FocusChangeMask | LeaveWindowMask | EnterWindowMask | StructureNotifyMask);
        return button;
 }
 
-xfFloatbar* xf_floatbar_new(xfContext* xfc, Window window)
+xfFloatbar* xf_floatbar_new(xfContext* xfc, Window window, DWORD flags)
 {
        xfFloatbar* floatbar;
-       XWindowAttributes attr;
-       int i, width;
+
+       /* Floatbar not enabled */
+       if ((flags & 0x0001) == 0)
+               return NULL;
+
        if (!xfc)
                return NULL;
 
+       /* Force disable with remote app */
+       if (xfc->remote_app)
+               return NULL;
+
        floatbar = (xfFloatbar*) calloc(1, sizeof(xfFloatbar));
-       floatbar->locked = TRUE;
-       XGetWindowAttributes(xfc->display, window, &attr);
 
-       for (i = 0; i < xfc->vscreen.nmonitors; i++)
-       {
-               if (attr.x >= xfc->vscreen.monitors[i].area.left && attr.x <= xfc->vscreen.monitors[i].area.right)
-               {
-                       width = xfc->vscreen.monitors[i].area.right - xfc->vscreen.monitors[i].area.left;
-                       floatbar->x = width / 2 + xfc->vscreen.monitors[i].area.left - FLOATBAR_DEFAULT_WIDTH / 2;
-               }
-       }
+       if (!floatbar)
+               return NULL;
 
-       floatbar->y = 0;
-       floatbar->handle = XCreateWindow(xfc->display, window, floatbar->x, 0, FLOATBAR_DEFAULT_WIDTH,
-                                        FLOATBAR_HEIGHT, 0,
-                                        CopyFromParent, InputOutput, CopyFromParent, 0, NULL);
-       floatbar->width = FLOATBAR_DEFAULT_WIDTH;
-       floatbar->height = FLOATBAR_HEIGHT;
-       floatbar->mode = XF_FLOATBAR_MODE_NONE;
-       floatbar->buttons[0] = xf_floatbar_new_button(xfc, floatbar, XF_FLOATBAR_BUTTON_CLOSE);
-       floatbar->buttons[1] = xf_floatbar_new_button(xfc, floatbar, XF_FLOATBAR_BUTTON_RESTORE);
-       floatbar->buttons[2] = xf_floatbar_new_button(xfc, floatbar, XF_FLOATBAR_BUTTON_MINIMIZE);
-       floatbar->buttons[3] = xf_floatbar_new_button(xfc, floatbar, XF_FLOATBAR_BUTTON_LOCKED);
-       XSelectInput(xfc->display, floatbar->handle, ExposureMask | ButtonPressMask | ButtonReleaseMask |
-                    PointerMotionMask | FocusChangeMask | LeaveWindowMask | EnterWindowMask | StructureNotifyMask |
-                    PropertyChangeMask);
+       floatbar->root_window = window;
+       floatbar->flags = flags;
+       floatbar->xfc = xfc;
+       floatbar->locked = flags & 0x0002;
+       xf_floatbar_toggle_fullscreen(floatbar, FALSE);
        return floatbar;
 }
 
-static unsigned long xf_floatbar_get_color(xfContext* xfc, char* rgb_value)
+static unsigned long xf_floatbar_get_color(xfFloatbar* floatbar, char* rgb_value)
 {
        Colormap cmap;
        XColor color;
-       cmap = DefaultColormap(xfc->display, XDefaultScreen(xfc->display));
-       XParseColor(xfc->display, cmap, rgb_value, &color);
-       XAllocColor(xfc->display, cmap, &color);
-       XFreeColormap(xfc->display, cmap);
+       Display* display = floatbar->xfc->display;
+       cmap = DefaultColormap(display, XDefaultScreen(display));
+       XParseColor(display, cmap, rgb_value, &color);
+       XAllocColor(display, cmap, &color);
+       XFreeColormap(display, cmap);
        return color.pixel;
 }
 
-static void xf_floatbar_event_expose(xfContext* xfc, XEvent* event)
+static void xf_floatbar_event_expose(xfFloatbar* floatbar, XEvent* event)
 {
        GC gc, shape_gc;
        Pixmap pmap;
        XPoint shape[5], border[5];
-       xfFloatbar* floatbar;
        int len;
-       floatbar = xfc->window->floatbar;
+       rdpSettings* settings = floatbar->xfc->context.settings;
+       Display* display = floatbar->xfc->display;
        /* create the pixmap that we'll use for shaping the window */
-       pmap = XCreatePixmap(xfc->display, floatbar->handle, floatbar->width, floatbar->height, 1);
-       gc = XCreateGC(xfc->display, floatbar->handle, 0, 0);
-       shape_gc = XCreateGC(xfc->display, pmap, 0, 0);
+       pmap = XCreatePixmap(display, floatbar->handle, floatbar->width, floatbar->height, 1);
+       gc = XCreateGC(display, floatbar->handle, 0, 0);
+       shape_gc = XCreateGC(display, pmap, 0, 0);
        /* points for drawing the floatbar */
        shape[0].x = 0;
        shape[0].y = 0;
@@ -282,34 +371,32 @@ static void xf_floatbar_event_expose(xfContext* xfc, XEvent* event)
        border[4].x = border[0].x;
        border[4].y = border[0].y;
        /* Fill all pixels with 0 */
-       XSetForeground(xfc->display, shape_gc, 0);
-       XFillRectangle(xfc->display, pmap, shape_gc, 0, 0, floatbar->width,
+       XSetForeground(display, shape_gc, 0);
+       XFillRectangle(display, pmap, shape_gc, 0, 0, floatbar->width,
                       floatbar->height);
        /* Fill all pixels which should be shown with 1 */
-       XSetForeground(xfc->display, shape_gc, 1);
-       XFillPolygon(xfc->display, pmap, shape_gc, shape, 5, 0, CoordModeOrigin);
-       XShapeCombineMask(xfc->display, floatbar->handle, ShapeBounding, 0, 0, pmap, ShapeSet);
+       XSetForeground(display, shape_gc, 1);
+       XFillPolygon(display, pmap, shape_gc, shape, 5, 0, CoordModeOrigin);
+       XShapeCombineMask(display, floatbar->handle, ShapeBounding, 0, 0, pmap, ShapeSet);
        /* draw the float bar */
-       XSetForeground(xfc->display, gc, xf_floatbar_get_color(xfc, FLOATBAR_COLOR_BACKGROUND));
-       XFillPolygon(xfc->display, floatbar->handle, gc, shape, 4, 0, CoordModeOrigin);
+       XSetForeground(display, gc, xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_BACKGROUND));
+       XFillPolygon(display, floatbar->handle, gc, shape, 4, 0, CoordModeOrigin);
        /* draw an border for the floatbar */
-       XSetForeground(xfc->display, gc, xf_floatbar_get_color(xfc, FLOATBAR_COLOR_BORDER));
-       XDrawLines(xfc->display, floatbar->handle, gc, border, 5, CoordModeOrigin);
+       XSetForeground(display, gc, xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_BORDER));
+       XDrawLines(display, floatbar->handle, gc, border, 5, CoordModeOrigin);
        /* draw the host name connected to */
-       len = strlen(xfc->context.settings->ServerHostname);
-       XSetForeground(xfc->display, gc, xf_floatbar_get_color(xfc, FLOATBAR_COLOR_FOREGROUND));
-       XDrawString(xfc->display, floatbar->handle, gc, floatbar->width / 2 - len * 2, 15,
-                   xfc->context.settings->ServerHostname, len);
-       XFreeGC(xfc->display, gc);
-       XFreeGC(xfc->display, shape_gc);
+       len = strlen(settings->ServerHostname);
+       XSetForeground(display, gc, xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_FOREGROUND));
+       XDrawString(display, floatbar->handle, gc, floatbar->width / 2 - len * 2, 15,
+                   settings->ServerHostname, len);
+       XFreeGC(display, gc);
+       XFreeGC(display, shape_gc);
 }
 
-static xfFloatbarButton* xf_floatbar_get_button(xfContext* xfc, XEvent* event)
+static xfFloatbarButton* xf_floatbar_get_button(xfFloatbar* floatbar, XEvent* event)
 {
-       xfFloatbar* floatbar;
        int i, size;
        size = ARRAYSIZE(floatbar->buttons);
-       floatbar = xfc->window->floatbar;
 
        for (i = 0; i < size; i++)
        {
@@ -322,12 +409,11 @@ static xfFloatbarButton* xf_floatbar_get_button(xfContext* xfc, XEvent* event)
        return NULL;
 }
 
-static void xf_floatbar_button_update_positon(xfContext* xfc, XEvent* event)
+static void xf_floatbar_button_update_positon(xfFloatbar* floatbar, XEvent* event)
 {
-       xfFloatbar* floatbar;
        xfFloatbarButton* button;
        int i, size;
-       floatbar = xfc->window->floatbar;
+       xfContext* xfc = floatbar->xfc;
        size = ARRAYSIZE(floatbar->buttons);
 
        for (i = 0; i < size; i++)
@@ -353,18 +439,17 @@ static void xf_floatbar_button_update_positon(xfContext* xfc, XEvent* event)
                }
 
                XMoveWindow(xfc->display, button->handle, button->x, button->y);
-               xf_floatbar_event_expose(xfc, event);
+               xf_floatbar_event_expose(floatbar, event);
        }
 }
 
-static void xf_floatbar_button_event_expose(xfContext* xfc, XEvent* event)
+static void xf_floatbar_button_event_expose(xfFloatbar* floatbar, XEvent* event)
 {
-       xfFloatbar* floatbar;
-       xfFloatbarButton* button;
+       xfFloatbarButton* button = xf_floatbar_get_button(floatbar, event);
        static unsigned char* bits;
        GC gc;
        Pixmap pattern;
-       button = xf_floatbar_get_button(xfc, event);
+       xfContext* xfc = floatbar->xfc;
 
        if (!button)
                return;
@@ -402,43 +487,39 @@ static void xf_floatbar_button_event_expose(xfContext* xfc, XEvent* event)
                                        FLOATBAR_BUTTON_WIDTH, FLOATBAR_BUTTON_WIDTH);
 
        if (!(button->focus))
-               XSetForeground(xfc->display, gc, xf_floatbar_get_color(xfc, FLOATBAR_COLOR_BACKGROUND));
+               XSetForeground(xfc->display, gc, xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_BACKGROUND));
        else
-               XSetForeground(xfc->display, gc, xf_floatbar_get_color(xfc, FLOATBAR_COLOR_BORDER));
+               XSetForeground(xfc->display, gc, xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_BORDER));
 
-       XSetBackground(xfc->display, gc, xf_floatbar_get_color(xfc, FLOATBAR_COLOR_FOREGROUND));
+       XSetBackground(xfc->display, gc, xf_floatbar_get_color(floatbar, FLOATBAR_COLOR_FOREGROUND));
        XCopyPlane(xfc->display, pattern, button->handle, gc, 0, 0, FLOATBAR_BUTTON_WIDTH,
                   FLOATBAR_BUTTON_WIDTH, 0, 0, 1);
        XFreePixmap(xfc->display, pattern);
        XFreeGC(xfc->display, gc);
 }
 
-static void xf_floatbar_button_event_buttonpress(xfContext* xfc, XEvent* event)
+static void xf_floatbar_button_event_buttonpress(xfFloatbar* floatbar, XEvent* event)
 {
-       xfFloatbarButton* button;
-       button = xf_floatbar_get_button(xfc, event);
+       xfFloatbarButton* button = xf_floatbar_get_button(floatbar, event);
 
        if (button)
                button->clicked = TRUE;
 }
 
-static void xf_floatbar_button_event_buttonrelease(xfContext* xfc, XEvent* event)
+static void xf_floatbar_button_event_buttonrelease(xfFloatbar* floatbar, XEvent* event)
 {
        xfFloatbarButton* button;
-       button = xf_floatbar_get_button(xfc, event);
+       button = xf_floatbar_get_button(floatbar, event);
 
        if (button)
        {
                if (button->clicked)
-                       button->onclick(xfc);
+                       button->onclick(floatbar);
        }
 }
 
-static void xf_floatbar_event_buttonpress(xfContext* xfc, XEvent* event)
+static void xf_floatbar_event_buttonpress(xfFloatbar* floatbar, XEvent* event)
 {
-       xfFloatbar* floatbar;
-       floatbar = xfc->window->floatbar;
-
        switch (event->xbutton.button)
        {
                case Button1:
@@ -456,12 +537,12 @@ static void xf_floatbar_event_buttonpress(xfContext* xfc, XEvent* event)
        }
 }
 
-static void xf_floatbar_event_buttonrelease(xfContext* xfc, XEvent* event)
+static void xf_floatbar_event_buttonrelease(xfFloatbar* floatbar, XEvent* event)
 {
        switch (event->xbutton.button)
        {
                case Button1:
-                       xfc->window->floatbar->mode = XF_FLOATBAR_MODE_NONE;
+                       floatbar->mode = XF_FLOATBAR_MODE_NONE;
                        break;
 
                default:
@@ -469,11 +550,10 @@ static void xf_floatbar_event_buttonrelease(xfContext* xfc, XEvent* event)
        }
 }
 
-static void xf_floatbar_resize(xfContext* xfc, XEvent* event)
+static void xf_floatbar_resize(xfFloatbar* floatbar, XEvent* event)
 {
-       xfFloatbar* floatbar;
-       floatbar = xfc->window->floatbar;
        int x, width, movement;
+       xfContext* xfc = floatbar->xfc;
        /* calculate movement which happened on the root window */
        movement = event->xmotion.x_root - floatbar->last_motion_x_root;
 
@@ -498,11 +578,10 @@ static void xf_floatbar_resize(xfContext* xfc, XEvent* event)
        }
 }
 
-static void xf_floatbar_dragging(xfContext* xfc, XEvent* event)
+static void xf_floatbar_dragging(xfFloatbar* floatbar, XEvent* event)
 {
-       xfFloatbar* floatbar;
-       floatbar = xfc->window->floatbar;
        int x, movement;
+       xfContext* xfc = floatbar->xfc;
        /* calculate movement and new x position */
        movement = event->xmotion.x_root - floatbar->last_motion_x_root;
        x = floatbar->x + movement;
@@ -518,78 +597,82 @@ static void xf_floatbar_dragging(xfContext* xfc, XEvent* event)
        floatbar->x = x;
 }
 
-static void xf_floatbar_event_motionnotify(xfContext* xfc, XEvent* event)
+static void xf_floatbar_event_motionnotify(xfFloatbar* floatbar, XEvent* event)
 {
        int mode;
-       xfFloatbar* floatbar;
        Cursor cursor;
-       mode = xfc->window->floatbar->mode;
-       floatbar = xfc->window->floatbar;
+       xfContext* xfc = floatbar->xfc;
+       mode = floatbar->mode;
        cursor = XCreateFontCursor(xfc->display, XC_arrow);
 
        if ((event->xmotion.state & Button1Mask) && (mode > XF_FLOATBAR_MODE_DRAGGING))
        {
-               xf_floatbar_resize(xfc, event);
+               xf_floatbar_resize(floatbar, event);
        }
        else if ((event->xmotion.state & Button1Mask) && (mode == XF_FLOATBAR_MODE_DRAGGING))
        {
-               xf_floatbar_dragging(xfc, event);
+               xf_floatbar_dragging(floatbar, event);
        }
        else
        {
                if (event->xmotion.x <= FLOATBAR_BORDER ||
-                   event->xmotion.x >= xfc->window->floatbar->width - FLOATBAR_BORDER)
+                   event->xmotion.x >= floatbar->width - FLOATBAR_BORDER)
                        cursor = XCreateFontCursor(xfc->display, XC_sb_h_double_arrow);
        }
 
        XDefineCursor(xfc->display, xfc->window->handle, cursor);
        XFreeCursor(xfc->display, cursor);
-       xfc->window->floatbar->last_motion_x_root = event->xmotion.x_root;
+       floatbar->last_motion_x_root = event->xmotion.x_root;
 }
 
-static void xf_floatbar_button_event_focusin(xfContext* xfc, XEvent* event)
+static void xf_floatbar_button_event_focusin(xfFloatbar* floatbar, XEvent* event)
 {
        xfFloatbarButton* button;
-       button = xf_floatbar_get_button(xfc, event);
+       button = xf_floatbar_get_button(floatbar, event);
 
        if (button)
        {
                button->focus = TRUE;
-               xf_floatbar_button_event_expose(xfc, event);
+               xf_floatbar_button_event_expose(floatbar, event);
        }
 }
 
-static void xf_floatbar_button_event_focusout(xfContext* xfc, XEvent* event)
+static void xf_floatbar_button_event_focusout(xfFloatbar* floatbar, XEvent* event)
 {
        xfFloatbarButton* button;
-       button = xf_floatbar_get_button(xfc, event);
+       button = xf_floatbar_get_button(floatbar, event);
 
        if (button)
        {
                button->focus = FALSE;
                button->clicked = FALSE;
-               xf_floatbar_button_event_expose(xfc, event);
+               xf_floatbar_button_event_expose(floatbar, event);
        }
 }
 
-static void xf_floatbar_event_focusout(xfContext* xfc, XEvent* event)
+static void xf_floatbar_event_focusout(xfFloatbar* floatbar, XEvent* event)
 {
-       Cursor cursor;
-       cursor = XCreateFontCursor(xfc->display, XC_arrow);
-       XDefineCursor(xfc->display, xfc->window->handle, cursor);
-       XFreeCursor(xfc->display, cursor);
+       xfContext* xfc = floatbar->xfc;
+
+       if (xfc->pointer)
+       {
+               XDefineCursor(xfc->display, xfc->window->handle, xfc->pointer->cursor);
+       }
 }
 
-BOOL xf_floatbar_check_event(xfContext* xfc, XEvent* event)
+BOOL xf_floatbar_check_event(xfFloatbar* floatbar, XEvent* event)
 {
-       xfFloatbar* floatbar;
        xfFloatbarButton* button;
        size_t i, size;
+       xfContext* xfc;
 
-       if (!xfc || !event || !xfc->window)
+       if (!floatbar || !floatbar->xfc || !event)
                return FALSE;
 
-       floatbar = xfc->window->floatbar;
+       if (!floatbar->created)
+               return FALSE;
+
+       xfc = floatbar->xfc;
 
        if (event->xany.window == floatbar->handle)
                return TRUE;
@@ -607,70 +690,69 @@ BOOL xf_floatbar_check_event(xfContext* xfc, XEvent* event)
        return FALSE;
 }
 
-BOOL xf_floatbar_event_process(xfContext* xfc, XEvent* event)
+BOOL xf_floatbar_event_process(xfFloatbar* floatbar, XEvent* event)
 {
-       xfFloatbar* floatbar;
-
-       if (!xfc || !xfc->window || !event)
+       if (!floatbar || !floatbar->xfc || !event)
                return FALSE;
 
-       floatbar = xfc->window->floatbar;
+       if (!floatbar->created)
+               return FALSE;
 
        switch (event->type)
        {
                case Expose:
                        if (event->xany.window == floatbar->handle)
-                               xf_floatbar_event_expose(xfc, event);
+                               xf_floatbar_event_expose(floatbar, event);
                        else
-                               xf_floatbar_button_event_expose(xfc, event);
+                               xf_floatbar_button_event_expose(floatbar, event);
 
                        break;
 
                case MotionNotify:
-                       xf_floatbar_event_motionnotify(xfc, event);
+                       xf_floatbar_event_motionnotify(floatbar, event);
                        break;
 
                case ButtonPress:
                        if (event->xany.window == floatbar->handle)
-                               xf_floatbar_event_buttonpress(xfc, event);
+                               xf_floatbar_event_buttonpress(floatbar, event);
                        else
-                               xf_floatbar_button_event_buttonpress(xfc, event);
+                               xf_floatbar_button_event_buttonpress(floatbar, event);
 
                        break;
 
                case ButtonRelease:
                        if (event->xany.window == floatbar->handle)
-                               xf_floatbar_event_buttonrelease(xfc, event);
+                               xf_floatbar_event_buttonrelease(floatbar, event);
                        else
-                               xf_floatbar_button_event_buttonrelease(xfc, event);
+                               xf_floatbar_button_event_buttonrelease(floatbar, event);
 
                        break;
 
                case EnterNotify:
                case FocusIn:
                        if (event->xany.window != floatbar->handle)
-                               xf_floatbar_button_event_focusin(xfc, event);
+                               xf_floatbar_button_event_focusin(floatbar, event);
 
                        break;
 
                case LeaveNotify:
                case FocusOut:
                        if (event->xany.window == floatbar->handle)
-                               xf_floatbar_event_focusout(xfc, event);
+                               xf_floatbar_event_focusout(floatbar, event);
                        else
-                               xf_floatbar_button_event_focusout(xfc, event);
+                               xf_floatbar_button_event_focusout(floatbar, event);
 
                        break;
 
                case ConfigureNotify:
                        if (event->xany.window == floatbar->handle)
-                               xf_floatbar_button_update_positon(xfc, event);
+                               xf_floatbar_button_update_positon(floatbar, event);
 
                        break;
 
                case PropertyNotify:
                        if (event->xany.window == floatbar->handle)
-                               xf_floatbar_button_update_positon(xfc, event);
+                               xf_floatbar_button_update_positon(floatbar, event);
 
                        break;
 
@@ -695,16 +777,19 @@ static void xf_floatbar_button_free(xfContext* xfc, xfFloatbarButton* button)
        free(button);
 }
 
-void xf_floatbar_free(xfContext* xfc, xfWindow* window, xfFloatbar* floatbar)
+void xf_floatbar_free(xfFloatbar* floatbar)
 {
        size_t i, size;
-       size = ARRAYSIZE(floatbar->buttons);
+       xfContext* xfc;
 
        if (!floatbar)
                return;
 
-       if (window->floatbar == floatbar)
-               window->floatbar = NULL;
+       xfc = floatbar->xfc;
+       size = ARRAYSIZE(floatbar->buttons);
+
+       if (!floatbar)
+               return;
 
        for (i = 0; i < size; i++)
        {
index fecb5cb..be92642 100644 (file)
@@ -22,13 +22,13 @@ typedef struct xf_floatbar xfFloatbar;
 
 #include "xfreerdp.h"
 
-typedef void(*OnClick)(xfContext*);
-xfFloatbar* xf_floatbar_new(xfContext* xfc, Window window);
-BOOL xf_floatbar_event_process(xfContext* xfc, XEvent* event);
-BOOL xf_floatbar_check_event(xfContext* xfc, XEvent* event);
-void xf_floatbar_toggle_visibility(xfContext* xfc, bool visible);
-void xf_floatbar_free(xfContext* xfc, xfWindow* window, xfFloatbar* floatbar);
-void xf_floatbar_hide_and_show(xfContext* xfc);
-void xf_floatbar_set_root_y(xfContext* xfc, int y);
+xfFloatbar* xf_floatbar_new(xfContext* xfc, Window window, DWORD flags);
+void xf_floatbar_free(xfFloatbar* floatbar);
+
+BOOL xf_floatbar_event_process(xfFloatbar* floatbar, XEvent* event);
+BOOL xf_floatbar_check_event(xfFloatbar* floatbar, XEvent* event);
+BOOL xf_floatbar_toggle_fullscreen(xfFloatbar* floatbar, bool visible);
+BOOL xf_floatbar_hide_and_show(xfFloatbar* floatbar);
+BOOL xf_floatbar_set_root_y(xfFloatbar* floatbar, int y);
 
 #endif /* FREERDP_CLIENT_X11_FLOATBAR_H */
index dfd1fc2..4e1d2b0 100644 (file)
@@ -163,9 +163,7 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
        /* show/hide decorations (e.g. title bar) as guided by xfc->decorations */
        xf_SetWindowDecorations(xfc, window->handle, window->decorations);
        DEBUG_X11(TAG, "X window decoration set to %d", (int)window->decorations);
-
-       if (xfc->floatbar)
-               xf_floatbar_toggle_visibility(xfc, fullscreen);
+       xf_floatbar_toggle_fullscreen(xfc->window->floatbar, fullscreen);
 
        if (fullscreen)
        {
@@ -587,7 +585,7 @@ xfWindow* xf_CreateDesktopWindow(xfContext* xfc, char* name, int width,
                            settings->DesktopPosY);
        }
 
-       window->floatbar = xf_floatbar_new(xfc, window->handle);
+       window->floatbar = xf_floatbar_new(xfc, window->handle, settings->Floatbar);
        return window;
 }
 
@@ -636,8 +634,7 @@ void xf_DestroyDesktopWindow(xfContext* xfc, xfWindow* window)
        if (xfc->window == window)
                xfc->window = NULL;
 
-       if (window->floatbar)
-               xf_floatbar_free(xfc, window, window->floatbar);
+       xf_floatbar_free(window->floatbar);
 
        if (window->gc)
                XFreeGC(xfc->display, window->gc);
index 746ea33..98dad2b 100644 (file)
@@ -161,7 +161,6 @@ struct xf_context
        BOOL use_xinput;
        BOOL mouse_active;
        BOOL fullscreen_toggle;
-       BOOL floatbar;
        BOOL controlToggle;
        UINT32 KeyboardLayout;
        BOOL KeyboardState[256];
index 652e937..7902cd5 100644 (file)
@@ -2628,7 +2628,70 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
                }
                CommandLineSwitchCase(arg, "floatbar")
                {
-                       settings->Floatbar = enable;
+                       /* Defaults are enabled, visible, sticky, fullscreen */
+                       settings->Floatbar = 0x0017;
+
+                       if (arg->Value)
+                       {
+                               char* start = arg->Value;
+
+                               do
+                               {
+                                       char* cur = start;
+                                       start = strchr(start, ',');
+
+                                       if (start)
+                                       {
+                                               *start = '\0';
+                                               start = start + 1;
+                                       }
+
+                                       /* sticky:[on|off] */
+                                       if (strncasecmp(cur, "sticky:", 7) == 0)
+                                       {
+                                               const char* val = cur + 7;
+                                               settings->Floatbar &= ~0x02u;
+
+                                               if (strncasecmp(val, "on", 3) == 0)
+                                                       settings->Floatbar |= 0x02u;
+                                               else if (strncasecmp(val, "off", 4) == 0)
+                                                       settings->Floatbar &= ~0x02u;
+                                               else
+                                                       return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
+                                       }
+                                       /* default:[visible|hidden] */
+                                       else if (strncasecmp(cur, "default:", 8) == 0)
+                                       {
+                                               const char* val = cur + 8;
+                                               settings->Floatbar &= ~0x04u;
+
+                                               if (strncasecmp(val, "visible", 8) == 0)
+                                                       settings->Floatbar |= 0x04u;
+                                               else if (strncasecmp(val, "hidden", 7) == 0)
+                                                       settings->Floatbar &= ~0x04u;
+                                               else
+                                                       return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
+                                       }
+                                       /* show:[always|fullscreen|window] */
+                                       else if (strncasecmp(cur, "show:", 5) == 0)
+                                       {
+                                               const char* val = cur + 5;
+                                               settings->Floatbar &= ~0x30u;
+
+                                               if (strncasecmp(val, "always", 7) == 0)
+                                                       settings->Floatbar |= 0x30u;
+                                               else if (strncasecmp(val, "fullscreen", 11) == 0)
+                                                       settings->Floatbar |= 0x10u;
+                                               else if (strncasecmp(val, "window", 7) == 0)
+                                                       settings->Floatbar |= 0x20u;
+                                               else
+                                                       return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
+                                       }
+                                       else
+                                               return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
+                               }
+                               while (start);
+                       }
                }
                CommandLineSwitchCase(arg, "mouse-motion")
                {
index df45ac2..b35273f 100644 (file)
@@ -68,7 +68,7 @@ static COMMAND_LINE_ARGUMENT_A args[] =
        { "f", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Fullscreen mode (<Ctrl>+<Alt>+<Enter> toggles fullscreen)" },
        { "fast-path", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "fast-path input/output" },
        { "fipsmode", COMMAND_LINE_VALUE_BOOL, NULL, NULL, NULL, -1, NULL, "FIPS mode" },
-       { "floatbar", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "floatbar in fullscreen mode" },
+       { "floatbar", COMMAND_LINE_VALUE_OPTIONAL, "sticky:[on|off],default:[visible|hidden],show:[always|fullscreen||window]", NULL, NULL, -1, NULL, "floatbar (default sticky in fullscreen mode)" },
        { "fonts", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "smooth fonts (ClearType)" },
        { "frame-ack", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL, "Number of frame acknowledgement" },
        { "from-stdin", COMMAND_LINE_VALUE_OPTIONAL, "force", NULL, NULL, -1, NULL, "Read credentials from stdin. With <force> the prompt is done before connection, otherwise on server request." },
index 54ea655..7f7c5ca 100644 (file)
@@ -1518,7 +1518,7 @@ struct rdp_settings
        ALIGN64 BYTE*
        SettingsModified;  /* byte array marking fields that have been modified from their default value */
        ALIGN64 char* ActionScript;
-       ALIGN64 BOOL   Floatbar;
+       ALIGN64 DWORD  Floatbar;
 
 };
 typedef struct rdp_settings rdpSettings;