home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Carousel Volume 2 #1
/
carousel.iso
/
mactosh
/
lang
/
simpleto.hqx
/
SimpleTools.c
next >
Wrap
Text File
|
1985-10-02
|
31KB
|
912 lines
/*
Title : SimpleTools.c
Author : Erik Kilk Copyright 1985
Date : June 7, 1985
Version : 1.2
Revisions:
09/05/85 EK Removed fix needed for a old compiler bug
07/13/85 EK Fixed menu unhilighting with D.A.'s menus.
07/16/85 EK Resettable default for new window type and has goaway.
Included menu command key usage.
07/17/85 EK Removed menu changes to avoid flicker.
Added return codes to most functions.
Fixed in-content call from changing event record.
Synopsis: A collection of subroutines to simplify programming
the Macintosh in C. These are for those little programs
you are tempted not to write because of all the hassles
you have to go through writing programs for the Macintosh
environment.
Copyright: These routines are copyrighted by Erik Kilk. You
may use them for your programming, as examples for your
own programming, in your programs, in programs you
distribute, copy them, and give copies to others who will
abide by these rules if you send $10 or more to:
Erik Kilk
325 San Leandro Way
San Francisco, CA 94127
You use this software "as is". The author make no
promises and is not responsible nor liable for anything
due to your use of these subroutines.
Thank you for your support.
Summary of User Routines:
simpletools ("About SimpleTools"); Initialize
simpleevents (); Process next event
menu ("Search", "Find", findroutine); Add a menu
window ("Sketch", 50,50,200,200,
activate,deactivate,update,content); Add a window
withwindow ("Sketch"); Set output to window
run (routine); Periodically call a routine
stop (routine); Stop periodic call
message ("Welcome to SimpleTools"); Display dialog message
prompt ("What is your name?", answer); Ask a question
simpletools("Name");
Call this once at the very beginning of your program. Pass
it the name of your program if you want an "About Name" menu
entry, otherwise pass it just "" as the name. It initializes
the data structures used by SimpleTools. It also does all of
the toolbox initializing and
installs the Apple, File, and Edit menus. Only base pointers
to linked structures and a few flags and scratch variables are
set. All other data is dynamically allocated with relocatable
blocks through the Macintosh memory manager for each new menu
and window created with these SimpleTools routines.
simpleevents();
Repeatedly call this routine as fast as you can. Often this
routine is in a for(;;) loop in the main procedure. This routine
handles menu selection, desk accessory startups, window moves,
window resizes, close-box clicks, all window events, and the
periodic calling of routines. It will only handle menus, windows,
and periodic routines installed with simpletools(), menu(),
window(), and run().
This routine does the systemtask() and getnextevent() calls
so you don't have to process them yourself.
At times simpleevents() will be looking up assigned procedures
to be executed. These procedures are passed some of information
particular to its situation. With Magamax C (and possibly others)
the called procedure need not declare or use this passed data if
it has no need for it. The kind of data passed is described below.
For key down and autokey events, the procedures set in
keydownproc and autokeyproc are passed the address to the event
record. By default, keydownproc and autokeyproc are set to
a no op procedure.
menu ("Settings", "Trace Execution", hideproc );
Call this routine for each menu to install or modify. The
first argument is the menu bar title, the second is the item name,
and the third is either the procedure to be executed when that
item is selected or a modifier ( 0L, itemdisable; 1L, itemenable;
2L, itemcheck, 3L, itemuncheck). The first call with a particular
menu/item pair will install the menu/item with either a procedure
or modifier (in which case it is assigned a no op procedure.)
Subseqent calls are used to change either the assigned procedure or
the current active modifiers. Calling it with a null item name
will disable or enable the entire menu if the menu already exists
and the third parameter is either a 0L or 1L as listed above.
Assigned procedures will be called with a (char *) pointing to
the item name chosen.
menuhandle mhand ("Settings");
This function returns the handle to a given menu bar selection
so that you can call the Menu manager routines yourself.
window ("Trace Output", 256, 50, 500, 300, activateproc,
deactivateproc, updateproc, incontentproc);
Call this routine for each window to install or modify. The
first argument is the window's name. Then the (x,y) of the top
left corner and the (x,y) of the bottom right corner. These
coordinates are only used for installing a window and will be
ignored for subsequent calls. Then comes four procedure names.
Activateproc is called when the window becomes the active window.
Deactivate when another window is activated. Updateproc when
windows have moved and the window needs redrawn. And incontentproc
when the mouse is clicked inside the window.
New windows are given a menu selection of their name under
a menu bar title of "Windows." Menu() is used to install these.
The procedure called for each window name is a procedure to
bring back the window if it was closed by clicking its closebox or
activate it (in case it is hidden and can't be clicked on.
When the close-box of a window is clicked, the window is just
hidden, it isn't really closed.
The assigned "in content" procedure will be called with two
(int)s. The x and y of the mouse position in that window's
local coordinates. Each assigned window procedure is also called
with a (windowptr) to the target window and an address to
the event record which just occured. Before each is called,
the current port is set to the target window.
withwindow ("Trace Output");
Call this routine to set the current output port to the
asked for window. Remember that proper scrolling of text in the
window is only taken care of for the active window though output
can be to any window.
windowptr windowpoint ("Trace Output");
This function returns a pointer to the given window name in
case you want to use one of the Window manager routines your
self.
run (flashsquareproc);
Call this routine to install a procedure to be periodically
executed. Up do 100 procedures may be installed at once. These
procedure are called just after each i/o event is read. They are
called with the address of the current unprocessed eventrecord.
stop (flashsquaresproc);
Call this to remove a procedure from the list of procedures
running periodically as installed with run().
message ("Are you sure you want to quit?");
Puts up a dialog with your message and an OK and Cancel
button. Returns true if OK is clicked, false if Cancel hit.
Memory for the dialog is allocated when it is put up and
returned to the heap when a button is clicked.
prompt ("What is your name?", answer);
Where answer is a string set to a default value. Puts up
a dialog with your question, an editable answer field with you
default answer, the OK and Cancel buttons. Returns true when
OK or RETURN is entered, false if Cancel is clicked.
*/
overlay "simpletools" /* remove or change this if needed */
#include <mem.h> /* include type defs and constants */
#include <qd.h> /* for the Macintosh tool box */
#include <qdvars.h>
#include <misc.h>
#include <event.h>
#include <res.h>
#include <win.h>
#include <te.h>
#include <dialog.h>
#include <menu.h>
#include <string.h>
#include <stdio.h>
#define TRUE (-1) /* local definitions */
#define FALSE 0
#define itemdisable 0 /* constants for menu modifiers */
#define itemenable 1
#define itemcheck 2
#define itemuncheck 3
#define maxsruns 50 /* procedure table size */
#define MESSN 30 /* array size for message dialog items */
#define QUESN 40 /* array size for prompt dialog items */
typedef struct { /* structure for an item */
char itemname[40]; /* to allow reference by name */
int itemno; /* item number within menu */
int menuid; /* menu id in case menu info is needed */
menuhandle menuhand; /* item's menu's handle */
procptr menurun; /* procedure to run */
ptr next; /* pointer to the next item */
} itemdatum;
typedef struct { /* structure for a menu */
char menuname[20]; /* to allow reference by name */
int menuid; /* menu id used to create the menu */
menuhandle menuhand; /* menu handle used to reference menu */
itemdatum **itemlist; /* pointer to the list of items */
ptr next; /* pointer to the next menu */
} menudatum;
typedef struct { /* structure for a window */
char windname[80]; /* the window's name and reference */
windowptr wptr; /* the window's pointer reference */
procptr wact; /* the activate procedure */
procptr wdeact; /* the deactivate procedure */
procptr wupdate; /* the update procedure */
procptr wcontent; /* the content procedure */
ptr next; /* pointer to the next window */
} winddatum;
menudatum **simplemenus; /* handle to menu data */
char accname[80]; /* desk accessory name to open */
rect dragrect, sizerect; /* limits for moving windows */
int wprocid = documentprod; /* window procedure id */
int dogoaway = TRUE; /* if window has go away box */
winddatum **simplewinds; /* handle to window data */
int firstwind; /* true if no windows have been made */
procptr keydownproc,
autokeyproc; /* routines for key down events */
procptr simpleruns[maxsruns]; /* list of procedures to run */
char applestring[2]
= {'\024', '\0'}; /* name of apple menu */
windowptr debugw; /* a window pointer for debugging */
int windmenu = TRUE; /* whether or not a window menu is made */
/******************************************************************/
/* Dialog lists. These were calculated by using the new resource */
/* editor to make a template for a dialog and then using fedit to */
/* list the hex listing of the item list for the dialog. */
/******************************************************************/
int messd[MESSN] = {2,0,0,0x38,0xf1,0x4c,0x12d,0x402,0x4f4b,0,0,5,5,
0x36,0x12d,0x800,0,0,0x38,0xac,0x4c,0xe8,0x406,
0x4361,0x6e63,0x656c};
int quesd[QUESN] = {3,0,0,0x21,0xf0,0x35,0x12c,0x402,0x4f4b,0,0,8,8,
0x28,0xe8,0x800,0,0,0x2b,8,0x4b,0xe8,0x1000,0,0,
8,0xf0,0x1c,0x12c,0x406,0x4361,0x6e63,0x656c};
stnop() /* a no op procedure for defaults */
{
}
/* Given a menu name, find our data structure for it. Return a handle
to this structure.
*/
menudatum **getourmenuhandle (name)
char *name; /* name of menu bar menu */
{
menudatum **here; /* a handle to our menu structure */
here = simplemenus;
/* find the menu name or the end of out menu list */
while ( (strcmp(name,(**here).menuname) != 0) &
((**here).next != (ptr)0L) )
here = (menudatum **)(**here).next;
/* see if we found it or just the end of the list */
if (strcmp(name,(**here).menuname) == 0)
return (here);
else
return ((menudatum **)0L); /* return 0 if not found */
}
/* Given a menu name, return the real menu handle as used by most
of the Macintosh toolbox menu manager routines.
*/
menuhandle mhand (name) /* find menuhandle */
char *name; /* given name of menu */
{
menudatum **menu; /* a handle to our data */
menu = getourmenuhandle(name);
if ( (long) menu != 0L )
return ( (**menu).menuhand); /* return menu handle */
else
return ( (menuhandle) 0 ); /* return 0 if not found */
}
/* This takes a handle to our personal item record and either a
procedure name or a modifier code. If it got a procedure name,
it sets it to the item's procedure to run when the item is chosen.
If it got a modifier code, it changes the state of the menu's item
to checked, unchecked, enabled, or disabled. It especially keeps
track of the standard Edit menu items so we can restore them after
a desk accessory is finished.
*/
setitem ( items, routine) /* set a menu item's routine or display */
itemdatum **items; /* if items is neg, then whole menu */
procptr routine;
{
int inumber;
menuhandle mhand;
/* check to see if a procedure pointer was given to us */
if ( (((long)items)>0L) && (routine > (procptr)0x1000L)) {
/* a good procedure value */
(**items).menurun = routine;
return;
}
/* Calculate which item number we are going to modify */
if ( (long)items < 0L) { /* the whole menu */
mhand = (menuhandle) (0L - (long)items);
inumber = 0;
}
else { /* just one item */
mhand = (**items).menuhand;
inumber = (**items).itemno;
}
/* If a NULL procedure pointer, then set to a no_op routine */
if ( (inumber > 0) && ((**items).menurun == (procptr)0L) )
(**items).menurun = stnop;
/* Now change the state of a menu item */
switch ((int)routine) {
case itemdisable:
disableitem(mhand,inumber); break;
case itemenable:
enableitem(mhand, inumber); break;
case itemcheck:
checkitem(mhand, inumber, TRUE); break;
case itemuncheck:
checkitem(mhand, inumber, FALSE); break;
}
if (inumber == 0) drawmenubar(); /* if main menu was changed */
}
/* This routine is described above. It takes care of our menu data
structure by adding or modifying menu entries.
*/
menu (name, item, routine) /* install or change a menu */
char *name; /* the menu name */
char *item; /* the item name */
char * routine; /* a procedure or modifier */
{
menudatum **here; /* a roving handle to our data */
menudatum **ourmhandle; /* another handle to our data */
itemdatum **items; /* a handle to the item */
menuhandle mhandle; /* a handle to the real menu */
int lastid, lastitem;
/* get the handle to menu named 'name' */
if ((ourmhandle = getourmenuhandle (name)) == 0L) {
/* make a new menu entry by finding the end of the list */
here = simplemenus;
while ((**here).next != 0L)
here = (menudatum **)(**here).next;
/* make a structure for our new entry */
lastid = (**here).menuid;
(**here).next = (ptr)newhandle ( (long)sizeof(menudatum));
here = (menudatum **)(**here).next;
strcpy ( (**here).menuname, name);
(**here).menuid = ++lastid;
(**here).next = (ptr) 0L;
/* make a new item structure */
(**here).itemlist = (itemdatum **)newhandle (
(long)sizeof(itemdatum));
/* make a new menu entry for the Macintosh */
(**here).menuhand = newmenu (lastid, name);
mhandle = (**here).menuhand;
items = (**here).itemlist;
strcpy ((**items).itemname, item);
(**items).itemno = 1;
(**items).menuid = lastid;
(**items).menuhand = (**here).menuhand;
(**items).menurun = (procptr) 0L;
(**items).next = 0L;
/* install and display the menu */
appendmenu ((**here).menuhand, item);
insertmenu ((**here).menuhand,0);
setitem (items, routine);
drawmenubar();
return(TRUE);
}
else {
if (strlen(item) == 0) {
/* then adjust main menu */
setitem( 0L - (long) ((**ourmhandle).menuhand), routine);
return(FALSE);
}
/* see if item is in list */
items = (**ourmhandle).itemlist;
while ( (strcmp(item,(**items).itemname) != 0) &
((**items).next != (ptr)0L)) {
items = (itemdatum **)(**items).next;
}
if (strcmp(item,(**items).itemname) ==0) {
setitem( items, routine);
return(FALSE);
}
else {
/* make new item entry */
lastitem = (**items).itemno;
(**items).next =(ptr)newhandle(
(long)sizeof(itemdatum));
items = (itemdatum **)(**items).next;
strcpy ((**items).itemname, item);
(**items).itemno = ++lastitem;
(**items).menuid = (**ourmhandle).menuid;
(**items).menuhand = (**ourmhandle).menuhand;
(**items).menurun = (procptr) 0L;
(**items).next = 0L;
/* and install the item in the menu bar */
appendmenu ((**ourmhandle).menuhand,item);
setitem (items, routine);
return(TRUE);
}
}
}
/* This routine is called by the simpletools() initial routine. It gets
the pointer list of menus started, loads the desk accessories into
the Apple menu, and loads up some standard menu entries. The reason
menu File has a New entry, and none others, is because as this code
currently stands, a menu must have at least one item. And since we
want File before Edit, I had to make an entry. The most commonly used
item under File is Quit. But we like quit to be at the end of the list.
So, since New is usually always first when it is used, that the one
chosen to start File.
*/
initsmenus(about) /* init simpletools' menus */
char *about;
{
itemdatum **items;
simplemenus = (menudatum **) newhandle ( (long)sizeof(menudatum));
strcpy ( (**simplemenus).menuname, applestring);
(**simplemenus).menuid = 1;
(**simplemenus).next = (ptr) 0L;
(**simplemenus).menuhand = newmenu (1, (**simplemenus).menuname);
(**simplemenus).itemlist = (itemdatum **)newhandle (
(long)sizeof(itemdatum));
items = (itemdatum **) (**simplemenus).itemlist;
strcpy ((**items).itemname, about);
(**items).itemno = 1;
(**items).menuid = 1;
(**items).menuhand = (**simplemenus).menuhand;
(**items).menurun = stnop;
(**items).next = 0L;
appendmenu ((**simplemenus).menuhand, about);
disableitem ((**simplemenus).menuhand, 1);
menu (applestring, "-", (procptr) itemdisable);
addresmenu ((**simplemenus).menuhand, "DRVR");
insertmenu ((**simplemenus).menuhand, 0);
menu ("File", "New", (procptr)itemdisable);
menu ("Edit", "Undo", stnop);
menu ("Edit", "-", (procptr)itemdisable);
menu ("Edit", "Cut/X", stnop);
menu ("Edit", "Copy/C", stnop);
menu ("Edit", "Paste/V", stnop);
menu ("Edit", "Clear", stnop);
}
/* Given a window's name, return its window pointer so that other
Macintosh Window Manager routines can be called for that window. */
windowptr windowpoint(name) /* get window pointer */
char *name; /* given window's name */
{
winddatum **wind; /* handle to our window data */
if (firstwind) return ((windowptr)0); /* forget if there aren't any */
wind = simplewinds; /* look for the named window */
while ( (strcmp ((**wind).windname, name) != 0) &
((**wind).next != (ptr) 0)) {
wind = (winddatum **) (**wind).next;
}
if ( strcmp ((**wind).windname, name) ==0)
return ( (**wind).wptr); /* return pointer */
else
return ( (windowptr) 0); /* or zero if it wasn't found */
}
/* This routine is for the Windows menu item. The Windows menu is
set up when new windows are added. It is used to bring forward and
bring into view windows that may be under other windows or have been
sent hiding by a click on their close box.
*/
showawindow(name) /* show the named window */
char *name;
{
windowptr foo;
foo = windowpoint(name); /* get its window pointer */
if ( (long)foo != 0L ) {
showwindow(foo); /* show it on the screen */
setport (foo); /* set further output to it */
if ( foo != frontwindow()) /* if it isn't active, */
selectwindow (foo); /* activate it */
}
}
/* This routine installs a new window onto the screen. It also gives
that window an item in the Window menu. This routine is also used
to modify a window's associated routines. The x,y positions are the
top left and bottom right corners of where the window should originally
be placed. The coordinates are never used when this routine is called
to update an already existing window. But the spaces must be filled,
so you can use zeros if you want. Once the window has been displayed in
its original position, the user has complete control of its size and
placement with the mouse.
*/
window(name, xtop, ytop, xbot, ybot, a, d, u, c)
char *name; /* window's name */
int xtop, ytop, xbot, ybot; /* position if this is a new window */
procptr a, d, u, c; /* activate, deactivate, update, and */
{ /* content procedure names */
winddatum **wind; /* handle to our window data */
winddatum **newentry; /* another handle */
rect newplace; /* a rectable for the window's placement */
if (a == (procptr) 0)
a = stnop;
if (d == (procptr) 0)
d = stnop;
if (u == (procptr) 0)
u = stnop;
if (c == (procptr) 0)
c = stnop;
if ( !firstwind ) {
/* see if window is in the list */
wind = simplewinds;
while ( (strcmp ((**wind).windname, name) != 0) &
((**wind).next != (ptr) 0)) {
wind = (winddatum **) (**wind).next;
}
if ( strcmp ((**wind).windname, name) ==0) {
/* reset the found window's parameters */
(**wind).wact = (procptr) a;
(**wind).wdeact = (procptr) d;
(**wind).wupdate = (procptr) u;
(**wind).wcontent = (procptr) c;
setport ( (**wind).wptr); /* set output to window */
return(FALSE);
}
}
/* make a new window entry */
newentry = (winddatum **)newhandle ( (long) sizeof (winddatum));
if (firstwind)
simplewinds = newentry;
else
(**wind).next = (ptr) newentry;
firstwind = 0;
strcpy ((**newentry).windname, name);
setrect (&newplace, xtop, ytop, xbot, ybot);
(**newentry).wptr = newwindow (0L, &newplace, name, -1,
wprocid, -1L, dogoaway, newentry);
(**newentry).wact = (procptr) a;
(**newentry).wdeact = (procptr) d;
(**newentry).wupdate = (procptr) u;
(**newentry).wcontent = (procptr) c;
(**newentry).next = (ptr) 0;
if (windmenu)
menu ("Windows", name, showawindow);/* make a menu entry for it */
setport ( (**newentry).wptr); /* set output to it */
return(TRUE);
}
winddatum **wdatum(windpt) /* return handle to window data */
windowptr windpt;
{
winddatum **wind;
if (firstwind) return ((winddatum **) 0L);
wind = simplewinds;
while ( ((**wind).wptr != windpt) & /* search for window's name */
((**wind).next != (ptr) 0)) {
wind = (winddatum **) (**wind).next;
}
if ( (**wind).wptr == windpt)
return (wind);
else
return ((winddatum **) 0L); /* zero if not found */
}
withwindow(name) /* set output to a window by name */
char *name; /* give it the window's name */
{ /* returns boolean if window exists */
winddatum **wind;
wind = simplewinds;
if (firstwind) return(FALSE); /* search for the window's name */
while ( (strcmp ((**wind).windname, name) != 0) &
((**wind).next != (ptr) 0)) {
wind = (winddatum **) (**wind).next;
}
if ( strcmp ((**wind).windname, name) ==0) {
setport ( (**wind).wptr); /* set output to it */
return(TRUE);
}
else
return(FALSE);
}
/* This run procedure is used to install routines to be occasionally
run. The routine will be run once for each call to simpleevents()
*/
run(routine) /* install a run procedure */
procptr routine; /* give it the procedure */
{ /* return TRUE if successful */
int i;
i = 0; /* add it to the end of the list */
while ( simpleruns[i] != (procptr) 0L) i++;
if (i < maxsruns) {
simpleruns[i] = routine;
simpleruns[i+1] = (procptr) 0L;
return(TRUE);
}
else
return(FALSE);
}
/* This routine removes a procedure from the list of run procedures */
stop(routine) /* stop a procedure from running */
procptr routine; /* give the procedure */
{ /* return TRUE if successful */
int i;
i = 0;
while ( (simpleruns[i] != routine) & (simpleruns[i] != (procptr) 0L))i++;
if (simpleruns[i] == (procptr) 0L)
return(FALSE);
else {
while ( simpleruns[i] != (procptr)0 ) {
simpleruns[i] = simpleruns[i+1];
i++;
}
return(TRUE);
}
}
runruns(event) /* run all the installed run procedures */
eventrecord *event; /* returns number of routines run */
{
int i;
i = 0;
while ( simpleruns[i] != 0 )
(*(simpleruns[i++])) (event);
return(i);
}
stdialog( question, answer, type) /* a general dialog displayer */
char *question;
char *answer;
int type; /* type: 1=prompt, 2=message */
{
dialogptr dialog; /* dialog reference */
handle item, items; /* handles for the dialog items */
rect screen, box; /* rectangles for dialog/items */
int dtype, hit, canc; /* item type and which was hit */
char tempanswer[255]; /* address where answer is */
items = newhandle (512L); /* get memory for items list */
hlock (items); /* lock it down */
if (type == 1)
blockmove (quesd, *items, (long) QUESN * 2L); /* fill it with list */
else
blockmove (messd, *items, (long) MESSN * 2L);
setrect (&screen, 103, 50, 409, 137); /* position window */
dialog = newdialog (0L, &screen, "", 0, dboxproc, -1L, 0, 0L, items);
getditem (dialog, 2, &dtype, &item, &box); /* get item#2 handle */
setitext (item, question); /* set item#2 text */
if (type == 1) { /* set default answer */
getditem (dialog, 3, &dtype, &item, &box);
setitext (item, answer);
canc = 4;
}
else
canc = 3;
showwindow (dialog); /* display the dialog */
do {
modaldialog (0L, &hit); /* process the dialog */
} while ( (hit != 1) & (hit != canc) );
if (type == 1) {
getditem (dialog, 3, &dtype, &item, &box); /* get item#3 handle */
hlock (item);
getitext (item, tempanswer); /* get item#3 text */
strcpy (answer, tempanswer); /* make a copy of it */
hunlock (item);
}
hunlock(items); /* unlock items memory */
hpurge(items); /* purge it */
disposdialog (dialog); /* get rid of dialog */
return ( hit==1 ); /* return true if ok */
}
prompt ( question, answer) /* dialog box question/answer */
char *question;
char *answer;
{
return (stdialog (question, answer, 1));
}
message ( message ) /* dialog box message */
char *message;
{
return (stdialog (message, message, 2));
}
docommand (which, thisevent)
long which;
eventrecord *thisevent;
{
int themenu, theitem;
long size;
char *cpoint;
grafptr tempport;
menudatum **here;
itemdatum **items;
char **myreshandle;
handle myhandle;
themenu = hiword (which);
theitem = loword (which);
if ((themenu == 1) && (theitem != 1)) {
/* start up a desk accessory */
getitem ((**simplemenus).menuhand,
theitem, accname);
setresload (FALSE);
myreshandle = getnamedresource ("DRVR", accname);
setresload (TRUE);
size = sizeresource (myreshandle);
myhandle = newhandle ( size + 3072L);
if (myhandle == 0L)
message ("Not enough memory to do that.");
else {
disposhandle (myhandle);
getport (&tempport);
opendeskacc(accname);
setport (tempport);
}
return;
}
if (themenu ==3) {
/* do any system edits */
if (systemedit(theitem -1) != FALSE)
return;
}
/* now we run an installed menu procedure */
here = simplemenus;
/* find out menu structure given the menu id */
while ( ((**here).menuid != themenu) &
((**here).next != (ptr)0L) )
here = (menudatum **)(**here).next;
if ((**here).menuid == themenu) {
/* now find the item structure */
items = (**here).itemlist;
while ( ((**items).itemno != theitem) &
((**items).next != (ptr) 0L) )
items = (itemdatum **)(**items).next;
/* prepare to give the item name to the procedure */
cpoint = (**items).itemname;
if ((**items).itemno == theitem)
/* if we found the item, call its procedure */
(*((**items).menurun))(cpoint,thisevent) ;
}
}
domousedown(thisevent) /* respond to mouse down events */
eventrecord *thisevent; /* passed the event record */
{
windowptr whichwindow;
int code, x, y;
char *cpoint;
menudatum **omhand;
winddatum **thewdatum;
long newplace;
point temp;
code = findwindow(&(thisevent->where), &whichwindow);
switch (code) {
case inmenubar:
docommand(menuselect(&(thisevent->where)),thisevent);
break;
case insyswindow:
systemclick(thisevent, whichwindow); break;
case indrag:
dragwindow(whichwindow, &(thisevent->where),
&dragrect); break;
case ingrow:
newplace= growwindow(whichwindow, &(thisevent->where),
&sizerect);
sizewindow(whichwindow, loword(newplace),
hiword(newplace), TRUE);
break;
case ingoaway:
if ( trackgoaway(whichwindow, &(thisevent->where))) {
hidewindow (whichwindow);
}
break;
case incontent:
/* make the window active if it isn't yet */
if (whichwindow != frontwindow()) {
selectwindow(whichwindow);
}
/* find our window data */
thewdatum = wdatum (whichwindow);
if ((long) thewdatum != 0L) {
/* convert the point of click to the window's
own coordinates since this will be always
more useful than the global coordintates */
temp = thisevent->where;
setport (whichwindow);
globaltolocal (&temp);
x = temp.a.h;
y = temp.a.v;
/* call the window's in content routine */
(*((**thewdatum).wcontent))(x, y, whichwindow,
thisevent);
}
break;
}
}
simpletools(about) /* to be called at the beginning of program */
char *about;
{
maxapplzone(); /* allow maximum heap expansion */
flushevents (everyevent,0); /* ignore left over events */
initgraf (&theport); /* initialize the screen */
initfonts();
initwindows();
initmenus();
initcursor(); /* make the arrow cursor */
teinit();
initdialogs(0L);
setrect ( &sizerect, 20, 50, 250, 330);
/*
debugw = newwindow(0L,&sizerect,"Debug",-1,documentproc,-1L,-1L,0L);
*/
simpleruns[0] = (procptr) 0; /* empty the run list */
/* These are the bounds we are allowed to size a window or
move a window to.
*/
setrect ( &sizerect, 20, 20, 511, 341);
setrect ( &dragrect, 4, 24, 507, 337);
firstwind = 1; /* empty window table */
keydownproc = stnop; /* default key hit procedures */
autokeyproc = stnop;
initsmenus(about); /* install the menus */
}
simpleevents() /* to be called in the main loop */
{
eventrecord newevent;
winddatum **thewdatum;
systemtask(); /* Do the system D.A. etc. stuff */
hilitemenu(0);
getnextevent(everyevent, &newevent);
runruns(&newevent); /* Do our run procedures */
switch (newevent.what) {
case mousedown:
domousedown(&newevent); break;
case keydown:
if ((newevent.modifiers & cmdkey) != 0)
docommand(menukey((char)(newevent.message & 0xffL)),
&newevent);
(*(keydownproc))(&newevent);
break;
case autokey:
if ((newevent.modifiers & cmdkey) != 0)
docommand(menukey((char)(newevent.message & 0xffL)),
&newevent);
(*(autokeyproc))(&newevent);
break;
case activateevt:
thewdatum = wdatum(newevent.message);
if ((long)thewdatum != 0L) {
setport(newevent.message);
if ((newevent.modifiers & 1) == 1) {
(*((**thewdatum).wact))(newevent.message,
&newevent);
}
else {
(*((**thewdatum).wdeact))(newevent.message,
&newevent);
}
}
break;
case updateevt:
thewdatum = wdatum(newevent.message);
if ((long)thewdatum != 0L) {
setport (newevent.message);
beginupdate (newevent.message);
(*((**thewdatum).wupdate))(newevent.message,
&newevent);
endupdate (newevent.message);
}
break;
}
}