[comp.sys.mac] Real Multifinder

truel@iuvax.cs.indiana.edu (Bob Truel) (08/15/89)

In article <1989Aug15.001507.14552@> enk@slcs.slb.com (Edan Kabatchnik) writes:
>
>     The Macintosh is not a true multitasking system from the perspective of a
>programmer, not the user: a programmer wishing to write a "multitasking"
>application under Macintosh OS must take great care to write his program
>carefully.  On a UNIX system, the programmer simply has an easier time writing
>a such a program.  The user, however, can observe the effects of multitasking
>under Macintosh OS just as easily as he can under UNIX: if the programmer who
>wrote the applications he or she is using spent the time to develop them
>properly, the user is rewarded with the benefit of multitasking.  The problem
>is that every application you use must be written properly in order for the
>whole system to multitask properly.
>
I haven't programmed much on the macintosh, and certainly have not
done any applications (didn't used to have enough memory :), so can someone
who is knowledgeable give a rough estimate as to the size of code that must
be included in every program in order to make it multifinder friendly, and 
the time it takes to produce this code (say for the first time, for a fairly
competant programmer).  Is this enough justification for apple to provide 
an inherently multiprocessing system?  People keep saying that it is the
programmer who is at fault, however it is the consumer that pays.

UNIX and its associated ideas have been around for 20 years now, I
would think that some of the better ideas could be scavenged for _The 
Complete System Rewrite_ that has been promised for 8.0.  I look at graceful
multiprogramming as just another human engineering guideline that should be
followed.  Isn't the job of any operating system and especially the Mac
toolbox to make programming easier and consistent?

It is time for the main event loop to be done away with.

Robert N. Truel			"Life sucks, of course, but it didn't have
				 to suck quite like this" -- RJSJR
truel@silver.bacs.indiana.edu
truelr@iubacs.BITNET
-- 
Robert N. Truel			"Life sucks, of course, but it didn't have
				 to suck quite like this" -- RJSJR
truel@silver.bacs.indiana.edu
truelr@iubacs.BITNET

casseres@apple.com (David Casseres) (08/15/89)

In article <24626@iuvax.cs.indiana.edu> truel@iuvax.cs.indiana.edu (Bob 
Truel) writes:
> I haven't programmed much on the macintosh, and certainly have not
> done any applications (didn't used to have enough memory :), so can 
someone
> who is knowledgeable give a rough estimate as to the size of code that 
must
> be included in every program in order to make it multifinder friendly, 
and 
> the time it takes to produce this code (say for the first time, for a 
fairly
> competant programmer).

It takes about a half-dozen lines of Pascal or C.  Reading the 
documentation might take an hour; writing the code would take half an hour 
the first time.  I'm assuming the code is being added into a competently 
written Mac application.

> UNIX and its associated ideas have been around for 20 years now, I
> would think that some of the better ideas could be scavenged for _The 
> Complete System Rewrite_ that has been promised for 8.0.

I don't think Apple has ever mentioned an 8.0 release, let alone promised 
that it would be a complete system rewrite; if I've missed something, let 
me know!

> It is time for the main event loop to be done away with.

Well, some folks think Unix should be done away with ;*).  I think that if 
you gain some experience with the Mac, you'll find that the main event 
loop is a good way to write event-driven programs, and this is central to 
implementing the Mac user interface.  There is absolutely nothing 
difficult about writing an event loop.  It is not the same thing as 
writing a program to run under Unix or DOS or VMS, but so what?

David Casseres

Exclaimer:  Hey!

enk@corona (Edan Kabatchnik) (08/17/89)

>Well, some folks think Unix should be done away with ;*).  I think that if
>you gain some experience with the Mac, you'll find that the main event
>loop is a good way to write event-driven programs, and this is central to
>implementing the Mac user interface.  There is absolutely nothing
>difficult about writing an event loop.  It is not the same thing as
>writing a program to run under Unix or DOS or VMS, but so what?

     Granted, (parts of) UNIX should be done away with.  But, there is a
superior form to the main event loop: callbacks (found in X and Xerox
Artificial Intelligence Workstations from which the Macintosh developed its
user interface.)  Instead of having to dispatch on every possible event in the
main event loop, one establishes a hook that is automatically called when an
event takes place.

	Example: when creating a menu, each item that can be selected
	in the menu is given the address of the function which should
	be called when that item is selected.

     So, the programmer does not call his menu handler explicitly; rather, it
