1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling, Julian Smart and Markus Holzem 
   7 // Licence:           wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  12 //#pragma implementation "utils.h" 
  16 #include "wx/string.h" 
  23 #include <sys/systeminfo.h> 
  26 #include "gdk/gdkx.h"        // GDK_DISPLAY 
  27 #include "gdk/gdkprivate.h"  // gdk_progclass 
  30 #include <X11/Xutil.h> 
  31 #include <X11/Xresource.h> 
  35 //----------------------------------------------------------------------------- 
  37 //----------------------------------------------------------------------------- 
  39 // Yuck this is really BOTH site and platform dependent 
  40 // so we should use some other strategy! 
  42     #define DEFAULT_XRESOURCE_DIR "/usr/openwin/lib/app-defaults" 
  44     #define DEFAULT_XRESOURCE_DIR "/usr/lib/X11/app-defaults" 
  47 //----------------------------------------------------------------------------- 
  48 // glabal data (data.cpp) 
  49 //----------------------------------------------------------------------------- 
  51 extern wxResourceCache 
*wxTheResourceCache
; 
  52 extern XrmDatabase wxResourceDatabase
; 
  54 //----------------------------------------------------------------------------- 
  55 // utility functions for get/write resources 
  56 //----------------------------------------------------------------------------- 
  58 static char *GetResourcePath(char *buf
, char *name
, bool create
) 
  60     if (create 
&& FileExists(name
)) { 
  62         return buf
; // Exists so ... 
  67         // Put in standard place for resource files if not absolute 
  68         strcpy(buf
, DEFAULT_XRESOURCE_DIR
); 
  70         strcat(buf
, FileNameFromPath(name
)); 
  73         // Touch the file to create it 
  74         FILE *fd 
= fopen(buf
, "w"); 
  80 // Read $HOME for what it says is home, if not 
  81 // read $USER or $LOGNAME for user name else determine 
  82 // the Real User, then determine the Real home dir. 
  83 static char *GetIniFile(char *dest
, const char *filename
) 
  85     char *home 
= (char *) NULL
; 
  86     if (filename 
&& wxIsAbsolutePath(filename
)) 
  88       strcpy(dest
, filename
); 
  92       if ((home 
= wxGetUserHome(wxString())) != NULL
) 
  95         if (dest
[strlen(dest
) - 1] != '/') strcat(dest
, "/"); 
  98           if ((filename 
= getenv("XENVIRONMENT")) == NULL
) filename 
= ".Xdefaults"; 
 101           if (*filename 
!= '.') strcat(dest
, "."); 
 102         strcat(dest
, filename
); 
 112 static void wxXMergeDatabases() 
 114     XrmDatabase homeDB
, serverDB
, applicationDB
; 
 115     char filenamebuf
[1024]; 
 117     char *filename 
= &filenamebuf
[0]; 
 119     char *classname 
= gdk_progclass
;               // Robert Roebling ?? 
 121     (void)strcpy(name
, "/usr/lib/X11/app-defaults/"); 
 122     (void)strcat(name
, classname 
? classname 
: "wxWindows"); 
 124     // Get application defaults file, if any 
 125     if ((applicationDB 
= XrmGetFileDatabase(name
))) 
 126         (void)XrmMergeDatabases(applicationDB
, &wxResourceDatabase
); 
 128     // Merge server defaults, created by xrdb, loaded as a property of the root 
 129     // window when the server initializes and loaded into the display 
 130     // structure on XOpenDisplay; 
 131     // if not defined, use .Xdefaults 
 132     if (XResourceManagerString(GDK_DISPLAY()) != NULL
) { 
 133         serverDB 
= XrmGetStringDatabase(XResourceManagerString(GDK_DISPLAY())); 
 135         (void)GetIniFile(filename
, (char *) NULL
); 
 136         serverDB 
= XrmGetFileDatabase(filename
); 
 139         XrmMergeDatabases(serverDB
, &wxResourceDatabase
); 
 141     // Open XENVIRONMENT file, or if not defined, the .Xdefaults, 
 142     // and merge into existing database 
 144     if ((environment 
= getenv("XENVIRONMENT")) == NULL
) { 
 146         environment 
= GetIniFile(filename
, (const char *) NULL
); 
 147         len 
= strlen(environment
); 
 148 #if !defined(SVR4) || defined(__sgi) 
 149         (void)gethostname(environment 
+ len
, 1024 - len
); 
 151         (void)sysinfo(SI_HOSTNAME
, environment 
+ len
, 1024 - len
); 
 154     if ((homeDB 
= XrmGetFileDatabase(environment
))) 
 155         XrmMergeDatabases(homeDB
, &wxResourceDatabase
); 
 158 //----------------------------------------------------------------------------- 
 159 // called on application exit 
 160 //----------------------------------------------------------------------------- 
 162 void wxFlushResources() 
 164     char nameBuffer
[512]; 
 166     wxNode 
*node 
= wxTheResourceCache
->First(); 
 168         wxString str 
= node
->GetKeyString(); 
 169         char *file 
= WXSTRINGCAST str
; 
 170         // If file doesn't exist, create it first. 
 171         (void)GetResourcePath(nameBuffer
, file
, TRUE
); 
 173         XrmDatabase database 
= (XrmDatabase
)node
->Data(); 
 174         XrmPutFileDatabase(database
, nameBuffer
); 
 175         XrmDestroyDatabase(database
); 
 176         wxNode 
*next 
= node
->Next(); 
 182 void wxDeleteResources(const char *file
) 
 184     wxLogTrace(wxTraceResAlloc
, "Delete: Number = %d", wxTheResourceCache
->Number()); 
 186     (void)GetIniFile(buffer
, file
); 
 188     wxNode 
*node 
= wxTheResourceCache
->Find(buffer
); 
 190         XrmDatabase database 
= (XrmDatabase
)node
->Data(); 
 191         XrmDestroyDatabase(database
); 
 196 //----------------------------------------------------------------------------- 
 197 // resource functions 
 198 //----------------------------------------------------------------------------- 
 200 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file 
) 
 204     if (!entry
) return FALSE
; 
 206     (void)GetIniFile(buffer
, file
); 
 208     XrmDatabase database
; 
 209     wxNode 
*node 
= wxTheResourceCache
->Find(buffer
); 
 211         database 
= (XrmDatabase
)node
->Data(); 
 213         database 
= XrmGetFileDatabase(buffer
); 
 214         wxLogTrace(wxTraceResAlloc
, "Write: Number = %d", wxTheResourceCache
->Number()); 
 215         wxTheResourceCache
->Append(buffer
, (wxObject 
*)database
); 
 218     strcpy(resName
, !section
.IsNull() ? WXSTRINGCAST section 
: "wxWindows"); 
 219     strcat(resName
, "."); 
 220     strcat(resName
, entry
); 
 221     XrmPutStringResource(&database
, resName
, value
); 
 225 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file 
) 
 228     sprintf(buf
, "%.4f", value
); 
 229     return wxWriteResource(section
, entry
, buf
, file
); 
 232 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file 
) 
 235     sprintf(buf
, "%ld", value
); 
 236     return wxWriteResource(section
, entry
, buf
, file
); 
 239 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file 
) 
 242     sprintf(buf
, "%d", value
); 
 243     return wxWriteResource(section
, entry
, buf
, file
); 
 246 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file 
) 
 248     if (!wxResourceDatabase
) 
 251     XrmDatabase database
