Back to index

tetex-bin  3.0
Classes | Defines | Enumerations | Functions | Variables
pagesel.c File Reference
#include "xdvi-config.h"
#include "xdvi.h"
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include "xm_toolbar.h"
#include "xm_menu.h"
#include "xaw_menu.h"
#include "x_util.h"
#include <X11/Xaw/Dialog.h>
#include <X11/Xaw/Cardinals.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/List.h>
#include <X11/Xaw/Viewport.h>
#include "message-window.h"
#include "pagesel.h"
#include "util.h"
#include "string-utils.h"
#include "dvi-init.h"
#include "statusline.h"
#include "events.h"
#include "print-dialog.h"
#include "search-internal.h"
#include "pagehist.h"

Go to the source code of this file.

Classes

struct  page_gc
struct  page_index
struct  page_index_info

Defines

#define PAGENUMLEN   128
#define SCROLL_LIST_SCROLLBAR   0
#define MAX_PAGE   (1024)
#define LONGESTPAGENUM   55
#define MOTIF_IDX_OFFSET   1 /* motif index starts at 1, not 0 */
#define LIST_WIDGET   list_widget
#define REDRAW_CURRENT_MARKER_HACK   1

Enumerations

enum  saveCmdT { SCROLL_UP, SCROLL_DOWN, CLICK }

Functions

static Boolean my_list_pos_to_bounds (Widget widget, int idx, Position *x, Position *y, Dimension *w, Dimension *h)
static void refresh_highlight_marker (Widget widget, GC gc, Position x, Position y, Dimension w, Dimension h)
static int xaw_maybe_scroll_pagelist (int new_page, Boolean force_recenter, int old)
static void xaw_maybe_redraw_highlight (int idx)
static void xaw_maybe_redraw_current_marker (int idx)
long pageinfo_get_offset (int page)
unsigned int pageinfo_get_page_width (int page)
unsigned int pageinfo_get_page_height (int page)
unsigned int pageinfo_get_window_width (int page)
unsigned int pageinfo_get_window_height (int page)
void pageinfo_set_page_width (int page, unsigned int width)
void pageinfo_set_page_height (int page, unsigned int height)
void pageinfo_set_window_width (int page, unsigned int width)
void pageinfo_set_window_height (int page, unsigned int height)
int pageinfo_get_number (int page)
int pageinfo_get_index_of_number (int number)
void pageinfo_set_offset (int index, long offset)
void pageinfo_set_number (int index, int number)
void pageinfo_allocate (int total_pages)
void pageinfo_deallocate (void)
Boolean pageinfo_have_marked_pages (void)
Boolean pageinfo_is_marked (int i)
static void internal_process_button2 (Widget widget, XEvent *event)
static int get_item_index (Widget w, int mouse_y)
static int get_page_size (void)
static void xaw_update_list (void)
static void xaw_get_row_height (Widget w, Dimension *row_height, Dimension *internal_h)
int xaw_get_pagelist_size (void)
static void xaw_drag_page_callback (Widget widget, XtPointer data, XEvent *event, Boolean *cont)
static void xaw_SendReportProc (Widget w, XtPointer closure, XtPointer call_data)
static void wheel_scroll_list_callback (Widget widget, XtPointer data, XEvent *event, Boolean *cont)
static void highlight_page_callback (Widget widget, XtPointer data, XEvent *event, Boolean *cont)
static void select_page_callback (Widget w, XtPointer closure, XtPointer call_data)
static void init_pagelabels (int start, int end)
static void mark_page_callback (Widget w, XtPointer data, XEvent *event, Boolean *cont)
void xaw_create_pagelist_widgets (Dimension height, Dimension width, Position y, Widget parent)
static void xaw_toggle_label (Widget w, int idx, Boolean update)
static void toggle_label (Widget widget, int idx, Boolean update)
void list_toggle_marks (int arg)
void handle_pagelist_resize (void)
void handle_destroy_pagelist (Widget w, XtPointer client_data, XtPointer call_data)
void create_pagelist (void)
static void free_pagelabels (void)
void refresh_pagelist (int newsize, int newpage)
void maybe_scroll_pagelist (int newpage, Boolean force_recenter)
void list_toggle_current (int arg)

Variables

static struct page_gc m_page_gc
static int view_y
Widget panel_widget
static Widget list_widget = NULL
static Widget viewport = NULL
static const char *const pageno_format = "%c %*d "
static int g_current_highlighted = -1
static struct page_index_info
static Boolean PagelistInitialized = False

Class Documentation

struct page_gc

Definition at line 122 of file pagesel.c.

Class Members
GC back
GC fore
struct page_index

Definition at line 242 of file pagesel.c.

Class Members
Boolean marked
int number
long offset
unsigned int ph
unsigned int pw
unsigned int wh
unsigned int ww
struct page_index_info

Definition at line 250 of file pagesel.c.

Collaboration diagram for page_index_info:
Class Members
struct page_index * index
size_t index_size
char ** page_labels

Define Documentation

#define LIST_WIDGET   list_widget

Definition at line 170 of file pagesel.c.

#define LONGESTPAGENUM   55

Definition at line 115 of file pagesel.c.

#define MAX_PAGE   (1024)

Definition at line 112 of file pagesel.c.

#define MOTIF_IDX_OFFSET   1 /* motif index starts at 1, not 0 */

Definition at line 127 of file pagesel.c.

#define PAGENUMLEN   128

Definition at line 108 of file pagesel.c.

Definition at line 176 of file pagesel.c.

#define SCROLL_LIST_SCROLLBAR   0

