X11TK: Introduce Thai support and rewrite/cleanup messagebox positioning code (#14474)

This commit is contained in:
eafton
2025-11-21 02:26:46 +03:00
committed by GitHub
parent 92eaa34277
commit 36976ecb43
10 changed files with 840 additions and 441 deletions

View File

@@ -349,6 +349,8 @@ dep_option(SDL_X11_XSYNC "Enable Xsync support" ON SDL_X11 OFF)
dep_option(SDL_X11_XTEST "Enable XTest support" ON SDL_X11 OFF)
dep_option(SDL_FRIBIDI "Enable Fribidi support" ON SDL_X11 OFF)
dep_option(SDL_FRIBIDI_SHARED "Dynamically load Fribidi support" ON "SDL_FRIBIDI;SDL_DEPS_SHARED" OFF)
dep_option(SDL_LIBTHAI "Enable Thai support" ON SDL_X11 OFF)
dep_option(SDL_LIBTHAI_SHARED "Dynamically load Thai support" ON "SDL_LIBTHAI;SDL_DEPS_SHARED" OFF)
dep_option(SDL_WAYLAND "Use Wayland video driver" ${UNIX_SYS} "SDL_VIDEO" OFF)
dep_option(SDL_WAYLAND_SHARED "Dynamically load Wayland support" ON "SDL_WAYLAND;SDL_DEPS_SHARED" OFF)
dep_option(SDL_WAYLAND_LIBDECOR "Use client-side window decorations on Wayland" ON "SDL_WAYLAND" OFF)
@@ -1813,6 +1815,7 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
CheckROCKCHIP()
CheckX11()
CheckFribidi()
CheckLibThai()
# Need to check for EGL first because KMSDRM and Wayland depend on it.
CheckEGL()
CheckKMSDRM()

View File

@@ -588,6 +588,31 @@ macro(CheckFribidi)
endif()
endmacro()
macro(CheckLibThai)
if(SDL_LIBTHAI)
set(LIBTHAI_PKG_CONFIG_SPEC libthai)
set(PC_LIBTHAI_FOUND FALSE)
if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_LIBTHAI IMPORTED_TARGET ${LIBTHAI_PKG_CONFIG_SPEC})
endif()
if(PC_LIBTHAI_FOUND)
set(HAVE_LIBTHAI TRUE)
set(HAVE_LIBTHAI_H 1)
if(SDL_LIBTHAI_SHARED AND NOT HAVE_SDL_LOADSO)
message(WARNING "You must have SDL_LoadObject() support for dynamic libthai loading")
endif()
FindLibraryAndSONAME("thai" LIBDIRS ${PC_LIBTHAI_LIBRARY_DIRS})
if(SDL_LIBTHAI_SHARED AND THAI_LIB AND HAVE_SDL_LOADSO)
set(SDL_LIBTHAI_DYNAMIC "\"${THAI_LIB_SONAME}\"")
set(HAVE_LIBTHAI_SHARED TRUE)
sdl_include_directories(PRIVATE SYSTEM $<TARGET_PROPERTY:PkgConfig::PC_LIBTHAI,INTERFACE_INCLUDE_DIRECTORIES>)
else()
sdl_link_dependency(libthai LIBS PkgConfig::PC_LIBTHAI PKG_CONFIG_PREFIX PC_LIBTHAI PKG_CONFIG_SPECS ${LIBTHAI_PKG_CONFIG_SPEC})
endif()
endif()
endif()
endmacro()
macro(WaylandProtocolGen _SCANNER _CODE_MODE _XML _PROTL)
set(_WAYLAND_PROT_C_CODE "${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols/${_PROTL}-protocol.c")
set(_WAYLAND_PROT_H_CODE "${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols/${_PROTL}-client-protocol.h")

View File

