Base image, Windows look

Jim Benson jb at speed.net
Wed Sep 2 07:22:43 UTC 1998


Doug Way wrote:

> I guess my thought was that native windows (only) might be a
> reasonably
> small subset of an OS's entire native widget set which could then be
> supported in the base image/VM.  Definitely keep it simple... all
> you'd
> really need is to support two types of windows: regular application
> windows, and modal dialogs.  (These two types are present in pretty
> much
> all windowing systems.)

To support these, you have to redefine the entire Squeak event mechanish
handler. Nasty.

In the following story, I will try to point out some of the more subtle
points of native window systems in Squeak.
I develop for Macintosh, but the story extends to other platforms as
well.

SUMMARY:  External API calls are useful for calling standalone code, but

Squeak would have to reinvent itself to take advantage of native window/

widget features.

After working on sqAPI for a while, I decided it needed quite a bit of
modification for it to meet my needs.  Never being one to shy away from
some useless coding, I started to design a Macintosh DLL interface.
There were several things I wanted to accomplish:

1. Create API function calls in a more "natural" manner. The ultimate
goal being to read C language header files and create "naturally " named

methods.
2. Hide type conversion from Squeak to C and back.
3.Create native windows, widgets and get Quicktime to run.

Also, I wanted to be able to run Squeak as is, without having to
recreate each UI component. That is Boris G. Chr. Shingarov's Cheese
project. Basically, Squeak would be the same, the only difference being
native windows would appear in place of "Squeaky" windows.

The good news is, I met my personal goals. Numbers 1 and 2 are fairly
straight forward, but have subtle undercurrents not easily seen on first

glance.

For goal number 1, I created a C language parser and modified the Squeak

parser to accept API calls a little more gracefully. Currently, I parse
the header files using a separate hideous Squeak program, and write the
result to intermediate files. The intermediate files are then parsed and

read into a "MacSqueak" base image.  At the end of this affront to
computer science, you can actually make API calls. Remember, there are
approximately 3000 API calls for the Mac and several hundred typedefs
and/or structs.

As an example:

To create a new native window in C language:

WindowPtr NewCWindow ( void *wStorage, Rect *boundsRect,
ConstStr255Param title, Boolean visible, short procID, WindowPtr behind,

Boolean goAwayFlag, long refCon ) ;

becomes in "MacSqueak"

NewCWindow: wStorage boundsRect: boundsRect title: title visible:
visible procID: procID behind: behind goAwayFlag: goAwayFlag refCon:
refCon
" ==== AUTOMATICALLY GENERATED ===== 14 May 1998  11:50:29 pm"
< WindowPtr NewCWindow ( void *wStorage, Rect *boundsRect,
ConstStr255Param title, Boolean visible, short procID, WindowPtr behind,

Boolean goAwayFlag, long refCon )  >
^self primitiveFailed.

To create a "native window" :

newWindow : label contentRect: contentRect
    " label is a Squeak string, contentRect is a Squeak rectangle"
   boundRect _ MacRect from: contentRect.
   ^ self toolbox
      NewCWindow: nil
       boundsRect: boundRect
        title: label
        visible: false
        procID: 8
        behind: -1
        goAwayFlag: true
           refCon: 0.
 
 
For goal number 2, I try to type the arguments dynamically at dispatch
time. Things like Squeak "false" and "true" get converted to C language
0 and 1. In addition, there is support for Squeak Strings in this
mechanism. C language pointers and handles are returned as Squeak
"special" objects. There are several clever bits here and there, but
most of the code is pretty straightforward. Of course, values returned
from function calls are also typed.

Problems:
The first issue that comes up is how to handle "external" memory. These
are things like structs and such that cannot be moved around by the
Squeak garbage collector. In addition, access to the structs should
probably be on a field name basis,  e.g.
    bo _ MacRect malloc.
    bo left: 20 ; right: 50 ; top: 100 bottom: 200.

Because Squeak does not currently support finalization in the base
image, this makes keeping track of external structures more difficult
than it needs to be.

Currently, I keep named C language structures in a dictionary. A named
structure is basically a schema denoting field names,  placement, and
type. Sometimes it is more convenient to access a Squeak class,  so the
user may elect to manufacture a class from a named structure. C language

struct names are prefixed with 'Mac' to avoid name space collision upon
conversion. Because of the sheer number of structures, only a handful of

C language structs are converted to Squeak classes.

All of the above is manageable. I suppose a few smart folks could sort
out the syntax for primitive API calls. If you have not
fallen asleep at this point, nearly interesting stuff follows.
 
Goal number 3: Ok, windows are on the screen, so what?

And here lies my answer to external API calls. It depends. If you want
your Squeak application to run like a native program (which was the
whole
point of this little exercise for me) it means that you need to rewrite
the VM event handler, and some of the MVC stuff, and a whole lot of the
base image GUI. For my project, I rewrote the event handler in Squeak,
and modified the VM to reflect this. In other words, I lifted the event
handler out of the VM and brought it into the Squeak image. In addition,

I modified the control manager to support native windows. Unfortunately,
the Event Manager
does not span platforms well.

When I started, I knew the Mac and C language inside and out, but only a

small part of MVC. As it turns out, even though Squeak appears to have
windows and controls that work like a Mac ( Windows , Motif ... ) , the
underlying code does not support a "modern" ( or regressive if you
prefer ) event driven model. I was entertained for many hours trying to
shove integrated native windows and widgets down Squeaks throat. I
mostly succeeded, but I am not sure it is worth the effort, or the extra

system instability. In addition to OS dependent event dispatching, you
also have initialization concerns ( like when exactly do I create the
native window? ), finalization problems,  and such other fun bits as the

control managers infatuation with processes.  A modern PC OS handles
event dispatching quite differently from the underlying model of Squeak.

Of course, this is mostly due to the nature of Squeak not having the
entire machine to itself, and Squeak being its own OS.

In summary, I rewrote some Squeak guts. Now Quicktime works and Squeak
runs in separate windows. My little Inspectors and Browsers come up in
their native windows. And I have a real menu bar. However, the entire
overall feel of Squeak has not been enhanced, and it is still a long way

from providing a "shrink wrapped" solution to a particular problem.  And

the image grew  and got more complicated when  it should have been
simplified.
 

Jim Benson
 
 
  





More information about the Squeak-dev mailing list