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 * Contributor(s): Campbell Barton 00019 * 00020 * Mode switching 00021 * Copyright (C) 1997-2001 Id Software, Inc. 00022 * Copyright (c) 1993-2011 Tim Riker 00023 * Copyright (C) 2012 Alex Fraser 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00032 #include "GHOST_SystemSDL.h" 00033 #include "GHOST_DisplayManagerSDL.h" 00034 00035 GHOST_DisplayManagerSDL::GHOST_DisplayManagerSDL(GHOST_SystemSDL *system) 00036 : 00037 GHOST_DisplayManager(), 00038 m_system(system) 00039 { 00040 /* do nothing */ 00041 } 00042 00043 GHOST_TSuccess 00044 GHOST_DisplayManagerSDL::getNumDisplays(GHOST_TUns8& numDisplays) const 00045 { 00046 numDisplays= SDL_GetNumVideoDisplays(); 00047 return GHOST_kSuccess; 00048 } 00049 00050 00051 GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplaySettings(GHOST_TUns8 display, 00052 GHOST_TInt32& numSettings) const 00053 { 00054 GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); 00055 int i; 00056 SDL_Rect **vidmodes; 00057 00058 vidmodes = SDL_ListModes(NULL, SDL_HWSURFACE | SDL_OPENGL | 00059 SDL_FULLSCREEN | SDL_HWPALETTE); 00060 if (!vidmodes) { 00061 fprintf(stderr, "Could not get available video modes: %s.\n", 00062 SDL_GetError()); 00063 return GHOST_kFailure; 00064 } 00065 for (i = 0; vidmodes[i]; i++); 00066 numSettings = GHOST_TInt32(i); 00067 00068 return GHOST_kSuccess; 00069 } 00070 00071 GHOST_TSuccess 00072 GHOST_DisplayManagerSDL::getDisplaySetting(GHOST_TUns8 display, 00073 GHOST_TInt32 index, 00074 GHOST_DisplaySetting& setting) const 00075 { 00076 GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); 00077 00078 int i; 00079 SDL_Rect **vidmodes; 00080 /* NULL is passed in here to get the modes for the current bit depth. 00081 * Other bit depths may be possible; in that case, an SDL_PixelFormat struct 00082 * should be passed in. To get a complete profile, all possible bit depths 00083 * would need to be iterated over. - z0r */ 00084 vidmodes = SDL_ListModes(NULL, SDL_HWSURFACE | SDL_OPENGL | 00085 SDL_FULLSCREEN | SDL_HWPALETTE); 00086 if (!vidmodes) { 00087 fprintf(stderr, "Could not get available video modes: %s.\n", 00088 SDL_GetError()); 00089 return GHOST_kFailure; 00090 } 00091 for (i = 0; vidmodes[i]; i++); 00092 GHOST_ASSERT(index < i, "Requested setting outside of valid range.\n"); 00093 00094 setting.xPixels = vidmodes[index]->w; 00095 setting.yPixels = vidmodes[index]->h; 00096 00097 SDL_Surface *surf; 00098 surf = SDL_GetVideoSurface(); 00099 if (surf == NULL) { 00100 fprintf(stderr, "Getting display setting: %s\n", SDL_GetError()); 00101 /* Just guess the bit depth */ 00102 setting.bpp = 32; 00103 } else { 00104 setting.bpp = surf->format->BitsPerPixel; 00105 } 00106 /* Just guess the frequency :( */ 00107 setting.frequency = 60; 00108 00109 return GHOST_kSuccess; 00110 } 00111 00112 GHOST_TSuccess 00113 GHOST_DisplayManagerSDL::getCurrentDisplaySetting(GHOST_TUns8 display, 00114 GHOST_DisplaySetting& setting) const 00115 { 00116 SDL_Surface *surf; 00117 const SDL_VideoInfo *info; 00118 00119 /* Note: not using SDL_GetDesktopDisplayMode because that does not return 00120 * the current mode. Try to use GetVideoSurface first, as it seems more 00121 * accurate. If that fails, try other methods. - z0r */ 00122 surf = SDL_GetVideoSurface(); 00123 00124 if (surf != NULL) { 00125 setting.xPixels = surf->w; 00126 setting.yPixels = surf->h; 00127 setting.bpp = surf->format->BitsPerPixel; 00128 /* Just guess the frequency :( */ 00129 setting.frequency = 60; 00130 } else { 00131 /* This may happen if the surface hasn't been created yet, e.g. on 00132 * application startup. */ 00133 info = SDL_GetVideoInfo(); 00134 setting.xPixels = info->current_w; 00135 setting.yPixels = info->current_h; 00136 setting.bpp = info->vfmt->BitsPerPixel; 00137 /* Just guess the frequency :( */ 00138 setting.frequency = 60; 00139 } 00140 00141 return GHOST_kSuccess; 00142 } 00143 00144 GHOST_TSuccess 00145 GHOST_DisplayManagerSDL:: setCurrentDisplaySetting(GHOST_TUns8 display, 00146 const GHOST_DisplaySetting& setting) 00147 { 00148 00149 /* 00150 * Mode switching code ported from Quake 2 version 3.21 and bzflag version 00151 * 2.4.0: 00152 * ftp://ftp.idsoftware.com/idstuff/source/q2source-3.21.zip 00153 * See linux/gl_glx.c:GLimp_SetMode 00154 * http://wiki.bzflag.org/BZFlag_Source 00155 * See src/platform/SDLDisplay.cxx:SDLDisplay and createWindow 00156 */ 00157 SDL_Surface *surf; 00158 int best_fit, best_dist, dist, x, y; 00159 00160 SDL_Rect **vidmodes = SDL_ListModes(NULL, SDL_HWSURFACE | SDL_OPENGL | 00161 SDL_FULLSCREEN | SDL_HWPALETTE); 00162 if (!vidmodes) { 00163 fprintf(stderr, "Could not get available video modes: %s.\n", 00164 SDL_GetError()); 00165 } 00166 00167 best_dist = 9999999; 00168 best_fit = -1; 00169 00170 if (vidmodes == (SDL_Rect **) -1) { 00171 /* Any mode is OK. */ 00172 x = setting.xPixels; 00173 y = setting.yPixels; 00174 } else { 00175 for (int i = 0; vidmodes[i]; i++) { 00176 if (setting.xPixels > vidmodes[i]->w || 00177 setting.yPixels > vidmodes[i]->h) 00178 continue; 00179 00180 x = setting.xPixels - vidmodes[i]->w; 00181 y = setting.yPixels - vidmodes[i]->h; 00182 dist = (x * x) + (y * y); 00183 if (dist < best_dist) { 00184 best_dist = dist; 00185 best_fit = i; 00186 } 00187 } 00188 00189 if (best_fit == -1) 00190 return GHOST_kFailure; 00191 00192 x = vidmodes[best_fit]->w; 00193 y = vidmodes[best_fit]->h; 00194 } 00195 00196 # ifdef _DEBUG 00197 printf("Switching to video mode %dx%d\n", x, y); 00198 # endif 00199 00200 // limit us to the main display 00201 static char singleDisplayEnv[] = "SDL_SINGLEDISPLAY=1"; 00202 putenv(singleDisplayEnv); 00203 00204 // change to the mode 00205 surf = SDL_SetVideoMode(x, y, setting.bpp, SDL_OPENGL | SDL_FULLSCREEN); 00206 if (surf == NULL) { 00207 fprintf(stderr, "Could not set video mode: %s.\n", SDL_GetError()); 00208 return GHOST_kFailure; 00209 } 00210 00211 return GHOST_kSuccess; 00212 }