root/foundation-apps/grosview-maxx/Xrm.cc

Revision 2, 8.3 KB (checked in by emasson, 3 years ago)

initial import for the community edition

Line 
1//
2//  Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov )
3//
4//  This file may be distributed under terms of the GPL
5//
6//
7// $Id: Xrm.cc,v 1.1.1.1 2008/05/04 15:53:48 emasson Exp $
8//
9
10#include <string.h>
11#include <stdlib.h>
12#include <stdio.h>      //  For snprintf().
13#include <ctype.h>
14#ifdef HAVE_IOSTREAM
15#include <iostream>
16#else
17#include <iostream.h>
18#endif
19#include <unistd.h>  //  for access(), etc.  BCG
20
21#include "general.h"
22#ifndef NULL
23#define NULL 0
24#endif
25#include "Xrm.h"
26#include "Xrmcommandline.h"
27
28CVSID("$Id: Xrm.cc,v 1.1.1.1 2008/05/04 15:53:48 emasson Exp $");
29CVSID_DOT_H(XRM_H_CVSID);
30CVSID_DOT_H2(XRMCOMMANDLINE_H_CVSID);
31
32
33extern char *defaultXResourceString;
34
35
36bool Xrm::_initialized = false;
37
38Xrm::Xrm(const char *instanceName, int argc, char **argv){
39  std::cerr << " Error:  This constructor is not supported yet." << std::endl;
40  exit (-1);
41  _db = NULL;
42  _class = _instance = NULLQUARK;
43  getDisplayName(argc, argv);
44
45  (void) instanceName;
46  //  End unsupported constructor.  !!!!!!!! BCG
47}
48
49Xrm::Xrm(const char *className, const char *instanceName){
50  XrmInitialize ();
51
52  //  Initialize everything to NULL.
53  _db = NULL;
54  _class = _instance = NULLQUARK;
55
56  // init the _instance and _class Quarks
57  _instance = XrmStringToQuark(instanceName);
58  initClassName(className);
59}
60
61const char*
62Xrm::getDisplayName (int argc, char** argv)
63{
64  (void) argc;  //  Avoid gcc warnings.
65  //  See if '-display foo:0' is on the command line, and return it if it is.
66  char** argp;
67
68  for (argp = argv; (*argp != NULL) &&
69      (strncasecmp (*argp, "-display", 9)); argp++)
70    ;  //  Don't do anything.
71
72  //  If we found -display and the next word exists...
73  if (*argp && *(++argp))
74    _display_name = *argp;
75  else
76    _display_name = "";
77  return _display_name;
78  //  An empty display string means use the DISPLAY environment variable.
79}
80
81const char *Xrm::getResource(const char *rname) const{
82  char frn[1024], fcn[1024];
83  snprintf(frn, 1024, "%s.%s", instanceName(), rname);
84  snprintf(fcn, 1024, "%s.%s", className(), rname);
85
86  XrmValue val;
87  val.addr = NULL;
88  char *type;
89  XrmGetResource(_db, frn, fcn, &type, &val);
90  //  This case here is a hack, because we are currently moving from
91  //  always making the instance name be "xosview" to allowing
92  //  user-specified ones.  And unfortunately, the class name is
93  //  XOsview, and not xosview, so our old defaults (xosview.font)
94  //  will not be found when searching for XOsview.font.  bgrayson Dec. 1996
95  if (!val.addr)
96  {
97    //  Let's try with a non-uppercased class name.
98    char fcn_lower[1024];
99    strncpy(fcn_lower, className(), 1024);
100    char *p = fcn_lower;
101    while (p && *p)
102      {
103      *p = tolower(*p);
104      p++;
105      }
106    snprintf(fcn, 1024, "%s.%s", fcn_lower, rname);
107    XrmGetResource(_db, frn, fcn, &type, &val);
108  }
109
110  return val.addr;
111}
112
113Xrm::~Xrm(){
114  XrmDestroyDatabase(_db);
115}
116
117//---------------------------------------------------------------------
118//  This function uses XrmParseCommand, and updates argc and argv through it.
119void Xrm::loadAndMergeResources(int& argc, char** argv, Display* display){
120
121  // init the database if it needs it
122  if (!_initialized){
123    XrmInitialize();
124    _initialized = true;
125  }
126  else
127  {
128    std::cerr << "Error:  Xrm:loadAndMergeResources() called twice!" << std::endl;
129    exit (-1);
130  }
131  //  This is ugly code.  According to X and Xt rules, many files need
132  //  to be checked for resource settings.  Since we aren't (yet) using
133  //  Xt or any other package, we need to do all of these checks
134  //  individually.  BCG
135//  =========== BEGIN X Resource lookup and merging ==========
136
137//  This all needs to be done in the proper order:
138/*
139Listed from weakest to strongest:
140  (from code-builtin-resources) (Stored in the string in defaultstring.h)
141  app-defaults
142  XOSView (from XAPPLRESDIR directory)
143  from RESOURCE_MANAGER property on server (reads .Xdefaults if needed)
144  from file specified in XENVIRONMENT
145  from command line (i.e., handled with XrmParseCommand)
146*/
147
148  // Get resources from the various resource files
149
150  //  Put the default, compile-time options as the lowest priority.
151  _db = XrmGetStringDatabase (defaultXResourceString);
152
153  //  Merge in the system resource database.
154  char rfilename[2048];
155
156  // Get the app-defaults
157  snprintf(rfilename, 2048, "/usr/X11R6/lib/X11/app-defaults/%s",
158      XrmQuarkToString(_class));
159  if (rfilename != NULL)
160    XrmCombineFileDatabase (rfilename, &_db, 1);
161  //  Try a few more, for SunOS/Solaris folks.
162  snprintf(rfilename, 2048, "/usr/openwin/lib/X11/app-defaults/%s",
163      XrmQuarkToString(_class));
164  if (rfilename != NULL)
165    XrmCombineFileDatabase (rfilename, &_db, 1);
166  snprintf(rfilename, 2048, "/usr/local/X11R6/lib/X11/app-defaults/%s",
167      XrmQuarkToString(_class));
168  if (rfilename != NULL)
169    XrmCombineFileDatabase (rfilename, &_db, 1);
170
171  //  Now, check for an XOSView file in the XAPPLRESDIR directory...
172  char* xappdir = getenv ("XAPPLRESDIR");
173  if (xappdir != NULL)
174  {
175    char xappfile[1024];
176    snprintf (xappfile, 1024, "%s/%s", xappdir, className());
177    // this did not work for XAPPLRESDIR
178    //if (!access (xappfile, X_OK | R_OK))
179    if (!access (xappfile, R_OK))
180    {
181      XrmCombineFileDatabase (xappfile, &_db, 1);
182      }
183  }
184
185  //  Now, check the display's RESOURCE_MANAGER property...
186  char* displayString = XResourceManagerString (display);
187  if (displayString != NULL)
188  {
189    XrmDatabase displayrdb = XrmGetStringDatabase (displayString);
190    XrmMergeDatabases (displayrdb, &_db);  //  Destroys displayrdb when done.
191  }
192
193  //  And check this screen of the display...
194  char* screenString =
195              XScreenResourceString (DefaultScreenOfDisplay(display));
196  if (screenString != NULL)
197  {
198    XrmDatabase screenrdb = XrmGetStringDatabase (screenString);
199    XrmMergeDatabases (screenrdb, &_db);  //  Destroys screenrdb when done.
200  }
201
202  //  Now, check for a user resource file, and merge it in if there is one...
203  if ( getenv( "HOME" ) != NULL ){
204    char userrfilename[1024];
205    char *home = getenv("HOME");
206    snprintf(userrfilename, 1024, "%s/.Xdefaults", home);
207    //  User file overrides system (_db).
208    XrmCombineFileDatabase (userrfilename, &_db, 1);
209  }
210
211  //  Second-to-last, parse any resource file specified in the
212  //  environment variable XENVIRONMENT.
213  char* xenvfile;
214  if ((xenvfile = getenv ("XENVIRONMENT")) != NULL)
215  {
216    //  The XENVIRONMENT file overrides all of the above.
217    XrmCombineFileDatabase (xenvfile, &_db, 1);
218  }
219  //  Command-line resources override system and user defaults.
220  XrmDatabase cmdlineRdb_ = NULL;
221  XrmParseCommand (&cmdlineRdb_, options, NUM_OPTIONS, instanceName(),
222                    &argc, argv);
223  XrmCombineDatabase (cmdlineRdb_, &_db, 1);  //  Keeps cmdlineRdb_ around.
224//  =========== END X Resource lookup and merging ==========
225}
226
227void Xrm::initClassName(const char* name){
228  char className[256];
229  strncpy(className, name, 255);  //  Avoid evil people out there...
230
231  className[0] = toupper(className[0]);
232  if (className[0] == 'X')
233      className[1] = toupper(className[1]);
234
235  _class = XrmStringToQuark(className);
236}
237
238
239
240//------------  Some debugging functions follow.  -----------------------
241inline std::ostream &operator<<(std::ostream &os, const XrmBinding &b){
242  switch (b){
243  case XrmBindTightly:
244    return os << ".";
245  case XrmBindLoosely:
246    return os << "*";
247  default:
248    std::cerr <<"std::ostream operator<<(std::ostream &, const XrmBinding &) : "
249      <<"Unknown XrmBinding!";
250    return os;
251  }
252
253  return os;
254}
255
256std::ostream &Xrm::dump(std::ostream &os) const {
257  os <<"--- Xrm --- class: " <<XrmQuarkToString(_class)
258     <<", instance: " <<XrmQuarkToString(_instance) <<"\n";
259
260  XrmName names[] = { _instance, NULLQUARK };
261  XrmClass classes[] = { _class, NULLQUARK };
262
263  XrmEnumerateDatabase(_db, names, classes, XrmEnumAllLevels, enumCB,
264                       (XPointer)&os);
265
266  return os;
267}
268
269Bool Xrm::enumCB(XrmDatabase *, XrmBindingList bindings,
270                 XrmQuarkList quarks, XrmRepresentation *type,
271                 XrmValue *value, XPointer closure) {
272
273  std::ostream *os = (std::ostream *)closure;
274  (void) type;  //  Avoid gcc warnings.
275
276  //std::cerr <<"type = " <<XrmQuarkToString(*type) <<std::endl;
277
278  int i = 0;
279  while (quarks[i] != NULLQUARK){
280    *os <<bindings[i] <<XrmQuarkToString(quarks[i]);
281    i++;
282  }
283  *os <<": " <<value->addr <<"\n";
284
285  return False;
286}
Note: See TracBrowser for help on using the browser.