diff options
Diffstat (limited to 'xorg-server/dix/privates.c')
-rw-r--r-- | xorg-server/dix/privates.c | 604 |
1 files changed, 282 insertions, 322 deletions
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 <dix-config.h> -#endif - -#include <stddef.h> -#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 <dix-config.h>
+#endif
+
+#include <stddef.h>
+#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;
+}
|