Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

x11_resolution.cpp

Go to the documentation of this file.
00001 /*
00002         $Id: x11_resolution.cpp,v 1.1 2001/03/06 15:09:19 mbn Exp $
00003 
00004         ------------------------------------------------------------------------
00005         ClanLib, the platform independent game SDK.
00006 
00007         This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE
00008         version 2. See COPYING for details.
00009 
00010         For a total list of contributers see CREDITS.
00011 
00012         ------------------------------------------------------------------------
00013 */
00014 
00015 #include "Core/precomp.h"
00016 
00017 #ifdef USE_X11
00018 #include "API/Core/System/cl_assert.h"
00019 #include "x11_resolution.h"
00020 
00021 CL_X11Resolution::CL_X11Resolution(Display *dpy, int scr)
00022 {
00023         this->dpy = dpy;
00024         this->scr = scr;
00025         mode_set = false;
00026         has_vidmode_extension = false;
00027 
00028 #ifdef USE_VIDMODE
00029         int dummy;
00030         has_vidmode_extension =
00031                 XF86VidModeQueryExtension(dpy, &dummy, &dummy) == True ? true : false;
00032 #endif
00033 
00034         cur_width = DisplayWidth(dpy, scr);
00035         cur_height = DisplayHeight(dpy, scr);
00036 }
00037 
00038 CL_X11Resolution::~CL_X11Resolution()
00039 {
00040         restore_mode();
00041 }
00042         
00043 void CL_X11Resolution::set_mode(int width, int height)
00044 {
00045 #ifdef USE_VIDMODE
00046         if (!has_vidmode_extension) return;
00047 
00048         if (!mode_set) // save original mode
00049         {
00050                 memset(&orig_mode, 0, sizeof(orig_mode));
00051                 memset(&orig_view, 0, sizeof(orig_view));
00052 
00053                 // Get mode info. (missing XF86VidModeGetModeInfo)
00054                 XF86VidModeModeLine *l = (XF86VidModeModeLine*)((char*) &orig_mode + sizeof orig_mode.dotclock);
00055                 cl_assert(XF86VidModeGetModeLine(dpy, scr, (int*) &orig_mode.dotclock, l) == True);
00056 
00057                 // Get the viewport position.
00058                 cl_assert(XF86VidModeGetViewPort(dpy, scr, &orig_view.x, &orig_view.y) == True);
00059         }
00060         
00061         XF86VidModeModeInfo mode = get_best_mode(width, height);
00062 
00063         if ((mode.vdisplay != 0) && (mode.hdisplay != 0))
00064         {
00065                 // Warping the mouse to the window (don't use SetViewPort - buggy)
00066                 XWarpPointer(dpy, None, RootWindow(dpy, scr), 0, 0, 0, 0, 0, 0);
00067                 cl_assert(XF86VidModeSwitchToMode(dpy, scr, &mode) == True);
00068                 XWarpPointer(dpy, None, RootWindow(dpy, scr), 0, 0, 0, 0, 0, 0);        
00069                 // cl_assert(XF86VidModeSetViewPort(dpy, scr, 0, 0) == True);
00070 
00071                 cur_width = mode.hdisplay;
00072                 cur_height = mode.vdisplay;
00073                 mode_set = true;
00074                 XSync(dpy, True);
00075         }
00076 #endif
00077 }
00078 
00079 void CL_X11Resolution::restore_mode()
00080 {
00081 #ifdef USE_VIDMODE
00082         if (!has_vidmode_extension) return;
00083         if (!mode_set) return;
00084         
00085         if (cur_width != orig_mode.hdisplay || cur_height != orig_mode.vdisplay)
00086         {
00087                 cl_assert(XF86VidModeSwitchToMode(dpy, scr, &orig_mode) == True);
00088         }
00089         if (orig_view.x != 0 || orig_view.y != 0)
00090         {
00091 #ifdef DEBUG
00092                 std::cout << "setting viewport" << std::endl;
00093 #endif
00094                 cl_assert(XF86VidModeSetViewPort(dpy, scr, orig_view.x, orig_view.y) == True);
00095         }
00096         cur_width = DisplayWidth(dpy, scr);
00097         cur_height = DisplayHeight(dpy, scr);
00098         
00099         mode_set = false;
00100         XSync(dpy, True);
00101 #endif
00102 }
00103 
00104 int CL_X11Resolution::get_width() const
00105 {
00106         return cur_width;
00107 }
00108 
00109 int CL_X11Resolution::get_height() const
00110 {
00111         return cur_height;
00112 }
00113 
00114 #ifdef USE_VIDMODE
00115 
00116 // needed by qsort
00117 static int cmpmodes(const void *va, const void *vb)
00118 {
00119         XF86VidModeModeInfo *a = *(XF86VidModeModeInfo**)va;
00120         XF86VidModeModeInfo *b = *(XF86VidModeModeInfo**)vb;
00121         if(a->hdisplay > b->hdisplay)
00122                 return -1;
00123         return b->vdisplay - a->vdisplay;
00124 }
00125 
00126 XF86VidModeModeInfo CL_X11Resolution::get_best_mode(int width, int height)
00127 {
00128         XF86VidModeModeInfo **modes;
00129         XF86VidModeModeLine mode;
00130         int nmodes;
00131         int i;
00132 
00133         if ( XF86VidModeGetModeLine(dpy, scr, &i, &mode) &&
00134                 XF86VidModeGetAllModeLines(dpy, scr, &nmodes, &modes))
00135         {
00136                 qsort(modes, nmodes, sizeof *modes, cmpmodes);
00137 #ifdef DEBUG
00138                 cout << "Available modes:" << endl;
00139                 for (i=0; i<nmodes; ++i) 
00140                 {
00141                         cout << "Mode " << i << " : " <<  modes[i]->hdisplay << "x" <<  modes[i]->vdisplay << endl;
00142                 }
00143 #endif
00144                 for (i=nmodes-1; i>= 0; --i) 
00145                 {
00146                         if ( (modes[i]->hdisplay >= width) &&
00147                              (modes[i]->vdisplay >= height) )
00148                                 break;
00149                 }
00150                 if (i>=0)
00151                 {
00152                         if ( (modes[i]->hdisplay != mode.hdisplay) ||
00153                              (modes[i]->vdisplay != mode.vdisplay) ) 
00154                         {
00155                                 return *modes[i];
00156                         }
00157                         XFree(modes);
00158                 }
00159         }
00160         
00161         XF86VidModeModeInfo dummy_mode;
00162         memset(&dummy_mode, 0, sizeof(dummy_mode));
00163         return dummy_mode;
00164 }
00165 #endif /* USE_VIDMODE */
00166 
00167 #endif

Generated at Wed Apr 4 19:54:04 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001