/* * gpe-helpviewer v0.5 * * Displays HTML help files * * Copyright (c) 2004 Phil Blundell * Copyright (c) 2004 Philippe De Swert, for Aleph One Ltd. * Copyright (c) 2005 Philippe De Swert * * Contact : philippedeswert@scarlet.be * * 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, 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SOCKETNAME "/tmp/comm" #define EC_FAIL 1 //#define DEBUG /* uncomment this if you want debug output*/ WebKitWebView *web_view; /* read a file into gtk-webcore */ void read_file (const gchar * url, GtkWidget * html) { const gchar *filename; filename = strchr (url, ':'); if (filename) filename = filename + 3; if (!access (filename, F_OK)) { #ifdef DEBUG fprintf (stderr, "loading html %s\n", filename); #endif webkit_web_view_stop_loading (web_view); webkit_web_view_open (web_view, filename); } else { #ifdef DEBUG fprintf (stderr, "Could not open %s\n", filename); #endif if (!access ("/usr/share/doc/gpe/doc-not-installed.html", F_OK)) read_file ("file:///usr/share/doc/gpe/doc-not-installed.html", html); else if (!access ("/usr/share/doc/gpe/help-index.html", F_OK)) { read_file ("file:///usr/share/doc/gpe/help-index.html", html); } else { gpe_error_box ("Help not installed or file not found"); } } } /* parse url to something easy to interprete */ const gchar * parse_url (const gchar * url) { const gchar *p; p = strchr (url, ':'); if (p) { return p; } else { p = g_strconcat ("file://", url, NULL); } return (p); } /*static void find_func () { }*/ /* makes the engine go forward one page */ static void forward_func (GtkWidget * forward, GtkWidget * html) { webkit_web_view_go_forward (web_view); /* TODO: check if we can provide similar functionality if (webi_can_go_forward (WEBI (html))) webi_go_forward (WEBI (html)); else gpe_error_box ("no more pages forward!"); */ } /* makes the engine go back one page */ static void back_func (GtkWidget * back, GtkWidget * html) { webkit_web_view_go_back (web_view); /* TODO: check if we can provide similar functionality if (webi_can_go_back (WEBI (html))) webi_go_back (WEBI (html)); else gpe_error_box ("No more pages back!"); */ } /* makes the engine load the help index page, if none exists it tries to generate it */ static void home_func (GtkWidget * home, GtkWidget * html) { if (!access ("/usr/share/doc/gpe/help-index.html", F_OK)) system ("gpe-helpindex"); read_file ("file:///usr/share/doc/gpe/help-index.html", GTK_WIDGET (html)); } /* open socket, check for instance and send it a quit message */ int checkinstance (const gchar * url) { struct sockaddr_un sv; int fd_skt, n, retry = 0; char buf[100]; strcpy (sv.sun_path, SOCKETNAME); sv.sun_family = AF_UNIX; fd_skt = socket (AF_UNIX, SOCK_STREAM, 0); #ifdef DEBUG while (connect (fd_skt, (struct sockaddr *) &sv, sizeof (sv)) == -1) { if ((errno != ENOENT) && (retry < 1)) { sleep (1); printf ("retry!\n"); retry++; continue; } else { return (0); } } #endif #ifndef DEBUG connect (fd_skt, (struct sockaddr *) &sv, sizeof (sv)); #endif n = strlen (url); //write (fd_skt, url, n+1); write (fd_skt, "quit", 5); read (fd_skt, buf, sizeof (buf)); close (fd_skt); return (0); } /* open listening socket for single instance. The application quits when it gets a message*/ static void * reportinstance (void *html2) { int fd_skt, fd_client, len; char buf[100]; struct sockaddr_un skt; while (1) { (void) unlink (SOCKETNAME); strcpy (skt.sun_path, SOCKETNAME); skt.sun_family = AF_UNIX; fd_skt = socket (AF_UNIX, SOCK_STREAM, 0); if (bind (fd_skt, (struct sockaddr *) &skt, sizeof (skt)) != 0) printf ("bind failed \n"); if (listen (fd_skt, SOMAXCONN) != 0) printf ("listening failed\n "); fd_client = accept (fd_skt, NULL, 0); read (fd_client, buf, sizeof (buf)); write (fd_client, "Goodbye!", 9); close (fd_client); close (fd_skt); exit (0); } } int main (int argc, char *argv[]) { GtkWidget *html; GtkWidget *app; GtkWidget *contentbox; GtkWidget *toolbar; GtkWidget *iconw; GtkWidget *back_button, *forward_button, *home_button, *search_button, *exit_button; const gchar *base; gchar *p; gint width = 240, height = 320; gpe_application_init (&argc, &argv); checkinstance (argv[1]); #ifdef DEBUG printf ("no instance running!\n"); #endif if (argc == 1) { printf ("GPE-helpviewer, basic help viewer application. (c)2005, Philippe De Swert\n"); printf ("Usage: gpe-helpviewer /path/to/file\n"); exit (0); } base = parse_url (argv[1]); #ifdef DEBUG fprintf (stderr, "url = %s\n", base); #endif //create application window app = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_signal_connect (G_OBJECT (app), "delete-event", gtk_main_quit, NULL); width = gdk_screen_width (); height = gdk_screen_height (); gtk_window_set_default_size (GTK_WINDOW (app), width, height); gtk_window_set_title (GTK_WINDOW (app), "Help viewer"); gtk_window_set_resizable (GTK_WINDOW (app), TRUE); gtk_widget_realize (app); //create boxes contentbox = gtk_vbox_new (FALSE, 0); //create toolbar and add to topbox toolbar = gtk_toolbar_new (); gtk_toolbar_set_orientation (GTK_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL); gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH); gtk_container_set_border_width (GTK_CONTAINER (toolbar), 5); //create html object (must be created before function calls to html to avoid segfault) html = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (html), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); web_view = WEBKIT_WEB_VIEW (webkit_web_view_new ()); gtk_container_add (GTK_CONTAINER (html), GTK_WIDGET (web_view)); #ifdef DEBUG printf ("report running! html=%d\n", html); printf ("continuing!\n"); #endif /*add home, search, back, forward and exit button */ gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar), GTK_STOCK_GO_BACK, ("Go back a page"), ("Back"), GTK_SIGNAL_FUNC (back_func), html, -1); gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar), GTK_STOCK_GO_FORWARD, ("Go to the next page"), ("Next"), GTK_SIGNAL_FUNC (forward_func), html, -1); /* TODO: Actually implement search function iconw = gtk_image_new_from_file ("help/search.png"); search_button = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), "Find", "Find a word in the text","Find", iconw, GTK_SIGNAL_FUNC (find_func), NULL); */ gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar), GTK_STOCK_HOME, ("Go to help home"), ("Home"), GTK_SIGNAL_FUNC (home_func), html, -1); gtk_toolbar_append_space (GTK_TOOLBAR (toolbar)); /* space after item */ gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar), GTK_STOCK_QUIT, ("Exit help"), ("Exit"), GTK_SIGNAL_FUNC (gtk_main_quit), NULL, -1); gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_SMALL_TOOLBAR); /* only show icons if the screen is 240x320 | 320x240 or smaller */ if ((width <= 240) || (height <= 240)) gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS); gtk_widget_show (toolbar); //create html reader gtk_widget_show_all (html); //make everything viewable gtk_box_pack_start (GTK_BOX (contentbox), toolbar, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (contentbox), html, TRUE, TRUE, 0); gtk_container_add (GTK_CONTAINER (app), contentbox); read_file (base, html); gtk_widget_show (GTK_WIDGET (contentbox)); gtk_widget_show (GTK_WIDGET (app)); gtk_main (); exit (0); }