summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlbrecht Schlosser <albrechts.fltk@online.de>2016-02-17 12:16:59 +0000
committerAlbrecht Schlosser <albrechts.fltk@online.de>2016-02-17 12:16:59 +0000
commit4a1662f1da8c57a446c8f19f0204c0048f2e1ba3 (patch)
treec9a1ed67711ab0e01c4d200a507afe20a4416982 /src
parentf7ef143c4f3e770fd8126389e628642c31efa62f (diff)
Fix compilation under Linux - compiles, but doesn't work :-(
I moved all timer related (X11) stuff from src/Fl.cxx to src/drivers/X11/Fl_X11_Screen_Driver.cxx and added externals as done by Ian in a previous commit for the WinAPI screen driver. I did not (yet) remove the code from Fl_x.cxx though, but disabled it. See: #if (0) // *FIXME* moved to src/drivers/X11/Fl_X11_Screen_Driver.cxx Current state is that FLTK can be compiled and linked again (under Linux) but doesn't work (shows empty windows only). I thought it was worth to commit my work, but can't check what's going on right now - other devs should feel free to continue this. PS: the new code in src/drivers/X11/Fl_X11_Screen_Driver.cxx was just dropped in, keeping the right order for usage of static helper functions, but should be fixed in all regards (order, logic, ...). git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11185 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
-rw-r--r--src/Fl.cxx3
-rw-r--r--src/drivers/X11/Fl_X11_Screen_Driver.cxx146
2 files changed, 137 insertions, 12 deletions
diff --git a/src/Fl.cxx b/src/Fl.cxx
index 329839b3a..7f7e2076c 100644
--- a/src/Fl.cxx
+++ b/src/Fl.cxx
@@ -355,6 +355,7 @@ int Fl::event_inside(const Fl_Widget *o) /*const*/ {
// X11 timers
//
+#if (0) // *FIXME* moved to src/drivers/X11/Fl_X11_Screen_Driver.cxx
////////////////////////////////////////////////////////////////////////
// Timeouts are stored in a sorted list (*first_timeout), so only the
@@ -451,6 +452,8 @@ void Fl::remove_timeout(Fl_Timeout_Handler cb, void *argp) {
}
}
+#endif // *FIXME* moved to src/drivers/X11/Fl_X11_Screen_Driver.cxx
+
#endif
////////////////////////////////////////////////////////////////
diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.cxx b/src/drivers/X11/Fl_X11_Screen_Driver.cxx
index a2422c7b4..489d09cb0 100644
--- a/src/drivers/X11/Fl_X11_Screen_Driver.cxx
+++ b/src/drivers/X11/Fl_X11_Screen_Driver.cxx
@@ -23,6 +23,8 @@
#include <FL/x.H>
#include <FL/fl_ask.H>
+#include <sys/time.h>
+
#if HAVE_XINERAMA
# include <X11/extensions/Xinerama.h>
#endif
@@ -33,6 +35,64 @@
extern Atom fl_NET_WORKAREA;
+// Add these externs to allow X11 port to build - same as Fl_WinAPI_Screen_Driver.cxx.
+// These should be in an internal header somewhere?
+// AlbrechtS (Comment by Ian, modified...)
+extern int fl_ready(); // in Fl_x.cxx
+extern int fl_wait(double time); // in Fl_x.cxx
+
+// these are set by Fl::args() and override any system colors: from Fl_get_system_colors.cxx
+extern const char *fl_fg;
+extern const char *fl_bg;
+extern const char *fl_bg2;
+// end of extern additions workaround
+
+//
+// X11 timers
+//
+
+
+////////////////////////////////////////////////////////////////////////
+// Timeouts are stored in a sorted list (*first_timeout), so only the
+// first one needs to be checked to see if any should be called.
+// Allocated, but unused (free) Timeout structs are stored in another
+// linked list (*free_timeout).
+
+struct Timeout {
+ double time;
+ void (*cb)(void*);
+ void* arg;
+ Timeout* next;
+};
+static Timeout* first_timeout, *free_timeout;
+
+// I avoid the overhead of getting the current time when we have no
+// timeouts by setting this flag instead of getting the time.
+// In this case calling elapse_timeouts() does nothing, but records
+// the current time, and the next call will actually elapse time.
+static char reset_clock = 1;
+
+static void elapse_timeouts() {
+ static struct timeval prevclock;
+ struct timeval newclock;
+ gettimeofday(&newclock, NULL);
+ double elapsed = newclock.tv_sec - prevclock.tv_sec +
+ (newclock.tv_usec - prevclock.tv_usec)/1000000.0;
+ prevclock.tv_sec = newclock.tv_sec;
+ prevclock.tv_usec = newclock.tv_usec;
+ if (reset_clock) {
+ reset_clock = 0;
+ } else if (elapsed > 0) {
+ for (Timeout* t = first_timeout; t; t = t->next) t->time -= elapsed;
+ }
+}
+
+
+// Continuously-adjusted error value, this is a number <= 0 for how late
+// we were at calling the last timeout. This appears to make repeat_timeout
+// very accurate even when processing takes a significant portion of the
+// time interval:
+static double missed_timeout_by;
/**
Creates a driver that manages all screen and display related calls.
@@ -56,13 +116,13 @@ void Fl_X11_Screen_Driver::display(const char *d)
int ne = strlen(ext);
int nd = strlen(d);
- char *buf = malloc(nc+ne+nd+1);
+ char *buf = (char *)malloc(nc+ne+nd+1);
strcpy(buf, cmd);
strcat(buf, d);
- if (strchr(d, ':')) {
- strcat(d, ext);
+ if (!strchr(d, ':')) {
+ strcat(buf, ext);
}
- putenv(e);
+ putenv(buf);
free(buf);
}
@@ -324,14 +384,14 @@ double Fl_X11_Screen_Driver::wait(double time_to_wait)
}
Fl::run_checks();
// if (idle && !fl_ready()) {
- if (idle) {
+ if (Fl::idle) {
if (!in_idle) {
in_idle = 1;
- idle();
+ Fl::idle();
in_idle = 0;
}
// the idle function may turn off idle, we can then wait:
- if (idle) time_to_wait = 0.0;
+ if (Fl::idle) time_to_wait = 0.0;
}
if (first_timeout && first_timeout->time < time_to_wait)
time_to_wait = first_timeout->time;
@@ -343,7 +403,7 @@ double Fl_X11_Screen_Driver::wait(double time_to_wait)
} else {
// do flush first so that user sees the display:
flush();
- if (idle && !in_idle) // 'idle' may have been set within flush()
+ if (Fl::idle && !in_idle) // 'idle' may have been set within flush()
time_to_wait = 0.0;
return fl_wait(time_to_wait);
}
@@ -375,7 +435,7 @@ void Fl_X11_Screen_Driver::grab(Fl_Window* win)
}
}
if (win) {
- if (!grab_) {
+ if (!Fl::grab()) {
Window xid = fullscreen_win ? fl_xid(fullscreen_win) : fl_xid(Fl::first_window());
XGrabPointer(fl_display,
xid,
@@ -394,9 +454,9 @@ void Fl_X11_Screen_Driver::grab(Fl_Window* win)
GrabModeAsync,
fl_event_time);
}
- grab_ = win;
+ Fl::grab(win);
} else {
- if (Fl::grab_) {
+ 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);
@@ -405,7 +465,7 @@ void Fl_X11_Screen_Driver::grab(Fl_Window* win)
// 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::grab(0);
fl_fix_focus();
}
}
@@ -483,6 +543,68 @@ const char *Fl_X11_Screen_Driver::get_system_scheme()
return s;
}
+// ###################### *FIXME* ########################
+// ###################### *FIXME* ########################
+// ###################### *FIXME* ########################
+
+
+//
+// X11 timers
+//
+
+void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void *argp) {
+ elapse_timeouts();
+ repeat_timeout(time, cb, argp);
+}
+
+void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void *argp) {
+ time += missed_timeout_by; if (time < -.05) time = 0;
+ Timeout* t = free_timeout;
+ if (t) {
+ free_timeout = t->next;
+ } else {
+ t = new Timeout;
+ }
+ t->time = time;
+ t->cb = cb;
+ t->arg = argp;
+ // insert-sort the new timeout:
+ Timeout** p = &first_timeout;
+ while (*p && (*p)->time <= time) p = &((*p)->next);
+ t->next = *p;
+ *p = t;
+}
+
+/**
+ Returns true if the timeout exists and has not been called yet.
+*/
+int Fl::has_timeout(Fl_Timeout_Handler cb, void *argp) {
+ for (Timeout* t = first_timeout; t; t = t->next)
+ if (t->cb == cb && t->arg == argp) return 1;
+ return 0;
+}
+
+/**
+ Removes a timeout callback. It is harmless to remove a timeout
+ callback that no longer exists.
+
+ \note This version removes all matching timeouts, not just the first one.
+ This may change in the future.
+*/
+void Fl::remove_timeout(Fl_Timeout_Handler cb, void *argp) {
+ for (Timeout** p = &first_timeout; *p;) {
+ Timeout* t = *p;
+ if (t->cb == cb && (t->arg == argp || !argp)) {
+ *p = t->next;
+ t->next = free_timeout;
+ free_timeout = t;
+ } else {
+ p = &(t->next);
+ }
+ }
+}
+
+
//
// End of "$Id$".