From: pottier@clipper.ens.fr (Francois Pottier)
Subject: csmp-digest-v3-074
Date: Tue, 6 Dec 1994 17:53:07 +0100 (MET)

C.S.M.P. Digest             Tue, 06 Dec 94       Volume 3 : Issue 74
 
Today's Topics:
 
        Faster SetCPixel Alternatives?
        Newbie Q Regarding Window Updates
        Pascal ProcPtr Example?
        QDGX and Pict resources
        TransSkel 3.18 (THINK C, Metrowerks) now available
        how can I implement-program Plug-Ins?
        using HLock before memcpy



The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
(pottier@clipper.ens.fr).
 
The digest is a collection of article threads from the internet newsgroup
comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
regularly and want an archive of the discussions.  If you don't know what a
newsgroup is, you probably don't have access to it.  Ask your systems
administrator(s) for details.  If you don't have access to news, you may
still be able to post messages to the group by using a mail server like
anon.penet.fi (mail help@anon.penet.fi for more information).
 
Each issue of the digest contains one or more sets of articles (called
threads), with each set corresponding to a 'discussion' of a particular
subject.  The articles are not edited; all articles included in this digest
are in their original posted form (as received by our news server at
nef.ens.fr).  Article threads are not added to the digest until the last
article added to the thread is at least two weeks old (this is to ensure that
the thread is dead before adding it to the digest).  Article threads that
consist of only one message are generally not included in the digest.

The digest is officially distributed by two means, by email and ftp.

If you want to receive the digest by mail, send email to listserv@ens.fr
with no subject and one of the following commands as body:
    help		                Sends you a summary of commands
    subscribe csmp-digest Your Name	Adds you to the mailing list
    signoff csmp-digest			Removes you from the list
Once you have subscribed, you will automatically receive each new
issue as it is created.

The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
Questions related to the ftp site should be directed to
scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
digest are available there.

Also, the digests are available to WAIS users.  To search back issues
with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.


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

>From smithab@hydra.syr.edu (Core Dumped)
Subject: Faster SetCPixel Alternatives?
Date: 12 Nov 1994 18:27:26 GMT
Organization: Syracuse University, Syracuse, NY

Hi. I am working on a fractal program which has to assemble a 640 by 480 
picture pixel by pixel.  Currently I am using SetCPixel since the color 
of each pixel I set is different from the previous.  What I would like to 
know, is how to draw directly into the GWorld PixMap.

I have tried this:
	
	I am trying to use 'baseAddr' to find the PixMap location, and 
write to it directly, but my colors get messed up, and can't get rowBytes 
to give me any information.  I am writing to a 40 by 40 GWorld, which is 
16-bit color.  Seems to me that rowBytes should be 80, but it's zero!?
Also, if I remove rowBytes from my assignment, and manually replace it 
with 80, that results in a skewing of the picture. Even more curiously, 
using 96 for the offset to the next line gives perfect alignment, but 
crashes the program with Error 11 at the end of the GWorld.  

Do powermac GWorlds have 16 bytes of some extra information in each line?

Perhaps my color structure is wrong also. I was assuming that 16bit color 
looks like this in memory (each letter = 1 bit):

		GGGGGRRRRRBBBBBM
                ^
                Least sig. bit at the left.

Is this correct?

If so, why can't I write a short word directly into memory? I am having 
to do this write in two calls, one for each byte.


Any info on the above would be great.

-Adam Smith
smithab@mailbox.syr.edu



+++++++++++++++++++++++++++

>From mjew@dnai.com (Matthew Jew)
Date: Wed, 16 Nov 1994 11:09:01 -0800
Organization: Bold Print Inc.

In article <3a31ee$n1c@newstand.syr.edu>, smithab@hydra.syr.edu (Core
Dumped) wrote:

> Hi. I am working on a fractal program which has to assemble a 640 by 480 
> picture pixel by pixel.  Currently I am using SetCPixel since the color 
> of each pixel I set is different from the previous.  What I would like to 
> know, is how to draw directly into the GWorld PixMap.
> 

Yes, SetCPixel is not the fastest thing in the world, but I was always 
taught that mucking around with the pixmap directly was very very very bad idea.
Your drawing routine (as described) sounds like it would work *only* with 
16-bit color pixmaps. Will your program need to handle other color depths?
Tread carefully. Doing things like this will almost guarantee your program will
break when the system software changes.

+++++++++++++++++++++++++++

>From kenp@tuli (Kenneth Prehoda)
Date: 16 Nov 1994 20:33:09 GMT
Organization: Division of Information Technology

Matthew Jew (mjew@dnai.com) wrote:
: In article <3a31ee$n1c@newstand.syr.edu>, smithab@hydra.syr.edu (Core
: Dumped) wrote:

: > Hi. I am working on a fractal program which has to assemble a 640 by 480 
: > picture pixel by pixel.  Currently I am using SetCPixel since the color 
: > of each pixel I set is different from the previous.  What I would like to 
: > know, is how to draw directly into the GWorld PixMap.
: > 

: Yes, SetCPixel is not the fastest thing in the world, but I was always 
: taught that mucking around with the pixmap directly was very very
: very bad idea.

Then you were taught incorrectly.  It is true that mucking around 
with a windows's pixmap, or anything else that would draw directly
to the screen is asking for trouble.  However, there is absolutely
nothing wrong with drawing directly into an offscreen pixmap.  In
fact, this is the Apple sanctioned way to do fast drawing:  Do all
of your direct drawing to an offscreen GWorld and copybits that
to the screen.

: Your drawing routine (as described) sounds like it would work *only* with 
: 16-bit color pixmaps. Will your program need to handle other color depths?
: Tread carefully. Doing things like this will almost guarantee your
: program will break when the system software changes.

If your program needs to handle different color depths, then it can
make gworlds with different depths.  Not complicated.  

Your warnings are not necessary.  This WILL NOT break when system software
changes.  If it does, then a lot of currently well-behaved programs
will.

-Ken Prehoda
Department of Biochemistry
University of Wisconsin-Madison
kenp@nmrfam.wisc.edu

+++++++++++++++++++++++++++

>From mjew@dnai.com (Matthew Jew)
Date: Wed, 16 Nov 1994 16:46:57 -0800
Organization: Bold Print Inc.

In article <3adqa5$7ti@news.doit.wisc.edu>, kenp@tuli (Kenneth Prehoda) wrote:

