diff options
| author | dec05eba <dec05eba@protonmail.com> | 2026-08-02 01:11:33 +0200 |
|---|---|---|
| committer | dec05eba <dec05eba@protonmail.com> | 2026-08-02 01:11:53 +0200 |
| commit | d72113be395891f4289f0d86a32a37a99a4d5b38 (patch) | |
| tree | c2dd74d24fe62d1020be64980b8a321e999bcc29 /include | |
| parent | b38d324c8fcb61b699a16c39fc0dcdb31ad9934b (diff) | |
Add -ipc option to control gpu-screen-recorder over a unix domain socket
The socket accepts the same commands as the signal handlers, except that
saving a replay takes an arbitrary number of seconds instead of only the
fixed times that the signals provide. Requests and replies are newline
terminated json objects and every request is replied to, parsed with the
sj.h json library that was added to external.
Requests are handled on a thread that only runs while the recorder
exists, so the recorder control fields are now atomics, which they have
to be now that another thread writes them.
Diffstat (limited to 'include')
| -rw-r--r-- | include/args_parser.h | 2 | ||||
| -rw-r--r-- | include/cli/ipc.h | 56 | ||||
| -rw-r--r-- | include/recorder/audio_capture.h | 6 | ||||
| -rw-r--r-- | include/recorder/replay_save.h | 4 | ||||
| -rw-r--r-- | include/recorder/screenshot.h | 4 |
5 files changed, 64 insertions, 8 deletions
diff --git a/include/args_parser.h b/include/args_parser.h index 813d4c6..2954dde 100644 --- a/include/args_parser.h +++ b/include/args_parser.h @@ -9,7 +9,7 @@ typedef struct gsr_egl gsr_egl; -#define NUM_ARGS 38 +#define NUM_ARGS 39 typedef enum { GSR_CAPTURE_SOURCE_TYPE_WINDOW, diff --git a/include/cli/ipc.h b/include/cli/ipc.h new file mode 100644 index 0000000..0862c71 --- /dev/null +++ b/include/cli/ipc.h @@ -0,0 +1,56 @@ +#ifndef GSR_CLI_IPC_H +#define GSR_CLI_IPC_H + +#include <stdbool.h> +#include <stddef.h> +#include <limits.h> +#include <pthread.h> + +#define GSR_IPC_MAX_CLIENTS 8 +#define GSR_IPC_MAX_REQUEST_SIZE 4096 +#define GSR_IPC_MAX_ERROR_MESSAGE_SIZE 256 + +/* + These are called from the ipc thread while the recording is running. + Return false and write a message to |error_message| to reply to the request with an error. +*/ +typedef struct { + bool (*stop)(char *error_message, size_t error_message_size, void *userdata); + bool (*toggle_pause)(char *error_message, size_t error_message_size, void *userdata); + bool (*toggle_replay_recording)(char *error_message, size_t error_message_size, void *userdata); + /* |seconds| is GSR_SAVE_REPLAY_SECONDS_FULL when the whole replay buffer should be saved */ + bool (*save_replay)(int seconds, char *error_message, size_t error_message_size, void *userdata); + void *userdata; +} gsr_ipc_handlers; + +typedef struct { + int fd; + char request[GSR_IPC_MAX_REQUEST_SIZE]; + size_t request_size; + bool request_too_large; +} gsr_ipc_client; + +/* Receives newline terminated json requests on a unix domain socket and replies to every request */ +typedef struct { + bool initialized; + int socket_fd; + bool socket_bound; + char socket_filepath[PATH_MAX]; + int wakeup_pipe[2]; + gsr_ipc_client clients[GSR_IPC_MAX_CLIENTS]; + int num_clients; + gsr_ipc_handlers handlers; + pthread_t thread; + bool thread_running; +} gsr_ipc; + +/* Returns a |gsr_error| value. Creates the socket, requests are not handled until gsr_ipc_start is called */ +int gsr_ipc_init(gsr_ipc *self, const char *socket_filepath); +void gsr_ipc_deinit(gsr_ipc *self); + +/* Returns a |gsr_error| value. Starts handling requests. Does nothing if |self| hasn't been initialized */ +int gsr_ipc_start(gsr_ipc *self, const gsr_ipc_handlers *handlers); +/* Stops handling requests. Does nothing if the ipc hasn't been started */ +void gsr_ipc_stop(gsr_ipc *self); + +#endif /* GSR_CLI_IPC_H */ diff --git a/include/recorder/audio_capture.h b/include/recorder/audio_capture.h index 68390aa..4f757c9 100644 --- a/include/recorder/audio_capture.h +++ b/include/recorder/audio_capture.h @@ -3,7 +3,7 @@ #include <stdbool.h> #include <stddef.h> -#include <signal.h> +#include <stdatomic.h> #include <pthread.h> #include "../sound.h" #include "recording_clock.h" @@ -64,11 +64,11 @@ struct gsr_audio_capture { gsr_encoder *encoder; gsr_recording_clock *clock; - const volatile sig_atomic_t *running; + const atomic_int *running; }; /* Returns a |gsr_error| value */ -int gsr_audio_capture_init(gsr_audio_capture *self, gsr_encoder *encoder, gsr_recording_clock *clock, const volatile sig_atomic_t *running); +int gsr_audio_capture_init(gsr_audio_capture *self, gsr_encoder *encoder, gsr_recording_clock *clock, const atomic_int *running); void gsr_audio_capture_deinit(gsr_audio_capture *self); bool gsr_audio_capture_add_track(gsr_audio_capture *self, const gsr_audio_track *track); diff --git a/include/recorder/replay_save.h b/include/recorder/replay_save.h index d92a8c0..7f48851 100644 --- a/include/recorder/replay_save.h +++ b/include/recorder/replay_save.h @@ -5,7 +5,7 @@ #include <stddef.h> #include <limits.h> #include <pthread.h> -#include <signal.h> +#include <stdatomic.h> #include "muxer.h" #include "audio_capture.h" #include "capture_setup.h" @@ -25,7 +25,7 @@ typedef struct { typedef struct { pthread_t thread; bool thread_created; - volatile sig_atomic_t finished; + atomic_int finished; bool success; char output_filepath[PATH_MAX]; diff --git a/include/recorder/screenshot.h b/include/recorder/screenshot.h index 057383c..00a7889 100644 --- a/include/recorder/screenshot.h +++ b/include/recorder/screenshot.h @@ -2,7 +2,7 @@ #define GSR_RECORDER_SCREENSHOT_H #include <stdbool.h> -#include <signal.h> +#include <stdatomic.h> #include "../egl.h" #include "../image_writer.h" #include "../plugins.h" @@ -19,7 +19,7 @@ typedef struct { gsr_image_format image_format; const char **plugin_filepaths; int num_plugin_filepaths; - const volatile sig_atomic_t *running; + const atomic_int *running; void (*screenshot_saved)(const char *filepath, void *userdata); void *userdata; } gsr_screenshot_params; |
