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 _T("/usr/openwin/lib/app-defaults") 
  44     #define DEFAULT_XRESOURCE_DIR _T("/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 wxChar 
*GetResourcePath(wxChar 
*buf
, wxChar 
*name
, bool create
) 
  60     if (create 
&& FileExists(name
))  
  63         return buf
; // Exists so ... 
  69         // Put in standard place for resource files if not absolute 
  70         wxStrcpy(buf
, DEFAULT_XRESOURCE_DIR
); 
  71         wxStrcat(buf
, _T("/")); 
  72         wxStrcat(buf
, FileNameFromPath(name
)); 
  76         // Touch the file to create it 
  77         FILE *fd 
= fopen(wxConvCurrent
->cWX2MB(buf
), "w"); 
  83 // Read $HOME for what it says is home, if not 
  84 // read $USER or $LOGNAME for user name else determine 
  85 // the Real User, then determine the Real home dir. 
  86 static wxChar 
*GetIniFile(wxChar 
*dest
, const wxChar 
*filename
) 
  88     const wxChar 
*home 
= (const wxChar 
*) NULL
; 
  89     if (filename 
&& wxIsAbsolutePath(filename
)) 
  91       wxStrcpy(dest
, filename
); 
  95       if ((home 
= wxGetUserHome(wxString())) != NULL
) 
  98         if (dest
[wxStrlen(dest
) - 1] != _T('/')) wxStrcat(dest
, _T("/")); 
 101           if ((filename 
= wxGetenv(_T("XENVIRONMENT"))) == NULL
) filename 
= _T(".Xdefaults"); 
 104           if (*filename 
!= _T('.')) wxStrcat(dest
, _T(".")); 
 105         wxStrcat(dest
, filename
); 
 115 static void wxXMergeDatabases() 
 117     XrmDatabase homeDB
, serverDB
, applicationDB
; 
 118     wxChar filenamebuf
[1024]; 
 120     wxChar 
*filename 
= &filenamebuf
[0]; 
 122     char *classname 
= gdk_progclass
;               // Robert Roebling ?? 
 124     (void)strcpy(name
, "/usr/lib/X11/app-defaults/"); 
 125     (void)strcat(name
, classname 
? classname 
: "wxWindows"); 
 127     // Get application defaults file, if any 
 128     if ((applicationDB 
= XrmGetFileDatabase(name
))) 
 129         (void)XrmMergeDatabases(applicationDB
, &wxResourceDatabase
); 
 131     // Merge server defaults, created by xrdb, loaded as a property of the root 
 132     // window when the server initializes and loaded into the display 
 133     // structure on XOpenDisplay; 
 134     // if not defined, use .Xdefaults 
 135     if (XResourceManagerString(GDK_DISPLAY()) != NULL
)  
 137         serverDB 
= XrmGetStringDatabase(XResourceManagerString(GDK_DISPLAY())); 
 141         (void)GetIniFile(filename
, (wxChar 
*) NULL
); 
 142         serverDB 
= XrmGetFileDatabase(wxConvCurrent
->cWX2MB(filename
)); 
 145         XrmMergeDatabases(serverDB
, &wxResourceDatabase
); 
 147     // Open XENVIRONMENT file, or if not defined, the .Xdefaults, 
 148     // and merge into existing database 
 150     if ((environment 
= wxGetenv(_T("XENVIRONMENT"))) == NULL
)  
 156         environment 
= GetIniFile(filename
, (const wxChar 
*) NULL
); 
 157         len 
= wxStrlen(environment
); 
 158 #if !defined(SVR4) || defined(__sgi) 
 160         (void)gethostname(hostbuf
, 1024 - len
); 
 162         (void)gethostname(environment 
+ len
, 1024 - len
); 
 166         (void)sysinfo(SI_HOSTNAME
, hostbuf
, 1024 - len
); 
 168         (void)sysinfo(SI_HOSTNAME
, environment 
+ len
, 1024 - len
); 
 172         wxStrcat(environment
, wxConvCurrent
->cMB2WX(hostbuf
)); 
 175     if ((homeDB 
= XrmGetFileDatabase(wxConvCurrent
->cWX2MB(environment
)))) 
 176         XrmMergeDatabases(homeDB
, &wxResourceDatabase
); 
 179 //----------------------------------------------------------------------------- 
 180 // called on application exit 
 181 //----------------------------------------------------------------------------- 
 183 void wxFlushResources() 
 185     wxChar nameBuffer
[512]; 
 187     wxNode 
*node 
= wxTheResourceCache
->First(); 
 189         wxString str 
= node
->GetKeyString(); 
 190         wxChar 
*file 
= WXSTRINGCAST str
; 
 191         // If file doesn't exist, create it first. 
 192         (void)GetResourcePath(nameBuffer
, file
, TRUE
); 
 194         XrmDatabase database 