; 
 252     if ( !file
.IsEmpty() ) { 
 254         // Is this right? Trying to get it to look in the user's 
 255         // home directory instead of current directory -- JACS 
 256         (void)GetIniFile(buffer
, file
); 
 258         wxNode 
*node 
= (wxNode
*) NULL
;  /* suppress egcs warning */ 
 259         node 
= wxTheResourceCache
->Find(buffer
); 
 262             database 
= (XrmDatabase
)node
->Data(); 
 266             database 
= XrmGetFileDatabase(buffer
); 
 267             wxLogTrace(wxTraceResAlloc
, "Get: Number = %d", wxTheResourceCache
->Number()); 
 268             wxTheResourceCache
->Append(buffer
, (wxObject 
*)database
); 
 271         database 
= wxResourceDatabase
; 
 276     strcpy(buf
, section
); 
 280     bool success 
= XrmGetResource(database
, buf
, "*", str_type
, &xvalue
); 
 281     // Try different combinations of upper/lower case, just in case... 
 283         buf
[0] = (isupper(buf
[0]) ? tolower(buf
[0]) : toupper(buf
[0])); 
 284         success 
= XrmGetResource(database
, buf
, "*", str_type
,        &xvalue
); 
 289         *value 
= new char[xvalue
.size 
+ 1]; 
 290         strncpy(*value
, xvalue
.addr
, (int)xvalue
.size
); 
 296 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file 
) 
 298     char *s 
= (char *) NULL
; 
 299     bool succ 
= wxGetResource(section
, entry
, &s
, file
); 
 301         *value 
= (float)strtod(s
, (char **) NULL
); 
 308 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file 
) 
 310     char *s 
= (char *) NULL
; 
 311     bool succ 
= wxGetResource(section
, entry
, &s
, file
); 
 313         *value 
= strtol(s
, (char **) NULL
, 10); 
 320 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file 
) 
 322     char *s 
= (char *) NULL
; 
 323     bool succ 
= wxGetResource(section
, entry
, &s
, file
); 
 325         // Handle True, False here 
 326         // True, Yes, Enables, Set or  Activated 
 327         if (*s 
== 'T' || *s 
== 'Y' || *s 
== 'E' || *s 
== 'S' || *s 
== 'A') 
 329         // False, No, Disabled, Reset, Cleared, Deactivated 
 330         else if (*s 
== 'F' || *s 
== 'N' || *s 
== 'D' || *s 
== 'R' || *s 
== 'C') 
 334             *value 
= (int)strtol(s
, (char **) NULL
, 10);