Improve display locking and rework X event wait functions.
authorgb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Mon, 22 Mar 2010 16:01:34 +0000 (16:01 +0000)
committergb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Mon, 22 Mar 2010 16:01:34 +0000 (16:01 +0000)
gst-libs/gst/vaapi/gstvaapiutils_x11.c
gst-libs/gst/vaapi/gstvaapiutils_x11.h
gst-libs/gst/vaapi/gstvaapiwindow_x11.c

index 1cfb66bd00737524ce6afd028836ea1df4d636a1..cb9bfc8edeaf8c941f665ab6c39688d14df47d65 100644 (file)
@@ -130,10 +130,3 @@ x11_get_geometry(
     if (pheight) *pheight = height;
     return TRUE;
 }
-
-void x11_wait_event(Display *dpy, Window w, int type)
-{
-    XEvent e;
-    while (!XCheckTypedWindowEvent(dpy, w, type, &e))
-        g_usleep(10);
-}
index 402f00817f16ea8b6cb1b3a87224b9e6cac66bdf..b66e5c165e4e5723ef7b569a173b6a8c5f7eddb2 100644 (file)
@@ -45,7 +45,4 @@ x11_get_geometry(
     guint      *pheight
 ) attribute_hidden;
 
-void x11_wait_event(Display *dpy, Window w, int type)
-    attribute_hidden;
-
 #endif /* GST_VAAPI_UTILS_X11_H */
index b58ad95a0f2daf48712004d7ad466c73716910fe..799894971621ee52583c9549c3cc1ca6fbbbfedd 100644 (file)
@@ -60,12 +60,11 @@ enum {
 #define _NET_WM_STATE_ADD       1 /* add/set property      */
 #define _NET_WM_STATE_TOGGLE    2 /* toggle property       */
 
-static gboolean
+static void
 send_wmspec_change_state(GstVaapiWindowX11 *window, Atom state, gboolean add)
 {
     GstVaapiWindowX11Private * const priv = window->priv;
     Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display);
-    gboolean has_errors;
     XClientMessageEvent xclient;
 
     memset(&xclient, 0, sizeof(xclient));
@@ -81,8 +80,6 @@ send_wmspec_change_state(GstVaapiWindowX11 *window, Atom state, gboolean add)
     xclient.data.l[3] = 0;
     xclient.data.l[4] = 0;
 
-    GST_VAAPI_DISPLAY_LOCK(priv->display);
-    x11_trap_errors();
     XSendEvent(
         dpy,
         DefaultRootWindow(dpy),
@@ -90,9 +87,58 @@ send_wmspec_change_state(GstVaapiWindowX11 *window, Atom state, gboolean add)
         SubstructureRedirectMask|SubstructureNotifyMask,
         (XEvent *)&xclient
     );
-    has_errors = x11_untrap_errors() != 0;
+}
+
+static void
+wait_event(GstVaapiWindow *window, int type)
+{
+    GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv;
+    Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display);
+    XEvent e;
+    Bool got_event;
+
+    for (;;) {
+        GST_VAAPI_DISPLAY_LOCK(priv->display);
+        got_event = XCheckTypedWindowEvent(dpy, priv->xid, type, &e);
+        GST_VAAPI_DISPLAY_UNLOCK(priv->display);
+        if (got_event)
+            break;
+        g_usleep(10);
+    }
+}
+
+static gboolean
+timed_wait_event(GstVaapiWindow *window, int type, guint64 end_time, XEvent *e)
+{
+    GstVaapiWindowX11Private * const priv = GST_VAAPI_WINDOW_X11(window)->priv;
+    Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display);
+    XEvent tmp_event;
+    GTimeVal now;
+    guint64 now_time;
+    Bool got_event;
+
+    if (!e)
+        e = &tmp_event;
+
+    GST_VAAPI_DISPLAY_LOCK(priv->display);
+    got_event = XCheckTypedWindowEvent(dpy, priv->xid, type, e);
     GST_VAAPI_DISPLAY_UNLOCK(priv->display);
