/*
  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.
*/
#include "../../SDL_internal.h"

#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2

#include "../../events/SDL_pen_c.h"
#include "../SDL_sysvideo.h"
#include "SDL_x11pen.h"
#include "SDL_x11video.h"
#include "SDL_x11xinput2.h"

#define PEN_ERASER_ID_MAXLEN 256      /* Max # characters of device name to scan */
#define PEN_ERASER_NAME_TAG  "eraser" /* String constant to identify erasers */

#define DEBUG_PEN (SDL_PEN_DEBUG_NOID | SDL_PEN_DEBUG_NONWACOM | SDL_PEN_DEBUG_UNKNOWN_WACOM | SDL_PEN_DEBUG_NOSERIAL_WACOM)

#define SDL_PEN_AXIS_VALUATOR_MISSING -1

/* X11-specific information attached to each pen */
typedef struct xinput2_pen
{
    float axis_min[SDL_PEN_NUM_AXES];
    float axis_max[SDL_PEN_NUM_AXES];
    float slider_bias;                         /* shift value to add to PEN_AXIS_SLIDER (before normalisation) */
    float rotation_bias;                       /* rotation to add to PEN_AXIS_ROTATION  (after normalisation) */
    Sint8 valuator_for_axis[SDL_PEN_NUM_AXES]; /* SDL_PEN_AXIS_VALUATOR_MISSING if not supported */
} xinput2_pen;

/* X11 atoms */
static struct
{
    int initialized; /* initialised to 0 */
    Atom device_product_id;
    Atom abs_pressure;
    Atom abs_tilt_x;
    Atom abs_tilt_y;
    Atom wacom_serial_ids;
    Atom wacom_tool_type;
} pen_atoms;

/*
 * Mapping from X11 device IDs to pen IDs
 *
 * In X11, the same device ID may represent any number of pens.  We
 * thus cannot directly use device IDs as pen IDs.
 */
static struct
{
    int num_pens_known; /* Number of currently known pens (based on their GUID); used to give pen ID to new pens */
    int num_entries;    /* Number of X11 device IDs that correspond to pens */

    struct pen_device_id_mapping
    {
        Uint32 deviceid;
        Uint32 pen_id;
    } * entries; /* Current pen to device ID mappings */
} pen_map;

typedef enum
{
    SDL_PEN_VENDOR_UNKNOWN = 0,
    SDL_PEN_VENDOR_WACOM
} sdl_pen_vendor;

/* Information to identify pens during discovery */
typedef struct
{
    sdl_pen_vendor vendor;
    SDL_GUID guid;
    SDL_PenSubtype heuristic_type; /* Distinguish pen+eraser devices with shared bus ID */
    Uint32 devicetype_id, serial;  /* used by PEN_VENDOR_WACOM */
    Uint32 deviceid;
} pen_identity;

int X11_PenIDFromDeviceID(int deviceid)
{
    int i;
    for (i = 0; i < pen_map.num_entries; ++i) {
        if (pen_map.entries[i].deviceid == deviceid) {
            return pen_map.entries[i].pen_id;
        }
    }
    return SDL_PEN_INVALID;
}

static void pen_atoms_ensure_initialized(SDL_VideoDevice *_this)
{
    SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;

    if (pen_atoms.initialized) {
        return;
    }
    /* Create atoms if they don't exist yet to pre-empt hotplugging updates */
    pen_atoms.device_product_id = X11_XInternAtom(data->display, "Device Product ID", False);
    pen_atoms.wacom_serial_ids = X11_XInternAtom(data->display, "Wacom Serial IDs", False);
    pen_atoms.wacom_tool_type = X11_XInternAtom(data->display, "Wacom Tool Type", False);
    pen_atoms.abs_pressure = X11_XInternAtom(data->display, "Abs Pressure", False);
    pen_atoms.abs_tilt_x = X11_XInternAtom(data->display, "Abs Tilt X", False);
    pen_atoms.abs_tilt_y = X11_XInternAtom(data->display, "Abs Tilt Y", False);

    pen_atoms.initialized = 1;
}

/* Read out an integer property and store into a preallocated Sint32 array, extending 8 and 16 bit values suitably.
   Returns number of Sint32s written (<= max_words), or 0 on error. */