> : Yes, SetCPixel is not the fastest thing in the world, but I was always 
> : taught that mucking around with the pixmap directly was very very
> : very bad idea.
> 
> Then you were taught incorrectly.  It is true that mucking around 
> with a windows's pixmap, or anything else that would draw directly
> to the screen is asking for trouble.  However, there is absolutely
> nothing wrong with drawing directly into an offscreen pixmap.  In
> fact, this is the Apple sanctioned way to do fast drawing:  Do all
> of your direct drawing to an offscreen GWorld and copybits that
> to the screen.

Yes, you are right. I wrote before I thought carefully about what he was asking.
Thanks for pointing that out.

> If your program needs to handle different color depths, then it can
> make gworlds with different depths.  Not complicated.  
> 

However, in his original question, he was asking *specifically* about the
format for 16-bit color pixmaps, and how to write to them. Therefore, even
if he did make a pixmap of a different depth (not complicated), the
routine would have to be rewritten to handle the differently formatted
pixmap (more complicated).

+++++++++++++++++++++++++++

>From macneils@aol.com (MacneilS)
Date: 16 Nov 1994 22:05:13 -0500
Organization: America Online, Inc. (1-800-827-6364)

In article <mjew-1611941109010001@dynamic-206.dnai.com>, mjew@dnai.com
(Matthew Jew) writes:

>>>>>>
but I was always taught that mucking around with the pixmap directly was
very very very bad idea.
<<<<<<

develop Issue 17 says that it's 100% OK to change the pixmap of a GWorld
directly, and that doing such will be supported on ALL future machines.
The article also tells you the best way to do it, and when to do it.

Take Care,
MacneilS@aol.com

+++++++++++++++++++++++++++

>From smithab@hydra.syr.edu (Core Dumped)
Date: 17 Nov 1994 12:49:49 GMT
Organization: Syracuse University

>> If your program needs to handle different color depths, then it can
>> make gworlds with different depths.  Not complicated.  
>> 
>
>However, in his original question, he was asking *specifically* about the
>format for 16-bit color pixmaps, and how to write to them. Therefore, even
>if he did make a pixmap of a different depth (not complicated), the
>routine would have to be rewritten to handle the differently formatted
>pixmap (more complicated).

	Yes, I did ask specifically about 16-bit GWorlds. I am using 16bit
because it is a nice compromise of GWorld size and image quality.  Having 
my routine only write to 16-bit GWorlds also means that I don't have to 
use any conditionals or function pointers to switch between separate 
drawing routines for each possible bit-depth GWorld, which makes for a 
simpler, faster program.  I just let copybits take care of the color 
translation, so my program is optimized for 16-bit monitors (though 
performance doesn't suffer much at 32-bits).  It's just a fractal 
program, and it doesn't ever use the full 32768 colors anyways :) 

Thanks to everyone who helped me out with this! I'm currently trying to
track down some of these past 'Develop's.

-Adam
smithab@mailbox.syr.edu

+++++++++++++++++++++++++++

>From Bruce@hoult.actrix.gen.nz (Bruce Hoult)
Date: Sat, 19 Nov 1994 12:56:58 +1300 (NZDT)
Organization: (none)

mjew@dnai.com (Matthew Jew) writes:
> In article <3a31ee$n1c@newstand.syr.edu>, smithab@hydra.syr.edu (Core
> Dumped) wrote:
> 
> > Hi. I am working on a fractal program which has to assemble a 640 by 480 
> > picture pixel by pixel.  Currently I am using SetCPixel since the color 
> > of each pixel I set is different from the previous.  What I would like to 
> > know, is how to draw directly into the GWorld PixMap.
> > 
> 
> Yes, SetCPixel is not the fastest thing in the world, but I was always 
> taught that mucking around with the pixmap directly was very very very bad idea.
> Your drawing routine (as described) sounds like it would work *only* with 
> 16-bit color pixmaps. Will your program need to handle other color depths?
> Tread carefully. Doing things like this will almost guarantee your program will
> break when the system software changes.

No, GWorlds are guarenteed always to work.  If he creates a 4-bit deep GWorld
then he will always get a 4-bit deep GWorld, even in the far distant future,
and the layout of the pixmap will always be the same.  And no matter what Apple
does to the screen hardware, CopyBits will always know how to copy from a
4-bit GWorld to whatever the new screen format is -- it may not always be
optimally fast, but it will always work.

-- Bruce

+++++++++++++++++++++++++++

>From bhamlin@netcom.com (Brian Hamlin)
Date: Mon, 21 Nov 1994 00:33:04 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)

  If you want to set pixels directly in GWorlds:
  - use the flag 'keepLocal' when calling NewGWorld
  - use routines GetGWorldPixMap(), then GetPixBaseAddr() to 
     find pixels
  - LockPixels whenever accessing bits
  - remember to clear the high bit of rowBytes when calc' bit positions !

  When CopyBits()'ing from a GWorld
  - don't mix GetPort()/SetPort() with GetGWorld()/SetGWorld()
  - always SetGWorld to the dst GrafPort
  - set ForeColor(blackColor) BackColor(whiteColor) in dst Port ! 

-- 
--
Brian M. Hamlin                          noEsis software construction
bhamlin@netcom.com                                    +1 510 271-7971


+++++++++++++++++++++++++++

>From 103t_english@west.cscwc.pima.edu
Date: 21 Nov 94 17:21:31 MST
Organization: (none)

In article <bhamlinCzLDJ4.Lq9@netcom.com>, bhamlin@netcom.com (Brian Hamlin) writes:
>   If you want to set pixels directly in GWorlds:
>   - use the flag 'keepLocal' when calling NewGWorld

I thought that one could draw to graphics card cache as well if one wanted?


Lawson

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

>From ineluki@u.washington.edu (Paul McElroy)
Subject: Newbie Q Regarding Window Updates
Date: 22 Nov 1994 20:01:40 GMT
Organization: University of Washington

