1 /*
2 * This file is part of the XForms library package.
3 *
4 * XForms is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as
6 * published by the Free Software Foundation; either version 2.1, or
7 * (at your option) any later version.
8 *
9 * XForms is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with XForms. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18
19 /**
20 * \file flresource.c
21 *
22 * This file is part of the XForms library package.
23 * Copyright (c) 1996-2002 T.C. Zhao
24 * All rights reserved.
25 *
26 * Handle XResources. Only rudimetry support is implemented. However,
27 * using this minimum implementation, more powerful and application
28 * specific resources can be developed easily.
29 */
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include "include/forms.h"
36 #include "flinternal.h"
37 #include "private/flsnprintf.h"
38 #include <X11/Xresource.h>
39 #include <ctype.h>
40 #include <sys/types.h>
41
42 #if 0
43 #include <locale.h>
44 #endif
45
46 #ifdef FL_WIN32
47 #include <X11/Xw32defs.h>
48 #endif
49
50
51 FLI_WM_STUFF fli_wmstuff; /* also used in win.c */
52 static XrmDatabase fldatabase; /* final merged database */
53 static XrmDatabase cmddb; /* command line database */
54 static char *fl_app_name,
55 *fl_app_class,
56 *fl_ori_app_name;
57
58 static void fli_init_resources( void );
59 static void fli_set_debug_level( int );
60
61 /* Command line options */
62
63 static XrmOptionDescRec copt[ ] =
64 {
65 { "-fldebug", "*fldebug", XrmoptionSepArg, ( caddr_t ) "0" },
66 { "-flversion", "*flversion", XrmoptionNoArg, ( caddr_t ) "1" },
67 { "-flhelp", "*flhelp", XrmoptionNoArg, ( caddr_t ) "1" },
68 { "-name", ".name", XrmoptionSepArg, ( caddr_t ) 0 },
69 { "-display", ".display", XrmoptionSepArg, ( caddr_t ) 0 },
70 { "-sync", "*sync", XrmoptionNoArg, ( caddr_t ) "1" },
71 { "-depth", "*depth", XrmoptionSepArg, ( caddr_t ) 0 },
72 { "-visual", "*visual", XrmoptionSepArg, ( caddr_t ) 0 },
73 { "-private", "*privateColormap", XrmoptionNoArg, ( caddr_t ) "1" },
74 { "-shared", "*sharedColormap", XrmoptionNoArg, ( caddr_t ) "1" },
75 { "-standard", "*standardColormap", XrmoptionNoArg, ( caddr_t ) "1" },
76 { "-stdcmap", "*standardColormap", XrmoptionNoArg, ( caddr_t ) "1" },
77 { "-double", "*doubleBuffer", XrmoptionNoArg, ( caddr_t ) "1" },
78 { "-bw", "*borderWidth", XrmoptionSepArg, ( caddr_t ) 0 },
79 { "-vid", "*visualID", XrmoptionSepArg, ( caddr_t ) 0 },
80
81 #ifdef DO_GAMMA_CORRECTION
82 { "-rgamma", "*rgamma", XrmoptionSepArg, ( caddr_t ) 0 },
83 { "-bgamma", "*bgamma", XrmoptionSepArg, ( caddr_t ) 0 },
84 { "-ggamma", "*ggamma", XrmoptionSepArg, ( caddr_t ) 0 },
85 #endif
86
87 { "-bs", "*backingStore", XrmoptionNoArg, ( caddr_t ) "0" }
88 };
89
90 #define Ncopt ( sizeof copt / sizeof *copt )
91
92
93 /* Other resources */
94
95 #define PV( a ) &( fli_cntl.a )
96 #define PS( a ) ( fli_cntl.a )
97 #define NS( a ) #a
98
99
100 /* xform and XForm will be generated on the fly */
101
102 typedef char Bop[ 8 ]; /* Boolean default */
103 typedef char Iop[ 8 ]; /* Integer default */
104 static Bop OpPrivateMap,
105 OpSharedMap,
106 OpStandardMap,
107 OpDouble;
108 static Bop OpSync,
109 OpULW = "1";
110 static Iop OpDebug,
111 OpDepth,
112 OpULT = "-1";
113 static char OpBS[ 12 ] = "1"; /* whenmapped */
114 static char OpSafe[ 12 ];
115 static char OpSCBT[ 16 ] = "thin";
116 static char OpBLsize[ 20 ] = NS( FL_DEFAULT_SIZE );
117 static char OpMLsize[ 20 ] = NS( FL_DEFAULT_SIZE );
118 static char OpBrFsize[ 20 ] = NS( FL_DEFAULT_SIZE );
119 static char OpChFsize[ 20 ] = NS( FL_DEFAULT_SIZE );
120 static char OpSLsize[ 20 ] = NS( FL_DEFAULT_SIZE );
121 static char OpLLsize[ 20 ] = NS( FL_DEFAULT_SIZE );
122 static char OpILsize[ 20 ] = NS( FL_DEFAULT_SIZE );
123 static char OpIBW[ 20 ] = NS( FL_BOUND_WIDTH );
124 static char OpPsize[ 20 ] = NS( FL_DEFAULT_SIZE );
125 static char OpVisualID[ 20 ] = "0";
126
127 #ifdef DO_GAMMA_CORRECTION
128 static char OpRgamma[ 12 ] = "1";
129 static char OpGgamma[ 12 ] = "1";
130 static char OpBgamma[ 12 ] = "1";
131 #endif
132
133 static char OpCoordUnit[ 32 ];
134
135 static FLI_VN_PAIR vn_coordunit[ ] =
136 {
137 { FL_COORD_PIXEL, "pixel" },
138 { FL_COORD_MM, "mm" },
139 { FL_COORD_POINT, "point" },
140 { FL_COORD_centiPOINT, "centipoint" },
141 { FL_COORD_centiPOINT, "cp" },
142 { FL_COORD_centiMM, "centimm" },
143 { FL_COORD_centiMM, "cmm" },
144 { -1, "Invalid" },
145 { -1, NULL }
146 };
147
148
149 #define SetR( name, rclass, type, deft, buflen ) \
150 { #name, rclass, type, &fli_cntl.name, deft, buflen }
151
152
153 static FL_resource internal_resources[ ] =
154 {
155 SetR( debug, "Debug", FL_INT, OpDebug, 0 ),
156 SetR( sync, "Sync", FL_BOOL, OpSync, 0 ),
157
158 #ifdef DO_GAMMA_CORRECTION
159 SetR( rgamma, "Gamma", FL_FLOAT, OpRgamma, 0 ),
160 SetR( ggamma, "Gamma", FL_FLOAT, OpGgamma, 0 ),
161 SetR( bgamma, "Gamma", FL_FLOAT, OpBgamma, 0 ),
162 #endif
163
164 SetR( depth, "Depth", FL_INT, OpDepth, 0 ),
165 { "visual", "Visual", FL_STRING, PS( vname ), PS( vname ), 20 },
166 { "scrollbarType", "ScrollbarType", FL_STRING, OpSCBT, OpSCBT, 16 },
167 SetR( doubleBuffer, "DoubleBuffer", FL_BOOL, OpDouble, 0 ),
168 SetR( ulThickness, "ULThickness", FL_INT, OpULT, 0 ),
169 SetR( privateColormap, "PrivateColormap", FL_BOOL, OpPrivateMap, 0 ),
170 SetR( sharedColormap, "SharedColormap", FL_BOOL, OpSharedMap, 0 ),
171 SetR( standardColormap, "StandardColormap", FL_BOOL, OpStandardMap, 0 ),
172 SetR( buttonFontSize, "FontSize", FL_INT, OpBLsize, 0 ),
173 SetR( menuFontSize, "FontSize", FL_INT, OpMLsize, 0 ),
174 SetR( choiceFontSize, "FontSize", FL_INT, OpChFsize, 0 ),
175 SetR( browserFontSize, "FontSize", FL_INT, OpBrFsize, 0 ),
176 SetR( labelFontSize, "FontSize", FL_INT, OpLLsize, 0 ),
177 SetR( sliderLabelSize, "FontSize", FL_INT, OpSLsize, 0 ),
178 SetR( inputLabelSize, "FontSize", FL_INT, OpILsize, 0 ),
179 SetR( pupFontSize, "PupFontSize", FL_INT, OpPsize, 0 ),
180 SetR( borderWidth, "BorderWidth", FL_INT, OpIBW, 0 ),
181 SetR( ulPropWidth, "ULWidth", FL_BOOL, OpULW, 0 ),
182 SetR( backingStore, "BackingStore", FL_INT, OpBS, 0 ),
183 SetR( safe, "Safe", FL_INT, OpSafe, 0 ),
184 { "coordUnit", "CoordUnit", FL_STRING, OpCoordUnit, OpCoordUnit, 32 },
185 { "visualID", "VisualID", FL_LONG, &fli_requested_vid, OpVisualID, 0 }
186 };
187
188 #define Niopt ( sizeof internal_resources / sizeof *internal_resources )
189
190
191 /* Program can set its own default, overriding XForms default */
192
193 #define SetMember( a ) fli_cntl.a = cntl->a
194
195
196 /***************************************
197 ***************************************/
198
199 void
fl_set_defaults(unsigned long mask,FL_IOPT * cntl)200 fl_set_defaults( unsigned long mask,
201 FL_IOPT * cntl )
202 {
203 if ( mask & FL_PDPrivateMap )
204 {
205 SetMember( privateColormap );
206 sprintf( OpPrivateMap, "%d", cntl->privateColormap != 0 );
207 }
208
209 if ( mask & FL_PDSharedMap )
210 {
211 SetMember( sharedColormap );
212 sprintf( OpSharedMap, "%d", cntl->sharedColormap != 0 );
213 }
214
215 if ( mask & FL_PDStandardMap )
216 {
217 SetMember( standardColormap );
218 sprintf( OpStandardMap, "%d", cntl->standardColormap != 0 );
219 }
220
221 if ( mask & FL_PDDouble )
222 {
223 SetMember( doubleBuffer );
224 sprintf( OpDouble, "%d", cntl->doubleBuffer != 0 );
225 }
226
227 if ( mask & FL_PDDepth )
228 {
229 SetMember( depth );
230 sprintf( OpDepth, "%d", cntl->depth );
231 }
232
233 if ( mask & FL_PDVisual )
234 {
235 SetMember( vclass );
236 strcpy( fli_cntl.vname, fli_vclass_name( cntl->vclass ) );
237 }
238
239 if ( mask & FL_PDButtonFontSize )
240 {
241 SetMember( buttonFontSize );
242 sprintf( OpBLsize, "%d", cntl->buttonFontSize );
243 }
244
245 if ( mask & FL_PDBrowserFontSize )
246 {
247 SetMember( browserFontSize );
248 sprintf( OpBrFsize, "%d", cntl->browserFontSize );
249 }
250
251 if ( mask & FL_PDMenuFontSize )
252 {
253 SetMember( menuFontSize );
254 sprintf( OpMLsize, "%d", cntl->menuFontSize );
255 }
256
257 if ( mask & FL_PDChoiceFontSize )
258 {
259 SetMember( choiceFontSize );
260 sprintf( OpChFsize, "%d", cntl->choiceFontSize );
261 }
262
263 if ( mask & FL_PDSliderFontSize )
264 {
265 SetMember( sliderFontSize );
266 sprintf( OpSLsize, "%d", cntl->sliderFontSize );
267 }
268
269 if ( mask & FL_PDInputFontSize )
270 {
271 SetMember( inputFontSize );
272 sprintf( OpILsize, "%d", cntl->inputFontSize );
273 }
274
275 if ( mask & FL_PDLabelFontSize )
276 {
277 SetMember( labelFontSize );
278 sprintf( OpLLsize, "%d", cntl->labelFontSize );
279 }
280
281 if ( mask & FL_PDBorderWidth )
282 fl_set_border_width( cntl->borderWidth );
283
284 if ( mask & FL_PDScrollbarType )
285 fl_set_scrollbar_type( cntl->scrollbarType );
286
287 if ( mask & FL_PDPupFontSize )
288 {
289 SetMember( pupFontSize );
290 sprintf( OpPsize, "%d", cntl->pupFontSize );
291 }
292
293 if ( mask & FL_PDSafe )
294 {
295 SetMember( safe );
296 sprintf( OpSafe, "%d", cntl->safe );
297 }
298
299 if ( mask & FL_PDBS )
300 {
301 SetMember( backingStore );
302 sprintf( OpBS, "%d", cntl->backingStore );
303 }
304
305 if ( mask & FL_PDCoordUnit )
306 fl_set_coordunit( cntl->coordUnit );
307
308 if ( mask & FL_PDDebug )
309 fli_set_debug_level( cntl->debug );
310 }
311
312
313 /***************************************
314 * Convenience functions
315 ***************************************/
316
317 void
fl_set_coordunit(int u)318 fl_set_coordunit( int u )
319 {
320 const char * cu = fli_get_vn_name( vn_coordunit, u );
321
322 if ( cu == NULL )
323 {
324 M_err( "fl_set_coordunit",
325 "Invald coord unit, defaulting to \"pixel\"" );
326 u = FL_COORD_PIXEL;
327 cu = "pixel";
328 }
329
330 fli_cntl.coordUnit = u;
331 strcpy( OpCoordUnit, cu );
332 }
333
334
335 /***************************************
336 ***************************************/
337
338 void
fl_set_border_width(int bw)339 fl_set_border_width( int bw )
340 {
341 fli_cntl.borderWidth = bw;
342 sprintf( OpIBW, "%d", bw );
343 }
344
345
346 /***************************************
347 ***************************************/
348
349 void
fl_set_scrollbar_type(int t)350 fl_set_scrollbar_type( int t )
351 {
352 fli_cntl.scrollbarType = t;
353
354 if ( t == FL_NORMAL_SCROLLBAR )
355 strcpy( OpSCBT, "normal" );
356 else if ( t == FL_NICE_SCROLLBAR )
357 strcpy( OpSCBT, "nice" );
358 else if ( t == FL_PLAIN_SCROLLBAR )
359 strcpy( OpSCBT, "plain" );
360 else
361 strcpy( OpSCBT, "thin" );
362 }
363
364
365 /***************************************
366 ***************************************/
367
368 void
fl_set_visualID(long id)369 fl_set_visualID( long id )
370 {
371 fli_requested_vid = id;
372 sprintf( OpVisualID, "0x%lx", id );
373 }
374
375
376 /***************************************
377 ***************************************/
378
379 int
fl_get_border_width(void)380 fl_get_border_width( void )
381 {
382 return fli_cntl.borderWidth;
383 }
384
385
386 /***************************************
387 ***************************************/
388
389 int
fl_get_coordunit(void)390 fl_get_coordunit( void )
391 {
392 return fli_cntl.coordUnit;
393 }
394
395
396 /***************************************
397 ***************************************/
398
399 static void
fli_set_debug_level(int l)400 fli_set_debug_level( int l )
401 {
402 fli_cntl.debug = l;
403 sprintf( OpDebug, "%d", fli_cntl.debug );
404 fli_set_msg_threshold( fli_cntl.debug );
405 }
406
407
408 /***************************************
409 * Handle XAPPLRESDIR (colon seperated directories) specification.
410 * Ignore the %T %N stuff
411 ***************************************/
412
413 static void
handle_applresdir(const char * rstr,const char * appclass)414 handle_applresdir( const char * rstr,
415 const char * appclass )
416 {
417 char *tok;
418 char rbuf[ 512 ],
419 buf[ 512 ];
420 XrmDatabase fdb = 0;
421
422 strcpy( rbuf, rstr );
423 for ( tok = strtok( rbuf, ":" ); tok; tok = strtok( 0, ":" ) )
424 {
425 fli_snprintf( buf, sizeof buf,"%s/%s", tok,appclass );
426 M_info( "handle_applresdir", "Trying XAPPLRESDIR: %s", buf );
427 if ( ( fdb = XrmGetFileDatabase( buf ) ) )
428 {
429 XrmMergeDatabases( fdb, &fldatabase );
430 M_warn( "handle_applresdir", "XAPPLRESDIR %s loaded", buf );
431 }
432 }
433 }
434
435
436 /***************************************
437 * Routine to merge all resource databases, excluding the commandline,
438 * which is done in fl_initialize.
439 ***************************************/
440
441 static void
init_resource_database(const char * appclass)442 init_resource_database( const char *appclass )
443 {
444 char buf[ FL_PATH_MAX + 127 ],
445 * rstr;
446 XrmDatabase fdb = 0;
447
448 if ( ! fl_display )
449 {
450 M_err( "init_resource_database", "fl_initialize is not called" );
451 return;
452 }
453
454 if ( fldatabase )
455 return;
456
457 XrmInitialize( );
458
459 #ifdef __VMS
460 /* For the VMS version try to load the resources from, in this order,
461
462 DECW$SYSTEM_DEFAULTS:appclass.DAT
463 DECW$USER_DEFAULTS:appclass.DAT
464 DECW$USER_DEFAULTS:DECW$XDEFAULTS.DAT
465 The window resource manager for this display
466 */
467
468 fli_snprintf( buf, sizeof buf, "DECW$SYSTEM_DEFAULTS:%s.DAT", appclass );
469 M_info( "init_resource_database", "Trying Sys_default: %s", buf );
470 if ( ( fdb = XrmGetFileDatabase( buf ) ) )
471 {
472 XrmMergeDatabases( fdb, &fldatabase );
473 M_warn( "init_resource_database", "System default %s loaded", buf );
474 }
475
476 fli_snprintf( buf, sizeof buf, "DECW$USER_DEFAULTS:%s.DAT", appclass );
477 M_info( "init_resource_database", "Trying User_default: %s", buf );
478 if ( ( fdb = XrmGetFileDatabase( buf ) ) )
479 {
480 XrmMergeDatabases( fdb, &fldatabase );
481 M_warn( "init_resource_database", "System default %s loaded", buf );
482 }
483
484 fli_snprintf( buf, sizeof buf, "DECW$USER_DEFAULTS:DECW$XDEFAULTS.DAT" );
485 M_info( "init_resource_database", "Trying Sys_default: %s", buf );
486 if ( ( fdb = XrmGetFileDatabase( buf ) ) )
487 {
488 XrmMergeDatabases( fdb, &fldatabase );
489 M_warn( "init_resource_database", "System default %s loaded", buf );
490 }
491
492 M_info( "init_resource_database", "Trying RESOURCE_MANAGER" );
493 if ( ( rstr = XResourceManagerString( fl_display ) ) )
494 {
495 if ( ( fdb = XrmGetStringDatabase( rstr ) ) )
496 {
497 XrmMergeDatabases( fdb, &fldatabase );
498 M_warn( "init_resource_database", "RESOURCE_MANAGER loaded" );
499 }
500 }
501 #else /* !VMS */
502
503 fli_snprintf( buf, sizeof buf, "/usr/lib/X11/app-defaults/%s", appclass );
504 M_info( "init_resource_database", "Trying Sys_default: %s", buf );
505 if ( ( fdb = XrmGetFileDatabase( buf ) ) )
506 {
507 XrmMergeDatabases( fdb, &fldatabase );
508 M_warn( "init_resource_database", "System default %s loaded", buf );
509 }
510
511 /* try XAPPLRESDIR */
512
513 M_info( "init_resource_database", "Trying XAPPLRESDIR" );
514 if ( ( rstr = getenv( "XAPPLRESDIR" ) ) )
515 handle_applresdir( rstr, appclass );
516
517 /* try server defined resources */
518
519 M_info( "init_resource_database", "Trying RESOURCE_MANAGER" );
520 if ( ( rstr = XResourceManagerString( fl_display ) ) )
521 {
522 if ( ( fdb = XrmGetStringDatabase( rstr ) ) )
523 {
524 XrmMergeDatabases( fdb, &fldatabase );
525 M_warn( "init_resource_database", "RESOURCE_MANAGER loaded" );
526 }
527 }
528 else
529 {
530 /* Try ~/.Xdefaults */
531
532 if ( ( rstr = getenv( "HOME" ) ) )
533 {
534 fli_snprintf( buf, sizeof buf,"%s/.Xdefaults", rstr );
535 M_info( "init_resource_database", "Trying %s", buf );
536 if ( ( fdb = XrmGetFileDatabase( buf ) ) )
537 {
538 XrmMergeDatabases( fdb, &fldatabase );
539 M_warn( "init_resource_database", "%s loaded", buf );
540 }
541 }
542 }
543
544 /* Load file XENVIRONMENT */
545
546 M_info( "init_resource_database",
547 "Trying environment variable XEVIRONMENT" );
548 if ( ( rstr = getenv( "XENVIRONMENT" ) ) )
549 {
550 if ( ( fdb = XrmGetFileDatabase( rstr ) ) )
551 {
552 XrmMergeDatabases( fdb, &fldatabase );
553 M_warn( "init_resource_database", "%s loaded", rstr );
554 }
555 }
556 else
557 {
558 /* ~/.Xdefaults-<hostname> */
559
560 M_info( "init_resource_database", "Trying ~/.Xdefaults-<hostname>" );
561 if ( ( rstr = getenv( "HOME" ) ) )
562 {
563 int l;
564
565 fli_snprintf( buf, sizeof buf,"%s/.Xdefaults", rstr );
566 l = strlen( strcat( buf, "-" ) );
567 gethostname( buf + l, sizeof buf - l );
568 M_info( "init_resource_database", "Trying %s", buf );
569 if ( ( fdb = XrmGetFileDatabase( buf ) ) )
570 {
571 XrmMergeDatabases( fdb, &fldatabase );
572 M_warn( "init_resource_database", "%s loaded", buf );
573 }
574 }
575 }
576 #endif /* VMS */
577
578 errno = 0;
579
580 if ( ! fldatabase )
581 {
582 M_warn( "init_resource_database",
583 "Can't find any resource databases!" );
584 return;
585 }
586 }
587
588
589 /***************************************
590 ***************************************/
591
592 static int
is_true(const char * s)593 is_true( const char * s )
594 {
595 return strncmp( s, "True", 4 ) == 0
596 || strncmp( s, "true", 4 ) == 0
597 || strncmp( s, "Yes", 3 ) == 0
598 || strncmp( s, "yes", 3 ) == 0
599 || strncmp( s, "On", 2 ) == 0
600 || strncmp( s, "on", 2 ) == 0
601 || *s == '1';
602 }
603
604
605 /***************************************
606 * The resource routine of the lowest level. Only adds the application
607 * name.
608 *
609 * Return the string representation of the resource value
610 ***************************************/
611
612 const char *
fl_get_resource(const char * rname,const char * cname,FL_RTYPE dtype,const char * defval,void * val,int size)613 fl_get_resource( const char * rname, /* resource name */
614 const char * cname, /* class name */
615 FL_RTYPE dtype, /* data type */
616 const char * defval, /* default */
617 void * val, /* variable */
618 int size ) /* buffer size if string */
619 {
620 XrmValue entry = { 0, NULL };
621 char * type = NULL;
622 char res_name[ 256 ] = "",
623 res_class[ 256 ] = "";
624
625
626 if ( ! ( rname && * rname ) && ! ( cname && *cname ) )
627 return NULL;
628
629 if ( rname && *rname )
630 fli_snprintf( res_name, sizeof res_name, "%s.%s", fl_app_name, rname );
631 else
632 fli_snprintf( res_class, sizeof res_class, "%s.%s",
633 fl_app_class, cname );
634
635 /* Just checking the return value of XrmGetResource() doesn't seem to
636 work (as it should, unless I completely misunderstand the man
637 page), and 'entry' seems to return the same data as on a previous
638 call (despite the initialization!), but 'type' seems to get set to
639 NULL in cases of failure to find the requested resource in the
640 database. So in that case we try to use the default value. JTT */
641
642 if ( ! XrmGetResource( fldatabase, res_name, res_class, &type, &entry )
643 || ! type
644 || strcmp( type, "String" )
645 || ! entry.addr )
646 {
647 M_warn( "fl_get_resource", "%s (%s): not found", res_name, res_class );
648 entry.addr = ( XPointer ) defval;
649 }
650 else
651 M_info( "fl_get_resource", "%s (%s): %s", res_name, res_class,
652 entry.addr );
653
654 if ( dtype == FL_NONE || ! entry.addr )
655 return entry.addr;
656
657 switch ( dtype )
658 {
659 case FL_SHORT:
660 * ( short * ) val = strtol( entry.addr, NULL, 10 );
661 break;
662
663 case FL_INT:
664 * ( int * ) val = strtol( entry.addr, NULL, 10 );
665 break;
666
667 case FL_BOOL:
668 * ( int * ) val = is_true( entry.addr );
669 break;
670
671 case FL_LONG:
672 * ( long * ) val = strtol( entry.addr, NULL, 10 );
673 break;
674
675 case FL_FLOAT:
676 * ( float * ) val = atof( entry.addr );
677 break;
678
679 case FL_STRING:
680 if ( val && val != entry.addr && size > 0 )
681 {
682 strncpy( val, entry.addr, size );
683 ( ( char * ) val )[ size - 1 ] = '\0';
684 }
685 break;
686
687 default:
688 M_err( "fl_get_resource", "Unknown type %d", dtype );
689 return NULL;
690 }
691
692 return entry.addr;
693 }
694
695
696 /***************************************
697 ***************************************/
698
699 void
fl_set_resource(const char * str,const char * val)700 fl_set_resource( const char * str,
701 const char * val )
702 {
703 char res_name[ 256 ];
704
705 fli_snprintf( res_name, sizeof res_name, "%s.%s", fl_app_name, str );
706 XrmPutStringResource( &fldatabase, res_name, ( char * ) val );
707 }
708
709
710 /***************************************
711 * internal resource initialization
712 ***************************************/
713
714 static void
fli_init_resources(void)715 fli_init_resources( void )
716 {
717 char res[ 256 ],
718 cls[ 256 ],
719 ores[ 256 ];
720 char * appname = fl_app_name,
721 * appclass = fl_app_class;
722 char * ori_appname = fl_ori_app_name;
723
724 /* internal resources need to be prefixed xform and XForm. need to
725 generate for all names */
726
727 fli_snprintf( cls, sizeof cls, "%s.XForm", fl_app_class );
728 fl_app_class = cls;
729 fli_snprintf( res, sizeof res, "%s.xform", fl_app_name );
730 fl_app_name = res;
731 fli_snprintf( ores, sizeof ores, "%s.xform", fl_ori_app_name );
732 fl_ori_app_name = ores;
733 fl_get_app_resources( internal_resources, Niopt );
734
735 fl_app_name = appname;
736 fl_app_class = appclass;
737 fl_ori_app_name = ori_appname;
738
739 if ( fli_cntl.sync )
740 {
741 XSynchronize( fl_display, 1 );
742 M_err( "fli_init_resources", "**** Synchronous Mode ********" );
743 fli_set_debug_level( 4 );
744 }
745 }
746
747
748 static int fli_argc;
749 static char ** fli_argv;
750
751
752 /***************************************
753 ***************************************/
754
755 static void
dup_argv(char ** argv,int n)756 dup_argv( char ** argv,
757 int n )
758 {
759 int i;
760
761 if ( ! argv )
762 return;
763
764 if ( ! fli_argv )
765 fli_argv = fl_malloc( ( n + 1 ) * sizeof *fli_argv );
766
767 for ( i = 0; i < n; i++ )
768 fli_argv[ i ] = fl_strdup( argv[ i ] );
769
770 fli_argv[ i ] = NULL;
771 }
772
773
774 /***************************************
775 ***************************************/
776
777 char **
fl_get_cmdline_args(int * n)778 fl_get_cmdline_args( int * n )
779 {
780 *n = fli_argc;
781 return fli_argv;
782 }
783
784
785 /***************************************
786 ***************************************/
787
788 void
fli_free_cmdline_args(void)789 fli_free_cmdline_args( void )
790 {
791 size_t i;
792
793 if ( ! fli_argv )
794 return;
795
796 for ( i = 0; fli_argv[ i ]; i++ )
797 fli_safe_free( fli_argv[ i ] );
798
799 fli_safe_free( fli_argv );
800 }
801
802
803 /***************************************
804 * find the command name from arg[0] and return a copy of it
805 ***************************************/
806
807 static char *
get_command_name(const char * arg0)808 get_command_name( const char * arg0 )
809 {
810 char *p;
811 char *s = fl_strdup( arg0 );
812 char *cmd_name = s;
813
814 #ifdef __VMS
815 /* vms command disk:[path]command.exe */
816
817 if ( ( p = strrchr( s, ']' ) ) )
818 cmd_name = p + 1;
819 #else
820 #ifdef FL_WIN32
821 _splitpath( arg0, NULL, NULL, cmd_name, NULL );
822 #else
823 if ( ( p = strrchr( s, '/' ) ) )
824 cmd_name = p + 1;
825 #endif
826 #endif
827
828 /* Remove the extension and the period */
829
830 if ( ( p = strrchr( cmd_name, '.' ) ) )
831 *p = '\0';
832
833 /* Prevent a valgrind warning about a possible memory leak. */
834
835 if ( s != cmd_name )
836 {
837 cmd_name = fl_strdup( cmd_name );
838 fl_free( s );
839 }
840
841 return cmd_name;
842 }
843
844
845 /*
846 * Global Routines to do the initialization and resource management
847 *
848 */
849
850 #define DumpD( a ) fprintf( stderr,"\t%s:%d\n", #a, fli_cntl.a )
851 #define DumpS( a ) fprintf( stderr,"\t%s:%s\n", #a, fli_cntl.a )
852 #define DumpF( a ) fprintf( stderr,"\t%s:%.3f\n", #a, fli_cntl.a )
853
854 static Window fli_GetVRoot( Display *,
855 int );
856
857
858 /***************************************
859 * initialize context
860 ***************************************/
861
862 void
fli_init_context(void)863 fli_init_context( void )
864 {
865 if ( fli_context )
866 return;
867
868 if ( ! ( fli_context = fl_calloc( 1, sizeof *fli_context ) ) )
869 {
870 M_err( "fli_init_context", "Running out of memory" );
871 exit( 1 );
872 }
873
874 fli_context->io_rec = NULL;
875 fli_context->idle_rec = NULL;
876 fli_context->atclose = NULL;
877 fli_context->signal_rec = NULL;
878 fli_context->idle_delta = FLI_TIMER_RES;
879 fli_context->hscb = FL_HOR_THIN_SCROLLBAR;
880 fli_context->vscb = FL_VERT_THIN_SCROLLBAR;
881 fli_context->navigate_mask = ShiftMask; /* to navigate input field */
882 fli_context->xim = NULL;
883 fli_context->xic = NULL;
884 }
885
886
887 /***************************************
888 ***************************************/
889
890 void
fli_set_input_navigate(unsigned int mask)891 fli_set_input_navigate( unsigned int mask )
892 {
893 fli_init_context( );
894
895 if ( mask == ShiftMask || mask == Mod1Mask || mask == ControlMask )
896 fli_context->navigate_mask = mask;
897 }
898
899
900 /***************************************
901 ***************************************/
902
903 Display *
fl_initialize(int * na,char * arg[],const char * appclass,FL_CMD_OPT * appopt,int nappopt)904 fl_initialize( int * na,
905 char * arg[ ],
906 const char * appclass,
907 FL_CMD_OPT * appopt,
908 int nappopt )
909 {
910 char disp_name[ 256 ],
911 disp_cls[ 256 ],
912 buf[ 256 ];
913 XrmValue xval;
914 char *type;
915 float xdpi,
916 ydpi;
917
918 if ( fl_display )
919 {
920 M_warn( "fl_initialize", "XForms: already initialized" );
921 return fl_display;
922 }
923
924 /* Be paranoid */
925
926 if ( ! na || ! *na )
927 {
928 M_err( "fl_initialize",
929 "XForms: argc == 0 or argv == NULL detected\n" );
930 exit( 1 );
931 }
932
933 fli_internal_init( );
934
935 XrmInitialize( );
936
937 /* Save a copy of the command line for later WM hints */
938
939 fli_argc = *na;
940 dup_argv( arg, *na );
941
942 /* Get appname and class, but without any leading paths */
943
944 fl_ori_app_name = fl_app_name = get_command_name( arg[ 0 ] );
945 fl_app_class = fl_strdup( ( appclass && *appclass ) ?
946 appclass : fl_app_name );
947
948 /* Make class name upper case if non supplied */
949
950 if ( ! appclass || ! *appclass )
951 {
952 fl_app_class[ 0 ] = toupper( fl_app_class[ 0 ] );
953 if ( fl_app_class[ 0 ] == 'X' )
954 fl_app_class[ 1 ] = toupper( fl_app_class[ 1 ] );
955 }
956
957 /* Do form internal resouces first */
958
959 XrmParseCommand( &cmddb, copt, Ncopt, fl_app_name, na, arg );
960
961 /* if there are still more left and appopt is not zero */
962
963 if ( appopt && na && *na )
964 XrmParseCommand( &cmddb, appopt, nappopt,
965 ( char * ) fl_ori_app_name, na, arg );
966
967 /* Check version request */
968
969 fli_snprintf( disp_name, sizeof disp_name, "%s.fl_version", fl_app_name );
970 fli_snprintf( disp_cls, sizeof disp_cls, "%s.flversion", fl_app_name );
971
972 if ( XrmGetResource( cmddb, disp_name, disp_cls, &type, &xval ) )
973 fli_print_version( 0 );
974
975 /* Get the display name first before doing anything */
976
977 fli_snprintf( disp_name, sizeof disp_name, "%s.display", fl_ori_app_name );
978 fli_snprintf( disp_cls , sizeof disp_cls , "%s.Display", fl_app_class );
979
980 *buf = '\0';
981
982 if ( XrmGetResource( cmddb, disp_name, disp_cls, &type, &xval ) )
983 {
984 strncpy( buf, xval.addr, sizeof buf );
985 buf[ sizeof buf - 1 ] = '\0';
986 }
987
988 /* Open display and quit on failure */
989
990 if ( ! ( fl_display = XOpenDisplay( buf ) ) )
991 {
992 /* if no display is set, there is no guarantee that buf
993 is long enough to contain the DISPLAY setting */
994
995 M_err( "fl_initialize", "%s: Can't open display %s", fli_argv[ 0 ],
996 XDisplayName( buf[ 0 ] ? buf : 0 ) );
997 return 0;
998 }
999
1000 flx->display = fl_display;
1001 flx->screen = fl_screen;
1002
1003 /* Get debug level settings since all error reporting will be controled
1004 by it */
1005
1006 fli_snprintf( disp_name, sizeof disp_name, "%s.fldebug", fl_app_name );
1007 fli_snprintf( disp_cls , sizeof disp_cls , "%s.flDebug", fl_app_class );
1008 if ( XrmGetResource( cmddb, disp_name, disp_cls, &type, &xval ) )
1009 fli_set_debug_level( atoi( xval.addr ) );
1010
1011 /* print help */
1012
1013 fli_snprintf( disp_name, sizeof disp_name, "%s.flhelp", fl_app_name );
1014 fli_snprintf( disp_cls , sizeof disp_cls , "%s.flhelp", fl_app_class );
1015
1016 if ( XrmGetResource( cmddb, disp_name, disp_cls, &type, &xval ) )
1017 {
1018 size_t i = 0;
1019
1020 while ( i < Ncopt )
1021 {
1022 if ( i == 0 )
1023 fprintf( stderr, "%s: ", fli_argv[ 0 ] );
1024 else
1025 fprintf( stderr, "%*s ",
1026 ( int ) strlen( fli_argv[ 0 ] ), "" );
1027
1028 fprintf( stderr, " %s", copt[ i ].option );
1029
1030 if ( copt[ i ].argKind == XrmoptionSepArg )
1031 fprintf( stderr, " \t[arg]" );
1032 fprintf( stderr, "\n" );
1033 i++;
1034 }
1035
1036 exit(1);
1037 }
1038
1039 /* Check if -name is present */
1040
1041 fli_snprintf( disp_name, sizeof disp_name, "%s.name", fl_app_name );
1042 fli_snprintf( disp_cls, sizeof disp_cls , "%s.Name", fl_app_class );
1043
1044 M_warn( "fl_initialize", "Trying display %s", disp_name );
1045
1046 if ( XrmGetResource( cmddb, disp_name, disp_cls, &type, &xval ) )
1047 {
1048 fl_app_name = fl_strdup( xval.addr );
1049 M_warn( "fl_initialize", "Changed AppName from %s to %s",
1050 fl_ori_app_name, fl_app_name );
1051 }
1052
1053 /* Merge other resource database */
1054
1055 init_resource_database( fl_app_class );
1056
1057 /* Override any options in the database with the command line opt */
1058
1059 XrmMergeDatabases( cmddb, &fldatabase );
1060
1061 /* Load FL resources */
1062
1063 fli_init_resources( );
1064
1065 fli_cntl.vclass = fli_vclass_val( fli_cntl.vname );
1066 fli_cntl.coordUnit = fli_get_vn_value( vn_coordunit, OpCoordUnit );
1067 if ( fli_cntl.coordUnit == -1 )
1068 fli_cntl.coordUnit = FL_COORD_PIXEL;
1069
1070 #if FL_DEBUG >= ML_WARN
1071 if ( fli_cntl.debug )
1072 {
1073 fprintf( stderr, "Options Set\n" );
1074 DumpD( debug );
1075 fprintf( stderr, "\tVisual:%s (%d)\n",
1076 fli_cntl.vclass >= 0 ?
1077 fli_vclass_name( fli_cntl.vclass ) : "To be set",
1078 fli_cntl.vclass );
1079 DumpD( depth );
1080 DumpD( privateColormap );
1081 DumpD( sharedColormap );
1082 DumpD( standardColormap );
1083 DumpD( doubleBuffer );
1084 DumpD( ulPropWidth );
1085 DumpD( ulThickness );
1086 DumpD( scrollbarType );
1087 DumpD( backingStore );
1088 fprintf( stderr, "\t%s:%s\n", "coordUnit",
1089 fli_get_vn_name( vn_coordunit, fli_cntl.coordUnit ) );
1090 fprintf( stderr, "\t%s: 0x%lx\n", "VisualId", fli_requested_vid );
1091
1092 #ifdef DO_GAMMA_CORRECTION
1093 DumpF( rgamma );
1094 DumpF( ggamma );
1095 DumpF( bgamma );
1096 #endif
1097 }
1098 #endif
1099
1100 #ifdef DO_GAMMA_CORRECTION
1101 fl_set_gamma( fli_cntl.rgamma, fli_cntl.ggamma, fli_cntl.bgamma );
1102 #endif
1103
1104 fli_set_ul_property( fli_cntl.ulPropWidth, fli_cntl.ulThickness );
1105
1106 fli_cntl.vclass = fli_vclass_val( fli_cntl.vname );
1107
1108 /* Get the current keyboard state */
1109
1110 {
1111 XKeyboardState xks;
1112
1113 XGetKeyboardControl( fl_display, &xks );
1114 fli_keybdcontrol.auto_repeat_mode = xks.global_auto_repeat;
1115 fli_keybdmask = KBAutoRepeatMode;
1116 }
1117
1118 /* Other initializations */
1119
1120 fl_screen = flx->screen = DefaultScreen( fl_display );
1121 fl_root = RootWindow( fl_display, fl_screen );
1122 fl_vroot = fli_GetVRoot( fl_display, fl_screen );
1123 fli_wmstuff.pos_request = USPosition;
1124
1125 if ( fl_root != fl_vroot )
1126 {
1127 M_warn( "fl_initialize", "fl_root = %lu fl_vroot = %lu",
1128 fl_root, fl_vroot );
1129
1130 /* tvtwm requires this to position a window relative to the current
1131 desktop */
1132
1133 fli_wmstuff.pos_request = PPosition;
1134 }
1135
1136 fl_scrh = DisplayHeight( fl_display, fl_screen );
1137 fl_scrw = DisplayWidth( fl_display, fl_screen );
1138
1139 xdpi = fl_scrw * 25.4 / DisplayWidthMM( fl_display, fl_screen );
1140 ydpi = fl_scrh * 25.4 / DisplayHeightMM( fl_display, fl_screen );
1141
1142 if ( xdpi / ydpi > 1.05 || ydpi / xdpi < 0.95 )
1143 M_warn( "fl_initialize", "NonSquarePixel %.1f %.1f", xdpi, ydpi );
1144
1145 fl_dpi = ( xdpi + ydpi ) / 2;
1146 fl_dpi = FL_nint( fl_dpi * 10.0 + 0.5 ) * 0.1;
1147
1148 M_info( "fl_initialize", "screen DPI = %f", fl_dpi );
1149
1150 fl_vmode = fli_initialize_program_visual( );
1151 fli_init_colormap( fl_vmode );
1152 fli_init_font( );
1153 fli_init_context( );
1154
1155 #ifdef XlibSpecificationRelease
1156 if ( XSupportsLocale( ) )
1157 {
1158 XSetLocaleModifiers( "" );
1159
1160 /* Use the same input method throughout xforms */
1161
1162 fli_context->xim = XOpenIM( fl_display, NULL, NULL, NULL );
1163
1164 /* Also use the same input context */
1165
1166 if ( fli_context->xim )
1167 {
1168 int style = XIMPreeditNothing | XIMStatusNothing;
1169
1170 fli_context->xic = XCreateIC( fli_context->xim,
1171 XNInputStyle, style,
1172 ( char * ) NULL );
1173
1174 /* Clean-up on failure */
1175
1176 if ( ! fli_context->xic )
1177 {
1178 M_err( "fl_initialize", "Could not create an input context" );
1179 XCloseIM( fli_context->xim );
1180 }
1181 }
1182 else
1183 M_err( "fl_initialize", "Could not create an input method" );
1184 }
1185 #endif
1186
1187 fli_default_xswa( );
1188 fli_init_stipples( );
1189
1190 /* If using non-default visual or private colormap, need a window with
1191 correct visual/colormap and depth */
1192
1193 fl_state[ fl_vmode ].trailblazer = fl_root;
1194
1195 if ( fli_visual( fl_vmode ) != DefaultVisual( fl_display, fl_screen )
1196 || fl_state[ fl_vmode ].pcm )
1197 {
1198 fl_state[ fl_vmode ].trailblazer =
1199 fli_create_window( fl_root, fli_colormap( fl_vmode ),
1200 "trailblazer" );
1201 }
1202
1203 if ( strcmp( OpSCBT, "plain" ) == 0 )
1204 {
1205 fli_context->hscb = FL_HOR_PLAIN_SCROLLBAR;
1206 fli_context->vscb = FL_VERT_PLAIN_SCROLLBAR;
1207 }
1208 else if ( strcmp( OpSCBT, "normal" ) == 0 )
1209 {
1210 fli_context->hscb = FL_HOR_SCROLLBAR;
1211 fli_context->vscb = FL_VERT_SCROLLBAR;
1212 }
1213 else if ( ! strcmp( OpSCBT, "thin" ) )
1214 {
1215 fli_context->hscb = FL_HOR_THIN_SCROLLBAR;
1216 fli_context->vscb = FL_VERT_THIN_SCROLLBAR;
1217 }
1218 else if ( ! strcmp( OpSCBT, "nice" ) )
1219 {
1220 fli_context->hscb = FL_HOR_NICE_SCROLLBAR;
1221 fli_context->vscb = FL_VERT_NICE_SCROLLBAR;
1222 }
1223
1224 fli_context->max_request_size = XMaxRequestSize( fl_display );
1225
1226 if ( fli_context->max_request_size < 4096 )
1227 {
1228 M_err( "fl_initialize", "Something is wrong with max_request_size: %ld",
1229 fli_context->max_request_size );
1230 fli_context->max_request_size = 4096;
1231 }
1232
1233
1234 #if XlibSpecificationRelease >= 6
1235 fli_context->ext_request_size = XExtendedMaxRequestSize( fl_display );
1236 #else
1237 fli_context->ext_request_size = 0;
1238 #endif
1239
1240 if ( ! fli_context->ext_request_size )
1241 fli_context->ext_request_size = fli_context->max_request_size;
1242
1243 fli_context->max_request_size -= 8;
1244 fli_context->ext_request_size -= 8;
1245 fli_context->tooltip_time = 600;
1246
1247 fl_add_io_callback( ConnectionNumber( fl_display ), FL_READ, NULL, NULL );
1248
1249 /* Has to be here, otherwise fl_add_symbol won't be able to replace the
1250 built-in */
1251
1252 fli_init_symbols( );
1253
1254 /* Hang the database on the display so application can get it */
1255
1256 XrmSetDatabase( fl_display, fldatabase );
1257
1258 /* Initialize popup system */
1259
1260 fli_popup_init( );
1261
1262 return fl_display;
1263 }
1264
1265
1266 /***************************************
1267 * Cleanup everything. At the moment, only need to restore the keyboard
1268 * settings and deallocate memory used for the object and event queue etc.
1269 ***************************************/
1270
1271 void
fl_finish(void)1272 fl_finish( void )
1273 {
1274 /* Make sure the connection is alive */
1275
1276 if ( ! flx->display )
1277 return;
1278
1279 XChangeKeyboardControl( flx->display, fli_keybdmask,
1280 &fli_keybdcontrol );
1281
1282 fli_remove_all_signal_callbacks( );
1283 fli_remove_all_timeouts( );
1284
1285 /* Get rid of all forms, first hide all of them */
1286
1287 while ( fli_int.formnumb > 0 )
1288 fl_hide_form( fli_int.forms[ 0 ] );
1289
1290 /* Now also delete them (to deallocate memory) - problem is that the
1291 tooltip form may only be deleted as the very last one since the objects
1292 that have a tooltip (and that get deleted in the process of deleting
1293 the form they belong to) still try to access the tooltip form */
1294
1295 while ( fli_int.hidden_formnumb > 0 )
1296 {
1297 if ( fli_int.hidden_formnumb > 1
1298 && fli_is_tooltip_form( fli_int.forms[ 0 ] ) )
1299 fl_free_form( fli_int.forms[ 1 ] );
1300 else
1301 fl_free_form( fli_int.forms[ 0 ] );
1302 }
1303
1304 /* Delete the object and event queue */
1305
1306 fli_obj_queue_delete( );
1307 fli_event_queue_delete( );
1308
1309 /* Free memory allocated in xtext.c */
1310
1311 fli_free_xtext_workmem( );
1312
1313 /* Release memory used for symbols */
1314
1315 fli_release_symbols( );
1316
1317 /* Release memory allocated in goodies */
1318
1319 fli_goodies_cleanup( );
1320
1321 /* Release memory allocated for file selectors */
1322
1323 fli_free_fselectors( );
1324
1325 /* Release memory used by the popup system */
1326
1327 fli_popup_finish( );
1328
1329 /* Release memory used for the copy of the command line arguments */
1330
1331 fli_free_cmdline_args( );
1332
1333 /* Release memory used for cursors */
1334
1335 fli_free_cursors( );
1336
1337 /* Free memory used for colormaps */
1338
1339 fli_free_colormap( fl_vmode );
1340
1341 /* Get rid of memory for input methods */
1342
1343 #ifdef XlibSpecificationRelease
1344 if ( fli_context && XSupportsLocale( ) && fli_context->xim )
1345 {
1346 if ( fli_context->xic )
1347 XDestroyIC( fli_context->xic );
1348 XCloseIM( fli_context->xim );
1349 }
1350 #endif
1351
1352 if ( fli_context )
1353 while ( fli_context->io_rec )
1354 fl_remove_io_callback( fli_context->io_rec->source,
1355 fli_context->io_rec->mask,
1356 fli_context->io_rec->callback );
1357
1358 fli_safe_free( fli_context );
1359
1360 /* Close the display */
1361
1362 XCloseDisplay( flx->display );
1363 flx->display = fl_display = None;
1364 }
1365
1366
1367 /***************************************
1368 * Find out about virtual root. Taken from XFaq
1369 ***************************************/
1370
1371 #include <X11/Xatom.h>
1372
1373 static int
xerror_handler(Display * d FL_UNUSED_ARG,XErrorEvent * xev)1374 xerror_handler( Display * d FL_UNUSED_ARG,
1375 XErrorEvent * xev )
1376 {
1377 return xev->error_code;
1378 }
1379
1380
1381 static Window
fli_GetVRoot(Display * dpy,int scr)1382 fli_GetVRoot( Display * dpy,
1383 int scr )
1384 {
1385 Window rootReturn;
1386 Window parentReturn;
1387 Window *children;
1388 unsigned int numChildren;
1389 Window root = RootWindow( dpy, scr );
1390 Atom __SWM_VROOT = None;
1391 unsigned int i;
1392 int ( * oldhandler )( Display *, XErrorEvent * );
1393
1394 __SWM_VROOT = XInternAtom( dpy, "__SWM_VROOT", False );
1395 XQueryTree( dpy, root, &rootReturn, &parentReturn, &children,
1396 &numChildren );
1397
1398 /* For some reasons XQueryTree sometimes seems to return an invalid window
1399 in the list of children (perhaps the window vanishes between the call
1400 of XQueryTree() and the subsequent call of XGetWindowProperty()?). To
1401 avoid a program using XForms aborting with a strange X error message on
1402 start-up, we catch these errors with a temporary error handler (which
1403 gets reset before leaving the function). */
1404
1405 oldhandler = XSetErrorHandler( xerror_handler );
1406
1407 for ( i = 0; i < numChildren; i++ )
1408 {
1409 Atom actual_type;
1410 int actual_format;
1411 unsigned long nitems, bytesafter;
1412 Window *newRoot = NULL;
1413
1414 /* Kludge here: the ( void * ) bit in
1415 ( unsigned char ** ) ( void * ) &newRoot
1416 is there to avoid a spurious GCC warning JTT */
1417
1418 children[ i ] = 0;
1419 if ( XGetWindowProperty( dpy, children[ i ], __SWM_VROOT, 0, 1,
1420 False, XA_WINDOW, &actual_type,
1421 &actual_format, &nitems, &bytesafter,
1422 ( unsigned char ** ) ( void * ) &newRoot )
1423 == Success
1424 && newRoot )
1425 {
1426 root = *newRoot;
1427 break;
1428 }
1429 }
1430
1431 XSetErrorHandler( oldhandler );
1432 XFree( ( char * ) children );
1433 return root;
1434 }
1435
1436
1437 /***************************************
1438 * For Application programs
1439 ***************************************/
1440
1441 static void
fli_get_app_resource(FL_resource * appresource,int n)1442 fli_get_app_resource( FL_resource * appresource,
1443 int n )
1444 {
1445 FL_resource *flr = appresource,
1446 *flrs = flr + n;
1447
1448 for ( ; flr < flrs; flr++ )
1449 if ( flr->type == FL_STRING && flr->nbytes == 0 )
1450 M_err( "fl_get_app_resources", "%s: buflen == 0", flr->res_name );
1451 else
1452 fl_get_resource( flr->res_name, flr->res_class,
1453 flr->type, flr->defval, flr->var, flr->nbytes );
1454 }
1455
1456
1457 /***************************************
1458 ***************************************/
1459
1460 void
fl_get_app_resources(FL_resource * appresource,int n)1461 fl_get_app_resources( FL_resource * appresource,
1462 int n )
1463 {
1464 char *tmp = fl_app_name;
1465
1466 fl_app_name = fl_ori_app_name;
1467 fli_get_app_resource( appresource, n );
1468
1469 if ( fl_app_name != tmp )
1470 {
1471 fl_app_name = tmp;
1472 fli_get_app_resource( appresource, n );
1473 }
1474 }
1475
1476
1477 /***************************************
1478 ***************************************/
1479
1480 void
fl_flip_yorigin(void)1481 fl_flip_yorigin( void )
1482 {
1483 if ( ! fl_display )
1484 fli_inverted_y = 1;
1485 else
1486 M_err( "fl_flip_yorigin", "Only supported before fl_initialize" );
1487 }
1488
1489
1490 /***************************************
1491 ***************************************/
1492
1493 void
fli_set_app_name(const char * n,const char * c)1494 fli_set_app_name( const char * n,
1495 const char * c )
1496 {
1497 if ( n )
1498 fl_app_name = fl_strdup( n );
1499 if ( c )
1500 fl_app_class = fl_strdup( c );
1501 }
1502
1503
1504 /*
1505 * Local variables:
1506 * tab-width: 4
1507 * indent-tabs-mode: nil
1508 * End:
1509 */
1510