static size_t xinput2_pen_get_int_property(SDL_VideoDevice *_this, int deviceid, Atom property, Sint32 *dest, size_t max_words)
{
    const SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
    Atom type_return;
    int format_return;
    unsigned long num_items_return;
    unsigned long bytes_after_return;
    unsigned char *output;

    if (property == None) {
        return 0;
    }

    if (Success != X11_XIGetProperty(data->display, deviceid,
                                     property,
                                     0, max_words, False,
                                     XA_INTEGER, &type_return, &format_return,
                                     &num_items_return, &bytes_after_return,
                                     &output) ||
        num_items_return == 0 || output == NULL) {
        return 0;
    }

    if (type_return == XA_INTEGER) {
        int k;
        const int to_copy = SDL_min(max_words, num_items_return);

        if (format_return == 8) {
            Sint8 *numdata = (Sint8 *)output;
            for (k = 0; k < to_copy; ++k) {
                dest[k] = numdata[k];
            }
        } else if (format_return == 16) {
            Sint16 *numdata = (Sint16 *)output;
            for (k = 0; k < to_copy; ++k) {
                dest[k] = numdata[k];
            }
        } else {
            SDL_memcpy(dest, output, sizeof(Sint32) * to_copy);
        }
        X11_XFree(output);
        return to_copy;
    }
    return 0; /* type mismatch */
}

/* 32 bit vendor + device ID from evdev */
static Uint32 xinput2_pen_evdevid(SDL_VideoDevice *_this, int deviceid)
{
#if !(SDL_PEN_DEBUG_NOID)
    Sint32 ids[2];

    pen_atoms_ensure_initialized(_this);

    if (2 != xinput2_pen_get_int_property(_this, deviceid, pen_atoms.device_product_id, ids, 2)) {
        return 0;
    }
    return ((ids[0] << 16) | (ids[1] & 0xffff));
#else /* Testing: pretend that we have no ID (not sure if this can happen IRL) */
    return 0;
#endif
}

/* Gets reasonably-unique GUID for the device */
static void xinput2_pen_update_generic_guid(SDL_VideoDevice *_this, pen_identity *pident, int deviceid)
{
    Uint32 evdevid = xinput2_pen_evdevid(_this, deviceid); /* also initialises pen_atoms  */

    if (!evdevid) {
        /* Fallback: if no evdevid is available; try to at least distinguish devices within the
           current session.  This is a poor GUID and our last resort. */
        evdevid = deviceid;
    }
    SDL_PenUpdateGUIDForGeneric(&pident->guid, 0, evdevid);
}

/* Identify Wacom devices (if SDL_TRUE is returned) and extract their device type and serial IDs */
static SDL_bool xinput2_wacom_deviceid(SDL_VideoDevice *_this, int deviceid, Uint32 *wacom_devicetype_id, Uint32 *wacom_serial)
{
#if !(SDL_PEN_DEBUG_NONWACOM) /* Can be disabled for testing */
    Sint32 serial_id_buf[3];
    int result;

    pen_atoms_ensure_initialized(_this);

    if ((result = xinput2_pen_get_int_property(_this, deviceid, pen_atoms.wacom_serial_ids, serial_id_buf, 3)) == 3) {
        *wacom_devicetype_id = serial_id_buf[2];
        *wacom_serial = serial_id_buf[1];
#if SDL_PEN_DEBUG_NOSERIAL_WACOM /* Disabled for testing? */
        *wacom_serial = 0;
#endif
        return SDL_TRUE;
    }
#endif
    return SDL_FALSE;
}

