summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2016-02-10 20:26:51 +0000
committerMatthias Melcher <fltk@matthiasm.com>2016-02-10 20:26:51 +0000
commitc3b3105720fbe10af88c97c25bc8939659021f07 (patch)
tree05f2cd0543a209df99e3b8531bb80477ccf4eb72 /src/drivers
parente83bc2527fd412bc235f1f8743659e31b12bdc31 (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.h9
-rw-r--r--src/drivers/X11/Fl_X11_Screen_Driver.cxx144
-rw-r--r--src/drivers/X11/Fl_X11_Screen_Driver.h14
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();