changeset 699:c661fbf968ad

merge with main
author Johannes Hofmann <Johannes.Hofmann@gmx.de>
date Sun, 28 Dec 2008 17:17:41 +0100
parents 602ab87f6cd2 (current diff) 0b47756eeb13 (diff)
children 657d779be7a4
files ChangeLog dw/style.cc src/form.cc src/html.cc src/nav.c
diffstat 25 files changed, 555 insertions(+), 270 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Dec 21 16:40:36 2008 -0300
+++ b/ChangeLog	Sun Dec 28 17:17:41 2008 +0100
@@ -20,6 +20,9 @@
  - Set middle click to submit in a new TAB. (Helps to keep form data!)
  - Added support for the Q element. BUG#343
  - Cleaned up Html_pop_tag().
+ - Ported the command line interface from dillo1 (XID not working yet).
+ - Switched file dpi error messages to HTML.
+ - Added a popup menu to form's submit button.
    Patches: place (AKA corvid)
 +- Switched SSL-enabled to configure.in (./configure --enable-ssl).
  - Standardised the installation of dpid/dpidrc with auto* tools.
@@ -427,7 +430,7 @@
    * Made the downloads plugin dillo-cookie aware.
    * Ported the cookies dpi to libDpip.a.
    * Merged the new dpip code into the source tree.