/* Heuristically determines if device is an eraser */
static SDL_bool xinput2_pen_is_eraser(SDL_VideoDevice *_this, int deviceid, char *devicename)
{
    SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
    char dev_name[PEN_ERASER_ID_MAXLEN];
    int k;

    pen_atoms_ensure_initialized(_this);

    if (pen_atoms.wacom_tool_type != None) {
        Atom type_return;
        int format_return;
        unsigned long num_items_return;
        unsigned long bytes_after_return;
        unsigned char *tooltype_name_info = NULL;

        /* Try Wacom-specific method */
        if (Success == X11_XIGetProperty(data->display, deviceid,
                                         pen_atoms.wacom_tool_type,
                                         0, 32, False,
                                         AnyPropertyType, &type_return, &format_return,
                                         &num_items_return, &bytes_after_return,
                                         &tooltype_name_info) &&
            tooltype_name_info != NULL && num_items_return > 0) {

            SDL_bool result = SDL_FALSE;
            char *tooltype_name = NULL;

            if (type_return == XA_ATOM) {
                /* Atom instead of string?  Un-intern */
                Atom atom = *((Atom *)tooltype_name_info);
                if (atom != None) {
                    tooltype_name = X11_XGetAtomName(data->display, atom);
                }
            } else if (type_return == XA_STRING && format_return == 8) {
                tooltype_name = (char *)tooltype_name_info;
            }

            if (tooltype_name) {
                if (0 == SDL_strcasecmp(tooltype_name, PEN_ERASER_NAME_TAG)) {
                    result = SDL_TRUE;
                }
                X11_XFree(tooltype_name_info);

                return result;
            }
        }
    }
    /* Non-Wacom device? */

    /* We assume that a device is an eraser if its name contains the string "eraser".
     * Unfortunately there doesn't seem to be a clean way to distinguish these cases (as of 2022-03). */

    SDL_strlcpy(dev_name, devicename, PEN_ERASER_ID_MAXLEN);
    /* lowercase device name string so we can use strstr() */
    for (k = 0; dev_name[k]; ++k) {
        dev_name[k] = SDL_tolower(dev_name[k]);
    }

    return (SDL_strstr(dev_name, PEN_ERASER_NAME_TAG)) ? SDL_TRUE : SDL_FALSE;
}

/* Gets GUID and other identifying information for the device using the best known method */
static pen_identity xinput2_identify_pen(SDL_VideoDevice *_this, int deviceid, char *name)
{
    pen_identity pident;

    pident.devicetype_id = 0ul;
    pident.serial = 0ul;
    pident.deviceid = deviceid;
    pident.heuristic_type = SDL_PEN_TYPE_PEN;
    SDL_memset(pident.guid.data, 0, sizeof(pident.guid.data));

    if (xinput2_pen_is_eraser(_this, deviceid, name)) {
        pident.heuristic_type = SDL_PEN_TYPE_ERASER;
    }

    if (xinput2_wacom_deviceid(_this, deviceid, &pident.devicetype_id, &pident.serial)) {
        pident.vendor = SDL_PEN_VENDOR_WACOM;
        SDL_PenUpdateGUIDForWacom(&pident.guid, pident.devicetype_id, pident.serial);

#if DEBUG_PEN
        printf("[pen] Pen %d reports Wacom device_id %x\n",
               deviceid, pident.devicetype_id);
#endif

    } else {
        pident.vendor = SDL_PEN_VENDOR_UNKNOWN;
    }
    if (!pident.serial) {
        /* If the pen has a serial number, we can move it across tablets and retain its identity.
           Otherwise, we use the evdev ID as part of its GUID, which may mean that we identify it with the tablet. */
        xinput2_pen_update_generic_guid(_this, &pident, deviceid);
    }
    SDL_PenUpdateGUIDForType(&pident.guid, pident.heuristic_type);
    return pident;
}

static void xinput2_pen_free_deviceinfo(Uint32 deviceid, void *x11_peninfo, void *context)
{
    SDL_free(x11_peninfo);
}

static void xinput2_merge_deviceinfo(xinput2_pen *dest, xinput2_pen *src)
{
    *dest = *src;
}

/**
 * Fill in vendor-specific device information, if available
 *
 * For Wacom pens: identify number of buttons and extra axis (if present)
 *
 * \param _this global state
 * \param dev The device to analyse
 * \param pen The pen to initialise
 * \param pident Pen identity information
 * \param[out] valuator_5 Meaning of the valuator with offset 5, if any
 *   (written only if known and if the device has a 6th axis,
 *   e.g., for the Wacom Art Pen and Wacom Airbrush Pen)
 * \param[out] axes Bitmask of all possibly supported axes
 *
 * This function identifies Wacom device types through a Wacom-specific device ID.
 * It then fills in pen details from an internal database.
 * If the device seems to be a Wacom pen/eraser but can't be identified, the function
 * leaves "axes" untouched and sets the other outputs to common defaults.
 *
 * There is no explicit support for other vendors, though vendors that
 * emulate the Wacom API might be supported.
 *
 * Unsupported devices will keep the default settings.
 */
