Compare commits

...

9 Commits

Author SHA1 Message Date
Marco Lizza
c549b83d1e
Merge cdcd9c194a into 936307558e 2025-11-08 10:42:16 +00:00
Doug Binks
936307558e X11: Clamp w,h in glfwSetWindowSize to >= 1
-  prevents BadValue error and program exit
2025-11-08 10:37:52 +00:00
Drew Weymouth
4df5129529 X11: check crtcInfo for NULL when polling monitors 2025-11-07 17:39:26 +00:00
Ivor Wanders
6de70d8252 X11: Prevent BadWindow when creating small windows
The glfwCreateWindow function ensures that the width and height are
at least greater or equal than zero, but on X11 it is invalid to
create a window with dimensions that equal zero, see [1].

This change ensures that the dimensions passed to XCreateWindow are
at least 1 by 1.

This issue was detected in [2], where a call to glfwCreateWindow
was done to request a 1x1 window, with a _glfw.x11.contentScaleX of
less than 1.0 (0.958333) this results in a request for a 0x0 window
which then causes an BadWindow error from X11.

[1]: e003f52661/specs/libX11/CH03.xml (L1333-1337)
[2]: https://github.com/WerWolv/ImHex/pull/2390
2025-11-07 17:24:35 +00:00
Marco Lizza
cdcd9c194a Fixing dlsym cast warning. 2024-02-29 01:57:41 +01:00
Marco Lizza
596cabbe58 Tweaking GLFW_ANY_POSITION to int32_t max value to avoid signed/unsigned warnings. 2024-02-29 01:51:48 +01:00
Marco Lizza
a02b287b1d Fixing signed/unsigned mismatch warnings. 2024-02-29 01:50:49 +01:00
Marco Lizza
7c2e8c7c5a Using designated initializers to avoid warnings. 2024-02-29 01:50:21 +01:00
Marco Lizza
58f2aab759 Fixing constant pointers. 2024-02-29 01:49:48 +01:00
20 changed files with 73 additions and 47 deletions

View File

@ -282,10 +282,12 @@ video tutorials.
- Corentin Wallez
- Torsten Walluhn
- Patrick Walton
- Ivor Wanders
- Jim Wang
- Xo Wang
- Andre Weissflog
- Jay Weisskopf
- Drew Weymouth
- Frank Wille
- Andy Williams
- Joel Winarske

View File

