# HG changeset patch
# User Thibaut Girka <thib@sitedethib.com>
# Date 1274523482 -7200
# Node ID 6b3dad2f174cace66b9e4101d628f1967572cc7a
# Parent  e1f056cecd44febf6f2a635ab4ef5f2ad2fc526b
Implement CDriverGL::setMode for X

diff -r e1f056cecd44 -r 6b3dad2f174c code/nel/src/3d/driver/opengl/driver_opengl.cpp
--- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp	Sat May 22 08:54:18 2010 +0200
+++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp	Sat May 22 12:18:02 2010 +0200
@@ -1612,9 +1612,46 @@
 	_WindowX = clientRect.left;
 	_WindowY = clientRect.top;
 	_FullScreen = !mode.Windowed;
-#else
-	// TODO linux version !!!
-#endif
+
+#elif defined(NL_OS_UNIX) // NL_OS_WINDOWS
+
+	// Update WM hints (update size and disallow resizing)
+	XSizeHints size_hints;
+	size_hints.x = 0;
+	size_hints.y = 0;
+	size_hints.width = mode.Width;
+	size_hints.height = mode.Height;
+	size_hints.flags = PSize | PMinSize | PMaxSize;
+	size_hints.min_width = mode.Width;
+	size_hints.min_height = mode.Height;
+	size_hints.max_width = mode.Width;
+	size_hints.max_height = mode.Height;
+
+	XSetWMNormalHints(dpy, win, &size_hints);
+
+	// Toggle fullscreen
+	if (mode.Windowed == _FullScreen)
+	{
+		XEvent xev;
+		memset(&xev, 0, sizeof(xev));
+		xev.type = ClientMessage;
+		xev.xclient.window = win;
+		xev.xclient.message_type =  XInternAtom(dpy, "_NET_WM_STATE", false);
+		xev.xclient.format = 32;
+		xev.xclient.data.l[0] = !mode.Windowed;
+		xev.xclient.data.l[1] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", false);
+		xev.xclient.data.l[2] = 0;
+		XSendEvent(dpy, DefaultRootWindow(dpy), false, SubstructureNotifyMask, &xev);
+
+		//TODO: Change X display mode
+	}
+	_FullScreen = !mode.Windowed;
+
+	// Resize and update the window
+	XResizeWindow(dpy, win, mode.Width, mode.Height);
+	XMapWindow(dpy, win);
+
+#endif // NL_OS_UNIX
 	return true;
 }
 
# HG changeset patch
# User Thibaut Girka <thib@sitedethib.com>
# Date 1274525666 -7200
# Node ID 133efed1e38f4b10e4c47ba983fb587705ca8d6b
# Parent  6b3dad2f174cace66b9e4101d628f1967572cc7a
Add X mode setting when fullscreen

diff -r 6b3dad2f174c -r 133efed1e38f code/nel/src/3d/driver/opengl/driver_opengl.cpp
--- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp	Sat May 22 12:18:02 2010 +0200
+++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp	Sat May 22 12:54:26 2010 +0200
@@ -1096,22 +1096,7 @@
 	XSetWindowAttributes attr;
 	attr.colormap = cmap;
 	attr.background_pixel = BlackPixel(dpy, DefaultScreen(dpy));
-
-#ifdef XF86VIDMODE
-	// If we're going to attempt fullscreen, we need to set redirect to True,
-	// This basically places the window with no borders in the top left
-	// corner of the screen.
-	if (mode.Windowed)
-	{
-		attr.override_redirect = False;
-	}
-	else
-	{
-		attr.override_redirect = True;
-	}
-#else
 	attr.override_redirect = False;
-#endif
 
 	int attr_flags = CWOverrideRedirect | CWColormap | CWBackPixel;
 
@@ -1615,6 +1600,52 @@
 
 #elif defined(NL_OS_UNIX) // NL_OS_WINDOWS
 
+#ifdef XF86VIDMODE
+	if (!mode.Windowed)
+	{
+		if (mode.Windowed == _FullScreen)
+		{
+			memset(&_OldScreenMode, 0, sizeof(_OldScreenMode));
+			XF86VidModeGetModeLine(dpy, DefaultScreen(dpy), &_OldDotClock, &_OldScreenMode);
+			XF86VidModeGetViewPort(dpy, DefaultScreen(dpy), &_OldX, &_OldY);
+		}
+
+		XF86VidModeModeInfo **modes;
+		int nmodes;
+		if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &nmodes, &modes))
+		{
+			for (int i = 0; i < nmodes; i++)
+			{
+				nldebug("3D: Available mode - %dx%d", modes[i]->hdisplay, modes[i]->vdisplay);
+				if(modes[i]->hdisplay == mode.Width && modes[i]->vdisplay == mode.Height)
+				{
+					if(XF86VidModeSwitchToMode(dpy, DefaultScreen(dpy), modes[i]))
+					{
+						nlinfo("3D: Switching to mode %dx%d", modes[i]->hdisplay, modes[i]->vdisplay);
+						XF86VidModeSetViewPort(dpy, DefaultScreen(dpy), 0, 0);
+					}
+					break;
+				}
+			}
+		}
+	}
+	else if (mode.Windowed == _FullScreen)
+	{
+		XF86VidModeModeInfo info;
+		nlinfo("3D: Switching back to original mode");
+
+		// This is a bit ugly - a quick hack to copy the ModeLine structure
+		// into the modeInfo structure.
+		memcpy((XF86VidModeModeLine *)((char *)&info + sizeof(info.dotclock)),&_OldScreenMode, sizeof(XF86VidModeModeLine));
+		info.dotclock = _OldDotClock;
+
+		nlinfo("3D: Switching back mode to %dx%d", info.hdisplay, info.vdisplay);
+		XF86VidModeSwitchToMode(dpy, DefaultScreen(dpy), &info);
+		nlinfo("3D: Switching back viewport to %d,%d",_OldX, _OldY);
+		XF86VidModeSetViewPort(dpy, DefaultScreen(dpy), _OldX, _OldY);
+	}
+#endif // XF86VIDMODE
+
 	// Update WM hints (update size and disallow resizing)
 	XSizeHints size_hints;
 	size_hints.x = 0;
