[296/906] Fix callbacks passed over XEvents on 64 bit architectures
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 3 Feb 2009 17:58:00 +0000 (18:58 +0100)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 9 Dec 2017 19:31:21 +0000 (19:31 +0000)
Althought the XEvent's xclient.data.l array is an array of
longs they will be constrained to 32 bit by the X11 protocol.
On 64 bit architectures use two elements of the array to store
one pointer.
This fixes segfaults that happen at least for every example
on startup.

gst-libs/gst/gl/gstglwindow_x11.c

index d097f3b..14dc124 100644 (file)
@@ -626,8 +626,19 @@ gst_gl_window_run_loop (GstGLWindow * window)
         /* Message sent with gst_gl_window_send_message */
         if (wm_gl != None && event.xclient.message_type == wm_gl) {
           if (priv->running) {
+#if SIZEOF_VOID_P == 8
+            GstGLWindowCB custom_cb =
+                (GstGLWindowCB) (((event.xclient.
+                        data.l[0] & 0xffffffff) << 32) | (event.xclient.
+                    data.l[1] & 0xffffffff));
+            gpointer custom_data =
+                (gpointer) (((event.xclient.
+                        data.l[2] & 0xffffffff) << 32) | (event.xclient.
+                    data.l[3] & 0xffffffff));
+#else
             GstGLWindowCB custom_cb = (GstGLWindowCB) event.xclient.data.l[0];
             gpointer custom_data = (gpointer) event.xclient.data.l[1];
+#endif
 
             if (!custom_cb || !custom_data)
               g_debug ("custom cb not initialized\n");
@@ -658,8 +669,19 @@ gst_gl_window_run_loop (GstGLWindow * window)
         /* message sent with gst_gl_window_quit_loop */
         else if (wm_quit_loop != None
             && event.xclient.message_type == wm_quit_loop) {
+#if SIZEOF_VOID_P == 8
+          GstGLWindowCB destroy_cb =
+              (GstGLWindowCB) (((event.xclient.
+                      data.l[0] & 0xffffffff) << 32) | (event.xclient.
+                  data.l[1] & 0xffffffff));
+          gpointer destroy_data =
+              (gpointer) (((event.xclient.
+                      data.l[2] & 0xffffffff) << 32) | (event.xclient.
+                  data.l[3] & 0xffffffff));
+#else
           GstGLWindowCB destroy_cb = (GstGLWindowCB) event.xclient.data.l[0];
           gpointer destroy_data = (gpointer) event.xclient.data.l[1];
+#endif
 
           g_debug ("Quit loop message %" G_GUINT64_FORMAT "\n",
               (guint64) priv->internal_win_id);
@@ -670,10 +692,19 @@ gst_gl_window_run_loop (GstGLWindow * window)
           /* make sure last pendings send message calls are executed */
           XFlush (priv->device);
           while (XCheckTypedEvent (priv->device, ClientMessage, &pending_event)) {
+#if SIZEOF_VOID_P == 8
             GstGLWindowCB custom_cb =
-                (GstGLWindowCB) pending_event.xclient.data.l[0];
-            gpointer custom_data = (gpointer) pending_event.xclient.data.l[1];
-
+                (GstGLWindowCB) (((event.xclient.
+                        data.l[0] & 0xffffffff) << 32) | (event.xclient.
+                    data.l[1] & 0xffffffff));
+            gpointer custom_data =
+                (gpointer) (((event.xclient.
+                        data.l[2] & 0xffffffff) << 32) | (event.xclient.
+                    data.l[3] & 0xffffffff));
+#else
+            GstGLWindowCB custom_cb = (GstGLWindowCB) event.xclient.data.l[0];
+            gpointer custom_data = (gpointer) event.xclient.data.l[1];
+#endif
             g_debug ("execute last pending custom x events\n");
 
             if (!custom_cb || !custom_data)
@@ -773,8 +804,15 @@ gst_gl_window_quit_loop (GstGLWindow * window, GstGLWindowCB callback,
       event.xclient.message_type =
           XInternAtom (priv->disp_send, "WM_QUIT_LOOP", True);;
       event.xclient.format = 32;
+#if SIZEOF_VOID_P == 8
+      event.xclient.data.l[0] = (((long) callback) >> 32) & 0xffffffff;
+      event.xclient.data.l[1] = (((long) callback)) & 0xffffffff;
+      event.xclient.data.l[2] = (((long) data) >> 32) & 0xffffffff;
+      event.xclient.data.l[3] = (((long) data)) & 0xffffffff;
+#else
       event.xclient.data.l[0] = (long) callback;
       event.xclient.data.l[1] = (long) data;
+#endif
 
       XSendEvent (priv->disp_send, priv->internal_win_id, FALSE, NoEventMask,
           &event);
@@ -805,8 +843,15 @@ gst_gl_window_send_message (GstGLWindow * window, GstGLWindowCB callback,
       event.xclient.message_type =
           XInternAtom (priv->disp_send, "WM_GL_WINDOW", True);
       event.xclient.format = 32;
+#if SIZEOF_VOID_P == 8
+      event.xclient.data.l[0] = (((long) callback) >> 32) & 0xffffffff;
+      event.xclient.data.l[1] = (((long) callback)) & 0xffffffff;
+      event.xclient.data.l[2] = (((long) data) >> 32) & 0xffffffff;
+      event.xclient.data.l[3] = (((long) data)) & 0xffffffff;
+#else
       event.xclient.data.l[0] = (long) callback;
       event.xclient.data.l[1] = (long) data;
+#endif
 
       XSendEvent (priv->disp_send, priv->internal_win_id, FALSE, NoEventMask,
           &event);