137 lines
5.6 KiB
C
137 lines
5.6 KiB
C
// Desktop protocol smoke test. Exercises window ownership, shared surfaces, z-order, focus, capture, and pointer policy.
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#include <ntlite/desktop.h>
|
|
#include <ntlite/syscall.h>
|
|
|
|
#define TEST_WIDTH 160u
|
|
#define TEST_HEIGHT 100u
|
|
|
|
// Exits without depending on a compiler runtime return path.
|
|
static void exit_now(int code) {
|
|
while (true) SysExitProcess(code);
|
|
}
|
|
|
|
static void print(const char* text) {
|
|
SYS_WRITE_CONSOLE_REQUEST request = { sizeof(request), SysSvFromCstr(text) };
|
|
(void)SysWriteConsole(&request);
|
|
}
|
|
|
|
static void print_status(KSTATUS status) {
|
|
static const char digits[] = "0123456789ABCDEF";
|
|
char buffer[11] = "0x00000000";
|
|
for (uint32_t i = 0; i < 8u; ++i)
|
|
buffer[2u + i] = digits[(status >> ((7u - i) * 4u)) & 0xFu];
|
|
print(buffer);
|
|
}
|
|
|
|
// Reports one failed desktop-smoke operation with its native status.
|
|
static void fail_status(const char* operation, KSTATUS status, int code) {
|
|
print("desktop_smoke: ");
|
|
print(operation);
|
|
print(" failed status=");
|
|
print_status(status);
|
|
print("\n");
|
|
exit_now(code);
|
|
}
|
|
|
|
// Reports one failed desktop-smoke invariant.
|
|
static void fail(const char* message, int code) {
|
|
print("desktop_smoke: ");
|
|
print(message);
|
|
print("\n");
|
|
exit_now(code);
|
|
}
|
|
|
|
// Fills one mapped XRGB surface with a deterministic test pattern.
|
|
static void fill_surface(void* base, uint32_t pitch) {
|
|
uint8_t* bytes = (uint8_t*)base;
|
|
for (uint32_t y = 0; y < TEST_HEIGHT; ++y) {
|
|
uint32_t* row = (uint32_t*)(bytes + (size_t)y * pitch);
|
|
for (uint32_t x = 0; x < TEST_WIDTH; ++x)
|
|
row[x] = 0x00202080u + ((x & 0x3Fu) << 16) + ((y & 0x3Fu) << 8);
|
|
}
|
|
}
|
|
|
|
// Exercises the first final-shaped DWM client contract.
|
|
int main(void) {
|
|
SYS_HANDLE desktop = SYS_HANDLE_INVALID;
|
|
KSTATUS status = NtlDesktopConnect(&desktop);
|
|
if (!KSUCCESS(status)) fail_status("connect /Sessions/0/Desktop", status, 1);
|
|
|
|
SYS_HANDLE surface = SYS_HANDLE_INVALID;
|
|
SYS_CREATE_SURFACE_REQUEST createSurface;
|
|
memset(&createSurface, 0, sizeof(createSurface));
|
|
createSurface.Size = sizeof(createSurface);
|
|
createSurface.Width = TEST_WIDTH;
|
|
createSurface.Height = TEST_HEIGHT;
|
|
createSurface.Format = SYS_SURFACE_FORMAT_XRGB8888;
|
|
createSurface.Flags = SYS_SURFACE_FLAG_NONE;
|
|
createSurface.HandleOut = &surface;
|
|
status = SysCreateSurface(&createSurface);
|
|
if (!KSUCCESS(status)) fail_status("create surface", status, 2);
|
|
|
|
void* base = (void*)0;
|
|
uint32_t pitch = 0;
|
|
status = SysMapSurface(surface, SYS_SURFACE_MAP_READ | SYS_SURFACE_MAP_WRITE, &base, &pitch);
|
|
if (!KSUCCESS(status)) fail_status("map surface", status, 3);
|
|
if (!base || pitch < TEST_WIDTH * sizeof(uint32_t)) fail("invalid surface mapping", 3);
|
|
fill_surface(base, pitch);
|
|
|
|
DISPLAY_RECT bounds = { 40, 40, (int32_t)TEST_WIDTH, (int32_t)TEST_HEIGHT };
|
|
NTL_WINDOW_ID window = 0;
|
|
status = NtlDesktopCreateWindow(desktop, &bounds, &window);
|
|
if (!KSUCCESS(status)) fail_status("create window", status, 4);
|
|
if (window == 0) fail("create window returned zero ID", 4);
|
|
status = NtlDesktopAttachSurface(desktop, window, surface);
|
|
if (!KSUCCESS(status)) fail_status("attach surface", status, 5);
|
|
status = NtlDesktopSetVisible(desktop, window, 1u);
|
|
if (!KSUCCESS(status)) fail_status("show window", status, 6);
|
|
|
|
DISPLAY_RECT damage = { 0, 0, (int32_t)TEST_WIDTH, (int32_t)TEST_HEIGHT };
|
|
status = SysCommitSurface(surface, &damage, 1u, 0);
|
|
if (!KSUCCESS(status)) fail_status("commit surface", status, 7);
|
|
|
|
NTL_DESKTOP_REPLY query;
|
|
memset(&query, 0, sizeof(query));
|
|
status = NtlDesktopQueryWindow(desktop, window, &query);
|
|
if (!KSUCCESS(status)) fail_status("query window", status, 8);
|
|
if (query.WindowId != window || !query.Visible || !query.HasSurface ||
|
|
query.SurfaceWidth != TEST_WIDTH || query.SurfaceHeight != TEST_HEIGHT)
|
|
fail("query window returned inconsistent state", 8);
|
|
|
|
status = NtlDesktopRequestFocus(desktop, window);
|
|
if (!KSUCCESS(status)) fail_status("request focus", status, 9);
|
|
status = NtlDesktopSetPointerMode(desktop, window, NTL_DESKTOP_POINTER_CONFINED);
|
|
if (!KSUCCESS(status)) fail_status("set confined pointer mode", status, 10);
|
|
status = NtlDesktopRequestCapture(desktop, window);
|
|
if (!KSUCCESS(status)) fail_status("request capture", status, 11);
|
|
status = NtlDesktopSetPointerMode(desktop, window, NTL_DESKTOP_POINTER_RELATIVE_LOCKED);
|
|
if (!KSUCCESS(status)) fail_status("set relative-locked pointer mode", status, 12);
|
|
status = NtlDesktopReleaseCapture(desktop, window);
|
|
if (!KSUCCESS(status)) fail_status("release capture", status, 13);
|
|
status = NtlDesktopSetPointerMode(desktop, window, NTL_DESKTOP_POINTER_FREE);
|
|
if (!KSUCCESS(status)) fail_status("set free pointer mode", status, 14);
|
|
|
|
bounds.X += 24;
|
|
bounds.Y += 18;
|
|
status = NtlDesktopSetBounds(desktop, window, &bounds);
|
|
if (!KSUCCESS(status)) fail_status("set bounds", status, 15);
|
|
status = NtlDesktopLowerWindow(desktop, window);
|
|
if (!KSUCCESS(status)) fail_status("lower window", status, 16);
|
|
status = NtlDesktopRaiseWindow(desktop, window);
|
|
if (!KSUCCESS(status)) fail_status("raise window", status, 17);
|
|
status = NtlDesktopDetachSurface(desktop, window);
|
|
if (!KSUCCESS(status)) fail_status("detach surface", status, 18);
|
|
status = NtlDesktopDestroyWindow(desktop, window);
|
|
if (!KSUCCESS(status)) fail_status("destroy window", status, 19);
|
|
|
|
(void)SysUnmapSurface(base);
|
|
(void)SysCloseHandle(surface);
|
|
(void)NtlDesktopClose(desktop);
|
|
print("desktop_smoke: PASS\n");
|
|
return 0;
|
|
}
|