aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.me.uk>2019-04-14 18:31:50 +0200
committerThomas White <taw@bitwiz.me.uk>2019-04-14 18:31:50 +0200
commit0f1501a4e5eb1fb1ff7024b6b2f4fd092519ba2c (patch)
treef5b5ae3dbff5b7999fdde0b377181a5186f7c14f
parent3b7e9356d56c7e632af931e161085e12bb1955d8 (diff)
Remove src-old foldersc2
-rw-r--r--src-old/colloquium.c476
-rw-r--r--src-old/colloquium.h45
-rw-r--r--src-old/debugger.c229
-rw-r--r--src-old/debugger.h32
-rw-r--r--src-old/frame.c1820
-rw-r--r--src-old/frame.h194
-rw-r--r--src-old/presentation.c362
-rw-r--r--src-old/presentation.h83
-rw-r--r--src-old/render.c332
-rw-r--r--src-old/render.h62
-rw-r--r--src-old/sc_editor.c2197
-rw-r--r--src-old/sc_editor.h199
-rw-r--r--src-old/sc_interp.c1148
-rw-r--r--src-old/sc_interp.h80
-rw-r--r--src-old/sc_parse.c856
-rw-r--r--src-old/sc_parse.h85
-rw-r--r--src-old/slide_window.c282
-rw-r--r--src-old/slide_window.h37
-rw-r--r--src-old/stylesheet.c288
-rw-r--r--src-old/stylesheet.h54
-rw-r--r--src-old/stylesheet_editor.c794
-rw-r--r--src-old/stylesheet_editor.h128
-rw-r--r--src-old/utils.c137
-rw-r--r--src-old/utils.h47
24 files changed, 0 insertions, 9967 deletions
diff --git a/src-old/colloquium.c b/src-old/colloquium.c
deleted file mode 100644
index 02ffa0a..0000000
--- a/src-old/colloquium.c
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- * colloquium.c
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtk.h>
-#include <getopt.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <glib.h>
-#include <glib/gstdio.h>
-
-#include "colloquium.h"
-#include "presentation.h"
-#include "narrative_window.h"
-#include "utils.h"
-
-
-struct _colloquium
-{
- GtkApplication parent_instance;
- GtkBuilder *builder;
- char *mydir;
- int first_run;
- char *imagestore;
- int hidepointer;
-};
-
-
-typedef GtkApplicationClass ColloquiumClass;
-
-
-G_DEFINE_TYPE(Colloquium, colloquium, GTK_TYPE_APPLICATION)
-
-
-static void colloquium_activate(GApplication *papp)
-{
- Colloquium *app = COLLOQUIUM(papp);
- if ( !app->first_run ) {
- struct presentation *p;
- p = new_presentation(app->imagestore);
- narrative_window_new(p, papp);
- }
-}
-
-
-static void new_sig(GSimpleAction *action, GVariant *parameter, gpointer vp)
-{
- GApplication *app = vp;
- g_application_activate(app);
-}
-
-
-static void open_intro_doc(Colloquium *app)
-{
- GFile *file = g_file_new_for_uri("resource:///uk/me/bitwiz/Colloquium/demo.sc");
- g_application_open(G_APPLICATION(app), &file, 1, "");
- g_object_unref(file);
-}
-
-
-static void intro_sig(GSimpleAction *action, GVariant *parameter, gpointer vp)
-{
- GApplication *app = vp;
- open_intro_doc(COLLOQUIUM(app));
-}
-
-
-void open_about_dialog(GtkWidget *parent)
-{
- GtkWidget *window;
-
- const gchar *authors[] = {
- "Thomas White <taw@bitwiz.org.uk>",
- NULL
- };
-
- window = gtk_about_dialog_new();
- gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(parent));
-
- gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(window),
- "Colloquium");
- gtk_about_dialog_set_logo_icon_name(GTK_ABOUT_DIALOG(window),
- "colloquium");
- gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(window),
- PACKAGE_VERSION);
- gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(window),
- "© 2017-2018 Thomas White <taw@bitwiz.me.uk>");
- gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(window),
- /* Description of the program */
- _("Narrative-based presentation system"));
- gtk_about_dialog_set_license_type(GTK_ABOUT_DIALOG(window), GTK_LICENSE_GPL_3_0);
- gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(window),
- "https://www.bitwiz.me.uk/");
- gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(window),
- "https://www.bitwiz.me.uk/");
- gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(window), authors);
- gtk_about_dialog_set_translator_credits(GTK_ABOUT_DIALOG(window),
- _("translator-credits"));
-
- g_signal_connect(window, "response", G_CALLBACK(gtk_widget_destroy),
- NULL);
-
- gtk_widget_show_all(window);
-}
-
-
-static void quit_sig(GSimpleAction *action, GVariant *parameter, gpointer vp)
-{
- GApplication *app = vp;
- g_application_quit(app);
-}
-
-
-static GFile **gslist_to_array(GSList *item, int *n)
-{
- int i = 0;
- int len = g_slist_length(item);
- GFile **files = malloc(len * sizeof(GFile *));
-
- if ( files == NULL ) return NULL;
-
- while ( item != NULL ) {
- if ( i == len ) {
- fprintf(stderr, "WTF? Too many files\n");
- break;
- }
- files[i++] = item->data;
- item = item->next;
- }
-
- *n = len;
- return files;
-}
-
-
-static gint open_response_sig(GtkWidget *d, gint response, GApplication *papp)
-{
- if ( response == GTK_RESPONSE_ACCEPT ) {
-
- GSList *files;
- int n_files = 0;
- GFile **files_array;
- int i;
-
- files = gtk_file_chooser_get_files(GTK_FILE_CHOOSER(d));
- files_array = gslist_to_array(files, &n_files);
- if ( files_array == NULL ) {
- fprintf(stderr, "Failed to convert file list\n");
- return 0;
- }
- g_slist_free(files);
- g_application_open(papp, files_array, n_files, "");
-
- for ( i=0; i<n_files; i++ ) {
- g_object_unref(files_array[i]);
- }
-
- }
-
- gtk_widget_destroy(d);
-
- return 0;
-}
-
-
-static void open_sig(GSimpleAction *action, GVariant *parameter, gpointer vp)
-{
- GtkWidget *d;
- GApplication *app = vp;
-
- d = gtk_file_chooser_dialog_new(_("Open Presentation"),
- gtk_application_get_active_window(GTK_APPLICATION(app)),
- GTK_FILE_CHOOSER_ACTION_OPEN,
- _("_Cancel"), GTK_RESPONSE_CANCEL,
- _("_Open"), GTK_RESPONSE_ACCEPT,
- NULL);
-
- gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(d), TRUE);
-
- g_signal_connect(G_OBJECT(d), "response",
- G_CALLBACK(open_response_sig), app);
-
- gtk_widget_show_all(d);
-}
-
-
-GActionEntry app_entries[] = {
-
- { "new", new_sig, NULL, NULL, NULL },
- { "open", open_sig, NULL, NULL, NULL },
- { "intro", intro_sig, NULL, NULL, NULL },
- { "quit", quit_sig, NULL, NULL, NULL },
-};
-
-
-static void colloquium_open(GApplication *papp, GFile **files, gint n_files,
- const gchar *hint)
-{
- int i;
- Colloquium *app = COLLOQUIUM(papp);
-
- for ( i = 0; i<n_files; i++ ) {
- struct presentation *p;
- p = new_presentation(app->imagestore);
- if ( load_presentation(p, files[i]) == 0 ) {
- narrative_window_new(p, papp);
- } else {
- char *uri = g_file_get_uri(files[i]);
- fprintf(stderr, _("Failed to load presentation '%s'\n"),
- uri);
- g_free(uri);
- }
- }
-}
-
-
-static void colloquium_finalize(GObject *object)
-{
- G_OBJECT_CLASS(colloquium_parent_class)->finalize(object);
-}
-
-
-static void create_config(const char *filename)
-{
-
- FILE *fh;
- fh = fopen(filename, "w");
- if ( fh == NULL ) {
- fprintf(stderr, _("Failed to create config\n"));
- return;
- }
-
- fprintf(fh, "imagestore: %s\n",
- g_get_user_special_dir(G_USER_DIRECTORY_PICTURES));
- fprintf(fh, "hidepointer: no\n");
-
- fclose(fh);
-}
-
-
-static int yesno(const char *a)
-{
- if ( a == NULL ) return 0;
-
- if ( strcmp(a, "1") == 0 ) return 1;
- if ( strcasecmp(a, "yes") == 0 ) return 1;
- if ( strcasecmp(a, "true") == 0 ) return 1;
-
- if ( strcasecmp(a, "0") == 0 ) return 0;
- if ( strcasecmp(a, "no") == 0 ) return 0;
- if ( strcasecmp(a, "false") == 0 ) return 0;
-
- fprintf(stderr, "Don't understand '%s', assuming false\n", a);
- return 0;
-}
-
-
-static void read_config(const char *filename, Colloquium *app)
-{
- FILE *fh;
- char line[1024];
-
- fh = fopen(filename, "r");
- if ( fh == NULL ) {
- fprintf(stderr, _("Failed to open config %s\n"), filename);
- return;
- }
-
- do {
-
- if ( fgets(line, 1024, fh) == NULL ) break;
- chomp(line);
-
- if ( strncmp(line, "imagestore: ", 11) == 0 ) {
- app->imagestore = strdup(line+12);
- }
-
- if ( strncmp(line, "hidepointer: ", 12) == 0 ) {
- app->hidepointer = yesno(line+13);
- }
- } while ( !feof(fh) );
-
- fclose(fh);
-}
-
-
-const char *colloquium_get_imagestore(Colloquium *app)
-{
- return app->imagestore;
-}
-
-
-int colloquium_get_hidepointer(Colloquium *app)
-{
- return app->hidepointer;
-}
-
-
-static void colloquium_startup(GApplication *papp)
-{
- Colloquium *app = COLLOQUIUM(papp);
- const char *configdir;
- char *tmp;
-
- G_APPLICATION_CLASS(colloquium_parent_class)->startup(papp);
-
- g_action_map_add_action_entries(G_ACTION_MAP(app), app_entries,
- G_N_ELEMENTS(app_entries), app);
-
- app->builder = gtk_builder_new_from_resource("/uk/me/bitwiz/Colloquium/menus.ui");
- gtk_builder_add_from_resource(app->builder, "/uk/me/bitwiz/Colloquium/windows.ui", NULL);
- gtk_application_set_menubar(GTK_APPLICATION(app),
- G_MENU_MODEL(gtk_builder_get_object(app->builder, "menubar")));
-
- if ( gtk_application_prefers_app_menu(GTK_APPLICATION(app)) ) {
- /* Set the application menu only if it will be shown by the
- * desktop environment. All the entries are already in the
- * normal menus, so don't let GTK create a fallback menu in the
- * menu bar. */
- GMenuModel *mmodel = G_MENU_MODEL(gtk_builder_get_object(app->builder, "app-menu"));
- gtk_application_set_app_menu(GTK_APPLICATION(app), mmodel);
- }
-
- configdir = g_get_user_config_dir();
- app->mydir = malloc(strlen(configdir)+14);
- strcpy(app->mydir, configdir);
- strcat(app->mydir, "/colloquium");
-
- if ( !g_file_test(app->mydir, G_FILE_TEST_IS_DIR) ) {
-
- /* Folder not created yet */
- open_intro_doc(app);
- app->first_run = 1;
-
- if ( g_mkdir(app->mydir, S_IRUSR | S_IWUSR | S_IXUSR) ) {
- fprintf(stderr, _("Failed to create config folder\n"));
- }
- }
-
- /* Read config file */
- tmp = malloc(strlen(app->mydir)+32);
- if ( tmp != NULL ) {
-
- tmp[0] = '\0';
- strcat(tmp, app->mydir);
- strcat(tmp, "/config");
-
- /* Create default config file if it doesn't exist */
- if ( !g_file_test(tmp, G_FILE_TEST_EXISTS) ) {
- create_config(tmp);
- }
-
- read_config(tmp, app);
- free(tmp);
- }
-}
-
-
-static void colloquium_shutdown(GApplication *app)
-{
- G_APPLICATION_CLASS(colloquium_parent_class)->shutdown(app);
-}
-
-
-static void colloquium_class_init(ColloquiumClass *class)
-{
- GApplicationClass *app_class = G_APPLICATION_CLASS(class);
- GObjectClass *object_class = G_OBJECT_CLASS(class);
-
- app_class->startup = colloquium_startup;
- app_class->shutdown = colloquium_shutdown;
- app_class->activate = colloquium_activate;
- app_class->open = colloquium_open;
-
- object_class->finalize = colloquium_finalize;
-}
-
-
-static void colloquium_init(Colloquium *app)
-{
- app->imagestore = NULL;
- app->hidepointer = 0;
-}
-
-
-static Colloquium *colloquium_new()
-{
- Colloquium *app;
-
- g_set_application_name("Colloquium");
- app = g_object_new(colloquium_get_type(),
- "application-id", "uk.org.bitwiz.Colloquium",
- "flags", G_APPLICATION_HANDLES_OPEN,
- "register-session", TRUE,
- NULL);
-
- app->first_run = 0; /* Will be updated at "startup" if appropriate */
-
- return app;
-}
-
-
-static void show_help(const char *s)
-{
- printf(_("Syntax: %s [options] [<file.sc>]\n\n"), s);
- printf(_("Narrative-based presentation system.\n\n"
- " -h, --help Display this help message.\n"));
-}
-
-
-int main(int argc, char *argv[])
-{
- int c;
- int status;
- Colloquium *app;
-
- /* Long options */
- const struct option longopts[] = {
- {"help", 0, NULL, 'h'},
- {0, 0, NULL, 0}
- };
-
- /* Short options */
- while ((c = getopt_long(argc, argv, "h", longopts, NULL)) != -1) {
-
- switch (c)
- {
- case 'h' :
- show_help(argv[0]);
- return 0;
-
- case 0 :
- break;
-
- default :
- return 1;
- }
-
- }
-
-#if !GLIB_CHECK_VERSION(2,36,0)
- g_type_init();
-#endif
-
- bindtextdomain("colloquium", LOCALEDIR);
- textdomain("colloquium");
-
- app = colloquium_new();
- status = g_application_run(G_APPLICATION(app), argc, argv);
- g_object_unref(app);
- return status;
-}
diff --git a/src-old/colloquium.h b/src-old/colloquium.h
deleted file mode 100644
index 89f600f..0000000
--- a/src-old/colloquium.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * colloquium.h
- *
- * Copyright © 2014-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef COLLOQUIUM_H
-#define COLLOQUIUM_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib-object.h>
-
-
-typedef struct _colloquium Colloquium;
-
-#define COLLOQUIUM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
- GTK_TYPE_APPLICATION, Colloquium))
-
-
-extern const char *colloquium_get_imagestore(Colloquium *app);
-extern int colloquium_get_hidepointer(Colloquium *app);
-
-extern void open_about_dialog(GtkWidget *parent);
-
-
-#endif /* COLLOQUIUM_H */
diff --git a/src-old/debugger.c b/src-old/debugger.c
deleted file mode 100644
index f15478a..0000000
--- a/src-old/debugger.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * print.c
- *
- * Copyright © 2017-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtk.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "presentation.h"
-#include "narrative_window.h"
-#include "render.h"
-#include "frame.h"
-#include "utils.h"
-
-
-#define MAX_DEBUG_RUNS (1024)
-
-struct debugwindow
-{
- GtkWidget *window;
- GtkWidget *drawingarea;
- struct frame *fr;
- guint timeout;
-};
-
-
-static void plot_hr(cairo_t *cr, double *ypos, double width)
-{
- cairo_move_to(cr, 10.0, *ypos+5.5);
- cairo_line_to(cr, width-20.0, *ypos+5.5);
- cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
- cairo_set_line_width(cr, 1.0);
- cairo_stroke(cr);
- *ypos += 10.0;
-}
-
-
-static void plot_text(cairo_t *cr, double *ypos, PangoFontDescription *fontdesc,
- const char *tmp)
-{
- PangoLayout *layout;
- PangoRectangle ext;
-
- cairo_move_to(cr, 10.0, *ypos);
-
- layout = pango_cairo_create_layout(cr);
- pango_layout_set_text(layout, tmp, -1);
- pango_layout_set_font_description(layout, fontdesc);
-
- pango_layout_get_extents(layout, NULL, &ext);
- *ypos += ext.height/PANGO_SCALE;
-
- cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
- pango_cairo_show_layout(cr, layout);
-
- g_object_unref(layout);
-}
-
-
-static const char *str_type(enum para_type t)
-{
- switch ( t ) {
-
- /* Text paragraph */
- case PARA_TYPE_TEXT : return "text";
-
- /* Callback paragraph */
- case PARA_TYPE_CALLBACK : return "callback";
-
- /* Unknown paragraph type */
- default : return "unknown";
- }
-}
-
-static void debug_text_para(Paragraph *para, cairo_t *cr, double *ypos,
- PangoFontDescription *fontdesc)
-{
- int i, nrun;
- char tmp[256];
-
- nrun = para_debug_num_runs(para);
- /* How many text runs */
- snprintf(tmp, 255, " %i runs", nrun);
- plot_text(cr, ypos, fontdesc, tmp);
-
- for ( i=0; i<nrun; i++ ) {
- SCBlock *scblock;
- if ( para_debug_run_info(para, i, &scblock) ) {
- /* Failed to get debug info for paragraph */
- plot_text(cr, ypos, fontdesc, "Error");
- } else {
- snprintf(tmp, 255, " Run %i: SCBlock %p", i, scblock);
- plot_text(cr, ypos, fontdesc, tmp);
- }
- }
-
- snprintf(tmp, 255, "Newline at end: %p",
- para_debug_get_newline_at_end(para));
- plot_text(cr, ypos, fontdesc, tmp);
-}
-
-
-static gboolean dbg_draw_sig(GtkWidget *da, cairo_t *cr, struct debugwindow *dbgw)
-{
- int width, height;
- char tmp[256];
- PangoFontDescription *fontdesc;
- int i;
- double ypos = 10.0;
-
- /* Background */
- width = gtk_widget_get_allocated_width(GTK_WIDGET(da));
- height = gtk_widget_get_allocated_height(GTK_WIDGET(da));
- cairo_set_source_rgba(cr, 1.0, 0.8, 0.8, 1.0);
- cairo_rectangle(cr, 0.0, 0.0, width, height);
- cairo_fill(cr);
-
- if ( dbgw->fr == NULL ) return FALSE;
-
- fontdesc = pango_font_description_new();
- pango_font_description_set_family_static(fontdesc, "Serif");
- pango_font_description_set_style(fontdesc, PANGO_STYLE_ITALIC);
- pango_font_description_set_absolute_size(fontdesc, 15*PANGO_SCALE);
-
- snprintf(tmp, 255, "Frame %p has %i paragraphs", dbgw->fr, dbgw->fr->n_paras);
- plot_text(cr, &ypos, fontdesc, tmp);
-
- for ( i=0; i<dbgw->fr->n_paras; i++ ) {
-
- enum para_type t = para_type(dbgw->fr->paras[i]);
- SCBlock *scblock = para_scblock(dbgw->fr->paras[i]);
-
- plot_hr(cr, &ypos, width);
- snprintf(tmp, 255, "Paragraph %i: type %s", i, str_type(t));
- plot_text(cr, &ypos, fontdesc, tmp);
-
- snprintf(tmp, 255, "SCBlock %p", scblock);
- plot_text(cr, &ypos, fontdesc, tmp);
-
- if ( t == PARA_TYPE_TEXT ) {
- debug_text_para(dbgw->fr->paras[i], cr, &ypos, fontdesc);
- }
-
- plot_text(cr, &ypos, fontdesc, "");
-
- }
-
- pango_font_description_free(fontdesc);
-
- return FALSE;
-}
-
-
-static gboolean queue_redraw(void *vp)
-{
- struct debugwindow *dbgw = vp;
- gint w, h;
- w = gtk_widget_get_allocated_width(GTK_WIDGET(dbgw->drawingarea));
- h = gtk_widget_get_allocated_height(GTK_WIDGET(dbgw->drawingarea));
- gtk_widget_queue_draw_area(GTK_WIDGET(dbgw->drawingarea), 0, 0, w, h);
- return TRUE;
-}
-
-
-static gboolean close_sig(GtkWidget *widget, GdkEvent *event, struct debugwindow *dbgw)
-{
- g_source_remove(dbgw->timeout);
- free(dbgw);
- return FALSE;
-}
-
-
-void open_debugger(struct frame *fr)
-{
- struct debugwindow *dbgw;
- GtkWidget *scroll;
-
- if ( fr == NULL ) return;
-
- dbgw = calloc(1, sizeof(struct debugwindow));
- if ( dbgw == NULL ) return;
-
- dbgw->fr = fr;
-
- dbgw->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_role(GTK_WINDOW(dbgw->window), "debugger");
- gtk_window_set_title(GTK_WINDOW(dbgw->window), "Colloquium debugger");
-
- scroll = gtk_scrolled_window_new(NULL, NULL);
- gtk_container_add(GTK_CONTAINER(dbgw->window), scroll);
-
- dbgw->drawingarea = gtk_drawing_area_new();
- gtk_container_add(GTK_CONTAINER(scroll), dbgw->drawingarea);
- gtk_widget_set_size_request(dbgw->drawingarea, 100, 8000);
-
- g_signal_connect(G_OBJECT(dbgw->drawingarea), "draw",
- G_CALLBACK(dbg_draw_sig), dbgw);
-
- g_signal_connect(G_OBJECT(dbgw->window), "delete-event",
- G_CALLBACK(close_sig), dbgw);
-
- dbgw->timeout = g_timeout_add(1000, queue_redraw, dbgw);
-
- gtk_widget_show_all(dbgw->window);
-}
diff --git a/src-old/debugger.h b/src-old/debugger.h
deleted file mode 100644
index d6191bf..0000000
--- a/src-old/debugger.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * debugger.h
- *
- * Copyright © 2017-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef DEBUGGER_H
-#define DEBUGGER_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-extern void open_debugger(struct frame *fr);
-
-#endif /* DEBUGGER_H */
diff --git a/src-old/frame.c b/src-old/frame.c
deleted file mode 100644
index 08b8fd9..0000000
--- a/src-old/frame.c
+++ /dev/null
@@ -1,1820 +0,0 @@
-/*
- * frame.c
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
-#include "sc_parse.h"
-#include "frame.h"
-#include "imagestore.h"
-#include "utils.h"
-
-struct text_run
-{
- SCBlock *scblock;
- char *real_text; /* Usually NULL */
- PangoFontDescription *fontdesc;
- double col[4];
-};
-
-struct _paragraph
-{
- enum para_type type;
- double height;
- float space[4];
- SCBlock *newline_at_end;
- int empty;
-
- /* For PARA_TYPE_TEXT */
- int n_runs;
- struct text_run *runs;
- PangoLayout *layout;
- PangoAlignment alignment;
-
- /* For anything other than PARA_TYPE_TEXT
- * (for text paragraphs, these things are in the runs) */
- SCBlock *scblock;
-
- /* For PARA_TYPE_IMAGE */
- char *filename;
- double image_w;
- double image_h;
- int image_real_w;
- int image_real_h;
-
- /* For PARA_TYPE_CALLBACK */
- double cb_w;
- double cb_h;
- SCCallbackDrawFunc draw_func;
- SCCallbackClickFunc click_func;
- void *bvp;
- void *vp;
-};
-
-
-/* Returns the height of the paragraph including all spacing, padding etc */
-double paragraph_height(Paragraph *para)
-{
- return para->height + para->space[2] + para->space[3];
-}
-
-
-static int alloc_ro(struct frame *fr)
-{
- struct frame **new_ro;
-
- new_ro = realloc(fr->children,
- fr->max_children*sizeof(struct frame *));
- if ( new_ro == NULL ) return 1;
-
- fr->children = new_ro;
-
- return 0;
-}
-
-
-struct frame *frame_new()
-{
- struct frame *n;
-
- n = calloc(1, sizeof(struct frame));
- if ( n == NULL ) return NULL;
-
- n->children = NULL;
- n->max_children = 32;
- if ( alloc_ro(n) ) {
- fprintf(stderr, "Couldn't allocate children\n");
- free(n);
- return NULL;
- }
- n->num_children = 0;
-
- n->scblocks = NULL;
- n->n_paras = 0;
- n->paras = NULL;
-
- return n;
-}
-
-
-static void free_paragraph(Paragraph *para)
-{
- int i;
-
- for ( i=0; i<para->n_runs; i++ ) {
- pango_font_description_free(para->runs[i].fontdesc);
- free(para->runs[i].real_text); /* free(NULL) is OK */
- }
- free(para->runs);
- if ( para->layout != NULL ) g_object_unref(para->layout);
- free(para);
-}
-
-
-void frame_free(struct frame *fr)
-{
- int i;
-
- if ( fr == NULL ) return;
-
- /* Free paragraphs */
- if ( fr->paras != NULL ) {
- for ( i=0; i<fr->n_paras; i++ ) {
- free_paragraph(fr->paras[i]);
- }
- free(fr->paras);
- }
-
- /* Free all children */
- for ( i=0; i<fr->num_children; i++ ) {
- frame_free(fr->children[i]);
- }
- free(fr->children);
-
- free(fr);
-}
-
-
-struct frame *add_subframe(struct frame *fr)
-{
- struct frame *n;
-
- n = frame_new();
- if ( n == NULL ) return NULL;
-
- if ( fr->num_children == fr->max_children ) {
- fr->max_children += 32;
- if ( alloc_ro(fr) ) return NULL;
- }
-
- fr->children[fr->num_children++] = n;
-
- return n;
-}
-
-
-void show_frame_hierarchy(struct frame *fr, const char *t)
-{
- int i;
- char tn[1024];
-
- strcpy(tn, t);
- strcat(tn, " ");
-
- printf("%s%p (%.2f x %.2f)\n", t, fr, fr->w, fr->h);
-
- for ( i=0; i<fr->num_children; i++ ) {
- show_frame_hierarchy(fr->children[i], tn);
- }
-
-}
-
-
-struct frame *find_frame_with_scblocks(struct frame *fr, SCBlock *scblocks)
-{
- int i;
-
- if ( fr->scblocks == scblocks ) return fr;
-
- for ( i=0; i<fr->num_children; i++ ) {
- struct frame *tt;
- tt = find_frame_with_scblocks(fr->children[i], scblocks);
- if ( tt != NULL ) return tt;
- }
-
- return NULL;
-}
-
-
-static const char *text_for_run(const struct text_run *run)
-{
- if ( run == NULL ) {
- fprintf(stderr, "NULL run passed to text_for_run\n");
- return 0;
- }
-
- if ( run->scblock == NULL ) {
- fprintf(stderr, "NULL scblock in text_for_run\n");
- return 0;
- }
-
- if ( run->real_text != NULL ) {
- return run->real_text;
- }
-
- return sc_block_contents(run->scblock);
-}
-
-
-static size_t run_text_len(const struct text_run *run)
-{
- if ( run == NULL ) {
- fprintf(stderr, "NULL run passed to run_text_len\n");
- return 0;
- }
-
- if ( run->scblock == NULL ) {
- fprintf(stderr, "NULL scblock in run_text_len\n");
- return 0;
- }
-
- if ( run->real_text != NULL ) {
- return strlen(run->real_text);
- }
-
- if ( sc_block_contents(run->scblock) == NULL ) {
- fprintf(stderr, "NULL scblock contents in run_text_len\n");
- return 0;
- }
-
- return strlen(sc_block_contents(run->scblock));
-}
-
-
-void wrap_paragraph(Paragraph *para, PangoContext *pc, double w,
- size_t sel_start, size_t sel_end)
-{
- size_t total_len = 0;
- int i;
- char *text;
- PangoAttrList *attrs;
- PangoRectangle rect;
- size_t pos = 0;
-
- w -= para->space[0] + para->space[1];
-
- if ( para->type == PARA_TYPE_IMAGE ) {
- if ( para->image_w < 0.0 ) {
- para->image_w = w;
- para->image_h = w*((float)para->image_real_h/para->image_real_w);
- }
- para->height = para->image_h;
- return;
- }
-
- if ( para->type != PARA_TYPE_TEXT ) return;
-
- for ( i=0; i<para->n_runs; i++ ) {
- total_len += run_text_len(&para->runs[i]);
- }
-
- /* Allocate the complete text */
- text = malloc(total_len+1);
- if ( text == NULL ) {
- fprintf(stderr, "Couldn't allocate combined text (%lli)\n",
- (long long int)total_len);
- return;
- }
-
- /* Allocate the attributes */
- attrs = pango_attr_list_new();
-
- /* Put all of the text together */
- text[0] = '\0';
- for ( i=0; i<para->n_runs; i++ ) {
-
- PangoAttribute *attr;
- const char *run_text;
- size_t run_len;
- guint16 r, g, b;
-
- run_text = text_for_run(&para->runs[i]);
- run_len = strlen(run_text);
-
- attr = pango_attr_font_desc_new(para->runs[i].fontdesc);
- attr->start_index = pos;
- attr->end_index = pos + run_len;
- pango_attr_list_insert(attrs, attr);
-
- r = para->runs[i].col[0] * 65535;
- g = para->runs[i].col[1] * 65535;
- b = para->runs[i].col[2] * 65535;
- attr = pango_attr_foreground_new(r, g, b);
- attr->start_index = pos;
- attr->end_index = pos + run_len;
- pango_attr_list_insert(attrs, attr);
-
- pos += run_len;
- strncat(text, run_text, run_len);
-
- }
-
- /* Add attributes for selected text */
- if ( sel_start > 0 || sel_end > 0 ) {
- PangoAttribute *attr;
- attr = pango_attr_background_new(42919, 58853, 65535);
- attr->start_index = sel_start;
- attr->end_index = sel_end;
- pango_attr_list_insert(attrs, attr);
- }
-
- if ( para->layout == NULL ) {
- para->layout = pango_layout_new(pc);
- }
- pango_layout_set_width(para->layout, pango_units_from_double(w));
- pango_layout_set_text(para->layout, text, total_len);
- pango_layout_set_alignment(para->layout, para->alignment);
- pango_layout_set_attributes(para->layout, attrs);
- free(text);
- pango_attr_list_unref(attrs);
-
- pango_layout_get_extents(para->layout, NULL, &rect);
- para->height = pango_units_to_double(rect.height);
-}
-
-static SCBlock *get_newline_at_end(Paragraph *para)
-{
- return para->newline_at_end;
-}
-
-
-SCBlock *para_debug_get_newline_at_end(Paragraph *para)
-{
- return get_newline_at_end(para);
-}
-
-
-void set_newline_at_end(Paragraph *para, SCBlock *bl)
-{
- para->newline_at_end = bl;
-}
-
-
-void add_run(Paragraph *para, SCBlock *scblock,
- PangoFontDescription *fdesc, double col[4], const char *real_text)
-{
- struct text_run *runs_new;
-
- runs_new = realloc(para->runs,
- (para->n_runs+1)*sizeof(struct text_run));
- if ( runs_new == NULL ) {
- fprintf(stderr, "Failed to add run.\n");
- return;
- }
-
- para->runs = runs_new;
- para->runs[para->n_runs].scblock = scblock;
- if ( real_text != NULL ) {
- para->runs[para->n_runs].real_text = strdup(real_text);
- } else {
- para->runs[para->n_runs].real_text = NULL;
- }
- para->runs[para->n_runs].fontdesc = pango_font_description_copy(fdesc);
- para->runs[para->n_runs].col[0] = col[0];
- para->runs[para->n_runs].col[1] = col[1];
- para->runs[para->n_runs].col[2] = col[2];
- para->runs[para->n_runs].col[3] = col[3];
- para->empty = 0;
- para->n_runs++;
-}
-
-
-Paragraph *create_paragraph(struct frame *fr, SCBlock *bl)
-{
- Paragraph **paras_new;
- Paragraph *pnew;
-
- paras_new = realloc(fr->paras, (fr->n_paras+1)*sizeof(Paragraph *));
- if ( paras_new == NULL ) return NULL;
-
- pnew = calloc(1, sizeof(struct _paragraph));
- if ( pnew == NULL ) return NULL;
-
- fr->paras = paras_new;
- fr->paras[fr->n_paras++] = pnew;
-
- /* For now, assume the paragraph is going to be for text.
- * However, this can easily be changed */
- pnew->type = PARA_TYPE_TEXT;
- pnew->scblock = bl;
- pnew->n_runs = 0;
- pnew->runs = NULL;
- pnew->layout = NULL;
- pnew->height = 0.0;
- pnew->alignment = PANGO_ALIGN_LEFT;
- pnew->empty = 1;
-
- return pnew;
-}
-
-
-/* Create a new paragraph in 'fr' just after paragraph 'pos' */
-Paragraph *insert_paragraph(struct frame *fr, int pos)
-{
- Paragraph **paras_new;
- Paragraph *pnew;
- int i;
-
- if ( pos >= fr->n_paras ) {
- fprintf(stderr, "insert_paragraph(): pos too high!\n");
- return NULL;
- }
-
- paras_new = realloc(fr->paras, (fr->n_paras+1)*sizeof(Paragraph *));
- if ( paras_new == NULL ) return NULL;
-
- pnew = calloc(1, sizeof(struct _paragraph));
- if ( pnew == NULL ) return NULL;
-
- fr->paras = paras_new;
- fr->n_paras++;
-
- for ( i=fr->n_paras-1; i>pos; i-- ) {
- fr->paras[i] = fr->paras[i-1];
- }
- fr->paras[pos+1] = pnew;
-
- return pnew;
-}
-
-
-Paragraph *add_callback_para(struct frame *fr, SCBlock *bl, double w, double h,
- SCCallbackDrawFunc draw_func,
- SCCallbackClickFunc click_func, void *bvp,
- void *vp)
-{
- Paragraph *pnew;
-
- if ( (fr->n_paras > 0) && (fr->paras[fr->n_paras-1]->empty) ) {
- pnew = fr->paras[fr->n_paras-1];
- } else {
- pnew = create_paragraph(fr, bl);
- if ( pnew == NULL ) {
- fprintf(stderr, "Failed to add callback paragraph\n");
- return NULL;
- }
- }
-
- pnew->type = PARA_TYPE_CALLBACK;
- pnew->scblock = bl;
- pnew->cb_w = w;
- pnew->cb_h = h;
- pnew->draw_func = draw_func;
- pnew->click_func = click_func;
- pnew->bvp = bvp;
- pnew->vp = vp;
- pnew->height = h;
- pnew->empty = 0;
-
- return pnew;
-}
-
-
-void add_image_para(struct frame *fr, SCBlock *scblock,
- const char *filename,
- ImageStore *is, double w, double h, int editable)
-{
- Paragraph *pnew;
- int wi, hi;
-
- if ( is == NULL ) {
- fprintf(stderr, "Adding image without ImageStore!\n");
- return;
- }
-
- if ( (fr->n_paras > 0) && (fr->paras[fr->n_paras-1]->empty) ) {
- pnew = fr->paras[fr->n_paras-1];
- } else {
- pnew = create_paragraph(fr, scblock);
- if ( pnew == NULL ) {
- fprintf(stderr, "Failed to add image paragraph\n");
- return;
- }
- }
-
- if ( imagestore_get_size(is, filename, &wi, &hi) ) {
- fprintf(stderr, _("Couldn't determine size of image '%s'\n"),
- filename);
- wi = 100;
- hi = 100;
- }
-
- pnew->type = PARA_TYPE_IMAGE;
- pnew->scblock = scblock;
- pnew->filename = strdup(filename);
- pnew->image_w = w;
- pnew->image_h = h;
- pnew->image_real_w = wi;
- pnew->image_real_h = hi;
- pnew->height = h;
- pnew->space[0] = 0.0;
- pnew->space[1] = 0.0;
- pnew->space[2] = 0.0;
- pnew->space[3] = 0.0;
- pnew->empty = 0;
-}
-
-
-double total_height(struct frame *fr)
-{
- int i;
- double t = 0.0;
- for ( i=0; i<fr->n_paras; i++ ) {
- t += paragraph_height(fr->paras[i]);
- }
- return t;
-}
-
-
-Paragraph *last_para(struct frame *fr)
-{
- if ( fr == NULL ) return NULL;
- if ( fr->paras == NULL ) return NULL;
- return fr->paras[fr->n_paras-1];
-}
-
-
-static void render_from_surf(cairo_surface_t *surf, cairo_t *cr,
- double w, double h, int border)
-{
- double x, y;
- int sw, sh;
-
- x = 0.0; y = 0.0;
- cairo_user_to_device(cr, &x, &y);
- x = rint(x); y = rint(y);
- cairo_device_to_user(cr, &x, &y);
-
- sw = cairo_image_surface_get_width(surf);
- sh = cairo_image_surface_get_height(surf);
-
- cairo_save(cr);
- cairo_scale(cr, w/sw, h/sh);
- cairo_new_path(cr);
- cairo_rectangle(cr, x, y, sw, sh);
- cairo_set_source_surface(cr, surf, 0.0, 0.0);
- cairo_pattern_t *patt = cairo_get_source(cr);
- cairo_pattern_set_extend(patt, CAIRO_EXTEND_PAD);
- cairo_pattern_set_filter(patt, CAIRO_FILTER_BEST);
- cairo_fill(cr);
- cairo_restore(cr);
-
- if ( border ) {
- cairo_new_path(cr);
- cairo_rectangle(cr, x+0.5, y+0.5, w, h);
- cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
- cairo_set_line_width(cr, 1.0);
- cairo_stroke(cr);
- }
-}
-
-
-void render_paragraph(cairo_t *cr, Paragraph *para, ImageStore *is)
-{
- cairo_surface_t *surf;
- cairo_surface_type_t type;
- double w, h;
-
- cairo_translate(cr, para->space[0], para->space[2]);
-
- type = cairo_surface_get_type(cairo_get_target(cr));
-
- switch ( para->type ) {
-
- case PARA_TYPE_TEXT :
- cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
- pango_cairo_update_layout(cr, para->layout);
- pango_cairo_show_layout(cr, para->layout);
- cairo_fill(cr);
- break;
-
- case PARA_TYPE_IMAGE :
- w = para->image_w;
- h = para->image_h;
- cairo_user_to_device_distance(cr, &w, &h);
- surf = lookup_image(is, para->filename, w);
- if ( surf != NULL ) {
- render_from_surf(surf, cr, para->image_w, para->image_h, 0);
- } else {
- printf("surf = NULL!\n");
- }
- break;
-
- case PARA_TYPE_CALLBACK :
- w = para->cb_w;
- h = para->cb_h;
- cairo_user_to_device_distance(cr, &w, &h);
- if ( type == CAIRO_SURFACE_TYPE_PDF ) {
- w *= 6; h *= 6;
- }
- surf = para->draw_func(w, h,
- para->bvp, para->vp);
- render_from_surf(surf, cr, para->cb_w, para->cb_h, 1);
- cairo_surface_destroy(surf); /* FIXME: Cache like crazy */
- break;
-
- }
-}
-
-
-static size_t end_offset_of_para(struct frame *fr, int pn)
-{
- int i;
- size_t total = 0;
- for ( i=0; i<fr->paras[pn]->n_runs; i++ ) {
- total += run_text_len(&fr->paras[pn]->runs[i]);
- }
- return total;
-}
-
-
-/* Local x,y in paragraph -> text offset */
-static size_t text_para_pos(Paragraph *para, double x, double y, int *ptrail)
-{
- int idx;
- pango_layout_xy_to_index(para->layout, pango_units_from_double(x),
- pango_units_from_double(y), &idx, ptrail);
- return idx;
-}
-
-
-void show_edit_pos(struct edit_pos a)
-{
- printf("para %i, pos %li, trail %i\n", a.para, (long int)a.pos, a.trail);
-}
-
-
-int positions_equal(struct edit_pos a, struct edit_pos b)
-{
- if ( a.para != b.para ) return 0;
- if ( a.pos != b.pos ) return 0;
- if ( a.trail != b.trail ) return 0;
- return 1;
-}
-
-
-void sort_positions(struct edit_pos *a, struct edit_pos *b)
-{
- if ( a->para > b->para ) {
- size_t tpos;
- int tpara, ttrail;
- tpara = b->para; tpos = b->pos; ttrail = b->trail;
- b->para = a->para; b->pos = a->pos; b->trail = a->trail;
- a->para = tpara; a->pos = tpos; a->trail = ttrail;
- }
-
- if ( (a->para == b->para) && (a->pos > b->pos) )
- {
- size_t tpos = b->pos;
- int ttrail = b->trail;
- b->pos = a->pos; b->trail = a->trail;
- a->pos = tpos; a->trail = ttrail;
- }
-}
-
-
-static PangoFontDescription *last_font_desc_and_col(struct frame *fr, int pn, double *col)
-{
- int i;
-
- for ( i=pn-1; i>=0; i-- ) {
- if ( fr->paras[i]->type != PARA_TYPE_TEXT ) continue;
- if ( fr->paras[i]->n_runs == 0 ) continue;
- col[0] = fr->paras[i]->runs[fr->paras[i]->n_runs-1].col[0];
- col[1] = fr->paras[i]->runs[fr->paras[i]->n_runs-1].col[1];
- col[2] = fr->paras[i]->runs[fr->paras[i]->n_runs-1].col[2];
- col[3] = fr->paras[i]->runs[fr->paras[i]->n_runs-1].col[3];
- return fr->paras[i]->runs[fr->paras[i]->n_runs-1].fontdesc;
- }
-
- /* No previous text at all, so use the default text style
- * (which is valid for new text in the frame, so this is OK) */
- col[0] = fr->col[0];
- col[1] = fr->col[1];
- col[2] = fr->col[2];
- col[3] = fr->col[3];
- return fr->fontdesc;
-}
-
-
-void ensure_run(struct frame *fr, struct edit_pos cpos)
-{
- SCBlock *bl;
- Paragraph *para;
- PangoFontDescription *fontdesc;
- double col[4];
-
- para = fr->paras[cpos.para];
-
- if ( para->n_runs > 0 ) return;
-
- if ( para->type != PARA_TYPE_TEXT ) return;
-
- if ( para->scblock != NULL ) {
-
- bl = sc_block_prepend(para->scblock, fr->scblocks);
- if ( bl == NULL ) {
- fprintf(stderr, "Couldn't prepend block\n");
- return;
- }
- sc_block_set_contents(bl, strdup(""));
-
- } else {
-
- /* If the paragraph's SCBlock is NULL, it means this paragraph
- * is right at the end of the document. The last thing in the
- * document is something like \newpara. */
- bl = sc_block_append_inside(fr->scblocks, NULL, NULL, strdup(""));
-
- }
-
- para->scblock = bl;
-
- fontdesc = last_font_desc_and_col(fr, cpos.para, col);
- add_run(para, bl, fontdesc, col, NULL);
- wrap_paragraph(para, NULL, fr->w - fr->pad_l - fr->pad_r, 0, 0);
-}
-
-
-int find_cursor(struct frame *fr, double x, double y, struct edit_pos *pos)
-{
- double pad;
- int i;
-
- if ( fr == NULL ) {
- fprintf(stderr, "Cursor frame is NULL.\n");
- return 1;
- }
-
- pad = fr->pad_t;
-
- for ( i=0; i<fr->n_paras; i++ ) {
- double npos = pad + paragraph_height(fr->paras[i]);
- if ( npos > y ) {
- pos->para = i;
- if ( fr->paras[i]->type == PARA_TYPE_TEXT ) {
- pos->pos = text_para_pos(fr->paras[i],
- x - fr->pad_l - fr->paras[i]->space[0],
- y - pad - fr->paras[i]->space[2],
- &pos->trail);
- } else {
- pos->pos = 0;
- }
- return 0;
- }
- pad = npos;
- }
-
- if ( fr->n_paras == 0 ) {
- printf("No paragraphs in frame.\n");
- return 1;
- }
-
- /* Pretend it's in the last paragraph */
- pad -= fr->paras[fr->n_paras-1]->height;
- pos->para = fr->n_paras - 1;
- pos->pos = text_para_pos(fr->paras[fr->n_paras-1],
- x - fr->pad_l, y - pad, &pos->trail);
- return 0;
-}
-
-
-int get_para_highlight(struct frame *fr, int cursor_para,
- double *cx, double *cy, double *cw, double *ch)
-{
- Paragraph *para;
- int i;
- double py = 0.0;
-
- if ( fr == NULL ) {
- fprintf(stderr, "Cursor frame is NULL.\n");
- return 1;
- }
-
- if ( cursor_para >= fr->n_paras ) {
- fprintf(stderr, "Highlight paragraph number is too high!\n");
- return 1;
- }
-
- para = fr->paras[cursor_para];
- for ( i=0; i<cursor_para; i++ ) {
- py += paragraph_height(fr->paras[i]);
- }
-
- *cx = fr->pad_l;
- *cy = fr->pad_t + py;
- *cw = fr->w - fr->pad_l - fr->pad_r;
- *ch = paragraph_height(para);
- return 0;
-}
-
-
-int get_cursor_pos(struct frame *fr, int cursor_para, int cursor_pos,
- double *cx, double *cy, double *ch)
-{
- Paragraph *para;
- PangoRectangle rect;
- int i;
- double py = 0.0;
-
- if ( fr == NULL ) {
- fprintf(stderr, "Cursor frame is NULL.\n");
- return 1;
- }
-
- if ( cursor_para >= fr->n_paras ) {
- fprintf(stderr, "Cursor paragraph number is too high!\n");
- return 1;
- }
-
- para = fr->paras[cursor_para];
- for ( i=0; i<cursor_para; i++ ) {
- py += paragraph_height(fr->paras[i]);
- }
-
- if ( para->type != PARA_TYPE_TEXT ) {
- return 1;
- }
-
- pango_layout_get_cursor_pos(para->layout, cursor_pos, &rect, NULL);
-
- *cx = pango_units_to_double(rect.x) + fr->pad_l + para->space[0];
- *cy = pango_units_to_double(rect.y) + fr->pad_t + py + para->space[2];
- *ch = pango_units_to_double(rect.height);
- return 0;
-}
-
-
-//void cursor_moveh(struct frame *fr, int *cpara, size_t *cpos, int *ctrail,
-void cursor_moveh(struct frame *fr, struct edit_pos *cp, signed int dir)
-{
- Paragraph *para = fr->paras[cp->para];
- int np = cp->pos;
-
- pango_layout_move_cursor_visually(para->layout, 1, cp->pos, cp->trail,
- dir, &np, &cp->trail);
- if ( np == -1 ) {
- if ( cp->para > 0 ) {
- size_t end_offs;
- cp->para--;
- end_offs = end_offset_of_para(fr, cp->para);
- if ( end_offs > 0 ) {
- cp->pos = end_offs - 1;
- cp->trail = 1;
- } else {
- /* Jumping into an empty paragraph */
- cp->pos = 0;
- cp->trail = 0;
- }
- return;
- } else {
- /* Can't move any further */
- return;
- }
- }
-
- if ( np == G_MAXINT ) {
- if ( cp->para < fr->n_paras-1 ) {
- cp->para++;
- cp->pos = 0;
- cp->trail = 0;
- return;
- } else {
- /* Can't move any further */
- return;
- }
- }
-
- cp->pos = np;
-}
-
-
-void check_callback_click(struct frame *fr, int para)
-{
- Paragraph *p = fr->paras[para];
- if ( p->type == PARA_TYPE_CALLBACK ) {
- p->click_func(0.0, 0.0, p->bvp, p->vp);
- }
-}
-
-
-static int get_paragraph_offset(Paragraph *para, int nrun)
-{
- int i;
- size_t t = 0;
-
- for ( i=0; i<nrun; i++ ) {
- struct text_run *run = &para->runs[i];
- t += run_text_len(run);
- }
- return t;
-}
-
-
-static int which_run(Paragraph *para, size_t offs)
-{
- int i;
- size_t t = 0;
-
- for ( i=0; i<para->n_runs; i++ ) {
- struct text_run *run = &para->runs[i];
- t += run_text_len(run);
- if ( t > offs ) return i;
- }
-
- /* Maybe offs points exactly to the end of the last run? */
- if ( t == offs ) return para->n_runs-1;
-
- return para->n_runs;
-}
-
-
-size_t pos_trail_to_offset(Paragraph *para, size_t offs, int trail)
-{
- glong char_offs;
- size_t run_offs;
- const char *run_text;
- struct text_run *run;
- int nrun;
- char *ptr;
- size_t para_offset_of_run;
-
- nrun = which_run(para, offs);
-
- if ( nrun == para->n_runs ) {
- fprintf(stderr, "pos_trail_to_offset: Offset too high\n");
- return 0;
- }
-
- if ( para->n_runs == 0 ) {
- return 0;
- }
-
- run = &para->runs[nrun];
-
- if ( para->type != PARA_TYPE_TEXT ) return 0;
-
- if ( run == NULL ) {
- fprintf(stderr, "pos_trail_to_offset: No run\n");
- return 0;
- }
-
- if ( run->scblock == NULL ) {
- fprintf(stderr, "pos_trail_to_offset: SCBlock = NULL?\n");
- return 0;
- }
-
- /* Get the text for the run */
- run_text = text_for_run(run);
- if ( run_text == NULL ) {
- fprintf(stderr, "pos_trail_to_offset: No contents "
- "(%p name=%s, options=%s)\n",
- run->scblock, sc_block_name(run->scblock),
- sc_block_options(run->scblock));
- return 0;
- }
-
-
- /* Turn the paragraph offset into a run offset */
- para_offset_of_run = get_paragraph_offset(para, nrun);
- run_offs = offs - para_offset_of_run;
-
- char_offs = g_utf8_pointer_to_offset(run_text, run_text+run_offs);
- char_offs += trail;
-
- if ( char_offs > g_utf8_strlen(run_text, -1) ) {
- printf("Offset outside string! '%s'\n"
- "char_offs %li offs %li len %li\n",
- run_text, (long int)char_offs, (long int)offs,
- (long int)g_utf8_strlen(run_text, -1));
- }
-
- ptr = g_utf8_offset_to_pointer(run_text, char_offs);
- return ptr - run_text + para_offset_of_run;
-}
-
-
-int position_editable(struct frame *fr, struct edit_pos cp)
-{
- Paragraph *para;
- int run;
- size_t paraoffs;
-
- if ( fr == NULL ) {
- fprintf(stderr, "Frame is NULL.\n");
- return 0;
- }
-
- if ( cp.para >= fr->n_paras ) {
- fprintf(stderr, "Paragraph number is too high!\n");
- return 0;
- }
-
- para = fr->paras[cp.para];
-
- if ( para->type != PARA_TYPE_TEXT ) {
- fprintf(stderr, "Paragraph is not text.\n");
- return 0;
- }
-
- paraoffs = pos_trail_to_offset(para, cp.pos, cp.trail);
- run = which_run(para, paraoffs);
- if ( run == para->n_runs ) {
- fprintf(stderr, "Couldn't find run!\n");
- return 0;
- }
-
- if ( para->runs[run].real_text != NULL ) return 0;
-
- return 1;
-}
-
-
-void insert_text_in_paragraph(Paragraph *para, size_t offs, const char *t)
-{
- int nrun;
-
- /* Find which run we are in */
- nrun = which_run(para, offs);
- if ( nrun == para->n_runs ) {
- fprintf(stderr, "Couldn't find run to insert into.\n");
- return;
- }
-
- if ( para->n_runs == 0 ) {
- printf("No runs in paragraph?\n");
- } else {
- struct text_run *run;
- size_t run_offs;
- run = &para->runs[nrun];
- run_offs = offs - get_paragraph_offset(para, nrun);
- sc_insert_text(run->scblock, run_offs, t);
- }
-}
-
-
-static SCBlock *pos_to_scblock(struct frame *fr, struct edit_pos p,
- enum para_type *type)
-{
- int run;
- size_t paraoffs;
- Paragraph *para;
-
- para = fr->paras[p.para];
- if ( type != NULL ) {
- *type = para->type;
- }
-
- if ( para->type != PARA_TYPE_TEXT ) {
- return para->scblock;
- }
-
- paraoffs = pos_trail_to_offset(para, p.pos, p.trail);
-
- run = which_run(para, paraoffs);
- assert(run < para->n_runs);
-
- return para->runs[run].scblock;
-}
-
-
-static size_t pos_to_offset(struct frame *fr, struct edit_pos p)
-{
- int run;
- size_t paraoffs;
- Paragraph *para;
-
- para = fr->paras[p.para];
- if ( para->type != PARA_TYPE_TEXT ) {
- return 0;
- }
-
- /* Offset of this position into the paragraph */
- paraoffs = pos_trail_to_offset(para, p.pos, p.trail);
-
- run = which_run(para, paraoffs);
- assert(run < para->n_runs);
-
- /* Offset of this position into the run
- * (and therefore into the SCBlock) */
- return paraoffs - get_paragraph_offset(para, run);
-}
-
-
-static int pos_to_run_number(struct frame *fr, struct edit_pos p)
-{
- int run;
- size_t paraoffs;
- Paragraph *para;
-
- para = fr->paras[p.para];
- if ( para->type != PARA_TYPE_TEXT ) {
- return 0;
- }
-
- paraoffs = pos_trail_to_offset(para, p.pos, p.trail);
-
- run = which_run(para, paraoffs);
- assert(run < para->n_runs);
-
- return run;
-}
-
-
-static void delete_run(Paragraph *para, int nrun)
-{
- printf("deleting run %i of %i from para %p\n", nrun, para->n_runs, para);
- memmove(&para->runs[nrun], &para->runs[nrun+1],
- (para->n_runs-nrun-1)*sizeof(struct text_run));
- para->n_runs--;
-}
-
-
-static Paragraph *scan_runs_for_scblock(struct frame *fr, int pn1, int pn2,
- SCBlock *bl, int *run)
-{
- int i;
-
- for ( i=pn1; i<=pn2; i++ ) {
-
- int j;
-
- /* Non-text paragraph - just one thing to check */
- if ( fr->paras[i]->scblock == bl ) {
- *run = 0;
- return fr->paras[i];
- }
-
- /* Check all runs */
- for ( j=0; j<fr->paras[i]->n_runs; j++ ) {
- if ( fr->paras[i]->runs[j].scblock == bl ) {
- *run = j;
- return fr->paras[i];
- }
- }
- }
- return NULL;
-}
-
-
-static Paragraph *find_run_for_scblock_next(struct frame *fr, int pn1, int pn2,
- SCBlock *bl, int *run)
-{
- if ( sc_block_child(bl) != NULL ) {
- Paragraph *para;
- para = find_run_for_scblock_next(fr, pn1, pn2,
- sc_block_child(bl), run);
- if ( para != NULL ) return para;
- }
-
- do {
- Paragraph *para;
- para = scan_runs_for_scblock(fr, pn1, pn2, bl, run);
- if ( para != NULL ) return para;
- bl = sc_block_next(bl);
- } while ( bl != NULL );
-
- return NULL;
-}
-
-
-/* Find the run which contains the text from "bl",
- * taking into account that it might be a child block, for example:
- * {some text}
- * \italic <---- bl points here
- * {more text} <---- but this block is referenced by the run
- * {final text}
- */
-static Paragraph *find_run_for_scblock(struct frame *fr, int pn1, int pn2,
- SCBlock *bl, int *run)
-{
- Paragraph *para;
-
- show_sc_block(bl, "searching ");
- para = scan_runs_for_scblock(fr, pn1, pn2, bl, run);
- if ( para != NULL ) return para;
-
- if ( sc_block_child(bl) != NULL ) {
- para = find_run_for_scblock_next(fr, pn1, pn2, sc_block_child(bl), run);
- if ( para != NULL ) return para;
- }
-
- return NULL;
-}
-
-
-static int paragraph_number(struct frame *fr, Paragraph *p, int *err)
-{
- int i;
- for ( i=0; i<fr->n_paras; i++ ) {
- if ( fr->paras[i] == p ) return i;
- }
- fprintf(stderr, "Couldn't find paragraph %p\n", p);
- *err = 1;
- return 0;
-}
-
-
-static int find_para(struct frame *fr, Paragraph *para)
-{
- int i;
-
- for ( i=0; i<fr->n_paras; i++ ) {
- if ( fr->paras[i] == para ) return i;
- }
-
- return fr->n_paras;
-}
-
-
-static void delete_paragraph(struct frame *fr, Paragraph *para, int *pnp)
-{
- int pn = find_para(fr, para);
- if ( pn == fr->n_paras ) {
- fprintf(stderr, "Couldn't find paragraph to delete (%p)\n", para);
- return;
- }
-
- printf("deleting paragraph %i (%p)\n", pn, para);
-
- memmove(&fr->paras[pn], &fr->paras[pn+1],
- (fr->n_paras-pn-1)*sizeof(Paragraph *));
- fr->n_paras--;
-
- if ( (pnp != NULL) && (*pnp > pn) ) {
- (*pnp)--;
- }
-}
-
-
-static void delete_run_for_scblock(struct frame *fr,
- Paragraph *p1, Paragraph *p2, SCBlock *bl,
- int *pnp)
-{
- int pn1, pn2;
- int err = 0;
- Paragraph *para;
- int run;
-
- pn1 = paragraph_number(fr, p1, &err);
- pn2 = paragraph_number(fr, p2, &err);
- if ( err ) return;
-
- para = find_run_for_scblock(fr, pn1, pn2, bl, &run);
- if ( para == NULL ) {
- fprintf(stderr, "Couldn't find block %p between paragraphs %p and %p\n",
- bl, p1, p2);
- return;
- }
-
- if ( (run==0) && (para->scblock == bl ) ) {
- delete_paragraph(fr, para, pnp);
- } else {
- delete_run(para, run);
- }
-}
-
-
-static signed int merge_paragraph_runs(Paragraph *p1, Paragraph *p2)
-{
- struct text_run *runs_new;
- int i, spos;
-
- /* All the runs from p2 get added to p1 */
- runs_new = realloc(p1->runs,
- (p1->n_runs+p2->n_runs)*sizeof(struct text_run));
- if ( runs_new == NULL ) {
- fprintf(stderr, "Failed to allocate merged runs.\n");
- return -1;
- }
- p1->runs = runs_new;
-
- spos = p1->n_runs;
-
- /* The end of the united paragraph should now be the end of the
- * second one */
- set_newline_at_end(p1, get_newline_at_end(p2));
-
- for ( i=0; i<p2->n_runs; i++ ) {
- p1->runs[p1->n_runs] = p2->runs[i];
- p1->n_runs++;
- }
- free(p2->runs);
- free(p2);
-
- return spos;
-}
-
-
-static void merge_paragraphs_by_newpara(struct frame *fr, SCBlock *np)
-{
- int i;
- Paragraph *p1;
- Paragraph *p2;
-
- for ( i=0; i<fr->n_paras-1; i++ ) {
- if ( fr->paras[i]->newline_at_end == np ) {
-
- int j;
- signed int spos;
-
- p1 = fr->paras[i];
- p2 = fr->paras[i+1];
-
- printf("-------------------------------\n");
- show_para(p1);
- printf("---x--------x------------------\n");
- show_para(p2);
- spos = merge_paragraph_runs(p1, p2);
- if ( spos < 0 ) {
- fprintf(stderr, "Failed to merge paragraphs\n");
- return;
- }
- printf("-------------------------------\n");
- show_para(p1);
-
- for ( j=i+1; j<fr->n_paras-1; j++ ) {
- fr->paras[j] = fr->paras[j+1];
- }
- fr->n_paras--;
-
- return;
-
- }
- }
-
- fprintf(stderr, "Couldn't find paragraphs to merge by newpara\n");
-}
-
-
-static int find_block_inside(SCBlock *needle, SCBlock *bl)
-{
- if ( needle == bl ) return 1;
-
- if ( sc_block_child(bl) != NULL ) {
- if ( find_block_inside(needle, sc_block_child(bl)) ) return 1;
- }
-
- if ( sc_block_next(bl) != NULL ) {
- if ( find_block_inside(needle, sc_block_next(bl)) ) return 1;
- }
-
- return 0;
-}
-
-
-/* Return true if "top" either IS "child", or contains "child" somewhere
- * underneath, even if via a macro expansion */
-static int block_is_under(SCBlock *needle, SCBlock *top)
-{
- if ( needle == top ) return 1;
-
- if ( sc_block_child(top) != NULL ) {
- if ( find_block_inside(needle, sc_block_child(top)) ) return 1;
- }
-
- /* Do not look at top->next here */
-
- return 0;
-}
-
-
-void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_pos p2,
- double wrapw)
-{
- int i;
- SCBlock *p1scblock, *p2scblock;
- enum para_type type1, type2;
- size_t p2offs;
- SCBlock *scblock;
- int wrap_end;
-
- sort_positions(&p1, &p2);
-
- /* To make sure there are no nasty surprises ahead, run through the
- * paragraphs we're about to touch, and make sure they all have at least
- * an empty dummy run */
- for ( i=p1.para; i<=p2.para; i++ ) {
- struct edit_pos ep;
- ep.para = i;
- ep.pos = 0;
- ep.trail = 0;
- ensure_run(fr, ep);
- }
-
- if ( !position_editable(fr, p1) || !position_editable(fr, p2) ) {
- fprintf(stderr, "Delete outside editable region\n");
- return;
- }
-
- /* Find SC positions for start and end */
- p1scblock = pos_to_scblock(fr, p1, &type1);
- p2scblock = pos_to_scblock(fr, p2, &type2);
- p2offs = pos_to_offset(fr, p2);
- wrap_end = p2.para;
-
- printf("SCBlocks %p to %p\n", p1scblock, p2scblock);
- if ( p1scblock == NULL ) {
- fprintf(stderr, "Starting block NULL. Not deleting.\n");
- return;
- }
- if ( p2scblock == NULL ) {
- fprintf(stderr, "Ending block NULL. Not deleting.\n");
- return;
- }
- //show_sc_blocks(p1scblock);
-
- if ( (p1scblock == p2scblock) && (type1 == PARA_TYPE_TEXT) ) {
-
- size_t p1offs;
- printf("Simple case, one SCBlock\n");
-
- assert(type1 == type2);
-
- /* Remove the text and update the run length */
- p1offs = pos_to_offset(fr, p1);
- scblock_delete_text(p1scblock, p1offs, p2offs);
-
- wrap_paragraph(fr->paras[p1.para], NULL, wrapw, 0, 0);
-
- return;
- }
-
- /* Starting point for iteration over blocks in middle of range.
- * Record this now, because p1scblock might be about to get deleted */
- scblock = sc_block_next(p1scblock);
-
- /* First SCBlock in range: delete whole thing or second half */
- printf("First block %p\n", p1scblock);
- if ( type1 == PARA_TYPE_TEXT ) {
-
- size_t p1offs = pos_to_offset(fr, p1);
- int p1run = pos_to_run_number(fr, p1);
- printf(" offs %li\n", (long int)p1offs);
- if ( p1offs != 0 ) {
- printf("Partial delete\n");
- printf("contents '%s'\n", sc_block_contents(p1scblock));
- printf("from offs %li\n", (long int)p1offs);
- scblock_delete_text(p1scblock, p1offs, -1);
- } else {
- printf("Deleting the whole text SCBlock\n");
- sc_block_delete(&fr->scblocks, p1scblock);
- delete_run(fr->paras[p1.para], p1run);
- }
-
- } else {
- printf("Deleting the whole non-text SCBlock\n");
- sc_block_delete(&fr->scblocks, p1scblock);
- }
-
- /* Delete all the complete SCBlocks in the middle of the range */
- if ( !block_is_under(p2scblock, scblock) ) {
- do {
-
- SCBlock *next;
-
- /* For each SC block in middle of range: */
- printf("Deleting %p\n", scblock);
- if ( scblock == NULL ) {
- fprintf(stderr, "nothing?\n");
- break;
- }
- printf("name is '%s'\n", sc_block_name(scblock));
-
- if ( (sc_block_name(scblock) != NULL)
- && (strcmp(sc_block_name(scblock), "newpara") == 0) )
- {
- /* Deleting newpara block, merge the paragraphs */
- merge_paragraphs_by_newpara(fr, scblock);
- p2.para--;
- }
-
- next = sc_block_next(scblock);
- delete_run_for_scblock(fr, fr->paras[p1.para],
- fr->paras[p2.para], scblock,
- &p2.para);
- sc_block_delete(&fr->scblocks, scblock);
-
- scblock = next;
-
- } while ( !block_is_under(p2scblock, scblock) );
- }
-
- /* Last SCBlock in range: delete whole thing or first half */
- printf("Last block %p (%s)\n", p2scblock, sc_block_name(p2scblock));
- if ( type2 == PARA_TYPE_TEXT ) {
- size_t len;
- printf(" offs %li\n", (long int)p2offs);
- if ( sc_block_contents(p2scblock) != NULL ) {
- len = strlen(sc_block_contents(p2scblock));
- } else {
- len = 0;
- }
- printf(" len %li\n", (long int)len);
- if ( (len > 0) && (p2offs == len) ) {
- printf("Deleting the whole text SCBlock\n");
- printf("deleting block %p\n", p2scblock);
- show_sc_block(p2scblock, "");
- sc_block_delete(&fr->scblocks, p2scblock);
- delete_run_for_scblock(fr, fr->paras[p1.para],
- fr->paras[p2.para], p2scblock,
- NULL);
- } else if ( p2offs > 0 ) {
- printf("Partial delete\n");
- printf("contents '%s'\n", sc_block_contents(p2scblock));
- printf("up to offs %li\n", (long int)p2offs);
- scblock_delete_text(p2scblock, 0, p2offs);
- } /* else do nothing */
- } else {
- printf("Deleting the whole non-text SCBlock\n");
- sc_block_delete(&fr->scblocks, p2scblock);
- }
-
- /* If any paragraphs have been deleted, this will wrap too many
- * paragraphs, but it doesn't matter as long as we don't wrap
- * past the end of the frame's contents. */
- for ( i=p1.para; i<=wrap_end; i++ ) {
- if ( i >= fr->n_paras ) break;
- printf("Wrapping para %i (%p)\n", i, fr->paras[i]);
- wrap_paragraph(fr->paras[i], NULL, wrapw, 0, 0);
- }
- printf("All done.\n");
-}
-
-
-void show_para(Paragraph *p)
-{
- printf("Paragraph %p\n", p);
-
- if ( p->type == PARA_TYPE_TEXT ) {
-
- int i;
-
- printf("%i runs:\n", p->n_runs);
- for ( i=0; i<p->n_runs; i++ ) {
- printf(" Run %2i: SCBlock %p %s '%s'\n",
- i, p->runs[i].scblock,
- pango_font_description_to_string(p->runs[i].fontdesc),
- sc_block_contents(p->runs[i].scblock));
- }
-
- } else if ( p->type == PARA_TYPE_IMAGE ) {
- printf(" Image: %s\n", p->filename);
- } else {
- printf(" Other paragraph type\n");
- }
-}
-
-
-static SCBlock *split_text_paragraph(struct frame *fr, int pn, size_t pos,
- PangoContext *pc)
-{
- Paragraph *pnew;
- int i;
- SCBlock *nnp;
- size_t run_offs;
- int run;
- Paragraph *para = fr->paras[pn];
- struct text_run *rr;
-
- pnew = insert_paragraph(fr, pn);
- if ( pnew == NULL ) {
- fprintf(stderr, "Failed to insert paragraph\n");
- return NULL;
- }
-
- /* Determine which run the cursor is in */
- run = which_run(para, pos);
-
- /* Create the new (second) paragraph */
- pnew->type = PARA_TYPE_TEXT;
- pnew->n_runs = 0;
- pnew->runs = NULL;
- for ( i=0; i<4; i++ ) pnew->space[i] = para->space[i];
-
- rr = &para->runs[run];
- run_offs = pos - get_paragraph_offset(para, run);
- printf("split at run %i\n", run);
-
- /* Easy case: splitting at a run boundary */
- if ( run_offs == run_text_len(rr) ) {
-
- /* Even easier case: splitting at the end of the paragraph */
- if ( run == para->n_runs-1 ) {
-
- SCBlock *np;
- SCBlock *end;
-
- printf("Simple new para\n");
-
- if ( get_newline_at_end(para) == NULL ) {
-
- /* The current paragraph doesn't have
- * a \newpara yet */
-
- np = sc_block_append(rr->scblock,
- strdup("newpara"), NULL,
- NULL, NULL);
- set_newline_at_end(para, np);
-
- } else {
-
- SCBlock *op;
-
- /* If the current paragraph did have \newpara,
- * then the new one needs one too */
- np = sc_block_append(rr->scblock,
- strdup("newpara"),
- NULL, NULL, NULL);
- op = get_newline_at_end(para);
- set_newline_at_end(para, np);
- set_newline_at_end(pnew, op);
-
-
- }
-
- /* Add an empty run + SCBlock to type into */
- end = sc_block_append(np, NULL, NULL, strdup(""), NULL);
-
- pnew->n_runs = 0;
- add_run(pnew, end, rr->fontdesc, rr->col, NULL);
- pnew->scblock = end;
-
- wrap_paragraph(pnew, pc, fr->w - fr->pad_l - fr->pad_r, 0, 0);
-
- return end;
-
- }
-
- } else {
-
- /* Split the run (and SCBlock) into two */
- double col[4] = {0,0,0,0};
- struct text_run *rn;
-
- printf("Splitting run %i. Before:\n", run);
- show_para(para);
-
- add_run(para, NULL, NULL, col, NULL);
- /* -2 here because add_run increased para->n_runs by 1 */
- memmove(&para->runs[run+2], &para->runs[run+1],
- (para->n_runs - run - 2)*sizeof(struct text_run));
-
- rr = &para->runs[run]; /* Because add_run realloced the runs */
- rn = &para->runs[run+1];
-
- rn->scblock = sc_block_split(rr->scblock, run_offs);
-
- rn->fontdesc = pango_font_description_copy(rr->fontdesc);
- rn->col[0] = rr->col[0];
- rn->col[1] = rr->col[1];
- rn->col[2] = rr->col[2];
- rn->col[3] = rr->col[3];
-
- printf("After:\n");
- show_para(para);
-
- }
-
- /* All later runs just get moved to the new paragraph */
- for ( i=run+1; i<para->n_runs; i++ ) {
- double col[4] = {0,0,0,0};
- printf("Moving run %i to pos %i\n", i, pnew->n_runs);
- add_run(pnew, NULL, NULL, col, NULL);
- pnew->runs[pnew->n_runs-1] = para->runs[i];
- }
- pnew->scblock = pnew->runs[0].scblock;
-
- /* Truncate the first paragraph at the appropriate position */
- para->n_runs = run+1;
-
- printf("Final paragraphs:\n");
- printf("First:\n");
- show_para(para);
- printf("Second:\n");
- show_para(pnew);
-
- /* Add a \newpara after the end of the first paragraph's SC */
- nnp = sc_block_append(rr->scblock, strdup("newpara"), NULL, NULL, NULL);
- set_newline_at_end(pnew, get_newline_at_end(para));
- set_newline_at_end(para, nnp);
-
- wrap_paragraph(para, pc, fr->w - fr->pad_l - fr->pad_r, 0, 0);
- wrap_paragraph(pnew, pc, fr->w - fr->pad_l - fr->pad_r, 0, 0);
-
- return sc_block_next(nnp);
-}
-
-
-SCBlock *split_paragraph(struct frame *fr, int pn, size_t pos, PangoContext *pc)
-{
- Paragraph *para = fr->paras[pn];
-
- if ( para->type == PARA_TYPE_TEXT ) {
- return split_text_paragraph(fr, pn, pos, pc);
- } else {
- /* Other types can't be split */
- return NULL;
- }
-}
-
-
-SCBlock *block_at_cursor(struct frame *fr, int pn, size_t pos)
-{
- Paragraph *para = fr->paras[pn];
-
- if ( para->type != PARA_TYPE_CALLBACK ) return NULL;
-
- return para->scblock;
-}
-
-
-int get_sc_pos(struct frame *fr, int pn, size_t pos,
- SCBlock **bl, size_t *ppos)
-{
- Paragraph *para = fr->paras[pn];
- int nrun;
- struct text_run *run;
-
- nrun = which_run(para, pos);
- if ( nrun == para->n_runs ) {
- fprintf(stderr, "Couldn't find run to insert into.\n");
- return 1;
- }
- run = &para->runs[nrun];
-
- *ppos = pos - get_paragraph_offset(para, nrun);
- *bl = run->scblock;
-
- return 0;
-}
-
-
-void set_para_spacing(Paragraph *para, float space[4])
-{
- if ( para == NULL ) return;
- para->space[0] = space[0];
- para->space[1] = space[1];
- para->space[2] = space[2];
- para->space[3] = space[3];
-}
-
-
-void set_para_alignment(Paragraph *para, PangoAlignment align)
-{
- if ( para == NULL ) return;
- para->alignment = align;
-}
-
-
-void *get_para_bvp(Paragraph *para)
-{
- if ( para->type != PARA_TYPE_CALLBACK ) return NULL;
- return para->bvp;
-}
-
-
-SCBlock *para_scblock(Paragraph *para)
-{
- return para->scblock;
-}
-
-
-enum para_type para_type(Paragraph *para)
-{
- return para->type;
-}
-
-
-int para_debug_num_runs(Paragraph *para)
-{
- if ( para->type != PARA_TYPE_TEXT ) return 0;
- return para->n_runs;
-}
-
-
-int para_debug_run_info(Paragraph *para, int i, SCBlock **scblock)
-{
- if ( para->type != PARA_TYPE_TEXT ) return 1;
- if ( i >= para->n_runs ) return 1;
-
- *scblock = para->runs[i].scblock;
- return 0;
-}
diff --git a/src-old/frame.h b/src-old/frame.h
deleted file mode 100644
index d0525f8..0000000
--- a/src-old/frame.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * frame.h
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef FRAME_H
-#define FRAME_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <pango/pango.h>
-#include <cairo.h>
-
-
-typedef enum
-{
- GRAD_NONE,
- GRAD_HORIZ,
- GRAD_VERT
-} GradientType;
-
-enum para_type
-{
- PARA_TYPE_TEXT,
- PARA_TYPE_IMAGE,
- PARA_TYPE_CALLBACK
-};
-
-typedef struct _paragraph Paragraph;
-
-#include "sc_parse.h"
-#include "sc_interp.h"
-#include "imagestore.h"
-
-
-struct edit_pos
-{
- int para; /* Paragraph number */
- size_t pos; /* Byte position within paragraph
- * Yes, really. See pango_layout_xy_to_index */
- int trail;
-};
-
-
-struct frame
-{
- struct frame **children;
- int num_children;
- int max_children;
-
- SCBlock *scblocks;
-
- Paragraph **paras;
- int n_paras;
- int max_paras;
-
- /* The font which will be used by default for this frame */
- PangoFontDescription *fontdesc;
- double col[4];
-
- /* The rectangle allocated to this frame, determined by the renderer */
- double x;
- double y;
- double w;
- double h;
-
- double pad_t;
- double pad_b;
- double pad_l;
- double pad_r;
-
- /* Background properties for this frame */
- double bgcol[4];
- double bgcol2[4];
- GradientType grad;
-
- /* True if this frame should be deleted on the next mouse click */
- int empty;
-
- /* True if the aspect ratio of this frame should be maintained */
- int is_image;
-
- /* True if this frame can be resized and moved */
- int resizable;
-};
-
-
-extern struct frame *frame_new(void);
-extern void frame_free(struct frame *fr);
-extern struct frame *add_subframe(struct frame *fr);
-extern struct frame *find_frame_with_scblocks(struct frame *top,
- SCBlock *scblocks);
-
-extern double total_height(struct frame *fr);
-
-extern Paragraph *last_para(struct frame *fr);
-extern void show_para(Paragraph *p);
-extern void set_para_spacing(Paragraph *para, float space[4]);
-extern void set_para_alignment(Paragraph *para, PangoAlignment align);
-
-extern double paragraph_height(Paragraph *para);
-extern void render_paragraph(cairo_t *cr, Paragraph *para, ImageStore *is);
-
-extern void set_newline_at_end(Paragraph *para, SCBlock *bl);
-extern void show_edit_pos(struct edit_pos a);
-
-extern void add_run(Paragraph *para, SCBlock *scblock,
- PangoFontDescription *fdesc, double col[4],
- const char *real_text);
-
-extern Paragraph *insert_paragraph(struct frame *fr, int pos);
-
-extern Paragraph *add_callback_para(struct frame *fr, SCBlock *scblock,
- double w, double h,
- SCCallbackDrawFunc draw_func,
- SCCallbackClickFunc click_func, void *bvp,
- void *vp);
-
-extern void add_image_para(struct frame *fr, SCBlock *scblock,
- const char *filename,
- ImageStore *is, double w, double h, int editable);
-
-extern void wrap_paragraph(Paragraph *para, PangoContext *pc, double w,
- size_t sel_start, size_t sel_end);
-
-extern int find_cursor(struct frame *fr, double x, double y,
- struct edit_pos *pos);
-
-extern void sort_positions(struct edit_pos *a, struct edit_pos *b);
-
-extern void ensure_run(struct frame *fr, struct edit_pos cpos);
-
-extern int positions_equal(struct edit_pos a, struct edit_pos b);
-
-extern int get_para_highlight(struct frame *fr, int cursor_para,
- double *cx, double *cy, double *cw, double *ch);
-
-extern int position_editable(struct frame *fr, struct edit_pos cp);
-
-extern int get_cursor_pos(struct frame *fr, int cursor_para, int cursor_pos,
- double *cx, double *cy, double *ch);
-
-extern void cursor_moveh(struct frame *fr, struct edit_pos *cp, signed int dir);
-
-extern void check_callback_click(struct frame *fr, int para);
-
-extern size_t pos_trail_to_offset(Paragraph *para, size_t offs, int trail);
-
-extern void insert_text_in_paragraph(Paragraph *para, size_t offs,
- const char *t);
-
-extern void delete_text_from_frame(struct frame *fr, struct edit_pos p1, struct edit_pos p2,
- double wrap_w);
-
-extern SCBlock *split_paragraph(struct frame *fr, int pn, size_t pos,
- PangoContext *pc);
-extern SCBlock *block_at_cursor(struct frame *fr, int para, size_t pos);
-
-extern void show_frame_hierarchy(struct frame *fr, const char *t);
-
-extern int get_sc_pos(struct frame *fr, int pn, size_t pos,
- SCBlock **bl, size_t *ppos);
-
-extern void *get_para_bvp(Paragraph *para);
-
-extern Paragraph *create_paragraph(struct frame *fr, SCBlock *bl);
-
-extern enum para_type para_type(Paragraph *para);
-extern SCBlock *para_scblock(Paragraph *para);
-
-extern SCBlock *para_debug_get_newline_at_end(Paragraph *para);
-extern int para_debug_num_runs(Paragraph *para);
-extern int para_debug_run_info(Paragraph *para, int i, SCBlock **scblock);
-
-#endif /* FRAME_H */
diff --git a/src-old/presentation.c b/src-old/presentation.c
deleted file mode 100644
index d7d9c08..0000000
--- a/src-old/presentation.c
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * presentation.c
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <gtk/gtk.h>
-
-#include "presentation.h"
-#include "slide_window.h"
-#include "frame.h"
-#include "imagestore.h"
-#include "render.h"
-#include "sc_interp.h"
-#include "utils.h"
-
-
-void free_presentation(struct presentation *p)
-{
- /* FIXME: Loads of stuff leaks here */
- g_object_unref(p->file);
- g_object_unref(p->stylesheet_from);
- imagestore_destroy(p->is);
- free(p);
-}
-
-
-char *get_titlebar_string(struct presentation *p)
-{
- if ( p == NULL || p->file == NULL ) {
- return strdup(_("(untitled)"));
- } else {
- char *bn = g_file_get_basename(p->file);
- return bn;
- }
-}
-
-
-static void find_and_load_stylesheet(struct presentation *p, GFile *file)
-{
- GFile *ssfile;
-
- if ( file != NULL ) {
-
- /* First choice: /same/directory/<presentation>.ss */
- gchar *ssuri = g_file_get_uri(file);
- if ( ssuri != NULL ) {
- size_t l = strlen(ssuri);
- if ( ssuri[l-3] == '.' && ssuri[l-2] == 's' && ssuri[l-1] =='c' ) {
- ssuri[l-1] = 's';
- ssfile = g_file_new_for_uri(ssuri);
- p->stylesheet = stylesheet_load(ssfile);
- p->stylesheet_from = ssfile;
- g_free(ssuri);
- }
- }
-
- /* Second choice: /same/directory/stylesheet.ss */
- if ( p->stylesheet == NULL ) {
- GFile *parent = g_file_get_parent(file);
- if ( parent != NULL ) {
- ssfile = g_file_get_child(parent, "stylesheet.ss");
- if ( ssfile != NULL ) {
- p->stylesheet = stylesheet_load(ssfile);
- p->stylesheet_from = ssfile;
- }
- g_object_unref(parent);
- }
- }
-
- }
-
- /* Third choice: <cwd>/stylesheet.ss */
- if ( p->stylesheet == NULL ) {
- ssfile = g_file_new_for_path("./stylesheet.ss");
- p->stylesheet = stylesheet_load(ssfile);
- p->stylesheet_from = ssfile;
- }
-
- /* Fourth choice: internal default stylesheet */
- if ( p->stylesheet == NULL ) {
- ssfile = g_file_new_for_uri("resource:///uk/me/bitwiz/Colloquium/default.ss");
- p->stylesheet = stylesheet_load(ssfile);
- p->stylesheet_from = NULL;
- g_object_unref(ssfile);
- }
-
- /* Last resort is NULL stylesheet and SCInterpreter's defaults */
- /* We keep a reference to the GFile */
-}
-
-
-struct presentation *new_presentation(const char *imagestore)
-{
- struct presentation *new;
-
- new = calloc(1, sizeof(struct presentation));
- if ( new == NULL ) return NULL;
-
- new->file = NULL;
- new->stylesheet_from = NULL;
-
- new->scblocks = NULL;
-
- /* Default slide size */
- new->slide_width = 1024.0;
- new->slide_height = 768.0;
-
- new->completely_empty = 1;
- new->saved = 1;
- new->stylesheet = NULL;
- new->is = imagestore_new(imagestore);
-
- new->lang = pango_language_get_default();
-
- find_and_load_stylesheet(new, NULL);
-
- return new;
-}
-
-
-int save_presentation(struct presentation *p, GFile *file, GFile *ssfile)
-{
- GFileOutputStream *fh;
- int r;
- int sr;
- GError *error = NULL;
-
- fh = g_file_replace(file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error);
- if ( fh == NULL ) {
- fprintf(stderr, _("Open failed: %s\n"), error->message);
- return 1;
- }
- r = save_sc_block(G_OUTPUT_STREAM(fh), p->scblocks);
- if ( r ) {
- fprintf(stderr, _("Couldn't save presentation\n"));
- }
- g_object_unref(fh);
-
- if ( ssfile != NULL ) {
- char *uri = g_file_get_uri(ssfile);
- printf(_("Saving stylesheet to %s\n"), uri);
- g_free(uri);
- sr = stylesheet_save(p->stylesheet, ssfile);
- if ( sr ) {
- fprintf(stderr, _("Couldn't save stylesheet\n"));
- }
- if ( p->stylesheet_from != ssfile ) {
- if ( p->stylesheet_from != NULL ) {
- g_object_unref(p->stylesheet_from);
- }
- p->stylesheet_from = ssfile;
- g_object_ref(p->stylesheet_from);
- }
- } else {
- fprintf(stderr, _("Not saving the stylesheet\n"));
- sr = 0;
- }
-
- if ( r || sr ) return 1;
-
- imagestore_set_parent(p->is, g_file_get_parent(file));
-
- if ( p->file != file ) {
- if ( p->file != NULL ) g_object_unref(p->file);
- p->file = file;
- g_object_ref(p->file);
- }
- p->saved = 1;
- update_titlebar(p->narrative_window);
- return 0;
-}
-
-
-int slide_number(struct presentation *p, SCBlock *sl)
-{
- SCBlock *bl = p->scblocks;
- int n = 0;
-
- while ( bl != NULL ) {
- if ( safe_strcmp(sc_block_name(bl), "slide") == 0 ) {
- n++;
- if ( bl == sl ) return n;
- }
- bl = sc_block_next(bl);
- }
-
- return 0;
-}
-
-
-int num_slides(struct presentation *p)
-{
- SCBlock *bl = p->scblocks;
- int n = 0;
-
- while ( bl != NULL ) {
- if ( safe_strcmp(sc_block_name(bl), "slide") == 0 ) {
- n++;
- }
- bl = sc_block_next(bl);
- }
-
- return n;
-}
-
-
-SCBlock *first_slide(struct presentation *p)
-{
- SCBlock *bl = p->scblocks;
-
- while ( bl != NULL ) {
- if ( safe_strcmp(sc_block_name(bl), "slide") == 0 ) {
- return bl;
- }
- bl = sc_block_next(bl);
- }
-
- fprintf(stderr, "Couldn't find first slide!\n");
- return NULL;
-}
-
-
-SCBlock *last_slide(struct presentation *p)
-{
- SCBlock *bl = p->scblocks;
- SCBlock *l = NULL;
-
- while ( bl != NULL ) {
- if ( safe_strcmp(sc_block_name(bl), "slide") == 0 ) {
- l = bl;
- }
- bl = sc_block_next(bl);
- }
-
- if ( l == NULL ) {
- fprintf(stderr, "Couldn't find last slide!\n");
- }
- return l;
-}
-
-
-SCBlock *next_slide(struct presentation *p, SCBlock *sl)
-{
- SCBlock *bl = sl;
- int found = 0;
-
- while ( bl != NULL ) {
- if ( safe_strcmp(sc_block_name(bl), "slide") == 0 ) {
- if ( found ) return bl;
- }
- if ( bl == sl ) {
- found = 1;
- }
- bl = sc_block_next(bl);
- }
-
- fprintf(stderr, "Couldn't find next slide!\n");
- return NULL;
-}
-
-
-SCBlock *prev_slide(struct presentation *p, SCBlock *sl)
-{
- SCBlock *bl = p->scblocks;
- SCBlock *l = NULL;
-
- while ( bl != NULL ) {
- if ( bl == sl ) {
- if ( l == NULL ) return sl; /* Already on first slide */
- return l;
- }
- if ( safe_strcmp(sc_block_name(bl), "slide") == 0 ) {
- l = bl;
- }
- bl = sc_block_next(bl);
- }
-
- fprintf(stderr, "Couldn't find prev slide!\n");
- return NULL;
-}
-
-
-static void set_slide_size_from_stylesheet(struct presentation *p)
-{
- char *result;
-
- result = stylesheet_lookup(p->stylesheet, "$.slide", "size");
- if ( result != NULL ) {
- float v[2];
- if ( parse_double(result, v) == 0 ) {
- p->slide_width = v[0];
- p->slide_height = v[1];
- }
- }
-}
-
-
-int load_presentation(struct presentation *p, GFile *file)
-{
- int r = 0;
- char *everything;
-
- assert(p->completely_empty);
-
- if ( !g_file_load_contents(file, NULL, &everything, NULL, NULL, NULL) ) {
- fprintf(stderr, _("Failed to load '%s'\n"), g_file_get_uri(file));
- return 1;
- }
-
- p->scblocks = sc_parse(everything);
- g_free(everything);
-
- p->lang = pango_language_get_default();
-
- if ( p->scblocks == NULL ) r = 1;
-
- if ( r ) {
- p->completely_empty = 1;
- fprintf(stderr, _("Parse error.\n"));
- return r; /* Error */
- }
-
- p->stylesheet = NULL;
-
- find_and_load_stylesheet(p, file);
-
- set_slide_size_from_stylesheet(p);
-
- assert(p->file == NULL);
- p->file = file;
- g_object_ref(file);
-
- imagestore_set_parent(p->is, g_file_get_parent(file));
-
- return 0;
-}
-
diff --git a/src-old/presentation.h b/src-old/presentation.h
deleted file mode 100644
index b288d8e..0000000
--- a/src-old/presentation.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * presentation.h
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef PRESENTATION_H
-#define PRESENTATION_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-struct presentation;
-
-#include "imagestore.h"
-#include "sc_parse.h"
-#include "slideshow.h"
-#include "narrative_window.h"
-#include "slide_window.h"
-#include "stylesheet.h"
-
-struct menu_pl;
-
-struct presentation
-{
- GFile *file;
- GFile *stylesheet_from;
- int completely_empty;
- int saved;
- PangoLanguage *lang;
-
- ImageStore *is;
-
- NarrativeWindow *narrative_window;
-
- struct pr_clock *clock;
-
- /* This is the "native" size of the slide. It only exists to give
- * font size some meaning in the context of a somewhat arbitrary DPI */
- double slide_width;
- double slide_height;
-
- SCBlock *scblocks;
- Stylesheet *stylesheet;
-};
-
-
-extern struct presentation *new_presentation(const char *imagestore);
-extern void free_presentation(struct presentation *p);
-
-extern char *get_titlebar_string(struct presentation *p);
-
-extern int slide_number(struct presentation *p, SCBlock *sl);
-extern int num_slides(struct presentation *p);
-extern SCBlock *first_slide(struct presentation *p);
-extern SCBlock *last_slide(struct presentation *p);
-extern SCBlock *next_slide(struct presentation *p, SCBlock *sl);
-extern SCBlock *prev_slide(struct presentation *p, SCBlock *sl);
-
-extern int load_presentation(struct presentation *p, GFile *file);
-extern int save_presentation(struct presentation *p, GFile *file, GFile *ssfile);
-
-#define UNUSED __attribute__((unused))
-
-
-#endif /* PRESENTATION_H */
diff --git a/src-old/render.c b/src-old/render.c
deleted file mode 100644
index 6ac09fc..0000000
--- a/src-old/render.c
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * render.c
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <cairo.h>
-#include <cairo-pdf.h>
-#include <pango/pangocairo.h>
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <gdk/gdk.h>
-
-#include "sc_parse.h"
-#include "sc_interp.h"
-#include "presentation.h"
-#include "frame.h"
-#include "render.h"
-#include "imagestore.h"
-#include "utils.h"
-
-
-static void do_background(cairo_t *cr, struct frame *fr)
-{
- cairo_pattern_t *patt = NULL;
-
- cairo_new_path(cr);
- cairo_rectangle(cr, 0.0, 0.0, fr->w, fr->h);
-
- switch ( fr->grad ) {
-
- case GRAD_NONE:
- cairo_set_source_rgba(cr, fr->bgcol[0],
- fr->bgcol[1],
- fr->bgcol[2],
- fr->bgcol[3]);
- break;
-
- case GRAD_VERT:
- patt = cairo_pattern_create_linear(0.0, 0.0,
- 0.0, fr->h);
- cairo_pattern_add_color_stop_rgba(patt, 0.0, fr->bgcol[0],
- fr->bgcol[1],
- fr->bgcol[2],
- fr->bgcol[3]);
- cairo_pattern_add_color_stop_rgba(patt, 1.0, fr->bgcol2[0],
- fr->bgcol2[1],
- fr->bgcol2[2],
- fr->bgcol2[3]);
- cairo_set_source(cr, patt);
- break;
-
- case GRAD_HORIZ:
- patt = cairo_pattern_create_linear(0.0, 0.0,
- fr->w, 0.0);
- cairo_pattern_add_color_stop_rgba(patt, 0.0, fr->bgcol[0],
- fr->bgcol[1],
- fr->bgcol[2],
- fr->bgcol[3]);
- cairo_pattern_add_color_stop_rgba(patt, 1.0, fr->bgcol2[0],
- fr->bgcol2[1],
- fr->bgcol2[2],
- fr->bgcol2[3]);
- cairo_set_source(cr, patt);
- break;
-
- }
-
- cairo_fill(cr);
- if ( patt != NULL ) cairo_pattern_destroy(patt);
-}
-
-
-static int draw_frame(cairo_t *cr, struct frame *fr, ImageStore *is,
- double min_y, double max_y)
-{
- int i;
- double hpos = 0.0;
-
- cairo_save(cr);
- do_background(cr, fr);
-
- /* Actually render the contents */
- cairo_translate(cr, fr->pad_l, fr->pad_t);
- for ( i=0; i<fr->n_paras; i++ ) {
-
- double cur_h = paragraph_height(fr->paras[i]);
-
- cairo_save(cr);
- cairo_translate(cr, 0.0, hpos);
-
- if ( (hpos + cur_h > min_y) && (hpos < max_y) ) {
- render_paragraph(cr, fr->paras[i], is);
- } /* else paragraph is not visible */
-
- hpos += cur_h;
- cairo_restore(cr);
-
- }
- cairo_restore(cr);
-
- return 0;
-}
-
-
-int recursive_draw(struct frame *fr, cairo_t *cr,
- ImageStore *is,
- double min_y, double max_y)
-{
- int i;
-
- draw_frame(cr, fr, is, min_y, max_y);
-
- for ( i=0; i<fr->num_children; i++ ) {
- cairo_save(cr);
- cairo_translate(cr, fr->children[i]->x, fr->children[i]->y);
- recursive_draw(fr->children[i], cr, is,
- min_y - fr->children[i]->y,
- max_y - fr->children[i]->y);
- cairo_restore(cr);
- }
-
- return 0;
-}
-
-
-void wrap_frame(struct frame *fr, PangoContext *pc)
-{
- int i;
- double w;
-
- w = fr->w - fr->pad_l - fr->pad_r;
-
- for ( i=0; i<fr->n_paras; i++ ) {
- wrap_paragraph(fr->paras[i], pc, w, 0, 0);
- }
-}
-
-
-int recursive_wrap(struct frame *fr, PangoContext *pc)
-{
- int i;
-
- wrap_frame(fr, pc);
-
- for ( i=0; i<fr->num_children; i++ ) {
- recursive_wrap(fr->children[i], pc);
- }
-
- return 0;
-}
-
-
-struct frame *interp_and_shape(SCBlock *scblocks, Stylesheet *stylesheet,
- SCCallbackList *cbl, ImageStore *is,
- int slide_number,
- PangoContext *pc, double w, double h,
- PangoLanguage *lang)
-{
- SCInterpreter *scin;
- char snum[64];
- struct frame *top;
-
- top = frame_new();
- top->resizable = 0;
- top->x = 0.0;
- top->y = 0.0;
- top->w = w;
- top->h = h;
- top->scblocks = scblocks;
-
- scin = sc_interp_new(pc, lang, is, top);
- if ( scin == NULL ) {
- fprintf(stderr, "Failed to set up interpreter.\n");
- frame_free(top);
- return NULL;
- }
-
- sc_interp_set_callbacks(scin, cbl);
-
- snprintf(snum, 63, "%i", slide_number);
- sc_interp_set_constant(scin, SCCONST_SLIDENUMBER, snum);
-
- top->fontdesc = pango_font_description_copy(sc_interp_get_fontdesc(scin));
- top->col[0] = sc_interp_get_fgcol(scin)[0];
- top->col[1] = sc_interp_get_fgcol(scin)[1];
- top->col[2] = sc_interp_get_fgcol(scin)[2];
- top->col[3] = sc_interp_get_fgcol(scin)[3];
-
- sc_interp_add_block(scin, scblocks, stylesheet);
-
- sc_interp_destroy(scin);
-
- return top;
-}
-
-
-static struct frame *render_sc_with_context(SCBlock *scblocks,
- cairo_t *cr, double log_w, double log_h,
- Stylesheet *stylesheet, SCCallbackList *cbl,
- ImageStore *is,
- int slide_number, PangoLanguage *lang,
- PangoContext *pc)
-{
- struct frame *top;
-
- cairo_rectangle(cr, 0.0, 0.0, log_w, log_h);
- cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
- cairo_fill(cr);
-
- top = interp_and_shape(scblocks, stylesheet, cbl, is,
- slide_number, pc, log_w, log_h, lang);
-
- recursive_wrap(top, pc);
-
- recursive_draw(top, cr, is, 0.0, log_h);
-
- return top;
-}
-
-
-cairo_surface_t *render_sc(SCBlock *scblocks, int w, int h,
- double log_w, double log_h,
- Stylesheet *stylesheet, SCCallbackList *cbl,
- ImageStore *is,
- int slide_number, struct frame **ptop,
- PangoLanguage *lang)
-{
- cairo_surface_t *surf;
- cairo_t *cr;
- struct frame *top;
- PangoContext *pc;
-
- surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
- cr = cairo_create(surf);
- pc = pango_cairo_create_context(cr);
- cairo_scale(cr, w/log_w, h/log_h);
- top = render_sc_with_context(scblocks, cr, log_w, log_h,
- stylesheet, cbl, is, slide_number,
- lang, pc);
- g_object_unref(pc);
- cairo_destroy(cr);
-
- *ptop = top;
-
- return surf;
-}
-
-
-int export_pdf(struct presentation *p, const char *filename)
-{
- double r;
- double w = 2048.0;
- double scale;
- cairo_surface_t *surf;
- cairo_t *cr;
- SCBlock *bl;
- int i;
- PangoContext *pc;
-
- r = p->slide_height / p->slide_width;
-
- surf = cairo_pdf_surface_create(filename, w, w*r);
- if ( cairo_surface_status(surf) != CAIRO_STATUS_SUCCESS ) {
- fprintf(stderr, _("Couldn't create Cairo surface\n"));
- return 1;
- }
-
- cr = cairo_create(surf);
- scale = w / p->slide_width;
- pc = pango_cairo_create_context(cr);
-
- i = 1;
- bl = p->scblocks;
- while ( bl != NULL ) {
-
- if ( safe_strcmp(sc_block_name(bl), "slide") != 0 ) {
- bl = sc_block_next(bl);
- continue;
- }
-
- cairo_save(cr);
-
- cairo_scale(cr, scale, scale);
-
- cairo_rectangle(cr, 0.0, 0.0, p->slide_width, p->slide_height);
- cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
- cairo_fill(cr);
-
- render_sc_with_context(bl, cr, p->slide_width,
- p->slide_height, p->stylesheet, NULL,
- p->is, i, p->lang, pc);
-
- cairo_restore(cr);
-
- cairo_show_page(cr);
-
- bl = sc_block_next(bl);
- i++;
-
- }
-
- g_object_unref(pc);
- cairo_surface_finish(surf);
- cairo_destroy(cr);
-
- return 0;
-}
diff --git a/src-old/render.h b/src-old/render.h
deleted file mode 100644
index 0cfae26..0000000
--- a/src-old/render.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * render.h
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef RENDER_H
-#define RENDER_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "presentation.h"
-#include "imagestore.h"
-#include "sc_interp.h"
-#include "frame.h"
-
-/* Convienience function to run the entire pipeline */
-extern cairo_surface_t *render_sc(SCBlock *scblocks, int w, int h,
- double log_w, double log_h,
- Stylesheet *stylesheet, SCCallbackList *cbl,
- ImageStore *is,
- int slide_number, struct frame **ptop,
- PangoLanguage *lang);
-
-/* Interpret StoryCode and measure boxes.
- * Needs to be followed by: wrap_contents() (recursively)
- * recursive_draw()
- */
-extern struct frame *interp_and_shape(SCBlock *scblocks, Stylesheet *stylesheet,
- SCCallbackList *cbl,
- ImageStore *is,
- int slide_number, PangoContext *pc,
- double w, double h, PangoLanguage *lang);
-
-extern void wrap_frame(struct frame *fr, PangoContext *pc);
-extern int recursive_wrap(struct frame *fr, PangoContext *pc);
-
-extern int export_pdf(struct presentation *p, const char *filename);
-
-extern int recursive_draw(struct frame *fr, cairo_t *cr,
- ImageStore *is,
- double min_y, double max_y);
-
-#endif /* RENDER_H */
diff --git a/src-old/sc_editor.c b/src-old/sc_editor.c
deleted file mode 100644
index 8e79fd8..0000000
--- a/src-old/sc_editor.c
+++ /dev/null
@@ -1,2197 +0,0 @@
-/*
- * sc_editor.c
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <gtk/gtk.h>
-#include <assert.h>
-#include <gdk/gdkkeysyms.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <math.h>
-
-#include "colloquium.h"
-#include "presentation.h"
-#include "slide_window.h"
-#include "render.h"
-#include "frame.h"
-#include "sc_parse.h"
-#include "sc_interp.h"
-#include "sc_editor.h"
-#include "slideshow.h"
-#include "debugger.h"
-#include "utils.h"
-
-
-static void scroll_interface_init(GtkScrollable *iface)
-{
-}
-
-
-enum
-{
- SCEDITOR_0,
- SCEDITOR_VADJ,
- SCEDITOR_HADJ,
- SCEDITOR_VPOL,
- SCEDITOR_HPOL,
-};
-
-
-G_DEFINE_TYPE_WITH_CODE(SCEditor, sc_editor, GTK_TYPE_DRAWING_AREA,
- G_IMPLEMENT_INTERFACE(GTK_TYPE_SCROLLABLE,
- scroll_interface_init))
-
-static void debug_paragraphs(SCEditor *e)
-{
- struct frame *fr = e->cursor_frame;
- int i;
-
- printf("Paragraphs in current frame:\n");
- for ( i=0; i<fr->n_paras; i++ ) {
- show_para(fr->paras[i]);
- }
-}
-
-
-static void horizontal_adjust(GtkAdjustment *adj, SCEditor *e)
-{
- e->h_scroll_pos = gtk_adjustment_get_value(adj);
- sc_editor_redraw(e);
-}
-
-
-static void set_horizontal_params(SCEditor *e)
-{
- if ( e->hadj == NULL ) return;
- gtk_adjustment_configure(e->hadj, e->h_scroll_pos, 0, e->w, 100,
- e->visible_width, e->visible_width);
-}
-
-
-static void vertical_adjust(GtkAdjustment *adj, SCEditor *e)
-{
- e->scroll_pos = gtk_adjustment_get_value(adj);
- sc_editor_redraw(e);
-}
-
-
-static void set_vertical_params(SCEditor *e)
-{
- double page;
-
- if ( e->vadj == NULL ) return;
-
- /* Ensure we do not scroll off the top of the document */
- if ( e->scroll_pos < 0.0 ) e->scroll_pos = 0.0;
-
- /* Ensure we do not scroll off the bottom of the document */
- if ( e->scroll_pos > e->h - e->visible_height ) {
- e->scroll_pos = e->h - e->visible_height;
- }
-
- /* If we can show the whole document, show it at the top */
- if ( e->h < e->visible_height ) {
- e->scroll_pos = 0.0;
- }
-
- if ( e->h > e->visible_height ) {
- page = e->visible_height;
- } else {
- page = e->h;
- }
-
- gtk_adjustment_configure(e->vadj, e->scroll_pos, 0, e->h, 100,
- e->visible_height, page);
-}
-
-
-static void update_size(SCEditor *e)
-{
- if ( e->flow ) {
-
- double total = total_height(e->top);
-
- e->w = e->top->w;
- e->h = total + e->top->pad_t + e->top->pad_b;
-
- e->log_w = e->w;
- e->log_h = e->h;
- e->top->h = e->h;
- } else {
- e->top->w = e->log_w;
- e->top->h = e->log_h;
- }
-
- if ( e->flow && (e->top->h < e->visible_height) ) {
- e->top->h = e->visible_height;
- }
-
- set_vertical_params(e);
- set_horizontal_params(e);
-}
-
-
-static gboolean resize_sig(GtkWidget *widget, GdkEventConfigure *event,
- SCEditor *e)
-{
- PangoContext *pc;
-
- pc = gdk_pango_context_get();
-
- if ( e->scale ) {
-
- double sx, sy;
- double aw, ah;
-
- e->w = event->width;
- e->h = event->height;
- sx = (double)e->w / e->log_w;
- sy = (double)e->h / e->log_h;
- e->view_scale = (sx < sy) ? sx : sy;
-
- /* Actual size (in device units) */
- aw = e->view_scale * e->log_w;
- ah = e->view_scale * e->log_h;
-
- e->border_offs_x = (event->width - aw)/2.0;
- e->border_offs_y = (event->height - ah)/2.0;
-
- }
-
- e->visible_height = event->height;
- e->visible_width = event->width;
-
- /* Interpret and shape, if not already done */
- if ( e->top == NULL ) {
- double w, h;
- if ( e->flow ) {
- w = event->width;
- h = 0.0;
- } else {
- w = e->log_w;
- h = e->log_h;
- }
- e->top = interp_and_shape(e->scblocks, e->stylesheet, e->cbl,
- e->is, e->slidenum, pc,
- w, h, e->lang);
- e->top->scblocks = e->scblocks;
- recursive_wrap(e->top, pc);
- }
-
- if ( e->flow ) {
- /* Wrap using current width */
- e->top->w = event->width;
- e->top->h = 0.0; /* To be updated in a moment */
- e->top->x = 0.0;
- e->top->y = 0.0;
- /* Only the top level needs to be wrapped */
- wrap_frame(e->top, pc);
- }
-
- update_size(e);
-
- g_object_unref(pc);
-
- return FALSE;
-}
-
-
-static void emit_change_sig(SCEditor *e)
-{
- g_signal_emit_by_name(e, "changed");
-}
-
-
-void sc_editor_set_flow(SCEditor *e, int flow)
-{
- e->flow = flow;
-}
-
-
-static void sc_editor_set_property(GObject *obj, guint id, const GValue *val,
- GParamSpec *spec)
-{
- SCEditor *e = SC_EDITOR(obj);
-
- switch ( id ) {
-
- case SCEDITOR_VPOL :
- e->vpol = g_value_get_enum(val);
- break;
-
- case SCEDITOR_HPOL :
- e->hpol = g_value_get_enum(val);
- break;
-
- case SCEDITOR_VADJ :
- e->vadj = g_value_get_object(val);
- set_vertical_params(e);
- if ( e->vadj != NULL ) {
- g_signal_connect(G_OBJECT(e->vadj), "value-changed",
- G_CALLBACK(vertical_adjust), e);
- }
- break;
-
- case SCEDITOR_HADJ :
- e->hadj = g_value_get_object(val);
- set_horizontal_params(e);
- if ( e->hadj != NULL ) {
- g_signal_connect(G_OBJECT(e->hadj), "value-changed",
- G_CALLBACK(horizontal_adjust), e);
- }
- break;
-
- default :
- printf("setting %i\n", id);
- break;
-
- }
-}
-
-
-static void sc_editor_get_property(GObject *obj, guint id, GValue *val,
- GParamSpec *spec)
-{
- SCEditor *e = SC_EDITOR(obj);
-
- switch ( id ) {
-
- case SCEDITOR_VADJ :
- g_value_set_object(val, e->vadj);
- break;
-
- case SCEDITOR_HADJ :
- g_value_set_object(val, e->hadj);
- break;
-
- case SCEDITOR_VPOL :
- g_value_set_enum(val, e->vpol);
- break;
-
- case SCEDITOR_HPOL :
- g_value_set_enum(val, e->hpol);
- break;
-
- default :
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, spec);
- break;
-
- }
-}
-
-
-static GtkSizeRequestMode get_request_mode(GtkWidget *widget)
-{
- return GTK_SIZE_REQUEST_CONSTANT_SIZE;
-}
-
-
-static void get_preferred_width(GtkWidget *widget, gint *min, gint *natural)
-{
- SCEditor *e = SC_EDITOR(widget);
- if ( e->flow ) {
- *min = 100;
- *natural = 640;
- } else {
- *min = e->w;
- *natural = e->w;
- }
-}
-
-
-static void get_preferred_height(GtkWidget *widget, gint *min, gint *natural)
-{
- SCEditor *e = SC_EDITOR(widget);
- if ( e->flow ) {
- *min = 1000;
- *natural = 1000;
- } else {
- *min = e->h;
- *natural = e->h;
- }
-}
-
-
-static void sc_editor_class_init(SCEditorClass *klass)
-{
- GObjectClass *goc = G_OBJECT_CLASS(klass);
- goc->set_property = sc_editor_set_property;
- goc->get_property = sc_editor_get_property;
- g_object_class_override_property(goc, SCEDITOR_VADJ, "vadjustment");
- g_object_class_override_property(goc, SCEDITOR_HADJ, "hadjustment");
- g_object_class_override_property(goc, SCEDITOR_VPOL, "vscroll-policy");
- g_object_class_override_property(goc, SCEDITOR_HPOL, "hscroll-policy");
-
- GTK_WIDGET_CLASS(klass)->get_request_mode = get_request_mode;
- GTK_WIDGET_CLASS(klass)->get_preferred_width = get_preferred_width;
- GTK_WIDGET_CLASS(klass)->get_preferred_height = get_preferred_height;
- GTK_WIDGET_CLASS(klass)->get_preferred_height_for_width = NULL;
-
- g_signal_new("changed", SC_TYPE_EDITOR, G_SIGNAL_RUN_LAST, 0,
- NULL, NULL, NULL, G_TYPE_NONE, 0);
-}
-
-
-static void sc_editor_init(SCEditor *e)
-{
- e->vpol = GTK_SCROLL_NATURAL;
- e->hpol = GTK_SCROLL_NATURAL;
- e->vadj = gtk_adjustment_new(0, 0, 100, 1, 10, 10);
- e->hadj = gtk_adjustment_new(0, 0, 100, 1, 10, 10);
-}
-
-
-void sc_editor_set_background(SCEditor *e, double r, double g, double b)
-{
- e->bgcol[0] = r;
- e->bgcol[1] = g;
- e->bgcol[2] = b;
-}
-
-
-void sc_editor_ensure_cursor(SCEditor *e)
-{
- if ( e->cursor_frame != NULL ) return;
- e->cursor_frame = e->top;
- e->cpos.para = 0;
- e->cpos.pos = 0;
- e->cpos.trail = 0;
- e->selection = NULL;
-}
-
-
-static void sc_editor_remove_cursor(SCEditor *e)
-{
- e->cursor_frame = NULL;
- e->cpos.para = 0;
- e->cpos.pos = 0;
- e->cpos.trail = 0;
- e->selection = NULL;
-}
-
-
-/* (Re-)run the entire rendering pipeline.
- * NB "full" means "full". All frame, line and box handles will become
- * invalid. The cursor position will be unset. */
-static void full_rerender(SCEditor *e)
-{
- PangoContext *pc;
-
- frame_free(e->top);
- sc_editor_remove_cursor(e);
-
- pc = gdk_pango_context_get();
-
- e->top = interp_and_shape(e->scblocks, e->stylesheet, e->cbl,
- e->is, e->slidenum,
- pc, e->log_w, 0.0, e->lang);
-
- e->top->x = 0.0;
- e->top->y = 0.0;
- e->top->w = e->w;
- e->top->h = 0.0; /* To be updated in a moment */
-
- recursive_wrap(e->top, pc);
- update_size(e);
-
- sc_editor_redraw(e);
-
- g_object_unref(pc);
-}
-
-
-void sc_editor_redraw(SCEditor *e)
-{
- gint w, h;
-
- w = gtk_widget_get_allocated_width(GTK_WIDGET(e));
- h = gtk_widget_get_allocated_height(GTK_WIDGET(e));
-
- gtk_widget_queue_draw_area(GTK_WIDGET(e), 0, 0, w, h);
-}
-
-
-static void paste_storycode_received(GtkClipboard *cb, GtkSelectionData *seldata,
- gpointer vp)
-{
- SCEditor *e = vp;
- SCBlock *nf;
- const guchar *t;
-
- t = gtk_selection_data_get_data(seldata);
-
- printf("received storycode paste\n");
- printf("'%s'\n", t);
- if ( t == NULL ) return;
-
- /* FIXME: It might not be a new frame */
- nf = sc_parse((char *)t);
- show_sc_blocks(nf);
- sc_block_append_block(sc_block_child(e->scblocks), nf);
- full_rerender(e);
-}
-
-
-static void paste_text_received(GtkClipboard *cb, GtkSelectionData *seldata,
- gpointer vp)
-{
- SCEditor *e = vp;
- SCBlock *bl;
- guchar *t;
- SCBlock *cur_bl;
- size_t cur_sc_pos;
- size_t offs;
- Paragraph *para;
-
- t = gtk_selection_data_get_text(seldata);
-
- printf("received text paste\n");
- printf("'%s'\n", t);
- if ( t == NULL ) return;
-
- bl = sc_parse((char *)t);
-
- if ( e->cursor_frame == NULL ) {
- fprintf(stderr, _("No frame selected for paste\n"));
- return;
- }
-
- para = e->cursor_frame->paras[e->cpos.para];
- offs = pos_trail_to_offset(para, e->cpos.pos, e->cpos.trail);
-
- get_sc_pos(e->cursor_frame, e->cpos.para, offs, &cur_bl, &cur_sc_pos);
- sc_insert_block(cur_bl, cur_sc_pos, bl);
- full_rerender(e);
-}
-
-
-static void paste_targets_received(GtkClipboard *cb, GdkAtom *targets,
- gint n_targets, gpointer vp)
-{
- SCEditor *e = vp;
- int i;
- int have_sc = 0;
- int index_sc, index_text;
- int have_text = 0;
-
- if ( targets == NULL ) {
- fprintf(stderr, "No paste targets offered.\n");
- return;
- }
-
- for ( i=0; i<n_targets; i++ ) {
- gchar *name = gdk_atom_name(targets[i]);
- if ( g_strcmp0(name, "text/x-storycode") == 0 ) {
- have_sc = 1;
- index_sc = i;
- }
- if ( g_strcmp0(name, "text/plain") == 0 ) {
- have_text = 1;
- index_text = i;
- }
- g_free(name);
- }
-
- if ( have_sc ) {
- printf("storycode is offered\n");
- gtk_clipboard_request_contents(cb, targets[index_sc],
- paste_storycode_received, e);
- } else if ( have_text ) {
- printf("text is offered\n");
- gtk_clipboard_request_contents(cb, targets[index_text],
- paste_text_received, e);
- } else {
- printf("nothing useful is offered\n");
- }
-}
-
-
-void sc_editor_paste(SCEditor *e)
-{
- GtkClipboard *cb;
- GdkAtom atom;
-
- printf("pasting\n");
-
- atom = gdk_atom_intern("CLIPBOARD", FALSE);
- if ( atom == GDK_NONE ) return;
- cb = gtk_clipboard_get(atom);
- gtk_clipboard_request_targets(cb, paste_targets_received, e);
-}
-
-
-void sc_editor_add_storycode(SCEditor *e, const char *sc)
-{
- SCBlock *nf;
- nf = sc_parse(sc);
- sc_block_append_block(sc_block_child(e->scblocks), nf);
- full_rerender(e);
-}
-
-
-static void clipboard_get(GtkClipboard *cb, GtkSelectionData *seldata,
- guint info, gpointer data)
-{
- char *t = data;
-
- printf("clipboard get\n");
-
- if ( info == 0 ) {
- printf("sending SC frame\n");
- gtk_selection_data_set(seldata,
- gtk_selection_data_get_target(seldata),
- 8, (const guchar *)t, strlen(t)+1);
- } else {
- GdkAtom target;
- gchar *name;
- target = gtk_selection_data_get_target(seldata);
- name = gdk_atom_name(target);
- fprintf(stderr, "Don't know what to send for %s\n", name);
- g_free(name);
- }
-}
-
-
-static void clipboard_clear(GtkClipboard *cb, gpointer data)
-{
- free(data);
-}
-
-
-void sc_editor_copy_selected_frame(SCEditor *e)
-{
- char *t;
- GtkClipboard *cb;
- GdkAtom atom;
- GtkTargetEntry targets[1];
-
- if ( e->selection == NULL ) return;
-
- atom = gdk_atom_intern("CLIPBOARD", FALSE);
- if ( atom == GDK_NONE ) return;
-
- cb = gtk_clipboard_get(atom);
-
- targets[0].target = "text/x-storycode";
- targets[0].flags = 0;
- targets[0].info = 0;
-
- /* FIXME: Offer image, PDF etc? */
-
- printf("copying frame\n");
-
- t = serialise_sc_block(e->selection->scblocks);
-
- gtk_clipboard_set_with_data(cb, targets, 1,
- clipboard_get, clipboard_clear, t);
-}
-
-
-static void copy_selection(SCEditor *e)
-{
- char *t;
- GtkClipboard *cb;
- GdkAtom atom;
- GtkTargetEntry targets[1];
- SCBlock *bl;
-
- if ( e->selection == NULL ) return;
-
- atom = gdk_atom_intern("CLIPBOARD", FALSE);
- if ( atom == GDK_NONE ) return;
-
- cb = gtk_clipboard_get(atom);
-
-
- targets[0].target = "text/x-storycode";
- targets[0].flags = 0;
- targets[0].info = 0;
-
- printf("copying selection\n");
-
- bl = block_at_cursor(e->cursor_frame, e->cpos.para, 0);
- if ( bl == NULL ) return;
-
- t = serialise_sc_block(bl);
-
- gtk_clipboard_set_with_data(cb, targets, 1,
- clipboard_get, clipboard_clear, t);
-}
-
-
-void sc_editor_delete_selected_frame(SCEditor *e)
-{
- SCBlock *scb_old = e->scblocks;
- sc_block_delete(&e->scblocks, e->selection->scblocks);
- assert(scb_old == e->scblocks);
- full_rerender(e);
- emit_change_sig(e);
-}
-
-
-static gint destroy_sig(GtkWidget *window, SCEditor *e)
-{
- return 0;
-}
-
-
-static void draw_editing_box(cairo_t *cr, struct frame *fr)
-{
- const double dash[] = {2.0, 2.0};
- double xmin, ymin, width, height;
- double ptot_w, ptot_h;
-
- xmin = fr->x;
- ymin = fr->y;
- width = fr->w;
- height = fr->h;
-
- cairo_new_path(cr);
- cairo_rectangle(cr, xmin, ymin, width, height);
- cairo_set_source_rgb(cr, 0.0, 0.69, 1.0);
- cairo_set_line_width(cr, 0.5);
- cairo_stroke(cr);
-
- cairo_new_path(cr);
- ptot_w = fr->pad_l + fr->pad_r;
- ptot_h = fr->pad_t + fr->pad_b;
- cairo_rectangle(cr, xmin+fr->pad_l, ymin+fr->pad_t,
- width-ptot_w, height-ptot_h);
- cairo_set_dash(cr, dash, 2, 0.0);
- cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
- cairo_set_line_width(cr, 0.1);
- cairo_stroke(cr);
-
- cairo_set_dash(cr, NULL, 0, 0.0);
-}
-
-
-static void draw_para_highlight(cairo_t *cr, struct frame *fr, int cursor_para)
-{
- double cx, cy, w, h;
-
- if ( get_para_highlight(fr, cursor_para, &cx, &cy, &w, &h) != 0 ) {
- return;
- }
-
- cairo_new_path(cr);
- cairo_rectangle(cr, cx+fr->x, cy+fr->y, w, h);
- cairo_set_source_rgba(cr, 0.7, 0.7, 1.0, 0.5);
- cairo_set_line_width(cr, 5.0);
- cairo_stroke(cr);
-}
-
-
-static void draw_caret(cairo_t *cr, struct frame *fr, struct edit_pos cpos,
- int hgh)
-{
- double cx, clow, chigh, h;
- const double t = 1.8;
- size_t offs;
- Paragraph *para;
-
- if ( hgh ) {
- draw_para_highlight(cr, fr, cpos.para);
- return;
- }
-
- assert(fr != NULL);
-
- para = fr->paras[cpos.para];
- if ( para_type(para) != PARA_TYPE_TEXT ) {
- draw_para_highlight(cr, fr, cpos.para);
- return;
- }
-
- offs = pos_trail_to_offset(para, cpos.pos, cpos.trail);
- get_cursor_pos(fr, cpos.para, offs, &cx, &clow, &h);
-
- cx += fr->x;
- clow += fr->y;
- chigh = clow + h;
-
- cairo_move_to(cr, cx, clow);
- cairo_line_to(cr, cx, chigh);
-
- cairo_move_to(cr, cx-t, clow-t);
- cairo_line_to(cr, cx, clow);
- cairo_move_to(cr, cx+t, clow-t);
- cairo_line_to(cr, cx, clow);
-
- cairo_move_to(cr, cx-t, chigh+t);
- cairo_line_to(cr, cx, chigh);
- cairo_move_to(cr, cx+t, chigh+t);
- cairo_line_to(cr, cx, chigh);
-
- cairo_set_source_rgb(cr, 0.86, 0.0, 0.0);
- cairo_set_line_width(cr, 1.0);
- cairo_stroke(cr);
-}
-
-
-static void draw_resize_handle(cairo_t *cr, double x, double y)
-{
- cairo_new_path(cr);
- cairo_rectangle(cr, x, y, 20.0, 20.0);
- cairo_set_source_rgba(cr, 0.9, 0.9, 0.9, 0.5);
- cairo_fill(cr);
-}
-
-
-static void draw_overlay(cairo_t *cr, SCEditor *e)
-{
- if ( e->selection != NULL ) {
-
- double x, y, w, h;
-
- draw_editing_box(cr, e->selection);
-
- x = e->selection->x;
- y = e->selection->y;
- w = e->selection->w;
- h = e->selection->h;
-
- if ( e->selection->resizable ) {
- /* Draw resize handles */
- draw_resize_handle(cr, x, y+h-20.0);
- draw_resize_handle(cr, x+w-20.0, y);
- draw_resize_handle(cr, x, y);
- draw_resize_handle(cr, x+w-20.0, y+h-20.0);
- }
-
- draw_caret(cr, e->cursor_frame, e->cpos, e->para_highlight);
-
- }
-
- if ( (e->drag_status == DRAG_STATUS_DRAGGING)
- && ((e->drag_reason == DRAG_REASON_CREATE)
- || (e->drag_reason == DRAG_REASON_IMPORT)) )
- {
- cairo_new_path(cr);
- cairo_rectangle(cr, e->start_corner_x, e->start_corner_y,
- e->drag_corner_x - e->start_corner_x,
- e->drag_corner_y - e->start_corner_y);
- cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
- cairo_set_line_width(cr, 0.5);
- cairo_stroke(cr);
- }
-
- if ( (e->drag_status == DRAG_STATUS_DRAGGING)
- && ((e->drag_reason == DRAG_REASON_RESIZE)
- || (e->drag_reason == DRAG_REASON_MOVE)) )
- {
- cairo_new_path(cr);
- cairo_rectangle(cr, e->box_x, e->box_y,
- e->box_width, e->box_height);
- cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
- cairo_set_line_width(cr, 0.5);
- cairo_stroke(cr);
- }
-}
-
-
-static gboolean draw_sig(GtkWidget *da, cairo_t *cr, SCEditor *e)
-{
- /* Ultimate background */
- if ( e->bg_pixbuf != NULL ) {
- gdk_cairo_set_source_pixbuf(cr, e->bg_pixbuf, 0.0, 0.0);
- cairo_pattern_t *patt = cairo_get_source(cr);
- cairo_pattern_set_extend(patt, CAIRO_EXTEND_REPEAT);
- cairo_paint(cr);
- } else {
- cairo_set_source_rgba(cr, 0.8, 0.8, 1.0, 1.0);
- cairo_paint(cr);
- }
-
- cairo_translate(cr, e->border_offs_x, e->border_offs_y);
- cairo_translate(cr, -e->h_scroll_pos, -e->scroll_pos);
- cairo_scale(cr, e->view_scale, e->view_scale);
-
- /* Rendering background */
- cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
- cairo_rectangle(cr, 0.0, 0.0, e->log_w, e->log_h);
- cairo_fill(cr);
-
- /* Contents */
- recursive_draw(e->top, cr, e->is,
- e->scroll_pos/e->view_scale,
- (e->scroll_pos + e->visible_height)/e->view_scale);
-
- /* Editing overlay */
- draw_overlay(cr, e);
-
- return FALSE;
-}
-
-
-SCBlock *split_paragraph_at_cursor(SCEditor *e)
-{
- size_t offs;
- Paragraph *para;
-
- if ( e->cursor_frame == NULL ) return NULL;
-
- para = e->cursor_frame->paras[e->cpos.para];
- offs = pos_trail_to_offset(para, e->cpos.pos, e->cpos.trail);
- return split_paragraph(e->cursor_frame, e->cpos.para, offs, e->pc);
-}
-
-
-static void check_cursor_visible(SCEditor *e)
-{
- double x, y, h;
- size_t offs;
- Paragraph *para;
-
- if ( e->cursor_frame == NULL ) return;
-
- para = e->cursor_frame->paras[e->cpos.para];
- offs = pos_trail_to_offset(para, e->cpos.pos, e->cpos.trail);
- get_cursor_pos(e->cursor_frame, e->cpos.para, offs, &x, &y, &h);
-
- /* Off the bottom? */
- if ( y - e->scroll_pos + h > e->visible_height ) {
- e->scroll_pos = y + h - e->visible_height;
- e->scroll_pos += e->cursor_frame->pad_b;
- }
-
- /* Off the top? */
- if ( y < e->scroll_pos ) {
- e->scroll_pos = y - e->cursor_frame->pad_t;
- }
-}
-
-
-static void do_backspace(struct frame *fr, SCEditor *e)
-{
- double wrapw = e->cursor_frame->w - e->cursor_frame->pad_l - e->cursor_frame->pad_r;
-
- if ( e->sel_active ) {
-
- /* Delete the selected block */
- delete_text_from_frame(e->cursor_frame, e->sel_start, e->sel_end, wrapw);
-
- /* Cursor goes at start of deletion */
- sort_positions(&e->sel_start, &e->sel_end);
- e->cpos = e->sel_start;
- e->sel_active = 0;
-
- } else {
-
- if ( para_type(e->cursor_frame->paras[e->cpos.para]) == PARA_TYPE_TEXT ) {
-
- /* Delete one character */
- struct edit_pos p1, p2;
-
- p1 = e->cpos;
-
- p2 = p1;
-
- cursor_moveh(e->cursor_frame, &p2, -1);
- show_edit_pos(p1);
- show_edit_pos(p2);
-
- delete_text_from_frame(e->cursor_frame, p1, p2, wrapw);
- e->cpos = p2;
-
- } else {
-
- /* FIXME: Implement this */
- fprintf(stderr, "Deleting non-text paragraph\n");
-
- }
-
- }
-
- emit_change_sig(e);
- sc_editor_redraw(e);
-}
-
-
-static void insert_text(char *t, SCEditor *e)
-{
- Paragraph *para;
-
- if ( e->cursor_frame == NULL ) return;
-
- if ( e->sel_active ) {
- do_backspace(e->cursor_frame, e);
- }
-
- if ( strcmp(t, "\n") == 0 ) {
- split_paragraph_at_cursor(e);
- if ( e->flow ) update_size(e);
- cursor_moveh(e->cursor_frame, &e->cpos, +1);
- check_cursor_visible(e);
- emit_change_sig(e);
- sc_editor_redraw(e);
- return;
- }
-
- para = e->cursor_frame->paras[e->cpos.para];
-
- /* Is this paragraph even a text one? */
- if ( para_type(para) == PARA_TYPE_TEXT ) {
-
- size_t off;
-
- /* Yes. The "easy" case */
-
- if ( !position_editable(e->cursor_frame, e->cpos) ) {
- fprintf(stderr, "Position not editable\n");
- return;
- }
-
- off = pos_trail_to_offset(para, e->cpos.pos, e->cpos.trail);
- insert_text_in_paragraph(para, off, t);
- wrap_paragraph(para, NULL,
- e->cursor_frame->w - e->cursor_frame->pad_l
- - e->cursor_frame->pad_r, 0, 0);
- if ( e->flow ) update_size(e);
-
- cursor_moveh(e->cursor_frame, &e->cpos, +1);
-
- } else {
-
- SCBlock *bd;
- SCBlock *ad;
- Paragraph *pnew;
-
- bd = para_scblock(para);
- if ( bd == NULL ) {
- fprintf(stderr, "No SCBlock for para\n");
- return;
- }
-
- /* No. Create a new text paragraph straight afterwards */
- ad = sc_block_insert_after(bd, NULL, NULL, strdup(t));
- if ( ad == NULL ) {
- fprintf(stderr, "Failed to add SCBlock\n");
- return;
- }
-
- pnew = insert_paragraph(e->cursor_frame, e->cpos.para);
- if ( pnew == NULL ) {
- fprintf(stderr, "Failed to insert paragraph\n");
- return;
- }
- add_run(pnew, ad, e->cursor_frame->fontdesc,
- e->cursor_frame->col, NULL);
-
- wrap_frame(e->cursor_frame, e->pc);
-
- e->cpos.para += 1;
- e->cpos.pos = 0;
- e->cpos.trail = 1;
-
- }
-
- emit_change_sig(e);
- check_cursor_visible(e);
- sc_editor_redraw(e);
-}
-
-
-static gboolean im_commit_sig(GtkIMContext *im, gchar *str,
- SCEditor *e)
-{
- insert_text(str, e);
- return FALSE;
-}
-
-
-static int within_frame(struct frame *fr, double x, double y)
-{
- if ( fr == NULL ) return 0;
- if ( x < fr->x ) return 0;
- if ( y < fr->y ) return 0;
- if ( x > fr->x + fr->w ) return 0;
- if ( y > fr->y + fr->h ) return 0;
- return 1;
-}
-
-
-static struct frame *find_frame_at_position(struct frame *fr,
- double x, double y)
-{
- int i;
-
- for ( i=0; i<fr->num_children; i++ ) {
-
- if ( within_frame(fr->children[i], x, y) ) {
- return find_frame_at_position(fr->children[i], x, y);
- }
-
- }
-
- if ( within_frame(fr, x, y) ) return fr;
- return NULL;
-}
-
-
-static enum corner which_corner(double xp, double yp, struct frame *fr)
-{
- double x, y; /* Relative to object position */
-
- x = xp - fr->x;
- y = yp - fr->y;
-
- if ( x < 0.0 ) return CORNER_NONE;
- if ( y < 0.0 ) return CORNER_NONE;
- if ( x > fr->w ) return CORNER_NONE;
- if ( y > fr->h ) return CORNER_NONE;
-
- /* Top left? */
- if ( (x<20.0) && (y<20.0) ) return CORNER_TL;
- if ( (x>fr->w-20.0) && (y<20.0) ) return CORNER_TR;
- if ( (x<20.0) && (y>fr->h-20.0) ) return CORNER_BL;
- if ( (x>fr->w-20.0) && (y>fr->h-20.0) ) return CORNER_BR;
-
- return CORNER_NONE;
-}
-
-
-static void calculate_box_size(struct frame *fr, SCEditor *e,
- double x, double y)
-{
- double ddx, ddy, dlen, mult;
- double vx, vy, dbx, dby;
-
- ddx = x - e->start_corner_x;
- ddy = y - e->start_corner_y;
-
- if ( !fr->is_image ) {
-
- switch ( e->drag_corner ) {
-
- case CORNER_BR :
- e->box_x = fr->x;
- e->box_y = fr->y;
- e->box_width = fr->w + ddx;
- e->box_height = fr->h + ddy;
- break;
-
- case CORNER_BL :
- e->box_x = fr->x + ddx;
- e->box_y = fr->y;
- e->box_width = fr->w - ddx;
- e->box_height = fr->h + ddy;
- break;
-
- case CORNER_TL :
- e->box_x = fr->x + ddx;
- e->box_y = fr->y + ddy;
- e->box_width = fr->w - ddx;
- e->box_height = fr->h - ddy;
- break;
-
- case CORNER_TR :
- e->box_x = fr->x;
- e->box_y = fr->y + ddy;
- e->box_width = fr->w + ddx;
- e->box_height = fr->h - ddy;
- break;
-
- case CORNER_NONE :
- break;
-
- }
- return;
-
-
- }
-
- switch ( e->drag_corner ) {
-
- case CORNER_BR :
- vx = fr->w;
- vy = fr->h;
- break;
-
- case CORNER_BL :
- vx = -fr->w;
- vy = fr->h;
- break;
-
- case CORNER_TL :
- vx = -fr->w;
- vy = -fr->h;
- break;
-
- case CORNER_TR :
- vx = fr->w;
- vy = -fr->h;
- break;
-
- case CORNER_NONE :
- default:
- vx = 0.0;
- vy = 0.0;
- break;
-
- }
-
- dlen = (ddx*vx + ddy*vy) / e->diagonal_length;
- mult = (dlen+e->diagonal_length) / e->diagonal_length;
-
- e->box_width = fr->w * mult;
- e->box_height = fr->h * mult;
- dbx = e->box_width - fr->w;
- dby = e->box_height - fr->h;
-
- if ( e->box_width < 40.0 ) {
- mult = 40.0 / fr->w;
- }
- if ( e->box_height < 40.0 ) {
- mult = 40.0 / fr->h;
- }
- e->box_width = fr->w * mult;
- e->box_height = fr->h * mult;
- dbx = e->box_width - fr->w;
- dby = e->box_height - fr->h;
-
- switch ( e->drag_corner ) {
-
- case CORNER_BR :
- e->box_x = fr->x;
- e->box_y = fr->y;
- break;
-
- case CORNER_BL :
- e->box_x = fr->x - dbx;
- e->box_y = fr->y;
- break;
-
- case CORNER_TL :
- e->box_x = fr->x - dbx;
- e->box_y = fr->y - dby;
- break;
-
- case CORNER_TR :
- e->box_x = fr->x;
- e->box_y = fr->y - dby;
- break;
-
- case CORNER_NONE :
- break;
-
- }
-}
-
-
-static void check_paragraph(struct frame *fr, PangoContext *pc,
- SCBlock *scblocks)
-{
- if ( fr->n_paras > 0 ) return;
- Paragraph *para = last_para(fr);
-
- if ( scblocks == NULL ) {
- /* We have no SCBlocks at all! Better create one... */
- scblocks = sc_parse("");
- fr->scblocks = scblocks;
- }
-
- /* We are creating the first paragraph. It uses the last SCBlock
- * in the chain */
- while ( sc_block_next(scblocks) != NULL ) {
- scblocks = sc_block_next(scblocks);
- }
- scblocks = sc_block_append(scblocks, NULL, NULL, strdup(""), NULL);
-
- add_run(para, scblocks, fr->fontdesc, fr->col, NULL);
- wrap_paragraph(para, pc, fr->w - fr->pad_l - fr->pad_r, 0, 0);
-}
-
-
-static void rewrap_paragraph_range(struct frame *fr, int a, int b,
- struct edit_pos sel_start,
- struct edit_pos sel_end,
- int sel_active)
-{
- int i;
- int sel_s, sel_e;
- Paragraph *para;
-
- if ( a > b ) {
- int t = a;
- a = b; b = t;
- }
-
- if ( fr == NULL ) return;
- if ( fr->paras == NULL ) return;
-
- sort_positions(&sel_start, &sel_end);
-
- //printf("frame %p\n", fr);
- //printf("start: ");
- //show_edit_pos(sel_start);
- //printf(" end: ");
- //show_edit_pos(sel_end);
-
- para = fr->paras[sel_start.para];
- sel_s = pos_trail_to_offset(para, sel_start.pos, sel_start.trail);
- para = fr->paras[sel_end.para];
- sel_e = pos_trail_to_offset(para, sel_end.pos, sel_end.trail);
-
- for ( i=a; i<=b; i++ ) {
- size_t srt, end;
- if ( sel_active ) {
- if ( i == sel_start.para ) {
- srt = sel_s;
- } else {
- srt = 0;
- }
- if ( i == sel_end.para ) {
- end = sel_e;
- } else {
- end = G_MAXUINT;
- }
- if ( i > sel_start.para && i < sel_end.para ) {
- end = G_MAXUINT;
- }
- } else {
- srt = 0;
- end = 0;
- }
- wrap_paragraph(fr->paras[i], NULL,
- fr->w - fr->pad_l - fr->pad_r, srt, end);
- }
-}
-
-
-static void unset_selection(SCEditor *e)
-{
- int a, b;
-
- if ( !e->sel_active ) return;
-
- a = e->sel_start.para;
- b = e->sel_end.para;
- if ( a > b ) {
- a = e->sel_end.para;
- b = e->sel_start.para;
- }
- e->sel_active = 0;
- rewrap_paragraph_range(e->cursor_frame, a, b, e->sel_start, e->sel_end, 0);
-}
-
-
-static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event,
- SCEditor *e)
-{
- enum corner c;
- gdouble x, y;
- struct frame *clicked;
- int shift;
-
- x = event->x - e->border_offs_x;
- y = event->y - e->border_offs_y + e->scroll_pos;
- x /= e->view_scale;
- y /= e->view_scale;
- shift = event->state & GDK_SHIFT_MASK;
-
- if ( within_frame(e->selection, x, y) ) {
- clicked = e->selection;
- } else {
- clicked = find_frame_at_position(e->top, x, y);
- }
-
- /* Clicked within the currently selected frame
- * -> resize, move or select text */
- if ( (e->selection != NULL) && (clicked == e->selection) ) {
-
- struct frame *fr;
-
- fr = e->selection;
-
- /* Within the resizing region? */
- c = which_corner(x, y, fr);
- if ( (c != CORNER_NONE) && fr->resizable && shift ) {
-
- e->drag_reason = DRAG_REASON_RESIZE;
- e->drag_corner = c;
-
- e->start_corner_x = x;
- e->start_corner_y = y;
- e->diagonal_length = pow(fr->w, 2.0);
- e->diagonal_length += pow(fr->h, 2.0);
- e->diagonal_length = sqrt(e->diagonal_length);
-
- calculate_box_size(fr, e, x, y);
-
- e->drag_status = DRAG_STATUS_COULD_DRAG;
- e->drag_reason = DRAG_REASON_RESIZE;
-
- } else {
-
- /* Position cursor and prepare for possible drag */
- e->cursor_frame = clicked;
- check_paragraph(e->cursor_frame, e->pc, sc_block_child(fr->scblocks));
- find_cursor(clicked, x-fr->x, y-fr->y, &e->cpos);
- ensure_run(e->cursor_frame, e->cpos);
-
- e->start_corner_x = x;
- e->start_corner_y = y;
-
- if ( event->type == GDK_2BUTTON_PRESS ) {
- check_callback_click(e->cursor_frame, e->cpos.para);
- }
-
- if ( fr->resizable && shift ) {
- e->drag_status = DRAG_STATUS_COULD_DRAG;
- e->drag_reason = DRAG_REASON_MOVE;
- } else if ( !e->para_highlight ) {
- e->drag_status = DRAG_STATUS_COULD_DRAG;
- e->drag_reason = DRAG_REASON_TEXTSEL;
- unset_selection(e);
- find_cursor(clicked, x-fr->x, y-fr->y, &e->sel_start);
- }
-
- }
-
- } else if ( (clicked == NULL)
- || ( !e->top_editable && (clicked == e->top) ) )
- {
- /* Clicked no object. Deselect old object.
- * If shift held, set up for creating a new one. */
- e->selection = NULL;
- unset_selection(e);
-
- if ( shift ) {
- e->start_corner_x = x;
- e->start_corner_y = y;
- e->drag_status = DRAG_STATUS_COULD_DRAG;
- e->drag_reason = DRAG_REASON_CREATE;
- } else {
- e->drag_status = DRAG_STATUS_NONE;
- e->drag_reason = DRAG_REASON_NONE;
- }
-
- } else {
-
- /* Clicked an existing frame, no immediate dragging */
- e->drag_status = DRAG_STATUS_COULD_DRAG;
- e->drag_reason = DRAG_REASON_TEXTSEL;
- unset_selection(e);
- find_cursor(clicked, x-clicked->x, y-clicked->y,
- &e->sel_start);
- find_cursor(clicked, x-clicked->x, y-clicked->y,
- &e->sel_end);
- e->selection = clicked;
- e->cursor_frame = clicked;
- if ( clicked == e->top ) {
- check_paragraph(e->cursor_frame, e->pc, clicked->scblocks);
- } else {
- check_paragraph(e->cursor_frame, e->pc,
- sc_block_child(clicked->scblocks));
- }
- find_cursor(clicked, x-clicked->x, y-clicked->y, &e->cpos);
- ensure_run(e->cursor_frame, e->cpos);
-
- }
-
- gtk_widget_grab_focus(GTK_WIDGET(da));
- sc_editor_redraw(e);
- return FALSE;
-}
-
-
-static gboolean motion_sig(GtkWidget *da, GdkEventMotion *event,
- SCEditor *e)
-{
- struct frame *fr = e->selection;
- gdouble x, y;
-
- x = event->x - e->border_offs_x;
- y = event->y - e->border_offs_y + e->scroll_pos;
- x /= e->view_scale;
- y /= e->view_scale;
-
- if ( e->drag_status == DRAG_STATUS_COULD_DRAG ) {
-
- /* We just got a motion signal, and the status was "could drag",
- * therefore the drag has started. */
- e->drag_status = DRAG_STATUS_DRAGGING;
-
- }
-
- switch ( e->drag_reason ) {
-
- case DRAG_REASON_NONE :
- break;
-
- case DRAG_REASON_CREATE :
- e->drag_corner_x = x;
- e->drag_corner_y = y;
- sc_editor_redraw(e);
- break;
-
- case DRAG_REASON_IMPORT :
- /* Do nothing, handled by dnd_motion() */
- break;
-
- case DRAG_REASON_RESIZE :
- calculate_box_size(fr, e, x, y);
- sc_editor_redraw(e);
- break;
-
- case DRAG_REASON_MOVE :
- e->box_x = (fr->x - e->start_corner_x) + x;
- e->box_y = (fr->y - e->start_corner_y) + y;
- e->box_width = fr->w;
- e->box_height = fr->h;
- sc_editor_redraw(e);
- break;
-
- case DRAG_REASON_TEXTSEL :
- unset_selection(e);
- find_cursor(fr, x-fr->x, y-fr->y, &e->sel_end);
- rewrap_paragraph_range(fr, e->sel_start.para, e->sel_end.para,
- e->sel_start, e->sel_end, 1);
- find_cursor(fr, x-fr->x, y-fr->y, &e->cpos);
- e->sel_active = !positions_equal(e->sel_start, e->sel_end);
- sc_editor_redraw(e);
- break;
-
- }
-
- gdk_event_request_motions(event);
- return FALSE;
-}
-
-
-static struct frame *create_frame(SCEditor *e, double x, double y,
- double w, double h)
-{
- struct frame *parent;
- struct frame *fr;
- SCBlock *scblocks;
-
- parent = e->top;
-
- if ( w < 0.0 ) {
- x += w;
- w = -w;
- }
-
- if ( h < 0.0 ) {
- y += h;
- h = -h;
- }
-
- /* Add to frame structure */
- fr = add_subframe(parent);
-
- /* Add to SC */
- scblocks = sc_block_append_end(sc_block_child(e->scblocks), "f", NULL, NULL);
- fr->scblocks = scblocks;
- sc_block_append_inside(scblocks, NULL, NULL, strdup(""));
-
- fr->x = x;
- fr->y = y;
- fr->w = w;
- fr->h = h;
- fr->is_image = 0;
- fr->empty = 1;
- fr->resizable = 1;
-
- update_geom(fr);
-
- full_rerender(e);
- return find_frame_with_scblocks(e->top, scblocks);
-}
-
-
-static void do_resize(SCEditor *e, double x, double y, double w, double h)
-{
- struct frame *fr;
-
- assert(e->selection != NULL);
-
- if ( w < 0.0 ) {
- w = -w;
- x -= w;
- }
-
- if ( h < 0.0 ) {
- h = -h;
- y -= h;
- }
-
- fr = e->selection;
- fr->x = x;
- fr->y = y;
- fr->w = w;
- fr->h = h;
- update_geom(fr);
-
- full_rerender(e);
- sc_editor_redraw(e);
-}
-
-
-static gboolean button_release_sig(GtkWidget *da, GdkEventButton *event,
- SCEditor *e)
-{
- gdouble x, y;
- struct frame *fr;
-
- x = event->x - e->border_offs_x;
- y = event->y - e->border_offs_y;
- x /= e->view_scale;
- y /= e->view_scale;
-
- /* Not dragging? Then I don't care. */
- if ( e->drag_status != DRAG_STATUS_DRAGGING ) return FALSE;
-
- e->drag_corner_x = x;
- e->drag_corner_y = y;
- e->drag_status = DRAG_STATUS_NONE;
-
- switch ( e->drag_reason )
- {
-
- case DRAG_REASON_NONE :
- printf("Release on pointless drag.\n");
- break;
-
- case DRAG_REASON_CREATE :
- fr = create_frame(e, e->start_corner_x, e->start_corner_y,
- e->drag_corner_x - e->start_corner_x,
- e->drag_corner_y - e->start_corner_y);
- if ( fr != NULL ) {
- check_paragraph(fr, e->pc, sc_block_child(fr->scblocks));
- e->selection = fr;
- e->cursor_frame = fr;
- e->cpos.para = 0;
- e->cpos.pos = 0;
- e->cpos.trail = 0;
- } else {
- fprintf(stderr, _("Failed to create frame!\n"));
- }
- break;
-
- case DRAG_REASON_IMPORT :
- /* Do nothing, handled in dnd_drop() or dnd_leave() */
- break;
-
- case DRAG_REASON_RESIZE :
- do_resize(e, e->box_x, e->box_y, e->box_width, e->box_height);
- break;
-
- case DRAG_REASON_MOVE :
- do_resize(e, e->box_x, e->box_y, e->box_width, e->box_height);
- break;
-
- case DRAG_REASON_TEXTSEL :
- /* Do nothing (text is already selected) */
- break;
-
- }
-
- e->drag_reason = DRAG_REASON_NONE;
-
- gtk_widget_grab_focus(GTK_WIDGET(da));
- sc_editor_redraw(e);
- return FALSE;
-}
-
-
-static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event,
- SCEditor *e)
-{
- gboolean r;
- int claim = 0;
-
- /* Throw the event to the IM context and let it sort things out */
- r = gtk_im_context_filter_keypress(GTK_IM_CONTEXT(e->im_context),
- event);
- if ( r ) return FALSE; /* IM ate it */
-
- switch ( event->keyval ) {
-
- case GDK_KEY_Escape :
- if ( !e->para_highlight ) {
- sc_editor_remove_cursor(e);
- sc_editor_redraw(e);
- claim = 1;
- }
- break;
-
- case GDK_KEY_Left :
- if ( e->selection != NULL ) {
- cursor_moveh(e->cursor_frame, &e->cpos, -1);
- sc_editor_redraw(e);
- }
- claim = 1;
- break;
-
- case GDK_KEY_Right :
- if ( e->selection != NULL ) {
- cursor_moveh(e->cursor_frame, &e->cpos, +1);
- sc_editor_redraw(e);
- }
- claim = 1;
- break;
-
- case GDK_KEY_Up :
- if ( e->selection != NULL ) {
- cursor_moveh(e->cursor_frame, &e->cpos, -1);
- sc_editor_redraw(e);
- }
- claim = 1;
- break;
-
- case GDK_KEY_Down :
- if ( e->selection != NULL ) {
- cursor_moveh(e->cursor_frame, &e->cpos, +1);
- sc_editor_redraw(e);
- }
- claim = 1;
- break;
-
-
- case GDK_KEY_Return :
- im_commit_sig(NULL, "\n", e);
- claim = 1;
- break;
-
- case GDK_KEY_BackSpace :
- if ( e->selection != NULL ) {
- do_backspace(e->selection, e);
- claim = 1;
- }
- break;
-
- case GDK_KEY_F5 :
- full_rerender(e);
- break;
-
- case GDK_KEY_F6 :
- show_edit_pos(e->cpos);
- break;
-
- case GDK_KEY_F7 :
- if ( e->cursor_frame != NULL ) {
- if ( event->state & GDK_CONTROL_MASK ) {
- debug_paragraphs(e);
- } else if ( event->state & GDK_SHIFT_MASK ) {
- printf("Cursor frame block = %p\n", e->cursor_frame->scblocks);
- printf("Editor top block = %p\n", e->scblocks);
- show_sc_block(e->cursor_frame->scblocks, "");
- } else {
- open_debugger(e->cursor_frame);
- }
- } else {
- if ( event->state & GDK_SHIFT_MASK ) {
- printf("Debugging the top frame:\n");
- printf("Editor top block = %p\n", e->scblocks);
- show_sc_block(e->top->scblocks, "");
- }
- }
- break;
-
- case GDK_KEY_C :
- case GDK_KEY_c :
- if ( event->state == GDK_CONTROL_MASK ) {
- copy_selection(e);
- }
- break;
-
- case GDK_KEY_V :
- case GDK_KEY_v :
- if ( event->state == GDK_CONTROL_MASK ) {
- sc_editor_paste(e);
- }
- break;
-
-
- }
-
- if ( claim ) return TRUE;
- return FALSE;
-}
-
-
-static gboolean dnd_motion(GtkWidget *widget, GdkDragContext *drag_context,
- gint x, gint y, guint time, SCEditor *e)
-{
- GdkAtom target;
-
- /* If we haven't already requested the data, do so now */
- if ( !e->drag_preview_pending && !e->have_drag_data ) {
-
- target = gtk_drag_dest_find_target(widget, drag_context, NULL);
-
- if ( target != GDK_NONE ) {
- gtk_drag_get_data(widget, drag_context, target, time);
- e->drag_preview_pending = 1;
- } else {
- e->import_acceptable = 0;
- gdk_drag_status(drag_context, 0, time);
- }
-
- }
-
- if ( e->have_drag_data && e->import_acceptable ) {
-
- gdk_drag_status(drag_context, GDK_ACTION_LINK, time);
- e->start_corner_x = x - e->import_width/2.0;
- e->start_corner_y = y - e->import_height/2.0;
- e->drag_corner_x = x + e->import_width/2.0;
- e->drag_corner_y = y + e->import_height/2.0;
-
- sc_editor_redraw(e);
-
- }
-
- return TRUE;
-}
-
-
-static gboolean dnd_drop(GtkWidget *widget, GdkDragContext *drag_context,
- gint x, gint y, guint time, SCEditor *e)
-{
- GdkAtom target;
-
- target = gtk_drag_dest_find_target(widget, drag_context, NULL);
-
- if ( target == GDK_NONE ) {
- gtk_drag_finish(drag_context, FALSE, FALSE, time);
- } else {
- gtk_drag_get_data(widget, drag_context, target, time);
- }
-
- return TRUE;
-}
-
-
-/* Scale the image down if it's a silly size */
-static void check_import_size(SCEditor *e)
-{
- if ( e->import_width > e->w ) {
-
- int new_import_width;
-
- new_import_width = e->w/2;
- e->import_height = (new_import_width * e->import_height) /
- e->import_width;
- e->import_width = new_import_width;
-
- }
-
- if ( e->import_height > e->h ) {
-
- int new_import_height;
-
- new_import_height = e->w/2;
- e->import_width = (new_import_height*e->import_width) /
- e->import_height;
- e->import_height = new_import_height;
-
- }
-}
-
-
-static void dnd_receive(GtkWidget *widget, GdkDragContext *drag_context,
- gint x, gint y, GtkSelectionData *seldata,
- guint info, guint time, SCEditor *e)
-{
- if ( e->drag_preview_pending ) {
-
- gchar *filename = NULL;
- GdkPixbufFormat *f;
- gchar **uris;
- int w, h;
-
- e->have_drag_data = 1;
- e->drag_preview_pending = 0;
- uris = gtk_selection_data_get_uris(seldata);
- if ( uris != NULL ) {
- filename = g_filename_from_uri(uris[0], NULL, NULL);
- }
- g_strfreev(uris);
-
- if ( filename == NULL ) {
-
- /* This doesn't even look like a sensible URI.
- * Bail out. */
- gdk_drag_status(drag_context, 0, time);
- if ( e->drag_highlight ) {
- gtk_drag_unhighlight(widget);
- e->drag_highlight = 0;
- }
- e->import_acceptable = 0;
- return;
-
- }
- chomp(filename);
-
- f = gdk_pixbuf_get_file_info(filename, &w, &h);
- g_free(filename);
-
- e->import_width = w;
- e->import_height = h;
-
- if ( f == NULL ) {
-
- gdk_drag_status(drag_context, 0, time);
- if ( e->drag_highlight ) {
- gtk_drag_unhighlight(widget);
- e->drag_highlight = 0;
- }
- e->drag_status = DRAG_STATUS_NONE;
- e->drag_reason = DRAG_REASON_NONE;
- e->import_acceptable = 0;
-
- } else {
-
- /* Looks like a sensible image */
- gdk_drag_status(drag_context, GDK_ACTION_PRIVATE, time);
- e->import_acceptable = 1;
-
- if ( !e->drag_highlight ) {
- gtk_drag_highlight(widget);
- e->drag_highlight = 1;
- }
-
- check_import_size(e);
- e->drag_reason = DRAG_REASON_IMPORT;
- e->drag_status = DRAG_STATUS_DRAGGING;
-
- }
-
- } else {
-
- gchar **uris;
- char *filename = NULL;
-
- uris = gtk_selection_data_get_uris(seldata);
- if ( uris != NULL ) {
- filename = g_filename_from_uri(uris[0], NULL, NULL);
- }
- g_strfreev(uris);
-
- if ( filename != NULL ) {
-
- struct frame *fr;
- char *opts;
- size_t len;
- int w, h;
-
- gtk_drag_finish(drag_context, TRUE, FALSE, time);
- chomp(filename);
-
- w = e->drag_corner_x - e->start_corner_x;
- h = e->drag_corner_y - e->start_corner_y;
-
- len = strlen(filename)+64;
- opts = malloc(len);
- if ( opts == NULL ) {
- free(filename);
- fprintf(stderr, "Failed to allocate SC\n");
- return;
- }
- snprintf(opts, len, "1fx1f+0+0,filename=\"%s\"",
- filename);
-
- fr = create_frame(e, e->start_corner_x,
- e->start_corner_y, w, h);
- fr->is_image = 1;
- fr->empty = 0;
- sc_block_set_name(sc_block_child(fr->scblocks), strdup("image"));
- sc_block_set_options(sc_block_child(fr->scblocks), opts);
- full_rerender(e);
- sc_editor_remove_cursor(e);
- sc_editor_redraw(e);
- free(filename);
-
- } else {
-
- gtk_drag_finish(drag_context, FALSE, FALSE, time);
-
- }
-
- }
-}
-
-
-static void dnd_leave(GtkWidget *widget, GdkDragContext *drag_context,
- guint time, SCEditor *sceditor)
-{
- if ( sceditor->drag_highlight ) {
- gtk_drag_unhighlight(widget);
- }
- sceditor->have_drag_data = 0;
- sceditor->drag_highlight = 0;
- sceditor->drag_status = DRAG_STATUS_NONE;
- sceditor->drag_reason = DRAG_REASON_NONE;
-}
-
-
-static gint realise_sig(GtkWidget *da, SCEditor *e)
-{
- GdkWindow *win;
-
- /* Keyboard and input method stuff */
- e->im_context = gtk_im_multicontext_new();
- win = gtk_widget_get_window(GTK_WIDGET(e));
- gtk_im_context_set_client_window(GTK_IM_CONTEXT(e->im_context), win);
- gdk_window_set_accept_focus(win, TRUE);
- g_signal_connect(G_OBJECT(e->im_context), "commit", G_CALLBACK(im_commit_sig), e);
- g_signal_connect(G_OBJECT(e), "key-press-event", G_CALLBACK(key_press_sig), e);
-
- /* FIXME: Can do this "properly" by setting up a separate font map */
- e->pc = gtk_widget_get_pango_context(GTK_WIDGET(e));
-
- return FALSE;
-}
-
-
-void sc_editor_set_scblock(SCEditor *e, SCBlock *scblocks)
-{
- e->scblocks = scblocks;
- full_rerender(e);
-}
-
-
-static void update_size_request(SCEditor *e)
-{
- gtk_widget_set_size_request(GTK_WIDGET(e), 0, e->h + 2.0*e->min_border);
-}
-
-
-void sc_editor_set_logical_size(SCEditor *e, double w, double h)
-{
- e->log_w = w;
- e->log_h = h;
- if ( gtk_widget_get_mapped(GTK_WIDGET(e)) ) {
- full_rerender(e);
- sc_editor_redraw(e);
- }
-}
-
-
-void sc_editor_set_slidenum(SCEditor *e, int slidenum)
-{
- e->slidenum = slidenum;
-}
-
-
-void sc_editor_set_min_border(SCEditor *e, double min_border)
-{
- e->min_border = min_border;
- update_size_request(e);
-}
-
-
-void sc_editor_set_top_frame_editable(SCEditor *e, int top_frame_editable)
-{
- e->top_editable = top_frame_editable;
-}
-
-
-void sc_editor_set_stylesheet(SCEditor *e, Stylesheet *stylesheet)
-{
- e->stylesheet = stylesheet;
-}
-
-
-void sc_editor_set_callbacks(SCEditor *e, SCCallbackList *cbl)
-{
- if ( e->cbl != NULL ) sc_callback_list_free(e->cbl);
- e->cbl = cbl;
-}
-
-
-void sc_editor_set_para_highlight(SCEditor *e, int para_highlight)
-{
- e->para_highlight = para_highlight;
- sc_editor_redraw(e);
-}
-
-int sc_editor_get_cursor_para(SCEditor *e)
-{
- if ( e->cursor_frame == NULL ) return 0;
- return e->cpos.para;
-}
-
-
-void *sc_editor_get_cursor_bvp(SCEditor *e)
-{
- Paragraph *para;
- if ( e->cursor_frame == NULL ) return 0;
- para = e->cursor_frame->paras[e->cpos.para];
- return get_para_bvp(para);
-}
-
-
-void sc_editor_set_cursor_para(SCEditor *e, signed int pos)
-{
- double h;
- int i;
-
- if ( e->cursor_frame == NULL ) {
- e->cursor_frame = e->top;
- e->selection = e->top;
- }
-
- if ( pos < 0 ) {
- e->cpos.para = e->cursor_frame->n_paras - 1;
- } else if ( pos >= e->cursor_frame->n_paras ) {
- e->cpos.para = e->cursor_frame->n_paras - 1;
- } else {
- e->cpos.para = pos;
- }
- e->cpos.pos = 0;
- e->cpos.trail = 0;
-
- h = 0;
- for ( i=0; i<e->cpos.para; i++ ) {
- h += paragraph_height(e->cursor_frame->paras[i]);
- }
- h += (paragraph_height(e->cursor_frame->paras[e->cpos.para]))/2;
- e->scroll_pos = h - (e->visible_height/2);
- set_vertical_params(e);
-
- sc_editor_redraw(e);
-}
-
-
-int sc_editor_get_num_paras(SCEditor *e)
-{
- if ( e->cursor_frame == NULL ) return 1;
- return e->cursor_frame->n_paras;
-}
-
-
-void sc_editor_set_scale(SCEditor *e, int scale)
-{
- e->scale = scale;
- if ( !scale ) {
- e->view_scale = 1.0;
- }
-}
-
-
-void sc_editor_set_imagestore(SCEditor *e, ImageStore *is)
-{
- if ( e->is != NULL ) {
- fprintf(stderr, "WARNING: Changing imagestore\n");
- }
- e->is = is;
-}
-
-
-SCEditor *sc_editor_new(SCBlock *scblocks, Stylesheet *stylesheet,
- PangoLanguage *lang, const char *storename)
-{
- SCEditor *sceditor;
- GtkTargetEntry targets[1];
- GError *err;
-
- sceditor = g_object_new(SC_TYPE_EDITOR, NULL);
-
- sceditor->scblocks = scblocks;
- sceditor->w = 100;
- sceditor->h = 100;
- sceditor->log_w = 100;
- sceditor->log_h = 100;
- sceditor->border_offs_x = 0;
- sceditor->border_offs_y = 0;
- sceditor->is = NULL;
- sceditor->slidenum = 0;
- sceditor->min_border = 0.0;
- sceditor->top_editable = 0;
- sceditor->cbl = NULL;
- sceditor->scroll_pos = 0;
- sceditor->flow = 0;
- sceditor->scale = 0;
- sceditor->view_scale = 1.0;
- sceditor->lang = lang;
-
- sceditor->para_highlight = 0;
- sc_editor_remove_cursor(sceditor);
-
- sceditor->stylesheet = stylesheet;
-
- err = NULL;
- sceditor->bg_pixbuf = gdk_pixbuf_new_from_resource("/uk/me/bitwiz/Colloquium/sky.png",
- &err);
- if ( sceditor->bg_pixbuf == NULL ) {
- fprintf(stderr, _("Failed to load background: %s\n"),
- err->message);
- }
-
- gtk_widget_set_size_request(GTK_WIDGET(sceditor),
- sceditor->w, sceditor->h);
-
- g_signal_connect(G_OBJECT(sceditor), "destroy",
- G_CALLBACK(destroy_sig), sceditor);
- g_signal_connect(G_OBJECT(sceditor), "realize",
- G_CALLBACK(realise_sig), sceditor);
- g_signal_connect(G_OBJECT(sceditor), "button-press-event",
- G_CALLBACK(button_press_sig), sceditor);
- g_signal_connect(G_OBJECT(sceditor), "button-release-event",
- G_CALLBACK(button_release_sig), sceditor);
- g_signal_connect(G_OBJECT(sceditor), "motion-notify-event",
- G_CALLBACK(motion_sig), sceditor);
- g_signal_connect(G_OBJECT(sceditor), "configure-event",
- G_CALLBACK(resize_sig), sceditor);
-
- /* Drag and drop */
- targets[0].target = "text/uri-list";
- targets[0].flags = 0;
- targets[0].info = 1;
- gtk_drag_dest_set(GTK_WIDGET(sceditor), 0, targets, 1,
- GDK_ACTION_PRIVATE);
- g_signal_connect(sceditor, "drag-data-received",
- G_CALLBACK(dnd_receive), sceditor);
- g_signal_connect(sceditor, "drag-motion",
- G_CALLBACK(dnd_motion), sceditor);
- g_signal_connect(sceditor, "drag-drop",
- G_CALLBACK(dnd_drop), sceditor);
- g_signal_connect(sceditor, "drag-leave",
- G_CALLBACK(dnd_leave), sceditor);
-
- gtk_widget_set_can_focus(GTK_WIDGET(sceditor), TRUE);
- gtk_widget_add_events(GTK_WIDGET(sceditor),
- GDK_POINTER_MOTION_HINT_MASK
- | GDK_BUTTON1_MOTION_MASK
- | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK
- | GDK_SCROLL_MASK);
-
- g_signal_connect(G_OBJECT(sceditor), "draw",
- G_CALLBACK(draw_sig), sceditor);
-
- gtk_widget_grab_focus(GTK_WIDGET(sceditor));
-
- gtk_widget_show(GTK_WIDGET(sceditor));
-
- return sceditor;
-}
diff --git a/src-old/sc_editor.h b/src-old/sc_editor.h
deleted file mode 100644
index d3c111b..0000000
--- a/src-old/sc_editor.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * sc_editor.h
- *
- * Copyright © 2014-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef SC_EDITOR_H
-#define SC_EDITOR_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtk.h>
-#include <glib-object.h>
-
-#include "frame.h"
-#include "sc_interp.h"
-#include "stylesheet.h"
-
-struct presentation;
-
-
-#define SC_TYPE_EDITOR (sc_editor_get_type())
-
-#define SC_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
- SC_TYPE_EDITOR, SCEditor))
-
-#define SC_IS_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
- SC_TYPE_EDITOR))
-
-#define SC_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((obj), \
- SC_TYPE_EDITOR, SCEditorClass))
-
-#define SC_IS_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), \
- SC_TYPE_EDITOR))
-
-#define SC_EDITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
- SC_TYPE_EDITOR, SCEditorClass))
-
-enum drag_reason
-{
- DRAG_REASON_NONE,
- DRAG_REASON_CREATE,
- DRAG_REASON_IMPORT,
- DRAG_REASON_RESIZE,
- DRAG_REASON_MOVE,
- DRAG_REASON_TEXTSEL
-};
-
-
-enum corner
-{
- CORNER_NONE,
- CORNER_TL,
- CORNER_TR,
- CORNER_BL,
- CORNER_BR
-};
-
-
-enum drag_status
-{
- DRAG_STATUS_NONE,
- DRAG_STATUS_COULD_DRAG,
- DRAG_STATUS_DRAGGING,
-};
-
-
-struct _sceditor
-{
- GtkDrawingArea parent_instance;
- PangoLanguage *lang;
-
- /*< private >*/
- GtkIMContext *im_context;
- int w; /* Surface size in pixels */
- int h;
- double log_w; /* Size of surface in "SC units" */
- double log_h;
- SCBlock *scblocks;
- Stylesheet *stylesheet;
- ImageStore *is;
- SCCallbackList *cbl;
- struct frame *top;
- int para_highlight;
-
- /* Redraw/scroll stuff */
- GtkScrollablePolicy hpol;
- GtkScrollablePolicy vpol;
- GtkAdjustment *hadj;
- GtkAdjustment *vadj;
- double scroll_pos;
- double h_scroll_pos;
- int visible_height;
- int visible_width;
- int flow;
- int scale; /* Whether the SCEditor should scale to fit */
- double view_scale; /* The scale factor, if scale=1 */
-
- /* Pointers to the frame currently being edited */
- struct frame *selection;
- int top_editable;
-
- PangoContext *pc;
-
- /* Location of the cursor */
- struct frame *cursor_frame;
- struct edit_pos cpos;
-
- /* Border surrounding actual slide within drawingarea */
- double border_offs_x;
- double border_offs_y;
- double min_border;
- double bgcol[3];
- GdkPixbuf *bg_pixbuf;
-
- /* Rubber band boxes and related stuff */
- double start_corner_x;
- double start_corner_y;
- double drag_corner_x;
- double drag_corner_y;
- double diagonal_length;
- double box_x;
- double box_y;
- double box_width;
- double box_height;
- enum drag_reason drag_reason;
- enum drag_status drag_status;
- enum corner drag_corner;
- int sel_active;
- struct edit_pos sel_start; /* Where the user dragged from */
- struct edit_pos sel_end;
-
- /* Stuff to do with drag and drop import of "content" */
- int drag_preview_pending;
- int have_drag_data;
- int drag_highlight;
- double import_width;
- double import_height;
- int import_acceptable;
-
- /* Stuff that doesn't really belong here */
- int slidenum;
-};
-
-struct _sceditorclass
-{
- GtkDrawingAreaClass parent_class;
-};
-
-typedef struct _sceditor SCEditor;
-typedef struct _sceditorclass SCEditorClass;
-
-extern void sc_editor_set_scblock(SCEditor *e, SCBlock *scblocks);
-extern void sc_editor_set_stylesheet(SCEditor *e, Stylesheet *stylesheet);
-extern SCEditor *sc_editor_new(SCBlock *scblocks, Stylesheet *stylesheet,
- PangoLanguage *lang, const char *storename);
-extern void sc_editor_set_logical_size(SCEditor *e, double w, double h);
-extern void sc_editor_set_flow(SCEditor *e, int flow);
-extern void sc_editor_set_scale(SCEditor *e, int scale);
-extern void sc_editor_redraw(SCEditor *e);
-extern void sc_editor_set_background(SCEditor *e, double r, double g, double b);
-extern void sc_editor_set_slidenum(SCEditor *e, int slidenum);
-extern void sc_editor_set_min_border(SCEditor *e, double min_border);
-extern void sc_editor_set_top_frame_editable(SCEditor *e,
- int top_frame_editable);
-extern void sc_editor_set_callbacks(SCEditor *e, SCCallbackList *cbl);
-extern void sc_editor_paste(SCEditor *e);
-extern void sc_editor_add_storycode(SCEditor *e, const char *sc);
-extern void sc_editor_copy_selected_frame(SCEditor *e);
-extern void sc_editor_delete_selected_frame(SCEditor *e);
-extern void sc_editor_ensure_cursor(SCEditor *e);
-extern SCBlock *split_paragraph_at_cursor(SCEditor *e);
-
-extern void sc_editor_set_imagestore(SCEditor *e, ImageStore *is);
-extern void sc_editor_set_para_highlight(SCEditor *e, int para_highlight);
-extern int sc_editor_get_cursor_para(SCEditor *e);
-extern void *sc_editor_get_cursor_bvp(SCEditor *e);
-extern void sc_editor_set_cursor_para(SCEditor *e, signed int pos);
-extern int sc_editor_get_num_paras(SCEditor *e);
-
-#endif /* SC_EDITOR_H */
diff --git a/src-old/sc_interp.c b/src-old/sc_interp.c
deleted file mode 100644
index 07f09a5..0000000
--- a/src-old/sc_interp.c
+++ /dev/null
@@ -1,1148 +0,0 @@
-/*
- * sc_interp.c
- *
- * Copyright © 2014-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pango/pangocairo.h>
-#include <gdk/gdk.h>
-
-#include "imagestore.h"
-#include "sc_parse.h"
-#include "sc_interp.h"
-#include "presentation.h"
-#include "utils.h"
-
-
-struct sc_state
-{
- PangoFontDescription *fontdesc;
- PangoFont *font;
- PangoAlignment alignment;
- double col[4];
- int ascent;
- int height;
- float paraspace[4];
- char *constants[NUM_SC_CONSTANTS];
-
- struct frame *fr; /* The current frame */
-};
-
-struct _scinterp
-{
- PangoContext *pc;
- PangoLanguage *lang;
- ImageStore *is;
-
- struct slide_constants *s_constants;
- struct presentation_constants *p_constants;
-
- struct sc_state *state;
- int j; /* Index of the current state */
- int max_state;
-
- SCCallbackList *cbl;
-};
-
-struct _sccallbacklist
-{
- int n_callbacks;
- int max_callbacks;
- char **names;
- SCCallbackBoxFunc *box_funcs;
- SCCallbackDrawFunc *draw_funcs;
- SCCallbackClickFunc *click_funcs;
- void **vps;
-};
-
-
-static int sc_interp_add_blocks(SCInterpreter *scin, SCBlock *bl, Stylesheet *ss)
-{
- while ( bl != NULL ) {
- if ( sc_interp_add_block(scin, bl, ss) ) return 1;
- bl = sc_block_next(bl);
- }
-
- return 0;
-}
-
-
-SCCallbackList *sc_callback_list_new()
-{
- SCCallbackList *cbl;
-
- cbl = malloc(sizeof(struct _sccallbacklist));
- if ( cbl == NULL ) return NULL;
-
- cbl->names = calloc(8, sizeof(char *));
- if ( cbl->names == NULL ) {
- free(cbl);
- return NULL;
- }
-
- cbl->box_funcs = calloc(8, sizeof(cbl->box_funcs[0]));
- if ( cbl->box_funcs == NULL ) {
- free(cbl->names);
- free(cbl);
- return NULL;
- }
-
- cbl->draw_funcs = calloc(8, sizeof(cbl->draw_funcs[0]));
- if ( cbl->draw_funcs == NULL ) {
- free(cbl->box_funcs);
- free(cbl->names);
- free(cbl);
- return NULL;
- }
-
- cbl->click_funcs = calloc(8, sizeof(cbl->click_funcs[0]));
- if ( cbl->click_funcs == NULL ) {
- free(cbl->draw_funcs);
- free(cbl->box_funcs);
- free(cbl->names);
- free(cbl);
- return NULL;
- }
-
- cbl->vps = calloc(8, sizeof(cbl->vps[0]));
- if ( cbl->vps == NULL ) {
- free(cbl->click_funcs);
- free(cbl->draw_funcs);
- free(cbl->box_funcs);
- free(cbl->names);
- free(cbl);
- return NULL;
- }
-
- cbl->max_callbacks = 8;
- cbl->n_callbacks = 0;
-
- return cbl;
-}
-
-
-void sc_callback_list_free(SCCallbackList *cbl)
-{
- int i;
-
- if ( cbl == NULL ) return;
-
- for ( i=0; i<cbl->n_callbacks; i++ ) {
- free(cbl->names[i]);
- }
-
- free(cbl->names);
- free(cbl->box_funcs);
- free(cbl->draw_funcs);
- free(cbl->vps);
- free(cbl);
-
-}
-
-
-void sc_callback_list_add_callback(SCCallbackList *cbl, const char *name,
- SCCallbackBoxFunc box_func,
- SCCallbackDrawFunc draw_func,
- SCCallbackClickFunc click_func,
- void *vp)
-{
- if ( cbl->n_callbacks == cbl->max_callbacks ) {
-
- SCCallbackBoxFunc *box_funcs_new;
- SCCallbackDrawFunc *draw_funcs_new;
- SCCallbackClickFunc *click_funcs_new;
- char **names_new;
- void **vps_new;
- int mcn = cbl->max_callbacks + 8;
-
- names_new = realloc(cbl->names, mcn*sizeof(char *));
- box_funcs_new = realloc(cbl->box_funcs,
- mcn*sizeof(SCCallbackBoxFunc));
- draw_funcs_new = realloc(cbl->draw_funcs,
- mcn*sizeof(SCCallbackDrawFunc));
- click_funcs_new = realloc(cbl->click_funcs,
- mcn*sizeof(SCCallbackClickFunc));
- vps_new = realloc(cbl->vps, mcn*sizeof(void *));
-
- if ( (names_new == NULL) || (box_funcs_new == NULL)
- || (vps_new == NULL) || (draw_funcs_new == NULL)
- || (click_funcs_new == NULL) ) {
- fprintf(stderr, "Failed to grow callback list\n");
- return;
- }
-
- cbl->names = names_new;
- cbl->box_funcs = box_funcs_new;
- cbl->draw_funcs = draw_funcs_new;
- cbl->click_funcs = click_funcs_new;
- cbl->vps = vps_new;
- cbl->max_callbacks = mcn;
-
- }
-
- cbl->names[cbl->n_callbacks] = strdup(name);
- cbl->box_funcs[cbl->n_callbacks] = box_func;
- cbl->draw_funcs[cbl->n_callbacks] = draw_func;
- cbl->click_funcs[cbl->n_callbacks] = click_func;
- cbl->vps[cbl->n_callbacks] = vp;
- cbl->n_callbacks++;
-}
-
-
-void sc_interp_set_callbacks(SCInterpreter *scin, SCCallbackList *cbl)
-{
- if ( scin->cbl != NULL ) {
- fprintf(stderr, "WARNING: Interpreter already has a callback "
- "list.\n");
- }
- scin->cbl = cbl;
-}
-
-
-static int check_callback(SCInterpreter *scin, SCBlock *bl)
-{
- int i;
- const char *name = sc_block_name(bl);
- SCCallbackList *cbl = scin->cbl;
-
- /* No callback list -> easy */
- if ( cbl == NULL ) return 0;
-
- /* No name -> definitely not a callback */
- if ( name == NULL ) return 0;
-
- for ( i=0; i<cbl->n_callbacks; i++ ) {
-
- double w, h;
- int r;
- void *bvp;
-
- if ( strcmp(cbl->names[i], name) != 0 ) continue;
- r = cbl->box_funcs[i](scin, bl, &w, &h, &bvp, cbl->vps[i]);
- if ( r ) {
- struct sc_state *st = &scin->state[scin->j];
- Paragraph *pnew;
- pnew = add_callback_para(sc_interp_get_frame(scin),
- bl, w, h,
- cbl->draw_funcs[i],
- cbl->click_funcs[i],
- bvp, cbl->vps[i]);
- if ( pnew != NULL ) {
- set_para_spacing(pnew, st->paraspace);
- }
-
- }
- return 1;
-
- }
-
- return 0;
-}
-
-
-PangoFontDescription *sc_interp_get_fontdesc(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- return st->fontdesc;
-}
-
-
-double *sc_interp_get_fgcol(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- return st->col;
-}
-
-
-static void set_frame_default_style(struct frame *fr, SCInterpreter *scin)
-{
- if ( fr == NULL ) return;
-
- if ( fr->fontdesc != NULL ) {
- pango_font_description_free(fr->fontdesc);
- }
- fr->fontdesc = pango_font_description_copy(sc_interp_get_fontdesc(scin));
- fr->col[0] = sc_interp_get_fgcol(scin)[0];
- fr->col[1] = sc_interp_get_fgcol(scin)[1];
- fr->col[2] = sc_interp_get_fgcol(scin)[2];
- fr->col[3] = sc_interp_get_fgcol(scin)[3];
-}
-
-
-static void update_font(SCInterpreter *scin)
-{
- PangoFontMetrics *metrics;
- struct sc_state *st = &scin->state[scin->j];
-
- if ( scin->pc == NULL ) return;
-
- st->font = pango_font_map_load_font(pango_context_get_font_map(scin->pc),
- scin->pc, st->fontdesc);
- if ( st->font == NULL ) {
- char *f = pango_font_description_to_string(st->fontdesc);
- fprintf(stderr, "Couldn't load font '%s' (font map %p, pc %p)\n",
- f, pango_context_get_font_map(scin->pc), scin->pc);
- g_free(f);
- return;
- }
-
- /* FIXME: Language for box */
- metrics = pango_font_get_metrics(st->font, NULL);
- st->ascent = pango_font_metrics_get_ascent(metrics);
- st->height = st->ascent + pango_font_metrics_get_descent(metrics);
- pango_font_metrics_unref(metrics);
- set_frame_default_style(sc_interp_get_frame(scin), scin);
-}
-
-
-static void set_font(SCInterpreter *scin, const char *font_name)
-{
- struct sc_state *st = &scin->state[scin->j];
-
- st->fontdesc = pango_font_description_from_string(font_name);
- if ( st->fontdesc == NULL ) {
- fprintf(stderr, "Couldn't describe font.\n");
- return;
- }
-
- update_font(scin);
-}
-
-
-static void copy_top_fontdesc(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
-
- /* If this is the first stack frame, don't even check */
- if ( scin->j == 0 ) return;
-
- /* If the fontdesc at the top of the stack is the same as the one
- * below, make a copy because we're about to do something to it (which
- * should not affect the next level up). */
- if ( st->fontdesc == scin->state[scin->j-1].fontdesc ) {
- st->fontdesc = pango_font_description_copy(st->fontdesc);
- }
-}
-
-
-static void set_fontsize(SCInterpreter *scin, const char *size_str)
-{
- struct sc_state *st = &scin->state[scin->j];
- int size;
- char *end;
-
- if ( size_str[0] == '\0' ) return;
-
- size = strtoul(size_str, &end, 10);
- if ( end[0] != '\0' ) {
- fprintf(stderr, _("Invalid font size '%s'\n"), size_str);
- return;
- }
-
- copy_top_fontdesc(scin);
- pango_font_description_set_size(st->fontdesc, size*PANGO_SCALE);
- update_font(scin);
-}
-
-
-static void set_bold(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- copy_top_fontdesc(scin);
- pango_font_description_set_weight(st->fontdesc, PANGO_WEIGHT_BOLD);
- update_font(scin);
-}
-
-
-static void set_oblique(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- copy_top_fontdesc(scin);
- pango_font_description_set_style(st->fontdesc, PANGO_STYLE_OBLIQUE);
- update_font(scin);
-}
-
-
-static void set_italic(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- copy_top_fontdesc(scin);
- pango_font_description_set_style(st->fontdesc, PANGO_STYLE_ITALIC);
- update_font(scin);
-}
-
-
-static void set_alignment(SCInterpreter *scin, PangoAlignment align)
-{
- struct sc_state *st = &scin->state[scin->j];
- st->alignment = align;
-}
-
-
-/* This sets the colour for the font at the top of the stack */
-static void set_colour(SCInterpreter *scin, const char *colour)
-{
- GdkRGBA col;
- struct sc_state *st = &scin->state[scin->j];
-
- if ( colour == NULL ) {
- printf(_("Invalid colour\n"));
- st->col[0] = 0.0;
- st->col[1] = 0.0;
- st->col[2] = 0.0;
- st->col[3] = 1.0;
- return;
- }
-
- gdk_rgba_parse(&col, colour);
-
- st->col[0] = col.red;
- st->col[1] = col.green;
- st->col[2] = col.blue;
- st->col[3] = col.alpha;
- set_frame_default_style(sc_interp_get_frame(scin), scin);
-}
-
-
-static void set_bgcol(SCInterpreter *scin, const char *colour)
-{
- GdkRGBA col;
- struct frame *fr = sc_interp_get_frame(scin);
-
- if ( fr == NULL ) return;
-
- if ( colour == NULL ) {
- printf(_("Invalid colour\n"));
- return;
- }
-
- gdk_rgba_parse(&col, colour);
-
- fr->bgcol[0] = col.red;
- fr->bgcol[1] = col.green;
- fr->bgcol[2] = col.blue;
- fr->bgcol[3] = col.alpha;
- fr->grad = GRAD_NONE;
-}
-
-
-static void set_bggrad(SCInterpreter *scin, const char *options,
- GradientType grad)
-{
- struct frame *fr = sc_interp_get_frame(scin);
- GdkRGBA col1, col2;
-
- if ( fr == NULL ) return;
-
- if ( options == NULL ) {
- printf(_("Invalid colour\n"));
- return;
- }
-
- if ( parse_colour_duo(options, &col1, &col2) == 0 ) {
-
- fr->bgcol[0] = col1.red;
- fr->bgcol[1] = col1.green;
- fr->bgcol[2] = col1.blue;
- fr->bgcol[3] = col1.alpha;
-
- fr->bgcol2[0] = col2.red;
- fr->bgcol2[1] = col2.green;
- fr->bgcol2[2] = col2.blue;
- fr->bgcol2[3] = col2.alpha;
-
- fr->grad = grad;
-
- }
-}
-
-
-static char *get_constant(SCInterpreter *scin, unsigned int constant)
-{
- struct sc_state *st = &scin->state[scin->j];
- if ( constant >= NUM_SC_CONSTANTS ) return NULL;
- return st->constants[constant];
-}
-
-
-void sc_interp_set_constant(SCInterpreter *scin, unsigned int constant,
- const char *val)
-{
- struct sc_state *st = &scin->state[scin->j];
- if ( constant >= NUM_SC_CONSTANTS ) return;
- if ( val == NULL ) return;
- st->constants[constant] = strdup(val);
-}
-
-
-void sc_interp_save(SCInterpreter *scin)
-{
- if ( scin->j+1 == scin->max_state ) {
-
- struct sc_state *stack_new;
-
- stack_new = realloc(scin->state, sizeof(struct sc_state)
- * (scin->max_state+8));
- if ( stack_new == NULL ) {
- fprintf(stderr, "Failed to add to stack.\n");
- return;
- }
-
- scin->state = stack_new;
- scin->max_state += 8;
-
- }
-
- /* When n_fonts=0, we leave the first font uninitialised. This allows
- * the stack to be "bootstrapped", but requires the first caller to do
- * set_font and set_colour straight away. */
- scin->state[scin->j+1] = scin->state[scin->j];
-
- scin->j++;
-}
-
-
-void sc_interp_restore(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
-
- if ( scin->j > 0 ) {
-
- int i;
-
- if ( st->fontdesc != scin->state[scin->j-1].fontdesc )
- {
- pango_font_description_free(st->fontdesc);
- } /* else the font is the same as the previous one, and we
- * don't need to free it just yet */
-
- for ( i=0; i<NUM_SC_CONSTANTS; i++ ) {
- if ( st->constants[i] != scin->state[scin->j-1].constants[i] ) {
- free(st->constants[i]);
- } /* same logic as above */
- }
- }
-
- scin->j--;
-}
-
-
-struct frame *sc_interp_get_frame(SCInterpreter *scin)
-{
- struct sc_state *st = &scin->state[scin->j];
- return st->fr;
-}
-
-
-static void set_frame(SCInterpreter *scin, struct frame *fr)
-{
- struct sc_state *st = &scin->state[scin->j];
- st->fr = fr;
-}
-
-
-SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang,
- ImageStore *is, struct frame *top)
-{
- SCInterpreter *scin;
- struct sc_state *st;
- int i;
-
- scin = malloc(sizeof(SCInterpreter));
- if ( scin == NULL ) return NULL;
-
- scin->state = malloc(8*sizeof(struct sc_state));
- if ( scin->state == NULL ) {
- free(scin);
- return NULL;
- }
- scin->j = 0;
- scin->max_state = 8;
-
- scin->pc = pc;
- scin->is = is;
- scin->s_constants = NULL;
- scin->p_constants = NULL;
- scin->cbl = NULL;
- scin->lang = lang;
-
- /* Initial state */
- st = &scin->state[0];
- st->fr = NULL;
- st->paraspace[0] = 0.0;
- st->paraspace[1] = 0.0;
- st->paraspace[2] = 0.0;
- st->paraspace[3] = 0.0;
- st->fontdesc = NULL;
- st->col[0] = 0.0;
- st->col[1] = 0.0;
- st->col[2] = 0.0;
- st->col[3] = 1.0;
- st->alignment = PANGO_ALIGN_LEFT;
- for ( i=0; i<NUM_SC_CONSTANTS; i++ ) {
- st->constants[i] = NULL;
- }
-
- /* The "ultimate" default font */
- if ( scin->pc != NULL ) {
- set_frame(scin, top);
- set_font(scin, "Cantarell Regular 14");
- set_colour(scin, "#000000");
- }
-
- return scin;
-}
-
-
-void sc_interp_destroy(SCInterpreter *scin)
-{
- /* Empty the stack */
- while ( scin->j > 0 ) {
- sc_interp_restore(scin);
- }
-
- if ( scin->state[0].fontdesc != NULL ) {
- pango_font_description_free(scin->state[0].fontdesc);
- }
-
- free(scin->state);
- free(scin);
-}
-
-
-static void set_padding(struct frame *fr, const char *opts)
-{
- float p[4];
-
- if ( parse_tuple(opts, p) ) return;
-
- if ( fr == NULL ) return;
-
- fr->pad_l = p[0];
- fr->pad_r = p[1];
- fr->pad_t = p[2];
- fr->pad_b = p[3];
-}
-
-
-static void set_paraspace(SCInterpreter *scin, const char *opts)
-{
- float p[4];
- struct sc_state *st = &scin->state[scin->j];
-
- if ( parse_tuple(opts, p) ) return;
-
- st->paraspace[0] = p[0];
- st->paraspace[1] = p[1];
- st->paraspace[2] = p[2];
- st->paraspace[3] = p[3];
-
- set_para_spacing(last_para(sc_interp_get_frame(scin)), p);
-}
-
-
-void update_geom(struct frame *fr)
-{
- char geom[256];
- snprintf(geom, 255, "%.1fux%.1fu+%.1f+%.1f",
- fr->w, fr->h, fr->x, fr->y);
-
- /* FIXME: What if there are other options? */
- sc_block_set_options(fr->scblocks, strdup(geom));
-}
-
-
-static int calculate_dims(const char *opt, struct frame *parent,
- double *wp, double *hp, double *xp, double *yp)
-{
- LengthUnits h_units, w_units;
-
- if ( parse_dims(opt, wp, hp, &w_units, &h_units, xp, yp) ) {
- return 1;
- }
-
- if ( w_units == UNITS_FRAC ) {
- if ( parent != NULL ) {
- double pw = parent->w;
- pw -= parent->pad_l;
- pw -= parent->pad_r;
- *wp = pw * *wp;
- } else {
- *wp = -1.0;
- }
-
- }
- if ( h_units == UNITS_FRAC ) {
- if ( parent != NULL ) {
- double ph = parent->h;
- ph -= parent->pad_t;
- ph -= parent->pad_b;
- *hp = ph * *hp;
- } else {
- *hp = -1.0;
- }
- }
-
- return 0;
-}
-
-
-static int parse_frame_option(const char *opt, struct frame *fr,
- struct frame *parent)
-{
- if ( (index(opt, 'x') != NULL) && (index(opt, '+') != NULL)
- && (index(opt, '+') != rindex(opt, '+')) ) {
- return calculate_dims(opt, parent, &fr->w, &fr->h, &fr->x, &fr->y);
- }
-
- fprintf(stderr, _("Unrecognised frame option '%s'\n"), opt);
-
- return 1;
-}
-
-
-static int parse_frame_options(struct frame *fr, struct frame *parent,
- const char *opth)
-{
- int i;
- size_t len;
- size_t start;
- char *opt;
-
- if ( opth == NULL ) return 1;
-
- opt = strdup(opth);
-
- len = strlen(opt);
- start = 0;
-
- for ( i=0; i<len; i++ ) {
-
- /* FIXME: comma might be escaped or quoted */
- if ( opt[i] == ',' ) {
- opt[i] = '\0';
- if ( parse_frame_option(opt+start, fr, parent) ) {
- return 1;
- }
- start = i+1;
- }
-
- }
-
- if ( start != len ) {
- if ( parse_frame_option(opt+start, fr, parent) ) return 1;
- }
-
- free(opt);
-
- return 0;
-}
-
-
-static int parse_image_option(const char *opt, struct frame *parent,
- double *wp, double *hp, char **filenamep)
-{
- if ( (index(opt, 'x') != NULL) && (index(opt, '+') != NULL)
- && (index(opt, '+') != rindex(opt, '+')) ) {
- double dum;
- return calculate_dims(opt, NULL, wp, hp, &dum, &dum);
- }
-
- if ( strncmp(opt, "filename=\"", 10) == 0 ) {
- char *fn;
- fn = strdup(opt+10);
- if ( fn[strlen(fn)-1] != '\"' ) {
- fprintf(stderr, "Unterminated filename?\n");
- free(fn);
- return 1;
- }
- fn[strlen(fn)-1] = '\0';
- *filenamep = fn;
- return 0;
- }
-
- fprintf(stderr, _("Unrecognised image option '%s'\n"), opt);
-
- return 1;
-}
-
-
-static int parse_image_options(const char *opth, struct frame *parent,
- double *wp, double *hp, char **filenamep)
-{
- int i;
- size_t len;
- size_t start;
- char *opt;
-
- if ( opth == NULL ) return 1;
-
- opt = strdup(opth);
-
- len = strlen(opt);
- start = 0;
-
- for ( i=0; i<len; i++ ) {
-
- /* FIXME: comma might be escaped or quoted */
- if ( opt[i] == ',' ) {
- opt[i] = '\0';
- if ( parse_image_option(opt+start, parent,
- wp, hp, filenamep) ) return 1;
- start = i+1;
- }
-
- }
-
- if ( start != len ) {
- if ( parse_image_option(opt+start, parent,
- wp, hp, filenamep) ) return 1;
- }
-
- free(opt);
-
- return 0;
-}
-
-
-static void maybe_recurse_before(SCInterpreter *scin, SCBlock *child)
-{
- if ( child == NULL ) return;
-
- sc_interp_save(scin);
-}
-
-
-static void maybe_recurse_after(SCInterpreter *scin, SCBlock *child,
- Stylesheet *ss)
-{
- if ( child == NULL ) return;
-
- sc_interp_add_blocks(scin, child, ss);
- sc_interp_restore(scin);
-}
-
-
-static void add_newpara(SCBlock *bl, SCInterpreter *scin)
-{
- Paragraph *last_para;
- Paragraph *para;
- struct sc_state *st = &scin->state[scin->j];
- struct frame *fr = sc_interp_get_frame(scin);
-
- if ( fr->paras == NULL ) return;
- last_para = fr->paras[fr->n_paras-1];
-
- set_newline_at_end(last_para, bl);
-
- /* The block after the \newpara will always be the first one of the
- * next paragraph, by definition, even if it's \f or another \newpara */
- para = create_paragraph(fr, sc_block_next(bl));
- set_para_alignment(para, st->alignment);
- set_para_spacing(para, st->paraspace);
-}
-
-
-/* Add the SCBlock to the text in 'frame', at the end */
-static int add_text(struct frame *fr, PangoContext *pc, SCBlock *bl,
- PangoLanguage *lang, int editable, SCInterpreter *scin,
- const char *real_text)
-{
- const char *text = sc_block_contents(bl);
- PangoFontDescription *fontdesc;
- double *col;
- struct sc_state *st = &scin->state[scin->j];
- Paragraph *para;
-
- /* Empty block? */
- if ( text == NULL && real_text == NULL ) return 1;
-
- fontdesc = sc_interp_get_fontdesc(scin);
- col = sc_interp_get_fgcol(scin);
-
- para = last_para(fr);
- if ( (para == NULL) || (para_type(para) != PARA_TYPE_TEXT) ) {
- /* Last paragraph is not text.
- * or: no paragraphs yet.
- * Either way: Create the first one */
- para = create_paragraph(fr, bl);
- }
-
- set_para_alignment(para, st->alignment);
- add_run(para, bl, fontdesc, col, real_text);
- set_para_spacing(para, st->paraspace);
-
- return 0;
-}
-
-
-static void apply_style(SCInterpreter *scin, Stylesheet *ss, const char *path)
-{
- char *result;
-
- if ( ss == NULL ) return;
-
- /* Font */
- result = stylesheet_lookup(ss, path, "font");
- if ( result != NULL ) set_font(scin, result);
-
- /* Foreground colour */
- result = stylesheet_lookup(ss, path, "fgcol");
- if ( result != NULL ) set_colour(scin, result);
-
- /* Background (vertical gradient) */
- result = stylesheet_lookup(ss, path, "bggradv");
- if ( result != NULL ) set_bggrad(scin, result, GRAD_VERT);
-
- /* Background (horizontal gradient) */
- result = stylesheet_lookup(ss, path, "bggradh");
- if ( result != NULL ) set_bggrad(scin, result, GRAD_HORIZ);
-
- /* Background (solid colour) */
- result = stylesheet_lookup(ss, path, "bgcol");
- if ( result != NULL ) set_bgcol(scin, result);
-
- /* Padding */
- result = stylesheet_lookup(ss, path, "pad");
- if ( result != NULL ) set_padding(sc_interp_get_frame(scin), result);
-
- /* Paragraph spacing */
- result = stylesheet_lookup(ss, path, "paraspace");
- if ( result != NULL ) set_paraspace(scin, result);
-
- /* Alignment */
- result = stylesheet_lookup(ss, path, "alignment");
- if ( result != NULL ) {
- if ( strcmp(result, "center") == 0 ) {
- set_alignment(scin, PANGO_ALIGN_CENTER);
- }
- if ( strcmp(result, "left") == 0 ) {
- set_alignment(scin, PANGO_ALIGN_LEFT);
- }
- if ( strcmp(result, "right") == 0 ) {
- set_alignment(scin, PANGO_ALIGN_RIGHT);
- }
- }
-}
-
-
-static void output_frame(SCInterpreter *scin, SCBlock *bl, Stylesheet *ss,
- const char *stylename)
-{
- struct frame *fr;
- SCBlock *child = sc_block_child(bl);
- const char *options = sc_block_options(bl);
- char *result;
-
- fr = add_subframe(sc_interp_get_frame(scin));
- if ( fr == NULL ) {
- fprintf(stderr, _("Failed to add frame.\n"));
- return;
- }
-
- fr->scblocks = bl;
- fr->resizable = 1;
-
- /* Lowest priority: current state of interpreter */
- set_frame_default_style(fr, scin);
-
- /* Next priority: geometry from stylesheet */
- result = stylesheet_lookup(ss, stylename, "geometry");
- if ( result != NULL ) {
- parse_frame_options(fr, sc_interp_get_frame(scin), result);
- }
-
- /* Highest priority: parameters to \f (or \slidetitle etc) */
- parse_frame_options(fr, sc_interp_get_frame(scin), options);
-
- maybe_recurse_before(scin, child);
- set_frame(scin, fr);
- apply_style(scin, ss, stylename);
- maybe_recurse_after(scin, child, ss);
-}
-
-
-static int check_outputs(SCBlock *bl, SCInterpreter *scin, Stylesheet *ss)
-{
- const char *name = sc_block_name(bl);
- const char *options = sc_block_options(bl);
-
- if ( name == NULL ) {
- add_text(sc_interp_get_frame(scin),
- scin->pc, bl, scin->lang, 1, scin, NULL);
-
- } else if ( strcmp(name, "image")==0 ) {
- double w, h;
- char *filename;
- if ( parse_image_options(options, sc_interp_get_frame(scin),
- &w, &h, &filename) == 0 )
- {
- add_image_para(sc_interp_get_frame(scin), bl,
- filename, scin->is, w, h, 1);
- free(filename);
- } else {
- fprintf(stderr, _("Invalid image options '%s'\n"),
- options);
- }
-
- } else if ( strcmp(name, "f")==0 ) {
- output_frame(scin, bl, ss, "$.slide.frame");
-
- } else if ( strcmp(name, "slidetitle")==0 ) {
- output_frame(scin, bl, ss, "$.slide.slidetitle");
-
- } else if ( strcmp(name, "prestitle")==0 ) {
- output_frame(scin, bl, ss, "$.slide.prestitle");
-
- } else if ( strcmp(name, "author")==0 ) {
- output_frame(scin, bl, ss, "$.slide.author");
-
- } else if ( strcmp(name, "footer")==0 ) {
- output_frame(scin, bl, ss, "$.slide.footer");
-
- } else if ( strcmp(name, "newpara")==0 ) {
- add_newpara(bl, scin);
-
- } else if ( strcmp(name, "slidenumber")==0 ) {
- char *con = get_constant(scin, SCCONST_SLIDENUMBER);
- if ( con != NULL ) {
- add_text(sc_interp_get_frame(scin), scin->pc, bl,
- scin->lang, 1, scin, con);
- }
-
- } else {
- return 0;
- }
-
- return 1; /* handled */
-}
-
-
-int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl, Stylesheet *ss)
-{
- const char *name = sc_block_name(bl);
- const char *options = sc_block_options(bl);
- SCBlock *child = sc_block_child(bl);
-
- //printf("Running this --------->\n");
- //show_sc_blocks(bl);
- //printf("<------------\n");
-
- if ( check_callback(scin, bl) ) {
- /* Handled in check_callback, don't do anything else */
-
- } else if ((sc_interp_get_frame(scin) != NULL)
- && check_outputs(bl, scin, ss) ) {
- /* Block handled as output thing */
-
- } else if ( name == NULL ) {
- /* Dummy to ensure name != NULL below */
-
- } else if ( strcmp(name, "presentation") == 0 ) {
- maybe_recurse_before(scin, child);
- apply_style(scin, ss, "$.narrative");
- maybe_recurse_after(scin, child, ss);
-
- } else if ( strcmp(name, "slide") == 0 ) {
- maybe_recurse_before(scin, child);
- apply_style(scin, ss, "$.slide");
- maybe_recurse_after(scin, child, ss);
-
- } else if ( strcmp(name, "font") == 0 ) {
- maybe_recurse_before(scin, child);
- set_font(scin, options);
- maybe_recurse_after(scin, child, ss);
-
- } else if ( strcmp(name, "fontsize") == 0 ) {
- maybe_recurse_before(scin, child);
- set_fontsize(scin, options);
- maybe_recurse_after(scin, child, ss);
-
- } else if ( strcmp(name, "bold") == 0 ) {
- maybe_recurse_before(scin, child);
- set_bold(scin);
- maybe_recurse_after(scin, child, ss);
-
- } else if ( strcmp(name, "oblique") == 0 ) {
- maybe_recurse_before(scin, child);
- set_oblique(scin);
- maybe_recurse_after(scin, child, ss);
-
- } else if ( strcmp(name, "italic") == 0 ) {
- maybe_recurse_before(scin, child);
- set_italic(scin);
- maybe_recurse_after(scin, child, ss);
-
- } else if ( strcmp(name, "lalign") == 0 ) {
- maybe_recurse_before(scin, child);
- set_alignment(scin, PANGO_ALIGN_LEFT);
- maybe_recurse_after(scin, child, ss);
-
- } else if ( strcmp(name, "ralign") == 0 ) {
- maybe_recurse_before(scin, child);
- set_alignment(scin, PANGO_ALIGN_RIGHT);
- maybe_recurse_after(scin, child, ss);
-
- } else if ( strcmp(name, "center") == 0 ) {
- maybe_recurse_before(scin, child);
- set_alignment(scin, PANGO_ALIGN_CENTER);
- maybe_recurse_after(scin, child, ss);
-
- } else if ( strcmp(name, "fgcol") == 0 ) {
- maybe_recurse_before(scin, child);
- set_colour(scin, options);
- maybe_recurse_after(scin, child, ss);
-
- } else if ( strcmp(name, "pad") == 0 ) {
- maybe_recurse_before(scin, child);
- set_padding(sc_interp_get_frame(scin), options);
- maybe_recurse_after(scin, child, ss);
-
- } else if ( strcmp(name, "bgcol") == 0 ) {
- set_bgcol(scin, options);
-
- } else if ( strcmp(name, "bggradh") == 0 ) {
- set_bggrad(scin, options, GRAD_HORIZ);
-
- } else if ( strcmp(name, "bggradv") == 0 ) {
- set_bggrad(scin, options, GRAD_VERT);
-
- } else if ( strcmp(name, "paraspace") == 0 ) {
- maybe_recurse_before(scin, child);
- set_paraspace(scin, options);
- maybe_recurse_after(scin, child, ss);
-
- } else {
-
- fprintf(stderr, "Don't know what to do with this:\n");
- show_sc_block(bl, "");
-
- }
-
- return 0;
-}
-
diff --git a/src-old/sc_interp.h b/src-old/sc_interp.h
deleted file mode 100644
index 764b532..0000000
--- a/src-old/sc_interp.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * sc_interp.h
- *
- * Copyright © 2014-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef SC_INTERP_H
-#define SC_INTERP_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <pango/pangocairo.h>
-
-struct frame;
-
-#define SCCONST_SLIDENUMBER (0)
-#define NUM_SC_CONSTANTS (1)
-
-struct presentation;
-typedef struct _scinterp SCInterpreter;
-typedef struct _sccallbacklist SCCallbackList;
-typedef int (*SCCallbackBoxFunc)(SCInterpreter *scin, SCBlock *bl,
- double *w, double *h, void **, void *);
-typedef cairo_surface_t *(*SCCallbackDrawFunc)(int w, int h, void *, void *);
-typedef int (*SCCallbackClickFunc)(double x, double y, void *, void *);
-
-#include "frame.h"
-#include "imagestore.h"
-#include "stylesheet.h"
-
-extern SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang,
- ImageStore *is, struct frame *top);
-extern void sc_interp_destroy(SCInterpreter *scin);
-
-extern void sc_interp_save(SCInterpreter *scin);
-extern void sc_interp_restore(SCInterpreter *scin);
-
-extern int sc_interp_add_block(SCInterpreter *scin, SCBlock *bl, Stylesheet *ss);
-
-extern void sc_interp_set_constant(SCInterpreter *scin, unsigned int constant,
- const char *val);
-
-/* Callback lists */
-extern SCCallbackList *sc_callback_list_new();
-extern void sc_callback_list_free(SCCallbackList *cbl);
-extern void sc_callback_list_add_callback(SCCallbackList *cbl, const char *name,
- SCCallbackBoxFunc box_func,
- SCCallbackDrawFunc draw_func,
- SCCallbackClickFunc click_func,
- void *vp);
-extern void sc_interp_set_callbacks(SCInterpreter *scin, SCCallbackList *cbl);
-
-/* Get the current state of the interpreter */
-extern struct frame *sc_interp_get_frame(SCInterpreter *scin);
-extern PangoFont *sc_interp_get_font(SCInterpreter *scin);
-extern PangoFontDescription *sc_interp_get_fontdesc(SCInterpreter *scin);
-extern double *sc_interp_get_fgcol(SCInterpreter *scin);
-
-extern void update_geom(struct frame *fr);
-
-
-#endif /* SC_INTERP_H */
diff --git a/src-old/sc_parse.c b/src-old/sc_parse.c
deleted file mode 100644
index 78f5799..0000000
--- a/src-old/sc_parse.c
+++ /dev/null
@@ -1,856 +0,0 @@
-/*
- * sc_parse.c
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <glib.h>
-#include <gio/gio.h>
-
-#include "sc_parse.h"
-#include "utils.h"
-
-struct _scblock
-{
- char *name;
- char *options;
- char *contents;
-
- SCBlock *next;
- SCBlock *child;
-};
-
-
-SCBlock *sc_block_new()
-{
- SCBlock *bl;
-
- bl = calloc(1, sizeof(SCBlock));
- if ( bl == NULL ) return NULL;
-
- return bl;
-}
-
-
-SCBlock *sc_block_next(const SCBlock *bl)
-{
- assert(bl != NULL);
- return bl->next;
-}
-
-
-SCBlock *sc_block_child(const SCBlock *bl)
-{
- return bl->child;
-}
-
-
-const char *sc_block_name(const SCBlock *bl)
-{
- return bl->name;
-}
-
-
-const char *sc_block_options(const SCBlock *bl)
-{
- return bl->options;
-}
-
-
-const char *sc_block_contents(const SCBlock *bl)
-{
- return bl->contents;
-}
-
-
-static SCBlock *sc_find_previous(SCBlock *top, SCBlock *find)
-{
- if ( top->next == find ) return top;
-
- if ( top->child != NULL ) {
- SCBlock *t = sc_find_previous(top->child, find);
- if ( t != NULL ) return t;
- }
- if ( top->next != NULL ) {
- SCBlock *t = sc_find_previous(top->next, find);
- if ( t != NULL ) return t;
- }
- return NULL;
-}
-
-
-/* Add a new block before "bl" */
-SCBlock *sc_block_prepend(SCBlock *bl, SCBlock *top)
-{
- SCBlock *bln;
- SCBlock *prev;
-
- prev = sc_find_previous(top, bl);
- if ( prev == NULL ) {
- fprintf(stderr, "Couldn't find previous\n");
- return NULL;
- }
-
- bln = sc_block_new();
- if ( bln == NULL ) return NULL;
-
- prev->next = bln;
- bln->next = bl;
- return bln;
-}
-
-
-/* Append "bln" after "bl" */
-void sc_block_append_p(SCBlock *bl, SCBlock *bln)
-{
- if ( bl != NULL ) {
- bln->next = bl->next;
- bl->next = bln;
- }
-}
-
-
-/* Insert a new block after "bl". "name", "options" and "contents"
- * will not be copied. Returns the block just created, or NULL on error.
- * If *blfp points to NULL, it will updated to point at the new block. */
-SCBlock *sc_block_append(SCBlock *bl, char *name, char *opt, char *contents,
- SCBlock **blfp)
-{
- SCBlock *bln = sc_block_new();
-
- if ( bln == NULL ) return NULL;
-
- bln->name = name;
- bln->options = opt;
- bln->contents = contents;
- bln->child = NULL;
- bln->next = NULL;
-
- sc_block_append_p(bl, bln);
-
- if ( (blfp != NULL) && (*blfp == NULL) ) {
- *blfp = bln;
- }
-
- return bln;
-}
-
-
-/* Insert a new block at the end of the chain starting 'bl'.
- * "name", "options" and "contents" will not be copied. Returns the block just
- * created, or NULL on error. */
-SCBlock *sc_block_append_end(SCBlock *bl, char *name, char *opt, char *contents)
-{
- SCBlock *bln = sc_block_new();
-
- if ( bln == NULL ) return NULL;
-
- while ( bl->next != NULL ) {
- bln->next = bl->next;
- bl = bl->next;
- };
-
- return sc_block_append(bl, name, opt, contents, NULL);
-}
-
-
-void sc_block_append_block(SCBlock *bl, SCBlock *bln)
-{
-
- if ( bl == NULL ) return;
-
- while ( bl->next != NULL ) bl = bl->next;
-
- bl->next = bln;
- bln->next = NULL;
-}
-
-
-/* Append a new block to the chain inside "parent".
- * "name", "options" and "contents" will not be copied. Returns the block just
- * created, or NULL on error. */
-SCBlock *sc_block_append_inside(SCBlock *parent,
- char *name, char *opt, char *contents)
-{
- SCBlock *bln;
- SCBlock *bl;
- SCBlock **ptr;
-
- bl = parent->child;
- if ( bl != NULL ) {
- while ( bl->next != NULL ) bl = bl->next;
- ptr = &bl->next;
- } else {
- ptr = &parent->child;
- }
-
- bln = sc_block_new();
- if ( bln == NULL ) return NULL;
-
- bln->name = name;
- bln->options = opt;
- bln->contents = contents;
- bln->child = NULL;
- bln->next = NULL;
-
- *ptr = bln;
-
- return bln;
-}
-
-
-/* Insert a new block to the chain, just after "afterme".
- * "name", "options" and "contents" will not be copied. Returns the block just
- * created, or NULL on error. */
-SCBlock *sc_block_insert_after(SCBlock *afterme,
- char *name, char *opt, char *contents)
-{
- SCBlock *bl;
-
- bl = sc_block_new();
- if ( bl == NULL ) return NULL;
-
- bl->name = name;
- bl->options = opt;
- bl->contents = contents;
- bl->child = NULL;
- bl->next = afterme->next;
- afterme->next = bl;
-
- return bl;
-}
-
-
-static SCBlock *sc_find_parent(SCBlock *top, SCBlock *find)
-{
- if ( top->child == find ) return top;
- if ( top->next == find ) return top;
-
- if ( top->child != NULL ) {
- SCBlock *t = sc_find_parent(top->child, find);
- if ( t != NULL ) return t;
- }
- if ( top->next != NULL ) {
- SCBlock *t = sc_find_parent(top->next, find);
- if ( t != NULL ) return t;
- }
- return NULL;
-}
-
-
-/* Unlink "deleteme", which is somewhere under "top" */
-static int sc_block_unlink(SCBlock **top, SCBlock *deleteme)
-{
- SCBlock *parent = sc_find_parent(*top, deleteme);
- if ( parent == NULL ) {
- /* Maybe it's the first block? */
- if ( *top == deleteme ) {
- fprintf(stderr, "Unlinking at top\n");
- *top = (*top)->next;
- return 0;
- } else {
- fprintf(stderr, "Couldn't find block parent!\n");
- return 1;
- }
- }
-
- if ( parent->next == deleteme ) {
- parent->next = deleteme->next;
- }
-
- if ( parent->child == deleteme ) {
- parent->child = deleteme->next;
- }
- return 0;
-}
-
-
-/* Delete "deleteme", which is somewhere under "top" */
-int sc_block_delete(SCBlock **top, SCBlock *deleteme)
-{
- int r;
- r = sc_block_unlink(top, deleteme);
- if ( !r ) {
- sc_block_free(deleteme);
- }
- return r;
-}
-
-
-/* Frees "bl" and all its children (but not the blocks following it) */
-void sc_block_free(SCBlock *bl)
-{
- if ( bl == NULL ) return;
-
- if ( bl->child != NULL ) {
- SCBlock *ch = bl->child;
- while ( ch != NULL ) {
- SCBlock *next = ch->next;
- sc_block_free(ch);
- ch = next;
- }
- }
-
- free(bl);
-}
-
-
-/* Serialise one block (including children) */
-char *serialise_sc_block(const SCBlock *bl)
-{
- char *a;
- SCBlock *ch;
- size_t len = 3;
-
- if ( bl == NULL ) return strdup("");
-
- if ( bl->name != NULL ) len += 1+strlen(bl->name);
- if ( bl->options != NULL ) len += 2+strlen(bl->options);
- if ( bl->contents != NULL ) len += 2+strlen(bl->contents);
- a = malloc(len);
- if ( a == NULL ) return NULL;
- a[0] = '\0';
-
- if ( bl->name == NULL ) {
- strcat(a, bl->contents);
- } else if ( strcmp(bl->name, "newpara") == 0 ) {
- strcat(a, "\n");
-
- } else {
-
- strcat(a, "\\");
- strcat(a, bl->name);
- if ( bl->options != NULL ) {
- strcat(a, "[");
- strcat(a, bl->options);
- strcat(a, "]");
- }
- if ( (bl->contents != NULL) || (bl->child != NULL) ) {
- strcat(a, "{");
- }
- if ( bl->contents != NULL ) {
- strcat(a, bl->contents);
- }
-
- /* Special case to prevent "\somethingSome text" */
- if ( (bl->name != NULL) && (bl->options == NULL)
- && (bl->contents == NULL) && (bl->next != NULL)
- && (bl->next->name == NULL) && (bl->child == NULL) )
- {
- strcat(a, "{}");
- }
-
- }
-
- /* Add ALL child blocks of this one */
- ch = bl->child;
- while ( ch != NULL ) {
-
- char *anew;
- char *c = serialise_sc_block(ch);
- if ( c == NULL ) {
- free(a);
- return NULL;
- }
-
- len += strlen(c);
-
- anew = realloc(a, len);
- if ( anew == NULL ) {
- return NULL;
- } else {
- a = anew;
- }
-
- strcat(a, c);
- free(c);
-
- ch = ch->next;
-
- }
-
- if ( (bl->name != NULL) &&
- ((bl->contents != NULL) || (bl->child != NULL)) ) {
- strcat(a, "}");
- }
-
- return a;
-}
-
-
-int save_sc_block(GOutputStream *fh, const SCBlock *bl)
-{
- while ( bl != NULL ) {
- GError *error = NULL;
- char *a = serialise_sc_block(bl);
- gssize r;
- if ( a == NULL ) {
- fprintf(stderr, "Failed to serialise block\n");
- return 1;
- }
- r = g_output_stream_write(fh, a, strlen(a), NULL, &error);
- if ( r == -1 ) {
- fprintf(stderr, "Write failed: %s\n", error->message);
- return 1;
- }
- free(a);
- bl = bl->next;
- }
- return 0;
-}
-
-
-static void recursive_show_sc_blocks(const char *prefix, const SCBlock *bl)
-{
- while ( bl != NULL ) {
- show_sc_block(bl, prefix);
- bl = bl->next;
- }
-}
-
-
-void show_sc_block(const SCBlock *bl, const char *prefix)
-{
- printf("%s (%p) ", prefix, bl);
- if ( bl == NULL ) return;
- if ( bl->name != NULL ) printf("\\%s ", bl->name);
- if ( bl->options != NULL ) printf("[%s] ", bl->options);
- if ( bl->contents != NULL ) printf("{%s} ", bl->contents);
- printf("\n");
-
- if ( bl->child != NULL ) {
- char new_prefix[strlen(prefix)+3];
- strcpy(new_prefix, " ");
- strcat(new_prefix, prefix);
- recursive_show_sc_blocks(new_prefix, bl->child);
- }
-}
-
-
-void show_sc_blocks(const SCBlock *bl)
-{
- recursive_show_sc_blocks("", bl);
-}
-
-
-static int get_subexpr(const char *sc, char *bk, char **pcontents, int *err)
-{
- size_t ml;
- int i;
- int bct = 1;
- int found = 0;
- char *contents;
-
- *err = 0;
-
- ml = strlen(sc);
- contents = malloc(ml+1);
- if ( contents == NULL ) {
- *err = -1;
- return 0;
- }
- *pcontents = contents;
-
- for ( i=0; i<ml; i++ ) {
- if ( sc[i] == bk[0] ) {
- bct++;
- } else if ( sc[i] == bk[1] ) {
- bct--;
- }
- if ( bct == 0 ) {
- found = 1;
- break;
- }
- contents[i] = sc[i];
- }
-
- if ( (!found) || (bct != 0) ) {
- *err = 1;
- return 0;
- }
-
- contents[i] = '\0';
- return i+1;
-}
-
-
-static size_t read_block(const char *sc, char **pname, char **options,
- char **contents, int *err)
-{
- size_t l, i, j;
- char *name;
- int done;
-
- *err = 0;
-
- l = strlen(sc);
- i = 0; j = 0;
- name = malloc(l+1);
- if ( name == NULL ) {
- *err = 1;
- return 0;
- }
-
- done = 0;
- do {
-
- char c = sc[i];
-
- if ( isalnum(c) ) {
- name[j++] = c;
- i++;
- } else {
- /* Found the end of the name */
- done = 1;
- }
-
- } while ( !done && (i<l) );
-
- name[j] = '\0';
- *pname = name;
-
- if ( sc[i] == '[' ) {
-
- i += get_subexpr(sc+i+1, "[]", options, err) + 1;
- if ( *err ) {
- printf("Couldn't find end of options '%s'\n", sc+i);
- return 0;
- }
-
- } else {
- *options = NULL;
- }
-
- if ( sc[i] == '{' ) {
-
- i += get_subexpr(sc+i+1, "{}", contents, err) + 1;
- if ( *err ) {
- printf("Couldn't find end of content '%s'\n", sc+i);
- return 0;
- }
-
- } else {
- *contents = NULL;
- }
-
- return i+1;
-}
-
-
-static void separate_newlines(SCBlock *bl)
-{
- while ( bl != NULL ) {
-
- const char *contents = sc_block_contents(bl);
-
- if ( contents != NULL ) {
- char *npos = strchr(contents, '\n');
- if ( npos != NULL ) {
- SCBlock *nb = NULL;
- if ( npos == contents ) {
- bl->name = strdup("newpara");
- bl->contents = NULL;
- nb = bl;
- } else {
- sc_block_append(bl, strdup("newpara"),
- NULL, NULL, &nb);
- }
-
- /* Add any text after the \n */
- if ( strlen(npos+1) > 0 ) {
- sc_block_append(nb, NULL, NULL,
- strdup(npos+1), &nb);
- }
- npos[0] = '\0';
- }
- }
-
- if ( sc_block_child(bl) != NULL ) {
- separate_newlines(sc_block_child(bl));
- }
-
- bl = sc_block_next(bl);
-
- }
-}
-
-
-SCBlock *sc_parse(const char *sc)
-{
- SCBlock *bl;
- SCBlock *blf = NULL;
- char *tbuf;
- size_t len, i, j;
-
- if ( sc == NULL ) return NULL;
-
- if ( strlen(sc) == 0 ) {
- SCBlock *bl = sc_block_new();
- sc_block_set_contents(bl, g_strdup(""));
- return bl;
- }
-
- bl = NULL;
-
- len = strlen(sc);
- tbuf = malloc(len+1);
- if ( tbuf == NULL ) {
- sc_block_free(bl);
- return NULL;
- }
-
- i = 0; j = 0;
- do {
-
- if ( sc[i] == '\\' ) {
-
- int err;
- char *name = NULL;
- char *opt = NULL;
- char *contents = NULL;
-
- /* Is this an escaped backslash? */
- if ( sc[i+1] == '\\' ) {
- tbuf[j++] = '\\';
- i += 2; /* Skip both backslashes */
- continue;
- }
-
- /* No, it's a real block. Dispatch the previous block */
- if ( j != 0 ) {
- tbuf[j] = '\0';
- bl = sc_block_append(bl, NULL, NULL,
- strdup(tbuf), &blf);
- if ( bl == NULL ) {
- fprintf(stderr, "Block add failed.\n");
- sc_block_free(blf);
- free(tbuf);
- return NULL;
- }
- j = 0;
- }
-
- i += read_block(sc+i+1, &name, &opt, &contents, &err);
- if ( err ) {
- printf(_("Parse error\n"));
- sc_block_free(blf);
- free(tbuf);
- return NULL;
- }
-
- bl = sc_block_append(bl, name, opt, contents, &blf);
- if ( bl == NULL ) {
- fprintf(stderr, "Block add failed.\n");
- sc_block_free(blf);
- free(tbuf);
- return NULL;
- }
- bl->child = sc_parse(contents);
- free(bl->contents);
- bl->contents = NULL;
-
- } else {
-
- tbuf[j++] = sc[i++];
- }
-
- } while ( i<len );
-
- /* Add final block, if it exists */
- if ( j > 0 ) {
-
- /* Leftover buffer is empty? */
- if ( (j==1) && (tbuf[0]=='\0') ) return bl;
-
- tbuf[j] = '\0';
- bl = sc_block_append(bl, NULL, NULL, tbuf, &blf);
- if ( bl == NULL ) {
- fprintf(stderr, "Block add failed.\n");
- sc_block_free(blf);
- free(tbuf);
- return NULL;
- }
- j = 0;
- }
-
- separate_newlines(blf);
-
- return blf;
-}
-
-
-void sc_block_set_name(SCBlock *bl, char *nam)
-{
- if ( bl == NULL ) {
- fprintf(stderr, "sc_block_set_name: NULL block\n");
- return;
- }
- free(bl->name);
- bl->name = nam;
-}
-
-
-void sc_block_set_options(SCBlock *bl, char *opt)
-{
- free(bl->options);
- bl->options = opt;
-}
-
-
-void sc_block_set_contents(SCBlock *bl, char *con)
-{
- g_free(bl->contents);
- bl->contents = con;
-}
-
-
-void sc_insert_text(SCBlock *b1, size_t o1, const char *t)
-{
- size_t len;
- char *cnew;
- char *tmp;
- char *p1;
-
- if ( b1->contents == NULL ) {
- b1->contents = strdup(t);
- return;
- }
- len = strlen(b1->contents)+1+strlen(t);
-
- cnew = realloc(b1->contents, len);
- if ( cnew == NULL ) return;
-
- tmp = malloc(len);
- if ( tmp == NULL ) {
- free(cnew);
- return;
- }
-
- p1 = cnew + o1;
- strcpy(tmp, p1);
- strcpy(p1, t);
- strcpy(p1+strlen(t), tmp);
- free(tmp);
- b1->contents = cnew;
-}
-
-
-void sc_insert_block(SCBlock *b1, int o1, SCBlock *ins)
-{
- SCBlock *second;
- char *p1 = g_utf8_offset_to_pointer(b1->contents, o1);
-
- /* Create a new block containing the second half of b1 */
- second = sc_block_new();
- sc_block_set_contents(second, g_strdup(p1));
-
- /* Chop off b1 at the insertion point */
- sc_block_set_contents(b1, g_utf8_substring(b1->contents, 0, o1));
-
- /* Link the new block into the chain */
- SCBlock *old_next = b1->next;
- b1->next = ins;
- ins->next = second;
- second->next = old_next;
-}
-
-
-/* Delete text from SCBlock contents. o2=-1 means "to the end".
- * Returns the number of bytes deleted. */
-size_t scblock_delete_text(SCBlock *b, ssize_t o1, ssize_t o2)
-{
- size_t len;
-
- if ( b->contents == NULL ) {
- fprintf(stderr, "Deleting text from block \\%s\n", b->name);
- return 0;
- }
-
- if ( (o2 != -1) && (o1 > o2) ) {
- ssize_t t = o2;
- o2 = o1;
- o1 = t;
- }
-
- len = strlen(b->contents);
- if ( o2 < 0 ) o2 = len;
- if ( (o1 >= o2) || (o1 > len) || (o2 > len) ) {
- fprintf(stderr, "Invalid delete: %i %i %i\n",
- (int)o1, (int)o2, (int)len);
- return 0;
- }
- memmove(b->contents+o1, b->contents+o2, len-o2+1);
-
- return o2-o1;
-}
-
-
-static char *s_strdup(const char *a)
-{
- if ( a == NULL ) return NULL;
- return strdup(a);
-}
-
-
-SCBlock *sc_block_split(SCBlock *bl, size_t pos)
-{
- SCBlock *n = sc_block_new();
-
- if ( bl->child != NULL ) {
- fprintf(stderr, "Splitting a block with a child!\n");
- return NULL;
- }
-
- /* Second block */
- n->name = s_strdup(bl->name);
- n->options = s_strdup(bl->options);
- if ( bl->contents != NULL ) {
- n->contents = strdup(bl->contents+pos);
- /* Truncate the first block */
- bl->contents[pos] = '\0';
- } else {
- n->contents = NULL;
- }
-
- n->next = bl->next;
- bl->next = n;
-
- return n;
-}
-
-
-/* Return a new block which is the parent for "bl" */
-SCBlock *sc_block_new_parent(SCBlock *bl, const char *name)
-{
- SCBlock *n = sc_block_new();
- if ( n == NULL ) return NULL;
- n->name = s_strdup(name);
- n->child = bl;
- return n;
-}
diff --git a/src-old/sc_parse.h b/src-old/sc_parse.h
deleted file mode 100644
index 17ce2dd..0000000
--- a/src-old/sc_parse.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * sc_parse.h
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef SC_PARSE_H
-#define SC_PARSE_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <gio/gio.h>
-
-typedef struct _scblock SCBlock;
-
-extern SCBlock *sc_parse(const char *sc);
-
-extern SCBlock *sc_block_new(void);
-extern void sc_block_free(SCBlock *bl);
-
-extern SCBlock *sc_block_next(const SCBlock *bl);
-extern SCBlock *sc_block_child(const SCBlock *bl);
-extern const char *sc_block_name(const SCBlock *bl);
-extern const char *sc_block_options(const SCBlock *bl);
-extern const char *sc_block_contents(const SCBlock *bl);
-
-extern SCBlock *sc_block_append(SCBlock *bl,
- char *name, char *opt, char *contents,
- SCBlock **blfp);
-
-extern SCBlock *sc_block_new_parent(SCBlock *bl, const char *name);
-
-extern SCBlock *sc_block_prepend(SCBlock *bl, SCBlock *top);
-
-extern void sc_block_append_p(SCBlock *bl, SCBlock *bln);
-
-extern void sc_block_append_block(SCBlock *bl, SCBlock *bln);
-
-extern SCBlock *sc_block_append_end(SCBlock *bl,
- char *name, char *opt, char *contents);
-
-extern SCBlock *sc_block_append_inside(SCBlock *parent,
- char *name, char *opt, char *contents);
-
-extern SCBlock *sc_block_insert_after(SCBlock *afterme,
- char *name, char *opt, char *contents);
-
-extern int sc_block_delete(SCBlock **top, SCBlock *deleteme);
-
-
-extern void sc_block_set_name(SCBlock *bl, char *nam);
-extern void sc_block_set_options(SCBlock *bl, char *opt);
-extern void sc_block_set_contents(SCBlock *bl, char *con);
-extern void sc_insert_text(SCBlock *b1, size_t o1, const char *t);
-extern void sc_insert_block(SCBlock *b1, int o1, SCBlock *ins);
-extern SCBlock *sc_block_split(SCBlock *bl, size_t pos);
-
-extern void show_sc_blocks(const SCBlock *bl);
-extern void show_sc_block(const SCBlock *bl, const char *prefix);
-
-extern char *serialise_sc_block(const SCBlock *bl);
-extern int save_sc_block(GOutputStream *fh, const SCBlock *bl);
-
-extern size_t scblock_delete_text(SCBlock *b, ssize_t o1, ssize_t o2);
-
-#endif /* SC_PARSE_H */
diff --git a/src-old/slide_window.c b/src-old/slide_window.c
deleted file mode 100644
index ed37a50..0000000
--- a/src-old/slide_window.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * slide_window.c
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <gtk/gtk.h>
-#include <assert.h>
-#include <gdk/gdkkeysyms.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <math.h>
-
-#include "colloquium.h"
-#include "presentation.h"
-#include "slide_window.h"
-#include "render.h"
-#include "frame.h"
-#include "slideshow.h"
-#include "pr_clock.h"
-#include "sc_parse.h"
-#include "sc_interp.h"
-#include "sc_editor.h"
-#include "utils.h"
-
-
-struct _slidewindow
-{
- struct presentation *p;
- GtkWidget *window;
- GtkToolItem *bfirst;
- GtkToolItem *bprev;
- GtkToolItem *bnext;
- GtkToolItem *blast;
-
- /* The slide being displayed. Note that the SCEditor is using the
- * child of this block, but we need to keep a record of it for changing
- * the slide. */
- SCBlock *scblocks;
-
- SCEditor *sceditor;
-};
-
-
-static void insert_slidetitle_sig(GSimpleAction *action, GVariant *parameter,
- gpointer vp)
-{
- SlideWindow *sw = vp;
- sc_editor_add_storycode(sw->sceditor, "\\slidetitle{Slide title}");
-}
-
-
-static void paste_sig(GSimpleAction *action, GVariant *parameter,
- gpointer vp)
-{
- SlideWindow *sw = vp;
- sc_editor_paste(sw->sceditor);
-}
-
-
-static void copy_frame_sig(GSimpleAction *action, GVariant *parameter,
- gpointer vp)
-{
- SlideWindow *sw = vp;
- sc_editor_copy_selected_frame(sw->sceditor);
-}
-
-
-static void delete_frame_sig(GSimpleAction *action, GVariant *parameter,
- gpointer vp)
-{
- SlideWindow *sw = vp;
- sc_editor_delete_selected_frame(sw->sceditor);
-}
-
-
-void slide_window_update(SlideWindow *sw)
-{
- sc_editor_set_scblock(sw->sceditor, sw->scblocks);
-}
-
-
-/* Change the editor's slide to "np" */
-static void change_edit_slide(SlideWindow *sw, SCBlock *np)
-{
- sc_editor_set_slidenum(sw->sceditor, slide_number(sw->p, np));
- sc_editor_set_scblock(sw->sceditor, np);
- sw->scblocks = np;
-}
-
-
-static void change_slide_first(SlideWindow *sw)
-{
- change_edit_slide(sw, first_slide(sw->p));
-}
-
-
-static void change_slide_backwards(SlideWindow *sw)
-{
- SCBlock *tt;
- tt = prev_slide(sw->p, sw->scblocks);
- if ( tt == NULL ) return;
- change_edit_slide(sw, tt);
-}
-
-
-static void change_slide_forwards(SlideWindow *sw)
-{
- SCBlock *tt;
- tt = next_slide(sw->p, sw->scblocks);
- if ( tt == NULL ) return;
- change_edit_slide(sw, tt);
-}
-
-
-static void change_slide_last(SlideWindow *sw)
-{
- change_edit_slide(sw, last_slide(sw->p));
-}
-
-
-static void first_slide_sig(GSimpleAction *action, GVariant *parameter,
- gpointer vp)
-{
- SlideWindow *sw = vp;
- change_slide_first(sw);
-}
-
-
-static void prev_slide_sig(GSimpleAction *action, GVariant *parameter,
- gpointer vp)
-{
- SlideWindow *sw = vp;
- change_slide_backwards(sw);
-}
-
-
-static void next_slide_sig(GSimpleAction *action, GVariant *parameter,
- gpointer vp)
-{
- SlideWindow *sw = vp;
- change_slide_forwards(sw);
-}
-
-
-static void last_slide_sig(GSimpleAction *action, GVariant *parameter,
- gpointer vp)
-{
- SlideWindow *sw = vp;
- change_slide_last(sw);
-}
-
-
-static gboolean sw_close_sig(GtkWidget *w, SlideWindow *sw)
-{
- narrative_window_sw_closed(sw->p->narrative_window, sw);
- return FALSE;
-}
-
-
-static gboolean sw_key_press_sig(GtkWidget *da, GdkEventKey *event,
- SlideWindow *sw)
-{
- switch ( event->keyval ) {
-
- case GDK_KEY_Page_Up :
- change_slide_backwards(sw);
- break;
-
- case GDK_KEY_Page_Down :
- change_slide_forwards(sw);
- break;
-
- }
-
- return FALSE;
-}
-
-
-static void about_sig(GSimpleAction *action, GVariant *parameter, gpointer vp)
-{
- SlideWindow *sw = vp;
- open_about_dialog(sw->window);
-}
-
-
-GActionEntry sw_entries[] = {
-
- { "about", about_sig, NULL, NULL, NULL },
- { "paste", paste_sig, NULL, NULL, NULL },
- { "copyframe", copy_frame_sig, NULL, NULL, NULL },
- { "deleteframe", delete_frame_sig, NULL, NULL, NULL },
- { "first", first_slide_sig, NULL, NULL, NULL },
- { "prev", prev_slide_sig, NULL, NULL, NULL },
- { "next", next_slide_sig, NULL, NULL, NULL },
- { "last", last_slide_sig, NULL, NULL, NULL },
- { "slidetitle", insert_slidetitle_sig, NULL, NULL, NULL },
-};
-
-
-SlideWindow *slide_window_open(struct presentation *p, SCBlock *scblocks,
- GApplication *papp)
-{
- GtkWidget *window;
- SlideWindow *sw;
- Colloquium *app = COLLOQUIUM(papp);
-
- sw = calloc(1, sizeof(SlideWindow));
- if ( sw == NULL ) return NULL;
-
- window = gtk_application_window_new(GTK_APPLICATION(app));
- gtk_window_set_role(GTK_WINDOW(window), "slide");
- sw->window = window;
- sw->p = p;
-
- g_action_map_add_action_entries(G_ACTION_MAP(window), sw_entries,
- G_N_ELEMENTS(sw_entries), sw);
-
- g_signal_connect(G_OBJECT(window), "destroy",
- G_CALLBACK(sw_close_sig), sw);
-
- sw->scblocks = scblocks;
- sw->sceditor = sc_editor_new(scblocks, p->stylesheet, p->lang,
- colloquium_get_imagestore(app));
- sc_editor_set_slidenum(sw->sceditor, slide_number(sw->p, scblocks));
- sc_editor_set_scale(sw->sceditor, 1);
- sc_editor_set_imagestore(sw->sceditor, p->is);
-
-// scroll = gtk_scrolled_window_new(NULL, NULL);
-// gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
-// GTK_POLICY_AUTOMATIC,
-// GTK_POLICY_AUTOMATIC);
-// gtk_container_add(GTK_CONTAINER(scroll), GTK_WIDGET(sw->sceditor));
-// gtk_window_set_focus(GTK_WINDOW(window), GTK_WIDGET(sw->sceditor));
- g_signal_connect(G_OBJECT(sw->sceditor), "key-press-event",
- G_CALLBACK(sw_key_press_sig), sw);
-
- sc_editor_set_logical_size(sw->sceditor,
- p->slide_width, p->slide_height);
-
- gtk_window_set_default_size(GTK_WINDOW(window),
- p->slide_width, p->slide_height);
-
- gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(sw->sceditor));
-
- /* Default size */
-// gtk_scrolled_window_set_min_content_width(GTK_SCROLLED_WINDOW(scroll),
-// 1024);
-// gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scroll),
-// 768);
- gtk_window_set_resizable(GTK_WINDOW(sw->window), TRUE);
-
- gtk_widget_show_all(window);
-// gtk_scrolled_window_set_min_content_width(GTK_SCROLLED_WINDOW(scroll),
-// 100);
-// gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scroll),
-// 100);
-
- return sw;
-}
diff --git a/src-old/slide_window.h b/src-old/slide_window.h
deleted file mode 100644
index 681ec39..0000000
--- a/src-old/slide_window.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * slide_window.h
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef SLIDEWINDOW_H
-#define SLIDEWINDOW_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-typedef struct _slidewindow SlideWindow;
-
-extern SlideWindow *slide_window_open(struct presentation *p, SCBlock *scblocks,
- GApplication *app);
-
-extern void slide_window_update(SlideWindow *sw);
-
-#endif /* SLIDEWINDOW_H */
diff --git a/src-old/stylesheet.c b/src-old/stylesheet.c
deleted file mode 100644
index a6e2531..0000000
--- a/src-old/stylesheet.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * stylesheet.c
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <json-glib/json-glib.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <gio/gio.h>
-#include <gdk/gdk.h>
-
-#include "stylesheet.h"
-#include "utils.h"
-
-
-struct _stylesheet {
- JsonNode *root;
-};
-
-
-static int find_comma(const char *a)
-{
- int i = 0;
- int in_brackets = 0;
- size_t len = strlen(a);
-
- do {
- if ( (a[i] == ',') && !in_brackets ) return i;
- if ( a[i] == '(' ) in_brackets++;
- if ( a[i] == ')' ) in_brackets--;
- i++;
- } while ( i < len );
- return 0;
-}
-
-
-int parse_colour_duo(const char *a, GdkRGBA *col1, GdkRGBA *col2)
-{
- char *acopy;
- int cpos;
-
- acopy = strdup(a);
- if ( acopy == NULL ) return 1;
-
- cpos = find_comma(acopy);
- if ( cpos == 0 ) {
- fprintf(stderr, _("Invalid background gradient '%s'\n"), a);
- return 1;
- }
-
- acopy[cpos] = '\0';
-
- if ( gdk_rgba_parse(col1, acopy) != TRUE ) {
- fprintf(stderr, _("Failed to parse colour: %s\n"), acopy);
- }
- if ( gdk_rgba_parse(col2, &acopy[cpos+1]) != TRUE ) {
- fprintf(stderr, _("Failed to parse colour: %s\n"), &acopy[cpos+1]);
- }
-
- free(acopy);
- return 0;
-}
-
-
-Stylesheet *stylesheet_load(GFile *file)
-{
- JsonParser *parser;
- gboolean r;
- GError *err = NULL;
- Stylesheet *ss;
- char *everything;
- gsize len;
-
- printf("Trying stylesheet '%s'\n", g_file_get_uri(file));
-
- ss = calloc(1, sizeof(Stylesheet));
- if ( ss == NULL ) return NULL;
-
- parser = json_parser_new();
-
- if ( !g_file_load_contents(file, NULL, &everything, &len, NULL, NULL) ) {
- fprintf(stderr, _("Failed to load stylesheet '%s'\n"),
- g_file_get_uri(file));
- free(ss);
- return NULL;
- }
-
- r = json_parser_load_from_data(parser, everything, len, &err);
- if ( r == FALSE ) {
- fprintf(stderr, _("Failed to load stylesheet: %s\n"),
- err->message);
- free(ss);
- return NULL;
- }
-
- ss->root = json_parser_steal_root(parser);
- g_object_unref(parser);
-
- return ss;
-}
-
-
-static JsonObject *find_stylesheet_object(Stylesheet *ss, const char *path,
- JsonNode **freeme)
-{
- JsonNode *node;
- JsonObject *obj;
- JsonArray *array;
- GError *err = NULL;
-
- node = json_path_query(path, ss->root, &err);
- array = json_node_get_array(node);
-
- if ( json_array_get_length(array) == 0 ) {
- json_node_unref(node);
- return NULL;
- }
-
- if ( json_array_get_length(array) > 1 ) {
- json_node_unref(node);
- fprintf(stderr, "More than one result in SS lookup (%s)!\n", path);
- return NULL;
- }
-
- obj = json_array_get_object_element(array, 0);
- if ( obj == NULL ) {
- printf("%s not a JSON object\n", path);
- json_node_unref(node);
- return NULL;
- }
-
- *freeme = node;
- return obj;
-}
-
-
-char *stylesheet_lookup(Stylesheet *ss, const char *path, const char *key)
-{
- JsonObject *obj;
- char *ret = NULL;
- JsonNode *node = NULL;
-
- if ( ss == NULL ) {
- fprintf(stderr, "No stylesheet!\n");
- return NULL;
- }
-
- obj = find_stylesheet_object(ss, path, &node);
- if ( obj == NULL ) return NULL;
-
- if ( json_object_has_member(obj, key) ) {
-
- const gchar *v;
- v = json_object_get_string_member(obj, key);
- if ( v != NULL ) {
- ret = strdup(v);
- } else {
- fprintf(stderr, "Error retrieving %s.%s\n", path, key);
- }
-
- } /* else not found, too bad */
-
- if ( node != NULL ) json_node_unref(node);
- return ret;
-}
-
-
-int stylesheet_set(Stylesheet *ss, const char *path, const char *key,
- const char *new_val)
-{
- JsonObject *obj;
- JsonNode *node = NULL;
- int r = 1;
-
- if ( ss == NULL ) {
- fprintf(stderr, "No stylesheet!\n");
- return 1;
- }
-
- obj = find_stylesheet_object(ss, path, &node);
- if ( obj != NULL ) {
- json_object_set_string_member(obj, key, new_val);
- r = 0;
- } /* else most likely the object (e.g. "$.slide", "$.slide.frame",
- * "$.narrative" etc doesn't exist */
-
- if ( node != NULL ) json_node_unref(node);
- return r;
-}
-
-
-int stylesheet_delete(Stylesheet *ss, const char *path, const char *key)
-{
- JsonObject *obj;
- JsonNode *node = NULL;
- int r = 1;
-
- if ( ss == NULL ) {
- fprintf(stderr, "No stylesheet!\n");
- return 1;
- }
-
- obj = find_stylesheet_object(ss, path, &node);
- if ( obj != NULL ) {
- json_object_remove_member(obj, key);
- r = 0;
- } /* else most likely the object (e.g. "$.slide", "$.slide.frame",
- * "$.narrative" etc doesn't exist */
-
- if ( node != NULL ) json_node_unref(node);
- return r;
-}
-
-
-void stylesheet_free(Stylesheet *ss)
-{
- json_node_unref(ss->root);
- free(ss);
-}
-
-
-int stylesheet_save(Stylesheet *ss, GFile *file)
-{
- JsonGenerator *gen;
- GError *error = NULL;
- GFileOutputStream *fh;
-
- fh = g_file_replace(file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error);
- if ( fh == NULL ) {
- fprintf(stderr, _("Open failed: %s\n"), error->message);
- return 1;
- }
-
- gen = json_generator_new();
- json_generator_set_root(gen, ss->root);
- json_generator_set_pretty(gen, TRUE);
- json_generator_set_indent(gen, 1);
- json_generator_set_indent_char(gen, '\t');
- if ( !json_generator_to_stream(gen, G_OUTPUT_STREAM(fh), NULL, &error) ) {
- fprintf(stderr, _("Open failed: %s\n"), error->message);
- return 1;
- }
- g_object_unref(fh);
- return 0;
-}
-
-
-char *stylesheet_data(Stylesheet *ss)
-{
- return json_to_string(ss->root, FALSE);
-}
-
-
-void stylesheet_set_data(Stylesheet *ss, const char *data)
-{
- JsonNode *new_root;
- GError *err = NULL;
- new_root = json_from_string(data, &err);
- if ( new_root == NULL ) {
- fprintf(stderr, "Internal parse error: %s\n", err->message);
- return;
- }
- json_node_unref(ss->root);
- ss->root = new_root;
-}
diff --git a/src-old/stylesheet.h b/src-old/stylesheet.h
deleted file mode 100644
index 16d0a0a..0000000
--- a/src-old/stylesheet.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * stylesheet.h
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef STYLESHEET_H
-#define STYLESHEET_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gio/gio.h>
-#include <gdk/gdk.h>
-
-typedef struct _stylesheet Stylesheet;
-
-extern Stylesheet *stylesheet_load(GFile *file);
-
-extern int stylesheet_save(Stylesheet *ss, GFile *file);
-
-extern char *stylesheet_data(Stylesheet *ss);
-
-extern void stylesheet_set_data(Stylesheet *ss, const char *data);
-
-extern int parse_colour_duo(const char *a, GdkRGBA *col1, GdkRGBA *col2);
-
-extern char *stylesheet_lookup(Stylesheet *ss, const char *path, const char *key);
-
-extern int stylesheet_set(Stylesheet *ss, const char *path, const char *key,
- const char *new_val);
-
-extern int stylesheet_delete(Stylesheet *ss, const char *path, const char *key);
-
-extern void stylesheet_free(Stylesheet *ss);
-
-#endif /* STYLESHEET_H */
diff --git a/src-old/stylesheet_editor.c b/src-old/stylesheet_editor.c
deleted file mode 100644
index 292bbf1..0000000
--- a/src-old/stylesheet_editor.c
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * stylesheet_editor.c
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <gtk/gtk.h>
-
-#include "stylesheet_editor.h"
-#include "presentation.h"
-#include "sc_interp.h"
-#include "stylesheet.h"
-#include "utils.h"
-
-
-G_DEFINE_TYPE_WITH_CODE(StylesheetEditor, stylesheet_editor,
- GTK_TYPE_DIALOG, NULL)
-
-
-struct _sspriv
-{
- struct presentation *p;
- const gchar *furniture;
- char *ssdata;
-};
-
-
-static void set_font_from_ss(Stylesheet *ss, const char *path, GtkWidget *w)
-{
- char *result = stylesheet_lookup(ss, path, "font");
- if ( result != NULL ) {
- gtk_font_button_set_font_name(GTK_FONT_BUTTON(w), result);
- }
-}
-
-
-static void set_col_from_ss(Stylesheet *ss, const char *path, GtkWidget *w)
-{
- char *result = stylesheet_lookup(ss, path, "fgcol");
- if ( result != NULL ) {
- GdkRGBA rgba;
- if ( gdk_rgba_parse(&rgba, result) == TRUE ) {
- gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(w), &rgba);
- }
- }
-}
-
-
-static void set_vals_from_ss(Stylesheet *ss, const char *path, const char *key,
- GtkWidget *wl, GtkWidget *wr,
- GtkWidget *wt, GtkWidget *wb)
-{
- char *result = stylesheet_lookup(ss, path, key);
- if ( result != NULL ) {
- float v[4];
- if ( parse_tuple(result, v) == 0 ) {
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(wl), v[0]);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(wr), v[1]);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(wt), v[2]);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(wb), v[3]);
- } else {
- fprintf(stderr, _("Failed to parse quad: %s\n"), result);
- }
- } else {
- printf("Not found %s.%s\n", path, key);
- }
-}
-
-
-static void set_geom_from_ss(Stylesheet *ss, const char *path, const char *key,
- GtkWidget *ww, GtkWidget *wh,
- GtkWidget *wx, GtkWidget *wy,
- GtkWidget *wwu, GtkWidget *whu)
-{
- char *result = stylesheet_lookup(ss, path, key);
- if ( result != NULL ) {
- double x, y, w, h;
- LengthUnits wu, hu;
- if ( parse_dims(result, &w, &h, &wu, &hu, &x, &y) == 0 ) {
- if ( wu == UNITS_FRAC ) {
- w *= 100;
- gtk_combo_box_set_active_id(GTK_COMBO_BOX(wwu), "percent");
- } else {
- gtk_combo_box_set_active_id(GTK_COMBO_BOX(wwu), "units");
- }
- if ( hu == UNITS_FRAC ) {
- h *= 100;
- gtk_combo_box_set_active_id(GTK_COMBO_BOX(whu), "percent");
- } else {
- gtk_combo_box_set_active_id(GTK_COMBO_BOX(whu), "units");
- }
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(ww), w);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(wh), h);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(wx), x);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(wy), y);
- } else {
- fprintf(stderr, _("Failed to parse dims: %s\n"), result);
- }
- } else {
- printf("Not found %s.%s\n", path, key);
- }
-}
-
-static void set_size_from_ss(Stylesheet *ss, const char *path,
- GtkWidget *ww, GtkWidget *wh)
-{
- char *result = stylesheet_lookup(ss, path, "size");
- if ( result != NULL ) {
- float v[2];
- if ( parse_double(result, v) == 0 ) {
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(ww), v[0]);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(wh), v[1]);
- } else {
- fprintf(stderr, _("Failed to parse double: %s\n"), result);
- }
- } else {
- printf("Not found %s.size\n", path);
- }
-}
-
-
-static int alignment_ok(const char *a)
-{
- if ( a == NULL ) return 0;
- if ( strcmp(a, "left") == 0 ) return 1;
- if ( strcmp(a, "center") == 0 ) return 1;
- if ( strcmp(a, "right") == 0 ) return 1;
- return 0;
-}
-
-
-static void set_alignment_from_ss(Stylesheet *ss, const char *path,
- GtkWidget *d)
-{
- char *result = stylesheet_lookup(ss, path, "alignment");
- if ( alignment_ok(result) ) {
- gtk_combo_box_set_active_id(GTK_COMBO_BOX(d), result);
- }
-}
-
-
-static void set_bg_from_ss(Stylesheet *ss, const char *path, GtkWidget *wcol,
- GtkWidget *wcol2, GtkWidget *wgrad)
-{
- char *result;
- int found = 0;
-
- result = stylesheet_lookup(ss, path, "bgcol");
- if ( result != NULL ) {
- GdkRGBA rgba;
- found = 1;
- if ( gdk_rgba_parse(&rgba, result) == TRUE ) {
- gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol), &rgba);
- gtk_combo_box_set_active_id(GTK_COMBO_BOX(wgrad), "flat");
- gtk_widget_set_sensitive(wcol, TRUE);
- gtk_widget_set_sensitive(wcol2, FALSE);
- } else {
- fprintf(stderr, _("Failed to parse colour: %s\n"), result);
- }
- }
-
- result = stylesheet_lookup(ss, path, "bggradv");
- if ( result != NULL ) {
- GdkRGBA rgba1, rgba2;
- found = 1;
- if ( parse_colour_duo(result, &rgba1, &rgba2) == 0 ) {
- gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol), &rgba1);
- gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol2), &rgba2);
- gtk_combo_box_set_active_id(GTK_COMBO_BOX(wgrad), "vert");
- gtk_widget_set_sensitive(wcol, TRUE);
- gtk_widget_set_sensitive(wcol2, TRUE);
- }
- }
-
- result = stylesheet_lookup(ss, path, "bggradh");
- if ( result != NULL ) {
- GdkRGBA rgba1, rgba2;
- found = 1;
- if ( parse_colour_duo(result, &rgba1, &rgba2) == 0 ) {
- gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol), &rgba1);
- gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol2), &rgba2);
- gtk_combo_box_set_active_id(GTK_COMBO_BOX(wgrad), "horiz");
- gtk_widget_set_sensitive(wcol, TRUE);
- gtk_widget_set_sensitive(wcol2, TRUE);
- }
- }
-
- if ( !found ) {
- GdkRGBA rgba;
- rgba.red = 1.0;
- rgba.green = 1.0;
- rgba.blue = 1.0;
- rgba.alpha = 0.0;
- gtk_combo_box_set_active_id(GTK_COMBO_BOX(wgrad), "flat");
- gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(wcol), &rgba);
- gtk_widget_set_sensitive(wcol, TRUE);
- gtk_widget_set_sensitive(wcol2, FALSE);
- }
-}
-
-
-static void set_furniture(StylesheetEditor *se, const char *furniture)
-{
- set_geom_from_ss(se->priv->p->stylesheet, furniture, "geometry",
- se->furniture_w,
- se->furniture_h,
- se->furniture_x,
- se->furniture_y,
- se->furniture_w_units,
- se->furniture_h_units);
-
- set_vals_from_ss(se->priv->p->stylesheet, furniture, "pad",
- se->furniture_padding_l,
- se->furniture_padding_r,
- se->furniture_padding_t,
- se->furniture_padding_b);
-
- set_vals_from_ss(se->priv->p->stylesheet, furniture, "paraspace",
- se->furniture_paraspace_l,
- se->furniture_paraspace_r,
- se->furniture_paraspace_t,
- se->furniture_paraspace_b);
-
- set_font_from_ss(se->priv->p->stylesheet, furniture, se->furniture_font);
- set_col_from_ss(se->priv->p->stylesheet, furniture, se->furniture_fgcol);
- set_alignment_from_ss(se->priv->p->stylesheet, furniture,
- se->furniture_alignment);
- set_bg_from_ss(se->priv->p->stylesheet, furniture, se->furniture_bgcol,
- se->furniture_bgcol2, se->furniture_bggrad);
-}
-
-
-static void set_values_from_presentation(StylesheetEditor *se)
-{
- Stylesheet *ss = se->priv->p->stylesheet;
-
- /* Narrative */
- set_font_from_ss(ss, "$.narrative", se->narrative_style_font);
- set_col_from_ss(ss, "$.narrative", se->narrative_style_fgcol);
- set_alignment_from_ss(ss, "$.narrative", se->narrative_style_alignment);
- set_bg_from_ss(ss, "$.narrative", se->narrative_style_bgcol,
- se->narrative_style_bgcol2,
- se->narrative_style_bggrad);
- set_vals_from_ss(ss, "$.narrative", "pad", se->narrative_style_padding_l,
- se->narrative_style_padding_r,
- se->narrative_style_padding_t,
- se->narrative_style_padding_b);
- set_vals_from_ss(ss, "$.narrative", "paraspace", se->narrative_style_paraspace_l,
- se->narrative_style_paraspace_r,
- se->narrative_style_paraspace_t,
- se->narrative_style_paraspace_b);
-
- /* Slides */
- set_size_from_ss(ss, "$.slide", se->slide_size_w, se->slide_size_h);
- set_bg_from_ss(ss, "$.slide", se->slide_style_bgcol,
- se->slide_style_bgcol2,
- se->slide_style_bggrad);
-
-
- /* Frames */
- set_font_from_ss(ss, "$.slide.frame", se->frame_style_font);
- set_col_from_ss(ss, "$.slide.frame", se->frame_style_fgcol);
- set_alignment_from_ss(ss, "$.slide.frame", se->frame_style_alignment);
- set_bg_from_ss(ss, "$.slide.frame", se->frame_style_bgcol,
- se->frame_style_bgcol2,
- se->frame_style_bggrad);
- set_vals_from_ss(ss, "$.slide.frame", "pad", se->frame_style_padding_l,
- se->frame_style_padding_r,
- se->frame_style_padding_t,
- se->frame_style_padding_b);
- set_vals_from_ss(ss, "$.slide.frame", "paraspace", se->frame_style_paraspace_l,
- se->frame_style_paraspace_r,
- se->frame_style_paraspace_t,
- se->frame_style_paraspace_b);
-
- set_furniture(se, se->priv->furniture);
-}
-
-
-static GradientType id_to_gradtype(const gchar *id)
-{
- assert(id != NULL);
- if ( strcmp(id, "flat") == 0 ) return GRAD_NONE;
- if ( strcmp(id, "horiz") == 0 ) return GRAD_HORIZ;
- if ( strcmp(id, "vert") == 0 ) return GRAD_VERT;
- return GRAD_NONE;
-}
-
-
-static void update_bg(struct presentation *p, const char *style_name,
- GtkWidget *bggradw, GtkWidget *col1w, GtkWidget*col2w)
-{
- GradientType g;
- const gchar *id;
- GdkRGBA rgba;
- gchar *col1;
- gchar *col2;
- gchar *gradient;
-
- id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(bggradw));
- g = id_to_gradtype(id);
-
- gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(col1w), &rgba);
- if ( rgba.alpha < 0.000001 ) rgba.alpha = 0.0;
- col1 = gdk_rgba_to_string(&rgba);
-
- gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(col2w), &rgba);
- col2 = gdk_rgba_to_string(&rgba);
-
- gradient = g_strconcat(col1, ",", col2, NULL);
-
- switch ( g ) {
-
- case GRAD_NONE :
- stylesheet_set(p->stylesheet, style_name, "bgcol",
- col1);
- stylesheet_delete(p->stylesheet, style_name, "bggradv");
- stylesheet_delete(p->stylesheet, style_name, "bggradh");
- break;
-
- case GRAD_HORIZ :
- stylesheet_set(p->stylesheet, style_name, "bggradh",
- gradient);
- stylesheet_delete(p->stylesheet, style_name, "bggradv");
- stylesheet_delete(p->stylesheet, style_name, "bgcol");
- break;
-
- case GRAD_VERT :
- stylesheet_set(p->stylesheet, style_name, "bggradv",
- gradient);
- stylesheet_delete(p->stylesheet, style_name, "bggradh");
- stylesheet_delete(p->stylesheet, style_name, "bgcol");
- break;
-
- }
-
- g_free(gradient);
- g_free(col1);
- g_free(col2);
-}
-
-
-static void update_spacing(struct presentation *p, const char *style_name,
- const char *key, GtkWidget *wl, GtkWidget *wr,
- GtkWidget *wt, GtkWidget *wb)
-{
- int v[4];
- char tmp[256];
-
- v[0] = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(wl));
- v[1] = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(wr));
- v[2] = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(wt));
- v[3] = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(wb));
-
- if ( snprintf(tmp, 256, "%i,%i,%i,%i", v[0], v[1], v[2], v[3]) >= 256 ) {
- fprintf(stderr, "Spacing too long\n");
- } else {
- stylesheet_set(p->stylesheet, style_name, key, tmp);
- }
-}
-
-
-static char units_id_to_char(const char *id)
-{
- if ( strcmp(id, "units") == 0 ) return 'u';
- if ( strcmp(id, "percent") == 0 ) return 'f';
- return 'u';
-}
-
-
-static void update_ss_dims(struct presentation *p, const char *style_name,
- const char *key, GtkWidget *ww, GtkWidget *wh,
- GtkWidget *wx, GtkWidget *wy,
- GtkWidget *wwu, GtkWidget *whu)
-{
- float w, h, x, y;
- char w_units, h_units;
- const gchar *uid;
- char tmp[256];
-
- w = gtk_spin_button_get_value(GTK_SPIN_BUTTON(ww));
- h = gtk_spin_button_get_value(GTK_SPIN_BUTTON(wh));
- x = gtk_spin_button_get_value(GTK_SPIN_BUTTON(wx));
- y = gtk_spin_button_get_value(GTK_SPIN_BUTTON(wy));
- uid = gtk_combo_box_get_active_id(GTK_COMBO_BOX(wwu));
- w_units = units_id_to_char(uid);
- uid = gtk_combo_box_get_active_id(GTK_COMBO_BOX(whu));
- h_units = units_id_to_char(uid);
-
- if ( w_units == 'f' ) w /= 100.0;
- if ( h_units == 'f' ) h /= 100.0;
-
- if ( snprintf(tmp, 256, "%.2f%cx%.2f%c+%.0f+%0.f",
- w, w_units, h, h_units, x, y) >= 256 )
- {
- fprintf(stderr, "Spacing too long\n");
- } else {
- stylesheet_set(p->stylesheet, style_name, key, tmp);
- }
-}
-
-
-static void revert_sig(GtkButton *button, StylesheetEditor *se)
-{
- stylesheet_set_data(se->priv->p->stylesheet,
- se->priv->ssdata);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void set_font(GtkFontButton *widget, StylesheetEditor *se,
- const char *style_name)
-{
- const gchar *font;
- font = gtk_font_button_get_font_name(GTK_FONT_BUTTON(widget));
-
- stylesheet_set(se->priv->p->stylesheet, style_name, "font", font);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void set_col(GtkColorButton *widget, StylesheetEditor *se,
- const char *style_name, const char *col_name)
-{
- GdkRGBA rgba;
- gchar *col;
- gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(widget), &rgba);
- col = gdk_rgba_to_string(&rgba);
- stylesheet_set(se->priv->p->stylesheet, style_name, "fgcol", col);
- g_free(col);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void narrative_font_sig(GtkFontButton *widget, StylesheetEditor *se)
-{
- set_font(widget, se, "$.narrative");
-}
-
-
-static void narrative_fgcol_sig(GtkColorButton *widget, StylesheetEditor *se)
-{
- set_col(widget, se, "$.narrative", "fgcol");
-}
-
-
-static void narrative_bg_sig(GtkColorButton *widget, StylesheetEditor *se)
-{
- update_bg(se->priv->p, "$.narrative",
- se->narrative_style_bggrad,
- se->narrative_style_bgcol,
- se->narrative_style_bgcol2);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void narrative_alignment_sig(GtkComboBoxText *widget, StylesheetEditor *se)
-{
- const gchar *id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widget));
- stylesheet_set(se->priv->p->stylesheet, "$.narrative", "alignment", id);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void slide_size_sig(GtkSpinButton *widget, StylesheetEditor *se)
-{
- int w, h;
- char tmp[256];
-
- w = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(se->slide_size_w));
- h = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(se->slide_size_h));
-
- if ( snprintf(tmp, 256, "%ix%i", w, h) >= 256 ) {
- fprintf(stderr, _("Slide size too long\n"));
- } else {
- stylesheet_set(se->priv->p->stylesheet, "$.slide", "size", tmp);
- se->priv->p->slide_width = w;
- se->priv->p->slide_height = h;
- }
-
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void slide_bg_sig(GtkColorButton *widget, StylesheetEditor *se)
-{
- update_bg(se->priv->p, "$.slide",
- se->slide_style_bggrad,
- se->slide_style_bgcol,
- se->slide_style_bgcol2);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void frame_font_sig(GtkFontButton *widget, StylesheetEditor *se)
-{
- set_font(widget, se, "$.slide.frame");
-}
-
-
-static void frame_fgcol_sig(GtkColorButton *widget, StylesheetEditor *se)
-{
- set_col(widget, se, "$.slide.frame", "fgcol");
-}
-
-
-static void frame_bg_sig(GtkColorButton *widget, StylesheetEditor *se)
-{
- update_bg(se->priv->p, "$.slide.frame",
- se->frame_style_bggrad,
- se->frame_style_bgcol,
- se->frame_style_bgcol2);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void frame_padding_sig(GtkSpinButton *widget, StylesheetEditor *se)
-{
- update_spacing(se->priv->p, "$.slide.frame", "pad",
- se->frame_style_padding_l,
- se->frame_style_padding_r,
- se->frame_style_padding_t,
- se->frame_style_padding_b);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void frame_paraspace_sig(GtkSpinButton *widget, StylesheetEditor *se)
-{
- update_spacing(se->priv->p, "$.slide.frame", "paraspace",
- se->frame_style_paraspace_l,
- se->frame_style_paraspace_r,
- se->frame_style_paraspace_t,
- se->frame_style_paraspace_b);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void frame_alignment_sig(GtkComboBoxText *widget, StylesheetEditor *se)
-{
- const gchar *id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widget));
- stylesheet_set(se->priv->p->stylesheet, "$.slide.frame", "alignment", id);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void narrative_padding_sig(GtkSpinButton *widget, StylesheetEditor *se)
-{
- update_spacing(se->priv->p, "$.narrative", "pad",
- se->narrative_style_padding_l,
- se->narrative_style_padding_r,
- se->narrative_style_padding_t,
- se->narrative_style_padding_b);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void narrative_paraspace_sig(GtkSpinButton *widget, StylesheetEditor *se)
-{
- update_spacing(se->priv->p, "$.narrative", "paraspace",
- se->narrative_style_paraspace_l,
- se->narrative_style_paraspace_r,
- se->narrative_style_paraspace_t,
- se->narrative_style_paraspace_b);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void furniture_selector_change_sig(GtkComboBoxText *widget, StylesheetEditor *se)
-{
- se->priv->furniture = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widget));
- set_furniture(se, se->priv->furniture);
-}
-
-
-static void furniture_font_sig(GtkFontButton *widget, StylesheetEditor *se)
-{
- set_font(widget, se, se->priv->furniture);
-}
-
-
-static void furniture_fgcol_sig(GtkColorButton *widget, StylesheetEditor *se)
-{
- set_col(widget, se,se->priv->furniture, "fgcol");
-}
-
-
-static void furniture_bg_sig(GtkColorButton *widget, StylesheetEditor *se)
-{
- update_bg(se->priv->p, se->priv->furniture, se->furniture_bggrad,
- se->furniture_bgcol, se->furniture_bgcol2);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void furniture_paraspace_sig(GtkSpinButton *widget, StylesheetEditor *se)
-{
- update_spacing(se->priv->p, se->priv->furniture, "pad",
- se->furniture_padding_l,
- se->furniture_padding_r,
- se->furniture_padding_t,
- se->furniture_padding_b);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void furniture_padding_sig(GtkSpinButton *widget, StylesheetEditor *se)
-{
- update_spacing(se->priv->p, se->priv->furniture, "pad",
- se->furniture_padding_l,
- se->furniture_padding_r,
- se->furniture_padding_t,
- se->furniture_padding_b);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void furniture_alignment_sig(GtkComboBoxText *widget, StylesheetEditor *se)
-{
- const gchar *id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(widget));
- stylesheet_set(se->priv->p->stylesheet, se->priv->furniture,
- "alignment", id);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void furniture_dims_sig(GtkSpinButton *widget, StylesheetEditor *se)
-{
- update_ss_dims(se->priv->p, se->priv->furniture, "geometry",
- se->furniture_w, se->furniture_h,
- se->furniture_x, se->furniture_y,
- se->furniture_w_units, se->furniture_h_units);
- set_values_from_presentation(se);
- g_signal_emit_by_name(se, "changed");
-}
-
-
-static void stylesheet_editor_finalize(GObject *obj)
-{
- StylesheetEditor *se = COLLOQUIUM_STYLESHEET_EDITOR(obj);
- free(se->priv->ssdata);
- G_OBJECT_CLASS(stylesheet_editor_parent_class)->finalize(obj);
-}
-
-
-static void stylesheet_editor_init(StylesheetEditor *se)
-{
- se->priv = G_TYPE_INSTANCE_GET_PRIVATE(se, COLLOQUIUM_TYPE_STYLESHEET_EDITOR,
- StylesheetEditorPrivate);
- gtk_widget_init_template(GTK_WIDGET(se));
-}
-
-
-#define SE_BIND_CHILD(a, b) \
- gtk_widget_class_bind_template_child(widget_class, StylesheetEditor, a); \
- gtk_widget_class_bind_template_callback(widget_class, b);
-
-void stylesheet_editor_class_init(StylesheetEditorClass *klass)
-{
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
-
- gtk_widget_class_set_template_from_resource(widget_class,
- "/uk/me/bitwiz/Colloquium/stylesheeteditor.ui");
-
- g_type_class_add_private(gobject_class, sizeof(StylesheetEditorPrivate));
- gobject_class->finalize = stylesheet_editor_finalize;
-
- /* Narrative style */
- SE_BIND_CHILD(narrative_style_font, narrative_font_sig);
- SE_BIND_CHILD(narrative_style_fgcol, narrative_fgcol_sig);
- SE_BIND_CHILD(narrative_style_bgcol, narrative_bg_sig);
- SE_BIND_CHILD(narrative_style_bgcol2, narrative_bg_sig);
- SE_BIND_CHILD(narrative_style_bggrad, narrative_bg_sig);
- SE_BIND_CHILD(narrative_style_paraspace_l, narrative_paraspace_sig);
- SE_BIND_CHILD(narrative_style_paraspace_r, narrative_paraspace_sig);
- SE_BIND_CHILD(narrative_style_paraspace_t, narrative_paraspace_sig);
- SE_BIND_CHILD(narrative_style_paraspace_b, narrative_paraspace_sig);
- SE_BIND_CHILD(narrative_style_padding_l, narrative_padding_sig);
- SE_BIND_CHILD(narrative_style_padding_r, narrative_padding_sig);
- SE_BIND_CHILD(narrative_style_padding_t, narrative_padding_sig);
- SE_BIND_CHILD(narrative_style_padding_b, narrative_padding_sig);
- SE_BIND_CHILD(narrative_style_alignment, narrative_alignment_sig);
-
- /* Slide style */
- SE_BIND_CHILD(slide_size_w, slide_size_sig);
- SE_BIND_CHILD(slide_size_h, slide_size_sig);
- SE_BIND_CHILD(slide_style_bgcol, slide_bg_sig);
- SE_BIND_CHILD(slide_style_bgcol2, slide_bg_sig);
- SE_BIND_CHILD(slide_style_bggrad, slide_bg_sig);
-
- /* Slide->frame style */
- SE_BIND_CHILD(frame_style_font, frame_font_sig);
- SE_BIND_CHILD(frame_style_fgcol, frame_fgcol_sig);
- SE_BIND_CHILD(frame_style_bgcol, frame_bg_sig);
- SE_BIND_CHILD(frame_style_bgcol2, frame_bg_sig);
- SE_BIND_CHILD(frame_style_bggrad, frame_bg_sig);
- SE_BIND_CHILD(frame_style_paraspace_l, frame_paraspace_sig);
- SE_BIND_CHILD(frame_style_paraspace_r, frame_paraspace_sig);
- SE_BIND_CHILD(frame_style_paraspace_t, frame_paraspace_sig);
- SE_BIND_CHILD(frame_style_paraspace_b, frame_paraspace_sig);
- SE_BIND_CHILD(frame_style_padding_l, frame_padding_sig);
- SE_BIND_CHILD(frame_style_padding_r, frame_padding_sig);
- SE_BIND_CHILD(frame_style_padding_t, frame_padding_sig);
- SE_BIND_CHILD(frame_style_padding_b, frame_padding_sig);
- SE_BIND_CHILD(frame_style_alignment, frame_alignment_sig);
-
- /* Furniture */
- SE_BIND_CHILD(furniture_selector, furniture_selector_change_sig);
- SE_BIND_CHILD(furniture_paraspace_l, furniture_paraspace_sig);
- SE_BIND_CHILD(furniture_paraspace_r, furniture_paraspace_sig);
- SE_BIND_CHILD(furniture_paraspace_t, furniture_paraspace_sig);
- SE_BIND_CHILD(furniture_paraspace_b, furniture_paraspace_sig);
- SE_BIND_CHILD(furniture_padding_l, furniture_padding_sig);
- SE_BIND_CHILD(furniture_padding_r, furniture_padding_sig);
- SE_BIND_CHILD(furniture_padding_t, furniture_padding_sig);
- SE_BIND_CHILD(furniture_padding_b, furniture_padding_sig);
- SE_BIND_CHILD(furniture_font, furniture_font_sig);
- SE_BIND_CHILD(furniture_fgcol, furniture_fgcol_sig);
- SE_BIND_CHILD(furniture_bgcol, furniture_bg_sig);
- SE_BIND_CHILD(furniture_bgcol2, furniture_bg_sig);
- SE_BIND_CHILD(furniture_bggrad, furniture_bg_sig);
- SE_BIND_CHILD(furniture_alignment, furniture_alignment_sig);
- SE_BIND_CHILD(furniture_w, furniture_dims_sig);
- SE_BIND_CHILD(furniture_h, furniture_dims_sig);
- SE_BIND_CHILD(furniture_x, furniture_dims_sig);
- SE_BIND_CHILD(furniture_y, furniture_dims_sig);
- SE_BIND_CHILD(furniture_w_units, furniture_dims_sig);
- SE_BIND_CHILD(furniture_h_units, furniture_dims_sig);
-
- gtk_widget_class_bind_template_callback(widget_class, revert_sig);
-
- g_signal_new("changed", COLLOQUIUM_TYPE_STYLESHEET_EDITOR,
- G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
-}
-
-
-StylesheetEditor *stylesheet_editor_new(struct presentation *p)
-{
- StylesheetEditor *se;
-
- se = g_object_new(COLLOQUIUM_TYPE_STYLESHEET_EDITOR, NULL);
- if ( se == NULL ) return NULL;
-
- se->priv->p = p;
- se->priv->furniture = gtk_combo_box_get_active_id(GTK_COMBO_BOX(se->furniture_selector));
- set_values_from_presentation(se);
-
- se->priv->ssdata = stylesheet_data(p->stylesheet);
-
- return se;
-}
-
diff --git a/src-old/stylesheet_editor.h b/src-old/stylesheet_editor.h
deleted file mode 100644
index a7c77b6..0000000
--- a/src-old/stylesheet_editor.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * stylesheet_editor.h
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef STYLESHEET_EDITOR_H
-#define STYLESHEET_EDITOR_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtk.h>
-
-#include "presentation.h"
-#include "frame.h"
-
-#define COLLOQUIUM_TYPE_STYLESHEET_EDITOR (stylesheet_editor_get_type())
-
-#define COLLOQUIUM_STYLESHEET_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
- COLLOQUIUM_TYPE_STYLESHEET_EDITOR, \
- StylesheetEditor))
-
-#define COLLOQUIUM_IS_STYLESHEET_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
- COLLOQUIUM_TYPE_STYLESHEET_EDITOR))
-
-#define COLLOQUIUM_STYLESHEET_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((obj), \
- COLLOQUIUM_TYPE_STYLESHEET_EDITOR, \
- StylesheetEditorClass))
-
-#define COLLOQUIUM_IS_STYLESHEET_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), \
- COLLOQUIUM_TYPE_STYLESHEET_EDITOR))
-
-#define COLLOQUIUM_STYLESHEET_EDITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
- COLLOQUIUM_TYPE_STYLESHEET_EDITOR, \
- StylesheetEditorClass))
-
-
-typedef struct _sspriv StylesheetEditorPrivate;
-
-struct _stylesheeteditor
-{
- GtkDialog parent_instance;
- GtkWidget *narrative_style_font;
- GtkWidget *narrative_style_fgcol;
- GtkWidget *narrative_style_bgcol;
- GtkWidget *narrative_style_bgcol2;
- GtkWidget *narrative_style_bggrad;
- GtkWidget *narrative_style_paraspace_l;
- GtkWidget *narrative_style_paraspace_r;
- GtkWidget *narrative_style_paraspace_t;
- GtkWidget *narrative_style_paraspace_b;
- GtkWidget *narrative_style_padding_l;
- GtkWidget *narrative_style_padding_r;
- GtkWidget *narrative_style_padding_t;
- GtkWidget *narrative_style_padding_b;
- GtkWidget *narrative_style_alignment;
- GtkWidget *slide_size_w;
- GtkWidget *slide_size_h;
- GtkWidget *slide_style_bgcol;
- GtkWidget *slide_style_bgcol2;
- GtkWidget *slide_style_bggrad;
- GtkWidget *frame_style_font;
- GtkWidget *frame_style_fgcol;
- GtkWidget *frame_style_bgcol;
- GtkWidget *frame_style_bgcol2;
- GtkWidget *frame_style_bggrad;
- GtkWidget *frame_style_paraspace_l;
- GtkWidget *frame_style_paraspace_r;
- GtkWidget *frame_style_paraspace_t;
- GtkWidget *frame_style_paraspace_b;
- GtkWidget *frame_style_padding_l;
- GtkWidget *frame_style_padding_r;
- GtkWidget *frame_style_padding_t;
- GtkWidget *frame_style_padding_b;
- GtkWidget *frame_style_alignment;
- GtkWidget *furniture_selector;
- GtkWidget *furniture_paraspace_l;
- GtkWidget *furniture_paraspace_r;
- GtkWidget *furniture_paraspace_t;
- GtkWidget *furniture_paraspace_b;
- GtkWidget *furniture_padding_l;
- GtkWidget *furniture_padding_r;
- GtkWidget *furniture_padding_t;
- GtkWidget *furniture_padding_b;
- GtkWidget *furniture_font;
- GtkWidget *furniture_fgcol;
- GtkWidget *furniture_bgcol;
- GtkWidget *furniture_bgcol2;
- GtkWidget *furniture_bggrad;
- GtkWidget *furniture_alignment;
- GtkWidget *furniture_w;
- GtkWidget *furniture_h;
- GtkWidget *furniture_x;
- GtkWidget *furniture_y;
- GtkWidget *furniture_w_units;
- GtkWidget *furniture_h_units;
- StylesheetEditorPrivate *priv;
-};
-
-struct _stylesheeteditorclass
-{
- GtkDialogClass parent_class;
-};
-
-typedef struct _stylesheeteditor StylesheetEditor;
-typedef struct _stylesheeteditorclass StylesheetEditorClass;
-
-extern StylesheetEditor *stylesheet_editor_new(struct presentation *p);
-
-#endif /* STYLESHEET_EDITOR_H */
diff --git a/src-old/utils.c b/src-old/utils.c
deleted file mode 100644
index b41f344..0000000
--- a/src-old/utils.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * utils.c
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "utils.h"
-
-void chomp(char *s)
-{
- size_t i;
-
- if ( !s ) return;
-
- for ( i=0; i<strlen(s); i++ ) {
- if ( (s[i] == '\n') || (s[i] == '\r') ) {
- s[i] = '\0';
- return;
- }
- }
-}
-
-
-int safe_strcmp(const char *a, const char *b)
-{
- if ( a == NULL ) return 1;
- if ( b == NULL ) return 1;
- return strcmp(a, b);
-}
-
-
-int parse_double(const char *a, float v[2])
-{
- int nn;
-
- nn = sscanf(a, "%fx%f", &v[0], &v[1]);
- if ( nn != 2 ) {
- fprintf(stderr, _("Invalid size '%s'\n"), a);
- return 1;
- }
-
- return 0;
-}
-
-
-int parse_tuple(const char *a, float v[4])
-{
- int nn;
-
- nn = sscanf(a, "%f,%f,%f,%f", &v[0], &v[1], &v[2], &v[3]);
- if ( nn != 4 ) {
- fprintf(stderr, _("Invalid tuple '%s'\n"), a);
- return 1;
- }
-
- return 0;
-}
-
-
-static LengthUnits get_units(const char *t)
-{
- size_t len = strlen(t);
-
- if ( t[len-1] == 'f' ) return UNITS_FRAC;
- if ( t[len-1] == 'u' ) return UNITS_SLIDE;
-
- fprintf(stderr, _("Invalid units in '%s'\n"), t);
- return UNITS_SLIDE;
-}
-
-
-int parse_dims(const char *opt, double *wp, double *hp,
- LengthUnits *wup, LengthUnits *hup,
- double *xp, double *yp)
-{
- char *w;
- char *h;
- char *x;
- char *y;
- char *check;
-
- w = strdup(opt);
- h = index(w, 'x');
- h[0] = '\0'; h++;
-
- x = index(h, '+');
- if ( x == NULL ) goto invalid;
- x[0] = '\0'; x++;
-
- y = index(x, '+');
- if ( x == NULL ) goto invalid;
- y[0] = '\0'; y++;
-
- *wp = strtod(w, &check);
- if ( check == w ) goto invalid;
- *wup = get_units(w);
-
- *hp = strtod(h, &check);
- if ( check == h ) goto invalid;
- *hup = get_units(h);
-
- *xp= strtod(x, &check);
- if ( check == x ) goto invalid;
- *yp = strtod(y, &check);
- if ( check == y ) goto invalid;
-
- return 0;
-
-invalid:
- fprintf(stderr, _("Invalid dimensions '%s'\n"), opt);
- return 1;
-}
diff --git a/src-old/utils.h b/src-old/utils.h
deleted file mode 100644
index af3c7b8..0000000
--- a/src-old/utils.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * utils.h
- *
- * Copyright © 2013-2018 Thomas White <taw@bitwiz.org.uk>
- *
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef UTILS_H
-#define UTILS_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-typedef enum
-{
- UNITS_SLIDE,
- UNITS_FRAC
-} LengthUnits;
-
-extern void chomp(char *s);
-extern int safe_strcmp(const char *a, const char *b);
-extern int parse_double(const char *a, float v[2]);
-extern int parse_tuple(const char *a, float v[4]);
-extern int parse_dims(const char *opt, double *wp, double *hp,
- LengthUnits *wup, LengthUnits *hup,
- double *xp, double *yp);
-
-#include <libintl.h>
-#define _(x) gettext(x)
-
-#endif /* UTILS_H */