From 96be636240cafe89a664647fdefd8e58d3d3b80e Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Wed, 1 Apr 2020 15:29:58 +0100
Subject: [PATCH] Fixing up HID event input on Mac/Windows

Removing old macOS separate input - the HID version is better in
every way.
---
 3rdparty/hidapi/CMakeLists.txt   |   6 +-
 CMakeLists.txt                   |  15 +-
 src/Input/CMakeLists.txt         |   3 +-
 src/Input/FGMacOSXEventInput.cxx | 650 -------------------------------
 src/Input/FGMacOSXEventInput.hxx |  67 ----
 src/Input/input.cxx              |   5 +-
 6 files changed, 6 insertions(+), 740 deletions(-)
 delete mode 100644 src/Input/FGMacOSXEventInput.cxx
 delete mode 100644 src/Input/FGMacOSXEventInput.hxx

diff --git a/3rdparty/hidapi/CMakeLists.txt b/3rdparty/hidapi/CMakeLists.txt
index 06fc8a352..f4d69cad3 100644
--- a/3rdparty/hidapi/CMakeLists.txt
+++ b/3rdparty/hidapi/CMakeLists.txt
@@ -23,11 +23,7 @@ add_library(hidapi STATIC
 )
 
 if(WIN32)
-    find_library(SETUP_API_LIB Setupapi)
-	if (NOT SETUP_API_LIB)
-        message(FATAL_ERROR "Failed to find Setupapi.lib")
-    endif()
-    target_link_libraries(hidapi ${SETUP_API_LIB})
+    target_link_libraries(hidapi PUBLIC SetupApi)
 elseif(APPLE)
     find_library(IOKIT_FRAMEWORK IOKit)
     target_link_libraries(hidapi ${IOKIT_FRAMEWORK})
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3818b1110..d2a9a5aa9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -123,11 +123,7 @@ IF(APPLE)
     find_library(COCOA_LIBRARY Cocoa)
     list(APPEND PLATFORM_LIBS ${COCOA_LIBRARY} ${CORESERVICES_LIBRARY})
 elseif(WIN32)
-    find_library(SETUP_API_LIB Setupapi)
-    if (SETUP_API_LIB)
-        set(EVENT_INPUT_DEFAULT 1)
-    endif()
-
+    set(EVENT_INPUT_DEFAULT 1)
     list(APPEND PLATFORM_LIBS "Shlwapi.lib")
 
     set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION "bin")
@@ -265,14 +261,7 @@ if(EVENT_INPUT)
             message(STATUS "event-based input enabled. Using ${UDEV_LIBRARIES}")
         endif()
     else()
-        # Windows
-        if (NOT SETUP_API_LIB)
-            message(WARNING "Setupapi.lib not found, HID/event input is disabled")
-            set(ENABLE_HID_INPUT 0)
-            set(EVENT_INPUT 0)
-        else()
-            add_definitions(-DWITH_EVENTINPUT)
-        endif()
+        add_definitions(-DWITH_EVENTINPUT)
     endif()
 
     if (ENABLE_HID_INPUT)
diff --git a/src/Input/CMakeLists.txt b/src/Input/CMakeLists.txt
index 680991e9d..758172281 100644
--- a/src/Input/CMakeLists.txt
+++ b/src/Input/CMakeLists.txt
@@ -1,8 +1,7 @@
 include(FlightGearComponent)
 
 IF(APPLE)
-	set(EVENT_INPUT_SOURCES FGMacOSXEventInput.cxx)
-	set(EVENT_INPUT_HEADERS FGMacOSXEventInput.hxx)
+	# no Mac implemention, use HID
 elseif(WIN32)
 	# no Win32 specific implementation, at least for now
 else()
