Merge branch 'master' of https://git.code.sf.net/p/cdesktopenv/code
[oweals/cde.git] / cde / programs / dtsession / SmXrm.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: SmXrm.c /main/4 1995/10/30 09:39:33 rswiston $ */
24 /*                                                                      *
25  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
26  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
27  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
28  * (c) Copyright 1993, 1994 Novell, Inc.                                *
29  */
30 /*************************************<+>*************************************
31  *****************************************************************************
32  **
33  **  File:        SmXrm.c
34  **
35  **  Project:     DT Session Manager (dtsession)
36  **
37  **  Description:
38  **  -----------
39  **  This file contains routines to manage an Xrm database
40  **
41  **  SmXrmSubtract() - subtract source_db from target_db and return result_db
42  **
43  *****************************************************************************
44  *************************************<+>*************************************/
45
46 #ifdef DEBUG
47 #include <stdio.h>
48 #endif
49
50 #include <X11/Intrinsic.h>
51
52 const XrmQuark empty = NULLQUARK;
53
54 struct smSubtractState {
55   XrmDatabase source_db;
56   XrmDatabase target_db;
57   XrmDatabase result_db;
58   XrmBindingList target_bindings;
59   XrmQuarkList target_quarks;
60 };
61
62
63 #ifdef DEBUG
64 static void _PrintDbEntry(
65   char *,
66   XrmBindingList,
67   XrmQuarkList,
68   XrmRepresentation *,
69   XrmValue *);
70 #endif
71
72 static Bool _CompareBindingQuarkList(
73   XrmBindingList bindings1,
74   XrmQuarkList   quarks1,
75   XrmBindingList bindings2,
76   XrmQuarkList   quarks2);
77 static Bool _SmCompareSourceAndTarget(
78   XrmDatabase *db,
79   XrmBindingList bindings,
80   XrmQuarkList quarks,
81   XrmRepresentation *type,
82   XrmValue *value,
83   XPointer closure);
84 static Bool _SmEnumerateSource(
85   XrmDatabase *db,
86   XrmBindingList bindings,
87   XrmQuarkList quarks,
88   XrmRepresentation *type,
89   XrmValue *value,
90   XPointer closure);
91
92
93 #ifndef DEBUG
94 #define _PrintDbEntry(a,b,c,d,e)
95 #endif /* !DEBUG */
96
97 \f
98 /*************************************<->*************************************
99  *
100  *  _CompareBindingQuarkList()
101  *
102  *  Description:
103  *  -----------
104  *  Compare two binding quark lists and return True if the same
105  *
106  *  Inputs:
107  *  ------
108  *  bindings1 - list1 bindings
109  *  quarks1 - list1 bindings
110  *  bindings2 - list2 bindings
111  *  quarks2 - list2 bindings
112  *
113  *  Outputs:
114  *  -------
115  *
116  *  Return:
117  *  ------
118  *  same - True if binding quark list is the same, False otherwise
119  *
120  *  Comments:
121  *  --------
122  *
123  *************************************<->***********************************/
124
125 static
126 Bool _CompareBindingQuarkList(
127   XrmBindingList bindings1,
128   XrmQuarkList   quarks1,
129   XrmBindingList bindings2,
130   XrmQuarkList   quarks2)
131 {
132   int i = 0;
133   Bool rc = False;
134
135  /* 
136   * loop through quarks in list1
137   */
138   while (quarks1[i] != NULLQUARK)
139   {
140    /*
141     * compare quark in list1 to same element in list2 and
142     * break out of loop if they differ.
143     */
144     if (quarks2[i] == NULLQUARK || quarks2[i] != quarks1[i])
145       break;
146
147    /*
148     * quarks for this level compare, now compare bindings
149     */
150     if (bindings1[i] != bindings2[i])
151       break;
152
153     i++;
154   }
155
156   if (quarks1[i] == NULLQUARK && quarks2[i] == NULLQUARK)
157   {
158    /*
159     * all quarks and bindings in list1 and list2 compare
160     */
161     rc = True;
162   }
163   
164   return(rc);
165 }
166
167 /*************************************<->*************************************
168  *
169  *  _PrintDbEntry()
170  *
171  *  Description:
172  *  -----------
173  *  Print an Xrm database entry (DEBUG only)
174  *
175  *  Inputs:
176  *  ------
177  *  leader - leading string
178  *  bindings - binding list
179  *  quarks - quark list
180  *  type - element type
181  *  value - element value
182  *
183  *  Outputs:
184  *  -------
185  *
186  *  Return:
187  *  ------
188  *
189  *  Comments:
190  *  --------
191  *
192  *************************************<->***********************************/
193
194 #ifdef DEBUG
195 static
196 void _PrintDbEntry(
197        char *leader,
198        XrmBindingList bindings,
199        XrmQuarkList quarks,
200        XrmRepresentation *type,
201        XrmValue *   value)
202 {
203    char *   str;
204    int i;
205
206    FILE *fp = fopen ("/tmp/dtsession.xrm", "a");
207
208    str = XrmQuarkToString(type);
209
210    fprintf(fp, "%8s ", leader);
211
212    i = 0;
213    while ( quarks[i] != NULLQUARK )
214    {
215       str = XrmQuarkToString(quarks[i]);
216       fprintf(fp, "%s", str);
217       i++;
218       if (quarks[i] != NULLQUARK)
219       {
220         fprintf(fp, bindings[i] == XrmBindLoosely ? "*" : ".");
221       }
222    }
223    fprintf(fp, ": %s\n",value->addr);
224    fclose(fp);
225 }
226 #endif /* DEBUG */
227
228 /*************************************<->*************************************
229  *
230  *  _SmCompareSourceAndTarget()
231  *
232  *  Description:
233  *  -----------
234  *  Xrm Enum callback that compares the current database element to the
235  *  current target element.
236  *
237  *  Inputs:
238  *  ------
239  *  db - source database
240  *  bindings - binding list
241  *  quarks - quark list
242  *  type - element type
243  *  value - element value
244  *  closure - pointer to smSubtractState data
245  *
246  *  Outputs:
247  *  -------
248  *
249  *  Return:
250  *  ------
251  *  result - True if same, False if different
252  *
253  *  Comments:
254  *  --------
255  *
256  *************************************<->***********************************/
257
258 static
259 Bool _SmCompareSourceAndTarget(
260   XrmDatabase *db,
261   XrmBindingList bindings,
262   XrmQuarkList quarks,
263   XrmRepresentation *type,
264   XrmValue *value,
265   XPointer closure)
266 {
267   struct smSubtractState *state = (struct smSubtractState *)closure;
268   Bool rc = False;
269
270   _PrintDbEntry("source", bindings, quarks, type, value);
271
272   if (_CompareBindingQuarkList(bindings, quarks,
273                               state->target_bindings, state->target_quarks))
274   {
275     rc = True;
276   }
277
278   return rc;
279 }
280
281 /*************************************<->*************************************
282  *
283  *  _SmEnumerateSource()
284  *
285  *  Description:
286  *  -----------
287  *  Xrm Enum callback that enumerates the source database for comparison
288  *  against the current target element.
289  *
290  *  Inputs:
291  *  ------
292  *  db - target database
293  *  bindings - binding list
294  *  quarks - quark list
295  *  type - element type
296  *  value - element value
297  *  closure - pointer to smSubtractState data
298  *
299  *  Outputs:
300  *  -------
301  *
302  *  Return:
303  *  ------
304  *  result - always False
305  *
306  *  Comments:
307  *  --------
308  *
309  *************************************<->***********************************/
310
311 static
312 Bool _SmEnumerateSource(
313   XrmDatabase *db,
314   XrmBindingList bindings,
315   XrmQuarkList quarks,
316   XrmRepresentation *type,
317   XrmValue *value,
318   XPointer closure)
319 {
320   struct smSubtractState *state = (struct smSubtractState *)closure;
321   Bool rc;
322
323   _PrintDbEntry("target", bindings, quarks, type, value);
324
325  /* 
326   * Enumerate source database and compare each element to current
327   * target bindings and quarks. 
328   */ 
329   state->target_bindings = bindings;
330   state->target_quarks = quarks;
331   if (XrmEnumerateDatabase(state->source_db, &empty, &empty, XrmEnumAllLevels,
332                            _SmCompareSourceAndTarget, closure) == False)
333   {
334    /*
335     * Target bindings and quarks don't match any element in source database,
336     * so copy target element to result db.
337     */
338     _PrintDbEntry("nomatch", bindings, quarks, type, value);
339     XrmQPutResource(&state->result_db, bindings, quarks, *type, value); 
340   }
341   return False;
342 }
343
344 /*************************************<->*************************************
345  *
346  *  SmXrmSubtractDatabase()
347  *
348  *  Description:
349  *  -----------
350  *  Subtracts source database from target database and returns
351  *  the result database.
352  *
353  *  Inputs:
354  *  ------
355  *  source_db - source database
356  *  target_db - target database
357  *
358  *  Outputs:
359  *  -------
360  *
361  *  Return:
362  *  ------
363  *  result_db - result database
364  *
365  *  Comments:
366  *  --------
367  *
368  *************************************<->***********************************/
369
370 /*
371  * Subtracts source database from target database and returns
372  * the result database.
373  */
374
375 XrmDatabase
376 SmXrmSubtractDatabase(
377   XrmDatabase source_db,
378   XrmDatabase target_db)
379 {
380   struct smSubtractState state;
381
382  /*
383   * return if source or target db not specified
384   */
385   if (source_db == NULL || target_db == NULL)
386     return NULL;
387
388  /*
389   * set up state
390   */
391   state.source_db = source_db;
392   state.target_db = target_db;
393   state.result_db = NULL;
394
395  /*
396   * populate result db by looping through target and
397   * copying elements that don't also exist in source db
398   */
399   XrmEnumerateDatabase(state.target_db, &empty, &empty, XrmEnumAllLevels,
400                        _SmEnumerateSource, (XPointer)&state);
401   
402   return(state.result_db); 
403 }