From: pottier@clipper.ens.fr (Francois Pottier)
Subject: csmp-digest-v3-028
Date: Wed, 18 May 94 14:13:10 MET DST

C.S.M.P. Digest             Wed, 18 May 94       Volume 3 : Issue 28
 
Today's Topics:
 
        CRC-16 routine in C for native code
        CodeWarrior Gold Education Price
        How to write a bullet-proof lib?
        PixMap to mask
        Posting an event to another application?
        Shared memory...
        Unmounting all volumes?



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 as comp.sys.mac.programmer.src.


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

>From satcomm@aol.com (SatComm)
Subject: CRC-16 routine in C for native code
Date: 30 Apr 1994 14:40:08 -0400
Organization: America Online, Inc. (1-800-827-6364)

I'm looking to replace some old code in assembly that calculated the standard
Xmodem/MacBinary CRC-16 stuff.  Unfortunately, I think I threw away all
remnants of my CRC stuff when I discovered the assembly routine.  Does anyone
have a CRC routine for this in C?

Thanks.

satcomm@aol.com

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

>From david@oahu.cs.ucla.edu (David Dantowitz)
Date: Sun, 01 May 94 16:36:57 GMT
Organization: UCLA, Computer Science Department

Here's some code and information on CRCs I put together some years
back.  It is in the public domain.

David

- --------- cut here --------------
/*

   Computing CRCs

   This set of implementations was written by David M. Dantowitz, and
   has been placed in the public domain, to be used at the user's
   discretion.  The original code was implemented in Turbo Pascal 3.0
   this submission is a version written in C.

   This program demonstrates various ways by which Cyclic
   Redundancy Checks (CRC) may be computed and their relative speeds.


   CRC polynomials in this program are represented by replacing
   each term that is non-zero with a 1 and each zero term with a 0.
   Note that the highest order bits represent the low order terms 
   of the polynomial.

   Thus X^3+X^1+1 becomes 1101 and X^4+X^1+1 becomes 11001.

   Now, since all polynomials have a highest term (X^a) we drop the
   highest term during computation (shift right one bit, dropping
   the low bit).


   Here are some examples of conversion from symbolic to binary
   representation (but not necessarily polynomials with desirable
   CRC properties):


           Polynomial                Representation     Hex

          X^5 + X^2 + 1                  10100          $14

            X^7 + 1                     1000000         $40

          X^3+X^2+X^1+1                   111           $7

          X^6+X^5+X^3+1                 100101          $25


   For a good discussion of polynomial selection see "Cyclic
   Codes for Error Detection", by W. W. Peterson and
   D. T. Brown, Proceedings of the IEEE, volume 49, pp 228-235,
   January 1961.

   A reference on table driven CRC computation is "A Cyclic
   Redundancy Checking (CRC) Algorithm" by A. B. Marton and
   T. K. Frambs, The Honeywell Computer Journal, volume 5,
   number 3, 1971.

   Also used to prepare these examples was "Computer Networks",
   by Andrew S. Tanenbaum, Prentice Hall, Inc.  Englewood Cliffs,
   New Jersey, 1981.

   The following four polynomials are international standards:


        CRC-12 = X^12 + X^11 + X^3 + X^2 + X^1 + 1
        CRC-16 = X^16 + X^15 + X^2 + 1
        CRC-CCITT = X^16 + X^12 + X^5 + 1
        CCITT-32 = X^32 + X^26 + X^23 + X^22 + X^16 + X^12 + X^11 + X^10 +
                   X^8 + X^7 + X^5 + X^4 + X^2 + X^1 + 1

   In Binary and hexadecimal :

                   Binary                     Hex

        CRC-12    = 1111 0000 0001           $0F01
        CRC-16    = 1010 0000 0000 0001      $A001
        CRC-CCITT = 1000 0100 0000 1000      $8404    (Used below)
        CCITT-32  = 1110 1101 1011 1000 
                    1000 0011 0010 0000      $EDB88320

   The first is used with 6-bit characters and the second two
   with 8-bit characters.  All of the above will detect any
   odd number of errors.  The second two will catch all 16-bit
   bursts, a high percentage of 17-bit bursts (~99.997%) and
   also a large percentage of 18-bit or larger bursts (~99.998%).
   The paper mentioned above (Peterson and Brown) discusses how 
   to compute the statistics presented which have been quoted 
   from Tanenbaum.

   (A burst of length N is defined a sequence of N bits, where
   the first and last bits are incorrect and the bits in the
   middle are any possible combination of correct and incorrect.
   See the paper by Peterson and Brown for more information)

   Note that when using a polynomial of degree N, the CRC is the
   first N bits of the value returned by the routines below.
   (e.g. with CRC-12, the CRC is bits 0 to 11 of the CRC value,
   with the other two mentioned above, the CRC is all 16 bits.)


   Here is a quick idea of what is being calculated ...

   The CRC is the residual from division of the data stream by
   the CRC polynomial.  The data stream is also thought of as a
   polynomial, with the highest order term being the lowest bit
   of the first byte of the data stream and the lowest order term
   of the polynomial being the high bit of the last byte of data.
   The actual division is performed on the data stream polynomial
   multiplied by X^y where y is the degree of the CRC polynomial.


   All math used to compute CRCs is done modulo 2.  This means the
   following relationships are used:


                0+0=0    0+1=1    1+0=1    1+1=0   (XOR)
                0-0=0    0-1=1    1-0=1    1-1=0   (XOR)
                0*0=0    0*1=0    1*0=0    1*1=1   (AND)

   Thus addition and subtraction have NO carries or borrows.

                                             
   Here is a sample computation showing the actual division.


   Polynomial = X^4+X^3+1; Data = $94.

   The division performed is 1001 into 0010 1001.  Notice that
   the highest order terms of the data polynomial are the lowest
   order bits of the data stream.  We will also multiply the
   dividend by X^4 as noted above:

             1011011  - The quotient is not important and is discarded.
   1001/001010010000
         -1001  ----    The extra 0s result from multiplying the data by X^4
          ----
            1101 <--    The code below calculates this value
           -1001
            ----
             1000
            -1001
             ----
                1000
               -1001
                ----
                0001  This is the CRC (the residual from the division)!


   The code below does not shift the data by the number of bits
   equal to the degree of the CRC polynomial.  There is no ill effect
   caused by not doing this multiply.  Now, the result of the CRC computation
   is just the residue from the division of the data by the CRC.  


   None of the routines below appear to compute a division.  In the example
   above the subtractions are really XORs (pronounced exclusive OR).  XOR
   has the same behavior as +/- in modulo two arithmetic, so it is used
   in the computations.  The first CRC routine below (Simple_CRC) models
   the computation lucidly.  The other routines use various optimization
   techniques to speed the computation.


   CRC use ...

   The CRC is appended to the end of the original data stream (or stored
   separetely).  When the receiver gets the data stream, the CRC is again
   computed and matched against the received CRC, if the two do not match
   then an error has most likely occurred.  


   My address is

   David Dantowitz
   Dantowitz Consulting and Research
   P.O. Box 8105
   Englewood, NJ  07631

   (201) Low-Bug-C
   AppleLink: Dantowitz
*/

