diff gui/wm/ws.c @ 35672:144d3a71db7d

Cosmetic: Relocate some functions. This groups functions that belong together.
author ib
date Thu, 17 Jan 2013 16:49:26 +0000
parents 8ce9bc8aa443
children 2b7f93ef711d
line wrap: on
line diff
--- a/gui/wm/ws.c	Thu Jan 17 16:39:05 2013 +0000
+++ b/gui/wm/ws.c	Thu Jan 17 16:49:26 2013 +0000
@@ -129,32 +129,6 @@
 
 #define MWM_DECOR_ALL           (1L << 0)
 
-// ----------------------------------------------------------------------------------------------
-//   Init X Window System.
-// ----------------------------------------------------------------------------------------------
-
-/**
- * @brief Inform about an X error that has occurred.
- *
- * @param display display
- * @param event pointer to an X error event structure
- *
- * @return 0
- */
-static int wsErrorHandler(Display *display, XErrorEvent *event)
-{
-    char type[128];
-
-    XGetErrorText(display, event->error_code, type, sizeof(type));
-
-    mp_msg(MSGT_GPLAYER, MSGL_ERR, "[ws] " MSGTR_WS_XError);
-    mp_msg(MSGT_GPLAYER, MSGL_ERR, "[ws]  Error code: %d - %s\n", event->error_code, type);
-    mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws]  Request code: %d (minor code: %d)\n", event->request_code, event->minor_code);
-    mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws]  MPlayer module: %s\n", current_module ? current_module : "(none)");
-
-    return 0;
-}
-
 /**
  * @brief Update screen width, screen height and screen origin x and y
  *        from xinerama information.
@@ -191,12 +165,77 @@
     }
 }
 
-/**
- * @brief Set the X error handler.
- */
-void wsSetErrorHandler(void)
+int wsGetDepthOnScreen(void)
 {
-    XSetErrorHandler(wsErrorHandler);
+    int depth;
+    XImage *mXImage;
+    Visual *visual;
+
+    if ((depth = vo_find_depth_from_visuals(wsDisplay, wsScreen, &visual)) > 0) {
+        mXImage = XCreateImage(wsDisplay, visual, depth, ZPixmap, 0, NULL,
+                               1, 1, 32, 0);
+        wsDepthOnScreen = mXImage->bits_per_pixel;
+        wsRedMask       = mXImage->red_mask;
+        wsGreenMask     = mXImage->green_mask;
+        wsBlueMask      = mXImage->blue_mask;
+#if HAVE_BIGENDIAN
+        wsNonNativeOrder = mXImage->byte_order == LSBFirst;
+#else
+        wsNonNativeOrder = mXImage->byte_order == MSBFirst;
+#endif
+        XDestroyImage(mXImage);
+    } else {
+        int bpp, ibpp;
+        XWindowAttributes attribs;
+
+        mXImage = XGetImage(wsDisplay, wsRootWin, 0, 0, 1, 1, AllPlanes, ZPixmap);
+        bpp     = mXImage->bits_per_pixel;
+
+        XGetWindowAttributes(wsDisplay, wsRootWin, &attribs);
+        ibpp    = attribs.depth;
+        mXImage = XGetImage(wsDisplay, wsRootWin, 0, 0, 1, 1, AllPlanes, ZPixmap);
+        bpp     = mXImage->bits_per_pixel;
+
+        if ((ibpp + 7) / 8 != (bpp + 7) / 8)
+            ibpp = bpp;
+
+        wsDepthOnScreen = ibpp;
+        wsRedMask       = mXImage->red_mask;
+        wsGreenMask     = mXImage->green_mask;
+        wsBlueMask      = mXImage->blue_mask;
+        XDestroyImage(mXImage);
+    }
+
+    return wsDepthOnScreen;
+}
+
+int wsGetOutMask(void)
+{
+    if ((wsDepthOnScreen == 32) && (wsRedMask == 0xff0000) && (wsGreenMask == 0x00ff00) && (wsBlueMask == 0x0000ff))
+        return wsRGB32;
+
+    if ((wsDepthOnScreen == 32) && (wsRedMask == 0x0000ff) && (wsGreenMask == 0x00ff00) && (wsBlueMask == 0xff0000))
+        return wsBGR32;
+
+    if ((wsDepthOnScreen == 24) && (wsRedMask == 0xff0000) && (wsGreenMask == 0x00ff00) && (wsBlueMask == 0x0000ff))
+        return wsRGB24;
+
+    if ((wsDepthOnScreen == 24) && (wsRedMask == 0x0000ff) && (wsGreenMask == 0x00ff00) && (wsBlueMask == 0xff0000))
+        return wsBGR24;
+
+    if ((wsDepthOnScreen == 16) && (wsRedMask == 0xf800) && (wsGreenMask == 0x7e0) && (wsBlueMask == 0x1f))
+        return wsRGB16;
+
+    if ((wsDepthOnScreen == 16) && (wsRedMask == 0x1f) && (wsGreenMask == 0x7e0) && (wsBlueMask == 0xf800))
+        return wsBGR16;
+
+    if ((wsDepthOnScreen == 15) && (wsRedMask == 0x7c00) && (wsGreenMask == 0x3e0) && (wsBlueMask == 0x1f))
+        return wsRGB15;
+
+    if ((wsDepthOnScreen == 15) && (wsRedMask == 0x1f) && (wsGreenMask == 0x3e0) && (wsBlueMask == 0x7c00))
+        return wsBGR15;
+
+    return 0;
 }
 
 void wsXInit(Display *display)
@@ -338,6 +377,327 @@
     }
 }
 
