wrlib: split X11 image-conversion path; --disable-x11-wraster

Phase θ — wrlib's X11 image-conversion path (RConvertImage,
RPutXImage, the X11 RCreateContext, libXpm-based RLoadXPM) is now
opt-out via --disable-x11-wraster, mirroring the WINGs phase η work.

Result: with --disable-x11-backend --disable-x11-wraster the WINGs
runtime libraries have ZERO libX11 transitive deps:

  $ ldd WINGs/.libs/libWINGs.so | grep X11
  (empty)
  $ ldd wrlib/.libs/libwraster.so | grep X11
  (empty)

That was the last libX11 transitive dep coming through WINGs — the
goal of the API surgery is now achieved at the library level.

configure.ac:
- New --enable-x11-wraster (default = same as --enable-x11-backend),
  AM_CONDITIONAL([USE_X11_WRASTER]), AC_DEFINE([USE_X11_WRASTER]).
  Forcing --disable-x11-wraster while --enable-x11-backend is rejected
  (X11 backend depends on the X11 conversion path).
- WRASTER_GFXLIBS_NO_XPM: GFXLIBS with -lXpm filtered (libXpm pulls
  libX11; load_xpm_normalized.c is the X11-free XPM loader used in
  the disabled-X11 build).
- WINGS_PANGO_LIBS_NO_XFT: PANGO_LIBS with -lpangoxft-* and -lXft
  filtered (PangoXft depends on libXft -> libX11; pangoft2 path is
  the X11-free Pango variant).

wrlib/Makefile.am:
- Split source list: shared / X11-only / Wayland-only.
- X11 sources (context.c, convert.c, convert_x11.c, xpixmap.c,
  xutil.c, load_xpm.c) only built when USE_X11_WRASTER.
- New context_wl.c (always built) — Wayland-mode RCreateContextWayland
  extracted from context.c.
- New wstubs_no_x11.c (only built when !USE_X11_WRASTER) — empty
  stubs for the public wraster API symbols normally exported from
  the X11 path (RCreateContext, RDestroyContext, RConvertImage,
  RConvertImageMask, RGetClosestXColor, RCreateImageFromDrawable,
  RCreateImageFromXImage, RCreateXImage, RGetXImage, RDestroyXImage,
  RPutXImage, RGetImageFromXPMData, RLoadXPM).
- @XLIBS@/@LIBXMU@ only added to libwraster_la_LIBADD when
  USE_X11_WRASTER; load_xpm.c only built when (USE_XPM and
  USE_X11_WRASTER).
- Added --filter USE_X11_WRASTER to the wraster.h generation rule
  so the @!USE_X11_WRASTER@ lines (forcing WRASTER_NO_XLIB) are
  retained when X11 is disabled.

wrlib/wraster.h.in:
- When USE_X11_WRASTER is undefined at config time, force
  WRASTER_NO_XLIB so consumers see only forward-decl'd opaque types
  (Display/Visual/XImage/etc.) and never <X11/Xlib.h>.
- Added True/False/None defines to the WRASTER_NO_XLIB block (raster.c
  uses them; previously got via Xlib.h).

wrlib/context.c — RCreateContextWayland moved out to context_wl.c.
wrlib/wstubs_no_x11.c — new (157 lines).
wrlib/context_wl.c — new (extracted Wayland branch).

WINGs/Makefile.am:
- libWINGs_la_LIBADD now uses WINGS_PANGO_LIBS, which is @PANGO_LIBS@
  when X11 backend enabled, @WINGS_PANGO_LIBS_NO_XFT@ otherwise.

WINGs/widgets.c — WMCreateScreen + WMCreateSimpleApplicationScreen
moved to widgets_x11.c (they use DefaultScreen() and RCreateContext()
which are X11-only).  Stubs added in WINGs/wstubs_no_x11.c.
WINGs shared rootWin assignment now reads context->drawable instead
of calling X11 RootWindow() macro directly.

WINGs/WINGs/wnative.h — added X11-numeric constants used by shared
WINGs widget code:
- Button1..Button5 (X.h pointer-button numbers)
- KeyPress..LASTEvent (X.h event-type constants)
- CWBackPixmap..CWCursor (X.h CreateWindow/ChangeWindowAttributes
  mask bits)
- WMShortRect (XRectangle layout-compatible struct)
All guarded by #ifndef so X11 headers can override on the X11 build.

WINGs/configuration.c — dropped unused <X11/Xlocale.h> include.
WINGs/wruler.c, wtabview.c, wtext.c — replaced raw XPoint/XRectangle
with WMShortPoint/WMShortRect; replaced lone XSetWindowAttributes
shim with direct view->attribs.cursor access.

