2025-07-20 16:04 CEST

View Issue Details Jump to Notes ]
IDProjectCategoryView StatusLast Update
0001637Spring engineLinuxpublic2014-01-03 01:05
ReporterXytovl 
Assigned Toabma 
PrioritynormalSeverityfeatureReproducibilityalways
StatusresolvedResolutionwon't fix 
Product Version 
Target Version0.81.0.0Fixed in Version 
Summary0001637: [PATCH] Xinerama dualscreen in Linux
DescriptionThis patch allows use of xinerama to detect screen geometry. It allows screens to be different and correctly map the view and map on each device.
Additional InformationIt does not work if the main screen is smaller (in height) than the map screen due to ViewPosY apparently not being used.

I am not used to cmake, so I have added USE_XINERAMA as a default value, without checking for Linux as well, this should be changed.
TagsNo tags attached.
Checked infolog.txt for Errors
Attached Files
  • patch file icon xinerama-spring.patch (5,859 bytes) 2009-09-09 14:24 -
    diff --unified -N rts/build/cmake/FindXinerama.cmake rts/build/cmake/FindXinerama.cmake
    --- rts/build/cmake/FindXinerama.cmake	1970-01-01 01:00:00.000000000 +0100
    +++ rts/build/cmake/FindXinerama.cmake	2009-09-09 02:38:55.000000000 +0200
    @@ -0,0 +1,46 @@
    +# - Find the Xinerama include file and library
    +#
    +
    +SET(Xinerama_INC_SEARCH_PATH
    +/usr/X11R6/include
    +/usr/local/include
    +/usr/include/X11
    +/usr/openwin/include
    +/usr/openwin/share/include
    +/opt/graphics/OpenGL/include
    +/usr/include)
    +
    +SET(Xinerama_LIB_SEARCH_PATH
    +/usr/X11R6/lib
    +/usr/local/lib
    +/usr/openwin/lib
    +/usr/lib)
    +
    +
    +FIND_PATH(Xinerama_INCLUDE_DIR X11/extensions/Xinerama.h
    +${Xinerama_INC_SEARCH_PATH})
    +
    +FIND_LIBRARY(Xinerama_LIBRARIES NAMES Xinerama PATH ${Xinerama_LIB_SEARCH_PATH})
    +
    +IF(Xinerama_INCLUDE_DIR AND Xinerama_LIBRARIES)
    +SET(Xinerama_FOUND TRUE)
    +ELSE(Xinerama_INCLUDE_DIR AND Xinerama_LIBRARIES)
    +SET(Xinerama_FOUND FALSE)
    +ENDIF(Xinerama_INCLUDE_DIR AND Xinerama_LIBRARIES)
    +
    +IF(Xinerama_FOUND)
    +INCLUDE(CheckLibraryExists)
    +
    +CHECK_LIBRARY_EXISTS(${Xinerama_LIBRARIES}
    +"XineramaQueryScreens"
    +${Xinerama_LIBRARIES}
    +Xinerama_HAS_QUERY)
    +
    +IF(NOT Xinerama_HAS_QUERY AND Xinerama_FIND_REQUIRED)
    +MESSAGE(FATAL_ERROR "Could NOT find Xinerama")
    +ENDIF(NOT Xinerama_HAS_QUERY AND Xinerama_FIND_REQUIRED)
    +ENDIF(Xinerama_FOUND)
    +
    +MARK_AS_ADVANCED(Xinerama_INCLUDE_DIR Xinerama_LIBRARIES)
    +
    +
    --- rts/Game/UI/MiniMap.cpp	2009-09-09 14:02:08.000000000 +0200
    +++ rts/Game/UI/MiniMap.cpp	2009-09-09 13:39:37.000000000 +0200
    @@ -61,6 +61,11 @@
     #include "TooltipConsole.h"
     #include <boost/cstdint.hpp>
     
    +#ifdef USE_XINERAMA
    +#include <X11/Xlib.h>
    +#include <X11/extensions/Xinerama.h>
    +#endif
    +
     //////////////////////////////////////////////////////////////////////
     // Construction/Destruction
     //////////////////////////////////////////////////////////////////////
    @@ -94,6 +99,27 @@
     		height = gu->viewSizeY;
     		xpos = (gu->viewSizeX - gu->viewPosX);
     		ypos = 0;
    +#ifdef USE_XINERAMA
    +		Display* display = XOpenDisplay(NULL);
    +		int number;
    +		XineramaScreenInfo* screenInfo = XineramaQueryScreens(display, &number);
    +
    +		if (number >1) {
    +			if (gu->dualScreenMiniMapOnLeft) {
    +				xpos   = screenInfo[0].x_org;
    +				width  = screenInfo[0].width;
    +				height = screenInfo[0].height;
    +				ypos   = gu->viewSizeY - (height + screenInfo[0].y_org);
    +			} else {
    +				xpos   = screenInfo[1].x_org;
    +				width  = screenInfo[1].width;
    +				height = screenInfo[1].height;
    +				ypos   = gu->viewSizeY - (height + screenInfo[1].y_org);
    +			}
    +		}
    +		if (screenInfo)
    +			XFree(screenInfo);
    +#endif
     	}
     	else {
     		const std::string geodef = "2 2 200 200";
    @@ -480,7 +506,7 @@
     		ypos -= dy;
     		xpos = std::max(0, xpos);
     		if (gu->dualScreenMode) {
    -			xpos = std::min((2 * gu->viewSizeX) - width, xpos);
    +			xpos = std::min((gu->winSizeX) - width, xpos);
     		} else {
     			xpos = std::min(gu->viewSizeX - width, xpos);
     		}
    @@ -495,7 +521,7 @@
     		height += dy;
     		height = std::min(gu->viewSizeY, height);
     		if (gu->dualScreenMode) {
    -			width = std::min(2 * gu->viewSizeX, width);
    +			width = std::min(gu->winSizeX, width);
     		} else {
     			width = std::min(gu->viewSizeX, width);
     		}
    @@ -571,6 +597,27 @@
     		height = gu->viewSizeY;
     		xpos = (gu->viewSizeX - gu->viewPosX);
     		ypos = 0;
    +#ifdef USE_XINERAMA
    +		Display* display = XOpenDisplay(NULL);
    +		int number;
    +		XineramaScreenInfo* screenInfo = XineramaQueryScreens(display, &number);
    +
    +		if (number >1) {
    +			if (gu->dualScreenMiniMapOnLeft) {
    +				xpos   = screenInfo[0].x_org;
    +				width  = screenInfo[0].width;
    +				height = screenInfo[0].height;
    +				ypos   = gu->viewSizeY - (height + screenInfo[0].y_org);
    +			} else {
    +				xpos   = screenInfo[1].x_org;
    +				width  = screenInfo[1].width;
    +				height = screenInfo[1].height;
    +				ypos   = gu->viewSizeY - (height + screenInfo[1].y_org);
    +			}
    +		}
    +		if (screenInfo)
    +			XFree(screenInfo);
    +#endif
     	}
     	else if (maximized) {
     		SetMaximizedGeometry();
    --- rts/System/SpringApp.cpp	2009-09-09 14:02:08.000000000 +0200
    +++ rts/System/SpringApp.cpp	2009-09-09 13:48:37.000000000 +0200
    @@ -69,6 +69,10 @@
     extern gmlClientServer<void, int,CUnit*> *gmlProcessor;
     #endif
     
    +#ifdef USE_XINERAMA
    +#include <X11/extensions/Xinerama.h>
    +#endif
    +
     using std::string;
     
     CGameController* activeController = 0;
    @@ -514,6 +518,37 @@
     			gu->viewPosX = 0;
     			gu->viewPosY = 0;
     		}
    +#ifdef USE_XINERAMA
    +
    +		SDL_SysWMinfo info;
    +		SDL_VERSION(&info.version);
    +
    +		if (SDL_GetWMInfo(&info)) {
    +			info.info.x11.lock_func();
    +			{
    +				Display* display = info.info.x11.display;
    +				int number;
    +				XineramaScreenInfo* screenInfo = XineramaQueryScreens(display, &number);
    +
    +				if (number >1) {
    +					if (gu->dualScreenMiniMapOnLeft) {
    +						gu->viewPosX  = screenInfo[1].x_org;
    +						gu->viewSizeX = screenInfo[1].width;
    +						gu->viewSizeY = screenInfo[1].height;
    +						gu->viewPosY  = gu->winSizeY - (gu->viewSizeY + screenInfo[1].y_org);
    +					} else {
    +						gu->viewPosX  = screenInfo[0].x_org;
    +						gu->viewSizeX = screenInfo[0].width;
    +						gu->viewSizeY = screenInfo[0].height;
    +						gu->viewPosY  = gu->winSizeY - (gu->viewSizeY + screenInfo[0].y_org);
    +					}
    +				}
    +				if (screenInfo)
    +					XFree(screenInfo);
    +			}
    +		info.info.x11.unlock_func();
    +		}
    +#endif
     	}
     
     	agui::gui->UpdateScreenGeometry(gu->viewSizeX, gu->viewSizeY);
    --- rts/CMakeLists.txt	2009-09-04 19:32:07.000000000 +0200
    +++ rts/CMakeLists.txt	2009-09-09 02:40:07.000000000 +0200
    @@ -21,6 +21,13 @@
     	ADD_DEFINITIONS(-DUSE_MMGR)
     endif (USE_MMGR)
     
    +SET(USE_XINERAMA TRUE CACHE BOOL "Use xinerama?")
    +if (USE_XINERAMA)
    +	ADD_DEFINITIONS(-DUSE_XINERAMA)
    +	FIND_PACKAGE(Xinerama REQUIRED)
    +	LIST(APPEND spring_libraries ${Xinerama_LIBRARIES})
    +endif (USE_XINERAMA)
    +
     SET(USE_GML FALSE CACHE BOOL "Use the GML OpenGL threading library?")
     if (USE_GML)
     	ADD_DEFINITIONS(-DUSE_GML)
    
    patch file icon xinerama-spring.patch (5,859 bytes) 2009-09-09 14:24 +
  • patch file icon xinerama-spring-v2.patch (4,402 bytes) 2010-01-15 14:31 -
    diff --git a/rts/CMakeLists.txt b/rts/CMakeLists.txt
    index 26c4d57..6f2b510 100644
    --- a/rts/CMakeLists.txt
    +++ b/rts/CMakeLists.txt
    @@ -15,6 +15,13 @@ if (USE_MMGR)
     	ADD_DEFINITIONS(-DUSE_MMGR)
     endif (USE_MMGR)
     
    +SET(USE_XINERAMA FALSE CACHE BOOL "Use xinerama?")
    +if (USE_XINERAMA)
    +       ADD_DEFINITIONS(-DUSE_XINERAMA)
    +       FIND_PACKAGE(Xinerama REQUIRED)
    +       LIST(APPEND spring_libraries ${Xinerama_LIBRARIES})
    +endif (USE_XINERAMA)
    +
     SET(USE_GML FALSE CACHE BOOL "Use the GML OpenGL threading library?")
     if (USE_GML)
     	ADD_DEFINITIONS(-DUSE_GML)
    diff --git a/rts/Game/UI/MiniMap.cpp b/rts/Game/UI/MiniMap.cpp
    index 1b1e02b..72456a3 100644
    --- a/rts/Game/UI/MiniMap.cpp
    +++ b/rts/Game/UI/MiniMap.cpp
    @@ -52,6 +52,10 @@
     #include "TooltipConsole.h"
     #include <boost/cstdint.hpp>
     
    +#ifdef USE_XINERAMA
    +#include "System/Platform/Linux/Xinerama.h"
    +#endif
    +
     //////////////////////////////////////////////////////////////////////
     // Construction/Destruction
     //////////////////////////////////////////////////////////////////////
    @@ -85,6 +89,9 @@ CMiniMap::CMiniMap()
     		height = gu->viewSizeY;
     		xpos = (gu->viewSizeX - gu->viewPosX);
     		ypos = 0;
    +#ifdef USE_XINERAMA
    +		getXineramaPosition(gu->dualScreenMiniMapOnLeft, &xpos, &ypos, &width, &height);
    +#endif
     	}
     	else {
     		const std::string geodef = "2 2 200 200";
    @@ -471,7 +478,7 @@ void CMiniMap::MouseMove(int x, int y, int dx, int dy, int button)
     		ypos -= dy;
     		xpos = std::max(0, xpos);
     		if (gu->dualScreenMode) {
    -			xpos = std::min((2 * gu->viewSizeX) - width, xpos);
    +			xpos = std::min(gu->winSizeX - width, xpos);
     		} else {
     			xpos = std::min(gu->viewSizeX - width, xpos);
     		}
    @@ -486,7 +493,7 @@ void CMiniMap::MouseMove(int x, int y, int dx, int dy, int button)
     		height += dy;
     		height = std::min(gu->viewSizeY, height);
     		if (gu->dualScreenMode) {
    -			width = std::min(2 * gu->viewSizeX, width);
    +			width = std::min(gu->winSizeX, width);
     		} else {
     			width = std::min(gu->viewSizeX, width);
     		}
    @@ -562,6 +569,9 @@ void CMiniMap::UpdateGeometry()
     		height = gu->viewSizeY;
     		xpos = (gu->viewSizeX - gu->viewPosX);
     		ypos = 0;
    +#ifdef USE_XINERAMA
    +		getXineramaPosition(gu->dualScreenMiniMapOnLeft, &xpos, &ypos, &width, &height);
    +#endif
     	}
     	else if (maximized) {
     		SetMaximizedGeometry();
    diff --git a/rts/System/Platform/Linux/Xinerama.cpp b/rts/System/Platform/Linux/Xinerama.cpp
    new file mode 100644
    index 0000000..24d1ecc
    --- /dev/null
    +++ b/rts/System/Platform/Linux/Xinerama.cpp
    @@ -0,0 +1,30 @@
    +#include "Xinerama.h"
    +#include <X11/Xlib.h>
    +#include <X11/extensions/Xinerama.h>
    +#include <algorithm>
    +
    +void getXineramaPosition(bool left, int *xpos, int *ypos, int *width, int *height){
    +	Display* display = XOpenDisplay(NULL);
    +	int number;
    +	int screen;
    +	XineramaScreenInfo* screenInfo = XineramaQueryScreens(display, &number);
    +	if (number >1) {
    +		if (screenInfo[0].x_org < screenInfo[1].x_org){
    +			if (left)
    +				screen = 0;
    +			else
    +				screen = 1;
    +		} else {
    +			if (left)
    +				screen = 1;
    +			else
    +				screen = 0;
    +		}
    +		*xpos   = screenInfo[screen].x_org;
    +		*width  = screenInfo[screen].width;
    +		*height = screenInfo[screen].height;
    +		*ypos   = std::max(screenInfo[0].height,screenInfo[1].height)- (*height + screenInfo[screen].y_org);
    +	}
    +	if (screenInfo)
    +		XFree(screenInfo);
    +}
    diff --git a/rts/System/Platform/Linux/Xinerama.h b/rts/System/Platform/Linux/Xinerama.h
    new file mode 100644
    index 0000000..a119523
    --- /dev/null
    +++ b/rts/System/Platform/Linux/Xinerama.h
    @@ -0,0 +1,5 @@
    +#ifndef XINERAMASPRING_H
    +#define XINERAMASPRING_H
    +
    +void getXineramaPosition(bool left, int *xpos, int *ypos, int *width, int *height);
    +#endif //XINERAMASPRING_H
    diff --git a/rts/System/SpringApp.cpp b/rts/System/SpringApp.cpp
    index 9582222..7a2ef12 100644
    --- a/rts/System/SpringApp.cpp
    +++ b/rts/System/SpringApp.cpp
    @@ -65,6 +65,10 @@
     	#include "Platform/Win/WinVersion.h"
     #endif // WIN32
     
    +#ifdef USE_XINERAMA
    +#include "System/Platform/Linux/Xinerama.h"
    +#endif
    +
     #ifdef USE_GML
     #include "lib/gml/gmlsrv.h"
     extern gmlClientServer<void, int,CUnit*> *gmlProcessor;
    @@ -529,6 +533,9 @@ void SpringApp::SetupViewportGeometry()
     			gu->viewPosX = 0;
     			gu->viewPosY = 0;
     		}
    +#ifdef USE_XINERAMA
    +		getXineramaPosition(!gu->dualScreenMiniMapOnLeft, &gu->viewPosX, &gu->viewPosY, &gu->viewSizeX, &gu->viewSizeY);
    +#endif
     	}
     
     	agui::gui->UpdateScreenGeometry(
    
    patch file icon xinerama-spring-v2.patch (4,402 bytes) 2010-01-15 14:31 +
  • patch file icon xinerama-small-viewSizeY.patch (14,860 bytes) 2010-01-18 11:53 -
    diff --git a/rts/Game/Game.cpp b/rts/Game/Game.cpp
    index 485a786..b52857c 100644
    --- a/rts/Game/Game.cpp
    +++ b/rts/Game/Game.cpp
    @@ -3099,7 +3099,7 @@ bool CGame::Draw() {
     			if (FBO::IsSupported())
     				FBO::Unbind();
     
    -			glViewport(gu->viewPosX, 0, gu->viewSizeX, gu->viewSizeY);
    +			glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     		}
     	}
     
    @@ -4381,11 +4381,11 @@ void CGame::UpdateUI(bool updateCam)
     		if (( fullscreen && fullscreenEdgeMove) ||
     		    (!fullscreen && windowedEdgeMove)) {
     
    -			const int screenW = gu->dualScreenMode ? (gu->viewSizeX << 1): gu->viewSizeX;
    +			const int screenW = gu->dualScreenMode ? (gu->winSizeX ): gu->viewSizeX;
     			disableTracker = false;
     
     			if (mouse->lasty <                  2 ) { movement.y += gu->lastFrameTime; disableTracker = true; }
    -			if (mouse->lasty > (gu->viewSizeY - 2)) { movement.y -= gu->lastFrameTime; disableTracker = true; }
    +			if (mouse->lasty > (gu->winSizeY - 2)) { movement.y -= gu->lastFrameTime; disableTracker = true; }
     			if (mouse->lastx >       (screenW - 2)) { movement.x += gu->lastFrameTime; disableTracker = true; }
     			if (mouse->lastx <                  2 ) { movement.x -= gu->lastFrameTime; disableTracker = true; }
     
    diff --git a/rts/Game/UI/CursorIcons.cpp b/rts/Game/UI/CursorIcons.cpp
    index b2d467d..85bb6d1 100644
    --- a/rts/Game/UI/CursorIcons.cpp
    +++ b/rts/Game/UI/CursorIcons.cpp
    @@ -123,7 +123,7 @@ void CCursorIcons::DrawCursors()
     
     void CCursorIcons::DrawTexts()
     {
    -	glViewport(gu->viewPosX, 0, gu->viewSizeX, gu->viewSizeY);
    +	glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     	glColor4f(1.0f,  1.0f, 1.0f, 1.0f);
     
     	const float fontScale = 1.0f;
    @@ -152,7 +152,7 @@ void CCursorIcons::DrawTexts()
     
     void CCursorIcons::DrawBuilds()
     {
    -	glViewport(gu->viewPosX, 0, gu->viewSizeX, gu->viewSizeY);
    +	glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     
     	glEnable(GL_DEPTH_TEST);
     	glColor4f(1.0f, 1.0f, 1.0f, 0.3f);
    diff --git a/rts/Game/UI/MiniMap.cpp b/rts/Game/UI/MiniMap.cpp
    index 72456a3..f3f0ffe 100644
    --- a/rts/Game/UI/MiniMap.cpp
    +++ b/rts/Game/UI/MiniMap.cpp
    @@ -479,10 +479,11 @@ void CMiniMap::MouseMove(int x, int y, int dx, int dy, int button)
     		xpos = std::max(0, xpos);
     		if (gu->dualScreenMode) {
     			xpos = std::min(gu->winSizeX - width, xpos);
    +			ypos = std::max(5, std::min(gu->winSizeY - height, ypos));
     		} else {
     			xpos = std::min(gu->viewSizeX - width, xpos);
    +			ypos = std::max(5, std::min(gu->viewSizeY - height, ypos));
     		}
    -		ypos = std::max(5, std::min(gu->viewSizeY - height, ypos));
     		UpdateGeometry();
     		return;
     	}
    @@ -656,7 +657,7 @@ void CMiniMap::MoveView(int x, int y)
     	}
     	float3 clickPos;
     	clickPos.x = (float(x - xpos)) / width * gs->mapx * 8;
    -	clickPos.z = (float(y - (gu->viewSizeY - ypos - height))) / height * gs->mapy * 8;
    +	clickPos.z = (float(y - ((gu->dualScreenMode ? (gu->winSizeY ):gu->viewSizeY) - ypos - height))) / height * gs->mapy * 8;
     	camHandler->GetCurrentController().SetPos(clickPos);
     	unitTracker.Disable();
     }
    @@ -809,7 +810,7 @@ float3 CMiniMap::GetMapPosition(int x, int y) const
     	const float mapX = gs->mapx * SQUARE_SIZE;
     	const float mapY = gs->mapy * SQUARE_SIZE;
     	const float3 pos(mapX * float(x - xpos) / width, mapHeight,
    -	                 mapY * float(y - (gu->viewSizeY - ypos - height)) / height);
    +	                 mapY * float(y - ((gu->dualScreenMode ? (gu->winSizeY ):gu->viewSizeY) - ypos - height)) / height);
     	return pos;
     }
     
    @@ -931,7 +932,7 @@ std::string CMiniMap::GetTooltip(int x, int y)
     	}
     
     	const float3 pos(float(x-xpos)/width*gs->mapx*SQUARE_SIZE, 500,
    -	                 float(y-(gu->viewSizeY-ypos-height))/height*gs->mapx*SQUARE_SIZE);
    +	                 float(y-((gu->dualScreenMode ? (gu->winSizeY ):gu->viewSizeY)-ypos-height))/height*gs->mapx*SQUARE_SIZE);
     	return CTooltipConsole::MakeGroundString(pos);
     }
     
    @@ -1212,7 +1213,7 @@ void CMiniMap::DrawForReal()
     		glLineWidth(1.0f);
     	}
     
    -	glViewport(gu->viewPosX, 0, gu->viewSizeX, gu->viewSizeY);
    +	glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     
     	cursorIcons.Enable(true);
     	setSurfaceCircleFunc(NULL);
    @@ -1257,7 +1258,7 @@ void CMiniMap::DrawMinimizedButton()
     	glLineWidth(1.0f);
     	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
     
    -	glViewport(gu->viewPosX, 0, gu->viewSizeX, gu->viewSizeY);
    +	glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     }
     
     
    diff --git a/rts/Game/UI/MouseCursor.cpp b/rts/Game/UI/MouseCursor.cpp
    index f67734b..2ba3d57 100644
    --- a/rts/Game/UI/MouseCursor.cpp
    +++ b/rts/Game/UI/MouseCursor.cpp
    @@ -303,7 +303,7 @@ void CMouseCursor::Draw(int x, int y, float scale)
     	glAlphaFunc(GL_GREATER, 0.01f);
     	glColor4f(1,1,1,1);
     
    -	glViewport(xp, gu->viewSizeY - yp, xs, ys);
    +	glViewport(xp, gu->winSizeY - yp, xs, ys);
     
     	glBegin(GL_QUADS);
     		glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f);
    @@ -312,7 +312,7 @@ void CMouseCursor::Draw(int x, int y, float scale)
     		glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, 0.0f, 0.0f);
     	glEnd();
     
    -	glViewport(gu->viewPosX, 0, gu->viewSizeX, gu->viewSizeY);
    +	glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     }
     
     
    @@ -328,7 +328,7 @@ void CMouseCursor::DrawQuad(int x, int y)
     	const int xp = int(float(x) - (float(xofs) * scale));
     	const int yp = int(float(y) - (float(ys) - (float(yofs) * scale)));
     
    -	glViewport(gu->viewPosX + xp, yp, xs, ys);
    +	glViewport(gu->viewPosX + xp, gu->viewPosY + yp, xs, ys);
     
     	glBegin(GL_QUADS);
     	 	glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f);
    diff --git a/rts/Game/UI/MouseHandler.cpp b/rts/Game/UI/MouseHandler.cpp
    index 86c9d34..470fa59 100644
    --- a/rts/Game/UI/MouseHandler.cpp
    +++ b/rts/Game/UI/MouseHandler.cpp
    @@ -169,7 +169,8 @@ void CMouseHandler::MouseMove(int x, int y)
     		lasty = y;
     
     		int dx = lastx - (gu->viewSizeX / 2 + gu->viewPosX);
    -		int dy = lasty - (gu->viewSizeY / 2 + gu->viewPosY);
    +		int dy = lasty - (gu->viewSizeY / 2 /*+ gu->viewPosY*/);
    +		//FIXME: this does not work if the viewport is not at the top of the display
     
     		float3 move;
     		move.x = dx;
    @@ -558,7 +559,8 @@ void CMouseHandler::WarpMouse(int x, int y)
     {
     	if (!locked) {
     		lastx = x + gu->viewPosX;
    -		lasty = y + gu->viewPosY;
    +		lasty = y /*+ gu->viewPosY*/;
    +		//FIXME: this does not work if the viewport is not at the top of the display
     		mouseInput->SetPos(int2(lastx, lasty));
     	}
     }
    @@ -635,7 +637,8 @@ void CMouseHandler::EmptyMsgQueUpdate()
     	}
     
     	lastx = gu->viewSizeX / 2 + gu->viewPosX;
    -	lasty = gu->viewSizeY / 2 + gu->viewPosY;
    +	lasty = gu->viewSizeY / 2 /*+ gu->viewPosY*/;
    +	//FIXME: this does not work if the viewport is not at the top of the display
     
     	if (gu->active) {
     		mouseInput->SetPos(int2(lastx, lasty));
    @@ -666,7 +669,8 @@ void CMouseHandler::HideMouse()
     		SDL_ShowCursor(SDL_DISABLE);
     		mouseInput->SetWMMouseCursor(NULL);
     		lastx = gu->viewSizeX / 2 + gu->viewPosX;
    -		lasty = gu->viewSizeY / 2 + gu->viewPosY;
    +		lasty = gu->viewSizeY / 2 /*+ gu->viewPosY*/;
    +		//FIXME: this does not work if the viewport is not at the top of the display
     		mouseInput->SetPos(int2(lastx, lasty));
     		hide = true;
     	}
    diff --git a/rts/Lua/LuaUnsyncedRead.cpp b/rts/Lua/LuaUnsyncedRead.cpp
    index 52cd5fd..63a425c 100644
    --- a/rts/Lua/LuaUnsyncedRead.cpp
    +++ b/rts/Lua/LuaUnsyncedRead.cpp
    @@ -1217,7 +1217,7 @@ int LuaUnsyncedRead::TraceScreenRay(lua_State* L)
     	const bool useMiniMap = (lua_isboolean(L, 4) && lua_toboolean(L, 4));
     
     	const int wx = mx + gu->viewPosX;
    -	const int wy = gu->viewSizeY - 1 - my - gu->viewPosY;
    +	const int wy = gu->viewSizeY - 1 - my /*- gu->viewPosY*/;
     
     	if (useMiniMap && (minimap != NULL) && !minimap->GetMinimized()) {
     		const int px = minimap->GetPosX() - gu->viewPosX; // for left dualscreen
    diff --git a/rts/Rendering/Env/AdvSky.cpp b/rts/Rendering/Env/AdvSky.cpp
    index f5a909e..30dc053 100644
    --- a/rts/Rendering/Env/AdvSky.cpp
    +++ b/rts/Rendering/Env/AdvSky.cpp
    @@ -797,7 +797,7 @@ void CAdvSky::CreateDetailTex(void)
     //	SwapBuffers(hDC);
     //	SleepEx(500,true);
     
    -	glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
    +	glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     	glEnable(GL_DEPTH_TEST);
     }
     
    diff --git a/rts/Rendering/Env/AdvTreeGenerator.cpp b/rts/Rendering/Env/AdvTreeGenerator.cpp
    index ed2f5a5..caf5a7b 100644
    --- a/rts/Rendering/Env/AdvTreeGenerator.cpp
    +++ b/rts/Rendering/Env/AdvTreeGenerator.cpp
    @@ -355,7 +355,7 @@ void CAdvTreeGenerator::CreateFarTex()
     	glDisable( GL_VERTEX_PROGRAM_ARB );
     	glDisable(GL_ALPHA_TEST);
     
    -	glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
    +	glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     	glMatrixMode(GL_PROJECTION);
     	glPopMatrix();
     	glMatrixMode(GL_MODELVIEW);
    @@ -824,7 +824,7 @@ void CAdvTreeGenerator::CreateLeafTex(unsigned int baseTex, int xpos, int ypos,u
     		}
     	}
     
    -	glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
    +	glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     	glMatrixMode(GL_PROJECTION);
     	glPopMatrix();
     	glMatrixMode(GL_MODELVIEW);
    diff --git a/rts/Rendering/Env/AdvWater.cpp b/rts/Rendering/Env/AdvWater.cpp
    index 991f357..2f1baec 100644
    --- a/rts/Rendering/Env/AdvWater.cpp
    +++ b/rts/Rendering/Env/AdvWater.cpp
    @@ -330,7 +330,7 @@ void CAdvWater::UpdateWater(CGame* game)
     
     	FBO::Unbind();
     
    -	glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
    +	glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     	glClearColor(mapInfo->atmosphere.fogColor[0],mapInfo->atmosphere.fogColor[1],mapInfo->atmosphere.fogColor[2],1);
     
     //	delete camera;
    diff --git a/rts/Rendering/Env/BumpWater.cpp b/rts/Rendering/Env/BumpWater.cpp
    index 4aabdba..bbd443d 100644
    --- a/rts/Rendering/Env/BumpWater.cpp
    +++ b/rts/Rendering/Env/BumpWater.cpp
    @@ -727,7 +727,7 @@ void CBumpWater::UpdateWater(CGame* game)
     	if (reflection>0) DrawReflection(game);
     	if (reflection || refraction) {
     		FBO::Unbind();
    -		glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
    +		glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     	}
     	glPopAttrib();
     }
    @@ -1077,7 +1077,7 @@ void CBumpWater::UpdateCoastmap()
     	glGenerateMipmapEXT(GL_TEXTURE_2D);
     
     	glUseProgram(0);
    -	glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
    +	glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     
     	//coastFBO.Unattach(GL_COLOR_ATTACHMENT1_EXT);
     	coastFBO.Unbind();
    @@ -1151,7 +1151,7 @@ void CBumpWater::UpdateDynWaves(const bool initialize)
     		glPopMatrix();
     	glMatrixMode(GL_MODELVIEW);
     		glPopMatrix();
    -	glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
    +	glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     
     	dynWavesFBO.Unbind();
     
    diff --git a/rts/Rendering/Env/CubeMapHandler.cpp b/rts/Rendering/Env/CubeMapHandler.cpp
    index 566a88a..13e4fc6 100644
    --- a/rts/Rendering/Env/CubeMapHandler.cpp
    +++ b/rts/Rendering/Env/CubeMapHandler.cpp
    @@ -147,7 +147,7 @@ void CubeMapHandler::CreateReflectionFace(unsigned int glType, const float3& cam
     
     	//! we do this later to save render context switches (this is one of the slowest opengl operations!)
     	// reflectionCubeFBO.Unbind();
    -	// glViewport(gu->viewPosX, 0, gu->viewSizeX, gu->viewSizeY);
    +	// glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     	glPopAttrib();
     
     	game->SetDrawMode(CGame::normalDraw);
    diff --git a/rts/Rendering/Env/DynWater.cpp b/rts/Rendering/Env/DynWater.cpp
    index 006bce4..aa5ff92 100644
    --- a/rts/Rendering/Env/DynWater.cpp
    +++ b/rts/Rendering/Env/DynWater.cpp
    @@ -482,7 +482,7 @@ void CDynWater::DrawReflection(CGame* game)
     	drawReflection=false;
     	glDisable(GL_CLIP_PLANE2);
     
    -	glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
    +	glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     	glClearColor(mapInfo->atmosphere.fogColor[0],mapInfo->atmosphere.fogColor[1],mapInfo->atmosphere.fogColor[2],1);
     
     //	delete camera;
    @@ -537,7 +537,7 @@ void CDynWater::DrawRefraction(CGame* game)
     	drawRefraction=false;
     
     
    -	glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
    +	glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     	glClearColor(mapInfo->atmosphere.fogColor[0],mapInfo->atmosphere.fogColor[1],mapInfo->atmosphere.fogColor[2],1);
     
     	unitDrawer->unitSunColor=oldsun;
    diff --git a/rts/Rendering/Env/GrassDrawer.cpp b/rts/Rendering/Env/GrassDrawer.cpp
    index 2756ead..45cbadc 100644
    --- a/rts/Rendering/Env/GrassDrawer.cpp
    +++ b/rts/Rendering/Env/GrassDrawer.cpp
    @@ -774,7 +774,7 @@ void CGrassDrawer::CreateFarTex(void)
     //	CBitmap bm(buf,1024*sizeMod,64*sizeMod);
     //	bm.Save("fartex.bmp");
     
    -	glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
    +	glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     	glMatrixMode(GL_PROJECTION);
     	glPopMatrix();
     	glMatrixMode(GL_MODELVIEW);
    diff --git a/rts/Rendering/FartextureHandler.cpp b/rts/Rendering/FartextureHandler.cpp
    index d74efeb..072426c 100644
    --- a/rts/Rendering/FartextureHandler.cpp
    +++ b/rts/Rendering/FartextureHandler.cpp
    @@ -190,7 +190,7 @@ void CFartextureHandler::ReallyCreateFarTexture(S3DModel* model)
     	}
     	unitDrawer->CleanUpUnitDrawing();
     
    -	glViewport(gu->viewPosX, 0, gu->viewSizeX, gu->viewSizeY);
    +	glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     
     	usedFarTextures++;
     
    diff --git a/rts/Rendering/Screenshot.cpp b/rts/Rendering/Screenshot.cpp
    index 5191347..fe232b4 100644
    --- a/rts/Rendering/Screenshot.cpp
    +++ b/rts/Rendering/Screenshot.cpp
    @@ -107,7 +107,7 @@ void TakeScreenshot(std::string type)
     	if (filesystem.CreateDirectory("screenshots"))
     	{
     		FunctionArgs args;
    -		args.x = gu->dualScreenMode? gu->viewSizeX << 1: gu->viewSizeX;
    +		args.x = gu->dualScreenMode? gu->winSizeX : gu->viewSizeX;
     		args.y = gu->viewSizeY;
     
     		if (args.x % 4)
    diff --git a/rts/Rendering/ShadowHandler.cpp b/rts/Rendering/ShadowHandler.cpp
    index 0dbbdbe..165c555 100644
    --- a/rts/Rendering/ShadowHandler.cpp
    +++ b/rts/Rendering/ShadowHandler.cpp
    @@ -262,7 +262,7 @@ void CShadowHandler::CreateShadows(void)
     
     	//we do this later to save render context switches (this is one of the slowest opengl operations!)
     	//fb.Unbind();
    -	//glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
    +	//glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     }
     
     
    diff --git a/rts/Sim/Projectiles/ProjectileHandler.cpp b/rts/Sim/Projectiles/ProjectileHandler.cpp
    index a02fa5b..cb723b2 100644
    --- a/rts/Sim/Projectiles/ProjectileHandler.cpp
    +++ b/rts/Sim/Projectiles/ProjectileHandler.cpp
    @@ -1195,7 +1195,7 @@ void CProjectileHandler::UpdatePerlin()
     		size*=2;
     	}
     	perlinFB.Unbind();
    -	glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
    +	glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
     
     	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     	glEnable(GL_DEPTH_TEST);
    
    patch file icon xinerama-small-viewSizeY.patch (14,860 bytes) 2010-01-18 11:53 +
  • patch file icon xinerama-cmake.patch (1,327 bytes) 2010-01-20 18:29 -
    diff --git a/rts/build/cmake/FindXinerama.cmake b/rts/build/cmake/FindXinerama.cmake
    new file mode 100644
    index 0000000..1e579fc
    --- /dev/null
    +++ b/rts/build/cmake/FindXinerama.cmake
    @@ -0,0 +1,45 @@
    +# - Find the Xinerama include file and library
    +#
    +
    +SET(Xinerama_INC_SEARCH_PATH
    +/usr/X11R6/include
    +/usr/local/include
    +/usr/include/X11
    +/usr/openwin/include
    +/usr/openwin/share/include
    +/opt/graphics/OpenGL/include
    +/usr/include)
    +
    +SET(Xinerama_LIB_SEARCH_PATH
    +/usr/X11R6/lib
    +/usr/local/lib
    +/usr/openwin/lib
    +/usr/lib)
    +
    +
    +FIND_PATH(Xinerama_INCLUDE_DIR X11/extensions/Xinerama.h
    +${Xinerama_INC_SEARCH_PATH})
    +
    +FIND_LIBRARY(Xinerama_LIBRARIES NAMES Xinerama PATH ${Xinerama_LIB_SEARCH_PATH})
    +
    +IF(Xinerama_INCLUDE_DIR AND Xinerama_LIBRARIES)
    +SET(Xinerama_FOUND TRUE)
    +ELSE(Xinerama_INCLUDE_DIR AND Xinerama_LIBRARIES)
    +SET(Xinerama_FOUND FALSE)
    +ENDIF(Xinerama_INCLUDE_DIR AND Xinerama_LIBRARIES)
    +
    +IF(Xinerama_FOUND)
    +INCLUDE(CheckLibraryExists)
    +
    +CHECK_LIBRARY_EXISTS(${Xinerama_LIBRARIES}
    +"XineramaQueryScreens"
    +${Xinerama_LIBRARIES}
    +Xinerama_HAS_QUERY)
    +
    +IF(NOT Xinerama_HAS_QUERY AND Xinerama_FIND_REQUIRED)
    +MESSAGE(FATAL_ERROR "Could NOT find Xinerama")
    +ENDIF(NOT Xinerama_HAS_QUERY AND Xinerama_FIND_REQUIRED)
    +ENDIF(Xinerama_FOUND)
    +
    +MARK_AS_ADVANCED(Xinerama_INCLUDE_DIR Xinerama_LIBRARIES)
    +
    
    patch file icon xinerama-cmake.patch (1,327 bytes) 2010-01-20 18:29 +

