[gimp] Bug 166643 - gimp support for the XDG basedir spec



commit 60e0cfe55ccdc99500d969ab5e9f8ff5f464b3db
Author: Jehan <jehan girinstud io>
Date:   Sun Nov 11 20:20:14 2012 +0900

    Bug 166643 - gimp support for the XDG basedir spec
    
    New configuration directory scheme, consistent across platforms, and
    following standards.
    
    UNIX platforms (except OSX): $XDG_CONFIG_HOME/GIMP/{GIMP_APP_VERSION}
    Windows: %APPDATA%/GIMP/{GIMP_APP_VERSION}
    OSX: NSApplicationSupportDirectory/GIMP/{GIMP_APP_VERSION}

 README                       |    6 +-
 app/core/gimp-user-install.c |   68 ++++++++++++++++++----
 configure.ac                 |    4 +-
 libgimpbase/gimpenv.c        |  132 ++++++++++++++++++++++++------------------
 4 files changed, 137 insertions(+), 73 deletions(-)
---
diff --git a/README b/README
index 29f1af1..552e3cf 100644
--- a/README
+++ b/README
@@ -77,12 +77,12 @@ The look of GIMP's interface can be customized like any other GTK app
 by editing the ~/.gtkrc-2.0 file or by using "themes" (ready-made
 customizations).  For downloadable themes and further details, see
 http://art.gnome.org/themes/gtk2 . Additionally, GIMP reads the file
-~/.gimp-2.8/gtkrc so you can have settings that only apply to GIMP.
+~/.config/GIMP/2.8/gtkrc so you can have settings that only apply to GIMP.
 
 Included is a set of keybindings similar to those in Adobe Photoshop.
 You can find them in the ps-menurc file.  To use them, copy this file
-to ~/.gimp-2.8/menurc. You can also manually change the keybindings to
-any of your choice by editing ~/.gimp-2.8/menurc.
+to ~/.config/GIMP/2.8/menurc. You can also manually change the keybindings to
+any of your choice by editing ~/.config/GIMP/2.8/menurc.
 
 
 Have fun,
diff --git a/app/core/gimp-user-install.c b/app/core/gimp-user-install.c
index 66251f4..3ea5542 100644
--- a/app/core/gimp-user-install.c
+++ b/app/core/gimp-user-install.c
@@ -110,8 +110,10 @@ gimp_user_install_items[] =
 };
 
 
-static gboolean  gimp_user_install_detect_old    (GimpUserInstall  *install,
+static gboolean  user_install_detect_old         (GimpUserInstall  *install,
                                                   const gchar      *gimp_dir);
+static gchar *   user_install_old_style_gimpdir  (void);
+
 static void      user_install_log                (GimpUserInstall  *install,
                                                   const gchar      *format,
                                                   ...) G_GNUC_PRINTF (2, 3);
@@ -134,6 +136,7 @@ static gboolean  user_install_create_files       (GimpUserInstall  *install);
 static gboolean  user_install_migrate_files      (GimpUserInstall  *install);
 
 
+/*  public functions  */
 
 GimpUserInstall *
 gimp_user_install_new (gboolean verbose)
@@ -142,20 +145,17 @@ gimp_user_install_new (gboolean verbose)
 
   install->verbose = verbose;
 
-  gimp_user_install_detect_old (install, gimp_directory ());
+  user_install_detect_old (install, gimp_directory ());
 
-#ifdef PLATFORM_OSX
   if (! install->old_dir)
     {
-      /*  if the default old gimpdir was not found, try the "classic" one
-       *  in the home folder
+      /* if the default XDG-style config directory was not found, try
+       * the "old-style" path in the home folder.
        */
-      gchar *dir = g_strdup_printf ("%s/.gimp-%s",
-                                    g_get_home_dir (), GIMP_APP_VERSION);
-      gimp_user_install_detect_old (install, dir);
+      gchar *dir = user_install_old_style_gimpdir ();
+      user_install_detect_old (install, dir);
       g_free (dir);
     }
-#endif
 
   return install;
 }
