diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2007-08-22 07:52:33 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2007-08-22 07:52:33 +0000 |
| commit | 8b3c16e6152a527f9aec1a88a9eed74119de7000 (patch) | |
| tree | f0bde5cea15e696e42cade06a3b12ff6b13acc57 /src/engine/external/glfw/lib/x11/x11_fullscreen.c | |
| parent | 9899666a7ce6679a3b9667ab09f615f4d0769c16 (diff) | |
| download | zcatch-8b3c16e6152a527f9aec1a88a9eed74119de7000.tar.gz zcatch-8b3c16e6152a527f9aec1a88a9eed74119de7000.zip | |
major engine cleanup. dependency on baselib removed. engine is now C code (not ansi tho). some other cruft removed aswell
Diffstat (limited to 'src/engine/external/glfw/lib/x11/x11_fullscreen.c')
| -rw-r--r-- | src/engine/external/glfw/lib/x11/x11_fullscreen.c | 524 |
1 files changed, 524 insertions, 0 deletions
diff --git a/src/engine/external/glfw/lib/x11/x11_fullscreen.c b/src/engine/external/glfw/lib/x11/x11_fullscreen.c new file mode 100644 index 00000000..2eb3cf75 --- /dev/null +++ b/src/engine/external/glfw/lib/x11/x11_fullscreen.c @@ -0,0 +1,524 @@ +//======================================================================== +// GLFW - An OpenGL framework +// File: x11_fullscreen.c +// Platform: X11 (Unix) +// API version: 2.6 +// WWW: http://glfw.sourceforge.net +//------------------------------------------------------------------------ +// Copyright (c) 2002-2006 Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + + +//************************************************************************ +//**** GLFW internal functions **** +//************************************************************************ + +//======================================================================== +// _glfwBPP2RGB() - Convert BPP to RGB bits (based on "best guess") +//======================================================================== + +static void _glfwBPP2RGB( int bpp, int *r, int *g, int *b ) +{ + int delta; + + // Special case: BPP = 32 (I don't think this is necessary for X11??) + if( bpp == 32 ) + bpp = 24; + + // Convert "bits per pixel" to red, green & blue sizes + *r = *g = *b = bpp / 3; + delta = bpp - (*r * 3); + if( delta >= 1 ) + { + *g = *g + 1; + } + if( delta == 2 ) + { + *r = *r + 1; + } +} + + +//======================================================================== +// Finds the video mode closest in size to the specified desired size +//======================================================================== + +int _glfwGetClosestVideoMode( int screen, int *width, int *height, int *rate ) +{ +#if defined( _GLFW_HAS_XRANDR ) + int i, match, bestmatch; + int sizecount, bestsize; + int ratecount, bestrate; + short *ratelist; + XRRScreenConfiguration *sc; + XRRScreenSize *sizelist; + + if( _glfwLibrary.XRandR.Available ) + { + sc = XRRGetScreenInfo( _glfwLibrary.Dpy, + RootWindow( _glfwLibrary.Dpy, screen ) ); + + sizelist = XRRConfigSizes( sc, &sizecount ); + + // Find the best matching mode + bestsize = -1; + bestmatch = 999999; + for( i = 0; i < sizecount; i++ ) + { + match = (*width - sizelist[i].width) * + (*width - sizelist[i].width) + + (*height - sizelist[i].height) * + (*height - sizelist[i].height); + if( match < bestmatch ) + { + bestmatch = match; + bestsize = i; + } + } + + if( bestsize != -1 ) + { + // Report width & height of best matching mode + *width = sizelist[bestsize].width; + *height = sizelist[bestsize].height; + + if( *rate > 0 ) + { + ratelist = XRRConfigRates( sc, bestsize, &ratecount ); + + bestrate = -1; + bestmatch = 999999; + for( i = 0; i < ratecount; i++ ) + { + match = abs( ratelist[i] - *rate ); + if( match < bestmatch ) + { + bestmatch = match; + bestrate = ratelist[i]; + } + } + + if( bestrate != -1 ) + { + *rate = bestrate; + } + } + } + + // Free modelist + XRRFreeScreenConfigInfo( sc ); + + if( bestsize != -1 ) + { + return bestsize; + } + } +#elif defined( _GLFW_HAS_XF86VIDMODE ) + XF86VidModeModeInfo **modelist; + int modecount, i, bestmode, bestmatch, match; + + // Use the XF86VidMode extension to control video resolution + if( _glfwLibrary.XF86VidMode.Available ) + { + // Get a list of all available display modes + XF86VidModeGetAllModeLines( _glfwLibrary.Dpy, screen, + &modecount, &modelist ); + + // Find the best matching mode + bestmode = -1; + bestmatch = 999999; + for( i = 0; i < modecount; i++ ) + { + match = (*width - modelist[i]->hdisplay) * + (*width - modelist[i]->hdisplay) + + (*height - modelist[i]->vdisplay) * + (*height - modelist[i]->vdisplay); + if( match < bestmatch ) + { + bestmatch = match; + bestmode = i; + } + } + + if( bestmode != -1 ) + { + // Report width & height of best matching mode + *width = modelist[ bestmode ]->hdisplay; + *h = modelist[ bestmode ]->vdisplay; + } + + // Free modelist + XFree( modelist ); + + if( bestmode != -1 ) + { + return bestmode; + } + } +#endif + + // Default: Simply use the screen resolution + *width = DisplayWidth( _glfwLibrary.Dpy, screen ); + *height = DisplayHeight( _glfwLibrary.Dpy, screen ); + + return 0; +} + + +//======================================================================== +// Change the current video mode +//======================================================================== + +void _glfwSetVideoModeMODE( int screen, int mode, int rate ) +{ +#if defined( _GLFW_HAS_XRANDR ) + XRRScreenConfiguration *sc; + Window root; + + if( _glfwLibrary.XRandR.Available ) + { + root = RootWindow( _glfwLibrary.Dpy, screen ); + sc = XRRGetScreenInfo( _glfwLibrary.Dpy, root ); + + // Remember old size and flag that we have changed the mode + if( !_glfwWin.FS.ModeChanged ) + { + _glfwWin.FS.OldSizeID = XRRConfigCurrentConfiguration( sc, &_glfwWin.FS.OldRotation ); + _glfwWin.FS.OldWidth = DisplayWidth( _glfwLibrary.Dpy, screen ); + _glfwWin.FS.OldHeight = DisplayHeight( _glfwLibrary.Dpy, screen ); + + _glfwWin.FS.ModeChanged = GL_TRUE; + } + + if( rate > 0 ) + { + // Set desired configuration + XRRSetScreenConfigAndRate( _glfwLibrary.Dpy, + sc, + root, + mode, + RR_Rotate_0, + (short) rate, + CurrentTime ); + } + else + { + // Set desired configuration + XRRSetScreenConfig( _glfwLibrary.Dpy, + sc, + root, + mode, + RR_Rotate_0, + CurrentTime ); + } + + XRRFreeScreenConfigInfo( sc ); + } +#elif defined( _GLFW_HAS_XF86VIDMODE ) + XF86VidModeModeInfo **modelist; + int modecount; + + // Use the XF86VidMode extension to control video resolution + if( _glfwLibrary.XF86VidMode.Available ) + { + // Get a list of all available display modes + XF86VidModeGetAllModeLines( _glfwLibrary.Dpy, screen, + &modecount, &modelist ); + + // Unlock mode switch if necessary + if( _glfwWin.FS.ModeChanged ) + { + XF86VidModeLockModeSwitch( _glfwLibrary.Dpy, screen, 0 ); + } + + // Change the video mode to the desired mode + XF86VidModeSwitchToMode( _glfwLibrary.Dpy, screen, + modelist[ mode ] ); + + // Set viewport to upper left corner (where our window will be) + XF86VidModeSetViewPort( _glfwLibrary.Dpy, screen, 0, 0 ); + + // Lock mode switch + XF86VidModeLockModeSwitch( _glfwLibrary.Dpy, screen, 1 ); + + // Remember old mode and flag that we have changed the mode + if( !_glfwWin.FS.ModeChanged ) + { + _glfwWin.FS.OldMode = *modelist[ 0 ]; + _glfwWin.FS.ModeChanged = GL_TRUE; + } + + // Free mode list + XFree( modelist ); + } +#endif +} + + +//======================================================================== +// Change the current video mode +//======================================================================== + +void _glfwSetVideoMode( int screen, int *width, int *height, int *rate ) +{ + int bestmode; + + // Find a best match mode + bestmode = _glfwGetClosestVideoMode( screen, width, height, rate ); + + // Change mode + _glfwSetVideoModeMODE( screen, bestmode, *rate ); +} + + + +//************************************************************************ +//**** Platform implementation functions **** +//************************************************************************ + +struct _glfwResolution { + int width; + int height; +}; + +//======================================================================== +// List available video modes +//======================================================================== + +int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount ) +{ + int count, k, l, r, g, b, rgba, gl; + int depth, screen; + Display *dpy; + XVisualInfo *vislist, dummy; + int viscount, rgbcount, rescount; + int *rgbarray; + struct _glfwResolution *resarray; +#if defined( _GLFW_HAS_XRANDR ) + XRRScreenConfiguration *sc; + XRRScreenSize *sizelist; + int sizecount; +#elif defined( _GLFW_HAS_XF86VIDMODE ) + XF86VidModeModeInfo **modelist; + int modecount, width, height; +#endif + + // Get display and screen + dpy = _glfwLibrary.Dpy; + screen = DefaultScreen( dpy ); + + // Get list of visuals + vislist = XGetVisualInfo( dpy, 0, &dummy, &viscount ); + if( vislist == NULL ) + { + return 0; + } + + rgbarray = (int*) malloc( sizeof(int) * viscount ); + rgbcount = 0; + + // Build RGB array + for( k = 0; k < viscount; k++ ) + { + // Does the visual support OpenGL & true color? + glXGetConfig( dpy, &vislist[k], GLX_USE_GL, &gl ); + glXGetConfig( dpy, &vislist[k], GLX_RGBA, &rgba ); + if( gl && rgba ) + { + // Get color depth for this visual + depth = vislist[k].depth; + + // Convert to RGB + _glfwBPP2RGB( depth, &r, &g, &b ); + depth = (r<<16) | (g<<8) | b; + + // Is this mode unique? + for( l = 0; l < rgbcount; l++ ) + { + if( depth == rgbarray[ l ] ) + { + break; + } + } + if( l >= rgbcount ) + { + rgbarray[ rgbcount ] = depth; + rgbcount++; + } + } + } + + rescount = 0; + resarray = NULL; + + // Build resolution array +#if defined( _GLFW_HAS_XRANDR ) + if( _glfwLibrary.XRandR.Available ) + { + sc = XRRGetScreenInfo( dpy, RootWindow( dpy, screen ) ); + sizelist = XRRConfigSizes( sc, &sizecount ); + + resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * sizecount ); + + for( k = 0; k < sizecount; k++ ) + { + resarray[ rescount ].width = sizelist[ k ].width; + resarray[ rescount ].height = sizelist[ k ].height; + rescount++; + } + + XRRFreeScreenConfigInfo( sc ); + } +#elif defined( _GLFW_HAS_XF86VIDMODE ) + if( _glfwLibrary.XF86VidMode.Available ) + { + XF86VidModeGetAllModeLines( dpy, screen, &modecount, &modelist ); + + resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * modecount ); + + for( k = 0; k < modecount; k++ ) + { + width = modelist[ k ]->hdisplay; + height = modelist[ k ]->vdisplay; + + // Is this mode unique? + for( l = 0; l < rescount; l++ ) + { + if( width == resarray[ l ].width && height == resarray[ l ].height ) + { + break; + } + } + if( l >= rescount ) + { + resarray[ rescount ].width = width; + resarray[ rescount ].height = height; + rescount++; + } + } + + XFree( modelist ); + } +#endif + + if( !resarray ) + { + rescount = 1; + resarray = (struct _glfwResolution*) malloc( sizeof(struct _glfwResolution) * rescount ); + + resarray[ 0 ].width = DisplayWidth( dpy, screen ); + resarray[ 0 ].height = DisplayHeight( dpy, screen ); + } + + // Build permutations of colors and resolutions + count = 0; + for( k = 0; k < rgbcount && count < maxcount; k++ ) + { + for( l = 0; l < rescount && count < maxcount; l++ ) + { + list[count].Width = resarray[ l ].width; + list[count].Height = resarray[ l ].height; + list[count].RedBits = (rgbarray[ k ] >> 16) & 255; + list[count].GreenBits = (rgbarray[ k ] >> 8) & 255; + list[count].BlueBits = rgbarray[ k ] & 255; + count++; + } + } + + // Free visuals list + XFree( vislist ); + + free( resarray ); + free( rgbarray ); + + return count; +} + + +//======================================================================== +// Get the desktop video mode +//======================================================================== + +void _glfwPlatformGetDesktopMode( GLFWvidmode *mode ) +{ + Display *dpy; + int bpp, screen; +#if defined( _GLFW_HAS_XF86VIDMODE ) + XF86VidModeModeInfo **modelist; + int modecount; +#endif + + // Get display and screen + dpy = _glfwLibrary.Dpy; + screen = DefaultScreen( dpy ); + + // Get display depth + bpp = DefaultDepth( dpy, screen ); + + // Convert BPP to RGB bits + _glfwBPP2RGB( bpp, &mode->RedBits, &mode->GreenBits, &mode->BlueBits ); + +#if defined( _GLFW_HAS_XRANDR ) + if( _glfwLibrary.XRandR.Available ) + { + if( _glfwWin.FS.ModeChanged ) + { + mode->Width = _glfwWin.FS.OldWidth; + mode->Height = _glfwWin.FS.OldHeight; + return; + } + } +#elif defined( _GLFW_HAS_XF86VIDMODE ) + if( _glfwLibrary.XF86VidMode.Available ) + { + if( _glfwWin.FS.ModeChanged ) + { + // The old (desktop) mode is stored in _glfwWin.FS.OldMode + mode->Width = _glfwWin.FS.OldMode.hdisplay; + mode->Height = _glfwWin.FS.OldMode.vdisplay; + } + else + { + // Use the XF86VidMode extension to get list of video modes + XF86VidModeGetAllModeLines( dpy, screen, &modecount, + &modelist ); + + // The first mode in the list is the current (desktio) mode + mode->Width = modelist[ 0 ]->hdisplay; + mode->Height = modelist[ 0 ]->vdisplay; + + // Free list + XFree( modelist ); + } + + return; + } +#endif + + // Get current display width and height + mode->Width = DisplayWidth( dpy, screen ); + mode->Height = DisplayHeight( dpy, screen ); +} + |