~ubuntu-branches/ubuntu/trusty/lmms/trusty

« back to all changes in this revision

Viewing changes to plugins/zynaddsubfx/fltk/src/screen_xywh.cxx

  • Committer: Charlie Smotherman
  • Date: 2012-12-05 22:08:38 UTC
  • mfrom: (33.1.7 lmms_0.4.13)
  • Revision ID: cjsmo@cableone.net-20121205220838-09pjfzew9m5023hr
* New  Upstream release.
  - Minor tweaking to ZynAddSubFX, CALF, SWH plugins  and Stefan Fendt's RC
    filters.
  - Added UI fixes: Magnentic effect of knobs and Piano-roll fixes
  - Updated German localization and copyright year
* debian/lmms-common.install:
  - added /usr/share/applications so the lmms.desktop file will correctly
    install (LP: #863366)
  - This should also fix the Software Center not displaying lmms in sound
    and video (LP: #824231)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
//
2
 
// "$Id: screen_xywh.cxx 7351 2010-03-29 10:35:00Z matt $"
 
2
// "$Id: screen_xywh.cxx 8783 2011-06-06 09:37:21Z AlbrechtS $"
3
3
//
4
4
// Screen/monitor bounding box API for the Fast Light Tool Kit (FLTK).
5
5
//
6
 
// Copyright 1998-2009 by Bill Spitzak and others.
 
6
// Copyright 1998-2010 by Bill Spitzak and others.
7
7
//
8
8
// This library is free software; you can redistribute it and/or
9
9
// modify it under the terms of the GNU Library General Public
31
31
#include <config.h>
32
32
 
33
33
 
34
 
// Number of screens...
35
 
static int num_screens = 0;
 
34
// Number of screens returned by multi monitor aware API; -1 before init
 
35
static int num_screens = -1;
36
36
 
37
37
#ifdef WIN32
38
38
#  if !defined(HMONITOR_DECLARED) && (_WIN32_WINNT < 0x0500)
56
56
static fl_gmi_func fl_gmi = NULL; // used to get a proc pointer for GetMonitorInfoA
57
57
 
58
58
static RECT screens[16];
 
59
static float dpi[16][2];
59
60
 
60
61
static BOOL CALLBACK screen_cb(HMONITOR mon, HDC, LPRECT r, LPARAM) {
61
62
  if (num_screens >= 16) return TRUE;
62
63
 
63
 
  MONITORINFO mi;
 
64
  MONITORINFOEX mi;
64
65
  mi.cbSize = sizeof(mi);
65
66
 
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;
 
71
    
 
72
    // find the pixel size
 
73
    if (mi.cbSize == sizeof(mi)) {
 
74
      HDC screen = CreateDC(mi.szDevice, NULL, NULL, NULL);
 
75
      if (screen) {
 
76
        dpi[num_screens][0] = (float)GetDeviceCaps(screen, LOGPIXELSX);
 
77
        dpi[num_screens][1] = (float)GetDeviceCaps(screen, LOGPIXELSY);
 
78
      }
 
79
      ReleaseDC(0L, screen);
 
80
    }
 
81
    
70
82
    num_screens ++;
71
83
  }
72
84
  return TRUE;
73
85
}
74
86
 
75
87
static void screen_init() {
 
88
  num_screens = 0;
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);
87
100
 
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");
91
104
 
92
105
        if (fl_gmi) {
93
106
          // We have GetMonitorInfoA, enumerate all the screens...
94
 
          num_screens = 0;
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);
98
110
          return;
99
111
        }
100
 
      }
 
112
//      }
101
113
    }
102
114
  }
103
115
 
104
116
  // If we get here, assume we have 1 monitor...
105
117
  num_screens = 1;
 
118
  screens[0].top      = 0;
 
119
  screens[0].left      = 0;
 
120
  screens[0].right  = GetSystemMetrics(SM_CXSCREEN);
 
121
  screens[0].bottom = GetSystemMetrics(SM_CYSCREEN);
106
122
}
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];
109
127
 
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;
 
131
  CGRect r;
 
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);
 
142
  }
 
143
  num_screens = count;
113
144
}
114
145
#elif HAVE_XINERAMA
115
146
#  include <X11/extensions/Xinerama.h>
116
147
 
117
148
// Screen data...
118
149
static XineramaScreenInfo *screens;
 
150
static float dpi[16][2];
119
151
 
120
152
static void screen_init() {
121
153
  if (!fl_display) fl_open_display();
122
154
 
123
155
  if (XineramaIsActive(fl_display)) {
124
156
    screens = XineramaQueryScreens(fl_display, &num_screens);
125
 
  } else num_screens = 1;
 
157
    int i;
 
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;
 
167
    }
 
168
  } else { // ! XineramaIsActive()
 
169
    num_screens = 1;
 
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];
 
174
  }
126
175
}
127
176
#else
 
177
static float dpi[2];
128
178
static void screen_init() {
129
179
  num_screens = 1;
 
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];  
130
185
}
131
186
#endif // WIN32
132
187
 
135
190
  Gets the number of available screens.
136
191
*/
137
192
int Fl::screen_count() {
138
 
  if (!num_screens) screen_init();
 
193
  if (num_screens < 0) screen_init();
139
194
 
140
 
  return num_screens;
 
195
  return num_screens ? num_screens : 1;
141
196
}
142
197
 
