summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Fl_Preferences.cxx58
-rw-r--r--src/drivers/X11/Fl_X11_System_Driver.cxx55
2 files changed, 83 insertions, 30 deletions
diff --git a/src/Fl_Preferences.cxx b/src/Fl_Preferences.cxx
index 83fa3da99..b3c3c9c9f 100644
--- a/src/Fl_Preferences.cxx
+++ b/src/Fl_Preferences.cxx
@@ -63,7 +63,7 @@ static int clocale_sscanf(const char *input, const char *format, ...)
\return a pointer to a static buffer containing the new UUID in ASCII format.
The buffer is overwritten during every call to this function!
*/
-const char *Fl_Preferences::newUUID() {
+const char *Fl_Preferences::new_UUID() {
Fl::system_driver()->newUUID(uuidBuffer);
return uuidBuffer;
}
@@ -126,7 +126,7 @@ unsigned int Fl_Preferences::file_access()
of the pathname componennts. This can be used to check if a preferneces file
already exists.
- \param[out] buffer write the reulting path into this buffer
+ \param[out] buffer write the resulting path into this buffer
\param[in] buffer_size size of the `buffer` in bytes
\param[in] root can be \c USER_L or \c SYSTEM_L for user specific or system
wide preferences
@@ -157,10 +157,16 @@ Fl_Preferences::Root Fl_Preferences::filename( char *buffer, size_t buffer_size,
/**
- The constructor creates a group that manages name/value pairs and
- child groups. Groups are ready for reading and writing at any time.
- The root argument is either `Fl_Preferences::USER_L`
- or `Fl_Preferences::SYSTEM_L`.
+ The constructor creates a group that manages key/value pairs and
+ child groups.
+
+ Preferences can be stored per user using the root type
+ `Fl_Preferences::USER_L`, or stored system-wide using
+ `Fl_Preferences::SYSTEM_L`.
+
+ Groups and key/value pairs can be read and written randomly. Reading undefined
+ values will return the default value. Writing undefined values will create
+ all required groups and key/vlaue pairs.
This constructor creates the <i>base</i> instance for all following entries
and reads the database from disk into memory if it exists.
@@ -192,12 +198,22 @@ Fl_Preferences::Root Fl_Preferences::filename( char *buffer, size_t buffer_size,
check the path member of the passwd struct returned by \c getpwuid(getuid()) .
If all attempts fail, data will be stored in RAM only and be lost when the
app exits.
- The filename and path is then constructed as
- <tt>\$(directory)/.fltk/\$(vendor)/\$(application).prefs</tt> .
- The \c SYSTEM directory is hardcoded as
+
+ The \c SYSTEM preferences filename is hardcoded as
<tt>/etc/fltk/\$(vendor)/\$(application).prefs</tt> .
- \par In FLTK versions before 1.4.0, if \c $HOME was not set, the \c USER path
+ For backward compatibility, the old \c USER `.prefs` file naming scheme
+ <tt>\$(directory)/.fltk/\$(vendor)/\$(application).prefs</tt> is checked first.
+ If that file does not exist, the environment variable `$XDG_CONFIG_HOME` is
+ read as a base directory. If `$XDG_CONFIG_HOME` not set, the base directory
+ defaults to `$HOME/.config/`.
+
+ The user preferences will be stored in
+ <tt>\$(directory)/\$(vendor)/\$(application).prefs</tt>, The user data path
+ will be
+ <tt>\$(directory)/\$(vendor)/\$(application)/</tt>
+
+ In FLTK versions before 1.4.0, if \c $HOME was not set, the \c USER path
would be empty, generating <tt>\$(vendor)/\$(application).prefs</tt>, which
was used relative to the current working directory.
@@ -270,11 +286,11 @@ Fl_Preferences::Fl_Preferences( Fl_Preferences &parent, const char *group ) {
only in local memory and is not associated with a file on disk. The root type
of this databse is set to `Fl_Preferences::MEMORY`.
- * the memory database is \em not shared among multiple instances of the same app
- * memory databses are \em not thread safe
- * all data will be lost when the app quits
+ - the memory database is \em not shared among multiple instances of the same app
+ - memory databses are \em not thread safe
+ - all data will be lost when the app quits
- ```{.cpp}
+ ```
void some_function() {
Fl_Preferences guide( NULL, "Guide" );
guide.set("answer", 42);
@@ -457,7 +473,7 @@ const char *Fl_Preferences::group( int num_group ) {
\param[in] key name of group that is searched for
\return 0 if no group by that name was found
*/
-char Fl_Preferences::groupExists( const char *key ) {
+char Fl_Preferences::group_exists( const char *key ) {
return node->search( key ) ? 1 : 0 ;
}
@@ -470,7 +486,7 @@ char Fl_Preferences::groupExists( const char *key ) {
\param[in] group name of the group to delete
\return 0 if call failed
*/
-char Fl_Preferences::deleteGroup( const char *group ) {
+char Fl_Preferences::delete_group( const char *group ) {
Node *nd = node->search( group );
if ( nd ) return nd->remove();
return 0;
@@ -479,7 +495,7 @@ char Fl_Preferences::deleteGroup( const char *group ) {
/**
Delete all groups.
*/
-char Fl_Preferences::deleteAllGroups() {
+char Fl_Preferences::delete_all_groups() {
node->deleteAllChildren();
return 1;
}
@@ -511,7 +527,7 @@ const char *Fl_Preferences::entry( int index ) {
\param[in] key name of entry that is searched for
\return 0 if entry was not found
*/
-char Fl_Preferences::entryExists( const char *key ) {
+char Fl_Preferences::entry_exists( const char *key ) {
return node->getEntry( key )>=0 ? 1 : 0 ;
}
@@ -523,14 +539,14 @@ char Fl_Preferences::entryExists( const char *key ) {
\param[in] key name of entry to delete
\return 0 if deleting the entry failed
*/
-char Fl_Preferences::deleteEntry( const char *key ) {
+char Fl_Preferences::delete_entry( const char *key ) {
return node->deleteEntry( key );
}
/**
Delete all entries.
*/
-char Fl_Preferences::deleteAllEntries() {
+char Fl_Preferences::delete_all_entries() {
node->deleteAllEntries();
return 1;
}
@@ -1012,7 +1028,7 @@ int Fl_Preferences::size( const char *key ) {
\see Fl_Preferences::Fl_Preferences(Root, const char*, const char*)
*/
-char Fl_Preferences::getUserdataPath( char *path, int pathlen ) {
+char Fl_Preferences::get_userdata_path( char *path, int pathlen ) {
if ( rootNode )
return rootNode->getPath( path, pathlen );
return 0;
diff --git a/src/drivers/X11/Fl_X11_System_Driver.cxx b/src/drivers/X11/Fl_X11_System_Driver.cxx
index 9ffae3d45..71becad49 100644
--- a/src/drivers/X11/Fl_X11_System_Driver.cxx
+++ b/src/drivers/X11/Fl_X11_System_Driver.cxx
@@ -459,19 +459,19 @@ char *Fl_X11_System_Driver::preference_rootnode(Fl_Preferences * /*prefs*/, Fl_P
{
static char *filename = 0L;
if (!filename) filename = (char*)::calloc(1, FL_PATH_MAX);
- const char *e;
+ const char *home;
switch (root&Fl_Preferences::ROOT_MASK) {
case Fl_Preferences::USER:
- e = getenv("HOME");
+ home = getenv("HOME");
// make sure that $HOME is set to an existing directory
- if ( (e==0L) || (e[0]==0) || (::access(e, F_OK)==-1) ) {
+ if ( (home==NULL) || (home[0]==0) || (::access(home, F_OK)==-1) ) {
struct passwd *pw = getpwuid(getuid());
- e = pw->pw_dir;
+ home = pw->pw_dir;
}
- if ( (e==0L) || (e[0]==0) || (::access(e, F_OK)==-1) ) {
- return 0L;
+ if ( (home==0L) || (home[0]==0) || (::access(home, F_OK)==-1) ) {
+ return NULL;
} else {
- strlcpy(filename, e, FL_PATH_MAX);
+ strlcpy(filename, home, FL_PATH_MAX);
if (filename[strlen(filename)-1] != '/')
strlcat(filename, "/", FL_PATH_MAX);
strlcat(filename, ".fltk/", FL_PATH_MAX);
@@ -483,13 +483,50 @@ char *Fl_X11_System_Driver::preference_rootnode(Fl_Preferences * /*prefs*/, Fl_P
}
// Make sure that the parameters are not NULL
- if ( (vendor==0L) || (vendor[0]==0) )
+ if ( (vendor==NULL) || (vendor[0]==0) )
vendor = "unknown";
- if ( (application==0L) || (application[0]==0) )
+ if ( (application==NULL) || (application[0]==0) )
application = "unknown";
snprintf(filename + strlen(filename), FL_PATH_MAX - strlen(filename),
"%s/%s.prefs", vendor, application);
+
+ // If this is the SYSTEM path, we are done
+ if ((root&Fl_Preferences::ROOT_MASK)!=Fl_Preferences::USER)
+ return filename;
+
+ // If the legacy file exists, we are also done
+ if (::access(filename, F_OK)==0)
+ return filename;
+
+ // This is USER mode, and there is no legacy file. Create an XDG conforming path.
+ // Check $XDG_CONFIG_HOME, and if it isn't set, default to $HOME/.config
+ const char *xdg = getenv("XDG_CONFIG_HOME");
+ if (xdg==NULL) {
+ xdg = "~/.config";
+ }
+ filename[0] = 0;
+ if (strncmp(xdg, "~/", 2)==0) {
+ strlcpy(filename, home, FL_PATH_MAX);
+ strlcat(filename, "/", FL_PATH_MAX);
+ strlcat(filename, xdg+2, FL_PATH_MAX);
+ } else if (strncmp(xdg, "$HOME/", 6)==0) {
+ strlcpy(filename, home, FL_PATH_MAX);
+ strlcat(filename, "/", FL_PATH_MAX);
+ strlcat(filename, xdg+6, FL_PATH_MAX);
+ } else if (strncmp(xdg, "${HOME}/", 8)==0) {
+ strlcpy(filename, home, FL_PATH_MAX);
+ strlcat(filename, "/", FL_PATH_MAX);
+ strlcat(filename, xdg+8, FL_PATH_MAX);
+ } else {
+ strlcpy(filename, xdg, FL_PATH_MAX);
+ }
+ strlcat(filename, "/", FL_PATH_MAX);
+ strlcat(filename, vendor, FL_PATH_MAX);
+ strlcat(filename, "/", FL_PATH_MAX);
+ strlcat(filename, application, FL_PATH_MAX);
+ strlcat(filename, ".prefs", FL_PATH_MAX);
+
return filename;
}