is "magically" called by the menu code in the toolbox when the selection
occurs.  This takes away all the pains of the main event loop.  (The main event
loop is reduced to a few standard lines of code that need not dispatch on
event.)

     So much code has been written for the Macintosh which works without
callbacks, making it unlikely that future versions of the system will take
advantage of callbacks.  But, if Apple could figure out a way of making both
systems work, then future programmers would be spared a great deal of pain.






+----------------------------------------------------+-------------------------+
|There is a club if you would like to go.            |     Edan Kabatchnik     |
|You could meet somebody who really loves you.       +-------------------------+
|So you go, and you stand on your own.               |           MIT           |
|And you leave on your own.                          | enk@wheaties.ai.mit.edu |
|And you go home, and you cry, and you want to die.  |Schlumberger Technologies|
|                                   - The Smiths     |    enk@slcs.slb.com     |
+----------------------------------------------------+-------------------------+

mfi@beach.cis.ufl.edu (Mark Interrante) (08/17/89)

In article <1989Aug16.175351.24310@sj.ate.slb.com> enk@slcs.slb.com (Edan Kabatchnik) writes:
>     Granted, (parts of) UNIX should be done away with.  But, there is a
>superior form to the main event loop: callbacks (found in X and Xerox
>Artificial Intelligence Workstations from which the Macintosh developed its
>user interface.)  Instead of having to dispatch on every possible event in the
>main event loop, one establishes a hook that is automatically called when an
>event takes place.
>
>	Example: when creating a menu, each item that can be selected
>	in the menu is given the address of the function which should
>	be called when that item is selected.

This is exactly the method used in Apples CommonLISP.  The definitiion
of a menu item consists of its name and the function it calls.  I find
this a very intuitive way to implement menus and dialogboxes.  

-----------------------------------------------------------------------------
Mark Interrante   		  Software Engineering Research Center
mfi@beach.cis.ufl.edu		  CIS Department, University of Florida 32611
-----------------------------------------------------------------------------
"X is just raster-op on wheels" - Bill Joy, January 1987

pepke@loligo.cc.fsu.edu (Eric Pepke) (08/17/89)

In article <1989Aug16.175351.24310@sj.ate.slb.com> enk@slcs.slb.com (Edan Kabatchnik) writes:
>     Granted, (parts of) UNIX should be done away with.  But, there is a
>superior form to the main event loop: callbacks (found in X and Xerox
>Artificial Intelligence Workstations from which the Macintosh developed its
>user interface.)  Instead of having to dispatch on every possible event in the
>main event loop, one establishes a hook that is automatically called when an
>event takes place.

Paul DuBois' TransSkel works a bit like this.  I used it for a couple of 
projects but then abandoned it because I prefer my way of doing cursor 
changes and menu updates.

>     So much code has been written for the Macintosh which works without
>callbacks, making it unlikely that future versions of the system will take
>advantage of callbacks.  But, if Apple could figure out a way of making both
>systems work, then future programmers would be spared a great deal of pain.

Do you really think so?  Sure, it took me a couple of weeks to figure out
how to design a main loop, but that was four years ago, and I only had
to do it once.  I had to make small changes for MultiFinder, but they had
more to do with keeping the clipboard clean than anything else.  Getting
a new main loop running from an old one now only takes me about 30 minutes
and is by far the least of my worries.  Compared to the task of designing
the interface, it is a triviality.

Having said that, I should also say that the Macintosh needs preemptive
multitasking.  It won't really affect my life very much--my Mac programs
tend to have a very similar structure to my IRIS programs--but it will
affect a lot of people.  Specifically, there are a lot of people who need
to use the Macintosh as a computer, as well as an "information appliance."
Many of them are not interested in analyzing and rethinking the algorithms
of 50,000-line FORTRAN numerical codes handed down from generation to 
generation, but they want to be able to run them in the background. In
many environments, such as the one in which I work, this is a major 
criterion for deciding which machine to buy.

Of course, the Apple folks tend not to think of themselves as competing
with so-called "workstations."  Then again, they have many tens of
thousands of bucks from us, at least, because Macintoshes are to some
degree competitive with workstations, regardless of what the marketing
types say.  If Apple have any sense, they will want people who can get
$30,000 grants to be their friends.

Eric Pepke                                     INTERNET: pepke@gw.scri.fsu.edu
Supercomputer Computations Research Institute  MFENET:   pepke@fsu
Florida State University                       SPAN:     scri::pepke
Tallahassee, FL 32306-4052                     BITNET:   pepke@fsu

