2010-10-14 21:07:36 +00:00
|
|
|
/*
|
|
|
|
|
Copyright 2007-2010 WebDriver committers
|
|
|
|
|
Copyright 2007-2010 Google Inc.
|
|
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
|
limitations under the License.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <ctime>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
|
|
#include "interactions.h"
|
|
|
|
|
#include "logging.h"
|
|
|
|
|
|
|
|
|
|
#include <gdk/gdk.h>
|
|
|
|
|
#include <gdk/gdkkeysyms.h>
|
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
|
#include <time.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <list>
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <functional>
|
|
|
|
|
|
|
|
|
|
#include "translate_keycode_linux.h"
|
|
|
|
|
#include "interactions_linux.h"
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
guint32 gLatestEventTime = 0;
|
|
|
|
|
|
|
|
|
|
// This is the timestamp needed in the GDK events.
|
|
|
|
|
guint32 TimeSinceBootMsec()
|
|
|
|
|
{
|
|
|
|
|
struct timespec clk_tm;
|
|
|
|
|
const int msec_nsec_factor = 1000000;
|
|
|
|
|
const int sec_msec_factor = 1000;
|
|
|
|
|
|
|
|
|
|
int clk_ret = clock_gettime(CLOCK_MONOTONIC, &clk_tm);
|
|
|
|
|
if (clk_ret == 0)
|
|
|
|
|
{
|
|
|
|
|
return (clk_tm.tv_sec * sec_msec_factor +
|
|
|
|
|
(clk_tm.tv_nsec / msec_nsec_factor));
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-05 18:03:39 +00:00
|
|
|
void sleep_for_ms(int sleep_time_ms)
|
|
|
|
|
{
|
|
|
|
|
struct timespec sleep_time;
|
|
|
|
|
sleep_time.tv_sec = sleep_time_ms / 1000;
|
|
|
|
|
sleep_time.tv_nsec = (sleep_time_ms % 1000) * 1000000;
|
|
|
|
|
nanosleep(&sleep_time, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-14 21:07:36 +00:00
|
|
|
bool is_gdk_keyboard_event(GdkEvent* ev)
|
|
|
|
|
{
|
|
|
|
|
return ((ev->type == GDK_KEY_PRESS) || (ev->type == GDK_KEY_RELEASE));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool is_gdk_mouse_event(GdkEvent* ev)
|
|
|
|
|
{
|
|
|
|
|
return ((ev->type == GDK_BUTTON_PRESS) || (ev->type == GDK_BUTTON_RELEASE) ||
|
2011-08-24 12:28:51 +00:00
|
|
|
(ev->type == GDK_MOTION_NOTIFY) || (ev->type == GDK_2BUTTON_PRESS));
|
2010-10-14 21:07:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool event_earlier_than(GdkEvent* ev, guint32 compare_time)
|
|
|
|
|
{
|
|
|
|
|
assert(is_gdk_keyboard_event(ev) || is_gdk_mouse_event(ev));
|
|
|
|
|
return (ev->key.time <= compare_time);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void print_key_event(GdkEvent* p_ev)
|
|
|
|
|
{
|
|
|
|
|
if (!((p_ev->type == GDK_KEY_PRESS) || (p_ev->type == GDK_KEY_RELEASE))) {
|
|
|
|
|
LOG(DEBUG) << "Not a key event.";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const gchar* gdk_name = gdk_keyval_name(p_ev->key.keyval);
|
|
|
|
|
const char* kNameUnknown = "UNKNOWN";
|
|
|
|
|
const char* print_name = (gdk_name != NULL ? gdk_name : kNameUnknown);
|
|
|
|
|
|
|
|
|
|
std::string ev_type = (p_ev->type == GDK_KEY_PRESS ? "press" : "release");
|
|
|
|
|
LOG(DEBUG) << "Type: " << ev_type << "Key code: " << p_ev->key.keyval <<
|
|
|
|
|
" (" << print_name << ") time: " <<
|
|
|
|
|
p_ev->key.time << " state: " << p_ev->key.state << " hw keycode: "
|
|
|
|
|
<< (int) p_ev->key.hardware_keycode << " ";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool additional_events_to_wait_for(GdkEvent* p_event)
|
|
|
|
|
{
|
|
|
|
|
return ((p_event->type == GDK_LEAVE_NOTIFY) ||
|
|
|
|
|
(p_event->type == GDK_ENTER_NOTIFY));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void init_logging()
|
|
|
|
|
{
|
|
|
|
|
#ifdef INTERACTIONS_DEBUG
|
|
|
|
|
static bool log_initalized = false;
|
|
|
|
|
if (!log_initalized) {
|
|
|
|
|
LOG::Level("DEBUG");
|
|
|
|
|
LOG::File(INTERACTIONS_LOG_FILE, "a");
|
|
|
|
|
log_initalized = true;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2011-05-05 18:03:39 +00:00
|
|
|
|
2010-10-14 21:07:36 +00:00
|
|
|
extern "C"
|
|
|
|
|
{
|
|
|
|
|
bool pending_input_events()
|
|
|
|
|
{
|
|
|
|
|
LOG(DEBUG) << "Waiting for all events to be processed. Latest: " << gLatestEventTime;
|
|
|
|
|
GdkEvent* lastEvent = gdk_event_peek();
|
|
|
|
|
LOG(DEBUG) << "Got event: " <<
|
|
|
|
|
(lastEvent != NULL ? lastEvent->type : 0);
|
|
|
|
|
if ((lastEvent != NULL) && is_gdk_keyboard_event(lastEvent)) {
|
|
|
|
|
print_key_event(lastEvent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ret_val = false;
|
|
|
|
|
if (lastEvent != NULL &&
|
|
|
|
|
(((is_gdk_keyboard_event(lastEvent) || is_gdk_mouse_event(lastEvent)) &&
|
|
|
|
|
event_earlier_than(lastEvent, gLatestEventTime))
|
|
|
|
|
|| (additional_events_to_wait_for(lastEvent)))) {
|
|
|
|
|
ret_val = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lastEvent != NULL) {
|
|
|
|
|
gdk_event_free(lastEvent);
|
|
|
|
|
}
|
|
|
|
|
LOG(DEBUG) << "Returning: " << ret_val;
|
|
|
|
|
|
|
|
|
|
return ret_val;
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-20 14:53:59 +00:00
|
|
|
// Does nothing on Linux
|
|
|
|
|
void stopPersistentEventFiring()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-18 13:07:00 +00:00
|
|
|
void setEnablePersistentHover(bool enablePersistentHover)
|
2012-10-11 16:02:44 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-14 21:07:36 +00:00
|
|
|
}
|