[PATCH 2/4] dix: Refactoring of selection code to allow for polyinstantiation.

Eamon Walsh ewalsh at tycho.nsa.gov
Wed Feb 27 20:41:46 PST 2008


Signed-off-by: Eamon Walsh <ewalsh at moss-charon.epoch.ncsc.mil>
---
 Xext/xselinux.c            |    2 -
 dix/Makefile.am            |    1 +
 dix/dispatch.c             |  274 ----------------------------------------
 dix/main.c                 |    2 +
 dix/selection.c            |  298 ++++++++++++++++++++++++++++++++++++++++++++
 hw/xfree86/loader/dixsym.c |    7 +-
 include/dix.h              |   23 ----
 include/selection.h        |   44 ++++++-
 8 files changed, 340 insertions(+), 311 deletions(-)
 create mode 100644 dix/selection.c

diff --git a/Xext/xselinux.c b/Xext/xselinux.c
index 98e1ec5..142de32 100644
--- a/Xext/xselinux.c
+++ b/Xext/xselinux.c
@@ -955,8 +955,6 @@ SELinuxSelectionState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 
     switch (rec->kind) {
     case SelectionSetOwner:
-    case SelectionGetOwner:
-    case SelectionConvertSelection:
     default:
 	break;
     }
diff --git a/dix/Makefile.am b/dix/Makefile.am
index 2cf9014..b7b1ec0 100644
--- a/dix/Makefile.am
+++ b/dix/Makefile.am
@@ -29,6 +29,7 @@ libdix_la_SOURCES = 	\
 	property.c	\
 	registry.c	\
 	resource.c	\
+	selection.c	\
 	swaprep.c	\
 	swapreq.c	\
 	tables.c	\
diff --git a/dix/dispatch.c b/dix/dispatch.c
index e8e650a..bb8b0c4 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -165,10 +165,6 @@ typedef const char *string;
 extern xConnSetupPrefix connSetupPrefix;
 extern char *ConnectionInfo;
 
-_X_EXPORT Selection *CurrentSelections;
-_X_EXPORT int NumCurrentSelections;
-CallbackListPtr SelectionCallback = NULL;
-
 static ClientPtr grabClient;
 #define GrabNone 0
 #define GrabActive 1
@@ -181,8 +177,6 @@ extern int connBlockScreenStart;
 
 static void KillAllClients(void);
 
-static void DeleteClientFromAnySelections(ClientPtr client);
-
 static int nextFreeClientID; /* always MIN free client ID */
 
 static int	nClients;	/* number of authorized clients */
@@ -246,14 +240,6 @@ UpdateCurrentTimeIf(void)
 	currentTime = systime;
 }
 
-static void
-InitSelections(void)
-{
-    if (CurrentSelections)
-	xfree(CurrentSelections);
-    CurrentSelections = (Selection *)NULL;
-    NumCurrentSelections = 0;
-}
 #ifdef SMART_SCHEDULE
 
 #undef SMART_DEBUG
@@ -372,7 +358,6 @@ Dispatch(void)
 #endif
 
     nextFreeClientID = 1;
-    InitSelections();
     nClients = 0;
 
     clientReady = (int *) xalloc(sizeof(int) * MaxClients);
@@ -968,217 +953,6 @@ ProcGetAtomName(ClientPtr client)
 }
 
 int
