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
);
35 XISetMask(mask
, XI_TouchBegin
);
36 XISetMask(mask
, XI_TouchUpdate
);
37 XISetMask(mask
, XI_TouchEnd
);
39 evmask
.mask_len
= sizeof(mask
);
42 const std::vector
<int>& master_pointers
=
43 ui::DeviceDataManagerX11::GetInstance()->master_pointers();
44 for (int master_pointer
: master_pointers
) {
45 evmask
.deviceid
= master_pointer
;
46 result
= XIGrabDevice(
47 gfx::GetXDisplay(), master_pointer
, window
, CurrentTime
, cursor
,
48 GrabModeAsync
, GrabModeAsync
, owner_events
, &evmask
);
49 // Assume that the grab will succeed on either all or none of the master
51 if (result
!= GrabSuccess
) {
52 // Try core pointer grab.
58 if (result
!= GrabSuccess
) {
59 int event_mask
= PointerMotionMask
| ButtonReleaseMask
| ButtonPressMask
;
61 XGrabPointer(gfx::GetXDisplay(), window
, owner_events
, event_mask
,
62 GrabModeAsync
, GrabModeAsync
, None
, cursor
, CurrentTime
);
65 if (result
== GrabSuccess
) {
66 g_grab_window
= window
;
67 g_owner_events
= owner_events
;
72 void ChangeActivePointerGrabCursor(::Cursor cursor
) {
73 DCHECK(g_grab_window
!= None
);
74 GrabPointer(g_grab_window
, g_owner_events
, cursor
);
77 void UngrabPointer() {
79 if (ui::IsXInput2Available()) {
80 const std::vector
<int>& master_pointers
=
81 ui::DeviceDataManagerX11::GetInstance()->master_pointers();
82 for (int master_pointer
: master_pointers
)
83 XIUngrabDevice(gfx::GetXDisplay(), master_pointer
, CurrentTime
);
85 // Try core pointer ungrab in case the XInput2 pointer ungrab failed.
86 XUngrabPointer(gfx::GetXDisplay(), CurrentTime
);