diff --git a/src/Input/FGMacOSXEventInput.cxx b/src/Input/FGMacOSXEventInput.cxx
deleted file mode 100644
index d7f6a33f4..000000000
--- a/src/Input/FGMacOSXEventInput.cxx
+++ /dev/null
@@ -1,650 +0,0 @@
-// FGMacOSXEventInput.cxx -- handle event driven input devices for Mac OS X
-//
-// Written by Tatsuhiro Nishioka, started Aug. 2009.
-//
-// Copyright (C) 2009 Tasuhiro Nishioka, tat <dot> fgmacosx <at> gmail <dot> com
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-//
-// $Id$
-
-#include "FGMacOSXEventInput.hxx"
-
-#include <simgear/sg_inlines.h>
-
-#include <cstdlib>
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <IOKit/hid/IOHIDLib.h>
-#include <IOKit/HID/IOHIDKeys.h>
-
-#include <simgear/structure/exception.hxx>
-
-static std::string nameForUsage(uint32_t usagePage, uint32_t usage)
-{
-    if (usagePage == kHIDPage_GenericDesktop) {
-        switch (usage) {
-        case kHIDUsage_GD_Joystick: return "joystick";
-        case kHIDUsage_GD_Wheel:        return "wheel";
-        case kHIDUsage_GD_Dial:         return "dial";
-        case kHIDUsage_GD_Hatswitch:    return "hat";
-        case kHIDUsage_GD_Slider:       return "slider";
-        case kHIDUsage_GD_Rx:           return "x-rotate";
-        case kHIDUsage_GD_Ry:           return "y-rotate";
-        case kHIDUsage_GD_Rz:           return "z-rotate";
-        case kHIDUsage_GD_X:            return "x-translate";
-        case kHIDUsage_GD_Y:            return "y-translate";
-        case kHIDUsage_GD_Z:            return "z-translate";
-        default:
-            SG_LOG(SG_INPUT, SG_WARN, "Unhandled HID generic desktop usage:" << usage);
-        }
-    } else if (usagePage == kHIDPage_Simulation) {
-        switch (usage) {
-        default:
-            SG_LOG(SG_INPUT, SG_WARN, "Unhandled HID simulation usage:" << usage);
-        }
-    } else if (usagePage == kHIDPage_Consumer) {
-        switch (usage) {
-            default:
-                SG_LOG(SG_INPUT, SG_WARN, "Unhandled HID consumer usage:" << usage);
-        }
-    } else if (usagePage == kHIDPage_AlphanumericDisplay) {
-        switch (usage) {
-        case kHIDUsage_AD_AlphanumericDisplay:  return "alphanumeric";
-        case kHIDUsage_AD_CharacterReport:  return "character-report";
-        case kHIDUsage_AD_DisplayData:  return "display-data";
-        case 0x46: return "display-brightness";
-
-        default:
-            SG_LOG(SG_INPUT, SG_WARN, "Unhandled HID alphanumeric usage:" << usage);
-        }
-    } else if (usagePage == kHIDPage_LEDs) {
-        switch (usage) {
-        case kHIDUsage_LED_GenericIndicator: return "led-misc";
-        case kHIDUsage_LED_Pause:       return "led-pause";
-        default:
-            SG_LOG(SG_INPUT, SG_WARN, "Unhandled HID LED usage:" << usage);
-
-        }
-    } else if (usagePage == kHIDPage_Button) {
-        std::stringstream os;
-        os << "button-" << usage;
-        return os.str();
-    } else if (usagePage >= kHIDPage_VendorDefinedStart) {
-        return "vendor";
-    } else {
-        SG_LOG(SG_INPUT, SG_WARN, "Unhandled HID usage page:" << usagePage);
-    }
-
-    return "unknown";
-}
-
-class FGMacOSXEventInputPrivate
-{
-public:
-    IOHIDManagerRef hidManager = nullptr;
-    FGMacOSXEventInput* p = nullptr;
-    double currentDt = 0.0;
-    int currentModifiers = 0;
-
-    void matchedDevice(IOHIDDeviceRef device);
-    void removedDevice(IOHIDDeviceRef device);
-
-    void iterateDevices(CFSetRef matchingSet);
-
-    std::string getDeviceStringProperty(IOHIDDeviceRef device, CFStringRef hidProp);
-    bool getDeviceIntProperty(IOHIDDeviceRef device, CFStringRef hidProp, int& value);
-};
-
-
-static void deviceMatchingCallback(
-                                  void *          inContext,       // context from IOHIDManagerRegisterDeviceMatchingCallback
-                                  IOReturn        inResult,        // the result of the matching operation
-                                  void *          inSender,        // the IOHIDManagerRef for the new device
-                                  IOHIDDeviceRef  inIOHIDDeviceRef // the new HID device
-)
-{
-   // printf("%s(context: %p, result: %p, sender: %p, device: %p).\n",
-    //       __PRETTY_FUNCTION__, inContext, (void *) inResult, inSender, (void*) inIOHIDDeviceRef);
-
-    FGMacOSXEventInputPrivate* p = static_cast<FGMacOSXEventInputPrivate*>(inContext);
-    p->matchedDevice(inIOHIDDeviceRef);
-}   // Handle_DeviceMatchingCallback
-
-
-static void deviceRemovalCallback(
-                                   void *          inContext,       // context from IOHIDManagerRegisterDeviceMatchingCallback
-                                   IOReturn        inResult,        // the result of the matching operation
-                                   void *          inSender,        // the IOHIDManagerRef for the new device
-                                   IOHIDDeviceRef  inIOHIDDeviceRef // the new HID device
-)
-{
-    // printf("%s(context: %p, result: %p, sender: %p, device: %p).\n",
-    //       __PRETTY_FUNCTION__, inContext, (void *) inResult, inSender, (void*) inIOHIDDeviceRef);
-    FGMacOSXEventInputPrivate* p = static_cast<FGMacOSXEventInputPrivate*>(inContext);
-    p->removedDevice(inIOHIDDeviceRef);
-}   // Handle_DeviceMatchingCallback
-
-//
-// FGMacOSXInputDevice implementation
-//
-
-//
-// FGMacOSXInputDevice
-// Mac OS X specific FGInputDevice
-//
-class FGMacOSXInputDevice : public FGInputDevice {
-public:
-
-    FGMacOSXInputDevice(IOHIDDeviceRef hidRef,
-                        FGMacOSXEventInputPrivate* subsys);
-
-    virtual ~FGMacOSXInputDevice();
-
-    bool Open() override;
-    void Close() override;
-    
-    virtual void update(double dt);
-    virtual const char *TranslateEventName(FGEventData &eventData);
-    virtual void Send( const char * eventName, double value );
-    virtual void SendFeatureReport(unsigned int reportId, const std::string& data);
-    virtual void AddHandledEvent( FGInputEvent_ptr handledEvent );
-
-    void drainQueue();
-    void handleValue(IOHIDValueRef value);
-
-private:
-    void buildElementNameDictionary();
-
-    std::string nameForHIDElement(IOHIDElementRef element) const;
-    
-    IOHIDDeviceRef _hid = nullptr;
-    IOHIDQueueRef _queue = nullptr;
-    FGMacOSXEventInputPrivate* _subsystem;
-
-    typedef std::map<std::string, IOHIDElementRef> NameElementDict;
-    NameElementDict namedElements;
-};
-
-#if 0
-static void valueAvailableCallback(void *   inContext, // context from IOHIDQueueRegisterValueAvailableCallback
-                                   IOReturn inResult,  // the inResult
-                                   void *   inSender  // IOHIDQueueRef of the queue
-) {
-    FGMacOSXInputDevice* dev = static_cast<FGMacOSXInputDevice*>(inContext);
-    dev->drainQueue();
-}   // Handle_ValueAvailableCallback
-#endif
-
-//
-// FGMacOSXEventInput implementation
-//
-
-
-FGMacOSXEventInput::FGMacOSXEventInput() :
-    FGEventInput(),
-    d(new FGMacOSXEventInputPrivate)
-{
-    d->p = this; // store back pointer to outer object on pimpl
-    SG_LOG(SG_INPUT, SG_DEBUG, "FGMacOSXEventInput created");
-}
-
-FGMacOSXEventInput::~FGMacOSXEventInput()
-{
-}
-
-void FGMacOSXEventInput::init()
-{
-    // everything is deffered until postinit since we need Nasal
-}
-
-void FGMacOSXEventInput::postinit()
-{
-    d->hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
-
-    // set the HID device matching dictionary
-    IOHIDManagerSetDeviceMatching( d->hidManager, NULL /* all devices */);
-
-    IOHIDManagerRegisterDeviceMatchingCallback(d->hidManager, deviceMatchingCallback, d.get());
-    IOHIDManagerRegisterDeviceRemovalCallback(d->hidManager, deviceRemovalCallback, d.get());
-
-    IOHIDManagerOpen(d->hidManager, kIOHIDOptionsTypeNone);
-
-    IOHIDManagerScheduleWithRunLoop(d->hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
-}
-
-void FGMacOSXEventInput::shutdown()
-{
-    FGEventInput::shutdown();
-
-    if (d->hidManager) {
-      IOHIDManagerClose(d->hidManager, kIOHIDOptionsTypeNone);
-      IOHIDManagerUnscheduleFromRunLoop(d->hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
-      CFRelease(d->hidManager);
-    }
-}
-
-//
-// read all elements in each input device
-//
-void FGMacOSXEventInput::update(double dt)
-{
-    d->currentDt = dt;
-    d->currentModifiers = fgGetKeyModifiers();
-    FGEventInput::update(dt);
-}
-
-void FGMacOSXEventInputPrivate::matchedDevice(IOHIDDeviceRef device)
-{
-    std::string productName = getDeviceStringProperty(device, CFSTR(kIOHIDProductKey));
-    std::string manufacturer = getDeviceStringProperty(device, CFSTR(kIOHIDManufacturerKey));
-    std::string serial = getDeviceStringProperty(device, CFSTR(kIOHIDSerialNumberKey));
-    
-// filter out keyboard and mouse devices : this is especially important for
-// Catalina TCC hardening to avoid secuirty alerts
-    int usagePage, usage;
-    getDeviceIntProperty(device,  CFSTR(kIOHIDPrimaryUsagePageKey), usagePage);
-    getDeviceIntProperty(device,  CFSTR(kIOHIDPrimaryUsageKey), usage);
-    
-    if (usagePage == kHIDPage_GenericDesktop) {
-        if ((usage == kHIDUsage_GD_Keyboard) || (usage == kHIDUsage_GD_Mouse)) {
-            SG_LOG(SG_INPUT, SG_INFO, "MacOSX-EventInput: skipping device:" << productName << "( from " << manufacturer << ") becuase it is a keyboard or mouse");
-            return;
-        }
-    }
-    
-    SG_LOG(SG_INPUT, SG_DEBUG, "MacOSX-EventInput: matched device:" << productName << "( from " << manufacturer << ")");
-            
-    // allocate a Mac input device, and add to the base class to see if we have
-    // a config
-
-    FGMacOSXInputDevice* macInputDevice = new FGMacOSXInputDevice(device, this);
-    macInputDevice->SetName(manufacturer + " " + productName);
-    macInputDevice->SetSerialNumber(serial);
-    
-    p->AddDevice(macInputDevice);
-}
-
-void FGMacOSXEventInputPrivate::removedDevice(IOHIDDeviceRef device)
-{
-    std::string productName = getDeviceStringProperty(device, CFSTR(kIOHIDProductKey));
-    std::string manufacturer = getDeviceStringProperty(device, CFSTR(kIOHIDManufacturerKey));
-    // see if we have an entry for the device
-}
-
-std::string FGMacOSXEventInputPrivate::getDeviceStringProperty(IOHIDDeviceRef device, CFStringRef hidProp)
-{
-    CFStringRef prop = (CFStringRef) IOHIDDeviceGetProperty(device, hidProp);
-    if ((prop == nullptr)|| (CFGetTypeID(prop) != CFStringGetTypeID())) {
-        return std::string();
-    }
-
-    size_t len = CFStringGetLength(prop);
-    if (len == 0) {
-        return std::string();
-    }
-
-    char* buffer = static_cast<char*>(malloc(len + 1)); // + 1 for the null byte
-    Boolean ok = CFStringGetCString(prop, buffer, len + 1, kCFStringEncodingUTF8);
-    if (!ok) {
-        SG_LOG(SG_INPUT, SG_WARN, "string conversion failed");
-    }
-
-    std::string result(buffer, len);
-    free(buffer);
-
-    return result;
-
-}
-
-bool FGMacOSXEventInputPrivate::getDeviceIntProperty(IOHIDDeviceRef device, CFStringRef hidProp, int& value)
-{
-    CFTypeRef prop = IOHIDDeviceGetProperty(device, hidProp);
-    if (CFGetTypeID(prop) != CFNumberGetTypeID()) {
-        return false;
-    }
-
-    int32_t v;
-    Boolean result = CFNumberGetValue((CFNumberRef) prop, kCFNumberSInt32Type, &v);
-    value = v;
-    return result;
-}
-
-void FGMacOSXEventInputPrivate::iterateDevices(CFSetRef matchingSet)
-{
-    size_t numDevices = CFSetGetCount(matchingSet);
-    IOHIDDeviceRef* devs = static_cast<IOHIDDeviceRef*>(::malloc(numDevices * sizeof(IOHIDDeviceRef)));
-    CFSetGetValues(matchingSet, (const void **) devs);
-
-    for (size_t i=0; i < numDevices; ++i) {
-        matchedDevice(devs[i]);
-    }
-
-    free(devs);
-}
-
-
-FGMacOSXInputDevice::FGMacOSXInputDevice(IOHIDDeviceRef hidRef,
-                                         FGMacOSXEventInputPrivate* subsys)
-{
-    _hid = hidRef;
-    CFRetain(_hid);
-    _subsystem = subsys;
-}
-
-FGMacOSXInputDevice::~FGMacOSXInputDevice()
-{
-    if (_queue) {
-        CFRelease(_queue);
-    }
-    
-    CFRelease(_hid);
-}
-
-bool FGMacOSXInputDevice::Open()
-{
-    IOReturn result = IOHIDDeviceOpen(_hid, kIOHIDOptionsTypeNone);
-    if (result != kIOReturnSuccess) {
-        return false;
-    }
-    
-    IOHIDDeviceScheduleWithRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
-    // IOHIDQueueRegisterValueAvailableCallback(_queue, valueAvailableCallback, this);
-    
-    CFIndex maxDepth = 128;
-    _queue = IOHIDQueueCreate(kCFAllocatorDefault, _hid, maxDepth, kIOHIDOptionsTypeNone);
-    
-    IOHIDQueueScheduleWithRunLoop(_queue, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
-    IOHIDQueueStart(_queue);
-    
-    return true;
-}
-
-void FGMacOSXInputDevice::buildElementNameDictionary()
-{
-    // copy all elements from the device
-    CFArrayRef elements = IOHIDDeviceCopyMatchingElements(_hid, NULL,
-                                                          kIOHIDOptionsTypeNone);
-
-    CFIndex count = CFArrayGetCount(elements);
-    typedef std::map<std::string, unsigned int> NameCountMap;
-    NameCountMap nameCounts;
-
-    std::set<IOHIDElementCookie> seenCookies;
-
-    for (int i = 0; i < count; ++i) {
-        IOHIDElementRef element = (IOHIDElementRef) CFArrayGetValueAtIndex(elements, i);
-        IOHIDElementCookie cookie = IOHIDElementGetCookie(element);
-        if (seenCookies.find(cookie) != seenCookies.end()) {
-            // skip duplicate match of this element;
-            continue;
-        }
-
-        seenCookies.insert(cookie);
-
-
-       // bool isWrapping = IOHIDElementIsWrapping(element);
-        IOHIDElementType ty = IOHIDElementGetType(element);
-        if (ty == kIOHIDElementTypeCollection)
-        {
-           continue;
-        }
-
-        uint32_t page = IOHIDElementGetUsagePage(element);
-        uint32_t usage = IOHIDElementGetUsage(element);
-        bool isRelative = IOHIDElementIsRelative(element);
-
-        // compute the name for the element
-        std::string name = nameForUsage(page, usage);
-        if (isRelative) {
-            name = "rel-" + name; // prefix relative elements
-        }
-
-        NameCountMap::iterator it = nameCounts.find(name);
-        unsigned int nameCount;
-        std::string finalName = name;
-
-        if (it == nameCounts.end()) {
-            nameCounts[name] = nameCount = 1;
-        } else {
-            // check if we have a collison but different element types, eg
-            // input & feature. In which case, prefix the feature one since
-            // we assume it's the input one which is more interesting.
-
-            IOHIDElementRef other = namedElements[name];
-            IOHIDElementType otherTy = IOHIDElementGetType(other);
-            if (otherTy != ty) {
-                // types mismatch
-                if (otherTy == kIOHIDElementTypeFeature) {
-                    namedElements[name] = element;
-                    element = other;
-                    finalName = "feature-" + name;
-                } else if (ty == kIOHIDElementTypeFeature) {
-                    finalName = "feature-" + name;
-                }
-                nameCount = 1;
-            } else {
-                // duplicate element, append ordinal suffix
-                std::stringstream os;
-                os << name << "-" << it->second;
-                finalName = os.str();
-                nameCount = ++(it->second);
-            }
-        }
-
-        CFRetain(element);
-        namedElements[finalName] = element;
-
-        if (nameCount == 2) {
-            // we have more than one entry for this name, so ensures
-            // the first item is availabe with the -0 suffix
-            std::stringstream os;
-            os << name << "-0";
-            namedElements[os.str()] = namedElements[name];
-            CFRetain(namedElements[os.str()]);
-        }
-
-    }
-
-// HID debugging code
-#if 0
-    NameElementDict::const_iterator it;
-    for (it = namedElements.begin(); it != namedElements.end(); ++it) {
-        int report = IOHIDElementGetReportID(it->second);
-        int reportCount = IOHIDElementGetReportCount(it->second);
-        int reportSize = IOHIDElementGetReportSize(it->second);
-        CFTypeRef sizeProp = IOHIDElementGetProperty(it->second, CFSTR(kIOHIDElementDuplicateIndexKey));
-        if (sizeProp) {
-            CFShow(sizeProp);
-        }
-
-        bool isArray = IOHIDElementIsArray(it->second);
-        if (isArray) {
-            SG_LOG(SG_INPUT, SG_INFO, "YYYYYYYYYYYYYYYYYY");
-        }
-        SG_LOG(SG_INPUT, SG_INFO, "\t" << it->first << " report ID " << report << " /count=" << reportCount
-               << " ;sz=" << reportSize);
-    }
-#endif
-
-    CFRelease(elements);
-}
-
-void FGMacOSXInputDevice::Close()
-{
-    // leaking these otherwise we get a crash shutting down the HID-manager
-    // object. Don't understand why that should be the case
-#if 0
-    for (auto it : namedElements) {
-        CFRelease(it.second);
-    }
-#endif
-    namedElements.clear();
-
-    IOHIDQueueStop(_queue);
-    IOHIDQueueUnscheduleFromRunLoop(_queue, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
-
-    IOHIDDeviceUnscheduleFromRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
-    IOHIDDeviceClose(_hid, kIOHIDOptionsTypeNone);
-}
-
-void FGMacOSXInputDevice::AddHandledEvent( FGInputEvent_ptr handledEvent )
-{
-    SG_LOG(SG_INPUT, SG_DEBUG, "adding event:" << handledEvent->GetName());
-    if (namedElements.empty()) {
-        buildElementNameDictionary();
-    }
-
-    NameElementDict::iterator it = namedElements.find(handledEvent->GetName());
-    if (it == namedElements.end()) {
-        SG_LOG(SG_INPUT, SG_WARN, "device does not have any element with name:" << handledEvent->GetName());
-        return;
-    }
-
-
-    IOHIDQueueAddElement(_queue, it->second);
-    FGInputDevice::AddHandledEvent(handledEvent);
-}
-
-void FGMacOSXInputDevice::update(double dt)
-{
-    SG_UNUSED(dt);
-    drainQueue();
-
-    FGInputDevice::update(dt);
-}
-
-void FGMacOSXInputDevice::drainQueue()
-{
-    do {
-        IOHIDValueRef valueRef = IOHIDQueueCopyNextValueWithTimeout( _queue, 0. );
-        if ( !valueRef ) break;
-        handleValue(valueRef);
-        CFRelease( valueRef );
-    } while ( 1 ) ;
-}
-
-void FGMacOSXInputDevice::handleValue(IOHIDValueRef value)
-{
-    IOHIDElementRef element = IOHIDValueGetElement(value);
-    CFIndex val;
-
-// need report count to know if we have to handle this specially
-    int reportCount = IOHIDElementGetReportCount(element);
-    if (reportCount > 1) {
-        // for a repeated element, we need to read the final value of
-        // the data bytes (even though this will be the lowest numbered name
-        // for this element.
-        int bitSize = IOHIDElementGetReportSize(element);
-        const uint8_t* bytes= IOHIDValueGetBytePtr(value);
-        size_t byteLen = IOHIDValueGetLength(value);
-        uint8_t finalByte = bytes[byteLen - 1];
-
-        if (bitSize == 8) {
-            val = (int8_t) finalByte; // force sign extension
-        } else if (bitSize == 4) {
-            int8_t b = finalByte >> 4; // high nibble
-            if (b & 0x08) {
-                // manually sign extend
-                b |= 0xf0; // set all bits except the low nibble
-            }
-            val = b;
-        } else {
-            throw sg_io_exception("Unhandled bit size in MacoSXHID");
-        }
-    } else {
-        val = IOHIDValueGetIntegerValue(value);
-    }
-
-// supress spurious 0-valued relative events
-    std::string name = nameForHIDElement(element);
-    if ((name.find("rel-") == 0) && (val == 0)) {
-        return;
-    }
-
-    FGMacOSXEventData eventData(name, val,
-                                _subsystem->currentDt,
-                                _subsystem->currentModifiers);
-    HandleEvent(eventData);
-    
-}
-
-std::string FGMacOSXInputDevice::nameForHIDElement(IOHIDElementRef element) const
-{
-    NameElementDict::const_iterator it;
-    for (it = namedElements.begin(); it != namedElements.end(); ++it) {
-        if (it->second == element) {
-            return it->first;
-        }
-    }
-
-    throw sg_exception("Unknown HID element");
-}
-
-const char *FGMacOSXInputDevice::TranslateEventName(FGEventData &eventData)
-{
-    FGMacOSXEventData &macEvent = (FGMacOSXEventData &)eventData;
-    return macEvent.name.c_str();
-}
-
-//
-// Outputs value to an writable element (like LEDElement)
-//
-void FGMacOSXInputDevice::Send(const char *eventName, double value)
-{
-    NameElementDict::const_iterator it = namedElements.find(eventName);
-    if (it == namedElements.end()) {
-        SG_LOG(SG_INPUT, SG_WARN, "FGMacOSXInputDevice::Send: unknown element:" << eventName);
-        return;
-    }
-
-    CFIndex cfVal = value;
-    uint64_t timestamp = 0;
-    IOHIDValueRef valueRef = IOHIDValueCreateWithIntegerValue(kCFAllocatorDefault,
-                                                              it->second, timestamp, cfVal);
-    IOHIDDeviceSetValue(_hid, it->second, valueRef);
-    CFRelease(valueRef);
-}
-
-void FGMacOSXInputDevice::SendFeatureReport(unsigned int reportId, const std::string& data)
-{
-
-    string d(data);
-    if (reportId > 0) {
-        // prefix with report number
-        d.insert(d.begin(), static_cast<char>(reportId));
-    }
-
-    size_t len = d.size();
-    const uint8_t* bytes = (const uint8_t*) d.data();
-
-    std::stringstream ss;
-    for (int i=0; i<len; ++i) {
-        ss << static_cast<int>(bytes[i]);
-        ss << ":";
-    }
-
-    SG_LOG(SG_INPUT, SG_INFO, "report " << reportId << " sending " << ss.str());
-
-    IOReturn res = IOHIDDeviceSetReport(_hid,
-                               kIOHIDReportTypeFeature,
-                               reportId, /* Report ID*/
-                               bytes, len);
-    
-    if (res != kIOReturnSuccess) {
-        SG_LOG(SG_INPUT, SG_WARN, "failed to send feature report" << reportId);
-    }
-
-}
diff --git a/src/Input/FGMacOSXEventInput.hxx b/src/Input/FGMacOSXEventInput.hxx
deleted file mode 100644
index 4dd2ecd4d..000000000
--- a/src/Input/FGMacOSXEventInput.hxx
+++ /dev/null
@@ -1,67 +0,0 @@
-// FGMacOSXEventInput.hxx -- handle event driven input devices for Mac OS X
-//
-// Written by Tatsuhiro Nishioka, started Aug. 2009.
-//
-// Copyright (C) 2009 Tasuhiro Nishioka, tat <dot> fgmacosx <at> gmail <dot> com
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-//
-// $Id$
-
-#ifndef __FGMACOSXEVENTINPUT_HXX_
-#define __FGMACOSXEVENTINPUT_HXX_
-
-#include <string>
-#include <vector>
-#include <map>
-#include <memory>
-
-#include "FGEventInput.hxx"
-
-class FGMacOSXEventInputPrivate;
-
-struct FGMacOSXEventData : public FGEventData {
-    FGMacOSXEventData(std::string name, double value, double dt, int modifiers) :
-        FGEventData(value, dt, modifiers), name(name) {}
-    std::string name;
-};
-
-
-//
-// Mac OS X specific FGEventInput
-//
-class FGMacOSXEventInput : public FGEventInput
-{
-public:
-    FGMacOSXEventInput();
-
-    virtual ~FGMacOSXEventInput();
-
-    // Subsystem API.
-    void init() override;
-    void postinit() override;
-    void shutdown() override;
-    void update(double dt) override;
-
-    // Subsystem identification.
-    static const char* staticSubsystemClassId() { return "input-event"; }
-
-private:
-    friend class FGMacOSXEventInputPrivate;
-
-    std::unique_ptr<FGMacOSXEventInputPrivate> d;
-};
-
-#endif
diff --git a/src/Input/input.cxx b/src/Input/input.cxx
index d13586fbd..9549a9c75 100644
--- a/src/Input/input.cxx
+++ b/src/Input/input.cxx
@@ -38,10 +38,9 @@
 
 #ifdef WITH_EVENTINPUT
   #if defined ( SG_MAC )
-    #include "FGMacOSXEventInput.hxx"
-    #define INPUTEVENT_CLASS FGMacOSXEventInput
+    // we use HID
   #elif defined(SG_WINDOWS)
-
+    // we use HID
   #else
     #include "FGLinuxEventInput.hxx"
     #define INPUTEVENT_CLASS FGLinuxEventInput