diff --git a/libvo/vo_directx.c b/libvo/vo_directx.c index 6df766cc4a..455752179e 100644 --- a/libvo/vo_directx.c +++ b/libvo/vo_directx.c @@ -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,"primary released\n"); - if(hWndFS)DestroyWindow(hWndFS); - hWndFS = NULL; - if((WinID == -1) && hWnd) DestroyWindow(hWnd); - hWnd = NULL; - mp_msg(MSGT_VO, MSGL_DBG3,"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,"GDI resources deleted\n"); @@ -373,6 +365,7 @@ static void uninit(void) hddraw_dll= NULL; mp_msg(MSGT_VO, MSGL_DBG3,"ddraw.dll freed\n"); mp_msg(MSGT_VO, MSGL_DBG3,"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,"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,"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,"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, ¤t_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 ,"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 ,"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 ,"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,"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,"can't create clipper\n");return 1;} - if(g_lpddclipper->lpVtbl->SetHWnd (g_lpddclipper, 0, hWnd)!= DD_OK){mp_msg(MSGT_VO, MSGL_FATAL,"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,"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,"can't associate primary surface with clipper\n");return 1;} mp_msg(MSGT_VO, MSGL_DBG3,"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,"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,"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,"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