[comp.sys.mac.programmer] Have you had problems with SetClikLoop?

mahboud@kinetics.com (Mahboud Zabetian) (12/27/89)

Hi.  Anybody out there ever try calling SetClikLoop twice consecutively for
different TEHandles?  I am doing so and it seems that the second call also
changes the value of the clikLoop field of the first TE!  Sound strange?

This is what I do:

		SetClikLoop(OneClikLoop, globalFirstTE);
		DebugNum(OneClikLoop);
		DebugNum(TwoClikLoop);
		DebugNum((*globalFirstTE)->clikLoop);
		DebugNum((*globalSecondTE)->clikLoop);
		SetClikLoop(TwoClikLoop, globalSecondTE);
		DebugNum((*globalFirstTE)->clikLoop);
		DebugNum((*globalSecondTE)->clikLoop);
		(*globalFirstTE)->clikLoop = (ProcPtr) OneClikLoop;
		DebugNum((*globalFirstTE)->clikLoop);
		DebugNum((*globalSecondTE)->clikLoop);

When I run this, the first four DebugNums return:
		
		0x0020CF48			(in my heap)
		0x0020CF58			(in my heap)
		0x000CB16C
		0x80011238
the second two DebugNums return:

		0x000CB16C
		0x000CB16C
and the third two DebugNums return:

		0x0020CF48
		0x000CB16C

When I look at the instructions at 0xCB16C, it seems they move a value from
$14(A5) into A0 and then JSR to that location.  The code, as it appears
above(without the debugnums) works the way I want it, but if I remove the
line:
		 (*globalFirstTE)->clikLoop = (ProcPtr) OneClikLoop;
Then the click loop executed for both TE's is the second ones, and the
program does not work right.

Anybody know what *exactly* is going on?  Should I just not use SetClikLoop()?

Thanx,			-mahboud
Standard Disclaimer:  Don't mind me, I'm just babbling.
------------------------------------------------------------------------------
     Mahboud Zabetian	 (415) 975-4511		mahboud@kinetics.com
  Kinetics/Excelan/Novell
 1340 Treat Blvd, Suite 500		...!ucbvax!mtxinu!kinetics!mahboud
   Walnut Creek, CA 94596

dan@lclark.UUCP (Dan Revel) (12/28/89)

In article <921@excelan.COM> mahboud@kinetics.com (Mahboud Zabetian) writes:
>
>Anybody out there ever try calling SetClikLoop twice consecutively for
>different TEHandles?

>Anybody know what *exactly* is going on?  Should I just not use SetClikLoop()?

