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