From a2fd9501d1c0e9ea3858fff117552d8369358ed2 Mon Sep 17 00:00:00 2001 From: "Enrico Weigelt, metux IT consult" Date: Thu, 2 Jul 2026 17:05:21 +0200 Subject: [PATCH] panoramiX: make XINERAMA_FOR_EACH_SCREEN_* macros variadic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The XINERAMA_FOR_EACH_SCREEN_FORWARD / _FORWARD_SKIP0 / _BACKWARD macros took the loop body as a single macro parameter. Any top-level comma in the body was therefore parsed as an argument separator, so a body containing e.g. a designated initialiser (`Foo f = { .a = 1, .b = 2 };`) failed to compile — the reason for the existing "static init would confuse preprocessor" workarounds at the call sites. Pass the body as a variadic argument (`...` / `__VA_ARGS__`) instead. Commas in the body are then preserved, so ordinary designated initialisers (and other comma-containing statements) can be used in the loop body without compound-literal-cast or memset workarounds. Pure enabling change: all existing call sites pass a single brace block, which is unchanged as __VA_ARGS__. Build-verified (Xvfb/Xnest link). Signed-off-by: Enrico Weigelt, metux IT consult (cherry picked from commit 486d71c5b066c25665dd9781fc795e157b2356a0) --- Xext/panoramiX/panoramiX.h | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/Xext/panoramiX/panoramiX.h b/Xext/panoramiX/panoramiX.h index 3db3079ee..be57b4d44 100644 --- a/Xext/panoramiX/panoramiX.h +++ b/Xext/panoramiX/panoramiX.h @@ -73,14 +73,18 @@ typedef struct { * Makes a new scopes and declares `walkScreenIdx` as the current screen's * index number as well as `walkScreen` as poiner to current ScreenRec * - * @param __LAMBDA__ the code to be executed in each iteration step. + * The body is passed via a variadic parameter so it may contain top-level + * commas (e.g. a `Foo f = { .a = 1, .b = 2 };` designated initialiser) + * without being mis-parsed as multiple macro arguments. + * + * @param ... the code to be executed in each iteration step. */ -#define XINERAMA_FOR_EACH_SCREEN_FORWARD(__LAMBDA__) \ +#define XINERAMA_FOR_EACH_SCREEN_FORWARD(...) \ do { \ for (unsigned walkScreenIdx = 0; walkScreenIdx < PanoramiXNumScreens; walkScreenIdx++) { \ ScreenPtr walkScreen = screenInfo.screens[walkScreenIdx]; \ (void)walkScreen; \ - __LAMBDA__; \ + __VA_ARGS__; \ } \ } while (0); @@ -88,29 +92,37 @@ typedef struct { * just like XINERAMA_FOR_EACH_SCREEN_FORWARD(), but skipping the first * screen (which is the frontend to the client) * - * @param __LAMBDA__ the code to be executed in each iteration step. + * The body is passed via a variadic parameter so it may contain top-level + * commas (e.g. a `Foo f = { .a = 1, .b = 2 };` designated initialiser) + * without being mis-parsed as multiple macro arguments. + * + * @param ... the code to be executed in each iteration step. */ -#define XINERAMA_FOR_EACH_SCREEN_FORWARD_SKIP0(__LAMBDA__) \ +#define XINERAMA_FOR_EACH_SCREEN_FORWARD_SKIP0(...) \ do { \ for (unsigned walkScreenIdx = 1; walkScreenIdx < PanoramiXNumScreens; walkScreenIdx++) { \ ScreenPtr walkScreen = screenInfo.screens[walkScreenIdx]; \ (void)walkScreen; \ - __LAMBDA__; \ + __VA_ARGS__; \ } \ } while (0); /* * like XINERAMA_FOR_EACH_SCREEN_FORWARD(), but traveling backwards. * - * @param __LAMBDA__ the code to be executed in each iteration step. + * The body is passed via a variadic parameter so it may contain top-level + * commas (e.g. a `Foo f = { .a = 1, .b = 2 };` designated initialiser) + * without being mis-parsed as multiple macro arguments. + * + * @param ... the code to be executed in each iteration step. */ -#define XINERAMA_FOR_EACH_SCREEN_BACKWARD(__LAMBDA__) \ +#define XINERAMA_FOR_EACH_SCREEN_BACKWARD(...) \ do { \ for (unsigned __walkidx = PanoramiXNumScreens; __walkidx > 0; __walkidx--) { \ unsigned walkScreenIdx = __walkidx - 1; \ ScreenPtr walkScreen = screenInfo.screens[walkScreenIdx]; \ (void)walkScreen; \ - __LAMBDA__; \ + __VA_ARGS__; \ } \ } while (0);