summaryrefslogtreecommitdiff
path: root/lib/river/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/river/src')
-rw-r--r--lib/river/src/river-output.c301
-rw-r--r--lib/river/src/river.c4
2 files changed, 287 insertions, 18 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);
diff --git a/lib/river/src/river.c b/lib/river/src/river.c
index 6f94c9c..38191ea 100644
--- a/lib/river/src/river.c
+++ b/lib/river/src/river.c
@@ -247,8 +247,8 @@ static void global_registry_handler(void* data, struct wl_registry* registry, ui
if (strcmp(interface, wl_output_interface.name) == 0) {
if (priv->river_status_manager == NULL) return;
struct wl_output* wl_out = wl_registry_bind(registry, id, &wl_output_interface, 4);
- AstalRiverOutput* output =
- astal_river_output_new(id, wl_out, priv->river_status_manager, priv->river_control, priv->seat, priv->display);
+ AstalRiverOutput* output = astal_river_output_new(
+ id, wl_out, priv->river_status_manager, priv->river_control, priv->seat, priv->display);
self->outputs = g_list_append(self->outputs, output);
g_object_notify(G_OBJECT(self), "outputs");