]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - mac.c
438838eb2841da441816ccf1c71acd1cfeba69db
[PuTTY.git] / mac.c
1 /* $Id: mac.c,v 1.1.2.10 1999/03/01 22:26:49 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
48 #define PUTTY_DO_GLOBALS
49
50 #include "macresid.h"
51 #include "putty.h"
52 #include "mac.h"
53
54 QDGlobals qd;
55
56 static int cold = 1;
57 struct mac_gestalts mac_gestalts;
58
59 static void mac_startup(void);
60 static void mac_eventloop(void);
61 static void mac_event(EventRecord *);
62 static void mac_contentclick(WindowPtr, EventRecord *);
63 static void mac_activatewindow(WindowPtr, Boolean);
64 static void mac_updatewindow(WindowPtr);
65 static void mac_keypress(EventRecord *);
66 static int mac_windowtype(WindowPtr);
67 static void mac_menucommand(long);
68 static void mac_adjustcursor(void);
69 static void mac_adjustmenus(void);
70 static void mac_closewindow(WindowPtr);
71 static void mac_zoomwindow(WindowPtr, short);
72 static void mac_shutdown(void);
73
74 static void mac_newsession(void);
75
76 int main (int argc, char **argv) {
77
78     mac_startup();
79     mac_eventloop();
80 }
81
82 static void mac_startup(void) {
83     Handle menuBar;
84
85     /* Init QuickDraw */
86     InitGraf(&qd.thePort);
87     /* Init Font Manager */
88     InitFonts();
89     /* Init Window Manager */
90     InitWindows();
91     /* Init Menu Manager */
92     InitMenus();
93     /* Init TextEdit */
94     TEInit();
95     /* Init Dialog Manager */
96     InitDialogs(nil);
97     cold = 0;
98     
99     /* Find out if we've got Color Quickdraw */
100     if (Gestalt(gestaltQuickdrawVersion, &mac_gestalts.qdvers) != noErr)
101         mac_gestalts.qdvers = gestaltOriginalQD;
102     /* ... and the Appearance Manager? */
103     if (Gestalt(gestaltAppearanceVersion, &mac_gestalts.apprvers) != noErr)
104         if (Gestalt(gestaltAppearanceAttr, NULL) == noErr)
105             mac_gestalts.apprvers = 0x0100;
106         else
107             mac_gestalts.apprvers = 0;
108     /* Mac OS 8.5 Control Manager (proportional scrollbars)? */
109     if (Gestalt(gestaltControlMgrAttr, &mac_gestalts.cntlattr) != noErr)
110         mac_gestalts.cntlattr = 0;
111
112     /* We've been tested with the Appearance Manager */
113     if (mac_gestalts.apprvers != 0)
114         RegisterAppearanceClient();
115     
116     menuBar = GetNewMBar(128);
117     if (menuBar == NULL)
118         fatalbox("Unable to create menu bar.");
119     SetMenuBar(menuBar);
120     AppendResMenu(GetMenuHandle(mApple), 'DRVR');
121     mac_adjustmenus();
122     DrawMenuBar();
123     InitCursor();
124 }
125
126 static void mac_eventloop(void) {
127     Boolean gotevent;
128     EventRecord event;
129     int i;
130
131     for (;;) {
132         mac_adjustcursor();
133         gotevent = WaitNextEvent(everyEvent, &event, LONG_MAX, NULL);
134         mac_adjustcursor();
135         if (gotevent)
136             mac_event(&event);
137     }
138 }
139
140 static void mac_event(EventRecord *event) {
141     short part;
142     WindowPtr window;
143     Point pt;
144
145     switch (event->what) {
146       case mouseDown:
147         part = FindWindow(event->where, &window);
148         switch (part) {
149           case inMenuBar:
150             mac_adjustmenus();
151             mac_menucommand(MenuSelect(event->where));
152             break;
153           case inSysWindow:
154             SystemClick(event, window);
155             break;
156           case inContent:
157             if (window != FrontWindow())
158                 /* XXX: check for movable modal dboxes? */
159                 SelectWindow(window);
160             else
161                 mac_contentclick(window, event);
162             break;
163           case inGoAway:
164             if (TrackGoAway(window, event->where))
165                 mac_closewindow(window);
166             break;
167           case inDrag:
168             /* XXX: moveable modal check? */
169             DragWindow(window, event->where, &qd.screenBits.bounds);
170             break;
171           case inGrow:
172             break;
173           case inZoomIn:
174           case inZoomOut:
175             if (TrackBox(window, event->where, part))
176                 mac_zoomwindow(window, part);
177             break;
178         }
179         break;
180       case keyDown:
181       case autoKey:
182         mac_keypress(event);
183         break;
184       case activateEvt:
185         mac_activatewindow((WindowPtr)event->message,
186                            (event->modifiers & activeFlag) != 0);
187         break;
188       case updateEvt:
189         mac_updatewindow((WindowPtr)event->message);
190         break;
191       case diskEvt:
192         if (HiWord(event->message) != noErr) {
193             SetPt(&pt, 120, 120);
194             DIBadMount(pt, event->message);
195         }
196         break;
197     }
198 }
199
200 static void mac_contentclick(WindowPtr window, EventRecord *event) {
201     short item;
202
203     switch (mac_windowtype(window)) {
204       case wTerminal:
205         mac_clickterm(window, event);
206         break;
207       case wAbout:
208         if (DialogSelect(event, &(DialogPtr)window, &item))
209             switch (item) {
210               case wiAboutLicence:
211                 /* XXX: Do something */
212                 break;
213             }
214         break;
215     }
216 }
217
218 static void mac_activatewindow(WindowPtr window, Boolean active) {
219
220     switch (mac_windowtype(window)) {
221       case wTerminal:
222         mac_activateterm(window, active);
223         break;
224     }
225 }
226
227 static void mac_updatewindow(WindowPtr window) {
228
229     switch (mac_windowtype(window)) {
230       case wTerminal:
231         mac_updateterm(window);
232         break;
233       case wAbout:
234         BeginUpdate(window);
235         UpdateDialog(window, window->visRgn);
236         EndUpdate(window);
237         break;
238       case wLicence:
239         /* Do something */
240         break;
241     }
242 }
243
244 /*
245  * Work out what kind of window we're dealing with.
246  * Concept shamelessly nicked from SurfWriter.
247  */
248 static int mac_windowtype(WindowPtr window) {
249     int kind;
250
251     if (window == NULL)
252         return wNone;
253     kind = ((WindowPeek)window)->windowKind;
254     if (kind < 0)
255         return wDA;
256     if (GetWVariant(window) == zoomDocProc)
257         return wTerminal;
258     return GetWRefCon(window);
259 }
260
261 /*
262  * Handle a key press
263  */
264 static void mac_keypress(EventRecord *event) {
265     char key;
266
267     if (event->what == keyDown && (event->modifiers & cmdKey)) {
268         mac_adjustmenus();
269         mac_menucommand(MenuKey(event->message & charCodeMask));
270     }
271 }
272
273 static void mac_menucommand(long result) {
274     short menu, item;
275     Str255 da;
276
277     menu = HiWord(result);
278     item = LoWord(result);
279     switch (menu) {
280       case mApple:
281         switch (item) {
282           case iAbout:
283             GetNewDialog(wAbout, NULL, (GrafPort *)-1);
284             break;
285           default:
286             GetMenuItemText(GetMenuHandle(mApple), item, da);
287             OpenDeskAcc(da);
288             break;
289         }
290         break;
291       case mFile:
292         switch (item) {
293           case iNew:
294             mac_newsession();
295             break;
296           case iClose:
297             mac_closewindow(FrontWindow());
298             break;
299           case iQuit:
300             mac_shutdown();
301             break;
302         }
303         break;
304     }
305     HiliteMenu(0);
306 }
307
308 static void mac_closewindow(WindowPtr window) {
309
310     switch (mac_windowtype(window)) {
311       case wDA:
312         CloseDeskAcc(((WindowPeek)window)->windowKind);
313         break;
314       case wTerminal:
315         /* FIXME: end session and stuff */
316         break;
317       default:
318         CloseWindow(window);
319         break;
320     }
321 }
322
323 static void mac_zoomwindow(WindowPtr window, short part) {
324
325     /* FIXME: do something */
326 }
327
328 /*
329  * Make the menus look right before the user gets to see them.
330  */
331 static void mac_adjustmenus(void) {
332
333 }
334
335 /*
336  * Make sure the right cursor's being displayed.
337  */
338 static void mac_adjustcursor(void) {
339
340     SetCursor(&qd.arrow);
341 }
342
343 static void mac_shutdown(void) {
344
345     ExitToShell();
346 }
347
348 void fatalbox(const char *fmt, ...) {
349     va_list ap;
350     Str255 stuff;
351     
352     va_start(ap, fmt);
353     /* We'd like stuff to be a Pascal string */
354     stuff[0] = vsprintf((char *)(&stuff[1]), fmt, ap);
355     va_end(ap);
356     ParamText(stuff, NULL, NULL, NULL);
357     StopAlert(128, nil);
358     exit(1);
359 }