]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - mac.c
Pass keyboard events to the terminal front-end.
[PuTTY.git] / mac.c
1 /* $Id: mac.c,v 1.1.2.12 1999/03/07 23:20:20 ben Exp $ */
2 /*
3  * Copyright (c) 1999 Ben Harris
4  * All rights reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use,
10  * copy, modify, merge, publish, distribute, sublicense, and/or
11  * sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following
13  * conditions:
14  * 
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  * 
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
23  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26  */
27 /*
28  * mac.c -- miscellaneous Mac-specific routines
29  */
30
31 #include <MacTypes.h>
32 #include <Quickdraw.h>
33 #include <Fonts.h>
34 #include <MacWindows.h>
35 #include <Menus.h>
36 #include <TextEdit.h>
37 #include <Appearance.h>
38 #include <Dialogs.h>
39 #include <Devices.h>
40 #include <DiskInit.h>
41 #include <Gestalt.h>
42 #include <ToolUtils.h>
43
44 #include <limits.h>
45 #include <stdarg.h>
46 #include <stdlib.h>             /* putty.h needs size_t */
47 #include <stdio.h>              /* for vsprintf */
48
49 #define PUTTY_DO_GLOBALS
50
51 #include "macresid.h"
52 #include "putty.h"
53 #include "mac.h"
54
55 QDGlobals qd;
56
57 static int cold = 1;
58 struct mac_gestalts mac_gestalts;
59
60 static void mac_startup(void);
61 static void mac_eventloop(void);
62 static void mac_event(EventRecord *);
63 static void mac_contentclick(WindowPtr, EventRecord *);
64 static void mac_growwindow(WindowPtr, EventRecord *);
65 static void mac_activatewindow(WindowPtr, Boolean);
66 static void mac_updatewindow(WindowPtr);
67 static void mac_keypress(EventRecord *);
68 static int mac_windowtype(WindowPtr);
69 static void mac_menucommand(long);
70 static void mac_adjustcursor(void);
71 static void mac_adjustmenus(void);
72 static void mac_closewindow(WindowPtr);
73 static void mac_zoomwindow(WindowPtr, short);
74 static void mac_shutdown(void);
75
76 static void mac_newsession(void);
77
78 int main (int argc, char **argv) {
79
80     mac_startup();
81     mac_eventloop();
82 }
83
84 static void mac_startup(void) {
85     Handle menuBar;
86
87     /* Init QuickDraw */
88     InitGraf(&qd.thePort);
89     /* Init Font Manager */
90     InitFonts();
91     /* Init Window Manager */
92     InitWindows();
93     /* Init Menu Manager */
94     InitMenus();
95     /* Init TextEdit */
96     TEInit();
97     /* Init Dialog Manager */
98     InitDialogs(nil);
99     cold = 0;
100     
101     /* Find out if we've got Color Quickdraw */
102     if (Gestalt(gestaltQuickdrawVersion, &mac_gestalts.qdvers) != noErr)
103         mac_gestalts.qdvers = gestaltOriginalQD;
104     /* ... and the Appearance Manager? */
105     if (Gestalt(gestaltAppearanceVersion, &mac_gestalts.apprvers) != noErr)
106         if (Gestalt(gestaltAppearanceAttr, NULL) == noErr)
107             mac_gestalts.apprvers = 0x0100;
108         else
109             mac_gestalts.apprvers = 0;
110     /* Mac OS 8.5 Control Manager (proportional scrollbars)? */
111     if (Gestalt(gestaltControlMgrAttr, &mac_gestalts.cntlattr) != noErr)
112         mac_gestalts.cntlattr = 0;
113
114     /* We've been tested with the Appearance Manager */
115     if (mac_gestalts.apprvers != 0)
116         RegisterAppearanceClient();
117     
118     menuBar = GetNewMBar(128);
119     if (menuBar == NULL)
120         fatalbox("Unable to create menu bar.");
121     SetMenuBar(menuBar);
122     AppendResMenu(GetMenuHandle(mApple), 'DRVR');
123     mac_adjustmenus();
124     DrawMenuBar();
125     InitCursor();
126 }
127
128 static void mac_eventloop(void) {
129     Boolean gotevent;
130     EventRecord event;
131     int i;
132
133     for (;;) {
134         mac_adjustcursor();
135         gotevent = WaitNextEvent(everyEvent, &event, LONG_MAX, NULL);
136         mac_adjustcursor();
137         if (gotevent)
138             mac_event(&event);
139     }
140 }
141
142 static void mac_event(EventRecord *event) {
143     short part;
144     WindowPtr window;
145     Point pt;
146
147     switch (event->what) {
148       case mouseDown:
149         part = FindWindow(event->where, &window);
150         switch (part) {
151           case inMenuBar:
152             mac_adjustmenus();
153             mac_menucommand(MenuSelect(event->where));
154             break;
155           case inSysWindow:
156             SystemClick(event, window);
157             break;
158           case inContent:
159             if (window != FrontWindow())
160                 /* XXX: check for movable modal dboxes? */
161                 SelectWindow(window);
162             else
163                 mac_contentclick(window, event);
164             break;
165           case inGoAway:
166             if (TrackGoAway(window, event->where))
167                 mac_closewindow(window);
168             break;
169           case inDrag:
170             /* XXX: moveable modal check? */
171             DragWindow(window, event->where, &qd.screenBits.bounds);
172             break;
173           case inGrow:
174             mac_growwindow(window, event);
175             break;
176           case inZoomIn:
177           case inZoomOut:
178             if (TrackBox(window, event->where, part))
179                 mac_zoomwindow(window, part);
180             break;
181         }
182         break;
183       case keyDown:
184       case autoKey:
185         mac_keypress(event);
186         break;
187       case activateEvt:
188         mac_activatewindow((WindowPtr)event->message,
189                            (event->modifiers & activeFlag) != 0);
190         break;
191       case updateEvt:
192         mac_updatewindow((WindowPtr)event->message);
193         break;
194       case diskEvt:
195         if (HiWord(event->message) != noErr) {
196             SetPt(&pt, 120, 120);
197             DIBadMount(pt, event->message);
198         }
199         break;
200     }
201 }
202
203 static void mac_contentclick(WindowPtr window, EventRecord *event) {
204     short item;
205
206     switch (mac_windowtype(window)) {
207       case wTerminal:
208         mac_clickterm(window, event);
209         break;
210       case wAbout:
211         if (DialogSelect(event, &(DialogPtr)window, &item))
212             switch (item) {
213               case wiAboutLicence:
214                 /* XXX: Do something */
215                 break;
216             }
217         break;
218     }
219 }
220
221 static void mac_growwindow(WindowPtr window, EventRecord *event) {
222
223     switch (mac_windowtype(window)) {
224       case wTerminal:
225         mac_growterm(window, event);
226     }
227 }
228
229 static void mac_activatewindow(WindowPtr window, Boolean active) {
230
231     switch (mac_windowtype(window)) {
232       case wTerminal:
233         mac_activateterm(window, active);
234         break;
235     }
236 }
237
238 static void mac_updatewindow(WindowPtr window) {
239
240     switch (mac_windowtype(window)) {
241       case wTerminal:
242         mac_updateterm(window);
243         break;
244       case wAbout:
245         BeginUpdate(window);
246         UpdateDialog(window, window->visRgn);
247         EndUpdate(window);
248         break;
249       case wLicence:
250         /* Do something */
251         break;
252     }
253 }
254
255 /*
256  * Work out what kind of window we're dealing with.
257  * Concept shamelessly nicked from SurfWriter.
258  */
259 static int mac_windowtype(WindowPtr window) {
260     int kind;
261
262     if (window == NULL)
263         return wNone;
264     kind = ((WindowPeek)window)->windowKind;
265     if (kind < 0)
266         return wDA;
267     if (GetWVariant(window) == zoomDocProc)
268         return wTerminal;
269     return GetWRefCon(window);
270 }
271
272 /*
273  * Handle a key press
274  */
275 static void mac_keypress(EventRecord *event) {
276     char key;
277     WindowPtr window;
278
279     if (event->what == keyDown && (event->modifiers & cmdKey)) {
280         mac_adjustmenus();
281         mac_menucommand(MenuKey(event->message & charCodeMask));
282     } else {
283         window = FrontWindow();
284         switch (mac_windowtype(window)) {
285           case wTerminal:
286             mac_keyterm(window, event);
287             break;
288         }
289     }       
290 }
291
292 static void mac_menucommand(long result) {
293     short menu, item;
294     Str255 da;
295
296     menu = HiWord(result);
297     item = LoWord(result);
298     switch (menu) {
299       case mApple:
300         switch (item) {
301           case iAbout:
302             GetNewDialog(wAbout, NULL, (GrafPort *)-1);
303             break;
304           default:
305             GetMenuItemText(GetMenuHandle(mApple), item, da);
306             OpenDeskAcc(da);
307             break;
308         }
309         break;
310       case mFile:
311         switch (item) {
312           case iNew:
313             mac_newsession();
314             break;
315           case iClose:
316             mac_closewindow(FrontWindow());
317             break;
318           case iQuit:
319             mac_shutdown();
320             break;
321         }
322         break;
323     }
324     HiliteMenu(0);
325 }
326
327 static void mac_closewindow(WindowPtr window) {
328
329     switch (mac_windowtype(window)) {
330       case wDA:
331         CloseDeskAcc(((WindowPeek)window)->windowKind);
332         break;
333       case wTerminal:
334         /* FIXME: end session and stuff */
335         break;
336       default:
337         CloseWindow(window);
338         break;
339     }
340 }
341
342 static void mac_zoomwindow(WindowPtr window, short part) {
343
344     /* FIXME: do something */
345 }
346
347 /*
348  * Make the menus look right before the user gets to see them.
349  */
350 static void mac_adjustmenus(void) {
351
352 }
353
354 /*
355  * Make sure the right cursor's being displayed.
356  */
357 static void mac_adjustcursor(void) {
358
359     SetCursor(&qd.arrow);
360 }
361
362 static void mac_shutdown(void) {
363
364     exit(0);
365 }
366
367 void fatalbox(const char *fmt, ...) {
368     va_list ap;
369     Str255 stuff;
370     
371     va_start(ap, fmt);
372     /* We'd like stuff to be a Pascal string */
373     stuff[0] = vsprintf((char *)(&stuff[1]), fmt, ap);
374     va_end(ap);
375     ParamText(stuff, NULL, NULL, NULL);
376     StopAlert(128, nil);
377     exit(1);
378 }