1 /* Copyright (C) 2003-2004 artofcode LLC. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15
16 */
17
18 /* $Id: dmmain.c,v 1.5 2004/12/09 08:24:28 giles Exp $ */
19
20 /* Ghostscript shlib example wrapper for Macintosh (Classic/Carbon) contributed
21 by Nigel Hathaway. Uses the Metrowerks CodeWarrior SIOUX command-line library.
22 */
23
24 #if __ide_target("Ghostscript PPC (Debug)") || __ide_target("Ghostscript PPC (Release)")
25 #define TARGET_API_MAC_CARBON 0
26 #define TARGET_API_MAC_OS8 1
27 #define ACCESSOR_CALLS_ARE_FUNCTIONS 1
28 #endif
29
30 #include <Carbon.h>
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <stdio.h>
35 #include <console.h>
36 #include <SIOUX.h>
37 #include <SIOUXGlobals.h>
38 #include <SIOUXMenus.h>
39
40 #include "gscdefs.h"
41 #define GSREVISION gs_revision
42 #include "ierrors.h"
43 #include "iapi.h"
44
45 #if DEBUG
46 #include "vdtrace.h"
47 #endif
48
49 #include "gdevdsp.h"
50
51 #define kScrollBarWidth 15
52 #define MAX_ARGS 25
53
54 Boolean gRunningOnX = false;
55 Boolean gDone;
56 ControlActionUPP gActionFunctionScrollUPP;
57
58 const char start_string[] = "systemdict /start get exec\n";
59 void *instance;
60
61 const unsigned int display_format = DISPLAY_COLORS_RGB | DISPLAY_UNUSED_FIRST |
62 DISPLAY_DEPTH_8 | DISPLAY_BIGENDIAN |
63 DISPLAY_TOPFIRST;
64 typedef struct IMAGE_S IMAGE;
65 struct IMAGE_S {
66 void *handle;
67 void *device;
68 WindowRef windowRef;
69 ControlRef scrollbarVertRef;
70 ControlRef scrollbarHorizRef;
71 PixMapHandle pixmapHdl;
72 UInt64 update_time;
73 int update_interval;
74 IMAGE *next;
75 };
76
77 IMAGE *first_image;
78
79 static IMAGE *image_find(void *handle, void *device);
80
81 static int GSDLLCALL gsdll_stdin(void *instance, char *buf, int len);
82 static int GSDLLCALL gsdll_stdout(void *instance, const char *str, int len);
83 static int GSDLLCALL gsdll_stderr(void *instance, const char *str, int len);
84 static int GSDLLCALL gsdll_poll(void *handle);
85
86 static int display_open(void *handle, void *device);
87 static int display_preclose(void *handle, void *device);
88 static int display_close(void *handle, void *device);
89 static int display_presize(void *handle, void *device, int width, int height,
90 int raster, unsigned int format);
91 static int display_size(void *handle, void *device, int width, int height,
92 int raster, unsigned int format, unsigned char *pimage);
93 static int display_sync(void *handle, void *device);
94 static int display_page(void *handle, void *device, int copies, int flush);
95 static int display_update(void *handle, void *device,
96 int x, int y, int w, int h);
97
98 static size_t get_input(void *ptr, size_t size);
99
100 static void window_create (IMAGE *img);
101 static void window_invalidate (WindowRef windowRef);
102 static void window_adjust_scrollbars (WindowRef windowRef);
103
104 void main (void);
105 OSErr quitAppEventHandler (AppleEvent *,AppleEvent *,SInt32);
106 void doEvents (EventRecord *);
107 void doMouseDown (EventRecord *);
108 void doUpdate (EventRecord *);
109 void doUpdateWindow (EventRecord *);
110 void doOSEvent (EventRecord *);
111 void doInContent (EventRecord *,WindowRef);
112 pascal void actionFunctionScroll (ControlRef,ControlPartCode);
113
114 /*********************************************************************/
115 /* stdio functions */
116 static int GSDLLCALL
gsdll_stdin(void * instance,char * buf,int len)117 gsdll_stdin(void *instance, char *buf, int len)
118 {
119 if (isatty(fileno(stdin)))
120 return get_input(buf, len);
121 else
122 return fread(buf, 1, len, stdin);
123 }
124
125 static int GSDLLCALL
gsdll_stdout(void * instance,const char * str,int len)126 gsdll_stdout(void *instance, const char *str, int len)
127 {
128 int n = fwrite(str, 1, len, stdout);
129 fflush(stdout);
130 return n;
131 }
132
133 static int GSDLLCALL
gsdll_stderr(void * instance,const char * str,int len)134 gsdll_stderr(void *instance, const char *str, int len)
135 {
136 return gsdll_stdout(instance, str, len);
137 }
138
139 /* Poll the caller for cooperative multitasking. */
140 /* If this function is NULL, polling is not needed */
gsdll_poll(void * handle)141 static int GSDLLCALL gsdll_poll(void *handle)
142 {
143 EventRecord eventStructure;
144
145 while (WaitNextEvent(everyEvent, &eventStructure, 0, NULL))
146 doEvents(&eventStructure);
147
148 return (gDone ? e_Fatal : 0);
149 }
150 /*********************************************************************/
151
152 /* new dll display device */
153
154 /* New device has been opened */
155 /* This is the first event from this device. */
display_open(void * handle,void * device)156 static int display_open(void *handle, void *device)
157 {
158 IMAGE *img = (IMAGE *)malloc(sizeof(IMAGE));
159 if (img == NULL)
160 return -1;
161 memset(img, 0, sizeof(IMAGE));
162
163 /* add to list */
164 if (first_image)
165 img->next = first_image;
166 first_image = img;
167
168 /* remember device and handle */
169 img->handle = handle;
170 img->device = device;
171
172 /* create window */
173 window_create(img);
174
175 gsdll_poll(handle);
176 return 0;
177 }
178
179 /* Device is about to be closed. */
180 /* Device will not be closed until this function returns. */
display_preclose(void * handle,void * device)181 static int display_preclose(void *handle, void *device)
182 {
183 /* do nothing - no thread synchonisation needed */
184 return 0;
185 }
186
187 /* Device has been closed. */
188 /* This is the last event from this device. */
display_close(void * handle,void * device)189 static int display_close(void *handle, void *device)
190 {
191 IMAGE *img = image_find(handle, device);
192 if (img == NULL)
193 return -1;
194
195 gsdll_poll(handle);
196
197 /* remove from list */
198 if (img == first_image)
199 first_image = img->next;
200 else
201 {
202 IMAGE *tmp;
203 for (tmp = first_image; tmp!=0; tmp=tmp->next)
204 {
205 if (img == tmp->next)
206 tmp->next = img->next;
207 }
208 }
209
210 DisposePixMap(img->pixmapHdl); // need to go in doCloseWindow()
211 DisposeWindow(img->windowRef);
212
213 free(img);
214
215 return 0;
216 }
217
218 /* Device is about to be resized. */
219 /* Resize will only occur if this function returns 0. */
display_presize(void * handle,void * device,int width,int height,int raster,unsigned int format)220 static int display_presize(void *handle, void *device, int width, int height,
221 int raster, unsigned int format)
222 {
223 /* Check for correct format (32-bit RGB), fatal error if not */
224 if (format != display_format)
225 {
226 printf("DisplayFormat has been set to an incompatible value.\n");
227 fflush(stdout);
228 return e_rangecheck;
229 }
230
231 return 0;
232 }
233
234 /* Device has been resized. */
235 /* New pointer to raster returned in pimage */
display_size(void * handle,void * device,int width,int height,int raster,unsigned int format,unsigned char * pimage)236 static int display_size(void *handle, void *device, int width, int height,
237 int raster, unsigned int format, unsigned char *pimage)
238 {
239 PixMapPtr pixmap;
240 IMAGE *img = image_find(handle, device);
241 if (img == NULL)
242 return -1;
243
244 /* Check that image is within allowable bounds */
245 if (raster > 0x3fff)
246 {
247 printf("QuickDraw can't cope with an image this big.\n");
248 fflush(stdout);
249 if (img->pixmapHdl)
250 {
251 DisposePixMap(img->pixmapHdl);
252 img->pixmapHdl = NULL;
253 }
254 return e_rangecheck;
255 }
256
257 /* Create the PixMap */
258 if (!img->pixmapHdl)
259 img->pixmapHdl = NewPixMap();
260
261 pixmap = *(img->pixmapHdl);
262 pixmap->baseAddr = (char*)pimage;
263 pixmap->rowBytes = (((SInt16)raster) & 0x3fff) | 0x8000;
264 pixmap->bounds.right = width;
265 pixmap->bounds.bottom = height;
266 pixmap->packType = 0;
267 pixmap->packSize = 0;
268 pixmap->pixelType = RGBDirect;
269 pixmap->pixelSize = 32;
270 pixmap->cmpCount = 3;
271 pixmap->cmpSize = 8;
272
273 /* Update the display window */
274 window_adjust_scrollbars(img->windowRef);
275 window_invalidate(img->windowRef);
276 return gsdll_poll(handle);
277 }
278
279 /* flushpage */
display_sync(void * handle,void * device)280 static int display_sync(void *handle, void *device)
281 {
282 IMAGE *img = image_find(handle, device);
283 if (img == NULL)
284 return -1;
285
286 window_invalidate(img->windowRef);
287 gsdll_poll(handle);
288
289 return 0;
290 }
291
292 /* showpage */
293 /* If you want to pause on showpage, then don't return immediately */
display_page(void * handle,void * device,int copies,int flush)294 static int display_page(void *handle, void *device, int copies, int flush)
295 {
296 return display_sync(handle, device);
297 }
298
299 /* Poll the caller for cooperative multitasking. */
300 /* If this function is NULL, polling is not needed */
display_update(void * handle,void * device,int x,int y,int w,int h)301 static int display_update(void *handle, void *device,
302 int x, int y, int w, int h)
303 {
304 UInt64 t1;
305 UInt64 t2;
306 int delta;
307 IMAGE *img = image_find(handle, device);
308 if (img == NULL)
309 return -1;
310
311 Microseconds((UnsignedWide*)&t1);
312 delta = (t1 - img->update_time) / 1000000L;
313 if (img->update_interval < 1)
314 img->update_interval = 1; /* seconds */
315 if (delta < 0)
316 img->update_time = t1;
317 else if (delta > img->update_interval)
318 {
319 /* redraw window */
320 window_invalidate(img->windowRef);
321
322 /* Make sure the update interval is at least 10 times
323 * what it takes to paint the window
324 */
325 Microseconds((UnsignedWide*)&t2);
326 delta = (t2 - t1) / 1000;
327 if (delta < 0)
328 delta += 60000; /* delta = time to redraw */
329 if (delta > img->update_interval * 100)
330 img->update_interval = delta/100;
331 img->update_time = t2;
332 }
333
334 return gsdll_poll(handle);
335 }
336
337 display_callback display = {
338 sizeof(display_callback),
339 DISPLAY_VERSION_MAJOR,
340 DISPLAY_VERSION_MINOR,
341 display_open,
342 display_preclose,
343 display_close,
344 display_presize,
345 display_size,
346 display_sync,
347 display_page,
348 display_update,
349 NULL, /* memalloc */
350 NULL, /* memfree */
351 NULL /* display_separation */
352 };
353
image_find(void * handle,void * device)354 static IMAGE * image_find(void *handle, void *device)
355 {
356 IMAGE *img;
357 for (img = first_image; img!=0; img=img->next) {
358 if ((img->handle == handle) && (img->device == device))
359 return img;
360 }
361 return NULL;
362 }
363
364 /*********************************************************************/
365
366 static char *stdin_buf = NULL;
367 static size_t stdin_bufpos = 0;
368 static size_t stdin_bufsize = 0;
369
370 /* This function is a fudge which allows the SIOUX window to be waiting for
371 input and not be modal at the same time. (Why didn't MetroWerks think of that?)
372 It is based on the SIOUX function ReadCharsFromConsole(), and contains an
373 event loop which allows other windows to be active.
374 It collects characters up to when the user presses ENTER, stores the complete
375 buffer and gives as much to the calling function as it wants until it runs
376 out, at which point it gets another line (or set of lines if pasting from the
377 clipboard) from the user.
378 */
get_input(void * ptr,size_t size)379 static size_t get_input(void *ptr, size_t size)
380 {
381 EventRecord eventStructure;
382 long charswaiting, old_charswaiting = 0;
383 char *text;
384
385 #if SIOUX_USE_WASTE
386 Handle textHandle;
387 #endif
388
389 /* If needing more input, set edit start position */
390 if (!stdin_buf)
391 #if SIOUX_USE_WASTE
392 SIOUXselstart = WEGetTextLength(SIOUXTextWindow->edit);
393 #else
394 SIOUXselstart = (*SIOUXTextWindow->edit)->teLength;
395 #endif
396
397 /* Wait until user presses exit (or quits) */
398 while(!gDone && !stdin_buf)
399 {
400 #if SIOUX_USE_WASTE
401 charswaiting = WEGetTextLength(SIOUXTextWindow->edit) - SIOUXselstart;
402 #else
403 if ((*SIOUXTextWindow->edit)->teLength > 0)
404 charswaiting = (*SIOUXTextWindow->edit)->teLength - SIOUXselstart;
405 else
406 charswaiting = ((unsigned short) (*SIOUXTextWindow->edit)->teLength) - SIOUXselstart;
407 #endif
408
409 /* If something has happened, see if we need to do anything */
410 if (charswaiting != old_charswaiting)
411 {
412 #if SIOUX_USE_WASTE
413 textHandle = WEGetText(SIOUXTextWindow->edit);
414 HLock(textHandle);
415 text = *textHandle + SIOUXselstart;
416 #else
417 text = (*(*SIOUXTextWindow->edit)->hText) + SIOUXselstart;
418 #endif
419 /* If user has pressed enter, gather up the buffer ready for returning */
420 if (text[charswaiting-1] == '\r')
421 {
422 stdin_buf = malloc(charswaiting);
423 if (!stdin_buf)
424 return -1;
425 stdin_bufsize = charswaiting;
426 memcpy(stdin_buf, text, stdin_bufsize);
427 SIOUXselstart += charswaiting;
428
429 text = stdin_buf;
430 while (text = memchr(text, '\r', charswaiting - (text - stdin_buf)))
431 *text = '\n';
432 }
433 #if SIOUX_USE_WASTE
434 HUnlock(textHandle);
435 #endif
436 old_charswaiting = charswaiting;
437
438 if (stdin_buf)
439 break;
440 }
441
442 /* Wait for next event and process it */
443 SIOUXState = SCANFING;
444
445 if(WaitNextEvent(everyEvent, &eventStructure, SIOUXSettings.sleep ,NULL))
446 doEvents(&eventStructure);
447 else
448 SIOUXHandleOneEvent(&eventStructure);
449
450 SIOUXState = IDLE;
451 }
452
453 /* If data has been entered, return as much as has been requested */
454 if (stdin_buf && !gDone)
455 {
456 if (size >= stdin_bufsize - stdin_bufpos)
457 {
458 size = stdin_bufsize - stdin_bufpos;
459 memcpy (ptr, stdin_buf + stdin_bufpos, size);
460 free(stdin_buf);
461 stdin_buf = NULL;
462 stdin_bufpos = 0;
463 stdin_bufsize = 0;
464 }
465 else
466 {
467 memcpy (ptr, stdin_buf + stdin_bufpos, size);
468 stdin_bufpos += size;
469 }
470 return size;
471 }
472 else if (stdin_buf)
473 {
474 free(stdin_buf);
475 stdin_buf = NULL;
476 stdin_bufpos = 0;
477 stdin_bufsize = 0;
478 }
479
480 return 0;
481 }
482
483 /*********************************************************************/
484
window_create(IMAGE * img)485 static void window_create(IMAGE *img)
486 {
487 WindowRef windowRef;
488 Str255 windowTitle = "\pGhostscript Image";
489 Rect windowRect = {20,4,580,420};//, portRect;
490 Rect scrollbarRect = {0,0,0,0};
491
492 #if TARGET_API_MAC_CARBON
493 GetAvailableWindowPositioningBounds(GetMainDevice(),&windowRect);
494 #endif
495
496 /* Create a new suitablty positioned window */
497 windowRect.top = windowRect.top * 2 + 2;
498 windowRect.bottom -= 10;
499 windowRect.left += 4;
500 windowRect.right = ((windowRect.bottom - windowRect.top) * 3) / 4 + windowRect.left;
501
502 if(!(windowRef = NewCWindow(NULL, &windowRect, windowTitle, true,
503 zoomDocProc, (WindowRef) -1, false, 0)))
504 ExitToShell();
505
506 img->windowRef = windowRef;
507
508 SetWRefCon(img->windowRef, (SInt32)img);
509
510 /* Create the window's scrollbars */
511 #if TARGET_API_MAC_CARBON
512 if(gRunningOnX)
513 ChangeWindowAttributes(windowRef,kWindowLiveResizeAttribute,0);
514
515 CreateScrollBarControl(windowRef, &scrollbarRect, 0, 0, 0, 0,
516 true, gActionFunctionScrollUPP, &(img->scrollbarVertRef));
517
518 CreateScrollBarControl(windowRef, &scrollbarRect, 0, 0, 0, 0,
519 true, gActionFunctionScrollUPP, &(img->scrollbarHorizRef));
520 #else
521 img->scrollbarVertRef = NewControl(windowRef,&scrollbarRect,"\p",false,0,0,0,scrollBarProc,0);
522 img->scrollbarHorizRef = NewControl(windowRef,&scrollbarRect,"\p",false,0,0,0,scrollBarProc,0);
523 #endif
524
525 window_adjust_scrollbars(windowRef);
526 }
527
window_invalidate(WindowRef windowRef)528 static void window_invalidate(WindowRef windowRef)
529 {
530 Rect portRect;
531
532 GetWindowPortBounds(windowRef, &portRect);
533 InvalWindowRect(windowRef, &portRect);
534 }
535
window_adjust_scrollbars(WindowRef windowRef)536 static void window_adjust_scrollbars(WindowRef windowRef)
537 {
538 IMAGE *img;
539 Rect portRect;
540
541 img = (IMAGE*)GetWRefCon(windowRef);
542 GetWindowPortBounds(windowRef,&portRect);
543
544 /* Move the crollbars to the edges of the window */
545 HideControl(img->scrollbarVertRef);
546 HideControl(img->scrollbarHorizRef);
547
548 MoveControl(img->scrollbarVertRef,portRect.right - kScrollBarWidth,
549 portRect.top - 1);
550 MoveControl(img->scrollbarHorizRef,portRect.left - 1,
551 portRect.bottom - kScrollBarWidth);
552
553 SizeControl(img->scrollbarVertRef,kScrollBarWidth + 1,
554 portRect.bottom - portRect.top - kScrollBarWidth + 1);
555 SizeControl(img->scrollbarHorizRef, portRect.right - portRect.left - kScrollBarWidth + 1,
556 kScrollBarWidth + 1);
557
558 /* Adjust the scroll position showing */
559 if (img->pixmapHdl)
560 {
561 PixMap *pixmap = *(img->pixmapHdl);
562 int visibleHeight = portRect.bottom - portRect.top - kScrollBarWidth;
563 int visibleWidth = portRect.right - portRect.left - kScrollBarWidth;
564
565 if (pixmap->bounds.bottom > visibleHeight)
566 {
567 SetControl32BitMaximum(img->scrollbarVertRef,
568 pixmap->bounds.bottom - visibleHeight);
569 SetControlViewSize(img->scrollbarVertRef,visibleHeight);
570 }
571 else
572 SetControlMaximum(img->scrollbarVertRef, 0);
573
574 if (pixmap->bounds.right > visibleWidth)
575 {
576 SetControl32BitMaximum(img->scrollbarHorizRef,
577 pixmap->bounds.right - visibleWidth);
578 SetControlViewSize(img->scrollbarHorizRef, visibleWidth);
579 }
580 else
581 SetControlMaximum(img->scrollbarHorizRef, 0);
582 }
583
584 ShowControl(img->scrollbarVertRef);
585 ShowControl(img->scrollbarHorizRef);
586 }
587
588 /*********************************************************************/
main(void)589 void main(void)
590 {
591 int code;
592 int exit_code;
593 int argc;
594 char **argv;
595 char dformat[64], ddevice[32];
596 SInt32 response;
597
598 /* Initialize operating environment */
599 #if TARGET_API_MAC_CARBON
600 MoreMasterPointers(224);
601 #else
602 MoreMasters();
603 #endif
604 InitCursor();
605 FlushEvents(everyEvent,0);
606
607 if (AEInstallEventHandler(kCoreEventClass,kAEQuitApplication,
608 NewAEEventHandlerUPP((AEEventHandlerProcPtr) quitAppEventHandler),
609 0L,false) != noErr)
610 ExitToShell();
611
612 gActionFunctionScrollUPP = NewControlActionUPP(&actionFunctionScroll);
613
614 Gestalt(gestaltMenuMgrAttr,&response);
615 if(response & gestaltMenuMgrAquaLayoutMask)
616 gRunningOnX = true;
617
618 /* Initialize SIOUX */
619 SIOUXSettings.initializeTB = false;
620 SIOUXSettings.standalone = false;
621 SIOUXSettings.asktosaveonclose = false;
622 SIOUXSettings.sleep = GetCaretTime();
623 SIOUXSettings.userwindowtitle = "\pGhostscript";
624
625 /* Get arguments from user */
626 argc = ccommand(&argv);
627
628 /* Show command line window */
629 if (InstallConsole(0))
630 ExitToShell();
631
632 /* Part of fudge to make SIOUX accept characters without becoming modal */
633 SelectWindow(SIOUXTextWindow->window);
634 PostEvent(keyDown, 0x4c00); // Enter
635 ReadCharsFromConsole(dformat, 0x7FFF);
636 clrscr();
637
638 /* Add in the display format as the first command line argument */
639 if (argc >= MAX_ARGS - 1)
640 {
641 printf("Too many command line arguments\n");
642 return;
643 }
644
645 memmove(&argv[3], &argv[1], (argc-1) * sizeof(char**));
646 argc += 2;
647 argv[1] = ddevice;
648 argv[2] = dformat;
649
650 sprintf(ddevice, "-sDEVICE=display");
651 sprintf(dformat, "-dDisplayFormat=%d", display_format);
652
653 /* Run Ghostscript */
654 if (gsapi_new_instance(&instance, NULL) < 0)
655 {
656 printf("Can't create Ghostscript instance\n");
657 return;
658 }
659
660 #ifdef DEBUG
661 visual_tracer_init();
662 set_visual_tracer(&visual_tracer);
663 #endif
664
665 gsapi_set_stdio(instance, gsdll_stdin, gsdll_stdout, gsdll_stderr);
666 gsapi_set_poll(instance, gsdll_poll);
667 gsapi_set_display_callback(instance, &display);
668
669 code = gsapi_init_with_args(instance, argc, argv);
670 if (code == 0)
671 code = gsapi_run_string(instance, start_string, 0, &exit_code);
672 else
673 {
674 printf("Failed to initialize. Error %d.\n", code);
675 fflush(stdout);
676 }
677 code = gsapi_exit(instance);
678 if (code != 0)
679 {
680 printf("Failed to terminate. Error %d.\n", code);
681 fflush(stdout);
682 }
683
684 gsapi_delete_instance(instance);
685
686 #ifdef DEBUG
687 visual_tracer_close();
688 #endif
689
690 /* Ghostscript has finished - let user see output before quitting */
691 WriteCharsToConsole("\r[Finished - hit any key to quit]", 33);
692 fflush(stdout);
693
694 /* Process events until a key is hit or user quits from menu */
695 while(!gDone)
696 {
697 EventRecord eventStructure;
698
699 if(WaitNextEvent(everyEvent,&eventStructure,SIOUXSettings.sleep,NULL))
700 {
701 if (eventStructure.what == keyDown)
702 gDone = true;
703
704 doEvents(&eventStructure);
705 }
706 else
707 SIOUXHandleOneEvent(&eventStructure);
708 }
709 }
710
711 /*********************************************************************/
712
doEvents(EventRecord * eventStrucPtr)713 void doEvents(EventRecord *eventStrucPtr)
714 {
715 WindowRef windowRef;
716
717 if (eventStrucPtr->what == mouseDown &&
718 FindWindow(eventStrucPtr->where,&windowRef) == inMenuBar)
719 SelectWindow(SIOUXTextWindow->window);
720
721 SIOUXSettings.standalone = true;
722 if (SIOUXHandleOneEvent(eventStrucPtr))
723 {
724 if (SIOUXQuitting)
725 gDone = true;
726 SIOUXSettings.standalone = false;
727 return;
728 }
729 SIOUXSettings.standalone = false;
730
731 switch(eventStrucPtr->what)
732 {
733 case kHighLevelEvent:
734 AEProcessAppleEvent(eventStrucPtr);
735 break;
736
737 case mouseDown:
738 doMouseDown(eventStrucPtr);
739 break;
740
741 case keyDown:
742 case autoKey:
743 break;
744
745 case updateEvt:
746 doUpdate(eventStrucPtr);
747 break;
748
749 case activateEvt:
750 DrawGrowIcon(windowRef);
751 break;
752
753 case osEvt:
754 doOSEvent(eventStrucPtr);
755 break;
756 }
757 }
758
doMouseDown(EventRecord * eventStrucPtr)759 void doMouseDown(EventRecord *eventStrucPtr)
760 {
761 WindowRef windowRef;
762 WindowPartCode partCode, zoomPart;
763 BitMap screenBits;
764 Rect constraintRect, mainScreenRect;
765 Point standardStateHeightAndWidth;
766 long newSize;
767
768 partCode = FindWindow(eventStrucPtr->where,&windowRef);
769
770 switch(partCode)
771 {
772 case inMenuBar:
773 break;
774
775 case inContent:
776 if(windowRef != FrontWindow())
777 SelectWindow(windowRef);
778 else
779 doInContent(eventStrucPtr,windowRef);
780 break;
781
782 case inDrag:
783 DragWindow(windowRef,eventStrucPtr->where,NULL);
784 break;
785
786 case inGoAway:
787 break;
788
789 case inGrow:
790 constraintRect.top = 75;
791 constraintRect.left = 250;
792 constraintRect.bottom = constraintRect.right = 32767;
793 newSize = GrowWindow(windowRef,eventStrucPtr->where,&constraintRect);
794 if (newSize != 0)
795 SizeWindow(windowRef,LoWord(newSize),HiWord(newSize),true);
796 window_adjust_scrollbars(windowRef);
797 window_invalidate(windowRef);
798 break;
799
800 case inZoomIn:
801 case inZoomOut:
802 mainScreenRect = GetQDGlobalsScreenBits(&screenBits)->bounds;
803 standardStateHeightAndWidth.v = mainScreenRect.bottom;
804 standardStateHeightAndWidth.h = mainScreenRect.right;
805
806 if(IsWindowInStandardState(windowRef,&standardStateHeightAndWidth,NULL))
807 zoomPart = inZoomIn;
808 else
809 zoomPart = inZoomOut;
810
811 if(TrackBox(windowRef,eventStrucPtr->where,partCode))
812 {
813 ZoomWindowIdeal(windowRef,zoomPart,&standardStateHeightAndWidth);
814 window_adjust_scrollbars(windowRef);
815 }
816 break;
817 }
818 }
819
doUpdate(EventRecord * eventStrucPtr)820 void doUpdate(EventRecord *eventStrucPtr)
821 {
822 WindowRef windowRef;
823
824 windowRef = (WindowRef) eventStrucPtr->message;
825
826 window_adjust_scrollbars(windowRef);
827
828 BeginUpdate(windowRef);
829
830 SetPortWindowPort(windowRef);
831 doUpdateWindow(eventStrucPtr);
832
833 EndUpdate(windowRef);
834 }
835
doUpdateWindow(EventRecord * eventStrucPtr)836 void doUpdateWindow(EventRecord *eventStrucPtr)
837 {
838 IMAGE *img;
839 WindowRef windowRef;
840 Rect srcRect, destRect, fillRect;
841 PixMapHandle srcPixmapHdl, destPixmapHdl;
842 RGBColor grayColour = { 0xC000,0xC000,0xC000 };
843 SInt32 hScroll, vScroll;
844
845 windowRef = (WindowRef) eventStrucPtr->message;
846 img = (IMAGE*)GetWRefCon(windowRef);
847 srcPixmapHdl = img->pixmapHdl;
848 destPixmapHdl = GetPortPixMap(GetWindowPort(windowRef));
849 hScroll = GetControl32BitValue(img->scrollbarHorizRef);
850 vScroll = GetControl32BitValue(img->scrollbarVertRef);
851
852 if (srcPixmapHdl)
853 {
854 PixMap *pixmap = *srcPixmapHdl;
855 PixPatHandle hdlPixPat = NewPixPat();
856 MakeRGBPat(hdlPixPat, &grayColour);
857
858 GetWindowPortBounds(windowRef,&destRect);
859 destRect.right -= kScrollBarWidth;
860 destRect.bottom -= kScrollBarWidth;
861
862 if (destRect.right > pixmap->bounds.right)
863 {
864 fillRect.top = destRect.top;
865 fillRect.bottom = destRect.bottom;
866 fillRect.left = pixmap->bounds.right;
867 fillRect.right = destRect.right;
868 FillCRect(&fillRect, hdlPixPat);
869 destRect.right = pixmap->bounds.right;
870 }
871 if (destRect.bottom > pixmap->bounds.bottom)
872 {
873 fillRect.top = pixmap->bounds.bottom;
874 fillRect.bottom = destRect.bottom;
875 fillRect.left = destRect.left;
876 fillRect.right = destRect.right;
877 FillCRect(&fillRect, hdlPixPat);
878 destRect.bottom = pixmap->bounds.bottom;
879 }
880 DisposePixPat(hdlPixPat);
881
882 srcRect = destRect;
883 srcRect.left += hScroll;
884 srcRect.right += hScroll;
885 srcRect.top += vScroll;
886 srcRect.bottom += vScroll;
887
888 CopyBits((BitMap*)*srcPixmapHdl, (BitMap*)*destPixmapHdl,
889 &srcRect, &destRect, srcCopy, NULL);
890 }
891
892 DrawGrowIcon(windowRef);
893 }
894
doOSEvent(EventRecord * eventStrucPtr)895 void doOSEvent(EventRecord *eventStrucPtr)
896 {
897 switch((eventStrucPtr->message >> 24) & 0x000000FF)
898 {
899 case suspendResumeMessage:
900 if((eventStrucPtr->message & resumeFlag) == 1)
901 SetThemeCursor(kThemeArrowCursor);
902 break;
903 }
904 }
905
doInContent(EventRecord * eventStrucPtr,WindowRef windowRef)906 void doInContent(EventRecord *eventStrucPtr,WindowRef windowRef)
907 {
908 ControlPartCode controlPartCode;
909 ControlRef controlRef;
910
911 SetPortWindowPort(windowRef);
912 GlobalToLocal(&eventStrucPtr->where);
913
914 if(controlRef = FindControlUnderMouse(eventStrucPtr->where,windowRef,&controlPartCode))
915 {
916 #if TARGET_API_MAC_CARBON
917 TrackControl(controlRef,eventStrucPtr->where,(ControlActionUPP) -1);
918 #else
919 if (controlPartCode == kControlIndicatorPart)
920 TrackControl(controlRef,eventStrucPtr->where,NULL);
921 else
922 TrackControl(controlRef,eventStrucPtr->where,gActionFunctionScrollUPP);
923 #endif
924
925 window_invalidate(windowRef);
926 }
927 }
928
actionFunctionScroll(ControlRef controlRef,ControlPartCode controlPartCode)929 pascal void actionFunctionScroll(ControlRef controlRef,ControlPartCode controlPartCode)
930 {
931 SInt32 scrollDistance, controlValue, oldControlValue, controlMax;
932
933 if(controlPartCode != kControlNoPart)
934 {
935 if(controlPartCode != kControlIndicatorPart)
936 {
937 switch(controlPartCode)
938 {
939 case kControlUpButtonPart:
940 case kControlDownButtonPart:
941 scrollDistance = 10;
942 break;
943
944 case kControlPageUpPart:
945 case kControlPageDownPart:
946 scrollDistance = 100;
947 break;
948
949 default:
950 scrollDistance = 0;
951 break;
952 }
953
954 if (scrollDistance)
955 {
956 if((controlPartCode == kControlDownButtonPart) ||
957 (controlPartCode == kControlPageDownPart))
958 scrollDistance = -scrollDistance;
959
960 controlValue = GetControl32BitValue(controlRef);
961
962 if(((controlValue == GetControl32BitMaximum(controlRef)) && scrollDistance < 0) ||
963 ((controlValue == GetControl32BitMinimum(controlRef)) && scrollDistance > 0))
964 return;
965
966 oldControlValue = controlValue;
967 controlMax = GetControl32BitMaximum(controlRef);
968 controlValue = oldControlValue - scrollDistance;
969
970 if(controlValue < 0)
971 controlValue = 0;
972 else if(controlValue > controlMax)
973 controlValue = controlMax;
974
975 SetControl32BitValue(controlRef,controlValue);
976 }
977 }
978 }
979 }
980
quitAppEventHandler(AppleEvent * appEvent,AppleEvent * reply,SInt32 handlerRefcon)981 OSErr quitAppEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefcon)
982 {
983 OSErr osError;
984 DescType returnedType;
985 Size actualSize;
986
987 osError = AEGetAttributePtr(appEvent,keyMissedKeywordAttr,typeWildCard,&returnedType,NULL,0,
988 &actualSize);
989
990 if(osError == errAEDescNotFound)
991 {
992 gDone = true;
993 osError = noErr;
994 }
995 else if(osError == noErr)
996 osError = errAEParamMissed;
997
998 return osError;
999 }
1000
1001 /*********************************************************************/
1002
1003