archie/tk4.2/mac/tkMacHLEvents.c
2024-05-27 16:40:40 +02:00

375 lines
9.2 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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 <Aliases.h>
#include <AppleEvents.h>
#include <SegLoad.h>
#include <ToolUtils.h>
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);
}