From 076f7282d65ce6f1adcbd712821b89b668e4776c Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 23 Feb 2022 21:21:04 +0100 Subject: Combine fixture and playback display tools into one --- meson.build | 12 -- src/starlet-fixture-display.c | 67 +++++++- src/starlet-playback-display.c | 360 ----------------------------------------- 3 files changed, 65 insertions(+), 374 deletions(-) delete mode 100644 src/starlet-playback-display.c diff --git a/meson.build b/meson.build index b4451a9..6edbd81 100644 --- a/meson.build +++ b/meson.build @@ -43,17 +43,5 @@ executable('starlet-fixture-display', install: true) -# Playback display tool -executable('starlet-playback-display', - ['src/starlet-playback-display.c', - 'src/repl-connection.c'], - dependencies: [gtk_dep, - cairo_dep, - pango_dep, - pangocairo_dep, - guile_dep], - install: true) - - # Install Scheme source files (all at once) install_subdir('guile/starlet', install_dir: guile_sitedir) diff --git a/src/starlet-fixture-display.c b/src/starlet-fixture-display.c index bf02350..c5a5a9a 100644 --- a/src/starlet-fixture-display.c +++ b/src/starlet-fixture-display.c @@ -55,6 +55,9 @@ struct fixture_display double fixture_tile_width; struct fixture *fixtures; int n_fixtures; + double current_cue_number; + double scanout_rate; + char *playback_name; GtkWidget *da; ReplConnection *repl; int shutdown; @@ -146,6 +149,22 @@ static void draw_fixture(cairo_t *cr, } +static void plot_text(cairo_t *cr, const char *text, + PangoContext *pc, PangoFontDescription *fontdesc, + double x, double y) +{ + PangoLayout *layout; + + layout = pango_layout_new(pc); + pango_layout_set_text(layout, text, -1); + pango_layout_set_font_description(layout, fontdesc); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + cairo_move_to(cr, x, y); + pango_cairo_show_layout(cr, layout); + g_object_unref(layout); +} + + static gboolean draw_sig(GtkWidget *widget, cairo_t *cr, struct fixture_display *fixd) { int w, h; @@ -153,10 +172,12 @@ static gboolean draw_sig(GtkWidget *widget, cairo_t *cr, struct fixture_display PangoContext *pc; PangoFontDescription *fontdesc; double x, y; + char tmp[128]; w = gtk_widget_get_allocated_width(widget); h = gtk_widget_get_allocated_height(widget); pc = gtk_widget_get_pango_context(widget); + fontdesc = pango_font_description_from_string("Comfortaa Bold 12"); /* Overall background */ if ( fixd->repl == NULL ) { @@ -173,10 +194,24 @@ static gboolean draw_sig(GtkWidget *widget, cairo_t *cr, struct fixture_display w -= OVERALL_BORDER*2.0; h -= OVERALL_BORDER*2.0; + /* Playback status */ + cairo_save(cr); + + if ( fixd->current_cue_number < 0.0 ) { + snprintf(tmp, 128, "Current cue doesn't exist! " + "Scanout %.2f per second", + fixd->scanout_rate); + } else { + snprintf(tmp, 128, "Current cue number: %.2f " + "Scanout %.2f per second", + fixd->current_cue_number, fixd->scanout_rate); + } + plot_text(cr, tmp, pc, fontdesc, 0.0, 0.0); + cairo_restore(cr); + /* Fixtures */ x = FIXTURE_BORDER; - y = FIXTURE_BORDER; - fontdesc = pango_font_description_from_string("Comfortaa Bold 12"); + y = FIXTURE_BORDER + 40.0; for ( i=0; in_fixtures; i++ ) { cairo_save(cr); cairo_translate(cr, x, y); @@ -214,6 +249,18 @@ static void shutdown_sig(GtkWidget *window, struct fixture_display *fixd) } +static void request_playback_status(struct fixture_display *fixd) +{ + char tmp[256]; + snprintf(tmp, 256, "(list 'playback-status (list " + "(get-playback-cue-number %s)" + "scanout-freq" + "))", + fixd->playback_name); + repl_send(fixd->repl, tmp); +} + + static void request_intensities(struct fixture_display *fixd) { int i; @@ -305,6 +352,7 @@ static gboolean redraw_cb(gpointer data) if ( !fixd->shutdown ) { request_intensities(fixd); request_selection(fixd); + request_playback_status(fixd); redraw(fixd); } return G_SOURCE_CONTINUE; @@ -500,6 +548,18 @@ static void handle_selection(struct fixture_display *fixd, SCM list) } +static void handle_playback_status(struct fixture_display *fixd, SCM list) +{ + SCM cue_number = scm_list_ref(list, scm_from_int(0)); + if ( scm_is_false(cue_number) ) { + fixd->current_cue_number = -1.0; + } else { + fixd->current_cue_number = scm_to_double(cue_number); + } + fixd->scanout_rate = scm_to_double(scm_list_ref(list, scm_from_int(1))); +} + + static void process_line(SCM sexp, void *data) { struct fixture_display *fixd = data; @@ -514,6 +574,8 @@ static void process_line(SCM sexp, void *data) handle_fixture_parameters(fixd, contents); } else if ( symbol_eq(tag, "selection") ) { handle_selection(fixd, contents); + } else if ( symbol_eq(tag, "playback-status") ) { + handle_playback_status(fixd, contents); } } } @@ -605,6 +667,7 @@ int main(int argc, char *argv[]) fixd.socket = socket; fixd.verbose = verbose; fixd.repl = NULL; + fixd.playback_name = strdup("pb"); gtk_container_add(GTK_CONTAINER(mainwindow), GTK_WIDGET(da)); gtk_widget_set_can_focus(GTK_WIDGET(da), TRUE); diff --git a/src/starlet-playback-display.c b/src/starlet-playback-display.c deleted file mode 100644 index 9ce5438..0000000 --- a/src/starlet-playback-display.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * starlet-playback-display.c - * - * Copyright © 2019-2021 Thomas White - * - * This file is part of Starlet. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#define _(x) gettext(x) - -#include "repl-connection.h" - - -#define OVERALL_BORDER (20.0) - - -struct playback_display -{ - GtkWidget *da; - ReplConnection *repl; - int shutdown; - const char *playback_name; - double current_cue_number; - double scanout_rate; - char *socket; - int verbose; -}; - - -static void plot_text(cairo_t *cr, const char *text, - PangoContext *pc, PangoFontDescription *fontdesc, - double x, double y) -{ - PangoLayout *layout; - - layout = pango_layout_new(pc); - pango_layout_set_text(layout, text, -1); - pango_layout_set_font_description(layout, fontdesc); - cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); - cairo_move_to(cr, x, y); - pango_cairo_show_layout(cr, layout); - g_object_unref(layout); -} - - -static gboolean draw_sig(GtkWidget *widget, cairo_t *cr, - struct playback_display *pbd) -{ - PangoContext *pc; - PangoFontDescription *fontdesc; - char tmp[32]; - - pc = gtk_widget_get_pango_context(widget); - fontdesc = pango_font_description_from_string("Comfortaa Bold 12"); - - /* Overall background */ - if ( pbd->repl == NULL ) { - cairo_set_source_rgb(cr, 0.2, 0.0, 0.0); - cairo_paint(cr); - return FALSE; - } else { - cairo_set_source_rgb(cr, 0.0, 0.0, 0.2); - cairo_paint(cr); - } - - cairo_save(cr); - cairo_translate(cr, OVERALL_BORDER, OVERALL_BORDER); - - if ( pbd->current_cue_number < 0.0 ) { - snprintf(tmp, 32, "Current cue doesn't exist!"); - } else { - snprintf(tmp, 32, "Current cue number: %.2f", pbd->current_cue_number); - } - plot_text(cr, tmp, pc, fontdesc, 0.0, 0.0); - snprintf(tmp, 32, "Scanout rate: %.2f per second", pbd->scanout_rate); - plot_text(cr, tmp, pc, fontdesc, 0.0, 32.0); - - cairo_restore(cr); - - return FALSE; -} - - -static void redraw(struct playback_display *pbd) -{ - gint w, h; - w = gtk_widget_get_allocated_width(GTK_WIDGET(pbd->da)); - h = gtk_widget_get_allocated_height(GTK_WIDGET(pbd->da)); - gtk_widget_queue_draw_area(GTK_WIDGET(pbd->da), 0, 0, w, h); -} - - -static void shutdown_sig(GtkWidget *window, struct playback_display *pbd) -{ - if ( pbd->repl != NULL ) { - repl_connection_close(pbd->repl); - } - pbd->shutdown = TRUE; -} - - -static void request_playback_status(struct playback_display *pbd) -{ - char tmp[256]; - snprintf(tmp, 256, "(list 'playback-status (list " - "(get-playback-cue-number %s)" - "scanout-freq" - "))", - pbd->playback_name); - repl_send(pbd->repl, tmp); -} - - -static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event, struct playback_display *pbd) -{ - int claim = 1; - - switch ( event->keyval ) { - - case GDK_KEY_Escape : - repl_send(pbd->repl, "(sel #f)"); - break; - - case GDK_KEY_KP_Enter : - repl_send(pbd->repl, "(go! pb)"); - break; - - case GDK_KEY_KP_Add : - repl_send(pbd->repl, "(back! pb)"); - break; - - default : - claim = 0; - break; - - } - - if ( claim ) return TRUE; - return FALSE; -} - - -static gint realise_sig(GtkWidget *da, struct playback_display *pbd) -{ - GdkWindow *win = gtk_widget_get_window(da); - - /* Keyboard and input method stuff */ - gdk_window_set_accept_focus(win, TRUE); - g_signal_connect(G_OBJECT(da), "key-press-event", G_CALLBACK(key_press_sig), pbd); - - return FALSE; -} - - -static gboolean redraw_cb(gpointer data) -{ - struct playback_display *pbd = data; - if ( pbd->repl == NULL ) { - return G_SOURCE_CONTINUE; - } - if ( repl_closed(pbd->repl) ) { - if ( pbd->shutdown ) { - gtk_main_quit(); - return G_SOURCE_REMOVE; - } else { - pbd->repl = NULL; - redraw(pbd); - return G_SOURCE_CONTINUE; - } - } else { - if ( !pbd->shutdown ) { - request_playback_status(pbd); - redraw(pbd); - } - return G_SOURCE_CONTINUE; - } -} - - -static void show_help(const char *s) -{ - printf(_("Syntax: %s [options]\n\n"), s); - printf(_("Show playback status in Starlet\n" - " -s, --socket REPL socket for Starlet process (default guile.socket).\n" - " -v, --verbose Show all REPL communications.\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) -{ - return scm_is_true(scm_eq_p(symbol, scm_from_utf8_symbol(val))); -} - - -static void handle_playback_status(struct playback_display *pbd, SCM list) -{ - SCM cue_number = scm_list_ref(list, scm_from_int(0)); - if ( scm_is_false(cue_number) ) { - pbd->current_cue_number = -1.0; - } else { - pbd->current_cue_number = scm_to_double(cue_number); - } - pbd->scanout_rate = scm_to_double(scm_list_ref(list, scm_from_int(1))); -} - - -static void process_line(SCM sexp, void *data) -{ - struct playback_display *pbd = 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, "playback-status") ) { - handle_playback_status(pbd, contents); - } - } - } -} - - -static gboolean try_connect_cb(gpointer data) -{ - struct playback_display *pbd = data; - if ( pbd->repl == NULL ) { - pbd->repl = repl_connection_new(pbd->socket, process_line, - pbd, pbd->verbose); - } - return G_SOURCE_CONTINUE; -} - - -int main(int argc, char *argv[]) -{ - struct playback_display pbd; - int c; - GtkWidget *mainwindow; - GtkWidget *da; - char *socket = NULL; - char *playback_name = "pb"; - int verbose = 0; - - gtk_init(&argc, &argv); - - const struct option longopts[] = { - {"help", 0, NULL, 'h'}, - {"socket", 1, NULL, 's'}, - {"playback", 1, NULL, 'p'}, - {"verbose", 0, NULL, 'v'}, - {0, 0, NULL, 0} - }; - - while ((c = getopt_long(argc, argv, "hvs:", longopts, NULL)) != -1) { - - switch (c) - { - case 'h' : - show_help(argv[0]); - return 0; - - case 's' : - socket = strdup(optarg); - break; - - case 'p' : - playback_name = strdup(optarg); - break; - - case 'v' : - verbose = 1; - break; - - case 0 : - break; - - default : - return 1; - } - - } - - #if !GLIB_CHECK_VERSION(2,36,0) - g_type_init(); - #endif - - bindtextdomain("starlet", LOCALEDIR); - textdomain("starlet"); - - if ( socket == NULL ) { - socket = strdup("guile.socket"); - } - - /* Create main window */ - mainwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_default_size(GTK_WINDOW(mainwindow), 320, 512); - g_signal_connect(G_OBJECT(mainwindow), "destroy", - G_CALLBACK(shutdown_sig), &pbd); - gtk_window_set_title(GTK_WINDOW(mainwindow), "Starlet playback display"); - - da = gtk_drawing_area_new(); - - pbd.da = da; - pbd.shutdown = FALSE; - pbd.playback_name = playback_name; - pbd.socket = socket; - pbd.verbose = verbose; - pbd.repl = NULL; - - gtk_container_add(GTK_CONTAINER(mainwindow), GTK_WIDGET(da)); - gtk_widget_set_can_focus(GTK_WIDGET(da), TRUE); - gtk_widget_add_events(da, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK - | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - | GDK_BUTTON_MOTION_MASK); - g_signal_connect(G_OBJECT(da), "draw", G_CALLBACK(draw_sig), &pbd); - g_signal_connect(G_OBJECT(da), "realize", G_CALLBACK(realise_sig), &pbd); - - gtk_widget_grab_focus(GTK_WIDGET(da)); - gtk_widget_show_all(mainwindow); - - g_timeout_add(50, redraw_cb, &pbd); - - g_timeout_add(1000, try_connect_cb, &pbd); - - gtk_main(); - - return 0; -} -- cgit v1.2.3