Skip to content

Commit 13ea9bb

Browse files
committed
move external dependencies into project map.
added mouse simulation utility.
1 parent 445db19 commit 13ea9bb

File tree

5 files changed

+308
-5
lines changed

5 files changed

+308
-5
lines changed

dep/CMakeLists.txt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,16 @@ add_subdirectory(zlib)
1818
#set(SKIP_INSTALL_HEADERS ON CACHE BOOL "" FORCE)
1919
add_subdirectory(minilzo)
2020
add_subdirectory(fmt)
21+
add_subdirectory(mouse_simulation)
2122
add_subdirectory(googletest)
2223
add_subdirectory(google_benchmark)
2324
add_subdirectory(yuvconvert)
2425

25-
2626
# cpptoml settings
2727
set(CPPTOML_BUILD_EXAMPLES OFF CACHE BOOL "Disable cpptoml examples" FORCE)
2828
add_subdirectory(cpptoml)
2929

3030
# fmt format library settings.
31-
set_target_properties(fmt
32-
PROPERTIES
33-
FOLDER "External/fmt"
34-
)
31+
set_target_properties(fmt PROPERTIES FOLDER "External/fmt")
32+
set_target_properties(mouse_simulation PROPERTIES FOLDER "External/mouse_simulation")
33+
set_target_properties(yuvconvert PROPERTIES FOLDER "External/yuvconvert")

