82 lines
2.6 KiB
C
82 lines
2.6 KiB
C
// Logical input-service smoke test. It verifies RSSRV publication and nonblocking protocol behavior without requiring user input.
|
|
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <ntlite/input_service.h>
|
|
#include <ntlite/resource.h>
|
|
#include <ntlite/syscall.h>
|
|
|
|
static int gFailures;
|
|
|
|
static void print(const char* text) {
|
|
SYS_WRITE_CONSOLE_REQUEST request = { sizeof(request), SysSvFromCstr(text) };
|
|
(void)SysWriteConsole(&request);
|
|
}
|
|
|
|
static void fail(const char* text) {
|
|
print("input_service_smoke: FAIL: ");
|
|
print(text);
|
|
print("\n");
|
|
gFailures++;
|
|
}
|
|
|
|
// Checks one status against an allowed nonblocking result pair.
|
|
static void expect_try_status(const char* what, KSTATUS status) {
|
|
if (status != NTLSTATUS_SUCCESS && status != NTLSTATUS_WOULD_BLOCK)
|
|
fail(what);
|
|
}
|
|
|
|
// Exercises RSSRV's logical-input listener and snapshot contract.
|
|
int main(void) {
|
|
print("input_service_smoke: start\n");
|
|
|
|
SYS_HANDLE resource = SYS_HANDLE_INVALID;
|
|
KSTATUS status = NtlResourceConnect(&resource);
|
|
if (!KSUCCESS(status)) {
|
|
fail("resource connect");
|
|
return 1;
|
|
}
|
|
uint32_t kind = NTL_RESOURCE_KIND_INVALID;
|
|
status = NtlResourceQuery(resource, SYS_SV_LITERAL(NTL_INPUT_SERVICE_PATH), &kind);
|
|
if (!KSUCCESS(status) || kind != NTL_RESOURCE_KIND_CAPABILITY)
|
|
fail("/Services/Input publication");
|
|
(void)NtlResourceClose(resource);
|
|
|
|
if (NtlInputConnect((SYS_HANDLE*)0) != NTLSTATUS_INVALID_PARAMETER)
|
|
fail("connect null");
|
|
|
|
SYS_HANDLE input = SYS_HANDLE_INVALID;
|
|
status = NtlInputConnect(&input);
|
|
if (!KSUCCESS(status) || input == SYS_HANDLE_INVALID) {
|
|
fail("input connect");
|
|
return 1;
|
|
}
|
|
|
|
NTL_INPUT_STATE state;
|
|
memset(&state, 0, sizeof(state));
|
|
status = NtlInputQueryState(input, &state);
|
|
if (!KSUCCESS(status) || state.Size != sizeof(state) || state.Flags != NTL_INPUT_STATE_FLAG_NONE)
|
|
fail("query state");
|
|
if (state.MouseX < 0 || state.MouseY < 0)
|
|
fail("pointer bounds");
|
|
|
|
INPUT_KEY_RECORD key;
|
|
status = NtlInputPeekEvent(input, 0, &key);
|
|
expect_try_status("peek key", status);
|
|
|
|
INPUT_MOUSE_EVENT mouse;
|
|
status = NtlInputPeekMouse(input, 0, &mouse);
|
|
expect_try_status("peek mouse", status);
|
|
|
|
NTL_INPUT_STATE defaultState;
|
|
memset(&defaultState, 0, sizeof(defaultState));
|
|
status = NtlInputQueryDefaultState(&defaultState);
|
|
if (!KSUCCESS(status) || defaultState.Size != sizeof(defaultState))
|
|
fail("default query state");
|
|
|
|
(void)NtlInputClose(input);
|
|
if (gFailures) return 1;
|
|
print("input_service_smoke: PASS\n");
|
|
return 0;
|
|
}
|