I have a simple question.  What is the correct procedure to make sure the 
correct window is updated on an updateEvt?  My WaitNextEvent loop 
includes:

	switch(event)
	{
		case updateEvt:
			HandleUpdate((WindowPtr)event->message);
			break;

Ok, and down here in HandleUpdate, I get 'window', the Window Pointer 
that was passed from above, and the usual stuff:

	GetPort(&savePort);
	SetPort(window);

	BeginUpdate(window);
	DrawControls(window);
	...etc...
	EndUpdate(window);
	SetPort(savePort);

Now, how do I distinguish between one window and another here?  My app 
has two windows displayed at once, one with a pic and a control, the 
other with a different pic and controls.  What is the procedure to update 
the correct window with the correct pic and controls?  Is it with a 
switch(window) or if(window)?  Thanks for any replies.

ineluki@u.washington.edu

+++++++++++++++++++++++++++

>From Eric Kidd <emk@dartmouth.edu>
Date: 22 Nov 1994 22:25:47 GMT
Organization: Dartmouth College

In article <3atin4$m6a@nntp1.u.washington.edu> Paul McElroy,
ineluki@u.washington.edu writes:
> Now, how do I distinguish between one window and another here?  My app 
> has two windows displayed at once, one with a pic and a control, the 
> other with a different pic and controls.  What is the procedure to
update 
> the correct window with the correct pic and controls?  Is it with a 
> switch(window) or if(window)?  Thanks for any replies.

In general, you can identify windows on screen by using the refCon field
in the window record. Assign some unique value to this when the window
is created (perhaps a pointer to the data describing the window) and
use this to identify your windows. (Either switch or if can be used,
depending on the situation and your style.) In the following code, I
assign refCon a pointer to data which:
	1) identifies the type of window
	2) provides info on drawing it
The latter varies, so I create two different data records with the ID
field at the top of each.