+void wsXDone(void)
+{
+    XCloseDisplay(wsDisplay);
+}
+
+/**
+ * @brief Inform about an X error that has occurred.
+ *
+ * @param display display
+ * @param event pointer to an X error event structure
+ *
+ * @return 0
+ */
+static int wsErrorHandler(Display *display, XErrorEvent *event)
+{
+    char type[128];
+
+    XGetErrorText(display, event->error_code, type, sizeof(type));
+
+    mp_msg(MSGT_GPLAYER, MSGL_ERR, "[ws] " MSGTR_WS_XError);
+    mp_msg(MSGT_GPLAYER, MSGL_ERR, "[ws]  Error code: %d - %s\n", event->error_code, type);
+    mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws]  Request code: %d (minor code: %d)\n", event->request_code, event->minor_code);
+    mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws]  MPlayer module: %s\n", current_module ? current_module : "(none)");
+
+    return 0;
+}
+
+/**
+ * @brief Set the X error handler.
+ */
+void wsSetErrorHandler(void)
+{
+    XSetErrorHandler(wsErrorHandler);
+}
+
+// ----------------------------------------------------------------------------------------------
+//   Handle events.
+// ----------------------------------------------------------------------------------------------
+
+static int wsSearch(Window win)
+{
+    int i;
+
+    for (i = 0; i < wsWLCount; i++)
+        if (wsWindowList[i] && wsWindowList[i]->WindowID == win)
+            return i;
+
+    return -1;
+}
+
+void wsEvents(XEvent *event)
+{
+    unsigned long i = 0;
+    int l;
+    int x, y;
+    Window child_window = 0;
+
+    l = wsSearch(event->xany.window);
+
+    if (l == -1)
+        return;
+
+    wsWindowList[l]->State = wsNone;
+
+    switch (event->type) {
+    case ClientMessage:
+
+        if (event->xclient.message_type == wsWindowList[l]->AtomProtocols) {
+            if ((Atom)event->xclient.data.l[0] == wsWindowList[l]->AtomDeleteWindow) {
+                i = wsWindowClosed;
+                goto expose;
+            }
+
+            if ((Atom)event->xclient.data.l[0] == wsWindowList[l]->AtomTakeFocus) {
+                i = wsWindowFocusIn;
+                wsWindowList[l]->Focused = wsFocused;
+                goto expose;
+            }
+
+            if ((Atom)event->xclient.data.l[0] == wsWindowList[l]->AtomRolle) {
+                mp_msg(MSGT_GPLAYER, MSGL_V, "[ws] role set.\n");
+            }
+        } else {
+            /* try to process DND events */
+            wsXDNDProcessClientMessage(&event->xclient);
+        }
+
+        break;
+
+    case MapNotify:
+
+        i = wsWindowMapped;
+        wsWindowList[l]->Mapped = wsMapped;
+        goto expose;
+
+    case UnmapNotify:
+
+        i = wsWindowUnmapped;
+        wsWindowList[l]->Mapped = wsNo;
+        goto expose;
+
+    case FocusIn:
+
+        if (wsWindowList[l]->Focused == wsFocused)
+            break;
+
+        i = wsWindowFocusIn;
+        wsWindowList[l]->Focused = wsFocused;
+        goto expose;
+
+    case FocusOut:
+
+        if (wsWindowList[l]->Focused == wsNo)
+            break;
+
+        i = wsWindowFocusOut;
+        wsWindowList[l]->Focused = wsNo;
+        goto expose;
+
+    case VisibilityNotify:
+
+        switch (event->xvisibility.state) {
+        case VisibilityUnobscured:
+            i = wsWindowVisible;
+            wsWindowList[l]->Visible = wsVisible;
+            goto expose;
+
+        case VisibilityFullyObscured:
+            i = wsWindowNotVisible;
+            wsWindowList[l]->Visible = wsNotVisible;
+            goto expose;
+
+        case VisibilityPartiallyObscured:
+            i = wsWindowPartialVisible;
+            wsWindowList[l]->Visible = wsPVisible;
+            goto expose;
+        }
+
+expose:
+        wsWindowList[l]->State = i;
+
+        if (wsWindowList[l]->ReDraw)
+            wsWindowList[l]->ReDraw();
+
+        break;
+
+    case Expose:
+
+        wsWindowList[l]->State = wsWindowExpose;
+
+        if ((wsWindowList[l]->ReDraw) && (!event->xexpose.count))
+            wsWindowList[l]->ReDraw();
+
+        break;
+
+    case ConfigureNotify:
+
+        XTranslateCoordinates(wsDisplay, wsWindowList[l]->WindowID, wsRootWin, 0, 0, &x, &y, &child_window);
+
+        if ((wsWindowList[l]->X != x) || (wsWindowList[l]->Y != y) || (wsWindowList[l]->Width != event->xconfigure.width) || (wsWindowList[l]->Height != event->xconfigure.height)) {
+            wsWindowList[l]->X      = x;
+            wsWindowList[l]->Y      = y;
+            wsWindowList[l]->Width  = event->xconfigure.width;
+            wsWindowList[l]->Height = event->xconfigure.height;
+        }
+
+        wsWindowList[l]->Rolled = wsNo;
+
+        if (event->xconfigure.y < 0) {
+            i = wsWindowRolled;
+            wsWindowList[l]->Rolled = wsRolled;
+            goto expose;
+        }
+
+        break;
+
+    case KeyPress:
+
+        i = wsKeyPressed;
+        goto keypressed;
+
+    case KeyRelease:
+
+        i = wsKeyReleased;
+keypressed:
+        wsWindowList[l]->Alt      = False;
+        wsWindowList[l]->Shift    = False;
+        wsWindowList[l]->NumLock  = False;
+        wsWindowList[l]->Control  = False;
+        wsWindowList[l]->CapsLock = False;
+
+        if (event->xkey.state & Mod1Mask)
+            wsWindowList[l]->Alt = True;
+
+        if (event->xkey.state & Mod2Mask)
+            wsWindowList[l]->NumLock = True;
+
+        if (event->xkey.state & ControlMask)
+            wsWindowList[l]->Control = True;
+
+        if (event->xkey.state & ShiftMask)
+            wsWindowList[l]->Shift = True;
+
+        if (event->xkey.state & LockMask)
+            wsWindowList[l]->CapsLock = True;
+
+#if 0
+        {
+            KeySym keySym;
+            keySym = XKeycodeToKeysym(wsDisplay, event->xkey.keycode, 0);
+
+            if (keySym != NoSymbol) {
+                keySym = ((keySym & 0xff00) != 0 ? ((keySym & 0x00ff) + 256) : (keySym));
+
+                if (wsWindowList[l]->KeyHandler)
+                    wsWindowList[l]->KeyHandler(event->xkey.state, i, keySym);
+            }
+        }
+#else
+        {
+            int key;
+            char buf[100];
+            KeySym keySym;
+            static XComposeStatus stat;
+
+            XLookupString(&event->xkey, buf, sizeof(buf), &keySym, &stat);
+            key = ((keySym & 0xff00) != 0 ? ((keySym & 0x00ff) + 256) : (keySym));
+
+            if (wsWindowList[l]->KeyHandler)
+                wsWindowList[l]->KeyHandler(event->xkey.keycode, i, key);
+        }
+#endif
+        break;
+
+    case MotionNotify:
+
+        i = wsMoveMouse;
+        {
+            /* pump all motion events from the display queue:
+             * this way it works faster when moving the window */
+            static XEvent e;
+
+            if (event->xmotion.state) {
+                while (XCheckTypedWindowEvent(wsDisplay, event->xany.window, MotionNotify, &e)) {
+                    /* FIXME: need to make sure we didn't release/press the button in between...*/
+                    /* FIXME: do we need some timeout here to make sure we don't spend too much time
+                     * removing events from the queue? */
+                    event = &e;
+                }
+            }
+        }
+
+        if (wsWindowList[l]->wsCursor != None) {
+            wsVisibleMouse(wsWindowList[l], wsShowMouseCursor);
+            mouse_win  = wsWindowList[l];
+            mouse_time = GetTimerMS();
+        }
+
+        goto buttonreleased;
+
+    case ButtonRelease:
+
+        i = event->xbutton.button + 128;
+
+        if (wsWindowList[l]->wsCursor != None) {
+            wsVisibleMouse(wsWindowList[l], wsShowMouseCursor);
+            mouse_win  = wsWindowList[l];
+            mouse_time = GetTimerMS();
+        }
+
+        goto buttonreleased;
+
+    case ButtonPress:
+
+        i = event->xbutton.button;
+
+        if (wsWindowList[l]->wsCursor != None) {
+            wsVisibleMouse(wsWindowList[l], wsShowMouseCursor);
+            mouse_win  = wsWindowList[l];
+            mouse_time = GetTimerMS();
+        }
+
+        goto buttonreleased;
+
+    case EnterNotify:
+
+        i = wsEnterWindow;
+        goto buttonreleased;
+
+    case LeaveNotify:
+
+        i = wsLeaveWindow;
+buttonreleased:
+
+        if (wsWindowList[l]->MouseHandler)
+            wsWindowList[l]->MouseHandler(i, event->xbutton.x, event->xbutton.y, event->xmotion.x_root, event->xmotion.y_root);
+
+        break;
+
+    case SelectionNotify:
+
+        /* Handle DandD */
+        wsXDNDProcessSelection(wsWindowList[l], event);
+        break;
+    }
+
+    XFlush(wsDisplay);
+    XSync(wsDisplay, False);
+}
+
+void wsHandleEvents(void)
+{
+    XEvent wsEvent;
+    /* handle pending events */
+    while (XPending(wsDisplay)) {
+        XNextEvent(wsDisplay, &wsEvent);
+//   printf("### X event: %d  [%d]\n",wsEvent.type,delay);
+        wsEvents(&wsEvent);
+    }
+}
+
 /**
  * @brief Calculate and store the x and y position for a window.
  *
@@ -626,38 +986,6 @@
     mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[ws] window is created. ( %s ).\n", label);
 }
 
-void wsWindowDecoration(wsWindow *win, Bool decor)
-{
-    MotifWmHints wsMotifWmHints;
-
-    wsMotifHints = XInternAtom(wsDisplay, "_MOTIF_WM_HINTS", 0);
-
-    if (wsMotifHints == None)
-        return;
-
-    memset(&wsMotifWmHints, 0, sizeof(MotifWmHints));
-    wsMotifWmHints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS;
-
-    if (decor) {
-        wsMotifWmHints.functions   = MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE;
-        wsMotifWmHints.decorations = MWM_DECOR_ALL;
-    }
-
-    XChangeProperty(wsDisplay, win->WindowID, wsMotifHints, wsMotifHints, 32,
-                    PropModeReplace, (unsigned char *)&wsMotifWmHints, 5);
-}
-
-static int wsSearch(Window win)
-{
-    int i;
-
-    for (i = 0; i < wsWLCount; i++)
-        if (wsWindowList[i] && wsWindowList[i]->WindowID == win)
-            return i;
-
-    return -1;
-}
-
 void wsDestroyWindow(wsWindow *win)
 {
     int l;
@@ -687,440 +1015,137 @@
 #endif
 }
 
+void wsSetTitle(wsWindow *win, char *name)
+{
+    XStoreName(wsDisplay, win->WindowID, name);
+}
+
+void wsWindowDecoration(wsWindow *win, Bool decor)
+{
+    MotifWmHints wsMotifWmHints;
+
+    wsMotifHints = XInternAtom(wsDisplay, "_MOTIF_WM_HINTS", 0);
+
+    if (wsMotifHints == None)
+        return;
+
+    memset(&wsMotifWmHints, 0, sizeof(MotifWmHints));
+    wsMotifWmHints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS;
+
+    if (decor) {
+        wsMotifWmHints.functions   = MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE;
+        wsMotifWmHints.decorations = MWM_DECOR_ALL;
+    }
+
+    XChangeProperty(wsDisplay, win->WindowID, wsMotifHints, wsMotifHints, 32,
+                    PropModeReplace, (unsigned char *)&wsMotifWmHints, 5);
+}
+
+void wsSetShape(wsWindow *win, char *data)
+{
+#ifdef CONFIG_XSHAPE
+    if (!wsUseXShape)
+        return;
+
+    if (data) {
+        win->Mask = XCreateBitmapFromData(wsDisplay, win->WindowID, data, win->Width, win->Height);
+        XShapeCombineMask(wsDisplay, win->WindowID, ShapeBounding, 0, 0, win->Mask, ShapeSet);
+        XFreePixmap(wsDisplay, win->Mask);
+    } else
+        XShapeCombineMask(wsDisplay, win->WindowID, ShapeBounding, 0, 0, None, ShapeSet);
+#endif
+}
+
 /**
- * @brief Handle automatic hiding of the cursor.
+ * @brief Set differently sized icons to a window.
+ *
+ *        This function sets the X icon hint as well as
+ *        the properties KWM_WIN_ICON and _NET_WM_ICON.
+ *
+ * @param display display
+ * @param Win window
+ * @param icon pointer to the icons
  */
