[comp.sys.mac.programmer] Offscreen Bitmap / MultiFinder

jkeegan@hawk.ulowell.edu (Jeff Keegan) (07/18/89)

This is actually a two part question (I'm getting lazy)..

One -> I want to have a window with a scroll bar that scrolls a large bitmap
       horizontally. I want to create an off-screen bitmap (actually an
       off-screen GrafPtr with it's own bitmap) and draw to that, then do
       a copybits to the screen after receiving an update event or after
       doing a scrollrect. Is this the best way to do it? And how exactly do
       I obtain the offscreen bitmap? I imagine that I must have to allocate
       enough memory for the bitmap (with NewPtr most likely) and have the
       baseAddr field of the bitmap point at that.. But how do I determine
       exactly how bit that NewPtr value must be? I know that I want my
       big-bitmap to have 7200 pixels across and a "n" pixels down..
       (By the way, I am creating the GrafPtr by creating a pointer with
       NewPtr(sizeof(GrafPort));  and then calling OpenPort. I've set the
       rectangle size to the correct size with PortSize.. What else am I
       going to have to do?

Two -> Because I am going to have to display the time constantly in one of
       windows, I am going to have to make my application "multi-finder
       aware".. Exactly what does this consist of? (I know there's some
       routine called waitnextevent, but what else is there? And how can I
       make it known that my routine UpdateTime() has to be called every
       once in a while, even if I'm in the background?

Thanks in advance.

..Jeff Keegan

-------------------------------------------------------------------------------
| Jeff Keegan                | I clutch the wire fence until my fingers bleed |
| jkeegan@hawk.ulowell.edu   | A wound that will not heal                     |
|----------------------------| A heart that cannot feel                       |
| This space intentionally   | Hoping that the horror will receed             |
| left blank                 | Hoping that tomorrow we'll all be freed  -RUSH |
-------------------------------------------------------------------------------

jnh@ecemwl.ncsu.edu (Joseph N. Hall) (07/19/89)

In article <14226@swan.ulowell.edu> jkeegan@hawk.ulowell.edu (Jeff Keegan) writes:
>This is actually a two part question (I'm getting lazy)..
>
>One -> I want to have a window with a scroll bar that scrolls a large bitmap
>       horizontally. I want to create an off-screen bitmap (actually an
>       off-screen GrafPtr with it's own bitmap) and draw to that, then do
>       a copybits to the screen after receiving an update event or after
>       doing a scrollrect.

Well, you CAN allocate your own GrafPtr if you want, but you can also use
your window's GrafPtr ...

        Is this the best way to do it? 

It's certainly the best way to handle update events if you have trouble
redrawing your window quickly.  It also looks better.  The NeXT maintains
a full offscreen bitmap for each open window and handles all of this stuff
automatically, by the way ...

	And how exactly do
>       I obtain the offscreen bitmap? I imagine that I must have to allocate
>       enough memory for the bitmap (with NewPtr most likely) and have the
>       baseAddr field of the bitmap point at that.. But how do I determine
>       exactly how bit that NewPtr value must be? I know that I want my
>       big-bitmap to have 7200 pixels across and a "n" pixels down..

Well, first of all, look up SetPortBits in IM vol. 1.  You can use the window's
own GrafPtr; just save the value of its portBits and then
SetPortBits(yourBits).

How do you MAKE your own offscreen bitmap?  Well, it needs to be large enough
to accomodate the existing window, and THEN it needs to be an even number of
bytes wide.  Thus rowBytes should equal ((horiz. pixels - 1) / 16) * 2 + 2.
The total size (in bytes) of the bitmap will be rowBytes * vert. pixels.
For simplicity, set bounds.left = bounds.top = 0, and bounds.right = horix.
pixels, bounds.bottom = vert. pixels.

This procedure is explained, although not exhaustively, in one of the early
Tech Notes (sorry, don't remember the number).  HIGHLY recommended reading,
although you may be able to get this working without it.

By the way, remember to scroll BOTH your bitmap and your window, if you're
using the bitmap to "back up" the window's contents ...

levin@bbn.com (Joel B Levin) (07/19/89)

In article <3427@ncsuvx.ncsu.edu> jnh@ecemwl.UUCP (Joseph N. Hall) writes:
|In article <14226@swan.ulowell.edu> jkeegan@hawk.ulowell.edu (Jeff Keegan) writes:
|Well, you CAN allocate your own GrafPtr if you want, but you can also use
|your window's GrafPtr ...
|	And how exactly do
|>       I obtain the offscreen bitmap? I imagine that I must have to allocate
|>       enough memory for the bitmap (with NewPtr most likely) and have the
|>       baseAddr field of the bitmap point at that.. But how do I determine
|>       exactly how bit that NewPtr value must be? I know that I want my
|>       big-bitmap to have 7200 pixels across and a "n" pixels down..
|
|Well, first of all, look up SetPortBits in IM vol. 1.  You can use the window's
|own GrafPtr; just save the value of its portBits and then
|SetPortBits(yourBits).

Well, no; I've been bitten by this.  You get into trouble with
following IM I's advice here.  Tech Note 41 is up-to-date and the
sample code in it helped me.  In short, you need a new GrafPort, for
which you allocate a new bitmap.  Just draw in the offscreen port.
Then you CopyBits from the offscreen port into the window -- that's
also your update routine.  (This is the simple model.)  My experience
with trying to use SetPortBits to swap bitmaps gave me trouble because
the offscreen bitmap got clipped (it was in the background under
multifinder).  See tech note 41 (and 120 for the equivalent with
CGrafPorts and pixel maps).

	/JBL
UUCP:     levin@bbn.com (new) or {backbone}!bbn!levin (old)
INTERNET: levin@bbn.com       		POTS: (617) 873-3463
   "The night was"

jnh@ecemwl.ncsu.edu (Joseph N. Hall) (08/15/89)

In article <42913@bbn.COM> levin@BBN.COM (Joel B Levin) writes:
 In article <3427@ncsuvx.ncsu.edu> jnh@ecemwl.UUCP (Joseph N. Hall) writes:
 |Well, first of all, look up SetPortBits in IM vol. 1.  You can use the window's
 |own GrafPtr; just save the value of its portBits and then
 |SetPortBits(yourBits).
 
 Well, no; I've been bitten by this.  You get into trouble with
 following IM I's advice here.
 ... My experience
 with trying to use SetPortBits to swap bitmaps gave me trouble because
 the offscreen bitmap got clipped (it was in the background under
 multifinder).

Yeah, true, this can happen ... I should have pointed this out. 
It also irritates me that there's no accessor function for OBTAINING the
value of your portBits, thus your code depends upon the window structure
remaining the same throughout antiquity ... not the most dangerous assumption
you could make, but still less advisable than finding a trap-only method
of implementing your algorithm.  Taking all this into consideration,
I guess I'd recommend starting off with a fresh GrafPtr ...