diff options
Diffstat (limited to '')
-rw-r--r-- | src/devices/xditview/Dvi.c | 603 |
1 files changed, 603 insertions, 0 deletions
diff --git a/src/devices/xditview/Dvi.c b/src/devices/xditview/Dvi.c new file mode 100644 index 0000000..3520676 --- /dev/null +++ b/src/devices/xditview/Dvi.c @@ -0,0 +1,603 @@ +#include <config.h> + +#ifndef SABER +#ifndef lint +static char Xrcsid[] = "$XConsortium: Dvi.c,v 1.9 89/12/10 16:12:25 rws Exp $"; +#endif /* lint */ +#endif /* SABER */ + +/* + * 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 <ctype.h> + +#include "DviP.h" +#include "font.h" +#include "page.h" +#include "parse.h" + +/**************************************************************** + * + * Full class record constant + * + ****************************************************************/ + +/* Private Data */ + +static char default_font_map_1[] = "\ +TR -adobe-times-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\ +TI -adobe-times-medium-i-normal--*-100-*-*-*-*-iso8859-1\n\ +TB -adobe-times-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\ +TBI -adobe-times-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\ +CR -adobe-courier-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\ +CI -adobe-courier-medium-o-normal--*-100-*-*-*-*-iso8859-1\n\ +CB -adobe-courier-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\ +CBI -adobe-courier-bold-o-normal--*-100-*-*-*-*-iso8859-1\n\ +"; +static char default_font_map_2[] = "\ +HR -adobe-helvetica-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\ +HI -adobe-helvetica-medium-o-normal--*-100-*-*-*-*-iso8859-1\n\ +HB -adobe-helvetica-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\ +HBI -adobe-helvetica-bold-o-normal--*-100-*-*-*-*-iso8859-1\n\ +"; +static char default_font_map_3[] = "\ +NR -adobe-new century schoolbook-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\ +NI -adobe-new century schoolbook-medium-i-normal--*-100-*-*-*-*-iso8859-1\n\ +NB -adobe-new century schoolbook-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\ +NBI -adobe-new century schoolbook-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\ +S -adobe-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\ +SS -adobe-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\ +"; + +#define offset(field) XtOffset(DviWidget, field) + +#define MY_WIDTH(dw) ((int)(dw->dvi.paperwidth * dw->dvi.scale_factor + .5)) +#define MY_HEIGHT(dw) ((int)(dw->dvi.paperlength * dw->dvi.scale_factor + .5)) + +static XtResource resources[] = { + {(String)XtNfontMap, (String)XtCFontMap, (String)XtRString, + sizeof (char *), offset(dvi.font_map_string), + (String)XtRString, NULL /* set in code */}, + {(String)XtNforeground, (String)XtCForeground, (String)XtRPixel, + sizeof (unsigned long), offset(dvi.foreground), + (String)XtRString, (XtPointer)"XtDefaultForeground"}, + {(String)XtNbackground, (String)XtCBackground, (String)XtRPixel, + sizeof (unsigned long), offset(dvi.background), + (String)XtRString, (XtPointer)"XtDefaultBackground"}, + {(String)XtNpageNumber, (String)XtCPageNumber, (String)XtRInt, + sizeof (int), offset(dvi.requested_page), + (String)XtRString, (XtPointer)"1"}, + {(String)XtNlastPageNumber, (String)XtCLastPageNumber, (String)XtRInt, + sizeof (int), offset (dvi.last_page), + (String)XtRString, (XtPointer)"0"}, + {(String)XtNfile, (String)XtCFile, (String)XtRFile, + sizeof (FILE *), offset (dvi.file), + (String)XtRFile, (XtPointer)0}, + {(String)XtNseek, (String)XtCSeek, (String)XtRBoolean, + sizeof (Boolean), offset(dvi.seek), + (String)XtRString, (XtPointer)"false"}, + {(String)XtNfont, (String)XtCFont, (String)XtRFontStruct, + sizeof (XFontStruct *), offset(dvi.default_font), + (String)XtRString, (XtPointer)"xtdefaultfont"}, + {(String)XtNbackingStore, (String)XtCBackingStore, (String)XtRBackingStore, + sizeof (int), offset(dvi.backing_store), + (String)XtRString, (XtPointer)"default"}, + {(String)XtNnoPolyText, (String)XtCNoPolyText, (String)XtRBoolean, + sizeof (Boolean), offset(dvi.noPolyText), + (String)XtRString, (XtPointer)"false"}, + {(String)XtNresolution, (String)XtCResolution, (String)XtRInt, + sizeof(int), offset(dvi.default_resolution), + (String)XtRString, (XtPointer)"75"}, +}; + +#undef offset + +static void ClassInitialize (void); +static void ClassPartInitialize(WidgetClass); +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 ShowDvi (DviWidget); +static void CloseFile (DviWidget); +static void OpenFile (DviWidget); +static void FindPage (DviWidget); + +static void SaveToFile (Widget, FILE *); + +DviClassRec dviClassRec = { +{ + &widgetClassRec, /* superclass */ + (String)"Dvi", /* class_name */ + sizeof(DviRec), /* size */ + ClassInitialize, /* class_initialize */ + ClassPartInitialize, /* 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 */ + TRUE, /* compress_exposure */ + TRUE, /* compress_enterleave */ + FALSE, /* visible_interest */ + Destroy, /* destroy */ + NULL, /* resize */ + Redisplay, /* expose */ + SetValues, /* set_values */ + SetValuesHook, /* set_values_hook */ + NULL, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + 0, /* tm_table */ + QueryGeometry, /* query_geometry */ + NULL, /* display_accelerator */ + NULL /* extension */ +},{ + SaveToFile, /* save */ +}, +}; + +WidgetClass dviWidgetClass = (WidgetClass) &dviClassRec; + +static void ClassInitialize (void) +{ + int len1 = strlen(default_font_map_1); + int len2 = strlen(default_font_map_2); + int len3 = strlen(default_font_map_3); + char *dfm = XtMalloc(len1 + len2 + len3 + 1); + char *ptr = dfm; + strcpy(ptr, default_font_map_1); ptr += len1; + strcpy(ptr, default_font_map_2); ptr += len2; + strcpy(ptr, default_font_map_3); + resources[0].default_addr = dfm; + + XtAddConverter( XtRString, XtRBackingStore, XmuCvtStringToBackingStore, + NULL, 0 ); +} + +/**************************************************************** + * + * Private Procedures + * + ****************************************************************/ + +/* ARGSUSED */ +static void Initialize(Widget request, Widget new_wd, + ArgList args, Cardinal *num_args) +{ + DviWidget dw = (DviWidget) new_wd; + + dw->dvi.current_page = 0; + dw->dvi.font_map = 0; + dw->dvi.cache.index = 0; + dw->dvi.text_x_width = 0; + dw->dvi.text_device_width = 0; + dw->dvi.word_flag = 0; + dw->dvi.file = 0; + dw->dvi.tmpFile = 0; + dw->dvi.state = 0; + dw->dvi.readingTmp = 0; + dw->dvi.cache.char_index = 0; + dw->dvi.cache.font_size = -1; + dw->dvi.cache.font_number = -1; + dw->dvi.cache.adjustable[0] = 0; + dw->dvi.file_map = 0; + dw->dvi.fonts = 0; + dw->dvi.seek = False; + dw->dvi.device_resolution = dw->dvi.default_resolution; + dw->dvi.display_resolution = dw->dvi.default_resolution; + dw->dvi.paperlength = dw->dvi.default_resolution*11; + dw->dvi.paperwidth = (dw->dvi.default_resolution*8 + + dw->dvi.default_resolution/2); + dw->dvi.scale_factor = 1.0; + dw->dvi.sizescale = 1; + dw->dvi.line_thickness = -1; + dw->dvi.line_width = 1; + dw->dvi.fill = DVI_FILL_MAX; + dw->dvi.device_font = 0; + dw->dvi.device_font_number = -1; + dw->dvi.device = 0; + dw->dvi.native = 0; + + request = request; /* unused; suppress compiler warning */ + args = args; + num_args = num_args; +} + +#include "gray1.bm" +#include "gray2.bm" +#include "gray3.bm" +#include "gray4.bm" +#include "gray5.bm" +#include "gray6.bm" +#include "gray7.bm" +#include "gray8.bm" + +static void +Realize (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; + values.cap_style = CapRound; + values.join_style = JoinRound; + values.line_width = dw->dvi.line_width; + dw->dvi.normal_GC = XCreateGC (XtDisplay (w), XtWindow (w), + GCForeground|GCCapStyle|GCJoinStyle + |GCLineWidth, + &values); + dw->dvi.gray[0] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w), + gray1_bits, + gray1_width, gray1_height); + dw->dvi.gray[1] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w), + gray2_bits, + gray2_width, gray2_height); + dw->dvi.gray[2] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w), + gray3_bits, + gray3_width, gray3_height); + dw->dvi.gray[3] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w), + gray4_bits, + gray4_width, gray4_height); + dw->dvi.gray[4] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w), + gray5_bits, + gray5_width, gray5_height); + dw->dvi.gray[5] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w), + gray6_bits, + gray6_width, gray6_height); + dw->dvi.gray[6] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w), + gray7_bits, + gray7_width, gray7_height); + dw->dvi.gray[7] = XCreateBitmapFromData(XtDisplay (w), XtWindow (w), + gray8_bits, + gray8_width, gray8_height); + values.background = dw->dvi.background; + values.stipple = dw->dvi.gray[5]; + dw->dvi.fill_GC = XCreateGC (XtDisplay (w), XtWindow (w), + GCForeground|GCBackground|GCStipple, + &values); + + dw->dvi.fill_type = 9; + + if (dw->dvi.file) + OpenFile (dw); + ParseFontMap (dw); +} + +static void +Destroy(Widget w) +{ + DviWidget dw = (DviWidget) w; + + XFreeGC (XtDisplay (w), dw->dvi.normal_GC); + XFreeGC (XtDisplay (w), dw->dvi.fill_GC); + XFreePixmap (XtDisplay (w), dw->dvi.gray[0]); + XFreePixmap (XtDisplay (w), dw->dvi.gray[1]); + XFreePixmap (XtDisplay (w), dw->dvi.gray[2]); + XFreePixmap (XtDisplay (w), dw->dvi.gray[3]); + XFreePixmap (XtDisplay (w), dw->dvi.gray[4]); + XFreePixmap (XtDisplay (w), dw->dvi.gray[5]); + XFreePixmap (XtDisplay (w), dw->dvi.gray[6]); + XFreePixmap (XtDisplay (w), dw->dvi.gray[7]); + DestroyFontMap (dw->dvi.font_map); + DestroyFileMap (dw->dvi.file_map); + device_destroy (dw->dvi.device); +} + +/* + * Repaint the widget window + */ + +/* ARGSUSED */ +static void +Redisplay(Widget w, XEvent *event, Region region) +{ + DviWidget dw = (DviWidget) w; + XRectangle extents; + + 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; + ShowDvi (dw); + + event = event; /* unused; suppress compiler warning */ +} + +/* + * Set specified arguments into widget + */ +/* ARGSUSED */ +static Boolean +SetValues (Widget wcurrent, Widget wrequest, Widget wnew, + ArgList args, Cardinal *num_args) +{ + Boolean redisplay = FALSE; + char *new_map; + int cur, req; + DviWidget current = (DviWidget)wcurrent; + DviWidget request = (DviWidget)wrequest; + DviWidget new_wd = (DviWidget)wnew; + + 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_wd->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_wd); + } + } + + req = request->dvi.requested_page; + cur = current->dvi.requested_page; + if (cur != req) { + if (!request->dvi.file) + req = 0; + else { + if (req < 1) + req = 1; + if (current->dvi.last_page != 0 && + req > current->dvi.last_page) + req = current->dvi.last_page; + } + if (cur != req) + redisplay = TRUE; + new_wd->dvi.requested_page = req; + if (current->dvi.last_page == 0 && req > cur) + FindPage (new_wd); + } + + args = args; /* unused; suppress compiler warning */ + num_args = num_args; + + return redisplay; +} + +/* + * use the set_values_hook entry to check when + * the file is set + */ + +static Boolean +SetValuesHook (Widget wdw, ArgList args, Cardinal *num_argsp) +{ + Cardinal i; + DviWidget dw = (DviWidget)wdw; + + for (i = 0; i < *num_argsp; i++) { + if (!strcmp (args[i].name, XtNfile)) { + CloseFile (dw); + OpenFile (dw); + return TRUE; + } + } + return FALSE; +} + +static void CloseFile (DviWidget dw) +{ + if (dw->dvi.tmpFile) + fclose (dw->dvi.tmpFile); + ForgetPagePositions (dw); +} + +static void OpenFile (DviWidget dw) +{ + dw->dvi.tmpFile = 0; + if (!dw->dvi.seek) + dw->dvi.tmpFile = tmpfile(); + dw->dvi.requested_page = 1; + dw->dvi.last_page = 0; +} + +static XtGeometryResult +QueryGeometry (Widget w, XtWidgetGeometry *request, + XtWidgetGeometry *geometry_return) +{ + XtGeometryResult ret; + DviWidget dw = (DviWidget) w; + + ret = XtGeometryYes; + if (((request->request_mode & CWWidth) + && request->width < MY_WIDTH(dw)) + || ((request->request_mode & CWHeight) + && request->height < MY_HEIGHT(dw))) + ret = XtGeometryAlmost; + geometry_return->width = MY_WIDTH(dw); + geometry_return->height = MY_HEIGHT(dw); + geometry_return->request_mode = CWWidth|CWHeight; + return ret; +} + +void +SetDevice (DviWidget dw, const char *name) +{ + XtWidgetGeometry request, reply; + XtGeometryResult ret; + + ForgetFonts (dw); + dw->dvi.device = device_load (name); + if (!dw->dvi.device) + return; + dw->dvi.sizescale = dw->dvi.device->sizescale; + dw->dvi.device_resolution = dw->dvi.device->res; + dw->dvi.native = dw->dvi.device->X11; + dw->dvi.paperlength = dw->dvi.device->paperlength; + dw->dvi.paperwidth = dw->dvi.device->paperwidth; + if (dw->dvi.native) { + dw->dvi.display_resolution = dw->dvi.device_resolution; + dw->dvi.scale_factor = 1.0; + } + else { + dw->dvi.display_resolution = dw->dvi.default_resolution; + dw->dvi.scale_factor = ((double)dw->dvi.display_resolution + / dw->dvi.device_resolution); + } + request.request_mode = CWWidth|CWHeight; + request.width = MY_WIDTH(dw); + request.height = MY_HEIGHT(dw); + ret = XtMakeGeometryRequest ((Widget)dw, &request, &reply); + if (ret == XtGeometryAlmost + && reply.height >= request.height + && reply.width >= request.width) { + request.width = reply.width; + request.height = reply.height; + XtMakeGeometryRequest ((Widget)dw, &request, &reply); + } +} + +static void +ShowDvi (DviWidget dw) +{ + if (!dw->dvi.file) { + static char Error[] = "No file selected"; + + XSetFont (XtDisplay(dw), dw->dvi.normal_GC, + dw->dvi.default_font->fid); + XDrawString (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC, + 20, 20, Error, strlen (Error)); + return; + } + + FindPage (dw); + + 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; +} + +static void +FindPage (DviWidget dw) +{ + int i; + long file_position; + + 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 beginning of this page. + */ + if (!dw->dvi.readingTmp && feof (dw->dvi.file)) { + file_position = SearchPagePosition (dw, + dw->dvi.current_page); + if (file_position != -1) + FileSeek (dw, file_position); + dw->dvi.requested_page = dw->dvi.current_page; + break; + } + } + } +} + +void DviSaveToFile(Widget w, FILE *fp) +{ + XtCheckSubclass(w, dviWidgetClass, NULL); + (*((DviWidgetClass) XtClass(w))->command_class.save)(w, fp); +} + +static +void SaveToFile(Widget w, FILE *fp) +{ + DviWidget dw = (DviWidget)w; + long pos; + int c; + + if (dw->dvi.tmpFile) { + pos = ftell(dw->dvi.tmpFile); + if (dw->dvi.ungot) { + pos--; + dw->dvi.ungot = 0; + /* The ungot character is in the tmpFile, so we don't + want to read it from file. */ + (void)getc(dw->dvi.file); + } + } + else + pos = ftell(dw->dvi.file); + FileSeek(dw, 0L); + while (DviGetC(dw, &c) != EOF) + if (putc(c, fp) == EOF) { + /* XXX print error message */ + break; + } + FileSeek(dw, pos); +} + +static +void ClassPartInitialize(WidgetClass widget_class) +{ + DviWidgetClass wc = (DviWidgetClass)widget_class; + DviWidgetClass super = (DviWidgetClass) wc->core_class.superclass; + if (wc->command_class.save == InheritSaveToFile) + wc->command_class.save = super->command_class.save; +} + +/* +Local Variables: +c-indent-level: 8 +c-continued-statement-offset: 8 +c-brace-offset: -8 +c-argdecl-indent: 8 +c-label-offset: -8 +c-tab-always-indent: nil +End: +*/ |