summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2016-03-01 00:54:21 +0000
committerMatthias Melcher <fltk@matthiasm.com>2016-03-01 00:54:21 +0000
commit95824506fe2f410e1cd37e9d2bed58af6f558a0a (patch)
treef8c18f415bcdbb1e6e27ecf7c5c754768fc166bd /src/drivers
parent6521bb2562c037dbb457bae42970989d1de5b089 (diff)
Moved timer code to screen drivers. Not sure if this should be in System Drivers instead.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11253 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h7
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx143
-rw-r--r--src/drivers/X11/Fl_X11_Screen_Driver.H5
-rw-r--r--src/drivers/X11/Fl_X11_Screen_Driver.cxx8
4 files changed, 158 insertions, 5 deletions
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h
index 22c17b165..12dbead09 100644
--- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h
+++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.h
@@ -26,7 +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.
@@ -71,6 +71,11 @@ public:
virtual int parse_color(const char* p, uchar& r, uchar& g, uchar& b);
virtual void get_system_colors();
virtual const char *get_system_scheme();
+ // --- global timers
+ virtual void add_timeout(double time, Fl_Timeout_Handler cb, void *argp);
+ virtual void repeat_timeout(double time, Fl_Timeout_Handler cb, void *argp);
+ virtual int has_timeout(Fl_Timeout_Handler cb, void *argp);
+ virtual void remove_timeout(Fl_Timeout_Handler cb, void *argp);
};
diff --git a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
index 2ebb2fb4f..3c386223a 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
+++ b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx
@@ -367,6 +367,149 @@ const char *Fl_WinAPI_Screen_Driver::get_system_scheme()
}
+// ---- timers
+
+
+struct Win32Timer
+{
+ UINT_PTR handle;
+ Fl_Timeout_Handler callback;
+ void *data;
+};
+static Win32Timer* win32_timers;
+static int win32_timer_alloc;
+static int win32_timer_used;
+static HWND s_TimerWnd;
+
+
+static void realloc_timers()
+{
+ if (win32_timer_alloc == 0) {
+ win32_timer_alloc = 8;
+ }
+ win32_timer_alloc *= 2;
+ Win32Timer* new_timers = new Win32Timer[win32_timer_alloc];
+ memset(new_timers, 0, sizeof(Win32Timer) * win32_timer_used);
+ memcpy(new_timers, win32_timers, sizeof(Win32Timer) * win32_timer_used);
+ Win32Timer* delete_me = win32_timers;
+ win32_timers = new_timers;
+ delete [] delete_me;
+}
+
+
+static void delete_timer(Win32Timer& t)
+{
+ KillTimer(s_TimerWnd, t.handle);
+ memset(&t, 0, sizeof(Win32Timer));
+}
+
+
+static LRESULT CALLBACK s_TimerProc(HWND hwnd, UINT msg,
+ WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_TIMER:
+ {
+ unsigned int id = (unsigned) (wParam - 1);
+ if (id < (unsigned int)win32_timer_used && win32_timers[id].handle) {
+ Fl_Timeout_Handler cb = win32_timers[id].callback;
+ void* data = win32_timers[id].data;
+ delete_timer(win32_timers[id]);
+ if (cb) {
+ (*cb)(data);
+ }
+ }
+ }
+ return 0;
+
+ default:
+ break;
+ }
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+
+void Fl_WinAPI_Screen_Driver::add_timeout(double time, Fl_Timeout_Handler cb, void* data)
+{
+ repeat_timeout(time, cb, data);
+}
+
+
+void Fl_WinAPI_Screen_Driver::repeat_timeout(double time, Fl_Timeout_Handler cb, void* data)
+{
+ int timer_id = -1;
+ for (int i = 0; i < win32_timer_used; ++i) {
+ if ( !win32_timers[i].handle ) {
+ timer_id = i;
+ break;
+ }
+ }
+ if (timer_id == -1) {
+ if (win32_timer_used == win32_timer_alloc) {
+ realloc_timers();
+ }
+ timer_id = win32_timer_used++;
+ }
+ unsigned int elapsed = (unsigned int)(time * 1000);
+
+ if ( !s_TimerWnd ) {
+ const char* timer_class = "FLTimer";
+ WNDCLASSEX wc;
+ memset(&wc, 0, sizeof(wc));
+ wc.cbSize = sizeof (wc);
+ wc.style = CS_CLASSDC;
+ wc.lpfnWndProc = (WNDPROC)s_TimerProc;
+ wc.hInstance = fl_display;
+ wc.lpszClassName = timer_class;
+ /*ATOM atom =*/ RegisterClassEx(&wc);
+ // create a zero size window to handle timer events
+ s_TimerWnd = CreateWindowEx(WS_EX_LEFT | WS_EX_TOOLWINDOW,
+ timer_class, "",
+ WS_POPUP,
+ 0, 0, 0, 0,
+ NULL, NULL, fl_display, NULL);
+ // just in case this OS won't let us create a 0x0 size window:
+ if (!s_TimerWnd)
+ s_TimerWnd = CreateWindowEx(WS_EX_LEFT | WS_EX_TOOLWINDOW,
+ timer_class, "",
+ WS_POPUP,
+ 0, 0, 1, 1,
+ NULL, NULL, fl_display, NULL);
+ ShowWindow(s_TimerWnd, SW_SHOWNOACTIVATE);
+ }
+
+ win32_timers[timer_id].callback = cb;
+ win32_timers[timer_id].data = data;
+
+ win32_timers[timer_id].handle =
+ SetTimer(s_TimerWnd, timer_id + 1, elapsed, NULL);
+}
+
+
+int Fl_WinAPI_Screen_Driver::has_timeout(Fl_Timeout_Handler cb, void* data)
+{
+ for (int i = 0; i < win32_timer_used; ++i) {
+ Win32Timer& t = win32_timers[i];
+ if (t.handle && t.callback == cb && t.data == data) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+void Fl_WinAPI_Screen_Driver::remove_timeout(Fl_Timeout_Handler cb, void* data)
+{
+ int i;
+ for (i = 0; i < win32_timer_used; ++i) {
+ Win32Timer& t = win32_timers[i];
+ if (t.handle && t.callback == cb &&
+ (t.data == data || data == NULL)) {
+ delete_timer(t);
+ }
+ }
+}
+
//
diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.H b/src/drivers/X11/Fl_X11_Screen_Driver.H
index fc9114c3c..4d107abd1 100644
--- a/src/drivers/X11/Fl_X11_Screen_Driver.H
+++ b/src/drivers/X11/Fl_X11_Screen_Driver.H
@@ -68,6 +68,11 @@ public:
virtual int parse_color(const char* p, uchar& r, uchar& g, uchar& b);
virtual void get_system_colors();
virtual const char *get_system_scheme();
+ // --- global timers
+ virtual void add_timeout(double time, Fl_Timeout_Handler cb, void *argp);
+ virtual void repeat_timeout(double time, Fl_Timeout_Handler cb, void *argp);
+ virtual int has_timeout(Fl_Timeout_Handler cb, void *argp);
+ virtual void remove_timeout(Fl_Timeout_Handler cb, void *argp);
};
diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.cxx b/src/drivers/X11/Fl_X11_Screen_Driver.cxx
index 6cf07e380..e168031c2 100644
--- a/src/drivers/X11/Fl_X11_Screen_Driver.cxx
+++ b/src/drivers/X11/Fl_X11_Screen_Driver.cxx
@@ -554,12 +554,12 @@ const char *Fl_X11_Screen_Driver::get_system_scheme()
// X11 timers
//
-void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void *argp) {
+void Fl_X11_Screen_Driver::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) {
+void Fl_X11_Screen_Driver::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) {
@@ -580,7 +580,7 @@ void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void *argp) {
/**
Returns true if the timeout exists and has not been called yet.
*/
-int Fl::has_timeout(Fl_Timeout_Handler cb, void *argp) {
+int Fl_X11_Screen_Driver::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;
@@ -593,7 +593,7 @@ int Fl::has_timeout(Fl_Timeout_Handler cb, void *argp) {
\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) {
+void Fl_X11_Screen_Driver::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)) {