Commit fc0faf53 authored by spang's avatar spang Committed by Commit bot

ozone: evdev: Sync caps lock LED state to evdev

Update LED state in kernel in InputControllerEvdev::SetCapsLockEnabled.
This is currently the only way to toggle caps lock.

BUG=463242
TEST=plug in external keyboard on link_freon & press caps lock. Light on
  keyboard should turn on.

Review URL: https://codereview.chromium.org/971753006

Cr-Commit-Position: refs/heads/master@{#318934}
parent 7d8d4236
...@@ -30,6 +30,8 @@ void EventConverterEvdev::Start() { ...@@ -30,6 +30,8 @@ void EventConverterEvdev::Start() {
} }
void EventConverterEvdev::Stop() { void EventConverterEvdev::Stop() {
// TODO(spang): If we reach here due to an error, we should treat it
// as if we have lost sync & release held keys, etc.
controller_.StopWatchingFileDescriptor(); controller_.StopWatchingFileDescriptor();
} }
...@@ -53,6 +55,10 @@ bool EventConverterEvdev::HasTouchscreen() const { ...@@ -53,6 +55,10 @@ bool EventConverterEvdev::HasTouchscreen() const {
return false; return false;
} }
bool EventConverterEvdev::HasCapsLockLed() const {
return false;
}
gfx::Size EventConverterEvdev::GetTouchscreenSize() const { gfx::Size EventConverterEvdev::GetTouchscreenSize() const {
NOTREACHED(); NOTREACHED();
return gfx::Size(); return gfx::Size();
...@@ -72,6 +78,33 @@ void EventConverterEvdev::AllowAllKeys() { ...@@ -72,6 +78,33 @@ void EventConverterEvdev::AllowAllKeys() {
NOTREACHED(); NOTREACHED();
} }
void EventConverterEvdev::SetCapsLockLed(bool enabled) {
if (!HasCapsLockLed())
return;
input_event events[2];
memset(&events, 0, sizeof(events));
events[0].type = EV_LED;
events[0].code = LED_CAPSL;
events[0].value = enabled;
events[1].type = EV_SYN;
events[1].code = SYN_REPORT;
events[1].value = 0;
ssize_t written = write(fd_, events, sizeof(events));
if (written < 0) {
if (errno != ENODEV)
PLOG(ERROR) << "cannot set leds for " << path_.value() << ":";
Stop();
} else if (written != sizeof(events)) {
LOG(ERROR) << "short write setting leds for " << path_.value();
Stop();
}
}
base::TimeDelta EventConverterEvdev::TimeDeltaFromInputEvent( base::TimeDelta EventConverterEvdev::TimeDeltaFromInputEvent(
const input_event& event) { const input_event& event) {
return base::TimeDelta::FromMicroseconds(event.time.tv_sec * 1000000 + return base::TimeDelta::FromMicroseconds(event.time.tv_sec * 1000000 +
......
...@@ -55,6 +55,9 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdev ...@@ -55,6 +55,9 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdev
// Returns true if the converter is used for a touchscreen device. // Returns true if the converter is used for a touchscreen device.
virtual bool HasTouchscreen() const; virtual bool HasTouchscreen() const;
// Returns true if the converter is used for a device with a caps lock LED.
virtual bool HasCapsLockLed() const;
// Returns the size of the touchscreen device if the converter is used for a // Returns the size of the touchscreen device if the converter is used for a
// touchscreen device. // touchscreen device.
virtual gfx::Size GetTouchscreenSize() const; virtual gfx::Size GetTouchscreenSize() const;
...@@ -69,6 +72,9 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdev ...@@ -69,6 +72,9 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdev
// Allows all keys to be processed. // Allows all keys to be processed.
virtual void AllowAllKeys(); virtual void AllowAllKeys();
// Update caps lock LED state.
virtual void SetCapsLockLed(bool enabled);
// Helper to generate a base::TimeDelta from an input_event's time // Helper to generate a base::TimeDelta from an input_event's time
static base::TimeDelta TimeDeltaFromInputEvent(const input_event& event); static base::TimeDelta TimeDeltaFromInputEvent(const input_event& event);
......
...@@ -33,6 +33,7 @@ EventConverterEvdevImpl::EventConverterEvdevImpl( ...@@ -33,6 +33,7 @@ EventConverterEvdevImpl::EventConverterEvdevImpl(
: EventConverterEvdev(fd, path, id, type), : EventConverterEvdev(fd, path, id, type),
has_keyboard_(devinfo.HasKeyboard()), has_keyboard_(devinfo.HasKeyboard()),
has_touchpad_(devinfo.HasTouchpad()), has_touchpad_(devinfo.HasTouchpad()),
has_caps_lock_led_(devinfo.HasLedEvent(LED_CAPSL)),
x_offset_(0), x_offset_(0),
y_offset_(0), y_offset_(0),
cursor_(cursor), cursor_(cursor),
...@@ -73,6 +74,10 @@ bool EventConverterEvdevImpl::HasTouchpad() const { ...@@ -73,6 +74,10 @@ bool EventConverterEvdevImpl::HasTouchpad() const {
return has_touchpad_; return has_touchpad_;
} }
bool EventConverterEvdevImpl::HasCapsLockLed() const {
return has_caps_lock_led_;
}
void EventConverterEvdevImpl::SetAllowedKeys( void EventConverterEvdevImpl::SetAllowedKeys(
scoped_ptr<std::set<DomCode>> allowed_keys) { scoped_ptr<std::set<DomCode>> allowed_keys) {
DCHECK(HasKeyboard()); DCHECK(HasKeyboard());
......
...@@ -41,6 +41,7 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdevImpl ...@@ -41,6 +41,7 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdevImpl
void OnFileCanReadWithoutBlocking(int fd) override; void OnFileCanReadWithoutBlocking(int fd) override;
bool HasKeyboard() const override; bool HasKeyboard() const override;
bool HasTouchpad() const override; bool HasTouchpad() const override;
bool HasCapsLockLed() const override;
void SetAllowedKeys(scoped_ptr<std::set<DomCode>> allowed_keys) override; void SetAllowedKeys(scoped_ptr<std::set<DomCode>> allowed_keys) override;
void AllowAllKeys() override; void AllowAllKeys() override;
...@@ -61,6 +62,9 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdevImpl ...@@ -61,6 +62,9 @@ class EVENTS_OZONE_EVDEV_EXPORT EventConverterEvdevImpl
bool has_keyboard_; bool has_keyboard_;
bool has_touchpad_; bool has_touchpad_;
// LEDs for this device.
bool has_caps_lock_led_;
// Save x-axis events of relative devices to be flushed at EV_SYN time. // Save x-axis events of relative devices to be flushed at EV_SYN time.
int x_offset_; int x_offset_;
......
...@@ -55,8 +55,6 @@ void EventModifiersEvdev::UpdateModifierLock(unsigned int modifier, bool down) { ...@@ -55,8 +55,6 @@ void EventModifiersEvdev::UpdateModifierLock(unsigned int modifier, bool down) {
if (down) if (down)
modifier_flags_locked_ ^= kEventFlagFromModifiers[modifier]; modifier_flags_locked_ ^= kEventFlagFromModifiers[modifier];
// TODO(spang): Synchronize with the CapsLock LED.
UpdateFlags(modifier); UpdateFlags(modifier);
} }
...@@ -68,8 +66,6 @@ void EventModifiersEvdev::SetModifierLock(unsigned int modifier, bool locked) { ...@@ -68,8 +66,6 @@ void EventModifiersEvdev::SetModifierLock(unsigned int modifier, bool locked) {
else else
modifier_flags_locked_ &= ~kEventFlagFromModifiers[modifier]; modifier_flags_locked_ &= ~kEventFlagFromModifiers[modifier];
// TODO(spang): Synchronize with the CapsLock LED.
UpdateFlags(modifier); UpdateFlags(modifier);
} }
......
...@@ -22,6 +22,7 @@ InputControllerEvdev::InputControllerEvdev(KeyboardEvdev* keyboard, ...@@ -22,6 +22,7 @@ InputControllerEvdev::InputControllerEvdev(KeyboardEvdev* keyboard,
button_map_(button_map), button_map_(button_map),
has_mouse_(false), has_mouse_(false),
has_touchpad_(false), has_touchpad_(false),
caps_lock_led_state_(false),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
} }
...@@ -33,6 +34,7 @@ void InputControllerEvdev::SetInputDeviceFactory( ...@@ -33,6 +34,7 @@ void InputControllerEvdev::SetInputDeviceFactory(
input_device_factory_ = input_device_factory; input_device_factory_ = input_device_factory;
UpdateDeviceSettings(); UpdateDeviceSettings();
UpdateCapsLockLed();
} }
void InputControllerEvdev::set_has_mouse(bool has_mouse) { void InputControllerEvdev::set_has_mouse(bool has_mouse) {
...@@ -57,6 +59,7 @@ bool InputControllerEvdev::IsCapsLockEnabled() { ...@@ -57,6 +59,7 @@ bool InputControllerEvdev::IsCapsLockEnabled() {
void InputControllerEvdev::SetCapsLockEnabled(bool enabled) { void InputControllerEvdev::SetCapsLockEnabled(bool enabled) {
keyboard_->SetCapsLockEnabled(enabled); keyboard_->SetCapsLockEnabled(enabled);
UpdateCapsLockLed();
} }
void InputControllerEvdev::SetNumLockEnabled(bool enabled) { void InputControllerEvdev::SetNumLockEnabled(bool enabled) {
...@@ -178,4 +181,13 @@ void InputControllerEvdev::UpdateDeviceSettings() { ...@@ -178,4 +181,13 @@ void InputControllerEvdev::UpdateDeviceSettings() {
settings_update_pending_ = false; settings_update_pending_ = false;
} }
void InputControllerEvdev::UpdateCapsLockLed() {
if (!input_device_factory_)
return;
bool caps_lock_state = IsCapsLockEnabled();
if (caps_lock_state != caps_lock_led_state_)
input_device_factory_->SetCapsLockLed(caps_lock_state);
caps_lock_led_state_ = caps_lock_state;
}
} // namespace ui } // namespace ui
...@@ -70,6 +70,9 @@ class EVENTS_OZONE_EVDEV_EXPORT InputControllerEvdev : public InputController { ...@@ -70,6 +70,9 @@ class EVENTS_OZONE_EVDEV_EXPORT InputControllerEvdev : public InputController {
// Send settings update to input_device_factory_. // Send settings update to input_device_factory_.
void UpdateDeviceSettings(); void UpdateDeviceSettings();
// Send caps lock update to input_device_factory_.
void UpdateCapsLockLed();
// Configuration that needs to be passed on to InputDeviceFactory. // Configuration that needs to be passed on to InputDeviceFactory.
InputDeviceSettingsEvdev input_device_settings_; InputDeviceSettingsEvdev input_device_settings_;
...@@ -89,6 +92,9 @@ class EVENTS_OZONE_EVDEV_EXPORT InputControllerEvdev : public InputController { ...@@ -89,6 +92,9 @@ class EVENTS_OZONE_EVDEV_EXPORT InputControllerEvdev : public InputController {
bool has_mouse_; bool has_mouse_;
bool has_touchpad_; bool has_touchpad_;
// LED state.
bool caps_lock_led_state_;
base::WeakPtrFactory<InputControllerEvdev> weak_ptr_factory_; base::WeakPtrFactory<InputControllerEvdev> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(InputControllerEvdev); DISALLOW_COPY_AND_ASSIGN(InputControllerEvdev);
......
...@@ -142,7 +142,7 @@ void OpenInputDevice(scoped_ptr<OpenInputDeviceParams> params, ...@@ -142,7 +142,7 @@ void OpenInputDevice(scoped_ptr<OpenInputDeviceParams> params,
TRACE_EVENT1("ozone", "OpenInputDevice", "path", path.value()); TRACE_EVENT1("ozone", "OpenInputDevice", "path", path.value());
int fd = open(path.value().c_str(), O_RDONLY | O_NONBLOCK); int fd = open(path.value().c_str(), O_RDWR | O_NONBLOCK);
if (fd < 0) { if (fd < 0) {
PLOG(ERROR) << "Cannot open '" << path.value(); PLOG(ERROR) << "Cannot open '" << path.value();
reply_runner->PostTask( reply_runner->PostTask(
...@@ -200,6 +200,7 @@ InputDeviceFactoryEvdev::InputDeviceFactoryEvdev( ...@@ -200,6 +200,7 @@ InputDeviceFactoryEvdev::InputDeviceFactoryEvdev(
keyboard_list_dirty_(false), keyboard_list_dirty_(false),
mouse_list_dirty_(false), mouse_list_dirty_(false),
touchpad_list_dirty_(false), touchpad_list_dirty_(false),
caps_lock_led_enabled_(false),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
} }
...@@ -256,6 +257,7 @@ void InputDeviceFactoryEvdev::AttachInputDevice( ...@@ -256,6 +257,7 @@ void InputDeviceFactoryEvdev::AttachInputDevice(
// Sync settings to new device. // Sync settings to new device.
ApplyInputDeviceSettings(); ApplyInputDeviceSettings();
ApplyCapsLockLed();
} }
if (--pending_device_changes_ == 0) if (--pending_device_changes_ == 0)
...@@ -328,6 +330,11 @@ void InputDeviceFactoryEvdev::EnableInternalKeyboard() { ...@@ -328,6 +330,11 @@ void InputDeviceFactoryEvdev::EnableInternalKeyboard() {
} }
} }
void InputDeviceFactoryEvdev::SetCapsLockLed(bool enabled) {
caps_lock_led_enabled_ = enabled;
ApplyCapsLockLed();
}
void InputDeviceFactoryEvdev::UpdateInputDeviceSettings( void InputDeviceFactoryEvdev::UpdateInputDeviceSettings(
const InputDeviceSettingsEvdev& settings) { const InputDeviceSettingsEvdev& settings) {
input_device_settings_ = settings; input_device_settings_ = settings;
...@@ -385,6 +392,13 @@ void InputDeviceFactoryEvdev::ApplyInputDeviceSettings() { ...@@ -385,6 +392,13 @@ void InputDeviceFactoryEvdev::ApplyInputDeviceSettings() {
input_device_settings_.tap_to_click_paused); input_device_settings_.tap_to_click_paused);
} }
void InputDeviceFactoryEvdev::ApplyCapsLockLed() {
for (const auto& it : converters_) {
EventConverterEvdev* converter = it.second;
converter->SetCapsLockLed(caps_lock_led_enabled_);
}
}
void InputDeviceFactoryEvdev::UpdateDirtyFlags( void InputDeviceFactoryEvdev::UpdateDirtyFlags(
const EventConverterEvdev* converter) { const EventConverterEvdev* converter) {
if (converter->HasTouchscreen()) if (converter->HasTouchscreen())
......
...@@ -63,6 +63,9 @@ class EVENTS_OZONE_EVDEV_EXPORT InputDeviceFactoryEvdev { ...@@ -63,6 +63,9 @@ class EVENTS_OZONE_EVDEV_EXPORT InputDeviceFactoryEvdev {
// Enables all keys on the internal keyboard. // Enables all keys on the internal keyboard.
void EnableInternalKeyboard(); void EnableInternalKeyboard();
// LED state.
void SetCapsLockLed(bool enabled);
// Bits from InputController that have to be answered on IO. // Bits from InputController that have to be answered on IO.
void UpdateInputDeviceSettings(const InputDeviceSettingsEvdev& settings); void UpdateInputDeviceSettings(const InputDeviceSettingsEvdev& settings);
void GetTouchDeviceStatus(const GetTouchDeviceStatusReply& reply); void GetTouchDeviceStatus(const GetTouchDeviceStatusReply& reply);
...@@ -80,6 +83,7 @@ class EVENTS_OZONE_EVDEV_EXPORT InputDeviceFactoryEvdev { ...@@ -80,6 +83,7 @@ class EVENTS_OZONE_EVDEV_EXPORT InputDeviceFactoryEvdev {
// Sync input_device_settings_ to attached devices. // Sync input_device_settings_ to attached devices.
void ApplyInputDeviceSettings(); void ApplyInputDeviceSettings();
void ApplyCapsLockLed();
// Update observers on device changes. // Update observers on device changes.
void UpdateDirtyFlags(const EventConverterEvdev* converter); void UpdateDirtyFlags(const EventConverterEvdev* converter);
...@@ -120,6 +124,9 @@ class EVENTS_OZONE_EVDEV_EXPORT InputDeviceFactoryEvdev { ...@@ -120,6 +124,9 @@ class EVENTS_OZONE_EVDEV_EXPORT InputDeviceFactoryEvdev {
bool mouse_list_dirty_; bool mouse_list_dirty_;
bool touchpad_list_dirty_; bool touchpad_list_dirty_;
// LEDs.
bool caps_lock_led_enabled_;
// Device settings. These primarily affect libgestures behavior. // Device settings. These primarily affect libgestures behavior.
InputDeviceSettingsEvdev input_device_settings_; InputDeviceSettingsEvdev input_device_settings_;
......
...@@ -80,6 +80,12 @@ void InputDeviceFactoryEvdevProxy::EnableInternalKeyboard() { ...@@ -80,6 +80,12 @@ void InputDeviceFactoryEvdevProxy::EnableInternalKeyboard() {
input_device_factory_)); input_device_factory_));
} }
void InputDeviceFactoryEvdevProxy::SetCapsLockLed(bool enabled) {
task_runner_->PostTask(FROM_HERE,
base::Bind(&InputDeviceFactoryEvdev::SetCapsLockLed,
input_device_factory_, enabled));
}
void InputDeviceFactoryEvdevProxy::UpdateInputDeviceSettings( void InputDeviceFactoryEvdevProxy::UpdateInputDeviceSettings(
const InputDeviceSettingsEvdev& settings) { const InputDeviceSettingsEvdev& settings) {
task_runner_->PostTask( task_runner_->PostTask(
......
...@@ -45,6 +45,7 @@ class EVENTS_OZONE_EVDEV_EXPORT InputDeviceFactoryEvdevProxy { ...@@ -45,6 +45,7 @@ class EVENTS_OZONE_EVDEV_EXPORT InputDeviceFactoryEvdevProxy {
void DisableInternalKeyboardExceptKeys( void DisableInternalKeyboardExceptKeys(
scoped_ptr<std::set<DomCode>> excepted_keys); scoped_ptr<std::set<DomCode>> excepted_keys);
void EnableInternalKeyboard(); void EnableInternalKeyboard();
void SetCapsLockLed(bool enabled);
void UpdateInputDeviceSettings(const InputDeviceSettingsEvdev& settings); void UpdateInputDeviceSettings(const InputDeviceSettingsEvdev& settings);
void GetTouchDeviceStatus(const GetTouchDeviceStatusReply& reply); void GetTouchDeviceStatus(const GetTouchDeviceStatusReply& reply);
void GetTouchEventLog(const base::FilePath& out_dir, void GetTouchEventLog(const base::FilePath& out_dir,
......
...@@ -52,6 +52,7 @@ class EVENTS_OZONE_EVDEV_EXPORT KeyboardEvdev { ...@@ -52,6 +52,7 @@ class EVENTS_OZONE_EVDEV_EXPORT KeyboardEvdev {
private: private:
void UpdateModifier(int modifier_flag, bool down); void UpdateModifier(int modifier_flag, bool down);
void UpdateCapsLockLed();
void UpdateKeyRepeat(unsigned int key, bool down); void UpdateKeyRepeat(unsigned int key, bool down);
void StartKeyRepeat(unsigned int key); void StartKeyRepeat(unsigned int key);
void StopKeyRepeat(); void StopKeyRepeat();
......
...@@ -35,6 +35,7 @@ EventReaderLibevdevCros::EventReaderLibevdevCros(int fd, ...@@ -35,6 +35,7 @@ EventReaderLibevdevCros::EventReaderLibevdevCros(int fd,
has_keyboard_(devinfo.HasKeyboard()), has_keyboard_(devinfo.HasKeyboard()),
has_mouse_(devinfo.HasMouse()), has_mouse_(devinfo.HasMouse()),
has_touchpad_(devinfo.HasTouchpad()), has_touchpad_(devinfo.HasTouchpad()),
has_caps_lock_led_(devinfo.HasLedEvent(LED_CAPSL)),
delegate_(delegate.Pass()) { delegate_(delegate.Pass()) {
memset(&evdev_, 0, sizeof(evdev_)); memset(&evdev_, 0, sizeof(evdev_));
evdev_.log = OnLogMessage; evdev_.log = OnLogMessage;
...@@ -82,6 +83,10 @@ bool EventReaderLibevdevCros::HasTouchpad() const { ...@@ -82,6 +83,10 @@ bool EventReaderLibevdevCros::HasTouchpad() const {
return has_touchpad_; return has_touchpad_;
} }
bool EventReaderLibevdevCros::HasCapsLockLed() const {
return has_caps_lock_led_;
}
void EventReaderLibevdevCros::SetAllowedKeys( void EventReaderLibevdevCros::SetAllowedKeys(
scoped_ptr<std::set<DomCode>> allowed_keys) { scoped_ptr<std::set<DomCode>> allowed_keys) {
DCHECK(HasKeyboard()); DCHECK(HasKeyboard());
......
...@@ -55,6 +55,7 @@ class EventReaderLibevdevCros : public EventConverterEvdev { ...@@ -55,6 +55,7 @@ class EventReaderLibevdevCros : public EventConverterEvdev {
bool HasKeyboard() const override; bool HasKeyboard() const override;
bool HasMouse() const override; bool HasMouse() const override;
bool HasTouchpad() const override; bool HasTouchpad() const override;
bool HasCapsLockLed() const override;
void SetAllowedKeys(scoped_ptr<std::set<DomCode>> allowed_keys) override; void SetAllowedKeys(scoped_ptr<std::set<DomCode>> allowed_keys) override;
void AllowAllKeys() override; void AllowAllKeys() override;
...@@ -69,6 +70,9 @@ class EventReaderLibevdevCros : public EventConverterEvdev { ...@@ -69,6 +70,9 @@ class EventReaderLibevdevCros : public EventConverterEvdev {
bool has_mouse_; bool has_mouse_;
bool has_touchpad_; bool has_touchpad_;
// LEDs for this device.
bool has_caps_lock_led_;
// Libevdev state. // Libevdev state.
Evdev evdev_; Evdev evdev_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment