* Cleanup and refactoring, made several Mouse-/Keyboard-/TouchpadDevice

functions private and moved them accordingly in the file.
* I forgot to initialize the BObjectList to own the items in
  TouchpadInputDevice.
* Changed the methods that read and apply settings in all three addons to be
  executed from the control threads only, which fixes race conditions.
* The success of opening a device is no longer checked in the Start() method
  of the *Devices. Instead, the control thread checks the device before it
  enters the polling loop and cleans up if there was an error. This fixes
  non-running devices in the input_server because the PS/2 driver publishes
  devices which is has not checked yet for other reasons. It is important,
  however, to open() the devices in the Start() hook and not the control
  thread, otherwise there are unwanted race conditions in case node monitoring
  events are received more than once for the same device. That's the case
  for some reason on one of my computers for the AT 0 keyboard.

TODO:
* Combine the Touchpad and Mouse device addon into one, it's almost the
  same code except the Touchpad knows more settings and one more control
  message.
* Refactor a common base class for Keyboard and Mouse device addon.
* Fix the mouse speed/acceleration. If the speed is lowered from the default
  in the preflet, the mouse becomes almost unusable. To fix this, the same
  trick should be used as I used in the touchpad kernel driver, which is to
  sum up previous mouse moved fractional offsets.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28590 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2008-11-10 11:16:02 +00:00
parent 577fe1f9a1
commit 5125eae25d
6 changed files with 657 additions and 429 deletions

View File

