moyman@ecn.purdue.edu (James M Moya) (08/10/90)
How is it that cdev/INIT's like Moire and SuperClock (and many others) can run in the background whether multifinder is running or not!! I have been checking every mac bnook I know of to learn of this black magic...NOTHING. Exactly what is it they are doing?? Or does anybody *really* know... I have an "appletalk" listener I am writing (cdev/INIT) that I want to come forward with a dialog when it recieves a particular packet...This should work whether Multi is running or not...I haven't been able to find *anything* in IM or any other book for that matter...I am frazzled at this point...Anybody with some insight to help a man on the brink... Mike Moya Systems Programmer Engineering Computer Network Purdue University
jackiw@cs.swarthmore.edu (Nick Jackiw) (08/10/90)
moyman@ecn.purdue.edu (James M Moya) writes: > How is it that cdev/INIT's like Moire and SuperClock (and many others) can > run in the background whether multifinder is running or not!! I have been > checking every mac bnook I know of to learn of this black magic...NOTHING. > > Exactly what is it they are doing?? Or does anybody *really* know... > > I have an "appletalk" listener I am writing (cdev/INIT) that I want to come > forward with a dialog when it recieves a particular packet...This should > work whether Multi is running or not...I haven't been able to find > *anything* in IM or any other book for that matter...I am frazzled at > this point...Anybody with some insight to help a man on the brink... > > > > Mike Moya > Systems Programmer > Engineering Computer Network > Purdue University -- -----Nicholas Jackiw [jackiw@cs.swarthmore.edu|jackiw@swarthmr.bitnet]----- "Here is how I built this artificial mine. I snatched a female louse from the hair of humanity. I was seen to lie with her on three successive nights, and then I flung her into the pit." _Maldoror_, Canto II
jackiw@cs.swarthmore.edu (Nick Jackiw) (08/10/90)
Sorry about that blank posting--MacIP trashed my window and I was typing blind. moyman@ecn.purdue.edu (James M Moya) writes: > How is it that cdev/INIT's like Moire and SuperClock (and many others) can > run in the background whether multifinder is running or not!! I have been > checking every mac bnook I know of to learn of this black magic...NOTHING. > > Exactly what is it they are doing?? Or does anybody *really* know... Multifinder only schedules applications, and thus has nothing to do with init/cdevs. Instead, these programs install their code (usually into the system heap) while their INIT section is running. Then, they alter the system environment somewhat so that their code gets called periodically. The two most popular ways of doing this are by patching a trap which you can count on all applications calling frequently (e. g. SystemTask) or which is relevant to your particular task (e. g. MenuSelect, if your init/cdev dynamically altered application menus), or by installing an interrupt handler which is invoked by the vertical blanking interval interrupt. When either the trap is called or the VBL fires, the code they've loaded into the system heap is executed, allowing them to, say, check whether User's been idle for the predetermined time (Moire) or whether the clock has ticked (Superclock). > > > > I have an "appletalk" listener I am writing (cdev/INIT) that I want to come > > forward with a dialog when it recieves a particular packet...This should > > work whether Multi is running or not...I haven't been able to find > > *anything* in IM or any other book for that matter...I am frazzled at > > this point...Anybody with some insight to help a man on the brink... There are problems inherent in forcing your own dialog from out of the wood- work on some foreground application. What if, for example, that application hasn't called _InitDialogs, which must be done before any dialog manager use? (There are many other problems, too.) TechNote#184, and a chapter in Inside Mac#6, describe the Notification Manager, a built-in way for background applications and other "faceless code" (like an init/cdev) to issue a dialog which minimizes these compatibility problems. The dialog is pretty limited--you can have some canned text and only one button. However, this dialog can instruct the user to take some action which will allow you full and legal control over the interface, at which time you can put up anything you want. In your case, the Notification Manager would say something like "Whoa! My particular packet's here! Quick, open up my cdev." Note that this is how the Print Monitor works. > > Mike Moya -- -----Nicholas Jackiw [jackiw@cs.swarthmore.edu|jackiw@swarthmr.bitnet]----- "Here is how I built this artificial mine. I snatched a female louse from the hair of humanity. I was seen to lie with her on three successive nights, and then I flung her into the pit." _Maldoror_, Canto II
topping@anaconda.cis.ohio-state.edu (brian e topping) (08/10/90)
In article <8JTNK0C@cs.swarthmore.edu> jackiw@cs.swarthmore.edu (Nick Jackiw) writes: > >moyman@ecn.purdue.edu (James M Moya) writes: >> How is it that cdev/INIT's like Moire and SuperClock (and many others) can >> run in the background whether multifinder is running or not!! I have been >> checking every mac bnook I know of to learn of this black magic...NOTHING. >... Instead, these programs install their code (usually into >the system heap) while their INIT section is running. Then, they alter >the system environment somewhat so that their code gets called periodically. >The two most popular ways of doing this are by patching a trap which you >can count on all applications calling frequently (e. g. SystemTask) or >which is relevant to your particular task (e. g. MenuSelect, if your >init/cdev dynamically altered application menus), or by installing an >interrupt handler which is invoked by the vertical blanking interval >interrupt. When either the trap is called or the VBL fires, the code >they've loaded into the system heap is executed, allowing them to, say, >check whether User's been idle for the predetermined time (Moire) or >whether the clock has ticked (Superclock). Actually, if you have ever looked inside what SuperClock, Pyro, and the like are doing, you will have found a safer method. I can never remember where I saw this documented, but it is somewhere in the phone book edition (the brown pages). The trick is to use the low memory global jGNEFilter, defined in the Apple assembler equates as: JGNEFilter EQU $29A; GetNextEvent filter proc [pointer] This is documented in Tech Note 85: You must call GetNextEvent periodically. GetNextEvent uses a filter (GNE filter) which allows for a routine to be installed which overrides (or augments) the behavior of the system. The GNE filter is installed by pointing the low-memory global jGNEFilter (a long word at $29A) to the routine. After all other GNE processing is complete, the routine will be called with A1 pointing to the event record and D0 containing the boolean result. The filter may then modify the event record or change the function result by altering the word on the stack at 4(A7). This word will match D0 initially, of course. The way the screen savers work is just watch the mouse location and reset a counter to the new event->when value when it moves. If (event->when - counter) goes past an amount of time (i.e. 360 for one minute) the screen blanks. This seems preferred over other methods because if the app isn't calling WaitNextEvent, it probably is too busy to have cycles eaten up by screen savers and the like. >> > Mike Moya >-----Nicholas Jackiw [jackiw@cs.swarthmore.edu|jackiw@swarthmr.bitnet]----- Brian Topping <topping@cis.ohio-state.edu>
llama@eleazar.dartmouth.edu (Joe Francis) (08/10/90)
In article <82899@tut.cis.ohio-state.edu> brian e topping <topping@cis.ohio-state.edu> writes:
->Actually, if you have ever looked inside what SuperClock, Pyro, and the like
->are doing, you will have found a safer method. I can never remember where
->I saw this documented, but it is somewhere in the phone book edition
->(the brown pages). The trick is to use the low memory global jGNEFilter,
->defined in the Apple assembler equates as:
-> JGNEFilter EQU $29A; GetNextEvent filter proc [pointer]
->This seems preferred over other methods because if the app isn't calling
->WaitNextEvent, it probably is too busy to have cycles eaten up by screen
->savers and the like.
If you do this (and I don't recommend it), make sure that you call the
previous contents of the global (if they are not null), otherwise other
"lurkers" using this method will be high and dry.
----------------------------------------------------------------------------
"...beeeeeeep...This has been a test of the auto reboot system. Had this
been a real system crash, the attention tone would be followed by loud
shrieks from distressed users..."
resnick@lees.cogsci.uiuc.edu (Pete Resnick) (08/11/90)
The method I have been using for getting something running in the background is writing the code as a device driver that is in the system heap and locked and the dNeedTime bit set. This seems much safer than patching traps, and unlike VBL tasks (at least in THINK C 4.0) you can have global variables floating around and call routines that move memory. All the INIT does is call OpenDriver and exits. pr -- Pete Resnick (...so what is a mojo, and why would one be rising?) Graduate assistant - Philosophy Department, Gregory Hall, UIUC System manager - Cognitive Science Group, Beckman Institute, UIUC Internet/ARPAnet/EDUnet : resnick@kant.cogsci.uiuc.edu BITNET (if no other way) : FREE0285@UIUCVMD
zben@umd5.umd.edu (Ben Cranston) (08/11/90)
In article <1990Aug9.203803.13885@ecn.purdue.edu> moyman@ecn.purdue.edu (James M Moya) writes: > How is it that cdev/INIT's like Moire and SuperClock (and many others) can > run in the background whether multifinder is running or not!! Other followups to this message have mentioned Vertical Retrace interrupts and patching traps, but there are two other solutions that might be useful in some specific instances. One possibility is to install a device driver at init time and use the "needs periodic service" bit to get the driver called periodically as a result of the user program calling SystemTask. Another possibility is to use IO completion chaining, in which the completion routine for one IO operation does an ASYNCHRONOUS call to schedule IO for the next IO operation. For example, a simple AppleTalk responder could daisy chain between a lurking read for a probe and a response to the probe. Can you say "responder"? This works well when the parameter blocks can be preallocated and mostly loaded and only a little information has to be patched in on the fly. -- Ben Cranston <zben@umd2.umd.edu> A determined iconoclast, it would be better to assume the opinion expressed above is the diametric OPPOSITE to that of the Warm and Fuzzy Network Group of Egregious State University...
hawley@adobe.COM (Steve Hawley) (08/11/90)
In article <1990Aug9.203803.13885@ecn.purdue.edu> moyman@ecn.purdue.edu (James M Moya) writes: >How is it that cdev/INIT's like Moire and SuperClock (and many others) can >run in the background whether multifinder is running or not!! I have been >checking every mac bnook I know of to learn of this black magic...NOTHING. > >Exactly what is it they are doing?? Or does anybody *really* know... I can't answer your question as to what they are doing, but I can tell you a few ways that this can be done (although not in specifics). First: you need to have your code running in the system heap so that it hangs around no matter what application is running. Second: You need some mechanism to have your function called periodically. Here are a few ways to do this: 1) have your job submitted as a VBL task. You can have it scheduled to run with a granularity down to 1/60th of a second. 2) Write a driver (file type DRVR, I think), which can also be accessed every so many clock ticks. Both of these get called at the interrupt level, so you cannot execute any of the 3 million toolbox functions that move memory. This includes pretty much everything useful (like drawing to the screen, but I'm sure someone like Tim Maroney will correct me on this, since he has all the memory moving traps memorized :'). 3) Patch a common trap that gets called a lot (like GetNextEvent() or WaitNextEvent()). This will not give you any control over granularity (in fact, you may NEVER get called), so you lose there. Also, you will most certainly conflict with every other Mac program in the world which patches traps (since I understand, that is an in-vogue thing to do) and you will have a hairy time trying to support it (hint: if you make it big, you just blame compatability problems on everyone else's software, another in-vogue practice), but you can get at QuickDraw. Conclusion: Doable. It ain't easy. It's probably not fun, at least not my idea of fun. Steve Hawley hawley@adobe.com -- "Break out the cameras that reshape my face and get someone to carve up my head" -Alcatraz, "God Blessed Video"
amanda@mermaid.intercon.com (Amanda Walker) (08/11/90)
In article <82899@tut.cis.ohio-state.edu>, topping@anaconda.cis.ohio-state.edu (brian e topping) writes: > The trick is to use the low memory global jGNEFilter You can also write your code as a driver, and turn on the "needTime" bit, which will cause your driver to be called when the application calls SystemTask() or WaitNextEvent(). You don't need to patch anything, and your cdev can talk to the driver code by doing PBControl() calls. -- Amanda Walker <amanda@intercon.com> InterCon Systems Corporation -- "I've been with the best and the worst in my life, and the secret is they're all people." -- Helen Drazenovich Berklich
stevec@Apple.COM (Steve Christensen) (08/11/90)
In article <23598@dartvax.Dartmouth.EDU> Joe Francis writes: >In article <82899@tut.cis.ohio-state.edu> brian e topping writes: >->Actually, if you have ever looked inside what SuperClock, Pyro, and the like >->are doing, you will have found a safer method. I can never remember where >->I saw this documented, but it is somewhere in the phone book edition >->(the brown pages). The trick is to use the low memory global jGNEFilter, >->defined in the Apple assembler equates as: > >-> JGNEFilter EQU $29A; GetNextEvent filter proc [pointer] > >->This seems preferred over other methods because if the app isn't calling >->WaitNextEvent, it probably is too busy to have cycles eaten up by screen >->savers and the like. > >If you do this (and I don't recommend it), make sure that you call the >previous contents of the global (if they are not null), otherwise other >"lurkers" using this method will be high and dry. jGNEFilter should never be nil since there is a default filterProc installed before anyone else gets their fingers in. The other important point is to be sure to save A1 (and maybe D0) around your code since others down the chain are expecting it to be setup... steve -- ____________________________________________________________________ Steve Christensen Internet: stevec@goofy.apple.com Apple Computer, Inc. AppleLink: STEVEC 20525 Mariani Ave, MS 81-CS CompuServe: 76174,1712 Cupertino, CA 95014 "You just contradicted me." "No I didn't." ____________________________________________________________________
stevec@Apple.COM (Steve Christensen) (08/11/90)
In article <1990Aug10.175429.6092@ux1.cso.uiuc.edu> resnick@lees.cogsci.uiuc.edu (Pete Resnick) writes: >The method I have been using for getting something running in the >background is writing the code as a device driver that is in the >system heap and locked and the dNeedTime bit set. This seems much >safer than patching traps, and unlike VBL tasks (at least in THINK >C 4.0) you can have global variables floating around and call routines >that move memory. All the INIT does is call OpenDriver and exits. Two of the problems about writing the code as a driver (when it doesn't need to be) are that you tie up a space in the unit table (for code that does need to be a driver), and that there may not be an opening for it in the unit table (admittedly there usually is). Patching traps is not as terrible as you imagine as long as you take a little care in writing the code. And both trap patches and VBL tasks can have as global a variable as a driver can. Which are really private variables since the applications own the global data space... steve -- ____________________________________________________________________ Steve Christensen Internet: stevec@goofy.apple.com Apple Computer, Inc. AppleLink: STEVEC 20525 Mariani Ave, MS 81-CS CompuServe: 76174,1712 Cupertino, CA 95014 "You just contradicted me." "No I didn't." ____________________________________________________________________
carlton@draco (Mike Carlton) (08/11/90)
In article <9694@goofy.Apple.COM> stevec@Apple.COM (Steve Christensen) writes: +In article <23598@dartvax.Dartmouth.EDU> Joe Francis writes: +>In article <82899@tut.cis.ohio-state.edu> brian e topping writes: +>->Actually, if you have ever looked inside what SuperClock, Pyro, and the like +>->are doing, you will have found a safer method. I can never remember where +>->I saw this documented, but it is somewhere in the phone book edition +>->(the brown pages). The trick is to use the low memory global jGNEFilter, +>->defined in the Apple assembler equates as: +> +>-> JGNEFilter EQU $29A; GetNextEvent filter proc [pointer] +> +>->This seems preferred over other methods because if the app isn't calling +>->WaitNextEvent, it probably is too busy to have cycles eaten up by screen +>->savers and the like. +> +>If you do this (and I don't recommend it), make sure that you call the +>previous contents of the global (if they are not null), otherwise other +>"lurkers" using this method will be high and dry. + +jGNEFilter should never be nil since there is a default filterProc installed +before anyone else gets their fingers in. The other important point is to +be sure to save A1 (and maybe D0) around your code since others down the +chain are expecting it to be setup... + +steve + Is using jGNEFilter safer or more dangerous than patching GetNextEvent? I've got an init which wants to steal some events. Right now it patches GNE and searchs the event queue and removes the one it wants. I could instead use jGNEFilter and turn the event I want into a null event before it is returned. Given that both methods would work for me, which is least likely to break when new system software comes out (like, maybe 7.0 :)? Is there any preference? cheers, Mike Carlton, UC Berkeley Computer Science ~ carlton@ernie.berkeley.edu ...!ucbvax!ernie!carlton Manana
stevec@Apple.COM (Steve Christensen) (08/13/90)
In article <26932@pasteur.Berkeley.EDU> carlton@draco.berkeley.edu (Mike Carlton) writes: >In article <9694@goofy.Apple.COM> stevec@Apple.COM (Steve Christensen) writes: >+In article <23598@dartvax.Dartmouth.EDU> Joe Francis writes: >+>In article <82899@tut.cis.ohio-state.edu> brian e topping writes: >[...discussion of hooking into jGNEFilter to be called at GetNextEvent time] > >Is using jGNEFilter safer or more dangerous than patching GetNextEvent? I've >got an init which wants to steal some events. Right now it patches GNE and >searchs the event queue and removes the one it wants. I could instead >use jGNEFilter and turn the event I want into a null event before it is >returned. > >Given that both methods would work for me, which is least likely to break >when new system software comes out (like, maybe 7.0 :)? Is there any >preference? Well, I think either way would do. SuperClock! uses jGNEFilter, and 7.0 hasn't broken it yet... :-) steve -- ____________________________________________________________________ Steve Christensen Internet: stevec@goofy.apple.com Apple Computer, Inc. AppleLink: STEVEC 20525 Mariani Ave, MS 81-CS CompuServe: 76174,1712 Cupertino, CA 95014 "You just contradicted me." "No I didn't." ____________________________________________________________________