[comp.sys.mac.programmer] LClikLoop in a DA

fore@athena.cs.uga.edu (Howard Fore) (01/01/91)

sorry to bother you folks with this but...

I'm writing a DA that involves using the list manager in a variety of ways.
However, I am wanting to do some custom stuff and wish to use my own LClikLoop
with LClick. The problem is IM says "no parameters" and and a DA has no
"real" global data. How does one gain access to the "globals" handle (or even
the ListHandle) in the Control record if one's LClikLoop proc is isolated
as such? Is this possible? Have I overlooked something? I've pondered several
hacks, but they don't appear promising or reliable.
I've noticed that there are several toolbox routines that allow the 
installation of custom procs that shouldn't have parameters. Are these to be
avoided in DAs?

Any help would be appreciated.

thanks

-- 


------------------------------------------------------------------------------
Howard Fore   fore@athena.cs.uga.edu    (128.192.4.49)

tim@hoptoad.uucp (Tim Maroney) (01/02/91)

In article <1990Dec31.202330.17197@athena.cs.uga.edu> fore@athena.cs.uga.edu
(Howard Fore) writes:
>I'm writing a DA that involves using the list manager in a variety of ways.
>However, I am wanting to do some custom stuff and wish to use my own LClikLoop
>with LClick. The problem is IM says "no parameters" and and a DA has no
>"real" global data. How does one gain access to the "globals" handle (or even
>the ListHandle) in the Control record if one's LClikLoop proc is isolated
>as such? Is this possible? Have I overlooked something? I've pondered several
>hacks, but they don't appear promising or reliable.

You have to cheat.  There are a few standard ways to do this.  The
most common is to write a little assembly language that uses PC-relative
addressing to manage a little block of storage (DC.L) in code space.

Another way, probably worse, is to rely on the undocumented fact that
the List Manager passes the list handle to the click loop routine in
register a3 or a4 -- I don't recall which.  Of course, this could all
change in the future.

Yet another way is to write what some people erroneously refer to as
self-modifying code.  Your click loop routine pointer points to a piece
of memory that contains the opcodes for something like

	move.l	#0,-(sp)
	jsr	realclikloop
	addq.l	#4,sp
	rts

And then, before ever calling this, write the list handle into the space
occupied by the constant zero (which will be two bytes into the code).
Then your realclikloop routine will get a parameter consisting of the
list handle.

Parameter-less procedure pointers are a major screwup in the OS.

(One more thing -- notice that the list handle has a field for the use
of the caller, much like a refcon field in a window; you can store all
your data in a handle there.)
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"The pride of the peacock is the glory of God.
 The lust of the goat is the bounty of God.
 The wrath of the lion is the wisdom of God.
 The nakedness of woman is the work of God."
    - Blake, "The Marriage of Heaven and Hell"

Lawson.English@p88.f15.n300.z1.fidonet.org (Lawson English) (01/07/91)

Tim Maroney writes in a message to All

TM> You have to cheat. There are a few standard ways to do this. 
TM> The most common is to write a little assembly language that uses 
TM> PC-relative addressing to manage a little block of storage (DC.L) 
TM> in code space. 
TM> Another way, probably worse, is to rely on the undocumented fact 
TM> that the List Manager passes the list handle to the click loop 
TM> routine in register a3 or a4 -- I don't recall which. Of course, 
TM> this could all change in the future.

Another way (and better IMHO) is to reserve enough heap space for your DA 
globals,
and put them into a record/struct whose handle is stored in dCtlStorage. Then,
 
when you need 'em, you can simply lock dCtlStorage and typecast it to 
myRecordStructHandle.

Lawson
 

 

--  
Uucp: ...{gatech,ames,rutgers}!ncar!asuvax!stjhmc!300!15.88!Lawson.English
Internet: Lawson.English@p88.f15.n300.z1.fidonet.org

tim@hoptoad.uucp (Tim Maroney) (01/07/91)

Tim Maroney writes in a message to All
>TM> You have to cheat. There are a few standard ways to do this. 
>TM> The most common is to write a little assembly language that uses 
>TM> PC-relative addressing to manage a little block of storage (DC.L) 
>TM> in code space. 
>TM> Another way, probably worse, is to rely on the undocumented fact 
>TM> that the List Manager passes the list handle to the click loop 
>TM> routine in register a3 or a4 -- I don't recall which. Of course, 
>TM> this could all change in the future.
>
n article <34232.27875328@stjhmc.fidonet.org>
Lawson.English@p88.f15.n300.z1.fidonet.org (Lawson English) writes:
>Another way (and better IMHO) is to reserve enough heap space for your DA 
>globals,
>and put them into a record/struct whose handle is stored in dCtlStorage. Then,
> 
>when you need 'em, you can simply lock dCtlStorage and typecast it to 
>myRecordStructHandle.

