550 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			550 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
/* $Xorg: lbxprop.c,v 1.4 2001/02/09 02:05:17 xorgcvs Exp $ */
 | 
						|
/*
 | 
						|
 | 
						|
Copyright 1986, 1998  The Open Group
 | 
						|
 | 
						|
Permission to use, copy, modify, distribute, and sell this software and its
 | 
						|
documentation for any purpose is hereby granted without fee, provided that
 | 
						|
the above copyright notice appear in all copies and that both that
 | 
						|
copyright notice and this permission notice appear in supporting
 | 
						|
documentation.
 | 
						|
 | 
						|
The above copyright notice and this permission notice shall be included in
 | 
						|
all copies or substantial portions of the Software.
 | 
						|
 | 
						|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
						|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
						|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 | 
						|
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 | 
						|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
						|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
						|
 | 
						|
Except as contained in this notice, the name of The Open Group shall not be
 | 
						|
used in advertising or otherwise to promote the sale, use or other dealings
 | 
						|
in this Software without prior written authorization from The Open Group.
 | 
						|
 | 
						|
*/
 | 
						|
/*
 | 
						|
 * Copyright 1993 Network Computing Devices, Inc.
 | 
						|
 *
 | 
						|
 * Permission to use, copy, modify, distribute, and sell this software and
 | 
						|
 * its documentation for any purpose is hereby granted without fee, provided
 | 
						|
 * that the above copyright notice appear in all copies and that both that
 | 
						|
 * copyright notice and this permission notice appear in supporting
 | 
						|
 * documentation, and that the name Network Computing Devices, Inc. not be
 | 
						|
 * used in advertising or publicity pertaining to distribution of this
 | 
						|
 * software without specific, written prior permission.
 | 
						|
 *
 | 
						|
 * THIS SOFTWARE IS PROVIDED `AS-IS'.  NETWORK COMPUTING DEVICES, INC.,
 | 
						|
 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
 | 
						|
 * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 | 
						|
 * PARTICULAR PURPOSE, OR NONINFRINGEMENT.  IN NO EVENT SHALL NETWORK
 | 
						|
 * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
 | 
						|
 * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
 | 
						|
 * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
 | 
						|
 * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
 | 
						|
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 *
 | 
						|
 */
 | 
						|
/* $XFree86: xc/programs/Xserver/lbx/lbxprop.c,v 1.4 2001/05/15 10:19:43 eich Exp $ */
 | 
						|
 | 
						|
/* various bits of DIX-level mangling */
 | 
						|
 | 
						|
#ifdef HAVE_DIX_CONFIG_H
 | 
						|
#include <dix-config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <sys/types.h>
 | 
						|
#include <stdio.h>
 | 
						|
#define NEED_REPLIES
 | 
						|
#define NEED_EVENTS
 | 
						|
#include <X11/X.h>
 | 
						|
#include <X11/Xproto.h>
 | 
						|
#include "misc.h"
 | 
						|
#include "os.h"
 | 
						|
#include "dixstruct.h"
 | 
						|
#include "resource.h"
 | 
						|
#include "servermd.h"
 | 
						|
#include "propertyst.h"
 | 
						|
#include "colormapst.h"
 | 
						|
#include "windowstr.h"
 | 
						|
#define _XLBX_SERVER_
 | 
						|
#include <X11/extensions/lbxstr.h>
 | 
						|
#include "lbxserve.h"
 | 
						|
#include "lbxtags.h"
 | 
						|
#include <X11/Xfuncproto.h>
 | 
						|
#ifdef XCSECURITY
 | 
						|
#define _SECURITY_SERVER
 | 
						|
#include <X11/extensions/security.h>
 | 
						|
#endif
 | 
						|
#include "swaprep.h"
 | 
						|
 | 
						|
void
 | 
						|
