/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/

#ifndef NO_BUILD_CONFIG
#include <stddef.h>

/**
 * Pen test suite
 */

#define SDL_internal_h_ /* Inhibit dynamic symbol redefinitions that clash with ours */

/* ================= System Under Test (SUT) ================== */
/* Renaming SUT operations to avoid link-time symbol clashes */
#define SDL_GetPens            SDL_SUT_GetPens
#define SDL_GetPenStatus       SDL_SUT_GetPenStatus
#define SDL_GetPenFromGUID     SDL_SUT_GetPenFromGUID
#define SDL_GetPenGUID         SDL_SUT_GetPenGUID
#define SDL_PenConnected       SDL_SUT_PenConnected
#define SDL_GetPenName         SDL_SUT_GetPenName
#define SDL_GetPenCapabilities SDL_SUT_GetPenCapabilities
#define SDL_GetPenType         SDL_SUT_GetPenType

#define SDL_GetPenPtr                SDL_SUT_GetPenPtr
#define SDL_PenModifyBegin           SDL_SUT_PenModifyBegin
#define SDL_PenModifyAddCapabilities SDL_SUT_PenModifyAddCapabilities
#define SDL_PenModifyForWacomID      SDL_SUT_PenModifyForWacomID
#define SDL_PenUpdateGUIDForWacom    SDL_SUT_PenUpdateGUIDForWacom
#define SDL_PenUpdateGUIDForType     SDL_SUT_PenUpdateGUIDForType
#define SDL_PenUpdateGUIDForGeneric  SDL_SUT_PenUpdateGUIDForGeneric
#define SDL_PenModifyEnd             SDL_SUT_PenModifyEnd
#define SDL_PenGCMark                SDL_SUT_PenGCMark
#define SDL_PenGCSweep               SDL_SUT_PenGCSweep
#define SDL_SendPenMotion            SDL_SUT_SendPenMotion
#define SDL_SendPenButton            SDL_SUT_SendPenButton
#define SDL_SendPenTipEvent          SDL_SUT_SendPenTipEvent
#define SDL_SendPenWindowEvent       SDL_SUT_SendPenWindowEvent
#define SDL_PenPerformHitTest        SDL_SUT_PenPerformHitTest
#define SDL_PenInit                  SDL_SUT_PenInit
#define SDL_PenQuit                  SDL_SUT_PenQuit

/* ================= Mock API ================== */

#include <stdlib.h>
#include <SDL3/SDL.h>
#include <SDL3/SDL_test.h>
/* For SDL_Window, SDL_Mouse, SDL_MouseID: */
#include "../src/events/SDL_mouse_c.h"
/* Divert calls to mock mouse API: */
#define SDL_SendMouseMotion       SDL_Mock_SendMouseMotion
#define SDL_SendMouseButton       SDL_Mock_SendMouseButton
#define SDL_GetMouse              SDL_Mock_GetMouse
#define SDL_MousePositionInWindow SDL_Mock_MousePositionInWindow
#define SDL_SetMouseFocus         SDL_Mock_SetMouseFocus

/* Mock mouse API */
static int SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, SDL_bool relative, float x, float y);
static int SDL_SendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button);
static SDL_Mouse *SDL_GetMouse(void);
static SDL_bool SDL_MousePositionInWindow(SDL_Window *window, float x, float y);
static void SDL_SetMouseFocus(SDL_Window *window);

/* Import SUT code with macro-renamed function names  */
#define SDL_waylanddyn_h_ /* hack: suppress spurious build problem with libdecor.h on Wayland */
#include "../src/events/SDL_pen.c"
#include "../src/events/SDL_pen_c.h"


/* ================= Internal SDL API Compatibility ================== */
/* Mock implementations of Pen -> Mouse calls */
/* Not thread-safe! */

static SDL_bool SDL_MousePositionInWindow(SDL_Window *window, float x, float y)
{
    return SDL_TRUE;
}

static int _mouseemu_last_event = 0;
static float _mouseemu_last_x = 0.0f;
static float _mouseemu_last_y = 0.0f;
static int _mouseemu_last_mouseid = 0;
static int _mouseemu_last_button = 0;
static SDL_bool _mouseemu_last_relative = SDL_FALSE;
static int _mouseemu_last_focus = -1;

static int SDL_SendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
{
    if (mouseID == SDL_PEN_MOUSEID) {
        _mouseemu_last_event = (state == SDL_PRESSED) ? SDL_EVENT_MOUSE_BUTTON_DOWN : SDL_EVENT_MOUSE_BUTTON_UP;
        _mouseemu_last_button = button;
        _mouseemu_last_mouseid = mouseID;
    }
    return 1;
}

static int SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, SDL_bool relative, float x, float y)
{
    if (mouseID == SDL_PEN_MOUSEID) {
        _mouseemu_last_event = SDL_EVENT_MOUSE_MOTION;
        _mouseemu_last_x = x;
        _mouseemu_last_y = y;
        _mouseemu_last_mouseid = mouseID;
        _mouseemu_last_relative = relative;
    }
    return 1;
}

static SDL_Mouse *SDL_GetMouse(void)
{
    static SDL_Mouse dummy_mouse;

    return &dummy_mouse;
}

static void SDL_SetMouseFocus(SDL_Window *window)
{
    _mouseemu_last_focus = window ? 1 : 0;
}

/* ================= Test Case Support ================== */

#define PEN_NUM_TEST_IDS 8

/* Helper functions */

/* Iterate over all pens to find index for pen ID, otherwise -1 */
static int _pen_iterationFindsPenIDAt(SDL_PenID needle)
{
    int i;
    int num_pens = -1;

    SDL_PenID *pens = SDL_GetPens(&num_pens);
    /* Check for (a) consistency and (b) ability to handle NULL parameter */
    SDL_PenID *pens2 = SDL_GetPens(NULL);

    SDLTest_AssertCheck(num_pens >= 0,
                        "SDL_GetPens() yielded %d pens", num_pens);
    SDLTest_AssertCheck(pens[num_pens] == 0,
                        "SDL_GetPens() not 0 terminated (num_pens = %d)", num_pens);
    SDLTest_AssertCheck(pens2[num_pens] == 0,
                        "SDL_GetPens(NULL) not 0 terminated (num_pens = %d)", num_pens);

    for (i = 0; i < num_pens; ++i) {
        SDLTest_AssertCheck(pens[i] == pens2[i],
                            "SDL_GetPens(&i) and SDL_GetPens(NULL) disagree at index %d/%d", i, num_pens);
        SDLTest_AssertCheck(pens[i] != SDL_PEN_INVALID,
                            "Invalid pen ID %08lx at index %d/%d after SDL_GetPens()", (unsigned long) pens[i], i, num_pens);
    }
    SDL_free(pens2);

    for (i = 0; pens[i]; ++i) {
        SDL_PenID pen_id = pens[i];

        SDLTest_AssertCheck(pen_id != SDL_PEN_INVALID,
                            "Invalid pen ID %08lx at index %d/%d after SDL_GetPens()", (unsigned long) pen_id, i, num_pens);
        if (pen_id == needle) {
            SDL_free(pens);
            return i;
        }
    }
    SDL_free(pens);
    return -1;
}

/* Retrieve number of pens and sanity-check SDL_GetPens() */
static int
_num_pens(void)
{
    int num_pens = -1;
    SDL_PenID *pens = SDL_GetPens(&num_pens);
    SDLTest_AssertCheck(pens != NULL,
                        "SDL_GetPens() => NULL");
    SDLTest_AssertCheck(num_pens >= 0,
                        "SDL_GetPens() reports %d pens", num_pens);
    SDLTest_AssertCheck(pens[num_pens] == 0,
                        "SDL_GetPens()[%d] != 0", num_pens);
    SDL_free(pens);
    return num_pens;
}

/* Assert number of pens is as expected */
static void _AssertCheck_num_pens(int expected, char *location)
{
    int num_pens = _num_pens();
    SDLTest_AssertCheck(expected == num_pens,
                        "Expected SDL_GetPens() =>count = %d, actual = %d: %s", expected, num_pens, location);
}

/* ---------------------------------------- */
/* Test device deallocation */

typedef struct /* Collection of pen (de)allocation information  */
{
    unsigned int deallocated_id_flags;         /* ith bits set to 1 if the ith test_id is deallocated */
    unsigned int deallocated_deviceinfo_flags; /* ith bits set to 1 if deviceinfo as *int with value i was deallocated */
    SDL_PenID ids[PEN_NUM_TEST_IDS];
    SDL_GUID guids[PEN_NUM_TEST_IDS];
    SDL_Window *window;
    int num_ids;
    int initial_pen_count;
} pen_testdata;

/* SDL_PenGCSweep(): callback for tracking pen deallocation */
static void _pen_testdata_callback(Uint32 deviceid, void *deviceinfo, void *tracker_ref)
{
    pen_testdata *tracker = (pen_testdata *)tracker_ref;
    int offset = -1;
    int i;

    for (i = 0; i < tracker->num_ids; ++i) {
        if (deviceid == tracker->ids[i]) {
            tracker->deallocated_id_flags |= (1 << i);
        }
    }

    SDLTest_AssertCheck(deviceinfo != NULL,
                        "Device %lu has deviceinfo",
                        (unsigned long) deviceid);
    offset = *((int *)deviceinfo);
    SDLTest_AssertCheck(offset >= 0 && offset <= 31,
                        "Device %lu has well-formed deviceinfo %d",
                        (unsigned long) deviceid, offset);
    tracker->deallocated_deviceinfo_flags |= 1 << offset;
    SDL_free(deviceinfo);
}

/* GC Sweep tracking: update "tracker->deallocated_id_flags" and "tracker->deallocated_deviceinfo_flags" to record deallocations */
static void _pen_trackGCSweep(pen_testdata *tracker)
{
    tracker->deallocated_id_flags = 0;
    tracker->deallocated_deviceinfo_flags = 0;
    SDL_PenGCSweep(tracker, _pen_testdata_callback);
}

/* Finds a number of unused pen IDs (does not allocate them).  Also initialises GUIDs. */
static void _pen_unusedIDs(pen_testdata *tracker, int count)
{
    static Uint8 guidmod = 0; /* Ensure uniqueness as long as we use no more than 256 test pens */
    Uint32 synthetic_penid = 1000u;
    int index = 0;

    tracker->num_ids = count;
    SDLTest_AssertCheck(count < PEN_NUM_TEST_IDS, "Test setup: Valid number of test IDs requested: %d", (int)count);

    while (count--) {
        int k;

        while (SDL_GetPenPtr(synthetic_penid)) {
            ++synthetic_penid;
        }
        tracker->ids[index] = synthetic_penid;
        for (k = 0; k < 15; ++k) {
            tracker->guids[index].data[k] = (Uint8)((16 * k) + index);
        }
        tracker->guids[index].data[15] = ++guidmod;

        ++synthetic_penid;
        ++index;
    }
}

#define DEVICEINFO_UNCHANGED -17

/* Allocate deviceinfo for pen */
static void _pen_setDeviceinfo(SDL_Pen *pen, int deviceinfo)
{
    if (deviceinfo == DEVICEINFO_UNCHANGED) {
        SDLTest_AssertCheck(pen->deviceinfo != NULL,
                            "pen->deviceinfo was already set for %p (%lu), as expected",
                            pen, (unsigned long) pen->header.id);
    } else {
        int *data = (int *)SDL_malloc(sizeof(int));
        *data = deviceinfo;

        SDLTest_AssertCheck(pen->deviceinfo == NULL,
                            "pen->deviceinfo was NULL for %p (%lu) when requesting deviceinfo %d",
                            pen, (unsigned long) pen->header.id, deviceinfo);

        pen->deviceinfo = data;
    }
    SDL_PenModifyEnd(pen, SDL_TRUE);
}

/* ---------------------------------------- */
/* Back up and restore device information */

