Live update of Input preferences device list

- Implement watch_input_devices in input_server, as it was TODO. For
  now, only one watcher is allowed at a time.
- Use it in Input preferences to get notified about added and removed
  devices and update the device list accordingly.

Change-Id: I52018af53738e68271d6d63b5bea31fd7cab1b3b
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2041
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
Adrien Destugues 2019-12-21 10:17:33 +01:00 committed by Adrien Destugues
parent c5e9dd9b68
commit 696d127d12
6 changed files with 120 additions and 36 deletions

View File

@ -35,6 +35,7 @@
#define IS_FIND_DEVICES 'Ifdv'
#define IS_WATCH_DEVICES 'Iwdv'
#define IS_NOTIFY_DEVICE 'Intf'
#define IS_IS_DEVICE_RUNNING 'Idvr'
#define IS_START_DEVICE 'Istd'
#define IS_STOP_DEVICE 'Ispd'

View File

@ -1,9 +1,10 @@
/*
* Copyright 2019, Haiku, Inc.
* Copyright 2019-2020, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Author:
* Authors:
* Preetpal Kaur <preetpalok123@gmail.com>
* Adrien Destugues <pulkomandy@gmail.com>
*/
@ -19,8 +20,8 @@
#include <LayoutBuilder.h>
#include <SplitView.h>
#include <Screen.h>
#include <stdio.h>
#include <private/input/InputServerTypes.h>
#include "InputConstants.h"
#include "InputDeviceView.h"
@ -53,12 +54,10 @@ InputWindow::InputWindow(BRect rect)
void
InputWindow::MessageReceived(BMessage* message)
{
int32 name = message->GetInt32("index", 0);
switch (message->what) {
case ITEM_SELECTED:
{
int32 name = message->GetInt32("index", 0);
fCardView->CardLayout()->SetVisibleItem(name);
}
case kMsgMouseType:
@ -93,12 +92,59 @@ InputWindow::MessageReceived(BMessage* message)
fCardView->CardLayout()->VisibleItem()->View());
break;
}
case IS_NOTIFY_DEVICE:
{
bool added = message->FindBool("added");
BString name = message->FindString("name");
if (added) {
BInputDevice* device = find_input_device(name);
if (device)
AddDevice(device);
} else {
for (int i = 0; i < fDeviceListView->fDeviceList->CountItems();
i++) {
BStringItem* item = dynamic_cast<BStringItem*>(
fDeviceListView->fDeviceList->ItemAt(i));
if (item->Text() == name) {
fDeviceListView->fDeviceList->RemoveItem(i);
BView* settings = fCardView->ChildAt(i);
fCardView->RemoveChild(settings);
delete settings;
break;
}
}
}
break;
}
default:
BWindow::MessageReceived(message);
break;
}
}
void
InputWindow::Show()
{
CenterOnScreen();
BWindow::Show();
status_t x = watch_input_devices(this, true);
puts(strerror(x));
}
void
InputWindow::Hide()
{
BWindow::Hide();
watch_input_devices(this, false);
}
status_t
InputWindow::FindDevice()
{
@ -119,30 +165,33 @@ InputWindow::FindDevice()
}
i++;
BString name = dev->Name();
if (dev->Type() == B_POINTING_DEVICE
&& name.FindFirst("Touchpad") >= 0) {
fTouchPad = dev;
TouchpadPrefView* view = new TouchpadPrefView(dev);
fCardView->AddChild(view);
fDeviceListView->fDeviceList->AddItem(new BStringItem(name));
} else if (dev->Type() == B_POINTING_DEVICE) {
fMouse = dev;
InputMouse* view = new InputMouse(dev);
fCardView->AddChild(view);
fDeviceListView->fDeviceList->AddItem(new BStringItem(name));
} else if (dev->Type() == B_KEYBOARD_DEVICE) {
fKeyboard = dev;
InputKeyboard* view = new InputKeyboard(dev);
fCardView->AddChild(view);
fDeviceListView->fDeviceList->AddItem(new BStringItem(name));
} else {
delete dev;
}
AddDevice(dev);
}
return B_OK;
}
void
InputWindow::AddDevice(BInputDevice* dev)
{
BString name = dev->Name();
if (dev->Type() == B_POINTING_DEVICE
&& name.FindFirst("Touchpad") >= 0) {
TouchpadPrefView* view = new TouchpadPrefView(dev);
fCardView->AddChild(view);
fDeviceListView->fDeviceList->AddItem(new BStringItem(name));
} else if (dev->Type() == B_POINTING_DEVICE) {
InputMouse* view = new InputMouse(dev);
fCardView->AddChild(view);
fDeviceListView->fDeviceList->AddItem(new BStringItem(name));
} else if (dev->Type() == B_KEYBOARD_DEVICE) {
InputKeyboard* view = new InputKeyboard(dev);
fCardView->AddChild(view);
fDeviceListView->fDeviceList->AddItem(new BStringItem(name));
} else {
delete dev;
}
return B_ENTRY_NOT_FOUND;
}

