diff --git a/src/kits/device/Jamfile b/src/kits/device/Jamfile index 294dc2d59c..743911d519 100644 --- a/src/kits/device/Jamfile +++ b/src/kits/device/Jamfile @@ -1,5 +1,7 @@ SubDir HAIKU_TOP src kits device ; +SetSubDirSupportedPlatformsBeOSCompatible ; + # for usb_raw.h that defines the ioctl protocol used by the USB classes UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel drivers bus usb ] : true ; diff --git a/src/kits/device/Joystick.cpp b/src/kits/device/Joystick.cpp index 0af036f229..7094154cd1 100644 --- a/src/kits/device/Joystick.cpp +++ b/src/kits/device/Joystick.cpp @@ -1,24 +1,104 @@ -/* - * Copyright 2002, Marcus Overhagen. All rights reserved. +/* + * Copyright 2002-2008, Marcus Overhagen, Stefano Ceccherini, Fredrik Modéen. + * All rights reserved. * Distributed under the terms of the MIT License. */ #include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#define DEVICEPATH "/dev/joystick/" + +typedef struct _joystick_info { + char module_name[64]; + char device_name[64]; + int16 num_axes; + int16 num_buttons; + int16 num_hats; + uint16 num_sticks; +} joystick_info; + +//Scans a directory and adds the entries it founds as strings to the given list +static status_t +scan_directory(const char* rootPath, BList *list, BEntry *rootEntry = NULL) +{ + BDirectory root; + + if (rootEntry != NULL) + root.SetTo( rootEntry); + else if (rootPath != NULL) + root.SetTo(rootPath); + else + return B_ERROR; + + BEntry entry; + + ASSERT(list != NULL); + while ((root.GetNextEntry(&entry)) > B_ERROR ) { + if (entry.IsDirectory()) { + scan_directory(rootPath, list, &entry); + } else { + BPath path; + entry.GetPath(&path); + BString str(path.Path()); + str.RemoveFirst(rootPath); + list->AddItem(strdup(str.String())); + } + } + return B_OK; +} + +class _BJoystickTweaker { + +public: + _BJoystickTweaker(); + _BJoystickTweaker(BJoystick &stick); +virtual ~_BJoystickTweaker(); + +protected: +private: + status_t scan_including_disabled(); + status_t save_config(const entry_ref * ref = NULL); + status_t get_info(); + BJoystick* fJoystick; +}; +//-------------------------------------------------------------------// + BJoystick::BJoystick() + : _mBeBoxMode(false) + , _fDevices(new BList) { + ScanDevices(); } BJoystick::~BJoystick() { + if (ffd >= 0) + close(ffd); + + for (int32 count = _fDevices->CountItems() - 1; count >= 0; count--) + free(_fDevices->RemoveItem(count)); + + delete _fDevices; } status_t BJoystick::Open(const char *portName) { - return B_ERROR; + return Open(portName, true); } @@ -26,13 +106,95 @@ status_t BJoystick::Open(const char *portName, bool enter_enhanced) { - return B_ERROR; + char buf[64]; + + //We don't want to use enhanced mode but _mBeBoxMode sugest if we use + //BeBoxMode + if(!enter_enhanced) + _mBeBoxMode = !enter_enhanced; + + if (portName == NULL) + return B_BAD_VALUE; // Heheee, we won't crash + + if (portName[0] != '/') + snprintf(buf, 64, DEVICEPATH"/%s", portName); + else + // A name like "/dev/joystick/usb/0" was passed + snprintf(buf, 64, "%s", portName); + + if (ffd >= 0) //If this port is already open, close it + close(ffd); + + // TODO: BeOS don't use O_EXCL, and this seems to lead to some issues. I + // added this flag having read some comments by Marco Nelissen on the + // annotated BeBook. I think BeOS uses O_RDWR|O_NONBLOCK here. + ffd = open(buf, O_RDWR | O_NONBLOCK | O_EXCL); + + if (ffd >= 0) { + // we used open() with O_NONBLOCK flag to let it return immediately, + // but we want read/write operations to block if needed, so we clear + // that bit here. + int flags = fcntl(ffd, F_GETFL); + fcntl(ffd, F_SETFL, flags & ~O_NONBLOCK); + + //DriverControl(); + } + // TODO: I wonder why the return type is a status_t, + // since we (as BeOS does) return the descriptor number for the device... + return (ffd >= 0) ? ffd : errno; } void BJoystick::Close(void) { + if (ffd >= 0) + close(ffd); + ffd = -1; +} + + +void +BJoystick::ScanDevices(bool use_disabled = false) +{ + // First, we empty the list + for (int32 count = _fDevices->CountItems() - 1; count >= 0; count--) + free(_fDevices->RemoveItem(count)); + + // Add devices to the list + scan_directory(DEVICEPATH, _fDevices); +} + + +int32 +BJoystick::CountDevices() +{ + int32 count = 0; + + // Refresh devices list + ScanDevices(); + + if (_fDevices != NULL) + count = _fDevices->CountItems(); + + return count; +} + + +status_t +BJoystick::GetDeviceName(int32 n, char *name, size_t bufSize) +{ + status_t result = B_ERROR; + const char *dev = NULL; + if (_fDevices != NULL) + dev = static_cast(_fDevices->ItemAt(n)); + + if (dev != NULL && name != NULL) { + strncpy(name, dev, bufSize); + name[bufSize - 1] = '\0'; + result = B_OK; + } + return result; } @@ -50,26 +212,11 @@ BJoystick::SetMaxLatency(bigtime_t max_latency) } -int32 -BJoystick::CountDevices() -{ - return 0; -} - - -status_t -BJoystick::GetDeviceName(int32 n, - char *name, - size_t bufSize) -{ - return B_ERROR; -} - - bool BJoystick::EnterEnhancedMode(const entry_ref *ref) { - return false; + _mBeBoxMode = false; + return !_mBeBoxMode; } @@ -196,42 +343,50 @@ BJoystick::save_config(const entry_ref *ref) } -void -BJoystick::_ReservedJoystick1() +/* These functions are here to maintain Binary Compatibility */ +void BJoystick::_ReservedJoystick1() {} +void BJoystick::_ReservedJoystick2() {} +void BJoystick::_ReservedJoystick3() {} +status_t BJoystick::_Reserved_Joystick_4(void *, ...) {return B_ERROR;} +status_t BJoystick::_Reserved_Joystick_5(void *, ...) {return B_ERROR;} +status_t BJoystick::_Reserved_Joystick_6(void *, ...) {return B_ERROR;} + + +//-------------------------------------------------------------------// + + +_BJoystickTweaker::_BJoystickTweaker() { } -void -BJoystick::_ReservedJoystick2() +_BJoystickTweaker::_BJoystickTweaker(BJoystick &stick) { + fJoystick = &stick; } -void -BJoystick::_ReservedJoystick3() +_BJoystickTweaker::~_BJoystickTweaker() { } status_t -BJoystick::_Reserved_Joystick_4(void *, ...) +_BJoystickTweaker::save_config(const entry_ref *ref) { return B_ERROR; } status_t -BJoystick::_Reserved_Joystick_5(void *, ...) +_BJoystickTweaker::scan_including_disabled() { return B_ERROR; } status_t -BJoystick::_Reserved_Joystick_6(void *, ...) +_BJoystickTweaker::get_info() { return B_ERROR; } - -