diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2016-02-10 20:26:51 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2016-02-10 20:26:51 +0000 |
| commit | c3b3105720fbe10af88c97c25bc8939659021f07 (patch) | |
| tree | 05f2cd0543a209df99e3b8531bb80477ccf4eb72 /src/drivers | |
| parent | e83bc2527fd412bc235f1f8743659e31b12bdc31 (diff) | |
Fix Screen Driver implementation for X11
- moved stuff around to fit X11 file layout
- fixed a few Cocoa variables
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11149 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/drivers')
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h | 9 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.cxx | 144 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.h | 14 |
3 files changed, 140 insertions, 27 deletions
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h index b0a64743c..4023e8706 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h +++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h @@ -26,6 +26,7 @@ #define FL_COCOA_SCREEN_DRIVER_H #include <FL/Fl_Screen_Driver.H> +#include <FL/x.H> /* Move everything here that manages the native screen interface. @@ -38,7 +39,13 @@ */ -class FL_EXPORT Fl_Cocoa_Screen_Driver : public Fl_Screen_Driver { +class FL_EXPORT Fl_Cocoa_Screen_Driver : public Fl_Screen_Driver +{ +protected: + XRectangle screens[MAX_SCREENS]; + float dpi_h[MAX_SCREENS]; + float dpi_v[MAX_SCREENS]; + public: virtual void init(); virtual int x(); diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.cxx b/src/drivers/X11/Fl_X11_Screen_Driver.cxx index 2891ac1f9..6ae8458a1 100644 --- a/src/drivers/X11/Fl_X11_Screen_Driver.cxx +++ b/src/drivers/X11/Fl_X11_Screen_Driver.cxx @@ -19,6 +19,14 @@ #include "../../config_lib.h" #include "Fl_X11_Screen_Driver.h" +#include <FL/Fl.H> +#include <FL/x.H> + +#if HAVE_XINERAMA +# include <X11/extensions/Xinerama.h> +#endif + +extern Atom fl_NET_WORKAREA; /** @@ -33,28 +41,105 @@ Fl_Screen_Driver *Fl_Screen_Driver::newScreenDriver() } +static int fl_workarea_xywh[4] = { -1, -1, -1, -1 }; + +void Fl_X11_Screen_Driver::init_workarea() +{ + fl_open_display(); + + Atom actual; + unsigned long count, remaining; + int format; + long *xywh = 0; + + /* If there are several screens, the _NET_WORKAREA property + does not give the work area of the main screen, but that of all screens together. + Therefore, we use this property only when there is a single screen, + and fall back to the main screen full area when there are several screens. + */ + if (Fl::screen_count() > 1 || XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen), + fl_NET_WORKAREA, 0, 4, False, + XA_CARDINAL, &actual, &format, &count, &remaining, + (unsigned char **)&xywh) || !xywh || !xywh[2] || + !xywh[3]) + { + Fl::screen_xywh(fl_workarea_xywh[0], + fl_workarea_xywh[1], + fl_workarea_xywh[2], + fl_workarea_xywh[3], 0); + } + else + { + fl_workarea_xywh[0] = (int)xywh[0]; + fl_workarea_xywh[1] = (int)xywh[1]; + fl_workarea_xywh[2] = (int)xywh[2]; + fl_workarea_xywh[3] = (int)xywh[3]; + } + if ( xywh ) { XFree(xywh); xywh = 0; } +} + + +int Fl_X11_Screen_Driver::x() { + if (fl_workarea_xywh[0] < 0) init_workarea(); + return fl_workarea_xywh[0]; +} + +int Fl_X11_Screen_Driver::y() { + if (fl_workarea_xywh[0] < 0) init_workarea(); + return fl_workarea_xywh[1]; +} + +int Fl_X11_Screen_Driver::w() { + if (fl_workarea_xywh[0] < 0) init_workarea(); + return fl_workarea_xywh[2]; +} + +int Fl_X11_Screen_Driver::h() { + if (fl_workarea_xywh[0] < 0) init_workarea(); + return fl_workarea_xywh[3]; +} + + 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.; + if (!fl_display) fl_open_display(); + // FIXME: Rewrite using RandR instead +#if HAVE_XINERAMA + if (XineramaIsActive(fl_display)) { + XineramaScreenInfo *xsi = XineramaQueryScreens(fl_display, &num_screens); + if (num_screens > MAX_SCREENS) num_screens = MAX_SCREENS; + + /* There's no way to use different DPI for different Xinerama screens. */ + for (int i=0; i<num_screens; i++) { + screens[i].x_org = xsi[i].x_org; + screens[i].y_org = xsi[i].y_org; + screens[i].width = xsi[i].width; + screens[i].height = xsi[i].height; + + int mm = DisplayWidthMM(fl_display, fl_screen); + dpi[i][0] = mm ? screens[i].width*25.4f/mm : 0.0f; + mm = DisplayHeightMM(fl_display, fl_screen); + dpi[i][1] = mm ? screens[i].height*25.4f/mm : 0.0f; + } + if (xsi) XFree(xsi); + } else +#endif + { // ! XineramaIsActive() + num_screens = ScreenCount(fl_display); + if (num_screens > MAX_SCREENS) num_screens = MAX_SCREENS; + + for (int i=0; i<num_screens; i++) { + screens[i].x_org = 0; + screens[i].y_org = 0; + screens[i].width = DisplayWidth(fl_display, i); + screens[i].height = DisplayHeight(fl_display, i); + + int mm = DisplayWidthMM(fl_display, i); + dpi[i][0] = mm ? DisplayWidth(fl_display, i)*25.4f/mm : 0.0f; + mm = DisplayHeightMM(fl_display, i); + dpi[i][1] = mm ? DisplayHeight(fl_display, i)*25.4f/mm : 0.0f; } } - num_screens = count; } @@ -62,7 +147,14 @@ void Fl_X11_Screen_Driver::screen_work_area(int &X, int &Y, int &W, int &H, int { if (num_screens < 0) init(); if (n < 0 || n >= num_screens) n = 0; - Fl_X::screen_work_area(X, Y, W, H, n); + 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); + } } @@ -73,10 +165,12 @@ void Fl_X11_Screen_Driver::screen_xywh(int &X, int &Y, int &W, int &H, int n) if ((n < 0) || (n >= num_screens)) n = 0; - X = screens[n].x; - Y = screens[n].y; - W = screens[n].width; - H = screens[n].height; + if (num_screens > 0) { + X = screens[n].x_org; + Y = screens[n].y_org; + W = screens[n].width; + H = screens[n].height; + } } @@ -86,8 +180,8 @@ void Fl_X11_Screen_Driver::screen_dpi(float &h, float &v, int n) h = v = 0.0f; if (n >= 0 && n < num_screens) { - h = dpi_h[n]; - v = dpi_v[n]; + h = dpi[n][0]; + v = dpi[n][1]; } } diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.h b/src/drivers/X11/Fl_X11_Screen_Driver.h index 8c7bc8da2..23e57fd52 100644 --- a/src/drivers/X11/Fl_X11_Screen_Driver.h +++ b/src/drivers/X11/Fl_X11_Screen_Driver.h @@ -28,8 +28,20 @@ #include <FL/Fl_Screen_Driver.H> -class FL_EXPORT Fl_X11_Screen_Driver : public Fl_Screen_Driver { +class FL_EXPORT Fl_X11_Screen_Driver : public Fl_Screen_Driver +{ +protected: + typedef struct { + short x_org; + short y_org; + short width; + short height; + } FLScreenInfo; + FLScreenInfo screens[MAX_SCREENS]; + float dpi[MAX_SCREENS][2]; + public: + void init_workarea(); virtual void init(); virtual int x(); virtual int y(); |