View File

@ -50,16 +50,17 @@ class InputWindow : public BWindow
public:
InputWindow(BRect rect);
void MessageReceived(BMessage* message);
void Show();
void Hide();
status_t FindDevice();
void AddDevice(BInputDevice* device);
private:
DeviceListView* fDeviceListView;
BCardView* fCardView;
MouseSettings fSettings;
SettingsView* fSettingsView;
BInputDevice* fKeyboard;
BInputDevice* fMouse;
BInputDevice* fTouchPad;
};
#endif /* INPUT_WINDOW_H */

View File

@ -17,6 +17,7 @@
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <Autolock.h>
#include <Deskbar.h>
@ -126,6 +127,7 @@ AddOnManager::AddOnManager()
AddOnMonitor(),
fHandler(new(std::nothrow) MonitorHandler(this))
{
openlog("input_server", LOG_PERROR, LOG_USER);
SetHandler(fHandler);
}
@ -153,6 +155,9 @@ AddOnManager::MessageReceived(BMessage* message)
case IS_WATCH_DEVICES:
status = _HandleWatchDevices(message, &reply);
break;
case IS_NOTIFY_DEVICE:
status = _HandleNotifyDevice(message, &reply);
break;
case IS_IS_DEVICE_RUNNING:
status = _HandleIsDeviceRunning(message, &reply);
break;
@ -750,7 +755,22 @@ AddOnManager::_HandleFindDevices(BMessage* message, BMessage* reply)
status_t
AddOnManager::_HandleWatchDevices(BMessage* message, BMessage* reply)
{
// TODO
// TODO handle multiple watchers at the same time
if (message->FindBool("start"))
message->FindMessenger("target", &fWatcherMessenger);
else
fWatcherMessenger = BMessenger();
return B_OK;
}
status_t
AddOnManager::_HandleNotifyDevice(BMessage* message, BMessage* reply)
{
// TODO handle multiple watchers at the same time
status_t result = fWatcherMessenger.SendMessage(message);
syslog(LOG_NOTICE, "Notify of added/removed device (%s)", strerror(result));
return B_OK;
}
@ -871,6 +891,7 @@ AddOnManager::_HandleDeviceMonitor(BMessage* message)
addOn->Device()->Control(NULL, NULL, B_NODE_MONITOR, message);
}
break;
}
}

View File

@ -63,6 +63,8 @@ private:
BMessage* reply);
status_t _HandleWatchDevices(BMessage* message,
BMessage* reply);
status_t _HandleNotifyDevice(BMessage* message,
BMessage* reply);
status_t _HandleIsDeviceRunning(BMessage* message,
BMessage* reply);
status_t _HandleStartStopDevices(BMessage* message,
@ -123,6 +125,7 @@ private:
PathList fDevicePaths;
MonitorHandler* fHandler;
BMessenger fWatcherMessenger;
bool fSafeMode;
};

View File

@ -1156,8 +1156,13 @@ InputServer::UnregisterDevices(BInputServerDevice& serverDevice,
if (item->ServerDevice() == &serverDevice && item->HasName(device->name)) {
item->Stop();
if (fInputDeviceList.RemoveItem(j))
if (fInputDeviceList.RemoveItem(j)) {
BMessage message(IS_NOTIFY_DEVICE);
message.AddBool("added", false);
message.AddString("name", device->name);
fAddOnManager->PostMessage(&message);
delete item;
}
break;
}
}
@ -1215,6 +1220,10 @@ debug_printf("InputServer::RegisterDevices() device_ref already exists: %s\n", d
*device);
if (item != NULL && fInputDeviceList.AddItem(item)) {
item->Start();
BMessage message(IS_NOTIFY_DEVICE);
message.AddBool("added", true);
message.AddString("name", device->name);
fAddOnManager->PostMessage(&message);
} else {
delete item;
return B_NO_MEMORY;