| // Licensed to the Software Freedom Conservancy (SFC) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The SFC licenses this file |
| // to you 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 "PersistentEventSimulator.h" |
| |
| #define THREAD_TERMINATION_WAIT_TIME_IN_MILLISECONDS 2500 |
| #define THREAD_SLEEP_TIME_IN_MILLISECONDS 10 |
| |
| namespace webdriver { |
| |
| PersistentEventSimulator::PersistentEventSimulator() { |
| this->target_window_handle_ = NULL; |
| this->x_coordinate_ = 0; |
| this->y_coordinate_ = 0; |
| this->button_state_ = 0; |
| this->event_firing_thread_handle_ = NULL; |
| this->is_firing_events_ = false; |
| } |
| |
| PersistentEventSimulator::~PersistentEventSimulator() { |
| if (this->event_firing_thread_handle_ != NULL) { |
| this->is_running_ = false; |
| ::WaitForSingleObject(this->event_firing_thread_handle_, |
| THREAD_TERMINATION_WAIT_TIME_IN_MILLISECONDS); |
| ::CloseHandle(this->event_firing_thread_handle_); |
| this->event_firing_thread_handle_ = NULL; |
| } |
| } |
| |
| DWORD WINAPI PersistentEventSimulator::MouseEventFiringFunction(LPVOID lpParam) { |
| PersistentEventSimulator* persistent_event_simulator; |
| |
| persistent_event_simulator = reinterpret_cast<PersistentEventSimulator*>(lpParam); |
| // busy-wait loop, waiting for 10 milliseconds between |
| // dispatching events. Since the thread is usually |
| // paused for short periods of time (tens of milliseconds), |
| // a more modern signalling method was not used. |
| while (persistent_event_simulator->is_running()) { |
| if (persistent_event_simulator->is_firing_events()) { |
| HWND target = persistent_event_simulator->target_window_handle(); |
| if (::IsWindow(target)) { |
| ::SendMessage(target, |
| WM_MOUSEMOVE, |
| persistent_event_simulator->button_state(), |
| MAKELPARAM(persistent_event_simulator->x_coordinate(), |
| persistent_event_simulator->y_coordinate())); |
| } |
| } |
| ::Sleep(THREAD_SLEEP_TIME_IN_MILLISECONDS); |
| } |
| |
| return 0; |
| } |
| |
| void PersistentEventSimulator::StartPersistentEventFiring(HWND inputTo, long toX, long toY, WPARAM buttonValue) { |
| this->target_window_handle_ = inputTo; |
| this->x_coordinate_ = toX; |
| this->y_coordinate_ = toY; |
| this->button_state_ = buttonValue; |
| if (this->event_firing_thread_handle_ == NULL) { |
| this->is_running_ = true; |
| this->event_firing_thread_handle_ = CreateThread(NULL, // Security permissions. |
| 0, // default stack size. |
| MouseEventFiringFunction, |
| reinterpret_cast<LPVOID>(this), |
| 0, // default creation flags |
| NULL); |
| } |
| this->is_firing_events_ = true; |
| } |
| |
| void PersistentEventSimulator::StopPersistentEventFiring() { |
| if (this->event_firing_thread_handle_ != NULL) { |
| this->is_firing_events_ = false; |
| ::Sleep(THREAD_SLEEP_TIME_IN_MILLISECONDS); |
| } |
| } |
| |
| } // namespace webdriver |