summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--byterun/rotatecursor.c69
-rw-r--r--byterun/rotatecursor.h57
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_ */