app.dhover×303 error×102all
// F08 DPI / runtime-rescale demo — both Wayland scale paths in one binary,
// runtime-selected by the advertised globals, on top of the xdg-shell scaffold
// (../scaffold/app.d; findings: ../../scaffold.md, ../../f08-dpi-scaling.md).
//
//   (a) fractional path — wp_fractional_scale_v1.preferred_scale (units of
//       1/120) + wp_viewport.set_destination(logical size), buffer allocated
//       at physical size, wl_surface buffer scale left at 1. Buffer-size math
//       follows the fractional-scale-v1 XML: "the size is rounded halfway
//       away from zero" (round half up for positive sizes) — asserted at
//       compile time AND on every commit.
//   (b) integer path — wl_surface.set_buffer_scale driven by
//       wl_surface.preferred_buffer_scale (wl_compositor v6+), falling back
//       to wl_output.scale via wl_surface.enter for older compositors.
//
// Every change logs `scale_changed scale120=N scale=X.XXX path=…` plus
// `commit_info logical=WxH buffer=WxH …`, and the *first* commit logs the
// scale the surface believed before any compositor event arrived — the
// "created at the wrong scale, then rescaled" evidence. The frame is a
// checkerboard with 1-physical-px hairlines on all four buffer edges, so a
// scaling/filtering artifact is immediately visible in a screenshot.
//
// Env knobs: WSI_FORCE_PATH=fractional|buffer_scale overrides the selection;
// WSI_AUTO_EXIT=1 + WSI_RUN_MS=<ms> bound the run (./run.sh drives live
// `swaymsg output … scale` changes against it). Headless-safe: no compositor
// → SKIP, exit 0.
module 
(module) app
app
;
import c; // ImportC: wayland-client + xdg-shell/viewporter/fractional-scale glue
unable to read module `c` Expected 'c.d' or 'c/package.d' in one of the following import paths:
unable to read module `c` Expected 'c.d' or 'c/package.d' in one of the following import paths:
import instrument;
unable to read module `instrument` Expected 'instrument.d' or 'instrument/package.d' in one of the following import paths:
unable to read module `instrument` Expected 'instrument.d' or 'instrument/package.d' in one of the following import paths:
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.stdio

D header file for C99 <stdio.h>

pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html, stdio.h

Source

core/stdc/stdio.d

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseDistributed under the Boost Software License 1.0. (See accompanying file LICENSE)@authorsSean Kelly, Alex Rønne Petersen@standardsISO/IEC 9899:1999 (E)
stdio
:
(alias) app.printf = int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
;
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.stdlib

D header file for C99.

pubs.opengroup.org/onlinepubs/009695399/basedefs/stdlib.h.html, stdlib.h

Source

core/stdc/stdlib.d

@copyrightCopyright Sean Kelly 2005 - 2014.@licenseDistributed under the Boost Software License 1.0. (See accompanying file LICENSE)@authorsSean Kelly@standardsISO/IEC 9899:1999 (E)
stdlib
:
(alias) app.atoi = int core.stdc.stdlib.atoi(scope const(char*) nptr) nothrow @nogc
atoi
,
(alias) app.getenv = char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
;
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.string

D header file for C99.

pubs.opengroup.org/onlinepubs/009695399/basedefs/string.h.html, string.h

Source

core/stdc/string.d

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseDistributed under the Boost Software License 1.0. (See accompanying file LICENSE)@authorsSean Kelly@standardsISO/IEC 9899:1999 (E)
string
:
(alias) app.strcmp = int core.stdc.string.strcmp(scope const(char*) s1, scope const(char*) s2) pure nothrow @nogc
strcmp
;
// ----------------------------------------------------------------- tunables enum int
(constant) int app.defaultWidth = 640
defaultWidth
= 640;
enum int
(constant) int app.defaultHeight = 480
defaultHeight
= 480;
enum int
(constant) int app.checkerPx = 16
checkerPx
= 16; // checkerboard cell, *physical* pixels
/// fractional-scale-v1 buffer math: logical size × (scale120/120), "rounded /// halfway away from zero" (the protocol XML's words; sizes are positive, so /// this is round half up). int
int app.physSize(int logical, uint scale120) pure nothrow @nogc @safe