@@ -1642,8 +1673,6 @@
 		xev.xclient.data.l[1] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", false);
 		xev.xclient.data.l[2] = 0;
 		XSendEvent(dpy, DefaultRootWindow(dpy), false, SubstructureNotifyMask, &xev);
-
-		//TODO: Change X display mode
 	}
 	_FullScreen = !mode.Windowed;
 
# HG changeset patch
# User Thibaut Girka <thib@sitedethib.com>
# Date 1274526416 -7200
# Node ID 012af51b75110a22ec1fbebc6f685f6c19793e7e
# Parent  133efed1e38f4b10e4c47ba983fb587705ca8d6b
Refactor a bit

diff -r 133efed1e38f -r 012af51b7511 code/nel/src/3d/driver/opengl/driver_opengl.cpp
--- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp	Sat May 22 12:54:26 2010 +0200
+++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp	Sat May 22 13:06:56 2010 +0200
@@ -1141,66 +1141,7 @@
 //	XEvent event;
 //	XIfEvent(dpy, &event, WaitForNotify, (char *)this);
 
-#ifdef XF86VIDMODE
-	if (!mode.Windowed)
-	{
-		// Set window to the right size, map it to the display, and raise it to the front
-		XResizeWindow(dpy, win, width, height);
-		XMapRaised(dpy, win);
-		XRaiseWindow(dpy, win);
-
-		// grab the mouse and keyboard on the fullscreen window
-		if ((XGrabPointer(dpy, win, True, 0, GrabModeAsync, GrabModeAsync, win, None, CurrentTime) != GrabSuccess) ||
-			(XGrabKeyboard(dpy, win, True, GrabModeAsync, GrabModeAsync, CurrentTime) != 0) )
-		{
-			// Until I work out how to deal with this nicely, it just gives
-			// an error and exits the prorgam.
-			nlerror("Unable to grab keyboard and mouse");
-		}
-		else
-		{
-			// Save the old screen mode and dotclock and viewport
-			memset(&_OldScreenMode, 0, sizeof(_OldScreenMode));
-			XF86VidModeGetModeLine(dpy, DefaultScreen(dpy), &_OldDotClock, &_OldScreenMode);
-			XF86VidModeGetViewPort(dpy, DefaultScreen(dpy), &_OldX, &_OldY);
-
-			// Get a list of modes, search for an appropriate one.
-			XF86VidModeModeInfo **modes;
-			int nmodes;
-			if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &nmodes, &modes))
-			{
-				int mode_index = -1; // Gah, magic numbers all bad.
-				for (int i = 0; i < nmodes; i++)
-				{
-					nldebug("3D: Available mode - %dx%d", modes[i]->hdisplay, modes[i]->vdisplay);
-					if(modes[i]->hdisplay == width && modes[i]->vdisplay == height)
-					{
-						mode_index = i;
-						break;
-					}
-				}
-				// Switch to the mode
-				if (mode_index != -1)
-				{
-					if(XF86VidModeSwitchToMode(dpy, DefaultScreen(dpy), modes[mode_index]))
-					{
-						nlinfo("3D: Switching to mode %dx%d", modes[mode_index]->hdisplay, modes[mode_index]->vdisplay);
-						XF86VidModeSetViewPort(dpy, DefaultScreen(dpy), 0, 0);
-						_FullScreen = true;
-					}
-				}
-				else
-				{
-					// This is a problem, since we've nuked the border from
-					// window in the setup stage, until I work out how
-					// to get it back (recreate window? seems excessive)
-					nlerror("Couldn't find an appropriate mode %dx%d", width, height);
-				}
-			}
-		}
-	}
-
-#endif // XF86VIDMODE
+	setMode(mode);
 
 #endif // NL_OS_UNIX
 
@@ -1603,6 +1544,7 @@
 #ifdef XF86VIDMODE
 	if (!mode.Windowed)
 	{
+		// Store old mdoe in order to restore it when leaving fullscreen
 		if (mode.Windowed == _FullScreen)
 		{
 			memset(&_OldScreenMode, 0, sizeof(_OldScreenMode));
@@ -1610,6 +1552,7 @@
 			XF86VidModeGetViewPort(dpy, DefaultScreen(dpy), &_OldX, &_OldY);
 		}
 
+		// Find the requested mode and use it
 		XF86VidModeModeInfo **modes;
 		int nmodes;
 		if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &nmodes, &modes))
