From ca1a2d33caf44a97c4eb3a65d884fb1fa00e73c5 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Sat, 6 Jun 2009 14:34:57 +0200 Subject: [PATCH] [349/906] can switch xoverlays while playing Fixes bug #584877 Before this commit calling "gst_x_overlay_set_xwindow_id" more than one time, had no effect. It mainly affects the glimagesink implementation. But on win32 (and CE), some stuff has to be done to release the old parent. And add a switchxoverlay example where the user can click on left/right part of the main window to switch the xoverlay. --- gst-libs/gst/gl/gstglwindow_win32.c | 66 +++++++++++++++++++++-------- gst-libs/gst/gl/gstglwindow_winCE.c | 66 +++++++++++++++++++++-------- 2 files changed, 98 insertions(+), 34 deletions(-) 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 */