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

Top Mobile Game Discounts
Every day, we pick out a curated list of the best mobile discounts on the App Store and post them here. This list won't be comprehensive, but it every game on it is recommended. Feel free to check out the coverage we did on them in the links... | Read more »
Price of Glory unleashes its 1.4 Alpha u...
As much as we all probably dislike Maths as a subject, we do have to hand it to geometry for giving us the good old Hexgrid, home of some of the best strategy games. One such example, Price of Glory, has dropped its 1.4 Alpha update, stocked full... | Read more »
The SLC 2025 kicks off this month to cro...
Ever since the Solo Leveling: Arise Championship 2025 was announced, I have been looking forward to it. The promotional clip they released a month or two back showed crowds going absolutely nuts for the previous competitions, so imagine the... | Read more »
Dive into some early Magicpunk fun as Cr...
Excellent news for fans of steampunk and magic; the Precursor Test for Magicpunk MMORPG Crystal of Atlan opens today. This rather fancy way of saying beta test will remain open until March 5th and is available for PC - boo - and Android devices -... | Read more »
Prepare to get your mind melted as Evang...
If you are a fan of sci-fi shooters and incredibly weird, mind-bending anime series, then you are in for a treat, as Goddess of Victory: Nikke is gearing up for its second collaboration with Evangelion. We were also treated to an upcoming... | Read more »
Square Enix gives with one hand and slap...
We have something of a mixed bag coming over from Square Enix HQ today. Two of their mobile games are revelling in life with new events keeping them alive, whilst another has been thrown onto the ever-growing discard pile Square is building. I... | Read more »
Let the world burn as you have some fest...
It is time to leave the world burning once again as you take a much-needed break from that whole “hero” lark and enjoy some celebrations in Genshin Impact. Version 5.4, Moonlight Amidst Dreams, will see you in Inazuma to attend the Mikawa Flower... | Read more »
Full Moon Over the Abyssal Sea lands on...
Aether Gazer has announced its latest major update, and it is one of the loveliest event names I have ever heard. Full Moon Over the Abyssal Sea is an amazing name, and it comes loaded with two side stories, a new S-grade Modifier, and some fancy... | Read more »
Open your own eatery for all the forest...
Very important question; when you read the title Zoo Restaurant, do you also immediately think of running a restaurant in which you cook Zoo animals as the course? I will just assume yes. Anyway, come June 23rd we will all be able to start up our... | Read more »
Crystal of Atlan opens registration for...
Nuverse was prominently featured in the last month for all the wrong reasons with the USA TikTok debacle, but now it is putting all that behind it and preparing for the Crystal of Atlan beta test. Taking place between February 18th and March 5th,... | Read more »

Price Scanner via MacPrices.net

AT&T is offering a 65% discount on the ne...
AT&T is offering the new iPhone 16e for up to 65% off their monthly finance fee with 36-months of service. No trade-in is required. Discount is applied via monthly bill credits over the 36 month... Read more
Use this code to get a free iPhone 13 at Visi...
For a limited time, use code SWEETDEAL to get a free 128GB iPhone 13 Visible, Verizon’s low-cost wireless cell service, Visible. Deal is valid when you purchase the Visible+ annual plan. Free... Read more
M4 Mac minis on sale for $50-$80 off MSRP at...
B&H Photo has M4 Mac minis in stock and on sale right now for $50 to $80 off Apple’s MSRP, each including free 1-2 day shipping to most US addresses: – M4 Mac mini (16GB/256GB): $549, $50 off... Read more
Buy an iPhone 16 at Boost Mobile and get one...
Boost Mobile, an MVNO using AT&T and T-Mobile’s networks, is offering one year of free Unlimited service with the purchase of any iPhone 16. Purchase the iPhone at standard MSRP, and then choose... Read more
Get an iPhone 15 for only $299 at Boost Mobil...
Boost Mobile, an MVNO using AT&T and T-Mobile’s networks, is offering the 128GB iPhone 15 for $299.99 including service with their Unlimited Premium plan (50GB of premium data, $60/month), or $20... Read more
Unreal Mobile is offering $100 off any new iP...
Unreal Mobile, an MVNO using AT&T and T-Mobile’s networks, is offering a $100 discount on any new iPhone with service. This includes new iPhone 16 models as well as iPhone 15, 14, 13, and SE... Read more
Apple drops prices on clearance iPhone 14 mod...
With today’s introduction of the new iPhone 16e, Apple has discontinued the iPhone 14, 14 Pro, and SE. In response, Apple has dropped prices on unlocked, Certified Refurbished, iPhone 14 models to a... Read more
B&H has 16-inch M4 Max MacBook Pros on sa...
B&H Photo is offering a $360-$410 discount on new 16-inch MacBook Pros with M4 Max CPUs right now. B&H offers free 1-2 day shipping to most US addresses: – 16″ M4 Max MacBook Pro (36GB/1TB/... Read more
Amazon is offering a $100 discount on the M4...
Amazon has the M4 Pro Mac mini discounted $100 off MSRP right now. Shipping is free. Their price is the lowest currently available for this popular mini: – Mac mini M4 Pro (24GB/512GB): $1299, $100... Read more
B&H continues to offer $150-$220 discount...
B&H Photo has 14-inch M4 MacBook Pros on sale for $150-$220 off MSRP. B&H offers free 1-2 day shipping to most US addresses: – 14″ M4 MacBook Pro (16GB/512GB): $1449, $150 off MSRP – 14″ M4... Read more

Jobs Board

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