summaryrefslogtreecommitdiff
path: root/dix/privates.c
diff options
context:
space:
mode:
Diffstat (limited to 'dix/privates.c')
-rw-r--r--dix/privates.c517
1 files changed, 155 insertions, 362 deletions
diff --git a/dix/privates.c b/dix/privates.c
index 246597117..e04da41b1 100644
--- a/dix/privates.c
+++ b/dix/privates.c
@@ -30,425 +30,218 @@ from The Open Group.
#include <dix-config.h>
#endif
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "misc.h"
-#include "os.h"
+#include <stddef.h>
#include "windowstr.h"
#include "resource.h"
-#include "dixstruct.h"
+#include "privates.h"
#include "gcstruct.h"
+#include "cursorstr.h"
#include "colormapst.h"
-#include "servermd.h"
-#include "site.h"
#include "inputstr.h"
-#include "extnsionst.h"
-/*
- * See the Wrappers and devPrivates section in "Definition of the
- * Porting Layer for the X v11 Sample Server" (doc/Server/ddx.tbl.ms)
- * for information on how to use devPrivates.
- */
-
-/*
- * extension private machinery
- */
-
-static int extensionPrivateCount;
-int extensionPrivateLen;
-unsigned *extensionPrivateSizes;
-unsigned totalExtensionSize;
-
-void
-ResetExtensionPrivates(void)
-{
- extensionPrivateCount = 0;
- extensionPrivateLen = 0;
- xfree(extensionPrivateSizes);
- extensionPrivateSizes = (unsigned *)NULL;
- totalExtensionSize =
- ((sizeof(ExtensionEntry) + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
-}
-
-_X_EXPORT int
-AllocateExtensionPrivateIndex(void)
-{
- return extensionPrivateCount++;
-}
-
-_X_EXPORT Bool
-AllocateExtensionPrivate(int index2, unsigned amount)
-{
- unsigned oldamount;
-
- /* Round up sizes for proper alignment */
- amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
-
- if (index2 >= extensionPrivateLen)
- {
- unsigned *nsizes;
- nsizes = (unsigned *)xrealloc(extensionPrivateSizes,
- (index2 + 1) * sizeof(unsigned));
- if (!nsizes)
- return FALSE;
- while (extensionPrivateLen <= index2)
- {
- nsizes[extensionPrivateLen++] = 0;
- totalExtensionSize += sizeof(DevUnion);
- }
- extensionPrivateSizes = nsizes;
+typedef struct _PrivateDesc {
+ DevPrivateKey key;
+ unsigned size;
+ CallbackListPtr initfuncs;
+ CallbackListPtr deletefuncs;
+ struct _PrivateDesc *next;
+} PrivateDescRec;
+
+/* list of all allocated privates */
+static PrivateDescRec *items = NULL;
+
+static _X_INLINE PrivateDescRec *
+findItem(const DevPrivateKey key)
+{
+ PrivateDescRec *item = items;
+ while (item) {
+ if (item->key == key)
+ return item;
+ item = item->next;
}
- oldamount = extensionPrivateSizes[index2];
- if (amount > oldamount)
- {
- extensionPrivateSizes[index2] = amount;
- totalExtensionSize += (amount - oldamount);
- }
- return TRUE;
+ return NULL;
}
/*
- * client private machinery
+ * Request pre-allocated space.
*/
-
-static int clientPrivateCount;
-int clientPrivateLen;
-unsigned *clientPrivateSizes;
-unsigned totalClientSize;
-
-void
-ResetClientPrivates(void)
-{
- clientPrivateCount = 0;
- clientPrivateLen = 0;
- xfree(clientPrivateSizes);
- clientPrivateSizes = (unsigned *)NULL;
- totalClientSize =
- ((sizeof(ClientRec) + sizeof(long) - 1) / sizeof(long)) * sizeof(long);
-}
-
_X_EXPORT int
-AllocateClientPrivateIndex(void)
-{
- return clientPrivateCount++;
-}
-
-_X_EXPORT Bool
-AllocateClientPrivate(int index2, unsigned amount)
+dixRequestPrivate(const DevPrivateKey key, unsigned size)
{
- unsigned oldamount;
-
- /* Round up sizes for proper alignment */
- amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
-
- if (index2 >= clientPrivateLen)
- {
- unsigned *nsizes;
- nsizes = (unsigned *)xrealloc(clientPrivateSizes,
- (index2 + 1) * sizeof(unsigned));
- if (!nsizes)
+ PrivateDescRec *item = findItem(key);
+ if (item) {
+ if (size > item->size)
+ item->size = size;
+ } else {
+ item = (PrivateDescRec *)xalloc(sizeof(PrivateDescRec));
+ if (!item)
return FALSE;
- while (clientPrivateLen <= index2)
- {
- nsizes[clientPrivateLen++] = 0;
- totalClientSize += sizeof(DevUnion);
- }
- clientPrivateSizes = nsizes;
- }
- oldamount = clientPrivateSizes[index2];
- if (amount > oldamount)
- {
- clientPrivateSizes[index2] = amount;
- totalClientSize += (amount - oldamount);
+ memset(item, 0, sizeof(PrivateDescRec));
+
+ /* add privates descriptor */
+ item->key = key;
+ item->size = size;
+ item->next = items;
+ items = item;
}
return TRUE;
}
/*
- * screen private machinery
- */
-
-int screenPrivateCount;
-
-void
-ResetScreenPrivates(void)
-{
- screenPrivateCount = 0;
-}
-
-/* this can be called after some screens have been created,
- * so we have to worry about resizing existing devPrivates
+ * Allocate a private and attach it to an existing object.
*/
-_X_EXPORT int
-AllocateScreenPrivateIndex(void)
-{
- int idx;
- int i;
- ScreenPtr pScreen;
- DevUnion *nprivs;
-
- idx = screenPrivateCount++;
- for (i = 0; i < screenInfo.numScreens; i++)
- {
- pScreen = screenInfo.screens[i];
- nprivs = (DevUnion *)xrealloc(pScreen->devPrivates,
- screenPrivateCount * sizeof(DevUnion));
- if (!nprivs)
- {
- screenPrivateCount--;
- return -1;
- }
- /* Zero the new private */
- bzero(&nprivs[idx], sizeof(DevUnion));
- pScreen->devPrivates = nprivs;
+_X_EXPORT pointer *
+dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key)
+{
+ PrivateDescRec *item = findItem(key);
+ PrivateRec *ptr;
+ unsigned size = sizeof(PrivateRec);
+
+ if (item)
+ size += item->size;
+
+ ptr = (PrivateRec *)xcalloc(size, 1);
+ if (!ptr)
+ return NULL;
+ ptr->key = key;
+ ptr->value = (size > sizeof(PrivateRec)) ? (ptr + 1) : NULL;
+ ptr->next = *privates;
+ *privates = ptr;
+
+ /* call any init funcs and return */
+ if (item) {
+ PrivateCallbackRec calldata = { key, &ptr->value };
+ CallCallbacks(&item->initfuncs, &calldata);
}
- return idx;
+ return &ptr->value;
}
-
/*
- * window private machinery
+ * Called to free privates at object deletion time.
*/
-
-static int windowPrivateCount;
-
-void
-ResetWindowPrivates(void)
-{
- windowPrivateCount = 0;
-}
-
-_X_EXPORT int
-AllocateWindowPrivateIndex(void)
-{
- return windowPrivateCount++;
-}
-
-_X_EXPORT Bool
-AllocateWindowPrivate(ScreenPtr pScreen, int index2, unsigned amount)
-{
- unsigned oldamount;
-
- /* Round up sizes for proper alignment */
- amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
-
- if (index2 >= pScreen->WindowPrivateLen)
- {
- unsigned *nsizes;
- nsizes = (unsigned *)xrealloc(pScreen->WindowPrivateSizes,
- (index2 + 1) * sizeof(unsigned));
- if (!nsizes)
- return FALSE;
- while (pScreen->WindowPrivateLen <= index2)
- {
- nsizes[pScreen->WindowPrivateLen++] = 0;
- pScreen->totalWindowSize += sizeof(DevUnion);
+_X_EXPORT void
+dixFreePrivates(PrivateRec *privates)
+{
+ PrivateRec *ptr, *next;
+ PrivateDescRec *item;
+ PrivateCallbackRec calldata;
+
+ /* first pass calls the delete callbacks */
+ for (ptr = privates; ptr; ptr = ptr->next) {
+ item = findItem(ptr->key);
+ if (item) {
+ calldata.key = ptr->key;
+ calldata.value = &ptr->value;
+ CallCallbacks(&item->deletefuncs, &calldata);
}
- pScreen->WindowPrivateSizes = nsizes;
}
- oldamount = pScreen->WindowPrivateSizes[index2];
- if (amount > oldamount)
- {
- pScreen->WindowPrivateSizes[index2] = amount;
- pScreen->totalWindowSize += (amount - oldamount);
+
+ /* second pass frees the memory */
+ ptr = privates;
+ while (ptr) {
+ next = ptr->next;
+ xfree(ptr);
+ ptr = next;
}
- return TRUE;
}
-
/*
- * gc private machinery
+ * Callback registration
*/
-
-static int gcPrivateCount;
-
-void
-ResetGCPrivates(void)
-{
- gcPrivateCount = 0;
-}
-
_X_EXPORT int
-AllocateGCPrivateIndex(void)
-{
- return gcPrivateCount++;
-}
-
-_X_EXPORT Bool
-AllocateGCPrivate(ScreenPtr pScreen, int index2, unsigned amount)
+dixRegisterPrivateInitFunc(const DevPrivateKey key,
+ CallbackProcPtr callback, pointer data)
{
- unsigned oldamount;
-
- /* Round up sizes for proper alignment */
- amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
-
- if (index2 >= pScreen->GCPrivateLen)
- {
- unsigned *nsizes;
- nsizes = (unsigned *)xrealloc(pScreen->GCPrivateSizes,
- (index2 + 1) * sizeof(unsigned));
- if (!nsizes)
+ PrivateDescRec *item = findItem(key);
+ if (!item) {
+ if (!dixRequestPrivate(key, 0))
return FALSE;
- while (pScreen->GCPrivateLen <= index2)
- {
- nsizes[pScreen->GCPrivateLen++] = 0;
- pScreen->totalGCSize += sizeof(DevUnion);
- }
- pScreen->GCPrivateSizes = nsizes;
+ item = findItem(key);
}
- oldamount = pScreen->GCPrivateSizes[index2];
- if (amount > oldamount)
- {
- pScreen->GCPrivateSizes[index2] = amount;
- pScreen->totalGCSize += (amount - oldamount);
- }
- return TRUE;
-}
-
-
-/*
- * pixmap private machinery
- */
-static int pixmapPrivateCount;
-
-void
-ResetPixmapPrivates(void)
-{
- pixmapPrivateCount = 0;
+ return AddCallback(&item->initfuncs, callback, data);
}
_X_EXPORT int
-AllocatePixmapPrivateIndex(void)
+dixRegisterPrivateDeleteFunc(const DevPrivateKey key,
+ CallbackProcPtr callback, pointer data)
{
- return pixmapPrivateCount++;
-}
-
-_X_EXPORT Bool
-AllocatePixmapPrivate(ScreenPtr pScreen, int index2, unsigned amount)
-{
- unsigned oldamount;
-
- /* Round up sizes for proper alignment */
- amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
-
- if (index2 >= pScreen->PixmapPrivateLen)
- {
- unsigned *nsizes;
- nsizes = (unsigned *)xrealloc(pScreen->PixmapPrivateSizes,
- (index2 + 1) * sizeof(unsigned));
- if (!nsizes)
+ PrivateDescRec *item = findItem(key);
+ if (!item) {
+ if (!dixRequestPrivate(key, 0))
return FALSE;
- while (pScreen->PixmapPrivateLen <= index2)
- {
- nsizes[pScreen->PixmapPrivateLen++] = 0;
- pScreen->totalPixmapSize += sizeof(DevUnion);
- }
- pScreen->PixmapPrivateSizes = nsizes;
- }
- oldamount = pScreen->PixmapPrivateSizes[index2];
- if (amount > oldamount)
- {
- pScreen->PixmapPrivateSizes[index2] = amount;
- pScreen->totalPixmapSize += (amount - oldamount);
+ item = findItem(key);
}
- pScreen->totalPixmapSize = BitmapBytePad(pScreen->totalPixmapSize * 8);
- return TRUE;
-}
-
+ 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;
/*
- * colormap private machinery
+ * Specify where the devPrivates field is located in a structure type
*/
-
-int colormapPrivateCount;
-
-void
-ResetColormapPrivates(void)
-{
- colormapPrivateCount = 0;
-}
-
-
_X_EXPORT int
-AllocateColormapPrivateIndex (InitCmapPrivFunc initPrivFunc)
+dixRegisterPrivateOffset(RESTYPE type, int offset)
{
- int index;
- int i;
- ColormapPtr pColormap;
- DevUnion *privs;
-
- index = colormapPrivateCount++;
-
- for (i = 0; i < screenInfo.numScreens; i++)
- {
- /*
- * AllocateColormapPrivateIndex may be called after the
- * default colormap has been created on each screen!
- *
- * We must resize the devPrivates array for the default
- * colormap on each screen, making room for this new private.
- * We also call the initialization function 'initPrivFunc' on
- * the new private allocated for each default colormap.
- */
-
- ScreenPtr pScreen = screenInfo.screens[i];
+ type = type & TypeMask;
- pColormap = (ColormapPtr) LookupIDByType (
- pScreen->defColormap, RT_COLORMAP);
-
- if (pColormap)
- {
- privs = (DevUnion *) xrealloc (pColormap->devPrivates,
- colormapPrivateCount * sizeof(DevUnion));
- if (!privs) {
- colormapPrivateCount--;
- return -1;
- }
- bzero(&privs[index], sizeof(DevUnion));
- pColormap->devPrivates = privs;
- if (!(*initPrivFunc)(pColormap,index))
- {
- colormapPrivateCount--;
- return -1;
- }
+ /* 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;
}
- return index;
+ offsets[type] = offset;
+ return TRUE;
}
-/*
- * device private machinery
- */
-
-static int devicePrivateIndex = 0;
-
_X_EXPORT int
-AllocateDevicePrivateIndex(void)
+dixLookupPrivateOffset(RESTYPE type)
{
- return devicePrivateIndex++;
+ type = type & TypeMask;
+ assert(type < offsetsSize);
+ return offsets[type];
}
-_X_EXPORT Bool
-AllocateDevicePrivate(DeviceIntPtr device, int index)
+int
+dixResetPrivates(void)
{
- if (device->nPrivates < ++index) {
- DevUnion *nprivs = (DevUnion *) xrealloc(device->devPrivates,
- index * sizeof(DevUnion));
- if (!nprivs)
- return FALSE;
- device->devPrivates = nprivs;
- bzero(&nprivs[device->nPrivates], sizeof(DevUnion)
- * (index - device->nPrivates));
- device->nPrivates = index;
- return TRUE;
- } else {
- return TRUE;
- }
-}
+ PrivateDescRec *next;
-void
-ResetDevicePrivateIndex(void)
-{
- devicePrivateIndex = 0;
+ /* reset internal structures */
+ while (items) {
+ next = items->next;
+ xfree(items);
+ items = next;
+ }
+ if (offsets)
+ xfree(offsets);
+ offsetsSize = sizeof(offsetDefaults);
+ offsets = (int *)xalloc(offsetsSize);
+ offsetsSize /= sizeof(int);
+ if (!offsets)
+ return FALSE;
+ memcpy(offsets, offsetDefaults, sizeof(offsetDefaults));
+ return TRUE;
}