TweetFollow Us on Twitter

Cursor Wrap
Volume Number:5
Issue Number:0
Column Tag:Pascal Procedures

Related Info: Control Panel OS Utilities

Writing INITs in Pascal

By Steve Kiene, Lincoln, NE

Why Inits: Trap Patching, etc

INITs are pretty hot items these days. I have at least six in my System Folder and I know people that have fifteen or more. INITs do anything from making it easier to move through SFGetFiles (SFScrollINIT by Andy Hertzfeld) to creating large virtual desktops (SteppingOUT II). INITs are used to customize the Macintosh. They are very simple to install and remove (dragging them into or out of the System Folder).

The majority of INITs trap patches. Patch trapping is simply the rewriting of the Macintosh’s internal routines or the modification of these routines for special situations. This is done by using the traps GetTrapAddress,SetTrapAddress, NSetTrapAddress, and NGetTrapAddress. Usually the programmer calls GetTrapAddress and saves the address for later use; the programmer then puts this address somewhere,usually in his/her code so that his/her code can check for the special situation, do whatever-taken that it is the special situation, and then call the original trap address. All trap patches should call the original trap address; this allows traps to be patched more than one time and is the best bet for compatibility insurance.

I would guess that 90% of all INITs are written in assembly. I’m sure they probably say that INITs are much easier to write in assembly. Well, it’s probably true, if you know assembly, but, if you don’t know assembly, I would say that it isn’t all that easy. This article, since it is in the Pascal section, demonstrates how to write an INIT in Pascal, includes full source to an INIT that allows the cursor to wrap around the screen, and gives a couple of hints on writing INITs in general.

Having the INIT install our patch.

INITs must load their code into the system heap so that the code will stay around as application’s are launched (the application heap is flushed every launch or return to the Finder). The INIT part of the code should put the trap patch or whatever code into the system heap. In CursorWrap, the included INIT, we create a pointer in the system heap that is four bytes greater than the size of our VBL task code; we then BlockMove the code into the pointer starting at the location of the pointer plus four. We store the pointer to our VBL task in the four bytes before our code so that we have easy access to it. The code is written in MPW Pascal, but should be easy to convert to any other development system.

{1}

Unit CursorWrap;
Interface
Uses
 {$LOAD MAC.Dump}
 MemTypes,QuickDraw,OSIntf,Toolintf,PackIntf,Script;
Procedure SetUpVBL;
Procedure Wrap;

Implementation
Procedure SetUpVBL;
var
 theVBL : VBLTask;
 myQElem: QElemPtr;
 myErr  : OSErr;
 SaveZone : THz;
 SizeNeeded : Longint;
 PatchPtr : Ptr;
 theCode: Handle;
 thePtr : ^LongInt;
 dummyErr : OSErr;
Begin
 { * Get handle to our code *}
 theCode:=Get1Resource(‘INIT’,1);
 { * Use the system’s Heap * }
 SaveZone:=GetZone;
 SetZone(SystemZone);
 { * Get size of our patch code and our QElem ptr * }
 SizeNeeded:=SizeResource(theCode)-(LongInt(@SetUpVBL)-LongInt(theCode^))+sizeof(QElem);
 ResrvMem(SizeNeeded);
 If MemError<>NoErr then
 begin
 { * If not enough room in system heap then get out * }
 SysBeep(1);
 SetZone(SaveZone);
 exit(SetUpVBL);
 end;
 { * Get new ptr for our code * }
 PatchPtr:=NewPtr(SizeNeeded+4);
 { * blockmove our code in * }
 BlockMove(@Wrap,Pointer(Ord(PatchPtr)+4),SizeNeeded);
 { * get new ptr for our VBL task * }
 myQElem:=QElemPtr(NewPtr(sizeof(QElem)));
 { * restore zone * }
 SetZone(SaveZone);
 { * put our vbl task ptr’s address into the ptr where our patch code 
will be * }
 thePtr:=Pointer(PatchPtr);
 thePtr^:=LongInt(myQElem);
 { * set up VBL and install * }
 with theVBL do
 begin
 qType:=Ord(vType);
 vblAddr:=Pointer(Ord(PatchPtr)+4);
 vblCount:=6;
 vblPhase:=0;
 end;
 myQElem^.vblQElem:=theVBL;
 dummyErr:=VInstall(myQElem);
End;
{------------------------------------------------------}
Procedure Wrap;
{**
This code allows the cursor to seemly wrap around the screen when the 
<Option> key is held down.  It checks the low level interupt mouse location 
(mTemp) and if it is on one edge of the screen it moves it to the the 
other edge.  It puts the new cursor cooridinate into mTemp and then puts 
$FF into cursorNew--this tells the cursor routines that the cursor has 
moved 
**}
const
 CurrentA5= $904;
