10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 20529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 30529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// found in the LICENSE file. 40529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ui/events/platform/x11/x11_event_source.h" 60529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include <glib.h> 80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include <X11/Xlib.h> 90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace ui { 110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace { 130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstruct GLibX11Source : public GSource { 150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Note: The GLibX11Source is created and destroyed by GLib. So its 160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // constructor/destructor may or may not get called. 170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch XDisplay* display; 180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GPollFD* poll_fd; 190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}; 200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochgboolean XSourcePrepare(GSource* source, gint* timeout_ms) { 220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GLibX11Source* gxsource = static_cast<GLibX11Source*>(source); 230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (XPending(gxsource->display)) 240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch *timeout_ms = 0; 250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch else 260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch *timeout_ms = -1; 270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return FALSE; 280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochgboolean XSourceCheck(GSource* source) { 310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GLibX11Source* gxsource = static_cast<GLibX11Source*>(source); 320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return XPending(gxsource->display); 330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochgboolean XSourceDispatch(GSource* source, 360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GSourceFunc unused_func, 370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch gpointer data) { 380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch X11EventSource* x11_source = static_cast<X11EventSource*>(data); 390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch x11_source->DispatchXEvents(); 400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return TRUE; 410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 430529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochGSourceFuncs XSourceFuncs = { 440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch XSourcePrepare, 450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch XSourceCheck, 460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch XSourceDispatch, 470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch NULL 480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}; 490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass X11EventSourceGlib : public X11EventSource { 510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public: 520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch explicit X11EventSourceGlib(XDisplay* display) 530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch : X11EventSource(display), 540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch x_source_(NULL) { 550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch InitXSource(ConnectionNumber(display)); 560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual ~X11EventSourceGlib() { 590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch g_source_destroy(x_source_); 600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch g_source_unref(x_source_); 610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private: 640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void InitXSource(int fd) { 650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch CHECK(!x_source_); 660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch CHECK(display()) << "Unable to get connection to X server"; 670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch x_poll_.reset(new GPollFD()); 690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch x_poll_->fd = fd; 700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch x_poll_->events = G_IO_IN; 710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch x_poll_->revents = 0; 720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GLibX11Source* glib_x_source = static_cast<GLibX11Source*> 740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch (g_source_new(&XSourceFuncs, sizeof(GLibX11Source))); 750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch glib_x_source->display = display(); 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch glib_x_source->poll_fd = x_poll_.get(); 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch x_source_ = glib_x_source; 790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch g_source_add_poll(x_source_, x_poll_.get()); 800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch g_source_set_can_recurse(x_source_, TRUE); 810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch g_source_set_callback(x_source_, NULL, this, NULL); 820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch g_source_attach(x_source_, g_main_context_default()); 830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // The GLib event source for X events. 860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch GSource* x_source_; 870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // The poll attached to |x_source_|. 890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<GPollFD> x_poll_; 900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DISALLOW_COPY_AND_ASSIGN(X11EventSourceGlib); 920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}; 930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} // namespace 950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochscoped_ptr<PlatformEventSource> PlatformEventSource::CreateDefault() { 970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return scoped_ptr<PlatformEventSource>( 980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch new X11EventSourceGlib(gfx::GetXDisplay())); 990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} // namespace ui 102