1f80a6dcdSmrg/* 2f80a6dcdSmrg 3f80a6dcdSmrgCopyright (c) 1991 X Consortium 4f80a6dcdSmrg 5f80a6dcdSmrgPermission is hereby granted, free of charge, to any person obtaining 6f80a6dcdSmrga copy of this software and associated documentation files (the 7f80a6dcdSmrg"Software"), to deal in the Software without restriction, including 8f80a6dcdSmrgwithout limitation the rights to use, copy, modify, merge, publish, 9f80a6dcdSmrgdistribute, sublicense, and/or sell copies of the Software, and to 10f80a6dcdSmrgpermit persons to whom the Software is furnished to do so, subject to 11f80a6dcdSmrgthe following conditions: 12f80a6dcdSmrg 13f80a6dcdSmrgThe above copyright notice and this permission notice shall be included 14f80a6dcdSmrgin all copies or substantial portions of the Software. 15f80a6dcdSmrg 16f80a6dcdSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17f80a6dcdSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18f80a6dcdSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19f80a6dcdSmrgIN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR 20f80a6dcdSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21f80a6dcdSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22f80a6dcdSmrgOTHER DEALINGS IN THE SOFTWARE. 23f80a6dcdSmrg 24f80a6dcdSmrgExcept as contained in this notice, the name of the X Consortium shall 25f80a6dcdSmrgnot be used in advertising or otherwise to promote the sale, use or 26f80a6dcdSmrgother dealings in this Software without prior written authorization 27f80a6dcdSmrgfrom the X Consortium. 28f80a6dcdSmrg 29f80a6dcdSmrg*/ 30f80a6dcdSmrg 31f80a6dcdSmrg 32f80a6dcdSmrg/* 33f80a6dcdSmrg * Dvi.c - Dvi display widget 34f80a6dcdSmrg */ 35f80a6dcdSmrg 36f80a6dcdSmrg#ifdef HAVE_CONFIG_H 37f80a6dcdSmrg# include "config.h" 38f80a6dcdSmrg#endif 39f80a6dcdSmrg 40f80a6dcdSmrg /* The following are defined for the reader's convenience. Any 41f80a6dcdSmrg Xt..Field macro in this code just refers to some field in 42f80a6dcdSmrg one of the substructures of the WidgetRec. */ 43f80a6dcdSmrg 44f80a6dcdSmrg#include <X11/IntrinsicP.h> 45f80a6dcdSmrg#include <X11/StringDefs.h> 46f80a6dcdSmrg#include <X11/Xmu/Converters.h> 47f80a6dcdSmrg#include <stdio.h> 48f80a6dcdSmrg#include <stdlib.h> 49f80a6dcdSmrg#include <unistd.h> 50f80a6dcdSmrg#include <ctype.h> 51f80a6dcdSmrg#include "DviP.h" 52f80a6dcdSmrg 53f80a6dcdSmrg/**************************************************************** 54f80a6dcdSmrg * 55f80a6dcdSmrg * Full class record constant 56f80a6dcdSmrg * 57f80a6dcdSmrg ****************************************************************/ 58f80a6dcdSmrg 59f80a6dcdSmrg/* Private Data */ 60f80a6dcdSmrg/* Note: default_font_map was too long a token for some machines... 618c7c3c7eSmrg * therefore it has been split in two and assigned to resources 62f80a6dcdSmrg * in the ClassInitialize routine. 63f80a6dcdSmrg */ 6400994698Smrgstatic const char *default_font_map_1 = "\ 65f80a6dcdSmrgR -*-times-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\ 66f80a6dcdSmrgI -*-times-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\ 67f80a6dcdSmrgB -*-times-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\ 68f80a6dcdSmrgF -*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\ 69f80a6dcdSmrgTR -*-times-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\ 70f80a6dcdSmrgTI -*-times-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\ 71f80a6dcdSmrgTB -*-times-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\ 72f80a6dcdSmrgTF -*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\ 73f80a6dcdSmrgBI -*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\ 74f80a6dcdSmrgC -*-courier-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\ 75f80a6dcdSmrgCO -*-courier-medium-o-normal--*-*-*-*-*-*-iso8859-1\n\ 76f80a6dcdSmrgCB -*-courier-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\ 77f80a6dcdSmrgCF -*-courier-bold-o-normal--*-*-*-*-*-*-iso8859-1\n\ 78f80a6dcdSmrgH -*-helvetica-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\ 79f80a6dcdSmrgHO -*-helvetica-medium-o-normal--*-*-*-*-*-*-iso8859-1\n\ 80f80a6dcdSmrgHB -*-helvetica-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\ 81f80a6dcdSmrgHF -*-helvetica-bold-o-normal--*-*-*-*-*-*-iso8859-1\n\ 82f80a6dcdSmrg"; 8300994698Smrgstatic const char *default_font_map_2 = "\ 84f80a6dcdSmrgN -*-new century schoolbook-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\ 85f80a6dcdSmrgNI -*-new century schoolbook-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\ 86f80a6dcdSmrgNB -*-new century schoolbook-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\ 87f80a6dcdSmrgNF -*-new century schoolbook-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\ 88f80a6dcdSmrgA -*-charter-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\ 89f80a6dcdSmrgAI -*-charter-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\ 90f80a6dcdSmrgAB -*-charter-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\ 91f80a6dcdSmrgAF -*-charter-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\ 92f80a6dcdSmrgS -*-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific\n\ 93f80a6dcdSmrgS2 -*-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific\n\ 94f80a6dcdSmrg"; 95f80a6dcdSmrg 96f80a6dcdSmrg#define offset(field) XtOffsetOf(DviRec, field) 97f80a6dcdSmrg 9800994698Smrgstatic XtResource resources[] = { 9900994698Smrg {XtNfontMap, XtCFontMap, XtRString, sizeof(char *), 10000994698Smrg offset(dvi.font_map_string), XtRString, NULL /* set in code */ }, 10100994698Smrg {XtNforeground, XtCForeground, XtRPixel, sizeof(unsigned long), 10200994698Smrg offset(dvi.foreground), XtRString, XtDefaultForeground}, 10300994698Smrg {XtNpageNumber, XtCPageNumber, XtRInt, sizeof(int), 10400994698Smrg offset(dvi.requested_page), XtRImmediate, (XtPointer) 1}, 10500994698Smrg {XtNlastPageNumber, XtCLastPageNumber, XtRInt, sizeof(int), 10600994698Smrg offset(dvi.last_page), XtRImmediate, (XtPointer) 0}, 10700994698Smrg {XtNfile, XtCFile, XtRFile, sizeof(FILE *), 10800994698Smrg offset(dvi.file), XtRFile, (char *) 0}, 10900994698Smrg {XtNseek, XtCSeek, XtRBoolean, sizeof(Boolean), 11000994698Smrg offset(dvi.seek), XtRImmediate, (XtPointer) False}, 11100994698Smrg {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), 11200994698Smrg offset(dvi.default_font), XtRString, XtDefaultFont}, 11300994698Smrg {XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof(int), 11400994698Smrg offset(dvi.backing_store), XtRString, "default"}, 11500994698Smrg {XtNnoPolyText, XtCNoPolyText, XtRBoolean, sizeof(Boolean), 11600994698Smrg offset(dvi.noPolyText), XtRImmediate, (XtPointer) False}, 11700994698Smrg {XtNscreenResolution, XtCScreenResolution, XtRInt, sizeof(int), 11800994698Smrg offset(dvi.screen_resolution), XtRImmediate, (XtPointer) 75}, 11900994698Smrg {XtNpageWidth, XtCPageWidth, XtRFloat, sizeof(float), 12000994698Smrg offset(dvi.page_width), XtRString, "8.5"}, 12100994698Smrg {XtNpageHeight, XtCPageHeight, XtRFloat, sizeof(float), 12200994698Smrg offset(dvi.page_height), XtRString, "11"}, 12300994698Smrg {XtNsizeScale, XtCSizeScale, XtRInt, sizeof(int), 12400994698Smrg offset(dvi.size_scale_set), XtRImmediate, (XtPointer) 0}, 125f80a6dcdSmrg}; 126f80a6dcdSmrg 127f80a6dcdSmrg#undef offset 128f80a6dcdSmrg 12900994698Smrgstatic void ClassInitialize(void); 13000994698Smrgstatic void Initialize(Widget, Widget, ArgList, Cardinal *); 13100994698Smrgstatic void Realize(Widget, XtValueMask *, XSetWindowAttributes *); 13200994698Smrgstatic void Destroy(Widget); 13300994698Smrgstatic void Redisplay(Widget, XEvent *, Region); 13400994698Smrgstatic Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *); 13500994698Smrgstatic Boolean SetValuesHook(Widget, ArgList, Cardinal *); 13600994698Smrgstatic XtGeometryResult QueryGeometry(Widget, 13700994698Smrg XtWidgetGeometry *, XtWidgetGeometry *); 13800994698Smrgstatic void RequestDesiredSize(DviWidget); 13900994698Smrgstatic void ShowDvi(DviWidget); 14000994698Smrgstatic void CloseFile(DviWidget); 14100994698Smrgstatic void OpenFile(DviWidget); 142f80a6dcdSmrg 143f80a6dcdSmrg#define SuperClass ((SimpleWidgetClass)&simpleClassRec) 144f80a6dcdSmrg 145f80a6dcdSmrgDviClassRec dviClassRec = { 14600994698Smrg { 14700994698Smrg (WidgetClass) SuperClass, /* superclass */ 14800994698Smrg "Dvi", /* class_name */ 14900994698Smrg sizeof(DviRec), /* size */ 15000994698Smrg ClassInitialize, /* class_initialize */ 15100994698Smrg NULL, /* class_part_initialize */ 15200994698Smrg FALSE, /* class_inited */ 15300994698Smrg Initialize, /* initialize */ 15400994698Smrg NULL, /* initialize_hook */ 15500994698Smrg Realize, /* realize */ 15600994698Smrg NULL, /* actions */ 15700994698Smrg 0, /* num_actions */ 15800994698Smrg resources, /* resources */ 15900994698Smrg XtNumber(resources), /* resource_count */ 16000994698Smrg NULLQUARK, /* xrm_class */ 16100994698Smrg FALSE, /* compress_motion */ 16200994698Smrg XtExposeCompressMaximal, /* compress_exposure */ 16300994698Smrg TRUE, /* compress_enterleave */ 16400994698Smrg FALSE, /* visible_interest */ 16500994698Smrg Destroy, /* destroy */ 16600994698Smrg NULL, /* resize */ 16700994698Smrg Redisplay, /* expose */ 16800994698Smrg SetValues, /* set_values */ 16900994698Smrg SetValuesHook, /* set_values_hook */ 17000994698Smrg XtInheritSetValuesAlmost, /* set_values_almost */ 17100994698Smrg NULL, /* get_values_hook */ 17200994698Smrg NULL, /* accept_focus */ 17300994698Smrg XtVersion, /* version */ 17400994698Smrg NULL, /* callback_private */ 17500994698Smrg NULL, /* tm_table */ 17600994698Smrg QueryGeometry, /* query_geometry */ 17700994698Smrg XtInheritDisplayAccelerator, /* display_accelerator */ 17800994698Smrg NULL, /* extension */ 17900994698Smrg }, /* CoreClass fields initialization */ 18000994698Smrg { 18100994698Smrg XtInheritChangeSensitive /* change_sensitive */ 18200994698Smrg }, /* SimpleClass fields initialization */ 18300994698Smrg { 18400994698Smrg 0, /* field not used */ 18500994698Smrg }, /* DviClass fields initialization */ 186f80a6dcdSmrg}; 187f80a6dcdSmrg 188f80a6dcdSmrgWidgetClass dviWidgetClass = (WidgetClass) &dviClassRec; 189f80a6dcdSmrg 190f80a6dcdSmrgstatic void 19100994698SmrgClassInitialize(void) 192f80a6dcdSmrg{ 19300994698Smrg size_t len1 = strlen(default_font_map_1); 19400994698Smrg size_t len2 = strlen(default_font_map_2); 19500994698Smrg char *dfm = XtMalloc(len1 + len2 + 1); 19600994698Smrg char *ptr = dfm; 19700994698Smrg 19800994698Smrg memcpy(ptr, default_font_map_1, len1); 19900994698Smrg ptr += len1; 20000994698Smrg memcpy(ptr, default_font_map_2, len2); 20100994698Smrg ptr[len2] = '\0'; 20200994698Smrg resources[0].default_addr = dfm; 20300994698Smrg 20400994698Smrg XtAddConverter(XtRString, XtRBackingStore, XmuCvtStringToBackingStore, 20500994698Smrg NULL, 0); 206f80a6dcdSmrg} 207f80a6dcdSmrg 208f80a6dcdSmrg/**************************************************************** 209f80a6dcdSmrg * 210f80a6dcdSmrg * Private Procedures 211f80a6dcdSmrg * 212f80a6dcdSmrg ****************************************************************/ 213f80a6dcdSmrg 214f80a6dcdSmrg/* ARGSUSED */ 215f80a6dcdSmrgstatic void 21665912f00SmrgInitialize(Widget request, Widget new, ArgList args, Cardinal *num_args) 217f80a6dcdSmrg{ 21800994698Smrg DviWidget dw = (DviWidget) new; 219f80a6dcdSmrg 22065912f00Smrg dw->dvi.tmpFile = NULL; 221f80a6dcdSmrg dw->dvi.readingTmp = 0; 222f80a6dcdSmrg dw->dvi.ungot = 0; 22365912f00Smrg dw->dvi.normal_GC = NULL; 22465912f00Smrg dw->dvi.file_map = NULL; 22565912f00Smrg dw->dvi.fonts = NULL; 22665912f00Smrg dw->dvi.font_map = NULL; 227f80a6dcdSmrg dw->dvi.current_page = 0; 228f80a6dcdSmrg dw->dvi.font_size = 0; 229f80a6dcdSmrg dw->dvi.font_number = 0; 230f80a6dcdSmrg dw->dvi.device_resolution = 0; 231f80a6dcdSmrg dw->dvi.line_width = 0; 232f80a6dcdSmrg dw->dvi.line_style = 0; 23365912f00Smrg dw->dvi.font = NULL; 234f80a6dcdSmrg dw->dvi.display_enable = 0; 235f80a6dcdSmrg dw->dvi.scale = 0.0; 23665912f00Smrg dw->dvi.state = NULL; 237f80a6dcdSmrg dw->dvi.cache.index = 0; 23800994698Smrg dw->dvi.cache.font = NULL; 239f80a6dcdSmrg dw->dvi.size_scale = 0; 240f80a6dcdSmrg dw->dvi.size_scale_set = 0; 24100994698Smrg RequestDesiredSize(dw); 242f80a6dcdSmrg} 243f80a6dcdSmrg 244f80a6dcdSmrgstatic void 24500994698SmrgRealize(Widget w, XtValueMask * valueMask, XSetWindowAttributes *attrs) 246f80a6dcdSmrg{ 24700994698Smrg DviWidget dw = (DviWidget) w; 24800994698Smrg XGCValues values; 249f80a6dcdSmrg 250f80a6dcdSmrg if (dw->dvi.backing_store != Always + WhenMapped + NotUseful) { 25100994698Smrg attrs->backing_store = dw->dvi.backing_store; 25200994698Smrg *valueMask |= CWBackingStore; 253f80a6dcdSmrg } 25400994698Smrg XtCreateWindow(w, (unsigned) InputOutput, (Visual *) CopyFromParent, 25500994698Smrg *valueMask, attrs); 256f80a6dcdSmrg values.foreground = dw->dvi.foreground; 25700994698Smrg dw->dvi.normal_GC = XCreateGC(XtDisplay(w), XtWindow(w), 25800994698Smrg GCForeground, &values); 259f80a6dcdSmrg#ifdef USE_XFT 260f80a6dcdSmrg { 26100994698Smrg int scr = XScreenNumberOfScreen(dw->core.screen); 26200994698Smrg Visual *visual = DefaultVisual(XtDisplay(w), scr); 26300994698Smrg Colormap cmap = DefaultColormap(XtDisplay(w), scr); 26400994698Smrg dw->dvi.draw = XftDrawCreate(XtDisplay(w), XtWindow(w), visual, cmap); 26500994698Smrg 26600994698Smrg XRenderColor black = { 26700994698Smrg .red = 0, 26800994698Smrg .green = 0, 26900994698Smrg .blue = 0, 27000994698Smrg .alpha = 0xffff 27100994698Smrg }; 27200994698Smrg XftColorAllocValue(XtDisplay(w), visual, cmap, &black, &dw->dvi.black); 27300994698Smrg dw->dvi.default_font = XftFontOpenName(XtDisplay(w), scr, "serif-12"); 274f80a6dcdSmrg } 275f80a6dcdSmrg#endif 276f80a6dcdSmrg if (dw->dvi.file) 27700994698Smrg OpenFile(dw); 27800994698Smrg ParseFontMap(dw); 279f80a6dcdSmrg} 280f80a6dcdSmrg 281f80a6dcdSmrgstatic void 28265912f00SmrgDestroy(Widget w) 283f80a6dcdSmrg{ 28400994698Smrg DviWidget dw = (DviWidget) w; 285f80a6dcdSmrg 28600994698Smrg XFreeGC(XtDisplay(w), dw->dvi.normal_GC); 28700994698Smrg DestroyFontMap(dw->dvi.font_map); 28800994698Smrg DestroyFileMap(dw->dvi.file_map); 289f80a6dcdSmrg} 290f80a6dcdSmrg 291f80a6dcdSmrg/* 292f80a6dcdSmrg * Repaint the widget window 293f80a6dcdSmrg */ 294f80a6dcdSmrg 295f80a6dcdSmrg/* ARGSUSED */ 296f80a6dcdSmrgstatic void 29765912f00SmrgRedisplay(Widget w, XEvent *event, Region region) 298f80a6dcdSmrg{ 29900994698Smrg DviWidget dw = (DviWidget) w; 30000994698Smrg 301f80a6dcdSmrg#ifndef USE_XFT 30200994698Smrg XRectangle extents; 303f80a6dcdSmrg#endif 30400994698Smrg 305f80a6dcdSmrg#ifdef USE_XFT 30600994698Smrg XClearArea(XtDisplay(dw), XtWindow(dw), 0, 0, 0, 0, False); 30700994698Smrg dw->dvi.extents.x1 = 0; 30800994698Smrg dw->dvi.extents.y1 = 0; 30900994698Smrg dw->dvi.extents.x2 = dw->core.width; 31000994698Smrg dw->dvi.extents.y2 = dw->core.height; 311f80a6dcdSmrg#else 31200994698Smrg XClipBox(region, &extents); 31300994698Smrg dw->dvi.extents.x1 = extents.x; 31400994698Smrg dw->dvi.extents.y1 = extents.y; 31500994698Smrg dw->dvi.extents.x2 = extents.x + extents.width; 31600994698Smrg dw->dvi.extents.y2 = extents.y + extents.height; 317f80a6dcdSmrg#endif 31800994698Smrg ShowDvi(dw); 319f80a6dcdSmrg} 320f80a6dcdSmrg 321f80a6dcdSmrgstatic void 32200994698SmrgRequestDesiredSize(DviWidget dw) 323f80a6dcdSmrg{ 32400994698Smrg XtWidgetGeometry req, rep; 325f80a6dcdSmrg 32600994698Smrg dw->dvi.desired_width = dw->dvi.page_width * dw->dvi.screen_resolution; 32700994698Smrg dw->dvi.desired_height = dw->dvi.page_height * dw->dvi.screen_resolution; 32800994698Smrg req.request_mode = CWWidth | CWHeight; 329f80a6dcdSmrg req.width = dw->dvi.desired_width; 330f80a6dcdSmrg req.height = dw->dvi.desired_height; 33100994698Smrg XtMakeGeometryRequest((Widget) dw, &req, &rep); 332f80a6dcdSmrg} 333f80a6dcdSmrg 334f80a6dcdSmrg/* 335f80a6dcdSmrg * Set specified arguments into widget 336f80a6dcdSmrg */ 337f80a6dcdSmrg/* ARGSUSED */ 338f80a6dcdSmrgstatic Boolean 33900994698SmrgSetValues(Widget wcurrent, Widget wrequest, Widget wnew, 34000994698Smrg ArgList args, Cardinal *num_args) 341f80a6dcdSmrg{ 34200994698Smrg DviWidget current = (DviWidget) wcurrent; 34300994698Smrg DviWidget request = (DviWidget) wrequest; 34400994698Smrg DviWidget new = (DviWidget) wnew; 34500994698Smrg Boolean redisplay = FALSE; 34600994698Smrg 34700994698Smrg int req = request->dvi.requested_page; 34800994698Smrg int cur = current->dvi.requested_page; 349f80a6dcdSmrg if (cur != req) { 35000994698Smrg if (req < 1) 35100994698Smrg req = 1; 35200994698Smrg if (request->dvi.file) { 35300994698Smrg if (current->dvi.last_page != 0 && req > current->dvi.last_page) 35400994698Smrg req = current->dvi.last_page; 35500994698Smrg } 35600994698Smrg if (cur != req) 35700994698Smrg redisplay = TRUE; 35800994698Smrg new->dvi.requested_page = req; 359f80a6dcdSmrg } 36000994698Smrg 361f80a6dcdSmrg if (current->dvi.font_map_string != request->dvi.font_map_string) { 36200994698Smrg size_t map_len = strlen (request->dvi.font_map_string) + 1; 36300994698Smrg char * new_map = XtMalloc (map_len); 36400994698Smrg 36500994698Smrg if (new_map) { 36600994698Smrg redisplay = TRUE; 36700994698Smrg memcpy(new_map, request->dvi.font_map_string, map_len); 36800994698Smrg new->dvi.font_map_string = new_map; 36900994698Smrg if (current->dvi.font_map_string) 37000994698Smrg XtFree(current->dvi.font_map_string); 37100994698Smrg current->dvi.font_map_string = NULL; 37200994698Smrg ParseFontMap(new); 37300994698Smrg } 374f80a6dcdSmrg } 37500994698Smrg if (current->dvi.screen_resolution != request->dvi.screen_resolution) { 37600994698Smrg ResetFonts(new); 37700994698Smrg new->dvi.line_width = -1; 378f80a6dcdSmrg } 379f80a6dcdSmrg if (request->dvi.device_resolution) 38000994698Smrg new->dvi.scale = ((double) request->dvi.screen_resolution) / 38100994698Smrg ((double) request->dvi.device_resolution); 38200994698Smrg if (current->dvi.page_width != request->dvi.page_width || 38300994698Smrg current->dvi.page_height != request->dvi.page_height || 38400994698Smrg current->dvi.screen_resolution != request->dvi.screen_resolution) { 38500994698Smrg RequestDesiredSize(new); 38600994698Smrg redisplay = TRUE; 387f80a6dcdSmrg } 388f80a6dcdSmrg return redisplay; 389f80a6dcdSmrg} 390f80a6dcdSmrg 391f80a6dcdSmrg/* 392f80a6dcdSmrg * use the set_values_hook entry to check when 393f80a6dcdSmrg * the file is set 394f80a6dcdSmrg */ 395f80a6dcdSmrg 396f80a6dcdSmrgstatic Boolean 39700994698SmrgSetValuesHook(Widget widget, ArgList args, Cardinal *num_argsp) 398f80a6dcdSmrg{ 39900994698Smrg DviWidget dw = (DviWidget) widget; 40000994698Smrg 40100994698Smrg for (Cardinal i = 0; i < *num_argsp; i++) { 40200994698Smrg if (!strcmp(args[i].name, XtNfile)) { 40300994698Smrg CloseFile(dw); 40400994698Smrg OpenFile(dw); 40500994698Smrg return TRUE; 40600994698Smrg } 40700994698Smrg } 40800994698Smrg return FALSE; 409f80a6dcdSmrg} 410f80a6dcdSmrg 411f80a6dcdSmrgstatic void 41200994698SmrgCloseFile(DviWidget dw) 413f80a6dcdSmrg{ 414f80a6dcdSmrg if (dw->dvi.tmpFile) 41500994698Smrg fclose(dw->dvi.tmpFile); 41600994698Smrg ForgetPagePositions(dw); 417f80a6dcdSmrg} 418f80a6dcdSmrg 419f80a6dcdSmrgstatic void 42000994698SmrgOpenFile(DviWidget dw) 421f80a6dcdSmrg{ 42265912f00Smrg dw->dvi.tmpFile = NULL; 423f80a6dcdSmrg if (!dw->dvi.seek) { 42400994698Smrg char tmpName[] = "/tmp/dviXXXXXX"; 425c166fba9Smrg 426f80a6dcdSmrg#ifndef HAS_MKSTEMP 42700994698Smrg mktemp(tmpName); 42800994698Smrg dw->dvi.tmpFile = fopen(tmpName, "w+"); 429f80a6dcdSmrg#else 43000994698Smrg int fd = mkstemp(tmpName); 43100994698Smrg 43200994698Smrg if (fd != -1) { 43300994698Smrg dw->dvi.tmpFile = fdopen(fd, "w+"); 43400994698Smrg if (dw->dvi.tmpFile == NULL) 43500994698Smrg close(fd); 43600994698Smrg } 437f80a6dcdSmrg#endif 43800994698Smrg remove(tmpName); 439f80a6dcdSmrg } 440f80a6dcdSmrg if (dw->dvi.requested_page < 1) 44100994698Smrg dw->dvi.requested_page = 1; 442f80a6dcdSmrg dw->dvi.last_page = 0; 443f80a6dcdSmrg} 444f80a6dcdSmrg 445f80a6dcdSmrgstatic XtGeometryResult 44600994698SmrgQueryGeometry(Widget w, XtWidgetGeometry *request, 44700994698Smrg XtWidgetGeometry *geometry_return) 448f80a6dcdSmrg{ 44900994698Smrg XtGeometryResult ret = XtGeometryYes; 45000994698Smrg DviWidget dw = (DviWidget) w; 45100994698Smrg 45200994698Smrg if ((int) request->width < dw->dvi.desired_width 45300994698Smrg || (int) request->height < dw->dvi.desired_height) 45400994698Smrg ret = XtGeometryAlmost; 45500994698Smrg geometry_return->width = dw->dvi.desired_width; 45600994698Smrg geometry_return->height = dw->dvi.desired_height; 45700994698Smrg geometry_return->request_mode = CWWidth | CWHeight; 45800994698Smrg return ret; 459f80a6dcdSmrg} 460f80a6dcdSmrg 461f80a6dcdSmrgvoid 46200994698SmrgSetDeviceResolution(DviWidget dw, int resolution) 463f80a6dcdSmrg{ 464f80a6dcdSmrg if (resolution != dw->dvi.device_resolution) { 46500994698Smrg dw->dvi.device_resolution = resolution; 46600994698Smrg dw->dvi.scale = ((double) dw->dvi.screen_resolution) / 46700994698Smrg ((double) resolution); 468f80a6dcdSmrg } 469f80a6dcdSmrg} 470f80a6dcdSmrg 471f80a6dcdSmrgstatic void 47200994698SmrgShowDvi(DviWidget dw) 473f80a6dcdSmrg{ 47400994698Smrg long file_position; 47500994698Smrg 47600994698Smrg if (!dw->dvi.file) 47700994698Smrg return; 47800994698Smrg 47900994698Smrg if (dw->dvi.requested_page < 1) 48000994698Smrg dw->dvi.requested_page = 1; 48100994698Smrg 48200994698Smrg if (dw->dvi.last_page != 0 && dw->dvi.requested_page > dw->dvi.last_page) 48300994698Smrg dw->dvi.requested_page = dw->dvi.last_page; 48400994698Smrg 48500994698Smrg file_position = SearchPagePosition(dw, dw->dvi.requested_page); 48600994698Smrg if (file_position != -1) { 48700994698Smrg FileSeek(dw, file_position); 48800994698Smrg dw->dvi.current_page = dw->dvi.requested_page; 48900994698Smrg } 49000994698Smrg else { 49100994698Smrg int i; 49200994698Smrg 49300994698Smrg for (i = dw->dvi.requested_page; i > 0; i--) { 49400994698Smrg file_position = SearchPagePosition(dw, i); 49500994698Smrg if (file_position != -1) 49600994698Smrg break; 49700994698Smrg } 49800994698Smrg if (file_position == -1) 49900994698Smrg file_position = 0; 50000994698Smrg FileSeek(dw, file_position); 50100994698Smrg 50200994698Smrg dw->dvi.current_page = i; 50300994698Smrg 50400994698Smrg dw->dvi.display_enable = 0; 50500994698Smrg while (dw->dvi.current_page != dw->dvi.requested_page) { 50600994698Smrg dw->dvi.current_page = ParseInput(dw); 50700994698Smrg /* 50800994698Smrg * at EOF, seek back to the beginning of this page. 50900994698Smrg */ 51000994698Smrg if (feof(dw->dvi.file)) { 51100994698Smrg file_position = SearchPagePosition(dw, dw->dvi.current_page); 51200994698Smrg if (file_position != -1) 51300994698Smrg FileSeek(dw, file_position); 51400994698Smrg break; 51500994698Smrg } 51600994698Smrg } 51700994698Smrg } 51800994698Smrg 51900994698Smrg dw->dvi.display_enable = 1; 52000994698Smrg ParseInput(dw); 52100994698Smrg if (dw->dvi.last_page && dw->dvi.requested_page > dw->dvi.last_page) 52200994698Smrg dw->dvi.requested_page = dw->dvi.last_page; 523f80a6dcdSmrg} 524