river-status support
This commit is contained in:
@@ -4,12 +4,22 @@
|
||||
#include <libguile.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libguile/bitvectors.h"
|
||||
#include "libguile/boolean.h"
|
||||
#include "libguile/foreign-object.h"
|
||||
#include "libguile/list.h"
|
||||
#include "libguile/numbers.h"
|
||||
#include "libguile/pairs.h"
|
||||
#include "libguile/scm.h"
|
||||
#include "libguile/strings.h"
|
||||
#include "libguile/symbols.h"
|
||||
#include "riverguile.h"
|
||||
#include "output.h"
|
||||
#include "seat.h"
|
||||
|
||||
#include "river-control-unstable-v1.h"
|
||||
#include "call-new-output-handler.h"
|
||||
#include "wayland-util.h"
|
||||
|
||||
/**
|
||||
* ISO C forbids casting a function pointer to a void pointer because on some
|
||||
@@ -246,6 +256,83 @@ error:
|
||||
return SCM_UNSPECIFIED;
|
||||
}
|
||||
|
||||
static SCM output_t;
|
||||
|
||||
static SCM scm_str(const char *chars) {
|
||||
if (chars != NULL)
|
||||
return scm_from_utf8_string(chars);
|
||||
return scm_from_utf8_string("");
|
||||
}
|
||||
|
||||
static SCM bitvector_tags(uint32_t tags) {
|
||||
SCM bitvector = scm_c_make_bitvector(32, SCM_BOOL_F);
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if ((tags & (1 << i)) != 0)
|
||||
scm_c_bitvector_set_bit_x(bitvector, i);
|
||||
}
|
||||
return bitvector;
|
||||
}
|
||||
|
||||
static SCM output_for(struct Output *output) {
|
||||
SCM output_scm = scm_make_foreign_object_0(output_t);
|
||||
scm_foreign_object_set_x(output_scm, 0, scm_from_int(output->name));
|
||||
scm_foreign_object_set_x(output_scm, 1,
|
||||
bitvector_tags(output->tags.focused_tags));
|
||||
SCM view_tags = SCM_EOL;
|
||||
for (ssize_t i = output->tags.view_tags_len - 1; i >= 0; i--)
|
||||
view_tags = scm_cons(bitvector_tags(*(output->tags.view_tags + i)), view_tags);
|
||||
scm_foreign_object_set_x(output_scm, 2, view_tags);
|
||||
scm_foreign_object_set_x(output_scm, 3,
|
||||
bitvector_tags(output->tags.urgent_tags));
|
||||
scm_foreign_object_set_x(output_scm, 4, scm_str(output->tags.layout_name));
|
||||
return output_scm;
|
||||
}
|
||||
|
||||
static SCM outputs(void) {
|
||||
SCM lst = SCM_EOL;
|
||||
struct Output *output, *tmp_o;
|
||||
wl_list_for_each_safe(output, tmp_o, &context.outputs, link)
|
||||
lst = scm_cons(output_for(output), lst);
|
||||
|
||||
return scm_reverse_x(lst, SCM_EOL);
|
||||
}
|
||||
|
||||
static SCM seat_t;
|
||||
|
||||
// Assumes there's only one seat available
|
||||
static SCM seat(void) {
|
||||
struct Seat *seat;
|
||||
// Take the first seat
|
||||
wl_list_for_each(seat, &context.seats, link)
|
||||
break;
|
||||
struct Output *output = NULL;
|
||||
if ( seat->status.focused_output != NULL )
|
||||
wl_list_for_each(output, &context.outputs, link)
|
||||
if ( output->wl_output == seat->status.focused_output )
|
||||
break;
|
||||
return scm_make_foreign_object_3(
|
||||
seat_t,
|
||||
output != NULL ? output_for(output) : SCM_BOOL_F,
|
||||
scm_str(seat->status.focused_view_title),
|
||||
scm_str(seat->status.mode));
|
||||
}
|
||||
|
||||
#define getters(X) \
|
||||
X(output_t, output_name, "output-name", 0) \
|
||||
X(output_t, output_focused_tags, "output-focused-tags", 1) \
|
||||
X(output_t, output_view_tags, "output-view-tags", 2) \
|
||||
X(output_t, output_urgent_tags, "output-urgent-tags", 3) \
|
||||
X(output_t, output_layout_name, "output-layout-name", 4) \
|
||||
X(seat_t, seat_focused_output, "seat-focused-output", 0) \
|
||||
X(seat_t, seat_focused_view_title, "seat-focused-view-title", 1) \
|
||||
X(seat_t, seat_mode, "seat-mode", 2)
|
||||
|
||||
#define X(t, c, scm, i) static SCM c (SCM output) { scm_assert_foreign_object_type(t, output); return scm_foreign_object_ref(output, i); }
|
||||
getters(X)
|
||||
#undef X
|
||||
|
||||
|
||||
|
||||
static void *load_script_inner (void *data)
|
||||
{
|
||||
const char *path = (char *)data;
|
||||
@@ -265,6 +352,30 @@ void *load_script (void *data)
|
||||
scm_c_define_gsubr_fix("install-handler", 2, 0, 0, install_handler);
|
||||
scm_c_define_gsubr_fix("riverctl", 1, 0, 1, riverctl);
|
||||
|
||||
output_t = scm_make_foreign_object_type(
|
||||
scm_from_utf8_symbol("output"),
|
||||
scm_list_5(scm_from_utf8_symbol("name"),
|
||||
scm_from_utf8_symbol("focused-tags"),
|
||||
scm_from_utf8_symbol("view-tags"),
|
||||
scm_from_utf8_symbol("urgent-tags"),
|
||||
scm_from_utf8_symbol("layout")),
|
||||
NULL);
|
||||
|
||||
seat_t = scm_make_foreign_object_type(
|
||||
scm_from_utf8_symbol("seat"),
|
||||
scm_list_3(scm_from_utf8_symbol("focused-output"),
|
||||
scm_from_utf8_symbol("focused-view-title"),
|
||||
scm_from_utf8_symbol("mode")),
|
||||
NULL);
|
||||
|
||||
scm_c_define_gsubr_fix("outputs", 0, 0, 0, outputs);
|
||||
scm_c_define_gsubr_fix("seat", 0, 0, 0, seat);
|
||||
|
||||
#define X(t, c, scm, i) scm_c_define_gsubr_fix(scm, 1, 0, 0, c);
|
||||
getters(X)
|
||||
#undef X
|
||||
|
||||
|
||||
/* Continuation barrier causes stack unwind on exceptions to stop here.
|
||||
* Otherwise the entire stack created by scm_with_guile() would be
|
||||
* unwound. This makes responding to exceptions nicer.
|
||||
|
||||
Reference in New Issue
Block a user