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

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

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


Revision 1.1 - (show annotations) (download)
Tue Aug 26 20:45:25 2003 UTC (20 years, 7 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 /* 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