static PyObject *AEDesc_AEGetParamPtr(AEDescObject *_self, PyObject *_args) { PyObject *_res = NULL; OSErr _err; AEKeyword theAEKeyword; DescType desiredType; DescType typeCode; char *dataPtr__out__; long dataPtr__len__; int dataPtr__in_len__; #ifndef AEGetParamPtr PyMac_PRECHECK(AEGetParamPtr); #endif if (!PyArg_ParseTuple(_args, "O&O&i", PyMac_GetOSType, &theAEKeyword, PyMac_GetOSType, &desiredType, &dataPtr__in_len__)) return NULL; if ((dataPtr__out__ = malloc(dataPtr__in_len__)) == NULL) { PyErr_NoMemory(); goto dataPtr__error__; } dataPtr__len__ = dataPtr__in_len__; _err = AEGetParamPtr(&_self->ob_itself, theAEKeyword, desiredType, &typeCode, dataPtr__out__, dataPtr__len__, &dataPtr__len__); // TO DO: see AEDesc_AEGetAttributePtr if (_err != noErr) return PyMac_Error(_err); _res = Py_BuildValue("O&s#", PyMac_BuildOSType, typeCode, dataPtr__out__, (int)dataPtr__len__); free(dataPtr__out__); dataPtr__error__: ; return _res; }
static OSStatus SendAppleEvent(const AEDesc *event, AEDesc *reply) // This is the bottleneck routine we use for sending Apple events. // It has a number of neato features. // // o It use the "AEMach.h" routine AESendMessage because that allows // us to do an RPC without having to field UI events while waiting // for the reply. Yay for Mac OS X! // // o It automatically extracts the error from the reply. // // o It allows you to enable printing of events and their replies // for debugging purposes. { static const long kAETimeoutTicks = 5 * 60; OSStatus err; OSErr replyErr; DescType junkType; Size junkSize; // Normally I don't declare function prototypes in local scope, // but I made this exception because I don't want anyone except // for this routine calling GDBPrintAEDesc. This routine takes // care to only link with the routine when debugging is enabled; // everyone else might not be so careful. #if LOGIN_ITEMS_AE_PRINT_DESC extern void GDBPrintAEDesc(const AEDesc *desc); // This is private system function used to print a // textual representation of an AEDesc to stderr. // It's very handy when debugging, and is meant only // for that purpose. It's only available to Mach-O // clients. We use it when debugging *only*. #endif assert(event != NULL); assert(reply != NULL); #if LOGIN_ITEMS_AE_PRINT_DESC GDBPrintAEDesc(event); #endif err = AESendMessage(event, reply, kAEWaitReply, kAETimeoutTicks); #if LOGIN_ITEMS_AE_PRINT_DESC GDBPrintAEDesc(reply); #endif // Extract any error from the Apple event handler via the // keyErrorNumber parameter of the reply. if ( (err == noErr) && (reply->descriptorType != typeNull) ) { err = AEGetParamPtr( reply, keyErrorNumber, typeShortInteger, &junkType, &replyErr, sizeof(replyErr), &junkSize ); if (err == errAEDescNotFound ) { err = noErr; } else { err = replyErr; } } return err; }
// 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;
// GetData_ofSize_ofType_ofTabletObject_ForAttribute // // This function will get an attribute of a tablet object. See the // TabletAEDictionary.h header file. Note that these are the global objects // that are modified by the user with the Wacom Control Panel. You should not // modify any of these attributes. However, you can use this function to get // information like the version of the Tablet Driver, size of a tablet, the // name of a transducer and so on. You might also use this function to get a // dump of the current setting of each transducer of each tablet for // diagnostics. // // 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. // TAEObject *pTabletObject - Pointer to a TAEObject that // describes exactly which tablet object // you want to get data from. // DescType attribute - The attribute you want to get. // // returns: noErr on success, else an AE error code ////////////////////////////////////////////////////////////////////////////// OSErr GetData_ofSize_ofType_ofTabletObject_ForAttribute(void *inDataPtr, Size inDataSize, DescType dataType, TAEObject *pTabletObject, DescType attribute) { AEDesc driverTarget,nullDesc,keyData,tObjSpecifier; AEDesc lastDesc; AppleEvent aeSend; AppleEvent aeReply; DescType outType; Size outSize; UInt32 tmpIndex = 0; 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 -> 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 get sizeof(DescType), &keyData ); err = CreateObjSpecifier(cProperty, &lastDesc, formPropertyID, &keyData, TRUE, &tObjSpecifier); // Add the data to set to the AE here. err = AEPutParamPtr ( &aeSend, keyAERequestedType, typeType, &dataType, sizeof(DescType)); err = AEPutParamDesc( &aeSend, keyDirectObject, &tObjSpecifier); // The Object chain // 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); return err;
// 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, 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; }
SOM_Scope void SOMLINK ODLinkSpecReadFromOSAEvent(ODLinkSpec *somSelf, Environment *ev, OSAEvent* theOSAEvent) #endif { ODLinkSpecData *somThis = ODLinkSpecGetData(somSelf); ODLinkSpecMethodDebug("ODLinkSpec","ReadFromAppleEvent"); #ifdef _PLATFORM_OS2_ // CED _interrupt(3); #endif // _PLATFORM_OS2_ #ifdef _PLATFORM_MACINTOSH_ SOM_CATCH return; /* Moved from somInit. SOM itself sets fields to zero _fProcessLaunchDate = 0; _fProcessID.lowLongOfPSN = kNoProcess; _fProcessID.highLongOfPSN = 0; */ OSErr result; DescType returnedType; Size actualSize; ODPart* part; ODByteArray partData; ProcessSerialNumber processID; ODULong processLaunchDate; ODULong dataSize; result = AEGetParamPtr((AppleEvent*) theAppleEvent, keyProcessSerialNumber, typeProcessSerialNumber, &returnedType, &processID, sizeof(processID), &actualSize); THROW_IF_ERROR(result); result = AEGetParamPtr((AppleEvent*) theAppleEvent, kODProcessLaunchDateKey, typeLongInteger, &returnedType, &processLaunchDate, sizeof(processLaunchDate), &actualSize); THROW_IF_ERROR(result); result = AEGetParamPtr((AppleEvent*) theAppleEvent, kODSourcePartKey, typeLongInteger, &returnedType, &part, sizeof(part), &actualSize); THROW_IF_ERROR(result); result = AEGetParamPtr((AppleEvent*) theAppleEvent, kODLinkSpecDataSizeKey, typeLongInteger, &returnedType, &dataSize, sizeof(ODULong), &actualSize); THROW_IF_ERROR(result); partData = CreateEmptyByteArrayStruct(dataSize); TRY if ( dataSize > 0 ) { result = AEGetParamPtr((AppleEvent*) theAppleEvent, kODLinkSpecDataKey, typeChar, &returnedType, partData._buffer, dataSize, &actualSize); THROW_IF_ERROR(result); partData._length = dataSize; } somSelf->InitBaseLinkSpec(ev, part, &partData); CATCH_ALL DisposeByteArrayStruct(partData); RERAISE; ENDTRY DisposeByteArrayStruct(partData); _fProcessID = processID; _fProcessLaunchDate = processLaunchDate; #endif // _PLATFORM_MACINTOSH_ }
Boolean AddCommands( SRRecognizer inSpeechRecognizer, SRLanguageModel inCommandsLangaugeModel, CFArrayRef inCommandNamesArray ) { // Dictionary keys for Commands Data property list #define kCommandsDataPlacementHintKey "PlacementHint" // value type is: CFNumberRef #define kPlacementHintWhereverNumValue 0 #define kPlacementHintProcessNumValue 1 // you must also provide the PSN using kCommandsDataProcessPSNHighKey & kCommandsDataProcessPSNLowKey #define kPlacementHintFirstNumValue 2 #define kPlacementHintMiddleNumValue 3 #define kPlacementHintLastNumValue 4 #define kCommandsDataProcessPSNHighKey "ProcessPSNHigh" // value type is: CFNumberRef #define kCommandsDataProcessPSNLowKey "ProcessPSNLow" // value type is: CFNumberRef #define kCommandsDataDisplayOrderKey "DisplayOrder" // value type is: CFNumberRef - the order in which recognizers from the same client process should be displayed. #define kCommandsDataCmdInfoArrayKey "CommandInfoArray" // value type is: CFArrayRef of CFDictionaryRef values #define kCommandInfoNameKey "Text" #define kCommandInfoChildrenKey "Children" Boolean successfullyAddCommands = false; if (inCommandNamesArray) { CFIndex numOfCommands = CFArrayGetCount( inCommandNamesArray ); CFMutableArrayRef theSectionArray = CFArrayCreateMutable( NULL, 0, &kCFTypeArrayCallBacks ); // Erase any existing commands in the language model before we begin adding the given list of commands if (SREmptyLanguageObject( inCommandsLangaugeModel ) == noErr && theSectionArray) { CFIndex i; char theCSringBuffer[100]; successfullyAddCommands = true; for (i = 0; i < numOfCommands; i++) { CFStringRef theCommandName = CFArrayGetValueAtIndex(inCommandNamesArray, i); if (theCommandName && CFStringGetCString( theCommandName, theCSringBuffer, 100, kCFStringEncodingMacRoman )) { // Conditionalized just to remove compiler warnings. #if __LP64__ if (SRAddText( inCommandsLangaugeModel, theCSringBuffer, strlen(theCSringBuffer), (void *)i) == noErr) { #else if (SRAddText( inCommandsLangaugeModel, theCSringBuffer, strlen(theCSringBuffer), i) == noErr) { #endif CFStringRef keys[1]; CFTypeRef values[1]; CFDictionaryRef theItemDict; keys[0] = CFSTR( kCommandInfoNameKey ); values[0] = theCommandName; // Make CDDictionary our keys and values. theItemDict = CFDictionaryCreate(NULL, (const void **)keys, (const void **)values, 1, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); // Add to command array if (theItemDict) { CFArrayAppendValue( theSectionArray, theItemDict ); CFRelease( theItemDict ); // We release our hold on the dictionary object and let the array own it now. } else successfullyAddCommands = false; } else successfullyAddCommands = false; if (! successfullyAddCommands) break; } } // // Create the XML data that contains the commands to display and give this data to the // recognizer object to display in the Speech Commands window. // { CFIndex numOfParams = 4; CFStringRef keys[numOfParams]; CFTypeRef values[numOfParams]; CFDictionaryRef theItemDict; SInt32 placementHint = 1; // 1 = show only when this app is front process ProcessSerialNumber thisAppsPSN; thisAppsPSN.highLongOfPSN = 0; thisAppsPSN.lowLongOfPSN = 0; GetCurrentProcess( &thisAppsPSN ); keys[0] = CFSTR( kCommandsDataPlacementHintKey ); keys[1] = CFSTR( kCommandsDataCmdInfoArrayKey ); keys[2] = CFSTR( kCommandsDataProcessPSNHighKey ); keys[3] = CFSTR( kCommandsDataProcessPSNLowKey ); values[0] = CFNumberCreate(NULL, kCFNumberSInt32Type, &placementHint); values[1] = theSectionArray; values[2] = CFNumberCreate(NULL, kCFNumberSInt32Type, &(thisAppsPSN.highLongOfPSN)); values[3] = CFNumberCreate(NULL, kCFNumberSInt32Type, &(thisAppsPSN.lowLongOfPSN)); // Make CDDictionary of our keys and values. theItemDict = CFDictionaryCreate(NULL, (const void **)keys, (const void **)values, numOfParams, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (theItemDict) { // Convert CFDictionary object to XML representation CFDataRef dictData = CFPropertyListCreateXMLData(NULL, theItemDict); if (dictData) { // Set command list in our SRRecognizer object, causing the Speech Commands window to update. (void)SRSetProperty (inSpeechRecognizer, 'cdpl', CFDataGetBytePtr(dictData), CFDataGetLength(dictData)); CFRelease( dictData ); } } // Release our hold on the dictionary object and let the array own it now. if (theItemDict) CFRelease( theItemDict ); // Release our values if (values[0]) CFRelease( values[0] ); if (values[2]) CFRelease( values[2] ); if (values[3]) CFRelease( values[3] ); CFRelease( theSectionArray ); } } } return successfullyAddCommands; } /* ConvertAppleEventResultIntoCommandID This routine converts the Apple event data received from a speech done (kAESpeechSuite, kAESpeechDone) Apple event into a command ID when using the AddCommands routine to add your commands to the top-level language model. This routine returns true if the spoken utterance was recognized as a valid command. */ Boolean ConvertAppleEventResultIntoCommandID( const AppleEvent *inAppleEvent, long * outCommandID ) { Boolean successfullyFound = false; Size actualSize; DescType actualType; OSErr recStatus = noErr; // Get recognition status from AE, and check that it is equal to 0. if (AEGetParamPtr( inAppleEvent, keySRSpeechStatus, typeSInt16, &actualType, (Ptr)&recStatus, sizeof(recStatus), &actualSize) == noErr && recStatus == noErr) { // Get recognition result from AE, and continue if not NULL. SRRecognitionResult recResult = NULL; if (AEGetParamPtr( inAppleEvent, keySRSpeechResult, typeSRSpeechResult, &actualType, (Ptr)&recResult, sizeof(recResult), &actualSize) == noErr && recResult) { // Get language model result from recognition result Size theLen = sizeof(SRLanguageModel); SRLanguageModel resultLanguageModel = 0; if (SRGetProperty( recResult, kSRLanguageModelFormat, &resultLanguageModel, &theLen ) == noErr) { // Get the recognized command object from the language model // Since there will only be one object in the langauge model, we just grab the first one. SRLanguageObject resultingCommandObj = 0; if (SRGetIndexedItem( resultLanguageModel, &resultingCommandObj, 0 ) == noErr) { // Get the command ID from the refCon property of the recognized command object. theLen = sizeof(long); if (SRGetProperty( resultingCommandObj, kSRRefCon, outCommandID, &theLen ) == noErr) successfullyFound = true; } } } } return successfullyFound; }
CFStringRef CFStringCreateWithEvent(const AppleEvent *ev, AEKeyword theKey, OSErr *errPtr) { CFStringRef outStr = NULL; DescType typeCode; DescType returnedType; Size actualSize; Size dataSize; CFStringEncoding encodeKey; OSType a_type; *errPtr = AESizeOfParam(ev, theKey, &typeCode, &dataSize); if ((*errPtr != noErr) || (typeCode == typeNull)){ goto bail; } #if useLog showAEDesc(ev); #endif if (dataSize == 0) { outStr = CFSTR(""); goto bail; } switch (typeCode) { case typeChar: encodeKey = CFStringGetSystemEncoding(); break; case typeUTF8Text: encodeKey = kCFStringEncodingUTF8; break; case typeType: *errPtr = AEGetParamPtr(ev, theKey, typeCode, &returnedType, &a_type, dataSize, &actualSize); if (a_type == cMissingValue) { goto bail; } //break; default : typeCode = typeUnicodeText; encodeKey = kCFStringEncodingUnicode; } UInt8 *dataPtr = malloc(dataSize); if (dataPtr == NULL) { *errPtr = errAEEventFailed; fputs("Failed to malloc.", stderr); goto bail; } *errPtr = AEGetParamPtr(ev, theKey, typeCode, &returnedType, dataPtr, dataSize, &actualSize); if (*errPtr != noErr) { free(dataPtr); goto bail; } if (actualSize > dataSize) { #if useLog printf("buffere size is allocated. data:%i actual:%i\n", (int)dataSize, (int)actualSize); #endif dataSize = actualSize; dataPtr = (UInt8 *)realloc(dataPtr, dataSize); if (dataPtr == NULL) { fputs("Failed to reallocate memory", stderr); goto bail; } *errPtr = AEGetParamPtr(ev, theKey, typeCode, &returnedType, dataPtr, dataSize, &actualSize); } if (*errPtr == noErr) { outStr = CFStringCreateWithBytes(NULL, dataPtr, dataSize, encodeKey, false); } free(dataPtr); bail: return outStr; }
// in // keyword // appleevent // dest pointer // max size, comes out as size got OSErr FetchParam(AEKeyword plop,AppleEvent *appIn,Ptr dest,DescType theType,Size *len) { DescType actualType; return AEGetParamPtr(appIn, plop, theType, &actualType, dest, *len, len); }