aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/capture/capture.h20
-rw-r--r--include/capture/kms.h6
-rw-r--r--include/capture/nvfbc.h7
-rw-r--r--include/capture/portal.h2
-rw-r--r--include/capture/xcomposite.h2
-rw-r--r--include/capture/ximage.h18
-rw-r--r--include/color_conversion.h3
-rw-r--r--include/damage.h1
-rw-r--r--include/dbus.h6
-rw-r--r--include/egl.h61
-rw-r--r--include/image_writer.h35
-rw-r--r--include/pipewire_audio.h41
-rw-r--r--include/pipewire_video.h4
-rw-r--r--include/sound.hpp27
-rw-r--r--include/utils.h25
-rw-r--r--include/window/wayland.h8
-rw-r--r--include/window/window.h37
-rw-r--r--include/window/x11.h10
18 files changed, 220 insertions, 93 deletions
diff --git a/include/capture/capture.h b/include/capture/capture.h
index dc5b7ac..634eee0 100644
--- a/include/capture/capture.h
+++ b/include/capture/capture.h
@@ -13,31 +13,39 @@ typedef struct AVMasteringDisplayMetadata AVMasteringDisplayMetadata;
typedef struct AVContentLightMetadata AVContentLightMetadata;
typedef struct gsr_capture gsr_capture;
+typedef struct {
+ int width;
+ int height;
+ int fps;
+ AVCodecContext *video_codec_context; /* can be NULL */
+ AVFrame *frame; /* can be NULL, but will never be NULL if |video_codec_context| is set */
+} gsr_capture_metadata;
+
struct gsr_capture {
/* These methods should not be called manually. Call gsr_capture_* instead */
- int (*start)(gsr_capture *cap, AVCodecContext *video_codec_context, AVFrame *frame);
+ int (*start)(gsr_capture *cap, gsr_capture_metadata *capture_metadata);
void (*on_event)(gsr_capture *cap, gsr_egl *egl); /* can be NULL */
void (*tick)(gsr_capture *cap); /* can be NULL. If there is an event then |on_event| is called before this */
bool (*should_stop)(gsr_capture *cap, bool *err); /* can be NULL. If NULL, return false */
- int (*capture)(gsr_capture *cap, AVFrame *frame, gsr_color_conversion *color_conversion);
+ int (*capture)(gsr_capture *cap, gsr_capture_metadata *capture_metadata, gsr_color_conversion *color_conversion);
bool (*uses_external_image)(gsr_capture *cap); /* can be NULL. If NULL, return false */
bool (*set_hdr_metadata)(gsr_capture *cap, AVMasteringDisplayMetadata *mastering_display_metadata, AVContentLightMetadata *light_metadata); /* can be NULL. If NULL, return false */
uint64_t (*get_window_id)(gsr_capture *cap); /* can be NULL. Returns 0 if unknown */
bool (*is_damaged)(gsr_capture *cap); /* can be NULL */
void (*clear_damage)(gsr_capture *cap); /* can be NULL */
- void (*destroy)(gsr_capture *cap, AVCodecContext *video_codec_context);
+ void (*destroy)(gsr_capture *cap);
void *priv; /* can be NULL */
bool started;
};
-int gsr_capture_start(gsr_capture *cap, AVCodecContext *video_codec_context, AVFrame *frame);
+int gsr_capture_start(gsr_capture *cap, gsr_capture_metadata *capture_metadata);
void gsr_capture_on_event(gsr_capture *cap, gsr_egl *egl);
void gsr_capture_tick(gsr_capture *cap);
bool gsr_capture_should_stop(gsr_capture *cap, bool *err);
-int gsr_capture_capture(gsr_capture *cap, AVFrame *frame, gsr_color_conversion *color_conversion);
+int gsr_capture_capture(gsr_capture *cap, gsr_capture_metadata *capture_metadata, gsr_color_conversion *color_conversion);
bool gsr_capture_uses_external_image(gsr_capture *cap);
bool gsr_capture_set_hdr_metadata(gsr_capture *cap, AVMasteringDisplayMetadata *mastering_display_metadata, AVContentLightMetadata *light_metadata);
-void gsr_capture_destroy(gsr_capture *cap, AVCodecContext *video_codec_context);
+void gsr_capture_destroy(gsr_capture *cap);
#endif /* GSR_CAPTURE_CAPTURE_H */
diff --git a/include/capture/kms.h b/include/capture/kms.h
index bf1ba62..ce09817 100644
--- a/include/capture/kms.h
+++ b/include/capture/kms.h
@@ -5,13 +5,13 @@
typedef struct {
gsr_egl *egl;
- const char *display_to_capture; /* if this is "screen", then the first monitor is captured. A copy is made of this */
- gsr_color_depth color_depth;
- gsr_color_range color_range;
+ const char *display_to_capture; /* A copy is made of this */
bool hdr;
bool record_cursor;
int fps;
vec2i output_resolution;
+ vec2i region_size;
+ vec2i region_position;
} gsr_capture_kms_params;
gsr_capture* gsr_capture_kms_create(const gsr_capture_kms_params *params);
diff --git a/include/capture/nvfbc.h b/include/capture/nvfbc.h
index f291f33..7e30d01 100644
--- a/include/capture/nvfbc.h
+++ b/include/capture/nvfbc.h
@@ -8,14 +8,11 @@ typedef struct {
gsr_egl *egl;
const char *display_to_capture; /* if this is "screen", then the entire x11 screen is captured (all displays). A copy is made of this */
int fps;
- vec2i pos;
- vec2i size;
bool direct_capture;
- gsr_color_depth color_depth;
- gsr_color_range color_range;
bool record_cursor;
- bool use_software_video_encoder;
vec2i output_resolution;
+ vec2i region_size;
+ vec2i region_position;
} gsr_capture_nvfbc_params;
gsr_capture* gsr_capture_nvfbc_create(const gsr_capture_nvfbc_params *params);
diff --git a/include/capture/portal.h b/include/capture/portal.h
index 3989b98..74cdba9 100644
--- a/include/capture/portal.h
+++ b/include/capture/portal.h
@@ -5,8 +5,6 @@
typedef struct {
gsr_egl *egl;
- gsr_color_depth color_depth;
- gsr_color_range color_range;
bool record_cursor;
bool restore_portal_session;
/* If this is set to NULL then this defaults to $XDG_CONFIG_HOME/gpu-screen-recorder/restore_token ($XDG_CONFIG_HOME defaults to $HOME/.config) */
diff --git a/include/capture/xcomposite.h b/include/capture/xcomposite.h
index 45eb481..bf6532e 100644
--- a/include/capture/xcomposite.h
+++ b/include/capture/xcomposite.h
@@ -8,9 +8,7 @@ typedef struct {
gsr_egl *egl;
unsigned long window;
bool follow_focused; /* If this is set then |window| is ignored */
- gsr_color_range color_range;
bool record_cursor;
- gsr_color_depth color_depth;
vec2i output_resolution;
} gsr_capture_xcomposite_params;
diff --git a/include/capture/ximage.h b/include/capture/ximage.h
new file mode 100644
index 0000000..e6c3607
--- /dev/null
+++ b/include/capture/ximage.h
@@ -0,0 +1,18 @@
+#ifndef GSR_CAPTURE_XIMAGE_H
+#define GSR_CAPTURE_XIMAGE_H
+
+#include "capture.h"
+#include "../vec2.h"
+
+typedef struct {
+ gsr_egl *egl;
+ const char *display_to_capture; /* A copy is made of this */
+ bool record_cursor;
+ vec2i output_resolution;
+ vec2i region_size;
+ vec2i region_position;
+} gsr_capture_ximage_params;
+
+gsr_capture* gsr_capture_ximage_create(const gsr_capture_ximage_params *params);
+
+#endif /* GSR_CAPTURE_XIMAGE_H */
diff --git a/include/color_conversion.h b/include/color_conversion.h
index c079edd..b80be21 100644
--- a/include/color_conversion.h
+++ b/include/color_conversion.h
@@ -22,7 +22,8 @@ typedef enum {
typedef enum {
GSR_DESTINATION_COLOR_NV12, /* YUV420, BT709, 8-bit */
- GSR_DESTINATION_COLOR_P010 /* YUV420, BT2020, 10-bit */
+ GSR_DESTINATION_COLOR_P010, /* YUV420, BT2020, 10-bit */
+ GSR_DESTINATION_COLOR_RGB8
} gsr_destination_color;
typedef struct {
diff --git a/include/damage.h b/include/damage.h
index 7229418..4b10e58 100644
--- a/include/damage.h
+++ b/include/damage.h
@@ -17,6 +17,7 @@ typedef enum {
typedef struct {
gsr_egl *egl;
+ Display *display;
bool track_cursor;
gsr_damage_track_type track_type;
diff --git a/include/dbus.h b/include/dbus.h
index 6978634..58edf3c 100644
--- a/include/dbus.h
+++ b/include/dbus.h
@@ -37,7 +37,11 @@ void gsr_dbus_deinit(gsr_dbus *self);
/* The follow functions should be called in order to setup ScreenCast properly */
/* These functions that return an int return the response status code */
int gsr_dbus_screencast_create_session(gsr_dbus *self, char **session_handle);
-int gsr_dbus_screencast_select_sources(gsr_dbus *self, const char *session_handle, gsr_portal_capture_type capture_type, gsr_portal_cursor_mode cursor_mode);
+/*
+ |capture_type| is a bitmask of gsr_portal_capture_type values. gsr_portal_capture_type values that are not supported by the desktop portal will be ignored.
+ |gsr_portal_cursor_mode| is a bitmask of gsr_portal_cursor_mode values. gsr_portal_cursor_mode values that are not supported will be ignored.
+*/
+int gsr_dbus_screencast_select_sources(gsr_dbus *self, const char *session_handle, uint32_t capture_type, uint32_t cursor_mode);
int gsr_dbus_screencast_start(gsr_dbus *self, const char *session_handle, uint32_t *pipewire_node);
bool gsr_dbus_screencast_open_pipewire_remote(gsr_dbus *self, const char *session_handle, int *pipewire_fd);
const char* gsr_dbus_screencast_get_restore_token(gsr_dbus *self);
diff --git a/include/egl.h b/include/egl.h
index 8958f31..0d08270 100644
--- a/include/egl.h
+++ b/include/egl.h
@@ -10,6 +10,8 @@
#include "vec2.h"
#include "defs.h"
+typedef struct gsr_window gsr_window;
+
#ifdef _WIN64
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
@@ -102,11 +104,13 @@ typedef void(*__GLXextFuncPtr)(void);
#define GL_RG 0x8227
#define GL_RGB 0x1907
#define GL_RGBA 0x1908
+#define GL_RGB8 0x8051
#define GL_RGBA8 0x8058
#define GL_R8 0x8229
#define GL_RG8 0x822B
#define GL_R16 0x822A
#define GL_RG16 0x822C
+#define GL_RGB16 0x8054
#define GL_UNSIGNED_BYTE 0x1401
#define GL_COLOR_BUFFER_BIT 0x00004000
#define GL_TEXTURE_WRAP_S 0x2802
@@ -128,6 +132,8 @@ typedef void(*__GLXextFuncPtr)(void);
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
#define GL_DEBUG_OUTPUT 0x92E0
#define GL_SCISSOR_TEST 0x0C11
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_UNPACK_ALIGNMENT 0x0CF5
#define GL_VENDOR 0x1F00
#define GL_RENDERER 0x1F01
@@ -152,54 +158,11 @@ typedef int (*FUNC_eglQueryDisplayAttribEXT)(EGLDisplay dpy, int32_t attribute,
typedef const char* (*FUNC_eglQueryDeviceStringEXT)(void *device, int32_t name);
typedef int (*FUNC_eglQueryDmaBufModifiersEXT)(EGLDisplay dpy, int32_t format, int32_t max_modifiers, uint64_t *modifiers, int *external_only, int32_t *num_modifiers);
-#define GSR_MAX_OUTPUTS 32
-
-typedef struct {
- char *name;
- vec2i pos;
- vec2i size;
- uint32_t connector_id;
- gsr_monitor_rotation rotation;
- uint32_t monitor_identifier; /* crtc id */
-} gsr_x11_output;
-
-typedef struct {
- Display *dpy;
- Window window;
- gsr_x11_output outputs[GSR_MAX_OUTPUTS];
- int num_outputs;
- XEvent xev;
-} gsr_x11;
-
-typedef struct {
- uint32_t wl_name;
- void *output;
- vec2i pos;
- vec2i size;
- int32_t transform;
- char *name;
-} gsr_wayland_output;
-
-typedef struct {
- void *dpy;
- void *window;
- void *registry;
- void *surface;
- void *compositor;
- gsr_wayland_output outputs[GSR_MAX_OUTPUTS];
- int num_outputs;
-} gsr_wayland;
-
typedef enum {
GSR_GL_CONTEXT_TYPE_EGL,
GSR_GL_CONTEXT_TYPE_GLX
} gsr_gl_context_type;
-typedef enum {
- GSR_DISPLAY_SERVER_X11,
- GSR_DISPLAY_SERVER_WAYLAND
-} gsr_display_server;
-
typedef struct gsr_egl gsr_egl;
struct gsr_egl {
void *egl_library;
@@ -207,6 +170,7 @@ struct gsr_egl {
void *gl_library;
gsr_gl_context_type context_type;
+ gsr_window *window;
EGLDisplay egl_display;
EGLSurface egl_surface;
@@ -218,8 +182,6 @@ struct gsr_egl {
gsr_gpu_info gpu_info;
- gsr_x11 x11;
- gsr_wayland wayland;
char card_path[128];
int32_t (*eglGetError)(void);
@@ -273,6 +235,7 @@ struct gsr_egl {
void (*glTexParameteriv)(unsigned int target, unsigned int pname, const int *params);
void (*glGetTexLevelParameteriv)(unsigned int target, int level, unsigned int pname, int *params);
void (*glTexImage2D)(unsigned int target, int level, int internalFormat, int width, int height, int border, unsigned int format, unsigned int type, const void *pixels);
+ void (*glTexSubImage2D)(unsigned int target, int level, int xoffset, int yoffset, int width, int height, unsigned format, unsigned type, const void *pixels);
void (*glGetTexImage)(unsigned int target, int level, unsigned int format, unsigned int type, void *pixels);
void (*glGenFramebuffers)(int n, unsigned int *framebuffers);
void (*glBindFramebuffer)(unsigned int target, unsigned int framebuffer);
@@ -309,6 +272,7 @@ struct gsr_egl {
void (*glEnable)(unsigned int cap);
void (*glDisable)(unsigned int cap);
void (*glBlendFunc)(unsigned int sfactor, unsigned int dfactor);
+ void (*glPixelStorei)(unsigned int pname, int param);
int (*glGetUniformLocation)(unsigned int program, const char *name);
void (*glUniform1f)(int location, float v0);
void (*glUniform2f)(int location, float v0, float v1);
@@ -319,15 +283,10 @@ struct gsr_egl {
unsigned char (*glUnmapBuffer)(unsigned int target);
};
-bool gsr_egl_load(gsr_egl *self, Display *dpy, bool wayland, bool is_monitor_capture);
+bool gsr_egl_load(gsr_egl *self, gsr_window *window, bool is_monitor_capture, bool enable_debug);
void gsr_egl_unload(gsr_egl *self);
-/* Returns true if an event is available */
-bool gsr_egl_process_event(gsr_egl *self);
/* Does opengl swap with egl or glx, depending on which one is active */
void gsr_egl_swap_buffers(gsr_egl *self);
-gsr_display_server gsr_egl_get_display_server(const gsr_egl *self);
-XEvent* gsr_egl_get_event_data(gsr_egl *self);
-
#endif /* GSR_EGL_H */
diff --git a/include/image_writer.h b/include/image_writer.h
new file mode 100644
index 0000000..400edd0
--- /dev/null
+++ b/include/image_writer.h
@@ -0,0 +1,35 @@
+#ifndef GSR_IMAGE_WRITER_H
+#define GSR_IMAGE_WRITER_H
+
+#include <stdbool.h>
+
+typedef struct gsr_egl gsr_egl;
+
+typedef enum {
+ GSR_IMAGE_FORMAT_JPEG,
+ GSR_IMAGE_FORMAT_PNG
+} gsr_image_format;
+
+typedef enum {
+ GSR_IMAGE_WRITER_SOURCE_OPENGL,
+ GSR_IMAGE_WRITER_SOURCE_MEMORY
+} gsr_image_writer_source;
+
+typedef struct {
+ gsr_image_writer_source source;
+ gsr_egl *egl;
+ int width;
+ int height;
+ unsigned int texture;
+ const void *memory; /* Reference */
+} gsr_image_writer;
+
+bool gsr_image_writer_init_opengl(gsr_image_writer *self, gsr_egl *egl, int width, int height);
+/* |memory| is taken as a reference */
+bool gsr_image_writer_init_memory(gsr_image_writer *self, const void *memory, int width, int height);
+void gsr_image_writer_deinit(gsr_image_writer *self);
+
+/* Quality is between 1 and 100 where 100 is the max quality. Quality doesn't apply to lossless formats */
+bool gsr_image_writer_write_to_file(gsr_image_writer *self, const char *filepath, gsr_image_format image_format, int quality);
+
+#endif /* GSR_IMAGE_WRITER_H */
diff --git a/include/pipewire_audio.h b/include/pipewire_audio.h
index 1d37eb8..10d8c9b 100644
--- a/include/pipewire_audio.h
+++ b/include/pipewire_audio.h
@@ -9,8 +9,10 @@
#include <stdbool.h>
#define GSR_PIPEWIRE_AUDIO_MAX_STREAM_NODES 128
-#define GSR_PIPEWIRE_AUDIO_MAX_PORTS 128
+#define GSR_PIPEWIRE_AUDIO_MAX_PORTS 256
+#define GSR_PIPEWIRE_AUDIO_MAX_LINKS 256
#define GSR_PIPEWIRE_AUDIO_MAX_REQUESTED_LINKS 32
+#define GSR_PIPEWIRE_AUDIO_MAX_VIRTUAL_SINKS 32
typedef enum {
GSR_PIPEWIRE_AUDIO_NODE_TYPE_STREAM_OUTPUT, /* Application audio */
@@ -36,14 +38,31 @@ typedef struct {
char *name;
} gsr_pipewire_audio_port;
+typedef struct {
+ uint32_t id;
+ uint32_t output_node_id;
+ uint32_t input_node_id;
+} gsr_pipewire_audio_link;
+
typedef enum {
GSR_PIPEWIRE_AUDIO_LINK_INPUT_TYPE_STREAM, /* Application */
GSR_PIPEWIRE_AUDIO_LINK_INPUT_TYPE_SINK /* Combined (virtual) sink */
} gsr_pipewire_audio_link_input_type;
+typedef enum {
+ GSR_PIPEWIRE_AUDIO_REQUESTED_TYPE_STANDARD,
+ GSR_PIPEWIRE_AUDIO_REQUESTED_TYPE_DEFAULT_OUTPUT,
+ GSR_PIPEWIRE_AUDIO_REQUESTED_TYPE_DEFAULT_INPUT
+} gsr_pipewire_audio_requested_type;
+
+typedef struct {
+ char *name;
+ gsr_pipewire_audio_requested_type type;
+} gsr_pipewire_audio_requested_output;
+
typedef struct {
- char **output_names;
- int num_output_names;
+ gsr_pipewire_audio_requested_output *outputs;
+ int num_outputs;
char *input_name;
bool inverted;
gsr_pipewire_audio_node_type output_type;
@@ -59,19 +78,33 @@ typedef struct {
struct spa_hook registry_listener;
int server_version_sync;
+ struct pw_proxy *metadata_proxy;
+ struct spa_hook metadata_listener;
+ struct spa_hook metadata_proxy_listener;
+ char default_output_device_name[128];
+ char default_input_device_name[128];
+
gsr_pipewire_audio_node stream_nodes[GSR_PIPEWIRE_AUDIO_MAX_STREAM_NODES];
int num_stream_nodes;
gsr_pipewire_audio_port ports[GSR_PIPEWIRE_AUDIO_MAX_PORTS];
int num_ports;
+ gsr_pipewire_audio_link links[GSR_PIPEWIRE_AUDIO_MAX_LINKS];
+ int num_links;
+
gsr_pipewire_audio_requested_link requested_links[GSR_PIPEWIRE_AUDIO_MAX_REQUESTED_LINKS];
int num_requested_links;
+
+ struct pw_proxy *virtual_sink_proxies[GSR_PIPEWIRE_AUDIO_MAX_VIRTUAL_SINKS];
+ int num_virtual_sink_proxies;
} gsr_pipewire_audio;
bool gsr_pipewire_audio_init(gsr_pipewire_audio *self);
void gsr_pipewire_audio_deinit(gsr_pipewire_audio *self);
+bool gsr_pipewire_audio_create_virtual_sink(gsr_pipewire_audio *self, const char *name);
+
/*
This function links audio source outputs from applications that match the name |app_names| to the input
that matches the name |stream_name_input|.
@@ -112,6 +145,8 @@ bool gsr_pipewire_audio_add_link_from_apps_to_sink_inverted(gsr_pipewire_audio *
If a device or a new device starts outputting audio after this function is called and the device name matches
then it will automatically link the audio sources.
|source_names| and |sink_name_input| are case-insensitive matches.
+ |source_names| can include "default_output" or "default_input" to use the default output/input
+ and it will automatically switch when the default output/input is changed in system audio settings.
*/
bool gsr_pipewire_audio_add_link_from_sources_to_sink(gsr_pipewire_audio *self, const char **source_names, int num_source_names, const char *sink_name_input);
diff --git a/include/pipewire_video.h b/include/pipewire_video.h
index 00e2835..92622b8 100644
--- a/include/pipewire_video.h
+++ b/include/pipewire_video.h
@@ -9,7 +9,7 @@
#include <spa/param/video/format.h>
#define GSR_PIPEWIRE_VIDEO_MAX_MODIFIERS 1024
-#define GSR_PIPEWIRE_VIDEO_NUM_VIDEO_FORMATS 6
+#define GSR_PIPEWIRE_VIDEO_MAX_VIDEO_FORMATS 12
#define GSR_PIPEWIRE_VIDEO_DMABUF_MAX_PLANES 4
typedef struct gsr_egl gsr_egl;
@@ -82,7 +82,7 @@ typedef struct {
uint32_t width, height;
} crop;
- gsr_video_format supported_video_formats[GSR_PIPEWIRE_VIDEO_NUM_VIDEO_FORMATS];
+ gsr_video_format supported_video_formats[GSR_PIPEWIRE_VIDEO_MAX_VIDEO_FORMATS];
gsr_pipewire_video_data_version server_version;
gsr_pipewire_video_video_info video_info;
diff --git a/include/sound.hpp b/include/sound.hpp
index b3e34cc..87e2e2d 100644
--- a/include/sound.hpp
+++ b/include/sound.hpp
@@ -26,6 +26,17 @@ typedef struct {
unsigned int frames;
} SoundDevice;
+struct AudioDevice {
+ std::string name;
+ std::string description;
+};
+
+struct AudioDevices {
+ std::string default_output;
+ std::string default_input;
+ std::vector<AudioDevice> audio_inputs;
+};
+
enum class AudioInputType {
DEVICE,
APPLICATION
@@ -33,18 +44,12 @@ enum class AudioInputType {
struct AudioInput {
std::string name;
- std::string description;
AudioInputType type = AudioInputType::DEVICE;
bool inverted = false;
};
-struct AudioDevices {
- std::string default_output;
- std::string default_input;
- std::vector<AudioInput> audio_inputs;
-};
-
struct MergedAudioInputs {
+ std::string track_name;
std::vector<AudioInput> audio_inputs;
};
@@ -56,14 +61,12 @@ typedef enum {
/*
Get a sound device by name, returning the device into the |device| parameter.
+ |device_name| can be a device name or "default_output" or "default_input".
+ If the device name is "default_output" or "default_input" then it will automatically switch which
+ device is records from when the default output/input is changed in the system audio settings.
Returns 0 on success, or a negative value on failure.
*/
int sound_device_get_by_name(SoundDevice *device, const char *device_name, const char *description, unsigned int num_channels, unsigned int period_frame_size, AudioFormat audio_format);
-/*
- Creates a module-combine-sink and connects to it for recording, returning the device into the |device| parameter.
- Returns 0 on success, or a negative value on failure.
-*/
-int sound_device_create_combined_sink_connect(SoundDevice *device, const char *combined_sink_name, unsigned int num_channels, unsigned int period_frame_size, AudioFormat audio_format);
void sound_device_close(SoundDevice *device);
diff --git a/include/utils.h b/include/utils.h
index 5b771ba..fd340e8 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -7,13 +7,15 @@
#include <stdbool.h>
#include <stdint.h>
+#define CONNECTOR_TYPE_COUNTS 32
+
typedef struct AVCodecContext AVCodecContext;
typedef struct AVFrame AVFrame;
typedef struct {
const char *name;
int name_len;
- vec2i pos;
+ vec2i pos; /* This is 0, 0 on wayland. Use |drm_monitor_get_display_server_data| to get the position */
vec2i size;
uint32_t connector_id; /* Only on x11 and drm */
gsr_monitor_rotation rotation; /* Only on x11 and wayland */
@@ -27,20 +29,31 @@ typedef struct {
bool found_monitor;
} get_monitor_by_name_userdata;
+typedef struct {
+ int type;
+ int count;
+ int count_active;
+} drm_connector_type_count;
+
double clock_get_monotonic_seconds(void);
bool generate_random_characters(char *buffer, int buffer_size, const char *alphabet, size_t alphabet_size);
bool generate_random_characters_standard_alphabet(char *buffer, int buffer_size);
typedef void (*active_monitor_callback)(const gsr_monitor *monitor, void *userdata);
void for_each_active_monitor_output_x11_not_cached(Display *display, active_monitor_callback callback, void *userdata);
-void for_each_active_monitor_output_x11(const gsr_egl *egl, active_monitor_callback callback, void *userdata);
-void for_each_active_monitor_output(const gsr_egl *egl, gsr_connection_type connection_type, active_monitor_callback callback, void *userdata);
+void for_each_active_monitor_output(const gsr_window *window, const char *card_path, gsr_connection_type connection_type, active_monitor_callback callback, void *userdata);
bool get_monitor_by_name(const gsr_egl *egl, gsr_connection_type connection_type, const char *name, gsr_monitor *monitor);
-gsr_monitor_rotation drm_monitor_get_display_server_rotation(const gsr_egl *egl, const gsr_monitor *monitor);
+bool drm_monitor_get_display_server_data(const gsr_window *window, const gsr_monitor *monitor, gsr_monitor_rotation *monitor_rotation, vec2i *monitor_position);
+
+int get_connector_type_by_name(const char *name);
+drm_connector_type_count* drm_connector_types_get_index(drm_connector_type_count *type_counts, int *num_type_counts, int connector_type);
+uint32_t monitor_identifier_from_type_and_count(int monitor_type_index, int monitor_type_count);
bool gl_get_gpu_info(gsr_egl *egl, gsr_gpu_info *info);
-bool gl_driver_version_greater_than(const gsr_egl *egl, int major, int minor, int patch);
+bool version_greater_than(int major, int minor, int patch, int other_major, int other_minor, int other_patch);
+bool gl_driver_version_greater_than(const gsr_gpu_info *gpu_info, int major, int minor, int patch);
+bool try_card_has_valid_plane(const char *card_path);
/* |output| should be at least 128 bytes in size */
bool gsr_get_valid_card_path(gsr_egl *egl, char *output, bool is_monitor_capture);
/* |render_path| should be at least 128 bytes in size */
@@ -56,4 +69,6 @@ bool vaapi_copy_egl_image_to_video_surface(gsr_egl *egl, EGLImage image, vec2i s
vec2i scale_keep_aspect_ratio(vec2i from, vec2i to);
+unsigned int gl_create_texture(gsr_egl *egl, int width, int height, int internal_format, unsigned int format, int filter);
+
#endif /* GSR_UTILS_H */
diff --git a/include/window/wayland.h b/include/window/wayland.h
new file mode 100644
index 0000000..3535b0f
--- /dev/null
+++ b/include/window/wayland.h
@@ -0,0 +1,8 @@
+#ifndef GSR_WINDOW_WAYLAND_H
+#define GSR_WINDOW_WAYLAND_H
+
+#include "window.h"
+
+gsr_window* gsr_window_wayland_create(void);
+
+#endif /* GSR_WINDOW_WAYLAND_H */
diff --git a/include/window/window.h b/include/window/window.h
new file mode 100644
index 0000000..7839f6a
--- /dev/null
+++ b/include/window/window.h
@@ -0,0 +1,37 @@
+#ifndef GSR_WINDOW_H
+#define GSR_WINDOW_H
+
+#include "../utils.h"
+#include <stdbool.h>
+
+typedef union _XEvent XEvent;
+typedef struct gsr_window gsr_window;
+
+typedef enum {
+ GSR_DISPLAY_SERVER_X11,
+ GSR_DISPLAY_SERVER_WAYLAND
+} gsr_display_server;
+
+struct gsr_window {
+ void (*destroy)(gsr_window *self);
+ /* Returns true if an event is available */
+ bool (*process_event)(gsr_window *self);
+ XEvent* (*get_event_data)(gsr_window *self); /* can be NULL */
+ gsr_display_server (*get_display_server)(void);
+ void* (*get_display)(gsr_window *self);
+ void* (*get_window)(gsr_window *self);
+ void (*for_each_active_monitor_output_cached)(const gsr_window *self, active_monitor_callback callback, void *userdata);
+ void *priv;
+};
+
+void gsr_window_destroy(gsr_window *self);
+
+/* Returns true if an event is available */
+bool gsr_window_process_event(gsr_window *self);
+XEvent* gsr_window_get_event_data(gsr_window *self);
+gsr_display_server gsr_window_get_display_server(const gsr_window *self);
+void* gsr_window_get_display(gsr_window *self);
+void* gsr_window_get_window(gsr_window *self);
+void gsr_window_for_each_active_monitor_output_cached(const gsr_window *self, active_monitor_callback callback, void *userdata);
+
+#endif /* GSR_WINDOW_H */
diff --git a/include/window/x11.h b/include/window/x11.h
new file mode 100644
index 0000000..e0c2948
--- /dev/null
+++ b/include/window/x11.h
@@ -0,0 +1,10 @@
+#ifndef GSR_WINDOW_X11_H
+#define GSR_WINDOW_X11_H
+
+#include "window.h"
+
+typedef struct _XDisplay Display;
+
+gsr_window* gsr_window_x11_create(Display *display);
+
+#endif /* GSR_WINDOW_X11_H */