diff --git a/gst-libs/gst/gl/gstglwindow_win32.c b/gst-libs/gst/gl/gstglwindow_win32.c index 879bc80ce7..04b9f2c98f 100644 --- a/gst-libs/gst/gl/gstglwindow_win32.c +++ b/gst-libs/gst/gl/gstglwindow_win32.c @@ -197,26 +197,58 @@ void gst_gl_window_set_external_window_id (GstGLWindow * window, gulong id) { GstGLWindowPrivate *priv = window->priv; - WNDPROC window_parent_proc = - (WNDPROC) GetWindowLongPtr ((HWND) id, GWL_WNDPROC); - RECT rect; - SetProp (priv->internal_win_id, "gl_window_parent_id", (HWND) id); - SetProp ((HWND) id, "gl_window_id", priv->internal_win_id); - SetProp ((HWND) id, "gl_window_parent_proc", (WNDPROC) window_parent_proc); - SetWindowLongPtr ((HWND) id, GWL_WNDPROC, (LONG_PTR) sub_class_proc); + //retrieve parent if previously set + HWND parent_id = GetProp (priv->internal_win_id, "gl_window_parent_id"); - SetWindowLongPtr (priv->internal_win_id, GWL_STYLE, WS_CHILD | WS_MAXIMIZE); - SetParent (priv->internal_win_id, (HWND) id); + if (priv->visible) { + ShowWindow (priv->internal_win_id, SW_HIDE); + priv->visible = FALSE; + } + + if (parent_id) { + WNDPROC parent_proc = GetProp (parent_id, "gl_window_parent_proc"); - //take changes into account: SWP_FRAMECHANGED - GetClientRect ((HWND) id, &rect); - SetWindowPos (priv->internal_win_id, HWND_TOP, rect.left, rect.top, - rect.right, rect.bottom, - SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | - SWP_FRAMECHANGED | SWP_NOACTIVATE); - MoveWindow (priv->internal_win_id, rect.left, rect.top, rect.right, - rect.bottom, FALSE); + g_debug ("release parent %lud\n", (gulong) parent_id); + + g_assert (parent_proc); + + SetWindowLongPtr (parent_id, GWL_WNDPROC, (LONG) parent_proc); + SetParent (priv->internal_win_id, NULL); + + RemoveProp (parent_id, "gl_window_parent_proc"); + RemoveProp (priv->internal_win_id, "gl_window_parent_id"); + } + + //not 0 + if (id) { + WNDPROC window_parent_proc = + (WNDPROC) GetWindowLongPtr ((HWND) id, GWL_WNDPROC); + RECT rect; + + g_debug ("set parent %lud\n", (gulong) id); + + SetProp (priv->internal_win_id, "gl_window_parent_id", (HWND) id); + SetProp ((HWND) id, "gl_window_id", priv->internal_win_id); + SetProp ((HWND) id, "gl_window_parent_proc", (WNDPROC) window_parent_proc); + SetWindowLongPtr ((HWND) id, GWL_WNDPROC, (LONG_PTR) sub_class_proc); + + SetWindowLongPtr (priv->internal_win_id, GWL_STYLE, WS_CHILD | WS_MAXIMIZE); + SetParent (priv->internal_win_id, (HWND) id); + + //take changes into account: SWP_FRAMECHANGED + GetClientRect ((HWND) id, &rect); + SetWindowPos (priv->internal_win_id, HWND_TOP, rect.left, rect.top, + rect.right, rect.bottom, + SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | + SWP_FRAMECHANGED | SWP_NOACTIVATE); + MoveWindow (priv->internal_win_id, rect.left, rect.top, rect.right, + rect.bottom, FALSE); + } else { + //no parent so the internal window needs borders and system menu + SetWindowLongPtr (priv->internal_win_id, GWL_STYLE, + WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW); + } } /* Must be called in the gl thread */ diff --git a/gst-libs/gst/gl/gstglwindow_winCE.c b/gst-libs/gst/gl/gstglwindow_winCE.c index da0c117d2b..546af06e2f 100644 --- a/gst-libs/gst/gl/gstglwindow_winCE.c +++ b/gst-libs/gst/gl/gstglwindow_winCE.c @@ -204,26 +204,58 @@ void gst_gl_window_set_external_window_id (GstGLWindow * window, gulong id) { GstGLWindowPrivate *priv = window->priv; - WNDPROC window_parent_proc = - (WNDPROC) (guint64) GetWindowLongPtr ((HWND) id, GWL_WNDPROC); - RECT rect; - SetProp (priv->internal_win_id, "gl_window_parent_id", (HWND) id); - SetProp ((HWND) id, "gl_window_id", priv->internal_win_id); - SetProp ((HWND) id, "gl_window_parent_proc", (WNDPROC) window_parent_proc); - SetWindowLongPtr ((HWND) id, GWL_WNDPROC, (DWORD) (guint64) sub_class_proc); + //retrieve parent if previously set + HWND parent_id = GetProp (priv->internal_win_id, "gl_window_parent_id"); - SetWindowLongPtr (priv->internal_win_id, GWL_STYLE, WS_CHILD | WS_MAXIMIZE); - SetParent (priv->internal_win_id, (HWND) id); + if (priv->visible) { + ShowWindow (priv->internal_win_id, SW_HIDE); + priv->visible = FALSE; + } + + if (parent_id) { + WNDPROC parent_proc = GetProp (parent_id, "gl_window_parent_proc"); - //take changes into account: SWP_FRAMECHANGED - GetClientRect ((HWND) id, &rect); - SetWindowPos (priv->internal_win_id, HWND_TOP, rect.left, rect.top, - rect.right, rect.bottom, - SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | - SWP_FRAMECHANGED | SWP_NOACTIVATE); - MoveWindow (priv->internal_win_id, rect.left, rect.top, rect.right, - rect.bottom, FALSE); + g_debug ("release parent %lud\n", (gulong) parent_id); + + g_assert (parent_proc); + + SetWindowLongPtr (parent_id, GWL_WNDPROC, (LONG) parent_proc); + SetParent (priv->internal_win_id, NULL); + + RemoveProp (parent_id, "gl_window_parent_proc"); + RemoveProp (priv->internal_win_id, "gl_window_parent_id"); + } + + //not 0 + if (id) { + WNDPROC window_parent_proc = + (WNDPROC) GetWindowLongPtr ((HWND) id, GWL_WNDPROC); + RECT rect; + + g_debug ("set parent %lud\n", (gulong) id); + + SetProp (priv->internal_win_id, "gl_window_parent_id", (HWND) id); + SetProp ((HWND) id, "gl_window_id", priv->internal_win_id); + SetProp ((HWND) id, "gl_window_parent_proc", (WNDPROC) window_parent_proc); + SetWindowLongPtr ((HWND) id, GWL_WNDPROC, (LONG_PTR) sub_class_proc); + + SetWindowLongPtr (priv->internal_win_id, GWL_STYLE, WS_CHILD | WS_MAXIMIZE); + SetParent (priv->internal_win_id, (HWND) id); + + //take changes into account: SWP_FRAMECHANGED + GetClientRect ((HWND) id, &rect); + SetWindowPos (priv->internal_win_id, HWND_TOP, rect.left, rect.top, + rect.right, rect.bottom, + SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | + SWP_FRAMECHANGED | SWP_NOACTIVATE); + MoveWindow (priv->internal_win_id, rect.left, rect.top, rect.right, + rect.bottom, FALSE); + } else { + //no parent so the internal window needs borders and system menu + SetWindowLongPtr (priv->internal_win_id, GWL_STYLE, + WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW); + } } /* Must be called in the gl thread */ diff --git a/gst/gl/gstglimagesink.c b/gst/gl/gstglimagesink.c index 1bdaa229cf..d73f90936f 100644 --- a/gst/gl/gstglimagesink.c +++ b/gst/gl/gstglimagesink.c @@ -251,6 +251,7 @@ gst_glimage_sink_init (GstGLImageSink * glimage_sink, { glimage_sink->display_name = NULL; glimage_sink->window_id = 0; + glimage_sink->new_window_id = 0; glimage_sink->display = NULL; glimage_sink->stored_buffer = NULL; glimage_sink->clientReshapeCallback = NULL; @@ -416,6 +417,9 @@ gst_glimage_sink_stop (GstBaseSink * bsink) glimage_sink->display = NULL; } + glimage_sink->window_id = 0; + //but do not reset glimage_sink->new_window_id + return TRUE; } @@ -485,7 +489,7 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) glimage_sink->par_n = par_n; glimage_sink->par_d = par_d; - if (!glimage_sink->window_id) + if (!glimage_sink->window_id && !glimage_sink->new_window_id) gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (glimage_sink)); return TRUE; @@ -510,10 +514,6 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf) if (glimage_sink->display == NULL) { glimage_sink->display = g_object_ref (gl_buffer->display); - if (glimage_sink->window_id) - gst_gl_display_set_window_id (glimage_sink->display, - glimage_sink->window_id); - gst_gl_display_set_client_reshape_callback (glimage_sink->display, glimage_sink->clientReshapeCallback); @@ -532,10 +532,6 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf) gst_gl_display_create_context (glimage_sink->display, glimage_sink->width, glimage_sink->height, 0); - if (glimage_sink->window_id) - gst_gl_display_set_window_id (glimage_sink->display, - glimage_sink->window_id); - //init colorspace conversion if needed gst_gl_display_init_upload (glimage_sink->display, glimage_sink->format, glimage_sink->width, glimage_sink->height, @@ -558,6 +554,12 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf) //gl_buffer is created in this block, so the gl buffer is already referenced } + if (glimage_sink->window_id != glimage_sink->new_window_id) { + glimage_sink->window_id = glimage_sink->new_window_id; + gst_gl_display_set_window_id (glimage_sink->display, + glimage_sink->window_id); + } + //the buffer is cleared when an other comes in if (glimage_sink->stored_buffer) { gst_buffer_unref (GST_BUFFER_CAST (glimage_sink->stored_buffer)); @@ -594,11 +596,7 @@ gst_glimage_sink_set_xwindow_id (GstXOverlay * overlay, gulong window_id) GST_DEBUG ("set_xwindow_id %ld", window_id); - if (glimage_sink->window_id == window_id) - return; - - if (window_id) - glimage_sink->window_id = window_id; + glimage_sink->new_window_id = window_id; } diff --git a/gst/gl/gstglimagesink.h b/gst/gl/gstglimagesink.h index 386181d0be..df32788174 100644 --- a/gst/gl/gstglimagesink.h +++ b/gst/gl/gstglimagesink.h @@ -53,6 +53,7 @@ struct _GstGLImageSink gchar *display_name; gulong window_id; + gulong new_window_id; //caps GstCaps *caps;