static void xinput2_vendor_peninfo(SDL_VideoDevice *_this, const XIDeviceInfo *dev, SDL_Pen *pen, pen_identity pident, int *valuator_5, Uint32 *axes)
{
    switch (pident.vendor) {
    case SDL_PEN_VENDOR_WACOM:
    {
        if (SDL_PenModifyForWacomID(pen, pident.devicetype_id, axes)) {
            if (*axes & SDL_PEN_AXIS_SLIDER_MASK) {
                /* Air Brush Pen or eraser */
                *valuator_5 = SDL_PEN_AXIS_SLIDER;
            } else if (*axes & SDL_PEN_AXIS_ROTATION_MASK) {
                /* Art Pen or eraser, or 6D Art Pen */
                *valuator_5 = SDL_PEN_AXIS_ROTATION;
            }
            return;
        } else {
#if DEBUG_PEN
            printf("[pen] Could not identify wacom pen %d with device id %x, using default settings\n",
                   pident.deviceid, pident.devicetype_id);
#endif
            break;
        }
    }

    default:
#if DEBUG_PEN
        printf("[pen] Pen %d is not from a known vendor\n", pident.deviceid);
#endif
        break;
    }

    /* Fall back to default heuristics for identifying device type */

    SDL_strlcpy(pen->name, dev->name, SDL_PEN_MAX_NAME);

    pen->type = pident.heuristic_type;
}

/* Does this device have a valuator for pressure sensitivity? */
static SDL_bool xinput2_device_is_pen(SDL_VideoDevice *_this, const XIDeviceInfo *dev)
{
    int classct;

    pen_atoms_ensure_initialized(_this);

    for (classct = 0; classct < dev->num_classes; ++classct) {
        const XIAnyClassInfo *classinfo = dev->classes[classct];

        switch (classinfo->type) {
        case XIValuatorClass:
        {
            XIValuatorClassInfo *val_classinfo = (XIValuatorClassInfo *)classinfo;
            Atom vname = val_classinfo->label;

            if (vname == pen_atoms.abs_pressure) {
                return SDL_TRUE;
            }
        }
        }
    }
    return SDL_FALSE;
}