dep/mouse_simulation/CMakeLists.txt

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Copyright (C) 2018 Steven Hoving
2+
#
3+
# This program is free software: you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License as published by
5+
# the Free Software Foundation, either version 3 of the License, or
6+
# (at your option) any later version.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
# GNU General Public License for more details.
12+
#
13+
# You should have received a copy of the GNU General Public License
14+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
15+
16+
project(mouse_simulation)
17+
18+
set(LIB_SOURCE
19+
src/mouse_simulation.cpp
20+
src/main.cpp
21+
)
22+
23+
set(LIB_INCLUDE
24+
include/mouse_simulation/mouse_simulation.h
25+
)
26+
27+
source_group(mouse_simulation FILES
28+
${LIB_SOURCE}
29+
${LIB_INCLUDE}
30+
)
31+
32+
add_executable(mouse_simulation
33+
${LIB_SOURCE}
34+
${LIB_INCLUDE}
35+
)
36+
37+
target_link_libraries(mouse_simulation
38+
PRIVATE
39+
fmt
40+
)
41+
42+
target_include_directories(mouse_simulation
43+
PUBLIC
44+
include
45+
)
46+
47+
target_compile_options(mouse_simulation
48+
PRIVATE
49+
/experimental:external
50+
/external:W0
51+
/external:anglebrackets
52+
)
53+
54+
set_target_properties(mouse_simulation PROPERTIES
55+
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
56+
)
57+
58+
install(
59+
TARGETS mouse_simulation
60+
RUNTIME DESTINATION bin
61+
LIBRARY DESTINATION lib
62+
ARCHIVE DESTINATION lib
63+
)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/**
2+
* Copyright(C) 2018 Steven Hoving
3+
*
4+
* This program is free software : you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
18+
#pragma once
19+
20+
#include <atomic>
21+
#include <thread>
22+
#include <mutex>
23+
#include <deque>
24+
#include <cstdint>
25+
26+
namespace mouse_simulation
27+
{
28+
29+
struct input_wrapper;
30+
class simulator
31+
{
32+
enum class mouse_button
33+
{
34+
none,
35+
left,
36+
middle,
37+
right
38+
};
39+
40+
enum class mouse_click
41+
{
42+
none,
43+
single_click,
44+
double_click
45+
};
46+
47+
struct click_data
48+
{
49+
int x;
50+
int y;
51+
mouse_button button;
52+
mouse_click click;
53+
uint64_t timeout; // in ms
54+
};
55+
public:
56+
simulator();
57+
~simulator();
58+
59+
void add_click(int x, int y);
60+
61+
void start();
62+
void flush();
63+
64+
void mouse_thread();
65+
private:
66+
void _send_input(const input_wrapper &input_event);
67+
private:
68+
int old_x{0};
69+
int old_y{0};
70+
std::deque<click_data> mouse_clicks_{};
71+
std::atomic<bool> run_{true};
72+
std::thread thread_{};
73+
};
74+
75+
} // namespace mouse_simulation

dep/mouse_simulation/src/main.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Copyright(C) 2018 Steven Hoving
3+
*
4+
* This program is free software : you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
18+
#include "mouse_simulation/mouse_simulation.h"
19+
20+
int main()
21+
{
22+
mouse_simulation::simulator sim;
23+
sim.add_click(50, 50);
24+
sim.add_click(200, 20);
25+
sim.add_click(20, 1000); // click on start menu
26+
sim.add_click(1920, 1080);
27+
sim.start();
28+
sim.flush();
29+
30+
return 0;
31+
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/**
2+
* Copyright(C) 2018 Steven Hoving
3+
*
4+
* This program is free software : you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
18+
#include "mouse_simulation/mouse_simulation.h"
19+
#include <fmt/printf.h>
20+
#include <windows.h>
21+
#include <array>
22+
23+
namespace mouse_simulation
24+
{
25+
void normalize_coordinates(int &x, int &y)
26+
{
27+
static const auto max_x = ::GetSystemMetrics(SM_CXVIRTUALSCREEN);
28+
static const auto max_y = ::GetSystemMetrics(SM_CYVIRTUALSCREEN);
29+
static const auto min_x = ::GetSystemMetrics(SM_XVIRTUALSCREEN);
30+
static const auto min_y = ::GetSystemMetrics(SM_YVIRTUALSCREEN);
31+
static const auto width = max_x - min_x;
32+
static const auto height = max_y - min_y;
33+
static const auto virtual_width = 65535;
34+
static const auto virtual_height = 65535;
35+
36+
x = static_cast<int>((static_cast<float>(x) / width) * virtual_width);
37+
y = static_cast<int>((static_cast<float>(y) / height) * virtual_height);
38+
}
39+
40+
struct input_wrapper : INPUT
41+
{
42+
input_wrapper(int x, int y, int mouse_event_type)
43+
{
44+
normalize_coordinates(x, y);
45+
type = INPUT_MOUSE;
46+
mi.dx = x;
47+
mi.dy = y;
48+
mi.mouseData = 0;
49+
mi.time = 0;
50+
mi.dwFlags = mouse_event_type;
51+
}
52+
};
53+
54+
simulator::simulator()
55+
{
56+
POINT pos;
57+
GetCursorPos(&pos);
58+
old_x = pos.x;
59+
old_y = pos.y;
60+
}
61+
62+
simulator::~simulator()
63+
{
64+
run_ = false;
65+
if (thread_.joinable())
66+
thread_.join();
67+
}
68+
69+
void simulator::add_click(int x, int y)
70+
{
71+
// linear interpolation between mouse clicks
72+
const auto dx = x - old_x;
73+
const auto x_stem = static_cast<float>(dx) / 100;
74+
75+
const auto dy = y - old_y;
76+
const auto y_stem = static_cast<float>(dy) / 100;
77+
78+
for (int i = 0; i < 100; ++i)
79+
{
80+
const auto new_x = static_cast<int>(old_x + (i * x_stem));
81+
const auto new_y = static_cast<int>(old_y + (i * y_stem));
82+
const auto data = click_data{ new_x, new_y, mouse_button::none, mouse_click::none, 10 };
83+
mouse_clicks_.emplace_back(data);
84+
}
85+
86+
const auto data = click_data{ x, y, mouse_button::left, mouse_click::single_click, 1000 };
87+
mouse_clicks_.emplace_back(data);
88+
89+
old_x = x;
90+
old_y = y;
91+
}
92+
93+
void simulator::start()
94+
{
95+
thread_ = std::thread([this](){mouse_thread();});
96+
}
97+
98+
void simulator::flush()
99+
{
100+
if (thread_.joinable())
101+
thread_.join();
102+
}
103+
104+
void simulator::mouse_thread()
105+
{
106+
while (run_)
107+
{
108+
fmt::print("process mouse event {}\n", mouse_clicks_.size());
109+
110+
const auto click = mouse_clicks_.front();
111+
mouse_clicks_.pop_front();
112+
113+
_send_input(input_wrapper(click.x, click.y,
114+
MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE |MOUSEEVENTF_VIRTUALDESK));
115+
116+
if (click.button != mouse_button::none)
117+
{
118+
_send_input(input_wrapper(click.x, click.y, MOUSEEVENTF_LEFTDOWN));
119+
_send_input(input_wrapper(click.x, click.y, MOUSEEVENTF_LEFTUP));
120+
}
121+
122+
std::this_thread::sleep_for(std::chrono::milliseconds(click.timeout));
123+
124+
if (mouse_clicks_.empty())
125+
run_ = false;
126+
}
127+
}
128+
129+
void simulator::_send_input(const input_wrapper &input_event)
130+
{
131+
const auto input_event_ptr = const_cast<input_wrapper *>(&input_event);
132+
SendInput(1, input_event_ptr, sizeof(INPUT));
133+
}
134+
135+
} // namespace mouse_simulation

0 commit comments

Comments
 (0)