#include <stdio.h>
#include <string.h>


#define INITIAL_CRC 0xFFFFFFFF


/*
   This result was obtained by calling make_crc_table(0xedb88320).
*/


int             crc_table[16] =
{
  0x00000000,
  0xfdb71064,
  0xfb6e20c8,
  0x06d930ac,
  0xf6dc4190,
  0x0b6b51f4,
  0x0db26158,
  0xf005713c,
  0xedb88320,
  0x100f9344,
  0x16d6a3e8,
  0xeb61b38c,
  0x1b64c2b0,
  0xe6d3d2d4,
  0xe00ae278,
  0x1dbdf21c
};



make_crc_table(crc_poly)
  int             crc_poly;
{
  int             i, val, result;

  for (val = 0; val < 16; val++)
  {
    result = val;

    for (i = 0; i < 4; i++)
      if (result & 1)
	result = (result >> 1) ^ crc_poly;
      else
	result >>= 1;

    crc_table[val] = result;

    printf("0x%08lx\n", result);
  }

}

int
compute_crc(old_crc, s, len)
  int             old_crc;
  char           *s;
  int             len;
{
  int             i;

  for (i = 0; i < len; i++)

  {
/*
   XOR in the data.
*/

    old_crc ^= s[i];
/*
   Perform the XORing for each nybble
*/
    old_crc = (old_crc >> 4) ^ crc_table[old_crc & 0x0f];
    old_crc = (old_crc >> 4) ^ crc_table[old_crc & 0x0f];
  }

  return (old_crc);
}

main()
{
  char            line[100];
  int             crc_val;
  int             len;

/*   make_crc_table(0xedb88320); done at compile time... */

/*
   initialize the crc -- start with this value each time you start
   a session.
*/
  crc_val = INITIAL_CRC;

  strcpy(line, "This will test the crc function");

  len = strlen(line);


  crc_val = compute_crc(crc_val, line, len);

/* 
   let's add MORE text to the CRC -- they can be cumulative across many
   blocks of data.
*/

  strcpy(line, "More text to add");

  len = strlen(line);

  crc_val = compute_crc(crc_val, line, len);

}

-- 
David Dantowitz
david@cs.ucla.edu

Singing Barbershop when I'm not doing parallel simulation

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

>From Bruce@hoult.actrix.gen.nz (Bruce Hoult)
Date: Mon, 2 May 1994 18:51:22 +1200 (NZST)
Organization: (none)

satcomm@aol.com (SatComm) writes:
> I'm looking to replace some old code in assembly that calculated the standard
> Xmodem/MacBinary CRC-16 stuff.  Unfortunately, I think I threw away all
> remnants of my CRC stuff when I discovered the assembly routine.  Does anyone
> have a CRC routine for this in C?

Here's a routine for checking the Macbinary header CRC.  I'm not sure what
XModem uses:

- --------------
#define CCITT_CRC_GEN	0x1021

short CalcCRC(register unsigned char *dataBuf, register long size)
{
	register unsigned short	crc = 0;
	register unsigned short	dataByte;
	register long i;
	
	while (size--)
	{
		dataByte = *dataBuf++ << 8;
		for (i = 8; i > 0; i--)
		{
			if ((dataByte ^ crc) & 0x8000)
				crc = (crc << 1) ^ CCITT_CRC_GEN;
			else
				crc <<= 1 ;
			dataByte <<= 1;
		}
	}
	return(crc);
}
- --------------


For my own use, I've recoded it slightly in a way that gives much better code
on unsophisticated compilers such as MPW C.  I was able to alternate operations
on different data, which should probably help a little on pipelined CPUs (I
don't know how much), and spelling things out a little more explicitely stopped
a lot of data moves etc that weren't needed.

Treating C as a two-address assembly language seems to help many compilers a
lot...  :-)

- --------------
#define CCITT_CRC_GEN	0x1021

short CalcCRC(register unsigned char *dataBuf, register long size)
{
	register unsigned long crc = 0;
	register unsigned long dataByte;
	register long i;
	
	while (--size >= 0)
	{
		dataByte = *dataBuf++;
		dataByte <<= 8;
		i = 8;
		do {	
			register long bit = dataByte;
			dataByte += dataByte;
			bit ^= crc;
			crc += crc;
			if (bit &= 0x8000)
				crc ^= CCITT_CRC_GEN;
		} while (--i);
	}
	return crc;
}
- --------------

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

>From Bruce@hoult.actrix.gen.nz (Bruce Hoult)
Date: Mon, 2 May 1994 19:15:41 +1200 (NZST)
Organization: (none)

satcomm@aol.com (SatComm) writes:
> I'm looking to replace some old code in assembly that calculated the standard
> Xmodem/MacBinary CRC-16 stuff.  Unfortunately, I think I threw away all
> remnants of my CRC stuff when I discovered the assembly routine.  Does anyone
> have a CRC routine for this in C?

Further to my last post, and to (hopefully) forstall email, yes I am aware
that a bit-by-bit algorithm for CRC isn't the fastest way to do it, no
matter how efficiently coded.

It was good enough for my purpose (which was checking a smallish Macbinary
header), and I was more interested in code size than in speed (for reasons
I won't go into...).

-- Bruce

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

>From cvafy002@csupomona.edu
Subject: CodeWarrior Gold Education Price
Date: 25 Apr 94 14:32:09 PST
Organization: California State Polytechnic University, Pomona

I have a friend who'd like to get CodeWarrior Gold at the education price (I
read it was $99). How would he go about getting it? He doesn't have internet
access. How can he find out if his College and/or he qualifies?


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

>From mwron@aol.com (MW Ron)
Date: 27 Apr 1994 21:16:03 -0400
Organization: America Online, Inc. (1-800-827-6364)

In article <1994Apr25.143209.1@clstac>, cvafy002@csupomona.edu writes:
>>I have a friend who'd like to get CodeWarrior Gold at the education price (I
read it was $99). How would he go about getting it? He doesn't have internet
access. How can he find out if his College and/or he qualifies?

I think this will be helpful to all of you strugling students.

For educational prices, BookMasters is our distributor and their phone number
is 1-800-247-6553 in the US. Educational pricing is as such:
 
                Gold    $99.00 US
                Silver  $79.00 US
                Bronze  $59.00 US
 
$15.00 shipping and handling US orders.
 
You must fax BookMasters proof that you are either a student or officially
affilliated with a University.  Their fax number is(419) 281-6883.

Ron Liechty
mwron@aol.com
Metrowerks Inc.

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

>From cs2ev@herts.ac.uk (Mas)
Date: 28 Apr 1994 17:29:59 +0100
Organization: University of Hertfordshire

  Dear all

    Please do tell me the difference between gold, silver & bronze
versions of codewarrior.  Thanks

Andre-John MAS


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

>From mwron@aol.com (MW Ron)
Date: 28 Apr 1994 20:46:02 -0400
Organization: America Online, Inc. (1-800-827-6364)

