]> granicus.if.org Git - nethack/commitdiff
Mac Carbon updates
authorkmhugo <kmhugo>
Wed, 10 Dec 2003 19:36:49 +0000 (19:36 +0000)
committerkmhugo <kmhugo>
Wed, 10 Dec 2003 19:36:49 +0000 (19:36 +0000)
src/allmain.c
sys/mac/macfile.c
sys/mac/macmain.c
sys/mac/macwin.c

index d5f329a156d4f99d48413a6206c1485140406ddc..c0183612b5f62290efbee0320b184d56677ef5a8 100644 (file)
@@ -456,14 +456,12 @@ display_gamewindows()
     WIN_INVEN = create_nhwindow(NHW_MENU);
 
 #ifdef MAC
-    /*
-     * This _is_ the right place for this - maybe we will
+    /* This _is_ the right place for this - maybe we will
      * have to split display_gamewindows into create_gamewindows
      * and show_gamewindows to get rid of this ifdef...
      */
-       if ( ! strcmp ( windowprocs . name , "mac" ) ) {
-           SanePositions ( ) ;
-       }
+       if (!strcmp(windowprocs. name, "mac"))
+           SanePositions();
 #endif
 
     /*
index 535bf60532eb2c9b33d45337331d6c0c491382a2..3009e9c269064c70ed8adfe0d7b828b431f713b8 100644 (file)
@@ -219,7 +219,7 @@ macopen (const char *name, int flags, long fileType)
                        TEXT_CREATOR, fileType) && (flags & O_EXCL)) {
                        return -1;
                }
-
+#if 0  /* Fails during makedefs */
                if (fileType == SAVE_TYPE) {
                        short resRef;
                        HCreateResFile(theDirs.dataRefNum, theDirs.dataDirID, s);
@@ -246,6 +246,7 @@ macopen (const char *name, int flags, long fileType)
                                CloseResFile(resRef);
                        }
                }
+#endif
 
        }
        /*
index 670283a43f438cbcb66824fee92879c5cbd10172..1c1266ee32a0e41b53b5ed89b2ded95c99b00cc4 100644 (file)
@@ -135,7 +135,7 @@ main (void)
 
        if (discover)
                You("are in non-scoring discovery mode.");
-       flags.move = 0;
+       context.move = 0;
 
        UndimMenuBar (); /* Yes, this is the place for it (!) */
        
index 27845db68bcc3762a7a052a2d088ab05aba48bda..cea2a96d6b0a79620f54d8de3319f2408ca3e279 100644 (file)
@@ -2,6 +2,11 @@
 /* Copyright (c) Jon W{tte, Hao-Yang Wang, Jonathan Handler 1992. */
 /* NetHack may be freely redistributed.  See license for details. */
 
+
+/**********************************************************************
+ *     Imported variables and functions
+ */
+
 #include "hack.h"
 #include "func_tab.h"
 #include "macwin.h"
 #include <ControlDefinitions.h>
 #endif
 
+
+
+/**********************************************************************
+ *     Local variables and functions
+ */
+
+#if TARGET_API_MAC_CARBON
+static EventTypeSpec baseevents[] = {
+       { kEventClassKeyboard, kEventRawKeyDown },
+       { kEventClassKeyboard, kEventRawKeyRepeat },
+       { kEventClassMouse, kEventMouseMoved },
+       { kEventClassWindow, kEventWindowDrawContent },
+       { kEventClassWindow, kEventWindowHandleContentClick },
+       { kEventClassWindow, kEventWindowClose }
+};
+
+static EventTypeSpec msgevents[] = {
+       { kEventClassControl, kEventControlHit },
+       { kEventClassKeyboard, kEventRawKeyDown },
+       { kEventClassKeyboard, kEventRawKeyRepeat },
+       { kEventClassWindow, kEventWindowDrawContent },
+       { kEventClassWindow, kEventWindowHandleContentClick },
+       { kEventClassWindow, kEventWindowClose }
+};
+
+static EventTypeSpec menwevents[] = {
+       { kEventClassControl, kEventControlHit },
+       { kEventClassKeyboard, kEventRawKeyDown },
+       { kEventClassKeyboard, kEventRawKeyRepeat },
+       { kEventClassWindow, kEventWindowDrawContent },
+       { kEventClassWindow, kEventWindowHandleContentClick },
+       { kEventClassWindow, kEventWindowClose }
+};
+
+static EventTypeSpec textevents[] = {
+       { kEventClassControl, kEventControlHit },
+       { kEventClassKeyboard, kEventRawKeyDown },
+       { kEventClassKeyboard, kEventRawKeyRepeat },
+       { kEventClassWindow, kEventWindowDrawContent },
+       { kEventClassWindow, kEventWindowClose }
+};
+
+static EventTypeSpec globalevents[] = {
+       { kEventClassCommand, kEventCommandProcess }
+};
+
+EventTargetRef dispatcher;
+EventHandlerUPP baseupp, msgupp, menwupp, textupp;
+
+static pascal OSStatus BaseEvent(EventHandlerCallRef, EventRef, void *);
+static void            MsgUpdate(NhWindow *wind);
+static pascal OSStatus MsgEvent(EventHandlerCallRef, EventRef, void *);
+static void            MenwUpdate(NhWindow *wind);
+static pascal OSStatus MenwEvent(EventHandlerCallRef, EventRef, void *);
+static void            TextUpdate(NhWindow *wind);
+static pascal OSStatus TextEvent(EventHandlerCallRef, EventRef, void *);
+static pascal OSStatus GlobalEvent(EventHandlerCallRef, EventRef, void *);
+
+#else
+
+static void FDECL(GeneralKey, (EventRecord *, WindowPtr));
+static void FDECL(macKeyMenu, (EventRecord *, WindowPtr));
+static void FDECL(macKeyText, (EventRecord *, WindowPtr));
+
+static void FDECL(macClickMessage, (EventRecord *, WindowPtr));
+static void FDECL(macClickTerm, (EventRecord *, WindowPtr));
+static void FDECL(macClickMenu, (EventRecord *, WindowPtr));
+static void FDECL(macClickText, (EventRecord *, WindowPtr));
+
+static short FDECL(macDoNull, (EventRecord *, WindowPtr));
+static short FDECL(macUpdateMessage, (EventRecord *, WindowPtr));
+static short FDECL(macUpdateMenu, (EventRecord *, WindowPtr));
+static short FDECL(GeneralUpdate, (EventRecord *, WindowPtr));
+
+static void FDECL(macCursorTerm, (EventRecord *, WindowPtr, RgnHandle));
+static void FDECL(GeneralCursor, (EventRecord *, WindowPtr, RgnHandle));
+#endif
+
+static void TextUpdate(NhWindow *wind);
+
+
 NhWindow *theWindows = (NhWindow *) 0;
 Cursor qdarrow;
 
@@ -138,26 +224,11 @@ Boolean small_screen = 0;
 
 static int FDECL(filter_scroll_key,(const int, NhWindow *));
 
-static void FDECL(GeneralKey, (EventRecord *, WindowPtr));
-static void FDECL(macKeyMenu, (EventRecord *, WindowPtr));
-static void FDECL(macKeyText, (EventRecord *, WindowPtr));
-
-static void FDECL(macClickMessage, (EventRecord *, WindowPtr));
-static void FDECL(macClickTerm, (EventRecord *, WindowPtr));
-static void FDECL(macClickMenu, (EventRecord *, WindowPtr));
-static void FDECL(macClickText, (EventRecord *, WindowPtr));
-
-static short FDECL(macDoNull, (EventRecord *, WindowPtr));
-static short FDECL(macUpdateMessage, (EventRecord *, WindowPtr));
-static short FDECL(macUpdateMenu, (EventRecord *, WindowPtr));
-static short FDECL(GeneralUpdate, (EventRecord *, WindowPtr));
-
-static void FDECL(macCursorTerm, (EventRecord *, WindowPtr, RgnHandle));
-static void FDECL(GeneralCursor, (EventRecord *, WindowPtr, RgnHandle));
 
 static void FDECL(DoScrollBar,(Point, short, ControlHandle, NhWindow *));
 static pascal void FDECL(MoveScrollBar, (ControlHandle, short));
 
+#if !TARGET_API_MAC_CARBON
 typedef void (*CbFunc) (EventRecord *, WindowPtr);
 typedef short (*CbUpFunc) (EventRecord *, WindowPtr);
 typedef void (*CbCursFunc) (EventRecord *, WindowPtr, RgnHandle);
@@ -181,6 +252,7 @@ static const CbCursFunc winCursorFuncs [NUM_FUNCS] = {
        (CbCursFunc) macDoNull, GeneralCursor, macCursorTerm, macCursorTerm,
        GeneralCursor, GeneralCursor
 };
+#endif
 
 
 static NhWindow *
