|
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) ![]() |
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 //