Definition at line 109 of file pagesel.c.


Enumeration Type Documentation

enum saveCmdT
Enumerator:
SCROLL_UP 
SCROLL_DOWN 
CLICK 

Definition at line 450 of file pagesel.c.


Function Documentation

Definition at line 1232 of file pagesel.c.

{
    Pixel background, foreground;
#ifdef MOTIF
    
/*     items = xrealloc(items, sizeof *items * (total_pages + 2)); */
    init_pagelabels(0, total_pages);
    xm_set_page_labels();
    if (!PagelistInitialized) {
       XtAppContext app;

       XtVaGetValues(LIST_WIDGET, XmNforeground, &foreground, XmNbackground, &background, NULL);
       m_page_gc.back = set_or_make_gc(NULL, GXcopy, background, foreground);
       m_page_gc.fore = set_or_make_gc(NULL, GXcopy, foreground, background);
       XtManageChild(LIST_WIDGET);

       XtAddCallback(LIST_WIDGET, XmNbrowseSelectionCallback, select_page_callback, NULL);
#if !defined(LESSTIF_VERSION)
       /*
         Don't use the highlighting hack with LessTif, since its XmListPosToBounds()
         is too broken to be usable (as of 0.93.36):
         - it returns generally too low values, apparently it doesn't take
           XmNlistSpacing into account;
         - it doesn't take scrollbar position into account.
       */
       if (resource.pagelist_highlight_current)
           XtAddEventHandler(LIST_WIDGET,
                           ButtonPressMask | ButtonReleaseMask | PointerMotionMask | LeaveWindowMask,
                           False, highlight_page_callback, (XtPointer)NULL);
#endif /* !defined(LESSTIF_VERSION) */
       XtAddEventHandler(LIST_WIDGET, ButtonPressMask | ButtonReleaseMask,
                       False, wheel_scroll_list_callback, (XtPointer)NULL);
       
       app = XtWidgetToApplicationContext(globals.widgets.top_level);
       XtAppAddActions(app, CustomListActions, XtNumber(CustomListActions));
       XtOverrideTranslations(LIST_WIDGET, XtParseTranslationTable(motif_custom_translations));
       PagelistInitialized = True;
    }
#else /* MOTIF */
    if ((resource.expert_mode & XPRT_SHOW_BUTTONS) == 0) {
       PagelistInitialized = False; /* might need to re-create widgets in this case */
       return;
    }

    if (globals.debug & DBG_GUI)
       fprintf(stderr, "allocating list with %d pages\n", total_pages);

    init_pagelabels(0, total_pages);
    if (!PagelistInitialized) {
       xaw_create_pagelist();
       XtVaGetValues(LIST_WIDGET, XtNforeground, &foreground, XtNbackground, &background, NULL);
       m_page_gc.back = set_or_make_gc(NULL, GXcopy, background, foreground);
       m_page_gc.fore = set_or_make_gc(NULL, GXcopy, foreground, background);
       PagelistInitialized = True;
    }
#endif /* MOTIF */
    /* scroll to the current page if needed */
    maybe_scroll_pagelist(current_page, False);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void free_pagelabels ( void  ) [static]

Definition at line 1294 of file pagesel.c.

{
    int i;
    for (i = 0; page_info.page_labels != NULL && page_info.page_labels[i] != NULL; i++) {
       free(page_info.page_labels[i]);
    }
    free(page_info.page_labels);
    page_info.page_labels = NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_item_index ( Widget  w,
int  mouse_y 
) [static]

Definition at line 646 of file pagesel.c.

{
#ifdef MOTIF
    return XmListYToPos(w, mouse_y);
#else
    Dimension row_height, internal_height;
    
    xaw_get_row_height(w, &row_height, &internal_height);
    return (mouse_y - internal_height) / row_height + MOTIF_IDX_OFFSET;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_page_size ( void  ) [static]

Definition at line 457 of file pagesel.c.

{
    int offset = 0;
    int min_page = 0;
    int max_page = 0;
    int min_pageno_len = 0;
    int max_pageno_len = 0;
    int i;

    if (globals.dvi_file.bak_fp == NULL)
       return 0;
    
    for (i = 0; i < total_pages; i++) {
       max_page = MAX(page_info.index[i].number, max_page);
       min_page = MIN(page_info.index[i].number, min_page);
    }

    if (min_page >= 0) {
       offset = 0;   /* plus symbol is hidden */
    } else {
       offset = 1;   /* offset for minus symbol */
       min_page = -min_page;
    }
    for (min_pageno_len = offset; min_page > 0;
        min_page /= 10, min_pageno_len++);

    if (max_page >= 0) {
       offset = 0;   /* plus symbol is hidden */
    } else {
       offset = 1;   /* offset for minus symbol */
       max_page = -max_page;
    }
    for (max_pageno_len = offset; max_page > 0;
        max_page /= 10, max_pageno_len++);

    return MAX(min_pageno_len, max_pageno_len);
  /* Plus 1 for minus symbol */
}

Here is the caller graph for this function:

void handle_destroy_pagelist ( Widget  w,
XtPointer  client_data,
XtPointer  call_data 
)

Definition at line 1216 of file pagesel.c.

{
    UNUSED(w);
    UNUSED(client_data);
    UNUSED(call_data);
    
    if (viewport != NULL) {
       XtDestroyWidget(viewport);
       viewport = NULL;
       LIST_WIDGET = NULL;
    }
    PagelistInitialized = False;
}

Here is the caller graph for this function:

Definition at line 1193 of file pagesel.c.

{
    /* TODO: the following will mess up the geometry of the list
       (doesn't increase height, and incrementally decreases width):
    if (list_widget) {
       Dimension height;
       --- without the (un)manage, I get an X Error:
       XtMakeGeometryRequest - parent has no geometry manager
       ---
       XtUnmanageChild(viewport);
       XtUnmanageChild(LIST_WIDGET);
       XtVaGetValues(globals.widgets.clip_widget, XtNheight, &height, NULL);
       height -= resource.btn_top_spacing + resource.btn_border_width + global_y_pos;
       XtVaSetValues(viewport, XtNheight, height, NULL);
       XtManageChild(LIST_WIDGET);
        XtManageChild(viewport);
    }
    ... so we use brute force instead: */
    handle_destroy_pagelist(LIST_WIDGET, NULL, NULL);
    create_pagelist();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void highlight_page_callback ( Widget  widget,
XtPointer  data,
XEvent *  event,
Boolean cont 
) [static]

Definition at line 761 of file pagesel.c.

{
    int curr_idx = get_item_index(widget, event->xmotion.y);
    Position x, y;
    Dimension w, h;
    static int idx_bak = -1;
    
    UNUSED(data);
    UNUSED(cont);

    switch(event->xany.type) {
    case ButtonPress:
    case ButtonRelease:
    case MotionNotify:
       /* might need to un-highlight previous one */
       if (idx_bak >= 0 && idx_bak != curr_idx
           && my_list_pos_to_bounds(widget, idx_bak, &x, &y, &w, &h)) {
/*         fprintf(stderr, "index: %d, %d, h: %d, w: %d\n", x, y, h, w); */
           refresh_highlight_marker(widget, m_page_gc.back, x, y, w, h);
#if REDRAW_CURRENT_MARKER_HACK
           xaw_maybe_redraw_highlight(curr_idx);
#endif
       }
       idx_bak = curr_idx;
       /* redraw unless out of bounds (when pagelist is shorter than view area) */
       if (my_list_pos_to_bounds(widget, curr_idx, &x, &y, &w, &h)) {
           refresh_highlight_marker(widget, m_page_gc.fore, x, y, w, h);
#if REDRAW_CURRENT_MARKER_HACK
           g_current_highlighted = curr_idx;
#endif
       }
       break;
    case LeaveNotify:
       /* this might look overly complicated, but is neccessary to cover all
          cases of 1-pixel movement up/down before leaving the list, or no
          movement at all before leaving it. */
       if ((idx_bak >= 0 && idx_bak != curr_idx && my_list_pos_to_bounds(widget, idx_bak, &x, &y, &w, &h))
           || my_list_pos_to_bounds(widget, curr_idx, &x, &y, &w, &h)) {
           refresh_highlight_marker(widget, m_page_gc.back, x, y, w, h);
#if REDRAW_CURRENT_MARKER_HACK
           xaw_maybe_redraw_highlight(curr_idx);
#endif
       }
       break;
    default:
       break;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void init_pagelabels ( int  start,
int  end 
) [static]

Definition at line 849 of file pagesel.c.

{
    int i;
    char s[PAGENUMLEN];
#if 0
    fprintf(stderr, "===== init_pagelabels from %d to %d\n", start, end);
#endif
    ASSERT(end < (int)page_info.index_size, "");
    
    page_info.page_labels = xrealloc(page_info.page_labels, sizeof *(page_info.page_labels) * (end + 2));
    for (i = start; i < end; i++) {
       if (page_info.index[i].marked)
           sprintf(s, "* %*d  ", get_page_size(),
                  resource.use_tex_pages ? page_info.index[i].number : i + 1);
       else
           sprintf(s, "  %*d  ", get_page_size(),
                  resource.use_tex_pages ? page_info.index[i].number : i + 1);

       page_info.page_labels[i] = xstrdup(s);
    }
    page_info.page_labels[i] = NULL; /* terminate - important for creating the widget. */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void internal_process_button2 ( Widget  widget,
XEvent *  event 
) [static]

Definition at line 1433 of file pagesel.c.

{
    int curr_idx;
    static int prev_idx = 0;
#ifndef MOTIF
    static int actual_idx = -2;
#endif
    static int top_visible = 0, bot_visible = 0;
    static int prev_y = 0, curr_y = 0;
    static saveCmdT prev_cmd = 0;  /* previous command (CLICK/SCROLL_UP/SCROLL_DOWN) */
    static saveCmdT curr_cmd = 0;  /* current command (CLICK/SCROLL_UP/SCROLL_DOWN) */
    static saveCmdT bak_cmd = 0;   /* last command that started inside the pagelist (CLICK/SCROLL_UP/SCROLL_DOWN) */
    static Boolean change_scroll_direction = False;
    
    switch(event->xany.type) {
    case ButtonPress:
       prev_y = event->xbutton.y;
       prev_idx = curr_idx = get_item_index(widget, prev_y);
#ifdef MOTIF
       top_visible = xm_get_top_visible(1);
       bot_visible = xm_get_bottom_visible(top_visible);
#endif
       toggle_label(widget, curr_idx - 1, True);
       prev_cmd = CLICK;
#ifdef MOTIF
       xm_maybe_scroll_pagelist(curr_idx - 1, CLICK, &top_visible, &bot_visible);
#else
       actual_idx = xaw_maybe_scroll_pagelist(curr_idx, False, actual_idx);
#endif
       break;
    case ButtonRelease:
       prev_cmd = CLICK;
       break;
    case MotionNotify:
       curr_y = (int)event->xmotion.y;
       curr_idx = get_item_index(widget, event->xmotion.y);
#ifndef MOTIF
       if (actual_idx > 0) {
           curr_idx = actual_idx;
       }
#endif

       if (curr_y < prev_y)
           curr_cmd = SCROLL_UP;
       else if (curr_y > prev_y)
           curr_cmd = SCROLL_DOWN;
       prev_y = curr_y;

       if (prev_cmd != CLICK && curr_cmd != prev_cmd)
           change_scroll_direction = True;

       if ((curr_idx != prev_idx && !change_scroll_direction)
           || (change_scroll_direction
              /* last or first visible are always spared, unless they are really
                 the first or last page; this way, always 1 more page is visible
                 than is currently marked/selected
              */
              && !(curr_idx == top_visible) && !(curr_idx == bot_visible))) {
           if (curr_idx <= 0) {
              /* When user has scrolled off, mark this by setting curr_idx to 1 more or less
                 than the pagelist has so that the last/first page don't oscillate between
                 marked/unmarked state when user continues to scroll.
                 Also, we continue scrolling as long as user drags in the same direction as
                 the last `real' scrolling event (saved as bak_cmd).
              */
              if (curr_cmd == SCROLL_DOWN && bak_cmd == SCROLL_DOWN && prev_idx <= total_pages) {
                  curr_idx = prev_idx + 1;
              }
              else if (curr_cmd == SCROLL_UP && bak_cmd == SCROLL_UP && prev_idx > 0) {
                  curr_idx = prev_idx - 1;
              }
           }


           if (curr_idx > 0 && curr_idx <= total_pages) {
              toggle_label(widget, curr_idx - 1, True);
#ifdef MOTIF
              xm_maybe_scroll_pagelist(curr_idx - 1, curr_cmd, &top_visible, &bot_visible);
#else
              actual_idx = xaw_maybe_scroll_pagelist(curr_idx, False, actual_idx);
#endif
              prev_idx = curr_idx;
              bak_cmd = curr_cmd;
              change_scroll_direction = False;
           }
           else {
#ifndef MOTIF
              if (curr_idx > total_pages)
                  actual_idx = -2;
              else
                  actual_idx = xaw_maybe_scroll_pagelist(curr_idx, False, actual_idx);
#endif
           }
           prev_cmd = curr_cmd;
       }
       break;
    default:
       break;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1535 of file pagesel.c.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1151 of file pagesel.c.

{
    
    int i;

    if (arg < 0) { /* mark all */
       for (i = 0; i < total_pages; i++) {
           ASSERT(i < (int)page_info.index_size, "");
/*         ensure_labelinfo_size(i); */
           if (!page_info.index[i].marked) {
              toggle_label(LIST_WIDGET, i, False);
           }
       }
    }
    else if (arg == 0) { /* unmark all */
       for (i = 0; i < total_pages; i++) {
           ASSERT(i < (int)page_info.index_size, "");
/*         ensure_labelinfo_size(i); */
           if (page_info.index[i].marked) {
              toggle_label(LIST_WIDGET, i, False);
           }
       }
    }
    else { /* toggle odd/even */
       if (arg == 2) /* toggle even */
           arg = 0;
       for (i = 0; i < total_pages; i++) {
           if ((i + 1) % 2 == arg) {
              toggle_label(LIST_WIDGET, i, False);
           }
       }
    }
    /* TODO: update widget once for Motif as well! */
#ifndef MOTIF
    xaw_update_list();
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void mark_page_callback ( Widget  w,
XtPointer  data,
XEvent *  event,
Boolean cont 
) [static]

Definition at line 982 of file pagesel.c.

{
    UNUSED(data);
    UNUSED(cont);

    /* moving button2 generates MotionNotify events for button0 */
    if (event->type == MotionNotify || event->xbutton.button == Button2)
       internal_process_button2(w, event);

    if (pageinfo_have_marked_pages()) {
       notify_print_dialog_have_marked(True);
    }
    else {
       notify_print_dialog_have_marked(False);
    }

}

Here is the call graph for this function:

Here is the caller graph for this function:

void maybe_scroll_pagelist ( int  newpage,
Boolean  force_recenter 
)

Definition at line 1343 of file pagesel.c.

{
#ifdef MOTIF
    int top_visible, bot_visible;
    UNUSED(force_recenter);
#endif

    if (
#ifndef MOTIF
       (resource.expert_mode & XPRT_SHOW_BUTTONS) == 0 ||
#endif
       !XtIsRealized(globals.widgets.top_level))
       return;

#ifdef MOTIF
    XmListSelectPos(LIST_WIDGET, newpage + MOTIF_IDX_OFFSET, False);

    top_visible = xm_get_top_visible(1);
    bot_visible = xm_get_bottom_visible(top_visible);

    xm_maybe_scroll_pagelist(newpage, CLICK, &top_visible, &bot_visible);
#if HAVE_XPM
    tb_check_navigation_sensitivity(current_page);
#endif
#else

    if (LIST_WIDGET == NULL)
       return;
    
    (void)xaw_maybe_scroll_pagelist(newpage + 1, force_recenter, 0);

    XawListHighlight(LIST_WIDGET, newpage);
#if REDRAW_CURRENT_MARKER_HACK
    /* if the XawListHighlight happens adjacent to the page that was
       last highlighted with our home-made `current selected'
       rectangle, it might overdraw that rectangle. In this case,
       restore it:
     */
    xaw_maybe_redraw_current_marker(newpage);
#endif
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Boolean my_list_pos_to_bounds ( Widget  widget,
int  idx,
Position *  x,
Position *  y,
Dimension w,
Dimension h 
) [static]

Definition at line 661 of file pagesel.c.

{
#ifdef MOTIF
    Position x1, y1;
    Dimension w1, h1;
    if (XmListPosToBounds(widget, idx, &x1, &y1, &w1, &h1)) {
       *x = x1;
       *y = y1;
       *w = w1;
       *h = h1;
       return True;
    }
    return False;
#else
    Dimension row_height, internal_height;
    /* FIXME: Remove this hard-coded offset! */
    const int X_OFFSET = 9;
    const int RULE_OFFSET = 2;

    if (idx <= 0 || idx > total_pages) {
       return False;
    }

    if (viewport != NULL && XtIsRealized(viewport))
       XtVaGetValues(viewport, XtNx, x, NULL);
    xaw_get_row_height(widget, &row_height, &internal_height);
    XtVaGetValues(widget, XtNwidth, w, NULL);
    
    *x -= X_OFFSET;
    *y = row_height * idx + internal_height - row_height - 1;
    *w -= RULE_OFFSET;
    *h = row_height + RULE_OFFSET;
    
    return True;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pageinfo_allocate ( int  total_pages)

Definition at line 358 of file pagesel.c.

{
    int i;
    page_info.index = xmalloc(total_pages * sizeof *(page_info.index));
    for (i = 0; i < total_pages; i++) {
       page_info.index[i].marked = False;
    }
    /* following initializations are handled by the respective Motif/Xaw functions */
    page_info.page_labels = NULL;
    page_info.index_size = total_pages;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 376 of file pagesel.c.

{
    free(page_info.index);
    page_info.index_size = 0;
    page_info.index = NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 333 of file pagesel.c.

{
    size_t i;
    for (i = 0; i < page_info.index_size - 1; i++) {
       if (number == page_info.index[i].number)
           return i;
    }
    return -1;
}

Here is the caller graph for this function:

Definition at line 325 of file pagesel.c.

{
    ASSERT(page >= 0 && page < (int)page_info.index_size, "Page number out of range");
    return page_info.index[page].number;
}

Here is the caller graph for this function:

long pageinfo_get_offset ( int  page)

Definition at line 260 of file pagesel.c.

{
    ASSERT(page >= 0 && page < (int)page_info.index_size, "Page number out of range");
/*      fprintf(stderr, "offset for page %d is %ld\n", page, page_info.index[page].offset); */
    return page_info.index[page].offset;
}

Here is the caller graph for this function:

unsigned int pageinfo_get_page_height ( int  page)

Definition at line 276 of file pagesel.c.

{
    ASSERT(page >= 0 && page < (int)page_info.index_size, "Page number out of range");
    return page_info.index[page].ph;
}

Here is the caller graph for this function:

unsigned int pageinfo_get_page_width ( int  page)

Definition at line 269 of file pagesel.c.

{
    ASSERT(page >= 0 && page < (int)page_info.index_size, "Page number out of range");
    return page_info.index[page].pw;
}

Here is the caller graph for this function:

unsigned int pageinfo_get_window_height ( int  page)

Definition at line 290 of file pagesel.c.

{
    ASSERT(page >= 0 && page < (int)page_info.index_size, "Page number out of range");
    return page_info.index[page].wh;
}

Here is the caller graph for this function:

unsigned int pageinfo_get_window_width ( int  page)

Definition at line 283 of file pagesel.c.

{
    ASSERT(page >= 0 && page < (int)page_info.index_size, "Page number out of range");
    return page_info.index[page].ww;
}

Here is the caller graph for this function:

Definition at line 429 of file pagesel.c.

{
    int i;
    for (i = 0; i < total_pages; i++) {
       if (page_info.index[i].marked) {
           return True;
       }
    }
    return False;
}

Here is the caller graph for this function:

Definition at line 443 of file pagesel.c.

{
    ASSERT(i <= (int)page_info.index_size, "");
    return page_info.index[i].marked;
}

Here is the caller graph for this function:

void pageinfo_set_number ( int  index,
int  number 
)

Definition at line 351 of file pagesel.c.

{
    ASSERT(index >= 0 && index < (int)page_info.index_size, "");
    page_info.index[index].number = number;
}

Here is the caller graph for this function:

void pageinfo_set_offset ( int  index,
long  offset 
)

Definition at line 344 of file pagesel.c.

{
    ASSERT(index >= 0 && index < (int)page_info.index_size, "");
    page_info.index[index].offset = offset;
}

Here is the caller graph for this function:

void pageinfo_set_page_height ( int  page,
unsigned int  height 
)

Definition at line 304 of file pagesel.c.

{
    ASSERT(page >= 0 && page < (int)page_info.index_size, "Page number out of range");
    page_info.index[page].ph = height;
}

Here is the caller graph for this function:

void pageinfo_set_page_width ( int  page,
unsigned int  width 
)

Definition at line 297 of file pagesel.c.

{
    ASSERT(page >= 0 && page < (int)page_info.index_size, "Page number out of range");
    page_info.index[page].pw = width;
}

Here is the caller graph for this function:

void pageinfo_set_window_height ( int  page,
unsigned int  height 
)

Definition at line 318 of file pagesel.c.

{
    ASSERT(page >= 0 && page < (int)page_info.index_size, "Page number out of range");
    page_info.index[page].wh = height;
}

Here is the caller graph for this function:

void pageinfo_set_window_width ( int  page,
unsigned int  width 
)

Definition at line 311 of file pagesel.c.

{
    ASSERT(page >= 0 && page < (int)page_info.index_size, "Page number out of range");
    page_info.index[page].ww = width;
}

Here is the caller graph for this function:

static void refresh_highlight_marker ( Widget  widget,
GC  gc,
Position  x,
Position  y,
Dimension  w,
Dimension  h 
) [static]

Definition at line 502 of file pagesel.c.

{
    XDrawRectangle(XtDisplay(widget), XtWindow(widget), gc,
#ifdef MOTIF
                 x + 1, y + 1, w - 3, h - 3
#else
                 x + 2, y, w - 1, h - 1
#endif
                 );
}

Here is the caller graph for this function:

void refresh_pagelist ( int  newsize,
int  newpage 
)

Definition at line 1307 of file pagesel.c.

{
    if (
#ifndef MOTIF
       (resource.expert_mode & XPRT_SHOW_BUTTONS) == 0 ||
#endif
       !XtIsRealized(globals.widgets.top_level))
       return;

#ifdef DEBUG
    fprintf(stderr, "=== refresh_pagelist: newsize %d, newpage %d\n", newsize, newpage);
#endif
#ifdef MOTIF
/*     items = xrealloc(items, sizeof *items * (newsize + 2)); */
    init_pagelabels(0, newsize);
    xm_set_page_labels();
#else /* MOTIF */
    if ((resource.expert_mode & XPRT_SHOW_BUTTONS) == 0)
       return;

    /* FIXME - is this really neccessary?? The alternative:
          XawListChange(LIST_WIDGET, page_info.page_labels, newsize, 0, True);
       has problems when freeing the page labels afterwards.
    */
    handle_destroy_pagelist(LIST_WIDGET, NULL, NULL);

    free_pagelabels();
    init_pagelabels(0, newsize);

    xaw_create_pagelist();
#endif /* MOTIF */
    /* `True' since the pagelist is newly created */
    maybe_scroll_pagelist(newpage, True);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void select_page_callback ( Widget  w,
XtPointer  closure,
XtPointer  call_data 
) [static]

Definition at line 815 of file pagesel.c.

{
#ifdef MOTIF
    XmListCallbackStruct *cbs = (XmListCallbackStruct *) call_data;
    int new = cbs->item_position;

    UNUSED(w);
    UNUSED(closure);

    maybe_scroll_pagelist(new - MOTIF_IDX_OFFSET, False);
    page_history_insert(new - MOTIF_IDX_OFFSET);
    goto_page(new - MOTIF_IDX_OFFSET, resource.keep_flag ? NULL : home, False);
#else
    XawListReturnStruct *item = (XawListReturnStruct *) call_data;
    int new = item->list_index;

    UNUSED(w);
    UNUSED(closure);

    if (globals.debug & DBG_EVENT)
       fprintf(stderr, "got: button-1 for `%d'\n", new);

#if 0
    fprintf(stderr, "select page: %d\n", new);
#endif
    maybe_scroll_pagelist(new, False);
    page_history_insert(new);
    goto_page(new, resource.keep_flag ? NULL : home, False);
#endif
    search_signal_page_changed();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void toggle_label ( Widget  widget,
int  idx,
Boolean  update 
) [static]

Definition at line 1136 of file pagesel.c.

{
    if (idx >= total_pages)
       return;
    ASSERT(idx < total_pages, "");
    ASSERT(idx >= 0, "");
#ifdef MOTIF
    xm_toggle_label(widget, idx, update);
#else
    xaw_toggle_label(widget, idx, update);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void wheel_scroll_list_callback ( Widget  widget,
XtPointer  data,
XEvent *  event,
Boolean cont 
) [static]

Definition at line 703 of file pagesel.c.

{
    int button = event->xbutton.button;

    UNUSED(widget);
    UNUSED(data);
    UNUSED(cont);

    if (event->xany.type == ButtonPress && (button == 4 || button == 5)) {
#if SCROLL_LIST_SCROLLBAR
       Widget vert = XtNameToWidget(viewport, "vertical");
       static Dimension row_height = 0, dummy = 0;
       int diff_y = 0;

       if (row_height == 0)
           xaw_get_row_height(LIST_WIDGET, &row_height, &dummy);
              
       if (vert == NULL) {
           XDVI_WARNING((stderr, "Couldn't get name of pagelist viewport widget!"));
           return;
       }
       if (button == 5) {
           diff_y = row_height;
       }
       else {
           diff_y = -row_height;
       }
       XtCallCallbacks(vert, XtNscrollProc, (XtPointer)diff_y);
#else
       int pageno = current_page;
       if (button == 5) {
           if (current_page >= total_pages - 1) {
              XBell(DISP, 0);
              statusline_print(STATUS_SHORT, "Last page of DVI file");
              return;
           }
           pageno++;
       }
       else {
           if (current_page == 0) {
              XBell(DISP, 0);
              statusline_print(STATUS_SHORT, "First page of DVI file");
              return;
           }
           pageno--;
       }
       goto_page(check_goto_page(pageno), resource.keep_flag ? NULL : home, False);
       search_signal_page_changed();
#endif
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void xaw_create_pagelist_widgets ( Dimension  height,
Dimension  width,
Position  y,
Widget  parent 
)

Definition at line 1001 of file pagesel.c.

{
    viewport = XtVaCreateWidget("viewport",
                            viewportWidgetClass, parent,
                            XtNallowVert, True,
                            /* this is not related to the scroll bar: */
                            /* XtNforceBars, True, */
                            XtNx, resource.btn_side_spacing,
                            XtNy, y,
                            XtNheight, height,
                            XtNwidth, width,
                            NULL);
    LIST_WIDGET = XtVaCreateWidget("list",
                               listWidgetClass, viewport,
                               XtNlist, page_info.page_labels,
                               XtNdefaultColumns, 1,
                               XtNforceColumns, True,
                               XtNx, 10,
                               XtNy, 10,
                               XtNheight, height,
                               XtNwidth, width - 10,
                               XtNlongest, LONGESTPAGENUM,
                               XtNverticalList, True,
                               NULL);
    XtManageChild(LIST_WIDGET);
    XtManageChild(viewport);
    XtAddCallback(LIST_WIDGET, XtNcallback, select_page_callback,
                (XtPointer) NULL);
    /* for scrolling the list */
    XtAddCallback(viewport, XtNreportCallback, xaw_SendReportProc,
                (XtPointer) NULL);
    XtAddEventHandler(LIST_WIDGET,
                    ButtonPressMask | ButtonReleaseMask | Button2MotionMask,
                    False, mark_page_callback, (XtPointer)NULL);

    if (resource.pagelist_highlight_current)
       XtAddEventHandler(LIST_WIDGET,
                       ButtonPressMask | ButtonReleaseMask | PointerMotionMask | LeaveWindowMask,
                       False, highlight_page_callback, (XtPointer)NULL);

    
    XtAddEventHandler(LIST_WIDGET, ButtonPressMask | ButtonReleaseMask,
                    False, wheel_scroll_list_callback, (XtPointer)NULL);
    
    
    XtAddEventHandler(LIST_WIDGET,
                    /* FIXME: We should add PointerMotionMask here, but handling PointerMotionMask
                      currently doesn't work with the Xaw list widget: the auto-scrolling code doesn't
                      realize when the mouse direction of the pointer movement changes, and continues
                      to scroll into the same direction. This will be rather annoying for users, so
                      we disabled PointerMotionMask for the time being.
                    */
                    ButtonReleaseMask /* | PointerMotionMask */ | Button1MotionMask,
                    False, xaw_drag_page_callback, (XtPointer)NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void xaw_drag_page_callback ( Widget  widget,
XtPointer  data,
XEvent *  event,
Boolean cont 
) [static]

Definition at line 595 of file pagesel.c.

{
    int y, idx, actual_idx = 0;

    UNUSED(data);
    UNUSED(cont);
    
    if (event->xany.type == ButtonPress || ((event->xbutton.state & Button1Mask) == 0))
       return;
    if (event->xany.type == MotionNotify)
       y = (int)event->xmotion.y;
    else
       y = (int)event->xbutton.y;

    idx = get_item_index(widget, y);
    
    if (idx <= 0) {
       idx = 1;
    }
    else if (idx > total_pages) {
       idx = total_pages;
    }

    actual_idx = xaw_maybe_scroll_pagelist(idx, False, actual_idx);
    XawListHighlight(LIST_WIDGET, idx - MOTIF_IDX_OFFSET);

/*      if (event->xany.type == ButtonRelease) { */
/*     fprintf(stderr, "1\n"); */
/*     page_history_insert(idx - MOTIF_IDX_OFFSET); */
/*     goto_page(idx - MOTIF_IDX_OFFSET, resource.keep_flag ? NULL : home); */
/*     search_signal_page_changed(); */
/*      } */
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 577 of file pagesel.c.

{
    Widget w;
    XFontStruct *font;

    w = XtVaCreateWidget("list", listWidgetClass, globals.widgets.top_level, NULL);
    XtVaGetValues(w, XtNfont, &font, NULL);
    XtDestroyWidget(w);

    /* have space for max. pageno + space + current-marker,
       plus a few pixels for right margin */
    return (get_page_size() + 2) * get_avg_font_width(font) + 6;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void xaw_get_row_height ( Widget  w,
Dimension row_height,
Dimension internal_h 
) [static]

Definition at line 556 of file pagesel.c.

{
    Dimension row_space;
    XFontStruct *font;
    Arg arglist[5];
    int i = 0;

    if (w == NULL || !XtIsRealized(w))
       return;

    XtSetArg(arglist[i], XtNfont, &font); ++i;
    XtSetArg(arglist[i], XtNrowSpacing, &row_space); ++i;
    XtSetArg(arglist[i], XtNinternalHeight, internal_h); i++;
    XtGetValues(w, arglist, i);
    *row_height = font->max_bounds.ascent + font->max_bounds.descent + row_space;
}

Here is the caller graph for this function:

static void xaw_maybe_redraw_current_marker ( int  idx) [static]

Definition at line 221 of file pagesel.c.

{
    Position x, y;
    Dimension w, h;

/*     fprintf(stderr, "idx: %d, high: %d; diff: %d\n", idx + MOTIF_IDX_OFFSET, g_current_highlighted, */
/*         abs(idx + MOTIF_IDX_OFFSET - g_current_highlighted)); */
    if (abs((idx + MOTIF_IDX_OFFSET) - g_current_highlighted) <= 2
       && my_list_pos_to_bounds(LIST_WIDGET, g_current_highlighted, &x, &y, &w, &h)) {
       refresh_highlight_marker(LIST_WIDGET, m_page_gc.fore, x, y, w, h);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void xaw_maybe_redraw_highlight ( int  idx) [static]

Definition at line 202 of file pagesel.c.

{
    XawListReturnStruct *ret;
    int high;
    
    if (LIST_WIDGET == NULL)
       return;
    
    ret = XawListShowCurrent(LIST_WIDGET);
    high = ret->list_index;
    if (high != XAW_LIST_NONE && abs(idx - (high + MOTIF_IDX_OFFSET)) <= 2) {
       /* re-highlight it */
       XawListHighlight(LIST_WIDGET, high);
    }
    g_current_highlighted = -1;
}

Here is the caller graph for this function:

static int xaw_maybe_scroll_pagelist ( int  new_page,
Boolean  force_recenter,
int  old 
) [static]

Definition at line 1083 of file pagesel.c.

{
    Position x;
    Position y, new_y, bot_y;
    Dimension view_height, row_height, internal_height;
    /* Dimension clip_height; */
    /* static Widget list_clip = 0; */
    
    if (LIST_WIDGET == NULL || (resource.expert_mode & XPRT_SHOW_BUTTONS) == 0)
       return idx_bak;

/*     if (list_clip == 0) { */
/*     list_clip = XtNameToWidget(viewport, "clip"); */
/*     } */
/*     if (XtIsRealized(list_clip)) */
/*     XtVaGetValues(list_clip, XtNheight, &clip_height, XtNx, &cx, XtNy, &y1, NULL); */
    if (viewport != NULL && XtIsRealized(viewport))
       XtVaGetValues(viewport, XtNheight, &view_height, XtNx, &x, NULL);
/*     fprintf(stderr, "diff: %d, %d, %d, %d, %d\n", cx - x, clip_height, view_height, y1, (int)y2); */
    xaw_get_row_height(LIST_WIDGET, &row_height, &internal_height);
    y = row_height * new_page;

#if DEBUG
    fprintf(stderr, "###### xaw_maybe_scroll_pagelist: y %d, view_y %d, view_height %d, row_height %d, internal_height %d; actual %d\n",
           y, view_y, view_height, row_height, internal_height, idx_bak);
#endif
    /*FIXME: when page list is destroyed, view_y will be 0 until user scrolls page list */
    bot_y = view_y + view_height;
    if (force_recenter || ((y >= bot_y - row_height))) {
#if DEBUG
       fprintf(stderr, "scrolled below bottom; incrementing %d to %d\n", view_y, view_y + row_height);
#endif
       y += row_height;
       XawViewportSetCoordinates(viewport, x, y - view_height > 0 ? y - view_height : 0);
       return new_page + 1;
    }
    else if (force_recenter || ((y <= view_y + row_height + internal_height))) {
#if DEBUG
       fprintf(stderr, "scrolled over top; new_y: %d\n", y - row_height);
#endif
       new_y = y - 2 * row_height;
       XawViewportSetCoordinates(viewport, x, new_y);
       return new_page - 1;
    }
    /* not scrolled */
    return -2;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void xaw_SendReportProc ( Widget  w,
XtPointer  closure,
XtPointer  call_data 
) [static]

Definition at line 630 of file pagesel.c.

{
    XawPannerReport *rep = (XawPannerReport *) call_data;

    UNUSED(w);
    UNUSED(closure);
    
    view_y = rep->slider_y;
}

Here is the caller graph for this function:

static void xaw_toggle_label ( Widget  w,
int  idx,
Boolean  update 
) [static]

Definition at line 1058 of file pagesel.c.

{
    if (w == NULL)
       return;

/*     ensure_labelinfo_size(idx); */
    ASSERT(idx < (int)page_info.index_size, "");
    if (!page_info.index[idx].marked) {
/*     sprintf(toc[idx], "* %*d  ", get_page_size(), page_index[idx].number);  */
       sprintf(page_info.page_labels[idx], pageno_format, '*', get_page_size(),
              resource.use_tex_pages ? page_info.index[idx].number : idx + 1);
       page_info.index[idx].marked = True;
    }
    else {
       sprintf(page_info.page_labels[idx], pageno_format, ' ', get_page_size(),
              resource.use_tex_pages ? page_info.index[idx].number : idx + 1);
/*     sprintf(toc[idx], "  %*d  ", get_page_size(), page_index[idx].number);  */
       page_info.index[idx].marked = False;
    }
    
    if (update)
       xaw_update_list();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void xaw_update_list ( void  ) [static]

Definition at line 524 of file pagesel.c.

{
    static int pagelist_width = -1;
    static int total_pages_bak = -1;

    XawListReturnStruct *ret;
    int idx, button_width;
    
    if (pagelist_width == -1 || total_pages != total_pages_bak) {
       pagelist_width = xaw_get_pagelist_size();
       total_pages_bak = total_pages;
    }
    
    /* save selected item */
    ret = XawListShowCurrent(LIST_WIDGET);
    idx = ret->list_index;
    button_width = get_panel_width() - 2 * (resource.btn_side_spacing + resource.btn_border_width);
    /* delete and re-create list */
    ASSERT(total_pages <= (int)page_info.index_size, "");
    XawListChange(LIST_WIDGET, page_info.page_labels, 0,
                MAX(button_width, pagelist_width), False);
    /* restore selected item */
    if (idx != XAW_LIST_NONE) {
       XawListHighlight(LIST_WIDGET, idx);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

int g_current_highlighted = -1 [static]

Definition at line 198 of file pagesel.c.

Widget list_widget = NULL [static]

Definition at line 168 of file pagesel.c.

struct page_gc m_page_gc [static]
struct page_index_info [static]

Definition at line 256 of file pagesel.c.

Definition at line 1189 of file pagesel.c.

const char* const pageno_format = "%c %*d " [static]

Definition at line 172 of file pagesel.c.

Widget panel_widget
int view_y [static]

Definition at line 166 of file pagesel.c.

Widget viewport = NULL [static]

Definition at line 169 of file pagesel.c.