Disclaimer: My employers seldom even LISTEN to my opinions.
Meta-disclaimer: Any society that needs disclaimers has too many lawyers.

sdh@wind.bellcore.com (Stephen D Hawley) (08/17/89)

In article <1989Aug16.175351.24310@sj.ate.slb.com> enk@slcs.slb.com (Edan Kabatchnik) writes:
>     Granted, (parts of) UNIX should be done away with.  But, there is a
>superior form to the main event loop: callbacks (found in X and Xerox
>Artificial Intelligence Workstations from which the Macintosh developed its
>user interface.)  Instead of having to dispatch on every possible event in the
>main event loop, one establishes a hook that is automatically called when an
>event takes place.

Yes, and no.  Callbacks are not superior, they are only different.  Keep in
mind that you have to do one of 2 things:
	1) make hooks for every possible call back routine in every
	  combination.  Set up all these vectors (in pascal, this will be
	  particularly painful without an initialized static data type),
	  and then go.
--or--
	2) Make a well thought out set of call back functions that are
	  grouped by types (like window events, controls, etc) and force
	  the call back routines to check a parameter for an action to be
	  taken.

The first is painful at best, the second is exactly the same as the event
loop.  The only difference is that you have taken the dispatcher away from
the user and put it somewhere else.  Think about it, when an event happens,
it would have to be sent through a function that picks a function pointer
from a vector of call back routines and executes it.  This is exactly
equivalent to having the all-too famous:
		switch(myEvent.what) {
		case ...
		}
Each case corresponds to a component of the vector of call back routines.

I do not think that either is superior at this level, only different.

Consider the following code:

#define N_EVENTS 16 /* from inside mac */
#define EVER (;;)
extern int no_op();
typedef int (*FUNCPTR)();
static FUNCPTR vector[N_EVENTS] = {
	no_op, no_op, no_op, no_op, no_op, no_op, no_op, no_op,
	no_op, no_op, no_op, no_op, no_op, no_op, no_op, no_op
};

int
no_op(evt)
eventRecord *evt;
{
	/* should a no_op return anything? */
	return(0);
}

SetEventCallBack(evt, func)
int evt;
FUNCPTR func;
{
	vector[evt] = func; /* record new callback */
}

FUNCPTR
GetEventCallBack(evt)
int evt;
{
	return(vector[evt]); /* return old callback */
}

SetNullEvent(evt)
int evt;
{
	SetEvent(evt, no_op); /* set a no_op */
}

DoEvents()
{
	EventRecord evt;

	 for EVER {
		/* infinite loop is no problem,
		 * just leave the program with a call to
		 * ExitToShell().
		 */
		if (GetNextEvent(everyEvent, &evt)) {
		/*
		 * Since the evnt codes go from 0-15, use
		 * that as an index into the vector, and
		 * execute.
		 */
			(*(vector[evt.what]))(&evt);
			/*
			 * pass in the event so the callback knows
			 * what happened.
			 */
		}
	}
}

Ok.  Now you have code to do all you events will callbacks.  There is
NO significant difference.  All you're doing is factoring out the switch
statement, and forcing yourself to write all the code to do calls to
SetCallBack() and GetCallBack().  The work isn't reduced, its just changed.

Steve Hawley
sdh@flash.bellcore.com
"Up is where you hang your hat."
	--Jim Blandy, computer scientist

bayes@hpislx.HP.COM (Scott Bayes) (08/17/89)

>      So much code has been written for the Macintosh which works without
> callbacks, making it unlikely that future versions of the system will take
> advantage of callbacks.  But, if Apple could figure out a way of making both
> systems work, then future programmers would be spared a great deal of pain.
> 

One way to achieve this (callback with main event loop compatibility)
may be to provide the callback with a boolean return variable, with some
name like "continue".  The callback gets first crack at the event, with
the system running its own "main event loop".  The system sets continue
to TRUE and calls the callback for the event.  If the callback wants to
handle it, it sets continue to FALSE, processes the event and returns.
In odd circumstances (such as remapping a key or mouseclick), it may
process the event, but leave continue TRUE.  If continue is TRUE on
return from the callback, the event stays in the queue, and is seen by
old application main event loop code, thus maintaining compatibility.

At bootup, the system installs dummy routines in all callbacks.  The
dummies' only jobs are to return, leaving continue TRUE, ensuring that
code that doesn't install callbacks runs in main event loop mode.  The
dummies are replaced by new applications (or INITs, whatever) that want
to use callbacks through a system procedure call, and are restored by
the system when the callback is removed, again by a system procedure; no
global access allowed here!