-   Patches: Diego Sáenz, Jorge Arellano
+   Patches: Diego S�enz, Jorge Arellano
  - * Added "./configure --disable-threaded-dns" (for some non reentrant BSDs).
    Patch: Jorge Arellano, Francis Daly
  - * Fixed a bug with roman literals divisible by 10 (BUG#700).
@@ -439,13 +442,13 @@
  - * Improved the dpi framework. Now dpi-programs can be specified in dpidrc,
    and there's no need to touch dillo's sources to add new dpi services.
    Just make your dpi program, add a dpidrc line and play with it!
-   Patch: Diego Sáenz, Jorge Arellano
+   Patch: Diego S�enz, Jorge Arellano
 
 
 dillo-0.8.5 [Jun 15, 2005]
 
  - * Set "file:" to work as URI for current directory.
-   Patch: Diego Sáenz
+   Patch: Diego S�enz
  - * Added a "small" dillorc option for panel size (medium without labels).
    Patch: Eugeniy, Jorge Arellano
  - * Fixed the shell escaping code in the ftp plugin.
@@ -547,17 +550,17 @@
    Patches: Jorge Arellano
  - * Introduced a light-weight heuristic algorithm over the W3C parsing
      scheme (allows for slightly better rendering: w3c_plus_heuristics=YES).
-   Patch: Rubén Fernández
+   Patch: Rub�n Fern�ndez
  - * Moved the internal support for "file:" URIs into a dpi (server plugin).
    * Added TABLE-based rendering of directory listings to the new file dpi.
-   Patches: Jorge Arellano, Jörgen Viksell
+   Patches: Jorge Arellano, J�rgen Viksell
  - * Removed DwWidget::realize and DwWidget::unrealize.
    * Made all signals expect events to abstract methods.
    * Renamed a_Dw_widget_{size_request|get_extremes|size_allocate|set_*} to
      p_*, they should not be used outside of Dw.
    Patches: Sebastian Geerken
  - * Fixed the meta refresh warning to not switch from IN_HEAD to IN_BODY.
-   Patch: Björn Brill
+   Patch: Bj�rn Brill
 
 
 dillo-0.8.2 [Jul 06, 2004]
@@ -591,7 +594,7 @@
    * Now you can copy & paste an URL into the "Clear URL" button.
    Patch: Jorge Arellano, Sebastian Geerken
  - * Made the save and open file dialogs remember the last directory (BUG#211).
-   Patch: Diego Sáenz
+   Patch: Diego S�enz
 
 
 dillo-0.8.1 [May 14, 2004]
@@ -601,13 +604,13 @@
  - * Fixed a slippery bug with certain interlaced gif images (BUG#500).
    Patch: Andreas Mueller
  - * Fixed libpng-1.2.4 detection in configure.in.
-   Patch: Rubén Helguera
+   Patch: Rub�n Helguera
  - * Added proxy authentication support through the "http_proxyuser" option
      in dillorc (the password is asked at run time).
    Patch: Ivan Daniluk, Jorge Arellano, Francis Daly
  - * Moved tooltips to DwStyle, tooltip event handling to DwPage, and applied
      this also to the TITLE attribute of <a> and <abbr>.
-   Patch: Jörgen Viksell, Sebastian Geerken
+   Patch: J�rgen Viksell, Sebastian Geerken
  - * Fixed a bug related to spaces after anchors and breaks.
    Patch: Sebastian Geerken
  - * Removed two "type punning" gcc warnings (dw_gtk_viewport.c).
@@ -617,9 +620,9 @@
    * Switch one realloc() call to g_realloc(), to match g_free() (dpi.c).
    * Removed unnecessary NULL-checks and NULL initializations.
    * Added Html_get_attr_wdef(), it lets providing a default return value.
-   Patches: Jörgen Viksell
+   Patches: J�rgen Viksell
  - * Fixed configure.in so pthreads are only linked where needed.
-   Patch: Jörgen Viksell, Jorge Arellano
+   Patch: J�rgen Viksell, Jorge Arellano
  - * Modified a_Misc_stuff_chars for simplicity and removed a memory leak.
    * Made the dpi framework send the HTTP query to the https dpi
      (this allows for an SSL-lib dpi and for easier session caching).
@@ -752,7 +755,7 @@
    * Added configure options to disable either: png, jpeg or gif.
    * Fixed configure.in for proper library linking for dpis and dpid.
    * Improved libpng detection.
-   Patches: Jörgen Viksell
+   Patches: J�rgen Viksell
  - * Fixed wrong handling of coordinates in ISMAP and USEMAP images.
    * Added a hand-shaped cursor to input controls of type image.
    * Fixed a off-by-one memory leak in Dw(Ext)Iterator.
@@ -775,7 +778,7 @@
      The search engine can be set in dillorc (defaults to google).
    Patch: Johan Hovold, Jorge Arellano
  - * Fixed a problem with libpng options detection (configure.in).
-   Patch: Rubén Fernández
+   Patch: Rub�n Fern�ndez
  - * Added "pthreads" (with an "s") detection to configure.in.
    Patch: Andreas Schweitzer
  - * Added the "-geometry" switch to the CLI.
@@ -807,7 +810,7 @@
  - * Added support for the hspace and vspace attributes of the IMG tag.
    * Made only left button activate the image input type (BUG#367,#451).
    * Fixed SELECT with "multiple" but without "size" (BUG#469).
-   Patches: Jörgen Viksell
+   Patches: J�rgen Viksell
  - * Added titles to bookmark server's html pages.
    Patch: Kelson Vibber
  - * Made IFRAME to be handled like FRAME (shows link).
@@ -843,9 +846,9 @@
    detection, enabling and disabling. (BUG#: 386, 407, 392, 349)!
    Patches: Andreas Schweitzer
  - * Fixed two leaks in Dw(Ext)Iterator.
-   Patches: Jörgen Viksell
+   Patches: J�rgen Viksell
  - * Repaired some minor misbehaviours in the cookie-strings parser.
-   Patches: Jörgen Viksell, Jorge Arellano
+   Patches: J�rgen Viksell, Jorge Arellano
  - * Enabled entities parsing in HTML-given hidden and password values.
    Patch: Jorge Arellano, Francis Daly
  - * Implemented character stuffing in dpi (Fix bookmarks with quotes) BUG#434.
@@ -901,14 +904,14 @@
  - * Fixed a problem occurring when scrolling with the "b" key.
    Patch: Livio Baldini
  - * Fixed a memory leak in DwAlignedPage.
-   Patch: Jörgen Viksell, Sebastian Geerken
+   Patch: J�rgen Viksell, Sebastian Geerken
  - * Moved stuff into remove_cookie() and add_cookie() functions.
    * Made cookies sort once in add_cookie().
    * Removed some unneeded casts and calls in cookies.
    * Repairing some minor misbehaviours in Cookies_parse_string().
-   Patches: Jörgen Viksell, Jorge Arellano, Madis Janson
+   Patches: J�rgen Viksell, Jorge Arellano, Madis Janson
  - * Fixed a bug in Dw_widget_mouse_event.
-   Patch: Jörgen Viksell
+   Patch: J�rgen Viksell
  - * Fixed a bug in DwPage ("height" argument).
    Patch: Pekka Lampila
  - * Removed a segfault source in http.c
@@ -986,7 +989,7 @@
  - * Fixed a bug with cookies path parsing.
    * Fixed persistent-cookies obliteration (BUG#312, BUG#314)
    * Set max 20 persistent cookies for each domain.
-   Patches: Jörgen Viksell
+   Patches: J�rgen Viksell
  - * Switched flock to lockf.
    Patch: Andreas Schweitzer
  - * Made a little bugfix in doc/Makefile.am.
@@ -1027,7 +1030,7 @@
  - * Fixed a tiny bug with dillorc parsing on certain locales (BUG#301)
    Patch: Lars Clausen, Jorge Arellano
  - * Added support for cookies! RFC-2965 (BUG#82)
-   Patch: Jörgen Viksell, Lars Clausen, Jorge Arellano
+   Patch: J�rgen Viksell, Lars Clausen, Jorge Arellano
  - * Added code to detect redirect-loops (BUG#260)
    Patch: Jorge Arellano, Chet Murthy
  - * Added support for missing Content-Type in HTTP headers (BUG#216)
@@ -1063,7 +1066,7 @@
    * Cleaned some casts to use the GPOINTER_TO_INT and GINT_TO_POINTER macros.
    * Added the 'static' qualifier to some module-internal variables.
    * Added the 'static' qualifier to module-internal functions!
-   Patches: Jörgen Viksell
+   Patches: J�rgen Viksell
  - * New widget DwAlignedPage for alignment of vertical arrays.
      - New widget DwListItem for nicer list items (based on some extensions
        of DwPage) BUG#271.
@@ -1112,10 +1115,10 @@
  - * Added full-screen mode! (left double-click toggles it).
    Patch: Jorge Arellano, Sebastian Geerken
  - * Extended interface customization options in dillorc (a must for iPAQ).
-   Patch: Jorge Arellano, Sam Engström
+   Patch: Jorge Arellano, Sam Engstr�m
  - * Rewrote the whole tag-parsing code with a new scheme (single pass FSM!)
      (BUG#190, BUG#197, BUG#207, BUG#228, BUG#239) --Big work here.
-   Patch: Jorge Arellano, Jörgen Viksell
+   Patch: Jorge Arellano, J�rgen Viksell
  - * Set form encoding to escape everything but alphanumeric and -_.* (BUG#236)
    * Rewrote Html_tag_open_input.
    * Extended BACK and FWD key shortcuts to: {ALT | MOD*} + {, | .}    :-)
@@ -1181,7 +1184,7 @@
    * Fixed (and made faster) Url_str_resolve_relative (BUG#194)
    Patch: Jorge Arellano, Livio Baldini
  - * Added parsing support for %HexHex escape sequences in file URIs
-   Patch: Jorge Arellano, Livio Baldini, Agustín Ferrín :)
+   Patch: Jorge Arellano, Livio Baldini, Agust�n Ferr�n :)
  - * Implemented Ctrl-W (close window) (BUG#87)
    Patch: Jorge Arellano, Martynas Jocius
  - * Fixed a segfault when dillo cannot access ~/.dillo for some reason.
@@ -1207,10 +1210,10 @@
  - * Fixed a bunch of memory leaks!
    * Fixed links on pages with only one line, tuned text-entries size and
      fixed the HTTP header problem (BUG#180)
-   Patches: Jörgen Viksell
+   Patches: J�rgen Viksell
  - * Improved dialogs handling: find_text, view_source, open_url, open_file,
      save_link and save_page (also removed a leak here).
-   Patches: Jorge Arellano, Jörgen Viksell
+   Patches: Jorge Arellano, J�rgen Viksell
  - * Modified GtkDwScrolledWindow and GtkDwViewport, now scrollbars work much
      better. This also fixes of the wrong viewport length (BUG#137).
    * Implemented tables! (incomplete)
@@ -1234,7 +1237,7 @@
    Patches: Sebastian Geerken
  - * Added nowrap attribute to DwStyle, and applied it to <pre> (BUG#134),
      <td> and <th>.
-   Patch: Jörgen Viksell, Sebastian Geerken
+   Patch: J�rgen Viksell, Sebastian Geerken
  - * Added a_List_resize to list.h methods.
    * Added debug.h to standarize debugging messages.
    Patches: Sebastian Geerken, Jorge Arellano
@@ -1243,7 +1246,7 @@
  - * Added a few 'const', a missing header and some strength reductions.
    Patch: Aaron Lehmann
  - * Made dillo to also check '/etc/dillorc' for options.
-   Patch: Eduardo Marcel Maçan, Jorge Arellano
+   Patch: Eduardo Marcel Ma�an, Jorge Arellano
  - * Made a help page, and linked it to 'about:help' (BUG#72)
    Patch: Jorge Arellano, Kristian A. Rink
  - * Added an "alt" camp to DilloUrl
@@ -1282,7 +1285,7 @@
    * Added support for EAGAIN in IO.c
    Patches: Livio Baldini
  - * Removed 6 memory leaks! (of varying significance)
-   Patches: Jörgen Viksell
+   Patches: J�rgen Viksell
  - * Fixed a bug in DwPage (BUG#162, crash when clicking on links).
    * Removed a_Dw_gtk_viewport_queue_anchor and related code (becomes obsolete
      with the new URL handling scheme).
@@ -1323,7 +1326,7 @@
      added READONLY, SIZE, MAXLENGTH attributes, type=BUTTON and some cleanups
    * Fixed VERBATIM parsing mode (BUG#130)
    * Fixed a bug in calculating the page width (BUG#136)
-   Patches: Jörgen Viksell
+   Patches: J�rgen Viksell
  - * Added a dillorc option to set the location entry within the menu bar.
    Patch: Eric Gaudet
  - * Integrated some modifications to ease compiling on GNU Darwin.
@@ -1362,7 +1365,7 @@
  - * Included a scaling font_factor into dillorc!
    Patch: Bruno Widmann
  - * Fixed bugs #125 and #129 (menu item focus and radio reset in forms)
-   Patch: Jörgen Viksell
+   Patch: J�rgen Viksell
  - * Added code to ignore anything inside STYLE tags.
    Patch: Mark McLoughlin
  - * Implemented image rendering based on GdkRGB and DwImage!
@@ -1382,9 +1385,9 @@
    * Repaired the dillorc parser to skip unknown symbols (BUG#119)
    Patch: Eric Gaudet
  - * Fixed the segfault for controls outside FORM and SELECT elements (BUG#121)
-   Patch: Eric Gaudet, Jörgen Viksell
+   Patch: Eric Gaudet, J�rgen Viksell
  - * Added support for SUB and SUP tags (BUG#115)
-   Patch: Jörgen Viksell
+   Patch: J�rgen Viksell
  - * Added a geometry directive to dillorc (sets initial browser size)
    Patch: Livio Baldini, Jorge Arellano
  - * Fixed bookmarks loading in new browser windows (BUG#110)
@@ -1412,7 +1415,7 @@
  - * Removed redundant functions from misc.c
    * Added support for BASE, CODE, DFN, KBD, SAMP and VAR tags (BUG#106)
    * Added support for TAB characters in plain text files (BUG#112)
-   Patches: Jörgen Viksell, Jorge Arellano
+   Patches: J�rgen Viksell, Jorge Arellano
  - * Fixed a_Url_squeeze (BUG#100)
    Patch: Livio Baldini, Jorge Arellano
  - * Added gamma support and basic transparency for PNG images (BUG#60)
@@ -1436,7 +1439,7 @@
 (Lots of patches are pending!)
 
  - * Added support for <strike>, <s>, <del> and <u> tags.
-   Patch: Jörgen Viksell
+   Patch: J�rgen Viksell
  - * Fixed a bug in #anchors code
    Patch: Sebastian Geerken
  - * Parsed text between script tags, out of the rendering part.
@@ -1486,7 +1489,7 @@
    * Added the base for refresh support in META tags.
    Patches: Sean 'Shaleh' Perry
  - * Added support for TEXTAREA tags!
-   Patch: Jörgen Viksell
+   Patch: J�rgen Viksell
  - * Improved and fixed Html_parse_entities.
    * Reimplemented the Stash buffer with a GString.
    * Fixed a bug with \r\n-terminated HTML lines.
@@ -1502,7 +1505,7 @@
  - * Removed "search.h" include in http.c (freeBSD compatibility).
    Patch: Kurt J. Lidl
  - * Removed several memory leaks that were sprinkled through the code.
-   Patches: Jörgen Viksell
+   Patches: J�rgen Viksell
  - * Fixed a segfault crash when hitting PgDn in the URL box (BUG #54).
    * Removed a segfault source in commands.c
    * Made some minor fixes to Dw and added more comments to the code.
@@ -1527,7 +1530,7 @@
      from having the same size as the main window. (Ex: with Sawfish)
    * Made some width and height changes to the SELECT-stuff
    * Added "submit" to submit buttons without a value.
-   Patches: Jörgen Viksell
+   Patches: J�rgen Viksell
  - * Fixed a segfault when calling "about:" method
    Patch: Dominic Wong
  - * Added an option to force dillorc-defined colors (Try it with slashdot!)
@@ -1571,7 +1574,7 @@
  - * Added some functionality to reload button (not complete yet)
    Patch: Luca Rota , Jorge Arellano Cid
  - * Fixed hash handling within URL parsing. (Bug #9)
-   Patch: Marcos Ramírez , Jorge Arellano Cid
+   Patch: Marcos Ram�rez , Jorge Arellano Cid
 
 
 dillo-0.2.0 [June 2, 2000]
@@ -1622,7 +1625,7 @@
    * Added a startup page
    Patches: Jorge Arellano Cid
  - * Fixed a bug with http queries that sometimes produced infinite loops
-   Patch: Marcos Ramírez
+   Patch: Marcos Ram�rez
 
 
 dillo-0.0.6 [Mar 9, 2000]
--- a/dpi/file.c	Sun Dec 21 16:40:36 2008 -0300
+++ b/dpi/file.c	Sun Dec 28 17:17:41 2008 +0100
@@ -47,12 +47,6 @@
 #define MAXNAMESIZE 30
 #define HIDE_DOTFILES TRUE
 
-enum {
-   FILE_OK,
-   FILE_NOT_FOUND,
-   FILE_NO_ACCESS
-};
-
 typedef struct {
    char *full_path;
    const char *filename;
@@ -408,7 +402,9 @@
    Hdirname = Escape_html_str(Ddir->dirname);
 
    sock_handler_printf(Client->sh, 0,
-      "Content-Type: text/html\n\n"
+      "HTTP/1.1 200 OK\r\n"
+      "Content-Type: text/html\r\n"
+      "\r\n"
       "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>\n"
       "<HTML>\n<HEAD>\n <BASE href='file:%s'>\n"
       " <TITLE>file:%s</TITLE>\n</HEAD>\n"
@@ -522,6 +518,43 @@
 }
 
 /*
+ * Send an error page
+ */
+static void File_send_error_page(ClientInfo *Client, int res,
+                                 const char *orig_url)
+{
+   const char *status;
+   const char *body;
+   char *d_cmd;
+
+   switch (res) {
+   case EACCES:
+      status = "403 Forbidden";
+      break;
+   case ENOENT:
+      status = "404 Not Found";
+      break;
+   default:
+      /* good enough */
+      status = "500 Internal Server Error";
+   }
+
+   body = status; /* it's simple */
+
+   /* Send DPI command */
+   d_cmd = a_Dpip_build_cmd("cmd=%s url=%s", "start_send_page", orig_url);
+   sock_handler_write_str(Client->sh, 1, d_cmd);
+   dFree(d_cmd);
+
+   sock_handler_printf(Client->sh, 0, "HTTP/1.1 %s\r\n"
+                                      "Content-Type: text/plain\r\n"
+                                      "Content-Length: %ld\r\n"
+                                      "\r\n"
+                                      "%s",
+                                      status, strlen(body), body);
+}
+
+/*
  * Try to stat the file and determine if it's readable.
  */
 static void File_get(ClientInfo *Client, const char *filename,
@@ -529,12 +562,10 @@
 {
    int res;
    struct stat sb;
-   char *d_cmd;
-   Dstr *ds = NULL;
 
    if (stat(filename, &sb) != 0) {
       /* stat failed, prepare a file-not-found error. */
-      res = FILE_NOT_FOUND;
+      res = ENOENT;
    } else if (S_ISDIR(sb.st_mode)) {
       /* set up for reading directory */
       res = File_get_dir(Client, filename, orig_url);
@@ -542,21 +573,8 @@
       /* set up for reading a file */
       res = File_get_file(Client, filename, &sb, orig_url);
    }
-
-   if (res == FILE_NOT_FOUND) {
-      ds = dStr_sized_new(128);
-      dStr_sprintf(ds, "%s Not Found: %s",
-                   S_ISDIR(sb.st_mode) ? "Directory" : "File", filename);
-   } else if (res == FILE_NO_ACCESS) {
-      ds = dStr_sized_new(128);
-      dStr_sprintf(ds, "Access denied to %s: %s",
-                   S_ISDIR(sb.st_mode) ? "Directory" : "File", filename);
-   }
-   if (ds) {
-      d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s","send_status_message",ds->str);
-      sock_handler_write_str(Client->sh, 1, d_cmd);
-      dFree(d_cmd);
-      dStr_free(ds, 1);
+   if (res != 0) {
+      File_send_error_page(Client, res, orig_url);
    }
 }
 
@@ -580,13 +598,13 @@
    if (Ddir) {
       File_transfer_dir(Client, Ddir, orig_url);
       File_dillodir_free(Ddir);
-      return FILE_OK;
+      return 0;
    } else
-      return FILE_NO_ACCESS;
+      return EACCES;
 }
 
 /*
- * Send the MIME content/type and then send the file itself.
+ * Send HTTP headers and then send the file itself.
  */
 static int File_get_file(ClientInfo *Client,
                          const char *filename,
@@ -602,7 +620,7 @@
    bool_t gzipped = FALSE;
 
    if ((fd = open(filename, O_RDONLY | O_NONBLOCK)) < 0)
-      return FILE_NO_ACCESS;
+      return errno;
 
    /* Send DPI command */
    d_cmd = a_Dpip_build_cmd("cmd=%s url=%s", "start_send_page", orig_url);
@@ -626,15 +644,18 @@
    dFree(name);
 
    /* Send HTTP headers */
+   sock_handler_write_str(Client->sh, 0, "HTTP/1.1 200 OK\r\n");
    if (gzipped) {
-      sock_handler_write_str(Client->sh, 0, "Content-Encoding: gzip\n");
+      sock_handler_write_str(Client->sh, 0, "Content-Encoding: gzip\r\n");
    }
    if (!gzipped || strcmp(ct, unknown_type)) {
-      sock_handler_printf(Client->sh, 0, "Content-Type: %s\n", ct);
+      sock_handler_printf(Client->sh, 0, "Content-Type: %s\r\n", ct);
    } else {
       /* If we don't know type for gzipped data, let dillo figure it out. */
    }
-   sock_handler_printf(Client->sh, 0, "Content-Length: %ld\n\n", sb->st_size);
+   sock_handler_printf(Client->sh, 0, "Content-Length: %ld\r\n"
+                                      "\r\n",
+                                      sb->st_size);
 
    /* Send body -- raw file contents */
    do {
@@ -657,11 +678,12 @@
    }
 
    File_close(fd);
-   return FILE_OK;
+      
+   return 0;
 }
 
 /*
- * Given an hex octet (e3, 2F, 20), return the corresponding
+ * Given a hex octet (e3, 2F, 20), return the corresponding
  * character if the octet is valid, and -1 otherwise
  */
 static int File_parse_hex_octet(const char *s)
@@ -729,7 +751,7 @@
 }
 
 /*
- * Set the style flag and ask for a reload, so it shows inmediatly.
+ * Set the style flag and ask for a reload, so it shows immediately.
  */
 static void File_toggle_html_style(ClientInfo *Client)
 {
--- a/dw/style.cc	Sun Dec 21 16:40:36 2008 -0300
+++ b/dw/style.cc	Sun Dec 28 17:17:41 2008 +0100
@@ -560,10 +560,10 @@
 // ----------------------------------------------------------------------
 
 static const char
-   *roman_I0[] = { "","I","II","III","IV","V","VI","VII","VIII","IX" },
-   *roman_I1[] = { "","X","XX","XXX","XL","L","LX","LXX","LXXX","XC" },
-   *roman_I2[] = { "","C","CC","CCC","CD","D","DC","DCC","DCCC","CM" },
-   *roman_I3[] = { "","M","MM","MMM","MMMM" };
+   *const roman_I0[] = { "","I","II","III","IV","V","VI","VII","VIII","IX" },
+   *const roman_I1[] = { "","X","XX","XXX","XL","L","LX","LXX","LXXX","XC" },
+   *const roman_I2[] = { "","C","CC","CCC","CD","D","DC","DCC","DCCC","CM" },
+   *const roman_I3[] = { "","M","MM","MMM","MMMM" };
 
 void strtolower (char *s)
 {
--- a/src/IO/about.c	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/IO/about.c	Sun Dec 28 17:17:41 2008 +0100
@@ -14,7 +14,7 @@
 /*
  * HTML text for startup screen
  */
-const char *AboutSplash=
+const char *const AboutSplash=
 "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>\n"
 "<html>\n"
 "<head>\n"
@@ -75,7 +75,7 @@
 "    <tr>\n"
 "    <td>&nbsp;&nbsp;\n"
 "    <td>\n"
-"     <a href='http://cvs.auriga.wearlab.de/cgi-bin/cvsweb.cgi/dillo2/ChangeLog?rev=HEAD;cvsroot=dillo'>\n"
+"     <a href='http://freehg.org/u/dillo/main/file/tip/ChangeLog'>\n"
 "     ChangeLog</a>\n"
 "    <tr>\n"
 "    <td>&nbsp;&nbsp;\n"
@@ -240,22 +240,14 @@
 "<tr>\n"
 " <td bgcolor='#CCCCCC'>\n"
 "  <h4>Release overview</h4>\n"
-"  October 14, 2008\n"
+"  ??, 2009\n"
 "<tr>\n"
 " <td bgcolor='#FFFFFF'>\n"
 "  <table border='0' cellspacing='0' cellpadding='5'>\n"
 "  <tr>\n"
 "   <td>\n"
 "<p>\n"
-"This is a rewrite of dillo, using FLTK2, that comes\n"
-"with lots of improvements and fixes.\n"
-"<p>\n"
-"Our users will surely enjoy this new release as it will give them\n"
-"the  same  things they're accustomed plus tabbed browsing,\n"
-"antialiasing, different\n"
-"character  sets,  accepting  compressed pages, control over image\n"
-"loading, smaller footprint, fewer dependencies, better table\n"
-"rendering, bugfixes, improved GUI, ... In brief, a better dillo.\n"
+"[...]\n"
 "<p>\n"
 "Remember that dillo project uses a release model where every new\n"
 "browser shall be better than the former.\n"
@@ -272,69 +264,20 @@
 " <td bgcolor='#CCCCCC'>\n"
 "  <h4>ChangeLog highlights</h4>\n"
 "  (Extracted from the\n"
-"  <a href='http://cvs.auriga.wearlab.de/cgi-bin/cvsweb.cgi/dillo2/ChangeLog?rev=HEAD;cvsroot=dillo'>full\n"
+"  <a href='http://freehg.org/u/dillo/main/file/tip/ChangeLog'>full\n"
 "  ChangeLog</a>)\n"
 "<tr>\n"
 " <td bgcolor='#FFFFFF'>\n"
 "  <table border='0' cellspacing='0' cellpadding='5'>\n"
 "  <tr>\n"
 "   <td>\n"
+"Dillo:<br>\n"
 "<ul>\n"
-"<li>Ported Dillo from GTK1 to FLTK2."
-"<li>Ported a susbstantial part of the code from C to C++ (FLTK2 is in C++)."
-"<li>Wrote a new library: Dlib. With 'Dlib' Dillo doesn't need glib anymore."
-"<li>Ported all the code to Dlib."
-"<li>Made Dillo's UI Control Panel resizable on-the-fly."
-"<li>Implemented a new, simpler, dillorc parser."
-"<li>Reimplemented the Concomitant Callback chains into a uniform scheme!"
-"<li>Removed threads from IO. Now it only uses select-based watches."
-"<li>Simplified http.c by reusing the new non-blocking writes in IO."
-"<li>Implemented Stop button to not only stop rendering but also networking."
-"<li>Bound Ctrl+Space to toggle fullscreen mode."
-"<li>Added a http_referer preference. See details in dillorc."
-"<li>CCC: added reentrancy control to the OpEnd and OpAbort operations."
-"<li>CCC: enhanced the debug function and implemented OpAbort for dpi."
-"<li>Hooked a decoder for text/plain with charset."
-"<li>Forbid dpi GET and POST from non dpi-generated urls."
-"<li>Implemented tabbed browsing."
-"<li>Added a image-loading toggle button to the UI."
-"<li>Added line numbers and enabled wrapping in the 'View Source' window."
-"<li>Added HTTP-1.1's chunked transfer support!"
-"<li>Made the stop button sensitive when loading an image."
-"<li>Added support for 'charset' in the HTTP header field for Content-Type."
-"<li>Added support for 'charset' in the META element."
-"<li>Added the multipart/form-data encoding method to form submission."
-"<li>Made zlib a configure requirement, and cleaned up configure.in."
-"<li>Enabled the file dpi to look inside gzipped files."
-"<li>Added code for optional image loading (nice interface)!"
-"<li>Fixed data guesser to detect ASCII, LATIN1, UTF8, KOI8-R, CP-1251 as"
-" text."
-"<li>Fixed void to int conversions for 64bit-arch."
-"<li>Set the url resolver to escape illegal chars instead of stripping."
-"<li>Big html.cc cleanup. New classes, form API, source split."
-"<li>Added int32_t, EAI_NODATA and iconv tests for FreeBSD."
-"<li>Replaced the findtext dialog with an in-window widget!"
+"<li>[...]"
 "</ul>\n"
-"Dw2:<br>\n"
+"Dw:<br>\n"
 "<ul>\n"
-"<li>Enabled clipped redraws (avoids some flickering)."
-"<li>Added combination of drawing rectangles into a larger one."
-"<li>Made getWidgetAtPoint() a virtual method of widget and implemented a"
-"   custom one for TextBlock, reducing CPU usage on pages full of links."
-"<li>Set FltkViewBase::draw to intersect with view area for expose."
-"<li>Added double buffering for partial redraws!"
-"<li>Reduced memory usage in 30% by reusing styles, reducing the size"
-"   of struct Content, and not preallocating in SimpleVector. !"
-"<li>Moved highlighting information from struct Word into Textblock"
-"   to save memory."
-"<li>Reduced memory usage 10% with a custom memory handler in Textblock."
-"<li>Implemented selection of multibyte glyphs (UTF-8)."
-"<li>Fixed a slithery BUG in lout::misc::Stringbuffer."
-"<li>Added 'enter' and 'leave' signals into class Resource."
-"<li>Enabled mouse wheel scrolling."
-"<li>Added setDeleteCallback(DW_Callback_t func, void *data) to widget."
-"   This allows to hook a callback when the widget is destroyed."
-"<li>Changed the table-apportion algorithms + bug fixes. Big work!"
+"<li>[...]"
 "</ul>\n"
 "  </table>\n"
 "</table>\n"
--- a/src/IO/http.c	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/IO/http.c	Sun Dec 28 17:17:41 2008 +0100
@@ -197,7 +197,8 @@
  */
 Dstr *a_Http_make_query_str(const DilloUrl *url, bool_t use_proxy)
 {
-   char *ptr, *cookies, *auth, *referer;
+   const char *auth;
+   char *ptr, *cookies, *referer;
    Dstr *query      = dStr_new(""),
         *full_path  = dStr_new(""),
         *proxy_auth = dStr_new("");
--- a/src/auth.c	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/auth.c	Sun Dec 28 17:17:41 2008 +0100
@@ -295,21 +295,20 @@
    int i, j;
    int match_length;
 
+   match_length = 0;
    realm_best = NULL;
    for (i = 0; (realm = dList_nth_data(host->realms, i)); i++) {
       char *realm_path;
 
       for (j = 0; (realm_path = dList_nth_data(realm->paths, j)); j++) {
-         int realm_path_length;
-
-         realm_path_length = strlen(realm_path);
+         int realm_path_length = strlen(realm_path);
          if (Auth_path_is_inside(path, realm_path, realm_path_length) &&
              !(realm_best && match_length >= realm_path_length)) {
             realm_best = realm;
             match_length = realm_path_length;
          }
-      } /* for (j = 0; (path = ... */
-   } /* for (i = 0; (realm = ... */
+      }
+   }
 
    return realm_best;
 }
@@ -353,7 +352,7 @@
 /*
  * Return the authorization header for an HTTP query.
  */
-char *a_Auth_get_auth_str(const DilloUrl *url)
+const char *a_Auth_get_auth_str(const DilloUrl *url)
 {
    AuthHost_t *host;
    AuthRealm_t *realm;
--- a/src/auth.h	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/auth.h	Sun Dec 28 17:17:41 2008 +0100
@@ -8,7 +8,7 @@
 #include "url.h"
 
 
-char *a_Auth_get_auth_str(const DilloUrl *request_url);
+const char *a_Auth_get_auth_str(const DilloUrl *request_url);
 int a_Auth_do_auth(Dlist *auth_string, const DilloUrl *url);
 void a_Auth_init(void);
 
--- a/src/dicache.c	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/dicache.c	Sun Dec 28 17:17:41 2008 +0100
@@ -33,9 +33,9 @@
  */
 static Dlist *CachedIMGs = NULL;
 
-static int dicache_size_total; /* invariant: dicache_size_total is
-                                * the sum of the image sizes (3*w*h)
-                                * of all the images in the dicache. */
+static uint_t dicache_size_total; /* invariant: dicache_size_total is
+                                   * the sum of the image sizes (3*w*h)
+                                   * of all the images in the dicache. */
 
 /*
  * Compare two dicache nodes
@@ -87,6 +87,7 @@
    entry->BitVec = NULL;
    entry->State = DIC_Empty;
    entry->version = 0;
+
    entry->next = NULL;
 
    return entry;
@@ -223,7 +224,6 @@
 /*
  * Refs the counter of a dicache entry.
  */
-
 DICacheEntry* a_Dicache_ref(const DilloUrl *Url, int version)
 {
    DICacheEntry *entry;
@@ -255,7 +255,6 @@
  */
 void a_Dicache_callback(int Op, CacheClient_t *Client)
 {
-   /* TODO: Handle Op = CA_Abort (to show what was got)  --Jcid */
    uint_t i;
    DilloWeb *Web = Client->Web;
    DilloImage *Image = Web->Image;
@@ -294,7 +293,7 @@
          }
       }
    } else if (Op == CA_Close || Op == CA_Abort) {
-      a_Image_close(Web->Image);
+      a_Image_close(Image);
       a_Bw_close_client(Web->bw, Client->Key);
    }
 }
@@ -309,12 +308,13 @@
                          uint_t width, uint_t height, DilloImgType type)
 {
    DICacheEntry *DicEntry;
-   size_t Size = width * height * 3;
 
    dReturn_if_fail ( Image != NULL && width && height );
    /* Find the DicEntry for this Image */
    DicEntry = Dicache_get_entry_version(url, version);
    dReturn_if_fail ( DicEntry != NULL );
+   /* Parameters already set? */
+   dReturn_if_fail ( DicEntry->State < DIC_SetParms );
 
    /* Initialize the DicEntry */
    DicEntry->linebuf = dNew(uchar_t, width * 3);
@@ -328,14 +328,14 @@
     * Extra code is necessary in Imgbuf to be able to free it */
    //a_Image_imgbuf_ref(DicEntry->v_imgbuf);
 
-   DicEntry->TotalSize = Size;
+   DicEntry->TotalSize = width * height * 3;
    DicEntry->width = width;
    DicEntry->height = height;
    DicEntry->type = type;
    DicEntry->BitVec = a_Bitvec_new((int)height);
    DicEntry->State = DIC_SetParms;
 
-   dicache_size_total += Size;
+   dicache_size_total += DicEntry->TotalSize;
 
    /* Allocate and initialize this image */
    a_Image_set_parms(Image, DicEntry->v_imgbuf, url, version,
--- a/src/dicache.h	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/dicache.h	Sun Dec 28 17:17:41 2008 +0100
@@ -29,7 +29,7 @@
    uchar_t *cmap;          /* Color map */
    uchar_t *linebuf;       /* Decompressed RGB buffer for one line */
    void *v_imgbuf;         /* Void pointer to an Imgbuf object */
-   size_t TotalSize;       /* Amount of memory the image takes up */
+   uint_t TotalSize;       /* Amount of memory the image takes up */
    int Y;                  /* Current decoding row */
    uint_t ScanNumber;      /* Current decoding scan */
    bitvec_t *BitVec;       /* Bit vector for decoded rows */
@@ -37,7 +37,6 @@
    int RefCount;           /* Reference Counter */
    int version;            /* Version number, used for different
                               versions of the same URL image */
-
    DICacheEntry *next;     /* Link to the next "newer" version */
 };
 
--- a/src/dillo.cc	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/dillo.cc	Sun Dec 28 17:17:41 2008 +0100
@@ -47,15 +47,135 @@
 #include "cookies.h"
 #include "auth.h"
 
+/*
+ * Command line options structure
+ */
+typedef enum {
+   DILLO_CLI_NONE          = 0,
+   DILLO_CLI_XID           = 1 << 0,
+   DILLO_CLI_FULLWINDOW    = 1 << 1,
+   DILLO_CLI_HELP          = 1 << 2,
+   DILLO_CLI_VERSION       = 1 << 3,
+   DILLO_CLI_LOCAL         = 1 << 4,
+   DILLO_CLI_GEOMETRY      = 1 << 5,
+   DILLO_CLI_ERROR         = 1 << 15,
+} OptID;
+
+typedef struct {
+   const char *shortopt;
+   const char *longopt;
+   int opt_argc; /* positive: mandatory, negative: optional */
+   OptID id;
+   const char *help;
+} CLI_options;
+
+static const CLI_options Options[] = {
+   {"-f", "--fullwindow", 0, DILLO_CLI_FULLWINDOW,
+    "  -f, --fullwindow       Start in full window mode: hide address bar,\n"
+    "                         navigation buttons, menu, and status bar."},
+   {"-g", "-geometry",    1, DILLO_CLI_GEOMETRY,
+    "  -g, -geometry GEO      Set initial window position where GEO is\n"
+    "                         WxH[{+-}X{+-}Y]"},
+   {"-h", "--help",       0, DILLO_CLI_HELP,
+    "  -h, --help             Display this help text and exit."},
+   {"-l", "--local",      0, DILLO_CLI_LOCAL,
+    "  -l, --local            Don't load images for these URL(s)."},
+   {"-v", "--version",    0, DILLO_CLI_VERSION,
+    "  -v, --version          Display version info and exit."},
+   {"-x", "--xid",        1, DILLO_CLI_XID,
+    "  -x, --xid XID          (DOES NOT WORK YET)\n"
+    "                         Open first Dillo window in an existing\n"
+    "                         GtkSocket which window ID is XID (decimal)."},
+   {NULL, NULL, 0, DILLO_CLI_NONE, NULL}
+};
+
+/*
+ * Print help text generated from the options structure
+ */
+static void Dillo_print_help(const char *cmdname, const CLI_options *options)
+{
+   printf("Usage: %s [OPTION]... [--] [URL|FILE]...\n"
+          "Options:\n", cmdname);
+   while(options && options->help) {
+      printf("%s\n", options->help);
+      options++;
+   }
+   printf("  URL                    URL to browse.\n"
+          "  FILE                   Local FILE to view.\n"
+          "\n");
+}
+
+/*
+ * Return the maximum number of option arguments
+ */
+static int Dillo_get_max_opt(const CLI_options *options)
+{
+   int i, max;
+
+   for (i = 0, max = 0; options[i].shortopt; i++)
+      if (abs(options[i].opt_argc) > max)
+         max = abs(options[i].opt_argc);
+   return max;
+}
+
+/*
+ * Get next command line option.
+ */
+static OptID Dillo_get_opt(const CLI_options *options, int argc, char **argv,
+                           char **opt_argv, int *idx)
+{
+   typedef enum { O_SEARCH, O_FOUND, O_NOTFOUND, O_DONE } State;
+   OptID opt_id = DILLO_CLI_NONE;
+   int i = 0;
+   State state = O_SEARCH;
+
+   if (*idx >= argc) {
+      state = O_DONE;
+   } else {
+      state = O_NOTFOUND;
+      for (i = 0; options[i].shortopt; i++) {
+         if (strcmp(options[i].shortopt, argv[*idx]) == 0 ||
+             strcmp(options[i].longopt, argv[*idx]) == 0) {
+            state = O_FOUND;
+            ++*idx;
+            break;
+         }
+      }
+   }
+   if (state == O_FOUND) {
+      int n_arg = options[i].opt_argc;
+      opt_id  = options[i].id;
+      /* Find the required/optional arguments of the option */
+      for (i = 0; *idx < argc && i < abs(n_arg) && argv[*idx][0] != '-'; i++)
+         opt_argv[i] = argv[(*idx)++];
+      opt_argv[i] = NULL;
+
+      /* Optional arguments have opt_argc < 0 */
+      if (i < n_arg) {
+         fprintf(stderr, "Option %s requires %d argument%s\n",
+                 argv[*idx-i-1], n_arg, (n_arg == 1) ? "" : "s");
+         opt_id = DILLO_CLI_ERROR;
+      }
+   }
+   if (state == O_NOTFOUND) {
+      if (strcmp(argv[*idx], "--") == 0)
+         (*idx)++;
+      else if (argv[*idx][0] == '-') {
+         fprintf(stderr, "Command line option \"%s\" not recognized.\n",
+                 argv[*idx]);
+         opt_id = DILLO_CLI_ERROR;
+      }
+   }
+   return opt_id;
+}
 
 /*
  * Given a command line argument, build a DilloUrl for it.
  */
-static DilloUrl *Dillo_make_start_url(char *str)
+static DilloUrl *Dillo_make_start_url(char *str, bool local)
 {
    char *url_str, *p;
    DilloUrl *start_url;
-   int is_file = FALSE;
 
    /* Relative path to a local file? */
    p = (*str == '/') ? dStrdup(str) : dStrconcat(a_Dir_get_owd(),"/",str,NULL);
@@ -63,19 +183,17 @@
    if (access(p, F_OK) == 0) {
       /* absolute path may have non-URL characters */
       url_str = a_Misc_escape_chars(p, "% ");
-      is_file = TRUE;
+      start_url = a_Url_new(url_str + 1, "file:/");
    } else {
       /* Not a file, filter URL string */
       url_str = a_Url_string_strip_delimiters(str);
+      start_url = a_Url_new(url_str, NULL);
    }
    dFree(p);
+   dFree(url_str);
 
-   if (is_file) {
-      start_url = a_Url_new(url_str + 1, "file:/");
-   } else {
-      start_url = a_Url_new(url_str, NULL);
-   }
-   dFree(url_str);
+   if (local)
+      a_Url_set_flags(start_url, URL_FLAGS(start_url) | URL_SpamSafe);
 
    return start_url;
 }
@@ -85,11 +203,58 @@
  */
 int main(int argc, char **argv)
 {
+   uint opt_id;
+   uint options_got = 0;
+   uint32_t xid = 0;
+   int idx = 1;
+   int xpos = D_GEOMETRY_DEFAULT_XPOS, ypos = D_GEOMETRY_DEFAULT_YPOS;
+   int width = D_GEOMETRY_DEFAULT_WIDTH, height = D_GEOMETRY_DEFAULT_HEIGHT;
+   char **opt_argv;
+
    srand((uint_t)(time(0) ^ getpid()));
 
    // Some OSes exit dillo without this (not GNU/Linux).
    signal(SIGPIPE, SIG_IGN);
 
+   /* Handle command line options */
+   opt_argv = dNew0(char*, Dillo_get_max_opt(Options) + 1);
+   while ((opt_id = Dillo_get_opt(Options, argc, argv, opt_argv, &idx))) {
+      options_got |= opt_id;
+      switch (opt_id) {
+      case DILLO_CLI_FULLWINDOW:
+      case DILLO_CLI_LOCAL:
+         break;
+      case DILLO_CLI_XID:
+      {
+         char *end;
+         xid = strtol(opt_argv[0], &end, 10);
+         if (*end) {
+            fprintf(stderr, "XID argument \"%s\" not valid. Must be an "
+                            "unsigned decimal number.\n",opt_argv[0]);
+            return -1;
+         }
+         break;
+      }
+      case DILLO_CLI_GEOMETRY:
+         if (!a_Misc_parse_geometry(opt_argv[0], &xpos, &ypos,&width,&height)){
+            fprintf(stderr, "geometry argument \"%s\" not valid. Must be of "
+                            "the form WxH[{+-}X{+-}Y].\n", opt_argv[0]);
+            return -1;
+         }
+         break;
+      case DILLO_CLI_VERSION:
+         puts("Dillo version " VERSION);
+         return 0;
+      case DILLO_CLI_HELP:
+         Dillo_print_help(argv[0], Options);
+         return 0;
+      default:
+         Dillo_print_help(argv[0], Options);
+         return -1;
+      }
+   }
+   dFree(opt_argv);
+
    // Initialize internal modules
    a_Dir_init();
    a_Prefs_init();
@@ -105,12 +270,23 @@
    a_Cookies_init();
    a_Auth_init();
 
+   /* command line options override preferences */
+   if (options_got & DILLO_CLI_FULLWINDOW)
+      prefs.fullwindow_start = TRUE;
+   if (options_got & DILLO_CLI_GEOMETRY) {
+       prefs.width = width;
+       prefs.height = height;
+       prefs.xpos = xpos;
+       prefs.ypos = ypos;
+   }
+
    // Sets WM_CLASS hint on X11
    fltk::Window::xclass("dillo");
 
    // WORKAROUND: sometimes the default pager triggers redraw storms
    fltk::TabGroup::default_pager(fltk::PAGER_SHRINK);
 
+   /* use preferred font for UI */
    fltk::Font *dfont = fltk::font(prefs.vw_fontname, 0);
    if (dfont) {
       fltk::Widget::default_style->textfont(dfont);
@@ -120,6 +296,7 @@
    // Create a new UI/bw pair
    BrowserWindow *bw = a_UIcmd_browser_window_new(0, 0, NULL);
 
+   /* Proxy authentication */
    if (prefs.http_proxyuser && !a_Http_proxy_auth()) {
       const char *passwd = a_UIcmd_get_passwd(prefs.http_proxyuser);
       if (passwd) {
@@ -129,23 +306,29 @@
       }
    }
 
-   if (argc == 2) {
-      DilloUrl *url = Dillo_make_start_url(argv[1]);
-      a_UIcmd_open_urlstr(bw, URL_STR(url));
-      a_Url_free(url);
-   } else if (argc == 6) {
-      // WORKAROUND: sylpheed execs "dillo -l -f -x XID URL"
-      if (strcmp(argv[1], "-l") == 0 && strcmp(argv[2], "-f") == 0 &&
-          strcmp(argv[3], "-x") == 0) {
-         a_UIcmd_set_images_enabled(bw, FALSE);
-         DilloUrl *url = Dillo_make_start_url(argv[5]);
-         a_Url_set_flags(url, URL_FLAGS(url) & URL_SpamSafe);
-         a_UIcmd_open_urlstr(bw, URL_STR(url));
-         a_Url_free(url);
+   /* Open URLs/files */
+   const bool local = options_got & DILLO_CLI_LOCAL;
+
+   if (idx == argc) {
+      /* No URLs/files on cmdline. Send startup screen */
+      a_Nav_push(bw, prefs.start_page);
+   } else {
+      for (int i = idx; i < argc; i++) {
+         DilloUrl *start_url = Dillo_make_start_url(argv[i], local);
+
+         if (i > idx) {
+            if (prefs.middle_click_opens_new_tab) {
+               /* user must prefer tabs */
+               const int focus = 0;
+               a_UIcmd_open_url_nt(bw, start_url, focus);
+            } else {
+               a_UIcmd_open_url_nw(bw, start_url);
+            }
+         } else {
+            a_Nav_push(bw, start_url);
+         }
+         a_Url_free(start_url);
       }
-   } else {
-      /* Send startup screen */
-      a_Nav_push(bw, prefs.start_page);
    }
 
    return fltk::run();
--- a/src/form.cc	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/form.cc	Sun Dec 28 17:17:41 2008 +0100
@@ -76,7 +76,6 @@
 
    DilloHtml *html;
    void eventHandler(Resource *resource, EventButton *event);
-   void submit(DilloHtmlInput *active_input, EventButton *event);
    DilloUrl *buildQueryUrl(DilloHtmlInput *active_input);
    Dstr *buildQueryData(DilloHtmlInput *active_submit);
    char *makeMultipartBoundary(iconv_t char_encoder,
@@ -113,6 +112,7 @@
    ~DilloHtmlForm ();
    DilloHtmlInput *getInput (Resource *resource);
    DilloHtmlInput *getRadioInput (const char *name);
+   void submit(DilloHtmlInput *active_input, EventButton *event);
    void reset ();
    void addInput(DilloHtmlInput *input, DilloHtmlInputType type);
 };
@@ -206,6 +206,16 @@
    delete input;
 }
 
+void a_Html_form_submit2(void *vform)
+{
+   ((DilloHtmlForm *)vform)->submit(NULL, NULL);
+}
+
+void a_Html_form_reset2(void *vform)
+{
+   ((DilloHtmlForm *)vform)->reset();
+}
+
 /*
  * Form parsing functions
  */
@@ -332,7 +342,7 @@
 
 void Html_tag_close_form(DilloHtml *html, int TagIdx)
 {
-   static const char *SubmitTag =
+   static const char *const SubmitTag =
       "<input type='submit' value='?Submit?' alt='dillo-generated-button'>";
    DilloHtmlForm *form;
 // int i;
@@ -945,7 +955,7 @@
 {
    MSG("DilloHtmlForm::eventHandler\n");
    if (event && (event->button == 3)) {
-      MSG("Form menu\n");
+      a_UIcmd_form_popup(html->bw, html->page_url, this);
    } else {
       DilloHtmlInput *input = getInput(resource);
       if (input) {
@@ -996,7 +1006,7 @@
 
       _MSG("DilloHtmlForm::buildQueryUrl: action=%s\n",URL_STR_(action));
 
-      if (num_submit_buttons > 0) {
+      if (active_input && num_submit_buttons > 0) {
          if ((active_input->type == DILLO_HTML_INPUT_SUBMIT) ||
              (active_input->type == DILLO_HTML_INPUT_IMAGE) ||
              (active_input->type == DILLO_HTML_INPUT_BUTTON_SUBMIT)) {
@@ -1727,6 +1737,7 @@
    switch (type) {
    case DILLO_HTML_INPUT_TEXT:
    case DILLO_HTML_INPUT_PASSWORD:
+   case DILLO_HTML_INPUT_INDEX:
       {
          EntryResource *entryres = (EntryResource*)embed->getResource();
          entryres->setText(init_str ? init_str : "");
--- a/src/form.hh	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/form.hh	Sun Dec 28 17:17:41 2008 +0100
@@ -38,6 +38,9 @@
 
 void a_Html_form_delete(DilloHtmlForm* form);
 void a_Html_input_delete(DilloHtmlInput* input);
+void a_Html_form_submit2(void *v_form);
+void a_Html_form_reset2(void *v_form);
+
 
 /*
  * Form parsing functions 
--- a/src/html.cc	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/html.cc	Sun Dec 28 17:17:41 2008 +0100
@@ -215,6 +215,45 @@
 }
 
 /*
+ * Search for form 
+ */
+static bool Html_contains_form(DilloHtml *html, void *v_form)
+{
+   for (int i = 0; i < html->forms->size(); i++) {
+      if (html->forms->get(i) == v_form) {
+         return true;
+      }
+   }
+   return false;
+}
+
+/*
+ * Used by the "Submit form" form menuitem.
+ */
+void a_Html_form_submit(void *v_html, void *v_form)
+{
+   DilloHtml *html = (DilloHtml*)v_html;
+
+   if (Html_contains_form(html, v_form)) {
+      /* it's still valid */              
+     a_Html_form_submit2(v_form);
+   }                          
+}
+
+/*
+ * Used by the "Reset form" form menuitem.
+ */
+void a_Html_form_reset(void *v_html, void *v_form)
+{
+   DilloHtml *html = (DilloHtml*)v_html;
+
+   if (Html_contains_form(html, v_form)) {
+      /* it's still valid */            
+     a_Html_form_reset2(v_form);
+   }
+}
+
+/*
  * Set the URL data for image maps.
  */
 static void Html_set_link_coordinates(DilloHtml *html, int link, int x, int y)
--- a/src/html.hh	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/html.hh	Sun Dec 28 17:17:41 2008 +0100
@@ -11,6 +11,8 @@
  * Exported functions
  */
 void a_Html_load_images(void *v_html, DilloUrl *pattern);
+void a_Html_form_submit(void *v_html, void *v_form);
+void a_Html_form_reset(void *v_html, void *v_form);
 
 #ifdef __cplusplus
 }
--- a/src/image.cc	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/image.cc	Sun Dec 28 17:17:41 2008 +0100
@@ -54,7 +54,6 @@
    Image->cmap = NULL;
    Image->in_type = DILLO_IMG_TYPE_NOTSET;
    Image->bg_color = bg_color;
-   Image->ProcessedBytes = 0;
    Image->ScanNumber = 0;
    Image->BitVec = NULL;
    Image->State = IMG_Empty;
@@ -172,7 +171,7 @@
 void a_Image_write(DilloImage *Image, void *v_imgbuf,
                    const uchar_t *buf, uint_t y, int decode)
 {
-   uchar_t *newbuf;
+   const uchar_t *newbuf;
 
    dReturn_if_fail ( y < Image->height );
 
--- a/src/image.hh	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/image.hh	Sun Dec 28 17:17:41 2008 +0100
@@ -42,7 +42,6 @@
    DilloImgType in_type;    /* Image Type */
    int32_t bg_color;        /* Background color */
 
-   int ProcessedBytes;      /* Amount of bytes already decoded */
    bitvec_t *BitVec;        /* Bit vector for decoded rows */
    uint_t ScanNumber;       /* Current decoding scan */
    ImageState State;        /* Processing status */
--- a/src/menu.cc	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/menu.cc	Sun Dec 28 17:17:41 2008 +0100
@@ -38,7 +38,7 @@
 // Weak reference to the popup's bw
 static BrowserWindow *popup_bw = NULL;
 // Where to place the filemenu popup
-int popup_x, popup_y;
+static int popup_x, popup_y;
 // History popup direction (-1 = back, 1 = forward).
 static int history_direction = -1; 
 // History popup, list of URL-indexes.
@@ -212,6 +212,44 @@
    }
 }
 
+/*
+ * Submit form
+ */
+static void Menu_form_submit_cb(Widget*, void *v_form)
+{
+  if (popup_bw && popup_bw->Docs) {
+      if (dList_find_custom(popup_bw->PageUrls, popup_url,
+                            (dCompareFunc)a_Url_cmp)){
+         /* HTML page is still there */
+         int n = dList_length(popup_bw->Docs);
+         if (n == 1) {
+            a_Html_form_submit(dList_nth_data(popup_bw->Docs, 0), v_form);
+         } else if (n > 1) {
+            MSG ("Menu_form_submit_cb multiple Docs not implemented\n");
+         }
+      }
+   }
+}
+
+/*
+ * Reset form
+ */
+static void Menu_form_reset_cb(Widget*, void *v_form)
+{
+   if (popup_bw && popup_bw->Docs) {
+      if (dList_find_custom(popup_bw->PageUrls, popup_url,
+                            (dCompareFunc)a_Url_cmp)){
+         /* HTML page is still there */
+         int n = dList_length(popup_bw->Docs);
+         if (n == 1) {
+            a_Html_form_reset(dList_nth_data(popup_bw->Docs, 0), v_form);
+         } else if (n > 1) {
+            MSG ("Menu_form_reset_cb multiple Docs not implemented\n");
+         }
+      }
+   }
+}
+
 /* 
  * Validate URL with the W3C
  */
@@ -452,6 +490,31 @@
 }
 
 /*
+ * Form popup menu (construction & popup)
+ */
+void a_Menu_form_popup(BrowserWindow *bw, const DilloUrl *page_url,
+                       void *formptr)
+{
+   static PopupMenu *pm = 0;
+
+   popup_bw = bw;
+   a_Url_free(popup_url);
+   popup_url = a_Url_dup(page_url);
+   if (!pm) {
+     Item *i;
+      pm = new PopupMenu(0,0,0,0,"FORM OPTIONS");
+      pm->add(i = new Item("Submit form"));
+      i->callback(Menu_form_submit_cb);
+      pm->add(i = new Item("Reset form"));
+      i->callback(Menu_form_reset_cb);
+      pm->type(PopupMenu::POPUP123);
+   }
+   pm->user_data(formptr);
+
+   a_Timeout_add(0.0, Menu_popup_cb, (void *)pm);
+}
+
+/*
  * File popup menu (construction & popup)
  */
 void a_Menu_file_popup(BrowserWindow *bw, void *v_wid)
--- a/src/menu.hh	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/menu.hh	Sun Dec 28 17:17:41 2008 +0100
@@ -12,6 +12,8 @@
 void a_Menu_link_popup(BrowserWindow *bw, const DilloUrl *url);
 void a_Menu_image_popup(BrowserWindow *bw, const DilloUrl *url,
                         bool_t loaded_img, DilloUrl *link_url);
+void a_Menu_form_popup(BrowserWindow *bw, const DilloUrl *page_url,
+                       void *vform);
 void a_Menu_file_popup(BrowserWindow *bw, void *v_wid);
 void a_Menu_bugmeter_popup(BrowserWindow *bw, const DilloUrl *url);
 void a_Menu_history_popup(BrowserWindow *bw, int direction);
--- a/src/nav.c	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/nav.c	Sun Dec 28 17:17:41 2008 +0100
@@ -200,7 +200,7 @@
 
    MSG("Nav_open_url: new url='%s'\n", URL_STR_(url));
 
-   Repush = (URL_FLAGS(url) & URL_ReloadFromCache);
+   Repush = (URL_FLAGS(url) & URL_ReloadFromCache) != 0;
    ForceReload = (URL_FLAGS(url) & (URL_E2EQuery + URL_ReloadFromCache)) != 0;
 
    /* Get the url of the current page */
--- a/src/png.c	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/png.c	Sun Dec 28 17:17:41 2008 +0100
@@ -4,6 +4,7 @@
  *
  * Geoff Lane nov 1999 zzassgl@twirl.mcc.ac.uk
  * Luca Rota, Jorge Arellano Cid, Eric Gaudet 2000
+ * Jorge Arellano Cid 2009
  *
  * "PNG: The Definitive Guide" by Greg Roelofs, O'Reilly
  * ISBN 1-56592-542-4
@@ -67,19 +68,19 @@
 struct _DilloPng {
    DilloImage *Image;           /* Image meta data */
    DilloUrl *url;               /* Primary Key for the dicache */
-   int version;                /* Secondary Key for the dicache */
+   int version;                 /* Secondary Key for the dicache */
 
    double display_exponent;     /* gamma correction */
-   ulong_t width;                /* png image width */
-   ulong_t height;               /* png image height */
+   ulong_t width;               /* png image width */
+   ulong_t height;              /* png image height */
    png_structp png_ptr;         /* libpng private data */
    png_infop info_ptr;          /* libpng private info */
-   uchar_t *image_data;          /* decoded image data    */
-   uchar_t **row_pointers;       /* pntr to row starts    */
+   uchar_t *image_data;         /* decoded image data    */
+   uchar_t **row_pointers;      /* pntr to row starts    */
    jmp_buf jmpbuf;              /* png error processing */
-   int error;                  /* error flag */
+   int error;                   /* error flag */
    png_uint_32 previous_row;
-   int rowbytes;               /* No. bytes in image row */
+   int rowbytes;                /* No. bytes in image row */
    short passes;
    short channels;              /* No. image channels */
 
@@ -92,13 +93,13 @@
  * ipbuf    ipbufstart                            ipbufsize
  */
 
-   uchar_t *ipbuf;               /* image data in buffer */
-   int ipbufstart;             /* first valid image byte */
-   int ipbufsize;              /* size of valid data in */
+   uchar_t *ipbuf;              /* image data in buffer */
+   int ipbufstart;              /* first valid image byte */
+   int ipbufsize;               /* size of valid data in */
 
    enum prog_state state;       /* FSM current state  */
 
-   uchar_t *linebuf;             /* o/p raster data */
+   uchar_t *linebuf;            /* o/p raster data */
 
 } DilloPng;
 
@@ -297,57 +298,37 @@
    png->state = IS_finished;
 }
 
+/*
+ * Finish the decoding process (and free the memory)
+ */
+static void Png_close(DilloPng *png, CacheClient_t *Client)
+{
+   /* Free up the resources for this image */
+   a_Dicache_close(png->url, png->version, Client);
+   dFree(png->image_data);
+   dFree(png->row_pointers);
+   dFree(png->linebuf);
+
+   if (setjmp(png->jmpbuf))
+      MSG_WARN("PNG: can't destroy read structure\n");
+   else if (png->png_ptr)
+      png_destroy_read_struct(&png->png_ptr, &png->info_ptr, NULL);
+   dFree(png);
+}
 
 /*
- * Op:  Operation to perform.
- *   If (Op == 0)
- *      start or continue processing an image if image data exists.
- *   else
- *       terminate processing, cleanup any allocated memory,
- *       close down the decoding process.
- *
- * Client->CbData  : pointer to previously allocated DilloPng work area.
- *  This holds the current state of the image processing and is saved
- *  across calls to this routine.
- * Client->Buf     : Pointer to data start.
- * Client->BufSize : the size of the data buffer.
- *
- * You have to keep track of where you are in the image data and
- * how much has been processed.
- *
- * It's entirely possible that you will not see the end of the data.  The
- * user may terminate transfer via a Stop button or there may be a network
- * failure.  This means that you can't just wait for all the data to be
- * presented before starting conversion and display.
+ * Receive and process new chunks of PNG image data
  */
-static void Png_callback(int Op, CacheClient_t *Client)
+static void Png_write(DilloPng *png, void *Buf, uint_t BufSize)
 {
-   DilloPng *png = Client->CbData;
-
-   if (Op) {
-      /* finished - free up the resources for this image */
-      a_Dicache_close(png->url, png->version, Client);
-      dFree(png->image_data);
-      dFree(png->row_pointers);
-      dFree(png->linebuf);
+   dReturn_if_fail ( Buf != NULL && BufSize > 0 );
 
-      if (setjmp(png->jmpbuf))
-         MSG_WARN("PNG: can't destroy read structure\n");
-      else if (png->png_ptr)
-         png_destroy_read_struct(&png->png_ptr, &png->info_ptr, NULL);
-      dFree(png);
-      return;
-   }
-
-   /* Let's make some sound if we have been called with no data */
-   dReturn_if_fail ( Client->Buf != NULL && Client->BufSize > 0 );
-
-   _MSG("Png_callback BufSize = %d\n", Client->BufSize);
+   _MSG("Png_callback BufSize = %d\n", BufSize);
 
    /* Keep local copies so we don't have to pass multiple args to
     * a number of functions. */
-   png->ipbuf = Client->Buf;
-   png->ipbufsize = Client->BufSize;
+   png->ipbuf = Buf;
+   png->ipbufsize = BufSize;
 
    /* start/resume the FSM here */
    while (png->state != IS_finished && DATASIZE) {
@@ -408,6 +389,37 @@
 }
 
 /*
+ * Op:  Operation to perform.
+ *   If (Op == 0)
+ *      start or continue processing an image if image data exists.
+ *   else
+ *       terminate processing, cleanup any allocated memory,
+ *       close down the decoding process.
+ *
+ * Client->CbData  : pointer to previously allocated DilloPng work area.
+ *  This holds the current state of the image processing and is kept
+ *  across calls to this routine.
+ * Client->Buf     : Pointer to data start.
+ * Client->BufSize : the size of the data buffer.
+ *
+ * You have to keep track of where you are in the image data and
+ * how much has been processed.
+ *
+ * It's entirely possible that you will not see the end of the data.  The
+ * user may terminate transfer via a Stop button or there may be a network
+ * failure.  This means that you can't just wait for all the data to be
+ * presented before starting conversion and display.
+ */
+static void Png_callback(int Op, CacheClient_t *Client)
+{
+   if (Op) { /* EOF */
+      Png_close(Client->CbData, Client);
+   } else {
+      Png_write(Client->CbData, Client->Buf, Client->BufSize);
+   }
+}
+
+/*
  * Create the image state data that must be kept between calls
  */
 static DilloPng *Png_new(DilloImage *Image, DilloUrl *url, int version)
@@ -433,25 +445,19 @@
 /*
  * MIME handler for "image/png" type
  * (Sets Png_callback or a_Dicache_callback as the cache-client)
+ *
+ * Parameters:
+ *   Type: MIME type
+ *   Ptr:  points to a Web structure
+ *   Call: Dillo calls this with more data/eod
+ *   Data: Decoding data structure
  */
 void *a_Png_image(const char *Type, void *Ptr, CA_Callback_t *Call,
                   void **Data)
 {
-/*
- * Type: MIME type
- * Ptr:  points to a Web structure
- * Call: Dillo calls this with more data/eod
- * Data: raw image data
- */
-
    DilloWeb *web = Ptr;
    DICacheEntry *DicEntry;
 
-   _MSG("a_Png_image: Type = %s\n"
-        "a_Png_image: libpng - Compiled %s; using %s.\n"
-        "a_Png_image: zlib   - Compiled %s; using %s.\n",
-        Type, PNG_LIBPNG_VER_STRING, png_libpng_ver,ZLIB_VERSION,zlib_version);
-
    if (!web->Image)
       web->Image = a_Image_new(0, 0, NULL, prefs.bg_color);
 
--- a/src/prefs.c	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/prefs.c	Sun Dec 28 17:17:41 2008 +0100
@@ -35,10 +35,6 @@
 
 #define DILLO_START_PAGE "about:splash"
 #define DILLO_HOME "http://www.dillo.org/"
-#define D_GEOMETRY_DEFAULT_WIDTH   780
-#define D_GEOMETRY_DEFAULT_HEIGHT  580
-#define D_GEOMETRY_DEFAULT_XPOS  -9999
-#define D_GEOMETRY_DEFAULT_YPOS  -9999
 
 #define D_VW_FONTNAME "DejaVu Sans"
 #define D_FW_FONTNAME "DejaVu Sans Mono"
--- a/src/prefs.h	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/prefs.h	Sun Dec 28 17:17:41 2008 +0100
@@ -7,6 +7,11 @@
 extern "C" {
 #endif /* __cplusplus */
 
+#define D_GEOMETRY_DEFAULT_WIDTH   780
+#define D_GEOMETRY_DEFAULT_HEIGHT  580
+#define D_GEOMETRY_DEFAULT_XPOS  -9999
+#define D_GEOMETRY_DEFAULT_YPOS  -9999
+
 /* Panel sizes */
 enum { P_tiny = 0, P_small, P_medium, P_large };
 
--- a/src/ui.cc	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/ui.cc	Sun Dec 28 17:17:41 2008 +0100
@@ -993,7 +993,8 @@
  */
 void UI::color_change_cb_i()
 {
-   static int ncolor = 0, cols[] = {7,17,26,51,140,156,205,206,215,-1};
+   const int cols[] = {7,17,26,51,140,156,205,206,215,-1};
+   static int ncolor = 0;
 
    ncolor = (cols[ncolor+1] < 0) ? 0 : ncolor + 1;
    CuteColor = cols[ncolor];
--- a/src/uicmd.cc	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/uicmd.cc	Sun Dec 28 17:17:41 2008 +0100
@@ -666,6 +666,14 @@
 }
 
 /*
+ * Pop up the form menu
+ */
+void a_UIcmd_form_popup(void *vbw, const DilloUrl *url, void *vform)
+{
+   a_Menu_form_popup((BrowserWindow*)vbw, url, vform);
+}
+
+/*
  * Pop up the file menu
  */
 void a_UIcmd_file_popup(void *vbw, void *v_wid)
--- a/src/uicmd.hh	Sun Dec 21 16:40:36 2008 -0300
+++ b/src/uicmd.hh	Sun Dec 28 17:17:41 2008 +0100
@@ -41,6 +41,7 @@
 void a_UIcmd_link_popup(void *vbw, const DilloUrl *url);
 void a_UIcmd_image_popup(void *vbw, const DilloUrl *url, bool_t loaded_img,
                          DilloUrl *link_url);
+void a_UIcmd_form_popup(void *vbw, const DilloUrl *url, void *vform);
 void a_UIcmd_file_popup(void *vbw, void *v_wid);
 void a_UIcmd_copy_urlstr(BrowserWindow *bw, const char *urlstr);
 void a_UIcmd_view_page_source(const DilloUrl *url);