src/WindowMaker.h — explicitly include <X11/Xlib.h>, <X11/Xutil.h>,
<X11/Xresource.h>, <X11/Xatom.h>.  The wmaker compositor uses these
extensively in its public headers; previously got them transitively
via WINGs.h.  After the WINGs surgery WINGs.h no longer pulls Xlib,
so the compositor must include them itself.

Verified:
  Default build (--enable-x11-backend, --enable-x11-wraster):
    Window Maker 0.96.0 boots, all features intact.
  Pure-Wayland build (--disable-x11-backend --disable-x11-wraster):
    libwraster.so / libWINGs.so build cleanly, no libX11 in ldd.
    (wmaker compositor binary still has X11 deps from src/* code;
     out of scope for this commit — that's a compositor-level
     refactor.)
This commit is contained in:
Window Maker 2026-05-24 12:24:45 +02:00
parent cff52676c2
commit a4eb10b2b5
16 changed files with 531 additions and 88 deletions

View File

@ -12,7 +12,7 @@ lib_LTLIBRARIES = libWUtil.la libWINGs.la
LDADD= libWUtil.la libWINGs.la $(top_builddir)/wrlib/libwraster.la @INTLIBS@
libWINGs_la_LIBADD = libWUtil.la $(top_builddir)/wrlib/libwraster.la $(X11_LIBS_IF_ENABLED) @FCLIBS@ @LIBM@ @PANGO_LIBS@ @PIXMAN_LIBS@ $(WAYLAND_CLIENT_LIBS_IF_ENABLED)
libWINGs_la_LIBADD = libWUtil.la $(top_builddir)/wrlib/libwraster.la $(X11_LIBS_IF_ENABLED) @FCLIBS@ @LIBM@ $(WINGS_PANGO_LIBS) @PIXMAN_LIBS@ $(WAYLAND_CLIENT_LIBS_IF_ENABLED)
libWUtil_la_LIBADD = @LIBBSD@
if USE_WAYLAND_CLIENT
@ -23,8 +23,12 @@ endif
if USE_X11_BACKEND
X11_LIBS_IF_ENABLED = @XLIBS@ @XFT_LIBS@
WINGS_PANGO_LIBS = @PANGO_LIBS@
else
X11_LIBS_IF_ENABLED =
# Without the X11 backend, PangoXft (which pulls libXft -> libX11) is
# unused; configure provides PANGO_LIBS with Xft variants filtered.
WINGS_PANGO_LIBS = @WINGS_PANGO_LIBS_NO_XFT@
endif
EXTRA_DIST = BUGS make-rgb Examples Extras Tests

View File

@ -47,6 +47,14 @@ typedef struct WMShortPoint {
short x, y;
} WMShortPoint;
/* WMShortRect — layout matches X11's XRectangle. Used by wtext.c
* selection rectangles and the ruler tab bar; X11 backend can cast
* directly to XRectangle for XClipRectangles / XFillRectangles. */
typedef struct WMShortRect {
short x, y;
unsigned short width, height;
} WMShortRect;
/* Bool / True / False — historically supplied by <X11/Xlib.h>. WINGs
* uses these types extensively in its public API. Define them here so
* WUtil.h / WINGs.h can stop including <X11/Xlib.h>. Guard with
@ -119,6 +127,83 @@ typedef struct _XftFont XftFont;
/* Sentinel button numbers. */
#define WM_ANY_BUTTON 0L
/* Pointer button numbers — values match X11 (Button1..Button5 in X.h).
* Defined here without an X11 dep so shared code (configuration.c,
* mouse-event dispatch) can refer to them without including <X11/X.h>. */
#ifndef Button1
# define Button1 1
# define Button2 2
# define Button3 3
# define Button4 4
# define Button5 5
#endif
/* X event-type constants — values match X11 (X.h KeyPress..LASTEvent).
* Used by the WMEvent.type field (which is wire-compatible with
* XEvent.type) and by WINGs shared code that switch()es on event type
* regardless of backend. Guarded by #ifndef so they don't clash with
* <X11/X.h> when X11 wraster/backend is enabled. */
#ifndef KeyPress
# define KeyPress 2
# define KeyRelease 3
# define ButtonPress 4
# define ButtonRelease 5
# define MotionNotify 6
# define EnterNotify 7
# define LeaveNotify 8
# define FocusIn 9
# define FocusOut 10
# define KeymapNotify 11
# define Expose 12
# define GraphicsExpose 13
# define NoExpose 14
# define VisibilityNotify 15
# define CreateNotify 16
# define DestroyNotify 17
# define UnmapNotify 18
# define MapNotify 19
# define MapRequest 20
# define ReparentNotify 21
# define ConfigureNotify 22
# define ConfigureRequest 23
# define GravityNotify 24
# define ResizeRequest 25
# define CirculateNotify 26
# define CirculateRequest 27
# define PropertyNotify 28
# define SelectionClear 29
# define SelectionRequest 30
# define SelectionNotify 31
# define ColormapNotify 32
# define ClientMessage 33
# define MappingNotify 34
# define GenericEvent 35
# define LASTEvent 36
#endif
/* X11 CreateWindow / ChangeWindowAttributes mask bits — values match
* X11 X.h CWBackPixmap..CWCursor. Used as flags in W_View.attribFlags
* when the X11 backend translates W_View.attribs into XSetWindowAttributes
* at the XCreateWindow boundary. Defined here without an X11 dep so
* shared widget code can still set these flags on views. */
#ifndef CWBackPixmap
# define CWBackPixmap (1L<<0)
# define CWBackPixel (1L<<1)
# define CWBorderPixmap (1L<<2)
# define CWBorderPixel (1L<<3)
# define CWBitGravity (1L<<4)
# define CWWinGravity (1L<<5)
# define CWBackingStore (1L<<6)
# define CWBackingPlanes (1L<<7)
# define CWBackingPixel (1L<<8)
# define CWOverrideRedirect (1L<<9)
# define CWSaveUnder (1L<<10)
# define CWEventMask (1L<<11)
# define CWDontPropagate (1L<<12)
# define CWColormap (1L<<13)
# define CWCursor (1L<<14)
#endif
/* ------------------------------------------------------------------ */
/* Event-mask bits — used by W_EventBackend.check_mask matching. */
/* Values match X11's WM_EVMASK_KEY_PRESS..WM_EVMASK_VISIBILITY_CHANGE layout. */

View File

@ -2,8 +2,6 @@
#include "WINGsP.h"
#include "wconfig.h"
#include <X11/Xlocale.h>
_WINGsConfiguration WINGsConfiguration;
#define SYSTEM_FONT "sans serif"

View File

@ -566,23 +566,6 @@ WMScreen *WMOpenScreen(const char *display)
return NULL;
}
WMScreen *WMCreateSimpleApplicationScreen(Display * display)
{
WMScreen *scr;
scr = WMCreateScreen(display, DefaultScreen(display));
scr->aflags.hasAppIcon = 0;
scr->aflags.simpleApplication = 1;
return scr;
}
WMScreen *WMCreateScreen(Display * display, int screen)
{
return WMCreateScreenWithRContext(display, screen, RCreateContext(display, screen, NULL));
}
/*
* W_screen_next_kind — communicates which widget backends the next
* WMCreateScreenWithRContext call should install. Set by the platform
@ -629,7 +612,10 @@ WMScreen *WMCreateScreenWithRContext(Display * display, int screen, RContext * c
scrPtr->depth = context ? context->depth : 32;
scrPtr->visual = context ? context->visual : NULL;
scrPtr->colormap = context ? context->cmap : 0;
scrPtr->rootWin = display ? RootWindow(display, screen) : WM_NATIVE_NONE;
/* RContext->drawable is set to RootWindow() by RCreateContext (X11)
* or 0 by RCreateContextWayland — use it directly so this file
* doesn't need the X11 RootWindow() macro. */
scrPtr->rootWin = context ? context->drawable : WM_NATIVE_NONE;
scrPtr->fontCache = WMCreateHashTable(WMStringPointerHashCallbacks);

