From 4dacc4ba5507c748f5d9665dd75d75b2999d5270 Mon Sep 17 00:00:00 2001 From: Vasilis Liaskovitis Date: Wed, 6 Aug 2014 16:48:03 +0300 Subject: [PATCH] GstGLWindow, GstGLImagesink, x11: Scale navigation events on resized windows If window is resized, GstStructure pointer values have to be rescaled to original geometry. A get_surface_dimensions GLWindow class method is added for this purpose and used in the navigation send_event function. https://bugzilla.gnome.org/show_bug.cgi?id=703486 --- ext/gl/gstglimagesink.c | 23 +++++++++++++++++++++++ gst-libs/gst/gl/gstglwindow.c | 27 +++++++++++++++++++++++++++ gst-libs/gst/gl/gstglwindow.h | 3 +++ gst-libs/gst/gl/x11/gstglwindow_x11.c | 17 +++++++++++++++++ 4 files changed, 70 insertions(+) diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c index dc919d8310..ba6c1385df 100644 --- a/ext/gl/gstglimagesink.c +++ b/ext/gl/gstglimagesink.c @@ -193,10 +193,33 @@ gst_glimage_sink_navigation_send_event (GstNavigation * navigation, GstStructure GstGLImageSink *sink = GST_GLIMAGE_SINK (navigation); GstEvent *event = NULL; GstPad *pad = NULL; + GstGLWindow *window = gst_gl_context_get_window (sink->context); + guint width, height; + gdouble x, y, xscale, yscale; + + g_return_if_fail (GST_GL_IS_WINDOW (window)); + + width = GST_VIDEO_SINK_WIDTH (sink); + height = GST_VIDEO_SINK_HEIGHT (sink); + gst_gl_window_get_surface_dimensions (window, &width, &height); event = gst_event_new_navigation (structure); pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sink)); + /* Converting pointer coordinates to the non scaled geometry */ + if (width != GST_VIDEO_SINK_WIDTH (sink) && + width != 0 && gst_structure_get_double (structure, "pointer_x", &x)) { + xscale = (gdouble) GST_VIDEO_SINK_WIDTH (sink) / width; + gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, + (gdouble) x * xscale, NULL); + } + if (height != GST_VIDEO_SINK_HEIGHT (sink) && + height != 0 && gst_structure_get_double (structure, "pointer_y", &y)) { + yscale = (gdouble) GST_VIDEO_SINK_HEIGHT (sink) / height; + gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, + (gdouble) y * yscale, NULL); + } + if (GST_IS_PAD (pad) && GST_IS_EVENT (event)) gst_pad_send_event (pad, event); diff --git a/gst-libs/gst/gl/gstglwindow.c b/gst-libs/gst/gl/gstglwindow.c index 497474d176..6732a144c8 100644 --- a/gst-libs/gst/gl/gstglwindow.c +++ b/gst-libs/gst/gl/gstglwindow.c @@ -601,6 +601,25 @@ gst_gl_window_get_context (GstGLWindow * window) return (GstGLContext *) g_weak_ref_get (&window->context_ref); } +/** + * gst_gl_window_get_surface_dimensions: + * @window: a #GstGLWindow + * @width: (out): resulting surface width + * @height: (out): resulting surface height + */ + +void +gst_gl_window_get_surface_dimensions (GstGLWindow * window, guint * width, + guint * height) +{ + GstGLWindowClass *window_class; + + g_return_if_fail (GST_GL_IS_WINDOW (window)); + window_class = GST_GL_WINDOW_GET_CLASS (window); + g_return_if_fail (window_class->get_surface_dimensions != NULL); + window_class->get_surface_dimensions (window, width, height); +} + GType gst_gl_dummy_window_get_type (void); G_DEFINE_TYPE (GstGLDummyWindow, gst_gl_dummy_window, GST_GL_TYPE_WINDOW); @@ -737,6 +756,12 @@ gst_gl_dummy_window_get_display (GstGLWindow * window) return 0; } +static void +gst_gl_dummy_window_get_surface_dimensions (GstGLWindow * window, guint * width, + guint * height) +{ +} + static void gst_gl_dummy_window_class_init (GstGLDummyWindowClass * klass) { @@ -756,6 +781,8 @@ gst_gl_dummy_window_class_init (GstGLDummyWindowClass * klass) GST_DEBUG_FUNCPTR (gst_gl_dummy_window_send_message_async); window_class->open = GST_DEBUG_FUNCPTR (gst_gl_dummy_window_open); window_class->close = GST_DEBUG_FUNCPTR (gst_gl_dummy_window_close); + window_class->get_surface_dimensions = + GST_DEBUG_FUNCPTR (gst_gl_dummy_window_get_surface_dimensions); } static void diff --git a/gst-libs/gst/gl/gstglwindow.h b/gst-libs/gst/gl/gstglwindow.h index ce5cba9053..2337849941 100644 --- a/gst-libs/gst/gl/gstglwindow.h +++ b/gst-libs/gst/gl/gstglwindow.h @@ -123,6 +123,7 @@ struct _GstGLWindowClass { gboolean (*open) (GstGLWindow *window, GError **error); void (*close) (GstGLWindow *window); + void (*get_surface_dimensions) (GstGLWindow *window, guint *width, guint *height); /*< private >*/ gpointer _reserved[GST_PADDING]; @@ -148,6 +149,8 @@ void gst_gl_window_quit (GstGLWindow *window); void gst_gl_window_send_message (GstGLWindow *window, GstGLWindowCB callback, gpointer data); void gst_gl_window_send_message_async (GstGLWindow *window, GstGLWindowCB callback, gpointer data, GDestroyNotify destroy); guintptr gst_gl_window_get_display (GstGLWindow *window); +void gst_gl_window_get_surface_dimensions (GstGLWindow * window, guint * width, + guint * height); GstGLContext * gst_gl_window_get_context (GstGLWindow *window); diff --git a/gst-libs/gst/gl/x11/gstglwindow_x11.c b/gst-libs/gst/gl/x11/gstglwindow_x11.c index c576f259f8..b654a043c3 100644 --- a/gst-libs/gst/gl/x11/gstglwindow_x11.c +++ b/gst-libs/gst/gl/x11/gstglwindow_x11.c @@ -77,6 +77,8 @@ gboolean gst_gl_window_x11_create_context (GstGLWindow * window, GstGLAPI gl_api, guintptr external_gl_context, GError ** error); gboolean gst_gl_window_x11_open (GstGLWindow * window, GError ** error); void gst_gl_window_x11_close (GstGLWindow * window); +static void gst_gl_window_x11_get_surface_dimensions (GstGLWindow * window, + guint * width, guint * height); static void gst_gl_window_x11_finalize (GObject * object) @@ -109,6 +111,8 @@ gst_gl_window_x11_class_init (GstGLWindowX11Class * klass) GST_DEBUG_FUNCPTR (gst_gl_window_x11_send_message_async); window_class->open = GST_DEBUG_FUNCPTR (gst_gl_window_x11_open); window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_x11_close); + window_class->get_surface_dimensions = + GST_DEBUG_FUNCPTR (gst_gl_window_x11_get_surface_dimensions); } static void @@ -705,3 +709,16 @@ gst_gl_window_x11_get_display (GstGLWindow * window) return (guintptr) window_x11->device; } + +static void +gst_gl_window_x11_get_surface_dimensions (GstGLWindow * window, guint * width, + guint * height) +{ + GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window); + XWindowAttributes attr; + XGetWindowAttributes (window_x11->device, window_x11->internal_win_id, &attr); + if (width != NULL) + *width = attr.width; + if (height != NULL) + *height = attr.height; +}