For example (from memory, my IM books are packed--check your header files
	for spelling errors and whatnot if this won't compile):

typedef struct {
	short id;
	ControlHandle myControl;
	PictHandle myPict;
} myWinData1;

typedef struct {
	short id;
	ControlHandle myControl;
	ControlHandle myOtherControl;
	PictHandle myPict;
} myWinData2;		/* Yes, unions work as well. */

# define	WINTYPE1	(1)
# define	WINTYPE2	(2)

.... at window creation (of the first type)

	// create window here
	
	myWinData1* data = (myWinData1*) NewPtr( sizeof(myWinData1) );
		// Handles 	work, 	too
		// check to see if data == 0. Don't proceed if it does,
		// because that means the system couldn't allocate
		// memory.
	win->refCon = (long) data;
	data->id = WINTYPE1;
	
	// fill out rest of info


.... at drawing time

		// since the ID is in the same place in both structures
		//	we can pick either type to check it. Once we know
		//	what it is, the doDrawWinTypeX functions can coerce
		//	the refCon to the right pointer type internally.
		
		// There is a way to identify DA refCons, but it has become
		//	mostly irrelevant under System 7. See the manual.
	switch ( ((myWinData1*) theWindow->refCon)->id )
	{
		case WINTYPE1:
			doDrawWinType1( theWindow );
			break;
		
		case WINTYPE2:
			doDrawWinType2( theWindow );
			break;
	};
	

That's very rough, but it may point you in the correct direction. If
you'd like a better presentation of this, mail me at emk@dartmouth.edu,
(or wait for someone else to elaborate). My books will be unpacked
when I return from Thanksgiving (I'm headed home tomorrow morning).

Have fun programming and consider getting Inside Macintosh: Toolbox
Essentials for a more enjoyable experience. The sample code is very good,
and helped me to implement a great number of things that would have kept
me up all night otherwise.

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

>From pzwiefel@students.wisc.edu (Zwiefelhofer)
Subject: Pascal ProcPtr Example?
Date: Sat, 19 Nov 1994 14:20:41 -0600
Organization: Division of Information Technology

I'd like to give the user the ability to choose between several transfer
functions in a program. I would like to use functions as procedure
pointers for convenience. 

Does anyone have any Pascal examples of how to declare my procedures or
functions so that I can use the @ operator on them and then pass a pointer
to them depending on which function the user chose?

Thanks.

Dave

+++++++++++++++++++++++++++

>From pottier@drakkar.ens.fr (Francois Pottier)
Date: 21 Nov 1994 12:56:48 GMT
Organization: Ecole Normale Superieure, PARIS, France

In article <pzwiefel-1911941420410001@f181-092.net.wisc.edu>,
Zwiefelhofer <pzwiefel@students.wisc.edu> wrote:
>I'd like to give the user the ability to choose between several transfer
>functions in a program. I would like to use functions as procedure
>pointers for convenience. 

If you want to use function pointers, then you will have to use some
inline assembly. Not much, but it can be a problem if you don't assembly
at all.

There is a way to do it in pure Think Pascal without pointers. I don't know
what you mean by a transfer function; let's say it's a function from reals
to reals. You can declare

function Transfer1 (x : real) : real;
blah blah...

function Transfer2 (x : real) : real;
more blah blah...

procedure ComputeUsingTransferFunction (function f (x : real) : real);
begin
  ... use f ...
end;

and finally you can call ComputeUsingTransferFunction(Transfer1)
or ComputeUsingTransferFunction(Transfer2).

Unfortunately, as far as I know, you have to pass function names as
parameters to ComputeUsingTransferFunction; I mean, you can't use a variable
of type "function (x : real) : real".

The Think Pascal doc should explain all this in detail...

Hope this helps




-- 
Francois Pottier                                            pottier@dmi.ens.fr
- ----------------------------------------------------------------------------
Check my WWW page at http://acacia.ens.fr:8080/home/pottier/index.html ...

+++++++++++++++++++++++++++

>From pzwiefel@students.wisc.edu (Zwiefelhofer)
Date: Sun, 20 Nov 1994 19:28:27 -0600
Organization: Division of Information Technology

In article <Jaeger-2011941747210001@slip-2-40.ots.utexas.edu>,
Jaeger@fquest.com (Brian Stern) wrote:

> Here's an example of jumping to a procedure that takes no parameters:
> 
>  procedure JumpToOldFilter (theFilterProc: ProcPtr);
> {Move the procptr to the stack and JSR to it }
>  inline
>   $205F, $4E90;      {MoveA.L  (A7)+, A0 ;   JSR (A0) }
> 
> 
> You can modify this based on the parameters that you need to pass and/or
> return.  Look at the disassembled code that the compiler generates to call
> a procedure like the one you want to call.  Model your inline procedure
> after that code.  Obviously this example won't work on the PPC.

I'm afraid this is beyond me. Do I really need to muck about with
assembly? I thought that there would be a comparatively simple method of
declaring a specific type of procPtr for functions that take one extended
and return one extended.

Is this possible? Any examples? Ideas?

Thanks.

-Dave

+++++++++++++++++++++++++++

>From greg@cosc.canterbury.ac.nz (Greg Ewing)
Date: 21 Nov 1994 04:36:59 GMT
Organization: University of Canterbury, Christchurch, New Zealand


In article <pzwiefel-2011941928270001@f180-222.net.wisc.edu>, pzwiefel@students.wisc.edu (Zwiefelhofer) writes:
|> I thought that there would be a comparatively simple method of
|> declaring a specific type of procPtr for functions that take one extended
|> and return one extended.

Unfortunately, in Pascal there is no such method.
Pascal has no notion of a pointer to a procedure
the way C has. Applying @ to a procedure is just
a kludge that was added to provide a way of passing
procedures to the toolbox. The Pascal compiler
has no idea what type of pointer this is, and
doesn't have the concepts to understand even if
you tried to explain to it.

If you are using Object Pascal there is a much
better method of achieving what you want.
Define an object type which has a method for
carrying out whatever it is you want to do,
and define subtypes which implement it in
different ways. e.g.

  type

    Transformer = object
      procedure MungeIt(inp: MyStuff; var out: MyStuff);
    end;

    FirstTransformer = object(Transformer)
      procedure MungeIt(inp: MyStuff; var out: MyStuff); override;
    end;

    SecondTransformer = object(Transformer)
      procedure MungeIt(inp: MyStuff; var out: MyStuff); override;
    end;

    {etc...}

    procedure FirstTransformer.MungeIt(inp: MyStuff; var out: MyStuff);
    begin
      {Munge your stuff the first way}
    end;

    procedure SecondTransformer.MungeIt(inp: MyStuff; var out: MyStuff);
    begin
      {Munge your stuff the second way}
    end;

    {etc...}

Now make an instance of each of these objects and
let the user choose one of them somehow, e.g.

  var
    transformers: array[1..numTransformers] of Transformer;

  procedure InitialiseTransformers;
  {Call this when you're initialising your application}
  var
    t1: FirstTransformer;
    t2: SecondTransformer;
    {etc}
  begin
    new(t1);
    transformers[1] := t1;
    new(t2);
    transformers[2] := t2;
    {etc}
  end;

  procedure ApplyATransformer(whichOne: integer; inp: MyStuff; var out: MyStuff);
  begin
    transformers[whichOne].MungeIt(inp, out);
  end;

There are many ways you use this stuff. The point is that
you can pass around Transformers the same way you would
procedure pointers, and call them easily and safely.

If you don't know about Object Pascal, find out -
it makes a lot of things much easier, and is the
basis of some very powerful GUI frameworks like
MacApp and the Think Class Library.

|> -Dave

Greg Ewing, Computer Science Dept, +--------------------------------------+
University of Canterbury,	   | A citizen of NewZealandCorp, a	  |
Christchurch, New Zealand	   | wholly-owned subsidiary of Japan Inc.|
greg@cosc.canterbury.ac.nz	   +--------------------------------------+

+++++++++++++++++++++++++++

>From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
Date: 22 Nov 94 10:06:44 +1300
Organization: University of Waikato, Hamilton, New Zealand

In article <pzwiefel-2011941928270001@f180-222.net.wisc.edu>, pzwiefel@students.wisc.edu (Zwiefelhofer) writes:
> In article <Jaeger-2011941747210001@slip-2-40.ots.utexas.edu>,
> Jaeger@fquest.com (Brian Stern) wrote:
>
>> Here's an example of jumping to a procedure that takes no parameters:
>>
>>  procedure JumpToOldFilter (theFilterProc: ProcPtr);
>> {Move the procptr to the stack and JSR to it }
>>  inline
>>   $205F, $4E90;      {MoveA.L  (A7)+, A0 ;   JSR (A0) }
>>
>>
>> You can modify this based on the parameters that you need to pass and/or
>> return.  Look at the disassembled code that the compiler generates to call
>> a procedure like the one you want to call.  Model your inline procedure
>> after that code.  Obviously this example won't work on the PPC.
>
> I'm afraid this is beyond me. Do I really need to muck about with
> assembly? I thought that there would be a comparatively simple method of
> declaring a specific type of procPtr for functions that take one extended
> and return one extended.

Stay cool! The above two words of machine code are all you will need. You
can use them to call any Pascal procedure or function, regardless of the
arguments or function result type. For example, you want to call a function
like

    Function F
      (
	X : Extended
      ) : Extended;

You can do it like this:

    Function Call_F
      (
	X : Extended;
	F : ProcPtr
      ) : Extended;

	Inline
	    $205F,	{ move.l (sp)+, a0 }
	    $4E90;	{ jsr (a0) }

eg

    FPtr := @F;
    Y := Call_F(X, FPtr)

The only rule to remember when defining the "Call_F" routine is that the
argument list and function result types must match those of the routine you're
going to call, except that Call_F takes an extra argument, which is the
address of the routine to call. This must be the last argument. The inline
code is always the same!

Lawrence D'Oliveiro                       fone: +64-7-856-2889
Computer Services Dept                     fax: +64-7-838-4066
University of Waikato            electric mail: ldo@waikato.ac.nz
Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00

+++++++++++++++++++++++++++

>From greg@cosc.canterbury.ac.nz (Greg Ewing)
Date: 22 Nov 1994 01:50:21 GMT
Organization: University of Canterbury, Christchurch, New Zealand


In article <pzwiefel-2111940914280001@f180-163.net.wisc.edu>, pzwiefel@students.wisc.edu (Zwiefelhofer) writes:
|> I really don't
|> want to go through several if-then statements in a procedure that may be
|> called several 100K times per session if I don't absolutely have to.

Have you considered using a case statement switching
on an integer or enumerated type? If the range of
cases is contiguous this should compile into a
table lookup, which will be faster than a chain
of if-thens if there are enough cases.

|> -Dave

Greg Ewing, Computer Science Dept, +--------------------------------------+
University of Canterbury,	   | A citizen of NewZealandCorp, a	  |
Christchurch, New Zealand	   | wholly-owned subsidiary of Japan Inc.|
greg@cosc.canterbury.ac.nz	   +--------------------------------------+

+++++++++++++++++++++++++++

>From pzwiefel@students.wisc.edu (Zwiefelhofer)
Date: Mon, 21 Nov 1994 21:30:49 -0600
Organization: Division of Information Technology

In article <1994Nov22.100645.35467@waikato.ac.nz>, ldo@waikato.ac.nz
(Lawrence D'Oliveiro, Waikato University) wrote:

> Stay cool! The above two words of machine code are all you will need.

Okay, I'll give it a go! Thanks.

-Dave

+++++++++++++++++++++++++++

>From obo@dec59.ruk.cuni.cz (Ondrej Bojar)
Date: 21 Nov 1994 13:21:55 GMT
Organization: Charles University Prague, Computer Center

When I wanted to do this (for updating windows), I had to ask a friend to
create an MPW .o file of a C routine calling my proc (at procptr) with some
params. I think pascal has only some routine called DOJSR (don't quote me)
that doesn't allow to pass any parameters.
 I think it's easier to use objects...


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

>From jaks@netcom.com (Eric Jackson)
Subject: QDGX and Pict resources
Date: Wed, 16 Nov 1994 20:47:07 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)

I would like to be able to read in  a 'pict' recource from a resource
file into my Quick Draw GX application.  This pict consists of a
color bit map image.

In all of the examples that I have seen in the Quick Draw GX Developer CD
the bit maps are of a type called 'pxmp'.

What I would like to do is to read my pict into a BitMapShape and them clip it.
Any suggestions would be nice.

Eric Jaskson
jaks@netcom.com


+++++++++++++++++++++++++++

>From jaks@netcom.com (Eric Jackson)
Date: Wed, 16 Nov 1994 22:57:09 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)

In article <jaksCzDoEK.EHG@netcom.com>, Eric Jackson <jaks@netcom.com> wrote:
>I would like to be able to read in  a 'pict' recource from a resource
>file into my Quick Draw GX application.  This pict consists of a
>color bit map image.
>
>In all of the examples that I have seen in the Quick Draw GX Developer CD
>the bit maps are of a type called 'pxmp'.
>
>What I would like to do is to read my pict into a BitMapShape and them clip it.
>Any suggestions would be nice.
>
>Eric Jaskson
>jaks@netcom.com
>

Well I have been able to draw my first gxShape that was imported from a
picture.  There is a good discussion of how to do this in QuickDraw GX
environment and utilities.

Here is some sample code that works:

void DoInitialization(gWindow)
WindowPtr gWindow;
{
	gxTransform	PerspectiveTransform;
	gxMapping		PerspectiveTransformMapping;
	PicHandle		Picture = (PicHandle) GetResource ('PICT',128);
	gxShape		aPictureShape;
	Rect			PictureBox;
	Point			styleStrech;

	PictureBox = (**Picture).picFrame;
	
	aPictureShape = GXNewShape(gxPictureType);
	
	styleStrech.v = 1;
	styleStrech.h = 1;
	
	GXConvertPICTToShape(Picture, gxDefaultOptionsTranslation,&PictureBox,&PictureBox,
						styleStrech,aPictureShape, nil);
						
	gShape = aPictureShape;

}

This code works with the *graphics shell.c* program shell that comes with
the QuickDraw GX SDK, later on it will draw gShape for me automatically.

I still don't really understand how to get this into a BitMap shape yet
but I will keep working. Shure does not seem to be a lot of discussion
about Quick Draw GX basics on here yet.

Eric Jackson
jaks@netcom.com


+++++++++++++++++++++++++++

>From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
Date: 17 Nov 94 16:56:39 +1300
Organization: University of Waikato, Hamilton, New Zealand

In article <jaksCzDoEK.EHG@netcom.com>, jaks@netcom.com (Eric Jackson) writes:
> I would like to be able to read in  a 'pict' recource from a resource
> file into my Quick Draw GX application.  This pict consists of a
> color bit map image.
>
> In all of the examples that I have seen in the Quick Draw GX Developer CD
> the bit maps are of a type called 'pxmp'.
>
> What I would like to do is to read my pict into a BitMapShape and them clip it.
> Any suggestions would be nice.

Are you trying to

  a) read QuickDraw pictures in from PICT resources and convert them to
     GX shapes, or
  b) read flattened GX shapes in from resources and unflatten them?

The first is easy, the second is only slightly harder.

To convert a QuickDraw picture to a GX shape, you use GXConvertPICTToShape.

To unflatten a GX shape, you use GXUnflattenShape. There is source code for
a routine called HandleToShape in the GX libraries, that should do exactly
what you want.

By the way, Apple seems to have standardized on 'qdgx' as the OSType type
code for GX shapes (as opposed to 'grfx', which some pre-release utilities
used, and which I prefer :-)). So if you want to store a flattened GX shape
in a resource, make it a resource of type 'qdgx'. Then when you copy it to
the clipboard from ResEdit, it will display properly in other GX-savvy programs.
And conversely, you can create the shape in another program, and paste it
into your resource forks with ResEdit.