View File

@ -213,6 +213,32 @@ void W_X11PlatformInit(W_Screen *scrPtr)
W_InitApplication(scrPtr);
}
/*
* WMCreateScreen — public API: open a WINGs screen on an existing X11
* Display. Lives in the X11 backend file because it directly creates
* an X11 RContext via RCreateContext(). Wayland callers should use
* WMOpenScreen() instead.
*/
WMScreen *WMCreateScreen(Display * display, int screen)
{
return WMCreateScreenWithRContext(display, screen,
RCreateContext(display, screen, NULL));
}
/*
* WMCreateSimpleApplicationScreen — public API: like WMCreateScreen
* but defaults to the X server's default screen and marks the screen
* as a simple (no app-icon) application. X11-only.
*/
WMScreen *WMCreateSimpleApplicationScreen(Display * display)
{
WMScreen *scr = WMCreateScreen(display, DefaultScreen(display));
if (!scr) return NULL;
scr->aflags.hasAppIcon = 0;
scr->aflags.simpleApplication = 1;
return scr;
}
/*
* W_X11OpenDisplay — open the X11 display and return a populated WMScreen.
*

View File

@ -68,7 +68,7 @@ static void drawLeftMarker(Ruler * rPtr)
W_Screen *scr = rPtr->view->screen;
const W_RenderBackend *R = scr->renderBackend;
void *rctx = scr->renderBackendCtx;
XPoint points[4];
WMShortPoint points[4];
int xpos = (rPtr->flags.whichMarker == 1 ? rPtr->motion : rPtr->margins.left);
R->draw_line(rctx, (WMDrawable)rPtr->drawBuffer, rPtr->fg, xpos, 8, xpos, 22);
@ -88,7 +88,7 @@ static void drawRightMarker(Ruler * rPtr)
W_Screen *scr = rPtr->view->screen;
const W_RenderBackend *R = scr->renderBackend;
void *rctx = scr->renderBackendCtx;
XPoint points[4];
WMShortPoint points[4];
int xpos = (rPtr->flags.whichMarker == 2 ? rPtr->motion : rPtr->margins.right);
R->draw_line(rctx, (WMDrawable)rPtr->drawBuffer, rPtr->fg, xpos, 8, xpos, 22);
@ -120,7 +120,7 @@ static void drawBodyMarker(Ruler * rPtr)
W_Screen *scr = rPtr->view->screen;
const W_RenderBackend *R = scr->renderBackend;
void *rctx = scr->renderBackendCtx;
XPoint points[4];
WMShortPoint points[4];
int xpos = ((rPtr->flags.whichMarker == 4 || rPtr->flags.whichMarker == 6) ?
rPtr->motion : rPtr->margins.body);

View File

@ -193,3 +193,18 @@ WMScreen *W_X11OpenDisplay(const char *display)
wwarning(_("WINGs built without X11 backend; cannot open X11 display"));
return NULL;
}
WMScreen *WMCreateScreen(Display *display, int screen)
{
(void)display; (void)screen;
wwarning(_("WINGs built without X11 backend; WMCreateScreen unavailable"));
return NULL;
}
WMScreen *WMCreateSimpleApplicationScreen(Display *display)
{
(void)display;
wwarning(_("WINGs built without X11 backend; "
"WMCreateSimpleApplicationScreen unavailable"));
return NULL;
}

View File

@ -542,7 +542,7 @@ static void drawTab(TabView * tPtr, WMDrawable d, int x, int y, unsigned width,
const W_RenderBackend *R = scr->renderBackend;
void *rctx = scr->renderBackendCtx;
WMColor *white_c = selected ? scr->white : tPtr->lightGray;
XPoint trap[8];
WMShortPoint trap[8];
trap[0].x = x + (selected ? 0 : 1);
trap[0].y = y + height - (selected ? 0 : 1);

View File

@ -274,7 +274,7 @@ static int newMargin(Text * tPtr, WMRulerMargins * margins)
return n;
}
static Bool sectionWasSelected(Text * tPtr, TextBlock * tb, XRectangle * rect, int s)
static Bool sectionWasSelected(Text * tPtr, TextBlock * tb, WMShortRect * rect, int s)
{
unsigned short i, w, lw, selected = False, extend = False;
myRect sel;
@ -712,7 +712,7 @@ static void paintText(Text * tPtr)
}
if (tPtr->flags.ownsSelection) {
XRectangle rect;
WMShortRect rect;
if (sectionWasSelected(tPtr, tb, &rect, s)) {
tb->selected = True;
@ -781,7 +781,7 @@ static void paintText(Text * tPtr)
}
if (tPtr->flags.ownsSelection) {
XRectangle rect;
WMShortRect rect;
if (sectionWasSelected(tPtr, tb, &rect, 0)) {
WMDrawable d = (0 && tb->object ?
@ -872,10 +872,11 @@ static void mouseOverObject(Text * tPtr, int x, int y)
tPtr->view->attribs.cursor = (result ? tPtr->view->screen->defaultCursor : tPtr->view->screen->textCursor);
{
XSetWindowAttributes attribs;
attribs.cursor = tPtr->view->attribs.cursor;
/* The cursor is already the backend-neutral attribute — pass
* directly to viewBackend->set_cursor. */
tPtr->view->screen->viewBackend->set_cursor(
tPtr->view->screen->viewBackendCtx, tPtr->view, attribs.cursor);
tPtr->view->screen->viewBackendCtx, tPtr->view,
tPtr->view->attribs.cursor);
}
}

