From 1c94119ae26b94a60bb2c2b33494ed43c3b8a52f Mon Sep 17 00:00:00 2001 From: marha Date: Sun, 16 May 2010 20:50:58 +0000 Subject: svn merge -r588:HEAD ^/branches/released . --- xorg-server/dix/privates.c | 604 +++++++++++++++++++++------------------------ 1 file changed, 282 insertions(+), 322 deletions(-) (limited to 'xorg-server/dix/privates.c') diff --git a/xorg-server/dix/privates.c b/xorg-server/dix/privates.c index e3e727462..52a8df3f6 100644 --- a/xorg-server/dix/privates.c +++ b/xorg-server/dix/privates.c @@ -1,322 +1,282 @@ -/* - -Copyright 1993, 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. - -*/ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include -#include "windowstr.h" -#include "resource.h" -#include "privates.h" -#include "gcstruct.h" -#include "cursorstr.h" -#include "colormapst.h" -#include "inputstr.h" - -struct _Private { - int state; - pointer value; -}; - -typedef struct _PrivateDesc { - DevPrivateKey key; - unsigned size; - CallbackListPtr initfuncs; - CallbackListPtr deletefuncs; -} PrivateDescRec; - -#define PRIV_MAX 256 -#define PRIV_STEP 16 - -/* list of all allocated privates */ -static PrivateDescRec items[PRIV_MAX]; -static int nextPriv; - -static PrivateDescRec * -findItem(const DevPrivateKey key) -{ - if (!*key) { - if (nextPriv >= PRIV_MAX) - return NULL; - - items[nextPriv].key = key; - *key = nextPriv; - nextPriv++; - } - - return items + *key; -} - -static _X_INLINE int -privateExists(PrivateRec **privates, const DevPrivateKey key) -{ - return *key && *privates && - (*privates)[0].state > *key && - (*privates)[*key].state; -} - -/* - * Request pre-allocated space. - */ -int -dixRequestPrivate(const DevPrivateKey key, unsigned size) -{ - PrivateDescRec *item = findItem(key); - if (!item) - return FALSE; - if (size > item->size) - item->size = size; - return TRUE; -} - -/* - * Allocate a private and attach it to an existing object. - */ -pointer * -dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key) -{ - PrivateDescRec *item = findItem(key); - PrivateCallbackRec calldata; - PrivateRec *ptr; - pointer value; - int oldsize, newsize; - - newsize = (*key / PRIV_STEP + 1) * PRIV_STEP; - - /* resize or init privates array */ - if (!item) - return NULL; - - /* initialize privates array if necessary */ - if (!*privates) { - ptr = xcalloc(newsize, sizeof(*ptr)); - if (!ptr) - return NULL; - *privates = ptr; - (*privates)[0].state = newsize; - } - - oldsize = (*privates)[0].state; - - /* resize privates array if necessary */ - if (*key >= oldsize) { - ptr = xrealloc(*privates, newsize * sizeof(*ptr)); - if (!ptr) - return NULL; - memset(ptr + oldsize, 0, (newsize - oldsize) * sizeof(*ptr)); - *privates = ptr; - (*privates)[0].state = newsize; - } - - /* initialize slot */ - ptr = *privates + *key; - ptr->state = 1; - if (item->size) { - value = xcalloc(item->size, 1); - if (!value) - return NULL; - ptr->value = value; - } - - calldata.key = key; - calldata.value = &ptr->value; - CallCallbacks(&item->initfuncs, &calldata); - - return &ptr->value; -} - -/* - * Look up a private pointer. - */ -pointer -dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key) -{ - pointer *ptr; - - if (privateExists(privates, key)) - return (*privates)[*key].value; - - ptr = dixAllocatePrivate(privates, key); - return ptr ? *ptr : NULL; -} - -/* - * Look up the address of a private pointer. - */ -pointer * -dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key) -{ - if (privateExists(privates, key)) - return &(*privates)[*key].value; - - return dixAllocatePrivate(privates, key); -} - -/* - * Set a private pointer. - */ -int -dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val) -{ - top: - if (privateExists(privates, key)) { - (*privates)[*key].value = val; - return TRUE; - } - - if (!dixAllocatePrivate(privates, key)) - return FALSE; - goto top; -} - -/* - * Called to free privates at object deletion time. - */ -void -dixFreePrivates(PrivateRec *privates) -{ - int i; - PrivateCallbackRec calldata; - - if (privates) - for (i = 1; i < privates->state; i++) - if (privates[i].state) { - /* call the delete callbacks */ - calldata.key = items[i].key; - calldata.value = &privates[i].value; - CallCallbacks(&items[i].deletefuncs, &calldata); - - /* free pre-allocated memory */ - if (items[i].size) - xfree(privates[i].value); - } - - xfree(privates); -} - -/* - * Callback registration - */ -int -dixRegisterPrivateInitFunc(const DevPrivateKey key, - CallbackProcPtr callback, pointer data) -{ - PrivateDescRec *item = findItem(key); - if (!item) - return FALSE; - - return AddCallback(&item->initfuncs, callback, data); -} - -int -dixRegisterPrivateDeleteFunc(const DevPrivateKey key, - CallbackProcPtr callback, pointer data) -{ - PrivateDescRec *item = findItem(key); - if (!item) - return FALSE; - - return AddCallback(&item->deletefuncs, callback, data); -} - -/* Table of devPrivates offsets */ -static const int offsetDefaults[] = { - -1, /* RT_NONE */ - offsetof(WindowRec, devPrivates), /* RT_WINDOW */ - offsetof(PixmapRec, devPrivates), /* RT_PIXMAP */ - offsetof(GC, devPrivates), /* RT_GC */ - -1, /* RT_FONT */ - offsetof(CursorRec, devPrivates), /* RT_CURSOR */ - offsetof(ColormapRec, devPrivates), /* RT_COLORMAP */ - -1, /* RT_CMAPENTRY */ - -1, /* RT_OTHERCLIENT */ - -1 /* RT_PASSIVEGRAB */ -}; - -static int *offsets = NULL; -static int offsetsSize = 0; - -/* - * Specify where the devPrivates field is located in a structure type - */ -int -dixRegisterPrivateOffset(RESTYPE type, int offset) -{ - type = type & TypeMask; - - /* resize offsets table if necessary */ - while (type >= offsetsSize) { - unsigned i = offsetsSize * 2 * sizeof(int); - offsets = (int *)xrealloc(offsets, i); - if (!offsets) { - offsetsSize = 0; - return FALSE; - } - for (i=offsetsSize; i < 2*offsetsSize; i++) - offsets[i] = -1; - offsetsSize *= 2; - } - - offsets[type] = offset; - return TRUE; -} - -int -dixLookupPrivateOffset(RESTYPE type) -{ - type = type & TypeMask; - assert(type < offsetsSize); - return offsets[type]; -} - -int -dixResetPrivates(void) -{ - int i; - - /* reset private descriptors */ - for (i = 1; i < nextPriv; i++) { - *items[i].key = 0; - items[i].size = 0; - DeleteCallbackList(&items[i].initfuncs); - DeleteCallbackList(&items[i].deletefuncs); - } - nextPriv = 1; - - /* reset offsets */ - if (offsets) - xfree(offsets); - offsetsSize = sizeof(offsetDefaults); - offsets = xalloc(offsetsSize); - offsetsSize /= sizeof(int); - if (!offsets) - return FALSE; - memcpy(offsets, offsetDefaults, sizeof(offsetDefaults)); - return TRUE; -} +/* + +Copyright 1993, 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. + +*/ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include "windowstr.h" +#include "resource.h" +#include "privates.h" +#include "gcstruct.h" +#include "cursorstr.h" +#include "colormapst.h" +#include "inputstr.h" + +struct _Private { + int state; + pointer value; +}; + +typedef struct _PrivateDesc { + DevPrivateKey key; + unsigned size; +} PrivateDescRec; + +#define PRIV_MAX 256 +#define PRIV_STEP 16 + +/* list of all allocated privates */ +static PrivateDescRec items[PRIV_MAX]; +static int nextPriv; + +static PrivateDescRec * +findItem(const DevPrivateKey key) +{ + if (!*key) { + if (nextPriv >= PRIV_MAX) + return NULL; + + items[nextPriv].key = key; + *key = nextPriv; + nextPriv++; + } + + return items + *key; +} + +static _X_INLINE int +privateExists(PrivateRec **privates, const DevPrivateKey key) +{ + return *key && *privates && + (*privates)[0].state > *key && + (*privates)[*key].state; +} + +/* + * Request pre-allocated space. + */ +int +dixRequestPrivate(const DevPrivateKey key, unsigned size) +{ + PrivateDescRec *item = findItem(key); + if (!item) + return FALSE; + if (size > item->size) + item->size = size; + return TRUE; +} + +/* + * Allocate a private and attach it to an existing object. + */ +pointer * +dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key) +{ + PrivateDescRec *item = findItem(key); + PrivateRec *ptr; + pointer value; + int oldsize, newsize; + + newsize = (*key / PRIV_STEP + 1) * PRIV_STEP; + + /* resize or init privates array */ + if (!item) + return NULL; + + /* initialize privates array if necessary */ + if (!*privates) { + ptr = calloc(newsize, sizeof(*ptr)); + if (!ptr) + return NULL; + *privates = ptr; + (*privates)[0].state = newsize; + } + + oldsize = (*privates)[0].state; + + /* resize privates array if necessary */ + if (*key >= oldsize) { + ptr = realloc(*privates, newsize * sizeof(*ptr)); + if (!ptr) + return NULL; + memset(ptr + oldsize, 0, (newsize - oldsize) * sizeof(*ptr)); + *privates = ptr; + (*privates)[0].state = newsize; + } + + /* initialize slot */ + ptr = *privates + *key; + ptr->state = 1; + if (item->size) { + value = calloc(item->size, 1); + if (!value) + return NULL; + ptr->value = value; + } + + return &ptr->value; +} + +/* + * Look up a private pointer. + */ +pointer +dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key) +{ + pointer *ptr; + + if (privateExists(privates, key)) + return (*privates)[*key].value; + + ptr = dixAllocatePrivate(privates, key); + return ptr ? *ptr : NULL; +} + +/* + * Look up the address of a private pointer. + */ +pointer * +dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key) +{ + if (privateExists(privates, key)) + return &(*privates)[*key].value; + + return dixAllocatePrivate(privates, key); +} + +/* + * Set a private pointer. + */ +int +dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val) +{ + top: + if (privateExists(privates, key)) { + (*privates)[*key].value = val; + return TRUE; + } + + if (!dixAllocatePrivate(privates, key)) + return FALSE; + goto top; +} + +/* + * Called to free privates at object deletion time. + */ +void +dixFreePrivates(PrivateRec *privates) +{ + int i; + + if (privates) + for (i = 1; i < privates->state; i++) + if (privates[i].state) { + /* free pre-allocated memory */ + if (items[i].size) + free(privates[i].value); + } + + free(privates); +} + +/* Table of devPrivates offsets */ +static const int offsetDefaults[] = { + -1, /* RT_NONE */ + offsetof(WindowRec, devPrivates), /* RT_WINDOW */ + offsetof(PixmapRec, devPrivates), /* RT_PIXMAP */ + offsetof(GC, devPrivates), /* RT_GC */ + -1, /* RT_FONT */ + offsetof(CursorRec, devPrivates), /* RT_CURSOR */ + offsetof(ColormapRec, devPrivates), /* RT_COLORMAP */ + -1, /* RT_CMAPENTRY */ + -1, /* RT_OTHERCLIENT */ + -1 /* RT_PASSIVEGRAB */ +}; + +static int *offsets = NULL; +static int offsetsSize = 0; + +/* + * Specify where the devPrivates field is located in a structure type + */ +int +dixRegisterPrivateOffset(RESTYPE type, int offset) +{ + type = type & TypeMask; + + /* resize offsets table if necessary */ + while (type >= offsetsSize) { + unsigned i = offsetsSize * 2 * sizeof(int); + offsets = (int *)realloc(offsets, i); + if (!offsets) { + offsetsSize = 0; + return FALSE; + } + for (i=offsetsSize; i < 2*offsetsSize; i++) + offsets[i] = -1; + offsetsSize *= 2; + } + + offsets[type] = offset; + return TRUE; +} + +int +dixLookupPrivateOffset(RESTYPE type) +{ + type = type & TypeMask; + assert(type < offsetsSize); + return offsets[type]; +} + +int +dixResetPrivates(void) +{ + int i; + + /* reset private descriptors */ + for (i = 1; i < nextPriv; i++) { + *items[i].key = 0; + items[i].size = 0; + } + nextPriv = 1; + + /* reset offsets */ + if (offsets) + free(offsets); + offsetsSize = sizeof(offsetDefaults); + offsets = malloc(offsetsSize); + offsetsSize /= sizeof(int); + if (!offsets) + return FALSE; + memcpy(offsets, offsetDefaults, sizeof(offsetDefaults)); + return TRUE; +} -- cgit v1.2.3