1 /*----------------------------------------------------------------------------
2 //
3 //   Class/module:     xmubCustUtil
4 //
5 //   Project:          xmub
6 //   System:           <>
7 //    Subsystem:       <>
8 //    Function block:  <>
9 //
10 //   Creation date:    05.11.1994
11 
12 // = LIBRARY
13 //    xmub
14 //
15 // = FILENAME
16 //    xmubCustUtil.h
17 //
18 // = AUTHORS
19 //    Ulrika Bornetun <bre@ubszh.ch.net>
20 //
21 // = COPYRIGHT
22 //    (C) Copyright Union Bank of Switzerland 1994
23 //        All rights reserved
24 
25 //  Permission to use, copy, modify, and distribute this software and its
26 //  documentation for any purpose and without fee is hereby granted,
27 //  provided that the above copyright notice appear in all copies.
28 //  Union Bank of Switzerland makes no representations about the usability
29 //  of this software for any purpose. It is provided "as is" without express
30 //  or implied warranty.
31 //
32 //   Modifications:
33 //
34 //   Version / When / Who
35 //   What
36 //   --------------------------------------------
37 //   %StartLog%
38 //   %EndLog%
39 //
40 //---------------------------------------------------------------------------*/
41 
42 /* SCCS module identifier. */
43 /* SCCSID = @(#) Module: xmubCustUtil.h, Version: 1.1, Date: 95/02/18 15:10:54 */
44 
45 #ifndef _INC_XMUB_CUST_UTIL_H
46 #  define _INC_XMUB_CUST_UTIL_H
47 
48 
49 /*----------------------------------------------------------------------------
50 //  Include files
51 ----------------------------------------------------------------------------*/
52 
53 #include <X11/Xlib.h>
54 #include <X11/Intrinsic.h>
55 
56 /*----------------------------------------------------------------------------
57 //  Macro definitions
58 ----------------------------------------------------------------------------*/
59 
60 #define XmUbNsubstringResources   "substringResources"
61 #define XmUbNsubstringDelimiters  "substringDelimiters"
62 
63 #define XmUbCSubstringResources   "SubstringResources"
64 #define XmUbCSubstringDelimiters  "SubstringDelimiters"
65 
66 
67 #define XMUB_RES_SET_CHANGED   1
68 
69 /* Names and classes used in the default definitions. */
70 
71 #define FONTMAP_RESOURCE_NAME  "fmap"
72 #define FONTMAP_CLASS_NAME     "Fmap"
73 #define PALETTE_RESOURCE_NAME  "palette"
74 #define PALETTE_CLASS_NAME     "Palette"
75 
76 /*----------------------------------------------------------------------------
77 //  Type declarations
78 ----------------------------------------------------------------------------*/
79 
80 typedef struct
81 {
82   char*  res_name;
83   char*  res_class;
84 } xmubAppResDesc, *xmubAppResRef;
85 
86 
87 typedef struct _xmubResourceMappingInfo  *xmubResourceMappingInfoRef;
88 
89 /*
90   A pointer to a  struct of the type xmubResSetChangeCallbackStruct is sent
91   as call_data to the resource set change callback. Its fields are:
92 
93   reason           XMUB_RES_SET_CHANGED
94   res_name         The name of the resource that was changed.
95                    May be NULL.
96   res_class        The class of the resource that was changed.
97                    May be NULL.
98   new_value        The new value of the resource.
99                    May be NULL.
100   mapping_changed  True if the changed lead to a real resource replacement,
101                    False otherwise.
102 
103   Note that the strings point to internal parameters and may not be changed
104   or deallocated.
105 */
106 
107 typedef struct
108 {
109   int      reason;
110 
111   char*    res_name;
112   char*    res_class;
113   char*    new_value;
114 
115   Boolean  mapping_changed;
116 
117 } xmubResSetChangeCallbackStruct;
118 
119 
120 typedef void (*xmubResSetChangeCallback)
121   ( xmubResourceMappingInfoRef, XtPointer, xmubResSetChangeCallbackStruct* );
122 
123 typedef struct
124 {
125   xmubResSetChangeCallback  callback;
126   XtPointer                 client_data;
127 
128 } xmubResSetChangeCallbackRec, *xmubResSetChangeCallbackList;
129 
130 
131 typedef struct _xmubResourceMappingInfo
132 {
133   XrmDatabase  orig_db;
134   XrmDatabase  mapping_db;
135   XrmDatabase  translation_db;
136   XrmDatabase  merge_db;
137 
138   char*        app_name;
139   char*        app_class;
140 
141   Display*     display;
142 
143   /* Internal information. */
144   XrmQuark     string_quark;
145 
146   /* Callbacks. */
147   xmubResSetChangeCallbackList  set_change_callbacks;
148   Cardinal                      num_set_change_callbacks;
149 
150   /* Temporary fields. */
151   Boolean      specific;
152 
153   XrmQuark     *selection;
154   int          num_selections;
155   Boolean      inclusive_selection;
156 
157   Boolean      replace_substrings;
158   char*        substring_delimiters;
159   char*        value;
160   Boolean      replaced;
161   Boolean      selected;
162 
163   Boolean      save_in_orig;
164 
165 } xmubResourceMappingInfo;
166 
167 /*----------------------------------------------------------------------------
168 //  Global definitions
169 ----------------------------------------------------------------------------*/
170 
171 /*
172   The xmub_res_options array can be used in XtOpenDisplay to assign the
173   default options to the default resources.
174   The mappings that are done are "-palette" to "*palette" and
175   "-fmap" to "*fmap".
176 */
177 
178 extern XrmOptionDescRec  xmub_options[];
179 extern Cardinal          xmub_num_options;
180 
181 /*
182   The xmub_resource_sets array is a default for the resources that define
183   resource sets. The supported resource sets are
184   "palette", "Palette" and "fmap", "Fmap".
185   This array may be used in the function xmubResAddMapFile.
186 */
187 
188 extern xmubAppResDesc  xmub_resource_sets[];
189 extern Cardinal        xmub_num_resource_sets;
190 
191 
192 /*----------------------------------------------------------------------------
193 //  Function prototypes
194 ----------------------------------------------------------------------------*/
195 
196 #ifdef __cplusplus
197 extern "C" {
198 #endif
199 
200 /*  For man-page generation: class xmubCustUtil  */
201 /*
202 // = TITLE
203 //    A library for resource mapping.
204 //
205 // = DESCRIPTION
206 //    This module contains functions for manipulating the mapping of
207 //    resources.
208 //
209 // = SEE ALSO
210 //	  xmubCustUi
211 */
212 
213 /*  For man-page generation: public: */
214 /*
215 // = INITIALIZATION
216 */
217 
218 Widget
219 xmubAppInitialize( XtAppContext                *app_context_return,
220                    String                      application_class,
221                    XrmOptionDescList           options,
222                    Cardinal                    num_options,
223                    Cardinal                    *argc_in_out,
224                    String                      *argv_in_out,
225                    String                      *fallback_resources,
226                    ArgList                     args,
227                    Cardinal                    num_args,
228                    xmubAppResDesc              *resource_sets,
229                    Cardinal                    num_resource_sets,
230                    xmubResourceMappingInfoRef  *ref_return );
231 /*
232 // Performs the function of XtAppInitialize, plus initalizes
233 // the resource mapping facility, reads the default mapping
234 // file and performs the replacements in it.
235 //
236 // The resource_sets parameter defines the resource sets to be used.
237 // See function xmubResAddMapFile for an explanation.
238 // An info record is allocated and the pointer to it is returned in
239 // ref_return. It must be freed by the caller with the function
240 // xmubResFreeInfo.
241 //
242 // The return value is the created shell widget.
243 //
244 // The resources argc and argv are added to the resources for the created
245 // shell.
246 */
247 
248 void
249 xmubInitResourceMapping( Display*                    display,
250                          xmubAppResDesc              resource_sets[],
251                          Cardinal                    num_resource_sets,
252                          xmubResourceMappingInfoRef  *res_info );
253 /*
254 // Initializes the resource mapping facility, reads the default mapping
255 // file and performs the replacements in it.
256 // The resource_sets parameter defines the resource sets to be used.
257 // See function xmubResAddMapFile for an explanation.
258 //
259 // If res_info is NULL, an info record is returned. It must
260 // be freed by the caller with the function xmubResFreeInfo.
261 */
262 
263 xmubResourceMappingInfoRef
264 xmubResInitialize( Display*  display );
265 /*
266 // Sets up an info record that will be used in further calls and returns
267 // a reference to it. The database entries are set to NULL.
268 //
269 // The info record is allocated in the function and must be freed by
270 // the caller. Note that the info record should be freed with the function
271 // xmubResFreeInfo, and not until all calls to this module have been done.
272 */
273 
274 char*
275 xmubResGetMappingFileName( Display*  display );
276 /*
277 // Returns the name of the file that contains the mapping database.
278 // The returned string must be deallocated with XtFree when no longer
279 // needed. If no file is found, NULL is returned.
280 //
281 // If the environment variable XRESOURCE_MAP_FILE is defined and points
282 // to a readable file, its translation is used as the file name.
283 // Otherwise, a map file with the name 'app_class'.map is looked for
284 // first in XUSERFILESEARCHPATH with the type set to app-defaults,
285 // then in the path
286 //
287 //   $XAPPLRESDIR/%L/%N/%S:$XAPPLRESDIR/%l/%N%S:$XAPPLRESDIR/%N%S:
288 //   $HOME/%N%S:.
289 //
290 // if XAPPLRESDIR is defined, and in
291 //
292 //   $HOME/%L/%N%S:$HOME/%l%N%S:$HOME/%N%S:.
293 //
294 // if it is not defined.
295 //
296 // Lastly, the system default path is searched.
297 // If no file with the name 'app_class'.map is found, the same search is
298 // performed for the file "xresource.map".
299 // If $HOME is not defined, the parts including it are left out.
300 //
301 // For VMS, there is a special version of this function. It uses the
302 // logical name XRESOURCE_MAP_FILE as the file name if defined.
303 // Otherwise, it searches first for the file 'app_class'.map and if
304 // not found, for the file "xresource.map" in the path
305 //
306 //   DECW$USER_DEFAULTS, DECW$SYSTEM_DEFAULTS, []
307 */
308 
309 /*
310 // = ADDING MAPPINGS
311 */
312 Boolean
313 xmubResAddMapFile( xmubResourceMappingInfoRef  info,
314                    char*                       file_name,
315                    Boolean                     add_defaults,
316                    xmubAppResDesc              resource_sets[],
317                    Cardinal                    num_resource_sets );
318 /*
319 // Adds mappings from the resource file indicated with file_name to
320 // the mapping database in info.
321 // If file_name is NULL, the default file as returned by
322 // xmubResGetMappingFileName is used.
323 //
324 // resource_sets is an array of records that define the resources
325 // that are used to store valid set names. The records define the
326 // name and class of the respective resources. If NULL is defined,
327 // a default array with the following definition is taken:
328 //   { { "palette", "Palette" }, { "fmap", "Fmap" } }
329 //
330 // If resource sets are defined, the function will extract the values
331 // for these resource sets and use these as the selection criteria
332 // when reading from the file. If no resource sets are defined, only
333 // mappings defined with '*', i.e. without a resource set name, will
334 // be used from the mapping file. Note that these general resources will
335 // only be added if add_defaults is True, and will be overridden by the
336 // selected sets.
337 //
338 // add_defaults should be True when initializing the resource mapping,
339 // and should only be set False when an update is made.
340 //
341 // False is returned if the specified file was not readable, or if there
342 // were no resources selected in the file.
343 // True is returned if everything was OK.
344 //
345 // The file database is merged into the mapping database.
346 */
347 
348 Boolean
349 xmubResAddMappings( xmubResourceMappingInfoRef  info,
350                     XrmDatabase                 db,
351                     Boolean                     add_defaults,
352                     xmubAppResDesc              resource_sets[],
353                     Cardinal                    num_resource_sets );
354 /*
355 // Adds mappings from the database to the translation database.
356 //
357 // resource_sets is an array of records that define the resources
358 // that are used to store valid set names. The records define the
359 // name and class of the respective resources. If NULL is defined,
360 // a default array with the following definition is taken:
361 //   { { "palette", "Palette" }, { "fmap", "Fmap" } }
362 //
363 // If resource sets are defined, the function will extract the values
364 // for these resource sets and use these as the selection criteria
365 // when reading from the database. If no resource sets are defined, only
366 // mappings defined with '*', i.e. without a resource set name, will
367 // be used from the database. Note that these general resources will
368 // only be added if add_defaults is True, and will be overridden by the
369 // selected sets.
370 //
371 // add_defaults should be True when initializing the resource mapping,
372 // and should only be set False when an update is made.
373 //
374 // False is returned if no resources were selected.
375 // True is returned if everything was OK.
376 //
377 // The mapping database is not modified.
378 */
379 
380 void
381 xmubResAddStringMapping( xmubResourceMappingInfoRef  info,
382                          char*                       keyword,
383                          char*                       translation );
384 /*
385 // Adds the translation *'keyword': 'translation' to both the mapping
386 // and the translation databases.
387 */
388 
389 /*
390 // = REPLACING KEYWORDS
391 */
392 void
393 xmubResReplace( xmubResourceMappingInfoRef  info,
394                 XrmDatabase                 start_db );
395 /*
396 // Takes start_db and replaces keywords defined info -\> translation_db with
397 // their respective values. The result is placed in info -\> merge_db.
398 // Note that only the modified resources are placed in merge_db.
399 // If start_db is NULL, the display database is taken.
400 //
401 // Two passes are run. The first pass replaces only whole definitions,
402 // and no substrings. If the application resource substringResources is
403 // defined, a second pass is run. This pass takes the resources defined
404 // in substringResources and runs a substring replacement for them.
405 // The resource substringDelimiters is used for determining the character
406 // set used to delimit the substrings. The default for this resource is
407 // " ".
408 //
409 // Unless there are very special requirements, this function should be
410 // used instead of xmubResReplaceKeywords, since it makes it possible
411 // to define the substring set from the outside. This function calls
412 // xmubResReplaceKeywords internally.
413 */
414 
415 void
416 xmubResReplaceKeywords( xmubResourceMappingInfoRef  info,
417                         XrmDatabase                 start_db,
418                         Boolean                     replace_substrings,
419                         char*                       substring_delimiters,
420                         char**                      resource_selection,
421                         Cardinal                    num_resource_selection,
422                         Boolean                     inclusive_selection );
423 /*
424 // Takes start_db and replaces keywords defined info -\> translation_db with
425 // their respective values. The result is placed in info -\> merge_db.
426 // Note that only the modified resources are placed in merge_db.
427 // If start_db is NULL, the display database is taken.
428 //
429 // If replace_substrings is True, parts of the resource definitions may be
430 // replaced. substring_delimiters may be used to define a set of characters
431 // that are recognized as valid delimiters. For example, if
432 // replace_substrings is True and substring_delimiters is "(),", and
433 // the keyword UserFont has been defined, the occurrence in resource value
434 // "Ergo15,UserFont,Rom14" would be replaced, but not the one in the value
435 // "Select a new UserFont".
436 //
437 // The parameter resource_selection can be used to define an array of
438 // strings with resource names that should be replaced or ignored.
439 //
440 // If inclusive_selection is True, the resources in the set are the ones
441 // that are included, and all others are ignored. If inclusive_selection
442 // is False, all resources EXCEPT the ones in resource_selection are
443 // processed. resource_selection should contain resource names or classes
444 // as entries, e.g. "background","layout","labelString". The size of the
445 // array is defined in num_resource_selection.
446 //
447 // The string definitions that are replaced are stored in the internal
448 // database info -\> orig_db. This is only done if the start_db is not
449 // already orig_db.
450 //
451 // Note:
452 //
453 // Since replacing keywords in substrings is very inefficient, slow and
454 // rarely needed, it should be used with care.
455 // The most efficient way to code the program is to perform the
456 // general replacements first, then call the function again for the
457 // substring replacement, but this time with a resource_selection that
458 // matches the resources that will be processed.
459 //
460 // Example:
461 //
462 // First call to xmubResReplaceKeywords specifies no resource_selection
463 // and sets replace_substrings False.
464 // Second call to xmubResReplaceKeywords sets replace_substrings True,
465 // and specifies the resource set "fontList","layout".
466 //
467 // Note 2:
468 //
469 // The function xmubResReplace offers a simpler interface and more
470 // customization possibilities for the user and should be used
471 // instead of this function whenever possible.
472 */
473 
474 
475 /*
476 // = MERGING RESOURCES
477 */
478 void
479 xmubResMergeMappedResources( xmubResourceMappingInfoRef  info,
480                              XrmDatabase                 target_db );
481 /*
482 // Merges the resources in info -\> merge_db into target_db.
483 // If target_db is NULL, the display database is used.
484 */
485 
486 /*
487 // = UPDATING RESOURCES
488 */
489 Boolean
490 xmubResUpdateResourceSet( xmubResourceMappingInfoRef  info,
491                           char*                       res_name,
492                           char*                       res_class,
493                           char*                       new_value,
494                           xmubResSetChangeCallback    apply_callback,
495                           XtPointer                   client_data );
496 /*
497 // Set the resource *'res_name' in the display database to new_value
498 // and updates the translation database using the default functions.
499 // The mapping database is used for selecting the values.
500 // If more advanced replacements than what is done in xmubResReplace
501 // must be made, this function is not sufficient.
502 // It is, however, enough for most applications.
503 //
504 // True is returned if a replacement was actually done, False if no
505 // replacement was done.
506 //
507 // The resource set changed callbacks are called just before the
508 // function returns. The mapping_changed field in the callback
509 // structure is set to the return value of the function.
510 //
511 // If an apply_callback is set, it is called just before the resource
512 // set change callbacks are called. It is called with the same callback
513 // structure as the resource change callbacks.
514 //
515 // Note that the default values are not selected. This leads to that
516 // nothing is done if new_value is empty. Also, parts of the resource
517 // sets that fall back to the default will not be changed.
518 //
519 // For a full update, set the affected resource values and then call
520 // xmubUpdateAllResources.
521 //
522 // Example:
523 //
524 // To change to the color set "Arizona", using the default values, call
525 // this function with the parameters
526 //   ( info, "palette", "Palette", "Arizona" )
527 //
528 // After this call, you may loop through your widgets and update the color,
529 // if desired.
530 */
531 
532 Boolean
533 xmubResUpdateAllResources( xmubResourceMappingInfoRef  info,
534                            xmubAppResDesc              resource_sets[],
535                            Cardinal                    num_resource_sets,
536                            xmubResSetChangeCallback    apply_callback,
537                            XtPointer                   client_data );
538 /*
539 // Clears the translation database and refreshes all resources according
540 // to xmubResReplace from the mapping_db.
541 // The resources are then merged into the translation db.
542 // The original strings are taken from orig_db.
543 //
544 // If an apply_callback is set, it is called just before the resource
545 // set change callbacks are called. It is called with the same callback
546 // structure as the resource change callbacks.
547 // Note that it is called with res_name, res_class and new_value set
548 // to NULL.
549 //
550 // The resource change callbacks are called for each resource, even
551 // though they may not have been changed.
552 */
553 
554 /*
555 // = LISTING RESOURCE CLASSES
556 */
557 char**
558 xmubResListClasses( xmubResourceMappingInfoRef  info,
559                     char*                       keyword,
560                     Boolean                     sorted,
561                     XrmDatabase                 db );
562 /*
563 // Runs through the database and returns a list of all resource sets
564 // that have the keyword defined. The list is guaranteed not to contain
565 // duplicates. If sorted is set, the strings are sorted in ascending order
566 // with strcoll(). If db is NULL, info -\> mapping_db is taken.
567 //
568 // The returned array is null-terminated. The strings and the array
569 // have been allocated in the function and must be freed by the caller
570 // using XtFree(). If no resource set containing the keyword is found,
571 // NULL is returned.
572 */
573 
574 /*
575 // = CALLBACKS
576 */
577 void
578 xmubResAddSetChangedCallback( xmubResourceMappingInfoRef  info,
579                               xmubResSetChangeCallback    callback,
580                               XtPointer                   client_data );
581 /*
582 // Adds the callback and its client_data to the internal list of
583 // callbacks for the resource set change.
584 */
585 
586 void
587 xmubResRemoveSetChangedCallback( xmubResourceMappingInfoRef  info,
588                                  xmubResSetChangeCallback    callback,
589                                  XtPointer                   client_data );
590 /*
591 // Removes the callback.
592 */
593 
594 
595 /*
596 // = FREEING STORAGE
597 */
598 void
599 xmubResFreeInfo( xmubResourceMappingInfoRef  info );
600 /*
601 // Frees the information pointed to by info.
602 */
603 
604 void
605 xmubResClearInternalDatabases(
606   xmubResourceMappingInfoRef  info,
607   Boolean                     clear_orig_db,
608   Boolean                     clear_mapping_db,
609   Boolean                     clear_translation_db,
610   Boolean                     clear_merge_db );
611 /*
612 // Clears the internal databases selectively.
613 */
614 
615 #ifdef __cplusplus
616 }
617 #endif
618 
619 #endif
620