View File

@ -749,6 +749,40 @@ AS_IF([test "x$enable_x11_backend" = "xyes"],
AM_CONDITIONAL([USE_X11_BACKEND], [test "x$enable_x11_backend" = "xyes"])
dnl X11 support inside libwraster (wrlib)
dnl =====================================
dnl Default: same as --enable-x11-backend. When disabled, libwraster
dnl is built without libX11 / libXpm / libXmu / libXext deps; all the
dnl X11-using files (context.c, convert.c, convert_x11.c, xpixmap.c,
dnl xutil.c, load_xpm.c) are excluded and replaced by empty stubs in
dnl wstubs_no_x11.c. This is what allows libWINGs.so to truly link
dnl with no X11 transitive deps in pure-Wayland mode.
dnl
dnl Forcing --enable-x11-wraster while --disable-x11-backend is allowed
dnl (a wraster consumer can still want X11 image conversion); forcing
dnl --disable-x11-wraster while --enable-x11-backend is rejected (the
dnl WINGs X11 backend depends on X11 image conversion paths).
m4_divert_push([INIT_PREPARE])dnl
AC_ARG_ENABLE([x11-wraster],
[AS_HELP_STRING([--disable-x11-wraster],
[build libwraster without X11 image-conversion path @<:@default=same as --enable-x11-backend@:>@])],
[AS_CASE(["$enableval"],
[yes|no], [],
[AC_MSG_ERROR([bad value $enableval for --enable-x11-wraster])])],
[enable_x11_wraster=$enable_x11_backend])
m4_divert_pop([INIT_PREPARE])dnl
AS_IF([test "x$enable_x11_backend" = "xyes" -a "x$enable_x11_wraster" = "xno"],
[AC_MSG_ERROR([--disable-x11-wraster requires --disable-x11-backend])])
AS_IF([test "x$enable_x11_wraster" = "xyes"],
[AC_DEFINE([USE_X11_WRASTER], [1],
[Define to 1 to build wrlib with the X11 image-conversion path])
supported_core="$supported_core X11Wraster"],
[unsupported="$unsupported X11Wraster"])
AM_CONDITIONAL([USE_X11_WRASTER], [test "x$enable_x11_wraster" = "xyes"])
dnl Math library
dnl ============
dnl libWINGS uses math functions, check whether usage requires linking
@ -803,6 +837,20 @@ AC_ARG_ENABLE([pango],
m4_divert_pop([INIT_PREPARE])dnl
WM_CHECK_LIBPANGO
dnl WINGS_PANGO_LIBS_NO_XFT — PANGO_LIBS with the Xft variants stripped.
dnl Used by WINGs/Makefile.am when the WINGs X11 backend is disabled, so
dnl libWINGs.so doesn't transitively pull libXft (which links libX11).
dnl The Wayland font backend uses pangoft2 / pangocairo paths, neither
dnl of which needs Xft.
WINGS_PANGO_LIBS_NO_XFT=""
for wm_pango_lib in $PANGO_LIBS; do
case "$wm_pango_lib" in
-lpangoxft-*|-lXft) ;;
*) WINGS_PANGO_LIBS_NO_XFT="$WINGS_PANGO_LIBS_NO_XFT $wm_pango_lib" ;;
esac
done
AC_SUBST([WINGS_PANGO_LIBS_NO_XFT])
dnl pixman-1 — used by WINGs Wayland font backend (wfont_wl.c)
PKG_CHECK_MODULES([PIXMAN], [pixman-1],
[AC_SUBST([PIXMAN_LIBS])
@ -944,6 +992,18 @@ AC_SUBST(HEADER_SEARCH_PATH)
AC_SUBST(GFXLIBS)
dnl WRASTER_GFXLIBS_NO_XPM — GFXLIBS with -lXpm filtered out. Used by
dnl wrlib/Makefile.am when --disable-x11-wraster, where the only XPM
dnl loader compiled in is the libXpm-free load_xpm_normalized.c.
WRASTER_GFXLIBS_NO_XPM=""
for wm_gfx_lib in $GFXLIBS; do
case "$wm_gfx_lib" in
-lXpm|-lXpm-*) ;;
*) WRASTER_GFXLIBS_NO_XPM="$WRASTER_GFXLIBS_NO_XPM $wm_gfx_lib" ;;
esac
done
AC_SUBST([WRASTER_GFXLIBS_NO_XPM])
AC_SUBST(ICONEXT)
AM_CONDITIONAL([ICON_EXT_XPM], [test "x$ICONEXT" = "xxpm"])
AM_CONDITIONAL([ICON_EXT_TIFF], [test "x$ICONEXT" = "xtiff"])