-Relationships
+Relationships

-Notes

~0004337

hoijui (reporter)

having a look at it
for the future, it would be nicer if you forked spring on github and pushed your changes there. credits for the changes would then go to you, and i/we would have less work :D

~0004494

tvo (reporter)

I tried this, seems to (sort of) work for me, although one time minimap was on wrong side (may happen if primary monitor is to the right of secondary monitor maybe?)

I think it needs a setting to set primary screen for Spring, I don't like having to change it in X server, as that also changes locations of panels etc. (i.e. in gnome)

Also this patch introduces a lot of code duplication, please factor as much as possible out into a function.

~0004495

Xytovl (reporter)

Here is a new version with no code replication and that should work when the main display is not on the left

~0004498

Xytovl (reporter)

I forgot to say that v2 of the patch has USE_XINERAMA disabled by default

~0004500

tvo (reporter)

Ah great, this looks a lot cleaner already :-)

~0004507

Xytovl (reporter)

Added the work-in-progress support for asymetric setups with the main screen that is smaller (in height) than the minimap screen.
Everything seems to work except movement orders given on the minimap, there is an offset I can't fix :(

~0004514

Xytovl (reporter)

Added the missing cmake file needed to find the library ... it would not compile without it

you should apply xinerama-spring-v2.patch and xinerama-cmake.patch together