(This maps fairly well onto the operations used in the OS I worked on
for >5 years, in which _everything_ is hooked together in this fashion.)

Scott Bayes
for a good time, call back!

>+----------------------------------------------------+-------------------------+
>|There is a club if you would like to go.            |     Edan Kabatchnik     |
>|You could meet somebody who really loves you.       +-------------------------+
>|So you go, and you stand on your own.               |           MIT           |
>|And you leave on your own.                          | enk@wheaties.ai.mit.edu |
> |And you go home, and you cry, and you want to die.  |Schlumberger Technologies|
>|                                   - The Smiths     |    enk@slcs.slb.com     |
>+----------------------------------------------------+-------------------------+
----------

t-stevep@microsoft.UUCP (Steve Pool) (08/18/89)

In article <1989Aug16.175351.24310@sj.ate.slb.com> enk@slcs.slb.com (Edan Kabatchnik) writes:
>     Granted, (parts of) UNIX should be done away with.  But, there is a
>superior form to the main event loop: callbacks (found in X and Xerox
>Artificial Intelligence Workstations from which the Macintosh developed its
>user interface.)  Instead of having to dispatch on every possible event in the
>main event loop, one establishes a hook that is automatically called when an
>event takes place.

This is how the Presentation Manager handles events (messages, in
PMSpeek), and it makes dealing with the event driven model much
cleaner, in my opinion.  Dispatching becomes a matter of merely
writing your message handling functions, marking them as being
exported so that they can be called from the PM DLLs, and then
forgetting about them.

I really think it's time for the Mac programming model to be updated.
That's probably unreasonable, considering the amount of code that would
undoubtedly cease functioning, but it would sure make me happy!

) (08/18/89)

In article <7420@microsoft.UUCP> t-stevep@microsoft.UUCP (Steve Pool) writes:
>I really think it's time for the Mac programming model to be updated.
>That's probably unreasonable, considering the amount of code that would
>undoubtedly cease functioning, but it would sure make me happy!

Of course not! Already working code has no reason to break even if
we change the future development system. You'll just have a skeleton
ready, where you put in your (pointers to) functions. I thought
that MacApp already did this. I could be wrong, I haven't used it.

Anyway, it's a piece of cake to write a "universal" dispatcher module
and compile it as a library to link with your other code. Then you
could either
a) have special names for your target routines (i.e. doMenu)
b) use a struct that's set up in the initialization and that contains
   pointers to all of your routines. (Better still, handles to them.
   Be sure to lock the segments that your routines are in, since things
   will be weird otherwise !)

Since Apple now wants us to use OOP, thing should get still easier.
MicroSoft may try to do things right, but in my opinion, they haven't
really gotten that far yet.

Have a nice day!

h+@nada.kth.se

-- 
This is your fortune from h+@nada.kth.se:
Xerox does it again and again and again and...

lsr@Apple.COM (Larry Rosenstein) (09/01/89)

In article <1428@draken.nada.kth.se> d88-jwa@nada.kth.se (All this was 
brought to you by h+@nada.kth.se  Replys via email welcome!) writes:
> In article <7420@microsoft.UUCP> t-stevep@microsoft.UUCP (Steve Pool) 
writes:
> >I really think it's time for the Mac programming model to be updated.
> >That's probably unreasonable, considering the amount of code that would
> >undoubtedly cease functioning, but it would sure make me happy!
> 
> Of course not! Already working code has no reason to break even if
> we change the future development system. You'll just have a skeleton
> ready, where you put in your (pointers to) functions. I thought
> that MacApp already did this. I could be wrong, I haven't used it.

There are 2 issues.  One is changing the development system.  For example, 
MacApp makes a radical change to the programming model, but it is layered 
on top of the standard ROM calls.  

The other issues is changing the fundamental set of ROM calls.  This 
happens incrementally, as new features are added.  The difficulty in 
adding new features is ensuring compatibility, and sometimes compatibility 
issues affect the design.  I think Steve Pool was advocating a fresh start 
at designing the system without worrying about compatibility.

Larry Rosenstein, Apple Computer, Inc.
Object Specialist

Internet: lsr@Apple.com   UUCP: {nsc, sun}!apple!lsr
AppleLink: Rosenstein1

lsr@Apple.COM (Larry Rosenstein) (09/01/89)

