1
mirror of https://github.com/mpv-player/mpv synced 2024-07-31 16:29:58 +02:00

adapter selection patch by Rune <runner at mail.tele.dk> +first attempt to implement 2 window fullscreenswitching by me

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@12006 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
faust3 2004-02-29 20:33:07 +00:00
parent e65a6fc09c
commit 70e246cc7f
2 changed files with 246 additions and 184 deletions

View File

@ -77,6 +77,11 @@ extern int osd_level;
extern char *ao_outputfilename; extern char *ao_outputfilename;
extern int ao_pcm_waveheader; extern int ao_pcm_waveheader;
#ifdef HAVE_DIRECTX
extern int adapter_num;
extern int refresh_rate;
#endif
#ifdef HAVE_X11 #ifdef HAVE_X11
extern char *mDisplayName; extern char *mDisplayName;
extern int WinID; extern int WinID;
@ -286,7 +291,11 @@ m_option_t mplayer_opts[]={
{"grabpointer", &vo_grabpointer, CONF_TYPE_FLAG, 0, 0, 1, NULL}, {"grabpointer", &vo_grabpointer, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{"nograbpointer", &vo_grabpointer, CONF_TYPE_FLAG, 0, 1, 0, NULL}, {"nograbpointer", &vo_grabpointer, CONF_TYPE_FLAG, 0, 1, 0, NULL},
#ifdef HAVE_DIRECTX
{"adapter", &adapter_num, CONF_TYPE_INT, CONF_RANGE, 0, 5, NULL},
{"refreshrate",&refresh_rate,CONF_TYPE_INT,CONF_RANGE, 0,100, NULL},
#endif
#ifdef HAVE_X11 #ifdef HAVE_X11
// x11,xv,xmga,xvidix // x11,xv,xmga,xvidix
{"wid", &WinID, CONF_TYPE_INT, 0, 0, 0, NULL}, {"wid", &WinID, CONF_TYPE_INT, 0, 0, 0, NULL},

View File

@ -21,6 +21,7 @@
#include <windows.h> #include <windows.h>
#include <windowsx.h> #include <windowsx.h>
#include <ddraw.h> #include <ddraw.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include "config.h" #include "config.h"
@ -33,26 +34,34 @@
#include "aspect.h" #include "aspect.h"
#include "geometry.h" #include "geometry.h"
static LPDIRECTDRAW2 g_lpdd = NULL; //DirectDraw Object static LPDIRECTDRAW7 g_lpdd = NULL; //DirectDraw Object
static LPDIRECTDRAWSURFACE g_lpddsPrimary = NULL; //Primary Surface: viewport through the Desktop static LPDIRECTDRAWSURFACE7 g_lpddsPrimary = NULL; //Primary Surface: viewport through the Desktop
static LPDIRECTDRAWSURFACE g_lpddsOverlay = NULL; //Overlay Surface static LPDIRECTDRAWSURFACE7 g_lpddsOverlay = NULL; //Overlay Surface
static LPDIRECTDRAWSURFACE g_lpddsBack = NULL; //Back surface static LPDIRECTDRAWSURFACE7 g_lpddsBack = NULL; //Back surface
static LPDIRECTDRAWCLIPPER g_lpddclipper; //clipper object, can only be used without overlay static LPDIRECTDRAWCLIPPER g_lpddclipper; //clipper object, can only be used without overlay
static DDSURFACEDESC ddsdsf; //surface descripiton needed for locking static DDSURFACEDESC2 ddsdsf; //surface descripiton needed for locking
static HINSTANCE hddraw_dll; //handle to ddraw.dll static HINSTANCE hddraw_dll; //handle to ddraw.dll
static RECT rd; //rect of our stretched image static RECT rd; //rect of our stretched image
static RECT rs; //rect of our source image static RECT rs; //rect of our source image
static HWND hWnd=NULL; //handle to the window static HWND hWnd=NULL; //handle to the window
static HWND hWndFS=NULL; //fullscreen window
static uint32_t image_width, image_height; //image width and height static uint32_t image_width, image_height; //image width and height
static uint32_t d_image_width, d_image_height; //image width and height zoomed static uint32_t d_image_width, d_image_height; //image width and height zoomed
static uint8_t *image=NULL; //image data static uint8_t *image=NULL; //image data
static uint32_t image_format=0; //image format static uint32_t image_format=0; //image format
static uint32_t primary_image_format; static uint32_t primary_image_format;
static uint32_t vm = 0; //exclusive mode, allows resolution switching (not implemented yet) static uint32_t vm_height=0;
static uint32_t vm_width=0;
static uint32_t vm_bpp=0;
static uint32_t dstride; //surface stride static uint32_t dstride; //surface stride
static uint32_t nooverlay = 0; //NonOverlay mode static uint32_t nooverlay = 0; //NonOverlay mode
static DWORD destcolorkey; //colorkey for our surface static DWORD destcolorkey; //colorkey for our surface
static COLORREF windowcolor = RGB(0,0,16); //windowcolor == colorkey static COLORREF windowcolor = RGB(0,0,16); //windowcolor == colorkey
int adapter_num=0;
int refresh_rate=0;
static int adapter_count=0;
static GUID selected_guid;
static GUID *selected_guid_ptr = NULL;
extern void mplayer_put_key(int code); //let mplayer handel the keyevents extern void mplayer_put_key(int code); //let mplayer handel the keyevents
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)); 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));
@ -60,15 +69,16 @@ extern int vo_doublebuffering; //tribblebuffering
extern int vo_fs; extern int vo_fs;
extern int vo_directrendering; extern int vo_directrendering;
extern int vo_ontop; extern int vo_ontop;
extern int vidmode;
/***************************************************************************** /*****************************************************************************
* DirectDraw GUIDs. * DirectDraw GUIDs.
* Defining them here allows us to get rid of the dxguid library during * Defining them here allows us to get rid of the dxguid library during
* the linking stage. * the linking stage.
*****************************************************************************/ *****************************************************************************/
static const GUID IID_IDirectDraw2 = static const GUID IID_IDirectDraw7 =
{ {
0xB3A6F3E0,0x2B43,0x11CF,{0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56} 0x15e65ec0,0x3b9c,0x11d2,{0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b}
}; };
typedef struct directx_fourcc_caps typedef struct directx_fourcc_caps
@ -164,11 +174,13 @@ query_format(uint32_t format)
static uint32_t Directx_CreatePrimarySurface() static uint32_t Directx_CreatePrimarySurface()
{ {
DDSURFACEDESC ddsd; DDSURFACEDESC2 ddsd;
//cleanup //cleanup
if(g_lpddsPrimary)g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary); if(g_lpddsPrimary)g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);
g_lpddsPrimary=NULL; g_lpddsPrimary=NULL;
ZeroMemory(&ddsd, sizeof(ddsd));
if(vidmode)g_lpdd->lpVtbl->SetDisplayMode(g_lpdd,vm_width,vm_height,vm_bpp,refresh_rate,0);
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd); ddsd.dwSize = sizeof(ddsd);
//set flags and create a primary surface. //set flags and create a primary surface.
ddsd.dwFlags = DDSD_CAPS; ddsd.dwFlags = DDSD_CAPS;
@ -186,7 +198,7 @@ static uint32_t Directx_CreatePrimarySurface()
static uint32_t Directx_CreateOverlay(uint32_t imgfmt) static uint32_t Directx_CreateOverlay(uint32_t imgfmt)
{ {
HRESULT ddrval; HRESULT ddrval;
DDSURFACEDESC ddsdOverlay; DDSURFACEDESC2 ddsdOverlay;
uint32_t i=0; uint32_t i=0;
while ( i < NUM_FORMATS +1 && imgfmt != g_ddpf[i].img_format) while ( i < NUM_FORMATS +1 && imgfmt != g_ddpf[i].img_format)
{ {
@ -270,7 +282,7 @@ static uint32_t Directx_CreateOverlay(uint32_t imgfmt)
static uint32_t Directx_CreateBackpuffer() static uint32_t Directx_CreateBackpuffer()
{ {
DDSURFACEDESC ddsd; DDSURFACEDESC2 ddsd;
//cleanup //cleanup
if (g_lpddsBack)g_lpddsBack->lpVtbl->Release(g_lpddsBack); if (g_lpddsBack)g_lpddsBack->lpVtbl->Release(g_lpddsBack);
g_lpddsBack=NULL; g_lpddsBack=NULL;
@ -306,9 +318,13 @@ static void uninit(void)
if (g_lpddsPrimary != NULL) g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary); if (g_lpddsPrimary != NULL) g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);
g_lpddsPrimary = NULL; g_lpddsPrimary = NULL;
mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>primary released\n"); mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>primary released\n");
if(hWndFS)DestroyWindow(hWndFS);
if(hWnd != NULL)DestroyWindow(hWnd); if(hWnd != NULL)DestroyWindow(hWnd);
mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>window destroyed\n"); mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>window destroyed\n");
if (g_lpdd != NULL) g_lpdd->lpVtbl->Release(g_lpdd); if (g_lpdd != NULL){
if(vidmode)g_lpdd->lpVtbl->RestoreDisplayMode(g_lpdd);
g_lpdd->lpVtbl->Release(g_lpdd);
}
mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>directdrawobject released\n"); mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>directdrawobject released\n");
FreeLibrary( hddraw_dll); FreeLibrary( hddraw_dll);
hddraw_dll= NULL; hddraw_dll= NULL;
@ -316,10 +332,43 @@ static void uninit(void)
mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>uninited\n"); mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>uninited\n");
} }
static BOOL WINAPI EnumCallbackEx(GUID FAR *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, LPVOID lpContext, HMONITOR hm)
{
mp_msg(MSGT_VO, MSGL_INFO ,"<vo_directx> adapter %d: ", adapter_count);
if (!lpGUID)
{
mp_msg(MSGT_VO, MSGL_INFO ,"%s", "Primary Display Adapter");
}
else
{
mp_msg(MSGT_VO, MSGL_INFO ,"%s", lpDriverDescription);
}
if(adapter_count == adapter_num){
if (!lpGUID)
selected_guid_ptr = NULL;
else
{
selected_guid = *lpGUID;
selected_guid_ptr = &selected_guid;
}
mp_msg(MSGT_VO, MSGL_INFO ,"\t\t<--");
}
mp_msg(MSGT_VO, MSGL_INFO ,"\n");
adapter_count++;
return 1; // list all adapters
}
static uint32_t Directx_InitDirectDraw() static uint32_t Directx_InitDirectDraw()
{ {
HRESULT (WINAPI *OurDirectDrawCreate)(GUID *,LPDIRECTDRAW *,IUnknown *); HRESULT (WINAPI *OurDirectDrawCreateEx)(GUID *,LPVOID *, REFIID,IUnknown FAR *);
LPDIRECTDRAW lpDDraw; LPDIRECTDRAW lpDDraw;
DDSURFACEDESC2 ddsd;
LPDIRECTDRAWENUMERATEEX OurDirectDrawEnumerateEx;
mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>Initing DirectDraw\n" ); mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>Initing DirectDraw\n" );
//load direct draw DLL: based on videolans code //load direct draw DLL: based on videolans code
@ -329,35 +378,78 @@ static uint32_t Directx_InitDirectDraw()
mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed loading ddraw.dll\n" ); mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed loading ddraw.dll\n" );
return 1; return 1;
} }
OurDirectDrawCreate = (void *)GetProcAddress(hddraw_dll, "DirectDrawCreate");
if ( OurDirectDrawCreate == NULL ) if(adapter_num){ //display other than default
{ OurDirectDrawEnumerateEx = (LPDIRECTDRAWENUMERATEEX) GetProcAddress(hddraw_dll,"DirectDrawEnumerateExA");
FreeLibrary( hddraw_dll ); if (!OurDirectDrawEnumerateEx){
hddraw_dll = NULL; FreeLibrary( hddraw_dll );
mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed geting proc address\n"); hddraw_dll = NULL;
return 1; mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed geting proc address: DirectDrawEnumerateEx\n");
mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>no directx 7 or higher installed\n");
return 1;
}
// enumerate all display devices attached to the desktop
OurDirectDrawEnumerateEx(EnumCallbackEx, NULL, DDENUM_ATTACHEDSECONDARYDEVICES );
if(adapter_num >= adapter_count)
mp_msg(MSGT_VO, MSGL_ERR,"Selected adapter (%d) doesn't exist: Default Display Adapter selected\n",adapter_num);
} }
// initialize DirectDraw and create directx v1 object
if (OurDirectDrawCreate( NULL, &lpDDraw, NULL ) != DD_OK ) OurDirectDrawCreateEx = (void *)GetProcAddress(hddraw_dll, "DirectDrawCreateEx");
if ( OurDirectDrawCreateEx == NULL )
{
FreeLibrary( hddraw_dll );
hddraw_dll = NULL;
mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>failed geting proc address: DirectDrawCreateEx\n");
return 1;
}
// initialize DirectDraw and create directx v7 object
if (OurDirectDrawCreateEx(selected_guid_ptr, (VOID**)&g_lpdd, &IID_IDirectDraw7, NULL ) != DD_OK )
{ {
lpDDraw = NULL;
FreeLibrary( hddraw_dll ); FreeLibrary( hddraw_dll );
hddraw_dll = NULL; hddraw_dll = NULL;
mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't initialize ddraw\n"); mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't initialize ddraw\n");
return 1; return 1;
} }
// ask IDirectDraw for IDirectDraw2
if (lpDDraw->lpVtbl->QueryInterface(lpDDraw, &IID_IDirectDraw2, (void **)&g_lpdd) != DD_OK) //get current screen siz for selected monitor ...
{ ddsd.dwSize=sizeof(ddsd);
mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>no directx 2 installed\n"); ddsd.dwFlags=DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
return 1; g_lpdd->lpVtbl->GetDisplayMode(g_lpdd, &ddsd);
} if(vo_screenwidth && vo_screenheight)
//release our old interface and free ddraw.dll {
lpDDraw->lpVtbl->Release(lpDDraw); vm_height=vo_screenheight;
mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>lpDDraw released\n" ); vm_width=vo_screenwidth;
//set cooperativelevel: for our tests, no handle to a window is needed }
if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, NULL, DDSCL_NORMAL) != DD_OK) else
{ {
vm_height=ddsd.dwHeight;
vm_width=ddsd.dwWidth;
}
if(vo_dbpp)vm_bpp=vo_dbpp;
else vm_bpp=ddsd.ddpfPixelFormat.dwRGBBitCount;
if(vidmode){
if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, 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;
}
/*SetDisplayMode(ddobject,width,height,bpp,refreshrate,aditionalflags)*/
if(g_lpdd->lpVtbl->SetDisplayMode(g_lpdd,vm_width, vm_height, vm_bpp,0,0) != DD_OK)
{
mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set displaymode\n");
return 1;
}
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);
return 0;
}
if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_NORMAL) != DD_OK) // or DDSCL_SETFOCUSWINDOW
{
mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>could not set cooperativelevel for hardwarecheck\n"); mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>could not set cooperativelevel for hardwarecheck\n");
return 1; return 1;
} }
@ -375,7 +467,7 @@ static void check_events(void)
} }
} }
static uint32_t Directx_ManageDisplay(uint32_t width,uint32_t height) static uint32_t Directx_ManageDisplay()
{ {
RECT rd_window; RECT rd_window;
HRESULT ddrval; HRESULT ddrval;
@ -386,7 +478,13 @@ static uint32_t Directx_ManageDisplay(uint32_t width,uint32_t height)
uint32_t xscreen = GetSystemMetrics(SM_CXSCREEN); uint32_t xscreen = GetSystemMetrics(SM_CXSCREEN);
uint32_t yscreen = GetSystemMetrics(SM_CYSCREEN); uint32_t yscreen = GetSystemMetrics(SM_CYSCREEN);
POINT point_window; POINT point_window;
if(vo_fs) uint32_t width,height;
if(vidmode){
xscreen=vm_width;
yscreen=vm_height;
}
if(vo_fs || vidmode)
{ {
/*center and zoom image*/ /*center and zoom image*/
rd_window.top = 0; rd_window.top = 0;
@ -398,6 +496,7 @@ static uint32_t Directx_ManageDisplay(uint32_t width,uint32_t height)
rd.right = rd.left+width; rd.right = rd.left+width;
rd.top = (yscreen-height)/2; rd.top = (yscreen-height)/2;
rd.bottom = rd.top + height; rd.bottom = rd.top + height;
if(ShowCursor(FALSE)>=0)while(ShowCursor(FALSE)>=0){}
} }
else /*windowed*/ else /*windowed*/
{ {
@ -409,8 +508,8 @@ static uint32_t Directx_ManageDisplay(uint32_t width,uint32_t height)
return 0; return 0;
} }
/*width and height are zero therefore we have to get them from the window size*/ /*width and height are zero therefore we have to get them from the window size*/
if(!width)width = rd_window.right - rd_window.left; width=rd_window.right - rd_window.left;
if(!height)height = rd_window.bottom - rd_window.top; height=rd_window.bottom - rd_window.top;
point_window.x = 0; //overlayposition relative to the window point_window.x = 0; //overlayposition relative to the window
point_window.y = 0; point_window.y = 0;
ClientToScreen(hWnd,&point_window); ClientToScreen(hWnd,&point_window);
@ -418,9 +517,11 @@ static uint32_t Directx_ManageDisplay(uint32_t width,uint32_t height)
rd.top = point_window.y; rd.top = point_window.y;
rd.bottom = rd.top + height; rd.bottom = rd.top + height;
rd.right = rd.left + width; rd.right = rd.left + width;
rd_window = rd; rd_window = rd;
ShowCursor(TRUE);
} }
/*ok, let's workaround some overlay limitations*/ /*ok, let's workaround some overlay limitations*/
if(!nooverlay) if(!nooverlay)
{ {
@ -513,7 +614,7 @@ static uint32_t Directx_ManageDisplay(uint32_t width,uint32_t height)
/*create an overlay FX structure to specify a destination color key*/ /*create an overlay FX structure to specify a destination color key*/
ZeroMemory(&ovfx, sizeof(ovfx)); ZeroMemory(&ovfx, sizeof(ovfx));
ovfx.dwSize = sizeof(ovfx); ovfx.dwSize = sizeof(ovfx);
if(vo_fs) if(vo_fs||vidmode)
{ {
ovfx.dckDestColorkey.dwColorSpaceLowValue = 0; ovfx.dckDestColorkey.dwColorSpaceLowValue = 0;
ovfx.dckDestColorkey.dwColorSpaceHighValue = 0; ovfx.dckDestColorkey.dwColorSpaceHighValue = 0;
@ -529,20 +630,17 @@ static uint32_t Directx_ManageDisplay(uint32_t width,uint32_t height)
if(capsDrv.dwCKeyCaps & DDCKEYCAPS_DESTOVERLAY) dwUpdateFlags |= DDOVER_KEYDESTOVERRIDE; if(capsDrv.dwCKeyCaps & DDCKEYCAPS_DESTOVERLAY) dwUpdateFlags |= DDOVER_KEYDESTOVERRIDE;
else vo_ontop = 1; else vo_ontop = 1;
} }
/*calculate window rect with borders*/ else
if(!vo_fs)AdjustWindowRect(&rd_window,WS_OVERLAPPEDWINDOW|WS_SIZEBOX,0); {
g_lpddclipper->lpVtbl->SetHWnd(g_lpddclipper, 0,vo_fs?hWndFS: hWnd);
}
if(!vidmode && !vo_fs){
if(vo_ontop)SetWindowPos(hWnd,HWND_TOPMOST,0,0,0,0,SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER);
else SetWindowPos(hWnd,HWND_NOTOPMOST,0,0,0,0,SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER);
}
if((vo_fs) || (!vo_fs && vo_ontop))hWndafter=HWND_TOPMOST;
else hWndafter=HWND_NOTOPMOST;
/*display the window*/
SetWindowPos(hWnd,
hWndafter,
rd_window.left,
rd_window.top,
rd_window.right - rd_window.left,
rd_window.bottom - rd_window.top,
SWP_SHOWWINDOW|SWP_NOOWNERZORDER);
//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); //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);
//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); //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);
//printf("Source:x1:%i,x2:%i,y1:%i,y2:%i\n",rs.left,rs.right,rs.top,rs.bottom); //printf("Source:x1:%i,x2:%i,y1:%i,y2:%i\n",rs.left,rs.right,rs.top,rs.bottom);
@ -604,7 +702,7 @@ static uint32_t Directx_CheckOverlayPixelformats()
{ {
DDCAPS capsDrv; DDCAPS capsDrv;
HRESULT ddrval; HRESULT ddrval;
DDSURFACEDESC ddsdOverlay; DDSURFACEDESC2 ddsdOverlay;
uint32_t i; uint32_t i;
uint32_t formatcount = 0; uint32_t formatcount = 0;
//get driver caps to determine overlay support //get driver caps to determine overlay support
@ -666,7 +764,7 @@ static uint32_t Directx_CheckPrimaryPixelformat()
uint32_t i=0; uint32_t i=0;
uint32_t formatcount = 0; uint32_t formatcount = 0;
DDPIXELFORMAT ddpf; DDPIXELFORMAT ddpf;
DDSURFACEDESC ddsd; DDSURFACEDESC2 ddsd;
HDC hdc; HDC hdc;
HRESULT hres; HRESULT hres;
COLORREF rgbT=RGB(0,0,0); COLORREF rgbT=RGB(0,0,0);
@ -734,6 +832,12 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
{ {
switch (message) switch (message)
{ {
case WM_NCACTIVATE:
{
if(vidmode && adapter_count > 2) //only disable if more than one adapter.
return 0;
break;
}
case WM_DESTROY: case WM_DESTROY:
{ {
PostQuitMessage(0); PostQuitMessage(0);
@ -809,6 +913,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
return DefWindowProc(hWnd, message, wParam, lParam); return DefWindowProc(hWnd, message, wParam, lParam);
} }
static uint32_t preinit(const char *arg) static uint32_t preinit(const char *arg)
{ {
HINSTANCE hInstance = GetModuleHandle(NULL); HINSTANCE hInstance = GetModuleHandle(NULL);
@ -823,6 +928,32 @@ static uint32_t preinit(const char *arg)
nooverlay = 1; nooverlay = 1;
} }
} }
/*load icon from the main app*/
if(GetModuleFileName(NULL,exedir,MAX_PATH))
{
mplayericon = ExtractIcon( hInstance, exedir, 0 );
}
if(!mplayericon)mplayericon=LoadIcon(NULL,IDI_APPLICATION);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hIcon = mplayericon;
wc.hbrBackground = CreateSolidBrush(vidmode?RGB(0,0,0):windowcolor);
wc.lpszClassName = "Mplayer - Movieplayer for Linux";
wc.lpszMenuName = NULL;
RegisterClass(&wc);
hWnd = CreateWindowEx(vidmode?WS_EX_TOPMOST:0,
"MPlayer - Movieplayer for Linux","",(vidmode)?WS_POPUP:WS_OVERLAPPEDWINDOW| WS_SIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,NULL,NULL,hInstance,NULL);
wc.hbrBackground = CreateSolidBrush(RGB(0,0,0));
wc.lpszClassName = "MPlayer - Fullscreen";
RegisterClass(&wc);
hWndFS = CreateWindow("MPlayer - Fullscreen","MPlayer Fullscreen",WS_POPUP,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),hWnd,NULL,hInstance,NULL);
mp_msg(MSGT_VO, MSGL_DBG3 ,"<vo_directx><INFO>initial mplayer windows created\n");
if (Directx_InitDirectDraw()!= 0)return 1; //init DirectDraw if (Directx_InitDirectDraw()!= 0)return 1; //init DirectDraw
if (Directx_CheckPrimaryPixelformat()!=0)return 1; if (Directx_CheckPrimaryPixelformat()!=0)return 1;
if (!nooverlay && Directx_CheckOverlayPixelformats() == 0) //check for supported hardware if (!nooverlay && Directx_CheckOverlayPixelformats() == 0) //check for supported hardware
@ -835,36 +966,7 @@ static uint32_t preinit(const char *arg)
mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>using backpuffer\n"); mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>using backpuffer\n");
nooverlay = 1; nooverlay = 1;
} }
/*load icon from the main app*/ mp_msg(MSGT_VO, MSGL_DBG3 ,"<vo_directx><INFO>preinit succesfully finished\n");
if(GetModuleFileName(NULL,exedir,MAX_PATH))
{
mplayericon = ExtractIcon( hInstance, exedir, 0 );
}
if(!mplayericon)mplayericon=LoadIcon(NULL,IDI_APPLICATION);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hIcon = mplayericon;
wc.hbrBackground = CreateSolidBrush(windowcolor);
wc.lpszClassName = "Mplayer - Movieplayer for Linux";
wc.lpszMenuName = NULL;
RegisterClass(&wc);
hWnd = CreateWindow("MPlayer - Movieplayer for Linux",
"",
WS_OVERLAPPEDWINDOW| WS_SIZEBOX,
CW_USEDEFAULT, //position x
CW_USEDEFAULT, //position y
100, //width
100, //height
NULL,
NULL,
hInstance,
NULL);
mp_msg(MSGT_VO, MSGL_DBG3 ,"<vo_directx><INFO>initial mplayer window created\n");
mp_msg(MSGT_VO, MSGL_DBG3 ,"<vo_directx><INFO>preinit succesfully finished\n");
return 0; return 0;
} }
@ -1043,10 +1145,10 @@ static uint32_t put_image(mp_image_t *mpi){
static uint32_t static uint32_t
config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t options, char *title, uint32_t format) config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t options, char *title, uint32_t format)
{ {
int wx=-1; vo_screenwidth = GetSystemMetrics(SM_CXSCREEN);
int wy=-1; vo_screenheight = GetSystemMetrics(SM_CYSCREEN);
vo_fs = options & 0x01; vo_fs = options & 0x01;
vm = options & 0x02; RECT rd;
image_format = format; image_format = format;
image_width = width; image_width = width;
image_height = height; image_height = height;
@ -1055,12 +1157,38 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin
nooverlay = 0; nooverlay = 0;
aspect_save_orig(image_width,image_height); aspect_save_orig(image_width,image_height);
aspect_save_prescale(d_image_width,d_image_height); aspect_save_prescale(d_image_width,d_image_height);
aspect_save_screenres(GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN)); if(vidmode){
geometry(&wx, &wy, &d_image_width, &d_image_height,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN)); vo_screenwidth=vm_width;
aspect(&d_image_width,&d_image_height,A_NOZOOM); vo_screenheight=vm_height;
if(wx !=-1)SetWindowPos(hWnd,NULL, wx, wy,d_image_width,d_image_height,SWP_SHOWWINDOW|SWP_NOOWNERZORDER); }
SetWindowText(hWnd,title); aspect_save_screenres(vo_screenwidth,vo_screenheight);
aspect(&d_image_width, &d_image_height, A_NOZOOM);
vo_dx = 0;
vo_dy = 0;
if(!vidmode){
if(vo_geometry){
vo_dx= ( vo_screenwidth - d_image_width ) / 2; vo_dy=( vo_screenheight - d_image_height ) / 2;
geometry(&vo_dx, &vo_dy, &d_image_width, &d_image_height, vo_screenwidth, vo_screenheight);
}
else {
GetWindowRect(hWnd,&rd);
vo_dx=rd.left;
vo_dy=rd.top;
}
rd.left = vo_dx;
rd.top = vo_dy;
rd.right = rd.left + d_image_width;
rd.bottom = rd.top + d_image_height;
AdjustWindowRect(&rd,WS_OVERLAPPEDWINDOW| WS_SIZEBOX,0);
SetWindowPos(hWnd,NULL, rd.left, rd.top,rd.right-rd.left,rd.bottom-rd.top,SWP_SHOWWINDOW|SWP_NOOWNERZORDER);
}
else ShowWindow(hWnd,SW_SHOW);
if(vo_fs && !vidmode)ShowWindow(hWndFS,SW_SHOW);
SetWindowText(hWnd,title);
if(vidmode)vo_fs=0;
/*release all surfaces*/ /*release all surfaces*/
if (g_lpddsBack != NULL) g_lpddsBack->lpVtbl->Release(g_lpddsBack); if (g_lpddsBack != NULL) g_lpddsBack->lpVtbl->Release(g_lpddsBack);
g_lpddsBack = NULL; g_lpddsBack = NULL;
@ -1072,45 +1200,8 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin
if (g_lpddsPrimary != NULL) g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary); if (g_lpddsPrimary != NULL) g_lpddsPrimary->lpVtbl->Release(g_lpddsPrimary);
g_lpddsPrimary = NULL; g_lpddsPrimary = NULL;
mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>overlay surfaces released\n"); mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>overlay surfaces released\n");
/*set cooperativelevel*/
if(vm) /*exclusive mode*/
{
vo_fs=1;
if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN) != DD_OK)
{
mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set cooperativelevel for exclusive mode");
return 1;
}
SetWindowLong( hWnd, GWL_STYLE, 0 );
/*SetDisplayMode(ddobject,width,height,bpp,refreshrate,aditionalflags)*/
if(g_lpdd->lpVtbl->SetDisplayMode(g_lpdd,640, 480, 16,0,0) != DD_OK)
{
mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set displaymode\n");
return 1;
}
aspect_save_screenres(GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));
mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>using exclusive mode\n");
}
else
{
if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_NORMAL) != DD_OK)
{
mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set cooperativelevel for windowed mode");
return 1;
}
mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>using normal cooperativelevel\n");
}
if(vo_fs)
{
/*remove the borders*/
SetWindowLong( hWnd, GWL_STYLE, 0 );
/*change backgroundcolor*/
SetClassLongA(hWnd,GCL_HBRBACKGROUND,(int)CreateSolidBrush(RGB(0,0,0)));
/*repaint*/
RedrawWindow(hWnd,NULL,NULL,RDW_INVALIDATE|RDW_ERASE|RDW_INTERNALPAINT);
/*hide mouse*/
ShowCursor(FALSE);
}
/*create the surfaces*/ /*create the surfaces*/
if(Directx_CreatePrimarySurface())return 1; if(Directx_CreatePrimarySurface())return 1;
if (!nooverlay && Directx_CreateOverlay(image_format)) if (!nooverlay && Directx_CreateOverlay(image_format))
@ -1138,9 +1229,9 @@ config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uin
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;} 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"); mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>clipper succesfully created\n");
} }
Directx_ManageDisplay(d_image_width,d_image_height); Directx_ManageDisplay();
memset(&ddsdsf, 0,sizeof(DDSURFACEDESC)); memset(&ddsdsf, 0,sizeof(DDSURFACEDESC2));
ddsdsf.dwSize = sizeof (DDSURFACEDESC); ddsdsf.dwSize = sizeof (DDSURFACEDESC2);
g_lpddsBack->lpVtbl->Lock(g_lpddsBack,NULL,&ddsdsf, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL); g_lpddsBack->lpVtbl->Lock(g_lpddsBack,NULL,&ddsdsf, DDLOCK_NOSYSLOCK | DDLOCK_WAIT, NULL);
dstride = ddsdsf.lPitch; dstride = ddsdsf.lPitch;
image = ddsdsf.lpSurface; image = ddsdsf.lpSurface;
@ -1158,7 +1249,7 @@ static uint32_t control(uint32_t request, void *data, ...)
case VOCTRL_DRAW_IMAGE: case VOCTRL_DRAW_IMAGE:
return put_image(data); return put_image(data);
case VOCTRL_ONTOP: case VOCTRL_ONTOP:
if(vm) if(vidmode)
{ {
mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>ontop has no meaning in exclusive mode\n"); mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>ontop has no meaning in exclusive mode\n");
} }
@ -1166,59 +1257,21 @@ static uint32_t control(uint32_t request, void *data, ...)
{ {
if(vo_ontop) vo_ontop = 0; if(vo_ontop) vo_ontop = 0;
else vo_ontop = 1; else vo_ontop = 1;
Directx_ManageDisplay(0,0); Directx_ManageDisplay();
} }
return VO_TRUE; return VO_TRUE;
case VOCTRL_FULLSCREEN: case VOCTRL_FULLSCREEN:
{ {
if(vm) if(vidmode)
{ {
mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>currently we do not allow to switch from exclusive to windowed mode\n"); mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>currently we do not allow to switch from exclusive to windowed mode\n");
} }
else else
{ {
WINDOWPLACEMENT window_placement; if(!vo_fs){vo_fs=1;ShowWindow(hWndFS,SW_SHOW);}
uint32_t width = 0; /*default: restore to the size it had before maximizing*/ else {vo_fs=0; ShowWindow(hWndFS,SW_HIDE);}
uint32_t height = 0; Directx_ManageDisplay();
window_placement.length = sizeof(WINDOWPLACEMENT); break;
GetWindowPlacement(hWnd, &window_placement);
if(vo_fs) /*go to windowed*/
{
vo_fs = 0;
/*prevent the screen being filled with garbage*/
window_placement.showCmd = SW_SHOWMINIMIZED;
SetWindowPlacement(hWnd,&window_placement);
/*change style and restore the window*/
SetWindowLong(hWnd,GWL_STYLE,WS_OVERLAPPEDWINDOW|WS_SIZEBOX);
window_placement.showCmd = SW_RESTORE;
SetWindowPlacement(hWnd,&window_placement );
/*restore backgroundcolor*/
SetClassLongA(hWnd,GCL_HBRBACKGROUND,(int)CreateSolidBrush(windowcolor));
/*never ever make a big window*/
if(((window_placement.rcNormalPosition.bottom - window_placement.rcNormalPosition.top)==GetSystemMetrics(SM_CYSCREEN))
&&((window_placement.rcNormalPosition.right - window_placement.rcNormalPosition.left)==GetSystemMetrics(SM_CXSCREEN)))
{
width = d_image_width;
height = d_image_height;
}
/*show cursor again*/
ShowCursor(TRUE);
}
else /*go to fullscreen*/
{
vo_fs = 1;
/*remove decoration and maximize*/
SetWindowLong(hWnd,GWL_STYLE,0);
window_placement.showCmd = SW_SHOWMAXIMIZED;
SetWindowPlacement(hWnd,&window_placement);
/*make the window really black*/
SetClassLongA(hWnd,GCL_HBRBACKGROUND,(int)CreateSolidBrush(RGB(0,0,0)));
/*hide mouse cursor in fullscreen mode*/
if(ShowCursor(FALSE)<0);
else while(ShowCursor(FALSE)>=0)mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx>ShowCursor(FALSE)>=0\n");
}
RedrawWindow(hWnd,NULL,NULL,RDW_INVALIDATE|RDW_ERASE|RDW_INTERNALPAINT);
Directx_ManageDisplay(width,height);
} }
return VO_TRUE; return VO_TRUE;
} }