1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
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.
13
/* $Id: dmmain.c 8022 2007-06-05 22:23:38Z giles $ */
15
/* Ghostscript shlib example wrapper for Macintosh (Classic/Carbon) contributed
16
by Nigel Hathaway. Uses the Metrowerks CodeWarrior SIOUX command-line library.
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
32
#include <SIOUXGlobals.h>
33
#include <SIOUXMenus.h>
36
#define GSREVISION gs_revision
46
#define kScrollBarWidth 15
49
Boolean gRunningOnX = false;
51
ControlActionUPP gActionFunctionScrollUPP;
53
const char start_string[] = "systemdict /start get exec\n";
56
const unsigned int display_format = DISPLAY_COLORS_RGB | DISPLAY_UNUSED_FIRST |
57
DISPLAY_DEPTH_8 | DISPLAY_BIGENDIAN |
59
typedef struct IMAGE_S IMAGE;
64
ControlRef scrollbarVertRef;
65
ControlRef scrollbarHorizRef;
66
PixMapHandle pixmapHdl;
74
static IMAGE *image_find(void *handle, void *device);
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);
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);
93
static size_t get_input(void *ptr, size_t size);
95
static void window_create (IMAGE *img);
96
static void window_invalidate (WindowRef windowRef);
97
static void window_adjust_scrollbars (WindowRef windowRef);
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);
109
/*********************************************************************/
110
/* stdio functions */
112
gsdll_stdin(void *instance, char *buf, int len)
114
if (isatty(fileno(stdin)))
115
return get_input(buf, len);
117
return fread(buf, 1, len, stdin);
121
gsdll_stdout(void *instance, const char *str, int len)
123
int n = fwrite(str, 1, len, stdout);
129
gsdll_stderr(void *instance, const char *str, int len)
131
return gsdll_stdout(instance, str, len);
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)
138
EventRecord eventStructure;
140
while (WaitNextEvent(everyEvent, &eventStructure, 0, NULL))
141
doEvents(&eventStructure);
143
return (gDone ? e_Fatal : 0);
145
/*********************************************************************/
147
/* new dll display device */
149
/* New device has been opened */
150
/* This is the first event from this device. */
151
static int display_open(void *handle, void *device)
153
IMAGE *img = (IMAGE *)malloc(sizeof(IMAGE));
156
memset(img, 0, sizeof(IMAGE));
160
img->next = first_image;
163
/* remember device and handle */
164
img->handle = handle;
165
img->device = device;
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)
178
/* do nothing - no thread synchonisation needed */
182
/* Device has been closed. */
183
/* This is the last event from this device. */
184
static int display_close(void *handle, void *device)
186
IMAGE *img = image_find(handle, device);
192
/* remove from list */
193
if (img == first_image)
194
first_image = img->next;
198
for (tmp = first_image; tmp!=0; tmp=tmp->next)
200
if (img == tmp->next)
201
tmp->next = img->next;
205
DisposePixMap(img->pixmapHdl); // need to go in doCloseWindow()
206
DisposeWindow(img->windowRef);
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)
218
/* Check for correct format (32-bit RGB), fatal error if not */
219
if (format != display_format)
221
printf("DisplayFormat has been set to an incompatible value.\n");
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)
235
IMAGE *img = image_find(handle, device);
239
/* Check that image is within allowable bounds */
242
printf("QuickDraw can't cope with an image this big.\n");
246
DisposePixMap(img->pixmapHdl);
247
img->pixmapHdl = NULL;
252
/* Create the PixMap */
254
img->pixmapHdl = NewPixMap();
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;
268
/* Update the display window */
269
window_adjust_scrollbars(img->windowRef);
270
window_invalidate(img->windowRef);
271
return gsdll_poll(handle);
275
static int display_sync(void *handle, void *device)
277
IMAGE *img = image_find(handle, device);
281
window_invalidate(img->windowRef);
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)
291
return display_sync(handle, device);
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)
302
IMAGE *img = image_find(handle, device);
306
Microseconds((UnsignedWide*)&t1);
307
delta = (t1 - img->update_time) / 1000000L;
308
if (img->update_interval < 1)
309
img->update_interval = 1; /* seconds */
311
img->update_time = t1;
312
else if (delta > img->update_interval)
315
window_invalidate(img->windowRef);
317
/* Make sure the update interval is at least 10 times
318
* what it takes to paint the window
320
Microseconds((UnsignedWide*)&t2);
321
delta = (t2 - t1) / 1000;
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;
329
return gsdll_poll(handle);
332
display_callback display = {
333
sizeof(display_callback),
334
DISPLAY_VERSION_MAJOR,
335
DISPLAY_VERSION_MINOR,
346
NULL /* display_separation */
349
static IMAGE * image_find(void *handle, void *device)
352
for (img = first_image; img!=0; img=img->next) {
353
if ((img->handle == handle) && (img->device == device))
359
/*********************************************************************/
361
static char *stdin_buf = NULL;
362
static size_t stdin_bufpos = 0;
363
static size_t stdin_bufsize = 0;
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.
374
static size_t get_input(void *ptr, size_t size)
376
EventRecord eventStructure;
377
long charswaiting, old_charswaiting = 0;
384
/* If needing more input, set edit start position */
387
SIOUXselstart = WEGetTextLength(SIOUXTextWindow->edit);
389
SIOUXselstart = (*SIOUXTextWindow->edit)->teLength;
392
/* Wait until user presses exit (or quits) */
393
while(!gDone && !stdin_buf)
396
charswaiting = WEGetTextLength(SIOUXTextWindow->edit) - SIOUXselstart;
398
if ((*SIOUXTextWindow->edit)->teLength > 0)
399
charswaiting = (*SIOUXTextWindow->edit)->teLength - SIOUXselstart;
401
charswaiting = ((unsigned short) (*SIOUXTextWindow->edit)->teLength) - SIOUXselstart;
404
/* If something has happened, see if we need to do anything */
405
if (charswaiting != old_charswaiting)
408
textHandle = WEGetText(SIOUXTextWindow->edit);
410
text = *textHandle + SIOUXselstart;
412
text = (*(*SIOUXTextWindow->edit)->hText) + SIOUXselstart;
414
/* If user has pressed enter, gather up the buffer ready for returning */
415
if (text[charswaiting-1] == '\r')
417
stdin_buf = malloc(charswaiting);
420
stdin_bufsize = charswaiting;
421
memcpy(stdin_buf, text, stdin_bufsize);
422
SIOUXselstart += charswaiting;
425
while (text = memchr(text, '\r', charswaiting - (text - stdin_buf)))
431
old_charswaiting = charswaiting;
437
/* Wait for next event and process it */
438
SIOUXState = SCANFING;
440
if(WaitNextEvent(everyEvent, &eventStructure, SIOUXSettings.sleep ,NULL))
441
doEvents(&eventStructure);
443
SIOUXHandleOneEvent(&eventStructure);
448
/* If data has been entered, return as much as has been requested */
449
if (stdin_buf && !gDone)
451
if (size >= stdin_bufsize - stdin_bufpos)
453
size = stdin_bufsize - stdin_bufpos;
454
memcpy (ptr, stdin_buf + stdin_bufpos, size);
462
memcpy (ptr, stdin_buf + stdin_bufpos, size);
463
stdin_bufpos += size;
478
/*********************************************************************/
480
static void window_create(IMAGE *img)
483
Str255 windowTitle = "\pGhostscript Image";
484
Rect windowRect = {20,4,580,420};//, portRect;
485
Rect scrollbarRect = {0,0,0,0};
487
#if TARGET_API_MAC_CARBON
488
GetAvailableWindowPositioningBounds(GetMainDevice(),&windowRect);
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;
497
if(!(windowRef = NewCWindow(NULL, &windowRect, windowTitle, true,
498
zoomDocProc, (WindowRef) -1, false, 0)))
501
img->windowRef = windowRef;
503
SetWRefCon(img->windowRef, (SInt32)img);
505
/* Create the window's scrollbars */
506
#if TARGET_API_MAC_CARBON
508
ChangeWindowAttributes(windowRef,kWindowLiveResizeAttribute,0);
510
CreateScrollBarControl(windowRef, &scrollbarRect, 0, 0, 0, 0,
511
true, gActionFunctionScrollUPP, &(img->scrollbarVertRef));
513
CreateScrollBarControl(windowRef, &scrollbarRect, 0, 0, 0, 0,
514
true, gActionFunctionScrollUPP, &(img->scrollbarHorizRef));
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);
520
window_adjust_scrollbars(windowRef);
523
static void window_invalidate(WindowRef windowRef)
527
GetWindowPortBounds(windowRef, &portRect);
528
InvalWindowRect(windowRef, &portRect);
531
static void window_adjust_scrollbars(WindowRef windowRef)
536
img = (IMAGE*)GetWRefCon(windowRef);
537
GetWindowPortBounds(windowRef,&portRect);
539
/* Move the crollbars to the edges of the window */
540
HideControl(img->scrollbarVertRef);
541
HideControl(img->scrollbarHorizRef);
543
MoveControl(img->scrollbarVertRef,portRect.right - kScrollBarWidth,
545
MoveControl(img->scrollbarHorizRef,portRect.left - 1,
546
portRect.bottom - kScrollBarWidth);
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);
553
/* Adjust the scroll position showing */
556
PixMap *pixmap = *(img->pixmapHdl);
557
int visibleHeight = portRect.bottom - portRect.top - kScrollBarWidth;
558
int visibleWidth = portRect.right - portRect.left - kScrollBarWidth;
560
if (pixmap->bounds.bottom > visibleHeight)
562
SetControl32BitMaximum(img->scrollbarVertRef,
563
pixmap->bounds.bottom - visibleHeight);
564
SetControlViewSize(img->scrollbarVertRef,visibleHeight);
567
SetControlMaximum(img->scrollbarVertRef, 0);
569
if (pixmap->bounds.right > visibleWidth)
571
SetControl32BitMaximum(img->scrollbarHorizRef,
572
pixmap->bounds.right - visibleWidth);
573
SetControlViewSize(img->scrollbarHorizRef, visibleWidth);
576
SetControlMaximum(img->scrollbarHorizRef, 0);
579
ShowControl(img->scrollbarVertRef);
580
ShowControl(img->scrollbarHorizRef);
583
/*********************************************************************/
590
char dformat[64], ddevice[32];
593
/* Initialize operating environment */
594
#if TARGET_API_MAC_CARBON
595
MoreMasterPointers(224);
600
FlushEvents(everyEvent,0);
602
if (AEInstallEventHandler(kCoreEventClass,kAEQuitApplication,
603
NewAEEventHandlerUPP((AEEventHandlerProcPtr) quitAppEventHandler),
607
gActionFunctionScrollUPP = NewControlActionUPP(&actionFunctionScroll);
609
Gestalt(gestaltMenuMgrAttr,&response);
610
if(response & gestaltMenuMgrAquaLayoutMask)
613
/* Initialize SIOUX */
614
SIOUXSettings.initializeTB = false;
615
SIOUXSettings.standalone = false;
616
SIOUXSettings.asktosaveonclose = false;
617
SIOUXSettings.sleep = GetCaretTime();
618
SIOUXSettings.userwindowtitle = "\pGhostscript";
620
/* Get arguments from user */
621
argc = ccommand(&argv);
623
/* Show command line window */
624
if (InstallConsole(0))
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);
633
/* Add in the display format as the first command line argument */
634
if (argc >= MAX_ARGS - 1)
636
printf("Too many command line arguments\n");
640
memmove(&argv[3], &argv[1], (argc-1) * sizeof(char**));
645
sprintf(ddevice, "-sDEVICE=display");
646
sprintf(dformat, "-dDisplayFormat=%d", display_format);
648
/* Run Ghostscript */
649
if (gsapi_new_instance(&instance, NULL) < 0)
651
printf("Can't create Ghostscript instance\n");
656
visual_tracer_init();
657
set_visual_tracer(&visual_tracer);
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);
664
code = gsapi_init_with_args(instance, argc, argv);
666
code = gsapi_run_string(instance, start_string, 0, &exit_code);
669
printf("Failed to initialize. Error %d.\n", code);
672
code = gsapi_exit(instance);
675
printf("Failed to terminate. Error %d.\n", code);
679
gsapi_delete_instance(instance);
682
visual_tracer_close();
685
/* Ghostscript has finished - let user see output before quitting */
686
WriteCharsToConsole("\r[Finished - hit any key to quit]", 33);
689
/* Process events until a key is hit or user quits from menu */
692
EventRecord eventStructure;
694
if(WaitNextEvent(everyEvent,&eventStructure,SIOUXSettings.sleep,NULL))
696
if (eventStructure.what == keyDown)
699
doEvents(&eventStructure);
702
SIOUXHandleOneEvent(&eventStructure);
706
/*********************************************************************/
708
void doEvents(EventRecord *eventStrucPtr)
712
if (eventStrucPtr->what == mouseDown &&
713
FindWindow(eventStrucPtr->where,&windowRef) == inMenuBar)
714
SelectWindow(SIOUXTextWindow->window);
716
SIOUXSettings.standalone = true;
717
if (SIOUXHandleOneEvent(eventStrucPtr))
721
SIOUXSettings.standalone = false;
724
SIOUXSettings.standalone = false;
726
switch(eventStrucPtr->what)
728
case kHighLevelEvent:
729
AEProcessAppleEvent(eventStrucPtr);
733
doMouseDown(eventStrucPtr);
741
doUpdate(eventStrucPtr);
745
DrawGrowIcon(windowRef);
749
doOSEvent(eventStrucPtr);
754
void doMouseDown(EventRecord *eventStrucPtr)
757
WindowPartCode partCode, zoomPart;
759
Rect constraintRect, mainScreenRect;
760
Point standardStateHeightAndWidth;
763
partCode = FindWindow(eventStrucPtr->where,&windowRef);
771
if(windowRef != FrontWindow())
772
SelectWindow(windowRef);
774
doInContent(eventStrucPtr,windowRef);
778
DragWindow(windowRef,eventStrucPtr->where,NULL);
785
constraintRect.top = 75;
786
constraintRect.left = 250;
787
constraintRect.bottom = constraintRect.right = 32767;
788
newSize = GrowWindow(windowRef,eventStrucPtr->where,&constraintRect);
790
SizeWindow(windowRef,LoWord(newSize),HiWord(newSize),true);
791
window_adjust_scrollbars(windowRef);
792
window_invalidate(windowRef);
797
mainScreenRect = GetQDGlobalsScreenBits(&screenBits)->bounds;
798
standardStateHeightAndWidth.v = mainScreenRect.bottom;
799
standardStateHeightAndWidth.h = mainScreenRect.right;
801
if(IsWindowInStandardState(windowRef,&standardStateHeightAndWidth,NULL))
804
zoomPart = inZoomOut;
806
if(TrackBox(windowRef,eventStrucPtr->where,partCode))
808
ZoomWindowIdeal(windowRef,zoomPart,&standardStateHeightAndWidth);
809
window_adjust_scrollbars(windowRef);
815
void doUpdate(EventRecord *eventStrucPtr)
819
windowRef = (WindowRef) eventStrucPtr->message;
821
window_adjust_scrollbars(windowRef);
823
BeginUpdate(windowRef);
825
SetPortWindowPort(windowRef);
826
doUpdateWindow(eventStrucPtr);
828
EndUpdate(windowRef);
831
void doUpdateWindow(EventRecord *eventStrucPtr)
835
Rect srcRect, destRect, fillRect;
836
PixMapHandle srcPixmapHdl, destPixmapHdl;
837
RGBColor grayColour = { 0xC000,0xC000,0xC000 };
838
SInt32 hScroll, vScroll;
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);
849
PixMap *pixmap = *srcPixmapHdl;
850
PixPatHandle hdlPixPat = NewPixPat();
851
MakeRGBPat(hdlPixPat, &grayColour);
853
GetWindowPortBounds(windowRef,&destRect);
854
destRect.right -= kScrollBarWidth;
855
destRect.bottom -= kScrollBarWidth;
857
if (destRect.right > pixmap->bounds.right)
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;
866
if (destRect.bottom > pixmap->bounds.bottom)
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;
875
DisposePixPat(hdlPixPat);
878
srcRect.left += hScroll;
879
srcRect.right += hScroll;
880
srcRect.top += vScroll;
881
srcRect.bottom += vScroll;
883
CopyBits((BitMap*)*srcPixmapHdl, (BitMap*)*destPixmapHdl,
884
&srcRect, &destRect, srcCopy, NULL);
887
DrawGrowIcon(windowRef);
890
void doOSEvent(EventRecord *eventStrucPtr)
892
switch((eventStrucPtr->message >> 24) & 0x000000FF)
894
case suspendResumeMessage:
895
if((eventStrucPtr->message & resumeFlag) == 1)
896
SetThemeCursor(kThemeArrowCursor);
901
void doInContent(EventRecord *eventStrucPtr,WindowRef windowRef)
903
ControlPartCode controlPartCode;
904
ControlRef controlRef;
906
SetPortWindowPort(windowRef);
907
GlobalToLocal(&eventStrucPtr->where);
909
if(controlRef = FindControlUnderMouse(eventStrucPtr->where,windowRef,&controlPartCode))
911
#if TARGET_API_MAC_CARBON
912
TrackControl(controlRef,eventStrucPtr->where,(ControlActionUPP) -1);
914
if (controlPartCode == kControlIndicatorPart)
915
TrackControl(controlRef,eventStrucPtr->where,NULL);
917
TrackControl(controlRef,eventStrucPtr->where,gActionFunctionScrollUPP);
920
window_invalidate(windowRef);
924
pascal void actionFunctionScroll(ControlRef controlRef,ControlPartCode controlPartCode)
926
SInt32 scrollDistance, controlValue, oldControlValue, controlMax;
928
if(controlPartCode != kControlNoPart)
930
if(controlPartCode != kControlIndicatorPart)
932
switch(controlPartCode)
934
case kControlUpButtonPart:
935
case kControlDownButtonPart:
939
case kControlPageUpPart:
940
case kControlPageDownPart:
941
scrollDistance = 100;
951
if((controlPartCode == kControlDownButtonPart) ||
952
(controlPartCode == kControlPageDownPart))
953
scrollDistance = -scrollDistance;
955
controlValue = GetControl32BitValue(controlRef);
957
if(((controlValue == GetControl32BitMaximum(controlRef)) && scrollDistance < 0) ||
958
((controlValue == GetControl32BitMinimum(controlRef)) && scrollDistance > 0))
961
oldControlValue = controlValue;
962
controlMax = GetControl32BitMaximum(controlRef);
963
controlValue = oldControlValue - scrollDistance;
967
else if(controlValue > controlMax)
968
controlValue = controlMax;
970
SetControl32BitValue(controlRef,controlValue);
976
OSErr quitAppEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefcon)
979
DescType returnedType;
982
osError = AEGetAttributePtr(appEvent,keyMissedKeywordAttr,typeWildCard,&returnedType,NULL,0,
985
if(osError == errAEDescNotFound)
990
else if(osError == noErr)
991
osError = errAEParamMissed;
996
/*********************************************************************/