[PATCH 2/3] Introduce per-object per-screen privates.

Jamey Sharp jamey at minilop.net
Fri Sep 17 02:48:33 PDT 2010


This replaces dixCreatePrivateKey and the only uses, which were in
midispcur.

Bonus: If you only have one screen, this avoids an allocation.

Commit by Jamey Sharp and Josh Triplett.

Signed-off-by: Jamey Sharp <jamey at minilop.net>
Signed-off-by: Josh Triplett <josh at joshtriplett.org>
---
 dix/privates.c           |   55 +++++++++++++++++++++++++++++----------------
 doc/xml/Xserver-spec.xml |   12 +++++-----
 include/privates.h       |   51 +++++++++++++++++++++++++++++++++---------
 mi/midispcur.c           |   42 ++++++++++++++++-------------------
 4 files changed, 100 insertions(+), 60 deletions(-)

diff --git a/dix/privates.c b/dix/privates.c
index 17e1050..cec13e3 100644
--- a/dix/privates.c
+++ b/dix/privates.c
@@ -237,28 +237,43 @@ dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size)
     return TRUE;
 }
 
-/*
- * Allocate a new private key.
- *
- * This manages the storage of the key object itself, freeing it when the
- * privates system is restarted at server reset time. All other keys
- * are expected to be statically allocated as the privates must be
- * reset after all objects have been freed
- */
-DevPrivateKey
-dixCreatePrivateKey(DevPrivateType type, unsigned size)
+Bool
+dixRegisterScreenPrivateKey(DevScreenPrivateKey key, ScreenPtr pScreen, DevPrivateType type, unsigned size)
 {
-    DevPrivateKey	key;
-
-    key = calloc(sizeof (DevPrivateKeyRec), 1);
-    if (!key)
-	return NULL;
-    if (!dixRegisterPrivateKey(key, type, size)) {
-	free(key);
-	return NULL;
+#ifdef PANORAMIX
+    if (!noPanoramiXExtension) {
+        DevPrivateKey real;
+        if (!dixRegisterPrivateKey(&key->screenKey, PRIVATE_SCREEN, 0))
+            return FALSE;
+        real = dixGetPrivate(&pScreen->devPrivates, &key->screenKey);
+        if (real != NULL) {
+            assert(real->size == size);
+            assert(real->type == type);
+            return TRUE;
+        }
+        real = calloc(1, sizeof (DevPrivateKeyRec));
+        if (real == NULL)
+            return FALSE;
+        if (!dixRegisterPrivateKey(real, type, size)) {
+            free(real);
+            return FALSE;
+        }
+        real->allocated = TRUE;
+        dixSetPrivate(&pScreen->devPrivates, &key->screenKey, real);
+        return TRUE;
     }
-    key->allocated = TRUE;
-    return key;
+#endif
+    return dixRegisterPrivateKey(&key->screenKey, type, size);
+}
+
+DevPrivateKey
+_dixGetScreenPrivateKey(const DevScreenPrivateKey key, ScreenPtr pScreen)
+{
+#ifdef PANORAMIX
+    if (!noPanoramiXExtension)
+        return dixGetPrivate(&pScreen->devPrivates, &key->screenKey);
+#endif
+    return &key->screenKey;
 }
 
 /*
diff --git a/doc/xml/Xserver-spec.xml b/doc/xml/Xserver-spec.xml
index a9fbfaf..61d2ae6 100644
--- a/doc/xml/Xserver-spec.xml
+++ b/doc/xml/Xserver-spec.xml
@@ -4757,16 +4757,16 @@ If the function is called more than once on the same key, all calls must use
 the same value for <type>size</type> or the server will abort.</para>
 
 <para>
-To request private space and have the server manage the key, use
+To request per-screen private space in an object, use
 <blockquote><programlisting>
-	DevPrivateKey dixCreatePrivateKey(DevPrivateType type, unsigned size);
+	Bool dixRegisterScreenPrivateKey(DevScreenPrivateKey key, ScreenPtr pScreen, DevPrivateType type, unsigned size);
 </programlisting></blockquote>
 The <parameter>type</parameter> and <parameter>size</parameter> arguments are
 the same as those to <function>dixRegisterPrivateKey</function> but this
-function allocates a <type>DevPrivateKeyRec</type> and returns a pointer to it
-instead of requiring the caller to pass a pointer to an existing structure.
-The server will free it automatically when the privates system is restarted
-at server reset time.</para>
+function ensures the given <parameter>key</parameter> exists on objects of
+the specified type with distinct storage for the given
+<parameter>pScreen</parameter>. The key is usable on ScreenPrivate variants
+that are otherwise equivalent to the following Private functions.</para>
 
 <para>
 To attach a piece of private data to an object, use:
diff --git a/include/privates.h b/include/privates.h
index d3c0e13..9fb6ae8 100644
--- a/include/privates.h
+++ b/include/privates.h
@@ -65,6 +65,10 @@ typedef struct _DevPrivateKeyRec {
     struct _DevPrivateKeyRec	*next;
 } DevPrivateKeyRec, *DevPrivateKey;
 
+typedef struct _DevScreenPrivateKeyRec {
+    DevPrivateKeyRec	screenKey;
+} DevScreenPrivateKeyRec, *DevScreenPrivateKey;
+
 /*
  * Let drivers know how to initialize private keys
  */
@@ -100,17 +104,6 @@ dixPrivateKeyRegistered(DevPrivateKey key)
 }
 
 /*
- * Allocate a new private key.
- *
- * This manages the storage of the key object itself, freeing it when the
- * privates system is restarted at server reset time. All other keys
- * are expected to be statically allocated as the privates must be
- * reset after all objects have been freed
- */
-extern _X_EXPORT DevPrivateKey
-dixCreatePrivateKey(DevPrivateType type, unsigned size);
-
-/*
  * Get the address of the private storage.
  *
  * For keys with pre-defined storage, this gets the base of that storage
@@ -180,6 +173,42 @@ dixLookupPrivateAddr(PrivatePtr *privates, const DevPrivateKey key)
     return (pointer *)dixGetPrivateAddr(privates, key);
 }
 
+extern _X_EXPORT Bool
+dixRegisterScreenPrivateKey(DevScreenPrivateKey key, ScreenPtr pScreen, DevPrivateType type, unsigned size);
+
+extern _X_EXPORT DevPrivateKey
+_dixGetScreenPrivateKey(const DevScreenPrivateKey key, ScreenPtr pScreen);
+
+static inline void *
+dixGetScreenPrivateAddr(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen)
+{
+    return dixGetPrivateAddr(privates, _dixGetScreenPrivateKey(key, pScreen));
+}
+
+static inline void *
+dixGetScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen)
+{
+    return dixGetPrivate(privates, _dixGetScreenPrivateKey(key, pScreen));
+}
+
+static inline void
+dixSetScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen, pointer val)
+{
+    return dixSetPrivate(privates, _dixGetScreenPrivateKey(key, pScreen), val);
+}
+
+static inline pointer
+dixLookupScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen)
+{
+    return dixLookupPrivate(privates, _dixGetScreenPrivateKey(key, pScreen));
+}
+
+static inline pointer *
+dixLookupScreenPrivateAddr(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen)
+{
+    return dixLookupPrivateAddr(privates, _dixGetScreenPrivateKey(key, pScreen));
+}
+
 /*
  * Allocates private data separately from main object.
  *
diff --git a/mi/midispcur.c b/mi/midispcur.c
index 455b5b0..7ac7fd6 100644
--- a/mi/midispcur.c
+++ b/mi/midispcur.c
@@ -56,6 +56,10 @@ in this Software without prior written authorization from The Open Group.
 /* per-screen private data */
 static DevPrivateKeyRec miDCScreenKeyRec;
 #define miDCScreenKey (&miDCScreenKeyRec)
