diff options
50 files changed, 703 insertions, 514 deletions
diff --git a/amiga/font.c b/amiga/font.c index 3430a4ea3..df4a18862 100755 --- a/amiga/font.c +++ b/amiga/font.c @@ -23,12 +23,12 @@ #include "amiga/gui.h" #include "amiga/utf8.h" #include "amiga/object.h" +#include "amiga/schedule.h" #include "utils/nsoption.h" #include "css/css.h" #include "css/utils.h" #include "render/font.h" #include "utils/log.h" -#include "utils/schedule.h" #include "utils/utf8.h" #include "utils/utils.h" @@ -831,7 +831,7 @@ void ami_init_fonts(void) NewList(&ami_diskfontlib_list); /* run first cleanup in ten minutes */ - schedule(60000, (schedule_callback_fn)ami_font_cleanup, ami_font_list); + ami_schedule(600000, ami_font_cleanup, ami_font_list); } void ami_close_fonts(void) @@ -875,7 +875,7 @@ static void ami_font_cleanup(struct MinList *ami_font_list) }while(node=nnode); /* reschedule to run in five minutes */ - schedule(30000, (schedule_callback_fn)ami_font_cleanup, ami_font_list); + ami_schedule(300000, ami_font_cleanup, ami_font_list); } void ami_font_setdevicedpi(int id) diff --git a/amiga/gui.c b/amiga/gui.c index aedb26c56..84e9dc98c 100644 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -2538,7 +2538,7 @@ static void ami_gui_fetch_callback(void *p) static void gui_poll(bool active) { - if(active) schedule(0, ami_gui_fetch_callback, NULL); + if(active) ami_schedule(0, ami_gui_fetch_callback, NULL); ami_get_msg(); } @@ -4050,19 +4050,19 @@ static void ami_redraw_callback(void *p) */ void ami_schedule_redraw(struct gui_window_2 *gwin, bool full_redraw) { - int cs = 0; + int ms = 0; if(full_redraw) gwin->redraw_required = true; if(gwin->redraw_scheduled == true) return; - if(gwin->bw->reformat_pending) cs = nsoption_int(reformat_delay); - schedule(cs, ami_redraw_callback, gwin); + if(gwin->bw->reformat_pending) ms = nsoption_int(reformat_delay) * 10; + ami_schedule(ms, ami_redraw_callback, gwin); gwin->redraw_scheduled = true; } static void ami_schedule_redraw_remove(struct gui_window_2 *gwin) { - schedule_remove(ami_redraw_callback, gwin); + ami_schedule(-1, ami_redraw_callback, gwin); } static void ami_do_redraw_tiled(struct gui_window_2 *gwin, bool busy, @@ -5133,6 +5133,7 @@ static struct gui_fetch_table amiga_fetch_table = { static struct gui_browser_table amiga_browser_table = { .poll = gui_poll, + .schedule = ami_schedule, .quit = gui_quit, .set_search_ico = gui_set_search_ico, diff --git a/amiga/menu.c b/amiga/menu.c index 2c019bd9e..9cb857e9d 100644 --- a/amiga/menu.c +++ b/amiga/menu.c @@ -58,12 +58,13 @@ #include "amiga/theme.h" #include "amiga/tree.h" #include "amiga/utf8.h" +#include "amiga/schedule.h" #include "desktop/hotlist.h" #include "desktop/browser_private.h" #include "desktop/gui.h" #include "desktop/textinput.h" #include "utils/messages.h" -#include "utils/schedule.h" + enum { NSA_GLYPH_SUBMENU, @@ -481,7 +482,11 @@ struct NewMenu *ami_create_menu(struct gui_window_2 *gwin) /* Set up scheduler to refresh the hotlist menu */ if(nsoption_int(menu_refresh) > 0) - schedule(nsoption_int(menu_refresh), (void *)ami_menu_refresh, gwin); + { + ami_schedule(nsoption_int(menu_refresh) * 10, + ami_menu_refresh, + gwin); + } return(gwin->menu); } diff --git a/amiga/schedule.c b/amiga/schedule.c index d4b35a509..4ec9df7e9 100755 --- a/amiga/schedule.c +++ b/amiga/schedule.c @@ -16,7 +16,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "utils/schedule.h" #include "amiga/os3support.h" #include "amiga/schedule.h" @@ -37,51 +36,18 @@ struct nscallback PblHeap *schedule_list; -void ami_remove_timer_event(struct nscallback *nscb); - -/** - * Schedule a callback. - * - * \param t interval before the callback should be made / cs - * \param callback callback function - * \param p user parameter, passed to callback function - * - * The callback function will be called as soon as possible after t cs have - * passed. - */ - -void schedule(int t, void (*callback)(void *p), void *p) +static void ami_remove_timer_event(struct nscallback *nscb) { - struct nscallback *nscb; - struct TimeVal tv; - ULONG time_us = 0; - - if(schedule_list == NULL) return; - - nscb = AllocVecTagList(sizeof(struct nscallback), NULL); if(!nscb) return; - time_us = t*10000; /* t converted to µs */ - - nscb->tv.Seconds = time_us / 1000000; - nscb->tv.Microseconds = time_us % 1000000; - - GetSysTime(&tv); - AddTime(&nscb->tv,&tv); // now contains time when event occurs - - if(nscb->treq = AllocVecTagList(sizeof(struct TimeRequest), NULL)) + if(nscb->treq) { - *nscb->treq = *tioreq; - nscb->treq->Request.io_Command=TR_ADDREQUEST; - nscb->treq->Time.Seconds=nscb->tv.Seconds; // secs - nscb->treq->Time.Microseconds=nscb->tv.Microseconds; // micro - SendIO((struct IORequest *)nscb->treq); - } - - nscb->callback = callback; - nscb->p = p; + if(CheckIO((struct IORequest *)nscb->treq)==NULL) + AbortIO((struct IORequest *)nscb->treq); - pblHeapInsert(schedule_list, nscb); + WaitIO((struct IORequest *)nscb->treq); + FreeVec(nscb->treq); + } } /** @@ -93,14 +59,22 @@ void schedule(int t, void (*callback)(void *p), void *p) * All scheduled callbacks matching both callback and p are removed. */ -void schedule_remove(void (*callback)(void *p), void *p) +static nserror schedule_remove(void (*callback)(void *p), void *p) { PblIterator *iterator; struct nscallback *nscb; bool restoreheap = false; - if(schedule_list == NULL) return; - if(pblHeapIsEmpty(schedule_list)) return; + /* check there is something on the list to remove */ + if (schedule_list == NULL) + { + return NSERROR_OK; + } + + if(pblHeapIsEmpty(schedule_list)) + { + return NSERROR_OK; + } iterator = pblHeapIterator(schedule_list); @@ -117,10 +91,15 @@ void schedule_remove(void (*callback)(void *p), void *p) pblIteratorFree(iterator); - if(restoreheap) pblHeapConstruct(schedule_list); + if(restoreheap) + { + pblHeapConstruct(schedule_list); + } + + return NSERROR_OK; } -void schedule_remove_all(void) +static void schedule_remove_all(void) { PblIterator *iterator; struct nscallback *nscb; @@ -139,13 +118,16 @@ void schedule_remove_all(void) pblIteratorFree(iterator); } -/** - * Process events up to current time. - * This implementation only takes the top entry off the heap, it does not - * venture to later scheduled events until the next time it is called - - * immediately afterwards, if we're in a timer signalled loop. - */ +static int ami_schedule_compare(const void *prev, const void *next) +{ + struct nscallback *nscb1 = *(struct nscallback **)prev; + struct nscallback *nscb2 = *(struct nscallback **)next; + + return CmpTime(&nscb1->tv, &nscb2->tv); +} + +/* exported function documented in amiga/schedule.h */ void schedule_run(BOOL poll) { struct nscallback *nscb; @@ -176,28 +158,7 @@ void schedule_run(BOOL poll) callback(p); } -void ami_remove_timer_event(struct nscallback *nscb) -{ - if(!nscb) return; - - if(nscb->treq) - { - if(CheckIO((struct IORequest *)nscb->treq)==NULL) - AbortIO((struct IORequest *)nscb->treq); - - WaitIO((struct IORequest *)nscb->treq); - FreeVec(nscb->treq); - } -} - -int ami_schedule_compare(const void *prev, const void *next) -{ - struct nscallback *nscb1 = *(struct nscallback **)prev; - struct nscallback *nscb2 = *(struct nscallback **)next; - - return CmpTime(&nscb1->tv, &nscb2->tv); -} - +/* exported function documented in amiga/schedule.h */ BOOL ami_schedule_create(void) { schedule_list = pblHeapNew(); @@ -206,6 +167,7 @@ BOOL ami_schedule_create(void) pblHeapSetCompareFunction(schedule_list, ami_schedule_compare); } +/* exported function documented in amiga/schedule.h */ void ami_schedule_free(void) { schedule_remove_all(); @@ -213,6 +175,7 @@ void ami_schedule_free(void) schedule_list = NULL; } +/* exported function documented in amiga/schedule.h */ void ami_schedule_open_timer(void) { msgport = AllocSysObjectTags(ASOT_PORT, @@ -231,6 +194,7 @@ void ami_schedule_open_timer(void) ITimer = (struct TimerIFace *)GetInterface((struct Library *)TimerBase,"main",1,NULL); } +/* exported function documented in amiga/schedule.h */ void ami_schedule_close_timer(void) { if(ITimer) @@ -242,3 +206,51 @@ void ami_schedule_close_timer(void) FreeSysObject(ASOT_IOREQUEST,tioreq); FreeSysObject(ASOT_PORT,msgport); } + +/* exported function documented in amiga/schedule.h */ +nserror ami_schedule(int t, void (*callback)(void *p), void *p) +{ + struct nscallback *nscb; + struct TimeVal tv; + ULONG time_us = 0; + + if(schedule_list == NULL) + { + return NSERROR_INIT_FAILED; + } + + if(t < 0) + { + return schedule_remove(callback, p); + } + + nscb = AllocVecTagList(sizeof(struct nscallback), NULL); + if(!nscb) + { + return NSERROR_NOMEM; + } + + time_us = t * 1000; /* t converted to µs */ + + nscb->tv.Seconds = time_us / 1000000; + nscb->tv.Microseconds = time_us % 1000000; + + GetSysTime(&tv); + AddTime(&nscb->tv,&tv); // now contains time when event occurs + + if(nscb->treq = AllocVecTagList(sizeof(struct TimeRequest), NULL)) + { + *nscb->treq = *tioreq; + nscb->treq->Request.io_Command=TR_ADDREQUEST; + nscb->treq->Time.Seconds=nscb->tv.Seconds; // secs + nscb->treq->Time.Microseconds=nscb->tv.Microseconds; // micro + SendIO((struct IORequest *)nscb->treq); + } + + nscb->callback = callback; + nscb->p = p; + + pblHeapInsert(schedule_list, nscb); + + return NSERROR_OK; +} diff --git a/amiga/schedule.h b/amiga/schedule.h index 3eddc8913..659230627 100755 --- a/amiga/schedule.h +++ b/amiga/schedule.h @@ -19,7 +19,6 @@ #ifndef AMIGA_SCHEDULE_H #define AMIGA_SCHEDULE_H #include <proto/timer.h> -#include "utils/schedule.h" #include "amiga/os3support.h" struct Device *TimerBase; @@ -28,9 +27,42 @@ struct TimerIFace *ITimer; struct TimeRequest *tioreq; struct MsgPort *msgport; -void ami_schedule_open_timer(void); -void ami_schedule_close_timer(void); +/** + * Schedule a callback. + * + * \param t interval before the callback should be made / ms + * \param callback callback function + * \param p user parameter, passed to callback function + * \return NSERROR_OK on sucess or appropriate error on faliure + * + * The callback function will be called as soon as possible after t ms have + * passed. + */ +nserror ami_schedule(int t, void (*callback)(void *p), void *p); + +/** + * Initialise amiga scheduler + * + * /return true if initialised ok or false on error. + */ BOOL ami_schedule_create(void); + +/** + * Finalise amiga scheduler + * + */ void ami_schedule_free(void); + +/** + * Process events up to current time. + * + * This implementation only takes the top entry off the heap, it does not + * venture to later scheduled events until the next time it is called - + * immediately afterwards, if we're in a timer signalled loop. + */ void schedule_run(BOOL poll); + +void ami_schedule_open_timer(void); +void ami_schedule_close_timer(void); + #endif diff --git a/amiga/tree.c b/amiga/tree.c index 8cffdb214..fa1252831 100644 --- a/amiga/tree.c +++ b/amiga/tree.c @@ -1390,11 +1390,11 @@ void ami_tree_redraw_request(int x, int y, int width, int height, void *data) atrr_data->height = height; atrr_data->twin = (struct treeview_window *)data; - /**TODO: Queue these requests properly like the main browser code does + /** /todo Queue these requests properly like the main browser code does **/ if(nsoption_bool(direct_render) == false) - schedule(0, ami_tree_redraw_req, atrr_data); + ami_schedule(0, ami_tree_redraw_req, atrr_data); else - schedule(0, ami_tree_redraw_req_dr, atrr_data); + am_schedule(0, ami_tree_redraw_req_dr, atrr_data); } diff --git a/atari/gui.c b/atari/gui.c index df029739f..d83864497 100644 --- a/atari/gui.c +++ b/atari/gui.c @@ -30,7 +30,6 @@ #include <stdbool.h> #include <hubbub/hubbub.h> -#include "utils/schedule.h" #include "utils/url.h" #include "utils/log.h" #include "utils/messages.h" @@ -597,7 +596,7 @@ static void throbber_advance( void * data ) return; toolbar_throbber_progress(gw->root->toolbar); - schedule(100, throbber_advance, gw ); + atari_schedule(1000, throbber_advance, gw ); } static void gui_window_start_throbber(struct gui_window *w) @@ -607,7 +606,7 @@ static void gui_window_start_throbber(struct gui_window *w) return; toolbar_set_throbber_state(w->root->toolbar, true); - schedule(100, throbber_advance, w ); + atari_schedule(1000, throbber_advance, w ); rendering = true; } @@ -618,7 +617,7 @@ static void gui_window_stop_throbber(struct gui_window *w) if (w->root->toolbar->throbber.running == false) return; - schedule_remove(throbber_advance, w); + atari_schedule(-1, throbber_advance, w); toolbar_set_throbber_state(w->root->toolbar, false); @@ -1084,6 +1083,7 @@ static struct gui_fetch_table atari_fetch_table = { static struct gui_browser_table atari_browser_table = { .poll = gui_poll, + .schedule = atari_schedule, .quit = gui_quit, .cert_verify = gui_cert_verify, diff --git a/atari/schedule.c b/atari/schedule.c index a91c510b3..02a376245 100755 --- a/atari/schedule.c +++ b/atari/schedule.c @@ -22,12 +22,15 @@ #include <sys/time.h> #include <time.h> -#include "utils/schedule.h" #include "atari/schedule.h" +#ifdef DEBUG_SCHEDULER #include "utils/log.h" +#else +#define LOG(X) +#endif -#define CS_NOW() ((clock() * 100) / CLOCKS_PER_SEC) +#define MS_NOW() ((clock() * 1000) / CLOCKS_PER_SEC) /* linked list of scheduled callbacks */ static struct nscallback *schedule_list = NULL; @@ -47,45 +50,6 @@ static int max_scheduled; static int cur_scheduled; /** - * Schedule a callback. - * - * \param tival interval before the callback should be made / cs - * \param callback callback function - * \param p user parameter, passed to callback function - * - * The callback function will be called as soon as possible after t cs have - * passed. - */ -void schedule( int cs_ival, void (*callback)(void *p), void *p) -{ - struct nscallback *nscb; - - /* - remove any callback of this kind, - other frontend do this, too. framebuffer frontend doesn't do it. - */ - schedule_remove(callback, p); - - nscb = calloc(1, sizeof(struct nscallback)); - - nscb->timeout = CS_NOW() + cs_ival; -#ifdef DEBUG_SCHEDULER - LOG(("adding callback %p for %p(%p) at %d cs", nscb, callback, p, nscb->timeout )); -#endif - nscb->callback = callback; - nscb->p = p; - - /* add to list front */ - nscb->next = schedule_list; - schedule_list = nscb; - cur_scheduled++; - if( cur_scheduled > max_scheduled ) - max_scheduled = cur_scheduled; -} - - - -/** * Unschedule a callback. * * \param callback callback function @@ -94,18 +58,18 @@ void schedule( int cs_ival, void (*callback)(void *p), void *p) * All scheduled callbacks matching both callback and p are removed. */ -void schedule_remove(void (*callback)(void *p), void *p) +static nserror schedule_remove(void (*callback)(void *p), void *p) { struct nscallback *cur_nscb; struct nscallback *prev_nscb; struct nscallback *unlnk_nscb; - if (schedule_list == NULL) - return; + /* check there is something on the list to remove */ + if (schedule_list == NULL) { + return NSERROR_OK; + } -#ifdef DEBUG_SCHEDULER LOG(("removing %p, %p", callback, p)); -#endif cur_nscb = schedule_list; prev_nscb = NULL; @@ -114,9 +78,8 @@ void schedule_remove(void (*callback)(void *p), void *p) if ((cur_nscb->callback == callback) && (cur_nscb->p == p)) { /* item to remove */ -#ifdef DEBUG_SCHEDULER - LOG(("callback entry %p removing %p(%p)", cur_nscb, cur_nscb->callback, cur_nscb->p)); -#endif + LOG(("callback entry %p removing %p(%p)", + cur_nscb, cur_nscb->callback, cur_nscb->p)); /* remove callback */ unlnk_nscb = cur_nscb; @@ -135,20 +98,51 @@ void schedule_remove(void (*callback)(void *p), void *p) cur_nscb = prev_nscb->next; } } + return NSERROR_OK; +} + +/* exported function documented in atari/schedule.h */ +nserror atari_schedule(int ival, void (*callback)(void *p), void *p) +{ + struct nscallback *nscb; + nserror ret; + + /* remove any existing callback of this kind */ + ret = schedule_remove(callback, p); + if ((ival < 0) || (ret != NSERROR_OK)) { + return ret; + } + + nscb = calloc(1, sizeof(struct nscallback)); + + nscb->timeout = MS_NOW() + ival; + + LOG(("adding callback %p for %p(%p) at %d ms", + nscb, callback, p, nscb->timeout )); + + nscb->callback = callback; + nscb->p = p; + + /* add to list front */ + nscb->next = schedule_list; + schedule_list = nscb; + cur_scheduled++; + if( cur_scheduled > max_scheduled ) { + max_scheduled = cur_scheduled; + } + + return NSERROR_OK; } -/** - * Process events up to current time. - */ -int -schedule_run(void) +/* exported function documented in atari/schedule.h */ +int schedule_run(void) { unsigned long nexttime; struct nscallback *cur_nscb; struct nscallback *prev_nscb; struct nscallback *unlnk_nscb; - unsigned long now = CS_NOW(); + unsigned long now = MS_NOW(); if (schedule_list == NULL) return -1; @@ -170,9 +164,9 @@ schedule_run(void) prev_nscb->next = unlnk_nscb->next; } -#ifdef DEBUG_SCHEDULER - LOG(("callback entry %p running %p(%p)", unlnk_nscb, unlnk_nscb->callback, unlnk_nscb->p)); -#endif + LOG(("callback entry %p running %p(%p)", + unlnk_nscb, unlnk_nscb->callback, unlnk_nscb->p)); + /* call callback */ unlnk_nscb->callback(unlnk_nscb->p); free(unlnk_nscb); @@ -180,9 +174,8 @@ schedule_run(void) /* need to deal with callback modifying the list. */ if (schedule_list == NULL) { -#ifdef DEBUG_SCHEDULER LOG(("schedule_list == NULL")); -#endif + return -1; /* no more callbacks scheduled */ } @@ -204,21 +197,22 @@ schedule_run(void) } /* make rettime relative to now and convert to ms */ - nexttime = (nexttime - now)*10; -#ifdef DEBUG_SCHEDULER + nexttime = nexttime - now; + LOG(("returning time to next event as %ldms", nexttime )); -#endif + /*return next event time in milliseconds (24days max wait) */ - return ( nexttime ); + return nexttime; } +/* exported function documented in atari/schedule.h */ void list_schedule(void) { struct timeval tv; struct nscallback *cur_nscb; - LOG(("schedule list at cs clock %ld", CS_NOW() )); + LOG(("schedule list at ms clock %ld", MS_NOW() )); cur_nscb = schedule_list; while (cur_nscb != NULL) { diff --git a/atari/schedule.h b/atari/schedule.h index e21b759a0..47d8c2ddf 100755 --- a/atari/schedule.h +++ b/atari/schedule.h @@ -17,10 +17,29 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef NS_SCHEDULE_H -#define NS_SCHEDULE_H +#ifndef NS_ATARI_SCHEDULE_H +#define NS_ATARI_SCHEDULE_H -void list_schedule(void); +/** + * Process events up to current time. + */ int schedule_run(void); +/** + * Schedule a callback. + * + * \param tival interval before the callback should be made in ms + * \param callback callback function + * \param p user parameter, passed to callback function + * + * The callback function will be called as soon as possible after t ms have + * passed. + */ +nserror atari_schedule(int cs_ival, void (*callback)(void *p), void *p); + +/** + * LOG all current scheduled events. + */ +void list_schedule(void); + #endif diff --git a/beos/gui.cpp b/beos/gui.cpp index 646356acf..365a35642 100644 --- a/beos/gui.cpp +++ b/beos/gui.cpp @@ -1049,6 +1049,7 @@ static struct gui_fetch_table beos_fetch_table = { static struct gui_browser_table beos_browser_table = { gui_poll, + beos_schedule, gui_quit, NULL, //set_search_ico gui_launch_url, diff --git a/beos/gui.h b/beos/gui.h index 24223a18d..642441fdd 100644 --- a/beos/gui.h +++ b/beos/gui.h @@ -51,9 +51,6 @@ virtual void AboutRequested(); virtual bool QuitRequested(); }; - -extern void schedule_run(void); - extern BWindow *wndAbout; extern BWindow *wndTooltip; diff --git a/beos/scaffolding.cpp b/beos/scaffolding.cpp index fa9549c8f..35153b33d 100644 --- a/beos/scaffolding.cpp +++ b/beos/scaffolding.cpp @@ -62,7 +62,6 @@ extern "C" { #include "render/font.h" #include "render/form.h" #include "utils/messages.h" -#include "utils/schedule.h" #include "utils/utils.h" #include "utils/log.h" } @@ -75,7 +74,7 @@ extern "C" { //#include "beos/completion.h" #include "beos/throbber.h" #include "beos/window.h" -//#include "beos/schedule.h" +#include "beos/schedule.h" //#include "beos/download.h" #define TOOLBAR_HEIGHT 32 @@ -1324,7 +1323,7 @@ void nsbeos_throb(void *p) g->top_view->UnlockLooper(); - schedule(10, nsbeos_throb, p); + beos_schedule(100, nsbeos_throb, p); } @@ -2190,7 +2189,7 @@ void gui_window_start_throbber(struct gui_window* _g) nsbeos_window_update_back_forward(g); - schedule(10, nsbeos_throb, g); + beos_schedule(100, nsbeos_throb, g); } void gui_window_stop_throbber(struct gui_window* _g) @@ -2199,7 +2198,7 @@ void gui_window_stop_throbber(struct gui_window* _g) nsbeos_window_update_back_forward(g); - schedule_remove(nsbeos_throb, g); + beos_schedule(-1, nsbeos_throb, g); if (!g->top_view->LockLooper()) return; diff --git a/beos/schedule.cpp b/beos/schedule.cpp index db0992e63..75e349045 100644 --- a/beos/schedule.cpp +++ b/beos/schedule.cpp @@ -23,7 +23,7 @@ #include <List.h> extern "C" { -#include "utils/schedule.h" +#include "beos/schedule.h" #include "desktop/browser.h" #ifdef DEBUG_BEOS_SCHEDULE @@ -65,7 +65,7 @@ nsbeos_schedule_kill_callback(void *_target, void *_match) return false; } -void +static void schedule_remove(void (*callback)(void *p), void *p) { LOG(("schedule_remove() for %p(%p)", cb->callback, cb->context)); @@ -75,22 +75,26 @@ schedule_remove(void (*callback)(void *p), void *p) cb_match.callback = callback; cb_match.context = p; - callbacks->DoForEach(nsbeos_schedule_kill_callback, &cb_match); } -void -schedule(int t, void (*callback)(void *p), void *p) +nserror beos_schedule(int t, void (*callback)(void *p), void *p) { - LOG(("schedule(%d, %p, %p)", t, cb->callback, cb->context)); - if (callbacks == NULL) + LOG(("t:%d cb:%p p:%p", t, cb->callback, cb->context)); + + if (callbacks == NULL) { callbacks = new BList; + } - bigtime_t timeout = system_time() + t * 10 * 1000LL; - const int msec_timeout = t * 10; - _nsbeos_callback_t *cb = (_nsbeos_callback_t *)malloc(sizeof(_nsbeos_callback_t)); /* Kill any pending schedule of this kind. */ schedule_remove(callback, p); + + if (t < 0) { + return NSERROR_OK; + } + + bigtime_t timeout = system_time() + t * 1000LL; + _nsbeos_callback_t *cb = (_nsbeos_callback_t *)malloc(sizeof(_nsbeos_callback_t)); cb->callback = callback; cb->context = p; cb->callback_killed = cb->callback_fired = false; @@ -99,6 +103,8 @@ schedule(int t, void (*callback)(void *p), void *p) earliest_callback_timeout = timeout; } callbacks->AddItem(cb); + + return NSERROR_OK; } bool diff --git a/beos/schedule.h b/beos/schedule.h index 02205baf4..a44615616 100644 --- a/beos/schedule.h +++ b/beos/schedule.h @@ -19,8 +19,11 @@ #ifndef NETSURF_BEOS_CALLBACK_H #define NETSURF_BEOS_CALLBACK_H 1 -typedef void (*beos_callback)(void *p); - extern bigtime_t earliest_callback_timeout; +extern nserror beos_schedule(int t, void (*callback)(void *p), void *p); + +extern void schedule_run(void); + + #endif /* NETSURF_BEOS_CALLBACK_H */ diff --git a/cocoa/apple_image.m b/cocoa/apple_image.m index ab17f8ab4..c6f9df324 100644 --- a/cocoa/apple_image.m +++ b/cocoa/apple_image.m @@ -25,7 +25,8 @@ #include "image/bitmap.h" #include "desktop/plotters.h" #include "utils/utils.h" -#include "utils/schedule.h" + +#include "cocoa/schedule.h" typedef struct apple_image_content { struct content base; @@ -147,7 +148,7 @@ static void animate_image_cb( void *ptr ) data.redraw.object = &ai->base; content_broadcast( &ai->base, CONTENT_MSG_REDRAW, data ); - schedule( ai->frameTimes[ai->currentFrame], animate_image_cb, ai ); + cocoa_schedule(ai->frameTimes[ai->currentFrame], animate_image_cb, ai ); } /** @@ -190,10 +191,10 @@ bool apple_image_convert(struct content *c) ai->frameTimes = calloc( ai->frames , sizeof(int)); for (NSUInteger i = 0; i < frames; i++) { [image setProperty: NSImageCurrentFrame withValue: [NSNumber numberWithUnsignedInteger: i]]; - ai->frameTimes[i] = 100 * [[image valueForProperty: NSImageCurrentFrameDuration] floatValue]; + ai->frameTimes[i] = 1000 * [[image valueForProperty: NSImageCurrentFrameDuration] floatValue]; } [image setProperty: NSImageCurrentFrame withValue: [NSNumber numberWithUnsignedInteger: 0]]; - schedule( ai->frameTimes[0], animate_image_cb, ai ); + cocoa_schedule( ai->frameTimes[0], animate_image_cb, ai ); } return true; @@ -206,7 +207,7 @@ void apple_image_destroy(struct content *c) [(id)ai_c->bitmap release]; ai_c->bitmap = NULL; - schedule_remove( animate_image_cb, c ); + cocoa_schedule(-1, animate_image_cb, c ); } diff --git a/cocoa/gui.m b/cocoa/gui.m index eba33014b..9ba614475 100644 --- a/cocoa/gui.m +++ b/cocoa/gui.m @@ -25,6 +25,7 @@ #import "cocoa/BrowserWindowController.h" #import "cocoa/FormSelectMenu.h" #import "cocoa/fetch.h" +#import "cocoa/schedule.h" #import "desktop/gui.h" #import "desktop/netsurf.h" @@ -294,6 +295,7 @@ struct gui_window_table *cocoa_window_table = &window_table; static struct gui_browser_table browser_table = { .poll = gui_poll, + .schedule = cocoa_schedule, .launch_url = gui_launch_url, .create_form_select_menu = gui_create_form_select_menu, diff --git a/utils/schedule.h b/cocoa/schedule.h index b5fe386cc..43b2c1462 100644 --- a/utils/schedule.h +++ b/cocoa/schedule.h @@ -1,5 +1,5 @@ /* - * Copyright 2011 Daniel Silverstone <dsilvers@netsurf-browser.org> + * Copyright 2011 Sven Weidauer <sven.weidauer@gmail.com> * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -16,17 +16,4 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -/** \file - * Job scheduler (interface). - */ - -#ifndef _NETSURF_UTILS_SCHEDULE_H_ -#define _NETSURF_UTILS_SCHEDULE_H_ - -/* In platform specific schedule.c. */ -typedef void (*schedule_callback_fn)(void *p); - -void schedule(int t, schedule_callback_fn callback, void *p); -void schedule_remove(schedule_callback_fn callback, void *p); - -#endif +nserror cocoa_schedule(int t, void (*callback)(void *p), void *p); diff --git a/cocoa/schedule.m b/cocoa/schedule.m index 1ad75b390..2dd9a81f6 100644 --- a/cocoa/schedule.m +++ b/cocoa/schedule.m @@ -17,7 +17,8 @@ */ #import <Cocoa/Cocoa.h> -#import "utils/schedule.h" + +#import "cocoa/schedule.h" @interface ScheduledCallback : NSObject { void (*callback)( void *userData ); @@ -73,18 +74,15 @@ static NSMutableSet *timerSet = nil; @end -/* In platform specific schedule.c. */ -void schedule(int t, void (*callback)(void *p), void *p) -{ - ScheduledCallback *cb = [[ScheduledCallback alloc] initWithCallback: callback userData: p]; - [cb schedule: (NSTimeInterval)t / 100]; - [cb release]; -} - -void schedule_remove(void (*callback)(void *p), void *p) +/* exported interface documented in cocoa/schedule.h */ +nserror cocoa_schedule(int t, void (*callback)(void *p), void *p) { ScheduledCallback *cb = [[ScheduledCallback alloc] initWithCallback: callback userData: p]; [timerSet removeObject: cb]; + if (t >= 0) { + [cb schedule: (NSTimeInterval)t / 1000]; + } [cb release]; -} + return NSERROR_OK; +} diff --git a/content/fetchers/curl.c b/content/fetchers/curl.c index d58b7d54a..612b77d0b 100644 --- a/content/fetchers/curl.c +++ b/content/fetchers/curl.c @@ -36,25 +36,25 @@ #include <strings.h> #include <time.h> #include <sys/stat.h> +#include <openssl/ssl.h> #include <libwapcaplet/libwapcaplet.h> #include "utils/config.h" -#include <openssl/ssl.h> -#include "content/fetch.h" -#include "content/fetchers/curl.h" -#include "content/urldb.h" #include "desktop/netsurf.h" #include "desktop/gui_factory.h" #include "utils/corestrings.h" #include "utils/nsoption.h" #include "utils/log.h" #include "utils/messages.h" -#include "utils/schedule.h" #include "utils/utils.h" #include "utils/ring.h" #include "utils/useragent.h" +#include "content/fetch.h" +#include "content/fetchers/curl.h" +#include "content/urldb.h" + /* uncomment this to use scheduler based calling #define FETCHER_CURLL_SCHEDULED 1 */ @@ -504,7 +504,7 @@ bool fetch_curl_initiate_fetch(struct curl_fetch_info *fetch, CURL *handle) codem = curl_multi_add_handle(fetch_curl_multi, fetch->curl_handle); assert(codem == CURLM_OK || codem == CURLM_CALL_MULTI_PERFORM); - schedule(1, (schedule_callback_fn)fetch_curl_poll, NULL); + guit->browser->schedule(10, (void *)fetch_curl_poll, NULL); return true; } @@ -837,7 +837,7 @@ void fetch_curl_poll(lwc_string *scheme_ignored) #ifdef FETCHER_CURLL_SCHEDULED if (running != 0) { - schedule(1, (schedule_callback_fn)fetch_curl_poll, fetch_curl_poll); + guit->browser->schedule(10, fetch_curl_poll, fetch_curl_poll); } #endif } diff --git a/content/hlcache.c b/content/hlcache.c index 618f4fd1e..16f9697ef 100644 --- a/content/hlcache.c +++ b/content/hlcache.c @@ -24,6 +24,7 @@ #include <stdlib.h> #include <string.h> +#include "desktop/gui_factory.h" #include "content/content.h" #include "content/hlcache.h" #include "content/mimesniff.h" @@ -31,7 +32,6 @@ #include "utils/log.h" #include "utils/messages.h" #include "utils/ring.h" -#include "utils/schedule.h" #include "utils/url.h" #include "utils/utils.h" @@ -146,7 +146,7 @@ static void hlcache_clean(void *ignored) llcache_clean(); /* Re-schedule ourselves */ - schedule(hlcache->params.bg_clean_time / 10, hlcache_clean, NULL); + guit->browser->schedule(hlcache->params.bg_clean_time, hlcache_clean, NULL); } /** @@ -536,7 +536,7 @@ hlcache_initialise(const struct hlcache_parameters *hlcache_parameters) hlcache->params = *hlcache_parameters; /* Schedule the cache cleanup */ - schedule(hlcache->params.bg_clean_time / 10, hlcache_clean, NULL); + guit->browser->schedule(hlcache->params.bg_clean_time, hlcache_clean, NULL); return NSERROR_OK; } @@ -545,7 +545,7 @@ hlcache_initialise(const struct hlcache_parameters *hlcache_parameters) void hlcache_stop(void) { /* Remove the hlcache_clean schedule */ - schedule_remove(hlcache_clean, NULL); + guit->browser->schedule(-1, hlcache_clean, NULL); } /* See hlcache.h for documentation */ diff --git a/desktop/browser.c b/desktop/browser.c index 03c7a8e76..b1e4b7594 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -63,7 +63,6 @@ #include "utils/log.h" #include "utils/messages.h" #include "utils/nsurl.h" -#include "utils/schedule.h" #include "utils/url.h" #include "utils/utils.h" #include "utils/utf8.h" @@ -1327,9 +1326,10 @@ static nserror browser_window_callback(hlcache_handle *c, browser_window_history_update(bw, c); hotlist_update_url(hlcache_handle_get_url(c)); - if (bw->refresh_interval != -1) - schedule(bw->refresh_interval, + if (bw->refresh_interval != -1) { + guit->browser->schedule(bw->refresh_interval * 10, browser_window_refresh, bw); + } break; case CONTENT_MSG_ERRORCODE: @@ -1620,10 +1620,11 @@ void browser_window_destroy_internal(struct browser_window *bw) LOG(("Destroying window")); - if (bw->children != NULL || bw->iframes != NULL) + if (bw->children != NULL || bw->iframes != NULL) { browser_window_destroy_children(bw); + } - schedule_remove(browser_window_refresh, bw); + guit->browser->schedule(-1, browser_window_refresh, bw); /* If this brower window is not the root window, and has focus, unset * the root browser window's focus pointer. */ @@ -2208,7 +2209,7 @@ void browser_window_stop(struct browser_window *bw) assert(error == NSERROR_OK); } - schedule_remove(browser_window_refresh, bw); + guit->browser->schedule(-1, browser_window_refresh, bw); if (bw->children) { children = bw->rows * bw->cols; diff --git a/desktop/gui.h b/desktop/gui.h index 85f1265bb..361c6bdf4 100644 --- a/desktop/gui.h +++ b/desktop/gui.h @@ -75,7 +75,8 @@ typedef struct nsnsclipboard_styles { plot_font_style_t style; /**< Style to give text run */ } nsclipboard_styles; -/** Graphical user interface window function table +/** + * Graphical user interface window function table. * * function table implementing window operations */ @@ -176,7 +177,9 @@ struct gui_window_table { */ void (*set_title)(struct gui_window *g, const char *title); - /** set the navigation url. */ + /** + * set the navigation url. + */ void (*set_url)(struct gui_window *g, const char *url); /** set favicon */ @@ -209,7 +212,7 @@ struct gui_window_table { /** * Remove the caret, if present. * - * \param g window with caret + * \param g window with caret */ void (*remove_caret)(struct gui_window *g); @@ -269,8 +272,9 @@ struct gui_window_table { void (*start_selection)(struct gui_window *g); }; + /** - * function table for download windows + * function table for download windows. */ struct gui_download_table { struct gui_download_window *(*create)(struct download_context *ctx, struct gui_window *parent); @@ -282,8 +286,9 @@ struct gui_download_table { void (*done)(struct gui_download_window *dw); }; + /** - * function table for clipboard operations + * function table for clipboard operations. */ struct gui_clipboard_table { /** @@ -305,6 +310,7 @@ struct gui_clipboard_table { void (*set)(const char *buffer, size_t length, nsclipboard_styles styles[], int n_styles); }; + /** * function table for fetcher operations */ @@ -390,8 +396,9 @@ struct gui_fetch_table { }; + /** - * User interface utf8 characterset conversion routines + * User interface utf8 characterset conversion routines. */ struct gui_utf8_table { /** @@ -415,7 +422,9 @@ struct gui_utf8_table { nserror (*local_to_utf8)(const char *string, size_t len, char **result); }; -/** Graphical user interface browser misc function table + +/** + * Graphical user interface browser misc function table. * * function table implementing GUI interface to miscelaneous browser * functionality @@ -429,6 +438,23 @@ struct gui_browser_table { */ void (*poll)(bool active); + /** + * Schedule a callback. + * + * \param t interval before the callback should be made in ms or + * negative value to remove any existing callback. + * \param callback callback function + * \param p user parameter passed to callback function + * \return NSERROR_OK on sucess or appropriate error on faliure + * + * The callback function will be called as soon as possible + * after the timeout has elapsed. + * + * Additional calls with the same callback and user parameter will + * reset the callback time to the newly specified value. + * + */ + nserror (*schedule)(int t, void (*callback)(void *p), void *p); /* Optional entries */ @@ -474,7 +500,8 @@ struct gui_browser_table { */ struct gui_table { - /** Browser table. + /** + * Browser table. * * Provides miscellaneous browser functionality. The table * is mandantory and must be provided. @@ -493,7 +520,8 @@ struct gui_table { /** Fetcher table */ struct gui_fetch_table *fetch; - /** UTF8 table + /** + * UTF8 table. * * Provides for conversion between the gui local character * encoding and utf8. The table optional and may be NULL which diff --git a/desktop/gui_factory.c b/desktop/gui_factory.c index 8996ab5d6..638abfd96 100644 --- a/desktop/gui_factory.c +++ b/desktop/gui_factory.c @@ -443,6 +443,10 @@ static nserror verify_browser_register(struct gui_browser_table *gbt) return NSERROR_BAD_PARAMETER; } + if (gbt->schedule == NULL) { + return NSERROR_BAD_PARAMETER; + } + /* fill in the optional entries with defaults */ if (gbt->quit == NULL) { gbt->quit = gui_default_quit; diff --git a/framebuffer/gui.c b/framebuffer/gui.c index cee58b9d7..7d3e95c38 100644 --- a/framebuffer/gui.c +++ b/framebuffer/gui.c @@ -40,7 +40,6 @@ #include "utils/filepath.h" #include "utils/log.h" #include "utils/messages.h" -#include "utils/schedule.h" #include "utils/types.h" #include "desktop/textinput.h" #include "render/form.h" @@ -557,7 +556,7 @@ static bool nslog_stream_configure(FILE *fptr) -static void gui_poll(bool active) +static void framebuffer_poll(bool active) { nsfb_event_t event; int timeout; /* timeout in miliseconds */ @@ -1696,7 +1695,7 @@ throbber_advance(void *pw) if (g->throbber_index >= 0) { fbtk_set_bitmap(g->throbber, image); - schedule(10, throbber_advance, g); + framebuffer_schedule(100, throbber_advance, g); } } @@ -1704,7 +1703,7 @@ static void gui_window_start_throbber(struct gui_window *g) { g->throbber_index = 0; - schedule(10, throbber_advance, g); + framebuffer_schedule(100, throbber_advance, g); } static void @@ -1785,7 +1784,8 @@ static struct gui_window_table framebuffer_window_table = { static struct gui_browser_table framebuffer_browser_table = { - .poll = gui_poll, + .poll = framebuffer_poll, + .schedule = framebuffer_schedule, .quit = gui_quit, }; diff --git a/framebuffer/schedule.c b/framebuffer/schedule.c index 43f531838..151b6f99f 100644 --- a/framebuffer/schedule.c +++ b/framebuffer/schedule.c @@ -20,10 +20,15 @@ #include <time.h> #include <stdlib.h> -#include "utils/schedule.h" +#include "utils/log.h" + #include "framebuffer/schedule.h" -#include "utils/log.h" +#ifdef DEBUG_SCHEDULER +#define SRLOG(x) LOG(x) +#else +#define SRLOG(x) +#endif /* linked list of scheduled callbacks */ static struct nscallback *schedule_list = NULL; @@ -39,39 +44,6 @@ struct nscallback void *p; }; - -/** - * Schedule a callback. - * - * \param tival interval before the callback should be made / cs - * \param callback callback function - * \param p user parameter, passed to callback function - * - * The callback function will be called as soon as possible after t cs have - * passed. - */ - -void schedule(int cs_ival, void (*callback)(void *p), void *p) -{ - struct nscallback *nscb; - struct timeval tv; - - tv.tv_sec = cs_ival / 100; /* cs to seconds */ - tv.tv_usec = (cs_ival % 100) * 10000; /* remainder to microseconds */ - - nscb = calloc(1, sizeof(struct nscallback)); - - gettimeofday(&nscb->tv, NULL); - timeradd(&nscb->tv, &tv, &nscb->tv); - - nscb->callback = callback; - nscb->p = p; - - /* add to list front */ - nscb->next = schedule_list; - schedule_list = nscb; -} - /** * Unschedule a callback. * @@ -80,17 +52,18 @@ void schedule(int cs_ival, void (*callback)(void *p), void *p) * * All scheduled callbacks matching both callback and p are removed. */ - -void schedule_remove(void (*callback)(void *p), void *p) +static nserror schedule_remove(void (*callback)(void *p), void *p) { struct nscallback *cur_nscb; struct nscallback *prev_nscb; struct nscallback *unlnk_nscb; - if (schedule_list == NULL) - return; + /* check there is something on the list to remove */ + if (schedule_list == NULL) { + return NSERROR_OK; + } - LOG(("removing %p, %p", callback, p)); + SRLOG(("removing %p, %p", callback, p)); cur_nscb = schedule_list; prev_nscb = NULL; @@ -100,7 +73,7 @@ void schedule_remove(void (*callback)(void *p), void *p) (cur_nscb->p == p)) { /* item to remove */ - LOG(("callback entry %p removing %p(%p)", + SRLOG(("callback entry %p removing %p(%p)", cur_nscb, cur_nscb->callback, cur_nscb->p)); /* remove callback */ @@ -119,16 +92,45 @@ void schedule_remove(void (*callback)(void *p), void *p) cur_nscb = prev_nscb->next; } } + + return NSERROR_OK; } -/** - * Process scheduled callbacks up to current time. - * - * @return The number of milliseconds untill the next scheduled event - * or -1 for no event. - */ -int -schedule_run(void) +/* exported function documented in framebuffer/schedule.h */ +nserror framebuffer_schedule(int tival, void (*callback)(void *p), void *p) +{ + struct nscallback *nscb; + struct timeval tv; + nserror ret; + + /* ensure uniqueness of the callback and context */ + ret = schedule_remove(callback, p); + if ((tival < 0) || (ret != NSERROR_OK)) { + return ret; + } + + SRLOG(("Adding %p(%p) in %d", callback, p, tival)); + + tv.tv_sec = tival / 1000; /* miliseconds to seconds */ + tv.tv_usec = (tival % 1000) * 1000; /* remainder to microseconds */ + + nscb = calloc(1, sizeof(struct nscallback)); + + gettimeofday(&nscb->tv, NULL); + timeradd(&nscb->tv, &tv, &nscb->tv); + + nscb->callback = callback; + nscb->p = p; + + /* add to list front */ + nscb->next = schedule_list; + schedule_list = nscb; + + return NSERROR_OK; +} + +/* exported function documented in framebuffer/schedule.h */ +int schedule_run(void) { struct timeval tv; struct timeval nexttime; @@ -188,7 +190,8 @@ schedule_run(void) /* make rettime relative to now */ timersub(&nexttime, &tv, &rettime); - /*LOG(("returning time to next event as %ldms",(rettime.tv_sec * 1000) + (rettime.tv_usec / 1000))); */ + SRLOG(("returning time to next event as %ldms",(rettime.tv_sec * 1000) + (rettime.tv_usec / 1000))); + /* return next event time in milliseconds (24days max wait) */ return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000); } diff --git a/framebuffer/schedule.h b/framebuffer/schedule.h index 2c9b55f82..4e94da68e 100644 --- a/framebuffer/schedule.h +++ b/framebuffer/schedule.h @@ -19,7 +19,27 @@ #ifndef FRAMEBUFFER_SCHEDULE_H #define FRAMEBUFFER_SCHEDULE_H +/** + * Schedule a callback. + * + * \param tival interval before the callback should be made in ms + * \param callback callback function + * \param p user parameter, passed to callback function + * + * The callback function will be called as soon as possible after t ms have + * passed. + */ + +nserror framebuffer_schedule(int tival, void (*callback)(void *p), void *p); + +/** + * Process scheduled callbacks up to current time. + * + * @return The number of milliseconds untill the next scheduled event + * or -1 for no event. + */ int schedule_run(void); + void list_schedule(void); #endif @@ -522,7 +522,7 @@ static bool nslog_stream_configure(FILE *fptr) -static void gui_poll(bool active) +static void nsgtk_poll(bool active) { CURLMcode code; fd_set read_fd_set, write_fd_set, exc_fd_set; @@ -990,7 +990,8 @@ uint32_t gtk_gui_gdkkey_to_nskey(GdkEventKey *key) static struct gui_browser_table nsgtk_browser_table = { - .poll = gui_poll, + .poll = nsgtk_poll, + .schedule = nsgtk_schedule, .quit = gui_quit, .set_search_ico = gui_set_search_ico, diff --git a/gtk/scaffolding.c b/gtk/scaffolding.c index 36ba13a85..ffe6a221c 100644 --- a/gtk/scaffolding.c +++ b/gtk/scaffolding.c @@ -26,7 +26,6 @@ #include <gdk-pixbuf/gdk-pixbuf.h> #include "utils/messages.h" -#include "utils/schedule.h" #include "utils/url.h" #include "utils/log.h" #include "utils/nsoption.h" @@ -70,7 +69,7 @@ #include "gtk/gdk.h" #include "gtk/scaffolding.h" #include "gtk/tabs.h" - +#include "gtk/schedule.h" /** Macro to define a handler for menu, button and activate events. */ @@ -329,7 +328,7 @@ static void nsgtk_throb(void *p) gtk_image_set_from_pixbuf(g->throbber, nsgtk_throbber->framedata[ g->throb_frame]); - schedule(10, nsgtk_throb, p); + nsgtk_schedule(100, nsgtk_throb, p); } static guint nsgtk_scaffolding_update_edit_actions_sensitivity( @@ -2175,7 +2174,7 @@ void gui_window_start_throbber(struct gui_window* _g) nsgtk_window_update_back_forward(g); - schedule(10, nsgtk_throb, g); + nsgtk_schedule(100, nsgtk_throb, g); } void gui_window_stop_throbber(struct gui_window* _g) @@ -2184,7 +2183,7 @@ void gui_window_stop_throbber(struct gui_window* _g) if (g == NULL) return; nsgtk_window_update_back_forward(g); - schedule_remove(nsgtk_throb, g); + nsgtk_schedule(-1, nsgtk_throb, g); if (g->buttons[STOP_BUTTON] != NULL) g->buttons[STOP_BUTTON]->sensitivity = false; if (g->buttons[RELOAD_BUTTON] != NULL) diff --git a/gtk/schedule.c b/gtk/schedule.c index 5b168b689..e28675a0b 100644 --- a/gtk/schedule.c +++ b/gtk/schedule.c @@ -20,7 +20,8 @@ #include <stdlib.h> #include <stdbool.h> -#include "utils/schedule.h" +#include "utils/errors.h" + #include "gtk/schedule.h" #ifdef DEBUG_GTK_SCHEDULE @@ -71,7 +72,7 @@ nsgtk_schedule_kill_callback(void *_target, void *_match) } } -void +static void schedule_remove(void (*callback)(void *p), void *p) { _nsgtk_callback_t cb_match = { @@ -87,19 +88,27 @@ schedule_remove(void (*callback)(void *p), void *p) nsgtk_schedule_kill_callback, &cb_match); } -void -schedule(int t, void (*callback)(void *p), void *p) +/* exported interface documented in gtk/schedule.h */ +nserror nsgtk_schedule(int t, void (*callback)(void *p), void *p) { - const int msec_timeout = t * 10; - _nsgtk_callback_t *cb = malloc(sizeof(_nsgtk_callback_t)); + _nsgtk_callback_t *cb; + /* Kill any pending schedule of this kind. */ schedule_remove(callback, p); + + if (t < 0) { + return NSERROR_OK; + } + + cb = malloc(sizeof(_nsgtk_callback_t)); cb->callback = callback; cb->context = p; cb->callback_killed = false; /* Prepend is faster right now. */ queued_callbacks = g_list_prepend(queued_callbacks, cb); - g_timeout_add(msec_timeout, nsgtk_schedule_generic_callback, cb); + g_timeout_add(t, nsgtk_schedule_generic_callback, cb); + + return NSERROR_OK; } bool diff --git a/gtk/schedule.h b/gtk/schedule.h index c63215e88..0a2d724d4 100644 --- a/gtk/schedule.h +++ b/gtk/schedule.h @@ -19,7 +19,8 @@ #ifndef NETSURF_GTK_CALLBACK_H #define NETSURF_GTK_CALLBACK_H 1 -typedef void (*gtk_callback)(void *p); +nserror nsgtk_schedule(int t, void (*callback)(void *p), void *p); + bool schedule_run(void); #endif /* NETSURF_GTK_CALLBACK_H */ diff --git a/image/gif.c b/image/gif.c index 4bd45c7fe..5c1b3abe8 100644 --- a/image/gif.c +++ b/image/gif.c @@ -39,14 +39,15 @@ #include "content/hlcache.h" #include "utils/nsoption.h" #include "desktop/plotters.h" -#include "image/image.h" -#include "image/bitmap.h" -#include "image/gif.h" +#include "desktop/gui_factory.h" #include "utils/log.h" #include "utils/messages.h" -#include "utils/schedule.h" #include "utils/utils.h" +#include "image/image.h" +#include "image/bitmap.h" +#include "image/gif.h" + typedef struct nsgif_content { struct content base; @@ -159,7 +160,7 @@ static void nsgif_animate(void *p) delay = gif->gif->frames[gif->current_frame].frame_delay; if (delay < nsoption_int(minimum_gif_delay)) delay = nsoption_int(minimum_gif_delay); - schedule(delay, nsgif_animate, gif); + guit->browser->schedule(delay * 10, nsgif_animate, gif); } if ((!nsoption_bool(animate_images)) || @@ -292,7 +293,9 @@ static bool nsgif_convert(struct content *c) /* Schedule the animation if we have one */ gif->current_frame = 0; if (gif->gif->frame_count_partial > 1) - schedule(gif->gif->frames[0].frame_delay, nsgif_animate, c); + guit->browser->schedule(gif->gif->frames[0].frame_delay * 10, + nsgif_animate, + c); /* Exit as a success */ content_set_ready(c); @@ -351,7 +354,7 @@ static void nsgif_destroy(struct content *c) nsgif_content *gif = (nsgif_content *) c; /* Free all the associated memory buffers */ - schedule_remove(nsgif_animate, c); + guit->browser->schedule(-1, nsgif_animate, c); gif_finalise(gif->gif); free(gif->gif); } diff --git a/image/image_cache.c b/image/image_cache.c index c1369086f..051243944 100644 --- a/image/image_cache.c +++ b/image/image_cache.c @@ -22,7 +22,7 @@ #include <stdbool.h> #include <string.h> -#include "utils/schedule.h" +#include "desktop/gui_factory.h" #include "utils/log.h" #include "content/content_protected.h" @@ -290,9 +290,9 @@ static void image_cache__background_update(void *p) image_cache__clean(icache); - schedule((icache->params.bg_clean_time / 10), - image_cache__background_update, - icache); + guit->browser->schedule(icache->params.bg_clean_time, + image_cache__background_update, + icache); } /* exported interface documented in image_cache.h */ @@ -372,9 +372,9 @@ image_cache_init(const struct image_cache_parameters *image_cache_parameters) image_cache->params = *image_cache_parameters; - schedule((image_cache->params.bg_clean_time / 10), - image_cache__background_update, - image_cache); + guit->browser->schedule(image_cache->params.bg_clean_time, + image_cache__background_update, + image_cache); LOG(("Image cache initilised with a limit of %d hysteresis of %d", image_cache->params.limit, image_cache->params.hysteresis)); @@ -387,7 +387,7 @@ nserror image_cache_fini(void) { unsigned int op_count; - schedule_remove(image_cache__background_update, image_cache); + guit->browser->schedule(-1, image_cache__background_update, image_cache); LOG(("Size at finish %d (in %d)", image_cache->total_bitmap_size, diff --git a/monkey/main.c b/monkey/main.c index 07ce7eeeb..96476d26a 100644 --- a/monkey/main.c +++ b/monkey/main.c @@ -21,14 +21,6 @@ #include <stdlib.h> #include "utils/nsoption.h" -#include "monkey/poll.h" -#include "monkey/dispatch.h" -#include "monkey/browser.h" -#include "monkey/cert.h" -#include "monkey/401login.h" -#include "monkey/filetype.h" -#include "monkey/fetch.h" - #include "content/urldb.h" #include "content/fetchers/resource.h" #include "desktop/gui.h" @@ -37,6 +29,15 @@ #include "utils/filepath.h" #include "utils/url.h" +#include "monkey/poll.h" +#include "monkey/dispatch.h" +#include "monkey/browser.h" +#include "monkey/cert.h" +#include "monkey/401login.h" +#include "monkey/filetype.h" +#include "monkey/fetch.h" +#include "monkey/schedule.h" + char **respaths; /** resource search path vector */ /* Stolen from gtk/gui.c */ @@ -103,6 +104,7 @@ static bool nslog_stream_configure(FILE *fptr) static struct gui_browser_table monkey_browser_table = { .poll = monkey_poll, + .schedule = monkey_schedule, .quit = monkey_quit, .launch_url = gui_launch_url, diff --git a/monkey/schedule.c b/monkey/schedule.c index c4b138533..e8ec1c6fa 100644 --- a/monkey/schedule.c +++ b/monkey/schedule.c @@ -20,7 +20,7 @@ #include <stdlib.h> #include <stdbool.h> -#include "utils/schedule.h" +#include "utils/errors.h" #include "monkey/schedule.h" @@ -75,7 +75,7 @@ nsgtk_schedule_kill_callback(void *_target, void *_match) } } -void +static void schedule_remove(void (*callback)(void *p), void *p) { _nsgtk_callback_t cb_match = { @@ -91,20 +91,27 @@ schedule_remove(void (*callback)(void *p), void *p) nsgtk_schedule_kill_callback, &cb_match); } -void -schedule(int t, void (*callback)(void *p), void *p) +nserror monkey_schedule(int t, void (*callback)(void *p), void *p) { - const int msec_timeout = t * 10; - _nsgtk_callback_t *cb = malloc(sizeof(_nsgtk_callback_t)); + _nsgtk_callback_t *cb; + /* Kill any pending schedule of this kind. */ schedule_remove(callback, p); + if (t < 0) { + return NSERROR_OK; + } + + cb = malloc(sizeof(_nsgtk_callback_t)); cb->callback = callback; cb->context = p; cb->callback_killed = false; /* Prepend is faster right now. */ - LOG(("queued a callback to %p(%p) for %d msecs time", callback, p, msec_timeout)); + LOG(("queued a callback to %p(%p) for %d msecs time", callback, p, t)); queued_callbacks = g_list_prepend(queued_callbacks, cb); - g_timeout_add(msec_timeout, nsgtk_schedule_generic_callback, cb); + g_timeout_add(t, nsgtk_schedule_generic_callback, cb); + + return NSERROR_OK; + } bool diff --git a/monkey/schedule.h b/monkey/schedule.h index c63215e88..44ef9bf3b 100644 --- a/monkey/schedule.h +++ b/monkey/schedule.h @@ -19,7 +19,8 @@ #ifndef NETSURF_GTK_CALLBACK_H #define NETSURF_GTK_CALLBACK_H 1 -typedef void (*gtk_callback)(void *p); +nserror monkey_schedule(int t, void (*callback)(void *p), void *p); + bool schedule_run(void); #endif /* NETSURF_GTK_CALLBACK_H */ diff --git a/render/box_construct.c b/render/box_construct.c index f5ef099b4..699102563 100644 --- a/render/box_construct.c +++ b/render/box_construct.c @@ -31,25 +31,27 @@ #include <stdlib.h> #include <string.h> #include <strings.h> + #include "utils/config.h" #include "content/content_protected.h" #include "css/css.h" #include "css/utils.h" #include "css/select.h" +#include "desktop/gui_factory.h" #include "utils/nsoption.h" -#include "render/box.h" -#include "render/box_textarea.h" -#include "render/form.h" -#include "render/html_internal.h" #include "utils/corestrings.h" #include "utils/locale.h" #include "utils/log.h" #include "utils/messages.h" -#include "utils/schedule.h" #include "utils/talloc.h" #include "utils/url.h" #include "utils/utils.h" +#include "render/box.h" +#include "render/box_textarea.h" +#include "render/form.h" +#include "render/html_internal.h" + /** * Context for box tree construction */ @@ -183,9 +185,7 @@ nserror dom_to_box(dom_node *n, html_content *c, box_construct_complete_cb cb) ctx->cb = cb; ctx->bctx = c->bctx; - schedule(0, (schedule_callback_fn) convert_xml_to_box, ctx); - - return NSERROR_OK; + return guit->browser->schedule(0, (void *)convert_xml_to_box, ctx); } /* mapping from CSS display to box type @@ -446,7 +446,7 @@ void convert_xml_to_box(struct box_construct_ctx *ctx) } while (++num_processed < max_processed_before_yield); /* More work to do: schedule a continuation */ - schedule(0, (schedule_callback_fn) convert_xml_to_box, ctx); + guit->browser->schedule(0, (void *)convert_xml_to_box, ctx); } /** diff --git a/render/html.c b/render/html.c index e375e62a5..bb24e585c 100644 --- a/render/html.c +++ b/render/html.c @@ -34,7 +34,6 @@ #include "utils/libdom.h" #include "utils/log.h" #include "utils/messages.h" -#include "utils/schedule.h" #include "utils/talloc.h" #include "utils/url.h" #include "utils/utf8.h" @@ -591,6 +590,7 @@ void html_finish_conversion(html_content *c) error = dom_to_box(html, c, html_box_convert_done); if (error != NSERROR_OK) { + LOG(("box conversion failed")); dom_node_unref(html); html_object_free_objects(c); content_broadcast_errorcode(&c->base, error); diff --git a/render/html_css.c b/render/html_css.c index ad24804a9..b4c25bae2 100644 --- a/render/html_css.c +++ b/render/html_css.c @@ -28,12 +28,13 @@ #include <stdlib.h> #include "content/hlcache.h" +#include "desktop/gui_factory.h" #include "utils/nsoption.h" -#include "render/html_internal.h" #include "utils/corestrings.h" #include "utils/config.h" #include "utils/log.h" -#include "utils/schedule.h" + +#include "render/html_internal.h" static nsurl *html_default_stylesheet_url; static nsurl *html_adblock_stylesheet_url; @@ -307,7 +308,7 @@ static void html_css_process_modified_styles(void *pw) /* If we failed to process any sheet, schedule a retry */ if (all_done == false) { - schedule(100, html_css_process_modified_styles, c); + guit->browser->schedule(1000, html_css_process_modified_styles, c); } } @@ -332,7 +333,7 @@ bool html_css_update_style(html_content *c, dom_node *style) s->modified = true; - schedule(0, html_css_process_modified_styles, c); + guit->browser->schedule(0, html_css_process_modified_styles, c); return true; } @@ -462,7 +463,7 @@ nserror html_css_free_stylesheets(html_content *html) { unsigned int i; - schedule_remove(html_css_process_modified_styles, html); + guit->browser->schedule(-1, html_css_process_modified_styles, html); for (i = 0; i != html->stylesheet_count; i++) { if (html->stylesheets[i].sheet != NULL) { diff --git a/render/html_object.c b/render/html_object.c index e76919dd4..6499f249a 100644 --- a/render/html_object.c +++ b/render/html_object.c @@ -31,12 +31,13 @@ #include "css/utils.h" #include "utils/nsoption.h" #include "desktop/scrollbar.h" -#include "render/box.h" -#include "render/html_internal.h" +#include "desktop/gui_factory.h" #include "utils/corestrings.h" #include "utils/config.h" #include "utils/log.h" -#include "utils/schedule.h" + +#include "render/box.h" +#include "render/html_internal.h" /* break reference loop */ static void html_object_refresh(void *p); @@ -335,7 +336,7 @@ html_object_callback(hlcache_handle *object, case CONTENT_MSG_REFRESH: if (content_get_type(object) == CONTENT_HTML) { /* only for HTML objects */ - schedule(event->data.delay * 100, + guit->browser->schedule(event->data.delay * 1000, html_object_refresh, o); } @@ -534,7 +535,7 @@ static bool html_replace_object(struct content_html_object *object, nsurl *url) } /** - * schedule() callback for object refresh + * schedule callback for object refresh */ static void html_object_refresh(void *p) @@ -630,8 +631,9 @@ nserror html_object_close_objects(html_content *html) if (content_get_type(object->content) == CONTENT_NONE) continue; - if (content_get_type(object->content) == CONTENT_HTML) - schedule_remove(html_object_refresh, object); + if (content_get_type(object->content) == CONTENT_HTML) { + guit->browser->schedule(-1, html_object_refresh, object); + } content_close(object->content); } @@ -646,9 +648,9 @@ nserror html_object_free_objects(html_content *html) if (victim->content != NULL) { LOG(("object %p", victim->content)); - if (content_get_type(victim->content) == CONTENT_HTML) - schedule_remove(html_object_refresh, victim); - + if (content_get_type(victim->content) == CONTENT_HTML) { + guit->browser->schedule(-1, html_object_refresh, victim); + } hlcache_handle_release(victim->content); } diff --git a/riscos/download.c b/riscos/download.c index b10c6c1d4..804a66459 100644 --- a/riscos/download.c +++ b/riscos/download.c @@ -33,7 +33,6 @@ #include <sys/time.h> #include <time.h> #include <curl/curl.h> - #include "oslib/mimemap.h" #include "oslib/osargs.h" #include "oslib/osfile.h" @@ -42,22 +41,24 @@ #include "oslib/osgbpb.h" #include "oslib/wimp.h" #include "oslib/wimpspriteop.h" + #include "desktop/gui.h" #include "desktop/netsurf.h" #include "desktop/download.h" -#include "riscos/dialog.h" #include "utils/nsoption.h" -#include "riscos/mouse.h" -#include "riscos/save.h" -#include "riscos/query.h" -#include "riscos/wimp.h" -#include "riscos/wimp_event.h" #include "utils/log.h" #include "utils/messages.h" -#include "utils/schedule.h" #include "utils/url.h" #include "utils/utf8.h" #include "utils/utils.h" + +#include "riscos/gui.h" +#include "riscos/dialog.h" +#include "riscos/mouse.h" +#include "riscos/save.h" +#include "riscos/query.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" #include "riscos/ucstables.h" #define ICON_DOWNLOAD_ICON 0 @@ -455,7 +456,7 @@ static void gui_download_window_error(struct gui_download_window *dw, dw->ctx = NULL; dw->error = true; - schedule_remove(ro_gui_download_update_status_wrapper, dw); + riscos_schedule(-1, ro_gui_download_update_status_wrapper, dw); /* place error message in status icon in red */ strncpy(dw->status, error_msg, sizeof dw->status); @@ -715,15 +716,16 @@ void ro_gui_download_update_status(struct gui_download_window *dw) warn_user("WimpError", error->errmess); } - if (dw->ctx) - schedule(100, ro_gui_download_update_status_wrapper, dw); - else - schedule_remove(ro_gui_download_update_status_wrapper, dw); + if (dw->ctx) { + riscos_schedule(1000, ro_gui_download_update_status_wrapper, dw); + } else { + riscos_schedule(-1, ro_gui_download_update_status_wrapper, dw); + } } /** - * Wrapper for ro_gui_download_update_status(), suitable for schedule(). + * Wrapper for ro_gui_download_update_status(), suitable for riscos_schedule(). */ void ro_gui_download_update_status_wrapper(void *p) @@ -795,10 +797,11 @@ static void gui_download_window_done(struct gui_download_window *dw) warn_user("SaveError", error->errmess); } - if (dw->send_dataload) + if (dw->send_dataload) { ro_gui_download_send_dataload(dw); + } - schedule(200, ro_gui_download_window_destroy_wrapper, dw); + riscos_schedule(2000, ro_gui_download_window_destroy_wrapper, dw); } } @@ -889,7 +892,7 @@ bool ro_gui_download_keypress(wimp_key *key) !nsoption_bool(confirm_overwrite)) && !dw->ctx) { /* finished already */ - schedule(200, ro_gui_download_window_destroy_wrapper, dw); + riscos_schedule(2000, ro_gui_download_window_destroy_wrapper, dw); } return true; } @@ -985,7 +988,7 @@ void ro_gui_download_datasave_ack(wimp_message *message) ro_gui_download_send_dataload(dw); - schedule(200, ro_gui_download_window_destroy_wrapper, dw); + riscos_schedule(2000, ro_gui_download_window_destroy_wrapper, dw); } } @@ -1417,7 +1420,7 @@ void ro_gui_download_send_dataload(struct gui_download_window *dw) warn_user("WimpError", error->errmess); } - schedule(200, ro_gui_download_window_destroy_wrapper, dw); + riscos_schedule(2000, ro_gui_download_window_destroy_wrapper, dw); } @@ -1480,8 +1483,8 @@ bool ro_gui_download_window_destroy(struct gui_download_window *dw, bool quit) return false; } - schedule_remove(ro_gui_download_update_status_wrapper, dw); - schedule_remove(ro_gui_download_window_destroy_wrapper, dw); + riscos_schedule(-1, ro_gui_download_update_status_wrapper, dw); + riscos_schedule(-1, ro_gui_download_window_destroy_wrapper, dw); /* remove from list */ if (dw->prev) @@ -1534,7 +1537,7 @@ bool ro_gui_download_window_destroy(struct gui_download_window *dw, bool quit) /** - * Wrapper for ro_gui_download_window_destroy(), suitable for schedule(). + * Wrapper for ro_gui_download_window_destroy(), suitable for riscos_schedule(). */ void ro_gui_download_window_destroy_wrapper(void *p) @@ -1613,7 +1616,7 @@ void ro_gui_download_overwrite_confirmed(query_id id, enum query_response res, v ro_gui_download_send_dataload(dw); - schedule(200, ro_gui_download_window_destroy_wrapper, dw); + riscos_schedule(2000, ro_gui_download_window_destroy_wrapper, dw); } } diff --git a/riscos/gui.c b/riscos/gui.c index 1663c1703..59a0138e7 100644 --- a/riscos/gui.c +++ b/riscos/gui.c @@ -1077,7 +1077,7 @@ void ro_gui_cleanup(void) * \param active return as soon as possible */ -void gui_poll(bool active) +static void riscos_poll(bool active) { wimp_event_no event; wimp_block block; @@ -1116,8 +1116,9 @@ void gui_poll(bool active) * from gui_multitask(). Scheduled callbacks must only be run from the * top-level. */ - if (event == wimp_NULL_REASON_CODE) + if (event == wimp_NULL_REASON_CODE) { schedule_run(); + } ro_gui_window_update_boxes(); @@ -2358,7 +2359,8 @@ static struct gui_fetch_table riscos_fetch_table = { }; static struct gui_browser_table riscos_browser_table = { - .poll = gui_poll, + .poll = riscos_poll, + .schedule = riscos_schedule, .quit = gui_quit, .launch_url = gui_launch_url, diff --git a/riscos/gui.h b/riscos/gui.h index dbf6373c0..3ea0c0b72 100644 --- a/riscos/gui.h +++ b/riscos/gui.h @@ -123,7 +123,6 @@ void ro_gui_dump_browser_window(struct browser_window *bw); void ro_gui_drag_box_start(wimp_pointer *pointer); bool ro_gui_prequit(void); const char *ro_gui_default_language(void); -void gui_poll(bool active); /* exported for riscos/wimp_event.c:722 */ char *url_to_path(const char *url); /* in download.c */ @@ -183,8 +182,24 @@ bits ro_filetype_from_unix_path(const char *unix_path); /* in schedule.c */ extern bool sched_active; extern os_t sched_time; + +/** + * Process events up to current time. + */ bool schedule_run(void); +/** + * Schedule a callback. + * + * \param t interval before the callback should be made in ms + * \param callback callback function + * \param p user parameter, passed to callback function + * + * The callback function will be called as soon as possible after t ms have + * passed. + */ +nserror riscos_schedule(int t, void (*callback)(void *p), void *p); + /* in search.c */ void ro_gui_search_init(void); void ro_gui_search_prepare(struct browser_window *g); diff --git a/riscos/gui/progress_bar.c b/riscos/gui/progress_bar.c index 445797611..f5b47313b 100644 --- a/riscos/gui/progress_bar.c +++ b/riscos/gui/progress_bar.c @@ -29,10 +29,11 @@ #include "oslib/osspriteop.h" #include "oslib/wimp.h" #include "oslib/wimpspriteop.h" + #include "desktop/plotters.h" #include "utils/log.h" -#include "utils/schedule.h" #include "utils/utils.h" + #include "riscos/gui.h" #include "riscos/tinct.h" #include "riscos/wimp_event.h" @@ -159,8 +160,9 @@ void ro_gui_progress_bar_destroy(struct progress_bar *pb) os_error *error; assert(pb); - if (pb->animating) - schedule_remove(ro_gui_progress_bar_animate, pb); + if (pb->animating) { + riscos_schedule(-1, ro_gui_progress_bar_animate, pb); + } ro_gui_wimp_event_finalise(pb->w); error = xwimp_delete_window(pb->w); if (error) { @@ -292,12 +294,14 @@ void ro_gui_progress_bar_update(struct progress_bar *pb, int width, int height) /* update the animation state */ if ((pb->value == 0) || (pb->value == pb->range)) { - if (pb->animating) - schedule_remove(ro_gui_progress_bar_animate, pb); + if (pb->animating) { + riscos_schedule(-1, ro_gui_progress_bar_animate, pb); + } pb->animating = false; } else { - if (!pb->animating) - schedule(20, ro_gui_progress_bar_animate, pb); + if (!pb->animating) { + riscos_schedule(200, ro_gui_progress_bar_animate, pb); + } pb->animating = true; } @@ -372,8 +376,9 @@ void ro_gui_progress_bar_animate(void *p) if (pb->offset < 0) pb->offset += progress_width * 2; - if (pb->animating) - schedule(20, ro_gui_progress_bar_animate, pb); + if (pb->animating) { + riscos_schedule(200, ro_gui_progress_bar_animate, pb); + } redraw.w = pb->w; redraw.box = pb->visible; diff --git a/riscos/gui/status_bar.c b/riscos/gui/status_bar.c index 899fe99b6..46a511f95 100644 --- a/riscos/gui/status_bar.c +++ b/riscos/gui/status_bar.c @@ -30,7 +30,6 @@ #include "oslib/wimpspriteop.h" #include "desktop/plotters.h" #include "utils/log.h" -#include "utils/schedule.h" #include "utils/utils.h" #include "riscos/gui.h" #include "riscos/wimp.h" @@ -171,7 +170,7 @@ void ro_gui_status_bar_destroy(struct status_bar *sb) ro_gui_progress_bar_destroy(sb->pb); /* Remove any scheduled redraw callbacks */ - schedule_remove(ro_gui_status_bar_redraw_callback, (void *) sb); + riscos_schedule(-1, ro_gui_status_bar_redraw_callback, (void *) sb); free(sb); } @@ -331,7 +330,7 @@ void ro_gui_status_bar_set_text(struct status_bar *sb, const char *text) * { callback, handle } pair is registered at once. */ if (sb->visible && text != NULL) { - schedule(1, ro_gui_status_bar_redraw_callback, (void *) sb); + riscos_schedule(10, ro_gui_status_bar_redraw_callback, sb); } } diff --git a/riscos/hotlist.c b/riscos/hotlist.c index 791035331..14e90fbfa 100644 --- a/riscos/hotlist.c +++ b/riscos/hotlist.c @@ -30,27 +30,29 @@ #include "oslib/osfile.h" #include "oslib/osmodule.h" #include "oslib/wimp.h" + #include "content/content.h" #include "content/hlcache.h" #include "content/urldb.h" #include "desktop/hotlist.h" #include "desktop/tree.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utils.h" +#include "utils/url.h" +#include "utils/nsoption.h" + +#include "riscos/gui.h" #include "riscos/dialog.h" #include "riscos/hotlist.h" #include "riscos/menus.h" #include "riscos/message.h" -#include "utils/nsoption.h" #include "riscos/save.h" #include "riscos/toolbar.h" #include "riscos/treeview.h" #include "riscos/wimp.h" #include "riscos/wimp_event.h" #include "riscos/query.h" -#include "utils/log.h" -#include "utils/messages.h" -#include "utils/schedule.h" -#include "utils/utils.h" -#include "utils/url.h" static void ro_gui_hotlist_toolbar_update_buttons(void); static void ro_gui_hotlist_toolbar_save_buttons(char *config); @@ -543,7 +545,7 @@ void ro_gui_hotlist_add_page(nsurl *url) * message didn't bounce. */ - schedule(0, ro_gui_hotlist_scheduled_callback, NULL); + riscos_schedule(0, ro_gui_hotlist_scheduled_callback, NULL); } @@ -569,7 +571,7 @@ static void ro_gui_hotlist_addurl_bounce(wimp_message *message) /* There's no longer any need to listen for the next Null poll. */ - schedule_remove(ro_gui_hotlist_scheduled_callback, NULL); + riscos_schedule(-1, ro_gui_hotlist_scheduled_callback, NULL); } diff --git a/riscos/schedule.c b/riscos/schedule.c index 257f2e72f..51290056d 100644 --- a/riscos/schedule.c +++ b/riscos/schedule.c @@ -24,10 +24,11 @@ #include <stdbool.h> #include <stdlib.h> + #include "oslib/os.h" -#include "riscos/gui.h" #include "utils/log.h" -#include "utils/schedule.h" + +#include "riscos/gui.h" /** Entry in the queue of scheduled callbacks. */ @@ -50,25 +51,53 @@ bool sched_active = false; /** Time of soonest scheduled event (valid only if sched_active is true). */ os_t sched_time; - /** - * Schedule a callback. + * Unschedule a callback. * - * \param t interval before the callback should be made / cs * \param callback callback function * \param p user parameter, passed to callback function * - * The callback function will be called as soon as possible after t cs have - * passed. + * All scheduled callbacks matching both callback and p are removed. */ -void schedule(int t, void (*callback)(void *p), void *p) +static nserror schedule_remove(void (*callback)(void *p), void *p) +{ + struct sched_entry *entry, *next; + + for (entry = &sched_queue; entry->next; entry = entry->next) { + if (entry->next->callback != callback || entry->next->p != p) + continue; + next = entry->next; + entry->next = entry->next->next; + free(next); + if (!entry->next) + break; + } + + if (sched_queue.next) { + sched_active = true; + sched_time = sched_queue.next->time; + } else { + sched_active = false; + } + + return NSERROR_OK; +} + +/* exported function documented in riscos/gui.h */ +nserror riscos_schedule(int t, void (*callback)(void *p), void *p) { struct sched_entry *entry; struct sched_entry *queue; os_t time; + nserror ret; - schedule_remove(callback, p); + ret = schedule_remove(callback, p); + if ((t < 0) || (ret != NSERROR_OK)) { + return ret; + } + + t = t / 10; /* convert to centiseconds */ time = os_read_monotonic_time() + t; @@ -91,44 +120,12 @@ void schedule(int t, void (*callback)(void *p), void *p) sched_active = true; sched_time = sched_queue.next->time; -} - -/** - * Unschedule a callback. - * - * \param callback callback function - * \param p user parameter, passed to callback function - * - * All scheduled callbacks matching both callback and p are removed. - */ - -void schedule_remove(void (*callback)(void *p), void *p) -{ - struct sched_entry *entry, *next; - - for (entry = &sched_queue; entry->next; entry = entry->next) { - if (entry->next->callback != callback || entry->next->p != p) - continue; - next = entry->next; - entry->next = entry->next->next; - free(next); - if (!entry->next) - break; - } - - if (sched_queue.next) { - sched_active = true; - sched_time = sched_queue.next->time; - } else - sched_active = false; + return NSERROR_OK; } -/** - * Process events up to current time. - */ - +/* exported function documented in riscos/gui.h */ bool schedule_run(void) { struct sched_entry *entry; @@ -144,8 +141,9 @@ bool schedule_run(void) p = entry->p; sched_queue.next = entry->next; free(entry); - /* The callback may call schedule() or schedule_remove(), so - * leave the queue in a safe state. */ + /* The callback may call riscos_schedule(), so leave + * the queue in a safe state. + */ callback(p); } diff --git a/windows/download.c b/windows/download.c index 8bdff3aac..fe2a09237 100644 --- a/windows/download.c +++ b/windows/download.c @@ -27,14 +27,15 @@ #include "content/fetch.h" #include "desktop/gui.h" #include "desktop/download.h" -#include "utils/schedule.h" #include "utils/log.h" #include "utils/messages.h" #include "utils/url.h" #include "utils/utils.h" + #include "windows/download.h" #include "windows/gui.h" #include "windows/resourceid.h" +#include "windows/schedule.h" static bool downloading = false; static struct gui_download_window *download1; @@ -182,7 +183,7 @@ void nsws_download_update_label(void *p) { struct gui_download_window *w = p; if (w->hwnd == NULL) { - schedule_remove(nsws_download_update_label, p); + win32_schedule(-1, nsws_download_update_label, p); return; } HWND sub = GetDlgItem(w->hwnd, IDC_DOWNLOAD_LABEL); @@ -222,21 +223,23 @@ void nsws_download_update_label(void *p) w->time_left = NULL; } SendMessage(sub, WM_SETTEXT, (WPARAM)0, (LPARAM)label); - if (w->progress < 10000) - schedule(50, nsws_download_update_label, p); + if (w->progress < 10000) { + win32_schedule(500, nsws_download_update_label, p); + } } void nsws_download_update_progress(void *p) { struct gui_download_window *w = p; if (w->hwnd == NULL) { - schedule_remove(nsws_download_update_progress, p); + win32_schedule(-1, nsws_download_update_progress, p); return; } HWND sub = GetDlgItem(w->hwnd, IDC_DOWNLOAD_PROGRESS); SendMessage(sub, PBM_SETPOS, (WPARAM)(w->progress / 100), 0); - if (w->progress < 10000) - schedule(50, nsws_download_update_progress, p); + if (w->progress < 10000) { + win32_schedule(500, nsws_download_update_progress, p); + } } void nsws_download_clear_data(struct gui_download_window *w) @@ -255,8 +258,8 @@ void nsws_download_clear_data(struct gui_download_window *w) free(w->total_size); if (w->file != NULL) fclose(w->file); - schedule_remove(nsws_download_update_progress, (void *)w); - schedule_remove(nsws_download_update_label, (void *)w); + win32_schedule(-1, nsws_download_update_progress, (void *)w); + win32_schedule(-1, nsws_download_update_label, (void *)w); } diff --git a/windows/gui.c b/windows/gui.c index 92ff400ba..8270c13ff 100644 --- a/windows/gui.c +++ b/windows/gui.c @@ -78,7 +78,7 @@ void gui_window_set_scroll(struct gui_window *w, int sx, int sy); static bool gui_window_get_scroll(struct gui_window *w, int *sx, int *sy); -static void gui_poll(bool active) +static void win32_poll(bool active) { MSG Msg; /* message from system */ BOOL bRet; /* message fetch result */ @@ -1888,7 +1888,8 @@ struct gui_fetch_table *win32_fetch_table = &fetch_table; static struct gui_browser_table browser_table = { - .poll = gui_poll, + .poll = win32_poll, + .schedule = win32_schedule, }; struct gui_browser_table *win32_browser_table = &browser_table; diff --git a/windows/schedule.c b/windows/schedule.c index 3181c55e8..f819918ba 100644 --- a/windows/schedule.c +++ b/windows/schedule.c @@ -19,12 +19,17 @@ #include <sys/time.h> #include <time.h> -#include "utils/schedule.h" #include "windows/schedule.h" #include "utils/log.h" #include "utils/utils.h" +#ifdef DEBUG_SCHEDULER +#define SRLOG(x) LOG(x) +#else +#define SRLOG(x) +#endif + /* linked list of scheduled callbacks */ static struct nscallback *schedule_list = NULL; @@ -41,39 +46,6 @@ struct nscallback /** - * Schedule a callback. - * - * \param tival interval before the callback should be made / cs - * \param callback callback function - * \param p user parameter, passed to callback function - * - * The callback function will be called as soon as possible after t cs have - * passed. - */ -void schedule(int cs_ival, void (*callback)(void *p), void *p) -{ - struct nscallback *nscb; - struct timeval tv; - - tv.tv_sec = cs_ival / 100; /* cs to seconds */ - tv.tv_usec = (cs_ival % 100) * 10000; /* remainder to microseconds */ - - nscb = calloc(1, sizeof(struct nscallback)); - - LOG(("adding callback %p for %p(%p) at %d cs", nscb, callback, p, cs_ival)); - - gettimeofday(&nscb->tv, NULL); - timeradd(&nscb->tv, &tv, &nscb->tv); - - nscb->callback = callback; - nscb->p = p; - - /* add to list front */ - nscb->next = schedule_list; - schedule_list = nscb; -} - -/** * Unschedule a callback. * * \param callback callback function @@ -82,16 +54,18 @@ void schedule(int cs_ival, void (*callback)(void *p), void *p) * All scheduled callbacks matching both callback and p are removed. */ -void schedule_remove(void (*callback)(void *p), void *p) +static nserror schedule_remove(void (*callback)(void *p), void *p) { struct nscallback *cur_nscb; struct nscallback *prev_nscb; struct nscallback *unlnk_nscb; - if (schedule_list == NULL) - return; + /* check there is something on the list to remove */ + if (schedule_list == NULL) { + return NSERROR_OK; + } - LOG(("removing %p, %p", callback, p)); + SRLOG(("removing %p, %p", callback, p)); cur_nscb = schedule_list; prev_nscb = NULL; @@ -101,7 +75,7 @@ void schedule_remove(void (*callback)(void *p), void *p) (cur_nscb->p == p)) { /* item to remove */ - LOG(("callback entry %p removing %p(%p)", + SRLOG(("callback entry %p removing %p(%p)", cur_nscb, cur_nscb->callback, cur_nscb->p)); /* remove callback */ @@ -120,8 +94,44 @@ void schedule_remove(void (*callback)(void *p), void *p) cur_nscb = prev_nscb->next; } } + return NSERROR_OK; } +/* exported interface documented in windows/schedule.h */ +nserror win32_schedule(int ival, void (*callback)(void *p), void *p) +{ + struct nscallback *nscb; + struct timeval tv; + nserror ret; + + ret = schedule_remove(callback, p); + if ((ival < 0) || (ret != NSERROR_OK)) { + return ret; + } + + tv.tv_sec = ival / 1000; /* miliseconds to seconds */ + tv.tv_usec = (cs_ival % 1000) * 1000; /* remainder to microseconds */ + + nscb = calloc(1, sizeof(struct nscallback)); + if (nscb == NULL) { + return NSERROR_NOMEM; + } + + SRLOG(("adding callback %p for %p(%p) at %d cs", + nscb, callback, p, ival)); + + gettimeofday(&nscb->tv, NULL); + timeradd(&nscb->tv, &tv, &nscb->tv); + + nscb->callback = callback; + nscb->p = p; + + /* add to list front */ + nscb->next = schedule_list; + schedule_list = nscb; + + return NSERROR_OK; +} /* exported interface documented in schedule.h */ int @@ -157,7 +167,7 @@ schedule_run(void) prev_nscb->next = unlnk_nscb->next; } - LOG(("callback entry %p running %p(%p)", + SRLOG(("callback entry %p running %p(%p)", unlnk_nscb, unlnk_nscb->callback, unlnk_nscb->p)); /* call callback */ unlnk_nscb->callback(unlnk_nscb->p); @@ -190,9 +200,9 @@ schedule_run(void) /* make returned time relative to now */ timersub(&nexttime, &tv, &rettime); -#if defined(DEBUG_SCHEDULER) - LOG(("returning time to next event as %ldms",(rettime.tv_sec * 1000) + (rettime.tv_usec / 1000))); -#endif + SRLOG(("returning time to next event as %ldms", + (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000))); + /* return next event time in milliseconds (24days max wait) */ return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000); } diff --git a/windows/schedule.h b/windows/schedule.h index e6a5d10d0..6d47b2db6 100644 --- a/windows/schedule.h +++ b/windows/schedule.h @@ -16,8 +16,20 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef FRAMEBUFFER_SCHEDULE_H -#define FRAMEBUFFER_SCHEDULE_H +#ifndef WINDOWS_SCHEDULE_H +#define WINDOWS_SCHEDULE_H + +/** + * Schedule a callback. + * + * \param ival interval before the callback should be made in ms + * \param callback callback function + * \param p user parameter, passed to callback function + * + * The callback function will be called as soon as possible after t ms have + * passed. + */ +nserror win32_schedule(int ival, void (*callback)(void *p), void *p); /** * Process scheduled callbacks up to current time. |