xserver: Branch 'master' - 4 commits
Eamon Walsh
ewalsh at kemper.freedesktop.org
Fri Feb 29 15:03:39 PST 2008
Xext/security.c | 2
Xext/xace.c | 9 -
Xext/xace.h | 7
Xext/xacestr.h | 4
Xext/xselinux.c | 31 +---
dix/Makefile.am | 1
dix/dispatch.c | 274 -----------------------------------
dix/main.c | 2
dix/property.c | 225 +++++++++++++----------------
dix/selection.c | 310 ++++++++++++++++++++++++++++++++++++++++
hw/xfree86/common/xf86Init.c | 11 -
hw/xfree86/loader/dixsym.c | 9 -
hw/xprint/pcl/PclMisc.c | 17 --
hw/xprint/pcl/PclWindow.c | 6
hw/xprint/ps/PsMisc.c | 17 --
hw/xprint/ps/PsWindow.c | 6
hw/xquartz/applewm.c | 14 -
hw/xquartz/quartzPasteboard.c | 48 ++----
hw/xquartz/xpr/xprFrame.c | 4
hw/xwin/winwin32rootless.c | 4
include/dix.h | 23 --
include/property.h | 7
include/selection.h | 47 +++++-
miext/rootless/rootlessWindow.c | 4
xkb/xkbInit.c | 4
25 files changed, 554 insertions(+), 532 deletions(-)
New commits:
commit ef60632e200853680282016e32a7a9fb01882852
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date: Fri Feb 29 18:00:27 2008 -0500
dix: Modify callers of property and selection API to use new interfaces.
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index d1603c0..6d5eaad 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -172,12 +172,11 @@ xf86CreateRootWindow(WindowPtr pWin)
Atom prop;
prop = MakeAtom(pProp->name, strlen(pProp->name), TRUE);
- err = ChangeWindowProperty(pWin,
- prop, pProp->type,
- pProp->format, PropModeReplace,
- pProp->size, pProp->data,
- FALSE
- );
+ err = dixChangeWindowProperty(serverClient, pWin,
+ prop, pProp->type,
+ pProp->format, PropModeReplace,
+ pProp->size, pProp->data,
+ FALSE);
}
/* Look at err */
diff --git a/hw/xprint/pcl/PclMisc.c b/hw/xprint/pcl/PclMisc.c
index e0b7dce..0b37836 100644
--- a/hw/xprint/pcl/PclMisc.c
+++ b/hw/xprint/pcl/PclMisc.c
@@ -115,7 +115,7 @@ GetPropString(
if(atom != BAD_RESOURCE)
{
WindowPtr pPropWin;
- int n;
+ int rc, n;
/*
* The atom has been defined, but it might only exist as a
@@ -124,15 +124,12 @@ GetPropString(
for(pPropWin = pWin; pPropWin != (WindowPtr)NULL;
pPropWin = pPropWin->parent)
{
- for(pProp = (PropertyPtr)(wUserProps(pPropWin));
- pProp != (PropertyPtr)NULL;
- pProp = pProp->next)
- {
- if (pProp->propertyName == atom)
- break;
- }
- if(pProp != (PropertyPtr)NULL)
- break;
+ rc = dixLookupProperty(&pProp, pPropWin, atom,
+ serverClient, DixReadAccess);
+ if (rc == Success)
+ break;
+ else
+ pProp = NULL;
}
if(pProp == (PropertyPtr)NULL)
return (char *)NULL;
diff --git a/hw/xprint/pcl/PclWindow.c b/hw/xprint/pcl/PclWindow.c
index a87dc0e..950933e 100644
--- a/hw/xprint/pcl/PclWindow.c
+++ b/hw/xprint/pcl/PclWindow.c
@@ -128,9 +128,9 @@ PclCreateWindow(
{
propName = MakeAtom(propStrings[i], strlen(propStrings[i]),
TRUE);
- ChangeWindowProperty(pWin, propName, XA_STRING, 8,
- PropModeReplace, strlen(propVal),
- (pointer)propVal, FALSE);
+ dixChangeWindowProperty(serverClient, pWin, propName, XA_STRING,
+ 8, PropModeReplace, strlen(propVal),
+ (pointer)propVal, FALSE);
xfree(propVal);
}
}
diff --git a/hw/xprint/ps/PsMisc.c b/hw/xprint/ps/PsMisc.c
index 0df039e..8d5005f 100644
--- a/hw/xprint/ps/PsMisc.c
+++ b/hw/xprint/ps/PsMisc.c
@@ -175,7 +175,7 @@ GetPropString(
if(atom != BAD_RESOURCE)
{
WindowPtr pPropWin;
- int n;
+ int rc, n;
*/
/*
@@ -186,15 +186,12 @@ GetPropString(
for(pPropWin = pWin; pPropWin != (WindowPtr)NULL;
pPropWin = pPropWin->parent)
{
- for(pProp = (PropertyPtr)(wUserProps(pPropWin));
- pProp != (PropertyPtr)NULL;
- pProp = pProp->next)
- {
- if (pProp->propertyName == atom)
- break;
- }
- if(pProp != (PropertyPtr)NULL)
- break;
+ rc = dixLookupProperty(&pProp, pPropWin, atom,
+ serverClient, DixReadAccess);
+ if (rc == Success)
+ break;
+ else
+ pProp = NULL;
}
if(pProp == (PropertyPtr)NULL)
return (char *)NULL;
diff --git a/hw/xprint/ps/PsWindow.c b/hw/xprint/ps/PsWindow.c
index d17cf8c..8bfde4b 100644
--- a/hw/xprint/ps/PsWindow.c
+++ b/hw/xprint/ps/PsWindow.c
@@ -154,9 +154,9 @@ PsCreateWindow(WindowPtr pWin)
{
propName = MakeAtom(propStrings[i], strlen(propStrings[i]),
TRUE);
- ChangeWindowProperty(pWin, propName, XA_STRING, 8,
- PropModeReplace, strlen(propVal),
- (pointer)propVal, FALSE);
+ dixChangeWindowProperty(serverClient, pWin, propName, XA_STRING,
+ 8, PropModeReplace, strlen(propVal),
+ (pointer)propVal, FALSE);
xfree(propVal);
}
}
diff --git a/hw/xquartz/applewm.c b/hw/xquartz/applewm.c
index c460ec6..072e57f 100644
--- a/hw/xquartz/applewm.c
+++ b/hw/xquartz/applewm.c
@@ -154,8 +154,8 @@ AppleWMSetScreenOrigin(
data[1] = (dixScreenOrigins[pWin->drawable.pScreen->myNum].y
+ darwinMainScreenY);
- ChangeWindowProperty(pWin, xa_native_screen_origin(), XA_INTEGER,
- 32, PropModeReplace, 2, data, TRUE);
+ dixChangeWindowProperty(serverClient, pWin, xa_native_screen_origin(),
+ XA_INTEGER, 32, PropModeReplace, 2, data, TRUE);
}
/* Window managers can set the _APPLE_NO_ORDER_IN property on windows
@@ -169,15 +169,11 @@ AppleWMDoReorderWindow(
{
Atom atom;
PropertyPtr prop;
+ int rc;
atom = xa_apple_no_order_in();
- for (prop = wUserProps(pWin); prop != NULL; prop = prop->next)
- {
- if (prop->propertyName == atom && prop->type == atom)
- return FALSE;
- }
-
- return TRUE;
+ rc = dixLookupProperty(&prop, pWin, atom, serverClient, DixReadAccess);
+ return (rc == Success) && (prop->type == atom);
}
diff --git a/hw/xquartz/quartzPasteboard.c b/hw/xquartz/quartzPasteboard.c
index 0cecff5..0bf84f5 100644
--- a/hw/xquartz/quartzPasteboard.c
+++ b/hw/xquartz/quartzPasteboard.c
@@ -43,9 +43,6 @@
#include "selection.h"
#include "globals.h"
-extern Selection *CurrentSelections;
-extern int NumCurrentSelections;
-
// Helper function to read the X11 cut buffer
// FIXME: What about multiple screens? Currently, this reads the first
@@ -54,18 +51,16 @@ extern int NumCurrentSelections;
// Returns NULL if there is no cut text or there is not enough memory.
static char * QuartzReadCutBuffer(void)
{
- int i;
+ int rc, i;
char *text = NULL;
for (i = 0; i < screenInfo.numScreens; i++) {
ScreenPtr pScreen = screenInfo.screens[i];
PropertyPtr pProp;
- pProp = wUserProps (WindowTable[pScreen->myNum]);
- while (pProp && pProp->propertyName != XA_CUT_BUFFER0) {
- pProp = pProp->next;
- }
- if (! pProp) continue;
+ rc = dixLookupProperty(&pProp, WindowTable[pScreen->myNum],
+ XA_CUT_BUFFER0, serverClient, DixReadAccess);
+ if (rc != Success) continue;
if (pProp->type != XA_STRING) continue;
if (pProp->format != 8) continue;
@@ -108,43 +103,40 @@ void QuartzReadPasteboard(void)
if ((text && oldText && !strequal(text, oldText)) ||
(text && !oldText)) {
- int scrn, sel;
+ int scrn, rc;
+ Selection *pSel;
for (scrn = 0; scrn < screenInfo.numScreens; scrn++) {
ScreenPtr pScreen = screenInfo.screens[scrn];
// Set the cut buffers on each screen
// fixme really on each screen?
- ChangeWindowProperty(WindowTable[pScreen->myNum], XA_CUT_BUFFER0,
- XA_STRING, 8, PropModeReplace,
- strlen(text), (pointer)text, TRUE);
+ dixChangeWindowProperty(serverClient, WindowTable[pScreen->myNum],
+ XA_CUT_BUFFER0, XA_STRING, 8, PropModeReplace,
+ strlen(text), (pointer)text, TRUE);
}
// Undo any current X selection (similar to code in dispatch.c)
// FIXME: what about secondary selection?
// FIXME: only touch first XA_PRIMARY selection?
- sel = 0;
- while ((sel < NumCurrentSelections) &&
- CurrentSelections[sel].selection != XA_PRIMARY)
- sel++;
- if (sel < NumCurrentSelections) {
+ rc = dixLookupSelection(&pSel, XA_PRIMARY, serverClient,
+ DixSetAttrAccess);
+ if (rc == Success) {
// Notify client if necessary
- if (CurrentSelections[sel].client) {
+ if (pSel->client) {
xEvent event;
event.u.u.type = SelectionClear;
event.u.selectionClear.time = GetTimeInMillis();
- event.u.selectionClear.window = CurrentSelections[sel].window;
- event.u.selectionClear.atom = CurrentSelections[sel].selection;
- TryClientEvents(CurrentSelections[sel].client, &event, 1,
- NoEventMask, NoEventMask /*CantBeFiltered*/,
- NullGrab);
+ event.u.selectionClear.window = pSel->window;
+ event.u.selectionClear.atom = pSel->selection;
+ TryClientEvents(pSel->client, &event, 1, NoEventMask,
+ NoEventMask /*CantBeFiltered*/, NullGrab);
}
// Erase it
- // FIXME: need to erase .selection too? dispatch.c doesn't
- CurrentSelections[sel].pWin = NullWindow;
- CurrentSelections[sel].window = None;
- CurrentSelections[sel].client = NullClient;
+ pSel->pWin = NullWindow;
+ pSel->window = None;
+ pSel->client = NullClient;
}
}
diff --git a/hw/xquartz/xpr/xprFrame.c b/hw/xquartz/xpr/xprFrame.c
index b9a33de..864ef0d 100644
--- a/hw/xquartz/xpr/xprFrame.c
+++ b/hw/xquartz/xpr/xprFrame.c
@@ -90,8 +90,8 @@ xprSetNativeProperty(RootlessWindowPtr pFrame)
/* FIXME: move this to AppleWM extension */
data = native_id;
- ChangeWindowProperty(pFrame->win, xa_native_window_id(),
- XA_INTEGER, 32, PropModeReplace, 1, &data, TRUE);
+ dixChangeWindowProperty(serverClient, pFrame->win, xa_native_window_id(),
+ XA_INTEGER, 32, PropModeReplace, 1, &data, TRUE);
}
}
diff --git a/hw/xwin/winwin32rootless.c b/hw/xwin/winwin32rootless.c
index 4b4cd3d..6f4e2c9 100755
--- a/hw/xwin/winwin32rootless.c
+++ b/hw/xwin/winwin32rootless.c
@@ -1087,6 +1087,6 @@ winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame)
/* FIXME: move this to WindowsWM extension */
lData = (long) pRLWinPriv->hWnd;
- ChangeWindowProperty (pFrame->win, AtmWindowsWmNativeHwnd (),
- XA_INTEGER, 32, PropModeReplace, 1, &lData, TRUE);
+ dixChangeWindowProperty(serverClient, pFrame->win, AtmWindowsWmNativeHwnd(),
+ XA_INTEGER, 32, PropModeReplace, 1, &lData, TRUE);
}
diff --git a/miext/rootless/rootlessWindow.c b/miext/rootless/rootlessWindow.c
index 7285f95..0dad44a 100644
--- a/miext/rootless/rootlessWindow.c
+++ b/miext/rootless/rootlessWindow.c
@@ -181,8 +181,8 @@ set_screen_origin (WindowPtr pWin)
data[1] = (dixScreenOrigins[pWin->drawable.pScreen->myNum].y
+ darwinMainScreenY);
- ChangeWindowProperty (pWin, xa_native_screen_origin (), XA_INTEGER,
- 32, PropModeReplace, 2, data, TRUE);
+ dixChangeWindowProperty(serverClient, pWin, xa_native_screen_origin(),
+ XA_INTEGER, 32, PropModeReplace, 2, data, TRUE);
}
/*
diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
index 2b5f1fb..c0afad0 100644
--- a/xkb/xkbInit.c
+++ b/xkb/xkbInit.c
@@ -222,8 +222,8 @@ char * pval;
ErrorF("Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n",
out,len);
}
- ChangeWindowProperty(WindowTable[0],name,XA_STRING,8,PropModeReplace,
- len,pval,True);
+ dixChangeWindowProperty(serverClient, WindowTable[0], name, XA_STRING, 8,
+ PropModeReplace, len, pval, True);
xfree(pval);
return True;
}
commit cc76ea6e3ac6a405f0c198c4e62be40aa8d2b546
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date: Fri Feb 29 17:55:31 2008 -0500
XACE: Add generic support for property and selection polyinstantiation.
diff --git a/Xext/security.c b/Xext/security.c
index cd67120..e82b976 100644
--- a/Xext/security.c
+++ b/Xext/security.c
@@ -910,7 +910,7 @@ SecurityProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
{
XacePropertyAccessRec *rec = calldata;
SecurityStateRec *subj, *obj;
- ATOM name = rec->pProp->propertyName;
+ ATOM name = (*rec->ppProp)->propertyName;
Mask requested = rec->access_mode;
Mask allowed = SecurityResourceMask | DixReadAccess;
diff --git a/Xext/xace.c b/Xext/xace.c
index e88debc..8a8f8c6 100644
--- a/Xext/xace.c
+++ b/Xext/xace.c
@@ -56,16 +56,17 @@ int XaceHookDispatch(ClientPtr client, int major)
}
int XaceHookPropertyAccess(ClientPtr client, WindowPtr pWin,
- PropertyPtr pProp, Mask access_mode)
+ PropertyPtr *ppProp, Mask access_mode)
{
- XacePropertyAccessRec rec = { client, pWin, pProp, access_mode, Success };
+ XacePropertyAccessRec rec = { client, pWin, ppProp, access_mode, Success };
CallCallbacks(&XaceHooks[XACE_PROPERTY_ACCESS], &rec);
return rec.status;
}
-int XaceHookSelectionAccess(ClientPtr client, Atom name, Mask access_mode)
+int XaceHookSelectionAccess(ClientPtr client,
+ Selection **ppSel, Mask access_mode)
{
- XaceSelectionAccessRec rec = { client, name, access_mode, Success };
+ XaceSelectionAccessRec rec = { client, ppSel, access_mode, Success };
CallCallbacks(&XaceHooks[XACE_SELECTION_ACCESS], &rec);
return rec.status;
}
diff --git a/Xext/xace.h b/Xext/xace.h
index 1f07d9f..bd69bca 100644
--- a/Xext/xace.h
+++ b/Xext/xace.h
@@ -29,6 +29,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "region.h"
#include "window.h"
#include "property.h"
+#include "selection.h"
/* Default window background */
#define XaceBackgroundNoneState(w) ((w)->forcedBG ? BackgroundPixel : None)
@@ -68,9 +69,9 @@ extern int XaceHook(
*/
extern int XaceHookDispatch(ClientPtr ptr, int major);
extern int XaceHookPropertyAccess(ClientPtr ptr, WindowPtr pWin,
- PropertyPtr pProp, Mask access_mode);
-extern int XaceHookSelectionAccess(ClientPtr ptr, Atom name,
- Mask access_mode);
+ PropertyPtr *ppProp, Mask access_mode);
+extern int XaceHookSelectionAccess(ClientPtr ptr,
+ Selection **ppSel, Mask access_mode);
extern void XaceHookAuditEnd(ClientPtr ptr, int result);
/* Register a callback for a given hook.
diff --git a/Xext/xacestr.h b/Xext/xacestr.h
index e31d424..ba115a4 100644
--- a/Xext/xacestr.h
+++ b/Xext/xacestr.h
@@ -59,7 +59,7 @@ typedef struct {
typedef struct {
ClientPtr client;
WindowPtr pWin;
- PropertyPtr pProp;
+ PropertyPtr *ppProp;
Mask access_mode;
int status;
} XacePropertyAccessRec;
@@ -110,7 +110,7 @@ typedef struct {
/* XACE_SELECTION_ACCESS */
typedef struct {
ClientPtr client;
- Atom name;
+ Selection **ppSel;
Mask access_mode;
int status;
} XaceSelectionAccessRec;
diff --git a/Xext/xselinux.c b/Xext/xselinux.c
index 8d66ea1..a7d3999 100644
--- a/Xext/xselinux.c
+++ b/Xext/xselinux.c
@@ -134,7 +134,7 @@ static struct security_class_mapping map[] = {
{ "x_gc", { "", "", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "use", NULL }},
{ "x_font", { "", "", "destroy", "create", "getattr", "", "", "", "", "", "", "", "add_glyph", "remove_glyph", "", "", "", "", "", "", "", "", "", "", "use", NULL }},
{ "x_colormap", { "read", "write", "destroy", "create", "getattr", "", "", "", "", "", "", "", "add_color", "remove_color", "", "", "", "", "", "", "install", "uninstall", "", "", "use", NULL }},
- { "x_property", { "read", "write", "destroy", "create", "getattr", "setattr", NULL }},
+ { "x_property", { "read", "write", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "write", NULL }},
{ "x_selection", { "read", "", "", "", "getattr", "setattr", NULL }},
{ "x_cursor", { "read", "write", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "use", NULL }},
{ "x_client", { "", "", "destroy", "", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "manage", NULL }},
@@ -691,14 +691,15 @@ SELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
SELinuxSubjectRec *subj;
SELinuxObjectRec *obj;
SELinuxAuditRec auditdata = { .client = rec->client };
+ PropertyPtr pProp = *rec->ppProp;
int rc;
subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
- obj = dixLookupPrivate(&rec->pProp->devPrivates, objectKey);
+ obj = dixLookupPrivate(&pProp->devPrivates, objectKey);
/* If this is a new object that needs labeling, do it now */
if (rec->access_mode & DixCreateAccess) {
- const char *name = NameForAtom(rec->pProp->propertyName);
+ const char *name = NameForAtom(pProp->propertyName);
security_context_t con;
security_id_t sid;
@@ -729,7 +730,7 @@ SELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
}
/* Perform the security check */
- auditdata.property = rec->pProp->propertyName;
+ auditdata.property = pProp->propertyName;
rc = SELinuxDoCheck(subj, obj, SECCLASS_X_PROPERTY, rec->access_mode,
&auditdata);
if (rc != Success)
@@ -870,17 +871,21 @@ SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata)
SELinuxSubjectRec *subj;
SELinuxObjectRec sel_sid;
SELinuxAuditRec auditdata = { .client = rec->client };
+ Selection *pSel = *rec->ppSel;
int rc;
+ if (rec->access_mode & DixCreateAccess)
+ return; /* don't use create currently */
+
subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
- rc = SELinuxSelectionToSID(rec->name, &sel_sid);
+ rc = SELinuxSelectionToSID(pSel->selection, &sel_sid);
if (rc != Success) {
rec->status = rc;
return;
}
- auditdata.selection = rec->name;
+ auditdata.selection = pSel->selection;
rc = SELinuxDoCheck(subj, &sel_sid, SECCLASS_X_SELECTION, rec->access_mode,
&auditdata);
if (rc != Success)
@@ -1206,16 +1211,8 @@ ProcSELinuxGetPropertyContext(ClientPtr client)
if (rc != Success)
return rc;
- pProp = wUserProps(pWin);
- while (pProp) {
- if (pProp->propertyName == stuff->property)
- break;
- pProp = pProp->next;
- }
- if (!pProp)
- return BadValue;
-
- rc = XaceHookPropertyAccess(client, pWin, pProp, DixGetAttrAccess);
+ rc = dixLookupProperty(&pProp, pWin, stuff->property, client,
+ DixGetAttrAccess);
if (rc != Success)
return rc;
diff --git a/dix/property.c b/dix/property.c
index e74becf..8b66ad6 100644
--- a/dix/property.c
+++ b/dix/property.c
@@ -103,7 +103,7 @@ dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName,
break;
if (pProp)
- rc = XaceHookPropertyAccess(client, pWin, pProp, access_mode);
+ rc = XaceHookPropertyAccess(client, pWin, &pProp, access_mode);
*result = pProp;
return rc;
}
@@ -256,12 +256,14 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
PropertyPtr pProp;
int sizeInBytes, totalSize, rc;
pointer data;
+ Mask access_mode;
sizeInBytes = format>>3;
totalSize = len * sizeInBytes;
+ access_mode = (mode == PropModeReplace) ? DixWriteAccess : DixBlendAccess;
/* first see if property already exists */
- rc = dixLookupProperty(&pProp, pWin, property, pClient, DixWriteAccess);
+ rc = dixLookupProperty(&pProp, pWin, property, pClient, access_mode);
if (rc == BadMatch) /* just add to list */
{
@@ -284,7 +286,7 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
memmove((char *)data, (char *)value, totalSize);
pProp->size = len;
pProp->devPrivates = NULL;
- rc = XaceHookPropertyAccess(pClient, pWin, pProp,
+ rc = XaceHookPropertyAccess(pClient, pWin, &pProp,
DixCreateAccess|DixWriteAccess);
if (rc != Success) {
xfree(data);
@@ -588,7 +590,7 @@ ProcListProperties(ClientPtr client)
temppAtoms = pAtoms;
for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) {
realProp = pProp;
- rc = XaceHookPropertyAccess(client, pWin, pProp, DixGetAttrAccess);
+ rc = XaceHookPropertyAccess(client, pWin, &realProp, DixGetAttrAccess);
if (rc == Success && realProp == pProp) {
*temppAtoms++ = pProp->propertyName;
numProps++;
diff --git a/dix/selection.c b/dix/selection.c
index e2e279a..52b1611 100644
--- a/dix/selection.c
+++ b/dix/selection.c
@@ -80,7 +80,7 @@ dixLookupSelection(Selection **result, Atom selectionName,
for (i = 0; i < NumCurrentSelections; i++)
if (CurrentSelections[i].selection == selectionName) {
pSel = CurrentSelections + i;
- rc = XaceHookSelectionAccess(client, selectionName, access_mode);
+ rc = XaceHookSelectionAccess(client, &pSel, access_mode);
break;
}
@@ -206,6 +206,10 @@ ProcSetSelectionOwner(ClientPtr client)
pSel = CurrentSelections + NumCurrentSelections;
pSel->selection = stuff->selection;
pSel->devPrivates = NULL;
+
+ /* security creation/labeling check */
+ (void)XaceHookSelectionAccess(client, &pSel, DixCreateAccess);
+
pSel->next = NULL;
if (NumCurrentSelections > 0)
CurrentSelections[NumCurrentSelections - 1].next = pSel;
commit 34bf308a9e66f1a2f48630a15b1802afad50ec24
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date: Fri Feb 29 18:00:23 2008 -0500
dix: Refactoring of selection code to allow for polyinstantiation.
Introduces dixLookupSelection() API.
Removes NumCurrentSelections from API.
diff --git a/Xext/xselinux.c b/Xext/xselinux.c
index 9adc931..8d66ea1 100644
--- a/Xext/xselinux.c
+++ b/Xext/xselinux.c
@@ -967,8 +967,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..e2e279a
--- /dev/null
+++ b/dix/selection.c
@@ -0,0 +1,306 @@
+/************************************************************
+
+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.
+ *
+ *****************************************************************/
+
+_X_EXPORT 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)
+{
+ Selection *pSel = CurrentSelections;
+
+ for (; pSel - CurrentSelections < NumCurrentSelections; pSel++)
+ dixFreePrivates(pSel->devPrivates);
+
+ 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;
+ pSel->next = NULL;
+ if (NumCurrentSelections > 0)
+ CurrentSelections[NumCurrentSelections - 1].next = pSel;
+ 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, DixReadAccess);
+
+ 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..d035c76 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,9 @@ _X_HIDDEN void *dixLookupTab[] = {
SYMFUNC(dixLookupProperty)
SYMFUNC(ChangeWindowProperty)
SYMFUNC(dixChangeWindowProperty)
+ /* selection.c */
+ SYMFUNC(dixLookupSelection)
+ SYMVAR(CurrentSelections)
/* 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..dd9b056 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,45 @@ typedef struct _Selection {
Window window;
WindowPtr pWin;
ClientPtr client;
- ClientPtr alt_client; /* support for redirection */
- Window alt_window; /* support for redirection */
+ struct _Selection *next;
PrivateRec *devPrivates;
} Selection;
+
+/*
+ * Selection API
+ */
+
+int dixLookupSelection(Selection **result, Atom name,
+ ClientPtr client, Mask access_mode);
+
+extern Selection *CurrentSelections;
+
+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 */
commit d5715f7beaad6816db27b01b67d7a3c69164d106
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date: Fri Feb 29 16:16:12 2008 -0500
dix: Refactoring of property code to allow for polyinstantiation.
Introduces dixLookupProperty() API.
diff --git a/dix/property.c b/dix/property.c
index ce61169..e74becf 100644
--- a/dix/property.c
+++ b/dix/property.c
@@ -63,11 +63,10 @@ SOFTWARE.
/*****************************************************************
* Property Stuff
*
- * ChangeProperty, DeleteProperty, GetProperties,
- * ListProperties
+ * dixLookupProperty, dixChangeProperty, DeleteProperty
*
- * Properties below to windows. A allocate slots each time
- * a property is added. No fancy searching done.
+ * Properties belong to windows. The list of properties should not be
+ * traversed directly. Instead, use the three functions listed above.
*
*****************************************************************/
@@ -91,17 +90,22 @@ PrintPropertys(WindowPtr pWin)
}
#endif
-static _X_INLINE PropertyPtr
-FindProperty(WindowPtr pWin, Atom propertyName)
+_X_EXPORT int
+dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName,
+ ClientPtr client, Mask access_mode)
{
- PropertyPtr pProp = wUserProps(pWin);
- while (pProp)
- {
+ PropertyPtr pProp;
+ int rc = BadMatch;
+ client->errorValue = propertyName;
+
+ for (pProp = wUserProps(pWin); pProp; pProp = pProp->next)
if (pProp->propertyName == propertyName)
break;
- pProp = pProp->next;
- }
- return pProp;
+
+ if (pProp)
+ rc = XaceHookPropertyAccess(client, pWin, pProp, access_mode);
+ *result = pProp;
+ return rc;
}
static void
@@ -125,65 +129,69 @@ ProcRotateProperties(ClientPtr client)
WindowPtr pWin;
Atom * atoms;
PropertyPtr * props; /* array of pointer */
- PropertyPtr pProp;
+ PropertyPtr pProp, saved;
REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
UpdateCurrentTime();
rc = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess);
- if (rc != Success)
+ if (rc != Success || stuff->nAtoms <= 0)
return rc;
- if (!stuff->nAtoms)
- return(Success);
+
atoms = (Atom *) & stuff[1];
props = (PropertyPtr *)xalloc(stuff->nAtoms * sizeof(PropertyPtr));
- if (!props)
- return(BadAlloc);
+ saved = (PropertyPtr)xalloc(stuff->nAtoms * sizeof(PropertyRec));
+ if (!props || !saved) {
+ rc = BadAlloc;
+ goto out;
+ }
+
for (i = 0; i < stuff->nAtoms; i++)
{
if (!ValidAtom(atoms[i])) {
- xfree(props);
+ rc = BadAtom;
client->errorValue = atoms[i];
- return BadAtom;
+ goto out;
}
for (j = i + 1; j < stuff->nAtoms; j++)
if (atoms[j] == atoms[i])
{
- xfree(props);
- return BadMatch;
+ rc = BadMatch;
+ goto out;
}
- pProp = FindProperty(pWin, atoms[i]);
- if (!pProp) {
- xfree(props);
- return BadMatch;
- }
- rc = XaceHookPropertyAccess(client, pWin, pProp,
- DixReadAccess|DixWriteAccess);
- if (rc != Success) {
- xfree(props);
- client->errorValue = atoms[i];
- return rc;
- }
+
+ rc = dixLookupProperty(&pProp, pWin, atoms[i], client,
+ DixReadAccess|DixWriteAccess);
+ if (rc != Success)
+ goto out;
+
props[i] = pProp;
+ saved[i] = *pProp;
}
delta = stuff->nPositions;
/* If the rotation is a complete 360 degrees, then moving the properties
around and generating PropertyNotify events should be skipped. */
- if ( (stuff->nAtoms != 0) && (abs(delta) % stuff->nAtoms) != 0 )
+ if (abs(delta) % stuff->nAtoms)
{
while (delta < 0) /* faster if abs value is small */
delta += stuff->nAtoms;
for (i = 0; i < stuff->nAtoms; i++)
{
- deliverPropertyNotifyEvent(pWin, PropertyNewValue,
- props[i]->propertyName);
-
- props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
+ j = (i + delta) % stuff->nAtoms;
+ deliverPropertyNotifyEvent(pWin, PropertyNewValue, atoms[i]);
+
+ /* Preserve name and devPrivates */
+ props[j]->type = saved[i].type;
+ props[j]->format = saved[i].format;
+ props[j]->size = saved[i].size;
+ props[j]->data = saved[i].data;
}
}
+out:
+ xfree(saved);
xfree(props);
- return Success;
+ return rc;
}
int
@@ -253,9 +261,9 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
totalSize = len * sizeInBytes;
/* first see if property already exists */
- pProp = FindProperty(pWin, property);
+ rc = dixLookupProperty(&pProp, pWin, property, pClient, DixWriteAccess);
- if (!pProp) /* just add to list */
+ if (rc == BadMatch) /* just add to list */
{
if (!pWin->optional && !MakeWindowOptional (pWin))
return(BadAlloc);
@@ -287,13 +295,8 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
pProp->next = pWin->optional->userProps;
pWin->optional->userProps = pProp;
}
- else
+ else if (rc == Success)
{
- rc = XaceHookPropertyAccess(pClient, pWin, pProp, DixWriteAccess);
- if (rc != Success) {
- pClient->errorValue = property;
- return rc;
- }
/* To append or prepend to a property the request format and type
must match those of the already defined property. The
existing format and type are irrelevant when using the mode
@@ -347,6 +350,8 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property,
pProp->size += len;
}
}
+ else
+ return rc;
if (sendevent)
deliverPropertyNotifyEvent(pWin, PropertyNewValue, pProp->propertyName);
@@ -369,37 +374,29 @@ DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName)
PropertyPtr pProp, prevProp;
int rc;
- if (!(pProp = wUserProps (pWin)))
- return(Success);
- prevProp = (PropertyPtr)NULL;
- while (pProp)
- {
- if (pProp->propertyName == propName)
- break;
- prevProp = pProp;
- pProp = pProp->next;
- }
- if (pProp)
- {
- rc = XaceHookPropertyAccess(client, pWin, pProp, DixDestroyAccess);
- if (rc != Success)
- return rc;
+ rc = dixLookupProperty(&pProp, pWin, propName, client, DixDestroyAccess);
+ if (rc == BadMatch)
+ return Success; /* Succeed if property does not exist */
- if (prevProp == (PropertyPtr)NULL) /* takes care of head */
- {
+ if (rc == Success) {
+ if (pWin->optional->userProps == pProp) {
+ /* Takes care of head */
if (!(pWin->optional->userProps = pProp->next))
CheckWindowOptionalNeed (pWin);
- }
- else
- {
- prevProp->next = pProp->next;
- }
+ } else {
+ /* Need to traverse to find the previous element */
+ prevProp = pWin->optional->userProps;
+ while (prevProp->next != pProp)
+ prevProp = prevProp->next;
+ prevProp->next = pProp->next;
+ }
+
deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName);
dixFreePrivates(pProp->devPrivates);
xfree(pProp->data);
xfree(pProp);
}
- return(Success);
+ return rc;
}
void
@@ -453,15 +450,16 @@ ProcGetProperty(ClientPtr client)
int rc;
WindowPtr pWin;
xGetPropertyReply reply;
- Mask access_mode = DixGetPropAccess;
+ Mask win_mode = DixGetPropAccess, prop_mode = DixReadAccess;
REQUEST(xGetPropertyReq);
REQUEST_SIZE_MATCH(xGetPropertyReq);
if (stuff->delete) {
UpdateCurrentTime();
- access_mode |= DixSetPropAccess;
+ win_mode |= DixSetPropAccess;
+ prop_mode |= DixDestroyAccess;
}
- rc = dixLookupWindow(&pWin, stuff->window, client, access_mode);
+ rc = dixLookupWindow(&pWin, stuff->window, client, win_mode);
if (rc != Success)
return rc;
@@ -481,30 +479,14 @@ ProcGetProperty(ClientPtr client)
return(BadAtom);
}
- pProp = wUserProps (pWin);
- prevProp = (PropertyPtr)NULL;
- while (pProp)
- {
- if (pProp->propertyName == stuff->property)
- break;
- prevProp = pProp;
- pProp = pProp->next;
- }
-
reply.type = X_Reply;
reply.sequenceNumber = client->sequence;
- if (!pProp)
- return NullPropertyReply(client, None, 0, &reply);
- access_mode = DixReadAccess;
- if (stuff->delete)
- access_mode |= DixDestroyAccess;
-
- rc = XaceHookPropertyAccess(client, pWin, pProp, access_mode);
- if (rc != Success) {
- client->errorValue = stuff->property;
+ rc = dixLookupProperty(&pProp, pWin, stuff->property, client, prop_mode);
+ if (rc == BadMatch)
+ return NullPropertyReply(client, None, 0, &reply);
+ else if (rc != Success)
return rc;
- }
/* If the request type and actual type don't match. Return the
property information, but not the data. */
@@ -560,15 +542,20 @@ ProcGetProperty(ClientPtr client)
(char *)pProp->data + ind);
}
- if (stuff->delete && (reply.bytesAfter == 0))
- { /* delete the Property */
- if (prevProp == (PropertyPtr)NULL) /* takes care of head */
- {
- if (!(pWin->optional->userProps = pProp->next))
+ if (stuff->delete && (reply.bytesAfter == 0)) {
+ /* Delete the Property */
+ if (pWin->optional->userProps == pProp) {
+ /* Takes care of head */
+ if (!(pWin->optional->userProps = pProp->next))
CheckWindowOptionalNeed (pWin);
- }
- else
+ } else {
+ /* Need to traverse to find the previous element */
+ prevProp = pWin->optional->userProps;
+ while (prevProp->next != pProp)
+ prevProp = prevProp->next;
prevProp->next = pProp->next;
+ }
+
dixFreePrivates(pProp->devPrivates);
xfree(pProp->data);
xfree(pProp);
@@ -583,7 +570,7 @@ ProcListProperties(ClientPtr client)
xListPropertiesReply xlpr;
int rc, numProps = 0;
WindowPtr pWin;
- PropertyPtr pProp;
+ PropertyPtr pProp, realProp;
REQUEST(xResourceReq);
REQUEST_SIZE_MATCH(xResourceReq);
@@ -591,34 +578,34 @@ ProcListProperties(ClientPtr client)
if (rc != Success)
return rc;
- pProp = wUserProps (pWin);
- while (pProp)
- {
- pProp = pProp->next;
+ for (pProp = wUserProps(pWin); pProp; pProp = pProp->next)
numProps++;
+
+ if (numProps && !(pAtoms = (Atom *)xalloc(numProps * sizeof(Atom))))
+ return BadAlloc;
+
+ numProps = 0;
+ temppAtoms = pAtoms;
+ for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) {
+ realProp = pProp;
+ rc = XaceHookPropertyAccess(client, pWin, pProp, DixGetAttrAccess);
+ if (rc == Success && realProp == pProp) {
+ *temppAtoms++ = pProp->propertyName;
+ numProps++;
+ }
}
- if (numProps)
- if(!(pAtoms = (Atom *)xalloc(numProps * sizeof(Atom))))
- return(BadAlloc);
xlpr.type = X_Reply;
xlpr.nProperties = numProps;
xlpr.length = (numProps * sizeof(Atom)) >> 2;
xlpr.sequenceNumber = client->sequence;
- pProp = wUserProps (pWin);
- temppAtoms = pAtoms;
- while (pProp)
- {
- *temppAtoms++ = pProp->propertyName;
- pProp = pProp->next;
- }
WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
if (numProps)
{
client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
- xfree(pAtoms);
}
+ xfree(pAtoms);
return(client->noClientException);
}
diff --git a/hw/xfree86/loader/dixsym.c b/hw/xfree86/loader/dixsym.c
index 49c7d27..e6c37fe 100644
--- a/hw/xfree86/loader/dixsym.c
+++ b/hw/xfree86/loader/dixsym.c
@@ -193,6 +193,7 @@ _X_HIDDEN void *dixLookupTab[] = {
SYMFUNC(XineramaGetCursorScreen)
#endif
/* property.c */
+ SYMFUNC(dixLookupProperty)
SYMFUNC(ChangeWindowProperty)
SYMFUNC(dixChangeWindowProperty)
/* extension.c */
diff --git a/include/property.h b/include/property.h
index ba7d226..1207e81 100644
--- a/include/property.h
+++ b/include/property.h
@@ -52,6 +52,13 @@ SOFTWARE.
typedef struct _Property *PropertyPtr;
+extern int dixLookupProperty(
+ PropertyPtr * /*result*/,
+ WindowPtr /*pWin*/,
+ Atom /*proprty*/,
+ ClientPtr /*pClient*/,
+ Mask /*access_mode*/);
+
extern int dixChangeWindowProperty(
ClientPtr /*pClient*/,
WindowPtr /*pWin*/,
More information about the xorg-commit
mailing list