@ -145,6 +145,10 @@ information on what to include when reporting a bug.
- [Wayland] Bugfix: The cursor position was not updated when clicking through
from a modal to the content area
- [X11] Bugfix: Running without a WM could trigger an assert (#2593,#2601,#2631)
- [X11] Bugfix: Occasional crash when an idle display awakes (#2766)
- [X11] Bugfix: Prevent BadWindow when creating small windows with a content scale
less than 1 (#2754)
- [X11] Bugfix: Clamp width and height to >= 1 to prevent BadValue error and app exit
- [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface`
- [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless`
- [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to

View File

@ -1180,7 +1180,7 @@ extern "C" {
#define GLFW_WAYLAND_PREFER_LIBDECOR 0x00038001
#define GLFW_WAYLAND_DISABLE_LIBDECOR 0x00038002
#define GLFW_ANY_POSITION 0x80000000
#define GLFW_ANY_POSITION 0x7FFFFFFF
/*! @defgroup shapes Standard cursor shapes
* @brief Standard system cursor shapes.

View File

@ -272,7 +272,7 @@ EGLenum _glfwGetEGLPlatformCocoa(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayCocoa(void);
EGLNativeWindowType _glfwGetEGLNativeWindowCocoa(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsCocoa(char** extensions);
void _glfwGetRequiredInstanceExtensionsCocoa(const char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportCocoa(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);

View File

@ -1922,7 +1922,7 @@ EGLNativeWindowType _glfwGetEGLNativeWindowCocoa(_GLFWwindow* window)
return window->ns.layer;
}
void _glfwGetRequiredInstanceExtensionsCocoa(char** extensions)
void _glfwGetRequiredInstanceExtensionsCocoa(const char** extensions)
{
if (_glfw.vk.KHR_surface && _glfw.vk.EXT_metal_surface)
{

View File

@ -1289,7 +1289,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
const size_t length = strcspn(c, "\r\n");
if (length < sizeof(line))
{
_GLFWmapping mapping = {{0}};
_GLFWmapping mapping = { .name = {0} };
memcpy(line, c, length);
line[length] = '\0';

View File

@ -755,7 +755,7 @@ struct _GLFWplatform
EGLNativeDisplayType (*getEGLNativeDisplay)(void);
EGLNativeWindowType (*getEGLNativeWindow)(_GLFWwindow*);
// vulkan
void (*getRequiredInstanceExtensions)(char**);
void (*getRequiredInstanceExtensions)(const char**);
GLFWbool (*getPhysicalDevicePresentationSupport)(VkInstance,VkPhysicalDevice,uint32_t);
VkResult (*createWindowSurface)(VkInstance,_GLFWwindow*,const VkAllocationCallbacks*,VkSurfaceKHR*);
};
@ -862,7 +862,7 @@ struct _GLFWlibrary
struct {
GLFWbool available;
void* handle;
char* extensions[2];
const char* extensions[2];
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
GLFWbool KHR_surface;
GLFWbool KHR_win32_surface;

View File

@ -274,7 +274,7 @@ EGLenum _glfwGetEGLPlatformNull(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void);
EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsNull(char** extensions);
void _glfwGetRequiredInstanceExtensionsNull(const char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportNull(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceNull(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);

View File

@ -701,7 +701,7 @@ int _glfwGetKeyScancodeNull(int key)
return _glfw.null.scancodes[key];
}
void _glfwGetRequiredInstanceExtensionsNull(char** extensions)
void _glfwGetRequiredInstanceExtensionsNull(const char** extensions)
{
if (!_glfw.vk.KHR_surface || !_glfw.vk.EXT_headless_surface)
return;

View File

@ -44,10 +44,17 @@ void _glfwPlatformFreeModule(void* module)
dlclose(module);
}
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name)
{
return dlsym(module, name);
return (GLFWproc)dlsym(module, name);
}
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#endif // GLFW_BUILD_POSIX_MODULE

View File

@ -150,7 +150,7 @@ GLFWbool _glfwInitVulkan(int mode)
_glfw.vk.available = GLFW_TRUE;
_glfw.platform.getRequiredInstanceExtensions(_glfw.vk.extensions);
_glfw.platform.getRequiredInstanceExtensions((const char **)_glfw.vk.extensions);
return GLFW_TRUE;
}

View File

@ -540,7 +540,7 @@ EGLenum _glfwGetEGLPlatformWin32(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayWin32(void);
EGLNativeWindowType _glfwGetEGLNativeWindowWin32(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsWin32(char** extensions);
void _glfwGetRequiredInstanceExtensionsWin32(const char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportWin32(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceWin32(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);

View File

@ -2501,7 +2501,7 @@ EGLNativeWindowType _glfwGetEGLNativeWindowWin32(_GLFWwindow* window)
return window->win32.handle;
}
void _glfwGetRequiredInstanceExtensionsWin32(char** extensions)
void _glfwGetRequiredInstanceExtensionsWin32(const char** extensions)
{
if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_win32_surface)
return;

View File

@ -243,7 +243,7 @@ void libdecorHandleError(struct libdecor* context,
static const struct libdecor_interface libdecorInterface =
{
libdecorHandleError
.error = libdecorHandleError
};
static void libdecorReadyCallback(void* userData,

View File

@ -674,7 +674,7 @@ EGLenum _glfwGetEGLPlatformWayland(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayWayland(void);
EGLNativeWindowType _glfwGetEGLNativeWindowWayland(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsWayland(char** extensions);
void _glfwGetRequiredInstanceExtensionsWayland(const char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportWayland(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceWayland(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);

View File

@ -620,8 +620,8 @@ static void surfaceHandleLeave(void* userData,
static const struct wl_surface_listener surfaceListener =
{
surfaceHandleEnter,
surfaceHandleLeave
.enter = surfaceHandleEnter,
.leave = surfaceHandleLeave
};
static void setIdleInhibitor(_GLFWwindow* window, GLFWbool enable)
@ -762,8 +762,8 @@ static void xdgToplevelHandleClose(void* userData,
static const struct xdg_toplevel_listener xdgToplevelListener =
{
xdgToplevelHandleConfigure,
xdgToplevelHandleClose
.configure = xdgToplevelHandleConfigure,
.close = xdgToplevelHandleClose
};
static void xdgSurfaceHandleConfigure(void* userData,
@ -937,10 +937,10 @@ void libdecorFrameHandleDismissPopup(struct libdecor_frame* frame,
static const struct libdecor_frame_interface libdecorFrameInterface =
{
libdecorFrameHandleConfigure,
libdecorFrameHandleClose,
libdecorFrameHandleCommit,
libdecorFrameHandleDismissPopup
.configure = libdecorFrameHandleConfigure,
.close = libdecorFrameHandleClose,
.commit = libdecorFrameHandleCommit,
.dismiss_popup = libdecorFrameHandleDismissPopup
};
static GLFWbool createLibdecorFrame(_GLFWwindow* window)
@ -1290,7 +1290,7 @@ static GLFWbool flushDisplay(void)
if (errno != EAGAIN)
return GLFW_FALSE;
struct pollfd fd = { wl_display_get_fd(_glfw.wl.display), POLLOUT };
struct pollfd fd = { .fd = wl_display_get_fd(_glfw.wl.display), POLLOUT };
while (poll(&fd, 1, -1) == -1)
{
@ -1664,11 +1664,11 @@ static void pointerHandleAxis(void* userData,
static const struct wl_pointer_listener pointerListener =
{
pointerHandleEnter,
pointerHandleLeave,
pointerHandleMotion,
pointerHandleButton,
pointerHandleAxis,
.enter = pointerHandleEnter,
.leave = pointerHandleLeave,
.motion = pointerHandleMotion,
.button = pointerHandleButton,
.axis = pointerHandleAxis,
};
static void keyboardHandleKeymap(void* userData,
@ -1977,7 +1977,7 @@ static void dataOfferHandleOffer(void* userData,
static const struct wl_data_offer_listener dataOfferListener =
{
dataOfferHandleOffer
.offer = dataOfferHandleOffer
};
static void dataDeviceHandleDataOffer(void* userData,
@ -1996,7 +1996,7 @@ static void dataDeviceHandleDataOffer(void* userData,
_glfw.wl.offers = offers;
_glfw.wl.offerCount++;
_glfw.wl.offers[_glfw.wl.offerCount - 1] = (_GLFWofferWayland) { offer };
_glfw.wl.offers[_glfw.wl.offerCount - 1] = (_GLFWofferWayland) { .offer = offer };
wl_data_offer_add_listener(offer, &dataOfferListener, NULL);
}
@ -3185,9 +3185,9 @@ static void dataSourceHandleCancelled(void* userData,
static const struct wl_data_source_listener dataSourceListener =
{
dataSourceHandleTarget,
dataSourceHandleSend,
dataSourceHandleCancelled,
.target = dataSourceHandleTarget,
.send = dataSourceHandleSend,
.cancelled = dataSourceHandleCancelled,
};
void _glfwSetClipboardStringWayland(const char* string)
@ -3261,7 +3261,7 @@ EGLNativeWindowType _glfwGetEGLNativeWindowWayland(_GLFWwindow* window)
return window->wl.egl.window;
}
void _glfwGetRequiredInstanceExtensionsWayland(char** extensions)
void _glfwGetRequiredInstanceExtensionsWayland(const char** extensions)
{
if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_wayland_surface)
return;

View File

@ -231,7 +231,7 @@ static void createKeyTables(void)
const struct
{
int key;
char* name;
const char* name;
} keymap[] =
{
{ GLFW_KEY_GRAVE_ACCENT, "TLDE" },
@ -366,7 +366,7 @@ static void createKeyTables(void)
// keyboard layout. Because function keys aren't mapped correctly
// when using traditional KeySym translations, they are mapped
// here instead.
for (int i = 0; i < sizeof(keymap) / sizeof(keymap[0]); i++)
for (size_t i = 0; i < sizeof(keymap) / sizeof(keymap[0]); i++)
{
if (strncmp(desc->names->keys[scancode].name,
keymap[i].name,
@ -390,7 +390,7 @@ static void createKeyTables(void)
continue;
}
for (int j = 0; j < sizeof(keymap) / sizeof(keymap[0]); j++)
for (size_t j = 0; j < sizeof(keymap) / sizeof(keymap[0]); j++)
{
if (strncmp(desc->names->key_aliases[i].alias,
keymap[j].name,

View File

@ -151,6 +151,11 @@ void _glfwPollMonitorsX11(void)
}
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
if (!ci) {
XRRFreeOutputInfo(oi);
continue;
}
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
{
widthMM = oi->mm_height;
@ -180,8 +185,8 @@ void _glfwPollMonitorsX11(void)
{
if (screens[j].x_org == ci->x &&
screens[j].y_org == ci->y &&
screens[j].width == ci->width &&
screens[j].height == ci->height)
screens[j].width == (int)ci->width &&
screens[j].height == (int)ci->height)
{
monitor->x11.index = j;
break;
@ -573,7 +578,7 @@ void _glfwSetGammaRampX11(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
{
if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) != ramp->size)
if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) != (int)ramp->size)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Gamma ramp size must match current ramp size");

View File

@ -960,7 +960,7 @@ EGLenum _glfwGetEGLPlatformX11(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayX11(void);
EGLNativeWindowType _glfwGetEGLNativeWindowX11(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsX11(char** extensions);
void _glfwGetRequiredInstanceExtensionsX11(const char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportX11(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceX11(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);

View File

@ -62,7 +62,7 @@
//
static GLFWbool waitForX11Event(double* timeout)
{
struct pollfd fd = { ConnectionNumber(_glfw.x11.display), POLLIN };
struct pollfd fd = { .fd = ConnectionNumber(_glfw.x11.display), .events = POLLIN };
while (!XPending(_glfw.x11.display))
{
@ -97,7 +97,7 @@ static GLFWbool waitForAnyEvent(double* timeout)
if (!_glfwPollPOSIX(fds, sizeof(fds) / sizeof(fds[0]), timeout))
return GLFW_FALSE;
for (int i = 1; i < sizeof(fds) / sizeof(fds[0]); i++)
for (size_t i = 1; i < sizeof(fds) / sizeof(fds[0]); i++)
{
if (fds[i].revents & POLLIN)
return GLFW_TRUE;
@ -235,10 +235,10 @@ static int translateState(int state)
// Translates an X11 key code to a GLFW key token
//
static int translateKey(int scancode)
static int translateKey(unsigned int scancode)
{
// Use the pre-filled LUT (see createKeyTables() in x11_init.c)
if (scancode < 0 || scancode > 255)
if (scancode > 255)
return GLFW_KEY_UNKNOWN;
return _glfw.x11.keycodes[scancode];
@ -576,6 +576,10 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
height *= _glfw.x11.contentScaleY;
}
// The dimensions must be nonzero, or a BadValue error results.
width = _glfw_max(1, width);
height = _glfw_max(1, height);
int xpos = 0, ypos = 0;
if (wndconfig->xpos != GLFW_ANY_POSITION && wndconfig->ypos != GLFW_ANY_POSITION)
@ -1145,7 +1149,7 @@ static void releaseMonitor(_GLFWwindow* window)
//
static void processEvent(XEvent *event)
{
int keycode = 0;
unsigned int keycode = 0;
Bool filtered = False;
// HACK: Save scancode as some IMs clear the field in XFilterEvent
@ -2203,6 +2207,10 @@ void _glfwGetWindowSizeX11(_GLFWwindow* window, int* width, int* height)
void _glfwSetWindowSizeX11(_GLFWwindow* window, int width, int height)
{
// The dimensions must be nonzero, or a BadValue error results.
width = _glfw_max(1, width);
height = _glfw_max(1, height);
if (window->monitor)
{
if (window->monitor->window == window)
@ -3133,7 +3141,7 @@ EGLNativeWindowType _glfwGetEGLNativeWindowX11(_GLFWwindow* window)
return (EGLNativeWindowType) window->x11.handle;
}
void _glfwGetRequiredInstanceExtensionsX11(char** extensions)
void _glfwGetRequiredInstanceExtensionsX11(const char** extensions)
{
if (!_glfw.vk.KHR_surface)
return;