In article <2pooa7$dej@altair.herts.ac.uk>, cs2ev@herts.ac.uk (Mas) writes:

Please do tell me the difference between gold, silver & bronze versions of
codewarrior.  

>>GOLD    Includes all for 68K Macintosh and Power Macintosh as well
as 68K-hosted PowerPC compilers.  

SILVER   Includes all for PowerPC Only (no 68K Macintosh  compilers or
linkers)

BRONZE  Includes all for 68K Macintosh (no PowerPC compilers or
linkers) 

Ron Liechty
mwron@aol.com
Metrowerks Inc.

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

>From zee@fwi.uva.nl (Daniel vd Zee)
Date: 3 May 1994 14:15:03 GMT
Organization: FWI, University of Amsterdam

mwron@aol.com (MW Ron) writes:
>For educational prices, BookMasters is our distributor and their phone number
>is 1-800-247-6553 in the US. Educational pricing is as such:
> 
>                Gold    $99.00 US
>                Silver  $79.00 US
>                Bronze  $59.00 US
> 
>$15.00 shipping and handling US orders.
How about non-US students, are the pricing and the distributor the same and
do i have to get some kind of internalional student card to order?

Thanx,
Daniel (zee@fwi.uva.nl)



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

>From mwron@aol.com (MW Ron)
Date: 4 May 1994 17:10:03 -0400
Organization: America Online, Inc. (1-800-827-6364)

In article <2q5m97$4dv@hermes.fwi.uva.nl>, zee@fwi.uva.nl (Daniel vd Zee)
writes:
>> How about non-US students, are the pricing and the distributor the same and
do i have to get some kind of internalional student card to order?

I do not know if we have  or do not have any  international educational
discounts you would have to contact one of the following to find out what the
item is in your particular country.
 
Japan       -  B.U.G. in Sapporo,  Applelink = BUGPLAN.DVJ
 
Australia   -  Techflow in Australia, Applelink = TECHFLOW
 
Germay      -  pandasoft in Berlin, Germany, telephone= (49) 3031 5913 16
 
All others,   BookMasters

                       U.S./Canada:   1-800-247-6553
                       International:   1-419-281-1802
                       Fax No.:   1-419-281-6883
Everywhere else in the world, including Europe out of Germany should be taken
direct through our distributor BookMasters.

Ron Liechty
mwron@aol.com
Metrowerks Inc.

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

>From neeri@iis.ee.ethz.ch (Matthias Neeracher)
Date: 4 May 1994 22:34:08 GMT
Organization: Swiss Federal Institute of Technology (ETHZ)

mwron@aol.com (MW Ron) writes:
>In article <2q5m97$4dv@hermes.fwi.uva.nl>, zee@fwi.uva.nl (Daniel vd Zee)
>writes:
>>> How about non-US students, are the pricing and the distributor the same and
>do i have to get some kind of internalional student card to order?

>I do not know if we have  or do not have any  international educational
>discounts 

Yes you do. It was no problem getting the Ed. Discount from Switzerland.

>All others,   BookMasters

>                       Fax No.:   1-419-281-6883

I got my copy of CodeWarrior from BookMasters. All I had to do was to fax
them a copy of my Student ID and my credit card number. They messed up
the reply to my first fax, but once I had sent the order, I got CW within
4 or 5 working days... well done, BookMasters!

Matthias

- ---
Matthias Neeracher                                      neeri@iis.ee.ethz.ch
  "Do not mess with any jumper you do not know about even if it is labeled
   SEX and FREE BEER" -- Dave Haynie

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

>From mpcline@cats.ucsc.edu (Matthew Paul Cline)
Subject: How to write a bullet-proof lib?
Date: 1 May 1994 23:35:06 GMT
Organization: University of California, Santa Cruz


	I am writing a library for the Mac, and would like it to be
bullet-proof.  When I say bullet proof, I'm using the term in a paranoid
way: if a customer calls up and complains that he/she can't use it to
make a desktop accessory, I can't say "Well, Apple recommends against
making a desktop accessory"; thus, I am not using any global variables
in the library (the only thing I know programming a desktop accessory).
Given my level of paranoia, is it possible to make a bullet-proof
library?  Or can I just get cloose to bullet-proof?  Any help would be
appreciated.

P.S.: Am I being paranoid, or is this the way you should go about
making a library?
-- 
X-phile, GATB               Have you hugged your shoggoth today?
GE d? p c++(+++) l++ u++ e+ m+ s/- n+(-) h+ f !g w+ t+ r y+

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

>From Matt Slot <fprefect@engin.umich.edu>
Date: 2 May 1994 07:15:30 GMT
Organization: University of Michigan

Matthew Paul Cline, mpcline@cats.ucsc.edu writes:

>P.S.: Am I being paranoid, or is this the way you should go about
>making a library?

I dont think its paranoid to put something out that you feel is stable
enough for others to want to use. If I get a library that I think
isn't of good quality or has some bugs in it, I dont feel comfortable
putting it into my own software.

When I wrote my Gamma Libs, I tried to test it on as many computers
as I could and make it work for the widest audience possible. These
are the things I learned:

	* Use simple interfaces and explain them well enough that others
	  can use them easily. Calling a function with wrong information
	  is an easy way to make anything barf.
	  
	* Comment the rest of your code (if provided) so users can see
	  what you are trying to do and can make improvments/changes as
	  fits their needs. (And bug feedback is much easier too)
	  
	* Use the best programming styles and follow the books, technotes
	  and advice you can find to make the software as compatible for
	  future versions.
	  
	* Use Gestalt and other calls make sure you are able to run in
	  a given environment and that your memory calls succeed. 
	  Returning error codes is very important.
	  
	* Try it out in a test app (making a demo program with source is
	  really nice), and run it with various system configurations
	  and extensions. Clearly define a minimum system that you require,
	  such as Mac Plus, System 6 or 7, or Color QD.
	  
	* Run it with heap scrambling and Even Better Bus Error. A user
	  trying to use software with my library complained that EBBE
	  flagged it... and it helped me to clean up some skanky pointer
	  arithmetic.
	  
	* Look for testers who will give you feedback before you make
	  the libs public... so you dont get your lib branded before it
	  gets popular. 
	  
	* Beg for programmer and user feedback, and try to work with others
	  who come to you with odd problems.
	  
Hope this helps... good luck with your library. 

Matt

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

>From gurgle@netcom.com (Pete Gontier)
Date: Mon, 2 May 1994 07:01:34 GMT
Organization: cellular

mpcline@cats.ucsc.edu (Matthew Paul Cline) writes:

>I am writing a library for the Mac, and would like it to be
>bullet-proof. ...thus, I am not using any global variables in the
>library (the only thing I know programming a desktop accessory).

It depends on what your library does, of course; I hope you're allowed
to post that so we can consider it. But, in general, you'll have to be
careful about some other things as well as global variables. If your
library is bigger than 32K, that's as bad as having globals, because any
number of segments greater than one causes many of the same problems as
global variables. Also be careful about calls which assume a valid A5
world. Many QuickDraw calls, for example, assume they own the A5 world.

