changeset 12387:5c2e728f5a00

keepaspect support, tryed to clean up DirectxManageDisplay a bit, enabled UYVY support and fixed bugs where switching to fullscreen would keep the console window on top and where the initial window position is wrongly calculated
author faust3
date Sat, 01 May 2004 20:21:03 +0000
parents be1e7cfddc08
children ca026dc6b44d
files libvo/vo_directx.c
diffstat 1 files changed, 70 insertions(+), 106 deletions(-) [+]
line wrap: on
line diff
--- a/libvo/vo_directx.c	Sat May 01 20:16:54 2004 +0000
+++ b/libvo/vo_directx.c	Sat May 01 20:21:03 2004 +0000
@@ -61,6 +61,7 @@
 static int adapter_count=0;
 static GUID selected_guid;
 static GUID *selected_guid_ptr = NULL;
+static float window_aspect;
 
 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));
@@ -96,7 +97,7 @@
 	{"IYUV ",IMGFMT_IYUV ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('I','Y','U','V'),0,0,0,0,0}},   //same as i420
 	{"YVU9 ",IMGFMT_YVU9 ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('Y','V','U','9'),0,0,0,0,0}},	
 	{"YUY2 ",IMGFMT_YUY2 ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('Y','U','Y','2'),0,0,0,0,0}},
-//	{"UYVY ",IMGFMT_UYVY ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('U','Y','V','Y'),0,0,0,0,0}},
+	{"UYVY ",IMGFMT_UYVY ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('U','Y','V','Y'),0,0,0,0,0}},
 	{"RGB15",IMGFMT_RGB15,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x0000001F, 0x000003E0, 0x00007C00, 0}},   //RGB 5:5:5
 	{"BGR15",IMGFMT_BGR15,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x00007C00, 0x000003E0, 0x0000001F, 0}},   
 	{"RGB16",IMGFMT_RGB16,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x0000001F, 0x000007E0, 0x0000F800, 0}},   //RGB 5:6:5
@@ -470,58 +471,46 @@
 
 static uint32_t Directx_ManageDisplay()
 {   
-    RECT            rd_window;
     HRESULT         ddrval;
     DDCAPS          capsDrv;
     DDOVERLAYFX     ovfx;
     DWORD           dwUpdateFlags=0;
-    HWND            hWndafter;
-    uint32_t        xscreen = GetSystemMetrics(SM_CXSCREEN);
-    uint32_t        yscreen = GetSystemMetrics(SM_CYSCREEN);
-	POINT           point_window;
-    uint32_t width,height;
-	
-    if(vidmode){
-	  xscreen=vm_width;
-	  yscreen=vm_height;
-	} 
-	if(vo_fs || vidmode)
-	{
-		/*center and zoom image*/
-		rd_window.top = 0;
-	    rd_window.left = 0;
-	    rd_window.right = xscreen;
-	    rd_window.bottom = yscreen;
-	    aspect(&width,&height,A_ZOOM);
-	    rd.left = (xscreen-width)/2;
-		rd.right = rd.left+width;
-	    rd.top = (yscreen-height)/2;
-	    rd.bottom = rd.top + height;
-        if(ShowCursor(FALSE)>=0)while(ShowCursor(FALSE)>=0){}        
-	}
-	else /*windowed*/
-	{
-		GetClientRect (hWnd, &rd_window);
-        if((rd_window.top == rd_window.bottom)&&!nooverlay)   
-		{
-			/*window is minimized let's hide our overlay*/
-			ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,NULL, g_lpddsPrimary, NULL, DDOVER_HIDE, NULL); //hide the overlay
-	        return 0;
-		}
-		/*width and height are zero therefore we have to get them from the window size*/
-		width=rd_window.right - rd_window.left;
-		height=rd_window.bottom - rd_window.top;
-	    point_window.x = 0;  //overlayposition relative to the window
-        point_window.y = 0;
-        ClientToScreen(hWnd,&point_window);  
-		rd.left = point_window.x;
-        rd.top = point_window.y;
-		rd.bottom = rd.top + height;
-		rd.right = rd.left + width;
-        rd_window = rd;
-        ShowCursor(TRUE);          
-	}
-
+    int width,height;
+   
+    if(vo_fs || vidmode){
+      aspect(&width,&height,A_ZOOM);
+      rd.left=(vo_screenwidth-width)/2;
+      rd.top=(vo_screenheight-height)/2;
+      if(ShowCursor(FALSE)>=0)while(ShowCursor(FALSE)>=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;
+	  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;
+      }    
+      ShowCursor(TRUE); 
+    }
+    rd.right=rd.left+width;
+    rd.bottom=rd.top+height;
 
 	/*ok, let's workaround some overlay limitations*/
 	if(!nooverlay)