@@ -220,8 +220,8 @@ gimp_user_install_set_log_handler (GimpUserInstall        *install,
 /*  Local functions  */
 
 static gboolean
-gimp_user_install_detect_old (GimpUserInstall *install,
-                              const gchar     *gimp_dir)
+user_install_detect_old (GimpUserInstall *install,
+                         const gchar     *gimp_dir)
 {
   gchar    *dir     = g_strdup (gimp_dir);
   gchar    *version;
@@ -266,6 +266,52 @@ gimp_user_install_detect_old (GimpUserInstall *install,
   return migrate;
 }
 
+static gchar *
+user_install_old_style_gimpdir (void)
+{
+  const gchar *home_dir = g_get_home_dir ();
+  gchar       *gimp_dir = NULL;
+
+  if (home_dir)
+    {
+      gimp_dir = g_build_filename (home_dir, ".gimp-" GIMP_APP_VERSION, NULL);
+    }
+  else
+    {
+      gchar *user_name = g_strdup (g_get_user_name ());
+      gchar *subdir_name;
+
+#ifdef G_OS_WIN32
+      gchar *p = user_name;
+
+      while (*p)
+        {
+          /* Replace funny characters in the user name with an
+           * underscore. The code below also replaces some
+           * characters that in fact are legal in file names, but
+           * who cares, as long as the definitely illegal ones are
+           * caught.
+           */
+          if (!g_ascii_isalnum (*p) && !strchr ("-.,@=", *p))
+            *p = '_';
+          p++;
+        }
+#endif
+
+#ifndef G_OS_WIN32
+      g_message ("warning: no home directory.");
+#endif
+      subdir_name = g_strconcat (".gimp-" GIMP_APP_VERSION ".", user_name, NULL);
+      gimp_dir = g_build_filename (gimp_data_directory (),
+                                   subdir_name,
+                                   NULL);
+      g_free (user_name);
+      g_free (subdir_name);
+    }
+
+  return gimp_dir;
+}
+
 static void
 user_install_log (GimpUserInstall *install,
                   const gchar     *format,
diff --git a/configure.ac b/configure.ac
index 05af74b..6b7c6c6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1985,8 +1985,8 @@ AM_CONDITIONAL(ENABLE_GIMP_CONSOLE, test "x$enable_gimp_console" != xno)
 
 
 # Possibly change default gimpdir from .gimp-major.minor
-gimpdir=.gimp-gimp_user_version
-AC_ARG_WITH(gimpdir, [  --with-gimpdir=DIR      change default gimpdir from .gimp-gimp_user_version to DIR],
+gimpdir=GIMP
+AC_ARG_WITH(gimpdir, [  --with-gimpdir=DIR      change default gimpdir from $XDG_CONFIG_HOME/GIMP/gimp_user_version to $XDG_CONFIG_HOME/DIR/gimp_user_version],
 if eval "test x$with_gimpdir != x"; then
   if eval "test x$with_gimpdir != xyes"; then
     gimpdir=$with_gimpdir
diff --git a/libgimpbase/gimpenv.c b/libgimpbase/gimpenv.c
index bc25f4a..71384d8 100644
--- a/libgimpbase/gimpenv.c
+++ b/libgimpbase/gimpenv.c
@@ -63,6 +63,20 @@
 #define gid_t gint
 #define geteuid() 0
 #define getegid() 0
+
+/* This is a hack for Windows known directory support.
+ * DATADIR (autotools-generated constant) is a type defined in objidl.h
+ * so we must #undef it before including shlobj.h in order to avoid a
+ * name clash. */
+static const char* datadir = DATADIR;
+#undef DATADIR
+#include <shlobj.h>
+#define DATADIR datadir
+/* Constant available since Shell32.dll 4.72 */
+#ifndef CSIDL_APPDATA
+#define CSIDL_APPDATA 0x001a
+#endif
+
 #endif
 
 
@@ -76,8 +90,11 @@
  **/
 
 
-static gchar * gimp_env_get_dir (const gchar *gimp_env_name,
-                                 const gchar *env_dir);
+static gchar * gimp_env_get_dir   (const gchar *gimp_env_name,
+                                   const gchar *env_dir);
+#ifdef G_OS_WIN32
+static gchar * get_special_folder (gint         csidl);
+#endif
 
 
 const guint gimp_major_version = GIMP_MAJOR_VERSION;
@@ -146,15 +163,26 @@ gimp_env_init (gboolean plug_in)
  * to be a subdirectory of gimp_data_directory().
  *
  * The usual case is that no GIMP2_DIRECTORY environment variable
- * exists, and then we use the GIMPDIR subdirectory of the home
- * directory. If no home directory exists, we use a per-user
- * subdirectory of gimp_data_directory().  In any case, we always
- * return some non-empty string, whether it corresponds to an existing
- * directory or not.
+ * exists, and then we use the GIMPDIR subdirectory of the local
+ * configuration directory:
+ *
+ * - UNIX: $XDG_CONFIG_HOME (defaults to $HOME/.config/)
+ *
+ * - Windows: CSIDL_APPDATA
+ *
+ * - OSX (UNIX exception): the Application Support Directory.
+ *
+ * If neither the configuration nor home directory exist,
+ * g_get_user_config_dir() will return {tmp}/{user_name}/.config/ where
+ * the temporary directory {tmp} and the {user_name} are determined
+ * according to platform rules.
+ *
+ * In any case, we always return some non-empty string, whether it
+ * corresponds to an existing directory or not.
  *
  * The returned string is owned by GIMP and must not be modified or
  * freed. The returned string is in the encoding used for filenames by
- * GLib, which isn't necessarily UTF-8. (On Windows it always is
+ * GLib, which isn't necessarily UTF-8 (on Windows it is always
  * UTF-8.)
  *
  * Returns: The user-specific GIMP settings directory.
@@ -166,7 +194,6 @@ gimp_directory (void)
   static gchar *last_env_gimp_dir = NULL;
 
   const gchar  *env_gimp_dir;
-  const gchar  *home_dir;
 
   env_gimp_dir = g_getenv ("GIMP2_DIRECTORY");
 
@@ -205,8 +232,6 @@ gimp_directory (void)
   g_free (last_env_gimp_dir);
   last_env_gimp_dir = g_strdup (env_gimp_dir);
 
-  home_dir = g_get_home_dir ();
-
   if (env_gimp_dir)
     {
       if (g_path_is_absolute (env_gimp_dir))
@@ -215,17 +240,12 @@ gimp_directory (void)
         }
       else
         {
+          const gchar *home_dir = g_get_home_dir ();
+
           if (home_dir)
-            {
-              gimp_dir = g_build_filename (home_dir,
-                                           env_gimp_dir,
-                                           NULL);
-            }
+            gimp_dir = g_build_filename (home_dir, env_gimp_dir, NULL);
           else
-            {
-              gimp_dir = g_build_filename (gimp_data_directory (),
-                                           env_gimp_dir, NULL);
-            }
+            gimp_dir = g_build_filename (gimp_data_directory (), env_gimp_dir, NULL);
         }
     }
   else
@@ -243,49 +263,25 @@ gimp_directory (void)
       library_dir = [path objectAtIndex:0];
 
       gimp_dir = g_build_filename ([library_dir UTF8String],
-                                   "GIMP", GIMP_USER_VERSION,
-                                   NULL);
+                                   GIMPDIR, GIMP_USER_VERSION, NULL);
 
       [pool drain];
 
-#else /* ! PLATFORM_OSX */
+#elif defined G_OS_WIN32
 
-      if (home_dir)
-        {
-          gimp_dir = g_build_filename (home_dir, GIMPDIR, NULL);
-        }
-      else
-        {
-          gchar *user_name = g_strdup (g_get_user_name ());
-          gchar *subdir_name;
+      gchar *conf_dir = get_special_folder (CSIDL_APPDATA);
 
-#ifdef G_OS_WIN32
-          gchar *p = user_name;
-
-          while (*p)
-            {
-              /* Replace funny characters in the user name with an
-               * underscore. The code below also replaces some
-               * characters that in fact are legal in file names, but
-               * who cares, as long as the definitely illegal ones are
-               * caught.
-               */
-              if (!g_ascii_isalnum (*p) && !strchr ("-.,@=", *p))
-                *p = '_';
-              p++;
-            }
-#endif
+      gimp_dir = g_build_filename (conf_dir,
+                                   GIMPDIR, GIMP_USER_VERSION, NULL);
+      g_free(conf_dir);
 
-#ifndef G_OS_WIN32
-          g_message ("warning: no home directory.");
-#endif
-          subdir_name = g_strconcat (GIMPDIR ".", user_name, NULL);
-          gimp_dir = g_build_filename (gimp_data_directory (),
-                                       subdir_name,
-                                       NULL);
-          g_free (user_name);
-          g_free (subdir_name);
-        }
+#else /* UNIX */
+
+      /* g_get_user_config_dir () always returns a path as a non-null
+       * and non-empty string
+       */
+      gimp_dir = g_build_filename (g_get_user_config_dir (),
+                                   GIMPDIR, GIMP_USER_VERSION, NULL);
 
 #endif /* PLATFORM_OSX */
     }
@@ -295,6 +291,28 @@ gimp_directory (void)
 
 #ifdef G_OS_WIN32
 
+/* Taken and slightly modified from glib 2.34.0 code. */
+static gchar *
+get_special_folder (int csidl)
+{
+  wchar_t      path[MAX_PATH+1];
+  HRESULT      hr;
+  LPITEMIDLIST pidl = NULL;
+  BOOL         b;
+  gchar       *retval = NULL;
+
+  hr = SHGetFolderLocation (NULL, csidl, NULL, 0, &pidl);
+  if (hr == S_OK)
+    {
+      b = SHGetPathFromIDListW (pidl, path);
+      if (b)
+        retval = g_utf16_to_utf8 (path, -1, NULL, NULL, NULL);
+      CoTaskMemFree (pidl);
+    }
+
+  return retval;
+}
+
 static HMODULE libgimpbase_dll = NULL;
 
 /* Minimal DllMain that just stores the handle to this DLL */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]