LbxStallPropRequest(ClientPtr   client,
 | 
						|
		    PropertyPtr pProp)
 | 
						|
{
 | 
						|
    xReq *req = (xReq *) client->requestBuffer;
 | 
						|
    register char n;
 | 
						|
 | 
						|
    LbxQueryTagData(client, pProp->owner_pid,
 | 
						|
		    pProp->tag_id, LbxTagTypeProperty);
 | 
						|
 | 
						|
    /*
 | 
						|
     * Before we reset the request, we must make sure
 | 
						|
     * it is in the client's byte order.
 | 
						|
     */
 | 
						|
 | 
						|
    if (client->swapped) {
 | 
						|
	if (req->reqType == X_ChangeProperty) {
 | 
						|
	    xChangePropertyReq *stuff = (xChangePropertyReq *) req;
 | 
						|
	    swaps(&stuff->length, n);
 | 
						|
	    swapl(&stuff->window, n);
 | 
						|
	    swapl(&stuff->property, n);
 | 
						|
	    swapl(&stuff->type, n);
 | 
						|
	    swapl(&stuff->nUnits, n);
 | 
						|
	    switch ( stuff->format ) {
 | 
						|
	    case 16:
 | 
						|
		SwapRestS(stuff);
 | 
						|
		break;
 | 
						|
	    case 32:
 | 
						|
		SwapRestL(stuff);
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
	} else if (req->reqType == X_GetProperty) {
 | 
						|
	    xGetPropertyReq *stuff = (xGetPropertyReq *) req;
 | 
						|
	    swaps(&stuff->length, n);
 | 
						|
	    swapl(&stuff->window, n);
 | 
						|
	    swapl(&stuff->property, n);
 | 
						|
	    swapl(&stuff->type, n);
 | 
						|
	    swapl(&stuff->longOffset, n);
 | 
						|
	    swapl(&stuff->longLength, n);
 | 
						|
	} else if (req->data == X_LbxChangeProperty) {
 | 
						|
	    xLbxChangePropertyReq *stuff = (xLbxChangePropertyReq *) req;
 | 
						|
	    swaps(&stuff->length, n);
 | 
						|
	    swapl(&stuff->window, n);
 | 
						|
	    swapl(&stuff->property, n);
 | 
						|
	    swapl(&stuff->type, n);
 | 
						|
	    swapl(&stuff->nUnits, n);
 | 
						|
	} else if (req->data == X_LbxGetProperty) {
 | 
						|
	    xLbxGetPropertyReq *stuff = (xLbxGetPropertyReq *) req;
 | 
						|
	    swaps(&stuff->length, n);
 | 
						|
	    swapl(&stuff->window, n);
 | 
						|
	    swapl(&stuff->property, n);
 | 
						|
	    swapl(&stuff->type, n);
 | 
						|
	    swapl(&stuff->longOffset, n);
 | 
						|
	    swapl(&stuff->longLength, n);
 | 
						|
	}
 | 
						|
    }
 | 
						|
    ResetCurrentRequest(client);
 | 
						|
    client->sequence--;
 | 
						|
    IgnoreClient(client);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
LbxChangeWindowProperty(ClientPtr   	client,
 | 
						|
			WindowPtr   	pWin,
 | 
						|
			Atom        	property,
 | 
						|
			Atom	    	type,
 | 
						|
			int         	format,
 | 
						|
			int	    	mode,
 | 
						|
			unsigned long	len,
 | 
						|
			Bool        	have_data,
 | 
						|
			pointer     	value,
 | 
						|
			Bool        	sendevent,
 | 
						|
			XID            *tag)
 | 
						|
{
 | 
						|
    PropertyPtr pProp;
 | 
						|
    xEvent      event;
 | 
						|
    int         sizeInBytes;
 | 
						|
    int         totalSize;
 | 
						|
    pointer     data;
 | 
						|
 | 
						|
    sizeInBytes = format >> 3;
 | 
						|
    totalSize = len * sizeInBytes;
 | 
						|
 | 
						|
    /* first see if property already exists */
 | 
						|
 | 
						|
    pProp = wUserProps(pWin);
 | 
						|
    while (pProp) {
 | 
						|
	if (pProp->propertyName == property)
 | 
						|
	    break;
 | 
						|
	pProp = pProp->next;
 | 
						|
    }
 | 
						|
    if (!pProp) {		/* just add to list */
 | 
						|
	if (!pWin->optional && !MakeWindowOptional(pWin))
 | 
						|
	    return (BadAlloc);
 | 
						|
	pProp = (PropertyPtr) xalloc(sizeof(PropertyRec));
 | 
						|
	if (!pProp)
 | 
						|
	    return (BadAlloc);
 | 
						|
	data = (pointer) xalloc(totalSize);
 | 
						|
	if (!data && len) {
 | 
						|
	    xfree(pProp);
 | 
						|
	    return (BadAlloc);
 | 
						|
	}
 | 
						|
	pProp->propertyName = property;
 | 
						|
	pProp->type = type;
 | 
						|
	pProp->format = format;
 | 
						|
	pProp->data = data;
 | 
						|
	if (have_data) {
 | 
						|
	    if (len)
 | 
						|
		memmove((char *) data, (char *) value, totalSize);
 | 
						|
	    pProp->tag_id = 0;
 | 
						|
	    pProp->owner_pid = 0;
 | 
						|
	} else {
 | 
						|
	    if (!TagSaveTag(LbxTagTypeProperty, totalSize,
 | 
						|
			    (pointer)pProp, &pProp->tag_id)) {
 | 
						|
		xfree(pProp);
 | 
						|
		xfree(pProp->data);
 | 
						|
		return BadAlloc;
 | 
						|
	    }
 | 
						|
	    pProp->owner_pid = LbxProxyID(client);
 | 
						|
	    TagMarkProxy(pProp->tag_id, pProp->owner_pid);
 | 
						|
	}
 | 
						|
	pProp->size = len;
 | 
						|
	pProp->next = pWin->optional->userProps;
 | 
						|
	pWin->optional->userProps = pProp;
 | 
						|
    } else {
 | 
						|
	/*
 | 
						|
	 * To append or prepend to a property the request format and type must
 | 
						|
	 * match those of the already defined property.  The existing format
 | 
						|
	 * and type are irrelevant when using the mode "PropModeReplace" since
 | 
						|
	 * they will be written over.
 | 
						|
	 */
 | 
						|
 | 
						|
	if ((format != pProp->format) && (mode != PropModeReplace))
 | 
						|
	    return (BadMatch);
 | 
						|
	if ((pProp->type != type) && (mode != PropModeReplace))
 | 
						|
	    return (BadMatch);
 | 
						|
 | 
						|
	/*
 | 
						|
	 * if its a modify instead of replace, make sure we have the current
 | 
						|
	 * value
 | 
						|
	 */
 | 
						|
	if ((mode != PropModeReplace) && pProp->tag_id && pProp->owner_pid) {
 | 
						|
	    LbxStallPropRequest(client, pProp);
 | 
						|
	    return (client->noClientException);
 | 
						|
	}
 | 
						|
	/* make sure any old tag is flushed first */
 | 
						|
	if (pProp->tag_id)
 | 
						|
	    TagDeleteTag(pProp->tag_id);
 | 
						|
	if (mode == PropModeReplace) {
 | 
						|
	    if (totalSize != pProp->size * (pProp->format >> 3)) {
 | 
						|
		data = (pointer) xrealloc(pProp->data, totalSize);
 | 
						|
		if (!data && len)
 | 
						|
		    return (BadAlloc);
 | 
						|
		pProp->data = data;
 | 
						|
	    }
 | 
						|
	    if (have_data) {
 | 
						|
		if (len)
 | 
						|
		    memmove((char *) pProp->data, (char *) value, totalSize);
 | 
						|
	    } else {
 | 
						|
		if (!TagSaveTag(LbxTagTypeProperty, totalSize,
 | 
						|
				(pointer)pProp, &pProp->tag_id)) {
 | 
						|
		    xfree(pProp);
 | 
						|
		    xfree(pProp->data);
 | 
						|
		    return BadAlloc;
 | 
						|
		}
 | 
						|
		pProp->owner_pid = LbxProxyID(client);
 | 
						|
		TagMarkProxy(pProp->tag_id, pProp->owner_pid);
 | 
						|
	    }
 | 
						|
	    pProp->size = len;
 | 
						|
	    pProp->type = type;
 | 
						|
	    pProp->format = format;
 | 
						|
	} else if (len == 0) {
 | 
						|
	    /* do nothing */
 | 
						|
	} else if (mode == PropModeAppend) {
 | 
						|
	    data = (pointer) xrealloc(pProp->data,
 | 
						|
				      sizeInBytes * (len + pProp->size));
 | 
						|
	    if (!data)
 | 
						|
		return (BadAlloc);
 | 
						|
	    pProp->data = data;
 | 
						|
	    memmove(&((char *) data)[pProp->size * sizeInBytes],
 | 
						|
		    (char *) value,
 | 
						|
		    totalSize);
 | 
						|
	    pProp->size += len;
 | 
						|
	} else if (mode == PropModePrepend) {
 | 
						|
	    data = (pointer) xalloc(sizeInBytes * (len + pProp->size));
 | 
						|
	    if (!data)
 | 
						|
		return (BadAlloc);
 | 
						|
	    memmove(&((char *) data)[totalSize], (char *) pProp->data,
 | 
						|
		    (int) (pProp->size * sizeInBytes));
 | 
						|
	    memmove((char *) data, (char *) value, totalSize);
 | 
						|
	    xfree(pProp->data);
 | 
						|
	    pProp->data = data;
 | 
						|
	    pProp->size += len;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    if (sendevent) {
 | 
						|
	event.u.u.type = PropertyNotify;
 | 
						|
	event.u.property.window = pWin->drawable.id;
 | 
						|
	event.u.property.state = PropertyNewValue;
 | 
						|
	event.u.property.atom = pProp->propertyName;
 | 
						|
	event.u.property.time = currentTime.milliseconds;
 | 
						|
	DeliverEvents(pWin, &event, 1, (WindowPtr) NULL);
 | 
						|
    }
 | 
						|
    if (pProp->tag_id)
 | 
						|
	*tag = pProp->tag_id;
 | 
						|
    return (Success);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
LbxChangeProperty(ClientPtr client)
 | 
						|
{
 | 
						|
    WindowPtr   pWin;
 | 
						|
    char        format,
 | 
						|
                mode;
 | 
						|
    unsigned long len;
 | 
						|
    int         err;
 | 
						|
    int         n;
 | 
						|
    XID         newtag;
 | 
						|
    xLbxChangePropertyReply rep;
 | 
						|
    REQUEST(xLbxChangePropertyReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xLbxChangePropertyReq);
 | 
						|
    UpdateCurrentTime();
 | 
						|
    format = stuff->format;
 | 
						|
    mode = stuff->mode;
 | 
						|
    if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
 | 
						|
	    (mode != PropModePrepend)) {
 | 
						|
	client->errorValue = mode;
 | 
						|
	return BadValue;
 | 
						|
    }
 | 
						|
    if ((format != 8) && (format != 16) && (format != 32)) {
 | 
						|
	client->errorValue = format;
 | 
						|
	return BadValue;
 | 
						|
    }
 | 
						|
    len = stuff->nUnits;
 | 
						|
    if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2))
 | 
						|
	return BadLength;
 | 
						|
 | 
						|
    pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
 | 
						|
					    SecurityWriteAccess);
 | 
						|
    if (!pWin)
 | 
						|
	return (BadWindow);
 | 
						|
    if (!ValidAtom(stuff->property)) {
 | 
						|
	client->errorValue = stuff->property;
 | 
						|
	return (BadAtom);
 | 
						|
    }
 | 
						|
    if (!ValidAtom(stuff->type)) {
 | 
						|
	client->errorValue = stuff->type;
 | 
						|
	return (BadAtom);
 | 
						|
    }
 | 
						|
 | 
						|
    rep.type = X_Reply;
 | 
						|
    rep.sequenceNumber = client->sequence;
 | 
						|
    rep.length = 0;
 | 
						|
    rep.pad = rep.pad0 = rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0;
 | 
						|
    if (client->swapped) {
 | 
						|
	swaps(&rep.sequenceNumber, n);
 | 
						|
    }
 | 
						|
 | 
						|
#ifdef XCSECURITY
 | 
						|
    switch (SecurityCheckPropertyAccess(client, pWin, stuff->property,
 | 
						|
					SecurityWriteAccess))
 | 
						|
    {
 | 
						|
	case SecurityErrorOperation:
 | 
						|
	    client->errorValue = stuff->property;
 | 
						|
	    return BadAtom;
 | 
						|
	case SecurityIgnoreOperation:
 | 
						|
	    rep.tag = 0;
 | 
						|
	    WriteToClient(client, sizeof(xLbxChangePropertyReply), (char *)&rep);
 | 
						|
	    return client->noClientException;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    err = LbxChangeWindowProperty(client, pWin, stuff->property, stuff->type,
 | 
						|
		   (int) format, (int) mode, len, FALSE, (pointer) &stuff[1],
 | 
						|
				  TRUE, &newtag);
 | 
						|
    if (err)
 | 
						|
	return err;
 | 
						|
 | 
						|
    rep.tag = newtag;
 | 
						|
 | 
						|
    if (client->swapped) {
 | 
						|
	swapl(&rep.tag, n);
 | 
						|
    }
 | 
						|
    WriteToClient(client, sizeof(xLbxChangePropertyReply), (char *)&rep);
 | 
						|
 | 
						|
    return client->noClientException;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
LbxWriteGetpropReply(ClientPtr   	   client,
 | 
						|
		     xLbxGetPropertyReply *rep)
 | 
						|
{
 | 
						|
    int         n;
 | 
						|
 | 
						|
    if (client->swapped) {
 | 
						|
	swaps(&rep->sequenceNumber, n);
 | 
						|
	swapl(&rep->length, n);
 | 
						|
	swapl(&rep->propertyType, n);
 | 
						|
	swapl(&rep->bytesAfter, n);
 | 
						|
	swapl(&rep->nItems, n);
 | 
						|
	swapl(&rep->tag, n);
 | 
						|
    }
 | 
						|
    WriteToClient(client, sizeof(xLbxGetPropertyReply), (char *)rep);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
LbxGetProperty(ClientPtr client)
 | 
						|
{
 | 
						|
    PropertyPtr pProp,
 | 
						|
                prevProp;
 | 
						|
    unsigned long n,
 | 
						|
                len,
 | 
						|
                ind;
 | 
						|
    WindowPtr   pWin;
 | 
						|
    xLbxGetPropertyReply reply;
 | 
						|
    Bool        send_data = FALSE;
 | 
						|
 | 
						|
    REQUEST(xLbxGetPropertyReq);
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xLbxGetPropertyReq);
 | 
						|
 | 
						|
    reply.pad1 = 0;
 | 
						|
    reply.pad2 = 0;
 | 
						|
 | 
						|
    if (stuff->delete)
 | 
						|
	UpdateCurrentTime();
 | 
						|
    pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
 | 
						|
					    SecurityReadAccess);
 | 
						|
    if (!pWin)
 | 
						|
	return (BadWindow);
 | 
						|
 | 
						|
    if (!ValidAtom(stuff->property)) {
 | 
						|
	client->errorValue = stuff->property;
 | 
						|
	return (BadAtom);
 | 
						|
    }
 | 
						|
    if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) {
 | 
						|
	client->errorValue = stuff->delete;
 | 
						|
	return (BadValue);
 | 
						|
    }
 | 
						|
    if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type))
 | 
						|
    {
 | 
						|
	client->errorValue = stuff->type;
 | 
						|
	return(BadAtom);
 | 
						|
    }
 | 
						|
    pProp = wUserProps(pWin);
 | 
						|
    prevProp = (PropertyPtr) NULL;
 | 
						|
    while (pProp) {
 | 
						|
	if (pProp->propertyName == stuff->property)
 | 
						|
	    break;
 | 
						|
	prevProp = pProp;
 | 
						|
	pProp = pProp->next;
 | 
						|
    }
 | 
						|
    reply.type = X_Reply;
 | 
						|
    reply.sequenceNumber = client->sequence;
 | 
						|
    if (!pProp) {
 | 
						|
	reply.nItems = 0;
 | 
						|
	reply.length = 0;
 | 
						|
	reply.bytesAfter = 0;
 | 
						|
	reply.propertyType = None;
 | 
						|
	reply.format = 0;
 | 
						|
	reply.tag = 0;
 | 
						|
	LbxWriteGetpropReply(client, &reply);
 | 
						|
	return client->noClientException;
 | 
						|
    }
 | 
						|
    /*
 | 
						|
     * If the request type and actual type don't match. Return the
 | 
						|
     * property information, but not the data.
 | 
						|
     */
 | 
						|
    if ((stuff->type != pProp->type) &&
 | 
						|
	(stuff->type != AnyPropertyType)) {
 | 
						|
	reply.bytesAfter = pProp->size;
 | 
						|
	reply.format = pProp->format;
 | 
						|
	reply.length = 0;
 | 
						|
	reply.nItems = 0;
 | 
						|
	reply.propertyType = pProp->type;
 | 
						|
	reply.tag = 0;
 | 
						|
	LbxWriteGetpropReply(client, &reply);
 | 
						|
	return client->noClientException;
 | 
						|
    }
 | 
						|
    /*
 | 
						|
     * Return type, format, value to client
 | 
						|
     */
 | 
						|
    n = (pProp->format >> 3) * pProp->size;	/* size (bytes) of prop */
 | 
						|
    ind = stuff->longOffset << 2;
 | 
						|
 | 
						|
    /*
 | 
						|
     * If longOffset is invalid such that it causes "len" to be
 | 
						|
     * negative, it's a value error.
 | 
						|
     */
 | 
						|
 | 
						|
    if (n < ind) {
 | 
						|
	client->errorValue = stuff->longOffset;
 | 
						|
	return BadValue;
 | 
						|
    }
 | 
						|
 | 
						|
    /* make sure we have the current value */
 | 
						|
    if (pProp->tag_id && pProp->owner_pid) {
 | 
						|
	LbxStallPropRequest(client, pProp);
 | 
						|
	return client->noClientException;
 | 
						|
    }
 | 
						|
 | 
						|
    len = min(n - ind, stuff->longLength << 2);
 | 
						|
 | 
						|
    reply.bytesAfter = n - (ind + len);
 | 
						|
    reply.format = pProp->format;
 | 
						|
    reply.propertyType = pProp->type;
 | 
						|
 | 
						|
    if (!pProp->tag_id) {
 | 
						|
	if (n && (!stuff->delete || reply.bytesAfter)) {
 | 
						|
	    TagSaveTag(LbxTagTypeProperty, n, (pointer)pProp, &pProp->tag_id);
 | 
						|
	    pProp->owner_pid = 0;
 | 
						|
	}
 | 
						|
	send_data = TRUE;
 | 
						|
    } else
 | 
						|
	send_data = !TagProxyMarked(pProp->tag_id, LbxProxyID(client));
 | 
						|
    if (pProp->tag_id && send_data)
 | 
						|
	TagMarkProxy(pProp->tag_id, LbxProxyID(client));
 | 
						|
    reply.tag = pProp->tag_id;
 | 
						|
 | 
						|
    if (!send_data)
 | 
						|
	len = 0;
 | 
						|
    else if (reply.tag) {
 | 
						|
	len = n;
 | 
						|
	ind = 0;
 | 
						|
    }
 | 
						|
    reply.nItems = len / (pProp->format >> 3);
 | 
						|
    reply.length = (len + 3) >> 2;
 | 
						|
 | 
						|
    if (stuff->delete && (reply.bytesAfter == 0)) {
 | 
						|
	xEvent      event;
 | 
						|
 | 
						|
	event.u.u.type = PropertyNotify;
 | 
						|
	event.u.property.window = pWin->drawable.id;
 | 
						|
	event.u.property.state = PropertyDelete;
 | 
						|
	event.u.property.atom = pProp->propertyName;
 | 
						|
	event.u.property.time = currentTime.milliseconds;
 | 
						|
	DeliverEvents(pWin, &event, 1, (WindowPtr) NULL);
 | 
						|
    }
 | 
						|
    LbxWriteGetpropReply(client, &reply);
 | 
						|
    if (len) {
 | 
						|
	switch (reply.format) {
 | 
						|
	case 32:
 | 
						|
	    client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write;
 | 
						|
	    break;
 | 
						|
	case 16:
 | 
						|
	    client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write;
 | 
						|
	    break;
 | 
						|
	default:
 | 
						|
	    client->pSwapReplyFunc = (ReplySwapPtr) WriteToClient;
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
	WriteSwappedDataToClient(client, len,
 | 
						|
				 (char *) pProp->data + ind);
 | 
						|
    }
 | 
						|
    if (stuff->delete && (reply.bytesAfter == 0)) {
 | 
						|
	if (pProp->tag_id)
 | 
						|
	    TagDeleteTag(pProp->tag_id);
 | 
						|
	if (prevProp == (PropertyPtr) NULL) {
 | 
						|
	    if (!(pWin->optional->userProps = pProp->next))
 | 
						|
		CheckWindowOptionalNeed(pWin);
 | 
						|
	} else
 | 
						|
	    prevProp->next = pProp->next;
 | 
						|
	xfree(pProp->data);
 | 
						|
	xfree(pProp);
 | 
						|
    }
 | 
						|
    return client->noClientException;
 | 
						|
}
 |