changeset 18116:d75953576ae4

Fix and improve xinerama support
author reimar
date Sun, 16 Apr 2006 13:38:28 +0000
parents 5e0bafa6f7e8
children 0b13bab3f237
files DOCS/man/en/mplayer.1 cfg-mplayer.h libvo/video_out.c libvo/video_out.h libvo/vo_gl.c libvo/vo_gl2.c libvo/vo_x11.c libvo/vo_xmga.c libvo/vo_xover.c libvo/vo_xv.c libvo/vo_xvidix.c libvo/vo_xvmc.c libvo/w32_common.c libvo/x11_common.c libvo/x11_common.h
diffstat 15 files changed, 121 insertions(+), 103 deletions(-) [+]
line wrap: on
line diff
--- a/DOCS/man/en/mplayer.1	Sun Apr 16 13:25:14 2006 +0000
+++ b/DOCS/man/en/mplayer.1	Sun Apr 16 13:38:28 2006 +0000
@@ -2601,9 +2601,14 @@
 Useful to embed MPlayer in a browser (e.g.\& the plugger extension).
 .
 .TP
-.B \-xineramascreen <0\-...>
+.B \-xineramascreen <\-2\-...> (X11 only)
 In Xinerama configurations (i.e.\& a single desktop that spans across multiple
 displays) this option tells MPlayer which screen to display the movie on.
+A value of \-2 means fullscreen across the whole virtual display, \-1 means
+fullscreen on the display the window currently is on.
+The initial position set via the -geometry option is relative to the
+specified screen.
+Will usually only work with "\-fstype \-fullscreen" or "\-fstype none".
 .
 .TP
 .B \-zrbw (\-vo zr only)
--- a/cfg-mplayer.h	Sun Apr 16 13:25:14 2006 +0000
+++ b/cfg-mplayer.h	Sun Apr 16 13:38:28 2006 +0000
@@ -264,9 +264,7 @@
 	{"nomouseinput", &vo_nomouse_input, CONF_TYPE_FLAG,0,0,-1,NULL},
 #endif
 
-#ifdef HAVE_XINERAMA
-	{"xineramascreen", &xinerama_screen, CONF_TYPE_INT, CONF_RANGE, 0, 32, NULL},
-#endif
+	{"xineramascreen", &xinerama_screen, CONF_TYPE_INT, CONF_RANGE, -2, 32, NULL},
 
 	{"brightness",&vo_gamma_brightness, CONF_TYPE_INT, CONF_RANGE, -100, 100, NULL},
 	{"saturation",&vo_gamma_saturation, CONF_TYPE_INT, CONF_RANGE, -100, 100, NULL},
--- a/libvo/video_out.c	Sun Apr 16 13:25:14 2006 +0000
+++ b/libvo/video_out.c	Sun Apr 16 13:38:28 2006 +0000
@@ -19,6 +19,10 @@
 
 //int vo_flags=0;
 
+int xinerama_screen = -1;
+int xinerama_x;
+int xinerama_y;
+
 // currect resolution/bpp on screen:  (should be autodetected by vo_init())
 int vo_depthonscreen=0;
 int vo_screenwidth=0;
--- a/libvo/video_out.h	Sun Apr 16 13:25:14 2006 +0000
+++ b/libvo/video_out.h	Sun Apr 16 13:38:28 2006 +0000
@@ -179,6 +179,10 @@
 
 extern int vo_config_count;
 
+extern int xinerama_screen;
+extern int xinerama_x;
+extern int xinerama_y;
+
 // correct resolution/bpp on screen:  (should be autodetected by vo_init())
 extern int vo_depthonscreen;
 extern int vo_screenwidth;
--- a/libvo/vo_gl.c	Sun Apr 16 13:25:14 2006 +0000
+++ b/libvo/vo_gl.c	Sun Apr 16 13:38:28 2006 +0000
@@ -310,13 +310,15 @@
 	panscan_init();
 	aspect_save_orig(width,height);
 	aspect_save_prescale(d_width,d_height);
