1 // Copyright 2019 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.
4 
5 #include "components/exo/wayland/serial_tracker.h"
6 
7 #include <wayland-server-core.h>
8 
9 namespace exo {
10 namespace wayland {
11 
12 namespace {
13 
14 // Number of previous events to retain information about.
15 constexpr uint32_t kMaxEventsTracked = 1024;
16 
17 }  // namespace
18 
SerialTracker(struct wl_display * display)19 SerialTracker::SerialTracker(struct wl_display* display)
20     : display_(display), events_(kMaxEventsTracked) {}
21 
~SerialTracker()22 SerialTracker::~SerialTracker() {}
23 
GetNextSerial(EventType type)24 uint32_t SerialTracker::GetNextSerial(EventType type) {
25   uint32_t serial = wl_display_next_serial(display_);
26   events_[serial % kMaxEventsTracked] = type;
27   max_event_ = serial + 1;
28   if ((max_event_ - min_event_) > kMaxEventsTracked)
29     min_event_ = max_event_ - kMaxEventsTracked;
30 
31   switch (type) {
32     case EventType::POINTER_BUTTON_DOWN:
33       pointer_down_serial_ = serial;
34       break;
35     case EventType::POINTER_BUTTON_UP:
36       pointer_down_serial_ = base::nullopt;
37       break;
38     case EventType::TOUCH_DOWN:
39       touch_down_serial_ = serial;
40       break;
41     case EventType::TOUCH_UP:
42       touch_down_serial_ = base::nullopt;
43       break;
44     default:
45       break;
46   }
47 
48   return serial;
49 }
50 
GetEventType(uint32_t serial) const51 base::Optional<SerialTracker::EventType> SerialTracker::GetEventType(
52     uint32_t serial) const {
53   if (max_event_ < min_event_) {
54     // The valid range has partially overflowed the 32 bit space, so we should
55     // only reject if the serial number is in neither the upper nor lower parts
56     // of the space.
57     if (!((serial < max_event_) || (serial >= min_event_)))
58       return base::nullopt;
59   } else {
60     // Normal, non-overflowed case. Reject the serial number if it isn't in the
61     // interval.
62     if (!((serial < max_event_) && (serial >= min_event_)))
63       return base::nullopt;
64   }
65 
66   return events_[serial % kMaxEventsTracked];
67 }
68 
GetPointerDownSerial()69 base::Optional<uint32_t> SerialTracker::GetPointerDownSerial() {
70   return pointer_down_serial_;
71 }
72 
GetTouchDownSerial()73 base::Optional<uint32_t> SerialTracker::GetTouchDownSerial() {
74   return touch_down_serial_;
75 }
76 
ResetTouchDownSerial()77 void SerialTracker::ResetTouchDownSerial() {
78   touch_down_serial_ = base::nullopt;
79 }
80 
81 }  // namespace wayland
82 }  // namespace exo
83