  netrik hacker's manual
>========================<

[This file contains a description of the viewer module. See hacking.txt or
hacking.html for an overview of the manual.]

_display()_

The viewer consists of a keyboard dispatcher that loops until the quit command
was given, a link was followed, a history command was given, or command prompt
was entered by the user.

The commands supported include vertical scrolling, link selection and following,
and history operations.

The scrolling commands are implemented by calls to <a
href="#scrollTo">_scroll_to()_ with different parameters. All relative
movement commands can simply add or subtract a constant number of lines to
move, as scroll_to() checks for the page boundaries.

The link handling commands are described in hacking-links.*.

The history commands all work alike:

'b' goes back to the previous page by setting the current position in the
history one backwards (decrementing). The page is then (re)loaded by quiting
the pager with "RET_HISTORY".  (load_page() and init_load() take care for
correct loading of pages from history.)

'f' goes forward in the same manner (incrementing "pos").

'B' searches the history backwards, until it finds some page that is followed
either by one with the "absolute" flag set or by an internal page (the
internal page is treated like a new site). If nothing is found the search
stops at the first entry in the history, and that one is taken.

'F' searches forwards, also looking for a page followed by an absoulte URL. The
last entry is taken if nothing was found.

'r' searches for a page with "mark" set. (By 's'.) It also takes the first
page if nothing was found.

'R' does the same forwards.

'^r' causes the current page to be reloaded, by returning RET_HISTORY, but
not changing the position in the page list.

When 'q' is typed the pager quits, and returns "RET_QUIT", indicating that
the main program should quit also.

When ':' is typed the pager quits too, but returns "RET_COMMAND"; this means
that the main program should enter command mode.

When a link is followed, "RET_LINK" is returned, and the main program follows
the current "active_link".

The 'u' command causes display() to return "RET_LINK_URL"; main() then shows
the URL of the currently active link.

'c' returns "RET_URL", and main() shows the current page URL.

'U' returns "RET_ABSOLUTE_URL", causing main() to print the absolute link
target URL which is used when the link is actually followed.

_scroll_to()_

This function scrolls the visible page area to the desired position. It
moves (or deletes) the screen content, and repaints newly visible areas
using render()</a>.

It is called with the desired new position as argument. This position
is described by the line number of that line of the output page which is
displayed in the first screen line.

First the desired new position is checked to be in the valid range.

If it is greater than the page length minus one screenwidth, it is set to that
value. (The last page line can't move above the bottom screen line this way.)

If smaller then zero, it is set to zero. (The page top can't move below the
screen top.) Note that this will undo the above check, if the output page
is smaller than one screenfull -- in this case, the page end is always above
the screen end.

Now that we know the real destination position, the difference to the present
position (stored in the static "old_line") is calculated.

If the absolute value of that difference is not more than a screenfull,
scrolling is used. This is done by the insdelln() curses function, called with
the cursor being in the first screen line. (Called with a negative value it
deletes lines, causing the screen contents to scroll up; called with a positive
argument, it inserts lines, causing the screen contents to scroll down.)

After scrolling, the new lines revealed at the top or bottom of the screen
need to be rendered. After scrolling down (negative "scroll_lines"), the first
"scroll_lines" of the screen have to be repainted. This is done by calling
render() with "scroll_lines" as the height, 0 as the screen position (the
first lines of the screen are repainted), and "new_line" as page position.
("new_line" contains the page position of the first screen line.)

After scrolling up, the last screen lines have to be repainted. This is
done similar. The hight is "-scroll_lines" ("scroll_lines" is negative when
scrolling up), the screen position is the screen end minus "-sroll_lines", and
the page position is the page position of the first screen line ("new_line")
plus the screen position of the rendered area.

If the difference is too big for scrolling, the whole screen is erased and
repainted.

The first time this function is called, "old_line" has the value PAGE_INVALID
(defined as the biggest possible positive int value), indicating that the
screen contains nothing valid yet. There is no special handling necessary for
this case -- "scroll_lines" gets a very big value, and thus the whole screen
is always repainted.

scroll_to() returns the adjusted "new_line", so the caller knows what is on
the screen, and can use it as the base for any successive commands.

