X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fvideo_output%2Fmsw%2Fcommon.c;h=414b93dd4c792f2d1b13c5faeb022a9badf0e6a8;hb=6154d28dabf97571b5d1057e107761eb8c951aba;hp=cc392ceb29e0311e1007cdec27e82e6e4917ae6c;hpb=36558eb52ea617c0c6293dc0974bc41df3fca1ba;p=vlc diff --git a/modules/video_output/msw/common.c b/modules/video_output/msw/common.c index cc392ceb29..414b93dd4c 100644 --- a/modules/video_output/msw/common.c +++ b/modules/video_output/msw/common.c @@ -48,6 +48,9 @@ #ifdef MODULE_NAME_IS_glwin32 #include "../opengl.h" #endif +#ifdef MODULE_NAME_IS_direct2d +#include +#endif #include "common.h" @@ -60,10 +63,13 @@ //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); +#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) @@ -83,9 +89,6 @@ int CommonInit(vout_display_t *vd) var_Create(vd, "video-title", VLC_VAR_STRING | VLC_VAR_DOINHERIT); var_Create(vd, "video-deco", VLC_VAR_BOOL | VLC_VAR_DOINHERIT); - /* FIXME remove mouse hide from msw */ - var_Create(vd, "mouse-hide-timeout", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); - /* */ sys->event = EventThreadCreate(vd); if (!sys->event) @@ -97,11 +100,11 @@ int CommonInit(vout_display_t *vd) cfg.use_desktop = sys->use_desktop; #endif #ifdef MODULE_NAME_IS_directx - cfg.use_overlay = sys->b_using_overlay; + cfg.use_overlay = sys->use_overlay; #endif cfg.win.type = VOUT_WINDOW_TYPE_HWND; - cfg.win.x = 0; - cfg.win.y = 0; + 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; @@ -135,6 +138,7 @@ void CommonClean(vout_display_t *vd) vout_display_sys_t *sys = vd->sys; if (sys->event) { + CommonChangeThumbnailClip(vd, false); EventThreadStop(sys->event); EventThreadDestroy(sys->event); } @@ -155,10 +159,11 @@ void CommonManage(vout_display_t *vd) /* If we do not control our window, we check for geometry changes * ourselves because the parent might not send us its events. */ - if (sys->hparent && !vd->cfg->is_fullscreen) { + if (sys->hparent) { RECT rect_parent; POINT point; + /* Check if the parent window has resized or moved */ GetClientRect(sys->hparent, &rect_parent); point.x = point.y = 0; ClientToScreen(sys->hparent, &point); @@ -167,44 +172,27 @@ void CommonManage(vout_display_t *vd) if (!EqualRect(&rect_parent, &sys->rect_parent)) { sys->rect_parent = rect_parent; - /* FIXME I find such #ifdef quite weirds. Are they really needed ? */ - -#if defined(MODULE_NAME_IS_direct3d) + /* This code deals with both resize and move + * + * For most drivers(direct3d, 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 + */ SetWindowPos(sys->hwnd, 0, 0, 0, rect_parent.right - rect_parent.left, rect_parent.bottom - rect_parent.top, SWP_NOZORDER); - UpdateRects(vd, NULL, NULL, true); -#else - /* This one is to force the update even if only - * the position has changed */ - SetWindowPos(sys->hwnd, 0, 1, 1, - rect_parent.right - rect_parent.left, - rect_parent.bottom - rect_parent.top, 0); - - SetWindowPos(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(vd, rect_parent.right - rect_parent.left, - rect_parent.bottom - rect_parent.top, - &i_x, &i_y, &i_width, &i_height); - - SetWindowPos(sys->hvideownd, HWND_TOP, - i_x, i_y, i_width, i_height, 0); -#endif -#endif + UpdateRects(vd, NULL, NULL, true); } } - /* */ + /* HasMoved means here resize or move */ if (EventThreadGetAndResetHasMoved(sys->event)) UpdateRects(vd, NULL, NULL, false); - - /* Pointer change */ - EventThreadMouseAutoHide(sys->event); } /** @@ -231,6 +219,106 @@ void CommonDisplay(vout_display_t *vd) sys->is_first_display = false; } +/** + * It updates a picture data/pitches. + */ +int CommonUpdatePicture(picture_t *picture, picture_t **fallback, + uint8_t *data, unsigned pitch) +{ + if (fallback) { + if (*fallback == NULL) { + *fallback = picture_NewFromFormat(&picture->format); + if (*fallback == NULL) + return VLC_EGENERIC; + } + for (int n = 0; n < picture->i_planes; n++) { + const plane_t *src = &(*fallback)->p[n]; + plane_t *dst = &picture->p[n]; + dst->p_pixels = src->p_pixels; + dst->i_pitch = src->i_pitch; + dst->i_lines = src->i_lines; + } + return VLC_SUCCESS; + } + /* 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; + + /* Fill chroma planes for planar YUV */ + if (picture->format.i_chroma == VLC_CODEC_I420 || + picture->format.i_chroma == VLC_CODEC_J420 || + picture->format.i_chroma == VLC_CODEC_YV12) { + + for (int n = 1; n < picture->i_planes; n++) { + const plane_t *o = &picture->p[n-1]; + plane_t *p = &picture->p[n]; + + 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; + } + /* The dx/d3d buffer is always allocated as YV12 */ + if (vlc_fourcc_AreUVPlanesSwapped(picture->format.i_chroma, VLC_CODEC_YV12)) { + uint8_t *p_tmp = picture->p[1].p_pixels; + picture->p[1].p_pixels = picture->p[2].p_pixels; + picture->p[2].p_pixels = p_tmp; + } + } + return VLC_SUCCESS; +} + +void AlignRect(RECT *r, int align_boundary, int align_size) +{ + if (align_boundary) + r->left = (r->left + align_boundary/2) & ~align_boundary; + if (align_size) + r->right = ((r->right - r->left + align_size/2) & ~align_size) + r->left; +} + +/* */ +static void CommonChangeThumbnailClip(vout_display_t *vd, bool show) +{ +#ifndef UNDER_CE + vout_display_sys_t *sys = vd->sys; + + /* Windows 7 taskbar thumbnail code */ + OSVERSIONINFO winVer; + winVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (!GetVersionEx(&winVer) || winVer.dwMajorVersion <= 5) + return; + + CoInitialize(0); + + LPTASKBARLIST3 taskbl; + if (S_OK == CoCreateInstance(&clsid_ITaskbarList, + NULL, CLSCTX_INPROC_SERVER, + &IID_ITaskbarList3, + &taskbl)) { + taskbl->vt->HrInit(taskbl); + + HWND hroot = GetAncestor(sys->hwnd,GA_ROOT); + RECT relative; + if (show) { + RECT video, parent; + GetWindowRect(sys->hvideownd, &video); + GetWindowRect(hroot, &parent); + relative.left = video.left - parent.left - 8; + relative.top = video.top - parent.top - 10; + + relative.right = video.right - video.left + relative.left; + relative.bottom = video.bottom - video.top + relative.top - 25; + } + if (S_OK != taskbl->vt->SetThumbnailClip(taskbl, hroot, + show ? &relative : NULL)) + msg_Err(vd, "SetThumbNailClip failed"); + + taskbl->vt->Release(taskbl); + } + CoUninitialize(); +#endif +} + /***************************************************************************** * UpdateRects: update clipping rectangles ***************************************************************************** @@ -252,6 +340,12 @@ void UpdateRects(vout_display_t *vd, RECT rect; POINT point; + /* */ + if (!cfg) + cfg = vd->cfg; + if (!source) + source = &vd->source; + /* Retrieve the window size */ GetClientRect(sys->hwnd, &rect); @@ -260,28 +354,29 @@ void UpdateRects(vout_display_t *vd, ClientToScreen(sys->hwnd, &point); /* If nothing changed, we can return */ - bool has_changed; - EventThreadUpdateWindowPosition(sys->event, &has_changed, + bool has_moved; + bool is_resized; + EventThreadUpdateWindowPosition(sys->event, &has_moved, &is_resized, point.x, point.y, rect.right, rect.bottom); - if (!is_forced && !has_changed) + if (is_resized) + vout_display_SendEventDisplaySize(vd, rect.right, rect.bottom, cfg->is_fullscreen); + if (!is_forced && !has_moved && !is_resized ) return; - /* */ - if (!cfg) - cfg = vd->cfg; - if (!source) - source = &vd->source; - /* Update the window position and size */ vout_display_cfg_t place_cfg = *cfg; place_cfg.display.width = rect.right; place_cfg.display.height = rect.bottom; vout_display_place_t place; - vout_display_PlacePicture(&place, source, &place_cfg, true); + 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, @@ -289,7 +384,7 @@ void UpdateRects(vout_display_t *vd, SWP_NOCOPYBITS|SWP_NOZORDER|SWP_ASYNCWINDOWPOS); /* Destination image position and dimensions */ -#if defined(MODULE_NAME_IS_direct3d) +#if defined(MODULE_NAME_IS_direct3d) || defined(MODULE_NAME_IS_direct2d) rect_dest.left = 0; rect_dest.right = place.width; rect_dest.top = 0; @@ -302,23 +397,13 @@ void UpdateRects(vout_display_t *vd, #ifdef MODULE_NAME_IS_directx /* Apply overlay hardware constraints */ - if (sys->b_using_overlay) { - if (sys->i_align_dest_boundary) - rect_dest.left = (rect_dest.left + - sys->i_align_dest_boundary / 2) & - ~sys->i_align_dest_boundary; - - if (sys->i_align_dest_size) - rect_dest.right = ((rect_dest.right - - rect_dest.left + - sys->i_align_dest_size / 2) & - ~sys->i_align_dest_size) + rect_dest.left; - } + if (sys->use_overlay) + AlignRect(&rect_dest, sys->i_align_dest_boundary, sys->i_align_dest_size); #endif #endif -#if defined(MODULE_NAME_IS_directx) || defined(MODULE_NAME_IS_direct3d) +#if defined(MODULE_NAME_IS_directx) || defined(MODULE_NAME_IS_direct3d) || defined(MODULE_NAME_IS_direct2d) /* 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 */ @@ -327,7 +412,7 @@ void UpdateRects(vout_display_t *vd, if (!IntersectRect(&rect_dest_clipped, &rect_dest, &sys->rect_display)) { SetRectEmpty(&rect_src_clipped); - return; + goto exit; } #ifndef NDEBUG @@ -348,7 +433,7 @@ void UpdateRects(vout_display_t *vd, if ((rect_dest_clipped.right - rect_dest_clipped.left) == 0 || (rect_dest_clipped.bottom - rect_dest_clipped.top) == 0) { SetRectEmpty(&rect_src_clipped); - return; + goto exit; } /* src image dimensions */ @@ -375,20 +460,9 @@ void UpdateRects(vout_display_t *vd, #ifdef MODULE_NAME_IS_directx /* Apply overlay hardware constraints */ - if (sys->b_using_overlay) { - if (sys->i_align_src_boundary) - rect_src_clipped.left = - (rect_src_clipped.left + - sys->i_align_src_boundary / 2) & - ~sys->i_align_src_boundary; - - if (sys->i_align_src_size) - rect_src_clipped.right = - ((rect_src_clipped.right - rect_src_clipped.left + - sys->i_align_src_size / 2) & - ~sys->i_align_src_size) + rect_src_clipped.left; - } -#elif defined(MODULE_NAME_IS_direct3d) + 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) /* Needed at least with YUV content */ rect_src_clipped.left &= ~1; rect_src_clipped.right &= ~1; @@ -410,42 +484,11 @@ void UpdateRects(vout_display_t *vd, rect_dest_clipped.right -= sys->rect_display.left; rect_dest_clipped.top -= sys->rect_display.top; rect_dest_clipped.bottom -= sys->rect_display.top; - - if (sys->b_using_overlay) - DirectDrawUpdateOverlay(vd); #endif -#ifndef UNDER_CE - /* Windows 7 taskbar thumbnail code */ - LPTASKBARLIST3 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, - &taskbl)) { - RECT rect_video, rect_parent, rect_relative; - HWND hroot = GetAncestor(sys->hwnd,GA_ROOT); - - taskbl->vt->HrInit(taskbl); - GetWindowRect(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 != taskbl->vt->SetThumbnailClip(taskbl, hroot, &rect_relative)) - msg_Err(vd, "SetThumbNailClip failed"); - - taskbl->vt->Release(taskbl); - } - CoUninitialize(); - } -#endif + CommonChangeThumbnailClip(vd, true); + +exit: /* Signal the change in size/position */ sys->changes |= DX_POSITION_CHANGE; @@ -556,9 +599,6 @@ static int CommonControlSetFullscreen(vout_display_t *vd, bool is_fullscreen) SetWindowPlacement(hwnd, &window_placement); ShowWindow(hwnd, SW_SHOWNORMAL); } - - /* Make sure the mouse cursor is displayed */ - EventThreadMouseShow(sys->event); } return VLC_SUCCESS; } @@ -632,18 +672,23 @@ int CommonControl(vout_display_t *vd, int query, va_list args) } 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 *); - return CommonControlSetFullscreen(vd, cfg->is_fullscreen); + if (CommonControlSetFullscreen(vd, cfg->is_fullscreen)) + return VLC_EGENERIC; + UpdateRects(vd, NULL, NULL, false); + return VLC_SUCCESS; } - case VOUT_DISPLAY_RESET_PICTURES: case VOUT_DISPLAY_HIDE_MOUSE: + EventThreadMouseHide(sys->event); + return VLC_SUCCESS; + case VOUT_DISPLAY_RESET_PICTURES: assert(0); default: return VLC_EGENERIC; } } -#ifndef UNDER_CE +#if !defined(UNDER_CE) && !defined(MODULE_NAME_IS_glwin32) static void DisableScreensaver(vout_display_t *vd) { vout_display_sys_t *sys = vd->sys;