typedef struct deviceinfo_backup
{
    Uint32 deviceid;
    void *deviceinfo;
    struct deviceinfo_backup *next;
} deviceinfo_backup;

/* SDL_PenGCSweep(): Helper callback for collecting all deviceinfo records */
static void _pen_accumulate_gc_sweep(Uint32 deviceid, void *deviceinfo, void *backup_ref)
{
    deviceinfo_backup **db_ref = (deviceinfo_backup **)backup_ref;
    deviceinfo_backup *next = *db_ref;

    *db_ref = SDL_calloc(sizeof(deviceinfo_backup), 1);
    (*db_ref)->deviceid = deviceid;
    (*db_ref)->deviceinfo = deviceinfo;
    (*db_ref)->next = next;
}

/* SDL_PenGCSweep(): Helper callback that must never be called  */
static void _pen_assert_impossible(Uint32 deviceid, void *deviceinfo, void *backup_ref)
{
    SDLTest_AssertCheck(0, "Deallocation for deviceid %lu during enableAndRestore: not expected",
                        (unsigned long) deviceid);
}

/* Disable all pens and store their status */
static deviceinfo_backup *_pen_disableAndBackup(void)
{
    deviceinfo_backup *backup = NULL;

    SDL_PenGCMark();
    SDL_PenGCSweep(&backup, _pen_accumulate_gc_sweep);
    return backup;
}

/* Restore all pens to their previous status */
static void _pen_enableAndRestore(deviceinfo_backup *backup, int test_marksweep)
{
    if (test_marksweep) {
        SDL_PenGCMark();
    }
    while (backup) {
        SDL_Pen *disabledpen = SDL_GetPenPtr(backup->deviceid);
        deviceinfo_backup *next = backup->next;

        SDL_PenModifyEnd(SDL_PenModifyBegin(disabledpen->header.id),
                         SDL_TRUE);
        disabledpen->deviceinfo = backup->deviceinfo;

        SDL_free(backup);
        backup = next;
    }
    if (test_marksweep) {
        SDL_PenGCSweep(NULL, _pen_assert_impossible);
    }
}

static struct SDL_Window _test_window = { 0 };

/* ---------------------------------------- */
/* Default set-up and tear down routines    */

/* Back up existing pens, allocate fresh ones but don't assign them yet */
static deviceinfo_backup *_setup_test(pen_testdata *ptest, int pens_for_testing)
{
    int i;
    deviceinfo_backup *backup;

    /* Get number of pens */
    SDL_free(SDL_GetPens(&ptest->initial_pen_count));

    /* Provide fake window for window enter/exit simulation */
    _test_window.id = 0x7e57da7a;
    _test_window.w = 1600;
    _test_window.h = 1200;
    ptest->window = &_test_window;

    /* Grab unused pen IDs for testing */
    _pen_unusedIDs(ptest, pens_for_testing);
    for (i = 0; i < pens_for_testing; ++i) {
        int index = _pen_iterationFindsPenIDAt(ptest->ids[i]);
        SDLTest_AssertCheck(-1 == index,
                            "Registered PenID(%lu) since index %d == -1",
                            (unsigned long) ptest->ids[i], index);
    }

    /* Remove existing pens, but back up */
    backup = _pen_disableAndBackup();

    _AssertCheck_num_pens(0, "after disabling and backing up all current pens");
    SDLTest_AssertPass("Removed existing pens");

    return backup;
}

static void _teardown_test_general(pen_testdata *ptest, deviceinfo_backup *backup, int with_gc_test)
{
    /* Restore previously existing pens */
    _pen_enableAndRestore(backup, with_gc_test);

    /* validate */
    SDLTest_AssertPass("Restored pens to pre-test state");
    _AssertCheck_num_pens(ptest->initial_pen_count, "after restoring all initial pens");
}

static void _teardown_test(pen_testdata *ptest, deviceinfo_backup *backup)
{
    _teardown_test_general(ptest, backup, 0);
}

static void _teardown_test_with_gc(pen_testdata *ptest, deviceinfo_backup *backup)
{
    _teardown_test_general(ptest, backup, 1);
}

/* ---------------------------------------- */
/* Pen simulation                           */

#define SIMPEN_ACTION_DONE           0
#define SIMPEN_ACTION_MOVE_X         1
#define SIMPEN_ACTION_MOVE_Y         2
#define SIMPEN_ACTION_AXIS           3
#define SIMPEN_ACTION_MOTION_EVENT   4 /* epxlicit motion event */
#define SIMPEN_ACTION_MOTION_EVENT_S 5 /* send motion event but expect it to be suppressed */
#define SIMPEN_ACTION_PRESS          6 /* implicit update event */
#define SIMPEN_ACTION_RELEASE        7 /* implicit update event */
#define SIMPEN_ACTION_DOWN           8 /* implicit update event */
#define SIMPEN_ACTION_UP             9 /* implicit update event */
#define SIMPEN_ACTION_ERASER_MODE    10

/* Individual action in pen simulation script */
typedef struct simulated_pen_action
{
    int type;
    int pen_index; /* index into the list of simulated pens */
    int index;     /* button or axis number, if needed */
    float update;  /* x,y; for AXIS, update[0] is the updated axis */
} simulated_pen_action;

static simulated_pen_action _simpen_event(int type, int pen_index, int index, float v, int line_nr)
{
    simulated_pen_action action;
    action.type = type;
    action.pen_index = pen_index;
    action.index = index;
    action.update = v;

    /* Sanity check-- turned out to be necessary */
    if ((type == SIMPEN_ACTION_PRESS || type == SIMPEN_ACTION_RELEASE) && index == 0) {
        SDL_Log("Error: SIMPEN_EVENT_BUTTON must have button > 0  (first button has number 1!), in line %d!", line_nr);
        exit(1);
    }
    return action;
}

/* STEP is passed in later (C macros use dynamic scoping) */

#define SIMPEN_DONE() \
    STEP _simpen_event(SIMPEN_ACTION_DONE, 0, 0, 0.0f, __LINE__)
#define SIMPEN_MOVE(pen_index, x, y)                                         \
    STEP _simpen_event(SIMPEN_ACTION_MOVE_X, (pen_index), 0, (x), __LINE__); \
    STEP _simpen_event(SIMPEN_ACTION_MOVE_Y, (pen_index), 0, (y), __LINE__)

#define SIMPEN_AXIS(pen_index, axis, y) \
    STEP _simpen_event(SIMPEN_ACTION_AXIS, (pen_index), (axis), (y), __LINE__)

#define SIMPEN_EVENT_MOTION(pen_index) \
    STEP _simpen_event(SIMPEN_ACTION_MOTION_EVENT, (pen_index), 0, 0.0f, __LINE__)

#define SIMPEN_EVENT_MOTION_SUPPRESSED(pen_index) \
    STEP _simpen_event(SIMPEN_ACTION_MOTION_EVENT_S, (pen_index), 0, 0.0f, __LINE__)

#define SIMPEN_EVENT_BUTTON(pen_index, push, button) \
    STEP _simpen_event((push) ? SIMPEN_ACTION_PRESS : SIMPEN_ACTION_RELEASE, (pen_index), (button), 0.0f, __LINE__)

#define SIMPEN_EVENT_TIP(pen_index, touch, tip) \
    STEP _simpen_event((touch) ? SIMPEN_ACTION_DOWN : SIMPEN_ACTION_UP, (pen_index), tip, 0.0f, __LINE__)

#define SIMPEN_SET_ERASER(pen_index, eraser_mode) \
    STEP _simpen_event(SIMPEN_ACTION_ERASER_MODE, (pen_index), eraser_mode, 0.0f, __LINE__)

static void
_pen_dump(const char *prefix, SDL_Pen *pen)
{
    int i;
    char *axes_str;

    if (!pen) {
        SDL_Log("(NULL pen)");
        return;
    }

    axes_str = SDL_strdup("");
    for (i = 0; i < SDL_PEN_NUM_AXES; ++i) {
        char *old_axes_str = axes_str;
        SDL_asprintf(&axes_str, "%s\t%f", old_axes_str, pen->last.axes[i]);
        SDL_free(old_axes_str);
    }
    SDL_Log("%s: pen %lu (%s): status=%04lx, flags=%lx, x,y=(%f, %f) axes = %s",
            prefix,
            (unsigned long) pen->header.id,
            pen->name,
            (unsigned long) pen->last.buttons,
            (unsigned long) pen->header.flags,
            pen->last.x, pen->last.y,
            axes_str);
    SDL_free(axes_str);
}

/* Runs until the next event has been issued or we are done and returns pointer to it.
   Returns NULL once we hit SIMPEN_ACTION_DONE.
   Updates simulated_pens accordingly.  There must be as many simulated_pens as the highest pen_index used in
   any of the "steps".
   Also validates the internal state with expectations (via SDL_GetPenStatus()) and updates the, but does not poll SDL events. */
