home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-09-08 | 35.0 KB | 1,008 lines | [TEXT/MPS ] |
- {[j=20-/40/80!,o=95,a-]} { PasMat formatting options }
-
- {$SETC AppleShareFriendly = FALSE} {set this to TRUE to save configuration to a resource
- file, FALSE saves it to the application's resources}
-
- PROGRAM Events; {a program to demonstrate how an application receives
- events under Juggler 6/30/87}
-
- {
- modified 8/1/87(v1.0B4): Just call SystemTask iff GNE is being called
- Saves window positions (like a real "Juggler-friendly" app)
- modified 9/1/87 to fix bugs -- thanks CK!
- }
-
- USES
- {$PUSH}
-
- {$LOAD PasDump.dump}
- Memtypes,QuickDraw,OSIntf,ToolIntf,PackIntf,WLW {WritelnWindow};
- {$LOAD}
- {$POP}
-
- {$D+}
- {$R-}
-
- CONST
- TheAngle = 15; {angle to paint in each time in dial-drawing routine}
- MaxChunk = 360 DIV TheAngle;
- WNETrapNum = $60; {trap number of WaitNextEvent}
- UnImplTrapNum = $9F; {trap number of "unimplemented trap"}
-
- {Window IDs}
- FugitID = 128;
- InfoID = 129; {resource IDs of our two windowettes}
- DebugID = 130; {resource ID of WIND template for debug window}
- AboutMeDLOG = 128; {resource ID of our about dialog}
-
- DebugWNum = 1; {array indices to our windows}
- FugitWNum = 2;
- InfoWNum = 3;
-
- NumWindows = InfoWNum; {FugitWind,InfoWind,DebugWind}
-
- {Menu IDs}
- MenuCount = 3; {total number of menus}
- AppleID = 128; {resource IDs/menu IDs for Apple,File and Options menus}
- FileID = 129;
- OptionID = 130;
-
- AppleM = 1; {index for each menu in myMenus (array of menu handles)}
- FileM = 2;
- OptionM = 3;
-
- AboutMeItem = 1; {menu item number of about me}
- QuitItem = 1; {menu item number of "quit" in file menu}
- ShowMouseItem = 1; {menu item number of ShowMouseItem in options menu}
-
- ConfCreator = 'EVNT'; {creator bytes for this application}
- ConfResType = 'CnFG'; {resource type of configuration data in configuration
- file, registered with tech support}
- ConfResID = 128; {resource ID... " " "}
- ConfigFNameStrID = 128; {resource ID of configuration file name string}
-
- {low-memory globals that we MUST use}
- GrayRgnLowMemGlobal = $9EE; {location of low-memory global for gray region -- this
- is the only way to get the correct region for multiple
- screens on the Mac II}
- MBarHeight = $BAA; {low-memory global location for mBarHeight}
-
- TYPE
- ELongPtr = ^Longint;
- EWordPtr = ^Integer;
- LongStuffType = RECORD {For type conversions}
- CASE Integer OF
- 1:
- (long: longint);
- 2:
- (HiWrd,LoWrd: Integer);
- 3:
- (HiByte,HiMidByte,LoMidByte,LoByte: SignedByte);
- END; {LongStuffType}
-
- ConfigWindInfo = RECORD
- windTopLeft: Point;
- height: Integer;
- width: Integer;
- END; {ConfigWindInfo}
-
- ConfigResType = RECORD {to write to configuration file}
- grayRgnRect: Rect; {so we can keep track of the GrayRgn's
- bbox}
- configWindArray: ARRAY [1..NumWindows] OF ConfigWindInfo;
- END;
- pConfigResType = ^ConfigResType;
- hConfigResType = ^pConfigResType;
-
- VAR
- MyMenus : ARRAY [1..MenuCount] OF MenuHandle;
- MyEvent : EventRecord;
- FugitWind : WindowPtr; {our window that will show the rotating dial}
- InfoWind : WindowPtr; {the window that will show status information}
- YieldTime : Integer; {number of ticks to pass to WNE}
- SysEnv : SysEnvRec; {for SysEnvirons}
- WNEIsImplemented : BOOLEAN; {is WaitNextEvent implemented}
- Suspended : BOOLEAN; {are we in the background?}
- Done : BOOLEAN;
- ThePat : Pattern; {used for drawing the rotating dial}
- ArcRect : Rect; { " " }
- Chunk : Integer; { " " }
- PatIsBlack : BOOLEAN; {we need this to flip patterns}
- WNERgn : RgnHandle; {cursor region to pass to WNE}
- InfoWindRgn : RgnHandle; {rgn containing rect of InfoWind in global coords}
- AllButInfoWindRgn : RgnHandle; {rgn containing everything but InfoWind rgn}
- ShowMouseMoved : BOOLEAN; {whether to report on mouse moved events or not}
- MouseMovedMessage : SignedByte; {we need this to check for mouse-moved events}
- PlusCursH : CursHandle; {cursor handle for the plus cursor}
- Err : OSErr; {general purpose error checker}
- WChanged : BOOLEAN; {have any of our windows changed -- not used in this
- version}
- SusPendCount: Integer;
- {------------------------------------------------------------------------------------}
-
- (* FUNCTION WaitNextEvent(eventMask: Integer; VAR theEvent: EventRecord; sleep: longint;
- mouseRgn: RgnHandle): BOOLEAN;
- INLINE $A860;
- *)
- {the above is now in the MPW 2.0 interfaces}
-
- {------------------------------------------------------------------------------------}
-
- PROCEDURE EvInitWW(r: Rect; wName: Str255);
-
- CONST
- EvNewCentury = 34; {font Family of New Century SchoolBook}
-
- VAR
- WWFamily,WWSize: Integer;
-
- BEGIN {InitWW}
- WWInit(50,80);
-
- IF RealFont(EvNewCentury,10) THEN BEGIN
- WWFamily := EvNewCentury;
- WWSize := 10
- END
- ELSE BEGIN
- WWFamily := monaco;
- WWSize := 9
- END;
- WWNew(r,wName,false,true,WWFamily,WWSize);
- SetWRefCon(gDebugWindowPtr,0); {clear out the refcon to show no change in configuration}
- END; {InitWW}
-
- {------------------------------------------------------------------------------------}
-
- PROCEDURE SetUpMenus;
- {set up menus and menu bar}
-
- VAR
- i : Integer;
-
- BEGIN
- MyMenus[AppleM] := GetMenu(AppleID); {read Apple menu from resource file}
- AddResMenu(MyMenus[AppleM],'DRVR'); {add desk accessory names to Apple menu}
- MyMenus[FileM] := GetMenu(FileID); {read file menu from resource file}
- MyMenus[OptionM] := GetMenu(OptionID); {read file menu from resource file}
-
- FOR i := 1 TO MenuCount DO InsertMenu(MyMenus[i],0); {install menus in menu bar}
- DrawMenuBar; {and draw menu bar}
- END; {of SetUpMenus}
-
- {------------------------------------------------------------------------------------}
-
- FUNCTION MenuBarHeight: Integer; {returns the menu height, independent of ROM}
-
- CONST
- MHt64KROM = 20; {menu-bar height for 64K ROMs}
-
- BEGIN {MenuBarHeight}
- IF SysEnv.machineType < 0 THEN {64K ROM machine}
- MenuBarHeight := MHt64KROM
- ELSE
- MenuBarHeight := EWordPtr(MBarHeight)^; {get it from low-memory}
- END; {MenuBarHeight}
-
- {------------------------------------------------------------------------------------}
-
- PROCEDURE DoAbout; {display the About box}
-
- VAR
- aboutMeDialog : DialogPtr; {our dialog}
- screenWidth : Integer;
- screenHeight : Integer;
- theItem : Integer;
-
- BEGIN {DoAbout}
- {now we'll get our INVISIBLE dialog -- invisible so we can center it}
- aboutMeDialog := GetNewDialog(AboutMeDLOG,NIL,WindowPtr( - 1));
-
- {we'll need these for centering}
- screenWidth := ScreenBits.bounds.right - ScreenBits.bounds.left;
- screenHeight := ScreenBits.bounds.bottom - ScreenBits.bounds.top-MenuBarHeight;
-
- {let's center it (it's still invisible)}
- WITH aboutMeDialog^.portRect DO
- MoveWindow(aboutMeDialog,(screenWidth - (right - left)) DIV 2,(screenHeight -
- (bottom - top)) DIV 2,TRUE); {center it}
-
- ShowWindow(aboutMeDialog); {make it visible}
- REPEAT
- ModalDialog(NIL,theItem); {this'll stop those pesky background tasks}
- UNTIL theItem = OK;
- DisposDialog(aboutMeDialog); {get rid of the about box dialog}
- END; {DoAbout}
-
-
- {------------------------------------------------------------------------------------}
-
- PROCEDURE FlipCursor;
- {we got a mouse-moved event, flip the cursor and assign the new region}
- {we only get mouse-moved events if we are the foreground app!}
- {WritelnWindow slows the cursor change in this example}
-
- BEGIN {FlipCursor}
- IF WNERgn = InfoWindRgn THEN BEGIN
- SetCursor(Arrow); {the cursor was in the InfoWind, it has moved out, set
- cursor to arrow}
- WNERgn := AllButInfoWindRgn; {flip the region}
- END
- ELSE BEGIN {the region was AllButInfoWindRgn}
- SetCursor(PlusCursH^^); {the cursor was not in the InfoWind, it moved in, set
- cursor to plu}
- WNERgn := InfoWindRgn; {flip the region}
- END
- END; {FlipCursor}
-
- {------------------------------------------------------------------------------------}
-
- PROCEDURE GetMouseCursor; {this is called when we get a menu command to turn
- ShowMouseMoved on}
-
- VAR
- mousePt : Point;
-
- BEGIN {GetMouseCursor}
- SetPort(InfoWind);
- GetMouse(mousePt); {we need to get the mouse here to see where we are when
- the command was issued}
-
- IF (PtInRect(mousePt,thePort^.portRect)) & (PlusCursH <> NIL) THEN BEGIN {we're in
- the InfoWind}
- SetCursor(PlusCursH^^); {set to plus cursor}
- WNERgn := InfoWindRgn; {we want to know when we move outside of InfoWind}
- END
- ELSE BEGIN {we're not in the InfoWind}
- SetCursor(Arrow); {set to arrow}
- WNERgn := AllButInfoWindRgn; {we want to know when we move into InfoWind}
- END; {ELSE}
- END; {GetMouseCursor}
-
- {------------------------------------------------------------------------------------}
-
- PROCEDURE DoCommand(mResult: longint; byKey: BOOLEAN);
-
- CONST
- menuTicks = 5; {number of ticks to Delay when a MenuKey is hit: 1/12
- sec.}
-
- VAR
- theItem,theMenu : Integer;
- daName : Str255; {name of DA to launch}
- temp : Integer;
- svPort : GrafPtr;
- longStuff : LongStuffType;
-
- BEGIN {DoCommand}
- longStuff.long := mResult; {Oh how I HATE calling HiWord and LoWord! -- you could
- call it, though}
- theItem := longStuff.LoWrd; {extract the menu and item numbers}
- theMenu := longStuff.HiWrd;
- CASE theMenu OF {which menu?}
- AppleID:
- IF theItem = AboutMeItem THEN
- DoAbout
- ELSE BEGIN {it's a DA - get its name and open it}
- GetPort(svPort); {save the port}
- GetItem(MyMenus[AppleM],theItem,daName);
- temp := OpenDeskAcc(daName);
- SetPort(svPort); {put us back in our port}
- END; {ELSE}
- FileID: {only one item in the File menu}
- CASE theItem OF
- QuitItem:
- Done := TRUE;
- END; {mini-case statement}
- OptionID: {for now, only one item in the Options menu}
- CASE theItem OF
- ShowMouseItem: BEGIN {this item will be disabled if we don't have
- WaitNextEvent}
- ShowMouseMoved := NOT (ShowMouseMoved); {this menu item toggles}
- CheckItem(MyMenus[OptionM],theItem,ShowMouseMoved); {check it
- accordingly}
- IF ShowMouseMoved THEN
- GetMouseCursor {find out which cursor and which region we need}
- ELSE BEGIN
- WNERgn := NIL; {pass NIL to WNE for no mouse tracking}
- SetCursor(Arrow); {no mouse tracking, set cursor to arrow}
- END;
- END; {CASE ShowMouseItem}
- END; {CASE}
- END; {menu case}
- IF byKey THEN Delay(menuTicks,longStuff.long); {Delay to show item was hit}
- HiliteMenu(0);
- END; {DoCommand}
-
- {------------------------------------------------------------------------------------}
-
- PROCEDURE UpdateWindow(theWindow: WindowPtr; theStr: Str255); {the port is set correctly by
- the main event loop}
-
- VAR
- myStr : Str255;
- r : Rect;
-
- BEGIN {UpdateWindow}
- BeginUpdate(theWindow);
- IF theWindow = InfoWind THEN BEGIN
- SetRect(r,5,0,theWindow^.portRect.right,40); {Erase just the two info items}
- EraseRect(r);
- MoveTo(5,20);
- IF WNEIsImplemented THEN BEGIN {display yieldtime}
- NumToString(YieldTime,myStr);
- DrawString(myStr);
- DrawString(' ticks');
- END
- ELSE
- DrawString('no WNE'); {this is easy}
-
- MoveTo(5,40); {to show information about 4Gnd/BackGnd}
- IF Suspended THEN
- DrawString('BackGnd')
- ELSE
- DrawString('4Gnd')
- END
- ELSE IF theWindow = FugitWind THEN
- IF PatIsBlack THEN
- FillArc(ArcRect,0,Chunk * TheAngle,Black) {fill in from 0 with black}
- ELSE
- FillArc(ArcRect,0,(Chunk * TheAngle) - 360,Black); {fill back from 0 with
- black}
-
- EndUpdate(theWindow);
- writeln(theStr); {to debug window}
- END; {UpdateWindow}
-
- {------------------------------------------------------------------------------------}
-
- PROCEDURE CalculateWNECursRgns; {called at startup time and whenever the InfoWind is
- dragged}
-
- VAR
- totalScreenRgn : RgnHandle; {used to figure out AllButInfoWindRgn}
- r : Rect; {utility rectangle}
-
- BEGIN {CalculateWNECursRgns}
- r := InfoWind^.portRect;
- WITH r DO BEGIN
- LocalToGlobal(TopLeft);
- LocalToGlobal(botRight);
- END;
- RectRgn(InfoWindRgn,r); {this needs to be in global coords}
-
- {now we'll make a region that combines the gray region and screenBits.bounds}
- {so we are sure to get the menu bar (then we won't get mouse-moveds when}
- {we're in the menu bar)}
-
- {there's probably a faster way of doing this, but this way will work with a variety}
- {of menu bar heights and multiple screens}
-
- totalScreenRgn := NewRgn; {we'll need this for a short time, get rid of it when
- done}
- {union GrayRgn's bbox with screenBits.bounds}
- UnionRect(ScreenBits.bounds,(RgnHandle(ELongPtr(GrayRgnLowMemGlobal)^)^^.rgnBBox),
- r);
- InsetRect(r, - 20, - 20); {to handle single screen Macs}
- RectRgn(totalScreenRgn,r); {convert to a region}
-
- DiffRgn(totalScreenRgn,InfoWindRgn,AllButInfoWindRgn); {diff of (gray+screenBits)
- and InfoWind}
- DisposeRgn(totalScreenRgn); {we're all done with this}
- END; {CalculateWNECursRgns}
-
- {------------------------------------------------------------------------------------}
-
- {$IFC AppleShareFriendly=TRUE}
-
- FUNCTION OpenConfigFile: Integer; {opens the configuration file, returns 0 if the open
- fails}
- {
-
- In order to keep track of our windows' positions, so that the user can put them where
- he/she wants them and they will come up that way the next time the app is run, we will
- use a configuration file. We do this in order to be server (AppleShare) friendly. We
- could keep a resource in our application's resource fork, but that would cause problems if
- the application were shared. So, we call SysEnvirons to see where we should put the file
- (SysEnv.sysVRefNum) and away we go -- both Juggler- and AppleShare-friendly
-
- }
-
- VAR
- oldVol : Integer;
- myStrH : StringHandle;
-
- BEGIN {OpenConfigFile}
- OpenConfigFile := 0; {default to error}
- Err := GetVol(NIL,oldVol); {save off the old volume}
- Err := SetVol(NIL,SysEnv.sysVRefNum); {set to the folder containing currently open
- system file}
- IF Err = noErr THEN BEGIN {if we get an error here, OpenConfigFile is set to fail
- (0) at this point}
- myStrH := GetString(ConfigFNameStrID); {from our application's resource file}
- OpenConfigFile := OpenResFile(myStrH^^); {if someone's ResEdited our resource
- away, tough!!}
- ReleaseResource(Handle(myStrH)); {all done with it}
- END; {IF err = noErr}
- Err := SetVol(NIL,oldVol); {restore default directory}
- END; {OpenConfigFile}
-
- {$ENDC}
- {------------------------------------------------------------------------------------}
-
- PROCEDURE WriteConfigInfo; {writes configuration info (window positions) to the
- configuration file}
-
- VAR
- configFileRef : Integer;
- myStrH : StringHandle;
- oldVol : Integer;
- myFndrInfo : FInfo;
-
- {------------------------------------------------------------------------------------}
-
- PROCEDURE WriteConfigData(whichResFile: Integer); {routine to write the data out}
-
- VAR
- myConfig : ConfigResType;
- hResConfig : Handle;
-
- {------------------------------------------------------------------------------------}
-
- PROCEDURE FillInWInfo(whichWind: WindowPtr; arrElem: Integer;
- VAR Data: ConfigResType); {gets window coordinates}
-
- VAR
- oldPort : GrafPtr;
- p : Point;
-
- BEGIN {FillInWInfo}
- GetPort(oldPort);
- SetPort(whichWind); {set port for the LocalToGlobal to follow}
- p := whichWind^.portRect.TopLeft;
- LocalToGlobal(p); {change to global coordinates}
- WITH Data.configWindArray[arrElem],whichWind^.portRect DO BEGIN
- windTopLeft := p;
- width := right - left;
- height := bottom - top;
- END; {WITH}
- SetPort(oldPort); {restore port}
- END; {FillInWInfo}
-
- {------------------------------------------------------------------------------------}
-
- BEGIN {WriteConfigData}
- {at this point, we know the appropriate resource file exists and is open}
- hResConfig := GetResource(ConfResType,ConfResID); {get the CNFG resource}
- IF (hResConfig = NIL) | (HomeResFile(hResConfig) <> whichResFile) THEN BEGIN
- IF hResConfig <> NIL THEN ReleaseResource(hResConfig); {It's not ours}
- hResConfig := NewHandle(sizeOf(myConfig)); {we'll make one}
- AddResource(hResConfig,ConfResType,ConfResID,''); {make a new one}
- END; {IF}
-
- {fill in the record with the appropriate information}
- FillInWInfo(gDebugWindowPtr,DebugWNum,hConfigResType(hResConfig)^^);
- FillInWInfo(FugitWind,FugitWNum,hConfigResType(hResConfig)^^);
- FillInWInfo(InfoWind,InfoWNum,hConfigResType(hResConfig)^^);
- hConfigResType(hResConfig)^^.grayRgnRect := (RgnHandle(ELongPtr(
- GrayRgnLowMemGlobal)^)^^
- .rgnBBox);
- ChangedResource(hResConfig); {we want it changed!} {no reason to
- ReleaseResource this guy}
- END; {WriteConfigData}
-
- {------------------------------------------------------------------------------------}
-
- BEGIN {WriteConfigInfo}
- {$IFC AppleShareFriendly = TRUE}
- writeln('writing config info to file');
- Err := GetVol(NIL,oldVol); {save default volume}
- Err := SetVol(NIL,SysEnv.sysVRefNum); {set to system folder}
-
- {strategy: create a resfile, if we get an error, just skip ahead to the open}
-
- myStrH := GetString(ConfigFNameStrID); {from our application's resource file}
- CreateResFile(myStrH^^); {ignore the error, just check for errors on the open
- call below}
-
- {IF we created the file, we need to set up the Finder Info}
- IF ResError = noErr THEN BEGIN
- {GetFInfo won't move memory, so no need to lock myStrH}
- Err := GetFInfo(myStrH^^,SysEnv.sysVRefNum,myFndrInfo);
- IF Err = noErr THEN BEGIN
- WITH myFndrInfo DO BEGIN
- fdType := ConfResType;
- fdCreator := ConfCreator;
- END; {WITH}
- Err := SetFInfo(myStrH^^,SysEnv.sysVRefNum,myFndrInfo);
- END; {IF}
- END; {IF ResError...}
- ReleaseResource(Handle(myStrH)); {all done with this string}
- configFileRef := OpenConfigFile; {go ahead and try to open it}
-
- {$ENDC}
- {$IFC AppleShareFriendly=TRUE}
- IF configFileRef <> 0 THEN BEGIN {the file exists, write configuration data}
- WriteConfigData(configFileRef); {write the actual data}
- CloseResFile(configFileRef); {and close the resource file}
- Err := FlushVol(NIL,SysEnv.sysVRefNum); {flush the volume the config file's on}
- END {IF configFileRef <> 0}
- ELSE; {do nothing, we just couldn't write it}
- Err := SetVol(NIL,oldVol); {restore default volume}
- {$ELSEC} {Duplicated code below}
- writeln('writing config info to resource');
- WriteConfigData(CurResFile);
- {$ENDC}
- END; {WriteConfigInfo}
-
- {------------------------------------------------------------------------------------}
-
- FUNCTION ReadConfigInfo(VAR wConfig: ConfigResType): BOOLEAN; {reads the info in the
- configuration file}
-
- VAR
- configFileRef : Integer;
- myConf : hConfigResType;
-
- BEGIN {ReadConfigInfo}
- {$IFC AppleShareFriendly=TRUE}
- ReadConfigInfo := FALSE; {start with this as a default}
-
- configFileRef := OpenConfigFile; {try to open it}
- IF configFileRef <> 0 THEN BEGIN {we got the file}
- {$ENDC}
- myConf := hConfigResType(GetResource(ConfResType,ConfResID));
- IF myConf <> NIL THEN BEGIN
- ReadConfigInfo := TRUE; {This is true}
- wConfig := myConf^^;
- {$IFC AppleShareFriendly=TRUE}
- CloseResFile(configFileRef); {all done, close the ResFile}
- {$ENDC}
- END; {IF}
- {$IFC AppleShareFriendly=TRUE}
- END; {IF configFileRef...}
- {$ENDC}
- END; {ReadConfigInfo}
-
- {------------------------------------------------------------------------------------}
-
- PROCEDURE Initialize;
-
- PROCEDURE SetUpWindows; {Gets windows and puts them in the right places}
-
- {
- NOTE: I use a very simplistic method to see if I can use the saved window positions.
- This is just an example, so you shouldn't use this code. All I check is to see if the
- GrayRgn's BBox has changed, and if it has, I assume that the world has changed, so I revert
- to the default window positions. This is to handle the multiple screens on the Macintosh II.
- Real programs, such as the Finder, save window positions in a much more intelligent fashion.
- The next version of Events, will include a better technique for handling this.
- }
-
- TYPE
- WindRSRC = RECORD
- bounds: Rect;
- procID: Integer;
- visible: BOOLEAN;
- Filler: BOOLEAN; {otherwise Pascal will pack Visible
- and goAwayFlag}
- goAwayFlag: BOOLEAN;
- filler2: BOOLEAN;
- refCon: longint;
- wTitle: Str255;
- END;
- pWindRSRC = ^WindRSRC;
- hWindRSRC = ^pWindRSRC;
-
- VAR
- hWIND : hWindRSRC;
- myConfig : ConfigResType;
- r : Rect;
- windTitle : Str255;
-
- BEGIN {SetUpWindows}
-
- {get our two invisible windows}
- FugitWind := GetNewWindow(FugitID,NIL,WindowPtr( - 1));
- InfoWind := GetNewWindow(InfoID,NIL,WindowPtr( - 1));
- hWIND := hWindRSRC(GetResource('WIND',DebugID)); {we'll need this to get the
- title string from}
- {or, if no configuration data is around, we'll get the bounds from this}
-
- IF ReadConfigInfo(myConfig) & EqualRect(myConfig.grayRgnRect,
- (RgnHandle(ELongPtr(GrayRgnLowMemGlobal)
- ^)^^.rgnBBox)) THEN BEGIN {we have a
- saved window configuration}
- WITH myConfig DO BEGIN
- {first, set up FugitWind}
- WITH configWindArray[FugitWNum] DO BEGIN
- MoveWindow(FugitWind,windTopLeft.h,windTopLeft.v,FALSE);
- SizeWindow(FugitWind,width,height,FALSE);
- END;
- {Now, the InfoWind}
- WITH configWindArray[InfoWNum] DO BEGIN
- MoveWindow(InfoWind,windTopLeft.h,windTopLeft.v,FALSE);
- SizeWindow(InfoWind,width,height,FALSE);
- END; {WITH}
- {now, set up the rectangle for the debug window}
-
- WITH configWindArray[DebugWNum] DO
- SetRect(r,windTopLeft.h,windTopLeft.v,windTopLeft.h + width,
- windTopLeft.v + height);
- END; {WITH MyConfig}
- END {IF}
- ELSE BEGIN {we don't have the configuration details...}
- {or the grayRgn's bbox changed, use defaults}
- {set up WritelnWindow stuff}
- r := hWIND^^.bounds;
- r.bottom := ScreenBits.bounds.bottom - 60;
- END;
-
- windTitle := hWIND^^.wTitle; {get the title}
- ReleaseResource(Handle(hWIND)); {all done}
- EvInitWW(r,windTitle); {we assume that no one's mucked with our resources}
-
- UnloadSeg(@WWInit); {unload this segment as well}
-
- ShowWindow(FugitWind); {show our two invisible windows}
- ShowWindow(InfoWind);
- SelectWindow(InfoWind); {bring this window to the front}
- END; {SetUpWindows}
-
- {------------------------------------------------------------------------------------}
-
- PROCEDURE _DataInit;
- EXTERNAL; {so we can unload it}
-
- {------------------------------------------------------------------------------------}
-
- BEGIN {Initialize}
- UnloadSeg(@_DataInit); {unload data initialization code before any allocations}
- MoreMasters; MoreMasters; {get some master pointer blocks}
- MaxApplZone; {grow the heap}
- InitGraf(@thePort); {standard Macintosh inits}
- InitFonts;
- FlushEvents(everyEvent,0);
- InitWindows;
- InitMenus;
- TEInit;
- InitDialogs(NIL);
- InitCursor;
-
- Err := SysEnvirons(1,SysEnv); {first version of SysEnvirons, we don't care about
- the error}
-
- SetUpMenus; {get our menus}
- SetUpWindows; {configure our windows}
- FlushEvents(everyEvent,0);
-
- {initialize variables for drawing routines}
- ThePat := Black; {draw with this to start}
- PatIsBlack := TRUE; {start with a black pattern for drawing}
- SetRect(ArcRect,10,10,90,90);
- Chunk := 0;
-
- ShowMouseMoved := FALSE; {don't show these initially}
- {Is WaitNextEvent implemented?}
- WNEIsImplemented := (SysEnv.machineType >= 0) & {>= 128K ROMs}
- (NGetTrapAddress(WNETrapNum,ToolTrap) <> NGetTrapAddress(UnImplTrapNum,ToolTrap));
- IF NOT WNEIsImplemented THEN {disable showmousemoved menu item}
- DisableItem(MyMenus[OptionM],ShowMouseItem);
-
- {now let's calculate all of our cursor regions}
- SetPort(InfoWind);
- InfoWindRgn := NewRgn; {we'll need this for the WNE cursor stuff}
- AllButInfoWindRgn := NewRgn; {we'll need this for the WNE cursor stuff}
- CalculateWNECursRgns; {calculate the cursor regions}
- WNERgn := NIL; {default to ShowMouseMoved = FALSE}
-
- MouseMovedMessage := $FA; {high byte of event record message for mouse moved
- events}
- PlusCursH := GetCursor(plusCursor);
- IF PlusCursH <> NIL THEN HNoPurge(Handle(PlusCursH));
-
- YieldTime := 0; {don't yield any time (Juggler 1.0B3 and later)}
- WChanged := FALSE; {nobody's changed yet}
- SusPendCount:= 0;
- END; {Initialize}
-
- {------------------------------------------------------------------------------------}
-
- PROCEDURE MainEventLoop;
-
- CONST
- quantum = 2; {run for 2 ticks before yielding}
- cleanUpTime = 300; {clean up once every 5 seconds}
-
- VAR
- hasEvent : BOOLEAN;
- whichWindow : WindowPtr;
- whichPart : Integer;
- theChar : char;
- longStuff : LongStuffType; {for conversions}
- dragRect : Rect;
- cleanUpTicks : longint; {so we know when to call CompactMem}
- timerTicks,ourTime : longint; {this is all for the percentage stuff -- thanks JM}
- runTime,elapsedTime: longint;
- lastTickCount : longint;
- lastPercent : longint;
-
- {------------------------------------------------------------------------------------}
-
- PROCEDURE DrawRotatingDial(VAR currentPat: Pattern);
-
- VAR
- myTicks : longint;
-
- BEGIN {DrawRotatingDial}
- {Now draw the rotating dial}
- SetPort(FugitWind); {set to correct port}
-
- myTicks := TickCount; {synch to VBL the poor man's way}
- REPEAT
- UNTIL TickCount <> myTicks;
-
- FillArc(ArcRect,Chunk * TheAngle,TheAngle,currentPat); {draw a chunk}
- Chunk := Chunk + 1; {go to next chunk}
- IF Chunk >= MaxChunk THEN BEGIN {we're done, flip color, reset Chunk}
- Chunk := 0;
- IF PatIsBlack THEN
- currentPat := white
- ELSE
- currentPat := Black;
- PatIsBlack := NOT (PatIsBlack);
- END; {IF}
- END; {DrawRotatingDial}
-
- {------------------------------------------------------------------------------------}
-
- PROCEDURE DrawPercentage(runTim,eTime: longint; VAR lastPerct: longint);
-
- VAR
- percent : longint;
- drawRect : Rect;
- myStr : Str255;
-
- BEGIN {DrawPercentage}
- {now draw the percentage information}
- SetPort(InfoWind); {in this window}
-
- percent := ((runTim * 100) DIV eTime);
- IF percent >= 100 THEN percent := 99; {just in case}
- IF percent <> lastPerct THEN BEGIN
- SetRect(drawRect,5,60 - 19 {poor man's} ,thePort^.portRect.right,60);
- EraseRect(drawRect);
- MoveTo(5,60);
- NumToString(percent,myStr);
- DrawString(myStr);
- DrawChar('%');
- lastPerct := percent;
- END; {IF}
- END; {DrawPercentage}
-
- {------------------------------------------------------------------------------------}
-
- BEGIN {MainEventLoop}
-
- {first initialize some globals}
- Done := FALSE; {we just started!}
- Suspended := FALSE; {as far as we know, we're not suspended}
-
- WITH ScreenBits.bounds DO
- SetRect(dragRect,4,MenuBarHeight + 4,right - 4,bottom - 4);
-
- {get initial values for the percentage stuff}
- lastTickCount := TickCount;
- ourTime := lastTickCount; {prime our lastTime}
- runTime := 0; {our total time running}
- elapsedTime := 100; {total time, avoid divide by zero}
- lastPercent := 0; {make sure this is drawn}
-
- cleanUpTicks := lastTickCount; {get the ticks so we know when to compact}
-
- REPEAT
-
- DrawRotatingDial(ThePat); {draw a chunk of the dial}
-
- {now calculate the percent of processor time -- stolen from John Meier}
- WHILE (TickCount - ourTime) < quantum DO; {use up rest of quantum}
- timerTicks := TickCount;
- runTime := runTime + timerTicks - ourTime;
- elapsedTime := elapsedTime + timerTicks - lastTickCount;
- lastTickCount := timerTicks;
- IF elapsedTime > 1000 THEN BEGIN
- runTime := 0;
- elapsedTime := 1;
- END;
-
- {see if we should compact the heap to get rid of all the free blocks that}
- {writelnWindow creates -- time to be anal ytical?}
- IF NOT Suspended THEN {only do this if we're in the 4Gnd}
- IF lastTickCount - cleanUpTicks > cleanUpTime THEN BEGIN
- longStuff.long := CompactMem(FreeMem); {coalesce free blocks-- won't
- purge}
- cleanUpTicks := lastTickCount; {reset this guy}
- END; {IF}
-
- {ask for events}
- IF WNEIsImplemented THEN
- hasEvent := WaitNextEvent(everyEvent,MyEvent,YieldTime,WNERgn)
- ELSE BEGIN
- SystemTask; {for drivers}
- hasEvent := GetNextEvent(everyEvent,MyEvent);
- END; {ELSE}
-
- ourTime := TickCount; {ourTime starts after GetNextEvent}
- DrawPercentage(runTime,elapsedTime,lastPercent); {show the current percentage}
-
- IF hasEvent THEN
- CASE MyEvent.what OF {which event?}
-
- mouseDown: BEGIN
- whichPart := FindWindow(MyEvent.where,whichWindow);
- {the events window gets its own mouseDown events, so let's check...}
- IF whichWindow = gDebugWindowPtr THEN BEGIN
- WWMouseDown(whichPart,MyEvent.where,MyEvent.modifiers);
- WChanged := TRUE; {since WW is a "black box" assume that a
- mouse-down means that it's grown or moved}
- writeln('mouseDown: Events window');
- END
- ELSE
- CASE whichPart OF
-
- inDesk:
- writeln('mouseDown: inDesk');
-
- inMenuBar: BEGIN
- writeln('mouseDown: inMenuBar');
- DoCommand(MenuSelect(MyEvent.where),FALSE);
- END; {inMenuBar}
-
- inSysWindow: BEGIN
- SystemClick(MyEvent,whichWindow);
- writeln('mouseDown: inSysWindow');
- END; {inSysWindow}
- inContent: BEGIN
- IF whichWindow <> FrontWindow THEN
- SelectWindow(whichWindow);
- writeln('mouseDown: inContent');
- END; {inContent}
- inDrag: BEGIN
- DragWindow(whichWindow,MyEvent.where,dragRect);
- WChanged := TRUE; {to show the configuration needs
- updating}
- IF whichWindow = InfoWind THEN CalculateWNECursRgns;
- {recalculate the regions if we move InfoWind}
- writeln('mouseDown: inDrag');
- END; {inDrag}
- inGrow:
- writeln('mouseDown: inGrow');
- inGoAway:
- writeln('mouseDown: inGoAway');
-
- END; {CASE}
- END; {mouseDown}
-
- keyDown,autoKey: BEGIN
- IF MyEvent.what = keyDown THEN
- writeln('keyDown')
- ELSE
- writeln('autoKey');
- theChar := CHR(BitAnd(MyEvent.message,charCodeMask)); {get the
- char}
- IF BitAnd(MyEvent.modifiers,cmdKey) <> 0 THEN
- DoCommand(MenuKey(theChar),TRUE) {pass it to the command
- handler}
- ELSE IF WNEIsImplemented THEN BEGIN
- YieldTime := Ord(theChar) - Ord('0'); {so that 0 thru 9 work}
- IF YieldTime < 0 THEN YieldTime := 0; {don't want negatives}
- SetPort(InfoWind);
- InvalRect(InfoWind^.portRect); {generate update event}
- END; {IF}
- END; {keyDown}
-
- updateEvt: BEGIN
- SetPort(WindowPtr(MyEvent.message));
- write('update: ');
- IF WindowPtr(MyEvent.message) = InfoWind THEN
- UpdateWindow(WindowPtr(MyEvent.message),'InfoWind')
- ELSE IF WindowPtr(MyEvent.message) = FugitWind THEN
- UpdateWindow(WindowPtr(MyEvent.message),'FugitWind')
- ELSE IF WindowPtr(MyEvent.message) = gDebugWindowPtr THEN BEGIN
- WWUpdateEvent;
- writeln('Events window');
- END {ELSE = gDebugWindowPtr}
- ELSE
- writeln('Unknown window');
- END; {updateEvt}
-
- diskEvt: BEGIN
- longStuff.long := MyEvent.message;
- IF longStuff.HiWrd < 0 THEN {got a bad mount}
- Err := DIBadMount(MyEvent.where,MyEvent.message);
- {we can't really do anything else here that BadMount couldn't do}
- writeln('Disk insert event');
- END; {diskEvt}
-
- activateEvt: BEGIN
- IF BitAnd(MyEvent.modifiers,activeFlag) <> 0 THEN
- write('activate: ')
- ELSE
- write('deactivate: ');
- IF WindowPtr(MyEvent.message) = FugitWind THEN
- writeln('FugitWind')
- ELSE IF WindowPtr(MyEvent.message) = InfoWind THEN
- writeln('InfoWind')
- ELSE IF WindowPtr(MyEvent.message) = gDebugWindowPtr THEN BEGIN
- writeln('Events window');
- WWActivateEvent(MyEvent.modifiers);
- END {ELSE IF}
- ELSE
- writeln('Unknown window');
- END; {Activate Event}
-
- networkEvt:
- writeln('Network Event'); {Juggler doesn't support these}
-
- driverEvt:
- writeln('Driver Event');
-
- app1Evt:
- writeln('App1Event');
-
- app2Evt:
- writeln('App2Event');
-
- app3Evt:
- writeln('App3Event');
-
- app4Evt: BEGIN {Juggler uses this for SUSPEND/RESUME and mouse-moved
- events}
- longStuff.long := MyEvent.message;
- IF longStuff.HiByte = MouseMovedMessage THEN BEGIN
- {mouse moved event}
- writeln('MouseMoved');
- FlipCursor; {we got a mouse-moved, flip the cursor}
- END {IF}
- ELSE IF Odd(MyEvent.message) THEN BEGIN
- writeln('RESUME');
- Suspended := FALSE;
- SetPort(InfoWind);
- InvalRect(thePort^.portRect); {force update of the info window}
- IF FrontWindow = gDebugWindowPtr then
- WWActivateEvent(1);
-
- END {ELSE IF}
- ELSE BEGIN
- writeln('SUSPEND');
- SusPendCount:= 1;
- Suspended := TRUE;
- {we need to deactivate this window, since we are Juggler smart}
- IF FrontWindow = gDebugWindowPtr THEN WWActivateEvent(0);
- SetPort(InfoWind);
- InvalRect(thePort^.portRect); {force update of the info window}
- END; {ELSE}
- END; {app4Evt}
- END; {event.what case}
- UNTIL Done;
- END; {MainEventLoop}
-
- {------------------------------------------------------------------------------------}
-
- BEGIN {PROGRAM}
- Initialize;
- MainEventLoop;
- DisposeRgn(InfoWindRgn); {we're all done with it}
- DisposeRgn(AllButInfoWindRgn); {we're all done with it}
-
- {here we could check to see if any of our windows have been changed, but, since
- this may be running under Juggler, and someone could go into the Finder and
- delete our configuration file while we are running, we'll just always write
- the configuration data}
-
- {IF WChanged THEN}
- WriteConfigInfo;
-
- writeln;
- writeln('Bye bye');
- END.
-