Mouse Preferences: store settings for multiple mouses.

Use a BMessage for the mouse settings. Store an array of mouse_setting
and an array of names for the corresponding mouses.

The input preferences can load the settings in both the old and new
format. If in the old format, the settings are applied to all mouses.

In this commit, input_server is not modified yet to use the new settings
format, leading to unusable mouse.

Change-Id: I37dd27cfa3ac55c6956cc4fb7fc8fabc85a59448
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2953
Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
Preetpal Kaur
2020-09-10 17:15:09 +00:00
committed by Adrien Destugues
parent 8f5c207181
commit 82430c4028
6 changed files with 294 additions and 118 deletions
+33 -37
View File
@@ -36,21 +36,17 @@
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "InputMouse"
static const bigtime_t kDefaultClickSpeed = 500000;
static const int32 kDefaultMouseSpeed = 65536;
static const int32 kDefaultMouseType = 3; // 3 button mouse
static const int32 kDefaultAccelerationFactor = 65536;
static const bool kDefaultAcceptFirstClick = true;
InputMouse::InputMouse(BInputDevice* dev)
InputMouse::InputMouse(BInputDevice* dev, MouseSettings* settings)
: BView("InputMouse", B_WILL_DRAW)
{
fSettingsView = new SettingsView(fSettings);
fSettings = settings;
fSettingsView = new SettingsView(*fSettings);
fDefaultsButton = new BButton(B_TRANSLATE("Defaults"),
new BMessage(kMsgDefaults));
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
fRevertButton = new BButton(B_TRANSLATE("Revert"),
new BMessage(kMsgRevert));
@@ -76,19 +72,19 @@ InputMouse::MessageReceived(BMessage* message)
{
switch (message->what) {
case kMsgDefaults: {
fSettings.Defaults();
fSettings->Defaults();
fSettingsView->UpdateFromSettings();
fDefaultsButton->SetEnabled(false);
fRevertButton->SetEnabled(fSettings.IsRevertable());
fRevertButton->SetEnabled(fSettings->IsRevertable());
break;
}
case kMsgRevert: {
fSettings.Revert();
fSettings->Revert();
fSettingsView->UpdateFromSettings();
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
fRevertButton->SetEnabled(false);
break;
@@ -98,10 +94,10 @@ InputMouse::MessageReceived(BMessage* message)
{
int32 type;
if (message->FindInt32("be:value", &type) == B_OK) {
fSettings.SetMouseType(type);
fSettings->SetMouseType(type);
fSettingsView->SetMouseType(type);
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(fSettings.IsRevertable());
fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
fRevertButton->SetEnabled(fSettings->IsRevertable());
}
break;
}
@@ -110,9 +106,9 @@ InputMouse::MessageReceived(BMessage* message)
{
int32 mode;
if (message->FindInt32("mode", &mode) == B_OK) {
fSettings.SetMouseMode((mode_mouse)mode);
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(fSettings.IsRevertable());
fSettings->SetMouseMode((mode_mouse)mode);
fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
fRevertButton->SetEnabled(fSettings->IsRevertable());
fSettingsView->fFocusFollowsMouseMenu->SetEnabled(
mode == B_FOCUS_FOLLOWS_MOUSE);
fSettingsView->fAcceptFirstClickBox->SetEnabled(
@@ -126,10 +122,10 @@ InputMouse::MessageReceived(BMessage* message)
int32 mode;
if (message->FindInt32("mode_focus_follows_mouse", &mode)
== B_OK) {
fSettings.SetFocusFollowsMouseMode(
fSettings->SetFocusFollowsMouseMode(
(mode_focus_follows_mouse)mode);
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(fSettings.IsRevertable());
fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
fRevertButton->SetEnabled(fSettings->IsRevertable());
}
break;
}
@@ -145,9 +141,9 @@ InputMouse::MessageReceived(BMessage* message)
if (acceptFirstClickBox)
acceptFirstClick = acceptFirstClickBox->Value()
== B_CONTROL_ON;
fSettings.SetAcceptFirstClick(acceptFirstClick);
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(fSettings.IsRevertable());
fSettings->SetAcceptFirstClick(acceptFirstClick);
fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
fRevertButton->SetEnabled(fSettings->IsRevertable());
}
break;
}
@@ -157,9 +153,9 @@ InputMouse::MessageReceived(BMessage* message)
int32 value;
if (message->FindInt32("be:value", &value) == B_OK) {
// slow = 1000000, fast = 0
fSettings.SetClickSpeed(value * 1000);
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(fSettings.IsRevertable());
fSettings->SetClickSpeed(value * 1000);
fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
fRevertButton->SetEnabled(fSettings->IsRevertable());
}
break;
}
@@ -169,10 +165,10 @@ InputMouse::MessageReceived(BMessage* message)
int32 value;
if (message->FindInt32("be:value", &value) == B_OK) {
// slow = 8192, fast = 524287
fSettings.SetMouseSpeed((int32)pow(2,
fSettings->SetMouseSpeed((int32)pow(2,
value * 6.0 / 1000) * 8192);
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(fSettings.IsRevertable());
fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
fRevertButton->SetEnabled(fSettings->IsRevertable());
}
break;
}
@@ -182,10 +178,10 @@ InputMouse::MessageReceived(BMessage* message)
int32 value;
if (message->FindInt32("be:value", &value) == B_OK) {
// slow = 0, fast = 262144
fSettings.SetAccelerationFactor((int32)pow(
fSettings->SetAccelerationFactor((int32)pow(
value * 4.0 / 1000, 2) * 16384);
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(fSettings.IsRevertable());
fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
fRevertButton->SetEnabled(fSettings->IsRevertable());
}
break;
}
@@ -197,9 +193,9 @@ InputMouse::MessageReceived(BMessage* message)
if (message->FindInt32("index", &index) == B_OK
&& message->FindInt32("button", &button) == B_OK) {
int32 mapping = B_MOUSE_BUTTON(index + 1);
fSettings.SetMapping(button, mapping);
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
fRevertButton->SetEnabled(fSettings.IsRevertable());
fSettings->SetMapping(button, mapping);
fDefaultsButton->SetEnabled(fSettings->IsDefaultable());
fRevertButton->SetEnabled(fSettings->IsRevertable());
fSettingsView->MouseMapUpdated();
}
break;
+3 -5
View File
@@ -34,7 +34,7 @@ class DeviceListView;
class InputMouse : public BView {
public:
InputMouse(BInputDevice* dev);
InputMouse(BInputDevice* dev, MouseSettings* settings);
virtual ~InputMouse();
void SetMouseType(int32 type);
void MessageReceived(BMessage* message);
@@ -46,9 +46,7 @@ private:
MouseView* fMouseView;
BButton* fDefaultsButton;
BButton* fRevertButton;
MouseSettings fSettings;
mouse_settings fMouseSettings, fOriginalSettings;
MouseSettings* fSettings;
};
#endif /* INPUT_MOUSE_H */
#endif /* INPUT_MOUSE_H */
+7 -2
View File
@@ -185,21 +185,26 @@ InputWindow::AddDevice(BInputDevice* dev)
if (dev->Type() == B_POINTING_DEVICE
&& name.FindFirst("Touchpad") >= 0) {
TouchpadPrefView* view = new TouchpadPrefView(dev);
fCardView->AddChild(view);
DeviceListItemView* touchpad = new DeviceListItemView(
name, TOUCHPAD_TYPE);
fDeviceListView->AddItem(touchpad);
} else if (dev->Type() == B_POINTING_DEVICE) {
InputMouse* view = new InputMouse(dev);
MouseSettings* settings;
settings = fMultipleMouseSettings.AddMouseSettings(name);
InputMouse* view = new InputMouse(dev, settings);
fCardView->AddChild(view);
DeviceListItemView* mouse = new DeviceListItemView(
name, MOUSE_TYPE);
fDeviceListView->AddItem(mouse);
} else if (dev->Type() == B_KEYBOARD_DEVICE) {
InputKeyboard* view = new InputKeyboard(dev);
fCardView->AddChild(view);
DeviceListItemView* keyboard = new DeviceListItemView(
name, KEYBOARD_TYPE);
fDeviceListView->AddItem(keyboard);
+4 -1
View File
@@ -40,6 +40,7 @@ class DeviceName;
class InputDevices;
class InputKeyboard;
class InputMouse;
class MultipleMouseSettings;
class TouchpadPrefView;
class TouchpadPref;
class TouchpadView;
@@ -56,10 +57,12 @@ public:
private:
status_t FindDevice();
void AddDevice(BInputDevice* device);
private:
private:
BListView* fDeviceListView;
BCardView* fCardView;
MultipleMouseSettings fMultipleMouseSettings;
};
#endif /* INPUT_WINDOW_H */
+209 -66
View File
@@ -30,8 +30,6 @@ static const bool kDefaultAcceptFirstClick = true;
MouseSettings::MouseSettings()
:
fWindowPosition(-1, -1)
{
_RetrieveSettings();
@@ -42,9 +40,23 @@ MouseSettings::MouseSettings()
}
MouseSettings::MouseSettings(mouse_settings settings)
:
fSettings(settings)
{
#ifdef DEBUG
Dump();
#endif
fOriginalSettings = fSettings;
fOriginalMode = fMode;
fOriginalFocusFollowsMouseMode = fFocusFollowsMouseMode;
fOriginalAcceptFirstClick = fAcceptFirstClick;
}
MouseSettings::~MouseSettings()
{
_SaveSettings();
}
@@ -90,56 +102,12 @@ MouseSettings::_RetrieveSettings()
if (file.InitCheck() < B_OK)
return;
#if R5_COMPATIBLE
const off_t kOffset = sizeof(mouse_settings) - sizeof(mouse_map)
+ sizeof(int32) * 3;
// we have to do this because mouse_map counts 16 buttons in OBOS
#else
const off_t kOffset = sizeof(mouse_settings);
#endif
if (file.ReadAt(kOffset, &fWindowPosition, sizeof(BPoint))
!= sizeof(BPoint)) {
// set default window position (invalid positions will be
// corrected by the application; the window will be centered
// in this case)
fWindowPosition.x = -1;
fWindowPosition.y = -1;
}
#ifdef DEBUG
Dump();
#endif
}
status_t
MouseSettings::_SaveSettings()
{
BPath path;
status_t status = _GetSettingsPath(path);
if (status < B_OK)
return status;
BFile file(path.Path(), B_READ_WRITE | B_CREATE_FILE);
status = file.InitCheck();
if (status < B_OK)
return status;
#if R5_COMPATIBLE
const off_t kOffset = sizeof(mouse_settings) - sizeof(mouse_map)
+ sizeof(int32) * 3;
// we have to do this because mouse_map counts 16 buttons in OBOS
#else
const off_t kOffset = sizeof(mouse_settings);
#endif
file.WriteAt(kOffset, &fWindowPosition, sizeof(BPoint));
return B_OK;
}
#ifdef DEBUG
void
MouseSettings::Dump()
@@ -267,20 +235,11 @@ MouseSettings::IsRevertable()
}
void
MouseSettings::SetWindowPosition(BPoint corner)
{
fWindowPosition = corner;
}
void
MouseSettings::SetMouseType(int32 type)
{
if (set_mouse_type(type) == B_OK)
fSettings.type = type;
else
fprintf(stderr, "error when set_mouse_type\n");
}
@@ -299,8 +258,6 @@ MouseSettings::SetClickSpeed(bigtime_t clickSpeed)
if (set_click_speed(clickSpeed) == B_OK)
fSettings.click_speed = clickSpeed;
else
fprintf(stderr, "error when set_click_speed\n");
}
@@ -309,8 +266,6 @@ MouseSettings::SetMouseSpeed(int32 speed)
{
if (set_mouse_speed(speed) == B_OK)
fSettings.accel.speed = speed;
else
fprintf(stderr, "error when set_mouse_speed\n");
}
@@ -319,8 +274,6 @@ MouseSettings::SetAccelerationFactor(int32 factor)
{
if (set_mouse_acceleration(factor) == B_OK)
fSettings.accel.accel_factor = factor;
else
fprintf(stderr, "error when set_mouse_acceleration\n");
}
@@ -342,8 +295,7 @@ void
MouseSettings::SetMapping(int32 index, uint32 button)
{
fSettings.map.button[index] = button;
if (set_mouse_map(&fSettings.map) != B_OK)
fprintf(stderr, "error when set_mouse_map\n");
set_mouse_map(&fSettings.map);
}
@@ -352,8 +304,6 @@ MouseSettings::SetMapping(mouse_map &map)
{
if (set_mouse_map(&map) == B_OK)
fSettings.map = map;
else
fprintf(stderr, "error when set_mouse_map\n");
}
@@ -379,3 +329,196 @@ MouseSettings::SetAcceptFirstClick(bool accept_first_click)
set_accept_first_click(accept_first_click);
fAcceptFirstClick = accept_first_click;
}
mouse_settings*
MouseSettings::GetSettings() {
return &fSettings;
}
MultipleMouseSettings::MultipleMouseSettings()
{
fDeprecatedMouseSettings = NULL;
RetrieveSettings();
#ifdef DEBUG
Dump();
#endif
}
MultipleMouseSettings::~MultipleMouseSettings()
{
SaveSettings();
#ifdef DEBUG
Dump();
#endif
std::map<BString, MouseSettings*>::iterator itr;
for (itr = fMouseSettingsObject.begin(); itr != fMouseSettingsObject.end();
++itr)
delete itr->second;
delete fDeprecatedMouseSettings;
}
status_t
MultipleMouseSettings::GetSettingsPath(BPath &path)
{
status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
if (status < B_OK)
return status;
path.Append(mouse_settings_file);
return B_OK;
}
void
MultipleMouseSettings::RetrieveSettings()
{
// retrieve current values
// also try to load the window position from disk
BPath path;
if (GetSettingsPath(path) < B_OK)
return;
BFile file(path.Path(), B_READ_ONLY);
if (file.InitCheck() < B_OK)
return;
BMessage message;
if (message.Unflatten(&file) == B_OK) {
int i = 0;
BString deviceName;
mouse_settings* settings;
ssize_t size = 0;
while (message.FindString("mouseDevice", i, &deviceName) == B_OK) {
message.FindData("mouseSettings", B_ANY_TYPE, i,
(const void**)&settings, &size);
MouseSettings* mouseSettings = new MouseSettings(*settings);
fMouseSettingsObject.insert(std::pair<BString, MouseSettings*>
(deviceName, mouseSettings));
i++;
}
} else {
// Does not look like a BMessage, try loading using the old format
fDeprecatedMouseSettings = new MouseSettings();
fDeprecatedMouseSettings->_RetrieveSettings();
}
}
status_t
MultipleMouseSettings::Archive(BMessage* into, bool deep) const
{
std::map<BString, MouseSettings*>::const_iterator itr;
for (itr = fMouseSettingsObject.begin(); itr != fMouseSettingsObject.end();
++itr) {
into->AddString("mouseDevice", itr->first);
into->AddData("mouseSettings", B_ANY_TYPE, itr->second->GetSettings(),
sizeof(*(itr->second->GetSettings())));
}
return B_OK;
}
status_t
MultipleMouseSettings::SaveSettings()
{
BPath path;
status_t status = GetSettingsPath(path);
if (status < B_OK)
return status;
BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
status = file.InitCheck();
if (status != B_OK)
return status;
BMessage message;
Archive(&message, true);
message.Flatten(&file);
return B_OK;
}
void
MultipleMouseSettings::Defaults()
{
std::map<BString, MouseSettings*>::iterator itr;
for (itr = fMouseSettingsObject.begin(); itr != fMouseSettingsObject.end();
++itr) {
itr->second->Defaults();
}
}
#ifdef DEBUG
void
MultipleMouseSettings::Dump()
{
std::map<BString, MouseSettings*>::iterator itr;
for (itr = fMouseSettingsObject.begin(); itr != fMouseSettingsObject.end();
++itr) {
printf("mouse_name:\t%s\n", itr->first.String());
itr->second->Dump();
printf("\n");
}
}
#endif
MouseSettings*
MultipleMouseSettings::AddMouseSettings(BString mouse_name)
{
if(fDeprecatedMouseSettings != NULL) {
MouseSettings* RetrievedSettings = new (std::nothrow) MouseSettings
(*fDeprecatedMouseSettings);
if (RetrievedSettings != NULL) {
fMouseSettingsObject.insert(std::pair<BString, MouseSettings*>
(mouse_name, RetrievedSettings));
return RetrievedSettings;
}
}
std::map<BString, MouseSettings*>::iterator itr;
itr = fMouseSettingsObject.find(mouse_name);
if (itr != fMouseSettingsObject.end())
return GetMouseSettings(mouse_name);
MouseSettings* settings = new (std::nothrow) MouseSettings();
if(settings !=NULL) {
fMouseSettingsObject.insert(std::pair<BString, MouseSettings*>
(mouse_name, settings));
return settings;
}
return B_OK;
}
MouseSettings*
MultipleMouseSettings::GetMouseSettings(BString mouse_name)
{
std::map<BString, MouseSettings*>::iterator itr;
itr = fMouseSettingsObject.find(mouse_name);
if (itr != fMouseSettingsObject.end())
return itr->second;
return NULL;
}
+38 -7
View File
@@ -11,6 +11,9 @@
#define MOUSE_SETTINGS_H
#include <map>
#include <Archivable.h>
#include <Input.h>
#include <InterfaceDefs.h>
#include <Point.h>
@@ -24,6 +27,7 @@ class BPath;
class MouseSettings {
public:
MouseSettings();
MouseSettings(mouse_settings settings);
~MouseSettings();
void Revert();
@@ -32,9 +36,6 @@ public:
bool IsDefaultable();
void Dump();
BPoint WindowPosition() const { return fWindowPosition; }
void SetWindowPosition(BPoint corner);
int32 MouseType() const { return fSettings.type; }
void SetMouseType(int32 type);
@@ -62,18 +63,48 @@ public:
bool AcceptFirstClick() const { return fAcceptFirstClick; }
void SetAcceptFirstClick(bool accept_first_click);
void _RetrieveSettings();
mouse_settings* GetSettings();
private:
static status_t _GetSettingsPath(BPath &path);
void _RetrieveSettings();
status_t _SaveSettings();
mouse_settings fSettings, fOriginalSettings;
mode_mouse fMode, fOriginalMode;
mode_focus_follows_mouse fFocusFollowsMouseMode;
mode_focus_follows_mouse fOriginalFocusFollowsMouseMode;
bool fAcceptFirstClick, fOriginalAcceptFirstClick;
BPoint fWindowPosition;
mouse_settings fSettings, fOriginalSettings;
};
class MultipleMouseSettings: public BArchivable
{
public:
MultipleMouseSettings();
~MultipleMouseSettings();
status_t Archive(BMessage* into, bool deep = false) const;
void Defaults();
void Dump();
status_t SaveSettings();
/** Get or create settings for the given mouse */
MouseSettings* AddMouseSettings(BString mouse_name);
/** Get the existing settings, or return NULL */
MouseSettings* GetMouseSettings(BString mouse_name);
private:
static status_t GetSettingsPath(BPath &path);
void RetrieveSettings();
private:
MouseSettings* fDeprecatedMouseSettings;
typedef std::map<BString, MouseSettings*> mouse_settings_object;
mouse_settings_object fMouseSettingsObject;
};
#endif // MOUSE_SETTINGS_H