static simulated_pen_action *
_pen_simulate(simulated_pen_action *steps, int *step_counter, SDL_Pen *simulated_pens, int num_pens)
{
    SDL_bool done = SDL_FALSE;
    SDL_bool dump_pens = SDL_FALSE;
    unsigned int mask;
    int pen_nr;

    do {
        simulated_pen_action step = steps[*step_counter];
        SDL_Pen *simpen = &simulated_pens[step.pen_index];

        if (step.pen_index >= num_pens) {
            SDLTest_AssertCheck(0,
                                "Unexpected pen index %d at step %d, action %d", step.pen_index, *step_counter, step.type);
            return NULL;
        }

        switch (step.type) {
        case SIMPEN_ACTION_DONE:
            SDLTest_AssertPass("SIMPEN_ACTION_DONE");
            return NULL;

        case SIMPEN_ACTION_MOVE_X:
            SDLTest_AssertPass("SIMPEN_ACTION_MOVE_X [pen %d] : y <- %f", step.pen_index, step.update);
            simpen->last.x = step.update;
            break;

        case SIMPEN_ACTION_MOVE_Y:
            SDLTest_AssertPass("SIMPEN_ACTION_MOVE_Y [pen %d] : x <- %f", step.pen_index, step.update);
            simpen->last.y = step.update;
            break;

        case SIMPEN_ACTION_AXIS:
            SDLTest_AssertPass("SIMPEN_ACTION_AXIS [pen %d] : axis[%d] <- %f", step.pen_index, step.index, step.update);
            simpen->last.axes[step.index] = step.update;
            break;

        case SIMPEN_ACTION_MOTION_EVENT:
            done = SDL_TRUE;
            SDLTest_AssertCheck(SDL_SendPenMotion(0, simpen->header.id, SDL_TRUE,
                                                  &simpen->last),
                                "SIMPEN_ACTION_MOTION_EVENT [pen %d]", step.pen_index);
            break;

        case SIMPEN_ACTION_MOTION_EVENT_S:
            SDLTest_AssertCheck(!SDL_SendPenMotion(0, simpen->header.id, SDL_TRUE,
                                                   &simpen->last),
                                "SIMPEN_ACTION_MOTION_EVENT_SUPPRESSED [pen %d]", step.pen_index);
            break;

        case SIMPEN_ACTION_PRESS:
            mask = (1 << (step.index - 1));
            simpen->last.buttons |= mask;
            SDLTest_AssertCheck(SDL_SendPenButton(0, simpen->header.id, SDL_PRESSED, (Uint8)step.index),
                                "SIMPEN_ACTION_PRESS [pen %d]: button %d (mask %x)", step.pen_index, step.index, mask);
            done = SDL_TRUE;
            break;

        case SIMPEN_ACTION_RELEASE:
            mask = ~(1 << (step.index - 1));
            simpen->last.buttons &= mask;
            SDLTest_AssertCheck(SDL_SendPenButton(0, simpen->header.id, SDL_RELEASED, (Uint8)step.index),
                                "SIMPEN_ACTION_RELEASE [pen %d]: button %d (mask %x)", step.pen_index, step.index, mask);
            done = SDL_TRUE;
            break;

        case SIMPEN_ACTION_DOWN:
            simpen->last.buttons |= SDL_PEN_DOWN_MASK;
            SDLTest_AssertCheck(SDL_SendPenTipEvent(0, simpen->header.id, SDL_PRESSED),
                                "SIMPEN_ACTION_DOWN [pen %d]: (mask %lx)", step.pen_index, SDL_PEN_DOWN_MASK);
            done = SDL_TRUE;
            break;

        case SIMPEN_ACTION_UP:
            simpen->last.buttons &= ~SDL_PEN_DOWN_MASK;
            SDLTest_AssertCheck(SDL_SendPenTipEvent(0, simpen->header.id, SDL_RELEASED),
                                "SIMPEN_ACTION_UP [pen %d]: (mask %lx)", step.pen_index, ~SDL_PEN_DOWN_MASK);
            done = SDL_TRUE;
            break;

        case SIMPEN_ACTION_ERASER_MODE: {
            Uint32 pmask;
            SDL_Pen *pen = SDL_PenModifyBegin(simpen->header.id);

            if (step.index) {
                pmask = SDL_PEN_ERASER_MASK;
            } else {
                pmask = SDL_PEN_INK_MASK;
            }

            SDL_PenModifyAddCapabilities(pen, pmask);
            SDL_PenModifyEnd(pen, SDL_TRUE);

            simpen->header.flags &= ~(SDL_PEN_INK_MASK | SDL_PEN_ERASER_MASK);
            simpen->header.flags |= pmask;
            break;
        }

        default:
            SDLTest_AssertCheck(0,
                                "Unexpected pen simulation action %d", step.type);
            return NULL;
        }
        ++(*step_counter);
    } while (!done);

    for (pen_nr = 0; pen_nr < num_pens; ++pen_nr) {
        SDL_Pen *simpen = &simulated_pens[pen_nr];
        float x = -1.0f, y = -1.0f;
        float axes[SDL_PEN_NUM_AXES];
        Uint32 actual_flags = SDL_GetPenStatus(simpen->header.id, &x, &y, axes, SDL_PEN_NUM_AXES);
        int i;

        if (simpen->last.x != x || simpen->last.y != y) {
            SDLTest_AssertCheck(0, "Coordinate mismatch in pen %d", pen_nr);
            dump_pens = SDL_TRUE;
        }
        if ((actual_flags & ~(SDL_PEN_INK_MASK | SDL_PEN_ERASER_MASK)) != (simpen->last.buttons & ~(SDL_PEN_INK_MASK | SDL_PEN_ERASER_MASK))) {
            SDLTest_AssertCheck(0, "Status mismatch in pen %d (reported: %08x)", pen_nr, (unsigned int)actual_flags);
            dump_pens = SDL_TRUE;
        }
        if ((actual_flags & (SDL_PEN_INK_MASK | SDL_PEN_ERASER_MASK)) != (simpen->header.flags & (SDL_PEN_INK_MASK | SDL_PEN_ERASER_MASK))) {
            SDLTest_AssertCheck(0, "Flags mismatch in pen %d (reported: %08x)", pen_nr, (unsigned int)actual_flags);
            dump_pens = SDL_TRUE;
        }
        for (i = 0; i < SDL_PEN_NUM_AXES; ++i) {
            if (axes[i] != simpen->last.axes[i]) {
                SDLTest_AssertCheck(0, "Axis %d mismatch in pen %d", pen_nr, i);
                dump_pens = SDL_TRUE;
            }
        }
    }

    if (dump_pens) {
        int i;
        for (i = 0; i < num_pens; ++i) {
            SDL_Log("==== pen #%d", i);
            _pen_dump("expect", simulated_pens + i);
            _pen_dump("actual", SDL_GetPenPtr(simulated_pens[i].header.id));
        }
    }

    return &steps[(*step_counter) - 1];
}

/* Init simulated_pens with suitable initial state */
static void
_pen_simulate_init(pen_testdata *ptest, SDL_Pen *simulated_pens, int num_pens)
{
    int i;
    for (i = 0; i < num_pens; ++i) {
        simulated_pens[i] = *SDL_GetPenPtr(ptest->ids[i]);
    }
}

/* ---------------------------------------- */
/* Other helper functions                   */

/* "standard" pen registration process */
static SDL_Pen *
_pen_register(SDL_PenID penid, SDL_GUID guid, char *name, Uint32 flags)
{
    SDL_Pen *pen = SDL_PenModifyBegin(penid);
    pen->guid = guid;
    SDL_strlcpy(pen->name, name, SDL_PEN_MAX_NAME);
    SDL_PenModifyAddCapabilities(pen, flags);
    return pen;
}

/* Test whether EXPECTED and ACTUAL of type TY agree.  Their C format string must be FMT.
   MESSAGE is a string with one format string, passed as ARG0. */
