diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/capture/capture.h | 20 | ||||
-rw-r--r-- | include/capture/kms.h | 6 | ||||
-rw-r--r-- | include/capture/nvfbc.h | 7 | ||||
-rw-r--r-- | include/capture/portal.h | 2 | ||||
-rw-r--r-- | include/capture/xcomposite.h | 2 | ||||
-rw-r--r-- | include/capture/ximage.h | 18 | ||||
-rw-r--r-- | include/color_conversion.h | 3 | ||||
-rw-r--r-- | include/damage.h | 1 | ||||
-rw-r--r-- | include/dbus.h | 6 | ||||
-rw-r--r-- | include/egl.h | 61 | ||||
-rw-r--r-- | include/image_writer.h | 35 | ||||
-rw-r--r-- | include/pipewire_audio.h | 41 | ||||
-rw-r--r-- | include/pipewire_video.h | 4 | ||||
-rw-r--r-- | include/sound.hpp | 27 | ||||
-rw-r--r-- | include/utils.h | 25 | ||||
-rw-r--r-- | include/window/wayland.h | 8 | ||||
-rw-r--r-- | include/window/window.h | 37 | ||||
-rw-r--r-- | include/window/x11.h | 10 |
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 */ |