0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 20:03:10 +02:00

vo_directx: Change vo_directx to use w32_common.c

While I tested it quite thoroughly, with and without
-wid, -vm, -fs, ... it is _very_ likely to break
something, please report any regressions!
In the worst case it can still be reverted, however
since it has very little relevance nowadays it will
rot all the faster if not at least some code is shared.

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@33657 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
reimar 2011-06-19 12:51:36 +00:00 committed by Uoti Urpala
parent 1b6ae1ff58
commit 070491f102

View File

@ -37,6 +37,7 @@
#include "geometry.h"
#include "mp_fifo.h"
#include "sub/sub.h"
#include "w32_common.h"
#ifndef WM_XBUTTONDOWN
# define WM_XBUTTONDOWN 0x020B
@ -58,8 +59,6 @@ static DDSURFACEDESC2 ddsdsf; //surface descripiton needed for
static HINSTANCE hddraw_dll; //handle to ddraw.dll
static RECT rd; //rect of our stretched image
static RECT rs; //rect of our source image
static HWND hWnd=NULL; //handle to the window
static HWND hWndFS=NULL; //fullscreen window
static HBRUSH colorbrush = NULL; // Handle to colorkey brush
static HBRUSH blackbrush = NULL; // Handle to black brush
static HICON mplayericon = NULL; // Handle to mplayer icon
@ -348,19 +347,12 @@ static void uninit(void)
if (g_lpddsPrimary != NULL) g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);
g_lpddsPrimary = NULL;
mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>primary released\n");
if(hWndFS)DestroyWindow(hWndFS);
hWndFS = NULL;
if((WinID == -1) && hWnd) DestroyWindow(hWnd);
hWnd = NULL;
mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>window destroyed\n");
UnregisterClass(WNDCLASSNAME_WINDOWED, GetModuleHandle(NULL));
UnregisterClass(WNDCLASSNAME_FULLSCREEN, GetModuleHandle(NULL));
if (mplayericon) DestroyIcon(mplayericon);
mplayericon = NULL;
if (mplayercursor) DestroyCursor(mplayercursor);
mplayercursor = NULL;
if (blackbrush) DeleteObject(blackbrush);
blackbrush = NULL;
if (colorbrush) DeleteObject(colorbrush);
colorbrush = NULL;
mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>GDI resources deleted\n");
@ -373,6 +365,7 @@ static void uninit(void)
hddraw_dll= NULL;
mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>ddraw.dll freed\n");
mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>uninitialized\n");
vo_w32_uninit();
}
static BOOL WINAPI EnumCallbackEx(GUID FAR *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, LPVOID lpContext, HMONITOR hm)
@ -495,7 +488,7 @@ static uint32_t Directx_InitDirectDraw(void)
else vm_bpp=ddsd.ddpfPixelFormat.dwRGBBitCount;
if(vidmode){
if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN) != DD_OK)
if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, vo_w32_window, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN) != DD_OK)
{
mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set cooperativelevel for exclusive mode\n");
return 1;
@ -509,7 +502,7 @@ static uint32_t Directx_InitDirectDraw(void)
mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>Initialized adapter %i for %i x %i @ %i \n",vo_adapter_num,vm_width,vm_height,vm_bpp);
return 0;
}
if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_NORMAL) != DD_OK) // or DDSCL_SETFOCUSWINDOW
if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, vo_w32_window, DDSCL_NORMAL) != DD_OK) // or DDSCL_SETFOCUSWINDOW
{
mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>could not set cooperativelevel for hardwarecheck\n");
return 1;
@ -518,13 +511,19 @@ static uint32_t Directx_InitDirectDraw(void)
return 0;
}
static uint32_t Directx_ManageDisplay(void);
static void check_events(void)
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
int evt = vo_w32_check_events();
if (evt & (VO_EVENT_RESIZE | VO_EVENT_MOVE))
Directx_ManageDisplay();
if (evt & (VO_EVENT_RESIZE | VO_EVENT_MOVE | VO_EVENT_EXPOSE)) {
HDC dc = vo_w32_get_dc(vo_w32_window);
RECT r;
GetClientRect(vo_w32_window, &r);
FillRect(dc, &r, vo_fs || vidmode ? blackbrush : colorbrush);
vo_w32_release_dc(vo_w32_window, dc);
}
}
@ -536,66 +535,20 @@ static uint32_t Directx_ManageDisplay(void)
DWORD dwUpdateFlags=0;
int width,height;
if(!vidmode && !vo_fs && WinID!=-1) {
RECT current_rect = {0, 0, 0, 0};
GetWindowRect(hWnd, &current_rect);
if ((current_rect.left == last_rect.left)
&& (current_rect.top == last_rect.top)
&& (current_rect.right == last_rect.right)
&& (current_rect.bottom == last_rect.bottom))
return 0;
last_rect = current_rect;
}
rd.left = vo_dx - xinerama_x;
rd.top = vo_dy - xinerama_y;
width = vo_dwidth;
height = vo_dheight;
aspect(&width, &height, A_WINZOOM);
panscan_calc_windowed();
width += vo_panscan_x;
height += vo_panscan_y;
width = FFMIN(width, vo_screenwidth);
height = FFMIN(height, vo_screenheight);
rd.left += (vo_dwidth - width ) / 2;
rd.top += (vo_dheight - height) / 2;
if(vo_fs || vidmode){
aspect(&width,&height,A_ZOOM);
rd.left=(vo_screenwidth-width)/2;
rd.top=(vo_screenheight-height)/2;
if (WinID == -1)
if(ShowCursor(FALSE)>=0)while(ShowCursor(FALSE)>=0){}
}
else if (WinID != -1 && vo_geometry) {
POINT pt;
pt.x = vo_dx;
pt.y = vo_dy;
ClientToScreen(hWnd,&pt);
width=d_image_width;
height=d_image_height;
rd.left = pt.x;
rd.top = pt.y;
while(ShowCursor(TRUE)<=0){}
}
else {
POINT pt;
pt.x = 0; //overlayposition relative to the window
pt.y = 0;
ClientToScreen(hWnd,&pt);
GetClientRect(hWnd, &rd);
width=rd.right - rd.left;
height=rd.bottom - rd.top;
pt.x -= monitor_rect.left; /* move coordinates from global to local monitor space */
pt.y -= monitor_rect.top;
rd.right -= monitor_rect.left;
rd.bottom -= monitor_rect.top;
rd.left = pt.x;
rd.top = pt.y;
if(!nooverlay && (!width || !height)){
/*window is minimized*/
ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,NULL, g_lpddsPrimary, NULL, DDOVER_HIDE, NULL);
return 0;
}
if(vo_keepaspect){
int tmpheight=((float)width/window_aspect);
tmpheight+=tmpheight%2;
if(tmpheight > height){
width=((float)height*window_aspect);
width+=width%2;
}
else height=tmpheight;
}
if (WinID == -1)
while(ShowCursor(TRUE)<=0){}
}
rd.right=rd.left+width;
rd.bottom=rd.top+height;
@ -680,24 +633,9 @@ static uint32_t Directx_ManageDisplay(void)
}
else
{
g_lpddclipper->lpVtbl->SetHWnd(g_lpddclipper, 0,(vo_fs && !vidmode)?hWndFS: hWnd);
g_lpddclipper->lpVtbl->SetHWnd(g_lpddclipper, 0, vo_w32_window);
}
if(!vidmode && !vo_fs){
if(WinID == -1) {
RECT rdw=rd;
if (vo_border)
AdjustWindowRect(&rdw,WNDSTYLE,FALSE);
// printf("window: %i %i %ix%i\n",rdw.left,rdw.top,rdw.right - rdw.left,rdw.bottom - rdw.top);
rdw.left += monitor_rect.left; /* move to global coordinate space */
rdw.top += monitor_rect.top;
rdw.right += monitor_rect.left;
rdw.bottom += monitor_rect.top;
SetWindowPos(hWnd,(vo_ontop)?HWND_TOPMOST:(vo_rootwin?HWND_BOTTOM:HWND_NOTOPMOST),rdw.left,rdw.top,rdw.right-rdw.left,rdw.bottom-rdw.top,SWP_NOOWNERZORDER);
}
}
else SetWindowPos(vidmode?hWnd:hWndFS,vo_rootwin?HWND_BOTTOM:HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOOWNERZORDER|SWP_NOCOPYBITS);
/*make sure the overlay is inside the screen*/
if(rd.left<0)rd.left=0;
if(rd.right>vo_screenwidth)rd.right=vo_screenwidth;
@ -887,172 +825,10 @@ static uint32_t Directx_CheckPrimaryPixelformat(void)
return 0;
}
//function handles input
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_MOUSEACTIVATE:
return MA_ACTIVATEANDEAT;
case WM_NCACTIVATE:
{
if(vidmode && adapter_count > 2) //only disable if more than one adapter.
return 0;
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
case WM_CLOSE:
{
mplayer_put_key(KEY_CLOSE_WIN);
return 0;
}
case WM_WINDOWPOSCHANGED:
{
//printf("Windowposchange\n");
if(g_lpddsBack != NULL) //or it will crash with -vm
{
Directx_ManageDisplay();
}
break;
}
case WM_SYSCOMMAND:
{
switch (wParam)
{ //kill screensaver etc.
//note: works only when the window is active
//you can workaround this by disabling the allow screensaver option in
//the link to the app
case SC_SCREENSAVE:
case SC_MONITORPOWER:
mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>killing screensaver\n" );
return 0;
case SC_MAXIMIZE:
if (!vo_fs) control(VOCTRL_FULLSCREEN, NULL);
return 0;
}
break;
}
case WM_KEYDOWN:
{
switch (wParam)
{
case VK_LEFT:
{mplayer_put_key(KEY_LEFT);break;}
case VK_UP:
{mplayer_put_key(KEY_UP);break;}
case VK_RIGHT:
{mplayer_put_key(KEY_RIGHT);break;}
case VK_DOWN:
{mplayer_put_key(KEY_DOWN);break;}
case VK_TAB:
{mplayer_put_key(KEY_TAB);break;}
case VK_BACK:
{mplayer_put_key(KEY_BS);break;}
case VK_DELETE:
{mplayer_put_key(KEY_DELETE);break;}
case VK_INSERT:
{mplayer_put_key(KEY_INSERT);break;}
case VK_HOME:
{mplayer_put_key(KEY_HOME);break;}
case VK_END:
{mplayer_put_key(KEY_END);break;}
case VK_PRIOR:
{mplayer_put_key(KEY_PAGE_UP);break;}
case VK_NEXT:
{mplayer_put_key(KEY_PAGE_DOWN);break;}
case VK_ESCAPE:
{mplayer_put_key(KEY_ESC);break;}
}
break;
}
case WM_CHAR:
{
mplayer_put_key(wParam);
break;
}
case WM_LBUTTONDOWN:
{
if (!vo_nomouse_input)
mplayer_put_key(MOUSE_BTN0);
break;
}
case WM_MBUTTONDOWN:
{
if (!vo_nomouse_input)
mplayer_put_key(MOUSE_BTN1);
break;
}
case WM_RBUTTONDOWN:
{
if (!vo_nomouse_input)
mplayer_put_key(MOUSE_BTN2);
break;
}
case WM_LBUTTONDBLCLK:
{
if(!vo_nomouse_input)
mplayer_put_key(MOUSE_BTN0_DBL);
break;
}
case WM_MBUTTONDBLCLK:
{
if(!vo_nomouse_input)
mplayer_put_key(MOUSE_BTN1_DBL);
break;
}
case WM_RBUTTONDBLCLK:
{
if(!vo_nomouse_input)
mplayer_put_key(MOUSE_BTN2_DBL);
break;
}
case WM_MOUSEWHEEL:
{
int x;
if (vo_nomouse_input)
break;
x = GET_WHEEL_DELTA_WPARAM(wParam);
if (x > 0)
mplayer_put_key(MOUSE_BTN3);
else
mplayer_put_key(MOUSE_BTN4);
break;
}
case WM_XBUTTONDOWN:
{
if (vo_nomouse_input)
break;
if (HIWORD(wParam) == 1)
mplayer_put_key(MOUSE_BTN5);
else
mplayer_put_key(MOUSE_BTN6);
break;
}
case WM_XBUTTONDBLCLK:
{
if (vo_nomouse_input)
break;
if (HIWORD(wParam) == 1)
mplayer_put_key(MOUSE_BTN5_DBL);
else
mplayer_put_key(MOUSE_BTN6_DBL);
break;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
static int preinit(const char *arg)
{
HINSTANCE hInstance = GetModuleHandle(NULL);
char exedir[MAX_PATH];
WNDCLASS wc;
if(arg)
{
if(strstr(arg,"noaccel"))
@ -1074,31 +850,13 @@ static int preinit(const char *arg)
windowcolor = vo_colorkey;
colorbrush = CreateSolidBrush(windowcolor);
blackbrush = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hCursor = mplayercursor;
wc.hIcon = mplayericon;
wc.hbrBackground = vidmode ? blackbrush : colorbrush;
wc.lpszClassName = WNDCLASSNAME_WINDOWED;
wc.lpszMenuName = NULL;
RegisterClass(&wc);
if (WinID != -1) hWnd = WinID;
else
hWnd = CreateWindowEx(vidmode?WS_EX_TOPMOST:0,
WNDCLASSNAME_WINDOWED,"",(vidmode || !vo_border)?WS_POPUP:WNDSTYLE,
CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,NULL,NULL,hInstance,NULL);
wc.hbrBackground = blackbrush;
wc.lpszClassName = WNDCLASSNAME_FULLSCREEN;
RegisterClass(&wc);
if (!vo_w32_init())
return 1;
if (!vo_w32_config(100, 100, VOFLAG_HIDDEN))
return 1;
if (Directx_InitDirectDraw()!= 0)return 1; //init DirectDraw
if(!vidmode)hWndFS = CreateWindow(WNDCLASSNAME_FULLSCREEN,"MPlayer Fullscreen",WS_POPUP,monitor_rect.left,monitor_rect.top,monitor_rect.right-monitor_rect.left,monitor_rect.bottom-monitor_rect.top,hWnd,NULL,hInstance,NULL);
mp_msg(MSGT_VO, MSGL_DBG3 ,"<vo_directx><INFO>initial mplayer windows created\n");
if (Directx_CheckPrimaryPixelformat()!=0)return 1;
if (!nooverlay && Directx_CheckOverlayPixelformats() == 0) //check for supported hardware
{
@ -1239,8 +997,6 @@ static uint32_t put_image(mp_image_t *mpi){
uint32_t w = mpi->w;
uint32_t h = mpi->h;
if (WinID != -1) Directx_ManageDisplay();
if((mpi->flags&MP_IMGFLAG_DIRECT)||(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK))
{
mp_msg(MSGT_VO, MSGL_DBG3 ,"<vo_directx><INFO>put_image: nothing to do: drawslices\n");
@ -1278,8 +1034,6 @@ static uint32_t put_image(mp_image_t *mpi){
static int
config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t options, char *title, uint32_t format)
{
RECT rd;
vo_fs = options & 0x01;
image_format = format;
image_width = width;
image_height = height;
@ -1302,32 +1056,11 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin
g_lpddsPrimary = NULL;
mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>overlay surfaces released\n");
if(!vidmode){
if(!vo_geometry){
GetWindowRect(hWnd,&rd);
vo_dx=rd.left;
vo_dy=rd.top;
}
vo_dx += monitor_rect.left; /* move position to global window space */
vo_dy += monitor_rect.top;
rd.left = vo_dx;
rd.top = vo_dy;
rd.right = rd.left + d_image_width;
rd.bottom = rd.top + d_image_height;
if (WinID == -1) {
if (vo_border)
AdjustWindowRect(&rd,WNDSTYLE,FALSE);
SetWindowPos(hWnd,NULL, vo_dx, vo_dy,rd.right-rd.left,rd.bottom-rd.top,SWP_SHOWWINDOW|SWP_NOOWNERZORDER);
}
}
else ShowWindow(hWnd,SW_SHOW);
if (!vo_w32_config(d_width, d_height, options))
return 1;
if(vo_fs && !vidmode)ShowWindow(hWndFS,SW_SHOW);
if (WinID == -1)
SetWindowText(hWnd,title);
if(vidmode)vo_fs=0;
SetWindowText(vo_w32_window,title);
/*create the surfaces*/
@ -1369,7 +1102,7 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin
vo_doublebuffering = 0;
/*create clipper for nonoverlay mode*/
if(g_lpdd->lpVtbl->CreateClipper(g_lpdd, 0, &g_lpddclipper,NULL)!= DD_OK){mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't create clipper\n");return 1;}
if(g_lpddclipper->lpVtbl->SetHWnd (g_lpddclipper, 0, hWnd)!= DD_OK){mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't associate clipper with window\n");return 1;}
if(g_lpddclipper->lpVtbl->SetHWnd (g_lpddclipper, 0, vo_w32_window)!= DD_OK){mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't associate clipper with window\n");return 1;}
if(g_lpddsPrimary->lpVtbl->SetClipper (g_lpddsPrimary,g_lpddclipper)!=DD_OK){mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't associate primary surface with clipper\n");return 1;}
mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>clipper succesfully created\n");
}else{
@ -1475,43 +1208,11 @@ static int control(uint32_t request, void *data)
case VOCTRL_DRAW_IMAGE:
return put_image(data);
case VOCTRL_BORDER:
if(WinID != -1) return VO_TRUE;
if(vidmode)
{
mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>border has no meaning in exclusive mode\n");
}
else
{
if(vo_border) {
vo_border = 0;
SetWindowLong(hWnd, GWL_STYLE, WS_POPUP);
} else {
vo_border = 1;
SetWindowLong(hWnd, GWL_STYLE, WNDSTYLE);
}
// needed AFAICT to force the window to
// redisplay with the new style. --Joey
if (!vo_fs) {
ShowWindow(hWnd,SW_HIDE);
ShowWindow(hWnd,SW_SHOW);
}
last_rect.left = 0xDEADC0DE; // reset window position cache
Directx_ManageDisplay();
}
vo_w32_border();
Directx_ManageDisplay();
return VO_TRUE;
case VOCTRL_ONTOP:
if(WinID != -1) return VO_TRUE;
if(vidmode)
{
mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>ontop has no meaning in exclusive mode\n");
}
else
{
if(vo_ontop) vo_ontop = 0;
else vo_ontop = 1;
last_rect.left = 0xDEADC0DE; // reset window position cache
Directx_ManageDisplay();
}
vo_w32_ontop();
return VO_TRUE;
case VOCTRL_ROOTWIN:
if(WinID != -1) return VO_TRUE;
@ -1529,29 +1230,8 @@ static int control(uint32_t request, void *data)
return VO_TRUE;
case VOCTRL_FULLSCREEN:
{
if(vidmode)
{
mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>currently we do not allow to switch from exclusive to windowed mode\n");
}
else
{
if(!vo_fs)
{
vo_fs=1;
ShowWindow(hWndFS,SW_SHOW);
ShowWindow(hWnd,SW_HIDE);
SetForegroundWindow(hWndFS);
}
else
{
vo_fs=0;
ShowWindow(hWndFS,SW_HIDE);
ShowWindow(hWnd,SW_SHOW);
}
last_rect.left = 0xDEADC0DE; // reset window position cache
Directx_ManageDisplay();
break;
}
vo_w32_fullscreen();
Directx_ManageDisplay();
return VO_TRUE;
}
case VOCTRL_SET_EQUALIZER: {
@ -1563,14 +1243,7 @@ static int control(uint32_t request, void *data)
return color_ctrl_get(args->name, args->valueptr);
}
case VOCTRL_UPDATE_SCREENINFO:
if (vidmode) {
vo_screenwidth = vm_width;
vo_screenheight = vm_height;
} else {
vo_screenwidth = monitor_rect.right - monitor_rect.left;
vo_screenheight = monitor_rect.bottom - monitor_rect.top;
}
aspect_save_screenres(vo_screenwidth, vo_screenheight);
w32_update_xinerama_info();
return VO_TRUE;
case VOCTRL_RESET:
last_rect.left = 0xDEADC0DE; // reset window position cache