#define SDLTest_AssertEq1(TY, FMT, EXPECTED, ACTUAL, MESSAGE, ARG0)                                                                                               \
    {                                                                                                                                                             \
        TY _t_expect = (EXPECTED);                                                                                                                                \
        TY _t_actual = (ACTUAL);                                                                                                                                  \
        SDLTest_AssertCheck(_t_expect == _t_actual, "L%d: " MESSAGE ": expected " #EXPECTED " = " FMT ", actual = " FMT, __LINE__, (ARG0), _t_expect, _t_actual); \
    }

/* ================= Test Case Implementation ================== */

/**
 * @brief Check basic pen device introduction and iteration, as well as basic queries
 *
 * @sa SDL_GetPens, SDL_GetPenName, SDL_GetPenCapabilities
 */
static int
pen_iteration(void *arg)
{
    pen_testdata ptest;
    int i;
    char long_pen_name[SDL_PEN_MAX_NAME + 10];
    const char *name;
    deviceinfo_backup *backup;

    /* Check initial pens */
    SDL_PumpEvents();
    SDLTest_AssertPass("SDL_GetPens() => count = %d", _num_pens());

    /* Grab unused pen IDs for testing */
    backup = _setup_test(&ptest, 3); /* validates that we have zero pens */

    /* Re-run GC, track deallocations */
    SDL_PenGCMark();
    _pen_trackGCSweep(&ptest);
    _AssertCheck_num_pens(0, "after second GC pass");
    SDLTest_AssertCheck(ptest.deallocated_id_flags == 0, "No unexpected device deallocations");
    SDLTest_AssertCheck(ptest.deallocated_deviceinfo_flags == 0, "No unexpected deviceinfo deallocations");
    SDLTest_AssertPass("Validated that GC on empty pen set is idempotent");

    /* Add three pens, validate */
    SDL_PenGCMark();

    SDL_memset(long_pen_name, 'x', sizeof(long_pen_name)); /* Include pen name that is too long */
    long_pen_name[sizeof(long_pen_name) - 1] = 0;

    _pen_setDeviceinfo(_pen_register(ptest.ids[0], ptest.guids[0], "pen 0",
                                     SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK),
                       16);
    _pen_setDeviceinfo(_pen_register(ptest.ids[2], ptest.guids[2], long_pen_name,
                                     SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK | SDL_PEN_AXIS_XTILT_MASK),
                       20);
    _pen_setDeviceinfo(_pen_register(ptest.ids[1], ptest.guids[1], "pen 1",
                                     SDL_PEN_ERASER_MASK | SDL_PEN_AXIS_PRESSURE_MASK | SDL_PEN_AXIS_YTILT_MASK),
                       24);
    _pen_trackGCSweep(&ptest);

    _AssertCheck_num_pens(3, "after allocating three pens");

    SDLTest_AssertCheck(ptest.deallocated_id_flags == 0, "No unexpected device deallocations");
    SDLTest_AssertCheck(ptest.deallocated_deviceinfo_flags == 0, "No unexpected deviceinfo deallocations");

    for (i = 0; i < 3; ++i) {
        /* Check that all pens are accounted for */
        int index = _pen_iterationFindsPenIDAt(ptest.ids[i]);
        SDLTest_AssertCheck(-1 != index, "Found PenID(%lu)", (unsigned long) ptest.ids[i]);
    }
    SDLTest_AssertPass("Validated that all three pens are indexable");

    /* Check pen properties */
    SDLTest_AssertCheck(0 == SDL_strcmp("pen 0", SDL_GetPenName(ptest.ids[0])),
                        "Pen #0 name");
    SDLTest_AssertCheck((SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK) == SDL_GetPenCapabilities(ptest.ids[0], NULL),
                        "Pen #0 capabilities");

    SDLTest_AssertCheck(0 == SDL_strcmp("pen 1", SDL_GetPenName(ptest.ids[1])),
                        "Pen #1 name");
    SDLTest_AssertCheck((SDL_PEN_ERASER_MASK | SDL_PEN_AXIS_PRESSURE_MASK | SDL_PEN_AXIS_YTILT_MASK) == SDL_GetPenCapabilities(ptest.ids[1], NULL),
                        "Pen #1 capabilities");

    name = SDL_GetPenName(ptest.ids[2]);
    SDLTest_AssertCheck(SDL_PEN_MAX_NAME - 1 == SDL_strlen(name),
                        "Pen #2 name length");
    SDLTest_AssertCheck(0 == SDL_memcmp(name, long_pen_name, SDL_PEN_MAX_NAME - 1),
                        "Pen #2 name contents");
    SDLTest_AssertCheck((SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK | SDL_PEN_AXIS_XTILT_MASK) == SDL_GetPenCapabilities(ptest.ids[2], NULL),
                        "Pen #2 capabilities");
    SDLTest_AssertPass("Pen registration and basic queries");

    /* Re-run GC, track deallocations */
    SDL_PenGCMark();
    _pen_trackGCSweep(&ptest);
    _AssertCheck_num_pens(0, "after third GC pass");
    SDLTest_AssertCheck(ptest.deallocated_id_flags == 0x07,
                        "No unexpected device deallocation : %08x", ptest.deallocated_id_flags);
    SDLTest_AssertCheck(ptest.deallocated_deviceinfo_flags == 0x01110000,
                        "No unexpected deviceinfo deallocation : %08x ", ptest.deallocated_deviceinfo_flags);
    SDLTest_AssertPass("Validated that GC on empty pen set is idempotent");

    /* tear down and finish */
    _teardown_test(&ptest, backup);
    return TEST_COMPLETED;
}

static void
_expect_pen_attached(SDL_PenID penid)
{
    SDLTest_AssertCheck(-1 != _pen_iterationFindsPenIDAt(penid),
                        "Found PenID(%lu)", (unsigned long) penid);
    SDLTest_AssertCheck(SDL_PenConnected(penid),
                        "Pen %lu was attached, as expected", (unsigned long) penid);
}

static void
_expect_pen_detached(SDL_PenID penid)
{
    SDLTest_AssertCheck(-1 == _pen_iterationFindsPenIDAt(penid),
                        "Did not find PenID(%lu), as expected", (unsigned long) penid);
    SDLTest_AssertCheck(!SDL_PenConnected(penid),
                        "Pen %lu was detached, as expected", (unsigned long) penid);
}

#define ATTACHED(i) (1 << (i))

static void
_expect_pens_attached_or_detached(SDL_PenID *pen_ids, int ids, Uint32 mask)
{
    int i;
    int attached_count = 0;
    for (i = 0; i < ids; ++i) {
        if (mask & (1 << i)) {
            ++attached_count;
            _expect_pen_attached(pen_ids[i]);
        } else {
            _expect_pen_detached(pen_ids[i]);
        }
    }
    _AssertCheck_num_pens(attached_count, "While checking attached/detached status");
}

/**
 * @brief Check pen device hotplugging
 *
 * @sa SDL_GetPens, SDL_GetPenName, SDL_GetPenCapabilities, SDL_PenConnected
 */
static int
pen_hotplugging(void *arg)
{
    pen_testdata ptest;
    deviceinfo_backup *backup = _setup_test(&ptest, 3);
    SDL_GUID checkguid;

    /* Add two pens */
    SDL_PenGCMark();

    _pen_setDeviceinfo(_pen_register(ptest.ids[0], ptest.guids[0], "pen 0", SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK),
                       16);
    _pen_setDeviceinfo(_pen_register(ptest.ids[2], ptest.guids[2], "pen 2", SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK),
                       24);
    _pen_trackGCSweep(&ptest);

    _AssertCheck_num_pens(2, "after allocating two pens (pass 1)");
    SDLTest_AssertCheck(ptest.deallocated_id_flags == 0, "No unexpected device deallocation (pass 1)");
    SDLTest_AssertCheck(ptest.deallocated_deviceinfo_flags == 0, "No unexpected deviceinfo deallocation (pass 1)");

    _expect_pens_attached_or_detached(ptest.ids, 3, ATTACHED(0) | ATTACHED(2));
    SDLTest_AssertPass("Validated hotplugging (pass 1): attachmend of two pens");

    /* Introduce pen #1, remove pen #2 */
    SDL_PenGCMark();
    _pen_setDeviceinfo(_pen_register(ptest.ids[0], ptest.guids[0], "pen 0", SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK),
                       DEVICEINFO_UNCHANGED);
    _pen_setDeviceinfo(_pen_register(ptest.ids[1], ptest.guids[1], "pen 1", SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK),
                       20);
    _pen_trackGCSweep(&ptest);

    _AssertCheck_num_pens(2, "after allocating two pens (pass 2)");
    SDLTest_AssertCheck(ptest.deallocated_id_flags == 0x04, "No unexpected device deallocation (pass 2): %x", ptest.deallocated_id_flags);
    SDLTest_AssertCheck(ptest.deallocated_deviceinfo_flags == 0x01000000, "No unexpected deviceinfo deallocation (pass 2): %x", ptest.deallocated_deviceinfo_flags);

    _expect_pens_attached_or_detached(ptest.ids, 3, ATTACHED(0) | ATTACHED(1));
    SDLTest_AssertPass("Validated hotplugging (pass 2): unplug one, attach another");

    /* Return to previous state (#0 and #2 attached) */
    SDL_PenGCMark();

    _pen_setDeviceinfo(_pen_register(ptest.ids[0], ptest.guids[0], "pen 0", SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK | SDL_PEN_AXIS_YTILT),
                       DEVICEINFO_UNCHANGED);
    _pen_setDeviceinfo(_pen_register(ptest.ids[2], ptest.guids[2], "pen 2", SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK),
                       24);
    _pen_trackGCSweep(&ptest);

    _AssertCheck_num_pens(2, "after allocating two pens (pass 3)");
    SDLTest_AssertCheck(ptest.deallocated_id_flags == 0x02, "No unexpected device deallocation (pass 3)");
    SDLTest_AssertCheck(ptest.deallocated_deviceinfo_flags == 0x00100000, "No unexpected deviceinfo deallocation (pass 3)");

    _expect_pens_attached_or_detached(ptest.ids, 3, ATTACHED(0) | ATTACHED(2));
    SDLTest_AssertPass("Validated hotplugging (pass 3): return to state of pass 1");

    /* Introduce pen #1, remove pen #0 */
    SDL_PenGCMark();
    _pen_setDeviceinfo(_pen_register(ptest.ids[1], ptest.guids[1], "pen 1", SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK),
                       20);
    _pen_setDeviceinfo(_pen_register(ptest.ids[2], ptest.guids[2], "pen 2", SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK),
                       DEVICEINFO_UNCHANGED);
    _pen_trackGCSweep(&ptest);

    _AssertCheck_num_pens(2, "after allocating two pens (pass 4)");
    SDLTest_AssertCheck(ptest.deallocated_id_flags == 0x01, "No unexpected device deallocation (pass 4): %x", ptest.deallocated_id_flags);
    SDLTest_AssertCheck(ptest.deallocated_deviceinfo_flags == 0x00010000, "No unexpected deviceinfo deallocation (pass 4): %x", ptest.deallocated_deviceinfo_flags);

    _expect_pens_attached_or_detached(ptest.ids, 3, ATTACHED(1) | ATTACHED(2));
    SDLTest_AssertPass("Validated hotplugging (pass 5)");

    /* Check detached pen */
    SDLTest_AssertCheck(0 == SDL_strcmp("pen 0", SDL_GetPenName(ptest.ids[0])),
                        "Pen #0 name");
    checkguid = SDL_GetPenGUID(ptest.ids[0]);
    SDLTest_AssertCheck(0 == SDL_memcmp(ptest.guids[0].data, checkguid.data, sizeof(ptest.guids[0].data)),
                        "Pen #0 guid");
    SDLTest_AssertCheck((SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK | SDL_PEN_AXIS_YTILT) == SDL_GetPenCapabilities(ptest.ids[0], NULL),
                        "Pen #0 capabilities");
    SDLTest_AssertPass("Validated that detached pens retained name, GUID, axis info after pass 5");

    /* Individually detach #1 dn #2 */
    _expect_pens_attached_or_detached(ptest.ids, 3, ATTACHED(1) | ATTACHED(2));
    SDL_PenModifyEnd(SDL_PenModifyBegin(ptest.ids[1]), SDL_FALSE);
    _expect_pens_attached_or_detached(ptest.ids, 3, ATTACHED(2));

    SDL_PenModifyEnd(SDL_PenModifyBegin(ptest.ids[2]), SDL_FALSE);
    _expect_pens_attached_or_detached(ptest.ids, 3, 0);

    SDLTest_AssertPass("Validated individual hotplugging (pass 6)");

    /* Individually attach all */
    SDL_PenModifyEnd(SDL_PenModifyBegin(ptest.ids[2]), SDL_TRUE);
    _expect_pens_attached_or_detached(ptest.ids, 3, ATTACHED(2));

    SDL_PenModifyEnd(SDL_PenModifyBegin(ptest.ids[0]), SDL_TRUE);
    _expect_pens_attached_or_detached(ptest.ids, 3, ATTACHED(0) | ATTACHED(2));

    SDL_PenModifyEnd(SDL_PenModifyBegin(ptest.ids[1]), SDL_TRUE);
    _expect_pens_attached_or_detached(ptest.ids, 3, ATTACHED(0) | ATTACHED(1) | ATTACHED(2));
    SDLTest_AssertPass("Validated individual hotplugging (pass 7)");

    SDL_PenGCMark();
    _pen_trackGCSweep(&ptest);
    _AssertCheck_num_pens(0, "after hotplugging test (cleanup)");
    SDLTest_AssertCheck(ptest.deallocated_id_flags == 0x06, "No unexpected device deallocation (cleanup): %x", ptest.deallocated_id_flags);
    SDLTest_AssertCheck(ptest.deallocated_deviceinfo_flags == 0x01100000, "No unexpected deviceinfo deallocation (pass 4): %x", ptest.deallocated_deviceinfo_flags);

    _teardown_test_with_gc(&ptest, backup);

    return TEST_COMPLETED;
}

/**
 * @brief Check pen device GUID handling
 *
 * @sa SDL_GetPenGUID
 */
static int
pen_GUIDs(void *arg)
{
    int i;
    char *names[4] = { "pen 0", "pen 1", "pen 2", "pen 3" };
    pen_testdata ptest;
    deviceinfo_backup *backup;

    backup = _setup_test(&ptest, 4);

    /* Define four pens */
    SDL_PenGCMark();
    for (i = 0; i < 4; ++i) {
        _pen_setDeviceinfo(_pen_register(ptest.ids[i], ptest.guids[i], names[i], SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK),
                           20);
    }
    _pen_trackGCSweep(&ptest);

    /* Detach pens 0 and 2 */
    SDL_PenGCMark();
    for (i = 1; i < 4; i += 2) {
        _pen_setDeviceinfo(_pen_register(ptest.ids[i], ptest.guids[i], names[i], SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK),
                           DEVICEINFO_UNCHANGED);
    }
    _pen_trackGCSweep(&ptest);

    for (i = 0; i < 4; ++i) {
        SDLTest_AssertCheck(ptest.ids[i] == SDL_GetPenFromGUID(ptest.guids[i]),
                            "GUID search succeeded for %d", i);
    }

    /* detach all */
    SDL_PenGCMark();
    _pen_trackGCSweep(&ptest);

    _teardown_test(&ptest, backup);
    SDLTest_AssertPass("Pen ID lookup by GUID");

    return TEST_COMPLETED;
}

/**
 * @brief Check pen device button reporting
 *
 */
static int
pen_buttonReporting(void *arg)
{
    int i;
    int button_nr, pen_nr;
    pen_testdata ptest;
    SDL_Event event;
    SDL_PenStatusInfo update;
    float axes[SDL_PEN_NUM_AXES + 1];
    const float expected_x[2] = { 10.0f, 20.0f };
    const float expected_y[2] = { 11.0f, 21.0f };
    const Uint32 all_axes = SDL_PEN_AXIS_PRESSURE_MASK | SDL_PEN_AXIS_XTILT_MASK | SDL_PEN_AXIS_YTILT_MASK | SDL_PEN_AXIS_DISTANCE_MASK | SDL_PEN_AXIS_ROTATION_MASK | SDL_PEN_AXIS_SLIDER_MASK;

    /* Register pen */
    deviceinfo_backup *backup = _setup_test(&ptest, 2);
    SDL_PenGCMark();
    _pen_setDeviceinfo(_pen_register(ptest.ids[0], ptest.guids[0], "test pen",
                                     SDL_PEN_INK_MASK | all_axes),
                       20);
    _pen_setDeviceinfo(_pen_register(ptest.ids[1], ptest.guids[1], "test eraser",
                                     SDL_PEN_ERASER_MASK | all_axes),
                       24);
    _pen_trackGCSweep(&ptest);

    /* Position mouse suitably before we start */
    for (i = 0; i <= SDL_PEN_NUM_AXES; ++i) {
        axes[i] = 0.0625f * i; /* initialise with numbers that can be represented precisely in IEEE 754 and
                                  are > 0.0f and <= 1.0f */
    }

    /* Let pens enter the test window */
    SDL_SendPenWindowEvent(0, ptest.ids[0], ptest.window);
    SDL_SendPenWindowEvent(0, ptest.ids[1], ptest.window);

    update.x = expected_x[0];
    update.y = expected_y[0];
    SDL_memcpy(update.axes, axes, sizeof(float) * SDL_PEN_NUM_AXES);
    SDL_SendPenMotion(0, ptest.ids[0], SDL_TRUE, &update);
    update.x = expected_x[1];
    update.y = expected_y[1];
    SDL_memcpy(update.axes, axes + 1, sizeof(float) * SDL_PEN_NUM_AXES);
    SDL_SendPenMotion(0, ptest.ids[1], SDL_TRUE, &update);

    while (SDL_PollEvent(&event))
        ; /* Flush event queue */

    /* Trigger pen tip events for PEN_DOWN */
    SDLTest_AssertPass("Touch pens to surface");

    for (pen_nr = 0; pen_nr < 2; ++pen_nr) {
        float *expected_axes = axes + pen_nr;
        SDL_bool found_event = SDL_FALSE;
        Uint16 pen_state = 0x0000 | SDL_PEN_DOWN_MASK;
        Uint8 tip = SDL_PEN_TIP_INK;

        if (pen_nr == 1) {
            pen_state |= SDL_PEN_ERASER_MASK;
            tip = SDL_PEN_TIP_ERASER;
        }

        SDL_SendPenTipEvent(0, ptest.ids[pen_nr], SDL_PRESSED);

        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_EVENT_PEN_DOWN) {
                SDLTest_AssertCheck(event.ptip.which == ptest.ids[pen_nr],
                            "Received SDL_EVENT_PEN_DOWN from correct pen");
                SDLTest_AssertCheck(event.ptip.tip == (pen_nr == 0)? SDL_PEN_TIP_INK : SDL_PEN_TIP_ERASER,
                                    "Received SDL_EVENT_PEN_DOWN for correct tip");
                SDLTest_AssertCheck(event.ptip.state == SDL_PRESSED,
                                    "Received SDL_EVENT_PEN_DOWN but and marked SDL_PRESSED");
                SDLTest_AssertCheck(event.ptip.tip == tip,
                                    "Received tip %x but expected %x", event.ptip.tip, tip);
                SDLTest_AssertCheck(event.ptip.pen_state == pen_state,
                                    "Received SDL_EVENT_PEN_DOWN, and state %04x == %04x (expected)",
                                    event.pbutton.pen_state, pen_state);
                SDLTest_AssertCheck((event.ptip.x == expected_x[pen_nr]) && (event.ptip.y == expected_y[pen_nr]),
                                    "Received SDL_EVENT_PEN_DOWN event at correct coordinates: (%f, %f) vs (%f, %f) (expected)",
                                    event.pbutton.x, event.pbutton.y, expected_x[pen_nr], expected_y[pen_nr]);
                SDLTest_AssertCheck(0 == SDL_memcmp(expected_axes, event.pbutton.axes, sizeof(float) * SDL_PEN_NUM_AXES),
                                    "Received SDL_EVENT_PEN_DOWN event with correct axis values");
                found_event = SDL_TRUE;
            }
            SDLTest_AssertCheck(found_event,
                                "Received the expected SDL_EVENT_PEN_DOWN event");
        }
    }

    SDLTest_AssertPass("Pen and eraser set up for button testing");

    /* Actual tests start: pen, then eraser */
    for (pen_nr = 0; pen_nr < 2; ++pen_nr) {
        Uint16 pen_state = 0x0000 | SDL_PEN_DOWN_MASK;
        float *expected_axes = axes + pen_nr;

        if (pen_nr == 1) {
            pen_state |= SDL_PEN_ERASER_MASK;
        }
        for (button_nr = 1; button_nr <= 8; ++button_nr) {
            SDL_bool found_event = SDL_FALSE;
            pen_state |= (1 << (button_nr - 1));

            SDL_SendPenButton(0, ptest.ids[pen_nr], SDL_PRESSED, (Uint8)button_nr);
            while (SDL_PollEvent(&event)) {
                if (event.type == SDL_EVENT_PEN_BUTTON_DOWN) {
                    SDLTest_AssertCheck(event.pbutton.which == ptest.ids[pen_nr],
                                        "Received SDL_EVENT_PEN_BUTTON_DOWN from correct pen");
                    SDLTest_AssertCheck(event.pbutton.button == button_nr,
                                        "Received SDL_EVENT_PEN_BUTTON_DOWN from correct button");
                    SDLTest_AssertCheck(event.pbutton.state == SDL_PRESSED,
                                        "Received SDL_EVENT_PEN_BUTTON_DOWN but and marked SDL_PRESSED");
                    SDLTest_AssertCheck(event.pbutton.pen_state == pen_state,
                                        "Received SDL_EVENT_PEN_BUTTON_DOWN, and state %04x == %04x (expected)",
                                        event.pbutton.pen_state, pen_state);
                    SDLTest_AssertCheck((event.pbutton.x == expected_x[pen_nr]) && (event.pbutton.y == expected_y[pen_nr]),
                                        "Received SDL_EVENT_PEN_BUTTON_DOWN event at correct coordinates: (%f, %f) vs (%f, %f) (expected)",
                                        event.pbutton.x, event.pbutton.y, expected_x[pen_nr], expected_y[pen_nr]);
                    SDLTest_AssertCheck(0 == SDL_memcmp(expected_axes, event.pbutton.axes, sizeof(float) * SDL_PEN_NUM_AXES),
                                        "Received SDL_EVENT_PEN_BUTTON_DOWN event with correct axis values");
                    if (0 != SDL_memcmp(expected_axes, event.pbutton.axes, sizeof(float) * SDL_PEN_NUM_AXES)) {
                        int ax;
                        for (ax = 0; ax < SDL_PEN_NUM_AXES; ++ax) {
                            SDL_Log("\tax %d\t%.5f\t%.5f expected (equal=%d)",
                                    ax,
                                    event.pbutton.axes[ax], expected_axes[ax],
                                    event.pbutton.axes[ax] == expected_axes[ax]);
                        }
                    }
                    found_event = SDL_TRUE;
                }
            }
            SDLTest_AssertCheck(found_event,
                                "Received the expected SDL_EVENT_PEN_BUTTON_DOWN event");
        }
    }
    SDLTest_AssertPass("Pressed all buttons");

    /* Release every other button */
    for (pen_nr = 0; pen_nr < 2; ++pen_nr) {
        Uint16 pen_state = 0x00ff | SDL_PEN_DOWN_MASK; /* 8 buttons pressed */
        float *expected_axes = axes + pen_nr;

        if (pen_nr == 1) {
            pen_state |= SDL_PEN_ERASER_MASK;
        }
        for (button_nr = pen_nr + 1; button_nr <= 8; button_nr += 2) {
            SDL_bool found_event = SDL_FALSE;
            pen_state &= ~(1 << (button_nr - 1));

            SDL_SendPenButton(0, ptest.ids[pen_nr], SDL_RELEASED, (Uint8)button_nr);
            while (SDL_PollEvent(&event)) {
                if (event.type == SDL_EVENT_PEN_BUTTON_UP) {
                    SDLTest_AssertCheck(event.pbutton.which == ptest.ids[pen_nr],
                                        "Received SDL_EVENT_PEN_BUTTON_UP from correct pen");
                    SDLTest_AssertCheck(event.pbutton.button == button_nr,
                                        "Received SDL_EVENT_PEN_BUTTON_UP from correct button");
                    SDLTest_AssertCheck(event.pbutton.state == SDL_RELEASED,
                                        "Received SDL_EVENT_PEN_BUTTON_UP and is marked SDL_RELEASED");
                    SDLTest_AssertCheck(event.pbutton.pen_state == pen_state,
                                        "Received SDL_EVENT_PEN_BUTTON_UP, and state %04x == %04x (expected)",
                                        event.pbutton.pen_state, pen_state);
                    SDLTest_AssertCheck((event.pbutton.x == expected_x[pen_nr]) && (event.pbutton.y == expected_y[pen_nr]),
                                        "Received SDL_EVENT_PEN_BUTTON_UP event at correct coordinates");
                    SDLTest_AssertCheck(0 == SDL_memcmp(expected_axes, event.pbutton.axes, sizeof(float) * SDL_PEN_NUM_AXES),
                                        "Received SDL_EVENT_PEN_BUTTON_UP event with correct axis values");
                    found_event = SDL_TRUE;
                }
            }
            SDLTest_AssertCheck(found_event,
                                "Received the expected SDL_EVENT_PEN_BUTTON_UP event");
        }
    }
    SDLTest_AssertPass("Released every other button");

    /* Trigger pen tip events for PEN_UP */
    SDLTest_AssertPass("Remove pens from surface");

    for (pen_nr = 0; pen_nr < 2; ++pen_nr) {
        float *expected_axes = axes + pen_nr;
        SDL_bool found_event = SDL_FALSE;
        Uint16 pen_state = 0x0000;
        Uint8 tip = SDL_PEN_TIP_INK;

        if (pen_nr == 1) {
            pen_state |= SDL_PEN_ERASER_MASK;
            tip = SDL_PEN_TIP_ERASER;
        }

        SDL_SendPenTipEvent(0, ptest.ids[pen_nr], SDL_RELEASED);

        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_EVENT_PEN_UP) {
                SDLTest_AssertCheck(event.ptip.which == ptest.ids[pen_nr],
                            "Received SDL_EVENT_PEN_UP from correct pen");
                SDLTest_AssertCheck(event.ptip.tip == (pen_nr == 0)? SDL_PEN_TIP_INK : SDL_PEN_TIP_ERASER,
                                    "Received SDL_EVENT_PEN_UP for correct tip");
                SDLTest_AssertCheck(event.ptip.state == SDL_RELEASED,
                                    "Received SDL_EVENT_PEN_UP but and marked SDL_RELEASED");
                SDLTest_AssertCheck(event.ptip.tip == tip,
                                    "Received tip %x but expected %x", event.ptip.tip, tip);
                SDLTest_AssertCheck((event.ptip.pen_state & 0xff00) == (pen_state & 0xff00),
                                    "Received SDL_EVENT_PEN_UP, and state %04x == %04x (expected)",
                                    event.pbutton.pen_state, pen_state);
                SDLTest_AssertCheck((event.ptip.x == expected_x[pen_nr]) && (event.ptip.y == expected_y[pen_nr]),
                                    "Received SDL_EVENT_PEN_UP event at correct coordinates: (%f, %f) vs (%f, %f) (expected)",
                                    event.pbutton.x, event.pbutton.y, expected_x[pen_nr], expected_y[pen_nr]);
                SDLTest_AssertCheck(0 == SDL_memcmp(expected_axes, event.pbutton.axes, sizeof(float) * SDL_PEN_NUM_AXES),
                                    "Received SDL_EVENT_PEN_UP event with correct axis values");
                found_event = SDL_TRUE;
            }
            SDLTest_AssertCheck(found_event,
                                "Received the expected SDL_EVENT_PEN_UP event");
        }
    }

    /* Cleanup */
    SDL_PenGCMark();
    _pen_trackGCSweep(&ptest);
    _teardown_test(&ptest, backup);

    return TEST_COMPLETED;
}