One alternative which takes care of many problems is to provide two
copies of the library, one for A5-based projects (apps) and the other
for A4-based projects (everything else). Of course, under MPW, there is
no such thing as a code resource which has global variables, so even a
separate A4-based lib will not help you there, so it is better to avoid
globals altogether.

>P.S.: Am I being paranoid, or is this the way you should go about
>making a library?

Be paranoid. Be very very paranoid. :-)

As long as you understand low-level Mac programming, and as long as your
boss is happy with the notion of a reasonable beta period, you should be
OK. Your testers may not find bugs in your code, but they can probably
be counted on to have problems linking your library into their projects,
even if you do everything right! :-) Resolving any linking problems they
have which are actually your fault won't be half as nasty as any one bug
hunt.
-- 
 Pete Gontier, CTO, Integer Poet Software; gurgle@netcom.com

 "Reality is 50 million polygons per second." -- Alvy Ray Smith

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

>From d88-jwa@dront.nada.kth.se (Jon Wätte)
Date: 2 May 1994 08:50:58 GMT
Organization: The Royal Institute of Technology

In <2q29ai$hcl@lastactionhero.rs.itd.umich.edu> Matt Slot <fprefect@engin.umich.edu> writes:

>	* Use simple interfaces and explain them well enough that others
>	  can use them easily. Calling a function with wrong information
>	  is an easy way to make anything barf.

Have a debugging version of your library, which calls
Debugger() when it detects inconsistent data, parameters
out of range or unexpected return values BEFORE returning
them. A simple ASSERT() macro will do this!

>	* Use Gestalt and other calls make sure you are able to run in
>	  a given environment and that your memory calls succeed. 
>	  Returning error codes is very important.

Actually, the library probably shouldn't call Gestalt. Maybe a
separate little utility rouinte, in source, which just made
sure that everything's OK and returned a Boolean. Let the user's
code do the checking, for instance by calling your separate
utility routine.

>	* Beg for programmer and user feedback, and try to work with others
>	  who come to you with odd problems.

Especially: be responsive, and take every complaint seriously.
-- 
 -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe (on a Swedish scale) --

   There's no problem that can't be solved using brute-force algorithms
   and a sufficiently fast computer. Ergo, buy more hardware.    (NOT!)

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

>From mpcline@cats.ucsc.edu (Matthew Paul Cline)
Date: 2 May 1994 17:56:24 GMT
Organization: University of California, Santa Cruz


In <gurgleCp5y6M.4KL@netcom.com> gurgle@netcom.com (Pete Gontier) writes:

>mpcline@cats.ucsc.edu (Matthew Paul Cline) writes:

>>I am writing a library for the Mac, and would like it to be
>>bullet-proof. ...thus, I am not using any global variables in the
>>library (the only thing I know programming a desktop accessory).

>It depends on what your library does, of course; I hope you're allowed
>to post that so we can consider it.

It uses the Novell socket library on top of MacTCP.

>                                     But, in general, you'll have to be
>careful about some other things as well as global variables.

Since this is a port of an already existing library, I'm replacing all
global variables with static variables local to one file, and then
using get_GLOBAL() and set_GLOBAL() type function calls.  Does that
still have the problem of globals variables?  What about staic variables
within a procedure?

>                                                              If your
>library is bigger than 32K, that's as bad as having globals, because any
>number of segments greater than one causes many of the same problems as
>global variables.

I was planning on either using pluged-in code resources or using ASLM.
Would this also be bad for a library?

[snip]

>As long as you understand low-level Mac programming.

Hmmm, might have a problem here: I'm very new to the Mac.  My boss
basically hired me and said: "Here, go and learn everything you need to
know about the Mac and port our library to it."  Do you have any advice
on taking a crash course on low-level Mac programming?  Thanks in
advance.
-- 
X-phile, GATB               Have you hugged your shoggoth today?
GE d? p c++(+++) l++ u++ e+ m+ s/- n+(-) h+ f !g w+ t+ r y+

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

>From rmah@panix.com (Robert S. Mah)
Date: Mon, 02 May 1994 19:25:06 -0500
Organization: One Step Beyond

mpcline@cats.ucsc.edu (Matthew Paul Cline) wrote:

> Since this is a port of an already existing library, I'm replacing all
> global variables with static variables local to one file, and then
> using get_GLOBAL() and set_GLOBAL() type function calls.  Does that
> still have the problem of globals variables?  What about staic variables
> within a procedure?

Using statics will prevent name space pollution but the variables 
themselves are still referenced like globals.  That is they are accessed 
via offsets from register a5.  This will fall down if the code is being 
used in drivers, extensions or anything without a proper a5 world.

One option is to build two sets of libraries, one compiled using a5 
offsets and another using a4 offsets.  This is the technique used by
Symantec for their ANSI libraries, for example.

Cheers,
Rob
___________________________________________________________________________
Robert S. Mah  -=-  One Step Beyond  -=-  212-947-6507  -=-  rmah@panix.com

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

>From gurgle@netcom.com (Pete Gontier)
Date: Tue, 3 May 1994 18:40:42 GMT
Organization: cellular

mpcline@cats.ucsc.edu (Matthew Paul Cline) writes:

>It uses the Novell socket library on top of MacTCP.

OK, if you are porting, then you do need to be careful the code you are
porting doesn't use any global variables or use the 'static' modifier
for variables declared inside functions. It's possible to let the code
do these things, depending on the compiler in use, but you do need to be
aware of it so you can make sure it works -- or document how to make it
work, if it needs to be the caller's responsibility.

>Since this is a port of an already existing library, I'm replacing all
>global variables with static variables local to one file, and then
>using get_GLOBAL() and set_GLOBAL() type function calls. Does that
>still have the problem of globals variables?

Yes. What your routines are doing is hiding the globals, to a certain
extent, and that's marginally good in terms of maintainability. But
the machine doesn't care how maintainable your code is. :-) The hidden
globals are still globals in terms of where they are stored in memory
at run-time, that is at offsets from register A5 (apps) or register A4
(everything else).

>What about staic variables within a procedure?

Same problem, as I said above.

>>If your library is bigger than 32K, that's as bad as having globals,
>>because any number of segments greater than one causes many of the
>>same problems as global variables.

>I was planning on either using pluged-in code resources or using ASLM.
>Would this also be bad for a library?

I don't know much about ASLM except that it's not available in a fairly
large subset of installed Systems. And last I heard, it required MPW
C++, but that restriction has probably gone away by now.

But, if you are stuffing this code into a code resource, I can tell you
you won't have to concern yourself with two different versions of a
linkable library file any more. Your project will be A4-based, and you
can look up and understand the use of <SetUpA4.h> and be done with it.
You can also have code larger than 32K without much difficulty.

There are a couple of drawbacks to a code resource, though.

First, there's the fact that if you want more than one entry point,
you must create them yourself. In other words, the calling program
should probably call the code resource's main entry point with the
understanding that all that will result is a list of other entry points
into the code resource. I'm basically talking about a structure full of
function pointers here.

