home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / csmpdigest / csmp-digest-v3-017 < prev    next >
Internet Message Format  |  2010-09-21  |  74KB

  1. From: pottier@clipper.ens.fr (Francois Pottier)
  2. Subject: csmp-digest-v3-017
  3. To: Scott.M.Silver@Dartmouth.EDU
  4. Date: Sat, 23 Apr 94 10:55:58 MET DST
  5. X-Mailer: ELM [version 2.3 PL11]
  6.  
  7. C.S.M.P. Digest             Wed, 20 Apr 94       Volume 3 : Issue 17
  8.  
  9. Today's Topics:
  10.  
  11.         'aete' and AppleScript
  12.         Help on recursive read of directory catalog..?
  13.         How can I display TIFF?
  14.         Inverting a button in a dialog
  15.         Looking for styled TE replacement?
  16.         Mounting AFPServer volume...
  17.         PPC ThreadManager w-CodeWarrior
  18.         RJW: Retrieving application name from OSType Creator
  19.         Range of OSErr's for private use?
  20.         Simple Q: Assigning char * to char []. How?
  21.         [Q] Validity of a memory address
  22.         textedit bounds
  23.  
  24.  
  25.  
  26. The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
  27. (pottier@clipper.ens.fr).
  28.  
  29. The digest is a collection of article threads from the internet newsgroup
  30. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  31. regularly and want an archive of the discussions.  If you don't know what a
  32. newsgroup is, you probably don't have access to it.  Ask your systems
  33. administrator(s) for details.  If you don't have access to news, you may
  34. still be able to post messages to the group by using a mail server like
  35. anon.penet.fi (mail help@anon.penet.fi for more information).
  36.  
  37. Each issue of the digest contains one or more sets of articles (called
  38. threads), with each set corresponding to a 'discussion' of a particular
  39. subject.  The articles are not edited; all articles included in this digest
  40. are in their original posted form (as received by our news server at
  41. nef.ens.fr).  Article threads are not added to the digest until the last
  42. article added to the thread is at least two weeks old (this is to ensure that
  43. the thread is dead before adding it to the digest).  Article threads that
  44. consist of only one message are generally not included in the digest.
  45.  
  46. The digest is officially distributed by two means, by email and ftp.
  47.  
  48. If you want to receive the digest by mail, send email to listserv@ens.fr
  49. with no subject and one of the following commands as body:
  50.     help                        Sends you a summary of commands
  51.     subscribe csmp-digest Your Name    Adds you to the mailing list
  52.     signoff csmp-digest            Removes you from the list
  53. Once you have subscribed, you will automatically receive each new
  54. issue as it is created.
  55.  
  56. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
  57. Questions related to the ftp site should be directed to
  58. scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
  59. digest are available there.
  60.  
  61. Also, the digests are available to WAIS users as comp.sys.mac.programmer.src.
  62.  
  63.  
  64. -------------------------------------------------------
  65.  
  66. From "Jared M. Oberhaus" <oberhaus+@CMU.EDU>
  67. Subject: 'aete' and AppleScript
  68. Date: Tue, 29 Mar 1994 03:54:34 -0500
  69. Organization: Senior, Electrical and Computer Engineering, Carnegie Mellon, Pittsburgh, PA
  70.  
  71. OK, I think I've figured out that the aete resource is the Dictionary
  72. for translating raw AppleEvent formats into plain English-like commands.
  73.  
  74. But, where is the Template resource for ResEdit, so I can create and
  75. modify this resource?
  76.  
  77. And if it doesn't exist yet, how do all you other guys do it? Not the
  78. hard way, I hope...
  79.  
  80. Help!!
  81.  
  82. ps-I saw the demo of Resorcerer and noticed that it supports aete
  83. resources, and looked around, and I supposed I could figure out how to
  84. do an aete resoure by looking at the hex offsets, etc., but I don't
  85. exactly feel like doing that!
  86.  
  87. pps-If you could, when you respond, could you respond to All (that is,
  88. put me on the adressee list) instead of just Readers, that way, it'll be
  89. easier than looking through five hundred messages every day... Thanks!
  90.  
  91.  
  92. - ---------------------------------------------------------------------------
  93. Jared M. Oberhaus                                           oberhaus+@CMU.EDU
  94. Electrical and Computer Engineering                             Class of 1994
  95. Carnegie Mellon University
  96. - ---------------------------------------------------------------------------
  97. "We are upping our standards,...so up yours."  
  98.         - Pat Paulsen for President, 1988
  99.  
  100.  
  101. +++++++++++++++++++++++++++
  102.  
  103. From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
  104. Date: 30 Mar 94 11:19:56 +1300
  105. Organization: University of Waikato, Hamilton, New Zealand
  106.  
  107. In article <AhZyn_y00iV4E0fEpd@andrew.cmu.edu>, "Jared M. Oberhaus" <oberhaus+@CMU.EDU> writes:
  108. > OK, I think I've figured out that the aete resource is the Dictionary
  109. > for translating raw AppleEvent formats into plain English-like commands.
  110. >
  111. > But, where is the Template resource for ResEdit, so I can create and
  112. > modify this resource?
  113.  
  114. I think I found a copy on the AppleScript developer CD. Trouble is, ResEdit
  115. doesn't seem to be entirely reliable in its support for templates, and I've
  116. hit problems trying to use it to open some aete resources.
  117.  
  118. Generally, if I want to know details of event IDs etc, I use MPW's DeRez to
  119. decompile the aete into source form. If I don't, then the Script Editor's
  120. "Open Dictionary" command suffices.
  121.  
  122. Lawrence D'Oliveiro                       fone: +64-7-856-2889
  123. Info & Tech Services Division              fax: +64-7-838-4066
  124. University of Waikato            electric mail: ldo@waikato.ac.nz
  125. Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00
  126. My hard disk is a Mightgrosoft-free zone.
  127.  
  128. +++++++++++++++++++++++++++
  129.  
  130. From knut.mork@admin.uio.no (Knut Mork)
  131. Date: Wed, 30 Mar 1994 10:16:28 +0200
  132. Organization: UniNett
  133.  
  134. In article <1994Mar30.111959.27070@waikato.ac.nz>, ldo@waikato.ac.nz
  135. (Lawrence D'Oliveiro, Waikato University) wrote:
  136.  
  137. > In article <AhZyn_y00iV4E0fEpd@andrew.cmu.edu>, "Jared M. Oberhaus" <oberhaus+@CMU.EDU> writes:
  138. > > OK, I think I've figured out that the aete resource is the Dictionary
  139. > > for translating raw AppleEvent formats into plain English-like commands.
  140. > >
  141. > > But, where is the Template resource for ResEdit, so I can create and
  142. > > modify this resource?
  143. > I think I found a copy on the AppleScript developer CD. Trouble is, ResEdit
  144. > doesn't seem to be entirely reliable in its support for templates, and I've
  145. > hit problems trying to use it to open some aete resources.
  146. > Generally, if I want to know details of event IDs etc, I use MPW's DeRez to
  147. > decompile the aete into source form. If I don't, then the Script Editor's
  148. > "Open Dictionary" command suffices.
  149.  
  150. The AppleScript developer CD also has a HyperCard stack for constructing
  151. aete resources, which is extremely useful. It has Rez templates for MPW,
  152. but those didn't work.. they compiled 'aete' resources which were invalid,
  153. at least for me. Anybody else have this problem?
  154.  
  155. --Knut
  156.  
  157. +++++++++++++++++++++++++++
  158.  
  159. From mlanett@netcom.com (Mark Lanett)
  160. Date: Wed, 30 Mar 1994 08:14:12 GMT
  161. Organization: Etch-a-Sketch Analysis and Design
  162.  
  163. ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
  164.  
  165. >I think I found a copy on the AppleScript developer CD. Trouble is, ResEdit
  166. >doesn't seem to be entirely reliable in its support for templates, and I've
  167. >hit problems trying to use it to open some aete resources.
  168.  
  169. I don't have the AS toolkit, so when I felt like doing stuff with scripting
  170. I had to figure out the format of the aete resource myself, and...
  171. It looks like it can't be handled by ResEdit. Apparently all the "direct"
  172. types like shorts and longs are word-aligned, but strings are not. There's no
  173. way to create a template which handles word-alignment in ResEdit, alas, and
  174. since the strings *aren't* aligned you can't make a template that works by
  175. specifying ESTR instead of PSTR.
  176.  
  177. >...the Script Editor's
  178. >"Open Dictionary" command suffices.
  179.  
  180. Never even thought of that one. Oh well, Sucks to be me.
  181.  
  182. >My hard disk is a Mightgrosoft-free zone.
  183. I love MS products. *My* HD is a Symantec-free zone.
  184. -- 
  185.     Mark Lanett "...a bajillion brilliant Jobsian lithium licks"
  186.  
  187. +++++++++++++++++++++++++++
  188.  
  189. From alldritt@mdd.comm.mot.com (Mark Alldritt)
  190. Date: 30 Mar 1994 08:31:00 -0800
  191. Organization: Motorola - Wireless Data Group; Richmond, BC
  192.  
  193. In <mlanettCnGxJo.Fov@netcom.com> mlanett@netcom.com (Mark Lanett) writes:
  194.  
  195. >ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
  196.  
  197. >>I think I found a copy on the AppleScript developer CD. Trouble is, ResEdit
  198. >>doesn't seem to be entirely reliable in its support for templates, and I've
  199. >>hit problems trying to use it to open some aete resources.
  200.  
  201. >I don't have the AS toolkit, so when I felt like doing stuff with scripting
  202. >I had to figure out the format of the aete resource myself, and...
  203. >It looks like it can't be handled by ResEdit. Apparently all the "direct"
  204. >types like shorts and longs are word-aligned, but strings are not. There's no
  205. >way to create a template which handles word-alignment in ResEdit, alas, and
  206. >since the strings *aren't* aligned you can't make a template that works by
  207. >specifying ESTR instead of PSTR.
  208.  
  209. The AppleScript developer CD contains a TMPL resource for editing aete
  210. resources which works reasonably well.  The problem is that TMPL layouts
  211. can only handle a limited number of fields.  Application aete resources are
  212. generally too large to be edited using the aete TMPL.
  213.  
  214. Another alternative is the aete editing Hypercard stack Apple provides on 
  215. the AppleScript CD and (I think) on the Develop Bookmark CD.
  216.  
  217. However, if your just interested in know what events and classes a application
  218. understands then the Script Editor's dictionary window is your best bet.
  219.  
  220. -Mark
  221.  
  222. +++++++++++++++++++++++++++
  223.  
  224. From lai@apple.com (Ed Lai)
  225. Date: 5 Apr 1994 17:04:19 GMT
  226. Organization: Apple
  227.  
  228. In article <AhZyn_y00iV4E0fEpd@andrew.cmu.edu>, "Jared M. Oberhaus"
  229. <oberhaus+@CMU.EDU> wrote:
  230.  
  231. > OK, I think I've figured out that the aete resource is the Dictionary
  232. > for translating raw AppleEvent formats into plain English-like commands.
  233. > But, where is the Template resource for ResEdit, so I can create and
  234. > modify this resource?
  235.  
  236. It should be on the developer CD. You should also find a copy in
  237. from ftp.apple.com in /pub/appleevents, although that may not be the
  238. latest copy. The problem is that ResEdit template editing probably
  239. uses the dialog manager and there can only be a limited number of
  240. item in the dialog, any decent size aete would reach the limit so
  241. for practical purpose it is useless for aete unless the aete is
  242. are very simple like those in an OSAX.
  243.  
  244. You should be able to find the HyperCard aete editor stack in the 
  245. same place.
  246.  
  247. > And if it doesn't exist yet, how do all you other guys do it? Not the
  248. > hard way, I hope...
  249. > Help!!
  250. > ps-I saw the demo of Resorcerer and noticed that it supports aete
  251. > resources, and looked around, and I supposed I could figure out how to
  252. > do an aete resoure by looking at the hex offsets, etc., but I don't
  253. > exactly feel like doing that!
  254.  
  255. I hear that Resorcerer is very good at editing aete resource, this is
  256. certainly a solution for those who owns Resorcerer.
  257.  
  258. There is yet another solution. I have written an osax to translate
  259. between resources and list using ResEdit template, and since aete is 
  260. a resource with ResEdit template. In theory you can use the osax
  261. and generate aete resource using AppleScript. I have not tried it
  262. for a long time, but I suspect it is very slow so may not be
  263. practical except for smaller aete. The osax can be found in
  264. ftp.apple.com in /pub/lai/osax/pgmTool.sit.hqx
  265.  
  266. -- 
  267. /* Disclaimer: All statments and opinions expressed are my own */
  268. /* Edmund K. Lai                                               */
  269. /* Apple Computer, MS303-3A                                    */
  270. /* 20525 Mariani Ave,                                          */
  271. /* Cupertino, CA 95014                                         */
  272. /* (408)974-6272                                               */
  273. zW@h9cOi
  274.  
  275. ---------------------------
  276.  
  277. From dsf5454@ritvax.isc.rit.edu
  278. Subject: Help on recursive read of directory catalog..?
  279. Date: Sun, 3 Apr 1994 16:59:38 GMT
  280. Organization: Rochester Institute of Technology
  281.  
  282. Ok...basically, I have a crucial subroutine where I need to read a directory
  283. tree below a specific subdirectory. However, I notice that I seem to be
  284. crashing into the debugger with an error of #28 and somewhere around in a VBL
  285. queue - stack and application heap collison. Therefore, I'm not sure how I
  286. could efficiently code such a recursive call... suggestions or pointers,
  287. anybody? I'm calling it with RecursiveDirList(1, 2L); in main to tell it to
  288. start from root folder.
  289.  
  290. I have a newer version that was re-written, but the principle is the same...
  291. Roughly speaking, here's what it looks like at the moment..:
  292.  
  293. -Dan
  294. Internet:    dsf5454@ritvax.isc.rit.edu
  295. BITNET/CREN:    dsf5454@ritvax.BITNET
  296.  
  297. long RecursiveDirList (t, dirIDToSearch)
  298. short t;
  299. long dirIDToSearch;
  300. {
  301.     short    index = 1;
  302.     OSErr    err;
  303.     long    curLine;
  304.  
  305.     do {
  306.  
  307.         myCPB.fileParam.ioFDirIndex = index;
  308.         myCPB.fileParam.ioVRefNum = vRefNum;
  309.         myCPB.fileParam.ioDirID = dirIDToSearch;
  310.         myCPB.fileParam.ioNamePtr = (unsigned char *)fName;
  311.  
  312.         err = PBGetCatInfo ((CInfoPBPtr)&myCPB, 0);
  313.         
  314.         if (err == noErr) 
  315.         {
  316.             if (((myCPB.fileParam.ioFlAttrib >> 4) & 0x01) == 1) 
  317.             {
  318.                 RecursiveDirList(t+1,myCPB.fileParam.ioDirID);
  319.                 err = 0;
  320.                 /* It's a directory; we want to go deeper into
  321.                 the subdirectories */
  322.             } 
  323.             else 
  324.             {
  325.                 /* it's a file */
  326.             }
  327.         }
  328.         index++;
  329.     } while ((err != fnfErr) && (err == noErr));
  330. }
  331.                                
  332.  
  333. +++++++++++++++++++++++++++
  334.  
  335. From allon@intercon.com (Allon Stern)
  336. Date: Tue,  5 Apr 1994 03:09:18 -0400
  337. Organization: InterCon Systems Corporation, Herndon VA.
  338.  
  339. In article <1994Apr3.165938.3952@ultb.isc.rit.edu>, 
  340. dsf5454@ritvax.isc.rit.edu writes:
  341. > Ok...basically, I have a crucial subroutine where I need to read a 
  342. > directory tree below a specific subdirectory. However, I notice that I 
  343. > seem to be crashing into the debugger with an error of #28 and 
  344. > somewhere around in a VBL queue - stack and application heap collison. 
  345. > Therefore, I'm not sure how I could efficiently code such a recursive 
  346. > call... suggestions or pointers, anybody? I'm calling it with 
  347. > RecursiveDirList(1, 2L); in main to tell it to start from root folder. 
  348. > I have a newer version that was re-written, but the principle is the 
  349. > same... 
  350. > Roughly speaking, here's what it looks like at the moment..: 
  351. > -Dan 
  352. > Internet:    dsf5454@ritvax.isc.rit.edu 
  353. > BITNET/CREN:    dsf5454@ritvax.BITNET 
  354.  
  355. It seems to me that you could probably do this non-recusively.
  356. Keep in mind that you will end up using stack space for each recursive call,
  357. and also that PBGetCatInfo and the file manager may also use some stack
  358. space.
  359.  
  360. Rather than using the stack to store where you were, you could build your own
  361. stack structure, say, using an array.  This would minimize stack usage, and
  362. would also store the same information much more efficiently.  If it is a
  363. transient thing (i.e. you use a bunch of storage for a short time, then would
  364. release it), you could use temporary memory for it.  You could also use a
  365. dynamic array, and if you run out of room in your own heap, you could transfer
  366. the contents to a handle in temporary memory space.
  367.  
  368. You could try increasing the memory requested for the program, but I think
  369. the best thing in this case is to find a non-recursive way to do it.
  370. --
  371. Allon
  372.  
  373.  
  374. | Allon Stern        | 703-709-5557 |  Ring around the Internet    |
  375. | allon@intercon.com |    KE4FYL    |  A packet with a bit not set |
  376. +--------------------+--------------+  ENQ ACK ENQ ACK             |
  377. |  All opinions above are my own.   |  We all go down!             |
  378. |------------------------------------------------------------------|
  379.  
  380.  
  381.  
  382. +++++++++++++++++++++++++++
  383.  
  384. From d88-jwa@mumrik.nada.kth.se (Jon Wdtte)
  385. Date: 5 Apr 1994 08:13:09 GMT
  386. Organization: The Royal Institute of Technology
  387.  
  388. In <9404050309.AA18685@hazmat.intercon.com> allon@intercon.com (Allon Stern) writes:
  389.  
  390. >> Ok...basically, I have a crucial subroutine where I need to read a 
  391. >> directory tree below a specific subdirectory. However, I notice that I 
  392. >> seem to be crashing into the debugger with an error of #28 and 
  393. >> somewhere around in a VBL queue - stack and application heap collison. 
  394.  
  395. >It seems to me that you could probably do this non-recusively.
  396. >Keep in mind that you will end up using stack space for each recursive call,
  397. >and also that PBGetCatInfo and the file manager may also use some stack
  398. >space.
  399.  
  400. Yeah, but PBGetCatInfo will give the stack space back when it's done.
  401. (It should be called as PBGetCatInfoSync() by the way, or maybe
  402. PBGetCatInfoAsync ( ) ; while ( rec . ioResult == 1 ) Yield ( ) ;)
  403.  
  404. Anyway, his routine only ate 4+4+4+4+4+4+4 bytes per recursion
  405. (2 int arguments, a6 link, return address, three int locals, given
  406. 4-byte ints)
  407. At 28 bytes per recursion, you need > 1000 folders deep structures
  408. to hit any real problems, unless you have MASSIVE parameter blocks
  409. and Str255s on the stack higher up. (Putting Str255s on the stack
  410. is a BAD idea btw)
  411.  
  412. What he could do is call StackSpace() (or whatever) before each
  413. recursive call, and call Debugger() if it goes below a K or so.
  414. Most probably, however, he's having some other bug which is causing
  415. the problem.
  416. -- 
  417.  -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe --
  418.  
  419.    What we need is a good GNU [...] licence manager implementation.
  420.                      -- Raphael Manfredi
  421.  
  422. +++++++++++++++++++++++++++
  423.  
  424. From jumplong@aol.com (Jump Long)
  425. Date: 5 Apr 1994 12:44:02 -0400
  426. Organization: America Online, Inc. (1-800-827-6364)
  427.  
  428. In article <1994Apr3.165938.3952@ultb.isc.rit.edu>, dsf5454@ritvax.isc.rit.edu
  429. writes:
  430.  
  431. > Ok...basically, I have a crucial subroutine where I need to read a directory
  432. > tree below a specific subdirectory. However, I notice that I seem to be
  433. > crashing into the debugger with an error of #28 and somewhere around in a VBL
  434. > queue - stack and application heap collison. Therefore, I'm not sure how I
  435. > could efficiently code such a recursive call... suggestions or pointers,
  436. > anybody? I'm calling it with RecursiveDirList(1, 2L); in main to tell it to
  437. > start from root folder.
  438.  
  439. You're using too much stack in your recursive routine - either that, of you
  440. don't have much stack when you start your recursive routine.
  441.  
  442. You can check the stack space before you start with the StackSpace function. 
  443. If that isn't your problem, then you might want to look at one of the recursive
  444. routines I put in DTS's MoreFiles File Manager sample code. In particular, the
  445. routines in DirectoryCopy.c show how you can use very little stack space per
  446. level in a recursive routine that enumerates a directory structure on a
  447. Macintosh disk volume.
  448.  
  449. The code in MoreFiles is based on the ideas presented in the Technical Note "
  450.  
  451. +++++++++++++++++++++++++++
  452.  
  453. From jumplong@aol.com (Jump Long)
  454. Date: 5 Apr 1994 12:45:03 -0400
  455. Organization: America Online, Inc. (1-800-827-6364)
  456.  
  457. In article <1994Apr3.165938.3952@ultb.isc.rit.edu>, dsf5454@ritvax.isc.rit.edu
  458. writes:
  459.  
  460. Ooops, hit the send button too soon... starting where I left off.
  461.  
  462. on ideas presented in the Technical Note "FL 31 - Searching Volumes-Solutions
  463. and Problems".
  464.  
  465. Hope that helps.
  466.  
  467. Jim Luther
  468. Apple DTS
  469.  
  470. ---------------------------
  471.  
  472. From jbell@garnet.berkeley.edu (John E. Bell)
  473. Subject: How can I display TIFF?
  474. Date: 22 Mar 1994 11:07:24 GMT
  475. Organization: University of California, Berkeley
  476.  
  477.  
  478. How can I display a TIFF file in my program? Are there library routines
  479. somewhere?
  480.  
  481. Thanks - John E. Bell
  482.  
  483. +++++++++++++++++++++++++++
  484.  
  485. From mssmith@afterlife.ncsc.mil (M. Scott Smith)
  486. Date: Tue, 22 Mar 1994 12:18:47 GMT
  487. Organization: The Great Beyond
  488.  
  489. In article <2mmjhc$sno@agate.berkeley.edu> jbell@garnet.berkeley.edu (John E. Bell) writes:
  490. >
  491. >How can I display a TIFF file in my program? Are there library routines
  492. >somewhere?
  493. >
  494. >Thanks - John E. Bell
  495.  
  496. John,
  497.  
  498.    There are some samples floating about that show how to read the TIFF
  499. format.  The TIFF format is kind of an ugly thing to read; it takes a lot
  500. of work.  It's designed to be a very flexible file format, so each TIFF
  501. file starts out with a number of "tags" which can contain everything from
  502. the expected width and height of the image, to the resolution, even comments
  503. and tags/fields which are specific to certain applications.
  504.  
  505.    I guess in order to claim that your program can read TIFF, you need to
  506. intelligently read a certain number of these tags, and you can ignore the
  507. rest.
  508.  
  509.    The tags will give you information like offsets for finding the actual
  510. data, etc.
  511.  
  512.    Really kind of yechy.  But, alas: if I remember correctly, NIH Image,
  513. a program which you can find at the usual FTP sites, reads color TIFF
  514. images.  The only problem is that it's written in Pascal.  (That may
  515. not be a problem for some people.)  You can probably easily translate it
  516. to C.
  517.  
  518.    I've written black and white TIFF-reading code (not color), and I
  519. suppose I might some day spruce that up to serve as an example.  (Right now,
  520. I think I'd be embarassed to claim credit for it.  It does read files
  521. quickly though.)
  522.  
  523.    What I'd like is a nice C++ library that lets you save/read PixMaps
  524. to/from a multitude of file formats, such as PICT, TIFF, PostScript,
  525. and the like.  I don't think such a thing exists (anyone know??), so
  526. it seems whenever you want to write a program with these capabilities,
  527. you need to re-invent the wheel.
  528.  
  529.    Maybe people could get together and build this library; between us,
  530. I'm sure we have all of the capability.
  531.  
  532. Anyway, good luck with the TIFF reading.  (Trivia: TIFF stands for
  533. Tagged Image File Format.)
  534.  
  535. - Scott
  536.  
  537. - -
  538. M. Scott Smith   (mssmith@afterlife.ncsc.mil || umsmith@mcs.drexel.edu)
  539.  
  540.   Mac developer. Student.  Not a member of the Michael Bolton fan club.
  541.  
  542.  
  543. +++++++++++++++++++++++++++
  544.  
  545. From perm@csd.uu.se (Per Mildner)
  546. Date: 22 Mar 1994 16:04:36 GMT
  547. Organization: Computing Science Dept.,Uppsala University, Sweden
  548.  
  549. I recommend looking for LIBTIFF with Archie, it reads and writes
  550. various tiff formats.  My only problem with that is that I know an
  551. application (Optix by Blueridge) that unpacks CCITT Group IV (fax)
  552. very much faster than the seemingly optimized LIBTIFF code (on a
  553. Quadra 700).
  554. Regards,
  555. --
  556. Per Mildner            Per.Mildner@CSD.UU.SE
  557. Computing Science Dept.        tel: +46 18 181049
  558. Uppsala University, Sweden    fax: +46 18 511925
  559.  
  560.  
  561. +++++++++++++++++++++++++++
  562.  
  563. From markhanrek@aol.com (MarkHanrek)
  564. Date: 22 Mar 1994 20:45:07 -0500
  565. Organization: America Online, Inc. (1-800-827-6364)
  566.  
  567. Yes, there is some TIFF source code available from a variety of places.
  568.  
  569. The place to start, though, is the Aldus Developer Desk, which is on
  570. CompuServe, from which you will be able to download the current TIFF Level 6.0
  571. specification, example source code (for level 5), and some TIFF pictures which
  572. are good to use for testing.
  573.  
  574. Or you could contact Aldus directly. Perhaps there is Internet access to them
  575.  
  576. Mark Hanrek
  577.  
  578.  
  579. +++++++++++++++++++++++++++
  580.  
  581. From kenlong@netcom.com (Ken Long)
  582. Date: Wed, 23 Mar 1994 02:51:35 GMT
  583. Organization: NETCOM On-line Communication Services (408 241-9760 guest)
  584.  
  585. There's some TIFF reader code on AOL.  Next time I log on I'll get a 
  586. description of it for you.  Seems like I saw some elsewhere, too.  i'll 
  587. check it out.
  588.  
  589. -Ken-
  590.  
  591. +++++++++++++++++++++++++++
  592.  
  593. From xinwei@otter.Stanford.EDU (Sha Xin Wei)
  594. Date: 5 Apr 1994 21:39:26 GMT
  595. Organization: Stanford University
  596.  
  597. M. Scott Smith writes
  598. > In article <2mmjhc$sno@agate.berkeley.edu> jbell@garnet.berkeley.edu (John E.  
  599. Bell) writes:
  600. > >
  601. > >How can I display a TIFF file in my program? Are there library routines
  602. > >somewhere?
  603. > >
  604. > >Thanks - John E. Bell
  605. > John,
  606. >    There are some samples floating about that show how to read the TIFF
  607. > format.>    Maybe people could get together and build this library; between  
  608. us,
  609. > I'm sure we have all of the capability.
  610. > Anyway, good luck with the TIFF reading.  (Trivia: TIFF stands for
  611. > Tagged Image File Format.)
  612. > - Scott
  613. > ---
  614. > M. Scott Smith   (mssmith@afterlife.ncsc.mil || umsmith@mcs.drexel.edu)
  615.  
  616.  
  617. By the way, in the unix world there's a whole wonderful library named pbmplus  
  618. by Jef Pozkaner, written in C, which is in the public domain.  It provides a  
  619. slew of tools for conversion between 12-40 different graphics formats  
  620. (depending on how you count) -- PICT, TIFF, PS, GIF, etc., and much more: color  
  621. histogram, diffusion, quatization, scaling, rotation, palette remaps, even  
  622. general convolution given a user-supplied kernel.   All in public domain.    
  623. PixelMagician, a NeXTSTEP application has extended pbmplus to handle pixmaps  
  624. with alpha channel, and a few more formats.
  625.  
  626. If anyone has compiled this under MPW or ThinkC, could they please publish it?
  627. Thanks.
  628.  
  629. Sha Xin Wei
  630. Stanford University
  631.  
  632. ---------------------------
  633.  
  634. From Vik_Rubenfeld@lamg.com (Vik Rubenfeld)
  635. Subject: Inverting a button in a dialog
  636. Date: 05 Apr 1994 00:21:14 -0000
  637. Organization: (none)
  638.  
  639. I've set up a filter procedure that returns the item number of the cancel
  640. button if the user hits the escape key. This lets the user dismiss the dialog
  641. from the keyboard, without using the mouse. It works great. However, it does
  642. not invert the cancel button before dismissing the dialog.
  643.  
  644. So, could someone upload some sample code that highlights (inverses) a
  645. standard dialog button? Thanks.
  646.  
  647. +++++++++++++++++++++++++++
  648.  
  649. From t-gaul@i-link.com (Troy Gaul)
  650. Date: Tue, 05 Apr 1994 10:48:58 -0500
  651. Organization: I-Link, Ltd.
  652.  
  653. In article <101974014.48568985@lamgnet.lamg.com>, Vik_Rubenfeld@lamg.com
  654. (Vik Rubenfeld) wrote:
  655.  
  656. > I've set up a filter procedure that returns the item number of the cancel
  657. > button if the user hits the escape key. This lets the user dismiss the dialog
  658. > from the keyboard, without using the mouse. It works great. However, it does
  659. > not invert the cancel button before dismissing the dialog.
  660. > So, could someone upload some sample code that highlights (inverses) a
  661. > standard dialog button? Thanks.
  662.  
  663. ControlHandle
  664. GetControlItemHandle(DialogPtr dlog, short item) {
  665.   short  iKind;
  666.   Handle iHandle;
  667.   Rect   iRect;
  668.  
  669.   GetDItem(dlog, item, &iKind, &iHandle, &iRect);
  670.   switch (iKind & ~itemDisable) {
  671.     case btnCtrl + ctrlItem:
  672.     case chkCtrl + ctrlItem:
  673.     case radCtrl + ctrlItem:
  674.     case resCtrl + ctrlItem:
  675.       return (ControlHandle) iHandle;
  676.   }
  677.   return nil;
  678. }
  679.  
  680. void 
  681. FlashDItem(DialogPtr dlog, short item) {
  682.   long ignored;
  683.   ControlHandle button;
  684.     
  685.   button = GetControlItemHandle(dlog, item);
  686.   if (button != nil && (**button).contrlHilite != 255) {
  687.     HiliteControl(button, 1);
  688.     Delay(8, &ignored);          // the Apple prescribed period of time
  689.     HiliteControl(button, 0);
  690.   }
  691. }
  692.  
  693. Of course, to flash the cancel button, you just call:
  694.  
  695.   FlashDItem(dlog, cancel);
  696.  
  697. _troy
  698. //////// //////___Troy Gaul_________________________t-gaul@i-link.com__ //
  699.   //    //       I-Link, Ltd. ; West Des Moines, Iowa                  //
  700.  //    //  //   "Iungo ergo sum." (I-Link, therefore I am.)           //
  701. //    //////________________________________________________________ //
  702.  
  703. +++++++++++++++++++++++++++
  704.  
  705. From charlesworth@andyne.on.ca (Dave Charlesworth)
  706. Date: Tue, 5 Apr 1994 22:15:45 GMT
  707. Organization: Andyne Computing
  708.  
  709. I don't have sample code handy but you'll find it really simple to
  710. write.  Here's the basic outline:
  711. 1.  Get the Cancel button item from the dialog.
  712. 2.  Coerce it to a control.
  713. 3.  Tell the control to highlight.
  714. 4.  Wait long enough for the user to see it.
  715. 5.  Go on with dismissing your dialog...
  716.  
  717. .../dave   Dave Charlesworth
  718.  
  719. ---------------------------
  720.  
  721. From RobTerrell@aol.com (Rob Terrell)
  722. Subject: Looking for styled TE replacement?
  723. Date: 4 Apr 1994 17:55:08 GMT
  724. Organization: Jecta Development Corp.
  725.  
  726. A few weeks back someone mentioned a styled text edit replacement
  727. called "WASTE". The poster claimed it would do styles as well as >32K
  728. of text.
  729.  
  730. I've never heard of it, nor has archie. Any ideas?
  731.  
  732. Thanks,
  733.  
  734.  
  735. Rob
  736. Software Designs Unlimited
  737.  
  738.  
  739.  
  740. +++++++++++++++++++++++++++
  741.  
  742. From mlanett@netcom.com (Mark Lanett)
  743. Date: Tue, 5 Apr 1994 02:30:27 GMT
  744. Organization: Etch-a-Sketch Analysis and Design
  745.  
  746. RobTerrell@aol.com (Rob Terrell) writes:
  747.  
  748. >A few weeks back someone mentioned a styled text edit replacement
  749. >called "WASTE". The poster claimed it would do styles as well as >32K
  750. >of text.
  751.  
  752. Host: ghost.dsi.unimi.it (149.132.1.2)
  753. Path: pub2/papers/piovanel/
  754. -- 
  755.     Mark Lanett "...a bajillion brilliant Jobsian lithium licks"
  756.  
  757. ---------------------------
  758.  
  759. From rdm4@acpub.duke.edu (RYAN MARTELL)
  760. Subject: Mounting AFPServer volume...
  761. Date: 5 Apr 1994 21:26:42 GMT
  762. Organization: Duke University, Durham, N.C.
  763.  
  764.  
  765. Does anyone have any sample code showing how to mount a volume from an
  766. AFPServer remotely?  I already have the address of the Server, and
  767. figure I need to use AFPCommand, but I don't know how to send the
  768. proper name/password verification data- or is there just a standard
  769. call to do all of that for you? (Essentially, I am trying to write
  770. something that acts as the chooser for you..)
  771.  
  772. Any help would be appreciated, please reply by email.
  773.  
  774. -Ryan Martell
  775.  
  776. +++++++++++++++++++++++++++
  777.  
  778. From jumplong@aol.com (Jump Long)
  779. Date: 5 Apr 1994 23:55:02 -0400
  780. Organization: America Online, Inc. (1-800-827-6364)
  781.  
  782. In article <2nsl2i$p38@news.duke.edu>, rdm4@acpub.duke.edu (RYAN MARTELL)
  783. writes:
  784.  
  785. > Does anyone have any sample code showing how to mount a volume from an
  786. > AFPServer remotely?  I already have the address of the Server, and
  787. > figure I need to use AFPCommand, but I don't know how to send the
  788. > proper name/password verification data- or is there just a standard
  789. > call to do all of that for you? (Essentially, I am trying to write
  790. > something that acts as the chooser for you..)
  791.  
  792. There's two ways to do this so that the volume is mounted by the File Manager
  793. (you probably don't want to mount the volume using AFP commands because the
  794. File Manager won't know about the volume if mounted that way).
  795.  
  796. The first method is to use the Alias Manager.  Create a new alias record using
  797. the NewAliasMinimalFromFullPath function.  Then, resolve the alias with the
  798. ResolveAlias function.  The Alias Manager will take care of the user interface
  799. for you.
  800.  
  801. The second way is to use the File Manager's PBVolumeMount function. You'll need
  802. to build an AFP VolumeMountInfo record to pass to PBVolumeMount.  The
  803. BuildAFPVolMountInfo function in the Apple DTS MoreFiles sample code will do
  804. that for you.  MoreFiles also includes a high level versions of the VolumeMount
  805. related calls if you don't like using parameter blocks.
  806.  
  807. - Jim Luther
  808.  
  809.  
  810. ---------------------------
  811.  
  812. From Frank Price <wprice@jarthur.claremont.edu>
  813. Subject: PPC ThreadManager w-CodeWarrior
  814. Date: 5 Apr 1994 16:38:15 GMT
  815. Organization: Pomona College
  816.  
  817. Has anybody managed to get the ThreadManager 2.0d7 release running native
  818. on the PowerPC using CodeWarrior?  All I get is crashes on NewThread which
  819. somewhat limits what one can do.  Other simple calls like GetCurrentThread
  820. seem to work fine.  Haven't tried this with MPW yet, but I don't imagine it
  821. would be any different (but if it wasn't different, how could they have
  822. released this??)  Compiling the same code for 68k runs fine.  No, I'm not
  823. trying to make preemptive threads, and I believe it would return an error
  824. even if I had.  Also, did anyone notice that the Threads.h header file
  825. doesn't even compile?  An excess comma has to be removed from inside an
  826. enum.  I get the feeling this went out the door a little too quickly.
  827.  
  828. -Frank
  829. _______________________________________________________________________
  830. | Frank Price   |  wprice@jarthur.claremont.edu                        |
  831. |_______________|______________________________________________________|
  832.  
  833. +++++++++++++++++++++++++++
  834.  
  835. From REDDEN@applelink.apple.com (Kevin Redden)
  836. Date: Tue, 5 Apr 1994 21:07:53 GMT
  837. Organization: Apple Computer
  838.  
  839. In article <2ns45n$ht9@jaws.cs.hmc.edu>, Frank Price
  840. <wprice@jarthur.claremont.edu> wrote:
  841.  
  842. > Has anybody managed to get the ThreadManager 2.0d7 release running native
  843. > on the PowerPC using CodeWarrior?  All I get is crashes on NewThread which
  844. > somewhat limits what one can do.  Other simple calls like GetCurrentThread
  845. > seem to work fine.  Haven't tried this with MPW yet, but I don't imagine it
  846. > would be any different (but if it wasn't different, how could they have
  847. > released this??)  Compiling the same code for 68k runs fine.  No, I'm not
  848. > trying to make preemptive threads, and I believe it would return an error
  849. > even if I had.  Also, did anyone notice that the Threads.h header file
  850. > doesn't even compile?  An excess comma has to be removed from inside an
  851. > enum.  I get the feeling this went out the door a little too quickly.
  852.  
  853. I had some code that I got working with it quite a while ago (I'm not
  854. positive that it was 2.0d7 but I think so because I got the same comma
  855. error), but I never tried it with CodeWarrier, just Apples SDK for PowerPC.
  856.  
  857. The comma compiles straight through with CFront and I believe that PPCC
  858. only flags it when -strict on is specified.  I did bring the comma problem
  859. up with one of the engineers that works on the Threads package but it was
  860. already too late.  Hopefully in the next versionI
  861.  
  862. Kevin
  863. Tech Lead, Macintosh On RISC SDK 2.0
  864.  
  865. +++++++++++++++++++++++++++
  866.  
  867. From bpost@apple.com (Brad Post)
  868. Date: Wed, 6 Apr 1994 01:44:05 GMT
  869. Organization: Apple Computer
  870.  
  871. In article <2ns45n$ht9@jaws.cs.hmc.edu>, Frank Price
  872. <wprice@jarthur.claremont.edu> wrote:
  873. > Has anybody managed to get the ThreadManager 2.0d7 release running native
  874. > on the PowerPC using CodeWarrior?  All I get is crashes on NewThread which
  875. > somewhat limits what one can do.  Other simple calls like GetCurrentThread
  876. > seem to work fine.  Haven't tried this with MPW yet, but I don't imagine it
  877. > would be any different (but if it wasn't different, how could they have
  878. > released this??)  Compiling the same code for 68k runs fine.  No, I'm not
  879. > trying to make preemptive threads, and I believe it would return an error
  880. > even if I had.  Also, did anyone notice that the Threads.h header file
  881. > doesn't even compile?  An excess comma has to be removed from inside an
  882. > enum.  I get the feeling this went out the door a little too quickly.
  883.  
  884.  
  885. Okay this is a simple problem to fix (crashing that is).  The problem is
  886. that you are most likely using the Voodoo Monkey Debugger Init.  It doesn't
  887. know about the native thread manager, so it's trying to do some gross stuff
  888. that it shouldn't be doing.  Remove it and you should work just fine.  As
  889. for the comma, it slipped out, and it should be fixed in the latest/next
  890. release (or it's an exercise for the programmer !-)
  891.  
  892. Brad 'SMMFD' Post
  893.  
  894. +++++++++++++++++++++++++++
  895.  
  896. From jwbaxter@olympus.net (John W. Baxter)
  897. Date: Tue, 05 Apr 1994 17:46:04 -0700
  898. Organization: Internet for the Olympic Peninsula
  899.  
  900. In article <2ns45n$ht9@jaws.cs.hmc.edu>, Frank Price
  901. <wprice@jarthur.claremont.edu> wrote:
  902.  
  903. > Has anybody managed to get the ThreadManager 2.0d7 release running native
  904. > on the PowerPC using CodeWarrior?  All I get is crashes on NewThread which
  905. > somewhat limits what one can do.
  906.  
  907. You might have better luck with the ThreadManager 2.0 (no qualification)
  908. which appeared on the April Developer CD.  I don't believe this one is the
  909. last word in Thread Managers, either, though.
  910.  
  911. -- 
  912. John Baxter    Port Ludlow, WA, USA  [West shore, Puget Sound]
  913.    jwbaxter@pt.olympus.net
  914.  
  915. +++++++++++++++++++++++++++
  916.  
  917. From Frank Price <wprice@jarthur.claremont.edu>
  918. Date: 6 Apr 1994 17:04:27 GMT
  919. Organization: Pomona College
  920.  
  921. In article <bpost-050494183834@bsp.apple.com> Brad Post, bpost@apple.com
  922. writes:
  923. >Okay this is a simple problem to fix (crashing that is).  The problem is
  924. >that you are most likely using the Voodoo Monkey Debugger Init.  It doesn't
  925. >know about the native thread manager, so it's trying to do some gross stuff
  926. >that it shouldn't be doing.  Remove it and you should work just fine.  As
  927. >for the comma, it slipped out, and it should be fixed in the latest/next
  928. >release (or it's an exercise for the programmer !-)
  929.  
  930. I wasn't and haven't ever used Voodoo Monkey.  I also took the suggestions
  931. of others to get the 2.0 release off the April CD instead of 2.0d7.  Same
  932. problem.  Compiling the simple NativeThreads app linking with the xcoff
  933. file, it always crashes with an "access fault exception" at NewThread. 
  934. Would appreciate it if someone could try this out to confirm what I'm
  935. saying.  I'm using DR2 of CodeWarrior.  And again, everything still works
  936. fine for the same code in 68k on the same machine.
  937.  
  938. -Frank
  939. _______________________________________________________________________
  940. | Frank Price   |  wprice@jarthur.claremont.edu                        |
  941. |_______________|______________________________________________________|
  942.  
  943. ---------------------------
  944.  
  945. From piper@char.vnet.net (John Wash)
  946. Subject: RJW: Retrieving application name from OSType Creator
  947. Date: 31 Mar 1994 17:04:19 -0500
  948. Organization: Vnet Internet Access, Inc. - Charlotte, NC. (704) 374-0779
  949.  
  950.  
  951. Hi.  This is done in the Finder, so I'm sure there's a simple way to do 
  952. it.  I have a document reference stored in a database.  I know it's 
  953. four-character Creator.  How do I resolve that Creator into a path to the 
  954. application?
  955.  
  956. I've looked through my old Inside Macs.  It seems to me that it should be 
  957. just a Toolbox call, but I can't seem to find it. 
  958.  
  959. E-mail or followup messages appreciated.
  960.  
  961. Thanks!
  962.  
  963. John Wash
  964. piper@vnet.net
  965.  
  966. -- 
  967. -
  968. John Wash                                               piper@vnet.net
  969. Wee Doggie Musical Instruments                          919-851-4620
  970. "Bagpipes are the missing link between music and noise." --Gordon Mooney
  971.  
  972. +++++++++++++++++++++++++++
  973.  
  974. From jumplong@aol.com (Jump Long)
  975. Date: 5 Apr 1994 12:34:09 -0400
  976. Organization: America Online, Inc. (1-800-827-6364)
  977.  
  978. In article <2nfhd3$1b3@char.vnet.net>, piper@char.vnet.net (John Wash) writes:
  979.  
  980. > How do I resolve that Creator into a path to the 
  981. > application?
  982.  
  983. I'd start by using the Process Manager to look through the list of open
  984. processes to see if the application is already running.
  985.  
  986. If the process isn't running, then use the Desktop Manager's PBDTGetAPPL
  987. function on the mounted volumes to try to locate the application. You'll want
  988. to start with the volume the file with the creator is on and if you don't find
  989. a match there, go on to the boot volume, local volumes, and then last, remote
  990. volumes.  So, until you find a match, here's the steps you'll need to take:
  991.  
  992. 1) Make sure the volume supports the Desktop Manager using PBHGetVolParms
  993. (check for the bHasDesktopMgr attribute bit).
  994.  
  995. 2) Open the desktop database (i.e., get the dtRefNum needed to make calls to
  996. the Desktop Manager) on that volume using PBDTOpenInform. If PBDTOpenInform
  997. fails with a paramErr, then try again using PBDTGetPath to open the desktop
  998. database.
  999.  
  1000. 3) Call PBDTGetAPPL using the creator of the application you want to find.
  1001. Start with ioIndex = 0 to get the newest match in the desktop database, check
  1002. to make sure the application match is really there and if not, increment the
  1003. index, call PBDTGetAPPL again to get the next match. If you get to the end of
  1004. the match list on the volume (with an afpItemNotFound error), try the next
  1005. volume.
  1006.  
  1007. OK, so what if you don't find a match using the Desktop Manager, then you'll
  1008. probably want to try any volumes that *don't* support the Desktop Manager (and
  1009. thus, have the old Desktop resource file). There's more than one way to do
  1010. this. You could simply search the volume (using PBCatSearch) for a file with
  1011. the creator and a file type of 'APPL'.  Or, if you really wanted, you could use
  1012. the Desktop file on the disk volume. Since the Finder already has the Desktop
  1013. file open and you won't be able to open it with the Resource Manager, you'll
  1014. need to make a temporary copy of the Desktop file. You can use the FileCopy
  1015. function in DTS's MoreFiles File Manager sample code to make the copy of the
  1016. Desktop file.  Then you can open it up with the Resource Manager and use the
  1017. 'APPL' resourced to attempt to find a matching application.  The Technical Note
  1018. "Resources Contained in the Desktop File" describes the resources you'll find
  1019. in the Desktop file and in particular, the 'APPL' resources.
  1020.  
  1021. So, what else can you do if none of these things finds an application match?
  1022.  
  1023. You could search each mounted volume for for a file with the creator and a file
  1024. type of 'APPL'.  The CreatorTypeFileSearch function in the MoreFiles sample
  1025. uses CatSearch to quickly search a volume for a file specified by creator and
  1026. file type.
  1027.  
  1028. About the only thing you cannot do that the Finder does is look through the
  1029. Finder's open windows for a match.
  1030.  
  1031. - Jim Luther
  1032.  
  1033.  
  1034. ---------------------------
  1035.  
  1036. From stk@uropax.contrib.de (Stefan Kurth)
  1037. Subject: Range of OSErr's for private use?
  1038. Date: 5 Apr 1994 20:47:50 +0200
  1039. Organization: Contributed Software GbR
  1040.  
  1041. Almost every function that I write returns a value of type OSErr.
  1042. Sometimes it would be desirable to return a private error code of my
  1043. own, rather than one of the Apple ones. Is there a range of values
  1044. that I can safely use for my own #defines, without having to worry
  1045. whether Apple might use them for their system 9.0 implementation of
  1046. the espresso manager or something?
  1047.  
  1048. -Stefan
  1049.  
  1050. _____________________________________________________________________
  1051. Stefan Kurth              Berlin, Germany              stk@contrib.de
  1052.  
  1053. +++++++++++++++++++++++++++
  1054.  
  1055. From gurgle@netcom.com (Pete Gontier)
  1056. Date: Wed, 6 Apr 1994 19:00:25 GMT
  1057. Organization: cellular
  1058.  
  1059. stk@uropax.contrib.de (Stefan Kurth) writes:
  1060.  
  1061. >Almost every function that I write returns a value of type OSErr.
  1062. >Sometimes it would be desirable to return a private error code of my
  1063. >own, rather than one of the Apple ones. Is there a range of values
  1064. >that I can safely use for my own #defines, without having to worry
  1065. >whether Apple might use them for their system 9.0 implementation of the
  1066. >espresso manager or something?
  1067.  
  1068. I was just thinking about this the other night, and my conclusion
  1069. was both yes and no.
  1070.  
  1071. It seems that the majority of error codes that Apple adds are negative.
  1072. They still have thousands left over, but they like to leave gaps in
  1073. between groups of error codes, so they might use positive codes in the
  1074. not-too-distant future. In fact, they already do use some of the lower
  1075. positive codes (for CTB calls). You could risk using relatively high
  1076. positive codes, but it probably wouldn't work in the long run and it
  1077. wouldn't even be guranateed to work in the short run.
  1078.  
  1079. One alternative I thought of is to simply return a 'long'. Since an
  1080. 'OSErr' is nothing but a signed 16-bit quantity, you could use signed
  1081. values which don't fit in 16 bits for your error codes and return a
  1082. 'long'. When you go to report the error, you could determine if the
  1083. value would have fit into an 'OSErr', and if it would have, that's what
  1084. it is, but if it wouldn't have, it must be one of your custom error
  1085. codes. The only problem with this is that if some of your routines
  1086. return an 'OSErr' and others return a 'CustomErr', C won't help you if
  1087. you forget and assign a 'CustomErr' to an 'OSErr'.
  1088.  
  1089.      (A certain Swede who shall be nameless is likely to pop in here and
  1090.      complain that not only should I really be advocating exceptions
  1091.      instead of error codes but also that Pascal would be much better
  1092.      for this scheme because it wouldn't allow you to screw up assigning
  1093.      the function result. To which I say: yeah, and your mother wears
  1094.      army boots! :-)
  1095.  
  1096. Of course, this is not what I personally do. Each of my modules has a
  1097. unique 8-bit "location code", and each module's functions which can
  1098. produce errors produce a 16-bit struct (fits nicely in a register)
  1099. which also contains a non-unique error code. Put the two codes together
  1100. and you have a description of which module caused the error and a a
  1101. description of what the error was which does not rely on 'OSErr'.
  1102. -- 
  1103.  Pete Gontier, CTO, Integer Poet Software; gurgle@netcom.com
  1104.  
  1105. ---------------------------
  1106.  
  1107. From guyyalif@tucson.Princeton.EDU (Guy Udassin Yalif)
  1108. Subject: Simple Q: Assigning char * to char []. How?
  1109. Date: Mon, 4 Apr 1994 21:27:46 GMT
  1110. Organization: Princeton University
  1111.  
  1112. This seems ridiculous: You should be able to assign a char * to 
  1113. an array of characters.  If you declare char a[10], a is a pointer
  1114. to the first of a contiguous group of 10 characters.  Yet when I try
  1115. this on THINK C 6.0.1, it tells me I cannot assign to an array.  If
  1116. I try to get around this with an assignment to &a[0], it tells
  1117. me that an lvalue is required.  This is an error I have gotten 
  1118. many times, and I do not know how to get around it.  ANY help would
  1119. be greatly appreciated!! Thanks for the time.  Guy
  1120. guyyalif@phoenix.princeton.edu
  1121.  
  1122. +++++++++++++++++++++++++++
  1123.  
  1124. From zstern@adobe.com (Zalman Stern)
  1125. Date: Tue, 5 Apr 1994 06:32:24 GMT
  1126. Organization: Adobe Systems Incorporated
  1127.  
  1128. Guy Udassin Yalif writes
  1129. > This seems ridiculous: You should be able to assign a char * to 
  1130. > an array of characters.  If you declare char a[10], a is a pointer
  1131. > to the first of a contiguous group of 10 characters.
  1132.  
  1133. No, a represents an absolute address of ten characters of storage. There is  
  1134. no storage allocated for a pointer (e.g. 4 bytes holding an address) which  
  1135. points to the beginning of that ten byte array. Another way to put this is  
  1136. that the declarations "extern char a[]" and "extern char *a" are very  
  1137. different. The best way to see this is to look at the assembly code  
  1138. generated for the following function:
  1139.  
  1140. extern char an_array[];
  1141. extern char *a_pointer;
  1142.  
  1143. int foo(void)
  1144. {
  1145.     int return_value;
  1146.  
  1147.     return_value = an_array[42];
  1148.     return_value += a_pointer[42];
  1149.  
  1150.     return return_value;
  1151. }
  1152.  
  1153. > Yet when I try
  1154. > this on THINK C 6.0.1, it tells me I cannot assign to an array.  If
  1155. > I try to get around this with an assignment to &a[0], it tells
  1156. > me that an lvalue is required.  This is an error I have gotten 
  1157. > many times, and I do not know how to get around it.  ANY help would
  1158. > be greatly appreciated!! Thanks for the time.  Guy
  1159.  
  1160. The C language specification says that array values are automatically  
  1161. converted to pointer values in most circumstances. It does not say they are  
  1162. the same thing. Think-C is trying to tell you that you do not understand the  
  1163. language. A good reading of the ANSI-C standard or other rigorous C  
  1164. documentation might be in order.
  1165. --
  1166. Zalman Stern           zalman@adobe.com            (415) 962 3824
  1167. Adobe Systems, 1585 Charleston Rd., POB 7900, Mountain View, CA 94039-7900
  1168. "Do right, and risk consequences." Motto of Sam Houston (via Molly Ivins)
  1169.  
  1170. +++++++++++++++++++++++++++
  1171.  
  1172. From d88-jwa@mumrik.nada.kth.se (Jon Wdtte)
  1173. Date: 5 Apr 1994 08:00:58 GMT
  1174. Organization: The Royal Institute of Technology
  1175.  
  1176. In <1994Apr4.212746.24171@Princeton.EDU> guyyalif@tucson.Princeton.EDU (Guy Udassin Yalif) writes:
  1177.  
  1178. >This seems ridiculous: You should be able to assign a char * to 
  1179. >an array of characters.  If you declare char a[10], a is a pointer
  1180.  
  1181. No, you should not. It's right there in K&R 2nd ed (and, indeed,
  1182. 1st ed as well)
  1183.  
  1184. That's because the array is a CONSTANT pointer to a slab of memory
  1185. that lives on the stack or in global space. You can't just move that
  1186. slab of memory; all you can do is copy stuff into or out of the
  1187. memory the array is "pointing to".
  1188.  
  1189. >me that an lvalue is required.  This is an error I have gotten 
  1190. >many times, and I do not know how to get around it.  ANY help would
  1191.  
  1192. You can't. If you want to shove stuff into the actual array memory,
  1193. you should use strcpy() or memcpy() or possibly BlockMove(). If you
  1194. want a variable that can point at different arrays, you should use
  1195. a pointer variable and initialize it first.
  1196. -- 
  1197.  -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe --
  1198.  
  1199.    What we need is a good GNU [...] licence manager implementation.
  1200.                      -- Raphael Manfredi
  1201.  
  1202. ---------------------------
  1203.  
  1204. From potterf@tartarus.uwa.edu.au (Felix Potter)
  1205. Subject: [Q] Validity of a memory address
  1206. Date: 28 Mar 1994 06:54:22 GMT
  1207. Organization: The University of Western Australia
  1208.  
  1209. How does one check that a pointer is valid?  (Without dereferencing it and
  1210. possibly crashing the machine.)  At the moment my definition for a pointer
  1211. that is at least _possibly_ OK is:
  1212.     not null (ie. not equal to 0), and
  1213.     even (ie. not divisble by 2), and
  1214.     > ApplZone (low memory global), and
  1215.     < ApplLimit (low memory global)
  1216. So if my pointer fails one of these conditions, then I know straight away
  1217. that something has gone wrong.  Does anyone have any comments on either how
  1218. reasonable or, on the other hand, how totally stupid the above description is?
  1219. Any suggestions for better ways of going about it?
  1220.  
  1221. The reason I want to be able to check _quickly_ whether a pointer is valid
  1222. or not is that I am writing a few little 'wrapper' macros/functions to
  1223. go around the standard C malloc/calloc/realloc/free functions.  I realise that
  1224. just about every man and his dog has done this before me, but hey, I'm
  1225. having fun :)  One of the things I would like to be able to do is detect
  1226. heap corruption, and corruption of my record keeping information in
  1227. particular, and so I'd like to be able to tell if dereferencing a pointer
  1228. is going to crash my code or not before I do it, in a few strategic places.
  1229. Hence my above query.
  1230.  
  1231. Also, I'm going to be asking in come more general-purpose newsgroups, but
  1232. does anyone have any ideas about how to check pointers on other systems,
  1233. DOS and UNIX in particular?
  1234.  
  1235. Thanks for any help (or even idle flames, if I'm being particularly stupid :)
  1236.  
  1237. --
  1238. ____________________________________________________________________________
  1239.  Felix Potter                                   potterf@lethe.uwa.edu.au
  1240.                                                 potterf@tartarus.uwa.edu.au
  1241.  University of Western Australia, Perth.        potter_f@cs.uwa.edu.au
  1242.  
  1243. +++++++++++++++++++++++++++
  1244.  
  1245. From potterf@tartarus.uwa.edu.au (Felix Potter)
  1246. Date: 28 Mar 1994 06:58:21 GMT
  1247. Organization: The University of Western Australia
  1248.  
  1249. I (potterf@tartarus.uwa.edu.au), in a fit of stupidity, wrote:
  1250. > How does one check that a pointer is valid?  (Without dereferencing it and
  1251. > possibly crashing the machine.)  At the moment my definition for a pointer
  1252. > that is at least _possibly_ OK is:
  1253. >     not null (ie. not equal to 0), and
  1254. >     even (ie. not divisble by 2), and
  1255.       ^^^^      ^^^^^^^^^^^^^^^^^
  1256.  
  1257. Oops *blush* :)
  1258.  
  1259. Obviously I mean "divisible by 2."
  1260.  
  1261. --
  1262. ____________________________________________________________________________
  1263.  Felix Potter                                   potterf@lethe.uwa.edu.au
  1264.                                                 potterf@tartarus.uwa.edu.au
  1265.  University of Western Australia, Perth.        potter_f@cs.uwa.edu.au
  1266.  
  1267. +++++++++++++++++++++++++++
  1268.  
  1269. From Cameron Esfahani <dirty@guest.apple.com>
  1270. Date: Mon, 4 Apr 1994 04:42:50 GMT
  1271. Organization: Apple Computer, Inc.
  1272.  
  1273. In article <2n5uuu$ekq@styx.uwa.edu.au> Felix Potter,
  1274. potterf@tartarus.uwa.edu.au writes:
  1275. > How does one check that a pointer is valid?  (Without dereferencing it and
  1276. > possibly crashing the machine.)  At the moment my definition for a pointer
  1277. > that is at least _possibly_ OK is:
  1278. >     not null (ie. not equal to 0), and
  1279. >     even (ie. not divisble by 2), and
  1280. >     > ApplZone (low memory global), and
  1281. >     < ApplLimit (low memory global)
  1282. > So if my pointer fails one of these conditions, then I know straight away
  1283. > that something has gone wrong.  Does anyone have any comments on either how
  1284. > reasonable or, on the other hand, how totally stupid the above description
  1285. is?
  1286. > Any suggestions for better ways of going about it?
  1287. > The reason I want to be able to check _quickly_ whether a pointer is valid
  1288. > or not is that I am writing a few little 'wrapper' macros/functions to
  1289. > go around the standard C malloc/calloc/realloc/free functions.  I realise
  1290. that
  1291. > just about every man and his dog has done this before me, but hey, I'm
  1292. > having fun :)  One of the things I would like to be able to do is detect
  1293. > heap corruption, and corruption of my record keeping information in
  1294. > particular, and so I'd like to be able to tell if dereferencing a pointer
  1295. > is going to crash my code or not before I do it, in a few strategic places.
  1296. > Hence my above query.
  1297. > Also, I'm going to be asking in come more general-purpose newsgroups, but
  1298. > does anyone have any ideas about how to check pointers on other systems,
  1299. > DOS and UNIX in particular?
  1300. > Thanks for any help (or even idle flames, if I'm being particularly stupid :)
  1301.  
  1302. Well, try installing your own Bus Error Handler and dereference
  1303. the pointer.  If you get called in your Bus Error Handler, then it
  1304. is not a valid pointer.  If you don't, it's valid....
  1305.  
  1306. Cameron Esfahani
  1307. dirty@apple.com
  1308.  
  1309. +++++++++++++++++++++++++++
  1310.  
  1311. From ari@world.std.com (Ari I Halberstadt)
  1312. Date: Mon, 4 Apr 1994 06:26:22 GMT
  1313. Organization: The World Public Access UNIX, Brookline, MA
  1314.  
  1315. In article <2n5uuu$ekq@styx.uwa.edu.au>,
  1316. Felix Potter <potterf@tartarus.uwa.edu.au> wrote:
  1317. >How does one check that a pointer is valid?  (Without dereferencing it and
  1318. >possibly crashing the machine.)  At the moment my definition for a pointer
  1319. >that is at least _possibly_ OK is:
  1320. >    not null (ie. not equal to 0), and
  1321. >    even (ie. not divisble by 2), and
  1322. >    > ApplZone (low memory global), and
  1323. >    < ApplLimit (low memory global)
  1324. >So if my pointer fails one of these conditions, then I know straight away
  1325. >that something has gone wrong.  Does anyone have any comments on either how
  1326. >reasonable or, on the other hand, how totally stupid the above description is?
  1327. >Any suggestions for better ways of going about it?
  1328.  
  1329. Those are most of the tests you'd ever need. If you get a crash from
  1330. dereferencing a pointer after doing those checks then I'd be pretty
  1331. surprised. If you didn't mind the speed hit, you could look for the
  1332. pointer in some private table of valid pointers, using some sort of
  1333. binary tree, for instance. What these tests don't tell you, however,
  1334. is whether the contents of the pointer are valid.
  1335.  
  1336. What I've done in my applications is create a header that is placed at
  1337. the start of every pointer allocated. The header contains the size of
  1338. the pointer and a 4-byte signature code. A unique signature code is
  1339. used for every type of object I allocate. Then I do something like
  1340. this:
  1341.  
  1342. ObjectPtr NewObject(...) {
  1343.   ObjectPtr object = NewObjectPtr(sizeof(ObjectType), 'objp');
  1344.   ...
  1345.   assert(ValidObject(object));
  1346.   return(object);
  1347. }
  1348.  
  1349. Boolean ValidObject(ObjectPtr object) {
  1350.   if (! ValidObjectPtr(object, sizeof(ObjectType), 'objp')) return(false);
  1351.   ... more tests to check relationships among members of the object ...
  1352. }
  1353.  
  1354. void DoSomethingToObject(ObjectPtr object) {
  1355.   assert(ValidObject(object));
  1356.   ... use object ...
  1357.   assert(ValidObject(object));
  1358. }
  1359.  
  1360. The function ValidObjectPtr compares the size and ID code passed to it
  1361. as parameters with the values stored in the pointer's header. If they
  1362. differ, then the pointer is deemed invalid and false is returned. The
  1363. function also checks that the pointer's header and the end of the
  1364. pointer are within the application's heap zone.
  1365.  
  1366. As a further enhancement, you could store a trailer at the end of each
  1367. pointer. The trailer would contain the same 4-byte id code, and would
  1368. help catch errors that resulted from overwriting the end of the
  1369. pointer.
  1370.  
  1371. Also, when you allocate a pointer, fill it with some random (or not so
  1372. random) garbage. Something like 0xff works pretty well and is easy to
  1373. spot with a debugger. Using an odd value like 0xff is also good since
  1374. any members of the object that are pointers will be detected as
  1375. illegal pointers (since they'll be odd integers). When you dispose of
  1376. the pointer, again fill it with 0xff, since this will ensure that you
  1377. won't be able to use its contents without immediate errors.
  1378. Alternatively, you could zero the pointer when you allocate it, thus
  1379. removing the need to initialize members to a default value. However,
  1380. you should still fill the pointer with invalid data when it is
  1381. disposed of. My personal preference is to zero program objects but to
  1382. fill data pointers with 0xff bits. I disable the filling of memory
  1383. with 0xff bits for greater efficiency in the final application
  1384.  
  1385. If you were really paranoid, you could checksum the contents of the
  1386. pointer. For instance, instead of just calling ValidObject, you could
  1387. do something like:
  1388.  
  1389.   CheckInObject(object);
  1390.   ...
  1391.   CheckOutObject(object);
  1392.  
  1393. CheckInObject would calculate a checksum for the object and compare it
  1394. with the checksum saved in the pointer's header. If the checksums
  1395. differ, CheckInObject would fail (e.g., raise an exception). Then, it
  1396. would call ValidObject, and finally it would increment a counter to
  1397. indicate that the object had been checksummed and is in use. A value
  1398. greater than zero for the counter would prevent further calls to
  1399. CheckInObject from calculating a checksum or calling ValidObject.
  1400. CheckOutObject would decrement the counter each time it is called.
  1401. When the matching call to CheckOutObject is made (the counter is zero)
  1402. then a new checksum would be calculated for the object and the
  1403. checksum would be stored in the pointer's header. This should be
  1404. reasonably efficient and quite robust. You could make CheckInObject
  1405. and CheckOutObject macros that you could undefine when debug code was
  1406. disabled, or could change the macros so that they didn't do the
  1407. checksum operation in the final product. I haven't used this method
  1408. yet in my own applications, but I'm thinking of adding it.
  1409.  
  1410. >
  1411. >The reason I want to be able to check _quickly_ whether a pointer is valid
  1412. >or not is that I am writing a few little 'wrapper' macros/functions to
  1413. >go around the standard C malloc/calloc/realloc/free functions.  I realise that
  1414. >just about every man and his dog has done this before me, but hey, I'm
  1415. >having fun :)  One of the things I would like to be able to do is detect
  1416. >heap corruption, and corruption of my record keeping information in
  1417. >particular, and so I'd like to be able to tell if dereferencing a pointer
  1418. >is going to crash my code or not before I do it, in a few strategic places.
  1419. >Hence my above query.
  1420.  
  1421. To check the heap, you can just use MacsBug or TMON with heap check
  1422. enabled.  It works pretty well for most things. With TMON, one problem
  1423. is that by the time the heap is corrupted you can't figure out where
  1424. it failed in your code since all of the function labels are gone (it's
  1425. kind of a pain to get around this problem).
  1426.  
  1427. I like to validate memory on several different levels. The most
  1428. secure, but slowest, level is used during development. Less checks are
  1429. done in a beta level, and most (or all) checks are disabled in a
  1430. release version. However, lately, my memory checks have been fairly
  1431. fast (they used to be really slow), so I'm thinking of leaving at
  1432. least some of them in the release level.
  1433.  
  1434. Just checking the validity of pointers before calling memory
  1435. allocation and disposal routines is better than nothing, but overall
  1436. is not very secure. A pointer can easily become corrupted long before
  1437. free is ever called on it. You can also do a lot of extra verification
  1438. if you provide type information (like a four-byte code) in your code.
  1439. If you get fancy, you can even check the logical relationships among
  1440. the members of your objects. Checking logical relationships helps
  1441. catch additional programmatic errors.
  1442.  
  1443. >Also, I'm going to be asking in come more general-purpose newsgroups, but
  1444. >does anyone have any ideas about how to check pointers on other systems,
  1445. >DOS and UNIX in particular?
  1446.  
  1447. All of the checks I described above can be used on Unix systems. You
  1448. might have trouble finding something equivalent to ApplZone/ApplLimit
  1449. on Unix, but there's probably some equivalent, even if it's not
  1450. totally portable. The checks should probably also work with DOS
  1451. systems.  The interpretation of multiple byte character constants is
  1452. not defined by the language, so things like 'objp' may have to be
  1453. modified (e.g., use defines in some common memory header, don't
  1454. scatter the constants all over the place).
  1455.  
  1456. -- 
  1457. Ari Halberstadt    ari@world.std.com     #include <std/disclaimer.h>
  1458. "These beetles were long considered to be very rare because very few
  1459. entomologists look for beetles in the mountains, in winter, at night,
  1460. during snow storms." -- Purves W. K., et al, "Life: The Science of
  1461.  
  1462. +++++++++++++++++++++++++++
  1463.  
  1464. From Alexander M. Rosenberg <alexr@apple.com>
  1465. Date: Mon, 4 Apr 1994 12:39:22 GMT
  1466. Organization: Hackers Anonymous
  1467.  
  1468. In article <1994Apr4.044250.27756@gallant.apple.com> Cameron Esfahani,
  1469. dirty@guest.apple.com writes:
  1470. > Well, try installing your own Bus Error Handler and dereference
  1471. > the pointer.  If you get called in your Bus Error Handler, then it
  1472. > is not a valid pointer.  If you don't, it's valid....
  1473.  
  1474. Trouble-maker.
  1475. - -------------------------------------------------------------------------
  1476. -  Alexander M. Rosenberg  - INTERNET: alexr@apple.com      - Yoyodyne    -
  1477. -  330 Waverley St., Apt B - UUCP:ucbvax!apple!alexr        - Propulsion  -
  1478. -  Palo Alto, CA 94301     -                                - Systems     -
  1479. -  (415) 329-8463          - Nobody is my employer so       - :-)         -
  1480. -                          - nobody cares what I say.       -             -
  1481.  
  1482. +++++++++++++++++++++++++++
  1483.  
  1484. From jbrowne@zaphod.ncsa.uiuc.edu (Jim Browne)
  1485. Date: 5 Apr 94 05:34:57 GMT
  1486. Organization: University of Illinois at Urbana
  1487.  
  1488. ari@world.std.com (Ari I Halberstadt) writes:
  1489.  
  1490. >What I've done in my applications... 
  1491.  
  1492. Ari offers some good suggestions.  I once saw most of his suggestions
  1493. implemented in a library that was published in MacTech (MacTutor?) a while
  1494. back.  I can't remember the name of the article, but I remember the library
  1495. functioned on the principle of wrapping accesses to your data with MMUse and
  1496. MMUnuse.  The idea being that you had to call MMUse to be able to use your
  1497. data and must call MMUnuse as soon as you were done with it at that point.
  1498. This allowed for all kinds of nifty things the library could do behind your
  1499. back, like checksumming, checking for leaks, and even some primitive virtual
  1500. memory techniques.  If I could remember the names of the authors, I'd cite
  1501. them for you.
  1502.  
  1503. (Was it 'MemMan'?)
  1504. -- 
  1505. Jim Browne                                             | jbrowne@ncsa.uiuc.edu |
  1506. Head NCSA Mac Telnet Hacker, SDG System Administrator  | (217) 244-7798        |
  1507. <a href="http://www.ncsa.uiuc.edu/SDG/People/jbrowne/jbrowne.html">Click me</a>
  1508.                     "Not me, not yet, not that bad."
  1509.  
  1510. +++++++++++++++++++++++++++
  1511.  
  1512. From jbrowne@zaphod.ncsa.uiuc.edu (Jim Browne)
  1513. Date: 5 Apr 94 07:28:00 GMT
  1514. Organization: University of Illinois at Urbana
  1515.  
  1516. jbrowne@zaphod.ncsa.uiuc.edu (Jim Browne) writes:
  1517.  
  1518. >ari@world.std.com (Ari I Halberstadt) writes:
  1519.  
  1520. >>What I've done in my applications... 
  1521.  
  1522. >Ari offers some good suggestions.  I once saw most of his suggestions
  1523. >implemented in a library that was published in MacTech (MacTutor?) a while
  1524. >back.  I can't remember the name of the article, but I remember the library
  1525. >functioned on the principle of wrapping accesses to your data with MMUse and
  1526. >MMUnuse.  The idea being that you had to call MMUse to be able to use your
  1527. >data and must call MMUnuse as soon as you were done with it at that point.
  1528. >This allowed for all kinds of nifty things the library could do behind your
  1529. >back, like checksumming, checking for leaks, and even some primitive virtual
  1530. >memory techniques.  If I could remember the names of the authors, I'd cite
  1531. >them for you.
  1532.  
  1533. Well, I've gone and looked up the article.  Thanks to those great people at
  1534. MacTech, I was able to grep the text index of articles for MacTech vols. 1-8.
  1535.  
  1536. Here's the reference:
  1537.  
  1538. "A Memory Manager for the Rest of US." by Jordan Zimmerman.  Vol. 7 No. 9 Pg. 40
  1539.  
  1540.  
  1541. -- 
  1542. Jim Browne                                             | jbrowne@ncsa.uiuc.edu |
  1543. Head NCSA Mac Telnet Hacker, SDG System Administrator  | (217) 244-7798        |
  1544. <a href="http://www.ncsa.uiuc.edu/SDG/People/jbrowne/jbrowne.html">Click me</a>
  1545. --"It's really weird... kind of like how Telnet is programmed." - Q. Koziol --
  1546.  
  1547. ---------------------------
  1548.  
  1549. From Ben J Fry <bf2c+@andrew.cmu.edu>
  1550. Subject: textedit bounds
  1551. Date: Tue,  5 Apr 1994 21:15:13 -0400
  1552. Organization: Freshman, Design, Carnegie Mellon, Pittsburgh, PA
  1553.  
  1554. does anyone know how to figure out the real boundaries for a styled
  1555. textedit field? that is, the natural boundary rectangle that the text
  1556. would fit in...
  1557.  
  1558. any help would be really appreciated.. i've nearly worn out my think
  1559. reference in trying to look for this... (if that's possible...)
  1560.  
  1561.  
  1562. ben
  1563.  
  1564. +++++++++++++++++++++++++++
  1565.  
  1566. From ari@world.std.com (Ari I Halberstadt)
  1567. Date: Wed, 6 Apr 1994 21:27:41 GMT
  1568. Organization: The World Public Access UNIX, Brookline, MA
  1569.  
  1570. In article <MhcUoV200iV8IC9nE_@andrew.cmu.edu>,
  1571. Ben J Fry  <bf2c+@andrew.cmu.edu> wrote:
  1572. >does anyone know how to figure out the real boundaries for a styled
  1573. >textedit field? that is, the natural boundary rectangle that the text
  1574. >would fit in...
  1575. >
  1576. >any help would be really appreciated.. i've nearly worn out my think
  1577. >reference in trying to look for this... (if that's possible...)
  1578. >
  1579. >
  1580. >ben
  1581.  
  1582.  
  1583. Assuming you have word wrap turned on, you can find the width of the
  1584. text from the width of the destination rectangle. You can get the
  1585. height of the text with TEGetHeight. If you don't have word wrap
  1586. turned on, then you can either assume some maximum width, say 72
  1587. inches (5184 pixels). This is a large enough value to ensure that the
  1588. user can view most text, without making the horizontal scroll bar
  1589. as useless as a value of 32767 would. If you really want to be
  1590. accurate, then you you can calculate the width of the widest line in
  1591. the text. Here's some code to do this for both styled and unstyled
  1592. text. It knows way too much about TextEdit internals, but hey, it
  1593. works :-)
  1594.  
  1595. A few utility functions:
  1596.  
  1597. typedef unsigned long TicksType;
  1598. typedef SignedByte HandleStateType;
  1599.  
  1600. HandleStateType HandleLock(void *h)
  1601. {
  1602.   HandleStateType state;
  1603.  
  1604.   state = HGetState(h);
  1605.   HLock(h);
  1606.   return(state);
  1607. }
  1608.  
  1609. void HandleStateSet(void *h, HandleStateType state)
  1610. {
  1611.   HSetState(h, state);
  1612. }
  1613.  
  1614. // word wrap macros
  1615. #define TEWrap(te)          ((**(te)).crOnly >= 0)
  1616. #define TEWrapSet(wrap, te) ((void) ((**(te)).crOnly = ((wrap) ? 1 : -1)))
  1617.  
  1618. static Boolean TEOldStyle(TEHandle te)
  1619. {
  1620.     return((**te).txSize != -1);
  1621. }
  1622.  
  1623. /* Calculate the width of the widest line in the line range. If the
  1624.    operation takes longer than 'timeout' ticks to compute, then the
  1625.    last line reached is returned in 'finalLine', and the result of
  1626.    the function is the width of the widest line between 'firstLine'
  1627.    and 'finalLine'. Otherwise (i.e., no timeout), the result of the
  1628.    function is the width of the widest line and 'finalLine' is equal
  1629.    to 'lastLine'.
  1630.    
  1631.    The time out is provided since calculating the widths of the lines--
  1632.    especially for long styled text documents--can take quite a while, and
  1633.    doing so every time the document changes could be prohibitively slow.
  1634.    Instead, if 'finalLine' is less than 'lastLine', then after processing some
  1635.    events, the application can continue to call this function, passing
  1636.    the value of 'finalLine' as the 'firstLine' parameter, until 'finalLine'
  1637.    is equal to 'lastLine', at which point the maximum of the values returned
  1638.    by the successive calls to this function will be the width of the widest
  1639.    line in the original line range. */
  1640. static short TEWidthUnstyled(short firstLine, short lastLine,
  1641.    TicksType timeout, long *finalLine, TEHandle te)
  1642. {
  1643.    HandleStateType   svTextHandleState;    /* saved state of handle to text */
  1644.    GrafPtr           svPort;               /* saved graf port */
  1645.    Ptr               textPtr;              /* pointer to text */
  1646.    short             textWidth;            /* width of text */
  1647.    short             lineIndex;            /* current line number */
  1648.    short             lineLongest;          /* length of longest line */
  1649.    short             lineStart;            /* first character of line */
  1650.    short             lineEnd;              /* last character of line */
  1651.    long              startTicks            /* time when we started */
  1652.    short             txFont, txSize, txFace;   /* saved text state */
  1653.       
  1654.    require(TEOldStyle(te));
  1655.    
  1656.    /* quick out */
  1657.    if ((**te).nLines == 0) return(0);
  1658.       
  1659.    /* keep track of elapsed time */
  1660.    startTicks = TickCount();
  1661.    
  1662.    /* find longest line */
  1663.    lineStart = lineEnd = lineLongest = 0;
  1664.    for (lineIndex = firstLine; lineIndex < lastLine; lineIndex++) {
  1665.  
  1666.       /* remember length of longest line encountered so far */
  1667.       if (lineLongest < (**te).lineStarts[lineIndex + 1] - (**te).lineStarts[lineIndex]) {
  1668.          lineStart = (**te).lineStarts[lineIndex];
  1669.          lineEnd = (**te).lineStarts[lineIndex + 1];
  1670.          lineLongest = lineEnd - lineStart;
  1671.       }
  1672.  
  1673.       /* stop if took too long */
  1674.       if (TickCount() - startTicks > timeout)
  1675.          break;
  1676.    }
  1677.    
  1678.    /* calculate width of longest line */
  1679.    GetPort(&svPort);
  1680.    SetPort((**te).inPort);
  1681.    txFont = (**te).inPort->txFont;
  1682.    txSize = (**te).inPort->txSize;
  1683.    txFace = (**te).inPort->txFace;
  1684.    TextFont((**te).txFont);
  1685.    TextSize((**te).txSize);
  1686.    TextFace((**te).txFace);
  1687.    svTextHandleState = HandleLock((**te).hText);
  1688.    textPtr = *(**te).hText;
  1689.    textWidth = TextWidth(textPtr, lineStart, lineEnd - lineStart);
  1690.    HandleStateSet((**te).hText, svTextHandleState);
  1691.    TextFont(txFont);
  1692.    TextSize(txSize);
  1693.    TextFace(txFace);
  1694.    SetPort(svPort);
  1695.  
  1696.    *finalLine = lineIndex;
  1697.    return(textWidth);
  1698. }
  1699.  
  1700. /* see description of TEWidthUnstyled */
  1701. static short TEWidthStyled(short firstLine, short lastLine, TicksType timeout,
  1702.    long *finalLine, TEHandle te)
  1703. {
  1704.    HandleStateType   svTextHandleState;      /* saved state of handle to text */
  1705.    HandleStateType   svStyleHandleState;     /* saved state of handle to style record */
  1706.    HandleStateType   svStyleTableState;      /* saved state of handle to style table */
  1707.    GrafPtr           svPort;                 /* saved graf port */
  1708.    TEStylePtr        stylePtr;               /* text's style record */
  1709.    STPtr             styleTable;             /* text's style table */
  1710.    StyleRun         *runPtr;                 /* style runs array */
  1711.    short             runStart;               /* start of next style run */
  1712.    Ptr               textPtr;                /* pointer to text */
  1713.    short             textLength;             /* length of text run */
  1714.    short             textWidth;              /* width of text */
  1715.    short             lineWidth;              /* width of current line */
  1716.    short             lineIndex;              /* current line number */
  1717.    short             lineStart;              /* first character of line */
  1718.    short             lineEnd;                /* last character of line */
  1719.    long              startTicks;             /* time when we started */
  1720.    short             txFont, txSize, txFace; /* saved text state */
  1721.    
  1722.    require(! TEOldStyle(te));
  1723.    
  1724.    /* quick out */
  1725.    if ((**te).nLines == 0) return(0);
  1726.  
  1727.    /* keep track of elapsed time */
  1728.    startTicks = TickCount();
  1729.    
  1730.    /* setup port */   
  1731.    GetPort(&svPort);
  1732.    SetPort((**te).inPort);
  1733.    txFont = (**te).inPort->txFont;
  1734.    txSize = (**te).inPort->txSize;
  1735.    txFace = (**te).inPort->txFace;
  1736.    
  1737.    /* lock and dereference handles */
  1738.    svTextHandleState = HandleLock((**te).hText);
  1739.    textPtr = *(**te).hText;
  1740.    svStyleHandleState = HandleLock(GetStylHandle(te));
  1741.    stylePtr = *GetStylHandle(te);
  1742.    svStyleTableState = HandleLock(stylePtr->styleTab);
  1743.    styleTable = *stylePtr->styleTab;
  1744.    
  1745.    /* initialize loop */
  1746.    textWidth = 0;
  1747.    runPtr = stylePtr->runs;
  1748.    runStart = runPtr[1].startChar;
  1749.    TextFont(styleTable[runPtr->styleIndex].stFont);
  1750.    TextFace(styleTable[runPtr->styleIndex].stFace);
  1751.    TextSize(styleTable[runPtr->styleIndex].stSize);
  1752.    
  1753.    /* calculate widths of all lines */
  1754.    for (lineIndex = firstLine; lineIndex < lastLine; lineIndex++) {
  1755.    
  1756.       /* calculate width of line */
  1757.       lineWidth = 0;
  1758.       lineStart = (**te).lineStarts[lineIndex];
  1759.       lineEnd = (**te).lineStarts[lineIndex + 1];
  1760.       while (lineStart < lineEnd) {
  1761.          if (lineStart == runStart) {
  1762.             /* use next style run (assumes run array is sorted by startChar) */
  1763.             runPtr++;
  1764.             runStart = runPtr[1].startChar;
  1765.             check(runPtr->startChar == lineStart);
  1766.             TextFont(styleTable[runPtr->styleIndex].stFont);
  1767.             TextFace(styleTable[runPtr->styleIndex].stFace);
  1768.             TextSize(styleTable[runPtr->styleIndex].stSize);
  1769.          }
  1770.          /* calculate width of style run */
  1771.          check(lineStart < runStart);
  1772.          textLength = min(lineEnd - lineStart, runStart - lineStart);
  1773.          check(textLength >= 1);
  1774.          lineWidth += TextWidth(textPtr, lineStart, textLength);
  1775.          lineStart += textLength;
  1776.       }
  1777.       textWidth = max(textWidth, lineWidth);
  1778.       
  1779.       /* stop if took too long */
  1780.       if (TickCount() - startTicks > timeout)
  1781.          break;
  1782.    }
  1783.  
  1784.    /* restore saved state */
  1785.    HandleStateSet(RecoverHandle((Ptr) styleTable), svStyleTableState);
  1786.    HandleStateSet(RecoverHandle((Ptr) stylePtr), svStyleHandleState);
  1787.    HandleStateSet(RecoverHandle((Ptr) textPtr), svTextHandleState);
  1788.    TextFont(txFont);
  1789.    TextSize(txSize);
  1790.    TextFace(txFace);
  1791.    SetPort(svPort);
  1792.    
  1793.    *finalLine = lineIndex;
  1794.    return(textWidth);
  1795. }
  1796.  
  1797. /* see description of TEWidthUnstyled */
  1798. short TEWidthTimeout(short start, short end,
  1799.    TicksType timeout, long *final, TEHandle te)
  1800. {
  1801.    return(TEOldStyle(te) ? TEWidthUnstyled(start, end, timeout, final, te) :
  1802.                            TEWidthStyled(start, end, timeout, final, te));
  1803. }
  1804.  
  1805. /* calculate the width of the widest line in the line range */
  1806. short TEWidth(short start, short end, TEHandle te)
  1807. {
  1808.    return(TEWidthTimeout(start, end, LONG_MAX, 0, te));
  1809. }
  1810. -- 
  1811. Ari Halberstadt    ari@world.std.com     #include <std/disclaimer.h>
  1812. "These beetles were long considered to be very rare because very few
  1813. entomologists look for beetles in the mountains, in winter, at night,
  1814. during snow storms." -- Purves W. K., et al, "Life: The Science of
  1815.  
  1816. ---------------------------
  1817.  
  1818. End of C.S.M.P. Digest
  1819. **********************
  1820.  
  1821.