/[MITgcm]/MITgcm/tools/mpack-1.6/macnapp.c
ViewVC logotype

Annotation of /MITgcm/tools/mpack-1.6/macnapp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download)
Tue Aug 26 20:45:25 2003 UTC (20 years, 8 months ago) by edhill
Branch: MAIN
CVS Tags: checkpoint64y, checkpoint64x, checkpoint58l_post, checkpoint64z, checkpoint51k_post, checkpoint57t_post, checkpoint64q, checkpoint64p, checkpoint64s, checkpoint64r, checkpoint64u, checkpoint64t, checkpoint64w, checkpoint64v, checkpoint64i, checkpoint64h, checkpoint64k, checkpoint64j, checkpoint64m, checkpoint64l, checkpoint64o, checkpoint64n, checkpoint64a, checkpoint57o_post, checkpoint64c, checkpoint64b, checkpoint64e, checkpoint64d, checkpoint64g, checkpoint64f, checkpoint52l_pre, checkpoint52e_pre, hrcube4, checkpoint58e_post, mitgcm_mapl_00, checkpoint52n_post, checkpoint52j_post, checkpoint53d_post, checkpoint58u_post, checkpoint58w_post, checkpoint54a_pre, checkpoint51o_pre, checkpoint57m_post, checkpoint55c_post, checkpoint54e_post, checkpoint52e_post, checkpoint57s_post, checkpoint51n_pre, checkpoint54a_post, checkpoint63p, checkpoint63q, checkpoint63r, checkpoint63s, checkpoint63l, checkpoint63m, checkpoint63n, checkpoint63o, checkpoint63h, checkpoint63i, checkpoint63j, checkpoint63k, checkpoint63d, checkpoint63e, checkpoint63f, checkpoint63g, checkpoint53c_post, checkpoint63a, checkpoint63b, checkpoint63c, checkpoint57k_post, checkpoint55d_pre, checkpoint57d_post, checkpoint51l_post, checkpoint57g_post, checkpoint51q_post, checkpoint64, checkpoint65, checkpoint60, checkpoint61, checkpoint62, checkpoint63, checkpoint57b_post, checkpoint57c_pre, checkpoint51j_post, checkpoint58r_post, checkpoint55j_post, checkpoint56b_post, checkpoint57i_post, checkpoint57y_post, hrcube_1, checkpoint57e_post, checkpoint66g, checkpoint66f, checkpoint66e, checkpoint66d, checkpoint66c, checkpoint66b, checkpoint66a, checkpoint66o, checkpoint66n, checkpoint66m, checkpoint66l, checkpoint66k, checkpoint66j, checkpoint66i, checkpoint66h, branch-netcdf, checkpoint52d_pre, checkpoint52l_post, checkpoint55h_post, checkpoint58n_post, checkpoint53b_post, checkpoint58x_post, checkpoint52k_post, checkpoint52b_pre, checkpoint57g_pre, checkpoint54b_post, checkpoint53b_pre, checkpoint55b_post, checkpoint58t_post, checkpoint58h_post, checkpoint65z, checkpoint65x, checkpoint65y, checkpoint54d_post, checkpoint65r, checkpoint65s, checkpoint65p, checkpoint65q, checkpoint65v, checkpoint65w, checkpoint65t, checkpoint65u, checkpoint65j, checkpoint65k, checkpoint65h, checkpoint65i, checkpoint65n, checkpoint65o, checkpoint65l, checkpoint65m, checkpoint65b, checkpoint65c, checkpoint65a, checkpoint65f, checkpoint65g, checkpoint65d, checkpoint65e, checkpoint56c_post, checkpoint52m_post, checkpoint57y_pre, checkpoint55, checkpoint53a_post, checkpoint57f_pre, checkpoint57a_post, checkpoint54, checkpoint58q_post, checkpoint54f_post, checkpoint57v_post, checkpoint59q, checkpoint59p, checkpoint55g_post, checkpoint59r, checkpoint51o_post, checkpoint51p_post, checkpoint58j_post, checkpoint52a_pre, checkpoint59e, checkpoint59d, checkpoint59g, checkpoint59f, checkpoint59a, checkpoint55f_post, checkpoint59c, checkpoint59b, checkpoint59m, checkpoint59l, checkpoint59o, checkpoint59n, checkpoint59i, checkpoint59h, checkpoint59k, checkpoint59j, checkpoint57r_post, checkpoint59, checkpoint58, checkpoint57a_pre, checkpoint55i_post, checkpoint57, checkpoint56, checkpoint51i_post, checkpoint53, checkpoint52, checkpoint51f_post, checkpoint52d_post, eckpoint57e_pre, checkpoint51r_post, checkpoint52a_post, checkpoint57h_done, checkpoint58f_post, checkpoint52b_post, checkpoint53g_post, checkpoint52f_post, branchpoint-genmake2, checkpoint57x_post, checkpoint57n_post, checkpoint52c_post, checkpoint58d_post, checkpoint58c_post, checkpoint57w_post, checkpoint57p_post, checkpint57u_post, checkpoint57f_post, checkpoint58a_post, checkpoint51h_pre, checkpoint51l_pre, checkpoint58i_post, checkpoint57q_post, checkpoint51g_post, checkpoint58g_post, ecco_c52_e35, hrcube5, checkpoint58o_post, checkpoint57z_post, checkpoint62c, checkpoint62b, checkpoint62a, checkpoint62g, checkpoint62f, checkpoint62e, checkpoint62d, checkpoint62k, checkpoint62j, checkpoint62i, checkpoint62h, checkpoint62o, checkpoint62n, checkpoint62m, checkpoint62l, checkpoint62s, checkpoint62r, checkpoint62q, checkpoint62p, checkpoint62w, checkpoint62v, checkpoint62u, checkpoint62t, checkpoint57c_post, checkpoint62z, checkpoint62y, checkpoint62x, checkpoint58y_post, checkpoint55e_post, checkpoint58k_post, checkpoint52i_post, checkpoint52j_pre, checkpoint58v_post, checkpoint53f_post, checkpoint55a_post, checkpoint51t_post, checkpoint53d_pre, checkpoint54c_post, checkpoint58s_post, checkpoint61f, checkpoint61g, checkpoint61d, checkpoint61e, checkpoint61b, checkpoint61c, checkpoint58p_post, checkpoint61a, checkpoint61n, checkpoint61o, checkpoint61l, checkpoint61m, checkpoint61j, checkpoint61k, checkpoint61h, checkpoint61i, checkpoint61v, checkpoint61w, checkpoint61t, checkpoint61u, checkpoint61r, checkpoint61s, checkpoint61p, checkpoint61q, checkpoint51n_post, checkpoint57j_post, checkpoint61z, checkpoint61x, checkpoint61y, checkpoint58b_post, checkpoint57h_pre, checkpoint51i_pre, checkpoint58m_post, checkpoint57l_post, checkpoint52i_pre, checkpoint51u_post, checkpoint52h_pre, checkpoint52f_pre, checkpoint57h_post, hrcube_2, hrcube_3, checkpoint56a_post, checkpoint51m_post, checkpoint51s_post, checkpoint55d_post, HEAD
Branch point for: branch-nonh, branch-genmake2, tg2-branch, checkpoint51n_branch, netcdf-sm0
File MIME type: text/plain
Initial check-in of the CMU "mpack" utility.  This allows us to (portably)
send MITgcm output as MIME-encoded email messages and will be used by the
"testreport" script.  The CMU license is basically an "AS-IS" statement.