You will also have to write *another* library to be linked into programs
in order to avoid the chore of documenting for others how to call your
external code resource. (Believe me, writing this extra library is much
better than writing a document about code resources, because people will
call you for tech support no matter how good your doc is.) Fortunately,
this extra library will probably be simple enough that you can include
source code instead of a library file without revealing any trade
secrets.

TAKE-HOME MESSAGE:

I think your best bet is to do linkable libraries. They involve the
fewest technical headaches. You'll actually have to do three of them
(one for A5, one for A4, and one for PowerPC), but once you have done
one, the rest will follow pretty easily. You'll also have a 32K limit on
each library file, but you can always do more than one library file for
each kind of project.

>>As long as you understand low-level Mac programming...

>Hmmm, might have a problem here: I'm very new to the Mac. My boss
>basically hired me and said: "Here, go and learn everything you need to
>know about the Mac and port our library to it."

Tell your boss right away that aspects of this project are beyond your
field of expertise. The Macintosh issues are fairly simple for a very
experienced Mac programmer, but for someone new to the Mac, they can
be really ugly and take a lot more time than you would like. It will
be especially frustrating if you know all there is to know about the
networking aspects of the job and are constrained only by the Mac
aspects, because your boss may not understand that. If you tell her now,
you'll be able to plan ahead.

>Do you have any advice on taking a crash course on low-level Mac
>programming?

Of course, if there is no way to tell your boss, then you have just
embarked on the best low-level Mac programming course there is!
Experience: 12 units. Unfortunately, it's also the *only* course. Good
luck, and the net will be here when you need it. :-)
-- 
 Pete Gontier, CTO, Integer Poet Software; gurgle@netcom.com

 You thought Obfuscated C was confusing? Wait for Obfuscated C++!

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

>From adamnash@Xenon.Stanford.EDU (Adam Nash)
Subject: PixMap to mask
Date: 2 May 1994 06:28:05 GMT
Organization: Computer Science Department, Stanford University.


This may be really simple, but I wanted to check with the net first
in case this has been done a better way.  I'm converting a PixMap
(from a Pict) into a Mask for that item.  Now, if you call BitMapToRegion
you get a nasty speckle because, it translates anything more than "half
white" to white, when I want every non-white pixel to be black.
So, I was going to roll my own PixMapToMask, which went through the
pixel data and every time it hit a value > 0, it would put a black pixel in
a temporary BitMap, then call BitMapToRgn.

What do you think, all you sprite and offscreen gurus out there?

-Adam

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

>From daniel@unx.al.alcoa.com (David L. Daniel)
Date: 2 May 1994 13:51:41 GMT
Organization: Alcoa

In article <2q26hl$f72@Times.Stanford.EDU>, adamnash@Xenon.Stanford.EDU
(Adam Nash) wrote:
> 
> So, I was going to roll my own PixMapToMask, which went through the
> pixel data and every time it hit a value > 0, it would put a black pixel in
> a temporary BitMap, then call BitMapToRgn.

You could try using SeedCFill and CalcCMask, but I have had lots of trouble
using these - not just understanding them (which can be difficult), but
also with inconsistent results.  Others have expressed similar problems.
Here is some code that I use to do what you want.  No guarantees, but it
seems to work for me.  The argument "ignoreColor" is the pixel value
that you want to be ignored in creating a mask.  Good luck.


/* ######################################################################
*/
/* Make a mask for a PixMap (put it into a BitMap). */

void MakeMask(unsigned char ignoreColor, PixMapHandle pmHndl, BitMapHandle
bmHndl)
{
	short			i,j,k,bmBytes,pmBytes,bmBit,cols,rows;
	unsigned char	*bmPtr,*pmPtr;
	

	cols = (**pmHndl).bounds.right - (**pmHndl).bounds.left;
	rows = (**pmHndl).bounds.bottom - (**pmHndl).bounds.top;

	/*if the image rectangles are not the same dimensions, then return an
error*/
	if( ( cols != ((**bmHndl).bounds.right - (**bmHndl).bounds.left))
		|| ( rows != ((**bmHndl).bounds.bottom - (**bmHndl).bounds.top)) )
		return;
	
	/*Get the number of rowBytes for each image*/
	pmBytes = (0x1fff & (**pmHndl).rowBytes);
	bmBytes = (**bmHndl).rowBytes;

	/*Determine the starting address for the rectangles in each image*/
	pmPtr=(unsigned char*) ((**pmHndl).baseAddr +
pmBytes*(**pmHndl).bounds.top + (**pmHndl).bounds.left);
	bmPtr=(unsigned char*) ((**bmHndl).baseAddr +
bmBytes*(**bmHndl).bounds.top + 
			(short)((**bmHndl).bounds.left / 8) );

	/*Get the number of bytes to increment at the end of a row for each
image*/
	bmBit = (**bmHndl).bounds.left % 8;		/*the starting bit for the bitmap*/
	pmBytes -= cols;
	bmBytes -= (short)( (cols + bmBit - 1) / 8);
	
	bmBit = 7 - bmBit;	/*image bits are reversed from the order they are
counted*/
	
	/*Loop through each row of the images*/
	for(i=0; i<rows; i++, pmPtr+=pmBytes, bmPtr+=bmBytes) {
	
		/*Loop through each column of the images*/
		for(j=0, k=bmBit; j<cols; j++, pmPtr++, k--) {

			/*check and set the current bitmap bit, and the bitmap pointer*/
			if(k == -1) {
				bmPtr++;
				k = 7;
			}

			/*Check that the current PixMap pixel doesn't match the ignored color*/
			if(*pmPtr != ignoreColor) {
				*bmPtr |= (1 << k);
			} else {
				*bmPtr &= (0xff ^ (1 << k));
			}
		}
	}
}/*MakeMask*/


/* ######################################################################
*/


-David Daniel
daniel@unx.al.alcoa.com
#######################
This random sign-off was generated by a statistician.
#######################

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

>From Dwayne Knowles <dwayne@bagend.nacjack.gen.nz>
Subject: Posting an event to another application?
Date: Tue, 03 May 94 01:23:48 +1200
Organization: Society for the Prevention of Cruelty to Hobbits


Is there a way to post an event to another application - eg. a keydown 
event, without writing my own version of postEvent? I realise this is 
probably going to break with future system releases and is very uncool in 
general but I would like to be able to control an application remotely that 
isn't scriptable or anything. Is this possible?

Thanks.

--

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

>From mkb@remarque.berkeley.edu (Mike Brodhead)
Date: 2 May 1994 17:47:02 GMT
Organization: STEDT Project, Dept. o' Linguistics, UCBerkeley

In article <94050301234800677@bagend.nacjack.gen.nz>, Dwayne Knowles
<dwayne@bagend.nacjack.gen.nz> wrote:

> 
> Is there a way to post an event to another application - eg. a keydown 
> event, without writing my own version of postEvent? I realise this is 
> probably going to break with future system releases and is very uncool in 
> general but I would like to be able to control an application remotely that 
> isn't scriptable or anything. Is this possible?
> 
> Thanks.
> 
> --