View File

@ -28,6 +28,16 @@
#include <limits.h>
#include <WINGs/WINGs.h>
/* The wmaker compositor uses X11 types (XContext, XFontStruct, XColor,
* IconicState, etc.) extensively in its headers and sources, regardless
* of whether the compositor's runtime backend is X11 or Wayland. Bring
* in the X11 headers explicitly so we don't depend on WINGs.h to do it
* transitively (which it no longer does once libWINGs has been split). */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <X11/Xatom.h>
/* class codes */
typedef enum {

View File

@ -23,6 +23,7 @@ endif
BUILT_SOURCES = wraster.h
nodist_include_HEADERS = wraster.h
# Backend-neutral / shared sources (always compiled).
libwraster_la_SOURCES = \
imgformat.h \
raster.c \
@ -32,13 +33,10 @@ libwraster_la_SOURCES = \
load.c \
save.c \
gradient.c \
xpixmap.c \
convert.h \
convert.c \
convert_funcs.h \
convert_x11.c \
convert_wl.c \
context.c \
context_wl.c \
misc.c \
scale.c \
scale.h \
@ -48,10 +46,26 @@ libwraster_la_SOURCES = \
convolve.c \
save_xpm.c \
wr_i18n.h \
xutil.c \
xutil.h \
load_ppm.c
# X11 conversion path: image-to-XImage converters, X11 context init,
# X11 pixmap helpers, XShm-aware XImage utilities, and the libXpm-based
# loader (which uses X11 colormaps). Excluded by --disable-x11-wraster.
if USE_X11_WRASTER
libwraster_la_SOURCES += \
context.c \
convert.c \
convert_x11.c \
xpixmap.c \
xutil.c \
xutil.h
else
# Empty stubs for the public wraster API symbols that normally come
# from the X11 path, so consumers that link libwraster but never use
# the X11 functions resolve cleanly.
libwraster_la_SOURCES += wstubs_no_x11.c
endif
if USE_GIF
libwraster_la_SOURCES += load_gif.c
endif
@ -71,8 +85,14 @@ libwraster_la_SOURCES += load_tiff.c
endif
if USE_XPM
if USE_X11_WRASTER
libwraster_la_SOURCES += load_xpm.c load_xpm_normalized.c
else
# load_xpm.c uses libXpm + X11 colormaps — only compile when X11
# wraster path is enabled. The X11-free normalized loader stays.
libwraster_la_SOURCES += load_xpm_normalized.c
endif
else
libwraster_la_SOURCES += load_xpm_normalized.c
endif
@ -87,7 +107,18 @@ endif
AM_CFLAGS = @MAGICKFLAGS@
AM_CPPFLAGS = $(DFLAGS) @HEADER_SEARCH_PATH@ $(PIXMAN_CFLAGS)
libwraster_la_LIBADD = @LIBRARY_SEARCH_PATH@ @GFXLIBS@ @MAGICKLIBS@ @XLIBS@ @LIBXMU@ -lm
if USE_X11_WRASTER
X11_WRASTER_LIBS = @XLIBS@ @LIBXMU@
WRASTER_GFXLIBS = @GFXLIBS@
else
X11_WRASTER_LIBS =
# libXpm pulls in libX11; the X11-free build uses load_xpm_normalized.c
# (a hand-written XPM parser) so libXpm isn't needed. configure.ac
# provides WRASTER_GFXLIBS_NO_XPM as GFXLIBS with -lXpm stripped.
WRASTER_GFXLIBS = @WRASTER_GFXLIBS_NO_XPM@
endif
libwraster_la_LIBADD = @LIBRARY_SEARCH_PATH@ $(WRASTER_GFXLIBS) @MAGICKLIBS@ $(X11_WRASTER_LIBS) -lm
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = wrlib.pc
@ -100,13 +131,14 @@ wrlib.pc: Makefile
@echo 'Description: Image manipulation and conversion library' >> $@
@echo 'Version: $(VERSION)' >> $@
@echo 'Libs: $(lib_search_path) -lwraster' >> $@
@echo 'Libs.private: $(GFXLIBS) $(MAGICKLIBS) $(XLIBS) -lm' >> $@
@echo 'Libs.private: $(WRASTER_GFXLIBS) $(MAGICKLIBS) $(X11_WRASTER_LIBS) -lm' >> $@
@echo 'Cflags: $(inc_search_path)' >> $@
wraster.h: wraster.h.in $(top_builddir)/config.h
$(AM_V_GEN)$(top_srcdir)/script/replace-ac-keywords.sh \
--header "$(top_builddir)/config.h" \
--filter "USE_XSHM" \
--filter "USE_X11_WRASTER" \
-o $@ $<

View File

@ -721,52 +721,3 @@ static Bool bestContext(Display * dpy, int screen_number, RContext * context)
return True;
}
/*
* Create a minimal RContext for Wayland mode.
* No X11 connection needed — just sets up 32-bit TrueColor parameters
* so that RImage operations (load, scale, combine) work.
* RConvertImage will not work (returns 0) since there's no X11 drawable.
*/
RContext *RCreateContextWayland(int width, int height,
const RContextAttributes *attribs)
{
RContext *context;
RContextAttributes *attr;
context = malloc(sizeof(RContext));
if (!context) {
RErrorCode = RERR_NOMEMORY;
return NULL;
}
memset(context, 0, sizeof(RContext));
attr = malloc(sizeof(RContextAttributes));
if (!attr) {
free(context);
RErrorCode = RERR_NOMEMORY;
return NULL;
}
if (attribs)
*attr = *attribs;
else
memset(attr, 0, sizeof(RContextAttributes));
context->attribs = attr;
/* 32-bit ARGB TrueColor — matches pixman ARGB32 */
context->depth = 32;
context->vclass = TrueColor;
context->red_offset = 16;
context->green_offset = 8;
context->blue_offset = 0;
context->black = 0xFF000000;
context->white = 0xFFFFFFFF;
(void)width;
(void)height;
context->convert_image = wl_convert_image;
context->convert_image_mask = wl_convert_image_mask;
return context;
}

