2 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
3 * (c) Copyright 1993, 1994 International Business Machines Corp. *
4 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
5 * (c) Copyright 1993, 1994 Novell, Inc. *
7 /*Add a string to the XA_RESOURCE_MANAGER*/
10 * DIGITAL EQUIPMENT CORPORATION
11 * MAYNARD, MASSACHUSETTS
12 * ALL RIGHTS RESERVED.
14 * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
15 * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
16 * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
17 * ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
19 * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS,
20 * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT
24 * Permission to use, copy, modify, and distribute this software and its
25 * documentation for any purpose and without fee is hereby granted, provided
26 * that the above copyright notice appear in all copies and that both that
27 * copyright notice and this permission notice appear in supporting
28 * documentation, and that the name of Digital Equipment Corporation not be
29 * used in advertising or publicity pertaining to distribution of the software
30 * without specific, written prior permission.
33 /*Lifted from xrdb(1X)*/
35 *******************************************************************************
37 * File: addToResource.c
38 * RCS: $TOG: addToRes.c /main/8 1999/10/14 16:01:17 mgreess $
39 * Description: Source code for adding strings to RESOURCE_PROPERTY on
41 * Author: DEC, Robert Williams
42 * Created: Thu Apr 26 14:42:08 PDT 1990
43 * Modified: Kim Dronesen
46 * Status: Experimental (Do Not Distribute)
48 * (C) Copyright 1990, Hewlett-Packard, all rights reserved.
50 *******************************************************************************
52 /*$TOG: addToRes.c /main/8 1999/10/14 16:01:17 mgreess $ */
55 #include <X11/Xatom.h>
61 #include <Dt/SessionM.h>
62 #include "DtSvcLock.h"
64 /****************************************/
65 /* Global variables */
66 /****************************************/
68 typedef struct _Entry {
73 typedef struct _Buffer {
78 typedef struct _Entries {
83 #define INIT_BUFFER_SIZE 10000
84 #define INIT_ENTRY_SIZE 500
87 /******** Public Function Declarations ********/
89 static Buffer * _DtAllocBuffer(const char **buff);
90 static void _DtFreeBuffer(Buffer *b);
91 static void _DtAppendToBuffer(
95 static void _DtAppendEntryToBuffer(
96 register Buffer *buffer,
99 static Entries * _DtAllocEntries( void) ;
100 static void _DtFreeEntries( Entries *) ;
101 static void _DtAddEntry(
104 static int _DtCompareEntries(
107 static char * _DtFindFirst(
108 register char *string,
109 register char dest) ;
110 static void _DtGetEntries(
111 register Entries *entries,
114 static void _DtMergeEntries(
118 static void _DtAddToResProp(
122 static void _getWinProp(
128 /******** End Public Function Declarations ********/
130 /****************************************/
132 /****************************************/
138 Buffer *b = (Buffer *)malloc(sizeof(Buffer));
139 b->room = INIT_BUFFER_SIZE;
140 b->buff = buff ? (char*) *buff :
141 (char *)malloc(INIT_BUFFER_SIZE*sizeof(char));
142 b->used = buff && *buff ? strlen(*buff) : 0;
143 b->freebuff = buff ? False : True;
151 if (b->freebuff == True) free(b->buff);
161 while (b->used + len > b->room) {
162 b->buff = (char *)realloc(b->buff, 2*b->room*(sizeof(char)));
165 strncpy(b->buff + b->used, str, len);
170 _DtAllocEntries( void )
172 Entries *e = (Entries *)malloc(sizeof(Entries));
173 e->room = INIT_ENTRY_SIZE;
175 e->entry = (Entry *)malloc(INIT_ENTRY_SIZE*sizeof(Entry));
187 free(e->entry[n].tag);
188 free(e->entry[n].value);
202 for (n = 0; n < e->used; n++)
204 if (strcmp(e->entry[n].tag, entry.tag) == 0)
205 { /* overwrite old entry - free its memory first*/
206 free(e->entry[n].tag);
207 free(e->entry[n].value);
209 return ; /* ok to leave, now there's only one of each tag in db */
213 if (e->used == e->room) {
214 e->entry = (Entry *)realloc(e->entry, 2*e->room*(sizeof(Entry)));
218 e->entry[e->used++] = entry;
226 return strcmp(e1->tag, e2->tag);
230 _DtAppendEntryToBuffer(
231 register Buffer *buffer,
234 _DtAppendToBuffer(buffer, entry.tag, strlen(entry.tag));
235 _DtAppendToBuffer(buffer, ":\t", 2);
236 _DtAppendToBuffer(buffer, entry.value, strlen(entry.value));
237 _DtAppendToBuffer(buffer, "\n", 1);
242 register char *string,
248 if((len = mblen(string, MB_CUR_MAX)) > 1) {
254 if (*string == '\\') {
255 if (*++string == '\0')
258 else if (*string == dest)
266 register Entries *entries,
270 register char *line, *colon, *temp, *str, *temp2;
277 for (; str < buff->buff + buff->used; str = line + 1)
279 line = _DtFindFirst(str, '\n');
290 if (sscanf (str, "# %d", &dummy) == 1) lineno = dummy - 1;
294 *temp && *temp != '\n' && isascii(*temp) && isspace((u_char)*temp);
296 if (!*temp || *temp == '\n') continue;
298 colon = _DtFindFirst(str, ':');
305 "%s: colon missing on line %d, ignoring entry \"%s\"\n",
306 "dtprefs", lineno, str);
311 while (temp2[0] == ' ' || temp2[0] == '\t')
315 temp = (char *)malloc((length = colon - temp2) + 1);
316 strncpy(temp, temp2, length);
318 while (temp[length-1] == ' ' || temp[length-1] == '\t')
319 temp[--length] = '\0';
324 while (temp2[0] == ' ' || temp2[0] == '\t')
328 temp = (char *)malloc((length = line - temp2) + 1);
329 strncpy(temp, temp2, length);
332 entry.lineno = lineno;
334 _DtAddEntry(entries, entry);
337 if (dosort && (entries->used > 0))
338 qsort(entries->entry, entries->used, sizeof(Entry),
339 (int (*)(const void *, const void *))_DtCompareEntries);
352 while ((n < new.used) && (o < old.used))
354 cmp = strcmp(new.entry[n].tag, old.entry[o].tag);
357 _DtAppendEntryToBuffer(buffer, old.entry[o]);
362 _DtAppendEntryToBuffer(buffer, new.entry[n]);
373 _DtAppendEntryToBuffer(buffer, new.entry[n]);
378 _DtAppendEntryToBuffer(buffer, old.entry[o]);
382 _DtAppendToBuffer(buffer, "\0", 1);
392 static Bool init = True;
393 static Window winprop;
394 static Atom xa_resmgr;
395 static Atom xa_prefs;
400 winprop = XRootWindow(dpy, 0);
401 xa_resmgr = XA_RESOURCE_MANAGER;
402 xa_prefs = XInternAtom (dpy, _XA_DT_SM_PREFERENCES, False);
405 _DtSvcProcessUnlock();
408 *prop = id == _DT_ATR_RESMGR ? xa_resmgr : xa_prefs;
419 Buffer *oldBuffer, *newBuffer;
424 unsigned long nitems, leftover;
429 * Get window and property
431 _getWinProp(dpy, id, &win, &prop);
432 if (win == (Window)0)
438 * Get resource database from specified window and property.
440 defStatus = XGetWindowProperty(dpy, win,
442 100000000L,False,XA_STRING,&actualType,
443 &actualFormat,&nitems,&leftover,
444 (unsigned char**) &xdefs);
448 * Allocate oldBuffer and init from resource database string
450 oldBuffer = _DtAllocBuffer((const char**) &xdefs);
455 oldDB = _DtAllocEntries();
458 * Convert oldBuffer to oldDB.
460 _DtGetEntries(oldDB, oldBuffer, 1);
463 * Init empty newBuffer, then populate by merging db into oldDB.
465 newBuffer = _DtAllocBuffer(NULL);
466 _DtMergeEntries(newBuffer, db, *oldDB);
469 * Finally, store newBuffer into resource database.
471 XChangeProperty (dpy, win, prop,
472 XA_STRING, 8, PropModeReplace,
473 (unsigned char *)newBuffer->buff, newBuffer->used);
480 if (oldBuffer->buff) XFree(oldBuffer->buff);
481 _DtFreeBuffer(oldBuffer);
482 _DtFreeBuffer(newBuffer);
483 _DtFreeEntries(oldDB);
492 Buffer *oldBuffer, *newBuffer;
497 unsigned long nitems, leftover;
502 * Get window and property
504 _getWinProp(dpy, id, &win, &prop);
505 if (win == (Window)0)
511 * Get resource database from specified window and property.
513 defStatus = XGetWindowProperty(dpy, win,
515 100000000L,False,XA_STRING,&actualType,
516 &actualFormat,&nitems,&leftover,
517 (unsigned char**) &xdefs);
527 _DtAddResString( dpy, data, _DT_ATR_RESMGR|_DT_ATR_PREFS);
543 unsigned long nitems, leftover;
545 if((data == NULL) || (*data == NULL))
551 * Init buffer with input data
553 buffer = _DtAllocBuffer(&data);
556 * Init, then populate, newDB from buffer
558 newDB = _DtAllocEntries();
559 _DtGetEntries(newDB, buffer, 1);
561 if (flags & _DT_ATR_RESMGR)
564 * Merge newDB into RESOURCE_MANAGER
566 _DtAddToResProp(dpy, _DT_ATR_RESMGR, *newDB);
569 if (flags & _DT_ATR_PREFS)
572 * Merge newDB into _DT_SM_PREFERENCES
574 _DtAddToResProp(dpy, _DT_ATR_PREFS, *newDB);
580 _DtFreeBuffer(buffer);
581 _DtFreeEntries(newDB);