xinerama-small-viewSizeY.patch can be applied as well, but it seems that some lua scripts are broken if viewsizeY is smaller than the screen height, so it is not totally usable.

~0009302

abma (administrator)

why wasn't this patch applied/decilined?

~0012578

abma (administrator)

patch doesn't apply any more, also not sure if SDL2 fixes some problems here (see SDL2 branch at github)

next time please use github, this way patches are more likely applied.
+Notes

-Issue History
Date Modified Username Field Change
2009-09-09 14:24 Xytovl New Issue
2009-09-09 14:24 Xytovl File Added: xinerama-spring.patch
2009-10-03 10:46 imbaczek Target Version => 0.81.0.0
2009-11-16 13:44 hoijui Note Added: 0004337
2010-01-15 00:14 tvo Note Added: 0004494
2010-01-15 14:31 Xytovl File Added: xinerama-spring-v2.patch
2010-01-15 14:32 Xytovl Note Added: 0004495
2010-01-16 21:30 Xytovl Note Added: 0004498
2010-01-17 11:49 tvo Note Added: 0004500
2010-01-18 11:53 Xytovl File Added: xinerama-small-viewSizeY.patch
2010-01-18 11:55 Xytovl Note Added: 0004507
2010-01-20 18:29 Xytovl File Added: xinerama-cmake.patch
2010-01-20 18:33 Xytovl Note Added: 0004514
2012-11-04 02:02 abma Note Added: 0009302
2012-11-04 02:02 abma Status new => feedback
2014-01-03 01:05 abma Note Added: 0012578
2014-01-03 01:05 abma Status feedback => resolved
2014-01-03 01:05 abma Resolution open => won't fix
2014-01-03 01:05 abma Assigned To => abma
+Issue History