Add Xinerama support for GHOST_GetMainDisplayDimensions() so X11 works as it should...
authorCampbell Barton <ideasman42@gmail.com>
Thu, 31 Jan 2013 11:05:09 +0000 (11:05 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 31 Jan 2013 11:05:09 +0000 (11:05 +0000)
Now the active monitor size is used on startup.
Currently the cursor position is checked for intersection with the monitor bounds to find the active screen.

CMakeLists.txt
intern/ghost/CMakeLists.txt
intern/ghost/intern/GHOST_SystemX11.cpp
source/blender/makesrna/intern/rna_fcurve.c
source/blender/windowmanager/intern/wm_window.c

index e400380..fbacb37 100644 (file)
@@ -166,6 +166,7 @@ unset(PLATFORM_DEFAULT)
 
 if(UNIX AND NOT APPLE)
        option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)"   ON)
+       option(WITH_X11_XINERAMA "Enable multi-monitor support" ON)
        option(WITH_X11_XF86VMODE "Enable X11 video mode switching"     ON)
        option(WITH_SYSTEM_GLEW "Use GLEW OpenGL wrapper library provided by the operating system" ON)
 
@@ -414,6 +415,7 @@ if(WITH_GHOST_SDL OR WITH_HEADLESS)
        set(WITH_GHOST_XDND OFF)
        set(WITH_X11_XF86VMODE OFF)
        set(WITH_X11_XINPUT OFF)
+       set(WITH_X11_XINERAMA OFF)
 endif()
 
 if(MINGW)
@@ -800,6 +802,10 @@ if(UNIX AND NOT APPLE)
                        set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} ${X11_Xinput_LIB}")
                endif()
 
+               if(WITH_X11_XINERAMA)
+                       set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} ${X11_Xinerama_LIB}")
+               endif()
+
                if(WITH_X11_XF86VMODE)
                        # XXX, why dont cmake make this available?
                        FIND_LIBRARY(X11_Xxf86vmode_LIB Xxf86vm   ${X11_LIB_SEARCH_PATH})
index ea09987..c6269d4 100644 (file)
@@ -271,6 +271,16 @@ elseif(UNIX)
 
        if(WITH_X11_XINPUT)
                add_definitions(-DWITH_X11_XINPUT)
+               list(APPEND INC_SYS
+                       ${X11_Xinput_INCLUDE_PATH}
+               )
+       endif()
+
+       if(WITH_X11_XINERAMA)
+               add_definitions(-DWITH_X11_XINERAMA)
+               list(APPEND INC_SYS
+                       ${X11_Xinerama_INCLUDE_PATH}
+               )
        endif()
 
 elseif(WIN32)
index 1e81587..6902b2e 100644 (file)
 #  include "GHOST_DropTargetX11.h"
 #endif
 
+#ifdef WITH_X11_XINERAMA
+#  include "X11/extensions/Xinerama.h"
+#endif
+
 #include "GHOST_Debug.h"
 
 #include <X11/Xatom.h>
@@ -237,8 +241,48 @@ getMainDisplayDimensions(
                GHOST_TUns32& height) const
 {
        if (m_display) {
-               width  = DisplayWidth(m_display, DefaultScreen(m_display));
-               height = DisplayHeight(m_display, DefaultScreen(m_display));
+
+#ifdef WITH_X11_XINERAMA
+               GHOST_TInt32 m_x = 1, m_y = 1;
+               getCursorPosition(m_x, m_y);
+
+               /* NOTE, no way to select a primary monitor, uses the first */
+               bool success = false;
+               int dummy1, dummy2;
+               if (XineramaQueryExtension(m_display, &dummy1, &dummy2)) {
+                       if (XineramaIsActive(m_display)) {
+                               int heads = 0;
+                               XineramaScreenInfo *p = XineramaQueryScreens(m_display, &heads);
+                               /* with a single head, all dimensions is fine */
+                               if (heads > 1) {
+                                       int i;
+                                       for (i = 0; i < heads; i++) {
+                                               if ((m_x >= p[i].x_org) && (m_x <= p[i].x_org + p[i].width) &&
+                                                   (m_y >= p[i].y_org) && (m_y <= p[i].y_org + p[i].height))
+                                               {
+                                                       width = p[i].width;
+                                                       height = p[i].height;
+                                                       break;
+                                               }
+                                       }
+                                       /* highly unlikely! */
+                                       if (i == heads) {
+                                               width = p[0].width;
+                                               height = p[0].height;
+                                       }
+                                       success = true;
+                               }
+                               XFree(p);
+                       }
+               }
+
+               if (success) {
+                       return;
+               }
+#endif
+
+               /* fallback to all */
+               getAllDisplayDimensions(width, height);
        }
 }
 
index fbc9101..1b3c6ef 100644 (file)
@@ -647,7 +647,6 @@ static FCM_EnvelopeData *rna_FModifierEnvelope_points_add(FModifier *fmod, Repor
        fed.f1 = fed.f2 = 0;
 
        if (env->data) {
-               /* add point to end of control points */
                short exists = -1;
                i = BKE_fcm_envelope_find_index(env->data, frame, env->totvert, &exists);
                if (exists) {
index a5f30fc..caf4e2b 100644 (file)
@@ -436,18 +436,11 @@ void wm_window_add_ghostwindows(wmWindowManager *wm)
                        wm_set_apple_prefsize(wm_init_state.size_x, wm_init_state.size_y);
                }
 #else
-               /* default size when un-maximized, unless the screen(s) are smaller */
-
-               /* clamp by these arbitrary values because currently wm_get_screensize()
-                * will span multiple monitors and using xinerama isnt totally reliable
-                * since we don't which monitor the window manager will put the blender
-                * window in. */
-               wm_init_state.size_x = MIN2(1800, wm_init_state.size_x - 100);
-               wm_init_state.size_y = MIN2(980,  wm_init_state.size_y - 100);
-
+               /* note!, this isnt quite correct, active screen maybe offset 1000s if PX,
+                * we'd need a wm_get_screensize like function that gives offset,
+                * in practice the window manager will likely move to the correct monitor */
                wm_init_state.start_x = 0;
                wm_init_state.start_y = 0;
-               
 #endif
        }