1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/logging.h"
6 #include "ui/base/x/x11_util.h"
7 #include "ui/events/devices/x11/device_data_manager_x11.h"
8 #include "ui/views/widget/desktop_aura/x11_pointer_grab.h"
10 #include <X11/extensions/XInput2.h>
17 // The grab window. None if there are no active pointer grabs.
18 XID g_grab_window
= None
;
20 // The "owner events" parameter used to grab the pointer.
21 bool g_owner_events
= false;
25 int GrabPointer(XID window
, bool owner_events
, ::Cursor cursor
) {
26 int result
= GrabInvalidTime
;
27 if (ui::IsXInput2Available()) {
28 // Do an XInput2 pointer grab. If there is an active XInput2 pointer grab
29 // as a result of normal button press, XGrabPointer() will fail.
30 unsigned char mask
[XIMaskLen(XI_LASTEVENT
)];
31 memset(mask
, 0, sizeof(mask
));
32 XISetMask(mask
, XI_ButtonPress
);
33 XISetMask(mask
, XI_ButtonRelease
);
34 XISetMask(mask
, XI_Motion
);
36 evmask
.mask_len
= sizeof(mask
);
39 const std::vector
<int>& master_pointers
=
40 ui::DeviceDataManagerX11::GetInstance()->master_pointers();
41 for (int master_pointer
: master_pointers
) {
42 evmask
.deviceid
= master_pointer
;
43 result
= XIGrabDevice(
44 gfx::GetXDisplay(), master_pointer
, window
, CurrentTime
, cursor
,
45 GrabModeAsync
, GrabModeAsync
, owner_events
, &evmask
);
46 // Assume that the grab will succeed on either all or none of the master
48 if (result
!= GrabSuccess
) {
49 // Try core pointer grab.
55 if (result
!= GrabSuccess
) {
56 int event_mask
= PointerMotionMask
| ButtonReleaseMask
| ButtonPressMask
;
58 XGrabPointer(gfx::GetXDisplay(), window
, owner_events
, event_mask
,
59 GrabModeAsync
, GrabModeAsync
, None
, cursor
, CurrentTime
);
62 if (result
== GrabSuccess
) {
63 g_grab_window
= window
;
64 g_owner_events
= owner_events
;
69 void ChangeActivePointerGrabCursor(::Cursor cursor
) {
70 DCHECK(g_grab_window
!= None
);
71 GrabPointer(g_grab_window
, g_owner_events
, cursor
);
74 void UngrabPointer() {
76 if (ui::IsXInput2Available()) {
77 const std::vector
<int>& master_pointers
=
78 ui::DeviceDataManagerX11::GetInstance()->master_pointers();
79 for (int master_pointer
: master_pointers
)
80 XIUngrabDevice(gfx::GetXDisplay(), master_pointer
, CurrentTime
);
82 // Try core pointer ungrab in case the XInput2 pointer ungrab failed.
83 XUngrabPointer(gfx::GetXDisplay(), CurrentTime
);