summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2016-02-13 16:12:57 +0000
committerMatthias Melcher <fltk@matthiasm.com>2016-02-13 16:12:57 +0000
commitd8f96b579d9359f62b984b2043a8f8c6854efe98 (patch)
tree00b5fa4cd4a195aa82431b0c211a717d6e4b6d86 /src
parent4af616a7a27c3104938bf580502c762becd4417b (diff)
Moed Fl::visual and System_Scheme to the driver
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11166 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
-rw-r--r--src/Fl.cxx87
-rw-r--r--src/Fl_Screen_Driver.cxx11
-rw-r--r--src/Fl_Tooltip.cxx2
-rw-r--r--src/Fl_get_system_colors.cxx23
-rw-r--r--src/Fl_grab.cxx88
-rw-r--r--src/Fl_visual.cxx90
-rw-r--r--src/Fl_win32.cxx2
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx46
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h9
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx58
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.h9
-rw-r--r--src/drivers/X11/Fl_X11_Screen_Driver.cxx194
-rw-r--r--src/drivers/X11/Fl_X11_Screen_Driver.h8
13 files changed, 363 insertions, 264 deletions
diff --git a/src/Fl.cxx b/src/Fl.cxx
index b3211f83b..329839b3a 100644
--- a/src/Fl.cxx
+++ b/src/Fl.cxx
@@ -74,7 +74,6 @@ void fl_cleanup_pens(void);
void fl_release_dc(HWND,HDC);
void fl_cleanup_dc_list(void);
#elif defined(__APPLE__) // PORTME: Fl_Screen_Driver - platform functions
-extern double fl_mac_flush_and_wait(double time_to_wait);
#endif // WIN32
@@ -160,6 +159,7 @@ bool Fl::cfg_sys_win32 = 0;
// Globals...
//
#if defined(__APPLE__) || defined(FL_DOXYGEN) // PORTME: Fl_Screen_Driver - platform text
+ // this should probably be part of Fl_Sys_Menubar
const char *Fl_Mac_App_Menu::about = "About %@";
const char *Fl_Mac_App_Menu::print = "Print Front Window";
const char *Fl_Mac_App_Menu::services = "Services";
@@ -543,7 +543,7 @@ int Fl::has_check(Fl_Timeout_Handler cb, void *argp) {
return 0;
}
-static void run_checks()
+void Fl::run_checks()
{
// checks are a bit messy so that add/remove and wait may be called
// from inside them without causing an infinite loop:
@@ -557,9 +557,6 @@ static void run_checks()
}
}
-#if !defined(WIN32) && !defined(__APPLE__) // PORTME: ??
-static char in_idle;
-#endif
////////////////////////////////////////////////////////////////
// Clipboard notifications
@@ -639,68 +636,7 @@ extern int fl_wait(double time); // in Fl_<platform>.cxx
double Fl::wait(double time_to_wait) {
// delete all widgets that were listed during callbacks
do_widget_deletion();
-
-#ifdef WIN32
-
- return fl_wait(time_to_wait);
-
-#elif defined(__APPLE__) // PORTME: Fl_Screen_Driver - platform fl_wait
-
- run_checks();
- return fl_mac_flush_and_wait(time_to_wait);
-
-#elif defined(FL_PORTING)
-
-# pragma message "FL_PORTING: implement waiting for a timer or a message from the system"
- return fl_wait(time_to_wait);
-
-#else
-
- if (first_timeout) {
- elapse_timeouts();
- Timeout *t;
- while ((t = first_timeout)) {
- if (t->time > 0) break;
- // The first timeout in the array has expired.
- missed_timeout_by = t->time;
- // We must remove timeout from array before doing the callback:
- void (*cb)(void*) = t->cb;
- void *argp = t->arg;
- first_timeout = t->next;
- t->next = free_timeout;
- free_timeout = t;
- // Now it is safe for the callback to do add_timeout:
- cb(argp);
- }
- } else {
- reset_clock = 1; // we are not going to check the clock
- }
- run_checks();
-// if (idle && !fl_ready()) {
- if (idle) {
- if (!in_idle) {
- in_idle = 1;
- idle();
- in_idle = 0;
- }
- // the idle function may turn off idle, we can then wait:
- if (idle) time_to_wait = 0.0;
- }
- if (first_timeout && first_timeout->time < time_to_wait)
- time_to_wait = first_timeout->time;
- if (time_to_wait <= 0.0) {
- // do flush second so that the results of events are visible:
- int ret = fl_wait(0.0);
- flush();
- return ret;
- } else {
- // do flush first so that user sees the display:
- flush();
- if (idle && !in_idle) // 'idle' may have been set within flush()
- time_to_wait = 0.0;
- return fl_wait(time_to_wait);
- }
-#endif
+ return screen_driver()->wait(time_to_wait);
}
#define FOREVER 1e20
@@ -786,20 +722,9 @@ int Fl::check() {
}
\endcode
*/
-int Fl::ready() {
-#if defined( WIN32 ) || defined(__APPLE__) // PORTME: Fl_System_Driver - platform timeouts
- // not used
-#elif defined(FL_PORTING)
-# pragma message "FL_PORTING: you may need to handle timers here."
-#else // X11
- if (first_timeout) {
- elapse_timeouts();
- if (first_timeout->time <= 0) return 1;
- } else {
- reset_clock = 1;
- }
-#endif
- return fl_ready();
+int Fl::ready()
+{
+ return screen_driver()->ready();
}
////////////////////////////////////////////////////////////////
diff --git a/src/Fl_Screen_Driver.cxx b/src/Fl_Screen_Driver.cxx
index 38ba38f3c..dcaad6571 100644
--- a/src/Fl_Screen_Driver.cxx
+++ b/src/Fl_Screen_Driver.cxx
@@ -38,6 +38,12 @@ void Fl_Screen_Driver::display(const char *) {
}
+int Fl_Screen_Driver::visual(int) {
+ // blank
+ return 1;
+}
+
+
void Fl_Screen_Driver::screen_xywh(int &X, int &Y, int &W, int &H)
{
int x, y;
@@ -128,6 +134,11 @@ int Fl_Screen_Driver::screen_num(int x, int y, int w, int h)
}
+const char *Fl_Screen_Driver::get_system_scheme()
+{
+ return 0L;
+}
+
//
// End of "$Id$".
diff --git a/src/Fl_Tooltip.cxx b/src/Fl_Tooltip.cxx
index c8057d528..26a2496eb 100644
--- a/src/Fl_Tooltip.cxx
+++ b/src/Fl_Tooltip.cxx
@@ -151,7 +151,7 @@ static void tooltip_timeout(void*) {
if (window) window->hide();
} else {
int condition = 1;
-#if !(defined(__APPLE__) || defined(WIN32)) // PORTME: Fl_Screen_Driver - platform ??
+#if !(defined(__APPLE__) || defined(WIN32)) // bugfix: no need to refactor
condition = (Fl::grab() == NULL);
#endif
if ( condition ) {
diff --git a/src/Fl_get_system_colors.cxx b/src/Fl_get_system_colors.cxx
index eae4002b5..55ba01d5b 100644
--- a/src/Fl_get_system_colors.cxx
+++ b/src/Fl_get_system_colors.cxx
@@ -60,6 +60,8 @@ void Fl::background(uchar r, uchar g, uchar b) {
uchar(pow(gray,powb)*255+.5));
}
}
+
+
/** Changes fl_color(FL_FOREGROUND_COLOR). */
void Fl::foreground(uchar r, uchar g, uchar b) {
Fl_Screen_Driver::fg_set = 1;
@@ -67,6 +69,7 @@ void Fl::foreground(uchar r, uchar g, uchar b) {
Fl::set_color(FL_FOREGROUND_COLOR,r,g,b);
}
+
/**
Changes the alternative background color. This color is used as a
background by Fl_Input and other text widgets.
@@ -81,6 +84,7 @@ void Fl::background2(uchar r, uchar g, uchar b) {
get_color(fl_contrast(FL_FOREGROUND_COLOR,FL_BACKGROUND2_COLOR)));
}
+
// these are set by Fl::args() and override any system colors:
const char *fl_fg = NULL;
const char *fl_bg = NULL;
@@ -133,6 +137,7 @@ Fl_Image *Fl::scheme_bg_ = (Fl_Image *)0; // current background image for the
static Fl_Pixmap tile(tile_xpm);
+
/**
Sets the current widget scheme. NULL will use the scheme defined
in the FLTK_SCHEME environment variable or the scheme resource
@@ -161,18 +166,7 @@ static Fl_Pixmap tile(tile_xpm);
*/
int Fl::scheme(const char *s) {
if (!s) {
- if ((s = getenv("FLTK_SCHEME")) == NULL) {
-#if defined(WIN32) || defined(__APPLE__) // PORTME: Fl_Screen_Driver - platform system scheme
-#elif defined(FL_PORTING)
-# pragma message "FL_PORTING: implement Fl::scheme"
-#else
- const char* key = 0;
- if (Fl::first_window()) key = Fl::first_window()->xclass();
- if (!key) key = "fltk";
- fl_open_display();
- s = XGetDefault(fl_display, key, "scheme");
-#endif // !WIN32 && !__APPLE__ // PORTME: Fl_Screen_Driver - platform system scheme
- }
+ s = screen_driver()->get_system_scheme();
}
if (s) {
@@ -196,6 +190,7 @@ int Fl::scheme(const char *s) {
return reload_scheme();
}
+
int Fl::reload_scheme() {
Fl_Window *win;
@@ -318,6 +313,10 @@ int Fl::reload_scheme() {
// is the workaround to use a group inside the window to achieve this.
// See also STR #3075.
// AlbrechtS, 01 Mar 2015
+ //
+ // If there is already an image assigned that is not the scheme_bg_,
+ // then don't change the labeltype or assign another image. Will that
+ // fix it?
for (win = first_window(); win; win = next_window(win)) {
win->labeltype(scheme_bg_ ? FL_NORMAL_LABEL : FL_NO_LABEL);
diff --git a/src/Fl_grab.cxx b/src/Fl_grab.cxx
index 22d49bbbd..f014c14d7 100644
--- a/src/Fl_grab.cxx
+++ b/src/Fl_grab.cxx
@@ -18,7 +18,7 @@
#include <config.h>
#include <FL/Fl.H>
-#include <FL/x.H>
+#include <FL/Fl_Screen_Driver.H>
////////////////////////////////////////////////////////////////
// "Grab" is done while menu systems are up. This has several effects:
@@ -28,90 +28,12 @@
// This also modifies how Fl_Window::show() works, on X it turns on
// override_redirect, it does similar things on WIN32.
-extern void fl_fix_focus(); // in Fl.cxx
-
-#ifdef WIN32
-// We have to keep track of whether we have captured the mouse, since
-// MSWindows shows little respect for this... Grep for fl_capture to
-// see where and how this is used.
-extern HWND fl_capture;
-
-#elif defined(__APPLE__) // PORTME: Fl_Screen_Driver - platform focus grabbing
-extern void *fl_capture;
-
-#elif defined(FL_PORTING)
-# pragma message "FL_PORTING: tell a window to grab all following events"
-
-#else // X11
-
-#endif
-
-void Fl::grab(Fl_Window* win) {
-#ifdef USE_X11
- Fl_Window *fullscreen_win = NULL;
- for (Fl_Window *W = Fl::first_window(); W; W = Fl::next_window(W)) {
- if (W->fullscreen_active()) {
- fullscreen_win = W;
- break;
- }
- }
-#endif
- if (win) {
- if (!grab_) {
-#ifdef WIN32
- SetActiveWindow(fl_capture = fl_xid(first_window()));
- SetCapture(fl_capture);
-#elif defined(__APPLE__) // PORTME: Fl_Screen_Driver - platform focus grabbing
- fl_capture = Fl_X::i(first_window())->xid;
- Fl_X::i(first_window())->set_key_window();
-#elif defined(FL_PORTING)
-# pragma message "FL_PORTING: implement event grabbing"
-#else
- Window xid = fullscreen_win ? fl_xid(fullscreen_win) : fl_xid(first_window());
- XGrabPointer(fl_display,
- xid,
- 1,
- ButtonPressMask|ButtonReleaseMask|
- ButtonMotionMask|PointerMotionMask,
- GrabModeAsync,
- GrabModeAsync,
- None,
- 0,
- fl_event_time);
- XGrabKeyboard(fl_display,
- xid,
- 1,
- GrabModeAsync,
- GrabModeAsync,
- fl_event_time);
-#endif
- }
- grab_ = win;
- } else {
- if (grab_) {
-#ifdef WIN32
- fl_capture = 0;
- ReleaseCapture();
-#elif defined(__APPLE__) // PORTME: Fl_Screen_Driver - platform focus grabbing
- fl_capture = 0;
-#elif defined(FL_PORTING)
-# pragma message "FL_PORTING: implement event grabbing"
-#else
- // We must keep the grab in the non-EWMH fullscreen case
- if (!fullscreen_win || Fl_X::ewmh_supported()) {
- XUngrabKeyboard(fl_display, fl_event_time);
- }
- XUngrabPointer(fl_display, fl_event_time);
- // this flush is done in case the picked menu item goes into
- // an infinite loop, so we don't leave the X server locked up:
- XFlush(fl_display);
-#endif
- grab_ = 0;
- fl_fix_focus();
- }
- }
+void Fl::grab(Fl_Window *win)
+{
+ screen_driver()->grab(win);
}
+
//
// End of "$Id$".
//
diff --git a/src/Fl_visual.cxx b/src/Fl_visual.cxx
index 65534e5a5..e3c08806e 100644
--- a/src/Fl_visual.cxx
+++ b/src/Fl_visual.cxx
@@ -20,7 +20,7 @@
#include <config.h>
#include <FL/Fl.H>
-#include <FL/x.H>
+#include <FL/Fl_Screen_Driver.H>
/** \fn Fl::visual(int flags)
Selects a visual so that your graphics are drawn correctly. This is
@@ -56,93 +56,11 @@
FLTK suceeded in turing them on. Your program will still work even if
this returns false (it just won't look as good).
*/
-#ifdef WIN32
-int Fl::visual(int flags) {
- fl_GetDC(0);
- if (flags & FL_DOUBLE) return 0;
- if (!(flags & FL_INDEX) &&
- GetDeviceCaps(fl_gc,BITSPIXEL) <= 8) return 0;
- if ((flags & FL_RGB8) && GetDeviceCaps(fl_gc,BITSPIXEL)<24) return 0;
- return 1;
+int Fl::visual(int flags)
+{
+ return screen_driver()->visual(flags);
}
-#elif defined(__APPLE__) // PORTME: Fl_Screen_Driver - platform visuals
-// \todo Mac : need to implement Visual flags
-int Fl::visual(int flags) {
- (void)flags;
- return 1;
-}
-
-#elif defined(FL_PORTING)
-# pragma message "FL_PORTING: add code to handle RGB and color index visuals"
-
-#else
-
-#if USE_XDBE
-#include <X11/extensions/Xdbe.h>
-#endif
-
-static int test_visual(XVisualInfo& v, int flags) {
- if (v.screen != fl_screen) return 0;
-#if USE_COLORMAP
- if (!(flags & FL_INDEX)) {
- if (v.c_class != StaticColor && v.c_class != TrueColor) return 0;
- if (v.depth <= 8) return 0; // fltk will work better in colormap mode
- }
- if (flags & FL_RGB8) {
- if (v.depth < 24) return 0;
- }
- // for now, fltk does not like colormaps of more than 8 bits:
- if ((v.c_class&1) && v.depth > 8) return 0;
-#else
- // simpler if we can't use colormapped visuals at all:
- if (v.c_class != StaticColor && v.c_class != TrueColor) return 0;
-#endif
-#if USE_XDBE
- if (flags & FL_DOUBLE) {
- static XdbeScreenVisualInfo *xdbejunk;
- if (!xdbejunk) {
- int event_base, error_base;
- if (!XdbeQueryExtension(fl_display, &event_base, &error_base)) return 0;
- Drawable root = RootWindow(fl_display,fl_screen);
- int numscreens = 1;
- xdbejunk = XdbeGetVisualInfo(fl_display,&root,&numscreens);
- if (!xdbejunk) return 0;
- }
- for (int j = 0; ; j++) {
- if (j >= xdbejunk->count) return 0;
- if (xdbejunk->visinfo[j].visual == v.visualid) break;
- }
- }
-#endif
- return 1;
-}
-
-int Fl::visual(int flags) {
-#if USE_XDBE == 0
- if (flags & FL_DOUBLE) return 0;
-#endif
- fl_open_display();
- // always use default if possible:
- if (test_visual(*fl_visual, flags)) return 1;
- // get all the visuals:
- XVisualInfo vTemplate;
- int num;
- XVisualInfo *visualList = XGetVisualInfo(fl_display, 0, &vTemplate, &num);
- // find all matches, use the one with greatest depth:
- XVisualInfo *found = 0;
- for (int i=0; i<num; i++) if (test_visual(visualList[i], flags)) {
- if (!found || found->depth < visualList[i].depth)
- found = &visualList[i];
- }
- if (!found) {XFree((void*)visualList); return 0;}
- fl_visual = found;
- fl_colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
- fl_visual->visual, AllocNone);
- return 1;
-}
-
-#endif
//
// End of "$Id$".
diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx
index 0edf3dd53..1b674c4b3 100644
--- a/src/Fl_win32.cxx
+++ b/src/Fl_win32.cxx
@@ -365,7 +365,7 @@ static void process_awake_handler_requests(void) {
int fl_wait(double time_to_wait) {
int have_message = 0;
- run_checks();
+ Fl::run_checks();
// idle processing
static char in_idle;
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
index e34f8b998..5bd136bcd 100644
--- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
+++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
@@ -20,12 +20,16 @@
#include "../../config_lib.h"
#include "Fl_Cocoa_Screen_Driver.h"
#include <FL/Fl.H>
+#include <FL/x.H>
#include <FL/fl_ask.h>
#include <stdio.h>
extern "C" void NSBeep(void);
+extern double fl_mac_flush_and_wait(double time_to_wait);
+extern int fl_ready();
+
/**
Creates a driver that manages all screen and display related calls.
@@ -121,6 +125,42 @@ void Fl_Cocoa_Screen_Driver::flush() {
}
+double Fl_Cocoa_Screen_Driver::wait(double time_to_wait)
+{
+ Fl::run_checks();
+ return fl_mac_flush_and_wait(time_to_wait);
+}
+
+
+int Fl_Cocoa_Screen_Driver::ready()
+{
+ return fl_ready();
+}
+
+
+extern void fl_fix_focus(); // in Fl.cxx
+
+extern void *fl_capture;
+
+
+void Fl_Cocoa_Screen_Driver::grab(Fl_Window* win)
+{
+ if (win) {
+ if (!Fl::grab_) {
+ fl_capture = Fl_X::i(Fl::first_window())->xid;
+ Fl_X::i(Fl::first_window())->set_key_window();
+ }
+ Fl::grab_ = win;
+ } else {
+ if (Fl::grab_) {
+ fl_capture = 0;
+ Fl::grab_ = 0;
+ fl_fix_focus();
+ }
+ }
+}
+
+
// simulation of XParseColor:
int Fl_Cocoa_Screen_Driver::parse_color(const char* p, uchar& r, uchar& g, uchar& b)
{
@@ -182,6 +222,12 @@ void Fl_Cocoa_Screen_Driver::get_system_colors()
}
+const char *Fl_Cocoa_Screen_Driver::get_system_scheme()
+{
+ return getenv("FLTK_SCHEME");
+}
+
+
//
// End of "$Id$".
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h
index b06192205..22c17b165 100644
--- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h
+++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h
@@ -39,6 +39,9 @@
*/
+class Fl_Window;
+
+
class FL_EXPORT Fl_Cocoa_Screen_Driver : public Fl_Screen_Driver
{
protected:
@@ -47,6 +50,8 @@ protected:
float dpi_v[MAX_SCREENS];
public:
+ // --- display management
+ // --- screen configuration
virtual void init();
virtual int x();
virtual int y();
@@ -59,9 +64,13 @@ public:
virtual void beep(int type);
// --- global events
virtual void flush();
+ virtual double wait(double time_to_wait);
+ virtual int ready();
+ virtual void grab(Fl_Window* win);
// --- global colors
virtual int parse_color(const char* p, uchar& r, uchar& g, uchar& b);
virtual void get_system_colors();
+ virtual const char *get_system_scheme();
};
diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
index 9c3b450cd..3d39ba7ed 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
+++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
@@ -19,6 +19,8 @@
#include "../../config_lib.h"
#include "Fl_WinAPI_Screen_Driver.h"
+#include <FL/Fl.H>
+#include <FL/x.H>
#include <FL/fl_ask.h>
#include <stdio.h>
@@ -40,6 +42,17 @@ Fl_Screen_Driver *Fl_Screen_Driver::newScreenDriver()
}
+int Fl_Screen_Driver::visual(int flags)
+{
+ fl_GetDC(0);
+ if (flags & FL_DOUBLE) return 0;
+ if (!(flags & FL_INDEX) &&
+ GetDeviceCaps(fl_gc,BITSPIXEL) <= 8) return 0;
+ if ((flags & FL_RGB8) && GetDeviceCaps(fl_gc,BITSPIXEL)<24) return 0;
+ return 1;
+}
+
+
// 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.
@@ -240,6 +253,45 @@ void Fl_WinAPI_Screen_Driver::flush()
}
+double Fl_WinAPI_Screen_Driver::wait(double time_to_wait)
+{
+ return fl_wait(time_to_wait);
+}
+
+
+int Fl_WinAPI_Screen_Driver::ready()
+{
+ return fl_ready();
+}
+
+
+extern void fl_fix_focus(); // in Fl.cxx
+
+// We have to keep track of whether we have captured the mouse, since
+// MSWindows shows little respect for this... Grep for fl_capture to
+// see where and how this is used.
+extern HWND fl_capture;
+
+
+void Fl_WinAPI_Screen_Driver::grab(Fl_Window* win)
+{
+ if (win) {
+ if (!Fl::grab_) {
+ SetActiveWindow(fl_capture = fl_xid(Fl::first_window()));
+ SetCapture(fl_capture);
+ }
+ Fl::grab_ = win;
+ } else {
+ if (Fl::grab_) {
+ fl_capture = 0;
+ ReleaseCapture();
+ Fl::grab_ = 0;
+ fl_fix_focus();
+ }
+ }
+}
+
+
// simulation of XParseColor:
int Fl_WinAPI_Screen_Driver::parse_color(const char* p, uchar& r, uchar& g, uchar& b)
{
@@ -295,6 +347,12 @@ void Fl_WinAPI_Screen_Driver::get_system_colors()
}
+const char *Fl_WinAPI_Screen_Driver::get_system_scheme()
+{
+ return getenv("FLTK_SCHEME");
+}
+
+
//
diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.h b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.h
index b44b70ebb..d6f5f01f1 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.h
+++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.h
@@ -29,6 +29,9 @@
#include <FL/x.H>
+class Fl_Window;
+
+
class FL_EXPORT Fl_WinAPI_Screen_Driver : public Fl_Screen_Driver
{
protected:
@@ -40,6 +43,8 @@ protected:
BOOL screen_cb(HMONITOR mon, HDC, LPRECT r);
public:
+ // --- display management
+ virtual int visual(int flags);
// --- screen configuration
virtual void init();
virtual int x();
@@ -53,9 +58,13 @@ public:
virtual void beep(int type);
// --- global events
virtual void flush();
+ virtual double wait(double time_to_wait);
+ virtual int ready();
+ virtual void grab(Fl_Window* win);
// --- global colors
virtual int parse_color(const char* p, uchar& r, uchar& g, uchar& b);
virtual void get_system_colors();
+ virtual const char *get_system_scheme();
};
diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.cxx b/src/drivers/X11/Fl_X11_Screen_Driver.cxx
index 7991e94f8..f60d565d9 100644
--- a/src/drivers/X11/Fl_X11_Screen_Driver.cxx
+++ b/src/drivers/X11/Fl_X11_Screen_Driver.cxx
@@ -27,6 +27,10 @@
# include <X11/extensions/Xinerama.h>
#endif
+#if USE_XDBE
+#include <X11/extensions/Xdbe.h>
+#endif
+
extern Atom fl_NET_WORKAREA;
@@ -63,6 +67,69 @@ void Fl_X11_Screen_Driver::display(const char *d)
}
+static int test_visual(XVisualInfo& v, int flags) {
+ if (v.screen != fl_screen) return 0;
+#if USE_COLORMAP
+ if (!(flags & FL_INDEX)) {
+ if (v.c_class != StaticColor && v.c_class != TrueColor) return 0;
+ if (v.depth <= 8) return 0; // fltk will work better in colormap mode
+ }
+ if (flags & FL_RGB8) {
+ if (v.depth < 24) return 0;
+ }
+ // for now, fltk does not like colormaps of more than 8 bits:
+ if ((v.c_class&1) && v.depth > 8) return 0;
+#else
+ // simpler if we can't use colormapped visuals at all:
+ if (v.c_class != StaticColor && v.c_class != TrueColor) return 0;
+#endif
+#if USE_XDBE
+ if (flags & FL_DOUBLE) {
+ static XdbeScreenVisualInfo *xdbejunk;
+ if (!xdbejunk) {
+ int event_base, error_base;
+ if (!XdbeQueryExtension(fl_display, &event_base, &error_base)) return 0;
+ Drawable root = RootWindow(fl_display,fl_screen);
+ int numscreens = 1;
+ xdbejunk = XdbeGetVisualInfo(fl_display,&root,&numscreens);
+ if (!xdbejunk) return 0;
+ }
+ for (int j = 0; ; j++) {
+ if (j >= xdbejunk->count) return 0;
+ if (xdbejunk->visinfo[j].visual == v.visualid) break;
+ }
+ }
+#endif
+ return 1;
+}
+
+
+int Fl_X11_Screen_Driver::visual(int flags)
+{
+#if USE_XDBE == 0
+ if (flags & FL_DOUBLE) return 0;
+#endif
+ fl_open_display();
+ // always use default if possible:
+ if (test_visual(*fl_visual, flags)) return 1;
+ // get all the visuals:
+ XVisualInfo vTemplate;
+ int num;
+ XVisualInfo *visualList = XGetVisualInfo(fl_display, 0, &vTemplate, &num);
+ // find all matches, use the one with greatest depth:
+ XVisualInfo *found = 0;
+ for (int i=0; i<num; i++) if (test_visual(visualList[i], flags)) {
+ if (!found || found->depth < visualList[i].depth)
+ found = &visualList[i];
+ }
+ if (!found) {XFree((void*)visualList); return 0;}
+ fl_visual = found;
+ fl_colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
+ fl_visual->visual, AllocNone);
+ return 1;
+}
+
+
static int fl_workarea_xywh[4] = { -1, -1, -1, -1 };
@@ -232,6 +299,119 @@ void Fl_X11_Screen_Driver::flush()
}
+double Fl_X11_Screen_Driver::wait(double time_to_wait)
+{
+ static char in_idle;
+
+ if (first_timeout) {
+ elapse_timeouts();
+ Timeout *t;
+ while ((t = first_timeout)) {
+ if (t->time > 0) break;
+ // The first timeout in the array has expired.
+ missed_timeout_by = t->time;
+ // We must remove timeout from array before doing the callback:
+ void (*cb)(void*) = t->cb;
+ void *argp = t->arg;
+ first_timeout = t->next;
+ t->next = free_timeout;
+ free_timeout = t;
+ // Now it is safe for the callback to do add_timeout:
+ cb(argp);
+ }
+ } else {
+ reset_clock = 1; // we are not going to check the clock
+ }
+ Fl::run_checks();
+ // if (idle && !fl_ready()) {
+ if (idle) {
+ if (!in_idle) {
+ in_idle = 1;
+ idle();
+ in_idle = 0;
+ }
+ // the idle function may turn off idle, we can then wait:
+ if (idle) time_to_wait = 0.0;
+ }
+ if (first_timeout && first_timeout->time < time_to_wait)
+ time_to_wait = first_timeout->time;
+ if (time_to_wait <= 0.0) {
+ // do flush second so that the results of events are visible:
+ int ret = fl_wait(0.0);
+ flush();
+ return ret;
+ } else {
+ // do flush first so that user sees the display:
+ flush();
+ if (idle && !in_idle) // 'idle' may have been set within flush()
+ time_to_wait = 0.0;
+ return fl_wait(time_to_wait);
+ }
+}
+
+
+int Fl_X11_Screen_Driver::ready()
+{
+ if (first_timeout) {
+ elapse_timeouts();
+ if (first_timeout->time <= 0) return 1;
+ } else {
+ reset_clock = 1;
+ }
+ return fl_ready();
+}
+
+
+extern void fl_fix_focus(); // in Fl.cxx
+
+
+void Fl_X11_Screen_Driver::grab(Fl_Window* win)
+{
+ Fl_Window *fullscreen_win = NULL;
+ for (Fl_Window *W = Fl::first_window(); W; W = Fl::next_window(W)) {
+ if (W->fullscreen_active()) {
+ fullscreen_win = W;
+ break;
+ }
+ }
+ if (win) {
+ if (!grab_) {
+ Window xid = fullscreen_win ? fl_xid(fullscreen_win) : fl_xid(Fl::first_window());
+ XGrabPointer(fl_display,
+ xid,
+ 1,
+ ButtonPressMask|ButtonReleaseMask|
+ ButtonMotionMask|PointerMotionMask,
+ GrabModeAsync,
+ GrabModeAsync,
+ None,
+ 0,
+ fl_event_time);
+ XGrabKeyboard(fl_display,
+ xid,
+ 1,
+ GrabModeAsync,
+ GrabModeAsync,
+ fl_event_time);
+ }
+ grab_ = win;
+ } else {
+ if (Fl::grab_) {
+ // We must keep the grab in the non-EWMH fullscreen case
+ if (!fullscreen_win || Fl_X::ewmh_supported()) {
+ XUngrabKeyboard(fl_display, fl_event_time);
+ }
+ XUngrabPointer(fl_display, fl_event_time);
+ // this flush is done in case the picked menu item goes into
+ // an infinite loop, so we don't leave the X server locked up:
+ XFlush(fl_display);
+ Fl::grab_ = 0;
+ fl_fix_focus();
+ }
+ }
+}
+
+
// Wrapper around XParseColor...
int Fl_X11_Screen_Driver::parse_color(const char* p, uchar& r, uchar& g, uchar& b)
{
@@ -290,6 +470,20 @@ void Fl_X11_Screen_Driver::get_system_colors()
}
+const char *Fl_X11_Screen_Driver::get_system_scheme()
+{
+ const char *s = 0L;
+ if ((s = getenv("FLTK_SCHEME")) == NULL) {
+ const char* key = 0;
+ if (Fl::first_window()) key = Fl::first_window()->xclass();
+ if (!key) key = "fltk";
+ fl_open_display();
+ s = XGetDefault(fl_display, key, "scheme");
+ }
+ return s;
+}
+
+
//
// End of "$Id$".
//
diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.h b/src/drivers/X11/Fl_X11_Screen_Driver.h
index f93e6e2d0..dc62e246a 100644
--- a/src/drivers/X11/Fl_X11_Screen_Driver.h
+++ b/src/drivers/X11/Fl_X11_Screen_Driver.h
@@ -28,6 +28,9 @@
#include <FL/Fl_Screen_Driver.H>
+class Fl_Window;
+
+
class FL_EXPORT Fl_X11_Screen_Driver : public Fl_Screen_Driver
{
protected:
@@ -43,6 +46,7 @@ protected:
public:
// --- display management
virtual void display(const char *disp);
+ virtual int visual(int flags);
// --- screen configuration
void init_workarea();
virtual void init();
@@ -57,9 +61,13 @@ public:
virtual void beep(int type);
// --- global events
virtual void flush();
+ virtual double wait(double time_to_wait);
+ virtual int ready();
+ virtual void grab(Fl_Window* win);
// --- global colors
virtual int parse_color(const char* p, uchar& r, uchar& g, uchar& b);
virtual void get_system_colors();
+ virtual const char *get_system_scheme();
};