wayland: Phase 29 — pixman SHM surface primitives

Add wm_shm_surface: a compositor-owned pixel buffer that bridges pixman
software rendering to the wlroots scene graph.

The struct embeds a wlr_buffer (wl_container_of compatible) so wlroots
can reference-count and GPU-upload the pixel data on demand via the
wlr_buffer_impl vtable (begin_data_ptr_access / end_data_ptr_access /
destroy).  A pixman_image_t wrapping the same malloc memory provides the
drawing API.

Four entry points:
  wm_shm_surface_create  — alloc + wlr_buffer_init + pixman_image_create
  wm_shm_surface_fill    — pixman_image_composite32(PIXMAN_OP_SRC, ...)
  wm_shm_surface_commit  — wlr_scene_buffer_create / set_position
  wm_shm_surface_destroy — scene node + wlr_buffer_drop (async free)

A 64×64 steel-blue (0xFF4080C0) test surface is committed to the root
scene node at (16,16) inside wl_screen_create_internals, proving the
pixman → wlr_scene_buffer upload pipeline works end-to-end.

Build fixes:
  - Add pixman-1 to PKG_CHECK_MODULES in configure.ac so -lpixman-1
    appears in WLROOTS_LIBS (linker was missing the symbol).
  - Add -I$(srcdir)/backend/wayland to AM_CPPFLAGS in Makefile.am so
    generated Wayland protocol headers are found during compilation.

Smoke test: PASS (all existing checks continue to pass; Phase 29 log
line "Phase 29 test surface committed" confirms the pipeline fires).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Levi Neely 2026-03-31 13:31:06 +02:00
parent 7018dac550
commit 1dde83e05e
5 changed files with 432 additions and 42 deletions

177
configure vendored
View File