@@ -338,20 +410,20 @@ InitMac(void) {
        gMouseRgn = NewRgn ();
        InitCursor();
        GetQDGlobalsArrow(&qdarrow);
-       ObscureCursor ();
-       
+       ObscureCursor();
+
        MoveScrollUPP = NewControlActionUPP(MoveScrollBar);
 
        /* Set up base fonts for all window types */
-       GetFNum ("\pHackFont", &i);
+       GetFNum("\pHackFont", &i);
        if (i == 0)
                i = kFontIDMonaco;
        win_fonts [NHW_BASE] = win_fonts [NHW_MAP] = win_fonts [NHW_STATUS] = i;
-       GetFNum ("\pPSHackFont", &i);
+       GetFNum("\pPSHackFont", &i);
        if (i == 0)
                i = kFontIDGeneva;
-       win_fonts [NHW_MESSAGE] = i;
-       win_fonts [NHW_TEXT] = kFontIDGeneva;
+       win_fonts[NHW_MESSAGE] = i;
+       win_fonts[NHW_TEXT] = kFontIDGeneva;
 
        macFlags.hasAE = 0;
        if(!Gestalt(gestaltAppleEventsAttr, &l) && (l & (1L << gestaltAppleEventsPresent))){
@@ -389,6 +461,17 @@ InitMac(void) {
 
        /* Create the "record" file, if necessary */
        check_recordfile("");
+
+#if TARGET_API_MAC_CARBON
+       /* Create event handler universal procedure pointers */
+       dispatcher = GetEventDispatcherTarget();
+       baseupp = NewEventHandlerUPP(BaseEvent);
+       msgupp = NewEventHandlerUPP(MsgEvent);
+       menwupp = NewEventHandlerUPP(MenwEvent);
+       textupp = NewEventHandlerUPP(TextEvent);
+       InstallApplicationEventHandler(NewEventHandlerUPP(GlobalEvent),
+               sizeof(globalevents)/sizeof(EventTypeSpec), globalevents, NULL, NULL);
+#endif
        return;
 }
 
@@ -482,8 +565,22 @@ int
 SanePositions (void)
 {
 #if TARGET_API_MAC_CARBON
+       Rect rbase, rmsg;
+       UInt16 height;
+
+
        ConstrainWindowToScreen(_mt_window, kWindowStructureRgn,
                kWindowConstrainMoveRegardlessOfFit, NULL, NULL);
+       GetWindowBounds(_mt_window, kWindowStructureRgn, &rbase);
+       GetWindowBounds(theWindows[NHW_MESSAGE].its_window, kWindowStructureRgn, &rmsg);
+       height = rmsg.bottom - rmsg.top;
+       rmsg.top = rbase.bottom+2;
+       rmsg.bottom = rmsg.top + height;
+       rmsg.left = rbase.left;
+       rmsg.right = rbase.right;
+       SetWindowBounds(theWindows[NHW_MESSAGE].its_window, kWindowStructureRgn, &rmsg);
+       ConstrainWindowToScreen(theWindows[NHW_MESSAGE].its_window, kWindowStructureRgn,
+               kWindowConstrainMoveRegardlessOfFit, NULL, NULL);
 #else
        short left, top, width, height;
        int ix, numText = 0, numMenu = 0;
@@ -572,6 +669,47 @@ SanePositions (void)
 }
 
 
+void
+mac_init_nhwindows (int *argcp, char **argv)
+{
+#if !TARGET_API_MAC_CARBON
+       Rect r, scr = (*GetGrayRgn())->rgnBBox;
+       small_screen = scr.bottom - scr.top <= (iflags.large_font ? 12*40 : 9*40);
+#endif
+
+
+       InitMenuRes();
+
+       theWindows = (NhWindow *) NewPtrClear (NUM_MACWINDOWS * sizeof (NhWindow));
+       if (MemError())
+               error("mac_init_nhwindows: Couldn't allocate memory for windows.");
+
+       DimMenuBar();
+
+       tty_init_nhwindows(argcp, argv);
+       iflags.window_inited = TRUE;
+
+       /* Some ugly hacks to make both interfaces happy:
+        * Mac port uses both tty interface (for main map) and extra windows.  The winids need to
+        * be kept in synch for both interfaces to map.  Also, the "blocked" display_nhwindow case
+        * for the map automatically calls the tty interface for the message box, so some version
+        * of the message box has to exist in the tty world to prevent a meltdown, even though most
+        * messages are handled in mac window.
+        */
+       mac_create_nhwindow(NHW_BASE);
+       tty_create_nhwindow(NHW_MESSAGE);
+
+#if !TARGET_API_MAC_CARBON
+       /* Resize and reposition the message window */
+       RetrievePosition(kMessageWindow, &r.top, &r.left);
+       RetrieveSize(kMessageWindow, r.top, r.left, &r.bottom, &r.right);
+       MoveWindow(theWindows[NHW_MESSAGE].its_window, r.left, r.top, false);
+       SizeWindow(theWindows[NHW_MESSAGE].its_window, r.right, r.bottom, true);
+#endif
+       return;
+}
+
+
 winid
 mac_create_nhwindow (int kind) {
        int i;
@@ -627,6 +765,11 @@ got1 :
                get_tty_metrics(aWin->its_window, &x_sz, &y_sz, &x_sz_p, &y_sz_p,
                                         &aWin->font_number, &aWin->font_size,
                                         &aWin->char_width, &aWin->row_height);
+#if TARGET_API_MAC_CARBON
+               InstallWindowEventHandler(aWin->its_window, baseupp,
+                       sizeof(baseevents)/sizeof(EventTypeSpec), baseevents,
+                       (void *)aWin, NULL);
+#endif
                return i;
        }
 
@@ -643,6 +786,25 @@ got1 :
        aWin->x_curs = aWin->y_curs = 0;
        aWin->drawn = TRUE;
        mac_clear_nhwindow (i);
+#if TARGET_API_MAC_CARBON
+       switch (kind) {
+       case NHW_MESSAGE:
+               InstallWindowEventHandler(aWin->its_window, msgupp,
+                       sizeof(msgevents)/sizeof(EventTypeSpec), msgevents,
+                       (void *)aWin, NULL);
+               break;
+       case NHW_MENU:
+               InstallWindowEventHandler(aWin->its_window, menwupp,
+                       sizeof(menwevents)/sizeof(EventTypeSpec), menwevents,
+                       (void *)aWin, NULL);
+               break;
+       case NHW_TEXT:
+               InstallWindowEventHandler(aWin->its_window, textupp,
+                       sizeof(textevents)/sizeof(EventTypeSpec), textevents,
+                       (void *)aWin, NULL);
+               break;
+       }
+#endif
 
        SetPortWindowPort(aWin->its_window);
 
@@ -680,53 +842,14 @@ got1 :
                r.left = r.right - SBARWIDTH;
                r.bottom -= (r.top + SBARHEIGHT);
                r.top = -1;
-               aWin->scrollBar = NewControl (aWin->its_window, &r, "\p", (r.bottom > r.top + 50), 0, 0, 0, 16, 0L);
+               aWin->scrollBar = NewControl(aWin->its_window, &r, "\p", (r.bottom > r.top + 50),
+                       0, 0, 0, 16, 0L);
                aWin->scrollPos = 0;
        }
        return i;
 }
 
 
-void
-mac_init_nhwindows (int *argcp, char **argv)
-{
-#if !TARGET_API_MAC_CARBON
-       Rect scr = (*GetGrayRgn())->rgnBBox;
-       small_screen = scr.bottom - scr.top <= (iflags.large_font ? 12*40 : 9*40);
-#endif
-       Rect r;
-
-
-       InitMenuRes ();
-
-       theWindows = (NhWindow *) NewPtrClear (NUM_MACWINDOWS * sizeof (NhWindow));
-       if (MemError())
-               error("mac_init_nhwindows: Couldn't allocate memory for windows.");
-
-       DimMenuBar ();
-
-       tty_init_nhwindows(argcp, argv);
-       iflags.window_inited = TRUE;
-
-       /* Some ugly hacks to make both interfaces happy:
-        * Mac port uses both tty interface (for main map) and extra windows.  The winids need to
-        * be kept in synch for both interfaces to map.  Also, the "blocked" display_nhwindow case
-        * for the map automatically calls the tty interface for the message box, so some version
-        * of the message box has to exist in the tty world to prevent a meltdown, even though most
-        * messages are handled in mac window.
-        */
-       mac_create_nhwindow(NHW_BASE);
-       tty_create_nhwindow(NHW_MESSAGE);
-       RetrievePosition(kMessageWindow, &r.top, &r.left);
-       RetrieveSize(kMessageWindow, r.top, r.left, &r.bottom, &r.right);
-       MoveWindow(theWindows[NHW_MESSAGE].its_window, r.left, r.top, false);
-       SizeWindow(theWindows[NHW_MESSAGE].its_window, r.right, r.bottom, true);
-       ConstrainWindowToScreen(theWindows[NHW_MESSAGE].its_window, kWindowStructureRgn,
-               kWindowConstrainMoveRegardlessOfFit, NULL, NULL);
-       return;
-}
-
-
 void
 mac_clear_nhwindow (winid win) {
        long l;
@@ -1110,9 +1233,9 @@ adjust_window_pos(NhWindow *aWin, short width, short height)
        if (pos.h + width + win_ind.right > scr_r.right)
                pos.h = scr_r.right      - width - win_ind.right;
        MoveWindow(theWindow, pos.h, pos.v, false);
-       if (aWin->scrollBar)    
-               DrawScrollbar (aWin);
 #endif
+       if (aWin->scrollBar)    
+               DrawScrollbar(aWin);
        return;
 }
 
@@ -1257,22 +1380,6 @@ trans_num_keys(EventRecord *theEvent) {
 }
 
 
-/*
- * Note; theWindow may very well be null here, since keyDown may call
- * it when theres no window !!!
- */
-static void
-GeneralKey (EventRecord *theEvent, WindowPtr theWindow) {
-#if defined(__SC__) || defined(__MRC__)
-# pragma unused(theWindow)
-#endif
-#if 0
-       trans_num_keys (theEvent);
-#endif
-       AddToKeyQueue (topl_resp_key (theEvent->message & 0xff), TRUE);
-}
-
-
 /*
  * Routine used to select and de-select elements in a menu window, used by KeyMenu,
  * ClickMenu, and UpdateMenu.  Takes the NhWindow and a line ref relative to the scrollbar.
@@ -1351,271 +1458,84 @@ ListCoordinateToItem (NhWindow *aWin, short Row) {
 }
 
 
-static void
-macKeyMenu (EventRecord *theEvent, WindowPtr theWindow) {
-       NhWindow *aWin = GetNhWin(theWindow);
-       MacMHMenuItem *mi;
-       int l, ch = theEvent->message & 0xff;
+static pascal void
+MoveScrollBar (ControlHandle theBar, short part) {
+#if !TARGET_API_MAC_CARBON
+       EventRecord fake;
+#endif
+       Rect r;
+       RgnHandle rgn;
+       int now, amtToScroll;
+       WindowPtr theWin;
+       NhWindow *winToScroll;
+       
+       if (!part)
+               return;
 
-       if (aWin && aWin->menuInfo) {
-               HLock ((char**)aWin->menuInfo);
-               for (l = 0, mi = *aWin->menuInfo; l < aWin->miLen; l++, mi++) {
-                       if (mi->accelerator == ch) {
-                               ToggleMenuListItemSelected (aWin, l);
-                               if (mi->line >= aWin->scrollPos && mi->line <= aWin->y_size) {
-                                       SetPortWindowPort(theWindow);
-                                       ToggleMenuSelect (aWin, mi->line - aWin->scrollPos);
-                               }                               
-                               /* Dismiss window if only picking one item */
-                               if (aWin->how != PICK_ANY)
-                                       AddToKeyQueue(CHAR_CR, 1);
-                               break;
-                       }
-               }
-               HUnlock ((char**)aWin->menuInfo);
-               /* add key if didn't find it in menu and not filtered */
-               if (l == aWin->miLen && filter_scroll_key (ch, aWin))
-                       GeneralKey (theEvent, theWindow);
+       theWin = GetControlOwner(theBar);
+       GetWindowBounds(theWin, kWindowContentRgn, &r);
+       OffsetRect(&r, -r.left, -r.top);
+       winToScroll = (NhWindow*)(GetWRefCon(theWin));
+       now = GetControlValue (theBar);
+
+       if (part == kControlPageUpPart || part == kControlPageDownPart) 
+               amtToScroll = (r.bottom - r.top) / winToScroll->row_height;
+       else
+               amtToScroll = 1;
+
+       if (part == kControlPageUpPart || part == kControlUpButtonPart) {
+               int bound = GetControlMinimum (theBar);
+               if (now - bound < amtToScroll)
+                       amtToScroll = now - bound;
+               amtToScroll = -amtToScroll;
+       } else {
+               int bound = GetControlMaximum (theBar);
+               if (bound - now < amtToScroll)
+                       amtToScroll = bound - now;
+       }
+       
+       if (!amtToScroll)
+               return;
+
+       SetControlValue (theBar, now + amtToScroll);
+       winToScroll->scrollPos = now + amtToScroll;
+       r.right -= SBARWIDTH;
+       if (winToScroll == theWindows + WIN_MESSAGE)
+               r.bottom -= SBARHEIGHT;
+       rgn = NewRgn ();
+       ScrollRect (&r, 0, -amtToScroll * winToScroll->row_height, rgn);
+       if (rgn) {
+               InvalWindowRgn(theWin, rgn);
+               BeginUpdate(theWin);
+       }
+#if TARGET_API_MAC_CARBON
+       switch (GetWindowKind(theWin) - WIN_BASE_KIND) {
+       case NHW_MESSAGE:
+               MsgUpdate(GetNhWin(theWin));
+               break;
+       case NHW_MENU:
+               MenwUpdate(GetNhWin(theWin));
+               break;
+       case NHW_TEXT:
+               TextUpdate(GetNhWin(theWin));
+               break;
+       }
+#else
+       winUpdateFuncs [GetWindowKind(theWin) - WIN_BASE_KIND] (&fake, theWin);
+#endif
+       if (rgn) {
+               EndUpdate(theWin);
+               DisposeRgn(rgn);
        }
 }
 
 
