Back to index

tetex-bin  3.0
Classes | Defines | Enumerations | Functions | Variables
hypertex.c File Reference
#include "alloc-debug.h"
#include "xdvi-config.h"
#include "xdvi.h"
#include <string.h>
#include <ctype.h>
#include "kpathsea/c-fopen.h"
#include "kpathsea/c-stat.h"
#include <X11/StringDefs.h>
#include "events.h"
#include "dvi-init.h"
#include "message-window.h"
#include "util.h"
#include "x_util.h"
#include "mime.h"
#include "mag.h"
#include "dvi-draw.h"
#include "statusline.h"
#include "browser.h"
#include "hypertex.h"
#include "special.h"
#include "string-utils.h"
#include "xm_toolbar.h"
#include "my-snprintf.h"
#include "pagehist.h"

Go to the source code of this file.

Classes

struct  prescan_info
struct  anchor_marker
struct  history_info
struct  anchor_info
struct  htex_page_info
struct  htex_anchor_stack_elem
struct  htex_anchor_stack
struct  visited_anchor
struct  visited_anchors

Defines

#define COPY_TMP_FILE   0 /* see comments below */
#define DO_EXPOSE(lx, ly, rx, ry)   (clearexpose(&mane, lx - 20, ly - 3, rx - lx + 26, ry - ly + 6))
#define ARG_LEN   32

Enumerations

enum  hrefLinkT { HYPERTEX_LINK, HDVIPS_LINK }
enum  htexAnchorT {
  A_HREF = 0, A_NAME, A_HREF_FILE, A_HREF_URL,
  A_HDVIPS_INTERNAL, A_HDVIPS_HREF, A_HDVIPS_NAME, A_OTHER,
  A_END, A_NONE, A_MISMATCH
}

Functions

static Boolean htex_is_href (htexAnchorT type)
static Boolean htex_is_name (htexAnchorT type)
static void parse_html_special (const char *special, size_t len, const char **beg, const char **end)
void htex_prescan_save (void)
void htex_prescan_restore (int pageno)
void htex_prescan_reset_firstpass (void)
static void htex_prescan_reset (void)
void htex_prescan_initpage (void)
Boolean htex_prescan_special (const char *cp, int cp_len, struct htex_prescan_data *data)
int htex_prescan_get_depth (void)
void htex_prescan_carry_over (int old_page, int new_page)
size_t htex_prescan_get_mismatched_anchor_num (size_t depth)
static void htex_erase_anchormarker (XtPointer client_data, XtIntervalId *id)
static void htex_draw_anchormarker (int y)
static void resize_info_if_needed (struct htex_page_info *info)
static void init_visited_links (struct visited_anchors *links, int total_pages, Boolean new_dvi_file)
static void save_in_list (struct visited_anchors *links, int pageno, int idx)
static void set_visited (struct visited_anchors *links, int pageno, int anchor_num)
static Boolean is_visited (struct visited_anchors *links, int pageno, int anchor_num)
static void push_stack (struct htex_anchor_stack *stack, htexAnchorT type, int anchor_num)
static htexAnchorT pop_stack (struct htex_anchor_stack *stack, int *anchor_num)
static Boolean get_href_depth (const struct htex_anchor_stack *stack)
static htexAnchorT peek_stack (struct htex_anchor_stack *stack, int *anchor_num)
static void push_colorspecial (void)
static void pop_colorspecial (void)
const char * is_local_file (const char *filename)
static char * parse_anchortext (const char *input, int len)
static void add_anchor (struct htex_page_info *info, htexAnchorT type, const char *str, size_t len, int pageno, char *filename)
static void set_anchor_size (struct htex_page_info *info, int index, int ulx, int uly, int lrx, int lry)
void htex_set_objecttype (htexObjectT type)
void htex_set_anchorsize (int ulx, int uly, int lrx, int lry)
static void enlarge_anchor_size (struct htex_page_info *info, int index, int ulx, int uly, int lrx, int lry)
static void reset_page_info (struct htex_page_info *info, int pageno, Boolean force_init)
void htex_initpage (Boolean new_dvi_file, Boolean size_changed, int pageno)
static void hdvips_add_anchor (struct htex_page_info *info, htexAnchorT type, const char *str)
void htex_reset_page (int pageno)
Boolean htex_scan_anchor (const char *cp, size_t len)
void htex_record_position (int ulx, int uly, int w, int h)
static char * check_relative_name (const char *link)
static void htex_update_toolbar_navigation (void)
void htex_back (void)
void htex_forward (void)
static void history_save_anchor (const char *anchor, int current_page, const char *dvi_name)
static char * get_anchor_at_index (int x, int y, int *count)
static void redraw_anchors (int idx)
Boolean htex_handleref (int x, int y, Boolean newwindow)
void htex_displayanchor (int x, int y)
void htex_resize_page (void)
void htex_reinit (void)
void htex_draw_anchormarkers (void)
void launch_xdvi (const char *filename, const char *anchor_name)
void launch_program (const char *filename)
void htex_set_anchormarker (int y)

Variables

char * g_link_color_rgb = NULL
char * g_visited_link_color_rgb = NULL
char * g_anchor_pos = NULL
size_t g_anchor_len = 0
static const int DEFAULT_MARKER_X_OFFSET = 2
static const int HTEX_ALLOC_STEP = 32
static const int ANCHOR_XTRA_V_BBOX = 6
static hrefLinkT m_href_type
static struct prescan_info = { 0, 0, 0, NULL, 0, NULL }
struct anchor_marker g_anchormarker
static XtIntervalId m_href_timeout_id = 0
static int x_pos_bak = 0
static int y_pos_bak = 0
static struct htex_page_info = { NULL, 0, 0, -1, -1 }
static struct dl_listhtex_history = NULL
static struct visited_anchors = { NULL, 0 }
static struct htex_anchor_stack = { 0, 0, NULL }
static char *const remote_URL_schemes []

Class Documentation

struct prescan_info

Definition at line 173 of file hypertex.c.

Class Members
int anchor_depth
int * anchor_list
size_t anchor_list_size
size_t anchor_num
char ** pagelist
size_t pagelist_len
struct anchor_marker

Definition at line 456 of file hypertex.c.

Class Members
char * filename
int page
int x_pos
int y_pos
struct history_info

Definition at line 466 of file hypertex.c.

Class Members
char * anchor
char * filename
int page
struct anchor_info

Definition at line 472 of file hypertex.c.

Class Members
char * a_href
char * a_name
int lrx
int lry
int next_wrapped
htexObjectT object_type
int prev_wrapped
int ulx
int uly
struct htex_page_info

Definition at line 486 of file hypertex.c.

Collaboration diagram for htex_page_info:
Class Members
struct anchor_info * anchors
int curr_cnt
int have_wrapped
int page
int tot_cnt
struct htex_anchor_stack_elem

Definition at line 506 of file hypertex.c.

Class Members
int anchor_num
htexAnchorT type
struct htex_anchor_stack

Definition at line 514 of file hypertex.c.

Collaboration diagram for htex_anchor_stack:
Class Members
size_t depth
size_t size
struct htex_anchor_stack_elem * types
struct visited_anchor

Definition at line 520 of file hypertex.c.

Class Members
int * list
size_t list_size
struct visited_anchors

Definition at line 525 of file hypertex.c.

Collaboration diagram for visited_anchors:
Class Members
struct visited_anchor * anchors
size_t size

Define Documentation

#define ARG_LEN   32
#define COPY_TMP_FILE   0 /* see comments below */

Definition at line 60 of file hypertex.c.

#define DO_EXPOSE (   lx,
  ly,
  rx,
  ry 
)    (clearexpose(&mane, lx - 20, ly - 3, rx - lx + 26, ry - ly + 6))

Enumeration Type Documentation

enum hrefLinkT
Enumerator:
HYPERTEX_LINK 
HDVIPS_LINK 

Definition at line 108 of file hypertex.c.

Enumerator:
A_HREF 
A_NAME 
A_HREF_FILE 
A_HREF_URL 
A_HDVIPS_INTERNAL 
A_HDVIPS_HREF 
A_HDVIPS_NAME 
A_OTHER 
A_END 
A_NONE 
A_MISMATCH 

Definition at line 111 of file hypertex.c.

             {
    A_HREF = 0,
    A_NAME,
    A_HREF_FILE,     /* hdvips file ref */
    A_HREF_URL,             /* hdvips URL ref */
    A_HDVIPS_INTERNAL,      /* internal ref */
    A_HDVIPS_HREF,   /* hdvips href */
    A_HDVIPS_NAME,   /* hdvips name */
    A_OTHER,
    A_END,
    A_NONE,
    A_MISMATCH
} htexAnchorT;

Function Documentation

static void add_anchor ( struct htex_page_info info,
htexAnchorT  type,
const char *  str,
size_t  len,
int  pageno,
char *  filename 
) [static]

Definition at line 867 of file hypertex.c.

