diff options
Diffstat (limited to 'src/devices/xditview/xditview.c')
-rw-r--r-- | src/devices/xditview/xditview.c | 684 |
1 files changed, 684 insertions, 0 deletions
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 <config.h> +#endif + +#include <X11/Xatom.h> +#include <X11/Xlib.h> +#include <X11/Xos.h> +#include <X11/Intrinsic.h> +#include <X11/StringDefs.h> +#include <X11/Shell.h> +#include <X11/Xaw/Paned.h> +#include <X11/Xaw/Viewport.h> +#include <X11/Xaw/Box.h> +#include <X11/Xaw/Command.h> +#include <X11/Xaw/Dialog.h> +#include <X11/Xaw/Label.h> +#include <X11/Xaw/SimpleMenu.h> +#include <X11/Xaw/SmeBSB.h> + +#include <stdbool.h> +#include <stdlib.h> +#include <signal.h> +#include <stdio.h> + +#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 <none>"; + +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 <none>"); + 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: +*/ |