diff options
-rw-r--r-- | byterun/rotatecursor.c | 69 | ||||
-rw-r--r-- | byterun/rotatecursor.h | 57 |
2 files changed, 96 insertions, 30 deletions
diff --git a/byterun/rotatecursor.c b/byterun/rotatecursor.c index ad75c24c7..46f7d07fd 100644 --- a/byterun/rotatecursor.c +++ b/byterun/rotatecursor.c @@ -11,29 +11,35 @@ /* $Id$ */ -/* Cursor rotation for MPW tools (ocamlrun and ocamlyacc) */ +/* Rotatecursor library, written by Damien Doligez + This file is in the public domain. + version 1.7 + + See rotatecursor.h for documentation. +*/ #include <CursorCtl.h> +#include <MacTypes.h> #include <stdlib.h> #include <Timer.h> -#include <Types.h> #include "rotatecursor.h" -int volatile have_to_interact; - typedef struct { TMTask t; int volatile *p1; int volatile *p2; } Xtmtask; -static Xtmtask mytmtask; +int volatile rotatecursor_flag = 1; +static int rotatecursor_inited = 0; +static int rotatecursor_period = 50; +static Xtmtask rotatecursor_tmtask; #if GENERATINGCFM -static void mytimerproc (Xtmtask *p) +static void rotatecursor_timerproc (Xtmtask *p) { if (p->p1 != NULL && *(p->p1) == 0) *(p->p1) = 1; if (p->p2 != NULL && *(p->p2) == 0) *(p->p2) = 1; @@ -43,38 +49,59 @@ static void mytimerproc (Xtmtask *p) extern Xtmtask *getparam() ONEWORDINLINE(0x2009); /* MOVE.L A1, D0 */ -static void mytimerproc (void) +static void rotatecursor_timerproc (void) { register Xtmtask *p = getparam (); - if (p->p1 != NULL) *(p->p1) = 1; - if (p->p2 != NULL) *(p->p2) = 1; + if (p->p1 != NULL && *(p->p1) == 0) *(p->p1) = 1; + if (p->p2 != NULL && *(p->p2) == 0) *(p->p2) = 1; } #endif /* GENERATINGCFM */ -static void remove_task (void) +static void rotatecursor_remove_task (void) { - RmvTime ((QElemPtr) &mytmtask); + RmvTime ((QElemPtr) &rotatecursor_tmtask); } -void rotatecursor_init (int volatile *p1) +static void rotatecursor_init (void) { + if (rotatecursor_inited) return; + InitCursorCtl (NULL); - mytmtask.t.tmAddr = NewTimerProc (mytimerproc); - mytmtask.t.tmWakeUp = 0; - mytmtask.t.tmReserved = 0; - mytmtask.p1 = p1; - mytmtask.p2 = &have_to_interact; - InsTime ((QElemPtr) &mytmtask); - PrimeTime ((QElemPtr) &mytmtask, 1); - atexit (remove_task); + + rotatecursor_tmtask.t.tmAddr = NewTimerProc (rotatecursor_timerproc); + rotatecursor_tmtask.t.tmWakeUp = 0; + rotatecursor_tmtask.t.tmReserved = 0; + rotatecursor_tmtask.p1 = NULL; + rotatecursor_tmtask.p2 = &rotatecursor_flag; + + InsTime ((QElemPtr) &rotatecursor_tmtask); + PrimeTime ((QElemPtr) &rotatecursor_tmtask, 1); + + atexit (rotatecursor_remove_task); + + rotatecursor_inited = 1; +} + +void rotatecursor_options (int volatile *p1, int period) +{ + if (!rotatecursor_inited) rotatecursor_init (); + + rotatecursor_tmtask.p1 = p1; + rotatecursor_period = period; } int rotatecursor_action (int reverse) { - PrimeTime ((QElemPtr) &mytmtask, 50); /* 20 Hz */ + if (!rotatecursor_inited) rotatecursor_init (); + + rotatecursor_flag = 0; + + PrimeTime ((QElemPtr) &rotatecursor_tmtask, rotatecursor_period); + RotateCursor (reverse ? -32 : 32); + return 0; } diff --git a/byterun/rotatecursor.h b/byterun/rotatecursor.h index 8951c418d..53414e11c 100644 --- a/byterun/rotatecursor.h +++ b/byterun/rotatecursor.h @@ -5,29 +5,68 @@ /* Damien Doligez, projet Para, INRIA Rocquencourt */ /* */ /* Copyright 1996 Institut National de Recherche en Informatique et */ -/* Automatique. Distributed only by permission. */ +/* en Automatique. Distributed only by permission. */ /* */ /***********************************************************************/ /* $Id$ */ -/* Cursor rotation for MPW tools (ocamlrun and ocamlyacc) */ +/* Rotatecursor library, written by Damien Doligez + This file is in the public domain. + version 1.7 + + The goal of this library is to help implement cooperative multitasking + for MPW tools: to make sure that your program calls RotateCursor often + enough (about 20 times per second) but not too often (to avoid a big + slowdown). It can also be used in applications as soon as you have + an implementation of InitCursorCtl and RotateCursor (which is not hard + to do). + + Simplified usage: + + 1. #include this file where appropriate + 2. Insert the following line in the inner loop(s) of your program: + ROTATECURSOR_MAGIC (); + The overhead of this macro is only a few CPU cycles, so it can be + used without problem even in a tight loop. +*/ #ifndef _rotatecursor_ #define _rotatecursor_ -/* [have_to_interact] will be magically set to 1 when the time comes to - call [rotatecursor_action]. */ -extern int volatile have_to_interact; +/* [rotatecursor_flag] will be automagically set to 1 when the time comes + to call [rotatecursor_action]. +*/ +extern int volatile rotatecursor_flag; + -/* [*p1] and [have_to_interact] will be set to 1 when the time comes to - call [rotatecursor_action]. If p1 is not used, pass it as NULL. +/* Use [rotatecursor_options] to set advanced parameters: + + 1. [p1] is a pointer to another variable that will be set to 1 when + the time is up, unless it is already nonzero. Typical use is when + you already have a variable in your program that is set + asynchronously for something else, and you want to avoid testing + two different variables in your inner loop. Pass NULL if you don't + need this feature. + + 2. [period] is the interval (in milliseconds) between calls to + RotateCursor. Reasonable values are between 10 and 200; + the default is 50. */ -void rotatecursor_init (int volatile *p1); +void rotatecursor_options (int volatile *p1, int period); /* [reverse] is 0 to rotate the cursor clockwise, anything else to - rotate counterclockwise. This function always returns 0. + rotate counterclockwise. This function resets [rotatecursor_flag] + to 0. + This function always returns 0. It returns an int so you can use + it in an expression as well as a statement. Useful for some macros. */ int rotatecursor_action (int reverse); +/* Simple interface to [rotatecursor_flag] and [rotatecursor_action]. + Can be used as a statement (followed by a semicolon) or in an + expression (followed by a comma). +*/ +#define ROTATECURSOR_MAGIC() (rotatecursor_flag ? rotatecursor_action (0) : 0) + #endif /* _rotatecursor_ */ |