[vlc-commits] xcb: handle cursor automatically (refs #18661)

Rémi Denis-Courmont git at videolan.org
Sun May 20 19:51:27 CEST 2018


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Fri May 18 16:20:41 2018 +0300| [624939fa27267dc56e3855e787cdfa08db243961] | committer: Rémi Denis-Courmont

xcb: handle cursor automatically (refs #18661)

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=624939fa27267dc56e3855e787cdfa08db243961
---

 modules/video_output/xcb/window.c | 97 +++++++++++++++++++++++++--------------
 1 file changed, 63 insertions(+), 34 deletions(-)

diff --git a/modules/video_output/xcb/window.c b/modules/video_output/xcb/window.c
index 26853f4011..fe201d85c8 100644
--- a/modules/video_output/xcb/window.c
+++ b/modules/video_output/xcb/window.c
@@ -48,8 +48,6 @@ struct vout_window_sys_t
 #endif
     vlc_thread_t thread;
 
-    xcb_cursor_t cursor; /* blank cursor */
-
     xcb_window_t root;
     xcb_atom_t wm_state;
     xcb_atom_t wm_state_above;
@@ -59,13 +57,24 @@ struct vout_window_sys_t
     bool embedded;
 };
 
-static void ProcessEvent (vout_window_t *wnd, xcb_generic_event_t *ev)
+static xcb_cursor_t CursorCreate(xcb_connection_t *conn, xcb_window_t root)
+{
+    xcb_cursor_t cur = xcb_generate_id(conn);
+    xcb_pixmap_t pix = xcb_generate_id(conn);
+
+    xcb_create_pixmap(conn, 1, pix, root, 1, 1);
+    xcb_create_cursor(conn, cur, pix, pix, 0, 0, 0, 0, 0, 0, 1, 1);
+    return cur;
+}
+
+static int ProcessEvent(vout_window_t *wnd, xcb_generic_event_t *ev)
 {
     vout_window_sys_t *sys = wnd->sys;
+    int ret = 0;
 
 #ifdef HAVE_XCB_KEYSYMS
     if (sys->keys != NULL && XCB_keyHandler_Process(sys->keys, ev, wnd) == 0)
-        return;
+        return 0;
 #endif
 
     switch (ev->response_type & 0x7f)
@@ -74,21 +83,27 @@ static void ProcessEvent (vout_window_t *wnd, xcb_generic_event_t *ev)
         case XCB_BUTTON_PRESS:
         {
             xcb_button_release_event_t *bpe = (void *)ev;
+
             vout_window_ReportMousePressed(wnd, bpe->detail - 1);
+            ret = 1;
             break;
         }
 
         case XCB_BUTTON_RELEASE:
         {
             xcb_button_release_event_t *bre = (void *)ev;
+
             vout_window_ReportMouseReleased(wnd, bre->detail - 1);
+            ret = 1;
             break;
         }
 
         case XCB_MOTION_NOTIFY:
         {
             xcb_motion_notify_event_t *mne = (void *)ev;
+
             vout_window_ReportMouseMoved(wnd, mne->event_x, mne->event_y);
+            ret = 1;
             break;
         }
 
@@ -110,6 +125,7 @@ static void ProcessEvent (vout_window_t *wnd, xcb_generic_event_t *ev)
     }
 
     free (ev);
+    return ret;
 }
 
 /** Background thread for X11 events handling */
@@ -118,21 +134,57 @@ static void *Thread (void *data)
     vout_window_t *wnd = data;
     vout_window_sys_t *p_sys = wnd->sys;
     xcb_connection_t *conn = p_sys->conn;
+    struct pollfd ufd = {
+        .fd = xcb_get_file_descriptor(conn),
+        .events = POLLIN,
+    };
+    xcb_cursor_t cursor = CursorCreate(conn, p_sys->root); /* blank cursor */
+    mtime_t lifetime = var_InheritInteger(wnd, "mouse-hide-timeout")
+                       * (CLOCK_FREQ / 1000);
+    mtime_t deadline = INT64_MAX;
 
-    int fd = xcb_get_file_descriptor (conn);
-    if (fd == -1)
+    if (ufd.fd == -1)
         return NULL;
 
     for (;;)
     {
-        xcb_generic_event_t *ev;
-        struct pollfd ufd = { .fd = fd, .events = POLLIN, };
+        int timeout = -1;
 
-        poll (&ufd, 1, -1);
+        if (deadline != INT64_MAX)
+        {
+            mtime_t delay = deadline - mdate();
+            timeout = (delay > 0) ? delay / (CLOCK_FREQ / 1000) : 0;
+        }
+
+        int val = poll(&ufd, 1, timeout);
 
         int canc = vlc_savecancel ();
-        while ((ev = xcb_poll_for_event (conn)) != NULL)
-            ProcessEvent(wnd, ev);
+
+        if (val == 0)
+        {   /* timeout: hide cursor */
+            xcb_change_window_attributes(conn, wnd->handle.xid,
+                                         XCB_CW_CURSOR, &cursor);
+            xcb_flush(conn);
+            deadline = INT64_MAX;
+        }
+        else
+        {
+            xcb_generic_event_t *ev;
+            bool show_cursor = false;
+
+            while ((ev = xcb_poll_for_event (conn)) != NULL)
+                show_cursor = ProcessEvent(wnd, ev) || show_cursor;
+
+            if (show_cursor)
+            {
+                xcb_change_window_attributes(conn, wnd->handle.xid,
+                                             XCB_CW_CURSOR,
+                                             &(uint32_t){ XCB_CURSOR_NONE });
+                xcb_flush(conn);
+                deadline = mdate() + lifetime;
+            }
+        }
+
         vlc_restorecancel (canc);
 
         if (xcb_connection_has_error (conn))
@@ -225,14 +277,6 @@ static int Control (vout_window_t *wnd, int cmd, va_list ap)
             change_wm_state (wnd, fs, p_sys->wm_state_fullscreen);
             break;
         }
-        case VOUT_WINDOW_HIDE_MOUSE:
-        {
-            xcb_cursor_t cursor = (va_arg (ap, int) ? p_sys->cursor
-                                                    : XCB_CURSOR_NONE);
-            xcb_change_window_attributes (p_sys->conn, wnd->handle.xid,
-                                          XCB_CW_CURSOR, &(uint32_t){ cursor });
-            break;
-        }
 
         default:
             msg_Err (wnd, "request %d not implemented", cmd);
@@ -313,18 +357,6 @@ xcb_atom_t get_atom (xcb_connection_t *conn, xcb_intern_atom_cookie_t ck)
     return atom;
 }
 
-static
-xcb_cursor_t CursorCreate(xcb_connection_t *conn,
-                                   const xcb_screen_t *scr)
-{
-    xcb_cursor_t cur = xcb_generate_id (conn);
-    xcb_pixmap_t pix = xcb_generate_id (conn);
-
-    xcb_create_pixmap (conn, 1, pix, scr->root, 1, 1);
-    xcb_create_cursor (conn, cur, pix, pix, 0, 0, 0, 0, 0, 0, 1, 1);
-    return cur;
-}
-
 static void CacheAtoms (vout_window_sys_t *p_sys)
 {
     xcb_connection_t *conn = p_sys->conn;
@@ -504,9 +536,6 @@ static int Open (vout_window_t *wnd, const vout_window_cfg_t *cfg)
         goto error;
     }
 
-    /* Create cursor */
-    p_sys->cursor = CursorCreate(conn, scr);
-
     xcb_flush (conn); /* Make sure map_window is sent (should be useless) */
     return VLC_SUCCESS;
 



More information about the vlc-commits mailing list