var
 myQElem: QElemPtr;
 thePtr : ^LongInt;
 CursorCoordPtr  : ^Point;
 ChangedPtr : ^Byte;
 changed: Boolean;
 theMap : KeyMap;
 currGDevice: GDHandle;
 mouseRect: Rect;
 myRectPtr: ^Rect;
 myPtr,myPtr2    : ^longint;
 myRect : Rect;
Begin
 { * Get the keymap and check if option down; if is not then do not allow 
wrap * }
 GetKeys(theMap);
 If theMap[58] then
 Begin
 { * set up ptr to low memory global of cursor location * }
 CursorCoordPtr:=Pointer($828);
 changed:=false;
 { * get rectangle of screen * }
 currGDevice:=GetGDevice;
 If currGDevice<>Nil then
 mouseRect:=currGDevice^^.gdRect
 else
 begin
 { * Use currentA5 to get offset to screenBits.bounds * }
 myPtr:=pointer(CurrentA5);
 myPtr2:=pointer(myPtr^);
 myRectPtr:=Pointer(myPtr2^-116);
 mouseRect:=myRectPtr^;
 end;
 InsetRect(mouseRect,1,1);
 { * check cursor location and change it if wrapping * }
 With CursorCoordPtr^,mouseRect do
 Begin
 if v<=top then
 Begin
 v:=bottom-1;
 changed:=true;
 End
 else if v>=bottom then
 Begin
 v:=top+1;
 changed:=true;
 End;
 if h<=left then
 Begin
 h:=right-1;
 changed:=true;
 End
 else if h>=right then
 Begin
 h:=left+1;
 changed:=true;
 End;
 End;
 { * if we changed the cursor location then set the low memory global 
cursorNew * }
 If changed then
 Begin
 changedPtr:=Pointer($8CE);
 { * this tells the cursor drawing routines that the cursor is moved 
* }
 changedPtr^:=$FF;
 End;
 End;
 { * get ptr to VBL taks from where we originally put it * }
 thePtr:=Pointer(Ord(@Wrap)-4);
 { * reset the vblcount so that we are executed again * }
 myQElem:=QElemPtr(thePtr^);
 myQElem^.vblQElem.vblCount:=6;
End;
End.

Another Way

There is another way to store variables. In our example INIT this would be the VBL pointer address. This way involves using a header file that is written in assembler. The header file does nothing but branch over instructions that take up space. The header would look something like the following in MPW assembly:

Header  MAIN EXPORT

Header1
 BRA.S  @1
 DC.L 0
 DC.L 0
 DC.L 0
@1
 END

This header would leave room for twelve bytes, three handles, or whatever. To use this you would have to link the Header.a.o in first and reference it in you pascal code. A little help:

{3}

Procedure Header; EXTERNAL;{must be after Implementation }
myPtr:=Ptr(Ord(@Header)+2); { myPtr points to the first byte of storage 
}

The above statement returns a pointer to the address of the header plus two bytes, so that we skip over the branch statement.

You would use this type of code when you are writing a WDEF, CDEF, etc. and you want to have some type of communication between your patches and your custom definition. We used this type of code when we wrote Tear-Off Menus and wanted our custom WDEF and MDEF to be able to access globals that our Menu and Window Manager traps used.

Added tips for coping with problems.

When writing INITs that are a little heavier than a ‘one trap patch’ INIT or a simple VBL installation, then you are most likely going to run into problems with certain programs. Maybe it will be because the guys at Microsoft didn’t quite follow all of the rules or perhaps it’s some other reason. Regardless the problem, the answer is to not install when you know you are not compatible. The easiest way to do this is to try and load the resource type of the creator type (ie. MSWD for Microsoft Word) when the application is launched.

{4}

theType:=Get1Resource(‘MSWD’,0);
If theType<>Nil then { the application exists }

Since some users can and do rename their applications, one can not just check for application names. Creator types should be unique (if they are registered with Apple) and no problems should be encountered this way.

Good luck with your INITs.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Latest Forum Discussions

See All