1 edhill 1.1 /* macnapp.c -- macintosh nifty application library
2     */
3     /* (C) Copyright 1995 by Carnegie Mellon University
4     * All Rights Reserved.
5     *
6     * Permission to use, copy, modify, distribute, and sell this software
7     * and its documentation for any purpose is hereby granted without
8     * fee, provided that the above copyright notice appear in all copies
9     * and that both that copyright notice and this permission notice
10     * appear in supporting documentation, and that the name of Carnegie
11     * Mellon University not be used in advertising or publicity
12     * pertaining to distribution of the software without specific,
13     * written prior permission. Carnegie Mellon University makes no
14     * representations about the suitability of this software for any
15     * purpose. It is provided "as is" without express or implied
16     * warranty.
17     *
18     * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
19     * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
20     * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
21     * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22     * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
23     * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
24     * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
25     * SOFTWARE.
26     */
27     /* (C) Copyright 1990-1995 by Christopher J. Newman
28     * All Rights Reserved.
29     *
30     * Permission to use, copy, modify, distribute, and sell this software and its
31     * documentation for any purpose is hereby granted without fee, provided that
32     * the above copyright notice appear in all copies and that both that
33     * copyright notice and this permission notice appear in supporting
34     * documentation, and that the name of Christopher J. Newman not be used in
35     * advertising or publicity pertaining to distribution of the software without
36     * specific, written prior permission. Christopher J. Newman makes no
37     * representations about the suitability of this software for any purpose. It
38     * is provided "as is" without express or implied warranty.
39     *
40     * CHRISTOPHER J. NEWMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
41     * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
42     * SHALL CHRISTOPHER J. NEWMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
43     * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
44     * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
45     * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
46     * OF THIS SOFTWARE.
47     *
48     * Author: Christopher J. Newman
49     * Message: This is a nifty program.
50     */
51    
52     #ifndef THINK_C
53     #include <Resources.h>
54     #include <Dialogs.h>
55     #include <Desk.h>
56     #include <SegLoad.h>
57     #include <OSEvents.h>
58     #include <DiskInit.h>
59     #include <Traps.h>
60     #include <ToolUtils.h>
61     #endif
62     #include <AppleEvents.h>
63     #include "macnapp.h"
64    
65     /* export globals */
66     na_win **NAhead = (na_win**) NULL; /* head of the window tree */
67     na_win **NAtask = (na_win**) NULL; /* head of the task list */
68     na_win **NActask = (na_win**) NULL; /* next task to be called */
69     na_win *NAwin = (na_win*) NULL; /* the current window */
70     na_menup NAmenup = (na_menup) NULL; /* application menu procedure */
71     MenuHandle **NAmenus; /* list of menu handles */
72     short NAnewitem = 0; /* the new item number */
73     short NAcloseitem = 0; /* the close item number */
74     short NAappleitems = 0; /* number of user apple menu items */
75     short NAhelpitems = 0; /* number of user help menu items */
76     short NAhelpcount = 0; /* number of system help menu items */
77     Boolean NAhasedit = false; /* true if application supports edit menu */
78     long NAdelay = 30; /* delay (1/60th of a second) between null events */
79     SysEnvRec NAsysenv; /* set up by Initialize */
80     Boolean NAinBack = false; /* true when app is in the background */
81     short NAlastmouse = NA_RELEASE; /* the last mouse event type */
82     long NAmousetime = 0; /* the time of the last mouse up */
83     Point NAmousept; /* the point (local) of last mouse down */
84    
85     THz NAappzone; /* the application heap zone */
86     RgnHandle NAfullRgn; /* a region containing everything */
87     RgnHandle NAnullRgn; /* a region containing nothing */
88     Cursor NAibeam; /* the Ibeam cursor */
89     long NAgestaltBits; /* flags for gestalt options */
90    
91     /* private globals */
92     static Point mselpoint; /* the menu selection point */
93     static short aestatus; /* if set, close everything */
94    
95     /* constants for DoDraw procedure */
96     #define DO_UPDATE 0x0
97     #define DO_RESIZE 0x1
98     #define DO_ACTIVATE 0x2
99     #define DO_DEACTIVATE 0x4
100    
101     /* private routines */
102    
103     static na_win **GetWinH(WindowPtr);
104     static void DoDraw(na_win*, short);
105     static short DoActivate(WindowPtr, na_win*, Boolean, Point p);
106     static short DoMenu(na_win*, BYTE);
107     static void AdjustCursor(na_win*, Point, Boolean);
108     static short aboutmouse(na_win*, Point, short, short);
109    
110     /* get the handle to a window
111     */
112     static na_win **GetWinH(WindowPtr window)
113     {
114     na_win **winh;
115    
116     /* make positively sure that we have a valid handle */
117     if (window != (WindowPtr) NULL && !NAisDAWindow(window)) {
118     #ifdef DEBUG
119     if (PtrZone((Ptr) window) == NAappzone && MemError() == noErr) {
120     #endif
121     if ((winh = (na_win **) GetWRefCon(window)) != (na_win**) NULL) {
122     #ifdef DEBUG
123     if (HandleZone((Handle) winh) == NAappzone && MemError() == noErr) {
124     if ((*winh)->pwin == window) {
125     #endif
126     return (winh);
127     #ifdef DEBUG
128     } else {
129     NAdebug("Corrupted window structure found.\015");
130     NAdebug("handle: %lx, pwin: %lx, window: %lx\015",
131     (long) winh, (long) (*winh)->pwin, (long) window);
132     Debugger();
133     }
134     } else {
135     NAdebug("Corrupted Handle Zone Found.\015");
136     NAdebug("handle: %lx, error: %ld\015", (long) winh,
137     (long) MemError());
138     Debugger();
139     }
140     #endif
141     }
142     #ifdef DEBUG
143     } else {
144     NAdebug("Corrupted Window Pointer Found.\n");
145     NAdebug("Pointer: %lx, error: %ld\n", (long) window, (long) MemError());
146     Debugger();
147     }
148     #endif
149     }
150     return ((na_win**) NULL);
151     }
152    
153     /* handle drawing controls & growbox for update/activate events
154     */
155     static void DoDraw(na_win *winp, short how)
156     {
157     WindowPtr window = winp->pwin;
158     long flags = winp->flags;
159     ControlHandle ctrl;
160     Rect tmpRect;
161     RgnHandle tmpRgn;
162    
163     /* hilite or draw controls as appropriate */
164     if (flags & NA_HASCONTROLS) {
165     if (how & (DO_ACTIVATE | DO_DEACTIVATE)) {
166     if (flags & NA_HILITECTRLS) {
167     for (ctrl = ((WindowPeek) window)->controlList; ctrl;
168     ctrl = (*ctrl)->nextControl) {
169     HiliteControl(ctrl, (how & DO_ACTIVATE) ? 0 : 255);
170     }
171     }
172     } else {
173     DrawControls(window);
174     }
175     }
176    
177     /* draw the grow box properly -- mask out scroll bar outlines */
178     if (flags & NA_GROWBOX) {
179     tmpRgn = window->clipRgn;
180     tmpRect.left = (tmpRect.right = window->portRect.right) - 15;
181     tmpRect.top = (tmpRect.bottom = window->portRect.bottom) - 15;
182     RectRgn(window->clipRgn = NewRgn(), &tmpRect);
183     DrawGrowIcon(window);
184     DisposeRgn(window->clipRgn);
185     window->clipRgn = tmpRgn;
186     }
187    
188     /* draw the default button on a dialog */
189     if (flags & NA_DEFBUTTON) NAdefaultButton(window);
190    
191     /* calculate the un-cursor region if the window size changed */
192     if (how & DO_RESIZE) NAcalcCursor(winp);
193     }
194    
195     /* handle activate event (either activate or MultiFinder suspend/resume)
196     */
197     static short DoActivate(WindowPtr window, na_win *winp, Boolean activate, Point p)
198     {
199     na_win **winh;
200     short status = NA_NOTPROCESSED;
201     GrafPtr tmpPort;
202    
203     /* unlock current front window */
204     if (winp != (na_win*) NULL) {
205     NAunlockWindow(winp);
206     NAwin = (na_win*) NULL;
207     }
208    
209     /* check if there is a new window, and lock it */
210     if (window == (WindowPtr) NULL) return (NA_PROCESSED);
211    
212     /* for app windows, update the cursor, call the activate proc, and DoDraw */
213     if ((NAwin = winp = NAlockWindow(winh = GetWinH(window))) != (na_win*) NULL) {
214     GetPort(&tmpPort);
215     SetPort(window);
216     if (winp->cursorRgn != (RgnHandle) NULL && ((activate && !NAinBack)
217     || winp->flags & NA_CURSORON)) {
218     LocalToGlobal(&p);
219     AdjustCursor(winp, p, activate);
220     }
221     if (winp->activep == (na_activep) NULL
222     || (status = (*winp->activep)(winp, activate)) == NA_NOTPROCESSED) {
223     DoDraw(winp, activate ? DO_ACTIVATE : DO_DEACTIVATE);
224     }
225     if (!activate || winp->pwin != FrontWindow()) {
226     SetPort(tmpPort);
227     NAunlockWindowh(winh, winp);
228     NAwin = (na_win*) NULL;
229     }
230     }
231    
232     return (status);
233     }
234    
235     /* handle menu selection -- either menu click or menu shortcut
236     */
237     static short DoMenu(na_win *winp, BYTE key)
238     {
239     WindowPtr window = FrontWindow();
240     short status = NA_NOTPROCESSED;
241     WORD menuid, itemno;
242     MenuHandle mnu;
243     long menusel;
244     PCstr mItem[256];
245    
246     /* enable/disable edit menu as appropriate */
247     if (NAhasedit) {
248     mnu = NAmenuh(mEdit);
249    
250     if (NAisDAWindow(window)) {
251     EnableItem(mnu, iUndo);
252     for (itemno = iCut; itemno <= iClear; itemno++) {
253     EnableItem(mnu, itemno);
254     }
255     } else {
256     DisableItem(mnu, iUndo);
257     for (itemno = iCut; itemno <= iClear; itemno++) {
258     DisableItem(mnu, itemno);
259     }
260     }
261     }
262    
263     /* enable/disable the close menu as appropriate */
264     if (NAcloseitem) {
265     mnu = NAmenuh(mFile);
266    
267     if (window != (WindowPtr) NULL && (winp == (na_win*) NULL
268     || winp->pwin != window || winp->flags & NA_CLOSEBOX)) {
269     EnableItem(mnu, NAcloseitem);
270     } else {
271     DisableItem(mnu, NAcloseitem);
272     }
273     }
274    
275     /* call menu proc to enable/disable items as appropriate */
276     if (winp != (na_win*) NULL && winp->menup != (na_menup) NULL) {
277     status = (*winp->menup)(winp, (WORD) 0, (WORD) key);
278     }
279     if (status == NA_NOTPROCESSED && NAmenup != (na_menup) NULL
280     && (winp == (na_win *) NULL || !(winp->flags & NA_MODAL))) {
281     status = (*NAmenup)(winp, (WORD) 0, (WORD) key);
282     }
283     if (status != NA_NOTPROCESSED) return (status);
284    
285     /* get menu selection */
286     menusel = (key == 0) ? MenuSelect(mselpoint) : MenuKey(key);
287     itemno = LOWORD(menusel);
288     if ((menuid = HIWORD(menusel)) == 0) menuid = 1;
289    
290     /* check for DA menu items */
291     switch (menuid) {
292     case mApple: /* check for a desk accessary selection */
293     if (itemno > NAappleitems) {
294     if (itemno - NAappleitems <= NAhelpitems) {
295     itemno -= NAappleitems;
296     menuid = mHelp;
297     } else {
298     GetItem(NAmenuh(mApple), itemno, mItem);
299     OpenDeskAcc(mItem);
300     menuid = 1;
301     }
302     }
303     break;
304    
305     case mFile: /* check for the close menu item for DAs */
306     if (itemno == NAcloseitem && NAisDAWindow(window)) {
307     CloseDeskAcc(((WindowPeek) window)->windowKind);
308     menuid = 1;
309     }
310     break;
311    
312     case mEdit: /* check for the edit menu for DAs */
313     if (NAhasedit && itemno <= iClear && SystemEdit(itemno - iUndo)) {
314     menuid = 1;
315     }
316     break;
317    
318     case mHelp:
319     itemno -= NAhelpcount;
320     break;
321     }
322    
323     /* call menu proc to handle/disable items */
324     if (winp != (na_win*) NULL && winp->menup != (na_menup) NULL) {
325     status = (*winp->menup)(winp, menuid, itemno);
326     }
327     if (status != NA_PROCESSED && NAmenup != (na_menup) NULL) {
328     status = (*NAmenup)(winp, menuid, itemno);
329     }
330    
331     /* if close/about item wasn't processed, process it */
332     if (status == NA_NOTPROCESSED) {
333     if (menuid == mFile && itemno == NAcloseitem) {
334     status = NA_REQCLOSE;
335     } else if (menuid == mApple && itemno == iAbout) {
336     NAwindow(0, NA_DIALOGWINDOW | NA_USERESOURCE | NA_MODAL,
337     NULL, NA_ABOUTDLOG, (long *) NULL, 0, NAabout);
338     }
339     }
340    
341     /* turn off the menu */
342     HiliteMenu(0);
343    
344     return (status);
345     }
346    
347     /* set the cursor icon appropriately
348     */
349     static void AdjustCursor(na_win *winp, Point gmouse, Boolean active)
350     {
351     short status = NA_NOTPROCESSED;
352    
353     /* don't change the cursor when in wrong window */
354     if (active && FrontWindow() != winp->pwin) return;
355    
356     /* if the cursor is on */
357     if (winp->flags & NA_CURSORON) {
358     /* and the point moves outside the cursor region or window is deactivated
359     * turn cursor off */
360     if (!active || PtInRgn(gmouse, winp->uncrsrRgn)) {
361     winp->flags &= ~NA_CURSORON;
362     if (winp->cursorp == (na_cursorp*) NULL) {
363     SetCursor(&QD(arrow));
364     } else {
365     goto DOCURSORP;
366     }
367     }
368    
369     /* if the cursor is off and the point moves into the window, turn cursor on */
370     } else if (PtInRgn(gmouse, winp->cursorRgn)) {
371     winp->flags |= NA_CURSORON;
372     if (winp->cursorp == (na_cursorp) NULL) {
373     SetCursor(&NAibeam);
374     } else {
375     DOCURSORP:
376     GlobalToLocal(&gmouse);
377     status = (*winp->cursorp)(winp, gmouse);
378     }
379     }
380    
381     /* if cursor event was processed, reset the un-cursor region */
382     if (status == NA_PROCESSED) NAcalcCursor(winp);
383     }
384    
385    
386     /* export routines */
387    
388     /* save the current window position in a resource file
389     */
390     void NAsaveWin(na_win *winp)
391     {
392     Rect *rptr;
393     WindowPtr window = winp->pwin;
394     Handle wind = GetResource('WIND', winp->resid);
395    
396     HLock(wind);
397     rptr = (Rect *) *wind;
398     rptr->right = (rptr->left = -window->portBits.bounds.left)
399     + window->portRect.right;
400     rptr->bottom = (rptr->top = -window->portBits.bounds.top)
401     + window->portRect.bottom;
402     ChangedResource(wind);
403     HUnlock(wind);
404     }
405    
406     /* calculate the cursor regions for Multi-Finder
407     */
408     void NAcalcCursor(na_win *winp)
409     {
410     if (winp->cursorRgn != (RgnHandle) NULL) {
411     if (winp->uncrsrRgn == (RgnHandle) NULL) winp->uncrsrRgn = NewRgn();
412     DiffRgn(NAfullRgn, winp->cursorRgn, winp->uncrsrRgn);
413     }
414     }
415    
416     /* lock a window context
417     */
418     na_win *NAlockWindow(na_win **winh)
419     {
420     if (winh == (na_win**) NULL) return ((na_win*) NULL);
421     if (!(*winh)->locks++) {
422     MoveHHi((Handle) winh);
423     HLock((Handle) winh);
424     }
425    
426     return (*winh);
427     }
428    
429     /* request or force a window to close
430     */
431     short NAcloseWindow(na_win *winp, short status)
432     {
433     na_win **winh, ***whp;
434     short childstatus;
435    
436     if (winp == (na_win*) NULL) return (NA_NOTPROCESSED);
437     switch (status) {
438     case NA_REQCLOSE:
439     /* check if window ready to close */
440     status = NA_CLOSED;
441     if (winp->closep != (na_closep) NULL) status = (*winp->closep)(winp);
442     if (status > NA_CLOSED) break;
443     case NA_CLOSED:
444     /* close children */
445     childstatus = NAcloseWindows(winp->child, NA_REQCLOSEALL);
446     /* clear current window */
447     if (winp == NAwin) NAwin = (na_win*) NULL;
448     /* reset the cursor */
449     if (winp->flags & NA_CURSORON) SetCursor(&QD(arrow));
450     /* dispose of any cursor regions */
451     if (winp->cursorRgn != (RgnHandle) NULL) DisposeRgn(winp->cursorRgn);
452     if (winp->uncrsrRgn != (RgnHandle) NULL) DisposeRgn(winp->uncrsrRgn);
453     /* close the window */
454     if (winp->pwin != (WindowPtr) NULL) {
455     if (winp->flags & NA_DIALOGWINDOW) {
456     DisposDialog((DialogPtr) winp->pwin);
457     } else {
458     DisposeWindow(winp->pwin);
459     }
460     }
461     /* remove from window list */
462     winh = (na_win**) RecoverHandle((Ptr) winp);
463     whp = &NAhead;
464     if (winp->parent != (na_win**) NULL) whp = &(*winp->parent)->child;
465     while (*whp != (na_win**) NULL) {
466     if (*whp == winh) {
467     *whp = winp->next;
468     } else {
469     whp = &(**whp)->next;
470     }
471     }
472     /* relink children in list */
473     if (childstatus > NA_ALLCLOSED) {
474     *whp = winp->child;
475     do {
476     (**whp)->parent = winp->parent;
477     whp = &(**whp)->next;
478     } while (*whp != (na_win**) NULL);
479     *whp = winp->next;
480     }
481     /* remove from task list */
482     whp = &NAtask;
483     while (*whp != (na_win**) NULL && *whp != winh) {
484     whp = &(**whp)->task;
485     }
486     *whp = winp->task;
487     NActask = (na_win**) NULL;
488     /* after-close function */
489     if (winp->afterp != (na_afterp) NULL) (*winp->afterp)(winp);
490     /* destroy window structure */
491     DisposHandle((Handle) winh);
492     if (status < NA_CLOSED) {
493     if ((status = NAcloseWindows(NAhead, status)) > NA_CLOSED) {
494     status = NA_CLOSED;
495     }
496     }
497     break;
498     }
499    
500     return (status);
501     }
502    
503     short NAcloseWindows(na_win **winh, short status)
504     {
505     na_win *winp, **lasth;
506     short substatus;
507    
508     while ((winp = NAlockWindow(winh)) != (na_win*) NULL) {
509     lasth = winh;
510     winh = winp->next;
511     substatus = NAcloseWindow(winp, status + 2);
512     if (substatus > NA_CLOSED) {
513     NAunlockWindowh(lasth, winp);
514     return (NA_NOTPROCESSED);
515     }
516     if (substatus < NA_CLOSED) return (substatus);
517     }
518    
519     return (NA_ALLCLOSED);
520     }
521    
522     /* remove the window on a mouse-up event
523     */
524     static short aboutmouse(na_win *winp, Point mousep, short type, short mods)
525     #ifdef applec
526     #pragma unused (winp, mousep, mods)
527     #endif
528     {
529     return (type & 1 ? NA_REQCLOSE : NA_PROCESSED);
530     }
531    
532     /* a standard about box init procedure
533     */
534     short NAabout(na_win *winp, long *dptr)
535     #ifdef applec
536     #pragma unused (dptr)
537     #endif
538     {
539     winp->mousep = aboutmouse;
540    
541     return (NA_PROCESSED);
542     }
543    
544     /* flash a button in a dialog box for equivalent keypresses
545     */
546     void NAflashButton(DialogPtr dialog, short item)
547     {
548     long scratch;
549     short type;
550     Handle ctrl;
551     Rect box;
552    
553     GetDItem(dialog, item, &type, &ctrl, &box);
554     if (type == ctrlItem + btnCtrl) {
555     HiliteControl((ControlHandle) ctrl, 1);
556     Delay(5, &scratch);
557     HiliteControl((ControlHandle) ctrl, 0);
558     }
559     }
560    
561     /* draw the default button
562     */
563     void NAdefaultButton(DialogPtr dialog)
564     {
565     Rect tmpRect;
566     PenState pnState;
567    
568     NAgetDRect(dialog, iOk, &tmpRect);
569     GetPenState(&pnState);
570     PenNormal();
571     PenSize(3, 3);
572     InsetRect(&tmpRect, -4, -4);
573     FrameRoundRect(&tmpRect, 16, 16);
574     SetPenState(&pnState);
575     }
576    
577     /* a filter proc which handles Return, Enter, Esc, command-period properly
578     */
579     pascal Boolean NAfilterProc(DialogPtr dialog, EventRecord *pevent, short *item)
580     {
581     if (pevent->what == autoKey || pevent->what == keyDown) {
582     switch (pevent->message & charCodeMask) {
583     case '\r':
584     case '\n':
585     case 0x03:
586     *item = 1;
587     goto HILITE;
588    
589     case '.':
590     if (!(pevent->modifiers & cmdKey)) break;
591     case '\033':
592     *item = 2;
593     HILITE:
594     NAflashButton(dialog, *item);
595     return (true);
596     }
597     }
598    
599     return (false);
600     }
601    
602     /* send an event message to all windows
603     */
604     short NAallWindows(na_win **winh, EventRecord *pevent)
605     {
606     na_win *winp, **oldwinh;
607     short status = NA_NOTPROCESSED;
608    
609     while ((winp = NAlockWindow(winh)) != (na_win*) NULL) {
610     oldwinh = winh;
611     winh = winp->next;
612     if (winp->miscp != (na_miscp) NULL) {
613     GrafPtr tempPort;
614    
615     GetPort(&tempPort);
616     SetPort(winp->pwin);
617     status = (*winp->miscp)(winp, pevent);
618     SetPort(tempPort);
619     }
620     if ((status == NA_CLOSED || status == NA_REQCLOSE)
621     && NAcloseWindow(winp, status) == NA_CLOSED) {
622     continue;
623     }
624     NAunlockWindowh(oldwinh, winp);
625     if (status == NA_ALLCLOSED || status == NA_REQCLOSEALL) {
626     if (NAcloseWindows(NAhead, status) == NA_ALLCLOSED) {
627     return (NA_ALLCLOSED);
628     }
629     /* make sure our handle is still valid */
630     if (GetHandleSize((Handle) oldwinh) == 0) continue;
631     }
632     if ((*oldwinh)->child != (na_win**) NULL &&
633     NAallWindows((*oldwinh)->child, pevent) == NA_ALLCLOSED) {
634     return (NA_ALLCLOSED);
635     }
636     }
637    
638     return (NA_PROCESSED);
639     }
640    
641     /* apple event handler
642     */
643     pascal OSErr NArequiredAE(AppleEvent *, AppleEvent *, long);
644     pascal OSErr NArequiredAE(AppleEvent *event, AppleEvent *reply, long ref)
645     {
646     na_openp openp = (na_openp) ref;
647     OSErr err;
648     DescType actualType, eventID;
649     Size actualSize;
650     AEDescList doclist;
651     long count, i;
652     short gotdoc;
653     FSSpec fspec;
654     AEKeyword keywd;
655     FInfo finfo;
656    
657     err = AEGetAttributePtr(event, keyEventIDAttr, typeType, &actualType,
658     (Ptr) &eventID, sizeof (eventID), &actualSize);
659     if (err == noErr) {
660     gotdoc = 0;
661     if (eventID == kAEOpenDocuments || eventID == kAEPrintDocuments) {
662     err = AEGetParamDesc(event, keyDirectObject, typeAEList, &doclist);
663     if (err == noErr) gotdoc = 1;
664     }
665     if (err == noErr) {
666     err = AEGetAttributePtr(event, keyMissedKeywordAttr, typeWildCard,
667     &actualType, NULL, 0, &actualSize);
668     if (err == errAEDescNotFound) {
669     err = noErr;
670     } else if (err == noErr) {
671     err = errAEEventNotHandled;
672     }
673     }
674     if (err == noErr) switch (eventID) {
675     case kAEOpenApplication:
676     if (NAmenup && NAnewitem) {
677     aestatus = (*NAmenup)(NULL, mFile, NAnewitem);
678     }
679     break;
680     case kAEOpenDocuments:
681     case kAEPrintDocuments:
682     err = AECountItems(&doclist, &count);
683     if (err != noErr) break;
684     for (i = 1; i <= count; ++i) {
685     err = AEGetNthPtr(&doclist, i, typeFSS, &keywd, &actualType,
686     (Ptr) &fspec, sizeof (fspec), &actualSize);
687     if (err != noErr) break;
688     FSpGetFInfo(&fspec, &finfo);
689     if (!openp || (*openp)(eventID == kAEOpenDocuments
690     ? appOpen : appPrint, &fspec, &finfo) <= 0) {
691     err = errAEEventNotHandled;
692     break;
693     }
694     }
695     break;
696     case kAEQuitApplication:
697     aestatus = NA_ALLCLOSED;
698     if (NAhead != NULL) {
699     aestatus = NAcloseWindows(NAhead, NA_REQCLOSEALL);
700     if (aestatus != NA_ALLCLOSED) err = userCanceledErr;
701     }
702     break;
703     }
704     if (gotdoc) {
705     AEDisposeDesc(&doclist);
706     }
707     }
708    
709     return (err);
710     }
711    
712     /* handle Dialog window events
713     */
714     static Boolean DoDialog(na_win *winp, EventRecord *event, Point mouse,
715     short item, short *status)
716     {
717     DialogPtr dialog = NULL;
718     ControlHandle ctrlh;
719     Boolean result = false;
720    
721     if (*status == NA_NOTPROCESSED && (item || ((result = IsDialogEvent(event))
722     && DialogSelect(event, &dialog, &item))) && winp && winp->ctrlp) {
723     if (!dialog) dialog = winp->pwin;
724     NAgetDHandle(dialog, item, &ctrlh);
725     *status = (*winp->ctrlp)(winp, mouse, item, event->modifiers, ctrlh);
726     }
727    
728     return (result);
729     }
730    
731     /* call the main loop procedure
732     */
733     void NAmainloop()
734     {
735     na_win *winp, *wp, **wh;
736     Boolean gotEvent;
737     EventRecord event;
738     Point mouse;
739     Point ptemp;
740     short status;
741     short citem, item;
742     short part;
743     short delay;
744     short mousepix;
745     short fastdelay = 0;
746     long growInfo;
747     long key;
748     WindowPtr window;
749     GrafPtr tempPort;
750     ControlHandle ctrl;
751     RgnHandle rgn;
752     Rect tmpRect, bRect;
753     short prioritycnt;
754    
755     UnloadSeg((Ptr) NAinit); /* unload the initialize routine */
756    
757     do {
758     /* check for a window in front */
759     if ((winp = NAwin) == (na_win*) NULL
760     && (window = FrontWindow()) != (WindowPtr) NULL
761     && (NAwin = winp = NAlockWindow(GetWinH(window))) != (na_win *) NULL) {
762     SetPort(window);
763     }
764    
765     /* get an event */
766     rgn = NAfullRgn;
767     delay = NAdelay;
768     /* if there is an app window in front, use app delay & cursor region */
769     if (winp != (na_win*) NULL) {
770     delay = winp->delay;
771     if (winp->cursorRgn != (RgnHandle) NULL && !NAinBack) {
772     rgn = winp->cursorRgn;
773     if (!(winp->flags & NA_CURSORON)) rgn = winp->uncrsrRgn;
774     }
775     if (winp->mousepix && !(NAlastmouse & 1)) {
776     rgn = NAnullRgn;
777     delay = 0;
778     }
779     }
780     gotEvent = WaitNextEvent(everyEvent, &event, fastdelay ? 0 : delay, rgn);
781     fastdelay = 0;
782     status = NA_NOTPROCESSED;
783    
784     /* get mouse position */
785     mouse = event.where;
786     GlobalToLocal(&mouse);
787     item = 0;
788    
789     /* handle the event */
790     if (gotEvent) switch (event.what) {
791     case mouseUp:
792     /* deal with mouse up events to keep track of double/triple clicks */
793     if (NAlastmouse & 1) break;
794     ++NAlastmouse;
795     NAmousetime = TickCount();
796     if (winp == (na_win*) NULL) break;
797     DOMOUSEP:
798     if (winp->mousep != (na_mousep) NULL) {
799     status = (*winp->mousep)(winp, mouse, NAlastmouse, event.modifiers);
800     }
801     break;
802    
803     case mouseDown:
804     part = FindWindow(event.where, &window);
805     /* Rules for clicks when a modal dialog is in front:
806     * 1) let the user command-move other windows
807     * 2) don't let user do anything else with other app windows
808     * 3) if not movable, require click to be in window
809     */
810     if (winp != (na_win*) NULL && winp->flags & NA_MODAL
811     && !(part == inDrag && event.modifiers & cmdKey)
812     && ((!(winp->flags & NA_TITLEBAR)
813     && !PtInRect(mouse, &winp->pwin->portRect))
814     || (window != NULL && window != winp->pwin))) {
815     SysBeep(10);
816     status = NA_PROCESSED;
817     break;
818     }
819     switch (part) {
820     case inMenuBar:
821     /* call an appropriate menu bar handler */
822     mselpoint = event.where;
823     status = DoMenu(winp, 0);
824     break;
825    
826     case inSysWindow:
827     /* System Click in DA */
828     SystemClick(&event, window);
829     break;
830    
831     case inContent:
832     /* click a window to front if not in front */
833     if (window != FrontWindow()) {
834     SelectWindow(window);
835     if (winp != (na_win*) NULL) NAunlockWindow(winp);
836     NAwin = (na_win*) NULL;
837     NAlastmouse = NA_RELEASE;
838     break;
839     }
840    
841     /* don't bother processing further if no mouse proc */
842     if (winp == (na_win*) NULL) break;
843    
844     /* check for control events */
845     if (winp->ctrlp != (na_ctrlp) NULL && winp->flags & NA_HASCONTROLS) {
846     if ((citem = FindControl(mouse, window, &ctrl)) != 0
847     && (status = (*winp->ctrlp)(winp, mouse, citem,
848     event.modifiers, ctrl)) != NA_NOTPROCESSED) {
849     break;
850     }
851     }
852    
853     /* deal with double clicks */
854     if ((NAlastmouse & 1) && NAlastmouse < NA_RELEASE
855     && event.when - NAmousetime <= GetDblTime()) {
856     if (++NAlastmouse > NA_DOWNN) NAlastmouse = NA_DOWNN;
857     } else {
858     NAlastmouse = NA_DOWN1;
859     }
860     NAmousept = mouse;
861    
862     /* call the mouse handler */
863     goto DOMOUSEP;
864    
865     case inDrag:
866     /* drag the window */
867     tmpRect = QD(screenBits.bounds);
868     InsetRect(&tmpRect, 4, 4);
869     bRect = window->portBits.bounds;
870     DragWindow(window, event.where, &tmpRect);
871     if ((bRect.left != window->portBits.bounds.left
872     || bRect.top != window->portBits.bounds.top) &&
873     (wp = NAlockWindow(wh = GetWinH(window))) != NULL) {
874     if (wp->flags & NA_SMARTSIZE) NAsaveWin(wp);
875     if (wp->cursorRgn != (RgnHandle) NULL) {
876     OffsetRgn(wp->cursorRgn,
877     bRect.left - window->portBits.bounds.left,
878     bRect.top - window->portBits.bounds.top);
879     NAcalcCursor(wp);
880     }
881     NAunlockWindowh(wh, wp);
882     }
883     break;
884    
885     case inGoAway:
886     /* deal with the close window box */
887     if (TrackGoAway(window, event.where)) status = NA_REQCLOSE;
888     break;
889    
890     case inGrow:
891     /* grow the window */
892     /* assume there is a valid app window in front */
893     /* calculate min & max grow dimensions */
894     tmpRect = QD(screenBits.bounds);
895     tmpRect.bottom -= tmpRect.top;
896     tmpRect.right -= tmpRect.left;
897     tmpRect.top = winp->minh;
898     tmpRect.left = winp->minw;
899     if (winp->maxh) tmpRect.bottom = winp->maxh;
900     if (winp->maxw) tmpRect.right = winp->maxw;
901    
902     /* check for resize proc */
903     if (winp->resizep != (na_resizep) NULL) {
904     status = (*winp->resizep)(winp, event.where, &tmpRect);
905     if (status == NA_PROCESSED) break;
906     goto RESIZEWINDOW;
907     }
908    
909     /* grow, resize, and update the window */
910     if ((growInfo = GrowWindow(window, event.where, &tmpRect))) {
911     SizeWindow(window, LOWORD(growInfo), HIWORD(growInfo),
912     false);
913     goto RESIZEWINDOW;
914     }
915     break;
916    
917     case inZoomIn:
918     case inZoomOut:
919     /* assume there is a valid app window in front */
920     /* track, zoom, and update the window */
921     if (TrackBox(window, event.where, part)) {
922     SetPort(window);
923     EraseRect(&window->portRect);
924     ZoomWindow(window, part, true);
925     RESIZEWINDOW:
926     if (winp != (na_win*) NULL) {
927     if (winp->flags & NA_SMARTSIZE) NAsaveWin(winp);
928     if (winp->updatep == (na_updatep) NULL ||
929     (status = (*winp->updatep)(winp, (Boolean) true))
930     == NA_NOTPROCESSED) {
931     DoDraw(winp, DO_RESIZE);
932     }
933     }
934     ValidRect(&window->portRect);
935     }
936     break;
937     }
938     break;
939    
940     case keyDown:
941     case autoKey:
942     /* deal with keyboard events */
943     key = event.message & charCodeMask;
944    
945     /* call the window's key handling procedure */
946     if (winp != (na_win *) NULL && winp->keyp != (na_keyp) NULL) {
947     status = (*winp->keyp)(winp, winp->flags & NA_RAWKEY ? event.message : key,
948     event.modifiers);
949     }
950    
951     /* translate command-foo to an appropriate menu operation */
952     if (status == NA_NOTPROCESSED &&
953     (event.modifiers & cmdKey) && event.what == keyDown &&
954     (status = DoMenu(winp, key)) != NA_NOTPROCESSED) {
955     break;
956     }
957    
958     /* require an app window for further processing */
959     if (winp == (na_win*) NULL) break;
960    
961     /* if it's an unprocessed event in a dialog window */
962     if (status == NA_NOTPROCESSED && (winp->flags & NA_DIALOGWINDOW)) {
963     if (!NAfilterProc(winp->pwin, &event, &item)
964     && (event.modifiers & cmdKey)) {
965     status = NA_PROCESSED;
966     }
967     }
968     break;
969    
970     case activateEvt:
971     /* deal with activate windows based on activeFlag */
972     status = DoActivate((WindowPtr) event.message, winp,
973     event.modifiers & activeFlag, mouse);
974     break;
975    
976     case updateEvt:
977     /* deal with update events with proper port setting, etc. */
978     window = (WindowPtr) event.message;
979     BeginUpdate(window);
980     if ((wp = NAlockWindow(wh = GetWinH(window))) != (na_win*) NULL) {
981     GetPort(&tempPort);
982     SetPort(window);
983     if (wp->flags & NA_DIALOGWINDOW) {
984     UpdtDialog(window, window->visRgn);
985     }
986     if (wp->updatep == (na_updatep) NULL
987     || (status = (*wp->updatep)(wp, (Boolean) false))
988     == NA_NOTPROCESSED) {
989     DoDraw(wp, DO_UPDATE);
990     }
991     DoDialog(winp, &event, mouse, 0, &status);
992     SetPort(tempPort);
993     NAunlockWindowh(wh, wp);
994     }
995     EndUpdate(window);
996     if (status == NA_NOTPROCESSED) status = NA_PROCESSED;
997     break;
998    
999     case diskEvt:
1000     /* let the user format bad disks */
1001     if (HIWORD(event.message) != noErr) {
1002     SetPt(&ptemp, 0x0070, 0x0050);
1003     (void) DIBadMount(ptemp, event.message);
1004     } else {
1005     status = NAallWindows(NAhead, &event);
1006     }
1007     break;
1008    
1009     case networkEvt:
1010     case driverEvt:
1011     case app1Evt:
1012     case app2Evt:
1013     case app3Evt:
1014     /* send event to all windows */
1015     status = NAallWindows(NAhead, &event);
1016     break;
1017    
1018     case osEvt:
1019     switch ((event.message >> 24) & 0xff) {
1020     case suspendResumeMessage:
1021     status = DoActivate(FrontWindow(), winp,
1022     !(NAinBack = !(event.message & resumeFlag)), mouse);
1023     break;
1024    
1025     case mouseMovedMessage:
1026     /* only interesting if a window is in front */
1027     if (NAinBack || winp == (na_win*) NULL) break;
1028    
1029     mousepix = winp->mousepix;
1030    
1031     /* deal with mouse dragging */
1032     if (mousepix && !(NAlastmouse & 1)) {
1033     if (NAlastmouse != NA_DRAG) {
1034     InsetRect(&tmpRect, -mousepix, -mousepix);
1035     if (PtInRect(mouse, &tmpRect)) break;
1036     NAlastmouse = NA_DRAG;
1037     }
1038     goto DOMOUSEP;
1039    
1040     /* deal with cursor moving in/out of window */
1041     } else if (winp->cursorRgn != (RgnHandle) NULL) {
1042     AdjustCursor(winp, event.where, true);
1043     }
1044     break;
1045     }
1046     break;
1047    
1048     case kHighLevelEvent:
1049     if (NAgestaltBits & NA_HASAEVENTS) {
1050     aestatus = status;
1051     (void) AEProcessAppleEvent(&event);
1052     status = aestatus;
1053     }
1054     break;
1055     }
1056    
1057     /* handle dialog events */
1058     DoDialog(winp, &event, mouse, item, &status);
1059    
1060     /* call the idle procedure of the front window */
1061     if (winp != (na_win*) NULL && !NAinBack
1062     && status >= NA_NOTPROCESSED && winp->idlep != (na_idlep) NULL) {
1063     status = (*winp->idlep)(winp);
1064     }
1065    
1066     /* deal with window/app close requests and events */
1067     switch (status) {
1068     case NA_ALLCLOSED:
1069     case NA_REQCLOSEALL:
1070     status = NAcloseWindows(NAhead, status);
1071     break;
1072    
1073     case NA_CLOSED:
1074     case NA_REQCLOSE:
1075     status = NAcloseWindow(winp, status);
1076     break;
1077    
1078     default:
1079     /* call the next task procedure */
1080     if (NAtask != (na_win**) NULL) {
1081     if (NActask == (na_win**) NULL) {
1082     NActask = NAtask;
1083     prioritycnt = (*NAtask)->priority;
1084     }
1085     for (wh = NAtask; wh; wh = (*wh)->task) {
1086     if ((wh == NActask || (*wh)->priority == -1)
1087     && (wp = NAlockWindow(wh)) != (na_win*) NULL
1088     && wp->taskp != (na_taskp) NULL) {
1089     GetPort(&tempPort);
1090     if (wp->pwin != (WindowPtr) NULL) SetPort(wp->pwin);
1091     status = (*wp->taskp)(wp);
1092     SetPort(tempPort);
1093     if (status == NA_REQCLOSE || status == NA_CLOSED) {
1094     status = NAcloseWindow(wp, status);
1095     break;
1096     }
1097     if (status == NA_REQCLOSEALL || status == NA_ALLCLOSED) {
1098     status = NAcloseWindows(NAhead, status);
1099     break;
1100     }
1101     if (status == NA_NOTPROCESSED) fastdelay = 1;
1102     NAunlockWindowh(wh, wp);
1103     }
1104     }
1105     if (NActask && prioritycnt-- <= 0
1106     && (NActask = (*NActask)->task) != (na_win **) NULL) {
1107     prioritycnt = (*NActask)->priority;
1108     }
1109     }
1110     case NA_USERINTERACT:
1111     break;
1112     }
1113     } while (status != NA_ALLCLOSED);
1114    
1115     while (NAtask != NULL) NAcloseWindow(NAlockWindow(NAtask), NA_REQCLOSE);
1116    
1117     DisposeRgn(NAfullRgn);
1118     DisposeRgn(NAnullRgn);
1119     DisposHandle((Handle) NAmenus);
1120     }
1121    
1122     /* position a rectangle based on screen size
1123     */
1124     Rect *NAscreenrect(short position)
1125     {
1126     static short stacktimes = 0;
1127     static Rect sb;
1128     short topoffset, leftoffset;
1129     short width, height;
1130     short bw;
1131    
1132     /* calculate the position to open the window */
1133     sb = QD(screenBits.bounds);
1134     InsetRect(&sb, 4, 4);
1135     sb.top += MBarHeight;
1136     if (position & NA_TITLEOFFSET) {
1137     sb.top += 18;
1138     }
1139     width = sb.right - sb.left;
1140     height = sb.bottom - sb.top;
1141     if (position & 0x03) {
1142     width = (width * (position & 0x03)) >> 2;
1143     }
1144     if (position & 0x0c) {
1145     height = (height * ((position & 0x0c) >> 2)) >> 2;
1146     }
1147     if (position & NA_TOPSCN) {
1148     sb.bottom = sb.top + height;
1149     } else if (position & NA_BOTTOMSCN) {
1150     sb.top = sb.bottom - height;
1151     } else {
1152     short bw = (sb.bottom - sb.top - height) >> 1;
1153     sb.top += bw;
1154     sb.bottom -= bw;
1155     }
1156     if (position & NA_LEFTSCN) {
1157     sb.right = sb.left + width;
1158     } else if (position & NA_RIGHTSCN) {
1159     sb.left = sb.right - width;
1160     } else {
1161     bw = (sb.right - sb.left - width) >> 1;
1162     sb.left += bw;
1163     sb.right -= bw;
1164     }
1165    
1166     return (&sb);
1167     }
1168    
1169     /* create a new window/dialog/task structure
1170     */
1171     short NAwindow(Rect *rpos, long flags, char *title, short res, long *initdata,
1172     long datasize, na_initp initp)
1173     {
1174     GrafPtr tmpPort;
1175     short procID;
1176     short status;
1177     Boolean goAwayFlag, visible;
1178     na_win **winh, *winp;
1179     char *newdata, *dcopy;
1180     WindowPtr behind, prev, window;
1181     Rect wsize, sb;
1182     PCstr wtitle[257];
1183     Handle items;
1184    
1185     /* save previous window */
1186     prev = FrontWindow();
1187    
1188     /* set up flags for the NewWindow call */
1189     goAwayFlag = (flags & NA_CLOSEBOX);
1190     visible = (flags & NA_NOTVISIBLE) ? false : true;
1191     behind = (flags & NA_BEHIND && NAwin != (na_win*) NULL) ? NAwin->pwin : (WindowPtr) -1;
1192    
1193     /* decide on the correct procID */
1194     procID = rDocProc;
1195     if ((flags & NA_ROUNDBORDER) != NA_ROUNDBORDER) {
1196     procID = plainDBox;
1197     if (flags & NA_SHADOWBORDER) procID = altDBoxProc;
1198     if (flags & NA_DOUBLEBORDER) procID = dBoxProc;
1199     if (flags & NA_TITLEBAR) {
1200     procID = flags & NA_DOUBLEBORDER ? movableDBoxProc : documentProc;
1201     }
1202     if (!(flags & NA_GROWBOX)
1203     && procID == documentProc) procID |= noGrowDocProc;
1204     if (flags & NA_ZOOMBOX) procID |= zoomDocProc;
1205     }
1206    
1207     /* get the window title to a pacsal string */
1208     if (title) CtoPCstrcpy(wtitle, title);
1209    
1210     /* allocate memory and copy the user data */
1211     if (!datasize) datasize = sizeof (na_win);
1212     winh = (na_win**) NewHandleClear((Size) datasize);
1213     if (winh == (na_win**) NULL) return (NA_NOTPROCESSED);
1214     MoveHHi((Handle) winh);
1215     HLock((Handle) winh);
1216     winp = *winh;
1217     if (initdata != NULL && flags & NA_COPYDATA) {
1218     dcopy = (char *) initdata;
1219     datasize -= sizeof (na_win);
1220     for (newdata = (char*) winp + sizeof (na_win); datasize > 0; datasize--) {
1221     *newdata = *dcopy++;
1222     newdata++;
1223     }
1224     }
1225    
1226     /* initialize winp parameters */
1227     winp->locks = 1;
1228     winp->delay = NAdelay;
1229     winp->flags = flags;
1230     winp->minw = 128;
1231     winp->minh = 64;
1232     winp->resid = res;
1233    
1234     /* install in window tree */
1235     if (flags & NA_CHILDWINDOW && NAwin != (na_win*) NULL) {
1236     winp->parent = (na_win**) RecoverHandle((Ptr)NAwin);
1237     winp->next = NAwin->child;
1238     NAwin->child = winh;
1239     } else {
1240     winp->next = NAhead;
1241     NAhead = winh;
1242     }
1243    
1244     /* install in task list */
1245     if (flags & NA_HASTASK) {
1246     winp->task = NAtask;
1247     NAtask = winh;
1248     }
1249    
1250     /* open the window appropriately */
1251     switch (flags & (NA_COLORWINDOW | NA_DIALOGWINDOW)) {
1252     case NA_DIALOGWINDOW:
1253     case (NA_DIALOGWINDOW | NA_COLORWINDOW):
1254     if (flags & NA_USERESOURCE) {
1255     window = (WindowPtr) GetNewDialog(res, (Ptr) NULL, behind);
1256     } else {
1257     items = GetResource('DITL', res);
1258     DetachResource(items);
1259     if (flags & NA_COLORWINDOW) {
1260     window = (WindowPtr) NewCDialog((Ptr) NULL, rpos, wtitle,
1261     visible, procID, behind, goAwayFlag, (long) winh, items);
1262     } else {
1263     window = (WindowPtr) NewDialog((Ptr) NULL, rpos, wtitle,
1264     visible, procID, behind, goAwayFlag, (long) winh, items);
1265     }
1266     }
1267     break;
1268    
1269     case NA_COLORWINDOW:
1270     if (flags & NA_USERESOURCE) {
1271     window = (WindowPtr) GetNewCWindow(res, (Ptr) NULL, behind);
1272     } else {
1273     window = (WindowPtr) NewCWindow((Ptr) NULL, rpos, wtitle,
1274     visible, procID, behind, goAwayFlag, (long) winh);
1275     }
1276     break;
1277    
1278     default:
1279     if (flags & NA_USERESOURCE) {
1280     window = GetNewWindow(res, (Ptr) NULL, behind);
1281     } else {
1282     window = NewWindow((Ptr) NULL, rpos, wtitle, visible, procID,
1283     behind, goAwayFlag, (long) winh);
1284     }
1285     break;
1286     }
1287     if (title && (flags & NA_USERESOURCE)) SetWTitle(window, wtitle);
1288     winp->pwin = window;
1289    
1290     /* activate the window */
1291     GetPort(&tmpPort);
1292     SetPort(window);
1293    
1294     /* additional options for windows from resources */
1295     if (flags & NA_USERESOURCE) {
1296     SetWRefCon(window, (long) winh);
1297    
1298     /* force the size */
1299     if (flags & NA_FORCESIZE) {
1300     MoveWindow(window, rpos->left, rpos->top, false);
1301     SizeWindow(window, rpos->right - rpos->left, rpos->bottom - rpos->top, false);
1302     }
1303     }
1304    
1305     /* get the screen bounds */
1306     sb = QD(screenBits.bounds);
1307     InsetRect(&sb, 4, 4);
1308    
1309     /* get window position */
1310     wsize = window->portRect;
1311     LocalToGlobal((Point *)&wsize.top);
1312    
1313     /* make sure the window is on the screen */
1314     if (wsize.top > sb.bottom || wsize.left > sb.right) {
1315     MoveWindow(window, 60, 60, false);
1316     }
1317    
1318     /* call the init procedure */
1319     if ((status = (*initp)(winp, initdata)) >= NA_NOTPROCESSED) {
1320    
1321     /* draw the window immediately for better look & update has first newsize */
1322     if (winp->updatep == (na_updatep) NULL
1323     || (status = (*winp->updatep)(winp, (Boolean) true))
1324     == NA_NOTPROCESSED) {
1325     DoDraw(winp, FrontWindow() != window ? DO_RESIZE | DO_DEACTIVATE :
1326     DO_RESIZE);
1327     }
1328     if (flags & NA_DIALOGWINDOW) DrawDialog(window);
1329     ValidRect(&window->portRect);
1330     }
1331    
1332     /* deal with close requests/events result codes */
1333     switch (status) {
1334     case NA_ALLCLOSED:
1335     case NA_REQCLOSEALL:
1336     status = NAcloseWindows(NAhead, status);
1337     break;
1338    
1339     case NA_CLOSED:
1340     case NA_REQCLOSE:
1341     status = NAcloseWindow(winp, status);
1342     break;
1343    
1344     default:
1345     NAunlockWindowh(winh, winp);
1346     break;
1347     }
1348    
1349     /* give a nice return value & clean up the port */
1350     if (status == NA_NOTPROCESSED) status = NA_PROCESSED;
1351     if (FrontWindow() != window || status != NA_PROCESSED) SetPort(tmpPort);
1352    
1353     return (status);
1354     }
1355    
1356     /* create & add a new task to the task list
1357     */
1358     na_win **NAaddtask(na_taskp taskp, long size)
1359     {
1360     na_win **task, *winp;
1361    
1362     if (!size) size = sizeof (na_win);
1363     task = (na_win **) NewHandleClear(size);
1364     if (task) {
1365     (*task)->taskp = taskp;
1366     (*task)->task = NAtask;
1367     NAtask = task;
1368     }
1369    
1370     return (task);
1371     }

  ViewVC Help
Powered by ViewVC 1.1.22