@@ -218,6 +218,8 @@
#cmakedefine HAVE_LIBURING_H 1
#cmakedefine HAVE_FRIBIDI_H 1
#cmakedefine SDL_FRIBIDI_DYNAMIC @SDL_FRIBIDI_DYNAMIC@
#cmakedefine HAVE_LIBTHAI_H 1
#cmakedefine SDL_LIBTHAI_DYNAMIC @SDL_LIBTHAI_DYNAMIC@
#cmakedefine HAVE_DDRAW_H 1
#cmakedefine HAVE_DSOUND_H 1

View File

@@ -0,0 +1,76 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef HAVE_LIBTHAI_H
#include "SDL_libthai.h"
#ifdef SDL_LIBTHAI_DYNAMIC
SDL_ELF_NOTE_DLOPEN(
"Thai",
"Thai language support",
SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
SDL_LIBTHAI_DYNAMIC
);
#endif
SDL_LibThai *SDL_LibThai_Create(void)
{
SDL_LibThai *th;
th = (SDL_LibThai *)SDL_malloc(sizeof(SDL_LibThai));
if (!th) {
return NULL;
}
#ifdef SDL_LIBTHAI_DYNAMIC
#define SDL_LIBTHAI_LOAD_SYM(a, x, n, t) x = ((t)SDL_LoadFunction(a->lib, n)); if (!x) { SDL_UnloadObject(a->lib); SDL_free(a); return NULL; }
th->lib = SDL_LoadObject(SDL_LIBTHAI_DYNAMIC);
if (!th->lib) {
SDL_free(th);
return NULL;
}
SDL_LIBTHAI_LOAD_SYM(th, th->make_cells, "th_make_cells", SDL_LibThaiMakeCells);
#else
th->make_cells = th_make_cells;
#endif
return th;
}
void SDL_LibThai_Destroy(SDL_LibThai *th)
{
if (!th) {
return;
}
#ifdef SDL_LIBTHAI_DYNAMIC
SDL_UnloadObject(th->lib);
#endif
SDL_free(th);
}
#endif

View File

@@ -0,0 +1,43 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_libthai_h_
#define SDL_libthai_h_
#ifdef HAVE_LIBTHAI_H
#include <thai/thcell.h>
typedef size_t (*SDL_LibThaiMakeCells)(const thchar_t *s, size_t, struct thcell_t cells[], size_t *, int);
typedef struct SDL_LibThai {
SDL_SharedObject *lib;
SDL_LibThaiMakeCells make_cells;
} SDL_LibThai;
extern SDL_LibThai *SDL_LibThai_Create(void);
extern void SDL_LibThai_Destroy(SDL_LibThai *th);
#endif // HAVE_LIBTHAI_H
#endif // SDL_libthai_h_

View File

