[comp.sys.mac.programmer] How to access QD globals in Code resources?

ahc@sisd.kodak.com (Aleck CheMponda CUST) (08/23/90)

I'm having problems trying to access quickdraw globals from a 
code resource.  I read that quickdraw globals can be accessed
as a negative offset from the low-memory global CurrentA5.

I would appreciate it if some kind sole could send me a the
necessary code or a description of what's required.  I'm using
Think_C 4.0. 

Thanks in advance.
******************
--
*****************************************************************
Aleck Che-Mponda		ahc@sisd.kodak.com
Software Engineer		amc4023@ma.rit.edu
"A geek, 'and proud of it, man!' "

ccc_ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) (08/24/90)

A valid QuickDraw context consists of a set of variables holding
the standard White, Black, Gray, LtGray and DkGray patterns, the
standard Arrow cursor, the ScreenBits bitmap, and RandSeed. These
variables are always in a fixed relative order, but there is *no*
standard offset for them from A5.

Instead, the value at the longword pointed to directly by A5 is
itself the address of this QuickDraw context. Thus, the only valid
access to these globals (other than from the application which
initialised the context in the first place) is indirectly
via A5.

Here are some useful routines which illustrate the idea. There
are functions which return pointers to each of the QuickDraw
globals, allowing you to do calls like

	FillOval(EyeRect, WhitePtr^)

and so on. I've thrown in a few other goodies as well, such
as my standard routines for saving/restoring the text settings
in the current GrafPort.

C programmers shouldn't have any trouble translating any of
this code. After all, whatever these Pascal wimps can do...

--------------------------------------------------------------------------------

    Const
      { offsets for use with QuickDrawGlobal (below) }
	WhiteOffset = $FFFFFFF8;
	BlackOffset = $FFFFFFF0;
	GrayOffset = $FFFFFFE8;
	LtGrayOffset = $FFFFFFE0;
	DkGrayOffset = $FFFFFFD8;
	ArrowOffset = $FFFFFF94;
	ScreenBitsOffset = $FFFFFF86;
	RandSeedOffset = $FFFFFF82;

    Type
	LongIntPtr = ^LongInt;
	TextState =		{ for saving font selection in a GrafPort }
	    Record
		txFont : Integer;
		txFace : Style;
		txMode : Integer;
		txSize : Integer
	    End {Record};

    Function QuickDrawGlobal
      (
	Offset : LongInt
      ) : LongInt;
      { returns the address of a QuickDraw global, given its offset. }

	Inline
	    $2015,		{move.l (a5), d0}
	    $D09F,		{add.l (sp)+, d0}
	    $2E80;		{move.l d0, (sp)}

    Function WhitePtr : PatPtr;

      Begin
	WhitePtr := PatPtr(QuickDrawGlobal(WhiteOffset))
      End {WhitePtr};

    Function BlackPtr : PatPtr;

      Begin
	BlackPtr := PatPtr(QuickDrawGlobal(BlackOffset))
      End {BlackPtr};

    Function GrayPtr : PatPtr;

      Begin
	GrayPtr := PatPtr(QuickDrawGlobal(GrayOffset))
      End {GrayPtr};

    Function LtGrayPtr : PatPtr;

      Begin
	LtGrayPtr := PatPtr(QuickDrawGlobal(LtGrayOffset))
      End {LtGrayPtr};

    Function DkGrayPtr : PatPtr;

      Begin
	DkGrayPtr := PatPtr(QuickDrawGlobal(DkGrayOffset))
      End {DkGrayPtr};

    Function ArrowPtr : CursPtr;

      Begin
	ArrowPtr := CursPtr(QuickDrawGlobal(ArrowOffset))
      End {ArrowPtr};

    Function ScreenBitsPtr : BitmapPtr;

      Begin
	ScreenBitsPtr := BitmapPtr(QuickDrawGlobal(ScreenBitsOffset))
      End {ScreenBitsPtr};

    Function RandSeedPtr : LongIntPtr;

      Begin
	RandSeedPtr := LongIntPtr(QuickDrawGlobal(RandSeedOffset))
      End {RandSeedPtr};

    Function GetTheCPort : CGrafPtr;
      { returns the current GrafPort or CGrafPort. }

	Inline
	    $2055,  { move.l (a5), a0 }
	    $2E90;  { move.l (a0), (sp) }

    Procedure GetTextState
      (
	var State : TextState
      );
      { gets the current font selection from the current GrafPort. }

	Var
	    CurPort : GrafPtr;

      Begin
	GetPort(CurPort);
	State.txFont := CurPort^.txFont;
	State.txFace := CurPort^.txFace;
	State.txMode := CurPort^.txMode;
	State.txSize := CurPort^.txSize
      End {GetTextState};

    Procedure SetTextState
      (
	State : TextState
      );
      { sets the font selection for the current GrafPort. Note that
	it is not correct to poke the fields directly. }

      Begin
	TextFont(State.txFont);
	TextFace(State.txFace);
	TextMode(State.txMode);
	TextSize(State.txSize)
      End {SetTextState};

--------------------------------------------------------------------------------

Lawrence D'Oliveiro                       fone: +64-71-562-889
Computer Services Dept                     fax: +64-71-384-066
University of Waikato            electric mail: ldo@waikato.ac.nz
Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00
To someone with a hammer and a screwdriver, every problem looks
like a nail with threads.