-	aspect_save_screenres(vo_screenwidth,vo_screenheight);
+	update_xinerama_info();
 
 	aspect(&d_width,&d_height,A_NOZOOM);
 	vo_dx = (int)(vo_screenwidth - d_width) / 2;
 	vo_dy = (int)(vo_screenheight - d_height) / 2;
 	geometry(&vo_dx, &vo_dy, &d_width, &d_height,
 	          vo_screenwidth, vo_screenheight);
+	vo_dx += xinerama_x;
+	vo_dy += xinerama_y;
 #ifdef HAVE_NEW_GUI
   if (use_gui) {
     // GUI creates and manages window for us
@@ -378,9 +380,6 @@
 	  XSetStandardProperties(mDisplay, vo_window, title, title, None, NULL, 0, &hint);
 	  /* Map window. */
 	  XMapWindow(mDisplay, vo_window);
-#ifdef HAVE_XINERAMA
-	  vo_x11_xinerama_move(mDisplay,vo_window);
-#endif
 
 	  /* Wait for map. */
 	  do 
--- a/libvo/vo_gl2.c	Sun Apr 16 13:25:14 2006 +0000
+++ b/libvo/vo_gl2.c	Sun Apr 16 13:38:28 2006 +0000
@@ -706,9 +706,6 @@
 
 	/* Map window. */
 	XMapWindow(mDisplay, vo_window);
-#ifdef HAVE_XINERAMA
-	vo_x11_xinerama_move(mDisplay,vo_window);
-#endif
 	vo_x11_sizehint( hint.x, hint.y, hint.width, hint.height,0 );
         XClearWindow(mDisplay,vo_window);
 
@@ -810,13 +807,15 @@
 	panscan_init();
 	aspect_save_orig(width,height);
 	aspect_save_prescale(d_width,d_height);
-	aspect_save_screenres(vo_screenwidth,vo_screenheight);
+	update_xinerama_info();
 
 	aspect(&d_width,&d_height,A_NOZOOM);
 	vo_dx = (int)(vo_screenwidth - d_width) / 2;
 	vo_dy = (int)(vo_screenheight - d_height) / 2;
 	geometry(&vo_dx, &vo_dy, &d_width, &d_height,
 	          vo_screenwidth, vo_screenheight);
+	vo_dx += xinerama_x;
+	vo_dy += xinerama_y;
 
 #if defined(HAVE_NEW_GUI) && !defined(GL_WIN32)
 	if (use_gui) {
--- a/libvo/vo_x11.c	Sun Apr 16 13:25:14 2006 +0000
+++ b/libvo/vo_x11.c	Sun Apr 16 13:38:28 2006 +0000
@@ -286,10 +286,13 @@
     in_format = format;
     srcW = width;
     srcH = height;
+    update_xinerama_info();
     vo_dx = (vo_screenwidth - d_width) / 2;
     vo_dy = (vo_screenheight - d_height) / 2;
     geometry(&vo_dx, &vo_dy, &d_width, &d_height, vo_screenwidth,
              vo_screenheight);
+    vo_dx += xinerama_x;
+    vo_dy += xinerama_y;
     vo_dwidth = d_width;
     vo_dheight = d_height;
 
@@ -422,9 +425,6 @@
 
                 if (fullscreen)
                     vo_x11_fullscreen();
-#ifdef HAVE_XINERAMA
-                vo_x11_xinerama_move(mDisplay, vo_window);
-#endif
             } else if (!fullscreen)
                 XMoveResizeWindow(mDisplay, vo_window, vo_dx, vo_dy,
                                   vo_dwidth, vo_dheight);
--- a/libvo/vo_xmga.c	Sun Apr 16 13:25:14 2006 +0000
+++ b/libvo/vo_xmga.c	Sun Apr 16 13:38:28 2006 +0000
@@ -127,7 +127,7 @@
 
     aspect_save_orig(width, height);
     aspect_save_prescale(d_width, d_height);
-    aspect_save_screenres(vo_screenwidth, vo_screenheight);
+    update_xinerama_info();
 
     mvWidth = width;
     mvHeight = height;
@@ -138,6 +138,8 @@
     vo_dy = (vo_screenheight - d_height) / 2;
     geometry(&vo_dx, &vo_dy, &d_width, &d_height, vo_screenwidth,
              vo_screenheight);
+    vo_dx += xinerama_x;
+    vo_dy += xinerama_y;
     vo_dwidth = d_width;
     vo_dheight = d_height;
     vo_mouse_autohide = 1;
@@ -241,9 +243,6 @@
                 if (flags & VOFLAG_FULLSCREEN)
                     vo_x11_fullscreen();
 
-#ifdef HAVE_XINERAMA
-                vo_x11_xinerama_move(mDisplay, vo_window);
-#endif
             } else if (!(flags & VOFLAG_FULLSCREEN))
                 XMoveResizeWindow(mDisplay, vo_window, vo_dx, vo_dy,
                                   vo_dwidth, vo_dheight);