fractional-scale-v1 buffer math: logical size × (scale120/120), "rounded halfway away from zero" (the protocol XML's words; sizes are positive, so this is round half up).

physSize
(int
(parameter) int logical
logical
, uint
(parameter) uint scale120
scale120
) pure nothrow @nogc @safe
{ return cast(int)((cast(long)
(parameter) int logical
logical
*
(parameter) uint scale120
scale120
+ 60) / 120);
} static assert(
int app.physSize(int logical, uint scale120) pure nothrow @nogc @safe

fractional-scale-v1 buffer math: logical size × (scale120/120), "rounded halfway away from zero" (the protocol XML's words; sizes are positive, so this is round half up).

physSize
(640, 120) == 640); // 1.0 → identity
static assert(
int app.physSize(int logical, uint scale120) pure nothrow @nogc @safe

fractional-scale-v1 buffer math: logical size × (scale120/120), "rounded halfway away from zero" (the protocol XML's words; sizes are positive, so this is round half up).

physSize
(640, 180) == 960); // 1.5 → exact
static assert(
int app.physSize(int logical, uint scale120) pure nothrow @nogc @safe

fractional-scale-v1 buffer math: logical size × (scale120/120), "rounded halfway away from zero" (the protocol XML's words; sizes are positive, so this is round half up).

physSize
(101, 180) == 152); // 151.5 rounds *up* (away from zero)
static assert(
int app.physSize(int logical, uint scale120) pure nothrow @nogc @safe

fractional-scale-v1 buffer math: logical size × (scale120/120), "rounded halfway away from zero" (the protocol XML's words; sizes are positive, so this is round half up).

physSize
(33, 150) == 41); // 41.25 rounds down
static assert(
int app.physSize(int logical, uint scale120) pure nothrow @nogc @safe

fractional-scale-v1 buffer math: logical size × (scale120/120), "rounded halfway away from zero" (the protocol XML's words; sizes are positive, so this is round half up).

physSize
(640, 150) == 800); // 1.25 → exact
// -------------------------------------------------------------------- state struct
(struct) app.Buffer
Buffer
{ wl_buffer*
(field) _error_ app.Buffer.handle
handle
;
undefined identifier `wl_buffer`
uint*
(field) uint* app.Buffer.pixels
pixels
;
(alias) object.size_t = ulong
size_t
(field) ulong app.Buffer.byteSize
byteSize
;
int
(field) int app.Buffer.width
width
,
(field) int app.Buffer.height
height
;
bool
(field) bool app.Buffer.busy
busy
;
} enum
(enum) app.Path
Path
{
(enum value) app.Path.bufferScale = 0
bufferScale
, // wl_surface.set_buffer_scale (integer)
(enum value) app.Path.fractional = 1
fractional
, // wp_fractional_scale_v1 + wp_viewport
} __gshared { wl_display*
_error_ app.g_display
g_display
;
undefined identifier `wl_display`, did you mean variable `g_display`?
wl_registry*
_error_ app.g_registry
g_registry
;
undefined identifier `wl_registry`, did you mean variable `g_registry`?
wl_compositor*
_error_ app.g_compositor
g_compositor
;
undefined identifier `wl_compositor`, did you mean variable `g_compositor`?
uint
(__gshared global) uint app.g_compositorVersion
g_compositorVersion
;
wl_shm*
_error_ app.g_shm
g_shm
;
undefined identifier `wl_shm`, did you mean variable `g_shm`?
wl_output*
_error_ app.g_output
g_output
; // first advertised output (enough for headless runs)
undefined identifier `wl_output`, did you mean variable `g_output`?
xdg_wm_base*
_error_ app.g_wmBase
g_wmBase
;
undefined identifier `xdg_wm_base`
wl_surface*
_error_ app.g_surface
g_surface
;
undefined identifier `wl_surface`, did you mean variable `g_surface`?
xdg_surface*
_error_ app.g_xdgSurface
g_xdgSurface
;
undefined identifier `xdg_surface`, did you mean variable `g_surface`?
xdg_toplevel*
_error_ app.g_toplevel
g_toplevel
;
undefined identifier `xdg_toplevel`, did you mean variable `g_toplevel`?
wl_callback*
_error_ app.g_frameCb
g_frameCb
;
undefined identifier `wl_callback`
wp_viewporter*
_error_ app.g_viewporter
g_viewporter
;
undefined identifier `wp_viewporter`, did you mean variable `g_viewporter`?
wp_viewport*
_error_ app.g_viewport
g_viewport
;
undefined identifier `wp_viewport`, did you mean variable `g_viewport`?
wp_fractional_scale_manager_v1*
_error_ app.g_fracManager
g_fracManager
;
undefined identifier `wp_fractional_scale_manager_v1`
wp_fractional_scale_v1*
_error_ app.g_fracScale
g_fracScale
;
undefined identifier `wp_fractional_scale_v1`
(struct) app.Buffer
Buffer
[2]
_error_ app.g_buffers
g_buffers
;
(enum) app.Path
Path
(__gshared global) app.Path app.g_path
g_path
;
int
(__gshared global) int app.g_logicalW
g_logicalW
= defaultWidth,
(__gshared global) int app.g_logicalH
g_logicalH
= defaultHeight; // last acked
int
(__gshared global) int app.g_pendingWidth
g_pendingWidth
,
(__gshared global) int app.g_pendingHeight
g_pendingHeight
;
uint
(__gshared global) uint app.g_scale120
g_scale120
= 120; // current scale in 1/120ths (both paths normalize here)
int
(__gshared global) int app.g_outputScale
g_outputScale
= 1; // last wl_output.scale (the v5-and-older fallback)
bool
(__gshared global) bool app.g_configured
g_configured
,
(__gshared global) bool app.g_running
g_running
= true,
(__gshared global) bool app.g_autoExit
g_autoExit
,
(__gshared global) bool app.g_firstCommitDone
g_firstCommitDone
;
long
(__gshared global) long app.g_runUsCap
g_runUsCap
= 2_500_000;
int
(__gshared global) int app.g_frames
g_frames
,
(__gshared global) int app.g_commits
g_commits
;
} const(char)*
const(char)* app.pathName() nothrow @nogc
pathName
() nothrow @nogc
{ return
(__gshared global) app.Path app.g_path
g_path
==
(enum) app.Path
Path
.
(enum value) app.Path.fractional = 1
fractional
? "fractional".
(constant) immutable(char)* "fractional".ptr = "fractional"
ptr
: "buffer_scale".
(constant) immutable(char)* "buffer_scale".ptr = "buffer_scale"
ptr
;
} /// Log `scale_changed` in the canonical format (scale as a decimal, plus the /// raw 120ths so fractional values stay exact). void
void app.logScaleChanged() nothrow @nogc

Log scale_changed in the canonical format (scale as a decimal, plus the raw 120ths so fractional values stay exact).

logScaleChanged
() nothrow @nogc
{ instrEvent("scale_changed", "scale120=%u scale=%u.%03u path=%s",
undefined identifier `instrEvent`, did you mean import `instrument`?
g_scale120, g_scale120 / 120, (g_scale120 % 120) * 1000 / 120, pathName()); } void
void app.bufferDims(out int w, out int h) nothrow @nogc
bufferDims
(out int
(parameter) int w
w
, out int
(parameter) int h
h
) nothrow @nogc
{ if (
(__gshared global) app.Path app.g_path
g_path
==
(enum) app.Path
Path
.
(enum value) app.Path.fractional = 1
fractional
)
{
(parameter) int w
w
=
int app.physSize(int logical, uint scale120) pure nothrow @nogc @safe

fractional-scale-v1 buffer math: logical size × (scale120/120), "rounded halfway away from zero" (the protocol XML's words; sizes are positive, so this is round half up).

physSize
(
(__gshared global) int app.g_logicalW
g_logicalW
,
(__gshared global) uint app.g_scale120
g_scale120
);
(parameter) int h
h
=
int app.physSize(int logical, uint scale120) pure nothrow @nogc @safe

fractional-scale-v1 buffer math: logical size × (scale120/120), "rounded halfway away from zero" (the protocol XML's words; sizes are positive, so this is round half up).

physSize
(
(__gshared global) int app.g_logicalH
g_logicalH
,
(__gshared global) uint app.g_scale120
g_scale120
);
} else { immutable
(local variable) immutable(int) s
s
= cast(int)
(__gshared global) uint app.g_scale120
g_scale120
/ 120;
(parameter) int w
w
=
(__gshared global) int app.g_logicalW
g_logicalW
*
(local variable) immutable(int) s
s
;
(parameter) int h
h
=
(__gshared global) int app.g_logicalH
g_logicalH
*
(local variable) immutable(int) s
s
;
} } // ------------------------------------------------------------ shm + drawing bool
app.ensureBuffer
ensureBuffer
(ref
(struct) app.Buffer
Buffer
(parameter) Buffer b
b
, int
(parameter) int w
w
, int
(parameter) int h
h
) nothrow @nogc
{ if (b.
b.handle
handle
!is null && (b.
b.width
width
!= w || b.
b.height
height
!= h))
{ wsi_buffer_destroy(b.
b.handle
handle
);
munmap(b.
b.pixels
pixels
, b.
b.byteSize
byteSize
);
b = Buffer.init; } if (b.
b.handle
handle
!is null)
return true; immutable
_error_ stride
stride
= w * 4;
immutable
_error_ size
size
= cast(
(unresolved type) size_t
size_t
) stride * h;
immutable
_error_ fd
fd
= memfd_create("wsi-f08", MFD_CLOEXEC);
if (fd < 0 || ftruncate(fd, cast(long) size) != 0) return false; void*
_error_ mem
mem
= mmap(null, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (mem is cast(void*)-1) { close(fd); return false; } wl_shm_pool*
_error_ pool
pool
= wsi_shm_create_pool(g_shm, fd, cast(int) size);
b.
b.handle
handle
= wsi_shm_pool_create_buffer(pool, 0, w, h, stride, WL_SHM_FORMAT_ARGB8888);
wsi_shm_pool_destroy(pool); close(fd); wsi_buffer_add_listener(b.
b.handle
handle
, &g_bufferListener, &b);
b.
b.pixels
pixels
= cast(uint*) mem;
b.
b.byteSize
byteSize
= size;
b.
b.width
width
= w;
b.
b.height
height
= h;
instrEvent("buffer_alloc", "size=%dx%d bytes=%zu", w, h, size); return true; } /// Checkerboard at physical resolution + 1-physical-px hairlines on all four /// buffer edges. If the compositor resamples (wrong buffer size for the /// scale), the hairlines blur or vanish — the artifact detector. void
app.paint

Checkerboard at physical resolution + 1-physical-px hairlines on all four buffer edges. If the compositor resamples (wrong buffer size for the scale), the hairlines blur or vanish — the artifact detector.

paint
(ref
(struct) app.Buffer
Buffer
(parameter) Buffer b
b
) nothrow @nogc
{ foreach (
(parameter) y
y
; 0 .. b.
b.height
height
)
{ uint*
_error_ row
row
= b.
b.pixels
pixels
+ cast(
(unresolved type) size_t
size_t
) y * b.
b.width
width
;
foreach (
(parameter) x
x
; 0 .. b.
b.width
width
)
row[x] = ((x / checkerPx + y / checkerPx) & 1) ? 0xff707070 : 0xff383838; } foreach (
(parameter) x
x
; 0 .. b.
b.width
width
) // top/bottom hairlines, exactly 1 physical px
{ b.
b.pixels
pixels
[x] = 0xffffffff;
b.
b.pixels
pixels
[cast(
(unresolved type) size_t
size_t
)(b.
b.height
height
- 1) * b.
b.width
width
+ x] = 0xffff2020;
} foreach (
(parameter) y
y
; 0 .. b.
b.height
height
) // left/right hairlines
{ b.
b.pixels
pixels
[cast(
(unresolved type) size_t
size_t
) y * b.
b.width
width
] = 0xff20ff20;
b.
b.pixels
pixels
[cast(
(unresolved type) size_t
size_t
) y * b.
b.width
width
+ b.
b.width
width
- 1] = 0xff40a0ff;
} } void
void app.render() nothrow @nogc
render
() nothrow @nogc
{
(struct) app.Buffer
Buffer
*
(local variable) _error_ buf
buf
= null;
foreach (ref
(parameter) b
b
; g_buffers)
if (!b.
b.busy
busy
)
{ buf = &b; break; } if (buf is null) return; // recovered by the wl_buffer.release handler int
(local variable) int bw
bw
,
(local variable) int bh
bh
;
void app.bufferDims(out int w, out int h) nothrow @nogc
bufferDims
(
(local variable) int bw
bw
,
(local variable) int bh
bh
);
if (!ensureBuffer(*buf, bw, bh)) return; paint(*buf); // The committed buffer must match the spec math for the current scale. assert(buf.
(field) _error_ buf.width
width
==
(local variable) int bw
bw
&& buf.
(field) _error_ buf.height
height
==
(local variable) int bh
bh
,
"committed buffer size does not match the scale math"); if (
(__gshared global) app.Path app.g_path
g_path
==
(enum) app.Path
Path
.
(enum value) app.Path.fractional = 1
fractional
)
{ // Buffer at physical size, destination at logical size, buffer scale 1. wsi_viewport_set_destination(g_viewport, g_logicalW, g_logicalH);
undefined identifier `wsi_viewport_set_destination`
} else wsi_surface_set_buffer_scale(g_surface, cast(int) g_scale120 / 120);
undefined identifier `wsi_surface_set_buffer_scale`
wsi_surface_attach(g_surface, buf.
buf.handle
handle
, 0, 0);
undefined identifier `wsi_surface_attach`
wsi_surface_damage_buffer(g_surface, 0, 0, buf.
buf.width
width
, buf.
buf.height
height
);
undefined identifier `wsi_surface_damage_buffer`
if (g_frameCb is null) { g_frameCb = wsi_surface_frame(g_surface); wsi_callback_add_listener(g_frameCb, &g_frameListener, null);
undefined identifier `wsi_callback_add_listener`
} wsi_surface_commit(g_surface);
undefined identifier `wsi_surface_commit`
buf.
buf.busy
busy
= true;
(__gshared global) int app.g_commits
g_commits
++;
if (!
(__gshared global) bool app.g_firstCommitDone
g_firstCommitDone
)
{
(__gshared global) bool app.g_firstCommitDone
g_firstCommitDone
= true;
// The created-at-wrong-scale evidence: this is the scale the surface // believed at its very first commit, before/after compositor events. instrEvent("first_commit", "logical=%dx%d buffer=%dx%d scale120=%u path=%s",
undefined identifier `instrEvent`, did you mean import `instrument`?
g_logicalW, g_logicalH, buf.
buf.width
width
, buf.
buf.height
height
, g_scale120, pathName());
} } /// Re-render right away on any scale/size change and log the new geometry. void
void app.applyChange(const(char)* why) nothrow @nogc

Re-render right away on any scale/size change and log the new geometry.

applyChange
(const(char)*
(parameter) const(char)* why
why
) nothrow @nogc
{ int
(local variable) int bw
bw
,
(local variable) int bh
bh
;
void app.bufferDims(out int w, out int h) nothrow @nogc
bufferDims
(
(local variable) int bw
bw
,
(local variable) int bh
bh
);
instrEvent("commit_info", "reason=%s logical=%dx%d buffer=%dx%d scale120=%u path=%s",
undefined identifier `instrEvent`, did you mean import `instrument`?
why, g_logicalW, g_logicalH, bw, bh, g_scale120, pathName()); if (
(__gshared global) bool app.g_configured
g_configured
)
void app.render() nothrow @nogc
render
();
} // ---------------------------------------------------------------- listeners extern (C) void
app.onFracPreferredScale
onFracPreferredScale
(void* data, wp_fractional_scale_v1* f, uint scale) nothrow @nogc
undefined identifier `wp_fractional_scale_v1`
{ instrEvent("preferred_scale", "scale120=%u (wp_fractional_scale_v1)", scale); if (g_path == Path.
Path.fractional
fractional
&& scale != g_scale120)
{ g_scale120 = scale; logScaleChanged(); applyChange("preferred_scale"); } } extern (C) void
app.onSurfaceEnter
onSurfaceEnter
(void* data, wl_surface*
(parameter) wl_surface* s
s
, wl_output* o) nothrow @nogc
undefined identifier `wl_surface`, did you mean variable `g_surface`?
undefined identifier `wl_output`, did you mean variable `g_output`?
{ instrEvent("surface_enter", "output_scale=%d", g_outputScale); // pre-v6 integer fallback: adopt the entered output's scale. if (g_path == Path.
Path.bufferScale
bufferScale
&& g_compositorVersion < 6
&& g_outputScale * 120 != g_scale120) { g_scale120 = g_outputScale * 120; logScaleChanged(); applyChange("wl_output.scale"); } } extern (C) void
app.onSurfaceLeave
onSurfaceLeave
(void* data, wl_surface*
(parameter) wl_surface* s
s
, wl_output* o) nothrow @nogc
undefined identifier `wl_surface`, did you mean variable `g_surface`?
undefined identifier `wl_output`, did you mean variable `g_output`?
{ instrEvent("surface_leave"); } extern (C) void
app.onPreferredBufferScale
onPreferredBufferScale
(void* data, wl_surface*
(parameter) wl_surface* s
s
, int factor) nothrow @nogc
undefined identifier `wl_surface`, did you mean variable `g_surface`?
{ instrEvent("preferred_buffer_scale", "factor=%d (wl_surface v6)", factor); if (g_path == Path.
Path.bufferScale
bufferScale
&& cast(uint)(factor * 120) != g_scale120)
{ g_scale120 = factor * 120; logScaleChanged(); applyChange("preferred_buffer_scale"); } } extern (C) void
app.onPreferredBufferTransform
onPreferredBufferTransform
(void* data, wl_surface*
(parameter) wl_surface* s
s
, uint transform) nothrow @nogc
undefined identifier `wl_surface`, did you mean variable `g_surface`?
{ } extern (C) void
app.onOutputGeometry
onOutputGeometry
(void* data, wl_output* o, int
(parameter) int x
x
, int
(parameter) int y
y
, int physW,
undefined identifier `wl_output`, did you mean variable `g_output`?
int physH, int subpixel, const(char)* make, const(char)* model, int transform) nothrow @nogc { instrEvent("output_geometry", "physical_mm=%dx%d", physW, physH); } extern (C) void
app.onOutputMode
onOutputMode
(void* data, wl_output* o, uint flags, int
(parameter) int w
w
, int
(parameter) int h
h
, int refresh) nothrow @nogc
undefined identifier `wl_output`, did you mean variable `g_output`?
{ instrEvent("output_mode", "size=%dx%d refresh_mhz=%d", w, h, refresh); } extern (C) void
app.onOutputDone
onOutputDone
(void* data, wl_output* o) nothrow @nogc
undefined identifier `wl_output`, did you mean variable `g_output`?
{ } extern (C) void
app.onOutputScale
onOutputScale
(void* data, wl_output* o, int factor) nothrow @nogc
undefined identifier `wl_output`, did you mean variable `g_output`?
{ instrEvent("output_scale", "scale=%d (wl_output v2)", factor); g_outputScale = factor; } extern (C) void
app.onOutputName
onOutputName
(void* data, wl_output* o, const(char)* name) nothrow @nogc
undefined identifier `wl_output`, did you mean variable `g_output`?
{ instrEvent("output_name", "name=%s", name); } extern (C) void
app.onOutputDescription
onOutputDescription
(void* data, wl_output* o, const(char)* desc) nothrow @nogc
undefined identifier `wl_output`, did you mean variable `g_output`?
{ } extern (C) void
app.onGlobal
onGlobal
(void* data, wl_registry* reg, uint name,
undefined identifier `wl_registry`, did you mean variable `g_registry`?
const(char)* iface, uint ver) nothrow @nogc { instrEvent("global", "iface=%s version=%u", iface, ver); // the registry dump static uint
uint capped(uint advertised, uint want) nothrow @nogc
capped
(uint
(parameter) uint advertised
advertised
, uint
(parameter) uint want
want
) nothrow @nogc
{ return advertised < want ? advertised : want; } if (strcmp(iface, wl_compositor_interface.name) == 0) { g_compositorVersion = capped(ver, 6); // v6: wl_surface.preferred_buffer_scale g_compositor = cast(wl_compositor*) wsi_registry_bind(reg, name, &wl_compositor_interface, g_compositorVersion); } else if (strcmp(iface, wl_shm_interface.name) == 0) g_shm = cast(wl_shm*) wsi_registry_bind(reg, name, &wl_shm_interface, 1); else if (strcmp(iface, xdg_wm_base_interface.name) == 0) g_wmBase = cast(xdg_wm_base*) wsi_registry_bind(reg, name, &xdg_wm_base_interface, 1); else if (strcmp(iface, wl_output_interface.name) == 0 && g_output is null) g_output = cast(wl_output*) wsi_registry_bind(reg, name, &wl_output_interface, capped(ver, 4)); // v2: scale, v4: name else if (strcmp(iface, wp_viewporter_interface.name) == 0) g_viewporter = cast(wp_viewporter*) wsi_registry_bind(reg, name, &wp_viewporter_interface, 1); else if (strcmp(iface, wp_fractional_scale_manager_v1_interface.name) == 0) g_fracManager = cast(wp_fractional_scale_manager_v1*) wsi_registry_bind(reg, name, &wp_fractional_scale_manager_v1_interface, 1); } extern (C) void
app.onGlobalRemove
onGlobalRemove
(void* data, wl_registry* reg, uint name) nothrow @nogc
undefined identifier `wl_registry`, did you mean variable `g_registry`?
{ } extern (C) void
app.onWmBasePing
onWmBasePing
(void* data, xdg_wm_base*
(parameter) xdg_wm_base* b
b
, uint serial) nothrow @nogc
undefined identifier `xdg_wm_base`
{ wsi_wm_base_pong(b, serial); } extern (C) void
app.onToplevelConfigure
onToplevelConfigure
(void* data, xdg_toplevel* t, int
(parameter) int w
w
, int
(parameter) int h
h
,
undefined identifier `xdg_toplevel`, did you mean variable `g_toplevel`?
wl_array* states) nothrow @nogc
undefined identifier `wl_array`
{ g_pendingWidth = w; g_pendingHeight = h; instrEvent("xdg_toplevel_configure", "size=%dx%d (logical)", w, h); } extern (C) void
app.onXdgSurfaceConfigure
onXdgSurfaceConfigure
(void* data, xdg_surface*
(parameter) xdg_surface* s
s
, uint serial) nothrow @nogc
undefined identifier `xdg_surface`, did you mean variable `g_surface`?
{ immutable
_error_ w
w
= g_pendingWidth > 0 ? g_pendingWidth : defaultWidth;
immutable
_error_ h
h
= g_pendingHeight > 0 ? g_pendingHeight : defaultHeight;
instrEvent("configure", "serial=%u size=%dx%d", serial, w, h); wsi_xdg_surface_ack_configure(s, serial); immutable
_error_ resized
resized
= w != g_logicalW || h != g_logicalH;
g_logicalW = w; g_logicalH = h; if (!g_configured) { g_configured = true; instrFirstConfigure(); render(); } else if (resized) { instrEvent("resize", "size=%dx%d scale120=%u", w, h, g_scale120); applyChange("configure"); } } extern (C) void
app.onToplevelClose
onToplevelClose
(void* data, xdg_toplevel* t) nothrow @nogc
undefined identifier `xdg_toplevel`, did you mean variable `g_toplevel`?
{ instrCloseRequested(); g_running = false; } extern (C) void
app.onToplevelConfigureBounds
onToplevelConfigureBounds
(void* data, xdg_toplevel* t, int
(parameter) int w
w
, int
(parameter) int h
h
) nothrow @nogc
undefined identifier `xdg_toplevel`, did you mean variable `g_toplevel`?
{ } extern (C) void
app.onToplevelWmCapabilities
onToplevelWmCapabilities
(void* data, xdg_toplevel* t, wl_array* caps) nothrow @nogc
undefined identifier `xdg_toplevel`, did you mean variable `g_toplevel`?
undefined identifier `wl_array`
{ } extern (C) void
app.onBufferRelease
onBufferRelease
(void* data, wl_buffer*
(parameter) wl_buffer* b
b
) nothrow @nogc
undefined identifier `wl_buffer`
{ (cast(
(unresolved type) Buffer
Buffer
*) data).
(cast(Buffer*)data).busy
busy
= false;
// sway/wlroots holds shm buffers until the *next* commit replaces them, so // both buffers can be busy when a frame callback fires; recover here. if (g_running && g_configured && g_frameCb is null) render(); } extern (C) void
app.onFrameDone
onFrameDone
(void* data, wl_callback* cb, uint timeMs) nothrow @nogc
undefined identifier `wl_callback`
{ wsi_callback_destroy(cb); g_frameCb = null; g_frames++; if (g_frames == 1) instrFirstPixelPresented(); render(); } __gshared wl_registry_listener
_error_ app.g_registryListener
g_registryListener
= {&onGlobal, &onGlobalRemove};
undefined identifier `wl_registry_listener`
__gshared xdg_wm_base_listener
_error_ app.g_wmBaseListener
g_wmBaseListener
= {&onWmBasePing};
undefined identifier `xdg_wm_base_listener`
__gshared wl_surface_listener
_error_ app.g_surfaceListener
g_surfaceListener
= {
undefined identifier `wl_surface_listener`
&onSurfaceEnter, &onSurfaceLeave, &onPreferredBufferScale, &onPreferredBufferTransform }; __gshared wl_output_listener
_error_ app.g_outputListener
g_outputListener
= {
undefined identifier `wl_output_listener`
&onOutputGeometry, &onOutputMode, &onOutputDone, &onOutputScale, &onOutputName, &onOutputDescription }; __gshared xdg_surface_listener
_error_ app.g_xdgSurfaceListener
g_xdgSurfaceListener
= {&onXdgSurfaceConfigure};
undefined identifier `xdg_surface_listener`
__gshared xdg_toplevel_listener
_error_ app.g_toplevelListener
g_toplevelListener
= {
undefined identifier `xdg_toplevel_listener`
&onToplevelConfigure, &onToplevelClose, &onToplevelConfigureBounds, &onToplevelWmCapabilities }; __gshared wl_buffer_listener
_error_ app.g_bufferListener
g_bufferListener
= {&onBufferRelease};
undefined identifier `wl_buffer_listener`
__gshared wl_callback_listener
_error_ app.g_frameListener
g_frameListener
= {&onFrameDone};
undefined identifier `wl_callback_listener`
// --------------------------------------------------------------------- main int
int D main()
main
()
{ instrInit("f08_wayland");
undefined identifier `instrInit`
const
(local variable) const(char*) autoEnv
autoEnv
=
char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
("WSI_AUTO_EXIT");
(__gshared global) bool app.g_autoExit
g_autoExit
=
(local variable) const(char*) autoEnv
autoEnv
!is null && *
(local variable) const(char*) autoEnv
autoEnv
== '1';
const
(local variable) const(char*) runMs
runMs
=
char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
("WSI_RUN_MS");
if (
(local variable) const(char*) runMs
runMs
!is null)
(__gshared global) long app.g_runUsCap
g_runUsCap
=
int core.stdc.stdlib.atoi(scope const(char*) nptr) nothrow @nogc
atoi
(
(local variable) const(char*) runMs
runMs
) * 1000L;
g_display = wl_display_connect(null); if (g_display is null) {
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("SKIP: no Wayland compositor (wl_display_connect returned null)\n");
return 0; } g_registry = wsi_display_get_registry(g_display); wsi_registry_add_listener(g_registry, &g_registryListener, null);
undefined identifier `wsi_registry_add_listener`
wl_display_roundtrip(g_display);
undefined identifier `wl_display_roundtrip`
if (g_compositor is null || g_shm is null || g_wmBase is null) {
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("SKIP: compositor lacks a required global\n");
wl_display_disconnect(g_display);
undefined identifier `wl_display_disconnect`
return 0; } // Path selection: fractional when both fractional-scale-v1 AND viewporter // are advertised (the former is useless without the latter), else integer. const
(local variable) const(char*) force
force
=
char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
("WSI_FORCE_PATH");
(__gshared global) app.Path app.g_path
g_path
= g_fracManager !is null && g_viewporter !is null ?
(enum) app.Path
Path
.
(enum value) app.Path.fractional = 1
fractional
:
(enum) app.Path
Path
.
(enum value) app.Path.bufferScale = 0
bufferScale
;
if (
(local variable) const(char*) force
force
!is null &&
int core.stdc.string.strcmp(scope const(char*) s1, scope const(char*) s2) pure nothrow @nogc
strcmp
(
(local variable) const(char*) force
force
, "buffer_scale") == 0)
(__gshared global) app.Path app.g_path
g_path
=
(enum) app.Path
Path
.
(enum value) app.Path.bufferScale = 0
bufferScale
;
if (
(local variable) const(char*) force
force
!is null &&
int core.stdc.string.strcmp(scope const(char*) s1, scope const(char*) s2) pure nothrow @nogc
strcmp
(
(local variable) const(char*) force
force
, "fractional") == 0 &&
(__gshared global) app.Path app.g_path
g_path
!=
(enum) app.Path
Path
.
(enum value) app.Path.fractional = 1
fractional
)
{
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("SKIP: fractional path forced but wp_fractional_scale_v1/wp_viewporter missing\n");
wl_display_disconnect(g_display);
undefined identifier `wl_display_disconnect`
return 0; } instrEvent("path_selected", "path=%s fractional_scale_v1=%d viewporter=%d compositor_version=%u",
undefined identifier `instrEvent`, did you mean import `instrument`?
pathName(), g_fracManager !is null ? 1 : 0, g_viewporter !is null ? 1 : 0, g_compositorVersion); wsi_wm_base_add_listener(g_wmBase, &g_wmBaseListener, null);
undefined identifier `wsi_wm_base_add_listener`
if (g_output !is null) wsi_output_add_listener(g_output, &g_outputListener, null);
undefined identifier `wsi_output_add_listener`
g_surface = wsi_compositor_create_surface(g_compositor); wsi_surface_add_listener(g_surface, &g_surfaceListener, null);
undefined identifier `wsi_surface_add_listener`
if (
(__gshared global) app.Path app.g_path
g_path
==
(enum) app.Path
Path
.
(enum value) app.Path.fractional = 1
fractional
)
{ g_fracScale = wsi_fractional_scale_manager_get(g_fracManager, g_surface); __gshared wp_fractional_scale_v1_listener
_error_ app.main.fracListener
fracListener
= {&onFracPreferredScale};
undefined identifier `wp_fractional_scale_v1_listener`
wsi_fractional_scale_add_listener(g_fracScale, &fracListener, null);
undefined identifier `wsi_fractional_scale_add_listener`
g_viewport = wsi_viewporter_get_viewport(g_viewporter, g_surface); } g_xdgSurface = wsi_wm_base_get_xdg_surface(g_wmBase, g_surface); wsi_xdg_surface_add_listener(g_xdgSurface, &g_xdgSurfaceListener, null);
undefined identifier `wsi_xdg_surface_add_listener`
g_toplevel = wsi_xdg_surface_get_toplevel(g_xdgSurface); wsi_toplevel_add_listener(g_toplevel, &g_toplevelListener, null);
undefined identifier `wsi_toplevel_add_listener`
wsi_toplevel_set_title(g_toplevel, "wsi-f08-dpi-scaling");
undefined identifier `wsi_toplevel_set_title`
wsi_toplevel_set_app_id(g_toplevel, "wsi-f08-dpi-scaling");
undefined identifier `wsi_toplevel_set_app_id`
instrWindowCreated();
undefined identifier `instrWindowCreated`
wsi_surface_commit(g_surface); // mandatory no-buffer first commit
undefined identifier `wsi_surface_commit`
// Poll-based pump (the F04 lesson) so the wall-clock auto-exit stays live // even when the compositor throttles frame callbacks. immutable
(local variable) immutable(_error_) dispFd
dispFd
= wl_display_get_fd(g_display);
undefined identifier `wl_display_get_fd`
while (
(__gshared global) bool app.g_running
g_running
)
{ while (wl_display_prepare_read(g_display) != 0)
undefined identifier `wl_display_prepare_read`
wl_display_dispatch_pending(g_display);
undefined identifier `wl_display_dispatch_pending`
wl_display_flush(g_display);
undefined identifier `wl_display_flush`
pollfd
(local variable) _error_ pfd
pfd
= {dispFd, POLLIN, 0};
undefined identifier `pollfd`
if (poll(&pfd, 1, 100) > 0)
undefined identifier `poll`
wl_display_read_events(g_display);
undefined identifier `wl_display_read_events`
else wl_display_cancel_read(g_display);
undefined identifier `wl_display_cancel_read`
if (wl_display_dispatch_pending(g_display) == -1)
undefined identifier `wl_display_dispatch_pending`
break; if (
(__gshared global) bool app.g_autoExit
g_autoExit
&& instrNowUs() >
(__gshared global) long app.g_runUsCap
g_runUsCap
)
undefined identifier `instrNowUs`
(__gshared global) bool app.g_running
g_running
= false;
} // Teardown: children before parents. if (g_fracScale !is null) wsi_fractional_scale_destroy(g_fracScale);
undefined identifier `wsi_fractional_scale_destroy`
if (g_fracManager !is null) wsi_fractional_scale_manager_destroy(g_fracManager);
undefined identifier `wsi_fractional_scale_manager_destroy`
if (g_viewport !is null) wsi_viewport_destroy(g_viewport);
undefined identifier `wsi_viewport_destroy`
if (g_viewporter !is null) wsi_viewporter_destroy(g_viewporter);
undefined identifier `wsi_viewporter_destroy`
foreach (ref
(parameter) b
b
; g_buffers)
if (b.
b.handle
handle
!is null)
{ wsi_buffer_destroy(b.
b.handle
handle
);
munmap(b.
b.pixels
pixels
, b.
b.byteSize
byteSize
);
} if (g_frameCb !is null) wsi_callback_destroy(g_frameCb);
undefined identifier `wsi_callback_destroy`
wsi_toplevel_destroy(g_toplevel);
undefined identifier `wsi_toplevel_destroy`
wsi_xdg_surface_destroy(g_xdgSurface);
undefined identifier `wsi_xdg_surface_destroy`
wsi_surface_destroy(g_surface);
undefined identifier `wsi_surface_destroy`
wsi_wm_base_destroy(g_wmBase);
undefined identifier `wsi_wm_base_destroy`
if (g_output !is null) wl_proxy_destroy(cast(wl_proxy*) g_output);
undefined identifier `wl_proxy_destroy`
wl_proxy_destroy(cast(wl_proxy*) g_shm);
undefined identifier `wl_proxy_destroy`
wl_proxy_destroy(cast(wl_proxy*) g_compositor);
undefined identifier `wl_proxy_destroy`
wl_proxy_destroy(cast(wl_proxy*) g_registry);
undefined identifier `wl_proxy_destroy`
wl_display_disconnect(g_display);
undefined identifier `wl_display_disconnect`
int
(local variable) int bw
bw
,
(local variable) int bh
bh
;
void app.bufferDims(out int w, out int h) nothrow @nogc
bufferDims
(
(local variable) int bw
bw
,
(local variable) int bh
bh
);
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("ok: frames=%d commits=%d path=%s final logical=%dx%d buffer=%dx%d scale120=%u\n",
(__gshared global) int app.g_frames
g_frames
,
(__gshared global) int app.g_commits
g_commits
,
const(char)* app.pathName() nothrow @nogc
pathName
(),
(__gshared global) int app.g_logicalW
g_logicalW
,
(__gshared global) int app.g_logicalH
g_logicalH
,
(local variable) int bw
bw
,
(local variable) int bh
bh
,
(__gshared global) uint app.g_scale120
g_scale120
);
return 0; }