/**
 * @brief Check pen device movement and axis update reporting
 *
 * Also tests SDL_GetPenStatus for agreement with the most recently reported events
 *
 * @sa SDL_GetPenStatus
 */
static int
pen_movementAndAxes(void *arg)
{
    pen_testdata ptest;
    SDL_Event event;
#define MAX_STEPS 80
    /* Pen simulation */
    simulated_pen_action steps[MAX_STEPS];
    size_t num_steps = 0;

    SDL_Pen simulated_pens[2];
    int sim_pc = 0;
    simulated_pen_action *last_action;

    /* Register pen */
    deviceinfo_backup *backup = _setup_test(&ptest, 2);

    /* Pen simulation program */
#define STEP steps[num_steps++] =

    /* #1: Check basic reporting */
    /* Hover eraser, tilt axes */
    SIMPEN_MOVE(0, 30.0f, 31.0f);
    SIMPEN_AXIS(0, SDL_PEN_AXIS_PRESSURE, 0.0f);
    SIMPEN_AXIS(0, SDL_PEN_AXIS_XTILT, 22.5f);
    SIMPEN_AXIS(0, SDL_PEN_AXIS_YTILT, 45.0f);
    SIMPEN_EVENT_MOTION(0);

    /* #2: Check that motion events without motion aren't reported */
    SIMPEN_EVENT_MOTION_SUPPRESSED(0);
    SIMPEN_EVENT_MOTION_SUPPRESSED(0);

    /* #3: Check multiple pens being reported */
    /* Move pen and touch surface, don't tilt */
    SIMPEN_MOVE(1, 40.0f, 41.0f);
    SIMPEN_AXIS(1, SDL_PEN_AXIS_PRESSURE, 0.25f);
    SIMPEN_EVENT_MOTION(1);

    /* $4: Multi-buttons */
    /* Press eraser buttons */
    SIMPEN_EVENT_TIP(0, "down", SDL_PEN_TIP_ERASER);
    SIMPEN_EVENT_BUTTON(0, "push", 2);
    SIMPEN_EVENT_BUTTON(0, "push", 1);
    SIMPEN_EVENT_BUTTON(0, 0, 2); /* release again */
    SIMPEN_EVENT_BUTTON(0, "push", 3);

    /* #5: Check move + button actions connecting */
    /* Move and tilt pen, press some pen buttons */
    SIMPEN_MOVE(1, 3.0f, 8.0f);
    SIMPEN_AXIS(1, SDL_PEN_AXIS_PRESSURE, 0.5f);
    SIMPEN_AXIS(1, SDL_PEN_AXIS_XTILT, -21.0f);
    SIMPEN_AXIS(1, SDL_PEN_AXIS_YTILT, -25.0f);
    SIMPEN_EVENT_MOTION(1);
    SIMPEN_EVENT_BUTTON(1, "push", 2);
    SIMPEN_EVENT_TIP(1, "down", SDL_PEN_TIP_INK);

    /* #6: Check nonterference between pens */
    /* Eraser releases buttons */
    SIMPEN_EVENT_BUTTON(0, 0, 1);
    SIMPEN_EVENT_TIP(0, 0, SDL_PEN_TIP_ERASER);

    /* #7: Press-move-release action */
    /* Eraser press-move-release */
    SIMPEN_EVENT_BUTTON(0, "push", 1);
    SIMPEN_MOVE(0, 99.0f, 88.0f);
    SIMPEN_AXIS(0, SDL_PEN_AXIS_PRESSURE, 0.625f);
    SIMPEN_EVENT_MOTION(0);
    SIMPEN_MOVE(0, 44.5f, 42.25f);
    SIMPEN_EVENT_MOTION(0);
    SIMPEN_EVENT_BUTTON(0, 0, 1);

    /* #8: Intertwining button release actions some more */
    /* Pen releases button */
    SIMPEN_EVENT_BUTTON(1, 0, 2);
    SIMPEN_EVENT_TIP(1, 0, SDL_PEN_TIP_INK);

    /* Push one more pen button, then release all ereaser buttons */
    SIMPEN_EVENT_TIP(1, "down", SDL_PEN_TIP_INK);
    SIMPEN_EVENT_BUTTON(0, 0, 2);
    SIMPEN_EVENT_BUTTON(0, 0, 3);

    /* Lift up pen, flip it so it becomes an eraser, and touch it again  */
    SIMPEN_EVENT_TIP(1, 0, SDL_PEN_TIP_INK);
    SIMPEN_SET_ERASER(1, 1);
    SIMPEN_EVENT_TIP(1, "push", SDL_PEN_TIP_ERASER);

    /* And back again */
    SIMPEN_EVENT_TIP(1, 0, SDL_PEN_TIP_ERASER);
    SIMPEN_SET_ERASER(1, 0);
    SIMPEN_EVENT_TIP(1, "push", SDL_PEN_TIP_INK);

    /* #9: Suppress move on unsupported axis */
    SIMPEN_AXIS(1, SDL_PEN_AXIS_DISTANCE, 0.25f);
    SIMPEN_EVENT_MOTION_SUPPRESSED(0);

    SIMPEN_DONE();
#undef STEP
    /* End of pen simulation program */

    SDLTest_AssertCheck(num_steps < MAX_STEPS, "Pen simulation program does not exceed buffer size");
#undef MAX_STEPS

    SDL_PenGCMark();
    _pen_setDeviceinfo(_pen_register(ptest.ids[0], ptest.guids[0], "test eraser",
                                     SDL_PEN_ERASER_MASK | SDL_PEN_AXIS_PRESSURE_MASK | SDL_PEN_AXIS_XTILT_MASK | SDL_PEN_AXIS_YTILT_MASK),
                       20);
    _pen_setDeviceinfo(_pen_register(ptest.ids[1], ptest.guids[1], "test pen",
                                     SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK | SDL_PEN_AXIS_XTILT_MASK | SDL_PEN_AXIS_YTILT_MASK),
                       24);
    _pen_trackGCSweep(&ptest);
    SDL_SendPenWindowEvent(0, ptest.ids[0], ptest.window);
    SDL_SendPenWindowEvent(0, ptest.ids[1], ptest.window);
    while (SDL_PollEvent(&event))
        ; /* Flush event queue */
    SDLTest_AssertPass("Pen and eraser set up for testing");

    _pen_simulate_init(&ptest, simulated_pens, 2);
    /* Simulate pen movements */
    while ((last_action = _pen_simulate(steps, &sim_pc, &simulated_pens[0], 2)) != 0) {
        int attempts = 0;
        SDL_Pen *simpen = &simulated_pens[last_action->pen_index];
        SDL_PenID reported_which = 0;
        float reported_x = -1.0f, reported_y = -1.0f;
        float *reported_axes = NULL;
        Uint32 reported_pen_state = 0;
        Uint32 expected_pen_state = simpen->header.flags & SDL_PEN_ERASER_MASK;
        SDL_bool dump_pens = SDL_FALSE;

        do {
            SDL_PumpEvents();
            SDL_PollEvent(&event);
            if (++attempts > 10000) {
                SDLTest_AssertCheck(0, "Never got the anticipated event");
                return TEST_ABORTED;
            }
        } while (event.type != SDL_EVENT_PEN_DOWN
                 && event.type != SDL_EVENT_PEN_UP
                 && event.type != SDL_EVENT_PEN_MOTION
                 && event.type != SDL_EVENT_PEN_BUTTON_UP
                 && event.type != SDL_EVENT_PEN_BUTTON_DOWN); /* skip boring events */

        expected_pen_state |= simpen->last.buttons;

        SDLTest_AssertCheck(0 != event.type,
                            "Received the anticipated event");

        switch (last_action->type) {
        case SIMPEN_ACTION_MOTION_EVENT:
            SDLTest_AssertCheck(event.type == SDL_EVENT_PEN_MOTION, "Expected pen motion event (but got 0x%lx)", (unsigned long) event.type);
            reported_which = event.pmotion.which;
            reported_x = event.pmotion.x;
            reported_y = event.pmotion.y;
            reported_pen_state = event.pmotion.pen_state;
            reported_axes = &event.pmotion.axes[0];
            break;

        case SIMPEN_ACTION_PRESS:
            SDLTest_AssertCheck(event.type == SDL_EVENT_PEN_BUTTON_DOWN, "Expected PENBUTTONDOWN event (but got 0x%lx)", (unsigned long) event.type);
            SDLTest_AssertCheck(event.pbutton.state == SDL_PRESSED, "Expected PRESSED button");
            SDL_FALLTHROUGH;
        case SIMPEN_ACTION_RELEASE:
            if (last_action->type == SIMPEN_ACTION_RELEASE) {
                SDLTest_AssertCheck(event.type == SDL_EVENT_PEN_BUTTON_UP, "Expected PENBUTTONUP event (but got 0x%lx)", (unsigned long) event.type);
                SDLTest_AssertCheck(event.pbutton.state == SDL_RELEASED, "Expected RELEASED button");
            }
            SDLTest_AssertCheck(event.pbutton.button == last_action->index, "Expected button %d, but got %d",
                                last_action->index, event.pbutton.button);
            reported_which = event.pbutton.which;
            reported_x = event.pbutton.x;
            reported_y = event.pbutton.y;
            reported_pen_state = event.pbutton.pen_state;
            reported_axes = &event.pbutton.axes[0];
            break;

        case SIMPEN_ACTION_DOWN:
            SDLTest_AssertCheck(event.type == SDL_EVENT_PEN_DOWN, "Expected PENBUTTONDOWN event (but got 0x%lx)", (unsigned long) event.type);
            SDLTest_AssertCheck(event.ptip.state == SDL_PRESSED, "Expected PRESSED button");
            SDL_FALLTHROUGH;
        case SIMPEN_ACTION_UP:
            if (last_action->type == SIMPEN_ACTION_UP) {
                SDLTest_AssertCheck(event.type == SDL_EVENT_PEN_UP, "Expected PENBUTTONUP event (but got 0x%lx)", (unsigned long) event.type);
                SDLTest_AssertCheck(event.ptip.state == SDL_RELEASED, "Expected RELEASED button");
            }
            SDLTest_AssertCheck(event.ptip.tip == last_action->index, "Expected tip %d, but got %d",
                                last_action->index, event.ptip.tip);
            reported_which = event.ptip.which;
            reported_x = event.ptip.x;
            reported_y = event.ptip.y;
            reported_pen_state = event.ptip.pen_state;
            reported_axes = &event.ptip.axes[0];
            break;

        case SIMPEN_ACTION_ERASER_MODE:
            break;

        default:
            SDLTest_AssertCheck(0, "Error in pen simulator: unexpected action %d", last_action->type);
            return TEST_ABORTED;
        }

        if (reported_which != simpen->header.id) {
            dump_pens = SDL_TRUE;
            SDLTest_AssertCheck(0, "Expected report for pen %lu but got report for pen %lu",
                                (unsigned long) simpen->header.id,
                                (unsigned long) reported_which);
        }
        if (reported_x != simpen->last.x || reported_y != simpen->last.y) {
            dump_pens = SDL_TRUE;
            SDLTest_AssertCheck(0, "Mismatch in pen coordinates");
        }
        if (reported_x != simpen->last.x || reported_y != simpen->last.y) {
            dump_pens = SDL_TRUE;
            SDLTest_AssertCheck(0, "Mismatch in pen coordinates");
        }
        if (reported_pen_state != expected_pen_state) {
            dump_pens = SDL_TRUE;
            SDLTest_AssertCheck(0, "Mismatch in pen state: %lx vs %lx (expected)",
                                (unsigned long) reported_pen_state,
                                (unsigned long) expected_pen_state);
        }
        if (0 != SDL_memcmp(reported_axes, simpen->last.axes, sizeof(float) * SDL_PEN_NUM_AXES)) {
            dump_pens = SDL_TRUE;
            SDLTest_AssertCheck(0, "Mismatch in axes");
        }

        if (dump_pens) {
            SDL_Log("----- Pen #%d:", last_action->pen_index);
            _pen_dump("expect", simpen);
            _pen_dump("actual", SDL_GetPenPtr(simpen->header.id));
        }
    }
    SDLTest_AssertPass("Pen and eraser move and report events correctly and independently");

    /* Cleanup */
    SDL_PenGCMark();
    _pen_trackGCSweep(&ptest);
    _teardown_test(&ptest, backup);
    return TEST_COMPLETED;
}

