X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=OSX%2Fjwxyz-timers.m;h=be31b2dcf57c41eccef1ffd0a37095c7f6bf6f4d;hb=6f5482d73adb0165c0130bb47d852644ab0c4869;hp=ec6f4394f73ec1d87b3aec925a9d523ffb247d06;hpb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;p=xscreensaver diff --git a/OSX/jwxyz-timers.m b/OSX/jwxyz-timers.m index ec6f4394..be31b2dc 100644 --- a/OSX/jwxyz-timers.m +++ b/OSX/jwxyz-timers.m @@ -1,4 +1,4 @@ -/* xscreensaver, Copyright (c) 2006 Jamie Zawinski +/* xscreensaver, Copyright (c) 2006-2012 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -12,11 +12,6 @@ /* This is the OSX implementation of Xt timers, for libjwxyz. */ -#import -#import -#import "jwxyz.h" -#import "jwxyz-timers.h" - //#define DEBUG_TIMERS //#define DEBUG_SOURCES @@ -30,6 +25,17 @@ #undef USE_COCOA_SOURCES +#import + +#ifdef USE_COCOA_SOURCES +# import +#endif + +#import "jwxyz.h" +#import "jwxyz-timers.h" + + + #ifdef DEBUG_TIMERS # define LOGT(str,arg1,arg2) NSLog(str,arg1,arg2) #else @@ -42,6 +48,12 @@ # define LOGI(str,arg1,arg2,arg3) #endif +#define ASSERT_RET(C,S) do { \ + if (!(C)) { \ + jwxyz_abort ("jwxyz-timers: %s",(S)); \ + return; \ + }} while(0) + XtAppContext XtDisplayToApplicationContext (Display *dpy) @@ -80,7 +92,7 @@ jwxyz_timer_retain (const void *arg) { struct jwxyz_XtIntervalId *data = (struct jwxyz_XtIntervalId *) arg; data->refcount++; - LOGT(@"timer 0x%08X: retain %d\n", (unsigned int) data, data->refcount); + LOGT(@"timer 0x%08X: retain %d", (unsigned int) data, data->refcount); return arg; } @@ -89,8 +101,8 @@ jwxyz_timer_release (const void *arg) { struct jwxyz_XtIntervalId *data = (struct jwxyz_XtIntervalId *) arg; data->refcount--; - LOGT(@"timer 0x%08X: release %d\n", (unsigned int) data, data->refcount); - if (data->refcount < 0) abort(); + LOGT(@"timer 0x%08X: release %d", (unsigned int) data, data->refcount); + ASSERT_RET (data->refcount >= 0, "double free"); if (data->refcount == 0) free (data); } @@ -99,7 +111,7 @@ jwxyz_source_retain (const void *arg) { struct jwxyz_XtInputId *data = (struct jwxyz_XtInputId *) arg; data->refcount++; - LOGI(@"source 0x%08X %2d: retain %d\n", (unsigned int) data, data->fd, + LOGI(@"source 0x%08X %2d: retain %d", (unsigned int) data, data->fd, data->refcount); return arg; } @@ -109,9 +121,9 @@ jwxyz_source_release (const void *arg) { struct jwxyz_XtInputId *data = (struct jwxyz_XtInputId *) arg; data->refcount--; - LOGI(@"source 0x%08X %2d: release %d\n", (unsigned int) data, data->fd, + LOGI(@"source 0x%08X %2d: release %d", (unsigned int) data, data->fd, data->refcount); - if (data->refcount < 0) abort(); + ASSERT_RET (data->refcount >= 0, "double free"); if (data->refcount == 0) { # ifdef USE_COCOA_SOURCES if (data->socket) @@ -130,7 +142,7 @@ static void jwxyz_timer_cb (CFRunLoopTimerRef timer, void *arg) { struct jwxyz_XtIntervalId *data = (struct jwxyz_XtIntervalId *) arg; - LOGT(@"timer 0x%08X: fire\n", (unsigned int) data, 0); + LOGT(@"timer 0x%08X: fire", (unsigned int) data, 0); data->cb (data->closure, &data); // Our caller (__CFRunLoopDoTimer) will now call CFRunLoopTimerInvalidate, @@ -159,18 +171,18 @@ jwxyz_source_cb (CFSocketRef s, CFSocketCallBackType type, { struct jwxyz_XtInputId *data = (struct jwxyz_XtInputId *) info; - if (type != kCFSocketReadCallBack) abort(); - if (call_data != 0) abort(); // not used for kCFSocketRead + ASSERT_RET (type == kCFSocketReadCallBack, "unnknown type"); + ASSERT_RET (!call_data, "no call data"); // not used for kCFSocketRead // We are sometimes called when there is not, in fact, data available! // So don't call data->cb if we're being fed a pack of lies. // if (! input_available_p (data->fd)) { - LOGI(@"source 0x%08X %2d: false alarm!\n", (unsigned int) data, data->fd, 0); + LOGI(@"source 0x%08X %2d: false alarm!", (unsigned int) data, data->fd, 0); return; } - LOGI(@"source 0x%08X %2d: fire\n", (unsigned int) data, data->fd, 0); + LOGI(@"source 0x%08X %2d: fire", (unsigned int) data, data->fd, 0); data->cb (data->closure, &data->fd, &data); } @@ -187,7 +199,7 @@ XtAppAddTimeOut (XtAppContext app, unsigned long msecs, data->cb = cb; data->closure = closure; - LOGT(@"timer 0x%08X: alloc %d\n", (unsigned int) data, msecs); + LOGT(@"timer 0x%08X: alloc %d", (unsigned int) data, msecs); CFRunLoopTimerContext ctx = { 0, }; ctx.info = data; @@ -211,10 +223,9 @@ XtAppAddTimeOut (XtAppContext app, unsigned long msecs, void XtRemoveTimeOut (XtIntervalId id) { - LOGT(@"timer 0x%08X: remove\n", (unsigned int) id, 0); - if (id->refcount <= 0) abort(); - if (!id->cftimer) abort(); - + LOGT(@"timer 0x%08X: remove", (unsigned int) id, 0); + ASSERT_RET (id->refcount > 0, "already freed"); + ASSERT_RET (id->cftimer, "timers corrupted"); CFRunLoopRemoveTimer (CFRunLoopGetCurrent(), id->cftimer, kCFRunLoopCommonModes); CFRunLoopTimerInvalidate (id->cftimer); @@ -247,8 +258,8 @@ static void jwxyz_source_select (XtInputId id) { jwxyz_sources_data *td = display_sources_data (app_to_display (id->app)); - if (id->fd <= 0 || id->fd >= FD_SETSIZE) abort(); - if (td->ids[id->fd]) abort(); + ASSERT_RET (id->fd > 0 && id->fd < FD_SETSIZE, "fd out of range"); + ASSERT_RET (td->ids[id->fd] == 0, "sources corrupted"); td->ids[id->fd] = id; td->count++; } @@ -257,9 +268,9 @@ static void jwxyz_source_deselect (XtInputId id) { jwxyz_sources_data *td = display_sources_data (app_to_display (id->app)); - if (td->count <= 0) abort(); - if (id->fd <= 0 || id->fd >= FD_SETSIZE) abort(); - if (td->ids[id->fd] != id) abort(); + ASSERT_RET (td->count > 0, "sources corrupted"); + ASSERT_RET (id->fd > 0 && id->fd < FD_SETSIZE, "fd out of range"); + ASSERT_RET (td->ids[id->fd] == id, "sources corrupted"); td->ids[id->fd] = 0; td->count--; } @@ -282,14 +293,14 @@ jwxyz_sources_run (jwxyz_sources_data *td) } } - if (!max) abort(); + ASSERT_RET (max > 0, "no fds"); if (0 < select (max+1, &fds, NULL, NULL, &tv)) { for (i = 0; i < FD_SETSIZE; i++) { if (FD_ISSET (i, &fds)) { XtInputId id = td->ids[i]; - if (!id || !id->cb) abort(); - if (id->fd != i) abort(); + ASSERT_RET (id && id->cb, "sources corrupted"); + ASSERT_RET (id->fd == i, "sources corrupted"); id->cb (id->closure, &id->fd, &id); } } @@ -309,7 +320,7 @@ XtAppAddInput (XtAppContext app, int fd, XtPointer flags, data->fd = fd; data->closure = closure; - LOGI(@"source 0x%08X %2d: alloc\n", (unsigned int) data, data->fd, 0); + LOGI(@"source 0x%08X %2d: alloc", (unsigned int) data, data->fd, 0); # ifdef USE_COCOA_SOURCES @@ -346,11 +357,11 @@ XtAppAddInput (XtAppContext app, int fd, XtPointer flags, void XtRemoveInput (XtInputId id) { - LOGI(@"source 0x%08X %2d: remove\n", (unsigned int) id, id->fd, 0); - if (id->refcount <= 0) abort(); + LOGI(@"source 0x%08X %2d: remove", (unsigned int) id, id->fd, 0); + ASSERT_RET (id->refcount > 0, "sources corrupted"); # ifdef USE_COCOA_SOURCES - if (! id->cfsource) abort(); - if (! id->socket) abort(); + ASSERT_RET (id->cfsource, "sources corrupted"); + ASSERT_RET (id->socket, "sources corrupted"); CFRunLoopRemoveSource (CFRunLoopGetCurrent(), id->cfsource, kCFRunLoopCommonModes); @@ -369,7 +380,7 @@ void jwxyz_XtRemoveInput_all (Display *dpy) { # ifdef USE_COCOA_SOURCES - abort(); + ASSERT_RET (0, "unimplemented"); # else /* !USE_COCOA_SOURCES */ jwxyz_sources_data *td = display_sources_data (dpy); @@ -381,3 +392,17 @@ jwxyz_XtRemoveInput_all (Display *dpy) # endif /* !USE_COCOA_SOURCES */ } + + +XtInputMask +XtAppPending (XtAppContext app) +{ + return XtIMAlternateInput; /* just always say yes */ +} + +void +XtAppProcessEvent (XtAppContext app, XtInputMask mask) +{ + jwxyz_sources_data *td = display_sources_data (app_to_display (app)); + jwxyz_sources_run (td); +}