Lawrence D'Oliveiro                       fone: +64-7-856-2889
Computer Services Dept                     fax: +64-7-838-4066
University of Waikato            electric mail: ldo@waikato.ac.nz
Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00

+++++++++++++++++++++++++++

>From jaks@netcom.com (Eric Jackson)
Date: Mon, 21 Nov 1994 05:32:36 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)

In article <1994Nov17.165639.35369@waikato.ac.nz>,
Lawrence D'Oliveiro, Waikato University <ldo@waikato.ac.nz> wrote:
>In article <jaksCzDoEK.EHG@netcom.com>, jaks@netcom.com (Eric Jackson) writes:
>> I would like to be able to read in  a 'pict' recource from a resource
>> file into my Quick Draw GX application.  This pict consists of a
>> color bit map image.
>>
>> In all of the examples that I have seen in the Quick Draw GX Developer CD
>> the bit maps are of a type called 'pxmp'.
>>
>> What I would like to do is to read my pict into a BitMapShape and them clip it.
>> Any suggestions would be nice.
>
>Are you trying to
>
>  a) read QuickDraw pictures in from PICT resources and convert them to
>     GX shapes, or
>  b) read flattened GX shapes in from resources and unflatten them?
>
>The first is easy, the second is only slightly harder.
>
>To convert a QuickDraw picture to a GX shape, you use GXConvertPICTToShape.
>
>To unflatten a GX shape, you use GXUnflattenShape. There is source code for
>a routine called HandleToShape in the GX libraries, that should do exactly
>what you want.
>
>By the way, Apple seems to have standardized on 'qdgx' as the OSType type
>code for GX shapes (as opposed to 'grfx', which some pre-release utilities
>used, and which I prefer :-)). So if you want to store a flattened GX shape
>in a resource, make it a resource of type 'qdgx'. Then when you copy it to
>the clipboard from ResEdit, it will display properly in other GX-savvy programs.
>And conversely, you can create the shape in another program, and paste it
>into your resource forks with ResEdit.
>
>Lawrence D'Oliveiro                       fone: +64-7-856-2889
>Computer Services Dept                     fax: +64-7-838-4066
>University of Waikato            electric mail: ldo@waikato.ac.nz
>Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00