+#if !TARGET_API_MAC_CARBON
 static void
-macClickMenu (EventRecord *theEvent, WindowRef theWindow) {
-       Point p;
-       NhWindow *aWin = GetNhWin(theWindow);
-       Rect wrect;
-
-
-       GetWindowBounds(theWindow, kWindowContentRgn, &wrect);
-       OffsetRect(&wrect, -wrect.left, -wrect.top);
-       if (aWin->scrollBar && IsControlVisible(aWin->scrollBar)) {
-               short code;
-               ControlHandle theBar;
-
-               p = theEvent->where;
-               GlobalToLocal (&p);
-               code = FindControl (p, theWindow, &theBar);
-               if (code) {
-                       DoScrollBar (p, code, theBar, aWin);
-                       return;
-               }
-       }
-       if (inSelect != WIN_ERR && aWin->how != PICK_NONE) {
-               short           currentRow = -1, previousRow = -1;
-               short           previousItem = -1, item = -1;
-               Boolean         majorSelectState, firstRow = TRUE;
-
-               do {
-#if !TARGET_API_MAC_CARBON
-                       SystemTask ();
-#endif
-                       GetMouse (&p);
-                       currentRow = p.v / aWin->row_height;
-                       if (p.h < wrect.left || p.h > wrect.right ||
-                               p.v < 0 || p.v > wrect.bottom || currentRow >= aWin->y_size) {
-                               continue;       /* not in window range */
-                       }
-
-                       item = ListCoordinateToItem (aWin, currentRow);
-
-                       if (item != previousItem) {
-                               /* Implement typical Mac multiple-selection behavior
-                                * (ie, not the UI implemented by the Finder)
-                                */
-                               Boolean itemIsSelected = (ListItemSelected (aWin,item) >= 0);
-
-                               if (firstRow) {
-                                       /* this is first valid row, so major state is opposite of what this row is */
-                                       majorSelectState = !itemIsSelected;
-                                       firstRow = FALSE;
-                               }
-
-                               if (aWin->how == PICK_ONE && previousItem != -1) {
-                                       /* if previous row was selected and we're only selecting one object,
-                                        * deselect previous row!
-                                        */
-                                       ToggleMenuListItemSelected (aWin, previousItem);
-                                       ToggleMenuSelect (aWin, previousRow);
-                                       previousItem = -1;
-                               }
-
-                               if (item == -1)
-                                       continue;       /* header line */
-                                       
-                               if (majorSelectState != itemIsSelected) {
-                                       ToggleMenuListItemSelected (aWin, item);
-                                       ToggleMenuSelect (aWin, currentRow);
-                               }
-
-                               previousRow             = currentRow;
-                               previousItem    = item;
-                       }
-               } while (StillDown ());
-
-               /* Dismiss window if only picking one item */
-               if (aWin->how == PICK_ONE)
-                       AddToKeyQueue(CHAR_CR, 1);
-       }
-}
-
-
-static void
-macKeyText (EventRecord *theEvent, WindowPtr theWindow) {
-       NhWindow *aWin = GetNhWin (theWindow);
-       char c = filter_scroll_key (theEvent->message & 0xff, aWin);
-       if (c) {
-               if (inSelect == WIN_ERR && ClosingWindowChar (c)) {
-                       HideWindow (theWindow);
-                       mac_destroy_nhwindow (aWin - theWindows);
-               } else {
-                       GeneralKey (theEvent, theWindow);
-               }
-       }
-}
-
-
-static void
-macClickText (EventRecord *theEvent, WindowPtr theWindow) {
-       NhWindow *aWin = GetNhWin (theWindow);
-
-       if (aWin->scrollBar && IsControlVisible(aWin->scrollBar)) {
-               short code;
-               Point p = theEvent->where;
-               ControlHandle theBar;
-
-               GlobalToLocal (&p);
-               code = FindControl (p, theWindow, &theBar);
-               if (code) {
-                       DoScrollBar (p, code, theBar, aWin);
-               }
-       }
-}
-
-
-static void
-macClickMessage (EventRecord *theEvent, WindowPtr theWindow) {
-       int r_idx = 0;
-       Point mouse = theEvent->where;
-
-       GlobalToLocal(&mouse);
-       while (topl_resp[r_idx]) {
-               Rect frame;
-               topl_resp_rect(r_idx, &frame);
-               InsetRect(&frame, 1, 1);
-               if (PtInRect(mouse, &frame)) {
-                       Boolean in_btn = true;
-
-                       InvertRect(&frame);
-                       while (WaitMouseUp()) {
-#if !TARGET_API_MAC_CARBON
-                               SystemTask();
-#endif
-                               GetMouse(&mouse);
-                               if (PtInRect(mouse, &frame) != in_btn) {
-                                       in_btn = !in_btn;
-                                       InvertRect(&frame);
-                               }
-                       }
-                       if (in_btn) {
-                               InvertRect(&frame);
-                               AddToKeyQueue (topl_resp [r_idx], 1);
-                       }
-                       return;
-
-               }
-               ++r_idx;
-       }
-
-       macClickText(theEvent, theWindow);
-}
-
-
-static void
-macClickTerm (EventRecord *theEvent, WindowPtr theWindow) {
-       NhWindow *nhw = GetNhWin(theWindow);
-       Point where = theEvent->where;
-
-       GlobalToLocal(&where);
-       where.h = where.h / nhw->char_width + 1;
-       where.v = where.v / nhw->row_height;
-       clicked_mod = (theEvent->modifiers & shiftKey) ? CLICK_2 : CLICK_1;
-
-       if (strchr(topl_resp, *click_to_cmd(where.h, where.v, clicked_mod)))
-               nhbell();
-       else {
-#if !TARGET_API_MAC_CARBON
-               if (cursor_locked)
-                       while (WaitMouseUp())
-                               SystemTask();
-#endif
-
-               gClickedToMove = TRUE;
-               clicked_pos = where;
-       }
-}
-
-static pascal void
-MoveScrollBar (ControlHandle theBar, short part) {
-       EventRecord fake;
-       Rect r;
-       RgnHandle rgn;
-       int now, amtToScroll;
-       WindowPtr theWin;
-       NhWindow *winToScroll;
-       
-       if (!part)
-               return;
-
-       theWin = GetControlOwner(theBar);
-       GetWindowBounds(theWin, kWindowContentRgn, &r);
-       OffsetRect(&r, -r.left, -r.top);
-       winToScroll = (NhWindow*)(GetWRefCon(theWin));
-       now = GetControlValue (theBar);
-
-       if (part == kControlPageUpPart || part == kControlPageDownPart) 
-               amtToScroll = (r.bottom - r.top) / winToScroll->row_height;
-       else
-               amtToScroll = 1;
-
-       if (part == kControlPageUpPart || part == kControlUpButtonPart) {
-               int bound = GetControlMinimum (theBar);
-               if (now - bound < amtToScroll)
-                       amtToScroll = now - bound;
-               amtToScroll = -amtToScroll;
-       } else {
-               int bound = GetControlMaximum (theBar);
-               if (bound - now < amtToScroll)
-                       amtToScroll = bound - now;
-       }
-       
-       if (!amtToScroll)
-               return;
-
-       SetControlValue (theBar, now + amtToScroll);
-       winToScroll->scrollPos = now + amtToScroll;
-       r.right -= SBARWIDTH;
-       if (winToScroll == theWindows + WIN_MESSAGE)
-               r.bottom -= SBARHEIGHT;
-       rgn = NewRgn ();
-       ScrollRect (&r, 0, -amtToScroll * winToScroll->row_height, rgn);
-       if (rgn) {
-               InvalWindowRgn(theWin, rgn);
-               BeginUpdate(theWin);
-       }
-       winUpdateFuncs [GetWindowKind(theWin) - WIN_BASE_KIND] (&fake, theWin);
-       if (rgn) {
-               EndUpdate(theWin);
-               DisposeRgn(rgn);
-       }
-}
-
-
-static void
-DoScrollBar (Point p, short code, ControlHandle theBar, NhWindow *aWin)
-{
-       ControlActionUPP func = NULL;
-       Rect rect;
+DoScrollBar (Point p, short code, ControlHandle theBar, NhWindow *aWin)
+{
+       ControlActionUPP func = NULL;
+       Rect rect;
 
        if (code == kControlUpButtonPart || code == kControlPageUpPart ||
                code == kControlDownButtonPart || code == kControlPageDownPart)
@@ -1630,6 +1550,7 @@ DoScrollBar (Point p, short code, ControlHandle theBar, NhWindow *aWin)
                }
        }
 }
+#endif
 
 
 static int
@@ -1664,12 +1585,6 @@ mac_doprev_message(void) {
 }
 
 
-static short
-macDoNull (EventRecord *theEvent, WindowPtr theWindow) {
-       return 0;
-}
-
-
 static void
 draw_growicon_vert_only(WindowPtr wind)
 {
@@ -1691,572 +1606,152 @@ draw_growicon_vert_only(WindowPtr wind)
 }
 
 