+static DevScreenPrivateKeyRec miDCCursorBitsKeyRec;
+#define miDCCursorBitsKey (&miDCCursorBitsKeyRec)
+static DevScreenPrivateKeyRec miDCDeviceKeyRec;
+#define miDCDeviceKey (&miDCDeviceKeyRec)
 
 static Bool	miDCCloseScreen(int index, ScreenPtr pScreen);
 
@@ -71,8 +75,8 @@ typedef struct {
 
 #define miGetDCDevice(dev, screen) \
  ((DevHasCursor(dev)) ? \
-  (miDCBufferPtr)dixLookupPrivate(&dev->devPrivates, miDCDeviceKey(screen)) : \
-  (miDCBufferPtr)dixLookupPrivate(&dev->u.master->devPrivates, miDCDeviceKey(screen)))
+  (miDCBufferPtr)dixLookupScreenPrivate(&dev->devPrivates, miDCDeviceKey, screen) : \
+  (miDCBufferPtr)dixLookupScreenPrivate(&dev->u.master->devPrivates, miDCDeviceKey, screen))
 
 /* 
  * The core pointer buffer will point to the index of the virtual core pointer
@@ -80,13 +84,9 @@ typedef struct {
  */
 typedef struct {
     CloseScreenProcPtr	CloseScreen;
-    DevPrivateKey	device_key;
-    DevPrivateKey	cursor_bits_key;
 } miDCScreenRec, *miDCScreenPtr;
 
 #define miGetDCScreen(s)	((miDCScreenPtr)(dixLookupPrivate(&(s)->devPrivates, miDCScreenKey)))
