prop.c revision 1a650d1e
1/* $Xorg: prop.c,v 1.4 2001/02/09 02:06:01 xorgcvs Exp $ */
2/******************************************************************************
3
4Copyright 1993, 1998  The Open Group
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from The Open Group.
25******************************************************************************/
26/* $XFree86: xc/programs/xsm/prop.c,v 1.5tsi Exp $ */
27
28#include "xsm.h"
29#include "info.h"
30#include "prop.h"
31#include <X11/Xaw/List.h>
32
33
34void
35FreePropValues(List *propValues)
36{
37    List	*pv;
38    PropValue	*pval;
39
40    for (pv = ListFirst (propValues); pv; pv = ListNext (pv))
41    {
42	pval = (PropValue *) pv->thing;
43	XtFree ((char *) pval->value);
44	XtFree ((char *) pval);
45    }
46
47    ListFreeAll (propValues);
48}
49
50
51
52void
53FreeProp(Prop *prop)
54{
55    FreePropValues (prop->values);
56    XtFree (prop->name);
57    XtFree (prop->type);
58    XtFree ((char *) prop);
59}
60
61
62
63void
64SetInitialProperties(ClientRec *client, List *props)
65{
66    List *pl;
67
68    if (verbose)
69	printf("Setting initial properties for %s\n", client->clientId);
70
71    if (client->props)
72    {
73	/*
74	 * The only way client->props could be non-NULL is if the list
75	 * was initialized, but nothing was added yet.  So we just free
76	 * the head of the list.
77	 */
78
79	XtFree ((char *) client->props);
80    }
81
82    client->props = props;
83
84    for (pl = ListFirst (props); pl; pl = ListNext (pl))
85    {
86	Prop		*pprop;
87	PropValue	*pval;
88	List		*vl;
89
90	pprop = (Prop *) pl->thing;
91
92	if (strcmp (pprop->name, SmDiscardCommand) == 0)
93	{
94	    if (client->discardCommand)
95		XtFree (client->discardCommand);
96
97	    vl = ListFirst (pprop->values);
98	    pval = (PropValue *) vl->thing;
99
100	    client->discardCommand = (char *) XtNewString (
101		(char *) pval->value);
102	}
103	else if (strcmp (pprop->name, SmRestartStyleHint) == 0)
104	{
105	    int hint;
106
107	    vl = ListFirst (pprop->values);
108	    pval = (PropValue *) vl->thing;
109
110	    hint = (int) *((char *) (pval->value));
111
112	    if (hint == SmRestartIfRunning || hint == SmRestartAnyway ||
113		hint == SmRestartImmediately || hint == SmRestartNever)
114	    {
115		client->restartHint = hint;
116	    }
117	}
118    }
119}
120
121
122
123void
124SetProperty(ClientRec *client, SmProp *theProp, Bool freeIt)
125{
126    List 	*pl;
127    Prop	*pprop = NULL;
128    int		found = 0, i;
129
130    /*
131     * If the property exists, delete the property values.  We can
132     * re-use the actual property header.
133     */
134
135    for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
136    {
137	pprop = (Prop *) pl->thing;
138
139	if (strcmp (theProp->name, pprop->name) == 0 &&
140	    strcmp (theProp->type, pprop->type) == 0)
141	{
142	    FreePropValues (pprop->values);
143	    found = 1;
144	    break;
145	}
146    }
147
148
149    /*
150     * Add the new property
151     */
152
153    if (!found)
154    {
155	pprop = (Prop *) XtMalloc (sizeof (Prop));
156	pprop->name = XtNewString (theProp->name);
157	pprop->type = XtNewString (theProp->type);
158    }
159
160    pprop->values = ListInit ();
161
162    for (i = 0; i < theProp->num_vals; i++)
163    {
164	PropValue *pval = (PropValue *) XtMalloc (sizeof (PropValue));
165
166	pval->length = theProp->vals[i].length;
167	pval->value = (XtPointer) XtMalloc (theProp->vals[i].length + 1);
168	memcpy (pval->value, theProp->vals[i].value, theProp->vals[i].length);
169	((char *) pval->value)[theProp->vals[i].length] = '\0';
170
171	ListAddLast (pprop->values, (char *) pval);
172    }
173
174    if (pl)
175	pl->thing = (char *) pprop;
176    else
177	ListAddLast (client->props, (char *) pprop);
178
179    if (strcmp (theProp->name, SmDiscardCommand) == 0)
180    {
181	if (saveInProgress)
182	{
183	    /*
184	     * We are in the middle of a save yourself.  We save the
185	     * discard command we get now, and make it the current discard
186	     * command when the save is over.
187	     */
188
189	    if (client->saveDiscardCommand)
190		XtFree (client->saveDiscardCommand);
191	    client->saveDiscardCommand =
192		(char *) XtNewString ((char *) theProp->vals[0].value);
193
194	    client->receivedDiscardCommand = True;
195	}
196	else
197	{
198	    if (client->discardCommand)
199		XtFree (client->discardCommand);
200	    client->discardCommand =
201		(char *) XtNewString ((char *) theProp->vals[0].value);
202	}
203    }
204    else if (strcmp (theProp->name, SmRestartStyleHint) == 0)
205    {
206	int hint = (int) *((char *) (theProp->vals[0].value));
207
208	if (hint == SmRestartIfRunning || hint == SmRestartAnyway ||
209	    hint == SmRestartImmediately || hint == SmRestartNever)
210	{
211	    client->restartHint = hint;
212	}
213    }
214
215    if (freeIt)
216	SmFreeProperty (theProp);
217}
218
219
220
221void
222DeleteProperty(ClientRec *client, char *propname)
223{
224    List *pl;
225
226    for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
227    {
228	Prop *pprop = (Prop *) pl->thing;
229
230	if (strcmp (pprop->name, propname) == 0)
231	{
232	    FreeProp (pprop);
233	    ListFreeOne (pl);
234
235	    if (strcmp (propname, SmDiscardCommand) == 0)
236	    {
237		if (client->discardCommand)
238		{
239		    XtFree (client->discardCommand);
240		    client->discardCommand = NULL;
241		}
242
243		if (client->saveDiscardCommand)
244		{
245		    XtFree (client->saveDiscardCommand);
246		    client->saveDiscardCommand = NULL;
247		}
248	    }
249	    break;
250	}
251    }
252}
253
254
255
256void
257SetPropertiesProc(SmsConn smsConn, SmPointer managerData, int numProps,
258		  SmProp **props)
259{
260    ClientRec	*client = (ClientRec *) managerData;
261    int		updateList, i;
262
263    if (verbose)
264    {
265	printf ("Client Id = %s, received SET PROPERTIES ", client->clientId);
266	printf ("[Num props = %d]\n", numProps);
267    }
268
269    updateList = (ListCount (client->props) == 0) &&
270	numProps > 0 && client_info_visible;
271
272    for (i = 0; i < numProps; i++)
273    {
274	SetProperty (client, props[i], True /* free it */);
275    }
276
277    free ((char *) props);
278
279    if (updateList)
280    {
281	/*
282	 * We have enough info from the client to display it in our list.
283	 */
284
285	UpdateClientList ();
286	XawListHighlight (clientListWidget, current_client_selected);
287    }
288    else if (client_prop_visible && clientListRecs &&
289	clientListRecs[current_client_selected] == client)
290    {
291	DisplayProps (client);
292    }
293}
294
295
296
297void
298DeletePropertiesProc(SmsConn smsConn, SmPointer managerData,
299		     int numProps, char **propNames)
300
301{
302    ClientRec	*client = (ClientRec *) managerData;
303    int		i;
304
305    if (verbose) {
306	printf ("Client Id = %s, received DELETE PROPERTIES ",
307	    client->clientId);
308	printf ("[Num props = %d]\n", numProps);
309    }
310
311    for (i = 0; i < numProps; i++)
312    {
313	if (verbose)
314	    printf ("   Name:	%s\n", propNames[i]);
315
316	DeleteProperty (client, propNames[i]);
317
318	free (propNames[i]);
319    }
320
321    free ((char *) propNames);
322}
323
324
325
326void
327GetPropertiesProc(SmsConn smsConn, SmPointer managerData)
328{
329    ClientRec	*client = (ClientRec *) managerData;
330    SmProp	**propsRet, *propRet;
331    SmPropValue *propValRet;
332    Prop	*pprop;
333    PropValue	*pval;
334    List	*pl, *pj;
335    int		numProps;
336    int		index, i;
337
338    if (verbose)
339    {
340	printf ("Client Id = %s, received GET PROPERTIES\n", client->clientId);
341	printf ("\n");
342    }
343
344    /*
345     * Unfortunately, we store the properties in a format different
346     * from the one required by SMlib.
347     */
348
349    numProps = ListCount (client->props);
350    propsRet = (SmProp **) XtMalloc (numProps * sizeof (SmProp *));
351
352    index = 0;
353    for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
354    {
355	propsRet[index] = propRet = (SmProp *) XtMalloc (sizeof (SmProp));
356
357	pprop = (Prop *) pl->thing;
358
359	propRet->name = XtNewString (pprop->name);
360	propRet->type = XtNewString (pprop->type);
361	propRet->num_vals = ListCount (pprop->values);
362	propRet->vals = propValRet = (SmPropValue *) XtMalloc (
363	    propRet->num_vals * sizeof (SmPropValue));
364
365	for (pj = ListFirst (pprop->values); pj; pj = ListNext (pj))
366	{
367	    pval = (PropValue *) pj->thing;
368
369	    propValRet->length = pval->length;
370	    propValRet->value = (SmPointer) XtMalloc (pval->length);
371	    memcpy (propValRet->value, pval->value, pval->length);
372
373	    propValRet++;
374	}
375
376	index++;
377    }
378
379    SmsReturnProperties (smsConn, numProps, propsRet);
380
381    if (verbose)
382    {
383	printf ("Client Id = %s, sent PROPERTIES REPLY [Num props = %d]\n",
384		client->clientId, numProps);
385    }
386
387    for (i = 0; i < numProps; i++)
388	SmFreeProperty (propsRet[i]);
389    XtFree ((char *) propsRet);
390}
391