home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / csmpdigest / csmp-digest-v3-067 < prev    next >
Text File  |  2010-09-21  |  132KB  |  3,372 lines

  1. C.S.M.P. Digest             Mon, 14 Nov 94       Volume 3 : Issue 67
  2.  
  3. Today's Topics:
  4.  
  5.         (Q) AppleScript & XCMD's
  6.         Can anyone help me with the Time Manager?
  7.         Dynamic Dialogs?
  8.         How to install your own templates using Macsbug 6.5d6???
  9.         IM: Networking book question
  10.         INIT Writing FAQ [1-3]
  11.         INIT Writing FAQ [2-3]
  12.         INIT Writing FAQ [3-3]
  13.         Linking 68k object files to PPC program
  14.         Network Programming
  15.         Stuck in SyncWait again
  16.         having trouble with AEInteractWithUser & drag manager
  17.  
  18.  
  19.  
  20. The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
  21. (pottier@clipper.ens.fr).
  22.  
  23. The digest is a collection of article threads from the internet newsgroup
  24. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  25. regularly and want an archive of the discussions.  If you don't know what a
  26. newsgroup is, you probably don't have access to it.  Ask your systems
  27. administrator(s) for details.  If you don't have access to news, you may
  28. still be able to post messages to the group by using a mail server like
  29. anon.penet.fi (mail help@anon.penet.fi for more information).
  30.  
  31. Each issue of the digest contains one or more sets of articles (called
  32. threads), with each set corresponding to a 'discussion' of a particular
  33. subject.  The articles are not edited; all articles included in this digest
  34. are in their original posted form (as received by our news server at
  35. nef.ens.fr).  Article threads are not added to the digest until the last
  36. article added to the thread is at least two weeks old (this is to ensure that
  37. the thread is dead before adding it to the digest).  Article threads that
  38. consist of only one message are generally not included in the digest.
  39.  
  40. The digest is officially distributed by two means, by email and ftp.
  41.  
  42. If you want to receive the digest by mail, send email to listserv@ens.fr
  43. with no subject and one of the following commands as body:
  44.     help                        Sends you a summary of commands
  45.     subscribe csmp-digest Your Name    Adds you to the mailing list
  46.     signoff csmp-digest            Removes you from the list
  47. Once you have subscribed, you will automatically receive each new
  48. issue as it is created.
  49.  
  50. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
  51. Questions related to the ftp site should be directed to
  52. scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
  53. digest are available there.
  54.  
  55. Also, the digests are available to WAIS users.  To search back issues
  56. with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
  57. http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.
  58.  
  59.  
  60. -------------------------------------------------------
  61.  
  62. >From Tom_Brodhurst-Hill@intouch.mpx.com.au (Tom Brodhurst-Hill)
  63. Subject: (Q) AppleScript & XCMD's
  64. Date: 31 Oct 1994 19:07:41 GMT
  65. Organization: MacInTouch BBS
  66.  
  67. Can anyone tell me whether XCMD's (typically for HyperCard) can be included
  68. in
  69. and accessed by a compiled AppleScript application, without running a
  70. separate HyperCard process?
  71. Thanks,
  72. Tom
  73. please email to tombh@intouch.mpx.com.au
  74. and post too for others.
  75.                             MacInTouch BBS
  76. info@intouch.mpx.com.au     Ph. 61 2 541 1287    BBS. 61 2 541 0799
  77. *** Sent by FirstClass the graphical email system by SoftArc. Inc. ***
  78.  
  79. +++++++++++++++++++++++++++
  80.  
  81. >From lai@apple.com (Ed Lai)
  82. Date: Mon, 31 Oct 1994 17:20:39 GMT
  83. Organization: Apple
  84.  
  85. In article <29224926.900353@intouch.intouch.mpx.com.au>,
  86. Tom_Brodhurst-Hill@intouch.mpx.com.au (Tom Brodhurst-Hill) wrote:
  87.  
  88. > Can anyone tell me whether XCMD's (typically for HyperCard) can be included
  89. in
  90. > and accessed by a compiled AppleScript application, without running a
  91. > separate HyperCard process?
  92. > Thanks,
  93. > Tom
  94. > please email to tombh@intouch.mpx.com.au
  95. > and post too for others.
  96. >                             MacInTouch BBS
  97. > info@intouch.mpx.com.au     Ph. 61 2 541 1287    BBS. 61 2 541 0799
  98. > *** Sent by FirstClass the graphical email system by SoftArc. Inc. ***
  99.  
  100. It depends on the XCMD, a lot of them can be used, but if they are
  101. very dependent on HyperCard specifc callback or globals, then they
  102. cannot.
  103.  
  104. Try to download the XCMD OSAX.
  105.  
  106. Generally the place to look for AppleScript related stuff is in
  107. gaea.kgs.ukans.edu.
  108.  
  109. If it is just for the XCMD OSAX, you may try ftp.apple.com in
  110. /pub/lai/osax.
  111.  
  112. It is an adaptor for AppleScript to use XCMDs. It also comes installed
  113. with a number of XCMDs by Rinaldi as examples.
  114.  
  115. In theory you can try it with any other XCMD/XFCNs you got. However to
  116. do that requires writing certain resources and that is not a easy
  117. job if you are doing it the first time.
  118.  
  119. -- 
  120. /* Disclaimer: All statments and opinions expressed are my own */
  121. /* Edmund K. Lai                                               */
  122. /* Apple Computer, MS303-3A                                    */
  123. /* 20525 Mariani Ave,                                          */
  124. /* Cupertino, CA 95014                                         */
  125. /* (408)974-6272                                               */
  126. zW@h9cOi
  127.  
  128. ---------------------------
  129.  
  130. >From anthonym@puree.ugcs.caltech.edu (Anthony Molinaro)
  131. Subject: Can anyone help me with the Time Manager?
  132. Date: 21 Oct 1994 08:09:59 GMT
  133. Organization: California Institute of Technology, Pasadena
  134.  
  135.  
  136. I worked on this piece of code for a friend using Symatec 
  137. THINK C which turns on the power to a digital I/O board, 
  138. delays for a certain number of ticks, and then turns the 
  139. power off. This was my first time programming on a Macintosh 
  140. and so I had to search a little bit to find out about Delay.  
  141. Now, he tells me he needs a delay time smaller than one tick.  
  142. I know that the time manager can do this but I have been 
  143. unable to get it to work.  I guess my confusion arises in the
  144. type declarations and getting all of the types to match for 
  145. functions InsXTime(), PrimeTime(), and such.  The Inside 
  146. Macintosh doesn't have any examples in C and I have not been 
  147. able to accurately port the Pascal functions with the proper
  148. type settings.  My midterms are quickly approaching but I 
  149. promised I would help him out, so any help that anyone could
  150. give would be .
  151.  
  152.  
  153.  
  154. /* Here is the original code */
  155.  
  156. void Play(int note, unsigned long time)
  157. {  long finalTicks;
  158.    short error;
  159.  
  160.    /* turn on power for port,line: portout, lineout */
  161.    error = DIG_Out_Line(4, notes[note].portout, notes[note].line, 1);
  162.    chkerr("DIG_Out_Line",error);
  163.  
  164.    /* if power is on delay */
  165.    if(error == 0)
  166.      Delay(time,&finalTicks);
  167.  
  168.    /* turn off power */
  169.    error = DIG_Out_Line(4, notes[note].portout, notes[note].line, 0);
  170.    chkerr("DIG_Out_Line",error);
  171. }
  172.  
  173. /* Here is what I tryed */
  174. /* global variables     */
  175.  
  176. int note;
  177. TMTask tblah;
  178.  
  179. pascal void MyTimeTask(void)
  180. { DIG_Out_Line(4, notes[note].portout, notes[note].line, 0);
  181. }
  182.  
  183. void MyDelay(unsigned long time)
  184. { tblah.tmAddr = &MyTimeTask();
  185.   tblah.tmWakeUp = 0;
  186.   tblah.tmReserved = 0;
  187.   InsXTime(&tblah);
  188.   PrimeTime(&tblah,time);
  189. }
  190.  
  191. This didn't work, and I don't have a lot of time to figure out 
  192. why, so if anyone has any ideas I'm open to them.  Thanks in
  193. advance.  Reply through e-mail if possible.
  194.  
  195. =====================================================================
  196. Anthony Molinaro
  197. anthonym@ugcs.caltech.edu
  198.  
  199.  
  200.  
  201.  
  202. +++++++++++++++++++++++++++
  203.  
  204. >From Carl R. Osterwald <carl_osterwald@nrel.gov>
  205. Date: Fri, 21 Oct 1994 17:23:44 GMT
  206. Organization: National Renewable Energy Laboratory
  207.  
  208. In article <387t0n$3rr@gap.cco.caltech.edu> Anthony Molinaro,
  209. anthonym@puree.ugcs.caltech.edu writes:
  210. >Now, he tells me he needs a delay time smaller than one tick.  
  211. >I know that the time manager can do this but I have been 
  212. >unable to get it to work.  I guess my confusion arises in the
  213. >type declarations and getting all of the types to match for 
  214. >functions InsXTime(), PrimeTime(), and such.  The Inside 
  215.  
  216. Here is an example of a Time Manager task:
  217.  
  218. typedef struct
  219.     {
  220.         TMTask        tm_task;
  221.         long        A5;
  222.     } time_info;
  223.  
  224. Initialization:
  225.     timer_rec.tm_task.tmAddr = (TimerProcPtr)&time_task;
  226.     timer_rec.tm_task.tmWakeUp = 0;
  227.     timer_rec.tm_task.tmReserved = 0;
  228.     timer_rec.A5 = SetCurrentA5();
  229.     InsXTime( (QElemPtr)&timer_rec );
  230.     PrimeTime( (QElemPtr)timer_rec, period );  <<-- This starts the task
  231.  
  232. static void time_task (void)
  233.     {
  234.         time_info    *timer_rec;
  235.         long        current_A5;
  236.         
  237.         asm
  238.             {
  239.                 MOVE.L        A1,timer_rec
  240.                 MOVE.L        A5,current_A5
  241.             };
  242.         SetA5(timer_rec->A5);
  243.         PrimeTime( (QElemPtr)timer_rec, period );  <<-- This restarts
  244. the task
  245.         SetA5(current_A5);
  246.     }    // time_task
  247.  
  248. You can access your globals between the SetA5 calls.  Because the time
  249. task runs as an interrupt, it is best to minimize processing inside.  In
  250. your case, I would just set a global flag that is polled in the main
  251. event loop to see if it is time to turn the device on or off.
  252.  
  253. +++++++++++++++++++++++++++
  254.  
  255. >From h+@nada.kth.se (Jon W{tte)
  256. Date: Fri, 21 Oct 1994 18:48:34 +0100
  257. Organization: Royal Institute of Something or other
  258.  
  259. In article <387t0n$3rr@gap.cco.caltech.edu>,
  260. anthonym@puree.ugcs.caltech.edu (Anthony Molinaro) wrote:
  261.  
  262. >Now, he tells me he needs a delay time smaller than one tick.  
  263. >I know that the time manager can do this but I have been 
  264. >unable to get it to work.  I guess my confusion arises in the
  265.  
  266.  
  267. All you need is the system call Microseconds. You can write 
  268. your own Delay.
  269.  
  270. Cheers,
  271.  
  272.                 / h+
  273.  
  274.  
  275. --
  276.   Jon W$E4tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
  277.     Not speaking for the Microsoft Corporation.
  278.  
  279.  
  280. +++++++++++++++++++++++++++
  281.  
  282. >From gbolsinga@aol.com (GBolsinga)
  283. Date: 24 Oct 1994 17:20:05 -0400
  284. Organization: America Online, Inc. (1-800-827-6364)
  285.  
  286. In article <387t0n$3rr@gap.cco.caltech.edu>,
  287. anthonym@puree.ugcs.caltech.edu (Anthony Molinaro) writes:
  288.  
  289. >pascal void MyTimeTask(void)
  290. >{ DIG_Out_Line(4, notes[note].portout, notes[note].line, 0);
  291. >}
  292.  
  293. Look at the other sample code: it looks good.  Another problem might
  294. be that this function DIG_Out_Line can't move memory.
  295.  
  296. MyTimeTask executes at interupt time, so just set a global, and in
  297. your idle in your event loop check for the global changing and then
  298. call your function.
  299.  
  300. Greg Bolsinga
  301. MPI Multimedia
  302.  
  303.  
  304. +++++++++++++++++++++++++++
  305.  
  306. >From Tim Dorcey <td11@cornell.edu>
  307. Date: 25 Oct 1994 19:01:49 GMT
  308. Organization: Cornell University
  309.  
  310. In article <AACDBD82966813F759@klkmac005.nada.kth.se> Jon W{tte,
  311. h+@nada.kth.se writes:
  312. >All you need is the system call Microseconds. You can write 
  313. >your own Delay.
  314.  
  315. Do anyone know where the Microseconds call is documented?  I stumbled
  316. upon it in <Timer.h>, but can't find documentation for it anywhere.  Is
  317. it safe to assume that it is available on any system that has the
  318. "Revised Time Manager?"  I had written my own version, using
  319. InsTime/RmvTime, which seems to work fine, but I'd just as soon use the
  320. system call if it's equally available.
  321.  
  322. Tim Dorcey
  323. Tim_Dorcey@cornell.edu
  324.  
  325. ---------------------------
  326.  
  327. >From joey@caseware.com (Joey Caturay)
  328. Subject: Dynamic Dialogs?
  329. Date: Thu, 13 Oct 1994 15:15:23 GMT
  330. Organization: CaseWare
  331.  
  332. I seem to recall a MacTutor/Tech article about writing dynamic dialogs (i.e. 
  333. dialogs in which controls change based on a selection in the dialog. The 
  334. Metrowerks Project Preference dialog is an example). 
  335.  
  336. Is there source anywhere for dynamic dialogs? 
  337.  
  338. Thanks,
  339.  
  340. joey 
  341.  
  342. +++++++++++++++++++++++++++
  343.  
  344. >From johns@efn.org (John Selhorst)
  345. Date: Fri, 14 Oct 1994 01:07:40 GMT
  346. Organization: hisself
  347.  
  348. In article <joey.23.2E9D4F0B@caseware.com>, joey@caseware.com (Joey
  349. Caturay) wrote:
  350.  
  351. > I seem to recall a MacTutor/Tech article about writing dynamic dialogs
  352. (i.e. 
  353. > dialogs in which controls change based on a selection in the dialog. The 
  354. > Metrowerks Project Preference dialog is an example). 
  355. > Is there source anywhere for dynamic dialogs? 
  356. > Thanks,
  357. > joey 
  358.  
  359. There are some nice snippets with dynamic dialogs on the developer CD and
  360. probably on ftp.apple.com or whatever it's called now.
  361.  
  362. Johnny
  363.  
  364. johns@efn.org
  365.  
  366. +++++++++++++++++++++++++++
  367.  
  368. >From gurgle@dnai.com (Pete Gontier)
  369. Date: Sat, 15 Oct 1994 02:39:20 -0800
  370. Organization: Integer Poet Software
  371.  
  372. In article <joey.23.2E9D4F0B@caseware.com>, joey@caseware.com (Joey
  373. Caturay) wrote:
  374.  
  375. > I seem to recall a MacTutor/Tech article about writing dynamic dialogs
  376. (i.e. 
  377. > dialogs in which controls change based on a selection in the dialog. The 
  378. > Metrowerks Project Preference dialog is an example). 
  379. > Is there source anywhere for dynamic dialogs? 
  380.  
  381. Just get creative with HideDItem and ShowDItem. I recently implemented a
  382. NewsWatcher-style dialog this way (and it was no coincidence...). There's
  383. a popup menu at the top from which the user can select a set of dialog
  384. items. The items always exist, but most of them are hidden most of the
  385. time. Creating this dialog can be a pain unless you have a cool dialog
  386. editor like the one in Resorcerer which actually lets you show and hide
  387. ranges of items in the same way the Dialog Manager will do at run-time.
  388. (It's been 
  389.  
  390. This all said, if you're contemplating doing this, it may also be the case
  391. that you are running into other limitations of the Dialog Manager.
  392. Consider using something else, like any one of the several commercial
  393. view-management systems (off the top of my head, QuickApp, AppsToGo,
  394. MacApp, TCL, PowerPlant, FaceIt), or roll your own. (It's not all that
  395. hard if all you want is a list of items like the Dialog Manager tracks.
  396. Trees get messy, of course.)
  397.  
  398. -- 
  399.  
  400.  Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
  401.  
  402.  "A Princeton Review executive said the whole affair was not that important
  403.   and offered to relinquish the Kaplan domain name 'for a case of beer'."
  404.         -- Chris Gulker, SF Examiner
  405.  
  406. +++++++++++++++++++++++++++
  407.  
  408. >From gurgle@dnai.com
  409. Date: 14 Oct 94 21:39 GMT+0300
  410. Organization: (none)
  411.  
  412. In article <joey.23.2E9D4F0B@caseware.com>, joey@caseware.com (Joey
  413. Caturay) wrote:
  414.  
  415. > I seem to recall a MacTutor/Tech article about writing dynamic dialogs
  416. (i.e. 
  417. > dialogs in which controls change based on a selection in the dialog. The 
  418. > Metrowerks Project Preference dialog is an example). 
  419. > Is there source anywhere for dynamic dialogs? 
  420.  
  421. Just get creative with HideDItem and ShowDItem. I recently implemented a
  422. NewsWatcher-style dialog this way (and it was no coincidence...). There's
  423. a popup menu at the top from which the user can select a set of dialog
  424. items. The items always exist, but most of them are hidden most of the
  425. time. Creating this dialog can be a pain unless you have a cool dialog
  426. editor like the one in Resorcerer which actually lets you show and hide
  427. ranges of items in the same way the Dialog Manager will do at run-time.
  428. (It's been 
  429.  
  430. This all said, if you're contemplating doing this, it may also be the case
  431. that you are running into other limitations of the Dialog Manager.
  432. Consider using something else, like any one of the several commercial
  433. view-management systems (off the top of my head, QuickApp, AppsToGo,
  434. MacApp, TCL, PowerPlant, FaceIt), or roll your own. (It's not all that
  435. hard if all you want is a list of items like the Dialog Manager tracks.
  436. Trees get messy, of course.)
  437.  
  438. -- 
  439.  
  440.  Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
  441.  
  442.  "A Princeton Review executive said the whole affair was not that important
  443.   and offered to relinquish the Kaplan domain name 'for a case of beer'."
  444.         -- Chris Gulker, SF Examiner
  445.  
  446. +++++++++++++++++++++++++++
  447.  
  448. >From ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde)
  449. Date: 18 Oct 1994 15:49:43 GMT
  450. Organization: Avid Technology, Inc.
  451.  
  452. In article <gurgle-1510940239200001@dynamic-215.dnai.com>, gurgle@dnai.com
  453. (Pete Gontier) wrote:
  454.  
  455. > In article <joey.23.2E9D4F0B@caseware.com>, joey@caseware.com (Joey
  456. > Caturay) wrote:
  457. > > I seem to recall a MacTutor/Tech article about writing dynamic dialogs
  458. (i.e. 
  459. > > dialogs in which controls change based on a selection in the dialog. The 
  460. > > Metrowerks Project Preference dialog is an example). 
  461. > > Is there source anywhere for dynamic dialogs? 
  462. > Just get creative with HideDItem and ShowDItem. I recently implemented a
  463. > NewsWatcher-style dialog this way (and it was no coincidence...). There's
  464. > a popup menu at the top from which the user can select a set of dialog
  465. > items. The items always exist, but most of them are hidden most of the
  466. > time. Creating this dialog can be a pain unless you have a cool dialog
  467. > editor like the one in Resorcerer which actually lets you show and hide
  468. > ranges of items in the same way the Dialog Manager will do at run-time.
  469. > (It's been 
  470.  
  471. I thought NewsWatcher used AppendDITL, RemoveDITL, etc. I do remember
  472. John's sample code from disinfectant containing routines along the lines
  473. of AppendDITL and RemoveDITL to allow you to append and remove items to
  474. the dialog (the Sys7/CTB routines of the same names work as long as you
  475. DON'T use 'ictb' resources - otherwise they can crash horribly). I don't
  476. have any source, but you might also want to look at either the QuickTime
  477. Sequence Grabber Panel Component API or the Sound Control Panel Component
  478. API for some pointers and ideas - it defines a clean layer between a main
  479. piece of code that you write that controls the main dialog (ie the NW
  480. popup menu or the "scrolling icon item" list in CW) and "plug-in"
  481. subcomponents that control the independent panels.
  482.  
  483. -Ivan
  484. - --
  485. Ivan Cavero Belaunde (ivan_cavero_belaunde@avid.com)
  486. Avid VideoShop Lead
  487. Avid Technology, Inc.
  488. Disclaimer:  All views expressed are entirely my own and do not
  489. reflect  the opinions of Avid Technology, Inc.
  490.  
  491. +++++++++++++++++++++++++++
  492.  
  493. >From reed@medicine.wustl.edu (Thomas Reed)
  494. Date: Tue, 18 Oct 1994 11:21:13 -0500
  495. Organization: Washington University
  496.  
  497. In article <gurgle-1510940239200001@dynamic-215.dnai.com>, gurgle@dnai.com
  498. (Pete Gontier) wrote:
  499.  
  500. >In article <joey.23.2E9D4F0B@caseware.com>, joey@caseware.com (Joey
  501. >Caturay) wrote:
  502. >
  503. >> I seem to recall a MacTutor/Tech article about writing dynamic dialogs
  504. >
  505. >Just get creative with HideDItem and ShowDItem.
  506.  
  507. The method I like better is to set up your dialog with a "base" DITL,
  508. containing whatever controls are going to be static for all settings. 
  509. This might contain your OK and Cancel buttons and a pop-up, if that's the
  510. method you want to use to switch to a different set of controls.  Then,
  511. you define a separate DITL for each setting (say you have an options
  512. dialog with three different options topics selectable on a pop-up menu,
  513. you use 3 different DITLs, one for each topic).  Make sure that the new
  514. DITL can be overlayed on the "base" DITL the way you want it.  I believe
  515. that you may also want to specify that the "base" DLOG is not initially
  516. visible.
  517.  
  518. Then, in your program, you use AppendDITL to overlay the DITLs.  Just open
  519. your base DLOG, then call AppendDITL to overlay the current setting on the
  520. base DITL.  The item numbers for the one you're adding will be bumped up
  521. by the number of items in your base DITL.
  522.  
  523. Then, when the user switches to a different set of controls, you use
  524. ShortenDITL to remove the old controls and AppendDITL to add the new set.
  525.  
  526. You've of course also got to take into account which set of controls
  527. you're using in your dialog handling routines, as item #5 under one
  528. setting may not be the same as item #5 under another.  However, this is
  529. not too hard to do.
  530.  
  531. I believe that this is the way that NewsWatcher does things.
  532.  
  533. -Thomas
  534.  
  535. =====================================================
  536. Thomas Reed                     Washington University
  537. reed@telesphere.wustl.edu           Medical School
  538. reed@medicine.wustl.edu            Saint Louis, MO
  539. - ---------------------------------------------------
  540. Clothes make the man.  Naked people have little or no
  541. influence on society.  -- Mark Twain
  542. =====================================================
  543.  
  544. Opinions posted are not the opinions of Wash. U.
  545.  
  546. +++++++++++++++++++++++++++
  547.  
  548. >From bb@lightside.com (Bob Bradley)
  549. Date: Mon, 17 Oct 1994 03:22:02 -0800
  550. Organization: SS Software Inc.
  551.  
  552. In article <ivan_cavero_belaunde-1810941144230001@predator.avid.com>,
  553. ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde) wrote:
  554.  
  555. > I thought NewsWatcher used AppendDITL, RemoveDITL, etc. I do remember
  556. > John's sample code from disinfectant containing routines along the lines
  557. > of AppendDITL and RemoveDITL to allow you to append and remove items to
  558. > the dialog (the Sys7/CTB routines of the same names work as long as you
  559. > DON'T use 'ictb' resources - otherwise they can crash horribly).
  560.  
  561. Any dialog with an ictb resource can't use AppendDITL/ShortenDITL? Is
  562. there any other way to get the functionality of those two routines when
  563. using dialogs with ictb resources without modifying the DITL in memory
  564. directly?
  565.  
  566. I had a lot problems in the past with AppendDITL and ShortenDITL and could
  567. never figure it out until you mentioned they didn't work with ictb
  568. resources. I end up using the Show/Hide method but, when working with
  569. dialogs with a lot of items, it gets difficult.
  570.  
  571. +++++++++++++++++++++++++++
  572.  
  573. >From rmah@panix.com (Robert Mah)
  574. Date: Tue, 18 Oct 1994 18:15:26 -0500
  575. Organization: One Step Beyond
  576.  
  577. Jason_Titus@odsnet.com wrote:
  578.  
  579.  ) I have been trying to work out a solution to a problem where I have a
  580.  ) base window and can have a thousand or so possible midifications.  It
  581.  ) sounds like having these numerous DITL's and appending them would be
  582.  ) the best solutions,but - 
  583.  ) 
  584.  ) how do I create DITLs?  I can't find real descriptions of their format..
  585.  ) My goal is to be able to create DITLs from text files of information
  586.  ) (ie - a text file made up of checkbox titles) so I can easily create
  587.  ) thousands of windows.
  588.  
  589. The usual way is to use ResEdit's or Resorcerer's graphical editors.
  590.  
  591. However given that you want to parse a text file to create user interfaces,
  592. and assuming that the text file is not in rez format, I think you're going
  593. to have to write a parser and create windows on the fly.  That is, don't
  594. use DITL and DLOG resources, but instead operate directly at the Window
  595. Manager, Control Manager, List Manager and TextEdit levels.
  596.  
  597. Depending upon the complexity of your "interface description language",
  598. this might not be too hard or it might be a royal pain in the...
  599.  
  600. Cheers,
  601. Rob
  602. _____________________________________________________________________
  603. Robert S. Mah           Software Development          +1.212.947.6507
  604. One Step Beyond        and Network Consulting          rmah@panix.com
  605.  
  606. +++++++++++++++++++++++++++
  607.  
  608. >From leonardr@netcom.com (Leonard Rosenthol)
  609. Date: Wed, 19 Oct 1994 21:47:29 GMT
  610. Organization: Aladdin Systems, Inc.
  611.  
  612. In article <bb-1710940322020001@user31.lightside.com>, bb@lightside.com
  613. (Bob Bradley) wrote:
  614.  
  615. > In article <ivan_cavero_belaunde-1810941144230001@predator.avid.com>,
  616. > ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde) wrote:
  617. > > I thought NewsWatcher used AppendDITL, RemoveDITL, etc. I do remember
  618. > > John's sample code from disinfectant containing routines along the lines
  619. > > of AppendDITL and RemoveDITL to allow you to append and remove items to
  620. > > the dialog (the Sys7/CTB routines of the same names work as long as you
  621. > > DON'T use 'ictb' resources - otherwise they can crash horribly).
  622. > Any dialog with an ictb resource can't use AppendDITL/ShortenDITL? Is
  623. > there any other way to get the functionality of those two routines when
  624. > using dialogs with ictb resources without modifying the DITL in memory
  625. > directly?
  626.    That info about 'ictb's is NOT true.  The System routines AppendDITL
  627. and ShortenDITL will work just fine with ictb's GIVEN THE LIMITATIONS of
  628. ictb resources (like they suck big time!).
  629.  
  630.  
  631. Leonard
  632. - ------------------------------------------------------------------------
  633. Leonard Rosenthol                      Internet:       leonardr@netcom.com
  634. Director of Advanced Technology        AppleLink:      MACgician
  635. Aladdin Systems, Inc.                  GEnie:          MACgician
  636.  
  637. +++++++++++++++++++++++++++
  638.  
  639. >From ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde)
  640. Date: 21 Oct 1994 14:44:58 GMT
  641. Organization: Avid Technology, Inc.
  642.  
  643. In article <bb-1710940322020001@user31.lightside.com>, bb@lightside.com
  644. (Bob Bradley) wrote:
  645. > In article <ivan_cavero_belaunde-1810941144230001@predator.avid.com>,
  646. > ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde) wrote:
  647. > > I thought NewsWatcher used AppendDITL, RemoveDITL, etc. I do remember
  648. > > John's sample code from disinfectant containing routines along the lines
  649. > > of AppendDITL and RemoveDITL to allow you to append and remove items to
  650. > > the dialog (the Sys7/CTB routines of the same names work as long as you
  651. > > DON'T use 'ictb' resources - otherwise they can crash horribly).
  652. > Any dialog with an ictb resource can't use AppendDITL/ShortenDITL? Is
  653. > there any other way to get the functionality of those two routines when
  654. > using dialogs with ictb resources without modifying the DITL in memory
  655. > directly?
  656. > I had a lot problems in the past with AppendDITL and ShortenDITL and could
  657. > never figure it out until you mentioned they didn't work with ictb
  658. > resources. I end up using the Show/Hide method but, when working with
  659. > dialogs with a lot of items, it gets difficult.
  660.  
  661. Yeah, I had a lot of problems with those as well. Some of the problems
  662. (text items changing colors, for example) hinted at a confused 'ictb', so
  663. I stopped using one and everything was fine (it meant I had to use
  664. useritems for some stuff, though). This suspicion was confirmed by someone
  665. on the net who had worked on the AppendDITL/ShortenDITL code for Apple -
  666. 'ictb's are not supported by those calls.
  667.  
  668. Upon rereading my post above, I realize I imply John Norstad's
  669. DITL-manipulation code supports 'ictb'. I actually don't know whether
  670. that's the case or not - but it'd be easy to check if you need that
  671. functionality.
  672.  
  673. -Ivan
  674. - --
  675. Ivan Cavero Belaunde (ivan_cavero_belaunde@avid.com)
  676. Avid VideoShop Lead
  677. Avid Technology, Inc.
  678. Disclaimer:  All views expressed are entirely my own and do not
  679. reflect  the opinions of Avid Technology, Inc.
  680.  
  681. +++++++++++++++++++++++++++
  682.  
  683. >From Peter_Gontier@novell.com (Pete Gontier)
  684. Date: Mon, 24 Oct 1994 20:05:03 -0800
  685. Organization: Novell, Inc., Walnut Creek Macintosh Site
  686.  
  687. In article <ivan_cavero_belaunde-1810941144230001@predator.avid.com>,
  688. ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde) wrote:
  689.  
  690. > In article <gurgle-1510940239200001@dynamic-215.dnai.com>, gurgle@dnai.com
  691. > (Pete Gontier) wrote:
  692. > > Just get creative with HideDItem and ShowDItem. I recently implemented a
  693. > > NewsWatcher-style dialog this way...
  694. > I thought NewsWatcher used AppendDITL, RemoveDITL, etc...
  695.  
  696. I don't know for sure what NewsWatcher uses, but what I remember of the
  697. way he stored his DITLs supports the notion that he's using AppendDITL,
  698. etc.
  699.  
  700. When I said "NewsWatcher-style" I only meant the user interface is similar.
  701.  
  702. -- 
  703.  Views expressed here do not necessarily reflect the views of Novell.
  704.  
  705. +++++++++++++++++++++++++++
  706.  
  707. >From ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde)
  708. Date: 31 Oct 1994 19:43:51 GMT
  709. Organization: Avid Technology, Inc.
  710.  
  711. In article <leonardr-1910941347290001@leonardr.slip.netcom.com>,
  712. leonardr@netcom.com (Leonard Rosenthol) wrote:
  713.  
  714. > In article <bb-1710940322020001@user31.lightside.com>, bb@lightside.com
  715. > (Bob Bradley) wrote:
  716. > > In article <ivan_cavero_belaunde-1810941144230001@predator.avid.com>,
  717. > > ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde) wrote:
  718. > > 
  719. > > > I thought NewsWatcher used AppendDITL, RemoveDITL, etc. I do remember
  720. > > > John's sample code from disinfectant containing routines along the
  721. lines
  722. > > > of AppendDITL and RemoveDITL to allow you to append and remove items to
  723. > > > the dialog (the Sys7/CTB routines of the same names work as long as you
  724. > > > DON'T use 'ictb' resources - otherwise they can crash horribly).
  725. > > 
  726. > > Any dialog with an ictb resource can't use AppendDITL/ShortenDITL? Is
  727. > > there any other way to get the functionality of those two routines when
  728. > > using dialogs with ictb resources without modifying the DITL in memory
  729. > > directly?
  730. >    That info about 'ictb's is NOT true.  The System routines AppendDITL
  731. > and ShortenDITL will work just fine with ictb's GIVEN THE LIMITATIONS of
  732. > ictb resources (like they suck big time!).
  733.  
  734. Are you sure? I had an exchange on the net about a year/year and a half
  735. ago with someone (his name slips me) that had worked on the
  736. Append/RemoveDITL routines at Apple, and he explicitly mentioned that they
  737. didn't support 'ictb's. This was at the time when I was having problems
  738. with them: I kept getting items coming up in funny colors and fonts when I
  739. appended them, as well as stray crashes inside UpdateDialog. Nuking the
  740. 'ictb's got rid of all those problems.
  741.  
  742. On a related note, how do they suck big time? My only beef is that they
  743. are hard to edit unless you have Resorcerer, which is another one of the
  744. bazillion reasons to get Resorcerer and skip ResEdit...
  745.  
  746. -Ivan
  747. - --
  748. Ivan Cavero Belaunde (ivan_cavero_belaunde@avid.com)
  749. Avid VideoShop Lead
  750. Avid Technology, Inc.
  751. Disclaimer:  All views expressed are entirely my own and do not
  752. reflect  the opinions of Avid Technology, Inc.
  753.  
  754. ---------------------------
  755.  
  756. >From hsieh@netcom.com (Julia Hsieh)
  757. Subject: How to install your own templates using Macsbug 6.5d6???
  758. Date: Mon, 31 Oct 1994 17:25:57 GMT
  759. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  760.  
  761.  
  762. i've just started playing with custom templates in Macsbug, but since
  763. the new version doesn't have a separate Debugger Prefs file with the
  764. resources in it, how do i add my own custom templates?
  765.  
  766. also, i'm confused from one of the recent threads, is the Debugger
  767. Prefs a file or a folder.
  768.  
  769. thanks.
  770. -julia
  771.  
  772. -- 
  773. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  774.  
  775. If each day falls
  776. inside each night,
  777. there exists a well
  778. where clarity is imprisoned.
  779.  
  780. We need to sit on the rim
  781. of the well of darkness
  782. and fish for fallen light
  783. with patience.
  784.  
  785.     -Pablo Neruda
  786. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  787.  
  788.  
  789. +++++++++++++++++++++++++++
  790.  
  791. >From johns@efn.org (John Selhorst)
  792. Date: Tue, 1 Nov 1994 14:29:33 GMT
  793. Organization: hisself
  794.  
  795. In article <hsiehCyJsFA.7vH@netcom.com>, hsieh@netcom.com (Julia Hsieh)
  796. wrote:
  797.  
  798. > i've just started playing with custom templates in Macsbug, but since
  799. > the new version doesn't have a separate Debugger Prefs file with the
  800. > resources in it, how do i add my own custom templates?
  801. > also, i'm confused from one of the recent threads, is the Debugger
  802. > Prefs a file or a folder.
  803. > thanks.
  804. > -julia
  805.  
  806. You've almost answered your own question.  Yes, Debugger Prefs is a file
  807. that goes into the system folder.  It still works with MacsBug 6.5.  If
  808. you don't have one, make one yourself.  You can make one with ResEdit.
  809.  
  810. Johnny
  811.  
  812. johns@efn.org
  813.  
  814. +++++++++++++++++++++++++++
  815.  
  816. >From jonasw@lysator.liu.se (Jonas Wallden)
  817. Date: 1 Nov 1994 16:50:44 GMT
  818. Organization: (none)
  819.  
  820. hsieh@netcom.com (Julia Hsieh) writes:
  821.  
  822. >i've just started playing with custom templates in Macsbug, but since
  823. >the new version doesn't have a separate Debugger Prefs file with the
  824. >resources in it, how do i add my own custom templates?
  825.  
  826. I'm running 6.5d6 and it uses a Debugger Prefs file.
  827.  
  828. You can also drop your templates and macros into the MacsBug file itself.
  829. Just open it in ResEdit and paste them.
  830.  
  831. >also, i'm confused from one of the recent threads, is the Debugger
  832. >Prefs a file or a folder.
  833.  
  834. It's a resource file, and should be located at the top level of your
  835. System Folder.
  836.  
  837. >thanks.
  838. >-julia
  839.  
  840. BTW, welcome on board! You just doubled the female/male ratio of Mac hackers
  841. posting in this newsgroup... :-)
  842. ...............   .......................   ...........   ...............
  843.  jonas wallden           internet            applelink       phone/fax
  844.    mac hacker      jonasw@lysator.liu.se      sw1369       +46-13-176084
  845.  
  846. +++++++++++++++++++++++++++
  847.  
  848. >From devon_hubbard@taligent.com (Devon Hubbard)
  849. Date: Mon, 31 Oct 1994 18:57:56 GMT
  850. Organization: Taligent, Inc.
  851.  
  852. In article <hsiehCyJsFA.7vH@netcom.com>, hsieh@netcom.com (Julia Hsieh)
  853. wrote:
  854.  
  855. >i've just started playing with custom templates in Macsbug, but since
  856. >the new version doesn't have a separate Debugger Prefs file with the
  857. >resources in it, how do i add my own custom templates?
  858.  
  859. Since most of the dcmds/templates in the old 'Debugger Prefs' were always
  860. shipped with Macsbug, someone got smart at Apple (you know who you are :-)
  861. and just put that stuff in Macsbug itself and then there was no need for
  862. the separate prefs file.  This didn't eliminate the usage of that prefs
  863. file though.  So if you want to add your own templates, macros, etc. go
  864. right ahead and create a file called 'Debugger Prefs' and put your stuff
  865. in there.  The file type/creator is usually 'rsrc'/'RSED' but it really
  866. doesn't matter to Macsbug as it'll open the rsrc fork of any type file
  867. called 'Debugger Prefs'.
  868.  
  869. Also note that because Apple ships Macsbug this way, there is no need to
  870. merge their prefs with yours when a new release comes out.
  871.  
  872. dEVoN
  873.  
  874. - -----------------------------------------------------------------------
  875. Devon Hubbard                                               Silicon Pilot
  876. devon_hubbard@taligent.com                                  Taligent, Inc
  877. - -----------------------------------------------------------------------
  878. "No amount of genius can overcome a preoccupation with detail." -Einstein
  879.  
  880. ---------------------------
  881.  
  882. >From schultz@iastate.edu (Jonathan Schultz)
  883. Subject: IM: Networking book question
  884. Date: 28 Oct 94 07:08:51 GMT
  885. Organization: Iowa State University, Ames, Iowa
  886.  
  887. Does IM: Networking totally supercede Inside AppleTalk?
  888.  
  889. Jonathan
  890. schultz@iastate.edu
  891.  
  892. -- 
  893. - -----------------
  894. Jonathan Schultz
  895. schultz@iastate.edu
  896.  
  897. +++++++++++++++++++++++++++
  898.  
  899. >From jumplong@aol.com (Jump Long)
  900. Date: 29 Oct 1994 21:32:03 -0400
  901. Organization: America Online, Inc. (1-800-827-6364)
  902.  
  903. In article <schultz.783328131@pv3449.vincent.iastate.edu>,
  904. schultz@iastate.edu (Jonathan Schultz) writes:
  905.  
  906. >Does IM: Networking totally supercede Inside AppleTalk?
  907.  
  908. No it doesn't.
  909.  
  910. IM: Networking replaces the AppleTalk chapters of Inside Macintosh volumes
  911. II, IV, V, and VI (the old Inside Macintosh volumes).  IM: Networking
  912. describes the Macintosh AppleTalk API.  Inside AppleTalk describes the
  913. AppleTalk *protocols* - not the API for any particular implementation of
  914. AppleTalk.
  915.  
  916. While Inside AppleTalk isn't required to use most parts of the Macintosh
  917. AppleTalk API, it is useful when debugging AppleTalk problems you may have
  918. when using the Macintosh API because it describes the network packets and
  919. describes how the protocol was designed to be used.  To use some parts of
  920. the Macintosh API, you must have Inside AppleTalk because the Macintosh
  921. API doesn't build the request packets or disassemble the reply packets for
  922. you.  An example of that is using the .XPP driver to send AFP requests. 
  923. Since the system doesn't build those packets for you, you'll have to use
  924. the information in Inside AppleTalk to know how to build them yourself.
  925.  
  926. - Jim Luther
  927.  
  928. ---------------------------
  929.  
  930. >From Jaeger@fquest.com (Brian Stern)
  931. Subject: INIT Writing FAQ [1-3]
  932. Date: 28 Oct 1994 00:37:24 GMT
  933. Organization: The University of Texas at Austin, Austin, Texas
  934.  
  935. Answers to Frequently Asked Questions about writing System Extensions 
  936. on the Macintosh Computer. Version 1.0 10/94
  937.  
  938. This document is Copyright (c) 1994 by Brian Stern.
  939. I can be contacted by email at <Jaeger@fquest.com> on Internet.
  940.  
  941. The purpose of this FAQ list is to provide information on the writing 
  942. of system extensions.  This arcane art is difficult to learn and the 
  943. existing information on the subject is spread around in various 
  944. places.  Hopefully the information here will help new and old INIT 
  945. writers to write better INITs in less time.
  946.  
  947. The questions in this document are broken into two sections: System 
  948. Extensions and Trap Patches.  While most extensions contain trap 
  949. patches these subjects seemed different so I have separated them.
  950.  
  951. FAQ lists like this one are an integral part of Usenet.  When I 
  952. started reading Usenet news I assure you that I knew nothing about 
  953. writing extensions.  I learned by posting questions to 
  954. comp.sys.mac.programmer and by reading other's questions and 
  955. responses.  Let me take this space to give you a few tips on phrasing 
  956. of questions to newsgroups.
  957.  
  958. When asking a question try to make the title as descriptive as 
  959. possible.  Most people don't have time to read every question posted 
  960. and will ignore posts whose titles are unclear or meaningless.  Don't 
  961. post questions titled 'HELP, My program doesn't work', or worse 
  962. 'URGENT NEED HELP with program'.  I'm sure it's urgent to you, but 
  963. not to me.  Always indicate that you're asking a questing by 
  964. including a (you guessed it) question mark.  Consider these titles: 
  965. 'Programmers make big salaries' and 'Programmers make big salaries?'  
  966. Don't waste people's time with the former when you mean the latter.  
  967. Another way to indicate a question is like this: '[Q] Programmers 
  968. make big salaries?'.  Try to include one of the words 'who, what, 
  969. when, where, why, or how' in the titles of your questions.  Your 
  970. questions are much more likely to be answered by someone who actually 
  971. knows the answer if your title is clear.
  972.  
  973. The code samples in this document were developed with Think C.  You 
  974. may need to make some changes to use them with other development 
  975. systems.  I've used inline assembly in many of the code samples.  To 
  976. my eye this makes things more clear since it's obvious what's going 
  977. on.  Not everyone agrees with this and not all development 
  978. environments provide inline assembly.  It's possible to rewrite most 
  979. or all of this code by use of inline functions.  If you're writing in 
  980. Pascal or using CodeWarrior you'll have to do it that way.
  981.  
  982. You'll be able to find information on general questions of Mac 
  983. programming in the FAQ list maintained by Jon Watte at: 
  984. ftp://nada.kth.se/pub/hacks/mac-faq/CSMP_PD_FAQ
  985.  
  986. If you have questions about writing extensions that aren't addressed 
  987. in this document or any comments about it feel free to send them to 
  988. me.  If I know the answer or can find it out it may find its way into 
  989. a later version.
  990.  
  991. This document may be distributed freely as long as no changes are 
  992. made to it.  It may not be distributed in ways in which the user must 
  993. pay for the document, other than reasonable download costs or costs 
  994. for the medium, without the consent of the author.
  995.  
  996. Thanks to the following people who provided sample code and made 
  997. constructive comments: Pete Gontier, Dair Grant, Chelly Green, Devon 
  998. Hubbard, Peter Lewis, Jim Walker, Jim Wintermyre.
  999.  
  1000. - -------------------------------------------------------------------
  1001. System Extension Writing FAQ Outline:
  1002.  
  1003. System Extensions:
  1004.  
  1005. [1] What is an INIT, exactly?
  1006. [2] Should I write an INIT?
  1007. [3] Can I write an INIT that makes the application menu into a 
  1008. hierarchical menu?
  1009. [4] Do I need to know assembler to write an INIT?
  1010. [5] Can you show me a sample INIT?
  1011. [6] Can I have global variables in my INIT?
  1012. [7] How do I debug an INIT?
  1013. [8] How do I write a Control Panel-INIT combination?
  1014. [9] How do I capture keystrokes?
  1015. [10] How can my extension get time periodically?
  1016. [11] How should an INIT manage memory?
  1017. [12] How do I get my INIT to turn itself off?
  1018. [13] How do I get my INIT to show its icon like all the other cool 
  1019. INITs do?
  1020. [14] How do I show a dialog from my INIT?
  1021. [15] How do I maintain compatibility with future systems?
  1022. [16] Any tips for INIT writing?
  1023.  
  1024. Trap Patches:
  1025.  
  1026. [17] What exactly is a trap patch?
  1027. [18] What's the difference between a head patch and a tail patch?
  1028. [19] How do I patch a trap?
  1029. [20] How do I patch a register-based trap?
  1030. [21] Can you show me an example tail patch?
  1031. [22] How do I patch a selector-based trap?
  1032. [23] How do I patch a trap on the PPC?
  1033. [24] Can I write a fat trap?
  1034. [25] Tips?
  1035. [26] What other sources of information are available?
  1036.  
  1037. - -------------------------------------------------------------------
  1038.  
  1039. [1] What is an INIT, exactly?
  1040.  
  1041. An INIT is a type of code resource that is loaded into memory and 
  1042. executed during the startup process.  They're called INITs because 
  1043. they're resources of type 'INIT'.  INITs load at the end of the 
  1044. startup process, after the hardware checks have been done and the 
  1045. system has been started.  The span of time during which INITs load 
  1046. and execute is known as INIT time.  Applications don't load until 
  1047. after INIT time and in most cases the first application to load is 
  1048. the Finder.
  1049.  
  1050. Because they load before all applications, INITs can modify the 
  1051. system in a way that affects all applications.  They can add new 
  1052. functionalities and modify the way in which many processes occur on 
  1053. the Mac.  Apple often supplies new additions and updates to system 
  1054. software as INITs.  This includes things such as the Drag-and-Drop 
  1055. Manager, Thread Manager, Speech Manager, and Sound Manager 3.0.  At 
  1056. some point these new features are rolled into a new software release 
  1057. and eventually they are included in new ROMs, but they all start life 
  1058. as INITs.
  1059.  
  1060. Apple recommends that the term 'system extension' be used when 
  1061. communicating with non-programmers.  This name carries the 
  1062. implication that they extend the functionality of the system.  You'll 
  1063. see the terms 'INIT', 'extension', and 'system extension' used to 
  1064. mean the same thing throughout this document.
  1065.  
  1066. Extensions are loaded in a defined order.  Resources of type 'INIT' 
  1067. can be found in files of type 'INIT' (System Extension), 'cdev' 
  1068. (Control Panel), 'RDEV' (Chooser Device), 'appe' (application 
  1069. extension), and 'scri' (script system extensions).  In order to be 
  1070. loaded, the INIT resource must be in one of these file types in one 
  1071. of several locations in the System Folder.  
  1072.  
  1073. Under system 7 INITs are loaded first from the Extensions Folder in 
  1074. alphabetical order.  INITs present in script system extension files 
  1075. (filetype 'scri') load before INITs present in system extension files 
  1076. (filetype 'INIT').  Next, any INITs in the Control Panels folder are 
  1077. loaded in alphabetical order.  Any INITs present at the root level of 
  1078. the System Folder are loaded after that.  This order of loading is 
  1079. important if an extension is dependent on the presence of another 
  1080. extension.  For example, if an INIT resource in an INIT file named 
  1081. 'SpeakAll' is dependent on the presence of the 'Speech Manager' 
  1082. extension, it either needs to have its name changed to something that 
  1083. sorts after 'Speech Manager' or it has to be located in the Control 
  1084. Panels folder, since extensions in the Control Panels folder load 
  1085. after extensions in the Extensions Folder. 
  1086.  
  1087. In system 6 the Extensions Folder and Control Panels Folders don't 
  1088. exist.  Extensions are simply loaded in alphabetical order from the 
  1089. root level of the System Folder.
  1090.  
  1091. --
  1092. [2] Should I write an INIT?
  1093.  
  1094. System extensions are not easy to write.  If this is your first 
  1095. attempt at Mac programming, the answer to this question is NO.  Many 
  1096. experienced Mac programmers have never written one and don't intend 
  1097. to.  
  1098.  
  1099. There are a number of other ways to add functionality without writing 
  1100. an extension.  If you want to add functionality to a single 
  1101. application then think about writing an FKEY.  These are invoked by 
  1102. hitting cmd-shift-number and perform an action at that time only.  
  1103. The standard screen shot (cmd-shift-3) is one example.
  1104.  
  1105. Another user-invokable means of adding functionality is plug-in 
  1106. modules.  A number of commercial software packages support plug-ins 
  1107. that can add functionality in a straightforward manner.  This 
  1108. includes PhotoShop, Quark Express, Hypercard and others.
  1109.  
  1110. Another means of adding functionality is the use of a background-only 
  1111. application, AKA faceless-background application (fba).  Fbas are 
  1112. applications without a user interface.  One type of fba is known as 
  1113. an application extension.  These are applications whose resource 
  1114. files are of type 'appe'.  They are placed in the extensions folder 
  1115. (or the Startup Items Folder) and are started up after INIT time.  
  1116. They can communicate with other processes by Apple Events and by 
  1117. Gestalt selectors.  If you don't need to patch a trap then an fba may 
  1118. be the way to add functionality to the system.  Since an fba runs as 
  1119. a normal process there are some things that it can do that system 
  1120. extensions cannot do (or at least cannot do safely), like launch 
  1121. applications and send and receive Apple Events.  An INIT resource in 
  1122. the resource fork of an application extension in the Extensions 
  1123. Folder will load normally at INIT time.  See issue 9 of develop and 
  1124. the Tech Note PS 2 - Background-Only Applications for more info.
  1125.  
  1126. Also consider an application that is started up by being placed in 
  1127. the startup items folder.  The Screen Saver 'Dark Side of the Mac' is 
  1128. written in this way.  Screen Savers are traditionally written as 
  1129. extensions because extensions can have access to the mouse location 
  1130. and all keyboard events.  However an intelligently written 
  1131. application can do the same and be more compatible.  
  1132.  
  1133. If none of these things seems like it will work for you and you are 
  1134. thinking something like 'I want X to happen every time a resource is 
  1135. loaded', or otherwise add to or replace the system's functionality in 
  1136. some way then an extension is probably what you need.
  1137.  
  1138. Remember that when developing system extensions you will be working 
  1139. without a net.
  1140.  
  1141. --
  1142. [3] Can I write an INIT that makes the application menu into a 
  1143. hierarchical menu?
  1144.  
  1145. Every couple of weeks someone posts a message on 
  1146. comp.sys.mac.programmer entitled 'Neat idea for an init'.  These 
  1147. posts go on to describe some non-programmer's idea of a great INIT.  
  1148. Invariably these posts fall into two groups: those that have already 
  1149. been done, and those that should never be done.  Think long and hard 
  1150. about the design of an extension before starting to write it.  
  1151. Consider your target audience.  If it's only yourself then you can do 
  1152. what you want.  My first couple of extensions were just tests to see 
  1153. if I could actually do it.  The answer to the above question is: 
  1154. Maybe you can but probably you shouldn't.
  1155.  
  1156. --
  1157. [4] Do I need to know assembler to write an extension?
  1158.  
  1159. Yes.  Strictly speaking, the simplest extension that just beeps at 
  1160. startup and doesn't hang around past INIT time requires no assembler.  
  1161. However, any extension that does anything useful will require some 
  1162. assembler in order to patch a trap or install a jGNEFilter.  The 
  1163. extension can be written mostly in a high level language like C or 
  1164. Pascal, but there will be bits and pieces that need to be written in 
  1165. assembler to keep the stack happy or to access parameters passed in 
  1166. registers.  Hopefully there will be enough sample code in this 
  1167. document to get you on your way if your assembler is weak.
  1168.  
  1169. You will often need to inspect the disassembled source of your 
  1170. extension.  If your development environment doesn't allow this the 
  1171. ResEdit Code Viewer will also allow you to inspect code resources.  
  1172. It can be found at ftp://ftp.apple.com/dts/mac/tools/resedit/resedit-
  1173. extensions.hqx.
  1174.  
  1175. --
  1176. [5] Can you show me a sample INIT?
  1177.  
  1178. Here's the code for the 'Hello World' of INITs.
  1179.  
  1180. void main(void)
  1181. {
  1182.    SysBeep( 5 );
  1183. }
  1184.  
  1185. Not very complicated is it?  There are a number of additional things 
  1186. that are required to make this work:
  1187.  
  1188. 1) Set the project type to code resource.
  1189. 2) Set the resource type to 'INIT'.
  1190. 3) Set the resource ID to something (>= 128), and set the resource 
  1191. name if desired.
  1192. 4) Set the resource attributes to 'System Heap'.
  1193. 5) Set the resource attributes to 'Locked'.
  1194. 6) Set the filetype of the built code resource file to 'INIT' with 
  1195. any creator signature.
  1196. 7) Set the filename of the built code resource file to 'Hello World'.
  1197.  
  1198. Let me explain what each of these things does.  
  1199.  
  1200. 1)  Because you're building a standalone code resource your compiler 
  1201. needs to know this.  This is how the compiler knows to use A4 
  1202. addressing, rather than the A5 addressing used in applications.
  1203.  
  1204. 2)  As mentioned above, extensions are code resources of type 'INIT'.  
  1205.  
  1206. 3)  Like any other resources they have IDs and can have names.  
  1207.  
  1208. 4)  Setting the system heap flag places the code resource in the 
  1209. system heap.  While not strictly required for this sample, in most 
  1210. other extensions we will want the code resource to remain in the 
  1211. system heap so this flag must be set.  During the process that loads 
  1212. and executes INITs a small heap is created.  Any memory allocation 
  1213. done by the INIT will, by default occur in this heap.  Also any 
  1214. resources read into memory will, by default, go into this heap.  If 
  1215. the system heap flag isn't set for the INIT itself then the INIT will 
  1216. be loaded into this temporary heap.  When the INIT exits the heap is 
  1217. disposed and anything in it is lost.  If an INIT intends to stay 
  1218. around past INIT time then it must have the system heap flag set.
  1219.  
  1220. 5)  The code resource should never move in memory so the Locked bit 
  1221. is set.  When a resource with the Locked bit is loaded into memory it 
  1222. is loaded as low in the heap as possible.  This is what we want since 
  1223. the INIT resource will never be unlocked.  It is poor design to not 
  1224. set the Locked bit and to rely on the INIT to lock itself.  In that 
  1225. case the INIT will not be loaded low in the system heap.  This isn't 
  1226. fatal but will lead to fragmentation of the system heap.  
  1227.  
  1228. Some INITs try to use MoveHHi/HLock to move themselves or associated 
  1229. resources high in the system heap.  MoveHHi is disabled for the 
  1230. system heap.  Since the system heap is dynamically sizable the 
  1231. concept of the top of the heap is invalid.  For this reason MoveHHi 
  1232. does nothing when the handle being referred to is within the system 
  1233. heap.  
  1234.  
  1235. 6)  The filetype of 'INIT' gives you the generic extension icon, and 
  1236. of course allows the extension to load and execute at INIT time.
  1237.  
  1238. 7)  Set the file name to something like 'Hello World'.
  1239.  
  1240. Once these things have been done you can build the code resource and 
  1241. drag its file to the System Folder.  The Finder should place it in 
  1242. the Extensions Folder for you and it should have the generic 
  1243. extension icon.  When you restart you will hear the beep when the 
  1244. extension is loaded.
  1245.  
  1246. Every extension must have a routine called 'main'.  When the INIT 
  1247. resource is loaded into memory during INIT time the system jumps to 
  1248. the beginning of the code resource.  The header of the code resource 
  1249. will normally contain a branch instruction that branches to the main 
  1250. routine.  This routine does whatever it needs to do and then returns.  
  1251. In this 'Hello World' extension all that the main routine does is 
  1252. call SysBeep.  In more substantial extensions the main routine will 
  1253. do things like patch traps, install gestalt selectors, and load 
  1254. resources into memory.
  1255.  
  1256. --
  1257. [6] Can I have global variables in my INIT?
  1258.  
  1259. Yes you can.  The Think environment and the CodeWarrior environment 
  1260. use A4-based addressing for global variables in code resources.  The 
  1261. base address of the extension is found in register A0 on entry to the 
  1262. extension, and routines are provided to save this value and to set up 
  1263. and restore register A4 when the INIT is entered later.  (In fact the 
  1264. standard header installed by Think C in code resources loads the 
  1265. address of the code resource into A0 by use of pc-relative 
  1266. addressing.)  See the A4-Addressing section of your development 
  1267. environment's manual for more information.  
  1268.  
  1269. When writing extensions with the MPW compilers you may need to use an 
  1270. A5-based method for accessing global variables.  See the Apple tech 
  1271. note 'StandAlone Code, ad nauseam' (#256) for more information on 
  1272. this method.  ftp://ftp.apple.com/dts/mac/tn/platforms.tools.pt/pt-
  1273. 35-stand-alone-code.hqx 
  1274.  
  1275. and 
  1276.  
  1277. "Another take on Globals in Standalone Code", Keith Rollin
  1278. ftp://ftp.apple.com/dts/mac/docs/develop/develop.12.code/globals-in-
  1279. standalone-code.hqx
  1280.  
  1281. Here is some sample code using the Think C routines to illustrate 
  1282. this:
  1283.  
  1284. /****Main*****************************************************/
  1285. void 
  1286. main(void)        //Main entry point of the extension
  1287. {
  1288.    void     *pToMe;
  1289.    Boolean  initedOK;
  1290.  
  1291.    pToMe = GetA0();     //Save our address locally
  1292.  
  1293.    RememberA0();        //Save our base address
  1294.    SetUpA4();           //Set up A4-based addressing
  1295.  
  1296.    initedOK = InitAll();   //Patch traps etc.
  1297.    if ( initedOK )
  1298.    {
  1299.                      //Make sure we stay around
  1300.       DetachResource( RecoverHandle( pToMe) );  
  1301.    }
  1302.  
  1303.    RestoreA4();         //Reset A4 to its value on entry
  1304. }
  1305.  
  1306. This code sample also illustrates one method extensions can use to 
  1307. remain in memory after INIT time.  Since extensions are code 
  1308. resources they will be removed from memory when their resource files 
  1309. are closed.  This happens when the main routine exits.  To avoid 
  1310. this, DetachResource must be called with the handle to the code 
  1311. resource.  One common mistake with this is not having the code 
  1312. resource marked system heap.  If it's not marked system heap it will 
  1313. be lost when the temporary heap is destroyed, whether it was detached 
  1314. or not.  The GetA0 routine used above is defined in the tips section 
  1315. farther down in this document.  Here are a few other methods for an 
  1316. extension to detach itself:
  1317.  
  1318. void 
  1319. main(void)     //Another method
  1320. {
  1321.    asm
  1322.    {
  1323.       RecoverHandle     //A0 already holdss our address
  1324.       move.L   A0, -(A7)   //DetachResource is stack-based
  1325.       DetachResource    //so push A0 onto the stack
  1326.    }
  1327. }
  1328.  
  1329. void 
  1330. main(void)     //This method uses no assembler
  1331. {
  1332.    DetachResource( Get1Resource( 'INIT', kOurResID ) );
  1333. }
  1334.  
  1335. --
  1336. [7] How do I debug an INIT?
  1337.  
  1338. Debugging is generally the most time consuming, difficult, and all-
  1339. around pain-in-the-neck part of producing good code.  That goes 
  1340. double for INITs.  Unfortunately many parts of INITs must be debugged 
  1341. with low level debuggers.  The low level debuggers that I know about 
  1342. are MacsBug, TMON, and Jasik's Debugger.  MacsBug is free and is 
  1343. available at ftp://ftp.apple.com/dts/mac/tools/macsbug/macsbug-6-
  1344. 5d6.hqx.  The two other low level debuggers are commercialware.  
  1345. Jasik's debugger has the ability to do source level debugging of code 
  1346. resources, like system extensions.
  1347.  
  1348. In most cases, your low level debugger of choice will load before 
  1349. INIT time so it can be used to debug initialization of INITs.  One 
  1350. exception to this is Jasik's Debugger, which loads in two parts.  One 
  1351. of these is an extension that must load before your extension.  
  1352.  
  1353. The debugger can be invoked by calling the Debugger() or DebugStr() 
  1354. traps.  Placing these trap calls in your code will drop you into the 
  1355. low level debugger so that you can step through your code and inspect 
  1356. registers or memory as needed.
  1357.  
  1358. One useful technique is to take advantage of Macsbug's ability to 
  1359. process commands after a semicolon in a DebugStr call.  The following 
  1360. function can display information that you would otherwise have to 
  1361. hunt down using hex offsets:
  1362.  
  1363. pascal void SomeFunction (arguments)
  1364. {
  1365.     // ...
  1366.  
  1367.     asm { MOVE.L fooP, A0 }      // fooP can be any type
  1368.     asm { MOVE.L sizeof(*fooP), D0 }
  1369.     DebugStr ("\p ; dm rA0 rD0");   // dump (*fooP) in hex
  1370.  
  1371.     // ...
  1372. }
  1373.  
  1374. If you haven't placed Debugger() calls in your code then you will 
  1375. have to set a breakpoint in order to step through any trap patches or 
  1376. other parts of your extension.  Here are a couple of methods to do 
  1377. that.  If you have patched a trap, say GetResource, if you drop into 
  1378. MacsBug and type 'il GetResource' MacsBug will begin to disassemble 
  1379. at your patch.  You can then set a breakpoint by typing 'br 
  1380. GetResource' or br theaddress' where theaddress is the address in hex 
  1381. of your patch or some part of it.  Type 'brc' when you want to clear 
  1382. all breakpoints.  Using the A-trap commands will also work.  'atb 
  1383. GetResource' will set a break and 'atc' will clear all A-trap 
  1384. breakpoints.
  1385.  
  1386. If you want to set a breakpoint in some other part of your extension, 
  1387. say in a jGNEFilter, then you need another way of finding its 
  1388. location in memory.  In MacsBug type 'hx syszone^' or just 'hx' to 
  1389. set the current heap to the system heap (where your extension is 
  1390. located).  Type 'br ' (don't hit return yet) and then type cmd-D to 
  1391. view the names of all the routines in the system heap that were 
  1392. compiled with MacsBug names turned on (like yours, right?)  Scroll 
  1393. down until you find the name of your routine.  Hit enter and the 
  1394. command line should look like 'br yourRoutineName'.  Hit enter again 
  1395. and the breakpoint will be set.  You can also simply type 'br 
  1396. yourRoutineName' and MacsBug will find it for you.  The zone must be 
  1397. set to the zone containing the routine that you want to break on for 
  1398. MacsBug to find it, so make sure to set the zone to the system zone.
  1399.  
  1400. Identifying your extension in the system heap is dependent on 
  1401. compiling it with the MacsBug symbols option turned on.  This inserts 
  1402. Ascii versions of the names of each function in the compiled code in 
  1403. such a way the MacsBug , and other debuggers can find these names.  
  1404. Jasik's debugger uses a different method for identifying your code 
  1405. that is based on SYM files, which are generated by your compiler.  
  1406. The SYM files allows Jasik's debugger to do source level debugging of 
  1407. INITs and other code resources.
  1408.  
  1409. I have used a two-project method, when developing INITs and other 
  1410. code resources, that helps to cut down debugging time.  Any extension 
  1411. consists of essentially two parts: the initialization portion and the 
  1412. implementation portion.  The initialization portion detaches the 
  1413. resource as described above, shows the icon, and often patches traps.  
  1414. The implementation portion contains the actual trap patches.  It is 
  1415. quite possible, and desirable, to test the implementation portion in 
  1416. the context of an application, rather than as an INIT.  To accomplish 
  1417. this your project consists of three parts, which for a simple case 
  1418. would be three files.
  1419.  
  1420. TesterApp Project:
  1421.    SetUpApplication.c   Simple application shell that sets up 
  1422.                the trap patches and provides a  
  1423.                mechanism to call the traps
  1424.    TrapPatches.c     Code for the trap patches
  1425.  
  1426. INIT Project:
  1427.    SetUpINIt.c       Standard INIT setup; contains main  
  1428.                entry point; patches all necessary  
  1429.                traps
  1430.    TrapPatches.c     Code for the trap patches; same file as 
  1431.                in the TesterApp Project
  1432.  
  1433. The mechanism for calling the traps in SetUpApplication.c is usually 
  1434. a menu item.  In some cases it might be a dialog with several 
  1435. buttons, each of which calls a particular trap.  It isn't always 
  1436. necessary to patch traps in your TesterApplication.  Simply calling 
  1437. the routines that implement the guts of the trap patches will often 
  1438. be just as good.  Having two projects, one that builds the tester 
  1439. application and the other that builds the extension, allows you to 
  1440. save time debugging and to be able to build the extension at any 
  1441. time.
  1442.  
  1443. Writing and testing extensions involves multiple rounds of 
  1444. 'compiling-installing the INIT-rebooting-Stepping through the INIT in 
  1445. a low level debugger'.  Use of the two-project method will cut down 
  1446. this time.
  1447.  
  1448. --
  1449. [8] How do I write a Control Panel-INIT combination?
  1450.  
  1451. System extensions generally have no interface.  They do what they do 
  1452. quietly and the user doesn't want to hear from them.  In many cases 
  1453. the user needs to set certain preferences.  The natural mechanism for 
  1454. this is to couple a control panel with an INIT.  The problem of 
  1455. course is how does the control panel communicate the changes to the 
  1456. INIT.  I won't discuss the general mechanisms of control panel 
  1457. authoring here (see NIM: More Macintosh Toolbox, Chapter 8), but 
  1458. there are several mechanisms available for communicating between 
  1459. extensions and control panels.
  1460.  
  1461. The simplest mechanism and one that will work in the vast majority of 
  1462. cases is for the extension to install a Gestalt selector.  This 
  1463. selector returns the address of a block of memory that holds 
  1464. variables that control the actions of the extension.  The control 
  1465. panel calls the Gestalt selector, retrieves the address of the memory 
  1466. block, and alters the values stored in the block as needed.  In some 
  1467. cases the memory block can contain a function pointer to a function 
  1468. in the extension that needs to be called from the control panel.  
  1469. Here is some sample code:
  1470.  
  1471. typedef struct CommonInfo{
  1472.    void     (*ResetINIT) (void);//function pointer to reset 
  1473.                            //func
  1474.    Boolean  On;
  1475. };
  1476.  
  1477. #define kSignature 'BLAH'  //Should be the sig of the INIT
  1478.  
  1479. static CommonInfo    gInfo;
  1480.  
  1481. /**InstallGestaltSelector****************************************/
  1482. //In the INIT; runs at INIT time
  1483. OSErr
  1484. InstallGestaltSelector(void)
  1485. {
  1486.    OSErr    err;
  1487.  
  1488.    err = NewGestalt( kSignature, OurSelector );
  1489.    
  1490.    if ( err == noErr )
  1491.    {
  1492.       gInfo.ResetINIT = (void *) ResetFunction;
  1493.       gInfo.On = TRUE;
  1494.    }
  1495.  
  1496.    return err;
  1497. }
  1498.  
  1499. /**OurSelector**************************************************/
  1500. //In the INIT
  1501. pascal OSErr 
  1502. OurSelector( OSType theSelector, long *theResponse )
  1503. {
  1504.    SetUpA4();
  1505.  
  1506.    *theResponse = (long) &gInfo;
  1507.    
  1508.    RestoreA4();
  1509.  
  1510.    return noErr;
  1511. }
  1512.  
  1513. /**ResetFunction***********************************************/
  1514. //In the INIT
  1515. void 
  1516. ResetFunction(void)
  1517. {
  1518.    SetUpA4();
  1519.  
  1520.    //Do something here
  1521.    
  1522.    RestoreA4();
  1523. }
  1524.  
  1525. /**Close********************************************************/
  1526. //In the Control Panel
  1527. void
  1528. Close( Boolean IsOn )
  1529. {
  1530.    long        result;
  1531.    CommonInfo     *Info;
  1532.    
  1533.    //Get address of globals struct from init
  1534.    err = Gestalt( kSignature, &result );
  1535.    if ( err == noErr )
  1536.    {
  1537.       Info = (GlobalsType *) result;
  1538.       Info->On = IsOn;        //Reset OnOff Boolean
  1539.       ( * (*Info).ResetINIT) (); //Jump to INIT
  1540.    }
  1541. }
  1542.  
  1543. If it is possible for an error to occur that prevents the extension 
  1544. from resetting itself the ResetFunction should return an error code 
  1545. and the control panel should display an alert indicating the problem.
  1546.  
  1547. Two additional methods are sometimes used to accomplish communication 
  1548. between an extension and a control panel:  
  1549.  
  1550. The first of these is to write a driver that is installed by the 
  1551. extension.  The driver holds global variables and will return the 
  1552. address of the block of memory holding these variables in response to 
  1553. i/o, status, or control calls to the driver.  Sample code showing how 
  1554. to do this is available in a package called driver-22 written by Pete 
  1555. Resnick to be found at:
  1556. ftp://sumex-aim.stanford.edu/info-mac/dev/src/driver-22-c.hqx.gz
  1557.  
  1558. The second additional method is to use the PPC toolbox for direct 
  1559. communication.  There is sample code demonstrating this at: 
  1560. ftp://ftp.apple.com/dts/mac/sc/7.0.samples/init-cdev.hqx.
  1561.  
  1562. --
  1563. [9] How do I capture keystrokes?
  1564.  
  1565. This is accomplished by writing a jGNEFilter function.  jGNEFilter 
  1566. functions are called from GetNextEvent and WaitNextEvent just before 
  1567. those traps return to an application.  They are passed a pointer to 
  1568. the event record that will be returned to the application.  In order 
  1569. to capture keystrokes the jGNEFilter would simply check the what 
  1570. field of the event record looking for keyboard events and would 
  1571. extract the information from the message field if one were found.  
  1572.  
  1573. The jGNEFilter mechanism is very powerful and is one way that 
  1574. screensavers can be implemented.  The filter would save the time of 
  1575. any keyboard events and would compare the location of the mouse 
  1576. against its previous location on null events.  If the preset time had 
  1577. elapsed during which no keyboard events or mouse movement had 
  1578. occurred then the screen saver would activate.  A more complete 
  1579. discussion of the jGNEFilter is in the next section.
  1580.  
  1581. If you are thinking of patching WaitNextEvent or PostEvent in order 
  1582. to capture keystrokes or other events, don't.  Use a jGNEFilter 
  1583. instead.  It's easier, it's compatible.  It's even documented.  See 
  1584. the Tech Note 'GetNextEvent; Blinking Apple Menu' (#85).
  1585.  
  1586. ftp://ftp.apple.com/dts/mac/tn/toolbox.tb/tb-11-getnextevent.hqx
  1587.  
  1588. -- 
  1589. Brian  Stern  :-{)}
  1590. Toolbox commando and Menu bard
  1591. Jaeger@fquest.com
  1592.  
  1593. ---------------------------
  1594.  
  1595. >From Jaeger@fquest.com (Brian Stern)
  1596. Subject: INIT Writing FAQ [2-3]
  1597. Date: 28 Oct 1994 00:42:44 GMT
  1598. Organization: The University of Texas at Austin, Austin, Texas
  1599.  
  1600. --
  1601. [10] How can my extension get time periodically?
  1602.  
  1603. Installing a jGNEFilter is one method of obtaining periodic time.  
  1604. Since the jGNEFilter mechanism is dependent on the event processing 
  1605. mechanism, one problem is that no events may be posted if the mouse 
  1606. is held down for an extended time.  
  1607.  
  1608. If your INIT only needs to get time every once in a while then I 
  1609. recommend that it only do its thing on null events.  On other events 
  1610. it should just return.  This will have the least impact on the 
  1611. machine's performance.  
  1612.  
  1613. Remember that your jGNEFilter will be called for EVERY event on the 
  1614. machine.  Do not do a lot of processing on every event or you will be 
  1615. slowing down the machine needlessly.  Another way to reduce the 
  1616. frequency of your extension's processing is to use a simple timer, 
  1617. based on TickCount().  In this way your processing is only done, say, 
  1618. every 30 or 60 ticks, on null events of course.
  1619.  
  1620. Sample code demonstrating jGNEFilters can be found in a package 
  1621. called jGNE Helper by Pete Gontier in the alt.sources.mac archive at: 
  1622. ftp://ftpbio.bgsu.edu/ftp/pub/alt.sources.mac/vol-
  1623. 01/jgnehelper.cpt.hqx.  
  1624.  
  1625. Another sample in MPW assembler is at 
  1626. ftp://ftp.apple.com/dts/mac/sc/snippets/toolbox/jgnefilter.hqx.
  1627.  
  1628. Here's another example that works in Think C:
  1629.  
  1630. static   ProcPtr  gOldGNEFilter;
  1631.  
  1632. /****InstallFilter***********************************************/
  1633. //Run this at INIT time
  1634. void
  1635. InstallGNEFilter (void)
  1636. {
  1637. /*Save the ProcPtr to the previous jGNEFilter and insert ours*/
  1638.    gOldGNEFilter = JGNEFilter;
  1639.    JGNEFilter = (ProcPtr) StripAddress( FilterProc );
  1640.  
  1641.  }
  1642.  
  1643. /****FilterProc**************************************************/
  1644.  
  1645. void
  1646. FilterProc(void)
  1647. {
  1648.    EventRecord    *theEvent;
  1649.    long        SaveD0;
  1650.    
  1651.    theEvent = GetA1();  //Move the eventPtr to a variable
  1652.    SaveD0 = GetD0(); //Preserve D0
  1653.  
  1654.    SetUpA4();
  1655.  
  1656.    switch ( (*theEvent).what ) {
  1657.       case nullEvent:
  1658.          //Do our thing
  1659.          break;
  1660.          
  1661.       case keyDown:
  1662.          //Do something else
  1663.          break;
  1664.    }
  1665.    
  1666.    //Execute the previous jGNEFilter
  1667.    SetA1( theEvent );   //Restore A1 for the next jGNEFiler
  1668.    SetD0( SaveD0);      //Restore D0
  1669.    SetA0( gOldGNEFilter ); //Put next jGNEFilter in A0
  1670.    
  1671.    RestoreA4();
  1672.  
  1673.    asm{
  1674.       Unlk     A6
  1675.       Move.W   D0, 4(A7)   ;Set Function result on the stack
  1676.       JMP      (A0)     ;Jump to the next jGNEFilter
  1677.    }
  1678.  
  1679. }
  1680.  
  1681. Since a jGNEFilter has access to the actual event record that will be 
  1682. returned to the application, the filter can alter the event.  The 
  1683. most common thing to do is to 'cancel' an event by changing it to a 
  1684. null event (Ex. theEvent->what = nullEvent).  In this case it should 
  1685. also set the value in register D0 to False, or zero.
  1686.  
  1687. Here are some additional methods for an extension to get time 
  1688. periodically:
  1689.  
  1690. If your extension needs more frequent or regular time then can be 
  1691. provided by a jGNEFilter then you can install a VBL task or a time 
  1692. manager task.  Since these run at interrupt time they cannot do 
  1693. anything that could move or purge memory.  Other methods include 
  1694. patching a trap that is called frequently, like SetPort.
  1695.  
  1696. A faceless Notification Manager request is another method to get 
  1697. time.  This is a request that has all the fields in the notification 
  1698. record set to NULL except the nmResp field that holds the address of 
  1699. your routine to be executed.  Your notification response routine will 
  1700. be called soon and will be able to move memory.  If necessary the 
  1701. routine can reinstall itself.  This technique is useful for tasks 
  1702. that need to be executed once or intermittently.  For those tasks 
  1703. that need to be executed regularly use one of the other techniques.
  1704.  
  1705. You could of course have a faceless NM request that is installed by a 
  1706. VBL task or a time manager task.  
  1707.  
  1708. Use of a faceless background application in concert with an extension 
  1709. is yet another method to get time.  The fba would do its work on its 
  1710. null events.
  1711.  
  1712. --
  1713. [11] How should an INIT manage memory?
  1714.  
  1715. In general, at INIT time extensions will want to allocate memory in 
  1716. the system heap.  If you are allocating pointers or handles, use the 
  1717. SYS variants, like NewHandleSys() and NewPtrSys().  It is a common 
  1718. error to forget this and then to wonder why the INIT crashes.  If you 
  1719. call NewHandle at INIT time, the handle will be allocated in the 
  1720. temporary heap allocated for your extension.  If your INIT attempts 
  1721. to use it after INIT time the temporary heap will be long gone, along 
  1722. with any handles or pointers that had been allocated in it.  Any 
  1723. attempt to use handles or pointers that no longer exist are 
  1724. predictably unpredictable :-) 
  1725.  
  1726. NewHandle and NewPtr will allocate their memory blocks in the system 
  1727. heap if the zone has been set to the system heap, as shown in the 
  1728. next paragraph.
  1729.  
  1730. If you need to read in resources you can ensure that they go into the 
  1731. system heap with something like the following code:
  1732.  
  1733. THz   saveZone = GetZone();
  1734.    SetZone( SystemZone() );
  1735.    //read in resources
  1736.    SetZone( saveZone );
  1737.  
  1738. You will of course need to detach the resources if they need to 
  1739. remain in memory after your extension exits.  The resource file 
  1740. containing your extension will be closed when your extension exits.
  1741.  
  1742. If you need to read resources into memory after INIT time you need to 
  1743. decide which heap they should go into, either the application heap or 
  1744. the system heap.  It's a bit hard to make a specific recommendation 
  1745. on this but if the resource is something that the application is 
  1746. expecting to be read in then it should go into the application heap.  
  1747. This would include things like WIND resources in a trap patch to 
  1748. GetNewWindow().  The problem of course is that the application heap 
  1749. may not have enough room.  However, if the resources are private to 
  1750. the extension then they should go into the system heap.
  1751.  
  1752. It should go without saying that you should always check the error 
  1753. codes on memory allocating calls and resource manager calls.  If your 
  1754. extension is doing something in response to a user action, say making 
  1755. a network connection, then it is appropriate to report such errors.  
  1756. In many cases however, your extension will simply do nothing in the 
  1757. case of out of memory errors or missing resource errors.  It is best 
  1758. to attempt to allocate all of these things at INIT time and if 
  1759. unsuccessful to bail out then.
  1760.  
  1761. As mentioned above, MoveHHi doesn't work in the system heap.  If you 
  1762. intend to allocate a handle that will remain locked for extended 
  1763. periods, then call ResrvMem before allocating and locking the handle.  
  1764. This will place the handle low in the system heap and help to prevent 
  1765. heap fragmentation. 
  1766.  
  1767. Many toolbox calls are documented as not moving or purging memory and 
  1768. as being safe to call at interrupt time.  If you are patching one of 
  1769. these traps then you must preserve this property.  You are guaranteed 
  1770. to cause other software to crash if you don't, and your users will 
  1771. hate you (once they figure out that it's you).  Be aware that the 
  1772. only memory manager routine safe to call under these circumstances is 
  1773. BlockMove. Also be aware that it is unsafe to access an unlocked 
  1774. handle at interrupt time.  It is possible that the memory manager is 
  1775. in the midst of moving it from one place to another in the heap, and 
  1776. the master pointer may not be updated yet.
  1777.  
  1778. --
  1779. [12] How do I get my INIT to turn itself off?
  1780.  
  1781. An extension might want to turn itself off at INIT time based on its 
  1782. preferences setting, or based on a key being pressed or the mouse 
  1783. button being pressed, or due to an error during initialization.  
  1784. Extensions usually show an icon with a red X through it in this case.  
  1785. An extension might also want to turn itself off temporarily after 
  1786. INIT time in response to its Control Panel.  For instance GateKeeper 
  1787. has an on/off switch that turns off virus checking for a set time.
  1788.  
  1789. The strategy for temporarily turning off an extension is simply to 
  1790. set a global flag and to check it from within the trap patches or 
  1791. other parts of the extension.  If the flag is off then the trap patch 
  1792. simply executes the previous trap.  It is generally unsafe to unpatch 
  1793. or patch traps after INIT time from an extension.  The reason for 
  1794. this is that if another extension patches the same trap after you 
  1795. have, then it will be jumping to your patch when it has completed its 
  1796. work.  If you have removed your patch then this calling chain will be 
  1797. disrupted and bad things will happen.  Also, the Finder patches 
  1798. various traps when it loads, which is after INIT time.  Disrupting 
  1799. those patches would be a very bad thing.
  1800.  
  1801. If an extension determines at INIT time that it isn't going to stay 
  1802. around then it shouldn't call DetachResource on itself.  It's best 
  1803. that your extension determine that anything it's dependent on, such 
  1804. as resources, specific system Managers, and sufficient memory, are 
  1805. present *before* it starts to patch traps and install drivers, 
  1806. jGNEFilters and so on.  It would be a very bad idea for an extension 
  1807. to not detach itself after it had already patched a trap if the trap 
  1808. patch resided in the extension.
  1809.  
  1810. Many extensions use a particular key press as a signal to indicate 
  1811. that the user wants them not to run.  Of course the system uses the 
  1812. shift key as a signal not to turn on any extensions so you can't use 
  1813. that.  Some extensions use the option or command keys for this 
  1814. purpose.  The problem with using those keys is that every time I 
  1815. rebuild the desktop those extensions are needlessly inactivated.  I 
  1816. recommend that the space bar be used for this purpose.  Here's some 
  1817. sample code:
  1818.  
  1819.  Boolean
  1820.  SpaceBarIsDown(void)
  1821.  {
  1822.    KeyMap      theKeys;
  1823.  
  1824.    GetKeys( theKeys );
  1825.  
  1826.    if ( theKeys[1] & 0x00000200 )//Check for spacebar
  1827.       return TRUE;
  1828.    else
  1829.       return FALSE;
  1830.  
  1831.  }
  1832.  
  1833. --
  1834. [13] How do I get my INIT to show it's icon like all the other cool 
  1835. inits do?
  1836.  
  1837. This is easy.  There is code available that does this for you.  Get a 
  1838. package written by Jim Walker called ShowIcon7 at:
  1839. ftp://mac.archive.umich.edu/mac/development/source/showicon7.sit.hqx
  1840.  
  1841. You use it essentially as a plug-in.  Just pass in the icon's 
  1842. resource ID and it does everything for you.  It also shows how to set 
  1843. up an A5 world in an extension.  You might also take a look at Dair 
  1844. Grant's Extension shell package.  This one shows how to do animated 
  1845. icons.
  1846.  
  1847. If your extension decides that it can't install itself then it passes 
  1848. the resource ID of an icon that has a red X through it to the 
  1849. showicon7 code resource.
  1850.  
  1851. Some extensions include the ShowIcon code within their own code 
  1852. resources.  This code is only about 1K but it seems pointless to me 
  1853. for this code to sit in the system heap when it doesn't have to be.  
  1854. Use it as a plug-in for your extensions.
  1855.  
  1856. --
  1857. [14] How do I show a dialog from my INIT?
  1858.  
  1859. First of all, I hate windows of any kind during the startup process.  
  1860. If all you want to do is show an alert then use the Notification 
  1861. Manager.  Your alert will show up when the Finder starts but the user 
  1862. will see it and will get whatever message you need to send.  
  1863.  
  1864. The problem I have with windows at INIT time is that they slow down 
  1865. this process and require user interactivity in a process that 
  1866. shouldn't do so.  Consider the computer that is on 24 hours a day 
  1867. doing something important unattended.  The power goes off and when it 
  1868. comes back on the machine reboots.  The user returns several hours 
  1869. later to find that the machine is still in the middle of its startup 
  1870. because your alert is waiting for a response.  Consider also the 
  1871. hapless INIT writer who has to reboot his machine 20 times a day.  
  1872. Your INIT will not last long on my, um, his machine.
  1873.  
  1874. One additional annoyance is that you need to call InitWindows to show 
  1875. your window and this erases all the nice INIT icons on the screen.  I 
  1876. hate that.
  1877.  
  1878. Here are a few possible alternatives.  
  1879.  
  1880. * Play a sound or use the Speech Manager to communicate the 
  1881. information.  
  1882.  
  1883. * Show a different icon during startup to indicate an error.  An icon 
  1884. with a red X through it is one way to do this.  You could also use 
  1885. animated icons.
  1886.  
  1887. * If you must put up an alert then use a timer so that the alert goes 
  1888. away by itself, even if the OK button isn't clicked.
  1889.  
  1890. * If you need to interact with the user to get some information, say 
  1891. a password for a network connection, then do this once and save the 
  1892. results in a preferences file.  Provide a Control Panel to change the 
  1893. information.  Think of Control Panels as the interface for 
  1894. extensions.
  1895.  
  1896. * Store descriptions of any errors that occur in a preferences file.  
  1897. Have the Control Panel display this information.  Remember to clear 
  1898. this information on each restart and to indicate to the user by sound 
  1899. or icon that an error has occurred.
  1900.  
  1901. * If you need to communicate error information to the user after INIT 
  1902. time then you should definitely use the Notification Manager.  For 
  1903. example, MacSLIP uses the NM to show an alert indicating that the 
  1904. carrier has been lost.
  1905.  
  1906. If you still want to show a dialog at INIT time then you need to set 
  1907. up an A5 world first.  The ShowIcon7 code mentioned above shows how 
  1908. to do this.  Also see the Tech Note 'Stand-Alone Code' (#256) for an 
  1909. explanation and sample code for this and 'Giving the (Desk)Hook to 
  1910. INITs' (247) discusses a bug that can appear when showing windows 
  1911. from extensions.
  1912. ftp://ftp.apple.com/dts/mac/tn/operating.system.os/os-02-deskhook-
  1913. and-init.hqx
  1914.  
  1915. If you do use the Notification Manager from an extension to indicate 
  1916. that the extension couldn't load you should use a self-disposing 
  1917. Notification request.  There are several strategies for doing this.  
  1918. I have some code samples for this that will be (have been?) posted to 
  1919. alt.sources.mac soon.
  1920.  
  1921. --
  1922. [15] How do I maintain compatibility with future systems?
  1923.  
  1924. This is tough, and the short answer is that you probably don't.  
  1925. You'll notice that Apple comes out with new versions of its 
  1926. extensions with each revision of the system.  Apple's extensions also 
  1927. eventually disappear as their functionality is rolled into the 
  1928. system.  In all likelihood you'll have to come out with new versions 
  1929. of your extensions as new versions of the system come out as well.
  1930.  
  1931. Having said all that, there are things you can do to minimize this 
  1932. problem.  Here are a few suggestions:
  1933.  
  1934. * Minimize your reliance on undocumented features of the system.
  1935.  
  1936. * Minimize your reliance on low memory globals.  Use the Universal 
  1937. Header access 'functions' for accessing the low memory globals if 
  1938. necessary.
  1939.  
  1940. * Use system features like Gestalt, the Process Manager, and the 
  1941. Notification Manager to get information about the system, and to 
  1942. communicate with the user.
  1943.  
  1944. * Try to patch as few traps as possible and use non-patching methods 
  1945. whenever possible (e.g., use a jGNEFilter instead of patching 
  1946. WaitNextEvent; the filter is more likely to remain compatible than 
  1947. your patch).  
  1948.  
  1949. * Don't use self-modifying code.  Self-modifying code changes the 
  1950. instructions from what they were compiled as, to something else, at 
  1951. run-time.  The classic example is to change the address in a JMP 
  1952. instruction at run-time so that it jumps to the address of the 
  1953. previous trap.  This may seem faster than using a global variable but 
  1954. it is only slightly faster.  It is harder to write, debug, and 
  1955. maintain self-modifying code, and it is definitely more likely to 
  1956. break with new system releases.  If you do use self-modifying code, 
  1957. remember to flush the cache.  See the tech note 'Cache As Cache Can' 
  1958. (#261) for more information on that subject.
  1959.  
  1960. * Use the Universal Headers for writing your extensions.  This will 
  1961. help to ease the transition when it comes.
  1962.  
  1963. --
  1964. [16] Any tips for INIT writing?
  1965.  
  1966. You may not want your INIT to actually do anything until after INIT 
  1967. time.  You can find the end of INIT time if you have a jGNEFilter 
  1968. installed when the first null event occurs.  The Notification Manager 
  1969. doesn't usually start processing requests until INIT time is over so 
  1970. posting a faceless notification request is another method to find the 
  1971. end of INIT time (probably the best if you don't need a jGNEFilter 
  1972. for something else).  You can also patch Launch to find the end of 
  1973. INIT time but this is trickier.
  1974.  
  1975. Unfortunately some extension writers do put up windows during INIT 
  1976. time.  Because of this it's possible that events will occur before 
  1977. INIT time is over.  To fail-safe the above approaches you also need 
  1978. to check for the presence of the Process Manager with a Gestalt call.  
  1979. The Process Manager isn't available until after INIT time.  If 
  1980. Gestalt reports that the Process Manager is not available then you 
  1981. need to reinstall your NM request, or simply wait for another event 
  1982. to be reported to your jGNEFilter when the Process Manager is 
  1983. available.
  1984.  
  1985. Here are some utility routines that can reduce the need for 68K 
  1986. assembler in your extensions:
  1987.  
  1988. pascal void SetA0( void* ) = { 0x205F };
  1989. pascal void SetA1( void* ) = { 0x225F };
  1990. void *   GetA0( void ) = { 0x2008 };
  1991. void *   GetA7( void ) = { 0x200F };
  1992.  
  1993.  
  1994. - -------------------------------------------------------------------
  1995.  
  1996. Trap Patches:
  1997.  
  1998. --
  1999. [17] What exactly is a trap patch?
  2000.  
  2001. A trap patch is a method for changing the functionality of a trap.  
  2002. The addresses of all the traps are maintained in the two trap 
  2003. dispatch tables.  By using the routine NSetTrapAddress and friends 
  2004. you can change the address of a particular trap to code that you 
  2005. provide.  When this is done at INIT time, all calls to the patched 
  2006. trap from all applications will go to your code, which in most cases 
  2007. will do something and then call through the existing trap in the 
  2008. ROMs.  Be warned that the Finder patches some traps when it starts up 
  2009. in a way that prevents previously-installed patches from executing.  
  2010.  
  2011. I recommend that you read the descriptions of the trap dispatch 
  2012. mechanism in the 'Using Assembly Language' chapters in IM I and IV 
  2013. and also in the 'Trap Manager' chapter in NIM Operating System 
  2014. Utilities.
  2015.  
  2016. Traps come in several types based on their parameter passing 
  2017. conventions.  Most toolbox traps use pascal calling conventions, 
  2018. which means that all parameters are passed on the stack and the 
  2019. return value, if any, is placed on the stack.  
  2020.  
  2021. Some traps use register-based calling conventions.  In these traps 
  2022. the parameters are passed in registers and the return value is 
  2023. returned in a register, usually D0.  For example all the Memory 
  2024. Manager traps are register-based and the File Manager traps are also 
  2025. register-based.  
  2026.  
  2027. Some traps are selector-based.  There are only so many spots in the 
  2028. trap-dispatch tables.  In order to preserve space in these tables 
  2029. selector-based traps have been developed.  In these traps a single 
  2030. trap serves as the front end for a number of system routines.  The 
  2031. parameters of these traps are passed in the usual manner, either on 
  2032. the stack or in registers, and a selector is also passed, usually in 
  2033. a register.  When the trap is called it checks the selector and then 
  2034. dispatches to the appropriate routine.  Patching each of these types 
  2035. of traps involves different mechanisms.  We'll look at samples of 
  2036. each one.
  2037.  
  2038. Patching traps on the PowerMac is a bit different than on the 68K 
  2039. Macs.  Most of the discussion here is aimed at patching traps on the 
  2040. 68K Macs.  Hopefully I'll learn some more about this subject soon and 
  2041. there will be some better info here on patching traps on the 
  2042. PowerMac.
  2043.  
  2044. --
  2045. [18] What's the difference between a head patch and a tail patch?
  2046.  
  2047. It is most common to add some functionality to a trap when patching 
  2048. it rather than just replacing the existing trap.  For instance I've 
  2049. written an extension that speaks the text in alerts by using the 
  2050. Speech Manager.  This works by patching Alert and friends.  When 
  2051. Alert is called the patch gets the text that appears in the alert and 
  2052. passes it to the Speech Manager.  The patch then calls the existing 
  2053. Alert trap that is in the ROMs.  A patch that works in this way is 
  2054. called a head patch; it does its business and then it calls the 
  2055. previous trap.
  2056.  
  2057. A tail patch is a bit different.  A virus-checking program might want 
  2058. to patch GetResource and then examine the resource that was read in 
  2059. to see if it contains a virus.  In order to do this the patch must 
  2060. first call the existing trap and then do its processing, and finally 
  2061. return to the application.  This is a tail patch because some 
  2062. processing occurs after the existing trap is called.  In order for a 
  2063. patch to be a head patch you must use a jmp instruction to jump to 
  2064. the previous trap.  If you use a jsr or a C function pointer to jump 
  2065. to the previous trap you have a tail patch.
  2066.  
  2067. The reason that this head and tail patch business has been so 
  2068. important in the past is because of an Apple invention called the 
  2069. come-from patch.  Patches were invented, of course, so that Apple 
  2070. could fix bugs in the ROMs and could update the routines in the ROMs 
  2071. with software.  This is why you can run system 7 on a Mac Plus, whose 
  2072. ROMs are obviously missing most of the additions made to the toolbox 
  2073. in recent years.  
  2074.  
  2075. Certain ROM routines are particularly large so it is inconvenient to 
  2076. patch them if they have bugs in them.  To get around this problem the 
  2077. Apple programmers searched for smaller routines that are called from 
  2078. the large buggy routines and placed patches in the smaller routines.  
  2079. These patches check the return address on the stack.  If it is the 
  2080. address of the buggy routine then a fix is applied.  If not then they 
  2081. just go on as usual.  The patches to these smaller routines are known 
  2082. as come-from patches.  If you tail patch one of these and then call 
  2083. the existing come-from patch, the return address on the stack will be 
  2084. in your patch and not the buggy routine that called you.  In this 
  2085. case the come-from patch will not apply its fix and your system will 
  2086. crash.  
  2087.  
  2088. The good news is that as of system 7 it is safe to apply tail 
  2089. patches.  The come-from patches still exist in system software, but 
  2090. NGetTrapAddress has been modified to return an address that is safe 
  2091. to use when applying tail-patches.  However, if you wish your 
  2092. extension to run in System 6 then tail-patches are not allowed.  This 
  2093. is documented in the Trap Manager chapter in NIM: OS Utilities.
  2094.  
  2095. If you absolutely positively need a tail patch in System 6 then the 
  2096. following logic may apply: (Just don't tell anyone that I told you 
  2097. this :-)  Apple is not releasing any new versions of System 6 so no 
  2098. new come-from patches will be forthcoming for System 6.  If you do 
  2099. careful testing of the traps you wish to tail-patch you will probably 
  2100. be OK.  In general traps not called from the ROMs, like Alert and 
  2101. MenuKey, will not contain come-from patches.
  2102.  
  2103. One final thing: In system 7 it is safe to apply tail-patches to all 
  2104. traps except FrontWindow.
  2105.  
  2106. --
  2107. [19] How do I patch a trap?
  2108.  
  2109. Here is some sample code for a head patch of Alert, a stack-based 
  2110. trap:
  2111.  
  2112. TrapPtr  gOldAlertTrapAddress;
  2113.  
  2114. /****InstallPatch***************************************************/
  2115.  
  2116. void 
  2117. InstallPatch (void)
  2118. {
  2119.    gOldAlertTrapAddress = GetToolTrapAddress( _Alert );
  2120.    SetToolTrapAddress( (long) AlertPatch, _Alert );
  2121. }
  2122.  
  2123. /****AlertPatch***************************************************/
  2124.  
  2125. pascal void 
  2126. AlertPatch( short alertID, ProcPtr filterProcPtr )
  2127. {
  2128.    SetUpA4();
  2129.  
  2130.    MyAlert( alertID) ;  //Do our thing
  2131.  
  2132.    //store the correct alert addr
  2133.    //in A0 while we can still access globals via A4
  2134.  
  2135.    asm   { move.l gOldAlertTrapAddress, A0 }
  2136.  
  2137.    RestoreA4();
  2138.    
  2139.    asm   {
  2140.          unlk     A6 //match the link generated by C
  2141.          jmp      (A0)  //jump to _Alert
  2142.       }
  2143. }
  2144.  
  2145. There are a number of details to note here.  This patch is of course 
  2146. part of a code resource that is loaded at INIT time and detached as 
  2147. described in an earlier section.  The routine InstallPatch must be 
  2148. called at INIT time.  
  2149.  
  2150. The routines GetToolTrapAddress and SetToolTrapAddress allow you to 
  2151. get and set the addresses of Tool Traps.  The similar routines 
  2152. GetOSTrapAddress and SetOSTrapAddress allow you to manipulate the 
  2153. addresses of OS traps.  The routines NGetTrapAddress and 
  2154. NSetTrapAddress allow you to manipulate the addresses of either, 
  2155. although they call glue code.  I recommend that you use the 
  2156. GetXTrapAddress and SetXTrapAddress calls.  There are two obsolete 
  2157. calls: GetTrapAddress and SetTrapAddress.  Don't use them.
  2158.  
  2159. The prototype for this patch is declared as 'pascal void' while the 
  2160. prototype for Alert is 'pascal short'.  Because this is a head patch 
  2161. it will not be returning a result; the result will be returned from 
  2162. the real Alert trap.  The pascal keyword is used to indicate pascal 
  2163. calling conventions.  It is not strictly required in all cases but 
  2164. does no harm.  
  2165.  
  2166. The Think C routines SetUpA4 and RestoreA4 are called to allow access 
  2167. to global variables by A4 addressing.  In this case 
  2168. gOldAlertTrapAddress is the only global variable we are addressing, 
  2169. unless any are used inside MyAlert.  Note that this variable is moved 
  2170. to A0 while access to global variables is still available.  In some 
  2171. cases one might move a global variable to a local variable, which 
  2172. doesn't rely on A4 addressing.  A4 could then be restored and the old 
  2173. trap address could be loaded into A0 later in the code. 
  2174.  
  2175. Because there is a parameter list the compiler generates a Link A6 
  2176. instruction at the start of this function.  In order to restore the 
  2177. stack a matching Unlk A6 must be placed at the end of the function.  
  2178. Since we are exiting by the jmp (A0) we must insert the Unlk A6 
  2179. ourselves.  The compiler does generate an Unlk A6 and an RTS at the 
  2180. end of this function, but they will never be executed.  The presence 
  2181. of the Link A6 instruction is dependent on the particular compiler 
  2182. you use and on its rules for generating a stack frame.  It is a good 
  2183. idea to disassemble the code for your trap patches to see whether a 
  2184. stack frame has been generated in order to determine if you need to 
  2185. insert the Unlk A6 instruction.  If you don't match the Link A6 with 
  2186. an Unlk A6 the stack will be screwed up.
  2187.  
  2188. It is essential that the stack look exactly the same on exit from a 
  2189. head patch as it does on entry.  If not you will surely crash.  (If 
  2190. you had good reason you could modify the value of a parameter on the 
  2191. stack, but that's another story.)  This patch saves and restores A4 
  2192. but does modify A0 and A1 (SetUpA4 uses A1).  In general, with head 
  2193. patches of stack-based traps you can modify A0, A1, D0, D1, and D2, 
  2194. but not any other registers.  You may need to look at the 
  2195. disassembled code to be sure that all your registers are properly 
  2196. saved and restored.  
  2197.  
  2198. The design of the patch as shown here, with the patch code calling a 
  2199. separate function to perform the actual functionality of the patch is 
  2200. a good design to follow with all but the simplest of patches.
  2201.  
  2202. You might think that you need to call StripAddress on the address of 
  2203. the patch routine before passing this address to SetToolTrapAddress.  
  2204. This is not necessary unless the address is actually a handle.  If 
  2205. you were to load a code resource and pass its entry point to 
  2206. SetToolTrapAddress then it would need to be stripped.
  2207.  
  2208. -- 
  2209. Brian  Stern  :-{)}
  2210. Toolbox commando and Menu bard
  2211. Jaeger@fquest.com
  2212.  
  2213. ---------------------------
  2214.  
  2215. >From Jaeger@fquest.com (Brian Stern)
  2216. Subject: INIT Writing FAQ [3-3]
  2217. Date: 28 Oct 1994 00:44:27 GMT
  2218. Organization: The University of Texas at Austin, Austin, Texas
  2219.  
  2220. --
  2221. [20] How do I patch a register-based trap?
  2222.  
  2223. Here is the code for a sample register-based trap patch:
  2224.  
  2225. TrapPtr     gMountVolAddress;
  2226.  
  2227. /****InstallPatch**************************************************/
  2228.  
  2229. void 
  2230. InstallPatch(void)
  2231. {
  2232.    gMountVolAddress =  GetOSTrapAddress( _MountVol );
  2233.    SetOSTrapAddress( (long) MountVolPatch, _MountVol );
  2234. }
  2235.  
  2236. /****MountVolPatch**************************************************
  2237.  
  2238. This is a register-based trap that has A0 set to point to its 
  2239. parameter
  2240. block on entry.  The  prototype for MountVol is:
  2241.  
  2242.    pascal OSErr PBMountVol( ParmBlkPtr paramBlock )
  2243.  
  2244. This patch beeps when a floppy or CD-ROM is inserted or when a 
  2245. harddrive is mounted by the Finder.
  2246.  
  2247. *******************************************************************/
  2248.  
  2249. pascal void 
  2250. MountVolPatch(void)
  2251. {
  2252. //Save some registers
  2253. //Save A0 since it's trashed by SetUpA4
  2254. //D1 contains the trap word
  2255.  
  2256.    asm   {  movem.l  a0/d0-d1, -(sp)      }
  2257.  
  2258.    SetUpA4();     //Allow access to global variables
  2259.  
  2260.    SysBeep( 5 );  //The guts of our head patch
  2261.    
  2262.    //store the correct MountVol addr
  2263.    //in A1 while we can still access globals via A4
  2264.    asm   {  move.l   gMountVolAddress, A1 }
  2265.  
  2266.    RestoreA4();   //Restore previous value in A4
  2267.    
  2268.    asm   {              //Restore the registers
  2269.          movem.l  (sp)+, a0/d0-d1
  2270.          jmp      (A1)     //jump to _MountVol
  2271.       }
  2272.  
  2273. }
  2274.  
  2275. This head patch is similar in structure to the patch to Alert with a 
  2276. few differences.  The prototype uses no parameters and has no return 
  2277. value. The single parameter is passed through A0.  This patch doesn't 
  2278. do anything with this value but it could be moved to a local variable 
  2279. and then used to reference the fields in the parameter block if 
  2280. desired.  Access to global variables is by the same A4 mechanism as 
  2281. in the Alert patch.  Note that _MountVol is an OS trap so 
  2282. GetOSTrapAddress and SetOSTrapAddress are used to set up the patch.  
  2283.  
  2284. Since A0 is used to pass the parameter to this trap we jump to the 
  2285. real _MountVol trap through A1.  
  2286.  
  2287. Obviously A0 must be saved and restored in this patch. OS traps 
  2288. expect to find the trap word in D1 so it must be saved and restored 
  2289. as well.  Three registers, A0, D0, and D1, are saved onto the stack 
  2290. with the movem instruction, and restored at the end of the patch.  
  2291.  
  2292. Think C doesn't generate a 'Link A6' at the start of this function 
  2293. because there are no parameters and no local variables.  Because of 
  2294. this no 'Unlk A6' is needed at the end of the function.
  2295.  
  2296. --
  2297. [21] Can you show me an example tail patch?
  2298.  
  2299. Here is another example of a patch to a register-based trap.  This 
  2300. sample is a tail patch and is dependent on the CodeWarrior 
  2301. environment.  Because CW allows you to specify that parameters are 
  2302. passed in registers this trap patch requires no assembly.
  2303.  
  2304. extern pascal OSErr (*Old_MountVol)( ParmBlkPtr pb : __A0 ) : __D0;
  2305.  
  2306. pascal OSErr My_MountVol( ParmBlkPtr pb : __A0 ) : __D0
  2307. {
  2308.    OSErr    err;
  2309.    long     saveA4 = SetCurrentA4();
  2310.  
  2311.    err = Old_MountVol( pb );
  2312.    DoSomthingFunc();
  2313.  
  2314.    SetA4( saveA4 );
  2315.    return err;
  2316. }
  2317.  
  2318. --
  2319. [22] How do I patch a selector-based trap?
  2320.  
  2321. Here is a sample patch to PrGlue.  This trap is the front end for all 
  2322. the Printing Manager routines.  Its selector is pushed on the stack
  2323.  
  2324. typedef struct 
  2325. {
  2326.    long     Selector;
  2327.    THPrint     hPrint;
  2328. } PrJobDialogStack;
  2329.  
  2330. TrapPtr     PrGlueAddress;
  2331.  
  2332. /****InstallPatch****************************************************
  2333. /
  2334.  
  2335. void 
  2336. InstallPatch(void)
  2337. {
  2338.    PrGlueAddress = GetToolTrapAddress( _PrGlue );
  2339.    SetToolTrapAddress( (long) PrGluePatch, _PrGlue );
  2340. }
  2341.  
  2342. /****PrGluePatch****************************************************
  2343.  
  2344. This is a stack-based trap with a long word selector also pushed 
  2345. onto the stack.  On entry the selector is at 4(A7).  The return 
  2346. address is at 0(A7).  After the 'Link A6' the selector is at 12(A7).
  2347.  
  2348. *******************************************************************/
  2349.  
  2350. #define kSelectorOffset 12
  2351. #define kPrJobDialogSelector 0x32040488
  2352.  
  2353. pascal void 
  2354. PrGluePatch(void)
  2355. {
  2356.    PrJobDialogStack  *StackPtr;
  2357.  
  2358.    //Get address of the stack frame
  2359.    //and save it in a local variable
  2360.  
  2361.    asm   { 
  2362.          lea    kSelectorOffset(A7), A0
  2363.          move.l A0, StackPtr
  2364.       }
  2365.  
  2366.    SetUpA4();     //Allow access to global variables
  2367.  
  2368.    //Check the selector
  2369.    if ( StackPtr->Selector == kPrJobDialogSelector )
  2370.    {
  2371.       SysBeep( 5 );
  2372.  
  2373.       //Pass hPrint to our function to do something
  2374.       DoSomethingFunc( StackPtr->hPrint );
  2375.    }
  2376.  
  2377.    //Store the correct PrGlue addr
  2378.    //in A0 while can still access globals via A4
  2379.    asm   { move.l PrGlueAddress, A0 }           
  2380.             
  2381.    RestoreA4();   //Restore previous value in A4
  2382.    
  2383.    asm   {
  2384.          unlk     A6 //match C's Link A6
  2385.          jmp      (A0)  //jump to _PrGlue
  2386.       }
  2387.  
  2388. }
  2389.  
  2390. In order to access the selector and the parameters for PrGlue we use 
  2391. a pointer to a struct.  Once the pointer is initialized correctly we 
  2392. can access the selector and any parameters from C easily.
  2393.  
  2394. According to NIM: PPC System Software it is not safe to patch 
  2395. selector-based traps with PPC native code.  All patches of selector-
  2396. based traps on the PowerMac should be written in 68K code.
  2397.  
  2398. --
  2399. [23] How do I patch a trap on the PPC?
  2400.  
  2401. See NIM 'PowerPC System Software' for a more complete discussion.  
  2402. There is also a new book by Tom Thomson called 'Power Macintosh 
  2403. Programming Starter Kit' that has examples of how to patch traps on 
  2404. the PowerMac.  
  2405.  
  2406. Patching traps on the PowerMac is similar to patching on the 68K 
  2407. architecture.  Of course you must generate a UniversalProcPtr for 
  2408. each of your patches in the system heap, and these are then passed to 
  2409. the SetXTrapAddress routines.  Since code fragments have their own 
  2410. globals the use of A4 or A5-based mechanisms for accessing global 
  2411. variables isn't needed.  In order to call the previous trap you need 
  2412. to call CallUniversalProc or CallOSTrapUniversalProc and return its 
  2413. result from your patch.  As a result all patches on the PowerMac are 
  2414. tail patches.
  2415.  
  2416. You may find an application called 'Traps Check' useful.  This app 
  2417. supplies a report about all the traps on a Powermac, indicating 
  2418. whether each trap is emulated or native.  Another way to do this is 
  2419. to drop into MacsBug and disassemble from the address of the trap 
  2420. you're interested in (e.g., 'il CopyBits' ).  For traps that are 
  2421. native you'll see a routine descriptor that begins with the 
  2422. MixedModeMagic trap (AAFE). This of course won't tell you if the trap 
  2423. has been patched.  You can identify a patch by whether it's in RAM or 
  2424. ROM, from its address.  Determining whether a patched trap is PPC 
  2425. native or not may take some additioinal sleuthing. You can find Traps 
  2426. Check at:  ftp://sumex-aim.stanford.edu/info-mac/dev/traps-check-
  2427. 10.hqx
  2428.  
  2429. Here is a sample PowerMac trap patch for GetResource:
  2430.  
  2431. UniversalProcPtr gGetResourceUPP;
  2432. UniversalProcPtr gGetResourcePatchUPP;
  2433.  
  2434. /****InstallPatch**************************************************/
  2435.  
  2436. void
  2437. InstallPatch(void)
  2438. {
  2439.    gGetResourceUPP = GetToolTrapAddress( _GetResource );
  2440.  
  2441.    gGetResourcePatchUPP = 
  2442.       NewRoutineDescriptor( (ProcPtr) GetResourcePatch,  
  2443.       kPascalStackBased, GetCurrentISA() );
  2444.  
  2445.    SetToolTrapAddress( gGetResourcePatchUPP, _GetResource );
  2446.  
  2447. }
  2448.  
  2449.  
  2450. /****GetResourcePatch*********************************************/
  2451.  
  2452. Handle 
  2453. GetResourcePatch( ResType theType, short theID )
  2454. {
  2455.    Handle   result;
  2456.  
  2457. //We don't need no 'DUMB' resources
  2458.    if ( theType == 'DUMB' )
  2459.       result = NULL;
  2460.    else
  2461.       result = (Handle) CallUniversalProc( gGetResourceUPP,
  2462.             kGetResourceProcInfo, theType, theID );
  2463.    
  2464.    return result;
  2465.  
  2466. }
  2467.  
  2468. --
  2469. [24] Can I write a fat trap?
  2470.  
  2471. //Under construction
  2472.  
  2473. --
  2474. [25] Tips?
  2475.  
  2476. If your patch isn't called you may have guessed wrong on whether it's 
  2477. a ToolTrap or an OSTrap.  The high bit of the second byte of the trap 
  2478. word is set for ToolTraps.  The following function can be used to get 
  2479. the correct trap address for both ToolTraps and OSTraps.
  2480.  
  2481. pascal void * GetCurrentTrapAddress( unsigned short trapWord )
  2482. {
  2483.    if ( trapWord & 0x0800 )
  2484.       return GetToolTrapAddress ( trapWord & 0x07FF );
  2485.    else
  2486.       return GetOSTrapAddress ( trapWord & 0x07FF );
  2487. }
  2488.  
  2489.  
  2490. If the machine crashes after leaving your patch you have probably 
  2491. munged the stack or not saved and restored all the registers that you 
  2492. must.
  2493.  
  2494. The Finder patches a number of traps when it loads in a way that 
  2495. prevents earlier trap patches from functioning.  If your patch 
  2496. doesn't appear to be called it may be one of these patches.
  2497.  
  2498. --
  2499. [26] What other sources of information are available?
  2500.  
  2501. Knaster 'How to Write Macintosh Software'
  2502. Knaster and Rollin, 'Macintosh Programming Secrets'.  These books on 
  2503. Mac programming has some excellent info on trap patching.
  2504.  
  2505. Tom Thomson 'Power Macintosh Programming Starter Kit' This book has 
  2506. some example code for writing trap patches and extensions on the 
  2507. PowerMac.
  2508.  
  2509. The Extension Shell package at:
  2510. ftp://sumex-aim.stanford.edu/info-mac/dev/src/extension-shell-13.hqx
  2511. Dair's email address has changed to: dair.grant@ucl.ac.uk.
  2512.  
  2513. Usenet Macintosh Programmers Guide
  2514. ftp://sumex-aim.stanford.edu/info-mac/dev/info/usenet-mac-prog-guide-
  2515. msw.hqx
  2516.  
  2517. All of the Apple Tech Notes have been made available on Apple's web 
  2518. server:   http://www.info.apple.com/dev/technotes/Main.html
  2519.  
  2520. -- 
  2521. Brian  Stern  :-{)}
  2522. Toolbox commando and Menu bard
  2523. Jaeger@fquest.com
  2524.  
  2525. ---------------------------
  2526.  
  2527. >From shawnl@andyne.on.ca (Dave Charlesworth)
  2528. Subject: Linking 68k object files to PPC program
  2529. Date: Thu, 27 Oct 1994 19:26:03 GMT
  2530. Organization: Andyne Computing
  2531.  
  2532. I want to link some third party code to a PowerPC program.  Can someone
  2533. point me to documentation on how to make this work?
  2534.  
  2535. I don't have source for the third party stuff.  I'm using MPW (ETO 15)
  2536. cross- platform tools (PPCLink, PPCC), and have the Inside Mac volume
  2537. "PowerPC System Software".  I haven't been able to find anything in it
  2538. or in the ETO documentation, but it must be somewhere!
  2539.  
  2540. Thanks.
  2541.  
  2542. Shawn Leclaire
  2543.  
  2544. +++++++++++++++++++++++++++
  2545.  
  2546. >From zellers@pokey.basilsoft.com (Steve Zellers)
  2547. Date: Fri, 28 Oct 1994 20:52:49 -0800
  2548. Organization: BasilSoft, Inc.
  2549.  
  2550. In article <CyCJBF.Ms4@andyne.on.ca>, shawnl@andyne.on.ca (Dave
  2551. Charlesworth) wrote:
  2552.  
  2553. > I want to link some third party code to a PowerPC program.  Can someone
  2554. > point me to documentation on how to make this work?
  2555.  
  2556. Assuming you mean that the third party code is 68k, you can't.  You'll
  2557. have to write a stub code resource that re-exports all the symbols you
  2558. need through a paramblock as some sort using route descriptors.
  2559.  
  2560. --smz
  2561.  
  2562. +++++++++++++++++++++++++++
  2563.  
  2564. >From wdh@fresh.com (Bill Hofmann)
  2565. Date: Sat, 29 Oct 1994 18:27:36 GMT
  2566. Organization: Fresh Software
  2567.  
  2568. In article <CyCJBF.Ms4@andyne.on.ca>, shawnl@andyne.on.ca (Dave
  2569. Charlesworth) wrote:
  2570.  
  2571. > I want to link some third party code to a PowerPC program.  Can someone
  2572. > point me to documentation on how to make this work?
  2573. > I don't have source for the third party stuff.  I'm using MPW (ETO 15)
  2574. > cross- platform tools (PPCLink, PPCC), and have the Inside Mac volume
  2575. > "PowerPC System Software".  I haven't been able to find anything in it
  2576. > or in the ETO documentation, but it must be somewhere!
  2577. Nope, not really.  Maybe some of the MacTech articles have mentioned it.
  2578. But what you have to do is:
  2579.     * find out which routines *you* call in the library
  2580.     * write some 68k code that wraps the library in a way that you can
  2581.       call it: either use a selector-based approach (ie, if message==1,
  2582.       call function 1, etc) or make a routine that returns a table of 
  2583.       procptrs
  2584.     * compile/link the wrapper with the library
  2585.     * create proc infos and stub code to call your 68k wrapper in your
  2586.       PowerPC program
  2587.     * debug :->
  2588.  
  2589. Or, yell at the third party until they produce a PowerPC version (shared
  2590. library, or whatever).
  2591.  
  2592. -Bill
  2593.  
  2594. -- 
  2595. Bill Hofmann                                  wdh@fresh.com
  2596. Fresh Software and Instructional Design       voice: +1 510 524 0852
  2597. 1640 San Pablo Ave #C, Berkeley CA 94702 USA  fax:   +1 510 524 0853
  2598.  
  2599. ---------------------------
  2600.  
  2601. >From rjkmehta@bu.edu (Ravi Mehta)
  2602. Subject: Network Programming
  2603. Date: 19 Oct 1994 16:20:21 GMT
  2604. Organization: Boston University
  2605.  
  2606. I want to write some networkable software, but am completely new to network
  2607. programming.  Besdies IM: Networking ( which I will pickup ) is there
  2608. anything else that would help?  Will IM: Networking discuss programming
  2609. for BOTH AppleTalk and Ethernet?  If not, what would be a good
  2610. source for learning how to write Ethernet and AppleTalk compatible software.
  2611.  
  2612. Thanks in advance.
  2613.  
  2614. Ravi J. K. Mehta
  2615. Terminal Sunset Software
  2616.  
  2617.  
  2618. +++++++++++++++++++++++++++
  2619.  
  2620. >From andym96@aol.com (AndyM96)
  2621. Date: 20 Oct 1994 01:13:05 -0400
  2622. Organization: America Online, Inc. (1-800-827-6364)
  2623.  
  2624. In article <383h05$a37@news.bu.edu>, rjkmehta@bu.edu (Ravi Mehta) writes:
  2625.  
  2626. <<
  2627. Will IM: Networking discuss programming
  2628. for BOTH AppleTalk and Ethernet?  If not, what would be a good
  2629. source for learning how to write Ethernet and AppleTalk compatible
  2630. software.>>
  2631. yes, IM networking  discusses how to do that. Also, a good book is
  2632. "Programming with AppleTalk" by Michael Peirce -code samples are in
  2633. Pascal, though, but it is a thorough and detailed description of how
  2634. AppleTalk protocols work & how to use 'em. 
  2635. BTW, if you dicover a code sample how to write a requester-responder pair
  2636. using ATP  in C, <<PLEASE>> e-mail me  @ andym96@aol.com -I've been trying
  2637. to get this info for a couple of weeks now with no avail.
  2638. Andy
  2639.  
  2640. +++++++++++++++++++++++++++
  2641.  
  2642. >From ntuck@muddcs.cs.hmc.edu (Nathan D. Tuck)
  2643. Date: 20 Oct 1994 20:02:38 GMT
  2644. Organization: Harvey Mudd College, Claremont CA
  2645.  
  2646.  
  2647. >In article <383h05$a37@news.bu.edu>, rjkmehta@bu.edu (Ravi Mehta) writes:
  2648. >
  2649.  
  2650. >Will IM: Networking discuss programming
  2651. >for BOTH AppleTalk and Ethernet?  If not, what would be a good
  2652. >source for learning how to write Ethernet and AppleTalk compatible
  2653. >software.>>
  2654.  
  2655. For both AppleTalk and Ethernet?  AppleTalk is a software protocol while
  2656. Ethernet is the physical format that AppleTalk runs over.  If you mean
  2657. LocalTalk and Ethernet, the two should be equivalent so far as ATP
  2658. API's are concerned.  If you mean to run transparantly over different
  2659. protocol stacks such as ATP and IPX/SPX or TCP/IP, that is another
  2660. question entirely.
  2661.  
  2662. Nate
  2663. ntuck@hmc.edu
  2664.  
  2665.  
  2666.  
  2667. +++++++++++++++++++++++++++
  2668.  
  2669. >From Yorick_Ph*nix,MacTel_Iconex@metro.mactel.org (Yorick
  2670. Ph*nix,MacTel_Iconex)
  2671. Date: 29 Oct 1994 02:48:38 GMT
  2672. Organization: MacTel Metro BBS, London, England.
  2673.  
  2674. Ravi
  2675.  
  2676. > I want to write some networkable software, but am completely new to
  2677. > network programming.  Besdies IM: Networking ( which I will pickup )
  2678. > is there anything else that would help?
  2679.  
  2680. There is a very good book called something like Introduction to AppleTalk
  2681. Programming - I have a copy at the office and I learnt all my Network
  2682. Programming from it. It is possibly published by Addison-Wesley and is one in
  2683. a series where Scott Knaster is the Series Editor.
  2684.  
  2685. AppleTalk programming is what you should be doing (ATP, NBP, ADSP, PAP, etc)
  2686. whereas LocalTalk and EtherNet are the phsyical mediums over which the
  2687. network data travels - you shouldnt need to get involved at this level or
  2688. even know which phsyical medium your program is dealing with.
  2689.  
  2690. Yorick
  2691.  
  2692. - sent via an evaluation copy of BulkRate (unregistered).
  2693.  
  2694. --
  2695. ****************************************************************************
  2696.               MacTel Metro - Europes largest Mac specific BBS
  2697.   The views expressed in this posting those of the individual author only.
  2698.                     Send mail to this user at either :-
  2699. INTERNET:User_Name@metro.mactel.org          [use underline]  between first
  2700.  FIDONET:User.Name@f202.n254.z2.fidonet.org  [use fullstop ]  & last names
  2701. ****************************************************************************
  2702.  
  2703. ---------------------------
  2704.  
  2705. >From walkerj@math.scarolina.edu (James W. Walker)
  2706. Subject: Stuck in SyncWait again
  2707. Date: Sat, 15 Oct 1994 21:39:18 -0500
  2708. Organization: Dept. of Mathematics, Univ. of South Carolina
  2709.  
  2710. When an application freezes, dropping into MacsBug often reveals that it
  2711. is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  2712. force-quit does nothing.  Is there any hope for someone with debugger
  2713. skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  2714. and make it die a clean death, or should I just restart the Mac?
  2715. -- 
  2716.  Jim Walker
  2717.  
  2718. +++++++++++++++++++++++++++
  2719.  
  2720. >From jonasw@lysator.liu.se (Jonas Wallden)
  2721. Date: 16 Oct 1994 09:57:15 GMT
  2722. Organization: (none)
  2723.  
  2724. walkerj@math.scarolina.edu (James W. Walker) writes:
  2725.  
  2726. >When an application freezes, dropping into MacsBug often reveals that it
  2727. >is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  2728. >force-quit does nothing.  Is there any hope for someone with debugger
  2729. >skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  2730. >and make it die a clean death, or should I just restart the Mac?
  2731. >-- 
  2732. > Jim Walker
  2733.  
  2734. The SyncWait loop waits for a parameter block error code to drop below +1
  2735. (which is the value used while the call is in progress), and as we all know
  2736. this error code is 0 (noErr) for a successful request and negative for
  2737. errors.
  2738.  
  2739. So, look at the SyncWait code to see which word it tests (usually something
  2740. like 10(A0)) and set this word to an error code (e.g. FFD5 for fileNotFound)
  2741. and it will often get you out of the lock.
  2742.  
  2743. I've used it successfully in Mosaic several times where it seems to hang
  2744. when I abort a connection, and at other times when the computer won't
  2745. reboot after a crash.
  2746.  
  2747. BTW, I have a MacsBug dcmd which lists error strings from error codes.
  2748. This is great as it's rather difficult to use ObiWan at these times...
  2749. Can't remember if I got it from sumex or a Developer CD, though.
  2750.  
  2751. --
  2752. `.`.   Jonas Wallden                    `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  2753. `.`.`.   Internet: jonasw@lysator.liu.se  `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  2754. `.`.`.`.   AppleLink: sw1369                `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  2755.  
  2756. +++++++++++++++++++++++++++
  2757.  
  2758. >From wysocki@netcom.com (Chris Wysocki)
  2759. Date: Sun, 16 Oct 1994 16:31:58 GMT
  2760. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  2761.  
  2762. In article <walkerj-1510942139180001@192.0.2.1>,
  2763. James W. Walker <walkerj@math.scarolina.edu> wrote:
  2764.  
  2765. >When an application freezes, dropping into MacsBug often reveals that it
  2766. >is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  2767. >force-quit does nothing.  Is there any hope for someone with debugger
  2768. >skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  2769. >and make it die a clean death, or should I just restart the Mac?
  2770.  
  2771. Here's a MacsBug dcmd that I wrote a few weeks ago that simply does a
  2772. KillIO for a specified driver.  You might be able to use this when
  2773. you're stuck in _SyncWait to kill the pending request and get out
  2774. safely.  Since it's so small, I've attached it below, along with the
  2775. source code to it; hope you find it useful.
  2776.  
  2777. Chris.
  2778.  
  2779. - ------
  2780.  
  2781. +++++++++++++++++++++++++++
  2782.  
  2783. >From h+@nada.kth.se (Jon W{tte)
  2784. Date: Sun, 16 Oct 1994 20:15:31 +0100
  2785. Organization: Royal Institute of Something or other
  2786.  
  2787. In article <walkerj-1510942139180001@192.0.2.1>,
  2788. walkerj@math.scarolina.edu (James W. Walker) wrote:
  2789.  
  2790. >When an application freezes, dropping into MacsBug often reveals that it
  2791. >is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  2792. >force-quit does nothing.  Is there any hope for someone with debugger
  2793. >skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  2794. >and make it die a clean death, or should I just restart the Mac?
  2795.  
  2796. Usually this means a SCSI request isn't being served (or an 
  2797. Ethernet request, or a Serial Port request, or...) This is 
  2798. usually caused because of buggy drivers (like early Applied 
  2799. Engineering drivers, some CD-ROM and MO drivers and version 1.x 
  2800. of the Digidesign card drivers)
  2801.  
  2802. When something hangs in _vSyncWait, it waits for the word at 
  2803. (a0)+10 to go 0 or negative (this is ioResult in the parameter 
  2804. block) One thing you can TRY is:
  2805.  
  2806.     atba
  2807.     sw a0+10 ffff
  2808.     g
  2809.     atc
  2810.     es
  2811.  
  2812. This will make the app halt as soon as it gets to an A-trap (so 
  2813. it won't just get stuck again) Then it fakes an interrupt 
  2814. service routine that sets the result to -1 (an error code) Run 
  2815. with this; and as soon as an A-trap is hit, clear breaks and 
  2816. exit.
  2817.  
  2818. However, since this is a driver that got hosed, chances are 
  2819. you'll run into the same problem an instant later, so it's 
  2820. usually not terribly helpful.
  2821.  
  2822. There are also several conditions which can make this fail:
  2823.  
  2824. - If some idiot masked interrupts, that's the reason you're
  2825.   waiting for an interrupt that's never serviced. Check with TD
  2826.   and look at the Int= figure - should be 0. 7 is real bad.
  2827.  
  2828. - If this was because of a file manager request; the file 
  2829.   manager is now in a meeting for the rest of the day, which 
  2830.   means you earned just about nothing by breaking out.
  2831.  
  2832. - If the driver makes interesting assumptions about the return 
  2833.   value you use (ffff==-1 in this case) OR wants a completion 
  2834.   routine to be called, you're probably hosed anyway.
  2835.  
  2836. There should be a law only competent people can write drivers. 
  2837. Unfortunately it seems to be the other way around with some 
  2838. people "Hey, we've got this interesting hardware we can sell. 
  2839. However, hiring someone expensive to write the drivers would 
  2840. eat into our margin way too much. Isn't Joes 13-year-old kid
  2841. into computers? Have him whip something up and we'll give him a 
  2842. Happy Meal."
  2843.  
  2844. Hardware without drivers is pretty useless.
  2845.  
  2846. Cheers,
  2847.  
  2848.                     / h+
  2849.  
  2850.  
  2851. --
  2852.   Jon W$E4tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
  2853.  
  2854.  -- I don't fear death, it's dying that scares me.
  2855.  
  2856.  
  2857. +++++++++++++++++++++++++++
  2858.  
  2859. >From jumplong@aol.com (Jump Long)
  2860. Date: 17 Oct 1994 00:44:01 -0400
  2861. Organization: America Online, Inc. (1-800-827-6364)
  2862.  
  2863. In article <walkerj-1510942139180001@192.0.2.1>,
  2864. walkerj@math.scarolina.edu (James W. Walker) wrote:
  2865.  
  2866. >When an application freezes, dropping into MacsBug often reveals that it
  2867. >is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  2868. >force-quit does nothing.  Is there any hope for someone with debugger
  2869. >skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  2870. >and make it die a clean death, or should I just restart the Mac?
  2871.  
  2872. Here are a couple of paragraphs from the article "Asynchronous Routines on
  2873. the Macintosh" in develop issue #13 that explain deadlock conditions and
  2874. SyncWait:
  2875.  
  2876. - ----
  2877.  
  2878. Avoid SyncWait.
  2879.  
  2880. Does your Macintosh just sit there not responding to user events? Drop
  2881. into the debugger and take a look at the code that's executing. Does it
  2882. look like this?
  2883.  
  2884. MOVE.W $0010(A0),D0
  2885. BGT.S  -$04,(PC)
  2886.  
  2887. That's SyncWait, the routine that synchronous calls sit in while waiting
  2888. for a request to complete. Register A0 points to the parameter block used
  2889. to make the call, offset $10 is the ioResult field of the parameter block,
  2890. and SyncWait is waiting for ioResult to be less than or equal to 0
  2891. (noErr).
  2892.  
  2893. The ioResult field is changed by code executing as a result of an
  2894. interrupt. If interrupts are disabled (because the synchronous call was
  2895. made at interrupt time) or if the synchronous call was made to a service
  2896. that's busy, you'll be in SyncWait forever. Take a look at the parameter
  2897. block and where it is in memory, and you'll probably be able to figure out
  2898. which synchronous call was made at interrupt time and which program made
  2899. it.
  2900.  
  2901. - ---
  2902.  
  2903. Deadlock is a state in which each of two or more processes is waiting for
  2904. one of the other processes to release some resource necessary for its
  2905. completion. The resource may be a file, a global variable, or even the
  2906. CPU. The process could, for example, be an application's main event loop
  2907. or a Time Manager task.
  2908.  
  2909. When deadlock occurs on the Macintosh, usually at least one of the
  2910. processes is executing as the result of an interrupt. VBL tasks, Time
  2911. Manager tasks, Deferred Task Manager tasks, completion routines, and
  2912. interrupt handlers can all interrupt an application's main thread of
  2913. execution. When the interrupted process is using a resource that the
  2914. interrupting process needs, the processes are deadlocked.
  2915.  
  2916. For example, suppose a Time Manager task periodically writes data to a
  2917. file by making a synchronous Write request, and an application reads the
  2918. data from its main event loop. Depending on the frequency of the task and
  2919. the activity level of the File Manager, the Time Manager task may often
  2920. write successfully. Inevitably, however, the Time Manager task will
  2921. interrupt the application's Read request and deadlock will occur.
  2922.  
  2923. Because the File Manager processes only one request at a time, any
  2924. subsequent requests must wait for the current request to complete. In this
  2925. case, the synchronous request made by the Time Manager task must wait for
  2926. the application's Read request to complete before its Write request will
  2927. be processed. Unfortunately, the File Manager must wait for the Time
  2928. Manager task to complete before it can resume execution. Each process is
  2929. now waiting for the other to complete, and they will continue to wait
  2930. forever.
  2931.  
  2932. Synchronous requests at interrupt time tend to produce deadlock, because
  2933. the call is queued for processing and then the CPU sits and spins, waiting
  2934. for an interrupt to occur, which signals that the request has been
  2935. completed. If interrupts are turned off, or if a previous pending request
  2936. can't finish because it's waiting to resume execution after the interrupt,
  2937. the CPU will wait patiently (and eternally) for the request to finish -
  2938. until you yank the power cord from the wall.
  2939.  
  2940. - ---
  2941.  
  2942. Read the rest of that article, it'll help you write code that doesn't end
  2943. up in SyncWait.
  2944.  
  2945. - Jim Luther
  2946.  
  2947.  
  2948. +++++++++++++++++++++++++++
  2949.  
  2950. >From walkerj@math.scarolina.edu (James W. Walker)
  2951. Date: Mon, 17 Oct 1994 23:41:46 -0500
  2952. Organization: Dept. of Mathematics, Univ. of South Carolina
  2953.  
  2954. In article <37sveh$t0t@newsbf01.news.aol.com>, jumplong@aol.com (Jump
  2955. Long) wrote:
  2956.  
  2957. > Read the rest of that article, it'll help you write code that doesn't end
  2958. > up in SyncWait.
  2959.  
  2960. I guess I didn't make it clear in my original post, but it's not *my* code
  2961. that gets stuck in SyncWait. It's usually Internet apps like Anarchie.  I
  2962. was just wondering whether there was anything I could do when it happens,
  2963. other than restart, and this thread has given me some ideas.  Gee, I can
  2964. hardly wait for the next freeze. :-)
  2965. -- 
  2966.  Jim Walker
  2967.  
  2968. +++++++++++++++++++++++++++
  2969.  
  2970. >From bierman@caelab1.cae.wisc.edu (Peter Bierman)
  2971. Date: Tue, 18 Oct 1994 14:36:31 -0600
  2972. Organization: Happy Frogs, Inc.
  2973.  
  2974. In article <walkerj-1710942341460001@192.0.2.1>,
  2975. walkerj@math.scarolina.edu (James W. Walker) wrote:
  2976.  
  2977. > In article <37sveh$t0t@newsbf01.news.aol.com>, jumplong@aol.com (Jump
  2978. > Long) wrote:
  2979. > > Read the rest of that article, it'll help you write code that doesn't end
  2980. > > up in SyncWait.
  2981. > I guess I didn't make it clear in my original post, but it's not *my* code
  2982. > that gets stuck in SyncWait. It's usually Internet apps like Anarchie.  I
  2983. > was just wondering whether there was anything I could do when it happens,
  2984. > other than restart, and this thread has given me some ideas.  Gee, I can
  2985. > hardly wait for the next freeze. :-)
  2986.  
  2987.  
  2988. Well, all of the ideas are good and accurate, but here's an easy fix.
  2989.  
  2990. Do a step (oa-T) till Macsbug says "Will [not] branch". Then type:
  2991.  
  2992. pc=pc+2
  2993.  
  2994. g
  2995.  
  2996. That will jump you out of the loop. It's faster than "fixing" the loop
  2997. condition. Just note that what John said is true: it'll probobly happen
  2998. again withing a short time. Restart right away.
  2999.  
  3000. -Peter
  3001.  
  3002. -- 
  3003.        Peter Bierman       \  The Metropolis  \ The most primitive part of
  3004. the
  3005. bierman@caelab1.cae.wisc.edu\  (614)-846-1911  \   the brain concerns itself
  3006.                              \  600MB Mac Files \     with the "Four F's":
  3007. "I've changed my mind, Hobbes.\  FirstClass GUI  \ Feeding, Fighting,
  3008. Fleeing,
  3009.  people are scum." --Calvin    \  Info-Mac CD-ROM \     and Reproduction.
  3010.  
  3011. +++++++++++++++++++++++++++
  3012.  
  3013. >From richardb@cocytus.demon.co.uk (Richard Buckle)
  3014. Date: Wed, 19 Oct 1994 06:37:42 GMT
  3015. Organization: none
  3016.  
  3017. In article <AAC73A63966886B32@klkmac003.nada.kth.se>,
  3018. h+@nada.kth.se (Jon W{tte) wrote:
  3019.  
  3020. >>When an application freezes, dropping into MacsBug often reveals that it
  3021. >>is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  3022. >>force-quit does nothing.  Is there any hope for someone with debugger
  3023. >>skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  3024. >>and make it die a clean death, or should I just restart the Mac?
  3025.  
  3026. To be honest you can often get away with stepping over the SyncWait test if
  3027. you restart *immediately* you regain control.
  3028.  
  3029. In MacsBug, do a T 40. This should pop you out of any subroutines you're in
  3030. and leave you in the 2-step SyncWait loop; if not, keep doing T 40 until
  3031. you are. If you're at the TST instruction, do one more T to get to the
  3032. branch instruction. Then do PC=PC+2;G to exit the loop. 
  3033.  
  3034. You may need to repeat this process one or more times to regain control.
  3035. Once you have control, go straight to the Finder and to a Restart before
  3036. the driver can bite you again.
  3037.  
  3038. No guarantees and YMMV. However, 90% of the tine this lets be save my work
  3039. :-|
  3040.  
  3041.  
  3042.  
  3043. - -----------------------------------------------------
  3044. Richard Buckle
  3045. richardb@cocytus.demon.co.uk
  3046. Using this darned fine NewsHopper thingy.
  3047.  
  3048.  
  3049. +++++++++++++++++++++++++++
  3050.  
  3051. >From quinn@cs.uwa.edu.au (Quinn "The Eskimo!")
  3052. Date: Fri, 28 Oct 1994 10:13:36 +0800
  3053. Organization: Department of Computer Science, The University of Western
  3054. Australia
  3055.  
  3056. In article <walkerj-1710942341460001@192.0.2.1>,
  3057. walkerj@math.scarolina.edu (James W. Walker) wrote:
  3058.  
  3059. >I guess I didn't make it clear in my original post, but it's not *my* code
  3060. >that gets stuck in SyncWait. It's usually Internet apps like Anarchie.
  3061.  
  3062. For reliable program (like Anarchie :) disappearing into SyncWait normally
  3063. means that your networking on your machine is stuffed up somehow.
  3064.  
  3065. To get out try this in MacsBug...
  3066.  
  3067.   sm a0+10 ffff
  3068.   g
  3069.  
  3070. What it does is set the ioResult field of the paramblock to -1, indicating
  3071. an error.  You often have to do it a *lot* of times before it comes back
  3072. and often it doesn't work at all.  But it makes you feel like you've got
  3073. control (:
  3074.  
  3075. Share and Enjoy.
  3076. --
  3077. Quinn "The Eskimo!"      "I wasn't the one who fired the heat seeking
  3078.                           population annihilator out the window!"
  3079.   Amaze your friends!  Learn some cool MacsBug or MicroBug commands today (:
  3080.  
  3081. +++++++++++++++++++++++++++
  3082.  
  3083. >From devon_hubbard@taligent.com (Devon Hubbard)
  3084. Date: Fri, 28 Oct 1994 16:20:48 GMT
  3085. Organization: Taligent, Inc.
  3086.  
  3087. In article <quinn-2810941013360001@mac168.cs.uwa.oz.au>,
  3088. quinn@cs.uwa.edu.au (Quinn "The Eskimo!") wrote:
  3089.  
  3090. >In article <walkerj-1710942341460001@192.0.2.1>,
  3091. >walkerj@math.scarolina.edu (James W. Walker) wrote:
  3092. >
  3093. >>I guess I didn't make it clear in my original post, but it's not *my* code
  3094. >>that gets stuck in SyncWait. It's usually Internet apps like Anarchie.
  3095. >
  3096. >For reliable program (like Anarchie :) disappearing into SyncWait normally
  3097. >means that your networking on your machine is stuffed up somehow.
  3098. >
  3099. >To get out try this in MacsBug...
  3100. >
  3101. >  sm a0+10 ffff
  3102. >  g
  3103. >
  3104. >What it does is set the ioResult field of the paramblock to -1, indicating
  3105. >an error.  You often have to do it a *lot* of times before it comes back
  3106. >and often it doesn't work at all.  But it makes you feel like you've got
  3107. >control (:
  3108.  
  3109. Ouch! OUCH! This is assuming that reg A0 really points to the
  3110. cntrlParamBlockRec, which I hate to say doesn't always! I recently ran
  3111. into a vSyncWait problem (on an 8100av) that lead to fingering the
  3112. offending driver by looking at the data moved off D2 and matching that as
  3113. a DCE entry with the help of Macsbug's 'drvr' dcmd.  In every case of
  3114. vSyncWait hang, a0 WAS NOT pointing to a valid paramblock so do a
  3115.  
  3116.    dm a0 cntrlparamblockrec
  3117.  
  3118. before the 'sm' and make sure it looks like a valid paramblock, or you'll
  3119. surely be rebooting thereafter.
  3120.  
  3121. dEVoN
  3122.  
  3123. - -----------------------------------------------------------------------
  3124. Devon Hubbard                                               Silicon Pilot
  3125. devon_hubbard@taligent.com                                  Taligent, Inc
  3126.  
  3127. ---------------------------
  3128.  
  3129. >From macrshap@bbn.com (Richard Shapiro)
  3130. Subject: having trouble with AEInteractWithUser & drag manager
  3131. Date: 9 Oct 1994 17:09:27 GMT
  3132. Organization: Bolt, Beranek and Newman Inc.
  3133.  
  3134. I'm in the process of adding some drag-support to an application. It's
  3135. working ok when the application is selected, so the underlying drag
  3136. management seems fine. But usually, I want to drag when another
  3137. application is selected (ie I'll be dragging from that other application).
  3138. In this case, when my app receives the drag, it needs to interact with the
  3139. user before proceeding. This is where I'm stuck. 
  3140.  
  3141. I've set the InteractionAllowed flag to kAEInteractWithLocal (the default,
  3142. I know, but I thought I'd be explicit), and I carefully call
  3143. AEInteractWithUser before attempting any interaction. I'm calling it
  3144. without a timeout (kNoTimeOut), without a notification rec (should be OK
  3145. since I have the relevant BNDL, FREF and ICN# resources defined), and with
  3146. a very simple idle procedure which essentially does nothing (since at the
  3147. moment nothing in my app cares about update or activate events). 
  3148.  
  3149. What I expected to happen was the usual flashing in the
  3150. current-application icon (on the right edge of the menubar), which would
  3151. allow me to bring my app to the front. What actually happens is...nothing:
  3152. no flashing, no process paying attention to mouse clicks, hence no way to
  3153. select my application (which has received the drop and is waiting in the
  3154. call to AEInteractWithUser) so that I can interact with it. All I can do
  3155. is cmd-opt-escape to force a quit.
  3156.  
  3157. What am I doing wrong? I'm assuming it must be one of two things: either
  3158. it's illegal to have user interaction after receiving a drop but before
  3159. acknowledging receipt; or I need to handle something in my idle function
  3160. which I'm not currently handling.
  3161.  
  3162. Any suggestions? If it matters, I'm using CW 4.5 C, and running System 7.1
  3163. on a q660av with drag extensions and the drag-ware Finder (7.1.3). The
  3164. drag flavors I'm handling at the moment are 'hfs ' and 'TEXT'.
  3165.  
  3166. Please copy followups to email -- thanks.
  3167.  
  3168. -- 
  3169. rs/macrshap@bbn.com
  3170.  
  3171. +++++++++++++++++++++++++++
  3172.  
  3173. >From Jens Alfke <jens_alfke@powertalk.apple.com>
  3174. Date: Mon, 10 Oct 1994 22:12:55 GMT
  3175. Organization: Apple Computer
  3176.  
  3177. Richard Shapiro, macrshap@bbn.com writes:
  3178. > What am I doing wrong? I'm assuming it must be one of two things: either
  3179. > it's illegal to have user interaction after receiving a drop but before
  3180. > acknowledging receipt
  3181.  
  3182. Bingo -- more specifically, it's illegal to cause a process switch while
  3183. inside a drag handler, since the drag handlers are called via a lightweight
  3184. process switch that is not compatible with the regular kind of process
  3185. switch. While you're in a drag handler, WNE is hacked to do nothing for
  3186. compatibility, but other ways to interact (such as calling AEInteractWithUser
  3187. or SetFrontProcess) will choke your machine.
  3188.  
  3189. Moral: Wait until after the drag finishes to try to interact with the user.
  3190.  
  3191. --Jens Alfke                           jens_alfke@powertalk.apple.com
  3192.                    "A man, a plan, a yam, a can of Spam ... Bananama!"
  3193.  
  3194. +++++++++++++++++++++++++++
  3195.  
  3196. >From macrshap@bbn.com (Richard Shapiro)
  3197. Date: 11 Oct 1994 01:54:10 GMT
  3198. Organization: Bolt, Beranek and Newman Inc.
  3199.  
  3200. In article <1994Oct10.221255.26429@gallant.apple.com>, Jens Alfke
  3201. <jens_alfke@powertalk.apple.com> wrote:
  3202.  
  3203. > Bingo -- more specifically, it's illegal to cause a process switch while
  3204. > inside a drag handler, since the drag handlers are called via a lightweight
  3205. > process switch that is not compatible with the regular kind of process
  3206. > switch. While you're in a drag handler, WNE is hacked to do nothing for
  3207. > compatibility, but other ways to interact (such as calling
  3208. AEInteractWithUser
  3209. > or SetFrontProcess) will choke your machine.
  3210. > Moral: Wait until after the drag finishes to try to interact with the user.
  3211.  
  3212. OK, I eventually came to that conclusion myself. I guess it's good to have
  3213. it validated... 
  3214.  
  3215. Problem is, I really need user interaction to complete the processing of
  3216. the drop. So, I tried to get around it by stashing the DragReference in a
  3217. global, setting a flag, returning from the handler, and then dealing with
  3218. the stashed DragReference when I'm back in the main event loop (depending
  3219. on the flag, of course). This doesn't work either. I can interact with the
  3220. user, but it looks as though the information associated with the
  3221. DragReference vanishes once the handler is exited. At least, I can't get
  3222. CountDragItems and the like to work properly outside the handler context.
  3223. Are these supposed to work outside the handler?
  3224.  
  3225. That seems to leave me with one final option: I have to get *all* the data
  3226. out of the DragReference while I'm in the handler, stash the whole pile
  3227. somewhere, exit the handler, and process the data later. Yucch, that's
  3228. pretty awful. Is there another possibility I'm missing here?
  3229.  
  3230. For now, I "fixed" the application to run without user-interaction when it
  3231. isn't in the foreground (which can only happen as a result of a drop).
  3232. It's better than nothing, but really not what I want...
  3233.  
  3234. -- 
  3235. rs/macrshap@bbn.com
  3236.  
  3237. +++++++++++++++++++++++++++
  3238.  
  3239. >From Jens Alfke <jens_alfke@powertalk.apple.com>
  3240. Date: Tue, 11 Oct 1994 17:28:36 GMT
  3241. Organization: Apple Computer
  3242.  
  3243. Richard Shapiro, macrshap@bbn.com writes:
  3244. > That seems to leave me with one final option: I have to get *all* the data
  3245. > out of the DragReference while I'm in the handler, stash the whole pile
  3246. > somewhere, exit the handler, and process the data later. Yucch, that's
  3247. > pretty awful. Is there another possibility I'm missing here?
  3248.  
  3249. Since you can't possibly use the DragReference after the sender disposes of
  3250. it, I think this is your only option. Is it that bad? Get the data you want
  3251. to use, stash it somewhere temporary, and when you get back into your event
  3252. loop ask the user what to do with it.
  3253.  
  3254. --Jens Alfke                           jens_alfke@powertalk.apple.com
  3255.                    "A man, a plan, a yam, a can of Spam ... Bananama!"
  3256.  
  3257. +++++++++++++++++++++++++++
  3258.  
  3259. >From macrshap@bbn.com (Richard Shapiro)
  3260. Date: 11 Oct 1994 22:25:03 GMT
  3261. Organization: Bolt, Beranek and Newman Inc.
  3262.  
  3263. In article <1994Oct11.172836.17257@gallant.apple.com>, Jens Alfke
  3264. <jens_alfke@powertalk.apple.com> wrote:
  3265.  
  3266.  
  3267. > Since you can't possibly use the DragReference after the sender disposes of
  3268. > it
  3269.  
  3270. As expected.
  3271.  
  3272. > I think this is your only option. Is it that bad? Get the data you want
  3273. > to use, stash it somewhere temporary, and when you get back into your event
  3274. > loop ask the user what to do with it.
  3275.  
  3276. No, it's not as bad as I thought. In fact it's already done and the result
  3277. is cleaner than my original plan :)
  3278.  
  3279. Now on to my next drag-manager question: receiving promise-hfs drags in an
  3280. application other than the Finder. Details in another posting...
  3281.  
  3282. -- 
  3283. rs/macrshap@bbn.com
  3284.  
  3285. +++++++++++++++++++++++++++
  3286.  
  3287. >From leonardr@netcom.com (Leonard Rosenthol)
  3288. Date: Wed, 19 Oct 1994 22:01:35 GMT
  3289. Organization: Aladdin Systems, Inc.
  3290.  
  3291. In article <macrshap-1110941825500001@ipa.bbn.com>, macrshap@bbn.com
  3292. (Richard Shapiro) wrote:
  3293.  
  3294. > > I think this is your only option. Is it that bad? Get the data you want
  3295. > > to use, stash it somewhere temporary, and when you get back into your
  3296. event
  3297. > > loop ask the user what to do with it.
  3298. > No, it's not as bad as I thought. In fact it's already done and the result
  3299. > is cleaner than my original plan :)
  3300.    What I've been doing in this case is to get all the info from the Drag,
  3301. and then send it back to myself in an Apple event (but NOT in sendToSelf
  3302. mode).  This works quite nicely...
  3303.  
  3304.  
  3305. Leonard
  3306. - ------------------------------------------------------------------------
  3307. Leonard Rosenthol                      Internet:       leonardr@netcom.com
  3308. Director of Advanced Technology        AppleLink:      MACgician
  3309. Aladdin Systems, Inc.                  GEnie:          MACgician
  3310.  
  3311. +++++++++++++++++++++++++++
  3312.  
  3313. >From jonpugh@netcom.com (Jon Pugh)
  3314. Date: Wed, 26 Oct 1994 07:08:53 GMT
  3315. Organization: Will hack for food
  3316.  
  3317. Leonard Rosenthol (leonardr@netcom.com) wrote:
  3318. >    What I've been doing in this case is to get all the info from the Drag,
  3319. > and then send it back to myself in an Apple event (but NOT in sendToSelf
  3320. > mode).  This works quite nicely...
  3321.  
  3322. I actually send the event twice.  Once to myself as record only, and then
  3323. again with signature addressing so that it goes through the event loop.
  3324. That way you can record the event too.
  3325.  
  3326. Jon
  3327.  
  3328.  
  3329. ---------------------------
  3330.  
  3331. End of C.S.M.P. Digest
  3332. **********************
  3333.  
  3334.  
  3335. ---------------------------------------------------------------------
  3336.  
  3337. NOTE:  The following Macintosh file(s) are enclosed with this
  3338. message, in BinHex format.  If your mail system does not convert
  3339. BinHex files automatically, you will need to transfer the message to
  3340. a Mac and run the BinHex application to decode it.
  3341.  
  3342. Filename: KillIO dcmd.sit    Size:  3181 bytes
  3343.  
  3344. ---------------------------------------------------------------------
  3345.  
  3346. (This file must be converted with BinHex 4.0)
  3347.  
  3348.  
  3349.