@@ -537,25 +526,25 @@
 		{
 			if(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKXN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only shrinkN\n");
 	        else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't shrink x\n");
-	        width=image_width;
+	        rd.right=rd.left+image_width;
 		}
 		else if((width > image_width)&& !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHX))
 		{
 			if(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHXN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only stretchN\n"); 
 	        else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't stretch x\n");
-	        width = image_width;
+	        rd.right = rd.left+image_width;
 		}
 		if((height < image_height) && !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKY))
 		{
 			if(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKYN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only shrinkN\n");
 	        else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't shrink y\n");
-	        height = image_height;
+	        rd.bottom = rd.top + image_height;
 		}
 		else if((height > image_height ) && !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHY))
 		{
 			if(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHYN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only stretchN\n");
 	        else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't stretch y\n");
-	        height = image_height;
+	        rd.bottom = rd.top + image_height;
 		}
 		/*get minimum stretch, depends on display adaptor and mode (refresh rate!) */
         uStretchFactor1000 = capsDrv.dwMinOverlayStretch>1000 ? capsDrv.dwMinOverlayStretch : 1000;
@@ -564,54 +553,25 @@
         /*calculate xstretch1000 and ystretch1000*/
         xstretch1000 = ((rd.right - rd.left)* 1000)/image_width ;
         ystretch1000 = ((rd.bottom - rd.top)* 1000)/image_height;
-        /*handle move outside of window with cropping
-		  not really needed with colorkey, but shouldn't hurt*/
 		rs.left=0;
 		rs.right=image_width;
 		rs.top=0;
 		rs.bottom=image_height;
-        if(!vo_fs)rd_window = rd;         /*don't crop the window !!!*/
-        if(rd.left < 0)         //move out left
-		{
-           rs.left=(-rd.left*1000)/xstretch1000;
-           rd.left = 0; 
-		}
-        else rs.left=0;
-        if(rd.top < 0)          //move out up
-		{
-	       rs.top=(-rd.top*1000)/ystretch1000;
-	       rd.top = 0;
-		}
-        else rs.top = 0;
-        if(rd.right > xscreen)  //move out right
-		{
-	       rs.right=((xscreen-rd.left)*1000)/xstretch1000;
-	       rd.right= xscreen;
-		}
-        else rs.right = image_width;
-        if(rd.bottom > yscreen) //move out down
-		{
-	       rs.bottom=((yscreen-rd.top)*1000)/ystretch1000;
-	       rd.bottom= yscreen;
-		}
-        else rs.bottom= image_height;
+        if(rd.left < 0)rs.left=(-rd.left*1000)/xstretch1000;
+        if(rd.top < 0)rs.top=(-rd.top*1000)/ystretch1000;
+        if(rd.right > vo_screenwidth)rs.right=((vo_screenwidth-rd.left)*1000)/xstretch1000;
+        if(rd.bottom > vo_screenheight)rs.bottom=((vo_screenheight-rd.top)*1000)/ystretch1000;
 		/*the last thing to check are alignment restrictions
           these expressions (x & -y) just do alignment by dropping low order bits...
           so to round up, we add first, then truncate*/
-		if ((capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYSRC) && capsDrv.dwAlignBoundarySrc)
-			rs.left = (rs.left + capsDrv.dwAlignBoundarySrc / 2) & -(signed)(capsDrv.dwAlignBoundarySrc);
-        if ((capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC) && capsDrv.dwAlignSizeSrc)
-			rs.right = rs.left + ((rs.right - rs.left + capsDrv.dwAlignSizeSrc / 2) & -(signed) (capsDrv.dwAlignSizeSrc));
-        if ((capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYDEST) && capsDrv.dwAlignBoundaryDest)
-		{
-			rd.left = (rd.left + capsDrv.dwAlignBoundaryDest / 2) & -(signed)(capsDrv.dwAlignBoundaryDest);
-	        if(!vo_fs)rd_window.left = (rd_window.left + capsDrv.dwAlignBoundaryDest / 2) & -(signed)(capsDrv.dwAlignBoundaryDest); //don't forget the window
-		}
-        if ((capsDrv.dwCaps & DDCAPS_ALIGNSIZEDEST) && capsDrv.dwAlignSizeDest)
-		{
-			rd.right = rd.left + ((rd.right - rd.left) & -(signed) (capsDrv.dwAlignSizeDest));
-	        if(!vo_fs)rd_window.right = rd_window.left + ((rd_window.right - rd_window.left) & -(signed) (capsDrv.dwAlignSizeDest)); //don't forget the window
-		}
+		if((capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYSRC) && capsDrv.dwAlignBoundarySrc)
+		  rs.left = (rs.left + capsDrv.dwAlignBoundarySrc / 2) & -(signed)(capsDrv.dwAlignBoundarySrc);
+        if((capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC) && capsDrv.dwAlignSizeSrc)
+		  rs.right = rs.left + ((rs.right - rs.left + capsDrv.dwAlignSizeSrc / 2) & -(signed) (capsDrv.dwAlignSizeSrc));
+        if((capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYDEST) && capsDrv.dwAlignBoundaryDest)
+		  rd.left = (rd.left + capsDrv.dwAlignBoundaryDest / 2) & -(signed)(capsDrv.dwAlignBoundaryDest);
+        if((capsDrv.dwCaps & DDCAPS_ALIGNSIZEDEST) && capsDrv.dwAlignSizeDest)
+		  rd.right = rd.left + ((rd.right - rd.left) & -(signed) (capsDrv.dwAlignSizeDest));
 		/*create an overlay FX structure to specify a destination color key*/
 		ZeroMemory(&ovfx, sizeof(ovfx));
         ovfx.dwSize = sizeof(ovfx);
@@ -637,20 +597,24 @@
     }       
 	
     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); 
