1 /* mac/scrnmgr/ScrnMgr.c: a screen management package for the Mac
2
3 Copyright (c) 1989-1991 Curtis McCauley, James E. Wilson
4
5 You may copy this subroutine package freely, modify it as you desire,
6 and distribute it at will, as long as the copyright notice in the source
7 material is not disturbed, excepting that no one may use this package or
8 any part of it for commercial purposes of any kind without the express
9 written consent of its author. */
10
11 /* Think C port by Benjamin Schreiber, 1991. */
12
13 #ifndef THINK_C
14
15 #include <Types.h>
16 #include <OSUtils.h>
17 #include <Files.h>
18 #include <Quickdraw.h>
19 #include <Windows.h>
20 #include <Memory.h>
21 #include <Controls.h>
22 #include <Resources.h>
23 #include <Desk.h>
24 #include <Dialogs.h>
25 #include <Events.h>
26 #include <Fonts.h>
27 #include <Menus.h>
28 #include <OSEvents.h>
29 #include <SegLoad.h>
30 #include <TextEdit.h>
31 #include <ToolUtils.h>
32 #include <Packages.h>
33 #include <Retrace.h>
34 #include <Script.h>
35 #include <Traps.h>
36 #include <SysEqu.h>
37
38 #include <StdDef.h>
39 #include <String.h>
40 #include <Strings.h>
41
42 #else
43
44 /* defined(THINK_C) */
45
46 #include <VRetraceMgr.h>
47 #include <ScriptMgr.h>
48 #include <MultiFinder.h> /* This may not be necessary. */
49
50 #include <string.h>
51 #include <stddef.h>
52
53 #define p2cstr PtoCstr /* Correct difference in names. */
54 #define c2pstr CtoPstr
55
56 typedef char Str63[64];
57
58 /* Cover up error in THINK C library. */
59 #define ok OK
60 #define cancel Cancel
61 #define normal 0
62
63 #endif
64
65
66 #include "ScrnMgr.h"
67
68 #define osEvent app4Evt
69 #define suspendResumeMessage 1
70 #define resumeMask 1
71
72 #define infoResType (ResType) 'INFO'
73 #define infoResID 1
74
75 #define ABS(i) ((i < 0) ? -i : i)
76
77 #define menuBarID1 128
78 #define menuBarID2 228
79
80 #define appleID 128
81 #define fileID1 129
82 #define fileID2 229
83 #define editID1 130
84 #define editID2 230
85 #define screenID 131
86 #define fontSizeID 132
87 #define appID1 133
88 #define appID2 233
89
90 #define aboutItem 1
91
92 #define openItem 1
93 #define closeItem 2
94 #define quitItem 4
95
96 #define undoItem 1
97 #define cutItem 3
98 #define copyItem 4
99 #define pasteItem 5
100 #define clearItem 6
101
102 #define colorsItem 1
103
104 #define aboutDlgID 128
105 #define aboutDfltBorder 2
106
107 #define aboutStrID 128
108
109 #define colorsDlgID 129
110 #define colorsDfltBorder 23
111 #define foregroundRect 19
112 #define backgroundRect 20
113 #define foreColors 3
114 #define backColors 11
115
116 #define yesOrNoDlgID 130
117 #define yesOrNoDfltBorder 3
118 #define yesOrNoText 4
119
120 #define fontNameID 129
121
122 #define fontSizeCount 50
123 #define minFontSize 1
124 #define maxFontSize 100
125 #define dfltFontSize 9
126
127 #define acurID 128
128
129 #define titleMargin 20
130 #define titleMinHgt 8
131 #define titleMinWid 8
132 #define titleDfltLeft 32
133 #define titleDfltTop 64
134
135 #define ESC '\x1B'
136 #define BACKQUOTE '\x60'
137
138 typedef struct Info {
139 Rect bounds;
140 short size;
141 long colorStdFore;
142 long colorStdBack;
143 } Info, *InfoPtr;
144
145 typedef struct Acur {
146 short frames;
147 short next;
148 union {
149 struct { short id; short fill; } cursID;
150 Cursor **cursHandle;
151 } table[1];
152 } Acur, *AcurPtr, **AcurHandle;
153
154 typedef struct Evt {
155 char keycode;
156 char modifiers;
157 char ascii;
158 short h;
159 short v;
160 } Evt, *EvtPtr;
161
162 #define qSize 32
163
164 typedef struct SaveScreenRec {
165 struct SaveScreenRec **link; /* link to previous saved screen */
166 char **chars; /* handle to saved character buffer */
167 char **attrs; /* handle to saved attribute buffer */
168 Point cursor; /* saved cursor location */
169 } SaveScreenRec, *SaveScreenPtr, **SaveScreenHandle;
170
171 typedef struct ScreenRec {
172 WindowPtr window; /* the screen window */
173 EventRecord event; /* the last event */
174 SysEnvRec env; /* the outside world */
175 long wneImplemented; /* do we have WaitNextEvent? */
176 long backgrounding; /* are we in the background? */
177 long reconfigFlag; /* true if user want to change options */
178 long colorFlag; /* true if multiple colors supported */
179 long cmdKeyFlag; /* true if cmd key equivalents ok */
180 long mouseFlag; /* true if mouse clicks are captured */
181 long escMapFlag; /* true if backquote maps to escape */
182 long waitFlag; /* true if in wait */
183 long waitRate; /* how fast to spin the cursor */
184 long colorStdFore; /* standard foreground color */
185 long colorStdBack; /* standard background color */
186 long windowW; /* its content width in pixels */
187 long windowH; /* its content height in pixels */
188 short txFont; /* the font number in use */
189 short txSize; /* the font size in use */
190 short txNum; /* index into fontSizes table + 1 */
191 short **fontSizes; /* a table of available sizes */
192 FontInfo info; /* font info for the current font */
193 Point cursor; /* cursor location in char coords */
194 Point charPDims; /* char cell size in pixels */
195 Point scrnCDims; /* screen size in chars */
196 Point origin; /* logical origin of screen for drawing */
197 Rect stdStateGRect; /* original standard state */
198 Rect scrnCRect; /* screen bounds in chars */
199 Rect scrnLRect; /* screen bounds in pixels */
200 Rect scrnXLRect; /* screen bounds in pixels plus margin */
201 Rect sizeLimitPRect; /* limits to growth */
202 Rect dragLimitGRect; /* limits to movement */
203 Rect hScrollPRect; /* horiz scroll bar bounds */
204 Rect vScrollPRect; /* vert scroll bar bounds */
205 Rect growPRect; /* grow icon bounds */
206 Rect picPRect; /* picture area bounds */
207 Rect picLRect; /* drawing is clipped here (pic area) */
208 Rect drawLRect; /* drawing is clipped here (screen area)*/
209 Rect drawXCRect; /* rect to draw in char coords */
210 Rect drawXLRect; /* rect to draw in pixel coords */
211 Rect mouseCRect; /* watch mouse activity in this area */
212 Rect mouseLRect; /* watch mouse activity in this area */
213 ControlHandle hScrollHandle; /* handle to horiz scroll control */
214 ControlHandle vScrollHandle; /* handle to vert scroll control */
215 short infoResFile; /* ref no of resource file */
216 Handle infoHandle; /* handle to info resource */
217 Handle versHandle; /* handle to vers. string, for about dlg */
218 char **chars; /* handle to character buffer */
219 char **attrs; /* handle to attribute buffer */
220 short **updLeft; /* handle to left margin for updates */
221 short **updRight; /* handle to right margin for updates */
222 long keyFlush; /* tick count at last key flush */
223 long mouseFlush; /* tick count at last mouse flush */
224 long qBegin; /* index to first elem in queue */
225 long qEnd; /* index to next elem to be stored */
226 Evt qBuffer[qSize]; /* queue of keystrokes */
227 long cursorLevel; /* greater than zero when cursor visible*/
228 long cursorColor; /* color of cursor lines */
229 long cursorLines; /* number of lines in cursor */
230 long cursorBlink; /* ticks between cursor blinks */
231 long cursorStatus; /* non-zero when cursor in on screen */
232 long cursorChangeTick; /* when to change cursor status */
233 void (*aboutProc)(void); /* what to call when about is selected */
234 void (*quitProc)(void); /* what to call when quit is selected */
235 void (*fileMenuProc)(long item);/* file menu handler */
236 void (*appMenuProc)(long item); /* app menu handler */
237 long quitReturns; /* true if quit proc will always return */
238 AcurHandle acur; /* table of cursors */
239 VBLTask vbl; /* for animating said cursors */
240 SaveScreenHandle stack; /* stack of saved screens */
241 } ScreenRec;
242
243 ScreenRec theScreen;
244
245 static long colors[8] = {
246 whiteColor, blackColor,
247 redColor, greenColor, blueColor,
248 cyanColor, magentaColor, yellowColor
249 };
250
DisposeStackTop()251 static void DisposeStackTop()
252
253 {
254 SaveScreenHandle next;
255
256 if (theScreen.stack != NULL) {
257
258 next = (*theScreen.stack)->link;
259
260 DisposHandle((Handle) (*theScreen.stack)->chars);
261 DisposHandle((Handle) (*theScreen.stack)->attrs);
262
263 DisposHandle((Handle) theScreen.stack);
264
265 theScreen.stack = next;
266
267 }
268
269 return;
270 }
271
WNETest(envp)272 static long WNETest(envp)
273 SysEnvRec *envp;
274
275 {
276 #ifndef THINK_C
277 long hasWNE;
278
279 if (envp->machineType < 0)
280 hasWNE = false;
281
282 else
283 hasWNE =
284 NGetTrapAddress(_WaitNextEvent, ToolTrap) != GetTrapAddress(_Unimplemented);
285
286 return(hasWNE);
287 #else
288 return 0;
289 #endif
290 }
291
NoEscTest(envp)292 static long NoEscTest(envp)
293 SysEnvRec *envp;
294
295 {
296 long hasNoEsc;
297
298 switch (envp->keyBoardType) {
299
300 case envAExtendKbd:
301 case envStandADBKbd:
302 hasNoEsc = false;
303 break;
304
305 default:
306 hasNoEsc = true;
307 break;
308
309 }
310
311 return(hasNoEsc);
312 }
313
FlushQueue()314 static void FlushQueue()
315
316 {
317 theScreen.qBegin = theScreen.qEnd = 0;
318 return;
319 }
320
PushQueue(keycode,modifiers,ascii,h,v)321 static void PushQueue(keycode, modifiers, ascii, h, v)
322 char keycode;
323 char modifiers;
324 char ascii;
325 short h;
326 short v;
327
328 {
329 long end;
330 EvtPtr next;
331
332 end = (theScreen.qEnd + 1) & (qSize - 1);
333 if (end != theScreen.qBegin) {
334 next = &theScreen.qBuffer[theScreen.qEnd];
335 next->keycode = keycode;
336 next->modifiers = modifiers;
337 next->ascii = ascii;
338 next->h = h;
339 next->v = v;
340 theScreen.qEnd = end;
341 }
342 else {
343 /* should I beep? */
344 }
345
346 return;
347 }
348
LenQueue()349 static long LenQueue()
350
351 {
352 return(ABS(theScreen.qEnd - theScreen.qBegin));
353 }
354
PopQueue(keycode,modifiers,ascii,h,v)355 static long PopQueue(keycode, modifiers, ascii, h, v)
356 char *keycode;
357 char *modifiers;
358 char *ascii;
359 short *h;
360 short *v;
361
362 {
363 long flag;
364 EvtPtr next;
365
366 if (theScreen.qEnd != theScreen.qBegin) {
367 flag = true;
368 next = &theScreen.qBuffer[theScreen.qBegin];
369 if (keycode != NULL) *keycode = next->keycode;
370 if (modifiers != NULL) *modifiers = next->modifiers;
371 if (ascii != NULL ) *ascii = next->ascii;
372 if (h != NULL ) *h = next->h;
373 if (v != NULL ) *v = next->v;
374 theScreen.qBegin = (theScreen.qBegin + 1) & (qSize - 1);
375 }
376 else {
377 flag = false;
378 }
379
380 return(flag);
381 }
382
GtoC(gh,gv,ch,cv)383 static int GtoC(gh, gv, ch, cv)
384 short gh, gv;
385 short *ch, *cv;
386
387 {
388 int flag;
389 Point temp;
390
391 temp.h = gh;
392 temp.v = gv;
393
394 SetOrigin(theScreen.origin.h, theScreen.origin.v);
395 GlobalToLocal(&temp);
396 SetOrigin(0, 0);
397
398 if ( PtInRect(temp, &theScreen.mouseLRect)
399 && PtInRect(temp, &theScreen.picLRect) ) {
400 flag = true;
401 *ch = temp.h / theScreen.charPDims.h;
402 *cv = temp.v / theScreen.charPDims.v;
403 }
404 else
405 flag = false;
406
407 return(flag);
408 }
409
DefaultCursor()410 static void DefaultCursor()
411
412 {
413 theScreen.cursorLevel = 0;
414 theScreen.cursorColor = attrColorBlack;
415 theScreen.cursorLines = 2;
416 theScreen.cursorBlink = 0;
417 theScreen.cursorStatus = 0;
418 theScreen.cursorChangeTick = 0;
419
420 return;
421 }
422
Prolog()423 static void Prolog()
424
425 {
426 #ifdef THINK_C
427 InitGraf(&thePort);
428 #else
429 InitGraf(&qd.thePort);
430 #endif
431 InitFonts();
432 FlushEvents(everyEvent, 0);
433 InitWindows();
434 InitMenus();
435 TEInit();
436 InitDialogs(NULL);
437 InitCursor();
438
439 return;
440 }
441
LoadCursors()442 static void LoadCursors()
443
444 {
445 short i, count;
446 Cursor **c;
447
448 theScreen.acur = (AcurHandle) GetResource('acur', acurID);
449
450 count = (*theScreen.acur)->frames;
451
452 for (i = 0; i < count; i++) {
453 c = GetCursor((*theScreen.acur)->table[i].cursID.id);
454 (*theScreen.acur)->table[i].cursHandle = c;
455 }
456
457 return;
458 }
459
GetFontSizes()460 static long GetFontSizes()
461
462 {
463 long i, j;
464 short fsize, sizes[fontSizeCount];
465 char **fname;
466
467 fname = (char **) GetString(fontNameID);
468
469 if (fname == NULL)
470 theScreen.txFont = 0;
471 else {
472 HLock(fname);
473 GetFNum(*fname, &theScreen.txFont);
474 HUnlock(fname);
475 }
476
477 for (i = 0, fsize = minFontSize;
478 (i < fontSizeCount) && (fsize < maxFontSize);
479 fsize++)
480 if (RealFont(theScreen.txFont, fsize))
481 sizes[i++] = fsize;
482
483 if (i == 0)
484 sizes[i++] = dfltFontSize;
485
486 theScreen.fontSizes = (short **) NewHandle(sizeof(short) * (i + 1));
487
488 if (theScreen.fontSizes != NULL)
489 for (j = 0; j < i; j++)
490 (*theScreen.fontSizes)[j] = sizes[j];
491
492 (*theScreen.fontSizes)[i++] = 0;
493
494 return(theScreen.fontSizes != NULL);
495 }
496
SetUpMenus()497 static void SetUpMenus()
498
499 {
500 long i, n, offset;
501 Handle h;
502 MenuHandle appMenuHndl, fontMenuHndl;
503 Str255 ftitle;
504
505 SetMenuBar(GetNewMBar(theScreen.cmdKeyFlag ? menuBarID1 : menuBarID2));
506 AddResMenu(GetMHandle(appleID), (ResType) 'DRVR');
507 if (theScreen.colorFlag || !theScreen.env.hasColorQD) {
508 InsertMenu(GetMenu(fontSizeID), 0);
509 fontMenuHndl = GetMHandle(fontSizeID);
510 offset = 1;
511 }
512 else {
513 InsertMenu(GetMenu(screenID), 0);
514 fontMenuHndl = GetMHandle(screenID);
515 offset = 3;
516 }
517
518 h = (Handle) GetString(aboutStrID);
519 if (h != NULL) {
520 MoveHHi(h);
521 HLock(h);
522 SetItem(GetMHandle(appleID), aboutItem, *h);
523 HUnlock(h);
524 }
525
526 for (i = 0; n = (*theScreen.fontSizes)[i]; i++) {
527 NumToString(n, ftitle);
528 (void) c2pstr(strcat(p2cstr((char *)ftitle), " point"));
529 AppendMenu(fontMenuHndl, ftitle);
530 if (n == theScreen.txSize) {
531 theScreen.txNum = i + offset;
532 CheckItem(fontMenuHndl, theScreen.txNum, true);
533 }
534 }
535
536 if (theScreen.appMenuProc != NULL) {
537 appMenuHndl = GetMenu(theScreen.cmdKeyFlag ? appID1 : appID2);
538 if (appMenuHndl != NULL) InsertMenu(appMenuHndl, 0);
539 }
540
541 DrawMenuBar();
542
543 return;
544 }
545
LoadInfo(resourceFile,rfCreator,rfType)546 static void LoadInfo(resourceFile, rfCreator, rfType)
547 Str255 resourceFile;
548 OSType rfCreator, rfType;
549
550 {
551 ResType dfltType;
552 short dfltID;
553 Str63 dfltName;
554 short saveVol;
555
556 (void) GetVol(NULL, &saveVol);
557 (void) SetVol(NULL, theScreen.env.sysVRefNum);
558
559 (void) Create(resourceFile, 0, rfCreator, rfType);
560 CreateResFile(resourceFile);
561
562 theScreen.infoResFile = OpenResFile(resourceFile);
563
564 theScreen.infoHandle = GetResource(infoResType, infoResID);
565
566 if ( (theScreen.infoResFile != -1) &&
567 (theScreen.infoResFile != HomeResFile(theScreen.infoHandle)) ) {
568 GetResInfo(theScreen.infoHandle, &dfltID, &dfltType, dfltName);
569 DetachResource(theScreen.infoHandle);
570 AddResource(theScreen.infoHandle, dfltType, dfltID, dfltName);
571 }
572
573 (void) SetVol(NULL, saveVol);
574
575 return;
576 }
577
UseInfo(boundsRectPtr,sizePtr,colorStdForePtr,colorStdBackPtr)578 static void UseInfo(boundsRectPtr, sizePtr, colorStdForePtr, colorStdBackPtr)
579 Rect *boundsRectPtr;
580 short *sizePtr;
581 long *colorStdForePtr;
582 long *colorStdBackPtr;
583
584 {
585 InfoPtr theInfo;
586
587 LoadResource(theScreen.infoHandle);
588
589 theInfo = (InfoPtr) *theScreen.infoHandle;
590
591 *boundsRectPtr = theInfo->bounds;
592 *sizePtr = theInfo->size;
593
594 if (theScreen.env.hasColorQD) {
595 *colorStdForePtr = theInfo->colorStdFore;
596 *colorStdBackPtr = theInfo->colorStdBack;
597 }
598 else {
599 *colorStdForePtr = attrColorBlack;
600 *colorStdBackPtr = attrColorWhite;
601 }
602
603 return;
604 }
605
SaveInfo()606 static void SaveInfo()
607
608 {
609 Point topLeft, bottomRight;
610 InfoPtr theInfo;
611
612 if (theScreen.infoResFile == -1) return;
613
614 LoadResource(theScreen.infoHandle);
615 HLock(theScreen.infoHandle);
616
617 theInfo = (InfoPtr) *theScreen.infoHandle;
618
619 #ifdef THINK_C
620 topLeft.h = thePort->portRect.left;
621 topLeft.v = thePort->portRect.top;
622
623 bottomRight.h = thePort->portRect.right;
624 bottomRight.v = thePort->portRect.bottom;
625 #else
626 topLeft.h = qd.thePort->portRect.left;
627 topLeft.v = qd.thePort->portRect.top;
628
629 bottomRight.h = qd.thePort->portRect.right;
630 bottomRight.v = qd.thePort->portRect.bottom;
631 #endif
632
633 LocalToGlobal(&topLeft);
634 LocalToGlobal(&bottomRight);
635
636 if ( (topLeft.h != theInfo->bounds.left) ||
637 (topLeft.v != theInfo->bounds.top) ||
638 (bottomRight.h != theInfo->bounds.right) ||
639 (bottomRight.v != theInfo->bounds.bottom) ) {
640
641 theInfo->bounds.left = topLeft.h;
642 theInfo->bounds.top = topLeft.v;
643 theInfo->bounds.right = bottomRight.h;
644 theInfo->bounds.bottom = bottomRight.v;
645 ChangedResource(theScreen.infoHandle);
646
647 }
648
649 if ( theScreen.txSize != theInfo->size ) {
650
651 theInfo->size = theScreen.txSize;
652 ChangedResource(theScreen.infoHandle);
653
654 }
655
656 if ( (theScreen.colorStdFore != theInfo->colorStdFore) ||
657 (theScreen.colorStdBack != theInfo->colorStdBack) ) {
658
659 theInfo->colorStdFore = theScreen.colorStdFore;
660 theInfo->colorStdBack = theScreen.colorStdBack;
661 ChangedResource(theScreen.infoHandle);
662
663 }
664
665 HUnlock(theScreen.infoHandle);
666
667 return;
668 }
669
AdjustPortBounds(bounds)670 static void AdjustPortBounds(bounds)
671 Rect *bounds;
672
673 {
674 long repos;
675 long wid, hgt;
676 Rect test, sect;
677 #ifndef THINK_C
678 GDHandle gdh;
679 #endif
680
681 test.left = bounds->left;
682 test.top = bounds->top - titleMargin;
683 test.right = bounds->right;
684 test.bottom = bounds->top;
685
686 #ifdef THINK_C /* Ignore color issues. -- BS */
687
688 (void) SectRect (&screenBits.bounds, &test, §);
689 wid = sect.right - sect.left;
690 hgt = sect.bottom - sect.top;
691 if ((wid < titleMinWid) || (hgt < titleMinHgt))
692 OffsetRect (bounds,
693 (screenBits.bounds.left + titleDfltLeft) - bounds->left\,
694 (screenBits.bounds.top + titleDfltTop) - bounds->top);
695
696 #else
697
698 repos = true;
699
700 if (!theScreen.env.hasColorQD) {
701
702 (void) SectRect(&qd.screenBits.bounds, &test, §);
703 wid = sect.right - sect.left;
704 hgt = sect.bottom - sect.top;
705 if ( (wid >= titleMinWid) && (hgt >= titleMinHgt) ) repos = false;
706
707 }
708
709 else {
710
711 gdh = GetDeviceList();
712
713 while ( (gdh != NULL) && (repos) ) {
714
715 if ( ((*gdh)->gdFlags && (1 << screenDevice)) &&
716 ((*gdh)->gdFlags && (1 << screenActive)) ) {
717
718 (void) SectRect(&(*gdh)->gdRect, &test, §);
719 wid = sect.right - sect.left;
720 hgt = sect.bottom - sect.top;
721 if ( (wid >= titleMinWid) && (hgt >= titleMinHgt) ) repos = false;
722
723 }
724
725 gdh = GetNextDevice(gdh);
726
727 }
728
729 }
730
731 if (repos)
732 OffsetRect(bounds,
733 (qd.screenBits.bounds.left + titleDfltLeft) - bounds->left,
734 (qd.screenBits.bounds.top + titleDfltTop) - bounds->top);
735 #endif
736
737 return;
738 }
739
SetScreenParameters()740 static void SetScreenParameters()
741
742 {
743 long stdWid, stdHgt;
744 Rect stdState;
745 WStateData **zoomInfo;
746
747 GetFontInfo(&theScreen.info);
748 theScreen.charPDims.h = theScreen.info.widMax;
749 theScreen.charPDims.v = theScreen.info.ascent
750 + theScreen.info.descent
751 + theScreen.info.leading;
752
753 theScreen.scrnCRect.left = 0;
754 theScreen.scrnCRect.right = theScreen.scrnCDims.h;
755 theScreen.scrnCRect.top = 0;
756 theScreen.scrnCRect.bottom = theScreen.scrnCDims.v;
757
758 theScreen.scrnLRect = theScreen.scrnCRect;
759 theScreen.scrnLRect.right *= theScreen.charPDims.h;
760 theScreen.scrnLRect.bottom *= theScreen.charPDims.v;
761
762 theScreen.scrnXLRect = theScreen.scrnLRect;
763 InsetRect(&theScreen.scrnXLRect, -4, -4);
764
765 theScreen.sizeLimitPRect.left = 64;
766 theScreen.sizeLimitPRect.top = 64;
767
768 theScreen.sizeLimitPRect.right =
769 theScreen.scrnXLRect.right - theScreen.scrnXLRect.left + 16;
770 if (theScreen.sizeLimitPRect.right < 65) theScreen.sizeLimitPRect.right = 65;
771
772 theScreen.sizeLimitPRect.bottom =
773 theScreen.scrnXLRect.bottom - theScreen.scrnXLRect.top + 16;
774 if (theScreen.sizeLimitPRect.bottom < 65)
775 theScreen.sizeLimitPRect.bottom = 65;
776
777 #ifdef THINK_C
778 theScreen.dragLimitGRect = screenBits.bounds;
779 #else
780 theScreen.dragLimitGRect = qd.screenBits.bounds;
781 #endif
782 theScreen.dragLimitGRect.top += GetMBarHeight();
783 InsetRect(&theScreen.dragLimitGRect, -4, -4);
784
785 stdState = theScreen.stdStateGRect;
786 stdWid = stdState.right - stdState.left - theScreen.sizeLimitPRect.right + 1;
787 stdHgt = stdState.bottom - stdState.top
788 - theScreen.sizeLimitPRect.bottom + 1;
789
790 if (stdWid > 0) {
791 InsetRect(&stdState, stdWid / 2, 0);
792 stdState.right -= stdWid % 2;
793 }
794
795 if (stdHgt > 0) {
796 InsetRect(&stdState, 0, stdHgt / 2);
797 stdState.bottom -= stdHgt % 2;
798 }
799
800 zoomInfo = (WStateData **) ((WindowPeek) theScreen.window)->dataHandle;
801 (*zoomInfo)->stdState = stdState;
802
803 theScreen.mouseLRect = theScreen.mouseCRect;
804 theScreen.mouseLRect.left *= theScreen.charPDims.h;
805 theScreen.mouseLRect.top *= theScreen.charPDims.v;
806 theScreen.mouseLRect.right *= theScreen.charPDims.h;
807 theScreen.mouseLRect.bottom *= theScreen.charPDims.v;
808
809 return;
810 }
811
SetScreenPortSize()812 static void SetScreenPortSize()
813
814 {
815 long oldW, oldH;
816 long newW, newH;
817
818 oldW = theScreen.window->portRect.right;
819 oldH = theScreen.window->portRect.bottom;
820
821 if (oldW > theScreen.sizeLimitPRect.right-1)
822 newW = theScreen.sizeLimitPRect.right-1;
823 else if (oldW < theScreen.sizeLimitPRect.left)
824 newW = theScreen.sizeLimitPRect.left;
825 else
826 newW = oldW;
827
828 if (oldH > theScreen.sizeLimitPRect.bottom-1)
829 newH = theScreen.sizeLimitPRect.bottom-1;
830 else if (oldH < theScreen.sizeLimitPRect.top)
831 newH = theScreen.sizeLimitPRect.top;
832 else
833 newH = oldH;
834
835 if ( (newW != oldW) || (newH != oldH) )
836 SizeWindow(theScreen.window, newW, newH, true);
837
838 return;
839 }
840
SetScreenPortRects()841 static void SetScreenPortRects()
842
843 {
844 ClipRect(&theScreen.window->portRect);
845
846 theScreen.windowW = theScreen.window->portRect.right;
847 theScreen.windowH = theScreen.window->portRect.bottom;
848
849 theScreen.vScrollPRect =
850 theScreen.hScrollPRect =
851 theScreen.growPRect =
852 theScreen.picPRect = theScreen.window->portRect;
853
854 theScreen.vScrollPRect.right += 1;
855 theScreen.vScrollPRect.top -= 1;
856 theScreen.vScrollPRect.left = theScreen.vScrollPRect.right - 16;
857 theScreen.vScrollPRect.bottom -= 14;
858
859 theScreen.hScrollPRect.bottom += 1;
860 theScreen.hScrollPRect.left -= 1;
861 theScreen.hScrollPRect.top = theScreen.hScrollPRect.bottom - 16;
862 theScreen.hScrollPRect.right -= 14;
863
864 theScreen.growPRect.top = theScreen.growPRect.bottom - 15;
865 theScreen.growPRect.left = theScreen.growPRect.right - 15;
866 theScreen.growPRect.bottom += 1;
867 theScreen.growPRect.right += 1;
868
869 theScreen.picPRect.right -= 15;
870 theScreen.picPRect.bottom -= 15;
871
872 return;
873 }
874
SetScreenDrawRects()875 static void SetScreenDrawRects()
876
877 {
878 theScreen.picLRect = theScreen.picPRect;
879 OffsetRect(&theScreen.picLRect, theScreen.origin.h, theScreen.origin.v);
880
881 SectRect(&theScreen.picLRect, &theScreen.scrnLRect, &theScreen.drawLRect);
882
883 theScreen.drawXCRect = theScreen.drawLRect;
884 theScreen.drawXCRect.right += theScreen.charPDims.h - 1;
885 theScreen.drawXCRect.bottom += theScreen.charPDims.v - 1;
886 theScreen.drawXCRect.left /= theScreen.charPDims.h;
887 theScreen.drawXCRect.right /= theScreen.charPDims.h;
888 theScreen.drawXCRect.top /= theScreen.charPDims.v;
889 theScreen.drawXCRect.bottom /= theScreen.charPDims.v;
890
891 theScreen.drawXLRect = theScreen.drawXCRect;
892 theScreen.drawXLRect.left *= theScreen.charPDims.h;
893 theScreen.drawXLRect.right *= theScreen.charPDims.h;
894 theScreen.drawXLRect.top *= theScreen.charPDims.v;
895 theScreen.drawXLRect.bottom *= theScreen.charPDims.v;
896
897 return;
898 }
899
RepositionScreen(deltaH,deltaV)900 static int RepositionScreen(deltaH, deltaV)
901 int deltaH, deltaV;
902
903 {
904 int changed;
905 int newH, newV;
906 int min, max;
907 RgnHandle updtRgn;
908
909 newH = GetCtlValue(theScreen.hScrollHandle) + deltaH;
910 if (newH < (min = GetCtlMin(theScreen.hScrollHandle))) newH = min;
911 if (newH > (max = GetCtlMax(theScreen.hScrollHandle))) newH = max;
912
913 newV = GetCtlValue(theScreen.vScrollHandle) + deltaV;
914 if (newV < (min = GetCtlMin(theScreen.vScrollHandle))) newV = min;
915 if (newV > (max = GetCtlMax(theScreen.vScrollHandle))) newV = max;
916
917 if ( (newH != theScreen.origin.h) || (newV != theScreen.origin.v) ) {
918 if (newH != theScreen.origin.h)
919 SetCtlValue(theScreen.hScrollHandle, newH);
920 if (newV != theScreen.origin.v)
921 SetCtlValue(theScreen.vScrollHandle, newV);
922 updtRgn = NewRgn();
923 ScrollRect(&theScreen.picPRect,
924 theScreen.origin.h - newH,
925 theScreen.origin.v - newV,
926 updtRgn);
927 InvalRgn(updtRgn);
928 DisposeRgn(updtRgn);
929 theScreen.origin.h = newH;
930 theScreen.origin.v = newV;
931 SetScreenDrawRects();
932 changed = true;
933 }
934
935 else
936 changed = false;
937
938 return(changed);
939 }
940
941 /* ARGH! This routine needs error checking code. */
942
InitScreenMgr(h,v,title,resFile,rfCreator,rfType,fileMenuProc,appMenuProc,colorFlag)943 long InitScreenMgr(h, v, title, resFile, rfCreator, rfType, fileMenuProc,
944 appMenuProc, colorFlag)
945 long h, v;
946 char *title;
947 char *resFile;
948 OSType rfCreator, rfType;
949 void (*fileMenuProc)(long item);
950 void (*appMenuProc)(long item);
951 long colorFlag;
952
953 {
954 long bytes, i;
955 Rect bounds;
956 WStateData **zoomInfo;
957 Str63 pstrTitle, pstrResFile;
958
959 Prolog();
960
961 SysEnvirons(curSysEnvVers, &theScreen.env);
962
963 theScreen.wneImplemented = WNETest(&theScreen.env);
964
965 theScreen.escMapFlag = NoEscTest(&theScreen.env);
966
967 theScreen.backgrounding = false;
968
969 #if 1
970 {
971 char keys[128];
972 GetKeys ((KeyMap *) &keys);
973 theScreen.reconfigFlag = keys[7] & 0x04;
974 }
975 #else
976 theScreen.reconfigFlag = ((char *) KeyMapLM)[7] & 0x04;
977 #endif
978
979 strncpy(pstrTitle, title, 63);
980 strncpy(pstrResFile, resFile, 63);
981 pstrTitle[63] = '\0';
982 pstrResFile[63] = '\0';
983 c2pstr(pstrTitle);
984 c2pstr(pstrResFile);
985
986 LoadInfo(pstrResFile, rfCreator, rfType);
987
988 UseInfo(&bounds,
989 &theScreen.txSize,
990 &theScreen.colorStdFore,
991 &theScreen.colorStdBack);
992
993 theScreen.versHandle = GetResource (rfCreator, 0);
994
995 AdjustPortBounds(&bounds);
996
997 LoadCursors();
998
999 theScreen.waitFlag = false;
1000
1001 theScreen.txNum = -1;
1002
1003 theScreen.fileMenuProc = fileMenuProc;
1004 theScreen.appMenuProc = appMenuProc;
1005
1006 theScreen.colorFlag = colorFlag;
1007
1008 switch (theScreen.env.keyBoardType) {
1009
1010 /* These are the old machines that we know. */
1011 case envUnknownKbd:
1012 case envMacKbd:
1013 case envMacAndPad:
1014 case envMacPlusKbd:
1015 theScreen.cmdKeyFlag = false;
1016 break;
1017
1018 case envAExtendKbd:
1019 case envStandADBKbd:
1020 case 10: /* Mac Classic. */
1021 /* Anything else is probably new and has ctrl. */
1022 default:
1023 theScreen.cmdKeyFlag = true;
1024
1025 }
1026
1027 theScreen.mouseFlag = false;
1028 theScreen.mouseCRect.left =
1029 theScreen.mouseCRect.top =
1030 theScreen.mouseCRect.right =
1031 theScreen.mouseCRect.bottom = 0;
1032
1033 bytes = h * v;
1034 theScreen.chars = (char **) NewHandle(bytes);
1035 theScreen.attrs = (char **) NewHandle(bytes);
1036
1037 memset(*theScreen.chars, ' ', bytes);
1038 memset(*theScreen.attrs, attrNormal, bytes);
1039
1040 bytes = v * sizeof(short);
1041 theScreen.updLeft = (short **) NewHandle(bytes);
1042 theScreen.updRight = (short **) NewHandle(bytes);
1043
1044 for (i = 0; i < v; i++) {
1045 (*theScreen.updLeft)[i] = h;
1046 (*theScreen.updRight)[i] = 0;
1047 }
1048
1049 theScreen.cursor.h = 0;
1050 theScreen.cursor.v = 0;
1051
1052 theScreen.scrnCDims.h = h;
1053 theScreen.scrnCDims.v = v;
1054
1055 FlushQueue();
1056
1057 DefaultCursor();
1058
1059 GetFontSizes();
1060
1061 SetUpMenus();
1062
1063 theScreen.window = NewWindow(NULL, &bounds, pstrTitle,
1064 false, zoomDocProc,
1065 (WindowPtr) -1, true, 0);
1066
1067 SetPort(theScreen.window);
1068
1069 zoomInfo = (WStateData **) ((WindowPeek) theScreen.window)->dataHandle;
1070 theScreen.stdStateGRect = (*zoomInfo)->stdState;
1071
1072 TextFont(theScreen.txFont);
1073 TextSize(theScreen.txSize);
1074
1075 SetScreenParameters();
1076 SetScreenPortSize();
1077 SetScreenPortRects();
1078
1079 theScreen.origin.h = theScreen.scrnXLRect.left;
1080 theScreen.origin.v = theScreen.scrnXLRect.top;
1081
1082 SetScreenDrawRects();
1083
1084 theScreen.hScrollHandle = NewControl(theScreen.window,
1085 &theScreen.hScrollPRect, "", true,
1086 theScreen.origin.h,
1087 theScreen.scrnXLRect.left,
1088 theScreen.scrnXLRect.right - theScreen.picPRect.right,
1089 scrollBarProc, 0L);
1090 theScreen.vScrollHandle = NewControl(theScreen.window,
1091 &theScreen.vScrollPRect, "", true,
1092 theScreen.origin.v,
1093 theScreen.scrnXLRect.top,
1094 theScreen.scrnXLRect.bottom - theScreen.picPRect.bottom,
1095 scrollBarProc, 0L);
1096
1097 ShowWindow(theScreen.window);
1098 EraseRect(&theScreen.picPRect);
1099
1100 theScreen.aboutProc = NULL;
1101 theScreen.quitProc = NULL;
1102
1103 theScreen.keyFlush = theScreen.mouseFlush = TickCount();
1104
1105 theScreen.stack = NULL;
1106
1107 return(scrnErrOk);
1108 }
1109
ChangeScreenFontSize(num)1110 static void ChangeScreenFontSize(num)
1111 long num;
1112
1113 {
1114 Point oldCharPDims;
1115
1116 DisposeControl(theScreen.hScrollHandle);
1117 DisposeControl(theScreen.vScrollHandle);
1118
1119 oldCharPDims = theScreen.charPDims;
1120
1121 theScreen.txSize = (*theScreen.fontSizes)[num];
1122
1123 TextSize(theScreen.txSize);
1124
1125 SetScreenParameters();
1126 SetScreenPortSize();
1127 SetScreenPortRects();
1128
1129 theScreen.origin.h *= theScreen.charPDims.h;
1130 theScreen.origin.h /= oldCharPDims.h;
1131 if (theScreen.origin.h < theScreen.scrnXLRect.left)
1132 theScreen.origin.h = theScreen.scrnXLRect.left;
1133 if (theScreen.origin.h > theScreen.scrnXLRect.right
1134 - theScreen.picPRect.right)
1135 theScreen.origin.h = theScreen.scrnXLRect.right - theScreen.picPRect.right;
1136 theScreen.origin.v *= theScreen.charPDims.v;
1137 theScreen.origin.v /= oldCharPDims.v;
1138 if (theScreen.origin.v < theScreen.scrnXLRect.top)
1139 theScreen.origin.v = theScreen.scrnXLRect.top;
1140 if (theScreen.origin.v > theScreen.scrnXLRect.bottom -
1141 theScreen.picPRect.bottom)
1142 theScreen.origin.v = theScreen.scrnXLRect.bottom
1143 - theScreen.picPRect.bottom;
1144
1145 SetScreenDrawRects();
1146
1147 theScreen.hScrollHandle = NewControl(theScreen.window,
1148 &theScreen.hScrollPRect, "", true,
1149 theScreen.origin.h,
1150 theScreen.scrnXLRect.left,
1151 theScreen.scrnXLRect.right - theScreen.picPRect.right,
1152 scrollBarProc, 0L);
1153 theScreen.vScrollHandle = NewControl(theScreen.window,
1154 &theScreen.vScrollPRect, "", true,
1155 theScreen.origin.v,
1156 theScreen.scrnXLRect.top,
1157 theScreen.scrnXLRect.bottom - theScreen.picPRect.bottom,
1158 scrollBarProc, 0L);
1159
1160 InvalRect(&theScreen.picPRect);
1161 InvalRect(&theScreen.growPRect);
1162
1163 return;
1164 }
1165
CloseScreenMgr()1166 void CloseScreenMgr()
1167
1168 {
1169 SaveInfo();
1170
1171 while (theScreen.stack != NULL)
1172 DisposeStackTop();
1173
1174 DisposHandle((Handle) theScreen.fontSizes);
1175
1176 DisposHandle((Handle) theScreen.chars);
1177 DisposHandle((Handle) theScreen.attrs);
1178
1179 DisposeWindow(theScreen.window);
1180
1181 return;
1182 }
1183
DrawDefaultBorder(theWindow,theItem)1184 pascal void DrawDefaultBorder(theWindow, theItem)
1185 WindowPtr theWindow;
1186 short theItem;
1187
1188 {
1189 short itsType;
1190 Handle itsHandle;
1191 Rect itsRect;
1192
1193 GetDItem((DialogPtr) theWindow, theItem, &itsType, &itsHandle, &itsRect);
1194 PenSize(3, 3);
1195 ForeColor(redColor);
1196 FrameRoundRect(&itsRect, 16, 16);
1197 ForeColor(blackColor);
1198 PenSize(1, 1);
1199
1200 return;
1201 }
1202
DrawGroupRect(theWindow,theItem)1203 pascal void DrawGroupRect(theWindow, theItem)
1204 WindowPtr theWindow;
1205 short theItem;
1206
1207 {
1208 short itsType;
1209 Handle itsHandle;
1210 Rect itsRect;
1211
1212 GetDItem((DialogPtr) theWindow, theItem, &itsType, &itsHandle, &itsRect);
1213 FrameRect(&itsRect);
1214
1215 return;
1216 }
1217
DoAboutDialog()1218 static void DoAboutDialog()
1219
1220 {
1221 DialogPtr theDialog;
1222 short itemHit;
1223 short itsType;
1224 Handle itsHandle;
1225 Rect itsRect;
1226 long h, v;
1227
1228 theDialog = GetNewDialog(aboutDlgID, nil, (WindowPtr) -1);
1229
1230 CenterScreenDLOG(aboutDlgID, fixThird, fixThird, &h, &v);
1231 MoveWindow((WindowPtr) theDialog, (short) h, (short) v, false);
1232
1233 GetDItem(theDialog, ok, &itsType, &itsHandle, &itsRect);
1234 InsetRect(&itsRect, -4, -4);
1235
1236 SetDItem(theDialog, aboutDfltBorder, userItem,
1237 (Handle) DrawDefaultBorder, &itsRect);
1238
1239 if (theScreen.versHandle) {
1240 MoveHHi (theScreen.versHandle);
1241 HLock (theScreen.versHandle);
1242 ParamText(*(theScreen.versHandle), nil, nil, nil);
1243 }
1244
1245 ShowWindow((WindowPtr) theDialog);
1246
1247 do {
1248 ModalDialog(nil, &itemHit);
1249 } while (itemHit != ok);
1250
1251 if (theScreen.versHandle)
1252 HUnlock(theScreen.versHandle);
1253
1254 DisposDialog(theDialog);
1255
1256 return;
1257 }
1258
DoColorsDialog()1259 static void DoColorsDialog()
1260
1261 {
1262 DialogPtr theDialog;
1263 long saveForeColor, saveBackColor;
1264 short itemHit;
1265 short itsType;
1266 Handle itsHandle, fgHandle, bgHandle;
1267 Rect itsRect;
1268 GrafPtr savePort;
1269 long redrawFlag;
1270 long h, v;
1271
1272 theDialog = GetNewDialog(colorsDlgID, nil, (WindowPtr) -1);
1273
1274 CenterScreenDLOG(colorsDlgID, fixHalf, fixThird, &h, &v);
1275 MoveWindow((WindowPtr) theDialog, (short) h, (short) v, false);
1276
1277 GetDItem(theDialog, ok, &itsType, &itsHandle, &itsRect);
1278 InsetRect(&itsRect, -4, -4);
1279
1280 SetDItem(theDialog, colorsDfltBorder, userItem,
1281 (Handle) DrawDefaultBorder, &itsRect);
1282
1283 GetDItem(theDialog, foregroundRect, &itsType, &itsHandle, &itsRect);
1284 SetDItem(theDialog, foregroundRect, itsType, (Handle) DrawGroupRect,
1285 &itsRect);
1286 GetDItem(theDialog, backgroundRect, &itsType, &itsHandle, &itsRect);
1287 SetDItem(theDialog, backgroundRect, itsType, (Handle) DrawGroupRect,
1288 &itsRect);
1289
1290 GetDItem(theDialog, foreColors+theScreen.colorStdFore, &itsType,
1291 &fgHandle, &itsRect);
1292 SetCtlValue((ControlHandle) fgHandle, true);
1293
1294 GetDItem(theDialog, backColors+theScreen.colorStdBack, &itsType,
1295 &bgHandle, &itsRect);
1296 SetCtlValue((ControlHandle) bgHandle, true);
1297
1298 ShowWindow((WindowPtr) theDialog);
1299
1300 saveForeColor = theScreen.colorStdFore;
1301 saveBackColor = theScreen.colorStdBack;
1302
1303 do {
1304 redrawFlag = false;
1305 ModalDialog(nil, &itemHit);
1306 if ( (itemHit >= foreColors) &&
1307 (itemHit <= (foreColors+7)) &&
1308 (itemHit != (foreColors+theScreen.colorStdFore)) ) {
1309 theScreen.colorStdFore = itemHit - foreColors;
1310 SetCtlValue((ControlHandle) fgHandle, false);
1311 GetDItem(theDialog, foreColors+theScreen.colorStdFore,
1312 &itsType, &fgHandle, &itsRect);
1313 SetCtlValue((ControlHandle) fgHandle, true);
1314 redrawFlag = true;
1315 }
1316 else if ( (itemHit >= backColors) &&
1317 (itemHit <= (backColors+7)) &&
1318 (itemHit != (backColors+theScreen.colorStdBack)) ) {
1319 theScreen.colorStdBack = itemHit - backColors;
1320 SetCtlValue((ControlHandle) bgHandle, false);
1321 GetDItem(theDialog, backColors+theScreen.colorStdBack,
1322 &itsType, &bgHandle, &itsRect);
1323 SetCtlValue((ControlHandle) bgHandle, true);
1324 redrawFlag = true;
1325 }
1326 if (redrawFlag) {
1327 GetPort(&savePort);
1328 SetPort(theScreen.window);
1329 InvalRect(&theScreen.picPRect);
1330 UpdateScreen();
1331 SetPort(savePort);
1332 }
1333 } while ( (itemHit != ok) && (itemHit != cancel) );
1334
1335 if (itemHit == cancel)
1336 if ( (theScreen.colorStdFore != saveForeColor) ||
1337 (theScreen.colorStdBack != saveBackColor) ) {
1338 theScreen.colorStdFore = saveForeColor;
1339 theScreen.colorStdBack = saveBackColor;
1340 GetPort(&savePort);
1341 SetPort(theScreen.window);
1342 InvalRect(&theScreen.picPRect);
1343 UpdateScreen();
1344 SetPort(savePort);
1345 }
1346
1347 DisposDialog(theDialog);
1348
1349 return;
1350 }
1351
DoAppleMenu(item)1352 static void DoAppleMenu(item)
1353 long item;
1354
1355 {
1356 GrafPtr savePort;
1357 Str255 daName;
1358
1359 switch (item) {
1360
1361 case aboutItem: if (theScreen.aboutProc != NULL)
1362 (*theScreen.aboutProc)();
1363 else
1364 DoAboutDialog();
1365 break;
1366
1367 default: GetItem(GetMHandle(appleID), item, daName);
1368 GetPort(&savePort);
1369 OpenDeskAcc(daName);
1370 SetPort(savePort);
1371 break;
1372
1373 }
1374
1375 return;
1376 }
1377
DoFileMenu(item)1378 static void DoFileMenu(item)
1379 long item;
1380
1381 {
1382 switch (item) {
1383
1384 case closeBoxItem: HideWindow(theScreen.window);
1385 break;
1386
1387 case openItem: ShowWindow(theScreen.window);
1388 break;
1389
1390 case closeItem: HideWindow(theScreen.window);
1391 break;
1392
1393 case quitItem: if (theScreen.quitProc != NULL) {
1394 if (!theScreen.quitReturns) HiliteMenu(0);
1395 (*theScreen.quitProc)();
1396 }
1397 break;
1398
1399 }
1400
1401 return;
1402 }
1403
DoEditMenu(item)1404 static void DoEditMenu(item)
1405 long item;
1406
1407 {
1408 switch (item) {
1409
1410 case undoItem:
1411 case cutItem:
1412 case copyItem:
1413 case pasteItem:
1414 case clearItem: SystemEdit(item-1);
1415 break;
1416
1417 }
1418
1419 return;
1420 }
1421
DoFontChange(hndl,item,offset)1422 static void DoFontChange(hndl, item, offset)
1423 MenuHandle hndl;
1424 long item, offset;
1425
1426 {
1427 if (item != theScreen.txNum) {
1428 if (theScreen.txNum > 0)
1429 CheckItem(hndl, theScreen.txNum, false);
1430 ChangeScreenFontSize(item - offset);
1431 theScreen.txNum = item;
1432 CheckItem(hndl, theScreen.txNum, true);
1433 }
1434
1435 return;
1436 }
1437
DoScreenMenu(item)1438 static void DoScreenMenu(item)
1439 long item;
1440
1441 {
1442 switch (item) {
1443
1444 case colorsItem: DoColorsDialog();
1445 break;
1446
1447 default: DoFontChange(GetMHandle(screenID), item, 3);
1448 break;
1449
1450 }
1451
1452 return;
1453 }
1454
DoFontSizeMenu(item)1455 static void DoFontSizeMenu(item)
1456 long item;
1457
1458 {
1459 DoFontChange(GetMHandle(fontSizeID), item, 1L);
1460 return;
1461 }
1462
DoMenuItem(select)1463 static void DoMenuItem(select)
1464 long select;
1465
1466 {
1467 long menuID, menuItem;
1468
1469 menuID = HiWord(select);
1470 menuItem = LoWord(select);
1471
1472 switch (menuID) {
1473
1474 case appleID: DoAppleMenu(menuItem);
1475 break;
1476
1477 case fileID1:
1478 case fileID2: if (theScreen.fileMenuProc != NULL)
1479 (*theScreen.fileMenuProc)(menuItem);
1480 else
1481 DoFileMenu(menuItem);
1482 break;
1483
1484 case editID1:
1485 case editID2: DoEditMenu(menuItem);
1486 break;
1487
1488 case screenID: DoScreenMenu(menuItem);
1489 break;
1490
1491 case fontSizeID: DoFontSizeMenu(menuItem);
1492 break;
1493
1494 case appID1:
1495 case appID2: if (theScreen.appMenuProc != NULL)
1496 (*theScreen.appMenuProc)(menuItem);
1497 break;
1498
1499 }
1500
1501 HiliteMenu(0);
1502
1503 return;
1504 }
1505
DoDrag(whichWindow,cursorLoc)1506 static void DoDrag(whichWindow, cursorLoc)
1507 WindowPtr whichWindow;
1508 Point *cursorLoc;
1509
1510 {
1511 if (whichWindow == theScreen.window)
1512 DragWindow(whichWindow, *cursorLoc, &theScreen.dragLimitGRect);
1513
1514 return;
1515 }
1516
HandlePreGrow(oldWidth,oldHeight,newWidth,newHeight)1517 static void HandlePreGrow(oldWidth, oldHeight, newWidth, newHeight)
1518 long oldWidth, oldHeight, newWidth, newHeight;
1519
1520 {
1521 if (newWidth > oldWidth) {
1522 InvalRect(&theScreen.vScrollPRect);
1523 InvalRect(&theScreen.growPRect);
1524 }
1525 if (newHeight > oldHeight) {
1526 InvalRect(&theScreen.hScrollPRect);
1527 InvalRect(&theScreen.growPRect);
1528 }
1529 return;
1530 }
1531
HandlePostGrow(oldWidth,oldHeight,newWidth,newHeight)1532 static void HandlePostGrow(oldWidth, oldHeight, newWidth, newHeight)
1533 long oldWidth, oldHeight, newWidth, newHeight;
1534
1535 {
1536 if ( (newWidth < oldWidth) || (newHeight < oldHeight) )
1537 InvalRect(&theScreen.growPRect);
1538 HideControl(theScreen.hScrollHandle);
1539 HideControl(theScreen.vScrollHandle);
1540 if (newWidth != oldWidth) {
1541 MoveControl(theScreen.vScrollHandle,
1542 theScreen.vScrollPRect.left, theScreen.vScrollPRect.top);
1543 SizeControl(theScreen.hScrollHandle,
1544 theScreen.hScrollPRect.right - theScreen.hScrollPRect.left,
1545 theScreen.hScrollPRect.bottom - theScreen.hScrollPRect.top);
1546 SetCtlMax(theScreen.hScrollHandle,
1547 theScreen.scrnXLRect.right - theScreen.picPRect.right);
1548 }
1549 if (newHeight != oldHeight) {
1550 MoveControl(theScreen.hScrollHandle,
1551 theScreen.hScrollPRect.left, theScreen.hScrollPRect.top);
1552 SizeControl(theScreen.vScrollHandle,
1553 theScreen.vScrollPRect.right - theScreen.vScrollPRect.left,
1554 theScreen.vScrollPRect.bottom - theScreen.vScrollPRect.top);
1555 SetCtlMax(theScreen.vScrollHandle,
1556 theScreen.scrnXLRect.bottom - theScreen.picPRect.bottom);
1557 }
1558 RepositionScreen(0, 0);
1559 ShowControl(theScreen.hScrollHandle);
1560 ShowControl(theScreen.vScrollHandle);
1561 ValidRect(&theScreen.hScrollPRect);
1562 ValidRect(&theScreen.vScrollPRect);
1563 return;
1564 }
1565
DoGrow(whichWindow,cursorLoc)1566 static void DoGrow(whichWindow, cursorLoc)
1567 WindowPtr whichWindow;
1568 Point *cursorLoc;
1569
1570 {
1571 long newSize;
1572 long oldWidth, oldHeight;
1573 long newWidth, newHeight;
1574
1575 if (whichWindow == theScreen.window) {
1576 oldWidth = theScreen.windowW;
1577 oldHeight = theScreen.windowH;
1578 newSize = GrowWindow(whichWindow, *cursorLoc, &theScreen.sizeLimitPRect);
1579 if (newSize) {
1580 newWidth = LoWord(newSize);
1581 newHeight = HiWord(newSize);
1582 HandlePreGrow(oldWidth, oldHeight, newWidth, newHeight);
1583 SizeWindow(whichWindow, newWidth, newHeight, true);
1584 SetScreenPortRects();
1585 SetScreenDrawRects();
1586 HandlePostGrow(oldWidth, oldHeight, newWidth, newHeight);
1587 }
1588
1589 }
1590
1591 return;
1592 }
1593
DoZoom(whichWindow,part)1594 static void DoZoom(whichWindow, part)
1595 WindowPtr whichWindow;
1596 long part;
1597
1598 {
1599 WStateData **zoomInfo;
1600 Rect newSize;
1601 long oldWidth, oldHeight;
1602 long newWidth, newHeight;
1603
1604 if (whichWindow == theScreen.window) {
1605 oldWidth = theScreen.windowW;
1606 oldHeight = theScreen.windowH;
1607 zoomInfo = (WStateData **) ((WindowPeek) whichWindow)->dataHandle;
1608 if (part == inZoomIn)
1609 newSize = ((*zoomInfo)->userState);
1610 else
1611 newSize = ((*zoomInfo)->stdState);
1612 newWidth = newSize.right - newSize.left;
1613 newHeight = newSize.bottom - newSize.top;
1614 HandlePreGrow(oldWidth, oldHeight, newWidth, newHeight);
1615 EraseRect(&theScreen.window->portRect);
1616 ZoomWindow(whichWindow, part, false);
1617 SetScreenPortRects();
1618 SetScreenDrawRects();
1619 HandlePostGrow(oldWidth, oldHeight, newWidth, newHeight);
1620 }
1621
1622 return;
1623 }
1624
ActOnScroll(theControl,partCode)1625 static pascal void ActOnScroll(theControl, partCode)
1626 ControlHandle theControl;
1627 short partCode;
1628
1629 {
1630 int delta;
1631
1632 if (theControl == theScreen.hScrollHandle) {
1633
1634 switch (partCode) {
1635 case inUpButton:
1636 delta = -theScreen.charPDims.h;
1637 break;
1638 case inDownButton:
1639 delta = theScreen.charPDims.h;
1640 break;
1641 case inPageUp:
1642 delta = theScreen.charPDims.h - theScreen.picPRect.right;
1643 break;
1644 case inPageDown:
1645 delta = theScreen.picPRect.right - theScreen.charPDims.h;
1646 break;
1647 default:
1648 delta = 0;
1649 break;
1650 }
1651
1652 if (delta)
1653 if (RepositionScreen(delta, 0)) UpdateScreen();
1654
1655 }
1656
1657 if (theControl == theScreen.vScrollHandle) {
1658
1659 switch (partCode) {
1660 case inUpButton:
1661 delta = -theScreen.charPDims.v;
1662 break;
1663 case inDownButton:
1664 delta = theScreen.charPDims.v;
1665 break;
1666 case inPageUp:
1667 delta = theScreen.charPDims.v - theScreen.picPRect.bottom;
1668 break;
1669 case inPageDown:
1670 delta = theScreen.picPRect.bottom - theScreen.charPDims.v;
1671 break;
1672 default:
1673 delta = 0;
1674 break;
1675 }
1676
1677 if (delta)
1678 if (RepositionScreen(0, delta)) UpdateScreen();
1679
1680 }
1681
1682 return;
1683 }
1684
DoHScroll(cursorLoc,thePart)1685 static void DoHScroll(cursorLoc, thePart)
1686 Point *cursorLoc;
1687 long thePart;
1688
1689 {
1690 switch (thePart) {
1691
1692 case inUpButton:
1693 case inDownButton:
1694 case inPageUp:
1695 case inPageDown:
1696 TrackControl(theScreen.hScrollHandle, *cursorLoc, (ProcPtr) ActOnScroll);
1697 break;
1698
1699 case inThumb:
1700 TrackControl(theScreen.hScrollHandle, *cursorLoc, NULL);
1701 break;
1702
1703 }
1704
1705 RepositionScreen(0, 0);
1706
1707 return;
1708 }
1709
DoVScroll(cursorLoc,thePart)1710 static void DoVScroll(cursorLoc, thePart)
1711 Point *cursorLoc;
1712 long thePart;
1713
1714 {
1715 switch (thePart) {
1716
1717 case inUpButton:
1718 case inDownButton:
1719 case inPageUp:
1720 case inPageDown:
1721 TrackControl(theScreen.vScrollHandle, *cursorLoc, (ProcPtr) ActOnScroll);
1722 break;
1723
1724 case inThumb:
1725 TrackControl(theScreen.vScrollHandle, *cursorLoc, NULL);
1726 break;
1727
1728 }
1729
1730 RepositionScreen(0, 0);
1731
1732 return;
1733 }
1734
DoCharClick()1735 static void DoCharClick()
1736
1737 {
1738 int reversed;
1739 short h, v;
1740 char c, an, ar;
1741 char modifiers;
1742 Rect charCell;
1743 Point mouse;
1744 void GetScreenCharAttr(), XSetScreenCharAttr(), UpdateScreen();
1745
1746 if ( (theScreen.event.when > theScreen.mouseFlush) &&
1747 (theScreen.window == FrontWindow()) &&
1748 (((WindowPeek) theScreen.window)->visible) ) {
1749
1750 if (GtoC(theScreen.event.where.h, theScreen.event.where.v, &h, &v)) {
1751
1752 modifiers = (char) ((theScreen.event.modifiers & 0xF0) >> 8);
1753 modifiers |= maskModMouse;
1754
1755 charCell.left = charCell.right = h;
1756 charCell.top = charCell.bottom = v;
1757 charCell.right++;
1758 charCell.bottom++;
1759
1760 charCell.left *= theScreen.charPDims.h;
1761 charCell.top *= theScreen.charPDims.v;
1762 charCell.right *= theScreen.charPDims.h;
1763 charCell.bottom *= theScreen.charPDims.v;
1764
1765 OffsetRect(&charCell, -theScreen.origin.h, -theScreen.origin.v);
1766
1767 GetScreenCharAttr(&c, &an, h, v);
1768 ar = (an & maskAttrFlags) | (MakeAttr(AttrBack(an), AttrFore(an)));
1769
1770 XSetScreenCharAttr(false, c, ar, h, v);
1771 UpdateScreen();
1772 reversed = true;
1773
1774 while (StillDown()) {
1775 GetMouse(&mouse);
1776 if (reversed) {
1777 if (!PtInRect(mouse, &charCell)) {
1778 XSetScreenCharAttr(false, c, an, h, v);
1779 UpdateScreen();
1780 reversed = false;
1781 }
1782 }
1783 else {
1784 if (PtInRect(mouse, &charCell)) {
1785 XSetScreenCharAttr(false, c, ar, h, v);
1786 UpdateScreen();
1787 reversed = true;
1788 }
1789 }
1790 }
1791
1792 if (reversed) {
1793
1794 XSetScreenCharAttr(false, c, an, h, v);
1795 UpdateScreen();
1796 reversed = false;
1797
1798 PushQueue(0, modifiers, 0, h, v);
1799
1800 }
1801
1802 }
1803
1804 }
1805
1806 return;
1807 }
1808
DoContentClick(whichWindow,cursorLoc)1809 static void DoContentClick(whichWindow, cursorLoc)
1810 WindowPtr whichWindow;
1811 Point *cursorLoc;
1812
1813 {
1814 short thePart;
1815 ControlHandle theControl;
1816 Point localCursor;
1817
1818 if (whichWindow == theScreen.window) {
1819 localCursor = *cursorLoc;
1820 GlobalToLocal(&localCursor);
1821 if (thePart = FindControl(localCursor, whichWindow, &theControl)) {
1822 if (theControl == theScreen.hScrollHandle)
1823 DoHScroll(&localCursor, thePart);
1824 else if (theControl == theScreen.vScrollHandle)
1825 DoVScroll(&localCursor, thePart);
1826 }
1827 else
1828 if (theScreen.mouseFlag) DoCharClick();
1829 }
1830
1831 return;
1832 }
1833
DoMouseDown(cursorLoc)1834 static void DoMouseDown(cursorLoc)
1835 Point *cursorLoc;
1836
1837 {
1838 long part;
1839 WindowPtr whichWindow;
1840
1841 switch (part = FindWindow(*cursorLoc, &whichWindow)) {
1842
1843 case inMenuBar: DoMenuItem(MenuSelect(*cursorLoc));
1844 break;
1845
1846 case inDrag: DoDrag(whichWindow, cursorLoc);
1847 break;
1848
1849 case inGrow: DoGrow(whichWindow, cursorLoc);
1850 break;
1851
1852 case inSysWindow: SystemClick(&theScreen.event, whichWindow);
1853 break;
1854
1855 case inContent: if (whichWindow != FrontWindow())
1856 SelectWindow(whichWindow);
1857 else
1858 DoContentClick(whichWindow, cursorLoc);
1859 break;
1860
1861 case inZoomIn:
1862 case inZoomOut: if (whichWindow == theScreen.window)
1863 if (TrackBox(whichWindow, *cursorLoc, part))
1864 DoZoom(whichWindow, part);
1865 break;
1866
1867 case inGoAway: if (whichWindow == theScreen.window)
1868 if (TrackGoAway(whichWindow, *cursorLoc)) {
1869 if (theScreen.fileMenuProc != NULL)
1870 (*theScreen.fileMenuProc)(closeBoxItem);
1871 else
1872 DoFileMenu(closeBoxItem);
1873 }
1874 break;
1875
1876 }
1877
1878 return;
1879 }
1880
DoKeyDown(cmdFlag)1881 static void DoKeyDown(cmdFlag)
1882 int cmdFlag;
1883
1884 {
1885 char keycode, modifiers, ascii;
1886 char upper;
1887
1888 if ( (theScreen.event.when > theScreen.keyFlush) &&
1889 (theScreen.window == FrontWindow()) &&
1890 (((WindowPeek) theScreen.window)->visible) ) {
1891
1892 ObscureCursor();
1893
1894 keycode = (char) ((theScreen.event.message & keyCodeMask) >> 8);
1895
1896 modifiers = (char) ((theScreen.event.modifiers & 0xFF00) >> 8);
1897 modifiers &= ~maskModMouse;
1898
1899 ascii = (char) (theScreen.event.message & charCodeMask);
1900 if (theScreen.escMapFlag) {
1901 if (ascii == BACKQUOTE) ascii = ESC;
1902 }
1903 if (cmdFlag) {
1904 upper = ascii;
1905 if ( (upper >= 'a') && (upper <= 'z') )
1906 upper = 'A' + (upper - 'a');
1907 if ( (upper >= '@') && (upper <= '_') )
1908 ascii = upper - '@';
1909 }
1910
1911 PushQueue(keycode, modifiers, ascii, 0, 0);
1912
1913 }
1914
1915 return;
1916 }
1917
DoUpdate(whichWindow)1918 static void DoUpdate(whichWindow)
1919 WindowPtr whichWindow;
1920
1921 {
1922 if (whichWindow == theScreen.window) {
1923 UpdateScreen();
1924 }
1925
1926 return;
1927 }
1928
DoActivate(whichWindow,activated)1929 static void DoActivate(whichWindow, activated)
1930 WindowPtr whichWindow;
1931 Boolean activated;
1932
1933 {
1934 MenuHandle menu;
1935
1936 menu = GetMHandle(theScreen.cmdKeyFlag ? editID1 : editID2);
1937
1938 if (whichWindow == theScreen.window) {
1939
1940 if (activated) {
1941 DisableItem(menu, undoItem);
1942 DisableItem(menu, cutItem);
1943 DisableItem(menu, copyItem);
1944 DisableItem(menu, pasteItem);
1945 DisableItem(menu, clearItem);
1946 ShowControl(theScreen.vScrollHandle);
1947 ShowControl(theScreen.hScrollHandle);
1948 DrawGrowIcon(whichWindow);
1949 }
1950 else {
1951 EnableItem(menu, undoItem);
1952 EnableItem(menu, cutItem);
1953 EnableItem(menu, copyItem);
1954 EnableItem(menu, pasteItem);
1955 EnableItem(menu, clearItem);
1956 HideControl(theScreen.vScrollHandle);
1957 HideControl(theScreen.hScrollHandle);
1958 DrawGrowIcon(whichWindow);
1959 }
1960 }
1961
1962 return;
1963 }
1964
InvalScreenRect(d,r)1965 static void InvalScreenRect(d, r)
1966 int d;
1967 Rect *r;
1968
1969 {
1970 register long v;
1971 register short *left, *right;
1972 short rl, rt, rr, rb;
1973
1974 if (d) {
1975
1976 rl = r->left;
1977 rt = r->top;
1978 rr = r->right;
1979 rb = r->bottom;
1980
1981 left = *theScreen.updLeft + rt;
1982 right = *theScreen.updRight + rt;
1983
1984 for (v = rt; v < rb; v++, left++, right++) {
1985 if (rl < *left) *left = rl;
1986 if (rr > *right) *right = rr;
1987 }
1988
1989 }
1990
1991 else {
1992
1993 r->left *= theScreen.charPDims.h;
1994 r->right *= theScreen.charPDims.h;
1995 r->top *= theScreen.charPDims.v;
1996 r->bottom *= theScreen.charPDims.v;
1997
1998 SetOrigin(theScreen.origin.h, theScreen.origin.v);
1999 InvalRect(r);
2000 SetOrigin(0, 0);
2001
2002 }
2003
2004 return;
2005 }
2006
InvalCursor(d)2007 static void InvalCursor(d)
2008 int d;
2009
2010 {
2011 Rect curs;
2012
2013 curs.left = curs.right = theScreen.cursor.h;
2014 curs.top = curs.bottom = theScreen.cursor.v;
2015 curs.right += 1;
2016 curs.bottom += 1;
2017
2018 if (d)
2019 InvalScreenRect(d, &curs);
2020
2021 else {
2022
2023 curs.left *= theScreen.charPDims.h;
2024 curs.right *= theScreen.charPDims.h;
2025 curs.top = curs.bottom = curs.bottom * theScreen.charPDims.v;
2026 curs.top -= theScreen.cursorLines;
2027
2028 SetOrigin(theScreen.origin.h, theScreen.origin.v);
2029 InvalRect(&curs);
2030 SetOrigin(0, 0);
2031
2032 }
2033
2034 return;
2035 }
2036
XSetScreenChar(d,c,h,v)2037 void XSetScreenChar(d, c, h, v)
2038 int d;
2039 char c;
2040 long h, v;
2041
2042 {
2043 long loc;
2044 Rect area;
2045 Point pos;
2046
2047 pos.h = h;
2048 pos.v = v;
2049
2050 if (PtInRect(pos, &theScreen.scrnCRect)) {
2051
2052 loc = v * theScreen.scrnCDims.h + h;
2053 (*theScreen.chars)[loc] = c;
2054
2055 area.left = area.right = h;
2056 area.right += 1;
2057 area.top = area.bottom = v;
2058 area.bottom += 1;
2059
2060 InvalScreenRect(d, &area);
2061
2062 }
2063
2064 return;
2065 }
2066
XSetScreenBuffer(d,c,row,bounds,h,v)2067 void XSetScreenBuffer(d, c, row, bounds, h, v)
2068 int d;
2069 char *c;
2070 long row;
2071 Rect *bounds;
2072 long h, v;
2073
2074 {
2075 long i;
2076 long wid;
2077 long srcLoc, dstLoc;
2078 char *srcC, *dstC;
2079 Rect temp, area;
2080
2081 temp.right = temp.left = h;
2082 temp.right += bounds->right - bounds->left;
2083 temp.bottom = temp.top = v;
2084 temp.bottom += bounds->bottom - bounds->top;
2085
2086 if (SectRect(&temp, &theScreen.scrnCRect, &area)) {
2087
2088 srcLoc = (area.top + bounds->top - v) * row +
2089 (area.left + bounds->left - h);
2090 dstLoc = area.top * theScreen.scrnCDims.h + area.left;
2091
2092 srcC = c + srcLoc;
2093 dstC = *theScreen.chars + dstLoc;
2094
2095 wid = area.right - area.left;
2096
2097 if ( (wid == row) && (wid == theScreen.scrnCDims.h) ) {
2098 wid *= (area.bottom - area.top);
2099 memcpy(dstC, srcC, wid);
2100 }
2101
2102 else {
2103
2104 for (i = area.top; i < area.bottom; i++) {
2105 memcpy(dstC, srcC, wid);
2106 srcC += row;
2107 dstC += theScreen.scrnCDims.h;
2108 }
2109
2110 }
2111
2112 InvalScreenRect(d, &area);
2113
2114 }
2115
2116 return;
2117 }
2118
XSetScreenString(d,s,h,v)2119 void XSetScreenString(d, s, h, v)
2120 int d;
2121 char *s;
2122 long h, v;
2123
2124 {
2125 Rect bounds;
2126
2127 bounds.left = 0;
2128 bounds.right = strlen(s);
2129 bounds.top = 0;
2130 bounds.bottom = 1;
2131
2132 XSetScreenBuffer(d, s, bounds.right, &bounds, h, v);
2133
2134 return;
2135 }
2136
XSetScreenCharAttr(d,c,a,h,v)2137 void XSetScreenCharAttr(d, c, a, h, v)
2138 int d;
2139 char c;
2140 char a;
2141 long h, v;
2142
2143 {
2144 long loc;
2145 Rect area;
2146 Point pos;
2147
2148 pos.h = h;
2149 pos.v = v;
2150
2151 if (PtInRect(pos, &theScreen.scrnCRect)) {
2152
2153 loc = v * theScreen.scrnCDims.h + h;
2154 (*theScreen.chars)[loc] = c;
2155 (*theScreen.attrs)[loc] = a;
2156
2157 area.left = area.right = h;
2158 area.right += 1;
2159 area.top = area.bottom = v;
2160 area.bottom += 1;
2161
2162 InvalScreenRect(d, &area);
2163
2164 }
2165
2166 return;
2167 }
2168
XSetScreenBufferAttr(d,c,a,row,bounds,h,v)2169 void XSetScreenBufferAttr(d, c, a, row, bounds, h, v)
2170 int d;
2171 char *c;
2172 char a;
2173 long row;
2174 Rect *bounds;
2175 long h, v;
2176
2177 {
2178 long i;
2179 long wid;
2180 long srcLoc, dstLoc;
2181 char *srcC, *dstC;
2182 char *dstA;
2183 Rect temp, area;
2184
2185 temp.right = temp.left = h;
2186 temp.right += bounds->right - bounds->left;
2187 temp.bottom = temp.top = v;
2188 temp.bottom += bounds->bottom - bounds->top;
2189
2190 if (SectRect(&temp, &theScreen.scrnCRect, &area)) {
2191
2192 srcLoc = (area.top + bounds->top - v) * row +
2193 (area.left + bounds->left - h);
2194 dstLoc = area.top * theScreen.scrnCDims.h + area.left;
2195
2196 srcC = c + srcLoc;
2197 dstC = *theScreen.chars + dstLoc;
2198
2199 dstA = *theScreen.attrs + dstLoc;
2200
2201 wid = area.right - area.left;
2202
2203 if ( (wid == row) && (wid == theScreen.scrnCDims.h) ) {
2204 wid *= (area.bottom - area.top);
2205 memcpy(dstC, srcC, wid);
2206 memset(dstA, a, wid);
2207 }
2208
2209 else {
2210
2211 for (i = area.top; i < area.bottom; i++) {
2212 memcpy(dstC, srcC, wid);
2213 memset(dstA, a, wid);
2214 srcC += row;
2215 dstC += theScreen.scrnCDims.h;
2216 dstA += theScreen.scrnCDims.h;
2217 }
2218
2219 }
2220
2221 InvalScreenRect(d, &area);
2222
2223 }
2224
2225 return;
2226 }
2227
XSetScreenStringAttr(d,s,a,h,v)2228 void XSetScreenStringAttr(d, s, a, h, v)
2229 int d;
2230 char *s;
2231 char a;
2232 long h, v;
2233
2234 {
2235 Rect bounds;
2236
2237 bounds.left = 0;
2238 bounds.right = strlen(s);
2239 bounds.top = 0;
2240 bounds.bottom = 1;
2241
2242 XSetScreenBufferAttr(d, s, a, bounds.right, &bounds, h, v);
2243
2244 return;
2245 }
2246
XSetScreenImage(d,c,a,row,bounds,h,v)2247 void XSetScreenImage(d, c, a, row, bounds, h, v)
2248 int d;
2249 char *c;
2250 char *a;
2251 long row;
2252 Rect *bounds;
2253 long h, v;
2254
2255 {
2256 long i;
2257 long wid;
2258 long srcLoc, dstLoc;
2259 char *srcC, *dstC;
2260 char *srcA, *dstA;
2261 Rect temp, area;
2262
2263 temp.right = temp.left = h;
2264 temp.right += bounds->right - bounds->left;
2265 temp.bottom = temp.top = v;
2266 temp.bottom += bounds->bottom - bounds->top;
2267
2268 if (SectRect(&temp, &theScreen.scrnCRect, &area)) {
2269
2270 srcLoc = (area.top + bounds->top - v) * row +
2271 (area.left + bounds->left - h);
2272 dstLoc = area.top * theScreen.scrnCDims.h + area.left;
2273
2274 srcC = c + srcLoc;
2275 dstC = *theScreen.chars + dstLoc;
2276
2277 srcA = a + srcLoc;
2278 dstA = *theScreen.attrs + dstLoc;
2279
2280 wid = area.right - area.left;
2281
2282 if ( (wid == row) && (wid == theScreen.scrnCDims.h) ) {
2283 wid *= (area.bottom - area.top);
2284 memcpy(dstC, srcC, wid);
2285 memcpy(dstA, srcA, wid);
2286 }
2287
2288 else {
2289
2290 for (i = area.top; i < area.bottom; i++) {
2291 memcpy(dstC, srcC, wid);
2292 memcpy(dstA, srcA, wid);
2293 srcC += row;
2294 srcA += row;
2295 dstC += theScreen.scrnCDims.h;
2296 dstA += theScreen.scrnCDims.h;
2297 }
2298
2299 }
2300
2301 InvalScreenRect(d, &area);
2302
2303 }
2304
2305 return;
2306 }
2307
XWriteScreenChar(d,c)2308 void XWriteScreenChar(d, c)
2309 int d;
2310 char c;
2311
2312 {
2313 InvalCursor(d);
2314
2315 XSetScreenChar(d, c, theScreen.cursor.h, theScreen.cursor.v);
2316 theScreen.cursor.h++;
2317
2318 InvalCursor(d);
2319
2320 return;
2321 }
2322
XWriteScreenBuffer(d,c,row,bounds)2323 void XWriteScreenBuffer(d, c, row, bounds)
2324 int d;
2325 char *c;
2326 long row;
2327 Rect *bounds;
2328
2329 {
2330 XSetScreenBuffer(d, c, row, bounds, theScreen.cursor.h,
2331 theScreen.cursor.v);
2332 theScreen.cursor.h += bounds->right - bounds->left;
2333 theScreen.cursor.v += bounds->bottom - bounds->top;
2334
2335 InvalCursor(d);
2336
2337 return;
2338 }
2339
XWriteScreenString(d,s)2340 void XWriteScreenString(d, s)
2341 int d;
2342 char *s;
2343
2344 {
2345 XSetScreenString(d, s, theScreen.cursor.h, theScreen.cursor.v);
2346 theScreen.cursor.h += strlen(s);
2347
2348 InvalCursor(d);
2349
2350 return;
2351 }
2352
XWriteScreenCharAttr(d,c,a)2353 void XWriteScreenCharAttr(d, c, a)
2354 int d;
2355 char c;
2356 char a;
2357
2358 {
2359 XSetScreenCharAttr(d, c, a, theScreen.cursor.h, theScreen.cursor.v);
2360 theScreen.cursor.h++;
2361
2362 InvalCursor(d);
2363
2364 return;
2365 }
2366
XWriteScreenBufferAttr(d,c,a,row,bounds)2367 void XWriteScreenBufferAttr(d, c, a, row, bounds)
2368 int d;
2369 char *c;
2370 char a;
2371 long row;
2372 Rect *bounds;
2373
2374 {
2375 XSetScreenBufferAttr(d, c, a, row, bounds, theScreen.cursor.h,
2376 theScreen.cursor.v);
2377 theScreen.cursor.h += bounds->right - bounds->left;
2378 theScreen.cursor.v += bounds->bottom - bounds->top;
2379
2380 InvalCursor(d);
2381
2382 return;
2383 }
2384
XWriteScreenStringAttr(d,s,a)2385 void XWriteScreenStringAttr(d, s, a)
2386 int d;
2387 char *s;
2388 char a;
2389
2390 {
2391 XSetScreenStringAttr(d, s, a, theScreen.cursor.h, theScreen.cursor.v);
2392 theScreen.cursor.h += strlen(s);
2393
2394 InvalCursor(d);
2395
2396 return;
2397 }
2398
XWriteScreenImage(d,c,a,row,bounds)2399 void XWriteScreenImage(d, c, a, row, bounds)
2400 int d;
2401 char *c;
2402 char *a;
2403 long row;
2404 Rect *bounds;
2405
2406 {
2407 XSetScreenImage(d, c, a, row, bounds, theScreen.cursor.h,
2408 theScreen.cursor.v);
2409 theScreen.cursor.h += bounds->right - bounds->left;
2410 theScreen.cursor.v += bounds->bottom - bounds->top;
2411
2412 InvalCursor(d);
2413
2414 return;
2415 }
2416
XFillScreen(d,c,a,bounds)2417 void XFillScreen(d, c, a, bounds)
2418 int d;
2419 char c;
2420 char a;
2421 Rect *bounds;
2422
2423 {
2424 long i;
2425 long wid;
2426 long dstLoc;
2427 char *dstC;
2428 char *dstA;
2429 Rect area;
2430
2431 if (SectRect(bounds, &theScreen.scrnCRect, &area)) {
2432
2433 dstLoc = area.top * theScreen.scrnCDims.h + area.left;
2434
2435 dstC = *theScreen.chars + dstLoc;
2436
2437 dstA = *theScreen.attrs + dstLoc;
2438
2439 wid = area.right - area.left;
2440
2441 if (wid == theScreen.scrnCDims.h) {
2442 wid *= (area.bottom - area.top);
2443 memset(dstC, c, wid);
2444 memset(dstA, a, wid);
2445 }
2446
2447 else {
2448
2449 for (i = area.top; i < area.bottom; i++) {
2450 memset(dstC, c, wid);
2451 memset(dstA, a, wid);
2452 dstC += theScreen.scrnCDims.h;
2453 dstA += theScreen.scrnCDims.h;
2454 }
2455
2456 }
2457
2458 InvalScreenRect(d, &area);
2459
2460 }
2461
2462 return;
2463 }
2464
XEraseScreen(d,bounds)2465 void XEraseScreen(d, bounds)
2466 int d;
2467 Rect *bounds;
2468
2469 {
2470 XFillScreen(d, ' ', attrNormal, bounds);
2471 return;
2472 }
2473
ScrollScreenPositive(area,offset,factor)2474 static void ScrollScreenPositive(area, offset, factor)
2475 Rect *area;
2476 long offset;
2477 short factor;
2478
2479 {
2480 register short i, j;
2481 short loc; /* Index of initial destination. */
2482 short nxt; /* Amount to skip going from one row to the next. */
2483 register char *srcc, *dstc;
2484 register char *srca, *dsta;
2485
2486 loc = (area->bottom - 1) * theScreen.scrnCDims.h + area->right - 1;
2487
2488 dstc = *theScreen.chars + loc;
2489 srcc = dstc - offset * factor;
2490
2491 dsta = *theScreen.attrs + loc;
2492 srca = dsta - offset * factor;
2493
2494 nxt = theScreen.scrnCDims.h - (area->right - area->left);
2495
2496 for (j = area->bottom; j > area->top; j--) {
2497 for (i = area->right; i > area->left; i--) {
2498 *dstc-- = *srcc--;
2499 *dsta-- = *srca--;
2500 }
2501 srcc -= nxt;
2502 dstc -= nxt;
2503 srca -= nxt;
2504 dsta -= nxt;
2505 }
2506
2507 return;
2508 }
2509
ScrollScreenNegative(area,offset,factor)2510 static void ScrollScreenNegative(area, offset, factor)
2511 Rect *area;
2512 long offset;
2513 short factor;
2514
2515 {
2516 register short i, j;
2517 short loc;
2518 short nxt;
2519 register char *srcc, *dstc;
2520 register char *srca, *dsta;
2521
2522 loc = area->top * theScreen.scrnCDims.h + area->left;
2523
2524 dstc = *theScreen.chars + loc;
2525 srcc = dstc - offset * factor; /* Offset is negative! */
2526
2527 dsta = *theScreen.attrs + loc;
2528 srca = dsta - offset * factor;
2529
2530 nxt = theScreen.scrnCDims.h - (area->right - area->left);
2531
2532 for (j = area->top; j < area->bottom; j++) {
2533 for (i = area->left; i < area->right; i++) {
2534 *dstc++ = *srcc++;
2535 *dsta++ = *srca++;
2536 }
2537 srcc += nxt;
2538 dstc += nxt;
2539 srca += nxt;
2540 dsta += nxt;
2541 }
2542
2543 return;
2544 }
2545
XScrollScreen(d,dh,dv,bounds,attr)2546 void XScrollScreen(d, dh, dv, bounds, attr)
2547 int d;
2548 long dh, dv;
2549 Rect *bounds;
2550 char attr;
2551
2552 {
2553 long wid, dep;
2554 Rect area, clear;
2555
2556 if (!dh && !dv) return;
2557
2558 if (SectRect(bounds, &theScreen.scrnCRect, &area)) {
2559
2560 wid = area.right - area.left;
2561 dep = area.bottom - area.top;
2562
2563 if ( (ABS(dh) >= wid) || (ABS(dv) >= dep) )
2564
2565 XFillScreen(d, ' ', attr, &area);
2566
2567 else {
2568
2569 if (dv > 0) {
2570 clear = area;
2571 clear.bottom = area.top += dv;
2572 ScrollScreenPositive(&area, dv, (short)theScreen.scrnCDims.h);
2573 XFillScreen(d, ' ', attr, &clear);
2574 }
2575
2576 else if (dv < 0) {
2577 clear = area;
2578 clear.top = area.bottom += dv;
2579 ScrollScreenNegative(&area, dv, (short)theScreen.scrnCDims.h);
2580 XFillScreen(d, ' ', attr, &clear);
2581 }
2582
2583 if (dh > 0) {
2584 clear = area;
2585 clear.right = area.left += dh;
2586 ScrollScreenPositive(&area, dh, (short)1);
2587 XFillScreen(d, ' ', attr, &clear);
2588 }
2589
2590 else if (dh < 0) {
2591 clear = area;
2592 clear.left = area.right += dh;
2593 ScrollScreenNegative(&area, dh, (short)1);
2594 XFillScreen(d, ' ', attr, &clear);
2595 }
2596
2597 InvalScreenRect(d, &area);
2598
2599 }
2600
2601 }
2602
2603 return;
2604 }
2605
GetScreenCharAttr(c,a,h,v)2606 void GetScreenCharAttr(c, a, h, v)
2607 char *c;
2608 char *a;
2609 long h, v;
2610
2611 {
2612 long loc;
2613 Point pos;
2614
2615 pos.h = h;
2616 pos.v = v;
2617
2618 if (PtInRect(pos, &theScreen.scrnCRect)) {
2619
2620 loc = v * theScreen.scrnCDims.h + h;
2621 *c = (*theScreen.chars)[loc];
2622 *a = (*theScreen.attrs)[loc];
2623
2624 }
2625
2626 return;
2627 }
2628
GetScreenImage(c,a,row,bounds,h,v)2629 void GetScreenImage(c, a, row, bounds, h, v)
2630 char *c;
2631 char *a;
2632 long row;
2633 Rect *bounds;
2634 long h, v;
2635
2636 {
2637 long i;
2638 long wid;
2639 long srcLoc, dstLoc;
2640 char *srcC, *dstC;
2641 char *srcA, *dstA;
2642 Rect temp, area;
2643
2644 temp.right = temp.left = h;
2645 temp.right += bounds->right - bounds->left;
2646 temp.bottom = temp.top = v;
2647 temp.bottom += bounds->bottom - bounds->top;
2648
2649 if (SectRect(&temp, &theScreen.scrnCRect, &area)) {
2650
2651 dstLoc = (area.top + bounds->top - v) * row +
2652 (area.left + bounds->left - h);
2653 srcLoc = area.top * theScreen.scrnCDims.h + area.left;
2654
2655 dstC = c + dstLoc;
2656 srcC = *theScreen.chars + srcLoc;
2657
2658 dstA = a + dstLoc;
2659 srcA = *theScreen.attrs + srcLoc;
2660
2661 wid = area.right - area.left;
2662
2663 if ( (wid == row) && (wid == theScreen.scrnCDims.h) ) {
2664 wid *= (area.bottom - area.top);
2665 memcpy(dstC, srcC, wid);
2666 memcpy(dstA, srcA, wid);
2667 }
2668
2669 else {
2670
2671 for (i = area.top; i < area.bottom; i++) {
2672 memcpy(dstC, srcC, wid);
2673 memcpy(dstA, srcA, wid);
2674 dstC += row;
2675 dstA += row;
2676 srcC += theScreen.scrnCDims.h;
2677 srcA += theScreen.scrnCDims.h;
2678 }
2679
2680 }
2681
2682 }
2683
2684 return;
2685 }
2686
XMoveScreenCursor(d,h,v)2687 void XMoveScreenCursor(d, h, v)
2688 int d;
2689 long h, v;
2690
2691 {
2692 InvalCursor(d);
2693
2694 theScreen.cursor.h += h;
2695 theScreen.cursor.v += v;
2696
2697 InvalCursor(d);
2698
2699 return;
2700 }
2701
XSetScreenCursor(d,h,v)2702 void XSetScreenCursor(d, h, v)
2703 int d;
2704 long h, v;
2705
2706 {
2707 InvalCursor(d);
2708
2709 theScreen.cursor.h = h;
2710 theScreen.cursor.v = v;
2711
2712 InvalCursor(d);
2713
2714 return;
2715 }
2716
GetScreenCursor(h,v)2717 void GetScreenCursor(h, v)
2718 long *h, *v;
2719 {
2720 *h = theScreen.cursor.h;
2721 *v = theScreen.cursor.v;
2722 return;
2723 }
2724
CheckCursorStatus()2725 static long CheckCursorStatus()
2726
2727 {
2728 long oldStatus;
2729 long changed;
2730
2731 oldStatus = theScreen.cursorStatus;
2732
2733 if (theScreen.cursorLevel <= 0)
2734 theScreen.cursorStatus = 0;
2735 else if (!theScreen.cursorBlink)
2736 theScreen.cursorStatus = 1;
2737 else if (theScreen.cursorChangeTick <= TickCount())
2738 theScreen.cursorStatus = !oldStatus;
2739
2740 changed = theScreen.cursorStatus != oldStatus;
2741
2742 if (changed) {
2743 theScreen.cursorChangeTick = TickCount() + theScreen.cursorBlink;
2744 InvalCursor(0);
2745 }
2746
2747 return(changed);
2748 }
2749
InvalDelayed()2750 static void InvalDelayed()
2751
2752 {
2753 long v;
2754 short *left, *right;
2755 Rect inval;
2756
2757 v = 0;
2758 left = *theScreen.updLeft;
2759 right = *theScreen.updRight;
2760
2761 while (v < theScreen.scrnCDims.v) {
2762
2763 if (!*right) {
2764
2765 v++;
2766 left++;
2767 right++;
2768
2769 }
2770
2771 else {
2772
2773 inval.top = v;
2774 inval.left = *left;
2775 inval.right = *right;
2776
2777 do {
2778 v++;
2779 *left++ = theScreen.scrnCDims.h;
2780 *right++ = 0;
2781 } while ( (v < theScreen.scrnCDims.v) &&
2782 (*left == inval.left) &&
2783 (*right == inval.right) );
2784
2785 inval.bottom = v;
2786
2787 InvalScreenRect(0, &inval);
2788
2789 left = *theScreen.updLeft + v;
2790 right = *theScreen.updRight + v;
2791
2792 }
2793
2794 }
2795
2796 return;
2797
2798 }
2799
UpdateScreenLine(area,c,a,len)2800 static void UpdateScreenLine(area, c, a, len)
2801 Rect *area;
2802 char *c;
2803 char *a;
2804 long len;
2805
2806 {
2807 long count;
2808 char attr;
2809 char *last, *prev;
2810 short face;
2811 Rect temp;
2812
2813 temp = *area;
2814
2815 last = a + len;
2816
2817 while (a < last) {
2818
2819 attr = *a;
2820
2821 prev = a;
2822 while ( (a < last) && (*a == attr) ) a++;
2823 count = a - prev;
2824
2825 temp.right = temp.left + count * theScreen.charPDims.h;
2826
2827 face = normal;
2828 if (attr & attrUnderlined) face |= underline;
2829 if (attr & attrItalicized) face |= italic;
2830 TextFace(face);
2831
2832 if (theScreen.colorFlag) {
2833 ForeColor(colors[AttrFore(attr)]);
2834 BackColor(colors[AttrBack(attr)]);
2835 }
2836 else {
2837 ForeColor(
2838 colors[
2839 (AttrFore(attr) == attrColorBack) ?
2840 theScreen.colorStdBack : theScreen.colorStdFore]);
2841 BackColor(
2842 colors[
2843 (AttrBack(attr) == attrColorBack) ?
2844 theScreen.colorStdBack : theScreen.colorStdFore]);
2845 }
2846
2847 EraseRect(&temp);
2848
2849 DrawText(c, 0, count);
2850
2851 temp.left = temp.right;
2852
2853 c += count;
2854
2855 }
2856
2857 return;
2858 }
2859
UpdateScreen()2860 void UpdateScreen()
2861
2862 {
2863 long j;
2864 long top, dep, left, wid;
2865 Rect clear, area, curs;
2866 RgnHandle vis;
2867 char *c, *a;
2868 long cursorLoc;
2869
2870 InvalDelayed();
2871
2872 BeginUpdate(theScreen.window);
2873
2874 SetOrigin(theScreen.origin.h, theScreen.origin.v);
2875
2876 ClipRect(&theScreen.picLRect);
2877
2878 if (!theScreen.colorFlag)
2879 BackColor(colors[theScreen.colorStdBack]);
2880
2881 if (theScreen.picLRect.top < theScreen.scrnLRect.top) {
2882 clear = theScreen.picLRect;
2883 clear.bottom = theScreen.scrnLRect.top;
2884 EraseRect(&clear);
2885 }
2886
2887 if (theScreen.picLRect.left < theScreen.scrnLRect.left) {
2888 clear = theScreen.picLRect;
2889 clear.right = theScreen.scrnLRect.left;
2890 EraseRect(&clear);
2891 }
2892
2893 if (theScreen.picLRect.right > theScreen.scrnLRect.right) {
2894 clear = theScreen.picLRect;
2895 clear.left = theScreen.scrnLRect.right;
2896 EraseRect(&clear);
2897 }
2898
2899 if (theScreen.picLRect.bottom > theScreen.scrnLRect.bottom) {
2900 clear = theScreen.picLRect;
2901 clear.top = theScreen.scrnLRect.bottom;
2902 EraseRect(&clear);
2903 }
2904
2905 ClipRect(&theScreen.drawLRect);
2906
2907 vis = theScreen.window->visRgn;
2908
2909 top = theScreen.drawXCRect.top;
2910 dep = theScreen.drawXCRect.bottom - top;
2911
2912 left = theScreen.drawXCRect.left;
2913 wid = theScreen.drawXCRect.right - left;
2914
2915 HLock((Handle) theScreen.chars);
2916 HLock((Handle) theScreen.attrs);
2917
2918 c = *theScreen.chars + top * theScreen.scrnCDims.h + left;
2919 a = *theScreen.attrs + top * theScreen.scrnCDims.h + left;
2920
2921 area = theScreen.drawXLRect;
2922 area.bottom = area.top + theScreen.charPDims.v;
2923
2924 for (j = 0; j < dep; j++) {
2925
2926 if (RectInRgn(&area, vis)) {
2927 MoveTo(area.left, area.top + theScreen.info.ascent);
2928 UpdateScreenLine(&area, c, a, wid);
2929 }
2930
2931 area.top = area.bottom;
2932 area.bottom += theScreen.charPDims.v;
2933
2934 c += theScreen.scrnCDims.h;
2935 a += theScreen.scrnCDims.h;
2936
2937 }
2938
2939 HUnlock((Handle) theScreen.chars);
2940 HUnlock((Handle) theScreen.attrs);
2941
2942 if (theScreen.cursorStatus) {
2943 curs.left = curs.right = theScreen.cursor.h * theScreen.charPDims.h;
2944 curs.right += theScreen.charPDims.h;
2945 curs.bottom = curs.top = (theScreen.cursor.v + 1) * theScreen.charPDims.v;
2946 if (theScreen.cursorLines <= theScreen.charPDims.v)
2947 curs.top -= theScreen.cursorLines;
2948 else
2949 curs.top -= theScreen.charPDims.v;
2950 if (theScreen.colorFlag)
2951 BackColor(colors[theScreen.cursorColor]);
2952 else {
2953 cursorLoc = theScreen.cursor.v * theScreen.scrnCDims.h
2954 + theScreen.cursor.h;
2955 BackColor(
2956 colors[
2957 (AttrFore((*theScreen.attrs)[cursorLoc]) == attrColorBack) ?
2958 theScreen.colorStdBack : theScreen.colorStdFore]);
2959 }
2960 EraseRect(&curs);
2961 }
2962
2963 SetOrigin(0, 0);
2964
2965 TextFace(normal);
2966
2967 ForeColor(blackColor);
2968 BackColor(whiteColor);
2969
2970 MoveTo(0, 0);
2971
2972 ClipRect(&theScreen.window->portRect);
2973
2974 UpdtControl(theScreen.window, theScreen.window->visRgn);
2975 DrawGrowIcon(theScreen.window);
2976
2977 EndUpdate(theScreen.window);
2978
2979 return;
2980 }
2981
IdleScreenMgr()2982 void IdleScreenMgr()
2983
2984 {
2985 long more;
2986 short mask;
2987
2988 do {
2989
2990 mask = everyEvent;
2991 if (theScreen.waitFlag) {
2992 mask -= mDownMask;
2993 mask -= keyDownMask;
2994 mask -= autoKeyMask;
2995 }
2996
2997 if ( (!theScreen.backgrounding) && (theScreen.window == FrontWindow()) )
2998 CheckCursorStatus();
2999
3000 if (theScreen.wneImplemented) {
3001 more = WaitNextEvent(mask, &theScreen.event, 0, NULL);
3002 }
3003 else {
3004 SystemTask();
3005 more = GetNextEvent(mask, &theScreen.event);
3006 }
3007
3008 if (more)
3009 switch (theScreen.event.what) {
3010
3011 case mouseDown: DoMouseDown(&theScreen.event.where);
3012 break;
3013
3014 case autoKey:
3015 case keyDown: if (theScreen.event.modifiers & cmdKey) {
3016 if (theScreen.cmdKeyFlag) {
3017 if (theScreen.event.what != autoKey)
3018 DoMenuItem(MenuKey(theScreen.event.message & charCodeMask));
3019 }
3020 else
3021 DoKeyDown(true);
3022 }
3023 else
3024 DoKeyDown(false);
3025 break;
3026
3027 case updateEvt: DoUpdate((WindowPtr) theScreen.event.message);
3028 break;
3029
3030 case activateEvt: DoActivate((WindowPtr) theScreen.event.message,
3031 theScreen.event.modifiers & activeFlag);
3032 break;
3033
3034 case osEvent: if ((theScreen.event.message >> 24)
3035 == suspendResumeMessage) {
3036 if (theScreen.event.message & resumeMask) {
3037 theScreen.backgrounding = false;
3038 DoActivate((WindowPtr) FrontWindow(), true);
3039 }
3040 else {
3041 theScreen.backgrounding = true;
3042 DoActivate((WindowPtr) FrontWindow(), false);
3043 }
3044 }
3045
3046 }
3047
3048 } while (more);
3049
3050 return;
3051 }
3052
FlushScreenKeys()3053 void FlushScreenKeys()
3054
3055 {
3056 theScreen.keyFlush = theScreen.mouseFlush = TickCount();
3057 FlushQueue();
3058 return;
3059 }
3060
CountScreenKeys()3061 long CountScreenKeys()
3062
3063 {
3064 return(LenQueue());
3065 }
3066
GetScreenKeys(keycode,modifiers,ascii,h,v)3067 int GetScreenKeys(keycode, modifiers, ascii, h, v)
3068 char *keycode;
3069 char *modifiers;
3070 char *ascii;
3071 short *h;
3072 short *v;
3073
3074 {
3075 short flag;
3076 short th, tv;
3077
3078 if (flag = PopQueue(keycode, modifiers, ascii, &th, &tv)) {
3079 if (h != NULL) *h = th;
3080 if (v != NULL) *v = tv;
3081 }
3082
3083 return(flag);
3084 }
3085
EnableScreenMouse(flag)3086 void EnableScreenMouse(flag)
3087 long flag;
3088
3089 {
3090 if ( (flag) && (!theScreen.mouseFlag) ) theScreen.mouseFlush = TickCount();
3091 theScreen.mouseFlag = flag;
3092 return;
3093 }
3094
ClipScreenMouse(area)3095 void ClipScreenMouse(area)
3096 Rect *area;
3097
3098 {
3099 theScreen.mouseLRect = theScreen.mouseCRect = *area;
3100 theScreen.mouseLRect.left *= theScreen.charPDims.h;
3101 theScreen.mouseLRect.top *= theScreen.charPDims.v;
3102 theScreen.mouseLRect.right *= theScreen.charPDims.h;
3103 theScreen.mouseLRect.bottom *= theScreen.charPDims.v;
3104
3105 return;
3106 }
3107
DefineScreenCursor(color,lines,blinkRate)3108 void DefineScreenCursor(color, lines, blinkRate)
3109 long color;
3110 long lines;
3111 long blinkRate;
3112
3113 {
3114 theScreen.cursorColor = color;
3115 theScreen.cursorLines = lines;
3116 theScreen.cursorBlink = blinkRate;
3117
3118 InvalCursor(0);
3119
3120 return;
3121 }
3122
HideScreenCursor()3123 void HideScreenCursor()
3124
3125 {
3126 theScreen.cursorLevel--;
3127 CheckCursorStatus();
3128 return;
3129 }
3130
ShowScreenCursor()3131 void ShowScreenCursor()
3132
3133 {
3134 theScreen.cursorLevel++;
3135 CheckCursorStatus();
3136 return;
3137 }
3138
3139 void SetScreenAboutProc(procPtr)
3140 void (*procPtr)();
3141
3142 {
3143 theScreen.aboutProc = procPtr;
3144 return;
3145 }
3146
3147 void SetScreenQuitProc(procPtr, flag)
3148 void (*procPtr)();
3149 long flag;
3150
3151 {
3152 theScreen.quitProc = procPtr;
3153 theScreen.quitReturns = flag;
3154 return;
3155 }
3156
YesOrNo(text)3157 long YesOrNo(text)
3158 char *text;
3159
3160 {
3161 DialogPtr theDialog;
3162 short itemHit;
3163 short itsType;
3164 Handle itsHandle;
3165 Rect itsRect;
3166 Str255 ptext;
3167 long h, v;
3168
3169 theDialog = GetNewDialog(yesOrNoDlgID, nil, (WindowPtr) -1);
3170
3171 CenterScreenDLOG(yesOrNoDlgID, fixHalf, fixThird, &h, &v);
3172 MoveWindow((WindowPtr) theDialog, (short) h, (short) v, false);
3173
3174 GetDItem(theDialog, ok, &itsType, &itsHandle, &itsRect);
3175 InsetRect(&itsRect, -4, -4);
3176
3177 SetDItem(theDialog, yesOrNoDfltBorder, userItem,
3178 (Handle) DrawDefaultBorder, &itsRect);
3179
3180 if (text != NULL) {
3181 strncpy((char *)ptext, text, 255);
3182 ptext[255] = '\0';
3183 c2pstr((char *)ptext);
3184 GetDItem(theDialog, yesOrNoText, &itsType, &itsHandle, &itsRect);
3185 SetIText(itsHandle, ptext);
3186 }
3187
3188 ShowWindow((WindowPtr) theDialog);
3189
3190 do {
3191 ModalDialog(nil, &itemHit);
3192 } while ( (itemHit != ok) && (itemHit != cancel) );
3193
3194 DisposDialog(theDialog);
3195
3196 return(itemHit == ok);
3197 }
3198
ShowScreen(visible)3199 void ShowScreen(visible)
3200 long visible;
3201
3202 {
3203 if (visible)
3204 ShowWindow(theScreen.window);
3205 else
3206 HideWindow(theScreen.window);
3207
3208 return;
3209 }
3210
GetScreenBounds(bounds)3211 void GetScreenBounds(bounds)
3212 Rect *bounds;
3213
3214 {
3215
3216 #ifdef THINK_C
3217
3218 *bounds = screenBits.bounds;
3219 bounds->top += GetMBarHeight();
3220
3221 #else /* I think we can live without this. -- BS */
3222
3223 Point mouse;
3224 GDHandle gdh;
3225
3226 if (!theScreen.env.hasColorQD) {
3227 *bounds = qd.screenBits.bounds;
3228 bounds->top += GetMBarHeight();
3229 }
3230
3231 else {
3232
3233 *bounds = (*GetMainDevice())->gdRect;
3234
3235 GetMouse(&mouse);
3236 LocalToGlobal(&mouse);
3237
3238 gdh = GetDeviceList();
3239
3240 while (gdh != NULL) {
3241
3242 if (PtInRect(mouse, &(*gdh)->gdRect)) {
3243 *bounds = (*gdh)->gdRect;
3244 if (gdh == GetMainDevice()) bounds->top += GetMBarHeight();
3245 gdh = NULL;
3246 }
3247
3248 else
3249 gdh = GetNextDevice(gdh);
3250
3251 }
3252
3253 }
3254 #endif
3255
3256 return;
3257 }
3258
3259
CenterScreenDLOG(id,hRatio,vRatio,h,v)3260 void CenterScreenDLOG(id, hRatio, vRatio, h, v)
3261 long id;
3262 Fixed hRatio, vRatio;
3263 long *h, *v;
3264
3265 {
3266 long wid, hgt;
3267 DialogTHndl d;
3268 Rect bounds;
3269
3270 d = (DialogTHndl) GetResource('DLOG', (short) id);
3271
3272 if (d != NULL) {
3273
3274 wid = (*d)->boundsRect.right - (*d)->boundsRect.left;
3275 hgt = (*d)->boundsRect.bottom - (*d)->boundsRect.top;
3276
3277 GetScreenBounds(&bounds);
3278
3279 wid = (bounds.right - bounds.left) - wid;
3280 hgt = (bounds.bottom - bounds.top) - hgt;
3281
3282 *h = bounds.left + FixRound(hRatio * wid);
3283 *v = bounds.top + FixRound(vRatio * hgt);
3284
3285 }
3286
3287 return;
3288 }
3289
DoScreenALRT(id,kind,hRatio,vRatio)3290 long DoScreenALRT(id, kind, hRatio, vRatio)
3291 long id;
3292 long kind;
3293 Fixed hRatio, vRatio;
3294
3295 {
3296 long wid, hgt, h, v;
3297 long item;
3298 AlertTHndl a;
3299 Rect bounds;
3300
3301 a = (AlertTHndl) GetResource('ALRT', (short) id);
3302
3303 if (a != NULL) {
3304
3305 wid = (*a)->boundsRect.right - (*a)->boundsRect.left;
3306 hgt = (*a)->boundsRect.bottom - (*a)->boundsRect.top;
3307
3308 GetScreenBounds(&bounds);
3309
3310 wid = (bounds.right - bounds.left) - wid;
3311 hgt = (bounds.bottom - bounds.top) - hgt;
3312
3313 h = bounds.left + FixRound(hRatio * wid) - (*a)->boundsRect.left;
3314 v = bounds.top + FixRound(vRatio * hgt) - (*a)->boundsRect.top;
3315
3316 OffsetRect(&(*a)->boundsRect, (short) h, (short) v);
3317
3318 MoveHHi((Handle) a);
3319 HLock((Handle) a);
3320
3321 switch (kind) {
3322 case akNormal: item = Alert((short) id, NULL); break;
3323 case akStop: item = StopAlert((short) id, NULL); break;
3324 case akNote: item = NoteAlert((short) id, NULL); break;
3325 case akCaution: item = CautionAlert((short) id, NULL); break;
3326 }
3327
3328 HUnlock((Handle) a);
3329
3330 }
3331
3332 else
3333
3334 item = -1;
3335
3336 return(item);
3337 }
3338
ConfigScreenMgr(force,theType,theID,ConfigProc)3339 void ConfigScreenMgr(force, theType, theID, ConfigProc)
3340 long force;
3341 ResType theType;
3342 long theID;
3343 long (*ConfigProc)(Handle theData);
3344
3345 {
3346 short saveResFile, homeResFile;
3347 short attrs;
3348 short itsID;
3349 ResType itsType;
3350 Str255 itsName;
3351 Handle theData;
3352
3353 saveResFile = CurResFile();
3354 UseResFile(theScreen.infoResFile);
3355
3356 theData = GetResource(theType, (short) theID);
3357
3358 if (theData != NULL) {
3359
3360 homeResFile = HomeResFile(theData);
3361
3362 if ( (theScreen.reconfigFlag) ||
3363 (force) ||
3364 (homeResFile != theScreen.infoResFile) ) {
3365
3366 if ((*ConfigProc)(theData)) {
3367
3368 if (homeResFile != theScreen.infoResFile) {
3369 GetResInfo(theData, &itsID, &itsType, itsName);
3370 attrs = GetResAttrs(theData);
3371 attrs |= resChanged;
3372 DetachResource(theData);
3373 AddResource(theData, itsType, itsID, itsName);
3374 SetResAttrs(theData, attrs);
3375 }
3376 else
3377 ChangedResource(theData);
3378
3379 WriteResource(theData);
3380
3381 }
3382
3383 }
3384
3385 }
3386
3387 UseResFile(saveResFile);
3388
3389 return;
3390 }
3391
AnimateCursor()3392 static pascal void AnimateCursor()
3393
3394 {
3395 short next;
3396 long oldA5;
3397
3398 oldA5 = SetCurrentA5();
3399
3400 next = (*theScreen.acur)->next + 1;
3401 if (next >= (*theScreen.acur)->frames) next = 0;
3402 SetCursor(*((*theScreen.acur)->table[next].cursHandle));
3403 (*theScreen.acur)->next = next;
3404
3405 theScreen.vbl.vblCount = (short) theScreen.waitRate;
3406
3407 (void) SetA5(oldA5);
3408
3409 return;
3410 }
3411
BeginScreenWait(rate)3412 void BeginScreenWait(rate)
3413 long rate;
3414
3415 {
3416 if (!theScreen.waitFlag) {
3417
3418 (*theScreen.acur)->next = 0;
3419
3420 SetCursor(*((*theScreen.acur)->table[0].cursHandle));
3421 ShowCursor();
3422
3423 theScreen.waitFlag = true;
3424 theScreen.waitRate = rate;
3425
3426 theScreen.vbl.qType = vType;
3427 #ifdef THINK_C
3428 theScreen.vbl.vblAddr = (int (*)())AnimateCursor;
3429 #else
3430 theScreen.vbl.vblAddr = AnimateCursor;
3431 #endif
3432 theScreen.vbl.vblCount = (short) theScreen.waitRate;
3433 theScreen.vbl.vblPhase = 0;
3434
3435 (void) VInstall((QElemPtr) &theScreen.vbl);
3436
3437 }
3438
3439 return;
3440 }
3441
EndScreenWait()3442 void EndScreenWait()
3443
3444 {
3445 if (theScreen.waitFlag) {
3446
3447 (void) VRemove((QElemPtr) &theScreen.vbl);
3448
3449 theScreen.waitFlag = false;
3450
3451 InitCursor();
3452
3453 }
3454
3455 return;
3456 }
3457
GetFileMHandle()3458 Handle GetFileMHandle()
3459
3460 {
3461 return((Handle) GetMHandle(theScreen.cmdKeyFlag ? fileID1 : fileID2));
3462 }
3463
GetAppMHandle()3464 Handle GetAppMHandle()
3465
3466 {
3467 return((Handle) GetMHandle(theScreen.cmdKeyFlag ? appID1 : appID2));
3468 }
3469
PushScreen()3470 long PushScreen()
3471
3472 {
3473 long errcode;
3474 char **chars, **attrs;
3475 SaveScreenHandle next;
3476 OSErr oops;
3477
3478 next = (SaveScreenHandle) NewHandle(sizeof(SaveScreenRec));
3479
3480 if (next != NULL) {
3481
3482 chars = theScreen.chars;
3483 oops = HandToHand((Handle *) &chars);
3484
3485 if (oops == noErr) {
3486
3487 attrs = theScreen.attrs;
3488 oops = HandToHand((Handle *) &attrs);
3489
3490 if (oops == noErr) {
3491
3492 (*next)->link = theScreen.stack;
3493 (*next)->chars = chars;
3494 (*next)->attrs = attrs;
3495 (*next)->cursor = theScreen.cursor;
3496
3497 theScreen.stack = next;
3498
3499 errcode = scrnErrOk;
3500
3501 }
3502
3503 else {
3504
3505 DisposHandle((Handle) chars);
3506 DisposHandle((Handle) next);
3507
3508 errcode = scrnErrNoMem;
3509
3510 }
3511
3512 }
3513
3514 else {
3515
3516 DisposHandle((Handle) next);
3517
3518 errcode = scrnErrNoMem;
3519
3520 }
3521
3522 }
3523
3524 else {
3525
3526 errcode = scrnErrNoMem;
3527
3528 }
3529
3530 return(errcode);
3531 }
3532
PopScreen()3533 void PopScreen()
3534
3535 {
3536 if (theScreen.stack != NULL) {
3537
3538 HLock((Handle) (*theScreen.stack)->chars);
3539 HLock((Handle) (*theScreen.stack)->attrs);
3540
3541 XSetScreenImage(0,
3542 *(*theScreen.stack)->chars,
3543 *(*theScreen.stack)->attrs,
3544 theScreen.scrnCDims.h,
3545 &theScreen.scrnCRect,
3546 0, 0);
3547
3548 XSetScreenCursor(0, (*theScreen.stack)->cursor.h,
3549 (*theScreen.stack)->cursor.v);
3550
3551 DisposeStackTop();
3552
3553 UpdateScreen();
3554
3555 }
3556
3557 return;
3558 }
3559