prop.c revision 8108eb18
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
33extern Widget clientListWidget;
34
35
36void
37FreePropValues(List *propValues)
38{
39    List	*pv;
40    PropValue	*pval;
41
42    for (pv = ListFirst (propValues); pv; pv = ListNext (pv))
43    {
44	pval = (PropValue *) pv->thing;
45	XtFree ((char *) pval->value);
46	XtFree ((char *) pval);
47    }
48
49    ListFreeAll (propValues);
50}
51
52
53
54void
55FreeProp(Prop *prop)
56{
57    FreePropValues (prop->values);
58    XtFree (prop->name);
59    XtFree (prop->type);
60    XtFree ((char *) prop);
61}
62
63
64
65void
66SetInitialProperties(ClientRec *client, List *props)
67{
68    List *pl;
69
70    if (verbose)
71	printf("Setting initial properties for %s\n", client->clientId);
72
73    if (client->props)
74    {
75	/*
76	 * The only way client->props could be non-NULL is if the list
77	 * was initialized, but nothing was added yet.  So we just free
78	 * the head of the list.
79	 */
80
81	XtFree ((char *) client->props);
82    }
83
84    client->props = props;
85
86    for (pl = ListFirst (props); pl; pl = ListNext (pl))
87    {
88	Prop		*pprop;
89	PropValue	*pval;
90	List		*vl;
91
92	pprop = (Prop *) pl->thing;
93
94	if (strcmp (pprop->name, SmDiscardCommand) == 0)
95	{
96	    if (client->discardCommand)
97		XtFree (client->discardCommand);
98
99	    vl = ListFirst (pprop->values);
100	    pval = (PropValue *) vl->thing;
101
102	    client->discardCommand = (char *) XtNewString (
103		(char *) pval->value);
104	}
105	else if (strcmp (pprop->name, SmRestartStyleHint) == 0)
106	{
107	    int hint;
108
109	    vl = ListFirst (pprop->values);
110	    pval = (PropValue *) vl->thing;
111
112	    hint = (int) *((char *) (pval->value));
113
114	    if (hint == SmRestartIfRunning || hint == SmRestartAnyway ||
115		hint == SmRestartImmediately || hint == SmRestartNever)
116	    {
117		client->restartHint = hint;
118	    }
119	}
120    }
121}
122
123
124
125void
126SetProperty(ClientRec *client, SmProp *theProp, Bool freeIt)
127{
128    List 	*pl;
129    Prop	*pprop = NULL;
130    int		found = 0, i;
131
132    /*
133     * If the property exists, delete the property values.  We can
134     * re-use the actual property header.
135     */
136
137    for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
138    {
139	pprop = (Prop *) pl->thing;
140
141	if (strcmp (theProp->name, pprop->name) == 0 &&
142	    strcmp (theProp->type, pprop->type) == 0)
143	{
144	    FreePropValues (pprop->values);
145	    found = 1;
146	    break;
147	}
148    }
149
150
151    /*
152     * Add the new property
153     */
154
155    if (!found)
156    {
157	pprop = (Prop *) XtMalloc (sizeof (Prop));
158	pprop->name = XtNewString (theProp->name);
159	pprop->type = XtNewString (theProp->type);
160    }
161
162    pprop->values = ListInit ();
163
164    for (i = 0; i < theProp->num_vals; i++)
165    {
166	PropValue *pval = (PropValue *) XtMalloc (sizeof (PropValue));
167
168	pval->length = theProp->vals[i].length;
169	pval->value = (XtPointer) XtMalloc (theProp->vals[i].length + 1);
170	memcpy (pval->value, theProp->vals[i].value, theProp->vals[i].length);
171	((char *) pval->value)[theProp->vals[i].length] = '\0';
172
173	ListAddLast (pprop->values, (char *) pval);
174    }
175
176    if (pl)
177	pl->thing = (char *) pprop;
178    else
179	ListAddLast (client->props, (char *) pprop);
180
181    if (strcmp (theProp->name, SmDiscardCommand) == 0)
182    {
183	if (saveInProgress)
184	{
185	    /*
186	     * We are in the middle of a save yourself.  We save the
187	     * discard command we get now, and make it the current discard
188	     * command when the save is over.
189	     */
190
191	    if (client->saveDiscardCommand)
192		XtFree (client->saveDiscardCommand);
193	    client->saveDiscardCommand =
194		(char *) XtNewString ((char *) theProp->vals[0].value);
195
196	    client->receivedDiscardCommand = True;
197	}
198	else
199	{
200	    if (client->discardCommand)
201		XtFree (client->discardCommand);
202	    client->discardCommand =
203		(char *) XtNewString ((char *) theProp->vals[0].value);
204	}
205    }
206    else if (strcmp (theProp->name, SmRestartStyleHint) == 0)
207    {
208	int hint = (int) *((char *) (theProp->vals[0].value));
209
210	if (hint == SmRestartIfRunning || hint == SmRestartAnyway ||
211	    hint == SmRestartImmediately || hint == SmRestartNever)
212	{
213	    client->restartHint = hint;
214	}
215    }
216
217    if (freeIt)
218	SmFreeProperty (theProp);
219}
220
221
222
223void
224DeleteProperty(ClientRec *client, char *propname)
225{
226    List *pl;
227
228    for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
229    {
230	Prop *pprop = (Prop *) pl->thing;
231
232	if (strcmp (pprop->name, propname) == 0)
233	{
234	    FreeProp (pprop);
235	    ListFreeOne (pl);
236
237	    if (strcmp (propname, SmDiscardCommand) == 0)
238	    {
239		if (client->discardCommand)
240		{
241		    XtFree (client->discardCommand);
242		    client->discardCommand = NULL;
243		}
244
245		if (client->saveDiscardCommand)
246		{
247		    XtFree (client->saveDiscardCommand);
248		    client->saveDiscardCommand = NULL;
249		}
250	    }
251	    break;
252	}
253    }
254}
255
256
257
258void
259SetPropertiesProc(SmsConn smsConn, SmPointer managerData, int numProps,
260		  SmProp **props)
261{
262    ClientRec	*client = (ClientRec *) managerData;
263    int		updateList, i;
264
265    if (verbose)
266    {
267	printf ("Client Id = %s, received SET PROPERTIES ", client->clientId);
268	printf ("[Num props = %d]\n", numProps);
269    }
270
271    updateList = (ListCount (client->props) == 0) &&
272	numProps > 0 && client_info_visible;
273
274    for (i = 0; i < numProps; i++)
275    {
276	SetProperty (client, props[i], True /* free it */);
277    }
278
279    free ((char *) props);
280
281    if (updateList)
282    {
283	/*
284	 * We have enough info from the client to display it in our list.
285	 */
286
287	UpdateClientList ();
288	XawListHighlight (clientListWidget, current_client_selected);
289    }
290    else if (client_prop_visible && clientListRecs &&
291	clientListRecs[current_client_selected] == client)
292    {
293	DisplayProps (client);
294    }
295}
296
297
298
299void
300DeletePropertiesProc(SmsConn smsConn, SmPointer managerData,
301		     int numProps, char **propNames)
302
303{
304    ClientRec	*client = (ClientRec *) managerData;
305    int		i;
306
307    if (verbose) {
308	printf ("Client Id = %s, received DELETE PROPERTIES ",
309	    client->clientId);
310	printf ("[Num props = %d]\n", numProps);
311    }
312
313    for (i = 0; i < numProps; i++)
314    {
315	if (verbose)
316	    printf ("   Name:	%s\n", propNames[i]);
317
318	DeleteProperty (client, propNames[i]);
319
320	free (propNames[i]);
321    }
322
323    free ((char *) propNames);
324}
325
326
327
328void
329GetPropertiesProc(SmsConn smsConn, SmPointer managerData)
330{
331    ClientRec	*client = (ClientRec *) managerData;
332    SmProp	**propsRet, *propRet;
333    SmPropValue *propValRet;
334    Prop	*pprop;
335    PropValue	*pval;
336    List	*pl, *pj;
337    int		numProps;
338    int		index, i;
339
340    if (verbose)
341    {
342	printf ("Client Id = %s, received GET PROPERTIES\n", client->clientId);
343	printf ("\n");
344    }
345
346    /*
347     * Unfortunately, we store the properties in a format different
348     * from the one required by SMlib.
349     */
350
351    numProps = ListCount (client->props);
352    propsRet = (SmProp **) XtMalloc (numProps * sizeof (SmProp *));
353
354    index = 0;
355    for (pl = ListFirst (client->props); pl; pl = ListNext (pl))
356    {
357	propsRet[index] = propRet = (SmProp *) XtMalloc (sizeof (SmProp));
358
359	pprop = (Prop *) pl->thing;
360
361	propRet->name = XtNewString (pprop->name);
362	propRet->type = XtNewString (pprop->type);
363	propRet->num_vals = ListCount (pprop->values);
364	propRet->vals = propValRet = (SmPropValue *) XtMalloc (
365	    propRet->num_vals * sizeof (SmPropValue));
366
367	for (pj = ListFirst (pprop->values); pj; pj = ListNext (pj))
368	{
369	    pval = (PropValue *) pj->thing;
370
371	    propValRet->length = pval->length;
372	    propValRet->value = (SmPointer) XtMalloc (pval->length);
373	    memcpy (propValRet->value, pval->value, pval->length);
374
375	    propValRet++;
376	}
377
378	index++;
379    }
380
381    SmsReturnProperties (smsConn, numProps, propsRet);
382
383    if (verbose)
384    {
385	printf ("Client Id = %s, sent PROPERTIES REPLY [Num props = %d]\n",
386		client->clientId, numProps);
387    }
388
389    for (i = 0; i < numProps; i++)
390	SmFreeProperty (propsRet[i]);
391    XtFree ((char *) propsRet);
392}
393