static void
_expect_pen_config(SDL_PenID penid,
                   SDL_GUID expected_guid,
                   SDL_bool expected_attached,
                   char *expected_name,
                   int expected_type,
                   int expected_num_buttons,
                   float expected_max_tilt,
                   int expected_axes)
{
    SDL_PenCapabilityInfo actual_info = { 0 };
    const char *actual_name = SDL_GetPenName(penid);

    if (penid == SDL_PEN_INVALID) {
        SDLTest_Assert(0, "Invalid pen ID");
        return;
    }

    SDLTest_AssertEq1(int, "%d", 0, SDL_GUIDCompare(expected_guid, SDL_GetPenGUID(penid)),
                      "Pen %lu guid equality", (unsigned long) penid);

    SDLTest_AssertCheck(0 == SDL_strcmp(expected_name, actual_name),
                        "Expected name='%s' vs actual='%s'", expected_name, actual_name);

    SDLTest_AssertEq1(int, "%d", expected_attached, SDL_PenConnected(penid),
                      "Pen %lu is attached", (unsigned long) penid);
    SDLTest_AssertEq1(int, "%d", expected_type, SDL_GetPenType(penid),
                      "Pen %lu type", (unsigned long) penid);
    SDLTest_AssertEq1(int, "%x", expected_axes, SDL_GetPenCapabilities(penid, &actual_info),
                      "Pen %lu axis flags", (unsigned long) penid);
    SDLTest_AssertEq1(int, "%d", expected_num_buttons, actual_info.num_buttons,
                      "Pen %lu number of buttons", (unsigned long) penid);
    SDLTest_AssertEq1(float, "%f", expected_max_tilt, actual_info.max_tilt,
                      "Pen %lu max tilt", (unsigned long) penid);
}

/**
 * @brief Check backend pen iniitalisation and pen meta-information
 *
 * @sa SDL_GetPenCapabilities, SDL_PenAxisInfo
 */
