home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / groff / libXdvi / Dvi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-30  |  11.3 KB  |  441 lines

  1. #ifndef lint
  2. static char Xrcsid[] = "$XConsortium: Dvi.c,v 1.9 89/12/10 16:12:25 rws Exp $";
  3. #endif /* lint */
  4.  
  5. /*
  6.  * Dvi.c - Dvi display widget
  7.  *
  8.  */
  9.  
  10. #define XtStrlen(s)    ((s) ? strlen(s) : 0)
  11.  
  12.   /* The following are defined for the reader's convenience.  Any
  13.      Xt..Field macro in this code just refers to some field in
  14.      one of the substructures of the WidgetRec.  */
  15.  
  16. #include <X11/IntrinsicP.h>
  17. #include <X11/StringDefs.h>
  18. #include <X11/Xmu/Converters.h>
  19. #include <stdio.h>
  20. #include <ctype.h>
  21. #include "DviP.h"
  22.  
  23. /****************************************************************
  24.  *
  25.  * Full class record constant
  26.  *
  27.  ****************************************************************/
  28.  
  29. /* Private Data */
  30.  
  31. static char default_font_map[] =  "\
  32. TR    -*-times-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
  33. TI    -*-times-medium-i-normal--*-100-*-*-*-*-iso8859-1\n\
  34. TB    -*-times-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
  35. TBI    -*-times-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\
  36. CR    -*-courier-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
  37. CI    -*-courier-medium-o-normal--*-100-*-*-*-*-iso8859-1\n\
  38. CB    -*-courier-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
  39. CBI    -*-courier-bold-o-normal--*-100-*-*-*-*-iso8859-1\n\
  40. HR    -*-helvetica-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
  41. HI    -*-helvetica-medium-o-normal--*-100-*-*-*-*-iso8859-1\n\
  42. HB    -*-helvetica-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
  43. HBI    -*-helvetica-bold-o-normal--*-100-*-*-*-*-iso8859-1\n\
  44. NR    -*-new century schoolbook-medium-r-normal--*-100-*-*-*-*-iso8859-1\n\
  45. NI    -*-new century schoolbook-medium-i-normal--*-100-*-*-*-*-iso8859-1\n\
  46. NB    -*-new century schoolbook-bold-r-normal--*-100-*-*-*-*-iso8859-1\n\
  47. NBI    -*-new century schoolbook-bold-i-normal--*-100-*-*-*-*-iso8859-1\n\
  48. S    -*-symbol-medium-r-normal--*-100-*-*-*-*-adobe-fontspecific\n\
  49. ";
  50.  
  51. #define offset(field) XtOffset(DviWidget, field)
  52.  
  53. # define MY_WIDTH(dw)    (dw->dvi.device_resolution * 9)
  54. # define MY_HEIGHT(dw)    (dw->dvi.device_resolution * 11)
  55.  
  56. static XtResource resources[] = { 
  57.     {XtNfontMap, XtCFontMap, XtRString, sizeof (char *),
  58.      offset(dvi.font_map_string), XtRString, default_font_map},
  59.     {XtNforeground, XtCForeground, XtRPixel, sizeof (unsigned long),
  60.      offset(dvi.foreground), XtRString, "black"},
  61.     {XtNbackground, XtCBackground, XtRPixel, sizeof (unsigned long),
  62.      offset(dvi.background), XtRString, "white"},
  63.     {XtNpageNumber, XtCPageNumber, XtRInt, sizeof (int),
  64.      offset(dvi.requested_page), XtRString, "1"},
  65.     {XtNlastPageNumber, XtCLastPageNumber, XtRInt, sizeof (int),
  66.      offset (dvi.last_page), XtRString, "0"},
  67.     {XtNfile, XtCFile, XtRFile, sizeof (FILE *),
  68.      offset (dvi.file), XtRFile, (char *) 0},
  69.     {XtNseek, XtCSeek, XtRBoolean, sizeof (Boolean),
  70.      offset(dvi.seek), XtRString, "false"},
  71.     {XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
  72.      offset(dvi.default_font), XtRString, "xtdefaultfont"},
  73.     {XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof (int),
  74.      offset(dvi.backing_store), XtRString, "default"},
  75.     {XtNnoPolyText, XtCNoPolyText, XtRBoolean, sizeof (Boolean),
  76.      offset(dvi.noPolyText), XtRString, "false"},
  77. };
  78.  
  79. #undef offset
  80.  
  81. static void        ClassInitialize ();
  82. static void        Initialize(), Realize (), Destroy (), Redisplay ();
  83. static Boolean        SetValues (), SetValuesHook ();
  84. static XtGeometryResult    QueryGeometry ();
  85. static void        ShowDvi ();
  86. static void        CloseFile (), OpenFile ();
  87. static void        FindPage ();
  88.  
  89. DviClassRec dviClassRec = {
  90. {
  91.     &widgetClassRec,        /* superclass          */    
  92.     "Dvi",                /* class_name          */
  93.     sizeof(DviRec),            /* size              */
  94.     ClassInitialize,        /* class_initialize      */
  95.     NULL,                /* class_part_initialize  */
  96.     FALSE,                /* class_inited          */
  97.     Initialize,            /* initialize          */
  98.     NULL,                /* initialize_hook      */
  99.     Realize,            /* realize          */
  100.     NULL,                /* actions          */
  101.     0,                /* num_actions          */
  102.     resources,            /* resources          */
  103.     XtNumber(resources),        /* resource_count      */
  104.     NULLQUARK,            /* xrm_class          */
  105.     FALSE,                /* compress_motion      */
  106.     TRUE,                /* compress_exposure      */
  107.     TRUE,                /* compress_enterleave    */
  108.     FALSE,                /* visible_interest      */
  109.     Destroy,            /* destroy          */
  110.     NULL,                /* resize          */
  111.     Redisplay,            /* expose          */
  112.     SetValues,            /* set_values          */
  113.     SetValuesHook,            /* set_values_hook      */
  114.     NULL,                /* set_values_almost      */
  115.     NULL,                /* get_values_hook      */
  116.     NULL,                /* accept_focus          */
  117.     XtVersion,            /* version          */
  118.     NULL,                /* callback_private      */
  119.     0,                /* tm_table          */
  120.     QueryGeometry,            /* query_geometry      */
  121.     NULL,                /* display_accelerator      */
  122.     NULL                /* extension          */
  123. },{
  124.     0,                /* field not used    */
  125. },
  126. };
  127.  
  128. WidgetClass dviWidgetClass = (WidgetClass) &dviClassRec;
  129.  
  130. static void ClassInitialize ()
  131. {
  132.     XtAddConverter( XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
  133.             NULL, 0 );
  134. }
  135.  
  136. /****************************************************************
  137.  *
  138.  * Private Procedures
  139.  *
  140.  ****************************************************************/
  141.  
  142. /* ARGSUSED */
  143. static void Initialize(request, new)
  144.     Widget request, new;
  145. {
  146.     DviWidget    dw = (DviWidget) new;
  147.  
  148.     dw->dvi.current_page = 0;
  149.     dw->dvi.font_map = 0;
  150.     dw->dvi.cache.index = 0;
  151.     dw->dvi.file = 0;
  152.     dw->dvi.seek = False;
  153.     dw->dvi.device_resolution = 75;
  154.     dw->dvi.line_thickness = -1;
  155.     dw->dvi.line_width = 1;
  156.     dw->dvi.fill = DVI_FILL_MAX;
  157. }
  158.  
  159. #include <X11/bitmaps/gray>
  160.  
  161. static void
  162. Realize (w, valueMask, attrs)
  163.     Widget            w;
  164.     XtValueMask        *valueMask;
  165.     XSetWindowAttributes    *attrs;
  166. {
  167.     DviWidget    dw = (DviWidget) w;
  168.     XGCValues    values;
  169.  
  170.     if (dw->dvi.backing_store != Always + WhenMapped + NotUseful) {
  171.         attrs->backing_store = dw->dvi.backing_store;
  172.         *valueMask |= CWBackingStore;
  173.     }
  174.     XtCreateWindow (w, (unsigned)InputOutput, (Visual *) CopyFromParent,
  175.             *valueMask, attrs);
  176.     values.foreground = dw->dvi.foreground;
  177.     values.cap_style = CapRound;
  178.     values.join_style = JoinRound;
  179.     values.line_width = dw->dvi.line_width;
  180.     dw->dvi.normal_GC = XCreateGC (XtDisplay (w), XtWindow (w),
  181.                        GCForeground|GCCapStyle|GCJoinStyle
  182.                        |GCLineWidth,
  183.                        &values);
  184.     dw->dvi.gray = XCreateBitmapFromData(XtDisplay (w), XtWindow (w),
  185.                          gray_bits,
  186.                          gray_width, gray_height);
  187.     values.background = dw->dvi.background;
  188.     values.stipple = dw->dvi.gray;
  189.     dw->dvi.fill_GC = XCreateGC (XtDisplay (w), XtWindow (w),
  190.                      GCForeground|GCBackground|GCStipple,
  191.                      &values);
  192.  
  193.     dw->dvi.fill_type = DVI_FILL_BLACK;
  194.  
  195.     if (dw->dvi.file)
  196.         OpenFile (dw);
  197.     ParseFontMap (dw);
  198. }
  199.  
  200. static void
  201. Destroy(w)
  202.     Widget w;
  203. {
  204.     DviWidget    dw = (DviWidget) w;
  205.  
  206.     XFreeGC (XtDisplay (w), dw->dvi.normal_GC);
  207.     XFreeGC (XtDisplay (w), dw->dvi.fill_GC);
  208.     XFreePixmap (XtDisplay (w), dw->dvi.gray);
  209.     DestroyFontMap (dw->dvi.font_map);
  210.     DestroyFileMap (dw->dvi.file_map);
  211. }
  212.  
  213. /*
  214.  * Repaint the widget window
  215.  */
  216.  
  217. /* ARGSUSED */
  218. static void
  219. Redisplay(w, event, region)
  220.     Widget w;
  221.     XEvent *event;
  222.     Region region;
  223. {
  224.     DviWidget    dw = (DviWidget) w;
  225.     XRectangle    extents;
  226.     
  227.     XClipBox (region, &extents);
  228.     dw->dvi.extents.x1 = extents.x;
  229.     dw->dvi.extents.y1 = extents.y;
  230.     dw->dvi.extents.x2 = extents.x + extents.width;
  231.     dw->dvi.extents.y2 = extents.y + extents.height;
  232.     ShowDvi (dw);
  233. }
  234.  
  235. /*
  236.  * Set specified arguments into widget
  237.  */
  238. /* ARGSUSED */
  239. static Boolean
  240. SetValues (current, request, new)
  241.     DviWidget current, request, new;
  242. {
  243.     Boolean        redisplay = FALSE;
  244.     extern char    *malloc ();
  245.     char        *new_map;
  246.     int        cur, req;
  247.  
  248.     if (current->dvi.font_map_string != request->dvi.font_map_string) {
  249.         new_map = malloc (strlen (request->dvi.font_map_string) + 1);
  250.         if (new_map) {
  251.             redisplay = TRUE;
  252.             strcpy (new_map, request->dvi.font_map_string);
  253.             new->dvi.font_map_string = new_map;
  254.             if (current->dvi.font_map_string)
  255.                 free (current->dvi.font_map_string);
  256.             current->dvi.font_map_string = 0;
  257.             ParseFontMap (new);
  258.         }
  259.     }
  260.  
  261.     req = request->dvi.requested_page;
  262.     cur = current->dvi.requested_page;
  263.     if (cur != req) {
  264.         if (!request->dvi.file)
  265.             req = 0;
  266.         else {
  267.             if (req < 1)
  268.                 req = 1;
  269.             if (current->dvi.last_page != 0 &&
  270.             req > current->dvi.last_page)
  271.                 req = current->dvi.last_page;
  272.         }
  273.         if (cur != req)
  274.                 redisplay = TRUE;
  275.         new->dvi.requested_page = req;
  276.         if (current->dvi.last_page == 0 && req > cur)
  277.             FindPage (new);
  278.     }
  279.  
  280.     return redisplay;
  281. }
  282.  
  283. /*
  284.  * use the set_values_hook entry to check when
  285.  * the file is set
  286.  */
  287.  
  288. static Boolean
  289. SetValuesHook (dw, args, num_argsp)
  290.     DviWidget    dw;
  291.     ArgList        args;
  292.     Cardinal    *num_argsp;
  293. {
  294.     Cardinal    i;
  295.  
  296.     for (i = 0; i < *num_argsp; i++) {
  297.         if (!strcmp (args[i].name, XtNfile)) {
  298.             CloseFile (dw);
  299.             OpenFile (dw);
  300.             return TRUE;
  301.         }
  302.     }
  303.     return FALSE;
  304. }
  305.  
  306. static void CloseFile (dw)
  307.     DviWidget    dw;
  308. {
  309.     if (dw->dvi.tmpFile)
  310.         fclose (dw->dvi.tmpFile);
  311.     ForgetPagePositions (dw);
  312. }
  313.  
  314. static void OpenFile (dw)
  315.     DviWidget    dw;
  316. {
  317.     char    tmpName[sizeof ("/tmp/dviXXXXXX")];
  318.  
  319.     dw->dvi.tmpFile = 0;
  320.     if (!dw->dvi.seek) {
  321.         strcpy (tmpName, "/tmp/dviXXXXXX");
  322.         mktemp (tmpName);
  323.         dw->dvi.tmpFile = fopen (tmpName, "w+");
  324.         unlink (tmpName);
  325.     }
  326.     dw->dvi.requested_page = 1;
  327.     dw->dvi.last_page = 0;
  328. }
  329.  
  330. static XtGeometryResult
  331. QueryGeometry (w, request, geometry_return)
  332.     Widget            w;
  333.     XtWidgetGeometry    *request, *geometry_return;
  334. {
  335.     XtGeometryResult    ret;
  336.     DviWidget        dw = (DviWidget) w;
  337.  
  338.     ret = XtGeometryYes;
  339.     if (request->width < MY_WIDTH(dw) || request->height < MY_HEIGHT(dw))
  340.         ret = XtGeometryAlmost;
  341.     geometry_return->width = MY_WIDTH(dw);
  342.     geometry_return->height = MY_HEIGHT(dw);
  343.     geometry_return->request_mode = CWWidth|CWHeight;
  344.     return ret;
  345. }
  346.  
  347. SetDeviceResolution (dw, resolution)
  348.     DviWidget   dw;
  349.     int        resolution;
  350. {
  351.     XtWidgetGeometry    request, reply;
  352.  
  353.     if (resolution != dw->dvi.device_resolution) {
  354.         dw->dvi.device_resolution = resolution;
  355.         request.request_mode = CWWidth|CWHeight;
  356.         request.width = MY_WIDTH(dw);
  357.         request.height = MY_HEIGHT(dw);
  358.         XtMakeGeometryRequest (dw, &request, &reply);
  359.     }
  360. }
  361.  
  362. static void
  363. ShowDvi (dw)
  364.     DviWidget    dw;
  365. {
  366.     if (!dw->dvi.file) {
  367.         static char Error[] = "No file selected";
  368.  
  369.         XSetFont (XtDisplay(dw), dw->dvi.normal_GC,
  370.               dw->dvi.default_font->fid);
  371.         XDrawString (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
  372.                  20, 20, Error, strlen (Error));
  373.         return;
  374.     }
  375.  
  376.     FindPage (dw);
  377.     
  378.     dw->dvi.display_enable = 1;
  379.     ParseInput (dw);
  380.     if (dw->dvi.last_page && dw->dvi.requested_page > dw->dvi.last_page)
  381.         dw->dvi.requested_page = dw->dvi.last_page;
  382. }
  383.  
  384. static void
  385. FindPage (dw)
  386.     DviWidget    dw;
  387. {
  388.     int    i;
  389.     long    file_position;
  390.  
  391.     if (dw->dvi.requested_page < 1)
  392.         dw->dvi.requested_page = 1;
  393.  
  394.     if (dw->dvi.last_page != 0 && dw->dvi.requested_page > dw->dvi.last_page)
  395.         dw->dvi.requested_page = dw->dvi.last_page;
  396.  
  397.     file_position = SearchPagePosition (dw, dw->dvi.requested_page);
  398.     if (file_position != -1) {
  399.         FileSeek(dw, file_position);
  400.         dw->dvi.current_page = dw->dvi.requested_page;
  401.     } else {
  402.         for (i=dw->dvi.requested_page; i > 0; i--) {
  403.             file_position = SearchPagePosition (dw, i);
  404.             if (file_position != -1)
  405.                 break;
  406.         }
  407.         if (file_position == -1)
  408.             file_position = 0;
  409.         FileSeek (dw, file_position);
  410.  
  411.         dw->dvi.current_page = i;
  412.         
  413.         dw->dvi.display_enable = 0;
  414.         while (dw->dvi.current_page != dw->dvi.requested_page) {
  415.             dw->dvi.current_page = ParseInput (dw);
  416.             /*
  417.              * at EOF, seek back to the begining of this page.
  418.              */
  419.             if (feof (dw->dvi.file)) {
  420.                 file_position = SearchPagePosition (dw,
  421.                         dw->dvi.current_page);
  422.                 if (file_position != -1)
  423.                     FileSeek (dw, file_position);
  424.                 dw->dvi.requested_page = dw->dvi.current_page;
  425.                 break;
  426.             }
  427.         }
  428.     }
  429. }
  430.  
  431. /*
  432. Local Variables:
  433. c-indent-level: 8
  434. c-continued-statement-offset: 8
  435. c-brace-offset: -8
  436. c-argdecl-indent: 8
  437. c-label-offset: -8
  438. c-tab-always-indent: nil
  439. End:
  440. */
  441.