{
    UNUSED(pageno);
    UNUSED(filename);

    resize_info_if_needed(info);

    ASSERT(htex_is_name(type) || htex_is_href(type), "This doesn't look like a valid anchor");
    /* add an anchor or a href, depending on `type' */
    if (type == A_HREF) {
       if (info->anchors[info->curr_cnt].a_href == NULL) {
           info->anchors[info->curr_cnt].a_href = parse_anchortext(str, len);
       }
       TRACE_HTEX((stderr, "adding HREF %d: |%s|", info->curr_cnt, info->anchors[info->curr_cnt].a_href));
    }
    else if (type == A_HREF_URL) {
       if (info->anchors[info->curr_cnt].a_href == NULL) {
           info->anchors[info->curr_cnt].a_href = xmalloc(len + 1);
           strncpy(info->anchors[info->curr_cnt].a_href, str, len);
           info->anchors[info->curr_cnt].a_href[len] = '\0';
       }
       TRACE_HTEX((stderr, "adding HREF_URL %d: |%s|", info->curr_cnt, info->anchors[info->curr_cnt].a_href));
    }
    else if (type == A_HDVIPS_INTERNAL) {
       if (info->anchors[info->curr_cnt].a_href == NULL) {
           /* dynamically add a `#' prefix */
           if (str[0] != '#') {
              info->anchors[info->curr_cnt].a_href = xmalloc(len + 2);
              strcpy(info->anchors[info->curr_cnt].a_href, "#");
              strncat(info->anchors[info->curr_cnt].a_href, str, len);
              info->anchors[info->curr_cnt].a_href[len + 1] = '\0';
           }
           else {
              info->anchors[info->curr_cnt].a_href = xmalloc(len + 1);
              strncpy(info->anchors[info->curr_cnt].a_href, str, len);
              info->anchors[info->curr_cnt].a_href[len] = '\0';
           }
       }
       TRACE_HTEX((stderr, "adding HREF_URL %d: |%s|", info->curr_cnt, info->anchors[info->curr_cnt].a_href));
    }
    else if (type == A_HREF_FILE) {
       if (info->anchors[info->curr_cnt].a_href == NULL) {
           /* dynamically add a `file:' extension */
           if (memcmp(str, "file:", strlen("file:")) == 0) {
              info->anchors[info->curr_cnt].a_href = xmalloc(len + 1);
              strncpy(info->anchors[info->curr_cnt].a_href, str, len);
              info->anchors[info->curr_cnt].a_href[len] = '\0';
           }
           else {
              info->anchors[info->curr_cnt].a_href = xmalloc(len + strlen("file:") + 1);
              strcpy(info->anchors[info->curr_cnt].a_href, "file:");
              strncat(info->anchors[info->curr_cnt].a_href, str, len);
              info->anchors[info->curr_cnt].a_href[len + strlen("file:")] = '\0';
           }
       }
       TRACE_HTEX((stderr, "adding HREF_FILE %d: |%s|", info->curr_cnt, info->anchors[info->curr_cnt].a_href));
    }
    else if (type == A_NAME) {
       if (info->anchors[info->curr_cnt].a_name == NULL) {
           info->anchors[info->curr_cnt].a_name = parse_anchortext(str, len);
       }
       TRACE_HTEX((stderr, "adding NAME %d: %s", info->curr_cnt, info->anchors[info->curr_cnt].a_name));
    }
    else if (type == A_HDVIPS_HREF) {
       if (info->anchors[info->curr_cnt].a_href == NULL) {
           info->anchors[info->curr_cnt].a_href = xmalloc(len + 1);
           strncpy(info->anchors[info->curr_cnt].a_href, str, len);
           info->anchors[info->curr_cnt].a_href[len] = '\0';
       }
       TRACE_HTEX((stderr, "adding HDVIPS_HREF %d: |%s|", info->curr_cnt, info->anchors[info->curr_cnt].a_name));
    }
    else if (type == A_HDVIPS_NAME) {
       if (info->anchors[info->curr_cnt].a_name == NULL) {
           info->anchors[info->curr_cnt].a_name = xmalloc(len + 1);
           strncpy(info->anchors[info->curr_cnt].a_name, str, len);
           info->anchors[info->curr_cnt].a_name[len] = '\0';
       }
       TRACE_HTEX((stderr, "adding HDVIPS_NAME %d: |%s|", info->curr_cnt, info->anchors[info->curr_cnt].a_name));
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* check_relative_name ( const char *  link) [static]

Definition at line 1332 of file hypertex.c.

{
    char *ptr;
    TRACE_HTEX((stderr, "check_relative_name: |%s|", link));
    if ((ptr = strchr(link, '#')) != NULL
       && ptr > link + 4
       && (memicmp(ptr - 4, ".dvi", 4) == 0)) {
       char *new_link = xstrdup(link);
       new_link[ptr - link] = '\0'; /* truncate the copy */
       free(g_anchor_pos);
       g_anchor_pos = xstrdup(ptr + 1);
       g_anchor_len = strlen(g_anchor_pos);
       
       return new_link;
    }
    else { /* reset g_anchor_pos */
       free(g_anchor_pos);
       g_anchor_pos = NULL;
    }
    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void enlarge_anchor_size ( struct htex_page_info info,
int  index,
int  ulx,
int  uly,
int  lrx,
int  lry 
) [static]

Definition at line 981 of file hypertex.c.

{
    struct anchor_info *anchor;
    
    ASSERT(info->anchors != NULL, "info->anchors should have been allocated before");
    ASSERT(index < info->curr_cnt, "info too small");

/*     fprintf(stderr, "enlarging anchor at index %d; %s\n", index, info->anchors[index].a_href); */
    anchor = &(info->anchors[index]);

    if (ulx < anchor->ulx) {
       anchor->ulx = ulx;
    }
    if (uly < anchor->uly) {
       anchor->uly = uly;
    }
    if (lrx > anchor->lrx) {
       anchor->lrx = lrx;
    }
    /* set lry only for first character, since this will be used
       to position underline */
/*      if (lry > anchor->lry && anchor->lry == 0) { */
    if (lry > anchor->lry) {
       anchor->lry = lry;
    }
}

Here is the caller graph for this function:

static char* get_anchor_at_index ( int  x,
int  y,
int count 
) [static]

Definition at line 1529 of file hypertex.c.

{
    int i;

    for (i = 0; i < htex_page_info.curr_cnt; i++) {
       struct anchor_info anchor = htex_page_info.anchors[i];
/*     fprintf(stderr, "getting anchor at index %d; %s\n", i, anchor.a_href); */
       if (anchor.a_href == NULL) {
           continue;
       }
       if (anchor.lry + 2 > y && anchor.uly - 1 < y /* allow some vertical fuzz */
           && anchor.lrx > x && anchor.ulx < x) {
           *count = i;
           return anchor.a_href;
       }
    }
    *count = -1;
    return NULL;
}

Here is the caller graph for this function:

static Boolean get_href_depth ( const struct htex_anchor_stack stack) [static]

Definition at line 758 of file hypertex.c.

{
    size_t i;
    for (i = 0; i <= stack->depth; i++) {
       ASSERT(stack->types != NULL, "types musn't be NULL!");
       if (htex_is_href(stack->types[i].type))
           return True;
    }
    return False;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void hdvips_add_anchor ( struct htex_page_info info,
htexAnchorT  type,
const char *  str 
) [static]

Definition at line 1090 of file hypertex.c.

{
    char *ptr;
    if ((ptr = strchr(str, ')')) != NULL) {
       int curr_cnt_bak = info->curr_cnt;
       /* overwrite previously created dummy/wrapped anchors */
       ASSERT(info->curr_cnt > 0, "hdvips_add_anchor must be called after add_anchor()!");

       while (info->curr_cnt > 0
              && info->anchors[info->curr_cnt - 1].a_href != NULL
              && (strcmp(info->anchors[info->curr_cnt - 1].a_href, "__WRAPPED__") == 0
                 || strcmp(info->anchors[info->curr_cnt - 1].a_href, "__DUMMY__") == 0)) {
           info->curr_cnt--;
           free(info->anchors[info->curr_cnt].a_href);
           free(info->anchors[info->curr_cnt].a_name);
           info->anchors[info->curr_cnt].a_href = info->anchors[info->curr_cnt].a_name = NULL;
           add_anchor(info, type, str, ptr - str, 0, NULL);
       }
       info->curr_cnt = curr_cnt_bak;
    }
    else {
       MYTRACE((stderr, "Xdvi warning: skipping malformed hdvips link `%s'", str));
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void history_save_anchor ( const char *  anchor,
int  current_page,
const char *  dvi_name 
) [static]

Definition at line 1493 of file hypertex.c.

{
    struct history_info *item;

    if (htex_history == NULL) {
       /* Insert dummy start elem. We need this to prevent dropping
          off from the begin of the list, since otherwise a 1-elem
          list couldn't encode the information whether we can still go
          back. This way it will point to the dummy elem when there's
          no way to go back.  */
       struct history_info *start_marker = XMALLOC(start_marker, sizeof *start_marker);
       start_marker->anchor = NULL;
       start_marker->filename = NULL;
       start_marker->page = -1;
       htex_history = dl_list_insert(htex_history, start_marker);
    }
    item = XMALLOC(item, sizeof *item);
    item->anchor = xstrdup(anchor);
    item->filename = xstrdup(dvi_name);
    item->page = current_page;
    htex_history = dl_list_truncate(dl_list_insert(htex_history, item));

#if 0
    MYTRACE((stderr, "==================== after inserting "));
    show_history();
#endif
    
    htex_update_toolbar_navigation();

}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1367 of file hypertex.c.

{
    struct history_info *info;

    if (htex_history == NULL) {
       XBell(DISP, 0);
       statusline_print(STATUS_SHORT, "Hyperref history is empty");
       return;
    }
    info = htex_history->item;

    if (htex_history->prev == NULL) {
       XBell(DISP, 0);
       statusline_print(STATUS_SHORT, "At begin of history");
       htex_update_toolbar_navigation();
       return;
    }

    if (strcmp(info->filename, globals.dvi_name) != 0) { /* new filename different */
       Boolean tried_dvi_ext = False;
       char *new_dvi_name = NULL;
       
       if ((new_dvi_name = open_dvi_file_wrapper(info->filename, False, False,
                                            &tried_dvi_ext, False))
           == NULL) {
           
           statusline_print(STATUS_MEDIUM, "Re-opening file \"%s\" failed!\n", info->filename);
           return;
       }
       else {
           set_dvi_name(new_dvi_name);
           globals.ev.flags |= EV_NEWDOC;
           globals.ev.flags |= EV_PAGEHIST_INSERT;
/*         statusline_print(STATUS_MEDIUM, "Back to file: \"%s\"", globals.dvi_name); */
       }
    }
    else {
       page_history_insert(info->page);
    }
    goto_page(info->page, resource.keep_flag ? NULL : home, False);

    MYTRACE((stderr, "curr page now: %d", current_page));
    htex_history = htex_history->prev;

    info = htex_history->item;

#if 0
    MYTRACE((stderr, "------ before skipping: %d, %s", info->page, info->anchor));
    show_history();
    while (info->page == current_page && htex_history->prev != NULL) {
       /* skip identical locations */
       MYTRACE((stderr, "+++++++ skipping identical page %d, %s", current_page, info->anchor));
       htex_history = htex_history->prev;
       info = htex_history->item;
    }
    MYTRACE((stderr, "------ after skipping: %d, %s", info->page, info->anchor));
#endif

    htex_update_toolbar_navigation();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void htex_displayanchor ( int  x,
int  y 
)

Definition at line 1674 of file hypertex.c.

{
    static int id_bak = -1;
    static int pageno_bak = -1;
    int id_curr;
    char *anchor_text;

    anchor_text = get_anchor_at_index(x, y, &id_curr);

    if (anchor_text != NULL) { /* found an anchor */
       if (!(globals.cursor.flags & CURSOR_LINK) && !dragging_text_selection()) {
           globals.cursor.flags |= CURSOR_LINK;
           globals.ev.flags |= EV_CURSOR;
       }
       /* to prevent flicker, print only when it differs from previous one,
          i.e. when it either has a different ID or is on a different page: */
       if ((resource.expert_mode & XPRT_SHOW_STATUSLINE) != 0
           && (id_curr != id_bak || current_page != pageno_bak)) {
           statusline_print(STATUS_FOREVER, "%s", anchor_text);
           id_bak = id_curr;
           pageno_bak = current_page;
       }
    }
    else { /* not over anchor text, reset cursor and statusline */
       if (globals.cursor.flags & CURSOR_LINK) {
           globals.cursor.flags &= ~CURSOR_LINK;
           globals.ev.flags |= EV_CURSOR;
       }

       if (id_bak != -1 && (resource.expert_mode & XPRT_SHOW_STATUSLINE) != 0) {
           statusline_clear();
           id_bak = -1;
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void htex_draw_anchormarker ( int  y) [static]

Definition at line 2103 of file hypertex.c.

{
    int x;
    XPoint points[3];

    Position drawing_x, clip_w;

    XtVaGetValues(globals.widgets.clip_widget, XtNwidth, &clip_w, NULL);
    XtVaGetValues(globals.widgets.draw_widget, XtNx, &drawing_x, NULL);

    /* compute offset to draw into visible region */
    x = DEFAULT_MARKER_X_OFFSET + -drawing_x;

    /* Eventually erase old marker, to avoid `smearing' on horizontal scrolls. */
    if (x != g_anchormarker.x_pos) {
       clearexpose(&mane, g_anchormarker.x_pos - 1, y - 3, 20, 10);
    }
    g_anchormarker.x_pos = x;

    points[0].x = x + 10;
    points[1].x = x + 19;
    points[2].x = x + 10;
    points[0].y = y - 3;
    points[1].y = y + 2;
    points[2].y = y + 7;

    XFillRectangle(DISP, mane.win, globals.gc.visited_linkcolor, x, y, 10, 4);
    XFillPolygon(DISP, mane.win, globals.gc.visited_linkcolor, points, 3, Convex, CoordModeOrigin);
    /* -1 indicates that no horizontal scrolling is wanted, since the
       anchormarker will always be horizontally positioned inside the
       visible area.
     */
    scroll_page_if_needed(-1, -1, y + 3, y - 3);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1740 of file hypertex.c.

{
    int i;
    int rule_height = (globals.page.h / 1000.0);
    XRectangle rect = { -1, -1, 0, 0 };
    
    if (rule_height == 0)
       rule_height = 1;

    if (current_page == g_anchormarker.page
       && strcmp(globals.dvi_name, g_anchormarker.filename) == 0
       &&  g_anchormarker.y_pos > 0) {
       htex_draw_anchormarker(g_anchormarker.y_pos);
    }
    
    if (resource.link_style == 0 || resource.link_style == 2)
       return;
    
    for (i = 0; i < htex_page_info.curr_cnt; i++) {
       struct anchor_info anchor = htex_page_info.anchors[i];

       if (anchor.a_href != NULL) {
           int offset;
           Boolean visited = False;

#if 0
           XDrawRectangle(DISP, mane.win, globals.gc.high,
                        anchor.ulx, anchor.uly,
                        anchor.lrx - anchor.ulx, anchor.lry - anchor.uly);
                        
#endif
           
           if (is_visited(&visited_links, current_page, i)) {/*  || wrapped_anchor_is_visited(i)) { */
              visited = True;
           }
           offset = ANCHOR_XTRA_V_BBOX / (double)currwin.shrinkfactor + 0.5;

           TRACE_HTEX((stderr, "UNDERLINE: %d, %s is %s", i, anchor.a_href,
                     visited ? "******* visited ****** " : "not visited"));
           anchor.ulx -= currwin.base_x;
           anchor.lrx -= currwin.base_x;
           anchor.lry -= currwin.base_y;
           anchor.uly -= currwin.base_y;
           
           /* BUG ALERT: Don't use put_rule here, since this will cause a segfault
            * with the new color code when switching density (#616920)!
            */
           MYTRACE((stderr, "UNDERLINE: checking if %d is visited: %d!", i, visited));

/*         if (clip_region_to_rect(&rect)) { */
           if (anchor.object_type == HTEX_IMG) {
              rect.x = anchor.ulx - 1;
              rect.y = anchor.uly - 1;
              rect.width = anchor.lrx - anchor.ulx + 2;
              rect.height = anchor.lry - anchor.uly + 2;
              if (clip_region_to_rect(&rect)) {
                  XDrawRectangle(DISP, mane.win,
                               visited ? globals.gc.visited_linkcolor : globals.gc.linkcolor,
                               rect.x, rect.y,
                               rect.width, rect.height);
              }
           }
           else {
              rect.x = anchor.ulx - 1;
              rect.y = anchor.lry + offset;
              rect.width = anchor.lrx - anchor.ulx + 2;
              rect.height = rule_height;
              if (clip_region_to_rect(&rect)) {
                  XFillRectangle(DISP, mane.win,
                               visited ? globals.gc.visited_linkcolor : globals.gc.linkcolor,
                               rect.x, rect.y,
                               rect.width, rect.height);
              }
           }
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void htex_erase_anchormarker ( XtPointer  client_data,
XtIntervalId *  id 
) [static]

Definition at line 2140 of file hypertex.c.

{
    Position clip_w;
    
    UNUSED(client_data);
    UNUSED(id);

    if (globals.debug & DBG_EVENT) {
       fprintf(stderr, "htex_erase_anchormarker called!\n");
    }

    if (m_href_timeout_id == (XtIntervalId)0) { /* timeout was removed but callback happened anyway */
       return;
    }

    m_href_timeout_id = (XtIntervalId)0;
    /* clear the mark if we're in the same file and on the same page as the mark */
    if (g_anchormarker.filename != NULL
       && strcmp(globals.dvi_name, g_anchormarker.filename) == 0
       && g_anchormarker.page == current_page) {
       XtVaGetValues(globals.widgets.clip_widget, XtNwidth, &clip_w, NULL);
       clearexpose(&mane, 0, g_anchormarker.y_pos - 3, clip_w, 10);
    }
    g_anchormarker.y_pos = -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1430 of file hypertex.c.

{
    struct history_info *info;
    char *link;
    
    if (htex_history == NULL) {
       XBell(DISP, 0);
       statusline_print(STATUS_SHORT, "Hyperref history is empty");
       return;
    }
    if (htex_history->next == NULL) {
       XBell(DISP, 0);
       statusline_print(STATUS_SHORT, "At end of history");
       return;
    }
    
    htex_history = htex_history->next;
    info = htex_history->item;
    link = info->anchor;
    /* go there */
    if (*link == '#') { /* it's a relative link */
       MYTRACE((stderr, "XXXXXXXX %s:%d: setting anchor to |%s|+1", __FILE__, __LINE__, info->anchor));
       free(g_anchor_pos);
       g_anchor_pos = xstrdup(info->anchor + 1);
       g_anchor_len = strlen(g_anchor_pos);
       globals.ev.flags |= EV_ANCHOR;
    }
    else { /* it's an absolute link */
       char *new_linkname = NULL;
       char *new_dvi_name = NULL;
       Boolean tried_dvi_ext = False;
       
       if ((new_linkname = check_relative_name(link)) != NULL)
           link = new_linkname;

       if ((new_dvi_name = open_dvi_file_wrapper(link, False, False,
                                            &tried_dvi_ext, False)) == NULL) {
           statusline_print(STATUS_MEDIUM, "Re-opening file \"%s\" failed!\n", info->filename);
           free(new_linkname);
           return;
       }
       else {
           set_dvi_name(new_dvi_name);
           
           globals.ev.flags |= EV_NEWDOC;
           goto_page(0, resource.keep_flag ? NULL : home, False);
           globals.ev.flags |= EV_PAGEHIST_INSERT;

           if (g_anchor_pos != NULL)
              globals.ev.flags |= EV_ANCHOR;

/*         statusline_print(STATUS_MEDIUM, "Loaded file: \"%s\"", globals.dvi_name); */
           free(new_linkname);
       }
    }

    htex_update_toolbar_navigation();
}

Here is the call graph for this function:

Here is the caller graph for this function:

Boolean htex_handleref ( int  x,
int  y,
Boolean  newwindow 
)

Definition at line 1604 of file hypertex.c.

{
    char *link;
    int link_num;

/*      fprintf(stderr, "---------- htex_handleref!\n"); */
    if (!(globals.cursor.flags & CURSOR_LINK))
       /* When no link cursor is shown, clicking shouldn't jump to link */
       return False;
    
    if ((link = get_anchor_at_index(x, y, &link_num)) != NULL) {
       set_visited(&visited_links, current_page, link_num);

       if (*link == '#') { /* it's a relative link */
           if (newwindow) {
              launch_xdvi(globals.dvi_name, link + 1);
              redraw_anchors(link_num);
              return True;
           }
           else {
              history_save_anchor(link, current_page, globals.dvi_name);
              free(g_anchor_pos);
              g_anchor_pos = xstrdup(link + 1);
              g_anchor_len = strlen(g_anchor_pos);
              globals.ev.flags |= EV_ANCHOR;
              redraw_anchors(link_num);
              return True;
           }
       }
       else { /* it's an absolute link */
           char *new_dvi_name = NULL;
           int pageno_bak = current_page;
           char *new_linkname = NULL;
           char *orig_link = link;
           Boolean tried_dvi_ext = False;
           
           MYTRACE((stderr, "OLD FILE: |%s|", globals.dvi_name));

           if ((new_linkname = check_relative_name(link)) != NULL)
              link = new_linkname;
           
           if ((new_dvi_name = open_dvi_file_wrapper(link, False, newwindow,
                                                &tried_dvi_ext, False)) != NULL) {
              /* only save link in history if opening succeeds */
              history_save_anchor(orig_link, pageno_bak, globals.dvi_name);
              set_dvi_name(new_dvi_name);
              if (!newwindow) {
                  globals.ev.flags |= EV_NEWDOC;
                  goto_page(0, resource.keep_flag ? NULL : home, False);
                  globals.ev.flags |= EV_PAGEHIST_INSERT;
                  
                  MYTRACE((stderr, "NEW FILE: |%s|", globals.dvi_name));
                  if (g_anchor_pos != NULL)
                     globals.ev.flags |= EV_ANCHOR;
/*                statusline_print(STATUS_MEDIUM, "Loaded file: \"%s\"", dvi_name); */
              }
              else {
                  redraw_anchors(link_num);
              }
           }
           free(new_linkname);
           redraw_anchors(link_num);
           return True;
       }
    }
    return False;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void htex_initpage ( Boolean  new_dvi_file,
Boolean  size_changed,
int  pageno 
)

Definition at line 1056 of file hypertex.c.

{
    reset_page_info(&htex_page_info, pageno, size_changed | new_dvi_file);
    init_visited_links(&visited_links, total_pages, new_dvi_file);

#if 0
    show_visited(&visited_links, pageno);
#endif
    
    if (pageno > 0
       && (int)m_prescan_info.pagelist_len > pageno /* pagelist_len will be 0 for file with no hyperlinks */
       && m_prescan_info.pagelist[pageno - 1] != NULL) {
       add_anchor(&htex_page_info, A_HREF,
                 m_prescan_info.pagelist[pageno - 1],
                 strlen(m_prescan_info.pagelist[pageno - 1]),
                 pageno, NULL);
       htex_page_info.curr_cnt++;
       MYTRACE((stderr, "++++++++++ mismatched anchor text (at %d): |%s|",
              htex_page_info.curr_cnt - 1, m_prescan_info.pagelist[pageno - 1]));
       /*     x_pos_bak = y_pos_bak = INT_MAX; */
       x_pos_bak = y_pos_bak = INT_MAX;
       set_anchor_size(&htex_page_info, htex_page_info.curr_cnt - 1, 0, 0, 1, 1);
       htex_page_info.have_wrapped = htex_page_info.curr_cnt - 1;
       if (bg_current != NULL) { /* only if it has been initialized by redraw_page in events.c */
           push_colorspecial();
       }
/*     else { */
/*         fprintf(stderr, "----------------------- NOT pushing color, waiting ...\n"); */
/*     } */
       push_stack(&stack, A_HREF, htex_page_info.curr_cnt - 1);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Boolean htex_is_href ( htexAnchorT  type) [static]

Definition at line 128 of file hypertex.c.

Here is the caller graph for this function:

static Boolean htex_is_name ( htexAnchorT  type) [static]

Definition at line 138 of file hypertex.c.

{
    return type == A_NAME || type == A_HDVIPS_NAME;
}

Here is the caller graph for this function:

void htex_prescan_carry_over ( int  old_page,
int  new_page 
)

Definition at line 423 of file hypertex.c.

{
    ASSERT(old_page >= 0, "old_page out of range");
    ASSERT(old_page < (int)m_prescan_info.pagelist_len, "old_page out of range");

    /* resize if needed */
    if (new_page >= (int)m_prescan_info.pagelist_len) {
       size_t old_len = m_prescan_info.pagelist_len;
       size_t i;
       m_prescan_info.pagelist_len = new_page + 1;
       m_prescan_info.pagelist = XREALLOC(m_prescan_info.pagelist,
                                      m_prescan_info.pagelist_len * sizeof *m_prescan_info.pagelist);
       /* initialize with NULL values */
       for (i = old_len; i < m_prescan_info.pagelist_len; i++) {
           m_prescan_info.pagelist[i] = NULL;
       }
    }
    free(m_prescan_info.pagelist[new_page]);
    /* don't share pointers here */
    m_prescan_info.pagelist[new_page] = xstrdup(m_prescan_info.pagelist[old_page]);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 416 of file hypertex.c.

{
    return m_prescan_info.anchor_depth;
}

Here is the caller graph for this function:

Definition at line 446 of file hypertex.c.

{
    ASSERT((int)depth <= m_prescan_info.anchor_depth, "depth too large");
    ASSERT(depth <= m_prescan_info.anchor_list_size, "depth too large for lookup list");
    
    return m_prescan_info.anchor_list[m_prescan_info.anchor_depth - 1];
}

Here is the caller graph for this function:

Definition at line 287 of file hypertex.c.

{
    m_prescan_info.anchor_num = 0;
}

Here is the caller graph for this function:

static void htex_prescan_reset ( void  ) [static]

Definition at line 265 of file hypertex.c.

{
    size_t i;
    m_prescan_info.anchor_depth = 0;
    m_prescan_info.anchor_num = 0;
    m_prescan_info.anchor_list_size = 0;
    
    free(m_prescan_info.anchor_list);
    m_prescan_info.anchor_list = NULL;
    
    for (i = 0; i < m_prescan_info.pagelist_len; i++) {
       free(m_prescan_info.pagelist[i]);
    }
    free(m_prescan_info.pagelist);
    m_prescan_info.pagelist = NULL;
    m_prescan_info.pagelist_len = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 250 of file hypertex.c.

{
    MYTRACE((stderr, "resetting anchor_depth to 0!!!!!!!!!!!!"));
    m_prescan_info.anchor_depth = 0;
    m_prescan_info.anchor_num = 0;
    m_prescan_info.anchor_list_size = 0;
    FREE(m_prescan_info.anchor_list);
    m_prescan_info.anchor_list = NULL;
}

Here is the caller graph for this function:

Definition at line 218 of file hypertex.c.

{
    m_prescan_info.anchor_depth = m_save_prescan_info.anchor_depth;
    m_prescan_info.anchor_num = m_save_prescan_info.anchor_num;
    /* copy back anchor list */
    if (m_save_prescan_info.anchor_depth > 0) {
       int i;
       /* old list might have been free()d in htex_prescan_reset_firstpass */
       while (m_save_prescan_info.anchor_depth >= (int)m_prescan_info.anchor_list_size) {
           m_prescan_info.anchor_list_size += HTEX_ALLOC_STEP;
           m_prescan_info.anchor_list = XREALLOC(m_prescan_info.anchor_list,
                                            m_prescan_info.anchor_list_size
                                            * sizeof *(m_prescan_info.anchor_list));
       }
       for (i = 0; i < m_save_prescan_info.anchor_depth; i++) {
           m_prescan_info.anchor_list[i] = m_save_prescan_info.anchor_list[i];
       }
    }
    /* reset anchor string info for this page */
    if ((int)m_prescan_info.pagelist_len > pageno) {
       ASSERT(m_prescan_info.pagelist != NULL, "m_prescan_info.pagelist not properly allocated");
       FREE(m_prescan_info.pagelist[pageno]);
       m_prescan_info.pagelist[pageno] = NULL;
    }
}

Here is the caller graph for this function:

Definition at line 194 of file hypertex.c.

{
    m_save_prescan_info.anchor_depth = m_prescan_info.anchor_depth;
    m_save_prescan_info.anchor_num = m_prescan_info.anchor_num;
    /* copy over anchor list */
    while (m_save_prescan_info.anchor_depth >= (int)m_save_prescan_info.anchor_list_size) {
       int i;
       m_save_prescan_info.anchor_list_size += HTEX_ALLOC_STEP;
       m_save_prescan_info.anchor_list = XREALLOC(m_save_prescan_info.anchor_list,
                                             m_save_prescan_info.anchor_list_size
                                             * sizeof *(m_save_prescan_info.anchor_list));
       for (i = 0; i < m_save_prescan_info.anchor_depth; i++) {
           m_save_prescan_info.anchor_list[i] = m_prescan_info.anchor_list[i];
       }
    }
    /* the page list of anchor strings can only have had its current position modified;
       we'll simply delete that position in htex_prescan_restore().
    */
}

Here is the caller graph for this function:

Boolean htex_prescan_special ( const char *  cp,
int  cp_len,
struct htex_prescan_data data 
)

Definition at line 294 of file hypertex.c.

{
    UNUSED(cp_len);
    ASSERT(data != NULL, "data argument to htex_prescan_special() mustn't be NULL");
    if (data->pageno + 1 < (int)m_prescan_info.pagelist_len) { /* already scanned this page */
       MYTRACE((stderr, "already scanned page %d", data->pageno+1));
       return False;
    }

    /* resize pagelist */
    while (data->pageno >= (int)m_prescan_info.pagelist_len) {
       size_t old_len = m_prescan_info.pagelist_len;
       size_t i;
       MYTRACE((stderr, "============ resizing pagelist to %d", data->pageno + 1));
       m_prescan_info.pagelist_len = data->pageno + 1;
       m_prescan_info.pagelist = XREALLOC(m_prescan_info.pagelist,
                                      m_prescan_info.pagelist_len * sizeof *m_prescan_info.pagelist);
       /* initialize with NULL values */
       for (i = old_len; i < m_prescan_info.pagelist_len; i++) {
           MYTRACE((stderr, "============ initializing pagelist %d", i));
           m_prescan_info.pagelist[i] = NULL;
       }
    }
    
    if (data->scan_type == HTEX_ANCHOR_STRING) {
       if ((int)m_prescan_info.anchor_num == data->anchor_num) {
           char *anchor;
           const char *beg, *end;
           const char *cp1 = cp;
           const char *ptr = NULL;
           const char *pptr = NULL;
           
           if (memicmp(cp1, "<a href", strlen("<a href")) == 0) {
              cp1 += strlen("<a href");
              parse_html_special(cp1, strlen(cp1), &beg, &end);
              anchor = xmalloc(end - beg + 1);
              memcpy(anchor, beg, end - beg);
              anchor[end - beg] = '\0';
              /* save the anchor string in m_prescan_info.pagelist[<current_page>] */
              m_prescan_info.pagelist[data->pageno] = anchor;
           }
           else if (memcmp(cp1, "/A", 2) == 0) {
              if ((ptr = strstr(cp1 + 2, "/GoToR")) != NULL /* external file */
                  && (ptr = strchr(ptr, '(')) != NULL
                  && (pptr = strchr(ptr + 1, '(')) != NULL) {
                  anchor = xmalloc(pptr - ptr);
                  memcpy(anchor, ptr + 1, pptr - ptr - 1);
                  anchor[pptr - ptr - 1] = '\0';
                  /* save the anchor string in m_prescan_info.pagelist[<current_page>] */
                  m_prescan_info.pagelist[data->pageno] = anchor;
              }
              else if ((ptr = strstr(cp1 + 2, "/URI")) != NULL /* external file */
                  && (ptr = strchr(ptr, '(')) != NULL
                  && (pptr = strchr(ptr + 1, '(')) != NULL) {
                  anchor = xmalloc(pptr - ptr);
                  memcpy(anchor, ptr + 1, pptr - ptr - 1);
                  anchor[pptr - ptr - 1] = '\0';
                  /* save the anchor string in m_prescan_info.pagelist[<current_page>] */
                  m_prescan_info.pagelist[data->pageno] = anchor;
              }
           }
           else if (memcmp(cp, "/L", 2) == 0) {
              if ((ptr = strstr(cp1 + 2, "/Dest")) != NULL /* internal link */
                  && (ptr = strchr(ptr, '(')) != NULL
                  && (pptr = strchr(ptr + 1, '(')) != NULL) {
                  anchor = xmalloc(pptr - ptr);
                  memcpy(anchor, ptr + 1, pptr - ptr - 1);
                  anchor[pptr - ptr - 1] = '\0';
                  /* save the anchor string in m_prescan_info.pagelist[<current_page>] */
                  m_prescan_info.pagelist[data->pageno] = anchor;
              }
           }
       }
    }
    if (memicmp(cp, "<a ", 3) == 0) {
       while (m_prescan_info.anchor_depth >= (int)m_prescan_info.anchor_list_size) {
           m_prescan_info.anchor_list_size += HTEX_ALLOC_STEP;
           m_prescan_info.anchor_list = XREALLOC(m_prescan_info.anchor_list,
                                            m_prescan_info.anchor_list_size
                                            * sizeof *(m_prescan_info.anchor_list));
       }
       ASSERT(m_prescan_info.anchor_depth >= 0, "List should contain previous anchor info");
       m_prescan_info.anchor_list[m_prescan_info.anchor_depth] = m_prescan_info.anchor_num;
       m_prescan_info.anchor_depth++;
       m_prescan_info.anchor_num++;
    }
    else if (memicmp(cp, "</a", 3) == 0) {
       if (m_prescan_info.anchor_depth < 1) {
           /* this can happen when stuff had been prescanned before */
           return False;
       }
       m_prescan_info.anchor_depth--;
       m_prescan_info.anchor_num++;
    }
    else if (memcmp(cp, "H.S end", strlen("H.S end")) == 0) { /* start of anchor */
       while (m_prescan_info.anchor_depth >= (int)m_prescan_info.anchor_list_size) {
           m_prescan_info.anchor_list_size += HTEX_ALLOC_STEP;
           m_prescan_info.anchor_list = XREALLOC(m_prescan_info.anchor_list,
                                            m_prescan_info.anchor_list_size
                                            * sizeof *(m_prescan_info.anchor_list));
       }
       ASSERT(m_prescan_info.anchor_depth >= 0, "List should contain previous anchor info");
       m_prescan_info.anchor_list[m_prescan_info.anchor_depth] = m_prescan_info.anchor_num;
       m_prescan_info.anchor_depth++;
       m_prescan_info.anchor_num++;

    }
    else if (memcmp(cp, "H.R end", strlen("H.R end")) == 0 /* end of rect */
            || memcmp(cp, "H.A end", strlen("H.A end")) == 0 /* end of anchor */
            || memcmp(cp, "H.L end", strlen("H.L end")) == 0 /* end of link */
            ) {
       if (m_prescan_info.anchor_depth < 1) {
           /* this can happen when stuff had been prescanned before */
           return False;
       }
       m_prescan_info.anchor_depth--;
       m_prescan_info.anchor_num++;
    }
    return False;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void htex_record_position ( int  ulx,
int  uly,
int  w,
int  h 
)

Definition at line 1232 of file hypertex.c.

{
    int lrx, lry;
    int y_delta, x_delta;

    if (!INSIDE_MANE_WIN) /* this would give wrong values */
       return;

    lrx = ulx + w;
    lry = uly + h;

    y_delta = lry - uly;
    x_delta = lrx - ulx;

    /* heuristics for creating new bounding box at what might be linebreaks */
    if (lrx < x_pos_bak /* ordinary linebreak */
       || lry + y_delta < y_pos_bak) { /* column break (from bottom of 1st to top 2nd column) */
       htexAnchorT type;
       int idx, prev, curr;
       /* get anchor index of topmost stack item, to find the matching open tag */
       if ((type = peek_stack(&stack, &idx)) == A_NONE) {
/*         fprintf(stderr, "!!!!!!!!!!!! couldn't find opening tag for this wrapped link!"); */
           return;
       }
       ASSERT(idx >= 0, "Index out of range");
/*     fprintf(stderr, "wrapped link: index %d, type %d\n", idx, type); */
       /* get correct idx */
       if (m_href_type == HYPERTEX_LINK) {
           while (htex_page_info.anchors[idx].a_href == NULL && idx > 0) {
              idx--;
           }
           if (htex_page_info.anchors[idx].a_href == NULL && idx == 0) {
              XDVI_ERROR((stderr, "Couldn't find wrapped anchor for idx %d, page %d!", idx, current_page));
              return;
           }
           add_anchor(&htex_page_info, A_HREF,
                     htex_page_info.anchors[idx].a_href,
                     strlen(htex_page_info.anchors[idx].a_href),
                     0, NULL);
       }
       else {
           add_anchor(&htex_page_info, A_HREF, "__WRAPPED__", strlen("__WRAPPED__"), 0, NULL);
       }
       htex_page_info.curr_cnt++;
       /* add wrapping info */
       if (htex_page_info.have_wrapped >= 0) {
           /* this is the only case where some other material might have come between
              this and the previous anchor */
           prev = htex_page_info.have_wrapped;
           htex_page_info.have_wrapped = -1;
       }
       else {
           prev = htex_page_info.curr_cnt - 2;
       }
       curr = htex_page_info.curr_cnt - 1;
       ASSERT(prev >= 0, "Index out of range");

/*     fprintf(stderr, "setting prev to %d, curr to %d\n", prev, curr); */
       htex_page_info.anchors[prev].next_wrapped = curr;
       htex_page_info.anchors[curr].prev_wrapped = prev;
       /* initialize it to cover current character */
       set_anchor_size(&htex_page_info, htex_page_info.curr_cnt - 1, ulx, uly, lrx, lry);
    }
    else {
       int prev_idx = htex_page_info.curr_cnt - 1;

       if (prev_idx >= 0) {
           enlarge_anchor_size(&htex_page_info, prev_idx, ulx, uly, lrx, lry);
       }
       else {
           MYTRACE((stderr, "!!!!!!!!!!!! Bug? prev_idx < 0"));
       }
    }
    x_pos_bak = lrx;
    y_pos_bak = uly;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1727 of file hypertex.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void htex_reset_page ( int  pageno)

Definition at line 1120 of file hypertex.c.

Here is the call graph for this function:

Definition at line 1715 of file hypertex.c.

Here is the call graph for this function:

Here is the caller graph for this function:

Boolean htex_scan_anchor ( const char *  cp,
size_t  len 
)

Definition at line 1127 of file hypertex.c.

{
    char *ptr;
    
    if (memicmp(cp, "</a>", 4) == 0) { /* end tag */
       /*     struct anchor_info *anchor; */
       int num;
       htexAnchorT type = pop_stack(&stack, &num);
       if (type == A_MISMATCH)
           return False;

       /* ASSERT(htex_page_info.curr_cnt - 1 >= 0, "Index out of range"); */
       /* anchor = &(htex_page_info.anchors[htex_page_info.curr_cnt - 1]); */

       /* reset color if needed */
       if (resource.link_style > 1 && resource.link_color != NULL && htex_is_href(type))
           pop_colorspecial();
    }
    else if (memicmp(cp, "<a ", 3) == 0) {
       m_href_type = HYPERTEX_LINK;
       cp += 3; /* skip over `<a ' part */
       len -= 3;
       TRACE_HTEX((stderr, "scan_anchor: |%s|", cp));
       if (memicmp(cp, "name", 4) == 0) {
           add_anchor(&htex_page_info, A_NAME, cp + 4, len - 4, 0, NULL);
           htex_page_info.curr_cnt++;
           push_stack(&stack, A_NAME, htex_page_info.curr_cnt);
       }
       else if (memicmp(cp, "href", 4) == 0) {
           add_anchor(&htex_page_info, A_HREF, cp + 4, len - 4, 0, NULL);
           htex_page_info.curr_cnt++;
           push_stack(&stack, A_HREF, htex_page_info.curr_cnt);

           /* MYTRACE((stderr, "NON-WRAPPED ANCHOR at %d,%d!", PXL_H, PXL_V)); */
           push_colorspecial();
           x_pos_bak = PXL_H;
           y_pos_bak = PXL_V;
/*         set_anchor_size(&htex_page_info, htex_page_info.curr_cnt - 1, PXL_H, PXL_V, PXL_H + 10, PXL_V + 10); */
       }
       else {
           XDVI_WARNING((stderr, "Skipping unimplemented htex special `%s'", cp));
           push_stack(&stack, A_OTHER, htex_page_info.curr_cnt);
       }
    }
    else if (memcmp(cp, "H.S end", strlen("H.S end")) == 0) {
       /* start of anchor, link or rect. We just assume that the link
          target will have length 0, so when we see text between H.S
          and H.R, assume that it's the link text.
       */
       m_href_type = HDVIPS_LINK;
       /* add dummy */
       add_anchor(&htex_page_info, A_HDVIPS_HREF, "__DUMMY__", strlen("__DUMMY__"), 0, NULL);
       htex_page_info.curr_cnt++;
       push_stack(&stack, A_HREF, htex_page_info.curr_cnt - 1);
       push_colorspecial();
       x_pos_bak = PXL_H;
       y_pos_bak = PXL_V;
       return True;
    }
    else if (memcmp(cp, "H.R end", strlen("H.R end")) == 0 /* end of rect */
            || memcmp(cp, "H.A end", strlen("H.A end")) == 0 /* end of anchor */
            || memcmp(cp, "H.L end", strlen("H.L end")) == 0 /* end of link */
            ) {
       int num;
       htexAnchorT type = pop_stack(&stack, &num);
       if (type == A_MISMATCH)
           return False;
       if (resource.link_style > 1 && resource.link_color != NULL)
           pop_colorspecial();
       return False;
    }
    /* add anchor texts for hdvips links */
    else if (memcmp(cp, "/A", 2) == 0) { /* possibly an hdvips external link */
/*     fprintf(stderr, "+++++ EXT: |%s|\n", cp); */
       if ((ptr = strstr(cp + 2, "/GoToR")) != NULL /* external file */
           && (ptr = strchr(ptr, '(')) != NULL) {
           hdvips_add_anchor(&htex_page_info, A_HREF_FILE, ptr + 1);
       }
       else if ((ptr = strstr(cp + 2, "/URI")) != NULL /* URL */
               && (ptr = strchr(ptr, '(')) != NULL) {
           hdvips_add_anchor(&htex_page_info, A_HREF_URL, ptr + 1);
       }
       return False;
    }
    else if (memcmp(cp, "/L", 2) == 0) { /* possibly an hdvips internal link */
       if ((ptr = strstr(cp + 2, "/Dest")) != NULL
           && (ptr = strchr(ptr, '(')) != NULL) {
           hdvips_add_anchor(&htex_page_info, A_HDVIPS_INTERNAL, ptr + 1);
       }
       return False;
    }
    else if (memcmp(cp, "/V", 2) == 0) { /* possibly an hdvips anchor */
       if ((ptr = strstr(cp + 2, "/Dest")) != NULL
           && (ptr = strchr(ptr, '(')) != NULL) {
           hdvips_add_anchor(&htex_page_info, A_HDVIPS_NAME, ptr + 1);
       }
       return False;
    }
    else { /* not a start tag */
       MYTRACE((stderr, "Xdvi warning: skipping malformed hyperref special `%s'", cp));
    }
    return get_href_depth(&stack);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2082 of file hypertex.c.

{
    Position drawing_x;

    /* erase old marker if it's on the same page as the new marker, after
       cancelling the old timeout so that it won't affect the new marker */
    if (m_href_timeout_id)
       XtRemoveTimeOut(m_href_timeout_id);
    htex_erase_anchormarker(NULL, NULL);
    XFlush(DISP);
    
    XtVaGetValues(globals.widgets.draw_widget, XtNx, &drawing_x, NULL);
    g_anchormarker.page = current_page;
    free(g_anchormarker.filename);
    g_anchormarker.filename = xstrdup(globals.dvi_name);
    g_anchormarker.y_pos = y;
    g_anchormarker.x_pos = DEFAULT_MARKER_X_OFFSET + -drawing_x;
    m_href_timeout_id = XtAppAddTimeOut(app, STATUS_SHORT * 1000, htex_erase_anchormarker, (XtPointer)NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void htex_set_anchorsize ( int  ulx,
int  uly,
int  lrx,
int  lry 
)

Definition at line 974 of file hypertex.c.

{
    set_anchor_size(&htex_page_info, htex_page_info.curr_cnt - 1,
                  ulx, uly, lrx, lry);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 968 of file hypertex.c.

Here is the caller graph for this function:

static void htex_update_toolbar_navigation ( void  ) [static]

Definition at line 1355 of file hypertex.c.

{
#if 0
    show_history();
#endif
#if defined(MOTIF) && HAVE_XPM
    tb_set_htex_back_sensitivity(htex_history->prev != NULL);
    tb_set_htex_forward_sensitivity(htex_history->next != NULL);
#endif
}

Here is the caller graph for this function:

static void init_visited_links ( struct visited_anchors links,
int  total_pages,
Boolean  new_dvi_file 
) [static]

Definition at line 616 of file hypertex.c.

{
    size_t i, old_size = links->size;
    if (new_dvi_file) {
       /* free old list */
       for (i = 0; i < old_size; i++) {
           FREE(links->anchors[i].list);
           links->anchors[i].list = NULL;
           links->anchors[i].list_size = 0;
       }
    }
    if (links->size <= (size_t)total_pages) {
       MYTRACE((stderr, "resetting visited links (%d != %d)", links->size, total_pages));
       links->size = total_pages + 1;
       links->anchors = XREALLOC(links->anchors, (links->size + 1) * sizeof *(links->anchors));
       for (i = old_size; i < links->size; i++) {
           MYTRACE((stderr, "+++ initializing visited links for page %d", i));
           links->anchors[i].list = NULL;
           links->anchors[i].list_size = 0;
       }
    }
}

Here is the caller graph for this function:

const char* is_local_file ( const char *  filename)

Definition at line 816 of file hypertex.c.

{
    int i;
    if (strchr(filename, ':') != NULL) {
       if (memicmp(filename, "file:", strlen("file:")) == 0) {
           TRACE_HTEX((stderr, "%s uses file scheme", filename));
           filename += strlen("file:");
           /*
             skip over `//localhost' part, and skip first `/' iff the
             absolute path starts with `//' (as required by RFC2396,
             but in the past most browsers/applications didn't support
             this).
            */
           if (memicmp(filename, "//localhost", strlen("//localhost")) == 0) {
              filename += strlen("//localhost");
           }
           if (memicmp(filename, "//", 2) == 0) {
              filename += 1;
           }
           return filename;
       }
       
       /* check remote schemes */
       for (i = 0; remote_URL_schemes[i] != NULL; i++) {
           if (memicmp(filename, remote_URL_schemes[i], strlen(remote_URL_schemes[i])) == 0) {
              TRACE_HTEX((stderr, "%s is a remote scheme", filename));
              return NULL;
           }
       }
    }
    /* in all other cases, treat it as an ordinary filename */
    TRACE_HTEX((stderr, "%s is an ordinary filename", filename));
    return filename;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Boolean is_visited ( struct visited_anchors links,
int  pageno,
int  anchor_num 
) [static]

Definition at line 690 of file hypertex.c.

{
    size_t i;
    
    ASSERT((size_t)pageno < links->size, "too few elements in links structure");

    for (i = 0; i < links->anchors[pageno].list_size; i++) {
       if (links->anchors[pageno].list[i] == anchor_num) {
           return True;
       }
    }
    return False;
}

Here is the caller graph for this function:

void launch_program ( const char *  filename)

Definition at line 1922 of file hypertex.c.

{
    const char *format_string = NULL;
    char *content_type = NULL;
    char *viewer = NULL;
    char *argv[4];
    struct stat statbuf;
    const char *local_filename_sans_prefix;
    char *path, *syscmd, *tmp;
#if COPY_TMP_FILE
    int tmp_fd;
#endif
    const char *ptr;
    char *fullpath = NULL;
    char canonical_path[MAXPATHLEN + 1];
    Boolean needs_terminal;
    
    TRACE_HTEX((stderr, "launch_program called with |%s|", filename));

    /* is it a local file? */
    local_filename_sans_prefix = is_local_file(filename);
    if (local_filename_sans_prefix == NULL) { /* not local */
       launch_browser(filename);
       return;
    }

    /* expand the filename if it contains a relative path */
    path = find_file(local_filename_sans_prefix, &statbuf, kpse_program_text_format);
    if (path != NULL) {
       /* fully canonicalize path before passing it to helper applications */
       fullpath = REALPATH(path, canonical_path);
       if (fullpath == NULL) {
           XDVI_WARNING((stderr, "Couldn't canonicalize %s to full path - returning unexpanded.",
                       path));
           fullpath = path;
       }
       else
           FREE(path);
    }
    else {
       XDVI_WARNING((stderr, "Couldn't find file %s; passing to application unchanged.",
                    local_filename_sans_prefix));
       /* if it doesn't exist, maybe the user has encoded some magic in the
          filename; in that case, pass it to the application unchanged. */
       fullpath = (char *)local_filename_sans_prefix;
    }

    TRACE_HTEX((stderr, "fullpath: |%s|", fullpath));
    content_type = figure_mime_type(fullpath);
    ASSERT(content_type != NULL, "figure_mime_type() should have returned a valid type (eventually a fallback)");
    
    /* make it safe to pass the argument to system() or `sh -c',
       by escaping all `dangerous' characters: */
    tmp = shell_escape_string(fullpath);
    fullpath = tmp;
    
    if ((viewer = figure_viewer(content_type, &format_string, &needs_terminal, fullpath)) == NULL) {
       /* warn user if no application has been found. Help text needs to be constructed at
          run-time, since we want the correct content-type in it. */
#if 0
       char *errmsg = NULL;
#else
       char *errmsg = xstrdup("Please assign an application to the MIME type `");
       errmsg = xstrcat(errmsg, content_type);
       errmsg = xstrcat(errmsg, "' in your ~/.mailcap file. "
                            "E.g. if you want to view the file with netscape, add the following line to your ~/.mailcap:\n");
       errmsg = xstrcat(errmsg, content_type);
       errmsg = xstrcat(errmsg, "; netscape -raise  -remote 'openURL(%%s,new-window)'\n\n");
#endif
       popup_message(globals.widgets.top_level,
                    MSG_WARN,
                    errmsg,
                    "Could not determine an application for the file %s, MIME type `%s'.",
                    fullpath, content_type);
       /* FIXME: something's wrong with the memory allocation scheme here -
          can't free errmsg, it's already free'd inside popup_message() ?? */
       /* free(errmsg); */
       free(fullpath);
       return;
    }
    
#if COPY_TMP_FILE
    /* copy the file to a temporary location before passing it to the
       viewer.  This is e.g. how Acroread does it. This should fix the
       problem with xdvizilla without -no-rm for DVI files (see comment
       in figure_viewer(), mime.c).
       SU 2003/10/02: currently I can't reproduce the xdvizilla problem
       any more - it seems that for xdvi files, argv[0] will be invoked
       anyway? Also, copying the files to tmp may break figure locations
       and relative links for DVI files. Suspended this for the time being.
    */
    tmp = NULL;
    if ((tmp_fd = xdvi_temp_fd(&tmp)) == -1) {
       XDVI_ERROR((stderr, "couldn't create temporary file; not calling helper application."));
       return;
    }
    TRACE_HTEX((stderr, "copying to temporary location: |%s->%s|", fullpath, tmp));
    if (!copy_file(fullpath, tmp)) {
       XDVI_ERROR((stderr, "couldn't copy %s to temporary file %s; not invoking helper application.",
                  fullpath, tmp));
       return;
    }
    free(fullpath);
    fullpath = tmp;
#endif
    
    if (strlen(format_string) > 0) {
       ptr = find_format_str(viewer, format_string);
    }
    else { /* countrary to RFC 1343, we don't pass stuff via pipes (too bothersome) */
       ptr = strchr(viewer, '\0');
    }

    if (needs_terminal) {
       size_t offset = strlen("xterm -e ");
       syscmd = xmalloc(offset + strlen(viewer) + strlen(fullpath) + 1);
       strcpy(syscmd, "xterm -e ");
       memcpy(syscmd + offset, viewer, ptr - viewer);
       strcpy(syscmd + offset + (ptr - viewer), fullpath);
       strcpy(syscmd + offset + (ptr - viewer) + strlen(fullpath), ptr + strlen(format_string));
       
    }
    else {
       syscmd = xmalloc(strlen(viewer) + strlen(fullpath) + 1);
       memcpy(syscmd, viewer, ptr - viewer);
       strcpy(syscmd + (ptr - viewer), fullpath);
       strcpy(syscmd + (ptr - viewer) + strlen(fullpath), ptr + strlen(format_string));
    }

    /*
      mailcap(4) says that the mailcap command shall be passed to system(),
      so we musn't use fork_process() directly here. Instead, we pass the command
      to `/bin/sh -c', but via fork_process so that
      
      - xdvi doesn't hang if the process doesn't return;
      - we can still catch the return value if `sh -c' exits with an error
        (e.g. if the viewer command is not found).

      Note however that this doesn't mimick most of POSIX's system() semantics.
    */
    TRACE_HTEX((stderr, "execv(\"/bin/sh -c %s\")", syscmd));
    argv[0] = "/bin/sh";
    argv[1] = "-c";
    argv[2] = syscmd;
    argv[3] = NULL;
#if COPY_TMP_FILE
    fork_process("/bin/sh", False, globals.dvi_file.dirname, remove_temp_file, fullpath, argv);
#else
    fork_process("/bin/sh", False, globals.dvi_file.dirname, NULL, NULL, argv);
#endif

    FREE(viewer);
#if COPY_TMP_FILE
#else
    FREE(fullpath);
#endif
    FREE(syscmd);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void launch_xdvi ( const char *  filename,
const char *  anchor_name 
)

Definition at line 1819 of file hypertex.c.

{
#define ARG_LEN 32
    int i = 0;
    char *argv[ARG_LEN];
    char *shrink_arg = NULL;

    ASSERT(filename != NULL, "filename argument to launch_xdvi() mustn't be NULL");

    argv[i++] = program_invocation_name;
    /* FIXME: there's something broken with this and invoking xdvi.bin.
       To reproduce the problem, invoke from the shell:
       xdvi.bin -geometry 829x1172 /usr/share/texmf/doc/programs/kpathsea.dvi
       this will run at 300dpi, i.e. ignore an .Xdefaults setting as opposed to:
       xdvi.bin /usr/share/texmf/doc/programs/kpathsea.dvi

       Also, how about the other command-line switches that might have
       been passed to the parent instance? How about things that have been changed
       at run-time, like shrink factor - should they be converted to command-line
       options?
    */

    argv[i++] = "-name";
    argv[i++] = "xdvi";

    /* start the new instance with the same debug flags as the current instance */
    if (globals.debug != 0) {
       char debug_flag[128];
       SNPRINTF(debug_flag, 128, "%lu", globals.debug);
       argv[i++] = "-debug";
       argv[i++] = debug_flag;
    }
    
    if (anchor_name != NULL) {
       argv[i++] = "-anchorposition";
       argv[i++] = (char *)anchor_name;
    }

    argv[i++] = "-s";
    shrink_arg = XMALLOC(shrink_arg, LENGTH_OF_INT + 1);
    sprintf(shrink_arg, "%d", currwin.shrinkfactor);
    argv[i++] = shrink_arg;

    argv[i++] = (char *)filename; /* FIXME */
    
    argv[i++] = NULL;
    ASSERT(i <= ARG_LEN, "Too few elements in argv[]");
    
    if (globals.debug & DBG_HTEX) {
       fprintf(stderr, "Invoking:\n");
       for (i = 0; argv[i]; i++) {
           fprintf(stderr, "%s\n", argv[i]);
       }
    }

    /*
      FIXME: using fork_process here hangs the new xdvi process when it tries
      printing to stderr, so we use plain fork/exec (see comments in util.c)
    */
#if 0
    fork_process(argv[0], False, NULL, NULL, NULL, argv);
#else
    {
       int pid;
       switch (pid = fork()) {
       case -1:
           perror("fork");
       case 0:
           execvp(argv[0], argv);
           MYTRACE((stderr, "%s: Execution of %s failed.", globals.program_name, argv[0]));
           _exit(EXIT_FAILURE);
       default:
           FREE(shrink_arg);
       }
    }
#endif
#undef ARG_LEN
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* parse_anchortext ( const char *  input,
int  len 
) [static]

Definition at line 853 of file hypertex.c.

{
    char *anchor = NULL;
    const char *beg, *end;

    parse_html_special(input, len, &beg, &end);

    anchor = XMALLOC(anchor, end - beg + 1);
    memcpy(anchor, beg, end - beg);
    anchor[end - beg] = '\0';
    return anchor;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void parse_html_special ( const char *  special,
size_t  len,
const char **  beg,
const char **  end 
) [static]

Definition at line 144 of file hypertex.c.

{
    *beg = special;
    while (isspace((int)**beg) || **beg == '=') {
       (*beg)++;
       len--;
    }
    *end = *beg + len - 1;

    while (isspace((int)**end) || **end == '>')
       (*end)--;

    /* remove quote pairs */
    if (**beg == '"') {
       (*beg)++;
       if (**end == '"') {
           (*end)--;
       }
    }
    /* now end points to last anchor char, move behind that */
    (*end)++;
}

Here is the caller graph for this function:

static htexAnchorT peek_stack ( struct htex_anchor_stack stack,
int anchor_num 
) [static]

Definition at line 770 of file hypertex.c.

{
    if (stack->depth < 1) {
       MYTRACE((stderr, "Xdvi warning: wrong nesting of anchors on page %d", current_page));
       *anchor_num = -1;
       return A_NONE;
    }
    
    *anchor_num = stack->types[stack->depth - 1].anchor_num;
    return stack->types[stack->depth - 1].type;
}

Here is the caller graph for this function:

static void pop_colorspecial ( void  ) [static]

Definition at line 809 of file hypertex.c.

{
    color_special("pop");
}

Here is the call graph for this function:

Here is the caller graph for this function:

static htexAnchorT pop_stack ( struct htex_anchor_stack stack,
int anchor_num 
) [static]

Definition at line 730 of file hypertex.c.

{
    htexAnchorT ret;
    
    if (stack->depth < 1) {
       return A_MISMATCH;
    }
    
#if 0
    {
       int i;
       MYTRACE((stderr, "POP - stack is now: "));
       for (i = 0; i < stack->depth; i++)
           MYTRACE((stderr, "%d:%d ", i, stack->types[i]));
       MYTRACE((stderr, ""));
    }
#endif
    stack->depth--;
    ret = stack->types[stack->depth].type;
    *anchor_num = stack->types[stack->depth].anchor_num;
    stack->types[stack->depth].type = A_NONE;
    stack->types[stack->depth].anchor_num = -1;
    return ret;
}

Here is the caller graph for this function:

static void push_colorspecial ( void  ) [static]

Definition at line 784 of file hypertex.c.

{
    int i;

    i = htex_page_info.curr_cnt - 1;
    /* apply color if needed */
    if (resource.link_style > 1) { /* colored links are wanted */
       Boolean visited = False;

       ASSERT(i >= 0, "i mustn't be negative");
       if (is_visited(&visited_links, current_page, i)) {/*  || wrapped_anchor_is_visited(i)) { */
           visited = True;
       }

       MYTRACE((stderr, "anchor %d, %s is %s\n",
               htex_page_info.curr_cnt - 1, htex_page_info.anchors[htex_page_info.curr_cnt - 1].a_href,
               visited ? "******* visited ****** " : "not visited"));
       if ((visited && resource.visited_link_color != NULL)
           || (! visited && resource.link_color != NULL)) {
           color_special(visited ? g_visited_link_color_rgb : g_link_color_rgb);
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void push_stack ( struct htex_anchor_stack stack,
htexAnchorT  type,
int  anchor_num 
) [static]

Definition at line 705 of file hypertex.c.

{
    size_t i = 0;
    if (stack->depth >= stack->size) {
       stack->size += HTEX_ALLOC_STEP;
       stack->types = XREALLOC(stack->types, stack->size * sizeof *(stack->types));
       for (i = stack->depth; i < stack->size; i++) {
           stack->types[i].type = A_NONE;
           stack->types[i].anchor_num = -1;
       }
    }
    stack->types[stack->depth].type = type;
    stack->types[stack->depth].anchor_num = anchor_num;
    stack->depth++;
#if 0
    {
       fprintf(stderr, "PUSH - stack is now: \n");
       for (i = 0; i < stack->depth; i++)
           fprintf(stderr, "%d:%d ", i, stack->types[i]);
       MYTRACE(stderr, "\n");
    }
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void redraw_anchors ( int  idx) [static]

Definition at line 1555 of file hypertex.c.

{
    struct anchor_info anchor = htex_page_info.anchors[idx];
    int other;
    int i = idx;
#define DO_EXPOSE(lx,ly,rx,ry) (clearexpose(&mane, lx - 20, ly - 3, rx - lx + 26, ry - ly + 6))    

    /* HACK ALERT: This is a workaround for a coloring problem with wrapped anchors
       (see regression/href/002/url-wrap-test2.dvi):
       We can't change the color on-the-fly for a wrapped anchor, since the special
       is pushed only at the opening tag. So for wrapped anchors, the visited colour
       wouldn't be set correctly. Redrawing the entire page ensures this (but it's ugly).
       Currently this hack overrides the algorithm below for all anchors that have a
       `prev_wrapped' pointer.
     */
    if (htex_page_info.anchors[i].prev_wrapped != -1) {
       globals.ev.flags |= EV_NEWPAGE;
       XSync(DISP, False);
       return;
    }

    DO_EXPOSE(anchor.ulx, anchor.uly, anchor.lrx, anchor.lry);

    /* previous parts of wrapped anchors: */
    for (i = idx;
        i >= 0 && (other = htex_page_info.anchors[i].prev_wrapped) != -1;
        i--) {
       DO_EXPOSE(htex_page_info.anchors[other].ulx, htex_page_info.anchors[other].uly,
                htex_page_info.anchors[other].lrx, htex_page_info.anchors[other].lry);
    }

    /* later parts of wrapped anchors: */
    for (i = idx;
        i < htex_page_info.curr_cnt && (other = htex_page_info.anchors[i].next_wrapped) != -1;
        i++) {
       DO_EXPOSE(htex_page_info.anchors[other].ulx, htex_page_info.anchors[other].uly,
                htex_page_info.anchors[other].lrx, htex_page_info.anchors[other].lry);
    }
#undef DO_EXPOSE
}

Here is the caller graph for this function:

static void reset_page_info ( struct htex_page_info info,
int  pageno,
Boolean  force_init 
) [static]

Definition at line 1010 of file hypertex.c.

{
    int i, dummy;

    if (force_init || pageno != info->page) {
#if 0
       fprintf(stderr, "%d or %d != %d: resetting anchorinfo for page %d (%d anchors)\n",
              force_init, pageno, info->page, current_page, info->curr_cnt);
#endif
       ASSERT(info->curr_cnt == 0 || info->anchors != NULL, "inconsistency in info structure");
       /* re-initialize all values */
       for (i = 0; i < info->curr_cnt; i++) {
           TRACE_HTEX((stderr, "----- resetting info for anchor %d", i));
           FREE(info->anchors[i].a_name);
           FREE(info->anchors[i].a_href);
           info->anchors[i].a_name = NULL;
           info->anchors[i].a_href = NULL;
           info->anchors[i].ulx = INT_MAX;
           info->anchors[i].uly = INT_MAX;
           info->anchors[i].lrx = 0;
           info->anchors[i].lry = 0;
           info->anchors[i].object_type = HTEX_TEXT;
           info->anchors[i].prev_wrapped = -1;
           info->anchors[i].next_wrapped = -1;
       }
    }
    if (pageno != info->page) { /* reset info */
       free(info->anchors);
       info->anchors = NULL;
       info->tot_cnt = 0;
    }
    TRACE_HTEX((stderr, "---------------- setting curr_cnt to 0, and emptying stack"));
    info->page = pageno;
    info->curr_cnt = 0;
    info->have_wrapped = -1;
    while (stack.depth > 0)
       pop_stack(&stack, &dummy);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void resize_info_if_needed ( struct htex_page_info info) [static]

Definition at line 590 of file hypertex.c.

{
    /* resize info if needed */
    if (info->curr_cnt + 2 >= info->tot_cnt) {
       int i;
       while (info->curr_cnt + 2 >= info->tot_cnt) {
           info->tot_cnt += HTEX_ALLOC_STEP;
       }
       info->anchors = XREALLOC(info->anchors, info->tot_cnt * sizeof *(info->anchors));
       for (i = info->curr_cnt; i < info->tot_cnt; i++) {
/*         fprintf(stderr, "initializing info at index %d\n", i); */
           info->anchors[i].a_href = NULL;
           info->anchors[i].a_name = NULL;
/*         info->anchors[i].filename = NULL; */
           info->anchors[i].ulx = INT_MAX;
           info->anchors[i].uly = INT_MAX;
           info->anchors[i].lrx = 0;
           info->anchors[i].lry = 0;
           info->anchors[i].object_type = HTEX_TEXT;
           info->anchors[i].prev_wrapped = -1;
           info->anchors[i].next_wrapped = -1;
       }
    }
}

Here is the caller graph for this function:

static void save_in_list ( struct visited_anchors links,
int  pageno,
int  idx 
) [static]

Definition at line 653 of file hypertex.c.

{
    links->anchors[pageno].list
       = XREALLOC(links->anchors[pageno].list,
                 (links->anchors[pageno].list_size + 1)
                 * sizeof *(links->anchors[pageno].list));
    links->anchors[pageno].list[links->anchors[pageno].list_size] = idx;
    links->anchors[pageno].list_size++;
}

Here is the caller graph for this function:

static void set_anchor_size ( struct htex_page_info info,
int  index,
int  ulx,
int  uly,
int  lrx,
int  lry 
) [static]

Definition at line 951 of file hypertex.c.

{
    struct anchor_info *anchor;
    
    ASSERT(info->anchors != NULL, "info->anchors should have been allocated before");
    ASSERT(index < info->curr_cnt, "info too small");
    
    anchor = &(info->anchors[index]);

    anchor->ulx = ulx;
    anchor->uly = uly;
    anchor->lrx = lrx;
    anchor->lry = lry;
}

Here is the caller graph for this function:

static void set_visited ( struct visited_anchors links,
int  pageno,
int  anchor_num 
) [static]

Definition at line 664 of file hypertex.c.

{
    int i;
    /* is it already present? */
    for (i = 0; i < (int)links->anchors[pageno].list_size; i++) {
       if (links->anchors[pageno].list[i] == anchor_num)
           return;
    }
    save_in_list(links, pageno, anchor_num);
    i = anchor_num;
    /* also set previous/next of this anchor to visited */
    while ((i = htex_page_info.anchors[i].prev_wrapped) != -1) {
       TRACE_HTEX((stderr, "set_visited: setting prev_wrapped %d to visited too", i));
       save_in_list(links, pageno, i);
    }
    i = anchor_num;
    while ((i = htex_page_info.anchors[i].next_wrapped) != -1) {
       TRACE_HTEX((stderr, "set_visited: setting next_wrapped %d to visited too", i));
       save_in_list(links, pageno, i);
    }
#if 0
    show_visited(links, pageno);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 105 of file hypertex.c.

Definition at line 101 of file hypertex.c.

Definition at line 99 of file hypertex.c.

char* g_anchor_pos = NULL

Definition at line 98 of file hypertex.c.

Definition at line 96 of file hypertex.c.

Definition at line 97 of file hypertex.c.

const int HTEX_ALLOC_STEP = 32 [static]

Definition at line 102 of file hypertex.c.

struct htex_anchor_stack = { 0, 0, NULL } [static]

Definition at line 532 of file hypertex.c.

struct dl_list* htex_history = NULL [static]

Definition at line 504 of file hypertex.c.

struct htex_page_info = { NULL, 0, 0, -1, -1 } [static]

Definition at line 499 of file hypertex.c.

XtIntervalId m_href_timeout_id = 0 [static]

Definition at line 463 of file hypertex.c.

Definition at line 109 of file hypertex.c.

static struct prescan_info = { 0, 0, 0, NULL, 0, NULL } [static]

Definition at line 185 of file hypertex.c.

char* const remote_URL_schemes[] [static]

Definition at line 542 of file hypertex.c.

struct visited_anchors = { NULL, 0 } [static]

Definition at line 530 of file hypertex.c.

int x_pos_bak = 0 [static]

Definition at line 496 of file hypertex.c.

int y_pos_bak = 0 [static]

Definition at line 497 of file hypertex.c.