--- a/libvo/vo_xover.c	Sun Apr 16 13:25:14 2006 +0000
+++ b/libvo/vo_xover.c	Sun Apr 16 13:38:28 2006 +0000
@@ -228,10 +228,8 @@
 
   aspect_save_orig(width, height);
   aspect_save_prescale(d_width, d_height);
-  aspect_save_screenres(vo_screenwidth, vo_screenheight);
+  update_xinerama_info();
 
-  vo_dx = 0;
-  vo_dy = 0;
   window_width = d_width;
   window_height = d_height;
 
@@ -261,6 +259,8 @@
   aspect(&d_width, &d_height, A_NOZOOM);
 
   vo_dx=( vo_screenwidth - d_width ) / 2; vo_dy=( vo_screenheight - d_height ) / 2;    
+  vo_dx += xinerama_x;
+  vo_dy += xinerama_y;
   vo_dwidth=d_width; vo_dheight=d_height;
 
 #ifdef HAVE_NEW_GUI
@@ -320,9 +320,6 @@
     
 	      if ( flags&VOFLAG_FULLSCREEN ) vo_x11_fullscreen();
     
-#ifdef HAVE_XINERAMA
-	      vo_x11_xinerama_move(mDisplay, vo_window);
-#endif
 	    } else if ( !(flags&VOFLAG_FULLSCREEN) ) XMoveResizeWindow( mDisplay,vo_window,vo_dx,vo_dy,vo_dwidth,vo_dheight );
 	}
 	 
--- a/libvo/vo_xv.c	Sun Apr 16 13:25:14 2006 +0000
+++ b/libvo/vo_xv.c	Sun Apr 16 13:38:28 2006 +0000
@@ -190,10 +190,13 @@
     int_pause = 0;
     visible_buf = -1;
 
+    update_xinerama_info();
     vo_dx = (vo_screenwidth - d_width) / 2;
     vo_dy = (vo_screenheight - d_height) / 2;
     geometry(&vo_dx, &vo_dy, &d_width, &d_height, vo_screenwidth,
              vo_screenheight);
+    vo_dx += xinerama_x;
+    vo_dy += xinerama_y;
     vo_dwidth = d_width;
     vo_dheight = d_height;
 
@@ -222,7 +225,6 @@
         if (!xv_format)
             return -1;
     }
-    aspect_save_screenres(vo_screenwidth, vo_screenheight);
 
 #ifdef HAVE_NEW_GUI
     if (use_gui)
@@ -348,12 +350,6 @@
             XMapWindow(mDisplay, vo_window);
             if (flags & VOFLAG_FULLSCREEN)
                 vo_x11_fullscreen();
-            else
-            {
-#ifdef HAVE_XINERAMA
-                vo_x11_xinerama_move(mDisplay, vo_window);
-#endif
-            }
         } else
         {
             // vo_fs set means we were already at fullscreen
--- a/libvo/vo_xvidix.c	Sun Apr 16 13:25:14 2006 +0000
+++ b/libvo/vo_xvidix.c	Sun Apr 16 13:38:28 2006 +0000
@@ -371,9 +371,6 @@
                 if (flags & VOFLAG_FULLSCREEN)
                     vo_x11_fullscreen();
 
-#ifdef HAVE_XINERAMA
-                vo_x11_xinerama_move(mDisplay, vo_window);
-#endif
             } else if (!(flags & VOFLAG_FULLSCREEN))
                 XMoveResizeWindow(mDisplay, vo_window, vo_dx, vo_dy,
                                   vo_dwidth, vo_dheight);
