From 968b34d90d3d904b24d441bbff0a52735538854f Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sat, 16 May 2015 00:21:45 +0200 Subject: Add test card --- Makefile.am | 2 +- src/colloquium.c | 4 + src/narrative_window.c | 8 ++ src/testcard.c | 244 +++++++++++++++++++++++++++++++++++++++++++++++++ src/testcard.h | 32 +++++++ 5 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 src/testcard.c create mode 100644 src/testcard.h diff --git a/Makefile.am b/Makefile.am index c1bc0ed..cf3e699 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,7 +17,7 @@ src_colloquium_SOURCES = src/colloquium.c src/render.c \ src/imagestore.c src/notes.c src/pr_clock.c \ src/inhibit_screensaver.c \ src/shape.c src/sc_editor.c src/narrative_window.c \ - src/slide_window.c + src/slide_window.c src/testcard.c INCLUDES = -Iharfatum/src diff --git a/src/colloquium.c b/src/colloquium.c index 61c0688..ab3aa1a 100644 --- a/src/colloquium.c +++ b/src/colloquium.c @@ -268,6 +268,10 @@ static void colloquium_startup(GApplication *app) " Presentation clock..." " win.clock" " " + " " + " Test card" + " win.testcard" + " " " " " " " " diff --git a/src/narrative_window.c b/src/narrative_window.c index 7f55d8c..b1966ef 100644 --- a/src/narrative_window.c +++ b/src/narrative_window.c @@ -146,6 +146,13 @@ static void open_clock_sig(GSimpleAction *action, GVariant *parameter, gpointer } +static void testcard_sig(GSimpleAction *action, GVariant *parameter, + NarrativeWindow *nw) +{ + show_testcard(nw->p); +} + + GActionEntry nw_entries[] = { { "save", save_sig, NULL, NULL, NULL }, @@ -157,6 +164,7 @@ GActionEntry nw_entries[] = { { "startslideshow", start_slideshow_sig, NULL, NULL, NULL }, { "notes", open_notes_sig, NULL, NULL, NULL }, { "clock", open_clock_sig, NULL, NULL, NULL }, + { "testcard", testcard_sig, NULL, NULL, NULL }, }; diff --git a/src/testcard.c b/src/testcard.c new file mode 100644 index 0000000..1b7c1df --- /dev/null +++ b/src/testcard.c @@ -0,0 +1,244 @@ +/* + * testcard.c + * + * Copyright © 2013-2015 Thomas White + * + * This file is part of Colloquium. + * + * Colloquium 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 . + * + */ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "inhibit_screensaver.h" +#include "presentation.h" + + +struct testcard +{ + GtkWidget *window; + char geom[256]; + int slide_width; + int slide_height; + GtkWidget *drawingarea; + struct inhibit_sys *inhibit; + struct presentation *p; +}; + +static gint destroy_sig(GtkWidget *widget, struct testcard *tc) +{ + free(tc); + return FALSE; +} + + +static void arrow_left(cairo_t *cr, double size) +{ + cairo_rel_line_to(cr, size, size); + cairo_rel_line_to(cr, 0.0, -2*size); + cairo_rel_line_to(cr, -size, size); +} + + +static void arrow_right(cairo_t *cr, double size) +{ + cairo_rel_line_to(cr, -size, size); + cairo_rel_line_to(cr, 0.0, -2*size); + cairo_rel_line_to(cr, size, size); +} + + +static void arrow_down(cairo_t *cr, double size) +{ + cairo_rel_line_to(cr, -size, -size); + cairo_rel_line_to(cr, 2*size, 0.0); + cairo_rel_line_to(cr, -size, size); +} + + +static void arrow_up(cairo_t *cr, double size) +{ + cairo_rel_line_to(cr, -size, size); + cairo_rel_line_to(cr, 2*size, 0.0); + cairo_rel_line_to(cr, -size, -size); +} + + +static gboolean draw_sig(GtkWidget *da, cairo_t *cr, struct testcard *tc) +{ + double xoff, yoff; + double width, height; + int h; + PangoLayout *pl; + PangoFontDescription *desc; + char tmp[1024]; + int plw, plh; + + width = gtk_widget_get_allocated_width(GTK_WIDGET(da)); + height = gtk_widget_get_allocated_height(GTK_WIDGET(da)); + + /* Overall background */ + cairo_rectangle(cr, 0.0, 0.0, width, height); + cairo_set_source_rgb(cr, 0.0, 0.0, 1.0); + cairo_fill(cr); + + /* FIXME: Assumes that monitor and slide sizes are such that + * letterboxing at sides. This needn't be the case. */ + h = tc->slide_width * tc->p->slide_height / tc->p->slide_width; + + /* Get the overall size */ + xoff = (width - tc->slide_width)/2.0; + yoff = (height - h)/2.0; + + /* Background of slide */ + cairo_rectangle(cr, xoff, yoff, tc->slide_width, h); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + cairo_fill(cr); + + snprintf(tmp, 1024, "Colloquium "PACKAGE_VERSION" test card\n" + "Screen resolution %.0f × %.0f\n" + "Slide resolution %i × %i", width, height, + tc->slide_width, h); + + pl = pango_cairo_create_layout(cr); + desc = pango_font_description_from_string("Sans 24"); + pango_layout_set_font_description(pl, desc); + pango_layout_set_text(pl, tmp, -1); + + pango_layout_get_size(pl, &plw, &plh); + plw = pango_units_to_double(plw); + plh = pango_units_to_double(plh); + cairo_move_to(cr, (width-plw)/2, (height-plh)/2); + cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); + pango_cairo_show_layout(cr, pl); + + /* Arrows showing edges of screen */ + cairo_move_to(cr, 0.0, height/2); + arrow_left(cr, 100.0); + cairo_fill(cr); + cairo_move_to(cr, width, height/2); + arrow_right(cr, 100.0); + cairo_fill(cr); + cairo_move_to(cr, width/2, height); + arrow_down(cr, 100.0); + cairo_fill(cr); + cairo_move_to(cr, width/2, 0.0); + arrow_up(cr, 100.0); + cairo_fill(cr); + + /* Arrows showing edges of slide */ + cairo_translate(cr, xoff, yoff); + cairo_set_source_rgb(cr, 0.5, 0.0, 0.0); + cairo_move_to(cr, 0.0, h/2); + arrow_left(cr, 80.0); + cairo_fill(cr); + cairo_move_to(cr, tc->slide_width, h/2); + arrow_right(cr, 80.0); + cairo_fill(cr); + cairo_move_to(cr, tc->slide_width/2, h); + arrow_down(cr, 80.0); + cairo_fill(cr); + cairo_move_to(cr, tc->slide_width/2, 0.0); + arrow_up(cr, 80.0); + cairo_fill(cr); + return FALSE; +} + + +static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event, + struct testcard *tc) +{ + gtk_widget_destroy(tc->window); + return FALSE; +} + + +static gboolean realize_sig(GtkWidget *w, struct testcard *tc) +{ + gtk_window_parse_geometry(GTK_WINDOW(w), tc->geom); + return FALSE; +} + + +void show_testcard(struct presentation *p) +{ + GdkScreen *screen; + int n_monitors; + int i; + struct testcard *tc; + double slide_width = 1024.0; /* Logical slide size */ + double slide_height = 768.0; /* FIXME: Should come from slide */ + + tc = calloc(1, sizeof(struct testcard)); + if ( tc == NULL ) return; + + tc->p = p; + + if ( tc->inhibit == NULL ) { + tc->inhibit = inhibit_prepare(); + } + + tc->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + + tc->drawingarea = gtk_drawing_area_new(); + gtk_container_add(GTK_CONTAINER(tc->window), tc->drawingarea); + + gtk_widget_set_can_focus(GTK_WIDGET(tc->drawingarea), TRUE); + gtk_widget_add_events(GTK_WIDGET(tc->drawingarea), GDK_KEY_PRESS_MASK); + + g_signal_connect(G_OBJECT(tc->drawingarea), "key-press-event", + G_CALLBACK(key_press_sig), tc); + g_signal_connect(G_OBJECT(tc->window), "destroy", + G_CALLBACK(destroy_sig), tc); + g_signal_connect(G_OBJECT(tc->window), "realize", + G_CALLBACK(realize_sig), tc); + g_signal_connect(G_OBJECT(tc->drawingarea), "draw", + G_CALLBACK(draw_sig), tc); + + gtk_widget_grab_focus(GTK_WIDGET(tc->drawingarea)); + + screen = gdk_screen_get_default(); + n_monitors = gdk_screen_get_n_monitors(screen); + for ( i=0; igeom, 255, "%ix%i+%i+%i", + rect.width, rect.height, rect.x, rect.y); + + w = rect.height * slide_width/slide_height; + if ( w > rect.width ) w = rect.width; + tc->slide_width = w; + tc->slide_height = rect.height; + + } /* FIXME: Sensible (configurable) choice of monitor */ + + gtk_window_fullscreen(GTK_WINDOW(tc->window)); + gtk_widget_show_all(GTK_WIDGET(tc->window)); + + if ( tc->inhibit != NULL ) do_inhibit(tc->inhibit, 1); +} + diff --git a/src/testcard.h b/src/testcard.h new file mode 100644 index 0000000..bd3437c --- /dev/null +++ b/src/testcard.h @@ -0,0 +1,32 @@ +/* + * testcard.h + * + * Copyright © 2013-2015 Thomas White + * + * This file is part of Colloquium. + * + * Colloquium 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 . + * + */ + +#ifndef TESTCARD_H +#define TESTCARD_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +extern void show_testcard(struct presentation *p); + +#endif /* TESTCARD_H */ -- cgit v1.2.3