static int
pen_initAndInfo(void *arg)
{
    pen_testdata ptest;
    SDL_Pen *pen;
    Uint32 mask;
    char strbuf[SDL_PEN_MAX_NAME];

    /* Init */
    deviceinfo_backup *backup = _setup_test(&ptest, 7);

    /* Register default pen */
    _expect_pens_attached_or_detached(ptest.ids, 7, 0);

    /* Register completely default pen */
    pen = SDL_PenModifyBegin(ptest.ids[0]);
    SDL_memcpy(pen->guid.data, ptest.guids[0].data, sizeof(ptest.guids[0].data));
    SDL_PenModifyEnd(pen, SDL_TRUE);

    SDL_snprintf(strbuf, sizeof(strbuf),
                 "Pen %lu", (unsigned long) ptest.ids[0]);
    _expect_pen_config(ptest.ids[0], ptest.guids[0], SDL_TRUE,
                       strbuf, SDL_PEN_TYPE_PEN, SDL_PEN_INFO_UNKNOWN, 0.0f,
                       SDL_PEN_INK_MASK);
    _expect_pens_attached_or_detached(ptest.ids, 7, ATTACHED(0));
    SDLTest_AssertPass("Pass #1: default pen");

    /* Register mostly-default pen with buttons and custom name */
    pen = SDL_PenModifyBegin(ptest.ids[1]);
    SDL_PenModifyAddCapabilities(pen, SDL_PEN_AXIS_PRESSURE_MASK);
    SDL_memcpy(pen->guid.data, ptest.guids[1].data, sizeof(ptest.guids[1].data));
    SDL_strlcpy(strbuf, "My special test pen", SDL_PEN_MAX_NAME);
    SDL_strlcpy(pen->name, strbuf, SDL_PEN_MAX_NAME);
    pen->info.num_buttons = 7;
    SDL_PenModifyEnd(pen, SDL_TRUE);

    _expect_pen_config(ptest.ids[1], ptest.guids[1], SDL_TRUE,
                       strbuf, SDL_PEN_TYPE_PEN, 7, 0.0f,
                       SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK);
    _expect_pens_attached_or_detached(ptest.ids, 7, ATTACHED(0) | ATTACHED(1));
    SDLTest_AssertPass("Pass #2: default pen with button and name info");

    /* Register eraser with default name, but keep initially detached */
    pen = SDL_PenModifyBegin(ptest.ids[2]);
    SDL_memcpy(pen->guid.data, ptest.guids[2].data, sizeof(ptest.guids[2].data));
    pen->type = SDL_PEN_TYPE_ERASER;
    SDL_PenModifyAddCapabilities(pen, SDL_PEN_AXIS_XTILT_MASK | SDL_PEN_AXIS_YTILT_MASK);
    SDL_PenModifyEnd(pen, SDL_FALSE);

    SDL_snprintf(strbuf, sizeof(strbuf),
                 "Eraser %lu", (unsigned long) ptest.ids[2]);
    _expect_pen_config(ptest.ids[2], ptest.guids[2], SDL_FALSE,
                       strbuf, SDL_PEN_TYPE_ERASER, SDL_PEN_INFO_UNKNOWN, SDL_PEN_INFO_UNKNOWN,
                       SDL_PEN_ERASER_MASK | SDL_PEN_AXIS_XTILT_MASK | SDL_PEN_AXIS_YTILT_MASK);
    _expect_pens_attached_or_detached(ptest.ids, 7, ATTACHED(0) | ATTACHED(1));
    /* now make available */
    SDL_PenModifyEnd(SDL_PenModifyBegin(ptest.ids[2]), SDL_TRUE);
    _expect_pen_config(ptest.ids[2], ptest.guids[2], SDL_TRUE,
                       strbuf, SDL_PEN_TYPE_ERASER, SDL_PEN_INFO_UNKNOWN, SDL_PEN_INFO_UNKNOWN,
                       SDL_PEN_ERASER_MASK | SDL_PEN_AXIS_XTILT_MASK | SDL_PEN_AXIS_YTILT_MASK);
    _expect_pens_attached_or_detached(ptest.ids, 7, ATTACHED(0) | ATTACHED(1) | ATTACHED(2));
    SDLTest_AssertPass("Pass #3: eraser-type pen initially detached, then attached");

    /* Abort pen registration */
    pen = SDL_PenModifyBegin(ptest.ids[3]);
    SDL_memcpy(pen->guid.data, ptest.guids[3].data, sizeof(ptest.guids[3].data));
    SDL_PenModifyAddCapabilities(pen, SDL_PEN_AXIS_XTILT_MASK | SDL_PEN_AXIS_YTILT_MASK);
    pen->type = SDL_PEN_TYPE_NONE;
    SDL_PenModifyEnd(pen, SDL_TRUE);
    _expect_pens_attached_or_detached(ptest.ids, 7, ATTACHED(0) | ATTACHED(1) | ATTACHED(2));
    SDLTest_AssertCheck(NULL == SDL_GetPenName(ptest.ids[3]), "Pen with aborted registration remains unknown");
    SDLTest_AssertPass("Pass #4: aborted pen registration");

    /* Brush with custom axes */
    pen = SDL_PenModifyBegin(ptest.ids[4]);
    SDL_memcpy(pen->guid.data, ptest.guids[4].data, sizeof(ptest.guids[4].data));
    SDL_strlcpy(pen->name, "Testish Brush", SDL_PEN_MAX_NAME);
    pen->type = SDL_PEN_TYPE_BRUSH;
    pen->info.num_buttons = 1;
    SDL_PenModifyAddCapabilities(pen, SDL_PEN_AXIS_ROTATION_MASK);
    pen->info.max_tilt = 72.5f;
    SDL_PenModifyAddCapabilities(pen, SDL_PEN_AXIS_XTILT_MASK);
    SDL_PenModifyAddCapabilities(pen, SDL_PEN_AXIS_PRESSURE_MASK);
    SDL_PenModifyEnd(pen, SDL_TRUE);
    _expect_pen_config(ptest.ids[4], ptest.guids[4], SDL_TRUE,
                       "Testish Brush", SDL_PEN_TYPE_BRUSH, 1, 72.5f,
                       SDL_PEN_INK_MASK | SDL_PEN_AXIS_XTILT_MASK | SDL_PEN_AXIS_ROTATION_MASK | SDL_PEN_AXIS_PRESSURE_MASK);
    _expect_pens_attached_or_detached(ptest.ids, 7, ATTACHED(0) | ATTACHED(1) | ATTACHED(2) | ATTACHED(4));
    SDLTest_AssertPass("Pass #5: brush-type pen with unusual axis layout");

    /* Wacom airbrush pen */
    {
        const Uint32 wacom_type_id = 0x0912;
        const Uint32 wacom_serial_id = 0xa0b1c2d3;
        SDL_GUID guid = {
            { 0, 0, 0, 0,
              0, 0, 0, 0,
              0, 0, 0, 0,
              0, 0, 0, 0 }
        };
        guid.data[0] = (wacom_serial_id >> 0) & 0xff;
        guid.data[1] = (wacom_serial_id >> 8) & 0xff;
        guid.data[2] = (wacom_serial_id >> 16) & 0xff;
        guid.data[3] = (wacom_serial_id >> 24) & 0xff;
        guid.data[4] = (wacom_type_id >> 0) & 0xff;
        guid.data[5] = (wacom_type_id >> 8) & 0xff;
        guid.data[6] = (wacom_type_id >> 16) & 0xff;
        guid.data[7] = (wacom_type_id >> 24) & 0xff;

        pen = SDL_PenModifyBegin(ptest.ids[5]);
        SDL_PenModifyForWacomID(pen, wacom_type_id, &mask);
        SDL_PenUpdateGUIDForWacom(&pen->guid, wacom_type_id, wacom_serial_id);
        SDL_PenModifyAddCapabilities(pen, mask);
        SDL_PenModifyEnd(pen, SDL_TRUE);
        _expect_pen_config(ptest.ids[5], guid, SDL_TRUE,
                           "Wacom Airbrush Pen", SDL_PEN_TYPE_AIRBRUSH, 1, 64.0f, /* Max tilt angle */
                           SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK | SDL_PEN_AXIS_XTILT_MASK | SDL_PEN_AXIS_YTILT_MASK | SDL_PEN_AXIS_DISTANCE_MASK | SDL_PEN_AXIS_SLIDER_MASK);
        _expect_pens_attached_or_detached(ptest.ids, 7, ATTACHED(0) | ATTACHED(1) | ATTACHED(2) | ATTACHED(4) | ATTACHED(5));
    }
    SDLTest_AssertPass("Pass #6: wacom airbrush pen");

    /* Cleanup */
    SDL_PenGCMark();
    _pen_trackGCSweep(&ptest);
    _teardown_test(&ptest, backup);
    return TEST_COMPLETED;
}

#define SET_POS(update, xpos, ypos) \
    (update).x = (xpos);            \
    (update).y = (ypos);

static void
_penmouse_expect_button(int type, int button)
{
    SDL_bool press = type == SDL_PRESSED;
    SDLTest_AssertCheck((press ? SDL_EVENT_MOUSE_BUTTON_DOWN : SDL_EVENT_MOUSE_BUTTON_UP) == _mouseemu_last_event,
                        "Mouse button %s: %x",
                        (press ? "press" : "release"), _mouseemu_last_event);
    SDLTest_AssertCheck(button == _mouseemu_last_button,
                        "Observed the expected simulated button: %d", _mouseemu_last_button);
    SDLTest_AssertCheck(SDL_PEN_MOUSEID == _mouseemu_last_mouseid,
                        "Observed the expected mouse ID: 0x%x", _mouseemu_last_mouseid);

    _mouseemu_last_event = 0;
}

/**
 * @brief Check pen device mouse emulation and event suppression without SDL_HINT_PEN_DELAY_MOUSE_BUTTON
 *
 * Since we include SDL_pen.c, we link it against our own mock implementations of SDL_PSendMouseButton
 * and SDL_SendMouseMotion; see tehere for details.
 */
