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 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().

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.