summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2010-04-30 19:38:38 -0700
committerKeith Packard <keithp@keithp.com>2010-06-05 19:31:32 -0700
commit495fc3eb2d6c98bde82ae1278f89fcf131fd9bf8 (patch)
treef7bbda052922634ca13d4f1e20d2fcebd201332b
parentfaeebead7bfcc78535757ca7acc1faf7554c03b7 (diff)
Change devPrivates implementation.
Each key now declares which object type it belongs to, this permits keys for different types to share the same offset within the allocated privates. As a special case for XSELinux, a key may be allocated as PRIVATE_XSELINUX which will allow it to continue to be used across the relevant object types. Signed-off-by: Keith Packard <keithp@keithp.com> Reviewed-by: Jamey Sharp <jamey@minilop.net>
-rw-r--r--dix/privates.c476
-rw-r--r--include/privates.h116
2 files changed, 407 insertions, 185 deletions
diff --git a/dix/privates.c b/dix/privates.c
index 87831c237..736e950f1 100644
--- a/dix/privates.c
+++ b/dix/privates.c
@@ -25,6 +25,28 @@ other dealings in this Software without prior written authorization
from The Open Group.
*/
+/*
+ * Copyright © 2010, Keith Packard
+ * Copyright © 2010, Jamey Sharp
+ *
+ * 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 of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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 <dix-config.h>
@@ -38,192 +60,300 @@ from The Open Group.
#include "cursorstr.h"
#include "colormapst.h"
#include "inputstr.h"
-
-struct _Private {
- int state;
- pointer value;
+#include "scrnintstr.h"
+#include "extnsionst.h"
+
+static struct {
+ DevPrivateKey key;
+ unsigned offset;
+ int created;
+ int allocated;
+} keys[PRIVATE_LAST];
+
+static const Bool xselinux_private[PRIVATE_LAST] = {
+ [PRIVATE_CLIENT] = TRUE,
+ [PRIVATE_WINDOW] = TRUE,
+ [PRIVATE_PIXMAP] = TRUE,
+ [PRIVATE_GC] = TRUE,
+ [PRIVATE_CURSOR] = TRUE,
+ [PRIVATE_COLORMAP] = TRUE,
+ [PRIVATE_DEVICE] = TRUE,
+ [PRIVATE_EXTENSION] = TRUE,
+ [PRIVATE_SELECTION] = TRUE,
+ [PRIVATE_PROPERTY] = TRUE,
+ [PRIVATE_PICTURE] = TRUE,
+ [PRIVATE_GLYPHSET] = TRUE,
};
-typedef struct _PrivateDesc {
- DevPrivateKey key;
- unsigned size;
-} PrivateDescRec;
+typedef Bool (*FixupFunc)(PrivatePtr *privates, int offset, unsigned bytes);
-#define PRIV_MAX 256
-#define PRIV_STEP 16
-
-static int number_privates_allocated;
-static int number_private_ptrs_allocated;
-static int bytes_private_data_allocated;
+static Bool
+dixReallocPrivates(PrivatePtr *privates, int old_offset, unsigned bytes)
+{
+ void *new_privates;
-/* list of all allocated privates */
-static PrivateDescRec items[PRIV_MAX];
-static int nextPriv;
+ new_privates = realloc(*privates, old_offset + bytes);
+ if (!new_privates)
+ return FALSE;
+ memset((char *) new_privates + old_offset, '\0', bytes);
+ *privates = new_privates;
+ return TRUE;
+}
-static PrivateDescRec *
-findItem(const DevPrivateKey key)
+static Bool
+dixMovePrivates(PrivatePtr *privates, int new_offset, unsigned bytes)
{
- if (!key->key) {
- if (nextPriv >= PRIV_MAX)
- return NULL;
+ memmove((char *) *privates + bytes, *privates, new_offset - bytes);
+ memset(*privates, '\0', bytes);
+ return TRUE;
+}
- items[nextPriv].key = key;
- key->key = nextPriv;
- nextPriv++;
- }
+static Bool
+fixupScreens(FixupFunc fixup, unsigned bytes)
+{
+ int s;
+ for (s = 0; s < screenInfo.numScreens; s++)
+ if (!fixup(&screenInfo.screens[s]->devPrivates, keys[PRIVATE_SCREEN].offset, bytes))
+ return FALSE;
+ return TRUE;
+}
- return items + key->key;
+static Bool
+fixupServerClient(FixupFunc fixup, unsigned bytes)
+{
+ if (serverClient)
+ return fixup(&serverClient->devPrivates, keys[PRIVATE_CLIENT].offset, bytes);
+ return TRUE;
}
-static _X_INLINE int
-privateExists(PrivateRec **privates, const DevPrivateKey key)
+static Bool
+fixupExtensions(FixupFunc fixup, unsigned bytes)
{
- return key->key && *privates &&
- (*privates)[0].state > key->key &&
- (*privates)[key->key].state;
+ unsigned char major;
+ ExtensionEntry *extension;
+ for (major = EXTENSION_BASE; (extension = GetExtensionEntry(major)); major++)
+ if (!fixup(&extension->devPrivates, keys[PRIVATE_EXTENSION].offset, bytes))
+ return FALSE;
+ return TRUE;
}
-/*
- * Request pre-allocated space.
- */
-int
-dixRegisterPrivateKey(const DevPrivateKey key, DevPrivateType type, unsigned size)
+static Bool
+fixupDefaultColormaps(FixupFunc fixup, unsigned bytes)
{
- PrivateDescRec *item = findItem(key);
- if (!item)
- return FALSE;
- if (size > item->size)
- item->size = size;
+ int s;
+ for (s = 0; s < screenInfo.numScreens; s++) {
+ ColormapPtr cmap;
+ dixLookupResourceByType((pointer *) &cmap, screenInfo.screens[s]->defColormap,
+ RT_COLORMAP, serverClient, DixCreateAccess);
+ if (cmap && !fixup(&cmap->devPrivates, keys[PRIVATE_COLORMAP].offset, bytes))
+ return FALSE;
+ }
return TRUE;
}
+static Bool (* const allocated_early[PRIVATE_LAST])(FixupFunc, unsigned) = {
+ [PRIVATE_SCREEN] = fixupScreens,
+ [PRIVATE_CLIENT] = fixupServerClient,
+ [PRIVATE_EXTENSION] = fixupExtensions,
+ [PRIVATE_COLORMAP] = fixupDefaultColormaps,
+};
+
/*
- * Allocate a private and attach it to an existing object.
+ * Register a private key. This takes the type of object the key will
+ * be used with, which may be PRIVATE_ALL indicating that this key
+ * will be used with all of the private objects. If 'size' is
+ * non-zero, then the specified amount of space will be allocated in
+ * the private storage. Otherwise, space for a single pointer will
+ * be allocated which can be set with dixSetPrivate
*/
-static pointer *
-dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key)
+Bool
+dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size)
{
- PrivateDescRec *item = findItem(key);
- PrivateRec *ptr;
- pointer value;
- int oldsize, newsize;
+ DevPrivateType t;
+ int offset;
+ unsigned bytes;
- newsize = (key->key / PRIV_STEP + 1) * PRIV_STEP;
-
- /* resize or init privates array */
- if (!item)
- return NULL;
-
- /* initialize privates array if necessary */
- if (!*privates) {
- ++number_privates_allocated;
- number_private_ptrs_allocated += newsize;
- ptr = calloc(newsize, sizeof(*ptr));
- if (!ptr)
- return NULL;
- *privates = ptr;
- (*privates)[0].state = newsize;
+ if (key->initialized) {
+ assert (size == key->size);
+ return TRUE;
}
- oldsize = (*privates)[0].state;
-
- /* resize privates array if necessary */
- if (key->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;
- number_private_ptrs_allocated -= oldsize;
- number_private_ptrs_allocated += newsize;
- }
+ /* Compute required space */
+ bytes = size;
+ if (size == 0)
+ bytes = sizeof (void *);
+
+ /* align to void * size */
+ bytes = (bytes + sizeof (void *) - 1) & ~(sizeof (void *) - 1);
+
+ /* Update offsets for all affected keys */
+ if (type == PRIVATE_XSELINUX) {
+ DevPrivateKey k;
+
+ /* Resize if we can, or make sure nothing's allocated if we can't
+ */
+ for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++)
+ if (xselinux_private[t]) {
+ if (!allocated_early[t])
+ assert (!keys[t].created);
+ else if (!allocated_early[t](dixReallocPrivates, bytes))
+ return FALSE;
+ }
- /* initialize slot */
- ptr = *privates + key->key;
- ptr->state = 1;
- if (item->size) {
- value = calloc(item->size, 1);
- if (!value)
- return NULL;
- bytes_private_data_allocated += item->size;
- ptr->value = value;
+ /* Move all existing keys up in the privates space to make
+ * room for this new global key
+ */
+ for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) {
+ if (xselinux_private[t]) {
+ for (k = keys[t].key; k; k = k->next)
+ k->offset += bytes;
+ keys[t].offset += bytes;
+ if (allocated_early[t])
+ allocated_early[t](dixMovePrivates, bytes);
+ }
+ }
+
+ offset = 0;
+ } else {
+ /* Resize if we can, or make sure nothing's allocated if we can't */
+ if (!allocated_early[type])
+ assert(!keys[type].created);
+ else if (!allocated_early[type](dixReallocPrivates, bytes))
+ return FALSE;
+ offset = keys[type].offset;
+ keys[type].offset += bytes;
}
- return &ptr->value;
+ /* Setup this key */
+ key->offset = offset;
+ key->size = size;
+ key->initialized = TRUE;
+ key->type = type;
+ key->next = keys[type].key;
+ keys[type].key = key;
+
+ return TRUE;
}
/*
- * Look up a private pointer.
+ * Initialize privates by zeroing them
*/
-pointer
-dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key)
+void
+_dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type)
{
- pointer *ptr;
-
- assert (key->key != 0);
- if (privateExists(privates, key))
- return (*privates)[key->key].value;
+ keys[type].created++;
+ if (xselinux_private[type])
+ keys[PRIVATE_XSELINUX].created++;
+ if (keys[type].offset == 0)
+ addr = 0;
+ *privates = addr;
+ memset(addr, '\0', keys[type].offset);
+}
- ptr = dixAllocatePrivate(privates, key);
- return ptr ? *ptr : NULL;
+/*
+ * Clean up privates
+ */
+void
+_dixFiniPrivates(PrivatePtr privates, DevPrivateType type)
+{
+ keys[type].created--;
+ if (xselinux_private[type])
+ keys[PRIVATE_XSELINUX].created--;
}
/*
- * Look up the address of a private pointer.
+ * Allocate new object with privates.
+ *
+ * This is expected to be invoked from the
+ * dixAllocateObjectWithPrivates macro
*/
-pointer *
-dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key)
+void *
+_dixAllocateObjectWithPrivates(unsigned baseSize, unsigned clear, unsigned offset, DevPrivateType type)
{
- assert (key->key != 0);
+ unsigned totalSize;
+ void *object;
+ PrivatePtr privates;
+ PrivatePtr *devPrivates;
+
+ assert (type > PRIVATE_SCREEN && type < PRIVATE_LAST);
+
+ /* round up so that void * is aligned */
+ baseSize = (baseSize + sizeof (void *) - 1) & ~(sizeof (void *) - 1);
+ totalSize = baseSize + keys[type].offset;
+ object = malloc(totalSize);
+ if (!object)
+ return NULL;
- if (privateExists(privates, key))
- return &(*privates)[key->key].value;
+ memset(object, '\0', clear);
+ privates = (PrivatePtr) (((char *) object) + baseSize);
+ devPrivates = (PrivatePtr *) ((char *) object + offset);
- return dixAllocatePrivate(privates, key);
+ _dixInitPrivates(devPrivates, privates, type);
+
+ return object;
}
/*
- * Set a private pointer.
+ * Allocate privates separately from containing object.
+ * Used for clients and screens.
*/
-int
-dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
+Bool
+dixAllocatePrivates(PrivatePtr *privates, DevPrivateType type)
{
- assert (key->key != 0);
- top:
- if (privateExists(privates, key)) {
- (*privates)[key->key].value = val;
- return TRUE;
+ unsigned size;
+ PrivatePtr p;
+
+ assert (type > PRIVATE_XSELINUX && type < PRIVATE_LAST);
+
+ size = keys[type].offset;
+ if (!size) {
+ p = NULL;
+ } else {
+ if (!(p = malloc(size)))
+ return FALSE;
}
- if (!dixAllocatePrivate(privates, key))
- return FALSE;
- goto top;
+ _dixInitPrivates(privates, p, type);
+ ++keys[type].allocated;
+
+ return TRUE;
}
/*
- * Called to free privates at object deletion time.
+ * Free an object that has privates
+ *
+ * This is expected to be invoked from the
+ * dixFreeObjectWithPrivates macro
*/
void
-dixFreePrivates(PrivateRec *privates, DevPrivateType type)
+_dixFreeObjectWithPrivates(void *object, PrivatePtr privates, DevPrivateType type)
{
- int i;
-
- if (privates) {
- number_private_ptrs_allocated -= privates->state;
- number_privates_allocated--;
- for (i = 1; i < privates->state; i++)
- if (privates[i].state) {
- /* free pre-allocated memory */
- if (items[i].size)
- free(privates[i].value);
- bytes_private_data_allocated -= items[i].size;
- }
- }
+ _dixFiniPrivates(privates, type);
+ free(object);
+}
+/*
+ * Called to free screen or client privates
+ */
+void
+dixFreePrivates(PrivatePtr privates, DevPrivateType type)
+{
+ _dixFiniPrivates(privates, type);
+ --keys[type].allocated;
free(privates);
}
+/*
+ * Return size of privates for the specified type
+ */
+extern _X_EXPORT int
+dixPrivatesSize(DevPrivateType type)
+{
+ assert (type >= PRIVATE_SCREEN && type < PRIVATE_LAST);
+
+ return keys[type].offset;
+}
+
/* Table of devPrivates offsets */
static const int offsets[] = {
-1, /* RT_NONE */
@@ -256,32 +386,80 @@ dixLookupPrivateOffset(RESTYPE type)
return -1;
}
+static const char *key_names[PRIVATE_LAST] = {
+ /* XSELinux uses the same private keys for numerous objects */
+ [PRIVATE_XSELINUX] = "XSELINUX",
+
+ /* Otherwise, you get a private in just the requested structure
+ */
+ /* These can have objects created before all of the keys are registered */
+ [PRIVATE_SCREEN] = "SCREEN",
+ [PRIVATE_EXTENSION] = "EXTENSION",
+ [PRIVATE_COLORMAP] = "COLORMAP",
+
+ /* These cannot have any objects before all relevant keys are registered */
+ [PRIVATE_DEVICE] = "DEVICE",
+ [PRIVATE_CLIENT] = "CLIENT",
+ [PRIVATE_PROPERTY] = "PROPERTY",
+ [PRIVATE_SELECTION] = "SELECTION",
+ [PRIVATE_WINDOW] = "WINDOW",
+ [PRIVATE_PIXMAP] = "PIXMAP",
+ [PRIVATE_GC] = "GC",
+ [PRIVATE_CURSOR] = "CURSOR",
+ [PRIVATE_CURSOR_BITS] = "CURSOR_BITS",
+
+ /* extension privates */
+ [PRIVATE_DBE_WINDOW] = "DBE_WINDOW",
+ [PRIVATE_DAMAGE] = "DAMAGE",
+ [PRIVATE_GLYPH] = "GLYPH",
+ [PRIVATE_GLYPHSET] = "GLYPHSET",
+ [PRIVATE_PICTURE] = "PICTURE",
+};
+
void
dixPrivateUsage(void)
{
- ErrorF("number of private structures: %d\n",
- number_privates_allocated);
- ErrorF("total number of private pointers: %d (%zd bytes)\n",
- number_private_ptrs_allocated,
- number_private_ptrs_allocated * sizeof (struct _Private));
- ErrorF("bytes of extra private data: %d\n",
- bytes_private_data_allocated);
- ErrorF("Total privates memory usage: %zd\n",
- bytes_private_data_allocated +
- number_private_ptrs_allocated * sizeof (struct _Private));
+ int objects = 0;
+ int bytes = 0;
+ int alloc = 0;
+ DevPrivateType t;
+
+ for (t = PRIVATE_XSELINUX + 1; t < PRIVATE_LAST; t++) {
+ if (keys[t].offset) {
+ ErrorF("%s: %d objects of %d bytes = %d total bytes %d private allocs\n",
+ key_names[t], keys[t].created, keys[t].offset, keys[t].created * keys[t].offset,
+ keys[t].allocated);
+ bytes += keys[t].created * keys[t].offset;
+ objects += keys[t].created;
+ alloc += keys[t].allocated;
+ }
+ }
+ ErrorF("TOTAL: %d objects, %d bytes, %d allocs\n",
+ objects, bytes, alloc);
}
void
dixResetPrivates(void)
{
- int i;
-
- /* reset private descriptors */
- for (i = 1; i < nextPriv; i++) {
- items[i].key->key = 0;
- items[i].size = 0;
+ DevPrivateType t;
+
+ for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) {
+ DevPrivateKey key;
+
+ for (key = keys[t].key; key; key = key->next) {
+ key->offset = 0;
+ key->initialized = FALSE;
+ key->size = 0;
+ key->type = 0;
+ }
+ if (keys[t].created) {
+ ErrorF("%d %ss still allocated at reset\n",
+ keys[t].created, key_names[t]);
+ dixPrivateUsage();
+ }
+ keys[t].key = NULL;
+ keys[t].offset = 0;
+ keys[t].created = 0;
+ keys[t].allocated = 0;
}
- nextPriv = 1;
- if (number_privates_allocated)
- dixPrivateUsage();
}
diff --git a/include/privates.h b/include/privates.h
index 9412fd613..e2bdafda5 100644
--- a/include/privates.h
+++ b/include/privates.h
@@ -57,7 +57,11 @@ typedef enum {
} DevPrivateType;
typedef struct _DevPrivateKeyRec {
- int key;
+ int offset;
+ int size;
+ Bool initialized;
+ DevPrivateType type;
+ struct _DevPrivateKeyRec *next;
} DevPrivateKeyRec, *DevPrivateKey;
/*
@@ -91,17 +95,46 @@ dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size);
static inline Bool
dixPrivateKeyRegistered(DevPrivateKey key)
{
- return key->key != 0;
+ return key->initialized;
+}
+
+/*
+ * Get the address of the private storage.
+ *
+ * For keys with pre-defined storage, this gets the base of that storage
+ * Otherwise, it returns the place where the private pointer is stored.
+ */
+static inline void *
+dixGetPrivateAddr(PrivatePtr *privates, const DevPrivateKey key)
+{
+ assert(key->initialized);
+ return (char *) (*privates) + key->offset;
+}
+
+/*
+ * Fetch a private pointer stored in the object
+ *
+ * Returns the pointer stored with dixSetPrivate.
+ * This must only be used with keys that have
+ * no pre-defined storage
+ */
+static inline void *
+dixGetPrivate(PrivatePtr *privates, const DevPrivateKey key)
+{
+ assert (key->size == 0);
+ return *(void **) dixGetPrivateAddr(privates, key);
}
/*
* Associate 'val' with 'key' in 'privates' so that later calls to
* dixLookupPrivate(privates, key) will return 'val'.
- *
- * dixSetPrivate returns FALSE if a memory allocation fails.
*/
-extern _X_EXPORT int
-dixSetPrivate(PrivatePtr *privates, const DevPrivateKey key, pointer val);
+static inline void
+dixSetPrivate(PrivatePtr *privates, const DevPrivateKey key, pointer val)
+{
+ assert (key->size == 0);
+ *(pointer *) dixGetPrivateAddr(privates, key) = val;
+}
#include "dix.h"
#include "resource.h"
@@ -113,28 +146,42 @@ dixSetPrivate(PrivatePtr *privates, const DevPrivateKey key, pointer val);
* storage. For privates without defined storage, return the pointer
* contents
*/
-extern _X_EXPORT pointer
-dixLookupPrivate(PrivatePtr *privates, const DevPrivateKey key);
+static inline pointer
+dixLookupPrivate(PrivatePtr *privates, const DevPrivateKey key)
+{
+ if (key->size)
+ return dixGetPrivateAddr(privates, key);
+ else
+ return dixGetPrivate(privates, key);
+}
/*
- * Look up the address of a private pointer. If 'key' is not associated with a
- * value in 'privates', then dixLookupPrivateAddr calls dixAllocatePrivate and
- * returns a pointer to the resulting associated value.
+ * Look up the address of the pointer to the storage
*
- * dixLookupPrivateAddr returns NULL if 'key' was not previously associated in
- * 'privates' and a memory allocation fails.
+ * This returns the place where the private pointer is stored,
+ * which is only valid for privates without predefined storage.
*/
-extern _X_EXPORT pointer *
-dixLookupPrivateAddr(PrivatePtr *privates, const DevPrivateKey key);
+static inline pointer *
+dixLookupPrivateAddr(PrivatePtr *privates, const DevPrivateKey key)
+{
+ assert (key->size == 0);
+ return dixGetPrivateAddr(privates, key);
+}
/*
- * Allocates private data separately from main object (clients and colormaps)
+ * Allocates private data separately from main object.
+ *
+ * For objects created during server initialization, this allows those
+ * privates to be re-allocated as new private keys are registered.
+ *
+ * This includes screens, the serverClient, default colormaps and
+ * extensions entries.
*/
-static inline Bool
-dixAllocatePrivates(PrivatePtr *privates, DevPrivateType type) { *privates = NULL; return TRUE; }
+extern _X_EXPORT Bool
+dixAllocatePrivates(PrivatePtr *privates, DevPrivateType type);
/*
- * Frees separately allocated private data (screens and clients)
+ * Frees separately allocated private data
*/
extern _X_EXPORT void
dixFreePrivates(PrivatePtr privates, DevPrivateType type);
@@ -142,48 +189,44 @@ dixFreePrivates(PrivatePtr privates, DevPrivateType type);
/*
* Initialize privates by zeroing them
*/
-static inline void
-_dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type) { *privates = NULL; }
+extern _X_EXPORT void
+_dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type);
#define dixInitPrivates(o, v, type) _dixInitPrivates(&(o)->devPrivates, (v), type);
/*
* Clean up privates
*/
-static inline void
-_dixFiniPrivates(PrivatePtr privates, DevPrivateType type) { dixFreePrivates(privates, type); }
+extern _X_EXPORT void
+_dixFiniPrivates(PrivatePtr privates, DevPrivateType type);
#define dixFiniPrivates(o,t) _dixFiniPrivates((o)->devPrivates,t)
/*
* Allocates private data at object creation time. Required
- * for all objects other than ScreenRecs.
+ * for almost all objects, except for the list described
+ * above for dixAllocatePrivates.
*/
-static inline void *
-_dixAllocateObjectWithPrivates(unsigned size, unsigned clear, unsigned offset, DevPrivateType type) {
- return calloc(size, 1);
-}
+extern _X_EXPORT void *
+_dixAllocateObjectWithPrivates(unsigned size, unsigned clear, unsigned offset, DevPrivateType type);
#define dixAllocateObjectWithPrivates(t, type) (t *) _dixAllocateObjectWithPrivates(sizeof(t), sizeof(t), offsetof(t, devPrivates), type)
-static inline void
-_dixFreeObjectWithPrivates(void *object, PrivatePtr privates, DevPrivateType type) {
- dixFreePrivates(privates, type);
- free(object);
-}
+extern _X_EXPORT void
+_dixFreeObjectWithPrivates(void *object, PrivatePtr privates, DevPrivateType type);
#define dixFreeObjectWithPrivates(o,t) _dixFreeObjectWithPrivates(o, (o)->devPrivates, t)
/*
* Return size of privates for the specified type
*/
-static inline int
-dixPrivatesSize(DevPrivateType type) { return 0; }
+extern _X_EXPORT int
+dixPrivatesSize(DevPrivateType type);
/*
* Dump out private stats to ErrorF
*/
-void
+extern void
dixPrivateUsage(void);
/*
@@ -195,6 +238,7 @@ dixResetPrivates(void);
/*
* Looks up the offset where the devPrivates field is located.
+ *
* Returns -1 if the specified resource has no dev privates.
* The position of the devPrivates field varies by structure
* and calling code might only know the resource type, not the