From 38e661c7d82fa0b34fbe9b3f3261295787bb6427 Mon Sep 17 00:00:00 2001 From: marha Date: Wed, 11 Jan 2012 08:18:52 +0100 Subject: mesa pixman xserver git update 11 jan 2012 --- xorg-server/dix/dispatch.c | 26 +- xorg-server/dix/dixutils.c | 17 +- xorg-server/dix/enterleave.c | 9 +- xorg-server/dix/eventconvert.c | 4 + xorg-server/dix/getevents.c | 2 +- xorg-server/dix/property.c | 1288 ++++++++++++++++++++-------------------- 6 files changed, 685 insertions(+), 661 deletions(-) (limited to 'xorg-server/dix') diff --git a/xorg-server/dix/dispatch.c b/xorg-server/dix/dispatch.c index 048dff652..b91b41f4a 100644 --- a/xorg-server/dix/dispatch.c +++ b/xorg-server/dix/dispatch.c @@ -425,9 +425,11 @@ Dispatch(void) client->minorOp = ext->MinorOpcode(client); } #ifdef XSERVER_DTRACE - XSERVER_REQUEST_START(LookupMajorName(client->majorOp), client->majorOp, - ((xReq *)client->requestBuffer)->length, - client->index, client->requestBuffer); + if (XSERVER_REQUEST_START_ENABLED()) + XSERVER_REQUEST_START(LookupMajorName(client->majorOp), + client->majorOp, + ((xReq *)client->requestBuffer)->length, + client->index, client->requestBuffer); #endif if (result > (maxBigRequestSize << 2)) result = BadLength; @@ -438,8 +440,10 @@ Dispatch(void) XaceHookAuditEnd(client, result); } #ifdef XSERVER_DTRACE - XSERVER_REQUEST_DONE(LookupMajorName(client->majorOp), client->majorOp, - client->sequence, client->index, result); + if (XSERVER_REQUEST_DONE_ENABLED()) + XSERVER_REQUEST_DONE(LookupMajorName(client->majorOp), + client->majorOp, client->sequence, + client->index, result); #endif if (client->noClientException != Success) @@ -3578,12 +3582,14 @@ ProcInitialConnection(ClientPtr client) REQUEST(xReq); xConnClientPrefix *prefix; int whichbyte = 1; + char order; prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); - if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B')) + order = prefix->byteOrder; + if (order != 'l' && order != 'B' && order != 'r' && order != 'R') return client->noClientException = -1; - if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) || - (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) + if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) || + (!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) { client->swapped = TRUE; SwapConnClientPrefix(prefix); @@ -3595,6 +3601,10 @@ ProcInitialConnection(ClientPtr client) { swaps(&stuff->length); } + if (order == 'r' || order == 'R') + { + client->local = FALSE; + } ResetCurrentRequest(client); return Success; } diff --git a/xorg-server/dix/dixutils.c b/xorg-server/dix/dixutils.c index 00bbde67c..da26dc144 100644 --- a/xorg-server/dix/dixutils.c +++ b/xorg-server/dix/dixutils.c @@ -202,13 +202,12 @@ dixLookupDrawable(DrawablePtr *pDraw, XID id, ClientPtr client, int rc; *pDraw = NULL; - client->errorValue = id; - - if (id == INVALID) - return BadDrawable; rc = dixLookupResourceByClass((pointer *)&pTmp, id, RC_DRAWABLE, client, access); + if (rc != Success) + client->errorValue = id; + if (rc == BadValue) return BadDrawable; if (rc != Success) @@ -225,7 +224,15 @@ dixLookupWindow(WindowPtr *pWin, XID id, ClientPtr client, Mask access) { int rc; rc = dixLookupDrawable((DrawablePtr*)pWin, id, client, M_WINDOW, access); - return (rc == BadDrawable) ? BadWindow : rc; + /* dixLookupDrawable returns BadMatch iff id is a valid Drawable + but is not a Window. Users of dixLookupWindow expect a BadWindow + error in this case; they don't care that it's a valid non-Window XID */ + if (rc == BadMatch) + rc = BadWindow; + /* Similarly, users of dixLookupWindow don't want BadDrawable. */ + if (rc == BadDrawable) + rc = BadWindow; + return rc; } int diff --git a/xorg-server/dix/enterleave.c b/xorg-server/dix/enterleave.c index a39e64001..89a82ab99 100644 --- a/xorg-server/dix/enterleave.c +++ b/xorg-server/dix/enterleave.c @@ -1292,14 +1292,17 @@ DeviceFocusEvents(DeviceIntPtr dev, NotifyPointer); DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyNonlinear, from); /* next call catches the root too, if the screen changed */ - DeviceFocusOutEvents(dev, from->parent, NullWindow, mode, + DeviceFocusOutEvents(dev, from, NullWindow, mode, NotifyNonlinearVirtual); } /* Notify all the roots */ for (i = 0; i < nscreens; i++) DeviceFocusEvent(dev, XI_FocusIn, mode, in, screenInfo.screens[i]->root); if (to == PointerRootWin) + { DeviceFocusInEvents(dev, GetCurrentRootWindow(dev), sprite->win, mode, NotifyPointer); + DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyPointer, sprite->win); + } } else { @@ -1321,7 +1324,7 @@ DeviceFocusEvents(DeviceIntPtr dev, if (IsParent(to, from)) { DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyAncestor, from); - DeviceFocusOutEvents(dev, from->parent, to, mode, + DeviceFocusOutEvents(dev, from, to, mode, NotifyVirtual); DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyInferior, to); if ((IsParent(to, sprite->win)) && @@ -1353,7 +1356,7 @@ DeviceFocusEvents(DeviceIntPtr dev, NotifyPointer); DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyNonlinear, from); if (from->parent != NullWindow) - DeviceFocusOutEvents(dev, from->parent, common, mode, + DeviceFocusOutEvents(dev, from, common, mode, NotifyNonlinearVirtual); if (to->parent != NullWindow) DeviceFocusInEvents(dev, common, to, mode, NotifyNonlinearVirtual); diff --git a/xorg-server/dix/eventconvert.c b/xorg-server/dix/eventconvert.c index 017c87190..60dc22fff 100644 --- a/xorg-server/dix/eventconvert.c +++ b/xorg-server/dix/eventconvert.c @@ -691,6 +691,10 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi) else xde->flags = ev->flags; + if (IsTouchEvent((InternalEvent*)ev) && + ev->flags & TOUCH_POINTER_EMULATED) + xde->flags |= XITouchEmulatingPointer; + if (ev->key_repeat) xde->flags |= XIKeyRepeat; diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c index 3b40a5bb7..d0014e617 100644 --- a/xorg-server/dix/getevents.c +++ b/xorg-server/dix/getevents.c @@ -1328,7 +1328,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type, storeLastValuators(pDev, &mask, 0, 1, devx, devy); /* Update the MD's co-ordinates, which are always in desktop space. */ - if (!IsMaster(pDev) || !IsFloating(pDev)) { + if (!IsMaster(pDev) && !IsFloating(pDev)) { DeviceIntPtr master = GetMaster(pDev, MASTER_POINTER); master->last.valuators[0] = screenx; master->last.valuators[1] = screeny; diff --git a/xorg-server/dix/property.c b/xorg-server/dix/property.c index 53b9821a9..d933d5cec 100644 --- a/xorg-server/dix/property.c +++ b/xorg-server/dix/property.c @@ -1,644 +1,644 @@ -/*********************************************************** - -Copyright 1987, 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 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -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 of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include -#include -#include "windowstr.h" -#include "propertyst.h" -#include "dixstruct.h" -#include "dispatch.h" -#include "swaprep.h" -#include "xace.h" - -/***************************************************************** - * Property Stuff - * - * dixLookupProperty, dixChangeProperty, DeleteProperty - * - * Properties belong to windows. The list of properties should not be - * traversed directly. Instead, use the three functions listed above. - * - *****************************************************************/ - -#ifdef notdef -static void -PrintPropertys(WindowPtr pWin) -{ - PropertyPtr pProp; - int j; - - pProp = pWin->userProps; - while (pProp) - { - ErrorF("[dix] %x %x\n", pProp->propertyName, pProp->type); - ErrorF("[dix] property format: %d\n", pProp->format); - ErrorF("[dix] property data: \n"); - for (j=0; j<(pProp->format/8)*pProp->size; j++) - ErrorF("[dix] %c\n", pProp->data[j]); - pProp = pProp->next; - } -} -#endif - -int -dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName, - ClientPtr client, Mask access_mode) -{ - PropertyPtr pProp; - int rc = BadMatch; - client->errorValue = propertyName; - - for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) - if (pProp->propertyName == propertyName) - break; - - if (pProp) - rc = XaceHookPropertyAccess(client, pWin, &pProp, access_mode); - *result = pProp; - return rc; -} - -static void -deliverPropertyNotifyEvent(WindowPtr pWin, int state, Atom atom) -{ - xEvent event; - - memset(&event, 0, sizeof(xEvent)); - event.u.u.type = PropertyNotify; - event.u.property.window = pWin->drawable.id; - event.u.property.state = state; - event.u.property.atom = atom; - event.u.property.time = currentTime.milliseconds; - DeliverEvents(pWin, &event, 1, (WindowPtr)NULL); -} - -int -ProcRotateProperties(ClientPtr client) -{ - int i, j, delta, rc; - REQUEST(xRotatePropertiesReq); - WindowPtr pWin; - Atom * atoms; - PropertyPtr * props; /* array of pointer */ - PropertyPtr pProp, saved; - - REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2); - UpdateCurrentTime(); - rc = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); - if (rc != Success || stuff->nAtoms <= 0) - return rc; - - atoms = (Atom *) & stuff[1]; - props = malloc(stuff->nAtoms * sizeof(PropertyPtr)); - saved = malloc(stuff->nAtoms * sizeof(PropertyRec)); - if (!props || !saved) { - rc = BadAlloc; - goto out; - } - - for (i = 0; i < stuff->nAtoms; i++) - { - if (!ValidAtom(atoms[i])) { - rc = BadAtom; - client->errorValue = atoms[i]; - goto out; - } - for (j = i + 1; j < stuff->nAtoms; j++) - if (atoms[j] == atoms[i]) - { - rc = BadMatch; - goto out; - } - - rc = dixLookupProperty(&pProp, pWin, atoms[i], client, - DixReadAccess|DixWriteAccess); - if (rc != Success) - goto out; - - props[i] = pProp; - saved[i] = *pProp; - } - delta = stuff->nPositions; - - /* If the rotation is a complete 360 degrees, then moving the properties - around and generating PropertyNotify events should be skipped. */ - - if (abs(delta) % stuff->nAtoms) - { - while (delta < 0) /* faster if abs value is small */ - delta += stuff->nAtoms; - for (i = 0; i < stuff->nAtoms; i++) - { - j = (i + delta) % stuff->nAtoms; - deliverPropertyNotifyEvent(pWin, PropertyNewValue, atoms[i]); - - /* Preserve name and devPrivates */ - props[j]->type = saved[i].type; - props[j]->format = saved[i].format; - props[j]->size = saved[i].size; - props[j]->data = saved[i].data; - } - } -out: - free(saved); - free(props); - return rc; -} - -int -ProcChangeProperty(ClientPtr client) -{ - WindowPtr pWin; - char format, mode; - unsigned long len; - int sizeInBytes, totalSize, err; - REQUEST(xChangePropertyReq); - - REQUEST_AT_LEAST_SIZE(xChangePropertyReq); - 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 > bytes_to_int32(0xffffffff - sizeof(xChangePropertyReq))) - return BadLength; - sizeInBytes = format>>3; - totalSize = len * sizeInBytes; - REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize); - - err = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); - if (err != Success) - return err; - if (!ValidAtom(stuff->property)) - { - client->errorValue = stuff->property; - return BadAtom; - } - if (!ValidAtom(stuff->type)) - { - client->errorValue = stuff->type; - return BadAtom; - } - - err = dixChangeWindowProperty(client, pWin, stuff->property, stuff->type, - (int)format, (int)mode, len, &stuff[1], - TRUE); - if (err != Success) - return err; - else - return Success; -} - -int -dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, - Atom type, int format, int mode, unsigned long len, - pointer value, Bool sendevent) -{ - PropertyPtr pProp; - PropertyRec savedProp; - int sizeInBytes, totalSize, rc; - unsigned char *data; - Mask access_mode; - - sizeInBytes = format>>3; - totalSize = len * sizeInBytes; - access_mode = (mode == PropModeReplace) ? DixWriteAccess : DixBlendAccess; - - /* first see if property already exists */ - rc = dixLookupProperty(&pProp, pWin, property, pClient, access_mode); - - if (rc == BadMatch) /* just add to list */ - { - if (!pWin->optional && !MakeWindowOptional (pWin)) - return BadAlloc; - pProp = dixAllocateObjectWithPrivates(PropertyRec, PRIVATE_PROPERTY); - if (!pProp) - return BadAlloc; - data = malloc(totalSize); - if (!data && len) - { - dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); - return BadAlloc; - } - memcpy(data, value, totalSize); - pProp->propertyName = property; - pProp->type = type; - pProp->format = format; - pProp->data = data; - pProp->size = len; - rc = XaceHookPropertyAccess(pClient, pWin, &pProp, - DixCreateAccess|DixWriteAccess); - if (rc != Success) { - free(data); - dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); - pClient->errorValue = property; - return rc; - } - pProp->next = pWin->optional->userProps; - pWin->optional->userProps = pProp; - } - else if (rc == Success) - { - /* 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; - - /* save the old values for later */ - savedProp = *pProp; - - if (mode == PropModeReplace) - { - data = malloc(totalSize); - if (!data && len) - return BadAlloc; - memcpy(data, value, totalSize); - pProp->data = data; - pProp->size = len; - pProp->type = type; - pProp->format = format; - } - else if (len == 0) - { - /* do nothing */ - } - else if (mode == PropModeAppend) - { - data = malloc((pProp->size + len) * sizeInBytes); - if (!data) - return BadAlloc; - memcpy(data, pProp->data, pProp->size * sizeInBytes); - memcpy(data + pProp->size * sizeInBytes, value, totalSize); - pProp->data = data; - pProp->size += len; - } - else if (mode == PropModePrepend) - { - data = malloc(sizeInBytes * (len + pProp->size)); - if (!data) - return BadAlloc; - memcpy(data + totalSize, pProp->data, pProp->size * sizeInBytes); - memcpy(data, value, totalSize); - pProp->data = data; - pProp->size += len; - } - - /* Allow security modules to check the new content */ - access_mode |= DixPostAccess; - rc = XaceHookPropertyAccess(pClient, pWin, &pProp, access_mode); - if (rc == Success) - { - if (savedProp.data != pProp->data) - free(savedProp.data); - } - else - { - if (savedProp.data != pProp->data) - free(pProp->data); - *pProp = savedProp; - return rc; - } - } - else - return rc; - - if (sendevent) - deliverPropertyNotifyEvent(pWin, PropertyNewValue, pProp->propertyName); - - return Success; -} - -int -ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format, - int mode, unsigned long len, pointer value, - Bool sendevent) -{ - return dixChangeWindowProperty(serverClient, pWin, property, type, format, - mode, len, value, sendevent); -} - -int -DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName) -{ - PropertyPtr pProp, prevProp; - int rc; - - rc = dixLookupProperty(&pProp, pWin, propName, client, DixDestroyAccess); - if (rc == BadMatch) - return Success; /* Succeed if property does not exist */ - - if (rc == Success) { - if (pWin->optional->userProps == pProp) { - /* Takes care of head */ - if (!(pWin->optional->userProps = pProp->next)) - CheckWindowOptionalNeed (pWin); - } else { - /* Need to traverse to find the previous element */ - prevProp = pWin->optional->userProps; - while (prevProp->next != pProp) - prevProp = prevProp->next; - prevProp->next = pProp->next; - } - - deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); - free(pProp->data); - dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); - } - return rc; -} - -void -DeleteAllWindowProperties(WindowPtr pWin) -{ - PropertyPtr pProp, pNextProp; - - pProp = wUserProps (pWin); - while (pProp) - { - deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); - pNextProp = pProp->next; - free(pProp->data); - dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); - pProp = pNextProp; - } - - if (pWin->optional) - pWin->optional->userProps = NULL; -} - -static int -NullPropertyReply( - ClientPtr client, - ATOM propertyType, - int format, - xGetPropertyReply *reply) -{ - reply->nItems = 0; - reply->length = 0; - reply->bytesAfter = 0; - reply->propertyType = propertyType; - reply->format = format; - WriteReplyToClient(client, sizeof(xGenericReply), reply); - return Success; -} - -/***************** - * GetProperty - * If type Any is specified, returns the property from the specified - * window regardless of its type. If a type is specified, returns the - * property only if its type equals the specified type. - * If delete is True and a property is returned, the property is also - * deleted from the window and a PropertyNotify event is generated on the - * window. - *****************/ - -int -ProcGetProperty(ClientPtr client) -{ - PropertyPtr pProp, prevProp; - unsigned long n, len, ind; - int rc; - WindowPtr pWin; - xGetPropertyReply reply; - Mask win_mode = DixGetPropAccess, prop_mode = DixReadAccess; - REQUEST(xGetPropertyReq); - - REQUEST_SIZE_MATCH(xGetPropertyReq); - if (stuff->delete) { - UpdateCurrentTime(); - win_mode |= DixSetPropAccess; - prop_mode |= DixDestroyAccess; - } - rc = dixLookupWindow(&pWin, stuff->window, client, win_mode); - if (rc != Success) - return (rc == BadMatch) ? BadWindow : rc; - - 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; - } - - memset(&reply, 0, sizeof(xGetPropertyReply)); - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - - rc = dixLookupProperty(&pProp, pWin, stuff->property, client, prop_mode); - if (rc == BadMatch) - return NullPropertyReply(client, None, 0, &reply); - else if (rc != Success) - return rc; - - /* 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; - WriteReplyToClient(client, sizeof(xGenericReply), &reply); - return Success; - } - -/* - * Return type, format, value to client - */ - n = (pProp->format/8) * 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; - } - - len = min(n - ind, 4 * stuff->longLength); - - reply.bytesAfter = n - (ind + len); - reply.format = pProp->format; - reply.length = bytes_to_int32(len); - reply.nItems = len / (pProp->format / 8 ); - reply.propertyType = pProp->type; - - if (stuff->delete && (reply.bytesAfter == 0)) - deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); - - WriteReplyToClient(client, sizeof(xGenericReply), &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)) { - /* Delete the Property */ - if (pWin->optional->userProps == pProp) { - /* Takes care of head */ - if (!(pWin->optional->userProps = pProp->next)) - CheckWindowOptionalNeed (pWin); - } else { - /* Need to traverse to find the previous element */ - prevProp = pWin->optional->userProps; - while (prevProp->next != pProp) - prevProp = prevProp->next; - prevProp->next = pProp->next; - } - - free(pProp->data); - dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); - } - return Success; -} - -int -ProcListProperties(ClientPtr client) -{ - Atom *pAtoms = NULL, *temppAtoms; - xListPropertiesReply xlpr; - int rc, numProps = 0; - WindowPtr pWin; - PropertyPtr pProp, realProp; - REQUEST(xResourceReq); - - REQUEST_SIZE_MATCH(xResourceReq); - rc = dixLookupWindow(&pWin, stuff->id, client, DixListPropAccess); - if (rc != Success) - return rc; - - for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) - numProps++; - - if (numProps && !(pAtoms = malloc(numProps * sizeof(Atom)))) - return BadAlloc; - - numProps = 0; - temppAtoms = pAtoms; - for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) { - realProp = pProp; - rc = XaceHookPropertyAccess(client, pWin, &realProp, DixGetAttrAccess); - if (rc == Success && realProp == pProp) { - *temppAtoms++ = pProp->propertyName; - numProps++; - } - } - - xlpr.type = X_Reply; - xlpr.nProperties = numProps; - xlpr.length = bytes_to_int32(numProps * sizeof(Atom)); - xlpr.sequenceNumber = client->sequence; - WriteReplyToClient(client, sizeof(xGenericReply), &xlpr); - if (numProps) - { - client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write; - WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms); - } - free(pAtoms); - return Success; -} - -int -ProcDeleteProperty(ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xDeletePropertyReq); - int result; - - REQUEST_SIZE_MATCH(xDeletePropertyReq); - UpdateCurrentTime(); - result = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); - if (result != Success) - return result; - if (!ValidAtom(stuff->property)) - { - client->errorValue = stuff->property; - return BadAtom; - } - - return DeleteProperty(client, pWin, stuff->property); -} +/*********************************************************** + +Copyright 1987, 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 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +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 of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include +#include "windowstr.h" +#include "propertyst.h" +#include "dixstruct.h" +#include "dispatch.h" +#include "swaprep.h" +#include "xace.h" + +/***************************************************************** + * Property Stuff + * + * dixLookupProperty, dixChangeProperty, DeleteProperty + * + * Properties belong to windows. The list of properties should not be + * traversed directly. Instead, use the three functions listed above. + * + *****************************************************************/ + +#ifdef notdef +static void +PrintPropertys(WindowPtr pWin) +{ + PropertyPtr pProp; + int j; + + pProp = pWin->userProps; + while (pProp) + { + ErrorF("[dix] %x %x\n", pProp->propertyName, pProp->type); + ErrorF("[dix] property format: %d\n", pProp->format); + ErrorF("[dix] property data: \n"); + for (j=0; j<(pProp->format/8)*pProp->size; j++) + ErrorF("[dix] %c\n", pProp->data[j]); + pProp = pProp->next; + } +} +#endif + +int +dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName, + ClientPtr client, Mask access_mode) +{ + PropertyPtr pProp; + int rc = BadMatch; + client->errorValue = propertyName; + + for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) + if (pProp->propertyName == propertyName) + break; + + if (pProp) + rc = XaceHookPropertyAccess(client, pWin, &pProp, access_mode); + *result = pProp; + return rc; +} + +static void +deliverPropertyNotifyEvent(WindowPtr pWin, int state, Atom atom) +{ + xEvent event; + + memset(&event, 0, sizeof(xEvent)); + event.u.u.type = PropertyNotify; + event.u.property.window = pWin->drawable.id; + event.u.property.state = state; + event.u.property.atom = atom; + event.u.property.time = currentTime.milliseconds; + DeliverEvents(pWin, &event, 1, (WindowPtr)NULL); +} + +int +ProcRotateProperties(ClientPtr client) +{ + int i, j, delta, rc; + REQUEST(xRotatePropertiesReq); + WindowPtr pWin; + Atom * atoms; + PropertyPtr * props; /* array of pointer */ + PropertyPtr pProp, saved; + + REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2); + UpdateCurrentTime(); + rc = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); + if (rc != Success || stuff->nAtoms <= 0) + return rc; + + atoms = (Atom *) & stuff[1]; + props = malloc(stuff->nAtoms * sizeof(PropertyPtr)); + saved = malloc(stuff->nAtoms * sizeof(PropertyRec)); + if (!props || !saved) { + rc = BadAlloc; + goto out; + } + + for (i = 0; i < stuff->nAtoms; i++) + { + if (!ValidAtom(atoms[i])) { + rc = BadAtom; + client->errorValue = atoms[i]; + goto out; + } + for (j = i + 1; j < stuff->nAtoms; j++) + if (atoms[j] == atoms[i]) + { + rc = BadMatch; + goto out; + } + + rc = dixLookupProperty(&pProp, pWin, atoms[i], client, + DixReadAccess|DixWriteAccess); + if (rc != Success) + goto out; + + props[i] = pProp; + saved[i] = *pProp; + } + delta = stuff->nPositions; + + /* If the rotation is a complete 360 degrees, then moving the properties + around and generating PropertyNotify events should be skipped. */ + + if (abs(delta) % stuff->nAtoms) + { + while (delta < 0) /* faster if abs value is small */ + delta += stuff->nAtoms; + for (i = 0; i < stuff->nAtoms; i++) + { + j = (i + delta) % stuff->nAtoms; + deliverPropertyNotifyEvent(pWin, PropertyNewValue, atoms[i]); + + /* Preserve name and devPrivates */ + props[j]->type = saved[i].type; + props[j]->format = saved[i].format; + props[j]->size = saved[i].size; + props[j]->data = saved[i].data; + } + } +out: + free(saved); + free(props); + return rc; +} + +int +ProcChangeProperty(ClientPtr client) +{ + WindowPtr pWin; + char format, mode; + unsigned long len; + int sizeInBytes, totalSize, err; + REQUEST(xChangePropertyReq); + + REQUEST_AT_LEAST_SIZE(xChangePropertyReq); + 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 > bytes_to_int32(0xffffffff - sizeof(xChangePropertyReq))) + return BadLength; + sizeInBytes = format>>3; + totalSize = len * sizeInBytes; + REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize); + + err = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); + if (err != Success) + return err; + if (!ValidAtom(stuff->property)) + { + client->errorValue = stuff->property; + return BadAtom; + } + if (!ValidAtom(stuff->type)) + { + client->errorValue = stuff->type; + return BadAtom; + } + + err = dixChangeWindowProperty(client, pWin, stuff->property, stuff->type, + (int)format, (int)mode, len, &stuff[1], + TRUE); + if (err != Success) + return err; + else + return Success; +} + +int +dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, + Atom type, int format, int mode, unsigned long len, + pointer value, Bool sendevent) +{ + PropertyPtr pProp; + PropertyRec savedProp; + int sizeInBytes, totalSize, rc; + unsigned char *data; + Mask access_mode; + + sizeInBytes = format>>3; + totalSize = len * sizeInBytes; + access_mode = (mode == PropModeReplace) ? DixWriteAccess : DixBlendAccess; + + /* first see if property already exists */ + rc = dixLookupProperty(&pProp, pWin, property, pClient, access_mode); + + if (rc == BadMatch) /* just add to list */ + { + if (!pWin->optional && !MakeWindowOptional (pWin)) + return BadAlloc; + pProp = dixAllocateObjectWithPrivates(PropertyRec, PRIVATE_PROPERTY); + if (!pProp) + return BadAlloc; + data = malloc(totalSize); + if (!data && len) + { + dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); + return BadAlloc; + } + memcpy(data, value, totalSize); + pProp->propertyName = property; + pProp->type = type; + pProp->format = format; + pProp->data = data; + pProp->size = len; + rc = XaceHookPropertyAccess(pClient, pWin, &pProp, + DixCreateAccess|DixWriteAccess); + if (rc != Success) { + free(data); + dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); + pClient->errorValue = property; + return rc; + } + pProp->next = pWin->optional->userProps; + pWin->optional->userProps = pProp; + } + else if (rc == Success) + { + /* 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; + + /* save the old values for later */ + savedProp = *pProp; + + if (mode == PropModeReplace) + { + data = malloc(totalSize); + if (!data && len) + return BadAlloc; + memcpy(data, value, totalSize); + pProp->data = data; + pProp->size = len; + pProp->type = type; + pProp->format = format; + } + else if (len == 0) + { + /* do nothing */ + } + else if (mode == PropModeAppend) + { + data = malloc((pProp->size + len) * sizeInBytes); + if (!data) + return BadAlloc; + memcpy(data, pProp->data, pProp->size * sizeInBytes); + memcpy(data + pProp->size * sizeInBytes, value, totalSize); + pProp->data = data; + pProp->size += len; + } + else if (mode == PropModePrepend) + { + data = malloc(sizeInBytes * (len + pProp->size)); + if (!data) + return BadAlloc; + memcpy(data + totalSize, pProp->data, pProp->size * sizeInBytes); + memcpy(data, value, totalSize); + pProp->data = data; + pProp->size += len; + } + + /* Allow security modules to check the new content */ + access_mode |= DixPostAccess; + rc = XaceHookPropertyAccess(pClient, pWin, &pProp, access_mode); + if (rc == Success) + { + if (savedProp.data != pProp->data) + free(savedProp.data); + } + else + { + if (savedProp.data != pProp->data) + free(pProp->data); + *pProp = savedProp; + return rc; + } + } + else + return rc; + + if (sendevent) + deliverPropertyNotifyEvent(pWin, PropertyNewValue, pProp->propertyName); + + return Success; +} + +int +ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format, + int mode, unsigned long len, pointer value, + Bool sendevent) +{ + return dixChangeWindowProperty(serverClient, pWin, property, type, format, + mode, len, value, sendevent); +} + +int +DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName) +{ + PropertyPtr pProp, prevProp; + int rc; + + rc = dixLookupProperty(&pProp, pWin, propName, client, DixDestroyAccess); + if (rc == BadMatch) + return Success; /* Succeed if property does not exist */ + + if (rc == Success) { + if (pWin->optional->userProps == pProp) { + /* Takes care of head */ + if (!(pWin->optional->userProps = pProp->next)) + CheckWindowOptionalNeed (pWin); + } else { + /* Need to traverse to find the previous element */ + prevProp = pWin->optional->userProps; + while (prevProp->next != pProp) + prevProp = prevProp->next; + prevProp->next = pProp->next; + } + + deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); + free(pProp->data); + dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); + } + return rc; +} + +void +DeleteAllWindowProperties(WindowPtr pWin) +{ + PropertyPtr pProp, pNextProp; + + pProp = wUserProps (pWin); + while (pProp) + { + deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); + pNextProp = pProp->next; + free(pProp->data); + dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); + pProp = pNextProp; + } + + if (pWin->optional) + pWin->optional->userProps = NULL; +} + +static int +NullPropertyReply( + ClientPtr client, + ATOM propertyType, + int format, + xGetPropertyReply *reply) +{ + reply->nItems = 0; + reply->length = 0; + reply->bytesAfter = 0; + reply->propertyType = propertyType; + reply->format = format; + WriteReplyToClient(client, sizeof(xGenericReply), reply); + return Success; +} + +/***************** + * GetProperty + * If type Any is specified, returns the property from the specified + * window regardless of its type. If a type is specified, returns the + * property only if its type equals the specified type. + * If delete is True and a property is returned, the property is also + * deleted from the window and a PropertyNotify event is generated on the + * window. + *****************/ + +int +ProcGetProperty(ClientPtr client) +{ + PropertyPtr pProp, prevProp; + unsigned long n, len, ind; + int rc; + WindowPtr pWin; + xGetPropertyReply reply; + Mask win_mode = DixGetPropAccess, prop_mode = DixReadAccess; + REQUEST(xGetPropertyReq); + + REQUEST_SIZE_MATCH(xGetPropertyReq); + if (stuff->delete) { + UpdateCurrentTime(); + win_mode |= DixSetPropAccess; + prop_mode |= DixDestroyAccess; + } + rc = dixLookupWindow(&pWin, stuff->window, client, win_mode); + if (rc != Success) + return rc; + + 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; + } + + memset(&reply, 0, sizeof(xGetPropertyReply)); + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; + + rc = dixLookupProperty(&pProp, pWin, stuff->property, client, prop_mode); + if (rc == BadMatch) + return NullPropertyReply(client, None, 0, &reply); + else if (rc != Success) + return rc; + + /* 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; + WriteReplyToClient(client, sizeof(xGenericReply), &reply); + return Success; + } + +/* + * Return type, format, value to client + */ + n = (pProp->format/8) * 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; + } + + len = min(n - ind, 4 * stuff->longLength); + + reply.bytesAfter = n - (ind + len); + reply.format = pProp->format; + reply.length = bytes_to_int32(len); + reply.nItems = len / (pProp->format / 8 ); + reply.propertyType = pProp->type; + + if (stuff->delete && (reply.bytesAfter == 0)) + deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); + + WriteReplyToClient(client, sizeof(xGenericReply), &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)) { + /* Delete the Property */ + if (pWin->optional->userProps == pProp) { + /* Takes care of head */ + if (!(pWin->optional->userProps = pProp->next)) + CheckWindowOptionalNeed (pWin); + } else { + /* Need to traverse to find the previous element */ + prevProp = pWin->optional->userProps; + while (prevProp->next != pProp) + prevProp = prevProp->next; + prevProp->next = pProp->next; + } + + free(pProp->data); + dixFreeObjectWithPrivates(pProp, PRIVATE_PROPERTY); + } + return Success; +} + +int +ProcListProperties(ClientPtr client) +{ + Atom *pAtoms = NULL, *temppAtoms; + xListPropertiesReply xlpr; + int rc, numProps = 0; + WindowPtr pWin; + PropertyPtr pProp, realProp; + REQUEST(xResourceReq); + + REQUEST_SIZE_MATCH(xResourceReq); + rc = dixLookupWindow(&pWin, stuff->id, client, DixListPropAccess); + if (rc != Success) + return rc; + + for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) + numProps++; + + if (numProps && !(pAtoms = malloc(numProps * sizeof(Atom)))) + return BadAlloc; + + numProps = 0; + temppAtoms = pAtoms; + for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) { + realProp = pProp; + rc = XaceHookPropertyAccess(client, pWin, &realProp, DixGetAttrAccess); + if (rc == Success && realProp == pProp) { + *temppAtoms++ = pProp->propertyName; + numProps++; + } + } + + xlpr.type = X_Reply; + xlpr.nProperties = numProps; + xlpr.length = bytes_to_int32(numProps * sizeof(Atom)); + xlpr.sequenceNumber = client->sequence; + WriteReplyToClient(client, sizeof(xGenericReply), &xlpr); + if (numProps) + { + client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write; + WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms); + } + free(pAtoms); + return Success; +} + +int +ProcDeleteProperty(ClientPtr client) +{ + WindowPtr pWin; + REQUEST(xDeletePropertyReq); + int result; + + REQUEST_SIZE_MATCH(xDeletePropertyReq); + UpdateCurrentTime(); + result = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); + if (result != Success) + return result; + if (!ValidAtom(stuff->property)) + { + client->errorValue = stuff->property; + return BadAtom; + } + + return DeleteProperty(client, pWin, stuff->property); +} -- cgit v1.2.3