doc/disorder-decode.8.html
doc/disorder-decode.8
doc/plumbing.png
-disobedience/manual.h
-disobedience/manual.html
disobedience/images.h
debian/disorder-server
doc/disorder-stats.8
server/disorder-stats
*.deb
*.dsc
+disobedience/disobedience.html
if test $want_coreaudio = yes; then
COREAUDIO="-framework CoreAudio"
fi
+ BROWSER=open
;;
* )
AC_MSG_RESULT([unknown, winging it])
esac
AC_SUBST([COREAUDIO])
+AC_ARG_WITH([browser],
+ [AS_HELP_STRING([--with-browser=BROWSER],
+ [use BROWSER to display HTML])],
+ [browser=$withval])
+
+AC_CACHE_CHECK([default HTML viewer],[rjk_cv_browser],[
+ rjk_cv_browser=UNKNOWN
+ for candidate in x-www-browser firefox mozilla konqueror netscape; do
+ if type $candidate >/dev/null 2>&1; then
+ rjk_cv_browser="$candidate"
+ break
+ fi
+ done
+])
+if test -z "$browser"; then
+ browser="$rjk_cv_browser"
+fi
+AC_DEFINE_UNQUOTED([BROWSER],["$browser"],[HTML viewer])
+
AC_ARG_WITH([server],
[AS_HELP_STRING([--without-server],
[do not build server])],
#
bin_PROGRAMS=disobedience
+doc_DATA=disobedience.html
AM_CPPFLAGS=-I${top_srcdir}/lib -I../lib
AM_CFLAGS=$(GLIB_CFLAGS) $(GTK_CFLAGS)
disobedience_SOURCES=disobedience.h disobedience.c client.c queue.c \
choose.c misc.c control.c properties.c menu.c \
log.c progress.c login.c rtp.c help.c \
- ../lib/memgc.c appearance.c
+ ../lib/memgc.c settings.c
disobedience_LDADD=../lib/libdisorder.a $(LIBPCRE) $(LIBGC) $(LIBGCRYPT)
disobedience_LDFLAGS=$(GTK_LIBS)
check: check-help
-help.o: manual.h
-
-manual.html: ../doc/disobedience.1 $(top_srcdir)/scripts/htmlman
+disobedience.html: ../doc/disobedience.1 $(top_srcdir)/scripts/htmlman
rm -f $@.new
$(top_srcdir)/scripts/htmlman $< >$@.new
chmod 444 $@.new
mv -f $@.new $@
-manual.h: manual.html ${top_srcdir}/scripts/text2c
- ${top_srcdir}/scripts/text2c manual manual.html > $@.tmp
- mv $@.tmp $@
-
misc.o: images.h
images.h: $(PNGS)
}
}
signal(SIGPIPE, SIG_IGN);
- load_appearance();
+ load_settings();
/* create the event loop */
D(("create main loop"));
mainloop = g_main_loop_new(0, 0);
void start_rtp(void);
void stop_rtp(void);
-/* Appearance */
+/* Settings */
extern GdkColor tool_bg, tool_fg, layout_bg, even_bg, odd_bg;
extern GdkColor active_bg, selected_bg, selected_fg, search_bg;
extern GdkColor title_bg, title_fg, item_fg, drag_target, tool_active;
-void save_appearance(void);
-void load_appearance(void);
+extern const char *browser;
+
+void save_settings(void);
+void load_settings(void);
void set_tool_colors(GtkWidget *w);
void set_slider_colors(GtkWidget *w);
*/
#include "disobedience.h"
-#include "html.h"
-#include "manual.h"
+#include <sys/wait.h>
+#include <unistd.h>
-VECTOR_TYPE(markstack, GtkTextMark *, xrealloc);
-
-/** @brief Known tag type */
-struct tag {
- /** @brief HTML tag name */
- const char *name;
-
- /** @brief Called to set up the tag */
- void (*init)(GtkTextTag *tag);
-
-};
-
-/** @brief Initialize the bold tag
- *
- * This doesn't seem to work on OS X though the italic and monospace tags are
- * fine, and bold is OK on Linux, even connecting to the Apple X swerver.
- */
-static void init_bold(GtkTextTag *tag) {
- g_object_set(G_OBJECT(tag), "weight", PANGO_WEIGHT_BOLD, (char *)0);
-}
-
-/** @brief Initialize the italic tag */
-static void init_italic(GtkTextTag *tag) {
- g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, (char *)0);
-}
-
-/** @brief Initialize the pre tag */
-static void init_pre(GtkTextTag *tag) {
- g_object_set(G_OBJECT(tag), "family", "monospace", (char *)0);
-}
-
-/** @brief Table of known tags
- *
- * Keep in alphabetical order
- */
-static const struct tag tags[] = {
- { "b", init_bold },
- { "i", init_italic },
- { "pre", init_pre }
-};
-
-/** @brief Number of known tags */
-#define NTAGS (sizeof tags / sizeof *tags)
-
-/** @brief State structure for insert_html() */
-struct state {
- /** @brief The buffer to insert into */
- GtkTextBuffer *buffer;
-
- /** @brief The buffer's tag table */
- GtkTextTagTable *tagtable;
-
- /** @brief True if we are inside <body> */
- int body;
-
- /** @brief True if inside <pre> */
- int pre;
-
- /** @brief True if a space is required before any non-space */
- int space;
-
- /** @brief Stack of marks corresponding to tags */
- struct markstack marks[1];
-
-};
-
-/** @brief Called for an open tag */
-static void html_open(const char *tag,
- hash attribute((unused)) *attrs,
- void *u) {
- struct state *const s = u;
- GtkTextIter iter[1];
-
- if(!strcmp(tag, "body"))
- ++s->body;
- else if(!strcmp(tag, "pre"))
- ++s->pre;
- if(!s->body)
- return;
- /* push a mark for the start of the region */
- gtk_text_buffer_get_iter_at_mark(s->buffer, iter,
- gtk_text_buffer_get_insert(s->buffer));
- markstack_append(s->marks,
- gtk_text_buffer_create_mark(s->buffer,
- 0/* mark_name */,
- iter,
- TRUE/*left_gravity*/));
-}
-
-/** @brief Called for a close tag */
-static void html_close(const char *tag,
- void *u) {
- struct state *const s = u;
- GtkTextIter start[1], end[1];
- GtkTextTag *texttag;
-
- if(!strcmp(tag, "body"))
- --s->body;
- else if(!strcmp(tag, "pre")) {
- --s->pre;
- s->space = 0;
- }
- if(!s->body)
- return;
- /* see if this is a known tag */
- texttag = gtk_text_tag_table_lookup(s->tagtable, tag);
- if(!texttag)
- return;
- /* pop the mark at the start of the region */
- assert(s->marks->nvec > 0);
- gtk_text_buffer_get_iter_at_mark(s->buffer, start,
- s->marks->vec[--s->marks->nvec]);
- gtk_text_buffer_get_iter_at_mark(s->buffer, end,
- gtk_text_buffer_get_insert(s->buffer));
- /* apply the tag */
- gtk_text_buffer_apply_tag(s->buffer, texttag, start, end);
- /* don't need the start mark any more */
- gtk_text_buffer_delete_mark(s->buffer, s->marks->vec[s->marks->nvec]);
-}
-
-/** @brief Called for text */
-static void html_text(const char *text,
- void *u) {
- struct state *const s = u;
-
- /* ignore header */
- if(!s->body)
- return;
- if(!s->pre) {
- char *formatted = xmalloc(strlen(text) + 1), *t = formatted;
- /* normalize spacing */
- while(*text) {
- if(isspace((unsigned char)*text)) {
- s->space = 1;
- ++text;
- } else {
- if(s->space) {
- *t++ = ' ';
- s->space = 0;
- }
- *t++ = *text++;
- }
- }
- *t = 0;
- text = formatted;
- }
- gtk_text_buffer_insert_at_cursor(s->buffer, text, strlen(text));
-}
-
-/** @brief Callbacks for insert_html() */
-static const struct html_parser_callbacks insert_html_callbacks = {
- html_open,
- html_close,
- html_text
-};
-
-/** @brief Insert @p html into @p buffer at cursor */
-static void insert_html(GtkTextBuffer *buffer,
- const char *html) {
- struct state s[1];
- size_t n;
-
- memset(s, 0, sizeof *s);
- s->buffer = buffer;
- markstack_init(s->marks);
- /* initialize tags */
- s->tagtable = gtk_text_buffer_get_tag_table(s->buffer);
- for(n = 0; n < NTAGS; ++n) {
- GtkTextTag *const tag = gtk_text_tag_new(tags[n].name);
- tags[n].init(tag);
- gtk_text_tag_table_add(s->tagtable, tag);
- }
- /* convert the input */
- html_parse(&insert_html_callbacks, html, s);
-}
-
-/** @brief Create a GtkTextBuffer with @p html rendered into it */
-static GtkTextBuffer *html_buffer(const char *html) {
- GtkTextBuffer *buffer = gtk_text_buffer_new(NULL);
-
- insert_html(buffer, html);
- return buffer;
-}
-
-/** @brief The manual page window */
-static GtkWidget *help_window;
-
-/** @brief Pop up the manual page in a window */
+/** @brief Display the manual page */
void popup_help(void) {
- GtkWidget *view;
-
- if(help_window) {
- gtk_window_present(GTK_WINDOW(help_window));
- return;
+ char *path;
+ pid_t pid;
+ int w;
+
+ byte_xasprintf(&path, "%s/disobedience.html", docdir);
+ if(!(pid = xfork())) {
+ exitfn = _exit;
+ if(!xfork()) {
+ execlp(browser, browser, path, (char *)0);
+ fatal(errno, "error executing %s", browser);
+ }
+ _exit(0);
}
- help_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- g_signal_connect(help_window, "destroy",
- G_CALLBACK(gtk_widget_destroyed), &help_window);
- gtk_window_set_title(GTK_WINDOW(help_window), "Disobedience Manual Page");
- view = gtk_text_view_new_with_buffer(html_buffer(manual));
- gtk_text_view_set_editable(GTK_TEXT_VIEW(view), FALSE);
- gtk_container_add(GTK_CONTAINER(help_window), scroll_widget(view));
- gtk_window_set_default_size(GTK_WINDOW(help_window), 512, 512);
- gtk_widget_show_all(help_window);
+ while(waitpid(pid, &w, 0) < 0 && errno == EINTR)
+ ;
}
/*
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
-/** @file disobedience/appearance.c
- * @brief Visual appearance of Disobedience
+/** @file disobedience/settings.c
+ * @brief Disobedience settings
*
* Originally I attempted to use a built-in rc file to configure
* Disobedience's colors. This is quite convenient but fails in the
/** @brief Drag target color */
GdkColor drag_target = { 0, 0x6666, 0x6666, 0x6666 };
+/** @brief HTML displayer */
+const char *browser = BROWSER;
+
struct colordesc {
GdkColor *color;
const char *name;
#define NCOLORS (sizeof colors / sizeof *colors)
-void save_appearance(void) {
+void save_settings(void) {
char *dir, *path, *tmp;
FILE *fp = 0;
size_t n;
return n > 0xFFFF ? 0xFFFF : n;
}
-void load_appearance(void) {
+void load_settings(void) {
char *path, *line;
FILE *fp;
size_t n;
#
# This file is part of DisOrder.
-# Copyright (C) 2004, 2005, 2006, s007 Richard Kettlewell
+# Copyright (C) 2004, 2005, 2006, 2007 Richard Kettlewell
#
# 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
hash.c hash.h \
heap.h \
hex.c hex.h \
- html.c html.h \
ifreq.c ifreq.h \
inputline.c inputline.h \
kvp.c kvp.h \
echo "#define SBINDIR \"${sbindir}/\"" >> $@.new
echo "#define BINDIR \"${bindir}/\"" >> $@.new
echo "#define FINKBINDIR \"${finkbindir}/\"" >> $@.new
+ echo "#define DOCDIR \"${docdir}/\"" >> $@.new
@if cmp $@.new $@; then \
echo rm -f $@.new; rm -f $@.new; else \
echo mv $@.new $@; mv $@.new $@; fi
*/
const char finkbindir[] = FINKBINDIR;
+/** @brief Package documentation directory */
+const char docdir[] = DOCDIR;
+
/*
Local Variables:
c-basic-offset:2
extern const char bindir[];
extern const char sbindir[];
extern const char finkbindir[];
+extern const char docdir[];
#endif /* DEFS_H */
+++ /dev/null
-/*
- * This file is part of DisOrder
- * Copyright (C) 2007 Richard Kettlewell
- *
- * 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
- */
-/** @file lib/html.c
- * @brief Noddy HTML parser
- */
-
-#include <config.h>
-#include "types.h"
-
-#include <string.h>
-#include <ctype.h>
-#include <stddef.h>
-
-#include "hash.h"
-#include "html.h"
-#include "mem.h"
-#include "log.h"
-#include "vector.h"
-#include "charset.h"
-#include "table.h"
-
-/** @brief Entity table type */
-struct entity {
- const char *name;
- uint32_t value;
-};
-
-/** @brief Known entities
- *
- * We only support the entities that turn up in the HTML files we
- * actually care about.
- *
- * Keep in alphabetical order.
- */
-static const struct entity entities[] = {
- { "amp", '&' },
- { "gt", '>' },
- { "lt", '<' }
-};
-
-/** @brief Skip whitespace */
-static const char *skipwhite(const char *input) {
- while(*input && isspace((unsigned char)*input))
- ++input;
- return input;
-}
-
-/** @brief Parse an entity */
-static const char *parse_entity(const char *input,
- uint32_t *entityp) {
- input = skipwhite(input);
- if(*input == '#') {
- input = skipwhite(input + 1);
- if(*input == 'x')
- *entityp = strtoul(skipwhite(input + 1), (char **)&input, 16);
- else
- *entityp = strtoul(input, (char **)&input, 10);
- } else {
- struct dynstr name[1];
- int n;
-
- dynstr_init(name);
- while(isalnum((unsigned char)*input))
- dynstr_append(name, tolower((unsigned char)*input++));
- dynstr_terminate(name);
- if((n = TABLE_FIND(entities, struct entity, name, name->vec)) < 0) {
- error(0, "unknown entity '%s'", name->vec);
- *entityp = '?';
- } else
- *entityp = entities[n].value;
- }
- input = skipwhite(input);
- if(*input == ';')
- ++input;
- return input;
-}
-
-/** @brief Parse one character or entity and append it to a @ref dynstr */
-static const char *parse_one(const char *input, struct dynstr *d) {
- if(*input == '&') {
- uint32_t c;
- input = parse_entity(input + 1, &c);
- if(one_ucs42utf8(c, d))
- dynstr_append(d, '?'); /* U+FFFD might be a better choice */
- } else
- dynstr_append(d, *input++);
- return input;
-}
-
-/** @brief Too-stupid-to-live HTML parser
- * @param callbacks Parser callbacks
- * @param input HTML document
- * @param u User data pointer
- * @return 0 on success, -1 on error
- */
-int html_parse(const struct html_parser_callbacks *callbacks,
- const char *input,
- void *u) {
- struct dynstr text[1];
-
- dynstr_init(text);
- while(*input) {
- if(*input == '<') {
- struct dynstr tag[1];
- hash *attrs;
-
- /* flush collected text */
- if(text->nvec) {
- dynstr_terminate(text);
- callbacks->text(text->vec, u);
- text->nvec = 0;
- }
- dynstr_init(tag);
- input = skipwhite(input + 1);
- /* see if it's an open or close tag */
- if(*input == '/') {
- input = skipwhite(input + 1);
- attrs = 0;
- } else
- attrs = hash_new(sizeof(char *));
- /* gather tag */
- while(isalnum((unsigned char)*input))
- dynstr_append(tag, tolower((unsigned char)*input++));
- dynstr_terminate(tag);
- input = skipwhite(input);
- if(attrs) {
- /* gather attributes */
- while(*input && *input != '>') {
- struct dynstr name[1], value[1];
-
- dynstr_init(name);
- dynstr_init(value);
- /* attribute name */
- while(isalnum((unsigned char)*input))
- dynstr_append(name, tolower((unsigned char)*input++));
- dynstr_terminate(name);
- input = skipwhite(input);
- if(*input == '=') {
- /* attribute value */
- input = skipwhite(input + 1);
- if(*input == '"' || *input == '\'') {
- /* quoted value */
- const int q = *input++;
- while(*input && *input != q)
- input = parse_one(input, value);
- if(*input == q)
- ++input;
- } else {
- /* unquoted value */
- while(*input && *input != '>' && !isspace((unsigned char)*input))
- input = parse_one(input, value);
- }
- dynstr_terminate(value);
- }
- /* stash the value */
- hash_add(attrs, name->vec, value->vec, HASH_INSERT_OR_REPLACE);
- input = skipwhite(input);
- }
- }
- if(*input != '>') {
- error(0, "unterminated tag %s", tag->vec);
- return -1;
- }
- ++input;
- if(attrs)
- callbacks->open(tag->vec, attrs, u);
- else
- callbacks->close(tag->vec, u);
- } else
- input = parse_one(input, text);
- }
- /* flush any trailing text */
- if(text->nvec) {
- dynstr_terminate(text);
- callbacks->text(text->vec, u);
- text->nvec = 0;
- }
- return 0;
-}
-
-/*
-Local Variables:
-c-basic-offset:2
-comment-column:40
-fill-column:79
-indent-tabs-mode:nil
-End:
-*/
+++ /dev/null
-/*
- * This file is part of DisOrder
- * Copyright (C) 2007 Richard Kettlewell
- *
- * 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
- */
-/** @file lib/html.c
- * @brief Noddy HTML parser
- */
-
-#ifndef HTML_H
-#define HTML_H
-
-/** @brief HTML parser callbacks */
-struct html_parser_callbacks {
- /** @brief Called for an open tag
- * @param tag Name of tag, normalized to lower case
- * @param attrs Hash containing attributes
- * @param u User data pointer
- */
- void (*open)(const char *tag,
- hash *attrs,
- void *u);
-
- /** @brief Called for a close tag
- * @param tag Name of tag, normalized to lower case
- * @param u User data pointer
- */
- void (*close)(const char *tag,
- void *u);
-
- /** @brief Called for text
- * @param text Pointer to text
- * @param u User data pointer
- */
- void (*text)(const char *text,
- void *u);
-};
-
-int html_parse(const struct html_parser_callbacks *callbacks,
- const char *input,
- void *u);
-
-#endif /* HTML_H */
-
-/*
-Local Variables:
-c-basic-offset:2
-comment-column:40
-fill-column:79
-indent-tabs-mode:nil
-End:
-*/