mirror of
https://repo.dec05eba.com/gpu-screen-recorder-ui
synced 2026-05-05 14:30:45 +09:00
Add daemon
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,5 +1,6 @@
|
|||||||
# Compiled sibs files
|
# Compiled sibs files
|
||||||
sibs-build/
|
sibs-build/
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
tests/sibs-build/
|
|
||||||
tests/compile_commands.json
|
gpu-screen-recorder-overlay-daemon/sibs-build/
|
||||||
|
gpu-screen-recorder-overlay-daemon/compile_commands.json
|
||||||
|
|||||||
10
build.sh
Executable file
10
build.sh
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
[ $# -ne 1 ] && echo "usage: build.sh debug|release" && exit 1
|
||||||
|
|
||||||
|
script_dir=$(dirname "$0")
|
||||||
|
cd "$script_dir"
|
||||||
|
|
||||||
|
sibs build --"$1" gpu-screen-recorder-overlay-daemon
|
||||||
|
sibs build --"$1"
|
||||||
|
echo "Successfully built"
|
||||||
68
gpu-screen-recorder-overlay-daemon/main.c
Normal file
68
gpu-screen-recorder-overlay-daemon/main.c
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/keysym.h>
|
||||||
|
|
||||||
|
static int xerror_dummy(Display *dpy, XErrorEvent *ee) {
|
||||||
|
(void)dpy;
|
||||||
|
(void)ee;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const KeySym toggle_overlay_key = XK_Z;
|
||||||
|
static void grab_keys(Display *display) {
|
||||||
|
unsigned int numlockmask = 0;
|
||||||
|
KeyCode numlock_keycode = XKeysymToKeycode(display, XK_Num_Lock);
|
||||||
|
XModifierKeymap *modmap = XGetModifierMapping(display);
|
||||||
|
for(int i = 0; i < 8; ++i) {
|
||||||
|
for(int j = 0; j < modmap->max_keypermod; ++j) {
|
||||||
|
if(modmap->modifiermap[i * modmap->max_keypermod + j] == numlock_keycode)
|
||||||
|
numlockmask = (1 << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XFreeModifiermap(modmap);
|
||||||
|
|
||||||
|
XErrorHandler prev_error_handler = XSetErrorHandler(xerror_dummy);
|
||||||
|
|
||||||
|
Window root_window = DefaultRootWindow(display);
|
||||||
|
unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
|
||||||
|
for(int i = 0; i < 4; ++i) {
|
||||||
|
XGrabKey(display, XKeysymToKeycode(display, toggle_overlay_key), Mod1Mask|modifiers[i], root_window, False, GrabModeAsync, GrabModeAsync);
|
||||||
|
}
|
||||||
|
|
||||||
|
XSync(display, False);
|
||||||
|
XSetErrorHandler(prev_error_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Window get_window_with_input_focus(Display *display) {
|
||||||
|
Window window = None;
|
||||||
|
int rev;
|
||||||
|
if(!XGetInputFocus(display, &window, &rev))
|
||||||
|
window = None;
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Display *display = XOpenDisplay(NULL);
|
||||||
|
if(!display) {
|
||||||
|
fprintf(stderr, "Error: XOpenDisplay failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
grab_keys(display);
|
||||||
|
const KeyCode overlay_keycode = XKeysymToKeycode(display, toggle_overlay_key);
|
||||||
|
|
||||||
|
XEvent xev;
|
||||||
|
for(;;) {
|
||||||
|
XNextEvent(display, &xev);
|
||||||
|
if(xev.type == KeyRelease && xev.xkey.keycode == overlay_keycode) {
|
||||||
|
Window window_with_input_focus = get_window_with_input_focus(display);
|
||||||
|
if(window_with_input_focus && window_with_input_focus != DefaultRootWindow(display)) {
|
||||||
|
char cmd[1024];
|
||||||
|
snprintf(cmd, sizeof(cmd), "/home/dec05eba/git/gpu-screen-recorder-overlay/sibs-build/linux_x86_64/debug/gpu-screen-recorder-overlay %ld", window_with_input_focus);
|
||||||
|
system(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
8
gpu-screen-recorder-overlay-daemon/project.conf
Normal file
8
gpu-screen-recorder-overlay-daemon/project.conf
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "gpu-screen-recorder-overlay-daemon"
|
||||||
|
type = "executable"
|
||||||
|
version = "0.1.0"
|
||||||
|
platforms = ["posix"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
x11 = ">=1"
|
||||||
@@ -4,6 +4,9 @@ type = "executable"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
platforms = ["posix"]
|
platforms = ["posix"]
|
||||||
|
|
||||||
|
[config]
|
||||||
|
ignore_dirs = ["gpu-screen-recorder-overlay-daemon"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
x11 = ">=1"
|
x11 = ">=1"
|
||||||
xext = ">=1"
|
xext = ">=1"
|
||||||
|
|||||||
49
src/main.cpp
49
src/main.cpp
@@ -5,6 +5,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/cursorfont.h>
|
#include <X11/cursorfont.h>
|
||||||
@@ -64,6 +65,11 @@ int main(int argc, char **argv) {
|
|||||||
if(argc != 2)
|
if(argc != 2)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
|
std::string program_root_dir = dirname(argv[0]);
|
||||||
|
if(!program_root_dir.empty() && program_root_dir.back() != '/')
|
||||||
|
program_root_dir += '/';
|
||||||
|
program_root_dir += "../../../";
|
||||||
|
|
||||||
int64_t target_window;
|
int64_t target_window;
|
||||||
if(!string_to_i64(argv[1], &target_window)) {
|
if(!string_to_i64(argv[1], &target_window)) {
|
||||||
fprintf(stderr, "Error: invalid number '%s' was specific for window argument\n", argv[1]);
|
fprintf(stderr, "Error: invalid number '%s' was specific for window argument\n", argv[1]);
|
||||||
@@ -94,11 +100,11 @@ int main(int argc, char **argv) {
|
|||||||
startup_error("failed to create window");
|
startup_error("failed to create window");
|
||||||
|
|
||||||
mgl::MemoryMappedFile title_font_file;
|
mgl::MemoryMappedFile title_font_file;
|
||||||
if(!title_font_file.load("fonts/Orbitron-Bold.ttf", mgl::MemoryMappedFile::LoadOptions{true, false}))
|
if(!title_font_file.load((program_root_dir + "fonts/Orbitron-Bold.ttf").c_str(), mgl::MemoryMappedFile::LoadOptions{true, false}))
|
||||||
startup_error("failed to load file: fonts/Orbitron-Bold.ttf");
|
startup_error("failed to load file: fonts/Orbitron-Bold.ttf");
|
||||||
|
|
||||||
mgl::MemoryMappedFile font_file;
|
mgl::MemoryMappedFile font_file;
|
||||||
if(!font_file.load("fonts/Orbitron-Regular.ttf", mgl::MemoryMappedFile::LoadOptions{true, false}))
|
if(!font_file.load((program_root_dir + "fonts/Orbitron-Regular.ttf").c_str(), mgl::MemoryMappedFile::LoadOptions{true, false}))
|
||||||
startup_error("failed to load file: fonts/Orbitron-Regular.ttf");
|
startup_error("failed to load file: fonts/Orbitron-Regular.ttf");
|
||||||
|
|
||||||
mgl::Font title_font;
|
mgl::Font title_font;
|
||||||
@@ -110,15 +116,15 @@ int main(int argc, char **argv) {
|
|||||||
startup_error("failed to load font: fonts/Orbitron-Regular.ttf");
|
startup_error("failed to load font: fonts/Orbitron-Regular.ttf");
|
||||||
|
|
||||||
mgl::Texture replay_button_texture;
|
mgl::Texture replay_button_texture;
|
||||||
if(!replay_button_texture.load_from_file("images/replay.png"))
|
if(!replay_button_texture.load_from_file((program_root_dir + "images/replay.png").c_str()))
|
||||||
startup_error("failed to load texture: images/replay.png");
|
startup_error("failed to load texture: images/replay.png");
|
||||||
|
|
||||||
mgl::Texture record_button_texture;
|
mgl::Texture record_button_texture;
|
||||||
if(!record_button_texture.load_from_file("images/record.png"))
|
if(!record_button_texture.load_from_file((program_root_dir + "images/record.png").c_str()))
|
||||||
startup_error("failed to load texture: images/record.png");
|
startup_error("failed to load texture: images/record.png");
|
||||||
|
|
||||||
mgl::Texture stream_button_texture;
|
mgl::Texture stream_button_texture;
|
||||||
if(!stream_button_texture.load_from_file("images/stream.png"))
|
if(!stream_button_texture.load_from_file((program_root_dir + "images/stream.png").c_str()))
|
||||||
startup_error("failed to load texture: images/stream.png");
|
startup_error("failed to load texture: images/stream.png");
|
||||||
|
|
||||||
struct MainButton {
|
struct MainButton {
|
||||||
@@ -245,27 +251,6 @@ int main(int argc, char **argv) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
update_overlay_shape();
|
update_overlay_shape();
|
||||||
|
|
||||||
WindowTexture target_window_texture;
|
|
||||||
window_texture_init(&target_window_texture, display, target_window);
|
|
||||||
|
|
||||||
int target_window_texture_width = 0;
|
|
||||||
int target_window_texture_height = 0;
|
|
||||||
window_texture_get_size_or(&target_window_texture, &target_window_texture_width, &target_window_texture_height, target_window_size.x, target_window_size.y);
|
|
||||||
|
|
||||||
mgl_texture window_texture_ref = {
|
|
||||||
window_texture_get_opengl_texture_id(&target_window_texture),
|
|
||||||
target_window_texture_width,
|
|
||||||
target_window_texture_height,
|
|
||||||
MGL_TEXTURE_FORMAT_RGB,
|
|
||||||
32768,
|
|
||||||
32768,
|
|
||||||
true
|
|
||||||
};
|
|
||||||
|
|
||||||
mgl::Texture window_texture = mgl::Texture::reference(window_texture_ref);
|
|
||||||
mgl::Sprite window_texture_sprite(&window_texture);
|
|
||||||
|
|
||||||
window.set_visible(true);
|
window.set_visible(true);
|
||||||
|
|
||||||
Cursor default_cursor = XCreateFontCursor(display, XC_arrow);
|
Cursor default_cursor = XCreateFontCursor(display, XC_arrow);
|
||||||
@@ -280,10 +265,7 @@ int main(int argc, char **argv) {
|
|||||||
while(window.is_open()) {
|
while(window.is_open()) {
|
||||||
if(XCheckTypedWindowEvent(display, target_window, VisibilityNotify, &xev)) {
|
if(XCheckTypedWindowEvent(display, target_window, VisibilityNotify, &xev)) {
|
||||||
if(xev.xvisibility.state) {
|
if(xev.xvisibility.state) {
|
||||||
window_texture_on_resize(&target_window_texture);
|
|
||||||
window_texture_ref.id = window_texture_get_opengl_texture_id(&target_window_texture);
|
|
||||||
window_texture_get_size_or(&target_window_texture, &window_texture_ref.width, &window_texture_ref.height, target_window_size.x, target_window_size.y);
|
|
||||||
window_texture = mgl::Texture::reference(window_texture_ref);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,11 +275,6 @@ int main(int argc, char **argv) {
|
|||||||
target_window_size.y = xev.xconfigure.height;
|
target_window_size.y = xev.xconfigure.height;
|
||||||
window.set_size(target_window_size);
|
window.set_size(target_window_size);
|
||||||
update_overlay_shape();
|
update_overlay_shape();
|
||||||
|
|
||||||
window_texture_on_resize(&target_window_texture);
|
|
||||||
window_texture_ref.id = window_texture_get_opengl_texture_id(&target_window_texture);
|
|
||||||
window_texture_get_size_or(&target_window_texture, &window_texture_ref.width, &window_texture_ref.height, target_window_size.x, target_window_size.y);
|
|
||||||
window_texture = mgl::Texture::reference(window_texture_ref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(window.poll_event(event)) {
|
if(window.poll_event(event)) {
|
||||||
@@ -305,7 +282,7 @@ int main(int argc, char **argv) {
|
|||||||
main_button.button.on_event(event, window);
|
main_button.button.on_event(event, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(event.type == mgl::Event::KeyPressed) {
|
if(event.type == mgl::Event::KeyReleased) {
|
||||||
if(event.key.code == mgl::Keyboard::Escape) {
|
if(event.key.code == mgl::Keyboard::Escape) {
|
||||||
window.close();
|
window.close();
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user