Well, I can't say that I know what is going on, I haven't taken the time to
trace the Toolbox routine SetClikLoop, but I have exeperienced the same
effect (e.g. SetClikLoop changes the clikLoop's for all my existing
TERecord's).  I worked around this by setting the clikLoop variables
'by hand'.

Dan
-- 
dan@lclark
tektronix!reed!lclark!dan			Dylsexics untie! (-|

6600pete@hub.UUCP (12/29/89)

From article <921@excelan.COM>, by mahboud@kinetics.com (Mahboud Zabetian):
> Hi.  Anybody out there ever try calling SetClikLoop twice consecutively for
> different TEHandles?  I am doing so and it seems that the second call also
> changes the value of the clikLoop field of the first TE!  Sound strange?

Yes and no.

Yes, it's strange that it happens. Dunno why they chose to do it this way.

No, it's not strange in that I've seen it before.

My own situation was that a TE application I was writing set a ClikLoop, but
a TE DA also wanted to do it. Under a certain set of circumstances, the DA
would try to call its clikLoop and die because by that time its clikLoop
pointed into outer space.

My solution was to SetClikLoop every time any of my TE windows became active.
I also had to do some mucking with an (undocumented?) application global.
I got this info from Michael Kahl, who apparently wrote a substantial portion
of TE (if I read him correctly). Here's a code fragment in Pascal:


		[ PROCEDURE Activate ( ... ); ]
		[ VAR TEMagic : LONGINT; TEMagicPtr : ^LONGINT; ]

		FUNCTION A5: longint;
			INLINE
				$2E8D;

		[ BEGIN... ]

			TEMagicPtr := pointer(A5 + 20);
			TEMagic := TEMagicPtr^;
			SetClikLoop(@myClikLoop, TEHandle(WindowPeek(whichWindow)^.refCon));
			TEClick(theEvent.where, BitAnd(theEvent.modifiers, shiftKey) <> 0,
						TEHandle(WindowPeek(whichWindow)^.refCon));
			TEMagicPtr^ := TEMagic;

		[ ...END; ]

---

I wager this would be a lot more elegant, not to mention easier, in C.
------------------------------------------------------------------------------
Pete Gontier   | InterNet: 6600pete@ucsbuxa.ucsb.edu, BitNet: 6600pete@ucsbuxa
Editor, Macker | Online Macintosh Programming Journal; mail for subscription
Hire this kid  | Mac, DOS, C, Pascal, asm, excellent communication skills

siegel@endor.harvard.edu (Rich Siegel) (12/29/89)

In article <3429@hub.UUCP> 6600pete@hub.UUCP writes:
>From article <921@excelan.COM>, by mahboud@kinetics.com (Mahboud Zabetian):
>> Hi.  Anybody out there ever try calling SetClikLoop twice consecutively for
>> different TEHandles?  I am doing so and it seems that the second call also
>> changes the value of the clikLoop field of the first TE!  Sound strange?
>
	SetClikLoop saves away the old clickLoop in a place relative to
A5, so that it can restore it. When and why, I don't know. Because TE
doesn't maintain a stack of saved clikLoops, it will smash old ones,
as you're finding out.

	The simplest workaround is to not use SetClickLoop but instead
to just store the clickLoop field directly. I don't know what the implications
are, if any, so maybe someone from Apple who *knows* TE can shed some light.

>I got this info from Michael Kahl, who apparently wrote a substantial portion
>of TE (if I read him correctly). Here's a code fragment in Pascal:

	I don't know if Mike Kahl would be insulted or not to be associated
with TE in this fashion. ;-) For the record, he wrote THINK C, not TE.

R.



~~~~~~~~~~~~~~~
 Rich Siegel
 Staff Software Developer
 Symantec Corporation, Language Products Group
 Internet: siegel@endor.harvard.edu
 UUCP: ..harvard!endor!siegel

"When someone who makes four hundred and fifty dollars an hour wants to
tell you something for free, it's a good idea to listen."

~~~~~~~~~~~~~~~

olson@bootsie.UUCP (Eric Olson) (12/30/89)

In article <3509@husc6.harvard.edu> siegel@endor.UUCP (Rich Siegel) writes:
>>From article <921@excelan.COM>, by mahboud@kinetics.com (Mahboud Zabetian):
>>> Hi.  Anybody out there ever try calling SetClikLoop twice consecutively for
>>> different TEHandles?  I am doing so and it seems that the second call also
>>> changes the value of the clikLoop field of the first TE!  Sound strange?

>	SetClikLoop saves away the old clickLoop in a place relative to
>A5, so that it can restore it. When and why, I don't know. Because TE
>doesn't maintain a stack of saved clikLoops, it will smash old ones,
>as you're finding out.
>

When I bumped into this problem, I thought it was a misfeature of Think C.
It seemed to me that the Think C routine for SetClikLoop would always set the
clikLoop field in the TERec to a Think C glue routine, after saving the
actual (pascal) function pointer away in a global.  The glue routine then
translates registers to pascal stack and calls the routine you specified.

Since only one global existed and all TERecs got a pointer to the glue routine,
only the last installed glue routine would ever get executed.

Is this _not_ the case?!?!?  I was pretty sure...

-Eric

P.S.  Of course, the workaround is to set the field directly and use one's
own glue routine, one per ClikLoop function, as amply described by others
who responded.

-- 
Eric K. Olson            olson@endor.harvard.edu          harvard!endor!olson

keith@Apple.COM (Keith Rollin) (01/01/90)

In article <4@bootsie.UUCP> olson@bootsie.UUCP (Eric Olson) writes:
>In article <3509@husc6.harvard.edu> siegel@endor.UUCP (Rich Siegel) writes:
>>>From article <921@excelan.COM>, by mahboud@kinetics.com (Mahboud Zabetian):
>>>> Hi.  Anybody out there ever try calling SetClikLoop twice consecutively for
>>>> different TEHandles?  I am doing so and it seems that the second call also
>>>> changes the value of the clikLoop field of the first TE!  Sound strange?
>
>>	SetClikLoop saves away the old clickLoop in a place relative to
>>A5, so that it can restore it. When and why, I don't know. Because TE
>>doesn't maintain a stack of saved clikLoops, it will smash old ones,
>>as you're finding out.
>>
>
>When I bumped into this problem, I thought it was a misfeature of Think C.
>It seemed to me that the Think C routine for SetClikLoop would always set the
>clikLoop field in the TERec to a Think C glue routine, after saving the
>actual (pascal) function pointer away in a global.  The glue routine then
>translates registers to pascal stack and calls the routine you specified.
>
>Since only one global existed and all TERecs got a pointer to the glue routine,
>only the last installed glue routine would ever get executed.
>
>Is this _not_ the case?!?!?  I was pretty sure...


Just got back from vacation, and caught up to the bottom of this thread. Yes,
Eric, you are correct. SetClikLoop is a glue routine that actually saves off
the pointer you pass to it in the Application parameters section, and then
points to one of its own routines. This routine is used to translate from the
register based routine TE uses to the stack based convention documented in
Inside Mac. And, yes, this seems like a pretty bad design decision, but it's
what we're stuck with.

By the way, this is in no way a Think C (or even Think Pascal) problem. The
fault is all ours. Think gets their Toolbox interface glue from us. This means
that you'll have the same problem in MPW C or Pascal.


>-Eric
>
>P.S.  Of course, the workaround is to set the field directly and use one's
>own glue routine, one per ClikLoop function, as amply described by others
>who responded.
>
>-- 
>Eric K. Olson            olson@endor.harvard.edu          harvard!endor!olson


-- 
------------------------------------------------------------------------------
Keith Rollin  ---  Apple Computer, Inc.  ---  Developer Technical Support
INTERNET: keith@apple.com
    UUCP: {decwrl, hoptoad, nsc, sun, amdahl}!apple!keith
"Argue for your Apple, and sure enough, it's yours" - Keith Rollin, Contusions

olson@bootsie.UUCP (Eric Olson) (01/03/90)

In article <37528@apple.Apple.COM> keith@Apple.COM (Keith Rollin) writes:
>By the way, this is in no way a Think C (or even Think Pascal) problem. The
>fault is all ours. Think gets their Toolbox interface glue from us. This means
>that you'll have the same problem in MPW C or Pascal.

Sorry to have attributed this problem to the wrong folks.  It is, however,
very heartwarming to learn that the [Not In ROM] glue routines are
standardized by Apple!  Sanity wins again!

-Eric
-- 
Eric K. Olson            olson@endor.harvard.edu          harvard!endor!olson