[vlc-devel] Re: [PATCH] Win32 directx/direct3d/opengl: fullscreen mode improved
Sergey Volk
sergey.volk at gmail.com
Thu May 3 13:52:48 CEST 2007
Here is a very similar patch for WinGdi output module. It also adds support
for hotkeys to WinGdi video_output module.
On 5/2/07, Sergey Volk <sergey.volk at gmail.com> wrote:
>
> Hi,
> Current implementation of directx video output modules (directx, direct3d,
> glwin32) leaves main interface window visible when the user toggles
> fullscreen mode. This causes two problems: (a) the user sees empty main
> interface window when he switches to another application or cycles through
> existing windows using Alt-Tab and (b) main interface window overlaps video
> window when he toggles "video-on-top" option while fullscreen mode is
> active. In order to fix both these issues, we should hide main interface
> window when entering fullscreen mode and restore it when leaving fullscreen
> mode. But some GUI modules (in particular qt4 module) may need to call
> show() for main interface window in order to apply "video-on-top" flag, so
> in order to avoid condition (b) described earlier we need also to hide
> VOUT_SET_STAY_ON_TOP queries from main interface window while we are in
> fullscreen mode and update "video-on-top" status for main window when we are
> leaving fullscreen mode.
>
> I have also noticed that there is a code in
> src/video_output/vout_intf.c:FullscreenCallback (line 1151), which sets
> video-on-top variable to false, when entering fullscreen mode. I think this
> code should be removed, there is no point in disabling video-on-top option,
> as the user may change this option in fullscreen mode anyway (through mouse
> / hotkey controls, at least). So video_output modules should be aware that
> video-on-top variable may be toggled in fullscreen mode and should handle
> such situations appropriately. I'm developing under win32/cygwin, so I
> haven't checked if similar reasoning applies to X11 module or any of the
> other video output modules. It seems that at least wingdi output module has
> the same problem, but it's code is somewhat different from
> DirectX/Direct3D/Win32 OpenGL code, so I'll provide patch for wingdi module
> later. In the meantime, I think it is safe to leave that old code as it is.
>
> Two patches are attached to this message: vlc-vout-dx-fullscreen.patch is
> a version which fixes fullscreen mode for DirectX module only, it is
> intended only to demonstrate what changes are being applied to current
> version. Another one - vlc-vout-dx-fullscreen2.patch, does essentially the
> same, only it fixes all three modules (directx, direct3d and opengl) and
> refactors some common code for toggling fullscreen mode into
> Win32ToggleFullscreen function, to remove code duplication between those
> modules.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20070503/0bf35dce/attachment.html>
-------------- next part --------------
Index: video_output/wingdi.c
===================================================================
--- video_output/wingdi.c (revision 19952)
+++ video_output/wingdi.c (working copy)
@@ -35,6 +35,8 @@
#include <commctrl.h>
+#include "vlc_keys.h"
+
#define SHFS_SHOWSIPBUTTON 0x0004
#define SHFS_HIDESIPBUTTON 0x0008
@@ -438,6 +440,28 @@
{
}
+/* Internal wrapper over GetWindowPlacement / SetWindowPlacement */
+static void SetWindowState(HWND hwnd, int nShowCmd)
+{
+ WINDOWPLACEMENT window_placement;
+ window_placement.length = sizeof(WINDOWPLACEMENT);
+ GetWindowPlacement( hwnd, &window_placement );
+ window_placement.showCmd = nShowCmd;
+ SetWindowPlacement( hwnd, &window_placement );
+ SetWindowPos( hwnd, 0, 0, 0, 0, 0,
+ SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
+}
+
+/* Internal wrapper to call vout_ControlWindow for hparent */
+static void ControlParentWindow( vout_thread_t *p_vout, int i_query, ... )
+{
+ va_list args;
+ va_start( args, i_query );
+ vout_ControlWindow( p_vout,
+ (void *)p_vout->p_sys->hparent, i_query, args );
+ va_end( args );
+}
+
/*****************************************************************************
* Manage: handle events
*****************************************************************************
@@ -446,10 +470,6 @@
*****************************************************************************/
static int Manage( vout_thread_t *p_vout )
{
-#ifndef UNDER_CE
- WINDOWPLACEMENT window_placement;
-#endif
-
/* If we do not control our window, we check for geometry changes
* ourselves because the parent might not send us its events. */
if( p_vout->p_sys->hparent && !p_vout->b_fullscreen )
@@ -505,11 +525,6 @@
p_vout->b_fullscreen = ! p_vout->b_fullscreen;
- /* We need to switch between Maximized and Normal sized window */
-#ifndef UNDER_CE
- window_placement.length = sizeof(WINDOWPLACEMENT);
- GetWindowPlacement( hwnd, &window_placement );
-#endif
if( p_vout->b_fullscreen )
{
#ifndef UNDER_CE
@@ -528,14 +543,10 @@
SetWindowPos( hwnd, 0, point.x, point.y,
rect.right, rect.bottom,
SWP_NOZORDER|SWP_FRAMECHANGED );
- GetWindowPlacement( hwnd, &window_placement );
}
/* Maximize window */
- window_placement.showCmd = SW_SHOWMAXIMIZED;
- SetWindowPlacement( hwnd, &window_placement );
- SetWindowPos( hwnd, 0, 0, 0, 0, 0,
- SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
+ SetWindowState( hwnd, SW_SHOWMAXIMIZED );
#endif
if( p_vout->p_sys->hparent )
@@ -546,6 +557,11 @@
SetWindowPos( p_vout->p_sys->hwnd, 0, 0, 0,
rect.right, rect.bottom,
SWP_NOZORDER|SWP_FRAMECHANGED );
+/* Not sure if GetAncestor is available on WinCE */
+#ifndef UNDER_CE
+ HWND topLevelParent = GetAncestor( p_vout->p_sys->hparent, GA_ROOT );
+ ShowWindow( topLevelParent, SW_HIDE );
+#endif
}
ShowWindow( hwnd, SW_SHOW );
@@ -558,10 +574,7 @@
#ifndef UNDER_CE
/* Normal window */
- window_placement.showCmd = SW_SHOWNORMAL;
- SetWindowPlacement( hwnd, &window_placement );
- SetWindowPos( hwnd, 0, 0, 0, 0, 0,
- SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
+ SetWindowState( hwnd, SW_SHOWNORMAL );
#endif
if( p_vout->p_sys->hparent )
@@ -574,7 +587,17 @@
SWP_NOZORDER|SWP_FRAMECHANGED );
ShowWindow( hwnd, SW_HIDE );
+#ifndef UNDER_CE
+ HWND topLevelParent = GetAncestor( p_vout->p_sys->hparent, GA_ROOT );
+ ShowWindow( topLevelParent, SW_SHOW );
+#endif
SetForegroundWindow( p_vout->p_sys->hparent );
+
+ /* Update "video-on-top" status for main interface window, it
+ needs to be updated as we were hiding VOUT_SET_STAY_ON_TOP
+ queries from it while we were in fullscreen mode */
+ int b_ontop = var_GetBool( p_vout, "video-on-top" );
+ ControlParentWindow( p_vout, VOUT_SET_STAY_ON_TOP, b_ontop );
}
/* Make sure the mouse cursor is displayed */
@@ -761,6 +784,77 @@
}
/*****************************************************************************
+ * ConvertWinKeyToVLC: converts Windows virtual key codes to VLC key codes
+ *****************************************************************************/
+static struct
+{
+ int i_winkey;
+ int i_vlckey;
+
+} winkeys_to_vlckeys[] =
+{
+ { VK_F1, KEY_F1 }, { VK_F2, KEY_F2 }, { VK_F3, KEY_F3 }, { VK_F4, KEY_F4 },
+ { VK_F5, KEY_F5 }, { VK_F6, KEY_F6 }, { VK_F7, KEY_F7 }, { VK_F8, KEY_F8 },
+ { VK_F9, KEY_F9 }, { VK_F10, KEY_F10 }, { VK_F11, KEY_F11 },
+ { VK_F12, KEY_F12 },
+
+ { VK_RETURN, KEY_ENTER },
+ { VK_SPACE, KEY_SPACE },
+ { VK_ESCAPE, KEY_ESC },
+
+ { VK_LEFT, KEY_LEFT },
+ { VK_RIGHT, KEY_RIGHT },
+ { VK_UP, KEY_UP },
+ { VK_DOWN, KEY_DOWN },
+
+ { VK_HOME, KEY_HOME },
+ { VK_END, KEY_END },
+ { VK_PRIOR, KEY_PAGEUP },
+ { VK_NEXT, KEY_PAGEDOWN },
+
+ { VK_INSERT, KEY_INSERT },
+ { VK_DELETE, KEY_DELETE },
+
+ { VK_CONTROL, 0 },
+ { VK_SHIFT, 0 },
+ { VK_MENU, 0 },
+
+/* Not sure if these keys are available under WinCE */
+#if 0
+ { VK_BROWSER_BACK, KEY_BROWSER_BACK },
+ { VK_BROWSER_FORWARD, KEY_BROWSER_FORWARD },
+ { VK_BROWSER_REFRESH, KEY_BROWSER_REFRESH },
+ { VK_BROWSER_STOP, KEY_BROWSER_STOP },
+ { VK_BROWSER_SEARCH, KEY_BROWSER_SEARCH },
+ { VK_BROWSER_FAVORITES, KEY_BROWSER_FAVORITES },
+ { VK_BROWSER_HOME, KEY_BROWSER_HOME },
+ { VK_VOLUME_MUTE, KEY_VOLUME_MUTE },
+ { VK_VOLUME_DOWN, KEY_VOLUME_DOWN },
+ { VK_VOLUME_UP, KEY_VOLUME_UP },
+ { VK_MEDIA_NEXT_TRACK, KEY_MEDIA_NEXT_TRACK },
+ { VK_MEDIA_PREV_TRACK, KEY_MEDIA_PREV_TRACK },
+ { VK_MEDIA_STOP, KEY_MEDIA_STOP },
+ { VK_MEDIA_PLAY_PAUSE, KEY_MEDIA_PLAY_PAUSE },
+#endif
+
+ { 0, 0 }
+};
+
+static int ConvertWinKeyToVLC( int i_key )
+{
+ int i;
+
+ for( i = 0; winkeys_to_vlckeys[i].i_winkey != 0; i++ )
+ {
+ if( winkeys_to_vlckeys[i].i_winkey == i_key )
+ {
+ return winkeys_to_vlckeys[i].i_vlckey;
+ }
+ }
+
+ return 0;
+}
+/*****************************************************************************
* EventThread: Event handling thread
*****************************************************************************/
static void EventThread ( vlc_object_t *p_event )
@@ -887,6 +981,34 @@
p_event->p_libvlc->b_die = VLC_TRUE;
break;
}
+
+ /* The key events are first processed here and not translated
+ * into WM_CHAR events because we need to know the status of the
+ * modifier keys. */
+ int i_key = ConvertWinKeyToVLC( msg.wParam );
+ if( !i_key )
+ {
+ /* This appears to be a "normal" (ascii) key */
+ i_key = tolower( MapVirtualKey( msg.wParam, 2 ) );
+ }
+
+ if( i_key )
+ {
+ if( GetKeyState(VK_CONTROL) & 0x8000 )
+ {
+ i_key |= KEY_MODIFIER_CTRL;
+ }
+ if( GetKeyState(VK_SHIFT) & 0x8000 )
+ {
+ i_key |= KEY_MODIFIER_SHIFT;
+ }
+ if( GetKeyState(VK_MENU) & 0x8000 )
+ {
+ i_key |= KEY_MODIFIER_ALT;
+ }
+
+ var_SetInteger( p_event->p_libvlc, "key-pressed", i_key );
+ }
TranslateMessage( &msg );
break;
@@ -1356,6 +1478,14 @@
return VLC_SUCCESS;
+ case VOUT_SET_STAY_ON_TOP:
+ if( p_vout->p_sys->hparent && !var_GetBool( p_vout, "fullscreen" ) )
+ return vout_ControlWindow( p_vout,
+ (void *)p_vout->p_sys->hparent, i_query, args );
+
+ //p_vout->p_sys->b_on_top_change = VLC_TRUE;
+ return VLC_SUCCESS;
+
default:
return vout_vaControlDefault( p_vout, i_query, args );
}
More information about the vlc-devel
mailing list