--- a/libvo/vo_xvmc.c	Sun Apr 16 13:25:14 2006 +0000
+++ b/libvo/vo_xvmc.c	Sun Apr 16 13:38:28 2006 +0000
@@ -604,16 +604,17 @@
 
    vo_mouse_autohide = 1;
 
+   update_xinerama_info();
    vo_dx=( vo_screenwidth - d_width ) / 2; vo_dy=( vo_screenheight - d_height ) / 2;
    geometry(&vo_dx, &vo_dy, &d_width, &d_height, vo_screenwidth, vo_screenheight);
+   vo_dx += xinerama_x;
+   vo_dy += xinerama_y;
    vo_dwidth=d_width; vo_dheight=d_height;
 
 #ifdef HAVE_XF86VM
    if( flags&VOFLAG_MODESWITCHING ) vm = 1;
 #endif
 
-   aspect_save_screenres(vo_screenwidth,vo_screenheight);
-
 #ifdef HAVE_NEW_GUI
    if(use_gui)
       guiGetEvent( guiSetShVideo,0 ); // let the GUI to setup/resize our window
@@ -702,9 +703,6 @@
 	 XMapWindow(mDisplay, vo_window);
 	 if ( flags&VOFLAG_FULLSCREEN ) vo_x11_fullscreen();
 	 else {
-#ifdef HAVE_XINERAMA
-	    vo_x11_xinerama_move(mDisplay,vo_window);
-#endif
 	    vo_x11_sizehint( hint.x, hint.y, hint.width, hint.height,0 );
 	 }
       } else {
--- a/libvo/w32_common.c	Sun Apr 16 13:25:14 2006 +0000
+++ b/libvo/w32_common.c	Sun Apr 16 13:38:28 2006 +0000
@@ -25,10 +25,6 @@
 int prev_x;
 int prev_y;
 
-// top left coordinates of current monitor
-int vo_screenx;
-int vo_screeny;
-
 uint32_t o_dwidth;
 uint32_t o_dheight;
 
@@ -36,9 +32,11 @@
 HWND vo_window = 0;
 static int cursor = 1;
 static int event_flags;
+static int mon_cnt;
 
 static HMONITOR (WINAPI* myMonitorFromWindow)(HWND, DWORD);
 static BOOL (WINAPI* myGetMonitorInfo)(HMONITOR, LPMONITORINFO);
+static BOOL (WINAPI* myEnumDisplayMonitors)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
 
 static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
     RECT r;
@@ -135,6 +133,44 @@
     return event_flags;
 }
 