I doubt you could do this easily from an app, but an INIT can surely
do it.  Witness QuickKeys.  In fact, you would probably be better off
installing QK on the machine and sending Apple Events to QK than doing
everything from scratch.  (I'm asuming this is for in-house use.)

If you want to code it yourself, you'll have to use the process manager
to check that the apropriate app is in the foreground before calling
PostEvent().  You could even force the app to the foreground.

__________________________________________________________________________
Mike Brodhead   (New! .sig now 33% shorter!)   <mkb@remarque.berkeley.edu> 
                    

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

>From Bruce@hoult.actrix.gen.nz (Bruce Hoult)
Date: Tue, 3 May 1994 14:15:05 +1200 (NZST)
Organization: (none)

Dwayne Knowles <dwayne@bagend.nacjack.gen.nz> writes:
> Is there a way to post an event to another application - eg. a keydown 
> event, without writing my own version of postEvent? I realise this is 
> probably going to break with future system releases and is very uncool in 
> general but I would like to be able to control an application remotely that 
> isn't scriptable or anything. Is this possible?

There is only one queue for mouse-downs, keydowns etc, and the frontmost
application always gets them -- if you want to post events for a particular
application then move it to the front (using the process manager) and then
use PostEvent in the normal way...

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

>From Dwayne Knowles <dwayne@bagend.nacjack.gen.nz>
Date: Thu, 05 May 94 01:46:59 +1200
Organization: Society for the Prevention of Cruelty to Hobbits


In article <mkb-020594104417@interzone.hip.berkeley.edu>, Mike Brodhead 
writes:

> 
> I doubt you could do this easily from an app, but an INIT can surely
> do it.  Witness QuickKeys.  In fact, you would probably be better off
> installing QK on the machine and sending Apple Events to QK than doing
> everything from scratch.  (I'm asuming this is for in-house use.)
> 
> If you want to code it yourself, you'll have to use the process manager
> to check that the apropriate app is in the foreground before calling
> PostEvent().  You could even force the app to the foreground.
> 

There are several problems with this however. The receiving app has to be 
forced into the foreground, and more importantly, postEvent doesn't let me 
post a keyDown event with the command key as a modifier - eg. post a menu 
key event.

Unfortunately I don't have Quickeys.

--

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

>From jeremyr@dcs.qmw.ac.uk (Jeremy Roussak;Guest of Distributed Systems Lab)
Date: Wed, 4 May 1994 21:04:28 GMT
Organization: Computer Science Dept, QMW, University of London

>> If you want to code it yourself, you'll have to use the process manager
>> to check that the apropriate app is in the foreground before calling
>> PostEvent().  You could even force the app to the foreground.

>There are several problems with this however. The receiving app has to be
>forced into the foreground, and more importantly, postEvent doesn't let me
>post a keyDown event with the command key as a modifier - eg. post a menu
>key event.

There's no way around forcing the app to the front, since, as
has been pointed out before, there's only one event queue and
all the events in it go to the frontmost app.

However, you can easily post an event with a specific set of
modifiers: use PPostEvent, which returns a pointer to the queue
element, and then modify the modifiers field.

Jeremy

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

>From mkb@remarque.berkeley.edu (Mike Brodhead)
Date: 5 May 1994 01:56:34 GMT
Organization: STEDT Project, Dept. o' Linguistics, UCBerkeley

In article <CpAqJJ.Jpz@dcs.qmw.ac.uk>, jeremyr@dcs.qmw.ac.uk (Jeremy
Roussak;Guest of Distributed Systems Lab) wrote:

> However, you can easily post an event with a specific set of
> modifiers: use PPostEvent, which returns a pointer to the queue
> element, and then modify the modifiers field.

This is true.  Still, if QuickKeys will do the job it is probably a
lot more cost effective to use it.  Divide the cost of QK by the number
of hours you expect to spend coding.  (Don't forget Hofstadter's law :)

What is your desired end result?  What will your code accomplish?
Who will use it?

__________________________________________________________________________
Mike Brodhead   (New! .sig now 33% shorter!)   <mkb@remarque.berkeley.edu> 
                    

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

>From Bruce@hoult.actrix.gen.nz (Bruce Hoult)
Date: Thu, 5 May 1994 18:36:54 +1200 (NZST)
Organization: (none)

Dwayne Knowles <dwayne@bagend.nacjack.gen.nz> writes:
> > If you want to code it yourself, you'll have to use the process manager
> > to check that the apropriate app is in the foreground before calling
> > PostEvent().  You could even force the app to the foreground.
> 
> 
> There are several problems with this however. The receiving app has to be 
> forced into the foreground, and more importantly, postEvent doesn't let me 
> post a keyDown event with the command key as a modifier - eg. post a menu 
> vkey event.

No, that's no problem -- you use PPostEvent, which returns a pointer to the
newly posted event queue element , and you can them diddle the modifiers.
Just don't call WaitNextEvent first :-)

-- Bruce

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

>From chris-b@cs.aukuni.ac.nz (Christopher David Burns)
Date: 5 May 1994 11:22:45 GMT
Organization: University of Auckland

Bruce@hoult.actrix.gen.nz (Bruce Hoult) writes:

>No, that's no problem -- you use PPostEvent, which returns a pointer to the
>newly posted event queue element , and you can them diddle the modifiers.
>Just don't call WaitNextEvent first :-)

Why don't you use the jGNEFilter mechanism instead of PPostEvent(). Simply
write an app that installs a jGNEFilter. This proc gets called just before
GetNextEvent() or WaitNextEvent() return. It has access to the boolean
result and the event record about to be returned. You can simply call
SetFrontProcess() and in your proc check curAppName (or maybe compare
GetFrontProcess() with the process you're interested in). When you find
that the right app is switched in, you can change the first null event to
a mouseDown (or whatever).
 
Simple. (I assume that the jGNEFilter is called on null events).
 
Give me a call if you want some code.
 
Cheers,
 
Chris B
- ---------------------------------------------------------------------
NewZealand:AucklandUniversity:ComputerScience:HyperMediaUnit:ChrisBurns
Internet:chris-b@cs.aukuni.ac.nz
Phone: +64 9 373-7599 x5602  Fax: +64 9 373-7453


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

>From zellers@berksys.com (Steve Zellers)
Date: 5 May 1994 21:17:01 GMT
Organization: Berkeley Systems, Inc.

In article <94050501465900688@bagend.nacjack.gen.nz>, Dwayne Knowles
<dwayne@bagend.nacjack.gen.nz> wrote:

> postEvent doesn't let me 
> post a keyDown event with the command key as a modifier - eg. post a menu 
> key event.

Check out PPostEvent.

Consider an INIT/background app combination.

-- 
Sr. Software Engineer
Berkeley Systems, Inc.

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

>From jedavis@CS.Stanford.EDU (James Edward Davis)
Date: 6 May 1994 14:20:57 -0500
Organization: UTexas Mail-to-News Gateway

References: <94050301234800677@bagend.nacjack.gen.nz>

Dwayne Knowles <dwayne@bagend.nacjack.gen.nz> writes:

>Is there a way to post an event to another application - eg. a keydown 
>event, without writing my own version of postEvent? I realise this is 
>probably going to break with future system releases and is very uncool in 
>general but I would like to be able to control an application remotely that 
>isn't scriptable or anything. Is this possible?

Well, the simple answer is use AutoType. An OSAX I worte that lets 
AppleScript send keyDowns with modifiers to other apps, so you can script 
non-scriptable applications. I use ppostevent essentially like others
in this thread described. Available at fine ftp sites everywhere.

-James Davis : jedavis@cs.stanford.edu



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

>From walkerj@math.scarolina.edu (Jim Walker)
Date: 4 May 1994 18:21:50 GMT
Organization: University of South Carolina - Columbia - Computer Science

Dwayne Knowles <dwayne@bagend.nacjack.gen.nz> writes:

(stuff deleted)
>There are several problems with this however. The receiving app has to be 
>forced into the foreground, and more importantly, postEvent doesn't let me 
>post a keyDown event with the command key as a modifier - eg. post a menu 
>key event.

PPostEvent (not a typo!) does allow you to post a keyDown event with
modifiers.
--

 -- Jim Walker  USC Dept. of Math.  walkerj@math.scarolina.edu

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

>From dnebing@bgsu.edu (  Mr. Neb)
Subject: Shared memory...
Date: 28 Apr 1994 02:04:11 GMT
Organization: Bowling Green State University

  Here's a good one...

  I have a component which can be opened multiple times.  I don't want
the components to have to allocate the same memory each time (they
all share a common resource (a picture) that I don't want multiple
copies of floating around in memory).  Anyone have a good solution
for setting up a shared buffer between the components?

Thanks in advance,

Dave Nebinger

============================================================
Dave Nebinger                    dnebing@andy.bgsu.edu
Network Manager, Biology Dept.   dnebing@opie.bgsu.edu
Bowling Green State University   dnebing@bgsuopie (bitnet)
Bowling Green, OH 43403          #include <std_disclaimer.h>

             *THE* alt.sources.mac supporter!

-- 
============================================================
Dave Nebinger                    dnebing@andy.bgsu.edu
Network Manager, Biology Dept.   dnebing@opie.bgsu.edu
Bowling Green State University   dnebing@bgsuopie (bitnet)

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

>From devon_hubbard@taligent.com (Devon Hubbard)
Date: Thu, 28 Apr 1994 17:35:31 GMT
Organization: Taligent, Inc.

In article <2pn5ir$rcm@falcon.bgsu.edu>, dnebing@bgsu.edu (  Mr. Neb)
wrote:

>   Here's a good one...
> 
>   I have a component which can be opened multiple times.  I don't want
> the components to have to allocate the same memory each time (they
> all share a common resource (a picture) that I don't want multiple
> copies of floating around in memory).  Anyone have a good solution
> for setting up a shared buffer between the components?
> 
> Thanks in advance,
> 
> Dave Nebinger
> 
> ============================================================
> Dave Nebinger                    dnebing@andy.bgsu.edu
> Network Manager, Biology Dept.   dnebing@opie.bgsu.edu
> Bowling Green State University   dnebing@bgsuopie (bitnet)
> Bowling Green, OH 43403          #include <std_disclaimer.h>
> 
>              *THE* alt.sources.mac supporter!
> 

Install your own _Gestalt selector.  Whichever process is first, it
installs the selector.  The other checks for it's existance.  If there, the
selector returns the address of a struct that contains whatever you want
(i.e. addresses of shared memory blocks).  Any of your processes can get to
it.  If you're starting and quitting apps, allocate the memory in the
system heap so it'll stick around.  Just be friendly and clean up the
memory when everything's done.

dEVoN

- ------------------------------------------------------------------------
Devon Hubbard                                                Silicon Pilot
devon_hubbard@taligent.com                                   Taligent, Inc

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

>From sblack@us.oracle.com (Steven T. Black)
Date: 28 Apr 94 22:15:44 GMT
Organization: Oracle Corporation

In article <devon_hubbard-280494093531@saucer.taligent.com>
devon_hubbard@taligent.com (Devon Hubbard) writes:

> In article <2pn5ir$rcm@falcon.bgsu.edu>, dnebing@bgsu.edu (  Mr. Neb)
> wrote:
> 
> >   Here's a good one...
> > 
> >   I have a component which can be opened multiple times.  I don't want
> > the components to have to allocate the same memory each time (they
> > all share a common resource (a picture) that I don't want multiple
> > copies of floating around in memory).  Anyone have a good solution
> > for setting up a shared buffer between the components?
> > 
> > Thanks in advance,
> > 
> > Dave Nebinger
> > 
> > ============================================================
> > Dave Nebinger                    dnebing@andy.bgsu.edu
> > Network Manager, Biology Dept.   dnebing@opie.bgsu.edu
> > Bowling Green State University   dnebing@bgsuopie (bitnet)
> > Bowling Green, OH 43403          #include <std_disclaimer.h>
> > 
> >              *THE* alt.sources.mac supporter!
> > 
> 
> Install your own _Gestalt selector.  Whichever process is first, it
> installs the selector.  The other checks for it's existance.  If there, the
> selector returns the address of a struct that contains whatever you want
> (i.e. addresses of shared memory blocks).  Any of your processes can get to
> it.  If you're starting and quitting apps, allocate the memory in the
> system heap so it'll stick around.  Just be friendly and clean up the
> memory when everything's done.
> 
> dEVoN
> 
> --------------------------------------------------------------------------
> Devon Hubbard                                                Silicon Pilot
> devon_hubbard@taligent.com                                   Taligent, Inc

You can also use the ASLM (Shared Library Manager) to store the
resource in a library, and have a routine that returns the address of
the PICT.  This has the advantage that the ASLM can monitor how many
clients are using the PICT, and so won't flush it from memory when the
original app that called it quits if other apps are still referencing
it.  It also takes care of flushing it from memory when it is no longer
needed.

- ----------------------------------------------------------------------
--
Steven T. Black                                     Lead Technical
Staff
sblack@us.oracle.com                                Oracle Desktop
Products

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

>From dnebing@falcon.bgsu.edu.bgsu.edu (  Mr. Neb,217 LSC,3722332,3531532)
Date: 29 Apr 1994 15:42:56 GMT
Organization: Bowling Green State University

sblack@us.oracle.com (Steven T. Black) writes:
> You can also use the ASLM (Shared Library Manager) to store the
> resource in a library, and have a routine that returns the address of
> the PICT.  This has the advantage that the ASLM can monitor how many
> clients are using the PICT, and so won't flush it from memory when the
> original app that called it quits if other apps are still referencing
> it.  It also takes care of flushing it from memory when it is no longer
> needed.

  This assumes the following:

    1.  That somehow you have the ASLM headers and libs necessary to
do so.

    2.  That the user has the ASLM or that Apple will give you a
license to distribute it in your shareware/freeware.


  I would love to use the ASLM because it would simplify my life
a great deal.  Currently I am implementing my package as a bunch
of components because Apple chooses to make me pay for the headers
and libraries needed to use the ASLM.

  The way I figure it, if Apple wanted me to use new functionality
within the system then they would provide the headerws and libs
necessary to do so.

  I can't even get the Universal Headers without purchasing a
major upgrade.

  Without the necessary headers, my stuff won't use the
DragMgr, PowerTalk, etc.  So people who use my stuff won't see
any reason to go buy the components from Apple.  So you tell
me who is really hurt by charging for these simple development
products.  Like I was quoted in the latest MacWEEK, I don't
expect to get the components for free.  But I don't think that
the headers and libs needed to implement the functionality of
those components is too much to ask for.

============================================================
Dave Nebinger                    dnebing@andy.bgsu.edu
Network Manager, Biology Dept.   dnebing@opie.bgsu.edu
Bowling Green State University   dnebing@bgsuopie (bitnet)
Bowling Green, OH 43403          #include <std_disclaimer.h>

             *THE* alt.sources.mac supporter!
-- 
============================================================
Dave Nebinger                    dnebing@andy.bgsu.edu
Network Manager, Biology Dept.   dnebing@opie.bgsu.edu
Bowling Green State University   dnebing@bgsuopie (bitnet)

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

>From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
Date: 30 Apr 94 15:01:20 +1200
Organization: University of Waikato, Hamilton, New Zealand

In article <2pn5ir$rcm@falcon.bgsu.edu>, dnebing@bgsu.edu (  Mr. Neb) writes:
>
>   I have a component which can be opened multiple times.  I don't want
> the components to have to allocate the same memory each time (they
> all share a common resource (a picture) that I don't want multiple
> copies of floating around in memory).  Anyone have a good solution
> for setting up a shared buffer between the components?

You could use SetComponentRefcon and GetComponentRefcon. The Component Manager
documentation makes it clear that a component only has a single Refcon value,
no matter how many instances are open.

If you want to dispose of the storage when the last instance is closed,
you can just call CountComponentInstances on yourself in your CloseComponent
handler. I assume the count isn't decremented until your CloseComponent
handler returns, in which case the value to check for is 1. If the count
_is_ decremented before entering your CloseComponent handler, then the value
to check for is 0.

Or you could avoid the question and maintain your own reference count...

Lawrence D'Oliveiro                       fone: +64-7-856-2889
Info & Tech Services Division              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+12:00

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

>From jim_reekes@quickmail.apple.com (Jim Reekes)
Date: Tue, 3 May 1994 19:56:15 GMT
Organization: Apple Computer, Inc.

In article <1994Apr30.150120.28180@waikato.ac.nz>, ldo@waikato.ac.nz
(Lawrence D'Oliveiro, Waikato University) wrote:
> 
> In article <2pn5ir$rcm@falcon.bgsu.edu>, dnebing@bgsu.edu (  Mr. Neb) writes:
> >
> >   I have a component which can be opened multiple times.  I don't want
> > the components to have to allocate the same memory each time (they
> > all share a common resource (a picture) that I don't want multiple
> > copies of floating around in memory).  Anyone have a good solution
> > for setting up a shared buffer between the components?
> 
> You could use SetComponentRefcon and GetComponentRefcon. The Component Manager
> documentation makes it clear that a component only has a single Refcon value,
> no matter how many instances are open.
> 
> If you want to dispose of the storage when the last instance is closed,
> you can just call CountComponentInstances on yourself in your CloseComponent
> handler. I assume the count isn't decremented until your CloseComponent
> handler returns, in which case the value to check for is 1. If the count
> _is_ decremented before entering your CloseComponent handler, then the value
> to check for is 0.
> 
> Or you could avoid the question and maintain your own reference count...
> 
> Lawrence D'Oliveiro                       fone: +64-7-856-2889
> Info & Tech Services Division              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+12:00

Lawrence is right. For components, the refCon was designed exactly for this
purpose. Only one thing to consider, if the system heap is tight and cannot
load your component there, then it will be "cloned" into the current
application heap (the heap that is responsible for opening it). When a
component is cloned it will not carry it's refCon from the parent. In this
case you need to check by calling GetComponentInstanceA5. A nil value means
you're in the system heap, but any value will mean you're in some
application's context.

- ---------------------------------------------------------------------
Jim Reekes, Polterzeitgeist   |     Macintosh Toolbox Engineering
                              |          Sound Manager Expert
Apple Computer, Inc.          | "All opinions expressed are mine, and do
20525 Mariani Ave. MS 302-3KS |   not necessarily represent those of my
Cupertino, CA 95014           |       employer, Apple Computer Inc."

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

>From Anders.Wahlin@hum.gu.se (Anders Wahlin)
Subject: Unmounting all volumes?
Date: Tue, 3 May 1994 08:03:46 GMT
Organization: Hum Fak:s Dataservice

I would like to know how I can unmount all volumes (except for the system
volume). I would like to do this without knowing the names or the reference
number of them. Should I do this in loop and not care about the errorcodes?

Thanks!

-- 
Anders Wahlin
Anders.Wahlin@hum.gu.se

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

>From jumplong@aol.com (Jump Long)
Date: 3 May 1994 16:03:02 -0400
Organization: America Online, Inc. (1-800-827-6364)

In article <Anders.Wahlin-030594100014@bigmac.hds.gu.se>,
Anders.Wahlin@hum.gu.se (Anders Wahlin) writes:

> I would like to know how I can unmount all volumes (except for the system
> volume). I would like to do this without knowing the names or the reference
> number of them. Should I do this in loop and not care about the errorcodes?

You can get a list of mounted volumes by calling PBHGetVInfo starting with
ioVolIndex==1 and then incrementing ioVolIndex until you get an error.  Each
call to PBHGetVInfo will give you a mounted volume's volume reference number in
ioVRefNum.  With that volume reference number, you'll be able to unmount
volumes that don't have any non-system files open on them with PBUnmountVol. 
If any non-system files are open on a volume, PBUnmountVol will return fBsyErr
(-47) and the volume won't be unmounted.  There's function named
UnmountAndEject in the DTS sample code MoreFiles that you can use to unmount
and eject (if needed) a volume correctly.

IMPORTANT WARNING: Some programmers have found and used the _UnmountVol trap
with the HFS bit set (PBHUnmountVol which isn't in Files.h) to unconditionally
unmount volumes that have open files.  DON'T EVER DO THAT!  PBHUnmountVol is
reserved for system use at shutdown when volumes need to be unmounted no matter
what because the system is either going to be shut off or restarted.  Use of
PBHUnmountVol at any other time can, and usually does, cause serious file and
volume corruption because all open files on the volume unmounted by
PBHUnmountVol are slammed closed by the file system that owns the volume. If
one of those "slammed closed" file's File Control Blocks (FCB) is reused to
open another file and the program that opened the first file writes to it or
closes it, it will be accessing the wrong file!  For a good explanation of how
closing files more than once (which is another thing that can happen if
PBHUnmountVol is used) can really screw things up, see the Technical Note "HFS
Elucidations" (used to be TN #102).

-- Jim Luther


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

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