diff --git a/Xext/xace.c b/Xext/xace.c index b12666159..7b27ecd6a 100644 --- a/Xext/xace.c +++ b/Xext/xace.c @@ -177,7 +177,6 @@ int XaceHook(int hook, ...) XaceSelectionAccessRec rec = { va_arg(ap, ClientPtr), va_arg(ap, Atom), - va_arg(ap, Selection*), va_arg(ap, Mask), Success /* default allow */ }; diff --git a/Xext/xacestr.h b/Xext/xacestr.h index 1c615433b..045f8364f 100644 --- a/Xext/xacestr.h +++ b/Xext/xacestr.h @@ -112,7 +112,6 @@ typedef struct { typedef struct { ClientPtr client; Atom name; - Selection *selection; Mask access_mode; int status; } XaceSelectionAccessRec; diff --git a/dix/dispatch.c b/dix/dispatch.c index 2cfeb2df9..814c2a853 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -1005,6 +1005,11 @@ ProcSetSelectionOwner(ClientPtr client) { int i = 0; + rc = XaceHook(XACE_SELECTION_ACCESS, client, stuff->selection, + DixSetAttrAccess); + if (rc != Success) + return rc; + /* * First, see if the selection is already set... */ @@ -1022,12 +1027,6 @@ ProcSetSelectionOwner(ClientPtr client) if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged) == EARLIER) return Success; - - rc = XaceHook(XACE_SELECTION_ACCESS, client, stuff->selection, - CurrentSelections + i, DixSetAttrAccess); - if (rc != Success) - return rc; - if (CurrentSelections[i].client && (!pWin || (CurrentSelections[i].client != client))) { @@ -1058,10 +1057,6 @@ ProcSetSelectionOwner(ClientPtr client) CurrentSelections = newsels; CurrentSelections[i].selection = stuff->selection; CurrentSelections[i].devPrivates = NULL; - rc = XaceHook(XACE_SELECTION_ACCESS, client, stuff->selection, - CurrentSelections + i, DixSetAttrAccess); - if (rc != Success) - return rc; } CurrentSelections[i].lastTimeChanged = time; CurrentSelections[i].window = stuff->window; @@ -1072,6 +1067,7 @@ ProcSetSelectionOwner(ClientPtr client) SelectionInfoRec info; info.selection = &CurrentSelections[i]; + info.client = client; info.kind= SelectionSetOwner; CallCallbacks(&SelectionCallback, &info); } @@ -1095,23 +1091,29 @@ ProcGetSelectionOwner(ClientPtr client) int rc, i; xGetSelectionOwnerReply reply; - i = 0; - while ((i < NumCurrentSelections) && - CurrentSelections[i].selection != stuff->id) i++; - rc = XaceHook(XACE_SELECTION_ACCESS, client, stuff->id, - CurrentSelections + i, DixGetAttrAccess); + 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) - reply.owner = CurrentSelections[i].window; - else - reply.owner = None; + 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); } @@ -1135,6 +1137,10 @@ ProcConvertSelection(ClientPtr client) rc = dixLookupWindow(&pWin, stuff->requestor, client, DixSetAttrAccess); if (rc != Success) return rc; + rc = XaceHook(XACE_SELECTION_ACCESS, client, stuff->selection, + DixReadAccess); + if (rc != Success) + return rc; paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target)); if (stuff->property != None) @@ -1146,11 +1152,15 @@ ProcConvertSelection(ClientPtr client) i = 0; while ((i < NumCurrentSelections) && CurrentSelections[i].selection != stuff->selection) i++; - if ((i < NumCurrentSelections) && - (CurrentSelections[i].window != None) && - XaceHook(XACE_SELECTION_ACCESS, client, stuff->selection, - CurrentSelections + i, DixReadAccess) == Success) - { + 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; diff --git a/include/dix.h b/include/dix.h index 09ed6d944..30fdc45b1 100644 --- a/include/dix.h +++ b/include/dix.h @@ -594,12 +594,15 @@ extern CallbackListPtr SelectionCallback; typedef enum { SelectionSetOwner, + SelectionGetOwner, + SelectionConvertSelection, SelectionWindowDestroy, SelectionClientClose } SelectionCallbackKind; typedef struct { struct _Selection *selection; + ClientPtr client; SelectionCallbackKind kind; } SelectionInfoRec;