-ProcSetSelectionOwner(ClientPtr client)
-{
-    WindowPtr pWin;
-    TimeStamp time;
-    int rc;
-    REQUEST(xSetSelectionOwnerReq);
-    REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
-
-    UpdateCurrentTime();
-    time = ClientTimeToServerTime(stuff->time);
-
-    /* If the client's time stamp is in the future relative to the server's
-	time stamp, do not set the selection, just return success. */
-    if (CompareTimeStamps(time, currentTime) == LATER)
-    	return Success;
-    if (stuff->window != None)
-    {
-	rc = dixLookupWindow(&pWin, stuff->window, client, DixSetAttrAccess);
-        if (rc != Success)
-            return rc;
-    }
-    else
-        pWin = (WindowPtr)None;
-    if (ValidAtom(stuff->selection))
-    {
-	int i = 0;
-
-	rc = XaceHookSelectionAccess(client, stuff->selection,
-				     DixSetAttrAccess);
-	if (rc != Success)
-	    return rc;
-
-	/*
-	 * First, see if the selection is already set... 
-	 */
-	while ((i < NumCurrentSelections) && 
-	       CurrentSelections[i].selection != stuff->selection) 
-            i++;
-        if (i < NumCurrentSelections)
-        {        
-	    xEvent event;
-
-	    /* If the timestamp in client's request is in the past relative
-		to the time stamp indicating the last time the owner of the
-		selection was set, do not set the selection, just return 
-		success. */
-            if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
-		== EARLIER)
-		return Success;
-	    if (CurrentSelections[i].client &&
-		(!pWin || (CurrentSelections[i].client != client)))
-	    {
-		event.u.u.type = SelectionClear;
-		event.u.selectionClear.time = time.milliseconds;
-		event.u.selectionClear.window = CurrentSelections[i].window;
-		event.u.selectionClear.atom = CurrentSelections[i].selection;
-		(void) TryClientEvents (CurrentSelections[i].client, &event, 1,
-				NoEventMask, NoEventMask /* CantBeFiltered */,
-				NullGrab);
-	    }
-	}
-	else
-	{
-	    /*
-	     * It doesn't exist, so add it...
-	     */
-	    Selection *newsels;
-
-	    if (i == 0)
-		newsels = (Selection *)xalloc(sizeof(Selection));
-	    else
-		newsels = (Selection *)xrealloc(CurrentSelections,
-			    (NumCurrentSelections + 1) * sizeof(Selection));
-	    if (!newsels)
-		return BadAlloc;
-	    NumCurrentSelections++;
-	    CurrentSelections = newsels;
-	    CurrentSelections[i].selection = stuff->selection;
-	    CurrentSelections[i].devPrivates = NULL;
-	}
-        CurrentSelections[i].lastTimeChanged = time;
-	CurrentSelections[i].window = stuff->window;
-	CurrentSelections[i].pWin = pWin;
-	CurrentSelections[i].client = (pWin ? client : NullClient);
-	if (SelectionCallback)
-	{
-	    SelectionInfoRec	info;
-
-	    info.selection = &CurrentSelections[i];
-	    info.client = client;
-	    info.kind= SelectionSetOwner;
-	    CallCallbacks(&SelectionCallback, &info);
-	}
-	return (client->noClientException);
-    }
-    else 
-    {
-	client->errorValue = stuff->selection;
-        return (BadAtom);
-    }
-}
-
-int
-ProcGetSelectionOwner(ClientPtr client)
-{
-    REQUEST(xResourceReq);
-
-    REQUEST_SIZE_MATCH(xResourceReq);
-    if (ValidAtom(stuff->id))
-    {
-	int rc, i;
-        xGetSelectionOwnerReply reply;
-
-	rc = XaceHookSelectionAccess(client, stuff->id, DixGetAttrAccess);
-	if (rc != Success)
-	    return rc;
-
-	i = 0;
-        while ((i < NumCurrentSelections) && 
-	       CurrentSelections[i].selection != stuff->id) i++;
-        reply.type = X_Reply;
-	reply.length = 0;
-	reply.sequenceNumber = client->sequence;
-	if (i < NumCurrentSelections) {
-	    if (SelectionCallback) {
-		SelectionInfoRec info;
-
-		info.selection = &CurrentSelections[i];
-		info.client = client;
-		info.kind= SelectionGetOwner;
-		CallCallbacks(&SelectionCallback, &info);
-	    }
-            reply.owner = CurrentSelections[i].window;
-	} else
-            reply.owner = None;
-        WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
-        return(client->noClientException);
-    }
-    else            
-    {
-	client->errorValue = stuff->id;
-        return (BadAtom); 
-    }
-}
-
-int
-ProcConvertSelection(ClientPtr client)
-{
-    Bool paramsOkay;
-    xEvent event;
-    WindowPtr pWin;
-    REQUEST(xConvertSelectionReq);
-    int rc;
-
-    REQUEST_SIZE_MATCH(xConvertSelectionReq);
-    rc = dixLookupWindow(&pWin, stuff->requestor, client, DixSetAttrAccess);
-    if (rc != Success)
-        return rc;
-    rc = XaceHookSelectionAccess(client, stuff->selection, DixReadAccess);
-    if (rc != Success)
-	return rc;
-
-    paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
-    if (stuff->property != None)
-	paramsOkay &= ValidAtom(stuff->property);
-    if (paramsOkay)
-    {
-	int i;
-
-	i = 0;
-	while ((i < NumCurrentSelections) && 
-	       CurrentSelections[i].selection != stuff->selection) i++;
-	if (i < NumCurrentSelections && CurrentSelections[i].window != None) {
-	    if (SelectionCallback) {
-		SelectionInfoRec info;
-
-		info.selection = &CurrentSelections[i];
-		info.client = client;
-		info.kind= SelectionConvertSelection;
-		CallCallbacks(&SelectionCallback, &info);
-	    }
-	    event.u.u.type = SelectionRequest;
-	    event.u.selectionRequest.time = stuff->time;
-	    event.u.selectionRequest.owner = CurrentSelections[i].window;
-	    event.u.selectionRequest.requestor = stuff->requestor;
-	    event.u.selectionRequest.selection = stuff->selection;
-	    event.u.selectionRequest.target = stuff->target;
-	    event.u.selectionRequest.property = stuff->property;
-	    if (TryClientEvents(
-		CurrentSelections[i].client, &event, 1, NoEventMask,
-		NoEventMask /* CantBeFiltered */, NullGrab))
-		return (client->noClientException);
-	}
-	event.u.u.type = SelectionNotify;
-	event.u.selectionNotify.time = stuff->time;
-	event.u.selectionNotify.requestor = stuff->requestor;
-	event.u.selectionNotify.selection = stuff->selection;
-	event.u.selectionNotify.target = stuff->target;
-	event.u.selectionNotify.property = None;
-	(void) TryClientEvents(client, &event, 1, NoEventMask,
-			       NoEventMask /* CantBeFiltered */, NullGrab);
-	return (client->noClientException);
-    }
-    else 
-    {
-	client->errorValue = stuff->property;
-        return (BadAtom);
-    }
-}
-
-int
 ProcGrabServer(ClientPtr client)
 {
     int rc;
@@ -3981,54 +3755,6 @@ SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
 }
 
 void
