diff options
Diffstat (limited to 'src/osd/modules/input/input_x11.cpp')
-rw-r--r-- | src/osd/modules/input/input_x11.cpp | 678 |
1 files changed, 380 insertions, 298 deletions
diff --git a/src/osd/modules/input/input_x11.cpp b/src/osd/modules/input/input_x11.cpp index 40df3d528b6..5230dfd7164 100644 --- a/src/osd/modules/input/input_x11.cpp +++ b/src/osd/modules/input/input_x11.cpp @@ -9,34 +9,41 @@ //============================================================ #include "input_module.h" + #include "modules/osdmodule.h" #if defined(SDLMAME_SDL2) && !defined(SDLMAME_WIN32) && defined(USE_XINPUT) && USE_XINPUT +#include "input_common.h" + +#include "sdl/osdsdl.h" + +// MAME headers +#include "inpttype.h" + +// standard SDL header +#include <SDL2/SDL.h> + // for X11 xinput #include <X11/Xlib.h> #include <X11/extensions/XInput.h> #include <X11/Xutil.h> -// standard sdl header -#include <SDL2/SDL.h> -#include <ctype.h> -#include <stddef.h> -#include <mutex> +#include <algorithm> +#include <cctype> +#include <cstddef> +#include <cstdio> +#include <cstring> #include <memory> +#include <mutex> #include <queue> #include <string> -#include <algorithm> +#include <unordered_map> -// MAME headers -#include "emu.h" -#include "osdepend.h" -// MAMEOS headers -#include "../lib/osdobj_common.h" -#include "input_common.h" -#include "../../sdl/osdsdl.h" -#include "input_sdlcommon.h" +namespace osd { + +namespace { #define MAX_DEVMAP_ENTRIES 16 @@ -49,20 +56,6 @@ static int key_release_type = INVALID_EVENT_TYPE; static int proximity_in_type = INVALID_EVENT_TYPE; static int proximity_out_type = INVALID_EVENT_TYPE; -// state information for a lightgun -struct lightgun_state -{ - int32_t lX, lY; - int32_t buttons[MAX_BUTTONS]; -}; - -struct x11_api_state -{ - XID deviceid; // X11 device id - int32_t maxx, maxy; - int32_t minx, miny; -}; - //============================================================ // DEBUG MACROS //============================================================ @@ -71,56 +64,64 @@ struct x11_api_state #define XI_DBG(format, ...) osd_printf_verbose(format, __VA_ARGS__) #define print_motion_event(motion) print_motion_event_impl(motion) -static inline void print_motion_event_impl(XDeviceMotionEvent *motion) +inline void print_motion_event_impl(XDeviceMotionEvent const *motion) { /* * print a lot of debug informations of the motion event(s). */ osd_printf_verbose( - "XDeviceMotionEvent:\n" - " type: %d\n" - " serial: %lu\n" - " send_event: %d\n" - " display: %p\n" - " window: --\n" - " deviceid: %lu\n" - " root: --\n" - " subwindow: --\n" - " time: --\n" - " x: %d, y: %d\n" - " x_root: %d, y_root: %d\n" - " state: %u\n" - " is_hint: %2.2X\n" - " same_screen: %d\n" - " device_state: %u\n" - " axes_count: %2.2X\n" - " first_axis: %2.2X\n" - " axis_data[6]: {%d,%d,%d,%d,%d,%d}\n", - motion->type, - motion->serial, - motion->send_event, - motion->display, - /* motion->window, */ - motion->deviceid, - /* motion->root */ - /* motion->subwindow */ - /* motion->time, */ - motion->x, motion->y, - motion->x_root, motion->y_root, - motion->state, - motion->is_hint, - motion->same_screen, - motion->device_state, - motion->axes_count, - motion->first_axis, - motion->axis_data[0], motion->axis_data[1], motion->axis_data[2], motion->axis_data[3], motion->axis_data[4], motion->axis_data[5] - ); + "XDeviceMotionEvent:\n" + " type: %d\n" + " serial: %lu\n" + " send_event: %d\n" + " display: %p\n" + " window: --\n" + " deviceid: %lu\n" + " root: --\n" + " subwindow: --\n" + " time: --\n" + " x: %d, y: %d\n" + " x_root: %d, y_root: %d\n" + " state: %u\n" + " is_hint: %2.2X\n" + " same_screen: %d\n" + " device_state: %u\n" + " axes_count: %2.2X\n" + " first_axis: %2.2X\n" + " axis_data[6]: {%d,%d,%d,%d,%d,%d}\n", + motion->type, + motion->serial, + motion->send_event, + motion->display, + /* motion->window, */ + motion->deviceid, + /* motion->root */ + /* motion->subwindow */ + /* motion->time, */ + motion->x, motion->y, + motion->x_root, motion->y_root, + motion->state, + motion->is_hint, + motion->same_screen, + motion->device_state, + motion->axes_count, + motion->first_axis, + motion->axis_data[0], motion->axis_data[1], motion->axis_data[2], motion->axis_data[3], motion->axis_data[4], motion->axis_data[5]); } #else -#define XI_DBG(format, ...) while(0) {} -#define print_motion_event(motion) while(0) {} +#define XI_DBG(format, ...) do { } while (false) +#define print_motion_event(motion) do { } while (false) #endif + +inline std::string remove_spaces(const char *s) +{ + std::string output(s); + output.erase(std::remove_if(output.begin(), output.end(), isspace), output.end()); + return output; +} + + //============================================================ // lightgun helpers: copy-past from xinfo //============================================================ @@ -138,7 +139,7 @@ find_device_info(Display *display, bool is_id = true; XID id = static_cast<XID>(-1); - for(loop = 0; loop < len; loop++) + for (loop = 0; loop < len; loop++) { if (!isdigit(name[loop])) { @@ -154,7 +155,7 @@ find_device_info(Display *display, devices = XListInputDevices(display, &num_devices); - for(loop = 0; loop < num_devices; loop++) + for (loop = 0; loop < num_devices; loop++) { osd_printf_verbose("Evaluating device with name: %s\n", devices[loop].name); @@ -185,7 +186,7 @@ find_device_info(Display *display, } //Copypasted from xinfo -static int +int register_events( Display *dpy, XDeviceInfo *info, @@ -252,32 +253,90 @@ register_events( return number; } -//============================================================ -// x11_event_manager -//============================================================ -class x11_event_handler +struct device_map { -public: - virtual ~x11_event_handler() {} + static inline constexpr unsigned MAX_ENTRIES = 16; + + struct { + std::string name; + int physical; + } map[MAX_ENTRIES]; + int logical[MAX_ENTRIES]; + int initialized; + + void init(osd_options const &options, const char *opt, int max_devices, const char *label) + { + // initialize based on an input option prefix and max number of devices + char defname[20]; + + // The max devices the user specified, better not be bigger than the max the arrays can old + assert(max_devices <= MAX_ENTRIES); - virtual void handle_event(XEvent &xevent) = 0; + // Initialize the map to default uninitialized values + for (int dev = 0; dev < MAX_ENTRIES; dev++) + { + map[dev].name.clear(); + map[dev].physical = -1; + logical[dev] = -1; + } + initialized = 0; + + // populate the device map up to the max number of devices + for (int dev = 0; dev < max_devices; dev++) + { + const char *dev_name; + + // derive the parameter name from the option name and index. For instance: lightgun_index1 to lightgun_index8 + sprintf(defname, "%s%d", opt, dev + 1); + + // Get the user-specified name that matches the parameter + dev_name = options.value(defname); + + // If they've specified a name and it's not "auto", treat it as a custom mapping + if (dev_name && *dev_name && strcmp(dev_name, OSDOPTVAL_AUTO)) + { + // remove the spaces from the name store it in the index + map[dev].name = remove_spaces(dev_name); + osd_printf_verbose("%s: Logical id %d: %s\n", label, dev + 1, map[dev].name); + initialized = 1; + } + } + } }; -class x11_event_manager : public event_manager_t<x11_event_handler> + +//============================================================ +// x11_event_manager +//============================================================ + +class x11_event_manager : public event_subscription_manager<XEvent, int> { private: - Display * m_display; - - x11_event_manager() - : event_manager_t(), - m_display(nullptr) + struct x_cleanup { - } + void operator()(Display *ptr) const + { + if (ptr) + XCloseDisplay(ptr); + } + void operator()(XExtensionVersion *ptr) const + { + if (ptr) + XFree(ptr); + } + }; + + template <typename T> using x_ptr = std::unique_ptr<T, x_cleanup>; + + x_ptr<Display> m_display; + + x11_event_manager() = default; + public: - Display * display() const { return m_display; } + Display *display() const { return m_display.get(); } - static x11_event_manager& instance() + static x11_event_manager &instance() { static x11_event_manager s_instance; return s_instance; @@ -285,20 +344,20 @@ public: int initialize() { - std::lock_guard<std::mutex> scope_lock(m_lock); + std::lock_guard<std::mutex> scope_lock(subscription_mutex()); - if (m_display != nullptr) + if (m_display) return 0; - m_display = XOpenDisplay(nullptr); - if (m_display == nullptr) + m_display.reset(XOpenDisplay(nullptr)); + if (!m_display) { osd_printf_verbose("Unable to connect to X server\n"); return -1; } - XExtensionVersion *version = XGetExtensionVersion(m_display, INAME); - if (!version || (version == reinterpret_cast<XExtensionVersion*>(NoSuchExtension))) + x_ptr<XExtensionVersion> version(XGetExtensionVersion(m_display.get(), INAME)); + if (!version || (version.get() == reinterpret_cast<XExtensionVersion *>(NoSuchExtension))) { osd_printf_verbose("xinput extension not available!\n"); return -1; @@ -307,28 +366,24 @@ public: return 0; } - void process_events(running_machine &machine) override + void process_events() { - std::lock_guard<std::mutex> scope_lock(m_lock); - XEvent xevent; + std::lock_guard<std::mutex> scope_lock(subscription_mutex()); - //Get XInput events - while (XPending(m_display) != 0) - { - XNextEvent(m_display, &xevent); - - // Find all subscribers for the event type - auto subscribers = m_subscription_index.equal_range(xevent.type); + // If X11 has become invalid for some reason, XPending will crash. Assert instead. + assert(m_display); - // Dispatch the events - std::for_each(subscribers.first, subscribers.second, [&xevent](auto &pair) - { - pair.second->handle_event(xevent); - }); + // Get XInput events + while (XPending(m_display.get()) != 0) + { + XEvent event; + XNextEvent(m_display.get(), &event); + dispatch_event(event.type, event); } } }; + //============================================================ // x11_input_device //============================================================ @@ -336,15 +391,23 @@ public: class x11_input_device : public event_based_device<XEvent> { public: - x11_api_state x11_state; - - x11_input_device(running_machine &machine, const char *name, const char *id, input_device_class devclass, input_module &module) - : event_based_device(machine, name, id, devclass, module), - x11_state({0}) + x11_input_device( + std::string &&name, + std::string &&id, + input_module &module, + XDeviceInfo const *info) : + event_based_device(std::move(name), std::move(id), module), + m_device_id(info ? info->id : 0) { } + + XID const &device_id() const { return m_device_id; } + +protected: + XID const m_device_id; // X11 device ID }; + //============================================================ // x11_lightgun_device //============================================================ @@ -352,55 +415,124 @@ public: class x11_lightgun_device : public x11_input_device { public: - lightgun_state lightgun; + x11_lightgun_device( + std::string &&name, + std::string &&id, + input_module + &module, + XDeviceInfo *info) : + x11_input_device(std::move(name), std::move(id), module, info), + m_axis_count(0), + m_button_count(0), + m_maxx(0), + m_maxy(0), + m_minx(0), + m_miny(0), + m_lightgun({ 0 }) + { + if (info && (info->num_classes > 0)) + { + // Grab device info and translate to stuff MAME can use + XAnyClassPtr any = static_cast<XAnyClassPtr>(info->inputclassinfo); + for (int i = 0; i < info->num_classes; i++) + { + switch (any->c_class) + { + // Set the axis min/max ranges if we got them + case ValuatorClass: + { + auto const valuator_info = reinterpret_cast<XValuatorInfoPtr>(any); + auto axis_info = reinterpret_cast<XAxisInfoPtr>(reinterpret_cast<char *>(valuator_info) + sizeof(XValuatorInfo)); + for (int j = 0; (j < valuator_info->num_axes) && (j < 2); j++, axis_info++) + { + if (j == 0) + { + XI_DBG("Set minx=%d, maxx=%d\n", axis_info->min_value, axis_info->max_value); + m_axis_count = 1; + m_maxx = axis_info->max_value; + m_minx = axis_info->min_value; + } + + if (j == 1) + { + XI_DBG("Set miny=%d, maxy=%d\n", axis_info->min_value, axis_info->max_value); + m_axis_count = 2; + m_maxy = axis_info->max_value; + m_miny = axis_info->min_value; + } + } + } + break; + + // Count the lightgun buttons based on what we read + case ButtonClass: + { + XButtonInfoPtr b = reinterpret_cast<XButtonInfoPtr>(any); + if (b->num_buttons < 0) + m_button_count = 0; + else if (b->num_buttons <= MAX_BUTTONS) + m_button_count = b->num_buttons; + else + m_button_count = MAX_BUTTONS; + } + break; + } - x11_lightgun_device(running_machine &machine, const char *name, const char *id, input_module &module) - : x11_input_device(machine, name, id, DEVICE_CLASS_LIGHTGUN, module), - lightgun({0}) + any = reinterpret_cast<XAnyClassPtr>(reinterpret_cast<char *>(any) + any->length); + } + } + } + + virtual void reset() override { + memset(&m_lightgun, 0, sizeof(m_lightgun)); } - void process_event(XEvent &xevent) override + virtual void configure(input_device &device) override + { + // Add buttons + for (int button = 0; button < m_button_count; button++) + { + input_item_id const itemid = input_item_id(ITEM_ID_BUTTON1 + button); + device.add_item(default_button_name(button), std::string_view(), itemid, generic_button_get_state<std::int32_t>, &m_lightgun.buttons[button]); + } + + // Add X and Y axis + if (1 <= m_axis_count) + device.add_item("X", std::string_view(), ITEM_ID_XAXIS, generic_axis_get_state<std::int32_t>, &m_lightgun.lX); + if (2 <= m_axis_count) + device.add_item("Y", std::string_view(), ITEM_ID_YAXIS, generic_axis_get_state<std::int32_t>, &m_lightgun.lY); + } + + virtual void process_event(XEvent const &xevent) override { if (xevent.type == motion_type) { - XDeviceMotionEvent *motion = reinterpret_cast<XDeviceMotionEvent *>(&xevent); + auto const motion = reinterpret_cast<XDeviceMotionEvent const *>(&xevent); print_motion_event(motion); - /* - * We have to check with axis will start on array index 0. - * We have also to check the number of axes that are stored in the array. - */ + // We have to check with axis will start on array index 0. + // We also have to check the number of axes that are stored in the array. switch (motion->first_axis) { - /* - * Starting with x, check number of axis, if there is also the y axis stored. - */ + // Starting with x, check number of axes, if there is also the y axis stored. case 0: if (motion->axes_count >= 1) - { - lightgun.lX = normalize_absolute_axis(motion->axis_data[0], x11_state.minx, x11_state.maxx); - if (motion->axes_count >= 2) - { - lightgun.lY = normalize_absolute_axis(motion->axis_data[1], x11_state.miny, x11_state.maxy); - } - } + m_lightgun.lX = normalize_absolute_axis(motion->axis_data[0], m_minx, m_maxx); + if (motion->axes_count >= 2) + m_lightgun.lY = normalize_absolute_axis(motion->axis_data[1], m_miny, m_maxy); break; - /* - * Starting with y, ... - */ + // Starting with y, ... case 1: if (motion->axes_count >= 1) - { - lightgun.lY = normalize_absolute_axis(motion->axis_data[0], x11_state.miny, x11_state.maxy); - } + m_lightgun.lY = normalize_absolute_axis(motion->axis_data[0], m_miny, m_maxy); break; } } else if (xevent.type == button_press_type || xevent.type == button_release_type) { - XDeviceButtonEvent *button = reinterpret_cast<XDeviceButtonEvent *>(&xevent); + auto const button = reinterpret_cast<XDeviceButtonEvent const *>(&xevent); /* * SDL/X11 Number the buttons 1,2,3, while windows and other parts of MAME @@ -408,140 +540,160 @@ public: * -1 the button number to align the numbering schemes. */ int button_number = button->button; - switch (button_number) + if (button_number <= MAX_BUTTONS) { + switch (button_number) + { case 2: - button_number = 3; - break; case 3: - button_number = 2; + button_number ^= 1; break; + } + m_lightgun.buttons[button_number - 1] = (xevent.type == button_press_type) ? 0x80 : 0; } - lightgun.buttons[button_number - 1] = (xevent.type == button_press_type) ? 0x80 : 0; } } - void reset() override +private: + struct lightgun_state { - memset(&lightgun, 0, sizeof(lightgun)); - } + int32_t lX, lY; + int32_t buttons[MAX_BUTTONS]; + }; + + int m_axis_count; + int m_button_count; + int32_t m_maxx; + int32_t m_maxy; + int32_t m_minx; + int32_t m_miny; + lightgun_state m_lightgun; }; + //============================================================ // x11_lightgun_module //============================================================ -class x11_lightgun_module : public input_module_base, public x11_event_handler +class x11_lightgun_module : public input_module_impl<x11_input_device, osd_common_t>, public x11_event_manager::subscriber { private: - device_map_t m_lightgun_map; - Display * m_display; + device_map m_lightgun_map; + Display *m_display; + public: - x11_lightgun_module() - : input_module_base(OSD_LIGHTGUNINPUT_PROVIDER, "x11"), - m_display(nullptr) + x11_lightgun_module() : + input_module_impl<x11_input_device, osd_common_t>(OSD_LIGHTGUNINPUT_PROVIDER, "x11"), + m_display(nullptr) { } - void input_init(running_machine &machine) override + virtual bool probe() override { - int index; + // If there is no X server, X11 lightguns cannot be supported + Display *const display = XOpenDisplay(nullptr); + if (!display) + return false; + XCloseDisplay(display); - osd_printf_verbose("Lightgun: Begin initialization\n"); - - devmap_init(machine, &m_lightgun_map, SDLOPTION_LIGHTGUNINDEX, 8, "Lightgun mapping"); + return true; + } + virtual int init(osd_interface &osd, osd_options const &options) override + { + // If the X server has become invalid, a crash can occur x11_event_manager::instance().initialize(); m_display = x11_event_manager::instance().display(); + if (!m_display) + return -1; + + return input_module_impl<x11_input_device, osd_common_t>::init(osd, options); + } + + virtual void input_init(running_machine &machine) override + { + assert(m_display); + + input_module_impl<x11_input_device, osd_common_t>::input_init(machine); + + osd_printf_verbose("Lightgun: Begin initialization\n"); + + m_lightgun_map.init(*options(), SDLOPTION_LIGHTGUNINDEX, 8, "Lightgun mapping"); // Loop through all 8 possible devices - for (index = 0; index < 8; index++) + for (int index = 0; index < 8; index++) { - XDeviceInfo *info; - // Skip if the name is empty - if (m_lightgun_map.map[index].name.length() == 0) + if (m_lightgun_map.map[index].name.empty()) continue; - x11_lightgun_device *devinfo; + // Find the device info associated with the name std::string const &name = m_lightgun_map.map[index].name; - char defname[512]; + osd_printf_verbose("%i: %s\n", index, name); + XDeviceInfo *const info = find_device_info(m_display, name.c_str(), 0); + if (!info) + osd_printf_verbose("Lightgun: Can't find device %s!\n", name); - // Register and add the device - devinfo = create_lightgun_device(machine, index); - osd_printf_verbose("%i: %s\n", index, name.c_str()); - - // Find the device info associated with the name - info = find_device_info(m_display, name.c_str(), 0); + // previously had code to use "NC%d" format if name was empty + // but that couldn't happen because device creation would be skipped - // If we couldn't find the device, skip - if (info == nullptr) - { - osd_printf_verbose("Can't find device %s!\n", name.c_str()); - continue; - } + // Register and add the device + create_device<x11_lightgun_device>( + DEVICE_CLASS_LIGHTGUN, + std::string(name), + std::string(name), + info); - //Grab device info and translate to stuff mame can use - if (info->num_classes > 0) + // Register this device to receive event notifications + if (info) { - // Add the lightgun buttons based on what we read - add_lightgun_buttons(static_cast<XAnyClassPtr>(info->inputclassinfo), info->num_classes, devinfo); - - // Also, set the axix min/max ranges if we got them - set_lightgun_axis_props(static_cast<XAnyClassPtr>(info->inputclassinfo), info->num_classes, devinfo); + int const events_registered = register_events(m_display, info, name.c_str(), 0); + osd_printf_verbose("Device %i: Registered %i events.\n", int(info->id), events_registered); } + } - // Add X and Y axis - sprintf(defname, "X %s", devinfo->name()); - devinfo->device()->add_item(defname, ITEM_ID_XAXIS, generic_axis_get_state<std::int32_t>, &devinfo->lightgun.lX); - - sprintf(defname, "Y %s", devinfo->name()); - devinfo->device()->add_item(defname, ITEM_ID_YAXIS, generic_axis_get_state<std::int32_t>, &devinfo->lightgun.lY); - - // Save the device id - devinfo->x11_state.deviceid = info->id; + // register ourself to handle events from event manager + int const event_types[] = { motion_type, button_press_type, button_release_type }; + osd_printf_verbose("Events types to register: motion:%d, press:%d, release:%d\n", motion_type, button_press_type, button_release_type); + subscribe(x11_event_manager::instance(), event_types); - // Register this device to receive event notifications - int events_registered = register_events(m_display, info, m_lightgun_map.map[index].name.c_str(), 0); - osd_printf_verbose("Device %i: Registered %i events.\n", static_cast<int>(info->id), events_registered); + osd_printf_verbose("Lightgun: End initialization\n"); + } - // register ourself to handle events from event manager - int event_types[] = { motion_type, button_press_type, button_release_type }; - osd_printf_verbose("Events types to register: motion:%d, press:%d, release:%d\n", motion_type, button_press_type, button_release_type); - x11_event_manager::instance().subscribe(event_types, ARRAY_LENGTH(event_types), this); - } + virtual void exit() override + { + // unsubscribe from events + unsubscribe(); - osd_printf_verbose("Lightgun: End initialization\n"); + input_module_impl<x11_input_device, osd_common_t>::exit(); } - bool should_poll_devices(running_machine &machine) override + virtual bool should_poll_devices() override { - return sdl_event_manager::instance().has_focus(); + return osd().has_focus(); } - void before_poll(running_machine &machine) override + virtual void before_poll() override { - if (!should_poll_devices(machine)) - return; + // trigger the SDL event manager so it can process window events + input_module_impl<x11_input_device, osd_common_t>::before_poll(); // Tell the event manager to process events and push them to the devices - x11_event_manager::instance().process_events(machine); - - // Also trigger the SDL event manager so it can process window events - sdl_event_manager::instance().process_events(machine); + if (should_poll_devices()) + x11_event_manager::instance().process_events(); } - void handle_event(XEvent &xevent) override + virtual void handle_event(XEvent const &xevent) override { XID deviceid; if (xevent.type == motion_type) { - XDeviceMotionEvent *motion = reinterpret_cast<XDeviceMotionEvent *>(&xevent); + auto const motion = reinterpret_cast<XDeviceMotionEvent const *>(&xevent); deviceid = motion->deviceid; } else if (xevent.type == button_press_type || xevent.type == button_release_type) { - XDeviceButtonEvent *button = reinterpret_cast<XDeviceButtonEvent *>(&xevent); + auto const button = reinterpret_cast<XDeviceButtonEvent const *>(&xevent); deviceid = button->deviceid; } else @@ -550,97 +702,27 @@ public: } // Figure out which lightgun this event id destined for - auto target_device = std::find_if(devicelist()->begin(), devicelist()->end(), [deviceid](auto &device) - { - std::unique_ptr<device_info> &ptr = device; - return downcast<x11_input_device*>(ptr.get())->x11_state.deviceid == deviceid; - }); + auto target_device = std::find_if( + devicelist().begin(), + devicelist().end(), + [&deviceid] (auto &device) { return device->device_id() == deviceid; }); // If we find a matching lightgun, dispatch the event to the lightgun - if (target_device != devicelist()->end()) - { - downcast<x11_input_device*>((*target_device).get())->queue_events(&xevent, 1); - } + if (target_device != devicelist().end()) + (*target_device)->queue_events(&xevent, 1); } +}; -private: - x11_lightgun_device* create_lightgun_device(running_machine &machine, int index) - { - char tempname[20]; - - if (m_lightgun_map.map[index].name.length() == 0) - { - if (m_lightgun_map.initialized) - { - snprintf(tempname, ARRAY_LENGTH(tempname), "NC%d", index); - devicelist()->create_device<x11_lightgun_device>(machine, tempname, tempname, *this); - } - - return nullptr; - } - - return devicelist()->create_device<x11_lightgun_device>(machine, m_lightgun_map.map[index].name.c_str(), m_lightgun_map.map[index].name.c_str(), *this); - } - - void add_lightgun_buttons(XAnyClassPtr first_info_class, int num_classes, x11_lightgun_device *devinfo) const - { - XAnyClassPtr any = first_info_class; - - for (int i = 0; i < num_classes; i++) - { - switch (any->c_class) - { - case ButtonClass: - XButtonInfoPtr b = reinterpret_cast<XButtonInfoPtr>(any); - for (int button = 0; button < b->num_buttons; button++) - { - input_item_id itemid = static_cast<input_item_id>(ITEM_ID_BUTTON1 + button); - devinfo->device()->add_item(default_button_name(button), itemid, generic_button_get_state<std::int32_t>, &devinfo->lightgun.buttons[button]); - } - break; - } +} // anonymous namespace - any = reinterpret_cast<XAnyClassPtr>(reinterpret_cast<char *>(any) + any->length); - } - } +} // namespace osd - void set_lightgun_axis_props(XAnyClassPtr first_info_class, int num_classes, x11_lightgun_device *devinfo) const - { - XAnyClassPtr any = first_info_class; - for (int i = 0; i < num_classes; i++) - { - switch (any->c_class) - { - case ValuatorClass: - XValuatorInfoPtr valuator_info = reinterpret_cast<XValuatorInfoPtr>(any); - XAxisInfoPtr axis_info = reinterpret_cast<XAxisInfoPtr>(reinterpret_cast<char *>(valuator_info) + sizeof(XValuatorInfo)); - for (int j = 0; j < valuator_info->num_axes; j++, axis_info++) - { - if (j == 0) - { - XI_DBG("Set minx=%d, maxx=%d\n", axis_info->min_value, axis_info->max_value); - devinfo->x11_state.maxx = axis_info->max_value; - devinfo->x11_state.minx = axis_info->min_value; - } +#else // defined(SDLMAME_SDL2) && !defined(SDLMAME_WIN32) && defined(USE_XINPUT) && USE_XINPUT - if (j == 1) - { - XI_DBG("Set miny=%d, maxy=%d\n", axis_info->min_value, axis_info->max_value); - devinfo->x11_state.maxy = axis_info->max_value; - devinfo->x11_state.miny = axis_info->min_value; - } - } - break; - } +namespace osd { namespace { MODULE_NOT_SUPPORTED(x11_lightgun_module, OSD_LIGHTGUNINPUT_PROVIDER, "x11") } } - any = reinterpret_cast<XAnyClassPtr>(reinterpret_cast<char *>(any) + any->length); - } - } -}; +#endif // defined(SDLMAME_SDL2) && !defined(SDLMAME_WIN32) && defined(USE_XINPUT) && USE_XINPUT -#else -MODULE_NOT_SUPPORTED(x11_lightgun_module, OSD_LIGHTGUNINPUT_PROVIDER, "x11") -#endif -MODULE_DEFINITION(LIGHTGUN_X11, x11_lightgun_module) +MODULE_DEFINITION(LIGHTGUN_X11, osd::x11_lightgun_module) |