+static BOOL CALLBACK mon_enum(HMONITOR hmon, HDC hdc, LPRECT r, LPARAM p) {
+    // this defaults to the last screen if specified number does not exist
+    xinerama_x = r->left;
+    xinerama_y = r->top;
+    vo_screenwidth = r->right - r->left;
+    vo_screenheight = r->bottom - r->top;
+    if (mon_cnt == xinerama_screen)
+        return FALSE;
+    mon_cnt++;
+    return TRUE;
+}
+
+void update_xinerama_info(void) {
+    xinerama_x = xinerama_y = 0;
+    if (xinerama_screen < -1) {
+        int tmp;
+        xinerama_x = GetSystemMetrics(SM_XVIRTUALSCREEN);
+        xinerama_y = GetSystemMetrics(SM_YVIRTUALSCREEN);
+        tmp = GetSystemMetrics(SM_CXVIRTUALSCREEN);
+        if (tmp) vo_screenwidth = tmp;
+        tmp = GetSystemMetrics(SM_CYVIRTUALSCREEN);
+        if (tmp) vo_screenheight = tmp;
+    } else if (xinerama_screen == -1 && myMonitorFromWindow && myGetMonitorInfo) {
+        MONITORINFO mi;
+        HMONITOR m = myMonitorFromWindow(vo_window, MONITOR_DEFAULTTOPRIMARY);
+        mi.cbSize = sizeof(mi);
+        myGetMonitorInfo(m, &mi);
+        xinerama_x = mi.rcMonitor.left;
+        xinerama_y = mi.rcMonitor.top;
+        vo_screenwidth = mi.rcMonitor.right - mi.rcMonitor.left;
+        vo_screenheight = mi.rcMonitor.bottom - mi.rcMonitor.top;
+    } else if (xinerama_screen > 0 && myEnumDisplayMonitors) {
+        mon_cnt = 0;
+        myEnumDisplayMonitors(NULL, NULL, mon_enum, 0);
+    }
+    aspect_save_screenres(vo_screenwidth, vo_screenheight);
+}
+
 static void updateScreenProperties() {
     DEVMODE dm;
     dm.dmSize = sizeof dm;
@@ -148,18 +184,7 @@
     vo_screenwidth = dm.dmPelsWidth;
     vo_screenheight = dm.dmPelsHeight;
     vo_depthonscreen = dm.dmBitsPerPel;
-    vo_screenx = vo_screeny = 0;
-    if (myMonitorFromWindow && myGetMonitorInfo) {
-        MONITORINFO mi;
-        HMONITOR m = myMonitorFromWindow(vo_window, MONITOR_DEFAULTTOPRIMARY);
-        mi.cbSize = sizeof(mi);
-        myGetMonitorInfo(m, &mi);
-        vo_screenx = mi.rcMonitor.left;
-        vo_screeny = mi.rcMonitor.top;
-        vo_screenwidth = mi.rcMonitor.right - mi.rcMonitor.left;
-        vo_screenheight = mi.rcMonitor.bottom - mi.rcMonitor.top;
-    }
-    aspect_save_screenres(vo_screenwidth, vo_screenheight);
+    update_xinerama_info();
 }
 
 static void changeMode(void) {
@@ -232,8 +257,8 @@
         prev_y = vo_dy;
         vo_dwidth = vo_screenwidth;
         vo_dheight = vo_screenheight;
-        vo_dx = vo_screenx;
-        vo_dy = vo_screeny;
+        vo_dx = xinerama_x;
+        vo_dy = xinerama_y;
     } else {
         vo_dwidth = prev_width;
         vo_dheight = prev_height;
@@ -322,10 +347,12 @@
 
     myMonitorFromWindow = NULL;
     myGetMonitorInfo = NULL;
+    myEnumDisplayMonitors = NULL;
     user32 = GetModuleHandle("user32.dll");
     if (user32) {
         myMonitorFromWindow = GetProcAddress(user32, "MonitorFromWindow");
         myGetMonitorInfo = GetProcAddress(user32, "GetMonitorInfoA");
+        myEnumDisplayMonitors = GetProcAddress(user32, "EnumDisplayMonitors");
     }
     updateScreenProperties();
 
--- a/libvo/x11_common.c	Sun Apr 16 13:25:14 2006 +0000
+++ b/libvo/x11_common.c	Sun Apr 16 13:38:28 2006 +0000
@@ -108,11 +108,6 @@
 static int vo_old_width = 0;
 static int vo_old_height = 0;
 
-#ifdef HAVE_XINERAMA
-int xinerama_screen = 0;
-int xinerama_x = 0;
-int xinerama_y = 0;
-#endif
 #ifdef HAVE_XF86VM
 XF86VidModeModeInfo **vidmodes = NULL;
 XF86VidModeModeLine modeline;
@@ -364,6 +359,43 @@
     XA_INIT(_BLACKBOX_PID);
 }
 
