From 179027f5ab84a23a158f8e45c5de4581b4f810de Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 17 Jan 2017 23:57:33 +0000 Subject: [PATCH] _online-help This works along the same lines as the Windows implementation, though we have to try a bit harder to find a help browser. Gbp-Pq: Name 202_online-help.diff --- Recipe | 1 + gtk.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/Recipe b/Recipe index ba8317f..cda4814 100644 --- a/Recipe +++ b/Recipe @@ -95,6 +95,7 @@ Puzzles.dmg: Puzzles !begin am bin_PROGRAMS = $(GAMES) +GTK_CFLAGS += -DSHAREDIR="\"$(datarootdir)\"" !end !begin am_begin GAMES = diff --git a/gtk.c b/gtk.c index 53f5d22..5bd1025 100644 --- a/gtk.c +++ b/gtk.c @@ -2,6 +2,10 @@ * gtk.c: GTK front end for my puzzle collection. */ +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 1 /* for PATH_MAX */ +#endif + #include #include #include @@ -10,6 +14,9 @@ #include #include #include +#include +#include +#include #include #include @@ -2273,6 +2280,89 @@ static void menu_config_event(GtkMenuItem *menuitem, gpointer data) midend_redraw(fe->me); } +#ifndef HELP_BROWSER_PATH +#define HELP_BROWSER_PATH "xdg-open:sensible-browser" +#endif + +static void show_help(frontend *fe, const char *topic) +{ + const char *list = HELP_BROWSER_PATH; + char path[PATH_MAX + 1]; + struct { + const char *s; + int len; + } lang[3]; + int i; + + /* + * Search for help file, trying: + * 1. Version for this locale, ignoring encoding (HTML browsers + * must handle multiple encodings) + * 2. Version for this locale, ignoring encoding and country + * 3. English version + */ + lang[0].s = setlocale(LC_MESSAGES, NULL); + lang[0].len = strcspn(lang[0].s, ".@"); + lang[1].s = lang[0].s; + lang[1].len = strcspn(lang[1].s, "_"); + if (lang[1].len > lang[0].len) + lang[1].len = lang[0].len; + lang[2].s = "en"; + lang[2].len = 2; + for (i = 0; i < lenof(lang); i++) { + sprintf(path, "%s/sgt-puzzles/help/%.*s/%s.html", + SHAREDIR, lang[i].len, lang[i].s, topic); + if (access(path, R_OK) == 0) + break; + } + if (i == lenof(lang)) { + error_box(fe->window, "Help file is not installed"); + return; + } + + for (;;) { + size_t len; + char buf[PATH_MAX + 1]; + const char *command; + const char *argv[3]; + + len = strcspn(list, ":"); + if (len <= PATH_MAX) { + memcpy(buf, list, len); + buf[len] = 0; + if (buf[0] == '$') + command = getenv(buf + 1); + else + command = buf; + if (command) { + argv[0] = command; + argv[1] = path; + argv[2] = NULL; + if (g_spawn_async(NULL, (char **)argv, NULL, + G_SPAWN_SEARCH_PATH, + NULL, NULL, NULL, NULL)) + return; + } + } + + if (!list[len]) + break; + list += len + 1; + } + + error_box(fe->window, "Failed to start a help browser"); +} + +static void menu_help_contents_event(GtkMenuItem *menuitem, gpointer data) +{ + show_help((frontend *)data, "index"); +} + +static void menu_help_specific_event(GtkMenuItem *menuitem, gpointer data) +{ + show_help((frontend *)data, thegame.htmlhelp_topic); +} + static void menu_about_event(GtkMenuItem *menuitem, gpointer data) { frontend *fe = (frontend *)data; @@ -2593,6 +2683,25 @@ static frontend *new_window(char *arg, int argtype, char **error) menu = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), menu); + menuitem = gtk_menu_item_new_with_label("Contents"); + gtk_container_add(GTK_CONTAINER(menu), menuitem); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(menu_help_contents_event), fe); + gtk_widget_show(menuitem); + + if (thegame.htmlhelp_topic) { + char *item; + assert(thegame.name); + item = snewn(9+strlen(thegame.name), char); /*ick*/ + sprintf(item, "Help on %s", thegame.name); + menuitem = gtk_menu_item_new_with_label(item); + sfree(item); + gtk_container_add(GTK_CONTAINER(menu), menuitem); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(menu_help_specific_event), fe); + gtk_widget_show(menuitem); + } + menuitem = gtk_menu_item_new_with_label("About"); gtk_container_add(GTK_CONTAINER(menu), menuitem); g_signal_connect(G_OBJECT(menuitem), "activate", -- 2.30.2