Skip to content

Commit 9541b5f

Browse files
committed
Merge pull request #51 from pqftgs/x11_multiple_monitors
Properly support multiple monitors on Linux. Re-adds Xinerama code for multi-monitor support on Linux. It was previously removed from Blender for having little use. However, it's fairly important for full-screen games. This makes full-screen windows render on one monitor, rather than halfway down the middle. Fixes this problem: https://dl.dropboxusercontent.com/u/19279604/temp/arrgghh.png
2 parents 5b3a67a + fc1a19b commit 9541b5f

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ endif()
269269

270270
if(WITH_X11)
271271
option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)" ON)
272+
option(WITH_X11_XINERAMA "Enable multi-monitor support" ON)
272273
option(WITH_X11_XF86VMODE "Enable X11 video mode switching" ON)
273274
endif()
274275

@@ -706,6 +707,7 @@ endif()
706707
if(WITH_GHOST_SDL OR WITH_HEADLESS)
707708
set(WITH_X11 OFF)
708709
set(WITH_X11_XINPUT OFF)
710+
set(WITH_X11_XINERAMA OFF)
709711
set(WITH_X11_XF86VMODE OFF)
710712
set(WITH_GHOST_XDND OFF)
711713
set(WITH_INPUT_IME OFF)
@@ -838,6 +840,14 @@ if(WITH_X11)
838840
endif()
839841
endif()
840842

843+
if(WITH_X11_XINERAMA)
844+
if(X11_Xinerama_LIB)
845+
list(APPEND PLATFORM_LINKLIBS ${X11_Xinerama_LIB})
846+
else()
847+
set(WITH_X11_XINERAMA OFF)
848+
endif()
849+
endif()
850+
841851
if(WITH_X11_XF86VMODE)
842852
# XXX, why dont cmake make this available?
843853
find_library(X11_Xxf86vmode_LIB Xxf86vm ${X11_LIB_SEARCH_PATH})
@@ -3048,6 +3058,7 @@ if(FIRST_RUN)
30483058
info_cfg_option(WITH_INSTALL_PORTABLE)
30493059
info_cfg_option(WITH_X11_XF86VMODE)
30503060
info_cfg_option(WITH_X11_XINPUT)
3061+
info_cfg_option(WITH_X11_XINERAMA)
30513062
info_cfg_option(WITH_MEM_JEMALLOC)
30523063
info_cfg_option(WITH_MEM_VALGRIND)
30533064
info_cfg_option(WITH_SYSTEM_GLEW)

intern/ghost/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,13 @@ elseif(WITH_X11)
242242
)
243243
endif()
244244

245+
if(WITH_X11_XINERAMA)
246+
add_definitions(-DWITH_X11_XINERAMA)
247+
list(APPEND INC_SYS
248+
${X11_Xinerama_INCLUDE_PATH}
249+
)
250+
endif()
251+
245252
add_definitions(-DWITH_X11)
246253

247254
elseif(WIN32)

intern/ghost/intern/GHOST_SystemX11.cpp

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@
5555
# include "GHOST_DropTargetX11.h"
5656
#endif
5757

58+
#ifdef WITH_X11_XINERAMA
59+
# include "X11/extensions/Xinerama.h"
60+
#endif
61+
5862
#include "GHOST_Debug.h"
5963

6064
#ifdef WITH_XF86KEYSYM
@@ -249,9 +253,47 @@ getMainDisplayDimensions(
249253
GHOST_TUns32& height) const
250254
{
251255
if (m_display) {
252-
/* note, for this to work as documented,
253-
* we would need to use Xinerama check r54370 for code that did this,
254-
* we've since removed since its not worth the extra dep - campbell */
256+
257+
#ifdef WITH_X11_XINERAMA
258+
GHOST_TInt32 m_x = 1, m_y = 1;
259+
getCursorPosition(m_x, m_y);
260+
261+
/* NOTE, no way to select a primary monitor, uses the first */
262+
bool success = false;
263+
int dummy1, dummy2;
264+
if (XineramaQueryExtension(m_display, &dummy1, &dummy2)) {
265+
if (XineramaIsActive(m_display)) {
266+
int heads = 0;
267+
XineramaScreenInfo *p = XineramaQueryScreens(m_display, &heads);
268+
/* with a single head, all dimensions is fine */
269+
if (heads > 1) {
270+
int i;
271+
for (i = 0; i < heads; i++) {
272+
if ((m_x >= p[i].x_org) && (m_x <= p[i].x_org + p[i].width) &&
273+
(m_y >= p[i].y_org) && (m_y <= p[i].y_org + p[i].height))
274+
{
275+
width = p[i].width;
276+
height = p[i].height;
277+
break;
278+
}
279+
}
280+
/* highly unlikely! */
281+
if (i == heads) {
282+
width = p[0].width;
283+
height = p[0].height;
284+
}
285+
success = true;
286+
}
287+
XFree(p);
288+
}
289+
}
290+
291+
if (success) {
292+
return;
293+
}
294+
#endif
295+
296+
/* fallback to all */
255297
getAllDisplayDimensions(width, height);
256298
}
257299
}

0 commit comments

Comments
 (0)