static PyObject *AEDesc_AEPutParamPtr(AEDescObject *_self, PyObject *_args) { PyObject *_res = NULL; OSErr _err; AEKeyword theAEKeyword; DescType typeCode; char *dataPtr__in__; long dataPtr__len__; int dataPtr__in_len__; #ifndef AEPutParamPtr PyMac_PRECHECK(AEPutParamPtr); #endif if (!PyArg_ParseTuple(_args, "O&O&s#", PyMac_GetOSType, &theAEKeyword, PyMac_GetOSType, &typeCode, &dataPtr__in__, &dataPtr__in_len__)) return NULL; dataPtr__len__ = dataPtr__in_len__; _err = AEPutParamPtr(&_self->ob_itself, theAEKeyword, typeCode, dataPtr__in__, dataPtr__len__); if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); _res = Py_None; return _res; }
/******************************************************************************** Add a parameter of type typeAlias to an AERecord (or AppleEvent) using the provided FSRef. pFSRef input: Pointer to the FSRef to use. pKeyword input: The key for the data to be added to the record. pAERecord input: Pointer to the record (or event) to add the data to. RESULT CODES ____________ noErr 0 No error paramErr -50 The value of target or alias parameter, or of both, is NIL, or the alias record is corrupt memFullErr -108 Not enough room in heap zone */ pascal OSErr MoreAEOAddAliasParameterFromFSRef(const FSRefPtr pFSRef, const DescType pKeyword, AERecord *pAERecord ) { OSErr anErr = noErr; AliasHandle tAliasHandle; anErr = FSNewAlias( NULL, pFSRef, &tAliasHandle); if ( noErr == anErr && tAliasHandle == NULL ) { anErr = paramErr; } if ( noErr == anErr ) { char handleState; handleState = HGetState((Handle) tAliasHandle ); HLock((Handle) tAliasHandle ); anErr = AEPutParamPtr( pAERecord, pKeyword, typeAlias, *tAliasHandle, (*tAliasHandle)->aliasSize); HSetState( (Handle)tAliasHandle, handleState ); DisposeHandle( (Handle)tAliasHandle ); } return anErr; }//end MoreAEOAddAliasParameterFromFSRef
/*---------------------------------------------------------------------------- HandleCount ----------------------------------------------------------------------------*/ void AEGenericClass::HandleCount(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply) { ConstAETokenDesc tokenDesc(token); long numberOfObjects = 0; DescType objectClass; OSErr err = noErr; if (!reply->dataHandle) return; // Get the class of object that we will count err = GetObjectClassFromAppleEvent(appleEvent, &objectClass); ThrowIfOSErr(err); err = CheckForUnusedParameters(appleEvent); ThrowIfOSErr(err); if (AEListUtils::TokenContainsTokenList(token)) { err = AECountItems(token, &numberOfObjects); ThrowIfOSErr(err); } else { CountObjects(objectClass, tokenDesc.GetDispatchClass(), token, &numberOfObjects); } err = AEPutParamPtr(reply, keyAEResult, typeLongInteger, (Ptr)&numberOfObjects, sizeof(long)); ThrowIfOSErr(err); }
OSErr BigSendAppleEvent(TargetID *targ,AEEventClass aeClass,AEEventID aeID,Ptr *data,short dataLen,DescType dataType,Boolean returnData,Boolean checkForHandlerErr) { AEAddressDesc targDesc={typeNull, nil}; // Desc for target AppleEvent appOut={typeNull, nil},appIn={typeNull, nil}; short sendMode=kAENeverInteract; OSErr err; if (returnData || checkForHandlerErr) sendMode+=kAEWaitReply; else sendMode+=kAENoReply; // Create the address desriptor err=AECreateDesc(typeTargetID,(Ptr)targ,sizeof(TargetID), &targDesc); if (err) return err; // now create the apple event which will be sent err=AECreateAppleEvent(aeClass,aeID,&targDesc,kAutoGenerateReturnID,kAnyTransactionID,&appOut); if (err) { AEDisposeDesc(&targDesc); return err; } if (data && *data) { err=AEPutParamPtr(&appOut,keyDirectObject,typeChar,*data,dataLen); DisposePtr(*data); *data=0L; if (err) { AEDisposeDesc(&appOut); AEDisposeDesc(&targDesc); } } // Send the apple event err=AESend(&appOut,&appIn,sendMode,kAENormalPriority,kAEDefaultTimeout,0L,0L); if (err) { AEDisposeDesc(&appOut); // get rid of the apple events AEDisposeDesc(&appIn); AEDisposeDesc(&targDesc); // and the address descriptor } if (returnData) // get info from reply event err=FetchParamAnySize(keyDirectObject,&appIn,data,dataType); // Get the error returned if any if (!err && checkForHandlerErr) err=FetchAEErr(&appIn); // The apple event has been sent, dispose of descriptors AEDisposeDesc(&appOut); // get rid of the apple events AEDisposeDesc(&appIn); AEDisposeDesc(&targDesc); // and the address descriptor return err; }
/*---------------------------------------------------------------------------- HandleExists If <anObject> exists... The AEResolve() function in AERCoreSuite.c will already have filtered out all cases where the object did not exist, so this function should always return TRUE. ----------------------------------------------------------------------------*/ void AEGenericClass::HandleExists(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply) { OSErr err; Boolean foundIt = true; err = AEPutParamPtr(reply, keyAEResult, typeBoolean, (Ptr)&foundIt, sizeof(Boolean)); ThrowIfOSErr(err); }
static void AttachErrorCode(AppleEvent *event,OSStatus err) { OSStatus returnVal; if ( event==NULL ) return; if (event->descriptorType != typeNull) { /* Check there isn't already an error attached */ returnVal = AESizeOfParam(event, keyErrorNumber, NULL, NULL); if (returnVal != noErr ) { /* Add success if no previous error */ AEPutParamPtr(event, keyErrorNumber, typeSInt32, &err, sizeof(err)); } } }
// ResendLastTabletEventofType // // This function will instruct the Tablet Driver to resend either the last // posted proximity event, or pointer event. // // parameters: DescType tabletEventType - eEventProximity, eEventPointer // // returns: noErr on success, else an AE error code ////////////////////////////////////////////////////////////////////////////// OSErr ResendLastTabletEventofType(DescType tabletEventType) { AEDesc driverTarget; AppleEvent aeSend; OSErr err; err = GetTabletDriverTarget(&driverTarget); if(err) { AEDisposeDesc(&driverTarget); return err; } err = AECreateAppleEvent(kAEWacomSuite, // Create a special Wacom Event eSendTabletEvent, // Send Last Tablet Event &driverTarget, kAutoGenerateReturnID, kAnyTransactionID, &aeSend); if(err) { AEDisposeDesc(&driverTarget); return err; } err = AEPutParamPtr ( &aeSend, keyAEData, typeEnumeration, &tabletEventType, sizeof(tabletEventType)); // Add what type of event to send if(err) { AEDisposeDesc(&driverTarget); return err; } // Finally send the event err = AESend(&aeSend, // The complete AE we created above NULL, kAEWaitReply, kAEHighPriority, kDefaultTimeOut, NULL, NULL); AEDisposeDesc(&aeSend);
SOM_Scope void SOMLINK ODLinkSpecWriteToOSAEvent(ODLinkSpec *somSelf, Environment *ev, OSAEvent* theOSAEvent) #endif { ODLinkSpecData *somThis = ODLinkSpecGetData(somSelf); ODLinkSpecMethodDebug("ODLinkSpec","WriteToAppleEvent"); #ifdef _PLATFORM_OS2_ // CED _interrupt(3); #endif #ifdef _PLATFORM_MACINTOSH_ SOM_TRY OSErr error; ODPart* part = somSelf->GetPart(ev); ODByteArray partData = somSelf->GetPartData(ev); ODULong version = kLinkSpecVersion; error = AEPutParamPtr((AppleEvent*) theAppleEvent, kODLinkSpecVersionKey, typeLongInteger, &version, sizeof(version)); if ( error == noErr ) error = AEPutParamPtr((AppleEvent*) theAppleEvent, keyProcessSerialNumber, typeProcessSerialNumber, &_fProcessID, sizeof(_fProcessID)); if ( error == noErr ) error = AEPutParamPtr((AppleEvent*) theAppleEvent, kODProcessLaunchDateKey, typeLongInteger, &_fProcessLaunchDate, sizeof(_fProcessLaunchDate)); if ( error == noErr ) error = AEPutParamPtr((AppleEvent*) theAppleEvent, kODSourcePartKey, typeLongInteger, &part, sizeof(part)); if ( error == noErr ) error = AEPutParamPtr((AppleEvent*) theAppleEvent, kODLinkSpecDataSizeKey, typeLongInteger, &partData._length, sizeof(ODULong)); if ( (error == noErr) && (partData._length > 0) ) error = AEPutParamPtr((AppleEvent*) theAppleEvent, kODLinkSpecDataKey, typeChar /* еее need better type here ееее */, partData._buffer, partData._length); DisposeByteArrayStruct(partData); THROW_IF_ERROR(error); SOM_CATCH_ALL SOM_ENDTRY #endif // _PLATFORM_MACINTOSH_ }
static VALUE __rbosa_insertion_loc_new (VALUE rcv, FourCharCode code) { AEDesc * self_desc; AEDesc rec; AEDesc pos_desc; AEDesc new_desc; self_desc = rbosa_element_aedesc (rcv); AECreateList (NULL, 0, true, &rec); AEPutParamDesc (&rec, keyAEObject, self_desc); AECreateDesc (code, NULL, 0, &pos_desc); AEPutParamPtr (&rec, keyAEPosition, typeEnumerated, &pos_desc, 4); AECoerceDesc (&rec, typeInsertionLoc, &new_desc); AEDisposeDesc (&rec); return rbosa_element_make (cOSAElement, &new_desc, Qnil); }
static pascal OSErr setmessageverb (const AppleEvent *event, AppleEvent *reply, long refcon) { #pragma unused (refcon) OSErr ec; AEDesc result; Str255 s; Handle htext; long lentext; Boolean fl; ec = AEGetParamDesc (event, keyDirectObject, typeChar, &result); if (ec != noErr) return (ec); htext = result.dataHandle; if (htext == nil) return (noErr); lentext = GetHandleSize (htext); if (lentext > 255) lentext = 255; s [0] = (unsigned char) lentext; BlockMove (*htext, &s [1], lentext); AEDisposeDesc (&result); setwindowmessage (s); fl = true; ec = AEPutParamPtr (reply, keyDirectObject, typeBoolean, (Ptr) &fl, sizeof (Boolean)); return (ec); } /*setmessageverb*/
wchar_t *sendpraatW (void *display, const wchar_t *programName, long timeOut, const wchar_t *text) { wchar_t nativeProgramName [100]; #if xwin char *home, pidFileName [256], messageFileName [256]; FILE *pidFile; long pid, wid = 0; #elif win wchar_t homeDirectory [256], messageFileName [256], windowName [256]; HWND window; (void) display; (void) timeOut; #elif mac AEDesc programDescriptor; AppleEvent event, reply; OSErr err; UInt32 signature; (void) display; #endif /* * Clean up from an earlier call. */ errorMessageW [0] = '\0'; /* * Handle case differences. */ wcscpy (nativeProgramName, programName); #if xwin nativeProgramName [0] = tolower (nativeProgramName [0]); #else nativeProgramName[0] = toupper (nativeProgramName [0]); #endif /* * If the text is going to be sent in a file, create its name. * The file is going to be written into the preferences directory of the receiving program. * On X Window, the name will be something like /home/jane/.praat-dir/message. * On Windows, the name will be something like C:\Documents and Settings\Jane\Praat\Message.txt, * or C:\Windows\Praat\Message.txt on older systems. * On Macintosh, the text is NOT going to be sent in a file. */ #if xwin if ((home = getenv ("HOME")) == NULL) { swprintf (errorMessageW, 1000, L"HOME environment variable not set."); return errorMessageW; } sprintf (messageFileName, "%s/.%ls-dir/message", home, programName); #elif win if (GetEnvironmentVariableW (L"USERPROFILE", homeDirectory, 255)) { ; /* Ready. */ } else if (GetEnvironmentVariableW (L"HOMEDRIVE", homeDirectory, 255)) { GetEnvironmentVariableW (L"HOMEPATH", homeDirectory + wcslen (homeDirectory), 255); } else { GetWindowsDirectoryW (homeDirectory, 255); } swprintf (messageFileName, 256, L"%ls\\%ls\\Message.txt", homeDirectory, programName); #endif /* * Write the message file (Unix and Windows only). */ #if xwin FILE *messageFile; if ((messageFile = fopen (messageFileName, "w")) == NULL) { swprintf (errorMessageW, 1000, L"Cannot create message file \"%s\" " L"(no privilege to write to directory, or disk full).\n", messageFileName); return errorMessageW; } if (timeOut) fwprintf (messageFile, L"#%ld\n", getpid ()); /* Write own process ID for callback. */ fwprintf (messageFile, L"\ufeff%ls", text); fclose (messageFile); #elif win { /* 20090401 [email protected] added braces to please visual studio */ FILE *messageFile; if ((messageFile = _wfopen (messageFileName, L"w")) == NULL) { swprintf (errorMessageW, 1000, L"Cannot create message file \"%ls\" " L"(no privilege to write to directory, or disk full).\n", messageFileName); return errorMessageW; } fwprintf (messageFile, L"\ufeff%ls", text); fclose (messageFile); } /* 20090401 [email protected] added braces to please visual studio */ #endif /* * Where shall we send the message? */ #if xwin /* * Get the process ID and the window ID of a running Praat-shell program. */ sprintf (pidFileName, "%s/.%ls-dir/pid", home, programName); if ((pidFile = fopen (pidFileName, "r")) == NULL) { swprintf (errorMessageW, 1000, L"Program %ls not running (or a version older than 3.6).", programName); return errorMessageW; } if (fscanf (pidFile, "%ld%ld", & pid, & wid) < 1) { fclose (pidFile); swprintf (errorMessageW, 1000, L"Program %ls not running, or disk has been full.", programName); return errorMessageW; } fclose (pidFile); #elif win /* * Get the window handle of the "Objects" window of a running Praat-shell program. */ swprintf (windowName, 256, L"PraatShell1 %ls", programName); window = FindWindowW (windowName, NULL); if (! window) { swprintf (errorMessageW, 1000, L"Program %ls not running (or an old version).", programName); return errorMessageW; } #elif mac /* * Convert the program name to a Macintosh signature. * I know of no system routine for this, so I'll just translate the two most common names: */ if (! wcscmp (programName, L"praat") || ! wcscmp (programName, L"Praat") || ! wcscmp (programName, L"PRAAT")) signature = 'PpgB'; else if (! wcscmp (programName, L"als") || ! wcscmp (programName, L"Als") || ! wcscmp (programName, L"ALS")) signature = 'CclA'; else signature = 0; AECreateDesc (typeApplSignature, & signature, 4, & programDescriptor); #endif /* * Send the message. */ #if xwin /* * Be ready to receive notification of completion. */ if (timeOut) signal (SIGUSR2, handleCompletion); /* * Notify running program. */ if (wid != 0) { /* Praat shell version October 21, 1998 or later? Send event to window. */ /* * Notify main window. */ XEvent event; int displaySupplied = display != NULL; if (! displaySupplied) { display = XOpenDisplay (NULL); if (display == NULL) { swprintf (errorMessageW, 1000, L"Cannot open display %s.", XDisplayName (NULL)); return errorMessageW; } } event. type = ClientMessage; event. xclient. serial = 0; event. xclient. send_event = True; event. xclient. display = display; event. xclient. window = (Window) wid; event. xclient. message_type = XInternAtom (display, "SENDPRAAT", False); event. xclient. format = 8; /* No byte swaps. */ strcpy (& event. xclient.data.b [0], "SENDPRAAT"); if(! XSendEvent (display, (Window) wid, True, KeyPressMask, & event)) { if (! displaySupplied) XCloseDisplay (display); swprintf (errorMessageW, 1000, L"Cannot send message to %ls (window %ld). " "The program %ls may have been started by a different user, " "or may have crashed.", programName, wid, programName); return errorMessageW; } if (! displaySupplied) XCloseDisplay (display); } else { /* * Use interrupt mechanism. */ if (kill (pid, SIGUSR1)) { swprintf (errorMessageW, 1000, L"Cannot send message to %ls (process %ld). " "The program %ls may have been started by a different user, " "or may have crashed.", programName, pid, programName); return errorMessageW; } } /* * Wait for the running program to notify us of completion, * but do not wait for more than 'timeOut' seconds. */ if (timeOut) { signal (SIGALRM, handleTimeOut); alarm (timeOut); theTimeOut = timeOut; /* Hand an argument to handleTimeOut () in a static variable. */ errorMessageW [0] = '\0'; pause (); if (errorMessageW [0] != '\0') return errorMessageW; } #elif win /* * Notify the running program by sending a WM_USER message to its main window. */ if (SendMessage (window, WM_USER, 0, 0)) { swprintf (errorMessageW, 1000, L"Program %ls returns error.", programName); /* BUG? */ return errorMessageW; } #elif mac /* * Notify the running program by sending it an Apple event of the magic class 758934755. */ AECreateAppleEvent (758934755, 0, & programDescriptor, kAutoGenerateReturnID, 1, & event); AEPutParamPtr (& event, 1, typeUnicodeText, text, wcslen (text) + 1); #ifdef __MACH__ err = AESendMessage (& event, & reply, ( timeOut == 0 ? kAENoReply : kAEWaitReply ) | kAECanInteract | kAECanSwitchLayer, timeOut == 0 ? kNoTimeOut : 60 * timeOut); #else err = AESend (& event, & reply, ( timeOut == 0 ? kAENoReply : kAEWaitReply ) | kAECanInteract | kAECanSwitchLayer, kAENormalPriority, timeOut == 0 ? kNoTimeOut : 60 * timeOut, NULL, NULL); #endif if (err != noErr) { if (err == procNotFound || err == connectionInvalid) swprintf (errorMessageW, 1000, L"Could not send message to program \"%ls\".\n" L"The program is probably not running (or an old version).", programName); else if (err == errAETimeout) swprintf (errorMessageW, 1000, L"Message to program \"%ls\" timed out " L"after %ld seconds, before completion.", programName, timeOut); else swprintf (errorMessageW, 1000, L"Unexpected sendpraat error %d.\nNotify the author.", err); } AEDisposeDesc (& programDescriptor); AEDisposeDesc (& event); AEDisposeDesc (& reply); #endif /* * Notify the caller of success (NULL pointer) or failure (string with an error message). */ return errorMessageW [0] == '\0' ? NULL : errorMessageW; }
// GetData_ofSize_ofType_ofContext_ForAttribute // // This function will get an attribute of a context your app created. See // Context Attributes near the bottom of the TabletAEDictionary.h header file. // // parameters: const void *inDataPtr - Location to store the attribute data. // Size inDataSize - Size of the data buffer pointed to above. // DescType dataType - Type of data bufferpointed to above. // UInt32 contextID - The context to get from. // DescType attribute - The attribute you want to get. // // returns: noErr on success, else an AE error code ////////////////////////////////////////////////////////////////////////////// OSErr GetData_ofSize_ofType_ofContext_ForAttribute(void *inDataPtr, Size inDataSize, DescType dataType, UInt32 contextID, DescType attribute) { AEDesc driverTarget,nullDesc,keyData,tObjSpecifier; AEDesc lastDesc; AppleEvent aeSend; AppleEvent aeReply; DescType outType; Size outSize; OSErr err; // assert(inDataPtr); if(!inDataPtr) { return -1; } err = GetTabletDriverTarget(&driverTarget); if(err) { return err; } err = AECreateAppleEvent(kAECoreSuite, kAEGetData, &driverTarget, kAutoGenerateReturnID, kAnyTransactionID, &aeSend); // Now tell the AE what to get // We have to set up a chain here. // Attribute -> Context -> null // The thing is, Apple Events are built backwards. So... //Create NULL AEDesc, this will signify the end of the AEDesc Chain AEInitializeDesc(&nullDesc); err = AECreateDesc( typeNull, NULL, NULL, &nullDesc ); AEInitializeDesc(&keyData); err = AECreateDesc( typeUInt32, &contextID, // This is the context ID that we want to modify sizeof(contextID), &keyData ); err = CreateObjSpecifier(cContext, // We want to modifiy a context attribute &nullDesc, // This is the last item in the chain formUniqueID, // use id to determine which context to modify &keyData, // This is the Context ID descriptor created above TRUE, // delete the nullDesc, and KeyData descriptor for us &tObjSpecifier); // The created descriptor which says that we want to modify Context X AEDuplicateDesc(&tObjSpecifier, &lastDesc); AEDisposeDesc(&tObjSpecifier); AEInitializeDesc(&keyData); err = AECreateDesc( typeType, &attribute, // This is the Attribute we want to set sizeof(DescType), &keyData ); err = CreateObjSpecifier(cProperty, // We want to destroy a context &lastDesc, // This is the last item in the chain (the Context) formPropertyID, // use id to determine which context to destroy &keyData, // This is the Context ID descriptor created above TRUE, // delete the nullDesc, and KeyData descriptor for us &tObjSpecifier); // The created descriptor which says that we want to delete Context X // Add the data to set to the AE here. err = AEPutParamPtr ( &aeSend, keyAERequestedType, typeType, &dataType, sizeof(DescType)); // The Object chain (Attribute -> Context -> null) err = AEPutParamDesc( &aeSend, keyDirectObject, &tObjSpecifier); // Finally send the event err = AESend(&aeSend, // The complete AE we created above &aeReply, kAEWaitReply, kAEHighPriority, kDefaultTimeOut, NULL, NULL); if(!err) { err = AEGetParamPtr(&aeReply, keyDirectObject, dataType, &outType, inDataPtr, // Put the answer into this variable inDataSize, &outSize); } AEDisposeDesc(&tObjSpecifier); AEDisposeDesc(&aeSend); AEDisposeDesc(&aeReply);
// CreateWacomContextForTablet // // This function will instruct the Tablet Driver to create a context for your // application that you can then modify. For example, you can modify your // context to change the tablet mapping or to diconnect the tablet from the // cursor. // // parameters: UInt32 tabletIdx - Tablet Number you want to a context for // UInt32 *contextID - On return, the ID used to modify / delete // your context. // // returns: a contextID and noErr on success, else an AE error code ////////////////////////////////////////////////////////////////////////////// OSErr CreateWacomContextForTablet(UInt32 tabletIdx, UInt32 *contextID) { AEDesc driverTarget,nullDesc,keyData,tObjSpecifier; DescType objectToMake = cContext; UInt32 outContextID; DescType outType; Size outSize; AppleEvent aeSend; AppleEvent aeReply; OSErr err; err = GetTabletDriverTarget(&driverTarget); if(err) { return err; } err = AECreateAppleEvent(kAECoreSuite, kAECreateElement, &driverTarget, kAutoGenerateReturnID, kAnyTransactionID, &aeSend); // Now tell the AE what to create err = AEPutParamPtr( &aeSend, keyAEObjectClass, typeType, &objectToMake, sizeof(DescType)); // Now tell the AE where to create a context //Create NULL AEDesc, this will signify the end of the AEDesc Chain AEInitializeDesc(&nullDesc); err = AECreateDesc( typeNull, NULL, NULL, &nullDesc ); AEInitializeDesc(&keyData); err = AECreateDesc( typeUInt32, &tabletIdx, // This is the tablet number we want the context for sizeof(tabletIdx), &keyData ); err = CreateObjSpecifier(cWTDTablet, // We want info from a tablet &nullDesc, // This is the last item in the chain formAbsolutePosition, // use indexing to determine which tablet to get data from &keyData, // This is the Tablet Number descriptor created above TRUE, // delete the nullDesc, and KeyData descriptor for us &tObjSpecifier); // The created descriptor which says that we want data from tablet number X err = AEPutParamDesc( &aeSend, keyAEInsertHere, &tObjSpecifier); // Finally send the event err = AESend(&aeSend, // The complete AE we created above &aeReply, // The reply event that contains the Context ID. kAEWaitReply, kAEHighPriority, kDefaultTimeOut, NULL, NULL); AEDisposeDesc(&tObjSpecifier); AEDisposeDesc(&aeSend); // Get the Context ID out of the reply err = AEGetParamPtr(&aeReply, keyDirectObject, typeUInt32, &outType, &outContextID, // Put the answer into this variable sizeof(long), &outSize); if(!err) { if(contextID) { *contextID = outContextID; } } AEDisposeDesc(&aeReply);
static OSErr ScriptHandler( const AppleEvent *event, AppleEvent *reply, SRefCon handlerRefcon) { OSStatus theErr; AEDescList theDesc; int tclErr = -1; Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon; char errString[128]; /* * The do script event receives one parameter that should be data or a * file. */ theErr = AEGetParamDesc(event, keyDirectObject, typeWildCard, &theDesc); if (theErr != noErr) { sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d", (int)theErr); theErr = AEPutParamPtr(reply, keyErrorString, typeChar, errString, strlen(errString)); } else if (MissedAnyParameters(event)) { /* * Return error if parameter is missing. */ sprintf(errString, "AEDoScriptHandler: extra parameters"); AEPutParamPtr(reply, keyErrorString, typeChar, errString, strlen(errString)); theErr = -1771; } else if (theDesc.descriptorType == (DescType) typeChar) { /* * We've had some data sent to us. Evaluate it. */ Tcl_DString encodedText; short i; Size size = AEGetDescDataSize(&theDesc); char *data = ckalloc(size + 1); AEGetDescData(&theDesc, data, size); data[size] = 0; for (i = 0; i < size; i++) { if (data[i] == '\r') { data[i] = '\n'; } } AEReplaceDescData(theDesc.descriptorType, data, size + 1, &theDesc); Tcl_ExternalToUtfDString(NULL, data, size, &encodedText); tclErr = Tcl_EvalEx(interp, Tcl_DStringValue(&encodedText), Tcl_DStringLength(&encodedText), TCL_EVAL_GLOBAL); Tcl_DStringFree(&encodedText); } else if (theDesc.descriptorType == (DescType) typeAlias) { /* * We've had a file sent to us. Source it. */ Boolean dummy; FSRef file; Size theSize = AEGetDescDataSize(&theDesc); AliasPtr alias = (AliasPtr) ckalloc(theSize); if (alias) { AEGetDescData(&theDesc, alias, theSize); theErr = FSResolveAlias(NULL, &alias, &file, &dummy); ckfree((char*)alias); } else { theErr = memFullErr; } if (theErr == noErr) { Tcl_DString scriptName; theErr = FSRefToDString(&file, &scriptName); if (theErr == noErr) { Tcl_EvalFile(interp, Tcl_DStringValue(&scriptName)); Tcl_DStringFree(&scriptName); } } else { sprintf(errString, "AEDoScriptHandler: file not found"); AEPutParamPtr(reply, keyErrorString, typeChar, errString, strlen(errString)); } } else { /* * Umm, don't recognize what we've got... */ sprintf(errString, "AEDoScriptHandler: invalid script type '%-4.4s'," " must be 'alis' or 'TEXT'", (char*) &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) { int reslen; const char *result = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &reslen); if (tclErr == TCL_OK) { AEPutParamPtr(reply, keyDirectObject, typeChar, result, reslen); } else { AEPutParamPtr(reply, keyErrorString, typeChar, result, reslen); AEPutParamPtr(reply, keyErrorNumber, typeSInt32, (Ptr) &tclErr, sizeof(int)); } } AEDisposeDesc(&theDesc); return theErr; }
/*---------------------------------------------------------------------------- HandleCoreSuiteEvent ----------------------------------------------------------------------------*/ void AECoreClass::HandleCoreSuiteEvent(const AppleEvent *appleEvent, AppleEvent *reply) { StAEDesc directParameter; StAEDesc token; OSErr err = noErr; // extract the direct parameter (an object specifier) err = ::AEGetKeyDesc(appleEvent, keyDirectObject, typeWildCard, &directParameter); ThrowIfOSErr(err); DescType tokenType = typeNull; DescType dispatchClass = typeNull; // check for null descriptor, which AEResolve doesn't handle well // If it's not null, then AEResolve will return an application-defined token if (directParameter.descriptorType == typeNull) { token = directParameter; // can throw } else { // The direct parameter contains an object specifier, or an "reference" in // AppleScript terminology, such as "rectangle 1 of document 1". // AEResolve() will recursively call our installed object accessors // until it returns a token with data referencing the requested object. err = ::AEResolve(&directParameter, kAEIDoMinimum, &token); } if (err == errAENoSuchObject || err == errAEIllegalIndex) { // If we were executing an "Exists..." AppleEvent, we can reply it here // because we have already determined that it DOES NOT exist. // First, we get the event ID. We use "eventError" instead of "err" // so that the result of AEGetAttributePtr() does not disturb the // errAENoSuchObject result previously returned. AEEventID eventID; OSType typeCode; Size actualSize = 0; OSErr eventError = ::AEGetAttributePtr(appleEvent, keyEventIDAttr, typeType, &typeCode, (Ptr)&eventID, // Get the eventID from the AppleEvent sizeof(eventID), &actualSize); // If event was an "Exists..." message, store the result (false) in the reply // because AEResolve() returned errAENoSuchObject. if (eventError == noErr && eventID == kAEDoObjectsExist) { Boolean foundIt = false; (void)AEPutParamPtr(reply, keyAEResult, typeBoolean, (Ptr)&foundIt, sizeof(Boolean)); // Now, we set the err to noErr so that the scripting component doesn't complain // that the object does not exist. We only do this if we were executing an "Exists..." // event. Otherwise, the errAENoSuchObject will be returned. ThrowNoErr(); } ThrowIfOSErr(err); return; } ThrowIfOSErr(err); // Pass the token returned by AEResolve(), and the original AppleEvent event and reply, // on to the appropriate object dispatcher // The token type is, by convention, the same as class ID that handles this event. // However, for property tokens, tokenType is cProperty for all objects, so // we look inside the token at its dispatchClass to find out which class of object // should really handle this AppleEvent. // Also, if the resolver returned a list of objects in the token, // the type will be typeAEList or one of our special list types, so // we set the dispatch class based on the list type // instead of on the type of the token itself if (AEListUtils::TokenContainsTokenList(&token)) { SInt32 numItems; err = AECountItems(&token, &numItems); if (numItems == 0) // could be an empty list { dispatchClass = typeNull; } else { StAEDesc tempToken; err = AEListUtils::GetFirstNonListToken((AEDesc *)&token, &tempToken); if (err == noErr && tempToken.descriptorType != typeNull) { ConstAETokenDesc tokenDesc(&tempToken); dispatchClass = tokenDesc.GetDispatchClass(); } else { dispatchClass = typeNull; err = noErr; } } } else if (token.descriptorType == typeNull) // make sure we correctly handle things for cApplication that don't have a direct parameter { dispatchClass = typeNull; } else { ConstAETokenDesc tokenDesc(&token); dispatchClass = tokenDesc.GetDispatchClass(); } // why is this special-cased? if (dispatchClass == cFile) { AEEventID eventID = 0; OSType typeCode = 0; Size actualSize = 0; OSErr eventError = AEGetAttributePtr(appleEvent, keyEventIDAttr, typeType, &typeCode, (Ptr)&eventID, // Get the eventID from the AppleEvent sizeof(eventID), &actualSize); } AEDispatchHandler* handler = GetDispatchHandler(dispatchClass); if (!handler) ThrowIfOSErr(errAEEventNotHandled); handler->DispatchEvent(&token, appleEvent, reply); }
OSErr SetData_ofSize_ofType_ofTabletObject_ForAttribute(void *inDataPtr, Size inDataSize, DescType dataType, TAEObject *pTabletObject, DescType attribute) { AEDesc driverTarget,nullDesc,keyData,tObjSpecifier; AEDesc lastDesc; AppleEvent aeSend; UInt32 tmpIndex = 0; OSErr err; // assert(inDataPtr); if(!inDataPtr) { return -1; } err = GetTabletDriverTarget(&driverTarget); if(err) { return err; } err = AECreateAppleEvent(kAECoreSuite, kAESetData, &driverTarget, kAutoGenerateReturnID, kAnyTransactionID, &aeSend); // Now tell the AE what to set // We have to set up a chain here. // Attribute -> Button -> Transducer -> Application -> Tablet -> null // The thing is, Apple Events are built backwards. So... //Create NULL AEDesc, this will signify the end of the AEDesc Chain AEInitializeDesc(&nullDesc); err = AECreateDesc( typeNull, NULL, NULL, &nullDesc ); // set up the driver desc AEInitializeDesc(&keyData); tmpIndex = 1; err = AECreateDesc( typeUInt32, &tmpIndex, // This is the Tablet Driver Index. Always 1 sizeof(tmpIndex), &keyData ); err = CreateObjSpecifier(cWTDDriver, &nullDesc, formAbsolutePosition, &keyData, TRUE, &tObjSpecifier); AEDuplicateDesc(&tObjSpecifier,&lastDesc); AEDisposeDesc(&tObjSpecifier); if (pTabletObject->objectType != cWTDDriver) { // set up the tablet desc AEInitializeDesc(&keyData); err = AECreateDesc( typeUInt32, &pTabletObject->tabletIndex, sizeof(UInt32), &keyData ); err = CreateObjSpecifier(cWTDTablet, &lastDesc, formAbsolutePosition, &keyData, TRUE, &tObjSpecifier); AEDuplicateDesc(&tObjSpecifier,&lastDesc); AEDisposeDesc(&tObjSpecifier); if (pTabletObject->objectType != cWTDTablet) { // set up the cutom app desc AEInitializeDesc(&keyData); err = AECreateDesc( typeUInt32, &pTabletObject->applicationIndex, sizeof(UInt32), &keyData ); err = CreateObjSpecifier(cWTDCustomizedApp, &lastDesc, formAbsolutePosition, &keyData, TRUE, &tObjSpecifier); AEDuplicateDesc(&tObjSpecifier,&lastDesc); AEDisposeDesc(&tObjSpecifier); if (pTabletObject->objectType != cWTDCustomizedApp) { if (pTabletObject->objectType == cWTDButton) { // set up the transducer desc AEInitializeDesc(&keyData); err = AECreateDesc( typeUInt32, &pTabletObject->transducerIndex, sizeof(UInt32), &keyData ); err = CreateObjSpecifier(cWTDTransducer, &lastDesc, formAbsolutePosition, &keyData, TRUE, &tObjSpecifier); AEDuplicateDesc(&tObjSpecifier,&lastDesc); AEDisposeDesc(&tObjSpecifier); } if (pTabletObject->objectType == cWTDTransducer) { // set up the transducer desc AEInitializeDesc(&keyData); err = AECreateDesc( typeUInt32, &pTabletObject->transducerIndex, sizeof(UInt32), &keyData ); err = CreateObjSpecifier(cWTDTransducer, &lastDesc, formAbsolutePosition, &keyData, TRUE, &tObjSpecifier); AEDuplicateDesc(&tObjSpecifier,&lastDesc); AEDisposeDesc(&tObjSpecifier); } else // cWTDButton || cWTDMenuItem || cWTDButton { // set up the transducer desc AEInitializeDesc(&keyData); err = AECreateDesc( typeUInt32, &pTabletObject->auxIndex, sizeof(UInt32), &keyData ); err = CreateObjSpecifier(pTabletObject->objectType, &lastDesc, formAbsolutePosition, &keyData, TRUE, &tObjSpecifier); AEDuplicateDesc(&tObjSpecifier,&lastDesc); AEDisposeDesc(&tObjSpecifier); } } } } AEInitializeDesc(&keyData); err = AECreateDesc( typeType, &attribute, // This is the Attribute we want to set sizeof(DescType), &keyData ); err = CreateObjSpecifier(cProperty, &lastDesc, formPropertyID, &keyData, TRUE, &tObjSpecifier); // Add the data to set to the AE here. err = AEPutParamPtr ( &aeSend, keyAEData, dataType, inDataPtr, inDataSize); err = AEPutParamDesc( &aeSend, keyDirectObject, &tObjSpecifier); // The Object chain // Finally send the event err = AESend(&aeSend, // The complete AE we created above NULL, // Don't need a reply kAEWaitReply, kAEHighPriority, kDefaultTimeOut, NULL, NULL); AEDisposeDesc(&tObjSpecifier); AEDisposeDesc(&aeSend); return err;
char *sendpraat (void *display, const char *programName, long timeOut, const char *text) { char nativeProgramName [100]; #if gtk char *home, pidFileName [256], messageFileName [256]; FILE *pidFile; long pid, wid = 0; #elif win char homeDirectory [256], messageFileName [256], windowName [256]; HWND window; (void) display; (void) timeOut; #elif mac AEDesc programDescriptor; AppleEvent event, reply; OSStatus err; UInt32 signature; (void) display; #endif /* * Clean up from an earlier call. */ errorMessage [0] = '\0'; /* * Handle case differences. */ strcpy (nativeProgramName, programName); #if gtk nativeProgramName [0] = tolower (nativeProgramName [0]); #else nativeProgramName [0] = toupper (nativeProgramName [0]); #endif /* * If the text is going to be sent in a file, create its name. * The file is going to be written into the preferences directory of the receiving program. * On Unix, the name will be something like /home/jane/.praat-dir/message. * On Windows, the name will be something like C:\Users\Jane\Praat\Message.txt, * or C:\Windows\Praat\Message.txt on older systems. * On Macintosh, the text is NOT going to be sent in a file. */ #if gtk if ((home = getenv ("HOME")) == NULL) { sprintf (errorMessage, "HOME environment variable not set."); return errorMessage; } sprintf (messageFileName, "%s/.%s-dir/message", home, programName); #elif win if (GetEnvironmentVariableA ("USERPROFILE", homeDirectory, 255)) { ; /* Ready. */ } else if (GetEnvironmentVariableA ("HOMEDRIVE", homeDirectory, 255)) { GetEnvironmentVariableA ("HOMEPATH", homeDirectory + strlen (homeDirectory), 255); } else { GetWindowsDirectoryA (homeDirectory, 255); } sprintf (messageFileName, "%s\\%s\\Message.txt", homeDirectory, programName); #endif /* * Save the message file (Unix and Windows only). */ #if gtk || win { FILE *messageFile; if ((messageFile = fopen (messageFileName, "w")) == NULL) { sprintf (errorMessage, "Cannot create message file \"%s\" " "(no privilege to write to directory, or disk full, or program is not called %s).\n", messageFileName, programName); return errorMessage; } #if gtk if (timeOut) fprintf (messageFile, "#%ld\n", (long) getpid ()); /* Write own process ID for callback. */ #endif fprintf (messageFile, "%s", text); fclose (messageFile); } #endif /* * Where shall we send the message? */ #if gtk /* * Get the process ID and the window ID of a running Praat-shell program. */ sprintf (pidFileName, "%s/.%s-dir/pid", home, programName); if ((pidFile = fopen (pidFileName, "r")) == NULL) { sprintf (errorMessage, "Program %s not running.", programName); return errorMessage; } if (fscanf (pidFile, "%ld%ld", & pid, & wid) < 1) { fclose (pidFile); sprintf (errorMessage, "Program %s not running, or disk has been full.", programName); return errorMessage; } fclose (pidFile); #elif win /* * Get the window handle of the "Objects" window of a running Praat-shell program. */ sprintf (windowName, "PraatShell1 %s", programName); window = FindWindowA (windowName, NULL); if (! window) { sprintf (errorMessage, "Program %s not running (or an old version).", programName); return errorMessage; } #elif mac /* * Convert the program name to a Macintosh signature. * I know of no system routine for this, so I'll just translate the two most common names: */ if (! strcmp (programName, "praat") || ! strcmp (programName, "Praat") || ! strcmp (programName, "PRAAT")) signature = 'PpgB'; else if (! strcmp (programName, "als") || ! strcmp (programName, "Als") || ! strcmp (programName, "ALS")) signature = 'CclA'; else signature = 0; AECreateDesc (typeApplSignature, & signature, 4, & programDescriptor); #endif /* * Send the message. */ #if gtk /* * Be ready to receive notification of completion. */ if (timeOut) signal (SIGUSR2, handleCompletion); /* * Notify running program. */ if (wid != 0) { /* Praat shell version October 21, 1998 or later? Send event to window. */ /* * Notify main window. */ GdkEventClient gevent; g_type_init (); int displaySupplied = display != NULL; if (! displaySupplied) { display = gdk_display_open (getenv ("DISPLAY")); /* GdkDisplay* */ if (display == NULL) { sprintf (errorMessage, "Cannot open display %s", getenv ("DISPLAY")); return errorMessage; } } gevent. type = GDK_CLIENT_EVENT; gevent. window = 0; gevent. send_event = 1; gevent. message_type = gdk_atom_intern_static_string ("SENDPRAAT"); gevent. data_format = 8; if (! gdk_event_send_client_message_for_display (display, (GdkEvent *) & gevent, wid)) { if (! displaySupplied) gdk_display_close (display); sprintf (errorMessage, "Cannot send message to %s (window %ld). " "The program %s may have been started by a different user, " "or may have crashed.", programName, wid, programName); return errorMessage; } if (! displaySupplied) gdk_display_close (display); } /* * Wait for the running program to notify us of completion, * but do not wait for more than 'timeOut' seconds. */ if (timeOut) { signal (SIGALRM, handleTimeOut); alarm (timeOut); theTimeOut = timeOut; /* Hand an argument to handleTimeOut () in a static variable. */ errorMessage [0] = '\0'; pause (); if (errorMessage [0] != '\0') return errorMessage; } #elif win /* * Notify the running program by sending a WM_USER message to its main window. */ if (SendMessage (window, WM_USER, 0, 0)) { sprintf (errorMessage, "Program %s returns error.", programName); /* BUG? */ return errorMessage; } #elif mac /* * Notify the running program by sending it an Apple event of the magic class 758934755. */ AECreateAppleEvent (758934755, 0, & programDescriptor, kAutoGenerateReturnID, 1, & event); AEPutParamPtr (& event, 1, typeChar, text, strlen (text) + 1); #ifdef __MACH__ err = AESendMessage (& event, & reply, ( timeOut == 0 ? kAENoReply : kAEWaitReply ) | kAECanInteract | kAECanSwitchLayer, timeOut == 0 ? kNoTimeOut : 60 * timeOut); #else err = AESend (& event, & reply, ( timeOut == 0 ? kAENoReply : kAEWaitReply ) | kAECanInteract | kAECanSwitchLayer, kAENormalPriority, timeOut == 0 ? kNoTimeOut : 60 * timeOut, NULL, NULL); #endif if (err != noErr) { if (err == procNotFound || err == connectionInvalid) sprintf (errorMessage, "Could not send message to program \"%s\".\n" "The program is probably not running (or an old version).", programName); else if (err == errAETimeout) sprintf (errorMessage, "Message to program \"%s\" timed out " "after %ld seconds, before completion.", programName, timeOut); else sprintf (errorMessage, "Unexpected sendpraat error %d.\nNotify the author.", err); } AEDisposeDesc (& programDescriptor); AEDisposeDesc (& event); AEDisposeDesc (& reply); #endif /* * Notify the caller of success (NULL pointer) or failure (string with an error message). */ return errorMessage [0] == '\0' ? NULL : errorMessage; }
// CountTabletObjects // // This function will return the number of particular items the Tablet Driver // knows about. For examle, the number of tablets, the number of transducers // for a customized application for a particular tablet... // // parameters: TAEObject *pTabletObject - Pointer to a TAEObject that // describes exactly which tablet object // you want to count. // UInt32 *outCount - The number of pTabletObjects the driver knows // about. // // returns: noErr on success, else an AE error code ////////////////////////////////////////////////////////////////////////////// OSErr CountTabletObjects(TAEObject *pTabletObject, UInt32 *outCount) { AEDesc driverTarget,keyData,tObjSpecifier; AEDesc lastDesc; AppleEvent aeSend; AppleEvent aeReply; DescType outType; Size outSize; UInt32 tmpIndex = 0; UInt32 tmpCount = 0; OSErr err; // assert(outCount); if(!outCount) { return -1; } err = GetTabletDriverTarget(&driverTarget); if(err) { return err; } err = AECreateAppleEvent(kAECoreSuite, kAECountElements, &driverTarget, kAutoGenerateReturnID, kAnyTransactionID, &aeSend); // Now tell the AE what to Count // We have to set up a chain here. // [Button ->] [Transducer ->] [Application ->] Tablet -> null // The thing is, Apple Events are built backwards. So... //Create NULL AEDesc, this will signify the end of the AEDesc Chain AEInitializeDesc(&lastDesc); err = AECreateDesc( typeNull, NULL, NULL, &lastDesc ); if (pTabletObject->objectType != cWTDDriver) { // set up the driver desc AEInitializeDesc(&keyData); tmpIndex = 1; err = AECreateDesc( typeUInt32, &tmpIndex, // This is the Tablet Driver Index. Always 1 sizeof(tmpIndex), &keyData ); err = CreateObjSpecifier(cWTDDriver, &lastDesc, formAbsolutePosition, &keyData, TRUE, &tObjSpecifier); AEDuplicateDesc(&tObjSpecifier,&lastDesc); AEDisposeDesc(&tObjSpecifier); if (pTabletObject->objectType != cWTDTablet) { // set up the tablet desc AEInitializeDesc(&keyData); err = AECreateDesc( typeUInt32, &pTabletObject->tabletIndex, sizeof(UInt32), &keyData ); err = CreateObjSpecifier(cWTDTablet, &lastDesc, formAbsolutePosition, &keyData, TRUE, &tObjSpecifier); AEDuplicateDesc(&tObjSpecifier,&lastDesc); AEDisposeDesc(&tObjSpecifier); if (pTabletObject->objectType != cWTDCustomizedApp) { // set up the cutom app desc AEInitializeDesc(&keyData); err = AECreateDesc( typeUInt32, &pTabletObject->applicationIndex, sizeof(UInt32), &keyData ); err = CreateObjSpecifier(cWTDCustomizedApp, &lastDesc, formAbsolutePosition, &keyData, TRUE, &tObjSpecifier); AEDuplicateDesc(&tObjSpecifier,&lastDesc); AEDisposeDesc(&tObjSpecifier); if (pTabletObject->objectType == cWTDButton) { // set up the transducer desc AEInitializeDesc(&keyData); err = AECreateDesc( typeUInt32, &pTabletObject->transducerIndex, sizeof(UInt32), &keyData ); err = CreateObjSpecifier(cWTDTransducer, &lastDesc, formAbsolutePosition, &keyData, TRUE, &tObjSpecifier); AEDuplicateDesc(&tObjSpecifier,&lastDesc); AEDisposeDesc(&tObjSpecifier); } } } } // Now we actually tell it to count the number of the tablet objects err = AEPutParamPtr( &aeSend, keyAEObjectClass, typeType, &pTabletObject->objectType, // This is the class of objects to count sizeof(DescType) ); err = AEPutParamDesc( &aeSend, keyDirectObject, &lastDesc); // The Object chain // Finally send the event err = AESend(&aeSend, // The complete AE we created above &aeReply, kAEWaitReply, kAEHighPriority, kDefaultTimeOut, NULL, NULL); if(!err) { // Get the answer from the Reply err = AEGetParamPtr(&aeReply, keyDirectObject, typeUInt32, &outType, &tmpCount, // Put the answer into this variable sizeof(long), &outSize); if(noErr != err) { tmpCount = 0; } else { *outCount = tmpCount; } } AEDisposeDesc(&tObjSpecifier); AEDisposeDesc(&aeSend); AEDisposeDesc(&aeReply); return err;
static OSErr ScriptHandler( const AppleEvent *event, AppleEvent *reply, long handlerRefcon) { OSStatus theErr; AEDescList theDesc; Size size; int tclErr = -1; Tcl_Interp *interp = (Tcl_Interp *) handlerRefcon; char errString[128]; /* * The do script event receives one parameter that should be data or a * file. */ theErr = AEGetParamDesc(event, keyDirectObject, typeWildCard, &theDesc); if (theErr != noErr) { sprintf(errString, "AEDoScriptHandler: GetParamDesc error %d", (int)theErr); theErr = AEPutParamPtr(reply, keyErrorString, typeChar, errString, strlen(errString)); } else if (MissedAnyParameters(event)) { /* * Return error if parameter is missing. */ sprintf(errString, "AEDoScriptHandler: extra parameters"); AEPutParamPtr(reply, keyErrorString, typeChar, errString, strlen(errString)); theErr = -1771; } else if (theDesc.descriptorType == (DescType) typeAlias && AEGetParamPtr(event, keyDirectObject, typeFSRef, NULL, NULL, 0, &size) == noErr && size == sizeof(FSRef)) { /* * We've had a file sent to us. Source it. */ FSRef file; theErr = AEGetParamPtr(event, keyDirectObject, typeFSRef, NULL, &file, size, NULL); if (theErr == noErr) { Tcl_DString scriptName; theErr = FSRefToDString(&file, &scriptName); if (theErr == noErr) { tclErr = Tcl_EvalFile(interp, Tcl_DStringValue(&scriptName)); Tcl_DStringFree(&scriptName); } else { sprintf(errString, "AEDoScriptHandler: file not found"); AEPutParamPtr(reply, keyErrorString, typeChar, errString, strlen(errString)); } } } else if (AEGetParamPtr(event, keyDirectObject, typeUTF8Text, NULL, NULL, 0, &size) == noErr && size) { /* * We've had some data sent to us. Evaluate it. */ char *data = ckalloc(size + 1); theErr = AEGetParamPtr(event, keyDirectObject, typeUTF8Text, NULL, data, size, NULL); if (theErr == noErr) { tclErr = Tcl_EvalEx(interp, data, size, TCL_EVAL_GLOBAL); } } else { /* * Umm, don't recognize what we've got... */ sprintf(errString, "AEDoScriptHandler: invalid script type '%-4.4s', " "must be 'alis' or coercable to 'utf8'", (char*) &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) { int reslen; const char *result = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &reslen); if (tclErr == TCL_OK) { AEPutParamPtr(reply, keyDirectObject, typeChar, result, reslen); } else { AEPutParamPtr(reply, keyErrorString, typeChar, result, reslen); AEPutParamPtr(reply, keyErrorNumber, typeSInt32, (Ptr) &tclErr, sizeof(int)); } } AEDisposeDesc(&theDesc); return theErr; }