Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtsession / SmProp.c
1 /*
2  * (c) Copyright 1995 Digital Equipment Corporation.
3  * (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
4  * (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
5  * (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
6  * (c) Copyright 1993, 1994, 1995 Novell, Inc. 
7  * (c) Copyright 1995 FUJITSU LIMITED.
8  * (c) Copyright 1995 Hitachi.
9  *
10  * $XConsortium: SmProp.c /main/4 1996/10/07 10:29:51 drk $
11  */
12
13 #include <stdio.h>
14 #include <X11/Intrinsic.h>
15 #include <X11/SM/SMlib.h>
16 #include "SmXSMP.h"
17
18 /*
19  * Forward declarations
20  */
21 static SmPropValue * CopyPropValues (
22         int                     numPropValues,
23         SmPropValue             * thePropValues);
24
25
26 void
27 SetPropertiesProc (
28         SmsConn                 smsConn,
29         SmPointer               managerData,
30         int                     numProps,
31         SmProp                  **theProps)
32 {
33         ClientRecPtr            pClient = (ClientRecPtr) managerData;
34         PropertyRecPtr          pProp;
35         int                     i, j;
36         Boolean                 found;
37
38 #ifdef DEBUG
39         (void) printf ("Received SET PROPERTIES [%p]\n", smsConn);
40 #endif /* DEBUG */
41
42         if (numProps == 0)
43                 return;
44
45         for (i = 0; i < numProps; i++) {
46
47                 found = False;
48
49                 if (theProps[i]->num_vals == 0)
50                         continue;
51
52                 for (pProp = pClient->props; 
53                      pProp != NULL; 
54                      pProp = pProp->next) {
55                         
56                         if (!strcmp (theProps[i]->name, pProp->prop.name) &&
57                             !strcmp (theProps[i]->type, pProp->prop.type)) {
58                                 /* 
59                                  * Reuse this property but replace its
60                                  * property values
61                                  */
62
63                                 for (j = 0; j < pProp->prop.num_vals; j++) {
64                                         XtFree (pProp->prop.vals[j].value);
65                                 }
66
67                                 if (pProp->prop.num_vals > 0)
68                                         XtFree ((char *) pProp->prop.vals);
69
70                                 pProp->prop.vals = CopyPropValues (
71                                         theProps[i]->num_vals, 
72                                         theProps[i]->vals);
73
74                                 pProp->prop.num_vals = theProps[i]->num_vals;
75
76                                 found = True;
77                                 break;
78                         }       
79                 }
80
81                 if (!found) {
82
83                         /*
84                          * Put it at the end of the list (or the beginning
85                          * if this client has no properties)
86                          */
87                         PropertyRecPtr          trail = pClient->props;
88                         for (pProp = pClient->props; 
89                              pProp != NULL; 
90                              trail = pProp, pProp = pProp->next);
91
92
93                         pProp = (PropertyRecPtr)XtMalloc (sizeof (PropertyRec));
94                         if (!pProp)
95                                 return;
96
97                         if (trail)
98                                 trail->next = pProp;
99                         else
100                                 pClient->props = pProp;
101
102                         pProp->prop.name = XtNewString (theProps[i]->name);
103                         pProp->prop.type = XtNewString (theProps[i]->type);
104                         pProp->prop.num_vals = theProps[i]->num_vals;
105                         pProp->next = NULL;
106
107                         pProp->prop.vals = CopyPropValues (
108                                 theProps[i]->num_vals, theProps[i]->vals);
109                 }
110
111                 SmFreeProperty (theProps[i]);
112         }
113
114         if (theProps)
115                 free ((char *) theProps);
116
117 #ifdef DEBUG
118         for (i = 0, pProp = pClient->props; 
119              pProp != NULL; 
120              i++, pProp = pProp->next) {
121                 (void) printf ("\t[%2d] name = %s\n", i + 1, 
122                         pProp->prop.name);
123                 (void) printf ("\t[%2d] type = %s\n", i + 1, 
124                         pProp->prop.type);
125                 (void) printf ("\t[%2d] num props = %d\n", i + 1, 
126                         pProp->prop.num_vals);
127                 for (j = 0; j < pProp->prop.num_vals; j++) {
128                         (void) printf ("\t\t [%2d] (%3d bytes) = %s\n", j + 1,
129                                 pProp->prop.vals[j].length,
130                                 pProp->prop.vals[j].value);
131                 }
132         }
133 #endif /* DEBUG */
134 }
135
136
137 void 
138 DeletePropertiesProc (
139         SmsConn                 smsConn,
140         SmPointer               managerData,
141         int                     numProps,
142         char                    **propNames)
143 {
144         ClientRecPtr            pClient = (ClientRecPtr) managerData;
145         int                     i;
146
147 #ifdef DEBUG
148         (void) printf ("Received DELETE PROPERTIES [%p] - %d properties\n", 
149                         smsConn, numProps);
150         for (i = 0; i < numProps; i++)
151                 (void) printf ("\t%s\n", propNames[i]);
152 #endif /* DEBUG */
153
154         if (numProps == 0)
155                 return;
156
157         for (i = 0; i < numProps; i++) {
158
159                 PropertyRecPtr          pProp;
160                 PropertyRecPtr          tmp;
161                 PropertyRecPtr          trail;
162
163                 for (pProp = pClient->props, trail = pClient->props ; 
164                      pProp != NULL;
165                      trail = pProp, pProp = pProp->next) {
166
167                         if (!strcmp (pProp->prop.name, propNames[i])) {
168
169                                 int             j;
170
171                                 XtFree (pProp->prop.name);
172                                 XtFree (pProp->prop.type);
173
174                                 for (j = 0; j < pProp->prop.num_vals; j++) {
175                                         XtFree (pProp->prop.vals[j].value);
176                                 }
177
178                                 if (pProp->prop.num_vals > 0)
179                                         XtFree ((char *) pProp->prop.vals);
180                                 /*
181                                  * Remove the record from the list and then
182                                  * free the record
183                                  */
184                                 trail->next = pProp->next;
185                                 XtFree ((char *) pProp);
186                                 pProp = trail;
187                         }
188                 }
189                 
190                 free (propNames[i]);
191         }
192
193         free ((char *) propNames);
194 }
195
196
197 void
198 GetPropertiesProc (
199         SmsConn                 smsConn,
200         SmPointer               managerData)
201 {
202         ClientRecPtr            pClient = (ClientRecPtr) managerData;
203         PropertyRecPtr          pProp;
204         PropertyRecPtr          trail;
205         int                     numProps;
206         int                     i, j;
207         SmProp                  **pPropsRet;
208
209 #ifdef DEBUG
210         (void) printf ("Received GET PROPERTIES [%p]\n", smsConn);
211 #endif /* DEBUG */
212
213         if (!pClient->props) {
214                 SmsReturnProperties (smsConn, 0, NULL);
215                 return;
216         }
217
218         for (pProp = pClient->props, numProps = 0; 
219              pProp != NULL;
220              pProp = pProp->next, numProps++);
221
222         pPropsRet = (SmProp **) XtMalloc (numProps * sizeof (SmProp *));
223
224         if (!pPropsRet) {
225                 SmsReturnProperties (smsConn, 0, NULL);
226                 return;
227         }
228
229         /*
230          * This function must return an array of pointers to SmProp
231          * structures and since the properties are actually stored
232          * in a linked list, a transformation is required.
233          */
234         for (i=0, pProp = pClient->props; 
235              pProp != NULL; 
236              i++, pProp = pProp->next) {
237
238                 pPropsRet[i] = (SmProp *) XtMalloc (sizeof (SmProp));
239                 if (!pPropsRet[i]) {
240                         SmsReturnProperties (smsConn, 0, NULL);
241                         return;
242                 }
243
244                 pPropsRet[i]->name = XtNewString (pProp->prop.name);
245                 pPropsRet[i]->type = XtNewString (pProp->prop.type);
246                 pPropsRet[i]->num_vals = pProp->prop.num_vals;
247                 pPropsRet[i]->vals = (SmPropValue *) XtMalloc (
248                         pProp->prop.num_vals * sizeof (SmPropValue));
249
250                 if (!pPropsRet[i]->vals) {
251                         SmsReturnProperties (smsConn, 0, NULL);
252                         return;
253                 }
254
255                 for (j = 0; j < pProp->prop.num_vals; j++) {
256
257                         pPropsRet[i]->vals[j].length = 
258                                 pProp->prop.vals[j].length;
259                         pPropsRet[i]->vals[j].value = (SmPointer)
260                                 XtMalloc (pProp->prop.vals[j].length);
261
262                         if (!pPropsRet[i]->vals[j].value) {
263                                 SmsReturnProperties (smsConn, 0, NULL);
264                                 return;
265                         }
266
267                         memcpy (pPropsRet[i]->vals[j].value,
268                                 pProp->prop.vals[j].value,
269                                 pProp->prop.vals[j].length);
270                 }
271         }
272
273         SmsReturnProperties (smsConn, numProps, pPropsRet);
274
275 #ifdef DEBUG
276         for (i = 0; i < numProps; i++) {
277                 (void) printf ("\t[%2d] name = %s\n", i + 1, 
278                         pPropsRet[i]->name);
279                 (void) printf ("\t[%2d] type = %s\n", i + 1, 
280                         pPropsRet[i]->type);
281                 (void) printf ("\t[%2d] num props = %d\n", i + 1, 
282                         pPropsRet[i]->num_vals);
283                 for (j = 0; j < pPropsRet[i]->num_vals; j++) {
284                         (void) printf ("\t\t [%2d] (%3d bytes) = %s\n", j + 1,
285                                 pPropsRet[i]->vals[j].length,
286                                 pPropsRet[i]->vals[j].value);
287                 }
288         }
289 #endif /* DEBUG */
290
291         for (i = 0; i < numProps; i++)
292                 SmFreeProperty (pPropsRet[i]);
293
294         XtFree ((char *) pPropsRet);
295 }
296
297
298 static SmPropValue *
299 CopyPropValues (
300         int                     numPropValues,
301         SmPropValue             * thePropValues)
302 {
303         SmPropValue             * pPropValueRet;
304         int                     i;
305
306         pPropValueRet = (SmPropValue *) XtMalloc (numPropValues *
307                   sizeof (SmPropValue));
308
309         if (!pPropValueRet)
310                 return (NULL);
311
312         for (i = 0; i < numPropValues; i++) {
313
314                 pPropValueRet[i].length = thePropValues[i].length;
315                 pPropValueRet[i].value = (SmPointer) 
316                         XtMalloc(thePropValues[i].length + 1);
317
318                 if (!pPropValueRet[i].value)
319                         return (NULL);
320
321                 memcpy (pPropValueRet[i].value,
322                         thePropValues[i].value,
323                         thePropValues[i].length);
324
325                 ((char *) pPropValueRet[i].value)[pPropValueRet[i].length]='\0';
326         }
327
328         return (pPropValueRet);
329 }
330
331
332 /*
333  * Returns a ptr to the property record list for the given
334  * property.
335  */
336 PropertyRecPtr
337 GetPropertyRec (
338         ClientRecPtr            pClientRec,
339         char                    * propName)
340 {
341         PropertyRecPtr          pPropRec;
342
343         for (pPropRec = pClientRec->props; pPropRec; 
344                         pPropRec = pPropRec->next) {
345
346                 if (!strcmp (propName, pPropRec->prop.name))
347                         return (pPropRec);
348
349         }
350
351         return (pPropRec);
352 }
353
354
355 /*
356  * If the given property exists, it returns a ptr to the first
357  * value of the property if the type of the property is SmARRAY8
358  * (char *).
359  */
360 char *
361 GetArrayPropertyValue (
362         ClientRecPtr            pClientRec,
363         char                    * propName)
364 {
365         PropertyRecPtr          pPropRec;
366
367         if ((pPropRec = GetPropertyRec (pClientRec, propName)) == NULL)
368                 return (NULL);
369
370         if ((!strcmp (pPropRec->prop.type, SmARRAY8)) &&
371             (pPropRec->prop.num_vals >= 1))
372                 return (pPropRec->prop.vals[0].value);
373
374         return (NULL);
375 }
376
377
378 /*************************************<->*************************************
379  *
380  *  GetListOfArrayPropertyValue -
381  *
382  *  Description: If the specified property exits and its type is
383  *      a LISTofARRAY8, then a NULL-terminated array of pointers
384  *      to the values is returned.
385  *
386  *  Returns: NULL-terminated array of values or NULL
387  *
388  *  Comments: caller is responsible for using XtFree to free the returned
389  *      pointer if it is not NULL
390  *
391  *************************************<->***********************************/
392 char **
393 GetListOfArrayPropertyValue (
394         ClientRecPtr            pClientRec,
395         char                    * propName)
396 {
397         PropertyRecPtr          pPropRec;
398         char                    ** ppchar;
399         int                     i;
400
401         if ((pPropRec = GetPropertyRec (pClientRec, propName)) == NULL)
402                 return (NULL);
403
404         if ((strcmp (pPropRec->prop.type, SmLISTofARRAY8)) ||
405                         (pPropRec->prop.num_vals <= 0))
406                 return (NULL);
407
408         ppchar = (char **) XtMalloc ((pPropRec->prop.num_vals + 1) *
409                                    sizeof (char *));
410         if (!ppchar)
411                 return (NULL);
412
413         for (i = 0; i < pPropRec->prop.num_vals; i++)
414                 ppchar[i] = pPropRec->prop.vals[i].value;
415
416         ppchar[pPropRec->prop.num_vals] = NULL;
417
418         return (ppchar);
419 }
420
421
422 /*************************************<->*************************************
423  *
424  *  GetCardPropertyValue -
425  *
426  *  Description: If the specified property exits and its type is
427  *      a CARD8, then return its value.
428  *
429  *  Returns: True if the property is found; False otherwise
430  *
431  *************************************<->***********************************/
432 Boolean
433 GetCardPropertyValue (
434         ClientRecPtr            pClientRec,
435         char                    * propName,
436         int                     * propValue)            /* MODIFIED */
437 {
438         PropertyRecPtr          pPropRec;
439
440         if ((pPropRec = GetPropertyRec (pClientRec, propName)) == NULL)
441                 return (False);
442
443         if ((!strcmp (pPropRec->prop.type, SmCARD8)) &&
444             (pPropRec->prop.num_vals >= 1)) {
445                 int     hint =  (int) *((char *) (pPropRec->prop.vals[0].value));
446                 *propValue = hint;
447                 return (True);
448         }
449
450         return (False);
451 }