static PyObject *AE_AECreateAppleEvent(PyObject *_self, PyObject *_args) { PyObject *_res = NULL; OSErr _err; AEEventClass theAEEventClass; AEEventID theAEEventID; AEAddressDesc target; AEReturnID returnID; AETransactionID transactionID; AppleEvent result; if (!PyArg_ParseTuple(_args, "O&O&O&hi", AE_GetOSType, &theAEEventClass, AE_GetOSType, &theAEEventID, AE_AEDesc_Convert, &target, &returnID, &transactionID)) return NULL; _err = AECreateAppleEvent(theAEEventClass, theAEEventID, &target, returnID, transactionID, &result); if (_err != noErr) return AE_MacOSError(_err); // workaround for return ID bug in 10.6 DescType typeCode; Size actualSize; SInt32 actualReturnID; if (returnID == kAutoGenerateReturnID) { _err = AEGetAttributePtr(&result, keyReturnIDAttr, typeSInt32, &typeCode, &actualReturnID, sizeof(actualReturnID), &actualSize); if (_err != noErr) return AE_MacOSError(_err); if (actualReturnID == -1) { AEDisposeDesc(&result); _err = AECreateAppleEvent(theAEEventClass, theAEEventID, &target, returnID, transactionID, &result); if (_err != noErr) return AE_MacOSError(_err); } } _res = Py_BuildValue("O&", AE_AEDesc_New, &result); return _res; }
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; }
static PyObject *AE_AECreateAppleEvent(PyObject *_self, PyObject *_args) { PyObject *_res = NULL; OSErr _err; AEEventClass theAEEventClass; AEEventID theAEEventID; AEAddressDesc target; AEReturnID returnID; AETransactionID transactionID; AppleEvent result; #ifndef AECreateAppleEvent PyMac_PRECHECK(AECreateAppleEvent); #endif if (!PyArg_ParseTuple(_args, "O&O&O&hl", PyMac_GetOSType, &theAEEventClass, PyMac_GetOSType, &theAEEventID, AEDesc_Convert, &target, &returnID, &transactionID)) return NULL; _err = AECreateAppleEvent(theAEEventClass, theAEEventID, &target, returnID, transactionID, &result); if (_err != noErr) return PyMac_Error(_err); _res = Py_BuildValue("O&", AEDesc_New, &result); return _res; }
OSStatus SendAppleEventToSystemProcess(AEEventID eventToSendID) { AEAddressDesc targetDesc; static const ProcessSerialNumber kPSNOfSystemProcess = {0, kSystemProcess }; AppleEvent eventReply = {typeNull, NULL}; AppleEvent eventToSend = {typeNull, NULL}; OSStatus status = AECreateDesc(typeProcessSerialNumber, &kPSNOfSystemProcess, sizeof(kPSNOfSystemProcess), &targetDesc); if (status != noErr) return status; status = AECreateAppleEvent(kCoreEventClass, eventToSendID, &targetDesc, kAutoGenerateReturnID, kAnyTransactionID, &eventToSend); AEDisposeDesc(&targetDesc); if (status != noErr) return status; status = AESendMessage(&eventToSend, &eventReply, kAENormalPriority, kAEDefaultTimeout); AEDisposeDesc(&eventToSend); if (status != noErr) return status; AEDisposeDesc(&eventReply); return status; }
Boolean IACnewsystemverb (OSType vclass, OSType vtoken, AppleEvent *event) { /* 6/29/92 DW: special entry point for messages sent to system event handlers. implementation detail: this is accomplished by sending the message to ourself. */ AEAddressDesc adr; OSErr ec; ProcessSerialNumber psn; psn.highLongOfPSN = 0; psn.lowLongOfPSN = kCurrentProcess; AECreateDesc (typeProcessSerialNumber, (Ptr) &psn, sizeof (psn), &adr); ec = AECreateAppleEvent ( vclass, vtoken, &adr, kAutoGenerateReturnID, kAnyTransactionID, event); AEDisposeDesc (&adr); IACglobals.errorcode = ec; return (ec == noErr); } /*IACnewsystemverb*/
OSStatus SendOpenAE( AEDescList list ) { OSStatus err; AEAddressDesc theAddress; AppleEvent dummyReply; AppleEvent theEvent; theAddress.descriptorType = typeNull; theAddress.dataHandle = NULL; dummyReply.descriptorType = typeNull; dummyReply.dataHandle = NULL; theEvent.descriptorType = typeNull; theEvent.dataHandle = NULL; do { ProcessSerialNumber psn; err = GetCurrentProcess(&psn); if ( err != noErr) break; err =AECreateDesc(typeProcessSerialNumber, &psn, sizeof(ProcessSerialNumber), &theAddress); if ( err != noErr) break; err = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &theAddress, kAutoGenerateReturnID, kAnyTransactionID, &theEvent); if ( err != noErr) break; err = AEPutParamDesc(&theEvent, keyDirectObject, &list); if ( err != noErr) break; err = AESend(&theEvent, &dummyReply, kAENoReply, kAENormalPriority, kAEDefaultTimeout, NULL, NULL); if ( err != noErr) break; } while (false); if ( theAddress.dataHandle != NULL ) { AEDisposeDesc( &theAddress ); } if ( dummyReply.dataHandle != NULL ) { AEDisposeDesc( &dummyReply ); } if ( theEvent.dataHandle != NULL ) { AEDisposeDesc( &theEvent ); } return err; }
// DestoryWacomContext // // This function will instruct the Tablet Driver to delete a context that your // application created. Please be nice and destroy all contexts you create // before your application quits. // // parameters: UInt32 contextID - The ID returned to you when you created the // context. // // returns: a contextID and noErr on success, else an AE error code ////////////////////////////////////////////////////////////////////////////// OSErr DestoryWacomContext(UInt32 contextID) { AEDesc driverTarget,nullDesc,keyData,tObjSpecifier; AppleEvent aeSend; OSErr err; err = GetTabletDriverTarget(&driverTarget); if(err) { return err; } err = AECreateAppleEvent(kAECoreSuite, kAEDelete, &driverTarget, kAutoGenerateReturnID, kAnyTransactionID, &aeSend); // Now tell the AE what to destroy //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 we want to destroy sizeof(contextID), &keyData ); err = CreateObjSpecifier(cContext, // We want to destroy a context &nullDesc, // This is the last item in the chain formUniqueID, // 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 err = AEPutParamDesc( &aeSend, keyDirectObject, &tObjSpecifier); // 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);
void Moose::launchAudioscrobbler( const std::vector<std::string>& vargs ) { FSRef appRef; LSFindApplicationForInfo( kLSUnknownCreator, CFSTR( AUDIOSCROBBLER_BUNDLEID ), NULL, &appRef, NULL ); const void* arg[vargs.size()]; int index(0); AEDescList argAEList; AECreateList( NULL, 0, FALSE, &argAEList ); for( std::vector<std::string>::const_iterator i = vargs.begin(); i != vargs.end(); i++ ) { arg[index++] = CFStringCreateWithCString( NULL, i->c_str(), kCFStringEncodingUTF8 ); AEPutPtr( &argAEList, 0, typeChar, i->c_str(), i->length()); } LSApplicationParameters params; params.version = 0; params.flags = kLSLaunchAndHide | kLSLaunchDontSwitch | kLSLaunchAsync;; params.application = &appRef; params.asyncLaunchRefCon = NULL; params.environment = NULL; CFArrayRef args = CFArrayCreate( NULL, ((const void**)arg), vargs.size(), NULL); params.argv = args; AEAddressDesc target; AECreateDesc( typeApplicationBundleID, CFSTR( AUDIOSCROBBLER_BUNDLEID ), 16, &target); AppleEvent event; AECreateAppleEvent ( kCoreEventClass, kAEReopenApplication , &target, kAutoGenerateReturnID, kAnyTransactionID, &event ); AEPutParamDesc( &event, keyAEPropData, &argAEList ); params.initialEvent = &event; LSOpenApplication( ¶ms, NULL ); AEDisposeDesc( &argAEList ); AEDisposeDesc( &target ); }
// 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);
OSStatus SendAppleEventToSystemProcess(AEEventID EventToSend) { AEAddressDesc targetDesc; static const ProcessSerialNumber kPSNOfSystemProcess = { 0, kSystemProcess }; AppleEvent eventReply = {typeNull, NULL}; AppleEvent appleEventToSend = {typeNull, NULL}; OSStatus error = noErr; error = AECreateDesc(typeProcessSerialNumber, &kPSNOfSystemProcess, sizeof(kPSNOfSystemProcess), &targetDesc); if (error != noErr) { return(error); } error = AECreateAppleEvent(kCoreEventClass, EventToSend, &targetDesc, kAutoGenerateReturnID, kAnyTransactionID, &appleEventToSend); AEDisposeDesc(&targetDesc); if (error != noErr) { return(error); } error = AESend(&appleEventToSend, &eventReply, kAENoReply, kAENormalPriority, kAEDefaultTimeout, NULL, NULL); AEDisposeDesc(&appleEventToSend); if (error != noErr) { return(error); } AEDisposeDesc(&eventReply); return(error); //if this is noErr then we are successful }
static OSStatus SendEventToSystemEventsWithParameters( AEEventClass theClass, AEEventID theEvent, AppleEvent * reply, ... ) // Creates an Apple event and sends it to the System Events // process. theClass and theEvent are the event class and ID, // respectively. If reply is not NULL, the caller gets a copy // of the reply. Following reply is a variable number of Apple event // parameters. Each AE parameter is made up of two C parameters, // the first being the AEKeyword, the second being a pointer to // the AEDesc for that parameter. This list is terminated by an // AEKeyword of value 0. // // You typically call this as: // // err = SendEventToSystemEventsWithParameters( // kClass, // kEvent, // NULL, // param1_keyword, param1_desc_ptr, // param2_keyword, param2_desc_ptr, // 0 // ); // // On entry, reply must be NULL or *reply must be the null AEDesc. // On success, if reply is not NULL, *reply will be the AE reply // (that is, not a null desc). // On error, if reply is not NULL, *reply will be the null AEDesc. { OSStatus err; ProcessSerialNumber psn; AppleEvent target; AppleEvent event; AppleEvent localReply; AEDescList results; assert( (reply == NULL) || (reply->descriptorType == typeNull) ); target = kAENull; event = kAENull; localReply = kAENull; results = kAENull; // Create Apple event. err = FindSystemEvents(&psn); if (err == noErr) { err = AECreateDesc(typeProcessSerialNumber, &psn, sizeof(psn), &target); } if (err == noErr) { err = AECreateAppleEvent( theClass, theEvent, &target, kAutoGenerateReturnID, kAnyTransactionID, &event ); } // Handle varargs parameters. if (err == noErr) { va_list ap; AEKeyword thisKeyword; const AEDesc * thisDesc; va_start(ap, reply); do { thisKeyword = va_arg(ap, AEKeyword); if (thisKeyword != 0) { thisDesc = va_arg(ap, const AEDesc *); assert(thisDesc != NULL); err = AEPutParamDesc(&event, thisKeyword, thisDesc); } } while ( (err == noErr) && (thisKeyword != 0) ); va_end(ap); }
// 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;
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;
// 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);
OSErr FinderLaunch(long nTargets, FSSpec *targetList) { OSErr err; AppleEvent theAEvent, theReply; AEAddressDesc fndrAddress; AEDescList targetListDesc; OSType fndrCreator; Boolean wasChanged; AliasHandle targetAlias; long index; /* verify parameters */ if ((nTargets == 0) || (targetList == NULL)) return paramErr; /* set up locals */ AECreateDesc(typeNull, NULL, 0, &theAEvent); AECreateDesc(typeNull, NULL, 0, &fndrAddress); AECreateDesc(typeNull, NULL, 0, &theReply); AECreateDesc(typeNull, NULL, 0, &targetListDesc); targetAlias = NULL; fndrCreator = 'MACS'; /* create an open documents event targeting the finder */ err = AECreateDesc(typeApplSignature, (Ptr) &fndrCreator, sizeof(fndrCreator), &fndrAddress); if (err != noErr) goto bail; err = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &fndrAddress, kAutoGenerateReturnID, kAnyTransactionID, &theAEvent); if (err != noErr) goto bail; /* create the list of files to open */ err = AECreateList(NULL, 0, false, &targetListDesc); if (err != noErr) goto bail; for ( index=0; index < nTargets; index++) { if (targetAlias == NULL) err = NewAlias(NULL, (targetList + index), &targetAlias); else err = UpdateAlias(NULL, (targetList + index), targetAlias, &wasChanged); if (err != noErr) goto bail; HLock((Handle) targetAlias); err = AEPutPtr(&targetListDesc, (index + 1), typeAlias, *targetAlias, GetHandleSize((Handle) targetAlias)); HUnlock((Handle) targetAlias); if (err != noErr) goto bail; } /* add the file list to the apple event */ err = AEPutParamDesc(&theAEvent, keyDirectObject, &targetListDesc); if (err != noErr) goto bail; /* send the event to the Finder */ err = AESend(&theAEvent, &theReply, kAENoReply, kAENormalPriority, kAEDefaultTimeout, NULL, NULL); /* clean up and leave */ bail: if (targetAlias != NULL) DisposeHandle((Handle) targetAlias); AEDisposeDesc(&targetListDesc); AEDisposeDesc(&theAEvent); AEDisposeDesc(&fndrAddress); AEDisposeDesc(&theReply); return err; }
// 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 QuitBOINCManager(OSType signature) { bool done = false; ProcessSerialNumber thisPSN; ProcessInfoRec thisPIR; OSErr err = noErr; Str63 thisProcessName; AEAddressDesc thisPSNDesc; AppleEvent thisQuitEvent, thisReplyEvent; thisPIR.processInfoLength = sizeof (ProcessInfoRec); thisPIR.processName = thisProcessName; thisPIR.processAppSpec = nil; thisPSN.highLongOfPSN = 0; thisPSN.lowLongOfPSN = kNoProcess; while (done == false) { err = GetNextProcess(&thisPSN); if (err == procNotFound) done = true; // apparently the demo app isn't running. Odd but not impossible else { err = GetProcessInformation(&thisPSN,&thisPIR); if (err != noErr) goto bail; if (thisPIR.processSignature == signature) { // is it or target process? err = AECreateDesc(typeProcessSerialNumber, (Ptr)&thisPSN, sizeof(thisPSN), &thisPSNDesc); if (err != noErr) goto bail; // Create the 'quit' Apple event for this process. err = AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &thisPSNDesc, kAutoGenerateReturnID, kAnyTransactionID, &thisQuitEvent); if (err != noErr) { AEDisposeDesc (&thisPSNDesc); goto bail; // don't know how this could happen, but limp gamely onward } // send the event err = AESend(&thisQuitEvent, &thisReplyEvent, kAEWaitReply, kAENormalPriority, kAEDefaultTimeout, 0L, 0L); AEDisposeDesc (&thisQuitEvent); AEDisposeDesc (&thisPSNDesc); #if 0 if (err == errAETimeout) { pid_t thisPID; err = GetProcessPID(&thisPSN , &thisPID); if (err == noErr) err = kill(thisPID, SIGKILL); } #endif done = true; // we've killed the process, presumably } } } bail: return err; }
void Utils::Misc::shutdownComputer(const ShutdownDialogAction &action) { #if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) && defined(QT_DBUS_LIB) // Use dbus to power off / suspend the system if (action != ShutdownDialogAction::Shutdown) { // Some recent systems use systemd's logind QDBusInterface login1Iface("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", QDBusConnection::systemBus()); if (login1Iface.isValid()) { if (action == ShutdownDialogAction::Suspend) login1Iface.call("Suspend", false); else login1Iface.call("Hibernate", false); return; } // Else, other recent systems use UPower QDBusInterface upowerIface("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", QDBusConnection::systemBus()); if (upowerIface.isValid()) { if (action == ShutdownDialogAction::Suspend) upowerIface.call("Suspend"); else upowerIface.call("Hibernate"); return; } // HAL (older systems) QDBusInterface halIface("org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer", "org.freedesktop.Hal.Device.SystemPowerManagement", QDBusConnection::systemBus()); if (action == ShutdownDialogAction::Suspend) halIface.call("Suspend", 5); else halIface.call("Hibernate"); } else { // Some recent systems use systemd's logind QDBusInterface login1Iface("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", QDBusConnection::systemBus()); if (login1Iface.isValid()) { login1Iface.call("PowerOff", false); return; } // Else, other recent systems use ConsoleKit QDBusInterface consolekitIface("org.freedesktop.ConsoleKit", "/org/freedesktop/ConsoleKit/Manager", "org.freedesktop.ConsoleKit.Manager", QDBusConnection::systemBus()); if (consolekitIface.isValid()) { consolekitIface.call("Stop"); return; } // HAL (older systems) QDBusInterface halIface("org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer", "org.freedesktop.Hal.Device.SystemPowerManagement", QDBusConnection::systemBus()); halIface.call("Shutdown"); } #endif #ifdef Q_OS_MAC AEEventID EventToSend; if (action != ShutdownDialogAction::Shutdown) EventToSend = kAESleep; else EventToSend = kAEShutDown; AEAddressDesc targetDesc; static const ProcessSerialNumber kPSNOfSystemProcess = { 0, kSystemProcess }; AppleEvent eventReply = {typeNull, NULL}; AppleEvent appleEventToSend = {typeNull, NULL}; OSStatus error = AECreateDesc(typeProcessSerialNumber, &kPSNOfSystemProcess, sizeof(kPSNOfSystemProcess), &targetDesc); if (error != noErr) return; error = AECreateAppleEvent(kCoreEventClass, EventToSend, &targetDesc, kAutoGenerateReturnID, kAnyTransactionID, &appleEventToSend); AEDisposeDesc(&targetDesc); if (error != noErr) return; error = AESend(&appleEventToSend, &eventReply, kAENoReply, kAENormalPriority, kAEDefaultTimeout, NULL, NULL); AEDisposeDesc(&appleEventToSend); if (error != noErr) return; AEDisposeDesc(&eventReply); #endif #ifdef Q_OS_WIN HANDLE hToken; // handle to process token TOKEN_PRIVILEGES tkp; // pointer to token structure if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return; // Get the LUID for shutdown privilege. LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; // one privilege to set tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // Get shutdown privilege for this process. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); // Cannot test the return value of AdjustTokenPrivileges. if (GetLastError() != ERROR_SUCCESS) return; if (action == ShutdownDialogAction::Suspend) SetSuspendState(false, false, false); else if (action == ShutdownDialogAction::Hibernate) SetSuspendState(true, false, false); else InitiateSystemShutdownA(0, QCoreApplication::translate("misc", "qBittorrent will shutdown the computer now because all downloads are complete.").toLocal8Bit().data(), 10, true, false); // Disable shutdown privilege. tkp.Privileges[0].Attributes = 0; AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); #endif }
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; }
OSErr FinderLaunch(const char *target) { OSErr err; AppleEvent theAEvent, theReply; AEAddressDesc fndrAddress; AEDescList targetListDesc; OSType fndrCreator; AliasHandle targetAlias; FSSpec fileinfo; FSRef privateInfo; /* * FSPathMakeRef needs (UInt8 *) as its first argument, but my current * understanding is that this is "just" a string but in an exlicitly * 8-bit code. Thus "char *" ought to suffice UNLESS you are compiling in a * world where char is a 16-bit item or some other wide-char messing about is * happening. The C compiler with 10.3 adjusted things without an explicit * cast hear and gave a warning. WIth 10.4 it gives an error. * ACN, August 2005 */ err = FSPathMakeRef((const UInt8 *)target, &privateInfo, NULL); #ifdef DEBUG printf("FSPathMakeRef()-> %d\n", err); #endif err = FSGetCatalogInfo(&privateInfo, kFSCatInfoNone, NULL, NULL, &fileinfo, NULL); #ifdef DEBUG printf("FSGetCatalogInfo()-> %d\n",err); #endif /* set up locals */ AECreateDesc(typeNull, NULL, 0, &theAEvent); AECreateDesc(typeNull, NULL, 0, &fndrAddress); AECreateDesc(typeNull, NULL, 0, &theReply); AECreateDesc(typeNull, NULL, 0, &targetListDesc); targetAlias = NULL; fndrCreator = 'MACS'; /* create an open documents event targeting the finder */ err = AECreateDesc(typeApplSignature, (Ptr) &fndrCreator, sizeof(fndrCreator), &fndrAddress); #ifdef DEBUG printf("AECreateDesc()-> %d\n",err); #endif if (err == noErr) { err = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &fndrAddress, kAutoGenerateReturnID, kAnyTransactionID, &theAEvent); #ifdef DEBUG printf("AECreateAppleEvent()-> %d\n",err); #endif } if (err == noErr) { err = AECreateList(NULL, 0, false, &targetListDesc); #ifdef DEBUG printf("AECreateList()-> %d\n", err); #endif } if (err == noErr) { err = NewAlias(NULL, &fileinfo, &targetAlias); #ifdef DEBUG printf("NewAlias()-> %d\n",err); #endif if (err == noErr) { HLock((Handle) targetAlias); err = AEPutPtr(&targetListDesc, 1, typeAlias, *targetAlias, GetHandleSize((Handle) targetAlias)); #ifdef DEBUG printf("AEPutPtr()-> %d\n",err); #endif HUnlock((Handle) targetAlias); } } /* add the file list to the apple event */ if( err == noErr ) { err = AEPutParamDesc(&theAEvent, keyDirectObject, &targetListDesc); #ifdef DEBUG printf("AEPutParamDesc()-> %d\n",err); #endif } if (err == noErr) { /* send the event to the Finder */ err = AESend(&theAEvent, &theReply, kAENoReply, kAENormalPriority, kAEDefaultTimeout, NULL, NULL); #ifdef DEBUG printf("AESend()-> %d\n",err); #endif } /* clean up and leave */ if (targetAlias != NULL) DisposeHandle((Handle) targetAlias); AEDisposeDesc(&targetListDesc); AEDisposeDesc(&theAEvent); AEDisposeDesc(&fndrAddress); AEDisposeDesc(&theReply); return err; }
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; }
/* *---------------------------------------------------------------------- * * GetFinderFont -- * * Gets the "views" font of the Macintosh Finder * * Results: * Standard Tcl result, and sets finderID to the font family * id for the current finder font. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int GetFinderFont(int *finderID) { OSErr err = noErr; OSType finderPrefs, viewFont = 'vfnt'; DescType returnType; Size returnSize; long result, sys8Mask = 0x0800; static AppleEvent outgoingAevt = {typeNull, NULL}; AppleEvent returnAevt; AEAddressDesc fndrAddress; AEDesc nullContainer = {typeNull, NULL}, tempDesc = {typeNull, NULL}, tempDesc2 = {typeNull, NULL}, finalDesc = {typeNull, NULL}; const OSType finderSignature = 'MACS'; if (outgoingAevt.descriptorType == typeNull) { if ((Gestalt(gestaltSystemVersion, &result) != noErr) || (result >= sys8Mask)) { finderPrefs = 'pfrp'; } else { finderPrefs = 'pvwp'; } AECreateDesc(typeApplSignature, &finderSignature, sizeof(finderSignature), &fndrAddress); err = AECreateAppleEvent(kAECoreSuite, kAEGetData, &fndrAddress, kAutoGenerateReturnID, kAnyTransactionID, &outgoingAevt); AEDisposeDesc(&fndrAddress); /* * The structure is: * the property view font ('vfnt') * of the property view preferences ('pvwp') * of the Null Container (i.e. the Finder itself). */ AECreateDesc(typeType, &finderPrefs, sizeof(finderPrefs), &tempDesc); err = CreateObjSpecifier(typeType, &nullContainer, formPropertyID, &tempDesc, true, &tempDesc2); AECreateDesc(typeType, &viewFont, sizeof(viewFont), &tempDesc); err = CreateObjSpecifier(typeType, &tempDesc2, formPropertyID, &tempDesc, true, &finalDesc); AEPutKeyDesc(&outgoingAevt, keyDirectObject, &finalDesc); AEDisposeDesc(&finalDesc); } err = AESend(&outgoingAevt, &returnAevt, kAEWaitReply, kAEHighPriority, kAEDefaultTimeout, NULL, NULL); if (err == noErr) { err = AEGetKeyPtr(&returnAevt, keyDirectObject, typeInteger, &returnType, (void *) finderID, sizeof(int), &returnSize); if (err == noErr) { return TCL_OK; } } return TCL_ERROR; }
static VALUE rbosa_app_send_event (VALUE self, VALUE event_class, VALUE event_id, VALUE params, VALUE need_retval) { OSErr error; AppleEvent ae; AppleEvent reply; VALUE rb_timeout; SInt32 timeout; VALUE rb_reply; unsigned has_direct_param; error = AECreateAppleEvent (RVAL2FOURCHAR (event_class), RVAL2FOURCHAR (event_id), rbosa_element_aedesc (self), kAutoGenerateReturnID, kAnyTransactionID, &ae); if (error != noErr) rb_raise (rb_eArgError, "Cannot create Apple Event '%s%s' : %s (%d)", RVAL2CSTR (event_class), RVAL2CSTR (event_id), error_code_to_string (error), error); has_direct_param = 0; if (!NIL_P (params)) { unsigned i; for (i = 0; i < RARRAY (params)->len; i++) { VALUE ary; VALUE type; VALUE element; FourCharCode code; ary = RARRAY (params)->ptr[i]; if (NIL_P (ary) || RARRAY (ary)->len != 2) continue; type = RARRAY (ary)->ptr[0]; element = RARRAY (ary)->ptr[1]; code = RVAL2FOURCHAR (type); if (code == '----') has_direct_param = 1; error = AEPutParamDesc (&ae, RVAL2FOURCHAR (type), rbosa_element_aedesc (element)); if (error != noErr) { AEDisposeDesc (&ae); rb_raise (rb_eArgError, "Cannot add Apple Event parameter '%s' : %s (%d)", RVAL2CSTR (type), error_code_to_string (error), error); } } } rb_timeout = rb_iv_get (mOSA, "@timeout"); timeout = NIL_P (rb_timeout) ? kAEDefaultTimeout : NUM2INT (rb_timeout); if (has_direct_param == 0) AEPutAttributePtr (&ae, 'subj', typeNull, NULL, 0); error = AESend (&ae, &reply, (RVAL2CBOOL(need_retval) ? kAEWaitReply : kAENoReply) | kAECanInteract | kAECanSwitchLayer, kAENormalPriority, timeout, NULL, NULL); AEDisposeDesc (&ae); if (error != noErr) rb_raise (rb_eRuntimeError, "Cannot send Apple Event '%s%s' : %s (%d)", RVAL2CSTR (event_class), RVAL2CSTR (event_id), error_code_to_string (error), error); __rbosa_raise_potential_app_error (&reply); if (RTEST (need_retval)) { AEDesc replyObject; AEGetParamDesc (&reply, keyDirectObject, typeWildCard, &replyObject); rb_reply = rbosa_element_make (cOSAElement, &replyObject, self); } else { rb_reply = Qnil; } AEDisposeDesc (&reply); return rb_reply; }