@ -26,16 +26,60 @@
#include "kb_mouse_driver.h"
//#define TRACE_KEYBOARD_DEVICE
#undef TRACE
#define TRACE_KEYBOARD_DEVICE
#ifdef TRACE_KEYBOARD_DEVICE
# define LOG(text...) debug_printf(text)
# define LOG_ERR(text...) LOG(text)
#else
# define LOG(text...) do {} while (0)
# define LOG_ERR(text...) debug_printf(text)
#endif
#define CALLED() LOG("%s\n", __PRETTY_FUNCTION__)
class FunctionTracer {
public:
FunctionTracer(const void* pointer, const char* className,
const char* functionName,
int32& depth)
: fFunctionName(),
fPrepend(),
fFunctionDepth(depth),
fPointer(pointer)
{
fFunctionDepth++;
fPrepend.Append(' ', fFunctionDepth * 2);
fFunctionName << className << "::" << functionName << "()";
debug_printf("%p -> %s%s {\n", fPointer, fPrepend.String(),
fFunctionName.String());
}
~FunctionTracer()
{
debug_printf("%p -> %s}\n", fPointer, fPrepend.String());
fFunctionDepth--;
}
private:
BString fFunctionName;
BString fPrepend;
int32& fFunctionDepth;
const void* fPointer;
};
static int32 sFunctionDepth = -1;
# define KD_CALLED(x...) FunctionTracer _ft(this, "KeyboardDevice", \
__FUNCTION__, sFunctionDepth)
# define KID_CALLED(x...) FunctionTracer _ft(this, "KeyboardInputDevice", \
__FUNCTION__, sFunctionDepth)
# define TRACE(x...) { BString _to; \
_to.Append(' ', (sFunctionDepth + 1) * 2); \
debug_printf("%p -> %s", this, _to.String()); \
debug_printf(x); }
# define LOG_EVENT(text...) do {} while (0)
# define LOG_ERR(text...) TRACE(text)
#else
# define TRACE(x...) do {} while (0)
# define KD_CALLED(x...) TRACE(x)
# define KID_CALLED(x...) TRACE(x)
# define LOG_ERR(text...) debug_printf(text)
# define LOG_EVENT(text...) TRACE(x)
#endif
const static uint32 kKeyboardThreadPriority = B_FIRST_REAL_TIME_PRIORITY + 4;
@ -346,7 +390,6 @@ instantiate_input_device()
static char*
get_short_name(const char* longName)
{
CALLED();
BString string(longName);
BString name;
@ -379,8 +422,12 @@ KeyboardDevice::KeyboardDevice(KeyboardInputDevice* owner, const char* path)
fThread(-1),
fActive(false),
fInputMethodStarted(false),
fUpdateSettings(false),
fSettingsCommand(0),
fKeymapLock("keymap lock")
{
KD_CALLED();
strcpy(fPath, path);
fDeviceRef.name = get_short_name(path);
fDeviceRef.type = B_KEYBOARD_DEVICE;
@ -397,6 +444,9 @@ KeyboardDevice::KeyboardDevice(KeyboardInputDevice* owner, const char* path)
KeyboardDevice::~KeyboardDevice()
{
KD_CALLED();
TRACE("delete\n");
if (fActive)
Stop();
@ -409,37 +459,11 @@ KeyboardDevice::~KeyboardDevice()
}
status_t
KeyboardDevice::EnqueueInlineInputMethod(int32 opcode,
const char* string, bool confirmed, BMessage* keyDown)
{
BMessage* message = new BMessage(B_INPUT_METHOD_EVENT);
if (message == NULL)
return B_NO_MEMORY;
message->AddInt32("be:opcode", opcode);
message->AddBool("be:inline_only", true);
if (string != NULL)
message->AddString("be:string", string);
if (confirmed)
message->AddBool("be:confirmed", true);
if (keyDown)
message->AddMessage("be:translated", keyDown);
if (opcode == B_INPUT_METHOD_STARTED)
message->AddMessenger("be:reply_to", this);
status_t status = fOwner->EnqueueMessage(message);
if (status != B_OK)
delete message;
return status;
}
void
KeyboardDevice::MessageReceived(BMessage* message)
{
KD_CALLED();
if (message->what != B_INPUT_METHOD_EVENT) {
BHandler::MessageReceived(message);
return;
@ -457,22 +481,21 @@ KeyboardDevice::MessageReceived(BMessage* message)
status_t
KeyboardDevice::Start()
{
if ((fFD = open(fPath, O_RDWR)) < B_OK) {
fprintf(stderr, "error when opening %s: %s\n", fPath, strerror(errno));
return B_ERROR;
}
KD_CALLED();
TRACE("name: %s\n", fDeviceRef.name);
InitFromSettings();
fFD = open(fPath, O_RDWR);
// let the control thread handle any error on opening the device
char threadName[B_OS_NAME_LENGTH];
snprintf(threadName, B_OS_NAME_LENGTH, "%s watcher", fDeviceRef.name);
fActive = true;
fThread = spawn_thread(_ThreadEntry, threadName,
fThread = spawn_thread(_ControlThreadEntry, threadName,
kKeyboardThreadPriority, this);
if (fThread < B_OK)
return fThread;
fActive = true;
resume_thread(fThread);
return B_OK;
}
@ -480,6 +503,9 @@ KeyboardDevice::Start()
void
KeyboardDevice::Stop()
{
KD_CALLED();
TRACE("name: %s\n", fDeviceRef.name);
fActive = false;
close(fFD);
@ -495,70 +521,48 @@ KeyboardDevice::Stop()
status_t
KeyboardDevice::InitFromSettings(uint32 opcode)
KeyboardDevice::UpdateSettings(uint32 opcode)
{
CALLED();
KD_CALLED();
if (opcode == 0 || opcode == B_KEY_REPEAT_RATE_CHANGED) {
if (get_key_repeat_rate(&fSettings.key_repeat_rate) != B_OK)
LOG_ERR("error when get_key_repeat_rate\n");
else if (ioctl(fFD, KB_SET_KEY_REPEAT_RATE,
&fSettings.key_repeat_rate) != B_OK)
LOG_ERR("error when KB_SET_KEY_REPEAT_RATE, fd:%d\n", fFD);
}
if (fThread < 0)
return B_ERROR;
if (opcode == 0 || opcode == B_KEY_REPEAT_DELAY_CHANGED) {
if (get_key_repeat_delay(&fSettings.key_repeat_delay) != B_OK)
LOG_ERR("error when get_key_repeat_delay\n");
else if (ioctl(fFD, KB_SET_KEY_REPEAT_DELAY,
&fSettings.key_repeat_delay) != B_OK)
LOG_ERR("error when KB_SET_KEY_REPEAT_DELAY, fd:%d\n", fFD);
}
if (opcode == 0 || opcode == B_KEY_MAP_CHANGED
|| opcode == B_KEY_LOCKS_CHANGED) {
BAutolock lock(fKeymapLock);
fKeymap.LoadCurrent();
fModifiers = fKeymap.Locks();
UpdateLEDs();
}
// schedule updating the settings from within the control thread
fSettingsCommand = opcode;
fUpdateSettings = true;
return B_OK;
}
void
KeyboardDevice::UpdateLEDs()
{
if (fFD < 0)
return;
uint32 locks = fModifiers;
char lockIO[3];
memset(lockIO, 0, sizeof(lockIO));
if (locks & B_NUM_LOCK)
lockIO[0] = 1;
if (locks & B_CAPS_LOCK)
lockIO[1] = 1;
if (locks & B_SCROLL_LOCK)
lockIO[2] = 1;
ioctl(fFD, KB_SET_LEDS, &lockIO);
}
// #pragma mark - control thread
/*static*/ int32
KeyboardDevice::_ThreadEntry(void* arg)
KeyboardDevice::_ControlThreadEntry(void* arg)
{
KeyboardDevice* device = (KeyboardDevice*)arg;
return device->_Thread();
return device->_ControlThread();
}
int32
KeyboardDevice::_Thread()
KeyboardDevice::_ControlThread()
{
CALLED();
KD_CALLED();
TRACE("fPath: %s\n", fPath);
if (fFD < B_OK) {
LOG_ERR("KeyboardDevice: error when opening %s: %s\n",
fPath, strerror(errno));
_ControlThreadCleanup();
// TOAST!
return B_ERROR;
}
_UpdateSettings(0);
uint8 buffer[16];
uint8 activeDeadKey = 0;
uint32 lastKeyCode = 0;
@ -568,29 +572,24 @@ KeyboardDevice::_Thread()
memset(states, 0, sizeof(states));
LOG("%s\n", __PRETTY_FUNCTION__);
while (fActive) {
if (ioctl(fFD, KB_READ, &buffer) != B_OK) {
if (fActive) {
fThread = -1;
fOwner->_RemoveDevice(fPath);
} else {
// In case fActive is already false, another thread
// waits for this thread to quit, and may already hold
// locks that _RemoveDevice() wants to acquire. In another
// words, the device is already being removed, so we simply
// quit here.
}
_ControlThreadCleanup();
// TOAST!
return 0;
}
// Update the settings from this thread if necessary
if (fUpdateSettings) {
_UpdateSettings(fSettingsCommand);
fUpdateSettings = false;
}
uint32 keycode = 0;
bool isKeyDown = false;
bigtime_t timestamp = 0;
LOG("KB_READ :");
LOG_EVENT("KB_READ :");
if (fIsAT) {
at_kbd_io* atKeyboard = (at_kbd_io*)buffer;
@ -598,7 +597,7 @@ KeyboardDevice::_Thread()
keycode = kATKeycodeMap[atKeyboard->scancode - 1];
isKeyDown = atKeyboard->is_keydown;
timestamp = atKeyboard->timestamp;
LOG(" %02x", atKeyboard->scancode);
LOG_EVENT(" %02x", atKeyboard->scancode);
} else {
raw_key_info* rawKeyInfo= (raw_key_info*)buffer;
isKeyDown = rawKeyInfo->is_keydown;
@ -609,7 +608,7 @@ KeyboardDevice::_Thread()
if (keycode == 0)
continue;
LOG(" %Ld, %02x, %02lx\n", timestamp, isKeyDown, keycode);
LOG_EVENT(" %Ld, %02x, %02lx\n", timestamp, isKeyDown, keycode);
if (isKeyDown && keycode == 0x68) {
// MENU KEY for Tracker
@ -638,7 +637,7 @@ KeyboardDevice::_Thread()
if (isKeyDown && keycode == 0x34 // DELETE KEY
&& (states[0x5c >> 3] & (1 << (7 - (0x5c & 0x7))))
&& (states[0x5d >> 3] & (1 << (7 - (0x5d & 0x7))))) {
LOG("TeamMonitor called\n");
LOG_EVENT("TeamMonitor called\n");
// show the team monitor
if (fOwner->fTeamMonitorWindow == NULL)
@ -686,7 +685,7 @@ KeyboardDevice::_Thread()
delete msg;
if (modifiers & (B_CAPS_LOCK | B_NUM_LOCK | B_SCROLL_LOCK))
UpdateLEDs();
_UpdateLEDs();
}
uint8 newDeadKey = 0;
@ -745,25 +744,25 @@ KeyboardDevice::_Thread()
if (isKeyDown && !modifiers && activeDeadKey != 0
&& fInputMethodStarted) {
// a dead key was completed
EnqueueInlineInputMethod(B_INPUT_METHOD_CHANGED,
_EnqueueInlineInputMethod(B_INPUT_METHOD_CHANGED,
string, true, msg);
} else if (fOwner->EnqueueMessage(msg) != B_OK)
delete msg;
} else if (isKeyDown) {
// start of a dead key
if (EnqueueInlineInputMethod(B_INPUT_METHOD_STARTED) == B_OK) {
if (_EnqueueInlineInputMethod(B_INPUT_METHOD_STARTED) == B_OK) {
char* string = NULL;
int32 numBytes = 0;
fKeymap.GetChars(keycode, fModifiers, 0, &string, &numBytes);
if (EnqueueInlineInputMethod(B_INPUT_METHOD_CHANGED, string) == B_OK)
if (_EnqueueInlineInputMethod(B_INPUT_METHOD_CHANGED, string) == B_OK)
fInputMethodStarted = true;
}
}
if (!isKeyDown && !modifiers) {
if (activeDeadKey != 0) {
EnqueueInlineInputMethod(B_INPUT_METHOD_STOPPED);
_EnqueueInlineInputMethod(B_INPUT_METHOD_STOPPED);
fInputMethodStarted = false;
}
@ -777,15 +776,116 @@ KeyboardDevice::_Thread()
}
void
KeyboardDevice::_ControlThreadCleanup()
{
// NOTE: Only executed when the control thread detected an error
// and from within the control thread!
if (fActive) {
fThread = -1;
fOwner->_RemoveDevice(fPath);
} else {
// In case active is already false, another thread
// waits for this thread to quit, and may already hold
// locks that _RemoveDevice() wants to acquire. In another
// words, the device is already being removed, so we simply
// quit here.
}
}
void
KeyboardDevice::_UpdateSettings(uint32 opcode)
{
KD_CALLED();
if (opcode == 0 || opcode == B_KEY_REPEAT_RATE_CHANGED) {
if (get_key_repeat_rate(&fSettings.key_repeat_rate) != B_OK) {
LOG_ERR("error when get_key_repeat_rate\n");
} else if (ioctl(fFD, KB_SET_KEY_REPEAT_RATE,
&fSettings.key_repeat_rate) != B_OK) {
LOG_ERR("error when KB_SET_KEY_REPEAT_RATE, fd:%d\n", fFD);
}
}
if (opcode == 0 || opcode == B_KEY_REPEAT_DELAY_CHANGED) {
if (get_key_repeat_delay(&fSettings.key_repeat_delay) != B_OK) {
LOG_ERR("error when get_key_repeat_delay\n");
} else if (ioctl(fFD, KB_SET_KEY_REPEAT_DELAY,
&fSettings.key_repeat_delay) != B_OK) {
LOG_ERR("error when KB_SET_KEY_REPEAT_DELAY, fd:%d\n", fFD);
}
}
if (opcode == 0 || opcode == B_KEY_MAP_CHANGED
|| opcode == B_KEY_LOCKS_CHANGED) {
BAutolock lock(fKeymapLock);
fKeymap.LoadCurrent();
fModifiers = fKeymap.Locks();
_UpdateLEDs();
}
}
void
KeyboardDevice::_UpdateLEDs()
{
if (fFD < 0)
return;
uint32 locks = fModifiers;
char lockIO[3];
memset(lockIO, 0, sizeof(lockIO));
if (locks & B_NUM_LOCK)
lockIO[0] = 1;
if (locks & B_CAPS_LOCK)
lockIO[1] = 1;
if (locks & B_SCROLL_LOCK)
lockIO[2] = 1;
ioctl(fFD, KB_SET_LEDS, &lockIO);
}
status_t
KeyboardDevice::_EnqueueInlineInputMethod(int32 opcode,
const char* string, bool confirmed, BMessage* keyDown)
{
BMessage* message = new BMessage(B_INPUT_METHOD_EVENT);
if (message == NULL)
return B_NO_MEMORY;
message->AddInt32("be:opcode", opcode);
message->AddBool("be:inline_only", true);
if (string != NULL)
message->AddString("be:string", string);
if (confirmed)
message->AddBool("be:confirmed", true);
if (keyDown)
message->AddMessage("be:translated", keyDown);
if (opcode == B_INPUT_METHOD_STARTED)
message->AddMessenger("be:reply_to", this);
status_t status = fOwner->EnqueueMessage(message);
if (status != B_OK)
delete message;
return status;
}
// #pragma mark -
KeyboardInputDevice::KeyboardInputDevice()
:
fDevices(2, true),
fDeviceListLock("KeyboardInputDevice list"),
fTeamMonitorWindow(NULL)
{
CALLED();
KID_CALLED();
StartMonitoringDevice(kKeyboardDevicesDirectory);
_RecursiveScan(kKeyboardDevicesDirectory);
@ -794,7 +894,7 @@ KeyboardInputDevice::KeyboardInputDevice()
KeyboardInputDevice::~KeyboardInputDevice()
{
CALLED();
KID_CALLED();
if (fTeamMonitorWindow) {
fTeamMonitorWindow->PostMessage(B_QUIT_REQUESTED);
@ -809,7 +909,7 @@ KeyboardInputDevice::~KeyboardInputDevice()
status_t
KeyboardInputDevice::SystemShuttingDown()
{
CALLED();
KID_CALLED();
if (fTeamMonitorWindow)
fTeamMonitorWindow->PostMessage(SYSTEM_SHUTTING_DOWN);
@ -820,7 +920,7 @@ KeyboardInputDevice::SystemShuttingDown()
status_t
KeyboardInputDevice::InitCheck()
{
CALLED();
KID_CALLED();
return BInputServerDevice::InitCheck();
}
@ -828,7 +928,9 @@ KeyboardInputDevice::InitCheck()
status_t
KeyboardInputDevice::Start(const char* name, void* cookie)
{
CALLED();
KID_CALLED();
TRACE("name %s\n", name);
KeyboardDevice* device = (KeyboardDevice*)cookie;
return device->Start();
@ -838,10 +940,10 @@ KeyboardInputDevice::Start(const char* name, void* cookie)
status_t
KeyboardInputDevice::Stop(const char* name, void* cookie)
{
CALLED();
KeyboardDevice* device = (KeyboardDevice*)cookie;
KID_CALLED();
TRACE("name %s\n", name);
LOG("Stop(%s)\n", name);
KeyboardDevice* device = (KeyboardDevice*)cookie;
device->Stop();
return B_OK;
@ -852,15 +954,15 @@ status_t
KeyboardInputDevice::Control(const char* name, void* cookie,
uint32 command, BMessage* message)
{
CALLED();
LOG("Control(%s, code: %lu)\n", name, command);
KID_CALLED();
TRACE("KeyboardInputDevice::Control(%s, code: %lu)\n", name, command);
if (command == B_NODE_MONITOR)
_HandleMonitor(message);
else if (command >= B_KEY_MAP_CHANGED
&& command <= B_KEY_REPEAT_RATE_CHANGED) {
KeyboardDevice* device = (KeyboardDevice*)cookie;
device->InitFromSettings(command);
device->UpdateSettings(command);
}
return B_OK;
}
@ -869,7 +971,7 @@ KeyboardInputDevice::Control(const char* name, void* cookie,
status_t
KeyboardInputDevice::_HandleMonitor(BMessage* message)
{
CALLED();
KID_CALLED();
const char* path;
int32 opcode;
@ -906,7 +1008,10 @@ KeyboardInputDevice::_FindDevice(const char* path) const
status_t
KeyboardInputDevice::_AddDevice(const char* path)
{
CALLED();
KID_CALLED();
TRACE("path: %s\n", path);
BAutolock _(fDeviceListLock);
_RemoveDevice(path);
@ -927,12 +1032,15 @@ KeyboardInputDevice::_AddDevice(const char* path)
status_t
KeyboardInputDevice::_RemoveDevice(const char* path)
{
CALLED();
BAutolock _(fDeviceListLock);
KeyboardDevice* device = _FindDevice(path);
if (device == NULL)
return B_ENTRY_NOT_FOUND;
KID_CALLED();
TRACE("path: %s\n", path);
input_device_ref* devices[2];
devices[0] = device->DeviceRef();
devices[1] = NULL;
@ -948,7 +1056,9 @@ KeyboardInputDevice::_RemoveDevice(const char* path)
void
KeyboardInputDevice::_RecursiveScan(const char* directory)
{
CALLED();
KID_CALLED();
TRACE("directory: %s\n", directory);
BEntry entry;
BDirectory dir(directory);
while (dir.GetNextEntry(&entry) == B_OK) {

View File

@ -10,7 +10,6 @@
#include <Handler.h>
#include <InputServerDevice.h>
#include <Locker.h>
#include <List.h>
#include <InputServerTypes.h>
#include <ObjectList.h>
@ -29,23 +28,24 @@ public:
virtual ~KeyboardDevice();
virtual void MessageReceived(BMessage* message);
status_t EnqueueInlineInputMethod(int32 opcode,
const char* string = NULL,
bool confirmed = false,
BMessage* keyDown = NULL);
status_t Start();
void Stop();
status_t InitFromSettings(uint32 opcode = 0);
void UpdateLEDs();
status_t UpdateSettings(uint32 opcode = 0);
const char* Path() const { return fPath; }
input_device_ref* DeviceRef() { return &fDeviceRef; }
private:
static int32 _ThreadEntry(void* arg);
int32 _Thread();
static int32 _ControlThreadEntry(void* arg);
int32 _ControlThread();
void _ControlThreadCleanup();
void _UpdateSettings(uint32 opcode);
void _UpdateLEDs();
status_t _EnqueueInlineInputMethod(int32 opcode,
const char* string = NULL,
bool confirmed = false,
BMessage* keyDown = NULL);
private:
KeyboardInputDevice* fOwner;
@ -59,6 +59,9 @@ private:
volatile bool fInputMethodStarted;
uint32 fModifiers;
volatile bool fUpdateSettings;
volatile uint32 fSettingsCommand;
Keymap fKeymap;
BLocker fKeymapLock;
};
@ -92,6 +95,7 @@ private:
status_t _RemoveDevice(const char* path);
BObjectList<KeyboardDevice> fDevices;
BLocker fDeviceListLock;
TeamMonitorWindow* fTeamMonitorWindow;
};

View File

@ -18,6 +18,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <Autolock.h>
#include <Debug.h>
#include <Directory.h>
#include <Entry.h>
@ -31,7 +32,6 @@
#undef TRACE
#undef CALLED
//#define TRACE_MOUSE_DEVICE
#ifdef TRACE_MOUSE_DEVICE
@ -76,64 +76,63 @@
_to.Append(' ', (sFunctionDepth + 1) * 2); \
debug_printf("%p -> %s", this, _to.String()); \
debug_printf(x); }
# define LOG(text...) debug_printf(text)
# define LOG_EVENT(text...) do {} while (0)
# define LOG_ERR(text...) LOG(text)
# define LOG_ERR(text...) TRACE(text)
#else
# define TRACE(x...) do {} while (0)
# define MD_CALLED(x...) TRACE(x)
# define MID_CALLED(x...) TRACE(x)
# define LOG(text...) TRACE(x)
# define LOG_ERR(text...) debug_printf(text)
# define LOG_EVENT(text...) TRACE(x)
#endif
//#define LOG_DEVICES(text...) debug_printf(text)
#define LOG_DEVICES(text...) LOG(text)
const static uint32 kMouseThreadPriority = B_FIRST_REAL_TIME_PRIORITY + 4;
const static char* kMouseDevicesDirectory = "/dev/input/mouse";
class MouseDevice {
public:
MouseDevice(MouseInputDevice& target, const char* path);
~MouseDevice();
public:
MouseDevice(MouseInputDevice& target,
const char* path);
~MouseDevice();
status_t Start();
void Stop();
status_t Start();
void Stop();
status_t UpdateSettings();
status_t UpdateSettings();
const char* Path() const { return fPath.String(); }
input_device_ref* DeviceRef() { return &fDeviceRef; }
const char* Path() const { return fPath.String(); }
input_device_ref* DeviceRef() { return &fDeviceRef; }
private:
void _Run();
static status_t _ThreadFunction(void* arg);
private:
char* _BuildShortName() const;
BMessage* _BuildMouseMessage(uint32 what, uint64 when, uint32 buttons,
int32 deltaX, int32 deltaY) const;
void _ComputeAcceleration(const mouse_movement& movements,
int32& deltaX, int32& deltaY) const;
uint32 _RemapButtons(uint32 buttons) const;
static status_t _ControlThreadEntry(void* arg);
void _ControlThread();
void _ControlThreadCleanup();
void _UpdateSettings();
char* _BuildShortName() const;
BMessage* _BuildMouseMessage(uint32 what,
uint64 when, uint32 buttons,
int32 deltaX, int32 deltaY) const;
void _ComputeAcceleration(
const mouse_movement& movements,
int32& deltaX, int32& deltaY) const;
uint32 _RemapButtons(uint32 buttons) const;
private:
MouseInputDevice& fTarget;
BString fPath;
int fDevice;
private:
MouseInputDevice& fTarget;
BString fPath;
int fDevice;
input_device_ref fDeviceRef;
mouse_settings fSettings;
bool fDeviceRemapsButtons;
input_device_ref fDeviceRef;
mouse_settings fSettings;
bool fDeviceRemapsButtons;
thread_id fThread;
volatile bool fActive;
thread_id fThread;
volatile bool fActive;
volatile bool fUpdateSettings;
};
@ -154,7 +153,8 @@ MouseDevice::MouseDevice(MouseInputDevice& target, const char* driverPath)
fDevice(-1),
fDeviceRemapsButtons(false),
fThread(-1),
fActive(false)
fActive(false),
fUpdateSettings(false)
{
MD_CALLED();
@ -175,9 +175,6 @@ MouseDevice::~MouseDevice()
MD_CALLED();
TRACE("delete\n");
if (fTarget._HasDevice(this))
TRACE("still in the list!\n");
if (fActive)
Stop();
@ -191,15 +188,12 @@ MouseDevice::Start()
MD_CALLED();
fDevice = open(fPath.String(), O_RDWR);
if (fDevice < 0)
return errno;
UpdateSettings();
// let the control thread handle any error on opening the device
char threadName[B_OS_NAME_LENGTH];
snprintf(threadName, B_OS_NAME_LENGTH, "%s watcher", fDeviceRef.name);
fThread = spawn_thread(_ThreadFunction, threadName,
fThread = spawn_thread(_ControlThreadEntry, threadName,
kMouseThreadPriority, (void*)this);
status_t status;
@ -213,7 +207,6 @@ MouseDevice::Start()
if (status < B_OK) {
LOG_ERR("%s: can't spawn/resume watching thread: %s\n",
fDeviceRef.name, strerror(status));
close(fDevice);
return status;
}
@ -248,45 +241,63 @@ MouseDevice::UpdateSettings()
{
MD_CALLED();
// retrieve current values
if (fThread < 0)
return B_ERROR;
if (get_mouse_map(&fSettings.map) != B_OK)
LOG_ERR("error when get_mouse_map\n");
else
fDeviceRemapsButtons = ioctl(fDevice, MS_SET_MAP, &fSettings.map) == B_OK;
if (get_click_speed(&fSettings.click_speed) != B_OK)
LOG_ERR("error when get_click_speed\n");
else
ioctl(fDevice, MS_SET_CLICKSPEED, &fSettings.click_speed);
if (get_mouse_speed(&fSettings.accel.speed) != B_OK)
LOG_ERR("error when get_mouse_speed\n");
else {
if (get_mouse_acceleration(&fSettings.accel.accel_factor) != B_OK)
LOG_ERR("error when get_mouse_acceleration\n");
else {
mouse_accel accel;
ioctl(fDevice, MS_GET_ACCEL, &accel);
accel.speed = fSettings.accel.speed;
accel.accel_factor = fSettings.accel.accel_factor;
ioctl(fDevice, MS_SET_ACCEL, &fSettings.accel);
}
}
if (get_mouse_type(&fSettings.type) != B_OK)
LOG_ERR("error when get_mouse_type\n");
else
ioctl(fDevice, MS_SET_TYPE, &fSettings.type);
fUpdateSettings = true;
// This will provoke the control thread to update the settings.
return B_OK;
}
char*
MouseDevice::_BuildShortName() const
{
BString string(fPath);
BString name;
int32 slash = string.FindLast("/");
string.CopyInto(name, slash + 1, string.Length() - slash);
int32 index = atoi(name.String()) + 1;
int32 previousSlash = string.FindLast("/", slash);
string.CopyInto(name, previousSlash + 1, slash - previousSlash - 1);
if (name == "ps2")
name = "PS/2";
else
name.Capitalize();
name << " Mouse " << index;
return strdup(name.String());
}
// #pragma mark - control thread
status_t
MouseDevice::_ControlThreadEntry(void* arg)
{
MouseDevice* device = (MouseDevice*)arg;
device->_ControlThread();
return B_OK;
}
void
MouseDevice::_Run()
MouseDevice::_ControlThread()
{
if (fDevice < 0) {
_ControlThreadCleanup();
// TOAST!
return;
}
_UpdateSettings();
uint32 lastButtons = 0;
while (fActive) {
@ -294,20 +305,17 @@ MouseDevice::_Run()
memset(&movements, 0, sizeof(movements));
if (ioctl(fDevice, MS_READ, &movements) != B_OK) {
if (fActive) {
fThread = -1;
fTarget._RemoveDevice(fPath.String());
} else {
// In case active is already false, another thread
// waits for this thread to quit, and may already hold
// locks that _RemoveDevice() wants to acquire. In another
// words, the device is already being removed, so we simply
// quit here.
}
_ControlThreadCleanup();
// TOAST!
return;
}
// take care of updating the settings first, if necessary
if (fUpdateSettings) {
_UpdateSettings();
fUpdateSettings = false;
}
uint32 buttons = lastButtons ^ movements.buttons;
uint32 remappedButtons = _RemapButtons(movements.buttons);
@ -361,12 +369,62 @@ MouseDevice::_Run()
}
status_t
MouseDevice::_ThreadFunction(void* arg)
void
MouseDevice::_ControlThreadCleanup()
{
MouseDevice* device = (MouseDevice*)arg;
device->_Run();
return B_OK;
// NOTE: Only executed when the control thread detected an error
// and from within the control thread!
if (fActive) {
fThread = -1;
fTarget._RemoveDevice(fPath.String());
} else {
// In case active is already false, another thread
// waits for this thread to quit, and may already hold
// locks that _RemoveDevice() wants to acquire. In another
// words, the device is already being removed, so we simply
// quit here.
}
}
void
MouseDevice::_UpdateSettings()
{
MD_CALLED();
// retrieve current values
if (get_mouse_map(&fSettings.map) != B_OK)
LOG_ERR("error when get_mouse_map\n");
else {
fDeviceRemapsButtons
= ioctl(fDevice, MS_SET_MAP, &fSettings.map) == B_OK;
}
if (get_click_speed(&fSettings.click_speed) != B_OK)
LOG_ERR("error when get_click_speed\n");
else
ioctl(fDevice, MS_SET_CLICKSPEED, &fSettings.click_speed);
if (get_mouse_speed(&fSettings.accel.speed) != B_OK)
LOG_ERR("error when get_mouse_speed\n");
else {
if (get_mouse_acceleration(&fSettings.accel.accel_factor) != B_OK)
LOG_ERR("error when get_mouse_acceleration\n");
else {
mouse_accel accel;
ioctl(fDevice, MS_GET_ACCEL, &accel);
accel.speed = fSettings.accel.speed;
accel.accel_factor = fSettings.accel.accel_factor;
ioctl(fDevice, MS_SET_ACCEL, &fSettings.accel);
}
}
if (get_mouse_type(&fSettings.type) != B_OK)
LOG_ERR("error when get_mouse_type\n");
else
ioctl(fDevice, MS_SET_TYPE, &fSettings.type);
}
@ -445,36 +503,13 @@ MouseDevice::_RemapButtons(uint32 buttons) const
}
char*
MouseDevice::_BuildShortName() const
{
BString string(fPath);
BString name;
int32 slash = string.FindLast("/");
string.CopyInto(name, slash + 1, string.Length() - slash);
int32 index = atoi(name.String()) + 1;
int32 previousSlash = string.FindLast("/", slash);
string.CopyInto(name, previousSlash + 1, slash - previousSlash - 1);
if (name == "ps2")
name = "PS/2";
else
name.Capitalize();
name << " Mouse " << index;
return strdup(name.String());
}
// #pragma mark -
MouseInputDevice::MouseInputDevice()
:
fDevices(2, true)
fDevices(2, true),
fDeviceListLock("MouseInputDevice list")
{
MID_CALLED();
@ -592,7 +627,7 @@ MouseInputDevice::_RecursiveScan(const char* directory)
MouseDevice*
MouseInputDevice::_FindDevice(const char* path)
MouseInputDevice::_FindDevice(const char* path) const
{
MID_CALLED();
@ -611,6 +646,8 @@ MouseInputDevice::_AddDevice(const char* path)
{
MID_CALLED();
BAutolock _(fDeviceListLock);
_RemoveDevice(path);
MouseDevice* device = new(std::nothrow) MouseDevice(*this, path);
@ -640,6 +677,8 @@ MouseInputDevice::_RemoveDevice(const char* path)
{
MID_CALLED();
BAutolock _(fDeviceListLock);
MouseDevice* device = _FindDevice(path);
if (device == NULL) {
TRACE("%s not found\n", path);
@ -660,14 +699,4 @@ MouseInputDevice::_RemoveDevice(const char* path)
}
bool
MouseInputDevice::_HasDevice(const MouseDevice* device) const
{
for (int32 i = fDevices.CountItems() - 1; i >= 0; i--) {
if (device == fDevices.ItemAt(i))
return true;
}
return false;
}

View File

@ -11,6 +11,7 @@
#include <InputServerDevice.h>
#include <InterfaceDefs.h>
#include <Locker.h>
#include <ObjectList.h>
@ -38,14 +39,13 @@ private:
status_t _HandleMonitor(BMessage* message);
void _RecursiveScan(const char* directory);
MouseDevice* _FindDevice(const char* path);
MouseDevice* _FindDevice(const char* path) const;
status_t _AddDevice(const char* path);
status_t _RemoveDevice(const char* path);
bool _HasDevice(const MouseDevice* device) const;
private:
BObjectList<MouseDevice> fDevices;
BLocker fDeviceListLock;
};
extern "C" BInputServerDevice* instantiate_input_device();

View File

@ -15,6 +15,7 @@
#include "kb_mouse_settings.h"
#include "touchpad_settings.h"
#include <Autolock.h>
#include <Debug.h>
#include <Directory.h>
#include <Entry.h>
@ -49,50 +50,57 @@ const static char* kTouchpadDevicesDirectoryPS2 = "/dev/input/touchpad/ps2";
class TouchpadDevice {
public:
TouchpadDevice(TouchpadInputDevice& target, const char* path);
~TouchpadDevice();
public:
TouchpadDevice(TouchpadInputDevice& target,
const char* path);
~TouchpadDevice();
status_t Start();
void Stop();
status_t Start();
void Stop();
status_t UpdateSettings();
status_t UpdateSettings();
status_t UpdateTouchpadSettings(const BMessage* message);
const char* Path() const { return fPath.String(); }
input_device_ref* DeviceRef() { return &fDeviceRef; }
const char* Path() const { return fPath.String(); }
input_device_ref* DeviceRef() { return &fDeviceRef; }
bool IsTouchpad() { return fIsTouchpad; }
status_t ReadTouchpadSettingsMsg(BMessage* msg);
status_t UpdateTouchpadSettings();
private:
char* _BuildShortName() const;
private:
void _Run();
static status_t _ThreadFunction(void *arg);
static status_t _ControlThreadEntry(void *arg);
void _ControlThread();
void _ControlThreadCleanup();
void _UpdateSettings();
BMessage* _BuildMouseMessage(uint32 what, uint64 when, uint32 buttons,
int32 deltaX, int32 deltaY) const;
void _ComputeAcceleration(const mouse_movement& movements,
int32& deltaX, int32& deltaY) const;
uint32 _RemapButtons(uint32 buttons) const;
status_t _GetSettingsPath(BPath &path);
status_t _ReadTouchpadSettingsMsg(BMessage* message);
status_t _UpdateTouchpadSettings();
char* _BuildShortName() const;
BMessage* _BuildMouseMessage(uint32 what,
uint64 when, uint32 buttons,
int32 deltaX, int32 deltaY) const;
void _ComputeAcceleration(
const mouse_movement& movements,
int32& deltaX, int32& deltaY) const;
uint32 _RemapButtons(uint32 buttons) const;
status_t _GetSettingsPath(BPath &path);
private:
TouchpadInputDevice& fTarget;
BString fPath;
int fDevice;
private:
TouchpadInputDevice& fTarget;
BString fPath;
int fDevice;
input_device_ref fDeviceRef;
mouse_settings fSettings;
bool fDeviceRemapsButtons;
input_device_ref fDeviceRef;
mouse_settings fSettings;
bool fDeviceRemapsButtons;
thread_id fThread;
volatile bool fActive;
volatile bool fUpdateSettings;
thread_id fThread;
volatile bool fActive;
bool fIsTouchpad;
touchpad_settings fTouchpadSettings;
bool fIsTouchpad;
touchpad_settings fTouchpadSettings;
BMessage* fTouchpadSettingsMessage;
BLocker fTouchpadSettingsLock;
};
@ -114,7 +122,10 @@ TouchpadDevice::TouchpadDevice(TouchpadInputDevice& target,
fDeviceRemapsButtons(false),
fThread(-1),
fActive(false),
fIsTouchpad(false)
fUpdateSettings(false),
fIsTouchpad(false),
fTouchpadSettingsMessage(NULL),
fTouchpadSettingsLock("Touchpad settings lock")
{
fPath = driverPath;
@ -137,16 +148,8 @@ TouchpadDevice::~TouchpadDevice()
Stop();
free(fDeviceRef.name);
}
status_t
TouchpadDevice::_GetSettingsPath(BPath &path)
{
status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
if (status < B_OK)
return status;
return path.Append(TOUCHPAD_SETTINGS_FILE);
delete fTouchpadSettingsMessage;
}
@ -154,36 +157,15 @@ status_t
TouchpadDevice::Start()
{
fDevice = open(fPath.String(), O_RDWR);
if (fDevice < 0)
return errno;
// touchpad settings
if (ioctl(fDevice, MS_IS_TOUCHPAD, NULL) == B_OK) {
LOG("is touchpad %s\n", fPath.String());
fIsTouchpad = true;
}
fTouchpadSettings = kDefaultTouchpadSettings;
BPath path;
status_t status = _GetSettingsPath(path);
BFile settingsFile(path.Path(), B_READ_ONLY);
if (status == B_OK && settingsFile.InitCheck() == B_OK) {
if (settingsFile.Read(&fTouchpadSettings, sizeof(touchpad_settings))
!= sizeof(touchpad_settings)) {
LOG("failed to load settings\n");
}
}
UpdateTouchpadSettings();
UpdateSettings();
// let the control thread handle any error on opening the device
char threadName[B_OS_NAME_LENGTH];
snprintf(threadName, B_OS_NAME_LENGTH, "%s watcher", fDeviceRef.name);
fThread = spawn_thread(_ThreadFunction, threadName,
fThread = spawn_thread(_ControlThreadEntry, threadName,
kMouseThreadPriority, (void*)this);
status_t status;
if (fThread < B_OK)
status = fThread;
else {
@ -225,83 +207,97 @@ TouchpadDevice::Stop()
status_t
TouchpadDevice::UpdateSettings()
{
// TODO: This is duplicated in MouseInputDevice.cpp -> Refactor
if (fThread < 0)
return B_ERROR;
CALLED();
// retrieve current values
if (get_mouse_map(&fSettings.map) != B_OK)
LOG_ERR("error when get_mouse_map\n");
else
fDeviceRemapsButtons = ioctl(fDevice, MS_SET_MAP, &fSettings.map) == B_OK;
if (get_click_speed(&fSettings.click_speed) != B_OK)
LOG_ERR("error when get_click_speed\n");
else
ioctl(fDevice, MS_SET_CLICKSPEED, &fSettings.click_speed);
if (get_mouse_speed(&fSettings.accel.speed) != B_OK)
LOG_ERR("error when get_mouse_speed\n");
else {
if (get_mouse_acceleration(&fSettings.accel.accel_factor) != B_OK)
LOG_ERR("error when get_mouse_acceleration\n");
else {
mouse_accel accel;
ioctl(fDevice, MS_GET_ACCEL, &accel);
accel.speed = fSettings.accel.speed;
accel.accel_factor = fSettings.accel.accel_factor;
ioctl(fDevice, MS_SET_ACCEL, &fSettings.accel);
}
}
if (get_mouse_type(&fSettings.type) != B_OK)
LOG_ERR("error when get_mouse_type\n");
else
ioctl(fDevice, MS_SET_TYPE, &fSettings.type);
// trigger updating the settings in the control thread
fUpdateSettings = true;
return B_OK;
}
status_t
TouchpadDevice::ReadTouchpadSettingsMsg(BMessage* msg)
TouchpadDevice::UpdateTouchpadSettings(const BMessage* message)
{
msg->FindBool("scroll_twofinger",
&(fTouchpadSettings.scroll_twofinger));
msg->FindBool("scroll_multifinger",
&(fTouchpadSettings.scroll_multifinger));
msg->FindFloat("scroll_rightrange",
&(fTouchpadSettings.scroll_rightrange));
msg->FindFloat("scroll_bottomrange",
&(fTouchpadSettings.scroll_bottomrange));
msg->FindInt16("scroll_xstepsize",
(int16*)&(fTouchpadSettings.scroll_xstepsize));
msg->FindInt16("scroll_ystepsize",
(int16*)&(fTouchpadSettings.scroll_ystepsize));
msg->FindInt8("scroll_acceleration",
(int8*)&(fTouchpadSettings.scroll_acceleration));
msg->FindInt8("tapgesture_sensibility",
(int8*)&(fTouchpadSettings.tapgesture_sensibility));
if (fThread < 0)
return B_ERROR;
BAutolock _(fTouchpadSettingsLock);
// trigger updating the settings in the control thread
fUpdateSettings = true;
delete fTouchpadSettingsMessage;
fTouchpadSettingsMessage = new BMessage(*message);
return B_OK;
}
status_t
TouchpadDevice::UpdateTouchpadSettings()
char *
TouchpadDevice::_BuildShortName() const
{
if (fIsTouchpad) {
ioctl(fDevice, MS_SET_TOUCHPAD_SETTINGS, &fTouchpadSettings);
return B_OK;
}
return B_ERROR;
BString string(fPath);
BString name;
int32 slash = string.FindLast("/");
string.CopyInto(name, slash + 1, string.Length() - slash);
//int32 index = atoi(name.String()) + 1;
BString final = "Touchpad ";
final += name;
LOG("NAME %s, %s\n", final.String(), fPath.String());
return strdup(final.String());
}
// #pragma mark - control thread
status_t
TouchpadDevice::_ControlThreadEntry(void* arg)
{
TouchpadDevice* device = (TouchpadDevice*)arg;
device->_ControlThread();
return B_OK;
}
void
TouchpadDevice::_Run()
TouchpadDevice::_ControlThread()
{
if (fDevice < 0) {
_ControlThreadCleanup();
// TOAST!
return;
}
// touchpad settings
if (ioctl(fDevice, MS_IS_TOUCHPAD, NULL) == B_OK) {
LOG("is touchpad %s\n", fPath.String());
fIsTouchpad = true;
}
fTouchpadSettings = kDefaultTouchpadSettings;
{
BPath path;
status_t status = _GetSettingsPath(path);
BFile settingsFile(path.Path(), B_READ_ONLY);
if (status == B_OK && settingsFile.InitCheck() == B_OK) {
if (settingsFile.Read(&fTouchpadSettings, sizeof(touchpad_settings))
!= sizeof(touchpad_settings)) {
LOG("failed to load settings\n");
}
}
}
_UpdateTouchpadSettings();
_UpdateSettings();
// TODO: Exact duplicate of MouseDevice::_Run() -> Refactor
uint32 lastButtons = 0;
@ -310,20 +306,24 @@ TouchpadDevice::_Run()
memset(&movements, 0, sizeof(movements));
if (ioctl(fDevice, MS_READ, &movements) != B_OK) {
if (fActive) {
fThread = -1;
fTarget._RemoveDevice(fPath.String());
} else {
// In case active is already false, another thread
// waits for this thread to quit, and may already hold
// locks that _RemoveDevice() wants to acquire. In another
// words, the device is already being removed, so we simply
// quit here.
}
_ControlThreadCleanup();
// TOAST!
return;
}
// update the settings if necessary
if (fUpdateSettings) {
fUpdateSettings = false;
BAutolock _(fTouchpadSettingsLock);
if (fTouchpadSettingsMessage) {
_ReadTouchpadSettingsMsg(fTouchpadSettingsMessage);
_UpdateTouchpadSettings();
delete fTouchpadSettingsMessage;
fTouchpadSettingsMessage = NULL;
} else
_UpdateSettings();
}
uint32 buttons = lastButtons ^ movements.buttons;
uint32 remappedButtons = _RemapButtons(movements.buttons);
@ -377,15 +377,110 @@ TouchpadDevice::_Run()
}
status_t
TouchpadDevice::_ThreadFunction(void* arg)
void
TouchpadDevice::_ControlThreadCleanup()
{
TouchpadDevice* device = (TouchpadDevice*)arg;
device->_Run();
// NOTE: Only executed when the control thread detected an error
// and from within the control thread!
if (fActive) {
fThread = -1;
fTarget._RemoveDevice(fPath.String());
} else {
// In case active is already false, another thread
// waits for this thread to quit, and may already hold
// locks that _RemoveDevice() wants to acquire. In another
// words, the device is already being removed, so we simply
// quit here.
}
}
void
TouchpadDevice::_UpdateSettings()
{
// TODO: This is duplicated in MouseInputDevice.cpp -> Refactor
CALLED();
// retrieve current values
if (get_mouse_map(&fSettings.map) != B_OK)
LOG_ERR("error when get_mouse_map\n");
else
fDeviceRemapsButtons = ioctl(fDevice, MS_SET_MAP, &fSettings.map) == B_OK;
if (get_click_speed(&fSettings.click_speed) != B_OK)
LOG_ERR("error when get_click_speed\n");
else
ioctl(fDevice, MS_SET_CLICKSPEED, &fSettings.click_speed);
if (get_mouse_speed(&fSettings.accel.speed) != B_OK)
LOG_ERR("error when get_mouse_speed\n");
else {
if (get_mouse_acceleration(&fSettings.accel.accel_factor) != B_OK)
LOG_ERR("error when get_mouse_acceleration\n");
else {
mouse_accel accel;
ioctl(fDevice, MS_GET_ACCEL, &accel);
accel.speed = fSettings.accel.speed;
accel.accel_factor = fSettings.accel.accel_factor;
ioctl(fDevice, MS_SET_ACCEL, &fSettings.accel);
}
}
if (get_mouse_type(&fSettings.type) != B_OK)
LOG_ERR("error when get_mouse_type\n");
else
ioctl(fDevice, MS_SET_TYPE, &fSettings.type);
}
status_t
TouchpadDevice::_GetSettingsPath(BPath &path)
{
status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
if (status < B_OK)
return status;
return path.Append(TOUCHPAD_SETTINGS_FILE);
}
status_t
TouchpadDevice::_ReadTouchpadSettingsMsg(BMessage* message)
{
message->FindBool("scroll_twofinger",
&(fTouchpadSettings.scroll_twofinger));
message->FindBool("scroll_multifinger",
&(fTouchpadSettings.scroll_multifinger));
message->FindFloat("scroll_rightrange",
&(fTouchpadSettings.scroll_rightrange));
message->FindFloat("scroll_bottomrange",
&(fTouchpadSettings.scroll_bottomrange));
message->FindInt16("scroll_xstepsize",
(int16*)&(fTouchpadSettings.scroll_xstepsize));
message->FindInt16("scroll_ystepsize",
(int16*)&(fTouchpadSettings.scroll_ystepsize));
message->FindInt8("scroll_acceleration",
(int8*)&(fTouchpadSettings.scroll_acceleration));
message->FindInt8("tapgesture_sensibility",
(int8*)&(fTouchpadSettings.tapgesture_sensibility));
return B_OK;
}
status_t
TouchpadDevice::_UpdateTouchpadSettings()
{
if (fIsTouchpad) {
ioctl(fDevice, MS_SET_TOUCHPAD_SETTINGS, &fTouchpadSettings);
return B_OK;
}
return B_ERROR;
}
BMessage*
TouchpadDevice::_BuildMouseMessage(uint32 what, uint64 when, uint32 buttons,
int32 deltaX, int32 deltaY) const
@ -467,29 +562,13 @@ TouchpadDevice::_RemapButtons(uint32 buttons) const
}
char *
TouchpadDevice::_BuildShortName() const
{
BString string(fPath);
BString name;
int32 slash = string.FindLast("/");
string.CopyInto(name, slash + 1, string.Length() - slash);
//int32 index = atoi(name.String()) + 1;
BString final = "Touchpad ";
final += name;
LOG("NAME %s, %s\n", final.String(), fPath.String());
return strdup(final.String());
}
// #pragma mark -
TouchpadInputDevice::TouchpadInputDevice()
:
fDevices(2, true),
fDeviceListLock("TouchpadInputDevice list")
{
CALLED();
@ -545,10 +624,8 @@ TouchpadInputDevice::Control(const char* name, void* cookie,
if (command == B_NODE_MONITOR)
return _HandleMonitor(message);
if (command == MS_SET_TOUCHPAD_SETTINGS) {
device->ReadTouchpadSettingsMsg(message);
return device->UpdateTouchpadSettings();
}
if (command == MS_SET_TOUCHPAD_SETTINGS)
return device->UpdateTouchpadSettings(message);
if (command >= B_MOUSE_TYPE_CHANGED
&& command <= B_MOUSE_ACCELERATION_CHANGED)
@ -602,7 +679,7 @@ TouchpadInputDevice::_RecursiveScan(const char* directory)
TouchpadDevice*
TouchpadInputDevice::_FindDevice(const char *path)
TouchpadInputDevice::_FindDevice(const char *path) const
{
CALLED();
@ -621,6 +698,10 @@ TouchpadInputDevice::_AddDevice(const char *path)
{
CALLED();
BAutolock _(fDeviceListLock);
_RemoveDevice(path);
TouchpadDevice* device = new (std::nothrow) TouchpadDevice(*this, path);
if (!device) {
LOG("No memory\n");
@ -647,6 +728,8 @@ TouchpadInputDevice::_RemoveDevice(const char *path)
{
CALLED();
BAutolock _(fDeviceListLock);
TouchpadDevice* device = _FindDevice(path);
if (device == NULL)
return B_ENTRY_NOT_FOUND;

View File

@ -12,6 +12,7 @@
#include <InputServerDevice.h>
#include <InterfaceDefs.h>
#include <Locker.h>
#include <ObjectList.h>
@ -41,11 +42,12 @@ public:
status_t _HandleMonitor(BMessage* message);
void _RecursiveScan(const char* directory);
TouchpadDevice* _FindDevice(const char* path);
TouchpadDevice* _FindDevice(const char* path) const;
status_t _AddDevice(const char* path);
status_t _RemoveDevice(const char* path);
BObjectList<TouchpadDevice> fDevices;
BLocker fDeviceListLock;
};
extern "C" BInputServerDevice* instantiate_input_device();