Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Backports:SLE-15-SP4
dvdisaster
27-allow-opening-in-browser-again.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 27-allow-opening-in-browser-again.patch of Package dvdisaster
From: Carlos Maddela <e7appew@gmail.com> Date: Thu, 5 Jan 2017 19:11:38 +1100 Subject: Resurrect old code to support opening URLs in a browser. Description: Resurrect old code to support opening URLs in a browser. Author: Carlos Maddela <e7appew@gmail.com> Forwarded: not-needed Last-Update: 2016-12-21 --- This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ --- closure.c | 2 + dvdisaster.h | 7 + help-dialogs.c | 3 +- show-html.c | 402 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 413 insertions(+), 1 deletion(-) create mode 100644 show-html.c diff --git a/closure.c b/closure.c index fa52f09..24c1e8c 100644 --- a/closure.c +++ b/closure.c @@ -474,6 +474,7 @@ void InitClosure() Closure->deviceNames = g_ptr_array_new(); Closure->deviceNodes = g_ptr_array_new(); Closure->viewer = g_strdup("xdg-open"); + Closure->browser = g_strdup("xdg-open"); Closure->methodList = g_ptr_array_new(); Closure->methodName = g_strdup("RS01"); Closure->dDumpDir = g_strdup(Closure->homeDir); @@ -589,6 +590,7 @@ void FreeClosure() cond_free(Closure->binDir); cond_free(Closure->docDir); cond_free(Closure->viewer); + cond_free(Closure->browser); cond_free(Closure->errorTitle); cond_free(Closure->simulateCD); cond_free(Closure->dDumpDir); diff --git a/dvdisaster.h b/dvdisaster.h index 9acd094..f536040 100644 --- a/dvdisaster.h +++ b/dvdisaster.h @@ -229,6 +229,7 @@ typedef struct _GlobalClosure char *binDir; /* place where the binary resides */ char *docDir; /* place where our documentation resides */ char *viewer; /* Name of preferred PDF viewer */ + char *browser; /* Name of preferred browser */ GMutex progressLock; /* A mutex protected the stuff below */ char bs[256]; /* A string of 255 backspace characters */ @@ -1348,6 +1349,12 @@ int ProbeAltiVec(void); void ShowPDF(char*); +/*** + *** show-html.c + ***/ + +void ShowHTML(char*); + /*** *** smart-lec.c ***/ diff --git a/help-dialogs.c b/help-dialogs.c index 75a615e..dc5b440 100644 --- a/help-dialogs.c +++ b/help-dialogs.c @@ -599,7 +599,8 @@ static gint about_cb(GtkWidget *widget, GdkEvent *event, gpointer data) { case GDK_BUTTON_PRESS: if(!inside) return FALSE; /* Defect in certain Gtk versions? */ if(!strcmp(label,"GPL")) ShowGPL(); - else if(!strcmp(label,"MODIFYING")) show_modifying(); + else if(!strcmp(label,"MODIFYING")) show_modifying(); + else if(strlen(label) > 4 && !strncmp(label, "http", 4)) ShowHTML(g_strdup(label)); else ShowPDF(g_strdup(label)); break; case GDK_ENTER_NOTIFY: diff --git a/show-html.c b/show-html.c new file mode 100644 index 0000000..608e8ec --- /dev/null +++ b/show-html.c @@ -0,0 +1,402 @@ +/* dvdisaster: Additional error correction for optical media. + * Copyright (C) 2004-2012 Carsten Gnoerlich. + * Project home page: http://www.dvdisaster.com + * Email: carsten@dvdisaster.com -or- cgnoerlich@fsfe.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, + * or direct your browser at http://www.gnu.org. + */ + +#include "dvdisaster.h" + +#if defined(SYS_LINUX) || defined(SYS_FREEBSD) || defined(SYS_NETBSD) +#include <sys/wait.h> +#endif + +#ifdef SYS_MINGW +#include "windows.h" +#include "shellapi.h" +#endif + +/*** + *** Ask user to specify his browser + ***/ + +#if defined(SYS_LINUX) || defined(SYS_FREEBSD) || defined(SYS_NETBSD) + +#define SEARCH_BUTTON 1 + +typedef struct +{ GtkWidget *dialog; + GtkWidget *entry; + GtkWidget *search; + GtkWidget *filesel; + GtkWidget *fileok; + GtkWidget *filecancel; + char *url; +} browser_dialog_info; + +static void response_cb(GtkWidget *widget, int response, gpointer data) +{ browser_dialog_info *bdi = (browser_dialog_info*)data; + + switch(response) + { case GTK_RESPONSE_ACCEPT: + if(Closure->browser) g_free(Closure->browser); + Closure->browser = g_strdup(gtk_entry_get_text(GTK_ENTRY(bdi->entry))); + ShowHTML(bdi->url); + break; + + case GTK_RESPONSE_REJECT: + if(bdi->url) g_free(bdi->url); + break; + } + gtk_widget_destroy(widget); + if(bdi->filesel) + gtk_widget_destroy(bdi->filesel); + g_free(bdi); +} + +static void search_cb(GtkWidget *widget, gpointer data) +{ browser_dialog_info *bdi = (browser_dialog_info*)data; + + if(widget == bdi->search) + { bdi->filesel = gtk_file_selection_new(_utf("windowtitle|Choose a browser")); + bdi->fileok = GTK_FILE_SELECTION(bdi->filesel)->ok_button; + bdi->filecancel = GTK_FILE_SELECTION(bdi->filesel)->cancel_button; + ReverseCancelOK(GTK_DIALOG(bdi->filesel)); + gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(bdi->filesel)); + g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(bdi->filesel)->ok_button), "clicked", + G_CALLBACK(search_cb), bdi); + + g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(bdi->filesel)->cancel_button), "clicked", + G_CALLBACK(search_cb), bdi); + + gtk_widget_show(bdi->filesel); + } + + if(widget == bdi->fileok) + { + if(Closure->browser) g_free(Closure->browser); + Closure->browser = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(bdi->filesel))); + ShowHTML(bdi->url); + gtk_widget_destroy(bdi->filesel); + gtk_widget_destroy(bdi->dialog); + g_free(bdi); + return; + } + + if(widget == bdi->filecancel) + { gtk_widget_destroy(bdi->filesel); + bdi->filesel = NULL; + } +} + +static void browser_dialog(char *url) +{ GtkWidget *dialog, *vbox, *hbox, *label, *entry, *button; + browser_dialog_info *bdi = g_malloc0(sizeof(browser_dialog_info)); + + /* Create the dialog */ + + dialog = gtk_dialog_new_with_buttons(_utf("windowtitle|Browser required"), + Closure->window, GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); + bdi->dialog = dialog; + if(url) + { bdi->url = g_strdup(url); + } + + vbox = gtk_vbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), vbox, FALSE, FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 10); + + /* Insert the contents */ + + label = gtk_label_new(NULL); + gtk_label_set_markup(GTK_LABEL(label), _utf("<b>Could not find a suitable browser.</b>\n\n" + "Which browser would you like to use\n" + "for reading the online documentation?\n\n" + "Please enter its name (e.g. mozilla) or\n" + "use the \"Search\" button for a file dialog.\n")), + gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 10); + + hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 10); + + bdi->entry = entry = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 10); + + bdi->search = button = gtk_button_new_with_label(_utf("Search")); + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(search_cb), bdi); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 10); + + /* Show it */ + + g_signal_connect(dialog, "response", G_CALLBACK(response_cb), bdi); + + gtk_widget_show_all(dialog); +} +#endif /* SYS_ unix-like */ + +/*** + *** Show the manual in an external browser + ***/ + +/* + * Check the child processes exit status + * to find whether the browser could be invoked. + */ + +typedef struct +{ pid_t pid; + char *url; + GtkWidget *msg; + int seconds; +} browser_info; + + +static void msg_destroy_cb(GtkWidget *widget, gpointer data) +{ browser_info *bi = (browser_info*)data; + + bi->msg = NULL; +} + +#if defined(SYS_LINUX) || defined(SYS_FREEBSD) || defined(SYS_NETBSD) + +/* + * The following list of browsers and html wrappers + * will be tried one at a time until one entry succeeds by: + * - returning zero + * - not returning within 60 seconds + */ + +static int browser_index; +static void try_browser(browser_info*); + +static char *browsers[] = +{ "user-selection", + "xdg-open", + "gnome-open", + "htmlview", + "firefox", + "mozilla", + "konqueror", + "epiphany", + "opera", + "/Applications/Safari.app/Contents/MacOS/Safari", /* better way to do this? */ + NULL +}; + +static gboolean browser_timeout_func(gpointer data) +{ browser_info *bi = (browser_info*)data; + int status; + + waitpid(bi->pid, &status, WNOHANG); + + /* At least mozilla returns random values under FreeBSD on success, + so we can't rely on the return value exept our own 110 one. */ + + if(WIFEXITED(status)) + { + switch(WEXITSTATUS(status)) + { case 110: /* browser did not execute */ + browser_index++; + if(!browsers[browser_index]) /* all browsers from the list failed */ + { browser_dialog(bi->url); + + if(bi->msg) + gtk_widget_destroy(bi->msg); + if(bi->url) + g_free(bi->url); + g_free(bi); + } + else /* try next browser from list */ + { bi->seconds = 0; + try_browser(bi); + } + return FALSE; + + case 0: /* browser assumed to be successful */ + default: + if(bi->msg) + gtk_widget_destroy(bi->msg); + if(bi->url) + g_free(bi->url); + g_free(bi); + return FALSE; + } + } + + bi->seconds++; + if(bi->seconds == 10 && bi->msg) + { gtk_widget_destroy(bi->msg); + bi->msg = NULL; + } + + return bi->seconds > 60 ? FALSE : TRUE; +} +#endif /* SYS_ unix-like */ + +#ifdef SYS_MINGW +static gboolean browser_timeout_func(gpointer data) +{ browser_info *bi = (browser_info*)data; + + bi->seconds++; + + if(bi->seconds >= 10) + { if(bi->msg) + { gtk_widget_destroy(bi->msg); + bi->msg = NULL; + } + if(bi->url) g_free(bi->url); + g_free(bi); + return FALSE; + } + + return TRUE; +} +#endif /* SYS_MINGW */ + +/* + * Invoke the browser + */ + +#if defined(SYS_LINUX) || defined(SYS_FREEBSD) || defined(SYS_NETBSD) +static void try_browser(browser_info *bi) +{ pid_t pid; + + bi->pid = pid = fork(); + + if(pid == -1) + { printf("fork failed\n"); + return; + } + + /* make the parent remember and wait() for the browser */ + + if(pid > 0) + { g_timeout_add(1000, browser_timeout_func, (gpointer)bi); + + if(browser_index) + { g_free(Closure->browser); + Closure->browser = g_strdup(browsers[browser_index]); + } + } + + /* try calling the browser */ + + if(pid == 0) + { char *argv[10]; + int argc = 0; + + argv[argc++] = browser_index ? browsers[browser_index] : Closure->browser; + argv[argc++] = bi->url; + argv[argc++] = NULL; + execvp(argv[0], argv); + + _exit(110); /* couldn't execute */ + } +} +#endif /* SYS_ unix-like */ + + +void ShowHTML(char *target) +{ browser_info *bi = g_malloc0(sizeof(browser_info)); + guint64 ignore; + const char *lang; + char *path = NULL; + int http_url; + + /* If no target is given, select between translations of the manual. */ + + if(!target) target = g_strdup("index.html"); + + http_url = strlen(target) > 4 && !strncmp(target, "http", 4); + + if(!http_url && !strchr(target, '/')) /* create full path */ + { + if(!Closure->docDir) + { + CreateMessage(_("Documentation not installed."), GTK_MESSAGE_ERROR); + g_free(bi); + return; + } + + lang = g_getenv("LANG"); + + if(lang) + { if(!strncmp(lang, "ru", 2)) +#ifdef SYS_MINGW + path = g_strdup_printf("%s\\ru\\%s",Closure->docDir,target); +#else + path = g_strdup_printf("%s/ru/%s",Closure->docDir,target); +#endif + else if(!strncmp(lang, "de", 2)) +#ifdef SYS_MINGW + path = g_strdup_printf("%s\\de\\%s",Closure->docDir,target); +#else + path = g_strdup_printf("%s/de/%s",Closure->docDir,target); +#endif + } + + if(!path) + { +#ifdef SYS_MINGW + path = g_strdup_printf("%s\\en\\%s",Closure->docDir,target); +#else + path = g_strdup_printf("%s/en/%s",Closure->docDir,target); +#endif + } + +#ifdef SYS_MINGW + if(!LargeStat(path, &ignore)) + { + g_free(path); /* the local dir is Windows specific */ + path = g_strdup_printf("%s\\local\\%s",Closure->docDir,target); + } +#endif + g_free(target); + bi->url = path; + } + else bi->url = target; + + if(!http_url && !LargeStat(bi->url, &ignore)) + { + CreateMessage(_("Documentation file\n%s\nnot found.\n"), GTK_MESSAGE_ERROR, bi->url); + g_free(bi); + g_free(bi->url); + return; + } + + /* Lock the help button and show a message for 10 seconds. */ + + TimedInsensitive(Closure->helpButton, 10000); + bi->msg = CreateMessage(_("Please hang on until the browser comes up!"), GTK_MESSAGE_INFO); + g_signal_connect(G_OBJECT(bi->msg), "destroy", G_CALLBACK(msg_destroy_cb), bi); + +#ifdef SYS_MINGW + /* Okay, Billy wins big time here ;-) */ + + ShellExecute(NULL, "open", bi->url, NULL, NULL, SW_SHOWNORMAL); + g_timeout_add(1000, browser_timeout_func, (gpointer)bi); +#endif + +#if defined(SYS_LINUX) || defined(SYS_FREEBSD) || defined(SYS_NETBSD) + /* Try the first browser */ + + browser_index = 0; + try_browser(bi); +#endif +}
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor