56
56
static fl_gmi_func fl_gmi = NULL; // used to get a proc pointer for GetMonitorInfoA
58
58
static RECT screens[16];
59
static float dpi[16][2];
60
61
static BOOL CALLBACK screen_cb(HMONITOR mon, HDC, LPRECT r, LPARAM) {
61
62
if (num_screens >= 16) return TRUE;
64
65
mi.cbSize = sizeof(mi);
66
67
// GetMonitorInfo(mon, &mi);
67
68
// (but we use our self-aquired function pointer instead)
68
69
if (fl_gmi(mon, &mi)) {
69
screens[num_screens] = mi.rcWork;
70
screens[num_screens] = mi.rcMonitor;
72
// find the pixel size
73
if (mi.cbSize == sizeof(mi)) {
74
HDC screen = CreateDC(mi.szDevice, NULL, NULL, NULL);
76
dpi[num_screens][0] = (float)GetDeviceCaps(screen, LOGPIXELSX);
77
dpi[num_screens][1] = (float)GetDeviceCaps(screen, LOGPIXELSY);
79
ReleaseDC(0L, screen);
75
87
static void screen_init() {
76
89
// Since not all versions of Windows include multiple monitor support,
77
90
// we do a run-time check for the required functions...
78
91
HMODULE hMod = GetModuleHandle("USER32.DLL");
85
98
// We do have EnumDisplayMonitors, so lets find out how many monitors...
86
99
num_screens = GetSystemMetrics(SM_CMONITORS);
88
if (num_screens > 1) {
101
// if (num_screens > 1) {
89
102
// If there is more than 1 monitor, enumerate them...
90
103
fl_gmi = (fl_gmi_func)GetProcAddress(hMod, "GetMonitorInfoA");
93
106
// We have GetMonitorInfoA, enumerate all the screens...
95
107
// EnumDisplayMonitors(0,0,screen_cb,0);
96
108
// (but we use our self-aquired function pointer instead)
97
109
fl_edm(0, 0, screen_cb, 0);
104
116
// If we get here, assume we have 1 monitor...
120
screens[0].right = GetSystemMetrics(SM_CXSCREEN);
121
screens[0].bottom = GetSystemMetrics(SM_CYSCREEN);
107
123
#elif defined(__APPLE__)
108
XRectangle screens[16];
124
static XRectangle screens[16];
125
static float dpi_h[16];
126
static float dpi_v[16];
110
extern int MACscreen_init(XRectangle screens[]);
111
128
static void screen_init() {
112
num_screens = MACscreen_init(screens);
129
CGDirectDisplayID displays[16];
130
CGDisplayCount count, i;
132
CGGetActiveDisplayList(16, displays, &count);
133
for( i = 0; i < count; i++) {
134
r = CGDisplayBounds(displays[i]);
135
screens[i].x = int(r.origin.x);
136
screens[i].y = int(r.origin.y);
137
screens[i].width = int(r.size.width);
138
screens[i].height = int(r.size.height);
139
CGSize s = CGDisplayScreenSize(displays[i]);
140
dpi_h[i] = screens[i].width / (s.width/25.4);
141
dpi_v[i] = screens[i].height / (s.height/25.4);
114
145
#elif HAVE_XINERAMA
115
146
# include <X11/extensions/Xinerama.h>
117
148
// Screen data...
118
149
static XineramaScreenInfo *screens;
150
static float dpi[16][2];
120
152
static void screen_init() {
121
153
if (!fl_display) fl_open_display();
123
155
if (XineramaIsActive(fl_display)) {
124
156
screens = XineramaQueryScreens(fl_display, &num_screens);
125
} else num_screens = 1;
158
// Xlib and Xinerama may disagree on the screen count. Sigh...
159
// Use the minimum of the reported counts.
160
// Use the previous screen's info for non-existent ones.
161
int sc = ScreenCount(fl_display); // Xlib screen count
162
for (i=0; i<num_screens; i++) {
163
int mm = (i < sc) ? DisplayWidthMM(fl_display, i) : 0;
164
dpi[i][0] = mm ? screens[i].width*25.4f/mm : (i > 0) ? dpi[i-1][0] : 0.0f;
165
mm = (i < sc) ? DisplayHeightMM(fl_display, i) : 0;
166
dpi[i][1] = mm ? screens[i].height*25.4f/mm : (i > 0) ? dpi[i-1][1] : 0.0f;
168
} else { // ! XineramaIsActive()
170
int mm = DisplayWidthMM(fl_display, fl_screen);
171
dpi[0][0] = mm ? Fl::w()*25.4f/mm : 0.0f;
172
mm = DisplayHeightMM(fl_display, fl_screen);
173
dpi[0][1] = mm ? Fl::h()*25.4f/mm : dpi[0][0];
128
178
static void screen_init() {
180
if (!fl_display) fl_open_display();
181
int mm = DisplayWidthMM(fl_display, fl_screen);
182
dpi[0] = mm ? Fl::w()*25.4f/mm : 0.0f;
183
mm = DisplayHeightMM(fl_display, fl_screen);
184
dpi[1] = mm ? Fl::h()*25.4f/mm : dpi[0];
147
202
\param[in] mx, my the absolute screen position
149
204
void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) {
150
if (!num_screens) screen_init();
153
if (num_screens > 1) {
156
for (i = 0; i < num_screens; i ++) {
157
if (mx >= screens[i].left && mx < screens[i].right &&
158
my >= screens[i].top && my < screens[i].bottom) {
161
W = screens[i].right - screens[i].left;
162
H = screens[i].bottom - screens[i].top;
167
#elif defined(__APPLE__)
168
if (num_screens > 1) {
171
for (i = 0; i < num_screens; i ++) {
172
if (mx >= screens[i].x &&
173
mx < (screens[i].x + screens[i].width) &&
174
my >= screens[i].y &&
175
my < (screens[i].y + screens[i].height)) {
178
W = screens[i].width;
179
H = screens[i].height;
185
if (num_screens > 1) {
188
for (i = 0; i < num_screens; i ++) {
189
if (mx >= screens[i].x_org &&
190
mx < (screens[i].x_org + screens[i].width) &&
191
my >= screens[i].y_org &&
192
my < (screens[i].y_org + screens[i].height)) {
193
X = screens[i].x_org;
194
Y = screens[i].y_org;
195
W = screens[i].width;
196
H = screens[i].height;
208
if (num_screens < 0) screen_init();
210
for (i = 0; i < num_screens; i ++) {
212
Fl::screen_xywh(sx, sy, sw, sh, i);
213
if ((mx >= sx) && (mx < (sx+sw)) && (my >= sy) && (my < (sy+sh))) {
219
screen_xywh(X, Y, W, H, screen);
216
226
\see void screen_xywh(int &x, int &y, int &w, int &h, int mx, int my)
218
228
void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int n) {
219
if (!num_screens) screen_init();
229
if (num_screens < 0) screen_init();
231
if ((n < 0) || (n >= num_screens))
222
if (num_screens > 1 && n >= 0 && n < num_screens) {
235
if (num_screens > 0) {
223
236
X = screens[n].left;
224
237
Y = screens[n].top;
225
238
W = screens[n].right - screens[n].left;
226
239
H = screens[n].bottom - screens[n].top;
241
/* Fallback if something is broken... */
244
W = GetSystemMetrics(SM_CXSCREEN);
245
H = GetSystemMetrics(SM_CYSCREEN);
229
247
#elif defined(__APPLE__)
230
if (num_screens > 1 && n >= 0 && n < num_screens) {
248
if (num_screens > 0) {
231
249
X = screens[n].x;
232
250
Y = screens[n].y;
233
251
W = screens[n].width;
234
252
H = screens[n].height;
254
/* Fallback if something is broken... */
238
if (num_screens > 1 && n >= 0 && n < num_screens) {
262
if (num_screens > 0 && screens) {
239
263
X = screens[n].x_org;
240
264
Y = screens[n].y_org;
241
265
W = screens[n].width;
242
266
H = screens[n].height;
268
#endif // HAVE_XINERAMA
270
/* Fallback if something is broken (or no Xinerama)... */
273
W = DisplayWidth(fl_display, fl_screen);
274
H = DisplayHeight(fl_display, fl_screen);
279
static inline float fl_intersection(int x1, int y1, int w1, int h1,
280
int x2, int y2, int w2, int h2) {
281
if(x1+w1 < x2 || x2+w2 < x1 || y1+h1 < y2 || y2+h2 < y1)
283
int int_left = x1 > x2 ? x1 : x2;
284
int int_right = x1+w1 > x2+w2 ? x2+w2 : x1+w1;
285
int int_top = y1 > y2 ? y1 : y2;
286
int int_bottom = y1+h1 > y2+h2 ? y2+h2 : y1+h1;
287
return (float)(int_right - int_left) * (int_bottom - int_top);
291
Gets the screen bounding rect for the screen
292
which intersects the most with the rectangle
293
defined by \p mx, \p my, \p mw, \p mh.
294
\param[out] X,Y,W,H the corresponding screen bounding box
295
\param[in] mx, my, mw, mh the rectangle to search for intersection with
296
\see void screen_xywh(int &X, int &Y, int &W, int &H, int n)
298
void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh) {
300
float best_intersection = 0.;
301
for(int i = 0; i < Fl::screen_count(); i++) {
303
Fl::screen_xywh(sx, sy, sw, sh, i);
304
float sintersection = fl_intersection(mx, my, mw, mh, sx, sy, sw, sh);
305
if(sintersection > best_intersection) {
307
best_intersection = sintersection;
310
screen_xywh(X, Y, W, H, best_screen);
316
Gets the screen resolution in dots-per-inch for the given screen.
317
\param[out] h, v horizontal and vertical resolution
318
\param[in] n the screen number (0 to Fl::screen_count() - 1)
319
\see void screen_xywh(int &x, int &y, int &w, int &h, int mx, int my)
321
void Fl::screen_dpi(float &h, float &v, int n)
323
if (num_screens < 0) screen_init();
327
if (n >= 0 && n < num_screens) {
328
h = float(dpi[n][0]);
329
v = float(dpi[n][1]);
331
#elif defined(__APPLE__)
332
if (n >= 0 && n < num_screens) {
337
if (n >= 0 && n < num_screens) {
342
if (n >= 0 && n < num_screens) {
257
// End of "$Id: screen_xywh.cxx 7351 2010-03-29 10:35:00Z matt $".
352
// End of "$Id: screen_xywh.cxx 8783 2011-06-06 09:37:21Z AlbrechtS $".