void X11_InitPen(SDL_VideoDevice *_this)
{
    SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
    int i;
    XIDeviceInfo *device_info;
    int num_device_info;

    device_info = X11_XIQueryDevice(data->display, XIAllDevices, &num_device_info);
    if (!device_info) {
        return;
    }

    /* Reset the device id -> pen map */
    if (pen_map.entries) {
        SDL_free(pen_map.entries);
        pen_map.entries = NULL;
        pen_map.num_entries = 0;
    }

    SDL_PenGCMark();

    for (i = 0; i < num_device_info; ++i) {
        const XIDeviceInfo *dev = &device_info[i];
        int classct;
        xinput2_pen pen_device;
        Uint32 capabilities = 0;
        Uint32 axis_mask = ~0;    /* Permitted axes (default: all) */
        int valuator_5_axis = -1; /* For Wacom devices, the 6th valuator (offset 5) has a model-specific meaning */
        pen_identity pident;
        SDL_PenID pen_id;
        SDL_Pen *pen;
        int old_num_pens_known = pen_map.num_pens_known;
        int k;

        /* Only track physical devices that are enabled and look like pens */
        if (dev->use != XISlavePointer || dev->enabled == 0 || !xinput2_device_is_pen(_this, dev)) {
            continue;
        }

        pen_device.slider_bias = 0.0f;
        pen_device.rotation_bias = 0.0f;
        for (k = 0; k < SDL_PEN_NUM_AXES; ++k) {
            pen_device.valuator_for_axis[k] = SDL_PEN_AXIS_VALUATOR_MISSING;
        }

        pident = xinput2_identify_pen(_this, dev->deviceid, dev->name);

        pen_id = SDL_GetPenFromGUID(pident.guid);
        if (pen_id == SDL_PEN_INVALID) {
            /* We have never met this pen */
            pen_id = ++pen_map.num_pens_known; /* start at 1 */
        }
        pen = SDL_PenModifyBegin(pen_id);

        /* Complement XF86 driver information with vendor-specific details */
        xinput2_vendor_peninfo(_this, dev, pen, pident, &valuator_5_axis, &axis_mask);

        for (classct = 0; classct < dev->num_classes; ++classct) {
            const XIAnyClassInfo *classinfo = dev->classes[classct];

            switch (classinfo->type) {
            case XIValuatorClass:
            {
                XIValuatorClassInfo *val_classinfo = (XIValuatorClassInfo *)classinfo;
                Sint8 valuator_nr = val_classinfo->number;
                Atom vname = val_classinfo->label;
                int axis = -1;

                float min = (float)val_classinfo->min;
                float max = (float)val_classinfo->max;

                if (vname == pen_atoms.abs_pressure) {
                    axis = SDL_PEN_AXIS_PRESSURE;
                } else if (vname == pen_atoms.abs_tilt_x) {
                    axis = SDL_PEN_AXIS_XTILT;
                } else if (vname == pen_atoms.abs_tilt_y) {
                    axis = SDL_PEN_AXIS_YTILT;
                }

                if (axis == -1 && valuator_nr == 5) {
                    /* Wacom model-specific axis support */
                    /* The meaning of the various axes is highly underspecitied in Xinput2.
                     * As of 2023-08-26, Wacom seems to be the only vendor to support these axes, so the code below
                     * captures the de-facto standard. */
                    axis = valuator_5_axis;

                    switch (axis) {
                    case SDL_PEN_AXIS_SLIDER:
                        /* cf. xinput2_wacom_peninfo for how this axis is used.
                           In all current cases, our API wants this value in 0..1, but the xf86 driver
                           starts at a negative offset, so we normalise here. */
                        pen_device.slider_bias = -min;
                        max -= min;
                        min = 0.0f;
                        break;

                    case SDL_PEN_AXIS_ROTATION:
                        /* The "0" value points to the left, rather than up, so we must
                           rotate 90 degrees counter-clockwise to have 0 point to the top. */

                        pen_device.rotation_bias = -90.0f;
                        break;

                    default:
                        break;
                    }
                }

                if (axis >= 0) {
                    capabilities |= SDL_PEN_AXIS_CAPABILITY(axis);

                    pen_device.valuator_for_axis[axis] = valuator_nr;
                    pen_device.axis_min[axis] = min;
                    pen_device.axis_max[axis] = max;
                }
                break;
            }
            default:
                break;
            }
        }

        /* We have a pen if and only if the device measures pressure */
        if (capabilities & SDL_PEN_AXIS_PRESSURE_MASK) {
            xinput2_pen *xinput2_deviceinfo;
            Uint64 guid_a, guid_b;

            /* Done collecting data, write to pen */
            SDL_PenModifyAddCapabilities(pen, capabilities);
            pen->guid = pident.guid;

            if (pen->deviceinfo) {
                /* Updating a known pen */
                xinput2_deviceinfo = (xinput2_pen *)pen->deviceinfo;
                xinput2_merge_deviceinfo(xinput2_deviceinfo, &pen_device);
            } else {
                /* Registering a new pen */
                xinput2_deviceinfo = SDL_malloc(sizeof(xinput2_pen));
                SDL_memcpy(xinput2_deviceinfo, &pen_device, sizeof(xinput2_pen));
            }
            pen->deviceinfo = xinput2_deviceinfo;

#if DEBUG_PEN
            printf("[pen] pen %d [%04x] valuators pressure=%d, xtilt=%d, ytilt=%d [%s]\n",
                   pen->header.id, pen->header.flags,
                   pen_device.valuator_for_axis[SDL_PEN_AXIS_PRESSURE],
                   pen_device.valuator_for_axis[SDL_PEN_AXIS_XTILT],
                   pen_device.valuator_for_axis[SDL_PEN_AXIS_YTILT],
                   pen->name);
#endif
            SDL_memcpy(&guid_a, &pen->guid.data[0], 8);
            SDL_memcpy(&guid_b, &pen->guid.data[8], 8);
            if (!(guid_a | guid_b)) {
#if DEBUG_PEN
                printf("[pen]    (pen eliminated due to zero GUID)\n");
#endif
                pen->type = SDL_PEN_TYPE_NONE;
            }

        } else {
            /* Not a pen, mark for deletion */
            pen->type = SDL_PEN_TYPE_NONE;
        }
        SDL_PenModifyEnd(pen, SDL_TRUE);

        if (pen->type != SDL_PEN_TYPE_NONE) {
            const int map_pos = pen_map.num_entries;

            /* We found a pen: add mapping */
            if (pen_map.entries == NULL) {
                pen_map.entries = SDL_calloc(sizeof(struct pen_device_id_mapping), 1);
                pen_map.num_entries = 1;
            } else {
                pen_map.num_entries += 1;
                pen_map.entries = SDL_realloc(pen_map.entries,
                                              pen_map.num_entries * (sizeof(struct pen_device_id_mapping)));
            }
            pen_map.entries[map_pos].deviceid = dev->deviceid;
            pen_map.entries[map_pos].pen_id = pen_id;
        } else {
            /* Revert pen number allocation */
            pen_map.num_pens_known = old_num_pens_known;
        }
    }
    X11_XIFreeDeviceInfo(device_info);

    SDL_PenGCSweep(NULL, xinput2_pen_free_deviceinfo);
}

