#include <X11/extensions/XInput.h>
#include <X11/extensions/XInput2.h>
#include <X11/extensions/XIproto.h>
-#include <string>
#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
+#include "base/sys_info.h"
#include "ui/events/event_switches.h"
-#include "ui/events/x/device_data_manager.h"
+#include "ui/events/x/device_data_manager_x11.h"
#include "ui/events/x/device_list_cache_x.h"
#include "ui/gfx/x/x11_types.h"
touch_events_disabled_(false),
touch_device_list_(),
max_touch_points_(-1),
+ virtual_core_keyboard_device_(-1),
id_generator_(0) {
- if (!DeviceDataManager::GetInstance()->IsXInput2Available())
+ if (!DeviceDataManagerX11::GetInstance()->IsXInput2Available())
return;
XDisplay* display = gfx::GetXDisplay();
// old version of query function (XListInputDevices) is used instead.
// If XInput2 is not supported, this will return null (with count of -1) so
// we assume there cannot be any touch devices.
- // With XI2.1 or older, we allow only single touch devices unless
- // |enable_xi2_mt| is turned on.
+ // With XI2.1 or older, we allow only single touch devices.
XDeviceList dev_list =
DeviceListCacheX::GetInstance()->GetXDeviceList(display);
-#if !defined(ENABLE_XI21_MT)
Atom xi_touchscreen = XInternAtom(display, XI_TOUCHSCREEN, false);
-#else
- // Certain Samsung and Intel devices support multi-touch with XInput2.1
- // using the device type "MULTITOUCHSCREEN".
- Atom xi_touchscreen = XInternAtom(display, "MULTITOUCHSCREEN", false);
-#endif
for (int i = 0; i < dev_list.count; i++) {
if (dev_list[i].type == xi_touchscreen) {
touch_device_lookup_[dev_list[i].id] = true;
}
#endif
- if (!DeviceDataManager::GetInstance()->IsXInput2Available())
+ if (!DeviceDataManagerX11::GetInstance()->IsXInput2Available())
return;
// Instead of asking X for the list of devices all the time, let's maintain a
XIAnyClassInfo* xiclassinfo = devinfo->classes[k];
if (xiclassinfo->type == XITouchClass) {
XITouchClassInfo* tci =
- reinterpret_cast<XITouchClassInfo *>(xiclassinfo);
+ reinterpret_cast<XITouchClassInfo*>(xiclassinfo);
// Only care direct touch device (such as touch screen) right now
if (tci->mode == XIDirectTouch) {
- CacheTouchscreenIds(display, devinfo->deviceid);
touch_device_lookup_[devinfo->deviceid] = true;
touch_device_list_[devinfo->deviceid] = true;
touch_device_available_ = true;
}
#endif
pointer_device_lookup_[devinfo->deviceid] = true;
+ } else if (devinfo->use == XIMasterKeyboard) {
+ virtual_core_keyboard_device_ = devinfo->deviceid;
}
+
+#if defined(USE_XI2_MT)
+ if (devinfo->use == XIFloatingSlave || devinfo->use == XISlavePointer) {
+ for (int k = 0; k < devinfo->num_classes; ++k) {
+ XIAnyClassInfo* xiclassinfo = devinfo->classes[k];
+ if (xiclassinfo->type == XITouchClass) {
+ XITouchClassInfo* tci =
+ reinterpret_cast<XITouchClassInfo*>(xiclassinfo);
+ // Only care direct touch device (such as touch screen) right now
+ if (tci->mode == XIDirectTouch)
+ CacheTouchscreenIds(display, devinfo->deviceid);
+ }
+ }
+ }
+#endif
}
}
return !touch_events_disabled_ && IsTouchDevice(xiev->deviceid);
}
#endif
+ // Make sure only key-events from the virtual core keyboard are processed.
+ if (event->evtype == XI_KeyPress || event->evtype == XI_KeyRelease) {
+ return (virtual_core_keyboard_device_ < 0) ||
+ (virtual_core_keyboard_device_ == xiev->deviceid);
+ }
+
if (event->evtype != XI_ButtonPress &&
event->evtype != XI_ButtonRelease &&
event->evtype != XI_Motion)
XISetMask(mask, XI_ButtonPress);
XISetMask(mask, XI_ButtonRelease);
XISetMask(mask, XI_Motion);
+#if defined(OS_CHROMEOS)
+ if (base::SysInfo::IsRunningOnChromeOS()) {
+ XISetMask(mask, XI_KeyPress);
+ XISetMask(mask, XI_KeyRelease);
+ }
+#endif
XIEventMask evmask;
evmask.deviceid = XIAllDevices;
return id_generator_.GetGeneratedID(tracking_id);
}
+void TouchFactory::AcquireSlotForTrackingID(uint32 tracking_id) {
+ tracking_id_refcounts_[tracking_id]++;
+}
+
void TouchFactory::ReleaseSlotForTrackingID(uint32 tracking_id) {
- id_generator_.ReleaseNumber(tracking_id);
+ tracking_id_refcounts_[tracking_id]--;
+ if (tracking_id_refcounts_[tracking_id] == 0)
+ id_generator_.ReleaseNumber(tracking_id);
}
bool TouchFactory::IsTouchDevicePresent() {
return max_touch_points_;
}
+void TouchFactory::ResetForTest() {
+ pointer_device_lookup_.reset();
+ touch_device_lookup_.reset();
+ touch_device_available_ = false;
+ touch_events_disabled_ = false;
+ touch_device_list_.clear();
+ touchscreen_ids_.clear();
+ tracking_id_refcounts_.clear();
+ max_touch_points_ = -1;
+ id_generator_.ResetForTest();
+}
+
void TouchFactory::SetTouchDeviceForTest(
const std::vector<unsigned int>& devices) {
touch_device_lookup_.reset();