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