static void xinput2_normalize_pen_axes(const SDL_Pen *peninfo,
                                       const xinput2_pen *xpen,
                                       /* inout-mode paramters: */
                                       float *coords)
{
    int axis;

    /* Normalise axes */
    for (axis = 0; axis < SDL_PEN_NUM_AXES; ++axis) {
        int valuator = xpen->valuator_for_axis[axis];
        if (valuator != SDL_PEN_AXIS_VALUATOR_MISSING) {
            float value = coords[axis];
            float min = xpen->axis_min[axis];
            float max = xpen->axis_max[axis];

            if (axis == SDL_PEN_AXIS_SLIDER) {
                value += xpen->slider_bias;
            }

            /* min ... 0 ... max */
            if (min < 0.0) {
                /* Normalise so that 0 remains 0.0 */
                if (value < 0) {
                    value = value / (-min);
                } else {
                    if (max == 0.0) {
                        value = 0.0f;
                    } else {
                        value = value / max;
                    }
                }
            } else {
                /* 0 ... min ... max */
                /* including 0.0 = min */
                if (max == 0.0) {
                    value = 0.0f;
                } else {
                    value = (value - min) / max;
                }
            }

            switch (axis) {
            case SDL_PEN_AXIS_XTILT:
            case SDL_PEN_AXIS_YTILT:
                if (peninfo->info.max_tilt > 0.0f) {
                    value *= peninfo->info.max_tilt; /* normalise to physical max */
                }
                break;

            case SDL_PEN_AXIS_ROTATION:
                /* normalised to -1..1, so let's convert to degrees */
                value *= 180.0f;
                value += xpen->rotation_bias;

                /* handle simple over/underflow */
                if (value >= 180.0f) {
                    value -= 360.0f;
                } else if (value < -180.0f) {
                    value += 360.0f;
                }
                break;

            default:
                break;
            }
            coords[axis] = value;
        }
    }
}

void X11_PenAxesFromValuators(const SDL_Pen *peninfo,
                              const double *input_values, const unsigned char *mask, const int mask_len,
                              /* out-mode parameters: */
                              float axis_values[SDL_PEN_NUM_AXES])
{
    const xinput2_pen *pen = (xinput2_pen *)peninfo->deviceinfo;
    int i;

    for (i = 0; i < SDL_PEN_NUM_AXES; ++i) {
        const int valuator = pen->valuator_for_axis[i];
        if (valuator == SDL_PEN_AXIS_VALUATOR_MISSING || valuator >= mask_len * 8 || !(XIMaskIsSet(mask, valuator))) {
            axis_values[i] = 0.0f;
        } else {
            axis_values[i] = (float)input_values[valuator];
        }
    }
    xinput2_normalize_pen_axes(peninfo, pen, axis_values);
}

#endif /* SDL_VIDEO_DRIVER_X11_XINPUT2 */

/* vi: set ts=4 sw=4 expandtab: */