-static short
-macUpdateMessage (EventRecord *theEvent, WindowPtr theWindow)
-{
-       RgnHandle org_clip = NewRgn(), clip = NewRgn();
-       Rect r;
+/* NOT_IN_CARBON */
+static void
+WindowGoAway (EventRecord *theEvent, WindowPtr theWindow) {
        NhWindow *aWin = GetNhWin(theWindow);
-       int l;
 
-       if (!theEvent)
-               return 0;
+       if (!theEvent || TrackGoAway (theWindow, theEvent->where)) {
+               if (aWin - theWindows == BASE_WINDOW && !iflags.window_inited) {
+                       AddToKeyQueue ('\033', 1);
+               } else {
+                       HideWindow (theWindow);
+                       if (aWin - theWindows != inSelect)
+                               mac_destroy_nhwindow (aWin - theWindows);
+                       else                                                            /* if this IS the inSelect window put a close char */
+                               AddToKeyQueue (CHAR_CR, 1);             /* in queue to exit and maintain inSelect */
+               }
+       }
+}
 
-       GetClip(org_clip);
-       GetWindowBounds(theWindow, kWindowContentRgn, &r);
-       OffsetRect(&r, -r.left, -r.top);
 
-       DrawControls(theWindow);
-       DrawGrowIcon(theWindow);
+void
+mac_get_nh_event(void) {
+       EventRecord anEvent;
 
-       for (l = 0; topl_resp[l]; l++) {
-               StringPtr name;
-               unsigned char tmp[2];
-               FontInfo font;
-               Rect frame;
-               topl_resp_rect(l, &frame);
-               switch (topl_resp[l]) {
-                       case 'y':
-                               name = "\pyes";
-                               break;
-                       case 'n':
-                               name = "\pno";
-                               break;
-                       case 'N':
-                               name = "\pNone";
-                               break;
-                       case 'a':
-                               name = "\pall";
-                               break;
-                       case 'q':
-                               name = "\pquit";
-                               break;
-                       case CHAR_ANY:
-                               name = "\pany key";
-                               break;
-                       default:
-                               tmp[0] = 1;
-                               tmp[1] = topl_resp[l];
-                               name = tmp;
-                               break;
-               }
-               TextFont(kFontIDGeneva);
-               TextSize(9);
-               GetFontInfo(&font);
-               MoveTo ((frame.left + frame.right - StringWidth(name)) / 2,
-                       (frame.top + frame.bottom + font.ascent-font.descent-font.leading-1) / 2);
-               DrawString(name);
-               PenNormal();
-               if (l == topl_def_idx)
-                       PenSize(2, 2);
-               FrameRoundRect(&frame, 4, 4);
-       }
 
-       r.right -= SBARWIDTH;
-       r.bottom -= SBARHEIGHT;
-       /* Clip to the portrect - scrollbar/growicon *before* adjusting the rect
-               to be larger than the size of the window (!) */
-       RectRgn(clip, &r);
-       SectRgn(clip, org_clip, clip);
-       if (r.right < MIN_RIGHT)
-               r.right = MIN_RIGHT;
-       r.top -= aWin->scrollPos * aWin->row_height;
+       /* KMH -- Don't proceed if the window system isn't set up */
+       if (!iflags.window_inited)
+               return;
 
-#if 0
-       /* If you enable this band of code (and disable the next band), you will get
-          fewer flickers but a slower performance while drawing the dot line. */
-       {       RgnHandle dotl_rgn = NewRgn();
-               Rect dotl;
-               dotl.left       = r.left;
-               dotl.right      = r.right;
-               dotl.bottom = r.top + aWin->save_lin * aWin->row_height;
-               dotl.top        = dotl.bottom - 1;
-               FillRect(&dotl, &qd.gray);
-               RectRgn(dotl_rgn, &dotl);
-               DiffRgn(clip, dotl_rgn, clip);
-               DisposeRgn(dotl_rgn);
-               SetClip(clip);
-       }
-#endif
+       (void) WaitNextEvent (everyEvent, &anEvent, -1, gMouseRgn);
+       HandleEvent(&anEvent);
+       return;
+}
 
-       if (in_topl_mode()) {
-               RgnHandle topl_rgn = NewRgn();
-               Rect topl_r = r;
-               topl_r.top += (aWin->y_size - 1) * aWin->row_height;
-               l = (*top_line)->destRect.right - (*top_line)->destRect.left;
-               (*top_line)->viewRect = topl_r;
-               (*top_line)->destRect = topl_r;
-               if (l != topl_r.right - topl_r.left)
-                       TECalText(top_line);
-               TEUpdate(&topl_r, top_line);
-               RectRgn(topl_rgn, &topl_r);
-               DiffRgn(clip, topl_rgn, clip);
-               DisposeRgn(topl_rgn);
-               SetClip(clip);
-       }
 
-       DisposeRgn(clip);
+int
+mac_nhgetch(void) {
+       int ch;
+       long doDawdle = 1L;
+       EventRecord anEvent;
 
-       TextFont (aWin->font_number);
-       TextSize (aWin->font_size);
-       HLock (aWin->windowText);
-       TETextBox (*aWin->windowText, aWin->windowTextLen, &r, teJustLeft);
-       HUnlock (aWin->windowText);
 
 #if !TARGET_API_MAC_CARBON
-       r.bottom = r.top + aWin->save_lin * aWin->row_height;
-       r.top    = r.bottom - 1;
-       FillRect(&r, (void *) &qd.gray);
-#endif
-
-       SetClip(org_clip);
-       DisposeRgn(org_clip);
-       return 0;
-}
-
+       /* We want to take care of keys in the buffer as fast as
+        * possible
+        */
+       if (keyQueueCount)
+               doDawdle = 0L;
+       else {
+               long total, contig;
+               static char warn = 0;
 
-static short 
-macUpdateMenu (EventRecord *theEvent, WindowPtr theWindow) {
-       NhWindow *aWin = GetNhWin (theWindow);
-       int i, line;
-       MacMHMenuItem *mi;
-       
-       GeneralUpdate (theEvent, theWindow);
-       HLock ((char**)aWin->menuInfo);
-       HLock ((char**)aWin->menuSelected);
-       for (i = 0; i < aWin->miSelLen; i++) {
-               mi = &(*aWin->menuInfo) [(*aWin->menuSelected) [i]];
-               line = mi->line;
-               if (line > aWin->scrollPos && line <= aWin->y_size)
-                       ToggleMenuSelect (aWin, line - aWin->scrollPos);
+               doDawdle = (in_topl_mode() ? GetCaretTime () : 120L);
+               /* Since we have time, check memory */
+               PurgeSpace(&total, &contig);
+               if (contig < 25000L || total < 50000L) {
+                       if (!warn) {
+                               pline ("Low Memory!");
+                               warn = 1;
+                       }
+               } else {
+                       warn = 0;
+               }
        }
-       HUnlock ((char**)aWin->menuInfo);
-       HUnlock ((char**)aWin->menuSelected);
-       return 0;
-}
-
-
-static short
-GeneralUpdate (EventRecord *theEvent, WindowPtr theWindow) {
-       Rect r, r2;
-       NhWindow *aWin = GetNhWin (theWindow);
-       RgnHandle h;
-       Boolean vis;
-
-
-       if (!theEvent)
-               return 0;
-
-       GetWindowBounds(theWindow, kWindowContentRgn, &r);
-       OffsetRect(&r, -r.left, -r.top);
-       r2 = r;
-       r2.left = r2.right - SBARWIDTH;
-       r2.right += 1;
-       r2.top -= 1;
-       vis = (r2.bottom > r2.top + 50);
+#endif
 
-       draw_growicon_vert_only(theWindow);
-       DrawControls (theWindow);
+       do {
+#if 0//TARGET_API_MAC_CARBON
+               EventRef event;
 
-       h = (RgnHandle) 0;
-       if (vis && (h = NewRgn ())) {
-               RgnHandle tmp = NewRgn ();
-               if (!tmp) {
-                       DisposeRgn (h);
-                       h = (RgnHandle) 0;
-               } else {
-                       GetClip (h);
-                       RectRgn (tmp, &r2);
-                       DiffRgn (h, tmp, tmp);
-                       SetClip (tmp);
-                       DisposeRgn (tmp);
+               if (ReceiveNextEvent(0, NULL, kEventDurationForever, TRUE, &event) == noErr) {
+                       SendEventToEventTarget(event, dispatcher);
+                       ReleaseEvent(event);
                }
-       }
-       if (r.right < MIN_RIGHT)
-               r.right = MIN_RIGHT;
-       r.top -= aWin->scrollPos * aWin->row_height;
-       r.right -= SBARWIDTH;
-       HLock (aWin->windowText);
-       TETextBox (*aWin->windowText, aWin->windowTextLen, &r, teJustLeft);
-       HUnlock (aWin->windowText);
-       if (h) {
-               SetClip (h);
-               DisposeRgn (h);
-       }
-       return 0;
-}
+#else
+               (void) WaitNextEvent(everyEvent, &anEvent, doDawdle, gMouseRgn);
+               HandleEvent(&anEvent);
+#endif
+               ch = GetFromKeyQueue();
+       } while (!ch && !gClickedToMove);
 
+       if (!gClickedToMove)
+               ObscureCursor();
+       else
+               gClickedToMove = 0;
 
-static void
-macCursorTerm (EventRecord *theEvent, WindowPtr theWindow, RgnHandle mouseRgn) {
-       char *dir_bas, *dir;
-       CursHandle ch;
-       GrafPtr gp;
-       NhWindow *nhw = GetNhWin (theWindow);
-       Rect r = {0, 0, 1, 1};
+#ifdef THINK_C
+       if (ch == '\r') ch = '\n';
+#endif
 
-       GetPort (&gp);
-       SetPortWindowPort(theWindow);
+       return (ch);
+}
 
-       if (cursor_locked)
-               dir = (char *)0;
-       else {
-               Point where = theEvent->where;
 
-               GlobalToLocal (&where);
-               dir_bas = iflags.num_pad ? (char *) ndir : (char *) sdir;
-               dir = strchr (dir_bas, *click_to_cmd (where.h / nhw->char_width + 1 ,
-                                                       where.v / nhw->row_height, CLICK_1));
-       }
-       ch = GetCursor (dir ? dir - dir_bas + 513 : 512);
-       if (ch) {
-               HLock ((Handle) ch);
-               SetCursor (*ch);
-               HUnlock ((Handle) ch);
+void
+mac_delay_output(void) {
+       long destTicks = TickCount () + 1;
 
-       } else {
-               SetCursor(&qdarrow);
+       while (TickCount () < destTicks) {
+               mac_get_nh_event ();
        }
-       OffsetRect (&r, theEvent->where.h, theEvent->where.v);
-       RectRgn (mouseRgn, &r);
-       SetPort (gp);
 }
 
 
+#ifdef CLIPPING
 static void
-GeneralCursor (EventRecord *theEvent, WindowPtr theWindow, RgnHandle mouseRgn) {
+mac_cliparound (int x, int y) {
 #if defined(__SC__) || defined(__MRC__)
-# pragma unused(theWindow)
+# pragma unused(x,y)
 #endif
-       Rect r = {-1, -1, 2, 2};
-
-       SetCursor(&qdarrow);
-       OffsetRect (&r, theEvent->where.h, theEvent->where.v);
-       RectRgn (mouseRgn, &r);
+       /* TODO */
 }
+#endif
 
+void
+mac_exit_nhwindows (const char *s) {
+       clear_screen ();
+       tty_exit_nhwindows (s);
+       mac_destroy_nhwindow (WIN_MESSAGE);
+       mac_destroy_nhwindow (WIN_INVEN);
+}
 
-static void
-HandleKey (EventRecord *theEvent) {
-       WindowPtr theWindow = FrontWindow ();
 
-       if (theEvent->modifiers & cmdKey) {
-               if (theEvent->message & 0xff == '.') {
                      /* Flush key queue */
-                       keyQueueCount = keyQueueWrite = keyQueueRead = 0;
-                       theEvent->message = '\033';
-                       goto dispatchKey;
-               } else {
-                       UndimMenuBar ();
-                       DoMenuEvt (MenuKey (theEvent->message & 0xff));
-               }
-       } else {
+/*
+ * Don't forget to decrease in_putstr before returning...
+ */
+void
+mac_putstr (winid win, int attr, const char *str) {
+       long len, slen;
+       NhWindow *aWin = &theWindows [win];
+       static char in_putstr = 0;
+       short newWidth, maxWidth;
+       Rect r;
+       char *src, *sline, *dst, ch;
 
-dispatchKey :
-               if (theWindow) {
-                       int kind = GetWindowKind(theWindow) - WIN_BASE_KIND;
-                       winKeyFuncs [kind] (theEvent, theWindow);
-               } else {
-                       GeneralKey (theEvent, (WindowPtr) 0);
-               }
+       if (win < 0 || win >= NUM_MACWINDOWS || !aWin->its_window) {
+               error ("putstr: Invalid win %d (Max %d).", win, NUM_MACWINDOWS, attr);
+               return;
        }
-}
-
-
-static void
-WindowGoAway (EventRecord *theEvent, WindowPtr theWindow) {
-       NhWindow *aWin = GetNhWin(theWindow);
 
-       if (!theEvent || TrackGoAway (theWindow, theEvent->where)) {
-               if (aWin - theWindows == BASE_WINDOW && !iflags.window_inited) {
-                       AddToKeyQueue ('\033', 1);
-               } else {
-                       HideWindow (theWindow);
-                       if (aWin - theWindows != inSelect)
-                               mac_destroy_nhwindow (aWin - theWindows);
-                       else                                                            /* if this IS the inSelect window put a close char */
-                               AddToKeyQueue (CHAR_CR, 1);             /* in queue to exit and maintain inSelect */
-               }
+       if (aWin->its_window == _mt_window) {
+               tty_putstr(win, attr, str);
+               return;
        }
-}
 
-
-static void
-HandleClick (EventRecord *theEvent) {
-       int code;
-       unsigned long l;
-       WindowPtr theWindow;
-       NhWindow *aWin;
-       Rect r;
-       Boolean not_inSelect;
-
-       InsetRect(GetRegionBounds(GetGrayRgn(), &r), 4, 4);
-
-       code = FindWindow (theEvent->where, &theWindow);
-       aWin = GetNhWin (theWindow);
-       not_inSelect = (inSelect == WIN_ERR || aWin - theWindows == inSelect);
-       
-       switch (code) {
-       case inContent :
-               if (not_inSelect) {
-                       int kind = GetWindowKind(theWindow) - WIN_BASE_KIND;
-                       winCursorFuncs [kind] (theEvent, theWindow, gMouseRgn);
-                       SelectWindow (theWindow);
-                       SetPortWindowPort(theWindow);
-                       winClickFuncs [kind] (theEvent, theWindow);
-               } else {
-                       nhbell ();
-               }
-               break;
-
-       case inDrag :
-               if (not_inSelect) {
-                       SetCursor(&qdarrow);
-                       DragWindow (theWindow, theEvent->where, &r);
-                       SaveWindowPos(theWindow);
-               } else {
-                       nhbell ();
-               }
-               break;
-
-       case inGrow :
-               if (not_inSelect) {
-                       SetCursor(&qdarrow);
-                       SetRect (&r, 80, 2 * aWin->row_height + 1, r.right, r.bottom);
-                       if (aWin == theWindows + WIN_MESSAGE)
-                               r.top += SBARHEIGHT;
-                       l = GrowWindow (theWindow, theEvent->where, &r);
-                       SizeWindow (theWindow, l & 0xffff, l >> 16, FALSE);
-                       SaveWindowSize(theWindow);
-                       SetPortWindowPort(theWindow);
-                       GetWindowBounds(theWindow, kWindowContentRgn, &r);
-                       OffsetRect(&r, -r.left, -r.top);
-                       InvalWindowRect(theWindow, &r);
-                       if (aWin->scrollBar) {
-                               DrawScrollbar (aWin);
-                       }
-               } else {
-                       nhbell ();
-               }
-               break;
-
-       case inGoAway :
-               WindowGoAway(theEvent, theWindow);
-               break;
-
-       case inMenuBar :
-               DoMenuEvt (MenuSelect (theEvent->where));
-               break;
-
-#if !TARGET_API_MAC_CARBON
-       case inSysWindow :
-               SystemClick(theEvent, theWindow);
-#endif
-       default :
-               break;
-       }
-}
-
-
-static void
-HandleUpdate (EventRecord *theEvent) {
-       WindowPtr theWindow = (WindowPtr) theEvent->message;
-       NhWindow *aWin = GetNhWin (theWindow);
-       Rect r;
-
-
-       char existing_update_region = FALSE;
-       Rect rect;
-       
-       if (theWindow == _mt_window) {
-               existing_update_region = (get_invalid_region (theWindow, &rect) == noErr);
-       }
-       BeginUpdate (theWindow);
-       SetPortWindowPort(theWindow);
-       GetWindowBounds(theWindow, kWindowContentRgn, &r);
-       OffsetRect(&r, -r.left, -r.top);
-       EraseRect(&r);
-       winUpdateFuncs [GetWindowKind(theWindow) - WIN_BASE_KIND] 
-                               (theEvent, theWindow);
-
-       if (theWindow == _mt_window && existing_update_region) {
-               set_invalid_region (theWindow, &rect);
-       }
-       aWin->drawn = TRUE;
-       EndUpdate (theWindow);
-}
-
-
-static void
-DoOsEvt (EventRecord *theEvent) {
-       WindowRef win;
-       short code;
-
-       if ((theEvent->message & 0xff000000) == 0xfa000000) {
-               /* Mouse Moved */
-
-               code = FindWindow (theEvent->where, &win);
-               if (code != inContent) {
-                       Rect r = {-1, -1, 2, 2};
-
-                       SetCursor(&qdarrow);
-                       OffsetRect (&r, theEvent->where.h, theEvent->where.v);
-                       RectRgn (gMouseRgn, &r);
-               } else {
-                       int kind = GetWindowKind(win) - WIN_BASE_KIND;
-                       if (kind >= 0 && kind <= NHW_TEXT) {
-                               winCursorFuncs [kind] (theEvent, win, gMouseRgn);
-                       }
-               }
-       }
-}
-
-
-void
-HandleEvent (EventRecord *theEvent) {
-       switch (theEvent->what) {
-       case autoKey :
-       case keyDown :
-               HandleKey (theEvent);
-               break;
-       case updateEvt :
-               HandleUpdate (theEvent);
-               break;
-       case mouseDown :
-               HandleClick (theEvent);
-               break;
-#if !TARGET_API_MAC_CARBON
-       case diskEvt :
-               if ((theEvent->message & 0xffff0000) != 0) {
-                       Point p = {150, 150};
-                       (void) DIBadMount (p, theEvent->message);
-               }
-               break;
-#endif
-       case osEvt :
-               DoOsEvt (theEvent);
-               break;
-       case kHighLevelEvent:
-               AEProcessAppleEvent(theEvent);
-       default :
-               break;
-       }
-}
-
-
-void
-mac_get_nh_event(void) {
-       EventRecord anEvent;
-
-       /* KMH -- Don't proceed if the window system isn't set up */
-       if (!iflags.window_inited)
-               return;
-
-       (void) WaitNextEvent (everyEvent, &anEvent, -1, gMouseRgn);
-       HandleEvent(&anEvent);
-}
-
-
-int
-mac_nhgetch(void) {
-       int ch;
-       long doDawdle;
-       EventRecord anEvent;
-
-       /* We want to take care of keys in the buffer as fast as
-        * possible
-        */
-       if (keyQueueCount)
-               doDawdle = 0L;
-       else {
-               long total, contig;
-               static char warn = 0;
-
-               doDawdle = (in_topl_mode() ? GetCaretTime () : 120L);
-               /* Since we have time, check memory */
-               PurgeSpace (&total, &contig);
-               if (contig < 25000L || total < 50000L) {
-                       if (!warn) {
-                               pline ("Low Memory!");
-                               warn = 1;
-                       }
-               } else {
-                       warn = 0;
-               }
-       }
-
-       do {
-               (void) WaitNextEvent (everyEvent, &anEvent, doDawdle, gMouseRgn);
-               HandleEvent (&anEvent);
-               ch = GetFromKeyQueue ();
-       } while (!ch && !gClickedToMove);
-
-       if (!gClickedToMove)
-               ObscureCursor ();
-       else
-               gClickedToMove = 0;
-
-#ifdef THINK_C
-       if (ch == '\r') ch = '\n';
-#endif
-
-       return ch;
-}
-
-
-void
-mac_delay_output(void) {
-       long destTicks = TickCount () + 1;
-
-       while (TickCount () < destTicks) {
-               mac_get_nh_event ();
-       }
-}
-
-
-#ifdef CLIPPING
-static void
-mac_cliparound (int x, int y) {
-#if defined(__SC__) || defined(__MRC__)
-# pragma unused(x,y)
-#endif
-       /* TODO */
-}
-#endif
-
-void
-mac_exit_nhwindows (const char *s) {
-       clear_screen ();
-       tty_exit_nhwindows (s);
-       mac_destroy_nhwindow (WIN_MESSAGE);
-       mac_destroy_nhwindow (WIN_INVEN);
-}
-
-
-/*
- * Don't forget to decrease in_putstr before returning...
- */
-void
-mac_putstr (winid win, int attr, const char *str) {
-       long len, slen;
-       NhWindow *aWin = &theWindows [win];
-       static char in_putstr = 0;
-       short newWidth, maxWidth;
-       Rect r;
-       char *src, *sline, *dst, ch;
-
-       if (win < 0 || win >= NUM_MACWINDOWS || !aWin->its_window) {
-               error ("putstr: Invalid win %d (Max %d).", win, NUM_MACWINDOWS, attr);
-               return;
-       }
-
-       if (aWin->its_window == _mt_window) {
-               tty_putstr(win, attr, str);
-               return;
-       }
-
-       if (in_putstr > 3)
-               return;
+       if (in_putstr > 3)
+               return;
 
        in_putstr ++;
        slen = strlen (str);
@@ -2267,7 +1762,7 @@ mac_putstr (winid win, int attr, const char *str) {
        if (win == WIN_MESSAGE) {
                r.right  -= SBARWIDTH;
                r.bottom -= SBARHEIGHT;
-               if (sysflags.page_wait && 
+               if (flags.page_wait && 
                        aWin->last_more_lin <= aWin->y_size - (r.bottom - r.top) / aWin->row_height) {
                        aWin->last_more_lin = aWin->y_size;
                        mac_display_nhwindow(win, TRUE);
@@ -2587,7 +2082,1127 @@ try_key_queue (char *bufp) {
        return 0;
 }
 
-/* Interface definition, for windows.c */
+
+
+/**********************************************************************
+ *     Base window
+ */
+
+static void
+BaseClick(NhWindow *wind, Point pt, UInt32 modifiers)
+{
+       pt.h = pt.h / wind->char_width + 1;
+       pt.v = pt.v / wind->row_height;
+       clicked_mod = (modifiers & shiftKey) ? CLICK_2 : CLICK_1;
+
+       if (strchr(topl_resp, *click_to_cmd(pt.h, pt.v, clicked_mod)))
+               nhbell();
+       else {
+#if !TARGET_API_MAC_CARBON
+               if (cursor_locked)
+                       while (WaitMouseUp())
+                               SystemTask();
+#endif
+
+               gClickedToMove = TRUE;
+               clicked_pos = pt;
+       }
+       return;
+}
+
+
+static void
+BaseCursor(NhWindow *wind, Point pt)
+{
+       char *dir_bas, *dir;
+       CursHandle ch;
+
+
+       if (cursor_locked)
+               dir = (char *)0;
+       else {
+               dir_bas = iflags.num_pad ? (char *) ndir : (char *) sdir;
+               dir = strchr(dir_bas, *click_to_cmd(pt.h / wind->char_width + 1 ,
+                       pt.v / wind->row_height, CLICK_1));
+       }
+       ch = GetCursor(dir ? dir - dir_bas + 513 : 512);
+       if (ch) {
+               HLock((Handle) ch);
+               SetCursor(*ch);
+               HUnlock((Handle) ch);
+       } else {
+               SetCursor(&qdarrow);
+       }
+       return;
+}
+
+
+#if TARGET_API_MAC_CARBON
+static pascal OSStatus
+BaseEvent(EventHandlerCallRef nexthandler, EventRef event, void *userdata)
+{
+       NhWindow *wind = (NhWindow *) userdata;
+
+
+       switch (GetEventClass(event)) {
+       case kEventClassKeyboard: {
+               char ch;
+               UInt32 modifiers;
+
+
+               GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL,
+                       sizeof(char), NULL, &ch);
+               GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL,
+                       sizeof(UInt32), NULL, &modifiers);
+               if (modifiers & cmdKey)
+                       return (eventNotHandledErr);
+               AddToKeyQueue(topl_resp_key(ch), TRUE);
+               return (noErr);
+       }
+
+       case kEventClassMouse: {
+               CGrafPtr saveport;
+               GDHandle savedev;
+               Point pt;
+
+               switch (GetEventKind(event)) {
+               case kEventMouseMoved:
+                       GetEventParameter(event, kEventParamMouseLocation, typeQDPoint,
+                               NULL, sizeof(Point), NULL, &pt);
+                       GetGWorld(&saveport, &savedev);
+                       SetPortWindowPort(wind->its_window);
+                       GlobalToLocal(&pt);
+                       SetGWorld(saveport, savedev);
+                       BaseCursor(wind, pt);
+                       return (eventNotHandledErr);
+               }
+               break;
+       }
+
+       case kEventClassWindow:
+               switch (GetEventKind(event)) {
+               case kEventWindowDrawContent: 
+                       CallNextEventHandler(nexthandler, event);
+                       image_tty(NULL, wind->its_window);
+                       return (noErr);
+
+               case kEventWindowHandleContentClick: {
+                       CGrafPtr saveport;
+                       GDHandle savedev;
+                       Point pt;
+                       UInt32 modifiers;
+
+                       GetEventParameter(event, kEventParamMouseLocation, typeQDPoint,
+                               NULL, sizeof(Point), NULL, &pt);
+                       GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL,
+                               sizeof(UInt32), NULL, &modifiers);
+                       GetGWorld(&saveport, &savedev);
+                       SetPortWindowPort(wind->its_window);
+                       GlobalToLocal(&pt);
+                       SetGWorld(saveport, savedev);
+                       BaseClick(wind, pt, modifiers);
+                       return (noErr);
+               }
+
+               case kEventWindowClose:
+                       /* TODO... */
+                       break;
+               }
+               break;
+       }
+       return (eventNotHandledErr);
+}
+
+#else
+
+static void
+macClickTerm (EventRecord *theEvent, WindowPtr theWindow) {
+       Point where = theEvent->where;
+
+       GlobalToLocal(&where);
+       BaseClick(GetNhWin(theWindow), where, theEvent->modifiers);
+       return;
+}
+
+
+static void
+macCursorTerm (EventRecord *theEvent, WindowPtr theWindow, RgnHandle mouseRgn) {
+       GrafPtr gp;
+       Point where = theEvent->where;
+       Rect r = {0, 0, 1, 1};
+
+
+       GetPort(&gp);
+       SetPortWindowPort(theWindow);
+       GlobalToLocal(&where);
+       BaseCursor(GetNhWin(theWindow), where);
+       OffsetRect(&r, theEvent->where.h, theEvent->where.v);
+       RectRgn(mouseRgn, &r);
+       SetPort(gp);
+       return;
+}
+
+#endif /* !TARGET_API_MAC_CARBON */
+
+
+
+/**********************************************************************
+ *     Status subwindow
+ */
+
+
+
+/**********************************************************************
+ *     Map subwindow
+ */
+
+
+
+/**********************************************************************
+ *     Message window
+ */
+
+static void
+MsgClick(NhWindow *wind, Point pt)
+{
+       int r_idx = 0;
+
+
+       while (topl_resp[r_idx]) {
+               Rect frame;
+               topl_resp_rect(r_idx, &frame);
+               InsetRect(&frame, 1, 1);
+               if (PtInRect(pt, &frame)) {
+                       Boolean in_btn = true;
+
+                       InvertRect(&frame);
+                       while (WaitMouseUp()) {
+#if !TARGET_API_MAC_CARBON
+                               SystemTask();
+#endif
+                               GetMouse(&pt);
+                               if (PtInRect(pt, &frame) != in_btn) {
+                                       in_btn = !in_btn;
+                                       InvertRect(&frame);
+                               }
+                       }
+                       if (in_btn) {
+                               InvertRect(&frame);
+                               AddToKeyQueue (topl_resp [r_idx], 1);
+                       }
+                       return;
+
+               }
+               ++r_idx;
+       }
+       return;
+}
+
+
+static void
+MsgUpdate(NhWindow *wind)
+{
+       RgnHandle org_clip = NewRgn(), clip = NewRgn();
+       Rect r;
+       int l;
+
+
+       GetClip(org_clip);
+       GetWindowBounds(wind->its_window, kWindowContentRgn, &r);
+       OffsetRect(&r, -r.left, -r.top);
+
+       DrawControls(wind->its_window);
+       DrawGrowIcon(wind->its_window);
+
+       for (l = 0; topl_resp[l]; l++) {
+               StringPtr name;
+               unsigned char tmp[2];
+               FontInfo font;
+               Rect frame;
+               topl_resp_rect(l, &frame);
+               switch (topl_resp[l]) {
+                       case 'y':
+                               name = "\pyes";
+                               break;
+                       case 'n':
+                               name = "\pno";
+                               break;
+                       case 'N':
+                               name = "\pNone";
+                               break;
+                       case 'a':
+                               name = "\pall";
+                               break;
+                       case 'q':
+                               name = "\pquit";
+                               break;
+                       case CHAR_ANY:
+                               name = "\pany key";
+                               break;
+                       default:
+                               tmp[0] = 1;
+                               tmp[1] = topl_resp[l];
+                               name = tmp;
+                               break;
+               }
+               TextFont(kFontIDGeneva);
+               TextSize(9);
+               GetFontInfo(&font);
+               MoveTo ((frame.left + frame.right - StringWidth(name)) / 2,
+                       (frame.top + frame.bottom + font.ascent-font.descent-font.leading-1) / 2);
+               DrawString(name);
+               PenNormal();
+               if (l == topl_def_idx)
+                       PenSize(2, 2);
+               FrameRoundRect(&frame, 4, 4);
+       }
+
+       r.right -= SBARWIDTH;
+       r.bottom -= SBARHEIGHT;
+       /* Clip to the portrect - scrollbar/growicon *before* adjusting the rect
+               to be larger than the size of the window (!) */
+       RectRgn(clip, &r);
+       SectRgn(clip, org_clip, clip);
+       if (r.right < MIN_RIGHT)
+               r.right = MIN_RIGHT;
+       r.top -= wind->scrollPos * wind->row_height;
+
+#if 0
+       /* If you enable this band of code (and disable the next band), you will get
+          fewer flickers but a slower performance while drawing the dot line. */
+       {       RgnHandle dotl_rgn = NewRgn();
+               Rect dotl;
+               dotl.left       = r.left;
+               dotl.right      = r.right;
+               dotl.bottom = r.top + aWin->save_lin * aWin->row_height;
+               dotl.top        = dotl.bottom - 1;
+               FillRect(&dotl, &qd.gray);
+               RectRgn(dotl_rgn, &dotl);
+               DiffRgn(clip, dotl_rgn, clip);
+               DisposeRgn(dotl_rgn);
+               SetClip(clip);
+       }
+#endif
+
+       if (in_topl_mode()) {
+               RgnHandle topl_rgn = NewRgn();
+               Rect topl_r = r;
+               topl_r.top += (wind->y_size - 1) * wind->row_height;
+               l = (*top_line)->destRect.right - (*top_line)->destRect.left;
+               (*top_line)->viewRect = topl_r;
+               (*top_line)->destRect = topl_r;
+               if (l != topl_r.right - topl_r.left)
+                       TECalText(top_line);
+               TEUpdate(&topl_r, top_line);
+               RectRgn(topl_rgn, &topl_r);
+               DiffRgn(clip, topl_rgn, clip);
+               DisposeRgn(topl_rgn);
+               SetClip(clip);
+       }
+
+       DisposeRgn(clip);
+
+       TextFont (wind->font_number);
+       TextSize (wind->font_size);
+       HLock (wind->windowText);
+       TETextBox (*wind->windowText, wind->windowTextLen, &r, teJustLeft);
+       HUnlock (wind->windowText);
+
+#if !TARGET_API_MAC_CARBON
+       r.bottom = r.top + aWin->save_lin * aWin->row_height;
+       r.top    = r.bottom - 1;
+       FillRect(&r, (void *) &qd.gray);
+#endif
+
+       SetClip(org_clip);
+       DisposeRgn(org_clip);
+       return;
+}
+
+
+#if TARGET_API_MAC_CARBON
+static pascal OSStatus
+MsgEvent(EventHandlerCallRef nexthandler, EventRef event, void *userdata)
+{
+       NhWindow *wind = (NhWindow *) userdata;
+
+
+       switch (GetEventClass(event)) {
+       case kEventClassControl: {
+               ControlRef control;
+               ControlID id;
+
+               switch (GetEventKind(event)) {
+               case kEventControlHit:
+                       GetEventParameter(event, kEventParamDirectObject,
+                               typeControlRef, NULL, sizeof(ControlRef), NULL, &control);
+                       GetControlID(control, &id);
+                       /* TODO... */
+                       return (noErr);
+               }
+               break;
+       }
+
+       case kEventClassKeyboard: {
+               char ch;
+               UInt32 modifiers;
+
+
+               GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL,
+                       sizeof(char), NULL, &ch);
+               GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL,
+                       sizeof(UInt32), NULL, &modifiers);
+               if (modifiers & cmdKey)
+                       return (eventNotHandledErr);
+               AddToKeyQueue(topl_resp_key(ch), TRUE);
+               return (noErr);
+       }
+
+       case kEventClassWindow:
+               switch (GetEventKind(event)) {
+               case kEventWindowDrawContent: 
+                       CallNextEventHandler(nexthandler, event);
+                       MsgUpdate(wind);
+                       return (noErr);
+
+               case kEventWindowHandleContentClick: {
+                       CGrafPtr saveport;
+                       GDHandle savedev;
+                       Point pt;
+
+                       GetEventParameter(event, kEventParamMouseLocation, typeQDPoint,
+                               NULL, sizeof(Point), NULL, &pt);
+                       GetGWorld(&saveport, &savedev);
+                       SetPortWindowPort(wind->its_window);
+                       GlobalToLocal(&pt);
+                       SetGWorld(saveport, savedev);
+                       MsgClick(wind, pt);
+                       return (noErr);
+               }
+
+               case kEventWindowClose:
+                       /* TODO... */
+                       break;
+               }
+               break;
+       }
+       return (eventNotHandledErr);
+}
+
+#else
+
+static void
+macClickMessage (EventRecord *theEvent, WindowPtr theWindow) {
+       Point mouse = theEvent->where;
+
+       GlobalToLocal(&mouse);
+       MsgClick(GetNhWin(theWindow), mouse);
+       macClickText(theEvent, theWindow);
+}
+
+
+static short
+macUpdateMessage (EventRecord *theEvent, WindowPtr theWindow)
+{
+       if (!theEvent)
+               return 0;
+       MsgUpdate(GetNhWin(theWindow));
+       return 0;
+}
+
+#endif /* !TARGET_API_MAC_CARBON */
+
+
+
+/**********************************************************************
+ *     Menu windows
+ */
+
+static void
+MenwKey(NhWindow *wind, char ch)
+{
+       MacMHMenuItem *mi;
+       int i;
+
+
+       ch = filter_scroll_key(ch, wind);
+       if (!ch)
+               return;
+       if (ClosingWindowChar(ch)) {
+               AddToKeyQueue(CHAR_CR, 1);
+               return;
+       }
+
+       if (!wind || !wind->menuInfo)
+               return;
+       HLock((char**)wind->menuInfo);
+       for (i = 0, mi = *wind->menuInfo; i < wind->miLen; i++, mi++) {
+               if (mi->accelerator == ch) {
+                       ToggleMenuListItemSelected (wind, i);
+                       if (mi->line >= wind->scrollPos && mi->line <= wind->y_size) {
+                               SetPortWindowPort(wind->its_window);
+                               ToggleMenuSelect(wind, mi->line - wind->scrollPos);
+                       }                               
+                       /* Dismiss window if only picking one item */
+                       if (wind->how != PICK_ANY)
+                               AddToKeyQueue(CHAR_CR, 1);
+                       break;
+               }
+       }
+       HUnlock ((char**)wind->menuInfo);
+       /* add key if didn't find it in menu and not filtered */
+       return;
+}
+
+
+static void
+MenwClick(NhWindow *wind, Point pt)
+{
+       Rect wrect;
+
+
+       GetWindowBounds(wind->its_window, kWindowContentRgn, &wrect);
+       OffsetRect(&wrect, -wrect.left, -wrect.top);
+       if (inSelect != WIN_ERR && wind->how != PICK_NONE) {
+               short           currentRow = -1, previousRow = -1;
+               short           previousItem = -1, item = -1;
+               Boolean         majorSelectState, firstRow = TRUE;
+
+               do {
+#if !TARGET_API_MAC_CARBON
+                       SystemTask ();
+#endif
+                       GetMouse (&pt);
+                       currentRow = pt.v / wind->row_height;
+                       if (pt.h < wrect.left || pt.h > wrect.right ||
+                               pt.v < 0 || pt.v > wrect.bottom || currentRow >= wind->y_size) {
+                               continue;       /* not in window range */
+                       }
+
+                       item = ListCoordinateToItem(wind, currentRow);
+
+                       if (item != previousItem) {
+                               /* Implement typical Mac multiple-selection behavior
+                                * (ie, not the UI implemented by the Finder)
+                                */
+                               Boolean itemIsSelected = (ListItemSelected(wind,item) >= 0);
+
+                               if (firstRow) {
+                                       /* this is first valid row, so major state is opposite of what this row is */
+                                       majorSelectState = !itemIsSelected;
+                                       firstRow = FALSE;
+                               }
+
+                               if (wind->how == PICK_ONE && previousItem != -1) {
+                                       /* if previous row was selected and we're only selecting one object,
+                                        * deselect previous row!
+                                        */
+                                       ToggleMenuListItemSelected(wind, previousItem);
+                                       ToggleMenuSelect(wind, previousRow);
+                                       previousItem = -1;
+                               }
+
+                               if (item == -1)
+                                       continue;       /* header line */
+                                       
+                               if (majorSelectState != itemIsSelected) {
+                                       ToggleMenuListItemSelected(wind, item);
+                                       ToggleMenuSelect(wind, currentRow);
+                               }
+
+                               previousRow             = currentRow;
+                               previousItem    = item;
+                       }
+               } while (StillDown());
+
+               /* Dismiss window if only picking one item */
+               if (wind->how == PICK_ONE)
+                       AddToKeyQueue(CHAR_CR, 1);
+       }
+       return;
+}
+
+
+static void
+MenwUpdate(NhWindow *wind)
+{
+       int i, line;
+       MacMHMenuItem *mi;
+
+
+       TextUpdate(wind);
+       HLock((Handle) wind->menuInfo);
+       HLock((Handle) wind->menuSelected);
+       for (i = 0; i < wind->miSelLen; i++) {
+               mi = &(*wind->menuInfo)[(*wind->menuSelected)[i]];
+               line = mi->line;
+               if (line > wind->scrollPos && line <= wind->y_size)
+                       ToggleMenuSelect(wind, line - wind->scrollPos);
+       }
+       HUnlock((Handle) wind->menuInfo);
+       HUnlock((Handle) wind->menuSelected);
+       return;
+}
+
+
+#if TARGET_API_MAC_CARBON
+static pascal OSStatus
+MenwEvent(EventHandlerCallRef nexthandler, EventRef event, void *userdata)
+{
+       NhWindow *wind = (NhWindow *) userdata;
+
+
+       switch (GetEventClass(event)) {
+       case kEventClassControl: {
+               ControlRef control;
+               ControlID id;
+
+               switch (GetEventKind(event)) {
+               case kEventControlHit:
+                       GetEventParameter(event, kEventParamDirectObject,
+                               typeControlRef, NULL, sizeof(ControlRef), NULL, &control);
+                       GetControlID(control, &id);
+                       /* TODO... */
+                       return (noErr);
+               }
+               break;
+       }
+
+       case kEventClassKeyboard: {
+               char ch;
+               UInt32 modifiers;
+
+
+               GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL,
+                       sizeof(char), NULL, &ch);
+               GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL,
+                       sizeof(UInt32), NULL, &modifiers);
+               if (modifiers & cmdKey)
+                       return (eventNotHandledErr);
+               MenwKey(wind, ch);
+               return (noErr);
+       }
+
+       case kEventClassWindow:
+               switch (GetEventKind(event)) {
+               case kEventWindowDrawContent: 
+                       CallNextEventHandler(nexthandler, event);
+                       MenwUpdate(wind);
+                       return (noErr);
+
+               case kEventWindowHandleContentClick: {
+                       CGrafPtr saveport;
+                       GDHandle savedev;
+                       Point pt;
+
+                       GetEventParameter(event, kEventParamMouseLocation, typeQDPoint,
+                               NULL, sizeof(Point), NULL, &pt);
+                       GetGWorld(&saveport, &savedev);
+                       SetPortWindowPort(wind->its_window);
+                       GlobalToLocal(&pt);
+                       SetGWorld(saveport, savedev);
+                       MenwClick(wind, pt);
+                       return (noErr);
+               }
+
+               case kEventWindowClose:
+                       /* TODO... */
+                       break;
+               }
+               break;
+       }
+       return (eventNotHandledErr);
+}
+
+
+#else
+
+static void
+macKeyMenu (EventRecord *theEvent, WindowPtr theWindow) {
+       MenwKey(GetNhWin(theWindow), theEvent->message & 0xff);
+       return;
+}
+
+
+static void
+macClickMenu (EventRecord *theEvent, WindowRef theWindow) {
+       Point p;
+       NhWindow *aWin = GetNhWin(theWindow);
+
+
+       if (aWin->scrollBar && IsControlVisible(aWin->scrollBar)) {
+               short code;
+               ControlHandle theBar;
+
+               p = theEvent->where;
+               GlobalToLocal (&p);
+               code = FindControl (p, theWindow, &theBar);
+               if (code) {
+                       DoScrollBar (p, code, theBar, aWin);
+                       return;
+               }
+       }
+       MenwClick(aWin, theEvent->where);
+}
+
+
+static short 
+macUpdateMenu (EventRecord *theEvent, WindowPtr theWindow) {
+       MenwUpdate(GetNhWin(theWindow));
+       return 0;
+}
+
+#endif /* !TARGET_API_MAC_CARBON */
+
+
+
+/**********************************************************************
+ *     Text windows
+ */
+
+static void
+TextKey(NhWindow *wind, char ch)
+{
+       ch = filter_scroll_key(ch, wind);
+       if (!ch)
+               return;
+       if (inSelect == WIN_ERR && ClosingWindowChar(ch)) {
+               HideWindow (wind->its_window);
+               mac_destroy_nhwindow(wind - theWindows);
+       } else
+               AddToKeyQueue(topl_resp_key(ch), TRUE);
+       return;
+}
+
+
+static void
+TextUpdate(NhWindow *wind)
+{
+       Rect r, r2;
+       RgnHandle h;
+       Boolean vis;
+
+
+       GetWindowBounds(wind->its_window, kWindowContentRgn, &r);
+       OffsetRect(&r, -r.left, -r.top);
+       r2 = r;
+       r2.left = r2.right - SBARWIDTH;
+       r2.right += 1;
+       r2.top -= 1;
+       vis = (r2.bottom > r2.top + 50);
+
+       draw_growicon_vert_only(wind->its_window);
+       DrawControls(wind->its_window);
+
+       h = (RgnHandle) 0;
+       if (vis && (h = NewRgn())) {
+               RgnHandle tmp = NewRgn();
+               if (!tmp) {
+                       DisposeRgn(h);
+                       h = (RgnHandle) 0;
+               } else {
+                       GetClip(h);
+                       RectRgn(tmp, &r2);
+                       DiffRgn(h, tmp, tmp);
+                       SetClip(tmp);
+                       DisposeRgn(tmp);
+               }
+       }
+       if (r.right < MIN_RIGHT)
+               r.right = MIN_RIGHT;
+       r.top -= wind->scrollPos * wind->row_height;
+       r.right -= SBARWIDTH;
+       HLock(wind->windowText);
+       TETextBox(*wind->windowText, wind->windowTextLen, &r, teJustLeft);
+       HUnlock(wind->windowText);
+       if (h) {
+               SetClip(h);
+               DisposeRgn(h);
+       }
+       return;
+}
+
+
+#if TARGET_API_MAC_CARBON
+static pascal OSStatus
+TextEvent(EventHandlerCallRef nexthandler, EventRef event, void *userdata)
+{
+       NhWindow *wind = (NhWindow *) userdata;
+
+
+       switch (GetEventClass(event)) {
+       case kEventClassControl: {
+               ControlRef control;
+               ControlID id;
+
+               switch (GetEventKind(event)) {
+               case kEventControlHit:
+                       GetEventParameter(event, kEventParamDirectObject,
+                               typeControlRef, NULL, sizeof(ControlRef), NULL, &control);
+                       GetControlID(control, &id);
+                       /* TODO... */
+                       return (noErr);
+               }
+               break;
+       }
+
+       case kEventClassKeyboard: {
+               char ch;
+               UInt32 modifiers;
+
+
+               GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL,
+                       sizeof(char), NULL, &ch);
+               GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL,
+                       sizeof(UInt32), NULL, &modifiers);
+               if (modifiers & cmdKey)
+                       return (eventNotHandledErr);
+               TextKey(wind, ch);
+               return (noErr);
+       }
+
+       case kEventClassWindow:
+               switch (GetEventKind(event)) {
+               case kEventWindowDrawContent: 
+                       CallNextEventHandler(nexthandler, event);
+                       TextUpdate(wind);
+                       return (noErr);
+
+               case kEventWindowClose:
+                       /* TODO... */
+                       break;
+               }
+               break;
+       }
+       return (eventNotHandledErr);
+}
+
+
+#else
+
+static void
+macKeyText (EventRecord *theEvent, WindowPtr theWindow) {
+       TextKey(GetNhWin(theWindow), theEvent->message & 0xff);
+       return;
+}
+
+static void
+macClickText (EventRecord *theEvent, WindowPtr theWindow) {
+       NhWindow *aWin = GetNhWin (theWindow);
+
+       if (aWin->scrollBar && IsControlVisible(aWin->scrollBar)) {
+               short code;
+               Point p = theEvent->where;
+               ControlHandle theBar;
+
+               GlobalToLocal (&p);
+               code = FindControl (p, theWindow, &theBar);
+               if (code) {
+                       DoScrollBar (p, code, theBar, aWin);
+               }
+       }
+}
+
+#endif /* !TARGET_API_MAC_CARBON */
+
+
+
+/**********************************************************************
+ *     Global events
+ */
+
+#if TARGET_API_MAC_CARBON
+static pascal OSStatus
+GlobalEvent(EventHandlerCallRef nexthandler, EventRef event, void *userdata)
+{
+       switch (GetEventClass(event)) {
+       case kEventClassCommand:
+               return (eventNotHandledErr);
+       }
+       return (eventNotHandledErr);
+}
+
+
+#else
+
+static short
+macDoNull (EventRecord *theEvent, WindowPtr theWindow) {
+       return 0;
+}
+
+
+/*
+ * Note; theWindow may very well be null here, since keyDown may call
+ * it when theres no window !!!
+ */
+/* NOT_IN_CARBON */
+static void
+GeneralKey (EventRecord *theEvent, WindowPtr theWindow) {
+#if defined(__SC__) || defined(__MRC__)
+# pragma unused(theWindow)
+#endif
+#if 0
+       trans_num_keys (theEvent);
+#endif
+       AddToKeyQueue (topl_resp_key (theEvent->message & 0xff), TRUE);
+}
+
+
+static void
+HandleKey (EventRecord *theEvent) {
+       WindowPtr theWindow = FrontWindow ();
+
+       if (theEvent->modifiers & cmdKey) {
+               if (theEvent->message & 0xff == '.') {
+                       /* Flush key queue */
+                       keyQueueCount = keyQueueWrite = keyQueueRead = 0;
+                       theEvent->message = '\033';
+                       goto dispatchKey;
+               } else {
+                       UndimMenuBar ();
+                       DoMenuEvt (MenuKey (theEvent->message & 0xff));
+               }
+       } else {
+
+dispatchKey :
+               if (theWindow) {
+                       int kind = GetWindowKind(theWindow) - WIN_BASE_KIND;
+                       winKeyFuncs [kind] (theEvent, theWindow);
+               } else {
+                       GeneralKey (theEvent, (WindowPtr) 0);
+               }
+       }
+}
+
+
+#endif /* !TARGET_API_MAC_CARBON */
+
+
+static void
+HandleClick (EventRecord *theEvent) {
+       int code;
+       unsigned long l;
+       WindowPtr theWindow;
+       NhWindow *aWin;
+       Rect r;
+       Boolean not_inSelect;
+
+       InsetRect(GetRegionBounds(GetGrayRgn(), &r), 4, 4);
+
+       code = FindWindow (theEvent->where, &theWindow);
+       aWin = GetNhWin (theWindow);
+       not_inSelect = (inSelect == WIN_ERR || aWin - theWindows == inSelect);
+       
+       switch (code) {
+       case inContent :
+#if !TARGET_API_MAC_CARBON
+               if (not_inSelect) {
+                       int kind = GetWindowKind(theWindow) - WIN_BASE_KIND;
+                       winCursorFuncs [kind] (theEvent, theWindow, gMouseRgn);
+                       SelectWindow (theWindow);
+                       SetPortWindowPort(theWindow);
+                       winClickFuncs [kind] (theEvent, theWindow);
+               } else {
+                       nhbell ();
+               }
+#endif
+               break;
+
+       case inDrag :
+               if (not_inSelect) {
+                       SetCursor(&qdarrow);
+                       DragWindow (theWindow, theEvent->where, &r);
+                       SaveWindowPos(theWindow);
+               } else {
+                       nhbell ();
+               }
+               break;
+
+       case inGrow :
+               if (not_inSelect) {
+                       SetCursor(&qdarrow);
+                       SetRect (&r, 80, 2 * aWin->row_height + 1, r.right, r.bottom);
+                       if (aWin == theWindows + WIN_MESSAGE)
+                               r.top += SBARHEIGHT;
+                       l = GrowWindow (theWindow, theEvent->where, &r);
+                       SizeWindow (theWindow, l & 0xffff, l >> 16, FALSE);
+                       SaveWindowSize(theWindow);
+                       SetPortWindowPort(theWindow);
+                       GetWindowBounds(theWindow, kWindowContentRgn, &r);
+                       OffsetRect(&r, -r.left, -r.top);
+                       InvalWindowRect(theWindow, &r);
+                       if (aWin->scrollBar) {
+                               DrawScrollbar (aWin);
+                       }
+               } else {
+                       nhbell ();
+               }
+               break;
+
+       case inGoAway :
+               WindowGoAway(theEvent, theWindow);
+               break;
+
+       case inMenuBar :
+               DoMenuEvt (MenuSelect (theEvent->where));
+               break;
+
+#if !TARGET_API_MAC_CARBON
+       case inSysWindow :
+               SystemClick(theEvent, theWindow);
+#endif
+       default :
+               break;
+       }
+}
+
+
+#if !TARGET_API_MAC_CARBON
+
+static short
+GeneralUpdate (EventRecord *theEvent, WindowPtr theWindow) {
+       if (!theEvent)
+               return 0;
+       TextUpdate(GetNhWin(theWindow));
+       return 0;
+}
+
+#endif
+
+
+static void
+HandleUpdate (EventRecord *theEvent) {
+       WindowPtr theWindow = (WindowPtr) theEvent->message;
+       NhWindow *aWin = GetNhWin (theWindow);
+       Rect r;
+
+
+       char existing_update_region = FALSE;
+       Rect rect;
+       
+       if (theWindow == _mt_window) {
+               existing_update_region = (get_invalid_region (theWindow, &rect) == noErr);
+       }
+       BeginUpdate (theWindow);
+       SetPortWindowPort(theWindow);
+       GetWindowBounds(theWindow, kWindowContentRgn, &r);
+       OffsetRect(&r, -r.left, -r.top);
+       EraseRect(&r);
+#if TARGET_API_MAC_CARBON
+       switch (GetWindowKind(theWindow) - WIN_BASE_KIND) {
+       case NHW_BASE:
+       case NHW_MAP:
+       case NHW_STATUS:
+               image_tty(NULL, theWindow);
+               break;
+       case NHW_MESSAGE:
+               MsgUpdate(GetNhWin(theWindow));
+               break;
+       case NHW_MENU:
+               MenwUpdate(GetNhWin(theWindow));
+               break;
+       case NHW_TEXT:
+               TextUpdate(GetNhWin(theWindow));
+               break;
+       }
+#else
+       winUpdateFuncs [GetWindowKind(theWin) - WIN_BASE_KIND] (&fake, theWin);
+#endif
+
+       if (theWindow == _mt_window && existing_update_region) {
+               set_invalid_region (theWindow, &rect);
+       }
+       aWin->drawn = TRUE;
+       EndUpdate (theWindow);
+}
+
+
+#if !TARGET_API_MAC_CARBON
+
+static void
+GeneralCursor (EventRecord *theEvent, WindowPtr theWindow, RgnHandle mouseRgn) {
+#if defined(__SC__) || defined(__MRC__)
+# pragma unused(theWindow)
+#endif
+       Rect r = {-1, -1, 2, 2};
+
+       SetCursor(&qdarrow);
+       OffsetRect (&r, theEvent->where.h, theEvent->where.v);
+       RectRgn (mouseRgn, &r);
+}
+
+
+static void
+DoOsEvt (EventRecord *theEvent) {
+       WindowRef win;
+       short code;
+
+       if ((theEvent->message & 0xff000000) == 0xfa000000) {
+               /* Mouse Moved */
+
+               code = FindWindow (theEvent->where, &win);
+               if (code != inContent) {
+                       Rect r = {-1, -1, 2, 2};
+
+                       SetCursor(&qdarrow);
+                       OffsetRect (&r, theEvent->where.h, theEvent->where.v);
+                       RectRgn (gMouseRgn, &r);
+               } else {
+#if !TARGET_API_MAC_CARBON
+                       int kind = GetWindowKind(win) - WIN_BASE_KIND;
+                       if (kind >= 0 && kind <= NHW_TEXT) {
+                               winCursorFuncs [kind] (theEvent, win, gMouseRgn);
+                       }
+#endif
+               }
+       }
+}
+
+
+#endif /* !TARGET_API_MAC_CARBON */
+
+
+void
+HandleEvent (EventRecord *theEvent) {
+       switch (theEvent->what) {
+#if !TARGET_API_MAC_CARBON
+       case autoKey:
+       case keyDown:
+               HandleKey(theEvent);
+               break;
+#endif
+       case updateEvt:
+               HandleUpdate(theEvent);
+               break;
+       case mouseDown:
+               HandleClick(theEvent);
+               break;
+#if !TARGET_API_MAC_CARBON
+       case diskEvt:
+               if ((theEvent->message & 0xffff0000) != 0) {
+                       Point p = {150, 150};
+                       (void) DIBadMount(p, theEvent->message);
+               }
+               break;
+#endif
+#if !TARGET_API_MAC_CARBON
+       case osEvt:
+               DoOsEvt(theEvent);
+               break;
+#endif
+       case kHighLevelEvent:
+               AEProcessAppleEvent(theEvent);
+       default:
+               break;
+       }
+}
+
+
+
+/**********************************************************************
+ *     Interface definition, for windows.c
+ */
+
 struct window_procs mac_procs = {
        "mac",
        WC_COLOR | WC_HILITE_PET |