92
wrlib/context_wl.c Normal file
View File

@ -0,0 +1,92 @@
/* context_wl.c - Wayland-mode RContext creation
*
* Raster graphics library
*
* Copyright (c) 2025 Window Maker Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*/
/*
* Wayland-side of the wraster context API.
*
* RCreateContextWayland creates a minimal RContext suitable for
* RImage operations (load, scale, combine, gradient) without an X11
* connection. No XOpenDisplay, no XCreateGC — the convert_image
* vtable is wired to wl_convert_image (pixman_image_t output).
*
* Compiled unconditionally (lives in libwraster regardless of
* --enable-x11-wraster) since it has no X11 dependencies.
*
* RDestroyContext is in context.c when X11 wraster is enabled, and
* stubbed (free-only) in wstubs_no_x11.c otherwise.
*/
#define WRASTER_NO_XLIB
#include <config.h>
#include <stdlib.h>
#include <string.h>
#include "wraster.h"
#include "convert_funcs.h"
/* TrueColor visual class constant (matches X.h definition). Used by
* convert/draw paths to select the TrueColor branch. We hard-code it
* here so we don't need <X11/X.h> when X11 wraster is disabled. */
#ifndef TrueColor
# define TrueColor 4
#endif
RContext *RCreateContextWayland(int width, int height,
const RContextAttributes *attribs)
{
RContext *context;
RContextAttributes *attr;
context = malloc(sizeof(RContext));
if (!context) {
RErrorCode = RERR_NOMEMORY;
return NULL;
}
memset(context, 0, sizeof(RContext));
attr = malloc(sizeof(RContextAttributes));
if (!attr) {
free(context);
RErrorCode = RERR_NOMEMORY;
return NULL;
}
if (attribs)
*attr = *attribs;
else
memset(attr, 0, sizeof(RContextAttributes));
context->attribs = attr;
/* 32-bit ARGB TrueColor — matches pixman ARGB32. */
context->depth = 32;
context->vclass = TrueColor;
context->red_offset = 16;
context->green_offset = 8;
context->blue_offset = 0;
context->black = 0xFF000000;
context->white = 0xFFFFFFFF;
(void)width;
(void)height;
context->convert_image = wl_convert_image;
context->convert_image_mask = wl_convert_image_mask;
return context;
}

