]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/dix/property.c
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / programs / Xserver / dix / property.c
1 /***********************************************************
2
3 Copyright (c) 1987  X Consortium
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
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 X CONSORTIUM 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 X Consortium 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 X Consortium.
25
26
27 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
28
29                         All Rights Reserved
30
31 Permission to use, copy, modify, and distribute this software and its 
32 documentation for any purpose and without fee is hereby granted, 
33 provided that the above copyright notice appear in all copies and that
34 both that copyright notice and this permission notice appear in 
35 supporting documentation, and that the name of Digital not be
36 used in advertising or publicity pertaining to distribution of the
37 software without specific, written prior permission.  
38
39 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
40 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
41 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
42 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
43 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
44 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
45 SOFTWARE.
46
47 ******************************************************************/
48 /* $XConsortium: property.c /main/41 1996/12/22 12:33:58 rws $ */
49 /* $XFree86: xc/programs/Xserver/dix/property.c,v 3.5 1996/12/24 11:52:04 dawes Exp $ */
50
51 #include "X.h"
52 #define NEED_REPLIES
53 #define NEED_EVENTS
54 #include "Xproto.h"
55 #include "windowstr.h"
56 #include "propertyst.h"
57 #include "dixstruct.h"
58 #include "dispatch.h"
59 #include "swaprep.h"
60 #ifdef XCSECURITY
61 #define _SECURITY_SERVER
62 #include "extensions/security.h"
63 #endif
64
65 #if defined(LBX) || defined(LBX_COMPAT)
66 int fWriteToClient(client, len, buf)
67     ClientPtr   client;
68     int         len;
69     char        *buf;
70 {
71     return WriteToClient(client, len, buf);
72 }
73 #endif
74
75 /*****************************************************************
76  * Property Stuff
77  *
78  *    ChangeProperty, DeleteProperty, GetProperties,
79  *    ListProperties
80  *
81  *   Properties below to windows.  A allocate slots each time
82  *   a property is added.  No fancy searching done.
83  *
84  *****************************************************************/
85
86 #ifdef notdef
87 static void
88 PrintPropertys(pWin)
89     WindowPtr pWin;
90 {
91     PropertyPtr pProp;
92     register int j;
93
94     pProp = pWin->userProps;
95     while (pProp)
96     {
97         ErrorF(  "%x %x\n", pProp->propertyName, pProp->type);
98         ErrorF("property format: %d\n", pProp->format);
99         ErrorF("property data: \n");
100         for (j=0; j<(pProp->format/8)*pProp->size; j++)
101            ErrorF("%c\n", pProp->data[j]);
102         pProp = pProp->next;
103     }
104 }
105 #endif
106
107 int
108 ProcRotateProperties(client)
109     ClientPtr client;
110 {
111     int     i, j, delta;
112     REQUEST(xRotatePropertiesReq);
113     WindowPtr pWin;
114     register    Atom * atoms;
115     PropertyPtr * props;               /* array of pointer */
116     PropertyPtr pProp;
117     xEvent event;
118
119     REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
120     UpdateCurrentTime();
121     pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
122                                             SecurityWriteAccess);
123     if (!pWin)
124         return(BadWindow);
125     if (!stuff->nAtoms)
126         return(Success);
127     atoms = (Atom *) & stuff[1];
128     props = (PropertyPtr *)ALLOCATE_LOCAL(stuff->nAtoms * sizeof(PropertyPtr));
129     if (!props)
130         return(BadAlloc);
131     for (i = 0; i < stuff->nAtoms; i++)
132     {
133 #ifdef XCSECURITY
134         char action = SecurityCheckPropertyAccess(client, pWin, atoms[i],
135                                 SecurityReadAccess|SecurityWriteAccess);
136 #endif
137         if (!ValidAtom(atoms[i])
138 #ifdef XCSECURITY
139             || (SecurityErrorOperation == action)
140 #endif
141            )
142         {
143             DEALLOCATE_LOCAL(props);
144             client->errorValue = atoms[i];
145             return BadAtom;
146         }
147 #ifdef XCSECURITY
148         if (SecurityIgnoreOperation == action)
149         {
150             DEALLOCATE_LOCAL(props);
151             return Success;
152         }
153 #endif
154         for (j = i + 1; j < stuff->nAtoms; j++)
155             if (atoms[j] == atoms[i])
156             {
157                 DEALLOCATE_LOCAL(props);
158                 return BadMatch;
159             }
160         pProp = wUserProps (pWin);
161         while (pProp)
162         {
163             if (pProp->propertyName == atoms[i])
164                 goto found;
165             pProp = pProp->next;
166         }
167         DEALLOCATE_LOCAL(props);
168         return BadMatch;
169 found: 
170         props[i] = pProp;
171     }
172     delta = stuff->nPositions;
173
174     /* If the rotation is a complete 360 degrees, then moving the properties
175         around and generating PropertyNotify events should be skipped. */
176
177     if ( (stuff->nAtoms != 0) && (abs(delta) % stuff->nAtoms) != 0 ) 
178     {
179         while (delta < 0)                  /* faster if abs value is small */
180             delta += stuff->nAtoms;
181         for (i = 0; i < stuff->nAtoms; i++)
182         {
183             /* Generate a PropertyNotify event for each property whose value
184                 is changed in the order in which they appear in the request. */
185  
186             event.u.u.type = PropertyNotify;
187             event.u.property.window = pWin->drawable.id;
188             event.u.property.state = PropertyNewValue;
189             event.u.property.atom = props[i]->propertyName;     
190             event.u.property.time = currentTime.milliseconds;
191             DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
192         
193             props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
194         }
195     }
196     DEALLOCATE_LOCAL(props);
197     return Success;
198 }
199
200 int 
201 ProcChangeProperty(client)
202     ClientPtr client;
203 {             
204     WindowPtr pWin;
205     char format, mode;
206     unsigned long len;
207     int sizeInBytes;
208     int totalSize;
209     int err;
210     REQUEST(xChangePropertyReq);
211
212     REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
213     UpdateCurrentTime();
214     format = stuff->format;
215     mode = stuff->mode;
216     if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
217         (mode != PropModePrepend))
218     {
219         client->errorValue = mode;
220         return BadValue;
221     }
222     if ((format != 8) && (format != 16) && (format != 32))
223     {
224         client->errorValue = format;
225         return BadValue;
226     }
227     len = stuff->nUnits;
228     if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2))
229         return BadLength;
230     sizeInBytes = format>>3;
231     totalSize = len * sizeInBytes;
232     REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize);
233
234     pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
235                                            SecurityWriteAccess);
236     if (!pWin)
237         return(BadWindow);
238     if (!ValidAtom(stuff->property))
239     {
240         client->errorValue = stuff->property;
241         return(BadAtom);
242     }
243     if (!ValidAtom(stuff->type))
244     {
245         client->errorValue = stuff->type;
246         return(BadAtom);
247     }
248
249 #ifdef XCSECURITY
250     switch (SecurityCheckPropertyAccess(client, pWin, stuff->property,
251                                         SecurityWriteAccess))
252     {
253         case SecurityErrorOperation:
254             client->errorValue = stuff->property;
255             return BadAtom;
256         case SecurityIgnoreOperation:
257             return Success;
258     }
259 #endif
260
261 #ifdef LBX
262     err = LbxChangeWindowProperty(client, pWin, stuff->property, stuff->type,
263          (int)format, (int)mode, len, TRUE, (pointer)&stuff[1], TRUE, NULL);
264 #else
265     err = ChangeWindowProperty(pWin, stuff->property, stuff->type, (int)format,
266                                (int)mode, len, (pointer)&stuff[1], TRUE);
267 #endif
268     if (err != Success)
269         return err;
270     else
271         return client->noClientException;
272 }
273
274 int
275 ChangeWindowProperty(pWin, property, type, format, mode, len, value, sendevent)
276     WindowPtr   pWin;
277     Atom        property, type;
278     int         format, mode;
279     unsigned long len;
280     pointer     value;
281     Bool        sendevent;
282 {
283 #ifdef LBX
284     return LbxChangeWindowProperty(NULL, pWin, property, type,
285                                    format, mode, len, TRUE, value,
286                                    sendevent, NULL);
287 #else
288     PropertyPtr pProp;
289     xEvent event;
290     int sizeInBytes;
291     int totalSize;
292     pointer data;
293
294     sizeInBytes = format>>3;
295     totalSize = len * sizeInBytes;
296
297     /* first see if property already exists */
298
299     pProp = wUserProps (pWin);
300     while (pProp)
301     {
302         if (pProp->propertyName == property)
303             break;
304         pProp = pProp->next;
305     }
306     if (!pProp)   /* just add to list */
307     {
308         if (!pWin->optional && !MakeWindowOptional (pWin))
309             return(BadAlloc);
310         pProp = (PropertyPtr)xalloc(sizeof(PropertyRec));
311         if (!pProp)
312             return(BadAlloc);
313         data = (pointer)xalloc(totalSize);
314         if (!data && len)
315         {
316             xfree(pProp);
317             return(BadAlloc);
318         }
319         pProp->propertyName = property;
320         pProp->type = type;
321         pProp->format = format;
322         pProp->data = data;
323         if (len)
324             memmove((char *)data, (char *)value, totalSize);
325         pProp->size = len;
326         pProp->next = pWin->optional->userProps;
327         pWin->optional->userProps = pProp;
328     }
329     else
330     {
331         /* To append or prepend to a property the request format and type
332                 must match those of the already defined property.  The
333                 existing format and type are irrelevant when using the mode
334                 "PropModeReplace" since they will be written over. */
335
336         if ((format != pProp->format) && (mode != PropModeReplace))
337             return(BadMatch);
338         if ((pProp->type != type) && (mode != PropModeReplace))
339             return(BadMatch);
340         if (mode == PropModeReplace)
341         {
342             if (totalSize != pProp->size * (pProp->format >> 3))
343             {
344                 data = (pointer)xrealloc(pProp->data, totalSize);
345                 if (!data && len)
346                     return(BadAlloc);
347                 pProp->data = data;
348             }
349             if (len)
350                 memmove((char *)pProp->data, (char *)value, totalSize);
351             pProp->size = len;
352             pProp->type = type;
353             pProp->format = format;
354         }
355         else if (len == 0)
356         {
357             /* do nothing */
358         }
359         else if (mode == PropModeAppend)
360         {
361             data = (pointer)xrealloc(pProp->data,
362                                      sizeInBytes * (len + pProp->size));
363             if (!data)
364                 return(BadAlloc);
365             pProp->data = data;
366             memmove(&((char *)data)[pProp->size * sizeInBytes], 
367                     (char *)value,
368                   totalSize);
369             pProp->size += len;
370         }
371         else if (mode == PropModePrepend)
372         {
373             data = (pointer)xalloc(sizeInBytes * (len + pProp->size));
374             if (!data)
375                 return(BadAlloc);
376             memmove(&((char *)data)[totalSize], (char *)pProp->data, 
377                   (int)(pProp->size * sizeInBytes));
378             memmove((char *)data, (char *)value, totalSize);
379             xfree(pProp->data);
380             pProp->data = data;
381             pProp->size += len;
382         }
383     }
384     if (sendevent)
385     {
386         event.u.u.type = PropertyNotify;
387         event.u.property.window = pWin->drawable.id;
388         event.u.property.state = PropertyNewValue;
389         event.u.property.atom = pProp->propertyName;
390         event.u.property.time = currentTime.milliseconds;
391         DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
392     }
393
394     /* Addition for RFB X server */
395     if (pWin->parent == NullWindow) {
396         extern void rfbRootPropertyChange();
397         rfbRootPropertyChange(pProp);
398     }
399
400     return(Success);
401 #endif
402 }
403
404 int
405 DeleteProperty(pWin, propName)
406     WindowPtr pWin;
407     Atom propName;
408 {
409     PropertyPtr pProp, prevProp;
410     xEvent event;
411
412     if (!(pProp = wUserProps (pWin)))
413         return(Success);
414     prevProp = (PropertyPtr)NULL;
415     while (pProp)
416     {
417         if (pProp->propertyName == propName)
418             break;
419         prevProp = pProp;
420         pProp = pProp->next;
421     }
422     if (pProp) 
423     {               
424         if (prevProp == (PropertyPtr)NULL)      /* takes care of head */
425         {
426             if (!(pWin->optional->userProps = pProp->next))
427                 CheckWindowOptionalNeed (pWin);
428         }
429         else
430         {
431             prevProp->next = pProp->next;
432         }
433 #ifdef LBX
434         if (pProp->tag_id)
435             TagDeleteTag(pProp->tag_id);
436 #endif
437         event.u.u.type = PropertyNotify;
438         event.u.property.window = pWin->drawable.id;
439         event.u.property.state = PropertyDelete;
440         event.u.property.atom = pProp->propertyName;
441         event.u.property.time = currentTime.milliseconds;
442         DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
443         xfree(pProp->data);
444         xfree(pProp);
445     }
446     return(Success);
447 }
448
449 void
450 DeleteAllWindowProperties(pWin)
451     WindowPtr pWin;
452 {
453     PropertyPtr pProp, pNextProp;
454     xEvent event;
455
456     pProp = wUserProps (pWin);
457     while (pProp)
458     {
459 #ifdef LBX
460         if (pProp->tag_id)
461             TagDeleteTag(pProp->tag_id);
462 #endif
463         event.u.u.type = PropertyNotify;
464         event.u.property.window = pWin->drawable.id;
465         event.u.property.state = PropertyDelete;
466         event.u.property.atom = pProp->propertyName;
467         event.u.property.time = currentTime.milliseconds;
468         DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
469         pNextProp = pProp->next;
470         xfree(pProp->data);
471         xfree(pProp);
472         pProp = pNextProp;
473     }
474 }
475
476 static int
477 NullPropertyReply(client, propertyType, format, reply)
478     ClientPtr client;
479     ATOM propertyType;
480     int format;
481     xGetPropertyReply *reply;
482 {
483     reply->nItems = 0;
484     reply->length = 0;
485     reply->bytesAfter = 0;
486     reply->propertyType = propertyType;
487     reply->format = format;
488     WriteReplyToClient(client, sizeof(xGenericReply), reply);
489     return(client->noClientException);
490 }
491
492 /*****************
493  * GetProperty
494  *    If type Any is specified, returns the property from the specified
495  *    window regardless of its type.  If a type is specified, returns the
496  *    property only if its type equals the specified type.
497  *    If delete is True and a property is returned, the property is also
498  *    deleted from the window and a PropertyNotify event is generated on the
499  *    window.
500  *****************/
501
502 int
503 ProcGetProperty(client)
504     ClientPtr client;
505 {
506     PropertyPtr pProp, prevProp;
507     unsigned long n, len, ind;
508     WindowPtr pWin;
509     xGetPropertyReply reply;
510     REQUEST(xGetPropertyReq);
511
512     REQUEST_SIZE_MATCH(xGetPropertyReq);
513     if (stuff->delete)
514         UpdateCurrentTime();
515     pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
516                                            SecurityReadAccess);
517     if (!pWin)
518         return BadWindow;
519
520     if (!ValidAtom(stuff->property))
521     {
522         client->errorValue = stuff->property;
523         return(BadAtom);
524     }
525     if ((stuff->delete != xTrue) && (stuff->delete != xFalse))
526     {
527         client->errorValue = stuff->delete;
528         return(BadValue);
529     }
530     if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type))
531     {
532         client->errorValue = stuff->type;
533         return(BadAtom);
534     }
535
536     pProp = wUserProps (pWin);
537     prevProp = (PropertyPtr)NULL;
538     while (pProp)
539     {
540         if (pProp->propertyName == stuff->property) 
541             break;
542         prevProp = pProp;
543         pProp = pProp->next;
544     }
545
546     reply.type = X_Reply;
547     reply.sequenceNumber = client->sequence;
548     if (!pProp) 
549         return NullPropertyReply(client, None, 0, &reply);
550
551 #ifdef XCSECURITY
552     {
553         Mask access_mode = SecurityReadAccess;
554
555         if (stuff->delete)
556             access_mode |= SecurityDestroyAccess;
557         switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
558                                            access_mode))
559         {
560             case SecurityErrorOperation:
561                 client->errorValue = stuff->property;
562                 return BadAtom;;
563             case SecurityIgnoreOperation:
564                 return NullPropertyReply(client, pProp->type, pProp->format,
565                                          &reply);
566         }
567     }
568 #endif
569     /* If the request type and actual type don't match. Return the
570     property information, but not the data. */
571
572     if (((stuff->type != pProp->type) &&
573          (stuff->type != AnyPropertyType))
574        )
575     {
576         reply.bytesAfter = pProp->size;
577         reply.format = pProp->format;
578         reply.length = 0;
579         reply.nItems = 0;
580         reply.propertyType = pProp->type;
581         WriteReplyToClient(client, sizeof(xGenericReply), &reply);
582         return(Success);
583     }
584 #ifdef LBX
585     /* make sure we have the current value */                       
586     if (pProp->tag_id && pProp->owner_pid) {
587         LbxStallPropRequest(client, pProp);
588         return client->noClientException;
589     }                                              
590 #endif
591
592 /*
593  *  Return type, format, value to client
594  */
595     n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
596     ind = stuff->longOffset << 2;        
597
598    /* If longOffset is invalid such that it causes "len" to
599             be negative, it's a value error. */
600
601     if (n < ind)
602     {
603         client->errorValue = stuff->longOffset;
604         return BadValue;
605     }
606
607     len = min(n - ind, 4 * stuff->longLength);
608
609     reply.bytesAfter = n - (ind + len);
610     reply.format = pProp->format;
611     reply.length = (len + 3) >> 2;
612     reply.nItems = len / (pProp->format / 8 );
613     reply.propertyType = pProp->type;
614
615     if (stuff->delete && (reply.bytesAfter == 0))
616     { /* send the event */
617         xEvent event;
618
619         event.u.u.type = PropertyNotify;
620         event.u.property.window = pWin->drawable.id;
621         event.u.property.state = PropertyDelete;
622         event.u.property.atom = pProp->propertyName;
623         event.u.property.time = currentTime.milliseconds;
624         DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
625     }
626
627     WriteReplyToClient(client, sizeof(xGenericReply), &reply);
628     if (len)
629     {
630         switch (reply.format) {
631         case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break;
632         case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break;
633         default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
634         }
635         WriteSwappedDataToClient(client, len,
636                                  (char *)pProp->data + ind);
637     }
638
639     if (stuff->delete && (reply.bytesAfter == 0))
640     { /* delete the Property */
641 #ifdef LBX
642         if (pProp->tag_id)
643             TagDeleteTag(pProp->tag_id);
644 #endif
645         if (prevProp == (PropertyPtr)NULL) /* takes care of head */
646         {
647             if (!(pWin->optional->userProps = pProp->next))
648                 CheckWindowOptionalNeed (pWin);
649         }
650         else
651             prevProp->next = pProp->next;
652         xfree(pProp->data);
653         xfree(pProp);
654     }
655     return(client->noClientException);
656 }
657
658 int
659 ProcListProperties(client)
660     ClientPtr client;
661 {
662     Atom *pAtoms, *temppAtoms;
663     xListPropertiesReply xlpr;
664     int numProps = 0;
665     WindowPtr pWin;
666     PropertyPtr pProp;
667     REQUEST(xResourceReq);
668
669     REQUEST_SIZE_MATCH(xResourceReq);
670     pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
671                                            SecurityReadAccess);
672     if (!pWin)
673         return(BadWindow);
674
675     pProp = wUserProps (pWin);
676     while (pProp)
677     {        
678         pProp = pProp->next;
679         numProps++;
680     }
681     if (numProps)
682         if(!(pAtoms = (Atom *)ALLOCATE_LOCAL(numProps * sizeof(Atom))))
683             return(BadAlloc);
684
685     xlpr.type = X_Reply;
686     xlpr.nProperties = numProps;
687     xlpr.length = (numProps * sizeof(Atom)) >> 2;
688     xlpr.sequenceNumber = client->sequence;
689     pProp = wUserProps (pWin);
690     temppAtoms = pAtoms;
691     while (pProp)
692     {
693         *temppAtoms++ = pProp->propertyName;
694         pProp = pProp->next;
695     }
696     WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
697     if (numProps)
698     {
699         client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
700         WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
701         DEALLOCATE_LOCAL(pAtoms);
702     }
703     return(client->noClientException);
704 }
705
706 int 
707 ProcDeleteProperty(client)
708     register ClientPtr client;
709 {
710     WindowPtr pWin;
711     REQUEST(xDeletePropertyReq);
712     int result;
713               
714     REQUEST_SIZE_MATCH(xDeletePropertyReq);
715     UpdateCurrentTime();
716     pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
717                                            SecurityWriteAccess);
718     if (!pWin)
719         return(BadWindow);
720     if (!ValidAtom(stuff->property))
721     {
722         client->errorValue = stuff->property;
723         return (BadAtom);
724     }
725
726 #ifdef XCSECURITY
727     switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
728                                        SecurityDestroyAccess))
729     {
730         case SecurityErrorOperation:
731             client->errorValue = stuff->property;
732             return BadAtom;;
733         case SecurityIgnoreOperation:
734             return Success;
735     }
736 #endif
737
738     result = DeleteProperty(pWin, stuff->property);
739     if (client->noClientException != Success)
740         return(client->noClientException);
741     else
742         return(result);
743 }