-void wsAutohideCursor(void)
+void wsSetIcon(Display *display, Window Win, guiIcon_t *icon)
 {
-    if (mouse_win && (GetTimerMS() - mouse_time >= MOUSEHIDE_DELAY)) {
-        wsVisibleMouse(mouse_win, wsHideMouseCursor);
-        mouse_win = NULL;
+    XWMHints *wm;
+    Atom iconatom;
+    long data[2];
+
+    if (icon->normal) {
+        wm = XGetWMHints(display, Win);
+
+        if (!wm)
+            wm = XAllocWMHints();
+
+        wm->icon_pixmap = icon->normal;
+        wm->icon_mask   = icon->normal_mask;
+        wm->flags      |= IconPixmapHint | IconMaskHint;
+
+        XSetWMHints(display, Win, wm);
+        XFree(wm);
+    }
+
+    if (icon->small || icon->normal) {
+        iconatom = XInternAtom(display, "KWM_WIN_ICON", False);
+        data[0]  = (icon->small ? icon->small : icon->normal);
+        data[1]  = (icon->small ? icon->small_mask : icon->normal_mask);
+
+        XChangeProperty(display, Win, iconatom, iconatom, 32, PropModeReplace, (unsigned char *)data, 2);
+    }
+
+    if (icon->collection) {
+        iconatom = XInternAtom(display, "_NET_WM_ICON", False);
+        XChangeProperty(display, Win, iconatom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)icon->collection, icon->collection_size);
     }
 }
 
 // ----------------------------------------------------------------------------------------------