View File

@ -44,6 +44,23 @@
#define WRASTER_HEADER_VERSION 25
/* When wrlib is built with --disable-x11-wraster, the X11 image-
* conversion path (convert.c, convert_x11.c, xpixmap.c, xutil.c,
* context.c, load_xpm.c) is excluded from libwraster. In that build
* any consumer of this header would link-fail trying to use the X11
* APIs (RConvertImage etc.), and worse, would still drag in libX11
* transitively just from the include itself. So when the build
* defines USE_X11_WRASTER=0 (i.e. line not retained by the template
* processor), we force WRASTER_NO_XLIB on so consumers see only
* forward-declared opaque types and no <X11/Xlib.h> include.
*
* The `@!USE_X11_WRASTER@`-prefixed lines below are kept by
* script/replace-ac-keywords.sh ONLY when USE_X11_WRASTER is NOT
* defined in config.h. */
@!USE_X11_WRASTER@#ifndef WRASTER_NO_XLIB
@!USE_X11_WRASTER@#define WRASTER_NO_XLIB
@!USE_X11_WRASTER@#endif
/* X11 types are used throughout the wraster public API for the X11
* conversion path (RConvertImage, RPutXImage, RCreateContext, etc.).
* To allow Wayland-only consumers (WINGs Wayland-client backend) to
@ -77,6 +94,15 @@ typedef struct _XShmSegmentInfo XShmSegmentInfo;
#ifndef Bool
typedef int Bool;
#endif
#ifndef True
#define True 1
#endif
#ifndef False
#define False 0
#endif
#ifndef None
#define None 0L
#endif
#else
#include <X11/Xlib.h>
#include <X11/Xutil.h>

157
wrlib/wstubs_no_x11.c Normal file
View File

@ -0,0 +1,157 @@
/* wstubs_no_x11.c - empty implementations for the X11 wraster public API.
*
* Compiled only when --disable-x11-wraster is configured. The X11
* conversion path source files (context.c, convert.c, convert_x11.c,
* xpixmap.c, xutil.c, load_xpm.c) are excluded in that build; this
* file provides the public-API symbols they would otherwise export
* so consumer code that calls them (or references them but never
* executes the call, like load.c's IM_XPM branch) links cleanly.
*
* Behaviour: every stub returns failure-neutral values (NULL, 0,
* RERR_INTERNAL). Calling them in pure-Wayland mode is silent and
* non-crashing rather than an error abort, so applications that
* branch on context->dpy correctly skip past these paths anyway.
*
* Raster graphics library
*
* Copyright (c) 2025 Window Maker Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*/
#define WRASTER_NO_XLIB
#include <config.h>
#include <stdlib.h>
#include "wraster.h"
/* ------------------------------------------------------------------ */
/* Context (context.c) */
/* ------------------------------------------------------------------ */
RContext *RCreateContext(Display *dpy, int screen_number,
const RContextAttributes *attribs)
{
(void)dpy; (void)screen_number; (void)attribs;
RErrorCode = RERR_INTERNAL;
return NULL;
}
void RDestroyContext(RContext *context)
{
if (!context) return;
if (context->attribs) free(context->attribs);
if (context->colors) free(context->colors);
if (context->pixels) free(context->pixels);
free(context);
}
/* ------------------------------------------------------------------ */
/* Image conversion (convert.c, convert_x11.c) */
/* ------------------------------------------------------------------ */
int RConvertImage(RContext *context, RImage *image, Pixmap *pixmap)
{
/* Use the backend vtable installed by RCreateContextWayland. */
if (context && context->convert_image)
return context->convert_image(context, image, pixmap);
RErrorCode = RERR_INTERNAL;
return 0;
}
int RConvertImageMask(RContext *context, RImage *image,
Pixmap *pixmap, Pixmap *mask, int threshold)
{
if (context && context->convert_image_mask)
return context->convert_image_mask(context, image, pixmap, mask, threshold);
RErrorCode = RERR_INTERNAL;
return 0;
}
Bool RGetClosestXColor(RContext *context, const RColor *color, XColor *retColor)
{
(void)context; (void)color; (void)retColor;
RErrorCode = RERR_INTERNAL;
return 0;
}
/* ------------------------------------------------------------------ */
/* Drawable → RImage (xpixmap.c) */
/* ------------------------------------------------------------------ */
RImage *RCreateImageFromDrawable(RContext *context, Drawable drawable, Pixmap mask)
{
(void)context; (void)drawable; (void)mask;
RErrorCode = RERR_INTERNAL;
return NULL;
}
RImage *RCreateImageFromXImage(RContext *context, XImage *image, XImage *mask)
{
(void)context; (void)image; (void)mask;
RErrorCode = RERR_INTERNAL;
return NULL;
}
/* ------------------------------------------------------------------ */
/* RXImage utilities (xutil.c) */
/* ------------------------------------------------------------------ */
RXImage *RCreateXImage(RContext *context, int depth,
unsigned width, unsigned height)
{
(void)context; (void)depth; (void)width; (void)height;
RErrorCode = RERR_INTERNAL;
return NULL;
}
RXImage *RGetXImage(RContext *context, Drawable d, int x, int y,
unsigned width, unsigned height)
{
(void)context; (void)d; (void)x; (void)y; (void)width; (void)height;
RErrorCode = RERR_INTERNAL;
return NULL;
}
void RDestroyXImage(RContext *context, RXImage *ximage)
{
(void)context;
if (ximage) free(ximage);
}
void RPutXImage(RContext *context, Drawable d, GC gc, RXImage *ximage,
int src_x, int src_y, int dest_x, int dest_y,
unsigned width, unsigned height)
{
(void)context; (void)d; (void)gc; (void)ximage;
(void)src_x; (void)src_y; (void)dest_x; (void)dest_y;
(void)width; (void)height;
}
/* ------------------------------------------------------------------ */
/* XPM loading (load_xpm.c) */
/* ------------------------------------------------------------------ */
RImage *RGetImageFromXPMData(RContext *context, char **xpmData)
{
(void)context; (void)xpmData;
RErrorCode = RERR_BADFORMAT;
return NULL;
}
RImage *RLoadXPM(RContext *context, const char *file)
{
(void)context; (void)file;
RErrorCode = RERR_BADFORMAT;
return NULL;
}