Skip to content

Commit c6e0ff1

Browse files
committed
split single hpp files into cpp/hpp
create headers + implementation files for each platform, as well as the entry point.
1 parent 66475ad commit c6e0ff1

File tree

12 files changed

+713
-591
lines changed

12 files changed

+713
-591
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
1+
bin
12
build
23
node_modules
4+
9*
5+
10*
6+
11*
7+
*.log

binding.gyp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
{
22
"targets": [{
3-
"target_name": "driver",
3+
"target_name": "serenade-driver",
44
"defines": ["NAPI_DISABLE_CPP_EXCEPTIONS"],
55
"sources": ["src/driver.cpp"],
66
"include_dirs": [
77
"<!@(node -p \"require('node-addon-api').include\")"
88
],
99
"conditions": [
1010
['OS=="mac"', {
11+
"sources": ["src/driver.cpp", "src/mac.cpp"],
1112
"link_settings": {
1213
"libraries": [
1314
"/System/Library/Frameworks/AppKit.framework",
@@ -20,7 +21,11 @@
2021
"OTHER_CFLAGS": ["-ObjC++"]
2122
}
2223
}],
24+
['OS=="win"', {
25+
"sources": ["src/driver.cpp", "src/windows.cpp"],
26+
}],
2327
['OS=="linux"', {
28+
"sources": ["src/driver.cpp", "src/linux.cpp"],
2429
"link_settings": {
2530
"libraries": ["-lX11", "-lXtst"]
2631
}

index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const fs = require("fs");
22
const os = require("os");
33
const path = require("path");
44
const shortcut = require("windows-shortcuts");
5-
const lib = require("bindings")("driver.node");
5+
const lib = require("bindings")("serenade-driver.node");
66

77
exports.click = (button, count) => {
88
if (!button) {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "driver",
2+
"name": "serenade-driver",
33
"version": "1.0.0",
44
"description": "A library for cross-platform system automations.",
55
"main": "index.js",

src/driver.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,27 @@
22

33
#include <vector>
44

5+
#include "driver.hpp"
6+
57
#if __APPLE__
8+
69
#include <unistd.h>
710

8-
#include "lib/mac.hpp"
11+
#include "mac.hpp"
12+
913
#elif __linux__
14+
1015
#include <X11/Xlib.h>
1116
#include <unistd.h>
1217

13-
#include "lib/linux.hpp"
18+
#include "linux.hpp"
19+
1420
#else
21+
1522
#include <Windows.h>
1623

17-
#include "lib/windows.hpp"
24+
#include "windows.hpp"
25+
1826
#endif
1927

2028
Napi::Value Click(const Napi::CallbackInfo& info) {

src/driver.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <napi.h>
2+
3+
#include <vector>
4+
5+
Napi::Value Click(const Napi::CallbackInfo& info);
6+
Napi::Value ClickButton(const Napi::CallbackInfo& info);
7+
Napi::Value FocusApplication(const Napi::CallbackInfo& info);
8+
Napi::Value GetActiveApplication(const Napi::CallbackInfo& info);
9+
Napi::Value GetClickableButtons(const Napi::CallbackInfo& info);
10+
Napi::Value GetEditorState(const Napi::CallbackInfo& info);
11+
Napi::Array GetRunningApplications(const Napi::CallbackInfo& info);
12+
Napi::Value PressKey(const Napi::CallbackInfo& info);
13+
Napi::Value SetEditorState(const Napi::CallbackInfo& info);
14+
Napi::Value SetMouseLocation(const Napi::CallbackInfo& info);
15+
Napi::Value SleepMilliseconds(const Napi::CallbackInfo& info);
16+
Napi::Value TypeText(const Napi::CallbackInfo& info);
17+
Napi::Object Init(Napi::Env env, Napi::Object exports);

src/lib/linux.hpp renamed to src/linux.cpp

Lines changed: 110 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,96 @@
33
#include <X11/Xutil.h>
44
#include <X11/extensions/XTest.h>
55
#include <unistd.h>
6+
67
#include <algorithm>
78
#include <cctype>
89
#include <fstream>
910
#include <streambuf>
1011
#include <string>
1112
#include <vector>
1213

14+
#include "linux.hpp"
15+
1316
namespace driver {
1417

18+
void Click(const std::string& buttonType, int count) {
19+
Display* display = XOpenDisplay(NULL);
20+
int button = Button1;
21+
if (buttonType == "middle") {
22+
button = Button2;
23+
} else if (buttonType == "right") {
24+
button = Button3;
25+
}
26+
27+
for (int i = 0; i < count; i++) {
28+
XTestFakeButtonEvent(display, button, true, 0);
29+
XFlush(display);
30+
usleep(10000);
31+
XTestFakeButtonEvent(display, button, false, 0);
32+
XFlush(display);
33+
}
34+
35+
XCloseDisplay(display);
36+
}
37+
38+
void FocusApplication(const std::string& application) {
39+
std::string lower = application;
40+
ToLower(lower);
41+
42+
Display* display = XOpenDisplay(NULL);
43+
Window root = XDefaultRootWindow(display);
44+
45+
unsigned long length = 0;
46+
unsigned char* property = 0;
47+
GetProperty(display, root, "_NET_CLIENT_LIST", &property, &length);
48+
49+
Window* windows = (Window*)property;
50+
for (unsigned long i = 0; i < length; i++) {
51+
Window window = windows[i];
52+
std::string name = ProcessName(display, window);
53+
if (name.find(application) != std::string::npos) {
54+
XClientMessageEvent event;
55+
event.type = ClientMessage;
56+
event.display = display;
57+
event.window = window;
58+
event.message_type =
59+
XInternAtom(display, std::string("_NET_ACTIVE_WINDOW").c_str(), 1);
60+
event.format = 32;
61+
event.data.l[0] = 1;
62+
event.data.l[1] = CurrentTime;
63+
64+
Window root = XDefaultRootWindow(display);
65+
XSendEvent(display, root, 0,
66+
SubstructureRedirectMask | SubstructureNotifyMask,
67+
(XEvent*)&event);
68+
}
69+
}
70+
71+
XFree(windows);
72+
XCloseDisplay(display);
73+
}
74+
75+
std::string GetActiveApplication() {
76+
Display* display = XOpenDisplay(NULL);
77+
Window root = XDefaultRootWindow(display);
78+
unsigned long length = 0;
79+
unsigned char* property = 0;
80+
GetProperty(display, root, "_NET_ACTIVE_WINDOW", &property, &length);
81+
82+
Window* window = (Window*)property;
83+
std::string result = ProcessName(display, *window);
84+
85+
XFree(window);
86+
XCloseDisplay(display);
87+
return result;
88+
}
89+
1590
void GetKeycode(Display* display, const std::string& key, int* keycode,
1691
bool* shift) {
1792
// convert our key names to the corresponding x11 key
1893
std::string mapped = key;
19-
if (key == "Escape") {
20-
mapped = "escape";
94+
if (key == "escape") {
95+
mapped = "Escape";
2196
} else if (key == "control" || key == "ctrl") {
2297
mapped = "Control_L";
2398
} else if (key == "alt") {
@@ -170,11 +245,6 @@ void GetKeycode(Display* display, const std::string& key, int* keycode,
170245
}
171246
}
172247

173-
void ToLower(std::string& s) {
174-
std::transform(s.begin(), s.end(), s.begin(),
175-
[](unsigned char c) { return std::tolower(c); });
176-
}
177-
178248
void GetProperty(Display* display, Window window, const std::string& property,
179249
unsigned char** result, unsigned long* length) {
180250
Atom atom = XInternAtom(display, property.c_str(), 1);
@@ -185,106 +255,6 @@ void GetProperty(Display* display, Window window, const std::string& property,
185255
&actual_format, length, &bytes_after, result);
186256
}
187257

188-
std::string ProcessName(Display* display, Window window) {
189-
unsigned long length = 0;
190-
unsigned char* property = 0;
191-
GetProperty(display, window, "_NET_WM_PID", &property, &length);
192-
193-
unsigned long* pid = (unsigned long*)property;
194-
std::ifstream t(std::string("/proc/") + std::to_string(*pid) +
195-
std::string("/cmdline"));
196-
std::string path((std::istreambuf_iterator<char>(t)),
197-
std::istreambuf_iterator<char>());
198-
199-
XFree(pid);
200-
ToLower(path);
201-
return path;
202-
}
203-
204-
void ToggleKey(Display* display, const std::string& key, bool down) {
205-
int keycode = -1;
206-
bool shift = false;
207-
GetKeycode(display, key, &keycode, &shift);
208-
if (keycode == -1) {
209-
return;
210-
}
211-
212-
XTestFakeKeyEvent(display, keycode, down, CurrentTime);
213-
XFlush(display);
214-
}
215-
216-
void Click(const std::string& buttonType, int count) {
217-
Display* display = XOpenDisplay(NULL);
218-
int button = Button1;
219-
if (buttonType == "middle") {
220-
button = Button2;
221-
} else if (buttonType == "right") {
222-
button = Button3;
223-
}
224-
225-
for (int i = 0; i < count; i++) {
226-
XTestFakeButtonEvent(display, button, true, 0);
227-
XFlush(display);
228-
usleep(10000);
229-
XTestFakeButtonEvent(display, button, false, 0);
230-
XFlush(display);
231-
}
232-
233-
XCloseDisplay(display);
234-
}
235-
236-
void FocusApplication(const std::string& application) {
237-
std::string lower = application;
238-
ToLower(lower);
239-
240-
Display* display = XOpenDisplay(NULL);
241-
Window root = XDefaultRootWindow(display);
242-
243-
unsigned long length = 0;
244-
unsigned char* property = 0;
245-
GetProperty(display, root, "_NET_CLIENT_LIST", &property, &length);
246-
247-
Window* windows = (Window*)property;
248-
for (unsigned long i = 0; i < length; i++) {
249-
Window window = windows[i];
250-
std::string name = ProcessName(display, window);
251-
if (name.find(application) != std::string::npos) {
252-
XClientMessageEvent event;
253-
event.type = ClientMessage;
254-
event.display = display;
255-
event.window = window;
256-
event.message_type =
257-
XInternAtom(display, std::string("_NET_ACTIVE_WINDOW").c_str(), 1);
258-
event.format = 32;
259-
event.data.l[0] = 1;
260-
event.data.l[1] = CurrentTime;
261-
262-
Window root = XDefaultRootWindow(display);
263-
XSendEvent(display, root, 0,
264-
SubstructureRedirectMask | SubstructureNotifyMask,
265-
(XEvent*)&event);
266-
}
267-
}
268-
269-
XFree(windows);
270-
XCloseDisplay(display);
271-
}
272-
273-
std::string GetActiveApplication() {
274-
Display* display = XOpenDisplay(NULL);
275-
Window root = XDefaultRootWindow(display);
276-
unsigned long length = 0;
277-
unsigned char* property = 0;
278-
GetProperty(display, root, "_NET_ACTIVE_WINDOW", &property, &length);
279-
280-
Window* window = (Window*)property;
281-
std::string result = ProcessName(display, *window);
282-
283-
XFree(window);
284-
XCloseDisplay(display);
285-
return result;
286-
}
287-
288258
std::vector<std::string> GetRunningApplications() {
289259
Display* display = XOpenDisplay(NULL);
290260
Window root = XDefaultRootWindow(display);
@@ -338,10 +308,43 @@ void PressKey(Display* display, std::string key,
338308
}
339309
}
340310

311+
std::string ProcessName(Display* display, Window window) {
312+
unsigned long length = 0;
313+
unsigned char* property = 0;
314+
GetProperty(display, window, "_NET_WM_PID", &property, &length);
315+
316+
unsigned long* pid = (unsigned long*)property;
317+
std::ifstream t(std::string("/proc/") + std::to_string(*pid) +
318+
std::string("/cmdline"));
319+
std::string path((std::istreambuf_iterator<char>(t)),
320+
std::istreambuf_iterator<char>());
321+
322+
XFree(pid);
323+
ToLower(path);
324+
return path;
325+
}
326+
341327
void SetMouseLocation(int x, int y) {
342328
Display* display = XOpenDisplay(NULL);
343329
XWarpPointer(display, None, XDefaultRootWindow(display), 0, 0, 0, 0, x, y);
344330
XCloseDisplay(display);
345331
}
346332

333+
void ToggleKey(Display* display, const std::string& key, bool down) {
334+
int keycode = -1;
335+
bool shift = false;
336+
GetKeycode(display, key, &keycode, &shift);
337+
if (keycode == -1) {
338+
return;
339+
}
340+
341+
XTestFakeKeyEvent(display, keycode, down, CurrentTime);
342+
XFlush(display);
343+
}
344+
345+
void ToLower(std::string& s) {
346+
std::transform(s.begin(), s.end(), s.begin(),
347+
[](unsigned char c) { return std::tolower(c); });
348+
}
349+
347350
} // namespace driver

src/linux.hpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include <X11/Xlib.h>
2+
#include <X11/Xutil.h>
3+
4+
#include <string>
5+
#include <vector>
6+
7+
namespace driver {
8+
9+
void Click(const std::string& buttonType, int count);
10+
void FocusApplication(const std::string& application);
11+
std::string GetActiveApplication();
12+
void GetKeycode(Display* display, const std::string& key, int* keycode,
13+
bool* shift);
14+
void GetProperty(Display* display, Window window, const std::string& property,
15+
unsigned char** result, unsigned long* length);
16+
std::vector<std::string> GetRunningApplications();
17+
void PressKey(Display* display, std::string key,
18+
std::vector<std::string> modifiers);
19+
std::string ProcessName(Display* display, Window window);
20+
void SetMouseLocation(int x, int y);
21+
void ToggleKey(Display* display, const std::string& key, bool down);
22+
void ToLower(std::string& s);
23+
24+
} // namespace driver

0 commit comments

Comments
 (0)