143
198
/**
147
202
  \param[in] mx, my the absolute screen position
148
203
*/
149
204
void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) {
150
 
  if (!num_screens) screen_init();
151
 
 
152
 
#ifdef WIN32
153
 
  if (num_screens > 1) {
154
 
    int i;
155
 
 
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) {
159
 
        X = screens[i].left;
160
 
        Y = screens[i].top;
161
 
        W = screens[i].right - screens[i].left;
162
 
        H = screens[i].bottom - screens[i].top;
163
 
        return;
164
 
      }
165
 
    }
166
 
  }
167
 
#elif defined(__APPLE__)
168
 
  if (num_screens > 1) {
169
 
    int i;
170
 
 
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)) {
176
 
        X = screens[i].x;
177
 
        Y = screens[i].y;
178
 
        W = screens[i].width;
179
 
        H = screens[i].height;
180
 
        return;
181
 
      }
182
 
    }
183
 
  }
184
 
#elif HAVE_XINERAMA
185
 
  if (num_screens > 1) {
186
 
    int i;
187
 
 
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;
197
 
        return;
198
 
      }
199
 
    }
200
 
  }
201
 
#else
202
 
  (void)mx;
203
 
  (void)my;
204
 
#endif // WIN32
205
 
 
206
 
  X = Fl::x();
207
 
  Y = Fl::y();
208
 
  W = Fl::w();
209
 
  H = Fl::h();
 
205
  int screen = 0;
 
206
  int i;
 
207
 
 
208
  if (num_screens < 0) screen_init();
 
209
 
 
210
  for (i = 0; i < num_screens; i ++) {
 
211
    int sx, sy, sw, sh;
 
212
    Fl::screen_xywh(sx, sy, sw, sh, i);
 
213
    if ((mx >= sx) && (mx < (sx+sw)) && (my >= sy) && (my < (sy+sh))) {
 
214
      screen = i;
 
215
      break;
 
216
    }
 
217
  }
 
218
 
 
219
  screen_xywh(X, Y, W, H, screen);
210
220
}
211
221
 
212
222
/**
216
226
  \see void screen_xywh(int &x, int &y, int &w, int &h, int mx, int my) 
217
227
*/
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();
 
230
 
 
231
  if ((n < 0) || (n >= num_screens))
 
232
    n = 0;
220
233
 
221
234
#ifdef WIN32
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;
227
 
    return;
 
240
  } else {
 
241
    /* Fallback if something is broken... */
 
242
    X = 0;
 
243
    Y = 0;
 
244
    W = GetSystemMetrics(SM_CXSCREEN);
 
245
    H = GetSystemMetrics(SM_CYSCREEN);
228
246
  }
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;
235
 
    return;
 
253
  } else {
 
254
    /* Fallback if something is broken... */
 
255
    X = Fl::x();
 
256
    Y = Fl::y();
 
257
    W = Fl::w();
 
258
    H = Fl::h();
236
259
  }
237
 
#elif HAVE_XINERAMA
238
 
  if (num_screens > 1 && n >= 0 && n < num_screens) {
 
260
#else
 
261
#if HAVE_XINERAMA
 
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;
243
 
    return;
 
267
  } else
 
268
#endif // HAVE_XINERAMA
 
269
  {
 
270
    /* Fallback if something is broken (or no Xinerama)... */
 
271
    X = 0;
 
272
    Y = 0;
 
273
    W = DisplayWidth(fl_display, fl_screen);
 
274
    H = DisplayHeight(fl_display, fl_screen);
 
275
  }
 
276
#endif // WIN32
 
277
}
 
278
 
 
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)
 
282
    return 0.;
 
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);
 
288
}
 
289
 
 
290
/**
 
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)
 
297
  */
 
298
void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh) {
 
299
  int best_screen = 0;
 
300
  float best_intersection = 0.;
 
301
  for(int i = 0; i < Fl::screen_count(); i++) {
 
302
    int sx, sy, sw, sh;
 
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) {
 
306
      best_screen = i;
 
307
      best_intersection = sintersection;
 
308
    }
 
309
  }
 
310
  screen_xywh(X, Y, W, H, best_screen);
 
311
}
 
312
  
 
313
 
 
314
 
 
315
/**
 
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) 
 
320
 */
 
321
void Fl::screen_dpi(float &h, float &v, int n)
 
322
{
 
323
  if (num_screens < 0) screen_init();
 
324
  h = v = 0.0f;
 
325
  
 
326
#ifdef WIN32
 
327
  if (n >= 0 && n < num_screens) {
 
328
    h = float(dpi[n][0]);
 
329
    v = float(dpi[n][1]);
 
330
  }
 
331
#elif defined(__APPLE__)
 
332
  if (n >= 0 && n < num_screens) {
 
333
    h = dpi_h[n];
 
334
    v = dpi_v[n];
 
335
  }
 
336
#elif HAVE_XINERAMA
 
337
  if (n >= 0 && n < num_screens) {
 
338
    h = dpi[n][0];
 
339
    v = dpi[n][1];
244
340
  }
245
341
#else
246
 
  (void)n;
 
342
  if (n >= 0 && n < num_screens) {
 
343
    h = dpi[0];
 
344
    v = dpi[1];
 
345
  }
247
346
#endif // WIN32
248
 
 
249
 
  X = Fl::x();
250
 
  Y = Fl::y();
251
 
  W = Fl::w();
252
 
  H = Fl::h();
253
347
}
254
348
 
255
349
 
 
350
 
256
351
//
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 $".
258
353
//