-#define miDCDeviceKey(s) 	(miGetDCScreen(s)->device_key)
-#define miDCCursorBitsKey(s)	(miGetDCScreen(s)->cursor_bits_key)
 
 /* per-cursor per-screen private data */
 typedef struct {
@@ -102,19 +102,15 @@ miDCInitialize (ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs)
 {
     miDCScreenPtr   pScreenPriv;
 
-    if (!dixRegisterPrivateKey(&miDCScreenKeyRec, PRIVATE_SCREEN, 0))
+    if (!dixRegisterPrivateKey(&miDCScreenKeyRec, PRIVATE_SCREEN, 0) ||
+        !dixRegisterScreenPrivateKey(&miDCCursorBitsKeyRec, pScreen, PRIVATE_CURSOR_BITS, 0) ||
+        !dixRegisterScreenPrivateKey(&miDCDeviceKeyRec, pScreen, PRIVATE_DEVICE, 0))
 	return FALSE;
 
     pScreenPriv = malloc(sizeof (miDCScreenRec));
     if (!pScreenPriv)
 	return FALSE;
 
-    pScreenPriv->cursor_bits_key = dixCreatePrivateKey(PRIVATE_CURSOR_BITS, 0);
-    pScreenPriv->device_key = dixCreatePrivateKey(PRIVATE_DEVICE, 0);
-    if (!pScreenPriv->cursor_bits_key || !pScreenPriv->device_key) {
-	free(pScreenPriv);
-	return FALSE;
-    }
     pScreenPriv->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = miDCCloseScreen;
 
@@ -144,7 +140,7 @@ Bool
 miDCRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
 {
     if (pCursor->bits->refcnt <= 1)
-	dixSetPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey(pScreen), NULL);
+	dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey, pScreen, NULL);
     return TRUE;
 }
 
@@ -243,7 +239,7 @@ miDCRealize (ScreenPtr pScreen, CursorPtr pCursor)
 	    free((pointer) pPriv);
 	    return NULL;
 	}
-	dixSetPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey(pScreen), pPriv);
+	dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey, pScreen, pPriv);
 	return pPriv;
     }
     pPriv->pPicture = 0;
@@ -261,7 +257,7 @@ miDCRealize (ScreenPtr pScreen, CursorPtr pCursor)
 	free((pointer) pPriv);
 	return NULL;
     }
-    dixSetPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey(pScreen), pPriv);
+    dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey, pScreen, pPriv);
 
     /* create the two sets of bits, clipping as appropriate */
 
@@ -305,8 +301,8 @@ miDCUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
 {
     miDCCursorPtr   pPriv;
 
-    pPriv = (miDCCursorPtr)dixLookupPrivate(&pCursor->bits->devPrivates,
-					    miDCCursorBitsKey(pScreen));
+    pPriv = (miDCCursorPtr)dixLookupScreenPrivate(&pCursor->bits->devPrivates,
+						  miDCCursorBitsKey, pScreen);
     if (pPriv && (pCursor->bits->refcnt <= 1))
     {
 	if (pPriv->sourceBits)
@@ -318,7 +314,7 @@ miDCUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
 	    FreePicture (pPriv->pPicture, 0);
 #endif
 	free((pointer) pPriv);
-	dixSetPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey(pScreen), NULL);
+	dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey, pScreen, NULL);
     }
     return TRUE;
 }
@@ -406,8 +402,8 @@ miDCPutUpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
     miDCBufferPtr   pBuffer;
     WindowPtr	    pWin;
 
-    pPriv = (miDCCursorPtr)dixLookupPrivate(&pCursor->bits->devPrivates,
-					    miDCCursorBitsKey(pScreen));
+    pPriv = (miDCCursorPtr)dixLookupScreenPrivate(&pCursor->bits->devPrivates,
+						  miDCCursorBitsKey, pScreen);
     if (!pPriv)
     {
 	pPriv = miDCRealize(pScreen, pCursor);
@@ -523,7 +519,7 @@ miDCDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
         if (!pBuffer)
             goto failure;
 
-        dixSetPrivate(&pDev->devPrivates, miDCDeviceKey(pScreen), pBuffer);
+        dixSetScreenPrivate(&pDev->devPrivates, miDCDeviceKey, pScreen, pBuffer);
         pWin = pScreen->root;
 
         pBuffer->pSourceGC = miDCMakeGC(pWin);
@@ -589,7 +585,7 @@ miDCDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
                 if (pBuffer->pSave) FreePixmap(pBuffer->pSave);
 
                 free(pBuffer);
-                dixSetPrivate(&pDev->devPrivates, miDCDeviceKey(pScreen), NULL);
+                dixSetScreenPrivate(&pDev->devPrivates, miDCDeviceKey, pScreen, NULL);
             }
         }
     }
-- 
1.7.0



More information about the xorg-devel mailing list