aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2021-06-20 14:07:17 +0200
committerThomas White <taw@physics.org>2021-06-20 14:07:17 +0200
commitd9bbee4fa984cb641e868b69331b4587f2281ddc (patch)
tree7be9556042a0720c8a721e258c3e40a7fe73acc6
parent3b1227ccc5ed3ddb9f13199cefe05baf34156c22 (diff)
Fixture display: Get the fixture names from Starlet
-rw-r--r--meson.build6
-rw-r--r--src/repl-connection.c48
-rw-r--r--src/repl-connection.h4
-rw-r--r--src/starlet-fixture-display.c83
4 files changed, 122 insertions, 19 deletions
diff --git a/meson.build b/meson.build
index dfe81e4..6edbd81 100644
--- a/meson.build
+++ b/meson.build
@@ -35,7 +35,11 @@ library('guile-ola', ['src/guile-ola.cpp'],
executable('starlet-fixture-display',
['src/starlet-fixture-display.c',
'src/repl-connection.c'],
- dependencies: [gtk_dep, cairo_dep, pango_dep, pangocairo_dep],
+ dependencies: [gtk_dep,
+ cairo_dep,
+ pango_dep,
+ pangocairo_dep,
+ guile_dep],
install: true)
diff --git a/src/repl-connection.c b/src/repl-connection.c
index 622e260..a159c0b 100644
--- a/src/repl-connection.c
+++ b/src/repl-connection.c
@@ -24,9 +24,11 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
+#include <ctype.h>
#include <glib.h>
#include <gio/gio.h>
#include <gio/gunixsocketaddress.h>
+#include <libguile.h>
#include <libintl.h>
#define _(x) gettext(x)
@@ -38,6 +40,8 @@ struct _replconnection
GSocketConnection *conn;
char inbuf[1024];
char input[2048];
+ void (*process_func)(SCM sexp, void *data);
+ void *process_func_data;
};
@@ -71,10 +75,46 @@ static char *strip_crap(const char *line_orig)
}
+static int find_reply(const char *line)
+{
+ const char *eq;
+ size_t eq_pos;
+ int i;
+
+ if ( line[0] != '$' ) return 0;
+
+ eq = strstr(line, " = ");
+ if ( eq == NULL ) return 0;
+ eq_pos = eq - line;
+
+ for ( i=1; i<eq_pos; i++ ) {
+ if ( !isdigit(line[i]) ) return 0;
+ }
+
+ return eq_pos+3;
+}
+
+
static void process_line(const char *line_orig, ReplConnection *repl)
{
+ SCM port, str, sexp;
+ int eq_pos;
char *line = strip_crap(line_orig);
+
printf("%p: '%s'\n", repl, line);
+ eq_pos = find_reply(line);
+ if ( eq_pos == 0 ) {
+ free(line);
+ return;
+ }
+
+ str = scm_from_utf8_string(line+eq_pos);
+ port = scm_open_input_string(str);
+ sexp = scm_read(port);
+
+ repl->process_func(sexp, repl->process_func_data);
+
+ scm_close_port(port);
free(line);
}
@@ -129,7 +169,9 @@ static void input_ready(GObject *source, GAsyncResult *res, gpointer vp)
}
-ReplConnection *repl_connection_new(const char *socket)
+ReplConnection *repl_connection_new(const char *socket,
+ void (*process_func)(SCM sexp, void *data),
+ void *data)
{
ReplConnection *repl;
GSocketClient *client;
@@ -151,6 +193,10 @@ ReplConnection *repl_connection_new(const char *socket)
}
repl->input[0] = '\0';
+ scm_init_guile();
+
+ repl->process_func = process_func;
+ repl->process_func_data = data;
g_input_stream_read_async(g_io_stream_get_input_stream(G_IO_STREAM(repl->conn)),
repl->inbuf, 1023, G_PRIORITY_DEFAULT, NULL,
diff --git a/src/repl-connection.h b/src/repl-connection.h
index 8245c38..f8b82f6 100644
--- a/src/repl-connection.h
+++ b/src/repl-connection.h
@@ -26,7 +26,9 @@
typedef struct _replconnection ReplConnection;
-extern ReplConnection *repl_connection_new(const char *socket);
+extern ReplConnection *repl_connection_new(const char *socket,
+ void (*process_func)(SCM sexp, void *data),
+ void *data);
extern int repl_send(ReplConnection *repl, const char *line);
#endif /* REPL_CONNECTION_H */
diff --git a/src/starlet-fixture-display.c b/src/starlet-fixture-display.c
index 366e0e6..535403f 100644
--- a/src/starlet-fixture-display.c
+++ b/src/starlet-fixture-display.c
@@ -28,6 +28,7 @@
#include <sys/stat.h>
#include <glib.h>
#include <glib/gstdio.h>
+#include <libguile.h>
#include <libintl.h>
#define _(x) gettext(x)
@@ -219,28 +220,78 @@ static gboolean redraw_cb(gpointer data)
}
-static void get_fixture_list(struct fixture_display *fixd)
+static void show_help(const char *s)
+{
+ printf(_("Syntax: %s [options]\n\n"), s);
+ printf(_("Show fixtures in Starlet"
+ " -s, --socket REPL socket for Starlet process (default guile.socket).\n"
+ " -h, --help Display this help message.\n"));
+}
+
+
+static int is_list(SCM list)
+{
+ return scm_is_true(scm_list_p(list));
+}
+
+
+static int symbol_eq(SCM symbol, const char *val)
{
- repl_send(fixd->repl, "(patched-fixture-names)");
+ return scm_is_true(scm_eq_p(symbol, scm_from_utf8_symbol(val)));
+}
- /* FIXME: Dummy */
+
+static void handle_patched_fixtures(struct fixture_display *fixd,
+ SCM list)
+{
int i;
- fixd->fixtures = malloc(32*sizeof(struct fixture));
- fixd->n_fixtures = 32;
- for ( i=0; i<32; i++ ) {
- char tmp[32];
- snprintf(tmp, 31, "mh%i", 1+i);
- fixd->fixtures[i].label = strdup(tmp);
+ int nfix;
+
+ if ( !is_list(list) ) {
+ fprintf(stderr, "Invalid patched fixture list\n");
+ return;
+ }
+
+ nfix = scm_to_int(scm_length(list));
+
+ free(fixd->fixtures);
+ fixd->fixtures = malloc(nfix*sizeof(struct fixture));
+ fixd->n_fixtures = nfix;
+
+ for ( i=0; i<nfix; i++ ) {
+ SCM item = scm_list_ref(list, scm_from_int(i));
+ if ( is_list(item) && (scm_to_int(scm_length(item)) == 3) ) {
+
+ char tmp[64];
+ SCM group_name = scm_list_ref(item, scm_from_int(1));
+ SCM idx = scm_list_ref(item, scm_from_int(2));
+ SCM name = scm_symbol_to_string(group_name);
+ snprintf(tmp, 63, "%s/%i",
+ scm_to_locale_string(name),
+ scm_to_int(idx));
+ fixd->fixtures[i].label = strdup(tmp);
+
+ } else {
+ SCM name = scm_symbol_to_string(item);
+ fixd->fixtures[i].label = scm_to_locale_string(name);
+ }
}
}
-static void show_help(const char *s)
+static void process_line(SCM sexp, void *data)
{
- printf(_("Syntax: %s [options]\n\n"), s);
- printf(_("Show fixtures in Starlet"
- " -s, --socket REPL socket for Starlet process (default guile.socket).\n"
- " -h, --help Display this help message.\n"));
+ struct fixture_display *fixd = data;
+
+ if ( is_list(sexp) && scm_to_int(scm_length(sexp)) == 2 ) {
+ SCM tag = scm_list_ref(sexp, scm_from_int(0));
+ SCM contents = scm_list_ref(sexp, scm_from_int(1));
+ if ( scm_is_symbol(tag) ) {
+ if ( symbol_eq(tag, "patched-fixtures") ) {
+ handle_patched_fixtures(fixd, contents);
+ }
+ }
+ }
}
@@ -318,8 +369,8 @@ int main(int argc, char *argv[])
g_timeout_add(50, redraw_cb, &fixd);
- fixd.repl = repl_connection_new(socket);
- get_fixture_list(&fixd);
+ fixd.repl = repl_connection_new(socket, process_line, &fixd);
+ repl_send(fixd.repl, "(list 'patched-fixtures (patched-fixture-names))");
gtk_main();