Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

open-axiom repository from github

24005 views
1
/*
2
Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd.
3
All rights reserved.
4
Copyright (C) 2007-2011, Gabriel Dos Reis.
5
All rights reserved.
6
7
Redistribution and use in source and binary forms, with or without
8
modification, are permitted provided that the following conditions are
9
met:
10
11
- Redistributions of source code must retain the above copyright
12
notice, this list of conditions and the following disclaimer.
13
14
- Redistributions in binary form must reproduce the above copyright
15
notice, this list of conditions and the following disclaimer in
16
the documentation and/or other materials provided with the
17
distribution.
18
19
- Neither the name of The Numerical Algorithms Group Ltd. nor the
20
names of its contributors may be used to endorse or promote products
21
derived from this software without specific prior written permission.
22
23
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
26
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
27
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
*/
35
36
#define _MAIN3D_C
37
#include "openaxiom-c-macros.h"
38
39
#include <string.h>
40
#include <stdio.h>
41
#include <stdlib.h>
42
#include <unistd.h>
43
#include <signal.h>
44
45
#include "cfuns.h"
46
#include "header.h"
47
#include "cpanel.h"
48
#include "process.h"
49
#include "bsdsignal.h"
50
#include "util.H1"
51
#include "Gfun.H1"
52
#include "XSpadFill.h"
53
#include "XShade.h"
54
#include "all_3d.H1"
55
56
using namespace OpenAxiom;
57
58
/**********************/
59
/** global variables **/
60
/**********************/
61
62
unsigned long * spadColors;
63
Display *dsply;
64
int scrn;
65
XFontStruct *globalFont, *buttonFont, *headerFont, *titleFont, *graphFont,
66
*lightingFont, *volumeFont, *quitFont, *saveFont,*serverFont;
67
char scaleReport[5];
68
char deltaXReport[5], deltaYReport[5];
69
int followMouse=no,
70
viewportKeyNum=0;
71
Window rtWindow;
72
GC globalGC1, globalGC2, anotherGC, globGC, trashGC,
73
controlMessageGC, lightingGC, volumeGC, quitGC,
74
saveGC, graphGC, componentGC, opaqueGC, renderGC;
75
XSizeHints viewSizeHints;
76
HashTable *table;
77
Colormap colorMap;
78
int Socket=1, ack=1;
79
80
GC processGC;
81
viewPoints *viewport;
82
controlPanelStruct *control;
83
XGCValues gcVals;
84
const char* s;
85
int someInt;
86
87
/* check /usr/include/X11 for current implementation of
88
pixels (e.g. BlackPixel()) */
89
unsigned long foregroundColor, backgroundColor;
90
91
/** totalShades is initially set to totalShadesConst.
92
If X cannot allocate 8 shades for each hue, total-
93
Shades is decremented. there is currently only a check for
94
this value to be positive. --> something to add: change over
95
to monochrome if totalShades=0. just modify the spadcolors.c
96
file. spadcolors.c has been modified so that it returns the
97
value for totalShades. since the return value had previously
98
been unused, a modification in this way ensures continued
99
support of other routines calling this function (e.g.
100
hypertex stuff). **/
101
102
int mono, totalColors, totalSolid, totalDithered, totalHues,
103
totalSolidShades, totalDitheredAndSolids,totalShades;
104
105
int drawMore;
106
107
int spadMode=no, /* yes if receiving OpenAxiom command and
108
calling drawViewport */
109
spadDraw=no; /* yes if drawing viewport for
110
an OpenAxiom command */
111
int spadSignalReceived=0; /* yes if current state is a result of
112
a signal from OpenAxiom */
113
int inNextEvent=no; /* true just before a call to
114
XNextEvent */
115
jmp_buf jumpFlag;
116
117
char errorStr[80];
118
119
view3DStruct viewData;
120
121
Window quitWindow, saveWindow;
122
123
/** variables below assume only one viewport per process **/
124
125
Window lightingWindow, lightingAxes;
126
float lightPointer[3], tempLightPointer[3];
127
128
int axesXY[3][4];
129
float axesZ[3][2];
130
131
float lightIntensity=1.0, tempLightIntensity;
132
float backLightIntensity = 1.0;
133
134
/** used for writing viewport info out to a file **/
135
char filename[256];
136
137
138
/** used for draw viewport routines */
139
float sinTheta, sinPhi, cosTheta, cosPhi, viewScale,
140
viewScaleX, viewScaleY, viewScaleZ, reScale;
141
int xCenter, yCenter;
142
143
XWindowAttributes vwInfo;
144
XWindowAttributes graphWindowAttrib;
145
146
XPoint *quadMesh;
147
XImage *imageX;
148
int *xPts; /* pointer to projected points (x followed by y) */
149
float transform[4][4], transform1[4][4],
150
R[4][4], R1[4][4], S[4][4], T[4][4], I[4][4];
151
float A[4][4], B[4][4], D[4], E[4][4], F[4], array[4][4];
152
153
154
int scanline, polyCount;
155
polyList *scanList[ARRAY_HEIGHT];
156
float xleft = (float)0 ,xright = (float)ARRAY_WIDTH;
157
158
colorBuffer cBuffer[ARRAY_WIDTH];
159
float zBuffer[ARRAY_WIDTH];
160
161
float zC, dzdx, lum, point_norm[3];
162
float intersectColor[2], dcolor;
163
triple dpt, dnorm;
164
165
/** eyePoint **/
166
float eyePoint[3];
167
168
/** tube stuff **/
169
XPoint polygonMesh[20];
170
171
/* bypass the hidden surface algorithm if no rotations, etc */
172
int saveFlag=no;
173
int firstTime=yes, noTrans = yes, startup = yes;
174
int redrawView = no; /* set to yes when returning from
175
subpanels */
176
int redoColor = no, pixelSetFlag = no, redoDither = no;
177
int redoSmooth = no, multiColorFlag = no;
178
179
/* In order to set recalc to true (see draw.h) */
180
int finishedList=no, zoomed=yes, translated = yes,
181
changedIntensity, movingLight = no, writeImage = no,
182
rotated=yes, switchedPerspective, changedEyeDistance,
183
gotToggle = no;
184
poly *quickList;
185
186
/** if not connected to OpenAxiom **/
187
int viewAloned;
188
189
/** for drawing the box **/
190
viewTriple corners[8], clipCorners[8];
191
boxSideStruct box[6], clipBox[6];
192
193
/** for freeing up points created frrom split polygons **/
194
viewTriple *splitPoints;
195
int resMax=0; /* number of points in the split point resevoir */
196
197
/** view volume stuff **/
198
Window volumeWindow;
199
int frustrumVertex;
200
int doingPanel=CONTROLpanel; /* rewrite titles in proper panel */
201
int doingVolume;
202
203
int screenX; /* global floating point indicating mouse position
204
on frustrum screen */
205
float xClipMinN, xClipMaxN, /* normalized values for
206
clip volume */
207
yClipMinN, yClipMaxN,
208
zClipMinN, zClipMaxN,
209
clipValue; /* mouse input */
210
float pzMin, pzMax; /* for a given (theta,phi): calculated in
211
drawViewport(), used in drawFrustrum() */
212
213
/** B/W shades **/
214
int maxGreyShade=0;
215
/** events from the viewport manager **/
216
char propertyName[14];
217
char propertyBuffer[256];
218
219
/* global ps variables */
220
int psInit=no; /* need to call globaInitPs() each run */
221
GCptr GChead=NULL; /* ptr to head of ps GC linked list */
222
char *PSfilename; /* output file name used in user directory */
223
char *envAXIOM; /* used for ps file paths */
224
225
/** Resource database **/
226
XrmDatabase rDB;
227
228
/** variables used for smooth shading **/
229
int smoothError = no;
230
Pixmap viewmap;
231
int viewmap_valid = 0;
232
float Cspec = 0.30;
233
float Cdiff = 0.4;
234
float Camb = 0.3;
235
float coeff = 35.0;
236
float saturation = 0.8;
237
int smoothHue;
238
int smoothConst = 50;
239
240
241
242
int
243
the_handler(Display *display,XErrorEvent *event)
244
{
245
char buffer[512];
246
XGetErrorText(display,event->error_code,buffer,511);
247
fprintf(stderr,"%s\n",buffer);
248
return(0);
249
}
250
251
int
252
main(void)
253
{
254
255
XGCValues controlGCVals;
256
int i;
257
258
char property[256];
259
char *prop = &property[0];
260
char *str_type[20];
261
XrmValue value;
262
263
264
/**** Global inits ****/
265
splitPoints = NIL(viewTriple);
266
267
/**** Set up display ****/
268
if ((dsply = XOpenDisplay(oa_getenv("DISPLAY"))) == NULL)
269
{fprintf(stderr,"Could not open display.\n");exit (-1);}
270
scrn = DefaultScreen(dsply);
271
rtWindow = RootWindow(dsply,scrn);
272
XSetErrorHandler(the_handler);
273
/* XSynchronize(dsply,False); */
274
275
/**** link Xwindows to viewports - X10 feature ****/
276
table = XCreateAssocTable(nbuckets);
277
278
/**** Create OpenAxiom color map ****/
279
totalShades = 0;
280
totalColors = XInitSpadFill(dsply,scrn,&colorMap,
281
&totalHues,&totalSolidShades,
282
&totalDitheredAndSolids,&totalShades);
283
if (totalColors < 0) {
284
fprintf(stderr,"ERROR: Could not allocate all the necessary colors.\n");
285
exitWithAck(RootWindow(dsply,scrn),Window,-1);
286
}
287
288
289
mergeDatabases();
290
291
/*** Determine whether monochrome or color is used ***/
292
if (XrmGetResource(rDB,"Axiom.3D.monochrome","",str_type,&value) == True){
293
(void) strncpy(prop,value.addr,(int)value.size);
294
}
295
else {
296
(void) strcpy(prop, "off");
297
}
298
299
300
mono = ((totalSolid == 2) || (strcmp(prop,"on") == 0));
301
if (mono) maxGreyShade=XInitShades(dsply,scrn) ;
302
303
if (XrmGetResource(rDB,"Axiom.3D.inverse","",str_type,&value) == True){
304
(void) strncpy(prop,value.addr,(int)value.size);
305
}
306
else {
307
(void) strcpy(prop, "off");
308
}
309
310
if (mono) {
311
if (strcmp(prop,"on") == 0) { /* 0 if equal - inverse video */
312
foregroundColor = white;
313
backgroundColor = black;
314
} else { /* off - no inverse video */
315
foregroundColor = black;
316
backgroundColor = white;
317
}
318
} else { /* inverse of inverse in color (for some strange reason) */
319
if (strcmp(prop,"on") == 0) { /* 0 if equal - inverse video */
320
foregroundColor = white;
321
backgroundColor = black;
322
} else { /* off - no inverse video */
323
foregroundColor = black;
324
backgroundColor = white;
325
}
326
}
327
328
/* read default file name for postScript output */
329
if (XrmGetResource(rDB,"Axiom.3D.postscriptFile","",str_type,&value) == True){
330
(void) strncpy(prop,value.addr,(int)value.size);
331
}
332
else {
333
(void) strcpy(prop, "axiom3D.ps");
334
}
335
PSfilename = (char *)malloc(strlen(prop)+1);
336
strcpy(PSfilename,prop);
337
338
XSync(dsply,0);
339
340
/**** Open global fonts ****/
341
serverFont = XQueryFont(dsply,XGContextFromGC(DefaultGC(dsply,scrn)));
342
343
if (XrmGetResource(rDB,"Axiom.3D.messageFont","Axiom.3D.Font",str_type,&value) == True){
344
(void) strncpy(prop,value.addr,(int)value.size);
345
}
346
else {
347
(void) strcpy(prop,messageFontDefault);
348
}
349
if ((globalFont = XLoadQueryFont(dsply, prop)) == NULL) {
350
fprintf(stderr, "Warning: could not get the %s font for messageFont\n",prop);
351
globalFont = serverFont;
352
}
353
354
if (XrmGetResource(rDB,"Axiom.3D.buttonFont","Axiom.3D.Font",str_type,&value) == True){
355
(void) strncpy(prop,value.addr,(int)value.size);
356
}
357
else {
358
(void) strcpy(prop,buttonFontDefault);
359
}
360
if ((buttonFont = XLoadQueryFont(dsply, prop)) == NULL) {
361
fprintf(stderr, "Warning: could not get the %s font for buttonFont\n",prop);
362
buttonFont = serverFont;
363
}
364
365
if (XrmGetResource(rDB,"Axiom.3D.headerFont","Axiom.3D.Font",str_type,&value) == True){
366
(void) strncpy(prop,value.addr,(int)value.size);
367
}
368
else {
369
(void) strcpy(prop,headerFontDefault);
370
}
371
if ((headerFont = XLoadQueryFont(dsply, prop)) == NULL) {
372
fprintf(stderr, "Warning: could not get the %s font for headerFont\n",prop);
373
headerFont = serverFont;
374
}
375
376
if (XrmGetResource(rDB,"Axiom.3D.titleFont","Axiom.3D.Font",str_type,&value) == True){
377
(void) strncpy(prop,value.addr,(int)value.size);
378
}
379
else {
380
(void) strcpy(prop,titleFontDefault);
381
}
382
if ((titleFont = XLoadQueryFont(dsply, prop)) == NULL) {
383
fprintf(stderr, "Warning: could not get the %s font for titleFont\n",prop);
384
titleFont = serverFont;
385
}
386
387
if (XrmGetResource(rDB,"Axiom.3D.lightingFont","Axiom.3D.Font",str_type,&value) == True){
388
(void) strncpy(prop,value.addr,(int)value.size);
389
}
390
else {
391
(void) strcpy(prop,lightingFontDefault);
392
}
393
if ((lightingFont = XLoadQueryFont(dsply, prop)) == NULL) {
394
fprintf(stderr, "Warning: could not get the %s font for lightingFont\n",prop);
395
lightingFont = serverFont;
396
}
397
398
if (XrmGetResource(rDB,"Axiom.3D.volumeFont","Axiom.3D.Font",str_type,&value) == True){
399
(void) strncpy(prop,value.addr,(int)value.size);
400
}
401
else {
402
(void) strcpy(prop,volumeFontDefault);
403
}
404
if ((volumeFont = XLoadQueryFont(dsply, prop)) == NULL) {
405
fprintf(stderr, "Warning: could not get the %s font for volumeFont\n",prop);
406
volumeFont = serverFont;
407
408
}
409
/**** Create widely used Graphic Contexts ****/
410
411
412
PSGlobalInit();
413
/* must initiate before using any G/PS functions */
414
/* need character name: used as postscript GC variable */
415
/* need to create ps GCs for all GCs used by drawing in viewWindow */
416
417
/* globalGC1 */
418
controlGCVals.foreground = monoColor(axesColor);
419
controlGCVals.background = backgroundColor;
420
globalGC1 = XCreateGC(dsply,rtWindow,GCForeground |
421
GCBackground ,&controlGCVals);
422
carefullySetFont(globalGC1,globalFont);
423
PSCreateContext(globalGC1, "globalGC1", psNormalWidth, psButtCap,
424
psMiterJoin, psWhite, psBlack);
425
426
/* controlMessageGC */
427
controlGCVals.foreground = controlMessageColor;
428
controlGCVals.background = backgroundColor;
429
controlMessageGC = XCreateGC(dsply,rtWindow,GCForeground |
430
GCBackground ,&controlGCVals);
431
carefullySetFont(controlMessageGC,globalFont);
432
433
/* globalGC2 */
434
controlGCVals.foreground = monoColor(labelColor);
435
globalGC2 = XCreateGC(dsply,rtWindow,GCForeground,&controlGCVals);
436
carefullySetFont(globalGC2,buttonFont);
437
PSCreateContext(globalGC2, "globalGC2", psNormalWidth, psButtCap,
438
psMiterJoin, psWhite, psBlack);
439
440
/* trashGC */
441
controlGCVals.function = GXcopy;
442
trashGC = XCreateGC(dsply,rtWindow,0 ,&controlGCVals);
443
carefullySetFont(trashGC,buttonFont);
444
PSCreateContext(trashGC, "trashGC", psNormalWidth, psButtCap,
445
psMiterJoin, psWhite, psBlack);
446
447
/* componentGC */
448
componentGC = XCreateGC(dsply,rtWindow,0 ,&controlGCVals);
449
carefullySetFont(componentGC,buttonFont);
450
PSCreateContext(componentGC, "componentGC", psNormalWidth, psButtCap,
451
psMiterJoin, psWhite, psBlack);
452
453
/* opaqueGC */
454
opaqueGC = XCreateGC(dsply,rtWindow,0 ,&controlGCVals);
455
carefullySetFont(opaqueGC,buttonFont);
456
PSCreateContext(opaqueGC, "opaqueGC", psNormalWidth, psButtCap,
457
psMiterJoin, psWhite, psBlack);
458
459
/* renderGC */
460
renderGC = XCreateGC(dsply,rtWindow,0,&controlGCVals);
461
carefullySetFont(renderGC,buttonFont);
462
PSCreateContext(renderGC, "renderGC", psNormalWidth, psButtCap,
463
psMiterJoin, psWhite, psBlack);
464
465
/* globGC */
466
globGC = XCreateGC(dsply,rtWindow,0,&controlGCVals);
467
carefullySetFont(globGC,headerFont);
468
PSCreateContext(globGC, "globGC", psNormalWidth, psButtCap,
469
psMiterJoin, psWhite, psBlack);
470
471
/* anotherGC */
472
controlGCVals.line_width = colorWidth;
473
anotherGC = XCreateGC(dsply,rtWindow,GCBackground | GCLineWidth |
474
GCFunction ,&controlGCVals);
475
carefullySetFont(anotherGC,titleFont);
476
PSCreateContext(anotherGC, "anotherGC", psNormalWidth, psButtCap,
477
psMiterJoin, psWhite, psBlack);
478
479
/* also create one for rendering (grayscale only for now) */
480
/* assign arbitrary number to renderGC as 9991 - see header.h */
481
PSCreateContext(GC9991, "renderGC", psNormalWidth, psButtCap,
482
psRoundJoin, psWhite, psBlack );
483
484
485
/* processGC */
486
gcVals.background = backgroundColor;
487
processGC = XCreateGC(dsply,rtWindow,GCBackground |
488
GCFillStyle,&gcVals);
489
carefullySetFont(processGC,buttonFont);
490
491
/* lightingGC */
492
controlGCVals.foreground = monoColor(axesColor);
493
controlGCVals.background = backgroundColor;
494
lightingGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
495
,&controlGCVals);
496
carefullySetFont(lightingGC,lightingFont);
497
498
499
/* volumeGC */
500
volumeGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
501
,&controlGCVals);
502
carefullySetFont(volumeGC,volumeFont);
503
504
/* quitGC */
505
quitGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
506
,&controlGCVals);
507
carefullySetFont(quitGC,buttonFont);
508
509
/* saveGC */
510
saveGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
511
,&controlGCVals);
512
carefullySetFont(saveGC,buttonFont);
513
514
515
/* graphGC */
516
graphGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
517
,&controlGCVals);
518
carefullySetFont(graphGC,buttonFont);
519
520
/**** Get Data from the Viewport Manager ****/
521
522
i = 123; /* Used in viewman, what is this for? */
523
check(write(Socket,&i,intSize));
524
525
/* Check if I am getting stuff from OpenAxiom or, if I am viewAlone. */
526
readViewman(&viewAloned,intSize);
527
readViewman(&viewData,sizeof(view3DStruct));
528
readViewman(&i,intSize);
529
530
if (!(viewData.title = (char *)saymem("main.c",i,sizeof(char)))) {
531
fprintf(stderr,"VIEW3D: Fatal Error>> Ran out of memory trying to receive\
532
the title.\n");
533
exitWithAck(RootWindow(dsply,scrn),Window,-1);
534
}
535
readViewman(viewData.title,i);
536
537
readViewman(&(viewData.lightVec[0]),floatSize);
538
readViewman(&(viewData.lightVec[1]),floatSize);
539
readViewman(&(viewData.lightVec[2]),floatSize);
540
541
viewData.scaleDown = yes;
542
543
switch (viewData.typeOf3D) {
544
545
/* Currently, the view3DType information doesn't get sent from
546
OpenAxiom - all surfaces are alike regardless of how they
547
were created. We may revert back to receiving this information
548
in case we want to take advantage of certain properties of
549
certain surfaces (e.g. z=f(x,y)). */
550
551
case view3DType:
552
case viewTubeType:
553
viewport = make3DComponents();
554
viewData.box = no;
555
viewData.pointSize = 3;
556
break;
557
}; /* switch typeOf3D */
558
559
560
/*************************************************
561
** Do some temporary assignments that would **
562
** later be coded in the makeViewport routines **
563
** when the corresponding code has been put **
564
** into the viewAlone, viewman and spad files. **
565
*************************************************/
566
567
viewData.distortX = viewData.distortY = viewData.distortZ = 1;
568
viewData.clipPlane = clipPlaneMin;
569
viewData.clipStuff = yes;
570
571
xClipMinN = yClipMinN = zClipMinN = 0.0;
572
xClipMaxN = yClipMaxN = zClipMaxN = 1.0;
573
574
control = viewport->controlPanel;
575
576
bsdSignal(SIGTERM,goodbye,DontRestartSystemCalls);
577
bsdSignal(SIGSEGV,goodbye,DontRestartSystemCalls);
578
579
/** send acknowledgement to viewport manager**/
580
i = 345;
581
582
sprintf(errorStr,"sending window info to viewport manager");
583
check(write(Socket,&(viewport->viewWindow),sizeof(Window)));
584
585
viewmap = XCreatePixmap(dsply,viewport->viewWindow,
586
vwInfo.width,vwInfo.height,
587
DisplayPlanes(dsply,scrn));
588
viewmap_valid = 1;
589
590
processEvents();
591
592
goodbye(-1);
593
return(0); /* control never gets here but compiler complains */
594
} /* main() */
595
596
597
598
void
599
mergeDatabases(void)
600
{
601
XrmDatabase homeDB,serverDB,applicationDB;
602
char filenamebuf[1024];
603
char *filename = &filenamebuf[0];
604
const char *classname = "OpenAxiom";
605
char name[255];
606
607
(void) XrmInitialize();
608
(void) strcpy(name, "/usr/lib/X11/app-defaults/");
609
(void) strcat(name, classname);
610
applicationDB = XrmGetFileDatabase(name);
611
(void) XrmMergeDatabases(applicationDB, &rDB);
612
613
if (XResourceManagerString(dsply) != NULL){
614
serverDB = XrmGetStringDatabase(XResourceManagerString(dsply));
615
}
616
else {
617
(void) strcpy(filename,oa_getenv("HOME"));
618
(void) strcat(filename,"/.Xdefaults");
619
serverDB = XrmGetFileDatabase(filename);
620
}
621
XrmMergeDatabases(serverDB,&rDB);
622
if ( oa_getenv ("XENVIRONMENT") == NULL) {
623
int len;
624
(void) strcpy(filename,oa_getenv("HOME"));
625
(void) strcat(filename,"/.Xdefaults-");
626
len = strlen(filename);
627
628
(void) gethostname(filename+len,1024-len);
629
630
}
631
else {
632
(void) strcpy (filename,oa_getenv ("XENVIRONMENT"));
633
}
634
homeDB = XrmGetFileDatabase(filename);
635
XrmMergeDatabases(homeDB,&rDB);
636
}
637
638
639