Dispatch is bringing its superhero shena...
If you were anywhere online last year, then you would have no doubt heard of Dispatch, and been flooded with videos of it. With its star-studded cast and unrelenting humour, it fast became a hit, racking up over four million downloads. And it is a... | Read more »
5 reasons to sink your teeth into VAMPIR...
On October 28, Netmarble will globally launch VAMPIR, its latest and most macabre MMORPG, plunging players into a Gothic world of vampires, sorcerers and cursed creatures of the night. Built around blood, fear and large scale battles, the MMORPG... | Read more »
Gundam Blitz Order opens registration fo...
It would appear that video game developers are delving into my childhood and making idle games from my favourite TV shows. First, Bandai completely whiffed with Digimon Up, perhaps the single biggest miss of a beloved franchise in recent memory. Now... | Read more »
The Traitors Interactive Game lets you l...
With the second season of The Celebrity Traitors in full swing, the world is once more enthralled by just how good a liar our heroes are. I don’t watch it, but I hope James Blunt wins. The premise does intrigue me, however, and thanks to Fusebox... | Read more »
Dissidia Duellum Final Fantasy brings in...
For all his successful manipulations and successes through Final Fantasy 9, I never really liked Kuja. And it's not like I dislike him; more I nothing him. But that's just me; the vast majority of the fandom adore him, and they are in luck, for Kuja... | Read more »
Combo Quest (Games)
Combo Quest 1.0 Device: iOS Universal Category: Games Price: $.99, Version: 1.0 (iTunes) Description: Combo Quest is an epic, time tap role-playing adventure. In this unique masterpiece, you are a knight on a heroic quest to retrieve... | Read more »
Hero Emblems (Games)
Hero Emblems 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: ** 25% OFF for a limited time to celebrate the release ** ** Note for iPhone 6 user: If it doesn't run fullscreen on your device... | Read more »
Puzzle Blitz (Games)
Puzzle Blitz 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Puzzle Blitz is a frantic puzzle solving race against the clock! Solve as many puzzles as you can, before time runs out! You have... | Read more »
Sky Patrol (Games)
Sky Patrol 1.0.1 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0.1 (iTunes) Description: 'Strategic Twist On The Classic Shooter Genre' - Indie Game Mag... | Read more »
The Princess Bride - The Official Game...
The Princess Bride - The Official Game 1.1 Device: iOS Universal Category: Games Price: $3.99, Version: 1.1 (iTunes) Description: An epic game based on the beloved classic movie? Inconceivable! Play the world of The Princess Bride... | Read more »

Price Scanner via MacPrices.net

B&H Slashes $400 Off 14″ M5 Pro MacBook P...
B&H has launched a substantial new discount on Apple’s 14-inch M5 Pro MacBook Pro, taking $400 off the Space Black configuration with 24GB RAM and a 1TB SSD. Regularly priced at $2499, the 14-... Read more
Take $50 off iPad at Amazon, prices start at...
Amazon again has 11th-generation A16 WiFi iPads in stock on sale for $50 off MSRP, starting at $399. Shipping is free: – 11″ 11th-generation 128GB WiFi iPads: $399 $50 off MSRP – 11″ 11th-generation... Read more
Amazon Lowers 13″ M5 MacBook Air to $1149, No...
Amazon has increased its discounts on Apple’s 13-inch M5 MacBook Air, dropping the standard 16GB/512GB configuration to just $1149. Apple sells this configuration for $1299, so Amazon’s latest price... Read more
Amazon and B&H Slash Mac mini Prices, M6...
Amazon and B&H are offering new discounts on Apple’s M6 and M5 Pro Mac minis, with savings reaching $149.01 and prices starting at just $779. Configuration Apple MSRP Retailer Sale Price Savings... Read more
Amazon Takes Up to $150 Off 15″ M5 MacBook Ai...
Amazon has launched new discounts on Apple’s 15-inch M5 MacBook Airs, with savings of up to $150 and prices starting at just $1399. Configuration Apple MSRP Amazon Price Savings 15″ M5 16GB/512GB $... Read more
Amazon Takes Up to $150 Off 13″ M5 MacBook Ai...
Amazon has launched a new round of discounts on Apple’s 13-inch M5 MacBook Airs, with savings of up to $150 and prices starting at just $1199. Configuration Apple MSRP Amazon Price Savings 13″ M5... Read more
Verizon Launches iPhone Duo Pre-Orders With N...
Verizon has opened pre-orders for Apple’s new iPhone Duo, the company’s first foldable iPhone, with prices starting at $1999.99 and a new no-trade-in promotion available through its Simplicity Plan.... Read more
Amazon Drops 14″ M5 Max MacBook Pro to $3299,...
Amazon has dropped the price of Apple’s 14-inch M5 Max MacBook Pro with 36GB RAM and a 2TB SSD to $3299, saving a substantial $800 off Apple’s $4099 MSRP. This is one of the strongest discounts we’ve... Read more
Amazon Drops 14″ M5 Pro MacBook Pro with 2TB...
Amazon has dropped the price of Apple’s 14-inch M5 Pro MacBook Pro with 24GB RAM and a 2TB SSD to just $2399, saving a substantial $600 off Apple’s $2999 MSRP. This is one of the best discounts we’ve... Read more
B&H Takes Up to $220 Off New M5 Max Mac S...
B&H has launched new discounts on Apple’s M5 Max Mac Studio, with savings of up to $220 and prices starting at just $2299. Configuration Regular Price B&H Price Savings M5 Max 18-Core CPU/32-... Read more

Jobs Board

All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.