Basic Screen Driver Structure. LIMBO!

Creating the basic structure for a screen driver system.
OS X works X11 and WinAPI are in limbo and will be fixed in the next hour or so.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11148 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Matthias Melcher 2016-02-10 19:49:35 +00:00
parent 478d633620
commit e83bc2527f
15 changed files with 2241 additions and 208 deletions

67
FL/Fl.H
View File

@ -3,7 +3,7 @@
//
// Main header file for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2010 by Bill Spitzak and others.
// 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
@ -134,10 +134,16 @@ typedef void (*Fl_Clipboard_Notify_Handler)(int source, void *data);
*/
class FL_EXPORT Fl {
Fl() {}; // no constructor!
private:
static class Fl_Screen_Driver *screen_driver_;
static int use_high_res_GL_;
public:
static Fl_Screen_Driver *screen_driver();
public: // run time information about compile time configuration
/** \defgroup cfg_gfx runtime graphics driver configuration */
/** @{ */
@ -1002,51 +1008,30 @@ int main() {
static void selection(Fl_Widget &owner, const char*, int len);
static void paste(Fl_Widget &receiver);
/** @} */
/** \defgroup fl_screen Screen functions
fl global screen functions declared in <FL/Fl.H>
@{ */
// screen size:
/** Returns the leftmost x coordinate of the main screen work area. */
static int x(); // platform dependent
/** Returns the topmost y coordinate of the main screen work area. */
static int y(); // platform dependent
/** Returns the width in pixels of the main screen work area. */
static int w(); // platform dependent
/** Returns the height in pixels of the main screen work area. */
static int h(); // platform dependent
static int x(); // via screen driver
static int y(); // via screen driver
static int w(); // via screen driver
static int h(); // via screen driver
// multi-head support:
static int screen_count();
/**
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)
*/
static void 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);
}
static void screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my);
static void screen_xywh(int &X, int &Y, int &W, int &H, int n);
static void screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh);
static int screen_num(int x, int y);
static int screen_num(int x, int y, int w, int h);
static void screen_dpi(float &h, float &v, int n=0);
static void screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my);
static void screen_work_area(int &X, int &Y, int &W, int &H, int n);
/**
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)
*/
static void 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);
}
static int screen_count(); // via screen driver
static void screen_xywh(int &X, int &Y, int &W, int &H); // via screen driver
static void screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my); // via screen driver
static void screen_xywh(int &X, int &Y, int &W, int &H, int n); // via screen driver
static void screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh); // via screen driver
static int screen_num(int x, int y); // via screen driver
static int screen_num(int x, int y, int w, int h); // via screen driver
static void screen_dpi(float &h, float &v, int n=0); // via screen driver
static void screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my); // via screen driver
static void screen_work_area(int &X, int &Y, int &W, int &H, int n); // via screen driver
static void screen_work_area(int &X, int &Y, int &W, int &H); // via screen driver
/** @} */
/** @} */
/** \defgroup fl_attributes Color & Font functions
fl global color, font functions.

View File

@ -31,6 +31,7 @@
class Fl_Graphics_Driver;
class Fl_Font_Descriptor;
class Fl_RGB_Image;
/**
All graphical output devices and all graphics systems.

1485
FL/Fl_Screen_Driver.H Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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)

View File

@ -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$".
//

124
src/Fl_Screen_Driver.cxx Normal file
View File

@ -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$".
//

View File

@ -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);
}

View File

@ -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

View File

@ -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$".
//

View File

@ -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
//

View File

@ -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$".
//

View File

@ -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 $".
//

View File

@ -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$".
//

View File

@ -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 $".
//

View File

@ -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();
}
#endif
/** 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();
}
/** 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);
}