Actually I got that far already.  That is I read in my picture and then
converted it into a gxPictureType shape.  Now what I wanted to do was to
change my PictureShape into a gxBitmapShape.

I was able to do this as well but I seem to have lost all of my color
information in doing this.

The way I did this was by calling

GXSetShapeType(PictureShapeThatWillBecomeBitMapShape,gxBitmapShape);

When I put my picture that I have created by exactly the method that you
discribed what happend is that I get a black and white bit map and all of
my color gets lost.  What I would like to do is to keep my color information.
For now what I have been doing is to just move forward and work with a picture
shape and not convert it into a bitmap.  Maybe what I should be doing is to
just draw my picture shape into a bitmap but I have not gotten around to trying
this just yet since there is so much other stuff that I have been working with.

I can report that I think that QuickDraw GX is really fun to work with and
has a lot of nice features.

Eric Jackson
jaks@netcom.com


+++++++++++++++++++++++++++

>From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
Date: 22 Nov 94 10:26:20 +1300
Organization: University of Waikato, Hamilton, New Zealand

In article <jaksCzLrEC.74s@netcom.com>, jaks@netcom.com (Eric Jackson) writes:
>
> Actually I got that far already.  That is I read in my picture and then
> converted it into a gxPictureType shape.  Now what I wanted to do was to
> change my PictureShape into a gxBitmapShape.
>
> I was able to do this as well but I seem to have lost all of my color
> information in doing this.
>
> The way I did this was by calling
>
> GXSetShapeType(PictureShapeThatWillBecomeBitMapShape,gxBitmapShape);
>
> When I put my picture that I have created by exactly the method that you
> discribed what happend is that I get a black and white bit map and all of
> my color gets lost.  What I would like to do is to keep my color information.
> For now what I have been doing is to just move forward and work with a picture
> shape and not convert it into a bitmap.  Maybe what I should be doing is to
> just draw my picture shape into a bitmap but I have not gotten around to trying
> this just yet since there is so much other stuff that I have been working with.

I guess if GXSetShapeType is changing the picture to a black-and-white bitmap,
then you really have to draw the shape into a bitmap of the depth you need,
if you want to keep the colours.

The good news is, it's not much harder than QuickDraw GWorld calls. Here's
an outline of the steps:

  1) Set up a gxBitmap record describing the bitmap shape you want to create,
     initializing the fields as follows:
	image := nil (* let GX allocate the pixels for you *)
	width := the desired width in pixels
	height := the desired height in pixels
	rowBytes := (width + 31) DIV 32 * 4
	pixelSize := 32
	space := gxRGB32Space
	set := nil (* ignored for direct depths *)
	profile := nil.
  2) Create a bitmap shape from the gxBitmap record, using GXNewBitmap.
  3) Create an offscreen viewgroup using GXNewViewGroup.
  4) Create an offscreen view device, using GXNewViewDevice, passing the
     bitmap you created in step 2, and the view group you created in step 3.
  5) Create a viewport attached to the viewgroup you created in step 3.

Now all you have to do is draw your shape into the viewport you created in
step 5.

Tip: you should create a full shape with an appropriate background colour
(eg white) and draw it into the offscreen viewport first, to initialize all
the pixels to a known value, before drawing your picture shape.

Once you've finished with the offscreen structures, you can dispose of them
by calling GXDisposeViewGroup on the offscreen viewgroup. This will
automatically dispose of the attached view device and viewport as well. All
that will be left is the bitmap shape.

> I can report that I think that QuickDraw GX is really fun to work with and
> has a lot of nice features.

Same here!

Lawrence D'Oliveiro                       fone: +64-7-856-2889
Computer Services Dept                     fax: +64-7-838-4066
University of Waikato            electric mail: ldo@waikato.ac.nz
Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00

+++++++++++++++++++++++++++

>From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
Date: 22 Nov 94 13:06:37 +1300
Organization: University of Waikato, Hamilton, New Zealand

In article <1994Nov22.102621.35468@waikato.ac.nz>, I wrote:

>   1) Set up a gxBitmap record describing the bitmap shape you want to create,
..
> 	rowBytes := (width + 31) DIV 32 * 4

Oops! This calculation is only correct for a 1-bit-deep pixmap. For 32 bits
per pixel, it should of course be

	rowBytes := width * 4

Lawrence D'Oliveiro                       fone: +64-7-856-2889
Computer Services Dept                     fax: +64-7-838-4066
University of Waikato            electric mail: ldo@waikato.ac.nz
Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00

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

>From dubois@uakari.primate.wisc.edu (Paul DuBois)
Subject: TransSkel 3.18 (THINK C, Metrowerks) now available
Date: 21 Nov 1994 10:56:42 -0600
Organization: Castra Parvulorum

Release 3.18 of TransSkel, a skeleton for Macintosh application development
under THINK C or Metrowerks C, is now available.

This release is quite similar to release 3.17, with the following differences:

- It compiles under either the universal headers or the old Apple headers.
Prior releases compiled only under the old headers.
- It compiles under THINK C or Metrowerks C.  Prior releases were written
for THINK C only.
- It can be used to generate either 68K or PowerPC code.  Prior releases
worked only for 68K code.  PowerPC code generation has been tested only
with Metrowerks C
- 3.17 broke compatibility of the THINK C library with THINK Pascal programs.
3.18 fixes that.

TransDisplay 3.06 and TransEdit 3.06 are also available now, and have been
updated in similar ways.  TransDisplay and TransEdit are modules that can
be dropped into TransSkel-based projects to provide display-only or editable
text windows.

TransSkel, TransDisplay, and TransEdit are available via any of the following:

anonymous ftp to ftp.primate.wisc.edu (under /pub/mac/TransSkel)

gopher to gopher.primate.wisc.edu (select "Primate Center Software Archives")

WWW using URL http://www.primate.wisc.edu/ (select "Primate Center Software
Archives")


-- 
Paul DuBois
dubois@primate.wisc.edu

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

>From juez@informatik.fh-augsburg.de (Juez Markus)
Subject: how can I implement-program Plug-Ins?
Date: 9 Nov 1994 13:23:04 GMT
Organization: Fachhochschule Augsburg, Germany

How can I implement Plug-Ins into my program (like filters in the Photoshop)?
What kind of data-structures and functions do I need? 
Will I need an extra program to generate the moduls (like the filters)?

Many Thanks for hints


+++++++++++++++++++++++++++

