Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Video mode switching 00024 * Copyright (C) 1997-2001 Id Software, Inc. 00025 * Ported from Quake 2 by Alex Fraser <alex@phatcore.com> 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00034 #ifdef WITH_X11_XF86VMODE 00035 # include <X11/Xlib.h> 00036 # include <X11/extensions/xf86vmode.h> 00037 #endif 00038 00039 #include "GHOST_DisplayManagerX11.h" 00040 #include "GHOST_SystemX11.h" 00041 00042 00043 00044 GHOST_DisplayManagerX11:: 00045 GHOST_DisplayManagerX11( 00046 GHOST_SystemX11 *system 00047 ) : 00048 GHOST_DisplayManager(), 00049 m_system(system) 00050 { 00051 //nothing to do. 00052 } 00053 00054 GHOST_TSuccess 00055 GHOST_DisplayManagerX11:: 00056 getNumDisplays( 00057 GHOST_TUns8& numDisplays 00058 ) const{ 00059 numDisplays = m_system->getNumDisplays(); 00060 return GHOST_kSuccess; 00061 } 00062 00063 00064 GHOST_TSuccess 00065 GHOST_DisplayManagerX11:: 00066 getNumDisplaySettings( 00067 GHOST_TUns8 display, 00068 GHOST_TInt32& numSettings 00069 ) const{ 00070 #ifdef WITH_X11_XF86VMODE 00071 int majorVersion, minorVersion; 00072 XF86VidModeModeInfo **vidmodes; 00073 Display *dpy = m_system->getXDisplay(); 00074 00075 GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); 00076 00077 if (dpy == NULL) 00078 return GHOST_kFailure; 00079 00080 majorVersion = minorVersion = 0; 00081 if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { 00082 fprintf(stderr, "Error: XF86VidMode extension missing!\n"); 00083 return GHOST_kFailure; 00084 } 00085 00086 /* The X11 man page says vidmodes needs to be freed, but doing so causes a 00087 * segfault. - z0r */ 00088 XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes); 00089 00090 #else 00091 // We only have one X11 setting at the moment. 00092 GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); 00093 numSettings = GHOST_TInt32(1); 00094 #endif 00095 00096 return GHOST_kSuccess; 00097 } 00098 00099 GHOST_TSuccess 00100 GHOST_DisplayManagerX11:: 00101 getDisplaySetting( 00102 GHOST_TUns8 display, 00103 GHOST_TInt32 index, 00104 GHOST_DisplaySetting& setting 00105 ) const { 00106 00107 #ifdef WITH_X11_XF86VMODE 00108 int majorVersion, minorVersion; 00109 XF86VidModeModeInfo **vidmodes; 00110 Display *dpy = m_system->getXDisplay(); 00111 int numSettings; 00112 00113 GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); 00114 00115 if (dpy == NULL) 00116 return GHOST_kFailure; 00117 00118 majorVersion = minorVersion = 0; 00119 if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { 00120 fprintf(stderr, "Error: XF86VidMode extension missing!\n"); 00121 return GHOST_kFailure; 00122 } 00123 00124 /* The X11 man page says vidmodes needs to be freed, but doing so causes a 00125 * segfault. - z0r */ 00126 XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &numSettings, &vidmodes); 00127 GHOST_ASSERT(index < numSettings, "Requested setting outside of valid range.\n"); 00128 00129 setting.xPixels = vidmodes[index]->hdisplay; 00130 setting.yPixels = vidmodes[index]->vdisplay; 00131 setting.bpp = DefaultDepth(dpy,DefaultScreen(dpy)); 00132 00133 #else 00134 GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); 00135 GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n"); 00136 00137 Display * x_display = m_system->getXDisplay(); 00138 00139 if (x_display == NULL) { 00140 return GHOST_kFailure; 00141 } 00142 00143 setting.xPixels = DisplayWidth(x_display, DefaultScreen(x_display)); 00144 setting.yPixels = DisplayHeight(x_display, DefaultScreen(x_display)); 00145 setting.bpp = DefaultDepth(x_display,DefaultScreen(x_display)); 00146 #endif 00147 00148 // Don't think it's possible to get this value from X! 00149 // So let's guess!! 00150 setting.frequency = 60; 00151 00152 return GHOST_kSuccess; 00153 } 00154 00155 GHOST_TSuccess 00156 GHOST_DisplayManagerX11:: 00157 getCurrentDisplaySetting( 00158 GHOST_TUns8 display, 00159 GHOST_DisplaySetting& setting 00160 ) const { 00161 /* According to the xf86vidmodegetallmodelines man page, 00162 * "The first element of the array corresponds to the current video mode." 00163 */ 00164 return getDisplaySetting(display,GHOST_TInt32(0),setting); 00165 } 00166 00167 00168 GHOST_TSuccess 00169 GHOST_DisplayManagerX11:: 00170 setCurrentDisplaySetting( 00171 GHOST_TUns8 display, 00172 const GHOST_DisplaySetting& setting 00173 ){ 00174 #ifdef WITH_X11_XF86VMODE 00175 // 00176 // Mode switching code ported from Quake 2: 00177 // ftp://ftp.idsoftware.com/idstuff/source/q2source-3.21.zip 00178 // See linux/gl_glx.c:GLimp_SetMode 00179 // 00180 int majorVersion, minorVersion; 00181 XF86VidModeModeInfo **vidmodes; 00182 Display *dpy = m_system->getXDisplay(); 00183 int scrnum, num_vidmodes; 00184 int best_fit, best_dist, dist, x, y; 00185 00186 if (dpy == NULL) 00187 return GHOST_kFailure; 00188 00189 scrnum = DefaultScreen(dpy); 00190 00191 // Get video mode list 00192 majorVersion = minorVersion = 0; 00193 if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) { 00194 fprintf(stderr, "Error: XF86VidMode extension missing!\n"); 00195 return GHOST_kFailure; 00196 } 00197 # ifdef _DEBUG 00198 printf("Using XFree86-VidModeExtension Version %d.%d\n", 00199 majorVersion, minorVersion); 00200 # endif 00201 00202 /* The X11 man page says vidmodes needs to be freed, but doing so causes a 00203 * segfault. - z0r */ 00204 XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes); 00205 00206 best_dist = 9999999; 00207 best_fit = -1; 00208 00209 for (int i = 0; i < num_vidmodes; i++) { 00210 if (setting.xPixels > vidmodes[i]->hdisplay || 00211 setting.yPixels > vidmodes[i]->vdisplay) 00212 continue; 00213 00214 x = setting.xPixels - vidmodes[i]->hdisplay; 00215 y = setting.yPixels - vidmodes[i]->vdisplay; 00216 dist = (x * x) + (y * y); 00217 if (dist < best_dist) { 00218 best_dist = dist; 00219 best_fit = i; 00220 } 00221 } 00222 00223 if (best_fit != -1) { 00224 # ifdef _DEBUG 00225 int actualWidth, actualHeight; 00226 actualWidth = vidmodes[best_fit]->hdisplay; 00227 actualHeight = vidmodes[best_fit]->vdisplay; 00228 printf("Switching to video mode %dx%d\n", 00229 actualWidth, actualHeight); 00230 # endif 00231 00232 // change to the mode 00233 XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); 00234 00235 // Move the viewport to top left 00236 XF86VidModeSetViewPort(dpy, scrnum, 0, 0); 00237 } else 00238 return GHOST_kFailure; 00239 00240 XFlush(dpy); 00241 return GHOST_kSuccess; 00242 00243 #else 00244 // Just pretend the request was successful. 00245 return GHOST_kSuccess; 00246 #endif 00247 } 00248 00249 00250 00251