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