dix: Refactoring of selection code to allow for polyinstantiation.
Introduces dixLookupSelection() API. Removes NumCurrentSelections from API.
This commit is contained in:
parent
d5715f7bea
commit
34bf308a9e
|
@ -967,8 +967,6 @@ SELinuxSelectionState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
|
|||
|
||||
switch (rec->kind) {
|
||||
case SelectionSetOwner:
|
||||
case SelectionGetOwner:
|
||||
case SelectionConvertSelection:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ libdix_la_SOURCES = \
|
|||
property.c \
|
||||
registry.c \
|
||||
resource.c \
|
||||
selection.c \
|
||||
swaprep.c \
|
||||
swapreq.c \
|
||||
tables.c \
|
||||
|
|
274
dix/dispatch.c
274
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);
|
||||
|
@ -967,217 +952,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)
|
||||
{
|
||||
|
@ -3980,54 +3754,6 @@ SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
|
|||
WriteEventsToClient (client, 1, (xEvent *)&rep);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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");
|
||||
|
|
306
dix/selection.c
Normal file
306
dix/selection.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user