Phase 80d: clean X11 from appmenu, main, switchpanel, window, xutil, texture

New vtable slots: appmenu_send, display_get_name, switchpanel_send_enter,
format_x_error, draw_bevel.

- appmenu.c: sendMessage dispatches through appmenu_send
- main.c: XDisplayName replaced with display_get_name
- switchpanel.c: XSendEvent replaced with switchpanel_send_enter
- window.c: XFree removed (backend owns cmap_windows lifecycle)
- xutil.c: FormatXError moved entirely to x11_backend.c
- texture.c: wDrawBevel dispatches through draw_bevel (done prev commit)

All 5 files verified X11-free with nm.
This commit is contained in:
Levi Neely 2026-05-13 10:42:06 +02:00
parent b8899b4cb8
commit b72d527ee7
8 changed files with 94 additions and 186 deletions

View File

@ -53,19 +53,7 @@ enum {
static void sendMessage(Window window, int what, int tag)
{
XEvent event;
event.xclient.type = ClientMessage;
event.xclient.message_type = w_global.atom.wmaker.menu;
event.xclient.format = 32;
event.xclient.display = dpy;
event.xclient.window = window;
event.xclient.data.l[0] = w_global.timestamp.last_event;
event.xclient.data.l[1] = what;
event.xclient.data.l[2] = tag;
event.xclient.data.l[3] = 0;
XSendEvent(dpy, window, False, NoEventMask, &event);
wm_backend->event_flush();
wm_backend->appmenu_send((WNativeWindow)window, what, tag);
}
static void notifyClient(WMenu * menu, WMenuEntry * entry)

View File

@ -1683,6 +1683,15 @@ typedef struct WMBackend {
void (*draw_bevel)(WNativeWindow d, unsigned int width, unsigned int height,
WTexSolid *texture, int relief);
/* ------------------------------------------------------------------ */
/* Misc mechanism (Phase 80d) */
/* ------------------------------------------------------------------ */
void (*appmenu_send)(WNativeWindow window, int what, int tag);
const char *(*display_get_name)(const char *name);
void (*switchpanel_send_enter)(WNativeWindow info_win, WNativeWindow window);
void (*format_x_error)(void *error, char *buf, int size);
} WMBackend;
/*

View File

@ -6184,6 +6184,18 @@ static void wl_noop_draw_bevel(WNativeWindow d, unsigned int width, unsigned int
WTexSolid *texture, int relief)
{ (void)d; (void)width; (void)height; (void)texture; (void)relief; }
static void wl_noop_appmenu_send(WNativeWindow window, int what, int tag)
{ (void)window; (void)what; (void)tag; }
static const char *wl_display_get_name(const char *name)
{ (void)name; return "wayland-0"; }
static void wl_noop_switchpanel_send_enter(WNativeWindow info_win, WNativeWindow window)
{ (void)info_win; (void)window; }
static void wl_noop_format_x_error(void *error, char *buf, int size)
{ (void)error; if (size > 0) buf[0] = '\0'; }
/* ------------------------------------------------------------------ */
/* vtable */
/* ------------------------------------------------------------------ */
@ -6394,4 +6406,8 @@ const WMBackend wl_backend = {
.menu_paint_entry = wl_noop_menu_paint_entry,
.menu_draw_frame = wl_noop_menu_draw_frame,
.draw_bevel = wl_noop_draw_bevel,
.appmenu_send = wl_noop_appmenu_send,
.display_get_name = wl_display_get_name,
.switchpanel_send_enter = wl_noop_switchpanel_send_enter,
.format_x_error = wl_noop_format_x_error,
};

View File

@ -42,7 +42,6 @@
#include "../../framewin.h" /* WFrameWindow -- needed by WWindow */
#include "../../window.h" /* WWindow -- for window_shape_clear/set */
#include "../../GNUstep.h" /* GNUstepWMAttributes */
#include "../../xutil.h" /* FormatXError */
#include "../../main.h" /* Exit() */
#include "../../startup.h" /* wHackedGrabKey, wHackedGrabButton */
#include "../../def_pixmaps.h"
@ -2407,7 +2406,15 @@ x11_catch_error(Display *edpy, XErrorEvent *error)
|| (error->request_code == X_InstallColormap))) {
return 0;
}
FormatXError(edpy, error, buffer, MAXLINE);
XGetErrorText(edpy, error->error_code, buffer, MAXLINE);
{
int i = strlen(buffer);
if (i < MAXLINE - 100)
snprintf(buffer + i, MAXLINE - i,
"\n\tRequest code: %i\n\tMinor code: %i\n\tResource ID: 0x%x\n\tSerial: %li\n",
error->request_code, error->minor_code,
(unsigned int)error->resourceid, error->serial);
}
wwarning(_("internal X error: %s"), buffer);
return -1;
}
@ -2994,6 +3001,51 @@ static void x11_draw_bevel(WNativeWindow d, unsigned int width, unsigned int hei
}
}
static void x11_appmenu_send(WNativeWindow window, int what, int tag)
{
XEvent event;
event.xclient.type = ClientMessage;
event.xclient.message_type = w_global.atom.wmaker.menu;
event.xclient.format = 32;
event.xclient.display = dpy;
event.xclient.window = (Window)window;
event.xclient.data.l[0] = w_global.timestamp.last_event;
event.xclient.data.l[1] = what;
event.xclient.data.l[2] = tag;
event.xclient.data.l[3] = 0;
XSendEvent(dpy, (Window)window, False, NoEventMask, &event);
XFlush(dpy);
}
static const char *x11_display_get_name(const char *name)
{
return XDisplayName(name);
}
static void x11_switchpanel_send_enter(WNativeWindow info_win, WNativeWindow window)
{
XEvent ev;
memset(&ev, 0, sizeof(ev));
ev.xclient.type = ClientMessage;
ev.xclient.message_type = w_global.atom.wm.ignore_focus_events;
ev.xclient.format = 32;
ev.xclient.data.l[0] = True;
XSendEvent(dpy, (Window)info_win, True, EnterWindowMask, &ev);
(void)window;
}
static void x11_format_x_error(void *error, char *buf, int size)
{
XErrorEvent *err = (XErrorEvent *)error;
XGetErrorText(dpy, err->error_code, buf, size);
int i = strlen(buf);
if (i < size - 100)
snprintf(buf + i, size - i,
"\n\tRequest code: %i\n\tMinor code: %i\n\tResource ID: 0x%x\n\tSerial: %li\n",
err->request_code, err->minor_code,
(unsigned int)err->resourceid, err->serial);
}
/* -------------------------------------------------------------------- */
/* Backend vtable instance and active-backend pointer */
/* -------------------------------------------------------------------- */
@ -3183,6 +3235,10 @@ const WMBackend x11_backend = {
.menu_paint_entry = x11_menu_paint_entry,
.menu_draw_frame = x11_menu_draw_frame,
.draw_bevel = x11_draw_bevel,
.appmenu_send = x11_appmenu_send,
.display_get_name = x11_display_get_name,
.switchpanel_send_enter = x11_switchpanel_send_enter,
.format_x_error = x11_format_x_error,
};
/*

View File

@ -242,7 +242,7 @@ void SetupEnvironment(WScreen * scr)
if (multiHead) {
int len = strlen(DisplayName) + 64;
tmp = wmalloc(len);
snprintf(tmp, len, "DISPLAY=%s", XDisplayName(DisplayName));
snprintf(tmp, len, "DISPLAY=%s", wm_backend->display_get_name(DisplayName));
/* Search from the end to be compatible with ipv6 address */
ptr = strrchr(tmp, ':');
@ -251,7 +251,7 @@ void SetupEnvironment(WScreen * scr)
if (!message_already_displayed)
wwarning(_("the display name has an unexpected syntax: \"%s\""),
XDisplayName(DisplayName));
wm_backend->display_get_name(DisplayName));
message_already_displayed = True;
} else {
/* If found, remove the screen specification from the display variable */
@ -601,7 +601,7 @@ int main(int argc, char **argv)
}
}
DisplayName = XDisplayName(DisplayName);
DisplayName = wm_backend->display_get_name(DisplayName);
len = strlen(DisplayName) + 64;
str = wmalloc(len);
snprintf(str, len, "DISPLAY=%s", DisplayName);
@ -780,7 +780,7 @@ static int real_main(int argc, char **argv)
/* open display */
dpy = (Display *)wm_backend->display_open(DisplayName);
if (!wm_backend->is_wayland && dpy == NULL) {
wfatal(_("could not open display \"%s\""), XDisplayName(DisplayName));
wfatal(_("could not open display \"%s\""), wm_backend->display_get_name(DisplayName));
exit(1);
}
@ -806,7 +806,7 @@ static int real_main(int argc, char **argv)
if (pos && sscanf(pos, ":%i.%i", &d, &s) == 2)
multiHead = False;
DisplayName = XDisplayName(DisplayName);
DisplayName = wm_backend->display_get_name(DisplayName);
setenv("DISPLAY", DisplayName, 1);
/* Path 1: skip XGetModifierMapping() when dpy is an XWayland

View File

@ -537,18 +537,11 @@ void wSwitchPanelDestroy(WSwitchPanel *panel)
RImage *image;
if (panel->win) {
Window info_win = panel->scr->info_window;
XEvent ev;
ev.xclient.type = ClientMessage;
ev.xclient.message_type = w_global.atom.wm.ignore_focus_events;
ev.xclient.format = 32;
ev.xclient.data.l[0] = True;
WNativeWindow info_win = (WNativeWindow)panel->scr->info_window;
XSendEvent(dpy, info_win, True, EnterWindowMask, &ev);
wm_backend->switchpanel_send_enter(info_win, (WNativeWindow)panel->scr->root_win);
WMUnmapWidget(panel->win);
ev.xclient.data.l[0] = False;
XSendEvent(dpy, info_win, True, EnterWindowMask, &ev);
wm_backend->switchpanel_send_enter(info_win, (WNativeWindow)panel->scr->root_win);
}
if (panel->images) {

View File

@ -213,7 +213,7 @@ void wWindowDestroy(WWindow *wwin)
wfree(wwin->wm_gnustep_attr);
if (wwin->cmap_windows)
XFree(wwin->cmap_windows);
wwin->cmap_windows = NULL;
wm_backend->context_delete(wwin->client_win, WM_CTX_CLIENT_WIN);

View File

@ -33,159 +33,5 @@
static Atom Clipboard = 0;
#endif
static const char *requestCodes[] = {
"DUMMY",
"X_CreateWindow",
"X_ChangeWindowAttributes",
"X_GetWindowAttributes",
"X_DestroyWindow",
"X_DestroySubwindows",
"X_ChangeSaveSet",
"X_ReparentWindow",
"X_MapWindow",
"X_MapSubwindows",
"X_UnmapWindow",
"X_UnmapSubwindows",
"X_ConfigureWindow",
"X_CirculateWindow",
"X_GetGeometry",
"X_QueryTree",
"X_InternAtom",
"X_GetAtomName",
"X_ChangeProperty",
"X_DeleteProperty",
"X_GetProperty",
"X_ListProperties",
"X_SetSelectionOwner",
"X_GetSelectionOwner",
"X_ConvertSelection",
"X_SendEvent",
"X_GrabPointer",
"X_UngrabPointer",
"X_GrabButton",
"X_UngrabButton",
"X_ChangeActivePointerGrab",
"X_GrabKeyboard",
"X_UngrabKeyboard",
"X_GrabKey",
"X_UngrabKey",
"X_AllowEvents",
"X_GrabServer",
"X_UngrabServer",
"X_QueryPointer",
"X_GetMotionEvents",
"X_TranslateCoords",
"X_WarpPointer",
"X_SetInputFocus",
"X_GetInputFocus",
"X_QueryKeymap",
"X_OpenFont",
"X_CloseFont",
"X_QueryFont",
"X_QueryTextExtents",
"X_ListFonts",
"X_ListFontsWithInfo",
"X_SetFontPath",
"X_GetFontPath",
"X_CreatePixmap",
"X_FreePixmap",
"X_CreateGC",
"X_ChangeGC",
"X_CopyGC",
"X_SetDashes",
"X_SetClipRectangles",
"X_FreeGC",
"X_ClearArea",
"X_CopyArea",
"X_CopyPlane",
"X_PolyPoint",
"X_PolyLine",
"X_PolySegment",
"X_PolyRectangle",
"X_PolyArc",
"X_FillPoly",
"X_PolyFillRectangle",
"X_PolyFillArc",
"X_PutImage",
"X_GetImage",
"X_PolyText8",
"X_PolyText16",
"X_ImageText8",
"X_ImageText16",
"X_CreateColormap",
"X_FreeColormap",
"X_CopyColormapAndFree",
"X_InstallColormap",
"X_UninstallColormap",
"X_ListInstalledColormaps",
"X_AllocColor",
"X_AllocNamedColor",
"X_AllocColorCells",
"X_AllocColorPlanes",
"X_FreeColors",
"X_StoreColors",
"X_StoreNamedColor",
"X_QueryColors",
"X_LookupColor",
"X_CreateCursor",
"X_CreateGlyphCursor",
"X_FreeCursor",
"X_RecolorCursor",
"X_QueryBestSize",
"X_QueryExtension",
"X_ListExtensions",
"X_ChangeKeyboardMapping",
"X_GetKeyboardMapping",
"X_ChangeKeyboardControl",
"X_GetKeyboardControl",
"X_Bell",
"X_ChangePointerControl",
"X_GetPointerControl",
"X_SetScreenSaver",
"X_GetScreenSaver",
"X_ChangeHosts",
"X_ListHosts",
"X_SetAccessControl",
"X_SetCloseDownMode",
"X_KillClient",
"X_RotateProperties",
"X_ForceScreenSaver",
"X_SetPointerMapping",
"X_GetPointerMapping",
"X_SetModifierMapping",
"X_GetModifierMapping",
"X_NoOperation"
};
void FormatXError(Display * dpy, XErrorEvent * error, char *buffer, int size)
{
int i, p;
XGetErrorText(dpy, error->error_code, buffer, size);
i = strlen(buffer);
if (i > size - 100)
return;
buffer += i;
if (error->request_code >= wlengthof(requestCodes)) {
sprintf(buffer, "\n Request code: %i\n", error->request_code);
} else {
sprintf(buffer, "\n Request code: %i %s\n", error->request_code,
requestCodes[error->request_code]);
}
i += p = strlen(buffer);
if (i > size - 40)
return;
buffer += p;
sprintf(buffer, " Request minor code: %i\n", error->minor_code);
i += p = strlen(buffer);
if (i > size - 30)
return;
buffer += p;
sprintf(buffer, " Resource ID: 0x%x\n", (unsigned int)error->resourceid);
i += p = strlen(buffer);
if (i > size - 30)
return;
buffer += p;
sprintf(buffer, " Error serial: %li\n", error->serial);
return;
}
/* FormatXError moved to x11_backend.c — X11 mechanism code */