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 "gtkosxapplication.h"
static CFURLRef fileURL;
static CFPropertyListRef propertyList;
static CFMutableDictionaryRef dict = NULL;
static GtkOSXApplication *theApp;
/* macos defines CFSTR to create a CFString object from a constant,
@ -19,94 +15,45 @@ static GtkOSXApplication *theApp;
(_var), kCFStringEncodingMacRoman, \
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 UI_FONT "Arial Unicode MS 12"
#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)
{
CFStringRef errorString;
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");
}
/* nothing at this time */
}
void subsurface_set_conf(char *name, pref_type_t type, const void *value)
{
if (!dict)
dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
switch (type) {
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;
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)
{
CFStringRef dict_entry;
/* if no settings exist, we return the value for FALSE */
if (!propertyList)
return NULL;
Boolean boolpref;
CFPropertyListRef strpref;
switch (type) {
case PREF_BOOL:
dict_entry = CFDictionaryGetValue(propertyList, CFSTR_VAR(name));
if (dict_entry && ! CFStringCompare(CFSTR("1"), dict_entry, 0))
boolpref = CFPreferencesGetAppBooleanValue(CFSTR_VAR(name), SUBSURFACE_PREFERENCES, FALSE);
if (boolpref)
return (void *) 1;
else
return NULL;
case PREF_STRING:
return CFStringGetCStringPtr(CFDictionaryGetValue(propertyList,
CFSTR_VAR(name)), kCFStringEncodingMacRoman);
strpref = CFPreferencesCopyAppValue(CFSTR_VAR(name), SUBSURFACE_PREFERENCES);
if (!strpref)
return NULL;
return CFStringGetCStringPtr(strpref, kCFStringEncodingMacRoman);
}
/* we shouldn't get here, but having this line makes the compiler happy */
return NULL;
@ -114,19 +61,9 @@ const void *subsurface_get_conf(char *name, pref_type_t type)
void subsurface_close_conf(void)
{
Boolean status;
SInt32 errorCode;
CFDataRef xmlData;
propertyList = dict;
dict = NULL;
xmlData = CFPropertyListCreateXMLData(kCFAllocatorDefault, propertyList);
status = CFURLWriteDataAndPropertiesToResource (fileURL, xmlData, NULL, &errorCode);
if (!status) {
show_error(errorCode, "writing");
}
CFRelease(xmlData);
CFRelease(propertyList);
int ok = CFPreferencesAppSynchronize(SUBSURFACE_PREFERENCES);
if (!ok)
fprintf(stderr,"Could not save preferences\n");
}
const char *subsurface_USB_name()