@ -680,6 +680,10 @@ XFT_LIBS
XFT_CFLAGS
FCLIBS
LIBM
USE_WAYLAND_BACKEND_FALSE
USE_WAYLAND_BACKEND_TRUE
WLROOTS_LIBS
WLROOTS_CFLAGS
LIBXRANDR
LIBXINERAMA
LIBXMU
@ -880,6 +884,7 @@ enable_shape
enable_shm
enable_xinerama
enable_randr
enable_wayland_backend
enable_pango
enable_xpm
enable_png
@ -909,6 +914,8 @@ PKG_CONFIG_PATH
PKG_CONFIG_LIBDIR
LINGUAS
XMKMF
WLROOTS_CFLAGS
WLROOTS_LIBS
XFT_CFLAGS
XFT_LIBS
PANGO_CFLAGS
@ -1565,6 +1572,9 @@ Optional Features:
--enable-xinerama enable Xinerama extension support
--enable-randr enable RandR extension support (NOT recommended,
buggy)
--enable-wayland-backend
build the wlroots-based Wayland compositor backend
[default=auto]
--disable-pango disable Pango text layout support [default=auto]
--disable-xpm disable use of XPM pixmaps through libXpm
--disable-png disable PNG support through libpng
@ -1622,6 +1632,10 @@ Some influential environment variables:
LINGUAS list of language translations to support (I18N), use 'list' to
get the list of supported languages, default: none
XMKMF Path to xmkmf, Makefile generator for X Window System
WLROOTS_CFLAGS
C compiler flags for WLROOTS, overriding pkg-config
WLROOTS_LIBS
linker flags for WLROOTS, overriding pkg-config
XFT_CFLAGS C compiler flags for XFT, overriding pkg-config
XFT_LIBS linker flags for XFT, overriding pkg-config
PANGO_CFLAGS
@ -2614,6 +2628,18 @@ else
enable_randr=no
fi
# Check whether --enable-wayland-backend was given.
if test "${enable_wayland_backend+set}" = set; then :
enableval=$enable_wayland_backend; case "$enableval" in #(
yes|no|auto) :
;; #(
*) :
as_fn_error $? "bad value $enableval for --enable-wayland-backend" "$LINENO" 5 ;;
esac
else
enable_wayland_backend=auto
fi
# Check whether --enable-pango was given.
if test "${enable_pango+set}" = set; then :
enableval=$enable_pango; case $enableval in #(
@ -6048,7 +6074,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
lt_cv_deplibs_check_method=pass_all
;;
netbsd* | netbsdelf*-gnu)
netbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
else
@ -6410,7 +6436,7 @@ esac
fi
: ${AR=ar}
: ${AR_FLAGS=cr}
: ${AR_FLAGS=cru}
@ -6911,8 +6937,11 @@ _LT_EOF
test $ac_status = 0; }; then
# Now try to grab the symbols.
nlist=conftest.nm
$ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5
if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
(eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } && test -s "$nlist"; then
# Try sorting and uniquifying the output.
if sort "$nlist" | uniq > "$nlist"T; then
mv -f "$nlist"T "$nlist"
@ -8131,8 +8160,8 @@ int forced_loaded() { return 2;}
_LT_EOF
echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
$LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
echo "$AR cr libconftest.a conftest.o" >&5
$AR cr libconftest.a conftest.o 2>&5
echo "$AR cru libconftest.a conftest.o" >&5
$AR cru libconftest.a conftest.o 2>&5
echo "$RANLIB libconftest.a" >&5
$RANLIB libconftest.a 2>&5
cat > conftest.c << _LT_EOF
@ -8164,11 +8193,11 @@ $as_echo "$lt_cv_ld_force_load" >&6; }
# to the OS version, if on x86, and 10.4, the deployment
# target defaults to 10.4. Don't you love it?
case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
10.0,*86*-darwin8*|10.0,*-darwin[912]*)
10.0,*86*-darwin8*|10.0,*-darwin[91]*)
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
10.[012][,.]*)
_lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
10.*|11.*)
10.*)
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
esac
;;
@ -9123,12 +9152,6 @@ lt_prog_compiler_static=
lt_prog_compiler_pic='-KPIC'
lt_prog_compiler_static='-static'
;;
# flang / f18. f95 an alias for gfortran or flang on Debian
flang* | f18* | f95*)
lt_prog_compiler_wl='-Wl,'
lt_prog_compiler_pic='-fPIC'
lt_prog_compiler_static='-static'
;;
# icc used to be incompatible with GCC.
# ICC 10 doesn't accept -KPIC any more.
icc* | ifort*)
@ -9605,9 +9628,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
openbsd* | bitrig*)
with_gnu_ld=no
;;
linux* | k*bsd*-gnu | gnu*)
link_all_deplibs=no
;;
esac
ld_shlibs=yes
@ -9862,7 +9882,7 @@ _LT_EOF
fi
;;
netbsd* | netbsdelf*-gnu)
netbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
@ -10532,7 +10552,6 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
if test yes = "$lt_cv_irix_exported_symbol"; then
archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
fi
link_all_deplibs=no
else
archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@ -10554,7 +10573,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
esac
;;
netbsd* | netbsdelf*-gnu)
netbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else
@ -11669,18 +11688,6 @@ fi
dynamic_linker='GNU/Linux ld.so'
;;
netbsdelf*-gnu)
version_type=linux
need_lib_prefix=no
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
shlibpath_var=LD_LIBRARY_PATH
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
dynamic_linker='NetBSD ld.elf_so'
;;
netbsd*)
version_type=sunos
need_lib_prefix=no
@ -17633,6 +17640,107 @@ fi
if test "x$enable_wayland_backend" != "xno"; then :
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for wlroots >= 0.15 wayland-server xkbcommon pixman-1" >&5
$as_echo_n "checking for wlroots >= 0.15 wayland-server xkbcommon pixman-1... " >&6; }
if test -n "$WLROOTS_CFLAGS"; then
pkg_cv_WLROOTS_CFLAGS="$WLROOTS_CFLAGS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"wlroots >= 0.15 wayland-server xkbcommon pixman-1\""; } >&5
($PKG_CONFIG --exists --print-errors "wlroots >= 0.15 wayland-server xkbcommon pixman-1") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_WLROOTS_CFLAGS=`$PKG_CONFIG --cflags "wlroots >= 0.15 wayland-server xkbcommon pixman-1" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test -n "$WLROOTS_LIBS"; then
pkg_cv_WLROOTS_LIBS="$WLROOTS_LIBS"
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"wlroots >= 0.15 wayland-server xkbcommon pixman-1\""; } >&5
($PKG_CONFIG --exists --print-errors "wlroots >= 0.15 wayland-server xkbcommon pixman-1") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_WLROOTS_LIBS=`$PKG_CONFIG --libs "wlroots >= 0.15 wayland-server xkbcommon pixman-1" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test $pkg_failed = yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi
if test $_pkg_short_errors_supported = yes; then
WLROOTS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "wlroots >= 0.15 wayland-server xkbcommon pixman-1" 2>&1`
else
WLROOTS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "wlroots >= 0.15 wayland-server xkbcommon pixman-1" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$WLROOTS_PKG_ERRORS" >&5
have_wlroots=no
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
have_wlroots=no
else
WLROOTS_CFLAGS=$pkg_cv_WLROOTS_CFLAGS
WLROOTS_LIBS=$pkg_cv_WLROOTS_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
have_wlroots=yes
fi
if test "x$have_wlroots" = "xyes"; then :
$as_echo "#define USE_WAYLAND_BACKEND 1" >>confdefs.h
WLROOTS_CFLAGS="$WLROOTS_CFLAGS -DWLR_USE_UNSTABLE"
supported_core="$supported_core WaylandBackend"
else
if test "x$enable_wayland_backend" = "xyes"; then :
as_fn_error $? "wlroots >= 0.15, wayland-server, or xkbcommon not found" "$LINENO" 5
fi
unsupported="$unsupported WaylandBackend"
fi
else
have_wlroots=no
unsupported="$unsupported WaylandBackend"
fi
if test "x$have_wlroots" = "xyes"; then
USE_WAYLAND_BACKEND_TRUE=
USE_WAYLAND_BACKEND_FALSE='#'
else
USE_WAYLAND_BACKEND_TRUE='#'
USE_WAYLAND_BACKEND_FALSE=
fi
ac_fn_c_check_header_mongrel "$LINENO" "math.h" "ac_cv_header_math_h" "$ac_includes_default"
if test "x$ac_cv_header_math_h" = xyes; then :
@ -19013,6 +19121,10 @@ if test -z "${USE_DOCK_XDND_TRUE}" && test -z "${USE_DOCK_XDND_FALSE}"; then
as_fn_error $? "conditional \"USE_DOCK_XDND\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${USE_WAYLAND_BACKEND_TRUE}" && test -z "${USE_WAYLAND_BACKEND_FALSE}"; then
as_fn_error $? "conditional \"USE_WAYLAND_BACKEND\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${USE_XPM_TRUE}" && test -z "${USE_XPM_FALSE}"; then
as_fn_error $? "conditional \"USE_XPM\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@ -20674,6 +20786,7 @@ See \`config.log' for more details" "$LINENO" 5; }
cat <<_LT_EOF >> "$cfgfile"
#! $SHELL
# Generated automatically by $as_me ($PACKAGE) $VERSION
# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
# Provide generalized library-building support services.

View File

@ -665,7 +665,7 @@ m4_divert_pop([INIT_PREPARE])dnl
AS_IF([test "x$enable_wayland_backend" != "xno"],
[PKG_CHECK_MODULES([WLROOTS],
[wlroots >= 0.15 wayland-server xkbcommon],
[wlroots >= 0.15 wayland-server xkbcommon pixman-1],
[have_wlroots=yes],
[have_wlroots=no])
AS_IF([test "x$have_wlroots" = "xyes"],

View File

@ -172,6 +172,7 @@ AM_CFLAGS = @PANGO_CFLAGS@ @WLROOTS_CFLAGS@
AM_CPPFLAGS = $(DFLAGS) \
-I$(top_builddir)/wrlib \
-I$(top_srcdir)/WINGs -I$(top_builddir)/WINGs \
-I$(srcdir)/backend/wayland \
@HEADER_SEARCH_PATH@

View File

@ -95,7 +95,11 @@ bin_PROGRAMS = wmaker$(EXEEXT)
@WM_OSDEP_DARWIN_TRUE@am__append_4 = osdep_darwin.c
@WM_OSDEP_LINUX_TRUE@am__append_5 = osdep_linux.c
@WM_OSDEP_GENERIC_TRUE@am__append_6 = osdep_stub.c
@USE_NESTED_FUNC_TRUE@am__append_7 = misc.c \
@USE_WAYLAND_BACKEND_TRUE@am__append_7 = \
@USE_WAYLAND_BACKEND_TRUE@ backend/wayland/wl_backend.h \
@USE_WAYLAND_BACKEND_TRUE@ backend/wayland/wl_backend.c
@USE_NESTED_FUNC_TRUE@am__append_8 = misc.c \
@USE_NESTED_FUNC_TRUE@ xmodifier.c
subdir = src
@ -148,8 +152,9 @@ am__wmaker_SOURCES_DIST = GNUstep.h WindowMaker.h actions.c actions.h \
wcore.h wdefaults.c wdefaults.h window.c window.h winmenu.c \
winmenu.h winspector.h winspector.c wmspec.h wmspec.c \
workspace.c workspace.h wsmap.c wsmap.h xdnd.c motif.h motif.c \
osdep_bsd.c osdep_darwin.c osdep_linux.c osdep_stub.c misc.c \
xmodifier.c
osdep_bsd.c osdep_darwin.c osdep_linux.c osdep_stub.c \
backend/wayland/wl_backend.h backend/wayland/wl_backend.c \
misc.c xmodifier.c
am__dirstamp = $(am__leading_dot)dirstamp
@USE_DOCK_XDND_TRUE@am__objects_1 = xdnd.$(OBJEXT)
@USE_MWM_HINTS_TRUE@am__objects_2 = motif.$(OBJEXT)
@ -157,7 +162,8 @@ am__dirstamp = $(am__leading_dot)dirstamp
@WM_OSDEP_DARWIN_TRUE@am__objects_4 = osdep_darwin.$(OBJEXT)
@WM_OSDEP_LINUX_TRUE@am__objects_5 = osdep_linux.$(OBJEXT)
@WM_OSDEP_GENERIC_TRUE@am__objects_6 = osdep_stub.$(OBJEXT)
@USE_NESTED_FUNC_TRUE@am__objects_7 = misc.$(OBJEXT) \
@USE_WAYLAND_BACKEND_TRUE@am__objects_7 = backend/wayland/wl_backend.$(OBJEXT)
@USE_NESTED_FUNC_TRUE@am__objects_8 = misc.$(OBJEXT) \
@USE_NESTED_FUNC_TRUE@ xmodifier.$(OBJEXT)
am_wmaker_OBJECTS = actions.$(OBJEXT) appicon.$(OBJEXT) \
application.$(OBJEXT) appmenu.$(OBJEXT) balloon.$(OBJEXT) \
@ -180,7 +186,8 @@ am_wmaker_OBJECTS = actions.$(OBJEXT) appicon.$(OBJEXT) \
winmenu.$(OBJEXT) winspector.$(OBJEXT) wmspec.$(OBJEXT) \
workspace.$(OBJEXT) wsmap.$(OBJEXT) $(am__objects_1) \
$(am__objects_2) $(am__objects_3) $(am__objects_4) \
$(am__objects_5) $(am__objects_6) $(am__objects_7)
$(am__objects_5) $(am__objects_6) $(am__objects_7) \
$(am__objects_8)
@USE_NESTED_FUNC_FALSE@nodist_wmaker_OBJECTS = misc.hack_nf.$(OBJEXT) \
@USE_NESTED_FUNC_FALSE@ xmodifier.hack_nf.$(OBJEXT)
wmaker_OBJECTS = $(am_wmaker_OBJECTS) $(nodist_wmaker_OBJECTS)
@ -233,7 +240,8 @@ am__depfiles_remade = ./$(DEPDIR)/actions.Po ./$(DEPDIR)/appicon.Po \
./$(DEPDIR)/workspace.Po ./$(DEPDIR)/wsmap.Po \
./$(DEPDIR)/xdnd.Po ./$(DEPDIR)/xinerama.Po \
./$(DEPDIR)/xmodifier.Po ./$(DEPDIR)/xmodifier.hack_nf.Po \
./$(DEPDIR)/xutil.Po backend/x11/$(DEPDIR)/x11_backend.Po \
./$(DEPDIR)/xutil.Po backend/wayland/$(DEPDIR)/wl_backend.Po \
backend/x11/$(DEPDIR)/x11_backend.Po \
backend/x11/$(DEPDIR)/x11_event.Po \
backend/x11/$(DEPDIR)/x11_monitor.Po \
backend/x11/$(DEPDIR)/x11_props.Po
@ -378,6 +386,8 @@ VERSION = @VERSION@
WEB_REPO_ROOT = @WEB_REPO_ROOT@
WINGSMOFILES = @WINGSMOFILES@
WINGS_VERSION = @WINGS_VERSION@
WLROOTS_CFLAGS = @WLROOTS_CFLAGS@
WLROOTS_LIBS = @WLROOTS_LIBS@
WMAKERMOFILES = @WMAKERMOFILES@
WPREFSMOFILES = @WPREFSMOFILES@
WRASTERMOFILES = @WRASTERMOFILES@
@ -484,15 +494,17 @@ wmaker_SOURCES = GNUstep.h WindowMaker.h actions.c actions.h appicon.c \
winmenu.h winspector.h winspector.c wmspec.h wmspec.c \
workspace.c workspace.h wsmap.c wsmap.h $(am__append_1) \
$(am__append_2) $(am__append_3) $(am__append_4) \
$(am__append_5) $(am__append_6) $(am__append_7)
$(am__append_5) $(am__append_6) $(am__append_7) \
$(am__append_8)
@USE_NESTED_FUNC_FALSE@nodist_wmaker_SOURCES = misc.hack_nf.c \
@USE_NESTED_FUNC_FALSE@ xmodifier.hack_nf.c
@USE_NESTED_FUNC_FALSE@CLEANFILES = $(nodist_wmaker_SOURCES)
AM_CFLAGS = @PANGO_CFLAGS@
AM_CFLAGS = @PANGO_CFLAGS@ @WLROOTS_CFLAGS@
AM_CPPFLAGS = $(DFLAGS) \
-I$(top_builddir)/wrlib \
-I$(top_srcdir)/WINGs -I$(top_builddir)/WINGs \
-I$(srcdir)/backend/wayland \
@HEADER_SEARCH_PATH@
wmaker_LDADD = \
@ -503,6 +515,7 @@ wmaker_LDADD = \
@LIBXRANDR@ \
@LIBXINERAMA@ \
@XLIBS@ \
@WLROOTS_LIBS@ \
@LIBM@ \
@INTLIBS@
@ -522,7 +535,51 @@ am__v_CHKOPTS_1 =
WM_POLICY_CLEAN_FILES = \
$(srcdir)/xinerama.c \
$(srcdir)/stacking.c \
$(srcdir)/placement.c
$(srcdir)/placement.c \
$(srcdir)/cycling.c \
$(srcdir)/workspace.c \
$(srcdir)/actions.c \
$(srcdir)/moveres.c \
$(srcdir)/window.c \
$(srcdir)/screen.c \
$(srcdir)/event.c \
$(srcdir)/colormap.c \
$(srcdir)/switchmenu.c \
$(srcdir)/superfluous.c \
$(srcdir)/balloon.c \
$(srcdir)/wsmap.c \
$(srcdir)/switchpanel.c \
$(srcdir)/properties.c \
$(srcdir)/wmspec.c \
$(srcdir)/application.c \
$(srcdir)/appicon.c \
$(srcdir)/dock.c \
$(srcdir)/dockedapp.c \
$(srcdir)/icon.c \
$(srcdir)/motif.c \
$(srcdir)/pixmap.c \
$(srcdir)/resources.c \
$(srcdir)/session.c \
$(srcdir)/shutdown.c \
$(srcdir)/texture.c \
$(srcdir)/winspector.c \
$(srcdir)/xdnd.c \
$(srcdir)/rootmenu.c \
$(srcdir)/xutil.c \
$(srcdir)/misc.c \
$(srcdir)/winmenu.c \
$(srcdir)/appmenu.c \
$(srcdir)/monitor.c \
$(srcdir)/usermenu.c \
$(srcdir)/main.c \
$(srcdir)/defaults.c \
$(srcdir)/dialog.c \
$(srcdir)/menu.c \
$(srcdir)/wdefaults.c \
$(srcdir)/xmodifier.c \
$(srcdir)/framewin.c \
$(srcdir)/client.c \
$(srcdir)/startup.c
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
@ -623,6 +680,14 @@ backend/x11/x11_props.$(OBJEXT): backend/x11/$(am__dirstamp) \
backend/x11/$(DEPDIR)/$(am__dirstamp)
backend/x11/x11_monitor.$(OBJEXT): backend/x11/$(am__dirstamp) \
backend/x11/$(DEPDIR)/$(am__dirstamp)
backend/wayland/$(am__dirstamp):
@$(MKDIR_P) backend/wayland
@: > backend/wayland/$(am__dirstamp)
backend/wayland/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) backend/wayland/$(DEPDIR)
@: > backend/wayland/$(DEPDIR)/$(am__dirstamp)
backend/wayland/wl_backend.$(OBJEXT): backend/wayland/$(am__dirstamp) \
backend/wayland/$(DEPDIR)/$(am__dirstamp)
wmaker$(EXEEXT): $(wmaker_OBJECTS) $(wmaker_DEPENDENCIES) $(EXTRA_wmaker_DEPENDENCIES)
@rm -f wmaker$(EXEEXT)
@ -630,6 +695,7 @@ wmaker$(EXEEXT): $(wmaker_OBJECTS) $(wmaker_DEPENDENCIES) $(EXTRA_wmaker_DEPENDE
mostlyclean-compile:
-rm -f *.$(OBJEXT)
-rm -f backend/wayland/*.$(OBJEXT)
-rm -f backend/x11/*.$(OBJEXT)
distclean-compile:
@ -691,6 +757,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmodifier.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmodifier.hack_nf.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xutil.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@backend/wayland/$(DEPDIR)/wl_backend.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@backend/x11/$(DEPDIR)/x11_backend.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@backend/x11/$(DEPDIR)/x11_event.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@backend/x11/$(DEPDIR)/x11_monitor.Po@am__quote@ # am--include-marker
@ -854,6 +921,8 @@ clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-rm -f backend/wayland/$(DEPDIR)/$(am__dirstamp)
-rm -f backend/wayland/$(am__dirstamp)
-rm -f backend/x11/$(DEPDIR)/$(am__dirstamp)
-rm -f backend/x11/$(am__dirstamp)
@ -922,6 +991,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/xmodifier.Po
-rm -f ./$(DEPDIR)/xmodifier.hack_nf.Po
-rm -f ./$(DEPDIR)/xutil.Po
-rm -f backend/wayland/$(DEPDIR)/wl_backend.Po
-rm -f backend/x11/$(DEPDIR)/x11_backend.Po
-rm -f backend/x11/$(DEPDIR)/x11_event.Po
-rm -f backend/x11/$(DEPDIR)/x11_monitor.Po
@ -1027,6 +1097,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/xmodifier.Po
-rm -f ./$(DEPDIR)/xmodifier.hack_nf.Po
-rm -f ./$(DEPDIR)/xutil.Po
-rm -f backend/wayland/$(DEPDIR)/wl_backend.Po
-rm -f backend/x11/$(DEPDIR)/x11_backend.Po
-rm -f backend/x11/$(DEPDIR)/x11_event.Po
-rm -f backend/x11/$(DEPDIR)/x11_monitor.Po

View File

@ -129,6 +129,8 @@
#include <wlr/backend/multi.h> /* Phase 18: multi-backend */
#include <wlr/types/wlr_scene.h> /* Phase 18: scene graph compositing */
#include <wlr/render/allocator.h> /* Phase 18: buffer allocator */
#include <wlr/types/wlr_buffer.h> /* Phase 29+: WM-owned SHM surface buffers */
#include <pixman.h> /* Phase 29+: software pixel rendering */
#include <wlr/types/wlr_cursor.h> /* Phase 23: hardware cursor tracking */
#include <wlr/types/wlr_xcursor_manager.h> /* Phase 23: xcursor theme */
#include <wlr/types/wlr_data_device.h> /* Phase 25: clipboard / selection */
@ -2361,6 +2363,198 @@ wl_event_loop_terminate(void)
}
}
/* ================================================================== */
/* Phase 29: WM-owned SHM surfaces (pixman rendering → wlroots scene) */
/* ================================================================== */
/*
* wm_shm_surface — a compositor-owned pixel buffer that plugs into the
* wlroots scene graph.
*
* Memory layout:
* wm_shm_surface embeds a wlr_buffer so wlroots can reference-count and
* upload its pixels as a GPU texture. The pixel array (ARGB8888) is
* malloc'd and wrapped by a pixman_image_t for drawing.
*
* Lifecycle:
* wm_shm_surface_create — alloc + pixman init
* wm_shm_surface_fill — draw into the pixman image (no upload yet)
* wm_shm_surface_commit — create/reposition the wlr_scene_buffer node
* wm_shm_surface_destroy — tear down scene node + drop wlr_buffer ref
* (shm_buf_destroy frees memory when ref = 0)
*
* Update model (Phase 29): surfaces are static after first commit.
* A re-draw path (drop + recreate scene node) will be added in Phase 30
* once the dock and title-bar code drives it.
*/
struct wm_shm_surface {
/* wlr_buffer interface — MUST be first so wl_container_of works */
struct wlr_buffer wlr_buf;
/* Pixel store */
uint32_t *data; /* ARGB8888, row-major */
int width;
int height;
size_t stride; /* bytes per row = width * 4 */
/* pixman drawing surface wrapping data[] */
pixman_image_t *image;
/* scene graph presence */
struct wlr_scene_buffer *scene_buf; /* NULL until first commit */
};
/* ---------- wlr_buffer implementation -------------------------------- */
static void
shm_buf_destroy(struct wlr_buffer *buf)
{
struct wm_shm_surface *s = wl_container_of(buf, s, wlr_buf);
if (s->image)
pixman_image_unref(s->image);
free(s->data);
free(s);
}
static bool
shm_buf_begin_data_ptr(struct wlr_buffer *buf, uint32_t flags,
void **out_data, uint32_t *out_fmt, size_t *out_stride)
{
struct wm_shm_surface *s = wl_container_of(buf, s, wlr_buf);
(void)flags;
*out_data = s->data;
*out_fmt = WL_SHM_FORMAT_ARGB8888;
*out_stride = s->stride;
return true;
}
static void
shm_buf_end_data_ptr(struct wlr_buffer *buf)
{
(void)buf;
}
static const struct wlr_buffer_impl wm_shm_buf_impl = {
.destroy = shm_buf_destroy,
.begin_data_ptr_access = shm_buf_begin_data_ptr,
.end_data_ptr_access = shm_buf_end_data_ptr,
};
/* ---------- surface API ---------------------------------------------- */
static struct wm_shm_surface *
wm_shm_surface_create(int width, int height)
{
if (width <= 0 || height <= 0)
return NULL;
struct wm_shm_surface *s = calloc(1, sizeof(*s));
if (!s)
return NULL;
s->width = width;
s->height = height;
s->stride = (size_t)width * 4;
s->data = calloc(1, (size_t)height * s->stride);
if (!s->data) {
free(s);
return NULL;
}
/* wlr_buffer init — producer holds one reference */
wlr_buffer_init(&s->wlr_buf, &wm_shm_buf_impl, width, height);
/* pixman image wrapping the same memory */
s->image = pixman_image_create_bits(PIXMAN_a8r8g8b8,
width, height,
(uint32_t *)s->data,
(int)s->stride);
if (!s->image) {
/* wlr_buffer_drop triggers shm_buf_destroy → frees data + s */
wlr_buffer_drop(&s->wlr_buf);
return NULL;
}
return s;
}
/*
* Fill a rectangle with a solid ARGB colour.
* argb: 0xAARRGGBB — e.g. 0xFF4080C0 for opaque steel-blue.
*/
static void
wm_shm_surface_fill(struct wm_shm_surface *s,
int x, int y, int w, int h,
uint32_t argb)
{
if (!s || !s->image)
return;
/* clamp to surface bounds */
if (x < 0) { w += x; x = 0; }
if (y < 0) { h += y; y = 0; }
if (x + w > s->width) w = s->width - x;
if (y + h > s->height) h = s->height - y;
if (w <= 0 || h <= 0)
return;
pixman_color_t c = {
.alpha = (uint16_t)(((argb >> 24) & 0xff) * 0x0101),
.red = (uint16_t)(((argb >> 16) & 0xff) * 0x0101),
.green = (uint16_t)(((argb >> 8) & 0xff) * 0x0101),
.blue = (uint16_t)(((argb >> 0) & 0xff) * 0x0101),
};
pixman_image_t *fill = pixman_image_create_solid_fill(&c);
if (!fill)
return;
pixman_image_composite32(PIXMAN_OP_SRC, fill, NULL, s->image,
0, 0, 0, 0, x, y, w, h);
pixman_image_unref(fill);
}
/*
* Commit the surface to the scene graph.
*
* parent — scene-graph parent node (e.g. &wl_state.scene->node)
* x, y — position in the compositor coordinate space
*
* First call creates the scene_buffer node; subsequent calls just
* reposition it (pixel updates are uploaded lazily by wlroots on the
* next wlr_scene_output_commit).
*/
static void
wm_shm_surface_commit(struct wm_shm_surface *s,
struct wlr_scene_node *parent,
int x, int y)
{
if (!s)
return;
if (!s->scene_buf) {
s->scene_buf = wlr_scene_buffer_create(parent, &s->wlr_buf);
if (!s->scene_buf) {
wwarning("wm_shm_surface_commit: wlr_scene_buffer_create failed");
return;
}
wwarning("wl_backend: SHM surface %dx%d committed to scene at %d,%d",
s->width, s->height, x, y);
}
wlr_scene_node_set_position(&s->scene_buf->node, x, y);
}
/*
* Destroy a surface and remove it from the scene graph.
* After this call s is invalid — the memory is freed asynchronously
* by shm_buf_destroy once the scene node releases its lock.
*/
static void
wm_shm_surface_destroy(struct wm_shm_surface *s)
{
if (!s)
return;
if (s->scene_buf) {
wlr_scene_node_destroy(&s->scene_buf->node);
s->scene_buf = NULL;
}
wlr_buffer_drop(&s->wlr_buf); /* producer done; shm_buf_destroy frees s */
}
/* ------------------------------------------------------------------ */
/* Screen open/close */
/* ------------------------------------------------------------------ */
@ -3866,6 +4060,17 @@ wl_screen_create_internals(WScreen *scr)
wPreferences.flags.noclip = 1;
wPreferences.flags.nodock = 1;
wwarning("wl_backend: dock/clip disabled pending native Wayland rendering");
/* Phase 29 smoke test: create a 64×64 steel-blue surface at (16,16) to
* verify the pixman → wlr_scene_buffer pipeline produces visible pixels. */
if (wl_state.scene) {
struct wm_shm_surface *test_surf = wm_shm_surface_create(64, 64);
if (test_surf) {
wm_shm_surface_fill(test_surf, 0, 0, 64, 64, 0xFF4080C0); /* steel-blue */
wm_shm_surface_commit(test_surf, &wl_state.scene->node, 16, 16);
wwarning("wl_backend: Phase 29 test surface committed (64x64 steel-blue at 16,16)");
}
}
}
static void wl_screen_create_pixmaps(WScreen *scr) { (void)scr; }
static void wl_screen_load_tech_font(WScreen *scr) { (void)scr; }