1/*
2 * $Xorg: xmore.c,v 1.1 2004/04/30 02:05:54 gisburn Exp $
3 *
4Copyright 2004 Roland Mainz <roland.mainz@nrubsig.org>
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from The Open Group.
25 *
26 */
27
28#ifdef HAVE_CONFIG_H
29# include "config.h"
30#endif
31
32/* Force ANSI C prototypes from X11 headers */
33#ifndef FUNCPROTO
34#define FUNCPROTO 15
35#endif /* !FUNCPROTO */
36
37#include <X11/StringDefs.h>
38#include <X11/Intrinsic.h>
39#include <X11/Shell.h>
40#include <X11/Xaw/Form.h>
41#include <X11/Xaw/List.h>
42#include <X11/Xaw/Command.h>
43#include <X11/Xaw/AsciiText.h>
44#include <X11/Xaw/Cardinals.h>
45
46#include "xmore.h"
47
48#include <stdlib.h>
49#include <stdio.h>
50#include <limits.h>
51
52/* Global vars */
53static Widget        toplevel          = NULL;
54static Widget        text              = NULL;
55static const char   *ProgramName;  /* program name   (from argv[0]) */
56static const char   *viewFileName; /* file to browse (from argv[1]) */
57
58/* prototypes */
59static void quitAction(Widget w,  XEvent *event, String *params, Cardinal *num_params);
60static void quitXtProc(Widget w, XtPointer client_data, XtPointer callData);
61
62static XrmOptionDescRec options[] = {
63{
64  "-v", "*verbose", XrmoptionNoArg, (XPointer) "on" },
65};
66
67
68static XtActionsRec actions[] = {
69    { "quit",          quitAction      },
70};
71
72/* See xmore.h */
73static XMoreResourceData userOptions;
74
75#define Offset(field) XtOffsetOf(XMoreResourceData, field)
76
77static XtResource resources[] = {
78  {"verbose", "Verbose", XtRBoolean, sizeof(Boolean),  Offset(verbose),  XtRImmediate, (XtPointer)False},
79  {"textfont", XtCFont,  XtRFontSet, sizeof(XFontSet), Offset(textfont), XtRString,    STANDARDFONT},
80};
81
82
83static String fallback_resources[] = {
84#ifdef NOTYET
85    "*iconPixmap:    xmore32",
86    "*iconMask:      xmore32",
87#endif /* NOTYET */
88    "*textfont: " STANDARDFONT,
89    "*international: True", /* set this globally for ALL widgets to avoid wierd crashes */
90    "*text.Translations: #override \\n\\"
91        "\tCtrl<Key>S:     no-op(RingBell)\\n\\"
92        "\tCtrl<Key>R:     no-op(RingBell)\\n\\"
93        "\t<Key>space:     next-page()\\n\\"
94        "\t<Key>F:         next-page()\\n\\"
95        "\tCtrl<Key>B:     previous-page()\\n\\"
96        "\t<Key>B:         previous-page()\\n\\"
97        "\t<Key>K:         scroll-one-line-down()\\n\\"
98        "\t<Key>Y:         scroll-one-line-down()\\n\\"
99        "\t<Key>Return:    scroll-one-line-up()\\n\\"
100        "\t<Key>J:         scroll-one-line-up()\\n\\"
101        "\t<Key>E:         scroll-one-line-up()\\n\\"
102        "\t<Key>q:         quit()\\n",
103    "*text.baseTranslations: #override \\n\\"
104        "\t<Key>space:     next-page()\\n\\"
105        "\t<Key>F:         next-page()\\n\\"
106        "\tCtrl<Key>B:     previous-page()\\n\\"
107        "\t<Key>K:         scroll-one-line-down()\\n\\"
108        "\t<Key>Y:         scroll-one-line-down()\\n\\"
109        "\t<Key>Return:    scroll-one-line-up()\\n\\"
110        "\t<Key>J:         scroll-one-line-up()\\n\\"
111        "\t<Key>E:         scroll-one-line-up()\\n\\"
112        "\t<Key>q:         quit()\\n",
113    NULL,
114};
115
116static void
117quitAction(Widget w, _X_UNUSED XEvent *event,
118           _X_UNUSED String *params, _X_UNUSED Cardinal *num_params)
119{
120    XtAppSetExitFlag(XtWidgetToApplicationContext(w));
121}
122
123static void
124quitXtProc(Widget w, _X_UNUSED XtPointer client_data,
125           _X_UNUSED XtPointer callData)
126{
127    XtCallActionProc(w, "quit", NULL, NULL, 0);
128}
129
130_X_NORETURN _X_COLD
131static void
132usage(FILE *out, int exitval)
133{
134  fprintf(out,
135          "usage: %s [ x options ] [-help|-version] filename\n",
136          ProgramName);
137  exit(exitval);
138}
139
140int main( int argc, char *argv[] )
141{
142  XtAppContext app;
143  Widget       form;
144  Widget       quitbutton;
145  int          n;
146  Arg          args[8];
147
148  ProgramName = argv[0];
149
150  /* Handle args that don't require opening a display */
151  for (int i = 1; i < argc; i++) {
152    const char *argn = argv[i];
153    /* accept single or double dash for -help & -version */
154    if (argn[0] == '-' && argn[1] == '-') {
155      argn++;
156    }
157    if (strcmp (argn, "-help") == 0) {
158      usage(stdout, EXIT_SUCCESS);
159    }
160    if (strcmp (argn, "-version") == 0) {
161      puts(PACKAGE_STRING);
162      exit(EXIT_SUCCESS);
163    }
164  }
165
166  XtSetLanguageProc(NULL, NULL, NULL);
167  toplevel = XtOpenApplication(&app, "XMore",
168                               options, XtNumber(options),
169                               &argc, argv, fallback_resources,
170                               sessionShellWidgetClass, NULL, ZERO);
171
172  if (argc != 2)
173  {
174    fputs("Unknown argument(s):", stderr);
175    for (int i = 1; i < argc; i++) {
176      fprintf(stderr, " %s", argv[i]);
177    }
178    fputs("\n\n", stderr);
179    usage(stderr, EXIT_FAILURE);
180  }
181
182  XtGetApplicationResources(toplevel, (XtPointer)&userOptions, resources,
183                            XtNumber(resources), NULL, 0);
184
185  XtAppAddActions(app, actions, XtNumber(actions));
186
187  viewFileName = argv[1];
188
189  form = XtCreateManagedWidget("form", formWidgetClass, toplevel, NULL, 0);
190
191  n = 0;
192  XtSetArg(args[n], XtNtype,             XawAsciiFile);            n++;
193  XtSetArg(args[n], XtNstring,           viewFileName);            n++;
194  XtSetArg(args[n], XtNwidth,            700);                     n++;
195  XtSetArg(args[n], XtNheight,           300);                     n++;
196  XtSetArg(args[n], XtNscrollHorizontal, XawtextScrollAlways);     n++;
197  XtSetArg(args[n], XtNscrollVertical,   XawtextScrollAlways);     n++;
198  XtSetArg(args[n], XtNfontSet,          userOptions.textfont);    n++;
199  text = XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, n);
200
201  n = 0;
202  XtSetArg(args[n], XtNfromHoriz,       NULL);                   n++;
203  XtSetArg(args[n], XtNfromVert,        text);                   n++;
204  XtSetArg(args[n], XtNlabel,           "Quit");      n++;
205  quitbutton = XtCreateManagedWidget("quit", commandWidgetClass, form, args, n);
206  XtAddCallback(quitbutton, XtNcallback, quitXtProc, NULL);
207
208  XtRealizeWidget(toplevel);
209
210  XtAppMainLoop(app);
211
212  return EXIT_SUCCESS;
213}
214
215