13551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file. 43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 53551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "media/base/user_input_monitor.h" 63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/bind.h" 8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/location.h" 9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/logging.h" 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/message_loop/message_loop.h" 11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/single_thread_task_runner.h" 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/strings/stringprintf.h" 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/synchronization/lock.h" 14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/win/message_window.h" 15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "media/base/keyboard_event_counter.h" 16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "third_party/skia/include/core/SkPoint.h" 17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/keycodes/keyboard_code_conversion_win.h" 18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace media { 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace { 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// From the HID Usage Tables specification. 23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)const USHORT kGenericDesktopPage = 1; 24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)const USHORT kMouseUsage = 2; 25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)const USHORT kKeyboardUsage = 6; 26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// This is the actual implementation of event monitoring. It's separated from 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// UserInputMonitorWin since it needs to be deleted on the UI thread. 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class UserInputMonitorWinCore 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : public base::SupportsWeakPtr<UserInputMonitorWinCore>, 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public base::MessageLoop::DestructionObserver { 32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public: 33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) enum EventBitMask { 34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) MOUSE_EVENT_MASK = 1, 35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) KEYBOARD_EVENT_MASK = 2, 36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) }; 37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) explicit UserInputMonitorWinCore( 39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, 40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const scoped_refptr<UserInputMonitor::MouseListenerList>& 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mouse_listeners); 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ~UserInputMonitorWinCore(); 43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // DestructionObserver overrides. 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void WillDestroyCurrentMessageLoop() OVERRIDE; 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) size_t GetKeyPressCount() const; 48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void StartMonitor(EventBitMask type); 49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void StopMonitor(EventBitMask type); 50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private: 52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Handles WM_INPUT messages. 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LRESULT OnInput(HRAWINPUT input_handle); 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Handles messages received by |window_|. 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool HandleMessage(UINT message, 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WPARAM wparam, 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LPARAM lparam, 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LRESULT* result); 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RAWINPUTDEVICE* GetRawInputDevices(EventBitMask event, DWORD flags); 60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Task runner on which |window_| is created. 62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; 63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_refptr<ObserverListThreadSafe<UserInputMonitor::MouseEventListener> > 64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mouse_listeners_; 65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // These members are only accessed on the UI thread. 67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<base::win::MessageWindow> window_; 68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) uint8 events_monitored_; 69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) KeyboardEventCounter counter_; 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(UserInputMonitorWinCore); 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}; 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class UserInputMonitorWin : public UserInputMonitor { 75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public: 76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) explicit UserInputMonitorWin( 77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner); 78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual ~UserInputMonitorWin(); 79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Public UserInputMonitor overrides. 81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual size_t GetKeyPressCount() const OVERRIDE; 82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private: 84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Private UserInputMonitor overrides. 85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void StartKeyboardMonitoring() OVERRIDE; 86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void StopKeyboardMonitoring() OVERRIDE; 87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void StartMouseMonitoring() OVERRIDE; 88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void StopMouseMonitoring() OVERRIDE; 89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; 91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) UserInputMonitorWinCore* core_; 92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(UserInputMonitorWin); 94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}; 95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)UserInputMonitorWinCore::UserInputMonitorWinCore( 97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, 98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const scoped_refptr<UserInputMonitor::MouseListenerList>& mouse_listeners) 99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : ui_task_runner_(ui_task_runner), 100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mouse_listeners_(mouse_listeners), 101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) events_monitored_(0) {} 102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)UserInputMonitorWinCore::~UserInputMonitorWinCore() { 104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!window_); 105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(!events_monitored_); 106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void UserInputMonitorWinCore::WillDestroyCurrentMessageLoop() { 1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(ui_task_runner_->BelongsToCurrentThread()); 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) StopMonitor(MOUSE_EVENT_MASK); 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) StopMonitor(KEYBOARD_EVENT_MASK); 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)size_t UserInputMonitorWinCore::GetKeyPressCount() const { 115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return counter_.GetKeyPressCount(); 116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void UserInputMonitorWinCore::StartMonitor(EventBitMask type) { 119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(ui_task_runner_->BelongsToCurrentThread()); 120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (events_monitored_ & type) 122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (type == KEYBOARD_EVENT_MASK) 125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) counter_.Reset(); 126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!window_) { 128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) window_.reset(new base::win::MessageWindow()); 129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!window_->Create(base::Bind(&UserInputMonitorWinCore::HandleMessage, 130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Unretained(this)))) { 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PLOG(ERROR) << "Failed to create the raw input window"; 132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) window_.reset(); 133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 137d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Register to receive raw mouse and/or keyboard input. 138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<RAWINPUTDEVICE> device(GetRawInputDevices(type, RIDEV_INPUTSINK)); 139d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!RegisterRawInputDevices(device.get(), 1, sizeof(*device))) { 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PLOG(ERROR) << "RegisterRawInputDevices() failed for RIDEV_INPUTSINK"; 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) window_.reset(); 142d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 143d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Start observing message loop destruction if we start monitoring the first 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // event. 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!events_monitored_) 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::MessageLoop::current()->AddDestructionObserver(this); 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) events_monitored_ |= type; 151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void UserInputMonitorWinCore::StopMonitor(EventBitMask type) { 154d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(ui_task_runner_->BelongsToCurrentThread()); 155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!(events_monitored_ & type)) 157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 158d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Stop receiving raw input. 160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(window_); 161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<RAWINPUTDEVICE> device(GetRawInputDevices(type, RIDEV_REMOVE)); 162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!RegisterRawInputDevices(device.get(), 1, sizeof(*device))) { 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PLOG(INFO) << "RegisterRawInputDevices() failed for RIDEV_REMOVE"; 165d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 167d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) events_monitored_ &= ~type; 1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (events_monitored_ == 0) { 169d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) window_.reset(); 1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Stop observing message loop destruction if no event is being monitored. 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::MessageLoop::current()->RemoveDestructionObserver(this); 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 175d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)LRESULT UserInputMonitorWinCore::OnInput(HRAWINPUT input_handle) { 177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(ui_task_runner_->BelongsToCurrentThread()); 178d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Get the size of the input record. 180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) UINT size = 0; 181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) UINT result = GetRawInputData( 182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) input_handle, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); 183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (result == -1) { 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PLOG(ERROR) << "GetRawInputData() failed"; 185d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return 0; 186d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 187d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_EQ(0u, result); 188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 189d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Retrieve the input record itself. 190d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<uint8[]> buffer(new uint8[size]); 191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RAWINPUT* input = reinterpret_cast<RAWINPUT*>(buffer.get()); 192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) result = GetRawInputData( 193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) input_handle, RID_INPUT, buffer.get(), &size, sizeof(RAWINPUTHEADER)); 194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (result == -1) { 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PLOG(ERROR) << "GetRawInputData() failed"; 196d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return 0; 197d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 198d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_EQ(size, result); 199d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Notify the observer about events generated locally. 201d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (input->header.dwType == RIM_TYPEMOUSE && input->header.hDevice != NULL) { 202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) POINT position; 203d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!GetCursorPos(&position)) { 204d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) position.x = 0; 205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) position.y = 0; 206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mouse_listeners_->Notify( 208d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) &UserInputMonitor::MouseEventListener::OnMouseMoved, 209d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SkIPoint::Make(position.x, position.y)); 210d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else if (input->header.dwType == RIM_TYPEKEYBOARD && 211d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) input->header.hDevice != NULL) { 212d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ui::EventType event = (input->data.keyboard.Flags & RI_KEY_BREAK) 213d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ? ui::ET_KEY_RELEASED 214d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : ui::ET_KEY_PRESSED; 215d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ui::KeyboardCode key_code = 216d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ui::KeyboardCodeForWindowsKeyCode(input->data.keyboard.VKey); 217d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) counter_.OnKeyboardEvent(event, key_code); 218d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 219d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 220d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return DefRawInputProc(&input, 1, sizeof(RAWINPUTHEADER)); 221d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 222d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool UserInputMonitorWinCore::HandleMessage(UINT message, 224d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WPARAM wparam, 225d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LPARAM lparam, 226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LRESULT* result) { 227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(ui_task_runner_->BelongsToCurrentThread()); 228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) switch (message) { 230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case WM_INPUT: 231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) *result = OnInput(reinterpret_cast<HRAWINPUT>(lparam)); 232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return true; 233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) default: 235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return false; 236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)RAWINPUTDEVICE* UserInputMonitorWinCore::GetRawInputDevices(EventBitMask event, 240d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DWORD flags) { 241d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(ui_task_runner_->BelongsToCurrentThread()); 242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 243d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<RAWINPUTDEVICE> device(new RAWINPUTDEVICE()); 244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (event == MOUSE_EVENT_MASK) { 245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) device->dwFlags = flags; 246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) device->usUsagePage = kGenericDesktopPage; 247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) device->usUsage = kMouseUsage; 248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) device->hwndTarget = window_->hwnd(); 249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else { 250d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_EQ(KEYBOARD_EVENT_MASK, event); 251d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) device->dwFlags = flags; 252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) device->usUsagePage = kGenericDesktopPage; 253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) device->usUsage = kKeyboardUsage; 254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) device->hwndTarget = window_->hwnd(); 255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return device.release(); 257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 259d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// 260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Implementation of UserInputMonitorWin. 261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// 262d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)UserInputMonitorWin::UserInputMonitorWin( 264d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) 265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : ui_task_runner_(ui_task_runner), 266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) core_(new UserInputMonitorWinCore(ui_task_runner, mouse_listeners())) {} 267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 268d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)UserInputMonitorWin::~UserInputMonitorWin() { 269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!ui_task_runner_->DeleteSoon(FROM_HERE, core_)) 270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) delete core_; 271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)size_t UserInputMonitorWin::GetKeyPressCount() const { 274d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return core_->GetKeyPressCount(); 275d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void UserInputMonitorWin::StartKeyboardMonitoring() { 278d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ui_task_runner_->PostTask( 279d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FROM_HERE, 280d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&UserInputMonitorWinCore::StartMonitor, 281d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) core_->AsWeakPtr(), 282d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) UserInputMonitorWinCore::KEYBOARD_EVENT_MASK)); 283d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 284d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 285d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void UserInputMonitorWin::StopKeyboardMonitoring() { 286d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ui_task_runner_->PostTask( 287d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FROM_HERE, 288d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&UserInputMonitorWinCore::StopMonitor, 289d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) core_->AsWeakPtr(), 290d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) UserInputMonitorWinCore::KEYBOARD_EVENT_MASK)); 291d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 292d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 293d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void UserInputMonitorWin::StartMouseMonitoring() { 294d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ui_task_runner_->PostTask( 295d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FROM_HERE, 296d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&UserInputMonitorWinCore::StartMonitor, 297d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) core_->AsWeakPtr(), 298d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) UserInputMonitorWinCore::MOUSE_EVENT_MASK)); 299d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 300d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 301d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void UserInputMonitorWin::StopMouseMonitoring() { 302d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ui_task_runner_->PostTask( 303d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FROM_HERE, 304d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&UserInputMonitorWinCore::StopMonitor, 305d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) core_->AsWeakPtr(), 306d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) UserInputMonitorWinCore::MOUSE_EVENT_MASK)); 307d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 308d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 309d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} // namespace 3103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<UserInputMonitor> UserInputMonitor::Create( 312d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, 3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) { 314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return scoped_ptr<UserInputMonitor>(new UserInputMonitorWin(ui_task_runner)); 3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} // namespace media 318