From 4904182915c1a02c8ac6fb26397cb12e0aab51b9 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 26 Feb 2019 21:21:36 +0100 Subject: Skeleton of main program --- src/colloquium.c | 493 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 493 insertions(+) create mode 100644 src/colloquium.c (limited to 'src/colloquium.c') diff --git a/src/colloquium.c b/src/colloquium.c new file mode 100644 index 0000000..7ce0dd8 --- /dev/null +++ b/src/colloquium.c @@ -0,0 +1,493 @@ +/* + * colloquium.c + * + * Copyright © 2013-2019 Thomas White + * + * This file is part of Colloquium. + * + * Colloquium is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +//#include + +#include "colloquium.h" + +#include +#define _(x) gettext(x) + + +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 ) { + Presentation *p; + p = presentation_new(); + 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 ", + 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-2019 Thomas White "); + 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; ifinalize(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 chomp(char *s) +{ + size_t i; + + if ( !s ) return; + + for ( i=0; iimagestore = 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] []\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; +} -- cgit v1.2.3