1 /* aNetHack 0.0.1 macwin.c $ANH-Date: 1432512796 2015/05/25 00:13:16 $ $ANH-Branch: master $:$ANH-Revision: 1.26 $ */
2 /* Copyright (c) Jon W{tte, Hao-Yang Wang, Jonathan Handler 1992. */
3 /* aNetHack may be freely redistributed. See license for details. */
5 /**********************************************************************
6 * Imported variables and functions
15 #if 1 /*!TARGET_API_MAC_CARBON*/
17 #include <AppleEvents.h>
19 #include <TextUtils.h>
21 #include <ControlDefinitions.h>
24 /**********************************************************************
25 * Local variables and functions
28 #if 0 // TARGET_API_MAC_CARBON
29 static EventTypeSpec baseevents
[] = {
30 { kEventClassKeyboard
, kEventRawKeyDown
},
31 { kEventClassKeyboard
, kEventRawKeyRepeat
},
32 { kEventClassMouse
, kEventMouseMoved
},
33 { kEventClassWindow
, kEventWindowDrawContent
},
34 { kEventClassWindow
, kEventWindowHandleContentClick
},
35 { kEventClassWindow
, kEventWindowClose
}
38 static EventTypeSpec msgevents
[] = {
39 { kEventClassControl
, kEventControlHit
},
40 { kEventClassKeyboard
, kEventRawKeyDown
},
41 { kEventClassKeyboard
, kEventRawKeyRepeat
},
42 { kEventClassWindow
, kEventWindowDrawContent
},
43 { kEventClassWindow
, kEventWindowHandleContentClick
},
44 { kEventClassWindow
, kEventWindowClose
}
47 static EventTypeSpec menwevents
[] = {
48 { kEventClassControl
, kEventControlHit
},
49 { kEventClassKeyboard
, kEventRawKeyDown
},
50 { kEventClassKeyboard
, kEventRawKeyRepeat
},
51 { kEventClassWindow
, kEventWindowDrawContent
},
52 { kEventClassWindow
, kEventWindowHandleContentClick
},
53 { kEventClassWindow
, kEventWindowClose
}
56 static EventTypeSpec textevents
[] = {
57 { kEventClassControl
, kEventControlHit
},
58 { kEventClassKeyboard
, kEventRawKeyDown
},
59 { kEventClassKeyboard
, kEventRawKeyRepeat
},
60 { kEventClassWindow
, kEventWindowDrawContent
},
61 { kEventClassWindow
, kEventWindowClose
}
64 static EventTypeSpec globalevents
[] = {
65 { kEventClassCommand
, kEventCommandProcess
}
68 EventTargetRef dispatcher
;
69 EventHandlerUPP baseupp
, msgupp
, menwupp
, textupp
;
71 static pascal OSStatus
BaseEvent(EventHandlerCallRef
, EventRef
, void *);
72 static void MsgUpdate(NhWindow
*wind
);
73 static pascal OSStatus
MsgEvent(EventHandlerCallRef
, EventRef
, void *);
74 static void MenwUpdate(NhWindow
*wind
);
75 static pascal OSStatus
MenwEvent(EventHandlerCallRef
, EventRef
, void *);
76 static void TextUpdate(NhWindow
*wind
);
77 static pascal OSStatus
TextEvent(EventHandlerCallRef
, EventRef
, void *);
78 static pascal OSStatus
GlobalEvent(EventHandlerCallRef
, EventRef
, void *);
82 static void FDECL(GeneralKey
, (EventRecord
*, WindowPtr
));
83 static void FDECL(macKeyMenu
, (EventRecord
*, WindowPtr
));
84 static void FDECL(macKeyText
, (EventRecord
*, WindowPtr
));
86 static void FDECL(macClickMessage
, (EventRecord
*, WindowPtr
));
87 static void FDECL(macClickTerm
, (EventRecord
*, WindowPtr
));
88 static void FDECL(macClickMenu
, (EventRecord
*, WindowPtr
));
89 static void FDECL(macClickText
, (EventRecord
*, WindowPtr
));
91 static short FDECL(macDoNull
, (EventRecord
*, WindowPtr
));
92 static short FDECL(macUpdateMessage
, (EventRecord
*, WindowPtr
));
93 static short FDECL(macUpdateMenu
, (EventRecord
*, WindowPtr
));
94 static short FDECL(GeneralUpdate
, (EventRecord
*, WindowPtr
));
96 static void FDECL(macCursorTerm
, (EventRecord
*, WindowPtr
, RgnHandle
));
97 static void FDECL(GeneralCursor
, (EventRecord
*, WindowPtr
, RgnHandle
));
100 static void TextUpdate(NhWindow
*wind
);
102 NhWindow
*theWindows
= (NhWindow
*) 0;
105 /* Borrowed from the Mac tty port */
106 extern WindowPtr _mt_window
;
108 /* Some useful #defines for the scroll bar width and height */
110 #define SBARHEIGHT 15
113 * We put a TE on the message window for the "top line" queries.
114 * top_line is the TE that holds both the query and the user's
115 * response. The first topl_query_len characters in top_line are
116 * the query, the rests are the response. topl_resp is the valid
117 * response to a yn query, while topl_resp[topl_def_idx] is the
118 * default response to a yn query.
120 static TEHandle top_line
= (TEHandle
) nil
;
121 static int topl_query_len
;
122 static int topl_def_idx
= -1;
123 static char topl_resp
[10] = "";
125 #define CHAR_ANY '\n'
128 * inSelect means we have a menu window up for selection or
129 * something similar. It makes the window with win number ==
130 * inSelect a movable modal (unfortunately without the border)
131 * and clicking the close box forces an RET into the key
132 * buffer. Don't forget to set inSelect to WIN_ERR when you're
135 static winid inSelect
= WIN_ERR
;
138 * The key queue ring buffer where Read is where to take from,
139 * Write is where next char goes and count is queue depth.
141 static unsigned char keyQueue
[QUEUE_LEN
];
142 static int keyQueueRead
= 0, keyQueueWrite
= 0, keyQueueCount
= 0;
144 static Boolean gClickedToMove
= 0; /* For ObscureCursor */
146 static Point clicked_pos
; /* For nh_poskey */
147 static int clicked_mod
;
148 static Boolean cursor_locked
= false;
150 static ControlActionUPP
151 MoveScrollUPP
; /* scrolling callback, init'ed in InitMac */
154 lock_mouse_cursor(Boolean new_cursor_locked
)
156 cursor_locked
= new_cursor_locked
;
160 * Add key to input queue, force means flush left and replace if full
163 AddToKeyQueue(unsigned char ch
, Boolean force
)
165 if (keyQueueCount
< QUEUE_LEN
) {
166 keyQueue
[keyQueueWrite
++] = ch
;
169 keyQueue
[keyQueueWrite
++] = ch
;
171 if (keyQueueRead
>= QUEUE_LEN
)
173 keyQueueCount
= QUEUE_LEN
;
175 if (keyQueueWrite
>= QUEUE_LEN
)
183 GetFromKeyQueue(void)
188 ret
= keyQueue
[keyQueueRead
++];
190 if (keyQueueRead
>= QUEUE_LEN
)
200 static RgnHandle gMouseRgn
= (RgnHandle
) 0;
203 * _Gestalt madness - we rely heavily on the _Gestalt glue, since we
204 * don't check for the trap...
209 * The screen layouts on the small 512x342 screen need special cares.
211 Boolean small_screen
= 0;
218 static int FDECL(filter_scroll_key
, (const int, NhWindow
*));
220 #if 1 //!TARGET_API_MAC_CARBON
221 static void FDECL(DoScrollBar
, (Point
, short, ControlHandle
, NhWindow
*));
223 static pascal void FDECL(MoveScrollBar
, (ControlHandle
, short));
225 #if 1 //!TARGET_API_MAC_CARBON
226 typedef void (*CbFunc
)(EventRecord
*, WindowPtr
);
227 typedef short (*CbUpFunc
)(EventRecord
*, WindowPtr
);
228 typedef void (*CbCursFunc
)(EventRecord
*, WindowPtr
, RgnHandle
);
231 static const CbFunc winKeyFuncs
[NUM_FUNCS
] = { GeneralKey
, GeneralKey
,
232 GeneralKey
, GeneralKey
,
233 macKeyMenu
, macKeyText
};
235 static const CbFunc winClickFuncs
[NUM_FUNCS
] = {
236 (CbFunc
) macDoNull
, macClickMessage
, macClickTerm
,
237 macClickTerm
, macClickMenu
, macClickText
240 static const CbUpFunc winUpdateFuncs
[NUM_FUNCS
] = {
241 macDoNull
, macUpdateMessage
, image_tty
,
242 image_tty
, macUpdateMenu
, GeneralUpdate
245 static const CbCursFunc winCursorFuncs
[NUM_FUNCS
] = {
246 (CbCursFunc
) macDoNull
, GeneralCursor
, macCursorTerm
,
247 macCursorTerm
, GeneralCursor
, GeneralCursor
252 GetNhWin(WindowPtr mac_win
)
254 if (mac_win
== _mt_window
) /* term window is still maintained by both
256 return theWindows
; /* WRefCon still refers to tty struct, so we have
259 NhWindow
*aWin
= (NhWindow
*) GetWRefCon(mac_win
);
260 if (aWin
>= theWindows
&& aWin
< &theWindows
[NUM_MACWINDOWS
])
263 return ((NhWindow
*) nil
);
267 CheckNhWin(WindowPtr mac_win
)
269 return GetNhWin(mac_win
) != nil
;
273 AppleEventHandler(const AppleEvent
*inAppleEvent
, AppleEvent
*outAEReply
,
276 #if defined(__SC__) || defined(__MRC__)
277 #pragma unused(outAEReply, inRefCon)
285 err
= AEGetAttributePtr(inAppleEvent
, keyEventIDAttr
, typeType
, &typeCode
,
286 &EventID
, sizeof(EventID
), &actualSize
);
290 case kAEOpenApplication
:
291 macFlags
.gotOpen
= 1;
293 case kAEPrintDocuments
:
294 err
= errAEEventNotHandled
;
296 case kAEQuitApplication
:
297 /* Flush key queue */
298 keyQueueCount
= keyQueueWrite
= keyQueueRead
= 0;
299 AddToKeyQueue('S', 1);
301 case kAEOpenDocuments
: {
306 long index
, itemsInList
;
308 if ((err
= AEGetParamDesc(inAppleEvent
, keyDirectObject
,
309 typeAEList
, &docList
)) != noErr
310 || (err
= AECountItems(&docList
, &itemsInList
)) != noErr
) {
311 if (err
== errAEDescNotFound
)
317 for (index
= 1; index
<= itemsInList
; index
++) {
318 err
= AEGetNthPtr(&docList
, index
, typeFSS
, &keywd
, &typeCode
,
319 (Ptr
) &fss
, sizeof(FSSpec
), &actualSize
);
323 err
= FSpGetFInfo(&fss
, &fndrInfo
);
327 if (fndrInfo
.fdType
!= SAVE_TYPE
)
328 continue; /* only look at save files */
330 process_openfile(fss
.vRefNum
, fss
.parID
, fss
.name
,
332 if (macFlags
.gotOpen
)
333 break; /* got our save file */
335 err
= AEDisposeDesc(&docList
);
341 /* Check to see if all required parameters for this type of event are
345 AEGetAttributePtr(inAppleEvent
, keyMissedKeywordAttr
,
346 typeWildCard
, &typeCode
, NULL
, 0, &actualSize
);
347 if (err
== errAEDescNotFound
)
348 err
= noErr
; /* got all the required parameters */
349 else if (err
== noErr
) /* missed a required parameter */
350 err
= errAEEventNotHandled
;
356 short win_fonts
[NHW_TEXT
+ 1];
365 #if !TARGET_API_MAC_CARBON
366 if (LMGetDefltStack() < 50 * 1024L) {
367 SetApplLimit((void *) ((long) LMGetCurStackBase() - (50 * 1024L)));
370 for (i
= 0; i
< 5; i
++)
373 InitGraf(&qd
.thePort
);
381 memset(&macFlags
, 0, sizeof(macFlags
));
382 if (!Gestalt(gestaltOSAttr
, &l
)) {
383 macFlags
.processes
= (l
& (1 << gestaltLaunchControl
)) ? 1 : 0;
384 macFlags
.tempMem
= (l
& (1 << gestaltRealTempMemory
)) ? 1 : 0;
385 macFlags
.hasDebugger
= (l
& (1 << gestaltSysDebuggerSupport
)) ? 1 : 0;
387 if (!Gestalt(gestaltQuickdrawVersion
, &l
))
388 macFlags
.color
= (l
>= gestalt8BitQD
) ? 1 : 0;
390 if (!Gestalt(gestaltFindFolderAttr
, &l
))
391 macFlags
.folders
= (l
& (1 << gestaltFindFolderPresent
)) ? 1 : 0;
393 if (!Gestalt(gestaltHelpMgrAttr
, &l
))
394 macFlags
.help
= (l
& (1 << gestaltHelpMgrPresent
)) ? 1 : 0;
396 if (!Gestalt(gestaltFSAttr
, &l
))
397 macFlags
.fsSpec
= (l
& (1 << gestaltHasFSSpecCalls
)) ? 1 : 0;
399 if (!Gestalt(gestaltFontMgrAttr
, &l
))
400 macFlags
.trueType
= (l
& (1 << gestaltOutlineFonts
)) ? 1 : 0;
402 if (!Gestalt(gestaltAUXVersion
, &l
))
403 macFlags
.aux
= (l
>= 0x200) ? 1 : 0;
405 if (!Gestalt(gestaltAliasMgrAttr
, &l
))
406 macFlags
.alias
= (l
& (1 << gestaltAliasMgrPresent
)) ? 1 : 0;
408 if (!Gestalt(gestaltStandardFileAttr
, &l
))
409 macFlags
.standardFile
= (l
& (1 << gestaltStandardFile58
)) ? 1 : 0;
411 gMouseRgn
= NewRgn();
413 GetQDGlobalsArrow(&qdarrow
);
416 MoveScrollUPP
= NewControlActionUPP(MoveScrollBar
);
418 /* Set up base fonts for all window types */
419 GetFNum("\pHackFont", &i
);
422 win_fonts
[NHW_BASE
] = win_fonts
[NHW_MAP
] = win_fonts
[NHW_STATUS
] = i
;
423 GetFNum("\pPSHackFont", &i
);
426 win_fonts
[NHW_MESSAGE
] = i
;
427 win_fonts
[NHW_TEXT
] = kFontIDGeneva
;
430 if (!Gestalt(gestaltAppleEventsAttr
, &l
)
431 && (l
& (1L << gestaltAppleEventsPresent
))) {
432 if (AEInstallEventHandler(kCoreEventClass
, typeWildCard
,
433 NewAEEventHandlerUPP(AppleEventHandler
), 0,
438 #if TARGET_API_MAC_CARBON
439 HGetVol(volName
, &theDirs
.dataRefNum
, &theDirs
.dataDirID
);
442 * We should try to get this data from a rsrc, in the profile file
443 * the user double-clicked... This data should be saved with the
444 * save file in the resource fork, AND be saveable in "stationary"
446 GetVol(volName
, &theDirs
.dataRefNum
);
447 GetWDInfo(theDirs
.dataRefNum
, &theDirs
.dataRefNum
, &theDirs
.dataDirID
,
452 for (l
= 1; l
<= volName
[0]; l
++) {
453 if (volName
[l
] == ':') {
459 BlockMove(volName
, theDirs
.dataName
, l
);
460 BlockMove(volName
, theDirs
.saveName
, l
);
461 BlockMove(volName
, theDirs
.levelName
, l
);
462 theDirs
.saveRefNum
= theDirs
.levelRefNum
= theDirs
.dataRefNum
;
463 theDirs
.saveDirID
= theDirs
.levelDirID
= theDirs
.dataDirID
;
465 /* Create the "record" file, if necessary */
466 check_recordfile("");
468 #if 0 // TARGET_API_MAC_CARBON
469 /* Create event handler universal procedure pointers */
470 dispatcher
= GetEventDispatcherTarget();
471 baseupp
= NewEventHandlerUPP(BaseEvent
);
472 msgupp
= NewEventHandlerUPP(MsgEvent
);
473 menwupp
= NewEventHandlerUPP(MenwEvent
);
474 textupp
= NewEventHandlerUPP(TextEvent
);
475 InstallApplicationEventHandler(NewEventHandlerUPP(GlobalEvent
),
476 sizeof(globalevents
)/sizeof(EventTypeSpec
), globalevents
, NULL
, NULL
);
482 * Change default window fonts.
485 set_tty_font_name(int window_type
, char *font_name
)
490 if (window_type
< NHW_BASE
|| window_type
> NHW_TEXT
)
491 return general_failure
;
493 C2P(font_name
, new_font
);
494 GetFNum(new_font
, &(fnum
));
496 return general_failure
;
497 win_fonts
[window_type
] = fnum
;
502 DrawScrollbar(NhWindow
*aWin
)
504 WindowPtr theWindow
= aWin
->its_window
;
507 short val
, lin
, win_height
;
509 if (!aWin
->scrollBar
)
511 GetControlBounds(aWin
->scrollBar
, &crect
);
512 GetWindowBounds(aWin
->its_window
, kWindowContentRgn
, &wrect
);
513 OffsetRect(&wrect
, -wrect
.left
, -wrect
.top
);
514 win_height
= wrect
.bottom
- wrect
.top
;
516 if (crect
.top
!= wrect
.top
- 1 || crect
.left
!= wrect
.right
- SBARWIDTH
) {
517 MoveControl(aWin
->scrollBar
, wrect
.right
- SBARWIDTH
, wrect
.top
- 1);
519 if (crect
.bottom
!= wrect
.bottom
- SBARHEIGHT
520 || crect
.right
!= wrect
.right
+ 1) {
521 SizeControl(aWin
->scrollBar
, SBARWIDTH
+ 1,
522 win_height
- SBARHEIGHT
+ 2);
524 vis
= (win_height
> (50 + SBARHEIGHT
));
525 if (vis
!= IsControlVisible(aWin
->scrollBar
)) {
526 /* current status != control */
527 if (vis
) /* if visible, show */
528 ShowControl(aWin
->scrollBar
);
530 HideControl(aWin
->scrollBar
);
533 if (aWin
== theWindows
+ WIN_MESSAGE
) {
534 /* calculate how big scroll bar is for message window */
535 lin
-= (win_height
- SBARHEIGHT
) / aWin
->row_height
;
538 val
= 0; /* always have message scrollbar active */
540 /* calculate how big scroll bar is for other windows */
541 lin
-= win_height
/ aWin
->row_height
;
545 val
= 0; /* if there are 1+ screen lines, activate scrollbar */
547 val
= 255; /* else grey it out */
549 SetControlMaximum(aWin
->scrollBar
, lin
);
550 HiliteControl(aWin
->scrollBar
, val
);
551 val
= GetControlValue(aWin
->scrollBar
);
552 if (val
!= aWin
->scrollPos
) {
553 InvalWindowRect(theWindow
, &wrect
);
554 aWin
->scrollPos
= val
;
558 #define MAX_HEIGHT 100
559 #define MIN_HEIGHT 50
560 #define MIN_WIDTH 300
563 * This function could be overloaded with any amount of intelligence...
568 #if TARGET_API_MAC_CARBON
570 SInt16 i
, width
, height
;
572 ConstrainWindowToScreen(_mt_window
, kWindowContentRgn
,
573 kWindowConstrainMoveRegardlessOfFit
, NULL
, NULL
);
574 GetWindowBounds(_mt_window
, kWindowContentRgn
, &rbase
);
575 if (RetrievePosition(kMapWindow
, &rbase
.top
, &rbase
.left
))
576 MoveWindow(_mt_window
, rbase
.left
, rbase
.top
, TRUE
);
578 GetWindowBounds(theWindows
[NHW_MESSAGE
].its_window
, kWindowContentRgn
,
580 height
= rmsg
.bottom
- rmsg
.top
;
581 rmsg
.top
= rbase
.bottom
+ 2;
582 rmsg
.bottom
= rmsg
.top
+ height
;
583 rmsg
.left
= rbase
.left
;
584 rmsg
.right
= rbase
.right
;
585 RetrievePosition(kMessageWindow
, &rmsg
.top
, &rmsg
.left
);
586 if (RetrieveSize(kMessageWindow
, rmsg
.top
, rmsg
.left
, &height
, &width
)) {
587 rmsg
.right
= rmsg
.left
+ width
;
588 rmsg
.bottom
= rmsg
.top
+ height
;
590 SetWindowBounds(theWindows
[NHW_MESSAGE
].its_window
, kWindowContentRgn
,
592 ConstrainWindowToScreen(theWindows
[NHW_MESSAGE
].its_window
,
594 kWindowConstrainMoveRegardlessOfFit
, NULL
, NULL
);
595 DrawScrollbar(&theWindows
[NHW_MESSAGE
]);
597 for (i
= 0; i
< NUM_MACWINDOWS
; i
++)
598 if (i
!= WIN_STATUS
&& i
!= WIN_MESSAGE
&& i
!= WIN_MAP
599 && i
!= BASE_WINDOW
&& theWindows
[i
].its_window
) {
601 ConstrainWindowToScreen(
602 theWindows
[i
].its_window
, kWindowContentRgn
,
603 kWindowConstrainMoveRegardlessOfFit
, NULL
, NULL
);
606 short left
, top
, width
, height
;
607 int ix
, numText
= 0, numMenu
= 0;
608 int mbar_height
= GetMBarHeight();
614 screenArea
= GetQDGlobalsScreenBits(&qbitmap
)->bounds
;
615 OffsetRect(&screenArea
, -screenArea
.left
, -screenArea
.top
);
618 height
= _mt_window
->portRect
.bottom
- _mt_window
->portRect
.top
;
619 width
= _mt_window
->portRect
.right
- _mt_window
->portRect
.left
;
621 if (!RetrievePosition(kMapWindow
, &top
, &left
)) {
622 top
= mbar_height
+ (small_screen
? 2 : 20);
623 left
= (screenArea
.right
- width
) / 2;
625 MoveWindow(_mt_window
, left
, top
, 1);
628 if (!RetrievePosition(kMessageWindow
, &top
, &left
)) {
634 if (!RetrieveSize(kMessageWindow
, top
, left
, &height
, &width
)) {
636 screenArea
.bottom
- top
- (small_screen
? 2 - SBARHEIGHT
: 2);
637 if (height
> MAX_HEIGHT
) {
639 } else if (height
< MIN_HEIGHT
) {
642 left
= screenArea
.right
- width
;
643 top
= screenArea
.bottom
- MIN_HEIGHT
;
647 /* Move these windows */
648 nhWin
= theWindows
+ WIN_MESSAGE
;
649 theWindow
= nhWin
->its_window
;
651 MoveWindow(theWindow
, left
, top
, 1);
652 SizeWindow(theWindow
, width
, height
, 1);
653 if (nhWin
->scrollBar
)
654 DrawScrollbar(nhWin
);
656 /* Handle other windows */
657 for (ix
= 0; ix
< NUM_MACWINDOWS
; ix
++) {
658 if (ix
!= WIN_STATUS
&& ix
!= WIN_MESSAGE
&& ix
!= WIN_MAP
659 && ix
!= BASE_WINDOW
) {
660 theWindow
= theWindows
[ix
].its_window
;
661 if (theWindow
&& ((WindowPeek
) theWindow
)->visible
) {
663 if (((WindowPeek
) theWindow
)->windowKind
664 == WIN_BASE_KIND
+ NHW_MENU
) {
665 if (!RetrievePosition(kMenuWindow
, &top
, &left
)) {
666 top
= mbar_height
* 2;
669 top
+= (numMenu
* mbar_height
);
673 if (!RetrievePosition(kTextWindow
, &top
, &left
)) {
674 top
= mbar_height
* 2;
675 left
= screenArea
.right
- 3
676 - (theWindow
->portRect
.right
677 - theWindow
->portRect
.left
);
679 top
+= (numText
* mbar_height
);
683 while (top
> screenArea
.bottom
- MIN_HEIGHT
) {
684 top
-= screenArea
.bottom
- mbar_height
* 2;
687 MoveWindow(theWindow
, left
, top
, 1);
696 mac_init_nhwindows(int *argcp
, char **argv
)
699 #if !TARGET_API_MAC_CARBON
700 Rect scr
= (*GetGrayRgn())->rgnBBox
;
702 scr
.bottom
- scr
.top
<= (iflags
.large_font
? 12 * 40 : 9 * 40);
707 theWindows
= (NhWindow
*) NewPtrClear(NUM_MACWINDOWS
* sizeof(NhWindow
));
709 error("mac_init_nhwindows: Couldn't allocate memory for windows.");
713 tty_init_nhwindows(argcp
, argv
);
714 iflags
.window_inited
= TRUE
;
716 /* Some ugly hacks to make both interfaces happy:
717 * Mac port uses both tty interface (for main map) and extra windows. The
719 * be kept in synch for both interfaces to map. Also, the "blocked"
720 * display_nhwindow case
721 * for the map automatically calls the tty interface for the message box,
723 * of the message box has to exist in the tty world to prevent a meltdown,
725 * messages are handled in mac window.
727 mac_create_nhwindow(NHW_BASE
);
728 tty_create_nhwindow(NHW_MESSAGE
);
730 #if 1 //!TARGET_API_MAC_CARBON
731 /* Resize and reposition the message window */
732 RetrievePosition(kMessageWindow
, &r
.top
, &r
.left
);
733 RetrieveSize(kMessageWindow
, r
.top
, r
.left
, &r
.bottom
, &r
.right
);
734 MoveWindow(theWindows
[NHW_MESSAGE
].its_window
, r
.left
, r
.top
, false);
735 SizeWindow(theWindows
[NHW_MESSAGE
].its_window
, r
.right
, r
.bottom
, true);
741 mac_create_nhwindow(int kind
)
747 if (kind
< NHW_BASE
|| kind
> NHW_TEXT
) {
748 error("cre_win: Invalid kind %d.", kind
);
752 for (i
= 0; i
< NUM_MACWINDOWS
; i
++) {
753 if (!theWindows
[i
].its_window
)
756 if (i
>= NUM_MACWINDOWS
) {
757 error("cre_win: Win full; freeing extras");
758 for (i
= 0; i
< NUM_MACWINDOWS
; i
++) {
759 if (IsWindowVisible(theWindows
[i
].its_window
) || i
== WIN_INVEN
760 || GetWindowKind(theWindows
[i
].its_window
)
761 != WIN_BASE_KIND
+ NHW_MENU
762 && GetWindowKind(theWindows
[i
].its_window
)
763 != WIN_BASE_KIND
+ NHW_TEXT
)
765 mac_destroy_nhwindow(i
);
768 error("cre_win: Out of ids!");
773 aWin
= &theWindows
[i
];
774 aWin
->windowTextLen
= 0L;
775 aWin
->scrollBar
= (ControlHandle
) 0;
777 aWin
->menuSelected
= 0;
780 aWin
->menuChar
= 'a';
782 dprintf("cre_win: New kind %d", kind
);
784 if (kind
== NHW_BASE
|| kind
== NHW_MAP
|| kind
== NHW_STATUS
) {
785 short x_sz
, x_sz_p
, y_sz
, y_sz_p
;
786 if (kind
!= NHW_BASE
) {
787 if (i
!= tty_create_nhwindow(kind
)) {
788 dprintf("cre_win: error creating kind %d", kind
);
790 if (kind
== NHW_MAP
) {
792 0; /* the message box is in a separate window */
795 aWin
->its_window
= _mt_window
;
796 get_tty_metrics(aWin
->its_window
, &x_sz
, &y_sz
, &x_sz_p
, &y_sz_p
,
797 &aWin
->font_number
, &aWin
->font_size
,
798 &aWin
->char_width
, &aWin
->row_height
);
799 #if 0 // TARGET_API_MAC_CARBON
800 InstallWindowEventHandler(aWin
->its_window
, baseupp
,
801 sizeof(baseevents
)/sizeof(EventTypeSpec
), baseevents
,
808 GetNewWindow(WIN_BASE_RES
+ kind
, (WindowPtr
) 0L, (WindowPtr
) -1L);
809 SetWindowKind(aWin
->its_window
, WIN_BASE_KIND
+ kind
);
810 SetWRefCon(aWin
->its_window
, (long) aWin
);
811 if (!(aWin
->windowText
= NewHandle(TEXT_BLOCK
))) {
812 error("cre_win: NewHandle fail(%ld)", (long) TEXT_BLOCK
);
813 DisposeWindow(aWin
->its_window
);
814 aWin
->its_window
= (WindowPtr
) 0;
817 aWin
->x_size
= aWin
->y_size
= 0;
818 aWin
->x_curs
= aWin
->y_curs
= 0;
820 mac_clear_nhwindow(i
);
821 #if 0 // TARGET_API_MAC_CARBON
824 InstallWindowEventHandler(aWin
->its_window
, msgupp
,
825 sizeof(msgevents
)/sizeof(EventTypeSpec
), msgevents
,
829 InstallWindowEventHandler(aWin
->its_window
, menwupp
,
830 sizeof(menwevents
)/sizeof(EventTypeSpec
), menwevents
,
834 InstallWindowEventHandler(aWin
->its_window
, textupp
,
835 sizeof(textevents
)/sizeof(EventTypeSpec
), textevents
,
841 SetPortWindowPort(aWin
->its_window
);
843 if (kind
== NHW_MESSAGE
) {
844 aWin
->font_number
= win_fonts
[NHW_MESSAGE
];
845 aWin
->font_size
= iflags
.wc_fontsiz_message
846 ? iflags
.wc_fontsiz_message
847 : iflags
.large_font
? 12 : 9;
849 const Rect out_of_scr
= { 10000, 10000, 10100, 10100 };
850 TextFont(aWin
->font_number
);
851 TextSize(aWin
->font_size
);
853 top_line
= TENew(&out_of_scr
, &out_of_scr
);
854 TEActivate(top_line
);
858 aWin
->font_number
= win_fonts
[NHW_TEXT
];
859 aWin
->font_size
= iflags
.wc_fontsiz_text
? iflags
.wc_fontsiz_text
: 9;
862 TextFont(aWin
->font_number
);
863 TextSize(aWin
->font_size
);
866 aWin
->ascent_height
= fi
.ascent
+ fi
.leading
;
867 aWin
->row_height
= aWin
->ascent_height
+ fi
.descent
;
868 aWin
->char_width
= fi
.widMax
;
870 if (kind
== NHW_MENU
|| kind
== NHW_TEXT
|| kind
== NHW_MESSAGE
) {
873 GetWindowBounds(aWin
->its_window
, kWindowContentRgn
, &r
);
874 r
.right
-= (r
.left
- 1);
875 r
.left
= r
.right
- SBARWIDTH
;
876 r
.bottom
-= (r
.top
+ SBARHEIGHT
);
879 NewControl(aWin
->its_window
, &r
, "\p", (r
.bottom
> r
.top
+ 50), 0,
887 mac_clear_nhwindow(winid win
)
891 NhWindow
*aWin
= &theWindows
[win
];
892 WindowPtr theWindow
= aWin
->its_window
;
894 if (win
< 0 || win
>= NUM_MACWINDOWS
|| !theWindow
) {
895 error("clr_win: Invalid win %d.", win
);
898 if (theWindow
== _mt_window
) {
899 tty_clear_nhwindow(win
);
905 SetPortWindowPort(theWindow
);
906 GetWindowBounds(theWindow
, kWindowContentRgn
, &r
);
907 OffsetRect(&r
, -r
.left
, -r
.top
);
909 r
.right
-= SBARWIDTH
;
911 switch (GetWindowKind(theWindow
) - WIN_BASE_KIND
) {
914 == aWin
->y_size
- 1) /* if no change since last clear */
915 return; /* don't bother with redraw */
916 r
.bottom
-= SBARHEIGHT
;
917 for (l
= 0; aWin
->y_size
> iflags
.msg_history
;) {
918 const char cr
= CHAR_CR
;
919 l
= Munger(aWin
->windowText
, l
, &cr
, 1, nil
, 0) + 1;
923 aWin
->windowTextLen
-= l
;
924 BlockMove(*aWin
->windowText
+ l
, *aWin
->windowText
,
925 aWin
->windowTextLen
);
927 aWin
->last_more_lin
= aWin
->y_size
;
928 aWin
->save_lin
= aWin
->y_size
;
929 aWin
->scrollPos
= aWin
->y_size
? aWin
->y_size
- 1 : 0;
932 if (aWin
->menuInfo
) {
933 DisposeHandle((Handle
) aWin
->menuInfo
);
934 aWin
->menuInfo
= NULL
;
936 if (aWin
->menuSelected
) {
937 DisposeHandle((Handle
) aWin
->menuSelected
);
938 aWin
->menuSelected
= NULL
;
940 aWin
->menuChar
= 'a';
946 SetHandleSize(aWin
->windowText
, TEXT_BLOCK
);
947 aWin
->windowTextLen
= 0L;
953 if (aWin
->scrollBar
) {
954 SetControlMaximum(aWin
->scrollBar
, aWin
->y_size
);
955 SetControlValue(aWin
->scrollBar
, aWin
->scrollPos
);
960 InvalWindowRect(theWindow
, &r
);
964 ClosingWindowChar(const int c
)
966 return (c
== CHAR_ESC
|| c
== CHAR_BLANK
|| c
== CHAR_LF
|| c
== CHAR_CR
);
974 GetWindowBounds(theWindows
[WIN_MESSAGE
].its_window
, kWindowContentRgn
,
976 OffsetRect(&rect
, -rect
.left
, -rect
.top
);
977 return (WIN_MESSAGE
!= WIN_ERR
&& top_line
978 && (*top_line
)->viewRect
.left
< rect
.right
);
983 #define BTN_H (SBARHEIGHT - 3)
986 topl_resp_rect(int resp_idx
, Rect
*r
)
990 GetWindowBounds(theWindows
[WIN_MESSAGE
].its_window
, kWindowContentRgn
,
992 OffsetRect(&rect
, -rect
.left
, -rect
.top
);
993 r
->left
= (BTN_IND
+ BTN_W
) * resp_idx
+ BTN_IND
;
994 r
->right
= r
->left
+ BTN_W
;
995 r
->bottom
= rect
.bottom
- 1;
996 r
->top
= r
->bottom
- BTN_H
;
1001 enter_topl_mode(char *query
)
1006 putstr(WIN_MESSAGE
, ATR_BOLD
, query
);
1008 topl_query_len
= strlen(query
);
1009 (*top_line
)->selStart
= topl_query_len
;
1010 (*top_line
)->selEnd
= topl_query_len
;
1011 (*top_line
)->viewRect
.left
= 0;
1012 PtrToXHand(query
, (*top_line
)->hText
, topl_query_len
);
1013 TECalText(top_line
);
1016 mac_display_nhwindow(WIN_MESSAGE
, FALSE
);
1020 leave_topl_mode(char *answer
)
1022 /*unsigned*/ char *ap
, *bp
;
1024 int ans_len
= (*top_line
)->teLength
- topl_query_len
;
1025 NhWindow
*aWin
= theWindows
+ WIN_MESSAGE
;
1027 if (!in_topl_mode())
1030 /* Cap length of reply */
1031 if (ans_len
>= BUFSZ
)
1032 ans_len
= BUFSZ
- 1;
1034 /* remove unprintables from the answer */
1035 for (ap
= *(*top_line
)->hText
+ topl_query_len
, bp
= answer
; ans_len
> 0;
1037 if (*ap
>= ' ' && *ap
< 128) {
1043 if (aWin
->windowTextLen
1044 && (*aWin
->windowText
)[aWin
->windowTextLen
- 1] == CHAR_CR
) {
1045 --aWin
->windowTextLen
;
1048 putstr(WIN_MESSAGE
, ATR_BOLD
, answer
);
1050 (*top_line
)->viewRect
.left
+= 10000;
1055 * TESetSelect flushes out all the pending key strokes. I hate it.
1058 topl_set_select(short selStart
, short selEnd
)
1060 TEDeactivate(top_line
);
1061 (*top_line
)->selStart
= selStart
;
1062 (*top_line
)->selEnd
= selEnd
;
1063 TEActivate(top_line
);
1067 topl_replace(char *new_ans
)
1069 topl_set_select(topl_query_len
, (*top_line
)->teLength
);
1071 TEInsert(new_ans
, strlen(new_ans
), top_line
);
1075 topl_key(unsigned char ch
, Boolean ext
)
1079 topl_replace("\x1b");
1086 mac_doprev_message();
1088 case '\x1e' /* up arrow */:
1092 case '\x1c' /* left arrow */:
1093 if ((*top_line
)->selEnd
<= topl_query_len
)
1100 TEKey(ch
, top_line
);
1102 int com_index
= -1, oindex
= 0;
1103 while (extcmdlist
[oindex
].ef_txt
!= (char *) 0) {
1104 if (!strncmpi(*(*top_line
)->hText
+ topl_query_len
,
1105 extcmdlist
[oindex
].ef_txt
,
1106 (*top_line
)->teLength
- topl_query_len
)) {
1107 if (com_index
== -1) /* No matches yet*/
1109 else /* More than 1 match */ {
1117 topl_replace((char *) extcmdlist
[com_index
].ef_txt
);
1124 topl_flash_resp(int resp_idx
)
1126 unsigned long dont_care
;
1128 SetPortWindowPort(theWindows
[WIN_MESSAGE
].its_window
);
1129 topl_resp_rect(resp_idx
, &frame
);
1130 InsetRect(&frame
, 1, 1);
1132 Delay(GetDblTime() / 2, &dont_care
);
1137 topl_set_def(int new_def_idx
)
1140 SetPortWindowPort(theWindows
[WIN_MESSAGE
].its_window
);
1141 topl_resp_rect(topl_def_idx
, &frame
);
1142 InvalWindowRect(theWindows
[WIN_MESSAGE
].its_window
, &frame
);
1143 topl_def_idx
= new_def_idx
;
1144 topl_resp_rect(new_def_idx
, &frame
);
1145 InvalWindowRect(theWindows
[WIN_MESSAGE
].its_window
, &frame
);
1149 topl_set_resp(char *resp
, char def
)
1156 const char any_str
[2] = { CHAR_ANY
, '\0' };
1157 resp
= (char *) any_str
;
1161 SetPortWindowPort(theWindows
[WIN_MESSAGE
].its_window
);
1162 r_len1
= strlen(resp
);
1163 r_len
= strlen(topl_resp
);
1166 topl_resp_rect(0, &frame
);
1167 frame
.right
= (BTN_IND
+ BTN_W
) * r_len
;
1168 InvalWindowRect(theWindows
[WIN_MESSAGE
].its_window
, &frame
);
1170 strcpy(topl_resp
, resp
);
1171 loc
= strchr(resp
, def
);
1172 topl_def_idx
= loc
? loc
- resp
: -1;
1176 topl_resp_key(char ch
)
1178 if (strlen(topl_resp
) > 0) {
1179 char *loc
= strchr(topl_resp
, ch
);
1182 if (ch
== '\x9' /* tab */) {
1183 topl_set_def(topl_def_idx
<= 0 ? strlen(topl_resp
) - 1
1184 : topl_def_idx
- 1);
1186 } else if (ch
== CHAR_ESC
) {
1187 loc
= strchr(topl_resp
, 'q');
1189 loc
= strchr(topl_resp
, 'n');
1190 if (!loc
&& topl_def_idx
>= 0)
1191 loc
= topl_resp
+ topl_def_idx
;
1193 } else if (ch
== (0x1f & 'P')) {
1194 mac_doprev_message();
1196 } else if (topl_def_idx
>= 0) {
1197 if (ch
== CHAR_ENTER
|| ch
== CHAR_CR
|| ch
== CHAR_LF
1199 || topl_resp
[topl_def_idx
] == CHAR_ANY
)
1200 loc
= topl_resp
+ topl_def_idx
;
1202 else if (strchr(topl_resp
, '#')) {
1204 topl_set_def(strchr(topl_resp
, '#') - topl_resp
);
1205 TEKey(ch
, top_line
);
1208 } else if (topl_resp
[topl_def_idx
] == '#') {
1209 if (ch
== '\x1e' /* up arrow */) {
1210 topl_set_select(topl_query_len
, topl_query_len
);
1212 } else if (ch
== '\x1d' /* right arrow */
1213 || ch
== '\x1f' /* down arrow */
1215 || ch
== '\x1c' /* left arrow */
1216 && (*top_line
)->selEnd
1218 TEKey(ch
, top_line
);
1227 topl_flash_resp(loc
- topl_resp
);
1228 if (*loc
!= CHAR_ANY
)
1230 TEKey(ch
, top_line
);
1238 adjust_window_pos(NhWindow
*aWin
, short width
, short height
)
1240 WindowRef theWindow
= aWin
->its_window
;
1241 #if TARGET_API_MAC_CARBON
1244 GetWindowBounds(theWindow
, kWindowContentRgn
, &r
);
1245 RetrieveWinPos(theWindow
, &r
.top
, &r
.left
);
1246 MoveWindow(theWindow
, r
.left
, r
.top
, false);
1247 SizeWindow(theWindow
, width
, height
, true);
1248 ConstrainWindowToScreen(theWindow
, kWindowStructureRgn
,
1249 kWindowConstrainMayResize
1250 | kWindowConstrainMoveRegardlessOfFit
,
1253 Rect scr_r
= (*GetGrayRgn())->rgnBBox
;
1254 const Rect win_ind
= { 2, 2, 3, 3 };
1255 const short min_w
= theWindow
->portRect
.right
- theWindow
->portRect
.left
,
1257 scr_r
.right
- scr_r
.left
- win_ind
.left
- win_ind
.right
;
1261 SetPortWindowPort(theWindow
);
1262 if (!RetrieveWinPos(theWindow
, &pos
.v
, &pos
.h
)) {
1263 pos
.v
= 0; /* take window's existing position */
1265 LocalToGlobal(&pos
);
1268 max_h
= scr_r
.bottom
- win_ind
.bottom
- pos
.v
;
1271 if (height
< MIN_HEIGHT
)
1272 height
= MIN_HEIGHT
;
1277 SizeWindow(theWindow
, width
, height
, true);
1279 if (pos
.v
+ height
+ win_ind
.bottom
> scr_r
.bottom
)
1280 pos
.v
= scr_r
.bottom
- height
- win_ind
.bottom
;
1281 if (pos
.h
+ width
+ win_ind
.right
> scr_r
.right
)
1282 pos
.h
= scr_r
.right
- width
- win_ind
.right
;
1283 MoveWindow(theWindow
, pos
.h
, pos
.v
, false);
1285 if (aWin
->scrollBar
)
1286 DrawScrollbar(aWin
);
1291 * display/select/update the window.
1292 * If f is true, this window should be "modal" - don't return
1293 * until presumed seen.
1296 mac_display_nhwindow(winid win
, BOOLEAN_P f
)
1298 NhWindow
*aWin
= &theWindows
[win
];
1299 WindowPtr theWindow
= aWin
->its_window
;
1301 if (win
< 0 || win
>= NUM_MACWINDOWS
|| !theWindow
) {
1302 error("disp_win: Invalid window %d.", win
);
1306 if (theWindow
== _mt_window
) {
1307 tty_display_nhwindow(win
, f
);
1311 if (f
&& inSelect
== WIN_ERR
&& win
== WIN_MESSAGE
) {
1312 topl_set_resp((char *) 0, 0);
1313 if (aWin
->windowTextLen
> 0
1314 && (*aWin
->windowText
)[aWin
->windowTextLen
- 1] == CHAR_CR
) {
1315 --aWin
->windowTextLen
;
1318 putstr(win
, flags
.standout
? ATR_INVERSE
: ATR_NONE
, " --More--");
1321 if (!IsWindowVisible(theWindow
)) {
1322 if (win
!= WIN_MESSAGE
)
1323 adjust_window_pos(aWin
, aWin
->x_size
+ SBARWIDTH
+ 1,
1324 aWin
->y_size
* aWin
->row_height
);
1326 SelectWindow(theWindow
);
1327 ShowWindow(theWindow
);
1330 if (f
&& inSelect
== WIN_ERR
) {
1337 } while (!ClosingWindowChar(ch
));
1341 if (win
== WIN_MESSAGE
)
1342 topl_set_resp("", '\0');
1344 HideWindow(theWindow
);
1349 mac_destroy_nhwindow(winid win
)
1351 WindowPtr theWindow
;
1352 NhWindow
*aWin
= &theWindows
[win
];
1355 if (win
< 0 || win
>= NUM_MACWINDOWS
) {
1356 if (iflags
.window_inited
)
1357 error("dest_win: Invalid win %d.", win
);
1360 theWindow
= aWin
->its_window
;
1362 error("dest_win: Not allocated win %d.", win
);
1367 * Check special windows. The base window should never go away.
1368 * Other "standard" windows should not go away unless we've exitted
1371 if (theWindow
== _mt_window
) {
1374 if (win
== WIN_INVEN
|| win
== WIN_MESSAGE
) {
1375 if (iflags
.window_inited
) {
1376 if (flags
.tombstone
&& killer
[0]) {
1377 /* Prepare for the coming of the tombstone window. */
1378 win_fonts
[NHW_TEXT
] = kFontIDMonaco
;
1382 if (win
== WIN_MESSAGE
)
1383 WIN_MESSAGE
= WIN_ERR
;
1386 kind
= GetWindowKind(theWindow
) - WIN_BASE_KIND
;
1388 if ((!IsWindowVisible(theWindow
)
1389 || (kind
!= NHW_MENU
&& kind
!= NHW_TEXT
))) {
1390 DisposeWindow(theWindow
);
1391 if (aWin
->windowText
) {
1392 DisposeHandle(aWin
->windowText
);
1394 aWin
->its_window
= (WindowPtr
) 0;
1395 aWin
->windowText
= (Handle
) 0;
1400 mac_number_pad(int pad
)
1402 #if defined(__SC__) || defined(__MRC__)
1409 trans_num_keys(EventRecord
*theEvent
)
1411 #if defined(__SC__) || defined(__MRC__)
1412 #pragma unused(theEvent)
1414 /* KMH -- Removed this translation.
1415 * Number pad keys should always emit digit characters.
1416 * That's consistent with the default MacOS behavior.
1417 * The number_pad option controls how digits are interpreted.
1421 Handle h
= GetResource('Nump', theEvent
->modifiers
& shiftKey
? 129 : 128);
1423 short inkey
= (theEvent
->message
& keyCodeMask
), *ab
= (short *)*h
;
1426 if (inkey
== (ab
[i
] & keyCodeMask
)) {
1427 theEvent
->message
= ab
[i
];
1437 * Routine used to select and de-select elements in a menu window, used by
1439 * ClickMenu, and UpdateMenu. Takes the NhWindow and a line ref relative to
1443 ToggleMenuSelect(NhWindow
*aWin
, int line
)
1447 GetWindowBounds(aWin
->its_window
, kWindowContentRgn
, &r
);
1448 OffsetRect(&r
, -r
.left
, -r
.top
);
1449 if (aWin
->scrollBar
)
1450 r
.right
-= SBARWIDTH
;
1451 r
.top
= line
* aWin
->row_height
;
1452 r
.bottom
= r
.top
+ aWin
->row_height
;
1454 LMSetHiliteMode((UInt8
)(LMGetHiliteMode() & 0x7F));
1459 * Check to see if given item is selected, return index if it is
1462 ListItemSelected(NhWindow
*aWin
, int item
)
1466 HLock((char **) aWin
->menuSelected
);
1467 /* Find item in selection list */
1468 for (i
= aWin
->miSelLen
- 1; i
>= 0; i
--) {
1469 if ((*aWin
->menuSelected
)[i
] == item
)
1472 HUnlock((char **) aWin
->menuSelected
);
1477 * Add item to selection list if it's not selected already
1478 * If it is selected already, remove it from the list.
1481 ToggleMenuListItemSelected(NhWindow
*aWin
, short item
)
1483 int i
= ListItemSelected(aWin
, item
);
1485 HLock((char **) aWin
->menuSelected
);
1486 if (i
< 0) { /* not there, so add */
1487 (*aWin
->menuSelected
)[aWin
->miSelLen
] = item
;
1489 } else { /* there, so remove */
1490 short *mi
= &(*aWin
->menuSelected
)[i
];
1492 memcpy(mi
, mi
+ 1, (aWin
->miSelLen
- i
) * sizeof(short));
1494 HUnlock((char **) aWin
->menuSelected
);
1498 * Find menu item in list given a line number on the window
1501 ListCoordinateToItem(NhWindow
*aWin
, short Row
)
1506 HLock((char **) aWin
->menuInfo
);
1507 for (i
= 0, mi
= *aWin
->menuInfo
; i
< aWin
->miLen
; i
++, mi
++) {
1508 if (mi
->line
== Row
+ aWin
->scrollPos
) {
1513 HUnlock((char **) aWin
->menuInfo
);
1518 MoveScrollBar(ControlHandle theBar
, short part
)
1520 #if 1 //!TARGET_API_MAC_CARBON
1525 int now
, amtToScroll
;
1527 NhWindow
*winToScroll
;
1532 theWin
= GetControlOwner(theBar
);
1533 GetWindowBounds(theWin
, kWindowContentRgn
, &r
);
1534 OffsetRect(&r
, -r
.left
, -r
.top
);
1535 winToScroll
= (NhWindow
*) (GetWRefCon(theWin
));
1536 now
= GetControlValue(theBar
);
1538 if (part
== kControlPageUpPart
|| part
== kControlPageDownPart
)
1539 amtToScroll
= (r
.bottom
- r
.top
) / winToScroll
->row_height
;
1543 if (part
== kControlPageUpPart
|| part
== kControlUpButtonPart
) {
1544 int bound
= GetControlMinimum(theBar
);
1545 if (now
- bound
< amtToScroll
)
1546 amtToScroll
= now
- bound
;
1547 amtToScroll
= -amtToScroll
;
1549 int bound
= GetControlMaximum(theBar
);
1550 if (bound
- now
< amtToScroll
)
1551 amtToScroll
= bound
- now
;
1557 SetControlValue(theBar
, now
+ amtToScroll
);
1558 winToScroll
->scrollPos
= now
+ amtToScroll
;
1559 r
.right
-= SBARWIDTH
;
1560 if (winToScroll
== theWindows
+ WIN_MESSAGE
)
1561 r
.bottom
-= SBARHEIGHT
;
1563 ScrollRect(&r
, 0, -amtToScroll
* winToScroll
->row_height
, rgn
);
1565 InvalWindowRgn(theWin
, rgn
);
1566 BeginUpdate(theWin
);
1568 #if 0 // TARGET_API_MAC_CARBON
1569 switch (GetWindowKind(theWin
) - WIN_BASE_KIND
) {
1571 MsgUpdate(GetNhWin(theWin
));
1574 MenwUpdate(GetNhWin(theWin
));
1577 TextUpdate(GetNhWin(theWin
));
1581 winUpdateFuncs
[GetWindowKind(theWin
) - WIN_BASE_KIND
](&fake
, theWin
);
1589 #if 1 //!TARGET_API_MAC_CARBON
1591 DoScrollBar(Point p
, short code
, ControlHandle theBar
, NhWindow
*aWin
)
1593 ControlActionUPP func
= NULL
;
1596 if (code
== kControlUpButtonPart
|| code
== kControlPageUpPart
1597 || code
== kControlDownButtonPart
|| code
== kControlPageDownPart
)
1598 func
= MoveScrollUPP
;
1599 (void) TrackControl(theBar
, p
, func
);
1601 if (aWin
->scrollPos
!= GetControlValue(theBar
)) {
1602 aWin
->scrollPos
= GetControlValue(theBar
);
1603 GetWindowBounds(aWin
->its_window
, kWindowContentRgn
, &rect
);
1604 OffsetRect(&rect
, -rect
.left
, -rect
.top
);
1605 InvalWindowRect(aWin
->its_window
, &rect
);
1612 filter_scroll_key(const int ch
, NhWindow
*aWin
)
1615 && GetControlValue(aWin
->scrollBar
)
1616 < GetControlMaximum(aWin
->scrollBar
)) {
1618 if (ch
== CHAR_BLANK
) {
1619 part
= kControlPageDownPart
;
1620 } else if (ch
== CHAR_CR
|| ch
== CHAR_LF
) {
1621 part
= kControlDownButtonPart
;
1624 SetPortWindowPort(aWin
->its_window
);
1625 MoveScrollBar(aWin
->scrollBar
, part
);
1633 mac_doprev_message(void)
1636 NhWindow
*winToScroll
= &theWindows
[WIN_MESSAGE
];
1637 mac_display_nhwindow(WIN_MESSAGE
, FALSE
);
1638 SetPortWindowPort(winToScroll
->its_window
);
1639 MoveScrollBar(winToScroll
->scrollBar
, kControlUpButtonPart
);
1645 draw_growicon_vert_only(WindowPtr wind
)
1648 RgnHandle org_clip
= NewRgn();
1652 SetPortWindowPort(wind
);
1654 GetWindowBounds(wind
, kWindowContentRgn
, &r
);
1655 OffsetRect(&r
, -r
.left
, -r
.top
);
1656 r
.left
= r
.right
- SBARWIDTH
;
1660 DisposeRgn(org_clip
);
1666 WindowGoAway(EventRecord
*theEvent
, WindowPtr theWindow
)
1668 NhWindow
*aWin
= GetNhWin(theWindow
);
1670 if (!theEvent
|| TrackGoAway(theWindow
, theEvent
->where
)) {
1671 if (aWin
- theWindows
== BASE_WINDOW
&& !iflags
.window_inited
) {
1672 AddToKeyQueue('\033', 1);
1674 HideWindow(theWindow
);
1675 if (aWin
- theWindows
!= inSelect
)
1676 mac_destroy_nhwindow(aWin
- theWindows
);
1677 else /* if this IS the inSelect window put a close char */
1678 AddToKeyQueue(CHAR_CR
,
1679 1); /* in queue to exit and maintain inSelect */
1685 mac_get_nh_event(void)
1687 EventRecord anEvent
;
1689 /* KMH -- Don't proceed if the window system isn't set up */
1690 if (!iflags
.window_inited
)
1693 #if TARGET_API_MAC_CARBON
1694 QDFlushPortBuffer(GetWindowPort(_mt_window
), NULL
);
1696 (void) WaitNextEvent(everyEvent
, &anEvent
, 1, gMouseRgn
);
1697 HandleEvent(&anEvent
);
1706 EventRecord anEvent
;
1708 #if 1 //!TARGET_API_MAC_CARBON
1709 /* We want to take care of keys in the buffer as fast as
1716 static char warn
= 0;
1718 doDawdle
= (in_topl_mode() ? GetCaretTime() : 120L);
1719 /* Since we have time, check memory */
1720 PurgeSpace(&total
, &contig
);
1721 if (contig
< 25000L || total
< 50000L) {
1723 pline("Low Memory!");
1733 #if TARGET_API_MAC_CARBON
1734 QDFlushPortBuffer(GetWindowPort(_mt_window
), NULL
);
1736 #if 0 // TARGET_API_MAC_CARBON
1739 if (ReceiveNextEvent(0, NULL
, kEventDurationForever
, TRUE
, &event
) == noErr
) {
1740 SendEventToEventTarget(event
, dispatcher
);
1741 ReleaseEvent(event
);
1744 (void) WaitNextEvent(everyEvent
, &anEvent
, doDawdle
, gMouseRgn
);
1745 HandleEvent(&anEvent
);
1747 ch
= GetFromKeyQueue();
1748 } while (!ch
&& !gClickedToMove
);
1750 if (!gClickedToMove
)
1764 mac_delay_output(void)
1766 long destTicks
= TickCount() + 1;
1768 while (TickCount() < destTicks
) {
1775 mac_cliparound(int x
, int y
)
1777 #if defined(__SC__) || defined(__MRC__)
1778 #pragma unused(x, y)
1785 mac_exit_nhwindows(const char *s
)
1788 tty_exit_nhwindows(s
);
1789 mac_destroy_nhwindow(WIN_MESSAGE
);
1790 mac_destroy_nhwindow(WIN_INVEN
);
1794 * Don't forget to decrease in_putstr before returning...
1797 mac_putstr(winid win
, int attr
, const char *str
)
1800 NhWindow
*aWin
= &theWindows
[win
];
1801 static char in_putstr
= 0;
1802 short newWidth
, maxWidth
;
1804 char *src
, *sline
, *dst
, ch
;
1806 if (win
< 0 || win
>= NUM_MACWINDOWS
|| !aWin
->its_window
) {
1807 error("putstr: Invalid win %d (Max %d).", win
, NUM_MACWINDOWS
, attr
);
1811 if (aWin
->its_window
== _mt_window
) {
1812 tty_putstr(win
, attr
, str
);
1822 SetPortWindowPort(aWin
->its_window
);
1823 GetWindowBounds(aWin
->its_window
, kWindowContentRgn
, &r
);
1824 OffsetRect(&r
, -r
.left
, -r
.top
);
1825 if (win
== WIN_MESSAGE
) {
1826 r
.right
-= SBARWIDTH
;
1827 r
.bottom
-= SBARHEIGHT
;
1829 && aWin
->last_more_lin
1830 <= aWin
->y_size
- (r
.bottom
- r
.top
) / aWin
->row_height
) {
1831 aWin
->last_more_lin
= aWin
->y_size
;
1832 mac_display_nhwindow(win
, TRUE
);
1837 * A "default" text window - uses TETextBox
1838 * We just add the text, without attributes for now
1840 len
= GetHandleSize(aWin
->windowText
);
1841 while (aWin
->windowTextLen
+ slen
+ 1 > len
) {
1842 len
= (len
> 2048) ? (len
+ 2048) : (len
* 2);
1843 SetHandleSize(aWin
->windowText
, len
);
1845 error("putstr: SetHandleSize");
1846 aWin
->windowTextLen
= 0L;
1853 len
= aWin
->windowTextLen
;
1854 dst
= *(aWin
->windowText
) + len
;
1855 sline
= src
= (char *) str
;
1856 maxWidth
= newWidth
= 0;
1857 for (ch
= *src
; ch
; ch
= *src
) {
1861 if (ch
== CHAR_CR
) {
1865 newWidth
= TextWidth(sline
, 0, src
- sline
);
1866 if (newWidth
> maxWidth
) {
1867 maxWidth
= newWidth
;
1869 sline
= src
+ 1; /* keep track of where new line begins */
1875 newWidth
= TextWidth(sline
, 0, src
- sline
);
1876 if (newWidth
> maxWidth
) {
1877 maxWidth
= newWidth
;
1880 aWin
->windowTextLen
+= slen
;
1882 if (ch
!= CHAR_CR
) {
1883 (*(aWin
->windowText
))[len
+ slen
] = CHAR_CR
;
1884 aWin
->windowTextLen
++;
1890 if (win
== WIN_MESSAGE
) {
1891 short min
= aWin
->y_size
- (r
.bottom
- r
.top
) / aWin
->row_height
;
1892 if (aWin
->scrollPos
< min
) {
1893 aWin
->scrollPos
= min
;
1894 SetControlMaximum(aWin
->scrollBar
, aWin
->y_size
);
1895 SetControlValue(aWin
->scrollBar
, min
);
1897 InvalWindowRect(aWin
->its_window
, &r
);
1898 } else /* Message has a fixed width, other windows base on content */
1899 if (maxWidth
> aWin
->x_size
)
1900 aWin
->x_size
= maxWidth
;
1905 mac_curs(winid win
, int x
, int y
)
1907 NhWindow
*aWin
= &theWindows
[win
];
1909 if (aWin
->its_window
== _mt_window
) {
1910 tty_curs(win
, x
, y
);
1914 SetPortWindowPort(aWin
->its_window
);
1915 MoveTo(x
* aWin
->char_width
,
1916 (y
* aWin
->row_height
) + aWin
->ascent_height
);
1922 mac_nh_poskey(int *a
, int *b
, int *c
)
1924 int ch
= mac_nhgetch();
1932 mac_start_menu(winid win
)
1934 HideWindow(theWindows
[win
].its_window
);
1935 mac_clear_nhwindow(win
);
1939 mac_add_menu(winid win
, int glyph
, const anything
*any
, CHAR_P menuChar
,
1940 CHAR_P groupAcc
, int attr
, const char *inStr
, int preselected
)
1942 #if defined(__SC__) || defined(__MRC__)
1943 #pragma unused(glyph)
1945 NhWindow
*aWin
= &theWindows
[win
];
1947 char locStr
[4 + BUFSZ
];
1948 MacMHMenuItem
*item
;
1953 if (any
->a_void
!= 0) {
1954 #define kMenuSizeBump 26
1955 if (!aWin
->miSize
) {
1956 aWin
->menuInfo
= (MacMHMenuItem
**) NewHandle(
1957 sizeof(MacMHMenuItem
) * kMenuSizeBump
);
1958 if (!aWin
->menuInfo
) {
1959 error("Can't alloc menu handle");
1962 aWin
->menuSelected
=
1963 (short **) NewHandle(sizeof(short) * kMenuSizeBump
);
1964 if (!aWin
->menuSelected
) {
1965 error("Can't alloc menu select handle");
1968 aWin
->miSize
= kMenuSizeBump
;
1971 if (aWin
->miLen
>= aWin
->miSize
) {
1972 SetHandleSize((Handle
) aWin
->menuInfo
,
1973 sizeof(MacMHMenuItem
)
1974 * (aWin
->miLen
+ kMenuSizeBump
));
1976 error("Can't resize menu handle");
1979 SetHandleSize((Handle
) aWin
->menuSelected
,
1980 sizeof(short) * (aWin
->miLen
+ kMenuSizeBump
));
1982 error("Can't resize menu select handle");
1985 aWin
->miSize
+= kMenuSizeBump
;
1988 if (menuChar
== 0) {
1989 if (('a' <= aWin
->menuChar
&& aWin
->menuChar
<= 'z')
1990 || ('A' <= aWin
->menuChar
&& aWin
->menuChar
<= 'Z')) {
1991 menuChar
= aWin
->menuChar
++;
1992 if (menuChar
== 'z')
1993 aWin
->menuChar
= 'A';
1997 Sprintf(locStr
, "%c - %s", (menuChar
? menuChar
: ' '), inStr
);
1999 HLock((char **) aWin
->menuInfo
);
2000 HLock((char **) aWin
->menuSelected
);
2001 (*aWin
->menuSelected
)[aWin
->miLen
] = preselected
;
2002 item
= &(*aWin
->menuInfo
)[aWin
->miLen
];
2005 item
->accelerator
= menuChar
;
2006 item
->groupAcc
= groupAcc
;
2007 item
->line
= aWin
->y_size
;
2008 HUnlock((char **) aWin
->menuInfo
);
2009 HUnlock((char **) aWin
->menuSelected
);
2013 putstr(win
, attr
, str
);
2017 * End a menu in this window, window must a type NHW_MENU.
2018 * str is a list of cancel characters (values that may be input)
2019 * morestr is a prompt to display, rather than the default.
2020 * str and morestr might be ignored by some ports.
2023 mac_end_menu(winid win
, const char *morestr
)
2026 NhWindow
*aWin
= &theWindows
[win
];
2031 SetWTitle(aWin
->its_window
, buf
);
2035 mac_select_menu(winid win
, int how
, menu_item
**selected_list
)
2038 NhWindow
*aWin
= &theWindows
[win
];
2039 WindowPtr theWin
= aWin
->its_window
;
2043 mac_display_nhwindow(win
, FALSE
);
2045 aWin
->how
= (short) how
;
2047 c
= map_menu_cmd(mac_nhgetch());
2048 if (c
== CHAR_ESC
) {
2049 /* deselect everything */
2052 } else if (ClosingWindowChar(c
)) {
2061 if (aWin
->miSelLen
) {
2064 *selected_list
= mp
=
2065 (menu_item
*) alloc(aWin
->miSelLen
* sizeof(menu_item
));
2066 HLock((char **) aWin
->menuInfo
);
2067 HLock((char **) aWin
->menuSelected
);
2068 for (c
= 0; c
< aWin
->miSelLen
; c
++) {
2069 mi
= &(*aWin
->menuInfo
)[(*aWin
->menuSelected
)[c
]];
2074 HUnlock((char **) aWin
->menuInfo
);
2075 HUnlock((char **) aWin
->menuSelected
);
2081 return aWin
->miSelLen
;
2087 mac_display_file(name
, complain
)
2088 const char *name
; /* not ANSI prototype because of boolean parameter */
2093 dlb
*fp
= dlb_fopen(name
, "r");
2096 long l
= dlb_fseek(fp
, 0, SEEK_END
);
2097 (void) dlb_fseek(fp
, 0, 0L);
2098 buf
= NewPtr(l
+ 1);
2100 l
= dlb_fread(buf
, 1, l
, fp
);
2103 win
= create_nhwindow(NHW_TEXT
);
2104 if (WIN_ERR
== win
) {
2106 error("Cannot make window.");
2108 putstr(win
, 0, buf
);
2109 display_nhwindow(win
, FALSE
);
2115 } else if (complain
)
2116 error("Cannot open %s.", name
);
2122 display_file(PORT_HELP
, TRUE
);
2126 mac_unimplemented(void)
2131 mac_suspend_nhwindows(const char *foo
)
2133 #if defined(__SC__) || defined(__MRC__)
2136 /* Can't really do that :-) */
2140 try_key_queue(char *bufp
)
2142 if (keyQueueCount
) {
2144 for (ch
= GetFromKeyQueue();; ch
= GetFromKeyQueue()) {
2145 if (ch
== CHAR_LF
|| ch
== CHAR_CR
)
2156 /**********************************************************************
2161 BaseClick(NhWindow
*wind
, Point pt
, UInt32 modifiers
)
2163 pt
.h
= pt
.h
/ wind
->char_width
+ 1;
2164 pt
.v
= pt
.v
/ wind
->row_height
;
2165 clicked_mod
= (modifiers
& shiftKey
) ? CLICK_2
: CLICK_1
;
2167 if (strchr(topl_resp
, *click_to_cmd(pt
.h
, pt
.v
, clicked_mod
)))
2170 #if 1 //!TARGET_API_MAC_CARBON
2172 while (WaitMouseUp())
2176 gClickedToMove
= TRUE
;
2183 BaseCursor(NhWindow
*wind
, Point pt
)
2185 char *dir_bas
, *dir
;
2191 dir_bas
= (char *) Cmd
.dirchars
;
2193 strchr(dir_bas
, *click_to_cmd(pt
.h
/ wind
->char_width
+ 1,
2194 pt
.v
/ wind
->row_height
, CLICK_1
));
2196 ch
= GetCursor(dir
? dir
- dir_bas
+ 513 : 512);
2200 HUnlock((Handle
) ch
);
2202 SetCursor(&qdarrow
);
2207 #if 0 // TARGET_API_MAC_CARBON
2208 static pascal OSStatus
2209 BaseEvent(EventHandlerCallRef nexthandler
, EventRef event
, void *userdata
)
2211 NhWindow
*wind
= (NhWindow
*) userdata
;
2214 switch (GetEventClass(event
)) {
2215 case kEventClassKeyboard
: {
2220 GetEventParameter(event
, kEventParamKeyMacCharCodes
, typeChar
, NULL
,
2221 sizeof(char), NULL
, &ch
);
2222 GetEventParameter(event
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
2223 sizeof(UInt32
), NULL
, &modifiers
);
2224 if (modifiers
& cmdKey
)
2225 return (eventNotHandledErr
);
2226 AddToKeyQueue(topl_resp_key(ch
), TRUE
);
2230 case kEventClassMouse
: {
2235 switch (GetEventKind(event
)) {
2236 case kEventMouseMoved
:
2237 GetEventParameter(event
, kEventParamMouseLocation
, typeQDPoint
,
2238 NULL
, sizeof(Point
), NULL
, &pt
);
2239 GetGWorld(&saveport
, &savedev
);
2240 SetPortWindowPort(wind
->its_window
);
2242 SetGWorld(saveport
, savedev
);
2243 BaseCursor(wind
, pt
);
2244 return (eventNotHandledErr
);
2249 case kEventClassWindow
:
2250 switch (GetEventKind(event
)) {
2251 case kEventWindowDrawContent
:
2252 CallNextEventHandler(nexthandler
, event
);
2253 image_tty(NULL
, wind
->its_window
);
2256 case kEventWindowHandleContentClick
: {
2262 GetEventParameter(event
, kEventParamMouseLocation
, typeQDPoint
,
2263 NULL
, sizeof(Point
), NULL
, &pt
);
2264 GetEventParameter(event
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
2265 sizeof(UInt32
), NULL
, &modifiers
);
2266 GetGWorld(&saveport
, &savedev
);
2267 SetPortWindowPort(wind
->its_window
);
2269 SetGWorld(saveport
, savedev
);
2270 BaseClick(wind
, pt
, modifiers
);
2274 case kEventWindowClose
:
2280 return (eventNotHandledErr
);
2286 macClickTerm(EventRecord
*theEvent
, WindowPtr theWindow
)
2288 Point where
= theEvent
->where
;
2290 GlobalToLocal(&where
);
2291 BaseClick(GetNhWin(theWindow
), where
, theEvent
->modifiers
);
2296 macCursorTerm(EventRecord
*theEvent
, WindowPtr theWindow
, RgnHandle mouseRgn
)
2299 Point where
= theEvent
->where
;
2300 Rect r
= { 0, 0, 1, 1 };
2303 SetPortWindowPort(theWindow
);
2304 GlobalToLocal(&where
);
2305 BaseCursor(GetNhWin(theWindow
), where
);
2306 OffsetRect(&r
, theEvent
->where
.h
, theEvent
->where
.v
);
2307 RectRgn(mouseRgn
, &r
);
2312 #endif /* !TARGET_API_MAC_CARBON */
2314 /**********************************************************************
2318 /**********************************************************************
2322 /**********************************************************************
2327 MsgClick(NhWindow
*wind
, Point pt
)
2331 while (topl_resp
[r_idx
]) {
2333 topl_resp_rect(r_idx
, &frame
);
2334 InsetRect(&frame
, 1, 1);
2335 if (PtInRect(pt
, &frame
)) {
2336 Boolean in_btn
= true;
2339 while (WaitMouseUp()) {
2340 #if !TARGET_API_MAC_CARBON
2344 if (PtInRect(pt
, &frame
) != in_btn
) {
2351 AddToKeyQueue(topl_resp
[r_idx
], 1);
2361 MsgUpdate(NhWindow
*wind
)
2363 RgnHandle org_clip
= NewRgn(), clip
= NewRgn();
2368 GetWindowBounds(wind
->its_window
, kWindowContentRgn
, &r
);
2369 OffsetRect(&r
, -r
.left
, -r
.top
);
2371 DrawControls(wind
->its_window
);
2372 DrawGrowIcon(wind
->its_window
);
2374 for (l
= 0; topl_resp
[l
]; l
++) {
2376 unsigned char tmp
[2];
2379 topl_resp_rect(l
, &frame
);
2380 switch (topl_resp
[l
]) {
2401 tmp
[1] = topl_resp
[l
];
2405 TextFont(kFontIDGeneva
);
2408 MoveTo((frame
.left
+ frame
.right
- StringWidth(name
)) / 2,
2409 (frame
.top
+ frame
.bottom
+ font
.ascent
- font
.descent
2410 - font
.leading
- 1) / 2);
2413 if (l
== topl_def_idx
)
2415 FrameRoundRect(&frame
, 4, 4);
2418 r
.right
-= SBARWIDTH
;
2419 r
.bottom
-= SBARHEIGHT
;
2420 /* Clip to the portrect - scrollbar/growicon *before* adjusting the rect
2421 to be larger than the size of the window (!) */
2423 SectRgn(clip
, org_clip
, clip
);
2424 if (r
.right
< MIN_RIGHT
)
2425 r
.right
= MIN_RIGHT
;
2426 r
.top
-= wind
->scrollPos
* wind
->row_height
;
2429 /* If you enable this band of code (and disable the next band), you will get
2430 fewer flickers but a slower performance while drawing the dot line. */
2431 { RgnHandle dotl_rgn
= NewRgn();
2434 dotl
.right
= r
.right
;
2435 dotl
.bottom
= r
.top
+ aWin
->save_lin
* aWin
->row_height
;
2436 dotl
.top
= dotl
.bottom
- 1;
2437 FillRect(&dotl
, &qd
.gray
);
2438 RectRgn(dotl_rgn
, &dotl
);
2439 DiffRgn(clip
, dotl_rgn
, clip
);
2440 DisposeRgn(dotl_rgn
);
2445 if (in_topl_mode()) {
2446 RgnHandle topl_rgn
= NewRgn();
2448 topl_r
.top
+= (wind
->y_size
- 1) * wind
->row_height
;
2449 l
= (*top_line
)->destRect
.right
- (*top_line
)->destRect
.left
;
2450 (*top_line
)->viewRect
= topl_r
;
2451 (*top_line
)->destRect
= topl_r
;
2452 if (l
!= topl_r
.right
- topl_r
.left
)
2453 TECalText(top_line
);
2454 TEUpdate(&topl_r
, top_line
);
2455 RectRgn(topl_rgn
, &topl_r
);
2456 DiffRgn(clip
, topl_rgn
, clip
);
2457 DisposeRgn(topl_rgn
);
2463 TextFont(wind
->font_number
);
2464 TextSize(wind
->font_size
);
2465 HLock(wind
->windowText
);
2466 TETextBox(*wind
->windowText
, wind
->windowTextLen
, &r
, teJustLeft
);
2467 HUnlock(wind
->windowText
);
2469 #if !TARGET_API_MAC_CARBON
2470 r
.bottom
= r
.top
+ aWin
->save_lin
* aWin
->row_height
;
2471 r
.top
= r
.bottom
- 1;
2472 FillRect(&r
, (void *) &qd
.gray
);
2476 DisposeRgn(org_clip
);
2480 #if 0 // TARGET_API_MAC_CARBON
2481 static pascal OSStatus
2482 MsgEvent(EventHandlerCallRef nexthandler
, EventRef event
, void *userdata
)
2484 NhWindow
*wind
= (NhWindow
*) userdata
;
2487 switch (GetEventClass(event
)) {
2488 case kEventClassControl
: {
2492 switch (GetEventKind(event
)) {
2493 case kEventControlHit
:
2494 GetEventParameter(event
, kEventParamDirectObject
,
2495 typeControlRef
, NULL
, sizeof(ControlRef
), NULL
, &control
);
2496 GetControlID(control
, &id
);
2503 case kEventClassKeyboard
: {
2508 GetEventParameter(event
, kEventParamKeyMacCharCodes
, typeChar
, NULL
,
2509 sizeof(char), NULL
, &ch
);
2510 GetEventParameter(event
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
2511 sizeof(UInt32
), NULL
, &modifiers
);
2512 if (modifiers
& cmdKey
)
2513 return (eventNotHandledErr
);
2514 AddToKeyQueue(topl_resp_key(ch
), TRUE
);
2518 case kEventClassWindow
:
2519 switch (GetEventKind(event
)) {
2520 case kEventWindowDrawContent
:
2521 CallNextEventHandler(nexthandler
, event
);
2525 case kEventWindowHandleContentClick
: {
2530 GetEventParameter(event
, kEventParamMouseLocation
, typeQDPoint
,
2531 NULL
, sizeof(Point
), NULL
, &pt
);
2532 GetGWorld(&saveport
, &savedev
);
2533 SetPortWindowPort(wind
->its_window
);
2535 SetGWorld(saveport
, savedev
);
2540 case kEventWindowClose
:
2546 return (eventNotHandledErr
);
2552 macClickMessage(EventRecord
*theEvent
, WindowPtr theWindow
)
2554 Point mouse
= theEvent
->where
;
2556 GlobalToLocal(&mouse
);
2557 MsgClick(GetNhWin(theWindow
), mouse
);
2558 macClickText(theEvent
, theWindow
);
2562 macUpdateMessage(EventRecord
*theEvent
, WindowPtr theWindow
)
2566 MsgUpdate(GetNhWin(theWindow
));
2570 #endif /* !TARGET_API_MAC_CARBON */
2572 /**********************************************************************
2577 MenwKey(NhWindow
*wind
, char ch
)
2582 ch
= filter_scroll_key(ch
, wind
);
2585 if (ClosingWindowChar(ch
)) {
2586 AddToKeyQueue(CHAR_CR
, 1);
2590 if (!wind
|| !wind
->menuInfo
)
2592 HLock((char **) wind
->menuInfo
);
2593 for (i
= 0, mi
= *wind
->menuInfo
; i
< wind
->miLen
; i
++, mi
++) {
2594 if (mi
->accelerator
== ch
) {
2595 ToggleMenuListItemSelected(wind
, i
);
2596 if (mi
->line
>= wind
->scrollPos
&& mi
->line
<= wind
->y_size
) {
2597 SetPortWindowPort(wind
->its_window
);
2598 ToggleMenuSelect(wind
, mi
->line
- wind
->scrollPos
);
2600 /* Dismiss window if only picking one item */
2601 if (wind
->how
!= PICK_ANY
)
2602 AddToKeyQueue(CHAR_CR
, 1);
2606 HUnlock((char **) wind
->menuInfo
);
2607 /* add key if didn't find it in menu and not filtered */
2612 MenwClick(NhWindow
*wind
, Point pt
)
2616 GetWindowBounds(wind
->its_window
, kWindowContentRgn
, &wrect
);
2617 OffsetRect(&wrect
, -wrect
.left
, -wrect
.top
);
2618 if (inSelect
!= WIN_ERR
&& wind
->how
!= PICK_NONE
) {
2619 short currentRow
= -1, previousRow
= -1;
2620 short previousItem
= -1, item
= -1;
2621 Boolean majorSelectState
, firstRow
= TRUE
;
2624 #if !TARGET_API_MAC_CARBON
2628 currentRow
= pt
.v
/ wind
->row_height
;
2629 if (pt
.h
< wrect
.left
|| pt
.h
> wrect
.right
|| pt
.v
< 0
2630 || pt
.v
> wrect
.bottom
|| currentRow
>= wind
->y_size
) {
2631 continue; /* not in window range */
2634 item
= ListCoordinateToItem(wind
, currentRow
);
2636 if (item
!= previousItem
) {
2637 /* Implement typical Mac multiple-selection behavior
2638 * (ie, not the UI implemented by the Finder)
2640 Boolean itemIsSelected
= (ListItemSelected(wind
, item
) >= 0);
2643 /* this is first valid row, so major state is opposite of
2644 * what this row is */
2645 majorSelectState
= !itemIsSelected
;
2649 if (wind
->how
== PICK_ONE
&& previousItem
!= -1) {
2650 /* if previous row was selected and we're only selecting
2652 * deselect previous row!
2654 ToggleMenuListItemSelected(wind
, previousItem
);
2655 ToggleMenuSelect(wind
, previousRow
);
2660 continue; /* header line */
2662 if (majorSelectState
!= itemIsSelected
) {
2663 ToggleMenuListItemSelected(wind
, item
);
2664 ToggleMenuSelect(wind
, currentRow
);
2667 previousRow
= currentRow
;
2668 previousItem
= item
;
2670 } while (StillDown());
2672 /* Dismiss window if only picking one item */
2673 if (wind
->how
== PICK_ONE
)
2674 AddToKeyQueue(CHAR_CR
, 1);
2680 MenwUpdate(NhWindow
*wind
)
2686 HLock((Handle
) wind
->menuInfo
);
2687 HLock((Handle
) wind
->menuSelected
);
2688 for (i
= 0; i
< wind
->miSelLen
; i
++) {
2689 mi
= &(*wind
->menuInfo
)[(*wind
->menuSelected
)[i
]];
2691 if (line
> wind
->scrollPos
&& line
<= wind
->y_size
)
2692 ToggleMenuSelect(wind
, line
- wind
->scrollPos
);
2694 HUnlock((Handle
) wind
->menuInfo
);
2695 HUnlock((Handle
) wind
->menuSelected
);
2699 #if 0 // TARGET_API_MAC_CARBON
2700 static pascal OSStatus
2701 MenwEvent(EventHandlerCallRef nexthandler
, EventRef event
, void *userdata
)
2703 NhWindow
*wind
= (NhWindow
*) userdata
;
2706 switch (GetEventClass(event
)) {
2707 case kEventClassControl
: {
2711 switch (GetEventKind(event
)) {
2712 case kEventControlHit
:
2713 GetEventParameter(event
, kEventParamDirectObject
,
2714 typeControlRef
, NULL
, sizeof(ControlRef
), NULL
, &control
);
2715 GetControlID(control
, &id
);
2722 case kEventClassKeyboard
: {
2727 GetEventParameter(event
, kEventParamKeyMacCharCodes
, typeChar
, NULL
,
2728 sizeof(char), NULL
, &ch
);
2729 GetEventParameter(event
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
2730 sizeof(UInt32
), NULL
, &modifiers
);
2731 if (modifiers
& cmdKey
)
2732 return (eventNotHandledErr
);
2737 case kEventClassWindow
:
2738 switch (GetEventKind(event
)) {
2739 case kEventWindowDrawContent
:
2740 CallNextEventHandler(nexthandler
, event
);
2744 case kEventWindowHandleContentClick
: {
2749 GetEventParameter(event
, kEventParamMouseLocation
, typeQDPoint
,
2750 NULL
, sizeof(Point
), NULL
, &pt
);
2751 GetGWorld(&saveport
, &savedev
);
2752 SetPortWindowPort(wind
->its_window
);
2754 SetGWorld(saveport
, savedev
);
2755 MenwClick(wind
, pt
);
2759 case kEventWindowClose
:
2765 return (eventNotHandledErr
);
2771 macKeyMenu(EventRecord
*theEvent
, WindowPtr theWindow
)
2773 MenwKey(GetNhWin(theWindow
), theEvent
->message
& 0xff);
2778 macClickMenu(EventRecord
*theEvent
, WindowRef theWindow
)
2781 NhWindow
*aWin
= GetNhWin(theWindow
);
2783 if (aWin
->scrollBar
&& IsControlVisible(aWin
->scrollBar
)) {
2785 ControlHandle theBar
;
2787 p
= theEvent
->where
;
2789 code
= FindControl(p
, theWindow
, &theBar
);
2791 DoScrollBar(p
, code
, theBar
, aWin
);
2795 MenwClick(aWin
, theEvent
->where
);
2799 macUpdateMenu(EventRecord
*theEvent
, WindowPtr theWindow
)
2801 MenwUpdate(GetNhWin(theWindow
));
2805 #endif /* !TARGET_API_MAC_CARBON */
2807 /**********************************************************************
2812 TextKey(NhWindow
*wind
, char ch
)
2814 ch
= filter_scroll_key(ch
, wind
);
2817 if (inSelect
== WIN_ERR
&& ClosingWindowChar(ch
)) {
2818 HideWindow(wind
->its_window
);
2819 mac_destroy_nhwindow(wind
- theWindows
);
2821 AddToKeyQueue(topl_resp_key(ch
), TRUE
);
2826 TextUpdate(NhWindow
*wind
)
2832 GetWindowBounds(wind
->its_window
, kWindowContentRgn
, &r
);
2833 OffsetRect(&r
, -r
.left
, -r
.top
);
2835 r2
.left
= r2
.right
- SBARWIDTH
;
2838 vis
= (r2
.bottom
> r2
.top
+ 50);
2840 draw_growicon_vert_only(wind
->its_window
);
2841 DrawControls(wind
->its_window
);
2844 if (vis
&& (h
= NewRgn())) {
2845 RgnHandle tmp
= NewRgn();
2852 DiffRgn(h
, tmp
, tmp
);
2857 if (r
.right
< MIN_RIGHT
)
2858 r
.right
= MIN_RIGHT
;
2859 r
.top
-= wind
->scrollPos
* wind
->row_height
;
2860 r
.right
-= SBARWIDTH
;
2861 HLock(wind
->windowText
);
2862 TETextBox(*wind
->windowText
, wind
->windowTextLen
, &r
, teJustLeft
);
2863 HUnlock(wind
->windowText
);
2871 #if 0 // TARGET_API_MAC_CARBON
2872 static pascal OSStatus
2873 TextEvent(EventHandlerCallRef nexthandler
, EventRef event
, void *userdata
)
2875 NhWindow
*wind
= (NhWindow
*) userdata
;
2878 switch (GetEventClass(event
)) {
2879 case kEventClassControl
: {
2883 switch (GetEventKind(event
)) {
2884 case kEventControlHit
:
2885 GetEventParameter(event
, kEventParamDirectObject
,
2886 typeControlRef
, NULL
, sizeof(ControlRef
), NULL
, &control
);
2887 GetControlID(control
, &id
);
2894 case kEventClassKeyboard
: {
2899 GetEventParameter(event
, kEventParamKeyMacCharCodes
, typeChar
, NULL
,
2900 sizeof(char), NULL
, &ch
);
2901 GetEventParameter(event
, kEventParamKeyModifiers
, typeUInt32
, NULL
,
2902 sizeof(UInt32
), NULL
, &modifiers
);
2903 if (modifiers
& cmdKey
)
2904 return (eventNotHandledErr
);
2909 case kEventClassWindow
:
2910 switch (GetEventKind(event
)) {
2911 case kEventWindowDrawContent
:
2912 CallNextEventHandler(nexthandler
, event
);
2916 case kEventWindowClose
:
2922 return (eventNotHandledErr
);
2928 macKeyText(EventRecord
*theEvent
, WindowPtr theWindow
)
2930 TextKey(GetNhWin(theWindow
), theEvent
->message
& 0xff);
2935 macClickText(EventRecord
*theEvent
, WindowPtr theWindow
)
2937 NhWindow
*aWin
= GetNhWin(theWindow
);
2939 if (aWin
->scrollBar
&& IsControlVisible(aWin
->scrollBar
)) {
2941 Point p
= theEvent
->where
;
2942 ControlHandle theBar
;
2945 code
= FindControl(p
, theWindow
, &theBar
);
2947 DoScrollBar(p
, code
, theBar
, aWin
);
2952 #endif /* !TARGET_API_MAC_CARBON */
2954 /**********************************************************************
2958 #if 0 // TARGET_API_MAC_CARBON
2959 static pascal OSStatus
2960 GlobalEvent(EventHandlerCallRef nexthandler
, EventRef event
, void *userdata
)
2962 switch (GetEventClass(event
)) {
2963 case kEventClassCommand
:
2964 return (eventNotHandledErr
);
2966 return (eventNotHandledErr
);
2972 macDoNull(EventRecord
*theEvent
, WindowPtr theWindow
)
2978 * Note; theWindow may very well be null here, since keyDown may call
2979 * it when theres no window !!!
2983 GeneralKey(EventRecord
*theEvent
, WindowPtr theWindow
)
2985 #if defined(__SC__) || defined(__MRC__)
2986 #pragma unused(theWindow)
2989 trans_num_keys (theEvent
);
2991 AddToKeyQueue(topl_resp_key(theEvent
->message
& 0xff), TRUE
);
2995 HandleKey(EventRecord
*theEvent
)
2997 WindowPtr theWindow
= FrontWindow();
2999 if (theEvent
->modifiers
& cmdKey
) {
3000 if (theEvent
->message
& 0xff == '.') {
3001 /* Flush key queue */
3002 keyQueueCount
= keyQueueWrite
= keyQueueRead
= 0;
3003 theEvent
->message
= '\033';
3007 DoMenuEvt(MenuKey(theEvent
->message
& 0xff));
3012 int kind
= GetWindowKind(theWindow
) - WIN_BASE_KIND
;
3013 winKeyFuncs
[kind
](theEvent
, theWindow
);
3015 GeneralKey(theEvent
, (WindowPtr
) 0);
3020 #endif /* !TARGET_API_MAC_CARBON */
3023 HandleClick(EventRecord
*theEvent
)
3027 WindowPtr theWindow
;
3030 Boolean not_inSelect
;
3032 InsetRect(GetRegionBounds(GetGrayRgn(), &r
), 4, 4);
3034 code
= FindWindow(theEvent
->where
, &theWindow
);
3035 aWin
= GetNhWin(theWindow
);
3036 not_inSelect
= (inSelect
== WIN_ERR
|| aWin
- theWindows
== inSelect
);
3040 #if 1 //!TARGET_API_MAC_CARBON
3042 int kind
= GetWindowKind(theWindow
) - WIN_BASE_KIND
;
3043 winCursorFuncs
[kind
](theEvent
, theWindow
, gMouseRgn
);
3044 SelectWindow(theWindow
);
3045 SetPortWindowPort(theWindow
);
3046 winClickFuncs
[kind
](theEvent
, theWindow
);
3055 SetCursor(&qdarrow
);
3056 DragWindow(theWindow
, theEvent
->where
, &r
);
3057 SaveWindowPos(theWindow
);
3065 SetCursor(&qdarrow
);
3066 SetRect(&r
, 80, 2 * aWin
->row_height
+ 1, r
.right
, r
.bottom
);
3067 if (aWin
== theWindows
+ WIN_MESSAGE
)
3068 r
.top
+= SBARHEIGHT
;
3069 l
= GrowWindow(theWindow
, theEvent
->where
, &r
);
3070 SizeWindow(theWindow
, l
& 0xffff, l
>> 16, FALSE
);
3071 SaveWindowSize(theWindow
);
3072 SetPortWindowPort(theWindow
);
3073 GetWindowBounds(theWindow
, kWindowContentRgn
, &r
);
3074 OffsetRect(&r
, -r
.left
, -r
.top
);
3075 InvalWindowRect(theWindow
, &r
);
3076 if (aWin
->scrollBar
) {
3077 DrawScrollbar(aWin
);
3085 WindowGoAway(theEvent
, theWindow
);
3089 DoMenuEvt(MenuSelect(theEvent
->where
));
3092 #if !TARGET_API_MAC_CARBON
3094 SystemClick(theEvent
, theWindow
);
3101 #if 1 //!TARGET_API_MAC_CARBON
3104 GeneralUpdate(EventRecord
*theEvent
, WindowPtr theWindow
)
3108 TextUpdate(GetNhWin(theWindow
));
3115 HandleUpdate(EventRecord
*theEvent
)
3117 WindowPtr theWindow
= (WindowPtr
) theEvent
->message
;
3118 NhWindow
*aWin
= GetNhWin(theWindow
);
3120 #if 1 //!TARGET_API_MAC_CARBON
3124 char existing_update_region
= FALSE
;
3127 if (theWindow
== _mt_window
) {
3128 existing_update_region
=
3129 (get_invalid_region(theWindow
, &rect
) == noErr
);
3131 BeginUpdate(theWindow
);
3132 SetPortWindowPort(theWindow
);
3133 GetWindowBounds(theWindow
, kWindowContentRgn
, &r
);
3134 OffsetRect(&r
, -r
.left
, -r
.top
);
3136 #if 0 // TARGET_API_MAC_CARBON
3137 switch (GetWindowKind(theWindow
) - WIN_BASE_KIND
) {
3141 image_tty(NULL
, theWindow
);
3144 MsgUpdate(GetNhWin(theWindow
));
3147 MenwUpdate(GetNhWin(theWindow
));
3150 TextUpdate(GetNhWin(theWindow
));
3154 winUpdateFuncs
[GetWindowKind(theWindow
) - WIN_BASE_KIND
](&fake
,
3158 if (theWindow
== _mt_window
&& existing_update_region
) {
3159 set_invalid_region(theWindow
, &rect
);
3162 EndUpdate(theWindow
);
3165 #if 1 //!TARGET_API_MAC_CARBON
3168 GeneralCursor(EventRecord
*theEvent
, WindowPtr theWindow
, RgnHandle mouseRgn
)
3170 #if defined(__SC__) || defined(__MRC__)
3171 #pragma unused(theWindow)
3173 Rect r
= { -1, -1, 2, 2 };
3175 SetCursor(&qdarrow
);
3176 OffsetRect(&r
, theEvent
->where
.h
, theEvent
->where
.v
);
3177 RectRgn(mouseRgn
, &r
);
3181 DoOsEvt(EventRecord
*theEvent
)
3186 if ((theEvent
->message
& 0xff000000) == 0xfa000000) {
3189 code
= FindWindow(theEvent
->where
, &win
);
3190 if (code
!= inContent
) {
3191 Rect r
= { -1, -1, 2, 2 };
3193 SetCursor(&qdarrow
);
3194 OffsetRect(&r
, theEvent
->where
.h
, theEvent
->where
.v
);
3195 RectRgn(gMouseRgn
, &r
);
3197 #if 1 //!TARGET_API_MAC_CARBON
3198 int kind
= GetWindowKind(win
) - WIN_BASE_KIND
;
3199 if (kind
>= 0 && kind
<= NHW_TEXT
) {
3200 winCursorFuncs
[kind
](theEvent
, win
, gMouseRgn
);
3207 #endif /* !TARGET_API_MAC_CARBON */
3210 HandleEvent(EventRecord
*theEvent
)
3212 switch (theEvent
->what
) {
3213 #if 1 //!TARGET_API_MAC_CARBON
3216 HandleKey(theEvent
);
3220 HandleUpdate(theEvent
);
3223 HandleClick(theEvent
);
3225 #if !TARGET_API_MAC_CARBON
3227 if ((theEvent
->message
& 0xffff0000) != 0) {
3228 Point p
= { 150, 150 };
3229 (void) DIBadMount(p
, theEvent
->message
);
3233 #if !TARGET_API_MAC_CARBON
3238 case kHighLevelEvent
:
3239 AEProcessAppleEvent(theEvent
);
3245 /**********************************************************************
3246 * Interface definition, for windows.c
3249 struct window_procs mac_procs
= {
3251 WC_COLOR
| WC_HILITE_PET
| WC_FONT_MAP
| WC_FONT_MENU
| WC_FONT_MESSAGE
3252 | WC_FONT_STATUS
| WC_FONT_TEXT
| WC_FONTSIZ_MAP
| WC_FONTSIZ_MENU
3253 | WC_FONTSIZ_MESSAGE
| WC_FONTSIZ_STATUS
| WC_FONTSIZ_TEXT
,
3254 0L, mac_init_nhwindows
,
3255 mac_unimplemented
, /* see macmenu.c:mac_askname() for player selection */
3256 mac_askname
, mac_get_nh_event
, mac_exit_nhwindows
, mac_suspend_nhwindows
,
3257 mac_unimplemented
, mac_create_nhwindow
, mac_clear_nhwindow
,
3258 mac_display_nhwindow
, mac_destroy_nhwindow
, mac_curs
, mac_putstr
,
3259 genl_putmixed
, mac_display_file
, mac_start_menu
, mac_add_menu
,
3260 mac_end_menu
, mac_select_menu
, genl_message_menu
, mac_unimplemented
,
3261 mac_get_nh_event
, mac_get_nh_event
,
3268 tty_print_glyph
, tty_raw_print
, tty_raw_print_bold
, mac_nhgetch
,
3269 mac_nh_poskey
, tty_nhbell
, mac_doprev_message
, mac_yn_function
,
3270 mac_getlin
, mac_get_ext_cmd
, mac_number_pad
, mac_delay_output
,
3272 tty_change_color
, tty_change_background
, set_tty_font_name
,
3273 tty_get_color_string
,
3275 /* other defs that really should go away (they're tty specific) */
3276 0, // mac_start_screen,
3277 0, // mac_end_screen,
3278 genl_outrip
, genl_preference_update
, genl_can_suspend_no
,