-//   Handle events.
+//    Set window background to 'color'.
 // ----------------------------------------------------------------------------------------------
-
-void wsEvents(XEvent *event)
+void wsSetBackgroundRGB(wsWindow *win, int r, int g, int b)
 {
-    unsigned long i = 0;
-    int l;
-    int x, y;
-    Window child_window = 0;
-
-    l = wsSearch(event->xany.window);
-
-    if (l == -1)
-        return;
-
-    wsWindowList[l]->State = wsNone;
-
-    switch (event->type) {
-    case ClientMessage:
-
-        if (event->xclient.message_type == wsWindowList[l]->AtomProtocols) {
-            if ((Atom)event->xclient.data.l[0] == wsWindowList[l]->AtomDeleteWindow) {
-                i = wsWindowClosed;
-                goto expose;
-            }
-
-            if ((Atom)event->xclient.data.l[0] == wsWindowList[l]->AtomTakeFocus) {
-                i = wsWindowFocusIn;
-                wsWindowList[l]->Focused = wsFocused;
-                goto expose;
-            }
-
-            if ((Atom)event->xclient.data.l[0] == wsWindowList[l]->AtomRolle) {
-                mp_msg(MSGT_GPLAYER, MSGL_V, "[ws] role set.\n");
-            }
-        } else {
-            /* try to process DND events */
-            wsXDNDProcessClientMessage(&event->xclient);
-        }
-
-        break;
-
-    case MapNotify:
-
-        i = wsWindowMapped;
-        wsWindowList[l]->Mapped = wsMapped;
-        goto expose;
-
-    case UnmapNotify:
+    int color = 0;
 
-        i = wsWindowUnmapped;
-        wsWindowList[l]->Mapped = wsNo;
-        goto expose;
-
-    case FocusIn:
-
-        if (wsWindowList[l]->Focused == wsFocused)
-            break;
-
-        i = wsWindowFocusIn;
-        wsWindowList[l]->Focused = wsFocused;
-        goto expose;
-
-    case FocusOut:
-
-        if (wsWindowList[l]->Focused == wsNo)
-            break;
-
-        i = wsWindowFocusOut;
-        wsWindowList[l]->Focused = wsNo;
-        goto expose;
-
-    case VisibilityNotify:
-
-        switch (event->xvisibility.state) {
-        case VisibilityUnobscured:
-            i = wsWindowVisible;
-            wsWindowList[l]->Visible = wsVisible;
-            goto expose;
-
-        case VisibilityFullyObscured:
-            i = wsWindowNotVisible;
-            wsWindowList[l]->Visible = wsNotVisible;
-            goto expose;
-
-        case VisibilityPartiallyObscured:
-            i = wsWindowPartialVisible;
-            wsWindowList[l]->Visible = wsPVisible;
-            goto expose;
-        }
-
-expose:
-        wsWindowList[l]->State = i;
-
-        if (wsWindowList[l]->ReDraw)
-            wsWindowList[l]->ReDraw();
-
-        break;
-
-    case Expose:
-
-        wsWindowList[l]->State = wsWindowExpose;
-
-        if ((wsWindowList[l]->ReDraw) && (!event->xexpose.count))
-            wsWindowList[l]->ReDraw();
-
+    switch (wsOutMask) {
+    case wsRGB32:
+    case wsRGB24:
+        color = (r << 16) + (g << 8) + b;
         break;
 
-    case ConfigureNotify:
-
-        XTranslateCoordinates(wsDisplay, wsWindowList[l]->WindowID, wsRootWin, 0, 0, &x, &y, &child_window);
+    case wsBGR32:
+    case wsBGR24:
+        color = (b << 16) + (g << 8) + r;
+        break;
 
-        if ((wsWindowList[l]->X != x) || (wsWindowList[l]->Y != y) || (wsWindowList[l]->Width != event->xconfigure.width) || (wsWindowList[l]->Height != event->xconfigure.height)) {
-            wsWindowList[l]->X      = x;
-            wsWindowList[l]->Y      = y;
-            wsWindowList[l]->Width  = event->xconfigure.width;
-            wsWindowList[l]->Height = event->xconfigure.height;
-        }
-
-        wsWindowList[l]->Rolled = wsNo;
-
-        if (event->xconfigure.y < 0) {
-            i = wsWindowRolled;
-            wsWindowList[l]->Rolled = wsRolled;
-            goto expose;
-        }
-
+    case wsRGB16:
+        PACK_RGB16(b, g, r, color);
         break;
 
-    case KeyPress:
-
-        i = wsKeyPressed;
-        goto keypressed;
-
-    case KeyRelease:
-
-        i = wsKeyReleased;
-keypressed:
-        wsWindowList[l]->Alt      = False;
-        wsWindowList[l]->Shift    = False;
-        wsWindowList[l]->NumLock  = False;
-        wsWindowList[l]->Control  = False;
-        wsWindowList[l]->CapsLock = False;
-
-        if (event->xkey.state & Mod1Mask)
-            wsWindowList[l]->Alt = True;
-
-        if (event->xkey.state & Mod2Mask)
-            wsWindowList[l]->NumLock = True;
-
-        if (event->xkey.state & ControlMask)
-            wsWindowList[l]->Control = True;
-
-        if (event->xkey.state & ShiftMask)
-            wsWindowList[l]->Shift = True;
-
-        if (event->xkey.state & LockMask)
-            wsWindowList[l]->CapsLock = True;
-
-#if 0
-        {
-            KeySym keySym;
-            keySym = XKeycodeToKeysym(wsDisplay, event->xkey.keycode, 0);
-
-            if (keySym != NoSymbol) {
-                keySym = ((keySym & 0xff00) != 0 ? ((keySym & 0x00ff) + 256) : (keySym));
-
-                if (wsWindowList[l]->KeyHandler)
-                    wsWindowList[l]->KeyHandler(event->xkey.state, i, keySym);
-            }
-        }
-#else
-        {
-            int key;
-            char buf[100];
-            KeySym keySym;
-            static XComposeStatus stat;
-
-            XLookupString(&event->xkey, buf, sizeof(buf), &keySym, &stat);
-            key = ((keySym & 0xff00) != 0 ? ((keySym & 0x00ff) + 256) : (keySym));
-
-            if (wsWindowList[l]->KeyHandler)
-                wsWindowList[l]->KeyHandler(event->xkey.keycode, i, key);
-        }
-#endif
+    case wsBGR16:
+        PACK_RGB16(r, g, b, color);
         break;
 
-    case MotionNotify:
-
-        i = wsMoveMouse;
-        {
-            /* pump all motion events from the display queue:
-             * this way it works faster when moving the window */
-            static XEvent e;
-
-            if (event->xmotion.state) {
-                while (XCheckTypedWindowEvent(wsDisplay, event->xany.window, MotionNotify, &e)) {
-                    /* FIXME: need to make sure we didn't release/press the button in between...*/
-                    /* FIXME: do we need some timeout here to make sure we don't spend too much time
-                     * removing events from the queue? */
-                    event = &e;
-                }
-            }
-        }
-
-        if (wsWindowList[l]->wsCursor != None) {
-            wsVisibleMouse(wsWindowList[l], wsShowMouseCursor);
-            mouse_win  = wsWindowList[l];
-            mouse_time = GetTimerMS();
-        }
-
-        goto buttonreleased;
-
-    case ButtonRelease:
-
-        i = event->xbutton.button + 128;
-
-        if (wsWindowList[l]->wsCursor != None) {
-            wsVisibleMouse(wsWindowList[l], wsShowMouseCursor);
-            mouse_win  = wsWindowList[l];
-            mouse_time = GetTimerMS();
-        }
-
-        goto buttonreleased;
-
-    case ButtonPress:
-
-        i = event->xbutton.button;
-
-        if (wsWindowList[l]->wsCursor != None) {
-            wsVisibleMouse(wsWindowList[l], wsShowMouseCursor);
-            mouse_win  = wsWindowList[l];
-            mouse_time = GetTimerMS();
-        }
-
-        goto buttonreleased;
-
-    case EnterNotify:
-
-        i = wsEnterWindow;
-        goto buttonreleased;
-
-    case LeaveNotify:
-
-        i = wsLeaveWindow;
-buttonreleased:
-
-        if (wsWindowList[l]->MouseHandler)
-            wsWindowList[l]->MouseHandler(i, event->xbutton.x, event->xbutton.y, event->xmotion.x_root, event->xmotion.y_root);
-
+    case wsRGB15:
+        PACK_RGB15(b, g, r, color);
         break;
 
-    case SelectionNotify:
-
-        /* Handle DandD */
-        wsXDNDProcessSelection(wsWindowList[l], event);
+    case wsBGR15:
+        PACK_RGB15(r, g, b, color);
         break;
     }
 
-    XFlush(wsDisplay);
-    XSync(wsDisplay, False);
-}
-
-void wsHandleEvents(void)
-{
-    XEvent wsEvent;
-    /* handle pending events */
-    while (XPending(wsDisplay)) {
-        XNextEvent(wsDisplay, &wsEvent);
-//   printf("### X event: %d  [%d]\n",wsEvent.type,delay);
-        wsEvents(&wsEvent);
-    }
-}
-
-// ----------------------------------------------------------------------------------------------
-//    Move window to selected layer
-// ----------------------------------------------------------------------------------------------
-
-/**
- * @brief Set the layer for a window.
- *
- * @param display display
- * @param Win window
- * @param fullscreen whether to set fullscreen or normal layer
- */
-void wsSetLayer(Display *display, Window Win, Bool fullscreen)
-{
-    vo_x11_setlayer(display, Win, fullscreen);
+    XSetWindowBackground(wsDisplay, win->WindowID, color);
 }
 
 /**
- * @brief Switch window fullscreen state.
- *
- *        Switch normal window to fullscreen and fullscreen window to normal.
+ * @brief Clear the entire area in a window.
  *
  * @param win pointer to a ws window structure
  */
-void wsFullScreen(wsWindow *win)
-{
-    if (win->isFullScreen) {
-        if (vo_fs_type & vo_wm_FULLSCREEN)
-            /* window manager supports EWMH */
-            vo_x11_ewmh_fullscreen(win->WindowID, _NET_WM_STATE_REMOVE);
-        else {
-            win->X      = win->OldX;
-            win->Y      = win->OldY;
-            win->Width  = win->OldWidth;
-            win->Height = win->OldHeight;
-        }
-
-        win->isFullScreen = False;
-    } else {
-        if (vo_fs_type & vo_wm_FULLSCREEN)
-            /* window manager supports EWMH */
-            vo_x11_ewmh_fullscreen(win->WindowID, _NET_WM_STATE_ADD);
-        else {
-            win->OldX      = win->X;
-            win->OldY      = win->Y;
-            win->OldWidth  = win->Width;
-            win->OldHeight = win->Height;
-        }
-
-        win->isFullScreen = True;
-
-        wsUpdateXineramaInfo(win);
-    }
-
-    /* unknown window manager and obsolete option -fsmode used */
-    if (vo_wm_type == 0 && !(vo_fsmode & 16)) {
-        XUnmapWindow(wsDisplay, win->WindowID); // required for MWM
-        XWithdrawWindow(wsDisplay, win->WindowID, wsScreen);
-    }
-
-    /* restore window if window manager doesn't support EWMH */
-    if (!(vo_fs_type & vo_wm_FULLSCREEN)) {
-        wsSizeHint(win);
-        wsWindowDecoration(win, win->Decorations && !win->isFullScreen);
-        wsSetLayer(wsDisplay, win->WindowID, win->isFullScreen);
-        XMoveResizeWindow(wsDisplay, win->WindowID, win->X, win->Y, win->Width, win->Height);
-    }
-
-    /* some window managers lose ontop after fullscreen */
-    if (!win->isFullScreen & vo_ontop)
-        wsSetLayer(wsDisplay, win->WindowID, vo_ontop);
-
-    wsRaiseWindowTop(wsDisplay, win->WindowID);
-    XFlush(wsDisplay);
-}
-
-// ----------------------------------------------------------------------------------------------
-//    Redraw screen.
-// ----------------------------------------------------------------------------------------------
-void wsPostRedisplay(wsWindow *win)
+void wsClearWindow(wsWindow *win)
 {
-    if (win->ReDraw) {
-        win->State = wsWindowExpose;
-        win->ReDraw();
-        XFlush(wsDisplay);
-    }
-}
-
-// ----------------------------------------------------------------------------------------------
-//    Put 'Image' to window.
-// ----------------------------------------------------------------------------------------------
-void wsConvert(wsWindow *win, unsigned char *Image)
-{
-    static struct SwsContext *sws_ctx;
-    const uint8_t *src[4] = { Image, NULL, NULL, NULL };
-    int src_stride[4]     = { 4 * win->xImage->width, 0, 0, 0 };
-    uint8_t *dst[4]       = { win->ImageData, NULL, NULL, NULL };
-    int dst_stride[4];
-    int i;
-
-    sws_ctx = sws_getCachedContext(sws_ctx, win->xImage->width, win->xImage->height, PIX_FMT_RGB32,
-                                   win->xImage->width, win->xImage->height, out_pix_fmt,
-                                   SWS_POINT, NULL, NULL, NULL);
-    av_image_fill_linesizes(dst_stride, out_pix_fmt, win->xImage->width);
-    sws_scale(sws_ctx, src, src_stride, 0, win->xImage->height, dst, dst_stride);
-
-    if (!wsNonNativeOrder)
-        return;
-
-    switch (win->xImage->bits_per_pixel) {
-    case 32:
-    {
-        uint32_t *d = (uint32_t *)win->ImageData;
-
-        for (i = 0; i < win->xImage->width * win->xImage->height; i++)
-            d[i] = bswap_32(d[i]);
-
-        break;
-    }
-
-    case 16:
-    case 15:
-    {
-        uint16_t *d = (uint16_t *)win->ImageData;
-
-        for (i = 0; i < win->xImage->width * win->xImage->height; i++)
-            d[i] = bswap_16(d[i]);
-
-        break;
-    }
-    }
-}
-
-void wsPutImage(wsWindow *win)
-{
-#ifdef HAVE_SHM
-    if (wsUseXShm) {
-        XShmPutImage(wsDisplay, win->WindowID, win->wGC, win->xImage,
-                     0, 0,
-                     (win->Width - win->xImage->width) / 2, (win->Height - win->xImage->height) / 2,
-                     win->xImage->width, win->xImage->height, 0);
-    } else
-#endif
-    {
-        XPutImage(wsDisplay, win->WindowID, win->wGC, win->xImage,
-                  0, 0,
-                  (win->Width - win->xImage->width) / 2, (win->Height - win->xImage->height) / 2,
-                  win->xImage->width, win->xImage->height);
-    }
+    XClearWindow(wsDisplay, win->WindowID);
 }
 
 // ----------------------------------------------------------------------------------------------
@@ -1192,6 +1217,65 @@
 }
 
 /**
+ * @brief Switch window fullscreen state.
+ *
+ *        Switch normal window to fullscreen and fullscreen window to normal.
+ *
+ * @param win pointer to a ws window structure
+ */
+void wsFullScreen(wsWindow *win)
+{
+    if (win->isFullScreen) {
+        if (vo_fs_type & vo_wm_FULLSCREEN)
+            /* window manager supports EWMH */
+            vo_x11_ewmh_fullscreen(win->WindowID, _NET_WM_STATE_REMOVE);
+        else {
+            win->X      = win->OldX;
+            win->Y      = win->OldY;
+            win->Width  = win->OldWidth;
+            win->Height = win->OldHeight;
+        }
+
+        win->isFullScreen = False;
+    } else {
+        if (vo_fs_type & vo_wm_FULLSCREEN)
+            /* window manager supports EWMH */
+            vo_x11_ewmh_fullscreen(win->WindowID, _NET_WM_STATE_ADD);
+        else {
+            win->OldX      = win->X;
+            win->OldY      = win->Y;
+            win->OldWidth  = win->Width;
+            win->OldHeight = win->Height;
+        }
+
+        win->isFullScreen = True;
+
+        wsUpdateXineramaInfo(win);
+    }
+
+    /* unknown window manager and obsolete option -fsmode used */
+    if (vo_wm_type == 0 && !(vo_fsmode & 16)) {
+        XUnmapWindow(wsDisplay, win->WindowID); // required for MWM
+        XWithdrawWindow(wsDisplay, win->WindowID, wsScreen);
+    }
+
+    /* restore window if window manager doesn't support EWMH */
+    if (!(vo_fs_type & vo_wm_FULLSCREEN)) {
+        wsSizeHint(win);
+        wsWindowDecoration(win, win->Decorations && !win->isFullScreen);
+        wsSetLayer(wsDisplay, win->WindowID, win->isFullScreen);
+        XMoveResizeWindow(wsDisplay, win->WindowID, win->X, win->Y, win->Width, win->Height);
+    }
+
+    /* some window managers lose ontop after fullscreen */
+    if (!win->isFullScreen & vo_ontop)
+        wsSetLayer(wsDisplay, win->WindowID, vo_ontop);
+
+    wsRaiseWindowTop(wsDisplay, win->WindowID);
+    XFlush(wsDisplay);
+}
+
+/**
  * @brief Iconify a window.
  *
  * @param win pointer to a ws window structure
@@ -1201,131 +1285,6 @@
     XIconifyWindow(wsDisplay, win->WindowID, 0);
 }
 
-/**
- * @brief Map a window and raise it to the top.
- *
- * @param display display
- * @param Win window
- */
-void wsRaiseWindowTop(Display *display, Window Win)
-{
-    XMapRaised(display, Win);     // NOTE TO MYSELF: is that really enough?
-    XRaiseWindow(display, Win);   // NOTE TO MYSELF: is that really enough?
-}
-
-// ----------------------------------------------------------------------------------------------
-//    Set window background to 'color'.
-// ----------------------------------------------------------------------------------------------
-void wsSetBackgroundRGB(wsWindow *win, int r, int g, int b)
-{
-    int color = 0;
-
-    switch (wsOutMask) {
-    case wsRGB32:
-    case wsRGB24:
-        color = (r << 16) + (g << 8) + b;
-        break;
-
-    case wsBGR32:
-    case wsBGR24:
-        color = (b << 16) + (g << 8) + r;
-        break;
-
-    case wsRGB16:
-        PACK_RGB16(b, g, r, color);
-        break;
-
-    case wsBGR16:
-        PACK_RGB16(r, g, b, color);
-        break;
-
-    case wsRGB15:
-        PACK_RGB15(b, g, r, color);
-        break;
-
-    case wsBGR15:
-        PACK_RGB15(r, g, b, color);
-        break;
-    }
-
-    XSetWindowBackground(wsDisplay, win->WindowID, color);
-}
-
-// ----------------------------------------------------------------------------------------------
-//    Show / hide mouse cursor.
-// ----------------------------------------------------------------------------------------------
-void wsVisibleMouse(wsWindow *win, int m)
-{
-    switch (m) {
-    case wsShowMouseCursor:
-
-        if (win->wsCursor != None) {
-            XFreeCursor(wsDisplay, win->wsCursor);
-            win->wsCursor = None;
-        }
-
-        XDefineCursor(wsDisplay, win->WindowID, 0);
-        break;
-
-    case wsHideMouseCursor:
-
-        win->wsCursor = XCreatePixmapCursor(wsDisplay, win->wsCursorPixmap, win->wsCursorPixmap, &win->wsColor, &win->wsColor, 0, 0);
-        XDefineCursor(wsDisplay, win->WindowID, win->wsCursor);
-        break;
-    }
-
-    XFlush(wsDisplay);
-}
-
-int wsGetDepthOnScreen(void)
-{
-    int depth;
-    XImage *mXImage;
-    Visual *visual;
-
-    if ((depth = vo_find_depth_from_visuals(wsDisplay, wsScreen, &visual)) > 0) {
-        mXImage = XCreateImage(wsDisplay, visual, depth, ZPixmap, 0, NULL,
-                               1, 1, 32, 0);
-        wsDepthOnScreen = mXImage->bits_per_pixel;
-        wsRedMask       = mXImage->red_mask;
-        wsGreenMask     = mXImage->green_mask;
-        wsBlueMask      = mXImage->blue_mask;
-#if HAVE_BIGENDIAN
-        wsNonNativeOrder = mXImage->byte_order == LSBFirst;
-#else
-        wsNonNativeOrder = mXImage->byte_order == MSBFirst;
-#endif
-        XDestroyImage(mXImage);
-    } else {
-        int bpp, ibpp;
-        XWindowAttributes attribs;
-
-        mXImage = XGetImage(wsDisplay, wsRootWin, 0, 0, 1, 1, AllPlanes, ZPixmap);
-        bpp     = mXImage->bits_per_pixel;
-
-        XGetWindowAttributes(wsDisplay, wsRootWin, &attribs);
-        ibpp    = attribs.depth;
-        mXImage = XGetImage(wsDisplay, wsRootWin, 0, 0, 1, 1, AllPlanes, ZPixmap);
-        bpp     = mXImage->bits_per_pixel;
-
-        if ((ibpp + 7) / 8 != (bpp + 7) / 8)
-            ibpp = bpp;
-
-        wsDepthOnScreen = ibpp;
-        wsRedMask       = mXImage->red_mask;
-        wsGreenMask     = mXImage->green_mask;
-        wsBlueMask      = mXImage->blue_mask;
-        XDestroyImage(mXImage);
-    }
-
-    return wsDepthOnScreen;
-}
-
-void wsXDone(void)
-{
-    XCloseDisplay(wsDisplay);
-}
-
 void wsVisibleWindow(wsWindow *win, int show)
 {
     switch (show) {
@@ -1348,22 +1307,49 @@
     XFlush(wsDisplay);
 }
 
-void wsDestroyImage(wsWindow *win)
+/**
+ * @brief Map a window and raise it to the top.
+ *
+ * @param display display
+ * @param Win window
+ */
+void wsRaiseWindowTop(Display *display, Window Win)
 {
-    if (win->xImage) {
-        XDestroyImage(win->xImage);
-
-#ifdef HAVE_SHM
-        if (wsUseXShm) {
-            XShmDetach(wsDisplay, &win->Shminfo);
-            shmdt(win->Shminfo.shmaddr);
-        }
-#endif
-    }
-
-    win->xImage = NULL;
+    XMapRaised(display, Win);     // NOTE TO MYSELF: is that really enough?
+    XRaiseWindow(display, Win);   // NOTE TO MYSELF: is that really enough?
 }
 
+// ----------------------------------------------------------------------------------------------
+//    Move window to selected layer
+// ----------------------------------------------------------------------------------------------
+
+/**
+ * @brief Set the layer for a window.
+ *
+ * @param display display
+ * @param Win window
+ * @param fullscreen whether to set fullscreen or normal layer
+ */
+void wsSetLayer(Display *display, Window Win, Bool fullscreen)
+{
+    vo_x11_setlayer(display, Win, fullscreen);
+}
+
+// ----------------------------------------------------------------------------------------------
+//    Redraw screen.
+// ----------------------------------------------------------------------------------------------
+void wsPostRedisplay(wsWindow *win)
+{
+    if (win->ReDraw) {
+        win->State = wsWindowExpose;
+        win->ReDraw();
+        XFlush(wsDisplay);
+    }
+}
+
+// ----------------------------------------------------------------------------------------------
+//    Put 'Image' to window.
+// ----------------------------------------------------------------------------------------------
 void wsCreateImage(wsWindow *win, int Width, int Height)
 {
 #ifdef HAVE_SHM
@@ -1420,111 +1406,121 @@
     win->ImageDatadw = (unsigned int *)win->xImage->data;
 }
 
+void wsDestroyImage(wsWindow *win)
+{
+    if (win->xImage) {
+        XDestroyImage(win->xImage);
+
+#ifdef HAVE_SHM
+        if (wsUseXShm) {
+            XShmDetach(wsDisplay, &win->Shminfo);
+            shmdt(win->Shminfo.shmaddr);
+        }
+#endif
+    }
+
+    win->xImage = NULL;
+}
+
+void wsConvert(wsWindow *win, unsigned char *Image)
+{
+    static struct SwsContext *sws_ctx;
+    const uint8_t *src[4] = { Image, NULL, NULL, NULL };
+    int src_stride[4]     = { 4 * win->xImage->width, 0, 0, 0 };
+    uint8_t *dst[4]       = { win->ImageData, NULL, NULL, NULL };
+    int dst_stride[4];
+    int i;
+
+    sws_ctx = sws_getCachedContext(sws_ctx, win->xImage->width, win->xImage->height, PIX_FMT_RGB32,
+                                   win->xImage->width, win->xImage->height, out_pix_fmt,
+                                   SWS_POINT, NULL, NULL, NULL);
+    av_image_fill_linesizes(dst_stride, out_pix_fmt, win->xImage->width);
+    sws_scale(sws_ctx, src, src_stride, 0, win->xImage->height, dst, dst_stride);
+
+    if (!wsNonNativeOrder)
+        return;
+
+    switch (win->xImage->bits_per_pixel) {
+    case 32:
+    {
+        uint32_t *d = (uint32_t *)win->ImageData;
+
+        for (i = 0; i < win->xImage->width * win->xImage->height; i++)
+            d[i] = bswap_32(d[i]);
+
+        break;
+    }
+
+    case 16:
+    case 15:
+    {
+        uint16_t *d = (uint16_t *)win->ImageData;
+
+        for (i = 0; i < win->xImage->width * win->xImage->height; i++)
+            d[i] = bswap_16(d[i]);
+
+        break;
+    }
+    }
+}
+
+void wsPutImage(wsWindow *win)
+{
+#ifdef HAVE_SHM
+    if (wsUseXShm) {
+        XShmPutImage(wsDisplay, win->WindowID, win->wGC, win->xImage,
+                     0, 0,
+                     (win->Width - win->xImage->width) / 2, (win->Height - win->xImage->height) / 2,
+                     win->xImage->width, win->xImage->height, 0);
+    } else
+#endif
+    {
+        XPutImage(wsDisplay, win->WindowID, win->wGC, win->xImage,
+                  0, 0,
+                  (win->Width - win->xImage->width) / 2, (win->Height - win->xImage->height) / 2,
+                  win->xImage->width, win->xImage->height);
+    }
+}
+
 void wsResizeImage(wsWindow *win, int Width, int Height)
 {
     wsDestroyImage(win);
     wsCreateImage(win, Width, Height);
 }
 
-int wsGetOutMask(void)
+// ----------------------------------------------------------------------------------------------
+//    Show / hide mouse cursor.
+// ----------------------------------------------------------------------------------------------
+void wsVisibleMouse(wsWindow *win, int m)
 {
-    if ((wsDepthOnScreen == 32) && (wsRedMask == 0xff0000) && (wsGreenMask == 0x00ff00) && (wsBlueMask == 0x0000ff))
-        return wsRGB32;
-
-    if ((wsDepthOnScreen == 32) && (wsRedMask == 0x0000ff) && (wsGreenMask == 0x00ff00) && (wsBlueMask == 0xff0000))
-        return wsBGR32;
-
-    if ((wsDepthOnScreen == 24) && (wsRedMask == 0xff0000) && (wsGreenMask == 0x00ff00) && (wsBlueMask == 0x0000ff))
-        return wsRGB24;
-
-    if ((wsDepthOnScreen == 24) && (wsRedMask == 0x0000ff) && (wsGreenMask == 0x00ff00) && (wsBlueMask == 0xff0000))
-        return wsBGR24;
+    switch (m) {
+    case wsShowMouseCursor:
 
-    if ((wsDepthOnScreen == 16) && (wsRedMask == 0xf800) && (wsGreenMask == 0x7e0) && (wsBlueMask == 0x1f))
-        return wsRGB16;
+        if (win->wsCursor != None) {
+            XFreeCursor(wsDisplay, win->wsCursor);
+            win->wsCursor = None;
+        }
 
-    if ((wsDepthOnScreen == 16) && (wsRedMask == 0x1f) && (wsGreenMask == 0x7e0) && (wsBlueMask == 0xf800))
-        return wsBGR16;
+        XDefineCursor(wsDisplay, win->WindowID, 0);
+        break;
 
-    if ((wsDepthOnScreen == 15) && (wsRedMask == 0x7c00) && (wsGreenMask == 0x3e0) && (wsBlueMask == 0x1f))
-        return wsRGB15;
+    case wsHideMouseCursor:
 
-    if ((wsDepthOnScreen == 15) && (wsRedMask == 0x1f) && (wsGreenMask == 0x3e0) && (wsBlueMask == 0x7c00))
-        return wsBGR15;
+        win->wsCursor = XCreatePixmapCursor(wsDisplay, win->wsCursorPixmap, win->wsCursorPixmap, &win->wsColor, &win->wsColor, 0, 0);
+        XDefineCursor(wsDisplay, win->WindowID, win->wsCursor);
+        break;
+    }
 
-    return 0;
+    XFlush(wsDisplay);
 }
 
 /**
- * @brief Clear the entire area in a window.
- *
- * @param win pointer to a ws window structure
+ * @brief Handle automatic hiding of the cursor.
  */
-void wsClearWindow(wsWindow *win)
-{
-    XClearWindow(wsDisplay, win->WindowID);
-}
-
-void wsSetTitle(wsWindow *win, char *name)
-{
-    XStoreName(wsDisplay, win->WindowID, name);
-}
-
-void wsSetShape(wsWindow *win, char *data)
+void wsAutohideCursor(void)
 {
-#ifdef CONFIG_XSHAPE
-    if (!wsUseXShape)
-        return;
-
-    if (data) {
-        win->Mask = XCreateBitmapFromData(wsDisplay, win->WindowID, data, win->Width, win->Height);
-        XShapeCombineMask(wsDisplay, win->WindowID, ShapeBounding, 0, 0, win->Mask, ShapeSet);
-        XFreePixmap(wsDisplay, win->Mask);
-    } else
-        XShapeCombineMask(wsDisplay, win->WindowID, ShapeBounding, 0, 0, None, ShapeSet);
-#endif
-}
-
-/**
- * @brief Set differently sized icons to a window.
- *
- *        This function sets the X icon hint as well as
- *        the properties KWM_WIN_ICON and _NET_WM_ICON.
- *
- * @param display display
- * @param Win window
- * @param icon pointer to the icons
- */
-void wsSetIcon(Display *display, Window Win, guiIcon_t *icon)
-{
-    XWMHints *wm;
-    Atom iconatom;
-    long data[2];
-
-    if (icon->normal) {
-        wm = XGetWMHints(display, Win);
-
-        if (!wm)
-            wm = XAllocWMHints();
-
-        wm->icon_pixmap = icon->normal;
-        wm->icon_mask   = icon->normal_mask;
-        wm->flags      |= IconPixmapHint | IconMaskHint;
-
-        XSetWMHints(display, Win, wm);
-        XFree(wm);
-    }
-
-    if (icon->small || icon->normal) {
-        iconatom = XInternAtom(display, "KWM_WIN_ICON", False);
-        data[0]  = (icon->small ? icon->small : icon->normal);
-        data[1]  = (icon->small ? icon->small_mask : icon->normal_mask);
-
-        XChangeProperty(display, Win, iconatom, iconatom, 32, PropModeReplace, (unsigned char *)data, 2);
-    }
-
-    if (icon->collection) {
-        iconatom = XInternAtom(display, "_NET_WM_ICON", False);
-        XChangeProperty(display, Win, iconatom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)icon->collection, icon->collection_size);
+    if (mouse_win && (GetTimerMS() - mouse_time >= MOUSEHIDE_DELAY)) {
+        wsVisibleMouse(mouse_win, wsHideMouseCursor);
+        mouse_win = NULL;
     }
 }