summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2018-05-12 16:44:31 +0000
committerManolo Gouy <Manolo>2018-05-12 16:44:31 +0000
commit6fd216d75984e25cdd3fada7396300965861ce90 (patch)
tree35fbf5f370fbe1de1fdca2b29ab5644c06e65d6f
parent8b7f7c78b2595b22aac6e3269bb1fd4b1a213420 (diff)
MacOS: move timer-related code from file Fl_cocoa.mm to file Fl_Cocoa_Screen_Driver.cxx
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12916 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
-rw-r--r--src/Fl_cocoa.mm160
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H1
-rw-r--r--src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx149
3 files changed, 157 insertions, 153 deletions
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm
index cc5d8f016..4c6392620 100644
--- a/src/Fl_cocoa.mm
+++ b/src/Fl_cocoa.mm
@@ -486,7 +486,7 @@ static void processFLTKEvent(void) {
/*
* break the current event loop
*/
-static void breakMacEventLoop()
+void Fl_Cocoa_Screen_Driver::breakMacEventLoop()
{
NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined location:NSMakePoint(0,0)
modifierFlags:0 timestamp:0
@@ -494,152 +494,6 @@ static void breakMacEventLoop()
[NSApp postEvent:event atStart:NO];
}
-//
-// MacOS X timers
-//
-
-struct MacTimeout {
- Fl_Timeout_Handler callback;
- void* data;
- CFRunLoopTimerRef timer;
- char pending;
- CFAbsoluteTime next_timeout; // scheduled time for this timer
-};
-static MacTimeout* mac_timers;
-static int mac_timer_alloc;
-static int mac_timer_used;
-static MacTimeout* current_timer; // the timer that triggered its callback function
-
-static void realloc_timers()
-{
- if (mac_timer_alloc == 0) {
- mac_timer_alloc = 8;
- fl_open_display(); // needed because the timer creates an event
- }
- mac_timer_alloc *= 2;
- MacTimeout* new_timers = new MacTimeout[mac_timer_alloc];
- memset(new_timers, 0, sizeof(MacTimeout)*mac_timer_alloc);
- memcpy(new_timers, mac_timers, sizeof(MacTimeout) * mac_timer_used);
- if (current_timer) {
- MacTimeout* newCurrent = new_timers + (current_timer - mac_timers);
- current_timer = newCurrent;
- }
- MacTimeout* delete_me = mac_timers;
- mac_timers = new_timers;
- delete [] delete_me;
-}
-
-static void delete_timer(MacTimeout& t)
-{
- if (t.timer) {
- CFRunLoopRemoveTimer(CFRunLoopGetCurrent(),
- t.timer,
- kCFRunLoopDefaultMode);
- CFRelease(t.timer);
- memset(&t, 0, sizeof(MacTimeout));
- }
-}
-
-static void do_timer(CFRunLoopTimerRef timer, void* data)
-{
- fl_lock_function();
- fl_intptr_t timerId = (fl_intptr_t)data;
- current_timer = &mac_timers[timerId];
- current_timer->pending = 0;
- (current_timer->callback)(current_timer->data);
- if (current_timer && current_timer->pending == 0)
- delete_timer(*current_timer);
- current_timer = NULL;
-
- breakMacEventLoop();
- fl_unlock_function();
-}
-
-void Fl_Cocoa_Screen_Driver::add_timeout(double time, Fl_Timeout_Handler cb, void* data)
-{
- // check, if this timer slot exists already
- for (int i = 0; i < mac_timer_used; ++i) {
- MacTimeout& t = mac_timers[i];
- // if so, simply change the fire interval
- if (t.callback == cb && t.data == data) {
- t.next_timeout = CFAbsoluteTimeGetCurrent() + time;
- CFRunLoopTimerSetNextFireDate(t.timer, t.next_timeout );
- t.pending = 1;
- return;
- }
- }
- // no existing timer to use. Create a new one:
- fl_intptr_t timer_id = -1;
- // find an empty slot in the timer array
- for (int i = 0; i < mac_timer_used; ++i) {
- if ( !mac_timers[i].timer ) {
- timer_id = i;
- break;
- }
- }
- // if there was no empty slot, append a new timer
- if (timer_id == -1) {
- // make space if needed
- if (mac_timer_used == mac_timer_alloc) {
- realloc_timers();
- }
- timer_id = mac_timer_used++;
- }
- // now install a brand new timer
- MacTimeout& t = mac_timers[timer_id];
- CFRunLoopTimerContext context = {0, (void*)timer_id, NULL,NULL,NULL};
- CFRunLoopTimerRef timerRef = CFRunLoopTimerCreate(kCFAllocatorDefault,
- CFAbsoluteTimeGetCurrent() + time,
- 1E30,
- 0,
- 0,
- do_timer,
- &context
- );
- if (timerRef) {
- CFRunLoopAddTimer(CFRunLoopGetCurrent(),
- timerRef,
- kCFRunLoopDefaultMode);
- t.callback = cb;
- t.data = data;
- t.timer = timerRef;
- t.pending = 1;
- t.next_timeout = CFRunLoopTimerGetNextFireDate(timerRef);
- }
-}
-
-void Fl_Cocoa_Screen_Driver::repeat_timeout(double time, Fl_Timeout_Handler cb, void* data)
-{
- // k = how many times 'time' seconds after the last scheduled timeout until the future
- double k = ceil( (CFAbsoluteTimeGetCurrent() - current_timer->next_timeout) / time);
- if (k < 1) k = 1;
- current_timer->next_timeout += k * time;
- CFRunLoopTimerSetNextFireDate(current_timer->timer, current_timer->next_timeout );
- current_timer->callback = cb;
- current_timer->data = data;
- current_timer->pending = 1;
-}
-
-int Fl_Cocoa_Screen_Driver::has_timeout(Fl_Timeout_Handler cb, void* data)
-{
- for (int i = 0; i < mac_timer_used; ++i) {
- MacTimeout& t = mac_timers[i];
- if (t.callback == cb && t.data == data && t.pending) {
- return 1;
- }
- }
- return 0;
-}
-
-void Fl_Cocoa_Screen_Driver::remove_timeout(Fl_Timeout_Handler cb, void* data)
-{
- for (int i = 0; i < mac_timer_used; ++i) {
- MacTimeout& t = mac_timers[i];
- if (t.callback == cb && ( t.data == data || data == NULL)) {
- delete_timer(t);
- }
- }
-}
@interface FLWindow : NSWindow {
Fl_Window *w;
@@ -1527,7 +1381,7 @@ static FLWindowDelegate *flwindowdelegate_instance = nil;
fl_unlock_function();
if ( ! Fl::first_window() ) {
Fl::program_should_quit(1);
- breakMacEventLoop(); // necessary when called through menu and in Fl::wait()
+ Fl_Cocoa_Screen_Driver::breakMacEventLoop(); // necessary when called through menu and in Fl::wait()
}
return NSTerminateCancel;
}
@@ -2482,7 +2336,7 @@ static FLTextInputContext* fltextinputcontext_instance = nil;
update_e_xy_and_e_xy_root([self window]);
fl_dnd_target_window = target;
int ret = Fl::handle( FL_DND_ENTER, target );
- breakMacEventLoop();
+ Fl_Cocoa_Screen_Driver::breakMacEventLoop();
fl_unlock_function();
Fl::flush();
return ret ? NSDragOperationCopy : NSDragOperationNone;
@@ -2494,7 +2348,7 @@ static FLTextInputContext* fltextinputcontext_instance = nil;
update_e_xy_and_e_xy_root([self window]);
fl_dnd_target_window = target;
int ret = Fl::handle( FL_DND_DRAG, target );
- breakMacEventLoop();
+ Fl_Cocoa_Screen_Driver::breakMacEventLoop();
fl_unlock_function();
// if the DND started in the same application, Fl::dnd() will not return until
// the DND operation is finished. The call below causes the drop indicator
@@ -2508,7 +2362,7 @@ static FLTextInputContext* fltextinputcontext_instance = nil;
fl_lock_function();
Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
if ( !Fl::handle( FL_DND_RELEASE, target ) ) {
- breakMacEventLoop();
+ Fl_Cocoa_Screen_Driver::breakMacEventLoop();
fl_unlock_function();
return NO;
}
@@ -2534,7 +2388,7 @@ static FLTextInputContext* fltextinputcontext_instance = nil;
convert_crlf(DragData, strlen(DragData));
}
else {
- breakMacEventLoop();
+ Fl_Cocoa_Screen_Driver::breakMacEventLoop();
fl_unlock_function();
return NO;
}
@@ -2547,7 +2401,7 @@ static FLTextInputContext* fltextinputcontext_instance = nil;
Fl::e_text = NULL;
Fl::e_length = 0;
fl_dnd_target_window = NULL;
- breakMacEventLoop();
+ Fl_Cocoa_Screen_Driver::breakMacEventLoop();
fl_unlock_function();
return YES;
}
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H
index 16cd246d3..79d5632e8 100644
--- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H
+++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H
@@ -56,6 +56,7 @@ protected:
public:
Fl_Cocoa_Screen_Driver();
static int next_marked_length; // next length of marked text after current marked text will have been replaced
+ static void breakMacEventLoop();
// --- display management
// --- screen configuration
virtual void init();
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
index b7623193d..b69e041e5 100644
--- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
+++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
@@ -31,6 +31,8 @@
extern "C" void NSBeep(void);
+extern void (*fl_lock_function)();
+extern void (*fl_unlock_function)();
int Fl_Cocoa_Screen_Driver::next_marked_length = 0;
@@ -399,5 +401,152 @@ Fl_RGB_Image *Fl_Cocoa_Screen_Driver::read_win_rectangle(int X, int Y, int w, in
}
//
+// MacOS X timers
+//
+
+struct MacTimeout {
+ Fl_Timeout_Handler callback;
+ void* data;
+ CFRunLoopTimerRef timer;
+ char pending;
+ CFAbsoluteTime next_timeout; // scheduled time for this timer
+};
+static MacTimeout* mac_timers;
+static int mac_timer_alloc;
+static int mac_timer_used;
+static MacTimeout* current_timer; // the timer that triggered its callback function
+
+static void realloc_timers()
+{
+ if (mac_timer_alloc == 0) {
+ mac_timer_alloc = 8;
+ fl_open_display(); // needed because the timer creates an event
+ }
+ mac_timer_alloc *= 2;
+ MacTimeout* new_timers = new MacTimeout[mac_timer_alloc];
+ memset(new_timers, 0, sizeof(MacTimeout)*mac_timer_alloc);
+ memcpy(new_timers, mac_timers, sizeof(MacTimeout) * mac_timer_used);
+ if (current_timer) {
+ MacTimeout* newCurrent = new_timers + (current_timer - mac_timers);
+ current_timer = newCurrent;
+ }
+ MacTimeout* delete_me = mac_timers;
+ mac_timers = new_timers;
+ delete [] delete_me;
+}
+
+static void delete_timer(MacTimeout& t)
+{
+ if (t.timer) {
+ CFRunLoopRemoveTimer(CFRunLoopGetCurrent(),
+ t.timer,
+ kCFRunLoopDefaultMode);
+ CFRelease(t.timer);
+ memset(&t, 0, sizeof(MacTimeout));
+ }
+}
+
+static void do_timer(CFRunLoopTimerRef timer, void* data)
+{
+ fl_lock_function();
+ fl_intptr_t timerId = (fl_intptr_t)data;
+ current_timer = &mac_timers[timerId];
+ current_timer->pending = 0;
+ (current_timer->callback)(current_timer->data);
+ if (current_timer && current_timer->pending == 0)
+ delete_timer(*current_timer);
+ current_timer = NULL;
+
+ Fl_Cocoa_Screen_Driver::breakMacEventLoop();
+ fl_unlock_function();
+}
+
+void Fl_Cocoa_Screen_Driver::add_timeout(double time, Fl_Timeout_Handler cb, void* data)
+{
+ // check, if this timer slot exists already
+ for (int i = 0; i < mac_timer_used; ++i) {
+ MacTimeout& t = mac_timers[i];
+ // if so, simply change the fire interval
+ if (t.callback == cb && t.data == data) {
+ t.next_timeout = CFAbsoluteTimeGetCurrent() + time;
+ CFRunLoopTimerSetNextFireDate(t.timer, t.next_timeout );
+ t.pending = 1;
+ return;
+ }
+ }
+ // no existing timer to use. Create a new one:
+ fl_intptr_t timer_id = -1;
+ // find an empty slot in the timer array
+ for (int i = 0; i < mac_timer_used; ++i) {
+ if ( !mac_timers[i].timer ) {
+ timer_id = i;
+ break;
+ }
+ }
+ // if there was no empty slot, append a new timer
+ if (timer_id == -1) {
+ // make space if needed
+ if (mac_timer_used == mac_timer_alloc) {
+ realloc_timers();
+ }
+ timer_id = mac_timer_used++;
+ }
+ // now install a brand new timer
+ MacTimeout& t = mac_timers[timer_id];
+ CFRunLoopTimerContext context = {0, (void*)timer_id, NULL,NULL,NULL};
+ CFRunLoopTimerRef timerRef = CFRunLoopTimerCreate(kCFAllocatorDefault,
+ CFAbsoluteTimeGetCurrent() + time,
+ 1E30,
+ 0,
+ 0,
+ do_timer,
+ &context
+ );
+ if (timerRef) {
+ CFRunLoopAddTimer(CFRunLoopGetCurrent(),
+ timerRef,
+ kCFRunLoopDefaultMode);
+ t.callback = cb;
+ t.data = data;
+ t.timer = timerRef;
+ t.pending = 1;
+ t.next_timeout = CFRunLoopTimerGetNextFireDate(timerRef);
+ }
+}
+
+void Fl_Cocoa_Screen_Driver::repeat_timeout(double time, Fl_Timeout_Handler cb, void* data)
+{
+ // k = how many times 'time' seconds after the last scheduled timeout until the future
+ double k = ceil( (CFAbsoluteTimeGetCurrent() - current_timer->next_timeout) / time);
+ if (k < 1) k = 1;
+ current_timer->next_timeout += k * time;
+ CFRunLoopTimerSetNextFireDate(current_timer->timer, current_timer->next_timeout );
+ current_timer->callback = cb;
+ current_timer->data = data;
+ current_timer->pending = 1;
+}
+
+int Fl_Cocoa_Screen_Driver::has_timeout(Fl_Timeout_Handler cb, void* data)
+{
+ for (int i = 0; i < mac_timer_used; ++i) {
+ MacTimeout& t = mac_timers[i];
+ if (t.callback == cb && t.data == data && t.pending) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void Fl_Cocoa_Screen_Driver::remove_timeout(Fl_Timeout_Handler cb, void* data)
+{
+ for (int i = 0; i < mac_timer_used; ++i) {
+ MacTimeout& t = mac_timers[i];
+ if (t.callback == cb && ( t.data == data || data == NULL)) {
+ delete_timer(t);
+ }
+ }
+}
+
+//
// End of "$Id$".
//