// Read a string or array of strings from a CFDictionary for a given key // Return an empty list on error wxArrayString ReadStringListFromCFDict( CFDictionaryRef dictionary, CFStringRef key ) { // Create an empty list wxArrayString results; // Look up the requested key CFTypeRef valueData = CFDictionaryGetValue( dictionary, key ); if( valueData ) { // Value is an array if( CFGetTypeID( valueData ) == CFArrayGetTypeID() ) { CFArrayRef valueList = reinterpret_cast< CFArrayRef >( valueData ); CFTypeRef itemData; wxCFStringRef item; // Look at each item in the array for( CFIndex i = 0, n = CFArrayGetCount( valueList ); i < n; i++ ) { itemData = CFArrayGetValueAtIndex( valueList, i ); // Make sure the item is a string if( CFGetTypeID( itemData ) == CFStringGetTypeID() ) { // wxCFStringRef will automatically CFRelease, so an extra CFRetain is needed item = reinterpret_cast< CFStringRef >( itemData ); wxCFRetain( item.get() ); // Add the string to the list results.Add( item.AsString() ); } } } // Value is a single string - return a list of one item else if( CFGetTypeID( valueData ) == CFStringGetTypeID() ) { // wxCFStringRef will automatically CFRelease, so an extra CFRetain is needed wxCFStringRef value = reinterpret_cast< CFStringRef >( valueData ); wxCFRetain( value.get() ); // Add the string to the list results.Add( value.AsString() ); } } // Return the list. If the dictionary did not contain key, // or contained the wrong data type, the list will be empty return results; }
void OpenUserDataRec::EventProcCBPopupMenuSelect(NavCBRecPtr ioParams) { NavMenuItemSpec * menu = (NavMenuItemSpec *) ioParams->eventData.eventDataParms.param ; const size_t numFilters = m_extensions.GetCount(); if ( menu->menuType < numFilters ) { m_currentfilter = menu->menuType ; if ( m_saveMode ) { int i = menu->menuType ; // isolate the first extension string wxString firstExtension = m_extensions[i].BeforeFirst('|').BeforeFirst(';'); wxString extension = firstExtension.AfterLast('.') ; wxString sfilename ; wxCFStringRef cfString( wxCFRetain( NavDialogGetSaveFileName( ioParams->context ) ) ); sfilename = cfString.AsString() ; int pos = sfilename.Find('.', true) ; if ( pos != wxNOT_FOUND && extension != wxT("*") ) { sfilename = sfilename.Left(pos+1)+extension ; cfString = wxCFStringRef( sfilename , wxFONTENCODING_DEFAULT ) ; NavDialogSetSaveFileName( ioParams->context , cfString ) ; } } } }
wxCFStringRef::wxCFStringRef( const wxString &st , wxFontEncoding WXUNUSED_IN_UNICODE(encoding) ) { if (st.IsEmpty()) { reset( wxCFRetain( CFSTR("") ) ); } else { wxString str = st ; wxMacConvertNewlines13To10( &str ) ; #if wxUSE_UNICODE #if wxUSE_UNICODE_WCHAR // native = wchar_t 4 bytes for us const wchar_t * const data = str.wc_str(); const size_t size = str.length()*sizeof(wchar_t); CFStringBuiltInEncodings cfencoding = kCFStringEncodingUTF32Native; #elif wxUSE_UNICODE_UTF8 // native = utf8 const char * const data = str.utf8_str(); const size_t size = str.utf8_length(); CFStringBuiltInEncodings cfencoding = kCFStringEncodingUTF8; #else #error "unsupported Unicode representation" #endif reset( CFStringCreateWithBytes( kCFAllocatorDefault, (const UInt8*)data, size, cfencoding, false /* no BOM */ ) ); #else // not wxUSE_UNICODE reset( CFStringCreateWithCString( kCFAllocatorSystemDefault , str.c_str() , wxMacGetSystemEncFromFontEnc( encoding ) ) ); #endif } }
// Look up the (locale) display name and icon file associated with a UTI void wxMimeTypesManagerImpl::LoadDisplayDataForUti(const wxString& uti) { // Keys in to Info.plist const static wxCFStringRef docTypesKey( "CFBundleDocumentTypes" ); const static wxCFStringRef descKey( "CFBundleTypeName" ); const static wxCFStringRef iconKey( "CFBundleTypeIconFile" ); // The call for finding the preferred application for a UTI is LSCopyDefaultRoleHandlerForContentType // This returns an empty string on OS X 10.5 // Instead it is necessary to get the primary extension and use LSGetApplicationForInfo wxCFStringRef ext = UTTypeCopyPreferredTagWithClass( wxCFStringRef( uti ), kUTTagClassFilenameExtension ); // Look up the preferred application CFURLRef appUrl; OSStatus status = LSGetApplicationForInfo( kLSUnknownType, kLSUnknownCreator, ext, kLSRolesAll, NULL, &appUrl ); if( status != noErr ) return; // Create a bundle object for that application wxCFRef< CFBundleRef > bundle; bundle = wxCFRef< CFBundleRef >( CFBundleCreate( kCFAllocatorDefault, appUrl ) ); if( !bundle ) return; // Also get the open command while we have the bundle wxCFStringRef cfsAppPath(CFURLCopyFileSystemPath(appUrl, kCFURLPOSIXPathStyle)); m_utiMap[ uti ].application = cfsAppPath.AsString(); // Get all the document type data in this bundle CFTypeRef docTypeData; docTypeData = CFBundleGetValueForInfoDictionaryKey( bundle, docTypesKey ); if( !docTypeData ) return; // Find the document type entry that matches ext CFDictionaryRef docType; docType = GetDocTypeForExt( docTypeData, ext ); if( !docType ) return; // Get the display name for docType wxCFStringRef description = reinterpret_cast< CFStringRef >( CFDictionaryGetValue( docType, descKey ) ); wxCFRetain( description.get() ); m_utiMap[ uti ].description = description.AsString(); // Get the icon path for docType CFStringRef iconFile = reinterpret_cast< CFStringRef > ( CFDictionaryGetValue( docType, iconKey ) ); m_utiMap[ uti ].iconLoc.SetFileName( GetPathForIconFile( bundle, iconFile ) ); }
void wxDataFormat::SetId( const wxString& zId ) { m_type = wxDF_PRIVATE; m_id = zId; if ( m_format != 0 ) { CFRelease( (CFStringRef) m_format ); m_format = 0; } // since it is private, no need to conform to anything ... m_format = (long) wxCFRetain( (CFStringRef) wxCFStringRef(m_id) ); }
/*static*/ int wxLocale::GetSystemLanguage() { CreateLanguagesDB(); // init i to avoid compiler warning size_t i = 0, count = ms_languagesDB->GetCount(); #if defined(__UNIX__) // first get the string identifying the language from the environment wxString langFull; #ifdef __WXMAC__ wxCFRef<CFLocaleRef> userLocaleRef(CFLocaleCopyCurrent()); // because the locale identifier (kCFLocaleIdentifier) is formatted a little bit differently, eg // az_Cyrl_AZ@calendar=buddhist;currency=JPY we just recreate the base info as expected by wx here wxCFStringRef str(wxCFRetain((CFStringRef)CFLocaleGetValue(userLocaleRef, kCFLocaleLanguageCode))); langFull = str.AsString()+"_"; str.reset(wxCFRetain((CFStringRef)CFLocaleGetValue(userLocaleRef, kCFLocaleCountryCode))); langFull += str.AsString(); #else if (!wxGetEnv(wxS("LC_ALL"), &langFull) && !wxGetEnv(wxS("LC_MESSAGES"), &langFull) && !wxGetEnv(wxS("LANG"), &langFull)) { // no language specified, treat it as English return wxLANGUAGE_ENGLISH_US; } if ( langFull == wxS("C") || langFull == wxS("POSIX") ) { // default C locale is English too return wxLANGUAGE_ENGLISH_US; } #endif // the language string has the following form // // lang[_LANG][.encoding][@modifier] // // (see environ(5) in the Open Unix specification) // // where lang is the primary language, LANG is a sublang/territory, // encoding is the charset to use and modifier "allows the user to select // a specific instance of localization data within a single category" // // for example, the following strings are valid: // fr // fr_FR // de_DE.iso88591 // de_DE@euro // de_DE.iso88591@euro // for now we don't use the encoding, although we probably should (doing // translations of the msg catalogs on the fly as required) (TODO) // // we need the modified for languages like Valencian: ca_ES@valencia // though, remember it wxString modifier; size_t posModifier = langFull.find_first_of(wxS("@")); if ( posModifier != wxString::npos ) modifier = langFull.Mid(posModifier); size_t posEndLang = langFull.find_first_of(wxS("@.")); if ( posEndLang != wxString::npos ) { langFull.Truncate(posEndLang); } // do we have just the language (or sublang too)? const bool justLang = langFull.find('_') == wxString::npos; // 0. Make sure the lang is according to latest ISO 639 // (this is necessary because glibc uses iw and in instead // of he and id respectively). // the language itself (second part is the dialect/sublang) wxString langOrig = ExtractLang(langFull); wxString lang; if ( langOrig == wxS("iw")) lang = wxS("he"); else if (langOrig == wxS("in")) lang = wxS("id"); else if (langOrig == wxS("ji")) lang = wxS("yi"); else if (langOrig == wxS("no_NO")) lang = wxS("nb_NO"); else if (langOrig == wxS("no_NY")) lang = wxS("nn_NO"); else if (langOrig == wxS("no")) lang = wxS("nb_NO"); else lang = langOrig; // did we change it? if ( lang != langOrig ) { langFull = lang + ExtractNotLang(langFull); } // 1. Try to find the language either as is: // a) With modifier if set if ( !modifier.empty() ) { wxString langFullWithModifier = langFull + modifier; for ( i = 0; i < count; i++ ) { if ( ms_languagesDB->Item(i).CanonicalName == langFullWithModifier ) break; } } // b) Without modifier if ( modifier.empty() || i == count ) { for ( i = 0; i < count; i++ ) { if ( ms_languagesDB->Item(i).CanonicalName == langFull ) break; } } // 2. If langFull is of the form xx_YY, try to find xx: if ( i == count && !justLang ) { for ( i = 0; i < count; i++ ) { if ( ms_languagesDB->Item(i).CanonicalName == lang ) { break; } } } // 3. If langFull is of the form xx, try to find any xx_YY record: if ( i == count && justLang ) { for ( i = 0; i < count; i++ ) { if ( ExtractLang(ms_languagesDB->Item(i).CanonicalName) == langFull ) { break; } } } if ( i == count ) { // In addition to the format above, we also can have full language // names in LANG env var - for example, SuSE is known to use // LANG="german" - so check for use of non-standard format and try to // find the name in verbose description. for ( i = 0; i < count; i++ ) { if (ms_languagesDB->Item(i).Description.CmpNoCase(langFull) == 0) { break; } } } #elif defined(__WIN32__) LCID lcid = GetUserDefaultLCID(); if ( lcid != 0 ) { wxUint32 lang = PRIMARYLANGID(LANGIDFROMLCID(lcid)); wxUint32 sublang = SUBLANGID(LANGIDFROMLCID(lcid)); for ( i = 0; i < count; i++ ) { if (ms_languagesDB->Item(i).WinLang == lang && ms_languagesDB->Item(i).WinSublang == sublang) { break; } } } //else: leave wxlang == wxLANGUAGE_UNKNOWN #endif // Unix/Win32 if ( i < count ) { // we did find a matching entry, use it return ms_languagesDB->Item(i).Language; } // no info about this language in the database return wxLANGUAGE_UNKNOWN; }
/* static */ wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat)) { CFLocaleRef userLocaleRefRaw; if ( wxGetLocale() ) { userLocaleRefRaw = CFLocaleCreate ( kCFAllocatorDefault, wxCFStringRef(wxGetLocale()->GetCanonicalName()) ); } else // no current locale, use the default one { userLocaleRefRaw = CFLocaleCopyCurrent(); } wxCFRef<CFLocaleRef> userLocaleRef(userLocaleRefRaw); CFStringRef cfstr = 0; switch ( index ) { case wxLOCALE_THOUSANDS_SEP: cfstr = (CFStringRef) CFLocaleGetValue(userLocaleRef, kCFLocaleGroupingSeparator); break; case wxLOCALE_DECIMAL_POINT: cfstr = (CFStringRef) CFLocaleGetValue(userLocaleRef, kCFLocaleDecimalSeparator); break; case wxLOCALE_SHORT_DATE_FMT: case wxLOCALE_LONG_DATE_FMT: case wxLOCALE_DATE_TIME_FMT: case wxLOCALE_TIME_FMT: { CFDateFormatterStyle dateStyle = kCFDateFormatterNoStyle; CFDateFormatterStyle timeStyle = kCFDateFormatterNoStyle; switch (index ) { case wxLOCALE_SHORT_DATE_FMT: dateStyle = kCFDateFormatterShortStyle; break; case wxLOCALE_LONG_DATE_FMT: dateStyle = kCFDateFormatterFullStyle; break; case wxLOCALE_DATE_TIME_FMT: dateStyle = kCFDateFormatterFullStyle; timeStyle = kCFDateFormatterMediumStyle; break; case wxLOCALE_TIME_FMT: timeStyle = kCFDateFormatterMediumStyle; break; default: wxFAIL_MSG( "unexpected time locale" ); return wxString(); } wxCFRef<CFDateFormatterRef> dateFormatter( CFDateFormatterCreate (NULL, userLocaleRef, dateStyle, timeStyle)); wxCFStringRef cfs = wxCFRetain( CFDateFormatterGetFormat(dateFormatter )); wxString format = TranslateFromUnicodeFormat(cfs.AsString()); // we always want full years format.Replace("%y","%Y"); return format; } break; default: wxFAIL_MSG( "Unknown locale info" ); return wxString(); } wxCFStringRef str(wxCFRetain(cfstr)); return str.AsString(); }
// ---------------------------------------------------------------------------- // wxHIDDevice::Create // // nClass is the HID Page such as // kHIDPage_GenericDesktop // nType is the HID Usage such as // kHIDUsage_GD_Joystick,kHIDUsage_GD_Mouse,kHIDUsage_GD_Keyboard // nDev is the device number to use // // ---------------------------------------------------------------------------- bool wxHIDDevice::Create (int nClass, int nType, int nDev) { //Create the mach port if(IOMasterPort(bootstrap_port, &m_pPort) != kIOReturnSuccess) { wxLogSysError(wxT("Could not create mach port")); return false; } //Dictionary that will hold first //the matching dictionary for determining which kind of devices we want, //then later some registry properties from an iterator (see below) // //The call to IOServiceMatching filters down the //the services we want to hid services (and also eats the //dictionary up for us (consumes one reference)) CFMutableDictionaryRef pDictionary = IOServiceMatching(kIOHIDDeviceKey); if(pDictionary == NULL) { wxLogSysError( wxT("IOServiceMatching(kIOHIDDeviceKey) failed") ); return false; } //Here we'll filter down the services to what we want if (nType != -1) { CFNumberRef pType = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &nType); CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsageKey), pType); CFRelease(pType); } if (nClass != -1) { CFNumberRef pClass = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &nClass); CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsagePageKey), pClass); CFRelease(pClass); } //Now get the maching services io_iterator_t pIterator; if( IOServiceGetMatchingServices(m_pPort, pDictionary, &pIterator) != kIOReturnSuccess ) { wxLogSysError(wxT("No Matching HID Services")); return false; } //Were there any devices matched? if(pIterator == 0) return false; // No devices found //Now we iterate through them io_object_t pObject; while ( (pObject = IOIteratorNext(pIterator)) != 0) { if(--nDev != 0) { IOObjectRelease(pObject); continue; } if ( IORegistryEntryCreateCFProperties ( pObject, &pDictionary, kCFAllocatorDefault, kNilOptions ) != KERN_SUCCESS ) { wxLogDebug(wxT("IORegistryEntryCreateCFProperties failed")); } // // Now we get the attributes of each "product" in the iterator // //Get [product] name CFStringRef cfsProduct = (CFStringRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey)); m_szProductName = wxCFStringRef( wxCFRetain(cfsProduct) ).AsString(); //Get the Product ID Key CFNumberRef cfnProductId = (CFNumberRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductIDKey)); if (cfnProductId) { CFNumberGetValue(cfnProductId, kCFNumberIntType, &m_nProductId); } //Get the Vendor ID Key CFNumberRef cfnVendorId = (CFNumberRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDVendorIDKey)); if (cfnVendorId) { CFNumberGetValue(cfnVendorId, kCFNumberIntType, &m_nManufacturerId); } // // End attribute getting // //Create the interface (good grief - long function names!) SInt32 nScore; IOCFPlugInInterface** ppPlugin; if(IOCreatePlugInInterfaceForService(pObject, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &ppPlugin, &nScore) != kIOReturnSuccess) { wxLogSysError(wxT("Could not create HID Interface for product")); return false; } //Now, the final thing we can check before we fall back to asserts //(because the dtor only checks if the device is ok, so if anything //fails from now on the dtor will delete the device anyway, so we can't break from this). //Get the HID interface from the plugin to the mach port if((*ppPlugin)->QueryInterface(ppPlugin, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (void**) &m_ppDevice) != S_OK) { wxLogSysError(wxT("Could not get device interface from HID interface")); return false; } //release the plugin (*ppPlugin)->Release(ppPlugin); //open the HID interface... if ( (*m_ppDevice)->open(m_ppDevice, 0) != S_OK ) { wxLogDebug(wxT("HID device: open failed")); } // //Now the hard part - in order to scan things we need "cookies" // CFArrayRef cfaCookies = (CFArrayRef)CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDElementKey)); BuildCookies(cfaCookies); //cleanup CFRelease(pDictionary); IOObjectRelease(pObject); //iterator cleanup IOObjectRelease(pIterator); return true; } //iterator cleanup IOObjectRelease(pIterator); return false; //no device }//end Create()
wxString wxDataFormat::GetId() const { return wxCFStringRef(wxCFRetain((CFStringRef)m_format)).AsString(); }
static pascal void NavEventProc( NavEventCallbackMessage inSelector, NavCBRecPtr ioParams, NavCallBackUserData ioUserData ) { OpenUserDataRec * data = ( OpenUserDataRec *) ioUserData ; if (inSelector == kNavCBEvent) { } else if ( inSelector == kNavCBStart ) { if (data && !(data->defaultLocation).empty()) { // Set default location for the modern Navigation APIs // Apple Technical Q&A 1151 FSRef theFile; wxMacPathToFSRef(data->defaultLocation, &theFile); AEDesc theLocation = { typeNull, NULL }; if (noErr == ::AECreateDesc(typeFSRef, &theFile, sizeof(FSRef), &theLocation)) ::NavCustomControl(ioParams->context, kNavCtlSetLocation, (void *) &theLocation); } if( data->extensions.GetCount() > 0 ) { NavMenuItemSpec menuItem; memset( &menuItem, 0, sizeof(menuItem) ); menuItem.version = kNavMenuItemSpecVersion; menuItem.menuType = data->currentfilter; ::NavCustomControl(ioParams->context, kNavCtlSelectCustomType, &menuItem); } } else if ( inSelector == kNavCBPopupMenuSelect ) { NavMenuItemSpec * menu = (NavMenuItemSpec *) ioParams->eventData.eventDataParms.param ; const size_t numFilters = data->extensions.GetCount(); if ( menu->menuType < numFilters ) { data->currentfilter = menu->menuType ; if ( data->saveMode ) { int i = menu->menuType ; // isolate the first extension string wxString firstExtension = data->extensions[i].BeforeFirst('|').BeforeFirst(';'); wxString extension = firstExtension.AfterLast('.') ; wxString sfilename ; wxCFStringRef cfString( wxCFRetain( NavDialogGetSaveFileName( ioParams->context ) ) ); sfilename = cfString.AsString() ; int pos = sfilename.Find('.', true) ; if ( pos != wxNOT_FOUND && extension != wxT("*") ) { sfilename = sfilename.Left(pos+1)+extension ; cfString = wxCFStringRef( sfilename , wxFONTENCODING_DEFAULT ) ; NavDialogSetSaveFileName( ioParams->context , cfString ) ; } } } } }
bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding, bool fixedWidthOnly) { wxArrayString fontFamilies ; wxUint32 macEncoding = wxMacGetSystemEncFromFontEnc(encoding) ; { CFArrayRef cfFontFamilies = nil; #if wxOSX_USE_COCOA_OR_CARBON #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) if ( UMAGetSystemVersion() >= 0x1060 ) cfFontFamilies = CTFontManagerCopyAvailableFontFamilyNames(); else #endif { #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6) // // From Apple's QA 1471 http://developer.apple.com/qa/qa2006/qa1471.html // CFMutableArrayRef atsfontnames = CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks);; ATSFontFamilyIterator theFontFamilyIterator = NULL; ATSFontFamilyRef theATSFontFamilyRef = 0; OSStatus status = noErr; // Create the iterator status = ATSFontFamilyIteratorCreate(kATSFontContextLocal, nil,nil, kATSOptionFlagsUnRestrictedScope, &theFontFamilyIterator ); while (status == noErr) { // Get the next font in the iteration. status = ATSFontFamilyIteratorNext( theFontFamilyIterator, &theATSFontFamilyRef ); if(status == noErr) { CFStringRef theName = NULL; ATSFontFamilyGetName(theATSFontFamilyRef, kATSOptionFlagsDefault, &theName); CFArrayAppendValue(atsfontnames, theName); CFRelease(theName); } else if (status == kATSIterationScopeModified) // Make sure the font database hasn't changed. { // reset the iterator status = ATSFontFamilyIteratorReset (kATSFontContextLocal, nil, nil, kATSOptionFlagsUnRestrictedScope, &theFontFamilyIterator); CFArrayRemoveAllValues(atsfontnames); } } ATSFontFamilyIteratorRelease(&theFontFamilyIterator); cfFontFamilies = atsfontnames; #endif } #elif wxOSX_USE_IPHONE cfFontFamilies = CopyAvailableFontFamilyNames(); #endif CFIndex count = CFArrayGetCount(cfFontFamilies); for(CFIndex i = 0; i < count; i++) { CFStringRef fontName = (CFStringRef)CFArrayGetValueAtIndex(cfFontFamilies, i); if ( encoding != wxFONTENCODING_SYSTEM || fixedWidthOnly) { wxCFRef<CTFontRef> font(CTFontCreateWithName(fontName, 12.0, NULL)); if ( encoding != wxFONTENCODING_SYSTEM ) { CFStringEncoding fontFamiliyEncoding = CTFontGetStringEncoding(font); if ( fontFamiliyEncoding != macEncoding ) continue; } if ( fixedWidthOnly ) { CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(font); if ( (traits & kCTFontMonoSpaceTrait) == 0 ) continue; } } wxCFStringRef cfName(wxCFRetain(fontName)) ; fontFamilies.Add(cfName.AsString(wxLocale::GetSystemEncoding())); } CFRelease(cfFontFamilies); } for ( size_t i = 0 ; i < fontFamilies.Count() ; ++i ) { if ( OnFacename( fontFamilies[i] ) == false ) break ; } return true; }