As I recently found out, Mac and Linux wont allow programs to use ~/ when creating directories in the home path - it has to be changed to a fully qualified path instead (eg /home/user).
I'm hoping Gernot will change PLATFORMINFO$("DOCUMENTS") to this, but if not, here is a routine for doing the conversion :
// --------------------------------- //
// Project: The Grid_Mac
// Start: Wednesday, November 25, 2009
// IDE Version: 7.181
INLINE
#ifdef WIN32
// No need to do anything for Windows
#elif LINUX
typedef struct __password {
char *pw_name; // user name
char *pw_passwd; // user password
int pw_uid; // user id
int pw_gid; // group id
char *pw_gecos; // real name
char *pw_dir; // home directory
char *pw_shell; // shell program
} __password;
extern "C" char *getenv(char *);
extern "C" struct __password *getpwuid(int uid);
extern "C" int getuid(void);
#elif OSXUNI
extern "C" int FSFindFolder(int vRefNum,int folderType,int createFolder,char *foundRef);
extern "C" int FSRefMakePath(char *ref,char *path,int maxPathSize);
#endif
ENDINLINE
FUNCTION GetHomeDir$:
LOCAL temp$
temp$=""
INLINE
#if LINUX
char *ptr;
ptr=getenv("$HOME");
if (!ptr)
{
struct __password *password;
password=getpwuid(getuid());
if (password)
{
if (password->pw_dir)
{
temp_Str.assign(password->pw_dir);
}
}
}
else
{
temp_Str.assign(ptr);
}
#elif OSXUNI
char buffer[1024]={0};
char ref[80]={0};
int kUserDomain=-32763;
int kVolumeRootFolderType=('r'<<24)|('o'<<16)|('o'<<8)|('t');
if (!FSFindFolder(kUserDomain,kVolumeRootFolderType,FALSE,(char *) &ref))
{
if (!FSRefMakePath((char *) &ref,(char *) &buffer,sizeof(buffer)-1))
{
temp_Str.assign((char *) &buffer);
}
}
#else
temp_Str.assign(PLATFORMINFO_Str("DOCUMENTS"));
#endif
ENDINLINE
RETURN temp$
ENDFUNCTION
Another nice snippet, many thanks! ;)
Vastly updated to allow the program to find the users Music directory, Picture directory and Shared Data directory :
// --------------------------------- //
// Project: The Grid_Mac
// Start: Wednesday, November 25, 2009
// IDE Version: 7.181
INLINE
#ifdef WIN32
// No need to do anything for Windows
DECLARE(SHGetFolderPathA,"shell32.dll",(HWND,int,HANDLE,DWORD,LPSTR),int);
const int CSIDL_APPDATA = 0x001A;
const int CSIDL_MYPICTURES = 0x0027;
const int CSIDL_MYMUSIC = 0x000D;
const int SHGFP_TYPE_CURRENT= 0;
#elif LINUX
typedef struct __password {
char *pw_name; // user name
char *pw_passwd; // user password
int pw_uid; // user id
int pw_gid; // group id
char *pw_gecos; // real name
char *pw_dir; // home directory
char *pw_shell; // shell program
} __password;
typedef int size_t;
extern "C" char *getenv(char *);
extern "C" struct __password *getpwuid(int uid);
extern "C" int getuid(void);
extern "C" void * malloc ( size_t size );
extern "C" int open(const char *filename,int oflag,int pmode);
extern "C" int close(int fd);
extern "C" size_t strlen ( const char * str );
extern "C" char * strcpy ( char * destination, const char * source );
extern "C" char * strcat ( char * destination, const char * source );
extern "C" void free ( void * ptr );
extern "C" int read(int fd,void *buffer,unsigned int count);
extern "C" char *strdup(const char *s1);
extern "C" int strcmp ( const char * str1, const char * str2 );
extern "C" int strncmp ( const char * str1, const char * str2, size_t num );
extern "C" int sprintf ( char * str, const char * format, ... );
extern "C" void *memset(void *s, int c, size_t n);
#define O_RDONLY 0
#define O_TEXT 0x4000
#elif OSXUNI
extern "C" int FSFindFolder(int vRefNum,int folderType,int createFolder,char *foundRef);
extern "C" int FSRefMakePath(char *ref,char *path,int maxPathSize);
const int kVolumeRootFolderType = ('r'<<24)|('o'<<16)|('o'<<8)|('t');
const int kMusicDocumentsFolderType = 0xB5646F63;
const int kPictureDocumentsFolderType = ('p'<<24)|('d'<<16)|('o'<<8)|('c');
const int kSharedUserDataFolderType = ('s'<<24)|('d'<<16)|('a'<<8)|('t');
int specificCode(int kind,char *store,int size);
#endif
ENDINLINE
INLINE
#ifdef OSXUNI
int specificCode(int kind,char *store,int size)
{
char ref[80]={0};
int kUserDomain=-32763;
if (!FSFindFolder(kUserDomain,kind,FALSE,(char *) &ref))
{
if (!FSRefMakePath((char *) &ref,store,size-1))
{
return true;
}
}
return false;
}
#elif LINUX
// This is needed so that a line can be read properly (as read reads up to a given number of characters)
int readALine(int handle,char *store,int size)
{
char one;
int index;
index=0;
memset(store,(char) 0,size);
while (read(handle,(char *) &one,sizeof(one))>0)
{
if (index<size)
{
*(store+index)=one;
index++;
if (one=='\n')
{
break;
}
}
else
{
break;
}
}
return (strlen(store));
}
// This file is not licenced under the GPL like the rest of the code.
// Its is under the MIT license, to encourage reuse by cut-and-paste.
// Copyright (c) 2007 Red Hat, inc
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation files
// (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// * xdg_user_dir_lookup_with_fallback:
// * @type: a string specifying the type of directory
// * @fallback: value to use if the directory isn't specified by the user
// * @returns: a newly allocated absolute pathname
// *
// * Looks up a XDG user directory of the specified type.
// * Example of types are "DESKTOP" and "DOWNLOAD".
// *
// * In case the user hasn't specified any directory for the specified
// * type the value returned is @fallback.
// *
// * The return value is newly allocated and must be freed with
// * free(). The return value is never NULL if @fallback != NULL, unless
// * out of memory.
// **/
static char *
xdg_user_dir_lookup_with_fallback (const char *type, const char *fallback)
{
int file;
char *home_dir, *config_home, *config_file;
char buffer[512]={0};
char *user_dir;
char *p, *d;
int len;
int relative;
home_dir = getenv ("HOME");
if (home_dir == NULL)
goto error;
config_home = getenv ("XDG_CONFIG_HOME");
if (config_home == NULL || config_home[0] == 0)
{
config_file = (char*) malloc (strlen (home_dir) + strlen ("/.config/user-dirs.dirs") + 1);
if (config_file == NULL)
goto error;
strcpy (config_file, home_dir);
strcat (config_file, "/.config/user-dirs.dirs");
}
else
{
config_file = (char*) malloc (strlen (config_home) + strlen ("/user-dirs.dirs") + 1);
if (config_file == NULL)
goto error;
strcpy (config_file, config_home);
strcat (config_file, "/user-dirs.dirs");
}
file=open(config_file,O_RDONLY,0);
free (config_file);
if (file<0)
{
goto error;
}
user_dir = NULL;
// Original version used fgets, which isn't availiable here, so I had to use read...
while (readALine(file,(char *) &buffer,sizeof(buffer))>0)
{
/* Remove newline at end */
len = strlen (buffer);
if (len > 0 && buffer[len-1] == '\n')
buffer[len-1] = 0;
p = buffer;
while (*p == ' ' || *p == '\t')
p++;
if (strncmp (p, "XDG_", 4) != 0)
continue;
p += 4;
if (strncmp (p, type, strlen (type)) != 0)
continue;
p += strlen (type);
if (strncmp (p, "_DIR", 4) != 0)
continue;
p += 4;
while (*p == ' ' || *p == '\t')
p++;
if (*p != '=')
continue;
p++;
while (*p == ' ' || *p == '\t')
p++;
if (*p != '"')
continue;
p++;
relative = 0;
if (strncmp (p, "$HOME/", 6) == 0)
{
p += 6;
relative = 1;
}
else if (*p != '/')
continue;
if (relative)
{
user_dir = (char*) malloc (strlen (home_dir) + 1 + strlen (p) + 1);
if (user_dir == NULL)
goto error2;
strcpy (user_dir, home_dir);
strcat (user_dir, "/");
}
else
{
user_dir = (char*) malloc (strlen (p) + 1);
if (user_dir == NULL)
goto error2;
*user_dir = 0;
}
d = user_dir + strlen (user_dir);
while (*p && *p != '"')
{
if ((*p == '\\') && (*(p+1) != 0))
p++;
*d++ = *p++;
}
*d = 0;
}
error2:
close (file);
if (user_dir)
return user_dir;
error:
if (fallback)
return strdup (fallback);
return NULL;
}
/**
* xdg_user_dir_lookup:
* @type: a string specifying the type of directory
* @returns: a newly allocated absolute pathname
*
* Looks up a XDG user directory of the specified type.
* Example of types are "DESKTOP" and "DOWNLOAD".
*
* The return value is always != NULL (unless out of memory),
* and if a directory
* for the type is not specified by the user the default
* is the home directory. Except for DESKTOP which defaults
* to ~/Desktop.
*
* The return value is newly allocated and must be freed with
* free().
**/
static char *
xdg_user_dir_lookup (const char *type)
{
char *dir, *home_dir, *user_dir;
dir = xdg_user_dir_lookup_with_fallback (type, NULL);
if (dir != NULL)
return dir;
home_dir = getenv("HOME");
if (home_dir == NULL)
return strdup ("/tmp");
/* Special case desktop for historical compatibility */
if (strcmp (type, "DESKTOP") == 0)
{
user_dir = (char*) malloc (strlen (home_dir) + strlen ("/Desktop") + 1);
if (user_dir == NULL)
return NULL;
strcpy (user_dir, home_dir);
strcat (user_dir, "/Desktop");
return user_dir;
}
return strdup (home_dir);
}
#ifdef STANDALONE_XDG_USER_DIR_LOOKUP
int
main (int argc, char *argv[])
{
if (argc != 2)
{
fprintf (stderr, "Usage %s <dir-type>\n", argv[0]);
exit (1);
}
printf ("%s\n", xdg_user_dir_lookup (argv[1]));
return 0;
}
#endif
#endif
ENDINLINE
FUNCTION GetHomeDir$:
LOCAL temp$
temp$=""
INLINE
#if WIN32
temp_Str.assign(PLATFORMINFO_Str("DOCUMENTS"));
#elif LINUX
char *ptr;
ptr=getenv("$HOME");
if (!ptr)
{
struct __password *password;
password=getpwuid(getuid());
if (password)
{
if (password->pw_dir)
{
temp_Str.assign(password->pw_dir);
}
}
}
else
{
temp_Str.assign(ptr);
}
#elif OSXUNI
char buffer[1024]={0};
char ref[80]={0};
int kUserDomain=-32763;
if (!FSFindFolder(kUserDomain,kVolumeRootFolderType,FALSE,(char *) &ref))
{
if (!FSRefMakePath((char *) &ref,(char *) &buffer,sizeof(buffer)-1))
{
temp_Str.assign((char *) &buffer);
}
}
#else
temp_Str.assign(PLATFORMINFO_Str("DOCUMENTS"));
#endif
ENDINLINE
RETURN temp$
ENDFUNCTION
FUNCTION getPicturesDir$:
LOCAL temp$
temp$=""
INLINE
#ifdef WIN32
char path[261]={0};
if (SHGetFolderPathA(NULL,CSIDL_MYPICTURES,NULL,SHGFP_TYPE_CURRENT,(char *) &path)==0)
{
temp_Str.assign((char *) &path);
}
#elif OSXUNI
char buffer[1024];
if (specificCode(kPictureDocumentsFolderType,(char *) &buffer,sizeof(buffer)))
{
temp_Str.assign((char *) &buffer);
}
#elif LINUX
char *ptr;
ptr=xdg_user_dir_lookup("PICTURES");
if (ptr)
{
temp_Str.assign(ptr);
}
#endif
ENDINLINE
RETURN temp$
ENDFUNCTION
FUNCTION GetMusicDir$:
LOCAL temp$
temp$=""
INLINE
#ifdef WIN32
char path[261]={0};
if (SHGetFolderPathA(NULL,CSIDL_MYMUSIC,NULL,SHGFP_TYPE_CURRENT,(char *) &path)==0)
{
temp_Str.assign((char *) &path);
}
#elif OSXUNI
char buffer[1024];
if (specificCode(kMusicDocumentsFolderType,(char *) &buffer,sizeof(buffer)))
{
temp_Str.assign((char *) &buffer);
}
#elif LINUX
char *ptr;
ptr=xdg_user_dir_lookup("MUSIC");
if (ptr)
{
temp_Str.assign(ptr);
}
#endif
ENDINLINE
RETURN temp$
ENDFUNCTION
FUNCTION GetSharedDataDir$:
LOCAL temp$
temp$=""
INLINE
#ifdef WIN32
char path[261]={0};
if (SHGetFolderPathA(NULL,CSIDL_APPDATA,NULL,SHGFP_TYPE_CURRENT,(char *) &path)==0)
{
temp_Str.assign((char *) &path);
}
#elif OSXUNI
char buffer[1024];
if (specificCode(kSharedUserDataFolderType,(char *) &buffer,sizeof(buffer)))
{
temp_Str.assign((char *) &buffer);
}
#elif LINUX
char *ptr;
ptr=xdg_user_dir_lookup("PUBLICSHARE");
if (ptr)
{
temp_Str.assign(ptr);
}
#endif
ENDINLINE
RETURN temp$
ENDFUNCTION
Excellent work. Will implement that instead of "~". Was a quick shot in the oven.
Great! That'll be useful - especially if you can do the Music, Pictures and Shared Data areas too :)
Its now been updated for Windows CE :
// --------------------------------- //
// Project: Get Application Directories
// Start: Wednesday, November 25, 2009
// IDE Version: 7.181
INLINE
#ifdef _WIN32_WCE
typedef int size_t;
typedef int BOOL;
typedef int LPBOOL;
typedef unsigned int UINT;
typedef char *LPCSTR;
typedef const wchar_t *LPTSTR;
typedef wchar_t WCHAR;
extern "C" BOOL SHGetSpecialFolderPath(HWND hwndOwner,LPTSTR lpszPath,int nFolder,BOOL fCreate);
extern "C" int WideCharToMultiByte(UINT CodePage,DWORD dwFlags,LPCWSTR lpWideCharStr,int cchWideChar,LPSTR lpMultiByteStr,
int cbMultiByte,LPCSTR lpDefaultChar,LPBOOL lpUsedDefaultChar);
extern "C" void * calloc ( size_t num, size_t size );
extern "C" void free ( void * ptr );
extern "C" int sprintf ( char * str, const char * format, ... );
extern "C" size_t wcslen(const wchar_t *str);
const int CSIDL_APPDATA = 0x001A;
const int CSIDL_MYPICTURES = 0x0027;
const int CSIDL_MYMUSIC = 0x000d;
#define MAX_PATH 260
#define CP_ACP 0
#elif WIN32
// No need to do anything for Windows
DECLARE(SHGetFolderPathA,"shell32.dll",(HWND,int,HANDLE,DWORD,LPSTR),int);
const int CSIDL_APPDATA = 0x001A;
const int CSIDL_MYPICTURES = 0x0027;
const int CSIDL_MYMUSIC = 0x000D;
const int SHGFP_TYPE_CURRENT= 0;
#define MAX_PATH 260
#elif LINUX
typedef struct __password {
char *pw_name; // user name
char *pw_passwd; // user password
int pw_uid; // user id
int pw_gid; // group id
char *pw_gecos; // real name
char *pw_dir; // home directory
char *pw_shell; // shell program
} __password;
typedef int size_t;
extern "C" char *getenv(char *);
extern "C" struct __password *getpwuid(int uid);
extern "C" int getuid(void);
extern "C" void * malloc ( size_t size );
extern "C" int open(const char *filename,int oflag,int pmode);
extern "C" int close(int fd);
extern "C" size_t strlen ( const char * str );
extern "C" char * strcpy ( char * destination, const char * source );
extern "C" char * strcat ( char * destination, const char * source );
extern "C" void free ( void * ptr );
extern "C" int READ(int fd,void *buffer,unsigned int count);
extern "C" char *strdup(const char *s1);
extern "C" int strcmp ( const char * str1, const char * str2 );
extern "C" int strncmp ( const char * str1, const char * str2, size_t num );
extern "C" int sprintf ( char * str, const char * format, ... );
extern "C" void *memset(void *s, int c, size_t n);
#define O_RDONLY 0
#define O_TEXT 0x4000
#elif OSXUNI
extern "C" int FSFindFolder(int vRefNum,int folderType,int createFolder,char *foundRef);
extern "C" int FSRefMakePath(char *ref,char *path,int maxPathSize);
const int kVolumeRootFolderType = ('r'<<24)|('o'<<16)|('o'<<8)|('t');
const int kMusicDocumentsFolderType = 0xB5646F63;
const int kPictureDocumentsFolderType = ('p'<<24)|('d'<<16)|('o'<<8)|('c');
const int kSharedUserDataFolderType = ('s'<<24)|('d'<<16)|('a'<<8)|('t');
int specificCode(int kind,char *store,int size);
#define BUFFER_SIZE 1024
#endif
ENDINLINE
INLINE
#ifdef OSXUNI
int specificCode(int kind,char *store,int size)
{
char ref[80]={0};
int kUserDomain=-32763;
if (!FSFindFolder(kUserDomain,kind,FALSE,(char *) &ref))
{
if (!FSRefMakePath((char *) &ref,store,size-1))
{
return true;
}
}
return false;
}
#elif LINUX
// This is needed so that a line can be read properly (as read reads up to a given number of characters)
int readALine(int handle,char *store,int size)
{
char one;
int index;
index=0;
memset(store,(char) 0,size);
WHILE (READ(handle,(char *) &one,sizeof(one))>0)
{
IF (index<size)
{
*(store+index)=one;
index++;
IF (one=='\n')
{
BREAK;
}
}
ELSE
{
BREAK;
}
}
RETURN (strlen(store));
}
// This file is not licenced under the GPL like the rest of the code.
// Its is under the MIT license, to encourage reuse by cut-and-paste.
// Copyright (c) 2007 Red Hat, inc
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation files
// (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// * xdg_user_dir_lookup_with_fallback:
// * @type: a string specifying the type of directory
// * @fallback: value to use if the directory isn't specified by the user
// * @returns: a newly allocated absolute pathname
// *
// * Looks up a XDG user directory of the specified type.
// * Example of types are "DESKTOP" and "DOWNLOAD".
// *
// * In case the user hasn't specified any directory for the specified
// * type the value returned is @fallback.
// *
// * The return value is newly allocated and must be freed with
// * free(). The return value is never NULL if @fallback != NULL, unless
// * out of memory.
// **/
static char *
xdg_user_dir_lookup_with_fallback (const char *type, const char *fallback)
{
int file;
char *home_dir, *config_home, *config_file;
char buffer[512]={0};
char *user_dir;
char *p, *d;
int len;
int relative;
home_dir = getenv ("HOME");
if (home_dir == NULL)
goto error;
config_home = getenv ("XDG_CONFIG_HOME");
if (config_home == NULL || config_home[0] == 0)
{
config_file = (char*) malloc (strlen (home_dir) + strlen ("/.config/user-dirs.dirs") + 1);
if (config_file == NULL)
goto error;
strcpy (config_file, home_dir);
strcat (config_file, "/.config/user-dirs.dirs");
}
else
{
config_file = (char*) malloc (strlen (config_home) + strlen ("/user-dirs.dirs") + 1);
if (config_file == NULL)
goto error;
strcpy (config_file, config_home);
strcat (config_file, "/user-dirs.dirs");
}
file=open(config_file,O_RDONLY,0);
free (config_file);
if (file<0)
{
goto error;
}
user_dir = NULL;
// Original version used fgets, which isn't availiable here, so I had to use read...
while (readALine(file,(char *) &buffer,sizeof(buffer))>0)
{
/* Remove newline at end */
len = strlen (buffer);
if (len > 0 && buffer[len-1] == '\n')
buffer[len-1] = 0;
p = buffer;
while (*p == ' ' || *p == '\t')
p++;
if (strncmp (p, "XDG_", 4) != 0)
continue;
p += 4;
if (strncmp (p, type, strlen (type)) != 0)
continue;
p += strlen (type);
if (strncmp (p, "_DIR", 4) != 0)
continue;
p += 4;
while (*p == ' ' || *p == '\t')
p++;
if (*p != '=')
continue;
p++;
while (*p == ' ' || *p == '\t')
p++;
if (*p != '"')
continue;
p++;
relative = 0;
if (strncmp (p, "$HOME/", 6) == 0)
{
p += 6;
relative = 1;
}
else if (*p != '/')
continue;
if (relative)
{
user_dir = (char*) malloc (strlen (home_dir) + 1 + strlen (p) + 1);
if (user_dir == NULL)
goto error2;
strcpy (user_dir, home_dir);
strcat (user_dir, "/");
}
else
{
user_dir = (char*) malloc (strlen (p) + 1);
if (user_dir == NULL)
goto error2;
*user_dir = 0;
}
d = user_dir + strlen (user_dir);
while (*p && *p != '"')
{
if ((*p == '\\') && (*(p+1) != 0))
p++;
*d++ = *p++;
}
*d = 0;
}
error2:
close (file);
if (user_dir)
return user_dir;
error:
if (fallback)
return strdup (fallback);
return NULL;
}
/**
* xdg_user_dir_lookup:
* @type: a string specifying the type of directory
* @returns: a newly allocated absolute pathname
*
* Looks up a XDG user directory of the specified type.
* Example of types are "DESKTOP" and "DOWNLOAD".
*
* The return value is always != NULL (unless out of memory),
* and if a directory
* for the type is not specified by the user the default
* is the home directory. Except for DESKTOP which defaults
* to ~/Desktop.
*
* The return value is newly allocated and must be freed with
* free().
**/
static char *
xdg_user_dir_lookup (const char *type)
{
char *dir, *home_dir, *user_dir;
dir = xdg_user_dir_lookup_with_fallback (type, NULL);
if (dir != NULL)
return dir;
home_dir = getenv("HOME");
if (home_dir == NULL)
return strdup ("/tmp");
/* Special case desktop for historical compatibility */
if (strcmp (type, "DESKTOP") == 0)
{
user_dir = (char*) malloc (strlen (home_dir) + strlen ("/Desktop") + 1);
if (user_dir == NULL)
return NULL;
strcpy (user_dir, home_dir);
strcat (user_dir, "/Desktop");
return user_dir;
}
return strdup (home_dir);
}
#ifdef STANDALONE_XDG_USER_DIR_LOOKUP
int
main (int argc, char *argv[])
{
if (argc != 2)
{
fprintf (stderr, "Usage %s <dir-type>\n", argv[0]);
exit (1);
}
printf ("%s\n", xdg_user_dir_lookup (argv[1]));
return 0;
}
#endif
#elif _WIN32_WCE
char *convertCSIDLToMultiByte(int which)
{
WCHAR path[MAX_PATH+1];
int size;
char *ptr;
char t[256];
SHGetSpecialFolderPath((HWND) GLBASIC_HWND(),path,which,FALSE);
if (wcslen(path))
{
size=WideCharToMultiByte(0, 0, (LPCWSTR) path, -1, NULL, 0, NULL, NULL);
if (size)
{
ptr=(char *) calloc(1,size+1);
if (ptr)
{
WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) path, -1, (LPSTR) ptr, size,NULL,NULL);
return ptr;
}
}
}
return NULL;
}
#endif
ENDINLINE
FUNCTION GetHomeDir$:
LOCAL temp$
temp$=""
INLINE
#if _WIN32_WCE
temp_Str.assign(PLATFORMINFO_Str("DOCUMENTS"));
#elif WIN32
temp_Str.assign(PLATFORMINFO_Str("DOCUMENTS"));
#elif LINUX
char *ptr;
ptr=getenv("HOME");
if (!ptr)
{
struct __password *password;
password=getpwuid(getuid());
if (password)
{
if (password->pw_dir)
{
temp_Str.assign(password->pw_dir);
}
}
}
else
{
temp_Str.assign(ptr);
}
#elif OSXUNI
char buffer[BUFFER_SIZE]={0};
if (specificCode(kVolumeRootFolderType,(char *) &buffer,sizeof(buffer)-1))
{
temp_Str.assign((char *) &buffer);
}
#else
temp_Str.assign(PLATFORMINFO_Str("DOCUMENTS"));
#endif
ENDINLINE
RETURN temp$
ENDFUNCTION
FUNCTION getPicturesDir$:
LOCAL temp$
temp$=""
INLINE
#ifdef _WIN32_WCE
char *ptr;
ptr=convertCSIDLToMultiByte(CSIDL_MYPICTURES);
if (ptr)
{
temp_Str.assign(ptr);
free(ptr);
}
#elif WIN32
char path[MAX_PATH+1]={0};
if (SHGetFolderPathA(NULL,CSIDL_MYPICTURES,NULL,SHGFP_TYPE_CURRENT,(char *) &path)==0)
{
temp_Str.assign((char *) &path);
}
#elif OSXUNI
char buffer[BUFFER_SIZE]={0};
if (specificCode(kPictureDocumentsFolderType,(char *) &buffer,sizeof(buffer)-1))
{
temp_Str.assign((char *) &buffer);
}
#elif LINUX
char *ptr;
ptr=xdg_user_dir_lookup("PICTURES");
if (ptr)
{
temp_Str.assign(ptr);
}
#endif
ENDINLINE
RETURN temp$
ENDFUNCTION
FUNCTION GetMusicDir$:
LOCAL temp$
temp$=""
INLINE
#ifdef _WIN32_WCE
char *ptr;
ptr=convertCSIDLToMultiByte(CSIDL_MYMUSIC);
if (ptr)
{
temp_Str.assign(ptr);
free(ptr);
}
#elif WIN32
char path[MAX_PATH+1]={0};
if (SHGetFolderPathA(NULL,CSIDL_MYMUSIC,NULL,SHGFP_TYPE_CURRENT,(char *) &path)==0)
{
temp_Str.assign((char *) &path);
}
#elif OSXUNI
char buffer[BUFFER_SIZE];
if (specificCode(kMusicDocumentsFolderType,(char *) &buffer,sizeof(buffer)-1))
{
temp_Str.assign((char *) &buffer);
}
#elif LINUX
char *ptr;
ptr=xdg_user_dir_lookup("MUSIC");
if (ptr)
{
temp_Str.assign(ptr);
}
#endif
ENDINLINE
RETURN temp$
ENDFUNCTION
FUNCTION GetSharedDataDir$:
LOCAL temp$
temp$=""
INLINE
#ifdef _WIN32_WCE
char *ptr;
ptr=convertCSIDLToMultiByte(CSIDL_APPDATA);
if (ptr)
{
temp_Str.assign(ptr);
free(ptr);
}
#elif WIN32
char path[MAX_PATH+1]={0};
if (SHGetFolderPathA(NULL,CSIDL_APPDATA,NULL,SHGFP_TYPE_CURRENT,(char *) &path)==0)
{
temp_Str.assign((char *) &path);
}
#elif OSXUNI
char buffer[BUFFER_SIZE]={0};
if (specificCode(kSharedUserDataFolderType,(char *) &buffer,sizeof(buffer)-1))
{
temp_Str.assign((char *) &buffer);
}
#elif LINUX
char *ptr;
ptr=xdg_user_dir_lookup("PUBLICSHARE");
IF (ptr)
{
temp_Str.assign(ptr);
}
#endif
ENDINLINE
RETURN temp$
ENDFUNCTION
:nw:
It was a nightmare getting the API parameters correct :) But I did it! :good: