changeset 1381:3ba4853d5b78

Initial attempt at dw_app_dir() for OS/2, Windows and Mac... This function will return the best attempt at determining the application data directory for the current platform. The executable directory on OS/2 or Windows. The application bundle directory on Mac. The "share" folder at the same level as the binary (or /usr/local/share if that can't be determined) plus the binary name on Unix.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Fri, 25 Nov 2011 17:36:59 +0000
parents cc66b6d4b74e
children 3eedfd4f7c5d
files mac/dw.m os2/dw.c os2/dw.def win/dw-mingw.def win/dw.c win/dw.def
diffstat 6 files changed, 87 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/mac/dw.m	Thu Nov 24 06:07:40 2011 +0000
+++ b/mac/dw.m	Fri Nov 25 17:36:59 2011 +0000
@@ -121,6 +121,7 @@
 pthread_key_t _dw_fg_color_key;
 pthread_key_t _dw_bg_color_key;
 SInt32 DWOSMajor, DWOSMinor, DWOSBuild;
+static char _dw_bundle_path[PATH_MAX+1] = { 0 };
 
 /* Create a default colors for a thread */
 void _init_colors(void)
@@ -3032,14 +3033,14 @@
  */
 char *dw_user_dir(void)
 {
-    static char _user_dir[1024] = "";
+    static char _user_dir[PATH_MAX+1] = { 0 };
 
     if(!_user_dir[0])
     {
         char *home = getenv("HOME");
 
         if(home)
-            strcpy(_user_dir, home);
+            strncpy(_user_dir, home, PATH_MAX);
         else
             strcpy(_user_dir, "/");
     }
@@ -3047,6 +3048,15 @@
 }
 
 /*
+ * Returns a pointer to a static buffer which containes the
+ * private application data directory. 
+ */
+char *dw_app_dir(void)
+{
+    return _dw_bundle_path;
+}
+
+/*
  * Displays a debug message on the console...
  * Parameters:
  *           format: printf style format string.
@@ -9604,8 +9614,11 @@
 
         if(app)
         {
-            char pathbuf[PATH_MAX];
-
+            char pathbuf[PATH_MAX+1] = { 0 };
+            size_t len = (size_t)(app - pathcopy);
+            
+            if(len > 0)
+                strncpy(_dw_bundle_path, pathcopy, len + 5);
             *app = 0;
 
             getcwd(pathbuf, PATH_MAX);
@@ -9613,22 +9626,23 @@
             /* If run from a bundle the path seems to be / */
             if(strcmp(pathbuf, "/") == 0)
             {
-                size_t len;
-
-                strncpy(pathbuf, pathcopy, PATH_MAX);
-
-                len = strlen(pathbuf);
-
-                while(len > 0 && pathbuf[len] != '/')
+                char *pos = strrchr(pathcopy, '/');
+
+                if(pos)
                 {
-                    len--;
+                    strncpy(pathbuf, pathcopy, (size_t)(pos - pathcopy));
+                    chdir(pathbuf);
                 }
-                pathbuf[len] = '\0';
-                chdir(pathbuf);
             }
         }
+    }
+    if(pathcopy)
         free(pathcopy);
-    }
+        
+    /* Just in case we can't obtain a path */
+    if(!_dw_bundle_path[0])
+        getcwd(_dw_bundle_path, PATH_MAX);
+    
     /* Get the operating system version */
     Gestalt(gestaltSystemVersionMajor, &DWOSMajor);
     Gestalt(gestaltSystemVersionMinor, &DWOSMinor);
--- a/os2/dw.c	Thu Nov 24 06:07:40 2011 +0000
+++ b/os2/dw.c	Fri Nov 25 17:36:59 2011 +0000
@@ -67,11 +67,12 @@
 
 HWND hwndApp = NULLHANDLE, hwndBubble = NULLHANDLE, hwndBubbleLast = NULLHANDLE, hwndEmph = NULLHANDLE;
 HWND hwndTrayServer = NULLHANDLE, hwndTaskBar = NULLHANDLE;
-;
+
 PRECORDCORE pCoreEmph = NULL;
 ULONG aulBuffer[4];
 HWND lasthcnr = 0, lastitem = 0, popup = 0, desktop;
 HMOD wpconfig = 0, pmprintf = 0;
+static char _dw_exec_dir[MAX_PATH+1] = {0};
 
 unsigned long _colors[] = {
    CLR_BLACK,
@@ -3985,8 +3986,22 @@
    APIRET rc;
    char objnamebuf[300] = "";
 
-   argc = argc; /* keep compiler happy */
-   argv = argv; /* keep compiler happy */
+   /* Setup the private data directory */
+   if(argc > 0 && argv[0])
+   {
+      char *pos = strrchr(argv[0], '\\');
+      
+      /* Just to be safe try the unix style */
+      if(!pos)
+         pos = strrchr(argv[0], '/');
+         
+      if(pos)
+         strncpy(_dw_exec_dir, argv[0], (size_t)(pos - argv[0]));
+   }
+   /* If that failed... just get the current directory */
+   if(!_dw_exec_dir[0])
+      _getcwd(_dw_exec_dir, MAX_PATH);
+      
    if(newthread)
    {
       dwhab = WinInitialize(0);
@@ -11135,7 +11150,7 @@
  */
 char * API dw_user_dir(void)
 {
-   static char _user_dir[1024] = "";
+   static char _user_dir[MAX_PATH+1] = {0};
 
    if(!_user_dir[0])
    {
@@ -11150,6 +11165,15 @@
 }
 
 /*
+ * Returns a pointer to a static buffer which containes the
+ * private application data directory. 
+ */
+char *dw_app_dir(void)
+{
+    return _dw_exec_dir;
+}
+
+/*
  * Call a function from the window (widget)'s context.
  * Parameters:
  *       handle: Window handle of the widget.
--- a/os2/dw.def	Thu Nov 24 06:07:40 2011 +0000
+++ b/os2/dw.def	Fri Nov 25 17:36:59 2011 +0000
@@ -24,6 +24,7 @@
   dw_free                                @22
   dw_main_sleep                          @23
   dw_main_iteration                      @24
+  dw_app_dir                             @25
 
   dw_box_new                             @40
   dw_groupbox_new                        @41
--- a/win/dw-mingw.def	Thu Nov 24 06:07:40 2011 +0000
+++ b/win/dw-mingw.def	Fri Nov 25 17:36:59 2011 +0000
@@ -21,6 +21,7 @@
   dw_free                                @22
   dw_main_sleep                          @23
   dw_main_iteration                      @24
+  dw_app_dir                             @25
 
   dw_box_new                             @40
   dw_groupbox_new                        @41
--- a/win/dw.c	Thu Nov 24 06:07:40 2011 +0000
+++ b/win/dw.c	Fri Nov 25 17:36:59 2011 +0000
@@ -143,7 +143,8 @@
  * an alternate temporary directory if TMP is not set, so we get the value
  * of TEMP and store it here.
  */
-static char _dw_alternate_temp_dir[MAX_PATH+1];
+static char _dw_alternate_temp_dir[MAX_PATH+1] = {0};
+static char _dw_exec_dir[MAX_PATH+1] = {0};
 
 int main(int argc, char *argv[]);
 
@@ -3649,6 +3650,22 @@
    struct GdiplusStartupInput si; 
 #endif
 
+   /* Setup the private data directory */
+   if(argc > 0 && argv[0])
+   {
+      char *pos = strrchr(argv[0], '\\');
+      
+      /* Just to be safe try the unix style */
+      if(!pos)
+         pos = strrchr(argv[0], '/');
+         
+      if(pos)
+         strncpy(_dw_exec_dir, argv[0], (size_t)(pos - argv[0]));
+   }
+   /* If that failed... just get the current directory */
+   if(!_dw_exec_dir[0])
+      GetCurrentDirectory(MAX_PATH, _dw_exec_dir);
+      
    /* Initialize our thread local storage */
    _foreground = TlsAlloc();
    _background = TlsAlloc();
@@ -10714,6 +10731,15 @@
 }
 
 /*
+ * Returns a pointer to a static buffer which containes the
+ * private application data directory. 
+ */
+char *dw_app_dir(void)
+{
+    return _dw_exec_dir;
+}
+
+/*
  * Call a function from the window (widget)'s context.
  * Parameters:
  *       handle: Window handle of the widget.
--- a/win/dw.def	Thu Nov 24 06:07:40 2011 +0000
+++ b/win/dw.def	Fri Nov 25 17:36:59 2011 +0000
@@ -21,6 +21,7 @@
   dw_free                                @22
   dw_main_sleep                          @23
   dw_main_iteration                      @24
+  dw_app_dir                             @25
 
   dw_box_new                             @40
   dw_groupbox_new                        @41