In article <1989Aug16.175351.24310@sj.ate.slb.com> enk@corona (Edan 
Kabatchnik) writes:
>      Granted, (parts of) UNIX should be done away with.  But, there is a
> superior form to the main event loop: callbacks (found in X and Xerox

I agree in general with your approach.  A cleaner way to get the same 
affect, however, is to use an object-oriented language, and develop an 
application framework such as MacApp.  Callbacks are just a hack to 
implement the same thing without special language constructs.

The advantage of using an OO language, however, is that is much more 
natural to define methods than to specify call backs.  It is easy to 
override a method and still execute the original version, which is not as 
straightforward using call backs.  

I also think that because defining new call backs is more tedious (in 
terms of bookkeeping and initialization) that there would be a tendency to 
define only high-level call backs (eg, menu-item-chosen).  In MacApp, for 
example, there are several menu handling methods, which gives the 
developer more flexibility.

>      So much code has been written for the Macintosh which works without
> callbacks, making it unlikely that future versions of the system will 
take
> advantage of callbacks.  But, if Apple could figure out a way of making 
both
> systems work, then future programmers would be spared a great deal of 
pain.

It probably wouldn't be hard to add some kind of call backs (there are 
some already for dialogs, for example).   If a call back is installed then 
the system would take action otherwise it would do the current thing.  
Since Apple is already using OO languages, I doubt that you would see 
wide-scale use of call backs.

On the other hand, there are packages built on top of the existing ROM 
which achieve the same results.  MacApp is one that uses an OO language, 
but MacExpress is one that works with standard languages and uses call 
backs as you suggested.

Larry Rosenstein, Apple Computer, Inc.
Object Specialist

Internet: lsr@Apple.com   UUCP: {nsc, sun}!apple!lsr
AppleLink: Rosenstein1

lsr@Apple.COM (Larry Rosenstein) (09/01/89)

In article <24626@iuvax.cs.indiana.edu> truel@iuvax.cs.indiana.edu (Bob 
Truel) writes:
> done any applications (didn't used to have enough memory :), so can 
someone
> who is knowledgeable give a rough estimate as to the size of code that 
must
> be included in every program in order to make it multifinder friendly, 
and 
> the time it takes to produce this code (say for the first time, for a 
fairly
> competant programmer). 

It is possible to work under MultiFinder without writing any extra code, 
although by writing some MultiFinder-specific code you can make the system 
operate more smoothly.

For most applications, the number of lines would be on the order of 50, 
and the lines are pretty well standardized.  One needs to use 
WaitNextEvent (when available) and respond to suspend/resume events  
(export the private clipboard and deactivate your window).

At the next level of complexity you have programs that use a lot of 
temporary memory, which could then take advantage of the MultiFinder 
temporary memory calls.  

Or you have programs that want to do a lengthy calculation in the 
background.  In that case you need some code to process events while you 
are doing the calculation.  If you have structured your application 
appropriately, then it shouldn't be very many lines of code.  You do have 
to locate the appropriate places in your algorithms for checking for 
events, etc.

>Is this enough justification for apple to provide an inherently 
multiprocessing system?

Of course.  The issue is supporting the existing application base.  In the 
case of MultiFinder, the question was whether it was better for customers 
to provide non-preemptive task scheduling, which could accomodate existing 
applications, or to provide a system that supported premptive multitasking 
but that required most or all applications to be rewritten.  With 
MultiFinder, users get much of the benefits of multitasking, although it 
puts more burden on developers.

> It is time for the main event loop to be done away with.

I don't think the event loop is the issue.  An event loop is pretty 
essential for any kind of highly interactive application.  The way to make 
things easier for the programmer is to provide an application framework 
that implements the standard event loop once and for all, so programmers 
can concentrate on what they really want to implement.

Larry Rosenstein, Apple Computer, Inc.
Object Specialist

Internet: lsr@Apple.com   UUCP: {nsc, sun}!apple!lsr
AppleLink: Rosenstein1

leipold@eplrx7.UUCP (leipold) (09/01/89)

In article <3997@internal.Apple.COM> Larry Rosenstein writes:
>It is possible to work under MultiFinder without writing any extra code, 
>although by writing some MultiFinder-specific code you can make the system 
>operate more smoothly.

I've been watching this thread for a week or so, and have to disagree
(partially) with the above.  The original question appeared to refer to
the amount of extra code you'd need to add to a Unix-style program
(which gets backgrounding for free) to get it running in the background
on the Mac.  This is not just a matter of adding some Multifinder-
specific code.  Instead, you have to add an entire event loop to the
program to allow Multifinder to timeslice it.  And quite often, a
program's original (hopefully) clean structure (the case for most
Unix filters) is badly corrupted by contorting it to fit an event loop.

