Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-2-2
Commits
955de909
Commit
955de909
authored
Jan 03, 2010
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Removed old msw files.
parent
25d33b29
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
0 additions
and
2217 deletions
+0
-2217
modules/video_output/msw/common_vo.c
modules/video_output/msw/common_vo.c
+0
-761
modules/video_output/msw/events_vo.c
modules/video_output/msw/events_vo.c
+0
-1093
modules/video_output/msw/events_vo.h
modules/video_output/msw/events_vo.h
+0
-57
modules/video_output/msw/vout.h
modules/video_output/msw/vout.h
+0
-306
No files found.
modules/video_output/msw/common_vo.c
deleted
100644 → 0
View file @
25d33b29
/*****************************************************************************
* common.c:
*****************************************************************************
* Copyright (C) 2001-2009 the VideoLAN team
* $Id$
*
* Authors: Gildas Bazin <gbazin@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble: This file contains the functions related to the creation of
* a window and the handling of its messages (events).
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_vout.h>
#include <vlc_vout_window.h>
#include <windows.h>
#include <windowsx.h>
#include <shellapi.h>
#ifdef MODULE_NAME_IS_directx
#include <ddraw.h>
#endif
#ifdef MODULE_NAME_IS_direct3d
#include <d3d9.h>
#endif
#ifdef MODULE_NAME_IS_glwin32
#include <GL/gl.h>
#endif
#include "vout.h"
#ifndef UNDER_CE
#include <vlc_windows_interfaces.h>
#endif
#ifdef UNDER_CE
#include <aygshell.h>
//WINSHELLAPI BOOL WINAPI SHFullScreen(HWND hwndRequester, DWORD dwState);
#endif
static
int
vaControlParentWindow
(
vout_thread_t
*
,
int
,
va_list
);
/* */
int
CommonInit
(
vout_thread_t
*
p_vout
)
{
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
p_sys
->
hwnd
=
NULL
;
p_sys
->
hvideownd
=
NULL
;
p_sys
->
hparent
=
NULL
;
p_sys
->
hfswnd
=
NULL
;
p_sys
->
i_changes
=
0
;
SetRectEmpty
(
&
p_sys
->
rect_display
);
SetRectEmpty
(
&
p_sys
->
rect_parent
);
var_Create
(
p_vout
,
"video-title"
,
VLC_VAR_STRING
|
VLC_VAR_DOINHERIT
);
/* Set main window's size */
vout_window_cfg_t
wnd_cfg
;
memset
(
&
wnd_cfg
,
0
,
sizeof
(
wnd_cfg
)
);
wnd_cfg
.
type
=
VOUT_WINDOW_TYPE_HWND
;
wnd_cfg
.
x
=
0
;
wnd_cfg
.
y
=
0
;
wnd_cfg
.
width
=
p_vout
->
i_window_width
;
wnd_cfg
.
height
=
p_vout
->
i_window_height
;
p_sys
->
p_event
=
EventThreadCreate
(
p_vout
,
&
wnd_cfg
);
if
(
!
p_sys
->
p_event
)
return
VLC_EGENERIC
;
event_cfg_t
cfg
;
memset
(
&
cfg
,
0
,
sizeof
(
cfg
));
#ifdef MODULE_NAME_IS_direct3d
cfg
.
use_desktop
=
p_vout
->
p_sys
->
b_desktop
;
#endif
#ifdef MODULE_NAME_IS_directx
cfg
.
use_overlay
=
p_vout
->
p_sys
->
b_using_overlay
;
#endif
event_hwnd_t
hwnd
;
if
(
EventThreadStart
(
p_sys
->
p_event
,
&
hwnd
,
&
cfg
)
)
return
VLC_EGENERIC
;
p_sys
->
parent_window
=
hwnd
.
parent_window
;
p_sys
->
hparent
=
hwnd
.
hparent
;
p_sys
->
hwnd
=
hwnd
.
hwnd
;
p_sys
->
hvideownd
=
hwnd
.
hvideownd
;
p_sys
->
hfswnd
=
hwnd
.
hfswnd
;
/* Variable to indicate if the window should be on top of others */
/* Trigger a callback right now */
var_TriggerCallback
(
p_vout
,
"video-on-top"
);
/* Why not with glwin32 */
#if !defined(UNDER_CE) && !defined(MODULE_NAME_IS_glwin32)
var_Create
(
p_vout
,
"disable-screensaver"
,
VLC_VAR_BOOL
|
VLC_VAR_DOINHERIT
);
DisableScreensaver
(
p_vout
);
#endif
return
VLC_SUCCESS
;
}
/* */
void
CommonClean
(
vout_thread_t
*
p_vout
)
{
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
ExitFullscreen
(
p_vout
);
if
(
p_sys
->
p_event
)
{
EventThreadStop
(
p_sys
->
p_event
);
EventThreadDestroy
(
p_sys
->
p_event
);
}
#if !defined(UNDER_CE) && !defined(MODULE_NAME_IS_glwin32)
RestoreScreensaver
(
p_vout
);
#endif
}
void
CommonManage
(
vout_thread_t
*
p_vout
)
{
/* 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
)
{
RECT
rect_parent
;
POINT
point
;
GetClientRect
(
p_vout
->
p_sys
->
hparent
,
&
rect_parent
);
point
.
x
=
point
.
y
=
0
;
ClientToScreen
(
p_vout
->
p_sys
->
hparent
,
&
point
);
OffsetRect
(
&
rect_parent
,
point
.
x
,
point
.
y
);
if
(
!
EqualRect
(
&
rect_parent
,
&
p_vout
->
p_sys
->
rect_parent
)
)
{
p_vout
->
p_sys
->
rect_parent
=
rect_parent
;
/* FIXME I find such #ifdef quite weirds. Are they really needed ? */
#if defined(MODULE_NAME_IS_direct3d)
SetWindowPos
(
p_vout
->
p_sys
->
hwnd
,
0
,
0
,
0
,
rect_parent
.
right
-
rect_parent
.
left
,
rect_parent
.
bottom
-
rect_parent
.
top
,
SWP_NOZORDER
);
UpdateRects
(
p_vout
,
true
);
#else
/* This one is to force the update even if only
* the position has changed */
SetWindowPos
(
p_vout
->
p_sys
->
hwnd
,
0
,
1
,
1
,
rect_parent
.
right
-
rect_parent
.
left
,
rect_parent
.
bottom
-
rect_parent
.
top
,
0
);
SetWindowPos
(
p_vout
->
p_sys
->
hwnd
,
0
,
0
,
0
,
rect_parent
.
right
-
rect_parent
.
left
,
rect_parent
.
bottom
-
rect_parent
.
top
,
0
);
#if defined(MODULE_NAME_IS_wingdi) || defined(MODULE_NAME_IS_wingapi)
unsigned
int
i_x
,
i_y
,
i_width
,
i_height
;
vout_PlacePicture
(
p_vout
,
rect_parent
.
right
-
rect_parent
.
left
,
rect_parent
.
bottom
-
rect_parent
.
top
,
&
i_x
,
&
i_y
,
&
i_width
,
&
i_height
);
SetWindowPos
(
p_vout
->
p_sys
->
hvideownd
,
HWND_TOP
,
i_x
,
i_y
,
i_width
,
i_height
,
0
);
#endif
#endif
}
}
/* */
p_vout
->
p_sys
->
i_changes
|=
EventThreadRetreiveChanges
(
p_vout
->
p_sys
->
p_event
);
/* autoscale toggle */
if
(
p_vout
->
i_changes
&
VOUT_SCALE_CHANGE
)
{
p_vout
->
i_changes
&=
~
VOUT_SCALE_CHANGE
;
p_vout
->
b_autoscale
=
var_GetBool
(
p_vout
,
"autoscale"
);
p_vout
->
i_zoom
=
(
int
)
ZOOM_FP_FACTOR
;
UpdateRects
(
p_vout
,
true
);
}
/* scaling factor */
if
(
p_vout
->
i_changes
&
VOUT_ZOOM_CHANGE
)
{
p_vout
->
i_changes
&=
~
VOUT_ZOOM_CHANGE
;
p_vout
->
b_autoscale
=
false
;
p_vout
->
i_zoom
=
(
int
)(
ZOOM_FP_FACTOR
*
var_GetFloat
(
p_vout
,
"scale"
)
);
UpdateRects
(
p_vout
,
true
);
}
/* Check for cropping / aspect changes */
if
(
p_vout
->
i_changes
&
VOUT_CROP_CHANGE
||
p_vout
->
i_changes
&
VOUT_ASPECT_CHANGE
)
{
p_vout
->
i_changes
&=
~
VOUT_CROP_CHANGE
;
p_vout
->
i_changes
&=
~
VOUT_ASPECT_CHANGE
;
p_vout
->
fmt_out
.
i_x_offset
=
p_vout
->
fmt_in
.
i_x_offset
;
p_vout
->
fmt_out
.
i_y_offset
=
p_vout
->
fmt_in
.
i_y_offset
;
p_vout
->
fmt_out
.
i_visible_width
=
p_vout
->
fmt_in
.
i_visible_width
;
p_vout
->
fmt_out
.
i_visible_height
=
p_vout
->
fmt_in
.
i_visible_height
;
p_vout
->
fmt_out
.
i_sar_num
=
p_vout
->
fmt_in
.
i_sar_num
;
p_vout
->
fmt_out
.
i_sar_den
=
p_vout
->
fmt_in
.
i_sar_den
;
p_vout
->
output
.
i_aspect
=
(
int64_t
)
VOUT_ASPECT_FACTOR
*
p_vout
->
fmt_in
.
i_sar_num
*
p_vout
->
fmt_in
.
i_width
/
(
p_vout
->
fmt_in
.
i_sar_den
*
p_vout
->
fmt_in
.
i_height
);
UpdateRects
(
p_vout
,
true
);
}
/* We used to call the Win32 PeekMessage function here to read the window
* messages. But since window can stay blocked into this function for a
* long time (for example when you move your window on the screen), I
* decided to isolate PeekMessage in another thread. */
/*
* Fullscreen change
*/
if
(
p_vout
->
i_changes
&
VOUT_FULLSCREEN_CHANGE
||
p_vout
->
p_sys
->
i_changes
&
VOUT_FULLSCREEN_CHANGE
)
{
Win32ToggleFullscreen
(
p_vout
);
p_vout
->
i_changes
&=
~
VOUT_FULLSCREEN_CHANGE
;
p_vout
->
p_sys
->
i_changes
&=
~
VOUT_FULLSCREEN_CHANGE
;
}
/*
* Pointer change
*/
EventThreadMouseAutoHide
(
p_vout
->
p_sys
->
p_event
);
/*
* "Always on top" status change
*/
if
(
p_vout
->
p_sys
->
b_on_top_change
)
{
HMENU
hMenu
=
GetSystemMenu
(
p_vout
->
p_sys
->
hwnd
,
FALSE
);
bool
b
=
var_GetBool
(
p_vout
,
"video-on-top"
);
/* Set the window on top if necessary */
if
(
b
&&
!
(
GetWindowLong
(
p_vout
->
p_sys
->
hwnd
,
GWL_EXSTYLE
)
&
WS_EX_TOPMOST
)
)
{
CheckMenuItem
(
hMenu
,
IDM_TOGGLE_ON_TOP
,
MF_BYCOMMAND
|
MFS_CHECKED
);
SetWindowPos
(
p_vout
->
p_sys
->
hwnd
,
HWND_TOPMOST
,
0
,
0
,
0
,
0
,
SWP_NOSIZE
|
SWP_NOMOVE
);
}
else
/* The window shouldn't be on top */
if
(
!
b
&&
(
GetWindowLong
(
p_vout
->
p_sys
->
hwnd
,
GWL_EXSTYLE
)
&
WS_EX_TOPMOST
)
)
{
CheckMenuItem
(
hMenu
,
IDM_TOGGLE_ON_TOP
,
MF_BYCOMMAND
|
MFS_UNCHECKED
);
SetWindowPos
(
p_vout
->
p_sys
->
hwnd
,
HWND_NOTOPMOST
,
0
,
0
,
0
,
0
,
SWP_NOSIZE
|
SWP_NOMOVE
);
}
p_vout
->
p_sys
->
b_on_top_change
=
false
;
}
}
/*****************************************************************************
* UpdateRects: update clipping rectangles
*****************************************************************************
* This function is called when the window position or size are changed, and
* its job is to update the source and destination RECTs used to display the
* picture.
*****************************************************************************/
void
UpdateRects
(
vout_thread_t
*
p_vout
,
bool
b_force
)
{
#define rect_src p_vout->p_sys->rect_src
#define rect_src_clipped p_vout->p_sys->rect_src_clipped
#define rect_dest p_vout->p_sys->rect_dest
#define rect_dest_clipped p_vout->p_sys->rect_dest_clipped
unsigned
int
i_width
,
i_height
,
i_x
,
i_y
;
RECT
rect
;
POINT
point
;
/* Retrieve the window size */
GetClientRect
(
p_vout
->
p_sys
->
hwnd
,
&
rect
);
/* Retrieve the window position */
point
.
x
=
point
.
y
=
0
;
ClientToScreen
(
p_vout
->
p_sys
->
hwnd
,
&
point
);
/* If nothing changed, we can return */
bool
b_changed
;
EventThreadUpdateWindowPosition
(
p_vout
->
p_sys
->
p_event
,
&
b_changed
,
point
.
x
,
point
.
y
,
rect
.
right
,
rect
.
bottom
);
if
(
!
b_force
&&
!
b_changed
)
return
;
/* Update the window position and size */
vout_PlacePicture
(
p_vout
,
rect
.
right
,
rect
.
bottom
,
&
i_x
,
&
i_y
,
&
i_width
,
&
i_height
);
if
(
p_vout
->
p_sys
->
hvideownd
)
SetWindowPos
(
p_vout
->
p_sys
->
hvideownd
,
0
,
i_x
,
i_y
,
i_width
,
i_height
,
SWP_NOCOPYBITS
|
SWP_NOZORDER
|
SWP_ASYNCWINDOWPOS
);
/* Destination image position and dimensions */
#if defined(MODULE_NAME_IS_direct3d)
rect_dest
.
left
=
0
;
rect_dest
.
right
=
i_width
;
rect_dest
.
top
=
0
;
rect_dest
.
bottom
=
i_height
;
#else
rect_dest
.
left
=
point
.
x
+
i_x
;
rect_dest
.
right
=
rect_dest
.
left
+
i_width
;
rect_dest
.
top
=
point
.
y
+
i_y
;
rect_dest
.
bottom
=
rect_dest
.
top
+
i_height
;
#ifdef MODULE_NAME_IS_directx
/* Apply overlay hardware constraints */
if
(
p_vout
->
p_sys
->
b_using_overlay
)
{
if
(
p_vout
->
p_sys
->
i_align_dest_boundary
)
rect_dest
.
left
=
(
rect_dest
.
left
+
p_vout
->
p_sys
->
i_align_dest_boundary
/
2
)
&
~
p_vout
->
p_sys
->
i_align_dest_boundary
;
if
(
p_vout
->
p_sys
->
i_align_dest_size
)
rect_dest
.
right
=
((
rect_dest
.
right
-
rect_dest
.
left
+
p_vout
->
p_sys
->
i_align_dest_size
/
2
)
&
~
p_vout
->
p_sys
->
i_align_dest_size
)
+
rect_dest
.
left
;
}
#endif
#endif
#if defined(MODULE_NAME_IS_directx) || defined(MODULE_NAME_IS_direct3d)
/* UpdateOverlay directdraw function doesn't automatically clip to the
* display size so we need to do it otherwise it will fail
* It is also needed for d3d to avoid exceding our surface size */
/* Clip the destination window */
if
(
!
IntersectRect
(
&
rect_dest_clipped
,
&
rect_dest
,
&
p_vout
->
p_sys
->
rect_display
)
)
{
SetRectEmpty
(
&
rect_src_clipped
);
return
;
}
#ifndef NDEBUG
msg_Dbg
(
p_vout
,
"DirectXUpdateRects image_dst_clipped coords:"
" %li,%li,%li,%li"
,
rect_dest_clipped
.
left
,
rect_dest_clipped
.
top
,
rect_dest_clipped
.
right
,
rect_dest_clipped
.
bottom
);
#endif
#else
/* AFAIK, there are no clipping constraints in Direct3D, OpenGL and GDI */
rect_dest_clipped
=
rect_dest
;
#endif
/* the 2 following lines are to fix a bug when clicking on the desktop */
if
(
(
rect_dest_clipped
.
right
-
rect_dest_clipped
.
left
)
==
0
||
(
rect_dest_clipped
.
bottom
-
rect_dest_clipped
.
top
)
==
0
)
{
SetRectEmpty
(
&
rect_src_clipped
);
return
;
}
/* src image dimensions */
rect_src
.
left
=
0
;
rect_src
.
top
=
0
;
rect_src
.
right
=
p_vout
->
render
.
i_width
;
rect_src
.
bottom
=
p_vout
->
render
.
i_height
;
/* Clip the source image */
rect_src_clipped
.
left
=
p_vout
->
fmt_out
.
i_x_offset
+
(
rect_dest_clipped
.
left
-
rect_dest
.
left
)
*
p_vout
->
fmt_out
.
i_visible_width
/
(
rect_dest
.
right
-
rect_dest
.
left
);
rect_src_clipped
.
right
=
p_vout
->
fmt_out
.
i_x_offset
+
p_vout
->
fmt_out
.
i_visible_width
-
(
rect_dest
.
right
-
rect_dest_clipped
.
right
)
*
p_vout
->
fmt_out
.
i_visible_width
/
(
rect_dest
.
right
-
rect_dest
.
left
);
rect_src_clipped
.
top
=
p_vout
->
fmt_out
.
i_y_offset
+
(
rect_dest_clipped
.
top
-
rect_dest
.
top
)
*
p_vout
->
fmt_out
.
i_visible_height
/
(
rect_dest
.
bottom
-
rect_dest
.
top
);
rect_src_clipped
.
bottom
=
p_vout
->
fmt_out
.
i_y_offset
+
p_vout
->
fmt_out
.
i_visible_height
-
(
rect_dest
.
bottom
-
rect_dest_clipped
.
bottom
)
*
p_vout
->
fmt_out
.
i_visible_height
/
(
rect_dest
.
bottom
-
rect_dest
.
top
);
#ifdef MODULE_NAME_IS_directx
/* Apply overlay hardware constraints */
if
(
p_vout
->
p_sys
->
b_using_overlay
)
{
if
(
p_vout
->
p_sys
->
i_align_src_boundary
)
rect_src_clipped
.
left
=
(
rect_src_clipped
.
left
+
p_vout
->
p_sys
->
i_align_src_boundary
/
2
)
&
~
p_vout
->
p_sys
->
i_align_src_boundary
;
if
(
p_vout
->
p_sys
->
i_align_src_size
)
rect_src_clipped
.
right
=
((
rect_src_clipped
.
right
-
rect_src_clipped
.
left
+
p_vout
->
p_sys
->
i_align_src_size
/
2
)
&
~
p_vout
->
p_sys
->
i_align_src_size
)
+
rect_src_clipped
.
left
;
}
#elif defined(MODULE_NAME_IS_direct3d)
/* Needed at least with YUV content */
rect_src_clipped
.
left
&=
~
1
;
rect_src_clipped
.
right
&=
~
1
;
rect_src_clipped
.
top
&=
~
1
;
rect_src_clipped
.
bottom
&=
~
1
;
#endif
#ifndef NDEBUG
msg_Dbg
(
p_vout
,
"DirectXUpdateRects image_src_clipped"
" coords: %li,%li,%li,%li"
,
rect_src_clipped
.
left
,
rect_src_clipped
.
top
,
rect_src_clipped
.
right
,
rect_src_clipped
.
bottom
);
#endif
#ifdef MODULE_NAME_IS_directx
/* The destination coordinates need to be relative to the current
* directdraw primary surface (display) */
rect_dest_clipped
.
left
-=
p_vout
->
p_sys
->
rect_display
.
left
;
rect_dest_clipped
.
right
-=
p_vout
->
p_sys
->
rect_display
.
left
;
rect_dest_clipped
.
top
-=
p_vout
->
p_sys
->
rect_display
.
top
;
rect_dest_clipped
.
bottom
-=
p_vout
->
p_sys
->
rect_display
.
top
;
if
(
p_vout
->
p_sys
->
b_using_overlay
)
DirectDrawUpdateOverlay
(
p_vout
);
#endif
#ifndef UNDER_CE
/* Windows 7 taskbar thumbnail code */
LPTASKBARLIST3
p_taskbl
;
OSVERSIONINFO
winVer
;
winVer
.
dwOSVersionInfoSize
=
sizeof
(
OSVERSIONINFO
);
if
(
GetVersionEx
(
&
winVer
)
&&
winVer
.
dwMajorVersion
>
5
)
{
CoInitialize
(
0
);
if
(
S_OK
==
CoCreateInstance
(
&
clsid_ITaskbarList
,
NULL
,
CLSCTX_INPROC_SERVER
,
&
IID_ITaskbarList3
,
&
p_taskbl
)
)
{
RECT
rect_video
,
rect_parent
,
rect_relative
;
HWND
hroot
=
GetAncestor
(
p_vout
->
p_sys
->
hwnd
,
GA_ROOT
);
p_taskbl
->
vt
->
HrInit
(
p_taskbl
);
GetWindowRect
(
p_vout
->
p_sys
->
hvideownd
,
&
rect_video
);
GetWindowRect
(
hroot
,
&
rect_parent
);
rect_relative
.
left
=
rect_video
.
left
-
rect_parent
.
left
-
8
;
rect_relative
.
right
=
rect_video
.
right
-
rect_video
.
left
+
rect_relative
.
left
;
rect_relative
.
top
=
rect_video
.
top
-
rect_parent
.
top
-
10
;
rect_relative
.
bottom
=
rect_video
.
bottom
-
rect_video
.
top
+
rect_relative
.
top
-
25
;
if
(
S_OK
!=
p_taskbl
->
vt
->
SetThumbnailClip
(
p_taskbl
,
hroot
,
&
rect_relative
))
msg_Err
(
p_vout
,
"SetThumbNailClip failed"
);
p_taskbl
->
vt
->
Release
(
p_taskbl
);
}
CoUninitialize
();
}
#endif
/* Signal the change in size/position */
p_vout
->
p_sys
->
i_changes
|=
DX_POSITION_CHANGE
;
#undef rect_src
#undef rect_src_clipped
#undef rect_dest
#undef rect_dest_clipped
}
/*****************************************************************************
* Control: control facility for the vout
*****************************************************************************/
int
Control
(
vout_thread_t
*
p_vout
,
int
i_query
,
va_list
args
)
{
RECT
rect_window
;
switch
(
i_query
)
{
case
VOUT_SET_SIZE
:
if
(
p_vout
->
p_sys
->
parent_window
)
return
vaControlParentWindow
(
p_vout
,
i_query
,
args
);
/* Update dimensions */
rect_window
.
top
=
rect_window
.
left
=
0
;
rect_window
.
right
=
va_arg
(
args
,
unsigned
int
);
rect_window
.
bottom
=
va_arg
(
args
,
unsigned
int
);
if
(
!
rect_window
.
right
)
rect_window
.
right
=
p_vout
->
i_window_width
;
if
(
!
rect_window
.
bottom
)
rect_window
.
bottom
=
p_vout
->
i_window_height
;
AdjustWindowRect
(
&
rect_window
,
EventThreadGetWindowStyle
(
p_vout
->
p_sys
->
p_event
),
0
);
SetWindowPos
(
p_vout
->
p_sys
->
hwnd
,
0
,
0
,
0
,
rect_window
.
right
-
rect_window
.
left
,
rect_window
.
bottom
-
rect_window
.
top
,
SWP_NOMOVE
);
return
VLC_SUCCESS
;
case
VOUT_SET_STAY_ON_TOP
:
if
(
p_vout
->
p_sys
->
hparent
&&
!
var_GetBool
(
p_vout
,
"fullscreen"
)
)
return
vaControlParentWindow
(
p_vout
,
i_query
,
args
);
p_vout
->
p_sys
->
b_on_top_change
=
true
;
return
VLC_SUCCESS
;
default:
return
VLC_EGENERIC
;
}
}
/* Internal wrapper over GetWindowPlacement */
static
WINDOWPLACEMENT
getWindowState
(
HWND
hwnd
)
{
WINDOWPLACEMENT
window_placement
;
window_placement
.
length
=
sizeof
(
WINDOWPLACEMENT
);
GetWindowPlacement
(
hwnd
,
&
window_placement
);
return
window_placement
;
}
/* Internal wrapper to call vout_ControlWindow for hparent */
static
int
vaControlParentWindow
(
vout_thread_t
*
p_vout
,
int
i_query
,
va_list
args
)
{
switch
(
i_query
)
{
case
VOUT_SET_SIZE
:
{
const
unsigned
i_width
=
va_arg
(
args
,
unsigned
);
const
unsigned
i_height
=
va_arg
(
args
,
unsigned
);
return
vout_window_SetSize
(
p_vout
->
p_sys
->
parent_window
,
i_width
,
i_height
);
}
case
VOUT_SET_STAY_ON_TOP
:
{
const
bool
is_on_top
=
va_arg
(
args
,
int
);
return
vout_window_SetState
(
p_vout
->
p_sys
->
parent_window
,
is_on_top
);
}
default:
return
VLC_EGENERIC
;
}
}
#if 0
static int ControlParentWindow( vout_thread_t *p_vout, int i_query, ... )
{
va_list args;
int ret;
va_start( args, i_query );
ret = vaControlParentWindow( p_vout, i_query, args );
va_end( args );
return ret;
}
#endif
void
ExitFullscreen
(
vout_thread_t
*
p_vout
)
{
if
(
p_vout
->
b_fullscreen
)
{
msg_Dbg
(
p_vout
,
"Quitting fullscreen"
);
Win32ToggleFullscreen
(
p_vout
);
/* Force fullscreen in the core for the next video */
var_SetBool
(
p_vout
,
"fullscreen"
,
true
);
}
}
void
Win32ToggleFullscreen
(
vout_thread_t
*
p_vout
)
{
HWND
hwnd
=
(
p_vout
->
p_sys
->
hparent
&&
p_vout
->
p_sys
->
hfswnd
)
?
p_vout
->
p_sys
->
hfswnd
:
p_vout
->
p_sys
->
hwnd
;
/* Save the current windows placement/placement to restore
when fullscreen is over */
WINDOWPLACEMENT
window_placement
=
getWindowState
(
hwnd
);
p_vout
->
b_fullscreen
=
!
p_vout
->
b_fullscreen
;
if
(
p_vout
->
p_sys
->
parent_window
)
{
vout_window_SetFullScreen
(
p_vout
->
p_sys
->
parent_window
,
p_vout
->
b_fullscreen
);
return
;
}
/* We want to go to Fullscreen */
if
(
p_vout
->
b_fullscreen
)
{
msg_Dbg
(
p_vout
,
"entering fullscreen mode"
);
/* Change window style, no borders and no title bar */
int
i_style
=
WS_CLIPCHILDREN
|
WS_VISIBLE
;
SetWindowLong
(
hwnd
,
GWL_STYLE
,
i_style
);
if
(
p_vout
->
p_sys
->
hparent
)
{
#ifdef UNDER_CE
POINT
point
=
{
0
,
0
};
RECT
rect
;
ClientToScreen
(
p_vout
->
p_sys
->
hwnd
,
&
point
);
GetClientRect
(
p_vout
->
p_sys
->
hwnd
,
&
rect
);
SetWindowPos
(
hwnd
,
0
,
point
.
x
,
point
.
y
,
rect
.
right
,
rect
.
bottom
,
SWP_NOZORDER
|
SWP_FRAMECHANGED
);
#else
/* Retrieve current window position so fullscreen will happen
*on the right screen */
HMONITOR
hmon
=
MonitorFromWindow
(
p_vout
->
p_sys
->
hparent
,
MONITOR_DEFAULTTONEAREST
);
MONITORINFO
mi
;
mi
.
cbSize
=
sizeof
(
MONITORINFO
);
if
(
GetMonitorInfo
(
hmon
,
&
mi
))
SetWindowPos
(
hwnd
,
0
,
mi
.
rcMonitor
.
left
,
mi
.
rcMonitor
.
top
,
mi
.
rcMonitor
.
right
-
mi
.
rcMonitor
.
left
,
mi
.
rcMonitor
.
bottom
-
mi
.
rcMonitor
.
top
,
SWP_NOZORDER
|
SWP_FRAMECHANGED
);
#endif
}
else
{
/* Maximize non embedded window */
ShowWindow
(
hwnd
,
SW_SHOWMAXIMIZED
);
}
if
(
p_vout
->
p_sys
->
hparent
)
{
/* Hide the previous window */
RECT
rect
;
GetClientRect
(
hwnd
,
&
rect
);
SetParent
(
p_vout
->
p_sys
->
hwnd
,
hwnd
);
SetWindowPos
(
p_vout
->
p_sys
->
hwnd
,
0
,
0
,
0
,
rect
.
right
,
rect
.
bottom
,
SWP_NOZORDER
|
SWP_FRAMECHANGED
);
#ifdef UNDER_CE
HWND
topLevelParent
=
GetParent
(
p_vout
->
p_sys
->
hparent
);
#else
HWND
topLevelParent
=
GetAncestor
(
p_vout
->
p_sys
->
hparent
,
GA_ROOT
);
#endif
ShowWindow
(
topLevelParent
,
SW_HIDE
);
}
SetForegroundWindow
(
hwnd
);
}
else
{
msg_Dbg
(
p_vout
,
"leaving fullscreen mode"
);
/* Change window style, no borders and no title bar */
SetWindowLong
(
hwnd
,
GWL_STYLE
,
EventThreadGetWindowStyle
(
p_vout
->
p_sys
->
p_event
)
);
if
(
p_vout
->
p_sys
->
hparent
)
{
RECT
rect
;
GetClientRect
(
p_vout
->
p_sys
->
hparent
,
&
rect
);
SetParent
(
p_vout
->
p_sys
->
hwnd
,
p_vout
->
p_sys
->
hparent
);
SetWindowPos
(
p_vout
->
p_sys
->
hwnd
,
0
,
0
,
0
,
rect
.
right
,
rect
.
bottom
,
SWP_NOZORDER
|
SWP_FRAMECHANGED
);
#ifdef UNDER_CE
HWND
topLevelParent
=
GetParent
(
p_vout
->
p_sys
->
hparent
);
#else
HWND
topLevelParent
=
GetAncestor
(
p_vout
->
p_sys
->
hparent
,
GA_ROOT
);
#endif
ShowWindow
(
topLevelParent
,
SW_SHOW
);
SetForegroundWindow
(
p_vout
->
p_sys
->
hparent
);
ShowWindow
(
hwnd
,
SW_HIDE
);
}
else
{
/* return to normal window for non embedded vout */
SetWindowPlacement
(
hwnd
,
&
window_placement
);
ShowWindow
(
hwnd
,
SW_SHOWNORMAL
);
}
/* Make sure the mouse cursor is displayed */
EventThreadMouseShow
(
p_vout
->
p_sys
->
p_event
);
}
/* Update the object variable and trigger callback */
var_SetBool
(
p_vout
,
"fullscreen"
,
p_vout
->
b_fullscreen
);
}
#ifndef UNDER_CE
void
DisableScreensaver
(
vout_thread_t
*
p_vout
)
{
/* disable screensaver by temporarily changing system settings */
p_vout
->
p_sys
->
i_spi_lowpowertimeout
=
0
;
p_vout
->
p_sys
->
i_spi_powerofftimeout
=
0
;
p_vout
->
p_sys
->
i_spi_screensavetimeout
=
0
;
if
(
var_GetBool
(
p_vout
,
"disable-screensaver"
)
)
{
msg_Dbg
(
p_vout
,
"disabling screen saver"
);
SystemParametersInfo
(
SPI_GETLOWPOWERTIMEOUT
,
0
,
&
(
p_vout
->
p_sys
->
i_spi_lowpowertimeout
),
0
);
if
(
0
!=
p_vout
->
p_sys
->
i_spi_lowpowertimeout
)
{
SystemParametersInfo
(
SPI_SETLOWPOWERTIMEOUT
,
0
,
NULL
,
0
);
}
SystemParametersInfo
(
SPI_GETPOWEROFFTIMEOUT
,
0
,
&
(
p_vout
->
p_sys
->
i_spi_powerofftimeout
),
0
);
if
(
0
!=
p_vout
->
p_sys
->
i_spi_powerofftimeout
)
{
SystemParametersInfo
(
SPI_SETPOWEROFFTIMEOUT
,
0
,
NULL
,
0
);
}
SystemParametersInfo
(
SPI_GETSCREENSAVETIMEOUT
,
0
,
&
(
p_vout
->
p_sys
->
i_spi_screensavetimeout
),
0
);
if
(
0
!=
p_vout
->
p_sys
->
i_spi_screensavetimeout
)
{
SystemParametersInfo
(
SPI_SETSCREENSAVETIMEOUT
,
0
,
NULL
,
0
);
}
}
}
void
RestoreScreensaver
(
vout_thread_t
*
p_vout
)
{
/* restore screensaver system settings */
if
(
0
!=
p_vout
->
p_sys
->
i_spi_lowpowertimeout
)
{
SystemParametersInfo
(
SPI_SETLOWPOWERTIMEOUT
,
p_vout
->
p_sys
->
i_spi_lowpowertimeout
,
NULL
,
0
);
}
if
(
0
!=
p_vout
->
p_sys
->
i_spi_powerofftimeout
)
{
SystemParametersInfo
(
SPI_SETPOWEROFFTIMEOUT
,
p_vout
->
p_sys
->
i_spi_powerofftimeout
,
NULL
,
0
);
}
if
(
0
!=
p_vout
->
p_sys
->
i_spi_screensavetimeout
)
{
SystemParametersInfo
(
SPI_SETSCREENSAVETIMEOUT
,
p_vout
->
p_sys
->
i_spi_screensavetimeout
,
NULL
,
0
);
}
}
#endif
modules/video_output/msw/events_vo.c
deleted
100644 → 0
View file @
25d33b29
/*****************************************************************************
* events.c: Windows DirectX video output events handler
*****************************************************************************
* Copyright (C) 2001-2009 the VideoLAN team
* $Id$
*
* Authors: Gildas Bazin <gbazin@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble: This file contains the functions related to the creation of
* a window and the handling of its messages (events).
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include <vlc_playlist.h>
#include <vlc_vout.h>
#include <vlc_vout_window.h>
#include <windows.h>
#include <windowsx.h>
#include <shellapi.h>
#include <ctype.h>
#ifdef MODULE_NAME_IS_directx
#include <ddraw.h>
#endif
#ifdef MODULE_NAME_IS_direct3d
#include <d3d9.h>
#endif
#ifdef MODULE_NAME_IS_glwin32
#include <GL/gl.h>
#endif
#include <vlc_keys.h>
#include "vout.h"
#ifdef UNDER_CE
#include <aygshell.h>
//WINSHELLAPI BOOL WINAPI SHFullScreen(HWND hwndRequester, DWORD dwState);
#endif
/*#if defined(UNDER_CE) && !defined(__PLUGIN__) --FIXME*/
/*# define SHFS_SHOWSIPBUTTON 0x0004
# define SHFS_HIDESIPBUTTON 0x0008
# define MENU_HEIGHT 26
BOOL SHFullScreen(HWND hwndRequester, DWORD dwState);
#endif*/
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
#define WM_VLC_HIDE_MOUSE (WM_APP + 0)
#define WM_VLC_SHOW_MOUSE (WM_APP + 1)
#define WM_VLC_CHANGE_TEXT (WM_APP + 2)
struct
event_thread_t
{
vout_thread_t
*
p_vout
;
/* */
vlc_thread_t
thread
;
vlc_mutex_t
lock
;
vlc_cond_t
wait
;
bool
b_ready
;
bool
b_done
;
bool
b_error
;
/* */
bool
use_desktop
;
bool
use_overlay
;
/* Mouse */
volatile
bool
b_cursor_hidden
;
volatile
mtime_t
i_lastmoved
;
mtime_t
i_mouse_hide_timeout
;
/* Title */
char
*
psz_title
;
int
i_window_style
;
vout_window_cfg_t
wnd_cfg
;
/* */
unsigned
i_changes
;
/* */
vout_window_t
*
parent_window
;
HWND
hparent
;
HWND
hwnd
;
HWND
hvideownd
;
HWND
hfswnd
;
};
static
int
DirectXCreateWindow
(
event_thread_t
*
);
static
void
DirectXCloseWindow
(
event_thread_t
*
);
static
long
FAR
PASCAL
DirectXEventProc
(
HWND
,
UINT
,
WPARAM
,
LPARAM
);
static
void
DirectXPopupMenu
(
event_thread_t
*
p_event
,
bool
b_open
)
{
var_SetBool
(
p_event
->
p_vout
->
p_libvlc
,
"intf-popupmenu"
,
b_open
);
}
static
int
DirectXConvertKey
(
int
i_key
);
/*****************************************************************************
* EventThread: Create video window & handle its messages
*****************************************************************************
* This function creates a video window and then enters an infinite loop
* that handles the messages sent to that window.
* The main goal of this thread is to isolate the Win32 PeekMessage function
* because this one can block for a long time.
*****************************************************************************/
static
void
*
EventThread
(
void
*
p_this
)
{
event_thread_t
*
p_event
=
(
event_thread_t
*
)
p_this
;
vout_thread_t
*
p_vout
=
p_event
->
p_vout
;
MSG
msg
;
POINT
old_mouse_pos
=
{
0
,
0
},
mouse_pos
;
vlc_value_t
val
;
unsigned
int
i_width
,
i_height
,
i_x
,
i_y
;
HMODULE
hkernel32
;
int
canc
=
vlc_savecancel
();
vlc_mutex_lock
(
&
p_event
->
lock
);
/* Create a window for the video */
/* Creating a window under Windows also initializes the thread's event
* message queue */
if
(
DirectXCreateWindow
(
p_event
)
)
p_event
->
b_error
=
true
;
p_event
->
b_ready
=
true
;
vlc_cond_signal
(
&
p_event
->
wait
);
const
bool
b_error
=
p_event
->
b_error
;
vlc_mutex_unlock
(
&
p_event
->
lock
);
if
(
b_error
)
{
vlc_restorecancel
(
canc
);
return
NULL
;
}
#ifndef UNDER_CE
/* Set power management stuff */
if
(
(
hkernel32
=
GetModuleHandle
(
_T
(
"KERNEL32"
)
)
)
)
{
ULONG
(
WINAPI
*
OurSetThreadExecutionState
)(
ULONG
);
OurSetThreadExecutionState
=
(
ULONG
(
WINAPI
*
)(
ULONG
))
GetProcAddress
(
hkernel32
,
_T
(
"SetThreadExecutionState"
)
);
if
(
OurSetThreadExecutionState
)
/* Prevent monitor from powering off */
OurSetThreadExecutionState
(
ES_DISPLAY_REQUIRED
|
ES_CONTINUOUS
);
else
msg_Dbg
(
p_vout
,
"no support for SetThreadExecutionState()"
);
}
#endif
/* Main loop */
/* GetMessage will sleep if there's no message in the queue */
for
(
;;
)
{
if
(
!
GetMessage
(
&
msg
,
0
,
0
,
0
)
)
{
vlc_mutex_lock
(
&
p_event
->
lock
);
p_event
->
b_done
=
true
;
vlc_mutex_unlock
(
&
p_event
->
lock
);
break
;
}
/* Check if we are asked to exit */
vlc_mutex_lock
(
&
p_event
->
lock
);
const
bool
b_done
=
p_event
->
b_done
;
vlc_mutex_unlock
(
&
p_event
->
lock
);
if
(
b_done
)
break
;
/* */
switch
(
msg
.
message
)
{
case
WM_MOUSEMOVE
:
vlc_mutex_lock
(
&
p_event
->
lock
);
vout_PlacePicture
(
p_event
->
p_vout
,
p_event
->
wnd_cfg
.
width
,
p_event
->
wnd_cfg
.
height
,
&
i_x
,
&
i_y
,
&
i_width
,
&
i_height
);
vlc_mutex_unlock
(
&
p_event
->
lock
);
if
(
msg
.
hwnd
==
p_event
->
hvideownd
)
{
/* Child window */
i_x
=
i_y
=
0
;
}
if
(
i_width
&&
i_height
)
{
val
.
i_int
=
(
GET_X_LPARAM
(
msg
.
lParam
)
-
i_x
)
*
p_event
->
p_vout
->
fmt_in
.
i_visible_width
/
i_width
+
p_event
->
p_vout
->
fmt_in
.
i_x_offset
;
var_Set
(
p_event
->
p_vout
,
"mouse-x"
,
val
);
val
.
i_int
=
(
GET_Y_LPARAM
(
msg
.
lParam
)
-
i_y
)
*
p_event
->
p_vout
->
fmt_in
.
i_visible_height
/
i_height
+
p_event
->
p_vout
->
fmt_in
.
i_y_offset
;
var_Set
(
p_event
->
p_vout
,
"mouse-y"
,
val
);
var_SetBool
(
p_event
->
p_vout
,
"mouse-moved"
,
true
);
}
case
WM_NCMOUSEMOVE
:
GetCursorPos
(
&
mouse_pos
);
if
(
(
abs
(
mouse_pos
.
x
-
old_mouse_pos
.
x
)
>
2
||
(
abs
(
mouse_pos
.
y
-
old_mouse_pos
.
y
))
>
2
)
)
{
GetCursorPos
(
&
old_mouse_pos
);
p_event
->
i_lastmoved
=
mdate
();
if
(
p_event
->
b_cursor_hidden
)
{
p_event
->
b_cursor_hidden
=
0
;
ShowCursor
(
TRUE
);
}
}
break
;
case
WM_VLC_HIDE_MOUSE
:
if
(
p_event
->
b_cursor_hidden
)
break
;
p_event
->
b_cursor_hidden
=
true
;
GetCursorPos
(
&
old_mouse_pos
);
ShowCursor
(
FALSE
);
break
;
case
WM_VLC_SHOW_MOUSE
:
if
(
!
p_event
->
b_cursor_hidden
)
break
;
p_event
->
b_cursor_hidden
=
false
;
GetCursorPos
(
&
old_mouse_pos
);
ShowCursor
(
TRUE
);
break
;
case
WM_LBUTTONDOWN
:
var_Get
(
p_event
->
p_vout
,
"mouse-button-down"
,
&
val
);
val
.
i_int
|=
1
;
var_Set
(
p_event
->
p_vout
,
"mouse-button-down"
,
val
);
DirectXPopupMenu
(
p_event
,
false
);
break
;
case
WM_LBUTTONUP
:
var_Get
(
p_event
->
p_vout
,
"mouse-button-down"
,
&
val
);
val
.
i_int
&=
~
1
;
var_Set
(
p_event
->
p_vout
,
"mouse-button-down"
,
val
);
var_SetBool
(
p_event
->
p_vout
,
"mouse-clicked"
,
true
);
break
;
case
WM_LBUTTONDBLCLK
:
vlc_mutex_lock
(
&
p_event
->
lock
);
p_event
->
i_changes
|=
VOUT_FULLSCREEN_CHANGE
;
vlc_mutex_unlock
(
&
p_event
->
lock
);
break
;
case
WM_MBUTTONDOWN
:
var_Get
(
p_event
->
p_vout
,
"mouse-button-down"
,
&
val
);
val
.
i_int
|=
2
;
var_Set
(
p_event
->
p_vout
,
"mouse-button-down"
,
val
);
DirectXPopupMenu
(
p_event
,
false
);
var_ToggleBool
(
p_event
->
p_vout
->
p_libvlc
,
"intf-show"
);
break
;
case
WM_MBUTTONUP
:
var_Get
(
p_event
->
p_vout
,
"mouse-button-down"
,
&
val
);
val
.
i_int
&=
~
2
;
var_Set
(
p_event
->
p_vout
,
"mouse-button-down"
,
val
);
break
;
case
WM_RBUTTONDOWN
:
var_Get
(
p_event
->
p_vout
,
"mouse-button-down"
,
&
val
);
val
.
i_int
|=
4
;
var_Set
(
p_event
->
p_vout
,
"mouse-button-down"
,
val
);
DirectXPopupMenu
(
p_event
,
false
);
break
;
case
WM_RBUTTONUP
:
var_Get
(
p_event
->
p_vout
,
"mouse-button-down"
,
&
val
);
val
.
i_int
&=
~
4
;
var_Set
(
p_event
->
p_vout
,
"mouse-button-down"
,
val
);
DirectXPopupMenu
(
p_event
,
true
);
break
;
case
WM_KEYDOWN
:
case
WM_SYSKEYDOWN
:
/* 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. */
val
.
i_int
=
DirectXConvertKey
(
msg
.
wParam
);
if
(
!
val
.
i_int
)
{
/* This appears to be a "normal" (ascii) key */
val
.
i_int
=
tolower
(
MapVirtualKey
(
msg
.
wParam
,
2
)
);
}
if
(
val
.
i_int
)
{
if
(
GetKeyState
(
VK_CONTROL
)
&
0x8000
)
{
val
.
i_int
|=
KEY_MODIFIER_CTRL
;
}
if
(
GetKeyState
(
VK_SHIFT
)
&
0x8000
)
{
val
.
i_int
|=
KEY_MODIFIER_SHIFT
;
}
if
(
GetKeyState
(
VK_MENU
)
&
0x8000
)
{
val
.
i_int
|=
KEY_MODIFIER_ALT
;
}
var_Set
(
p_vout
->
p_libvlc
,
"key-pressed"
,
val
);
}
break
;
case
WM_MOUSEWHEEL
:
if
(
GET_WHEEL_DELTA_WPARAM
(
msg
.
wParam
)
>
0
)
{
val
.
i_int
=
KEY_MOUSEWHEELUP
;
}
else
{
val
.
i_int
=
KEY_MOUSEWHEELDOWN
;
}
if
(
val
.
i_int
)
{
if
(
GetKeyState
(
VK_CONTROL
)
&
0x8000
)
{
val
.
i_int
|=
KEY_MODIFIER_CTRL
;
}
if
(
GetKeyState
(
VK_SHIFT
)
&
0x8000
)
{
val
.
i_int
|=
KEY_MODIFIER_SHIFT
;
}
if
(
GetKeyState
(
VK_MENU
)
&
0x8000
)
{
val
.
i_int
|=
KEY_MODIFIER_ALT
;
}
var_Set
(
p_vout
->
p_libvlc
,
"key-pressed"
,
val
);
}
break
;
case
WM_VLC_CHANGE_TEXT
:
{
vlc_mutex_lock
(
&
p_event
->
lock
);
wchar_t
*
pwz_title
=
NULL
;
if
(
p_event
->
psz_title
)
{
const
size_t
i_length
=
strlen
(
p_event
->
psz_title
);
pwz_title
=
malloc
(
2
*
(
i_length
+
1
)
);
if
(
pwz_title
)
{
mbstowcs
(
pwz_title
,
p_event
->
psz_title
,
2
*
i_length
);
pwz_title
[
i_length
]
=
0
;
}
}
vlc_mutex_unlock
(
&
p_event
->
lock
);
if
(
pwz_title
)
{
SetWindowText
(
p_event
->
hwnd
,
(
LPCTSTR
)
pwz_title
);
if
(
p_event
->
hfswnd
)
SetWindowText
(
p_event
->
hfswnd
,
(
LPCTSTR
)
pwz_title
);
free
(
pwz_title
);
}
break
;
}
default:
/* Messages we don't handle directly are dispatched to the
* window procedure */
TranslateMessage
(
&
msg
);
DispatchMessage
(
&
msg
);
break
;
}
/* End Switch */
}
/* End Main loop */
/* Check for WM_QUIT if we created the window */
if
(
!
p_event
->
hparent
&&
msg
.
message
==
WM_QUIT
)
{
msg_Warn
(
p_vout
,
"WM_QUIT... should not happen!!"
);
p_event
->
hwnd
=
NULL
;
/* Window already destroyed */
}
msg_Dbg
(
p_vout
,
"DirectXEventThread terminating"
);
DirectXCloseWindow
(
p_event
);
vlc_restorecancel
(
canc
);
return
NULL
;
}
/* following functions are local */
/*****************************************************************************
* DirectXCreateWindow: create a window for the video.
*****************************************************************************
* Before creating a direct draw surface, we need to create a window in which
* the video will be displayed. This window will also allow us to capture the
* events.
*****************************************************************************/
static
int
DirectXCreateWindow
(
event_thread_t
*
p_event
)
{
vout_thread_t
*
p_vout
=
p_event
->
p_vout
;
HINSTANCE
hInstance
;
HMENU
hMenu
;
RECT
rect_window
;
WNDCLASS
wc
;
/* window class components */
HICON
vlc_icon
;
char
vlc_path
[
MAX_PATH
+
1
];
int
i_style
,
i_stylex
;
msg_Dbg
(
p_vout
,
"DirectXCreateWindow"
);
/* Get this module's instance */
hInstance
=
GetModuleHandle
(
NULL
);
#ifdef MODULE_NAME_IS_direct3d
if
(
!
p_event
->
use_desktop
)
{
#endif
/* If an external window was specified, we'll draw in it. */
p_event
->
parent_window
=
vout_window_New
(
VLC_OBJECT
(
p_vout
),
NULL
,
&
p_event
->
wnd_cfg
);
if
(
p_event
->
parent_window
)
p_event
->
hparent
=
p_event
->
parent_window
->
hwnd
;
else
p_event
->
hparent
=
NULL
;
#ifdef MODULE_NAME_IS_direct3d
}
else
{
/* Find Program Manager */
HWND
hwnd
=
FindWindow
(
_T
(
"Progman"
),
NULL
);
if
(
hwnd
)
hwnd
=
FindWindowEx
(
hwnd
,
NULL
,
_T
(
"SHELLDLL_DefView"
),
NULL
);
if
(
hwnd
)
hwnd
=
FindWindowEx
(
hwnd
,
NULL
,
_T
(
"SysListView32"
),
NULL
);
if
(
!
hwnd
)
msg_Err
(
p_vout
,
"Couldn't find desktop icon window. Desktop mode can't be established."
);
p_event
->
hparent
=
hwnd
;
}
#endif
/* Get the Icon from the main app */
vlc_icon
=
NULL
;
#ifndef UNDER_CE
if
(
GetModuleFileName
(
NULL
,
vlc_path
,
MAX_PATH
)
)
{
vlc_icon
=
ExtractIcon
(
hInstance
,
vlc_path
,
0
);
}
#endif
/* Fill in the window class structure */
wc
.
style
=
CS_OWNDC
|
CS_DBLCLKS
;
/* style: dbl click */
wc
.
lpfnWndProc
=
(
WNDPROC
)
DirectXEventProc
;
/* event handler */
wc
.
cbClsExtra
=
0
;
/* no extra class data */
wc
.
cbWndExtra
=
0
;
/* no extra window data */
wc
.
hInstance
=
hInstance
;
/* instance */
wc
.
hIcon
=
vlc_icon
;
/* load the vlc big icon */
wc
.
hCursor
=
LoadCursor
(
NULL
,
IDC_ARROW
);
/* default cursor */
wc
.
hbrBackground
=
GetStockObject
(
BLACK_BRUSH
);
/* background color */
wc
.
lpszMenuName
=
NULL
;
/* no menu */
wc
.
lpszClassName
=
_T
(
"VLC DirectX"
);
/* use a special class */
/* Register the window class */
if
(
!
RegisterClass
(
&
wc
)
)
{
WNDCLASS
wndclass
;
if
(
vlc_icon
)
DestroyIcon
(
vlc_icon
);
/* Check why it failed. If it's because one already exists
* then fine, otherwise return with an error. */
if
(
!
GetClassInfo
(
hInstance
,
_T
(
"VLC DirectX"
),
&
wndclass
)
)
{
msg_Err
(
p_vout
,
"DirectXCreateWindow RegisterClass FAILED (err=%lu)"
,
GetLastError
()
);
return
VLC_EGENERIC
;
}
}
/* Register the video sub-window class */
wc
.
lpszClassName
=
_T
(
"VLC DirectX video"
);
wc
.
hIcon
=
0
;
wc
.
hbrBackground
=
NULL
;
/* no background color */
if
(
!
RegisterClass
(
&
wc
)
)
{
WNDCLASS
wndclass
;
/* Check why it failed. If it's because one already exists
* then fine, otherwise return with an error. */
if
(
!
GetClassInfo
(
hInstance
,
_T
(
"VLC DirectX video"
),
&
wndclass
)
)
{
msg_Err
(
p_vout
,
"DirectXCreateWindow RegisterClass FAILED (err=%lu)"
,
GetLastError
()
);
return
VLC_EGENERIC
;
}
}
/* When you create a window you give the dimensions you wish it to
* have. Unfortunatly these dimensions will include the borders and
* titlebar. We use the following function to find out the size of
* the window corresponding to the useable surface we want */
rect_window
.
top
=
10
;
rect_window
.
left
=
10
;
rect_window
.
right
=
rect_window
.
left
+
p_event
->
wnd_cfg
.
width
;
rect_window
.
bottom
=
rect_window
.
top
+
p_event
->
wnd_cfg
.
height
;
if
(
var_GetBool
(
p_vout
,
"video-deco"
)
)
{
/* Open with window decoration */
AdjustWindowRect
(
&
rect_window
,
WS_OVERLAPPEDWINDOW
|
WS_SIZEBOX
,
0
);
i_style
=
WS_OVERLAPPEDWINDOW
|
WS_SIZEBOX
|
WS_VISIBLE
|
WS_CLIPCHILDREN
;
i_stylex
=
0
;
}
else
{
/* No window decoration */
AdjustWindowRect
(
&
rect_window
,
WS_POPUP
,
0
);
i_style
=
WS_POPUP
|
WS_VISIBLE
|
WS_CLIPCHILDREN
;
i_stylex
=
0
;
// WS_EX_TOOLWINDOW; Is TOOLWINDOW really needed ?
// It messes up the fullscreen window.
}
if
(
p_event
->
hparent
)
{
i_style
=
WS_VISIBLE
|
WS_CLIPCHILDREN
|
WS_CHILD
;
i_stylex
=
0
;
}
p_event
->
i_window_style
=
i_style
;
/* Create the window */
p_event
->
hwnd
=
CreateWindowEx
(
WS_EX_NOPARENTNOTIFY
|
i_stylex
,
_T
(
"VLC DirectX"
),
/* name of window class */
_T
(
VOUT_TITLE
)
_T
(
" (DirectX Output)"
),
/* window title */
i_style
,
/* window style */
(
p_event
->
wnd_cfg
.
x
<
0
)
?
CW_USEDEFAULT
:
(
UINT
)
p_event
->
wnd_cfg
.
x
,
/* default X coordinate */
(
p_event
->
wnd_cfg
.
y
<
0
)
?
CW_USEDEFAULT
:
(
UINT
)
p_event
->
wnd_cfg
.
y
,
/* default Y coordinate */
rect_window
.
right
-
rect_window
.
left
,
/* window width */
rect_window
.
bottom
-
rect_window
.
top
,
/* window height */
p_event
->
hparent
,
/* parent window */
NULL
,
/* no menu in this window */
hInstance
,
/* handle of this program instance */
(
LPVOID
)
p_event
);
/* send p_vout to WM_CREATE */
if
(
!
p_event
->
hwnd
)
{
msg_Warn
(
p_vout
,
"DirectXCreateWindow create window FAILED (err=%lu)"
,
GetLastError
()
);
return
VLC_EGENERIC
;
}
if
(
p_event
->
hparent
)
{
LONG
i_style
;
/* We don't want the window owner to overwrite our client area */
i_style
=
GetWindowLong
(
p_event
->
hparent
,
GWL_STYLE
);
if
(
!
(
i_style
&
WS_CLIPCHILDREN
)
)
/* Hmmm, apparently this is a blocking call... */
SetWindowLong
(
p_event
->
hparent
,
GWL_STYLE
,
i_style
|
WS_CLIPCHILDREN
);
/* Create our fullscreen window */
p_event
->
hfswnd
=
CreateWindowEx
(
WS_EX_APPWINDOW
,
_T
(
"VLC DirectX"
),
_T
(
VOUT_TITLE
)
_T
(
" (DirectX Output)"
),
WS_OVERLAPPEDWINDOW
|
WS_CLIPCHILDREN
|
WS_SIZEBOX
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
CW_USEDEFAULT
,
NULL
,
NULL
,
hInstance
,
NULL
);
}
else
{
p_event
->
hfswnd
=
NULL
;
}
/* Append a "Always On Top" entry in the system menu */
hMenu
=
GetSystemMenu
(
p_event
->
hwnd
,
FALSE
);
AppendMenu
(
hMenu
,
MF_SEPARATOR
,
0
,
_T
(
""
)
);
AppendMenu
(
hMenu
,
MF_STRING
|
MF_UNCHECKED
,
IDM_TOGGLE_ON_TOP
,
_T
(
"Always on &Top"
)
);
/* Create video sub-window. This sub window will always exactly match
* the size of the video, which allows us to use crazy overlay colorkeys
* without having them shown outside of the video area. */
p_event
->
hvideownd
=
CreateWindow
(
_T
(
"VLC DirectX video"
),
_T
(
""
),
/* window class */
WS_CHILD
,
/* window style, not visible initially */
0
,
0
,
p_vout
->
render
.
i_width
,
/* default width */
p_vout
->
render
.
i_height
,
/* default height */
p_event
->
hwnd
,
/* parent window */
NULL
,
hInstance
,
(
LPVOID
)
p_event
);
/* send p_vout to WM_CREATE */
if
(
!
p_event
->
hvideownd
)
msg_Warn
(
p_vout
,
"can't create video sub-window"
);
else
msg_Dbg
(
p_vout
,
"created video sub-window"
);
/* Now display the window */
ShowWindow
(
p_event
->
hwnd
,
SW_SHOW
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* DirectXCloseWindow: close the window created by DirectXCreateWindow
*****************************************************************************
* This function returns all resources allocated by DirectXCreateWindow.
*****************************************************************************/
static
void
DirectXCloseWindow
(
event_thread_t
*
p_event
)
{
vout_thread_t
*
p_vout
=
p_event
->
p_vout
;
msg_Dbg
(
p_vout
,
"DirectXCloseWindow"
);
DestroyWindow
(
p_event
->
hwnd
);
if
(
p_event
->
hfswnd
)
DestroyWindow
(
p_event
->
hfswnd
);
#ifdef MODULE_NAME_IS_direct3d
if
(
!
p_event
->
use_desktop
)
#endif
vout_window_Delete
(
p_event
->
parent_window
);
p_event
->
hwnd
=
NULL
;
/* We don't unregister the Window Class because it could lead to race
* conditions and it will be done anyway by the system when the app will
* exit */
}
/*****************************************************************************
* DirectXEventProc: This is the window event processing function.
*****************************************************************************
* On Windows, when you create a window you have to attach an event processing
* function to it. The aim of this function is to manage "Queued Messages" and
* "Nonqueued Messages".
* Queued Messages are those picked up and retransmitted by vout_Manage
* (using the GetMessage and DispatchMessage functions).
* Nonqueued Messages are those that Windows will send directly to this
* procedure (like WM_DESTROY, WM_WINDOWPOSCHANGED...)
*****************************************************************************/
static
long
FAR
PASCAL
DirectXEventProc
(
HWND
hwnd
,
UINT
message
,
WPARAM
wParam
,
LPARAM
lParam
)
{
event_thread_t
*
p_event
;
if
(
message
==
WM_CREATE
)
{
/* Store p_vout for future use */
p_event
=
(
event_thread_t
*
)((
CREATESTRUCT
*
)
lParam
)
->
lpCreateParams
;
SetWindowLongPtr
(
hwnd
,
GWLP_USERDATA
,
(
LONG_PTR
)
p_event
);
return
TRUE
;
}
else
{
LONG_PTR
p_user_data
=
GetWindowLongPtr
(
hwnd
,
GWLP_USERDATA
);
p_event
=
(
event_thread_t
*
)
p_user_data
;
if
(
!
p_event
)
{
/* Hmmm mozilla does manage somehow to save the pointer to our
* windowproc and still calls it after the vout has been closed. */
return
DefWindowProc
(
hwnd
,
message
,
wParam
,
lParam
);
}
}
vout_thread_t
*
p_vout
=
p_event
->
p_vout
;
#ifndef UNDER_CE
/* Catch the screensaver and the monitor turn-off */
if
(
message
==
WM_SYSCOMMAND
&&
(
(
wParam
&
0xFFF0
)
==
SC_SCREENSAVE
||
(
wParam
&
0xFFF0
)
==
SC_MONITORPOWER
)
)
{
//if( p_vout ) msg_Dbg( p_vout, "WinProc WM_SYSCOMMAND screensaver" );
return
0
;
/* this stops them from happening */
}
#endif
if
(
hwnd
==
p_event
->
hvideownd
)
{
#ifdef MODULE_NAME_IS_directx
vlc_mutex_lock
(
&
p_event
->
lock
);
const
bool
use_overlay
=
p_event
->
use_overlay
;
vlc_mutex_unlock
(
&
p_event
->
lock
);
#endif
switch
(
message
)
{
#ifdef MODULE_NAME_IS_directx
case
WM_ERASEBKGND
:
/* For overlay, we need to erase background */
return
!
use_overlay
?
1
:
DefWindowProc
(
hwnd
,
message
,
wParam
,
lParam
);
case
WM_PAINT
:
/*
** For overlay, DefWindowProc() will erase dirty regions
** with colorkey.
** For non-overlay, vout will paint the whole window at
** regular interval, therefore dirty regions can be ignored
** to minimize repaint.
*/
if
(
!
use_overlay
)
{
ValidateRect
(
hwnd
,
NULL
);
}
// fall through to default
#else
/*
** For OpenGL and Direct3D, vout will update the whole
** window at regular interval, therefore dirty region
** can be ignored to minimize repaint.
*/
case
WM_ERASEBKGND
:
/* nothing to erase */
return
1
;
case
WM_PAINT
:
/* nothing to repaint */
ValidateRect
(
hwnd
,
NULL
);
// fall through
#endif
default:
return
DefWindowProc
(
hwnd
,
message
,
wParam
,
lParam
);
}
}
switch
(
message
)
{
case
WM_WINDOWPOSCHANGED
:
UpdateRects
(
p_vout
,
true
);
return
0
;
/* the user wants to close the window */
case
WM_CLOSE
:
{
playlist_t
*
p_playlist
=
pl_Hold
(
p_vout
);
if
(
p_playlist
)
{
playlist_Stop
(
p_playlist
);
pl_Release
(
p_vout
);
}
return
0
;
}
/* the window has been closed so shut down everything now */
case
WM_DESTROY
:
msg_Dbg
(
p_vout
,
"WinProc WM_DESTROY"
);
/* just destroy the window */
PostQuitMessage
(
0
);
return
0
;
case
WM_SYSCOMMAND
:
switch
(
wParam
)
{
case
IDM_TOGGLE_ON_TOP
:
/* toggle the "on top" status */
{
msg_Dbg
(
p_vout
,
"WinProc WM_SYSCOMMAND: IDM_TOGGLE_ON_TOP"
);
/* Change the current value */
var_ToggleBool
(
p_vout
,
"video-on-top"
);
return
0
;
}
}
break
;
case
WM_PAINT
:
case
WM_NCPAINT
:
case
WM_ERASEBKGND
:
return
DefWindowProc
(
hwnd
,
message
,
wParam
,
lParam
);
case
WM_KILLFOCUS
:
#ifdef MODULE_NAME_IS_wingapi
GXSuspend
();
#endif
#ifdef UNDER_CE
if
(
hwnd
==
p_event
->
hfswnd
)
{
HWND
htbar
=
FindWindow
(
_T
(
"HHTaskbar"
),
NULL
);
ShowWindow
(
htbar
,
SW_SHOW
);
}
if
(
!
p_event
->
hparent
||
hwnd
==
p_event
->
hfswnd
)
{
SHFullScreen
(
hwnd
,
SHFS_SHOWSIPBUTTON
);
}
#endif
return
0
;
case
WM_SETFOCUS
:
#ifdef MODULE_NAME_IS_wingapi
GXResume
();
#endif
#ifdef UNDER_CE
if
(
p_event
->
hparent
&&
hwnd
!=
p_event
->
hfswnd
&&
p_vout
->
b_fullscreen
)
{
vlc_mutex_lock
(
&
p_event
->
lock
);
p_event
->
i_changes
|=
VOUT_FULLSCREEN_CHANGE
;
vlc_mutex_unlock
(
&
p_event
->
lock
);
}
if
(
hwnd
==
p_event
->
hfswnd
)
{
HWND
htbar
=
FindWindow
(
_T
(
"HHTaskbar"
),
NULL
);
ShowWindow
(
htbar
,
SW_HIDE
);
}
if
(
!
p_event
->
hparent
||
hwnd
==
p_event
->
hfswnd
)
{
SHFullScreen
(
hwnd
,
SHFS_HIDESIPBUTTON
);
}
#endif
return
0
;
default:
//msg_Dbg( p_vout, "WinProc WM Default %i", message );
break
;
}
/* Let windows handle the message */
return
DefWindowProc
(
hwnd
,
message
,
wParam
,
lParam
);
}
static
struct
{
int
i_dxkey
;
int
i_vlckey
;
}
dxkeys_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
,
' '
},
{
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
},
{
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
},
{
0
,
0
}
};
static
int
DirectXConvertKey
(
int
i_key
)
{
int
i
;
for
(
i
=
0
;
dxkeys_to_vlckeys
[
i
].
i_dxkey
!=
0
;
i
++
)
{
if
(
dxkeys_to_vlckeys
[
i
].
i_dxkey
==
i_key
)
{
return
dxkeys_to_vlckeys
[
i
].
i_vlckey
;
}
}
return
0
;
}
void
EventThreadMouseAutoHide
(
event_thread_t
*
p_event
)
{
vout_thread_t
*
p_vout
=
p_event
->
p_vout
;
if
(
p_vout
->
b_fullscreen
&&
!
p_event
->
b_cursor_hidden
&&
(
mdate
()
-
p_event
->
i_lastmoved
)
>
p_event
->
i_mouse_hide_timeout
)
{
/* Hide the cursor only if it is inside our window */
POINT
point
;
GetCursorPos
(
&
point
);
HWND
hwnd
=
WindowFromPoint
(
point
);
if
(
hwnd
==
p_event
->
hwnd
||
hwnd
==
p_event
->
hvideownd
)
{
PostMessage
(
p_event
->
hwnd
,
WM_VLC_HIDE_MOUSE
,
0
,
0
);
}
else
{
p_event
->
i_lastmoved
=
mdate
();
}
}
}
void
EventThreadMouseShow
(
event_thread_t
*
p_event
)
{
PostMessage
(
p_event
->
hwnd
,
WM_VLC_SHOW_MOUSE
,
0
,
0
);
}
void
EventThreadUpdateTitle
(
event_thread_t
*
p_event
,
const
char
*
psz_fallback
)
{
char
*
psz_title
=
var_GetNonEmptyString
(
p_event
->
p_vout
,
"video-title"
);
if
(
!
psz_title
)
psz_title
=
strdup
(
psz_fallback
);
if
(
!
psz_title
)
return
;
vlc_mutex_lock
(
&
p_event
->
lock
);
free
(
p_event
->
psz_title
);
p_event
->
psz_title
=
psz_title
;
vlc_mutex_unlock
(
&
p_event
->
lock
);
PostMessage
(
p_event
->
hwnd
,
WM_VLC_CHANGE_TEXT
,
0
,
0
);
}
unsigned
EventThreadRetreiveChanges
(
event_thread_t
*
p_event
)
{
vlc_mutex_lock
(
&
p_event
->
lock
);
unsigned
i_changes
=
p_event
->
i_changes
;
p_event
->
i_changes
=
0
;
vlc_mutex_unlock
(
&
p_event
->
lock
);
return
i_changes
;
}
int
EventThreadGetWindowStyle
(
event_thread_t
*
p_event
)
{
/* No need to lock, it is serialized by EventThreadStart */
return
p_event
->
i_window_style
;
}
void
EventThreadUpdateWindowPosition
(
event_thread_t
*
p_event
,
bool
*
pb_changed
,
int
x
,
int
y
,
int
w
,
int
h
)
{
vlc_mutex_lock
(
&
p_event
->
lock
);
*
pb_changed
=
x
!=
p_event
->
wnd_cfg
.
x
||
y
!=
p_event
->
wnd_cfg
.
y
||
w
!=
p_event
->
wnd_cfg
.
width
||
h
!=
p_event
->
wnd_cfg
.
height
;
p_event
->
wnd_cfg
.
x
=
x
;
p_event
->
wnd_cfg
.
y
=
y
;
p_event
->
wnd_cfg
.
width
=
w
;
p_event
->
wnd_cfg
.
height
=
h
;
vlc_mutex_unlock
(
&
p_event
->
lock
);
}
void
EventThreadUseOverlay
(
event_thread_t
*
p_event
,
bool
b_used
)
{
vlc_mutex_lock
(
&
p_event
->
lock
);
p_event
->
use_overlay
=
b_used
;
vlc_mutex_unlock
(
&
p_event
->
lock
);
}
event_thread_t
*
EventThreadCreate
(
vout_thread_t
*
p_vout
,
const
vout_window_cfg_t
*
p_wnd_cfg
)
{
/* Create the Vout EventThread, this thread is created by us to isolate
* the Win32 PeekMessage function calls. We want to do this because
* Windows can stay blocked inside this call for a long time, and when
* this happens it thus blocks vlc's video_output thread.
* Vout EventThread will take care of the creation of the video
* window (because PeekMessage has to be called from the same thread which
* created the window). */
msg_Dbg
(
p_vout
,
"creating Vout EventThread"
);
event_thread_t
*
p_event
=
malloc
(
sizeof
(
*
p_event
)
);
if
(
!
p_event
)
return
NULL
;
p_event
->
p_vout
=
p_vout
;
vlc_mutex_init
(
&
p_event
->
lock
);
vlc_cond_init
(
&
p_event
->
wait
);
p_event
->
b_cursor_hidden
=
false
;
p_event
->
i_lastmoved
=
mdate
();
p_event
->
i_mouse_hide_timeout
=
var_GetInteger
(
p_vout
,
"mouse-hide-timeout"
)
*
1000
;
p_event
->
psz_title
=
NULL
;
p_event
->
wnd_cfg
=
*
p_wnd_cfg
;
return
p_event
;
}
void
EventThreadDestroy
(
event_thread_t
*
p_event
)
{
free
(
p_event
->
psz_title
);
vlc_cond_destroy
(
&
p_event
->
wait
);
vlc_mutex_destroy
(
&
p_event
->
lock
);
free
(
p_event
);
}
int
EventThreadStart
(
event_thread_t
*
p_event
,
event_hwnd_t
*
p_hwnd
,
const
event_cfg_t
*
p_cfg
)
{
p_event
->
use_desktop
=
p_cfg
->
use_desktop
;
p_event
->
use_overlay
=
p_cfg
->
use_overlay
;
p_event
->
i_changes
=
0
;
p_event
->
b_ready
=
false
;
p_event
->
b_done
=
false
;
p_event
->
b_error
=
false
;
if
(
vlc_clone
(
&
p_event
->
thread
,
EventThread
,
p_event
,
VLC_THREAD_PRIORITY_LOW
)
)
{
msg_Err
(
p_event
->
p_vout
,
"cannot create Vout EventThread"
);
return
VLC_EGENERIC
;
}
vlc_mutex_lock
(
&
p_event
->
lock
);
while
(
!
p_event
->
b_ready
)
vlc_cond_wait
(
&
p_event
->
wait
,
&
p_event
->
lock
);
const
bool
b_error
=
p_event
->
b_error
;
vlc_mutex_unlock
(
&
p_event
->
lock
);
if
(
b_error
)
{
vlc_join
(
p_event
->
thread
,
NULL
);
p_event
->
b_ready
=
false
;
return
VLC_EGENERIC
;
}
msg_Dbg
(
p_event
->
p_vout
,
"Vout EventThread running"
);
if
(
!
p_event
->
use_desktop
)
p_hwnd
->
parent_window
=
p_event
->
parent_window
;
else
p_hwnd
->
parent_window
=
NULL
;
p_hwnd
->
hparent
=
p_event
->
hparent
;
p_hwnd
->
hwnd
=
p_event
->
hwnd
;
p_hwnd
->
hvideownd
=
p_event
->
hvideownd
;
p_hwnd
->
hfswnd
=
p_event
->
hfswnd
;
return
VLC_SUCCESS
;
}
void
EventThreadStop
(
event_thread_t
*
p_event
)
{
if
(
!
p_event
->
b_ready
)
return
;
vlc_mutex_lock
(
&
p_event
->
lock
);
p_event
->
b_done
=
true
;
vlc_mutex_unlock
(
&
p_event
->
lock
);
/* we need to be sure Vout EventThread won't stay stuck in
* GetMessage, so we send a fake message */
if
(
p_event
->
hwnd
)
PostMessage
(
p_event
->
hwnd
,
WM_NULL
,
0
,
0
);
vlc_join
(
p_event
->
thread
,
NULL
);
p_event
->
b_ready
=
false
;
}
modules/video_output/msw/events_vo.h
deleted
100644 → 0
View file @
25d33b29
/*****************************************************************************
* event.h: Windows video output header file
*****************************************************************************
* Copyright (C) 2001-2009 the VideoLAN team
* $Id$
*
* Authors: Gildas Bazin <gbazin@videolan.org>
* Damien Fouilleul <damienf@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include <vlc_vout_window.h>
/**
* HWNDs manager.
*/
typedef
struct
event_thread_t
event_thread_t
;
typedef
struct
{
bool
use_desktop
;
/* direct3d */
bool
use_overlay
;
/* directx */
}
event_cfg_t
;
typedef
struct
{
vout_window_t
*
parent_window
;
HWND
hparent
;
HWND
hwnd
;
HWND
hvideownd
;
HWND
hfswnd
;
}
event_hwnd_t
;
event_thread_t
*
EventThreadCreate
(
vout_thread_t
*
,
const
vout_window_cfg_t
*
);
void
EventThreadDestroy
(
event_thread_t
*
);
int
EventThreadStart
(
event_thread_t
*
,
event_hwnd_t
*
,
const
event_cfg_t
*
);
void
EventThreadStop
(
event_thread_t
*
);
void
EventThreadMouseAutoHide
(
event_thread_t
*
);
void
EventThreadMouseShow
(
event_thread_t
*
);
void
EventThreadUpdateTitle
(
event_thread_t
*
,
const
char
*
psz_fallback
);
unsigned
EventThreadRetreiveChanges
(
event_thread_t
*
);
int
EventThreadGetWindowStyle
(
event_thread_t
*
);
void
EventThreadUpdateWindowPosition
(
event_thread_t
*
,
bool
*
pb_changed
,
int
x
,
int
y
,
int
w
,
int
h
);
void
EventThreadUseOverlay
(
event_thread_t
*
,
bool
b_used
);
modules/video_output/msw/vout.h
deleted
100644 → 0
View file @
25d33b29
/*****************************************************************************
* vout.h: Windows video output header file
*****************************************************************************
* Copyright (C) 2001-2009 the VideoLAN team
* $Id$
*
* Authors: Gildas Bazin <gbazin@videolan.org>
* Damien Fouilleul <damienf@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* event_thread_t: event thread
*****************************************************************************/
#include "events_vo.h"
#ifdef MODULE_NAME_IS_wingapi
typedef
struct
GXDisplayProperties
{
DWORD
cxWidth
;
DWORD
cyHeight
;
long
cbxPitch
;
long
cbyPitch
;
long
cBPP
;
DWORD
ffFormat
;
}
GXDisplayProperties
;
typedef
struct
GXScreenRect
{
DWORD
dwTop
;
DWORD
dwLeft
;
DWORD
dwWidth
;
DWORD
dwHeight
;
}
GXScreenRect
;
# define GX_FULLSCREEN 0x01
# define GX_NORMALKEYS 0x02
# define GX_LANDSCAPEKEYS 0x03
# ifndef kfLandscape
# define kfLandscape 0x8
# define kfPalette 0x10
# define kfDirect 0x20
# define kfDirect555 0x40
# define kfDirect565 0x80
# define kfDirect888 0x100
# define kfDirect444 0x200
# define kfDirectInverted 0x400
# endif
#endif
struct
vout_window_t
;
/*****************************************************************************
* vout_sys_t: video output method descriptor
*****************************************************************************
* This structure is part of the video output thread descriptor.
* It describes the module specific properties of an output thread.
*****************************************************************************/
struct
vout_sys_t
{
HWND
hwnd
;
/* Handle of the main window */
HWND
hvideownd
;
/* Handle of the video sub-window */
struct
vout_window_t
*
parent_window
;
/* Parent window VLC object */
HWND
hparent
;
/* Handle of the parent window */
HWND
hfswnd
;
/* Handle of the fullscreen window */
/* Multi-monitor support */
HMONITOR
hmonitor
;
/* handle of the current monitor */
GUID
*
p_display_driver
;
HMONITOR
(
WINAPI
*
MonitorFromWindow
)(
HWND
,
DWORD
);
BOOL
(
WINAPI
*
GetMonitorInfo
)(
HMONITOR
,
LPMONITORINFO
);
/* size of the display */
RECT
rect_display
;
int
i_display_depth
;
/* size of the overall window (including black bands) */
RECT
rect_parent
;
volatile
uint16_t
i_changes
;
/* changes made to the video display */
/* Misc */
bool
b_on_top_change
;
#ifndef UNDER_CE
/* screensaver system settings to be restored when vout is closed */
UINT
i_spi_lowpowertimeout
;
UINT
i_spi_powerofftimeout
;
UINT
i_spi_screensavetimeout
;
#endif
/* Coordinates of src and dest images (used when blitting to display) */
RECT
rect_src
;
RECT
rect_src_clipped
;
RECT
rect_dest
;
RECT
rect_dest_clipped
;
bool
b_hw_yuv
;
/* Should we use hardware YUV->RGB conversions */
#ifdef MODULE_NAME_IS_directx
/* Overlay alignment restrictions */
int
i_align_src_boundary
;
int
i_align_src_size
;
int
i_align_dest_boundary
;
int
i_align_dest_size
;
bool
b_wallpaper
;
/* show as desktop wallpaper ? */
bool
b_using_overlay
;
/* Are we using an overlay surface */
bool
b_use_sysmem
;
/* Should we use system memory for surfaces */
bool
b_3buf_overlay
;
/* Should we use triple buffered overlays */
/* DDraw capabilities */
int
b_caps_overlay_clipping
;
unsigned
int
i_rgb_colorkey
;
/* colorkey in RGB used by the overlay */
unsigned
int
i_colorkey
;
/* colorkey used by the overlay */
COLORREF
color_bkg
;
COLORREF
color_bkgtxt
;
LPDIRECTDRAW2
p_ddobject
;
/* DirectDraw object */
LPDIRECTDRAWSURFACE2
p_display
;
/* Display device */
LPDIRECTDRAWSURFACE2
p_current_surface
;
/* surface currently displayed */
LPDIRECTDRAWCLIPPER
p_clipper
;
/* clipper used for blitting */
HINSTANCE
hddraw_dll
;
/* handle of the opened ddraw dll */
vlc_mutex_t
lock
;
#endif
#ifdef MODULE_NAME_IS_glwin32
HDC
hGLDC
;
HGLRC
hGLRC
;
#endif
#ifdef MODULE_NAME_IS_direct3d
/* show video on desktop window ? */
bool
b_desktop
;
// core objects
HINSTANCE
hd3d9_dll
;
/* handle of the opened d3d9 dll */
LPDIRECT3D9
p_d3dobj
;
LPDIRECT3DDEVICE9
p_d3ddev
;
D3DPRESENT_PARAMETERS
d3dpp
;
// scene objects
LPDIRECT3DTEXTURE9
p_d3dtex
;
LPDIRECT3DVERTEXBUFFER9
p_d3dvtc
;
#endif
#ifdef MODULE_NAME_IS_wingdi
int
i_depth
;
/* Our offscreen bitmap and its framebuffer */
HDC
off_dc
;
HBITMAP
off_bitmap
;
uint8_t
*
p_pic_buffer
;
int
i_pic_pitch
;
int
i_pic_pixel_pitch
;
BITMAPINFO
bitmapinfo
;
RGBQUAD
red
;
RGBQUAD
green
;
RGBQUAD
blue
;
#endif
#ifdef MODULE_NAME_IS_wingapi
int
i_depth
;
int
render_width
;
int
render_height
;
/* Our offscreen bitmap and its framebuffer */
HDC
off_dc
;
HBITMAP
off_bitmap
;
uint8_t
*
p_pic_buffer
;
int
i_pic_pitch
;
int
i_pic_pixel_pitch
;
BITMAPINFO
bitmapinfo
;
RGBQUAD
red
;
RGBQUAD
green
;
RGBQUAD
blue
;
HINSTANCE
gapi_dll
;
/* handle of the opened gapi dll */
/* GAPI functions */
int
(
*
GXOpenDisplay
)(
HWND
hWnd
,
DWORD
dwFlags
);
int
(
*
GXCloseDisplay
)();
void
*
(
*
GXBeginDraw
)();
int
(
*
GXEndDraw
)();
GXDisplayProperties
(
*
GXGetDisplayProperties
)();
int
(
*
GXSuspend
)();
int
(
*
GXResume
)();
#endif
event_thread_t
*
p_event
;
};
#ifdef MODULE_NAME_IS_wingapi
# define GXOpenDisplay p_vout->p_sys->GXOpenDisplay
# define GXCloseDisplay p_vout->p_sys->GXCloseDisplay
# define GXBeginDraw p_vout->p_sys->GXBeginDraw
# define GXEndDraw p_vout->p_sys->GXEndDraw
# define GXGetDisplayProperties p_vout->p_sys->GXGetDisplayProperties
# define GXSuspend p_vout->p_sys->GXSuspend
# define GXResume p_vout->p_sys->GXResume
#endif
/*****************************************************************************
* Prototypes from directx.c
*****************************************************************************/
int
DirectDrawUpdateOverlay
(
vout_thread_t
*
p_vout
);
/*****************************************************************************
* Prototypes from common.c
*****************************************************************************/
int
CommonInit
(
vout_thread_t
*
);
void
CommonClean
(
vout_thread_t
*
);
void
CommonManage
(
vout_thread_t
*
);
int
Control
(
vout_thread_t
*
p_vout
,
int
i_query
,
va_list
args
);
void
UpdateRects
(
vout_thread_t
*
p_vout
,
bool
b_force
);
void
Win32ToggleFullscreen
(
vout_thread_t
*
p_vout
);
void
ExitFullscreen
(
vout_thread_t
*
p_vout
);
#ifndef UNDER_CE
void
DisableScreensaver
(
vout_thread_t
*
p_vout
);
void
RestoreScreensaver
(
vout_thread_t
*
p_vout
);
#endif
/*****************************************************************************
* Constants
*****************************************************************************/
#define IDM_TOGGLE_ON_TOP WM_USER + 1
#define DX_POSITION_CHANGE 0x1000
#define DX_WALLPAPER_CHANGE 0x2000
#define DX_DESKTOP_CHANGE 0x4000
/*****************************************************************************
* WinCE helpers
*****************************************************************************/
#ifdef UNDER_CE
#define AdjustWindowRect(a,b,c) AdjustWindowRectEx(a,b,c,0)
#ifndef GCL_HBRBACKGROUND
# define GCL_HBRBACKGROUND (-10)
#endif
//#define FindWindowEx(a,b,c,d) 0
#define GetWindowPlacement(a,b)
#define SetWindowPlacement(a,b)
/*typedef struct _WINDOWPLACEMENT {
UINT length;
UINT flags;
UINT showCmd;
POINT ptMinPosition;
POINT ptMaxPosition;
RECT rcNormalPosition;
} WINDOWPLACEMENT;*/
#ifndef WM_NCMOUSEMOVE
# define WM_NCMOUSEMOVE 160
#endif
#ifndef CS_OWNDC
# define CS_OWNDC 32
#endif
#ifndef SC_SCREENSAVE
# define SC_SCREENSAVE 0xF140
#endif
#ifndef SC_MONITORPOWER
# define SC_MONITORPOWER 0xF170
#endif
#ifndef WM_NCPAINT
# define WM_NCPAINT 133
#endif
#ifndef WS_OVERLAPPEDWINDOW
# define WS_OVERLAPPEDWINDOW 0xcf0000
#endif
#ifndef WS_EX_NOPARENTNOTIFY
# define WS_EX_NOPARENTNOTIFY 4
#endif
#ifndef WS_EX_APPWINDOW
#define WS_EX_APPWINDOW 0x40000
#endif
//#define SetWindowLongPtr SetWindowLong
//#define GetWindowLongPtr GetWindowLong
//#define GWLP_USERDATA GWL_USERDATA
#endif //UNDER_CE
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment