// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/aura/dispatcher_linux.h" #include #include "ui/base/events.h" namespace aura { DispatcherLinux::DispatcherLinux() : x_root_window_( DefaultRootWindow(base::MessagePumpAuraX11::GetDefaultXDisplay())) { base::MessagePumpAuraX11::SetDefaultDispatcher(this); MessageLoopForUI::current()->AddObserver(this); } DispatcherLinux::~DispatcherLinux() { MessageLoopForUI::current()->RemoveObserver(this); base::MessagePumpAuraX11::SetDefaultDispatcher(NULL); } void DispatcherLinux::AddDispatcherForWindow( MessageLoop::Dispatcher* dispatcher, ::Window x_window) { dispatchers_.insert(std::make_pair(x_window, dispatcher)); } void DispatcherLinux::RemoveDispatcherForWindow(::Window x_window) { dispatchers_.erase(x_window); } void DispatcherLinux::AddDispatcherForRootWindow( MessageLoop::Dispatcher* dispatcher) { DCHECK(std::find(root_window_dispatchers_.begin(), root_window_dispatchers_.end(), dispatcher) == root_window_dispatchers_.end()); root_window_dispatchers_.push_back(dispatcher); } void DispatcherLinux::RemoveDispatcherForRootWindow( MessageLoop::Dispatcher* dispatcher) { root_window_dispatchers_.erase( std::remove(root_window_dispatchers_.begin(), root_window_dispatchers_.end(), dispatcher)); } bool DispatcherLinux::Dispatch(const base::NativeEvent& xev) { // XI_HierarchyChanged events are special. There is no window associated with // these events. So process them directly from here. if (xev->type == GenericEvent && xev->xgeneric.evtype == XI_HierarchyChanged) { ui::UpdateDeviceList(); return true; } // MappingNotify events (meaning that the keyboard or pointer buttons have // been remapped) aren't associated with a window; send them to all // dispatchers. if (xev->type == MappingNotify) { for (DispatchersMap::const_iterator it = dispatchers_.begin(); it != dispatchers_.end(); ++it) { it->second->Dispatch(xev); } return true; } if (xev->xany.window == x_root_window_) { for (Dispatchers::const_iterator it = root_window_dispatchers_.begin(); it != root_window_dispatchers_.end(); ++it) { (*it)->Dispatch(xev); } return true; } MessageLoop::Dispatcher* dispatcher = GetDispatcherForXEvent(xev); return dispatcher ? dispatcher->Dispatch(xev) : true; } base::EventStatus DispatcherLinux::WillProcessEvent( const base::NativeEvent& event) { return base::EVENT_CONTINUE; } void DispatcherLinux::DidProcessEvent(const base::NativeEvent& event) { } MessageLoop::Dispatcher* DispatcherLinux::GetDispatcherForXEvent( XEvent* xev) const { ::Window x_window = xev->xany.window; if (xev->type == GenericEvent) { XIDeviceEvent* xievent = static_cast(xev->xcookie.data); x_window = xievent->event; } DispatchersMap::const_iterator it = dispatchers_.find(x_window); return it != dispatchers_.end() ? it->second : NULL; } MessageLoop::Dispatcher* CreateDispatcher() { return new DispatcherLinux; } } // namespace aura