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/drivers/X11 | |
| 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/drivers/X11')
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.cxx | 194 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.h | 8 |
2 files changed, 202 insertions, 0 deletions
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(); }; |
