aboutsummaryrefslogtreecommitdiff
path: root/xorg-server
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server')
-rw-r--r--xorg-server/Xi/extinit.c2
-rw-r--r--xorg-server/dix/devices.c22
-rw-r--r--xorg-server/dix/dispatch.c3
-rw-r--r--xorg-server/dix/gc.c2
-rw-r--r--xorg-server/dix/main.c1
-rw-r--r--xorg-server/dix/pixmap.c4
-rw-r--r--xorg-server/dix/privates.c405
-rw-r--r--xorg-server/dix/touch.c11
-rw-r--r--xorg-server/dix/window.c4
-rw-r--r--xorg-server/doc/Xserver-spec.xml26
-rw-r--r--xorg-server/exa/exa.c10
-rw-r--r--xorg-server/exa/exa_priv.h12
-rw-r--r--xorg-server/fb/fb.h23
-rw-r--r--xorg-server/fb/fballpriv.c29
-rw-r--r--xorg-server/fb/fboverlay.c4
-rw-r--r--xorg-server/fb/fbscreen.c4
-rw-r--r--xorg-server/fb/fbwindow.c2
-rw-r--r--xorg-server/fb/wfbrename.h4
-rw-r--r--xorg-server/glx/clientinfo.c27
-rw-r--r--xorg-server/glx/createcontext.c101
-rw-r--r--xorg-server/glx/extension_string.c2
-rw-r--r--xorg-server/glx/extension_string.h2
-rw-r--r--xorg-server/glx/glxcmds.c10
-rw-r--r--xorg-server/glx/glxcontext.h5
-rw-r--r--xorg-server/glx/glxdri2.c97
-rw-r--r--xorg-server/glx/glxserver.h1
-rw-r--r--xorg-server/hw/dmx/input/dmxevents.c24
-rw-r--r--xorg-server/hw/dmx/input/dmxsigio.c22
-rw-r--r--xorg-server/hw/dmx/input/dmxsigio.h2
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr.c24
-rw-r--r--xorg-server/hw/kdrive/src/kinput.c40
-rw-r--r--xorg-server/hw/xfree86/common/xf86Config.c1
-rw-r--r--xorg-server/hw/xfree86/common/xf86Cursor.c12
-rw-r--r--xorg-server/hw/xfree86/common/xf86Events.c14
-rw-r--r--xorg-server/hw/xfree86/common/xf86Init.c9
-rw-r--r--xorg-server/hw/xfree86/common/xf86PM.c12
-rw-r--r--xorg-server/hw/xfree86/loader/loader.c6
-rw-r--r--xorg-server/hw/xfree86/loader/loader.h1
-rw-r--r--xorg-server/hw/xfree86/loader/loadmod.c2
-rw-r--r--xorg-server/hw/xfree86/os-support/shared/sigio.c24
-rw-r--r--xorg-server/include/list.h2
-rw-r--r--xorg-server/include/os.h6
-rw-r--r--xorg-server/include/privates.h56
-rw-r--r--xorg-server/include/scrnintstr.h2
-rw-r--r--xorg-server/mi/midispcur.c189
-rw-r--r--xorg-server/os/utils.c54
-rw-r--r--xorg-server/render/picture.c5
-rw-r--r--xorg-server/test/Makefile.am3
-rw-r--r--xorg-server/test/os.c130
-rw-r--r--xorg-server/xkb/xkbAccessX.c10
50 files changed, 1051 insertions, 412 deletions
diff --git a/xorg-server/Xi/extinit.c b/xorg-server/Xi/extinit.c
index 494e887cd..94f46f72f 100644
--- a/xorg-server/Xi/extinit.c
+++ b/xorg-server/Xi/extinit.c
@@ -365,7 +365,7 @@ RESTYPE RT_INPUTCLIENT;
extern XExtensionVersion XIVersion;
-Mask PropagateMask[MAXDEVICES];
+Mask PropagateMask[EMASKSIZE];
/*****************************************************************
*
diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c
index 08875bc3a..70fb273c9 100644
--- a/xorg-server/dix/devices.c
+++ b/xorg-server/dix/devices.c
@@ -246,13 +246,17 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
if (devid >= MAXDEVICES)
return (DeviceIntPtr) NULL;
- dev =
- _dixAllocateObjectWithPrivates(sizeof(DeviceIntRec) +
- sizeof(SpriteInfoRec),
- sizeof(DeviceIntRec) +
- sizeof(SpriteInfoRec),
- offsetof(DeviceIntRec, devPrivates),
- PRIVATE_DEVICE);
+ dev = calloc(1,
+ sizeof(DeviceIntRec) +
+ sizeof(SpriteInfoRec));
+ if (!dev)
+ return (DeviceIntPtr) NULL;
+
+ if (!dixAllocatePrivates(&dev->devPrivates, PRIVATE_DEVICE)) {
+ free(dev);
+ return NULL;
+ }
+
if (!dev)
return (DeviceIntPtr) NULL;
@@ -282,6 +286,7 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
/* security creation/labeling check
*/
if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) {
+ dixFreePrivates(dev->devPrivates, PRIVATE_DEVICE);
free(dev);
return NULL;
}
@@ -961,7 +966,8 @@ CloseDevice(DeviceIntPtr dev)
free(dev->last.touches[j].valuators);
free(dev->last.touches);
dev->config_info = NULL;
- dixFreeObjectWithPrivates(dev, PRIVATE_DEVICE);
+ dixFreePrivates(dev->devPrivates, PRIVATE_DEVICE);
+ free(dev);
}
/**
diff --git a/xorg-server/dix/dispatch.c b/xorg-server/dix/dispatch.c
index b88f9744d..7d2d3b727 100644
--- a/xorg-server/dix/dispatch.c
+++ b/xorg-server/dix/dispatch.c
@@ -3743,6 +3743,8 @@ AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
if (!pScreen)
return -1;
+ dixInitScreenSpecificPrivates(pScreen);
+
if (!dixAllocatePrivates(&pScreen->devPrivates, PRIVATE_SCREEN)) {
free(pScreen);
return -1;
@@ -3794,6 +3796,7 @@ AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
screenInfo.screens[i] = pScreen;
screenInfo.numScreens++;
if (!(*pfnInit) (pScreen, argc, argv)) {
+ dixFreeScreenSpecificPrivates(pScreen);
dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
free(pScreen);
screenInfo.numScreens--;
diff --git a/xorg-server/dix/gc.c b/xorg-server/dix/gc.c
index ac67643cf..60f54ec31 100644
--- a/xorg-server/dix/gc.c
+++ b/xorg-server/dix/gc.c
@@ -463,7 +463,7 @@ NewGCObject(ScreenPtr pScreen, int depth)
{
GCPtr pGC;
- pGC = dixAllocateObjectWithPrivates(GC, PRIVATE_GC);
+ pGC = dixAllocateScreenObjectWithPrivates(pScreen, GC, PRIVATE_GC);
if (!pGC) {
return (GCPtr) NULL;
}
diff --git a/xorg-server/dix/main.c b/xorg-server/dix/main.c
index e95ca1cc2..9524189d0 100644
--- a/xorg-server/dix/main.c
+++ b/xorg-server/dix/main.c
@@ -329,6 +329,7 @@ main(int argc, char *argv[], char *envp[])
FreeScratchPixmapsForScreen(screenInfo.screens[i]);
FreeGCperDepth(i);
FreeDefaultStipple(i);
+ dixFreeScreenSpecificPrivates(screenInfo.screens[i]);
(*screenInfo.screens[i]->CloseScreen) (screenInfo.screens[i]);
dixFreePrivates(screenInfo.screens[i]->devPrivates, PRIVATE_SCREEN);
free(screenInfo.screens[i]);
diff --git a/xorg-server/dix/pixmap.c b/xorg-server/dix/pixmap.c
index 545ff54ac..0c85c3fb1 100644
--- a/xorg-server/dix/pixmap.c
+++ b/xorg-server/dix/pixmap.c
@@ -88,7 +88,7 @@ CreateScratchPixmapsForScreen(ScreenPtr pScreen)
{
unsigned int pixmap_size;
- pixmap_size = sizeof(PixmapRec) + dixPrivatesSize(PRIVATE_PIXMAP);
+ pixmap_size = sizeof(PixmapRec) + dixScreenSpecificPrivatesSize(pScreen, PRIVATE_PIXMAP);
pScreen->totalPixmapSize =
BitmapBytePad(pixmap_size * 8);
@@ -118,7 +118,7 @@ AllocatePixmap(ScreenPtr pScreen, int pixDataSize)
if (!pPixmap)
return NullPixmap;
- dixInitPrivates(pPixmap, pPixmap + 1, PRIVATE_PIXMAP);
+ dixInitScreenPrivates(pScreen, pPixmap, pPixmap + 1, PRIVATE_PIXMAP);
return pPixmap;
}
diff --git a/xorg-server/dix/privates.c b/xorg-server/dix/privates.c
index 15fbf7590..b58085ffd 100644
--- a/xorg-server/dix/privates.c
+++ b/xorg-server/dix/privates.c
@@ -62,13 +62,9 @@ from The Open Group.
#include "inputstr.h"
#include "scrnintstr.h"
#include "extnsionst.h"
+#include "inputstr.h"
-static struct {
- DevPrivateKey key;
- unsigned offset;
- int created;
- int allocated;
-} keys[PRIVATE_LAST];
+static DevPrivateSetRec global_keys[PRIVATE_LAST];
static const Bool xselinux_private[PRIVATE_LAST] = {
[PRIVATE_SCREEN] = TRUE,
@@ -86,8 +82,57 @@ static const Bool xselinux_private[PRIVATE_LAST] = {
[PRIVATE_GLYPHSET] = TRUE,
};
+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",
+ [PRIVATE_DEVICE] = "DEVICE",
+
+ /* These cannot have any objects before all relevant keys are registered */
+ [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",
+ [PRIVATE_SYNC_FENCE] = "SYNC_FENCE",
+};
+
+static const Bool screen_specific_private[PRIVATE_LAST] = {
+ [PRIVATE_SCREEN] = FALSE,
+ [PRIVATE_CLIENT] = FALSE,
+ [PRIVATE_WINDOW] = TRUE,
+ [PRIVATE_PIXMAP] = TRUE,
+ [PRIVATE_GC] = TRUE,
+ [PRIVATE_CURSOR] = FALSE,
+ [PRIVATE_COLORMAP] = FALSE,
+ [PRIVATE_DEVICE] = FALSE,
+ [PRIVATE_EXTENSION] = FALSE,
+ [PRIVATE_SELECTION] = FALSE,
+ [PRIVATE_PROPERTY] = FALSE,
+ [PRIVATE_PICTURE] = TRUE,
+ [PRIVATE_GLYPHSET] = FALSE,
+};
+
typedef Bool (*FixupFunc) (PrivatePtr *privates, int offset, unsigned bytes);
+typedef enum { FixupMove, FixupRealloc } FixupType;
+
static Bool
dixReallocPrivates(PrivatePtr *privates, int old_offset, unsigned bytes)
{
@@ -110,14 +155,72 @@ dixMovePrivates(PrivatePtr *privates, int new_offset, unsigned bytes)
}
static Bool
+fixupOneScreen(ScreenPtr pScreen, FixupFunc fixup, unsigned bytes)
+{
+ intptr_t dist;
+ char *old;
+ char *new;
+ DevPrivateKey *keyp, key;
+ DevPrivateType type;
+ int size;
+
+ old = (char *) pScreen->devPrivates;
+ size = global_keys[PRIVATE_SCREEN].offset;
+ if (!fixup (&pScreen->devPrivates, size, bytes))
+ return FALSE;
+
+ /* Screen privates can contain screen-specific private keys
+ * for other types. When they move, the linked list we use to
+ * track them gets scrambled. Fix that by computing the change
+ * in the location of each private adjusting our linked list
+ * pointers to match
+ */
+
+ new = (char *) pScreen->devPrivates;
+
+ /* Moving means everyone shifts up in the privates by 'bytes' amount,
+ * realloc means the base pointer moves
+ */
+ if (fixup == dixMovePrivates)
+ new += bytes;
+
+ dist = new - old;
+
+ if (dist) {
+ for (type = PRIVATE_XSELINUX; type < PRIVATE_LAST; type++)
+
+ /* Walk the privates list, being careful as the
+ * pointers are scrambled before we patch them.
+ */
+ for (keyp = &pScreen->screenSpecificPrivates[type].key;
+ (key = *keyp) != NULL;
+ keyp = &key->next)
+ {
+
+ /* Only mangle things if the private structure
+ * is contained within the allocation. Privates
+ * stored elsewhere will be left alone
+ */
+ if (old <= (char *) key && (char *) key < old + size)
+ {
+ /* Compute new location of key */
+ key = (DevPrivateKey) ((char *) key + dist);
+
+ /* Patch the list */
+ *keyp = key;
+ }
+ }
+ }
+ return TRUE;
+}
+
+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))
+ if (!fixupOneScreen (screenInfo.screens[s], fixup, bytes))
return FALSE;
return TRUE;
}
@@ -126,7 +229,7 @@ static Bool
fixupServerClient(FixupFunc fixup, unsigned bytes)
{
if (serverClient)
- return fixup(&serverClient->devPrivates, keys[PRIVATE_CLIENT].offset,
+ return fixup(&serverClient->devPrivates, global_keys[PRIVATE_CLIENT].offset,
bytes);
return TRUE;
}
@@ -140,7 +243,7 @@ fixupExtensions(FixupFunc fixup, unsigned bytes)
for (major = EXTENSION_BASE; (extension = GetExtensionEntry(major));
major++)
if (!fixup
- (&extension->devPrivates, keys[PRIVATE_EXTENSION].offset, bytes))
+ (&extension->devPrivates, global_keys[PRIVATE_EXTENSION].offset, bytes))
return FALSE;
return TRUE;
}
@@ -157,17 +260,60 @@ fixupDefaultColormaps(FixupFunc fixup, unsigned bytes)
screenInfo.screens[s]->defColormap, RT_COLORMAP,
serverClient, DixCreateAccess);
if (cmap &&
- !fixup(&cmap->devPrivates, keys[PRIVATE_COLORMAP].offset, bytes))
+ !fixup(&cmap->devPrivates, screenInfo.screens[s]->screenSpecificPrivates[PRIVATE_COLORMAP].offset, bytes))
return FALSE;
}
return TRUE;
}
+static Bool
+fixupDeviceList(DeviceIntPtr device, FixupFunc fixup, unsigned bytes)
+{
+ while (device) {
+ if (!fixup(&device->devPrivates, global_keys[PRIVATE_DEVICE].offset, bytes))
+ return FALSE;
+ device = device->next;
+ }
+ return TRUE;
+}
+
+static Bool
+fixupDevices(FixupFunc fixup, unsigned bytes)
+{
+ return (fixupDeviceList(inputInfo.devices, fixup, bytes) &&
+ fixupDeviceList(inputInfo.off_devices, fixup, bytes));
+}
+
static Bool (*const allocated_early[PRIVATE_LAST]) (FixupFunc, unsigned) = {
-[PRIVATE_SCREEN] = fixupScreens,
- [PRIVATE_CLIENT] = fixupServerClient,
- [PRIVATE_EXTENSION] = fixupExtensions,
- [PRIVATE_COLORMAP] = fixupDefaultColormaps,};
+ [PRIVATE_SCREEN] = fixupScreens,
+ [PRIVATE_CLIENT] = fixupServerClient,
+ [PRIVATE_EXTENSION] = fixupExtensions,
+ [PRIVATE_COLORMAP] = fixupDefaultColormaps,
+ [PRIVATE_DEVICE] = fixupDevices,
+};
+
+static void
+grow_private_set(DevPrivateSetPtr set, unsigned bytes)
+{
+ DevPrivateKey k;
+
+ for (k = set->key; k; k = k->next)
+ k->offset += bytes;
+ set->offset += bytes;
+}
+
+static void
+grow_screen_specific_set(DevPrivateType type, unsigned bytes)
+{
+ int s;
+
+ /* Update offsets for all screen-specific keys */
+ for (s = 0; s < screenInfo.numScreens; s++) {
+ ScreenPtr pScreen = screenInfo.screens[s];
+
+ grow_private_set(&pScreen->screenSpecificPrivates[type], bytes);
+ }
+}
/*
* Register a private key. This takes the type of object the key will
@@ -199,14 +345,13 @@ dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size)
/* 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);
+ assert(!global_keys[t].created);
else if (!allocated_early[t] (dixReallocPrivates, bytes))
return FALSE;
}
@@ -216,12 +361,12 @@ dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size)
*/
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;
+ grow_private_set(&global_keys[t], bytes);
+ grow_screen_specific_set(t, bytes);
if (allocated_early[t])
allocated_early[t] (dixMovePrivates, bytes);
}
+
}
offset = 0;
@@ -229,11 +374,12 @@ dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size)
else {
/* Resize if we can, or make sure nothing's allocated if we can't */
if (!allocated_early[type])
- assert(!keys[type].created);
+ assert(!global_keys[type].created);
else if (!allocated_early[type] (dixReallocPrivates, bytes))
return FALSE;
- offset = keys[type].offset;
- keys[type].offset += bytes;
+ offset = global_keys[type].offset;
+ global_keys[type].offset += bytes;
+ grow_screen_specific_set(type, bytes);
}
/* Setup this key */
@@ -242,8 +388,8 @@ dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size)
key->initialized = TRUE;
key->type = type;
key->allocated = FALSE;
- key->next = keys[type].key;
- keys[type].key = key;
+ key->next = global_keys[type].key;
+ global_keys[type].key = key;
return TRUE;
}
@@ -286,13 +432,15 @@ _dixGetScreenPrivateKey(const DevScreenPrivateKey key, ScreenPtr pScreen)
void
_dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type)
{
- keys[type].created++;
+ assert (!screen_specific_private[type]);
+
+ global_keys[type].created++;
if (xselinux_private[type])
- keys[PRIVATE_XSELINUX].created++;
- if (keys[type].offset == 0)
+ global_keys[PRIVATE_XSELINUX].created++;
+ if (global_keys[type].offset == 0)
addr = 0;
*privates = addr;
- memset(addr, '\0', keys[type].offset);
+ memset(addr, '\0', global_keys[type].offset);
}
/*
@@ -301,9 +449,9 @@ _dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type)
void
_dixFiniPrivates(PrivatePtr privates, DevPrivateType type)
{
- keys[type].created--;
+ global_keys[type].created--;
if (xselinux_private[type])
- keys[PRIVATE_XSELINUX].created--;
+ global_keys[PRIVATE_XSELINUX].created--;
}
/*
@@ -322,10 +470,11 @@ _dixAllocateObjectWithPrivates(unsigned baseSize, unsigned clear,
PrivatePtr *devPrivates;
assert(type > PRIVATE_SCREEN && type < PRIVATE_LAST);
+ assert(!screen_specific_private[type]);
/* round up so that void * is aligned */
baseSize = (baseSize + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
- totalSize = baseSize + keys[type].offset;
+ totalSize = baseSize + global_keys[type].offset;
object = malloc(totalSize);
if (!object)
return NULL;
@@ -350,8 +499,9 @@ dixAllocatePrivates(PrivatePtr *privates, DevPrivateType type)
PrivatePtr p;
assert(type > PRIVATE_XSELINUX && type < PRIVATE_LAST);
+ assert(!screen_specific_private[type]);
- size = keys[type].offset;
+ size = global_keys[type].offset;
if (!size) {
p = NULL;
}
@@ -361,7 +511,7 @@ dixAllocatePrivates(PrivatePtr *privates, DevPrivateType type)
}
_dixInitPrivates(privates, p, type);
- ++keys[type].allocated;
+ ++global_keys[type].allocated;
return TRUE;
}
@@ -387,7 +537,7 @@ void
dixFreePrivates(PrivatePtr privates, DevPrivateType type)
{
_dixFiniPrivates(privates, type);
- --keys[type].allocated;
+ --global_keys[type].allocated;
free(privates);
}
@@ -398,8 +548,9 @@ extern _X_EXPORT int
dixPrivatesSize(DevPrivateType type)
{
assert(type >= PRIVATE_SCREEN && type < PRIVATE_LAST);
+ assert (!screen_specific_private[type]);
- return keys[type].offset;
+ return global_keys[type].offset;
}
/* Table of devPrivates offsets */
@@ -434,36 +585,136 @@ dixLookupPrivateOffset(RESTYPE type)
return -1;
}
-static const char *key_names[PRIVATE_LAST] = {
- /* XSELinux uses the same private keys for numerous objects */
- [PRIVATE_XSELINUX] = "XSELINUX",
+/*
+ * Screen-specific privates
+ */
- /* 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",
+extern _X_EXPORT Bool
+dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key,
+ DevPrivateType type, unsigned size)
+{
+ int offset;
+ unsigned bytes;
- /* 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",
+ if (!screen_specific_private[type])
+ FatalError("Attempt to allocate screen-specific private storage for type %s\n",
+ key_names[type]);
- /* extension privates */
- [PRIVATE_DBE_WINDOW] = "DBE_WINDOW",
- [PRIVATE_DAMAGE] = "DAMAGE",
- [PRIVATE_GLYPH] = "GLYPH",
- [PRIVATE_GLYPHSET] = "GLYPHSET",
- [PRIVATE_PICTURE] = "PICTURE",
- [PRIVATE_SYNC_FENCE] = "SYNC_FENCE",
-};
+ if (key->initialized) {
+ assert(size == key->size);
+ return TRUE;
+ }
+
+ /* Compute required space */
+ bytes = size;
+ if (size == 0)
+ bytes = sizeof(void *);
+
+ /* align to void * size */
+ bytes = (bytes + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
+
+ assert (!allocated_early[type]);
+ assert (!pScreen->screenSpecificPrivates[type].created);
+ offset = pScreen->screenSpecificPrivates[type].offset;
+ pScreen->screenSpecificPrivates[type].offset += bytes;
+
+ /* Setup this key */
+ key->offset = offset;
+ key->size = size;
+ key->initialized = TRUE;
+ key->type = type;
+ key->allocated = FALSE;
+ key->next = pScreen->screenSpecificPrivates[type].key;
+ pScreen->screenSpecificPrivates[type].key = key;
+
+ return TRUE;
+}
+
+/* Clean up screen-specific privates before CloseScreen */
+void
+dixFreeScreenSpecificPrivates(ScreenPtr pScreen)
+{
+}
+
+/* Initialize screen-specific privates in AddScreen */
+void
+dixInitScreenSpecificPrivates(ScreenPtr pScreen)
+{
+ DevPrivateType t;
+
+ for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++)
+ pScreen->screenSpecificPrivates[t].offset = global_keys[t].offset;
+}
+
+/* Initialize screen-specific privates in AddScreen */
+void
+_dixInitScreenPrivates(ScreenPtr pScreen, PrivatePtr *privates, void *addr, DevPrivateType type)
+{
+ int privates_size;
+ assert (screen_specific_private[type]);
+
+ if (pScreen) {
+ privates_size = pScreen->screenSpecificPrivates[type].offset;
+ pScreen->screenSpecificPrivates[type].created++;
+ }
+ else
+ privates_size = global_keys[type].offset;
+
+ global_keys[type].created++;
+ if (xselinux_private[type])
+ global_keys[PRIVATE_XSELINUX].created++;
+ if (privates_size == 0)
+ addr = 0;
+ *privates = addr;
+ memset(addr, '\0', privates_size);
+}
+
+void *
+_dixAllocateScreenObjectWithPrivates(ScreenPtr pScreen,
+ unsigned baseSize,
+ unsigned clear,
+ unsigned offset,
+ DevPrivateType type)
+{
+ unsigned totalSize;
+ void *object;
+ PrivatePtr privates;
+ PrivatePtr *devPrivates;
+ int privates_size;
+
+ assert(type > PRIVATE_SCREEN && type < PRIVATE_LAST);
+ assert (screen_specific_private[type]);
+
+ if (pScreen)
+ privates_size = pScreen->screenSpecificPrivates[type].offset;
+ else
+ privates_size = global_keys[type].offset;
+ /* round up so that void * is aligned */
+ baseSize = (baseSize + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
+ totalSize = baseSize + privates_size;
+ object = malloc(totalSize);
+ if (!object)
+ return NULL;
+
+ memset(object, '\0', clear);
+ privates = (PrivatePtr) (((char *) object) + baseSize);
+ devPrivates = (PrivatePtr *) ((char *) object + offset);
+
+ _dixInitScreenPrivates(pScreen, devPrivates, privates, type);
+
+ return object;
+}
+
+int
+dixScreenSpecificPrivatesSize(ScreenPtr pScreen, DevPrivateType type)
+{
+ assert(type >= PRIVATE_SCREEN && type < PRIVATE_LAST);
+
+ if (screen_specific_private[type])
+ return pScreen->screenSpecificPrivates[type].offset;
+ else
+ return global_keys[type].offset;
+}
void
dixPrivateUsage(void)
@@ -474,14 +725,14 @@ dixPrivateUsage(void)
DevPrivateType t;
for (t = PRIVATE_XSELINUX + 1; t < PRIVATE_LAST; t++) {
- if (keys[t].offset) {
+ if (global_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;
+ key_names[t], global_keys[t].created, global_keys[t].offset,
+ global_keys[t].created * global_keys[t].offset, global_keys[t].allocated);
+ bytes += global_keys[t].created * global_keys[t].offset;
+ objects += global_keys[t].created;
+ alloc += global_keys[t].allocated;
}
}
ErrorF("TOTAL: %d objects, %d bytes, %d allocs\n", objects, bytes, alloc);
@@ -495,7 +746,7 @@ dixResetPrivates(void)
for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) {
DevPrivateKey key, next;
- for (key = keys[t].key; key; key = next) {
+ for (key = global_keys[t].key; key; key = next) {
next = key->next;
key->offset = 0;
key->initialized = FALSE;
@@ -504,14 +755,14 @@ dixResetPrivates(void)
if (key->allocated)
free(key);
}
- if (keys[t].created) {
+ if (global_keys[t].created) {
ErrorF("%d %ss still allocated at reset\n",
- keys[t].created, key_names[t]);
+ global_keys[t].created, key_names[t]);
dixPrivateUsage();
}
- keys[t].key = NULL;
- keys[t].offset = 0;
- keys[t].created = 0;
- keys[t].allocated = 0;
+ global_keys[t].key = NULL;
+ global_keys[t].offset = 0;
+ global_keys[t].created = 0;
+ global_keys[t].allocated = 0;
}
}
diff --git a/xorg-server/dix/touch.c b/xorg-server/dix/touch.c
index a01f152cd..497ad7dac 100644
--- a/xorg-server/dix/touch.c
+++ b/xorg-server/dix/touch.c
@@ -160,11 +160,13 @@ TouchBeginDDXTouch(DeviceIntPtr dev, uint32_t ddx_id)
int i;
TouchClassPtr t = dev->touch;
DDXTouchPointInfoPtr ti = NULL;
- Bool emulate_pointer = (t->mode == XIDirectTouch);
+ Bool emulate_pointer;
if (!t)
return NULL;
+ emulate_pointer = (t->mode == XIDirectTouch);
+
/* Look for another active touchpoint with the same DDX ID. DDX
* touchpoints must be unique. */
if (TouchFindByDDXID(dev, ddx_id, FALSE))
@@ -461,14 +463,17 @@ TouchEventHistoryPush(TouchPointInfoPtr ti, const DeviceEvent *ev)
void
TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource)
{
- InternalEvent *tel = InitEventList(GetMaximumEventsNum());
- ValuatorMask *mask = valuator_mask_new(0);
+ InternalEvent *tel;
+ ValuatorMask *mask;
int i, nev;
int flags;
if (!ti->history)
return;
+ tel = InitEventList(GetMaximumEventsNum());
+ mask = valuator_mask_new(0);
+
valuator_mask_set_double(mask, 0, ti->history[0].valuators.data[0]);
valuator_mask_set_double(mask, 1, ti->history[0].valuators.data[1]);
diff --git a/xorg-server/dix/window.c b/xorg-server/dix/window.c
index 5cc3a502d..b66080830 100644
--- a/xorg-server/dix/window.c
+++ b/xorg-server/dix/window.c
@@ -446,7 +446,7 @@ CreateRootWindow(ScreenPtr pScreen)
BoxRec box;
PixmapFormatRec *format;
- pWin = dixAllocateObjectWithPrivates(WindowRec, PRIVATE_WINDOW);
+ pWin = dixAllocateScreenObjectWithPrivates(pScreen, WindowRec, PRIVATE_WINDOW);
if (!pWin)
return FALSE;
@@ -710,7 +710,7 @@ CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w,
return NullWindow;
}
- pWin = dixAllocateObjectWithPrivates(WindowRec, PRIVATE_WINDOW);
+ pWin = dixAllocateScreenObjectWithPrivates(pScreen, WindowRec, PRIVATE_WINDOW);
if (!pWin) {
*error = BadAlloc;
return NullWindow;
diff --git a/xorg-server/doc/Xserver-spec.xml b/xorg-server/doc/Xserver-spec.xml
index 31b6fb05d..cd1a9d07a 100644
--- a/xorg-server/doc/Xserver-spec.xml
+++ b/xorg-server/doc/Xserver-spec.xml
@@ -109,6 +109,12 @@
<revremark>Revised for Xorg 1.9 devPrivates changes
and 1.8 CreateNewResourceType changes</revremark>
</revision>
+ <revision>
+ <revnumber>3.6</revnumber>
+ <date>July 2012</date>
+ <authorinitials>kp</authorinitials>
+ <revremark>Revised for X server 1.13 screen-specific devPrivates changes</revremark>
+ </revision>
</revhistory>
<abstract>
<para>The following document explains the structure of the X Window System display server and the interfaces among the larger pieces. It is intended as a reference for programmers who are implementing an X Display Server on their workstation hardware. It is included with the X Window System source tape, along with the document "Strategies for Porting the X v11 Sample Server." The order in which you should read these documents is:
@@ -4714,7 +4720,8 @@ Two new extensibility concepts have been developed for release 4, Wrappers
and devPrivates. These replace the R3 GCInterest queues, which were not a
general enough mechanism for many extensions and only provided hooks into a
single data structure. devPrivates have been revised substantially for
-X.Org X server release 1.5, and updated again for the 1.9 release.</para>
+X.Org X server release 1.5, updated again for the 1.9 release and extended
+again for the 1.13 relealse.</para>
<section>
<title>devPrivates</title>
<para>
@@ -4758,6 +4765,23 @@ the specified type with distinct storage for the given
that are otherwise equivalent to the following Private functions.</para>
<para>
+ To request private space in objects created for a specific screen, use
+ <blockquote><programlisting>
+ Bool dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key, 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 ensures only that the given <parameter>key</parameter> exists on objects of
+ the specified type that are allocated with reference to the specified
+ <parameter>pScreen</parameter>. Using the key on objects allocated for
+ other screens will result in incorrect results; there is no check made to
+ ensure that the caller's screen matches the private's screen. The key is
+ usable in any of the following functions. Screen-specific private storage is available
+ only for Windows, GCs, Pixmaps and Pictures. Attempts to allocate screen-specific
+ privates on other objects will result in a call to FatalError.
+</para>
+
+<para>
To attach a piece of private data to an object, use:
<blockquote><programlisting>
void dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
diff --git a/xorg-server/exa/exa.c b/xorg-server/exa/exa.c
index 0f90e593c..623ece073 100644
--- a/xorg-server/exa/exa.c
+++ b/xorg-server/exa/exa.c
@@ -38,8 +38,6 @@
#include "exa.h"
DevPrivateKeyRec exaScreenPrivateKeyRec;
-DevPrivateKeyRec exaPixmapPrivateKeyRec;
-DevPrivateKeyRec exaGCPrivateKeyRec;
#ifdef MITSHM
static ShmFuncs exaShmFuncs = { NULL, NULL };
@@ -915,8 +913,8 @@ exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo)
exaDDXDriverInit(pScreen);
- if (!dixRegisterPrivateKey
- (&exaGCPrivateKeyRec, PRIVATE_GC, sizeof(ExaGCPrivRec))) {
+ if (!dixRegisterScreenSpecificPrivateKey
+ (pScreen, &pExaScr->gcPrivateKeyRec, PRIVATE_GC, sizeof(ExaGCPrivRec))) {
LogMessage(X_WARNING, "EXA(%d): Failed to allocate GC private\n",
pScreen->myNum);
return FALSE;
@@ -964,8 +962,8 @@ exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo)
* Hookup offscreen pixmaps
*/
if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) {
- if (!dixRegisterPrivateKey
- (&exaPixmapPrivateKeyRec, PRIVATE_PIXMAP,
+ if (!dixRegisterScreenSpecificPrivateKey
+ (pScreen, &pExaScr->pixmapPrivateKeyRec, PRIVATE_PIXMAP,
sizeof(ExaPixmapPrivRec))) {
LogMessage(X_WARNING,
"EXA(%d): Failed to allocate pixmap private\n",
diff --git a/xorg-server/exa/exa_priv.h b/xorg-server/exa/exa_priv.h
index f980fea6d..68eadc550 100644
--- a/xorg-server/exa/exa_priv.h
+++ b/xorg-server/exa/exa_priv.h
@@ -208,6 +208,8 @@ typedef struct {
RegionRec maskReg;
PixmapPtr srcPix;
+ DevPrivateKeyRec pixmapPrivateKeyRec;
+ DevPrivateKeyRec gcPrivateKeyRec;
} ExaScreenPrivRec, *ExaScreenPrivPtr;
/*
@@ -225,17 +227,11 @@ typedef struct {
extern DevPrivateKeyRec exaScreenPrivateKeyRec;
#define exaScreenPrivateKey (&exaScreenPrivateKeyRec)
-extern DevPrivateKeyRec exaPixmapPrivateKeyRec;
-
-#define exaPixmapPrivateKey (&exaPixmapPrivateKeyRec)
-extern DevPrivateKeyRec exaGCPrivateKeyRec;
-
-#define exaGCPrivateKey (&exaGCPrivateKeyRec)
#define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)dixGetPrivate(&(s)->devPrivates, exaScreenPrivateKey))
#define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s)
-#define ExaGetGCPriv(gc) ((ExaGCPrivPtr)dixGetPrivateAddr(&(gc)->devPrivates, exaGCPrivateKey))
+#define ExaGetGCPriv(gc) ((ExaGCPrivPtr)dixGetPrivateAddr(&(gc)->devPrivates, &ExaGetScreenPriv(gc->pScreen)->gcPrivateKeyRec))
#define ExaGCPriv(gc) ExaGCPrivPtr pExaGC = ExaGetGCPriv(gc)
/*
@@ -286,7 +282,7 @@ extern DevPrivateKeyRec exaGCPrivateKeyRec;
#define EXA_PIXMAP_SCORE_PINNED 1000
#define EXA_PIXMAP_SCORE_INIT 1001
-#define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, exaPixmapPrivateKey))
+#define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &ExaGetScreenPriv((p)->drawable.pScreen)->pixmapPrivateKeyRec))
#define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p)
#define EXA_RANGE_PITCH (1 << 0)
diff --git a/xorg-server/fb/fb.h b/xorg-server/fb/fb.h
index cc3b6ee61..40a7e38db 100644
--- a/xorg-server/fb/fb.h
+++ b/xorg-server/fb/fb.h
@@ -570,12 +570,6 @@ extern _X_EXPORT void fbSetBits(FbStip * bits, int stride, FbStip data);
} \
}
-extern _X_EXPORT DevPrivateKey
- fbGetGCPrivateKey(void);
-
-extern _X_EXPORT DevPrivateKey
- fbGetWinPrivateKey(void);
-
extern _X_EXPORT const GCOps fbGCOps;
extern _X_EXPORT const GCFuncs fbGCFuncs;
@@ -605,7 +599,7 @@ typedef void (*FinishWrapProcPtr) (DrawablePtr pDraw);
#endif
extern _X_EXPORT DevPrivateKey
- fbGetScreenPrivateKey(void);
+fbGetScreenPrivateKey(void);
/* private field of a screen */
typedef struct {
@@ -615,6 +609,8 @@ typedef struct {
SetupWrapProcPtr setupWrap; /* driver hook to set pixmap access wrapping */
FinishWrapProcPtr finishWrap; /* driver hook to clean up pixmap access wrapping */
#endif
+ DevPrivateKeyRec gcPrivateKeyRec;
+ DevPrivateKeyRec winPrivateKeyRec;
} FbScreenPrivRec, *FbScreenPrivPtr;
#define fbGetScreenPrivate(pScreen) ((FbScreenPrivPtr) \
@@ -630,8 +626,10 @@ typedef struct {
unsigned char bpp; /* current drawable bpp */
} FbGCPrivRec, *FbGCPrivPtr;
+#define fbGetGCPrivateKey(pGC) (&fbGetScreenPrivate((pGC)->pScreen)->gcPrivateKeyRec)
+
#define fbGetGCPrivate(pGC) ((FbGCPrivPtr)\
- dixLookupPrivate(&(pGC)->devPrivates, fbGetGCPrivateKey()))
+ dixLookupPrivate(&(pGC)->devPrivates, fbGetGCPrivateKey(pGC)))
#define fbGetCompositeClip(pGC) ((pGC)->pCompositeClip)
#define fbGetExpose(pGC) ((pGC)->fExpose)
@@ -639,8 +637,11 @@ typedef struct {
#define fbGetRotatedPixmap(pGC) ((pGC)->pRotatedPixmap)
#define fbGetScreenPixmap(s) ((PixmapPtr) (s)->devPrivate)
+
+#define fbGetWinPrivateKey(pWin) (&fbGetScreenPrivate(((DrawablePtr) (pWin))->pScreen)->winPrivateKeyRec)
+
#define fbGetWindowPixmap(pWin) ((PixmapPtr)\
- dixLookupPrivate(&((WindowPtr)(pWin))->devPrivates, fbGetWinPrivateKey()))
+ dixLookupPrivate(&((WindowPtr)(pWin))->devPrivates, fbGetWinPrivateKey(pWin)))
#ifdef ROOTLESS
#define __fbPixDrawableX(pPix) ((pPix)->drawable.x)
@@ -782,14 +783,14 @@ fb24_32ModifyPixmapHeader(PixmapPtr pPixmap,
* fballpriv.c
*/
extern _X_EXPORT Bool
- fbAllocatePrivates(ScreenPtr pScreen, DevPrivateKey *pGCIndex);
+fbAllocatePrivates(ScreenPtr pScreen);
/*
* fbarc.c
*/
extern _X_EXPORT void
- fbPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * parcs);
+fbPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * parcs);
/*
* fbbits.c
diff --git a/xorg-server/fb/fballpriv.c b/xorg-server/fb/fballpriv.c
index c6504f915..187d0b068 100644
--- a/xorg-server/fb/fballpriv.c
+++ b/xorg-server/fb/fballpriv.c
@@ -33,33 +33,20 @@ fbGetScreenPrivateKey(void)
return &fbScreenPrivateKeyRec;
}
-static DevPrivateKeyRec fbGCPrivateKeyRec;
-DevPrivateKey
-fbGetGCPrivateKey(void)
-{
- return &fbGCPrivateKeyRec;
-}
-
-static DevPrivateKeyRec fbWinPrivateKeyRec;
-DevPrivateKey
-fbGetWinPrivateKey(void)
-{
- return &fbWinPrivateKeyRec;
-}
-
Bool
-fbAllocatePrivates(ScreenPtr pScreen, DevPrivateKey *pGCKey)
+fbAllocatePrivates(ScreenPtr pScreen)
{
- if (pGCKey)
- *pGCKey = &fbGCPrivateKeyRec;
+ FbScreenPrivPtr pScrPriv;
if (!dixRegisterPrivateKey
- (&fbGCPrivateKeyRec, PRIVATE_GC, sizeof(FbGCPrivRec)))
- return FALSE;
- if (!dixRegisterPrivateKey
(&fbScreenPrivateKeyRec, PRIVATE_SCREEN, sizeof(FbScreenPrivRec)))
return FALSE;
- if (!dixRegisterPrivateKey(&fbWinPrivateKeyRec, PRIVATE_WINDOW, 0))
+
+ pScrPriv = fbGetScreenPrivate(pScreen);
+
+ if (!dixRegisterScreenSpecificPrivateKey (pScreen, &pScrPriv->gcPrivateKeyRec, PRIVATE_GC, sizeof(FbGCPrivRec)))
+ return FALSE;
+ if (!dixRegisterScreenSpecificPrivateKey (pScreen, &pScrPriv->winPrivateKeyRec, PRIVATE_WINDOW, 0))
return FALSE;
return TRUE;
diff --git a/xorg-server/fb/fboverlay.c b/xorg-server/fb/fboverlay.c
index a882ffa39..c6802e4b4 100644
--- a/xorg-server/fb/fboverlay.c
+++ b/xorg-server/fb/fboverlay.c
@@ -63,7 +63,7 @@ fbOverlayCreateWindow(WindowPtr pWin)
for (i = 0; i < pScrPriv->nlayers; i++) {
pPixmap = pScrPriv->layer[i].u.run.pixmap;
if (pWin->drawable.depth == pPixmap->drawable.depth) {
- dixSetPrivate(&pWin->devPrivates, fbGetWinPrivateKey(), pPixmap);
+ dixSetPrivate(&pWin->devPrivates, fbGetWinPrivateKey(pWin), pPixmap);
/*
* Make sure layer keys are written correctly by
* having non-root layers set to full while the
@@ -103,7 +103,7 @@ fbOverlayWindowLayer(WindowPtr pWin)
int i;
for (i = 0; i < pScrPriv->nlayers; i++)
- if (dixLookupPrivate(&pWin->devPrivates, fbGetWinPrivateKey()) ==
+ if (dixLookupPrivate(&pWin->devPrivates, fbGetWinPrivateKey(pWin)) ==
(pointer) pScrPriv->layer[i].u.run.pixmap)
return i;
return 0;
diff --git a/xorg-server/fb/fbscreen.c b/xorg-server/fb/fbscreen.c
index 0833cd41e..7c7d6560e 100644
--- a/xorg-server/fb/fbscreen.c
+++ b/xorg-server/fb/fbscreen.c
@@ -85,7 +85,7 @@ _fbGetWindowPixmap(WindowPtr pWindow)
void
_fbSetWindowPixmap(WindowPtr pWindow, PixmapPtr pPixmap)
{
- dixSetPrivate(&pWindow->devPrivates, fbGetWinPrivateKey(), pPixmap);
+ dixSetPrivate(&pWindow->devPrivates, fbGetWinPrivateKey(pWindow), pPixmap);
}
Bool
@@ -95,7 +95,7 @@ fbSetupScreen(ScreenPtr pScreen, pointer pbits, /* pointer to screen bitmap */
int dpiy, int width, /* pixel width of frame buffer */
int bpp)
{ /* bits per pixel for screen */
- if (!fbAllocatePrivates(pScreen, NULL))
+ if (!fbAllocatePrivates(pScreen))
return FALSE;
pScreen->defColormap = FakeClientID(0);
/* let CreateDefColormap do whatever it wants for pixels */
diff --git a/xorg-server/fb/fbwindow.c b/xorg-server/fb/fbwindow.c
index d27ccd4d5..368c4b883 100644
--- a/xorg-server/fb/fbwindow.c
+++ b/xorg-server/fb/fbwindow.c
@@ -31,7 +31,7 @@
Bool
fbCreateWindow(WindowPtr pWin)
{
- dixSetPrivate(&pWin->devPrivates, fbGetWinPrivateKey(),
+ dixSetPrivate(&pWin->devPrivates, fbGetWinPrivateKey(pWin),
fbGetScreenPixmap(pWin->drawable.pScreen));
if (pWin->drawable.bitsPerPixel == 32)
pWin->drawable.bitsPerPixel =
diff --git a/xorg-server/fb/wfbrename.h b/xorg-server/fb/wfbrename.h
index 8b896eb9a..588440c2b 100644
--- a/xorg-server/fb/wfbrename.h
+++ b/xorg-server/fb/wfbrename.h
@@ -69,15 +69,11 @@
#define fbFixCoordModePrevious wfbFixCoordModePrevious
#define fbGCFuncs wfbGCFuncs
#define fbGCOps wfbGCOps
-#define fbGCPrivateKeyRec wfbGCPrivateKeyRec
#define fbGeneration wfbGeneration
-#define fbGetGCPrivateKey wfbGetGCPrivateKey
#define fbGetImage wfbGetImage
#define fbGetScreenPrivateKey wfbGetScreenPrivateKey
#define fbGetSpans wfbGetSpans
#define _fbGetWindowPixmap _wfbGetWindowPixmap
-#define fbWinPrivateKeyRec wfbWinPrivateKeyRec
-#define fbGetWinPrivateKey wfbGetWinPrivateKey
#define fbGlyph16 wfbGlyph16
#define fbGlyph24 wfbGlyph24
#define fbGlyph32 wfbGlyph32
diff --git a/xorg-server/glx/clientinfo.c b/xorg-server/glx/clientinfo.c
index b26ac1a72..4aaa4c967 100644
--- a/xorg-server/glx/clientinfo.c
+++ b/xorg-server/glx/clientinfo.c
@@ -29,10 +29,10 @@
#include "glxbyteorder.h"
#include "unpack.h"
-int
-__glXDisp_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc)
+static int
+set_client_info(__GLXclientState * cl, xGLXSetClientInfoARBReq * req,
+ unsigned bytes_per_version)
{
- xGLXSetClientInfoARBReq *req = (xGLXSetClientInfoARBReq *) pc;
char *gl_extensions;
char *glx_extensions;
@@ -40,7 +40,7 @@ __glXDisp_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc)
* sizes specified for the various fields.
*/
const unsigned expected_size = sz_xGLXSetClientInfoARBReq
- + (req->numVersions * 8)
+ + (req->numVersions * bytes_per_version)
+ __GLX_PAD(req->numGLExtensionBytes)
+ __GLX_PAD(req->numGLXExtensionBytes);
@@ -50,7 +50,7 @@ __glXDisp_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc)
/* Verify that the actual length of the GL extension string matches what's
* encoded in protocol packet.
*/
- gl_extensions = (char *) (req + 1) + (req->numVersions * 8);
+ gl_extensions = (char *) (req + 1) + (req->numVersions * bytes_per_version);
if (req->numGLExtensionBytes != 0
&& memchr(gl_extensions, 0,
__GLX_PAD(req->numGLExtensionBytes)) == NULL)
@@ -72,6 +72,12 @@ __glXDisp_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc)
}
int
+__glXDisp_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc)
+{
+ return set_client_info(cl, (xGLXSetClientInfoARBReq *) pc, 8);
+}
+
+int
__glXDispSwap_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc)
{
xGLXSetClientInfoARBReq *req = (xGLXSetClientInfoARBReq *) pc;
@@ -87,11 +93,18 @@ __glXDispSwap_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc)
int
__glXDisp_SetClientInfo2ARB(__GLXclientState * cl, GLbyte * pc)
{
- return BadRequest;
+ return set_client_info(cl, (xGLXSetClientInfoARBReq *) pc, 12);
}
int
__glXDispSwap_SetClientInfo2ARB(__GLXclientState * cl, GLbyte * pc)
{
- return BadRequest;
+ xGLXSetClientInfoARBReq *req = (xGLXSetClientInfoARBReq *) pc;
+
+ req->length = bswap_16(req->length);
+ req->numVersions = bswap_32(req->numVersions);
+ req->numGLExtensionBytes = bswap_32(req->numGLExtensionBytes);
+ req->numGLXExtensionBytes = bswap_32(req->numGLXExtensionBytes);
+
+ return __glXDisp_SetClientInfo2ARB(cl, pc);
}
diff --git a/xorg-server/glx/createcontext.c b/xorg-server/glx/createcontext.c
index 025c423fe..13d21ccb9 100644
--- a/xorg-server/glx/createcontext.c
+++ b/xorg-server/glx/createcontext.c
@@ -30,7 +30,8 @@
#include "indirect_dispatch.h"
#define ALL_VALID_FLAGS \
- (GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
+ (GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB \
+ | GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB)
static Bool
validate_GL_version(int major_version, int minor_version)
@@ -90,6 +91,24 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
__GLXconfig *config;
int err;
+ /* The GLX_ARB_create_context_robustness spec says:
+ *
+ * "The default value for GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB
+ * is GLX_NO_RESET_NOTIFICATION_ARB."
+ */
+ int reset = GLX_NO_RESET_NOTIFICATION_ARB;
+
+ /* The GLX_ARB_create_context_profile spec says:
+ *
+ * "The default value for GLX_CONTEXT_PROFILE_MASK_ARB is
+ * GLX_CONTEXT_CORE_PROFILE_BIT_ARB."
+ *
+ * The core profile only makes sense for OpenGL versions 3.2 and later.
+ * If the version ultimately specified is less than 3.2, the core profile
+ * bit is cleared (see below).
+ */
+ int profile = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+
/* Verify that the size of the packet matches the size inferred from the
* sizes specified for the various fields.
*/
@@ -161,6 +180,18 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
render_type = attribs[2 * i + 1];
break;
+ case GLX_CONTEXT_PROFILE_MASK_ARB:
+ profile = attribs[2 * i + 1];
+ break;
+
+ case GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB:
+ reset = attribs[2 * i + 1];
+ if (reset != GLX_NO_RESET_NOTIFICATION_ARB
+ && reset != GLX_LOSE_CONTEXT_ON_RESET_ARB)
+ return BadValue;
+
+ break;
+
default:
return BadValue;
}
@@ -202,6 +233,73 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
if ((flags & ~ALL_VALID_FLAGS) != 0)
return BadValue;
+ /* The GLX_ARB_create_context_profile spec says:
+ *
+ * "* If attribute GLX_CONTEXT_PROFILE_MASK_ARB has no bits set; has
+ * any bits set other than GLX_CONTEXT_CORE_PROFILE_BIT_ARB and
+ * GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; has more than one of
+ * these bits set; or if the implementation does not support the
+ * requested profile, then GLXBadProfileARB is generated."
+ */
+ switch (profile) {
+ case GLX_CONTEXT_CORE_PROFILE_BIT_ARB:
+ case GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
+ break;
+ case GLX_CONTEXT_ES2_PROFILE_BIT_EXT:
+ /* The GLX_EXT_create_context_es2_profile spec says:
+ *
+ * "... If the version requested is 2.0, and the
+ * GLX_CONTEXT_ES2_PROFILE_BIT_EXT bit is set in the
+ * GLX_CONTEXT_PROFILE_MASK_ARB attribute (see below), then the
+ * context returned will implement OpenGL ES 2.0."
+ *
+ * It also says:
+ *
+ * "* If attribute GLX_CONTEXT_PROFILE_MASK_ARB has no bits set;
+ * has any bits set other than
+ * GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
+ * GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, or
+ * GLX_CONTEXT_ES2_PROFILE_BIT_EXT; has more than one of these
+ * bits set; or if the implementation does not supported the
+ * requested profile, then GLXBadProfileARB is generated."
+ *
+ * It does not specifically say what is supposed to happen if
+ * GLX_CONTEXT_ES2_PROFILE_BIT_EXT is set but the version requested is
+ * not 2.0. We choose to generate GLXBadProfileARB as this matches
+ * NVIDIA's behavior.
+ */
+ if (major_version != 2 || minor_version != 0)
+ return __glXError(GLXBadProfileARB);
+ break;
+ default:
+ return __glXError(GLXBadProfileARB);
+ }
+
+ /* The GLX_ARB_create_context_robustness spec says:
+ *
+ * "* If the reset notification behavior of <share_context> and the
+ * newly created context are different, BadMatch is generated."
+ */
+ if (shareCtx != NULL && shareCtx->resetNotificationStrategy != reset)
+ return BadMatch;
+
+ /* There is no GLX protocol for desktop OpenGL versions after 1.4. There
+ * is no GLX protocol for any version of OpenGL ES. If the application is
+ * requested an indirect rendering context for a version that cannot be
+ * satisfied, reject it.
+ *
+ * The GLX_ARB_create_context spec says:
+ *
+ * "* If <config> does not support compatible OpenGL contexts
+ * providing the requested API major and minor version,
+ * forward-compatible flag, and debug context flag, GLXBadFBConfig
+ * is generated."
+ */
+ if (!req->isDirect && (major_version > 1 || minor_version > 4
+ || profile == GLX_CONTEXT_ES2_PROFILE_BIT_EXT)) {
+ return __glXError(GLXBadFBConfig);
+ }
+
/* Allocate memory for the new context
*/
if (req->isDirect) {
@@ -232,6 +330,7 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
ctx->selectBufSize = 0;
ctx->drawPriv = NULL;
ctx->readPriv = NULL;
+ ctx->resetNotificationStrategy = reset;
/* Add the new context to the various global tables of GLX contexts.
*/
diff --git a/xorg-server/glx/extension_string.c b/xorg-server/glx/extension_string.c
index 6a1a6c6b2..ee9864e64 100644
--- a/xorg-server/glx/extension_string.c
+++ b/xorg-server/glx/extension_string.c
@@ -70,8 +70,10 @@ static const struct extension_info known_glx_extensions[] = {
/* *INDENT-OFF* */
{ GLX(ARB_create_context), VER(0,0), N, },
{ GLX(ARB_create_context_profile), VER(0,0), N, },
+ { GLX(ARB_create_context_robustness), VER(0,0), N, },
{ GLX(ARB_multisample), VER(1,4), Y, },
+ { GLX(EXT_create_context_es2_profile), VER(0,0), N, },
{ GLX(EXT_import_context), VER(0,0), Y, },
{ GLX(EXT_texture_from_pixmap), VER(0,0), Y, },
{ GLX(EXT_visual_info), VER(0,0), Y, },
diff --git a/xorg-server/glx/extension_string.h b/xorg-server/glx/extension_string.h
index 947bf89e6..7a4a8b1c2 100644
--- a/xorg-server/glx/extension_string.h
+++ b/xorg-server/glx/extension_string.h
@@ -38,7 +38,9 @@ enum {
/* GLX_ARB_get_proc_address is implemented on the client. */
ARB_create_context_bit = 0,
ARB_create_context_profile_bit,
+ ARB_create_context_robustness_bit,
ARB_multisample_bit,
+ EXT_create_context_es2_profile_bit,
EXT_import_context_bit,
EXT_texture_from_pixmap_bit,
EXT_visual_info_bit,
diff --git a/xorg-server/glx/glxcmds.c b/xorg-server/glx/glxcmds.c
index d483bbf8a..d05421971 100644
--- a/xorg-server/glx/glxcmds.c
+++ b/xorg-server/glx/glxcmds.c
@@ -308,6 +308,16 @@ DoCreateContext(__GLXclientState * cl, GLXContextID gcId,
glxc->drawPriv = NULL;
glxc->readPriv = NULL;
+ /* The GLX_ARB_create_context_robustness spec says:
+ *
+ * "The default value for GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB
+ * is GLX_NO_RESET_NOTIFICATION_ARB."
+ *
+ * Without using glXCreateContextAttribsARB, there is no way to specify a
+ * non-default reset notification strategy.
+ */
+ glxc->resetNotificationStrategy = GLX_NO_RESET_NOTIFICATION_ARB;
+
/* Add the new context to the various global tables of GLX contexts.
*/
if (!__glXAddContext(glxc)) {
diff --git a/xorg-server/glx/glxcontext.h b/xorg-server/glx/glxcontext.h
index b803a7fd1..4764e56f5 100644
--- a/xorg-server/glx/glxcontext.h
+++ b/xorg-server/glx/glxcontext.h
@@ -104,6 +104,11 @@ struct __GLXcontext {
*/
GLenum renderMode;
+ /**
+ * Reset notification strategy used when a GPU reset occurs.
+ */
+ GLenum resetNotificationStrategy;
+
/*
** Buffers for feedback and selection.
*/
diff --git a/xorg-server/glx/glxdri2.c b/xorg-server/glx/glxdri2.c
index 7b76c3a5f..1e99179d4 100644
--- a/xorg-server/glx/glxdri2.c
+++ b/xorg-server/glx/glxdri2.c
@@ -59,6 +59,16 @@ typedef struct __GLXDRIscreen __GLXDRIscreen;
typedef struct __GLXDRIcontext __GLXDRIcontext;
typedef struct __GLXDRIdrawable __GLXDRIdrawable;
+
+#ifdef __DRI2_ROBUSTNESS
+#define ALL_DRI_CTX_FLAGS (__DRI_CTX_FLAG_DEBUG \
+ | __DRI_CTX_FLAG_FORWARD_COMPATIBLE \
+ | __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS)
+#else
+#define ALL_DRI_CTX_FLAGS (__DRI_CTX_FLAG_DEBUG \
+ | __DRI_CTX_FLAG_FORWARD_COMPATIBLE)
+#endif
+
struct __GLXDRIscreen {
__GLXscreen base;
__DRIscreen *driScreen;
@@ -381,7 +391,7 @@ __glXDRIscreenDestroy(__GLXscreen * baseScreen)
static Bool
dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
unsigned *major_ver, unsigned *minor_ver,
- uint32_t *flags, unsigned *error)
+ uint32_t *flags, int *api, int *reset, unsigned *error)
{
unsigned i;
@@ -395,6 +405,11 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
*major_ver = 1;
*minor_ver = 0;
+#ifdef __DRI2_ROBUSTNESS
+ *reset = __DRI_CTX_RESET_NO_NOTIFICATION;
+#else
+ (void) reset;
+#endif
for (i = 0; i < num_attribs; i++) {
switch (attribs[i * 2]) {
@@ -409,6 +424,42 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
break;
case GLX_RENDER_TYPE:
break;
+ case GLX_CONTEXT_PROFILE_MASK_ARB:
+ switch (attribs[i * 2 + 1]) {
+ case GLX_CONTEXT_CORE_PROFILE_BIT_ARB:
+ *api = __DRI_API_OPENGL_CORE;
+ break;
+ case GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
+ *api = __DRI_API_OPENGL;
+ break;
+ case GLX_CONTEXT_ES2_PROFILE_BIT_EXT:
+ *api = __DRI_API_GLES2;
+ break;
+ default:
+ *error = __glXError(GLXBadProfileARB);
+ return False;
+ }
+ break;
+#ifdef __DRI2_ROBUSTNESS
+ case GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB:
+ if (screen->dri2->base.version >= 4) {
+ *error = BadValue;
+ return False;
+ }
+
+ switch (attribs[i * 2 + 1]) {
+ case GLX_NO_RESET_NOTIFICATION_ARB:
+ *reset = __DRI_CTX_RESET_NO_NOTIFICATION;
+ break;
+ case GLX_LOSE_CONTEXT_ON_RESET_ARB:
+ *reset = __DRI_CTX_RESET_LOSE_CONTEXT;
+ break;
+ default:
+ *error = BadValue;
+ return False;
+ }
+ break;
+#endif
default:
/* If an unknown attribute is received, fail.
*/
@@ -419,11 +470,21 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
/* Unknown flag value.
*/
- if (*flags & ~(__DRI_CTX_FLAG_DEBUG | __DRI_CTX_FLAG_FORWARD_COMPATIBLE)) {
+ if ((*flags & ~ALL_DRI_CTX_FLAGS) != 0) {
*error = BadValue;
return False;
}
+ /* If the core profile is requested for a GL version is less than 3.2,
+ * request the non-core profile from the DRI driver. The core profile
+ * only makes sense for GL versions >= 3.2, and many DRI drivers that
+ * don't support OpenGL 3.2 may fail the request for a core profile.
+ */
+ if (*api == __DRI_API_OPENGL_CORE
+ && (*major_ver < 3 || (*major_ver < 3 && *minor_ver < 2))) {
+ *api == __DRI_API_OPENGL;
+ }
+
*error = Success;
return True;
}
@@ -447,11 +508,14 @@ create_driver_context(__GLXDRIcontext * context,
unsigned major_ver;
unsigned minor_ver;
uint32_t flags;
+ int reset;
+ int api;
if (num_attribs != 0) {
if (!dri2_convert_glx_attribs(num_attribs, attribs,
&major_ver, &minor_ver,
- &flags, (unsigned *) error))
+ &flags, &api, &reset,
+ (unsigned *) error))
return NULL;
ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION;
@@ -467,11 +531,19 @@ create_driver_context(__GLXDRIcontext * context,
*/
ctx_attribs[num_ctx_attribs++] = flags;
}
+
+#ifdef __DRI2_ROBUSTNESS
+ if (reset != __DRI_CTX_NO_RESET_NOTIFICATION) {
+ ctx_attribs[num_ctx_attribs++] =
+ __DRI_CTX_ATTRIB_RESET_NOTIFICATION;
+ ctx_attribs[num_ctx_attribs++] = reset;
+ }
+#endif
}
context->driContext =
(*screen->dri2->createContextAttribs)(screen->driScreen,
- __DRI_API_OPENGL,
+ api,
config->driConfig,
driShare,
num_ctx_attribs / 2,
@@ -786,7 +858,14 @@ initializeExtensions(__GLXDRIscreen * screen)
if (screen->dri2->base.version >= 3) {
__glXEnableExtension(screen->glx_enable_bits,
"GLX_ARB_create_context");
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_ARB_create_context_profile");
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_EXT_create_context_es2_profile");
LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_create_context\n");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_create_context_profile\n");
+ LogMessage(X_INFO,
+ "AIGLX: enabled GLX_EXT_create_context_es2_profile\n");
}
#endif
@@ -823,6 +902,16 @@ initializeExtensions(__GLXDRIscreen * screen)
}
#endif
+#ifdef __DRI2_ROBUSTNESS
+ if (strcmp(extensions[i]->name, __DRI2_ROBUSTNESS) == 0 &&
+ screen->dri2->base.version >= 3) {
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_ARB_create_context_robustness");
+ LogMessage(X_INFO,
+ "AIGLX: enabled GLX_ARB_create_context_robustness\n");
+ }
+#endif
+
/* Ignore unknown extensions */
}
}
diff --git a/xorg-server/glx/glxserver.h b/xorg-server/glx/glxserver.h
index 87c94d9ec..24e3d626f 100644
--- a/xorg-server/glx/glxserver.h
+++ b/xorg-server/glx/glxserver.h
@@ -46,7 +46,6 @@
#include <resource.h>
#include <scrnintstr.h>
-#define GL_GLEXT_PROTOTYPES /* we want prototypes */
#include <GL/gl.h>
#include <GL/glxproto.h>
diff --git a/xorg-server/hw/dmx/input/dmxevents.c b/xorg-server/hw/dmx/input/dmxevents.c
index f73480824..28756203b 100644
--- a/xorg-server/hw/dmx/input/dmxevents.c
+++ b/xorg-server/hw/dmx/input/dmxevents.c
@@ -227,25 +227,25 @@ dmxCoreMotion(DevicePtr pDev, int x, int y, int delta, DMXBlockType block)
&& pScreen->myNum == dmxScreen->index) {
/* Screen is old screen */
if (block)
- dmxSigioBlock();
+ OsBlockSIGIO();
if (pDev)
enqueueMotion(pDev, localX, localY);
if (block)
- dmxSigioUnblock();
+ OsReleaseSIGIO();
}
else {
/* Screen is new */
DMXDBG4(" New screen: old=%d new=%d localX=%d localY=%d\n",
pScreen->myNum, dmxScreen->index, localX, localY);
if (block)
- dmxSigioBlock();
+ OsBlockSIGIO();
mieqProcessInputEvents();
miPointerSetScreen(inputInfo.pointer, dmxScreen->index,
localX, localY);
if (pDev)
enqueueMotion(pDev, localX, localY);
if (block)
- dmxSigioUnblock();
+ OsReleaseSIGIO();
}
#if 00
miPointerGetPosition(inputInfo.pointer, &localX, &localY);
@@ -387,12 +387,12 @@ dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
}
if (block)
- dmxSigioBlock();
+ OsBlockSIGIO();
valuator_mask_set_range(&mask, firstAxis, axesCount, v);
QueuePointerEvents(pDevice, MotionNotify, 0, POINTER_ABSOLUTE, &mask);
if (block)
- dmxSigioUnblock();
+ OsReleaseSIGIO();
}
static int
@@ -492,10 +492,10 @@ dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count,
valuators);
if (block)
- dmxSigioBlock();
+ OsBlockSIGIO();
QueueKeyboardEvents(pDevice, event, ke->keycode, &mask);
if (block)
- dmxSigioUnblock();
+ OsReleaseSIGIO();
break;
case XI_DeviceButtonPress:
case XI_DeviceButtonRelease:
@@ -503,11 +503,11 @@ dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count,
valuators);
if (block)
- dmxSigioBlock();
+ OsBlockSIGIO();
QueuePointerEvents(pDevice, event, ke->keycode,
POINTER_ABSOLUTE, &mask);
if (block)
- dmxSigioUnblock();
+ OsReleaseSIGIO();
break;
case XI_ProximityIn:
case XI_ProximityOut:
@@ -515,10 +515,10 @@ dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count,
valuators);
if (block)
- dmxSigioBlock();
+ OsBlockSIGIO();
QueueProximityEvents(pDevice, event, &mask);
if (block)
- dmxSigioUnblock();
+ OsReleaseSIGIO();
break;
break;
diff --git a/xorg-server/hw/dmx/input/dmxsigio.c b/xorg-server/hw/dmx/input/dmxsigio.c
index 9b1b493b8..6ef543c8b 100644
--- a/xorg-server/hw/dmx/input/dmxsigio.c
+++ b/xorg-server/hw/dmx/input/dmxsigio.c
@@ -84,28 +84,6 @@ dmxSigioHandler(int sig)
}
}
-/** Block SIGIO handling. */
-void
-dmxSigioBlock(void)
-{
- sigset_t s;
-
- sigemptyset(&s);
- sigaddset(&s, SIGIO);
- sigprocmask(SIG_BLOCK, &s, 0);
-}
-
-/** Unblock SIGIO handling. */
-void
-dmxSigioUnblock(void)
-{
- sigset_t s;
-
- sigemptyset(&s);
- sigaddset(&s, SIGIO);
- sigprocmask(SIG_UNBLOCK, &s, 0);
-}
-
static void
dmxSigioHook(void)
{
diff --git a/xorg-server/hw/dmx/input/dmxsigio.h b/xorg-server/hw/dmx/input/dmxsigio.h
index 4e4874929..9f30662d1 100644
--- a/xorg-server/hw/dmx/input/dmxsigio.h
+++ b/xorg-server/hw/dmx/input/dmxsigio.h
@@ -36,8 +36,6 @@
#ifndef _DMXSIGIO_H_
#define _DMXSIGIO_H_
-extern void dmxSigioBlock(void);
-extern void dmxSigioUnblock(void);
extern void dmxSigioEnableInput(void);
extern void dmxSigioDisableInput(void);
extern void dmxSigioRegister(DMXInputInfo * dmxInput, int fd);
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.c b/xorg-server/hw/kdrive/ephyr/ephyr.c
index 8eda539aa..fe3dae66e 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyr.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyr.c
@@ -772,26 +772,6 @@ ephyrUpdateModifierState(unsigned int state)
}
}
-static void
-ephyrBlockSigio(void)
-{
- sigset_t set;
-
- sigemptyset(&set);
- sigaddset(&set, SIGIO);
- sigprocmask(SIG_BLOCK, &set, 0);
-}
-
-static void
-ephyrUnblockSigio(void)
-{
- sigset_t set;
-
- sigemptyset(&set);
- sigaddset(&set, SIGIO);
- sigprocmask(SIG_UNBLOCK, &set, 0);
-}
-
static Bool
ephyrCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
{
@@ -808,11 +788,11 @@ int ephyrCurScreen; /*current event screen */
static void
ephyrWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
{
- ephyrBlockSigio();
+ OsBlockSIGIO();
ephyrCurScreen = pScreen->myNum;
miPointerWarpCursor(inputInfo.pointer, pScreen, x, y);
- ephyrUnblockSigio();
+ OsReleaseSIGIO();
}
miPointerScreenFuncRec ephyrPointerScreenFuncs = {
diff --git a/xorg-server/hw/kdrive/src/kinput.c b/xorg-server/hw/kdrive/src/kinput.c
index 0e06fd42f..b1068bbee 100644
--- a/xorg-server/hw/kdrive/src/kinput.c
+++ b/xorg-server/hw/kdrive/src/kinput.c
@@ -102,26 +102,6 @@ KdSigio(int sig)
(*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure);
}
-static void
-KdBlockSigio(void)
-{
- sigset_t set;
-
- sigemptyset(&set);
- sigaddset(&set, SIGIO);
- sigprocmask(SIG_BLOCK, &set, 0);
-}
-
-static void
-KdUnblockSigio(void)
-{
- sigset_t set;
-
- sigemptyset(&set);
- sigaddset(&set, SIGIO);
- sigprocmask(SIG_UNBLOCK, &set, 0);
-}
-
#ifdef DEBUG_SIGIO
void
@@ -261,7 +241,7 @@ KdDisableInput(void)
KdPointerInfo *pi;
int found = 0, i = 0;
- KdBlockSigio();
+ OsBlockSIGIO();
for (ki = kdKeyboards; ki; ki = ki->next) {
if (ki->driver && ki->driver->Disable)
@@ -343,7 +323,7 @@ KdEnableInput(void)
NoticeEventTime(&ev, pi->dixdev);
NoticeEventTime(&ev, ki->dixdev);
- KdUnblockSigio();
+ OsReleaseSIGIO();
}
static KdKeyboardDriver *
@@ -1801,7 +1781,7 @@ KdReleaseAllKeys(void)
int key;
KdKeyboardInfo *ki;
- KdBlockSigio();
+ OsBlockSIGIO();
for (ki = kdKeyboards; ki; ki = ki->next) {
for (key = ki->keySyms.minKeyCode; key < ki->keySyms.maxKeyCode; key++) {
@@ -1812,7 +1792,7 @@ KdReleaseAllKeys(void)
}
}
- KdUnblockSigio();
+ OsReleaseSIGIO();
#endif
}
@@ -2008,18 +1988,18 @@ KdWakeupHandler(ScreenPtr pScreen, unsigned long lresult, pointer readmask)
if (kdInputEnabled && result > 0) {
for (i = 0; i < kdNumInputFds; i++)
if (FD_ISSET(kdInputFds[i].fd, pReadmask)) {
- KdBlockSigio();
+ OsBlockSIGIO();
(*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure);
- KdUnblockSigio();
+ OsReleaseSIGIO();
}
}
for (pi = kdPointers; pi; pi = pi->next) {
if (pi->timeoutPending) {
if ((long) (GetTimeInMillis() - pi->emulationTimeout) >= 0) {
pi->timeoutPending = FALSE;
- KdBlockSigio();
+ OsBlockSIGIO();
KdReceiveTimeout(pi);
- KdUnblockSigio();
+ OsReleaseSIGIO();
}
}
}
@@ -2116,10 +2096,10 @@ int KdCurScreen; /* current event screen */
static void
KdWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
{
- KdBlockSigio();
+ OsBlockSIGIO();
KdCurScreen = pScreen->myNum;
miPointerWarpCursor(pDev, pScreen, x, y);
- KdUnblockSigio();
+ OsReleaseSIGIO();
}
miPointerScreenFuncRec kdPointerScreenFuncs = {
diff --git a/xorg-server/hw/xfree86/common/xf86Config.c b/xorg-server/hw/xfree86/common/xf86Config.c
index b22b617a4..3ec40fe9b 100644
--- a/xorg-server/hw/xfree86/common/xf86Config.c
+++ b/xorg-server/hw/xfree86/common/xf86Config.c
@@ -2329,6 +2329,7 @@ checkInput(serverLayoutPtr layout, Bool implicit_layout)
current = dev;
free(*dev);
+ *dev = NULL;
do {
*current = *(current + 1);
diff --git a/xorg-server/hw/xfree86/common/xf86Cursor.c b/xorg-server/hw/xfree86/common/xf86Cursor.c
index c01cfd138..65a9e8264 100644
--- a/xorg-server/hw/xfree86/common/xf86Cursor.c
+++ b/xorg-server/hw/xfree86/common/xf86Cursor.c
@@ -199,7 +199,7 @@ xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
ScrnInfoPtr pScr = xf86ScreenToScrn(pScreen);
ScreenPtr pCursorScreen;
Bool Switched;
- int px, py, was_blocked;
+ int px, py;
DeviceIntPtr dev, it;
if (!pScr->vtSema || !mode || !pScr->SwitchMode)
@@ -228,7 +228,7 @@ xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
if (pScreen == pCursorScreen)
miPointerGetPosition(dev, &px, &py);
- was_blocked = xf86BlockSIGIO();
+ OsBlockSIGIO();
Switched = (*pScr->SwitchMode) (pScr, mode);
if (Switched) {
pScr->currentMode = mode;
@@ -267,7 +267,7 @@ xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
pScr->frameY1 = pScr->virtualY - 1;
}
}
- xf86UnblockSIGIO(was_blocked);
+ OsReleaseSIGIO();
if (pScr->AdjustFrame)
(*pScr->AdjustFrame) (pScr, pScr->frameX0, pScr->frameY0);
@@ -469,13 +469,11 @@ xf86CrossScreen(ScreenPtr pScreen, Bool entering)
static void
xf86WarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
{
- int sigstate;
-
- sigstate = xf86BlockSIGIO();
+ OsBlockSIGIO();
miPointerWarpCursor(pDev, pScreen, x, y);
xf86Info.currentScreen = pScreen;
- xf86UnblockSIGIO(sigstate);
+ OsReleaseSIGIO();
}
void *
diff --git a/xorg-server/hw/xfree86/common/xf86Events.c b/xorg-server/hw/xfree86/common/xf86Events.c
index 4fcad4000..47429ecfe 100644
--- a/xorg-server/hw/xfree86/common/xf86Events.c
+++ b/xorg-server/hw/xfree86/common/xf86Events.c
@@ -254,7 +254,7 @@ xf86Wakeup(pointer blockData, int err, pointer pReadmask)
while (pInfo) {
if (pInfo->read_input && pInfo->fd >= 0 &&
(FD_ISSET(pInfo->fd, &devicesWithInput) != 0)) {
- int sigstate = xf86BlockSIGIO();
+ OsBlockSIGIO();
/*
* Remove the descriptior from the set because more than one
@@ -263,7 +263,7 @@ xf86Wakeup(pointer blockData, int err, pointer pReadmask)
FD_CLR(pInfo->fd, &devicesWithInput);
pInfo->read_input(pInfo);
- xf86UnblockSIGIO(sigstate);
+ OsReleaseSIGIO();
}
pInfo = pInfo->next;
}
@@ -397,9 +397,9 @@ xf86ReleaseKeys(DeviceIntPtr pDev)
for (i = keyc->xkbInfo->desc->min_key_code;
i < keyc->xkbInfo->desc->max_key_code; i++) {
if (key_is_down(pDev, i, KEY_POSTED)) {
- sigstate = xf86BlockSIGIO();
+ OsBlockSIGIO();
QueueKeyboardEvents(pDev, KeyRelease, i, NULL);
- xf86UnblockSIGIO(sigstate);
+ OsReleaseSIGIO();
}
}
}
@@ -457,7 +457,7 @@ xf86VTSwitch(void)
}
}
- prevSIGIO = xf86BlockSIGIO();
+ OsBlockSIGIO();
for (i = 0; i < xf86NumScreens; i++)
xf86Screens[i]->LeaveVT(xf86Screens[i]);
@@ -492,7 +492,7 @@ xf86VTSwitch(void)
for (ih = InputHandlers; ih; ih = ih->next)
xf86EnableInputHandler(ih);
- xf86UnblockSIGIO(prevSIGIO);
+ OsReleaseSIGIO();
}
else {
@@ -549,7 +549,7 @@ xf86VTSwitch(void)
for (ih = InputHandlers; ih; ih = ih->next)
xf86EnableInputHandler(ih);
- xf86UnblockSIGIO(prevSIGIO);
+ OsReleaseSIGIO();
}
}
diff --git a/xorg-server/hw/xfree86/common/xf86Init.c b/xorg-server/hw/xfree86/common/xf86Init.c
index 84c866944..1f5a382b7 100644
--- a/xorg-server/hw/xfree86/common/xf86Init.c
+++ b/xorg-server/hw/xfree86/common/xf86Init.c
@@ -394,7 +394,7 @@ InstallSignalHandlers(void)
void
InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
{
- int i, j, k, scr_index, was_blocked = 0;
+ int i, j, k, scr_index;
char **modulelist;
pointer *optionlist;
Pix24Flags screenpix24, pix24;
@@ -806,7 +806,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
#endif
xf86AccessEnter();
- was_blocked = xf86BlockSIGIO();
+ OsBlockSIGIO();
}
}
@@ -879,7 +879,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
}
xf86VGAarbiterWrapFunctions();
- xf86UnblockSIGIO(was_blocked);
+ OsReleaseSIGIO();
xf86InitOrigins();
@@ -964,6 +964,7 @@ OsVendorInit(void)
}
#endif
#endif
+ OsReleaseSIGIO();
beenHere = TRUE;
}
@@ -1022,7 +1023,7 @@ AbortDDX(enum ExitCode error)
{
int i;
- xf86BlockSIGIO();
+ OsBlockSIGIO();
/*
* try to restore the original video state
diff --git a/xorg-server/hw/xfree86/common/xf86PM.c b/xorg-server/hw/xfree86/common/xf86PM.c
index 1830640d5..15257cb81 100644
--- a/xorg-server/hw/xfree86/common/xf86PM.c
+++ b/xorg-server/hw/xfree86/common/xf86PM.c
@@ -92,8 +92,6 @@ eventName(pmEvent event, const char **str)
}
}
-static int sigio_blocked_for_suspend;
-
static void
suspend(pmEvent event, Bool undo)
{
@@ -109,7 +107,7 @@ suspend(pmEvent event, Bool undo)
DisableDevice(pInfo->dev, TRUE);
pInfo = pInfo->next;
}
- sigio_blocked_for_suspend = xf86BlockSIGIO();
+ OsBlockSIGIO();
for (i = 0; i < xf86NumScreens; i++) {
if (xf86Screens[i]->PMEvent)
xf86Screens[i]->PMEvent(xf86Screens[i], event, undo);
@@ -137,7 +135,7 @@ resume(pmEvent event, Bool undo)
xf86Screens[i]->EnterVT(xf86Screens[i]);
}
}
- xf86UnblockSIGIO(sigio_blocked_for_suspend);
+ OsReleaseSIGIO();
for (i = 0; i < xf86NumScreens; i++) {
if (xf86Screens[i]->EnableDisableFBAccess)
(*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE);
@@ -153,7 +151,7 @@ resume(pmEvent event, Bool undo)
static void
DoApmEvent(pmEvent event, Bool undo)
{
- int i, was_blocked;
+ int i;
switch (event) {
#if 0
@@ -184,13 +182,13 @@ DoApmEvent(pmEvent event, Bool undo)
}
break;
default:
- was_blocked = xf86BlockSIGIO();
+ OsBlockSIGIO();
for (i = 0; i < xf86NumScreens; i++) {
if (xf86Screens[i]->PMEvent) {
xf86Screens[i]->PMEvent(xf86Screens[i], event, undo);
}
}
- xf86UnblockSIGIO(was_blocked);
+ OsReleaseSIGIO();
break;
}
}
diff --git a/xorg-server/hw/xfree86/loader/loader.c b/xorg-server/hw/xfree86/loader/loader.c
index edaefb8f9..5fbea38f8 100644
--- a/xorg-server/hw/xfree86/loader/loader.c
+++ b/xorg-server/hw/xfree86/loader/loader.c
@@ -160,6 +160,12 @@ LoaderSymbol(const char *name)
return NULL;
}
+void *
+LoaderSymbolFromModule(void *handle, const char *name)
+{
+ return dlsym(handle, name);
+}
+
void
LoaderUnload(const char *name, void *handle)
{
diff --git a/xorg-server/hw/xfree86/loader/loader.h b/xorg-server/hw/xfree86/loader/loader.h
index 5cadd5ad6..c89c6410a 100644
--- a/xorg-server/hw/xfree86/loader/loader.h
+++ b/xorg-server/hw/xfree86/loader/loader.h
@@ -72,5 +72,6 @@ extern unsigned long LoaderOptions;
/* Internal Functions */
void *LoaderOpen(const char *, int *, int *);
+void *LoaderSymbolFromModule(void *, const char *);
#endif /* _LOADER_H */
diff --git a/xorg-server/hw/xfree86/loader/loadmod.c b/xorg-server/hw/xfree86/loader/loadmod.c
index 72020a58c..dd2057318 100644
--- a/xorg-server/hw/xfree86/loader/loadmod.c
+++ b/xorg-server/hw/xfree86/loader/loadmod.c
@@ -956,7 +956,7 @@ doLoadModule(const char *module, const char *path, const char **subdirlist,
*errmin = 0;
goto LoadModule_fail;
}
- initdata = LoaderSymbol(p);
+ initdata = LoaderSymbolFromModule(ret->handle, p);
if (initdata) {
ModuleSetupProc setup;
ModuleTearDownProc teardown;
diff --git a/xorg-server/hw/xfree86/os-support/shared/sigio.c b/xorg-server/hw/xfree86/os-support/shared/sigio.c
index 231d6c04f..f3c153b89 100644
--- a/xorg-server/hw/xfree86/os-support/shared/sigio.c
+++ b/xorg-server/hw/xfree86/os-support/shared/sigio.c
@@ -136,7 +136,6 @@ xf86InstallSIGIOHandler(int fd, void (*f) (int, void *), void *closure)
struct sigaction sa;
struct sigaction osa;
int i;
- int blocked;
int installed = FALSE;
if (!xf86Info.useSIGIO)
@@ -146,7 +145,7 @@ xf86InstallSIGIOHandler(int fd, void (*f) (int, void *), void *closure)
if (!xf86SigIOFuncs[i].f) {
if (xf86IsPipe(fd))
return 0;
- blocked = xf86BlockSIGIO();
+ OsBlockSIGIO();
#ifdef O_ASYNC
if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_ASYNC) == -1) {
xf86Msg(X_WARNING, "fcntl(%d, O_ASYNC): %s\n",
@@ -174,7 +173,7 @@ xf86InstallSIGIOHandler(int fd, void (*f) (int, void *), void *closure)
}
#endif
if (!installed) {
- xf86UnblockSIGIO(blocked);
+ OsReleaseSIGIO();
return 0;
}
sigemptyset(&sa.sa_mask);
@@ -190,7 +189,7 @@ xf86InstallSIGIOHandler(int fd, void (*f) (int, void *), void *closure)
if (fd >= xf86SigIOMaxFd)
xf86SigIOMaxFd = fd + 1;
FD_SET(fd, &xf86SigIOMask);
- xf86UnblockSIGIO(blocked);
+ OsReleaseSIGIO();
return 1;
}
/* Allow overwriting of the closure and callback */
@@ -263,26 +262,13 @@ xf86RemoveSIGIOHandler(int fd)
int
xf86BlockSIGIO(void)
{
- sigset_t set, old;
- int ret;
-
- sigemptyset(&set);
- sigaddset(&set, SIGIO);
- sigprocmask(SIG_BLOCK, &set, &old);
- ret = sigismember(&old, SIGIO);
- return ret;
+ return OsBlockSIGIO();
}
void
xf86UnblockSIGIO(int wasset)
{
- sigset_t set;
-
- if (!wasset) {
- sigemptyset(&set);
- sigaddset(&set, SIGIO);
- sigprocmask(SIG_UNBLOCK, &set, NULL);
- }
+ OsReleaseSIGIO();
}
void
diff --git a/xorg-server/include/list.h b/xorg-server/include/list.h
index 96c0bcbd6..d54a207b1 100644
--- a/xorg-server/include/list.h
+++ b/xorg-server/include/list.h
@@ -453,7 +453,7 @@ xorg_list_is_empty(struct xorg_list *head)
#define nt_list_del(_entry, _list, _type, _member) \
do { \
_type *__e = _entry; \
- if (__e == NULL) break; \
+ if (__e == NULL || _list == NULL) break; \
if ((_list) == __e) { \
_list = __e->_member; \
} else { \
diff --git a/xorg-server/include/os.h b/xorg-server/include/os.h
index e93c48ae6..34ca1f557 100644
--- a/xorg-server/include/os.h
+++ b/xorg-server/include/os.h
@@ -334,6 +334,12 @@ OsBlockSignals(void);
extern _X_EXPORT void
OsReleaseSignals(void);
+extern _X_EXPORT int
+OsBlockSIGIO(void);
+
+extern _X_EXPORT void
+OsReleaseSIGIO(void);
+
extern _X_EXPORT void
OsAbort(void)
_X_NORETURN;
diff --git a/xorg-server/include/privates.h b/xorg-server/include/privates.h
index c34b9512c..2c8864b8a 100644
--- a/xorg-server/include/privates.h
+++ b/xorg-server/include/privates.h
@@ -33,9 +33,9 @@ typedef enum {
PRIVATE_SCREEN,
PRIVATE_EXTENSION,
PRIVATE_COLORMAP,
+ PRIVATE_DEVICE,
/* These cannot have any objects before all relevant keys are registered */
- PRIVATE_DEVICE,
PRIVATE_CLIENT,
PRIVATE_PROPERTY,
PRIVATE_SELECTION,
@@ -66,6 +66,13 @@ typedef struct _DevPrivateKeyRec {
struct _DevPrivateKeyRec *next;
} DevPrivateKeyRec, *DevPrivateKey;
+typedef struct _DevPrivateSetRec {
+ DevPrivateKey key;
+ unsigned offset;
+ int created;
+ int allocated;
+} DevPrivateSetRec, *DevPrivateSetPtr;
+
typedef struct _DevScreenPrivateKeyRec {
DevPrivateKeyRec screenKey;
} DevScreenPrivateKeyRec, *DevScreenPrivateKey;
@@ -219,6 +226,51 @@ dixLookupScreenPrivateAddr(PrivatePtr *privates, const DevScreenPrivateKey key,
}
/*
+ * These functions relate to allocations related to a specific screen;
+ * space will only be available for objects allocated for use on that
+ * screen. As such, only objects which are related directly to a specific
+ * screen are candidates for allocation this way, this includes
+ * windows, pixmaps, gcs, pictures and colormaps. This key is
+ * used just like any other key using dixGetPrivate and friends.
+ *
+ * This is distinctly different from the ScreenPrivateKeys above which
+ * allocate space in global objects like cursor bits for a specific
+ * screen, allowing multiple screen-related chunks of storage in a
+ * single global object.
+ */
+
+#define HAVE_SCREEN_SPECIFIC_PRIVATE_KEYS 1
+
+extern _X_EXPORT Bool
+dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key,
+ DevPrivateType type, unsigned size);
+
+/* Clean up screen-specific privates before CloseScreen */
+extern void
+dixFreeScreenSpecificPrivates(ScreenPtr pScreen);
+
+/* Initialize screen-specific privates in AddScreen */
+extern void
+dixInitScreenSpecificPrivates(ScreenPtr pScreen);
+
+extern _X_EXPORT void *
+_dixAllocateScreenObjectWithPrivates(ScreenPtr pScreen,
+ unsigned size,
+ unsigned clear,
+ unsigned offset,
+ DevPrivateType type);
+
+#define dixAllocateScreenObjectWithPrivates(s, t, type) _dixAllocateScreenObjectWithPrivates(s, sizeof(t), sizeof(t), offsetof(t, devPrivates), type)
+
+extern _X_EXPORT int
+dixScreenSpecificPrivatesSize(ScreenPtr pScreen, DevPrivateType type);
+
+extern _X_EXPORT void
+_dixInitScreenPrivates(ScreenPtr pScreen, PrivatePtr *privates, void *addr, DevPrivateType type);
+
+#define dixInitScreenPrivates(s, o, v, type) _dixInitScreenPrivates(s, &(o)->devPrivates, (v), type);
+
+/*
* Allocates private data separately from main object.
*
* For objects created during server initialization, this allows those
@@ -240,7 +292,7 @@ extern _X_EXPORT void
* Initialize privates by zeroing them
*/
extern _X_EXPORT void
- _dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type);
+_dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type);
#define dixInitPrivates(o, v, type) _dixInitPrivates(&(o)->devPrivates, (v), type);
diff --git a/xorg-server/include/scrnintstr.h b/xorg-server/include/scrnintstr.h
index c592d1ffe..7af2bf53f 100644
--- a/xorg-server/include/scrnintstr.h
+++ b/xorg-server/include/scrnintstr.h
@@ -367,6 +367,8 @@ typedef struct _Screen {
WindowPtr root;
ScreenSaverStuffRec screensaver;
+ DevPrivateSetRec screenSpecificPrivates[PRIVATE_LAST];
+
/* Random screen procedures */
CloseScreenProcPtr CloseScreen;
diff --git a/xorg-server/mi/midispcur.c b/xorg-server/mi/midispcur.c
index df141cdc7..edca9696f 100644
--- a/xorg-server/mi/midispcur.c
+++ b/xorg-server/mi/midispcur.c
@@ -56,9 +56,7 @@ in this Software without prior written authorization from The Open Group.
static DevPrivateKeyRec miDCScreenKeyRec;
#define miDCScreenKey (&miDCScreenKeyRec)
-static DevScreenPrivateKeyRec miDCCursorBitsKeyRec;
-#define miDCCursorBitsKey (&miDCCursorBitsKeyRec)
static DevScreenPrivateKeyRec miDCDeviceKeyRec;
#define miDCDeviceKey (&miDCDeviceKeyRec)
@@ -86,18 +84,15 @@ typedef struct {
*/
typedef struct {
CloseScreenProcPtr CloseScreen;
-} miDCScreenRec, *miDCScreenPtr;
-
-#define miGetDCScreen(s) ((miDCScreenPtr)(dixLookupPrivate(&(s)->devPrivates, miDCScreenKey)))
-
-/* per-cursor per-screen private data */
-typedef struct {
PixmapPtr sourceBits; /* source bits */
PixmapPtr maskBits; /* mask bits */
#ifdef ARGB_CURSOR
PicturePtr pPicture;
#endif
-} miDCCursorRec, *miDCCursorPtr;
+ CursorPtr pCursor;
+} miDCScreenRec, *miDCScreenPtr;
+
+#define miGetDCScreen(s) ((miDCScreenPtr)(dixLookupPrivate(&(s)->devPrivates, miDCScreenKey)))
Bool
miDCInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs)
@@ -105,13 +100,11 @@ miDCInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs)
miDCScreenPtr pScreenPriv;
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));
+ pScreenPriv = calloc(1, sizeof(miDCScreenRec));
if (!pScreenPriv)
return FALSE;
@@ -127,6 +120,28 @@ miDCInitialize(ScreenPtr pScreen, miPointerScreenFuncPtr screenFuncs)
return TRUE;
}
+static void
+miDCSwitchScreenCursor(ScreenPtr pScreen, CursorPtr pCursor, PixmapPtr sourceBits, PixmapPtr maskBits, PicturePtr pPicture)
+{
+ miDCScreenPtr pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miDCScreenKey);
+
+ if (pScreenPriv->sourceBits)
+ (*pScreen->DestroyPixmap)(pScreenPriv->sourceBits);
+ pScreenPriv->sourceBits = sourceBits;
+
+ if (pScreenPriv->maskBits)
+ (*pScreen->DestroyPixmap)(pScreenPriv->maskBits);
+ pScreenPriv->maskBits = maskBits;
+
+#ifdef ARGB_CURSOR
+ if (pScreenPriv->pPicture)
+ FreePicture(pScreenPriv->pPicture, 0);
+ pScreenPriv->pPicture = pPicture;
+#endif
+
+ pScreenPriv->pCursor = pCursor;
+}
+
static Bool
miDCCloseScreen(ScreenPtr pScreen)
{
@@ -135,6 +150,8 @@ miDCCloseScreen(ScreenPtr pScreen)
pScreenPriv = (miDCScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
miDCScreenKey);
pScreen->CloseScreen = pScreenPriv->CloseScreen;
+
+ miDCSwitchScreenCursor(pScreen, NULL, NULL, NULL, NULL);
free((pointer) pScreenPriv);
return (*pScreen->CloseScreen) (pScreen);
}
@@ -142,9 +159,6 @@ miDCCloseScreen(ScreenPtr pScreen)
Bool
miDCRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
{
- if (pCursor->bits->refcnt <= 1)
- dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey,
- pScreen, NULL);
return TRUE;
}
@@ -154,8 +168,6 @@ miDCRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
static PicturePtr
miDCMakePicture(PicturePtr * ppPicture, DrawablePtr pDraw, WindowPtr pWin)
{
- ScreenPtr pScreen = pDraw->pScreen;
- VisualPtr pVisual;
PictFormatPtr pFormat;
XID subwindow_mode = IncludeInferiors;
PicturePtr pPicture;
@@ -172,42 +184,39 @@ miDCMakePicture(PicturePtr * ppPicture, DrawablePtr pDraw, WindowPtr pWin)
}
#endif
-static miDCCursorPtr
+static Bool
miDCRealize(ScreenPtr pScreen, CursorPtr pCursor)
{
- miDCCursorPtr pPriv;
+ miDCScreenPtr pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miDCScreenKey);
GCPtr pGC;
ChangeGCVal gcvals;
+ PixmapPtr sourceBits, maskBits;
+
+ if (pScreenPriv->pCursor == pCursor)
+ return TRUE;
- pPriv = malloc(sizeof(miDCCursorRec));
- if (!pPriv)
- return NULL;
#ifdef ARGB_CURSOR
+
if (pCursor->bits->argb) {
PixmapPtr pPixmap;
PictFormatPtr pFormat;
int error;
+ PicturePtr pPicture;
pFormat = PictureMatchFormat(pScreen, 32, PICT_a8r8g8b8);
- if (!pFormat) {
- free((pointer) pPriv);
- return NULL;
- }
+ if (!pFormat)
+ return FALSE;
- pPriv->sourceBits = 0;
- pPriv->maskBits = 0;
pPixmap = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width,
pCursor->bits->height, 32,
CREATE_PIXMAP_USAGE_SCRATCH);
- if (!pPixmap) {
- free((pointer) pPriv);
- return NULL;
- }
+ if (!pPixmap)
+ return FALSE;
+
pGC = GetScratchGC(32, pScreen);
if (!pGC) {
(*pScreen->DestroyPixmap) (pPixmap);
- free((pointer) pPriv);
- return NULL;
+ return FALSE;
}
ValidateGC(&pPixmap->drawable, pGC);
(*pGC->ops->PutImage) (&pPixmap->drawable, pGC, 32,
@@ -215,105 +224,86 @@ miDCRealize(ScreenPtr pScreen, CursorPtr pCursor)
pCursor->bits->height,
0, ZPixmap, (char *) pCursor->bits->argb);
FreeScratchGC(pGC);
- pPriv->pPicture = CreatePicture(0, &pPixmap->drawable,
- pFormat, 0, 0, serverClient, &error);
+ pPicture = CreatePicture(0, &pPixmap->drawable,
+ pFormat, 0, 0, serverClient, &error);
(*pScreen->DestroyPixmap) (pPixmap);
- if (!pPriv->pPicture) {
- free((pointer) pPriv);
- return NULL;
- }
- dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey,
- pScreen, pPriv);
- return pPriv;
+ if (!pPicture)
+ return FALSE;
+
+ miDCSwitchScreenCursor(pScreen, pCursor, NULL, NULL, pPicture);
+ return TRUE;
}
- pPriv->pPicture = 0;
#endif
- pPriv->sourceBits =
- (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width,
- pCursor->bits->height, 1, 0);
- if (!pPriv->sourceBits) {
- free((pointer) pPriv);
- return NULL;
- }
- pPriv->maskBits =
- (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width,
- pCursor->bits->height, 1, 0);
- if (!pPriv->maskBits) {
- (*pScreen->DestroyPixmap) (pPriv->sourceBits);
- free((pointer) pPriv);
- return NULL;
+ sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width,
+ pCursor->bits->height, 1, 0);
+ if (!sourceBits)
+ return FALSE;
+
+ maskBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width,
+ pCursor->bits->height, 1, 0);
+ if (!maskBits) {
+ (*pScreen->DestroyPixmap) (sourceBits);
+ return FALSE;
}
- dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey, pScreen,
- pPriv);
/* create the two sets of bits, clipping as appropriate */
pGC = GetScratchGC(1, pScreen);
if (!pGC) {
- (void) miDCUnrealizeCursor(pScreen, pCursor);
- return NULL;
+ (*pScreen->DestroyPixmap) (sourceBits);
+ (*pScreen->DestroyPixmap) (maskBits);
+ return FALSE;
}
- ValidateGC((DrawablePtr) pPriv->sourceBits, pGC);
- (*pGC->ops->PutImage) ((DrawablePtr) pPriv->sourceBits, pGC, 1,
+ ValidateGC((DrawablePtr) sourceBits, pGC);
+ (*pGC->ops->PutImage) ((DrawablePtr) sourceBits, pGC, 1,
0, 0, pCursor->bits->width, pCursor->bits->height,
0, XYPixmap, (char *) pCursor->bits->source);
gcvals.val = GXand;
ChangeGC(NullClient, pGC, GCFunction, &gcvals);
- ValidateGC((DrawablePtr) pPriv->sourceBits, pGC);
- (*pGC->ops->PutImage) ((DrawablePtr) pPriv->sourceBits, pGC, 1,
+ ValidateGC((DrawablePtr) sourceBits, pGC);
+ (*pGC->ops->PutImage) ((DrawablePtr) sourceBits, pGC, 1,
0, 0, pCursor->bits->width, pCursor->bits->height,
0, XYPixmap, (char *) pCursor->bits->mask);
/* mask bits -- pCursor->mask & ~pCursor->source */
gcvals.val = GXcopy;
ChangeGC(NullClient, pGC, GCFunction, &gcvals);
- ValidateGC((DrawablePtr) pPriv->maskBits, pGC);
- (*pGC->ops->PutImage) ((DrawablePtr) pPriv->maskBits, pGC, 1,
+ ValidateGC((DrawablePtr) maskBits, pGC);
+ (*pGC->ops->PutImage) ((DrawablePtr) maskBits, pGC, 1,
0, 0, pCursor->bits->width, pCursor->bits->height,
0, XYPixmap, (char *) pCursor->bits->mask);
gcvals.val = GXandInverted;
ChangeGC(NullClient, pGC, GCFunction, &gcvals);
- ValidateGC((DrawablePtr) pPriv->maskBits, pGC);
- (*pGC->ops->PutImage) ((DrawablePtr) pPriv->maskBits, pGC, 1,
+ ValidateGC((DrawablePtr) maskBits, pGC);
+ (*pGC->ops->PutImage) ((DrawablePtr) maskBits, pGC, 1,
0, 0, pCursor->bits->width, pCursor->bits->height,
0, XYPixmap, (char *) pCursor->bits->source);
FreeScratchGC(pGC);
- return pPriv;
+
+ miDCSwitchScreenCursor(pScreen, pCursor, sourceBits, maskBits, NULL);
+ return TRUE;
}
Bool
miDCUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
{
- miDCCursorPtr pPriv;
-
- pPriv = (miDCCursorPtr) dixLookupScreenPrivate(&pCursor->bits->devPrivates,
- miDCCursorBitsKey, pScreen);
- if (pPriv && (pCursor->bits->refcnt <= 1)) {
- if (pPriv->sourceBits)
- (*pScreen->DestroyPixmap) (pPriv->sourceBits);
- if (pPriv->maskBits)
- (*pScreen->DestroyPixmap) (pPriv->maskBits);
-#ifdef ARGB_CURSOR
- if (pPriv->pPicture)
- FreePicture(pPriv->pPicture, 0);
-#endif
- free((pointer) pPriv);
- dixSetScreenPrivate(&pCursor->bits->devPrivates, miDCCursorBitsKey,
- pScreen, NULL);
- }
+ miDCScreenPtr pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miDCScreenKey);
+
+ if (pCursor == pScreenPriv->pCursor)
+ miDCSwitchScreenCursor(pScreen, NULL, NULL, NULL, NULL);
return TRUE;
}
static void
miDCPutBits(DrawablePtr pDrawable,
- miDCCursorPtr pPriv,
GCPtr sourceGC,
GCPtr maskGC,
int x_org,
int y_org,
unsigned w, unsigned h, unsigned long source, unsigned long mask)
{
+ miDCScreenPtr pScreenPriv = dixLookupPrivate(&pDrawable->pScreen->devPrivates, miDCScreenKey);
ChangeGCVal gcval;
int x, y;
@@ -333,7 +323,7 @@ miDCPutBits(DrawablePtr pDrawable,
y = y_org;
}
- (*sourceGC->ops->PushPixels) (sourceGC, pPriv->sourceBits, pDrawable, w, h,
+ (*sourceGC->ops->PushPixels) (sourceGC, pScreenPriv->sourceBits, pDrawable, w, h,
x, y);
if (maskGC->fgPixel != mask) {
gcval.val = mask;
@@ -351,7 +341,7 @@ miDCPutBits(DrawablePtr pDrawable,
y = y_org;
}
- (*maskGC->ops->PushPixels) (maskGC, pPriv->maskBits, pDrawable, w, h, x, y);
+ (*maskGC->ops->PushPixels) (maskGC, pScreenPriv->maskBits, pDrawable, w, h, x, y);
}
static GCPtr
@@ -373,27 +363,22 @@ Bool
miDCPutUpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
int x, int y, unsigned long source, unsigned long mask)
{
- miDCCursorPtr pPriv;
+ miDCScreenPtr pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miDCScreenKey);
miDCBufferPtr pBuffer;
WindowPtr pWin;
- pPriv = (miDCCursorPtr) dixLookupScreenPrivate(&pCursor->bits->devPrivates,
- miDCCursorBitsKey, pScreen);
- if (!pPriv) {
- pPriv = miDCRealize(pScreen, pCursor);
- if (!pPriv)
- return FALSE;
- }
+ if (!miDCRealize(pScreen, pCursor))
+ return FALSE;
pWin = pScreen->root;
pBuffer = miGetDCDevice(pDev, pScreen);
#ifdef ARGB_CURSOR
- if (pPriv->pPicture) {
+ if (pScreenPriv->pPicture) {
if (!EnsurePicture(pBuffer->pRootPicture, &pWin->drawable, pWin))
return FALSE;
CompositePicture(PictOpOver,
- pPriv->pPicture,
+ pScreenPriv->pPicture,
NULL,
pBuffer->pRootPicture,
0, 0, 0, 0,
@@ -402,7 +387,7 @@ miDCPutUpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
else
#endif
{
- miDCPutBits((DrawablePtr) pWin, pPriv,
+ miDCPutBits((DrawablePtr) pWin,
pBuffer->pSourceGC, pBuffer->pMaskGC,
x, y, pCursor->bits->width, pCursor->bits->height,
source, mask);
diff --git a/xorg-server/os/utils.c b/xorg-server/os/utils.c
index 998c3ed4a..253793467 100644
--- a/xorg-server/os/utils.c
+++ b/xorg-server/os/utils.c
@@ -1167,15 +1167,15 @@ OsBlockSignals(void)
if (BlockedSignalCount++ == 0) {
sigset_t set;
+#ifdef SIGIO
+ OsBlockSIGIO();
+#endif
sigemptyset(&set);
sigaddset(&set, SIGALRM);
sigaddset(&set, SIGVTALRM);
#ifdef SIGWINCH
sigaddset(&set, SIGWINCH);
#endif
-#ifdef SIGIO
- sigaddset(&set, SIGIO);
-#endif
sigaddset(&set, SIGTSTP);
sigaddset(&set, SIGTTIN);
sigaddset(&set, SIGTTOU);
@@ -1185,12 +1185,60 @@ OsBlockSignals(void)
#endif
}
+#ifdef SIG_BLOCK
+static sig_atomic_t sigio_blocked;
+#endif
+
+/**
+ * returns zero if this call caused SIGIO to be blocked now, non-zero if it
+ * was already blocked by a previous call to this function.
+ */
+int
+OsBlockSIGIO(void)
+{
+#ifdef SIGIO
+#ifdef SIG_BLOCK
+ if (sigio_blocked++ == 0) {
+ sigset_t set, old;
+ int ret;
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGIO);
+ sigprocmask(SIG_BLOCK, &set, &old);
+ ret = sigismember(&old, SIGIO);
+ return ret;
+ } else
+ return 1;
+#endif
+#endif
+}
+
+void
+OsReleaseSIGIO(void)
+{
+#ifdef SIGIO
+#ifdef SIG_BLOCK
+ if (--sigio_blocked == 0) {
+ sigset_t set;
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGIO);
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
+ } else if (sigio_blocked < 0) {
+ BUG_WARN(sigio_blocked < 0);
+ sigio_blocked = 0;
+ }
+#endif
+#endif
+}
+
void
OsReleaseSignals(void)
{
#ifdef SIG_BLOCK
if (--BlockedSignalCount == 0) {
sigprocmask(SIG_SETMASK, &PreviousSignalMask, 0);
+ OsReleaseSIGIO();
}
#endif
}
diff --git a/xorg-server/render/picture.c b/xorg-server/render/picture.c
index ebbfa29e9..2908b7629 100644
--- a/xorg-server/render/picture.c
+++ b/xorg-server/render/picture.c
@@ -763,7 +763,8 @@ CreatePicture(Picture pid,
PicturePtr pPicture;
PictureScreenPtr ps = GetPictureScreen(pDrawable->pScreen);
- pPicture = dixAllocateObjectWithPrivates(PictureRec, PRIVATE_PICTURE);
+ pPicture = dixAllocateScreenObjectWithPrivates(pDrawable->pScreen,
+ PictureRec, PRIVATE_PICTURE);
if (!pPicture) {
*error = BadAlloc;
return 0;
@@ -853,7 +854,7 @@ createSourcePicture(void)
{
PicturePtr pPicture;
- pPicture = dixAllocateObjectWithPrivates(PictureRec, PRIVATE_PICTURE);
+ pPicture = dixAllocateScreenObjectWithPrivates(NULL, PictureRec, PRIVATE_PICTURE);
pPicture->pDrawable = 0;
pPicture->pFormat = 0;
pPicture->pNext = 0;
diff --git a/xorg-server/test/Makefile.am b/xorg-server/test/Makefile.am
index e5b25c97f..15c51ed22 100644
--- a/xorg-server/test/Makefile.am
+++ b/xorg-server/test/Makefile.am
@@ -5,7 +5,7 @@ if XORG
# Tests that require at least some DDX functions in order to fully link
# For now, requires xf86 ddx, could be adjusted to use another
SUBDIRS += xi2
-noinst_PROGRAMS += xkb input xtest misc fixes xfree86 hashtabletest signal-logging
+noinst_PROGRAMS += xkb input xtest misc fixes xfree86 hashtabletest os signal-logging
endif
check_LTLIBRARIES = libxservertest.la
@@ -38,6 +38,7 @@ xfree86_LDADD=$(TEST_LDADD)
touch_LDADD=$(TEST_LDADD)
signal_logging_LDADD=$(TEST_LDADD)
hashtabletest_LDADD=$(TEST_LDADD) $(top_srcdir)/Xext/hashtable.c
+os_LDADD=$(TEST_LDADD)
libxservertest_la_LIBADD = $(XSERVER_LIBS)
if XORG
diff --git a/xorg-server/test/os.c b/xorg-server/test/os.c
new file mode 100644
index 000000000..1460a34d6
--- /dev/null
+++ b/xorg-server/test/os.c
@@ -0,0 +1,130 @@
+/**
+ * Copyright © 2012 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <signal.h>
+#include "os.h"
+
+static int
+sig_is_blocked(int sig)
+{
+ sigset_t current;
+
+ sigemptyset(&current);
+ assert(sigprocmask(SIG_BLOCK, NULL, &current) == 0);
+ return sigismember(&current, sig);
+}
+
+static void block_sigio_test(void)
+{
+#ifdef SIG_BLOCK
+ sigset_t current;
+
+ sigemptyset(&current);
+ assert(!sig_is_blocked(SIGIO));
+
+ /* block once */
+ OsBlockSIGIO();
+ assert(sig_is_blocked(SIGIO));
+ OsReleaseSIGIO();
+ assert(!sig_is_blocked(SIGIO));
+
+ /* block twice, nested */
+ OsBlockSIGIO();
+ assert(sig_is_blocked(SIGIO));
+ OsBlockSIGIO();
+ assert(sig_is_blocked(SIGIO));
+ OsReleaseSIGIO();
+ assert(sig_is_blocked(SIGIO));
+ OsReleaseSIGIO();
+ assert(!sig_is_blocked(SIGIO));
+
+ /* block all */
+ OsBlockSignals();
+ assert(sig_is_blocked(SIGIO));
+ OsReleaseSignals();
+ assert(!sig_is_blocked(SIGIO));
+
+ /* block all nested */
+ OsBlockSignals();
+ assert(sig_is_blocked(SIGIO));
+ OsBlockSignals();
+ assert(sig_is_blocked(SIGIO));
+ OsReleaseSignals();
+ assert(sig_is_blocked(SIGIO));
+ OsReleaseSignals();
+ assert(!sig_is_blocked(SIGIO));
+
+ /* mix the two */
+ /* ABBA */
+ OsBlockSignals();
+ assert(sig_is_blocked(SIGIO));
+ OsBlockSIGIO();
+ assert(sig_is_blocked(SIGIO));
+ OsReleaseSIGIO();
+ assert(sig_is_blocked(SIGIO));
+ OsReleaseSignals();
+ assert(!sig_is_blocked(SIGIO));
+
+ /* ABAB */
+ OsBlockSignals();
+ assert(sig_is_blocked(SIGIO));
+ OsBlockSIGIO();
+ assert(sig_is_blocked(SIGIO));
+ OsReleaseSignals();
+ assert(sig_is_blocked(SIGIO));
+ OsReleaseSIGIO();
+ assert(!sig_is_blocked(SIGIO));
+
+ /* BAAB */
+ OsBlockSIGIO();
+ assert(sig_is_blocked(SIGIO));
+ OsBlockSignals();
+ assert(sig_is_blocked(SIGIO));
+ OsReleaseSignals();
+ assert(sig_is_blocked(SIGIO));
+ OsReleaseSIGIO();
+ assert(!sig_is_blocked(SIGIO));
+
+ /* BABA */
+ OsBlockSIGIO();
+ assert(sig_is_blocked(SIGIO));
+ OsBlockSignals();
+ assert(sig_is_blocked(SIGIO));
+ OsReleaseSIGIO();
+ assert(sig_is_blocked(SIGIO));
+ OsReleaseSignals();
+ assert(!sig_is_blocked(SIGIO));
+
+#endif
+}
+
+int
+main(int argc, char **argv)
+{
+ block_sigio_test();
+ return 0;
+}
diff --git a/xorg-server/xkb/xkbAccessX.c b/xorg-server/xkb/xkbAccessX.c
index fe28e12d7..082c0db57 100644
--- a/xorg-server/xkb/xkbAccessX.c
+++ b/xorg-server/xkb/xkbAccessX.c
@@ -281,12 +281,12 @@ AccessXStickyKeysTurnOff(DeviceIntPtr dev, xkbControlsNotify * pCN)
static CARD32
AccessXKRGExpire(OsTimerPtr timer, CARD32 now, pointer arg)
{
- XkbSrvInfoPtr xkbi = ((DeviceIntPtr) arg)->key->xkbInfo;
xkbControlsNotify cn;
+ DeviceIntPtr dev = arg;
+ XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
if (xkbi->krgTimerActive == _KRG_WARN_TIMER) {
- XkbDDXAccessXBeep((DeviceIntPtr) arg, _BEEP_SLOW_WARN,
- XkbStickyKeysMask);
+ XkbDDXAccessXBeep(dev, _BEEP_SLOW_WARN, XkbStickyKeysMask);
xkbi->krgTimerActive = _KRG_TIMER;
return 4000;
}
@@ -296,11 +296,11 @@ AccessXKRGExpire(OsTimerPtr timer, CARD32 now, pointer arg)
cn.requestMajor = 0;
cn.requestMinor = 0;
if (xkbi->desc->ctrls->enabled_ctrls & XkbSlowKeysMask) {
- AccessXKRGTurnOff((DeviceIntPtr) arg, &cn);
+ AccessXKRGTurnOff(dev, &cn);
LogMessage(X_INFO, "XKB SlowKeys are disabled.\n");
}
else {
- AccessXKRGTurnOn((DeviceIntPtr) arg, XkbSlowKeysMask, &cn);
+ AccessXKRGTurnOn(dev, XkbSlowKeysMask, &cn);
LogMessage(X_INFO, "XKB SlowKeys are now enabled. Hold shift to disable.\n");
}