summaryrefslogtreecommitdiff
path: root/Dvi.c
diff options
context:
space:
mode:
Diffstat (limited to 'Dvi.c')
-rw-r--r--Dvi.c554
1 files changed, 554 insertions, 0 deletions
diff --git a/Dvi.c b/Dvi.c
new file mode 100644
index 0000000..4148020
--- /dev/null
+++ b/Dvi.c
@@ -0,0 +1,554 @@
+/* $XConsortium: Dvi.c,v 1.21 94/04/17 20:43:34 keith Exp $ */
+/*
+
+Copyright (c) 1991 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+*/
+/* $XFree86: xc/programs/xditview/Dvi.c,v 1.4 2001/08/27 23:35:12 dawes Exp $ */
+
+
+/*
+ * Dvi.c - Dvi display widget
+ */
+
+#define XtStrlen(s) ((s) ? strlen(s) : 0)
+
+ /* The following are defined for the reader's convenience. Any
+ Xt..Field macro in this code just refers to some field in
+ one of the substructures of the WidgetRec. */
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xmu/Converters.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+#include "DviP.h"
+
+/****************************************************************
+ *
+ * Full class record constant
+ *
+ ****************************************************************/
+
+/* Private Data */
+/* Note: default_font_map was too long a token for some machines...
+ * therefor it has been split in to and assigned to resources
+ * in the ClassInitialize routine.
+ */
+static char default_font_map_1[] = "\
+R -*-times-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
+I -*-times-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
+B -*-times-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
+F -*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
+TR -*-times-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
+TI -*-times-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
+TB -*-times-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
+TF -*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
+BI -*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
+C -*-courier-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
+CO -*-courier-medium-o-normal--*-*-*-*-*-*-iso8859-1\n\
+CB -*-courier-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
+CF -*-courier-bold-o-normal--*-*-*-*-*-*-iso8859-1\n\
+H -*-helvetica-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
+HO -*-helvetica-medium-o-normal--*-*-*-*-*-*-iso8859-1\n\
+HB -*-helvetica-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
+HF -*-helvetica-bold-o-normal--*-*-*-*-*-*-iso8859-1\n\
+";
+static char default_font_map_2[] = "\
+N -*-new century schoolbook-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
+NI -*-new century schoolbook-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
+NB -*-new century schoolbook-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
+NF -*-new century schoolbook-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
+A -*-charter-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
+AI -*-charter-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
+AB -*-charter-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
+AF -*-charter-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
+S -*-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific\n\
+S2 -*-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific\n\
+";
+
+#define offset(field) XtOffsetOf(DviRec, field)
+
+static XtResource resources[] = {
+ {XtNfontMap, XtCFontMap, XtRString, sizeof (char *),
+ offset(dvi.font_map_string), XtRString, NULL /* set in code */},
+ {XtNforeground, XtCForeground, XtRPixel, sizeof (unsigned long),
+ offset(dvi.foreground), XtRString, XtDefaultForeground},
+ {XtNpageNumber, XtCPageNumber, XtRInt, sizeof (int),
+ offset(dvi.requested_page), XtRImmediate, (XtPointer) 1},
+ {XtNlastPageNumber, XtCLastPageNumber, XtRInt, sizeof (int),
+ offset (dvi.last_page), XtRImmediate, (XtPointer) 0},
+ {XtNfile, XtCFile, XtRFile, sizeof (FILE *),
+ offset (dvi.file), XtRFile, (char *) 0},
+ {XtNseek, XtCSeek, XtRBoolean, sizeof (Boolean),
+ offset(dvi.seek), XtRImmediate, (XtPointer) False},
+ {XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
+ offset(dvi.default_font), XtRString, XtDefaultFont},
+ {XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof (int),
+ offset(dvi.backing_store), XtRString, "default"},
+ {XtNnoPolyText, XtCNoPolyText, XtRBoolean, sizeof (Boolean),
+ offset(dvi.noPolyText), XtRImmediate, (XtPointer) False},
+ {XtNscreenResolution, XtCScreenResolution, XtRInt, sizeof (int),
+ offset(dvi.screen_resolution), XtRImmediate, (XtPointer) 75},
+ {XtNpageWidth, XtCPageWidth, XtRFloat, sizeof (float),
+ offset(dvi.page_width), XtRString, "8.5"},
+ {XtNpageHeight, XtCPageHeight, XtRFloat, sizeof (float),
+ offset(dvi.page_height), XtRString, "11"},
+ {XtNsizeScale, XtCSizeScale, XtRInt, sizeof (int),
+ offset(dvi.size_scale_set), XtRImmediate, (XtPointer) 0},
+};
+
+#undef offset
+
+static void ClassInitialize(void);
+static void Initialize(Widget, Widget, ArgList, Cardinal *);
+static void Realize(Widget, XtValueMask *, XSetWindowAttributes *);
+static void Destroy(Widget);
+static void Redisplay(Widget, XEvent *, Region);
+static Boolean SetValues(Widget, Widget, Widget, ArgList , Cardinal *);
+static Boolean SetValuesHook(Widget, ArgList, Cardinal *);
+static XtGeometryResult QueryGeometry(Widget,
+ XtWidgetGeometry *, XtWidgetGeometry *);
+static void RequestDesiredSize(DviWidget);
+static void ShowDvi(DviWidget);
+static void CloseFile(DviWidget);
+static void OpenFile(DviWidget);
+
+#define SuperClass ((SimpleWidgetClass)&simpleClassRec)
+
+DviClassRec dviClassRec = {
+{
+ (WidgetClass) SuperClass, /* superclass */
+ "Dvi", /* class_name */
+ sizeof(DviRec), /* size */
+ ClassInitialize, /* class_initialize */
+ NULL, /* class_part_initialize */
+ FALSE, /* class_inited */
+ Initialize, /* initialize */
+ NULL, /* initialize_hook */
+ Realize, /* realize */
+ NULL, /* actions */
+ 0, /* num_actions */
+ resources, /* resources */
+ XtNumber(resources), /* resource_count */
+ NULLQUARK, /* xrm_class */
+ FALSE, /* compress_motion */
+ XtExposeCompressMaximal, /* compress_exposure */
+ TRUE, /* compress_enterleave */
+ FALSE, /* visible_interest */
+ Destroy, /* destroy */
+ NULL, /* resize */
+ Redisplay, /* expose */
+ SetValues, /* set_values */
+ SetValuesHook, /* set_values_hook */
+ XtInheritSetValuesAlmost, /* set_values_almost */
+ NULL, /* get_values_hook */
+ NULL, /* accept_focus */
+ XtVersion, /* version */
+ NULL, /* callback_private */
+ 0, /* tm_table */
+ QueryGeometry, /* query_geometry */
+ XtInheritDisplayAccelerator, /* display_accelerator */
+ NULL, /* extension */
+}, /* CoreClass fields initialization */
+{
+ XtInheritChangeSensitive /* change_sensitive */
+}, /* SimpleClass fields initialization */
+{
+ 0, /* field not used */
+}, /* DviClass fields initialization */
+};
+
+WidgetClass dviWidgetClass = (WidgetClass) &dviClassRec;
+
+static void
+ClassInitialize (void)
+{
+ int len1 = strlen(default_font_map_1);
+ int len2 = strlen(default_font_map_2);
+ char *dfm = XtMalloc(len1 + len2 + 1);
+ char *ptr = dfm;
+ strcpy(ptr, default_font_map_1); ptr += len1;
+ strcpy(ptr, default_font_map_2);
+ resources[0].default_addr = dfm;
+
+ XtAddConverter( XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
+ NULL, 0 );
+}
+
+/****************************************************************
+ *
+ * Private Procedures
+ *
+ ****************************************************************/
+
+/* ARGSUSED */
+static void
+Initialize(request, new, args, num_args)
+ Widget request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ DviWidget dw = (DviWidget) new;
+
+ dw->dvi.tmpFile = 0;
+ dw->dvi.readingTmp = 0;
+ dw->dvi.ungot = 0;
+ dw->dvi.normal_GC = 0;
+ dw->dvi.file_map = 0;
+ dw->dvi.fonts = 0;
+ dw->dvi.font_map = 0;
+ dw->dvi.current_page = 0;
+ dw->dvi.font_size = 0;
+ dw->dvi.font_number = 0;
+ dw->dvi.device_resolution = 0;
+ dw->dvi.line_width = 0;
+ dw->dvi.line_style = 0;
+ dw->dvi.font = 0;
+ dw->dvi.display_enable = 0;
+ dw->dvi.scale = 0.0;
+ dw->dvi.state = 0;
+ dw->dvi.cache.index = 0;
+ dw->dvi.cache.font = 0;
+ dw->dvi.size_scale = 0;
+ dw->dvi.size_scale_set = 0;
+ RequestDesiredSize (dw);
+}
+
+static void
+Realize(w, valueMask, attrs)
+ Widget w;
+ XtValueMask *valueMask;
+ XSetWindowAttributes *attrs;
+{
+ DviWidget dw = (DviWidget) w;
+ XGCValues values;
+
+ if (dw->dvi.backing_store != Always + WhenMapped + NotUseful) {
+ attrs->backing_store = dw->dvi.backing_store;
+ *valueMask |= CWBackingStore;
+ }
+ XtCreateWindow (w, (unsigned)InputOutput, (Visual *) CopyFromParent,
+ *valueMask, attrs);
+ values.foreground = dw->dvi.foreground;
+ dw->dvi.normal_GC = XCreateGC (XtDisplay (w), XtWindow (w),
+ GCForeground, &values);
+#ifdef USE_XFT
+ {
+ int scr;
+ Visual *visual;
+ Colormap cmap;
+ XRenderColor black;
+
+ scr = XScreenNumberOfScreen (dw->core.screen);
+ visual = DefaultVisual (XtDisplay (w), scr);
+ cmap = DefaultColormap (XtDisplay (w), scr);
+ dw->dvi.draw = XftDrawCreate (XtDisplay (w), XtWindow (w),
+ visual, cmap);
+
+ black.red = black.green = black.blue = 0;
+ black.alpha = 0xffff;
+ XftColorAllocValue (XtDisplay (w), visual, cmap,
+ &black, &dw->dvi.black);
+ dw->dvi.default_font = XftFontOpenName (XtDisplay (w),
+ scr,
+ "serif-12");
+ }
+#endif
+ if (dw->dvi.file)
+ OpenFile (dw);
+ ParseFontMap (dw);
+}
+
+static void
+Destroy(w)
+ Widget w;
+{
+ DviWidget dw = (DviWidget) w;
+
+ XFreeGC (XtDisplay (w), dw->dvi.normal_GC);
+ DestroyFontMap (dw->dvi.font_map);
+ DestroyFileMap (dw->dvi.file_map);
+}
+
+/*
+ * Repaint the widget window
+ */
+
+/* ARGSUSED */
+static void
+Redisplay(w, event, region)
+ Widget w;
+ XEvent *event;
+ Region region;
+{
+ DviWidget dw = (DviWidget) w;
+#ifndef USE_XFT
+ XRectangle extents;
+#endif
+
+#ifdef USE_XFT
+ XClearArea (XtDisplay (dw),
+ XtWindow (dw),
+ 0, 0, 0, 0, False);
+ dw->dvi.extents.x1 = 0;
+ dw->dvi.extents.y1 = 0;
+ dw->dvi.extents.x2 = dw->core.width;
+ dw->dvi.extents.y2 = dw->core.height;
+#else
+ XClipBox (region, &extents);
+ dw->dvi.extents.x1 = extents.x;
+ dw->dvi.extents.y1 = extents.y;
+ dw->dvi.extents.x2 = extents.x + extents.width;
+ dw->dvi.extents.y2 = extents.y + extents.height;
+#endif
+ ShowDvi (dw);
+}
+
+static void
+RequestDesiredSize (dw)
+ DviWidget dw;
+{
+ XtWidgetGeometry req, rep;
+
+ dw->dvi.desired_width = dw->dvi.page_width *
+ dw->dvi.screen_resolution;
+ dw->dvi.desired_height = dw->dvi.page_height *
+ dw->dvi.screen_resolution;
+ req.request_mode = CWWidth|CWHeight;
+ req.width = dw->dvi.desired_width;
+ req.height = dw->dvi.desired_height;
+ XtMakeGeometryRequest ((Widget) dw, &req, &rep);
+}
+
+/*
+ * Set specified arguments into widget
+ */
+/* ARGSUSED */
+static Boolean
+SetValues (wcurrent, wrequest, wnew, args, num_args)
+ Widget wcurrent, wrequest, wnew;
+ ArgList args;
+ Cardinal *num_args;
+{
+ DviWidget current = (DviWidget) wcurrent;
+ DviWidget request = (DviWidget) wrequest;
+ DviWidget new = (DviWidget) wnew;
+ Boolean redisplay = FALSE;
+ char *new_map;
+ int cur, req;
+
+ req = request->dvi.requested_page;
+ cur = current->dvi.requested_page;
+ if (cur != req) {
+ if (req < 1)
+ req = 1;
+ if (request->dvi.file)
+ {
+ if (current->dvi.last_page != 0 &&
+ req > current->dvi.last_page)
+ req = current->dvi.last_page;
+ }
+ if (cur != req)
+ redisplay = TRUE;
+ new->dvi.requested_page = req;
+ }
+
+ if (current->dvi.font_map_string != request->dvi.font_map_string) {
+ new_map = XtMalloc (strlen (request->dvi.font_map_string) + 1);
+ if (new_map) {
+ redisplay = TRUE;
+ strcpy (new_map, request->dvi.font_map_string);
+ new->dvi.font_map_string = new_map;
+ if (current->dvi.font_map_string)
+ XtFree (current->dvi.font_map_string);
+ current->dvi.font_map_string = 0;
+ ParseFontMap (new);
+ }
+ }
+ if (current->dvi.screen_resolution != request->dvi.screen_resolution)
+ {
+ ResetFonts (new);
+ new->dvi.line_width = -1;
+ }
+ if (request->dvi.device_resolution)
+ new->dvi.scale = ((double) request->dvi.screen_resolution) /
+ ((double) request->dvi.device_resolution);
+ if (current->dvi.page_width != request->dvi.page_width ||
+ current->dvi.page_height != request->dvi.page_height ||
+ current->dvi.screen_resolution != request->dvi.screen_resolution)
+ {
+ RequestDesiredSize (new);
+ redisplay = TRUE;
+ }
+ return redisplay;
+}
+
+/*
+ * use the set_values_hook entry to check when
+ * the file is set
+ */
+
+static Boolean
+SetValuesHook (widget, args, num_argsp)
+ Widget widget;
+ ArgList args;
+ Cardinal *num_argsp;
+{
+ DviWidget dw = (DviWidget) widget;
+ Cardinal i;
+
+ for (i = 0; i < *num_argsp; i++) {
+ if (!strcmp (args[i].name, XtNfile)) {
+ CloseFile (dw);
+ OpenFile (dw);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void
+CloseFile (dw)
+ DviWidget dw;
+{
+ if (dw->dvi.tmpFile)
+ fclose (dw->dvi.tmpFile);
+ ForgetPagePositions (dw);
+}
+
+static void
+OpenFile (dw)
+ DviWidget dw;
+{
+ char tmpName[sizeof ("/tmp/dviXXXXXX")];
+#ifdef HAS_MKSTEMP
+ int fd;
+#endif
+
+ dw->dvi.tmpFile = 0;
+ if (!dw->dvi.seek) {
+ strcpy (tmpName, "/tmp/dviXXXXXX");
+#ifndef HAS_MKSTEMP
+ mktemp (tmpName);
+ dw->dvi.tmpFile = fopen (tmpName, "w+");
+#else
+ fd = mkstemp(tmpName);
+ dw->dvi.tmpFile = fdopen(fd, "w+");
+#endif
+ unlink (tmpName);
+ }
+ if (dw->dvi.requested_page < 1)
+ dw->dvi.requested_page = 1;
+ dw->dvi.last_page = 0;
+}
+
+static XtGeometryResult
+QueryGeometry (w, request, geometry_return)
+ Widget w;
+ XtWidgetGeometry *request, *geometry_return;
+{
+ XtGeometryResult ret;
+ DviWidget dw = (DviWidget) w;
+
+ ret = XtGeometryYes;
+ if ((int)request->width < dw->dvi.desired_width
+ || (int)request->height < dw->dvi.desired_height)
+ ret = XtGeometryAlmost;
+ geometry_return->width = dw->dvi.desired_width;
+ geometry_return->height = dw->dvi.desired_height;
+ geometry_return->request_mode = CWWidth|CWHeight;
+ return ret;
+}
+
+void
+SetDeviceResolution (dw, resolution)
+ DviWidget dw;
+ int resolution;
+{
+ if (resolution != dw->dvi.device_resolution) {
+ dw->dvi.device_resolution = resolution;
+ dw->dvi.scale = ((double) dw->dvi.screen_resolution) /
+ ((double) resolution);
+ }
+}
+
+static void
+ShowDvi (dw)
+ DviWidget dw;
+{
+ int i;
+ long file_position;
+
+ if (!dw->dvi.file)
+ return;
+
+ if (dw->dvi.requested_page < 1)
+ dw->dvi.requested_page = 1;
+
+ if (dw->dvi.last_page != 0 && dw->dvi.requested_page > dw->dvi.last_page)
+ dw->dvi.requested_page = dw->dvi.last_page;
+
+ file_position = SearchPagePosition (dw, dw->dvi.requested_page);
+ if (file_position != -1) {
+ FileSeek(dw, file_position);
+ dw->dvi.current_page = dw->dvi.requested_page;
+ } else {
+ for (i=dw->dvi.requested_page; i > 0; i--) {
+ file_position = SearchPagePosition (dw, i);
+ if (file_position != -1)
+ break;
+ }
+ if (file_position == -1)
+ file_position = 0;
+ FileSeek (dw, file_position);
+
+ dw->dvi.current_page = i;
+
+ dw->dvi.display_enable = 0;
+ while (dw->dvi.current_page != dw->dvi.requested_page) {
+ dw->dvi.current_page = ParseInput (dw);
+ /*
+ * at EOF, seek back to the begining of this page.
+ */
+ if (feof (dw->dvi.file)) {
+ file_position = SearchPagePosition (dw,
+ dw->dvi.current_page);
+ if (file_position != -1)
+ FileSeek (dw, file_position);
+ break;
+ }
+ }
+ }
+
+ dw->dvi.display_enable = 1;
+ ParseInput (dw);
+ if (dw->dvi.last_page && dw->dvi.requested_page > dw->dvi.last_page)
+ dw->dvi.requested_page = dw->dvi.last_page;
+}