home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / xditview / Dvi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-26  |  13.8 KB  |  478 lines

  1. /* $XConsortium: Dvi.c,v 1.18 91/07/26 15:21:52 keith Exp $ */
  2. /*
  3.  * Copyright 1991 Massachusetts Institute of Technology
  4.  *
  5.  * Permission to use, copy, modify, distribute, and sell this software and its
  6.  * documentation for any purpose is hereby granted without fee, provided that
  7.  * the above copyright notice appear in all copies and that both that
  8.  * copyright notice and this permission notice appear in supporting
  9.  * documentation, and that the name of M.I.T. not be used in advertising or
  10.  * publicity pertaining to distribution of the software without specific,
  11.  * written prior permission.  M.I.T. makes no representations about the
  12.  * suitability of this software for any purpose.  It is provided "as is"
  13.  * without express or implied warranty.
  14.  *
  15.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  16.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  17.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  18.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  19.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  20.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21.  *
  22.  */
  23.  
  24. /*
  25.  * Dvi.c - Dvi display widget
  26.  */
  27.  
  28. #define XtStrlen(s)    ((s) ? strlen(s) : 0)
  29.  
  30.   /* The following are defined for the reader's convenience.  Any
  31.      Xt..Field macro in this code just refers to some field in
  32.      one of the substructures of the WidgetRec.  */
  33.  
  34. #include <X11/IntrinsicP.h>
  35. #include <X11/StringDefs.h>
  36. #include <X11/Xmu/Converters.h>
  37. #include <stdio.h>
  38. #include <ctype.h>
  39. #include "DviP.h"
  40.  
  41. /****************************************************************
  42.  *
  43.  * Full class record constant
  44.  *
  45.  ****************************************************************/
  46.  
  47. /* Private Data */
  48. /* Note: default_font_map was too long a token for some machines...
  49.  *       therefor it has been split in to and assigned to resources
  50.  *       in the ClassInitialize routine.
  51.  */
  52. static char default_font_map_1[] =  "\
  53. R    -*-times-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
  54. I    -*-times-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
  55. B    -*-times-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
  56. F    -*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
  57. BI    -*-times-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
  58. C    -*-courier-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
  59. CO    -*-courier-medium-o-normal--*-*-*-*-*-*-iso8859-1\n\
  60. CB    -*-courier-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
  61. CF    -*-courier-bold-o-normal--*-*-*-*-*-*-iso8859-1\n\
  62. H    -*-helvetica-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
  63. HO    -*-helvetica-medium-o-normal--*-*-*-*-*-*-iso8859-1\n\
  64. HB    -*-helvetica-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
  65. HF    -*-helvetica-bold-o-normal--*-*-*-*-*-*-iso8859-1\n\
  66. ";
  67. static char default_font_map_2[] =  "\
  68. N    -*-new century schoolbook-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
  69. NI    -*-new century schoolbook-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
  70. NB    -*-new century schoolbook-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
  71. NF    -*-new century schoolbook-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
  72. A    -*-charter-medium-r-normal--*-*-*-*-*-*-iso8859-1\n\
  73. AI    -*-charter-medium-i-normal--*-*-*-*-*-*-iso8859-1\n\
  74. AB    -*-charter-bold-r-normal--*-*-*-*-*-*-iso8859-1\n\
  75. AF    -*-charter-bold-i-normal--*-*-*-*-*-*-iso8859-1\n\
  76. S    -*-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific\n\
  77. S2    -*-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific\n\
  78. ";
  79.  
  80. #define offset(field) XtOffsetOf(DviRec, field)
  81.  
  82. static XtResource resources[] = { 
  83.     {XtNfontMap, XtCFontMap, XtRString, sizeof (char *),
  84.      offset(dvi.font_map_string), XtRString, NULL /* set in code */},
  85.     {XtNforeground, XtCForeground, XtRPixel, sizeof (unsigned long),
  86.      offset(dvi.foreground), XtRString, XtDefaultForeground},
  87.     {XtNpageNumber, XtCPageNumber, XtRInt, sizeof (int),
  88.      offset(dvi.requested_page), XtRImmediate, (XtPointer) 1},
  89.     {XtNlastPageNumber, XtCLastPageNumber, XtRInt, sizeof (int),
  90.      offset (dvi.last_page), XtRImmediate, (XtPointer) 0},
  91.     {XtNfile, XtCFile, XtRFile, sizeof (FILE *),
  92.      offset (dvi.file), XtRFile, (char *) 0},
  93.     {XtNseek, XtCSeek, XtRBoolean, sizeof (Boolean),
  94.      offset(dvi.seek), XtRImmediate, (XtPointer) False},
  95.     {XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
  96.      offset(dvi.default_font), XtRString, XtDefaultFont},
  97.     {XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof (int),
  98.      offset(dvi.backing_store), XtRString, "default"},
  99.     {XtNnoPolyText, XtCNoPolyText, XtRBoolean, sizeof (Boolean),
  100.      offset(dvi.noPolyText), XtRImmediate, (XtPointer) False},
  101.     {XtNscreenResolution, XtCScreenResolution, XtRInt, sizeof (int),
  102.      offset(dvi.screen_resolution), XtRImmediate, (XtPointer) 75},
  103.     {XtNpageWidth, XtCPageWidth, XtRFloat, sizeof (float),
  104.      offset(dvi.page_width), XtRString, "8.5"},
  105.     {XtNpageHeight, XtCPageHeight, XtRFloat, sizeof (float),
  106.      offset(dvi.page_height), XtRString, "11"},
  107. };
  108.  
  109. #undef offset
  110.  
  111. static void        ClassInitialize ();
  112. static void        Initialize(), Realize (), Destroy (), Redisplay ();
  113. static Boolean        SetValues (), SetValuesHook ();
  114. static XtGeometryResult    QueryGeometry ();
  115. static void        ShowDvi ();
  116. static void        CloseFile (), OpenFile ();
  117.  
  118. #define SuperClass ((SimpleWidgetClass)&simpleClassRec)
  119.  
  120. DviClassRec dviClassRec = {
  121. {
  122.     (WidgetClass) SuperClass,    /* superclass          */    
  123.     "Dvi",                /* class_name          */
  124.     sizeof(DviRec),            /* size              */
  125.     ClassInitialize,        /* class_initialize      */
  126.     NULL,                /* class_part_initialize  */
  127.     FALSE,                /* class_inited          */
  128.     Initialize,            /* initialize          */
  129.     NULL,                /* initialize_hook      */
  130.     Realize,            /* realize          */
  131.     NULL,                /* actions          */
  132.     0,                /* num_actions          */
  133.     resources,            /* resources          */
  134.     XtNumber(resources),        /* resource_count      */
  135.     NULLQUARK,            /* xrm_class          */
  136.     FALSE,                /* compress_motion      */
  137.     TRUE,                /* compress_exposure      */
  138.     TRUE,                /* compress_enterleave    */
  139.     FALSE,                /* visible_interest      */
  140.     Destroy,            /* destroy          */
  141.     NULL,                /* resize          */
  142.     Redisplay,            /* expose          */
  143.     SetValues,            /* set_values          */
  144.     SetValuesHook,            /* set_values_hook      */
  145.     XtInheritSetValuesAlmost,    /* set_values_almost      */
  146.     NULL,                /* get_values_hook      */
  147.     NULL,                /* accept_focus          */
  148.     XtVersion,            /* version          */
  149.     NULL,                /* callback_private      */
  150.     0,                /* tm_table          */
  151.     QueryGeometry,            /* query_geometry      */
  152.     XtInheritDisplayAccelerator,    /* display_accelerator      */
  153.     NULL,                /* extension          */
  154. },  /* CoreClass fields initialization */
  155. {
  156.     XtInheritChangeSensitive        /* change_sensitive    */
  157. },  /* SimpleClass fields initialization */
  158. {
  159.     0,                                     /* field not used    */
  160. },  /* DviClass fields initialization */
  161. };
  162.  
  163. WidgetClass dviWidgetClass = (WidgetClass) &dviClassRec;
  164.  
  165. static void ClassInitialize ()
  166. {
  167.   int len1 = strlen(default_font_map_1);
  168.   int len2 = strlen(default_font_map_2);
  169.   char *dfm = XtMalloc(len1 + len2 + 1);
  170.   char *ptr = dfm;
  171.   strcpy(ptr, default_font_map_1); ptr += len1;
  172.   strcpy(ptr, default_font_map_2); 
  173.   resources[0].default_addr = dfm;
  174.  
  175.   XtAddConverter( XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
  176.          NULL, 0 );
  177. }
  178.  
  179. /****************************************************************
  180.  *
  181.  * Private Procedures
  182.  *
  183.  ****************************************************************/
  184.  
  185. /* ARGSUSED */
  186. static void Initialize(request, new)
  187.     Widget request, new;
  188. {
  189.     DviWidget    dw = (DviWidget) new;
  190.  
  191.     dw->dvi.current_page = 0;
  192.     dw->dvi.font_map = 0;
  193.     dw->dvi.cache.index = 0;
  194.     dw->dvi.file = 0;
  195.     dw->dvi.seek = False;
  196.     dw->dvi.device_resolution = 75;
  197.     dw->dvi.tmpFile = 0;
  198.     dw->dvi.readingTmp = 0;
  199.     dw->dvi.ungot = 0;
  200.     dw->dvi.file_map = 0;
  201.     dw->dvi.fonts = 0;
  202.     dw->dvi.font_map = 0;
  203.     dw->dvi.current_page = 0;
  204.     dw->dvi.font_size = 0;
  205.     dw->dvi.font_number = 0;
  206.     dw->dvi.device_resolution = 0;
  207.     dw->dvi.line_width = 0;
  208.     dw->dvi.backing_store = 0;
  209.     dw->dvi.font = 0;
  210.     dw->dvi.display_enable = 0;
  211.     dw->dvi.state = 0;
  212.     dw->dvi.cache.font = 0; 
  213.     RequestDesiredSize (dw);
  214. }
  215.  
  216. static void
  217. Realize (w, valueMask, attrs)
  218.     Widget            w;
  219.     XtValueMask        *valueMask;
  220.     XSetWindowAttributes    *attrs;
  221. {
  222.     DviWidget    dw = (DviWidget) w;
  223.     XGCValues    values;
  224.  
  225.     if (dw->dvi.backing_store != Always + WhenMapped + NotUseful) {
  226.     attrs->backing_store = dw->dvi.backing_store;
  227.     *valueMask |= CWBackingStore;
  228.     }
  229.     XtCreateWindow (w, (unsigned)InputOutput, (Visual *) CopyFromParent,
  230.             *valueMask, attrs);
  231.     values.foreground = dw->dvi.foreground;
  232.     dw->dvi.normal_GC = XCreateGC (XtDisplay (w), XtWindow (w),
  233.                     GCForeground, &values);
  234.     if (dw->dvi.file)
  235.     OpenFile (dw);
  236.     ParseFontMap (dw);
  237. }
  238.  
  239. static void
  240. Destroy(w)
  241.     Widget w;
  242. {
  243.     DviWidget    dw = (DviWidget) w;
  244.  
  245.     XFreeGC (XtDisplay (w), dw->dvi.normal_GC);
  246.     DestroyFontMap (dw->dvi.font_map);
  247.     DestroyFileMap (dw->dvi.file_map);
  248. }
  249.  
  250. /*
  251.  * Repaint the widget window
  252.  */
  253.  
  254. /* ARGSUSED */
  255. static void
  256. Redisplay(w, event, region)
  257.     Widget w;
  258.     XEvent *event;
  259.     Region region;
  260. {
  261.     DviWidget    dw = (DviWidget) w;
  262.     XRectangle    extents;
  263.     
  264.     XClipBox (region, &extents);
  265.     dw->dvi.extents.x1 = extents.x;
  266.     dw->dvi.extents.y1 = extents.y;
  267.     dw->dvi.extents.x2 = extents.x + extents.width;
  268.     dw->dvi.extents.y2 = extents.y + extents.height;
  269.     ShowDvi (dw);
  270. }
  271.  
  272. RequestDesiredSize (dw)
  273.     DviWidget    dw;
  274. {
  275.     XtWidgetGeometry    req, rep;
  276.  
  277.     dw->dvi.desired_width = dw->dvi.page_width *
  278.                  dw->dvi.screen_resolution;
  279.     dw->dvi.desired_height = dw->dvi.page_height *
  280.                   dw->dvi.screen_resolution;
  281.     req.request_mode = CWWidth|CWHeight;
  282.     req.width = dw->dvi.desired_width;
  283.     req.height = dw->dvi.desired_height;
  284.     XtMakeGeometryRequest ((Widget) dw, &req, &rep);
  285. }
  286.  
  287. /*
  288.  * Set specified arguments into widget
  289.  */
  290. /* ARGSUSED */
  291. static Boolean
  292. SetValues (current, request, new)
  293.     DviWidget current, request, new;
  294. {
  295.     Boolean        redisplay = FALSE;
  296.     char        *new_map;
  297.     int        cur, req;
  298.  
  299.     req = request->dvi.requested_page;
  300.     cur = current->dvi.requested_page;
  301.     if (cur != req) {
  302.         if (req < 1)
  303.         req = 1;
  304.         if (request->dvi.file)
  305.         {
  306.         if (current->dvi.last_page != 0 &&
  307.             req > current->dvi.last_page)
  308.             req = current->dvi.last_page;
  309.         }
  310.         if (cur != req)
  311.         redisplay = TRUE;
  312.         new->dvi.requested_page = req;
  313.     }
  314.     
  315.     if (current->dvi.font_map_string != request->dvi.font_map_string) {
  316.         new_map = XtMalloc (strlen (request->dvi.font_map_string) + 1);
  317.         if (new_map) {
  318.             redisplay = TRUE;
  319.             strcpy (new_map, request->dvi.font_map_string);
  320.             new->dvi.font_map_string = new_map;
  321.             if (current->dvi.font_map_string)
  322.                 XtFree (current->dvi.font_map_string);
  323.             current->dvi.font_map_string = 0;
  324.             ParseFontMap (new);
  325.         }
  326.     }
  327.     if (current->dvi.screen_resolution != request->dvi.screen_resolution)
  328.     {
  329.     ResetFonts (new);
  330.     new->dvi.line_width = -1;
  331.     }
  332.     if (request->dvi.device_resolution)
  333.     new->dvi.scale = ((double) request->dvi.screen_resolution) /
  334.                  ((double) request->dvi.device_resolution);
  335.     if (current->dvi.page_width !=  request->dvi.page_width ||
  336.     current->dvi.page_height != request->dvi.page_height ||
  337.     current->dvi.screen_resolution != request->dvi.screen_resolution)
  338.     {
  339.     RequestDesiredSize (new);
  340.     redisplay = TRUE;
  341.     }
  342.     return redisplay;
  343. }
  344.  
  345. /*
  346.  * use the set_values_hook entry to check when
  347.  * the file is set
  348.  */
  349.  
  350. static Boolean
  351. SetValuesHook (dw, args, num_argsp)
  352.     DviWidget    dw;
  353.     ArgList        args;
  354.     Cardinal    *num_argsp;
  355. {
  356.     Cardinal    i;
  357.  
  358.     for (i = 0; i < *num_argsp; i++) {
  359.         if (!strcmp (args[i].name, XtNfile)) {
  360.             CloseFile (dw);
  361.             OpenFile (dw);
  362.             return TRUE;
  363.         }
  364.     }
  365.     return FALSE;
  366. }
  367.  
  368. static void CloseFile (dw)
  369.     DviWidget    dw;
  370. {
  371.     if (dw->dvi.tmpFile)
  372.     fclose (dw->dvi.tmpFile);
  373.     ForgetPagePositions (dw);
  374. }
  375.  
  376. static void OpenFile (dw)
  377.     DviWidget    dw;
  378. {
  379.     char    tmpName[sizeof ("/tmp/dviXXXXXX")];
  380.  
  381.     dw->dvi.tmpFile = 0;
  382.     if (!dw->dvi.seek) {
  383.     strcpy (tmpName, "/tmp/dviXXXXXX");
  384.     mktemp (tmpName);
  385.     dw->dvi.tmpFile = fopen (tmpName, "w+");
  386.     unlink (tmpName);
  387.     }
  388.     if (dw->dvi.requested_page < 1)
  389.     dw->dvi.requested_page = 1;
  390.     dw->dvi.last_page = 0;
  391. }
  392.  
  393. static XtGeometryResult
  394. QueryGeometry (w, request, geometry_return)
  395.     Widget            w;
  396.     XtWidgetGeometry    *request, *geometry_return;
  397. {
  398.     XtGeometryResult    ret;
  399.     DviWidget        dw = (DviWidget) w;
  400.  
  401.     ret = XtGeometryYes;
  402.     if ((int)request->width < dw->dvi.desired_width
  403.         || (int)request->height < dw->dvi.desired_height)
  404.         ret = XtGeometryAlmost;
  405.     geometry_return->width = dw->dvi.desired_width;
  406.     geometry_return->height = dw->dvi.desired_height;
  407.     geometry_return->request_mode = CWWidth|CWHeight;
  408.     return ret;
  409. }
  410.  
  411. SetDeviceResolution (dw, resolution)
  412.     DviWidget   dw;
  413.     int        resolution;
  414. {
  415.     if (resolution != dw->dvi.device_resolution) {
  416.     dw->dvi.device_resolution = resolution;
  417.     dw->dvi.scale = ((double)  dw->dvi.screen_resolution) /
  418.             ((double) resolution);
  419.     if (dw->dvi.state)
  420.         dw->dvi.state->line_width =
  421.         FontSizeInDevice(dw, dw->dvi.state->line_width/10.0);
  422.     }
  423. }
  424.  
  425. static void
  426. ShowDvi (dw)
  427.     DviWidget    dw;
  428. {
  429.     int    i;
  430.     long    file_position;
  431.  
  432.     if (!dw->dvi.file) 
  433.       return;
  434.  
  435.     if (dw->dvi.requested_page < 1)
  436.         dw->dvi.requested_page = 1;
  437.  
  438.     if (dw->dvi.last_page != 0 && dw->dvi.requested_page > dw->dvi.last_page)
  439.         dw->dvi.requested_page = dw->dvi.last_page;
  440.  
  441.     file_position = SearchPagePosition (dw, dw->dvi.requested_page);
  442.     if (file_position != -1) {
  443.         FileSeek(dw, file_position);
  444.         dw->dvi.current_page = dw->dvi.requested_page;
  445.     } else {
  446.         for (i=dw->dvi.requested_page; i > 0; i--) {
  447.             file_position = SearchPagePosition (dw, i);
  448.             if (file_position != -1)
  449.                 break;
  450.         }
  451.         if (file_position == -1)
  452.             file_position = 0;
  453.         FileSeek (dw, file_position);
  454.  
  455.         dw->dvi.current_page = i;
  456.         
  457.         dw->dvi.display_enable = 0;
  458.         while (dw->dvi.current_page != dw->dvi.requested_page) {
  459.             dw->dvi.current_page = ParseInput (dw);
  460.             /*
  461.              * at EOF, seek back to the begining of this page.
  462.              */
  463.             if (feof (dw->dvi.file)) {
  464.                 file_position = SearchPagePosition (dw,
  465.                         dw->dvi.current_page);
  466.                 if (file_position != -1)
  467.                     FileSeek (dw, file_position);
  468.                 break;
  469.             }
  470.         }
  471.     }
  472.     
  473.     dw->dvi.display_enable = 1;
  474.     ParseInput (dw);
  475.     if (dw->dvi.last_page && dw->dvi.requested_page > dw->dvi.last_page)
  476.         dw->dvi.requested_page = dw->dvi.last_page;
  477. }
  478.