>From nick+@pitt.edu ( nick.c )
Date: Wed, 09 Nov 1994 12:59:24 -0500
Organization: The Pitt, Chemistry

In article <39qifo$7ju@av2.rz.fh-augsburg.de>,
juez@informatik.fh-augsburg.de (Juez Markus) wrote:

> How can I implement Plug-Ins into my program (like filters in the Photoshop)?
> What kind of data-structures and functions do I need? 
> Will I need an extra program to generate the moduls (like the filters)?
> 
> Many Thanks for hints


   Don't really know, but can think of a few possibilities.
      If it's simple, you can create "preferences" like files,
      that toggle on or off or configure pre-made functionality
      it the program.  That would be the easiest, and if your just
      need file translation filters, it would be doable.  If not,
      compile code resources (an option in the compiler in both
      CW & SC++), imbed those resources in files with the type and
      creator set for your app, then have the app scan a certain
      folder in the same folder (or in the preference folder) as
      your app on startup, and load those code resources that
      it finds.  Not sure about the interface between those resources
      and your app's code.  Maybe just call a function with the same name
      as the module as it loads them, and that function tells your
      program what functions in your app the module interfaces to.
      Then you'd have to do negotiation within your program to 
      make sure two modules don't step on each others feet.
      Hmm...

    Might be easier if you mentioned what the modules are supposed to
      do.  Are they just file translation filters, or do they have
      to have functionality of some kind?


 Internet: nick+@pitt.edu            _/   _/  _/  _/_/_/   _/   _/  
   eWorld: nick                     _/_/ _/  _/  _/   _/  _/_/_/ 
      CIS: 71232,766               _/ _/_/  _/  _/       _/ _/    
     http://www.pitt.edu/~nick/   _/   _/  _/   _/_/_/  _/   _/     
                    

+++++++++++++++++++++++++++

>From oster@netcom.com (David Phillip Oster)
Date: Wed, 9 Nov 1994 20:57:52 GMT
Organization: Netcom Online Communications Services (408-241-9760 login: guest)


Here is what you need to do:
1.) Define a storage location for the plug-ins. such as, for an application
called Foo, a folder called "Foo Pouch", which your installer creates,
and which you search for in the same folder as your application, the
preferences folder, and the System Folder (for System 6 (no preferences))
the name of the pouch folder should be in a 'STR ' or 'STR#' resource for
easy internationalization.

2.) Define a resource type to hold your plug-in exectuable code. You
should allow any resID number, since some development systems have
restrictions on which id numbers can be used for multi-segment code resources.

Decide whether you will allow multiple code resources per file.
For example, Photoshop lets you bundle an import resource, an export
resource, and a filter into the same file, each is its own resource type.
It uses the resource name to tell the user, so each has its own name.

3.) Decide on the user interface to plug-ins. Commonly, at program
start-up, you scan the pouch and collect all the files of the correct
types. Then you scan for appropriate code resources, then put the names
of the resources in the menus. You can also use the file names, or
run the code resources and ask them for the correct name.

4.) decide on the programmer's interface. MPW likes to pass parameters
as longs, and pascal development systems usually can't generate C
interfaces, so your best bet is to have the entry point of your code 
resource be something like:

extern pascal long PlugIn(long selector, CallbackPtr callback, 
	long param1, long param2, long param3, long refcon);

where params 1 through 3 will have specific meanings depending upon
which function selector is asking to be performed.

CallbackPtr is something like this:
typedef struct CallbackRec{
	DrawFunc	erase;
	DrawFunc	paint;
}CallbackRec, *CallbackPtr;

where DrawFunc is something like:
typedef pascal void (*DrawFunc)(Rect *);

This is the place where you define services that your application will
perform when asked to by the code resource of the plug-in.

You'll need to define a bunch of selectors for what you want the plug-in
to do.

You should definately give the plug-in an Init selector, and a 
dispose selector, and have Init return an error or a refcon, which
will be passed back to the plug-in on each call, so the plug-in
can have some persistent storage.  You should definately set the
CurResFile to the plug-in's file while it is running, so it can 
easily get at any resources it needs.

The Init selector should pass the interface version in param1
and the program version in param2, so that the plug-in can cope
with different versions of your program.

The actual call to the plug-in looks like:
	h = GetResource('PLUG', 1);
	HLock(h);
	xh = StripAddress(h);
	((PlugInFunc) *xh)(kInit, callbacks, kInterfaceVer1, kProgVer1, 0, 0);
	HUnlock(h);
-- 
- ------- oster@netcom.com ----------
"A man hears what he wants to hear and misremembers the rest."
     -- Paul Simon, ("The Boxer")


+++++++++++++++++++++++++++

>From jonasw@lysator.liu.se (Jonas Wallden)
Date: 10 Nov 1994 10:22:19 GMT
Organization: (none)

juez@informatik.fh-augsburg.de (Juez Markus) writes:

>How can I implement Plug-Ins into my program (like filters in the Photoshop)?
>What kind of data-structures and functions do I need? 
>Will I need an extra program to generate the moduls (like the filters)?
>
>Many Thanks for hints

Plug-in code is not too hard to write. Basically you load resources
from external files and call them with a predefined set of parameters.

If you are writing your own application you are free to design this
calling interface any way you like, but if you are writing e.g. BBEdit
externals you should read the documentation to see what the application
requires from your code.

Now, you asked for the first case, and here are some hints:

* Keep a list of external files that you open so you can set the
  correct resource file before calling the code. This will make life
  easier for the external in case it needs to access resources in it's
  own file.

* Define an API that can be extended in future versions. Parameter blocks
  are great for this; just place a version number first in the parameter
  block so the extension knows which fields in the pb that are available.
  When you call you simply pass a pointer to this block (whose size can
  vary among different versions).

* Provide a parameter block with callbacks. This is a list of function
  pointers that point to routines in your application that the extension
  can call to request services from you. This can e.g. be window handling
  in case you need to handle floating windows.

* Make sure the resources are locked down while you call them. Also call
  StripAddress on the handle to ensure compatibility with 24-bit systems.

* Define a number of messages that you pass to the extension. Look at some
  of Apple's xDEF docs to get inspiration. It is very useful for the
  extension to know when it's called the first time, and when it's about
  to be closed down so it can allocate and dispose of memory that it needs.

  Also define error messages, or use the error codes already defined for
  other Toolbox managers.

* Write a header file that you ship together with your application so
  other programmers can compile their extensions. Declare all C routines
  as 'pascal'.

* Document required resources, file types/creators and other stuff that
  your application expects to find in the external resource files as well.

