1 /*
2 * Copyright © 2012 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26 #include "config.h"
27
28 #include <stdint.h>
29
30 #include "input-timestamps-helper.h"
31 #include "shared/timespec-util.h"
32 #include "weston-test-client-helper.h"
33 #include "weston-test-fixture-compositor.h"
34
35 static enum test_result_code
fixture_setup(struct weston_test_harness * harness)36 fixture_setup(struct weston_test_harness *harness)
37 {
38 struct compositor_setup setup;
39
40 compositor_setup_defaults(&setup);
41
42 return weston_test_harness_execute_as_client(harness, &setup);
43 }
44 DECLARE_FIXTURE_SETUP(fixture_setup);
45
46 static const struct timespec t1 = { .tv_sec = 1, .tv_nsec = 1000001 };
47 static const struct timespec t2 = { .tv_sec = 2, .tv_nsec = 2000001 };
48 static const struct timespec t_other = { .tv_sec = 123, .tv_nsec = 456 };
49
50 static struct client *
create_client_with_keyboard_focus(void)51 create_client_with_keyboard_focus(void)
52 {
53 struct client *cl = create_client_and_test_surface(10, 10, 1, 1);
54 assert(cl);
55
56 weston_test_activate_surface(cl->test->weston_test,
57 cl->surface->wl_surface);
58 client_roundtrip(cl);
59
60 return cl;
61 }
62
63 static void
send_key(struct client * client,const struct timespec * time,uint32_t key,uint32_t state)64 send_key(struct client *client, const struct timespec *time,
65 uint32_t key, uint32_t state)
66 {
67 uint32_t tv_sec_hi, tv_sec_lo, tv_nsec;
68
69 timespec_to_proto(time, &tv_sec_hi, &tv_sec_lo, &tv_nsec);
70 weston_test_send_key(client->test->weston_test, tv_sec_hi, tv_sec_lo,
71 tv_nsec, key, state);
72 client_roundtrip(client);
73 }
74
TEST(simple_keyboard_test)75 TEST(simple_keyboard_test)
76 {
77 struct client *client = create_client_with_keyboard_focus();
78 struct keyboard *keyboard = client->input->keyboard;
79 struct surface *expect_focus = client->surface;
80 uint32_t expect_key = 0;
81 uint32_t expect_state = 0;
82
83 while (1) {
84 assert(keyboard->key == expect_key);
85 assert(keyboard->state == expect_state);
86 assert(keyboard->focus == expect_focus);
87
88 if (keyboard->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
89 expect_state = WL_KEYBOARD_KEY_STATE_RELEASED;
90 send_key(client, &t1, expect_key, expect_state);
91 } else if (keyboard->focus) {
92 expect_focus = NULL;
93 weston_test_activate_surface(
94 client->test->weston_test, NULL);
95 client_roundtrip(client);
96 } else if (expect_key < 10) {
97 expect_key++;
98 expect_focus = client->surface;
99 expect_state = WL_KEYBOARD_KEY_STATE_PRESSED;
100 weston_test_activate_surface(
101 client->test->weston_test,
102 expect_focus->wl_surface);
103 send_key(client, &t1, expect_key, expect_state);
104 } else {
105 break;
106 }
107 }
108 }
109
TEST(keyboard_key_event_time)110 TEST(keyboard_key_event_time)
111 {
112 struct client *client = create_client_with_keyboard_focus();
113 struct keyboard *keyboard = client->input->keyboard;
114 struct input_timestamps *input_ts =
115 input_timestamps_create_for_keyboard(client);
116
117 send_key(client, &t1, 1, WL_KEYBOARD_KEY_STATE_PRESSED);
118 assert(keyboard->key_time_msec == timespec_to_msec(&t1));
119 assert(timespec_eq(&keyboard->key_time_timespec, &t1));
120
121 send_key(client, &t2, 1, WL_KEYBOARD_KEY_STATE_RELEASED);
122 assert(keyboard->key_time_msec == timespec_to_msec(&t2));
123 assert(timespec_eq(&keyboard->key_time_timespec, &t2));
124
125 input_timestamps_destroy(input_ts);
126 }
127
TEST(keyboard_timestamps_stop_after_input_timestamps_object_is_destroyed)128 TEST(keyboard_timestamps_stop_after_input_timestamps_object_is_destroyed)
129 {
130 struct client *client = create_client_with_keyboard_focus();
131 struct keyboard *keyboard = client->input->keyboard;
132 struct input_timestamps *input_ts =
133 input_timestamps_create_for_keyboard(client);
134
135 send_key(client, &t1, 1, WL_KEYBOARD_KEY_STATE_PRESSED);
136 assert(keyboard->key_time_msec == timespec_to_msec(&t1));
137 assert(timespec_eq(&keyboard->key_time_timespec, &t1));
138
139 input_timestamps_destroy(input_ts);
140
141 send_key(client, &t2, 1, WL_KEYBOARD_KEY_STATE_RELEASED);
142 assert(keyboard->key_time_msec == timespec_to_msec(&t2));
143 assert(timespec_is_zero(&keyboard->key_time_timespec));
144 }
145
TEST(keyboard_timestamps_stop_after_client_releases_wl_keyboard)146 TEST(keyboard_timestamps_stop_after_client_releases_wl_keyboard)
147 {
148 struct client *client = create_client_with_keyboard_focus();
149 struct keyboard *keyboard = client->input->keyboard;
150 struct input_timestamps *input_ts =
151 input_timestamps_create_for_keyboard(client);
152
153 send_key(client, &t1, 1, WL_KEYBOARD_KEY_STATE_PRESSED);
154 assert(keyboard->key_time_msec == timespec_to_msec(&t1));
155 assert(timespec_eq(&keyboard->key_time_timespec, &t1));
156
157 wl_keyboard_release(client->input->keyboard->wl_keyboard);
158
159 /* Set input_timestamp to an arbitrary value (different from t1, t2
160 * and 0) and check that it is not changed by sending the event.
161 * This is preferred over just checking for 0, since 0 is used
162 * internally for resetting the timestamp after handling an input
163 * event and checking for it here may lead to false negatives. */
164 keyboard->input_timestamp = t_other;
165 send_key(client, &t2, 1, WL_KEYBOARD_KEY_STATE_RELEASED);
166 assert(timespec_eq(&keyboard->input_timestamp, &t_other));
167
168 input_timestamps_destroy(input_ts);
169 }
170