diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2016-03-01 00:54:21 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2016-03-01 00:54:21 +0000 |
| commit | 95824506fe2f410e1cd37e9d2bed58af6f558a0a (patch) | |
| tree | f8c18f415bcdbb1e6e27ecf7c5c754768fc166bd /src/drivers | |
| parent | 6521bb2562c037dbb457bae42970989d1de5b089 (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.h | 7 | ||||
| -rw-r--r-- | src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.cxx | 143 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.H | 5 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.cxx | 8 |
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)) { |
