Skip to content

Several fixes for messageboxes on X11 #13042

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 49 additions & 21 deletions src/video/x11/SDL_x11messagebox.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,6 @@ static const SDL_MessageBoxColor g_default_colors[SDL_MESSAGEBOX_COLOR_COUNT] =
{ 205, 202, 53 }, // SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED,
};

#define SDL_MAKE_RGB(_r, _g, _b) (((Uint32)(_r) << 16) | \
((Uint32)(_g) << 8) | \
((Uint32)(_b)))

typedef struct SDL_MessageBoxButtonDataX11
{
int x, y; // Text position
Expand All @@ -95,13 +91,18 @@ typedef struct SDL_MessageBoxDataX11
Display *display;
int screen;
Window window;
Visual *visual;
Colormap cmap;
#ifdef SDL_VIDEO_DRIVER_X11_XDBE
XdbeBackBuffer buf;
bool xdbe; // Whether Xdbe is present or not
#endif
long event_mask;
Atom wm_protocols;
Atom wm_delete_message;
#ifdef SDL_VIDEO_DRIVER_X11_XRANDR
bool xrandr; // Whether Xrandr is present or not
#endif

int dialog_width; // Dialog box width.
int dialog_height; // Dialog box height.
Expand All @@ -122,7 +123,7 @@ typedef struct SDL_MessageBoxDataX11
const SDL_MessageBoxButtonData *buttondata;
SDL_MessageBoxButtonDataX11 buttonpos[MAX_BUTTONS];

Uint32 color[SDL_MESSAGEBOX_COLOR_COUNT];
XColor xcolor[SDL_MESSAGEBOX_COLOR_COUNT];

const SDL_MessageBoxData *messageboxdata;
} SDL_MessageBoxDataX11;
Expand Down Expand Up @@ -199,7 +200,12 @@ static bool X11_MessageBoxInit(SDL_MessageBoxDataX11 *data, const SDL_MessageBox
if (!data->display) {
return SDL_SetError("Couldn't open X11 display");
}


#ifdef SDL_VIDEO_DRIVER_X11_XRANDR
int xrandr_event_base, xrandr_error_base;
data->xrandr = X11_XRRQueryExtension(data->display, &xrandr_event_base, &xrandr_error_base);
#endif

#ifdef X_HAVE_UTF8_STRING
if (SDL_X11_HAVE_UTF8) {
char **missing = NULL;
Expand Down Expand Up @@ -233,9 +239,12 @@ static bool X11_MessageBoxInit(SDL_MessageBoxDataX11 *data, const SDL_MessageBox
colorhints = g_default_colors;
}

// Convert our SDL_MessageBoxColor r,g,b values to packed RGB format.
// Convert colors to 16 bpc XColor format
for (i = 0; i < SDL_MESSAGEBOX_COLOR_COUNT; i++) {
data->color[i] = SDL_MAKE_RGB(colorhints[i].r, colorhints[i].g, colorhints[i].b);
data->xcolor[i].flags = DoRed|DoGreen|DoBlue;
data->xcolor[i].red = colorhints[i].r*257;
data->xcolor[i].green = colorhints[i].g*257;
data->xcolor[i].blue = colorhints[i].b*257;
}

return true;
Expand Down Expand Up @@ -418,7 +427,7 @@ static void X11_MessageBoxShutdown(SDL_MessageBoxDataX11 *data)
// Create and set up our X11 dialog box indow.
static bool X11_MessageBoxCreateWindow(SDL_MessageBoxDataX11 *data)
{
int x, y;
int x, y, i;
XSizeHints *sizehints;
XSetWindowAttributes wnd_attr;
Atom _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DIALOG;
Expand All @@ -441,17 +450,24 @@ static bool X11_MessageBoxCreateWindow(SDL_MessageBoxDataX11 *data)
data->screen = DefaultScreen(display);
}

data->visual = DefaultVisual(display, data->screen);
data->cmap = DefaultColormap(display, data->screen);
for (i = 0; i < SDL_MESSAGEBOX_COLOR_COUNT; i++) {
X11_XAllocColor(display, data->cmap, &data->xcolor[i]);
}

data->event_mask = ExposureMask |
ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask |
StructureNotifyMask | FocusChangeMask | PointerMotionMask;
wnd_attr.event_mask = data->event_mask;
wnd_attr.colormap = data->cmap;

data->window = X11_XCreateWindow(
display, RootWindow(display, data->screen),
0, 0,
data->dialog_width, data->dialog_height,
0, CopyFromParent, InputOutput, CopyFromParent,
CWEventMask, &wnd_attr);
0, DefaultDepth(display, data->screen), InputOutput, data->visual,
CWEventMask | CWColormap, &wnd_attr);
if (data->window == None) {
return SDL_SetError("Couldn't create X window");
}
Expand Down Expand Up @@ -506,15 +522,27 @@ static bool X11_MessageBoxCreateWindow(SDL_MessageBoxDataX11 *data)
y = dpydata->y + ((dpy->current_mode->h - data->dialog_height) / 3);
}
#ifdef SDL_VIDEO_DRIVER_X11_XRANDR
else if (SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XRANDR, use_xrandr_by_default)) {
else if (SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XRANDR, use_xrandr_by_default) && data->xrandr) {
XRRScreenResources *screen = X11_XRRGetScreenResourcesCurrent(display, DefaultRootWindow(display));
if (!screen) {
goto XRANDRBAIL;
}
if (!screen->ncrtc) {
goto XRANDRBAIL;
}

XRRCrtcInfo *crtc_info = X11_XRRGetCrtcInfo(display, screen, screen->crtcs[0]);
x = (crtc_info->width - data->dialog_width) / 2;
y = (crtc_info->height - data->dialog_height) / 3;
if (crtc_info) {
x = (crtc_info->width - data->dialog_width) / 2;
y = (crtc_info->height - data->dialog_height) / 3;
} else {
goto XRANDRBAIL;
}
}
#endif
else {
// oh well. This will misposition on a multi-head setup. Init first next time.
XRANDRBAIL:
x = (DisplayWidth(display, data->screen) - data->dialog_width) / 2;
y = (DisplayHeight(display, data->screen) - data->dialog_height) / 3;
}
Expand Down Expand Up @@ -569,10 +597,10 @@ static void X11_MessageBoxDraw(SDL_MessageBoxDataX11 *data, GC ctx)
}
#endif

