windowmaker-wl/src/backend/backend.h

1193 lines
50 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;
/*
* 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 {
/* ------------------------------------------------------------------ */
/* 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);
/*
* 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);
/* ------------------------------------------------------------------ */
/* 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);
/*
* 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);
/* ------------------------------------------------------------------ */
/* 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);
/* ------------------------------------------------------------------ */
/* 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);
/* ------------------------------------------------------------------ */
/* 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);
/* ------------------------------------------------------------------ */
/* 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);
/* ------------------------------------------------------------------ */
/* 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)(void *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)(void *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);
} 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_ */