windowmaker-wl/src/backend/backend.h

1873 lines
76 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* backend.h -- WMBackend vtable: the policy/display-system boundary
*
* All WM policy code dispatches display operations through this interface.
* Currently only an X11 implementation exists; the vtable is the seam
* that a future Wayland backend will plug into.
*
* Phase 1: frame-window lifecycle, context table (wcore.c)
* Phase 2: generalized context table (all call sites), screen lifecycle
*
* NOTE: The function pointer parameters still use X11 types (Visual *,
* Colormap) because WScreen's visual fields have not been abstracted yet.
* A later phase will replace them with WBackendScreen *.
*/
#ifndef WM_BACKEND_H_
#define WM_BACKEND_H_
/* <X11/Xlib.h> removed Phase 30: Visual,Colormap,XEvent confined to x11_backend.c.
* Vtable uses void* / unsigned long for Visual/Colormap/XEvent slots.
* Policy files receive Xlib types transitively via WINGs.h (WindowMaker.h). */
/* <X11/Xatom.h> removed Phase 29: XA_* replaced by WA_* in backend_types.h. */
/* <X11/keysym.h> removed Phase 28: XK_* replaced by WM_KEY_* in backend_types.h;
* keysym_to_keycode vtable replaces XKeysymToKeycode calls in policy files. */
/* <X11/XKBlib.h> removed Phase 26: XkbGroup*Index replaced by WKB_GROUP*_INDEX in backend_types.h;
* XkbLockGroup/XkbGetState/XkbUseCoreKbd confined to x11_backend.c */
/* <X11/Xutil.h> removed Phase 27: XSizeHints/XClassHint/XWMHints/XTextProperty
* confined to x11_backend.c; policy uses WNormalHints/WWMHints and new vtable slots. */
/* <X11/Xproto.h> removed Phase 25: BadWindow/X_* moved to x11_backend.c */
/* <X11/cursorfont.h> removed Phase 24: XC_* constants moved to x11_backend.c */
#include <WINGs/WINGs.h> /* WMPixel */
#include <wraster.h> /* RImage */
#include "backend_types.h" /* WNativeWindow, WContextKey, WBackendScreen */
/* Forward-declare policy types so backend.h needs no policy headers. */
typedef struct _WScreen WScreen;
typedef struct WWindow WWindow;
typedef struct GNUstepWMAttributes GNUstepWMAttributes;
struct WObjDescriptor;
struct WFrameWindow;
typedef struct WMEvent WMEvent;
typedef struct _WCoreWindow WCoreWindow;
typedef union WTexture WTexture;
typedef struct WPixmap WPixmap;
typedef struct WApplication WApplication;
typedef struct WAppIcon WAppIcon;
typedef struct WIcon WIcon;
typedef struct WProtocols WProtocols;
typedef struct WShortKey WShortKey;
typedef struct MWMHints MWMHints;
typedef struct WMenu WMenu;
typedef struct WTexSolid WTexSolid;
/*
* WMBackend -- vtable for all display-system operations.
*
* The active backend is pointed to by wm_backend (defined below).
* Startup code sets wm_backend before any display operation is called.
*/
typedef struct WMBackend {
/* ------------------------------------------------------------------ */
/* Backend identity flag (Path 1) */
/* ------------------------------------------------------------------ */
/*
* Non-zero if this is the Wayland compositor backend.
* Allows policy code to take the Wayland fast-path even when dpy != NULL
* (i.e. when WindowMaker's X11 UI is bridged through XWayland).
* X11 backend: is_wayland = 0. Wayland backend: is_wayland = 1.
*/
int is_wayland;
/* ------------------------------------------------------------------ */
/* Display lifecycle (Phase 32) */
/* ------------------------------------------------------------------ */
/*
* Open the display connection and return the native handle.
* X11: XOpenDisplay(name) -- returns Display*.
* Wayland: initialises the wl_display + wlroots compositor; returns NULL
* (no X11 Display* exists in the Wayland path).
* Called from main.c before StartUp(). Sets up any connection-level
* state (e.g. X11 close-on-exec flag).
*/
void *(*display_open)(const char *name);
/*
* Close/destroy the display connection.
* Called during final shutdown after all screens have been closed.
*/
void (*display_close)(void);
/*
* Post-open initialization: validate the connection, set up visual IDs,
* parse display name for multi-head, set DISPLAY env var.
* Called from main.c immediately after display_open().
* X11: checks dpy != NULL (fatal if not), sets default visual, parses
* screen number from display name, sets DISPLAY env.
* Wayland: no-op (display_open handles all setup internally).
* display_name: the user-supplied -display argument (may be NULL).
* multi_head_out: set to 0 if a specific screen was requested.
*/
void (*display_post_open)(const char *display_name, int *multi_head_out);
/*
* Return the number of logical screens (X11: ScreenCount; Wayland: 1).
* Called from main.c / StartUp() after display_open().
*/
int (*display_screen_count)(void);
/*
* Return the default screen index for the display connection.
* X11: DefaultScreen(dpy). Wayland: 0.
* Called from StartUp() to pass to wScreenInit().
*/
int (*display_default_screen)(void);
/*
* Intern an atom by name.
* X11: XInternAtom(dpy, name, False) -- returns Atom (unsigned long).
* Wayland: returns 0 (atoms have no meaning in native Wayland).
* Called from StartUp() to populate w_global.atom.*.
*/
unsigned long (*atom_intern)(const char *name);
/*
* Run the backend's main event loop until shutdown.
* X11: no-op; EventLoop() drives the WINGs/X11 event pump.
* Wayland: wl_display_run(display) -- blocks until wl_display_terminate().
* Called from EventLoop() when dpy == NULL (Wayland path).
*/
void (*event_loop_run)(void);
/*
* Request the backend event loop to stop.
* X11: no-op (X11 EventLoop exits via exit()).
* Wayland: wl_display_terminate(display) -- causes event_loop_run() to return.
* Called from signal handlers so that cleanup happens outside signal context.
*/
void (*event_loop_terminate)(void);
/* ------------------------------------------------------------------ */
/* Screen lifecycle (Phase 2) */
/* ------------------------------------------------------------------ */
/*
* Allocate and initialize the backend's per-screen state.
* Called from wScreenInit before any display operation on the screen.
* Sets scr->backend_screen on success; calls wfatal on failure.
*/
void (*screen_open)(WScreen *scr);
/*
* Initialize the display-specific parts of the screen: RContext,
* WMScreen, color pixels. Returns 1 on success, 0 on failure.
* On success scr->rcontext, scr->wmscreen, scr->black/white/gray/
* darkGray and the pixel values are all set.
* X11: creates RContext via wrlib, WMScreen via WINGs with dpy.
* Wayland: creates RContextWayland, WMScreen with NULL display.
*/
int (*screen_init_display)(WScreen *scr, int screen_number);
/*
* Release all backend per-screen resources.
* Called from wScreenFinish.
*/
void (*screen_close)(WScreen *scr);
/* ------------------------------------------------------------------ */
/* Frame window lifecycle (Phase 1 / wcore.c) */
/* ------------------------------------------------------------------ */
/*
* Create an override-redirect toplevel window used for frames, icons,
* menus, and dialogs. Equivalent to XCreateWindow(dpy, root, ...) +
* XClearWindow.
*/
WNativeWindow (*frame_create_toplevel)(WScreen *scr,
int x, int y, int width, int height,
int border_width,
int depth, void *visual,
unsigned long colormap,
WMPixel border_pixel);
/*
* Create a child window of an existing frame window.
* Equivalent to XCreateWindow(dpy, parent_win, ...).
*/
WNativeWindow (*frame_create_child)(WNativeWindow parent_win,
WScreen *scr,
int x, int y, int width, int height);
/*
* Destroy a frame window.
* Equivalent to XDestroyWindow(dpy, win).
*/
void (*frame_destroy)(WScreen *scr, WNativeWindow win);
/*
* Move and/or resize a frame window.
* Equivalent to XConfigureWindow(dpy, win, CWX|CWY|CWWidth|CWHeight, ...).
*/
void (*frame_configure)(WNativeWindow win, int x, int y, int width, int height);
/*
* Render the complete frame decoration (titlebar, buttons, resizebar)
* into the frame's backing store and make it visible.
* X11: uses Xlib drawing on the frame sub-windows (the traditional path).
* Wayland: renders into a pixman buffer and commits to the scene graph.
* Returns 1 if the backend handled painting, 0 if the caller should
* fall through to legacy Xlib code (X11 backend returns 0).
*/
int (*frame_paint)(struct WFrameWindow *fwin);
/* ------------------------------------------------------------------ */
/* Window context table (Phase 2) */
/* */
/* Three lookup tables keyed by WContextKey map a WNativeWindow to */
/* the owning policy object (WObjDescriptor *, WApplication *, or */
/* WCoreWindow *). X11 uses XContext / Xrm; a Wayland backend uses */
/* a hash table. */
/* ------------------------------------------------------------------ */
/*
* Associate data with win under key.
* Equivalent to XSaveContext(dpy, win, ctx[key], data).
*/
void (*context_save)(WNativeWindow win, WContextKey key, void *data);
/*
* Look up win under key. Returns the stored pointer or NULL.
* Equivalent to XFindContext(dpy, win, ctx[key], &ptr).
*/
void *(*context_find)(WNativeWindow win, WContextKey key);
/*
* Remove the association for win under key.
* Returns 0 on success, -1 if the entry was not found.
* Equivalent to XDeleteContext(dpy, win, ctx[key]).
*/
int (*context_delete)(WNativeWindow win, WContextKey key);
/* ------------------------------------------------------------------ */
/* Focus and input grabs (Phase 4) */
/* ------------------------------------------------------------------ */
/*
* Set keyboard input focus to win.
* Equivalent to XSetInputFocus(dpy, win, revert_to, timestamp).
*/
void (*focus_set)(WNativeWindow win, int revert_to, unsigned long timestamp);
/*
* Grab a key+modifier combination on win.
* The X11 backend applies LockMask and NumLock/ScrollLock hack variants
* internally; policy code passes the canonical modifier only.
* Equivalent to XGrabKey + wHackedGrabKey.
*/
void (*key_grab)(WNativeWindow win, unsigned int keycode,
unsigned int modifier, int owner_events);
/*
* Release all key grabs on win.
* Equivalent to XUngrabKey(dpy, AnyKey, AnyModifier, win).
*/
void (*key_ungrab_all)(WNativeWindow win);
/*
* Grab a button+modifier on win.
* The X11 backend applies LockMask and NumLock/ScrollLock variants.
* Equivalent to wHackedGrabButton(button, modifier, win, owner_events,
* event_mask, GrabModeSync, GrabModeAsync,
* None, None).
*/
void (*button_grab)(WNativeWindow win, unsigned int button,
unsigned int modifier, unsigned int event_mask,
int owner_events);
/*
* Release all button grabs on win.
* Equivalent to XUngrabButton(dpy, AnyButton, AnyModifier, win).
*/
void (*button_ungrab_all)(WNativeWindow win);
/* ------------------------------------------------------------------ */
/* Interactive pointer operations (Phase 7) */
/* ------------------------------------------------------------------ */
/*
* Grab the pointer for an interactive move, resize, or placement.
* grab_win: window that receives events during the grab (typically root).
* confine_to: window to confine pointer to, or WNATIVE_NONE.
* event_mask: events to receive during the grab (X11 mask constants).
* cursor_id: cursor to display during the grab (WCUR_* constant).
* owner_events: non-zero = events routed normally; zero = all to grab_win.
* timestamp: event timestamp; pass 0 for CurrentTime.
* Returns 1 on success, 0 if the grab failed.
* Equivalent to XGrabPointer(dpy, grab_win, owner_events, event_mask,
* GrabModeAsync, GrabModeAsync,
* confine_to, cursor, timestamp).
*/
int (*pointer_grab)(WNativeWindow grab_win, WNativeWindow confine_to,
unsigned int event_mask, int cursor_id,
int owner_events, unsigned long timestamp);
/*
* Release a previously acquired pointer grab.
* timestamp: event timestamp; pass 0 for CurrentTime.
* Equivalent to XUngrabPointer(dpy, timestamp).
*/
void (*pointer_ungrab)(unsigned long timestamp);
/*
* Warp the pointer by (dx, dy) relative to its current position.
* Equivalent to XWarpPointer(dpy, None, None, 0, 0, 0, 0, dx, dy).
*/
void (*pointer_warp)(int dx, int dy);
/*
* Query the root-window-relative pointer coordinates.
* root: the root window to query on.
* root_x, root_y: output: pointer position in root coordinates.
* Returns 1 if the pointer is on the same screen as root, 0 otherwise.
* Equivalent to XQueryPointer(dpy, root, ..., root_x, root_y, ...).
*/
int (*pointer_query)(WNativeWindow root, int *root_x, int *root_y);
/*
* Send a synthetic ConfigureNotify to the client window.
* Used after reparenting or interactive moves to inform the client of its
* new position/size in root coordinates.
* above: the sibling window just above this one in the stack, or WNATIVE_NONE.
* Equivalent to the XSendEvent(ConfigureNotify) in wWindowSynthConfigureNotify.
*/
void (*client_synth_configure)(WNativeWindow client_win,
int x, int y, int width, int height,
int border_width, WNativeWindow above);
/* ------------------------------------------------------------------ */
/* Stacking (Phase 4) */
/* ------------------------------------------------------------------ */
/*
* Reorder the given windows to match the array order (front-to-back).
* Equivalent to XRestackWindows(dpy, (Window *)windows, count).
*/
void (*stacking_restack)(WNativeWindow *windows, int count);
/*
* Raise win to the top of the stacking order.
* Equivalent to XRaiseWindow(dpy, win).
*/
void (*stacking_raise)(WNativeWindow win);
/*
* Lower win to the bottom of the stacking order.
* Equivalent to XLowerWindow(dpy, win).
*/
void (*stacking_lower)(WNativeWindow win);
/*
* Query the server's window stacking order under root.
* On success stores a wmalloc'd WNativeWindow array in *out and the
* count in *count; caller must wfree(*out). Returns 1 on success, 0 on
* failure.
* Equivalent to XQueryTree (children only; root and parent are ignored).
*/
int (*stacking_query)(WNativeWindow root,
WNativeWindow **out, unsigned int *count);
/*
* Notify the backend that a frame's WM stacking level has changed.
* The backend may use this to place the frame in the correct scene-graph
* layer so that level ordering is structurally enforced without requiring
* a full CommitStacking reorder.
* level is one of the WM*Level constants from WindowMaker.h.
* No-op on backends that do not have per-level scene trees (e.g. X11).
*/
void (*stacking_set_level)(WNativeWindow win, int level);
/* ------------------------------------------------------------------ */
/* Event queue operations (Phase 3) */
/* ------------------------------------------------------------------ */
/*
* Flush all pending output to the display server.
* Equivalent to XFlush(dpy).
*/
void (*event_flush)(void);
/*
* Flush all pending output and optionally discard queued events.
* Equivalent to XSync(dpy, discard).
*/
void (*event_sync)(int discard);
/*
* Return the number of events currently in the local queue.
* Equivalent to XPending(dpy).
*/
int (*event_pending)(void);
/* ------------------------------------------------------------------ */
/* Window properties (Phase 5) */
/* ------------------------------------------------------------------ */
/*
* Fetch WM_NORMAL_HINTS from win into *out.
* Returns 1 on success, 0 if not present.
* Sets *pre_icccm=1 if the hint set matches the pre-ICCCM convention.
* Equivalent to XGetWMNormalHints.
*/
int (*prop_get_normal_hints)(WNativeWindow win, WNormalHints *out,
int *pre_icccm);
/*
* Fetch WM_HINTS from win.
* Returns a wmalloc'd WWMHints * on success, NULL if not present.
* Caller must wfree() the returned pointer.
* Equivalent to XGetWMHints (but returns wmalloc'd, not XMalloc'd).
*/
WWMHints *(*prop_get_wm_hints)(WNativeWindow win);
/*
* Fetch WM_CLASS from win.
* On success stores strdup'd strings in *wm_class and *wm_instance; returns 1.
* On failure stores "default" in both fields; returns 0.
* Equivalent to XGetClassHint.
*/
int (*prop_get_wm_class)(WNativeWindow win,
char **wm_class, char **wm_instance);
/*
* Fetch WM_NAME from win into *name_out (wstrdup'd string).
* Returns True on success, False if property is absent.
* Equivalent to XGetWMName + encoding conversion.
*/
Bool (*window_fetch_name)(WNativeWindow win, char **name_out);
/*
* Fetch WM_ICON_NAME from win into *name_out.
* Returns True on success, False if absent.
* Equivalent to XGetWMIconName + encoding conversion.
*/
Bool (*window_get_icon_name)(WNativeWindow win, char **name_out);
/*
* Read the _WINDOWMAKER_MENU text property from win.
* On success stores an XFreeStringList-allocated string array in *list_out,
* its length in *count_out, and returns 1.
* On failure returns 0. Caller frees with icccm_free_command().
* Equivalent to XGetTextProperty + XTextPropertyToStringList on wmaker.menu atom.
*/
int (*prop_get_wmaker_menu)(WNativeWindow win,
char ***list_out, int *count_out);
/* ------------------------------------------------------------------ */
/* Window visibility and geometry (Phase 10) */
/* ------------------------------------------------------------------ */
/*
* Map win (make it visible on screen) at its current stacking position.
* Equivalent to XMapWindow(dpy, win).
*/
void (*window_map)(WNativeWindow win);
/*
* Map win and raise it to the top of the stacking order atomically.
* Equivalent to XMapRaised(dpy, win).
*/
void (*window_map_raised)(WNativeWindow win);
/*
* Unmap win (hide it without destroying it).
* Equivalent to XUnmapWindow(dpy, win).
*/
void (*window_unmap)(WNativeWindow win);
/*
* Move win to (x, y) in root-window coordinates.
* Equivalent to XMoveWindow(dpy, win, x, y).
*/
void (*window_move)(WNativeWindow win, int x, int y);
/*
* Resize win to width × height.
* Equivalent to XResizeWindow(dpy, win, width, height).
*/
void (*window_resize)(WNativeWindow win, int width, int height);
/*
* Extended pointer query: root-relative coordinates plus the child
* window (top-level window) currently under the pointer and the
* current button/modifier mask.
*
* All output parameters are optional (pass NULL to ignore).
* child_out: the child of root directly under the pointer, or
* WNATIVE_NONE if the pointer is on the root background.
* root_x, root_y: pointer position in root coordinates.
* buttons_out: button + modifier mask at query time.
*
* Returns 1 if the pointer is on the same screen as root, 0 otherwise.
* Equivalent to XQueryPointer(dpy, root, ...).
*/
int (*pointer_query_full)(WNativeWindow root,
WNativeWindow *child_out,
int *root_x, int *root_y,
unsigned int *buttons_out);
/* ------------------------------------------------------------------ */
/* Workspace name badge (Phase 10) */
/* ------------------------------------------------------------------ */
/*
* Render the workspace-name label onto badge_win.
*
* Performs all server-side pixmap creation, font drawing, shape masking
* and background-pixmap setup needed to display the label. Does NOT map
* the window; the caller maps it afterwards with window_map_raised.
*
* On success returns an RImage * of the rendered text (owned by the
* caller; must be released with RReleaseImage). Returns NULL on failure
* (e.g., rendering context unavailable); the caller should still map
* and display the window without the fade animation.
*
* The X11 backend uses XCreatePixmap + WMDrawString + XShapeCombineMask
* + XSetWindowBackgroundPixmap.
*/
RImage *(*workspace_badge_render)(WScreen *scr, WNativeWindow badge_win,
const char *name, int name_len,
int width, int height);
/*
* Update badge_win to display the pre-blended RImage img (one fade step).
*
* The X11 backend: converts img to a server pixmap via RConvertImage,
* sets it as badge_win's background, clears the window, frees the
* pixmap, and flushes.
* Equivalent to: RConvertImage + XSetWindowBackgroundPixmap +
* XClearWindow + XFreePixmap + XFlush.
*/
void (*workspace_badge_update)(WScreen *scr, WNativeWindow badge_win,
RImage *img);
/*
* Capture the background behind the workspace badge for the fade effect.
*
* X11: RGetXImage + RCreateImageFromXImage on the root window.
* Wayland: returns a solid dark RImage (no screen capture needed).
*
* Returns an RImage* owned by the caller (must be freed with RReleaseImage).
* Returns NULL on failure.
*/
RImage *(*workspace_badge_get_background)(WScreen *scr, int x, int y,
int width, int height);
/* ------------------------------------------------------------------ */
/* Server grab (Phase 11) */
/* ------------------------------------------------------------------ */
/*
* Grab the X server, preventing other clients from issuing requests.
* Used to bracket animation drawing so frames appear atomically.
* Equivalent to XGrabServer(dpy).
*/
void (*server_grab)(void);
/*
* Release a previously acquired server grab.
* Equivalent to XUngrabServer(dpy).
*/
void (*server_ungrab)(void);
/* ------------------------------------------------------------------ */
/* Overlay drawing (Phase 11) */
/* ------------------------------------------------------------------ */
/*
* Draw a polyline on the root window using the frame XOR GC.
* Used for miniaturize/deiconify twist/flip animations.
* points: array of n WPoint vertices (memory-compatible with XPoint).
* Equivalent to XDrawLines(dpy, root, frame_gc, points, n, CoordModeOrigin).
*/
void (*overlay_draw_lines)(WScreen *scr, WPoint *points, int n);
/*
* Draw a rectangle on the root window using the frame XOR GC.
* Used for miniaturize/deiconify zoom animation.
* Equivalent to XDrawRectangle(dpy, root, frame_gc, x, y, w, h).
*/
void (*overlay_draw_rect)(WScreen *scr, int x, int y, int w, int h);
/* ------------------------------------------------------------------ */
/* Window attributes (Phase 11) */
/* ------------------------------------------------------------------ */
/*
* Query a window's position (within its parent) and dimensions.
* Returns 1 on success; 0 if the window no longer exists.
* Any output pointer may be NULL if that value is not needed.
* Equivalent to XGetWindowAttributes (position and size fields only).
*/
int (*window_get_rect)(WNativeWindow win,
int *win_x, int *win_y, int *win_w, int *win_h);
/* ------------------------------------------------------------------ */
/* Client snapshot (Phase 11) */
/* ------------------------------------------------------------------ */
/*
* Capture the visible pixels of a managed client window as an RImage.
* Raises frame_win, resolves root-relative coords, clips to screen edges,
* and captures the client surface. Returns a wmalloc'd RImage * owned
* by the caller (release with RReleaseImage), or NULL on failure.
* Used to populate the mini-preview icon thumbnail.
* Equivalent to: XRaiseWindow(frame) + XTranslateCoordinates +
* XGetImage + RCreateImageFromXImage + XDestroyImage.
*/
RImage *(*client_snapshot)(WScreen *scr,
WNativeWindow client_win,
WNativeWindow frame_win);
/* ------------------------------------------------------------------ */
/* Desktop refresh (Phase 11) */
/* ------------------------------------------------------------------ */
/*
* Force a full repaint of the root window by briefly covering it with
* a transient override-redirect window and immediately destroying it.
* Equivalent to: XCreateWindow(CWSaveUnder|CWBackingStore) +
* XMapRaised + XDestroyWindow + XFlush.
*/
void (*refresh_desktop)(WScreen *scr);
/* ------------------------------------------------------------------ */
/* Window event subscription (Phase 11) */
/* ------------------------------------------------------------------ */
/*
* Set the X event mask for win.
* Used to temporarily suppress StructureNotify during shade animation
* and to re-subscribe after pointer warp.
* Equivalent to XSelectInput(dpy, win, mask).
*/
void (*window_select_events)(WNativeWindow win, unsigned long mask);
/* ------------------------------------------------------------------ */
/* Window border (Phase 11) */
/* ------------------------------------------------------------------ */
/*
* Set the border colour of win to pixel.
* Used by wSelectWindow to highlight / de-highlight selected frames.
* Equivalent to XSetWindowBorder(dpy, win, pixel).
*/
void (*window_set_border)(WNativeWindow win, unsigned long pixel);
/*
* Set the border width of win to width pixels.
* Used by wSelectWindow when toggling borders on/off.
* Equivalent to XSetWindowBorderWidth(dpy, win, width).
*/
void (*window_set_border_width)(WNativeWindow win, int width);
/* ------------------------------------------------------------------ */
/* Absolute pointer warp (Phase 11) */
/* ------------------------------------------------------------------ */
/*
* Warp the pointer to absolute root-window coordinates (x, y).
* Used by movePointerToWindowCenter after half-maximise.
* Equivalent to XWarpPointer(dpy, None, root, 0,0,0,0, x, y).
*/
void (*pointer_warp_to)(int x, int y);
/* ------------------------------------------------------------------ */
/* Expose event drain (Phase 11) */
/* ------------------------------------------------------------------ */
/*
* Drain and dispatch all pending Expose events, then sync.
* Called before miniaturise animation so the screen is repainted
* before the server grab begins.
* Equivalent to: while(XCheckTypedEvent(Expose)) WMHandleEvent(&ev);
* XSync(dpy, 0).
*/
void (*event_flush_expose)(void);
/* ------------------------------------------------------------------ */
/* Keyboard grab (Phase 9) */
/* ------------------------------------------------------------------ */
/*
* Grab the keyboard to win for the duration of an interactive operation
* (e.g. Alt-Tab cycling, keyboard-driven move/resize).
* Equivalent to XGrabKeyboard(dpy, win, False,
* GrabModeAsync, GrabModeAsync, CurrentTime).
* Returns 1 on success (GrabSuccess), 0 on failure.
*/
int (*keyboard_grab)(WNativeWindow win);
/*
* Release a previously acquired keyboard grab.
* Equivalent to XUngrabKeyboard(dpy, CurrentTime).
*/
void (*keyboard_ungrab)(void);
/*
* Translate a key symbol to a hardware keycode on the current keyboard.
* keysym: one of the WM_KEY_* constants defined in backend_types.h.
* Returns the hardware keycode, or 0 if the keysym has no mapping.
* Equivalent to XKeysymToKeycode(dpy, keysym).
*/
unsigned int (*keysym_to_keycode)(unsigned long keysym);
/* ------------------------------------------------------------------ */
/* Interactive pointer grab change (Phase 12) */
/* ------------------------------------------------------------------ */
/*
* Change the event mask and/or cursor of an active pointer grab.
* Used mid-move/resize when the drag direction is determined.
* cursor_id: WCUR_* cursor index; WCUR_NONE leaves cursor unchanged.
* timestamp: event timestamp; pass 0 for CurrentTime.
* Equivalent to XChangeActivePointerGrab(dpy, event_mask, cursor, time).
*/
void (*pointer_change_grab)(unsigned int event_mask, int cursor_id,
unsigned long timestamp);
/* ------------------------------------------------------------------ */
/* Event queue operations (Phase 12) */
/* ------------------------------------------------------------------ */
/*
* Drain all pending ButtonMotion events from the queue without
* processing them. Used to coalesce mouse-move updates.
* Equivalent to: while (XCheckMaskEvent(dpy, ButtonMotionMask, &ev)) ;
*/
void (*event_drain_motion)(void);
/*
* Discard queued EnterNotify and LeaveNotify events whose timestamp
* is <= the given timestamp; put back any that arrived after it.
* Used after a move/resize button release to discard stale focus events.
* Equivalent to the XCheckTypedEvent/XPutBackEvent pattern for
* EnterNotify and LeaveNotify.
*/
void (*event_discard_enter_leave_until)(unsigned long timestamp);
/* ------------------------------------------------------------------ */
/* Coordinate translation (Phase 12) */
/* ------------------------------------------------------------------ */
/*
* Translate (src_x, src_y) from src-window coordinates to dst-window
* coordinates. The child-window output of XTranslateCoordinates is
* discarded. Returns 1 on success, 0 if src/dst are on different
* screens.
* Equivalent to XTranslateCoordinates(dpy, src, dst, sx, sy, dx, dy, &junk).
*/
int (*coords_translate)(WNativeWindow src, WNativeWindow dst,
int src_x, int src_y, int *dst_x, int *dst_y);
/* ------------------------------------------------------------------ */
/* Window save-under attribute (Phase 12) */
/* ------------------------------------------------------------------ */
/*
* Enable or disable server-side backing-store for opaque moves.
* save_under: non-zero to enable, zero to disable.
* Equivalent to XChangeWindowAttributes(dpy, win, CWSaveUnder, &attr).
*/
void (*window_set_save_under)(WNativeWindow win, int save_under);
/*
* Set the background pixel of a window.
* Equivalent to XSetWindowBackground(dpy, win, pixel).
*/
void (*window_set_background)(WNativeWindow win, unsigned long pixel);
/*
* Set the background pixmap of a window.
* Equivalent to XSetWindowBackgroundPixmap(dpy, win, pixmap).
*/
void (*window_set_background_pixmap)(WNativeWindow win, unsigned long pixmap);
/* ------------------------------------------------------------------ */
/* Keysym from hardware keycode (Phase 12) */
/* ------------------------------------------------------------------ */
/*
* Return the keysym for a hardware keycode at the given modifier index.
* index 0 = unshifted, 1 = shifted; other indices map to modifiers.
* Returns 0 (NoSymbol) if the keycode has no mapping.
* Equivalent to XLookupKeysym(&ev, index) or XKeycodeToKeysym(dpy, kc, i).
*/
unsigned long (*keysym_from_keycode)(unsigned int keycode, unsigned int index);
/* ------------------------------------------------------------------ */
/* Extended overlay drawing (Phase 12) */
/* ------------------------------------------------------------------ */
/*
* Draw a single line on the root window using the frame XOR GC.
* Used for transparent frame decoration lines (title separator, etc.).
* Equivalent to XDrawLine(dpy, root, frame_gc, x1, y1, x2, y2).
*/
void (*overlay_draw_line)(WScreen *scr, int x1, int y1, int x2, int y2);
/*
* Draw a set of line segments on the root window using the line GC.
* Sets the foreground colour to scr->line_pixel before drawing.
* Used for the WDIS_NEW geometry display arrows.
* segs: WSegment array (memory-compatible with XSegment).
* Equivalent to XSetForeground + XDrawSegments(dpy, root, line_gc, segs, n).
*/
void (*overlay_draw_segments)(WScreen *scr, WSegment *segs, int n);
/*
* Return the pixel width of a string rendered in the technical-draw font.
* Used to centre the size label in the geometry display.
* Equivalent to XTextWidth(scr->tech_draw_font, str, n).
*/
int (*overlay_text_width)(WScreen *scr, const char *str, int n);
/*
* Draw a text string on the root window using the line GC and the
* technical-draw font. Sets the GC font before drawing.
* Used for the size/position label in the WDIS_NEW geometry display.
* Equivalent to XSetFont + XDrawString(dpy, root, line_gc, x, y, str, n).
*/
void (*overlay_draw_string)(WScreen *scr, int x, int y,
const char *str, int n);
/* ------------------------------------------------------------------ */
/* Window clear and repaint (Phase 13) */
/* ------------------------------------------------------------------ */
/*
* Clear win's drawable area, triggering a background repaint.
* Equivalent to XClearWindow(dpy, win).
*/
void (*window_clear)(WNativeWindow win);
/*
* Map all unmapped direct children of parent.
* Equivalent to XMapSubwindows(dpy, parent).
*/
void (*window_map_subwindows)(WNativeWindow parent);
/*
* Free a server-side pixmap.
* Equivalent to XFreePixmap(dpy, pixmap).
* No-op in Wayland mode (pixmaps are CPU-side RImages).
*/
void (*pixmap_free)(unsigned long pixmap);
/* ------------------------------------------------------------------ */
/* Client window attributes query (Phase 13) */
/* ------------------------------------------------------------------ */
/*
* Query a client window's override_redirect, map_state, and border_width.
* Returns 1 if the window exists, 0 if it has been destroyed.
* Equivalent to XGetWindowAttributes (selected fields only).
*/
int (*window_get_client_attrs)(WNativeWindow win, WClientAttributes *out);
/*
* Fill *out with the visual/colormap attributes of client window win.
* Used by wManageWindow to create a matching frame window.
* Equivalent to XGetWindowAttributes (depth, visual, colormap fields).
*/
void (*client_get_visual_attrs)(WNativeWindow win, WClientVisual *out);
/*
* Add extra_mask to whatever event mask win currently has subscribed.
* Used to ensure leader windows receive StructureNotify + PropertyChange.
* Equivalent to: XGetWindowAttributes(win, &a);
* XSelectInput(win, a.your_event_mask | extra_mask).
*/
void (*window_add_events)(WNativeWindow win, unsigned long extra_mask);
/*
* Apply client-window attributes needed when first adopting a client:
* - set event_mask on win
* - set do-not-propagate mask to suppress Button+Key events
* - disable save-under
* Equivalent to XChangeWindowAttributes(CWEventMask|CWDontPropagate|
* CWSaveUnder).
*/
void (*client_adopt_attributes)(WNativeWindow win, unsigned long event_mask);
/* ------------------------------------------------------------------ */
/* Client reparenting and save-set (Phase 13) */
/* ------------------------------------------------------------------ */
/*
* Reparent client into new_parent at position (x, y).
* Equivalent to XReparentWindow(dpy, client, new_parent, x, y).
*/
void (*client_reparent)(WNativeWindow client, WNativeWindow new_parent,
int x, int y);
/*
* Add win to the WM's save-set.
* Equivalent to XAddToSaveSet(dpy, win).
* No-op on backends without save-set support.
*/
void (*client_add_to_save_set)(WNativeWindow win);
/*
* Remove win from the WM's save-set.
* Equivalent to XRemoveFromSaveSet(dpy, win).
* No-op on backends without save-set support.
*/
void (*client_remove_from_save_set)(WNativeWindow win);
/*
* Request a client window to close itself.
* On X11: XKillClient (forceful); on Wayland: xdg_toplevel_send_close.
*/
void (*client_close)(WNativeWindow win);
/* ------------------------------------------------------------------ */
/* Fake group-leader window (Phase 13) */
/* ------------------------------------------------------------------ */
/*
* Create a minimal invisible window on scr for use as a synthetic
* WM_HINTS group leader. Returns WNATIVE_NONE on failure.
* Equivalent to XCreateSimpleWindow(dpy, root, 10,10,10,10, 0,0,0).
*/
WNativeWindow (*fake_leader_create)(WScreen *scr);
/*
* Destroy a window previously created by fake_leader_create.
* Equivalent to XDestroyWindow(dpy, win).
*/
void (*fake_leader_destroy)(WNativeWindow win);
/* ------------------------------------------------------------------ */
/* ICCCM property helpers (Phase 13) */
/* ------------------------------------------------------------------ */
/*
* Set WM_CLASS on win to instance/class unconditionally.
* Equivalent to XSetClassHint.
*/
void (*icccm_set_class_hint)(WNativeWindow win,
const char *instance, const char *class_name);
/*
* Set WM_CLASS on win to instance/class only if win has no WM_CLASS yet.
* Equivalent to: if (XGetClassHint(win) == 0) XSetClassHint(win, ...).
*/
void (*icccm_set_class_hint_if_absent)(WNativeWindow win,
const char *instance,
const char *class_name);
/*
* Set WM_HINTS on win from hints.
* hints is policy-allocated (wmalloc); the backend copies it.
* Equivalent to XSetWMHints(dpy, win, <converted from WWMHints>).
*/
void (*icccm_set_wm_hints)(WNativeWindow win, const WWMHints *hints);
/*
* Set WM_COMMAND on win.
* Equivalent to XSetCommand(dpy, win, argv, argc).
*/
void (*icccm_set_command)(WNativeWindow win, char **argv, int argc);
/*
* Read WM_COMMAND from win.
* On success stores a malloc'd argv array in *argv_out and argc in
* *argc_out; caller must free with icccm_free_command().
* Returns non-zero on success, 0 if the property is absent.
* Equivalent to XGetCommand(dpy, win, argv_out, argc_out).
*/
int (*icccm_get_command)(WNativeWindow win, char ***argv_out, int *argc_out);
/*
* Free a argv array returned by icccm_get_command.
* Equivalent to XFreeStringList(argv).
*/
void (*icccm_free_command)(char **argv);
/* ------------------------------------------------------------------ */
/* Transient-for hint (Phase 13) */
/* ------------------------------------------------------------------ */
/*
* Fetch WM_TRANSIENT_FOR from win.
* Returns the owner WNativeWindow, or WNATIVE_NONE if absent.
* Equivalent to XGetTransientForHint(dpy, win, &owner).
*/
WNativeWindow (*prop_get_transient_for)(WNativeWindow win);
/* ------------------------------------------------------------------ */
/* Property existence tests (Phase 13) */
/* ------------------------------------------------------------------ */
/*
* Return non-zero if win has the WM_T(_WINDOWMAKER_MENU) property set.
* Equivalent to XGetTextProperty(win, w_global.atom.wmaker.menu) check.
*/
int (*prop_has_wmaker_menu)(WNativeWindow win);
/*
* Return non-zero if win has _GTK_APPLICATION_OBJECT_PATH set.
* Equivalent to XGetWindowProperty(w_global.atom.desktop.gtk_object_path)
* presence check.
*/
int (*prop_has_gtk_object_path)(WNativeWindow win);
/* ------------------------------------------------------------------ */
/* wmaker saved-state property (Phase 13) */
/* ------------------------------------------------------------------ */
/*
* Store data[0..n-1] as the wmaker.WM_STATE property on win
* (PropModeReplace, 32-bit format).
* Equivalent to XChangeProperty(wmaker.state, ...).
*/
void (*prop_set_wm_state)(WNativeWindow win, const long *data, int n);
/*
* Retrieve the wmaker.WM_STATE property from win.
* On success stores a wmalloc'd long array in *data_out (10 elements)
* and returns 1; caller must wfree(*data_out).
* Deletes the property after reading (consume semantics).
* Returns 0 if absent or malformed.
* Equivalent to XGetWindowProperty(wmaker.state, True, ...).
*/
int (*prop_get_wm_state)(WNativeWindow win, long **data_out);
/* ------------------------------------------------------------------ */
/* XRes client PID (Phase 13) */
/* ------------------------------------------------------------------ */
/*
* Query the display server for the PID of the client owning win.
* Returns the pid on success, or -1 if unavailable.
* Encapsulates XResQueryClientIds + XResGetClientPid +
* XResClientIdsDestroy. Returns -1 if USE_XRES is not compiled in.
*/
int (*client_get_pid)(WNativeWindow win);
/* ------------------------------------------------------------------ */
/* Client window shape (Phase 13) */
/* ------------------------------------------------------------------ */
/*
* Remove any bounding-shape from wwin's frame (restores rectangle).
* Encapsulates XShapeCombineMask(frame, None, ShapeSet) + XFlush.
* No-op if USE_XSHAPE is not compiled in.
*/
void (*window_shape_clear)(WWindow *wwin);
/*
* Recompute and apply the bounding-shape for wwin's frame, combining
* the client's shape with decoration rectangles.
* Encapsulates XShapeGetRectangles/XShapeCombineRectangles/
* XShapeCombineShape/XFree/XFlush.
* No-op if USE_XSHAPE is not compiled in.
*/
void (*window_shape_set)(WWindow *wwin);
/*
* Subscribe win to ShapeNotify events and query whether it is shaped.
* shaped_out: set to non-zero if client has a non-rectangular shape.
* Encapsulates XShapeSelectInput + XShapeQueryExtents.
* No-op (leaves *shaped_out=0) if USE_XSHAPE is not compiled in.
*/
void (*client_query_shaped)(WNativeWindow win, int *shaped_out);
/*
* client_get_gnustep_attrs() -- read GNUstep WM attributes for a client.
* Allocates *attr_out via malloc and populates it; caller must free().
* Returns True if the client advertised GNUstep attributes, False if not
* (in which case *attr_out is set to NULL).
* On X11: reads the _GNUSTEP_WM_ATTR property.
* On Wayland: reads from a gnustep-wm-v1 protocol object (future), or
* returns False if the client does not support it.
*/
int (*client_get_gnustep_attrs)(WNativeWindow win, GNUstepWMAttributes **attr_out);
/* ------------------------------------------------------------------ */
/* Monitor/head geometry (Phase 6) */
/* ------------------------------------------------------------------ */
/*
* Query the available monitors/heads for scr.
* On success allocates a wmalloc'd WHeadGeometry array, stores the
* pointer in *heads_out and the count in *count_out.
* Caller must wfree(*heads_out) when done.
* Falls back to a single head covering the full screen if no
* multi-head extension is available.
* Equivalent to XineramaIsActive + XineramaQueryScreens (or Solaris
* XineramaGetInfo), synthesizing a single-screen fallback.
*/
void (*monitors_query)(WScreen *scr,
WHeadGeometry **heads_out, int *count_out);
/*
* Subscribe to monitor-change events on scr->root_win.
* Equivalent to XRRSelectInput(dpy, root_win, RRScreenChangeNotifyMask).
* No-op if the extension is unavailable.
*/
void (*monitors_select_events)(WScreen *scr);
/* ------------------------------------------------------------------ */
/* Screen initialization (Phase 14) */
/* ------------------------------------------------------------------ */
/*
* ICCCM 2.0 WM replacement protocol.
* Creates scr->info_window; acquires the WM_Sn selection.
* Returns 1 on success (we own the screen), 0 on failure.
* Destroys any internally-created resources before returning 0.
*/
int (*screen_replace_wm)(WScreen *scr);
/*
* XSelectInput on root_win + error-handler bracket + XSync.
* Also calls XkbSelectEvents if KEEP_XKB_LOCK_STATUS is compiled in.
* Returns 1 on success, 0 if another WM is already running.
* event_mask: combination of X11 event-mask bit constants.
*/
int (*screen_select_input)(WScreen *scr, long event_mask);
/*
* XDefineCursor on the root window.
* cursor_id: WCUR_* constant (index into wPreferences.cursor[]).
*/
void (*screen_set_root_cursor)(WScreen *scr, int cursor_id);
/*
* XSetIconSizes on root_win.
* min_size: minimum icon dimension; max_size: maximum icon dimension.
*/
void (*screen_set_icon_sizes)(WScreen *scr, int min_size, int max_size);
/*
* Set up the WMaker noticeboard XChangeProperty on info_window and root.
*/
void (*screen_setup_noticeboard)(WScreen *scr);
/*
* Allocate all GCs stored in WScreen (frame_gc, line_gc, copy_gc, etc.).
* Equivalent to the old allocGCs() function.
*/
void (*screen_alloc_gcs)(WScreen *scr);
/*
* Create internal utility windows: no_focus_win, dock_shadow,
* workspace_name. Equivalent to the old createInternalWindows().
*/
void (*screen_create_internals)(WScreen *scr);
/*
* Create shared pixmaps: dock_dots, button pixmaps, indicator pixmaps.
* Equivalent to the old createPixmaps().
*/
void (*screen_create_pixmaps)(WScreen *scr);
/*
* Load the technical-draw font into scr->tech_draw_font.
* Falls back to "fixed" if the preferred font is unavailable.
*/
void (*screen_load_tech_font)(WScreen *scr);
/*
* Interactive rubber-band area capture.
* Grabs pointer and server, lets the user drag a rectangle, captures
* that region and returns it as an RImage *.
* Returns NULL if the user cancels (Escape) or the region is empty.
*/
RImage *(*screen_capture_area)(WScreen *scr);
/*
* Capture the visible portion of wwin's client window as an RImage *.
* Used for screenshot of a partially-off-screen window.
* Returns NULL on failure.
*/
RImage *(*screen_capture_window)(WScreen *scr, WWindow *wwin);
/*
* Show a mini screenshot overlay at the bottom-right of the screen.
* Displays img for ~2 seconds then fades away.
*/
void (*screen_show_mini_screenshot)(WScreen *scr, RImage *img);
/* ------------------------------------------------------------------ */
/* Extension event dispatch (Phase 15) */
/* ------------------------------------------------------------------ */
/*
* Dispatch extension events (Shape, XKB, RandR) for one XEvent.
* Called from the default: branch of the main event switch.
* The X11 backend checks each enabled extension's event base and
* handles ShapeNotify (updates window shape), XKB indicator state
* (updates keyboard group for the focused window), and
* RRScreenChangeNotify (calls XRRUpdateConfiguration then restarts).
* No-op for event types not matching any known extension.
*/
void (*event_handle_extensions)(WMEvent *event);
/*
* Notify the backend of a ConfigureNotify on the root window.
* The X11 backend calls XRRUpdateConfiguration(event) when RandR is
* compiled in; other backends may update their screen geometry state.
* Called from the ConfigureNotify case in the main event switch.
* No-op if USE_RANDR is not compiled in (or equivalent).
*/
void (*event_randr_update)(WMEvent *event);
/*
* Return the current XKB keyboard group (layout index, 0-based).
* Used by the WKBD_TOGGLE keyboard shortcut to read the current group
* before swapping window language modes.
* Equivalent to XkbGetState(dpy, XkbUseCoreKbd, &state); return state.group.
* Returns 0 if KEEP_XKB_LOCK_STATUS is not compiled in.
*/
int (*xkb_get_group)(void);
/*
* Set the active XKB keyboard group to group.
* Used by the WKBD_TOGGLE keyboard shortcut to restore the saved
* group after swapping window language modes.
* Equivalent to XkbLockGroup(dpy, XkbUseCoreKbd, group).
* No-op if KEEP_XKB_LOCK_STATUS is not compiled in.
*/
void (*xkb_lock_group)(int group);
/* ------------------------------------------------------------------ */
/* Error handler registration (Phase 25) */
/* ------------------------------------------------------------------ */
/*
* Install the backend's X error handler and I/O error handler.
* Called once during startup after the display is open.
* On X11: XSetErrorHandler + XSetIOErrorHandler.
* On Wayland: no-op (protocol errors handled via wl_display listener).
*/
void (*register_error_handlers)(void);
/* Extension detection (Phase 21) */
/*
* Probe available X11 extensions (shape, randr, xkb) and populate
* w_global.xext.*.supported / *.event_base. Called once during startup
* after the display is open. No-op for extensions not compiled in.
*/
void (*extensions_init)(void);
/* ------------------------------------------------------------------ */
/* Cursor creation (Phase 24) */
/* ------------------------------------------------------------------ */
/*
* Create all built-in WCUR_* cursors and store them in
* wPreferences.cursor[]. Called once during startup after the
* display is open.
* On X11: XCreateFontCursor(XC_*) + XCreatePixmapCursor for WCUR_EMPTY.
* On Wayland: loads from the compositor cursor theme.
*/
void (*cursors_init)(void);
/*
* Create a cursor by its X11 font-cursor name (e.g. "fleur", "watch").
* Used to honour user cursor preferences from the defaults database.
* Returns WNATIVE_NONE if the name is not recognised.
* On X11: looks up XC_* id and calls XCreateFontCursor.
* On Wayland: maps the name to a Wayland cursor theme entry.
*/
WNativeWindow (*cursor_create_named)(const char *name);
/* Shape mask (Phase 17) */
/*
* Apply or clear a bounding-shape mask on a window.
* Equivalent to XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, mask, ShapeSet).
* Pass WNATIVE_NONE as mask to clear the shape (reset to rectangular).
* No-op if USE_XSHAPE is not compiled in.
*/
void (*shape_combine_mask)(WNativeWindow win, WNativeWindow mask);
/* ------------------------------------------------------------------ */
/* Texture helpers (Phase 19) */
/* ------------------------------------------------------------------ */
/*
* Allocate a colour cell in the screen's colormap.
* X11: XAllocColor(dpy, scr->w_colormap, color).
* Wayland: no-op (colours stored as direct pixel values).
*/
void (*texture_alloc_color)(WScreen *scr, XColor *color);
/*
* Free colour cells previously allocated with texture_alloc_color.
* X11: XFreeColors(dpy, scr->w_colormap, pixels, count, 0) with
* error-handler bracket for buggy servers.
* Wayland: no-op.
*/
void (*texture_free_colors)(WScreen *scr, unsigned long *pixels, int count);
/*
* Create a GC for texture bevel drawing.
* X11: XCreateGC(dpy, scr->w_win, mask, &gcv).
* Wayland: returns NULL (GCs do not exist).
*/
GC (*texture_create_gc)(WScreen *scr, unsigned long pixel);
/*
* Free a GC used by the texture system for bevel drawing.
* X11: XFreeGC(dpy, gc).
* Wayland: no-op (GCs do not exist).
*/
void (*texture_free_gc)(GC gc);
/* ------------------------------------------------------------------ */
/* Frame decoration helpers (Phase 80) */
/* ------------------------------------------------------------------ */
/*
* Allocate a frame border colour from a colormap by name.
* On success stores a wmalloc'd pixel value in *pixel_out.
* On failure sets *pixel_out = NULL.
* X11: XParseColor + XAllocColor.
* Wayland: no-op (*pixel_out = NULL; frame_paint handles colours).
*/
void (*frame_alloc_border_pixel)(unsigned long colormap,
const char *color_name,
unsigned long **pixel_out);
/*
* Update X11 window backgrounds for frame sub-windows after a
* texture/state change. Clears and repaints titlebar + buttons.
* X11: XSetWindowBackground[Pixmap] + XClearWindow on sub-windows.
* Wayland: no-op (frame_paint renders the entire frame).
*/
void (*frame_update_texture)(struct WFrameWindow *fwin);
/*
* Paint a single frame button (close/miniaturize/language).
* X11: Xlib drawing into the button sub-window.
* Wayland: no-op (frame_paint renders buttons into the frame buffer).
*/
void (*frame_paint_button)(WCoreWindow *button, WTexture *texture,
unsigned long color, WPixmap *image,
int pushed);
/* ------------------------------------------------------------------ */
/* NETWM/EWMH (Phase 80) */
/* ------------------------------------------------------------------ */
/*
* Initialize NETWM atoms and root-window hints.
* X11: interns atoms, sets _NET_SUPPORTED, registers observers.
* Wayland: no-op (no X11 root-window properties).
*/
void (*netwm_init)(WScreen *scr);
/*
* Remove all NETWM properties from the root window.
* X11: XDeleteProperty for each _NET_* atom.
* Wayland: no-op.
*/
void (*netwm_cleanup)(WScreen *scr);
/*
* Update _NET_DESKTOP_GEOMETRY and _NET_DESKTOP_VIEWPORT on root.
* X11: XChangeProperty.
* Wayland: no-op.
*/
void (*netwm_update_desktop)(WScreen *scr);
/*
* Read _NET_CURRENT_DESKTOP from root.
* X11: PropGetCheckProperty.
* Wayland: returns -1.
*/
int (*netwm_get_current_desktop)(WScreen *scr);
/*
* Copy _NET_WM_WINDOW_OPACITY from client to frame window.
* X11: XGetWindowProperty + XChangeProperty.
* Wayland: no-op.
*/
void (*netwm_update_opacity)(WWindow *wwin);
/*
* Set _NET_WM_ALLOWED_ACTIONS on a client window.
* X11: XChangeProperty / XDeleteProperty.
* Wayland: no-op.
*/
void (*netwm_update_actions)(WWindow *wwin, int del);
/*
* Read _NET_WM_DESKTOP, _NET_WM_STATE, _NET_WM_WINDOW_TYPE from client.
* X11: XGetWindowProperty for each.
* Wayland: no-op.
*/
void (*netwm_check_client_hints)(WWindow *wwin, int *layer, int *workspace);
/*
* Read initial NETWM state (window type, icon info) for a new client.
* X11: reads properties, updates wwin flags.
* Wayland: no-op.
*/
void (*netwm_check_initial_state)(WWindow *wwin);
/*
* Read _NET_WM_PID from a window.
* X11: XGetWindowProperty.
* Wayland: returns 0.
*/
int (*netwm_get_pid)(WNativeWindow window);
/*
* Remove _NET_FRAME_EXTENTS from a client window.
* X11: XDeleteProperty.
* Wayland: no-op.
*/
void (*netwm_cleanup_frame_extents)(WWindow *wwin);
/* ------------------------------------------------------------------ */
/* X11 root-window properties (Phase 80) */
/* ------------------------------------------------------------------ */
/*
* Read WM_PROTOCOLS from a client window.
* X11: XGetWMProtocols, populates prots.
* Wayland: sets DELETE_WINDOW=1 (all XDG toplevels support close).
*/
void (*prop_get_protocols)(WNativeWindow window, WProtocols *prots);
/*
* Read an arbitrary X11 property from a window.
* X11: XGetWindowProperty.
* Wayland: returns NULL.
*/
unsigned char *(*prop_get_check_property)(WNativeWindow window,
unsigned long hint,
unsigned long type,
int format, int count,
int *ret_count);
/*
* Set _WINDOWMAKER_WM_PROTOCOLS on root.
* X11: XChangeProperty.
* Wayland: no-op.
*/
void (*prop_set_wmaker_protocols)(WNativeWindow root);
/*
* Set _WINDOWMAKER_ICON_TILE hint on info_window.
* X11: XChangeProperty with RGBA data.
* Wayland: no-op.
*/
void (*prop_set_icon_tile)(WScreen *scr, RImage *image);
/*
* Remove WMaker protocol properties from root.
* X11: XDeleteProperty for wm_protocols, noticeboard, icon_size.
* Wayland: no-op.
*/
void (*prop_cleanup)(WNativeWindow root);
/* ------------------------------------------------------------------ */
/* Client operations (Phase 80) */
/* ------------------------------------------------------------------ */
/*
* Reparent client window back to root (during unmanage/shutdown).
* X11: XSetWindowBorderWidth + XReparentWindow.
* Wayland: no-op.
*/
void (*client_restore)(WWindow *wwin);
/*
* Set WM_STATE property on client window.
* X11: XChangeProperty with state + icon_win.
* Wayland: no-op (state tracked internally).
*/
void (*client_set_state)(WWindow *wwin, int state, WNativeWindow icon_win);
/* Notify the client of maximized/fullscreen state changes.
* X11: no-op (handled via _NET_WM_STATE property).
* Wayland: sends xdg_toplevel set_maximized/set_fullscreen. */
void (*client_set_maximized)(WNativeWindow win, int maximized);
/*
* Send a WM_PROTOCOLS message to a client (e.g. WM_DELETE_WINDOW).
* X11: XSendEvent with ClientMessage.
* Wayland: dispatches client_close for delete, no-op otherwise.
*/
void (*client_send_protocol)(WWindow *wwin, unsigned long protocol,
unsigned long timestamp);
/*
* Forcefully kill a client.
* X11: XKillClient + XFlush.
* Wayland: client_close (request close via xdg_toplevel).
*/
void (*client_kill)(WWindow *wwin);
/*
* Read WM_COLORMAP_WINDOWS from a client.
* X11: XGetWMColormapWindows.
* Wayland: no-op.
*/
void (*client_get_colormap_windows)(WWindow *wwin);
/* ------------------------------------------------------------------ */
/* Misc X11 utilities (Phase 80) */
/* ------------------------------------------------------------------ */
/*
* Drain pending Expose events from the X11 queue.
* X11: XCheckMaskEvent loop.
* Wayland: no-op.
*/
void (*eat_expose)(void);
/*
* Move a window with optional animation.
* X11: XMoveWindow (or slide_window with animation).
* Wayland: no-op (frame positions are virtual).
*/
void (*move_window)(WNativeWindow win, int from_x, int from_y,
int to_x, int to_y);
/*
* Slide an array of windows with animation.
* X11: animated XMoveWindow loop.
* Wayland: no-op.
*/
void (*slide_windows)(WNativeWindow *wins, int n,
int from_x, int from_y, int to_x, int to_y);
/*
* Get text from an X11 cut buffer selection.
* X11: XFetchBuffer.
* Wayland: returns NULL.
*/
char *(*get_text_selection)(WScreen *scr, unsigned long selection);
/*
* Convert a key shortcut to a human-readable string.
* X11: XKeysymToString + modifier labels.
* Wayland: returns NULL (TODO: implement with xkbcommon).
*/
char *(*get_shortcut_string)(WShortKey key);
/*
* Read WM_COMMAND from a window and return as joined string.
* X11: XGetCommand.
* Wayland: uses icccm_get_command vtable slot.
*/
char *(*get_command_for_window)(WNativeWindow win, int elements);
/* ------------------------------------------------------------------ */
/* Icon rendering (Phase 80) */
/* ------------------------------------------------------------------ */
/*
* Update the icon's X11 pixmap from its file_image and repaint.
* X11: XFreePixmap + icon_update_pixmap + XSetWindowBackgroundPixmap + wIconPaint.
* Wayland: no-op (icons rendered via frame_paint or scene buffers).
*/
void (*icon_update_pixmap)(WIcon *icon);
/*
* Paint an icon (clear window, draw title, selection rect).
* X11: XClearWindow + text drawing + XDrawRectangle.
* Wayland: no-op.
*/
void (*icon_paint)(WIcon *icon);
/* ------------------------------------------------------------------ */
/* App icon (Phase 80) */
/* ------------------------------------------------------------------ */
/*
* Show/place an application icon on screen.
* X11: PlaceIcon + wAppIconMove + wLowerFrame + wAppIconPaint.
* Wayland: no-op.
*/
void (*appicon_show)(WApplication *wapp);
/*
* Paint an app icon (icon + dock dots + indicators).
* X11: wIconPaint + XCopyArea for dock dots + indicators.
* Wayland: no-op.
*/
void (*appicon_paint)(WAppIcon *aicon);
/* ------------------------------------------------------------------ */
/* Shutdown (Phase 80) */
/* ------------------------------------------------------------------ */
/*
* Restore desktop: reparent all clients back to root, clean up.
* X11: XGrabServer + restoreWindows + PropCleanUp + wNETWMCleanup.
* Wayland: no-op (clients are independent).
*/
void (*restore_desktop)(WScreen *scr);
/*
* Kill/close all managed windows on a screen.
* X11: sends DELETE_WINDOW or XKillClient to each window.
* Wayland: no-op (compositor handles client lifecycle).
*/
void (*wipe_desktop)(WScreen *scr);
/* ------------------------------------------------------------------ */
/* Resources / colormap (Phase 80) */
/* ------------------------------------------------------------------ */
/*
* Allocate a named colour from a colormap.
* X11: XParseColor + XAllocColor.
* Wayland: returns False.
*/
int (*get_color_for_colormap)(unsigned long colormap,
const char *color_name, XColor *color);
/*
* Free a previously allocated colour pixel.
* X11: XFreeColors.
* Wayland: no-op.
*/
void (*free_color)(WScreen *scr, unsigned long pixel);
/*
* Install a colormap for a window.
* X11: XInstallColormap for client cmap_windows.
* Wayland: no-op.
*/
void (*colormap_install)(WScreen *scr, WWindow *wwin);
/* ------------------------------------------------------------------ */
/* Protocol-specific init (Phase 80) */
/* ------------------------------------------------------------------ */
/*
* Initialize XDND (X11 drag-and-drop) atoms.
* X11: XInternAtom for all XdndAware/XdndEnter/etc.
* Wayland: no-op.
*/
void (*xdnd_init)(void);
/*
* Read Motif WM hints from a client window.
* X11: XGetWindowProperty for _MOTIF_WM_HINTS.
* Wayland: returns 0 (no hints).
*/
int (*motif_get_hints)(WNativeWindow window, MWMHints *hints_out);
/* ------------------------------------------------------------------ */
/* Superfluous effects (Phase 80) */
/* ------------------------------------------------------------------ */
/*
* Perform app-icon bounce animation.
* X11: XRaiseWindow + XMoveWindow loop.
* Wayland: no-op.
*/
void (*appicon_bounce)(WAppIcon *aicon, void *data);
/* ------------------------------------------------------------------ */
/* Startup (Phase 80) */
/* ------------------------------------------------------------------ */
/*
* Adopt all existing top-level windows (after WM startup).
* X11: XQueryTree + wManageWindow loop.
* Wayland: no-op (clients connect dynamically).
*/
void (*manage_all_windows)(WScreen *scr, int crash_recovery);
/* ------------------------------------------------------------------ */
/* Event dispatch (Phase 80) */
/* ------------------------------------------------------------------ */
/*
* Handle signal-driven state changes in the event loop.
* X11: calls Shutdown(WSExitMode).
* Wayland: calls event_loop_terminate().
*/
void (*event_handle_signal_exit)(void);
/* ------------------------------------------------------------------ */
/* Icon interaction (Phase 80c) */
/* ------------------------------------------------------------------ */
void (*icon_select)(WIcon *icon);
void (*icon_change_title)(WIcon *icon, WWindow *wwin);
/* ------------------------------------------------------------------ */
/* Clip/Drawer icon rendering (Phase 80c) */
/* ------------------------------------------------------------------ */
void (*clip_icon_paint)(WAppIcon *aicon);
void (*drawer_icon_paint)(WAppIcon *aicon);
/* ------------------------------------------------------------------ */
/* Balloon tooltips (Phase 80c) */
/* ------------------------------------------------------------------ */
void (*balloon_init)(WScreen *scr);
/* ------------------------------------------------------------------ */
/* Superfluous effects (Phase 80c) */
/* ------------------------------------------------------------------ */
void (*do_kaboom)(WScreen *scr, WNativeWindow win, int x, int y);
/* ------------------------------------------------------------------ */
/* Menu rendering (Phase 80c) */
/* ------------------------------------------------------------------ */
void (*menu_paint_entry)(WMenu *menu, int index, int selected);
void (*menu_draw_frame)(WScreen *scr, WNativeWindow win,
int y, int w, int h, int type);
/* ------------------------------------------------------------------ */
/* Bevel drawing (Phase 80c) */
/* ------------------------------------------------------------------ */
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);
/* ------------------------------------------------------------------ */
/* Pixmap creation (Phase 80d) */
/* ------------------------------------------------------------------ */
WPixmap *(*pixmap_create_from_xbm)(WScreen *scr, char *data, char *mask,
int width, int height,
unsigned long fg, unsigned long bg);
WPixmap *(*pixmap_create)(unsigned long image, unsigned long mask);
unsigned long (*keysym_from_name)(const char *name);
void (*frame_paint_resizebar)(struct WFrameWindow *fwin);
void (*frame_paint_titlebar)(struct WFrameWindow *fwin, int state);
WNativeWindow (*prop_get_client_leader)(WNativeWindow window);
int (*prop_get_window_state)(WNativeWindow window);
void (*setup_modifier_lock_masks)(void);
void (*key_grab_hacked)(WNativeWindow window, int keycode, unsigned int modifiers);
void (*button_grab_hacked)(unsigned int button, unsigned int modifiers,
WNativeWindow window, int owner_events,
unsigned int event_mask);
void (*context_init)(void);
void (*query_tree)(WNativeWindow root, WNativeWindow **children_out,
unsigned int *nchildren_out);
WScreen *(*screen_for_window)(WNativeWindow window);
int (*parse_color)(WScreen *scr, const char *name, XColor *color_out);
int (*cursor_create_from_files)(WScreen *scr, const char *bitmap_path,
const char *mask_path, Cursor *cursor_out);
void (*cursor_free)(Cursor cursor);
void (*cursor_set)(WNativeWindow window, Cursor cursor);
void (*pointer_change_cursor)(int cursor_id);
void (*appicon_paint_dock_dots)(struct WAppIcon *aicon, void *wapp);
int (*pixmap_get_size)(unsigned long drawable, unsigned int *w, unsigned int *h, unsigned int *depth);
void (*icon_paint_title_bg)(WScreen *scr, unsigned long pixmap, int height);
void (*icon_select_paint)(WIcon *icon, int step);
unsigned long (*window_get_event_mask)(WNativeWindow window);
void (*balloon_show)(WScreen *scr, void *bal);
void (*window_fill_stipple)(WNativeWindow win, int x, int y, int w, int h);
int (*event_check_enter_leave)(void *dock);
/* Event mechanism (Phase 80p) */
void (*event_allow_async)(void);
void (*event_replay_pointer)(void);
void (*keyboard_mapping_refresh)(WMEvent *event);
void (*event_flush_window)(WNativeWindow win, int event_type);
void (*event_flush_type)(int event_type);
int (*event_check_window)(WNativeWindow win, int event_type);
int (*event_check_type)(int event_type, WMEvent *event_out);
void (*client_send_event)(WNativeWindow win, void *event_data);
/*
* Forward a ClientMessage event that was delivered to one window
* to a different target window. Used by handleClientMessage to
* redirect OffiX DND ClientMessages from icon frames to the actual
* client_win. Only meaningful for X11 (and XWayland clients via
* the Wayland backend).
*/
void (*client_message_forward)(WMEvent *event, WNativeWindow target_win);
/*
* Deliver a synthetic key press/release to a client window. Used by
* usermenu.c to translate menu entries into keystrokes for the
* focused client.
*
* X11: synthesize XKeyEvent and XSendEvent it to the window.
* Wayland: deliver via XSendEvent for XWayland clients (the X
* server backed by wlroots' xwayland surfaces still
* accepts synthetic events). Native Wayland clients are
* not yet handled (would need zwp_virtual_keyboard_v1).
*/
void (*client_send_key)(WNativeWindow win, unsigned int keycode,
unsigned int modifier_mask, int press);
int (*window_exists)(WNativeWindow win);
void (*window_get_colormap)(WNativeWindow win, unsigned long *colormap_out);
WNativeWindow (*pointer_query_window)(WNativeWindow root);
void (*dialog_paint_icon)(unsigned long drawable, void *back_color,
void *pixmap, WScreen *scr,
int x, int y, int width, int height);
void (*pointer_get_position)(int *x, int *y);
const char *(*keysym_to_string)(unsigned long keysym);
int (*window_get_command)(WNativeWindow win, char ***argv_out, int *argc_out);
/* NETWM/XDND mechanism (Phase 80s) */
int (*netwm_process_client_message)(WMEvent *event);
int (*xdnd_process_client_message)(WMEvent *event);
void (*xdnd_process_selection)(WMEvent *event);
void (*xdnd_make_awareness)(WNativeWindow win);
void (*netwm_check_client_hint_change)(WWindow *wwin, void *event);
/*
* ICCCM WM-replacement SelectionRequest / SelectionClear handling.
*
* The X server delivers SelectionRequest/SelectionClear events for
* the WM_Sn selection that wmaker holds when running under X11.
* Both handlers need access to the X display, atom interning, and
* XChangeProperty — all X11-only. They live in the X11 backend.
*
* Wayland: the Wayland backend's wmaker UI does not own a WM_Sn
* selection on the X server, so these are no-ops. XWayland clients
* still receive their own selections via wlroots' data device path
* and never reach these slots.
*/
void (*handle_selection_request)(WMEvent *event);
void (*handle_selection_clear)(WMEvent *event);
void (*netwm_position_splash)(WWindow *wwin, int *x, int *y, int width, int height);
void (*netwm_check_initial_frame_state)(WWindow *wwin);
/* wrlib context creation */
RContext *(*create_rcontext)(int screen_number, RContextAttributes *attribs);
/*
* Show crash dialog. Returns WMAbort or WMStartAlternate.
*/
int (*show_crash_dialog)(int sig);
} WMBackend;
/*
* The active backend. Set by startup code before any display call.
* Pointer is mutable (allows backend swap at startup); pointed-to struct
* is const (vtable never changes at runtime).
*/
extern const WMBackend *wm_backend;
#endif /* WM_BACKEND_H_ */