diff --git a/dix/dixutils.c b/dix/dixutils.c index b1e0c4cfe2..427e1cf68a 100644 --- a/dix/dixutils.c +++ b/dix/dixutils.c @@ -90,6 +90,7 @@ Author: Adobe Systems Incorporated #include "dix/dix_priv.h" #include "dix/resource_priv.h" #include "dix/screenint_priv.h" +#include "dix/saveset_priv.h" #include "misc.h" #include "windowstr.h" @@ -250,50 +251,35 @@ XRetCode AlterSaveSetForClient(ClientPtr client, WindowPtr pWin, unsigned mode, Bool toRoot, Bool map) { - unsigned numnow; - SaveSetElt *pTmp = NULL; - int j; + if (mode == SetModeDelete) { + SaveSetEntry *walk, *tmp; + xorg_list_for_each_entry_safe(walk, tmp, &client->saveSets, entry) { + if (walk->windowPtr == pWin) { + xorg_list_del(&(walk->entry)); + free(walk); + } + } + return Success; + } - numnow = client->numSaved; - j = 0; - if (numnow) { - pTmp = client->saveSet; - while ((j < numnow) && (SaveSetWindow(pTmp[j]) != (void *) pWin)) - j++; - } if (mode == SetModeInsert) { - if (j < numnow) /* duplicate */ - return Success; - numnow++; - pTmp = (SaveSetElt *) realloc(client->saveSet, sizeof(*pTmp) * numnow); - if (!pTmp) + SaveSetEntry *walk; + xorg_list_for_each_entry(walk, &client->saveSets, entry) { + if (walk->windowPtr == pWin) + return Success; /* duplicate */ + } + + SaveSetEntry *newent = calloc(1, sizeof(SaveSetEntry)); + if (!newent) return BadAlloc; - client->saveSet = pTmp; - client->numSaved = numnow; - SaveSetAssignWindow(client->saveSet[numnow - 1], pWin); - SaveSetAssignToRoot(client->saveSet[numnow - 1], toRoot); - SaveSetAssignMap(client->saveSet[numnow - 1], map); - return Success; - } - else if ((mode == SetModeDelete) && (j < numnow)) { - while (j < numnow - 1) { - pTmp[j] = pTmp[j + 1]; - j++; - } - numnow--; - if (numnow) { - pTmp = - (SaveSetElt *) realloc(client->saveSet, sizeof(*pTmp) * numnow); - if (pTmp) - client->saveSet = pTmp; - } - else { - free(client->saveSet); - client->saveSet = (SaveSetElt *) NULL; - } - client->numSaved = numnow; + + newent->windowPtr = pWin; + newent->toRoot = toRoot; + newent->map = map; + xorg_list_add(&newent->entry, &client->saveSets); return Success; } + return Success; } @@ -304,9 +290,7 @@ DeleteWindowFromAnySaveSet(WindowPtr pWin) for (int i = 0; i < currentMaxClients; i++) { client = clients[i]; - if (client && client->numSaved) - (void) AlterSaveSetForClient(client, pWin, SetModeDelete, FALSE, - TRUE); + (void) AlterSaveSetForClient(client, pWin, SetModeDelete, FALSE, TRUE); } } diff --git a/dix/saveset_priv.h b/dix/saveset_priv.h new file mode 100644 index 0000000000..12f6b8c32f --- /dev/null +++ b/dix/saveset_priv.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: MIT OR X11 + * + * Copyright © 2024 Enrico Weigelt, metux IT consult + */ +#ifndef _XSERVER_DIX_SAVESET_PRIV_H +#define _XSERVER_DIX_SAVESET_PRIV_H + +#include + +#include "include/list.h" +#include "include/window.h" + +typedef struct { + struct xorg_list entry; + WindowPtr windowPtr; + bool toRoot; + bool map; +} SaveSetEntry; + +#endif /*_XSERVER_DIX_SAVESET_PRIV_H */ diff --git a/dix/window.c b/dix/window.c index e661350f49..358e988084 100644 --- a/dix/window.c +++ b/dix/window.c @@ -108,6 +108,7 @@ Equipment Corporation. #include "dix/property_priv.h" #include "dix/request_priv.h" #include "dix/resource_priv.h" +#include "dix/saveset_priv.h" #include "dix/screenint_priv.h" #include "dix/screensaver_priv.h" #include "dix/selection_priv.h" @@ -2919,11 +2920,11 @@ UnmapSubwindows(WindowPtr pWin) void HandleSaveSet(ClientPtr client) { - WindowPtr pParent, pWin; - - for (unsigned j = 0; j < client->numSaved; j++) { - pWin = SaveSetWindow(client->saveSet[j]); - if (SaveSetToRoot(client->saveSet[j])) + SaveSetEntry *walk, *tmp; + xorg_list_for_each_entry_safe(walk, tmp, &client->saveSets, entry) { + WindowPtr pParent = NULL; + WindowPtr pWin = walk->windowPtr; + if (walk->toRoot) pParent = pWin->drawable.pScreen->root; else { @@ -2934,7 +2935,7 @@ HandleSaveSet(ClientPtr client) if (pParent) { if (pParent != pWin->parent) { /* unmap first so that ReparentWindow doesn't remap */ - if (!SaveSetShouldMap(client->saveSet[j])) + if (!walk->map) UnmapWindow(pWin, FALSE); ReparentWindow(pWin, pParent, pWin->drawable.x - wBorderWidth(pWin) - @@ -2944,13 +2945,13 @@ HandleSaveSet(ClientPtr client) if (!pWin->realized && pWin->mapped) pWin->mapped = FALSE; } - if (SaveSetShouldMap(client->saveSet[j])) + if (walk->map) MapWindow(pWin, client); } + + xorg_list_del(&walk->entry); + free(walk); } - free(client->saveSet); - client->numSaved = 0; - client->saveSet = NULL; } /** diff --git a/include/dixstruct.h b/include/dixstruct.h index a4dbea09ff..d3e7f5fdd6 100644 --- a/include/dixstruct.h +++ b/include/dixstruct.h @@ -60,18 +60,6 @@ typedef enum { ClientStateInitial, ClientStateGone } ClientState; -typedef struct _saveSet { - struct _Window *windowPtr; - Bool toRoot; - Bool map; -} SaveSetElt; -#define SaveSetWindow(ss) ((ss).windowPtr) -#define SaveSetToRoot(ss) ((ss).toRoot) -#define SaveSetShouldMap(ss) ((ss).map) -#define SaveSetAssignWindow(ss,w) ((ss).windowPtr = (w)) -#define SaveSetAssignToRoot(ss,tr) ((ss).toRoot = (tr)) -#define SaveSetAssignMap(ss,m) ((ss).map = (m)) - struct _ClientId; typedef struct _Client { @@ -95,8 +83,8 @@ typedef struct _Client { XID errorValue; int sequence; int ignoreCount; /* count for Attend/IgnoreClient */ - unsigned numSaved; /* amount of windows in saveSet */ - SaveSetElt *saveSet; + int __dummy0; /* used to be numSave */ + void *__dummy1; /* used to be saveSet */ int (**requestVector) (ClientPtr /* pClient */ ); CARD32 req_len; /* length of current request */ unsigned int replyBytesRemaining; @@ -112,6 +100,10 @@ typedef struct _Client { DeviceIntPtr clientPtr; struct _ClientId *clientIds; int req_fds; + + /* driver should never ever touch anything beyond here */ + + struct xorg_list saveSets; } ClientRec; extern _X_EXPORT TimeStamp currentTime;