Of course, you could argue that Unix-style filter programs don't fit
the Mac's user interface model, and that their use should therefore be
discouraged (or even made a punishable offense).  However, there are a
_lot_ of good Unix programs.  I'd like to be able to use them "out of
the box" on my Mac.  And some tasks (that I'd probably like to run in
the background anyway) are more efficiently handled with the Unix 'user
interface standard' of filters and pipes, especially when enhanced by
shell scripts and filename wildcards.

-- 
"As long as you've lit one candle,                         Walt Leipold
you're allowed to curse the darkness."       (leipolw%esvax@dupont.com)
--

lsr@Apple.COM (Larry Rosenstein) (09/02/89)

In article <738@eplrx7.UUCP> leipold@eplrx7.UUCP (leipold) writes:
> I've been watching this thread for a week or so, and have to disagree
> (partially) with the above.  The original question appeared to refer to
> the amount of extra code you'd need to add to a Unix-style program
> (which gets backgrounding for free) to get it running in the background

As I said in my message, you have you have to do more work to write a 
program that does a computation in the background under MultiFinder.  For 
the typical Macintosh application, however, the work necessary to get it 
to run smoothly under MultiFinder is small.

If you are talking about a UNIX-style tool (eg, grep), then you need to 
provide a mechanism for handling the command line arguments to the tool.  
In the normal Macintosh environment, this means writing code to collect 
the parameters in a dialog box.  You will have to write some extra code to 
run in the background (including and event loop), but it won't destroy the 
structure of the tool.

It is pretty trivial to get a UNIX tool to run under MPW.  (I suspect this 
also applies to development environments besides MPW.)  You don't need an 
event loop at all.  To run in the background, all you need to do is yield 
the CPU periodially; MPW will take care of the rest.

> _lot_ of good Unix programs.  I'd like to be able to use them "out of
> the box" on my Mac.  And some tasks (that I'd probably like to run in
> the background anyway) are more efficiently handled with the Unix 'user
> interface standard' of filters and pipes, especially when enhanced by
> shell scripts and filename wildcards.

MPW is the ideal environment for this kind of work.

Larry Rosenstein, Apple Computer, Inc.
Object Specialist

Internet: lsr@Apple.com   UUCP: {nsc, sun}!apple!lsr
AppleLink: Rosenstein1

peirce@claris.com (Michael Peirce) (09/02/89)

In article <738@eplrx7.UUCP> leipold@eplrx7.UUCP (Walt Leipold) writes:
>In article <3997@internal.Apple.COM> Larry Rosenstein writes:
>>It is possible to work under MultiFinder without writing any extra code, 
>>although by writing some MultiFinder-specific code you can make the system 
>>operate more smoothly.
>
>I've been watching this thread for a week or so, and have to disagree
>(partially) with the above.  The original question appeared to refer to
>the amount of extra code you'd need to add to a Unix-style program
>(which gets backgrounding for free) to get it running in the background
>on the Mac.  This is not just a matter of adding some Multifinder-
>specific code.  Instead, you have to add an entire event loop to the
>program to allow Multifinder to timeslice it.  And quite often, a
>program's original (hopefully) clean structure (the case for most
>Unix filters) is badly corrupted by contorting it to fit an event loop.
>
>-- 
>"As long as you've lit one candle,                         Walt Leipold
>you're allowed to curse the darkness."       (leipolw%esvax@dupont.com)
>--

If you really wanted to port a Unix style filter program to the Mac the 
easiest way to do so is to make it into a MPW tool.  These programs can
use simple printf and getch style i/o without change.  And to get these
to work with MultiFinder is trivial.  Simply sprinkly a few calls to SpinCursor
in places where lots of processing is taking place and you're all set. 

This approach doesn't lead to "badly corrupted" code with event loops, just
a few extra calls that can be #IFDEF'ed in.  

Porting Unix tools to the Finder environment is probably a waste of time, the
two environments have too different a view on how the world looks.  But 
porting Unix tools to the MPW environment can be quite easy and rewarding.

Claris Corp. | Michael R. Peirce
-------------+--------------------------------------
             | 5201 Patrick Henry Drive MS-C4
             | Box 58168
             | Santa Clara, CA 95051-8168
             | (408) 987-7319
             | AppleLink: peirce1
             | Internet:  peirce@claris.com
             | uucp:      {ames,decwrl,apple,sun}!claris!peirce