summaryrefslogtreecommitdiff
path: root/Build/source/texk/windvi/src-spec.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/windvi/src-spec.c')
-rw-r--r--Build/source/texk/windvi/src-spec.c1675
1 files changed, 0 insertions, 1675 deletions
diff --git a/Build/source/texk/windvi/src-spec.c b/Build/source/texk/windvi/src-spec.c
deleted file mode 100644
index cc45b8d4df6..00000000000
--- a/Build/source/texk/windvi/src-spec.c
+++ /dev/null
@@ -1,1675 +0,0 @@
-/************************************************************************
-src special support for xdvi(k) previewer
-written by S. Ulrich (ulrich@cis.uni-muenchen.de) 8/1999
-
-version 0.1a 1999/11/02
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-------------------------------------------------------------
-
-NOTES ON IMPLEMENTATION
-
-The basic idea is that there's a key that takes the user into `src
-special' mode: In this mode, the location of the specials on the page
-may optionally be indicated by little tick marks (indeed the list of
-specials is only built and maintained with this mode being active),
-and a convenient mouse/keyboard action will do a system() call with
-some editor command for the next special found. IMHO the advantages
-of such a special mode are: The user gets some visual feedback where
-the next click will take him (before he actually clicks somewhere),
-which is especially important if the insertion technique for the
-specials (on the TeX side) doesn't always produce predictable results;
-and the performance in `normal mode' isn't affected by the source
-specials (list handling, display stuff, and bugs ;).
-
-The method used here for evaluating the src specials is very simple:
-During the scan of the .dvi page, applicationDoSpecial will call
-src_eval_special which inserts the special just scanned into a
-lookup array (in case src specials mode is ON; see below) containing
-pointers to the horizontal lists of specials. The length of the
-array is dynamically allocated to page_h.
-
-While this data structure isn't terribly efficient because of the
-`gaps' in the y-coordinates (\lineskip), it fulfils the following
-two requirements which are important in our case:
-
-- sequential searching has to be possible in case the user clicks
- somewhere between two specials, i.e. the structure has to be
- order-preserving w.r.t. the coordinates on the page;
-
-- insertion should be fairly fast because redrawing the page
- will cause each special to be checked if it's already contained
- in the structure.
-
-(Note that for these reasons a hash table would probably not
-be better suited, because of the requirement of order-preserving
-and the `gaps' in the data.)
-
-This structure should work reasonably with any number of specials on
-the page; while it might be wasteful if only few (< 50) specials are
-used, it still works well with a large number of specials per page (it
-can handle even the pathological case where one special is used for
-each glyph on the page).
-
-To call the editor for a certain special, the x/y coordinates of the
-Xevent (mouse position) are handed to a function (src_find_special)
-that checks if there is a special just at those coordinates, and if
-not, it returns the next special on the current line or the first
-special in the next line (doing a search in the horizontal list).
-
-************************************************************************/
-
-#ifdef WIN32
-#define XDVIK
-#define XBell(a, b) MessageBeep(0xFFFFFFFF)
-#include <win32lib.h>
-#endif
-
-#ifdef XDVIK
-#include "xdvi-config.h"
-#include <kpathsea/c-fopen.h>
-#include <kpathsea/c-stat.h>
-#include <kpathsea/magstep.h>
-#include <kpathsea/tex-file.h>
-#include "dvi.h"
-#define XMALLOC(x,y) xmalloc(x)
-#define XREALLOC(x,y,z) xrealloc(x,y)
-
-#else /* non-k version of xdvi */
-
-#ifndef findrec
-#include "filf_app.h" /* application-related defs, etc. */
-#include "filefind.h"
-#endif /* findrec */
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-
-#define XMALLOC(x,y) xmalloc(x,y) /* has explanative string as 2nd argument */
-#define XREALLOC(x,y,z) xrealloc(x,y,z) /* has explanative string as 3rd argument */
-#endif /* XDVIK */
-
-#if !defined(WIN32)
-#include <unistd.h> /* added SU; have to test for availability !! */
-#endif
-
-#include <limits.h> /* added SU, for UINT_MAX, CHAR_BIT; have to test for availability !! */
-#include <ctype.h>
-
-#ifdef SRC_SPECIALS
-
-/*
- * Define a reasonable maximum length of the lookup array, because
- * the variable the value is usually taken from (page_h) might
- * overflow on a 32-bit architecture; here are examples for the size
- * of page_h at various font resolutions on my Intel Linux box:
- *
- * resolution page_h (at shrink factor 10)
- *
- * 600dpi 704
- * 1200dpi 1406
- * 2400dpi 2812
- * 2540dpi 2972
- * 3386dpi 6601
- * 5333dpi 429494415
- *
- * It's obvious that the last number results from an overflow at
- * that resolution, while all the other values are inside some reasonable
- * range << 100 000 (the worst case would be ten times the above values
- * for shrink factor 1). (This overflow also shows in the display:
- * the vertical scrollbar becomes very tiny, and the glyphs below a certain
- * y coordinate are not drawn.)
- *
- * Using (page_w * 2) instead could be a possible workaround, but that's
- * no clean solution either (src specials exceeding the y maximum would
- * still cause `out of bounds' errors in the `src_insert_into_array' function).
- *
- * So we simply define the maximum size of the lookup array to be 100 000.
- */
-
-#define ARR_MAX_SIZE 100000
-
-
-/* from special.c */
-#define xRESOLUTION (pixels_per_inch/shrink_factor)
-#define yRESOLUTION (pixels_per_inch/shrink_factor)
-
-#define src_is_smaller(x,y) ((x->y_coord < y->y_coord) || ((x->y_coord == y->y_coord) && (x->x_coord < y->x_coord)))
-#define src_is_equal(x,y) ((x->y_coord == y->y_coord) && (x->x_coord == y->x_coord))
-
-
-/* get the values of these from Xresources or command-line options */
-
-#define src_specialFormat resource._src_specialFormat
-#define src_tickSize resource._src_tickSize
-
-/* kludgy check if magnifier is off; is this always defined/correct?? */
-#define MAGNIFIER_NOT_ACTIVE (mane.shrinkfactor == currwin.shrinkfactor)
-
-#define PRELIM_VERSION
-
-
-/* double-linked list structure for src specials
- *
- * Note: currently only the `next' pointer of the list is used;
- * so a single-linked list would also do. Not sure if we might not
- * need the `previous' pointer in the future, though.
- */
-
-struct SRC_special {
- char *filename; /* filename contained in the special */
- unsigned int lineno; /* line number contained in the special */
- int pageno; /* number of displayed page on which special is drawn */
- float pt_size;
- /*
- * pixel coordinates in xdvi display
- * (take the values of PXL_H, PXL_V; hence int)
- */
- int x_coord;
- int y_coord;
- /* pointers to next/previous elem in list */
- struct SRC_special *next_special;
- struct SRC_special *prev_special;
-};
-
-/*
- * structure to save specials that caused warnings,
- * used to display these warnings only once:
- */
-struct SRC_warn_special {
- char *src_string;
- struct SRC_warn_special *next_warn_special;
-};
-
-
-/*
- * A list of vertical positions of the specials on a page (indexes of
- * src_arr that point to a horizontal list). This is used to speed up
- * traversing src_arr to delete all non-NULL elements (inside the
- * src_delete_all_specials() routine): For deletion, only non-empty
- * positions will have to be looked at, which is generally much less
- * than the total number of index positions (because the former
- * correspond roughly to line numbers on the page); e.g., a src_arr of
- * length 879 (shrink 8 at 600dpi) will generally only have 30 to 40
- * entries.
- */
-
-struct SRC_vertical_list {
- unsigned int index;
- struct SRC_vertical_list *next_vertical;
-};
-
-#ifndef XDVIK
-
-static _Xconst char no_f_str_tex[] = "/%f";
-
-static struct findrec search_tex = {
- /* path1 */ NULL,
-#if CFGFILE
- /* envptr */ NULL,
-#endif
- /* path2 */ DEFAULT_HEADER_PATH,
- /* type */ "TeX file",
- /* fF_etc */ "fF",
- /* x_var_char */ 'f',
- /* n_var_opts */ 2,
- /* no_f_str */ no_f_str_tex,
- /* no_f_str_end */ no_f_str_tex + sizeof(no_f_str_tex) - 1,
- /* abs_str */ "%f",
-#ifdef PK_AND_GF
- /* no_f_str_flags */ F_FILE_USED,
- /* abs_str_flags */ F_FILE_USED,
- /* pk_opt_char */ 'f',
- /* pk_gf_addr */ NULL,
-#endif
- /* pct_s_str */ "%q//",
- {
- /* v.stephead */ NULL,
- /* v.pct_s_head */ NULL,
- /* v.pct_s_count */ 0,
- /* v.pct_s_atom */ NULL,
- /* v.rootp */ NULL,
- }
-};
-#endif /* not XDVIK */
-
-
-/*
- * maximum length of long int in octal representation; compare C FAQ.
- * CHAR_BIT is from limits.h (may we assume 8 if it's unavailable?) I
- * *think* the +2 is for rounding up the length to include the full
- * triad; the / 3 computes the length of the octal digit. The + 1 is
- * for the minus sign. Note that the value is the same for int as for
- * unsigned int, since there the minus sign might be taken by another
- * digit (the maximum value of unsigned being twice as much as the
- * maximum value for signed). How about the trailing `\n' ?
- */
-
-#define LONG_SIZE ((sizeof(long) * CHAR_BIT + 2) / 3 + 1)
-#define UINT_SIZE ((sizeof(int) * CHAR_BIT + 2) / 3 + 1)
-
-/* global variables */
-struct SRC_special *head_special = NULL;
-struct SRC_vertical_list *head_vertical = NULL;
-struct SRC_vertical_list *first_vertical = NULL;
-struct SRC_vertical_list *last_vertical = NULL;
-static Boolean greatest_smallest_notset = True;
-struct SRC_warn_special *head_warn_special = NULL;
-struct SRC_special *last_active_special = NULL;
-int save_shrinkfactor = 0;
-static Boolean specials_not_initialized = True;
-static Boolean src_arr_not_initialized = True;
-static int corr_fact;
-static struct stat statbuf;
-
-/*
- * A global array holding pointers to src special lists.
- * The array is implemented using pointers so that its
- * size can be set at run-time (inside src_initialize_array).
- * Throughout the program, this array will be treated as an
- * ordinary array, i.e. we'll write
- * src_arr[i]
- * instead of
- * *(src_arr+i)
- */
-struct SRC_special **src_arr;
-static unsigned int src_arr_len;
-
-
-
-
-
-/*
- ========================================================================
- Private Functions
- ========================================================================
-*/
-
-
-
-
-/*************************************************************************
- small helper function: print out the list of specials
- *************************************************************************/
-static void
-print_out_list(top)
- struct SRC_special *top;
-{
- struct SRC_special *curr;
- int j;
- for (curr = top, j=0; curr != NULL; curr = curr->next_special, j++) {
- Fprintf(stderr, "[%d] %s:%u (%d,%d)\n",
- j, curr->filename, curr->lineno, curr->x_coord, curr->y_coord);
- }
-
-}
-
-/* currently unused */
-static void
-print_out_warn_list()
-{
- struct SRC_warn_special *curr;
- int j;
- for (curr = head_warn_special, j=0; curr != NULL; curr = curr->next_warn_special, j++) {
- Fprintf(stderr, "%d: %s\n",
- j, curr->src_string);
- }
-
-}
-
-/*************************************************************************
- print out the list of specials in reverse order
- currently unused
- *************************************************************************/
-static void
-test_print_out_reversed_list()
-{
- struct SRC_special *curr;
- int j;
- for (curr = head_special, j=0; curr->next_special != NULL; curr = curr->next_special, j++) { ; }
- for (; curr != NULL; curr = curr->prev_special, j--) {
- Fprintf(stderr, "[%d] %s:%u (%d,%d)\n",
- j, curr->filename, curr->lineno, curr->x_coord, curr->y_coord);
- if (j > 500) {return;}
- }
-
-}
-
-/*************************************************************************
- A test to draw the entire background of the text in a certian height.
-*************************************************************************/
-static void
-test_draw_mark(x_coord, y_coord, pt_size, gc)
- int x_coord, y_coord;
- float pt_size;
- GC gc;
-{
-
- XFillRectangle(DISP, mane.win, gc, x_coord, y_coord - (int)(0.5 + pt_size),
- (int)(0.5 + pt_size * 2), (int)(0.5 + pt_size));
-}
-
-/*************************************************************************
- draw glyphs representing the specials on a page
- *************************************************************************/
-static void
-draw_src_glyph(x_coord, y_coord, gc)
- int x_coord, y_coord;
- GC gc;
-{
- /*
- * The height/width of the shapes we're going to draw.
- * Height/width have their `natural' meaning only for the rectangle.
- * For the equilateral triangle, height is the base of the triangle.
- * For the angles, height is the length of the lines, width is twice
- * the thickness of the lines.
- */
-
-#ifdef WIN32
- POINT point1, point2, point3;
- POINT triangle_points[3];
- extern int xCurrentScroll, yCurrentScroll;
-
- gc = foreGC; /* FIXME : not good !!! */
-
- x_coord -= xCurrentScroll;
- y_coord -= yCurrentScroll;
-
- switch (src_tickShape) {
- case 0: {
- /* rectangle */
- RECT r;
- r.left = x_coord;
- r.top = y_coord;
- r.right = r.left + src_tick_width/mane.shrinkfactor;
- r.bottom = r.top + src_tick_height/mane.shrinkfactor;
- /* FIXME: this is wrong !
- The use of foreGC / highGC / ruleGC should be sorted out ! */
- FillRect(gc, &r, foreBrush);
- }
- break;
- case 1:
- /* equilateral triangle */
- /*
- * Since XFillPolygon will be drawn with `CoordModePrevious', each point
- * will be specified relative to its predecessor.
- */
- /* top */
- point1.x = x_coord;
- point1.y = y_coord;
- /* lower left corner */
- point2.x = x_coord + (src_tick_height/shrink_factor)/2;
- point2.y = y_coord + src_tick_height/shrink_factor;
- /* lower right corner */
- point3.x = x_coord + src_tick_height/shrink_factor;
- point3.y = y_coord;
-
- triangle_points[0] = point1;
- triangle_points[1] = point2;
- triangle_points[2] = point3;
- Polygon(gc, triangle_points, 3);
- break;
- case 2:
- /*
- * angle: _|
- */
- XFillRectangle(DISP,
- mane.win,
- gc,
- x_coord - src_tick_height/mane.shrinkfactor + ((src_tick_width/2) / mane.shrinkfactor),
- y_coord,
- src_tick_height/mane.shrinkfactor, /* length */
- (src_tick_width/2)/mane.shrinkfactor /* height */
- );
- /* vertical line */
- XFillRectangle(DISP,
- mane.win,
- gc,
- x_coord,
- /*
- * increase height for (height/10) to compensate for optical error
- * that makes vertical lines appear shorter
- */
- y_coord - (src_tick_height/mane.shrinkfactor -
- (src_tick_width/mane.shrinkfactor/2)), /* */
-
- (src_tick_width/2)/mane.shrinkfactor, /* height */
- /* like before */
- src_tick_height/mane.shrinkfactor - (src_tick_width/mane.shrinkfactor/2)
-
- );
- break;
- case 3:
- /*
- * angle, rotated 180 degs: _
- * |
- */
- XFillRectangle(DISP,
- mane.win,
- gc,
- x_coord,
- y_coord,
- src_tick_height/mane.shrinkfactor,
- src_tick_width/mane.shrinkfactor/2
- );
- /* vertical line */
- XFillRectangle(DISP,
- mane.win,
- gc,
- x_coord,
- y_coord + src_tick_width/mane.shrinkfactor/2,
- src_tick_width/mane.shrinkfactor/2,
- src_tick_height/mane.shrinkfactor - src_tick_width/mane.shrinkfactor/2
- );
- break;
- case 4:
- /* Ellipse */
- {
- /* FIXME: this is wrong !
- The use of foreGC / highGC / ruleGC should be sorted out ! */
- Ellipse(gc, x_coord, y_coord,
- x_coord + src_tick_width/mane.shrinkfactor,
- y_coord + src_tick_height/mane.shrinkfactor);
- }
- break;
- }
-#else
- XPoint point1, point2, point3;
- XPoint triangle_points[3];
-
- /* used to have this initialization which required that height and width are constant:
- XPoint points[] = {
- {x, y},
- {((-height/shrink_factor)/2), (height/shrink_factor)},
- {(height/shrink_factor), 0}
- };
- */
-
- switch (src_tickShape) {
- case 0:
- /* rectangle */
- XFillRectangle(DISP, mane.win, gc, x_coord, y_coord,
- src_tick_width/mane.shrinkfactor, src_tick_height/mane.shrinkfactor);
- break;
- case 1:
- /* equilateral triangle */
- /*
- * Since XFillPolygon will be drawn with `CoordModePrevious', each point
- * will be specified relative to its predecessor.
- */
- /* top */
- point1.x = x_coord;
- point1.y = y_coord;
- /* lower left corner */
- point2.x = (-src_tick_height/shrink_factor)/2;
- point2.y = src_tick_height/shrink_factor;
- /* lower right corner */
- point3.x = src_tick_height/shrink_factor;
- point3.y = 0;
-
- triangle_points[0] = point1;
- triangle_points[1] = point2;
- triangle_points[2] = point3;
-
- XFillPolygon(DISP,
- mane.win,
- gc,
- triangle_points,
- (sizeof(triangle_points)/sizeof(XPoint)),
- Convex,
- CoordModePrevious);
- break;
- case 2:
- /*
- * angle: _|
- */
- /* horizontal line */
- XFillRectangle(DISP,
- mane.win,
- gc,
- x_coord - src_tick_height/mane.shrinkfactor + ((src_tick_width/2) / mane.shrinkfactor),
- y_coord,
- src_tick_height/mane.shrinkfactor, /* length */
- (src_tick_width/2)/mane.shrinkfactor /* height */
- );
- /* vertical line */
- XFillRectangle(DISP,
- mane.win,
- gc,
- x_coord,
- y_coord - (src_tick_height/mane.shrinkfactor - (src_tick_width/mane.shrinkfactor/2)),
- (src_tick_width/2)/mane.shrinkfactor, /* height */
- src_tick_height/mane.shrinkfactor - (src_tick_width/mane.shrinkfactor/2) /*length */
- );
- break;
- case 3:
- /*
- * angle, rotated 180 degs: _
- * |
- */
- /* horizontal line */
- XFillRectangle(DISP,
- mane.win,
- gc,
- x_coord,
- y_coord,
- src_tick_height/mane.shrinkfactor, /* length */
- src_tick_width/mane.shrinkfactor/2 /* height */
- );
- /* vertical line */
- XFillRectangle(DISP,
- mane.win,
- gc,
- x_coord,
- y_coord + src_tick_width/mane.shrinkfactor/2,
- src_tick_width/mane.shrinkfactor/2, /*height */
- src_tick_height/mane.shrinkfactor - src_tick_width/mane.shrinkfactor/2 /*length */
- );
- break;
- }
-#endif
-}
-
-
-/*************************************************************************
- check if string `my_string' occurs already in the SRC_warn_special list
- *************************************************************************/
-
-static Boolean
-occurs_in_warn_specials(my_string)
- char *my_string;
-{
- struct SRC_warn_special *curr;
- for (curr = head_warn_special; curr != NULL; curr = curr->next_warn_special) {
- if (strcmp(my_string, curr->src_string) == 0) { /* matched */
- return True;
- }
- }
- return False;
-}
-
-/*************************************************************************
- insert SRC_special `new' into list pointed to by *list, return
- pointer to head of the list. Assumes that the space for `new' and
- its field `filename' have been malloc-ed by the caller.
- *************************************************************************/
-
-static struct SRC_special *
-insert_into_src_specials(top, new)
- struct SRC_special *top, *new;
-{
- struct SRC_special *curr, *bak;
-
- if (top == NULL) { /* list empty */
- if (debug & DBG_SRC_SPECIALS) {
- Fprintf(stderr, "new is only elem in list\n");
- }
- new->next_special = NULL;
- new->prev_special = NULL;
- return new;
- }
- /* arrive here only if list not empty. */
- curr = top;
- bak = NULL;
-
- /*
- * advance in list while next item is `smaller' than new item,
- * eventually reaching the end of the list. bak is a save pointer
- * to the previous item.
- */
- while (curr != NULL && src_is_smaller(curr, new)) {
- bak = curr;
- curr = curr->next_special;
- }
-
- /* don't append elems already in the list; top is unchanged: */
- if (curr != NULL && src_is_equal(curr, new)) {
- free(new->filename);
- free(new);
- return top;
- }
-
- /*
- * now curr is NULL (end of list) or `bigger' item; bak is pointer to
- * the previous element (to NULL if we're still at the head of the list).
- * Use these to assign prev/next to new (doesn't matter if they are NULL):
- */
- new->next_special = curr;
- new->prev_special = bak;
- if(bak != NULL) {
- /*
- * we're not not at the head of list. Make `new' the successor of previous;
- * top is unchanged:
- */
- bak->next_special = new;
- }
- else {
- /* we're at the head of the list; `new' becomes new top: */
- top = new;
- }
- if(curr != NULL) {
- /*
- * we're not at the end of the list. Make `new' predecessor of next;
- * top is unchanged:
- */
- curr->prev_special = new;
- }
- /****
- if (debug & DBG_SRC_SPECIALS) {
- Fprintf(stderr, "List after insert:\n");
- print_out_list(top);
- }
- ****/
- return top;
-}
-
-// unused
-static struct SRC_special *
-delete_from_pages(top, page)
- struct SRC_special *top;
- int page;
-{
- struct SRC_special *curr, *tmp;
-
- /* loop throuhg list, deleting all elems with pageno == page */
- for (curr = top; curr != NULL; curr = tmp) {
- tmp = curr->next_special;
- if (curr->pageno == page) {
- if (curr == top) { /* delete from top */
- top = curr->next_special;
- if (top) {
- top->prev_special = NULL;
- }
- else {
- if (debug & DBG_SRC_SPECIALS) {
- Fprintf(stderr, "removing last elem in list\n");
- }
- }
- }
- else { /* delete from middle or end */
- curr->prev_special->next_special = curr->next_special;
- if (curr->next_special != NULL) { /* delete from middle */
- curr->next_special->prev_special = curr->prev_special;
- }
- }
- Fprintf(stderr, "Deleted %s:%u (%d,%d)\n", curr->filename, curr->lineno, curr->x_coord, curr->y_coord);
- free(curr->filename);
- free(curr);
- }
- /***
- if (debug & DBG_SRC_SPECIALS) {
- for (tmp = top, j=0; tmp != NULL; tmp = tmp->next_special, j++) {
- Fprintf(stderr, "Delete: [%d] %s:%u (%d,%d)\n", j, tmp->filename, tmp->lineno, tmp->x_coord, tmp->y_coord);
- }
- }
- ***/
- }
- return top;
-}
-
-// unused
-static struct SRC_special *
-delete_from_pages_2(top)
- struct SRC_special *top;
-{
- struct SRC_special *curr, *tmp;
-
- /* loop throuhg list, deleting all elems with pageno == page */
- for (curr = top; curr != NULL; curr = tmp) {
- tmp = curr->next_special;
- if (curr == top) { /* delete from top */
- top = curr->next_special;
- if (top) {
- top->prev_special = NULL;
- }
- else {
- if (debug & DBG_SRC_SPECIALS) {
- Fprintf(stderr, "removing last elem in list\n");
- }
- }
- }
- else { /* delete from middle or end */
- curr->prev_special->next_special = curr->next_special;
- if (curr->next_special != NULL) { /* delete from middle */
- curr->next_special->prev_special = curr->prev_special;
- }
- }
- Fprintf(stderr, "Deleted %s:%u (%d,%d)\n", curr->filename, curr->lineno, curr->x_coord, curr->y_coord);
- free(curr->filename);
- free(curr);
-
- /***
- if (debug & DBG_SRC_SPECIALS) {
- for (tmp = top, j=0; tmp != NULL; tmp = tmp->next_special, j++) {
- Fprintf(stderr, "Delete: [%d] %s:%u (%d,%d)\n", j, tmp->filename, tmp->lineno, tmp->x_coord, tmp->y_coord);
- }
- }
- ***/
- }
- return top;
-}
-
-// delete all specials in list pointed to by top.
-//static struct SRC_special *
-static void
-delete_special_list(top)
- struct SRC_special **top;
-{
- struct SRC_special *curr, *tmp;
-
- /* loop throuhg list, deleting all elems */
- for (curr = *top; curr != NULL; curr = tmp) {
- tmp = curr->next_special;
- // fprintf(stderr, "deleting %s:%d\n", curr->filename, curr->lineno);
- free(curr->filename);
- free(curr);
- /***
- if (debug & DBG_SRC_SPECIALS) {
- for (tmp = top, j=0; tmp != NULL; tmp = tmp->next_special, j++) {
- Fprintf(stderr, "Delete: [%d] %s:%u (%d,%d)\n", j, tmp->filename, tmp->lineno, tmp->x_coord, tmp->y_coord);
- }
- }
- ***/
- }
-}
-
-
-/*************************************************************************
- Print warning or error message (only once) if a special string doesn't
- conform to the current format selected. level = 0 is warning, level = 1
- is error.
-*************************************************************************/
-static void
-src_special_format_error(level, input_string, err_msg)
- int level;
- char *input_string, *err_msg;
-{
- int string_len;
- char *bad_src_string;
- struct SRC_warn_special *new_warn_special;
- static int have_mentioned_man_page = 0;
-
- if (!occurs_in_warn_specials(input_string)) {
- switch(level) {
- case 0:
- Fprintf(stderr, "\nWarning: src special \"%s\"%s\n", input_string, err_msg);
- break;
- case 1:
- Fprintf(stderr, "\nError: src special \"%s\"%s\n", input_string, err_msg);
- break;
- }
- if (have_mentioned_man_page == 0) {
- Fprintf(stderr, "(See the xdvi man page on \"SRC special format\" for more information)\n");
- have_mentioned_man_page++;
- }
- /* remember this special as warned about */
- string_len = strlen(input_string);
- bad_src_string = XMALLOC(string_len + 1, "remember bad special");
- Sprintf(bad_src_string, "%.*s", string_len, input_string);
- new_warn_special = XMALLOC(sizeof(struct SRC_warn_special), "warn special");
- new_warn_special->src_string = bad_src_string;
- /*
- * insert new_warn_special at begin of SRC_warn_special list.
- *
- * Note that this list is never free'd again!
- *
- * While this is probably what we want (ensuring the user will
- * never see the same warning twice, even after resizing/... the
- * page), this might eventually lead to space problems if there
- * are *many* warnings. But since this is a pathological case
- * anyway (and the user would probably turn specials off in this
- * case), I think we might leave it like that.
- */
- new_warn_special->next_warn_special = head_warn_special;
- head_warn_special = new_warn_special;
- }
-}
-
-/**********************************************************************
- Parse the special string pointed to by `input_string' and return
- pointer to a SRC_special element containing the necessary
- information, or NULL if parsing `input_string' failed.
- **********************************************************************/
-static struct SRC_special *
-src_parse_special_string(input_string, x, y)
- char *input_string;
- Position x, y;
-{
- struct SRC_special *new_special;
- char *my_filename, *my_lineno, *save_special;
- int filename_string_len = 0, lineno_string_len = 0;
- unsigned long numtest; /* for testing if line number fits into unsigned int */
- Boolean read_leading_garbage = False; /* true if we had to read over leading garbage */
- /*
- * preliminary stuff to account for various formats of the src specials.
- * 0 is: `<filename>:<lineno>'
- * 1 is: `<lineno> <filename>'
- * 2 is: `<lineno>[ ]*<filename>'
- *
- * where (0) has been used by myself for test purposes, (1) is used
- * by YAP, (2) (where there may be any (including 0) number of spaces
- * separating lineno and filename) is used by YAP and DVIWIN.
- * (note that if there are zero spaces, the filename mustn't start with
- * a digit).
- *
- * The current web2c patch uses (2), but in a safe way: it inserts a
- * space as separator iff the filename starts with a digit.
- *
- * So (1) is a special case of (2); you might use it if you want to enforce the
- * use of white-space as separator.
- *
- * I still have to find out which format the viewers/editors on some
- * (commercial) MAC implementations use.
- */
-
- new_special = XMALLOC(sizeof(struct SRC_special), "new special");
- save_special = input_string;
-
- switch(src_specialFormat) {
- case 0:
- /* this case is for testing only, so it doesn't contain many sanity checks that
- * have been included in the tests below.
- */
- if((my_lineno = rindex(input_string, ':')) == NULL) {
- src_special_format_error(1, input_string, " doesn't contain a `:' (skipped)");
- return NULL;
- }
-
- /* first char in my_lineno is now `:' - read over it: */
- my_lineno++;
- lineno_string_len = strlen(my_lineno);
- filename_string_len = strlen(input_string) - lineno_string_len - 1; /* - 1 for the `:' */
-
- my_filename = XMALLOC(filename_string_len + 1, "filename in special");
- (void) strncpy(my_filename, input_string, filename_string_len);
- my_filename[filename_string_len] = '\0';
- break;
-
- default: /* treat src_specialFormat == 1 and 2 simultaneously */
- /*
- * Delete everything that isn't a digit from the start of
- * input_string (including, eventually, minus signs etc.) Will
- * check below for read_leading_garbage and issue a warning in
- * this case (after fatal errors have been processed).
- */
- while(*input_string != '\0' && !isdigit(*input_string)) {
- input_string++;
- read_leading_garbage = True;
- }
- my_lineno = input_string;
- lineno_string_len = 0;
-
- if (src_specialFormat == 1) {
- /* read line number until finding a space: */
- while (*input_string != '\0' && *input_string != ' ') {
- input_string++;
- lineno_string_len++;
- }
- }
- else {
- while (*input_string != '\0' && isdigit(*input_string)) {
- input_string++;
- lineno_string_len++;
- }
- }
-
- /* did we read a line number? */
- if(lineno_string_len == 0) {
- src_special_format_error(1, save_special, " doesn't contain a digit (skipped)");
- return NULL;
- }
-
- if (src_specialFormat == 1) {
- /* read over single whitespace */
- if (*input_string != '\0' && *input_string == ' ') {
- input_string++;
- }
- else {
- src_special_format_error(1, save_special, " doesn't contain a space (skipped)");
- return NULL;
- }
- }
- else {
- /* read over any amount of whitespace */
- while (*input_string != '\0' && isspace(*input_string)) {
- input_string++;
- }
- }
-
- filename_string_len = strlen(input_string);
-
- /* is the remaining chunk of input_string empty? */
- if(filename_string_len == 0) {
- src_special_format_error(1, save_special, " contains only digits and no filename (skipped)");
- return NULL;
- }
-
- /* if everything else was OK, warn if special had contained leading garbage: */
- if (read_leading_garbage) {
- src_special_format_error(0, save_special, ": leading non-digits deleted");
- }
-
- /* finally, allocate and copy filename */
- my_filename = XMALLOC(filename_string_len + 1, "filename in special");
- (void) strncpy(my_filename, input_string, filename_string_len);
- my_filename[filename_string_len] = '\0';
- break;
- }
- new_special->filename = my_filename;
-
- /*
- * similar to atol(my_lineno), but converts to unsigned long int
- * and does additional error checking. First set errno to 0 so that
- * it won't contain the result of calls:
- */
- errno = 0;
- numtest = strtoul((my_lineno), (char **)NULL, 10);
- new_special->lineno = (unsigned int)numtest;
-
- /*
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- have to check for ERANGE availability (errno.h) !!
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- */
-
- /*
- * If number has been too long for unsigned long int (ERANGE),
- * it's definitely too long for unsigned int either.
- * If not, check if it is too long for unsigned int.
- * Note that the test for ERANGE isn't redundant, since on
- * Intel Linux UINT_MAX == ULONG_MAX.
- */
- if ((errno == ERANGE) || (numtest > UINT_MAX)) {
- Fprintf(stderr, "\nWarning: line number %s too long for data type \"unsigned int\";\nchopping to %u\n",
- my_lineno, new_special->lineno);
- }
- /*
- * If special is in a text line, currinf.fontp->pt_size
- * should contain the pt size of the font.
- */
- if (currinf.fontp != NULL) {
- // new_special->pt_size = pt_size;
- new_special->pt_size = currinf.fontp->pt_size;
- }
- else {
- /*
- * Assume some reasonable default value. Note that this is not
- * critical, since currinf.fontp == NULL means that the current
- * special doesn't occur in a text line at all
- * (but before all text on the current page).
- */
- new_special->pt_size = 12.0;
- }
- new_special->x_coord = x;
- new_special->y_coord = y;
- new_special->pageno = current_page;
-
- /***
- if (debug & DBG_SRC_SPECIALS) {
- Fprintf(stderr, "\n============ lineno: %u; filename: |%s|\n", new_special->lineno, input_string);
- }
- ***/
- return new_special;
-}
-
-
-/*************************************************************************
- Build up the editor command for the system call and perform the system
- call.
- Example format for emacs: emacsclient --no-wait +lineno filename
- *************************************************************************/
-
-//_Xconst char *kpse_pathname = ""; /* used to hold the expanded path name of the file in the special */
-char *kpse_pathname; /* used to hold the expanded path name of the file in the special */
-
-static void
-issue_src_editor_cmd(filename, lineno)
- char *filename;
- long lineno;
-{
- char *cmdstring;
-
- /*
- * Here's the very simple algorithm for finding the files contained
- * in the specials: First check if file is in current directory; if
- * so, open it. Else, use kpse_find_tex (special form of
- * kpse_find_file) if kpathsearch library is available, or the
- * `filefind' function from non-k xdvi to expand the path name.
- * This should nearly always succeed, even if the path may not be
- * exactly what you wanted ... however you'll get decent results when
- * calling xdvi from the same directory as LaTeX, which is (I hope ;)
- * quite common.
- */
- if (stat(filename, &statbuf) == 0) {
- if (debug & DBG_SRC_SPECIALS) {
- Fprintf(stderr, "Found file \"%s\" in current dir\n", filename);
- }
- kpse_pathname = filename;
- }
- else {
-#ifdef XDVIK
- /* make a kpathsea search for filename */
- if (debug & DBG_SRC_SPECIALS) {
- Fprintf(stderr, "file \"%s\" not found in cwd, trying kpathsea expansion\n", filename);
- }
- kpse_pathname = kpse_find_tex(filename);
- if (stat(kpse_pathname, &statbuf) != 0) {
- Fprintf(stderr, "Error: file `%s' not found, couldn't jump to special `%s:%ld'\n",
- filename, filename, lineno);
- return;
- }
- else {
- if (debug & DBG_SRC_SPECIALS) {
- Fprintf(stderr, "Found file: `%s'\n", kpse_pathname);
- }
- }
-#else /* XDVIK */
- /*
- * search for filename in $TEXINPUTS, using the filefind function from
- * non-k xdvi's filefind.c
- */
- if (debug & DBG_SRC_SPECIALS) {
- Fprintf(stderr, "file \"%s\" not found in cwd, trying TEXINPUTS\n", filename);
- }
- search_tex.path1 = getenv("TEXINPUTS");
-#if CFGFILE
- search_tex.envptr = ffgetenv("TEXINPUTS");
- if (search_tex.envptr != NULL && search_tex.envptr->value == NULL) {
- search_tex.envptr = NULL;
- }
-#endif /* CFGFILE */
- (void) filefind(filename, &search_tex, &kpse_pathname);
- if (stat(kpse_pathname, &statbuf) != 0) {
- Fprintf(stderr, "Error: file `%s' not found, couldn't jump to special `%s:%ld'\n",
- filename, filename, lineno);
- return;
- }
- else {
- if (debug & DBG_SRC_SPECIALS) {
- Fprintf(stderr, "Found file: `%s'\n", kpse_pathname);
- }
- }
-#endif /* XDVIK */
- }
- src_warn_outdated();
-
- /* now allocate space for the command string, and issue the editor command */
-
- /* + 1 is for `\n' */
- cmdstring = XMALLOC((unsigned)strlen(src_editorCommand) + (unsigned)strlen(kpse_pathname) + LONG_SIZE + 1,
- "editor command string");
- if (src_EditorCmd_filename_first) { /* set inside src_get_settings, called by main() */
- Sprintf(cmdstring, src_editorCommand, kpse_pathname, lineno);
- }
- else {
- Sprintf(cmdstring, src_editorCommand, lineno, kpse_pathname);
- }
- if (src_warn_verbosity >= SRC_WARNINGS_MEDIUM) {
- Fprintf (stderr, "Calling: %s\n", cmdstring);
- }
- (void) system(cmdstring);
- free(cmdstring);
-}
-
-static Boolean
-src_arr_too_long(len)
- unsigned int len;
-{
- if (len > ARR_MAX_SIZE) {
- Fprintf(stderr, "Error: Requested lookup array size %u exceeds sensible limit of %d\n", len, ARR_MAX_SIZE);
- Fprintf(stderr, "(Reason might be an overflow in page_h)\n", ARR_MAX_SIZE);
- Fprintf(stderr, "Disabling src specials at this resolution/magnification.\n\n", ARR_MAX_SIZE);
- src_arr_len = 0;
- return True;
- }
- return False;
-}
-
-static void
-src_initialize_array(len)
- unsigned int len;
-{
- unsigned int j;
-
- /*
- * Note that src_arr isn't free()d at exit(0). Should we do
- * something like `atexit(src_cleanup)? However I think every real
- * OS takes care of that (and if it doesn't, it probably also
- * doesn't have `atexit'; and in any case all this would only work
- * in case of normal program termination anyway ...)
- */
-
- if (src_arr_too_long(len)) {
- return;
- }
-
- if (debug & DBG_SRC_SPECIALS) {
- fprintf(stderr, "initializing array of len: %u; page_h: %u; shrink_factor: %d\n", src_arr_len, len, shrink_factor);
- }
- src_arr = XMALLOC((len * sizeof(struct SRC_special *)), "src specials lookup array");
-
- /* initialize all index positions to NULL */
- for (j = 0; j < len; j++) {
- src_arr[j] = NULL;
- }
-}
-
-static void
-src_resize_array(len)
- unsigned int len;
-{
- unsigned int j;
-
- if (src_arr_too_long(len)) {
- return;
- }
-
- if (debug & DBG_SRC_SPECIALS) {
- fprintf(stderr, "resizing array to len: %d; page_h: %d; shrink_factor: %d\n", src_arr_len, page_h, shrink_factor);
- }
- src_arr = XREALLOC(src_arr, len * sizeof(struct SRC_special *), "src specials lookup array");
-
- /* re-initialize all index positions to NULL */
- for (j = 0; j < len; j++) {
- src_arr[j] = NULL;
- }
-}
-
-/*************************************************************************
- private function called by src_find_special
- *************************************************************************/
-
-static struct SRC_special *
-src_get_special(x,y)
- Position x,y; /* coordinates of Xevent that triggered the search */
-{
- struct SRC_special *curr = NULL, *bak = NULL, *remember = NULL;
- Position i = y; /* don't modify y, will be needed later */
- long last_line_y;
-
-
- if(last_vertical == NULL || first_vertical == NULL) {
- /* this means that there aren't any specials on this page; we may return NULL: */
- return NULL;
- }
- else {
- // fprintf(stderr, "== Last/first: %d/%d\n", last_vertical->index, first_vertical->index);
- }
-
- /***
- fprintf(stderr, "pixels per inch: %d; xresolution: %d\n", resource._pixels_per_inch, xRESOLUTION);
- fprintf(stderr, "find got args: %u, %u\n", x, y);
- x = (int)((double)x / (double)corr_fact);
- y = (int)((double)y / (double)corr_fact);
- fprintf(stderr, "after conversion: %u, %u\n", x, y);
- ***/
-
- if (debug & DBG_SRC_SPECIALS) {
- Fprintf(stderr, "Current point: x: %d, y: %d (%d,%d)\n", x, y, PXL_H, PXL_V);
- }
-
- /* check if lookup array at y position is empty, and if yes, start moving: */
- if (src_arr[i] == NULL) {
- if (debug & DBG_SRC_SPECIALS) {
- Fprintf(stderr, "array at %d is NULL\n", y);
- }
- while (src_arr[i] == NULL && i < src_arr_len && i < last_vertical->index) {
- // Fprintf(stderr, "moving down: %d (bound: %d)", i, last_vertical->index);
- i++;
- }
- while (src_arr[i] == NULL && i > 0 && i > first_vertical->index) {
- // Fprintf(stderr, "moving up: %d (bound: %d)", i, first_vertical->index);
- i--;
- }
- }
- if (debug & DBG_SRC_SPECIALS) {
- fprintf(stderr, "Found: i: %d; horizontal list:\n", i);
- for (curr = src_arr[i]; curr != NULL; curr = curr->next_special) {
- fprintf(stderr, "%s:%u (%d,%d)\n", curr->filename, curr->lineno, curr->x_coord, curr->y_coord);
- }
- }
- if((curr = src_arr[i]) != NULL) {
- /* compute the y coord of the previous line: */
- last_line_y = curr->y_coord - (Position)(curr->pt_size / 72.27 * (double)yRESOLUTION);
-
- if (y >= curr->y_coord) { /* point is below last line; return last of last line */
- while (curr->next_special != NULL) {
- curr = curr->next_special;
- }
- }
- else if ((x < curr->x_coord || y < last_line_y) && y > first_vertical->index) {
- /* point is above/left of current line; return last of previous line */
- i--;
- while (src_arr[i] == NULL && i > first_vertical->index) {
- i--;
- // fprintf(stderr, "moving up: %d\n", i);
- }
- if ((curr = src_arr[i]) != NULL) {
- while (curr->next_special != NULL) {
- curr = curr->next_special;
- }
- }
- }
- else { /* point is on current line; find closest x */
- bak = curr;
- while (curr != NULL && x > curr->x_coord) {
- // fprintf(stderr, "moving right: %d\n", curr->x_coord);
- bak = curr;
- curr = curr->next_special;
- }
- curr = bak;
- }
- }
- return curr;
-}
-
-/*************************************************************************
- insert special into array at index y. Returns 0 for success,
- 1 if y is larger than array size.
-*************************************************************************/
-static int
-src_insert_into_array(y,special)
- Position y;
- struct SRC_special *special;
-{
- struct SRC_vertical_list *new_vertical, *tmp;
- static Position save_greatest, save_smallest; /* save minimum/maximum y coordinates for this page */
- static int initialized = 0;
- if (greatest_smallest_notset) {
- save_smallest = save_greatest = y;
- // fprintf(stderr, "==smallest: %d\n", y);
- greatest_smallest_notset = False;
- }
- if (y >= src_arr_len) {
- Fprintf(stderr, "\nShouldn't happen: y coordinate %d exceeds src_arr bounds (%d)\n", y, src_arr_len);
- Fprintf(stderr, "- skipping this special.\n");
- Fprintf(stderr, "As a workaround, you may try a smaller magnification factor;\n");
- Fprintf(stderr, "however please report this bug to the maintainer(s) of xdvi(k).\n");
- return 1;
- }
- if (src_arr[y] == NULL) {
- /* array is empty at this index; insert this index into helper list SRC_vertical_list */
- new_vertical = XMALLOC(sizeof(struct SRC_vertical_list), "elem of vertical list");
- new_vertical->index = y;
-
- if (y >= save_greatest) {
- save_greatest = y;
- // fprintf(stderr, "==greatest: %d\n", y);
- last_vertical = new_vertical;
- }
- if (y <= save_smallest) {
- save_smallest = y;
- // fprintf(stderr, "==smallest: %d\n", y);
- first_vertical = new_vertical;
- }
- if (debug & DBG_SRC_SPECIALS) {
- Fprintf(stderr, "inserting new vertical pointer to %u\n", new_vertical->index);
- }
- new_vertical->next_vertical = head_vertical;
- head_vertical = new_vertical;
- }
- src_arr[y] = insert_into_src_specials(src_arr[y], special);
- return 0;
-}
-
-/*************************************************************************
- Called from src_eval_special (once, when the first special is found);
- assigns values to the global variables:
-
- src_EditorCmd_filename_first
- src_tick_width
- src_tick_height
-
- by parsing the settings of src_editorCommand and src_tickSize,
- and initializes the lookup array src_arr.
- *************************************************************************/
-static void
-src_get_settings(void)
-{
-
- char *line_substring, *file_substring;
- char *my_size;
- char *test_src_editorCommand;
-
- if (src_editorCommand == NULL) { /* in case there's something wrong with the default settings */
- Fprintf(stderr, "\nShouldn't happen: Resource \"srcEditorCommand\" has no default value!\n");
- Fprintf(stderr, "Please report this as a bug to the maintainer, along with this error message.\n");
- src_editorCommand = "emacsclient --no-wait '+%u' '%s'";
- Fprintf(stderr, "(Assuming \"%s\" to recover.)\n", src_editorCommand);
- }
-
- if((file_substring = strstr(src_editorCommand, "%s")) == NULL) {
- Fprintf(stderr, "\nError: srcEditorCommand %s doesn't contain a \"%%s\"\n(to hold the file name)\n",
- src_editorCommand);
- src_editorCommand = "emacsclient --no-wait '+%u' '%s'";
- Fprintf(stderr, "Using built-in default: \"%s\"\n", src_editorCommand);
- src_EditorCmd_filename_first = False;
- }
- else {
- if((line_substring = strstr(src_editorCommand, "%u")) == NULL) {
- Fprintf(stderr, "\nError: srcEditorCommand %s doesn't contain a \"%%u\"\n(to hold the line number)\n",
- src_editorCommand);
- src_editorCommand = "emacsclient --no-wait '+%u' '%s'";
- Fprintf(stderr, "Using built-in default: \"%s\"\n", src_editorCommand);
- src_EditorCmd_filename_first = False;
- }
- else {
- /*
- * warn if src_editorCommand doesn't start with a command, i.e.
- * doesn't contain at least one alphabetic character in front of
- * the format string.
- */
- test_src_editorCommand = src_editorCommand;
- while (!isalpha(*test_src_editorCommand) && *test_src_editorCommand != '%') {
- test_src_editorCommand++;
- }
- if (*test_src_editorCommand == '%') {
- /* ring all bells */
- XBell(DISP, 20);
- Fprintf(stderr, "\n\n****************************************************************\n");
- Fprintf(stderr, "WARNING: srcEditorCommand string %s doesn't seem\n", src_editorCommand);
- Fprintf(stderr, "to contain a command name -- this might be a security problem!\n");
- Fprintf(stderr, "Be sure to read the section on `src specials and security'\n");
- Fprintf(stderr, "in the xdvi man page before proceeding.\n");
- Fprintf(stderr, "****************************************************************\n\n");
- }
- if (strlen(file_substring) > strlen(line_substring)) { /* %s before %u */
- if (debug & DBG_SRC_SPECIALS) {
- Fprintf(stderr, "SRC info: filename comes first in editor command\n");
- }
- src_EditorCmd_filename_first = True;
- }
- else { /* %u before %s */
- if (debug & DBG_SRC_SPECIALS) {
- Fprintf(stderr, "SRC info: line number comes first in editor command\n");
- }
- src_EditorCmd_filename_first = False;
- }
- }
- }
-
- /* get settings for src_tick_width, src_tick_height */
- if(src_tickSize == NULL) { /* in case there's something wrong with the default settings */
- Fprintf(stderr, "\nShouldn't happen: Resource \"srcTickSize\" has no default value!\n");
- Fprintf(stderr, "Please report this as a bug to the maintainer, along with this error message.\n");
- src_tickSize = "40x70";
- Fprintf(stderr, "(Assuming \"%s\" to recover.)\n", src_tickSize);
- }
- if ((my_size = rindex(src_tickSize, 'x')) == NULL) {
- src_tickSize = "40x70";
- src_tick_height = 70;
- src_tick_width = 40;
- Fprintf(stderr, "\nError: argument for \"-srcTickSize\" not in `geometry' format\n");
- Fprintf(stderr, "(e.g.: \"40x70\"); using default: %s\n", src_tickSize);
- }
- else {
- my_size++;
- fflush(stderr);
- src_tick_height = atoi(my_size);
- src_tick_width = atoi(src_tickSize);
- }
-}
-
-
-/*
- ========================================================================
- Public Functions
- ========================================================================
-*/
-
-void
-src_warn_outdated(void)
-{
- /*
- * Warn if source file is newer than .dvi file (the line number
- * information in the specials might be outdated in this case).
- */
- char *warnmsg;
- // if (kpse_pathname
- if (statbuf.st_mtime > dvi_time) {
- if (src_warn_verbosity >= SRC_WARNINGS_VERBOSE) {
- warnmsg = XMALLOC((unsigned)strlen(kpse_pathname) +
- (unsigned)strlen("Warning: File %s is newer than dvi file!") + 2,
- "warning message");
- Sprintf(warnmsg, "Warning: File %s is newer than dvi file!", kpse_pathname);
- // redraw(&mane);
-
- showmessage(warnmsg);
- free(warnmsg);
- XFlush(DISP);
- }
- else {
- if (src_warn_verbosity >= SRC_WARNINGS_MEDIUM) {
- Fprintf(stdout, "\nWarning: file \"%s\" is newer than .dvi file;\n", kpse_pathname);
- Fprintf(stdout, " line number in special might be wrong!\n\n");
- }
- }
- }
-}
-
-
-
-/************************************************************************
- find src special that's closest to x,y.
- `jump' signals that we want to issue the editor command (if jump == 1)
- or just highlight the special found (jump == 0).
-************************************************************************/
-void
-src_find_special(jump,x,y)
- int jump; /* 1 if we are to call the editor command, 0 else */
- Position x,y;
-{
- struct SRC_special *found;
- /*
- * last_active_special (last item searched) will have highlight colour; redraw with
- * ordinary colour if last_active_special was on current page:
- */
- if (last_active_special != NULL && src_tickVisibility) {
- draw_src_glyph(last_active_special->x_coord, last_active_special->y_coord, highGC);
- }
-
- if(src_arr_len == 0) { /* return immediately if searching is disabled */
- XBell(DISP, 15);
- fprintf(stdout, "specials not enabled.\n");
- return;
- }
-
- found = src_get_special(x,y);
- if (found != NULL) {
- last_active_special = found;
- if (src_tickVisibility) {
- draw_src_glyph(found->x_coord, found->y_coord, foreGC);
- }
- if (src_warn_verbosity >= SRC_WARNINGS_MEDIUM) {
- Fprintf(stderr, "SRC special file:%s, line:%d (x:%d,y:%d;%f)\n",
- found->filename, found->lineno, found->x_coord, found->y_coord, found->pt_size);
- }
- /* if `jump' argument == 1, issue the editor command: */
- if (jump == 1) {
- issue_src_editor_cmd(found->filename, found->lineno);
- }
- }
- else {
- XBell(DISP, 15);
- fprintf(stdout, "No specials on this page.\n");
- }
-}
-
-
-/*************************************************************************
- free the memory used by src_arr
- *************************************************************************/
-void
-src_cleanup(void) {
- fprintf(stderr, "freeing memory...\n");
- src_delete_all_specials();
- free(src_arr);
- src_arr_len = 0;
- src_arr_not_initialized = True;
-}
-
-/*************************************************************************
- delete all elements from specials list. Not static, since also called
- from external functions (check_dvi_file in dvi-init.c, and ... in events.c).
- *************************************************************************/
-void
-src_delete_all_specials(void)
-{
- int j;
- struct SRC_vertical_list *curr, *tmp;
-
- /*
- * use SRC_vertical_list to locate and delete all elements in
- * src_arr, and free SRC_vertical_list at the same time.
- */
- for (curr=head_vertical; curr != NULL; curr = tmp) {
- tmp = curr->next_vertical;
- delete_special_list(&src_arr[curr->index]);
- src_arr[curr->index] = NULL;
- free(curr);
- }
- head_vertical = NULL;
- last_active_special = NULL;
- greatest_smallest_notset = True;
- last_vertical = NULL;
- first_vertical = NULL;
-}
-
-/*************************************************************************
- Evaluate a src special; called during the page scan from
- `applicationDoSpecial' (special.c).
- Main tasks are:
- - allocate space for the SRC_special struct and its elements
- - call `src_delete_all_specials' if page or magnification factor has changed
- - call `src_insert_into_array' to insert special into search array
- - call `draw_src_glyph' to draw the `tick' indicating the specials on the
- displayed page
- *************************************************************************/
-void
-src_eval_special(input_string, x, y)
- char *input_string;
- Position x, y;
-{
- struct SRC_special *new_special;
- unsigned int j;
-
- if (!src_evalMode) {
- return;
- }
-
- if (specials_not_initialized) {
- if (debug & DBG_SRC_SPECIALS) {
- fprintf(stderr, "initializing specials...\n");
- }
- src_get_settings();
- specials_not_initialized = False;
- }
-
- if (src_arr_not_initialized) {
- src_arr_len = page_h;
- /* initialize save_shrinkfactor to sensible value: */
- save_shrinkfactor = mane.shrinkfactor;
- src_initialize_array(src_arr_len);
- src_arr_not_initialized = False;
- }
-
- if (debug & DBG_SRC_SPECIALS) {
- if (currinf.fontp == NULL) {
- Fprintf(stderr, "SRC special: %s (%d, %d); (NULL font)\n", input_string, x, y);
- }
- else {
- Fprintf(stderr, "SRC special: %s (%d, %d), font:%s (%f)\n",
- input_string, x, y, currinf.fontp->fontname, currinf.fontp->pt_size
- );
- }
- Fprintf(stderr, "shrink factors: %d,%d,%d\n", alt.shrinkfactor, mane.shrinkfactor, currwin.shrinkfactor);
- }
-
- /*
- * flush specials if shrink factor has changed.
- * The test (mane.shrinkfactor != save_shrinkfactor) gave
- * misbehaviour with the magnifier which also sets the shrinkfactor;
- * hence the additional check MAGNIFIER_NOT_ACTIVE (kludgy, see
- * definition above). The specials are also flushed when changing
- * pages; this is done inside keystroke (in events.c).
-
- */
- if (mane.shrinkfactor != save_shrinkfactor && MAGNIFIER_NOT_ACTIVE) {
- if (debug & DBG_SRC_SPECIALS) {
- Fprintf(stderr, "shrink factor changed, flushing specials ...\n");
- }
-
- /* delete all specials from src_arr */
- src_delete_all_specials();
-
- /* recompute length of src_arr */
- src_arr_len = page_h;
- src_resize_array(src_arr_len);
- }
-
- /*
- * only insert new specials if displaying specials is ON (ignoring
- * size changes by the magnifier glass - this would insert way too
- * many specials), if src special is well-formed and if its y coordinate
- * doesn't exceed the length of the src_arr.
- */
- if (MAGNIFIER_NOT_ACTIVE && (src_arr_len > 0)) {
- // fprintf(stderr, "scanning: %s\n", input_string);
- if ((new_special = src_parse_special_string(input_string, x, y)) != NULL) {
- if ((src_insert_into_array(y, new_special) == 0) && src_tickVisibility) {
- draw_src_glyph(new_special->x_coord, new_special->y_coord, highGC);
- }
- }
- }
- save_shrinkfactor = mane.shrinkfactor;
-}
-
-/*************************************************************************
- Currently unused.
- In case an external function would have to draw the src ticks, it might
- want to call this function.
- *************************************************************************/
-void draw_src_specials()
-{
- struct SRC_special *curr;
- for(curr = head_special; curr != NULL; curr = curr->next_special) {
- draw_src_glyph(curr->x_coord, curr->y_coord, highGC);
- }
-}
-
-/************************************************************************
- function that prints out the list of specials for the current page
-************************************************************************/
-
-void
-test_print_out_list()
-{
- struct SRC_special *curr2;
- struct SRC_vertical_list *curr, *tmp;
- int j;
- for (curr = head_vertical; curr != NULL; curr = curr->next_vertical) {
- curr2 = src_arr[curr->index];
- for (curr2 = src_arr[curr->index], j = 0; curr2 != NULL; curr2 = curr2->next_special, j++) {
- Fprintf(stderr, "[%3d:%3d] %s:%u (%d,%d;%f)\n",
- curr->index, j, curr2->filename, curr2->lineno, curr2->x_coord, curr2->y_coord, curr2->pt_size);
- }
- }
-}
-
-
-#endif