= (XrmDatabase
)node
->Data(); 
 195         XrmPutFileDatabase(database
, wxConvCurrent
->cWX2MB(nameBuffer
)); 
 196         XrmDestroyDatabase(database
); 
 197         wxNode 
*next 
= node
->Next(); 
 203 void wxDeleteResources(const wxChar 
*file
) 
 205     wxLogTrace(wxTraceResAlloc
, _T("Delete: Number = %d"), wxTheResourceCache
->Number()); 
 207     (void)GetIniFile(buffer
, file
); 
 209     wxNode 
*node 
= wxTheResourceCache
->Find(buffer
); 
 211         XrmDatabase database 
= (XrmDatabase
)node
->Data(); 
 212         XrmDestroyDatabase(database
); 
 217 //----------------------------------------------------------------------------- 
 218 // resource functions 
 219 //----------------------------------------------------------------------------- 
 221 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file 
) 
 225     if (!entry
) return FALSE
; 
 227     (void)GetIniFile(buffer
, file
); 
 229     XrmDatabase database
; 
 230     wxNode 
*node 
= wxTheResourceCache
->Find(buffer
); 
 232         database 
= (XrmDatabase
)node
->Data(); 
 234         database 
= XrmGetFileDatabase(wxConvCurrent
->cWX2MB(buffer
)); 
 235         wxLogTrace(wxTraceResAlloc
, _T("Write: Number = %d"), wxTheResourceCache
->Number()); 
 236         wxTheResourceCache
->Append(buffer
, (wxObject 
*)database
); 
 239     strcpy(resName
, !section
.IsNull() ? MBSTRINGCAST section
.mb_str() : "wxWindows"); 
 240     strcat(resName
, "."); 
 241     strcat(resName
, entry
.mb_str()); 
 242     XrmPutStringResource(&database
, resName
, value
.mb_str()); 
 246 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file 
) 
 249     sprintf(buf
, "%.4f", value
); 
 250     return wxWriteResource(section
, entry
, buf
, file
); 
 253 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file 
) 
 256     sprintf(buf
, "%ld", value
); 
 257     return wxWriteResource(section
, entry
, buf
, file
); 
 260 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file 
) 
 263     sprintf(buf
, "%d", value
); 
 264     return wxWriteResource(section
, entry
, buf
, file
); 
 267 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file 
) 
 269     if (!wxResourceDatabase
) 
 272     XrmDatabase database
; 
 276         // Is this right? Trying to get it to look in the user's 
 277         // home directory instead of current directory -- JACS 
 278         (void)GetIniFile(buffer
, file
); 
 280         wxNode 
*node 
= (wxNode
*) NULL
;  /* suppress egcs warning */ 
 281         node 
= wxTheResourceCache
->Find(buffer
); 
 284             database 
= (XrmDatabase
)node
->Data(); 
 288             database 
= XrmGetFileDatabase(wxConvCurrent
->cWX2MB(buffer
)); 
 289             wxLogTrace(wxTraceResAlloc
, _T("Get: Number = %d"), wxTheResourceCache
->Number()); 
 290             wxTheResourceCache
->Append(buffer
, (wxObject 
*)database
); 
 293         database 
= wxResourceDatabase
; 
 298     strcpy(buf
, section
.mb_str()); 
 300     strcat(buf
, entry
.mb_str()); 
 302     bool success 
= XrmGetResource(database
, buf
, "*", str_type
, &xvalue
); 
 303     // Try different combinations of upper/lower case, just in case... 
 306         buf
[0] = (isupper(buf
[0]) ? tolower(buf
[0]) : toupper(buf
[0])); 
 307         success 
= XrmGetResource(database
, buf
, "*", str_type
,        &xvalue
); 
 313         *value 
= new char[xvalue
.size 
+ 1]; 
 314         strncpy(*value
, xvalue
.addr
, (int)xvalue
.size
); 
 320 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file 
) 
 322     char *s 
= (char *) NULL
; 
 323     bool succ 
= wxGetResource(section
, entry
, &s
, file
); 
 326         *value 
= (float)strtod(s
, (char **) NULL
); 
 333 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file 
) 
 335     char *s 
= (char *) NULL
; 
 336     bool succ 
= wxGetResource(section
, entry
, &s
, file
); 
 339         *value 
= strtol(s
, (char **) NULL
, 10); 
 346 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file 
) 
 348     char *s 
= (char *) NULL
; 
 349     bool succ 
= wxGetResource(section
, entry
, &s
, file
); 
 352         // Handle True, False here 
 353         // True, Yes, Enables, Set or  Activated 
 354         if (*s 
== 'T' || *s 
== 'Y' || *s 
== 'E' || *s 
== 'S' || *s 
== 'A') 
 356         // False, No, Disabled, Reset, Cleared, Deactivated 
 357         else if (*s 
== 'F' || *s 
== 'N' || *s 
== 'D' || *s 
== 'R' || *s 
== 'C') 
 361             *value 
= (int)strtol(s
, (char **) NULL
, 10);