You're proving what I said about Fidonet, Lawson.  How are you supposed
to get to the dCtlStorage with no globals and no arguments?  You would
have to search the unit table and compare driver names to yours.  Pretty
inefficient, no?
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"Americans will buy anything, as long as it doesn't cross the thin line
 between cute and demonic." -- Ian Shoales

Lawson.English@p88.f15.n300.z1.fidonet.org (Lawson English) (01/09/91)

Tim Maroney writes in a message to All

TM> You're proving what I said about Fidonet, Lawson. How are you 
TM> supposed to get to the dCtlStorage with no globals and no arguments? 
TM> You would have to search the unit table and compare driver names 
TM> to yours. Pretty inefficient, no?

You are correct. I misread the original question slightly.

Lawson
 

--  
Uucp: ...{gatech,ames,rutgers}!ncar!asuvax!stjhmc!300!15.88!Lawson.English
Internet: Lawson.English@p88.f15.n300.z1.fidonet.org

kinsey@athena.cs.uga.edu (Kevin Kinsey) (01/11/91)

In article <34586.278C73D9@stjhmc.fidonet.org> Lawson.English@p88.f15.n300.z1.fidonet.org (Lawson English) writes:
>Tim Maroney writes in a message to All
>
>TM> You're proving what I said about Fidonet, Lawson. How are you 
>TM> supposed to get to the dCtlStorage with no globals and no arguments? 
>TM> You would have to search the unit table and compare driver names 
>TM> to yours. Pretty inefficient, no?
>
>You are correct. I misread the original question slightly.
>
>Lawson
> 

Okay, so someone misunderstood.                       

Has anyone figured out a workable solution other than adding a small
bit of PC relative assembly ?!?!

kevin

===========================================================================
Kevin Kinsey	  	  			kinsey@athena.cs.uga.edu
UCNS			  			st19@uga.cc.uga.edu
University of Georgia
Athens, GA

tim@hoptoad.uucp (Tim Maroney) (01/22/91)

Kevin Kinsey writes in a message to All
>KK> Okay, so someone misunderstood. Has anyone figured out a workable 
>KK> solution other than adding a small bit of PC relative assembly 
>KK> ?!?

In article <35049.2793F96E@stjhmc.fidonet.org>
Lawson.English@p88.f15.n300.z1.fidonet.org (Lawson English) writes:
>This is off the top of my head, but perhaps a resouce containing the address
>you need might be put in the heap, to be set by your DA, and examined by the
>actionProc. As there should be only one resource of type "myAd", you might be
>able to get away with it...

That would work, provided the resource was owned by your DA, except for
one thing -- to get the resource, you need to know the id, which might
have been changed by Font/DA Mover.  Once again you have to walk the
unit table (this time, to find your id), and if you're going to do
that, you might as well just get to the dCtlStorage field directly.

All the good solutions (i.e., those that are reasonably efficient)
depend on some assembly language or machine language.  But big deal!
What's so hard about putting a few bytes of hex into a pointer which
you use as a function pointer, as I described earlier?
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"Everything that gives us pleasure gives us pain to measure it by."
    -- The Residents, GOD IN THREE PERSONS

Lawson.English@p88.f15.n300.z1.fidonet.org (Lawson English) (01/27/91)

TO CONTINUE THE ARGUEMENT...

Kevin Kinsey writes in a message to All
>KK> Okay, so someone misunderstood. Has anyone figured out a workable 
>KK> solution other than adding a small bit of PC relative assembly 
>KK> ?!?
Lawson.English@p88.f15.n300.z1.fidonet.org (Lawson English) writes:
>This is off the top of my head, but perhaps a resouce containing the address
>you need might be put in the heap, to be set by your DA, and examined by the
>actionProc. As there should be only one resource of type "myAd", you might
be
>able to get away with it...

Tim Maroney writes in a message to All

TM> That would work, provided the resource was owned by your DA, 
TM> except for one thing -- to get the resource, you need to know 
TM> the id, which might have been changed by Font/DA Mover.


So what is wrong with "GetNamedResource"? If you create a unique Resource Name,
as well as a unique TYPE, why wouldn't that work? 


Lawson
 

--  
Uucp: ...{gatech,ames,rutgers}!ncar!asuvax!stjhmc!300!15.88!Lawson.English
Internet: Lawson.English@p88.f15.n300.z1.fidonet.org