Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
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
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
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 */
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. */
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. */
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. */
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. */
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 */
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 */
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 */
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 */
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
 
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
*/
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
 
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
 
528
static void window_invalidate(WindowRef windowRef)
529
{
530
    Rect portRect;
531
 
532
    GetWindowPortBounds(windowRef, &portRect);
533
    InvalWindowRect(windowRef, &portRect);
534
}
535
 
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
/*********************************************************************/
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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
 
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