diff options
author | kotontrion <[email protected]> | 2025-03-05 14:54:23 +0100 |
---|---|---|
committer | noname <[email protected]> | 2025-04-25 01:19:20 +1000 |
commit | dcbe03a985ad4ecb90e57323efe96dd818957b27 (patch) | |
tree | 1377a5c46e641db242c95cc2774d2cd719cd7de5 /lib/river/src/river-output.c | |
parent | 8c8578c2090e460b74dc04c2000eaaf6adc13d7c (diff) |
AstalRiver: add wl_output properties.
Diffstat (limited to 'lib/river/src/river-output.c')
-rw-r--r-- | lib/river/src/river-output.c | 301 |
1 files changed, 285 insertions, 16 deletions
diff --git a/lib/river/src/river-output.c b/lib/river/src/river-output.c index 078efb9..6e46a96 100644 --- a/lib/river/src/river-output.c +++ b/lib/river/src/river-output.c @@ -1,10 +1,24 @@ #include <gio/gio.h> +#include <stdint.h> +#include <wayland-client-protocol.h> +#include "astal-river.h.in" #include "glib-object.h" #include "glib.h" #include "river-private.h" #include "river-status-unstable-v1-client.h" +G_DEFINE_ENUM_TYPE( + AstalRiverTransform, astal_river_transform, + G_DEFINE_ENUM_VALUE(ASTAL_RIVER_TRANSFORM_NORMAL, "normal"), + G_DEFINE_ENUM_VALUE(ASTAL_RIVER_TRANSFORM_ROTATE_90_DEG, "rotate-90"), + G_DEFINE_ENUM_VALUE(ASTAL_RIVER_TRANSFORM_ROTATE_180_DEG, "rotate-180"), + G_DEFINE_ENUM_VALUE(ASTAL_RIVER_TRANSFORM_ROTATE_270_DEG, "rotate-270"), + G_DEFINE_ENUM_VALUE(ASTAL_RIVER_TRANSFORM_FLIPPED, "flipped"), + G_DEFINE_ENUM_VALUE(ASTAL_RIVER_TRANSFORM_FLIPPED_ROTATE_90_DEG, "flipped-rotate-90"), + G_DEFINE_ENUM_VALUE(ASTAL_RIVER_TRANSFORM_FLIPPED_ROTATE_180_DEG, "flipped-rotate-180"), + G_DEFINE_ENUM_VALUE(ASTAL_RIVER_TRANSFORM_FLIPPED_ROTATE_270_DEG, "flipped-rotate-270")); + struct _AstalRiverOutput { GObject parent_instance; guint focused_tags; @@ -13,7 +27,22 @@ struct _AstalRiverOutput { gchar* layout_name; gchar* focused_view; guint id; + gchar* name; + gchar* description; + gchar* make; + gchar* model; + + gint scale_factor; + gint x; + gint y; + gint width; + gint height; + gint physical_width; + gint physical_height; + gdouble refresh_rate; + + AstalRiverTransform transform; }; typedef struct { @@ -35,6 +64,18 @@ typedef enum { ASTAL_RIVER_OUTPUT_PROP_NAME, ASTAL_RIVER_OUTPUT_PROP_FOCUSED_VIEW, ASTAL_RIVER_OUTPUT_PROP_ID, + ASTAL_RIVER_OUTPUT_PROP_DESCRIPTION, + ASTAL_RIVER_OUTPUT_PROP_MAKE, + ASTAL_RIVER_OUTPUT_PROP_MODEL, + ASTAL_RIVER_OUTPUT_PROP_X, + ASTAL_RIVER_OUTPUT_PROP_Y, + ASTAL_RIVER_OUTPUT_PROP_WIDTH, + ASTAL_RIVER_OUTPUT_PROP_HEIGHT, + ASTAL_RIVER_OUTPUT_PROP_PHYSICAL_WIDTH, + ASTAL_RIVER_OUTPUT_PROP_PHYSICAL_HEIGHT, + ASTAL_RIVER_OUTPUT_PROP_TRANSFORM, + ASTAL_RIVER_OUTPUT_PROP_REFRESH_RATE, + ASTAL_RIVER_OUTPUT_PROP_SCALE_FACTOR, ASTAL_RIVER_OUTPUT_N_PROPERTIES } AstalRiverOutputProperties; @@ -112,9 +153,9 @@ void astal_river_output_set_focused_view(AstalRiverOutput* self, const gchar* fo * sets the focused tags of the output * */ -void astal_river_output_set_focused_tags(AstalRiverOutput* self, guint tags) { +void astal_river_output_set_focused_tags(AstalRiverOutput* self, guint tags) { AstalRiverOutputPrivate* priv = astal_river_output_get_instance_private(self); - gchar *tagstring = g_strdup_printf("%i", tags); + gchar* tagstring = g_strdup_printf("%i", tags); zriver_control_v1_add_argument(priv->river_control, "set-focused-tags"); zriver_control_v1_add_argument(priv->river_control, tagstring); @@ -133,7 +174,6 @@ void astal_river_output_set_focused_tags(AstalRiverOutput* self, guint tags) { */ guint astal_river_output_get_focused_tags(AstalRiverOutput* self) { return self->focused_tags; } - /** * astal_river_output_get_urgent_tags * @self: the AstalRiverOutput object @@ -154,6 +194,108 @@ guint astal_river_output_get_urgent_tags(AstalRiverOutput* self) { return self-> */ guint astal_river_output_get_occupied_tags(AstalRiverOutput* self) { return self->occupied_tags; } +/** + * astal_river_output_get_description + * @self: the AstalRiverOutput object + * + * the description of the output + */ +const gchar* astal_river_output_get_description(AstalRiverOutput* self) { + return self->description; +} + +/** + * astal_river_output_get_make + * @self: the AstalRiverOutput object + * + * the make of the output + */ +const gchar* astal_river_output_get_make(AstalRiverOutput* self) { return self->make; } + +/** + * astal_river_output_get_model + * @self: the AstalRiverOutput object + * + * the model of the output + */ +const gchar* astal_river_output_get_model(AstalRiverOutput* self) { return self->model; } + +/** + * astal_river_output_get_x + * @self: the AstalRiverOutput object + * + * the x coordinate of the outputs position + */ +gint astal_river_output_get_x(AstalRiverOutput* self) { return self->x; } + +/** + * astal_river_output_get_y + * @self: the AstalRiverOutput object + * + * the y coordinate of the outputs position + */ +gint astal_river_output_get_y(AstalRiverOutput* self) { return self->y; } + +/** + * astal_river_output_get_width + * @self: the AstalRiverOutput object + * + * the width of the output + */ +gint astal_river_output_get_width(AstalRiverOutput* self) { return self->width; } + +/** + * astal_river_output_get_height + * @self: the AstalRiverOutput object + * + * the height of the output + */ +gint astal_river_output_get_height(AstalRiverOutput* self) { return self->height; } + +/** + * astal_river_output_get_physical_width + * @self: the AstalRiverOutput object + * + * the physical width of the output + */ +gint astal_river_output_get_physical_width(AstalRiverOutput* self) { return self->physical_width; } + +/** + * astal_river_output_get_physical_height + * @self: the AstalRiverOutput object + * + * the physical height of the output + */ +gint astal_river_output_get_physical_height(AstalRiverOutput* self) { + return self->physical_height; +} + +/** + * astal_river_output_get_scale_factor + * @self: the AstalRiverOutput object + * + * the scale factor of the output + */ +gdouble astal_river_output_get_scale_factor(AstalRiverOutput* self) { return self->scale_factor; } + +/** + * astal_river_output_get_refresh_rate + * @self: the AstalRiverOutput object + * + * the refresh rate of the output + */ +gdouble astal_river_output_get_refresh_rate(AstalRiverOutput* self) { return self->refresh_rate; } + +/** + * astal_river_output_get_transform + * @self: the AstalRiverOutput object + * + * the transform of the output + */ +AstalRiverTransform astal_river_output_get_transform(AstalRiverOutput* self) { + return self->transform; +} + struct wl_output* astal_river_output_get_wl_output(AstalRiverOutput* self) { AstalRiverOutputPrivate* priv = astal_river_output_get_instance_private(self); return priv->wl_output; @@ -165,25 +307,61 @@ static void astal_river_output_get_property(GObject* object, guint property_id, switch (property_id) { case ASTAL_RIVER_OUTPUT_PROP_FOCUSED_TAGS: - g_value_set_uint(value, self->focused_tags); + g_value_set_uint(value, astal_river_output_get_focused_tags(self)); break; case ASTAL_RIVER_OUTPUT_PROP_OCCUPIED_TAGS: - g_value_set_uint(value, self->occupied_tags); + g_value_set_uint(value, astal_river_output_get_occupied_tags(self)); break; case ASTAL_RIVER_OUTPUT_PROP_URGENT_TAGS: - g_value_set_uint(value, self->urgent_tags); + g_value_set_uint(value, astal_river_output_get_urgent_tags(self)); break; case ASTAL_RIVER_OUTPUT_PROP_ID: - g_value_set_uint(value, self->id); + g_value_set_uint(value, astal_river_output_get_id(self)); break; case ASTAL_RIVER_OUTPUT_PROP_NAME: - g_value_set_string(value, self->name); + g_value_set_string(value, astal_river_output_get_name(self)); break; case ASTAL_RIVER_OUTPUT_PROP_LAYOUT_NAME: - g_value_set_string(value, self->layout_name); + g_value_set_string(value, astal_river_output_get_layout_name(self)); break; case ASTAL_RIVER_OUTPUT_PROP_FOCUSED_VIEW: - g_value_set_string(value, self->focused_view); + g_value_set_string(value, astal_river_output_get_focused_view(self)); + break; + case ASTAL_RIVER_OUTPUT_PROP_DESCRIPTION: + g_value_set_string(value, astal_river_output_get_description(self)); + break; + case ASTAL_RIVER_OUTPUT_PROP_MAKE: + g_value_set_string(value, astal_river_output_get_make(self)); + break; + case ASTAL_RIVER_OUTPUT_PROP_MODEL: + g_value_set_string(value, astal_river_output_get_model(self)); + break; + case ASTAL_RIVER_OUTPUT_PROP_X: + g_value_set_int(value, astal_river_output_get_x(self)); + break; + case ASTAL_RIVER_OUTPUT_PROP_Y: + g_value_set_int(value, astal_river_output_get_y(self)); + break; + case ASTAL_RIVER_OUTPUT_PROP_WIDTH: + g_value_set_int(value, astal_river_output_get_width(self)); + break; + case ASTAL_RIVER_OUTPUT_PROP_HEIGHT: + g_value_set_int(value, astal_river_output_get_height(self)); + break; + case ASTAL_RIVER_OUTPUT_PROP_PHYSICAL_WIDTH: + g_value_set_int(value, astal_river_output_get_physical_width(self)); + break; + case ASTAL_RIVER_OUTPUT_PROP_PHYSICAL_HEIGHT: + g_value_set_int(value, astal_river_output_get_physical_height(self)); + break; + case ASTAL_RIVER_OUTPUT_PROP_SCALE_FACTOR: + g_value_set_int(value, astal_river_output_get_scale_factor(self)); + break; + case ASTAL_RIVER_OUTPUT_PROP_REFRESH_RATE: + g_value_set_double(value, astal_river_output_get_refresh_rate(self)); + break; + case ASTAL_RIVER_OUTPUT_PROP_TRANSFORM: + g_value_set_enum(value, astal_river_output_get_transform(self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); @@ -267,6 +445,64 @@ static void astal_river_wl_output_handle_name(void* data, struct wl_output* outp g_signal_emit(self, astal_river_output_signals[ASTAL_RIVER_OUTPUT_SIGNAL_CHANGED], 0); } +static void astal_river_wl_output_handle_geometry(void* data, struct wl_output* output, int32_t x, + int32_t y, int32_t physical_width, + int32_t physical_height, int32_t subpixel, + const char* make, const char* model, + int32_t transform) { + AstalRiverOutput* self = ASTAL_RIVER_OUTPUT(data); + self->x = x; + self->y = y; + self->physical_height = physical_height; + self->physical_width = physical_width; + self->transform = transform; + g_free(self->make); + self->make = g_strdup(make); + g_free(self->model); + self->model = g_strdup(model); + g_object_notify(G_OBJECT(self), "x"); + g_object_notify(G_OBJECT(self), "y"); + g_object_notify(G_OBJECT(self), "physical-width"); + g_object_notify(G_OBJECT(self), "physical-height"); + g_object_notify(G_OBJECT(self), "transform"); + g_object_notify(G_OBJECT(self), "make"); + g_object_notify(G_OBJECT(self), "model"); + g_signal_emit_by_name(self, "changed", 0); +} + +static void astal_river_wl_output_handle_mode(void* data, struct wl_output* output, uint32_t mode, + int32_t width, int32_t height, int32_t refresh) { + AstalRiverOutput* self = ASTAL_RIVER_OUTPUT(data); + + if (mode != WL_OUTPUT_MODE_CURRENT) return; + + self->height = height; + self->width = width; + self->refresh_rate = refresh / 1000.0; + g_object_notify(G_OBJECT(self), "height"); + g_object_notify(G_OBJECT(self), "width"); + g_object_notify(G_OBJECT(self), "refresh-rate"); + g_signal_emit_by_name(self, "changed", 0); +} + +static void astal_river_wl_output_handle_scale(void* data, struct wl_output* output, + int32_t scale) { + AstalRiverOutput* self = ASTAL_RIVER_OUTPUT(data); + + self->scale_factor = scale; + g_object_notify(G_OBJECT(self), "scale-factor"); + g_signal_emit_by_name(self, "changed", 0); +} + +static void astal_river_wl_output_handle_description(void* data, struct wl_output* output, + const char* description) { + AstalRiverOutput* self = ASTAL_RIVER_OUTPUT(data); + g_free(self->description); + self->description = g_strdup(description); + g_object_notify(G_OBJECT(self), "description"); + g_signal_emit_by_name(self, "changed", 0); +} + static const struct zriver_output_status_v1_listener output_status_listener = { .focused_tags = astal_river_handle_focused_tags, .view_tags = astal_river_handle_occupied_tags, @@ -277,10 +513,10 @@ static const struct zriver_output_status_v1_listener output_status_listener = { static const struct wl_output_listener wl_output_listener = { .name = astal_river_wl_output_handle_name, - .geometry = noop, - .mode = noop, - .scale = noop, - .description = noop, + .geometry = astal_river_wl_output_handle_geometry, + .mode = astal_river_wl_output_handle_mode, + .scale = astal_river_wl_output_handle_scale, + .description = astal_river_wl_output_handle_description, .done = noop, }; @@ -304,8 +540,7 @@ static void astal_river_output_init(AstalRiverOutput* self) {} AstalRiverOutput* astal_river_output_new(guint id, struct wl_output* wl_output, struct zriver_status_manager_v1* status_manager, struct zriver_control_v1* river_control, - struct wl_seat* seat, - struct wl_display* wl_display) { + struct wl_seat* seat, struct wl_display* wl_display) { AstalRiverOutput* self = g_object_new(ASTAL_RIVER_TYPE_OUTPUT, NULL); AstalRiverOutputPrivate* priv = astal_river_output_get_instance_private(self); @@ -385,6 +620,40 @@ static void astal_river_output_class_init(AstalRiverOutputClass* class) { g_param_spec_string("focused-view", "focused-view", "name of last focused view on this output", NULL, G_PARAM_READABLE); + astal_river_output_properties[ASTAL_RIVER_OUTPUT_PROP_DESCRIPTION] = g_param_spec_string( + "description", "description", "description of the output", NULL, G_PARAM_READABLE); + astal_river_output_properties[ASTAL_RIVER_OUTPUT_PROP_MAKE] = + g_param_spec_string("make", "make", "make of the output", NULL, G_PARAM_READABLE); + astal_river_output_properties[ASTAL_RIVER_OUTPUT_PROP_MODEL] = + g_param_spec_string("model", "model", "model of the output", NULL, G_PARAM_READABLE); + astal_river_output_properties[ASTAL_RIVER_OUTPUT_PROP_X] = g_param_spec_int( + "x", "x", "x coordinate of the output", INT_MIN, INT_MAX, 0, G_PARAM_READABLE); + astal_river_output_properties[ASTAL_RIVER_OUTPUT_PROP_Y] = g_param_spec_int( + "y", "y", "y coordinate of the output", INT_MIN, INT_MAX, 0, G_PARAM_READABLE); + astal_river_output_properties[ASTAL_RIVER_OUTPUT_PROP_WIDTH] = + g_param_spec_int("width", "width", "width of the output", 0, INT_MAX, 0, G_PARAM_READABLE); + astal_river_output_properties[ASTAL_RIVER_OUTPUT_PROP_HEIGHT] = g_param_spec_int( + "height", "height", "height of the output", 0, INT_MAX, 0, G_PARAM_READABLE); + astal_river_output_properties[ASTAL_RIVER_OUTPUT_PROP_PHYSICAL_WIDTH] = + g_param_spec_int("physical-width", "physical-width", "physical width of the output", 0, + INT_MAX, 0, G_PARAM_READABLE); + astal_river_output_properties[ASTAL_RIVER_OUTPUT_PROP_PHYSICAL_HEIGHT] = + g_param_spec_int("physical-height", "physical-height", "physical height of the output", 0, + INT_MAX, 0, G_PARAM_READABLE); + astal_river_output_properties[ASTAL_RIVER_OUTPUT_PROP_SCALE_FACTOR] = + g_param_spec_int("scale-factor", "scale-factor", "scale factor of the output", 0, INT_MAX, + 0, G_PARAM_READABLE); + astal_river_output_properties[ASTAL_RIVER_OUTPUT_PROP_REFRESH_RATE] = + g_param_spec_double("refresh-rate", "refresh-rate", "refresh rate of the output", 0, + INT_MAX, 0, G_PARAM_READABLE); + /** + * AstalRiverOutput:transform: (type AstalRiverTransform) + * + */ + astal_river_output_properties[ASTAL_RIVER_OUTPUT_PROP_TRANSFORM] = g_param_spec_enum( + "transform", "transform", "the transfrom of the output", ASTAL_RIVER_TYPE_TRANSFORM, + ASTAL_RIVER_TRANSFORM_NORMAL, G_PARAM_READABLE); + g_object_class_install_properties(object_class, ASTAL_RIVER_OUTPUT_N_PROPERTIES, astal_river_output_properties); |