diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 7 | ||||
| -rw-r--r-- | src/Fl.cxx | 18 | ||||
| -rw-r--r-- | src/Fl_Screen_Driver.cxx | 124 | ||||
| -rw-r--r-- | src/Fl_cocoa.mm | 9 | ||||
| -rw-r--r-- | src/Makefile | 12 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx | 72 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h | 16 | ||||
| -rw-r--r-- | src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx | 98 | ||||
| -rw-r--r-- | src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.h | 58 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.cxx | 98 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.h | 48 | ||||
| -rw-r--r-- | src/screen_xywh.cxx | 336 |
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); } |
