~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to src/dmmain.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

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