/* * tkMacHLEvents.c -- * * Implements high level event support for the Macintosh. Currently, * the only event that really does anything is the Quit event. * * Copyright (c) 1995-1996 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkMacHLEvents.c 1.15 96/09/05 11:21:33 */ #include "tcl.h" #include "tclMacInt.h" #include "tkMacInt.h" #include #include #include #include static pascal OSErr QuitHandler _ANSI_ARGS_((AppleEvent* event, AppleEvent* reply, long refcon)); static pascal OSErr OappHandler _ANSI_ARGS_((AppleEvent* event, AppleEvent* reply, long refcon)); static pascal OSErr OdocHandler _ANSI_ARGS_((AppleEvent* event, AppleEvent* reply, long refcon)); static pascal OSErr PrintHandler _ANSI_ARGS_((AppleEvent* event, AppleEvent* reply, long refcon)); static pascal OSErr ScriptHandler _ANSI_ARGS_((AppleEvent* event, AppleEvent* reply, long refcon)); static int MissedAnyParameters _ANSI_ARGS_((AppleEvent *theEvent)); /* *---------------------------------------------------------------------- * * TkMacInitAppleEvents -- * * Initilize the Apple Events on the Macintosh. This registers the * core event handlers. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TkMacInitAppleEvents(interp) Tcl_Interp *interp; { OSErr err; AEEventHandlerUPP OappHandlerUPP, OdocHandlerUPP, PrintHandlerUPP, QuitHandlerUPP, ScriptHandlerUPP; /* Install event handlers for the core apple events. */ QuitHandlerUPP = NewAEEventHandlerProc(QuitHandler); err = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, QuitHandlerUPP, (long) interp, false); OappHandlerUPP = NewAEEventHandlerProc(OappHandler); err = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, OappHandlerUPP, (long) interp, false); OdocHandlerUPP = NewAEEventHandlerProc(OdocHandler); err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, OdocHandlerUPP, (long) interp, false); PrintHandlerUPP = NewAEEventHandlerProc(PrintHandler); err = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, PrintHandlerUPP, (long) interp, false); if (interp != NULL) { ScriptHandlerUPP = NewAEEventHandlerProc(ScriptHandler); err = AEInstallEventHandler('misc', 'dosc', ScriptHandlerUPP, (long) interp, false); } } /* *---------------------------------------------------------------------- * * TkMacDoHLEvent -- * * Dispatch incomming highlevel events. * * Results: * None. * * Side effects: * Depends on the incoming event. * *---------------------------------------------------------------------- */ void TkMacDoHLEvent(theEvent) EventRecord *theEvent; { AEProcessAppleEvent(theEvent); return; } /* *---------------------------------------------------------------------- * * QuitHandler, OappHandler, etc. -- * * These are the core Apple event handlers. Only the Quit event does * anything interesting. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static pascal OSErr QuitHandler(theAppleEvent, reply, handlerRefcon) AppleEvent *theAppleEvent; AppleEvent *reply; long handlerRefcon; { Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon; /* * Call the exit command. However, if it doesn't quit - quit anyway. */ if (interp != NULL) { Tcl_GlobalEval(interp, "exit"); } Tcl_Exit(0); return noErr; } static pascal OSErr OappHandler(theAppleEvent, reply, handlerRefcon) AppleEvent *theAppleEvent; AppleEvent *reply; long handlerRefcon; { return noErr; } static pascal OSErr OdocHandler(theAppleEvent, reply, handlerRefcon) AppleEvent *theAppleEvent; AppleEvent *reply; long handlerRefcon; { Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon; AEDescList fileSpecList; FSSpec file; OSErr err; DescType type; Size actual; long count; AEKeyword keyword; long index; Tcl_DString command; Tcl_DString pathName; Tcl_CmdInfo dummy; /* * Don't bother if we don't have an interp or * the open document procedure doesn't exist. */ if ((interp == NULL) || (Tcl_GetCommandInfo(interp, "tkOpenDocument", &dummy)) == 0) { return noErr; } /* * If we get any errors wil retrieving our parameters * we just return with no error. */ err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &fileSpecList); if (err != noErr) { return noErr; } err = MissedAnyParameters(theAppleEvent); if (err != noErr) { return noErr; } err = AECountItems(&fileSpecList, &count); if (err != noErr) { return noErr; } Tcl_DStringInit(&command); Tcl_DStringInit(&pathName); Tcl_DStringAppend(&command, "tkOpenDocument", -1); for (index = 1; index <= count; index++) { int length; Handle fullPath; Tcl_DStringSetLength(&pathName, 0); err = AEGetNthPtr(&fileSpecList, index, typeFSS, &keyword, &type, (Ptr) &file, sizeof(FSSpec), &actual); if ( err != noErr ) { continue; } err = FSpPathFromLocation(&file, &length, &fullPath); HLock(fullPath); Tcl_DStringAppend(&pathName, *fullPath, length); HUnlock(fullPath); DisposeHandle(fullPath); Tcl_DStringAppendElement(&command, pathName.string); } Tcl_GlobalEval(interp, command.string); Tcl_DStringFree(&command); Tcl_DStringFree(&pathName); return noErr; } static pascal OSErr PrintHandler(theAppleEvent, reply, handlerRefcon) AppleEvent *theAppleEvent; AppleEvent *reply; long handlerRefcon; { return noErr; } /* *---------------------------------------------------------------------- * * DoScriptHandler -- * * This handler process the do script event. * * Results: * Scedules the given event to be processed. * * Side effects: * None. * *---------------------------------------------------------------------- */ static pascal OSErr ScriptHandler(theAppleEvent, reply, handlerRefcon) AppleEvent *theAppleEvent; AppleEvent *reply; long handlerRefcon; { OSErr theErr; AEDescList theDesc; int tclErr = -1; Tcl_Interp *interp; char errString[128]; interp = (Tcl_Interp *) handlerRefcon; /* * The do script event receives one parameter that should be data or a file. */ theErr = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &theDesc); if (theErr != noErr) { sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d", theErr); theErr = AEPutParamPtr(reply, keyErrorString, typeChar, errString, strlen(errString)); } else if (MissedAnyParameters(theAppleEvent)) { sprintf(errString, "AEDoScriptHandler: extra parameters"); AEPutParamPtr(reply, keyErrorString, typeChar, errString, strlen(errString)); theErr = -1771; } else { if (theDesc.descriptorType == (DescType)'TEXT') { short length; length = GetHandleSize(theDesc.dataHandle); SetHandleSize(theDesc.dataHandle, length + 1); *(*theDesc.dataHandle + length) = '\0'; HLock(theDesc.dataHandle); tclErr = Tcl_GlobalEval(interp, *theDesc.dataHandle); HUnlock(theDesc.dataHandle); } else if (theDesc.descriptorType == (DescType)'alis') { Boolean dummy; FSSpec theFSS; Handle fullPath; int length; theErr = ResolveAlias(NULL, (AliasHandle)theDesc.dataHandle, &theFSS, &dummy); if (theErr == noErr) { FSpPathFromLocation(&theFSS, &length, &fullPath); HLock(fullPath); Tcl_EvalFile(interp, *fullPath); HUnlock(fullPath); DisposeHandle(fullPath); } else { sprintf(errString, "AEDoScriptHandler: file not found"); AEPutParamPtr(reply, keyErrorString, typeChar, errString, strlen(errString)); } } else { sprintf(errString, "AEDoScriptHandler: invalid script type '%-4.4s', must be 'alis' or 'TEXT'", &theDesc.descriptorType); AEPutParamPtr(reply, keyErrorString, typeChar, errString, strlen(errString)); theErr = -1770; } } /* * If we actually go to run Tcl code - put the result in the reply. */ if (tclErr >= 0) { if (tclErr == TCL_OK) { AEPutParamPtr(reply, keyDirectObject, typeChar, interp->result, strlen(interp->result)); } else { AEPutParamPtr(reply, keyErrorString, typeChar, interp->result, strlen(interp->result)); AEPutParamPtr(reply, keyErrorNumber, typeInteger, (Ptr) &tclErr, sizeof(int)); } } AEDisposeDesc(&theDesc); return theErr; } /* *---------------------------------------------------------------------- * * MissedAnyParameters -- * * Checks to see if parameters are still left in the event. * * Results: * True or false. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int MissedAnyParameters(theEvent) AppleEvent *theEvent; { DescType returnedType; Size actualSize; OSErr err; err = AEGetAttributePtr(theEvent, keyMissedKeywordAttr, typeWildCard, &returnedType, NULL, 0, &actualSize); return (err != errAEDescNotFound); }