]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - mac.c
Menu items now turn on and off in a vaguely useful way.
[PuTTY.git] / mac.c
1 /* $Id: mac.c,v 1.1.2.14 1999/03/11 21:40:31 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 struct mac_windows {
79     WindowPtr terminal; /* XXX: Temporary */
80     WindowPtr about;
81     WindowPtr licence;
82 };
83
84 struct mac_windows windows;
85
86 int main (int argc, char **argv) {
87
88     mac_startup();
89     mac_eventloop();
90 }
91
92 static void mac_startup(void) {
93     Handle menuBar;
94
95     /* Init QuickDraw */
96     InitGraf(&qd.thePort);
97     /* Init Font Manager */
98     InitFonts();
99     /* Init Window Manager */
100     InitWindows();
101     /* Init Menu Manager */
102     InitMenus();
103     /* Init TextEdit */
104     TEInit();
105     /* Init Dialog Manager */
106     InitDialogs(nil);
107     cold = 0;
108     
109     /* Find out if we've got Color Quickdraw */
110     if (Gestalt(gestaltQuickdrawVersion, &mac_gestalts.qdvers) != noErr)
111         mac_gestalts.qdvers = gestaltOriginalQD;
112     /* ... and the Appearance Manager? */
113     if (Gestalt(gestaltAppearanceVersion, &mac_gestalts.apprvers) != noErr)
114         if (Gestalt(gestaltAppearanceAttr, NULL) == noErr)
115             mac_gestalts.apprvers = 0x0100;
116         else
117             mac_gestalts.apprvers = 0;
118     /* Mac OS 8.5 Control Manager (proportional scrollbars)? */
119     if (Gestalt(gestaltControlMgrAttr, &mac_gestalts.cntlattr) != noErr)
120         mac_gestalts.cntlattr = 0;
121
122     /* We've been tested with the Appearance Manager */
123     if (mac_gestalts.apprvers != 0)
124         RegisterAppearanceClient();
125     
126     menuBar = GetNewMBar(128);
127     if (menuBar == NULL)
128         fatalbox("Unable to create menu bar.");
129     SetMenuBar(menuBar);
130     AppendResMenu(GetMenuHandle(mApple), 'DRVR');
131     mac_adjustmenus();
132     DrawMenuBar();
133     InitCursor();
134     windows.terminal = NULL;
135     windows.about = NULL;
136     windows.licence = NULL;
137 }
138
139 static void mac_eventloop(void) {
140     Boolean gotevent;
141     EventRecord event;
142     int i;
143
144     for (;;) {
145         mac_adjustcursor();
146         gotevent = WaitNextEvent(everyEvent, &event, LONG_MAX, NULL);
147         mac_adjustcursor();
148         if (gotevent)
149             mac_event(&event);
150     }
151 }
152
153 static void mac_event(EventRecord *event) {
154     short part;
155     WindowPtr window;
156     Point pt;
157
158     switch (event->what) {
159       case mouseDown:
160         part = FindWindow(event->where, &window);
161         switch (part) {
162           case inMenuBar:
163             mac_adjustmenus();
164             mac_menucommand(MenuSelect(event->where));
165             break;
166           case inSysWindow:
167             SystemClick(event, window);
168             break;
169           case inContent:
170             if (window != FrontWindow())
171                 /* XXX: check for movable modal dboxes? */
172                 SelectWindow(window);
173             else
174                 mac_contentclick(window, event);
175             break;
176           case inGoAway:
177             if (TrackGoAway(window, event->where))
178                 mac_closewindow(window);
179             break;
180           case inDrag:
181             /* XXX: moveable modal check? */
182             DragWindow(window, event->where, &qd.screenBits.bounds);
183             break;
184           case inGrow:
185             mac_growwindow(window, event);
186             break;
187           case inZoomIn:
188           case inZoomOut:
189             if (TrackBox(window, event->where, part))
190                 mac_zoomwindow(window, part);
191             break;
192         }
193         break;
194       case keyDown:
195       case autoKey:
196         mac_keypress(event);
197         break;
198       case activateEvt:
199         mac_activatewindow((WindowPtr)event->message,
200                            (event->modifiers & activeFlag) != 0);
201         break;
202       case updateEvt:
203         mac_updatewindow((WindowPtr)event->message);
204         break;
205       case diskEvt:
206         if (HiWord(event->message) != noErr) {
207             SetPt(&pt, 120, 120);
208             DIBadMount(pt, event->message);
209         }
210         break;
211     }
212 }
213
214 static void mac_contentclick(WindowPtr window, EventRecord *event) {
215     short item;
216
217     switch (mac_windowtype(window)) {
218       case wTerminal:
219         mac_clickterm(window, event);
220         break;
221       case wAbout:
222         if (DialogSelect(event, &(DialogPtr)window, &item))
223             switch (item) {
224               case wiAboutLicence:
225                 /* XXX: Do something */
226                 break;
227             }
228         break;
229     }
230 }
231
232 static void mac_growwindow(WindowPtr window, EventRecord *event) {
233
234     switch (mac_windowtype(window)) {
235       case wTerminal:
236         mac_growterm(window, event);
237     }
238 }
239
240 static void mac_activatewindow(WindowPtr window, Boolean active) {
241
242     mac_adjustmenus();
243     switch (mac_windowtype(window)) {
244       case wTerminal:
245         mac_activateterm(window, active);
246         break;
247     }
248 }
249
250 static void mac_updatewindow(WindowPtr window) {
251
252     switch (mac_windowtype(window)) {
253       case wTerminal:
254         mac_updateterm(window);
255         break;
256       case wAbout:
257         BeginUpdate(window);
258         UpdateDialog(window, window->visRgn);
259         EndUpdate(window);
260         break;
261       case wLicence:
262         /* Do something */
263         break;
264     }
265 }
266
267 /*
268  * Work out what kind of window we're dealing with.
269  * Concept shamelessly nicked from SurfWriter.
270  */
271 static int mac_windowtype(WindowPtr window) {
272     int kind;
273
274     if (window == NULL)
275         return wNone;
276     kind = ((WindowPeek)window)->windowKind;
277     if (kind < 0)
278         return wDA;
279     if (GetWVariant(window) == zoomDocProc)
280         return wTerminal;
281     return GetWRefCon(window);
282 }
283
284 /*
285  * Handle a key press
286  */
287 static void mac_keypress(EventRecord *event) {
288     char key;
289     WindowPtr window;
290
291     if (event->what == keyDown && (event->modifiers & cmdKey)) {
292         mac_adjustmenus();
293         mac_menucommand(MenuKey(event->message & charCodeMask));
294     } else {
295         window = FrontWindow();
296         switch (mac_windowtype(window)) {
297           case wTerminal:
298             mac_keyterm(window, event);
299             break;
300         }
301     }       
302 }
303
304 static void mac_menucommand(long result) {
305     short menu, item;
306     Str255 da;
307
308     menu = HiWord(result);
309     item = LoWord(result);
310     switch (menu) {
311       case mApple:
312         switch (item) {
313           case iAbout:
314             GetNewDialog(wAbout, NULL, (GrafPort *)-1);
315             break;
316           default:
317             GetMenuItemText(GetMenuHandle(mApple), item, da);
318             OpenDeskAcc(da);
319             break;
320         }
321         break;
322       case mFile:
323         switch (item) {
324           case iNew:
325             mac_newsession();
326             break;
327           case iClose:
328             mac_closewindow(FrontWindow());
329             break;
330           case iQuit:
331             mac_shutdown();
332             break;
333         }
334         break;
335     }
336     HiliteMenu(0);
337 }
338
339 static void mac_closewindow(WindowPtr window) {
340
341     switch (mac_windowtype(window)) {
342       case wDA:
343         CloseDeskAcc(((WindowPeek)window)->windowKind);
344         break;
345       case wTerminal:
346         /* FIXME: end session and stuff */
347         break;
348       default:
349         CloseWindow(window);
350         break;
351     }
352 }
353
354 static void mac_zoomwindow(WindowPtr window, short part) {
355
356     /* FIXME: do something */
357 }
358
359 /*
360  * Make the menus look right before the user gets to see them.
361  */
362 static void mac_adjustmenus(void) {
363     WindowPtr window;
364     MenuHandle menu;
365
366     window = FrontWindow();
367     menu = GetMenuHandle(mApple);
368     EnableItem(menu, 0);
369     EnableItem(menu, iAbout);
370
371     menu = GetMenuHandle(mFile);
372     EnableItem(menu, 0);
373     EnableItem(menu, iNew);
374     EnableItem(menu, iQuit);
375
376     switch (mac_windowtype(window)) {
377       case wTerminal:
378         mac_adjusttermmenus(window);
379         break;
380       default:
381         menu = GetMenuHandle(mEdit);
382         DisableItem(menu, 0);
383         break;
384     }
385     DrawMenuBar();
386 }
387
388 /*
389  * Make sure the right cursor's being displayed.
390  */
391 static void mac_adjustcursor(void) {
392
393     SetCursor(&qd.arrow);
394 }
395
396 void write_clip(void *data, int len) {
397
398     /* XXX: do something */
399 }
400
401 void get_clip(void **p, int *lenp) {
402
403     /* XXX: do something */
404 }
405
406 static void mac_shutdown(void) {
407
408     exit(0);
409 }
410
411 void fatalbox(const char *fmt, ...) {
412     va_list ap;
413     Str255 stuff;
414     
415     va_start(ap, fmt);
416     /* We'd like stuff to be a Pascal string */
417     stuff[0] = vsprintf((char *)(&stuff[1]), fmt, ap);
418     va_end(ap);
419     ParamText(stuff, NULL, NULL, NULL);
420     StopAlert(128, nil);
421     exit(1);
422 }
423
424 /*
425  * Local Variables:
426  * c-file-style: "simon"
427  * End:
428  */