There are a number of sample applications that you can look at. E.g., check
out the CodeWarrior CD which includes instructions on how to write code that
work on PowerPC Macs, and how to call PPC from 68K and vice versa.

BBEdit is also a good place to start. Read the programmer documentation that
is included to get an idea of how things work.

Finally, writing externals is just like writing any other code resource
and can be done in Pascal or C. Note though that Pascal is not as flexible
so you might need some inline assembly to use e.g. callback routines.

Disclaimer: those who have seen my shareware application PowerScan knows
that I don't follow all of the recommendations myself. This is because I've
learned most things by doing it the wrong way... :-)

...............   .......................   ...........   ...............
 jonas wallden           internet            applelink       phone/fax
   mac hacker      jonasw@lysator.liu.se      sw1369       +46-13-176084

+++++++++++++++++++++++++++

>From sandvik@apple.com (Kent Sandvik)
Date: Mon, 21 Nov 1994 18:05:51 -0800
Organization: Apple Computer, Inc. Developer Technical Support

I would like to know why developers in general are not interested to use
the Component Manager for plug-in material. Let me know more of the pros
and cons so I could provide feedback to engineering and marketing about
this all.

Cheers, Kent

-- 
Kent Sandvik   sandvik@apple.com   New Media Analyst/Programmer
Private activities on Internet.

+++++++++++++++++++++++++++

>From spencerl@crl.com (Spencer Low)
Date: 21 Nov 1994 22:08:01 -0800
Organization: LowTek Creations

Kent Sandvik (sandvik@apple.com) wrote:
> I would like to know why developers in general are not interested to use
> the Component Manager for plug-in material. Let me know more of the pros
> and cons so I could provide feedback to engineering and marketing about
> this all.

I just got into this thread, but...

One reason I'm reluctant to use the Component Manager is all the 
UniversalProcPtr stuff needed for use with the Universal Headers. It's 
not as easy as, say a Control Strip plug-in. I do think that components 
are easier to use in an application (OpenComponent, call the stuff, 
CloseComponent). Another con is the glue necessary for PowerMac native 
components (I've read about this in the Component Manager 3 Q/A Tech Note).

Spencer
-- 
________________________________________________________________________
    Spencer Low ------- LowTek Creations ------- spencerl@crl.com

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

>From tjb@acpub.duke.edu (Thomas J. Bryce)
Subject: using HLock before memcpy
Date: 19 Nov 1994 03:04:19 GMT
Organization: Duke University, Durham, NC, USA


I notice people usually surround a memcpy statement of a handle or
pointer with HLock and HUnlock. Is this necessary always? 

I'm inclined to believe, YES, but I'd like to hear it stated directly rather
than assuming it from seeing it done all the time.

It seems you can't rely on the memory to not be moved if you copy the
pointer from the handle and use it for a while, as in memcpy (*handle1,
*handle2,size);

Could someone verify this for me?

Tom


+++++++++++++++++++++++++++

>From wem53067@uxa.cso.uiuc.edu (TheBard)
Date: Fri, 18 Nov 1994 21:52:29 -0600
Organization: Bard 'O Matic Software

In article <3ajpvj$49l@news.duke.edu>, tjb@acpub.duke.edu (Thomas J.
Bryce) wrote:
> It seems you can't rely on the memory to not be moved if you copy the
> pointer from the handle and use it for a while, as in memcpy (*handle1,
> *handle2,size);
> 
> Could someone verify this for me?

I'll verify it. :) You see, the whole idea of using handles is to let the
ystem move memory around. That way you don't get a swiss-cheese looking
memory map. Now, if for some reason you don't lock the handles, and then
you try to copy.. the one you are copying to or from may move and then you
are writting to or from  some other place than you wanted to. Yuk.

Lock your handles :)

Wayde

-- 
=====================================================================
--=The Bard=--
"Just remember, no matter where you go, there you are!"
- -------------------------------------------------------------------
PGP Public Key available upon request

+++++++++++++++++++++++++++

>From Jaeger@fquest.com (Brian Stern)
Date: 19 Nov 1994 05:52:41 GMT
Organization: The University of Texas at Austin, Austin, Texas

In article <3ajpvj$49l@news.duke.edu>, tjb@acpub.duke.edu (Thomas J.
Bryce) wrote:

< I notice people usually surround a memcpy statement of a handle or
< pointer with HLock and HUnlock. Is this necessary always? 
< 
< I'm inclined to believe, YES, but I'd like to hear it stated directly rather
< than assuming it from seeing it done all the time.
< 
< It seems you can't rely on the memory to not be moved if you copy the
< pointer from the handle and use it for a while, as in memcpy (*handle1,
< *handle2,size);
< 
< Could someone verify this for me?
< 
< Tom

If the memcopy routine is in a non-resident segment then calling it could
cause the segment to be loaded.  I assume that it's in the ANSI lib.  If
you make sure that the segment containing ANSI is loaded before you call
memcopy and is never unloaded then you're probably safe and don't need to
lock the handle.  

I don't know how memcopy is implemented.  It's probably a bytewise copy,
something like *dest++ = *src++.  Code like that won't cause memory to
move.  

Many people would rather be safe than sorry.  If other people are likely
to use your code in other projects where ANSI may not be loaded and locked
then you're better off locking the handle.

Good luck,

-- 
Brian  Stern  :-{)}
Toolbox commando and Menu bard
Jaeger@fquest.com

+++++++++++++++++++++++++++

>From pgontier@novell.com (Pete Gontier)
Date: Mon, 21 Nov 1994 12:29:07 -0700
Organization: Novell, Inc., Walnut Creek/Macintosh Site

In article <3ajpvj$49l@news.duke.edu>, tjb@acpub.duke.edu (Thomas J.
Bryce) wrote:

> I notice people usually surround a memcpy statement of a handle or
> pointer with HLock and HUnlock. Is this necessary always? 

Depends on what code segment 'memcpy' lives in. If it's in another
segment, the handle might move when that segment is loaded. Since there
isn't a good way to tell if 'memcpy' is in the same segement as the code
calling it, 'HLock' is a good idea. I just call 'BlockMoveData'; it's a
trap call, so no segment will load. The net savings are one, maybe two,
trap calls over the usual 'HGetState'/'HLock'/'HUnlock' sequence, and
'BlockMoveData' is generally much faster for surprisingly small blocks.

-- 

 Views expressed here do not necessarily reflect those of my employer.

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

End of C.S.M.P. Digest
**********************