fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
  SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation)  

screen_xywh.cxx

Go to the documentation of this file.
00001 //
00002 // "$Id: screen_xywh.cxx 8210 2011-01-07 12:39:51Z AlbrechtS $"
00003 //
00004 // Screen/monitor bounding box API for the Fast Light Tool Kit (FLTK).
00005 //
00006 // Copyright 1998-2010 by Bill Spitzak and others.
00007 //
00008 // This library is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU Library General Public
00010 // License as published by the Free Software Foundation; either
00011 // version 2 of the License, or (at your option) any later version.
00012 //
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 // Library General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU Library General Public
00019 // License along with this library; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021 // USA.
00022 //
00023 // Please report all bugs and problems on the following page:
00024 //
00025 //     http://www.fltk.org/str.php
00026 //
00027 
00028 
00029 #include <FL/Fl.H>
00030 #include <FL/x.H>
00031 #include <config.h>
00032 
00033 
00034 // Number of screens...
00035 static int num_screens = 0;
00036 
00037 #ifdef WIN32
00038 #  if !defined(HMONITOR_DECLARED) && (_WIN32_WINNT < 0x0500)
00039 #    define COMPILE_MULTIMON_STUBS
00040 #    include <multimon.h>
00041 #  endif // !HMONITOR_DECLARED && _WIN32_WINNT < 0x0500
00042 
00043 // We go the much more difficult route of individually picking some multi-screen
00044 // functions from the USER32.DLL . If these functions are not available, we
00045 // will gracefully fall back to single monitor support.
00046 //
00047 // If we were to insist on the existence of "EnumDisplayMonitors" and 
00048 // "GetMonitorInfoA", it would be impossible to use FLTK on Windows 2000
00049 // before SP2 or earlier.
00050 
00051 // BOOL EnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM)
00052 typedef BOOL (WINAPI* fl_edm_func)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
00053 // BOOL GetMonitorInfo(HMONITOR, LPMONITORINFO)
00054 typedef BOOL (WINAPI* fl_gmi_func)(HMONITOR, LPMONITORINFO);
00055 
00056 static fl_gmi_func fl_gmi = NULL; // used to get a proc pointer for GetMonitorInfoA
00057 
00058 static RECT screens[16];
00059 static float dpi[16][2];
00060 
00061 static BOOL CALLBACK screen_cb(HMONITOR mon, HDC, LPRECT r, LPARAM) {
00062   if (num_screens >= 16) return TRUE;
00063 
00064   MONITORINFOEX mi;
00065   mi.cbSize = sizeof(mi);
00066 
00067 //  GetMonitorInfo(mon, &mi);
00068 //  (but we use our self-aquired function pointer instead)
00069   if (fl_gmi(mon, &mi)) {
00070     screens[num_screens] = mi.rcWork;
00071     
00072     // find the pixel size
00073     if (mi.cbSize == sizeof(mi)) {
00074       HDC screen = CreateDC(mi.szDevice, NULL, NULL, NULL);
00075       if (screen) {
00076         dpi[num_screens][0] = (float)GetDeviceCaps(screen, LOGPIXELSX);
00077         dpi[num_screens][1] = (float)GetDeviceCaps(screen, LOGPIXELSY);
00078       }
00079       ReleaseDC(0L, screen);
00080     }
00081     
00082     num_screens ++;
00083   }
00084   return TRUE;
00085 }
00086 
00087 static void screen_init() {
00088   // Since not all versions of Windows include multiple monitor support,
00089   // we do a run-time check for the required functions...
00090   HMODULE hMod = GetModuleHandle("USER32.DLL");
00091 
00092   if (hMod) {
00093     // check that EnumDisplayMonitors is available
00094     fl_edm_func fl_edm = (fl_edm_func)GetProcAddress(hMod, "EnumDisplayMonitors");
00095 
00096     if (fl_edm) {
00097       // We do have EnumDisplayMonitors, so lets find out how many monitors...
00098       num_screens = GetSystemMetrics(SM_CMONITORS);
00099 
00100 //      if (num_screens > 1) {
00101         // If there is more than 1 monitor, enumerate them...
00102         fl_gmi = (fl_gmi_func)GetProcAddress(hMod, "GetMonitorInfoA");
00103 
00104         if (fl_gmi) {
00105           // We have GetMonitorInfoA, enumerate all the screens...
00106           num_screens = 0;
00107 //        EnumDisplayMonitors(0,0,screen_cb,0);
00108 //        (but we use our self-aquired function pointer instead)
00109           fl_edm(0, 0, screen_cb, 0);
00110           return;
00111         }
00112 //      }
00113     }
00114   }
00115 
00116   // If we get here, assume we have 1 monitor...
00117   num_screens = 1;
00118 }
00119 #elif defined(__APPLE__)
00120 static XRectangle screens[16];
00121 static float dpi[16];
00122 
00123 static void screen_init() {
00124   num_screens = Fl_X::screen_init(screens, dpi);
00125 }
00126 #elif HAVE_XINERAMA
00127 #  include <X11/extensions/Xinerama.h>
00128 
00129 // Screen data...
00130 static XineramaScreenInfo *screens;
00131 static float dpi[16][2];
00132 
00133 static void screen_init() {
00134   if (!fl_display) fl_open_display();
00135 
00136   if (XineramaIsActive(fl_display)) {
00137     screens = XineramaQueryScreens(fl_display, &num_screens);
00138     int i;
00139     for (i=0; i<num_screens; i++) {
00140       int mm = DisplayWidthMM(fl_display, i);
00141       dpi[i][0] = mm ? screens[i].width*25.4f/mm : 0.0f;
00142       mm = DisplayHeightMM(fl_display, fl_screen);
00143       dpi[i][1] = mm ? screens[i].height*25.4f/mm : dpi[i][0];
00144     }
00145   } else { // ! XineramaIsActive()
00146     num_screens = 1;
00147     int mm = DisplayWidthMM(fl_display, fl_screen);
00148     dpi[0][0] = mm ? Fl::w()*25.4f/mm : 0.0f;
00149     mm = DisplayHeightMM(fl_display, fl_screen);
00150     dpi[0][1] = mm ? Fl::h()*25.4f/mm : dpi[0][0];
00151   }
00152 }
00153 #else
00154 static float dpi[2];
00155 static void screen_init() {
00156   num_screens = 1;
00157   if (!fl_display) fl_open_display();
00158   int mm = DisplayWidthMM(fl_display, fl_screen);
00159   dpi[0] = mm ? Fl::w()*25.4f/mm : 0.0f;
00160   mm = DisplayHeightMM(fl_display, fl_screen);
00161   dpi[1] = mm ? Fl::h()*25.4f/mm : dpi[0];  
00162 }
00163 #endif // WIN32
00164 
00165 
00169 int Fl::screen_count() {
00170   if (!num_screens) screen_init();
00171 
00172   return num_screens;
00173 }
00174 
00181 void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) {
00182   if (!num_screens) screen_init();
00183 
00184 #ifdef WIN32
00185   if (num_screens > 1) {
00186     int i;
00187 
00188     for (i = 0; i < num_screens; i ++) {
00189       if (mx >= screens[i].left && mx < screens[i].right &&
00190           my >= screens[i].top && my < screens[i].bottom) {
00191         X = screens[i].left;
00192         Y = screens[i].top;
00193         W = screens[i].right - screens[i].left;
00194         H = screens[i].bottom - screens[i].top;
00195         return;
00196       }
00197     }
00198   }
00199 #elif defined(__APPLE__)
00200   if (num_screens > 1) {
00201     int i;
00202 
00203     for (i = 0; i < num_screens; i ++) {
00204       if (mx >= screens[i].x &&
00205           mx < (screens[i].x + screens[i].width) &&
00206           my >= screens[i].y &&
00207           my < (screens[i].y + screens[i].height)) {
00208         X = screens[i].x;
00209         Y = screens[i].y;
00210         W = screens[i].width;
00211         H = screens[i].height;
00212         return;
00213       }
00214     }
00215   }
00216 #elif HAVE_XINERAMA
00217   if (num_screens > 1) {
00218     int i;
00219 
00220     for (i = 0; i < num_screens; i ++) {
00221       if (mx >= screens[i].x_org &&
00222           mx < (screens[i].x_org + screens[i].width) &&
00223           my >= screens[i].y_org &&
00224           my < (screens[i].y_org + screens[i].height)) {
00225         X = screens[i].x_org;
00226         Y = screens[i].y_org;
00227         W = screens[i].width;
00228         H = screens[i].height;
00229         return;
00230       }
00231     }
00232   }
00233 #else
00234   (void)mx;
00235   (void)my;
00236 #endif // WIN32
00237 
00238   X = Fl::x();
00239   Y = Fl::y();
00240   W = Fl::w();
00241   H = Fl::h();
00242 }
00243 
00250 void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int n) {
00251   if (!num_screens) screen_init();
00252 
00253 #ifdef WIN32
00254   if (num_screens > 1 && n >= 0 && n < num_screens) {
00255     X = screens[n].left;
00256     Y = screens[n].top;
00257     W = screens[n].right - screens[n].left;
00258     H = screens[n].bottom - screens[n].top;
00259     return;
00260   }
00261 #elif defined(__APPLE__)
00262   if (num_screens > 1 && n >= 0 && n < num_screens) {
00263     X = screens[n].x;
00264     Y = screens[n].y;
00265     W = screens[n].width;
00266     H = screens[n].height;
00267     return;
00268   }
00269 #elif HAVE_XINERAMA
00270   if (num_screens > 1 && n >= 0 && n < num_screens) {
00271     X = screens[n].x_org;
00272     Y = screens[n].y_org;
00273     W = screens[n].width;
00274     H = screens[n].height;
00275     return;
00276   }
00277 #else
00278   (void)n;
00279 #endif // WIN32
00280 
00281   X = Fl::x();
00282   Y = Fl::y();
00283   W = Fl::w();
00284   H = Fl::h();
00285 }
00286 
00287 
00294 void Fl::screen_dpi(float &h, float &v, int n)
00295 {
00296   if (!num_screens) screen_init();
00297   h = v = 0.0f;
00298   
00299 #ifdef WIN32
00300   if (n >= 0 && n < num_screens) {
00301     h = float(dpi[n][0]);
00302     v = float(dpi[n][1]);
00303   }
00304 #elif defined(__APPLE__)
00305   if (n >= 0 && n < num_screens) {
00306     h = v = dpi[n];
00307   }
00308 #elif HAVE_XINERAMA
00309   if (n >= 0 && n < num_screens) {
00310     h = dpi[n][0];
00311     v = dpi[n][1];
00312   }
00313 #else
00314   if (n >= 0 && n < num_screens) {
00315     h = dpi[0];
00316     v = dpi[1];
00317   }
00318 #endif // WIN32
00319 }
00320 
00321 
00322 
00323 //
00324 // End of "$Id: screen_xywh.cxx 8210 2011-01-07 12:39:51Z AlbrechtS $".
00325 //