@@ -28,7 +28,7 @@
#include "SDL_x11toolkit.h"
#ifndef SDL_FORK_MESSAGEBOX
#define SDL_FORK_MESSAGEBOX 1
#define SDL_FORK_MESSAGEBOX 0
#endif
#if SDL_FORK_MESSAGEBOX
@@ -38,246 +38,181 @@
#include <errno.h>
#endif
typedef struct SDL_MessageBoxCallbackDataX11
{
int *buttonID;
SDL_ToolkitWindowX11 *window;
} SDL_MessageBoxCallbackDataX11;
typedef struct SDL_MessageBoxControlsX11
typedef struct SDL_MessageBoxX11
{
SDL_ToolkitWindowX11 *window;
SDL_ToolkitControlX11 *icon;
SDL_ToolkitControlX11 fake_icon;
SDL_ToolkitControlX11 *message;
SDL_ToolkitControlX11 **buttons;
const SDL_MessageBoxData *messageboxdata;
} SDL_MessageBoxControlsX11;
int *buttonID;
} SDL_MessageBoxX11;
static void X11_MessageBoxButtonCallback(SDL_ToolkitControlX11 *control, void *data)
{
SDL_MessageBoxCallbackDataX11 *cbdata;
SDL_MessageBoxX11 *cbdata;
cbdata = (SDL_MessageBoxCallbackDataX11 *)data;
cbdata = data;
*cbdata->buttonID = X11Toolkit_GetButtonControlData(control)->buttonID;
X11Toolkit_SignalWindowClose(cbdata->window);
}
static void X11_PositionMessageBox(SDL_MessageBoxControlsX11 *controls, int *wp, int *hp) {
int max_button_w;
int max_button_h;
int total_button_w;
int total_text_and_icon_w;
int w;
int h;
static void X11_PositionMessageBox(SDL_MessageBoxX11 *controls, int *wp, int *hp) {
int first_line_width;
int first_line_height;
int second_line_width;
int second_line_height;
int max_button_width;
int max_button_height;
int window_width;
int window_height;
int i;
int t;
/* Init vars */
max_button_w = 50;
max_button_h = 0;
w = h = 2;
i = t = total_button_w = total_text_and_icon_w = 0;
max_button_w *= controls->window->iscale;
/* Positioning and sizing */
for (i = 0; i < controls->messageboxdata->numbuttons; i++) {
max_button_w = SDL_max(max_button_w, controls->buttons[i]->rect.w);
max_button_h = SDL_max(max_button_h, controls->buttons[i]->rect.h);
controls->buttons[i]->rect.x = 0;
}
if (controls->icon) {
controls->icon->rect.x = controls->icon->rect.y = 0;
}
if (controls->icon) {
controls->message->rect.x = (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale) + controls->icon->rect.x + controls->icon->rect.w;
controls->message->rect.y = X11Toolkit_GetIconControlCharY(controls->icon);
} else {
controls->message->rect.x = 0;
controls->message->rect.y = -2 * controls->window->iscale;
controls->icon = &controls->fake_icon;
controls->icon->rect.w = 0;
controls->icon->rect.h = 0;
controls->icon->rect.x = 0;
controls->icon->rect.y = 0;
}
bool rtl;
/* window size */
window_width = 1;
window_height = 1;
/* rtl */
if (controls->messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) {
for (i = controls->messageboxdata->numbuttons; i != -1; i--) {
controls->buttons[i]->rect.w = max_button_w;
controls->buttons[i]->rect.h = max_button_h;
rtl = true;
} else if (controls->messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_LEFT_TO_RIGHT) {
rtl = false;
} else {
rtl = controls->window->flip_interface;
}
/* first line */
first_line_width = first_line_height = 0;
if (controls->icon && controls->message) {
controls->icon->rect.y = 0;
first_line_width = controls->icon->rect.w + SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale + controls->message->rect.w;
if (!controls->window->flip_interface) {
controls->message->rect.x = controls->icon->rect.w + SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale;
controls->icon->rect.x = 0;
} else {
controls->message->rect.x = 0;
controls->icon->rect.x = controls->message->rect.w + SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale;;
}
if (controls->message->rect.h > controls->icon->rect.h) {
controls->message->rect.y = (controls->icon->rect.h - X11Toolkit_GetLabelControlFirstLineHeight(controls->message))/2;
first_line_height = controls->message->rect.y + controls->message->rect.h;
} else {
controls->message->rect.y = (controls->icon->rect.h - controls->message->rect.h)/2;
first_line_height = controls->icon->rect.h;
}
} else if (!controls->icon && controls->message) {
first_line_width = controls->message->rect.w;
first_line_height = controls->message->rect.h;
controls->message->rect.x = 0;
controls->message->rect.y = 0;
} else if (controls->icon && !controls->message) {
first_line_width = controls->icon->rect.w;
first_line_height = controls->icon->rect.h;
controls->icon->rect.x = 0;
controls->icon->rect.y = 0;
}
/* second line */
max_button_width = 50;
max_button_height = 0;
second_line_width = second_line_height = 0;
for (i = 0; i < controls->messageboxdata->numbuttons; i++) {
max_button_width = SDL_max(max_button_width, controls->buttons[i]->rect.w);
max_button_height = SDL_max(max_button_height, controls->buttons[i]->rect.h);
controls->buttons[i]->rect.x = 0;
controls->buttons[i]->rect.y = 0;
}
if (rtl) {
for (i = (controls->messageboxdata->numbuttons - 1); i != -1; i--) {
controls->buttons[i]->rect.w = max_button_width;
controls->buttons[i]->rect.h = max_button_height;
X11Toolkit_NotifyControlOfSizeChange(controls->buttons[i]);
if (controls->icon->rect.h > controls->message->rect.h) {
controls->buttons[i]->rect.y = controls->icon->rect.h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 *controls-> window->iscale);
if (first_line_height) {
controls->buttons[i]->rect.y = first_line_height + SDL_TOOLKIT_X11_ELEMENT_PADDING_4 * controls->window->iscale;
second_line_height = max_button_height + SDL_TOOLKIT_X11_ELEMENT_PADDING_4 * controls->window->iscale;
} else {
controls->buttons[i]->rect.y = controls->message->rect.h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
second_line_height = max_button_height;
}
if (i) {
controls->buttons[i]->rect.x = controls->buttons[i-1]->rect.x + controls->buttons[i-1]->rect.w + (SDL_TOOLKIT_X11_ELEMENT_PADDING_3 * controls->window->iscale);
if ((i + 1) < controls->messageboxdata->numbuttons) {
controls->buttons[i]->rect.x = controls->buttons[i + 1]->rect.x + controls->buttons[i + 1]->rect.w + (SDL_TOOLKIT_X11_ELEMENT_PADDING_3 * controls->window->iscale);
}
}
}
} else {
for (i = 0; i < controls->messageboxdata->numbuttons; i++) {
controls->buttons[i]->rect.w = max_button_w;
controls->buttons[i]->rect.h = max_button_h;
controls->buttons[i]->rect.w = max_button_width;
controls->buttons[i]->rect.h = max_button_height;
X11Toolkit_NotifyControlOfSizeChange(controls->buttons[i]);
if (controls->icon->rect.h > controls->message->rect.h) {
controls->buttons[i]->rect.y = controls->icon->rect.h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
if (first_line_height) {
controls->buttons[i]->rect.y = first_line_height + SDL_TOOLKIT_X11_ELEMENT_PADDING_4 * controls->window->iscale;
second_line_height = max_button_height + SDL_TOOLKIT_X11_ELEMENT_PADDING_4 * controls->window->iscale;
} else {
controls->buttons[i]->rect.y = controls->message->rect.h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
second_line_height = max_button_height;
}
if (i) {
controls->buttons[i]->rect.x = controls->buttons[i-1]->rect.x + controls->buttons[i-1]->rect.w + (SDL_TOOLKIT_X11_ELEMENT_PADDING_3 * controls->window->iscale);
}
}
}
total_button_w = controls->buttons[controls->messageboxdata->numbuttons-1]->rect.x + controls->buttons[controls->messageboxdata->numbuttons-1]->rect.w;
total_text_and_icon_w = controls->message->rect.x + controls->message->rect.w;
if (total_button_w > total_text_and_icon_w) {
w = total_button_w;
} else {
w = total_text_and_icon_w;
}
w += (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale) * 2;
if (controls->message->rect.h > controls->icon->rect.h) {
h = controls->message->rect.h;
} else {
h = controls->icon->rect.h;
}
h += max_button_h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale) * 3;
t = (w - total_text_and_icon_w) / 2;
controls->icon->rect.x += t;
controls->message->rect.x += t;
controls->icon->rect.y += (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
controls->message->rect.y += (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
t = (w - total_button_w) / 2;
for (i = 0; i < controls->messageboxdata->numbuttons; i++) {
controls->buttons[i]->rect.x += t;
controls->buttons[i]->rect.y += (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
}
if (!controls->messageboxdata->message) {
controls->icon->rect.x = (w - controls->icon->rect.w)/2;
if (controls->messageboxdata->numbuttons) {
if (rtl) {
second_line_width = controls->buttons[0]->rect.x + controls->buttons[0]->rect.w;
} else {
second_line_width = controls->buttons[controls->messageboxdata->numbuttons - 1]->rect.x + controls->buttons[controls->messageboxdata->numbuttons - 1]->rect.w;
}
}
*wp = w;
*hp = h;
}
static void X11_PositionMessageBoxFlipped(SDL_MessageBoxControlsX11 *controls, int *wp, int *hp)
{
int max_button_w;
int max_button_h;
int total_button_w;
int total_text_and_icon_w;
int w;
int h;
int i;
int t;
/* Init vars */
max_button_w = 50;
max_button_h = 0;
w = h = 2;
i = t = total_button_w = total_text_and_icon_w = 0;
max_button_w *= controls->window->iscale;
/* Positioning and sizing */
for (i = 0; i < controls->messageboxdata->numbuttons; i++) {
max_button_w = SDL_max(max_button_w, controls->buttons[i]->rect.w);
max_button_h = SDL_max(max_button_h, controls->buttons[i]->rect.h);
controls->buttons[i]->rect.x = 0;
}
if (controls->icon) {
controls->icon->rect.y = 0;
}
if (controls->icon) {
controls->message->rect.x = 0;
controls->message->rect.y = X11Toolkit_GetIconControlCharY(controls->icon);
controls->icon->rect.x = (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale) + controls->message->rect.w + controls->message->rect.x;
} else {
controls->message->rect.x = 0;
controls->message->rect.y = -2 * controls->window->iscale;
controls->icon = &controls->fake_icon;
controls->icon->rect.w = 0;
controls->icon->rect.h = 0;
controls->icon->rect.x = 0;
controls->icon->rect.y = 0;
}
if (controls->messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) {
for (i = controls->messageboxdata->numbuttons; i != -1; i--) {
controls->buttons[i]->rect.w = max_button_w;
controls->buttons[i]->rect.h = max_button_h;
X11Toolkit_NotifyControlOfSizeChange(controls->buttons[i]);
if (controls->icon->rect.h > controls->message->rect.h) {
controls->buttons[i]->rect.y = controls->icon->rect.h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 *controls-> window->iscale);
} else {
controls->buttons[i]->rect.y = controls->message->rect.h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
}
if (i) {
controls->buttons[i]->rect.x = controls->buttons[i-1]->rect.x + controls->buttons[i-1]->rect.w + (SDL_TOOLKIT_X11_ELEMENT_PADDING_3 * controls->window->iscale);
}
/* center lines */
if (second_line_width > first_line_width) {
int pad;
pad = (second_line_width - first_line_width)/2;
if (controls->message) {
controls->message->rect.x += pad;
}
if (controls->icon) {
controls->icon->rect.x += pad;
}
} else {
int pad;
pad = (first_line_width - second_line_width)/2;
for (i = 0; i < controls->messageboxdata->numbuttons; i++) {
controls->buttons[i]->rect.w = max_button_w;
controls->buttons[i]->rect.h = max_button_h;
X11Toolkit_NotifyControlOfSizeChange(controls->buttons[i]);
if (controls->icon->rect.h > controls->message->rect.h) {
controls->buttons[i]->rect.y = controls->icon->rect.h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
} else {
controls->buttons[i]->rect.y = controls->message->rect.h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
}
if (i) {
controls->buttons[i]->rect.x = controls->buttons[i-1]->rect.x + controls->buttons[i-1]->rect.w + (SDL_TOOLKIT_X11_ELEMENT_PADDING_3 * controls->window->iscale);
}
controls->buttons[i]->rect.x += pad;
}
}
total_button_w = controls->buttons[controls->messageboxdata->numbuttons-1]->rect.x + controls->buttons[controls->messageboxdata->numbuttons-1]->rect.w;
total_text_and_icon_w = controls->message->rect.w + controls->icon->rect.w + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
if (total_button_w > total_text_and_icon_w) {
w = total_button_w;
} else {
w = total_text_and_icon_w;
/* window size and final padding */
window_width = SDL_max(first_line_width, second_line_width) + SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * 2 * controls->window->iscale;
window_height = first_line_height + second_line_height + SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * 2 * controls->window->iscale;
*wp = window_width;
*hp = window_height;
if (controls->message) {
controls->message->rect.x += SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale;
controls->message->rect.y += SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale;
}
w += (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale) * 2;
if (controls->message->rect.h > controls->icon->rect.h) {
h = controls->message->rect.h;
} else {
h = controls->icon->rect.h;
if (controls->icon) {
controls->icon->rect.x += SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale;
controls->icon->rect.y += SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale;
}
h += max_button_h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale) * 3;
t = (w - total_text_and_icon_w) / 2;
controls->icon->rect.x += t;
controls->message->rect.x += t;
controls->icon->rect.y += (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
controls->message->rect.y += (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
t = (w - total_button_w) / 2;
for (i = 0; i < controls->messageboxdata->numbuttons; i++) {
controls->buttons[i]->rect.x += t;
controls->buttons[i]->rect.y += (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
controls->buttons[i]->rect.x += SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale;
controls->buttons[i]->rect.y += SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale;
}
if (!controls->messageboxdata->message) {
controls->icon->rect.x = (w - controls->icon->rect.w)/2;
}
*wp = w;
*hp = h;
}
static void X11_OnMessageBoxScaleChange(SDL_ToolkitWindowX11 *window, void *data) {
SDL_MessageBoxControlsX11 *controls;
SDL_MessageBoxX11 *controls;
int w;
int h;
@@ -290,8 +225,7 @@ static bool X11_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int
{
SDL_VideoDevice *video = SDL_GetVideoDevice();
SDL_Window *parent_window = NULL;
SDL_MessageBoxControlsX11 controls;
SDL_MessageBoxCallbackDataX11 data;
SDL_MessageBoxX11 controls;
const SDL_MessageBoxColor *colorhints;
int i;
int w;
@@ -323,22 +257,17 @@ static bool X11_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int
}
/* Create controls */
controls.buttonID = buttonID;
controls.buttons = SDL_calloc(messageboxdata->numbuttons, sizeof(SDL_ToolkitControlX11 *));
controls.icon = X11Toolkit_CreateIconControl(controls.window, messageboxdata->flags);
controls.message = X11Toolkit_CreateLabelControl(controls.window, (char *)messageboxdata->message);
data.buttonID = buttonID;
data.window = controls.window;
for (i = 0; i < messageboxdata->numbuttons; i++) {
controls.buttons[i] = X11Toolkit_CreateButtonControl(controls.window, &messageboxdata->buttons[i]);
X11Toolkit_RegisterCallbackForButtonControl(controls.buttons[i], &data, X11_MessageBoxButtonCallback);
X11Toolkit_RegisterCallbackForButtonControl(controls.buttons[i], &controls, X11_MessageBoxButtonCallback);
}
/* Positioning */
if (data.window->flip_interface) {
X11_PositionMessageBoxFlipped(&controls, &w, &h);
} else {
X11_PositionMessageBox(&controls, &w, &h);
}
X11_PositionMessageBox(&controls, &w, &h);
/* Actually create window, do event loop, cleanup */
X11Toolkit_CreateWindowRes(controls.window, w, h, 0, 0, (char *)messageboxdata->title);

View File

@@ -56,6 +56,7 @@ SDL_X11_SYM(int,XDeleteProperty,(Display* a,Window b,Atom c))
SDL_X11_SYM(int,XDestroyWindow,(Display* a,Window b))
SDL_X11_SYM(int,XDisplayKeycodes,(Display* a,int* b,int* c))
SDL_X11_SYM(int,XDrawRectangle,(Display* a,Drawable b,GC c,int d,int e,unsigned int f,unsigned int g))
SDL_X11_SYM(int,XFontsOfFontSet,(XFontSet a,XFontStruct ***b,char ***c))
SDL_X11_SYM(int,XFillArc,(Display* a,Drawable b,GC c,int d,int e,unsigned int f,unsigned int g, int h, int i))
SDL_X11_SYM(char*,XDisplayName,(_Xconst char* a))
SDL_X11_SYM(int,XDrawString,(Display* a,Drawable b,GC c,int d,int e,_Xconst char* f,int g))

File diff suppressed because it is too large Load Diff

View File

@@ -32,6 +32,9 @@
#ifdef HAVE_FRIBIDI_H
#include "../../core/unix/SDL_fribidi.h"
#endif
#ifdef HAVE_LIBTHAI_H
#include "../../core/unix/SDL_libthai.h"
#endif
#ifdef SDL_VIDEO_DRIVER_X11
@@ -50,6 +53,22 @@ typedef enum SDL_ToolkitChildModeX11
SDL_TOOLKIT_WINDOW_MODE_X11_TOOLTIP
} SDL_ToolkitWindowModeX11;
typedef enum SDL_ToolkitThaiEncodingX11
{
SDL_TOOLKIT_THAI_ENCODING_X11_NONE,
SDL_TOOLKIT_THAI_ENCODING_X11_TIS, /* -0 */
SDL_TOOLKIT_THAI_ENCODING_X11_TIS_WIN, /* -2 */
SDL_TOOLKIT_THAI_ENCODING_X11_TIS_MAC, /* -1 */
SDL_TOOLKIT_THAI_ENCODING_X11_8859,
SDL_TOOLKIT_THAI_ENCODING_X11_UNICODE
} SDL_ToolkitThaiEncodingX11;
typedef enum SDL_ToolkitThaiFontX11
{
SDL_TOOLKIT_THAI_FONT_X11_OFFSET,
SDL_TOOLKIT_THAI_FONT_X11_CELL
} SDL_ToolkitThaiFontX11;
typedef struct SDL_ToolkitWindowX11
{
/* Locale */
@@ -119,7 +138,9 @@ typedef struct SDL_ToolkitWindowX11
/* Font */
XFontSet font_set; // for UTF-8 systems
XFontStruct *font_struct; // Latin1 (ASCII) fallback.
SDL_ToolkitThaiEncodingX11 thai_encoding;
SDL_ToolkitThaiFontX11 thai_font;
/* Control colors */
const SDL_MessageBoxColor *color_hints;
XColor xcolor[SDL_MESSAGEBOX_COLOR_COUNT];
@@ -164,6 +185,10 @@ typedef struct SDL_ToolkitWindowX11
bool do_shaping;
#endif
#ifdef HAVE_LIBTHAI_H
SDL_LibThai *th;
#endif
bool flip_interface;
} SDL_ToolkitWindowX11;
@@ -231,10 +256,10 @@ extern bool X11Toolkit_NotifyControlOfSizeChange(SDL_ToolkitControlX11 *control)
/* ICON CONTROL FUNCTIONS */
extern SDL_ToolkitControlX11 *X11Toolkit_CreateIconControl(SDL_ToolkitWindowX11 *window, SDL_MessageBoxFlags flags);
extern int X11Toolkit_GetIconControlCharY(SDL_ToolkitControlX11 *control);
/* LABEL CONTROL FUNCTIONS */
extern SDL_ToolkitControlX11 *X11Toolkit_CreateLabelControl(SDL_ToolkitWindowX11 *window, char *utf8);
extern int X11Toolkit_GetLabelControlFirstLineHeight(SDL_ToolkitControlX11 *control);
/* BUTTON CONTROL FUNCTIONS */
extern SDL_ToolkitControlX11 *X11Toolkit_CreateButtonControl(SDL_ToolkitWindowX11 *window, const SDL_MessageBoxButtonData *data);

View File

@@ -164,6 +164,11 @@ int main(int argc, char *argv[])
quit(1);
}
success = SDL_ShowSimpleMessageBox(0,
"No icon",
"This is a MessageBox with no icon!",
NULL);
/* Google says this is Traditional Chinese for "beef with broccoli" */
success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
"UTF-8 Simple MessageBox",