/*****************************************************************************
- * common.c:
+ * common.c: Windows video output common code
*****************************************************************************
- * Copyright (C) 2001-2009 the VideoLAN team
+ * Copyright (C) 2001-2009 VLC authors and VideoLAN
* $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
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser 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.
+ * You should have received a copy of the GNU Lesser 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).
+ * Preamble: This file contains the functions related to the init of the vout
+ * structure, the common display code, the screensaver, but not the
+ * events and the Window Creation (events.c)
*****************************************************************************/
+
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
-#include <assert.h>
#include <vlc_common.h>
#include <vlc_vout_display.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 "../opengl.h"
-#endif
-#ifdef MODULE_NAME_IS_direct2d
-#include <d2d1.h>
-#endif
+#include <assert.h>
#include "common.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 void CommonChangeThumbnailClip(vout_display_t *, bool show);
-static int CommonControlSetFullscreen(vout_display_t *, bool is_fullscreen);
+static int CommonControlSetFullscreen(vout_display_t *, bool is_fullscreen);
-#if !defined(UNDER_CE) && !defined(MODULE_NAME_IS_glwin32)
static void DisableScreensaver(vout_display_t *);
static void RestoreScreensaver(vout_display_t *);
-#endif
/* */
int CommonInit(vout_display_t *vd)
sys->is_first_display = true;
sys->is_on_top = false;
- var_Create(vd, "video-title", VLC_VAR_STRING | VLC_VAR_DOINHERIT);
var_Create(vd, "video-deco", VLC_VAR_BOOL | VLC_VAR_DOINHERIT);
+ var_Create(vd, "disable-screensaver", VLC_VAR_BOOL | VLC_VAR_DOINHERIT);
/* */
sys->event = EventThreadCreate(vd);
event_cfg_t cfg;
memset(&cfg, 0, sizeof(cfg));
-#ifdef MODULE_NAME_IS_direct3d
+#ifdef MODULE_NAME_IS_direct3d9
cfg.use_desktop = sys->use_desktop;
#endif
-#ifdef MODULE_NAME_IS_directx
+#ifdef MODULE_NAME_IS_directdraw
cfg.use_overlay = sys->use_overlay;
#endif
- cfg.win.type = VOUT_WINDOW_TYPE_HWND;
- cfg.win.x = var_InheritInteger(vd, "video-x");
- cfg.win.y = var_InheritInteger(vd, "video-y");
- cfg.win.width = vd->cfg->display.width;
- cfg.win.height = vd->cfg->display.height;
+ cfg.x = var_InheritInteger(vd, "video-x");
+ cfg.y = var_InheritInteger(vd, "video-y");
+ cfg.width = vd->cfg->display.width;
+ cfg.height = vd->cfg->display.height;
event_hwnd_t hwnd;
if (EventThreadStart(sys->event, &hwnd, &cfg))
vout_display_SendEventFullscreen(vd, false);
}
- /* Why not with glwin32 */
-#if !defined(UNDER_CE) && !defined(MODULE_NAME_IS_glwin32)
- var_Create(vd, "disable-screensaver", VLC_VAR_BOOL | VLC_VAR_DOINHERIT);
DisableScreensaver (vd);
-#endif
return VLC_SUCCESS;
}
EventThreadDestroy(sys->event);
}
-#if !defined(UNDER_CE) && !defined(MODULE_NAME_IS_glwin32)
RestoreScreensaver(vd);
-#endif
}
void CommonManage(vout_display_t *vd)
/* This code deals with both resize and move
*
- * For most drivers(direct3d, gdi, opengl), move is never
+ * For most drivers(direct3d9, gdi, opengl), move is never
* an issue. The surface automatically gets moved together
* with the associated window (hvideownd)
*
- * For directx, it is still important to call UpdateRects
- * on a move of the parent window, even if no resize occured
+ * For directdraw, it is still important to call UpdateRects
+ * on a move of the parent window, even if no resize occurred
*/
SetWindowPos(sys->hwnd, 0, 0, 0,
rect_parent.right - rect_parent.left,
/* fill in buffer info in first plane */
picture->p->p_pixels = data;
picture->p->i_pitch = pitch;
- picture->p->i_lines = picture->format.i_height;
+ picture->p->i_lines = picture->format.i_visible_height;
/* Fill chroma planes for planar YUV */
if (picture->format.i_chroma == VLC_CODEC_I420 ||
p->p_pixels = o->p_pixels + o->i_lines * o->i_pitch;
p->i_pitch = pitch / 2;
- p->i_lines = picture->format.i_height / 2;
+ p->i_lines = picture->format.i_visible_height / 2;
}
/* The dx/d3d buffer is always allocated as YV12 */
if (vlc_fourcc_AreUVPlanesSwapped(picture->format.i_chroma, VLC_CODEC_YV12)) {
/* */
static void CommonChangeThumbnailClip(vout_display_t *vd, bool show)
{
-#ifndef UNDER_CE
vout_display_sys_t *sys = vd->sys;
/* Windows 7 taskbar thumbnail code */
if (!GetVersionEx(&winVer) || winVer.dwMajorVersion <= 5)
return;
- CoInitialize(0);
+ CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
void *ptr;
if (S_OK == CoCreateInstance(&CLSID_TaskbarList,
taskbl->lpVtbl->Release(taskbl);
}
CoUninitialize();
-#endif
}
/*****************************************************************************
point.x, point.y,
rect.right, rect.bottom);
if (is_resized)
- vout_display_SendEventDisplaySize(vd, rect.right, rect.bottom, cfg->is_fullscreen);
- if (!is_forced && !has_moved && !is_resized )
+ vout_display_SendEventDisplaySize(vd, rect.right, rect.bottom);
+ if (!is_forced && !has_moved && !is_resized)
return;
/* Update the window position and size */
vout_display_PlacePicture(&place, source, &place_cfg, false);
EventThreadUpdateSourceAndPlace(sys->event, source, &place);
-#if defined(MODULE_NAME_IS_wingapi)
- if (place.width != vd->fmt.i_width || place.height != vd->fmt.i_height)
- vout_display_SendEventPicturesInvalid(vd);
-#endif
if (sys->hvideownd)
SetWindowPos(sys->hvideownd, 0,
SWP_NOCOPYBITS|SWP_NOZORDER|SWP_ASYNCWINDOWPOS);
/* Destination image position and dimensions */
-#if defined(MODULE_NAME_IS_direct3d) || defined(MODULE_NAME_IS_direct2d)
+#if defined(MODULE_NAME_IS_direct3d9) || defined(MODULE_NAME_IS_direct2d)
rect_dest.left = 0;
rect_dest.right = place.width;
rect_dest.top = 0;
rect_dest.top = point.y + place.y;
rect_dest.bottom = rect_dest.top + place.height;
-#ifdef MODULE_NAME_IS_directx
+#ifdef MODULE_NAME_IS_directdraw
/* Apply overlay hardware constraints */
if (sys->use_overlay)
AlignRect(&rect_dest, sys->i_align_dest_boundary, sys->i_align_dest_size);
#endif
-#if defined(MODULE_NAME_IS_directx)
+#if defined(MODULE_NAME_IS_directdraw)
/* UpdateOverlay directdraw function doesn't automatically clip to the
* display size so we need to do it otherwise it will fail */
/* src image dimensions */
rect_src.left = 0;
rect_src.top = 0;
- rect_src.right = source->i_width;
- rect_src.bottom = source->i_height;
+ rect_src.right = vd->fmt.i_visible_width;
+ rect_src.bottom = vd->fmt.i_visible_height;
/* Clip the source image */
rect_src_clipped.left = source->i_x_offset +
(rect_dest.bottom - rect_dest_clipped.bottom) *
source->i_visible_height / (rect_dest.bottom - rect_dest.top);
-#ifdef MODULE_NAME_IS_directx
+#ifdef MODULE_NAME_IS_directdraw
/* Apply overlay hardware constraints */
if (sys->use_overlay)
AlignRect(&rect_src_clipped, sys->i_align_src_boundary, sys->i_align_src_size);
-#elif defined(MODULE_NAME_IS_direct3d) || defined(MODULE_NAME_IS_direct2d)
+#elif defined(MODULE_NAME_IS_direct3d9) || defined(MODULE_NAME_IS_direct2d)
/* Needed at least with YUV content */
rect_src_clipped.left &= ~1;
rect_src_clipped.right &= ~1;
rect_src_clipped.right, rect_src_clipped.bottom);
#endif
-#ifdef MODULE_NAME_IS_directx
+#ifdef MODULE_NAME_IS_directdraw
/* The destination coordinates need to be relative to the current
* directdraw primary surface (display) */
rect_dest_clipped.left -= sys->rect_display.left;
{
vout_display_sys_t *sys = vd->sys;
-#ifdef MODULE_NAME_IS_direct3d
+#ifdef MODULE_NAME_IS_direct3d9
if (sys->use_desktop && is_fullscreen)
return VLC_EGENERIC;
#endif
/* */
if (sys->parent_window)
- return vout_window_SetFullScreen(sys->parent_window, is_fullscreen);
+ return VLC_EGENERIC;
/* */
HWND hwnd = sys->hparent && sys->hfswnd ? sys->hfswnd : sys->hwnd;
SetWindowLong(hwnd, GWL_STYLE, WS_CLIPCHILDREN | WS_VISIBLE);
if (sys->hparent) {
-#ifdef UNDER_CE
- POINT point = {0,0};
- RECT rect;
- ClientToScreen(sys->hwnd, &point);
- GetClientRect(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(sys->hparent,
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);
rect.right, rect.bottom,
SWP_NOZORDER|SWP_FRAMECHANGED);
-#ifdef UNDER_CE
- HWND topLevelParent = GetParent(sys->hparent);
-#else
HWND topLevelParent = GetAncestor(sys->hparent, GA_ROOT);
-#endif
ShowWindow(topLevelParent, SW_HIDE);
}
SetForegroundWindow(hwnd);
rect.right, rect.bottom,
SWP_NOZORDER|SWP_FRAMECHANGED);
-#ifdef UNDER_CE
- HWND topLevelParent = GetParent(sys->hparent);
-#else
HWND topLevelParent = GetAncestor(sys->hparent, GA_ROOT);
-#endif
ShowWindow(topLevelParent, SW_SHOW);
SetForegroundWindow(sys->hparent);
ShowWindow(hwnd, SW_HIDE);
vout_display_sys_t *sys = vd->sys;
switch (query) {
- case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE: /* const vout_display_cfg_t *p_cfg, int is_forced */
+ case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE: /* const vout_display_cfg_t *p_cfg */
+ { /* Update dimensions */
+ const vout_display_cfg_t *cfg = va_arg(args, const vout_display_cfg_t *);
+ RECT rect_window = {
+ .top = 0,
+ .left = 0,
+ .right = cfg->display.width,
+ .bottom = cfg->display.height,
+ };
+
+ AdjustWindowRect(&rect_window, EventThreadGetWindowStyle(sys->event), 0);
+ SetWindowPos(sys->hwnd, 0, 0, 0,
+ rect_window.right - rect_window.left,
+ rect_window.bottom - rect_window.top, SWP_NOMOVE);
+ UpdateRects(vd, cfg, &vd->source, false);
+ return VLC_SUCCESS;
+ }
case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED: /* const vout_display_cfg_t *p_cfg */
case VOUT_DISPLAY_CHANGE_ZOOM: /* const vout_display_cfg_t *p_cfg */
case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT: /* const video_format_t *p_source */
case VOUT_DISPLAY_CHANGE_SOURCE_CROP: { /* const video_format_t *p_source */
const vout_display_cfg_t *cfg;
const video_format_t *source;
- bool is_forced = true;
+
if (query == VOUT_DISPLAY_CHANGE_SOURCE_CROP ||
query == VOUT_DISPLAY_CHANGE_SOURCE_ASPECT) {
cfg = vd->cfg;
} else {
cfg = va_arg(args, const vout_display_cfg_t *);
source = &vd->source;
- if (query == VOUT_DISPLAY_CHANGE_DISPLAY_SIZE)
- is_forced = va_arg(args, int);
- }
- if (query == VOUT_DISPLAY_CHANGE_DISPLAY_SIZE && is_forced) {
- /* Update dimensions */
- if (sys->parent_window) {
- vout_window_SetSize(sys->parent_window, cfg->display.width, cfg->display.height);
- } else {
- RECT rect_window;
- rect_window.top = 0;
- rect_window.left = 0;
- rect_window.right = cfg->display.width;
- rect_window.bottom = cfg->display.height;
- AdjustWindowRect(&rect_window, EventThreadGetWindowStyle(sys->event), 0);
-
- SetWindowPos(sys->hwnd, 0, 0, 0,
- rect_window.right - rect_window.left,
- rect_window.bottom - rect_window.top, SWP_NOMOVE);
- }
}
- UpdateRects(vd, cfg, source, is_forced);
+ UpdateRects(vd, cfg, source, false);
return VLC_SUCCESS;
}
case VOUT_DISPLAY_CHANGE_WINDOW_STATE: { /* unsigned state */
const unsigned state = va_arg(args, unsigned);
const bool is_on_top = (state & VOUT_WINDOW_STATE_ABOVE) != 0;
-#ifdef MODULE_NAME_IS_direct3d
+#ifdef MODULE_NAME_IS_direct3d9
if (sys->use_desktop && is_on_top)
return VLC_EGENERIC;
#endif
- if (sys->parent_window) {
- if (vout_window_SetState(sys->parent_window, state))
- return VLC_EGENERIC;
- } else {
- HMENU hMenu = GetSystemMenu(sys->hwnd, FALSE);
-
- if (is_on_top && !(GetWindowLong(sys->hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST)) {
- CheckMenuItem(hMenu, IDM_TOGGLE_ON_TOP, MF_BYCOMMAND | MFS_CHECKED);
- SetWindowPos(sys->hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
- } else if (!is_on_top && (GetWindowLong(sys->hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST)) {
- CheckMenuItem(hMenu, IDM_TOGGLE_ON_TOP, MF_BYCOMMAND | MFS_UNCHECKED);
- SetWindowPos(sys->hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
- }
+ HMENU hMenu = GetSystemMenu(sys->hwnd, FALSE);
+
+ if (is_on_top && !(GetWindowLong(sys->hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST)) {
+ CheckMenuItem(hMenu, IDM_TOGGLE_ON_TOP, MF_BYCOMMAND | MFS_CHECKED);
+ SetWindowPos(sys->hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
+ } else if (!is_on_top && (GetWindowLong(sys->hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST)) {
+ CheckMenuItem(hMenu, IDM_TOGGLE_ON_TOP, MF_BYCOMMAND | MFS_UNCHECKED);
+ SetWindowPos(sys->hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
}
sys->is_on_top = is_on_top;
return VLC_SUCCESS;
}
- case VOUT_DISPLAY_CHANGE_FULLSCREEN: { /* const vout_display_cfg_t *p_cfg */
- const vout_display_cfg_t *cfg = va_arg(args, const vout_display_cfg_t *);
- if (CommonControlSetFullscreen(vd, cfg->is_fullscreen))
+ case VOUT_DISPLAY_CHANGE_FULLSCREEN: {
+ bool fs = va_arg(args, int);
+ if (CommonControlSetFullscreen(vd, fs))
return VLC_EGENERIC;
UpdateRects(vd, NULL, NULL, false);
return VLC_SUCCESS;
EventThreadMouseHide(sys->event);
return VLC_SUCCESS;
case VOUT_DISPLAY_RESET_PICTURES:
- assert(0);
+ vlc_assert_unreachable();
default:
return VLC_EGENERIC;
}
}
-#if !defined(UNDER_CE) && !defined(MODULE_NAME_IS_glwin32)
static void DisableScreensaver(vout_display_t *vd)
{
vout_display_sys_t *sys = vd->sys;
/* disable screensaver by temporarily changing system settings */
- sys->i_spi_lowpowertimeout = 0;
- sys->i_spi_powerofftimeout = 0;
- sys->i_spi_screensavetimeout = 0;
+ sys->i_spi_screensaveactive = 0;
if (var_GetBool(vd, "disable-screensaver")) {
msg_Dbg(vd, "disabling screen saver");
- SystemParametersInfo(SPI_GETLOWPOWERTIMEOUT, 0,
- &sys->i_spi_lowpowertimeout, 0);
- if (0 != sys->i_spi_lowpowertimeout) {
- SystemParametersInfo(SPI_SETLOWPOWERTIMEOUT, 0, NULL, 0);
- }
- SystemParametersInfo(SPI_GETPOWEROFFTIMEOUT, 0,
- &sys->i_spi_powerofftimeout, 0);
- if (0 != sys->i_spi_powerofftimeout) {
- SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT, 0, NULL, 0);
+ SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0,
+ &sys->i_spi_screensaveactive, 0);
+
+ if (LOWORD(GetVersion()) == 0x0005) {
+ /* If this is NT 5.0 (i.e., Win2K), we need to hack around
+ * KB318781 (see http://support.microsoft.com/kb/318781) */
+
+ HKEY hKeyCP = NULL;
+
+ if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,
+ TEXT("Control Panel\\Desktop"),
+ 0, KEY_QUERY_VALUE, &hKeyCP) &&
+ ERROR_SUCCESS != RegQueryValueEx(hKeyCP, TEXT("SCRNSAVE.EXE"),
+ NULL, NULL, NULL, NULL)) {
+ sys->i_spi_screensaveactive = FALSE;
+ }
}
- SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0,
- &sys->i_spi_screensavetimeout, 0);
- if (0 != sys->i_spi_screensavetimeout) {
- SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, 0, NULL, 0);
+
+ if (FALSE != sys->i_spi_screensaveactive) {
+ SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, NULL, 0);
}
}
}
vout_display_sys_t *sys = vd->sys;
/* restore screensaver system settings */
- if (0 != sys->i_spi_lowpowertimeout) {
- SystemParametersInfo(SPI_SETLOWPOWERTIMEOUT,
- sys->i_spi_lowpowertimeout, NULL, 0);
- }
- if (0 != sys->i_spi_powerofftimeout) {
- SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT,
- sys->i_spi_powerofftimeout, NULL, 0);
- }
- if (0 != sys->i_spi_screensavetimeout) {
- SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT,
- sys->i_spi_screensavetimeout, NULL, 0);
+ if (0 != sys->i_spi_screensaveactive) {
+ SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,
+ sys->i_spi_screensaveactive, NULL, 0);
}
}
-#endif
-