From d318611dd6f23fcfedd50e9b9e24620b102ba96a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 21:44:05 +0200 Subject: Adding upstream version 1.23.0. Signed-off-by: Daniel Baumann --- src/devices/xditview/ChangeLog | 556 ++++++++++++++++++++++ src/devices/xditview/DESC.in | 9 + src/devices/xditview/Dvi.c | 603 +++++++++++++++++++++++ src/devices/xditview/Dvi.h | 46 ++ src/devices/xditview/DviP.h | 235 +++++++++ src/devices/xditview/FontMap-X11 | 17 + src/devices/xditview/GXditview-color.ad | 15 + src/devices/xditview/GXditview.ad | 71 +++ src/devices/xditview/Menu.h | 46 ++ src/devices/xditview/README | 13 + src/devices/xditview/TODO | 21 + src/devices/xditview/ad2c | 64 +++ src/devices/xditview/device.c | 565 ++++++++++++++++++++++ src/devices/xditview/device.h | 21 + src/devices/xditview/draw.c | 709 +++++++++++++++++++++++++++ src/devices/xditview/draw.h | 18 + src/devices/xditview/font.c | 446 +++++++++++++++++ src/devices/xditview/font.h | 6 + src/devices/xditview/gray1.bm | 4 + src/devices/xditview/gray2.bm | 4 + src/devices/xditview/gray3.bm | 4 + src/devices/xditview/gray4.bm | 4 + src/devices/xditview/gray5.bm | 4 + src/devices/xditview/gray6.bm | 4 + src/devices/xditview/gray7.bm | 4 + src/devices/xditview/gray8.bm | 4 + src/devices/xditview/gxditview.1.man | 815 ++++++++++++++++++++++++++++++++ src/devices/xditview/lex.c | 100 ++++ src/devices/xditview/lex.h | 1 + src/devices/xditview/page.c | 86 ++++ src/devices/xditview/page.h | 5 + src/devices/xditview/parse.c | 343 ++++++++++++++ src/devices/xditview/parse.h | 1 + src/devices/xditview/xdit.bm | 14 + src/devices/xditview/xdit_mask.bm | 14 + src/devices/xditview/xditview.am | 130 +++++ src/devices/xditview/xditview.c | 684 +++++++++++++++++++++++++++ 37 files changed, 5686 insertions(+) create mode 100644 src/devices/xditview/ChangeLog create mode 100644 src/devices/xditview/DESC.in create mode 100644 src/devices/xditview/Dvi.c create mode 100644 src/devices/xditview/Dvi.h create mode 100644 src/devices/xditview/DviP.h create mode 100644 src/devices/xditview/FontMap-X11 create mode 100644 src/devices/xditview/GXditview-color.ad create mode 100644 src/devices/xditview/GXditview.ad create mode 100644 src/devices/xditview/Menu.h create mode 100644 src/devices/xditview/README create mode 100644 src/devices/xditview/TODO create mode 100644 src/devices/xditview/ad2c create mode 100644 src/devices/xditview/device.c create mode 100644 src/devices/xditview/device.h create mode 100644 src/devices/xditview/draw.c create mode 100644 src/devices/xditview/draw.h create mode 100644 src/devices/xditview/font.c create mode 100644 src/devices/xditview/font.h create mode 100644 src/devices/xditview/gray1.bm create mode 100644 src/devices/xditview/gray2.bm create mode 100644 src/devices/xditview/gray3.bm create mode 100644 src/devices/xditview/gray4.bm create mode 100644 src/devices/xditview/gray5.bm create mode 100644 src/devices/xditview/gray6.bm create mode 100644 src/devices/xditview/gray7.bm create mode 100644 src/devices/xditview/gray8.bm create mode 100644 src/devices/xditview/gxditview.1.man create mode 100644 src/devices/xditview/lex.c create mode 100644 src/devices/xditview/lex.h create mode 100644 src/devices/xditview/page.c create mode 100644 src/devices/xditview/page.h create mode 100644 src/devices/xditview/parse.c create mode 100644 src/devices/xditview/parse.h create mode 100644 src/devices/xditview/xdit.bm create mode 100644 src/devices/xditview/xdit_mask.bm create mode 100644 src/devices/xditview/xditview.am create mode 100644 src/devices/xditview/xditview.c (limited to 'src/devices/xditview') diff --git a/src/devices/xditview/ChangeLog b/src/devices/xditview/ChangeLog new file mode 100644 index 0000000..a33297b --- /dev/null +++ b/src/devices/xditview/ChangeLog @@ -0,0 +1,556 @@ +2004-05-29 Werner LEMBERG + + gxditview and xtotroff have been integrated into the normal groff + directory structure; future changes are logged in the main + ChangeLog file. + +2004-05-13 Werner LEMBERG + +Version 1.19.1 released +======================= + +2004-04-17 Werner LEMBERG + + * device.c (scale_round): Round correctly for negative values + (this is the same function as in src/libs/libgroff/font.c). + Found by Paul Eggert. + +2003-11-10 Werner LEMBERG + + * Imakefile.in: s/@top_srcdir@/@abs_top_srcdir@/, + s/@groff_top_builddir@/@abs_top_builddir@/. + +Version 1.19 released +===================== + +2003-03-03 Werner LEMBERG + + * Imakefile.in (extraclean): Added gxditview._man. + +2003-01-28 Werner LEMBERG + + * Imakefile.in (SEP): New variable; set to @PATH_SEPARATOR@. + (GROFF_FONTPATH): Use it. + +2003-01-07 Werner LEMBERG + + * DviChar.c (Adobe_Symbol_map): Add `sqrt'. + +2003-01-06 Werner LEMBERG + + * DviChar.c (Adobe_Symbol_map): Add `integral'. + +2002-12-29 Werner LEMBERG + + * DviChar.c (ISO_8859_1_map): Remove `ap' and `eq'. + +2002-12-20 Werner LEMBERG + + * DviChar.c (Adobe_Symbol_map): Don't include `or'. + * draw.c (AdjustCharDeltas): Apply correction only if nadj > 1. + (DoCharacter): Call FlushCharCache if font size and font number + differ. + Reset `dw->dvi.cache.adjustable' properly. + +2002-12-09 Werner LEMBERG + + * DviChar.c (ISO_8859_1_map): Use `tno' symbol instead of `no'. + +2002-12-01 Werner LEMBERG + + * Imakefile.in: Use `InstallAppDefaultsLong' instead of + `InstallAppDefaults' to make it work if build directory isn't + $srcdir. + +2002-11-24 Werner LEMBERG + + * DviChar.c (Adobe_Symbol_map): Add glyph `braceex'. + +2002-11-14 Werner LEMBERG + + * DviChar.c (ISO_8859_1_map): Don't include `or'. + +Version 1.18.1 released +======================= + +2002-09-16 Werner LEMBERG + + * Imakefile.in (GROFF_LOCALFONTDIR): New variable. + (GROFF_FONTPATH): Use it. + Remove /usr/local/lib/font. + +Version 1.18.0 released +======================= + +2002-06-22 Werner LEMBERG + + * gxditview.c (main): Handle `-help' and `--help' correctly. + +2002-06-17 Colin Watson + + * Imakefile.in: s/@top_builddir@/@groff_top_builddir@/. + +2002-04-06 Werner LEMBERG + + * DviChar.c (ISO_8859_1_map, Adobe_Symbol_map): Remove all + characters > 0x80. + * parse.c (ParseInput): Ignore `m' command. + (ParseDrawFunction): Don't move for unknown drawing functions. + Don't move for `f' drawing function. + +2002-03-25 Werner LEMBERG + + * DviChar.c (ISO_8859_1_map): Use `t+-', `tmu', and `tdi' symbols + instead of `+-', `mu', and `di', respectively. + +2002-02-23 Werner LEMBERG + + * DviChar.c (ISO_8859_1_map): Add `mc' symbol. + +2001-09-22 Werner LEMBERG + + * Imakefile.in: Redefine `ProgramTargetHelper' as + `ProgramTargetHelperNoMan' and add a call to `InstallManPageLong' + to make the `install.man' target work if the build directory isn't + $srcdir. + +Version 1.17.2 released +======================= + +Version 1.17.1 released +======================= + +2001-04-21 Albert Chin-A-Young + + * Imakefile.in: Add support for recent HP architectures. + +Version 1.17 released +===================== + +2001-01-04 Rob Daasch + + * parse.c (ParseInput): Added 'F' to command switch to swallow + filename strings as ignored comments. + +2000-12-02 Werner LEMBERG + + * device.c (find_file): Remove home directory in search path. + +2000-11-14 Werner LEMBERG + + * device.c (open_device_file): Remove `path' parameter. + (find_file): Construct font path similar to groff: First the contents + of GROFF_FONT_PATH, then the home directory, and finally the default + font path. + * Imakefile.in: Fix GROFF_DATAPROGRAMDIR and GROFF_FONTPATH. + +2000-10-23 Werner LEMBERG + + Change installation structure for data files from .../groff/... to + .../groff//... to be conform with other GNU + programs. + + * Imakefile.in: Implement it. + +Version 1.16.1 released +======================= + +Version 1.16 released +===================== + +2000-05-18 Werner LEMBERG + + * DviChar.c: Adding `cq' as an alias for "'" in latin-1 map. + +2000-05-03 Werner LEMBERG + + * DviChar.c: Adding `dq' as an alias for `"' in latin-1 map. + +2000-04-28 Werner LEMBERG + + * DviChar.c: Replacing `md' glyph name with `pc' in latin-1 map to + make it distinct from the `md' glyph in the symbol font. + +2000-03-03 Werner LEMBERG + + * Imakefile replaced with Imakefile.in which will be configured by + the main configure script of groff. This will set the correct font + path, and it will make it possible to build xditview in a directory + different from $srcdir. + +2000-03-01 Colin Phipps + + * Dvi.c (OpenFile): Use tmpdir() for security reasons. + * xtotroff.c (MapFont): Avoid race while opening file. + +2000-02-06 Werner LEMBERG + + * Imakefile: Adapted to new directory structure. + + * README: Updated. + +Version 1.15 released +===================== + +1999-12-21 Werner LEMBERG + + * README: Fixed ftp GNU address. + +1999-12-13 Werner LEMBERG + + * device.c: Use extern declarations of strtok(), strchr(), and + getenv() only if not defined as macros. + +1999-11-18 Larry Jones + + * xditview.c: Add fallback_resources to allow running without + access to the app-defaults file. + + * Imakefile: Added rule to create app-defaults to a C header file. + + * GXditview-ad.h: New file containing fallback default resources. + + * ad2c: New file to do the app-defaults -> C header file + conversion. + +1999-10-27 Larry Jones + + * font.c (DisposeFontSizes): If there's a problem loading a font, + xditview will fall-back and use the default font, but it hasn't + checked before unloading fonts which could result in unloading the + default font (possibly multiple times) and then X errors. + +1999-09-13 Werner LEMBERG + + * Imakefile (extraclean): Added Makefile. + + * xditview.c (main, MakePrompt): Fixing compilation warnings. + + * TODO: Imakefile should be replaced with a configure script. + +1999-09-13 Werner LEMBERG + + * Makefile: Removed. + +1999-09-12 Werner LEMBERG + + * Imakefile (GROFF_FONTPATH): Another addition. + + * device.c (FONTPATH): Update to match current groff version. + +1999-09-11 Larry Jones + + * Imakefile (GROFF_LIBDIR, GROFF_FONTPATH): Update to match + current groff version. + + * Dvi.c (Realize, Destroy), DviP.h, draw.c (setFillGC), gray*.bm: + Allow 8 levels of gray rather than just 1. + + * draw.c (DrawFilledCircle, DrawFilledEllipse, DrawFilledPolygon): + Draw outlines to prevent gaps between abutting figures. + +1999-05-27 Werner LEMBERG + + * xtotroff.c (usage): Fixed typo. + +Mon Sep 11 10:40:33 1995 James Clark + + * device.c (INT_MIN, INT_MAX): Don't define if already defined. + +Mon Aug 8 11:14:11 1994 James Clark (jjc@jclark.com) + + * DviChar.c (Adobe_Symbol_map): Use \(nb for notsubset. + +Tue Apr 19 04:41:16 1994 James Clark (jjc@jclark.com) + + * Dvi.c (resources): Change default for background and foreground + to "XtDefaultBackground" and "XtDefaultForeground". + +Sat Feb 12 10:38:47 1994 James Clark (jjc@jclark.com) + + * DviChar.c (Adobe_Symbol_map): Rename radicalex to rn. + +Thu May 27 20:30:12 1993 James Clark (jjc@jclark.com) + + * device.c (isascii): Define if necessary. + (canonicalize_name): Cast argument to isdigit() to unsigned char. + +Thu Apr 29 18:36:57 1993 James Clark (jjc at jclark.com) + + * xditview.c: Include . + (NewFile): Don't declare rindex(). Use strrchr() rather than + rindex(). + +Tue Mar 30 15:12:09 1993 James Clark (jjc at jclark) + + * draw.c (charExists): Check that fi->per_char is not NULL. + +Sat Dec 12 17:42:40 1992 James Clark (jjc at jclark) + + * Dvi.c (SetGeometry): Cast XtMakeGeometryRequest arguments. + + * draw.c (DrawPolygon, DrawFilledPolygon): Cast Xtfree argument. + + * font.c (DisposeFontSizes): Add declaration. + + * draw.c (FakeCharacter): Add declaration. + +Wed Oct 28 13:24:00 1992 James Clark (jjc at jclark) + + * Imakefile (install.dev): Deleted. + (fonts): New target. + +Mon Oct 12 10:50:44 1992 James Clark (jjc at jclark) + + * Imakefile (install.dev): Say when we're installing devX*-12. + + * Imakefile (install.dev): Depends on DESC and FontMap. + +Thu Oct 1 20:03:45 1992 James Clark (jjc at jclark) + + * xditview.c (Syntax): Mention -filename option. + +Sat Aug 15 12:56:39 1992 James Clark (jjc at jclark) + + * GXditview.ad: Bind space and return to NextPage. Bind backspace + and delete to previous page. + + * DviChar.c (Adobe_Symbol_map): Add `an'. + + * DviChar.c (Adobe_Symbol_map): Add arrowvertex, arrowverttp, and + arrowvertbt. + +Mon Aug 10 11:54:27 1992 James Clark (jjc at jclark) + + * FontMap: Add m/p fields to the fonts names. + +Sat Aug 8 12:00:28 1992 James Clark (jjc at jclark) + + * DESC: Leave font positions 5-9 blank. + +Tue Jul 28 11:37:05 1992 James Clark (jjc at jclark) + + * Imakefile: Don't use gendef. Pass definition of FONTPATH using + DEFINES. + (path.h): Deleted. + (device.c): Don't include path.h. Provide default definition of + FONTPATH. + +Mon Jul 6 14:06:53 1992 James Clark (jjc at jclark) + + * Imakefile: Don't install tmac.X and tmac.Xps. + * tmac.X, tmac.Xps: Moved to ../macros. + + * Imakefile: Don't install eqnchar. + * eqnchar: Deleted. + +Sun Jun 14 12:55:02 1992 James Clark (jjc@jclark) + + * tmac.Xps: Handle OE, oe, lq, rq. + * draw.c (FakeCharacter): Don't handle these. + + * draw.c (FakeCharacter): Don't handle f/. + +Mon Jun 8 11:46:37 1992 James Clark (jjc@jclark) + + * tmac.X: Translate char160 to space. + +Sun Jun 7 14:39:53 1992 James Clark (jjc@jclark) + + * tmac.X: Do `mso tmac.psic' before restoring compatibility mode. + + * tmac.X: Add \(OE, \(oe, \(ah, \(ao, \(ho. + + * tmac.Xps: Make it work in compatibility mode. + Redo existing character definitions with .Xps-char. + Add more character definitions. + (Xps-char): New macro. + +Sat Jun 6 21:46:03 1992 James Clark (jjc@jclark) + + * DviChar.c (Adobe_Symbol_map): Add +h, +f, +p, Fn, lz. + * tmac.X: Add \(bq, \(Bq, \(aq. + * tmac.Xps: Handle \(aq, \(bq, \(Bq, \(Fn. + +Wed Jun 3 11:11:15 1992 James Clark (jjc@jclark) + + * DviChar.c (Adobe_Symbol_map): Add wp. + +Tue Apr 21 09:21:59 1992 James Clark (jjc at jclark) + + * GXditview.ad: Bind n, p, q keys to NextPage, PreviousPage and + Quit actions. + + * xditview.c (RerasterizeAction): New function. + (xditview_actions): Add RerasterizeAction. + * GXditview.ad: Bind r key to Rerasterize action. + +Fri Apr 17 08:25:36 1992 James Clark (jjc at jclark) + + * xditview.c: Add -filename option. + (main): Copy any -filename argument into current_file_name. + +Mon Mar 16 10:21:58 1992 James Clark (jjc at jclark) + + * tmac.X: Load tmac.pspic. + +Sun Mar 8 11:27:19 1992 James Clark (jjc at jclark) + + * Lex.c (GetLine, GetWord, GetNumber): Rewrite. + +Sat Oct 12 22:58:52 1991 James Clark (jjc at jclark) + + * Dvi.c (SetDevice): If the size change request is refused but a + larger geometry is offered, request that. + +Wed Oct 9 12:27:48 1991 James Clark (jjc at jclark) + + * font.c (InstallFontSizes): Ignore FontNameAverageWidth component. + + * Dvi.c (default_font_map): Add `adobe' to font names to avoid + ambiguity. + + * FontMap: New file. + * FontMap.X100, FontMap.X75: Deleted. + * xtotroff.c (main, usage): Add -s and -r options. + (MapFont): Change the font pattern to have the selected resolution and + size. + * Imakefile (install.dev): Use FontMap and supply appropriate -s + and -r options. + + * xtotroff.c (MapFont): Check for ambiguity by comparing canonicalized + font names. + + * DviP.h (DviFontList): Add initialized and scalable members. + (font.c): Add support for scalable fonts based on R5 xditview. + + * DviChar.c: Use xmalloc rather than malloc. + * xditview.c (xmalloc): New function. + * xtotroff.c (xmalloc): New function. + * other files: Use XtMalloc and XtFree instead of malloc and free. + +Thu Aug 29 20:15:31 1991 James Clark (jjc at jclark) + + * draw.c (setGC): Do multiplication in floating point to avoid + overflow. + +Tue Aug 13 12:04:41 1991 James Clark (jjc at jclark) + + * draw.c (FakeCharacter): Remove casts in definition of pack2. + +Tue Jul 30 11:42:39 1991 James Clark (jjc at jclark) + + * tmac.Xps: New file. + * Imakefile (install): Install tmac.Xps. + +Tue Jul 2 09:31:37 1991 James Clark (jjc at jclark) + + * xtotroff.c (main): Pass argv[0] to usage(). + +Sun Jun 30 12:34:06 1991 James Clark (jjc at jclark) + + * xtotroff.c (MapFont): Handle the case where XLoadQueryFont + returns NULL. + +Sat Jun 29 12:32:52 1991 James Clark (jjc at jclark) + + * Imakefile: Use ../gendef to generate path.h. + +Sun Jun 16 13:26:34 1991 James Clark (jjc at jclark) + + * Imakefile (depend.o): Change to device.o. + +Sun Jun 2 12:17:56 1991 James Clark (jjc at jclark) + + * Imakefile: Remove spaces from the beginning of variable + assignment lines. + +Sun May 26 14:14:01 1991 James Clark (jjc at jclark) + + * xditview.c (Syntax): Update. + + * Dvi.c (DviSaveToFile, SaveToFile): New functions. + (FindPage): Check that we're not readingTmp before checking for + end of file of normal input file. + (ClassPartInitialize): New function. + * Dvi.h: Add declaration of DviSaveToFile. + * DviP.h: Add save method to DviClassPart. Declare + InheritSaveToFile. + * xditview.c (DoPrint, Print, PrintAction): New functions. + * xditview.c: Add print menu entry. + * xditview.c: Provide printCommand application resource. + * lex.c: Don't output EOF to temporary file. + + * Dvi.c (QueryGeometry): Check request->request_mode. + + * Dvi.c (SetDevice): New function. + (SetDeviceResolution): Deleted. + + * Dvi.c: Add resolution resource. + * DviP.h: Add definitions of XtNResolution and XtCResolution. + * xditview.c: Add -resolution argument. + * GXditview.ad: Add default for GXditview.height. + * Dvi.c (Initialize, SetDevice): Use default_resolution. + + * Dvi.c: Make MY_HEIGHT and MY_WIDTH use the paperlength and + paperwidth commands in the DESC file. + + * Dvi.c: Add SS font to default font map. + + * draw.c: Rewritten so as not to assume device and display + resolution is the same. + * DviP.h: Include device.h. Add device_font member to DviFontList. + Add adjustable array to DviCharCache. Add text_x_width, + text_device_width, word_flag, device_font, device_font_number, + device, native, device_resolution, display_resolution, + paperlength, paperwidth, scale_factor, sizescale members. + * Dvi.c (Initialize): Initialize new variable used by draw.c. + (Destroy): Call device_destroy. + * font.c (MaxFontPosition): New function. + (LookupFontSizeBySize): Handle sizescale. + (InstallFont): Load the device font. + (ForgetFonts): New function. + (QueryDeviceFont): New function. + * parse.c (ParseInput): Handle t and u commands. Split off + character output into draw.c. + (ParseDeviceControl): Ignore res command. Use the device argument + to the T command. + + * font.c (MapXNameToDviName): Ifdefed out. + + * path.h: New file. + * device.c, device.h: New files. + + * DviChar.c: Add entries for lB, rB, oq, lC, rC, md. + + * INSTALL: New file. + + * libxdvi: Merged into main directory. + * xtotroff.c, xditview.c: Change includes accordingly. + + * devX75, devX100: Merged into main directory. + * xditview.man: Renamed to gxditview.man. + + * Xditview.ad: Renamed to GXditview.ad. + * xditview.c (main): Use class of GXditview rather than xditview. + + * Imakefile: New file. + * Makefile: Deleted. + + * xtotroff.c (MapFont): Unlink output file before opening it. + + * Started separate ChangeLog. + +________________________________________________________________________ + +Copyright 1991-2020 Free Software Foundation, Inc. + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. + +Local Variables: +version-control: never +mode: change-log +coding: latin-1 +End: diff --git a/src/devices/xditview/DESC.in b/src/devices/xditview/DESC.in new file mode 100644 index 0000000..172170c --- /dev/null +++ b/src/devices/xditview/DESC.in @@ -0,0 +1,9 @@ +styles R I B BI +fonts 6 0 0 0 0 0 S +sizes 8 10 12 14 18 24 0 +res 75 +X11 +hor 1 +vert 1 +unitwidth 10 +postpro gxditview 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 + +#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 +#include +#include +#include +#include + +#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: +*/ diff --git a/src/devices/xditview/Dvi.h b/src/devices/xditview/Dvi.h new file mode 100644 index 0000000..bf97374 --- /dev/null +++ b/src/devices/xditview/Dvi.h @@ -0,0 +1,46 @@ +/* +* $XConsortium: Dvi.h,v 1.4 89/07/21 14:22:06 jim Exp $ +*/ + +#ifndef _XtDvi_h +#define _XtDvi_h + +/*********************************************************************** + * + * Dvi Widget + * + ***********************************************************************/ + +/* Parameters: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background pixel White + foreground Foreground Pixel Black + fontMap FontMap char * ... + pageNumber PageNumber int 1 +*/ + +#define XtNfontMap (String)"fontMap" +#define XtNpageNumber (String)"pageNumber" +#define XtNlastPageNumber (String)"lastPageNumber" +#define XtNnoPolyText (String)"noPolyText" +#define XtNseek (String)"seek" +#define XtNresolution (String)"resolution" + +#define XtCFontMap (String)"FontMap" +#define XtCPageNumber (String)"PageNumber" +#define XtCLastPageNumber (String)"LastPageNumber" +#define XtCNoPolyText (String)"NoPolyText" +#define XtCSeek (String)"Seek" +#define XtCResolution (String)"Resolution" + +typedef struct _DviRec *DviWidget; /* completely defined in DviP.h */ +typedef struct _DviClassRec *DviWidgetClass; /* completely defined in DviP.h */ + +extern WidgetClass dviWidgetClass; + +void DviSaveToFile(Widget, FILE *); + +#endif /* _XtDvi_h */ +/* DON'T ADD STUFF AFTER THIS #endif */ diff --git a/src/devices/xditview/DviP.h b/src/devices/xditview/DviP.h new file mode 100644 index 0000000..8b71c69 --- /dev/null +++ b/src/devices/xditview/DviP.h @@ -0,0 +1,235 @@ +/* + * $XConsortium: DviP.h,v 1.5 89/07/22 19:44:08 keith Exp $ + */ + +/* + * DviP.h - Private definitions for Dvi widget + */ + +#ifndef _XtDviP_h +#define _XtDviP_h + +#include "Dvi.h" +#include "DviChar.h" +#include "device.h" + +/*********************************************************************** + * + * Dvi Widget Private Data + * + ***********************************************************************/ + +/************************************ + * + * Class structure + * + ***********************************/ + +/* Type for save method. */ + +typedef void (*DviSaveProc)(Widget, FILE *); + +/* + * New fields for the Dvi widget class record + */ + + +typedef struct _DviClass { + DviSaveProc save; +} DviClassPart; + +/* + * Full class record declaration + */ + +typedef struct _DviClassRec { + CoreClassPart core_class; + DviClassPart command_class; +} DviClassRec; + +extern DviClassRec dviClassRec; + +/*************************************** + * + * Instance (widget) structure + * + **************************************/ + +/* + * a list of fonts we've used for this widget + */ + +typedef struct _dviFontSizeList { + struct _dviFontSizeList *next; + int size; + char *x_name; + XFontStruct *font; + int doesnt_exist; +} DviFontSizeList; + +typedef struct _dviFontList { + struct _dviFontList *next; + char *dvi_name; + char *x_name; + int dvi_number; + Boolean initialized; + Boolean scalable; + DviFontSizeList *sizes; + DviCharNameMap *char_map; + DeviceFont *device_font; +} DviFontList; + +typedef struct _dviFontMap { + struct _dviFontMap *next; + char *dvi_name; + char *x_name; +} DviFontMap; + +#define DVI_TEXT_CACHE_SIZE 256 +#define DVI_CHAR_CACHE_SIZE 1024 + +typedef struct _dviCharCache { + XTextItem cache[DVI_TEXT_CACHE_SIZE]; + char adjustable[DVI_TEXT_CACHE_SIZE]; + char char_cache[DVI_CHAR_CACHE_SIZE]; + int index; + int max; + int char_index; + int font_size; + int font_number; + XFontStruct *font; + int start_x, start_y; + int x, y; +} DviCharCache; + +typedef struct _dviState { + struct _dviState *next; + int font_size; + int font_number; + int x; + int y; +} DviState; + +typedef struct _dviFileMap { + struct _dviFileMap *next; + long position; + int page_number; +} DviFileMap; + +/* + * New fields for the Dvi widget record + */ + +typedef struct { + /* + * resource specifiable items + */ + char *font_map_string; + unsigned long foreground; + unsigned long background; + int requested_page; + int last_page; + XFontStruct *default_font; + FILE *file; + Boolean noPolyText; + Boolean seek; /* file is 'seekable' */ + int default_resolution; + /* + * private state + */ + FILE *tmpFile; /* used when reading stdin */ + char readingTmp; /* reading now from tmp */ + char ungot; /* have ungetc'd a char */ + GC normal_GC; + GC fill_GC; + DviFileMap *file_map; + DviFontList *fonts; + DviFontMap *font_map; + int current_page; + int font_size; + int font_number; + DeviceFont *device_font; + int device_font_number; + Device *device; + int native; + int device_resolution; + int display_resolution; + int paperlength; + int paperwidth; + double scale_factor; /* display res / device res */ + int sizescale; + int line_thickness; + int line_width; + +#define DVI_FILL_MAX 1000 + + int fill; +#define DVI_FILL_WHITE 0 +#define DVI_FILL_GRAY 1 +#define DVI_FILL_BLACK 2 + int fill_type; + Pixmap gray[8]; + int backing_store; + XFontStruct *font; + int display_enable; + struct ExposedExtents { + int x1, y1, x2, y2; + } extents; + DviState *state; + DviCharCache cache; + int text_x_width; + int text_device_width; + int word_flag; +} DviPart; + +int DviGetAndPut(DviWidget, int *); +#define DviGetIn(dw,cp)\ + (dw->dvi.tmpFile ? (\ + DviGetAndPut (dw, cp) \ + ) :\ + (*cp = getc (dw->dvi.file))\ +) + +#define DviGetC(dw, cp)\ + (dw->dvi.readingTmp ? (\ + ((*cp = getc (dw->dvi.tmpFile)) == EOF) ? (\ + fseek (dw->dvi.tmpFile, 0l, 2),\ + (dw->dvi.readingTmp = 0),\ + DviGetIn (dw,cp)\ + ) : (\ + *cp\ + )\ + ) : (\ + DviGetIn(dw,cp)\ + )\ +) + +#define DviUngetC(dw, c)\ + (dw->dvi.readingTmp ? (\ + ungetc (c, dw->dvi.tmpFile)\ + ) : ( \ + (dw->dvi.ungot = 1),\ + ungetc (c, dw->dvi.file))) + +/* + * Full widget declaration + */ + +typedef struct _DviRec { + CorePart core; + DviPart dvi; +} DviRec; + +#define InheritSaveToFile ((DviSaveProc)_XtInherit) + +XFontStruct *QueryFont (DviWidget, int, int); + +DviCharNameMap *QueryFontMap (DviWidget, int); + +DeviceFont *QueryDeviceFont (DviWidget, int); + +char *GetWord(DviWidget, char *, int); +char *GetLine(DviWidget, char *, int); + +void SetDevice (DviWidget dw, const char *name); +#endif /* _XtDviP_h */ diff --git a/src/devices/xditview/FontMap-X11 b/src/devices/xditview/FontMap-X11 new file mode 100644 index 0000000..90911f0 --- /dev/null +++ b/src/devices/xditview/FontMap-X11 @@ -0,0 +1,17 @@ +TR -adobe-times-medium-r-normal--*-*-*-*-p-*-iso8859-1 +TI -adobe-times-medium-i-normal--*-*-*-*-p-*-iso8859-1 +TB -adobe-times-bold-r-normal--*-*-*-*-p-*-iso8859-1 +TBI -adobe-times-bold-i-normal--*-*-*-*-p-*-iso8859-1 +CR -adobe-courier-medium-r-normal--*-*-*-*-m-*-iso8859-1 +CI -adobe-courier-medium-o-normal--*-*-*-*-m-*-iso8859-1 +CB -adobe-courier-bold-r-normal--*-*-*-*-m-*-iso8859-1 +CBI -adobe-courier-bold-o-normal--*-*-*-*-m-*-iso8859-1 +HR -adobe-helvetica-medium-r-normal--*-*-*-*-p-*-iso8859-1 +HI -adobe-helvetica-medium-o-normal--*-*-*-*-p-*-iso8859-1 +HB -adobe-helvetica-bold-r-normal--*-*-*-*-p-*-iso8859-1 +HBI -adobe-helvetica-bold-o-normal--*-*-*-*-p-*-iso8859-1 +NR -adobe-new century schoolbook-medium-r-normal--*-*-*-*-p-*-iso8859-1 +NI -adobe-new century schoolbook-medium-i-normal--*-*-*-*-p-*-iso8859-1 +NB -adobe-new century schoolbook-bold-r-normal--*-*-*-*-p-*-iso8859-1 +NBI -adobe-new century schoolbook-bold-i-normal--*-*-*-*-p-*-iso8859-1 +S -adobe-symbol-medium-r-normal--*-*-*-*-p-*-adobe-fontspecific diff --git a/src/devices/xditview/GXditview-color.ad b/src/devices/xditview/GXditview-color.ad new file mode 100644 index 0000000..61abd8f --- /dev/null +++ b/src/devices/xditview/GXditview-color.ad @@ -0,0 +1,15 @@ + +#include "GXditview" + +GXditview.paned.viewport.Scrollbar.background: Thistle +GXditview.paned.viewport.Scrollbar.foreground: Orchid +GXditview.paned.viewport.Scrollbar.thumb: None +GXditview.paned.viewport.dvi.background: LemonChiffon +GXditview.paned.viewport.background: Thistle +GXditview.paned.label.background: PeachPuff +GXditview.menu.background: Gold +GXditview.promptShell.promptDialog*background: Gold +GXditview.promptShell.promptDialog.accept.background: DarkOliveGreen1 +GXditview.promptShell.promptDialog.cancel.background: RosyBrown1 +GXditview.promptShell.promptDialog.value.background: Khaki + diff --git a/src/devices/xditview/GXditview.ad b/src/devices/xditview/GXditview.ad new file mode 100644 index 0000000..549f0d7 --- /dev/null +++ b/src/devices/xditview/GXditview.ad @@ -0,0 +1,71 @@ + +GXditview*shapeStyle: rectangle + +GXditview.paned.allowResize: true +GXditview.paned.label.skipAdjust: true +GXditview.paned.viewport.skipAdjust: false +GXditview.paned.viewport.showGrip: false +GXditview.paned.viewport.allowVert: true +GXditview.paned.viewport.allowHoriz: true +GXditview.paned.viewport.forceBars: true +! viewport size = papersize * resol + scrollbarthickness + 1 +! letter size paper +!GXditview.paned.viewport.width: 652 +!GXditview.paned.viewport.height: 840 +! a4 size paper +! 865 is wide enough for a page of X100-12. +GXditview.paned.viewport.width: 865 +GXditview.paned.viewport.height: 892 +GXditview.paned.viewport.Scrollbar.thickness: 14 + +GXditview.geometry: 865x892 + +GXditview.paned.translations: #augment \ + Next: NextPage()\n\ + n: NextPage()\n\ + space: NextPage()\n\ + Return: NextPage()\n\ + Prior: PreviousPage()\n\ + p: PreviousPage()\n\ + b: PreviousPage()\n\ + BackSpace: PreviousPage()\n\ + Delete: PreviousPage()\n\ + g: SelectPage()\n\ + o: OpenFile()\n\ + r: Rerasterize()\n\ + q: Quit() +GXditview.paned.viewport.clip.translations: #augment \ + : XawPositionSimpleMenu(menu) MenuPopup(menu) +GXditview.paned.label.translations: #augment \ + : XawPositionSimpleMenu(menu) MenuPopup(menu) +GXditview.paned.viewport.vertical.accelerators: #override \ + k: StartScroll(Backward) NotifyScroll(FullLength) EndScroll()\n\ + j: StartScroll(Forward) NotifyScroll(FullLength) EndScroll()\n\ + Up: StartScroll(Backward) NotifyScroll(FullLength) EndScroll()\n\ + Down: StartScroll(Forward) NotifyScroll(FullLength) EndScroll() +GXditview.paned.viewport.horizontal.accelerators: #override \ + h: StartScroll(Backward) NotifyScroll(FullLength) EndScroll()\n\ + l: StartScroll(Forward) NotifyScroll(FullLength) EndScroll()\n\ + Left: StartScroll(Backward) NotifyScroll(FullLength) EndScroll()\n\ + Right: StartScroll(Forward) NotifyScroll(FullLength) EndScroll() + +GXditview.menu.nextPage.label: Next Page +GXditview.menu.previousPage.label: Previous Page +GXditview.menu.selectPage.label: Goto Page +GXditview.menu.print.label: Print +GXditview.menu.openFile.label: Open +GXditview.menu.quit.label: Quit + +GXditview.promptShell.allowShellResize: true +GXditview.promptShell.promptDialog.value.translations: #override \ + Return: Accept() \n\ + Escape: Cancel() + +GXditview.promptShell.promptDialog.accept.label: Accept +GXditview.promptShell.promptDialog.accept.translations: #override \ + : Accept() unset() + +GXditview.promptShell.promptDialog.cancel.label: Cancel +GXditview.promptShell.promptDialog.cancel.translations: #override \ + : Cancel() unset() + diff --git a/src/devices/xditview/Menu.h b/src/devices/xditview/Menu.h new file mode 100644 index 0000000..c306b27 --- /dev/null +++ b/src/devices/xditview/Menu.h @@ -0,0 +1,46 @@ +/* + * $XConsortium: Menu.h,v 1.2 89/07/21 14:22:10 jim Exp $ + */ + +#ifndef _XtMenu_h +#define _XtMenu_h + +/*********************************************************************** + * + * Menu Widget + * + ***********************************************************************/ + +/* Parameters: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background pixel White + border BorderColor pixel Black + borderWidth BorderWidth int 1 + height Height int 120 + mappedWhenManaged MappedWhenManaged Boolean True + reverseVideo ReverseVideo Boolean False + width Width int 120 + x Position int 0 + y Position int 0 + +*/ + +#define XtNmenuEntries "menuEntries" +#define XtNhorizontalPadding "horizontalPadding" +#define XtNverticalPadding "verticalPadding" +#define XtNselection "Selection" + +#define XtCMenuEntries "MenuEntries" +#define XtCPadding "Padding" +#define XtCSelection "Selection" + +typedef struct _MenuRec *MenuWidget; /* completely defined in MenuPrivate.h */ +typedef struct _MenuClassRec *MenuWidgetClass; /* completely defined in MenuPrivate.h */ + +extern WidgetClass menuWidgetClass; + +extern Widget XawMenuCreate (); +#endif /* _XtMenu_h */ +/* DON'T ADD STUFF AFTER THIS #endif */ diff --git a/src/devices/xditview/README b/src/devices/xditview/README new file mode 100644 index 0000000..9de7869 --- /dev/null +++ b/src/devices/xditview/README @@ -0,0 +1,13 @@ +This is gxditview, an X11 previewer for groff based on MIT's xditview. +This version can be used with the output of gtroff -Tps as well as +with -TX75 and -TX100. You will need X11R5 or newer to install it (it +might work on X11R4, but I haven't tested it.) + +Previously, gxditview was installed in the usual place for X binaries +(e.g., /usr/bin/X11); you have to remove it manually. + +xditview is copyrighted by MIT under the usual X terms (see +gxditview.man); the changes to that which come along with the groff package +are in the public domain. + +Please report bugs at http://savannah.gnu.org/bugs/?group=groff. diff --git a/src/devices/xditview/TODO b/src/devices/xditview/TODO new file mode 100644 index 0000000..0b5b140 --- /dev/null +++ b/src/devices/xditview/TODO @@ -0,0 +1,21 @@ +Open the main window with the correct width and height, depending on +both the selected device and the paper dimensions. + +Add a command-line option to specify the paper dimensions (similar to +other groff devices). + +Better error handling. + +Resource and command-line option to specify font path. + +Resource to specify name of environment variable from which to get the +font path. + +Have character substitutions (currently done in draw.c:FakeCharacter) +specified in a resource (similar format to FontMap). + +The initial width of the dialog box should expand to accommodate the +default value. + +Option in Print dialog to specify that only the current page should be +printed. diff --git a/src/devices/xditview/ad2c b/src/devices/xditview/ad2c new file mode 100644 index 0000000..2ec45ed --- /dev/null +++ b/src/devices/xditview/ad2c @@ -0,0 +1,64 @@ +#! /bin/sh +# +# ad2c : Convert app-defaults file to C strings decls. +# +# George Ferguson, ferguson@cs.rcohester.edu, 12 Nov 1990. +# 19 Mar 1991: gf +# Made it self-contained. +# 6 Jan 1992: mycroft@gnu.ai.mit.edu (Charles Hannum) +# Removed use of "-n" and ":read" label since Gnu and +# IBM sed print pattern space on "n" command. Still works +# with Sun sed, of course. +# 7 Jan 1992: matthew@sunpix.East.Sun.COM (Matthew Stier) +# Escape quotes after escaping backslashes. +# 8 Jul 1992: Version 1.6 +# Manpage fixes. +# 19 Apr 1993: Version 1.7 +# Remove comments that were inside the sed command since +# some versions of sed don't like them. The comments are +# now given here in the header. +# 31 May 2004: Werner Lemberg +# Force casts to 'String'. +# +# Comments on the script by line: +# /^!/d Remove comments +# /^$/d Remove blanks +# s/\\/\\\\/g Escape backslashes... +# s/\\$//g ...except the line continuation ones +# s/"/\\"/g Escape quotes +# s/^/"/ Add leading quote and cast +# : test Establish label for later branch +# /\\$/b slash Branch to label "slash" if line ends in backslash +# s/$/",/ Otherwise add closing quote and comma... +# p ...output the line... +# d ...and clear the pattern space so it's not printed again +# : slash Branch comes here if line ends in backslash +# n Read next line, append to pattern space +# [...] The "d" and "s" commands that follow just delete +# comments and blank lines and escape control sequences +# b test Branch up to see if the line ends in backslash or not +# + +sed ' +/^!/d +/^$/d +s/\\/\\\\/g +s/\\$//g +s/"/\\"/g +s/^/(String)"/ +: test +/\\$/b slash +s/$/",/ +p +d +: slash +n +/^!/d +/^$/d +s/"/\\"/g +s/\\\\/\\/g +s/\\n/\\\\n/g +s/\\t/\\\\t/g +s/\\f/\\\\f/g +s/\\b/\\\\b/g +b test' "$@" diff --git a/src/devices/xditview/device.c b/src/devices/xditview/device.c new file mode 100644 index 0000000..1eaafbe --- /dev/null +++ b/src/devices/xditview/device.c @@ -0,0 +1,565 @@ +/* device.c */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include +#include + +#include "device.h" +#include "defs.h" + +#ifndef isascii +#define isascii(c) (1) +#endif + +/* Name of environment variable containing path to be used for +searching for device and font description files. */ +#define FONTPATH_ENV_VAR "GROFF_FONT_PATH" + +#define WS " \t\r\n" + +#ifndef INT_MIN +/* Minimum and maximum values a 'signed int' can hold. */ +#define INT_MIN (-INT_MAX-1) +#define INT_MAX 2147483647 +#endif + +#define CHAR_TABLE_SIZE 307 + +struct _DeviceFont { + char *name; + int special; + DeviceFont *next; + Device *dev; + struct charinfo *char_table[CHAR_TABLE_SIZE]; + struct charinfo *code_table[256]; +}; + +struct charinfo { + int width; + int code; + struct charinfo *next; + struct charinfo *code_next; + char name[1]; +}; + +static char *current_filename = 0; +static int current_lineno = -1; + +static void error(const char *s); +static FILE *open_device_file(const char *, const char *, char **); +static DeviceFont *load_font(Device *, const char *); +static Device *new_device(const char *); +static DeviceFont *new_font(const char *, Device *); +static void delete_font(DeviceFont *); +static unsigned hash_name(const char *); +static struct charinfo *add_char(DeviceFont *, const char *, int, int); +static int read_charset_section(DeviceFont *, FILE *); +static char *canonicalize_name(const char *); +static int scale_round(int, int, int); + +static +Device *new_device(const char *name) +{ + Device *dev; + + dev = XtNew(Device); + dev->sizescale = 1; + dev->res = 0; + dev->unitwidth = 0; + dev->fonts = 0; + dev->X11 = 0; + dev->paperlength = 0; + dev->paperwidth = 0; + dev->name = XtNewString(name); + return dev; +} + +void device_destroy(Device *dev) +{ + DeviceFont *f; + + if (!dev) + return; + f = dev->fonts; + while (f) { + DeviceFont *tem = f; + f = f->next; + delete_font(tem); + } + + XtFree(dev->name); + XtFree((char *)dev); +} + +Device *device_load(const char *name) +{ + Device *dev; + FILE *fp; + int err = 0; + char buf[256]; + + fp = open_device_file(name, "DESC", ¤t_filename); + if (!fp) + return 0; + dev = new_device(name); + current_lineno = 0; + while (fgets(buf, sizeof(buf), fp)) { + char *p; + current_lineno++; + p = strtok(buf, WS); + if (p) { + int *np = 0; + char *q; + + if (strcmp(p, "charset") == 0) + break; + if (strcmp(p, "X11") == 0) + dev->X11 = 1; + else if (strcmp(p, "sizescale") == 0) + np = &dev->sizescale; + else if (strcmp(p, "res") == 0) + np = &dev->res; + else if (strcmp(p, "unitwidth") == 0) + np = &dev->unitwidth; + else if (strcmp(p, "paperwidth") == 0) + np = &dev->paperwidth; + else if (strcmp(p, "paperlength") == 0) + np = &dev->paperlength; + + if (np) { + q = strtok((char *)0, WS); + if (!q || sscanf(q, "%d", np) != 1 || *np <= 0) { + error("bad argument"); + err = 1; + break; + } + } + } + } + fclose(fp); + current_lineno = -1; + if (!err) { + if (dev->res == 0) { + error("missing res line"); + err = 1; + } + else if (dev->unitwidth == 0) { + error("missing unitwidth line"); + err = 1; + } + } + if (dev->paperlength == 0) + dev->paperlength = dev->res*11; + if (dev->paperwidth == 0) + dev->paperwidth = dev->res*8 + dev->res/2; + if (err) { + device_destroy(dev); + dev = 0; + } + XtFree(current_filename); + current_filename = 0; + return dev; +} + + +DeviceFont *device_find_font(Device *dev, const char *name) +{ + DeviceFont *f; + + if (!dev) + return 0; + for (f = dev->fonts; f; f = f->next) + if (strcmp(f->name, name) == 0) + return f; + return load_font(dev, name); +} + +static +DeviceFont *load_font(Device *dev, const char *name) +{ + FILE *fp; + char buf[256]; + DeviceFont *f; + int special = 0; + + fp = open_device_file(dev->name, name, ¤t_filename); + if (!fp) + return 0; + current_lineno = 0; + for (;;) { + char *p; + + if (!fgets(buf, sizeof(buf), fp)) { + error("no charset line"); + return 0; + } + current_lineno++; + p = strtok(buf, WS); + /* charset must be on a line by itself */ + if (p && strcmp(p, "charset") == 0 && strtok((char *)0, WS) == 0) + break; + if (p && strcmp(p, "special") == 0) + special = 1; + } + f = new_font(name, dev); + f->special = special; + if (!read_charset_section(f, fp)) { + delete_font(f); + f = 0; + } + else { + f->next = dev->fonts; + dev->fonts = f; + } + fclose(fp); + XtFree(current_filename); + current_filename = 0; + return f; +} + +static +DeviceFont *new_font(const char *name, Device *dev) +{ + int i; + DeviceFont *f; + + f = XtNew(DeviceFont); + f->name = XtNewString(name); + f->dev = dev; + f->special = 0; + f->next = 0; + for (i = 0; i < CHAR_TABLE_SIZE; i++) + f->char_table[i] = 0; + for (i = 0; i < 256; i++) + f->code_table[i] = 0; + return f; +} + +static +void delete_font(DeviceFont *f) +{ + int i; + + if (!f) + return; + XtFree(f->name); + for (i = 0; i < CHAR_TABLE_SIZE; i++) { + struct charinfo *ptr = f->char_table[i]; + while (ptr) { + struct charinfo *tem = ptr; + ptr = ptr->next; + XtFree((char *)tem); + } + } + XtFree((char *)f); +} + + +static +unsigned hash_name(const char *name) +{ + unsigned n = 0; + /* XXX do better than this */ + while (*name) + n = (n << 1) ^ *name++; + + return n; +} + +static +int scale_round(int n, int x, int y) +{ + int y2; + + if (x == 0) + return 0; + y2 = y/2; + if (n >= 0) { + if (n <= (INT_MAX - y2)/x) + return (n*x + y2)/y; + return (int)(n*(double)x/(double)y + .5); + } + else { + if (-(unsigned)n <= (-(unsigned)INT_MIN - y2)/x) + return (n*x - y2)/y; + return (int)(n*(double)x/(double)y + .5); + } +} + +static +char *canonicalize_name(const char *s) +{ + static char ch[2]; + if (s[0] == 'c' && s[1] == 'h' && s[2] == 'a' && s[3] == 'r') { + const char *p; + int n; + + for (p = s + 4; *p; p++) + if (!isascii(*p) || !isdigit((unsigned char)*p)) + return (char *)s; + n = atoi(s + 4); + if (n >= 0 && n <= 0xff) { + ch[0] = (char)n; + return ch; + } + } + return (char *)s; +} + +/* Return 1 if the character is present in the font; widthp gets the +width if non-null. */ + +int device_char_width(DeviceFont *f, int ps, const char *name, int *widthp) +{ + struct charinfo *p; + + name = canonicalize_name(name); + for (p = f->char_table[hash_name(name) % CHAR_TABLE_SIZE];; p = p->next) { + if (!p) + return 0; + if (strcmp(p->name, name) == 0) + break; + } + *widthp = scale_round(p->width, ps, f->dev->unitwidth); + return 1; +} + +int device_code_width(DeviceFont *f, int ps, int code, int *widthp) +{ + struct charinfo *p; + + for (p = f->code_table[code & 0xff];; p = p->code_next) { + if (!p) + return 0; + if (p->code == code) + break; + } + *widthp = scale_round(p->width, ps, f->dev->unitwidth); + return 1; +} + +char *device_name_for_code(DeviceFont *f, int code) +{ + static struct charinfo *state = 0; + if (f) + state = f->code_table[code & 0xff]; + for (; state; state = state->code_next) + if (state->code == code && state->name[0] != '\0') { + char *name = state->name; + state = state->code_next; + return name; + } + return 0; +} + +int device_font_special(DeviceFont *f) +{ + return f->special; +} + +static +struct charinfo *add_char(DeviceFont *f, const char *name, int width, int code) +{ + struct charinfo **pp; + struct charinfo *ci; + + name = canonicalize_name(name); + if (strcmp(name, "---") == 0) + name = ""; + + ci = (struct charinfo *)XtMalloc(XtOffsetOf(struct charinfo, name[0]) + + strlen(name) + 1); + + strcpy(ci->name, name); + ci->width = width; + ci->code = code; + + if (*name != '\0') { + pp = &f->char_table[hash_name(name) % CHAR_TABLE_SIZE]; + ci->next = *pp; + *pp = ci; + } + pp = &f->code_table[code & 0xff]; + ci->code_next = *pp; + *pp = ci; + return ci; +} + +/* Return non-zero for success. */ + +static +int read_charset_section(DeviceFont *f, FILE *fp) +{ + struct charinfo *last_charinfo = 0; + char buf[256]; + + while (fgets(buf, sizeof(buf), fp)) { + char *name; + int width; + int code; + char *p; + + current_lineno++; + name = strtok(buf, WS); + if (!name) + continue; /* ignore blank lines */ + p = strtok((char *)0, WS); + if (!p) /* end of charset section */ + break; + if (strcmp(p, "\"") == 0) { + if (!last_charinfo) { + error("first line of charset section cannot use '\"'"); + return 0; + } + else + (void)add_char(f, name, + last_charinfo->width, last_charinfo->code); + } + else { + char *q; + if (sscanf(p, "%d", &width) != 1) { + error("bad width field"); + return 0; + } + p = strtok((char *)0, WS); + if (!p) { + error("missing type field"); + return 0; + } + p = strtok((char *)0, WS); + if (!p) { + error("missing code field"); + return 0; + } + code = (int)strtol(p, &q, 0); + if (q == p) { + error("bad code field"); + return 0; + } + last_charinfo = add_char(f, name, width, code); + } + } + return 1; +} + +static +FILE *find_file(const char *file, char **result) +{ + char *buf = NULL; + int bufsiz = 0; + int flen; + FILE *fp; + char *path; + char *env; + + env = getenv(FONTPATH_ENV_VAR); + path = XtMalloc(((env && *env) ? strlen(env) + 1 : 0) + + strlen(FONTPATH) + 1); + *path = '\0'; + if (env && *env) { + strcat(path, env); + strcat(path, ":"); + } + strcat(path, FONTPATH); + + *result = NULL; + + if (file == NULL) + return NULL; + if (*file == '\0') + return NULL; + + if (*file == '/') { + fp = fopen(file, "r"); + if (fp) + *result = XtNewString(file); + return fp; + } + + flen = strlen(file); + + while (*path) { + int len; + char *start, *end; + + start = path; + end = strchr(path, ':'); + if (end) + path = end + 1; + else + path = end = strchr(path, '\0'); + if (start >= end) + continue; + if (end[-1] == '/') + --end; + len = (end - start) + 1 + flen + 1; + if (len > bufsiz) { + if (buf) + buf = XtRealloc(buf, len); + else + buf = XtMalloc(len); + bufsiz = len; + } + memcpy(buf, start, end - start); + buf[end - start] = '/'; + strcpy(buf + (end - start) + 1, file); + fp = fopen(buf, "r"); + if (fp) { + *result = buf; + return fp; + } + } + XtFree(buf); + return NULL; +} + +static +FILE *open_device_file(const char *device_name, const char *file_name, + char **result) +{ + char *buf; + FILE *fp; + + buf = XtMalloc(3 + strlen(device_name) + 1 + strlen(file_name) + 1); + sprintf(buf, "dev%s/%s", device_name, file_name); + fp = find_file(buf, result); + if (!fp) { + fprintf(stderr, "can't find device file '%s'\n", file_name); + fflush(stderr); + } + XtFree(buf); + return fp; +} + +static +void error(const char *s) +{ + if (current_filename) { + fprintf(stderr, "%s:", current_filename); + if (current_lineno > 0) + fprintf(stderr, "%d:", current_lineno); + putc(' ', stderr); + } + fputs(s, stderr); + putc('\n', stderr); + fflush(stderr); +} + +/* +Local Variables: +c-indent-level: 4 +c-continued-statement-offset: 4 +c-brace-offset: -4 +c-argdecl-indent: 4 +c-label-offset: -4 +c-tab-always-indent: nil +End: +*/ diff --git a/src/devices/xditview/device.h b/src/devices/xditview/device.h new file mode 100644 index 0000000..6f2944b --- /dev/null +++ b/src/devices/xditview/device.h @@ -0,0 +1,21 @@ + +typedef struct _DeviceFont DeviceFont; + +typedef struct _Device { + char *name; + int sizescale; + int res; + int unitwidth; + int paperlength; + int paperwidth; + int X11; + DeviceFont *fonts; +} Device; + +void device_destroy(Device *); +Device *device_load(const char *); +DeviceFont *device_find_font(Device *, const char *); +int device_char_width(DeviceFont *, int, const char *, int *); +char *device_name_for_code(DeviceFont *, int); +int device_code_width(DeviceFont *, int, int, int *); +int device_font_special(DeviceFont *); diff --git a/src/devices/xditview/draw.c b/src/devices/xditview/draw.c new file mode 100644 index 0000000..288d98a --- /dev/null +++ b/src/devices/xditview/draw.c @@ -0,0 +1,709 @@ +/* + * draw.c + * + * accept dvi function calls and translate to X + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +/* math.h on a Sequent doesn't define M_PI, apparently */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#include "DviP.h" +#include "draw.h" +#include "font.h" + +#define DeviceToX(dw, n) ((int)((n) * (dw)->dvi.scale_factor + .5)) +#define XPos(dw) (DeviceToX((dw), (dw)->dvi.state->x - \ + (dw)->dvi.text_device_width) + (dw)->dvi.text_x_width) +#define YPos(dw) (DeviceToX((dw), (dw)->dvi.state->y)) + +/* forward reference */ +static int FakeCharacter(DviWidget, char *, int); + +/* shadowed by a macro definition in parse.c, and unused elsewhere */ +#if 0 +static void +HorizontalMove(DviWidget dw, int delta) +{ + dw->dvi.state->x += delta; +} +#endif + +void +HorizontalGoto(DviWidget dw, int NewPosition) +{ + dw->dvi.state->x = NewPosition; +} + +void +VerticalMove(DviWidget dw, int delta) +{ + dw->dvi.state->y += delta; +} + +void +VerticalGoto(DviWidget dw, int NewPosition) +{ + dw->dvi.state->y = NewPosition; +} + +static void +AdjustCacheDeltas (DviWidget dw) +{ + int extra; + int nadj; + int i; + + nadj = 0; + extra = DeviceToX(dw, dw->dvi.text_device_width) + - dw->dvi.text_x_width; + if (extra == 0) + return; + for (i = 0; i <= dw->dvi.cache.index; i++) + if (dw->dvi.cache.adjustable[i]) + ++nadj; + dw->dvi.text_x_width += extra; + if (nadj <= 1) + return; + for (i = 0; i <= dw->dvi.cache.index; i++) + if (dw->dvi.cache.adjustable[i]) { + int x; + int *deltap; + + x = extra/nadj; + deltap = &dw->dvi.cache.cache[i].delta; +#define MIN_DELTA 2 + if (*deltap > 0 && x + *deltap < MIN_DELTA) { + x = MIN_DELTA - *deltap; + if (x <= 0) + *deltap = MIN_DELTA; + else + x = 0; + } + else + *deltap += x; + extra -= x; + --nadj; + dw->dvi.cache.adjustable[i] = 0; + } +} + +void +FlushCharCache (DviWidget dw) +{ + if (dw->dvi.cache.char_index != 0) { + AdjustCacheDeltas (dw); + XDrawText (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC, + dw->dvi.cache.start_x, dw->dvi.cache.start_y, + dw->dvi.cache.cache, dw->dvi.cache.index + 1); + } + dw->dvi.cache.index = 0; + dw->dvi.cache.max = DVI_TEXT_CACHE_SIZE; +#if 0 + if (dw->dvi.noPolyText) + dw->dvi.cache.max = 1; +#endif + dw->dvi.cache.char_index = 0; + dw->dvi.cache.cache[0].nchars = 0; + dw->dvi.cache.start_x = dw->dvi.cache.x = XPos (dw); + dw->dvi.cache.start_y = dw->dvi.cache.y = YPos (dw); +} + +void +Newline (DviWidget dw) +{ + FlushCharCache (dw); + dw->dvi.text_x_width = dw->dvi.text_device_width = 0; + dw->dvi.word_flag = 0; +} + +void +Word (DviWidget dw) +{ + dw->dvi.word_flag = 1; +} + +#define charWidth(fi,c) (\ + (fi)->per_char ?\ + (fi)->per_char[(c) - (fi)->min_char_or_byte2].width\ + :\ + (fi)->max_bounds.width\ +) + + +static +int charExists (XFontStruct *fi, int c) +{ + XCharStruct *p; + + /* 'c' is always >= 0 */ + if (fi->per_char == NULL + || (unsigned int)c < fi->min_char_or_byte2 + || (unsigned int)c > fi->max_char_or_byte2) + return 0; + p = fi->per_char + (c - fi->min_char_or_byte2); + return (p->lbearing != 0 || p->rbearing != 0 || p->width != 0 + || p->ascent != 0 || p->descent != 0 || p->attributes != 0); +} + +/* 'wid' is in device units */ +static void +DoCharacter (DviWidget dw, int c, int wid) +{ + register XFontStruct *font; + register XTextItem *text; + int x, y; + + x = XPos(dw); + y = YPos(dw); + + /* + * quick and dirty extents calculation: + */ + if (!(y + 24 >= dw->dvi.extents.y1 + && y - 24 <= dw->dvi.extents.y2 +#if 0 + && x + 24 >= dw->dvi.extents.x1 + && x - 24 <= dw->dvi.extents.x2 +#endif + )) + return; + + if (y != dw->dvi.cache.y + || dw->dvi.cache.char_index >= DVI_CHAR_CACHE_SIZE) { + FlushCharCache (dw); + x = dw->dvi.cache.x; + dw->dvi.cache.adjustable[dw->dvi.cache.index] = 0; + } + /* + * load a new font, if the current block is not empty, + * step to the next. + */ + if (dw->dvi.cache.font_size != dw->dvi.state->font_size || + dw->dvi.cache.font_number != dw->dvi.state->font_number) + { + FlushCharCache (dw); + x = dw->dvi.cache.x; + dw->dvi.cache.font_size = dw->dvi.state->font_size; + dw->dvi.cache.font_number = dw->dvi.state->font_number; + dw->dvi.cache.font = QueryFont (dw, + dw->dvi.cache.font_number, + dw->dvi.cache.font_size); + if (dw->dvi.cache.cache[dw->dvi.cache.index].nchars != 0) { + ++dw->dvi.cache.index; + if (dw->dvi.cache.index >= dw->dvi.cache.max) + FlushCharCache (dw); + dw->dvi.cache.cache[dw->dvi.cache.index].nchars = 0; + dw->dvi.cache.adjustable[dw->dvi.cache.index] = 0; + } + } + if (x != dw->dvi.cache.x || dw->dvi.word_flag) { + if (dw->dvi.cache.cache[dw->dvi.cache.index].nchars != 0) { + ++dw->dvi.cache.index; + if (dw->dvi.cache.index >= dw->dvi.cache.max) + FlushCharCache (dw); + dw->dvi.cache.cache[dw->dvi.cache.index].nchars = 0; + dw->dvi.cache.adjustable[dw->dvi.cache.index] = 0; + } + dw->dvi.cache.adjustable[dw->dvi.cache.index] + = dw->dvi.word_flag; + dw->dvi.word_flag = 0; + } + font = dw->dvi.cache.font; + text = &dw->dvi.cache.cache[dw->dvi.cache.index]; + if (text->nchars == 0) { + text->chars = &dw->dvi.cache.char_cache[dw->dvi.cache.char_index]; + text->delta = x - dw->dvi.cache.x; + if (font != dw->dvi.font) { + text->font = font->fid; + dw->dvi.font = font; + } else + text->font = None; + dw->dvi.cache.x += text->delta; + } + if (charExists(font, c)) { + int w; + dw->dvi.cache.char_cache[dw->dvi.cache.char_index++] = (char) c; + ++text->nchars; + w = charWidth(font, c); + dw->dvi.cache.x += w; + if (wid != 0) { + dw->dvi.text_x_width += w; + dw->dvi.text_device_width += wid; + } + } +} + +static +int FindCharWidth (DviWidget dw, char *buf, int *widp) +{ + int maxpos; + int i; + + if (dw->dvi.device_font == 0 + || dw->dvi.state->font_number != dw->dvi.device_font_number) { + dw->dvi.device_font_number = dw->dvi.state->font_number; + dw->dvi.device_font + = QueryDeviceFont (dw, dw->dvi.device_font_number); + } + if (dw->dvi.device_font + && device_char_width (dw->dvi.device_font, + dw->dvi.state->font_size, buf, widp)) + return 1; + + maxpos = MaxFontPosition (dw); + for (i = 1; i <= maxpos; i++) { + DeviceFont *f = QueryDeviceFont (dw, i); + if (f && device_font_special (f) + && device_char_width (f, dw->dvi.state->font_size, + buf, widp)) { + dw->dvi.state->font_number = i; + return 1; + } + } + return 0; +} + +/* Return the width of the character in device units. */ + +int +PutCharacter (DviWidget dw, char *buf) +{ + int prevFont; + int c = -1; + int wid = 0; + DviCharNameMap *map; + + if (!dw->dvi.display_enable) + return 0; /* The width doesn't matter in this case. */ + prevFont = dw->dvi.state->font_number; + if (!FindCharWidth (dw, buf, &wid)) + return 0; + map = QueryFontMap (dw, dw->dvi.state->font_number); + if (map) + c = DviCharIndex (map, buf); + if (c >= 0) + DoCharacter (dw, c, wid); + else + (void) FakeCharacter (dw, buf, wid); + dw->dvi.state->font_number = prevFont; + return wid; +} + +/* Return 1 if we can fake it; 0 otherwise. */ + +static +int FakeCharacter (DviWidget dw, char *buf, int wid) +{ + int oldx, oldw; + char ch[2]; + const char *chars = 0; + + if (buf[0] == '\0' || buf[1] == '\0' || buf[2] != '\0') + return 0; +#define pack2(c1, c2) (((c1) << 8) | (c2)) + + switch (pack2(buf[0], buf[1])) { + case pack2('f', 'i'): + chars = "fi"; + break; + case pack2('f', 'l'): + chars = "fl"; + break; + case pack2('f', 'f'): + chars = "ff"; + break; + case pack2('F', 'i'): + chars = "ffi"; + break; + case pack2('F', 'l'): + chars = "ffl"; + break; + } + if (!chars) + return 0; + oldx = dw->dvi.state->x; + oldw = dw->dvi.text_device_width; + ch[1] = '\0'; + for (; *chars; chars++) { + ch[0] = *chars; + dw->dvi.state->x += PutCharacter (dw, ch); + } + dw->dvi.state->x = oldx; + dw->dvi.text_device_width = oldw + wid; + return 1; +} + +void +PutNumberedCharacter (DviWidget dw, int c) +{ + char *name; + int wid; + DviCharNameMap *map; + + if (!dw->dvi.display_enable) + return; + + if (dw->dvi.device_font == 0 + || dw->dvi.state->font_number != dw->dvi.device_font_number) { + dw->dvi.device_font_number = dw->dvi.state->font_number; + dw->dvi.device_font + = QueryDeviceFont (dw, dw->dvi.device_font_number); + } + + if (dw->dvi.device_font == 0 + || !device_code_width (dw->dvi.device_font, + dw->dvi.state->font_size, c, &wid)) + return; + if (dw->dvi.native) { + DoCharacter (dw, c, wid); + return; + } + map = QueryFontMap (dw, dw->dvi.state->font_number); + if (!map) + return; + for (name = device_name_for_code (dw->dvi.device_font, c); + name; + name = device_name_for_code ((DeviceFont *)0, c)) { + int code = DviCharIndex (map, name); + if (code >= 0) { + DoCharacter (dw, code, wid); + break; + } + if (FakeCharacter (dw, name, wid)) + break; + } +} + +/* unused */ +#if 0 +static void +ClearPage (DviWidget dw) +{ + XClearWindow (XtDisplay (dw), XtWindow (dw)); +} +#endif + +static void +setGC (DviWidget dw) +{ + int desired_line_width; + + if (dw->dvi.line_thickness < 0) + desired_line_width = (int)(((double)dw->dvi.device_resolution + * dw->dvi.state->font_size) + / (10.0*72.0*dw->dvi.sizescale)); + else + desired_line_width = dw->dvi.line_thickness; + + if (desired_line_width != dw->dvi.line_width) { + XGCValues values; + values.line_width = DeviceToX(dw, desired_line_width); + if (values.line_width == 0) + values.line_width = 1; + XChangeGC(XtDisplay (dw), dw->dvi.normal_GC, + GCLineWidth, &values); + dw->dvi.line_width = desired_line_width; + } +} + +static void +setFillGC (DviWidget dw) +{ + int fill_type; + unsigned long mask = GCFillStyle | GCForeground; + + fill_type = (dw->dvi.fill * 10) / (DVI_FILL_MAX + 1); + if (dw->dvi.fill_type != fill_type) { + XGCValues values; + if (fill_type <= 0) { + values.foreground = dw->dvi.background; + values.fill_style = FillSolid; + } else if (fill_type >= 9) { + values.foreground = dw->dvi.foreground; + values.fill_style = FillSolid; + } else { + values.foreground = dw->dvi.foreground; + values.fill_style = FillOpaqueStippled; + values.stipple = dw->dvi.gray[fill_type - 1]; + mask |= GCStipple; + } + XChangeGC(XtDisplay (dw), dw->dvi.fill_GC, mask, &values); + dw->dvi.fill_type = fill_type; + } +} + +void +DrawLine (DviWidget dw, int x, int y) +{ + int xp, yp; + + AdjustCacheDeltas (dw); + setGC (dw); + xp = XPos (dw); + yp = YPos (dw); + XDrawLine (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC, + xp, yp, + xp + DeviceToX (dw, x), yp + DeviceToX (dw, y)); +} + +void +DrawCircle (DviWidget dw, int diam) +{ + int d; + + AdjustCacheDeltas (dw); + setGC (dw); + d = DeviceToX (dw, diam); + XDrawArc (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC, + XPos (dw), YPos (dw) - d/2, + d, d, 0, 64*360); +} + +void +DrawFilledCircle (DviWidget dw, int diam) +{ + int d; + + AdjustCacheDeltas (dw); + setFillGC (dw); + d = DeviceToX (dw, diam); + XFillArc (XtDisplay (dw), XtWindow (dw), dw->dvi.fill_GC, + XPos (dw), YPos (dw) - d/2, + d, d, 0, 64*360); + XDrawArc (XtDisplay (dw), XtWindow (dw), dw->dvi.fill_GC, + XPos (dw), YPos (dw) - d/2, + d, d, 0, 64*360); +} + +void +DrawEllipse (DviWidget dw, int a, int b) +{ + AdjustCacheDeltas (dw); + setGC (dw); + XDrawArc (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC, + XPos (dw), YPos (dw) - DeviceToX (dw, b/2), + DeviceToX (dw, a), DeviceToX (dw, b), 0, 64*360); +} + +void +DrawFilledEllipse (DviWidget dw, int a, int b) +{ + AdjustCacheDeltas (dw); + setFillGC (dw); + XFillArc (XtDisplay (dw), XtWindow (dw), dw->dvi.fill_GC, + XPos (dw), YPos (dw) - DeviceToX (dw, b/2), + DeviceToX (dw, a), DeviceToX (dw, b), 0, 64*360); + XDrawArc (XtDisplay (dw), XtWindow (dw), dw->dvi.fill_GC, + XPos (dw), YPos (dw) - DeviceToX (dw, b/2), + DeviceToX (dw, a), DeviceToX (dw, b), 0, 64*360); +} + +void +DrawArc (DviWidget dw, int x_0, int y_0, int x_1, int y_1) +{ + int angle1, angle2; + int rad = (int)((sqrt ((double)x_0*x_0 + (double)y_0*y_0) + + sqrt ((double)x_1*x_1 + (double)y_1*y_1) + + 1.0)/2.0); + if ((x_0 == 0 && y_0 == 0) || (x_1 == 0 && y_1 == 0)) + return; + angle1 = (int)(atan2 ((double)y_0, (double)-x_0)*180.0*64.0/M_PI); + angle2 = (int)(atan2 ((double)-y_1, (double)x_1)*180.0*64.0/M_PI); + + angle2 -= angle1; + if (angle2 < 0) + angle2 += 64*360; + + AdjustCacheDeltas (dw); + setGC (dw); + + rad = DeviceToX (dw, rad); + XDrawArc (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC, + XPos (dw) + DeviceToX (dw, x_0) - rad, + YPos (dw) + DeviceToX (dw, y_0) - rad, + rad*2, rad*2, angle1, angle2); +} + +void +DrawPolygon (DviWidget dw, int *v, int n) +{ + XPoint *p; + int i; + int dx, dy; + + n /= 2; + + AdjustCacheDeltas (dw); + setGC (dw); + p = (XPoint *)XtMalloc((n + 2)*sizeof(XPoint)); + p[0].x = XPos (dw); + p[0].y = YPos (dw); + dx = 0; + dy = 0; + for (i = 0; i < n; i++) { + dx += v[2*i]; + p[i + 1].x = DeviceToX (dw, dx) + p[0].x; + dy += v[2*i + 1]; + p[i + 1].y = DeviceToX (dw, dy) + p[0].y; + } + p[n+1].x = p[0].x; + p[n+1].y = p[0].y; + XDrawLines (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC, + p, n + 2, CoordModeOrigin); + XtFree((char *)p); +} + +void +DrawFilledPolygon (DviWidget dw, int *v, int n) +{ + XPoint *p; + int i; + int dx, dy; + + n /= 2; + if (n < 2) + return; + + AdjustCacheDeltas (dw); + setFillGC (dw); + p = (XPoint *)XtMalloc((n + 2)*sizeof(XPoint)); + p[0].x = p[n+1].x = XPos (dw); + p[0].y = p[n+1].y = YPos (dw); + dx = 0; + dy = 0; + for (i = 0; i < n; i++) { + dx += v[2*i]; + p[i + 1].x = DeviceToX (dw, dx) + p[0].x; + dy += v[2*i + 1]; + p[i + 1].y = DeviceToX (dw, dy) + p[0].y; + } + XFillPolygon (XtDisplay (dw), XtWindow (dw), dw->dvi.fill_GC, + p, n + 1, Complex, CoordModeOrigin); + XDrawLines (XtDisplay (dw), XtWindow (dw), dw->dvi.fill_GC, + p, n + 2, CoordModeOrigin); + XtFree((char *)p); +} + +#define POINTS_MAX 10000 + +static void +appendPoint(XPoint *points, int *pointi, int x, int y) +{ + if (*pointi < POINTS_MAX) { + points[*pointi].x = x; + points[*pointi].y = y; + *pointi += 1; + } +} + +#define FLATNESS 1 + +static void +flattenCurve(XPoint *points, int *pointi, + int x_2, int y_2, int x_3, int y_3, int x_4, int y_4) +{ + int x_1, y_1, dx, dy, n1, n2, n; + + x_1 = points[*pointi - 1].x; + y_1 = points[*pointi - 1].y; + + dx = x_4 - x_1; + dy = y_4 - y_1; + + n1 = dy*(x_2 - x_1) - dx*(y_2 - y_1); + n2 = dy*(x_3 - x_1) - dx*(y_3 - y_1); + if (n1 < 0) + n1 = -n1; + if (n2 < 0) + n2 = -n2; + n = n1 > n2 ? n1 : n2; + + if (n*n / (dy*dy + dx*dx) <= FLATNESS*FLATNESS) + appendPoint (points, pointi, x_4, y_4); + else { + flattenCurve (points, pointi, + (x_1 + x_2)/2, + (y_1 + y_2)/2, + (x_1 + x_2*2 + x_3)/4, + (y_1 + y_2*2 + y_3)/4, + (x_1 + 3*x_2 + 3*x_3 + x_4)/8, + (y_1 + 3*y_2 + 3*y_3 + y_4)/8); + flattenCurve (points, pointi, + (x_2 + x_3*2 + x_4)/4, + (y_2 + y_3*2 + y_4)/4, + (x_3 + x_4)/2, + (y_3 + y_4)/2, + x_4, + y_4); + } +} + +void +DrawSpline (DviWidget dw, int *v, int n) +{ + int sx, sy, tx, ty; + int ox, oy, dx, dy; + int i; + int pointi; + XPoint points[POINTS_MAX]; + + if (n == 0 || (n & 1) != 0) + return; + AdjustCacheDeltas (dw); + setGC (dw); + ox = XPos (dw); + oy = YPos (dw); + dx = v[0]; + dy = v[1]; + sx = ox; + sy = oy; + tx = sx + DeviceToX (dw, dx); + ty = sy + DeviceToX (dw, dy); + + pointi = 0; + + appendPoint (points, &pointi, sx, sy); + appendPoint (points, &pointi, (sx + tx)/2, (sy + ty)/2); + + for (i = 2; i < n; i += 2) { + int ux = ox + DeviceToX (dw, dx += v[i]); + int uy = oy + DeviceToX (dw, dy += v[i+1]); + flattenCurve (points, &pointi, + (sx + tx*5)/6, (sy + ty*5)/6, + (tx*5 + ux)/6, (ty*5 + uy)/6, + (tx + ux)/2, (ty + uy)/2); + sx = tx; + sy = ty; + tx = ux; + ty = uy; + } + + appendPoint (points, &pointi, tx, ty); + + XDrawLines (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC, + points, pointi, CoordModeOrigin); +} + + +/* +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: +*/ diff --git a/src/devices/xditview/draw.h b/src/devices/xditview/draw.h new file mode 100644 index 0000000..7a3772c --- /dev/null +++ b/src/devices/xditview/draw.h @@ -0,0 +1,18 @@ +void HorizontalGoto(DviWidget, int); +void VerticalGoto(DviWidget, int); +void VerticalMove(DviWidget, int); +void FlushCharCache(DviWidget); +void Newline(DviWidget); +void Word(DviWidget); +int PutCharacter(DviWidget, char *); +void PutNumberedCharacter(DviWidget, int); +void DrawLine(DviWidget, int, int); +void DrawCircle(DviWidget, int); +void DrawFilledCircle(DviWidget, int); +void DrawEllipse(DviWidget, int, int); +void DrawFilledEllipse(DviWidget, int, int); +void DrawArc(DviWidget, int, int, int, int); +void DrawPolygon(DviWidget, int *, int); +void DrawFilledPolygon(DviWidget, int *, int); +void DrawSpline(DviWidget, int *, int); + diff --git a/src/devices/xditview/font.c b/src/devices/xditview/font.c new file mode 100644 index 0000000..8462608 --- /dev/null +++ b/src/devices/xditview/font.c @@ -0,0 +1,446 @@ +/* + * font.c + * + * map dvi fonts to X fonts + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "DviP.h" +#include "XFontName.h" +#include "font.h" + +/* forward reference */ +static void DisposeFontSizes(DviWidget, DviFontSizeList *); + +static char * +savestr (const char *s) +{ + char *n; + + if (!s) + return 0; + n = XtMalloc (strlen (s) + 1); + if (n) + strcpy (n, s); + return n; +} + +static DviFontList * +LookupFontByPosition (DviWidget dw, int position) +{ + DviFontList *f; + + for (f = dw->dvi.fonts; f; f = f->next) + if (f->dvi_number == position) + break; + return f; +} + +int +MaxFontPosition (DviWidget dw) +{ + DviFontList *f; + int n = -1; + + for (f = dw->dvi.fonts; f; f = f->next) + if (f->dvi_number > n) + n = f->dvi_number; + return n; +} + +static DviFontSizeList * +LookupFontSizeBySize (DviWidget dw, DviFontList *f, int size) +{ + DviFontSizeList *fs, *best = 0, *smallest = 0; + int bestsize = 0; + XFontName fontName; + unsigned int fontNameAttributes; + char fontNameString[2048]; + int decipointsize; + + if (f->scalable) { + decipointsize = (10*size)/dw->dvi.sizescale; + for (best = f->sizes; best; best = best->next) + if (best->size == decipointsize) + return best; + best = (DviFontSizeList *) XtMalloc(sizeof *best); + best->next = f->sizes; + best->size = decipointsize; + f->sizes = best; + XParseFontName (f->x_name, &fontName, &fontNameAttributes); + fontNameAttributes &= ~(FontNamePixelSize|FontNameAverageWidth); + fontNameAttributes |= FontNameResolutionX; + fontNameAttributes |= FontNameResolutionY; + fontNameAttributes |= FontNamePointSize; + fontName.ResolutionX = dw->dvi.display_resolution; + fontName.ResolutionY = dw->dvi.display_resolution; + fontName.PointSize = decipointsize; + XFormatFontName (&fontName, fontNameAttributes, fontNameString); + best->x_name = savestr (fontNameString); + best->doesnt_exist = 0; + best->font = 0; + return best; + } + for (fs = f->sizes; fs; fs=fs->next) { + if (dw->dvi.sizescale*fs->size <= 10*size + && fs->size >= bestsize) { + best = fs; + bestsize = fs->size; + } + if (smallest == 0 || fs->size < smallest->size) + smallest = fs; + } + return best ? best : smallest; +} + +static char * +SkipFontNameElement (char *n) +{ + while (*n != '-') + if (!*++n) + return 0; + return n+1; +} + +# define SizePosition 8 +# define EncodingPosition 13 + +static int +ConvertFontNameToSize (char *n) +{ + int i, size; + + for (i = 0; i < SizePosition; i++) { + n = SkipFontNameElement (n); + if (!n) + return -1; + } + size = atoi (n); + return size; +} + +static char * +ConvertFontNameToEncoding (char *n) +{ + int i; + for (i = 0; i < EncodingPosition; i++) { + n = SkipFontNameElement (n); + if (!n) + return 0; + } + return n; +} + +static DviFontSizeList * +InstallFontSizes (DviWidget dw, const char *x_name, Boolean *scalablep) +{ + char fontNameString[2048]; + char **fonts; + int i, count; + int size; + DviFontSizeList *sizes, *new_size; + XFontName fontName; + unsigned int fontNameAttributes; + + *scalablep = FALSE; + if (!XParseFontName ((XFontNameString)x_name, &fontName, + &fontNameAttributes)) + return 0; + fontNameAttributes &= ~(FontNamePixelSize|FontNamePointSize + |FontNameAverageWidth); + fontNameAttributes |= FontNameResolutionX; + fontNameAttributes |= FontNameResolutionY; + fontName.ResolutionX = dw->dvi.display_resolution; + fontName.ResolutionY = dw->dvi.display_resolution; + XFormatFontName (&fontName, fontNameAttributes, fontNameString); + fonts = XListFonts (XtDisplay (dw), fontNameString, 10000000, &count); + sizes = 0; + for (i = 0; i < count; i++) { + size = ConvertFontNameToSize (fonts[i]); + if (size == 0) { + DisposeFontSizes (dw, sizes); + sizes = 0; + *scalablep = TRUE; + break; + } + if (size != -1) { + new_size = (DviFontSizeList *) XtMalloc (sizeof *new_size); + new_size->next = sizes; + new_size->size = size; + new_size->x_name = savestr (fonts[i]); + new_size->doesnt_exist = 0; + new_size->font = 0; + sizes = new_size; + } + } + XFreeFontNames (fonts); + return sizes; +} + +static void +DisposeFontSizes (DviWidget dw, DviFontSizeList *fs) +{ + DviFontSizeList *next; + + for (; fs; fs=next) { + next = fs->next; + if (fs->x_name) + XtFree (fs->x_name); + if (fs->font && fs->font != dw->dvi.default_font) { + XUnloadFont (XtDisplay (dw), fs->font->fid); + XFree ((char *)fs->font); + } + XtFree ((char *) fs); + } +} + +static DviFontList * +InstallFont (DviWidget dw, int position, + const char *dvi_name, const char *x_name) +{ + DviFontList *f; + char *encoding; + + if ((f = LookupFontByPosition (dw, position)) != NULL) { + /* + * ignore gratuitous font loading + */ + if (!strcmp (f->dvi_name, dvi_name) && + !strcmp (f->x_name, x_name)) + return f; + + DisposeFontSizes (dw, f->sizes); + if (f->dvi_name) + XtFree (f->dvi_name); + if (f->x_name) + XtFree (f->x_name); + f->device_font = 0; + } else { + f = (DviFontList *) XtMalloc (sizeof (*f)); + f->next = dw->dvi.fonts; + dw->dvi.fonts = f; + } + f->initialized = FALSE; + f->dvi_name = savestr (dvi_name); + f->device_font = device_find_font (dw->dvi.device, dvi_name); + f->x_name = savestr (x_name); + f->dvi_number = position; + f->sizes = 0; + f->scalable = FALSE; + if (f->x_name) { + encoding = ConvertFontNameToEncoding (f->x_name); + f->char_map = DviFindMap (encoding); + } else + f->char_map = 0; + /* + * force requery of fonts + */ + dw->dvi.font = 0; + dw->dvi.font_number = -1; + dw->dvi.cache.font = 0; + dw->dvi.cache.font_number = -1; + dw->dvi.device_font = 0; + dw->dvi.device_font_number = -1; + return f; +} + +void +ForgetFonts (DviWidget dw) +{ + DviFontList *f = dw->dvi.fonts; + + while (f) { + DviFontList *tem = f; + + if (f->sizes) + DisposeFontSizes (dw, f->sizes); + if (f->dvi_name) + XtFree (f->dvi_name); + if (f->x_name) + XtFree (f->x_name); + f = f->next; + XtFree ((char *) tem); + } + + /* + * force requery of fonts + */ + dw->dvi.font = 0; + dw->dvi.font_number = -1; + dw->dvi.cache.font = 0; + dw->dvi.cache.font_number = -1; + dw->dvi.device_font = 0; + dw->dvi.device_font_number = -1; + dw->dvi.fonts = 0; +} + + +static char * +MapDviNameToXName (DviWidget dw, const char *dvi_name) +{ + DviFontMap *fm; + + for (fm = dw->dvi.font_map; fm; fm=fm->next) + if (!strcmp (fm->dvi_name, dvi_name)) + return fm->x_name; + return 0; +} + +#if 0 +static char * +MapXNameToDviName (DviWidget dw, const char *x_name) +{ + DviFontMap *fm; + + for (fm = dw->dvi.font_map; fm; fm=fm->next) + if (!strcmp (fm->x_name, x_name)) + return fm->dvi_name; + return 0; +} +#endif + +void +ParseFontMap (DviWidget dw) +{ + char dvi_name[1024]; + char x_name[2048]; + char *m, *s; + DviFontMap *fm, *new_map; + + if (dw->dvi.font_map) + DestroyFontMap (dw->dvi.font_map); + fm = 0; + m = dw->dvi.font_map_string; + while (*m) { + s = m; + while (*m && !isspace (*m)) + ++m; + strncpy (dvi_name, s, m-s); + dvi_name[m-s] = '\0'; + while (isspace (*m)) + ++m; + s = m; + while (*m && *m != '\n') + ++m; + strncpy (x_name, s, m-s); + x_name[m-s] = '\0'; + new_map = (DviFontMap *) XtMalloc (sizeof *new_map); + new_map->x_name = savestr (x_name); + new_map->dvi_name = savestr (dvi_name); + new_map->next = fm; + fm = new_map; + ++m; + } + dw->dvi.font_map = fm; +} + +void +DestroyFontMap (DviFontMap *font_map) +{ + DviFontMap *next; + + for (; font_map; font_map = next) { + next = font_map->next; + if (font_map->x_name) + XtFree (font_map->x_name); + if (font_map->dvi_name) + XtFree (font_map->dvi_name); + XtFree ((char *) font_map); + } +} + +/* ARGSUSED */ + +void +SetFontPosition (DviWidget dw, int position, + const char *dvi_name, const char *extra) +{ + char *x_name; + + x_name = MapDviNameToXName (dw, dvi_name); + if (x_name) + (void) InstallFont (dw, position, dvi_name, x_name); + + extra = extra; /* unused; suppress compiler warning */ +} + +XFontStruct * +QueryFont (DviWidget dw, int position, int size) +{ + DviFontList *f; + DviFontSizeList *fs; + + f = LookupFontByPosition (dw, position); + if (!f) + return dw->dvi.default_font; + if (!f->initialized) { + f->sizes = InstallFontSizes (dw, f->x_name, &f->scalable); + f->initialized = TRUE; + } + fs = LookupFontSizeBySize (dw, f, size); + if (!fs) + return dw->dvi.default_font; + if (!fs->font) { + if (fs->x_name) + fs->font = XLoadQueryFont (XtDisplay (dw), fs->x_name); + if (!fs->font) + fs->font = dw->dvi.default_font; + } + return fs->font; +} + +DeviceFont * +QueryDeviceFont (DviWidget dw, int position) +{ + DviFontList *f; + + f = LookupFontByPosition (dw, position); + if (!f) + return 0; + return f->device_font; +} + +DviCharNameMap * +QueryFontMap (DviWidget dw, int position) +{ + DviFontList *f; + + f = LookupFontByPosition (dw, position); + if (f) + return f->char_map; + else + return 0; +} + +#if 0 +LoadFont (DviWidget dw, int position, int size) +{ + XFontStruct *font; + + font = QueryFont (dw, position, size); + dw->dvi.font_number = position; + dw->dvi.font_size = size; + dw->dvi.font = font; + XSetFont (XtDisplay (dw), dw->dvi.normal_GC, font->fid); + return; +} +#endif + +/* +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: +*/ diff --git a/src/devices/xditview/font.h b/src/devices/xditview/font.h new file mode 100644 index 0000000..ae6c765 --- /dev/null +++ b/src/devices/xditview/font.h @@ -0,0 +1,6 @@ +void DestroyFontMap(DviFontMap *); +void ForgetFonts (DviWidget dw); +int MaxFontPosition (DviWidget dw); +void ParseFontMap (DviWidget dw); +void SetFontPosition (DviWidget dw, int position, const char *dvi_name, + const char *extra); diff --git a/src/devices/xditview/gray1.bm b/src/devices/xditview/gray1.bm new file mode 100644 index 0000000..c40a95e --- /dev/null +++ b/src/devices/xditview/gray1.bm @@ -0,0 +1,4 @@ +#define gray1_width 3 +#define gray1_height 3 +static char gray1_bits[] = { + 0x00, 0x02, 0x00}; diff --git a/src/devices/xditview/gray2.bm b/src/devices/xditview/gray2.bm new file mode 100644 index 0000000..e87a1bc --- /dev/null +++ b/src/devices/xditview/gray2.bm @@ -0,0 +1,4 @@ +#define gray2_width 3 +#define gray2_height 3 +static char gray2_bits[] = { + 0x00, 0x03, 0x00}; diff --git a/src/devices/xditview/gray3.bm b/src/devices/xditview/gray3.bm new file mode 100644 index 0000000..d9313eb --- /dev/null +++ b/src/devices/xditview/gray3.bm @@ -0,0 +1,4 @@ +#define gray3_width 3 +#define gray3_height 3 +static char gray3_bits[] = { + 0x00, 0x03, 0x02}; diff --git a/src/devices/xditview/gray4.bm b/src/devices/xditview/gray4.bm new file mode 100644 index 0000000..dad142a --- /dev/null +++ b/src/devices/xditview/gray4.bm @@ -0,0 +1,4 @@ +#define gray4_width 3 +#define gray4_height 3 +static char gray4_bits[] = { + 0x00, 0x07, 0x02}; diff --git a/src/devices/xditview/gray5.bm b/src/devices/xditview/gray5.bm new file mode 100644 index 0000000..5f57618 --- /dev/null +++ b/src/devices/xditview/gray5.bm @@ -0,0 +1,4 @@ +#define gray5_width 3 +#define gray5_height 3 +static char gray5_bits[] = { + 0x04, 0x07, 0x02}; diff --git a/src/devices/xditview/gray6.bm b/src/devices/xditview/gray6.bm new file mode 100644 index 0000000..b76701d --- /dev/null +++ b/src/devices/xditview/gray6.bm @@ -0,0 +1,4 @@ +#define gray6_width 3 +#define gray6_height 3 +static char gray6_bits[] = { + 0x04, 0x07, 0x03}; diff --git a/src/devices/xditview/gray7.bm b/src/devices/xditview/gray7.bm new file mode 100644 index 0000000..ef47bc6 --- /dev/null +++ b/src/devices/xditview/gray7.bm @@ -0,0 +1,4 @@ +#define gray7_width 3 +#define gray7_height 3 +static char gray7_bits[] = { + 0x05, 0x07, 0x03}; diff --git a/src/devices/xditview/gray8.bm b/src/devices/xditview/gray8.bm new file mode 100644 index 0000000..12de7cb --- /dev/null +++ b/src/devices/xditview/gray8.bm @@ -0,0 +1,4 @@ +#define gray8_width 3 +#define gray8_height 3 +static char gray8_bits[] = { + 0x05, 0x07, 0x07}; diff --git a/src/devices/xditview/gxditview.1.man b/src/devices/xditview/gxditview.1.man new file mode 100644 index 0000000..920ccfd --- /dev/null +++ b/src/devices/xditview/gxditview.1.man @@ -0,0 +1,815 @@ +.TH gxditview @MAN1EXT@ "@MDATE@" "groff @VERSION@" +.SH Name +gxditview \- display +.I groff +intermediate output files in X11 +. +. +.\" ==================================================================== +.\" Legal Terms +.\" ==================================================================== +.\" +.\" Copyright 1991 Massachusetts Institute of Technology +.\" +.\" Permission to use, copy, modify, distribute, and sell this software +.\" and its documentation for any purpose is hereby granted without fee, +.\" provided that the above copyright notice appear in all copies and +.\" that both that copyright notice and this permission notice appear in +.\" supporting documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the software +.\" without specific, written prior permission. M.I.T. makes no +.\" representations about the suitability of this software for any +.\" purpose. It is provided "as is" without express or implied +.\" warranty. +.\" +.\" M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +.\" INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN +.\" NO EVENT SHALL M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR +.\" CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +.\" OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +. +. +.\" Save and disable compatibility mode (for, e.g., Solaris 10/11). +.do nr *groff_gxditview_1_man_C \n[.cp] +.cp 0 +. +.\" Define fallback for groff 1.23's MR macro if the system lacks it. +.nr do-fallback 0 +.if !\n(.f .nr do-fallback 1 \" mandoc +.if \n(.g .if !d MR .nr do-fallback 1 \" older groff +.if !\n(.g .nr do-fallback 1 \" non-groff *roff +.if \n[do-fallback] \{\ +. de MR +. ie \\n(.$=1 \ +. I \%\\$1 +. el \ +. IR \%\\$1 (\\$2)\\$3 +. . +.\} +.rr do-fallback +. +. +.\" ==================================================================== +.SH Synopsis +.\" ==================================================================== +. +.SY gxditview +.RI [ X-toolkit-option \~.\|.\|.\&] +.RB [ \-backingStore\~\c +.IR backing-store-type ] +.RB [ \-filename\~\c +.IR file ] +.\" While recognized, the relevant logic is "#if 0"ed out in draw.c. +.\" .RB [ \-noPolyText ] +.RB [ \-page\~\c +.IR page-number ] +.RB [ \-printCommand\~\c +.IR command ] +.RB [ \-resolution\~\c +.IR resolution ] +.I file +.YS +. +. +.SY gxditview +.B \-help +. +.SY gxditview +.B \-\-help +.YS +. +. +.SY gxditview +.B \-version +. +.SY gxditview +.B \-\-version +.YS +. +. +.\" ==================================================================== +.SH Description +.\" ==================================================================== +. +.I gxditview +interprets and displays the intermediate output format of +.MR groff @MAN1EXT@ +on an X11\~display. +. +It uses the standard X11 fonts, +so it does not require access to the server machine for font loading. +. +There are several ways to use +.IR gxditview . +. +. +.PP +The +intermediate output format of +.IR groff , +documented in +.MR groff_out @MAN5EXT@ , +is produced by +.I @g@troff +or the +.B \-Z +option to +.IR groff . +. +. +It can be viewed by explicitly calling +.RB \[lq] gxditview +.IR file \[rq]. +. +If the +.I file +operand is +.RB \[lq] \- \[rq], +.I gxditview +will read the standard input stream; +.I file +cannot be omitted. +. +The intermediate output format of +.I groff +is device-independent but not device-agnostic. +. +.I gxditview +can view it for all typesetter devices, +but the quality is device-dependent. +. +.I gxditview +will not display output for terminal +.RI ( nroff ) +devices. +. +. +.PP +The best results are achieved with the +.BR X * +devices for +.IR groff 's +.B \-T +option, +of which there are four: +.BR \-TX75 , +.BR \-TX75\-12 , +.BR \-TX100 , +and +.BR \-TX100\-12 . +. +They differ by the X\~resolution +(75 or 100 dots per inch) +and the base point size +(10 or 12 points). +. +They are especially built for +.IR gxditview . +. +When using one of these, +.I groff +generates the intermediate output for this device and calls +.I gxditview +automatically for viewing. +. +. +.P +.B \-X +produces good results only with +.BR \-Tps , +.BR \-TX75 , +.BR \-TX75\-12 , +.BR \-TX100 , +and +.BR \-TX100\-12 . +. +The default resolution for previewing +.B \-Tps +output is 75\|dpi; +this can be changed with the +.B \-resolution +option. +. +. +.PP +While +.I gxditview +is running, +the left mouse button brings up a menu with several entries. +. +. +.TP 13n +.B Next Page +Display the next page. +. +. +.TP +.B Previous Page +Display the previous page. +. +. +.TP +.B Select Page +Select a particular numbered page specified by a dialog box. +. +. +.TP +.B Print +Print the +.I groff +intermediate output using a command specified by a dialog box. +. +The default command initially displayed is controlled by the +.B printCommand +application resource, +and by the +.B \-printCommand +option. +. +. +.TP +.B Open +Open for display a new file specified by a dialog box. +. +The file should contain +.I groff +intermediate output. +. +If the filename starts with a bar or pipe symbol, +.RB \[lq] | \[rq] +it will be interpreted as a command from which to read. +. +. +.TP +.B Quit +Exit from +.BR gxditview . +. +. +.PP +The menu entries correspond to actions with similar but not identical +names, +which can also be accessed with keyboard accelerators. +. +The +.IR n , +.IR Space , +.IR Return , +and +.I Next +.RI ( PgDn ) +keys are bound to the +.B NextPage +action. +. +The +.IR p , +.IR b , +.IR BackSpace , +.IR Delete , +and +.I Prior +.RI ( PgUp ) +keys are bound to the +.B PreviousPage +action. +. +The +.I g +key is bound to the +.B SelectPage +action. +. +The +.I o +key is bound to the +.B OpenFile +action. +. +The +.I q +key is bound to the +.B Quit +action. +. +The +.I r +key is bound to a +.B Rerasterize +action which rereads the current file, +and redisplays the current page; +if the current file is a command, +the command will be re-executed. +. +Vertical scrolling can be done with the +.I k +and +.I j +keys; +horizontal scrolling is bound to the +.I h +and +.I l +keys. +. +The arrow keys +.RI ( up , +.IR down , +.IR left , +and +.IR right ) +are also bound to the obvious scrolling actions. +. +. +.PP +The +.B paperlength +and +.B paperwidth +commands in the +.I DESC +file describing a +.I groff +output device specify the length and width in machine units of the +virtual page displayed by +.IR gxditview ; +see +.MR groff_font @MAN5EXT@ . +. +. +.\" ==================================================================== +.SS "X defaults" +.\" ==================================================================== +. +This program uses the +.I Dvi +widget from the X\~Toolkit. +. +It understands all of the core resource names and classes as well as: +. +. +.TP +.BR width\~ (class\~ Width ) +Specifies the width of the window. +. +. +.TP +.BR height\~ (class\~ Height ) +Specifies the height of the window. +. +. +.TP +.BR foreground\~ (class\~ Foreground ) +Specifies the default foreground color. +. +. +.TP +.BR font\~ (class\~ Font ) +Specifies the font to be used for error messages. +. +. +.TP +.BR fontMap\~ (class\~ FontMap ) +Specifies the mapping from +.I groff +font names to X\~font names. +. +This must be a string containing a sequence of lines. +. +Each line contains two whitespace-separated fields: +firstly the +.I groff +font name, +and secondly the XLFD +(X Logical Font Description). +. +The default is shown in subsection \[lq]Default font map\[rq] below. +. +. +.\" ==================================================================== +.SS "Default font map" +.\" ==================================================================== +. +XLFDs are long and unwieldy, +so some lines are shown broken and indented below. +.\" Break them after the POINT_SIZE field (in "decipoints", so "100"). +. +. +.PP +.EX +TR \-adobe\-times\-medium\-r\-normal\-\-*\-100\ +\-*\-*\-*\-*\-iso8859\-1\[rs]n\[rs] +TI \-adobe\-times\-medium\-i\-normal\-\-*\-100\ +\-*\-*\-*\-*\-iso8859\-1\[rs]n\[rs] +TB \-adobe\-times\-bold\-r\-normal\-\-*\-100\ +\-*\-*\-*\-*\-iso8859\-1\[rs]n\[rs] +TBI \-adobe\-times\-bold\-i\-normal\ +\-\-*\-100\-*\-*\-*\-*\-iso8859\-1\[rs]n\[rs] +CR \-adobe\-courier\-medium\-r\-normal\-\-*\-100\" break + \-*\-*\-*\-*\-iso8859\-1\[rs]n\[rs] +CI \-adobe\-courier\-medium\-o\-normal\" break + \-\-*\-100\-*\-*\-*\-*\-iso8859\-1\[rs]n\[rs] +CB \-adobe\-courier\-bold\-r\-normal\ +\-\-*\-100\-*\-*\-*\-*\-iso8859\-1\[rs]n\[rs] +CBI \-adobe\-courier\-bold\-o\-normal\ +\-\-*\-100\-*\-*\-*\-*\-iso8859\-1\[rs]n\[rs] +HR \-adobe\-helvetica\-medium\-r\-normal\" break + \-\-*\-100\-*\-*\-*\-*\-iso8859\-1\[rs]n\[rs] +HI \-adobe\-helvetica\-medium\-o\-normal\" break + \-\-*\-100\-*\-*\-*\-*\-iso8859\-1\[rs]n\[rs] +HB \-adobe\-helvetica\-bold\-r\-normal\" break + \-\-*\-100\-*\-*\-*\-*\-iso8859\-1\[rs]n\[rs] +HBI \-adobe\-helvetica\-bold\-o\-normal\" break + \-\-*\-100\-*\-*\-*\-*\-iso8859\-1\[rs]n\[rs] +NR \-adobe\-new century schoolbook\-medium\-r\-normal\-\-*\-100\" break + \-*\-*\-*\-*\-iso8859\-1\[rs]n\[rs] +NI \-adobe\-new century schoolbook\-medium\-i\-normal\-\-*\-100\" break + \-*\-*\-*\-*\-iso8859\-1\[rs]n\[rs] +NB \-adobe\-new century schoolbook\-bold\-r\-normal\-\-*\-100\" break + \-*\-*\-*\-*\-iso8859\-1\[rs]n\[rs] +NBI \-adobe\-new century schoolbook\-bold\-i\-normal\-\-*\-100\" break + \-*\-*\-*\-*\-iso8859\-1\[rs]n\[rs] +S \-adobe\-symbol\-medium\-r\-normal\-\-*\-100\" break + \-*\-*\-*\-*\-adobe\-fontspecific\[rs]n\[rs] +SS \-adobe\-symbol\-medium\-r\-normal\-\-*\-100\" break + \-*\-*\-*\-*\-adobe\-fontspecific\[rs]n\[rs] +.EE +. +. +.br +.ne 3v +.\" ==================================================================== +.SH Options +.\" ==================================================================== +. +.B \-help +and +.B \-\-help +display a usage message, +while +.B \-version +and +.B \-\-version +show version information; +all exit afterward. +. +. +.P +.I gxditview +accepts all of the standard X\~Toolkit command-line options along with +the additional options listed below. +. +. +.TP +.B \-page +This option specifies the page number of the document to be displayed. +. +. +.TP +.BI \-backingStore\~ backing-store-type +Because redisplay of the +.I groff +intermediate output window can take a perceiptible amount of time, +this option causes the server to save the window contents so that when +it is scrolled around the viewport, +the window is painted from contents saved in backing store. +. +.I backing-store-type +can be one of +.BR Always , +.B WhenMapped +or +.BR NotUseful . +. +. +.TP +.BI \-printCommand\~ command +The default command displayed in the dialog box for the +.B Print +menu entry will be +.IR command . +. +. +.TP +.BI \-resolution\~ res +The +.I groff +intermediate output file will be displayed at a resolution of +.I res +dots per inch, +unless the +.I DESC +file contains the +.B X11 +command, +in which case the device resolution will be used. +. +This corresponds to the +.I Dvi +widget's +.B resolution +resource. +. +The default is +.BR 75 . +. +. +.TP +.BI \-filename\~ string +The default filename displayed in the dialog box for the +.B Open +menu entry will be +.IR string . +. +This can be either a filename, +or a command starting with +.RB \[lq] | \[rq]. +. +. +.PP +The following standard X\~Toolkit command-line arguments are commonly +used with +.IR gxditview . +. +. +.TP +.BI \-bg\~ color +This option specifies the color to use for the background of the window. +. +The default is +.RB \[lq] white \[rq]. +. +. +.TP +.BI \-bd\~ color +This option specifies the color to use for the border of the window. +. +The default is +.RB \[lq] black \[rq]. +. +. +.TP +.BI \-bw\~ number +This option specifies the width in pixels of the border surrounding the +window. +. +. +.TP +.BI \-fg\~ color +This option specifies the color to use for displaying text. +. +The default is +.RB \[lq] black \[rq]. +. +. +.TP +.BI \-fn\~ font +This option specifies the font to be used for displaying widget text. +. +The default is +.RB \[lq] fixed \[rq]. +. +. +.TP +.B \-rv +This option indicates that reverse video should be simulated by swapping +the foreground and background colors. +. +. +.TP +.BI \-geometry\~ geometry +This option specifies the preferred size and position of the window. +. +. +.TP +.BI \-display\~ host : display +This option specifies the X\~server to contact. +. +. +.TP +.BI \-xrm\~ resourcestring +This option specifies a resource string to be used. +. +. +.\" ==================================================================== +.SH Environment +.\" ==================================================================== +. +.TP +.I GROFF_FONT_PATH +A list of directories in which to seek the selected output device's +directory of device and font description files. +. +See +.MR @g@troff @MAN1EXT@ +and +.MR groff_font @MAN5EXT@ . +. +. +.\" ==================================================================== +.SH Files +.\" ==================================================================== +. +.TP +.I @APPDEFDIR@/\:\%GXditview +.TQ +.I @APPDEFDIR@/\:\%GXditview\-color +define X application defaults for +.IR gxditview . +. +Users can override these values in the +.I .Xdefaults +file, +normally located in the user's home directory. +. +See +.MR appres 1 +and +.MR xrdb 1 . +. +. +.TP +.I @FONTDIR@/\:\%devX100/\:DESC +describes the +.B X100 +output device. +. +. +.TP +.IR @FONTDIR@/\:\%devX100/ F +describes the font known +.RI as\~ F +on device +.BR X100 . +. +. +.TP +.I @FONTDIR@/\:\%devX100\-12/\:DESC +describes the +.B X100\-12 +output device. +. +. +.TP +.IR @FONTDIR@/\:\%devX100\-12/ F +describes the font known +.RI as\~ F +on device +.BR X100\-12 . +. +. +.TP +.I @FONTDIR@/\:\%devX75/\:DESC +describes the +.B X75 +output device. +. +. +.TP +.IR @FONTDIR@/\:\%devX75/ F +describes the font known +.RI as\~ F +on device +.BR X75 . +. +. +.TP +.I @FONTDIR@/\:\%devX75\-12/\:DESC +describes the +.B X75\-12 +output device. +. +. +.TP +.IR @FONTDIR@/\:\%devX75\-12/ F +describes the font known +.RI as\~ F +on device +.BR X75\-12 . +. +. +.TP +.I @MACRODIR@/\:X.tmac +defines macros for use with the +.BR X100 , +.BR X100\-12 , +.BR X75 , +and +.B X75\-12 +output devices. +. +It is automatically loaded by +.I troffrc +when any of those output devices is selected. +. +. +.TP +.I @MACRODIR@/\:Xps\:.tmac +sets up +.I @g@troff +to use +.I \%gxditview +as a previewer for device-independent output targeting the +.B ps +output device. +. +It is automatically loaded by +.I troffrc +when +.I @g@troff +is given the options +.B \-X +and +.BR \-Tps . +. +. +.\" ==================================================================== +.SH Examples +.\" ==================================================================== +. +The following command views this man page with a base point size of 12. +. +. +.RS +.P +.EX +groff \-TX100\-12 \-man gxditview.1 +.EE +.RE +. +. +.P +The quality of the result depends mainly on the chosen point size and +display resolution; +for rapid previewing, +however, +something like +. +.RS +.EX +.RI "groff \-X \-P\-resolution \-P100\~" document +.EE +.RE +. +yields acceptable results. +. +. +.\" ==================================================================== +.SH Authors +.\" ==================================================================== +. +.I gxditview +and its predecessor +.I xditview +were written by +Keith Packard (MIT X Consortium), +Richard L.\& Hyde (Purdue), +David Slattengren (Berkeley), +Malcolm Slaney (Schlumberger Palo Alto Research), +Mark Moraes (University of Toronto), +and +James Clark. +. +. +.PP +This program is derived from +.IR xditview ; +portions of +.I xditview +originated in +.IR xtroff , +which was derived from +.IR \%suntroff . +. +. +.\" ==================================================================== +.SH "See also" +.\" ==================================================================== +. +.UR https://\:www\:.x\:.org/\:releases/\:X11R7.6/\:doc/\:xorg\-docs/\ +\:specs/\:XLFD/xlfd\:.html +\[lq]X Logical Font Description Conventions\[rq] +.UE , +by Jim Flowers and Stephen Gildea. +. +. +.PP +.MR X 7 , +.MR xrdb 1 , +.MR xditview 1 , +.MR groff @MAN1EXT@ , +.MR groff_out @MAN5EXT@ +. +. +.\" Restore compatibility mode (for, e.g., Solaris 10/11). +.cp \n[*groff_gxditview_1_man_C] +.do rr *groff_gxditview_1_man_C +. +. +.\" Local Variables: +.\" fill-column: 72 +.\" mode: nroff +.\" End: +.\" vim: set filetype=groff textwidth=72: diff --git a/src/devices/xditview/lex.c b/src/devices/xditview/lex.c new file mode 100644 index 0000000..19cf292 --- /dev/null +++ b/src/devices/xditview/lex.c @@ -0,0 +1,100 @@ +#include + +#include +#include +#include +#include + +#include "DviP.h" +#include "lex.h" + +int +DviGetAndPut(DviWidget dw, int *cp) +{ + if (dw->dvi.ungot) { + dw->dvi.ungot = 0; + *cp = getc (dw->dvi.file); + } + else { + *cp = getc (dw->dvi.file); + if (*cp != EOF) + putc (*cp, dw->dvi.tmpFile); + } + return *cp; +} + +char * +GetLine(DviWidget dw, char *Buffer, int Length) +{ + int i = 0, c; + + Length--; /* Save room for final '\0' */ + + while (DviGetC (dw, &c) != EOF) { + if (Buffer && i < Length) + Buffer[i++] = c; + if (c == '\n') { + DviUngetC(dw, c); + break; + } + } + if (Buffer) + Buffer[i] = '\0'; + return Buffer; +} + +char * +GetWord(DviWidget dw, char *Buffer, int Length) +{ + int i = 0, c; + + Length--; /* Save room for final '\0' */ + while (DviGetC(dw, &c) == ' ' || c == '\n') + ; + while (c != EOF) { + if (Buffer && i < Length) + Buffer[i++] = c; + if (DviGetC(dw, &c) == ' ' || c == '\n') { + DviUngetC(dw, c); + break; + } + } + if (Buffer) + Buffer[i] = '\0'; + return Buffer; +} + +int +GetNumber(DviWidget dw) +{ + int i = 0, c; + int negative = 0; + + while (DviGetC(dw, &c) == ' ' || c == '\n') + ; + if (c == '-') { + negative = 1; + DviGetC(dw, &c); + } + + for (; c >= '0' && c <= '9'; DviGetC(dw, &c)) { + if (negative) + i = i*10 - (c - '0'); + else + i = i*10 + c - '0'; + } + if (c != EOF) + DviUngetC(dw, c); + return i; +} + +/* +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: +*/ diff --git a/src/devices/xditview/lex.h b/src/devices/xditview/lex.h new file mode 100644 index 0000000..0a4cba0 --- /dev/null +++ b/src/devices/xditview/lex.h @@ -0,0 +1 @@ +int GetNumber(DviWidget); diff --git a/src/devices/xditview/page.c b/src/devices/xditview/page.c new file mode 100644 index 0000000..352d871 --- /dev/null +++ b/src/devices/xditview/page.c @@ -0,0 +1,86 @@ +/* + * page.c + * + * map page numbers to file position + */ + +#include + +#include +#include +#include +#include +#include + +#include "DviP.h" +#include "page.h" + +#ifdef X_NOT_STDC_ENV +extern long ftell(); +#endif + +static DviFileMap * +MapPageNumberToFileMap (DviWidget dw, int number) +{ + DviFileMap *m; + + for (m = dw->dvi.file_map; m; m=m->next) + if (m->page_number == number) + break; + return m; +} + +void +DestroyFileMap (DviFileMap *m) +{ + DviFileMap *next; + + for (; m; m = next) { + next = m->next; + XtFree ((char *) m); + } +} + +void +ForgetPagePositions (DviWidget dw) +{ + DestroyFileMap (dw->dvi.file_map); + dw->dvi.file_map = 0; +} + +void +RememberPagePosition(DviWidget dw, int number) +{ + DviFileMap *m; + + if (!(m = MapPageNumberToFileMap (dw, number))) { + m = (DviFileMap *) XtMalloc (sizeof *m); + m->page_number = number; + m->next = dw->dvi.file_map; + dw->dvi.file_map = m; + } + if (dw->dvi.tmpFile) + m->position = ftell (dw->dvi.tmpFile); + else + m->position = ftell (dw->dvi.file); +} + +long +SearchPagePosition (DviWidget dw, int number) +{ + DviFileMap *m; + + if (!(m = MapPageNumberToFileMap (dw, number))) + return -1; + return m->position; +} + +void +FileSeek(DviWidget dw, long position) +{ + if (dw->dvi.tmpFile) { + dw->dvi.readingTmp = 1; + fseek (dw->dvi.tmpFile, position, 0); + } else + fseek (dw->dvi.file, position, 0); +} diff --git a/src/devices/xditview/page.h b/src/devices/xditview/page.h new file mode 100644 index 0000000..e2c938d --- /dev/null +++ b/src/devices/xditview/page.h @@ -0,0 +1,5 @@ +void DestroyFileMap(DviFileMap *); +void FileSeek(DviWidget, long); +void ForgetPagePositions(DviWidget); +void RememberPagePosition(DviWidget, int); +long SearchPagePosition(DviWidget, int); diff --git a/src/devices/xditview/parse.c b/src/devices/xditview/parse.c new file mode 100644 index 0000000..456c7da --- /dev/null +++ b/src/devices/xditview/parse.c @@ -0,0 +1,343 @@ +/* + * parse.c + * + * parse dvi input + */ + +#include + +#include +#include +#include +#include +#include + +#include "DviP.h" +#include "draw.h" +#include "font.h" +#include "lex.h" +#include "page.h" +#include "parse.h" + +static int StopSeen = 0; +static void ParseDrawFunction(DviWidget, char *); +static void ParseDeviceControl(DviWidget); +static void push_env(DviWidget); +static void pop_env(DviWidget); + +#define HorizontalMove(dw, delta) ((dw)->dvi.state->x += (delta)) + + +int +ParseInput(register DviWidget dw) +{ + int n, k; + int c; + char Buffer[BUFSIZ]; + int NextPage; + int otherc; + + StopSeen = 0; + + /* + * make sure some state exists + */ + + if (!dw->dvi.state) + push_env (dw); + for (;;) { + switch (DviGetC(dw, &c)) { + case '\n': + break; + case ' ': /* when input is text */ + case 0: /* occasional noise creeps in */ + break; + case '{': /* push down current environment */ + push_env(dw); + break; + case '}': + pop_env(dw); + break; + /* + * two motion digits plus a character + */ + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + HorizontalMove(dw, (c-'0')*10 + + DviGetC(dw,&otherc)-'0'); + /* fall through */ + case 'c': /* single ascii character */ + DviGetC(dw,&c); + if (c == ' ') + break; + Buffer[0] = c; + Buffer[1] = '\0'; + (void) PutCharacter (dw, Buffer); + break; + case 'C': + GetWord (dw, Buffer, BUFSIZ); + (void) PutCharacter (dw, Buffer); + break; + case 't': + Buffer[1] = '\0'; + while (DviGetC (dw, &c) != EOF + && c != ' ' && c != '\n') { + Buffer[0] = c; + HorizontalMove (dw, PutCharacter (dw, Buffer)); + } + break; + case 'u': + n = GetNumber(dw); + Buffer[1] = '\0'; + while (DviGetC (dw, &c) == ' ') + ; + while (c != EOF && c != ' ' && c != '\n') { + Buffer[0] = c; + HorizontalMove (dw, + PutCharacter (dw, Buffer) + n); + DviGetC (dw, &c); + } + break; + + case 'D': /* draw function */ + (void) GetLine(dw, Buffer, BUFSIZ); + if (dw->dvi.display_enable) + ParseDrawFunction(dw, Buffer); + break; + case 's': /* ignore fractional sizes */ + n = GetNumber(dw); + dw->dvi.state->font_size = n; + break; + case 'f': + n = GetNumber(dw); + dw->dvi.state->font_number = n; + break; + case 'H': /* absolute horizontal motion */ + k = GetNumber(dw); + HorizontalGoto(dw, k); + break; + case 'h': /* relative horizontal motion */ + k = GetNumber(dw); + HorizontalMove(dw, k); + break; + case 'w': /* word space */ + Word (dw); + break; + case 'V': + n = GetNumber(dw); + VerticalGoto(dw, n); + break; + case 'v': + n = GetNumber(dw); + VerticalMove(dw, n); + break; + case 'P': /* new spread */ + break; + case 'p': /* new page */ + (void) GetNumber(dw); + NextPage = dw->dvi.current_page + 1; + RememberPagePosition(dw, NextPage); + FlushCharCache (dw); + return(NextPage); + case 'N': + n = GetNumber(dw); + PutNumberedCharacter (dw, n); + break; + case 'n': /* end of line */ + GetNumber(dw); + GetNumber(dw); + Newline (dw); + HorizontalGoto(dw, 0); + break; + case 'F': /* input files */ + case '+': /* continuation of X device control */ + case 'm': /* color */ + case '#': /* comment */ + GetLine(dw, NULL, 0); + break; + case 'x': /* device control */ + ParseDeviceControl(dw); + break; + case EOF: + dw->dvi.last_page = dw->dvi.current_page; + FlushCharCache (dw); + return dw->dvi.current_page; + default: + break; + } + } +} + +static void +push_env(DviWidget dw) +{ + DviState *new_state; + + new_state = (DviState *) XtMalloc (sizeof (*new_state)); + if (dw->dvi.state) + *new_state = *(dw->dvi.state); + else { + new_state->font_size = 10; + new_state->font_number = 1; + new_state->x = 0; + new_state->y = 0; + } + new_state->next = dw->dvi.state; + dw->dvi.state = new_state; +} + +static void +pop_env(DviWidget dw) +{ + DviState *old; + + old = dw->dvi.state; + dw->dvi.state = old->next; + XtFree ((char *) old); +} + +static void +InitTypesetter (DviWidget dw) +{ + while (dw->dvi.state) + pop_env (dw); + push_env (dw); + FlushCharCache (dw); +} + +#define DRAW_ARGS_MAX 128 + +static void +ParseDrawFunction(DviWidget dw, char *buf) +{ + int v[DRAW_ARGS_MAX]; + int i, no_move = 0; + char *ptr; + + v[0] = v[1] = v[2] = v[3] = 0; + + if (buf[0] == '\0') + return; + ptr = buf+1; + + for (i = 0; i < DRAW_ARGS_MAX; i++) { + if (sscanf(ptr, "%d", v + i) != 1) + break; + while (*ptr == ' ') + ptr++; + while (*ptr != '\0' && *ptr != ' ') + ptr++; + } + + switch (buf[0]) { + case 'l': /* draw a line */ + DrawLine(dw, v[0], v[1]); + break; + case 'c': /* circle */ + DrawCircle(dw, v[0]); + break; + case 'C': + DrawFilledCircle(dw, v[0]); + break; + case 'e': /* ellipse */ + DrawEllipse(dw, v[0], v[1]); + break; + case 'E': + DrawFilledEllipse(dw, v[0], v[1]); + break; + case 'a': /* arc */ + DrawArc(dw, v[0], v[1], v[2], v[3]); + break; + case 'p': + DrawPolygon(dw, v, i); + break; + case 'P': + DrawFilledPolygon(dw, v, i); + break; + case '~': /* wiggly line */ + DrawSpline(dw, v, i); + break; + case 't': + dw->dvi.line_thickness = v[0]; + break; + case 'f': + if (i > 0 && v[0] >= 0 && v[0] <= DVI_FILL_MAX) + dw->dvi.fill = v[0]; + no_move = 1; + break; + default: +#if 0 + warning("unknown drawing function %s", buf); +#endif + no_move = 1; + break; + } + + if (!no_move) { + if (buf[0] == 'e') { + if (i > 0) + dw->dvi.state->x += v[0]; + } + else { + while (--i >= 0) { + if (i & 1) + dw->dvi.state->y += v[i]; + else + dw->dvi.state->x += v[i]; + } + } + } +} + +static void +ParseDeviceControl(DviWidget dw) /* Parse the x commands */ +{ + char str[20], str1[50]; + int c, n; + + GetWord (dw, str, 20); + switch (str[0]) { /* crude for now */ + case 'T': /* output device */ + GetWord (dw, str, 20); + SetDevice (dw, str); + break; + case 'i': /* initialize */ + InitTypesetter (dw); + break; + case 't': /* trailer */ + break; + case 'p': /* pause -- can restart */ + break; + case 's': /* stop */ + StopSeen = 1; + return; + case 'r': /* resolution when prepared */ + break; + case 'f': /* font used */ + n = GetNumber (dw); + GetWord (dw, str, 20); + GetLine (dw, str1, 50); + SetFontPosition (dw, n, str, str1); + break; + case 'H': /* char height */ + break; + case 'S': /* slant */ + break; + } + while (DviGetC (dw, &c) != '\n') /* skip rest of input line */ + if (c == EOF) + return; + return; +} + + +/* +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: +*/ diff --git a/src/devices/xditview/parse.h b/src/devices/xditview/parse.h new file mode 100644 index 0000000..636f3a6 --- /dev/null +++ b/src/devices/xditview/parse.h @@ -0,0 +1 @@ +int ParseInput(register DviWidget dw); diff --git a/src/devices/xditview/xdit.bm b/src/devices/xditview/xdit.bm new file mode 100644 index 0000000..0c7aa8c --- /dev/null +++ b/src/devices/xditview/xdit.bm @@ -0,0 +1,14 @@ +#define xdit_width 32 +#define xdit_height 32 +static unsigned char xdit_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x03, 0x02, 0x00, 0x00, 0x02, + 0x8a, 0xa2, 0xfc, 0x03, 0x52, 0x14, 0x03, 0x04, 0x02, 0x80, 0x00, 0x08, + 0x52, 0x54, 0x00, 0x10, 0x8a, 0x22, 0x8f, 0x23, 0x02, 0x20, 0x06, 0x21, + 0x8a, 0x12, 0x8c, 0x40, 0x52, 0x14, 0x8c, 0x40, 0x02, 0x10, 0x58, 0x40, + 0x52, 0x14, 0x30, 0x40, 0x8a, 0x12, 0x30, 0x40, 0x02, 0x10, 0x70, 0x40, + 0x8a, 0x12, 0xc8, 0x40, 0x52, 0x24, 0xc4, 0xe0, 0x02, 0x20, 0x84, 0xe1, + 0x52, 0x54, 0xce, 0xf3, 0x8a, 0xa2, 0x00, 0xf8, 0x02, 0x00, 0x03, 0xfc, + 0x8a, 0x22, 0xfc, 0xf3, 0x52, 0x14, 0x00, 0xc2, 0x02, 0x00, 0x00, 0x02, + 0x52, 0x14, 0x45, 0x02, 0x8a, 0xa2, 0x28, 0x02, 0x02, 0x00, 0x00, 0x02, + 0x02, 0x00, 0x00, 0x02, 0xfe, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/src/devices/xditview/xdit_mask.bm b/src/devices/xditview/xdit_mask.bm new file mode 100644 index 0000000..a584629 --- /dev/null +++ b/src/devices/xditview/xdit_mask.bm @@ -0,0 +1,14 @@ +#define xdit_mask_width 32 +#define xdit_mask_height 32 +static unsigned char xdit_mask_bits[] = { + 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0x07, + 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0x1f, + 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xc7, + 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0x07, + 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/src/devices/xditview/xditview.am b/src/devices/xditview/xditview.am new file mode 100644 index 0000000..7bb32ba --- /dev/null +++ b/src/devices/xditview/xditview.am @@ -0,0 +1,130 @@ +# Copyright (C) 2014-2020 Free Software Foundation, Inc. +# +# This file is part of groff. +# +# groff is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# groff is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +GXDITVIEWSOURCES = \ + src/devices/xditview/device.c \ + src/devices/xditview/draw.c \ + src/devices/xditview/draw.h \ + src/devices/xditview/Dvi.c \ + src/devices/xditview/font.c \ + src/devices/xditview/font.h \ + src/devices/xditview/lex.c \ + src/devices/xditview/lex.h \ + src/devices/xditview/page.c \ + src/devices/xditview/page.h \ + src/devices/xditview/parse.c \ + src/devices/xditview/parse.h \ + src/devices/xditview/xditview.c \ + src/devices/xditview/device.h \ + src/devices/xditview/DviP.h \ + src/devices/xditview/Menu.h \ + src/devices/xditview/Dvi.h + +GXDITVIEW_GROFF_VERSION_H=src/devices/xditview/groff_version.h + +$(GXDITVIEW_GROFF_VERSION_H): $(top_srcdir)/.version + $(AM_V_at)$(MKDIR_P) `dirname $@` + $(AM_V_GEN)printf \ + 'const char *Version_string = "%s";\n' '@VERSION@' > $@ + +if WITHOUT_X11 +GXDITVIEW_MAN1 = +EXTRA_DIST += $(GXDITVIEWSOURCES) +else +GXDITVIEW_MAN1 = src/devices/xditview/gxditview.1 +xditview_srcdir = $(top_srcdir)/src/devices/xditview +bin_PROGRAMS += gxditview +gxditview_CPPFLAGS = $(AM_CPPFLAGS) $(X_CFLAGS) -Dlint \ + -I$(top_builddir)/src/devices/xditview +gxditview_LDADD = $(X_LIBS) $(X_PRE_LIBS) -lXaw -lXmu -lXt -lX11 \ + $(X_EXTRA_LIBS) $(LIBM) libxutil.a lib/libgnu.a +XDITVIEW_GENHDRS = \ + src/devices/xditview/GXditview-ad.h \ + $(GXDITVIEW_GROFF_VERSION_H) +gxditview_SOURCES = $(GXDITVIEWSOURCES) +nodist_gxditview_SOURCES = $(XDITVIEW_GENHDRS) +CLEANFILES += $(XDITVIEW_GENHDRS) + +man1_MANS += $(GXDITVIEW_MAN1) + +# Because we defined gxditview_CPPFLAGS, automake renames all of +# xditview's objects, adding an "gxditview-" prefix. +src/devices/xditview/gxditview-device.$(OBJEXT): defs.h +src/devices/xditview/gxditview-xditview.$(OBJEXT): $(XDITVIEW_GENHDRS) + +src/devices/xditview/GXditview-ad.h: $(xditview_srcdir)/GXditview.ad + $(AM_V_GEN)$(SHELL) $(xditview_srcdir)/ad2c \ + $(xditview_srcdir)/GXditview.ad > $@ +endif + +EXTRA_DIST += \ + src/devices/xditview/ad2c \ + src/devices/xditview/ChangeLog \ + src/devices/xditview/DESC.in \ + src/devices/xditview/FontMap-X11 \ + src/devices/xditview/GXditview-color.ad \ + src/devices/xditview/GXditview.ad \ + src/devices/xditview/README \ + src/devices/xditview/TODO \ + src/devices/xditview/gray1.bm \ + src/devices/xditview/gray2.bm \ + src/devices/xditview/gray3.bm \ + src/devices/xditview/gray4.bm \ + src/devices/xditview/gray5.bm \ + src/devices/xditview/gray6.bm \ + src/devices/xditview/gray7.bm \ + src/devices/xditview/gray8.bm \ + src/devices/xditview/xdit.bm \ + src/devices/xditview/xdit_mask.bm \ + src/devices/xditview/gxditview.1.man + +# Custom installation of GXditview.ad and GXditview-color.ad +install-data-local: install_xditview +uninstall-local: uninstall_xditview + +if WITHOUT_X11 +install_xditview: +uninstall_xditview: +else +install_xditview: \ + $(xditview_srcdir)/FontMap-X11 \ + $(xditview_srcdir)/GXditview.ad \ + $(xditview_srcdir)/GXditview-color.ad + $(MKDIR_P) $(DESTDIR)$(fontdir) + $(INSTALL_DATA) $(xditview_srcdir)/FontMap-X11 \ + $(DESTDIR)$(fontdir)/FontMap-X11 + -test -d $(DESTDIR)$(appdefdir) \ + || $(mkinstalldirs) $(DESTDIR)$(appdefdir) + $(INSTALL_DATA) $(xditview_srcdir)/GXditview.ad \ + $(DESTDIR)$(appdefdir)/GXditview + $(INSTALL_DATA) $(xditview_srcdir)/GXditview-color.ad \ + $(DESTDIR)$(appdefdir)/GXditview-color + +uninstall_xditview: + rm -f $(DESTDIR)$(appdefdir)/GXditview + rm -f $(DESTDIR)$(appdefdir)/GXditview-color + rm -f $(DESTDIR)$(fontdir)/FontMap-X11 + -rmdir $(DESTDIR)$(fontdir) 2>/dev/null + +endif + + +# Local Variables: +# fill-column: 72 +# mode: makefile-automake +# End: +# vim: set autoindent filetype=automake textwidth=72: diff --git a/src/devices/xditview/xditview.c b/src/devices/xditview/xditview.c new file mode 100644 index 0000000..1f56940 --- /dev/null +++ b/src/devices/xditview/xditview.c @@ -0,0 +1,684 @@ +/* + * Copyright 1991 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ +/* + * xditview -- + * + * Display ditroff output in an X window + */ + +#ifndef SABER +#ifndef lint +static char rcsid[] = "$XConsortium: xditview.c,v 1.17 89/12/10 17:05:08 rws Exp $"; +#endif /* lint */ +#endif /* SABER */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "Dvi.h" +#include "groff_version.h" + +#include "xdit.bm" +#include "xdit_mask.bm" + +#ifdef NEED_DECLARATION_POPEN +FILE *popen(const char *, const char *); +#endif /* NEED_DECLARATION_POPEN */ + +#ifdef NEED_DECLARATION_PCLOSE +int pclose (FILE *); +#endif /* NEED_DECLARATION_PCLOSE */ + +typedef void (*MakePromptFunc)(const char *); + +static String fallback_resources[] = { +#include "GXditview-ad.h" + NULL +}; + +static struct app_resources { + char *print_command; + char *filename; +} app_resources; + +#define offset(field) XtOffset(struct app_resources *, field) + +/* Application resources. */ + +static XtResource resources[] = { + {(String)"printCommand", (String)"PrintCommand", (String)XtRString, + sizeof(char*), offset(print_command), (String)XtRString, NULL}, + {(String)"filename", (String)"Filename", (String)XtRString, + sizeof(char*), offset(filename), (String)XtRString, NULL}, +}; + +#undef offset + +/* Command line options table. Only resources are entered here...there is a + pass over the remaining options after XrmParseCommand is let loose. */ + +static XrmOptionDescRec options[] = { +{(char *)"-page", (char *)"*dvi.pageNumber", + XrmoptionSepArg, NULL}, +{(char *)"-backingStore", (char *)"*dvi.backingStore", + XrmoptionSepArg, NULL}, +{(char *)"-resolution", (char *)"*dvi.resolution", + XrmoptionSepArg, NULL}, +{(char *)"-printCommand", (char *)".printCommand", + XrmoptionSepArg, NULL}, +{(char *)"-filename", (char *)".filename", + XrmoptionSepArg, NULL}, +{(char *)"-noPolyText", (char *)"*dvi.noPolyText", + XrmoptionNoArg, (XPointer)"TRUE"}, +}; + +static char current_print_command[1024]; + +static char current_file_name[1024]; +static FILE *current_file; + +/* + * Report the syntax for calling xditview. + */ + +static void +Syntax(const char *progname, bool had_error) +{ + FILE *stream = stdout; + if (had_error) + stream = stderr; + (void) fprintf (stream, "usage: %s [X-toolkit-option]" + " [-backingStore backing-store-type]" + " [-filename file]" +// See draw.c:FlushCharCache(). +#if 0 + " [-noPolyText]" +#endif + " [-page page-number]" + " [-printCommand command]" + " [-resolution resolution]" + " [file]\n", progname); + (void) fprintf (stream, "usage: %s {-version | --version}\n", + progname); + (void) fprintf (stream, "usage: %s {-help | --help}\n", + progname); + if (had_error) + exit(EXIT_FAILURE); + else + exit(EXIT_SUCCESS); +} + +static void NewFile (const char *); +static void SetPageNumber (int); +static Widget toplevel, paned, viewport, dvi; +static Widget page; +static Widget simpleMenu; + +static void NextPage(Widget, XtPointer, XtPointer); +static void PreviousPage(Widget, XtPointer, XtPointer); +static void SelectPage(Widget, XtPointer, XtPointer); +static void OpenFile(Widget, XtPointer, XtPointer); +static void Quit(Widget, XtPointer, XtPointer); +static void Print(Widget, XtPointer, XtPointer); + +static struct menuEntry { + const char *name; + XtCallbackProc function; +} menuEntries[] = { + {"nextPage", NextPage}, + {"previousPage", PreviousPage}, + {"selectPage", SelectPage}, + {"print", Print}, + {"openFile", OpenFile}, + {"quit", Quit}, +}; + +static void NextPageAction(Widget, XEvent *, String *, Cardinal *); +static void PreviousPageAction(Widget, XEvent *, String *, Cardinal *); +static void SelectPageAction(Widget, XEvent *, String *, Cardinal *); +static void OpenFileAction(Widget, XEvent *, String *, Cardinal *); +static void QuitAction(Widget, XEvent *, String *, Cardinal *); +static void AcceptAction(Widget, XEvent *, String *, Cardinal *); +static void CancelAction(Widget, XEvent *, String *, Cardinal *); +static void PrintAction(Widget, XEvent *, String *, Cardinal *); +static void RerasterizeAction(Widget, XEvent *, String *, Cardinal *); + +static void MakePrompt(Widget, const char *, MakePromptFunc, const char *); + +XtActionsRec xditview_actions[] = { + {(String)"NextPage", NextPageAction}, + {(String)"PreviousPage", PreviousPageAction}, + {(String)"SelectPage", SelectPageAction}, + {(String)"Print", PrintAction}, + {(String)"OpenFile", OpenFileAction}, + {(String)"Rerasterize", RerasterizeAction}, + {(String)"Quit", QuitAction}, + {(String)"Accept", AcceptAction}, + {(String)"Cancel", CancelAction}, +}; + +#define MenuNextPage 0 +#define MenuPreviousPage 1 +#define MenuSelectPage 2 +#define MenuPrint 3 +#define MenuOpenFile 4 +#define MenuQuit 5 + +static char pageLabel[256] = "Page "; + +int main(int argc, char **argv) +{ + char *file_name = 0; + Cardinal i; + static Arg labelArgs[] = { + {XtNlabel, (XtArgVal) pageLabel}, + }; + XtAppContext xtcontext; + Arg topLevelArgs[2]; + Widget entry; + Arg pageNumberArgs[1]; + int page_number; + + toplevel = XtAppInitialize(&xtcontext, "GXditview", + options, XtNumber (options), + &argc, argv, fallback_resources, NULL, 0); + if (argc > 2) + Syntax(argv[0], true /* had error */); + else if (argc == 2) { + if ((strcmp(argv[1], "-help") == 0) + || (strcmp(argv[1], "--help") == 0)) + Syntax(argv[0], false /* did not have error */); + else if ((strcmp(argv[1], "-version") == 0) + || (strcmp(argv[1], "--version") == 0)) { + (void) printf("GNU gxditview (groff) version %s\n", + Version_string); + exit(EXIT_SUCCESS); + } + } + + XtGetApplicationResources(toplevel, (XtPointer)&app_resources, + resources, XtNumber(resources), + NULL, (Cardinal) 0); + if (app_resources.print_command) + strcpy(current_print_command, app_resources.print_command); + + XtAppAddActions(xtcontext, xditview_actions, XtNumber (xditview_actions)); + + XtSetArg (topLevelArgs[0], XtNiconPixmap, + XCreateBitmapFromData (XtDisplay (toplevel), + XtScreen(toplevel)->root, + (char *)xdit_bits, + xdit_width, xdit_height)); + + XtSetArg (topLevelArgs[1], XtNiconMask, + XCreateBitmapFromData (XtDisplay (toplevel), + XtScreen(toplevel)->root, + (char *)xdit_mask_bits, + xdit_mask_width, xdit_mask_height)); + XtSetValues (toplevel, topLevelArgs, 2); + if (argc > 1) + file_name = argv[1]; + + /* + * create the menu and insert the entries + */ + simpleMenu = XtCreatePopupShell ("menu", simpleMenuWidgetClass, toplevel, + NULL, 0); + for (i = 0; i < XtNumber (menuEntries); i++) { + entry = XtCreateManagedWidget(menuEntries[i].name, + smeBSBObjectClass, simpleMenu, + NULL, (Cardinal) 0); + XtAddCallback(entry, XtNcallback, menuEntries[i].function, NULL); + } + + paned = XtCreateManagedWidget("paned", panedWidgetClass, toplevel, + NULL, (Cardinal) 0); + viewport = XtCreateManagedWidget("viewport", viewportWidgetClass, paned, + NULL, (Cardinal) 0); + dvi = XtCreateManagedWidget ("dvi", dviWidgetClass, viewport, NULL, 0); + page = XtCreateManagedWidget ("label", labelWidgetClass, paned, + labelArgs, XtNumber (labelArgs)); + XtSetArg (pageNumberArgs[0], XtNpageNumber, &page_number); + XtGetValues (dvi, pageNumberArgs, 1); + if (file_name) + NewFile (file_name); + /* NewFile modifies current_file_name, so do this here. */ + if (app_resources.filename) + strcpy(current_file_name, app_resources.filename); + XtRealizeWidget (toplevel); + if (file_name) + SetPageNumber (page_number); + XtInstallAllAccelerators(paned,paned); + XtAppMainLoop(xtcontext); + return 0; +} + +static void +SetPageNumber (int number) +{ + Arg arg[2]; + int actual_number, last_page; + + XtSetArg (arg[0], XtNpageNumber, number); + XtSetValues (dvi, arg, 1); + XtSetArg (arg[0], XtNpageNumber, &actual_number); + XtSetArg (arg[1], XtNlastPageNumber, &last_page); + XtGetValues (dvi, arg, 2); + if (actual_number == 0) + sprintf (pageLabel, "Page "); + else if (last_page > 0) + sprintf (pageLabel, "Page %d of %d", actual_number, last_page); + else + sprintf (pageLabel, "Page %d", actual_number); + XtSetArg (arg[0], XtNlabel, pageLabel); + XtSetValues (page, arg, 1); +} + +static void +SelectPageNumber (const char *number_string) +{ + SetPageNumber (atoi(number_string)); +} + +static int hadFile = 0; + +static void +NewFile (const char *name) +{ + Arg arg[2]; + char *n; + FILE *new_file; + Boolean seek = 0; + + if (current_file) { + if (!strcmp (current_file_name, "-")) + ; + else if (current_file_name[0] == '|') + pclose (current_file); + else + fclose (current_file); + } + if (!strcmp (name, "-")) + new_file = stdin; + else if (name[0] == '|') + new_file = popen (name+1, "r"); + else { + new_file = fopen (name, "r"); + seek = 1; + } + if (!new_file) { + /* XXX display error message */ + return; + } + XtSetArg (arg[0], XtNfile, new_file); + XtSetArg (arg[1], XtNseek, seek); + XtSetValues (dvi, arg, 2); + if (hadFile || name[0] != '-' || name[1] != '\0') { + XtSetArg (arg[0], XtNtitle, name); + if (name[0] != '/' && (n = strrchr (name, '/'))) + n = n + 1; + else + n = (char *)name; + XtSetArg (arg[1], XtNiconName, n); + XtSetValues (toplevel, arg, 2); + } + hadFile = 1; + SelectPageNumber ("1"); + strcpy (current_file_name, name); + current_file = new_file; +} + +static char fileBuf[1024]; + +static void +ResetMenuEntry (Widget entry) +{ + Arg arg[1]; + + XtSetArg (arg[0], (String)XtNpopupOnEntry, entry); + XtSetValues (XtParent(entry) , arg, (Cardinal) 1); +} + +/*ARGSUSED*/ + +static void +NextPage (Widget entry, XtPointer name, XtPointer data) +{ + name = name; /* unused; suppress compiler warning */ + data = data; + + NextPageAction((Widget)NULL, (XEvent *) 0, (String *) 0, (Cardinal *) 0); + ResetMenuEntry (entry); +} + +static void +NextPageAction (Widget widget, XEvent *event, + String *params, Cardinal *num_params) +{ + Arg args[1]; + int number; + + XtSetArg (args[0], XtNpageNumber, &number); + XtGetValues (dvi, args, 1); + SetPageNumber (number+1); + + widget = widget; /* unused; suppress compiler warning */ + event = event; + params = params; + num_params = num_params; +} + +/*ARGSUSED*/ + +static void +PreviousPage (Widget entry, XtPointer name, XtPointer data) +{ + name = name; /* unused; suppress compiler warning */ + data = data; + + PreviousPageAction ((Widget)NULL, (XEvent *) 0, (String *) 0, + (Cardinal *) 0); + ResetMenuEntry (entry); +} + +static void +PreviousPageAction (Widget widget, XEvent *event, + String *params, Cardinal *num_params) +{ + Arg args[1]; + int number; + + XtSetArg (args[0], XtNpageNumber, &number); + XtGetValues (dvi, args, 1); + SetPageNumber (number-1); + + widget = widget; /* unused; suppress compiler warning */ + event = event; + params = params; + num_params = num_params; +} + +/* ARGSUSED */ + +static void +SelectPage (Widget entry, XtPointer name, XtPointer data) +{ + name = name; /* unused; suppress compiler warning */ + data = data; + + SelectPageAction ((Widget)NULL, (XEvent *) 0, (String *) 0, + (Cardinal *) 0); + ResetMenuEntry (entry); +} + +static void +SelectPageAction (Widget widget, XEvent *event, + String *params, Cardinal *num_params) +{ + widget = widget; /* unused; suppress compiler warning */ + event = event; + params = params; + num_params = num_params; + + MakePrompt (toplevel, "Page number", SelectPageNumber, ""); +} + + +static void +DoPrint (const char *name) +{ + FILE *print_file; + RETSIGTYPE (*handler)(int); + + /* Avoid dying because of an invalid command. */ + handler = signal(SIGPIPE, SIG_IGN); + + print_file = popen(name, "w"); + if (!print_file) + /* XXX print error message */ + return; + DviSaveToFile(dvi, print_file); + pclose(print_file); + signal(SIGPIPE, handler); + strcpy(current_print_command, name); +} + +static void +RerasterizeAction (Widget widget, XEvent *event, + String *params, Cardinal *num_params) +{ + Arg args[1]; + int number; + + if (current_file_name[0] == 0) { + /* XXX display an error message */ + return; + } + XtSetArg (args[0], XtNpageNumber, &number); + XtGetValues (dvi, args, 1); + NewFile(current_file_name); + SetPageNumber (number); + + widget = widget; /* unused; suppress compiler warning */ + event = event; + params = params; + num_params = num_params; +} + +/* ARGSUSED */ + +static void +Print (Widget entry, XtPointer name, XtPointer data) +{ + name = name; /* unused; suppress compiler warning */ + data = data; + + PrintAction ((Widget)NULL, (XEvent *) 0, (String *) 0, (Cardinal *) 0); + ResetMenuEntry (entry); +} + +static void +PrintAction (Widget widget, XEvent *event, + String *params, Cardinal *num_params) +{ + widget = widget; /* unused; suppress compiler warning */ + event = event; + params = params; + num_params = num_params; + + if (current_print_command[0]) + strcpy (fileBuf, current_print_command); + else + fileBuf[0] = '\0'; + MakePrompt (toplevel, "Print command:", DoPrint, fileBuf); +} + + +/* ARGSUSED */ + +static void +OpenFile (Widget entry, XtPointer name, XtPointer data) +{ + name = name; /* unused; suppress compiler warning */ + data = data; + + OpenFileAction ((Widget)NULL, (XEvent *) 0, (String *) 0, (Cardinal *) 0); + ResetMenuEntry (entry); +} + +static void +OpenFileAction (Widget widget, XEvent *event, + String *params, Cardinal *num_params) +{ + widget = widget; /* unused; suppress compiler warning */ + event = event; + params = params; + num_params = num_params; + + if (current_file_name[0]) + strcpy (fileBuf, current_file_name); + else + fileBuf[0] = '\0'; + MakePrompt (toplevel, "File to open:", NewFile, fileBuf); +} + +/* ARGSUSED */ + +static void +Quit (Widget entry, XtPointer closure, XtPointer data) +{ + entry = entry; /* unused; suppress compiler warning */ + closure = closure; + data = data; + + QuitAction ((Widget)NULL, (XEvent *) 0, (String *) 0, (Cardinal *) 0); +} + +static void +QuitAction (Widget widget, XEvent *event, + String *params, Cardinal *num_params) +{ + widget = widget; /* unused; suppress compiler warning */ + event = event; + params = params; + num_params = num_params; + + exit (0); +} + +Widget promptShell, promptDialog; +MakePromptFunc promptfunction; + +/* ARGSUSED */ +static +void CancelAction (Widget widget, XEvent *event, + String *params, Cardinal *num_params) +{ + widget = widget; /* unused; suppress compiler warning */ + event = event; + params = params; + num_params = num_params; + + if (promptShell) { + XtSetKeyboardFocus(toplevel, (Widget) None); + XtDestroyWidget(promptShell); + promptShell = (Widget) 0; + } +} + +static +void AcceptAction (Widget widget, XEvent *event, + String *params, Cardinal *num_params) +{ + (*promptfunction)(XawDialogGetValueString(promptDialog)); + CancelAction (widget, event, params, num_params); +} + +static void +MakePrompt(Widget centerw, const char *prompt, + MakePromptFunc func, const char *def) +{ + static Arg dialogArgs[] = { + {XtNlabel, 0}, + {XtNvalue, 0}, + }; + Arg valueArgs[1]; + Arg centerArgs[2]; + Position source_x, source_y; + Position dest_x, dest_y; + Dimension center_width, center_height; + Dimension prompt_width, prompt_height; + Widget valueWidget; + + CancelAction ((Widget)NULL, (XEvent *) 0, (String *) 0, (Cardinal *) 0); + promptShell = XtCreatePopupShell ("promptShell", transientShellWidgetClass, + toplevel, NULL, (Cardinal) 0); + dialogArgs[0].value = (XtArgVal)prompt; + dialogArgs[1].value = (XtArgVal)def; + promptDialog = XtCreateManagedWidget( "promptDialog", dialogWidgetClass, + promptShell, dialogArgs, XtNumber (dialogArgs)); + XawDialogAddButton(promptDialog, "accept", NULL, (XtPointer) 0); + XawDialogAddButton(promptDialog, "cancel", NULL, (XtPointer) 0); + valueWidget = XtNameToWidget (promptDialog, "value"); + if (valueWidget) { + XtSetArg (valueArgs[0], (String)XtNresizable, TRUE); + XtSetValues (valueWidget, valueArgs, 1); + /* + * as resizable isn't set until just above, the + * default value will be displayed incorrectly. + * rectify the situation by resetting the values + */ + XtSetValues (promptDialog, dialogArgs, XtNumber (dialogArgs)); + } + XtSetKeyboardFocus (promptDialog, valueWidget); + XtSetKeyboardFocus (toplevel, valueWidget); + XtRealizeWidget (promptShell); + /* + * place the widget in the center of the "parent" + */ + XtSetArg (centerArgs[0], XtNwidth, ¢er_width); + XtSetArg (centerArgs[1], XtNheight, ¢er_height); + XtGetValues (centerw, centerArgs, 2); + XtSetArg (centerArgs[0], XtNwidth, &prompt_width); + XtSetArg (centerArgs[1], XtNheight, &prompt_height); + XtGetValues (promptShell, centerArgs, 2); + source_x = (center_width - prompt_width) / 2; + source_y = (center_height - prompt_height) / 3; + XtTranslateCoords (centerw, source_x, source_y, &dest_x, &dest_y); + XtSetArg (centerArgs[0], XtNx, dest_x); + XtSetArg (centerArgs[1], XtNy, dest_y); + XtSetValues (promptShell, centerArgs, 2); + XtMapWidget(promptShell); + promptfunction = func; +} + +/* +Local Variables: +c-indent-level: 4 +c-continued-statement-offset: 4 +c-brace-offset: -4 +c-argdecl-indent: 4 +c-label-offset: -4 +c-tab-always-indent: nil +End: +*/ -- cgit v1.2.3