-DeleteWindowFromAnySelections(WindowPtr pWin)
-{
-    int i;
-
-    for (i = 0; i< NumCurrentSelections; i++)
-        if (CurrentSelections[i].pWin == pWin)
-        {
-	    if (SelectionCallback)
-	    {
-	        SelectionInfoRec    info;
-
-		info.selection = &CurrentSelections[i];
-		info.kind = SelectionWindowDestroy;
-		CallCallbacks(&SelectionCallback, &info);
-	    }
-	    dixFreePrivates(CurrentSelections[i].devPrivates);
-            CurrentSelections[i].pWin = (WindowPtr)NULL;
-            CurrentSelections[i].window = None;
-	    CurrentSelections[i].client = NullClient;
-	    CurrentSelections[i].devPrivates = NULL;
-	}
-}
-
-static void
-DeleteClientFromAnySelections(ClientPtr client)
-{
-    int i;
-
-    for (i = 0; i< NumCurrentSelections; i++)
-        if (CurrentSelections[i].client == client)
-        {
-	    if (SelectionCallback)
-	    {
-	        SelectionInfoRec    info;
-
-		info.selection = &CurrentSelections[i];
-		info.kind = SelectionWindowDestroy;
-		CallCallbacks(&SelectionCallback, &info);
-	    }
-	    dixFreePrivates(CurrentSelections[i].devPrivates);
-            CurrentSelections[i].pWin = (WindowPtr)NULL;
-            CurrentSelections[i].window = None;
-	    CurrentSelections[i].client = NullClient;
-	    CurrentSelections[i].devPrivates = NULL;
-	}
-}
-
-void
 MarkClientException(ClientPtr client)
 {
     client->noClientException = -1;
diff --git a/dix/main.c b/dix/main.c
index 068dae9..db43473 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -93,6 +93,7 @@ Equipment Corporation.
 #include "colormap.h"
 #include "colormapst.h"
 #include "cursorstr.h"
+#include "selection.h"
 #include <X11/fonts/font.h>
 #include "opaque.h"
 #include "servermd.h"
@@ -346,6 +347,7 @@ main(int argc, char *argv[], char *envp[])
 
 	InitAtoms();
 	InitEvents();
+	InitSelections();
 	InitGlyphCaching();
 	if (!dixResetPrivates())
 	    FatalError("couldn't init private data storage");
diff --git a/dix/selection.c b/dix/selection.c
new file mode 100644
index 0000000..e04fa5c
--- /dev/null
+++ b/dix/selection.c
@@ -0,0 +1,298 @@
+/************************************************************
+
+Copyright 1987, 1989, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "windowstr.h"
+#include "dixstruct.h"
+#include "dispatch.h"
+#include "selection.h"
+#include "xace.h"
+
+/*****************************************************************
+ * Selection Stuff
+ *
+ *    dixLookupSelection
+ *
+ *   Selections are global to the server.  The list of selections should
+ *   not be traversed directly.  Instead, use the functions listed above.
+ *
+ *****************************************************************/
+
+static Selection *CurrentSelections;
+static int NumCurrentSelections;
+CallbackListPtr SelectionCallback;
+
+_X_EXPORT int
+dixLookupSelection(Selection **result, Atom selectionName,
+		   ClientPtr client, Mask access_mode)
+{
+    Selection *pSel = NULL;
+    int i, rc = BadMatch;
+    client->errorValue = selectionName;
+
+    for (i = 0; i < NumCurrentSelections; i++)
+	if (CurrentSelections[i].selection == selectionName) {
+	    pSel = CurrentSelections + i;
+	    rc = XaceHookSelectionAccess(client, selectionName, access_mode);
+	    break;
+	}
+
+    *result = pSel;
+    return rc;
+}
+
+void
+InitSelections(void)
+{
+    xfree(CurrentSelections);
+    CurrentSelections = NULL;
+    NumCurrentSelections = 0;
+}
+
+static _X_INLINE void
+CallSelectionCallback(Selection *pSel, ClientPtr client,
+		      SelectionCallbackKind kind)
+{
+    SelectionInfoRec info = { pSel, client, kind };
+    CallCallbacks(&SelectionCallback, &info);
+}
+
+void
+DeleteWindowFromAnySelections(WindowPtr pWin)
+{
+    Selection *pSel = CurrentSelections;
+
+    for (; pSel - CurrentSelections < NumCurrentSelections; pSel++)
+        if (pSel->pWin == pWin) {
+	    CallSelectionCallback(pSel, NULL, SelectionWindowDestroy);
+
+            pSel->pWin = (WindowPtr)NULL;
+            pSel->window = None;
+	    pSel->client = NullClient;
+	}
+}
+
+void
+DeleteClientFromAnySelections(ClientPtr client)
+{
+    Selection *pSel = CurrentSelections;
+
+    for (; pSel - CurrentSelections < NumCurrentSelections; pSel++)
+        if (pSel->client == client) {
+	    CallSelectionCallback(pSel, NULL, SelectionClientClose);
+
+            pSel->pWin = (WindowPtr)NULL;
+            pSel->window = None;
+	    pSel->client = NullClient;
+	}
+}
+
+int
+ProcSetSelectionOwner(ClientPtr client)
+{
+    WindowPtr pWin = NULL;
+    TimeStamp time;
+    Selection *pSel;
+    int rc;
+
+    REQUEST(xSetSelectionOwnerReq);
+    REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+
+    UpdateCurrentTime();
+    time = ClientTimeToServerTime(stuff->time);
+
+    /* If the client's time stamp is in the future relative to the server's
+	time stamp, do not set the selection, just return success. */
+    if (CompareTimeStamps(time, currentTime) == LATER)
+    	return Success;
+
+    if (stuff->window != None) {
+	rc = dixLookupWindow(&pWin, stuff->window, client, DixSetAttrAccess);
+        if (rc != Success)
+            return rc;
+    }
+    if (!ValidAtom(stuff->selection)) {
+	client->errorValue = stuff->selection;
+        return BadAtom;
+    }
+
+    /*
+     * First, see if the selection is already set...
+     */
+    rc = dixLookupSelection(&pSel, stuff->selection, client, DixSetAttrAccess);
+
+    if (rc == Success) {
+	xEvent event;
+
+	/* If the timestamp in client's request is in the past relative
+	   to the time stamp indicating the last time the owner of the
+	   selection was set, do not set the selection, just return 
+	   success. */
+	if (CompareTimeStamps(time, pSel->lastTimeChanged) == EARLIER)
+	    return Success;
+	if (pSel->client && (!pWin || (pSel->client != client)))
+	{
+	    event.u.u.type = SelectionClear;
+	    event.u.selectionClear.time = time.milliseconds;
+	    event.u.selectionClear.window = pSel->window;
+	    event.u.selectionClear.atom = pSel->selection;
+	    TryClientEvents(pSel->client, &event, 1, NoEventMask,
+			    NoEventMask /* CantBeFiltered */, NullGrab);
+	}
+    }
+    else if (rc == BadMatch)
+    {
+	/*
+	 * It doesn't exist, so add it...
+	 */
+	int size = (NumCurrentSelections + 1) * sizeof(Selection);
+	CurrentSelections = xrealloc(CurrentSelections, size);
+	if (!CurrentSelections) {
+	    NumCurrentSelections = 0;
+	    return BadAlloc;
+	}
+	pSel = CurrentSelections + NumCurrentSelections;
+	pSel->selection = stuff->selection;
+	pSel->devPrivates = NULL;
+	NumCurrentSelections++;
+    }
+    else
+	return rc;
+
+    pSel->lastTimeChanged = time;
+    pSel->window = stuff->window;
+    pSel->pWin = pWin;
+    pSel->client = (pWin ? client : NullClient);
+
+    CallSelectionCallback(pSel, client, SelectionSetOwner);
+    return client->noClientException;
+}
+
+int
+ProcGetSelectionOwner(ClientPtr client)
+{
+    int rc;
+    Selection *pSel;
+    xGetSelectionOwnerReply reply;
+
+    REQUEST(xResourceReq);
+    REQUEST_SIZE_MATCH(xResourceReq);
+
+    if (!ValidAtom(stuff->id)) {
+	client->errorValue = stuff->id;
+        return BadAtom;
+    }
+
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+
+    rc = dixLookupSelection(&pSel, stuff->id, client, DixGetAttrAccess);
+    if (rc == Success)
+	reply.owner = pSel->window;
+    else if (rc == BadMatch)
+	reply.owner = None;
+    else
+	return rc;
+
+    WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
+    return client->noClientException;
+}
+
+int
+ProcConvertSelection(ClientPtr client)
+{
+    Bool paramsOkay;
+    xEvent event;
+    WindowPtr pWin;
+    Selection *pSel;
+    int rc;
+
+    REQUEST(xConvertSelectionReq);
+    REQUEST_SIZE_MATCH(xConvertSelectionReq);
+
+    rc = dixLookupWindow(&pWin, stuff->requestor, client, DixSetAttrAccess);
+    if (rc != Success)
+        return rc;
+
+    paramsOkay = ValidAtom(stuff->selection) && ValidAtom(stuff->target);
+    paramsOkay &= (stuff->property == None) || ValidAtom(stuff->property);
+    if (!paramsOkay) {
+	client->errorValue = stuff->property;
+        return BadAtom;
+    }
+
+    rc = dixLookupSelection(&pSel, stuff->selection, client, DixGetAttrAccess);
+
+    if (rc != Success && rc != BadMatch)
+	return rc;
+    else if (rc == Success && pSel->window != None) {
+	event.u.u.type = SelectionRequest;
+	event.u.selectionRequest.owner = pSel->window;
+	event.u.selectionRequest.time = stuff->time;
+	event.u.selectionRequest.requestor = stuff->requestor;
+	event.u.selectionRequest.selection = stuff->selection;
+	event.u.selectionRequest.target = stuff->target;
+	event.u.selectionRequest.property = stuff->property;
+	if (TryClientEvents(pSel->client, &event, 1, NoEventMask,
+			    NoEventMask /* CantBeFiltered */, NullGrab))
+	    return client->noClientException;
+    }
+
+    event.u.u.type = SelectionNotify;
+    event.u.selectionNotify.time = stuff->time;
+    event.u.selectionNotify.requestor = stuff->requestor;
+    event.u.selectionNotify.selection = stuff->selection;
+    event.u.selectionNotify.target = stuff->target;
+    event.u.selectionNotify.property = None;
+    TryClientEvents(client, &event, 1, NoEventMask,
+		    NoEventMask /* CantBeFiltered */, NullGrab);
+    return client->noClientException;
+}
diff --git a/hw/xfree86/loader/dixsym.c b/hw/xfree86/loader/dixsym.c
index e6c37fe..7054e2b 100644
--- a/hw/xfree86/loader/dixsym.c
+++ b/hw/xfree86/loader/dixsym.c
@@ -92,9 +92,6 @@
 extern int XkbDfltRepeatDelay, XkbDfltRepeatInterval;
 #endif
 
-extern Selection *CurrentSelections;
-extern int NumCurrentSelections;
-
 /* DIX things */
 
 _X_HIDDEN void *dixLookupTab[] = {
@@ -150,8 +147,6 @@ _X_HIDDEN void *dixLookupTab[] = {
     SYMVAR(isItTimeToYield)
     SYMVAR(ClientStateCallback)
     SYMVAR(ServerGrabCallback)
-    SYMVAR(CurrentSelections)
-    SYMVAR(NumCurrentSelections)
     /* dixfonts.c */
     SYMFUNC(CloseFont)
     SYMFUNC(FontToXError)
@@ -196,6 +191,8 @@ _X_HIDDEN void *dixLookupTab[] = {
     SYMFUNC(dixLookupProperty)
     SYMFUNC(ChangeWindowProperty)
     SYMFUNC(dixChangeWindowProperty)
+    /* selection.c */
+    SYMFUNC(dixLookupSelection)
     /* extension.c */
     SYMFUNC(AddExtension)
     SYMFUNC(AddExtensionAlias)
diff --git a/include/dix.h b/include/dix.h
index 52212e7..0790f58 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -166,9 +166,6 @@ extern void SendErrorToClient(
     XID /*resId*/,
     int /*errorCode*/);
 
-extern void DeleteWindowFromAnySelections(
-    WindowPtr /*pWin*/);
-
 extern void MarkClientException(
     ClientPtr /*client*/);
 
@@ -556,26 +553,6 @@ typedef struct {
     int count;
 } DeviceEventInfoRec;
 
-/*
- * SelectionCallback stuff
- */
-
-extern CallbackListPtr SelectionCallback;
-
-typedef enum {
-    SelectionSetOwner,
-    SelectionGetOwner,
-    SelectionConvertSelection,
-    SelectionWindowDestroy,
-    SelectionClientClose
-} SelectionCallbackKind;
-
-typedef struct {
-    struct _Selection	    *selection;
-    ClientPtr		    client;
-    SelectionCallbackKind   kind;
-} SelectionInfoRec;
-
 /* strcasecmp.c */
 #if NEED_STRCASECMP
 #define strcasecmp xstrcasecmp
diff --git a/include/selection.h b/include/selection.h
index 859b6a3..20749b5 100644
--- a/include/selection.h
+++ b/include/selection.h
@@ -1,7 +1,3 @@
-
-#ifndef SELECTION_H
-#define SELECTION_H 1
-
 /***********************************************************
 
 Copyright 1987, 1998  The Open Group
@@ -49,10 +45,13 @@ SOFTWARE.
 
 ******************************************************************/
 
+#ifndef SELECTION_H
+#define SELECTION_H 1
+
 #include "dixstruct.h"
 #include "privates.h"
+
 /*
- *
  *  Selection data structures 
  */
 
@@ -62,11 +61,42 @@ typedef struct _Selection {
     Window window;
     WindowPtr pWin;
     ClientPtr client;
-    ClientPtr alt_client; /* support for redirection */
-    Window alt_window;    /* support for redirection */
     PrivateRec *devPrivates;
 } Selection;
 
+
+/*
+ *  Selection API
+ */
+
+int dixLookupSelection(Selection **result, Atom name,
+		       ClientPtr client, Mask access_mode);
+
+extern CallbackListPtr SelectionCallback;
+
+typedef enum {
+    SelectionSetOwner,
+    SelectionWindowDestroy,
+    SelectionClientClose
+} SelectionCallbackKind;
+
+typedef struct {
+    struct _Selection	    *selection;
+    ClientPtr		    client;
+    SelectionCallbackKind   kind;
+} SelectionInfoRec;
+
+
+/*
+ *  Selection server internals
+ */
+
+void InitSelections(void);
+
+void DeleteWindowFromAnySelections(WindowPtr pWin);
+
+void DeleteClientFromAnySelections(ClientPtr client);
+
 #endif /* SELECTION_H */
 
 
-- 
1.5.4.3




More information about the xorg mailing list