diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2016-02-13 16:12:57 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2016-02-13 16:12:57 +0000 |
| commit | d8f96b579d9359f62b984b2043a8f8c6854efe98 (patch) | |
| tree | 00b5fa4cd4a195aa82431b0c211a717d6e4b6d86 /src | |
| parent | 4af616a7a27c3104938bf580502c762becd4417b (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.cxx | 87 | ||||
| -rw-r--r-- | src/Fl_Screen_Driver.cxx | 11 | ||||
| -rw-r--r-- | src/Fl_Tooltip.cxx | 2 | ||||
| -rw-r--r-- | src/Fl_get_system_colors.cxx | 23 | ||||
| -rw-r--r-- | src/Fl_grab.cxx | 88 | ||||
| -rw-r--r-- | src/Fl_visual.cxx | 90 | ||||
| -rw-r--r-- | src/Fl_win32.cxx | 2 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx | 46 | ||||
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h | 9 | ||||
| -rw-r--r-- | src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx | 58 | ||||
| -rw-r--r-- | src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.h | 9 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.cxx | 194 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.h | 8 |
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(); }; |
