xserver/dix/screenint_priv.h
Enrico Weigelt, metux IT consult 70057fdf6e dix: DIX_FOR_N_SCREENS — make self-contained (ternary instead of MIN)
Remove dependency on MIN() from os/mathx_priv.h by replacing the MIN()
call with an explicit bounds check using ternary-style logic.

Changes:
- Change walkStop from int to unsigned (consistency with walkScreenIdx)
- Replace MIN(start + num, screenInfo.numScreens) with explicit check
- Update doc comment to accurately describe 'start + num limited by
  screenInfo.numScreens' semantics instead of 'all screens'
- Fix typo 'poiner' -> 'pointer' in doc comment

This keeps the macro signature and behavior unchanged (#3725 uses it),
while making it self-contained without requiring os/mathx_priv.h.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
2026-09-24 14:23:13 +02:00

151 lines
4.9 KiB
C

/* SPDX-License-Identifier: X11 OR MIT OR AGPL-3.0-or-later
*
* Copyright © 2026 Enrico Weigelt, metux IT consult <info@metux.net>
*/
#ifndef _XSERVER_DIX_SCREENINT_PRIV_H
#define _XSERVER_DIX_SCREENINT_PRIV_H
#include <stdbool.h>
#include <X11/Xdefs.h>
#include "include/callback.h"
#include "include/screenint.h"
#include "include/scrnintstr.h" /* for screenInfo */
#include "Xext/panoramiX/panoramiX_priv.h"
typedef bool (*ScreenInitProcPtr)(ScreenPtr pScreen, int argc, char **argv, void *closure);
int AddScreen(ScreenInitProcPtr pfnInit, int argc, char **argv, void *closure);
int AddGPUScreen(ScreenInitProcPtr pfnInit, int argc, char **argv, void *closure);
void RemoveGPUScreen(ScreenPtr pScreen);
void AttachUnboundGPU(ScreenPtr pScreen, ScreenPtr newScreen);
void DetachUnboundGPU(ScreenPtr unbound);
void AttachOffloadGPU(ScreenPtr pScreen, ScreenPtr newScreen);
void DetachOffloadGPU(ScreenPtr slave);
void InitOutput(int argc, char **argv);
static inline ScreenPtr dixGetMasterScreen(void) {
return screenInfo.screens[0];
}
/*
* retrieve pointer to screen by it's index. If index is above the total
* number of screens, returns NULL
*
* @param idx screen index
* @return pointer to idx'th screen or NULL
*/
static inline ScreenPtr dixGetScreenPtr(unsigned int idx) {
if (idx < screenInfo.numScreens)
return screenInfo.screens[idx];
return NULL;
}
/*
* check whether screen with given index exists
*
* @param idx screen index
* @return TRUE if the screen at this index exists
*/
static inline bool dixScreenExists(unsigned int idx) {
return ((idx < screenInfo.numScreens) &&
(screenInfo.screens[idx] != NULL));
}
/*
* macro for looping over all screens (up to `screenInfo.numScreens`).
* 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.
*/
#define DIX_FOR_EACH_SCREEN(__LAMBDA__) \
do { \
for (unsigned walkScreenIdx = 0; walkScreenIdx < screenInfo.numScreens; walkScreenIdx++) { \
ScreenPtr walkScreen = screenInfo.screens[walkScreenIdx]; \
(void)walkScreen; \
__LAMBDA__; \
} \
} while (0);
/*
* macro for looping over a range of screens (up to `start + num`,
* limited by `screenInfo.numScreens`).
* Makes a new scope and declares `walkScreenIdx` as the current screen's
* index number as well as `walkScreen` as pointer to current ScreenRec
*
* @param start starting screen index
* @param num number of screens to walk (limited by screenInfo.numScreens)
* @param __LAMBDA__ the code to be executed in each iteration step.
*/
#define DIX_FOR_N_SCREENS(start, num, __LAMBDA__) \
do { \
unsigned walkStop = (unsigned)(start + num); \
if (walkStop > screenInfo.numScreens) \
walkStop = screenInfo.numScreens; \
for (unsigned walkScreenIdx = start; walkScreenIdx < walkStop; walkScreenIdx++) { \
ScreenPtr walkScreen = screenInfo.screens[walkScreenIdx]; \
(void)walkScreen; \
__LAMBDA__; \
} \
} while (0);
/*
* macro for looping over all screens (up to `screenInfo.numScreens`),
* but if XINERAMA enabled only hit the first screen.
*
* @param __LAMBDA__ the code to be executed in each iteration step.
*/
#ifdef XINERAMA
#define DIX_FOR_EACH_SCREEN_XINERAMA(__LAMBDA__) \
do { \
unsigned int __num_screens = screenInfo.numScreens; \
if (PanoramiXIsEnabled()) { __num_screens = 1; } \
for (unsigned walkScreenIdx = 0; walkScreenIdx < __num_screens; walkScreenIdx++) { \
ScreenPtr walkScreen = screenInfo.screens[walkScreenIdx]; \
(void)walkScreen; \
__LAMBDA__; \
} \
} while (0);
#else
#define DIX_FOR_EACH_SCREEN_XINERAMA DIX_FOR_EACH_SCREEN
#endif
/*
* macro for looping over all GPU screens (up to `screenInfo.numScreens`).
* 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.
*/
#define DIX_FOR_EACH_GPU_SCREEN(__LAMBDA__) \
do { \
for (unsigned walkScreenIdx = 0; walkScreenIdx < screenInfo.numGPUScreens; walkScreenIdx++) { \
ScreenPtr walkScreen = screenInfo.gpuscreens[walkScreenIdx]; \
(void)walkScreen; \
__LAMBDA__; \
} \
} while (0);
extern CallbackListPtr ScreenAccessCallback;
typedef struct {
ClientPtr client;
ScreenPtr screen;
Mask access_mode;
int status;
} ScreenAccessCallbackParam;
static inline int dixCallScreenAccessCallback(ClientPtr client, ScreenPtr screen, Mask access_mode)
{
ScreenAccessCallbackParam rec = { client, screen, access_mode, Success };
CallCallbacks(&ScreenAccessCallback, &rec);
return rec.status;
}
#endif /* _XSERVER_DIX_SCREENINT_PRIV_H */