From b1f8ba81c4e4575058720dcddcd308169d63a0ab Mon Sep 17 00:00:00 2001 From: "Enrico Weigelt, metux IT consult" Date: Mon, 29 Jul 2024 14:22:00 +0200 Subject: [PATCH] (!1794) 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 --- randr/randr.c | 11 ---- randr/randrstr_priv.h | 3 +- randr/rrdispatch.c | 125 +++++++++++++++++++++++------------------- 3 files changed, 70 insertions(+), 69 deletions(-) diff --git a/randr/randr.c b/randr/randr.c index 59d101ba76..078514a3c5 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -50,7 +50,6 @@ static int RRNScreens; real->mem = priv->mem; \ } -static int ProcRRDispatch(ClientPtr pClient); static int SProcRRDispatch(ClientPtr pClient); int RREventBase; @@ -738,16 +737,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) { diff --git a/randr/randrstr_priv.h b/randr/randrstr_priv.h index 7f802215f9..a125f293ab 100644 --- a/randr/randrstr_priv.h +++ b/randr/randrstr_priv.h @@ -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_ */ diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c index 4381f52ca2..5552d27821 100644 --- a/randr/rrdispatch.c +++ b/randr/rrdispatch.c @@ -211,60 +211,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; +}