summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt7
-rw-r--r--src/Fl.cxx18
-rw-r--r--src/Fl_Screen_Driver.cxx124
-rw-r--r--src/Fl_cocoa.mm9
-rw-r--r--src/Makefile12
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx72
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h16
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx98
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.h58
-rw-r--r--src/drivers/X11/Fl_X11_Screen_Driver.cxx98
-rw-r--r--src/drivers/X11/Fl_X11_Screen_Driver.h48
-rw-r--r--src/screen_xywh.cxx336
12 files changed, 729 insertions, 167 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c391aba81..f866f9e9f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -54,6 +54,7 @@ set(CPPFILES
Fl_Return_Button.cxx
Fl_Roller.cxx
Fl_Round_Button.cxx
+ Fl_Screen_Driver.cxx
Fl_Scroll.cxx
Fl_Scrollbar.cxx
Fl_Shared_Image.cxx
@@ -166,6 +167,7 @@ if (USE_X11)
# X11 (including APPLE with X11)
set(DRIVER_FILES
+ drivers/X11/Fl_X11_Screen_Driver.cxx
drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx
drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx
drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx
@@ -184,7 +186,8 @@ if (USE_X11)
)
endif (USE_XFT)
set(DRIVER_HEADER_FILES
- drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx
+ drivers/Quartz/Fl_Quartz_Graphics_Driver.h
+ drivers/X11/Fl_X11_Screen_Driver.h
)
elseif (APPLE)
@@ -226,9 +229,11 @@ else ()
drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx
drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx
drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx
+ drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
)
set(DRIVER_HEADER_FILES
drivers/GDI/Fl_GDI_Graphics_Driver.h
+ drivers/WinAPI/Fl_WinAPI_Screen_Driver.h
)
endif (USE_X11)
diff --git a/src/Fl.cxx b/src/Fl.cxx
index 9e421f0ff..52208b58f 100644
--- a/src/Fl.cxx
+++ b/src/Fl.cxx
@@ -46,6 +46,7 @@
#endif
#include <FL/Fl.H>
+#include <FL/Fl_Screen_Driver.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Tooltip.H>
#include <FL/x.H>
@@ -208,6 +209,21 @@ Fl_Window *Fl::modal_; // topmost modal() window
char const * const Fl::clipboard_plain_text = "text/plain";
char const * const Fl::clipboard_image = "image";
+
+//
+// Drivers
+//
+
+Fl_Screen_Driver *Fl::screen_driver_ = Fl_Screen_Driver::newScreenDriver();
+
+Fl_Screen_Driver *Fl::screen_driver()
+{
+ if (!screen_driver_)
+ screen_driver_ = Fl_Screen_Driver::newScreenDriver();
+ return screen_driver_;
+}
+
+
//
// 'Fl::version()' - Return the API version number...
//
@@ -2350,6 +2366,8 @@ Fl_Widget_Tracker::~Fl_Widget_Tracker()
}
int Fl::use_high_res_GL_ = 0;
+
+
//
// End of "$Id$".
//
diff --git a/src/Fl_Screen_Driver.cxx b/src/Fl_Screen_Driver.cxx
new file mode 100644
index 000000000..46e9e5d2c
--- /dev/null
+++ b/src/Fl_Screen_Driver.cxx
@@ -0,0 +1,124 @@
+//
+// "$Id$"
+//
+// All screen related calls in a driver style class.
+//
+// Copyright 1998-2016 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+
+#include "config_lib.h"
+#include <FL/Fl_Screen_Driver.H>
+#include <FL/Fl.H>
+
+
+Fl_Screen_Driver::Fl_Screen_Driver() :
+num_screens(-1)
+{
+}
+
+
+void Fl_Screen_Driver::screen_xywh(int &X, int &Y, int &W, int &H)
+{
+ int x, y;
+ Fl::get_mouse(x, y);
+ screen_xywh(X, Y, W, H, x, y);
+}
+
+
+void Fl_Screen_Driver::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my)
+{
+ screen_xywh(X, Y, W, H, screen_num(mx, my));
+}
+
+
+void Fl_Screen_Driver::screen_work_area(int &X, int &Y, int &W, int &H)
+{
+ int x, y;
+ Fl::get_mouse(x, y);
+ screen_work_area(X, Y, W, H, x, y);
+}
+
+
+void Fl_Screen_Driver::screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my)
+{
+ screen_work_area(X, Y, W, H, screen_num(mx, my));
+}
+
+
+int Fl_Screen_Driver::screen_count()
+{
+ if (num_screens < 0)
+ init();
+ return num_screens ? num_screens : 1;
+}
+
+
+void Fl_Screen_Driver::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh)
+{
+ screen_xywh(X, Y, W, H, screen_num(mx, my, mw, mh));
+}
+
+
+int Fl_Screen_Driver::screen_num(int x, int y)
+{
+ int screen = 0;
+ if (num_screens < 0) init();
+
+ for (int i = 0; i < num_screens; i ++) {
+ int sx, sy, sw, sh;
+ Fl::screen_xywh(sx, sy, sw, sh, i);
+ if ((x >= sx) && (x < (sx+sw)) && (y >= sy) && (y < (sy+sh))) {
+ screen = i;
+ break;
+ }
+ }
+ return screen;
+}
+
+
+// Return the number of pixels common to the two rectangular areas
+static inline float fl_intersection(int x1, int y1, int w1, int h1,
+ int x2, int y2, int w2, int h2)
+{
+ if(x1+w1 < x2 || x2+w2 < x1 || y1+h1 < y2 || y2+h2 < y1)
+ return 0.;
+ int int_left = x1 > x2 ? x1 : x2;
+ int int_right = x1+w1 > x2+w2 ? x2+w2 : x1+w1;
+ int int_top = y1 > y2 ? y1 : y2;
+ int int_bottom = y1+h1 > y2+h2 ? y2+h2 : y1+h1;
+ return (float)(int_right - int_left) * (int_bottom - int_top);
+}
+
+
+int Fl_Screen_Driver::screen_num(int x, int y, int w, int h)
+{
+ int best_screen = 0;
+ float best_intersection = 0.;
+ for (int i = 0; i < num_screens; i++) {
+ int sx = 0, sy = 0, sw = 0, sh = 0;
+ screen_xywh(sx, sy, sw, sh, i);
+ float sintersection = fl_intersection(x, y, w, h, sx, sy, sw, sh);
+ if (sintersection > best_intersection) {
+ best_screen = i;
+ best_intersection = sintersection;
+ }
+ }
+ return best_screen;
+}
+
+
+
+//
+// End of "$Id$".
+//
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm
index c6d55206b..be0da7834 100644
--- a/src/Fl_cocoa.mm
+++ b/src/Fl_cocoa.mm
@@ -44,6 +44,7 @@ extern "C" {
#include <FL/Fl_Printer.H>
#include <FL/Fl_Copy_Surface.H>
#include "drivers/Quartz/Fl_Quartz_Graphics_Driver.h"
+#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -1849,7 +1850,7 @@ static void get_window_frame_sizes(int &bx, int &by, int &bt) {
/*
* smallest x coordinate in screen space of work area of menubar-containing display
*/
-int Fl::x() {
+int Fl_Cocoa_Screen_Driver::x() {
return int([[[NSScreen screens] objectAtIndex:0] visibleFrame].origin.x);
}
@@ -1857,7 +1858,7 @@ int Fl::x() {
/*
* smallest y coordinate in screen space of work area of menubar-containing display
*/
-int Fl::y() {
+int Fl_Cocoa_Screen_Driver::y() {
fl_open_display();
NSRect visible = [[[NSScreen screens] objectAtIndex:0] visibleFrame];
return int(main_screen_height - (visible.origin.y + visible.size.height));
@@ -1867,7 +1868,7 @@ int Fl::y() {
/*
* width of work area of menubar-containing display
*/
-int Fl::w() {
+int Fl_Cocoa_Screen_Driver::w() {
return int([[[NSScreen screens] objectAtIndex:0] visibleFrame].size.width);
}
@@ -1875,7 +1876,7 @@ int Fl::w() {
/*
* height of work area of menubar-containing display
*/
-int Fl::h() {
+int Fl_Cocoa_Screen_Driver::h() {
return int([[[NSScreen screens] objectAtIndex:0] visibleFrame].size.height);
}
diff --git a/src/Makefile b/src/Makefile
index 8740353fd..b6edb372d 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -74,6 +74,7 @@ CPPFILES = \
Fl_Return_Button.cxx \
Fl_Roller.cxx \
Fl_Round_Button.cxx \
+ Fl_Screen_Driver.cxx \
Fl_Scroll.cxx \
Fl_Scrollbar.cxx \
Fl_Shared_Image.cxx \
@@ -231,7 +232,10 @@ QUARTZCPPFILES = \
drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx \
drivers/Quartz/Fl_Quartz_Printer_Graphics_Driver.cxx \
drivers/Quartz/Fl_Quartz_Graphics_Driver_arci.cxx \
- drivers/Quartz/Fl_Quartz_Graphics_Driver_line_style.cxx
+ drivers/Quartz/Fl_Quartz_Graphics_Driver_line_style.cxx \
+ drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx \
+ drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx \
+ drivers/Darwin/Fl_Darwin_System_Driver.cxx
XLIBCPPFILES = \
drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx \
@@ -240,7 +244,8 @@ XLIBCPPFILES = \
drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx \
drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx \
drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx \
- drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx
+ drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx \
+ drivers/X11/Fl_X11_Screen_Driver.cxx
XLIBFONTFILES = \
drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx
@@ -256,7 +261,8 @@ GDICPPFILES = \
drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx \
drivers/GDI/Fl_GDI_Graphics_Driver_line_style.cxx \
drivers/GDI/Fl_GDI_Graphics_Driver_rect.cxx \
- drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx
+ drivers/GDI/Fl_GDI_Graphics_Driver_vertex.cxx \
+ drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
################################################################
FLTKFLAGS = -DFL_LIBRARY
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
index f44beade4..94dedb813 100644
--- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
+++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
@@ -22,6 +22,78 @@
+/**
+ Creates a driver that manages all screen and display related calls.
+
+ This function must be implemented once for every platform. It is called
+ when the static members of the class "Fl" are created.
+ */
+Fl_Screen_Driver *Fl_Screen_Driver::newScreenDriver()
+{
+ return new Fl_Cocoa_Screen_Driver();
+}
+
+
+void Fl_Cocoa_Screen_Driver::init()
+{
+ CGDirectDisplayID displays[MAX_SCREENS];
+ CGDisplayCount count, i;
+ CGRect r;
+ CGGetActiveDisplayList(MAX_SCREENS, displays, &count);
+ for( i = 0; i < count; i++) {
+ r = CGDisplayBounds(displays[i]);
+ screens[i].x = int(r.origin.x);
+ screens[i].y = int(r.origin.y);
+ screens[i].width = int(r.size.width);
+ screens[i].height = int(r.size.height);
+ //fprintf(stderr,"screen %d %dx%dx%dx%d\n",i,screens[i].x,screens[i].y,screens[i].width,screens[i].height);
+ if (&CGDisplayScreenSize != NULL) {
+ CGSize s = CGDisplayScreenSize(displays[i]); // from 10.3
+ dpi_h[i] = screens[i].width / (s.width/25.4);
+ dpi_v[i] = screens[i].height / (s.height/25.4);
+ } else {
+ dpi_h[i] = dpi_v[i] = 75.;
+ }
+ }
+ num_screens = count;
+}
+
+
+void Fl_Cocoa_Screen_Driver::screen_work_area(int &X, int &Y, int &W, int &H, int n)
+{
+ if (num_screens < 0) init();
+ if (n < 0 || n >= num_screens) n = 0;
+ Fl_X::screen_work_area(X, Y, W, H, n);
+}
+
+
+void Fl_Cocoa_Screen_Driver::screen_xywh(int &X, int &Y, int &W, int &H, int n)
+{
+ if (num_screens < 0) init();
+
+ if ((n < 0) || (n >= num_screens))
+ n = 0;
+
+ X = screens[n].x;
+ Y = screens[n].y;
+ W = screens[n].width;
+ H = screens[n].height;
+}
+
+
+void Fl_Cocoa_Screen_Driver::screen_dpi(float &h, float &v, int n)
+{
+ if (num_screens < 0) init();
+ h = v = 0.0f;
+
+ if (n >= 0 && n < num_screens) {
+ h = dpi_h[n];
+ v = dpi_v[n];
+ }
+}
+
+
+
//
// End of "$Id$".
//
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h
index cc5b7150f..b0a64743c 100644
--- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h
+++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h
@@ -25,6 +25,8 @@
#ifndef FL_COCOA_SCREEN_DRIVER_H
#define FL_COCOA_SCREEN_DRIVER_H
+#include <FL/Fl_Screen_Driver.H>
+
/*
Move everything here that manages the native screen interface.
@@ -35,6 +37,20 @@
- native dialog boxes
*/
+
+class FL_EXPORT Fl_Cocoa_Screen_Driver : public Fl_Screen_Driver {
+public:
+ virtual void init();
+ virtual int x();
+ virtual int y();
+ virtual int w();
+ virtual int h();
+ virtual void screen_xywh(int &X, int &Y, int &W, int &H, int n);
+ virtual void screen_dpi(float &h, float &v, int n=0);
+ virtual void screen_work_area(int &X, int &Y, int &W, int &H, int n);
+};
+
+
#endif // FL_COCOA_SCREEN_DRIVER_H
//
diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
new file mode 100644
index 000000000..4f2da2e33
--- /dev/null
+++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
@@ -0,0 +1,98 @@
+//
+// "$Id$"
+//
+// Definition of MSWindows Win32/64 Screen interface
+//
+// Copyright 1998-2016 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+
+#include "../../config_lib.h"
+#include "Fl_WinAPI_Screen_Driver.h"
+
+
+/**
+ Creates a driver that manages all screen and display related calls.
+
+ This function must be implemented once for every platform. It is called
+ when the static members of the class "Fl" are created.
+ */
+Fl_Screen_Driver *Fl_Screen_Driver::newScreenDriver()
+{
+ return new Fl_WinAPI_Screen_Driver();
+}
+
+
+void Fl_WinAPI_Screen_Driver::init()
+{
+ CGDirectDisplayID displays[MAX_SCREENS];
+ CGDisplayCount count, i;
+ CGRect r;
+ CGGetActiveDisplayList(MAX_SCREENS, displays, &count);
+ for( i = 0; i < count; i++) {
+ r = CGDisplayBounds(displays[i]);
+ screens[i].x = int(r.origin.x);
+ screens[i].y = int(r.origin.y);
+ screens[i].width = int(r.size.width);
+ screens[i].height = int(r.size.height);
+ //fprintf(stderr,"screen %d %dx%dx%dx%d\n",i,screens[i].x,screens[i].y,screens[i].width,screens[i].height);
+ if (&CGDisplayScreenSize != NULL) {
+ CGSize s = CGDisplayScreenSize(displays[i]); // from 10.3
+ dpi_h[i] = screens[i].width / (s.width/25.4);
+ dpi_v[i] = screens[i].height / (s.height/25.4);
+ } else {
+ dpi_h[i] = dpi_v[i] = 75.;
+ }
+ }
+ num_screens = count;
+}
+
+
+void Fl_WinAPI_Screen_Driver::screen_work_area(int &X, int &Y, int &W, int &H, int n)
+{
+ if (num_screens < 0) init();
+ if (n < 0 || n >= num_screens) n = 0;
+ Fl_X::screen_work_area(X, Y, W, H, n);
+}
+
+
+void Fl_WinAPI_Screen_Driver::screen_xywh(int &X, int &Y, int &W, int &H, int n)
+{
+ if (num_screens < 0) init();
+
+ if ((n < 0) || (n >= num_screens))
+ n = 0;
+
+ X = screens[n].x;
+ Y = screens[n].y;
+ W = screens[n].width;
+ H = screens[n].height;
+}
+
+
+void Fl_WinAPI_Screen_Driver::screen_dpi(float &h, float &v, int n)
+{
+ if (num_screens < 0) init();
+ h = v = 0.0f;
+
+ if (n >= 0 && n < num_screens) {
+ h = dpi_h[n];
+ v = dpi_v[n];
+ }
+}
+
+
+
+//
+// End of "$Id$".
+//
diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.h b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.h
new file mode 100644
index 000000000..2f7e104f0
--- /dev/null
+++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.h
@@ -0,0 +1,58 @@
+//
+// "$Id: quartz.H 11017 2016-01-20 21:40:12Z matt $"
+//
+// Definition of MSWindows Win32/64 Screen interface
+// for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2010-2016 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+/**
+ \file Fl_WinAPI_Screen_Driver.h
+ \brief Definition of MSWindows Win32/64 Screen interface.
+ */
+
+#ifndef FL_WINAPI_SCREEN_DRIVER_H
+#define FL_WINAPI_SCREEN_DRIVER_H
+
+#include <FL/Fl_Screen_Driver.H>
+
+/*
+ Move everything here that manages the native screen interface.
+
+ There is exactly one screen driver in the system.
+
+ - screen configuration and sizes
+ - multiple screens
+ - native dialog boxes
+*/
+
+
+class FL_EXPORT Fl_WinAPI_Screen_Driver : public Fl_Screen_Driver {
+public:
+ virtual void init();
+ virtual int x();
+ virtual int y();
+ virtual int w();
+ virtual int h();
+ virtual void screen_xywh(int &X, int &Y, int &W, int &H, int n);
+ virtual void screen_dpi(float &h, float &v, int n=0);
+ virtual void screen_work_area(int &X, int &Y, int &W, int &H, int n);
+};
+
+
+#endif // FL_WINAPI_SCREEN_DRIVER_H
+
+//
+// End of "$Id: quartz.H 11017 2016-01-20 21:40:12Z matt $".
+//
diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.cxx b/src/drivers/X11/Fl_X11_Screen_Driver.cxx
new file mode 100644
index 000000000..2891ac1f9
--- /dev/null
+++ b/src/drivers/X11/Fl_X11_Screen_Driver.cxx
@@ -0,0 +1,98 @@
+//
+// "$Id$"
+//
+// Definition of X11 Screen interface
+//
+// Copyright 1998-2016 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+
+#include "../../config_lib.h"
+#include "Fl_X11_Screen_Driver.h"
+
+
+/**
+ Creates a driver that manages all screen and display related calls.
+
+ This function must be implemented once for every platform. It is called
+ when the static members of the class "Fl" are created.
+ */
+Fl_Screen_Driver *Fl_Screen_Driver::newScreenDriver()
+{
+ return new Fl_X11_Screen_Driver();
+}
+
+
+void Fl_X11_Screen_Driver::init()
+{
+ CGDirectDisplayID displays[MAX_SCREENS];
+ CGDisplayCount count, i;
+ CGRect r;
+ CGGetActiveDisplayList(MAX_SCREENS, displays, &count);
+ for( i = 0; i < count; i++) {
+ r = CGDisplayBounds(displays[i]);
+ screens[i].x = int(r.origin.x);
+ screens[i].y = int(r.origin.y);
+ screens[i].width = int(r.size.width);
+ screens[i].height = int(r.size.height);
+ //fprintf(stderr,"screen %d %dx%dx%dx%d\n",i,screens[i].x,screens[i].y,screens[i].width,screens[i].height);
+ if (&CGDisplayScreenSize != NULL) {
+ CGSize s = CGDisplayScreenSize(displays[i]); // from 10.3
+ dpi_h[i] = screens[i].width / (s.width/25.4);
+ dpi_v[i] = screens[i].height / (s.height/25.4);
+ } else {
+ dpi_h[i] = dpi_v[i] = 75.;
+ }
+ }
+ num_screens = count;
+}
+
+
+void Fl_X11_Screen_Driver::screen_work_area(int &X, int &Y, int &W, int &H, int n)
+{
+ if (num_screens < 0) init();
+ if (n < 0 || n >= num_screens) n = 0;
+ Fl_X::screen_work_area(X, Y, W, H, n);
+}
+
+
+void Fl_X11_Screen_Driver::screen_xywh(int &X, int &Y, int &W, int &H, int n)
+{
+ if (num_screens < 0) init();
+
+ if ((n < 0) || (n >= num_screens))
+ n = 0;
+
+ X = screens[n].x;
+ Y = screens[n].y;
+ W = screens[n].width;
+ H = screens[n].height;
+}
+
+
+void Fl_X11_Screen_Driver::screen_dpi(float &h, float &v, int n)
+{
+ if (num_screens < 0) init();
+ h = v = 0.0f;
+
+ if (n >= 0 && n < num_screens) {
+ h = dpi_h[n];
+ v = dpi_v[n];
+ }
+}
+
+
+
+//
+// End of "$Id$".
+//
diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.h b/src/drivers/X11/Fl_X11_Screen_Driver.h
new file mode 100644
index 000000000..8c7bc8da2
--- /dev/null
+++ b/src/drivers/X11/Fl_X11_Screen_Driver.h
@@ -0,0 +1,48 @@
+//
+// "$Id: quartz.H 11017 2016-01-20 21:40:12Z matt $"
+//
+// Definition of X11 Screen interface
+// for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2010-2016 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+/**
+ \file Fl_X11_Screen_Driver.h
+ \brief Definition of X11 Screen interface
+ */
+
+#ifndef FL_X11_SCREEN_DRIVER_H
+#define FL_X11_SCREEN_DRIVER_H
+
+#include <FL/Fl_Screen_Driver.H>
+
+
+class FL_EXPORT Fl_X11_Screen_Driver : public Fl_Screen_Driver {
+public:
+ virtual void init();
+ virtual int x();
+ virtual int y();
+ virtual int w();
+ virtual int h();
+ virtual void screen_xywh(int &X, int &Y, int &W, int &H, int n);
+ virtual void screen_dpi(float &h, float &v, int n=0);
+ virtual void screen_work_area(int &X, int &Y, int &W, int &H, int n);
+};
+
+
+#endif // FL_X11_SCREEN_DRIVER_H
+
+//
+// End of "$Id: quartz.H 11017 2016-01-20 21:40:12Z matt $".
+//
diff --git a/src/screen_xywh.cxx b/src/screen_xywh.cxx
index 45a2a07e5..49897dcf1 100644
--- a/src/screen_xywh.cxx
+++ b/src/screen_xywh.cxx
@@ -19,6 +19,7 @@
#include <FL/Fl.H>
#include <FL/x.H>
+#include <FL/Fl_Screen_Driver.H>
#include <config.h>
#define MAX_SCREENS 16
@@ -32,6 +33,12 @@ static int num_screens = -1;
# include <multimon.h>
# endif // !HMONITOR_DECLARED && _WIN32_WINNT < 0x0500
+#ifndef FL_DOXYGEN
+void Fl::call_screen_init() {
+ screen_init();
+}
+#endif
+
// We go the much more difficult route of individually picking some multi-screen
// functions from the USER32.DLL . If these functions are not available, we
// will gracefully fall back to single monitor support.
@@ -47,12 +54,12 @@ typedef BOOL (WINAPI* fl_gmi_func)(HMONITOR, LPMONITORINFO);
static fl_gmi_func fl_gmi = NULL; // used to get a proc pointer for GetMonitorInfoA
-static RECT screens[16];
-static RECT work_area[16];
-static float dpi[16][2];
+static RECT screens[MAX_SCREENS];
+static RECT work_area[MAX_SCREENS];
+static float dpi[MAX_SCREENS][2];
static BOOL CALLBACK screen_cb(HMONITOR mon, HDC, LPRECT r, LPARAM) {
- if (num_screens >= 16) return TRUE;
+ if (num_screens >= MAX_SCREENS) return TRUE;
MONITORINFOEX mi;
mi.cbSize = sizeof(mi);
@@ -115,40 +122,17 @@ static void screen_init() {
work_area[0] = screens[0];
}
#elif defined(__APPLE__)
-static XRectangle screens[16];
-static float dpi_h[16];
-static float dpi_v[16];
-
-static void screen_init() {
- CGDirectDisplayID displays[16];
- CGDisplayCount count, i;
- CGRect r;
- CGGetActiveDisplayList(16, displays, &count);
- for( i = 0; i < count; i++) {
- r = CGDisplayBounds(displays[i]);
- screens[i].x = int(r.origin.x);
- screens[i].y = int(r.origin.y);
- screens[i].width = int(r.size.width);
- screens[i].height = int(r.size.height);
-//fprintf(stderr,"screen %d %dx%dx%dx%d\n",i,screens[i].x,screens[i].y,screens[i].width,screens[i].height);
- if (&CGDisplayScreenSize != NULL) {
- CGSize s = CGDisplayScreenSize(displays[i]); // from 10.3
- dpi_h[i] = screens[i].width / (s.width/25.4);
- dpi_v[i] = screens[i].height / (s.height/25.4);
- } else {
- dpi_h[i] = dpi_v[i] = 75.;
- }
- }
- num_screens = count;
-}
#elif defined(FL_PORTING)
-# pragma message "FL_PORTING: return various information about the screens in the system"
-static void screen_init() { }
-
#else
+#ifndef FL_DOXYGEN
+void Fl::call_screen_init() {
+ screen_init();
+}
+#endif
+
#if HAVE_XINERAMA
# include <X11/extensions/Xinerama.h>
#endif
@@ -204,29 +188,61 @@ static void screen_init() {
#endif // WIN32
-#ifndef FL_DOXYGEN
-void Fl::call_screen_init() {
- screen_init();
+
+
+
+void Fl::call_screen_init()
+{
+ screen_driver()->init();
+}
+
+
+/** Returns the leftmost x coordinate of the main screen work area. */
+int Fl::x()
+{
+ return screen_driver()->x();
+}
+
+
+/** Returns the topmost y coordinate of the main screen work area. */
+int Fl::y()
+{
+ return screen_driver()->y();
+}
+
+
+/** Returns the width in pixels of the main screen work area. */
+int Fl::w()
+{
+ return screen_driver()->w();
}
-#endif
+
+
+/** Returns the height in pixels of the main screen work area. */
+int Fl::h()
+{
+ return screen_driver()->h();
+}
+
/**
Gets the number of available screens.
*/
-int Fl::screen_count() {
- if (num_screens < 0) screen_init();
-
- return num_screens ? num_screens : 1;
+int Fl::screen_count()
+{
+ return screen_driver()->screen_count();
}
+
/**
Gets the bounding box of a screen
that contains the specified screen position \p mx, \p my
\param[out] X,Y,W,H the corresponding screen bounding box
\param[in] mx, my the absolute screen position
*/
-void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) {
- screen_xywh(X, Y, W, H, screen_num(mx, my));
+void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my)
+{
+ screen_driver()->screen_xywh(X, Y, W, H, mx, my);
}
@@ -236,8 +252,9 @@ void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) {
\param[out] X,Y,W,H the work area bounding box
\param[in] mx, my the absolute screen position
*/
-void Fl::screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my) {
- screen_work_area(X, Y, W, H, screen_num(mx, my));
+void Fl::screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my)
+{
+ screen_driver()->screen_work_area(X, Y, W, H, mx, my);
}
/**
@@ -246,26 +263,28 @@ void Fl::screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my) {
\param[in] n the screen number (0 to Fl::screen_count() - 1)
\see void screen_xywh(int &x, int &y, int &w, int &h, int mx, int my)
*/
-void Fl::screen_work_area(int &X, int &Y, int &W, int &H, int n) {
- if (num_screens < 0) screen_init();
- if (n < 0 || n >= num_screens) n = 0;
-#ifdef WIN32
- X = work_area[n].left;
- Y = work_area[n].top;
- W = work_area[n].right - X;
- H = work_area[n].bottom - Y;
-#elif defined(__APPLE__)
- Fl_X::screen_work_area(X, Y, W, H, n);
-#else
- if (n == 0) { // for the main screen, these return the work area
- X = Fl::x();
- Y = Fl::y();
- W = Fl::w();
- H = Fl::h();
- } else { // for other screens, work area is full screen,
- screen_xywh(X, Y, W, H, n);
- }
-#endif
+void Fl::screen_work_area(int &X, int &Y, int &W, int &H, int n)
+{
+ screen_driver()->screen_work_area(X, Y, W, H, n);
+// if (num_screens < 0) screen_init();
+// if (n < 0 || n >= num_screens) n = 0;
+//#ifdef WIN32
+// X = work_area[n].left;
+// Y = work_area[n].top;
+// W = work_area[n].right - X;
+// H = work_area[n].bottom - Y;
+//#elif defined(__APPLE__)
+// Fl_X::screen_work_area(X, Y, W, H, n);
+//#else
+// if (n == 0) { // for the main screen, these return the work area
+// X = Fl::x();
+// Y = Fl::y();
+// W = Fl::w();
+// H = Fl::h();
+// } else { // for other screens, work area is full screen,
+// screen_xywh(X, Y, W, H, n);
+// }
+//#endif
}
/**
@@ -275,43 +294,47 @@ void Fl::screen_work_area(int &X, int &Y, int &W, int &H, int n) {
\param[in] n the screen number (0 to Fl::screen_count() - 1)
\see void screen_xywh(int &x, int &y, int &w, int &h, int mx, int my)
*/
-void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int n) {
- if (num_screens < 0) screen_init();
-
- if ((n < 0) || (n >= num_screens))
- n = 0;
-
-#ifdef WIN32
- if (num_screens > 0) {
- X = screens[n].left;
- Y = screens[n].top;
- W = screens[n].right - screens[n].left;
- H = screens[n].bottom - screens[n].top;
- } else {
- /* Fallback if something is broken... */
- X = 0;
- Y = 0;
- W = GetSystemMetrics(SM_CXSCREEN);
- H = GetSystemMetrics(SM_CYSCREEN);
- }
-#elif defined(__APPLE__)
- X = screens[n].x;
- Y = screens[n].y;
- W = screens[n].width;
- H = screens[n].height;
-#elif defined(FL_PORTING)
-# pragma message "FL_PORTING: implement screen_xywh"
- X = 0; Y = 0; W = 800; H = 600;
-#else
- if (num_screens > 0) {
- X = screens[n].x_org;
- Y = screens[n].y_org;
- W = screens[n].width;
- H = screens[n].height;
- }
-#endif // WIN32
+void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int n)
+{
+ screen_driver()->screen_xywh(X, Y, W, H, n);
+//
+// if (num_screens < 0) screen_init();
+//
+// if ((n < 0) || (n >= num_screens))
+// n = 0;
+//
+//#ifdef WIN32
+// if (num_screens > 0) {
+// X = screens[n].left;
+// Y = screens[n].top;
+// W = screens[n].right - screens[n].left;
+// H = screens[n].bottom - screens[n].top;
+// } else {
+// /* Fallback if something is broken... */
+// X = 0;
+// Y = 0;
+// W = GetSystemMetrics(SM_CXSCREEN);
+// H = GetSystemMetrics(SM_CYSCREEN);
+// }
+//#elif defined(__APPLE__)
+// X = screens[n].x;
+// Y = screens[n].y;
+// W = screens[n].width;
+// H = screens[n].height;
+//#elif defined(FL_PORTING)
+//# pragma message "FL_PORTING: implement screen_xywh"
+// X = 0; Y = 0; W = 800; H = 600;
+//#else
+// if (num_screens > 0) {
+// X = screens[n].x_org;
+// Y = screens[n].y_org;
+// W = screens[n].width;
+// H = screens[n].height;
+// }
+//#endif // WIN32
}
+
/**
Gets the screen bounding rect for the screen
which intersects the most with the rectangle
@@ -320,41 +343,22 @@ void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int n) {
\param[in] mx, my, mw, mh the rectangle to search for intersection with
\see void screen_xywh(int &X, int &Y, int &W, int &H, int n)
*/
-void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh) {
- screen_xywh(X, Y, W, H, screen_num(mx, my, mw, mh));
+void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh)
+{
+ screen_driver()->screen_xywh(X, Y, W, H, mx, my, mw, mh);
}
+
/**
Gets the screen number of a screen
that contains the specified screen position \p x, \p y
\param[in] x, y the absolute screen position
*/
-int Fl::screen_num(int x, int y) {
- int screen = 0;
- if (num_screens < 0) screen_init();
-
- for (int i = 0; i < num_screens; i ++) {
- int sx, sy, sw, sh;
- Fl::screen_xywh(sx, sy, sw, sh, i);
- if ((x >= sx) && (x < (sx+sw)) && (y >= sy) && (y < (sy+sh))) {
- screen = i;
- break;
- }
- }
- return screen;
+int Fl::screen_num(int x, int y)
+{
+ return screen_driver()->screen_num(x, y);
}
-// Return the number of pixels common to the two rectangular areas
-static inline float fl_intersection(int x1, int y1, int w1, int h1,
- int x2, int y2, int w2, int h2) {
- if(x1+w1 < x2 || x2+w2 < x1 || y1+h1 < y2 || y2+h2 < y1)
- return 0.;
- int int_left = x1 > x2 ? x1 : x2;
- int int_right = x1+w1 > x2+w2 ? x2+w2 : x1+w1;
- int int_top = y1 > y2 ? y1 : y2;
- int int_bottom = y1+h1 > y2+h2 ? y2+h2 : y1+h1;
- return (float)(int_right - int_left) * (int_bottom - int_top);
-}
/**
Gets the screen number for the screen
@@ -362,21 +366,12 @@ static inline float fl_intersection(int x1, int y1, int w1, int h1,
defined by \p x, \p y, \p w, \p h.
\param[in] x, y, w, h the rectangle to search for intersection with
*/
-int Fl::screen_num(int x, int y, int w, int h) {
- int best_screen = 0;
- float best_intersection = 0.;
- for (int i = 0; i < Fl::screen_count(); i++) {
- int sx = 0, sy = 0, sw = 0, sh = 0;
- Fl::screen_xywh(sx, sy, sw, sh, i);
- float sintersection = fl_intersection(x, y, w, h, sx, sy, sw, sh);
- if (sintersection > best_intersection) {
- best_screen = i;
- best_intersection = sintersection;
- }
- }
- return best_screen;
+int Fl::screen_num(int x, int y, int w, int h)
+{
+ return screen_driver()->screen_num(x, y, w, h);
}
+
/**
Gets the screen resolution in dots-per-inch for the given screen.
\param[out] h, v horizontal and vertical resolution
@@ -385,27 +380,50 @@ int Fl::screen_num(int x, int y, int w, int h) {
*/
void Fl::screen_dpi(float &h, float &v, int n)
{
- if (num_screens < 0) screen_init();
- h = v = 0.0f;
+ screen_driver()->screen_dpi(h, v, n);
+// if (num_screens < 0) screen_init();
+// h = v = 0.0f;
+//
+//#ifdef WIN32
+// if (n >= 0 && n < num_screens) {
+// h = float(dpi[n][0]);
+// v = float(dpi[n][1]);
+// }
+//#elif defined(__APPLE__)
+// if (n >= 0 && n < num_screens) {
+// h = dpi_h[n];
+// v = dpi_v[n];
+// }
+//#elif defined(FL_PORTING)
+//# pragma message "FL_PORTING: implement screen_dpi"
+//#else
+// if (n >= 0 && n < num_screens) {
+// h = dpi[n][0];
+// v = dpi[n][1];
+// }
+//#endif // WIN32
+}
-#ifdef WIN32
- if (n >= 0 && n < num_screens) {
- h = float(dpi[n][0]);
- v = float(dpi[n][1]);
- }
-#elif defined(__APPLE__)
- if (n >= 0 && n < num_screens) {
- h = dpi_h[n];
- v = dpi_v[n];
- }
-#elif defined(FL_PORTING)
-# pragma message "FL_PORTING: implement screen_dpi"
-#else
- if (n >= 0 && n < num_screens) {
- h = dpi[n][0];
- v = dpi[n][1];
- }
-#endif // WIN32
+
+/**
+ Gets the bounding box of a screen that contains the mouse pointer.
+ \param[out] X,Y,W,H the corresponding screen bounding box
+ \see void screen_xywh(int &x, int &y, int &w, int &h, int mx, int my)
+ */
+void Fl::screen_xywh(int &X, int &Y, int &W, int &H)
+{
+ Fl::screen_driver()->screen_xywh(X, Y, W, H);
+}
+
+
+/**
+ Gets the bounding box of the work area of the screen that contains the mouse pointer.
+ \param[out] X,Y,W,H the work area bounding box
+ \see void screen_work_area(int &x, int &y, int &w, int &h, int mx, int my)
+ */
+void Fl::screen_work_area(int &X, int &Y, int &W, int &H)
+{
+ Fl::screen_driver()->screen_xywh(X, Y, W, H);
}