dix: Convert selection list to a linked list.
Fixes a bug where pointers were being invalidated after a realloc.
This commit is contained in:
parent
0bd0f90d7c
commit
72f2197545
|
@ -66,24 +66,22 @@ SOFTWARE.
|
||||||
*****************************************************************/
|
*****************************************************************/
|
||||||
|
|
||||||
_X_EXPORT Selection *CurrentSelections;
|
_X_EXPORT Selection *CurrentSelections;
|
||||||
static int NumCurrentSelections;
|
|
||||||
CallbackListPtr SelectionCallback;
|
CallbackListPtr SelectionCallback;
|
||||||
|
|
||||||
_X_EXPORT int
|
_X_EXPORT int
|
||||||
dixLookupSelection(Selection **result, Atom selectionName,
|
dixLookupSelection(Selection **result, Atom selectionName,
|
||||||
ClientPtr client, Mask access_mode)
|
ClientPtr client, Mask access_mode)
|
||||||
{
|
{
|
||||||
Selection *pSel = NULL;
|
Selection *pSel;
|
||||||
int i, rc = BadMatch;
|
int rc = BadMatch;
|
||||||
client->errorValue = selectionName;
|
client->errorValue = selectionName;
|
||||||
|
|
||||||
for (i = 0; i < NumCurrentSelections; i++)
|
for (pSel = CurrentSelections; pSel; pSel = pSel->next)
|
||||||
if (CurrentSelections[i].selection == selectionName) {
|
if (pSel->selection == selectionName)
|
||||||
pSel = CurrentSelections + i;
|
|
||||||
rc = XaceHookSelectionAccess(client, &pSel, access_mode);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
|
if (pSel)
|
||||||
|
rc = XaceHookSelectionAccess(client, &pSel, access_mode);
|
||||||
*result = pSel;
|
*result = pSel;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -91,14 +89,17 @@ dixLookupSelection(Selection **result, Atom selectionName,
|
||||||
void
|
void
|
||||||
InitSelections(void)
|
InitSelections(void)
|
||||||
{
|
{
|
||||||
Selection *pSel = CurrentSelections;
|
Selection *pSel, *pNextSel;
|
||||||
|
|
||||||
for (; pSel - CurrentSelections < NumCurrentSelections; pSel++)
|
pSel = CurrentSelections;
|
||||||
|
while (pSel) {
|
||||||
|
pNextSel = pSel->next;
|
||||||
dixFreePrivates(pSel->devPrivates);
|
dixFreePrivates(pSel->devPrivates);
|
||||||
|
xfree(pSel);
|
||||||
|
pSel = pNextSel;
|
||||||
|
}
|
||||||
|
|
||||||
xfree(CurrentSelections);
|
|
||||||
CurrentSelections = NULL;
|
CurrentSelections = NULL;
|
||||||
NumCurrentSelections = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static _X_INLINE void
|
static _X_INLINE void
|
||||||
|
@ -112,9 +113,9 @@ CallSelectionCallback(Selection *pSel, ClientPtr client,
|
||||||
void
|
void
|
||||||
DeleteWindowFromAnySelections(WindowPtr pWin)
|
DeleteWindowFromAnySelections(WindowPtr pWin)
|
||||||
{
|
{
|
||||||
Selection *pSel = CurrentSelections;
|
Selection *pSel;
|
||||||
|
|
||||||
for (; pSel - CurrentSelections < NumCurrentSelections; pSel++)
|
for (pSel = CurrentSelections; pSel; pSel = pSel->next)
|
||||||
if (pSel->pWin == pWin) {
|
if (pSel->pWin == pWin) {
|
||||||
CallSelectionCallback(pSel, NULL, SelectionWindowDestroy);
|
CallSelectionCallback(pSel, NULL, SelectionWindowDestroy);
|
||||||
|
|
||||||
|
@ -127,9 +128,9 @@ DeleteWindowFromAnySelections(WindowPtr pWin)
|
||||||
void
|
void
|
||||||
DeleteClientFromAnySelections(ClientPtr client)
|
DeleteClientFromAnySelections(ClientPtr client)
|
||||||
{
|
{
|
||||||
Selection *pSel = CurrentSelections;
|
Selection *pSel;
|
||||||
|
|
||||||
for (; pSel - CurrentSelections < NumCurrentSelections; pSel++)
|
for (pSel = CurrentSelections; pSel; pSel = pSel->next)
|
||||||
if (pSel->client == client) {
|
if (pSel->client == client) {
|
||||||
CallSelectionCallback(pSel, NULL, SelectionClientClose);
|
CallSelectionCallback(pSel, NULL, SelectionClientClose);
|
||||||
|
|
||||||
|
@ -197,23 +198,18 @@ ProcSetSelectionOwner(ClientPtr client)
|
||||||
/*
|
/*
|
||||||
* It doesn't exist, so add it...
|
* It doesn't exist, so add it...
|
||||||
*/
|
*/
|
||||||
int size = (NumCurrentSelections + 1) * sizeof(Selection);
|
pSel = xalloc(sizeof(Selection));
|
||||||
CurrentSelections = xrealloc(CurrentSelections, size);
|
if (!pSel)
|
||||||
if (!CurrentSelections) {
|
|
||||||
NumCurrentSelections = 0;
|
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
}
|
|
||||||
pSel = CurrentSelections + NumCurrentSelections;
|
|
||||||
pSel->selection = stuff->selection;
|
pSel->selection = stuff->selection;
|
||||||
pSel->devPrivates = NULL;
|
pSel->devPrivates = NULL;
|
||||||
|
|
||||||
/* security creation/labeling check */
|
/* security creation/labeling check */
|
||||||
(void)XaceHookSelectionAccess(client, &pSel, DixCreateAccess);
|
(void)XaceHookSelectionAccess(client, &pSel, DixCreateAccess);
|
||||||
|
|
||||||
pSel->next = NULL;
|
pSel->next = CurrentSelections;
|
||||||
if (NumCurrentSelections > 0)
|
CurrentSelections = pSel;
|
||||||
CurrentSelections[NumCurrentSelections - 1].next = pSel;
|
|
||||||
NumCurrentSelections++;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return rc;
|
return rc;
|
||||||
|
|
Loading…
Reference in New Issue