From 9fc58606dba39016a66371a30c23c14799576731 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Mon, 8 Sep 2008 18:14:14 +0000 Subject: Scheduled events now signal when the scheduled time has passed. The timer appears to stop signalling events occasionally - needs some investigation. svn path=/trunk/netsurf/; revision=5287 --- amiga/gui.c | 51 ++++++++++++++++++++++++++++++++++++--------------- amiga/object.c | 4 ++++ amiga/schedule.c | 35 +++++++++++++++++++++++++++++++++-- amiga/schedule.h | 5 +++++ 4 files changed, 78 insertions(+), 17 deletions(-) diff --git a/amiga/gui.c b/amiga/gui.c index 63f620e9c..642ef05a4 100755 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -88,7 +88,6 @@ struct gui_window *search_current_window = NULL; struct MsgPort *sport; struct MsgPort *appport; struct MsgPort *msgport; -struct timerequest *tioreq; struct Device *TimerBase; struct TimerIFace *ITimer; struct Library *PopupMenuBase = NULL; @@ -152,7 +151,7 @@ void gui_init(int argc, char** argv) ASO_NoTrack,FALSE, TAG_DONE); - OpenDevice("timer.device",UNIT_VBLANK,(struct IORequest *)tioreq,0); + OpenDevice("timer.device",UNIT_WAITUNTIL,(struct IORequest *)tioreq,0); TimerBase = (struct Device *)tioreq->tr_node.io_Device; ITimer = (struct TimerIFace *)GetInterface((struct Library *)TimerBase,"main",1,NULL); @@ -609,8 +608,7 @@ void ami_handle_msg(void) break; case WMHI_INTUITICK: -// these are only here to stop netsurf stalling waiting for an event - break; + break; default: // printf("class: %ld\n",(result & WMHI_CLASSMASK)); @@ -737,6 +735,9 @@ void ami_handle_appmsg(void) else { browser_window_mouse_click(gwin->bw, BROWSER_MOUSE_PRESS_1, x,y); + /* This bit pastes a plain text file into a form. Really we should be using + Datatypes for this to support more formats */ + if(fh = FOpen(filename,MODE_OLDFILE,0)) { while(len = FRead(fh,filename,1,1024)) @@ -757,6 +758,9 @@ void ami_handle_appmsg(void) } } ReplyMsg((struct Message *)appmsg); + + if(gwin->redraw_required) + ami_do_redraw(gwin); } } @@ -764,8 +768,10 @@ void ami_get_msg(void) { ULONG winsignal = 1L << sport->mp_SigBit; ULONG appsig = 1L << appport->mp_SigBit; - ULONG signalmask = winsignal | appsig; + ULONG schedulesig = 1L << msgport->mp_SigBit; + ULONG signalmask = winsignal | appsig | schedulesig; ULONG signal; + struct Message *timermsg = NULL; signal = Wait(signalmask); @@ -777,6 +783,11 @@ void ami_get_msg(void) { ami_handle_appmsg(); } + else if(signal & schedulesig) + { + while(GetMsg(msgport)) + schedule_run(); + } } void gui_multitask(void) @@ -791,15 +802,25 @@ void gui_multitask(void) void gui_poll(bool active) { /* However, down here we are waiting for the user to do something or for a - scheduled event to kick in (scheduled events will be signalled using - timer.device in the future rather than inefficiently polled - currently - Intuition is sending IDCMP_INTUITICKS messages every 1/10s to our active - window which breaks us out of ami_get_msg - and schedule_run checks every - event, really they need to be sorted and/or when signalled the schedule - node should be part of the message) */ - - ami_get_msg(); - schedule_run(); + scheduled event to kick in (scheduled events are signalled using + timer.device, but NetSurf seems to still be wanting to run code. We ask + Intuition to send IDCMP_INTUITICKS messages every 1/10s to our active + window to break us out of ami_get_msg to stop NetSurf stalling (the active + variable seems to have no real bearing on reality, but is supposed to + indicate that NetSurf wants control back ASAP, so we poll in that case). + + schedule_run checks every event, really they need to be sorted so only + the first event needs to be run on each signal. */ + + if(active) + { + gui_multitask(); + schedule_run(); + } + else + { + ami_get_msg(); + } } void gui_quit(void) @@ -940,7 +961,7 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, WA_CustomScreen,scrn, WA_ReportMouse,TRUE, WA_IDCMP,IDCMP_MENUPICK | IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS | - IDCMP_NEWSIZE | IDCMP_VANILLAKEY | IDCMP_RAWKEY | IDCMP_GADGETUP | IDCMP_IDCMPUPDATE, + IDCMP_NEWSIZE | IDCMP_VANILLAKEY | IDCMP_RAWKEY | IDCMP_GADGETUP | IDCMP_IDCMPUPDATE | IDCMP_INTUITICKS, // WINDOW_IconifyGadget, TRUE, WINDOW_NewMenu,menu, WINDOW_HorizProp,1, diff --git a/amiga/object.c b/amiga/object.c index 32886fe89..f13451bfb 100755 --- a/amiga/object.c +++ b/amiga/object.c @@ -20,6 +20,7 @@ #include #include #include "amiga/object.h" +#include "amiga/schedule.h" struct MinList *NewObjList(void) { @@ -64,6 +65,9 @@ void FreeObjList(struct MinList *objlist) while(nnode=(struct nsObject *)(node->dtz_Node.mln_Succ)) { + if(node->Type == AMINS_CALLBACK) + ami_remove_timer_event((struct nscallback *)node->objstruct); + DelObject(node); node=nnode; } diff --git a/amiga/schedule.c b/amiga/schedule.c index 80e95377a..8843c013b 100755 --- a/amiga/schedule.c +++ b/amiga/schedule.c @@ -20,7 +20,6 @@ #include "amiga/object.h" #include "amiga/schedule.h" #include -#include /** * Schedule a callback. @@ -47,8 +46,23 @@ void schedule(int t, void (*callback)(void *p), void *p) nscb->tv.tv_sec = 0; nscb->tv.tv_micro = t*10000; + + while(nscb->tv.tv_micro >= 1000000) + { + nscb->tv.tv_sec++; + nscb->tv.tv_micro -= 1000000; + } + GetSysTime(&tv); - AddTime(&nscb->tv,&tv); + AddTime(&nscb->tv,&tv); // now contains time when event occurs + + nscb->treq = AllocVec(sizeof(struct timerequest),MEMF_CLEAR); + + *nscb->treq = *tioreq; + nscb->treq->tr_node.io_Command=TR_ADDREQUEST; + nscb->treq->tr_time.tv_sec=nscb->tv.tv_sec; // secs + nscb->treq->tr_time.tv_micro=nscb->tv.tv_micro; // micro + SendIO((struct IORequest *)nscb->treq); nscb->callback = callback; nscb->p = p; @@ -76,9 +90,11 @@ void schedule_remove(void (*callback)(void *p), void *p) while(nnode=(struct nsObject *)(node->dtz_Node.mln_Succ)) { nscb = node->objstruct; + if(!nscb) continue; if((nscb->callback == callback) && (nscb->p == p)) { + ami_remove_timer_event(nscb); DelObject(node); } @@ -115,6 +131,7 @@ void schedule_run(void) { callback = nscb->callback; p = nscb->p; + ami_remove_timer_event(nscb); DelObject(node); callback(p); } @@ -123,3 +140,17 @@ void schedule_run(void) node=nnode; } } + +void ami_remove_timer_event(struct nscallback *nscb) +{ + if(!nscb) return; + + if(nscb->treq) + { + if(CheckIO((struct IORequest *)nscb->treq)==0) + AbortIO((struct IORequest *)nscb->treq); + + WaitIO((struct IORequest *)nscb->treq); + FreeVec(nscb->treq); + } +} diff --git a/amiga/schedule.h b/amiga/schedule.h index 5b8574b16..02d70450f 100755 --- a/amiga/schedule.h +++ b/amiga/schedule.h @@ -19,13 +19,18 @@ #ifndef AMIGA_SCHEDULE_H #define AMIGA_SCHEDULE_H #include +#include struct MinList *schedule_list; +struct timerequest *tioreq; struct nscallback { struct timeval tv; void *callback; void *p; + struct timerequest *treq; }; + +void ami_remove_timer_event(struct nscallback *nscb); #endif -- cgit v1.2.3