Use a more standard approach to save preferences on MacOSX

CFPreferences* seems to be the proper way to handle preferences on MacOSX.
This approach also eliminates a problem where the hard coded preferences
path couldn't be read.

Signed-off-by: Henrik Brautaset Aronsen <subsurface@henrik.synth.no>
[ fixed small coding style issues ]
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Henrik Brautaset Aronsen 2012-01-02 15:14:42 +01:00 committed by Dirk Hohndel
parent 0915d2e691
commit 3232632fd6

97
macos.c
View file

@ -5,10 +5,6 @@
#include <mach-o/dyld.h> #include <mach-o/dyld.h>
#include "gtkosxapplication.h" #include "gtkosxapplication.h"
static CFURLRef fileURL;
static CFPropertyListRef propertyList;
static CFMutableDictionaryRef dict = NULL;
static GtkOSXApplication *theApp; static GtkOSXApplication *theApp;
/* macos defines CFSTR to create a CFString object from a constant, /* macos defines CFSTR to create a CFString object from a constant,
@ -19,94 +15,45 @@ static GtkOSXApplication *theApp;
(_var), kCFStringEncodingMacRoman, \ (_var), kCFStringEncodingMacRoman, \
kCFAllocatorNull) kCFAllocatorNull)
#define SUBSURFACE_PREFERENCES "~/Library/Preferences/org.hohndel.subsurface.plist" #define SUBSURFACE_PREFERENCES CFSTR("org.hohndel.subsurface")
#define REL_ICON_PATH "Resources/Subsurface.icns" #define REL_ICON_PATH "Resources/Subsurface.icns"
#define UI_FONT "Arial Unicode MS 12" #define UI_FONT "Arial Unicode MS 12"
#define DIVELIST_MAC_DEFAULT_FONT "Arial Unicode MS 9" #define DIVELIST_MAC_DEFAULT_FONT "Arial Unicode MS 9"
static void show_error(SInt32 errorCode, char *action)
{
char *errortext;
switch(errorCode) {
case -11: errortext = "kCFURLUnknownSchemeError";
break;
case -12: errortext = "kCFURLResourceNotFoundError";
break;
case -13: errortext = "kCFURLResourceAccessViolationError";
break;
case -14: errortext = "kCFURLRemoteHostUnavailableError";
break;
case -15: errortext = "kCFURLImproperArgumentsError";
break;
case -16: errortext = "kCFURLUnknownPropertyKeyError";
break;
case -17: errortext = "kCFURLPropertyKeyUnavailableError";
break;
case -18: errortext = "kCFURLTimeoutError";
break;
default: errortext = "kCFURLUnknownError";
};
fprintf(stderr, "Error %s preferences: %s\n", action, errortext);
}
void subsurface_open_conf(void) void subsurface_open_conf(void)
{ {
CFStringRef errorString; /* nothing at this time */
CFDataRef resourceData;
Boolean status;
SInt32 errorCode;
fileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
CFSTR(SUBSURFACE_PREFERENCES),// file path name
kCFURLPOSIXPathStyle, // interpret as POSIX path
false ); // is it a directory?
status = CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault,
fileURL, &resourceData,
NULL, NULL, &errorCode);
if (status) {
propertyList = CFPropertyListCreateFromXMLData(kCFAllocatorDefault,
resourceData, kCFPropertyListImmutable,
&errorString);
CFRelease(resourceData);
} else {
show_error(errorCode, "reading");
}
} }
void subsurface_set_conf(char *name, pref_type_t type, const void *value) void subsurface_set_conf(char *name, pref_type_t type, const void *value)
{ {
if (!dict)
dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
switch (type) { switch (type) {
case PREF_BOOL: case PREF_BOOL:
CFDictionarySetValue(dict, CFSTR_VAR(name), value == NULL ? CFSTR("0") : CFSTR("1")); CFPreferencesSetAppValue(CFSTR_VAR(name),
value == NULL ? kCFBooleanFalse : kCFBooleanTrue, SUBSURFACE_PREFERENCES);
break; break;
case PREF_STRING: case PREF_STRING:
CFDictionarySetValue(dict, CFSTR_VAR(name), CFSTR_VAR(value)); CFPreferencesSetAppValue(CFSTR_VAR(name), CFSTR_VAR(value), SUBSURFACE_PREFERENCES);
} }
} }
const void *subsurface_get_conf(char *name, pref_type_t type) const void *subsurface_get_conf(char *name, pref_type_t type)
{ {
CFStringRef dict_entry; Boolean boolpref;
CFPropertyListRef strpref;
/* if no settings exist, we return the value for FALSE */
if (!propertyList)
return NULL;
switch (type) { switch (type) {
case PREF_BOOL: case PREF_BOOL:
dict_entry = CFDictionaryGetValue(propertyList, CFSTR_VAR(name)); boolpref = CFPreferencesGetAppBooleanValue(CFSTR_VAR(name), SUBSURFACE_PREFERENCES, FALSE);
if (dict_entry && ! CFStringCompare(CFSTR("1"), dict_entry, 0)) if (boolpref)
return (void *) 1; return (void *) 1;
else else
return NULL; return NULL;
case PREF_STRING: case PREF_STRING:
return CFStringGetCStringPtr(CFDictionaryGetValue(propertyList, strpref = CFPreferencesCopyAppValue(CFSTR_VAR(name), SUBSURFACE_PREFERENCES);
CFSTR_VAR(name)), kCFStringEncodingMacRoman); if (!strpref)
return NULL;
return CFStringGetCStringPtr(strpref, kCFStringEncodingMacRoman);
} }
/* we shouldn't get here, but having this line makes the compiler happy */ /* we shouldn't get here, but having this line makes the compiler happy */
return NULL; return NULL;
@ -114,19 +61,9 @@ const void *subsurface_get_conf(char *name, pref_type_t type)
void subsurface_close_conf(void) void subsurface_close_conf(void)
{ {
Boolean status; int ok = CFPreferencesAppSynchronize(SUBSURFACE_PREFERENCES);
SInt32 errorCode; if (!ok)
CFDataRef xmlData; fprintf(stderr,"Could not save preferences\n");
propertyList = dict;
dict = NULL;
xmlData = CFPropertyListCreateXMLData(kCFAllocatorDefault, propertyList);
status = CFURLWriteDataAndPropertiesToResource (fileURL, xmlData, NULL, &errorCode);
if (!status) {
show_error(errorCode, "writing");
}
CFRelease(xmlData);
CFRelease(propertyList);
} }
const char *subsurface_USB_name() const char *subsurface_USB_name()