Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/cpp/webdriver-interactions/interactions_linux_common.cpp
2867 views
1
/*
2
Copyright 2007-2010 WebDriver committers
3
Copyright 2007-2010 Google Inc.
4
5
Licensed under the Apache License, Version 2.0 (the "License");
6
you may not use this file except in compliance with the License.
7
You may obtain a copy of the License at
8
9
http://www.apache.org/licenses/LICENSE-2.0
10
11
Unless required by applicable law or agreed to in writing, software
12
distributed under the License is distributed on an "AS IS" BASIS,
13
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
See the License for the specific language governing permissions and
15
limitations under the License.
16
*/
17
18
#include <ctime>
19
#include <string>
20
#include <iostream>
21
#include <fstream>
22
23
#include "interactions.h"
24
#include "logging.h"
25
26
#include <gdk/gdk.h>
27
#include <gdk/gdkkeysyms.h>
28
#include <X11/Xlib.h>
29
#include <time.h>
30
#include <stdlib.h>
31
#include <assert.h>
32
#include <list>
33
#include <algorithm>
34
#include <functional>
35
36
#include "translate_keycode_linux.h"
37
#include "interactions_linux.h"
38
39
using namespace std;
40
41
guint32 gLatestEventTime = 0;
42
43
// This is the timestamp needed in the GDK events.
44
guint32 TimeSinceBootMsec()
45
{
46
struct timespec clk_tm;
47
const int msec_nsec_factor = 1000000;
48
const int sec_msec_factor = 1000;
49
50
int clk_ret = clock_gettime(CLOCK_MONOTONIC, &clk_tm);
51
if (clk_ret == 0)
52
{
53
return (clk_tm.tv_sec * sec_msec_factor +
54
(clk_tm.tv_nsec / msec_nsec_factor));
55
}
56
return 0;
57
}
58
59
void sleep_for_ms(int sleep_time_ms)
60
{
61
struct timespec sleep_time;
62
sleep_time.tv_sec = sleep_time_ms / 1000;
63
sleep_time.tv_nsec = (sleep_time_ms % 1000) * 1000000;
64
nanosleep(&sleep_time, NULL);
65
}
66
67
bool is_gdk_keyboard_event(GdkEvent* ev)
68
{
69
return ((ev->type == GDK_KEY_PRESS) || (ev->type == GDK_KEY_RELEASE));
70
}
71
72
bool is_gdk_mouse_event(GdkEvent* ev)
73
{
74
return ((ev->type == GDK_BUTTON_PRESS) || (ev->type == GDK_BUTTON_RELEASE) ||
75
(ev->type == GDK_MOTION_NOTIFY) || (ev->type == GDK_2BUTTON_PRESS));
76
}
77
78
bool event_earlier_than(GdkEvent* ev, guint32 compare_time)
79
{
80
assert(is_gdk_keyboard_event(ev) || is_gdk_mouse_event(ev));
81
return (ev->key.time <= compare_time);
82
}
83
84
void print_key_event(GdkEvent* p_ev)
85
{
86
if (!((p_ev->type == GDK_KEY_PRESS) || (p_ev->type == GDK_KEY_RELEASE))) {
87
LOG(DEBUG) << "Not a key event.";
88
return;
89
}
90
const gchar* gdk_name = gdk_keyval_name(p_ev->key.keyval);
91
const char* kNameUnknown = "UNKNOWN";
92
const char* print_name = (gdk_name != NULL ? gdk_name : kNameUnknown);
93
94
std::string ev_type = (p_ev->type == GDK_KEY_PRESS ? "press" : "release");
95
LOG(DEBUG) << "Type: " << ev_type << "Key code: " << p_ev->key.keyval <<
96
" (" << print_name << ") time: " <<
97
p_ev->key.time << " state: " << p_ev->key.state << " hw keycode: "
98
<< (int) p_ev->key.hardware_keycode << " ";
99
}
100
101
bool additional_events_to_wait_for(GdkEvent* p_event)
102
{
103
return ((p_event->type == GDK_LEAVE_NOTIFY) ||
104
(p_event->type == GDK_ENTER_NOTIFY));
105
106
}
107
108
void init_logging()
109
{
110
#ifdef INTERACTIONS_DEBUG
111
static bool log_initalized = false;
112
if (!log_initalized) {
113
LOG::Level("DEBUG");
114
LOG::File(INTERACTIONS_LOG_FILE, "a");
115
log_initalized = true;
116
}
117
#endif
118
}
119
120
extern "C"
121
{
122
bool pending_input_events()
123
{
124
LOG(DEBUG) << "Waiting for all events to be processed. Latest: " << gLatestEventTime;
125
GdkEvent* lastEvent = gdk_event_peek();
126
LOG(DEBUG) << "Got event: " <<
127
(lastEvent != NULL ? lastEvent->type : 0);
128
if ((lastEvent != NULL) && is_gdk_keyboard_event(lastEvent)) {
129
print_key_event(lastEvent);
130
}
131
132
bool ret_val = false;
133
if (lastEvent != NULL &&
134
(((is_gdk_keyboard_event(lastEvent) || is_gdk_mouse_event(lastEvent)) &&
135
event_earlier_than(lastEvent, gLatestEventTime))
136
|| (additional_events_to_wait_for(lastEvent)))) {
137
ret_val = true;
138
}
139
140
if (lastEvent != NULL) {
141
gdk_event_free(lastEvent);
142
}
143
LOG(DEBUG) << "Returning: " << ret_val;
144
145
return ret_val;
146
}
147
148
// Does nothing on Linux
149
void stopPersistentEventFiring()
150
{
151
}
152
153
void setEnablePersistentHover(bool enablePersistentHover)
154
{
155
}
156
157
}
158
159