| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/events/event_rewriter.h" | 5 #include "chrome/browser/chromeos/events/event_rewriter.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "ash/sticky_keys/sticky_keys_controller.h" | 9 #include "ash/sticky_keys/sticky_keys_controller.h" |
| 10 #include "ash/wm/window_state.h" | 10 #include "ash/wm/window_state.h" |
| 11 #include "ash/wm/window_util.h" | 11 #include "ash/wm/window_util.h" |
| 12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/prefs/pref_service.h" | 15 #include "base/prefs/pref_service.h" |
| 16 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
| 17 #include "base/sys_info.h" | 17 #include "base/sys_info.h" |
| 18 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" | 18 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" |
| 19 #include "chrome/browser/chromeos/login/users/user_manager.h" | 19 #include "chrome/browser/chromeos/login/users/user_manager.h" |
| 20 #include "chrome/browser/profiles/profile_manager.h" | 20 #include "chrome/browser/profiles/profile_manager.h" |
| 21 #include "chrome/common/pref_names.h" | 21 #include "chrome/common/pref_names.h" |
| 22 #include "chromeos/chromeos_switches.h" | 22 #include "chromeos/chromeos_switches.h" |
| 23 #include "chromeos/ime/ime_keyboard.h" | 23 #include "chromeos/ime/ime_keyboard.h" |
| 24 #include "chromeos/ime/input_method_manager.h" | 24 #include "chromeos/ime/input_method_manager.h" |
| 25 #include "ui/events/event.h" | 25 #include "ui/events/event.h" |
| 26 #include "ui/events/event_utils.h" | 26 #include "ui/events/event_utils.h" |
| 27 #include "ui/events/keycodes/keyboard_code_conversion.h" | 27 #include "ui/events/keycodes/keyboard_code_conversion.h" |
| 28 #include "ui/events/platform/platform_event_source.h" | |
| 29 #include "ui/wm/core/window_util.h" | 28 #include "ui/wm/core/window_util.h" |
| 30 | 29 |
| 31 #if defined(USE_X11) | 30 #if defined(USE_X11) |
| 32 #include <X11/extensions/XInput2.h> | 31 #include <X11/extensions/XInput2.h> |
| 33 #include <X11/Xlib.h> | 32 #include <X11/Xlib.h> |
| 34 // Get rid of macros from Xlib.h that conflicts with other parts of the code. | 33 // Get rid of macros from Xlib.h that conflicts with other parts of the code. |
| 35 #undef RootWindow | 34 #undef RootWindow |
| 36 #undef Status | 35 #undef Status |
| 37 | 36 |
| 38 #include "chrome/browser/chromeos/events/xinput_hierarchy_changed_event_listener
.h" | |
| 39 #include "ui/base/x/x11_util.h" | 37 #include "ui/base/x/x11_util.h" |
| 40 #include "ui/events/keycodes/keyboard_code_conversion_x.h" | 38 #include "ui/events/keycodes/keyboard_code_conversion_x.h" |
| 41 #endif | 39 #endif |
| 42 | 40 |
| 43 namespace chromeos { | 41 namespace chromeos { |
| 44 | 42 |
| 45 namespace { | 43 namespace { |
| 46 | 44 |
| 47 const int kBadDeviceId = -1; | |
| 48 | |
| 49 // Table of key properties of remappable keys and/or remapping targets. | 45 // Table of key properties of remappable keys and/or remapping targets. |
| 50 // This is searched in two distinct ways: | 46 // This is searched in two distinct ways: |
| 51 // - |remap_to| is an |input_method::ModifierKey|, which is the form | 47 // - |remap_to| is an |input_method::ModifierKey|, which is the form |
| 52 // held in user preferences. |GetRemappedKey()| maps this to the | 48 // held in user preferences. |GetRemappedKey()| maps this to the |
| 53 // corresponding |key_code| and characterstic event |flag|. | 49 // corresponding |key_code| and characterstic event |flag|. |
| 54 // - |flag| is a |ui::EventFlags|. |GetRemappedModifierMasks()| maps this | 50 // - |flag| is a |ui::EventFlags|. |GetRemappedModifierMasks()| maps this |
| 55 // to the corresponding user preference |pref_name| for that flag's | 51 // to the corresponding user preference |pref_name| for that flag's |
| 56 // key, so that it can then be remapped as above. | 52 // key, so that it can then be remapped as above. |
| 57 // In addition |kModifierRemappingCtrl| is a direct reference to the | 53 // In addition |kModifierRemappingCtrl| is a direct reference to the |
| 58 // Control key entry in the table, used in handling Chromebook Diamond | 54 // Control key entry in the table, used in handling Chromebook Diamond |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 {ui::EF_MIDDLE_MOUSE_BUTTON, Button2Mask}, | 142 {ui::EF_MIDDLE_MOUSE_BUTTON, Button2Mask}, |
| 147 {ui::EF_RIGHT_MOUSE_BUTTON, Button3Mask}, | 143 {ui::EF_RIGHT_MOUSE_BUTTON, Button3Mask}, |
| 148 }; | 144 }; |
| 149 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(flags); ++i) { | 145 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(flags); ++i) { |
| 150 if (ui_flags & flags[i].ui) | 146 if (ui_flags & flags[i].ui) |
| 151 *x_flags |= flags[i].x; | 147 *x_flags |= flags[i].x; |
| 152 else | 148 else |
| 153 *x_flags &= ~flags[i].x; | 149 *x_flags &= ~flags[i].x; |
| 154 } | 150 } |
| 155 } | 151 } |
| 156 #endif | 152 |
| 153 void UpdateX11Button(int ui_flag, unsigned int* x_button) { |
| 154 switch (ui_flag) { |
| 155 case ui::EF_LEFT_MOUSE_BUTTON: |
| 156 *x_button = Button1; |
| 157 break; |
| 158 case ui::EF_MIDDLE_MOUSE_BUTTON: |
| 159 *x_button = Button2; |
| 160 break; |
| 161 case ui::EF_RIGHT_MOUSE_BUTTON: |
| 162 *x_button = Button3; |
| 163 break; |
| 164 } |
| 165 } |
| 166 #endif // defined(USE_X11) |
| 157 | 167 |
| 158 bool IsSendEvent(const ui::Event& event) { | 168 bool IsSendEvent(const ui::Event& event) { |
| 159 #if defined(USE_X11) | 169 #if defined(USE_X11) |
| 160 // Do not rewrite an event sent by ui_controls::SendKeyPress(). See | 170 // Do not rewrite an event sent by ui_controls::SendKeyPress(). See |
| 161 // crbug.com/136465. | 171 // crbug.com/136465. |
| 162 XEvent* xev = event.native_event(); | 172 XEvent* xev = event.native_event(); |
| 163 if (xev && xev->xany.send_event) | 173 if (xev && xev->xany.send_event) |
| 164 return true; | 174 return true; |
| 165 #endif | 175 #endif |
| 166 return false; | 176 return false; |
| 167 } | 177 } |
| 168 | 178 |
| 169 } // namespace | 179 } // namespace |
| 170 | 180 |
| 171 EventRewriter::EventRewriter(ash::StickyKeysController* sticky_keys_controller) | 181 EventRewriter::EventRewriter(ash::StickyKeysController* sticky_keys_controller) |
| 172 : last_device_id_(kBadDeviceId), | 182 : last_keyboard_device_id_(ui::ED_UNKNOWN_DEVICE), |
| 173 ime_keyboard_for_testing_(NULL), | 183 ime_keyboard_for_testing_(NULL), |
| 174 pref_service_for_testing_(NULL), | 184 pref_service_for_testing_(NULL), |
| 175 sticky_keys_controller_(sticky_keys_controller) { | 185 sticky_keys_controller_(sticky_keys_controller) { |
| 176 #if defined(USE_X11) | |
| 177 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this); | |
| 178 if (base::SysInfo::IsRunningOnChromeOS()) { | |
| 179 XInputHierarchyChangedEventListener::GetInstance()->AddObserver(this); | |
| 180 } | |
| 181 #endif | |
| 182 } | 186 } |
| 183 | 187 |
| 184 EventRewriter::~EventRewriter() { | 188 EventRewriter::~EventRewriter() { |
| 185 #if defined(USE_X11) | |
| 186 ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this); | |
| 187 if (base::SysInfo::IsRunningOnChromeOS()) { | |
| 188 XInputHierarchyChangedEventListener::GetInstance()->RemoveObserver(this); | |
| 189 } | |
| 190 #endif | |
| 191 } | 189 } |
| 192 | 190 |
| 193 EventRewriter::DeviceType EventRewriter::DeviceAddedForTesting( | 191 EventRewriter::DeviceType EventRewriter::KeyboardDeviceAddedForTesting( |
| 194 int device_id, | 192 int device_id, |
| 195 const std::string& device_name) { | 193 const std::string& device_name) { |
| 196 return DeviceAddedInternal(device_id, device_name); | 194 // Tests must avoid XI2 reserved device IDs. |
| 195 DCHECK((device_id < 0) || (device_id > 1)); |
| 196 return KeyboardDeviceAddedInternal(device_id, device_name); |
| 197 } | 197 } |
| 198 | 198 |
| 199 void EventRewriter::RewriteLocatedEventForTesting(const ui::Event& event, | 199 void EventRewriter::RewriteMouseButtonEventForTesting( |
| 200 int* flags) { | 200 const ui::MouseEvent& event, |
| 201 RewriteLocatedEvent(event, flags); | 201 scoped_ptr<ui::Event>* rewritten_event) { |
| 202 RewriteMouseButtonEvent(event, rewritten_event); |
| 202 } | 203 } |
| 203 | 204 |
| 204 ui::EventRewriteStatus EventRewriter::RewriteEvent( | 205 ui::EventRewriteStatus EventRewriter::RewriteEvent( |
| 205 const ui::Event& event, | 206 const ui::Event& event, |
| 206 scoped_ptr<ui::Event>* rewritten_event) { | 207 scoped_ptr<ui::Event>* rewritten_event) { |
| 207 if ((event.type() == ui::ET_KEY_PRESSED) || | 208 if ((event.type() == ui::ET_KEY_PRESSED) || |
| 208 (event.type() == ui::ET_KEY_RELEASED)) { | 209 (event.type() == ui::ET_KEY_RELEASED)) { |
| 209 return RewriteKeyEvent(static_cast<const ui::KeyEvent&>(event), | 210 return RewriteKeyEvent(static_cast<const ui::KeyEvent&>(event), |
| 210 rewritten_event); | 211 rewritten_event); |
| 211 } | 212 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 238 // modifier key releases that match the ones previously discarded. So, we | 239 // modifier key releases that match the ones previously discarded. So, we |
| 239 // know that they don't have to be passed through the post-sticky key | 240 // know that they don't have to be passed through the post-sticky key |
| 240 // rewriting phases, |RewriteExtendedKeys()| and |RewriteFunctionKeys()|, | 241 // rewriting phases, |RewriteExtendedKeys()| and |RewriteFunctionKeys()|, |
| 241 // because those phases do nothing with modifier key releases. | 242 // because those phases do nothing with modifier key releases. |
| 242 return sticky_keys_controller_->NextDispatchEvent(new_event); | 243 return sticky_keys_controller_->NextDispatchEvent(new_event); |
| 243 } | 244 } |
| 244 NOTREACHED(); | 245 NOTREACHED(); |
| 245 return ui::EVENT_REWRITE_CONTINUE; | 246 return ui::EVENT_REWRITE_CONTINUE; |
| 246 } | 247 } |
| 247 | 248 |
| 249 void EventRewriter::BuildRewrittenKeyEvent( |
| 250 const ui::KeyEvent& key_event, |
| 251 ui::KeyboardCode key_code, |
| 252 int flags, |
| 253 scoped_ptr<ui::Event>* rewritten_event) { |
| 254 ui::KeyEvent* rewritten_key_event = NULL; |
| 248 #if defined(USE_X11) | 255 #if defined(USE_X11) |
| 256 XEvent* xev = key_event.native_event(); |
| 257 if (xev) { |
| 258 XEvent xkeyevent; |
| 259 // Convert all XI2-based key events into X11 core-based key events, |
| 260 // until consumers no longer depend on receiving X11 core events. |
| 261 if (xev->type == GenericEvent) |
| 262 ui::InitXKeyEventFromXIDeviceEvent(*xev, &xkeyevent); |
| 263 else |
| 264 xkeyevent.xkey = xev->xkey; |
| 265 |
| 266 // Update native event to match rewritten |ui::Event|. |
| 267 xkeyevent.xkey.keycode = XKeysymToKeycode( |
| 268 gfx::GetXDisplay(), |
| 269 ui::XKeysymForWindowsKeyCode(key_code, flags & ui::EF_SHIFT_DOWN)); |
| 270 UpdateX11EventMask(flags, &xkeyevent.xkey.state); |
| 271 ui::KeyEvent x11_key_event(&xkeyevent, false); |
| 272 rewritten_key_event = new ui::KeyEvent(x11_key_event); |
| 273 } |
| 274 #endif |
| 275 if (!rewritten_key_event) |
| 276 rewritten_key_event = new ui::KeyEvent(key_event); |
| 277 rewritten_key_event->set_flags(flags); |
| 278 rewritten_key_event->set_key_code(key_code); |
| 279 rewritten_key_event->set_character( |
| 280 ui::GetCharacterFromKeyCode(key_code, flags)); |
| 281 rewritten_key_event->NormalizeFlags(); |
| 282 rewritten_event->reset(rewritten_key_event); |
| 283 } |
| 284 |
| 249 void EventRewriter::DeviceKeyPressedOrReleased(int device_id) { | 285 void EventRewriter::DeviceKeyPressedOrReleased(int device_id) { |
| 250 if (!device_id_to_type_.count(device_id)) { | 286 if (!device_id_to_type_.count(device_id)) |
| 251 // |device_id| is unknown. This means the device was connected before | 287 KeyboardDeviceAdded(device_id); |
| 252 // booting the OS. Query the name of the device and add it to the map. | 288 last_keyboard_device_id_ = device_id; |
| 253 DeviceAdded(device_id); | |
| 254 } | |
| 255 last_device_id_ = device_id; | |
| 256 } | 289 } |
| 257 #endif | |
| 258 | 290 |
| 259 const PrefService* EventRewriter::GetPrefService() const { | 291 const PrefService* EventRewriter::GetPrefService() const { |
| 260 if (pref_service_for_testing_) | 292 if (pref_service_for_testing_) |
| 261 return pref_service_for_testing_; | 293 return pref_service_for_testing_; |
| 262 Profile* profile = ProfileManager::GetActiveUserProfile(); | 294 Profile* profile = ProfileManager::GetActiveUserProfile(); |
| 263 return profile ? profile->GetPrefs() : NULL; | 295 return profile ? profile->GetPrefs() : NULL; |
| 264 } | 296 } |
| 265 | 297 |
| 266 bool EventRewriter::IsAppleKeyboard() const { | 298 bool EventRewriter::IsAppleKeyboard() const { |
| 267 if (last_device_id_ == kBadDeviceId) | 299 if (last_keyboard_device_id_ == ui::ED_UNKNOWN_DEVICE) |
| 268 return false; | 300 return false; |
| 269 | 301 |
| 270 // Check which device generated |event|. | 302 // Check which device generated |event|. |
| 271 std::map<int, DeviceType>::const_iterator iter = | 303 std::map<int, DeviceType>::const_iterator iter = |
| 272 device_id_to_type_.find(last_device_id_); | 304 device_id_to_type_.find(last_keyboard_device_id_); |
| 273 if (iter == device_id_to_type_.end()) { | 305 if (iter == device_id_to_type_.end()) { |
| 274 LOG(ERROR) << "Device ID " << last_device_id_ << " is unknown."; | 306 LOG(ERROR) << "Device ID " << last_keyboard_device_id_ << " is unknown."; |
| 275 return false; | 307 return false; |
| 276 } | 308 } |
| 277 | 309 |
| 278 const DeviceType type = iter->second; | 310 const DeviceType type = iter->second; |
| 279 return type == kDeviceAppleKeyboard; | 311 return type == kDeviceAppleKeyboard; |
| 280 } | 312 } |
| 281 | 313 |
| 282 bool EventRewriter::TopRowKeysAreFunctionKeys(const ui::KeyEvent& event) const { | 314 bool EventRewriter::TopRowKeysAreFunctionKeys(const ui::KeyEvent& event) const { |
| 283 const PrefService* prefs = GetPrefService(); | 315 const PrefService* prefs = GetPrefService(); |
| 284 if (prefs && prefs->FindPreference(prefs::kLanguageSendFunctionKeys) && | 316 if (prefs && prefs->FindPreference(prefs::kLanguageSendFunctionKeys) && |
| 285 prefs->GetBoolean(prefs::kLanguageSendFunctionKeys)) | 317 prefs->GetBoolean(prefs::kLanguageSendFunctionKeys)) |
| 286 return true; | 318 return true; |
| 287 | 319 |
| 288 ash::wm::WindowState* state = ash::wm::GetActiveWindowState(); | 320 ash::wm::WindowState* state = ash::wm::GetActiveWindowState(); |
| 289 return state ? state->top_row_keys_are_function_keys() : false; | 321 return state ? state->top_row_keys_are_function_keys() : false; |
| 290 } | 322 } |
| 291 | 323 |
| 292 int EventRewriter::GetRemappedModifierMasks(const PrefService& pref_service, | 324 int EventRewriter::GetRemappedModifierMasks(const PrefService& pref_service, |
| 293 const ui::Event& event, | 325 const ui::Event& event, |
| 294 int original_flags) const { | 326 int original_flags) const { |
| 295 int unmodified_flags = original_flags; | 327 int unmodified_flags = original_flags; |
| 296 int rewritten_flags = 0; | 328 int rewritten_flags = 0; |
| 297 for (size_t i = 0; unmodified_flags && (i < arraysize(kModifierRemappings)); | 329 for (size_t i = 0; unmodified_flags && (i < arraysize(kModifierRemappings)); |
| 298 ++i) { | 330 ++i) { |
| 299 const ModifierRemapping* remapped_key = 0; | 331 const ModifierRemapping* remapped_key = NULL; |
| 300 if (!(unmodified_flags & kModifierRemappings[i].flag)) | 332 if (!(unmodified_flags & kModifierRemappings[i].flag)) |
| 301 continue; | 333 continue; |
| 302 switch (kModifierRemappings[i].flag) { | 334 switch (kModifierRemappings[i].flag) { |
| 303 case ui::EF_COMMAND_DOWN: | 335 case ui::EF_COMMAND_DOWN: |
| 304 // Rewrite Command key presses on an Apple keyboard to Control. | 336 // Rewrite Command key presses on an Apple keyboard to Control. |
| 305 if (IsAppleKeyboard()) { | 337 if (IsAppleKeyboard()) { |
| 306 DCHECK_EQ(ui::EF_CONTROL_DOWN, kModifierRemappingCtrl->flag); | 338 DCHECK_EQ(ui::EF_CONTROL_DOWN, kModifierRemappingCtrl->flag); |
| 307 remapped_key = kModifierRemappingCtrl; | 339 remapped_key = kModifierRemappingCtrl; |
| 308 } | 340 } |
| 309 break; | 341 break; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 remapped_state->key_code = map.output_key_code; | 379 remapped_state->key_code = map.output_key_code; |
| 348 remapped_state->flags = (input.flags & ~map.input_flags) | map.output_flags; | 380 remapped_state->flags = (input.flags & ~map.input_flags) | map.output_flags; |
| 349 return true; | 381 return true; |
| 350 } | 382 } |
| 351 return false; | 383 return false; |
| 352 } | 384 } |
| 353 | 385 |
| 354 ui::EventRewriteStatus EventRewriter::RewriteKeyEvent( | 386 ui::EventRewriteStatus EventRewriter::RewriteKeyEvent( |
| 355 const ui::KeyEvent& key_event, | 387 const ui::KeyEvent& key_event, |
| 356 scoped_ptr<ui::Event>* rewritten_event) { | 388 scoped_ptr<ui::Event>* rewritten_event) { |
| 389 if (key_event.source_device_id() != ui::ED_UNKNOWN_DEVICE) |
| 390 DeviceKeyPressedOrReleased(key_event.source_device_id()); |
| 357 MutableKeyState state = {key_event.flags(), key_event.key_code()}; | 391 MutableKeyState state = {key_event.flags(), key_event.key_code()}; |
| 358 bool is_send_event = IsSendEvent(key_event); | 392 bool is_send_event = IsSendEvent(key_event); |
| 359 if (!is_send_event) { | 393 if (!is_send_event) { |
| 360 RewriteModifierKeys(key_event, &state); | 394 RewriteModifierKeys(key_event, &state); |
| 361 RewriteNumPadKeys(key_event, &state); | 395 RewriteNumPadKeys(key_event, &state); |
| 362 } | 396 } |
| 363 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; | 397 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; |
| 364 if (sticky_keys_controller_) { | 398 if (sticky_keys_controller_) { |
| 365 status = sticky_keys_controller_->RewriteKeyEvent( | 399 status = sticky_keys_controller_->RewriteKeyEvent( |
| 366 key_event, state.key_code, &state.flags); | 400 key_event, state.key_code, &state.flags); |
| 367 if (status == ui::EVENT_REWRITE_DISCARD) | 401 if (status == ui::EVENT_REWRITE_DISCARD) |
| 368 return ui::EVENT_REWRITE_DISCARD; | 402 return ui::EVENT_REWRITE_DISCARD; |
| 369 } | 403 } |
| 370 if (!is_send_event) { | 404 if (!is_send_event) { |
| 371 RewriteExtendedKeys(key_event, &state); | 405 RewriteExtendedKeys(key_event, &state); |
| 372 RewriteFunctionKeys(key_event, &state); | 406 RewriteFunctionKeys(key_event, &state); |
| 373 } | 407 } |
| 374 if ((key_event.flags() == state.flags) && | 408 if ((key_event.flags() == state.flags) && |
| 375 (key_event.key_code() == state.key_code) && | 409 (key_event.key_code() == state.key_code) && |
| 410 #if defined(USE_X11) |
| 411 // TODO(kpschoedel): This test is present because several consumers of |
| 412 // key events depend on having a native core X11 event, so we rewrite |
| 413 // all XI2 key events (GenericEvent) into corresponding core X11 key |
| 414 // events. Remove this when event consumers no longer care about |
| 415 // native X11 event details (crbug.com/380349). |
| 416 (!key_event.HasNativeEvent() || |
| 417 (key_event.native_event()->type != GenericEvent)) && |
| 418 #endif |
| 376 (status == ui::EVENT_REWRITE_CONTINUE)) { | 419 (status == ui::EVENT_REWRITE_CONTINUE)) { |
| 377 return ui::EVENT_REWRITE_CONTINUE; | 420 return ui::EVENT_REWRITE_CONTINUE; |
| 378 } | 421 } |
| 379 // Sticky keys may have returned a result other than |EVENT_REWRITE_CONTINUE|, | 422 // Sticky keys may have returned a result other than |EVENT_REWRITE_CONTINUE|, |
| 380 // in which case we need to preserve that return status. Alternatively, we | 423 // in which case we need to preserve that return status. Alternatively, we |
| 381 // might be here because key_event changed, in which case we need to return | 424 // might be here because key_event changed, in which case we need to |
| 382 // |EVENT_REWRITE_REWRITTEN|. | 425 // return |EVENT_REWRITE_REWRITTEN|. |
| 383 if (status == ui::EVENT_REWRITE_CONTINUE) | 426 if (status == ui::EVENT_REWRITE_CONTINUE) |
| 384 status = ui::EVENT_REWRITE_REWRITTEN; | 427 status = ui::EVENT_REWRITE_REWRITTEN; |
| 385 ui::KeyEvent* rewritten_key_event = new ui::KeyEvent(key_event); | 428 BuildRewrittenKeyEvent( |
| 386 rewritten_event->reset(rewritten_key_event); | 429 key_event, state.key_code, state.flags, rewritten_event); |
| 387 rewritten_key_event->set_flags(state.flags); | |
| 388 rewritten_key_event->set_key_code(state.key_code); | |
| 389 rewritten_key_event->set_character( | |
| 390 ui::GetCharacterFromKeyCode(state.key_code, state.flags)); | |
| 391 rewritten_key_event->NormalizeFlags(); | |
| 392 #if defined(USE_X11) | |
| 393 XEvent* xev = rewritten_key_event->native_event(); | |
| 394 if (xev) { | |
| 395 CHECK(xev->type == KeyPress || xev->type == KeyRelease); | |
| 396 XKeyEvent* xkey = &(xev->xkey); | |
| 397 UpdateX11EventMask(rewritten_key_event->flags(), &xkey->state); | |
| 398 xkey->keycode = | |
| 399 XKeysymToKeycode(gfx::GetXDisplay(), | |
| 400 ui::XKeysymForWindowsKeyCode( | |
| 401 state.key_code, state.flags & ui::EF_SHIFT_DOWN)); | |
| 402 } | |
| 403 #endif | |
| 404 return status; | 430 return status; |
| 405 } | 431 } |
| 406 | 432 |
| 407 ui::EventRewriteStatus EventRewriter::RewriteMouseButtonEvent( | 433 ui::EventRewriteStatus EventRewriter::RewriteMouseButtonEvent( |
| 408 const ui::MouseEvent& mouse_event, | 434 const ui::MouseEvent& mouse_event, |
| 409 scoped_ptr<ui::Event>* rewritten_event) { | 435 scoped_ptr<ui::Event>* rewritten_event) { |
| 410 int flags = mouse_event.flags(); | 436 int flags = mouse_event.flags(); |
| 411 RewriteLocatedEvent(mouse_event, &flags); | 437 RewriteLocatedEvent(mouse_event, &flags); |
| 412 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; | 438 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE; |
| 413 if (sticky_keys_controller_) | 439 if (sticky_keys_controller_) |
| 414 status = sticky_keys_controller_->RewriteMouseEvent(mouse_event, &flags); | 440 status = sticky_keys_controller_->RewriteMouseEvent(mouse_event, &flags); |
| 441 int changed_button = ui::EF_NONE; |
| 442 if ((mouse_event.type() == ui::ET_MOUSE_PRESSED) || |
| 443 (mouse_event.type() == ui::ET_MOUSE_RELEASED)) { |
| 444 changed_button = RewriteModifierClick(mouse_event, &flags); |
| 445 } |
| 415 if ((mouse_event.flags() == flags) && | 446 if ((mouse_event.flags() == flags) && |
| 416 (status == ui::EVENT_REWRITE_CONTINUE)) { | 447 (status == ui::EVENT_REWRITE_CONTINUE)) { |
| 417 return ui::EVENT_REWRITE_CONTINUE; | 448 return ui::EVENT_REWRITE_CONTINUE; |
| 418 } | 449 } |
| 419 if (status == ui::EVENT_REWRITE_CONTINUE) | 450 if (status == ui::EVENT_REWRITE_CONTINUE) |
| 420 status = ui::EVENT_REWRITE_REWRITTEN; | 451 status = ui::EVENT_REWRITE_REWRITTEN; |
| 421 ui::MouseEvent* rewritten_mouse_event = new ui::MouseEvent(mouse_event); | 452 ui::MouseEvent* rewritten_mouse_event = new ui::MouseEvent(mouse_event); |
| 422 rewritten_event->reset(rewritten_mouse_event); | 453 rewritten_event->reset(rewritten_mouse_event); |
| 423 rewritten_mouse_event->set_flags(flags); | 454 rewritten_mouse_event->set_flags(flags); |
| 455 if (changed_button != ui::EF_NONE) |
| 456 rewritten_mouse_event->set_changed_button_flags(changed_button); |
| 424 #if defined(USE_X11) | 457 #if defined(USE_X11) |
| 425 XEvent* xev = rewritten_mouse_event->native_event(); | 458 XEvent* xev = rewritten_mouse_event->native_event(); |
| 426 if (xev) { | 459 if (xev) { |
| 427 switch (xev->type) { | 460 switch (xev->type) { |
| 428 case ButtonPress: | 461 case ButtonPress: |
| 429 case ButtonRelease: { | 462 case ButtonRelease: { |
| 430 XButtonEvent* xbutton = &(xev->xbutton); | 463 XButtonEvent* xbutton = &(xev->xbutton); |
| 431 UpdateX11EventMask(rewritten_mouse_event->flags(), &xbutton->state); | 464 UpdateX11EventMask(rewritten_mouse_event->flags(), &xbutton->state); |
| 465 if (changed_button) |
| 466 UpdateX11Button(changed_button, &xbutton->button); |
| 432 break; | 467 break; |
| 433 } | 468 } |
| 434 case GenericEvent: { | 469 case GenericEvent: { |
| 435 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); | 470 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); |
| 436 CHECK(xievent->evtype == XI_ButtonPress || | 471 CHECK(xievent->evtype == XI_ButtonPress || |
| 437 xievent->evtype == XI_ButtonRelease); | 472 xievent->evtype == XI_ButtonRelease); |
| 438 UpdateX11EventMask( | 473 UpdateX11EventMask( |
| 439 rewritten_mouse_event->flags(), | 474 rewritten_mouse_event->flags(), |
| 440 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); | 475 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); |
| 476 if (changed_button) { |
| 477 UpdateX11Button(changed_button, |
| 478 reinterpret_cast<unsigned int*>(&xievent->detail)); |
| 479 } |
| 441 break; | 480 break; |
| 442 } | 481 } |
| 443 default: | 482 default: |
| 444 NOTREACHED(); | 483 NOTREACHED(); |
| 445 } | 484 } |
| 446 } | 485 } |
| 447 #endif | 486 #endif |
| 448 return status; | 487 return status; |
| 449 } | 488 } |
| 450 | 489 |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 rewritten = RewriteWithKeyboardRemappingsByKeyCode( | 868 rewritten = RewriteWithKeyboardRemappingsByKeyCode( |
| 830 kNumberKeysToFkeys, arraysize(kNumberKeysToFkeys), incoming, state); | 869 kNumberKeysToFkeys, arraysize(kNumberKeysToFkeys), incoming, state); |
| 831 } | 870 } |
| 832 } | 871 } |
| 833 | 872 |
| 834 void EventRewriter::RewriteLocatedEvent(const ui::Event& event, | 873 void EventRewriter::RewriteLocatedEvent(const ui::Event& event, |
| 835 int* flags) { | 874 int* flags) { |
| 836 const PrefService* pref_service = GetPrefService(); | 875 const PrefService* pref_service = GetPrefService(); |
| 837 if (!pref_service) | 876 if (!pref_service) |
| 838 return; | 877 return; |
| 839 | |
| 840 // First, remap modifier masks. | |
| 841 *flags = GetRemappedModifierMasks(*pref_service, event, *flags); | 878 *flags = GetRemappedModifierMasks(*pref_service, event, *flags); |
| 842 | |
| 843 #if defined(USE_X11) | |
| 844 // TODO(kpschoedel): de-X11 with unified device ids from crbug.com/360377 | |
| 845 XEvent* xevent = event.native_event(); | |
| 846 if (!xevent || xevent->type != GenericEvent) | |
| 847 return; | |
| 848 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data); | |
| 849 if (xievent->evtype != XI_ButtonPress && xievent->evtype != XI_ButtonRelease) | |
| 850 return; | |
| 851 UpdateX11EventMask(*flags, | |
| 852 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); | |
| 853 | |
| 854 // Then, remap Alt+Button1 to Button3. | |
| 855 if ((xievent->evtype == XI_ButtonPress || | |
| 856 pressed_device_ids_.count(xievent->sourceid)) && | |
| 857 (xievent->mods.effective & Mod1Mask) && xievent->detail == Button1) { | |
| 858 *flags &= ~(ui::EF_ALT_DOWN | ui::EF_LEFT_MOUSE_BUTTON); | |
| 859 *flags |= ui::EF_RIGHT_MOUSE_BUTTON; | |
| 860 xievent->mods.effective &= ~Mod1Mask; | |
| 861 xievent->detail = Button3; | |
| 862 if (xievent->evtype == XI_ButtonRelease) { | |
| 863 // On the release clear the left button from the existing state and the | |
| 864 // mods, and set the right button. | |
| 865 XISetMask(xievent->buttons.mask, Button3); | |
| 866 XIClearMask(xievent->buttons.mask, Button1); | |
| 867 xievent->mods.effective &= ~Button1Mask; | |
| 868 pressed_device_ids_.erase(xievent->sourceid); | |
| 869 } else { | |
| 870 pressed_device_ids_.insert(xievent->sourceid); | |
| 871 } | |
| 872 } | |
| 873 #endif // defined(USE_X11) | |
| 874 } | 879 } |
| 875 | 880 |
| 876 EventRewriter::DeviceType EventRewriter::DeviceAddedInternal( | 881 int EventRewriter::RewriteModifierClick(const ui::MouseEvent& mouse_event, |
| 882 int* flags) { |
| 883 // Remap Alt+Button1 to Button3. |
| 884 const int kAltLeftButton = (ui::EF_ALT_DOWN | ui::EF_LEFT_MOUSE_BUTTON); |
| 885 if (((*flags & kAltLeftButton) == kAltLeftButton) && |
| 886 ((mouse_event.type() == ui::ET_MOUSE_PRESSED) || |
| 887 pressed_device_ids_.count(mouse_event.source_device_id()))) { |
| 888 *flags &= ~kAltLeftButton; |
| 889 *flags |= ui::EF_RIGHT_MOUSE_BUTTON; |
| 890 if (mouse_event.type() == ui::ET_MOUSE_PRESSED) |
| 891 pressed_device_ids_.insert(mouse_event.source_device_id()); |
| 892 else |
| 893 pressed_device_ids_.erase(mouse_event.source_device_id()); |
| 894 return ui::EF_RIGHT_MOUSE_BUTTON; |
| 895 } |
| 896 return ui::EF_NONE; |
| 897 } |
| 898 |
| 899 EventRewriter::DeviceType EventRewriter::KeyboardDeviceAddedInternal( |
| 877 int device_id, | 900 int device_id, |
| 878 const std::string& device_name) { | 901 const std::string& device_name) { |
| 879 const DeviceType type = GetDeviceType(device_name); | 902 const DeviceType type = GetDeviceType(device_name); |
| 880 if (type == kDeviceAppleKeyboard) { | 903 if (type == kDeviceAppleKeyboard) { |
| 881 VLOG(1) << "Apple keyboard '" << device_name << "' connected: " | 904 VLOG(1) << "Apple keyboard '" << device_name << "' connected: " |
| 882 << "id=" << device_id; | 905 << "id=" << device_id; |
| 883 } | 906 } |
| 884 // Always overwrite the existing device_id since the X server may reuse a | 907 // Always overwrite the existing device_id since the X server may reuse a |
| 885 // device id for an unattached device. | 908 // device id for an unattached device. |
| 886 device_id_to_type_[device_id] = type; | 909 device_id_to_type_[device_id] = type; |
| 887 return type; | 910 return type; |
| 888 } | 911 } |
| 889 | 912 |
| 913 void EventRewriter::KeyboardDeviceAdded(int device_id) { |
| 890 #if defined(USE_X11) | 914 #if defined(USE_X11) |
| 891 void EventRewriter::WillProcessEvent(const ui::PlatformEvent& event) { | |
| 892 XEvent* xevent = event; | |
| 893 if (xevent->type == GenericEvent) { | |
| 894 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data); | |
| 895 if (xievent->evtype == XI_KeyPress || xievent->evtype == XI_KeyRelease) { | |
| 896 if (xievent->deviceid == xievent->sourceid) | |
| 897 DeviceKeyPressedOrReleased(xievent->deviceid); | |
| 898 } | |
| 899 } | |
| 900 } | |
| 901 | |
| 902 void EventRewriter::DidProcessEvent(const ui::PlatformEvent& event) { | |
| 903 } | |
| 904 | |
| 905 void EventRewriter::DeviceHierarchyChanged() { | |
| 906 } | |
| 907 | |
| 908 void EventRewriter::DeviceAdded(int device_id) { | |
| 909 DCHECK_NE(XIAllDevices, device_id); | 915 DCHECK_NE(XIAllDevices, device_id); |
| 910 DCHECK_NE(XIAllMasterDevices, device_id); | 916 DCHECK_NE(XIAllMasterDevices, device_id); |
| 911 if (device_id == XIAllDevices || device_id == XIAllMasterDevices) { | 917 if (device_id == XIAllDevices || device_id == XIAllMasterDevices) { |
| 912 LOG(ERROR) << "Unexpected device_id passed: " << device_id; | 918 LOG(ERROR) << "Unexpected device_id passed: " << device_id; |
| 913 return; | 919 return; |
| 914 } | 920 } |
| 915 | 921 |
| 916 int ndevices_return = 0; | 922 int ndevices_return = 0; |
| 917 XIDeviceInfo* device_info = | 923 XIDeviceInfo* device_info = |
| 918 XIQueryDevice(gfx::GetXDisplay(), device_id, &ndevices_return); | 924 XIQueryDevice(gfx::GetXDisplay(), device_id, &ndevices_return); |
| 919 | 925 |
| 920 // Since |device_id| is neither XIAllDevices nor XIAllMasterDevices, | 926 // Since |device_id| is neither XIAllDevices nor XIAllMasterDevices, |
| 921 // the number of devices found should be either 0 (not found) or 1. | 927 // the number of devices found should be either 0 (not found) or 1. |
| 922 if (!device_info) { | 928 if (!device_info) { |
| 923 LOG(ERROR) << "XIQueryDevice: Device ID " << device_id << " is unknown."; | 929 LOG(ERROR) << "XIQueryDevice: Device ID " << device_id << " is unknown."; |
| 924 return; | 930 return; |
| 925 } | 931 } |
| 926 | 932 |
| 927 DCHECK_EQ(1, ndevices_return); | 933 DCHECK_EQ(1, ndevices_return); |
| 928 for (int i = 0; i < ndevices_return; ++i) { | 934 for (int i = 0; i < ndevices_return; ++i) { |
| 929 DCHECK_EQ(device_id, device_info[i].deviceid); // see the comment above. | 935 DCHECK_EQ(device_id, device_info[i].deviceid); // see the comment above. |
| 930 DCHECK(device_info[i].name); | 936 DCHECK(device_info[i].name); |
| 931 DeviceAddedInternal(device_info[i].deviceid, device_info[i].name); | 937 KeyboardDeviceAddedInternal(device_info[i].deviceid, device_info[i].name); |
| 932 } | 938 } |
| 933 | 939 |
| 934 XIFreeDeviceInfo(device_info); | 940 XIFreeDeviceInfo(device_info); |
| 941 #else |
| 942 KeyboardDeviceAddedInternal(device_id, "keyboard"); |
| 943 #endif |
| 935 } | 944 } |
| 936 | 945 |
| 937 void EventRewriter::DeviceRemoved(int device_id) { | |
| 938 device_id_to_type_.erase(device_id); | |
| 939 } | |
| 940 #endif | |
| 941 | |
| 942 } // namespace chromeos | 946 } // namespace chromeos |
| OLD | NEW |