Skip to content

Commit 27b74d3

Browse files
flibitijibiboicculus
authored andcommitted
Implement Wayland_ShowMessageBox using Zenity
1 parent 5262b52 commit 27b74d3

File tree

3 files changed

+203
-1
lines changed

3 files changed

+203
-1
lines changed

src/video/SDL_video.c

+11-1
Original file line numberDiff line numberDiff line change
@@ -4042,6 +4042,9 @@ SDL_IsScreenKeyboardShown(SDL_Window *window)
40424042
#if SDL_VIDEO_DRIVER_X11
40434043
#include "x11/SDL_x11messagebox.h"
40444044
#endif
4045+
#if SDL_VIDEO_DRIVER_WAYLAND
4046+
#include "wayland/SDL_waylandmessagebox.h"
4047+
#endif
40454048
#if SDL_VIDEO_DRIVER_HAIKU
40464049
#include "haiku/SDL_bmessagebox.h"
40474050
#endif
@@ -4052,7 +4055,7 @@ SDL_IsScreenKeyboardShown(SDL_Window *window)
40524055
#include "vita/SDL_vitamessagebox.h"
40534056
#endif
40544057

4055-
#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_HAIKU || SDL_VIDEO_DRIVER_OS2
4058+
#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_HAIKU || SDL_VIDEO_DRIVER_OS2
40564059
static SDL_bool SDL_MessageboxValidForDriver(const SDL_MessageBoxData *messageboxdata, SDL_SYSWM_TYPE drivertype)
40574060
{
40584061
SDL_SysWMinfo info;
@@ -4151,6 +4154,13 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
41514154
retval = 0;
41524155
}
41534156
#endif
4157+
#if SDL_VIDEO_DRIVER_WAYLAND
4158+
if (retval == -1 &&
4159+
SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WAYLAND) &&
4160+
Wayland_ShowMessageBox(messageboxdata, buttonid) == 0) {
4161+
retval = 0;
4162+
}
4163+
#endif
41544164
#if SDL_VIDEO_DRIVER_HAIKU
41554165
if (retval == -1 &&
41564166
SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_HAIKU) &&
+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/*
2+
Simple DirectMedia Layer
3+
Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
4+
5+
This software is provided 'as-is', without any express or implied
6+
warranty. In no event will the authors be held liable for any damages
7+
arising from the use of this software.
8+
9+
Permission is granted to anyone to use this software for any purpose,
10+
including commercial applications, and to alter it and redistribute it
11+
freely, subject to the following restrictions:
12+
13+
1. The origin of this software must not be misrepresented; you must not
14+
claim that you wrote the original software. If you use this software
15+
in a product, an acknowledgment in the product documentation would be
16+
appreciated but is not required.
17+
2. Altered source versions must be plainly marked as such, and must not be
18+
misrepresented as being the original software.
19+
3. This notice may not be removed or altered from any source distribution.
20+
*/
21+
22+
#include "../../SDL_internal.h"
23+
24+
#if SDL_VIDEO_DRIVER_WAYLAND
25+
26+
#include "SDL.h"
27+
#include <stdlib.h> /* popen/pclose/fgets */
28+
29+
int
30+
Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
31+
{
32+
#define ZENITY_CONST(name, str) \
33+
const char *name = str; \
34+
const size_t name##_len = SDL_strlen(name);
35+
ZENITY_CONST(zenity, "zenity --question --switch --icon-name=dialog-")
36+
ZENITY_CONST(title, "--title=")
37+
ZENITY_CONST(message, "--text=")
38+
ZENITY_CONST(extrabutton, "--extra-button=")
39+
ZENITY_CONST(icon_info, "information")
40+
ZENITY_CONST(icon_warn, "warning")
41+
ZENITY_CONST(icon_error, "error")
42+
#undef ZENITY_CONST
43+
44+
char *command, *output;
45+
size_t command_len, output_len;
46+
const char *icon;
47+
char *tmp;
48+
FILE *process;
49+
int i;
50+
51+
/* Start by calculating the lengths of the strings. These commands can get
52+
* pretty long, so we need to dynamically allocate this.
53+
*/
54+
command_len = zenity_len;
55+
output_len = 0;
56+
switch (messageboxdata->flags)
57+
{
58+
case SDL_MESSAGEBOX_ERROR:
59+
icon = icon_error;
60+
command_len += icon_error_len;
61+
break;
62+
case SDL_MESSAGEBOX_WARNING:
63+
icon = icon_warn;
64+
command_len += icon_warn_len;
65+
break;
66+
case SDL_MESSAGEBOX_INFORMATION:
67+
default:
68+
icon = icon_info;
69+
command_len += icon_info_len;
70+
break;
71+
}
72+
#define ADD_ARGUMENT(arg, value) \
73+
command_len += arg + 3; /* Two " and a space */ \
74+
if (messageboxdata->value != NULL) { \
75+
command_len += SDL_strlen(messageboxdata->value); \
76+
}
77+
ADD_ARGUMENT(title_len, title)
78+
ADD_ARGUMENT(message_len, message)
79+
for (i = 0; i < messageboxdata->numbuttons; i += 1) {
80+
ADD_ARGUMENT(extrabutton_len, buttons[i].text)
81+
}
82+
#undef ADD_ARGUMENT
83+
84+
/* Don't forget null terminators! */
85+
command_len += 1;
86+
output_len += 1;
87+
88+
/* Now that we know the length of the command, allocate! */
89+
command = (char*) SDL_malloc(command_len + output_len);
90+
if (command == NULL) {
91+
return SDL_OutOfMemory();
92+
}
93+
output = command + command_len;
94+
command[0] = '\0';
95+
output[0] = '\0';
96+
97+
/* Now we can build the command... */
98+
SDL_strlcpy(command, zenity, command_len);
99+
SDL_strlcat(command, icon, command_len);
100+
#define ADD_ARGUMENT(arg, value) \
101+
SDL_strlcat(command, " ", command_len); \
102+
SDL_strlcat(command, arg, command_len); \
103+
SDL_strlcat(command, "\"", command_len); \
104+
if (value != NULL) { \
105+
SDL_strlcat(command, value, command_len); \
106+
} \
107+
SDL_strlcat(command, "\"", command_len)
108+
ADD_ARGUMENT(title, messageboxdata->title);
109+
ADD_ARGUMENT(message, messageboxdata->message);
110+
for (i = 0; i < messageboxdata->numbuttons; i += 1) {
111+
ADD_ARGUMENT(extrabutton, messageboxdata->buttons[i].text);
112+
}
113+
#undef ADD_ARGUMENT
114+
115+
/* ... then run it, finally. */
116+
process = popen(command, "r");
117+
if (process == NULL) {
118+
SDL_free(command);
119+
return SDL_SetError("zenity failed to run");
120+
}
121+
122+
/* At this point, if no button ID is needed, we can just bail as soon as the
123+
* process has completed.
124+
*/
125+
if (buttonid == NULL) {
126+
pclose(process);
127+
goto end;
128+
}
129+
*buttonid = -1;
130+
131+
/* Read the result from stdout */
132+
tmp = fgets(output, output_len, process);
133+
pclose(process);
134+
if ((tmp == NULL) || (*tmp == '\0') || (*tmp == '\n')) {
135+
goto end; /* User simply closed the dialog */
136+
}
137+
138+
/* It likes to add a newline... */
139+
tmp = SDL_strrchr(output, '\n');
140+
if (tmp != NULL) {
141+
*tmp = '\0';
142+
}
143+
144+
/* Check which button got pressed */
145+
for (i = 0; i < messageboxdata->numbuttons; i += 1) {
146+
if (SDL_strcmp(output, messageboxdata->buttons[i].text) == 0) {
147+
*buttonid = i;
148+
break;
149+
}
150+
}
151+
152+
end:
153+
SDL_free(command);
154+
return 0;
155+
}
156+
157+
#endif /* SDL_VIDEO_DRIVER_WAYLAND */
158+
159+
/* vi: set ts=4 sw=4 expandtab: */
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
Simple DirectMedia Layer
3+
Copyright (C) 1997-2021 Sam Lantinga <[email protected]>
4+
5+
This software is provided 'as-is', without any express or implied
6+
warranty. In no event will the authors be held liable for any damages
7+
arising from the use of this software.
8+
9+
Permission is granted to anyone to use this software for any purpose,
10+
including commercial applications, and to alter it and redistribute it
11+
freely, subject to the following restrictions:
12+
13+
1. The origin of this software must not be misrepresented; you must not
14+
claim that you wrote the original software. If you use this software
15+
in a product, an acknowledgment in the product documentation would be
16+
appreciated but is not required.
17+
2. Altered source versions must be plainly marked as such, and must not be
18+
misrepresented as being the original software.
19+
3. This notice may not be removed or altered from any source distribution.
20+
*/
21+
22+
#ifndef SDL_waylandmessagebox_h_
23+
#define SDL_waylandmessagebox_h_
24+
25+
#if SDL_VIDEO_DRIVER_WAYLAND
26+
27+
extern int Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
28+
29+
#endif /* SDL_VIDEO_DRIVER_WAYLAND */
30+
31+
#endif /* SDL_waylandmessagebox_h_ */
32+
33+
/* vi: set ts=4 sw=4 expandtab: */

0 commit comments

Comments
 (0)