+          RECT rdw=rd;
+          AdjustWindowRect(&rdw,WS_OVERLAPPEDWINDOW|WS_SIZEBOX,FALSE);
+//          printf("window: %i %i %ix%i\n",rdw.left,rdw.top,rdw.right - rdw.left,rdw.bottom - rdw.top);      
+          SetWindowPos(hWnd,(vo_ontop)?HWND_TOPMOST:HWND_NOTOPMOST,rdw.left,rdw.top,rdw.right-rdw.left,rdw.bottom-rdw.top,SWP_NOOWNERZORDER); 
     }
+    else SetWindowPos(hWndFS,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|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("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("Image:x:%i->%i,y:%i->%i\n",image_width,d_image_width,image_height,d_image_height);
+  	/*for nonoverlay mode we are finished, for overlay mode we have to display the overlay first*/
+	if(nooverlay)return 0;
+
+    /*make sure the overlay is inside the screen*/
+    if(rd.left<0)rd.left=0;
+    if(rd.right>vo_screenwidth)rd.right=vo_screenwidth;
+    if(rd.top<0)rd.top=0;
+    if(rd.bottom>vo_screenheight)rd.bottom=vo_screenheight;
+    
 	
-	
-	/*for nonoverlay mode we are finished, for overlay mode we have to display the overlay first*/
-	if(nooverlay)return 0;
-	
+//    printf("overlay: %i %i %ix%i\n",rd.left,rd.top,rd.right - rd.left,rd.bottom - rd.top);
 	ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,&rs, g_lpddsPrimary, &rd, dwUpdateFlags, &ovfx);
     if(FAILED(ddrval))
     {
@@ -1197,6 +1161,7 @@
     }	
 	aspect_save_screenres(vo_screenwidth,vo_screenheight);
     aspect(&d_image_width, &d_image_height, A_NOZOOM);
+    window_aspect= (float)d_image_width / (float)d_image_height;
     vo_dx = 0;
     vo_dy = 0;   
     if(!vidmode){
@@ -1213,7 +1178,6 @@
         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);