X11_XSetForeground(display, ctx, data->color[SDL_MESSAGEBOX_COLOR_BACKGROUND]);
X11_XSetForeground(display, ctx, data->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].pixel);
X11_XFillRectangle(display, window, ctx, 0, 0, data->dialog_width, data->dialog_height);

X11_XSetForeground(display, ctx, data->color[SDL_MESSAGEBOX_COLOR_TEXT]);
X11_XSetForeground(display, ctx, data->xcolor[SDL_MESSAGEBOX_COLOR_TEXT].pixel);
for (i = 0; i < data->numlines; i++) {
TextLineData *plinedata = &data->linedata[i];

Expand All @@ -596,17 +624,17 @@ static void X11_MessageBoxDraw(SDL_MessageBoxDataX11 *data, GC ctx)
int border = (buttondata->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) ? 2 : 0;
int offset = ((data->mouse_over_index == i) && (data->button_press_index == data->mouse_over_index)) ? 1 : 0;

X11_XSetForeground(display, ctx, data->color[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND]);
X11_XSetForeground(display, ctx, data->xcolor[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].pixel);
X11_XFillRectangle(display, window, ctx,
buttondatax11->rect.x - border, buttondatax11->rect.y - border,
buttondatax11->rect.w + 2 * border, buttondatax11->rect.h + 2 * border);

X11_XSetForeground(display, ctx, data->color[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER]);
X11_XSetForeground(display, ctx, data->xcolor[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].pixel);
X11_XDrawRectangle(display, window, ctx,
buttondatax11->rect.x, buttondatax11->rect.y,
buttondatax11->rect.w, buttondatax11->rect.h);

X11_XSetForeground(display, ctx, (data->mouse_over_index == i) ? data->color[SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED] : data->color[SDL_MESSAGEBOX_COLOR_TEXT]);
X11_XSetForeground(display, ctx, (data->mouse_over_index == i) ? data->xcolor[SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED].pixel : data->xcolor[SDL_MESSAGEBOX_COLOR_TEXT].pixel);

#ifdef X_HAVE_UTF8_STRING
if (SDL_X11_HAVE_UTF8) {
Expand Down Expand Up @@ -657,8 +685,8 @@ static bool X11_MessageBoxLoop(SDL_MessageBoxDataX11 *data)
#endif

SDL_zero(ctx_vals);
ctx_vals.foreground = data->color[SDL_MESSAGEBOX_COLOR_BACKGROUND];
ctx_vals.background = data->color[SDL_MESSAGEBOX_COLOR_BACKGROUND];
ctx_vals.foreground = data->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].pixel;
ctx_vals.background = data->xcolor[SDL_MESSAGEBOX_COLOR_BACKGROUND].pixel;

if (!have_utf8) {
gcflags |= GCFont;
Expand Down
1 change: 1 addition & 0 deletions src/video/x11/SDL_x11sym.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ SDL_X11_SYM(Cursor,XCreatePixmapCursor,(Display* a,Pixmap b,Pixmap c,XColor* d,X
SDL_X11_SYM(Cursor,XCreateFontCursor,(Display* a,unsigned int b))
SDL_X11_SYM(XFontSet,XCreateFontSet,(Display* a, _Xconst char* b, char*** c, int* d, char** e))
SDL_X11_SYM(GC,XCreateGC,(Display* a,Drawable b,unsigned long c,XGCValues* d))
SDL_X11_SYM(Status,XAllocColor,(Display *a, Colormap b, XColor *c))
SDL_X11_SYM(XImage*,XCreateImage,(Display* a,Visual* b,unsigned int c,int d,int e,char* f,unsigned int g,unsigned int h,int i,int j))
SDL_X11_SYM(Window,XCreateWindow,(Display* a,Window b,int c,int d,unsigned int e,unsigned int f,unsigned int g,int h,unsigned int i,Visual* j,unsigned long k,XSetWindowAttributes* l))
SDL_X11_SYM(int,XDefineCursor,(Display* a,Window b,Cursor c))
Expand Down
Loading