comparison libvo/vo_directx.c @ 12005:a8adfcf47f4e

adapter selection patch by Rune <runner at mail.tele.dk> +first attempt to implement 2 window fullscreenswitching by me
author faust3
date Sun, 29 Feb 2004 20:33:07 +0000
parents 85e503ddf65f
children 1604d07d3539
comparison
equal deleted inserted replaced
12004:494a93a19242 12005:a8adfcf47f4e
19 *****************************************************************************/ 19 *****************************************************************************/
20 20
21 #include <windows.h> 21 #include <windows.h>
22 #include <windowsx.h> 22 #include <windowsx.h>
23 #include <ddraw.h> 23 #include <ddraw.h>
24 #include <stdio.h>
24 #include <stdlib.h> 25 #include <stdlib.h>
25 #include <errno.h> 26 #include <errno.h>
26 #include "config.h" 27 #include "config.h"
27 #include "video_out.h" 28 #include "video_out.h"
28 #include "video_out_internal.h" 29 #include "video_out_internal.h"
31 #include "../osdep/keycodes.h" 32 #include "../osdep/keycodes.h"
32 #include "../mp_msg.h" 33 #include "../mp_msg.h"
33 #include "aspect.h" 34 #include "aspect.h"
34 #include "geometry.h" 35 #include "geometry.h"
35 36
36 static LPDIRECTDRAW2 g_lpdd = NULL; //DirectDraw Object 37 static LPDIRECTDRAW7 g_lpdd = NULL; //DirectDraw Object
37 static LPDIRECTDRAWSURFACE g_lpddsPrimary = NULL; //Primary Surface: viewport through the Desktop 38 static LPDIRECTDRAWSURFACE7 g_lpddsPrimary = NULL; //Primary Surface: viewport through the Desktop
38 static LPDIRECTDRAWSURFACE g_lpddsOverlay = NULL; //Overlay Surface 39 static LPDIRECTDRAWSURFACE7 g_lpddsOverlay = NULL; //Overlay Surface
39 static LPDIRECTDRAWSURFACE g_lpddsBack = NULL; //Back surface 40 static LPDIRECTDRAWSURFACE7 g_lpddsBack = NULL; //Back surface
40 static LPDIRECTDRAWCLIPPER g_lpddclipper; //clipper object, can only be used without overlay 41 static LPDIRECTDRAWCLIPPER g_lpddclipper; //clipper object, can only be used without overlay
41 static DDSURFACEDESC ddsdsf; //surface descripiton needed for locking 42 static DDSURFACEDESC2 ddsdsf; //surface descripiton needed for locking
42 static HINSTANCE hddraw_dll; //handle to ddraw.dll 43 static HINSTANCE hddraw_dll; //handle to ddraw.dll
43 static RECT rd; //rect of our stretched image 44 static RECT rd; //rect of our stretched image
44 static RECT rs; //rect of our source image 45 static RECT rs; //rect of our source image
45 static HWND hWnd=NULL; //handle to the window 46 static HWND hWnd=NULL; //handle to the window
47 static HWND hWndFS=NULL; //fullscreen window
46 static uint32_t image_width, image_height; //image width and height 48 static uint32_t image_width, image_height; //image width and height
47 static uint32_t d_image_width, d_image_height; //image width and height zoomed 49 static uint32_t d_image_width, d_image_height; //image width and height zoomed
48 static uint8_t *image=NULL; //image data 50 static uint8_t *image=NULL; //image data
49 static uint32_t image_format=0; //image format 51 static uint32_t image_format=0; //image format
50 static uint32_t primary_image_format; 52 static uint32_t primary_image_format;
51 static uint32_t vm = 0; //exclusive mode, allows resolution switching (not implemented yet) 53 static uint32_t vm_height=0;
54 static uint32_t vm_width=0;
55 static uint32_t vm_bpp=0;
52 static uint32_t dstride; //surface stride 56 static uint32_t dstride; //surface stride
53 static uint32_t nooverlay = 0; //NonOverlay mode 57 static uint32_t nooverlay = 0; //NonOverlay mode
54 static DWORD destcolorkey; //colorkey for our surface 58 static DWORD destcolorkey; //colorkey for our surface
55 static COLORREF windowcolor = RGB(0,0,16); //windowcolor == colorkey 59 static COLORREF windowcolor = RGB(0,0,16); //windowcolor == colorkey
60 int adapter_num=0;
61 int refresh_rate=0;
62 static int adapter_count=0;
63 static GUID selected_guid;
64 static GUID *selected_guid_ptr = NULL;
56 65
57 extern void mplayer_put_key(int code); //let mplayer handel the keyevents 66 extern void mplayer_put_key(int code); //let mplayer handel the keyevents
58 extern void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)); 67 extern void vo_draw_text(int dxs,int dys,void (*draw_alpha)(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride));
59 extern int vo_doublebuffering; //tribblebuffering 68 extern int vo_doublebuffering; //tribblebuffering
60 extern int vo_fs; 69 extern int vo_fs;
61 extern int vo_directrendering; 70 extern int vo_directrendering;
62 extern int vo_ontop; 71 extern int vo_ontop;
72 extern int vidmode;
63 73
64 /***************************************************************************** 74 /*****************************************************************************
65 * DirectDraw GUIDs. 75 * DirectDraw GUIDs.
66 * Defining them here allows us to get rid of the dxguid library during 76 * Defining them here allows us to get rid of the dxguid library during
67 * the linking stage. 77 * the linking stage.
68 *****************************************************************************/ 78 *****************************************************************************/
69 static const GUID IID_IDirectDraw2 = 79 static const GUID IID_IDirectDraw7 =
70 { 80 {
71 0xB3A6F3E0,0x2B43,0x11CF,{0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56} 81 0x15e65ec0,0x3b9c,0x11d2,{0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b}
72 }; 82 };
73 83
74 typedef struct directx_fourcc_caps 84 typedef struct directx_fourcc_caps
75 { 85 {
76 char* img_format_name; //human readable name 86 char* img_format_name; //human readable name
162 return 0; 172 return 0;
163 } 173 }
164 174
165 static uint32_t Directx_CreatePrimarySurface() 175 static uint32_t Directx_CreatePrimarySurface()
166 { 176 {
167 DDSURFACEDESC ddsd; 177 DDSURFACEDESC2 ddsd;
168 //cleanup 178 //cleanup
169 if(g_lpddsPrimary)g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary); 179 if(g_lpddsPrimary)g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);
170 g_lpddsPrimary=NULL; 180 g_lpddsPrimary=NULL;
171 ZeroMemory(&ddsd, sizeof(ddsd)); 181
182 if(vidmode)g_lpdd->lpVtbl->SetDisplayMode(g_lpdd,vm_width,vm_height,vm_bpp,refresh_rate,0);
183 ZeroMemory(&ddsd, sizeof(ddsd));
172 ddsd.dwSize = sizeof(ddsd); 184 ddsd.dwSize = sizeof(ddsd);
173 //set flags and create a primary surface. 185 //set flags and create a primary surface.
174 ddsd.dwFlags = DDSD_CAPS; 186 ddsd.dwFlags = DDSD_CAPS;
175 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; 187 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
176 if(g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsd, &g_lpddsPrimary, NULL )== DD_OK) 188 if(g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsd, &g_lpddsPrimary, NULL )== DD_OK)
184 } 196 }
185 197
186 static uint32_t Directx_CreateOverlay(uint32_t imgfmt) 198 static uint32_t Directx_CreateOverlay(uint32_t imgfmt)
187 { 199 {
188 HRESULT ddrval; 200 HRESULT ddrval;
189 DDSURFACEDESC ddsdOverlay; 201 DDSURFACEDESC2 ddsdOverlay;
190 uint32_t i=0; 202 uint32_t i=0;
191 while ( i < NUM_FORMATS +1 && imgfmt != g_ddpf[i].img_format) 203 while ( i < NUM_FORMATS +1 && imgfmt != g_ddpf[i].img_format)
192 { 204 {
193 i++; 205 i++;
194 } 206 }
268 return 0; 280 return 0;
269 } 281 }
270 282
271 static uint32_t Directx_CreateBackpuffer() 283 static uint32_t Directx_CreateBackpuffer()
272 { 284 {
273 DDSURFACEDESC ddsd; 285 DDSURFACEDESC2 ddsd;
274 //cleanup 286 //cleanup
275 if (g_lpddsBack)g_lpddsBack->lpVtbl->Release(g_lpddsBack); 287 if (g_lpddsBack)g_lpddsBack->lpVtbl->Release(g_lpddsBack);
276 g_lpddsBack=NULL; 288 g_lpddsBack=NULL;
277 ZeroMemory(&ddsd, sizeof(ddsd)); 289 ZeroMemory(&ddsd, sizeof(ddsd));
278 ddsd.dwSize = sizeof(ddsd); 290 ddsd.dwSize = sizeof(ddsd);
304 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>overlay surface released\n"); 316 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>overlay surface released\n");
305 } 317 }
306 if (g_lpddsPrimary != NULL) g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary); 318 if (g_lpddsPrimary != NULL) g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);
307 g_lpddsPrimary = NULL; 319 g_lpddsPrimary = NULL;
308 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>primary released\n"); 320 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>primary released\n");
321 if(hWndFS)DestroyWindow(hWndFS);
309 if(hWnd != NULL)DestroyWindow(hWnd); 322 if(hWnd != NULL)DestroyWindow(hWnd);
310 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>window destroyed\n"); 323 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>window destroyed\n");
311 if (g_lpdd != NULL) g_lpdd->lpVtbl->Release(g_lpdd); 324 if (g_lpdd != NULL){
325 if(vidmode)g_lpdd->lpVtbl->RestoreDisplayMode(g_lpdd);
326 g_lpdd->lpVtbl->Release(g_lpdd);
327 }
312 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>directdrawobject released\n"); 328 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>directdrawobject released\n");
313 FreeLibrary( hddraw_dll); 329 FreeLibrary( hddraw_dll);
314 hddraw_dll= NULL; 330 hddraw_dll= NULL;
315 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>ddraw.dll freed\n"); 331 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>ddraw.dll freed\n");
316 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>uninited\n"); 332 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>uninited\n");
317 } 333 }
318 334
335 static BOOL WINAPI EnumCallbackEx(GUID FAR *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, LPVOID lpContext, HMONITOR hm)
336 {
337 mp_msg(MSGT_VO, MSGL_INFO ,"<vo_directx> adapter %d: ", adapter_count);
338
339 if (!lpGUID)
340 {
341 mp_msg(MSGT_VO, MSGL_INFO ,"%s", "Primary Display Adapter");
342 }
343 else
344 {
345 mp_msg(MSGT_VO, MSGL_INFO ,"%s", lpDriverDescription);
346 }
347
348 if(adapter_count == adapter_num){
349 if (!lpGUID)
350 selected_guid_ptr = NULL;
351 else
352 {
353 selected_guid = *lpGUID;
354 selected_guid_ptr = &selected_guid;
355 }
356 mp_msg(MSGT_VO, MSGL_INFO ,"\t\t<--");
357 }
358 mp_msg(MSGT_VO, MSGL_INFO ,"\n");
359
360 adapter_count++;
361
362 return 1; // list all adapters
363 }
364
319 static uint32_t Directx_InitDirectDraw() 365 static uint32_t Directx_InitDirectDraw()
320 { 366 {
321 HRESULT (WINAPI *OurDirectDrawCreate)(GUID *,LPDIRECTDRAW *,IUnknown *); 367 HRESULT (WINAPI *OurDirectDrawCreateEx)(GUID *,LPVOID *, REFIID,IUnknown FAR *);
322 LPDIRECTDRAW lpDDraw; 368 LPDIRECTDRAW lpDDraw;
369 DDSURFACEDESC2 ddsd;
370 LPDIRECTDRAWENUMERATEEX OurDirectDrawEnumerateEx;
371
323 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>Initing DirectDraw\n" ); 372 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>Initing DirectDraw\n" );
324 373
325 //load direct draw DLL: based on videolans code 374 //load direct draw DLL: based on videolans code
326 hddraw_dll = LoadLibrary("DDRAW.DLL"); 375 hddraw_dll = LoadLibrary("DDRAW.DLL");
327 if( hddraw_dll == NULL ) 376 if( hddraw_dll == NULL )
328 { 377 {
329 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed loading ddraw.dll\n" ); 378 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed loading ddraw.dll\n" );
330 return 1; 379 return 1;
331 } 380 }
332 OurDirectDrawCreate = (void *)GetProcAddress(hddraw_dll, "DirectDrawCreate"); 381
333 if ( OurDirectDrawCreate == NULL ) 382 if(adapter_num){ //display other than default
334 { 383 OurDirectDrawEnumerateEx = (LPDIRECTDRAWENUMERATEEX) GetProcAddress(hddraw_dll,"DirectDrawEnumerateExA");
335 FreeLibrary( hddraw_dll ); 384 if (!OurDirectDrawEnumerateEx){
336 hddraw_dll = NULL; 385 FreeLibrary( hddraw_dll );
337 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed geting proc address\n"); 386 hddraw_dll = NULL;
338 return 1; 387 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed geting proc address: DirectDrawEnumerateEx\n");
339 } 388 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>no directx 7 or higher installed\n");
340 // initialize DirectDraw and create directx v1 object 389 return 1;
341 if (OurDirectDrawCreate( NULL, &lpDDraw, NULL ) != DD_OK ) 390 }
342 { 391
343 lpDDraw = NULL; 392 // enumerate all display devices attached to the desktop
393 OurDirectDrawEnumerateEx(EnumCallbackEx, NULL, DDENUM_ATTACHEDSECONDARYDEVICES );
394
395 if(adapter_num >= adapter_count)
396 mp_msg(MSGT_VO, MSGL_ERR,"Selected adapter (%d) doesn't exist: Default Display Adapter selected\n",adapter_num);
397 }
398
399 OurDirectDrawCreateEx = (void *)GetProcAddress(hddraw_dll, "DirectDrawCreateEx");
400 if ( OurDirectDrawCreateEx == NULL )
401 {
402 FreeLibrary( hddraw_dll );
403 hddraw_dll = NULL;
404 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed geting proc address: DirectDrawCreateEx\n");
405 return 1;
406 }
407
408 // initialize DirectDraw and create directx v7 object
409 if (OurDirectDrawCreateEx(selected_guid_ptr, (VOID**)&g_lpdd, &IID_IDirectDraw7, NULL ) != DD_OK )
410 {
344 FreeLibrary( hddraw_dll ); 411 FreeLibrary( hddraw_dll );
345 hddraw_dll = NULL; 412 hddraw_dll = NULL;
346 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't initialize ddraw\n"); 413 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't initialize ddraw\n");
347 return 1; 414 return 1;
348 } 415 }
349 // ask IDirectDraw for IDirectDraw2 416
350 if (lpDDraw->lpVtbl->QueryInterface(lpDDraw, &IID_IDirectDraw2, (void **)&g_lpdd) != DD_OK) 417 //get current screen siz for selected monitor ...
351 { 418 ddsd.dwSize=sizeof(ddsd);
352 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>no directx 2 installed\n"); 419 ddsd.dwFlags=DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
353 return 1; 420 g_lpdd->lpVtbl->GetDisplayMode(g_lpdd, &ddsd);
354 } 421 if(vo_screenwidth && vo_screenheight)
355 //release our old interface and free ddraw.dll 422 {
356 lpDDraw->lpVtbl->Release(lpDDraw); 423 vm_height=vo_screenheight;
357 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>lpDDraw released\n" ); 424 vm_width=vo_screenwidth;
358 //set cooperativelevel: for our tests, no handle to a window is needed 425 }
359 if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, NULL, DDSCL_NORMAL) != DD_OK) 426 else
360 { 427 {
428 vm_height=ddsd.dwHeight;
429 vm_width=ddsd.dwWidth;
430 }
431
432
433 if(vo_dbpp)vm_bpp=vo_dbpp;
434 else vm_bpp=ddsd.ddpfPixelFormat.dwRGBBitCount;
435
436 if(vidmode){
437 if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN) != DD_OK)
438 {
439 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set cooperativelevel for exclusive mode\n");
440 return 1;
441 }
442 /*SetDisplayMode(ddobject,width,height,bpp,refreshrate,aditionalflags)*/
443 if(g_lpdd->lpVtbl->SetDisplayMode(g_lpdd,vm_width, vm_height, vm_bpp,0,0) != DD_OK)
444 {
445 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set displaymode\n");
446 return 1;
447 }
448 mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>Inited adapter %i for %i x %i @ %i \n",adapter_num,vm_width,vm_height,vm_bpp);
449 return 0;
450 }
451 if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_NORMAL) != DD_OK) // or DDSCL_SETFOCUSWINDOW
452 {
361 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>could not set cooperativelevel for hardwarecheck\n"); 453 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>could not set cooperativelevel for hardwarecheck\n");
362 return 1; 454 return 1;
363 } 455 }
364 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>DirectDraw Inited\n"); 456 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>DirectDraw Inited\n");
365 return 0; 457 return 0;
373 TranslateMessage(&msg); 465 TranslateMessage(&msg);
374 DispatchMessage(&msg); 466 DispatchMessage(&msg);
375 } 467 }
376 } 468 }
377 469
378 static uint32_t Directx_ManageDisplay(uint32_t width,uint32_t height) 470 static uint32_t Directx_ManageDisplay()
379 { 471 {
380 RECT rd_window; 472 RECT rd_window;
381 HRESULT ddrval; 473 HRESULT ddrval;
382 DDCAPS capsDrv; 474 DDCAPS capsDrv;
383 DDOVERLAYFX ovfx; 475 DDOVERLAYFX ovfx;
384 DWORD dwUpdateFlags=0; 476 DWORD dwUpdateFlags=0;
385 HWND hWndafter; 477 HWND hWndafter;
386 uint32_t xscreen = GetSystemMetrics(SM_CXSCREEN); 478 uint32_t xscreen = GetSystemMetrics(SM_CXSCREEN);
387 uint32_t yscreen = GetSystemMetrics(SM_CYSCREEN); 479 uint32_t yscreen = GetSystemMetrics(SM_CYSCREEN);
388 POINT point_window; 480 POINT point_window;
389 if(vo_fs) 481 uint32_t width,height;
482
483 if(vidmode){
484 xscreen=vm_width;
485 yscreen=vm_height;
486 }
487 if(vo_fs || vidmode)
390 { 488 {
391 /*center and zoom image*/ 489 /*center and zoom image*/
392 rd_window.top = 0; 490 rd_window.top = 0;
393 rd_window.left = 0; 491 rd_window.left = 0;
394 rd_window.right = xscreen; 492 rd_window.right = xscreen;
396 aspect(&width,&height,A_ZOOM); 494 aspect(&width,&height,A_ZOOM);
397 rd.left = (xscreen-width)/2; 495 rd.left = (xscreen-width)/2;
398 rd.right = rd.left+width; 496 rd.right = rd.left+width;
399 rd.top = (yscreen-height)/2; 497 rd.top = (yscreen-height)/2;
400 rd.bottom = rd.top + height; 498 rd.bottom = rd.top + height;
499 if(ShowCursor(FALSE)>=0)while(ShowCursor(FALSE)>=0){}
401 } 500 }
402 else /*windowed*/ 501 else /*windowed*/
403 { 502 {
404 GetClientRect (hWnd, &rd_window); 503 GetClientRect (hWnd, &rd_window);
405 if((rd_window.top == rd_window.bottom)&&!nooverlay) 504 if((rd_window.top == rd_window.bottom)&&!nooverlay)
407 /*window is minimized let's hide our overlay*/ 506 /*window is minimized let's hide our overlay*/
408 ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,NULL, g_lpddsPrimary, NULL, DDOVER_HIDE, NULL); //hide the overlay 507 ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,NULL, g_lpddsPrimary, NULL, DDOVER_HIDE, NULL); //hide the overlay
409 return 0; 508 return 0;
410 } 509 }
411 /*width and height are zero therefore we have to get them from the window size*/ 510 /*width and height are zero therefore we have to get them from the window size*/
412 if(!width)width = rd_window.right - rd_window.left; 511 width=rd_window.right - rd_window.left;
413 if(!height)height = rd_window.bottom - rd_window.top; 512 height=rd_window.bottom - rd_window.top;
414 point_window.x = 0; //overlayposition relative to the window 513 point_window.x = 0; //overlayposition relative to the window
415 point_window.y = 0; 514 point_window.y = 0;
416 ClientToScreen(hWnd,&point_window); 515 ClientToScreen(hWnd,&point_window);
417 rd.left = point_window.x; 516 rd.left = point_window.x;
418 rd.top = point_window.y; 517 rd.top = point_window.y;
419 rd.bottom = rd.top + height; 518 rd.bottom = rd.top + height;
420 rd.right = rd.left + width; 519 rd.right = rd.left + width;
421 rd_window = rd; 520 rd_window = rd;
422 } 521 ShowCursor(TRUE);
423 522 }
523
524
424 /*ok, let's workaround some overlay limitations*/ 525 /*ok, let's workaround some overlay limitations*/
425 if(!nooverlay) 526 if(!nooverlay)
426 { 527 {
427 uint32_t uStretchFactor1000; //minimum stretch 528 uint32_t uStretchFactor1000; //minimum stretch
428 uint32_t xstretch1000,ystretch1000; 529 uint32_t xstretch1000,ystretch1000;
511 if(!vo_fs)rd_window.right = rd_window.left + ((rd_window.right - rd_window.left) & -(signed) (capsDrv.dwAlignSizeDest)); //don't forget the window 612 if(!vo_fs)rd_window.right = rd_window.left + ((rd_window.right - rd_window.left) & -(signed) (capsDrv.dwAlignSizeDest)); //don't forget the window
512 } 613 }
513 /*create an overlay FX structure to specify a destination color key*/ 614 /*create an overlay FX structure to specify a destination color key*/
514 ZeroMemory(&ovfx, sizeof(ovfx)); 615 ZeroMemory(&ovfx, sizeof(ovfx));
515 ovfx.dwSize = sizeof(ovfx); 616 ovfx.dwSize = sizeof(ovfx);
516 if(vo_fs) 617 if(vo_fs||vidmode)
517 { 618 {
518 ovfx.dckDestColorkey.dwColorSpaceLowValue = 0; 619 ovfx.dckDestColorkey.dwColorSpaceLowValue = 0;
519 ovfx.dckDestColorkey.dwColorSpaceHighValue = 0; 620 ovfx.dckDestColorkey.dwColorSpaceHighValue = 0;
520 } 621 }
521 else 622 else
527 dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX; 628 dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX;
528 /*if hardware can't do colorkeying set the window on top*/ 629 /*if hardware can't do colorkeying set the window on top*/
529 if(capsDrv.dwCKeyCaps & DDCKEYCAPS_DESTOVERLAY) dwUpdateFlags |= DDOVER_KEYDESTOVERRIDE; 630 if(capsDrv.dwCKeyCaps & DDCKEYCAPS_DESTOVERLAY) dwUpdateFlags |= DDOVER_KEYDESTOVERRIDE;
530 else vo_ontop = 1; 631 else vo_ontop = 1;
531 } 632 }
532 /*calculate window rect with borders*/ 633 else
533 if(!vo_fs)AdjustWindowRect(&rd_window,WS_OVERLAPPEDWINDOW|WS_SIZEBOX,0); 634 {
534 635 g_lpddclipper->lpVtbl->SetHWnd(g_lpddclipper, 0,vo_fs?hWndFS: hWnd);
535 if((vo_fs) || (!vo_fs && vo_ontop))hWndafter=HWND_TOPMOST; 636 }
536 else hWndafter=HWND_NOTOPMOST; 637
537 638 if(!vidmode && !vo_fs){
538 /*display the window*/ 639 if(vo_ontop)SetWindowPos(hWnd,HWND_TOPMOST,0,0,0,0,SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER);
539 SetWindowPos(hWnd, 640 else SetWindowPos(hWnd,HWND_NOTOPMOST,0,0,0,0,SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER);
540 hWndafter, 641 }
541 rd_window.left, 642
542 rd_window.top, 643
543 rd_window.right - rd_window.left,
544 rd_window.bottom - rd_window.top,
545 SWP_SHOWWINDOW|SWP_NOOWNERZORDER);
546 //printf("Window:x:%i,y:%i,w:%i,h:%i\n",rd_window.left,rd_window.top,rd_window.right - rd_window.left,rd_window.bottom - rd_window.top); 644 //printf("Window:x:%i,y:%i,w:%i,h:%i\n",rd_window.left,rd_window.top,rd_window.right - rd_window.left,rd_window.bottom - rd_window.top);
547 //printf("Overlay:x1:%i,y1:%i,x2:%i,y2:%i,w:%i,h:%i\n",rd.left,rd.top,rd.right,rd.bottom,rd.right - rd.left,rd.bottom - rd.top); 645 //printf("Overlay:x1:%i,y1:%i,x2:%i,y2:%i,w:%i,h:%i\n",rd.left,rd.top,rd.right,rd.bottom,rd.right - rd.left,rd.bottom - rd.top);
548 //printf("Source:x1:%i,x2:%i,y1:%i,y2:%i\n",rs.left,rs.right,rs.top,rs.bottom); 646 //printf("Source:x1:%i,x2:%i,y1:%i,y2:%i\n",rs.left,rs.right,rs.top,rs.bottom);
549 //printf("Image:x:%i->%i,y:%i->%i\n",image_width,d_image_width,image_height,d_image_height); 647 //printf("Image:x:%i->%i,y:%i->%i\n",image_width,d_image_width,image_height,d_image_height);
550 648
602 //find out supported overlay pixelformats 700 //find out supported overlay pixelformats
603 static uint32_t Directx_CheckOverlayPixelformats() 701 static uint32_t Directx_CheckOverlayPixelformats()
604 { 702 {
605 DDCAPS capsDrv; 703 DDCAPS capsDrv;
606 HRESULT ddrval; 704 HRESULT ddrval;
607 DDSURFACEDESC ddsdOverlay; 705 DDSURFACEDESC2 ddsdOverlay;
608 uint32_t i; 706 uint32_t i;
609 uint32_t formatcount = 0; 707 uint32_t formatcount = 0;
610 //get driver caps to determine overlay support 708 //get driver caps to determine overlay support
611 ZeroMemory(&capsDrv, sizeof(capsDrv)); 709 ZeroMemory(&capsDrv, sizeof(capsDrv));
612 capsDrv.dwSize = sizeof(capsDrv); 710 capsDrv.dwSize = sizeof(capsDrv);
664 static uint32_t Directx_CheckPrimaryPixelformat() 762 static uint32_t Directx_CheckPrimaryPixelformat()
665 { 763 {
666 uint32_t i=0; 764 uint32_t i=0;
667 uint32_t formatcount = 0; 765 uint32_t formatcount = 0;
668 DDPIXELFORMAT ddpf; 766 DDPIXELFORMAT ddpf;
669 DDSURFACEDESC ddsd; 767 DDSURFACEDESC2 ddsd;
670 HDC hdc; 768 HDC hdc;
671 HRESULT hres; 769 HRESULT hres;
672 COLORREF rgbT=RGB(0,0,0); 770 COLORREF rgbT=RGB(0,0,0);
673 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>checking primary surface\n"); 771 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>checking primary surface\n");
674 memset( &ddpf, 0, sizeof( DDPIXELFORMAT )); 772 memset( &ddpf, 0, sizeof( DDPIXELFORMAT ));
732 //function handles input 830 //function handles input
733 static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 831 static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
734 { 832 {
735 switch (message) 833 switch (message)
736 { 834 {
835 case WM_NCACTIVATE:
836 {
837 if(vidmode && adapter_count > 2) //only disable if more than one adapter.
838 return 0;
839 break;
840 }
737 case WM_DESTROY: 841 case WM_DESTROY:
738 { 842 {
739 PostQuitMessage(0); 843 PostQuitMessage(0);
740 return 0; 844 return 0;
741 } 845 }
807 911
808 } 912 }
809 return DefWindowProc(hWnd, message, wParam, lParam); 913 return DefWindowProc(hWnd, message, wParam, lParam);
810 } 914 }
811 915
916
812 static uint32_t preinit(const char *arg) 917 static uint32_t preinit(const char *arg)
813 { 918 {
814 HINSTANCE hInstance = GetModuleHandle(NULL); 919 HINSTANCE hInstance = GetModuleHandle(NULL);
815 HICON mplayericon=NULL; 920 HICON mplayericon=NULL;
816 char exedir[MAX_PATH]; 921 char exedir[MAX_PATH];
821 { 926 {
822 mp_msg(MSGT_VO,MSGL_V,"<vo_directx><INFO>disabled overlay\n"); 927 mp_msg(MSGT_VO,MSGL_V,"<vo_directx><INFO>disabled overlay\n");
823 nooverlay = 1; 928 nooverlay = 1;
824 } 929 }
825 } 930 }
826 if (Directx_InitDirectDraw()!= 0)return 1; //init DirectDraw 931 /*load icon from the main app*/
827 if (Directx_CheckPrimaryPixelformat()!=0)return 1;
828 if (!nooverlay && Directx_CheckOverlayPixelformats() == 0) //check for supported hardware
829 {
830 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>hardware supports overlay\n");
831 nooverlay = 0;
832 }
833 else //if we can't have overlay we create a backpuffer with the same imageformat as the primary surface
834 {
835 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>using backpuffer\n");
836 nooverlay = 1;
837 }
838 /*load icon from the main app*/
839 if(GetModuleFileName(NULL,exedir,MAX_PATH)) 932 if(GetModuleFileName(NULL,exedir,MAX_PATH))
840 { 933 {
841 mplayericon = ExtractIcon( hInstance, exedir, 0 ); 934 mplayericon = ExtractIcon( hInstance, exedir, 0 );
842 } 935 }
843 if(!mplayericon)mplayericon=LoadIcon(NULL,IDI_APPLICATION); 936 if(!mplayericon)mplayericon=LoadIcon(NULL,IDI_APPLICATION);
844 wc.style = CS_HREDRAW | CS_VREDRAW; 937 wc.style = CS_HREDRAW | CS_VREDRAW;
845 wc.lpfnWndProc = WndProc; 938 wc.lpfnWndProc = WndProc;
846 wc.cbClsExtra = 0; 939 wc.cbClsExtra = 0;
847 wc.cbWndExtra = 0; 940 wc.cbWndExtra = 0;
848 wc.hInstance = hInstance; 941 wc.hInstance = hInstance;
849 wc.hCursor = LoadCursor(NULL,IDC_ARROW); 942 wc.hCursor = LoadCursor(NULL,IDC_ARROW);
850 wc.hIcon = mplayericon; 943 wc.hIcon = mplayericon;
851 wc.hbrBackground = CreateSolidBrush(windowcolor); 944 wc.hbrBackground = CreateSolidBrush(vidmode?RGB(0,0,0):windowcolor);
852 wc.lpszClassName = "Mplayer - Movieplayer for Linux"; 945 wc.lpszClassName = "Mplayer - Movieplayer for Linux";
853 wc.lpszMenuName = NULL; 946 wc.lpszMenuName = NULL;
854 RegisterClass(&wc); 947 RegisterClass(&wc);
855 hWnd = CreateWindow("MPlayer - Movieplayer for Linux", 948 hWnd = CreateWindowEx(vidmode?WS_EX_TOPMOST:0,
856 "", 949 "MPlayer - Movieplayer for Linux","",(vidmode)?WS_POPUP:WS_OVERLAPPEDWINDOW| WS_SIZEBOX,
857 WS_OVERLAPPEDWINDOW| WS_SIZEBOX, 950 CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,NULL,NULL,hInstance,NULL);
858 CW_USEDEFAULT, //position x 951 wc.hbrBackground = CreateSolidBrush(RGB(0,0,0));
859 CW_USEDEFAULT, //position y 952 wc.lpszClassName = "MPlayer - Fullscreen";
860 100, //width 953 RegisterClass(&wc);
861 100, //height 954 hWndFS = CreateWindow("MPlayer - Fullscreen","MPlayer Fullscreen",WS_POPUP,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),hWnd,NULL,hInstance,NULL);
862 NULL, 955 mp_msg(MSGT_VO, MSGL_DBG3 ,"<vo_directx><INFO>initial mplayer windows created\n");
863 NULL, 956
864 hInstance, 957 if (Directx_InitDirectDraw()!= 0)return 1; //init DirectDraw
865 NULL); 958 if (Directx_CheckPrimaryPixelformat()!=0)return 1;
866 mp_msg(MSGT_VO, MSGL_DBG3 ,"<vo_directx><INFO>initial mplayer window created\n"); 959 if (!nooverlay && Directx_CheckOverlayPixelformats() == 0) //check for supported hardware
867 mp_msg(MSGT_VO, MSGL_DBG3 ,"<vo_directx><INFO>preinit succesfully finished\n"); 960 {
961 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>hardware supports overlay\n");
962 nooverlay = 0;
963 }
964 else //if we can't have overlay we create a backpuffer with the same imageformat as the primary surface
965 {
966 mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>using backpuffer\n");
967 nooverlay = 1;
968 }
969 mp_msg(MSGT_VO, MSGL_DBG3 ,"<vo_directx><INFO>preinit succesfully finished\n");
868 return 0; 970 return 0;
869 } 971 }
870 972
871 static uint32_t draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y ) 973 static uint32_t draw_slice(uint8_t *src[], int stride[], int w,int h,int x,int y )
872 { 974 {
1041 } 1143 }
1042 1144
1043 static uint32_t 1145 static uint32_t
1044 config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t options, char *title, uint32_t format) 1146 config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t options, char *title, uint32_t format)
1045 { 1147 {
1046 int wx=-1; 1148 vo_screenwidth = GetSystemMetrics(SM_CXSCREEN);
1047 int wy=-1; 1149 vo_screenheight = GetSystemMetrics(SM_CYSCREEN);
1048 vo_fs = options & 0x01; 1150 vo_fs = options & 0x01;
1049 vm = options & 0x02; 1151 RECT rd;
1050 image_format = format; 1152 image_format = format;
1051 image_width = width; 1153 image_width = width;
1052 image_height = height; 1154 image_height = height;
1053 d_image_width = d_width; 1155 d_image_width = d_width;
1054 d_image_height = d_height; 1156 d_image_height = d_height;
1055 nooverlay = 0; 1157 nooverlay = 0;
1056 aspect_save_orig(image_width,image_height); 1158 aspect_save_orig(image_width,image_height);
1057 aspect_save_prescale(d_image_width,d_image_height); 1159 aspect_save_prescale(d_image_width,d_image_height);
1058 aspect_save_screenres(GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN)); 1160 if(vidmode){
1059 geometry(&wx, &wy, &d_image_width, &d_image_height,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN)); 1161 vo_screenwidth=vm_width;
1060 aspect(&d_image_width,&d_image_height,A_NOZOOM); 1162 vo_screenheight=vm_height;
1061 if(wx !=-1)SetWindowPos(hWnd,NULL, wx, wy,d_image_width,d_image_height,SWP_SHOWWINDOW|SWP_NOOWNERZORDER); 1163 }
1062 SetWindowText(hWnd,title); 1164 aspect_save_screenres(vo_screenwidth,vo_screenheight);
1165 aspect(&d_image_width, &d_image_height, A_NOZOOM);
1166 vo_dx = 0;
1167 vo_dy = 0;
1168 if(!vidmode){
1169 if(vo_geometry){
1170 vo_dx= ( vo_screenwidth - d_image_width ) / 2; vo_dy=( vo_screenheight - d_image_height ) / 2;
1171 geometry(&vo_dx, &vo_dy, &d_image_width, &d_image_height, vo_screenwidth, vo_screenheight);
1172 }
1173 else {
1174 GetWindowRect(hWnd,&rd);
1175 vo_dx=rd.left;
1176 vo_dy=rd.top;
1177 }
1178 rd.left = vo_dx;
1179 rd.top = vo_dy;
1180 rd.right = rd.left + d_image_width;
1181 rd.bottom = rd.top + d_image_height;
1182 AdjustWindowRect(&rd,WS_OVERLAPPEDWINDOW| WS_SIZEBOX,0);
1183 SetWindowPos(hWnd,NULL, rd.left, rd.top,rd.right-rd.left,rd.bottom-rd.top,SWP_SHOWWINDOW|SWP_NOOWNERZORDER);
1184 }
1185 else ShowWindow(hWnd,SW_SHOW);
1186
1187 if(vo_fs && !vidmode)ShowWindow(hWndFS,SW_SHOW);
1188 SetWindowText(hWnd,title);
1063 1189
1190
1191 if(vidmode)vo_fs=0;
1064 /*release all surfaces*/ 1192 /*release all surfaces*/
1065 if (g_lpddsBack != NULL) g_lpddsBack->lpVtbl->Release(g_lpddsBack); 1193 if (g_lpddsBack != NULL) g_lpddsBack->lpVtbl->Release(g_lpddsBack);
1066 g_lpddsBack = NULL; 1194 g_lpddsBack = NULL;
1067 if(vo_doublebuffering) 1195 if(vo_doublebuffering)
1068 { 1196 {
1070 } 1198 }
1071 g_lpddsOverlay = NULL; 1199 g_lpddsOverlay = NULL;
1072 if (g_lpddsPrimary != NULL) g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary); 1200 if (g_lpddsPrimary != NULL) g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);
1073 g_lpddsPrimary = NULL; 1201 g_lpddsPrimary = NULL;
1074 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>overlay surfaces released\n"); 1202 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>overlay surfaces released\n");
1075 /*set cooperativelevel*/ 1203
1076 if(vm) /*exclusive mode*/ 1204
1077 {
1078 vo_fs=1;
1079 if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN) != DD_OK)
1080 {
1081 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set cooperativelevel for exclusive mode");
1082 return 1;
1083 }
1084 SetWindowLong( hWnd, GWL_STYLE, 0 );
1085 /*SetDisplayMode(ddobject,width,height,bpp,refreshrate,aditionalflags)*/
1086 if(g_lpdd->lpVtbl->SetDisplayMode(g_lpdd,640, 480, 16,0,0) != DD_OK)
1087 {
1088 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set displaymode\n");
1089 return 1;
1090 }
1091 aspect_save_screenres(GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
1092 mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>using exclusive mode\n");
1093 }
1094 else
1095 {
1096 if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_NORMAL) != DD_OK)
1097 {
1098 mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set cooperativelevel for windowed mode");
1099 return 1;
1100 }
1101 mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>using normal cooperativelevel\n");
1102 }
1103 if(vo_fs)
1104 {
1105 /*remove the borders*/
1106 SetWindowLong( hWnd, GWL_STYLE, 0 );
1107 /*change backgroundcolor*/
1108 SetClassLongA(hWnd,GCL_HBRBACKGROUND,(int)CreateSolidBrush(RGB(0,0,0)));
1109 /*repaint*/
1110 RedrawWindow(hWnd,NULL,NULL,RDW_INVALIDATE|RDW_ERASE|RDW_INTERNALPAINT);
1111 /*hide mouse*/
1112 ShowCursor(FALSE);
1113 }
1114 /*create the surfaces*/ 1205 /*create the surfaces*/
1115 if(Directx_CreatePrimarySurface())return 1; 1206 if(Directx_CreatePrimarySurface())return 1;
1116 if (!nooverlay && Directx_CreateOverlay(image_format)) 1207 if (!nooverlay && Directx_CreateOverlay(image_format))
1117 { 1208 {
1118 if(format == primary_image_format)nooverlay=1; /*overlay creation failed*/ 1209 if(format == primary_image_format)nooverlay=1; /*overlay creation failed*/
1136 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;} 1227 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;}
1137 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;} 1228 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;}
1138 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;} 1229 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;}
1139 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>clipper succesfully created\n"); 1230 mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>clipper succesfully created\n");
1140 } 1231 }
1141 Directx_ManageDisplay(d_image_width,d_image_height); 1232 Directx_ManageDisplay();
1142 memset(&ddsdsf, 0,sizeof(DDSURFACEDESC)); 1233 memset(&ddsdsf, 0,sizeof(DDSURFACEDESC2));
1143 ddsdsf.dwSize = sizeof (DDSURFACEDESC); 1234 ddsdsf.dwSize = sizeof (DDSURFACEDESC2);
1144 g_lpddsBack->lpVtbl->Lock(g_lpddsBack,NULL,&ddsdsf, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL); 1235 g_lpddsBack->lpVtbl->Lock(g_lpddsBack,NULL,&ddsdsf, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL);
1145 dstride = ddsdsf.lPitch; 1236 dstride = ddsdsf.lPitch;
1146 image = ddsdsf.lpSurface; 1237 image = ddsdsf.lpSurface;
1147 return 0; 1238 return 0;
1148 } 1239 }
1156 case VOCTRL_QUERY_FORMAT: 1247 case VOCTRL_QUERY_FORMAT:
1157 return query_format(*((uint32_t*)data)); 1248 return query_format(*((uint32_t*)data));
1158 case VOCTRL_DRAW_IMAGE: 1249 case VOCTRL_DRAW_IMAGE:
1159 return put_image(data); 1250 return put_image(data);
1160 case VOCTRL_ONTOP: 1251 case VOCTRL_ONTOP:
1161 if(vm) 1252 if(vidmode)
1162 { 1253 {
1163 mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>ontop has no meaning in exclusive mode\n"); 1254 mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>ontop has no meaning in exclusive mode\n");
1164 } 1255 }
1165 else 1256 else
1166 { 1257 {
1167 if(vo_ontop) vo_ontop = 0; 1258 if(vo_ontop) vo_ontop = 0;
1168 else vo_ontop = 1; 1259 else vo_ontop = 1;
1169 Directx_ManageDisplay(0,0); 1260 Directx_ManageDisplay();
1170 } 1261 }
1171 return VO_TRUE; 1262 return VO_TRUE;
1172 case VOCTRL_FULLSCREEN: 1263 case VOCTRL_FULLSCREEN:
1173 { 1264 {
1174 if(vm) 1265 if(vidmode)
1175 { 1266 {
1176 mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>currently we do not allow to switch from exclusive to windowed mode\n"); 1267 mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>currently we do not allow to switch from exclusive to windowed mode\n");
1177 } 1268 }
1178 else 1269 else
1179 { 1270 {
1180 WINDOWPLACEMENT window_placement; 1271 if(!vo_fs){vo_fs=1;ShowWindow(hWndFS,SW_SHOW);}
1181 uint32_t width = 0; /*default: restore to the size it had before maximizing*/ 1272 else {vo_fs=0; ShowWindow(hWndFS,SW_HIDE);}
1182 uint32_t height = 0; 1273 Directx_ManageDisplay();
1183 window_placement.length = sizeof(WINDOWPLACEMENT); 1274 break;
1184 GetWindowPlacement(hWnd, &window_placement);
1185 if(vo_fs) /*go to windowed*/
1186 {
1187 vo_fs = 0;
1188 /*prevent the screen being filled with garbage*/
1189 window_placement.showCmd = SW_SHOWMINIMIZED;
1190 SetWindowPlacement(hWnd,&window_placement);
1191 /*change style and restore the window*/
1192 SetWindowLong(hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW|WS_SIZEBOX);
1193 window_placement.showCmd = SW_RESTORE;
1194 SetWindowPlacement(hWnd,&window_placement );
1195 /*restore backgroundcolor*/
1196 SetClassLongA(hWnd,GCL_HBRBACKGROUND,(int)CreateSolidBrush(windowcolor));
1197 /*never ever make a big window*/
1198 if(((window_placement.rcNormalPosition.bottom - window_placement.rcNormalPosition.top)==GetSystemMetrics(SM_CYSCREEN))
1199 &&((window_placement.rcNormalPosition.right - window_placement.rcNormalPosition.left)==GetSystemMetrics(SM_CXSCREEN)))
1200 {
1201 width = d_image_width;
1202 height = d_image_height;
1203 }
1204 /*show cursor again*/
1205 ShowCursor(TRUE);
1206 }
1207 else /*go to fullscreen*/
1208 {
1209 vo_fs = 1;
1210 /*remove decoration and maximize*/
1211 SetWindowLong(hWnd,GWL_STYLE,0);
1212 window_placement.showCmd = SW_SHOWMAXIMIZED;
1213 SetWindowPlacement(hWnd,&window_placement);
1214 /*make the window really black*/
1215 SetClassLongA(hWnd,GCL_HBRBACKGROUND,(int)CreateSolidBrush(RGB(0,0,0)));
1216 /*hide mouse cursor in fullscreen mode*/
1217 if(ShowCursor(FALSE)<0);
1218 else while(ShowCursor(FALSE)>=0)mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx>ShowCursor(FALSE)>=0\n");
1219 }
1220 RedrawWindow(hWnd,NULL,NULL,RDW_INVALIDATE|RDW_ERASE|RDW_INTERNALPAINT);
1221 Directx_ManageDisplay(width,height);
1222 } 1275 }
1223 return VO_TRUE; 1276 return VO_TRUE;
1224 } 1277 }
1225 }; 1278 };
1226 return VO_NOTIMPL; 1279 return VO_NOTIMPL;