#include #include #include #include #include #include #include #include "mswint.h" #include #include #if _MSC_VER >=1400 #define stricmp _stricmp #endif char * mswStrdup( const char * ); static char appLibDirName[MAX_PATH]; static char appWorkDirName[MAX_PATH]; /** * Get the location of the shared files (parameters, help file, etc. ): This location is * derived from the modulename, ie. the directory where the exe is installed. * For an instalaltion directory of somedir/bin/xtrkcad.exe the library directory is * somedir/share/xtrkcad/ */ const char * wGetAppLibDir( void ) { char *cp; char module_name[MAX_PATH]; if (appLibDirName[0] != '\0') { return appLibDirName; } GetModuleFileName( mswHInst, module_name, sizeof module_name ); cp = strrchr( module_name, '\\' ); if (cp) *cp = '\0'; #ifdef XTRKCAD_CMAKE_BUILD strncpy(appLibDirName, module_name, sizeof(appLibDirName)); size_t len = sizeof(appLibDirName)-strlen(appLibDirName)-1; strncat(appLibDirName, "\\..\\share\\xtrkcad", len); _fullpath( appLibDirName, appLibDirName, MAX_PATH ); return appLibDirName; #endif strncpy(appLibDirName, module_name, sizeof(appLibDirName)); appLibDirName[sizeof(appLibDirName)-1] = '\0'; return appLibDirName; } /** * Gets the working directory for the application. At least the INI file is stored here. * The working directory can be specified manually by creating a file called xtrkcad0.ini * in the application lib dir (the directory where the .EXE is located). * * [workdir] * path=somepath * * when somepath is set to the keyword "installdir", the install directory for the EXE is * used. * * If no xtrkcad0.ini could be found, the user settings directory (appdata) is used. * */ const char * wGetAppWorkDir( void ) { char *cp; int rc; if ( appWorkDirName[0] != 0 ) { return appWorkDirName; } wGetAppLibDir(); snprintf( mswTmpBuff, sizeof(mswTmpBuff), "%s\\xtrkcad0.ini", appLibDirName ); rc = GetPrivateProfileString( "workdir", "path", "", appWorkDirName, sizeof appWorkDirName, mswTmpBuff ); if ( rc!=0 ) { if ( stricmp( appWorkDirName, "installdir" ) == 0 ) { strncpy( appWorkDirName, appLibDirName, sizeof(appWorkDirName) ); appWorkDirName[sizeof(appWorkDirName)-1] = '\0'; } else { cp = &appWorkDirName[strlen(appWorkDirName)-1]; while (cp>appWorkDirName && *cp == '\\') *cp-- = 0; } return appWorkDirName; } if (SHGetSpecialFolderPath( NULL, mswTmpBuff, CSIDL_APPDATA, 0 ) == 0 ) { wNoticeEx( NT_ERROR, "Cannot get user's profile directory", "Exit", NULL ); wExit(0); } else { snprintf( appWorkDirName, sizeof(appWorkDirName), "%s\\%s", mswTmpBuff, "XTrackCad" ); if( !PathIsDirectory( appWorkDirName )) { if( !CreateDirectory( appWorkDirName, NULL )) { wNoticeEx( NT_ERROR, "Cannot create user's profile directory", "Exit", NULL ); wExit(0); } } } return appWorkDirName; } /** Get the user's home directory. The environment variable HOME is * assumed to contain the proper directory. * * \return pointer to the user's home directory */ const char *wGetUserHomeDir( void ) { if (SHGetSpecialFolderPath( NULL, mswTmpBuff, CSIDL_PERSONAL, 0 ) == 0 ) { wNoticeEx( NT_ERROR, "Cannot get user's home directory", "Exit", NULL ); wExit(0); return( NULL ); } else { return( mswTmpBuff ); } } typedef struct { char * section; char * name; BOOL_T present; BOOL_T dirty; char * val; } prefs_t; static dynArr_t prefs_da; #define prefs(N) DYNARR_N(prefs_t,prefs_da,N) void wPrefSetString( const char * section, const char * name, const char * sval ) { prefs_t * p; for (p=&prefs(0); p<&prefs(prefs_da.cnt); p++) { if ( strcmp( p->section, section ) == 0 && strcmp( p->name, name ) == 0 ) { if (p->val) free(p->val); p->dirty = TRUE; p->val = mswStrdup( sval ); return; } } DYNARR_APPEND( prefs_t, prefs_da, 10 ); p = &prefs(prefs_da.cnt-1); p->name = mswStrdup(name); p->section = mswStrdup(section); p->dirty = TRUE; p->val = mswStrdup(sval); } void wPrefsLoad(char * name) { prefs_t *p; for (int i= 0; isection, p->name, "", mswTmpBuff, sizeof mswTmpBuff, name ); if (rc==0) continue; p->val = mswStrdup(mswTmpBuff); } } char * wPrefGetStringBasic( const char * section, const char * name ) { prefs_t * p; int rc; for (p=&prefs(0); p<&prefs(prefs_da.cnt); p++) { if ( strcmp( p->section, section ) == 0 && strcmp( p->name, name ) == 0 ) { return p->val; } } rc = GetPrivateProfileString( section, name, "", mswTmpBuff, sizeof mswTmpBuff, mswProfileFile ); if (rc==0) return NULL; DYNARR_APPEND( prefs_t, prefs_da, 10 ); p = &prefs(prefs_da.cnt-1); p->name = mswStrdup(name); p->section = mswStrdup(section); p->dirty = FALSE; p->val = mswStrdup(mswTmpBuff); return p->val; } void wPrefSetInteger( const char * section, const char * name, long lval ) { char tmp[20]; snprintf( tmp, sizeof(tmp), "%ld", lval ); wPrefSetString( section, name, tmp ); } wBool_t wPrefGetIntegerBasic( const char * section, const char * name, long *res, long def ) { const char * cp; char * cp1; cp = wPrefGetStringBasic( section, name ); if (cp == NULL) { *res = def; return FALSE; } *res = strtol(cp,&cp1,0); if (cp==cp1) { *res = def; return FALSE; } return TRUE; } void wPrefSetFloat( const char * section, /* Section */ const char * name, /* Name */ double lval ) /* Value */ /* */ { char tmp[20]; snprintf(tmp, sizeof(tmp), "%0.6f", lval ); wPrefSetString( section, name, tmp ); } wBool_t wPrefGetFloatBasic( const char * section, /* Section */ const char * name, /* Name */ double * res, /* Address of result */ double def ) /* Default value */ /* */ { const char * cp; char * cp1; cp = wPrefGetStringBasic( section, name ); if (cp == NULL) { *res = def; return FALSE; } *res = strtod(cp, &cp1); if (cp == cp1) { *res = def; return FALSE; } return TRUE; } void wPrefFlush( char * name ) { prefs_t * p; for (p=&prefs(0); p<&prefs(prefs_da.cnt); p++) { if (name && name[0]) WritePrivateProfileString( p->section, p->name, p->val, name ); else if (p->dirty) WritePrivateProfileString( p->section, p->name, p->val, mswProfileFile ); } if (name && name[0]) WritePrivateProfileString( NULL, NULL, NULL, name ); else WritePrivateProfileString( NULL, NULL, NULL, mswProfileFile ); } void wPrefReset( void ) /* */ { prefs_t * p; for (p=&prefs(0); p<&prefs(prefs_da.cnt); p++) { if (p->section) free( p->section ); if (p->name) free( p->name ); if (p->val) free( p->val ); } prefs_da.cnt = 0; }