From b72d527ee7e110c6fb9c5c7a96cb5d260a716037 Mon Sep 17 00:00:00 2001 From: Levi Neely <141506390+lneely@users.noreply.github.com> Date: Wed, 13 May 2026 10:42:06 +0200 Subject: [PATCH] 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. --- src/appmenu.c | 14 +-- src/backend/backend.h | 9 ++ src/backend/wayland/wl_backend.c | 16 ++++ src/backend/x11/x11_backend.c | 60 +++++++++++- src/main.c | 10 +- src/switchpanel.c | 13 +-- src/window.c | 2 +- src/xutil.c | 156 +------------------------------ 8 files changed, 94 insertions(+), 186 deletions(-) diff --git a/src/appmenu.c b/src/appmenu.c index 410d6f5..722ac55 100644 --- a/src/appmenu.c +++ b/src/appmenu.c @@ -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) diff --git a/src/backend/backend.h b/src/backend/backend.h index 0e3dd84..19e02dd 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -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; /* diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index 5d88841..1f2e431 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -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, }; diff --git a/src/backend/x11/x11_backend.c b/src/backend/x11/x11_backend.c index 5b61606..8f3e193 100644 --- a/src/backend/x11/x11_backend.c +++ b/src/backend/x11/x11_backend.c @@ -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, }; /* diff --git a/src/main.c b/src/main.c index 29c37e2..f764fd3 100644 --- a/src/main.c +++ b/src/main.c @@ -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 diff --git a/src/switchpanel.c b/src/switchpanel.c index 57e44e2..122bb07 100644 --- a/src/switchpanel.c +++ b/src/switchpanel.c @@ -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) { diff --git a/src/window.c b/src/window.c index 7d35992..1f8ba6c 100644 --- a/src/window.c +++ b/src/window.c @@ -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); diff --git a/src/xutil.c b/src/xutil.c index f6bb743..c475aa4 100644 --- a/src/xutil.c +++ b/src/xutil.c @@ -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 */