// F14 — window state & vetoable close (see ../../f14-window-state.md and
// ../../../features/f14-window-state.md). One binary, two stories:
//
// State storm (WSI_AUTO_EXIT=1) a timed choreography issues the full
// request quartet plus the asymmetric fifth —
// set_maximized → unset_maximized → set_fullscreen →
// unset_fullscreen → set_minimized
// — and decodes the *complete* states array of every
// xdg_toplevel.configure (maximized/fullscreen/resizing/activated/
// tiled_*/suspended/constrained_*). xdg_wm_base is bound at
// min(advertised, 6) so the v6 `suspended` state is delivered when the
// compositor has it; advertised vs bound is logged. After
// set_minimized the demo keeps polling (frame callbacks may stop —
// F04's occlusion finding) and reports how many frame callbacks
// arrived in the post-minimize window.
//
// Vetoable close (always armed) the document is permanently "dirty":
// the first WSI_VETO_CLOSE (default 1) xdg_toplevel.close events are
// *ignored* — that is the entire veto mechanism, close is an event,
// not a question, and there is nothing to return — and the next one
// exits. A dispatch error (compositor died while we lingered) is
// captured as errno (EPIPE).
//
// Headless-safe: no compositor → SKIP, exit 0.
module (module) appapp;
import c; // ImportC: wayland-client + xdg-shell glue (wsi_*)
import instrument;
import (package) corecore.(package) core.stdcstdc.(module) core.stdc.stdioD header file for C99 <stdio.h>
pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html, stdio.h
Source
core/stdc/stdio.d
stdio : (alias) app.printf = int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogcprintf, (alias) app.snprintf = int core.stdc.stdio.snprintf(scope char* s, ulong n, scope const(char*) format, scope const ...) nothrow @nogcsnprintf;
import (package) corecore.(package) core.stdcstdc.(module) core.stdc.stdlibD header file for C99.
pubs.opengroup.org/onlinepubs/009695399/basedefs/stdlib.h.html, stdlib.h
Source
core/stdc/stdlib.d
stdlib : (alias) app.getenv = char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogcgetenv, (alias) app.atoi = int core.stdc.stdlib.atoi(scope const(char*) nptr) nothrow @nogcatoi;
import (package) corecore.(package) core.stdcstdc.(module) core.stdc.stringD header file for C99.
pubs.opengroup.org/onlinepubs/009695399/basedefs/string.h.html, string.h
Source
core/stdc/string.d
string : (alias) app.strcmp = int core.stdc.string.strcmp(scope const(char*) s1, scope const(char*) s2) pure nothrow @nogcstrcmp;
enum int (constant) int app.defaultWidth = 640defaultWidth = 640, (constant) int app.defaultHeight = 480defaultHeight = 480;
// The timed choreography (µs since init). Time-based, not frame-based: after
// set_minimized there may be no frame callbacks left to count with.
enum long (constant) long app.tMaximize = 700000LtMaximize = 700_000;
enum long (constant) long app.tUnmaximize = 1400000LtUnmaximize = 1_400_000;
enum long (constant) long app.tFullscreen = 2100000LtFullscreen = 2_100_000;
enum long (constant) long app.tUnfullscreen = 2800000LtUnfullscreen = 2_800_000;
enum long (constant) long app.tMinimize = 3500000LtMinimize = 3_500_000;
enum long (constant) long app.tReport = 4700000LtReport = 4_700_000; // frame-callback census for the minimized span
struct (struct) app.BufferBuffer
{
wl_buffer* (field) _error_ app.Buffer.handlehandle;
uint* (field) uint* app.Buffer.pixelspixels;
(alias) object.size_t = ulongsize_t (field) ulong app.Buffer.byteSizebyteSize;
int (field) int app.Buffer.widthwidth, (field) int app.Buffer.heightheight;
bool (field) bool app.Buffer.busybusy;
}
__gshared
{
wl_display* _error_ app.g_displayg_display;
wl_registry* _error_ app.g_registryg_registry;
wl_compositor* _error_ app.g_compositorg_compositor;
wl_shm* _error_ app.g_shmg_shm;
xdg_wm_base* _error_ app.g_wmBaseg_wmBase;
wl_surface* _error_ app.g_surfaceg_surface;
xdg_surface* _error_ app.g_xdgSurfaceg_xdgSurface;
xdg_toplevel* _error_ app.g_toplevelg_toplevel;
wl_callback* _error_ app.g_frameCbg_frameCb;
(struct) app.BufferBuffer[2] _error_ app.g_buffersg_buffers;
uint (__gshared global) uint app.g_wmBaseAdvertisedg_wmBaseAdvertised, (__gshared global) uint app.g_wmBaseBoundg_wmBaseBound;
int (__gshared global) int app.g_widthg_width = defaultWidth, (__gshared global) int app.g_heightg_height = defaultHeight;
int (__gshared global) int app.g_pendingWidthg_pendingWidth, (__gshared global) int app.g_pendingHeightg_pendingHeight;
char[160] (__gshared global) char[160] app.g_pendingStatesg_pendingStates; // decoded states array of the latest configure
bool (__gshared global) bool app.g_configuredg_configured, (__gshared global) bool app.g_runningg_running = true, (__gshared global) bool app.g_autoExitg_autoExit;
long (__gshared global) long app.g_runUsCapg_runUsCap = 5_200_000;
int (__gshared global) int app.g_framesg_frames, (__gshared global) int app.g_configuresg_configures;
int (__gshared global) int app.g_phaseg_phase; // next choreography step to fire (0..5)
int (__gshared global) int app.g_framesAtMinimizeg_framesAtMinimize = -1;
bool (__gshared global) bool app.g_reportedg_reported;
int (__gshared global) int app.g_vetoesLeftg_vetoesLeft = 1; // the "dirty document": ignore this many closes
int (__gshared global) int app.g_closesSeeng_closesSeen;
}
// ------------------------------------------------------------ states decode
/// Decode a configure states wl_array into "[a,b,c]" — every value the v6
/// protocol can deliver, plus raw numbers for anything newer.
void app.decodeStatesDecode a configure states wl_array into "a,b,c" — every value the v6
protocol can deliver, plus raw numbers for anything newer.
decodeStates(const(wl_array)* states, char[] outBuf) nothrow @nogc
{
static immutable (unresolved type) stringstring[10] string[10] namesnames = [
"?0", "maximized", "fullscreen", "resizing", "activated",
"tiled_left", "tiled_right", "tiled_top", "tiled_bottom", "suspended",
];
(unresolved type) size_tsize_t _error_ pospos = 0;
void void putc(char c) nothrow @nogcputc(char (parameter) char cc) nothrow @nogc
{
if (pos + 1 < outBuf.outBuf.lengthlength)
outBuf[pos++] = c;
}
putc('[');
const _error_ valsvals = cast(const(uint)*) states.data;
foreach ((parameter) ii; 0 .. states.states.sizesize / uint.sizeof)
{
if (i > 0)
putc(',');
immutable _error_ vv = vals[i];
if (v < names.names.lengthlength)
foreach ((parameter) chch; names[v])
putc(ch);
else // constrained_* (v7) or future states
{
char[12] _error_ numnum = void;
immutable _error_ nn = snprintf(num.ptr, num.num.lengthlength, "%u", v);
foreach ((parameter) chch; num[0 .. n])
putc(ch);
}
}
putc(']');
outBuf[pos] = '\0';
}
// ---------------------------------------------------------- shm buffer pool
bool app.ensureBufferensureBuffer(ref (struct) app.BufferBuffer (parameter) Buffer bb, int (parameter) int ww, int (parameter) int hh) nothrow @nogc
{
if (b.b.handlehandle !is null && (b.b.widthwidth != w || b.b.heightheight != h))
{
wsi_buffer_destroy(b.b.handlehandle);
munmap(b.b.pixelspixels, b.b.byteSizebyteSize);
b = Buffer.init;
}
if (b.b.handlehandle !is null)
return true;
immutable _error_ stridestride = w * 4;
immutable _error_ sizesize = cast((unresolved type) size_tsize_t) stride * h;
immutable _error_ fdfd = memfd_create("wsi-f14", MFD_CLOEXEC);
if (fd < 0 || ftruncate(fd, cast(long) size) != 0)
return false;
void* _error_ memmem = 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_ poolpool = wsi_shm_create_pool(g_shm, fd, cast(int) size);
b.b.handlehandle = wsi_shm_pool_create_buffer(pool, 0, w, h, stride, WL_SHM_FORMAT_XRGB8888);
wsi_shm_pool_destroy(pool);
close(fd);
wsi_buffer_add_listener(b.b.handlehandle, &g_bufferListener, &b);
b.b.pixelspixels = cast(uint*) mem;
b.b.byteSizebyteSize = size;
b.b.widthwidth = w;
b.b.heightheight = h;
return true;
}
void void app.render() nothrow @nogcrender() nothrow @nogc
{
(struct) app.BufferBuffer* (local variable) _error_ bufbuf = null;
foreach (ref (parameter) bb; g_buffers)
if (!b.b.busybusy)
{
buf = &b;
break;
}
if (buf is null)
return; // both held; wl_buffer.release re-renders
if (!ensureBuffer(*buf, g_width, g_height))
{
(__gshared global) bool app.g_runningg_running = false;
return;
}
foreach ((parameter) yy; 0 .. buf.(field) _error_ buf.heightheight) // gradient (scaffold pattern)
{
uint* _error_ rowrow = buf.buf.pixelspixels + cast((unresolved type) size_tsize_t) y * buf.buf.widthwidth;
immutable uint _error_ gg = cast(uint)(y * 255 / (buf.buf.heightheight > 1 ? buf.buf.heightheight - 1 : 1)) << 8;
foreach ((parameter) xx; 0 .. buf.buf.widthwidth)
row[x] = 0xff00_0000
| (cast(uint)(x * 255 / (buf.buf.widthwidth > 1 ? buf.buf.widthwidth - 1 : 1)) << 16) | g;
}
wsi_surface_attach(g_surface, buf.buf.handlehandle, 0, 0);
wsi_surface_damage_buffer(g_surface, 0, 0, buf.buf.widthwidth, buf.buf.heightheight);
if (g_frameCb is null)
{
g_frameCb = wsi_surface_frame(g_surface);
wsi_callback_add_listener(g_frameCb, &g_frameListener, null);
}
wsi_surface_commit(g_surface);
buf.buf.busybusy = true;
}
// ---------------------------------------------------------------- listeners
extern (C) void app.onGlobalonGlobal(void* data, wl_registry* reg, uint name,
const(char)* iface, uint ver) nothrow @nogc
{
if (strcmp(iface, wl_compositor_interface.name) == 0)
g_compositor = cast(wl_compositor*) wsi_registry_bind(reg, name,
&wl_compositor_interface, ver < 4 ? ver : 4);
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)
{
// Bind up to v6: the `suspended` state exists "since 6" — at v1..5 the
// compositor is *forbidden* from sending it, whatever it knows.
g_wmBaseAdvertised = ver;
g_wmBaseBound = ver < 6 ? ver : 6;
g_wmBase = cast(xdg_wm_base*) wsi_registry_bind(reg, name,
&xdg_wm_base_interface, g_wmBaseBound);
instrEvent("wm_base", "advertised=%u bound=%u suspended_possible=%d",
g_wmBaseAdvertised, g_wmBaseBound, g_wmBaseBound >= 6 ? 1 : 0);
}
}
extern (C) void app.onGlobalRemoveonGlobalRemove(void* data, wl_registry* reg, uint name) nothrow @nogc
{
}
extern (C) void app.onWmBasePingonWmBasePing(void* data, xdg_wm_base* (parameter) xdg_wm_base* bb, uint serial) nothrow @nogc
{
wsi_wm_base_pong(b, serial);
}
extern (C) void app.onToplevelConfigureonToplevelConfigure(void* data, xdg_toplevel* t, int (parameter) int ww, int (parameter) int hh,
wl_array* states) nothrow @nogc
{
g_pendingWidth = w;
g_pendingHeight = h;
decodeStates(states, g_pendingStates[]);
}
extern (C) void app.onXdgSurfaceConfigureonXdgSurfaceConfigure(void* data, xdg_surface* s, uint serial) nothrow @nogc
{
immutable _error_ ww = g_pendingWidth > 0 ? g_pendingWidth : defaultWidth;
immutable _error_ hh = g_pendingHeight > 0 ? g_pendingHeight : defaultHeight;
g_configures++;
instrEvent("configure", "serial=%u size=%dx%d states=%s",
serial, w, h, g_pendingStates.ptr);
wsi_xdg_surface_ack_configure(s, serial);
immutable _error_ resizedresized = w != g_width || h != g_height;
g_width = w;
g_height = h;
if (!g_configured)
{
g_configured = true;
instrFirstConfigure();
render();
}
else if (resized)
render();
}
/// xdg_toplevel.close — "a one-way *event*, not a request/response pair. The
/// client decides; ignoring it IS the veto" (no reply exists to send).
extern (C) void app.onToplevelClosexdg_toplevel.close — "a one-way event, not a request/response pair. The
client decides; ignoring it IS the veto" (no reply exists to send).
onToplevelClose(void* data, xdg_toplevel* t) nothrow @nogc
{
g_closesSeen++;
if (g_vetoesLeft > 0)
{
g_vetoesLeft--;
instrEvent("close_requested", "n=%d verdict=vetoed dirty=1 note=event ignored, no reply sent",
g_closesSeen);
return; // the whole veto: do nothing
}
instrEvent("close_requested", "n=%d verdict=accepted", g_closesSeen);
instrCloseRequested();
g_running = false;
}
extern (C) void app.onToplevelConfigureBoundsonToplevelConfigureBounds(void* data, xdg_toplevel* t, int (parameter) int ww, int (parameter) int hh) nothrow @nogc
{
}
extern (C) void app.onToplevelWmCapabilitiesonToplevelWmCapabilities(void* data, xdg_toplevel* t, wl_array* caps) nothrow @nogc
{
char[160] _error_ bufbuf = void;
decodeCaps(caps, buf[]);
instrEvent("wm_capabilities", "caps=%s", buf.ptr);
}
/// xdg_toplevel.wm_capabilities (v5): does the compositor even *do* minimize?
void app.decodeCapsxdg_toplevel.wm_capabilities (v5): does the compositor even do minimize?
decodeCaps(const(wl_array)* caps, char[] outBuf) nothrow @nogc
{
static immutable (unresolved type) stringstring[5] string[5] namesnames = ["?0", "window_menu", "maximize", "fullscreen", "minimize"];
(unresolved type) size_tsize_t _error_ pospos = 0;
const _error_ valsvals = cast(const(uint)*) caps.data;
outBuf[pos++] = '[';
foreach ((parameter) ii; 0 .. caps.caps.sizesize / uint.sizeof)
{
if (i > 0)
outBuf[pos++] = ',';
immutable _error_ vv = vals[i];
foreach ((parameter) chch; v < names.names.lengthlength ? names[v] : "?")
if (pos + 2 < outBuf.outBuf.lengthlength)
outBuf[pos++] = ch;
}
outBuf[pos++] = ']';
outBuf[pos] = '\0';
}
extern (C) void app.onBufferReleaseonBufferRelease(void* data, wl_buffer* (parameter) wl_buffer* bb) nothrow @nogc
{
(cast((unresolved type) BufferBuffer*) data).(cast(Buffer*)data).busybusy = false;
}
extern (C) void app.onFrameDoneonFrameDone(void* data, wl_callback* cb, uint timeMs) nothrow @nogc
{
wsi_callback_destroy(cb);
g_frameCb = null;
g_frames++;
if (g_frames == 1)
instrFirstPixelPresented();
if (g_running && g_configured)
render();
}
__gshared wl_registry_listener _error_ app.g_registryListenerg_registryListener = {&onGlobal, &onGlobalRemove};
__gshared xdg_wm_base_listener _error_ app.g_wmBaseListenerg_wmBaseListener = {&onWmBasePing};
__gshared xdg_surface_listener _error_ app.g_xdgSurfaceListenerg_xdgSurfaceListener = {&onXdgSurfaceConfigure};
__gshared xdg_toplevel_listener _error_ app.g_toplevelListenerg_toplevelListener = {
&onToplevelConfigure, &onToplevelClose,
&onToplevelConfigureBounds, &onToplevelWmCapabilities
};
__gshared wl_buffer_listener _error_ app.g_bufferListenerg_bufferListener = {&onBufferRelease};
__gshared wl_callback_listener _error_ app.g_frameListenerg_frameListener = {&onFrameDone};
// -------------------------------------------------------------- choreography
void void app.step(int phase) nothrow @nogcstep(int (parameter) int phasephase) nothrow @nogc
{
final switch ((parameter) int phasephase)
{
case 0:
instrEvent("state_request", "kind=set_maximized frames=%d", g_frames);
wsi_toplevel_set_maximized(g_toplevel);
break;
case 1:
instrEvent("state_request", "kind=unset_maximized frames=%d", g_frames);
wsi_toplevel_unset_maximized(g_toplevel);
break;
case 2:
instrEvent("state_request", "kind=set_fullscreen frames=%d", g_frames);
wsi_toplevel_set_fullscreen(g_toplevel);
break;
case 3:
instrEvent("state_request", "kind=unset_fullscreen frames=%d", g_frames);
wsi_toplevel_unset_fullscreen(g_toplevel);
break;
case 4:
// No unset_minimized exists, no `minimized` state will ever appear in
// a configure — only the user (or compositor IPC) can bring it back.
instrEvent("state_request", "kind=set_minimized frames=%d note=no unset twin, no state feedback", g_frames);
wsi_toplevel_set_minimized(g_toplevel);
(__gshared global) int app.g_framesAtMinimizeg_framesAtMinimize = (__gshared global) int app.g_framesg_frames;
break;
}
}
__gshared immutable long[5] (immutable global) immutable(long[5]) app.g_stepAtg_stepAt = [
(constant) long app.tMaximize = 700000LtMaximize, (constant) long app.tUnmaximize = 1400000LtUnmaximize, (constant) long app.tFullscreen = 2100000LtFullscreen, (constant) long app.tUnfullscreen = 2800000LtUnfullscreen, (constant) long app.tMinimize = 3500000LtMinimize,
];
// --------------------------------------------------------------------- main
int int D main()main()
{
instrInit("f14-state");
bool bool app.main.env(const(char)* n) nothrow @nogc @systemenv(const(char)* (parameter) const(char)* nn)
{
const (local variable) const(char*) vv = char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogcgetenv((parameter) const(char)* nn);
return (local variable) const(char*) vv !is null && *(local variable) const(char*) vv == '1';
}
(__gshared global) bool app.g_autoExitg_autoExit = bool app.main.env(const(char)* n) nothrow @nogc @systemenv("WSI_AUTO_EXIT");
if (const (local variable) const(char*) msms = char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogcgetenv("WSI_RUN_MS"))
(__gshared global) long app.g_runUsCapg_runUsCap = int core.stdc.stdlib.atoi(scope const(char*) nptr) nothrow @nogcatoi((local variable) const(char*) msms) * 1000L;
if (const (local variable) const(char*) vv = char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogcgetenv("WSI_VETO_CLOSE"))
(__gshared global) int app.g_vetoesLeftg_vetoesLeft = int core.stdc.stdlib.atoi(scope const(char*) nptr) nothrow @nogcatoi((local variable) const(char*) vv);
g_display = wl_display_connect(null);
if (g_display is null)
{
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogcprintf("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);
wl_display_roundtrip(g_display);
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 @nogcprintf("SKIP: compositor lacks a required global\n");
wl_display_disconnect(g_display);
return 0;
}
wsi_wm_base_add_listener(g_wmBase, &g_wmBaseListener, null);
g_surface = wsi_compositor_create_surface(g_compositor);
g_xdgSurface = wsi_wm_base_get_xdg_surface(g_wmBase, g_surface);
wsi_xdg_surface_add_listener(g_xdgSurface, &g_xdgSurfaceListener, null);
g_toplevel = wsi_xdg_surface_get_toplevel(g_xdgSurface);
wsi_toplevel_add_listener(g_toplevel, &g_toplevelListener, null);
wsi_toplevel_set_title(g_toplevel, "wsi-f14-window-state");
const (local variable) const(char*) appIdappId = char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogcgetenv("WSI_APP_ID");
wsi_toplevel_set_app_id(g_toplevel, appId !is null ? appId : "wsi-f14-window-state");
instrWindowCreated();
wsi_surface_commit(g_surface); // mandatory no-buffer commit
// Poll-driven loop: dispatch when the fd is readable, otherwise tick the
// clock. Blocking in wl_display_dispatch would hang the choreography the
// moment frame callbacks stop (minimized/occluded — F04).
immutable (local variable) immutable(_error_) fdfd = wl_display_get_fd(g_display);
while ((__gshared global) bool app.g_runningg_running)
{
if (wl_display_dispatch_pending(g_display) == -1)
break;
wl_display_flush(g_display);
pollfd (local variable) _error_ pfdpfd = {fd: fd, events: POLLIN};
if (poll(&pfd, 1, 50) > 0 && (pfd.revents & POLLIN))
{
if (wl_display_dispatch(g_display) == -1)
break;
}
immutable (local variable) immutable(_error_) nownow = instrNowUs();
if ((__gshared global) bool app.g_autoExitg_autoExit && (__gshared global) bool app.g_configuredg_configured)
{
while ((__gshared global) int app.g_phaseg_phase < (immutable global) immutable(long[5]) app.g_stepAtg_stepAt.(constant) ulong immutable(long[5]).length = 5LUlength && now > (immutable global) immutable(long[5]) app.g_stepAtg_stepAt[(__gshared global) int app.g_phaseg_phase])
void app.step(int phase) nothrow @nogcstep((__gshared global) int app.g_phaseg_phase++);
if (!(__gshared global) bool app.g_reportedg_reported && (__gshared global) int app.g_framesAtMinimizeg_framesAtMinimize >= 0 && now > tReport)
{
(__gshared global) bool app.g_reportedg_reported = true;
instrEvent("minimize_census",
"frames_in_%dms_after_set_minimized=%d total_frames=%d",
cast(int)((tReport - tMinimize) / 1000), g_frames - g_framesAtMinimize,
g_frames);
}
if (now > (__gshared global) long app.g_runUsCapg_runUsCap)
(__gshared global) bool app.g_runningg_running = false;
}
}
immutable (local variable) immutable(_error_) errerr = wl_display_get_error(g_display);
if (err != 0) // the compositor died while we lingered (the EPIPE capture)
instrEvent("dispatch_error", "errno=%d note=%s", err,
err == 32 ? "EPIPE - compositor gone, veto moot".ptr : "connection error".ptr);
foreach (ref (parameter) bb; g_buffers)
if (b.b.handlehandle !is null)
{
wsi_buffer_destroy(b.b.handlehandle);
munmap(b.b.pixelspixels, b.b.byteSizebyteSize);
}
if (g_frameCb !is null)
wsi_callback_destroy(g_frameCb);
wsi_toplevel_destroy(g_toplevel);
wsi_xdg_surface_destroy(g_xdgSurface);
wsi_surface_destroy(g_surface);
wsi_wm_base_destroy(g_wmBase);
wl_proxy_destroy(cast(wl_proxy*) g_shm);
wl_proxy_destroy(cast(wl_proxy*) g_compositor);
wl_proxy_destroy(cast(wl_proxy*) g_registry);
wl_display_disconnect(g_display);
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogcprintf("ok: %d frames, %d configures, closes_seen=%d vetoes_left=%d\n",
(__gshared global) int app.g_framesg_frames, (__gshared global) int app.g_configuresg_configures, (__gshared global) int app.g_closesSeeng_closesSeen, (__gshared global) int app.g_vetoesLeftg_vetoesLeft);
return 0;
}