Links -- a port of the graphical web browser for Plan 9
News:
20/05/2005:
- From Gorka Guardiola Múzquiz: When there is a lookup error in part of the page, for example a photo, it hangs with the last pull from sources. download the fixed file: links-varfont.tgz...
- Gorka Guardiola Múzquiz submitted a patch to varfont links which fixes variable-width font rendering. looks much better now (new screenshots if i don't forget). download links-varfont.tgz...
- Steve Simon submitted a patch to varfont links which fixes a crashing bug.
- Fixed down arrow key...
- Check out the difference between the old, static font links and the variable-size one, done using the Vera fonts (note that the varsize fonts have been created without antialiasing):
- To download the new code click here: links-varfont.tgz
- Compile and see the 'runme' file for information on how to start up links.
- For various fonts look in the ../9fonts/ directory. Make sure you use the ttfy script to create the fonts with proper sizes.
- Warning: there's a problem with links' font width calculation, but I can't find it for the love of me... null-size glyphs should appear as squares instead of leaving a blank spot. Fixes would be most welcome!
- New binary and source fix a problem with memcpy which could crash small-memory terminals.
- Links finally rendering using Plan 9 fonts! For now it renders in a single size only, but arrangements have been made to use multiple size fonts as soon as reasonable descriptions of such files have been created in /lib/font/bit/. Make sure to check the screenshots!
Improvements in speed and responsiveness are huge -- yahoo is rendered in 1.75 seconds, slashdot's front page in 3. - No more font_data[]. The binary is now 3.2MB instead of 4.6MB. The archive is just 2MB.
- Geoff Collyer's changes finally made it in. This introduces a few problems:
- Killing Links may leave a broken process. The recommended fix for now is to do:
#!/bin/rc real-links $* broke | rc kill links | rc
- Gorka Guardiola has sent a patch allowing Links to plumb to Plan 9, this allows files such as PDF or PS to be viewed directly in Plan 9's viewer. We are currently experimenting with plumbing images too.
- You need the following two rules for the plumber (put them at the end of basic, or in your lib/plumbing file):
src is links #eliminate recursive links type is text data matches '(https?|ftp|file|gopher|mailto|news|nntp|telnet|wais|prospero)://[a-zA-Z0-9_@\-]+([.:][a-zA-Z0-9_@\-]+)*/?[a-zA-Z0-9_?,%#~&/\-+=]+([:.][a-zA-Z0-9_?,%#~&/\-+=]+)*' plumb to none type is text data matches '(https?|ftp|file|gopher|mailto|news|nntp|telnet|wais|prospero)://[a-zA-Z0-9_@\-]+([.:][a-zA-Z0-9_@\-]+)*/?[a-zA-Z0-9_?,%#~&/\-+=]+([:.][a-zA-Z0-9_?,%#~&/\-+=]+)*' plumb start window links $0
- Changed select() timeout to 0.1 seconds (from 0.001 secs). now Links makes less syscalls without slowing down percieved responsiveness too much.
- Dave Presotto made select() in Plan 9 Links-safe. Now sites such as nytimes.com, cnn.com and theregister.co.uk open without too much fuss. This exposes other possible problems, but for now one major hurdle is gone.
- Fixed problem with rendering large gif images, implemented prepare_strip for that (X11 programs use a special optimization allowing links to draw directly to video memory, we can't do that without teaching Links to understand draw() functions). There is a library flush problem that persists, unsure if it's links or the libdraw APE port.
- Added a handler for refreshing the screen (good for flushing out large images). Ins does it. If not -- wiggle the mouse with the middle button pressed. Then hit Ins again.
- Initial release.
- Fixed many little problems with the makefiles and extra libraries, thanks to Dave Presotto for noticing them.
- Removed leftover binaries that haven't been cleaned by the mkfiles properly.
- Changed the dependency between the different support libraries. Should compile properly now.
- Fixed a bug in the ordering of bytes -- it was BGR instead of RGB, this could be just my choice of incorrect get_color routine, and everything that is not a bitmap (such as text and images) was drawn with swapped red and blue values. This is now fixed.
This is a port of the Links web browser using only its graphical web browser capabilities (i.e. it doesn't run in a terminal, but in a rio window). The version the port is based on is 2.1pre14.
Download:
links-varfont.tgz -- source, 2MB.
links-ape.tgz -- source, 2MB.
links-386.gz -- binary for 386, 730KB.
Build:
% hget http://mirtchovski.com/p9/links/links-ape.tgz | gunzip | tar xv % cd links-ape % mk % mk installThis will put a single binary called links in $home/bin/386... The binary is ~2MB (now without font_data[]).
Screenshots:
Why:
There have been many different solutions to web browsing in Plan 9, mostly involving either horribly outdated browsers (i and mothra), installing of a different operating system or having a separate machine on which to run the browser via vnc.
This projects attempts to bring a reasonably up-to-date browser as a native application. Links renders pages in a readable manner (most of the time) and with features such as JavaScript support, UTF rendering of non-english text pages, etc. becomes a good solution for light web browsing. It is released in a slightly mangled state in hopes that others will chip in to iron the few bugs that remain out of the differences between Plan 9 and Lunixland.
What's there:
The browser works in its basic state.
- The GUI is operational.
- Light pages (such as Google, or Plan 9's home page) are rendered correctly.
- Scrolling/panning with the mouse.
- Most other functionality.
What isn't:
All of the below are in the TODO list. Any help is appreciated:
- JavaScript support is turned off -- with java turned on select.c:1906 becomes true and one can't click on any links. The JS source files appear to have been mangled with Bison originally, which makes hunting the bug much harder.
- Browsing in multiple windows. (this will happen sooner or later with the help of plumbing and webfs)
- Shell exec command. (not really needed)
- Language support (original links has 30+ languages) is limited to English.
- Bitmaps (see port details for more info) are drawn directly to the screen instead of being drawn to an off-line bitmap representing the entire page. This means that each refresh of the screen causes for each bitmap, including characters, the driver to do an allocimage|loadimage|draw|freeimage. Amazingly enough this isn't too slow. (fixed -- Links now uses Plan 9 fonts for rendering )
- Scrolling is not optimized very well due to the above. (fixed -- see above )
Bugs:
Any help hunting those is greatly appreciated:
- Fixed 11/12/2003: Complex pages cause APE's select() to return with EBADFD. I haven't been able to find out why. All pages with this problem have been confirmed to work with Links on Loonix. It is doubtful that the problem is with APE's select() implementation. If you see 'ERROR: select failed: 4' just hit Del and start bug hunting.
- Fixed 17/12/2003:Text rendering in the status bar, entry fields, buttons, raw html and many other places is incorrect -- characters appear as Rect(0,0,4,16) when they should be Rect(0,0,8,16), or at least that's how they appear in Lunix. This may be because we have modified the font data to make it compileable under Plan 9. The original font_include.c caused pcc to crash with "out of memory" errors. This does not affect rendering of normal text in a web page or the GUI menus.
- Added Ins -> Refresh key mapping Images may not be flushed completely, requiring a resize or a scroll. This was a problem with libdraw's APE port. If you're not seeing images rendered recompile /sys/src/ape/lib/draw/.
- The event library doesn't offer any way of accessing compound keys such as Alt+F4 or Ctrl+C. Such keys are unimplemented.
- Fixed 17/12/2003:Links should really use Plan 9 fonts to render web pages. The fonts supplied with it are far from complete.
Port details:
Note: these are no longer relevant. Included here for your information only.Here are the details of the Plan 9 graphics driver implementation:
- The port comes with three support libraries -- libpng, libjpeg and zlib. Zlib is identical to the one in /sys/src/cmd/gs/zlib but is included here for completeness. Libpng and libjpeg are the respective latest versions of the libraries and differ from the ones that come with the default Plan 9 distribution. None of those will be installed on your system, they're only used during the compilation phase.
- All #defines for this port are inconfig.h, which by the way may be useful as a general reference for future ports -- compare that with the config.h configure creates on Lunix/BSD and see what APE supports.
- The plan9 graphics driver is located in plan9.c. The driver itself uses the APE port of libdraw (thanx to Russ Cox for doing it so quickly).
- Links works by rendering images in bitmap arrays of a configurable size. The Plan 9 driver renders those by doing a loadimage()/draw() directly to the screen.
- The graphics driver was modelled after x.c, which is the one used in
the X11 port. It defines the following functions which the
renderer interfaces to:
- plan9_init_driver -- initialize graphics and event handlers for Plan 9, open a pipe file and add it to the group of fd's links will run select on (the pipe is explained below).
- plan9_init_device -- should be done for each window Links is running in, currently just sets the internal device structure with the proper size of the window and sets the clipping rectangle to be the entire window.
- plan9_shutdown_device -- name says it all
- plan9_shutdown_driver -- window closed. Here means 'exit'.
- plan9_get_driver_param -- unused.
- plan9_get_empty_bitmap -- allocates memory for a [x,y] bitmap.
- plan9_get_filled_bitmap -- allocates memory for a [x,y] bitmap and fills it with a specified color. Unused.
- plan9_register_bitmap -- unused.
- plan9_prepare_strip -- return a pointer to the offset of a new line in the bitmap.
- plan9_commit_strip -- unused.
- plan9_unregister_bitmap -- free whatever get_empty_bitmap allocated.
- plan9_draw_bitmap -- allocimage|loadimage|draw|freeimage
- plan9_draw_bitmaps -- same as above, but for many bitmaps. Links doesn't seem to call it too often.
- color_pass_rgb -- passes an RGB color onto a long (internal Links routine).
- plan9_fill_area -- fill an area with a specific colour.
- plan9_draw_hline -- draw horizontal line.
- plan9_draw_vline -- draw vertical line.
- plan9_hscroll -- scrolling horizontally.
- plan9_vscroll -- scrolling vertically.
- plan9_set_clip_area -- set the clipping rectangle (replclipr()).
- plan9_block -- unused.
- plan9_unblock -- unused.
- plan9_set_window_title -- sets the window title.
- plan9_exec -- unused.
- 195 -- depth. A magic number, explained in the structure definition for the driver, which means that we're going to be rendering at 3 bytes per pixel in RGB mode. draw() will handle the conversion to the actual screen depth when the images are drawn.
- Links believes strongly in select().. To accomodate for this the Plan 9 driver implements its own select routine. I found out quickly that opening /dev/mouse and /dev/cons and letting APE's select them is not working -- select would always call the mouse handler even though there were no mouse events waiting in /dev/mouse, the following read would block and...
- The plan9_select() routine first examines whether any mouse or keyboard events are present using the normal Plan 9 event mechanism (much more robust, thank you) and calls the handling routines if there are any. Afterwards it calls the normal APE select with a timeout of 1000 microseconds so that it never blocks completely and we can always handle the mouse. This means that Links will never be able to 'sleep' completely on the system and there's always going to be activity within the program. If you can make the select behave more nicely (i.e. if you can incorporate mouse and keyboard in the select mechanism) I'd be happy to switch to your method.
- To make Links happy (it assumes that there's going to be at least one file descriptor for events handled by the graphics driver) the init code opens a pipe and feeds one of its file descriptors to the select() loop. There is no data being sent through the pipe.
License:
The original source is GNU. The Plan 9 driver is IDCLMA (I Don't Care, Leave Me Alone).
Documentation:
Links has a man page which this distribution will not install on your system. You can find documentation on Links' home page, linked to from the Help menu of a running instance.
Your bookmarks and configuration files are stored in /tmp/.links instead of $home/.links
Plan 9-only commands:
- Del -- exit Links.
- Ins -- refresh the window.
Last Modified: May 20, 2005
mirtchovski at gmail