randr: use explicit case statement instead of ProcRandrVector table

No need to go indirectly through a vector table, since everything's fixed
anyways. It's not a pretty robust programming style: any changes need great
care, in order to not mix up things.

Replacing this by direct switch/case statement, which is using the defines
from the xrandr protocol headers. Also adding a little bit more protection
against subtle programming errors and reducing cognitive load (source size)
on understanding the code by using a tiny macro for deducing define name and
function name from the request's name.

This approach actually uncovered some subtle bug that had been waiting in
the dark for over 15 years.

As collateral benefit, getting a tiny bit better performance.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
Enrico Weigelt, metux IT consult
2024-07-29 14:22:00 +02:00
parent 00ef5b1f5f
commit da336d0fe3
3 changed files with 70 additions and 69 deletions

View File

@@ -50,7 +50,6 @@ static int RRNScreens;
real->mem = priv->mem; \
}
static int ProcRRDispatch(ClientPtr pClient);
static int SProcRRDispatch(ClientPtr pClient);
int RREventBase;
@@ -723,16 +722,6 @@ RRVerticalRefresh(xRRModeInfo * mode)
return (CARD16) refresh;
}
static int
ProcRRDispatch(ClientPtr client)
{
REQUEST(xReq);
if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data])
return BadRequest;
UpdateCurrentTimeIf();
return (*ProcRandrVector[stuff->data]) (client);
}
static int _X_COLD
SProcRRDispatch(ClientPtr client)
{

View File

@@ -33,7 +33,6 @@
extern int RREventBase, RRErrorBase;
extern int (*ProcRandrVector[RRNumberRequests]) (ClientPtr);
extern int (*SProcRandrVector[RRNumberRequests]) (ClientPtr);
extern RESTYPE RRClientType, RREventType; /* resource types for event masks */
@@ -140,4 +139,6 @@ int ProcRRQueryVersion(ClientPtr client);
int ProcRRSelectInput(ClientPtr client);
int ProcRRDispatch(ClientPtr client);
#endif /* _XSERVER_RANDRSTR_PRIV_H_ */

View File

@@ -210,60 +210,71 @@ ProcRRSelectInput(ClientPtr client)
return Success;
}
int (*ProcRandrVector[RRNumberRequests]) (ClientPtr) = {
ProcRRQueryVersion, /* 0 */
/* we skip 1 to make old clients fail pretty immediately */
NULL, /* 1 ProcRandrOldGetScreenInfo */
/* V1.0 apps share the same set screen config request id */
ProcRRSetScreenConfig, /* 2 */
NULL, /* 3 ProcRandrOldScreenChangeSelectInput */
/* 3 used to be ScreenChangeSelectInput; deprecated */
ProcRRSelectInput, /* 4 */
ProcRRGetScreenInfo, /* 5 */
/* V1.2 additions */
ProcRRGetScreenSizeRange, /* 6 */
ProcRRSetScreenSize, /* 7 */
ProcRRGetScreenResources, /* 8 */
ProcRRGetOutputInfo, /* 9 */
ProcRRListOutputProperties, /* 10 */
ProcRRQueryOutputProperty, /* 11 */
ProcRRConfigureOutputProperty, /* 12 */
ProcRRChangeOutputProperty, /* 13 */
ProcRRDeleteOutputProperty, /* 14 */
ProcRRGetOutputProperty, /* 15 */
ProcRRCreateMode, /* 16 */
ProcRRDestroyMode, /* 17 */
ProcRRAddOutputMode, /* 18 */
ProcRRDeleteOutputMode, /* 19 */
ProcRRGetCrtcInfo, /* 20 */
ProcRRSetCrtcConfig, /* 21 */
ProcRRGetCrtcGammaSize, /* 22 */
ProcRRGetCrtcGamma, /* 23 */
ProcRRSetCrtcGamma, /* 24 */
/* V1.3 additions */
ProcRRGetScreenResourcesCurrent, /* 25 */
ProcRRSetCrtcTransform, /* 26 */
ProcRRGetCrtcTransform, /* 27 */
ProcRRGetPanning, /* 28 */
ProcRRSetPanning, /* 29 */
ProcRRSetOutputPrimary, /* 30 */
ProcRRGetOutputPrimary, /* 31 */
/* V1.4 additions */
ProcRRGetProviders, /* 32 */
ProcRRGetProviderInfo, /* 33 */
ProcRRSetProviderOffloadSink, /* 34 */
ProcRRSetProviderOutputSource, /* 35 */
ProcRRListProviderProperties, /* 36 */
ProcRRQueryProviderProperty, /* 37 */
ProcRRConfigureProviderProperty, /* 38 */
ProcRRChangeProviderProperty, /* 39 */
ProcRRDeleteProviderProperty, /* 40 */
ProcRRGetProviderProperty, /* 41 */
/* V1.5 additions */
ProcRRGetMonitors, /* 42 */
ProcRRSetMonitor, /* 43 */
ProcRRDeleteMonitor, /* 44 */
/* V1.6 additions */
ProcRRCreateLease, /* 45 */
ProcRRFreeLease, /* 46 */
};
#define HANDLER(name) case X_##name: return Proc##name(client)
int
ProcRRDispatch(ClientPtr client)
{
REQUEST(xReq);
UpdateCurrentTimeIf();
switch (stuff->data) {
HANDLER(RRQueryVersion);
HANDLER(RRSetScreenConfig);
HANDLER(RRSelectInput);
HANDLER(RRGetScreenInfo);
/* V1.2 additions */
HANDLER(RRGetScreenSizeRange);
HANDLER(RRSetScreenSize);
HANDLER(RRGetScreenResources);
HANDLER(RRGetOutputInfo);
HANDLER(RRListOutputProperties);
HANDLER(RRQueryOutputProperty);
HANDLER(RRConfigureOutputProperty);
HANDLER(RRChangeOutputProperty);
HANDLER(RRDeleteOutputProperty);
HANDLER(RRGetOutputProperty);
HANDLER(RRCreateMode);
HANDLER(RRDestroyMode);
HANDLER(RRAddOutputMode);
HANDLER(RRDeleteOutputMode);
HANDLER(RRGetCrtcInfo);
HANDLER(RRSetCrtcConfig);
HANDLER(RRGetCrtcGammaSize);
HANDLER(RRGetCrtcGamma);
HANDLER(RRSetCrtcGamma);
/* V1.3 additions */
HANDLER(RRGetScreenResourcesCurrent);
HANDLER(RRSetCrtcTransform);
HANDLER(RRGetCrtcTransform);
HANDLER(RRGetPanning);
HANDLER(RRSetPanning);
HANDLER(RRSetOutputPrimary);
HANDLER(RRGetOutputPrimary);
/* V1.4 additions */
HANDLER(RRGetProviders);
HANDLER(RRGetProviderInfo);
HANDLER(RRSetProviderOffloadSink);
HANDLER(RRSetProviderOutputSource);
HANDLER(RRListProviderProperties);
HANDLER(RRQueryProviderProperty);
HANDLER(RRConfigureProviderProperty);
HANDLER(RRChangeProviderProperty);
HANDLER(RRDeleteProviderProperty);
HANDLER(RRGetProviderProperty);
/* V1.5 additions */
HANDLER(RRGetMonitors);
HANDLER(RRSetMonitor);
HANDLER(RRDeleteMonitor);
/* V1.6 additions */
HANDLER(RRCreateLease);
HANDLER(RRFreeLease);
}
return BadRequest;
}