+void update_xinerama_info(void) {
+    int screen = xinerama_screen;
+    xinerama_x = xinerama_y = 0;
+#ifdef HAVE_XINERAMA
+    if (screen >= -1 && XineramaIsActive(mDisplay))
+    {
+        XineramaScreenInfo *screens;
+        int num_screens;
+
+        screens = XineramaQueryScreens(mDisplay, &num_screens);
+        if (screen >= num_screens)
+            screen = num_screens - 1;
+        if (screen == -1) {
+            int x = vo_dx + vo_dwidth / 2;
+            int y = vo_dy + vo_dheight / 2;
+            for (screen = num_screens - 1; screen > 0; screen--) {
+               int left = screens[screen].x_org;
+               int right = left + screens[screen].width;
+               int top = screens[screen].y_org;
+               int bottom = top + screens[screen].height;
+               if (left <= x && x <= right && top <= y && y <= bottom)
+                   break;
+            }
+        }
+        if (screen < 0)
+            screen = 0;
+        vo_screenwidth = screens[screen].width;
+        vo_screenheight = screens[screen].height;
+        xinerama_x = screens[screen].x_org;
+        xinerama_y = screens[screen].y_org;
+
+        XFree(screens);
+    }
+    aspect_save_screenres(vo_screenwidth, vo_screenheight);
+#endif
+}
+
 int vo_init(void)
 {
 // int       mScreen;
@@ -411,25 +443,6 @@
 
     init_atoms();
 
-#ifdef HAVE_XINERAMA
-    if (XineramaIsActive(mDisplay))
-    {
-        XineramaScreenInfo *screens;
-        int num_screens;
-
-        screens = XineramaQueryScreens(mDisplay, &num_screens);
-        if (xinerama_screen >= num_screens)
-            xinerama_screen = 0;
-        if (!vo_screenwidth)
-            vo_screenwidth = screens[xinerama_screen].width;
-        if (!vo_screenheight)
-            vo_screenheight = screens[xinerama_screen].height;
-        xinerama_x = screens[xinerama_screen].x_org;
-        xinerama_y = screens[xinerama_screen].y_org;
-
-        XFree(screens);
-    } else
-#endif
 #ifdef HAVE_XF86VM
     {
         int clock;
@@ -1447,8 +1460,9 @@
             vo_old_y = vo_dy;
             vo_old_width = vo_dwidth;
             vo_old_height = vo_dheight;
-            x = 0;
-            y = 0;
+            update_xinerama_info();
+            x = xinerama_x;
+            y = xinerama_y;
             w = vo_screenwidth;
             h = vo_screenheight;
         }
@@ -1482,10 +1496,6 @@
     if ((!(vo_fs)) & vo_ontop)
         vo_x11_setlayer(mDisplay, vo_window, vo_ontop);
 
-#ifdef HAVE_XINERAMA
-    vo_x11_xinerama_move(mDisplay, vo_window);
-#endif
-
     XMapRaised(mDisplay, vo_window);
     XRaiseWindow(mDisplay, vo_window);
     XFlush(mDisplay);
@@ -1778,17 +1788,6 @@
     }
 }
 
-#ifdef HAVE_XINERAMA
-void vo_x11_xinerama_move(Display * dsp, Window w)
-{
-    if (XineramaIsActive(dsp) && !geometry_xy_changed)
-    {
-        /* printf("XXXX Xinerama screen: x: %hd y: %hd\n",xinerama_x,xinerama_y); */
-        XMoveWindow(dsp, w, xinerama_x, xinerama_y);
-    }
-}
-#endif
-
 #ifdef HAVE_XF86VM
 void vo_vm_switch(uint32_t X, uint32_t Y, int *modeline_width,
                   int *modeline_height)
--- a/libvo/x11_common.h	Sun Apr 16 13:25:14 2006 +0000
+++ b/libvo/x11_common.h	Sun Apr 16 13:38:28 2006 +0000
@@ -114,10 +114,6 @@
 void saver_off( Display * );
 void saver_on( Display * );
 
-#ifdef HAVE_XINERAMA
-void vo_x11_xinerama_move(Display *dsp, Window w);
-#endif
-
 #ifdef HAVE_XF86VM
 void vo_vm_switch(uint32_t, uint32_t, int*, int*);
 void vo_vm_close(Display*);