static int
pen_mouseEmulation(void *arg)
{
    pen_testdata ptest;
    SDL_Event event;
    int i;
    SDL_PenStatusInfo update;
    deviceinfo_backup *backup;

    pen_delay_mouse_button_mode = 0;
    pen_mouse_emulation_mode = PEN_MOUSE_EMULATE; /* to trigger our own SDL_SendMouseButton */

    /* Register pen */
    backup = _setup_test(&ptest, 1);
    SDL_PenGCMark();
    _pen_setDeviceinfo(_pen_register(ptest.ids[0], ptest.guids[0], "testpen",
                                     SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK | SDL_PEN_AXIS_XTILT | SDL_PEN_AXIS_YTILT),
                       20);
    _pen_trackGCSweep(&ptest);

    /* Move pen into window */
    SDL_SendPenWindowEvent(0, ptest.ids[0], ptest.window);

    /* Initialise pen location */
    SDL_memset(update.axes, 0, sizeof(update.axes));
    SET_POS(update, 100.0f, 100.0f);
    SDL_SendPenMotion(0, ptest.ids[0], SDL_TRUE, &update);
    while (SDL_PollEvent(&event))
        ; /* Flush event queue */

    /* Test motion forwarding */
    _mouseemu_last_event = 0;
    SET_POS(update, 121.25f, 110.75f);
    SDL_SendPenMotion(0, ptest.ids[0], SDL_TRUE, &update);
    SDLTest_AssertCheck(SDL_EVENT_MOUSE_MOTION == _mouseemu_last_event,
                        "Mouse motion event: %d", _mouseemu_last_event);
    SDLTest_AssertCheck(121.25f == _mouseemu_last_x && 110.75f == _mouseemu_last_y,
                        "Motion to correct position: %f,%f", _mouseemu_last_x, _mouseemu_last_y);
    SDLTest_AssertCheck(SDL_PEN_MOUSEID == _mouseemu_last_mouseid,
                        "Observed the expected mouse ID: 0x%x", _mouseemu_last_mouseid);
    SDLTest_AssertCheck(0 == _mouseemu_last_relative,
                        "Absolute motion event");
    SDLTest_AssertPass("Motion emulation");

    /* Test redundant motion report suppression */
    _mouseemu_last_event = 0;

    SET_POS(update, 121.25f, 110.75f);
    SDL_SendPenMotion(0, ptest.ids[0], SDL_TRUE, &update);

    SET_POS(update, 121.25f, 110.75f);
    SDL_SendPenMotion(0, ptest.ids[0], SDL_TRUE, &update);

    update.axes[0] = 1.0f;
    SDL_SendPenMotion(0, ptest.ids[0], SDL_TRUE, &update);

    SET_POS(update, 121.25f, 110.75f);
    update.axes[0] = 0.0f;
    update.axes[1] = 0.75f;
    SDL_SendPenMotion(0, ptest.ids[0], SDL_TRUE, &update);

    SDLTest_AssertCheck(0 == _mouseemu_last_event,
                        "Redundant mouse motion suppressed: %d", _mouseemu_last_event);
    SDLTest_AssertPass("Redundant motion suppression");

    /* Test button press reporting */
    SDL_SendPenTipEvent(0, ptest.ids[0], SDL_PRESSED);
    _penmouse_expect_button(SDL_PRESSED, 1);

    for (i = 1; i <= 3; ++i) {
        SDL_SendPenButton(0, ptest.ids[0], SDL_PRESSED, (Uint8)i);
        _penmouse_expect_button(SDL_PRESSED, i + 1);
    }
    SDLTest_AssertPass("Button press mouse emulation");

    /* Test button release reporting */
    SDL_SendPenTipEvent(0, ptest.ids[0], SDL_RELEASED);
    _penmouse_expect_button(SDL_RELEASED, 1);

    for (i = 1; i <= 3; ++i) {
        SDL_SendPenButton(0, ptest.ids[0], SDL_RELEASED, (Uint8)i);
        _penmouse_expect_button(SDL_RELEASED, i + 1);
    }
    SDLTest_AssertPass("Button release mouse emulation");

    /* Cleanup */
    SDL_PenGCMark();
    _pen_trackGCSweep(&ptest);
    _teardown_test(&ptest, backup);
    return TEST_COMPLETED;
}

/**
 * @brief Check pen device mouse emulation when SDL_HINT_PEN_DELAY_MOUSE_BUTTON is enabled (default)
 */
static int
pen_mouseEmulationDelayed(void *arg)
{
    pen_testdata ptest;
    SDL_Event event;
    int i;
    SDL_PenStatusInfo update;
    deviceinfo_backup *backup;

    pen_delay_mouse_button_mode = 1;
    pen_mouse_emulation_mode = PEN_MOUSE_EMULATE; /* to trigger our own SDL_SendMouseButton */

    /* Register pen */
    backup = _setup_test(&ptest, 1);
    SDL_PenGCMark();
    _pen_setDeviceinfo(_pen_register(ptest.ids[0], ptest.guids[0], "testpen",
                                     SDL_PEN_INK_MASK | SDL_PEN_AXIS_PRESSURE_MASK | SDL_PEN_AXIS_XTILT | SDL_PEN_AXIS_YTILT),
                       20);
    _pen_trackGCSweep(&ptest);

    /* Move pen into window */
    SDL_SendPenWindowEvent(0, ptest.ids[0], ptest.window);

    /* Initialise pen location */
    SDL_memset(update.axes, 0, sizeof(update.axes));
    SET_POS(update, 100.0f, 100.0f);
    SDL_SendPenMotion(0, ptest.ids[0], SDL_TRUE, &update);
    while (SDL_PollEvent(&event))
        ; /* Flush event queue */

    /* Test motion forwarding */
    _mouseemu_last_event = 0;
    SET_POS(update, 121.25f, 110.75f);
    SDL_SendPenMotion(0, ptest.ids[0], SDL_TRUE, &update);
    SDLTest_AssertCheck(SDL_EVENT_MOUSE_MOTION == _mouseemu_last_event,
                        "Mouse motion event: %d", _mouseemu_last_event);
    SDLTest_AssertCheck(121.25f == _mouseemu_last_x && 110.75f == _mouseemu_last_y,
                        "Motion to correct position: %f,%f", _mouseemu_last_x, _mouseemu_last_y);
    SDLTest_AssertCheck(SDL_PEN_MOUSEID == _mouseemu_last_mouseid,
                        "Observed the expected mouse ID: 0x%x", _mouseemu_last_mouseid);
    SDLTest_AssertCheck(0 == _mouseemu_last_relative,
                        "Absolute motion event");
    SDLTest_AssertPass("Motion emulation");
    _mouseemu_last_event = 0;

    /* Test button press reporting */
    for (i = 1; i <= 2; ++i) {
        SDL_SendPenButton(0, ptest.ids[0], SDL_PRESSED, (Uint8)i);
        SDLTest_AssertCheck(0 == _mouseemu_last_event,
                            "Non-touching button press suppressed: %d", _mouseemu_last_event);
        SDL_SendPenButton(0, ptest.ids[0], SDL_RELEASED, (Uint8)i);
        SDLTest_AssertCheck(0 == _mouseemu_last_event,
                            "Non-touching button release suppressed: %d", _mouseemu_last_event);
    }

    /* Touch surface */
    SDL_SendPenTipEvent(0, ptest.ids[0], SDL_PRESSED);
    _penmouse_expect_button(SDL_PRESSED, 1);
    SDL_SendPenTipEvent(0, ptest.ids[0], SDL_RELEASED);
    _penmouse_expect_button(SDL_RELEASED, 1);

    /* Test button press reporting, releasing extra button AFTER lifting pen */
    for (i = 1; i <= 2; ++i) {
        SDL_SendPenButton(0, ptest.ids[0], SDL_PRESSED, (Uint8)i);
        SDLTest_AssertCheck(0 == _mouseemu_last_event,
                            "Non-touching button press suppressed (A.1): %d", _mouseemu_last_event);
        SDL_SendPenTipEvent(0, ptest.ids[0], SDL_PRESSED);
        _penmouse_expect_button(SDL_PRESSED, i + 1);

        SDL_SendPenTipEvent(0, ptest.ids[0], SDL_RELEASED);
        _penmouse_expect_button(SDL_RELEASED, i + 1);

        SDL_SendPenButton(0, ptest.ids[0], SDL_RELEASED, (Uint8)i);
        SDLTest_AssertCheck(0 == _mouseemu_last_event,
                            "Non-touching button press suppressed (A.2): %d", _mouseemu_last_event);
    }
    SDLTest_AssertPass("Delayed button press mouse emulation, touching without releasing button");

    /* Test button press reporting, releasing extra button BEFORE lifting pen */
    for (i = 1; i <= 2; ++i) {
        SDL_SendPenButton(0, ptest.ids[0], SDL_PRESSED, (Uint8)i);
        SDLTest_AssertCheck(0 == _mouseemu_last_event,
                            "Non-touching button press suppressed (B.1): %d", _mouseemu_last_event);
        SDL_SendPenTipEvent(0, ptest.ids[0], SDL_PRESSED);
        _penmouse_expect_button(SDL_PRESSED, i + 1);

        SDL_SendPenButton(0, ptest.ids[0], SDL_RELEASED, (Uint8)i);
        SDLTest_AssertCheck(0 == _mouseemu_last_event,
                            "Non-touching button press suppressed (B.2): %d", _mouseemu_last_event);
        SDL_SendPenTipEvent(0, ptest.ids[0], SDL_RELEASED);
        _penmouse_expect_button(SDL_RELEASED, i + 1);
    }
    SDLTest_AssertPass("Delayed button press mouse emulation, touching and then releasing button");

    /* Cleanup */
    SDL_PenGCMark();
    _pen_trackGCSweep(&ptest);
    _teardown_test(&ptest, backup);
    return TEST_COMPLETED;
}

/**
 * @brief Ensure that all SDL_Pen*Event structures have compatible memory layout, as expected by SDL_pen.c
 */
static int
pen_memoryLayout(void *arg)
{
#define LAYOUT_COMPATIBLE(field) \
    SDLTest_AssertCheck(offsetof(SDL_PenTipEvent, field) == offsetof(SDL_PenMotionEvent, field), \
                        "Memory layout SDL_PenTipEvent and SDL_PenMotionEvent compatibility: '" #field "'"); \
    SDLTest_AssertCheck(offsetof(SDL_PenTipEvent, field) == offsetof(SDL_PenButtonEvent, field), \
                        "Memory layout SDL_PenTipEvent and SDL_PenBUttonEvent compatibility: '" #field "'");

    LAYOUT_COMPATIBLE(which);
    LAYOUT_COMPATIBLE(x);
    LAYOUT_COMPATIBLE(y);
    LAYOUT_COMPATIBLE(axes);

    return TEST_COMPLETED;
}

/* ================= Test Setup and Teardown ================== */

static void
pen_test_setup(void *arg) {
    SDL_PenInit();
}

static void
pen_test_teardown(void *arg) {
    SDL_PenQuit();
}

/* ================= Test References ================== */

/* Pen test cases */
static const SDLTest_TestCaseReference penTest1 = { (SDLTest_TestCaseFp)pen_iteration, "pen_iteration", "Iterate over all pens with SDL_PenIDForIndex", TEST_ENABLED };

static const SDLTest_TestCaseReference penTest2 = { (SDLTest_TestCaseFp)pen_hotplugging, "pen_hotplugging", "Hotplug pens and validate their status, including SDL_PenConnected", TEST_ENABLED };

static const SDLTest_TestCaseReference penTest3 = { (SDLTest_TestCaseFp)pen_GUIDs, "pen_GUIDs", "Check Pen SDL_GUID operations", TEST_ENABLED };

static const SDLTest_TestCaseReference penTest4 = { (SDLTest_TestCaseFp)pen_buttonReporting, "pen_buttonReporting", "Check pen button presses", TEST_ENABLED };

static const SDLTest_TestCaseReference penTest5 = { (SDLTest_TestCaseFp)pen_movementAndAxes, "pen_movementAndAxes", "Check pen movement and axis update reporting", TEST_ENABLED };

static const SDLTest_TestCaseReference penTest6 = { (SDLTest_TestCaseFp)pen_initAndInfo, "pen_info", "Check pen self-description and initialisation", TEST_ENABLED };

static const SDLTest_TestCaseReference penTest7 = { (SDLTest_TestCaseFp)pen_mouseEmulation, "pen_mouseEmulation", "Check pen-as-mouse event forwarding (direct)", TEST_ENABLED };

static const SDLTest_TestCaseReference penTest8 = { (SDLTest_TestCaseFp)pen_mouseEmulationDelayed, "pen_mouseEmulationDelayed", "Check pen-as-mouse event forwarding (delayed)", TEST_ENABLED };

static const SDLTest_TestCaseReference penTest9 = { (SDLTest_TestCaseFp)pen_memoryLayout, "pen_memoryLayout", "Check that all pen events have compatible layout (required by SDL_pen.c)", TEST_ENABLED };

/* Sequence of Pen test cases */
static const SDLTest_TestCaseReference *penTests[] = {
    &penTest1, &penTest2, &penTest3, &penTest4, &penTest5, &penTest6, &penTest7, &penTest8, &penTest9, NULL
};

/* Pen test suite (global) */
SDLTest_TestSuiteReference penTestSuite = {
    "Pen",
    (SDLTest_TestCaseSetUpFp)pen_test_setup,
    penTests,
    (SDLTest_TestCaseTearDownFp)pen_test_teardown
};

#else

#include <SDL3/SDL_test.h>
#include "testautomation_suites.h"

/* Sequence of Mouse test cases */
static const SDLTest_TestCaseReference *penTests[] = {
    NULL
};

/* Mouse test suite (global) */
SDLTest_TestSuiteReference penTestSuite = {
    "Pen",
    NULL,
    penTests,
    NULL
};

#endif
