xmore.c revision 16910e25
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/* Force ANSI C prototypes from X11 headers */
29#ifndef FUNCPROTO
30#define FUNCPROTO 15
31#endif /* !FUNCPROTO */
32
33#include <X11/StringDefs.h>
34#include <X11/Intrinsic.h>
35#include <X11/Shell.h>
36#include <X11/Xaw/Form.h>
37#include <X11/Xaw/List.h>
38#include <X11/Xaw/Command.h>
39#include <X11/Xaw/AsciiText.h>
40#include <X11/Xaw/Cardinals.h>
41
42#include "xmore.h"
43
44#ifdef USE_XPRINT
45
46#include "printdialog.h"
47#include "print.h"
48
49#endif
50
51#include <stdlib.h>
52#include <stdio.h>
53#include <limits.h>
54
55/* Turn a NULL pointer string into an empty string */
56#define NULLSTR(x) (((x)!=NULL)?(x):(""))
57
58#define Error(x) { printf x ; exit(EXIT_FAILURE); }
59#define Assertion(expr, msg) { if (!(expr)) { Error msg } }
60#define Log(x)   { if (userOptions.verbose) printf x; }
61
62/* Global vars */
63static Widget        printdialog_shell = NULL;
64static Widget        printdialog       = NULL;
65static Widget        toplevel          = NULL;
66static Widget        text              = NULL;
67static char          printJobNameBuffer[PATH_MAX+256];
68static const char   *ProgramName;  /* program name   (from argv[0]) */
69static const char   *viewFileName; /* file to browse (from argv[1]) */
70
71/* prototypes */
72static void quitAction(Widget w,  XEvent *event, String *params, Cardinal *num_params);
73static void quitXtProc(Widget w, XtPointer client_data, XtPointer callData);
74#ifdef USE_XPRINT
75static void printAction(Widget w, XEvent *event, String *params, Cardinal *num_params);
76static void printXtProc(Widget w, XtPointer client_data, XtPointer callData);
77#endif
78
79static XrmOptionDescRec options[] = {
80{
81  "-v", "*verbose", XrmoptionNoArg, (XPointer) "on" },
82};
83
84
85static XtActionsRec actions[] = {
86    { "quit",          quitAction      },
87#ifdef USE_XPRINT
88    { "print",         printAction     }
89#endif
90};
91
92/* See xmore.h */
93XMoreResourceData userOptions;
94
95#define Offset(field) XtOffsetOf(XMoreResourceData, field)
96
97XtResource resources[] = {
98  {"verbose", "Verbose", XtRBoolean, sizeof(Boolean),  Offset(verbose),  XtRImmediate, (XtPointer)False},
99  {"textfont", XtCFont,  XtRFontSet, sizeof(XFontSet), Offset(textfont), XtRString,    STANDARDFONT},
100};
101
102
103String fallback_resources[] = {
104#ifdef NOTYET
105    "*iconPixmap:    xmore32",
106    "*iconMask:      xmore32",
107#endif /* NOTYET */
108    "*textfont: " STANDARDFONT,
109    "*international: True", /* set this globally for ALL widgets to avoid wiered crashes */
110    "*text.Translations: #override \\n\\"
111        "\tCtrl<Key>S:     no-op(RingBell)\\n\\"
112        "\tCtrl<Key>R:     no-op(RingBell)\\n\\"
113        "\t<Key>space:     next-page()\\n\\"
114        "\t<Key>F:         next-page()\\n\\"
115        "\tCtrl<Key>B:     previous-page()\\n\\"
116        "\t<Key>B:         previous-page()\\n\\"
117        "\t<Key>K:         scroll-one-line-down()\\n\\"
118        "\t<Key>Y:         scroll-one-line-down()\\n\\"
119        "\t<Key>Return:    scroll-one-line-up()\\n\\"
120        "\t<Key>J:         scroll-one-line-up()\\n\\"
121        "\t<Key>E:         scroll-one-line-up()\\n\\"
122        "\t<Key>p:         print()\\n\\"
123        "\t<Key>q:         quit()\\n",
124    "*text.baseTranslations: #override \\n\\"
125        "\t<Key>space:     next-page()\\n\\"
126        "\t<Key>F:         next-page()\\n\\"
127        "\tCtrl<Key>B:     previous-page()\\n\\"
128        "\t<Key>K:         scroll-one-line-down()\\n\\"
129        "\t<Key>Y:         scroll-one-line-down()\\n\\"
130        "\t<Key>Return:    scroll-one-line-up()\\n\\"
131        "\t<Key>J:         scroll-one-line-up()\\n\\"
132        "\t<Key>E:         scroll-one-line-up()\\n\\"
133        "\t<Key>p:         print()\\n\\"
134        "\t<Key>q:         quit()\\n",
135    NULL,
136};
137
138static void
139quitAction(Widget w,  XEvent *event, String *params, Cardinal *num_params)
140{
141    XtAppSetExitFlag(XtWidgetToApplicationContext(w));
142}
143
144static void
145quitXtProc(Widget w, XtPointer client_data, XtPointer callData)
146{
147    XtCallActionProc(w, "quit", NULL, NULL, 0);
148}
149
150static void
151printshellDestroyXtProc(Widget w, XtPointer client_data, XtPointer callData)
152{
153    XawPrintDialogClosePrinterConnection(printdialog, False);
154}
155
156#ifdef USE_XPRINT
157
158static void
159printOKXtProc(Widget w, XtPointer client_data, XtPointer callData)
160{
161    XawPrintDialogCallbackStruct *pdcs = (XawPrintDialogCallbackStruct *)callData;
162    Cardinal                      n;
163    Arg                           args[2];
164    Widget                        textsource;
165
166    Log(("printOKXtProc: OK.\n"));
167
168    /* Get TextSource object */
169    n = 0;
170    XtSetArg(args[n], XtNtextSource, &textsource); n++;
171    XtGetValues(text, args, n);
172
173    Assertion(textsource != NULL, (("printOKXtProc: textsource == NULL.\n")));
174
175    /* ||printJobNameBuffer| must live as long the print job prints
176     * because it is used for the job title AND the page headers... */
177    sprintf(printJobNameBuffer, "XMore print job %s", viewFileName);
178
179    DoPrintTextSource(ProgramName,
180                      textsource, toplevel,
181                      pdcs->pdpy, pdcs->pcontext, pdcs->colorspace,
182                      printshellDestroyXtProc,
183                      printJobNameBuffer,
184                      pdcs->printToFile?pdcs->printToFileName:NULL);
185
186    XtPopdown(printdialog_shell);
187}
188
189static void
190printCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
191{
192    Log(("printCancelXtProc: cancel.\n"));
193    XtPopdown(printdialog_shell);
194
195    Log(("destroying print dialog shell...\n"));
196    XtDestroyWidget(printdialog_shell);
197    printdialog_shell = NULL;
198    printdialog       = NULL;
199    Log(("... done\n"));
200}
201
202static void
203printXtProc(Widget w, XtPointer client_data, XtPointer callData)
204{
205    XtCallActionProc(toplevel, "print", NULL, NULL, 0);
206}
207
208static void
209printAction(Widget w,  XEvent *event, String *params, Cardinal *num_params)
210{
211  Dimension   width, height;
212  Position    x, y;
213  Widget      parent = toplevel;
214  Log(("print!\n"));
215
216  if (!printdialog) {
217    int n;
218    Arg args[20];
219
220    n = 0;
221    XtSetArg(args[n], XtNallowShellResize, True); n++;
222    printdialog_shell = XtCreatePopupShell("printdialogshell",
223                                           transientShellWidgetClass,
224                                           toplevel, args, n);
225    n = 0;
226    printdialog = XtCreateManagedWidget("printdialog", printDialogWidgetClass,
227                                        printdialog_shell, args, n);
228    XtAddCallback(printdialog, XawNOkCallback,     printOKXtProc,     NULL);
229    XtAddCallback(printdialog, XawNCancelCallback, printCancelXtProc, NULL);
230
231    XtRealizeWidget(printdialog_shell);
232  }
233
234  /* Center dialog */
235  XtVaGetValues(printdialog_shell,
236      XtNwidth,  &width,
237      XtNheight, &height,
238      NULL);
239
240  x = (Position)(XWidthOfScreen( XtScreen(parent)) - width)  / 2;
241  y = (Position)(XHeightOfScreen(XtScreen(parent)) - height) / 3;
242
243  XtVaSetValues(printdialog_shell,
244      XtNx, x,
245      XtNy, y,
246      NULL);
247
248  XtPopup(printdialog_shell, XtGrabNonexclusive);
249}
250
251#endif
252
253int main( int argc, char *argv[] )
254{
255  XtAppContext app;
256  Widget       form;
257  Widget       printbutton;
258  Widget       quitbutton;
259  int          n;
260  Arg          args[8];
261
262  ProgramName = argv[0];
263
264  XtSetLanguageProc(NULL, NULL, NULL);
265  toplevel = XtOpenApplication(&app, "XMore",
266                               options, XtNumber(options),
267                               &argc, argv, fallback_resources,
268                               sessionShellWidgetClass, NULL, ZERO);
269
270  if (argc != 2)
271  {
272    printf("usage: %s [ x options ] filename\n", argv[0]);
273    exit(EXIT_FAILURE);
274  }
275
276  XtGetApplicationResources(toplevel, (XtPointer)&userOptions, resources,
277                            XtNumber(resources), NULL, 0);
278
279  XtAppAddActions(app, actions, XtNumber(actions));
280
281  viewFileName = argv[1];
282
283  form = XtCreateManagedWidget("form", formWidgetClass, toplevel, NULL, 0);
284
285  n = 0;
286  XtSetArg(args[n], XtNtype,             XawAsciiFile);            n++;
287  XtSetArg(args[n], XtNstring,           viewFileName);            n++;
288  XtSetArg(args[n], XtNwidth,            700);                     n++;
289  XtSetArg(args[n], XtNheight,           300);                     n++;
290  XtSetArg(args[n], XtNscrollHorizontal, XawtextScrollAlways);     n++;
291  XtSetArg(args[n], XtNscrollVertical,   XawtextScrollAlways);     n++;
292  XtSetArg(args[n], XtNfontSet,          userOptions.textfont);    n++;
293  text = XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, n);
294
295#ifdef USE_XPRINT
296  n = 0;
297  XtSetArg(args[n], XtNfromHoriz,       NULL);            n++;
298  XtSetArg(args[n], XtNfromVert,        text);            n++;
299  XtSetArg(args[n], XtNlabel,           "Print...");      n++;
300  printbutton = XtCreateManagedWidget("print", commandWidgetClass, form, args, n);
301  XtAddCallback(printbutton, XtNcallback, printXtProc, 0);
302#endif
303
304  n = 0;
305  XtSetArg(args[n], XtNfromHoriz,       printbutton);            n++;
306  XtSetArg(args[n], XtNfromVert,        text);                   n++;
307  XtSetArg(args[n], XtNlabel,           "Quit");      n++;
308  quitbutton = XtCreateManagedWidget("quit", commandWidgetClass, form, args, n);
309  XtAddCallback(quitbutton, XtNcallback, quitXtProc, 0);
310
311  printdialog_shell = NULL;
312  printdialog       = NULL;
313
314  XtRealizeWidget(toplevel);
315
316  XtAppMainLoop(app);
317
318  return EXIT_SUCCESS;
319}
320
321