-    return !has_errors;
+    if (got_event)
+        return TRUE;
+
+    do {
+        g_usleep(10);
+        GST_VAAPI_DISPLAY_LOCK(priv->display);
+        got_event = XCheckTypedWindowEvent(dpy, priv->xid, type, e);
+        GST_VAAPI_DISPLAY_UNLOCK(priv->display);
+        if (got_event) {
+            g_print("HERE\n");
+            return TRUE;
+        }
+        g_get_current_time(&now);
+        now_time = (guint64)now.tv_sec * 1000000 + now.tv_usec;
+    } while (now_time < end_time);
+    return FALSE;
 }
 
 static gboolean
@@ -108,13 +154,14 @@ gst_vaapi_window_x11_show(GstVaapiWindow *window)
     GST_VAAPI_DISPLAY_LOCK(priv->display);
     x11_trap_errors();
     XMapWindow(dpy, priv->xid);
-    if (priv->create_window)
-        x11_wait_event(dpy, priv->xid, MapNotify);
     has_errors = x11_untrap_errors() != 0;
     GST_VAAPI_DISPLAY_UNLOCK(priv->display);
     if (has_errors)
         return FALSE;
 
+    if (priv->create_window)
+        wait_event(window, MapNotify);
+
     priv->is_mapped = TRUE;
     return TRUE;
 }
@@ -132,13 +179,14 @@ gst_vaapi_window_x11_hide(GstVaapiWindow *window)
     GST_VAAPI_DISPLAY_LOCK(priv->display);
     x11_trap_errors();
     XUnmapWindow(dpy, priv->xid);
-    if (priv->create_window)
-        x11_wait_event(dpy, priv->xid, UnmapNotify);
     has_errors = x11_untrap_errors() != 0;
     GST_VAAPI_DISPLAY_UNLOCK(priv->display);
     if (has_errors)
         return FALSE;
 
+    if (priv->create_window)
+        wait_event(window, UnmapNotify);
+
     priv->is_mapped = FALSE;
     return TRUE;
 }
@@ -203,12 +251,12 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen)
     Display * const dpy = GST_VAAPI_DISPLAY_XDISPLAY(priv->display);
     gboolean has_errors;
 
+    GST_VAAPI_DISPLAY_LOCK(priv->display);
+    x11_trap_errors();
     if (fullscreen) {
         if (!priv->is_mapped) {
             priv->fullscreen_on_map = TRUE;
 
-            GST_VAAPI_DISPLAY_LOCK(priv->display);
-            x11_trap_errors();
             XChangeProperty(
                 dpy,
                 priv->xid,
@@ -216,11 +264,9 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen)
                 PropModeReplace,
                 (unsigned char *)&priv->atom_NET_WM_STATE_FULLSCREEN, 1
             );
-            has_errors = x11_untrap_errors() != 0;
-            GST_VAAPI_DISPLAY_UNLOCK(priv->display);
         }
         else {
-            has_errors = !send_wmspec_change_state(
+            send_wmspec_change_state(
                 GST_VAAPI_WINDOW_X11(window),
                 priv->atom_NET_WM_STATE_FULLSCREEN,
                 TRUE
@@ -231,24 +277,22 @@ gst_vaapi_window_x11_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen)
         if (!priv->is_mapped) {
             priv->fullscreen_on_map = FALSE;
 
-            GST_VAAPI_DISPLAY_LOCK(priv->display);
-            x11_trap_errors();
             XDeleteProperty(
                 dpy,
                 priv->xid,
                 priv->atom_NET_WM_STATE
             );
-            has_errors = x11_untrap_errors() != 0;
-            GST_VAAPI_DISPLAY_UNLOCK(priv->display);
         }
         else {
-            has_errors = !send_wmspec_change_state(
+            send_wmspec_change_state(
                 GST_VAAPI_WINDOW_X11(window),
                 priv->atom_NET_WM_STATE_FULLSCREEN,
                 FALSE
             );
         }
     }
+    has_errors = x11_untrap_errors() != 0;
+    GST_VAAPI_DISPLAY_UNLOCK(priv->display);
     return !has_errors;
 }