summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--print.c353
-rw-r--r--print.h44
-rw-r--r--printdialog.c1375
-rw-r--r--printdialog.h84
-rw-r--r--printdialogprivates.h176
-rw-r--r--xmore.c200
-rw-r--r--xmore.h35
-rw-r--r--xmore.man25
-rw-r--r--xmore.sgml82
9 files changed, 2374 insertions, 0 deletions
diff --git a/print.c b/print.c
new file mode 100644
index 0000000..d8d93d7
--- /dev/null
+++ b/print.c
@@ -0,0 +1,353 @@
+/*
+ * $Xorg: print.c,v 1.1 2004/04/30 02:05:54 gisburn Exp $
+ *
+Copyright 2004 Roland Mainz <roland.mainz@nrubsig.org>
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ */
+
+/* Turn a NULL pointer string into an empty string */
+#define NULLSTR(x) (((x)!=NULL)?(x):(""))
+
+#define Error(x) { printf x ; exit(EXIT_FAILURE); }
+#define Assertion(expr, msg) { if (!(expr)) { Error msg } }
+#define Log(x) { if(True) printf x; }
+
+#include "xmore.h"
+#include "print.h"
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/AsciiText.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define PRINT_PAGEHEADER 1
+
+static Widget
+CreatePrintShell(Widget videoshell,
+ Screen *pscreen,
+ String printshell_name,
+ ArgList args,
+ Cardinal numargs)
+{
+ String videoname,
+ videoclass;
+ Widget pappshell,
+ printshell;
+ Display *pdpy = XDisplayOfScreen(pscreen);
+ int dummyc = 0;
+ String dummys = "";
+ XtGetApplicationNameAndClass(XtDisplay(videoshell),
+ &videoname, &videoclass);
+
+ /* XXX: Why is the |dummyc|&&|dummys| stuff needed here ? */
+ XtDisplayInitialize(XtWidgetToApplicationContext(videoshell), pdpy,
+ videoname, videoclass,
+ NULL, 0,
+ &dummyc, &dummys);
+
+ pappshell = XtVaAppCreateShell(videoname, videoclass,
+ applicationShellWidgetClass,
+ pdpy,
+ XtNscreen, pscreen,
+ NULL);
+ printshell = XtCreatePopupShell(printshell_name,
+ xawPrintShellWidgetClass,
+ pappshell, args, numargs);
+
+
+ /* we're mapping/unmapping at start/end page time */
+ XtSetMappedWhenManaged(printshell, False);
+
+ /* We realise the widget when we're done with building the widget tree... */
+
+ return printshell;
+}
+
+typedef struct
+{
+ Widget toplevel;
+ Bool isPrinting;
+ Widget printshell;
+ struct
+ {
+ Widget form;
+ Widget pageheaderlabel;
+ Widget text;
+ } content; /* content to print */
+ int numpages;
+ Display *pdpy;
+ Screen *pscreen;
+ XPContext pcontext;
+ void *printtofile_handle;
+ const char *jobtitle;
+} AppPrintData;
+
+static AppPrintData apdx;
+static AppPrintData *apd = &apdx;
+
+/* Count pages in a text widget
+ * WARNING: This will reset the current position of the text widget
+ * back to the beginning */
+static
+long CountPages(Widget textWidget)
+{
+ long numpages = 0;
+
+ XawTextPosition prevpagepos = -1,
+ currpos = 0;
+
+ /* Move to the top of the file... */
+ XtCallActionProc(textWidget, "beginning-of-file", NULL, NULL, 0);
+
+ /* ... count pages ...*/
+ do
+ {
+ prevpagepos = XawTextTopPosition(textWidget);
+ XtCallActionProc(textWidget, "next-page", NULL, NULL, 0);
+ currpos = XawTextTopPosition(textWidget);
+ numpages++;
+ } while(prevpagepos != currpos);
+
+ /* ... and move to the top of the file... */
+ XtCallActionProc(textWidget, "beginning-of-file", NULL, NULL, 0);
+
+ return numpages;
+}
+
+static
+int GetCurrPageNum(Widget printshell)
+{
+ Cardinal n;
+ Arg args[2];
+ int pagenum = -666; /* bah! */
+
+ n = 0;
+ XtSetArg(args[n], XawNcurrPageNumInJob, &pagenum); n++;
+ XtGetValues(printshell, args, n);
+
+ return pagenum;
+}
+
+static void
+PageSetupCB(Widget widget, XtPointer client_data, XtPointer call_data)
+{
+ Widget pshell = widget;
+ XawPrintShellCallbackStruct *psp = (XawPrintShellCallbackStruct *)call_data;
+ AppPrintData *p = (AppPrintData *)client_data;
+
+ Log(("--> PageSetupCB\n"));
+
+ if (!psp->last_page_in_job) {
+ int currpage = GetCurrPageNum(pshell);
+#ifdef PRINT_PAGEHEADER
+ char buffer[256];
+ sprintf(buffer, "Title: %s / Page: %d/%d", p->jobtitle, currpage, p->numpages);
+ XtVaSetValues(apd->content.pageheaderlabel, XtNlabel, buffer, NULL);
+#endif /* PRINT_PAGEHEADER */
+
+ /* Note: XawPrintShell's pagecount starts with '1'
+ * (=first page is page no. '1') */
+ if (currpage > 1) {
+ Log(("pagedown %d\n", currpage));
+ XtCallActionProc(p->content.text, "next-page", NULL, NULL, 0);
+ }
+ else
+ {
+ Log(("first page\n"));
+ }
+
+ if (currpage >= p->numpages) {
+ psp->last_page_in_job = True;
+ }
+ }
+}
+
+void FinishPrinting(AppPrintData *p)
+{
+ if (p->printtofile_handle) {
+ if (XpuWaitForPrintFileChild(p->printtofile_handle) != XPGetDocFinished) {
+ fprintf(stderr, "%s: Error while printing to file.\n", ProgramName);
+ }
+ p->printtofile_handle = NULL;
+ }
+
+ if (p->printshell) {
+ XtDestroyWidget(p->printshell);
+ p->printshell = NULL;
+ }
+
+ /* |p->pdpy| and |p->pcontext| are destroyed when th
+ * print dialog widget gets destroyed. */
+
+ p->toplevel = NULL;
+ p->isPrinting = False;
+ p->pdpy = NULL;
+ p->pscreen = NULL;
+ p->pcontext = None;
+}
+
+static
+void PrintEndJobCB(Widget pshell, XtPointer client_data, XtPointer call_data)
+{
+ AppPrintData *p = (AppPrintData *)client_data;
+
+ Log(("--> PrintEndJobCB\n"));
+
+ /* Finish printing and destroy print shell (it's legal to destroy Xt
+ * widgets from within it's own callbacks) */
+ FinishPrinting(p);
+}
+
+XFontStruct *GetPrintTextFont(Display *pdpy, long dpi)
+{
+ XFontStruct *font;
+ char fontname[1024];
+
+ sprintf(fontname, "-adobe-courier-medium-r-normal--40-*-%ld-%ld-*-*-iso8859-1", dpi, dpi);
+ font = XLoadQueryFont(pdpy, fontname);
+ if (!font) {
+ sprintf(fontname, "-*-*-*-*-*-*-*-160-%ld-%ld-*-*-iso8859-1", dpi, dpi);
+ font = XLoadQueryFont(pdpy, fontname);
+ }
+ if (!font)
+ Error(("XLoadQueryFont failure.\n"));
+ return font;
+}
+
+void DoPrint(Widget toplevel, Display *pdpy, XPContext pcontext,
+ const char *jobtitle, const char *toFile)
+{
+ long dpi = 0;
+ int n;
+ Arg args[20];
+ XFontStruct *textfont = NULL;
+
+ if (apd->isPrinting) {
+ fprintf(stderr, "%s: Already busy with printing.\n", ProgramName);
+ return;
+ }
+
+ /* Configure the print context (paper size, title etc.)
+ * We must do this before creating any Xt widgets - otherwise they will
+ * make wrong assuptions about fonts, resultions etc. ...
+ */
+ XpuSetJobTitle(pdpy, pcontext, jobtitle);
+
+ /* Configuration done, set the context */
+ XpSetContext(pdpy, pcontext);
+
+ /* Get default printer resolution */
+ if (XpuGetResolution(pdpy, pcontext, &dpi) != 1) {
+ fprintf(stderr, "%s: No default resolution for printer.\n", ProgramName);
+ XpuClosePrinterDisplay(pdpy, pcontext);
+ return;
+ }
+
+ apd->toplevel = toplevel;
+ apd->pdpy = pdpy;
+ apd->pcontext = pcontext;
+ apd->pscreen = XpGetScreenOfContext(pdpy, pcontext);
+ apd->jobtitle = jobtitle;
+
+ n = 0;
+ XtSetArg(args[n], XawNlayoutMode, XawPrintLAYOUTMODE_DRAWABLEAREA); n++;
+ apd->printshell = CreatePrintShell(toplevel, apd->pscreen, "Print", args, n);
+
+ n = 0;
+ XtSetArg(args[n], XtNresizable, True); n++;
+ XtSetArg(args[n], XtNright, XtChainRight); n++;
+ apd->content.form = XtCreateManagedWidget("form", formWidgetClass, apd->printshell, args, n);
+
+ textfont = GetPrintTextFont(pdpy, dpi);
+
+#ifdef PRINT_PAGEHEADER
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, NULL); n++;
+ XtSetArg(args[n], XtNfromVert, NULL); n++;
+ XtSetArg(args[n], XtNtop, XtChainTop); n++;
+ XtSetArg(args[n], XtNright, XtChainRight); n++;
+ XtSetArg(args[n], XtNresizable, True); n++;
+ XtSetArg(args[n], XtNfont, textfont); n++; /* fontset would be better */
+ XtSetArg(args[n], XtNlabel, "Page: n/n"); n++;
+ XtSetArg(args[n], XtNjustify, XtJustifyRight); n++;
+ apd->content.pageheaderlabel = XtCreateManagedWidget("pageinfo", labelWidgetClass, apd->content.form, args, n);
+#endif /* PRINT_PAGEHEADER */
+
+ n = 0;
+ XtSetArg(args[n], XtNtype, XawAsciiFile); n++;
+ XtSetArg(args[n], XtNstring, viewFileName); n++;
+ XtSetArg(args[n], XtNscrollHorizontal, XawtextScrollNever); n++;
+ XtSetArg(args[n], XtNscrollVertical, XawtextScrollNever); n++;
+
+/* Usually I would expect that using |XtNfromVert, apd->content.pageheaderlabel|
+ * would be the correct way to place the text widget with the main content below
+ * the page header widget - but for an unknown reason this doesn not work: The
+ * text widget squishes itself into the bottom half of the page and only occupies
+ * 1/2 of the page's with... ;-(( */
+#define WORKAROUND_FOR_SOMETHING_IS_WRONG 1
+#ifdef WORKAROUND_FOR_SOMETHING_IS_WRONG
+ XtSetArg(args[n], XtNtop, XtChainTop); n++;
+ XtSetArg(args[n], XtNright, XtChainRight); n++;
+ XtSetArg(args[n], XtNvertDistance, (textfont->ascent+textfont->descent+2)*2); n++;
+#else
+ XtSetArg(args[n], XtNfromHoriz, NULL); n++;
+ XtSetArg(args[n], XtNfromVert, apd->content.pageheaderlabel); n++;
+#endif
+ XtSetArg(args[n], XtNfont, textfont); n++; /* fontset would be better */
+ apd->content.text = XtCreateManagedWidget("text", asciiTextWidgetClass, apd->content.form, args, n);
+ /* Disable the caret - that is not needed for printing */
+ XawTextDisplayCaret(apd->content.text, False);
+
+ XtAddCallback(apd->printshell, XawNpageSetupCallback, PageSetupCB, (XtPointer)apd);
+ XtAddCallback(apd->printshell, XawNendJobCallback, PrintEndJobCB, (XtPointer)apd);
+
+ /* Realise print shell (which will set position+size of the child
+ * widgets based on the current page size) */
+ XtRealizeWidget(apd->printshell);
+
+ /* Count number of pages in the text widget */
+ apd->numpages = CountPages(apd->content.text);
+
+ /* Make sure that the Xt machinery is really using the right screen (assertion) */
+ if (XpGetScreenOfContext(XtDisplay(apd->printshell), apd->pcontext) != XtScreen(apd->printshell))
+ Error(("Widget's screen != print screen. BAD.\n"));
+
+ apd->isPrinting = True;
+
+ if (toFile) {
+ printf("%s: Printing to file '%s'...\n", ProgramName, toFile);
+ apd->printtofile_handle = XpuStartJobToFile(pdpy, pcontext, toFile);
+ if (!apd->printtofile_handle) {
+ perror("XpuStartJobToFile failure");
+ apd->isPrinting = False;
+ return;
+ }
+ }
+ else
+ {
+ printf("%s: Printing to printer...\n", ProgramName);
+ XpuStartJobToSpooler(pdpy);
+ }
+}
+
+
diff --git a/print.h b/print.h
new file mode 100644
index 0000000..0dc94df
--- /dev/null
+++ b/print.h
@@ -0,0 +1,44 @@
+/*
+ * $Xorg: print.h,v 1.1 2004/04/30 02:05:54 gisburn Exp $
+ *
+Copyright 2004 Roland Mainz <roland.mainz@nrubsig.org>
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ */
+
+#ifndef XMORE_PRINT_H
+#define XMORE_PRINT_H 1
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Shell.h>
+#include <X11/Xaw/Print.h>
+#include <X11/Xaw/Cardinals.h>
+#include <X11/XprintUtil/xprintutil.h>
+
+/* Prototypes */
+void DoPrint(Widget toplevel,
+ Display *pdpy, XPContext pcontext,
+ const char *jobTitle,
+ const char *toFile);
+
+#endif /* !XMORE_PRINT_H */
diff --git a/printdialog.c b/printdialog.c
new file mode 100644
index 0000000..7c5eb60
--- /dev/null
+++ b/printdialog.c
@@ -0,0 +1,1375 @@
+/*
+ * $Xorg: printdialog.c,v 1.1 2004/05/12 02:05:54 gisburn Exp $
+ *
+Copyright 2004 Roland Mainz <roland.mainz@nrubsig.org>
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ */
+
+/* Force ANSI C prototypes from X11 headers */
+#ifndef FUNCPROTO
+#define FUNCPROTO 15
+#endif /* !FUNCPROTO */
+
+#include <X11/StringDefs.h>
+#include <X11/Intrinsic.h>
+#include <X11/Shell.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Toggle.h>
+#include <X11/Xaw/List.h>
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/AsciiText.h>
+#include <X11/Xaw/Dialog.h>
+
+#include "printdialog.h"
+#include "printdialogprivates.h"
+#include "print.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <stdio.h>
+
+/* Turn a NULL pointer string into an empty string */
+#define NULLSTR(x) (((x)!=NULL)?(x):(""))
+
+#define Error(x) { printf x ; exit(EXIT_FAILURE); }
+#define Assertion(expr, msg) { if (!(expr)) { Error msg } }
+#define Log(x) { if(True) printf x; }
+
+/* Local prototypes */
+static void do_beep(PrintDialogWidget pdw);
+static void center_popup(Widget parent, Widget popup);
+static void updateWidgetStates(PrintDialogWidget pdw);
+static void printSetupClose(PrintDialogWidget pdw);
+static void printSetupOKXtProc(Widget w, XtPointer client_data, XtPointer callData);
+static void printSetupCancelXtProc(Widget w, XtPointer client_data, XtPointer callData);
+static void printSetupJobCopiesXtProc(Widget w, XtPointer client_data, XtPointer callData);
+static void printDialogDestXtProc(Widget w, XtPointer client_data, XtPointer callData);
+static void printSelectFileXtProc(Widget w, XtPointer client_data, XtPointer callData);
+static void printOKXtProc(Widget w, XtPointer client_data, XtPointer callData);
+static void printSetupXtProc(Widget w, XtPointer client_data, XtPointer callData);
+static void printFileSelectedXtProc(Widget w, XtPointer client_data, XtPointer callData);
+static void buildFileDialog(PrintDialogWidget pdw);
+static void closePrinterConnection(PrintDialogWidget pdw);
+static Bool openPrinterConnection(PrintDialogWidget pdw);
+static void destroyPrintSetupDialog(PrintDialogWidget pdw);
+static Widget buildPrintSetupDialog(PrintDialogWidget pdw);
+static String *xpprinterlist_to_widget_printerlist(XPPrinterList printerlist, int num_printers);
+static String *xppaperlist_to_widget_paperlist(XpuMediumSourceSizeList paperlist, int num_papers);
+static String *xpresolutionlist_to_widget_resolutionlist(XpuResolutionList reslist, int num_resolutions);
+static String *xporientationlist_to_widget_orientationlist(XpuOrientationList orientationlist, int num_orientations);
+static String *xpplexlist_to_widget_plexlist(XpuPlexList plexlist, int num_plex);
+static void printerSelectionPrinterSelectedXtProc(Widget w, XtPointer client_data, XtPointer callData);
+static void printSelectPrinterXtProc(Widget w, XtPointer client_data, XtPointer callData);
+static void printerSelectionClose(PrintDialogWidget pdw);
+static void printerSelectionOKXtProc(Widget w, XtPointer client_data, XtPointer callData);
+static void printerSelectionCancelXtProc(Widget w, XtPointer client_data, XtPointer callData);
+static Bool buildPrinterSelectionDialog(PrintDialogWidget pdw);
+static void destroyPrinterSelectionDialog(PrintDialogWidget pdw);
+static void createprintdialogchildren(Widget w);
+
+static
+void do_beep(PrintDialogWidget pdw)
+{
+ Log(("*** Beep!\n"));
+}
+
+/* Center popup (on parent, not on screen - which would be a bad idea
+ * in the Xinerama case) */
+static
+void center_popup(Widget parent, Widget popup)
+{
+ Dimension width,
+ height;
+ Position x,
+ y;
+
+ XtVaGetValues(parent,
+ XtNx, &x,
+ XtNy, &y,
+ NULL);
+ XtVaGetValues(popup,
+ XtNwidth, &width,
+ XtNheight, &height,
+ NULL);
+
+ x += (Position)width / 2;
+ y += (Position)height / 3;
+
+ XtVaSetValues(popup,
+ XtNx, x,
+ XtNy, y,
+ NULL);
+}
+
+static
+void updateWidgetStates(PrintDialogWidget pdw)
+{
+ PrintDialogPart *pdp = &pdw->printdialog;
+
+ /* Do not update anything if we will be destroyed */
+ if (pdw->core.being_destroyed)
+ return;
+
+ if (pdp->printToFile == False) {
+ XtVaSetValues(pdp->main.printtoprinter, XtNstate, True, NULL);
+ XtVaSetValues(pdp->main.printtofile, XtNstate, False, NULL);
+ /* Disable the widgets which depend on print-to-file */
+ XtVaSetValues(pdp->main.filenamelabel, XtNsensitive, False, NULL);
+ XtVaSetValues(pdp->main.filename, XtNsensitive, False, NULL);
+ XtVaSetValues(pdp->main.selectfile, XtNsensitive, False, NULL);
+ }
+ else
+ {
+ XtVaSetValues(pdp->main.printtoprinter, XtNstate, False, NULL);
+ XtVaSetValues(pdp->main.printtofile, XtNstate, True, NULL);
+ /* Enable the widgets which depend on print-to-file */
+ XtVaSetValues(pdp->main.filenamelabel, XtNsensitive, True, NULL);
+ XtVaSetValues(pdp->main.filename, XtNsensitive, True, NULL);
+ XtVaSetValues(pdp->main.selectfile, XtNsensitive, True, NULL);
+ }
+
+ /* Update file name */
+ XtVaSetValues(pdp->main.filename, XtNlabel, pdp->filename?pdp->filename:"-", NULL);
+
+ /* General check whether we can print... */
+ pdp->canPrint = True;
+ if (pdp->printer_name == NULL) {
+ pdp->canPrint = False;
+ }
+ else if (strlen(pdp->printer_name) == 0) {
+ pdp->canPrint = False;
+ }
+
+ pdp->canReallyPrint = pdp->canPrint;
+
+ /* Some extra checks for print-to-file */
+ if (pdp->printToFile) {
+ if (pdp->filename == NULL) {
+ pdp->canReallyPrint = False;
+ }
+ else if (strlen(pdp->filename) == 0) {
+ pdp->canReallyPrint = False;
+ }
+ }
+
+ XtVaSetValues(pdp->main.ok, XtNsensitive, pdp->canReallyPrint, NULL);
+ XtVaSetValues(pdp->main.setup, XtNsensitive, pdp->canPrint, NULL);
+}
+
+static void
+printSetupClose(PrintDialogWidget pdw)
+{
+ PrintDialogPart *pdp = &pdw->printdialog;
+ if (pdp->setup.popup) {
+ XtPopdown(pdp->setup.popup);
+ }
+}
+
+static void
+printSetupOKXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ PrintDialogWidget pdw = (PrintDialogWidget)client_data;
+ PrintDialogPart *pdp = &pdw->printdialog;
+ char *s;
+ int c;
+ XawListReturnStruct *lrs;
+ Log(("## printSetupOK: closing print setup!\n"));
+
+ /* Set copy count (if the value is invalid beep and return to the user ) */
+ XtVaGetValues(pdp->setup.jobcopies, XtNstring, &s, NULL);
+ if (s) {
+ c = atoi(s);
+ if (c < 1 || c > 999) {
+ do_beep(pdw);
+ XtVaSetValues(pdp->setup.jobcopies, XtNstring, "1", NULL);
+ Log(("## printSetupOKXtProc: not a valid copy count value\n"));
+ return;
+ }
+
+ /* Fix me: We should set the number of _job_ copies here, not _doc_ copies */
+ XpuSetDocumentCopies(pdp->pdpy, pdp->pcontext, c);
+ }
+
+ /* Set paper size */
+ lrs = XawListShowCurrent(pdp->setup.paperlist);
+ if (lrs->list_index != XAW_LIST_NONE) {
+ Log(("selected paper is '%s'/'%d'\n", lrs->string, lrs->list_index));
+ Assertion(lrs->list_index < pdp->num_papers, (("Error: lrs->list_index < pdp->num_papers\n")));
+ XpuSetDocMediumSourceSize(pdp->pdpy, pdp->pcontext, &pdp->paperlist[lrs->list_index]);
+ }
+ XtFree((char *)lrs);
+
+ /* Set resolution */
+ lrs = XawListShowCurrent(pdp->setup.resolutionlist);
+ if (lrs->list_index != XAW_LIST_NONE) {
+ Log(("selected resolution is '%s'/'%d'\n", lrs->string, lrs->list_index));
+ Assertion(lrs->list_index < pdp->num_resolutions, (("Error: lrs->list_index < pdp->num_resolutions\n")));
+ XpuSetDocResolution(pdp->pdpy, pdp->pcontext, &pdp->resolutionlist[lrs->list_index]);
+ }
+ XtFree((char *)lrs);
+
+ /* Set orientation */
+ lrs = XawListShowCurrent(pdp->setup.orientationlist);
+ if (lrs->list_index != XAW_LIST_NONE) {
+ Log(("selected orientation is '%s'/'%d'\n", lrs->string, lrs->list_index));
+ Assertion(lrs->list_index < pdp->num_orientations, (("Error: lrs->list_index < pdp->num_orientations\n")));
+ XpuSetDocOrientation(pdp->pdpy, pdp->pcontext, &pdp->orientationlist[lrs->list_index]);
+ }
+ XtFree((char *)lrs);
+
+ /* Set plex mode */
+ lrs = XawListShowCurrent(pdp->setup.plexlist);
+ if (lrs->list_index != XAW_LIST_NONE) {
+ Log(("selected plex is '%s'/'%d'\n", lrs->string, lrs->list_index));
+ Assertion(lrs->list_index < pdp->num_plex, (("Error: lrs->list_index < pdp->num_plex\n")));
+ XpuSetDocPlex(pdp->pdpy, pdp->pcontext, &pdp->plexlist[lrs->list_index]);
+ }
+ XtFree((char *)lrs);
+
+ printSetupClose(pdw);
+}
+
+static void
+printSetupCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ PrintDialogWidget pdw = (PrintDialogWidget)client_data;
+ Log(("## printSetupCancel: closing print setup!\n"));
+
+ printSetupClose(pdw);
+}
+
+static void
+printSetupJobCopiesXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ PrintDialogWidget pdw = (PrintDialogWidget)client_data;
+ PrintDialogPart *pdp = &pdw->printdialog;
+ char *string = NULL;
+
+ Log(("## printSetupJobCopiesXtProc!\n"));
+
+ /* Check whether the input is a valid number - and in the case of invalid input reset the value */
+ XtVaGetValues(pdp->setup.jobcopies, XtNstring, &string, NULL);
+ if (string) {
+ char *s;
+ int c;
+ Bool isValidNumber = True;
+
+ /* First check for invalid characters... */
+ for( s = string ; (c = *s++) != '\0' ; s++ ) {
+ if (!isdigit(c)) {
+ isValidNumber = False;
+ break;
+ }
+ }
+
+ /* .. and the do a range check... */
+ c = atoi(string);
+ if (c < 1 || c > 999) {
+ isValidNumber = False;
+ }
+
+ if (!isValidNumber) {
+ do_beep(pdw);
+ XtVaSetValues(pdp->setup.jobcopies, XtNstring, "1", NULL);
+ Log(("## printSetupJobCopiesXtProc: not a valid number\n"));
+ }
+ }
+}
+
+static void
+printCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ PrintDialogWidget pdw = (PrintDialogWidget)client_data;
+ PrintDialogPart *pdp = &pdw->printdialog;
+
+ printSetupClose(pdw);
+
+ if (pdp->cancel_callback) {
+ Log(("printCancelXtProc: calling callback"));
+ XtCallCallbackList((Widget)pdw, pdp->cancel_callback, NULL);
+ }
+}
+
+static void
+printDialogDestXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ PrintDialogWidget pdw = (PrintDialogWidget)client_data;
+ PrintDialogPart *pdp = &pdw->printdialog;
+
+ if (w == pdp->main.printtoprinter) {
+ pdp->printToFile = False;
+ }
+ else if (w == pdp->main.printtofile) {
+ pdp->printToFile = True;
+ }
+ else
+ {
+ Log(("printDialogDestXtProc: ERROR: Unknown widget."));
+ }
+
+ updateWidgetStates(pdw);
+}
+
+static void
+printSelectFileXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ PrintDialogWidget pdw = (PrintDialogWidget)client_data;
+ PrintDialogPart *pdp = &pdw->printdialog;
+
+ Log(("## printSelectFileXtProc!\n"));
+
+ if (!pdp->selectFile.shell) {
+ buildFileDialog(pdw);
+ }
+
+ center_popup((Widget)pdw, pdp->selectFile.shell);
+
+ XtPopup(pdp->selectFile.shell, XtGrabExclusive);
+}
+
+static void
+printOKXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ PrintDialogWidget pdw = (PrintDialogWidget)client_data;
+ PrintDialogPart *pdp = &pdw->printdialog;
+ Log(("## printing!\n"));
+
+ if (!pdp->pdpy) {
+ Log(("printOKXtProc: no printer connection, opening one....\n"));
+ openPrinterConnection(pdw);
+
+ if (!pdp->pdpy) {
+ Log(("printOKXtProc: still no printer connection - BAD (this should never happen).\n"));
+ do_beep(pdw);
+ return;
+ }
+ }
+
+ if (pdp->ok_callback) {
+ XawPrintDialogCallbackStruct pdcs;
+
+ Log(("printOKXtProc: calling callbacks...\n"));
+ memset(&pdcs, 0, sizeof(pdcs));
+ pdcs.pdpy = pdp->pdpy;
+ pdcs.pcontext = pdp->pcontext;
+ pdcs.printToFile = pdp->printToFile;
+ pdcs.printToFileName = (const char *)pdp->filename;
+ XtCallCallbackList((Widget)pdw, pdp->ok_callback, &pdcs);
+ }
+
+ printSetupClose(pdw);
+}
+
+static void
+printSetupXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ PrintDialogWidget pdw = (PrintDialogWidget)client_data;
+ PrintDialogPart *pdp = &pdw->printdialog;
+
+ Log(("## setup!\n"));
+
+ if (!pdp->setup.popup) {
+ if (buildPrintSetupDialog(pdw) == NULL) {
+ Log(("printSetupXtProc: buildPrintSetupDialog failure.\n"));
+ return;
+ }
+ }
+
+ center_popup((Widget)pdw, pdp->setup.popup);
+
+ XtPopup(pdp->setup.popup, XtGrabExclusive);
+}
+
+static void
+printFileSelectedXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ PrintDialogWidget pdw = (PrintDialogWidget)client_data;
+ PrintDialogPart *pdp = &pdw->printdialog;
+ const char *filename;
+
+ Log(("printFileSelectedXtProc: User selected file.\n"));
+ filename = XawDialogGetValueString(pdp->selectFile.dialog);
+
+ if (pdp->filename)
+ free(pdp->filename);
+ pdp->filename = strdup(filename);
+
+ XtPopdown(pdp->selectFile.shell);
+
+ updateWidgetStates(pdw);
+}
+
+static
+void buildFileDialog(PrintDialogWidget pdw)
+{
+ PrintDialogPart *pdp = &pdw->printdialog;
+ int n;
+ Arg args[20];
+
+ pdp->selectFile.shell = XtCreatePopupShell("shell",
+ transientShellWidgetClass,
+ (Widget)pdw, NULL, 0);
+ n = 0;
+ XtSetArg(args[n], XtNvalue, pdp->filename?pdp->filename:""); n++;
+ XtSetArg(args[n], XtNlabel, "Select Filename:"); n++;
+ pdp->selectFile.dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
+ pdp->selectFile.shell, args, n);
+ XawDialogAddButton(pdp->selectFile.dialog, "Accept", printFileSelectedXtProc, pdw);
+
+ XtRealizeWidget(pdp->selectFile.shell);
+}
+
+static
+void closePrinterConnection(PrintDialogWidget pdw)
+{
+ PrintDialogPart *pdp = &pdw->printdialog;
+
+ Log(("# closePrinterConnection\n"));
+
+ destroyPrintSetupDialog(pdw);
+
+ if (pdp->paperlist) {
+ XpuFreeMediumSourceSizeList(pdp->paperlist);
+ pdp->paperlist = NULL;
+ }
+
+ if (pdp->widget_paperlist) {
+ free(pdp->widget_paperlist);
+ pdp->widget_paperlist = NULL;
+ }
+
+ if (pdp->resolutionlist) {
+ XpuFreeResolutionList(pdp->resolutionlist);
+ pdp->resolutionlist = NULL;
+ }
+
+ if (pdp->widget_resolutionlist) {
+ free(pdp->widget_resolutionlist);
+ pdp->widget_resolutionlist = NULL;
+ }
+
+
+ if (pdp->orientationlist) {
+ XpuFreeOrientationList(pdp->orientationlist);
+ pdp->orientationlist = NULL;
+ }
+
+ if (pdp->widget_orientationlist) {
+ free(pdp->widget_orientationlist);
+ pdp->widget_orientationlist = NULL;
+ }
+
+ if (pdp->plexlist) {
+ XpuFreePlexList(pdp->plexlist);
+ pdp->plexlist = NULL;
+ }
+
+ if (pdp->widget_plexlist) {
+ free(pdp->widget_plexlist);
+ pdp->widget_plexlist = NULL;
+ }
+
+ if (pdp->pdpy) {
+ XpuClosePrinterDisplay(pdp->pdpy, pdp->pcontext);
+ pdp->pdpy = NULL;
+ pdp->pcontext = None;
+ }
+
+ updateWidgetStates(pdw);
+}
+
+static
+Bool openPrinterConnection(PrintDialogWidget pdw)
+{
+ PrintDialogPart *pdp = &pdw->printdialog;
+
+ Log(("# openPrinterConnection\n"));
+
+ /* Close any outstanding connection first... */
+ closePrinterConnection(pdw);
+
+ if (!pdp->printer_name) {
+ Log(("# error: openPrinterConnection: No printer name.\n"));
+ return False;
+ }
+
+ if (XpuGetPrinter(pdp->printer_name, &pdp->pdpy, &pdp->pcontext) == False) {
+ Log(("openPrinterConnection: could not open printer.\n"));
+ return False;
+ }
+
+ pdp->paperlist = XpuGetMediumSourceSizeList(pdp->pdpy, pdp->pcontext, &pdp->num_papers);
+ pdp->resolutionlist = XpuGetResolutionList(pdp->pdpy, pdp->pcontext, &pdp->num_resolutions);
+ pdp->orientationlist = XpuGetOrientationList(pdp->pdpy, pdp->pcontext, &pdp->num_orientations);
+ pdp->plexlist = XpuGetPlexList(pdp->pdpy, pdp->pcontext, &pdp->num_plex);
+
+ pdp->widget_paperlist = xppaperlist_to_widget_paperlist(pdp->paperlist, pdp->num_papers);
+ pdp->widget_resolutionlist = xpresolutionlist_to_widget_resolutionlist(pdp->resolutionlist, pdp->num_resolutions);
+ pdp->widget_orientationlist = xporientationlist_to_widget_orientationlist(pdp->orientationlist, pdp->num_orientations);
+ pdp->widget_plexlist = xpplexlist_to_widget_plexlist(pdp->plexlist, pdp->num_plex);
+
+ updateWidgetStates(pdw);
+
+ return True;
+}
+
+#undef DEFAULT_WIDTH
+#define DEFAULT_WIDTH 120
+#undef DEFAULT_INFOLABEL_WIDTH
+#define DEFAULT_INFOLABEL_WIDTH 250
+
+static
+void destroyPrintSetupDialog(PrintDialogWidget pdw)
+{
+ PrintDialogPart *pdp = &pdw->printdialog;
+
+ if (pdp->setup.popup) {
+ XtDestroyWidget(pdp->setup.popup);
+ }
+
+ /* |XtDestroyWidget(pdp->setup.popup);| above will recursively destroy
+ * all children so we only have to reset the pointers here... */
+ pdp->setup.popup = NULL;
+ pdp->setup.form = NULL;
+ pdp->setup.paperlist = NULL;
+ pdp->setup.resolutionlist = NULL;
+ pdp->setup.orientationlist = NULL;
+ pdp->setup.plexlist = NULL;
+ pdp->setup.ok = NULL;
+ pdp->setup.cancel = NULL;
+}
+
+static
+Widget buildPrintSetupDialog(PrintDialogWidget pdw)
+{
+ PrintDialogPart *pdp = &pdw->printdialog;
+ int n;
+ Arg args[20];
+ Widget listform;
+ XpuSupportedFlags jobflags,
+ docflags;
+ Bool canChangeJobCopies,
+ canChangePaperSize,
+ canChangeResolution,
+ canChangeOrientation,
+ canChangePlex;
+
+ if (!pdp->pdpy) {
+ Log(("buildPrintSetupDialog: no printer connection, opening one....\n"));
+ openPrinterConnection(pdw);
+
+ if (!pdp->pdpy) {
+ Log(("buildPrintSetupDialog: still no printer connection - BAD.\n"));
+ do_beep(pdw);
+ return NULL;
+ }
+ }
+
+ /* Get flags which types of attributes can be modified */
+ jobflags = XpuGetSupportedDocAttributes(pdp->pdpy, pdp->pcontext);
+ docflags = XpuGetSupportedDocAttributes(pdp->pdpy, pdp->pcontext);
+ canChangeJobCopies = (jobflags & XPUATTRIBUTESUPPORTED_COPY_COUNT) == XPUATTRIBUTESUPPORTED_COPY_COUNT;
+ canChangePaperSize = (docflags & XPUATTRIBUTESUPPORTED_DEFAULT_MEDIUM) == XPUATTRIBUTESUPPORTED_DEFAULT_MEDIUM;
+ canChangeResolution = (docflags & XPUATTRIBUTESUPPORTED_DEFAULT_PRINTER_RESOLUTION) == XPUATTRIBUTESUPPORTED_DEFAULT_PRINTER_RESOLUTION;
+ canChangeOrientation = (docflags & XPUATTRIBUTESUPPORTED_CONTENT_ORIENTATION) == XPUATTRIBUTESUPPORTED_CONTENT_ORIENTATION;
+ canChangePlex = (docflags & XPUATTRIBUTESUPPORTED_PLEX) == XPUATTRIBUTESUPPORTED_PLEX;
+
+ n = 0;
+ XtSetArg(args[n], XtNallowShellResize, True); n++;
+ pdp->setup.popup = XtCreatePopupShell("popup", transientShellWidgetClass, (Widget)pdw, args, n);
+
+ n = 0;
+ pdp->setup.form = XtCreateManagedWidget("form", formWidgetClass, pdp->setup.popup, args, n);
+
+ n = 0;
+ listform = XtCreateManagedWidget("list", formWidgetClass, pdp->setup.form, args, n);
+
+ n = 0;
+ XtSetArg(args[n], XtNresizable, True); n++;
+ XtSetArg(args[n], XtNforceColumns, True); n++;
+ XtSetArg(args[n], XtNdefaultColumns, 1); n++;
+ XtSetArg(args[n], XtNfromHoriz, NULL); n++;
+ XtSetArg(args[n], XtNfromVert, NULL); n++;
+ XtSetArg(args[n], XtNsensitive, canChangePaperSize); n++;
+ XtSetArg(args[n], XtNlist, pdp->widget_paperlist); n++;
+ XtSetArg(args[n], XtNwidth, DEFAULT_WIDTH); n++;
+ pdp->setup.paperlist = XtCreateManagedWidget("paperlist", listWidgetClass, listform, args, n);
+
+ n = 0;
+ XtSetArg(args[n], XtNresizable, True); n++;
+ XtSetArg(args[n], XtNforceColumns, True); n++;
+ XtSetArg(args[n], XtNdefaultColumns, 1); n++;
+ XtSetArg(args[n], XtNfromHoriz, pdp->setup.paperlist); n++;
+ XtSetArg(args[n], XtNfromVert, NULL); n++;
+ XtSetArg(args[n], XtNsensitive, canChangeResolution); n++;
+ XtSetArg(args[n], XtNlist, pdp->widget_resolutionlist); n++;
+ XtSetArg(args[n], XtNwidth, DEFAULT_WIDTH); n++;
+ pdp->setup.resolutionlist = XtCreateManagedWidget("resolutionlist", listWidgetClass, listform, args, n);
+
+ n = 0;
+ XtSetArg(args[n], XtNresizable, True); n++;
+ XtSetArg(args[n], XtNforceColumns, True); n++;
+ XtSetArg(args[n], XtNdefaultColumns, 1); n++;
+ XtSetArg(args[n], XtNfromHoriz, pdp->setup.resolutionlist); n++;
+ XtSetArg(args[n], XtNfromVert, NULL); n++;
+ XtSetArg(args[n], XtNsensitive, canChangeOrientation); n++;
+ XtSetArg(args[n], XtNlist, pdp->widget_orientationlist); n++;
+ XtSetArg(args[n], XtNwidth, DEFAULT_WIDTH); n++;
+ pdp->setup.orientationlist = XtCreateManagedWidget("orientationlist", listWidgetClass, listform, args, n);
+
+ n = 0;
+ XtSetArg(args[n], XtNresizable, True); n++;
+ XtSetArg(args[n], XtNforceColumns, True); n++;
+ XtSetArg(args[n], XtNdefaultColumns, 1); n++;
+ XtSetArg(args[n], XtNfromHoriz, pdp->setup.orientationlist); n++;
+ XtSetArg(args[n], XtNfromVert, NULL); n++;
+ XtSetArg(args[n], XtNsensitive, canChangePlex); n++;
+ XtSetArg(args[n], XtNlist, pdp->widget_plexlist); n++;
+ XtSetArg(args[n], XtNwidth, DEFAULT_WIDTH); n++;
+ pdp->setup.plexlist = XtCreateManagedWidget("plexlist", listWidgetClass, listform, args, n);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, NULL); n++;
+ XtSetArg(args[n], XtNfromVert, pdp->setup.paperlist); n++;
+ XtSetArg(args[n], XtNborderWidth, 0); n++;
+ XtSetArg(args[n], XtNresizable, False); n++;
+ XtSetArg(args[n], XtNjustify, XtJustifyRight); n++;
+ XtSetArg(args[n], XtNwidth, DEFAULT_WIDTH); n++;
+ XtSetArg(args[n], XtNlabel, "Job Copies:"); n++;
+ XtSetArg(args[n], XtNsensitive, canChangeJobCopies); n++;
+ pdp->setup.jobcopieslabel = XtCreateManagedWidget("jobcopieslabel", labelWidgetClass, listform, args, n);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, pdp->setup.jobcopieslabel); n++;
+ XtSetArg(args[n], XtNfromVert, pdp->setup.paperlist); n++;
+ XtSetArg(args[n], XtNstring, "1"); n++;
+ XtSetArg(args[n], XtNresizable, True); n++;
+ XtSetArg(args[n], XtNeditType, XawtextEdit); n++;
+ XtSetArg(args[n], XtNsensitive, canChangeJobCopies); n++;
+ pdp->setup.jobcopies = XtCreateManagedWidget("jobcopies", asciiTextWidgetClass, listform, args, n);
+ XtAddCallback(pdp->setup.jobcopies, XtNpositionCallback, printSetupJobCopiesXtProc, pdw);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, NULL); n++;
+ XtSetArg(args[n], XtNfromVert, listform); n++;
+ XtSetArg(args[n], XtNlabel, "OK"); n++;
+ pdp->setup.ok = XtCreateManagedWidget("ok", commandWidgetClass, pdp->setup.form, args, n);
+ XtAddCallback(pdp->setup.ok, XtNcallback, printSetupOKXtProc, pdw);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, pdp->setup.ok); n++;
+ XtSetArg(args[n], XtNfromVert, listform); n++;
+ XtSetArg(args[n], XtNlabel, "Cancel"); n++;
+ pdp->setup.cancel = XtCreateManagedWidget("cancel", commandWidgetClass, pdp->setup.form, args, n);
+ XtAddCallback(pdp->setup.cancel, XtNcallback, printSetupCancelXtProc, pdw);
+
+ XtRealizeWidget(pdp->setup.popup);
+
+ return pdp->setup.popup;
+}
+
+#undef DEFAULT_WIDTH
+#define DEFAULT_WIDTH 150
+
+static
+String *xpprinterlist_to_widget_printerlist(XPPrinterList printerlist, int num_printers)
+{
+ int i;
+ String *names;
+
+ names = malloc(sizeof(String *) * (num_printers+1));
+ if(!names)
+ return NULL;
+
+ for(i = 0 ; i < num_printers ; i++)
+ names[i] = printerlist[i].name;
+
+ names[i] = NULL; /* Terminate the list */
+
+ return names;
+}
+
+static
+String *xppaperlist_to_widget_paperlist(XpuMediumSourceSizeList paperlist, int num_papers)
+{
+ int i;
+ String *names;
+
+ names = malloc(sizeof(String *) * (num_papers+1));
+ if (!names)
+ return NULL;
+
+ for(i = 0 ; i < num_papers ; i++)
+ names[i] = (char *)paperlist[i].medium_name; /* FixMe: tray selection missing */
+
+ names[i] = NULL; /* Terminate the list */
+
+ return names;
+}
+
+static
+String *xpresolutionlist_to_widget_resolutionlist(XpuResolutionList reslist, int num_resolutions)
+{
+ int i;
+ String *names;
+ char *mem;
+
+ /* Allocate a chunk of memory... */
+ mem = malloc((sizeof(String *)+32) * (num_resolutions+2));
+
+ /* ... which has enougth space for the list pointers... */
+ names = (String *)mem;
+ if (!names)
+ return NULL;
+
+ /* ... and the numbers (assuming one number isn't longer than 32-1 chars) */
+ mem += sizeof(String *) * (num_resolutions+2);
+
+ for(i = 0 ; i < num_resolutions ; i++) {
+ sprintf(mem, "%d", (int)reslist[i].dpi);
+ names[i] = mem;
+ mem += strlen(mem) + 1;
+ }
+
+ names[i] = NULL; /* Terminate the list */
+
+ return names;
+}
+
+static
+String *xporientationlist_to_widget_orientationlist(XpuOrientationList orientationlist, int num_orientations)
+{
+ int i;
+ String *names;
+
+ names = malloc(sizeof(String *) * (num_orientations+1));
+ if (!names)
+ return NULL;
+
+ for(i = 0 ; i < num_orientations ; i++)
+ names[i] = (char *)orientationlist[i].orientation;
+
+ names[i] = NULL; /* Terminate the list */
+
+ return names;
+}
+
+static
+String *xpplexlist_to_widget_plexlist(XpuPlexList plexlist, int num_plex)
+{
+ int i;
+ String *names;
+
+ names = malloc(sizeof(String *) * (num_plex+1));
+ if(!names)
+ return NULL;
+
+ for(i = 0 ; i < num_plex ; i++)
+ names[i] = (char *)plexlist[i].plex;
+
+ names[i] = NULL; /* Terminate the list */
+
+ return names;
+}
+
+static void
+printerSelectionPrinterSelectedXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ PrintDialogWidget pdw = (PrintDialogWidget)client_data;
+ PrintDialogPart *pdp = &pdw->printdialog;
+ XawListReturnStruct *lrs = (XawListReturnStruct *)callData;
+ int list_index;
+
+ Log(("## user selected a printer\n"));
+
+ list_index = lrs->list_index;
+ if (list_index == XAW_LIST_NONE) {
+ Log(("printerSelectionPrinterSelectedXtProc: Nothing selected."));
+ return;
+ }
+
+ Log(("selected printer is '%d'/'%s'/'%s'\n",
+ list_index, lrs->string, NULLSTR(pdp->printerlist[list_index].name)));
+
+ /* Enable OK button */
+ XtVaSetValues(pdp->selectPrinter.ok, XtNsensitive, True, NULL);
+}
+
+static void
+printSelectPrinterXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ PrintDialogWidget pdw = (PrintDialogWidget)client_data;
+ PrintDialogPart *pdp = &pdw->printdialog;
+
+ Log(("## select printer!\n"));
+
+ if (!pdp->selectPrinter.popup) {
+ if (!buildPrinterSelectionDialog(pdw)) {
+ Log(("printSelectPrinterXtProc: buildPrinterSelectionDialog failure.\n"));
+ return;
+ }
+ }
+
+ center_popup((Widget)pdw, pdp->selectPrinter.popup);
+
+ XtPopup(pdp->selectPrinter.popup, XtGrabExclusive);
+}
+
+static void
+printerSelectionClose(PrintDialogWidget pdw)
+{
+ PrintDialogPart *pdp = &pdw->printdialog;
+
+ if (pdp->selectPrinter.popup) {
+ XtPopdown(pdp->selectPrinter.popup);
+ }
+}
+
+static void
+printerSelectionOKXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ PrintDialogWidget pdw = (PrintDialogWidget)client_data;
+ PrintDialogPart *pdp = &pdw->printdialog;
+ XawListReturnStruct *lrs;
+ int list_index;
+
+ Log(("## printerSelectionOKXtProc: closing printer selection!\n"));
+
+ /* Copy current selection in printer list widget and open a printer connection */
+ lrs = XawListShowCurrent(pdp->selectPrinter.list);
+ if (!lrs) {
+ Log(("printerSelectionOKXtProc: |lrs|==NULL\n"));
+ return;
+ }
+
+ list_index = lrs->list_index;
+ if (lrs->list_index == XAW_LIST_NONE) {
+ Log(("printerSelectionOKXtProc: rs->list_index == XAW_LIST_NONE\n"));
+ XtFree((char *)lrs);
+ return;
+ }
+
+ /* Set printer name and description in main dialog */
+ XtVaSetValues(pdp->main.name, XtNlabel, NULLSTR(pdp->printerlist[list_index].name), NULL);
+ XtVaSetValues(pdp->main.desc, XtNlabel, NULLSTR(pdp->printerlist[list_index].desc), NULL);
+
+ if (pdp->printer_name)
+ free(pdp->printer_name);
+ pdp->printer_name = strdup(lrs->string);
+
+ /* Close any outstanding printer connection since user has selected
+ * a different printer */
+ closePrinterConnection(pdw);
+
+ printerSelectionClose(pdw);
+
+ XtFree((char *)lrs);
+}
+
+static void
+printerSelectionCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ PrintDialogWidget pdw = (PrintDialogWidget)client_data;
+ Log(("## printerSelectionCancelXtProc: closing printer selection!\n"));
+
+ printerSelectionClose(pdw);
+}
+
+static
+Bool buildPrinterSelectionDialog(PrintDialogWidget pdw)
+{
+ PrintDialogPart *pdp = &pdw->printdialog;
+
+ int n;
+ Arg args[20];
+
+ n = 0;
+ XtSetArg(args[n], XtNallowShellResize, True); n++;
+ pdp->selectPrinter.popup = XtCreatePopupShell("popup", transientShellWidgetClass, (Widget)pdw, args, n);
+
+ n = 0;
+ pdp->selectPrinter.form = XtCreateManagedWidget("form", formWidgetClass, pdp->selectPrinter.popup, args, n);
+
+ n = 0;
+ XtSetArg(args[n], XtNresizable, True); n++;
+ XtSetArg(args[n], XtNforceColumns, True); n++;
+ XtSetArg(args[n], XtNdefaultColumns, 1); n++;
+ XtSetArg(args[n], XtNfromHoriz, NULL); n++;
+ XtSetArg(args[n], XtNfromVert, NULL); n++;
+ XtSetArg(args[n], XtNlist, pdp->widget_printerlist); n++;
+ XtSetArg(args[n], XtNwidth, DEFAULT_WIDTH); n++;
+ pdp->selectPrinter.list = XtCreateManagedWidget("list", listWidgetClass, pdp->selectPrinter.form, args, n);
+ XtAddCallback(pdp->selectPrinter.list, XtNcallback, printerSelectionPrinterSelectedXtProc, pdw);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, NULL); n++;
+ XtSetArg(args[n], XtNfromVert, pdp->selectPrinter.list); n++;
+ XtSetArg(args[n], XtNlabel, "OK"); n++;
+ XtSetArg(args[n], XtNsensitive, False); n++;
+ pdp->selectPrinter.ok = XtCreateManagedWidget("ok", commandWidgetClass, pdp->selectPrinter.form, args, n);
+ XtAddCallback(pdp->selectPrinter.ok, XtNcallback, printerSelectionOKXtProc, pdw);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, pdp->selectPrinter.ok); n++;
+ XtSetArg(args[n], XtNfromVert, pdp->selectPrinter.list); n++;
+ XtSetArg(args[n], XtNlabel, "Cancel"); n++;
+ pdp->selectPrinter.cancel = XtCreateManagedWidget("cancel", commandWidgetClass, pdp->selectPrinter.form, args, n);
+ XtAddCallback(pdp->selectPrinter.cancel, XtNcallback, printerSelectionCancelXtProc, pdw);
+
+ XtRealizeWidget(pdp->selectPrinter.popup);
+
+ return True;
+}
+
+static
+void destroyPrinterSelectionDialog(PrintDialogWidget pdw)
+{
+ PrintDialogPart *pdp = &pdw->printdialog;
+
+ if (pdp->selectPrinter.popup) {
+ XtDestroyWidget(pdp->selectPrinter.popup);
+ }
+
+ /* |XtDestroyWidget(pdp->setup.popup);| above will recursively destroy
+ * all children so we only have to reset the pointers here... */
+ pdp->selectPrinter.popup = NULL;
+ pdp->selectPrinter.form = NULL;
+ pdp->selectPrinter.list = NULL;
+ pdp->selectPrinter.popup = NULL;
+ pdp->selectPrinter.cancel = NULL;
+}
+
+/*
+ * Function:
+ * createprintdialogchildren
+ *
+ * Parameters:
+ * w - print dialog widget
+ *
+ * Description:
+ * Creates the print dialog widgets.
+ *
+ * Note
+ * -
+ */
+static void
+createprintdialogchildren(Widget w)
+{
+ int n;
+ Arg args[20];
+ PrintDialogWidget pdw = (PrintDialogWidget)w;
+ PrintDialogPart *pdp = &pdw->printdialog;
+ const char *default_printername = NULL,
+ *default_printerdesc = NULL;
+ Bool has_default_printer = False;
+
+ pdp->printerlist = XpuGetPrinterList(NULL, &pdp->num_printers);
+ pdp->widget_printerlist = xpprinterlist_to_widget_printerlist(pdp->printerlist, pdp->num_printers);
+
+ if (pdp->num_printers > 0) {
+ if (pdp->printerlist[0].name && strlen(pdp->printerlist[0].name)) {
+ /* XprintUtils moves the default printer to the top */
+ default_printername = pdp->printerlist[0].name;
+ default_printerdesc = pdp->printerlist[0].desc;
+ pdp->printer_name = strdup(pdp->printerlist[0].name);
+ has_default_printer = True;
+ }
+ }
+
+ n = 0;
+ XtSetArg(args[n], XtNborderWidth, 0); n++;
+ pdp->main.form = XtCreateManagedWidget("form", formWidgetClass, (Widget)pdw, args, n);
+
+ n = 0;
+ pdp->main.innerform = XtCreateManagedWidget("innerform", formWidgetClass, pdp->main.form, args, n);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, NULL); n++;
+ XtSetArg(args[n], XtNfromVert, NULL); n++;
+ XtSetArg(args[n], XtNborderWidth, 0); n++;
+ XtSetArg(args[n], XtNresizable, False); n++;
+ XtSetArg(args[n], XtNjustify, XtJustifyRight); n++;
+ XtSetArg(args[n], XtNwidth, DEFAULT_WIDTH); n++;
+ XtSetArg(args[n], XtNlabel, "Printer Description:"); n++;
+ pdp->main.desclabel = XtCreateManagedWidget("desclabel", labelWidgetClass, pdp->main.innerform, args, n);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, pdp->main.desclabel); n++;
+ XtSetArg(args[n], XtNfromVert, NULL); n++;
+ XtSetArg(args[n], XtNborderWidth, 0); n++;
+ XtSetArg(args[n], XtNresizable, False); n++;
+ XtSetArg(args[n], XtNjustify, XtJustifyLeft); n++;
+ XtSetArg(args[n], XtNwidth, DEFAULT_INFOLABEL_WIDTH); n++;
+ XtSetArg(args[n], XtNlabel, default_printerdesc?default_printerdesc:"-"); n++;
+ pdp->main.desc = XtCreateManagedWidget("desc", labelWidgetClass, pdp->main.innerform, args, n);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, pdp->main.desc); n++;
+ XtSetArg(args[n], XtNfromVert, NULL); n++;
+ XtSetArg(args[n], XtNsensitive, has_default_printer); n++;
+ XtSetArg(args[n], XtNlabel, "Printer info..."); n++;
+ pdp->main.info = XtCreateManagedWidget("info", commandWidgetClass, pdp->main.innerform, args, n);
+ /*
+ XtAddCallback(pdp->main.info, XtNcallback, printerInfoXtProc, pdw);
+ */
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, NULL); n++;
+ XtSetArg(args[n], XtNfromVert, pdp->main.desclabel); n++;
+ XtSetArg(args[n], XtNborderWidth, 0); n++;
+ XtSetArg(args[n], XtNresizable, False); n++;
+ XtSetArg(args[n], XtNjustify, XtJustifyRight); n++;
+ XtSetArg(args[n], XtNwidth, DEFAULT_WIDTH); n++;
+ XtSetArg(args[n], XtNlabel, "Printer Name:"); n++;
+ pdp->main.namelabel = XtCreateManagedWidget("namelabel", labelWidgetClass, pdp->main.innerform, args, n);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, pdp->main.namelabel); n++;
+ XtSetArg(args[n], XtNfromVert, pdp->main.desclabel); n++;
+ XtSetArg(args[n], XtNborderWidth, 0); n++;
+ XtSetArg(args[n], XtNresizable, False); n++;
+ XtSetArg(args[n], XtNjustify, XtJustifyLeft); n++;
+ XtSetArg(args[n], XtNlabel, default_printername?default_printername:"-"); n++;
+ XtSetArg(args[n], XtNwidth, DEFAULT_INFOLABEL_WIDTH); n++;
+ pdp->main.name = XtCreateManagedWidget("name", labelWidgetClass, pdp->main.innerform, args, n);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, pdp->main.name); n++;
+ XtSetArg(args[n], XtNfromVert, pdp->main.desclabel); n++;
+ XtSetArg(args[n], XtNlabel, "Select Printer..."); n++;
+ pdp->main.selectprinter = XtCreateManagedWidget("selectprinter", commandWidgetClass, pdp->main.innerform, args, n);
+ XtAddCallback(pdp->main.selectprinter, XtNcallback, printSelectPrinterXtProc, pdw);
+
+ /* Line: "File selection" */
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, NULL); n++;
+ XtSetArg(args[n], XtNfromVert, pdp->main.namelabel); n++;
+ XtSetArg(args[n], XtNborderWidth, 0); n++;
+ XtSetArg(args[n], XtNresizable, False); n++;
+ XtSetArg(args[n], XtNjustify, XtJustifyRight); n++;
+ XtSetArg(args[n], XtNwidth, DEFAULT_WIDTH); n++;
+ XtSetArg(args[n], XtNlabel, "File Name:"); n++;
+ XtSetArg(args[n], XtNsensitive, False); n++;
+ pdp->main.filenamelabel = XtCreateManagedWidget("filenamelabel", labelWidgetClass, pdp->main.innerform, args, n);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, pdp->main.filenamelabel); n++;
+ XtSetArg(args[n], XtNfromVert, pdp->main.namelabel); n++;
+ XtSetArg(args[n], XtNborderWidth, 0); n++;
+ XtSetArg(args[n], XtNresizable, False); n++;
+ XtSetArg(args[n], XtNjustify, XtJustifyLeft); n++;
+ XtSetArg(args[n], XtNlabel, "-"); n++;
+ XtSetArg(args[n], XtNwidth, DEFAULT_INFOLABEL_WIDTH); n++;
+ XtSetArg(args[n], XtNsensitive, False); n++;
+ pdp->main.filename = XtCreateManagedWidget("filename", labelWidgetClass, pdp->main.innerform, args, n);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, pdp->main.filename); n++;
+ XtSetArg(args[n], XtNfromVert, pdp->main.namelabel); n++;
+ XtSetArg(args[n], XtNsensitive, False); n++;
+ XtSetArg(args[n], XtNlabel, "Select File..."); n++;
+ pdp->main.selectfile = XtCreateManagedWidget("selectfile", commandWidgetClass, pdp->main.innerform, args, n);
+ XtAddCallback(pdp->main.selectfile, XtNcallback, printSelectFileXtProc, pdw);
+
+ /* Line: Misc (Print destination toggles, copy-count etc.)*/
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, NULL); n++;
+ XtSetArg(args[n], XtNfromVert, pdp->main.filenamelabel); n++;
+ XtSetArg(args[n], XtNlabel, "Print to Printer"); n++;
+ XtSetArg(args[n], XtNstate, True); n++;
+ pdp->main.printtoprinter = XtCreateManagedWidget("printtoprinter", toggleWidgetClass, pdp->main.innerform, args, n);
+ XtAddCallback(pdp->main.printtoprinter, XtNcallback, printDialogDestXtProc, pdw);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, pdp->main.printtoprinter); n++;
+ XtSetArg(args[n], XtNfromVert, pdp->main.filenamelabel); n++;
+ XtSetArg(args[n], XtNlabel, "Print to File"); n++;
+ XtSetArg(args[n], XtNstate, False); n++;
+ pdp->main.printtofile = XtCreateManagedWidget("printtofile", toggleWidgetClass, pdp->main.innerform, args, n);
+ XtAddCallback(pdp->main.printtofile, XtNcallback, printDialogDestXtProc, pdw);
+
+ /* End-of-Inner-Form-Content */
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, NULL); n++;
+ XtSetArg(args[n], XtNfromVert, pdp->main.innerform); n++;
+ XtSetArg(args[n], XtNlabel, "Print"); n++;
+ XtSetArg(args[n], XtNsensitive, has_default_printer); n++;
+ pdp->main.ok = XtCreateManagedWidget("ok", commandWidgetClass, pdp->main.form, args, n);
+ XtAddCallback(pdp->main.ok, XtNcallback, printOKXtProc, pdw);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, pdp->main.ok); n++;
+ XtSetArg(args[n], XtNfromVert, pdp->main.innerform); n++;
+ XtSetArg(args[n], XtNlabel, "Setup..."); n++;
+ XtSetArg(args[n], XtNsensitive, has_default_printer); n++;
+ pdp->main.setup = XtCreateManagedWidget("setup", commandWidgetClass, pdp->main.form, args, n);
+ XtAddCallback(pdp->main.setup, XtNcallback, printSetupXtProc, pdw);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, pdp->main.setup); n++;
+ XtSetArg(args[n], XtNfromVert, pdp->main.innerform); n++;
+ XtSetArg(args[n], XtNlabel, "Cancel"); n++;
+ pdp->main.cancel = XtCreateManagedWidget("cancel", commandWidgetClass, pdp->main.form, args, n);
+ XtAddCallback(pdp->main.cancel, XtNcallback, printCancelXtProc, pdw);
+}
+
+/*
+ * Class Methods
+ */
+static void XawPrintDialogConstraintInitialize(Widget, Widget, ArgList, Cardinal *);
+static void XawPrintDialogGetValuesHook(Widget, ArgList, Cardinal*);
+static void XawPrintDialogInitialize(Widget, Widget, ArgList, Cardinal*);
+static void XawPrintDialogDestroy(Widget);
+static Boolean XawPrintDialogSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
+
+/*
+ * Initialization
+ */
+static XtResource resources[] = {
+ {
+ XtNicon,
+ XtCIcon,
+ XtRBitmap,
+ sizeof(Pixmap),
+ XtOffsetOf(PrintDialogRec, printdialog.icon),
+ XtRImmediate,
+ 0
+ },
+ {
+ XawNOkCallback, XtCCallback, XtRCallback,
+ sizeof(XtCallbackList), XtOffsetOf(PrintDialogRec, printdialog.ok_callback),
+ XtRImmediate, (XtPointer)NULL
+ },
+ {
+ XawNCancelCallback, XtCCallback, XtRCallback,
+ sizeof(XtCallbackList), XtOffsetOf(PrintDialogRec, printdialog.cancel_callback),
+ XtRImmediate, (XtPointer)NULL
+ },
+};
+
+PrintDialogClassRec printdialogClassRec = {
+ /* core */
+ {
+ (WidgetClass)&formClassRec, /* superclass */
+ "PrintDialog", /* class_name */
+ sizeof(PrintDialogRec), /* widget_size */
+ XawInitializeWidgetSet, /* class_initialize */
+ NULL, /* class_part init */
+ False, /* class_inited */
+ XawPrintDialogInitialize, /* initialize */
+ NULL, /* initialize_hook */
+ XtInheritRealize, /* realize */
+ NULL, /* actions */
+ 0, /* num_actions */
+ resources, /* resources */
+ XtNumber(resources), /* num_resources */
+ NULLQUARK, /* xrm_class */
+ True, /* compress_motion */
+ True, /* compress_exposure */
+ True, /* compress_enterleave */
+ False, /* visible_interest */
+ XawPrintDialogDestroy, /* destroy */
+ XtInheritResize, /* resize */
+ XtInheritExpose, /* expose */
+ XawPrintDialogSetValues, /* set_values */
+ NULL, /* set_values_hook */
+ XtInheritSetValuesAlmost, /* set_values_almost */
+ XawPrintDialogGetValuesHook, /* get_values_hook */
+ NULL, /* accept_focus */
+ XtVersion, /* version */
+ NULL, /* callback_private */
+ NULL, /* tm_table */
+ XtInheritQueryGeometry, /* query_geometry */
+ XtInheritDisplayAccelerator, /* display_accelerator */
+ NULL, /* extension */
+ },
+ /* composite */
+ {
+ XtInheritGeometryManager, /* geometry_manager */
+ XtInheritChangeManaged, /* change_managed */
+ XtInheritInsertChild, /* insert_child */
+ XtInheritDeleteChild, /* delete_child */
+ NULL, /* extension */
+ },
+ /* constraint */
+ {
+ NULL, /* subresourses */
+ 0, /* subresource_count */
+ sizeof(PrintDialogConstraintsRec), /* constraint_size */
+ XawPrintDialogConstraintInitialize, /* initialize */
+ NULL, /* destroy */
+ NULL, /* set_values */
+ NULL, /* extension */
+ },
+ /* form */
+ {
+ XtInheritLayout, /* layout */
+ },
+ /* printdialog */
+ {
+ NULL, /* extension */
+ }
+};
+
+WidgetClass printDialogWidgetClass = (WidgetClass)&printdialogClassRec;
+
+/*
+ * Implementation
+ */
+/*ARGSUSED*/
+static void
+XawPrintDialogInitialize(Widget request, Widget cnew, ArgList args, Cardinal *num_args)
+{
+ PrintDialogWidget dw = (PrintDialogWidget)cnew;
+ Arg arglist[9];
+ Cardinal arg_cnt = 0;
+
+ XtSetArg(arglist[arg_cnt], XtNborderWidth, 0); arg_cnt++;
+ XtSetArg(arglist[arg_cnt], XtNleft, XtChainLeft); arg_cnt++;
+
+ if (dw->printdialog.icon != (Pixmap)0) {
+ XtSetArg(arglist[arg_cnt], XtNbitmap, dw->printdialog.icon); arg_cnt++;
+ XtSetArg(arglist[arg_cnt], XtNright, XtChainLeft); arg_cnt++;
+ dw->printdialog.iconW = XtCreateManagedWidget("icon", labelWidgetClass,
+ cnew, arglist, arg_cnt);
+ arg_cnt = 2;
+ XtSetArg(arglist[arg_cnt], XtNfromHoriz, dw->printdialog.iconW); arg_cnt++;
+ }
+ else {
+ dw->printdialog.iconW = NULL;
+ }
+
+ createprintdialogchildren((Widget)dw);
+}
+
+/*ARGSUSED*/
+static void
+XawPrintDialogConstraintInitialize(Widget request, Widget cnew,
+ ArgList args, Cardinal *num_args)
+{
+ PrintDialogWidget dw = (PrintDialogWidget)cnew->core.parent;
+ PrintDialogConstraints constraint = (PrintDialogConstraints)cnew->core.constraints;
+
+ if (!XtIsSubclass(cnew, commandWidgetClass)) /* if not a button */
+ return; /* then just use defaults */
+
+ constraint->form.left = constraint->form.right = XtChainLeft;
+ constraint->form.vert_base = dw->printdialog.main.form;
+
+ if (dw->composite.num_children > 1) {
+ WidgetList children = dw->composite.children;
+ Widget *childP;
+
+ for (childP = children + dw->composite.num_children - 1;
+ childP >= children; childP-- ) {
+ if (*childP == dw->printdialog.main.form)
+ break;
+ if (XtIsManaged(*childP) &&
+ XtIsSubclass(*childP, commandWidgetClass)) {
+ constraint->form.horiz_base = *childP;
+ break;
+ }
+ }
+ }
+}
+
+#define ICON 0
+#define NUM_CHECKS 1
+/*ARGSUSED*/
+static Boolean
+XawPrintDialogSetValues(Widget current, Widget request, Widget cnew,
+ ArgList in_args, Cardinal *in_num_args)
+{
+ PrintDialogWidget w = (PrintDialogWidget)cnew;
+ PrintDialogWidget old = (PrintDialogWidget)current;
+ Arg args[5];
+ unsigned int i;
+ Bool checks[NUM_CHECKS];
+
+ for (i = 0; i < NUM_CHECKS; i++)
+ checks[i] = False;
+
+ for (i = 0; i < *in_num_args; i++) {
+ if (!strcmp(XtNicon, in_args[i].name))
+ checks[ICON] = True;
+ }
+
+ if (checks[ICON]) {
+ if (w->printdialog.icon != 0) {
+ XtSetArg(args[0], XtNbitmap, w->printdialog.icon);
+ if (old->printdialog.iconW != NULL) {
+ XtSetValues(old->printdialog.iconW, args, 1);
+ }
+ else {
+ XtSetArg(args[1], XtNborderWidth, 0);
+ XtSetArg(args[2], XtNleft, XtChainLeft);
+ XtSetArg(args[3], XtNright, XtChainLeft);
+ w->printdialog.iconW = XtCreateWidget("icon", labelWidgetClass,
+ cnew, args, 4);
+ XtManageChild(w->printdialog.iconW);
+ }
+ }
+ else if (old->printdialog.icon != 0) {
+ XtDestroyWidget(old->printdialog.iconW);
+ w->printdialog.iconW = NULL;
+ }
+ }
+
+ return True;
+}
+
+/*
+ * Function:
+ * XawPrintDialogGetValuesHook
+ *
+ * Parameters:
+ * w - Print Dialog Widget
+ * args - argument list
+ * num_args - number of args
+ *
+ * Description:
+ * This is a get values hook routine that gets the values in the dialog.
+ */
+static void
+XawPrintDialogGetValuesHook(Widget w, ArgList args, Cardinal *num_args)
+{
+ /* NO-OP for now */
+}
+
+static void
+XawPrintDialogDestroy(Widget w)
+{
+ PrintDialogWidget pdw = (PrintDialogWidget)w;
+ Log(("# XawPrintDialogDestroy: start.\n"));
+
+ destroyPrintSetupDialog(pdw);
+ destroyPrinterSelectionDialog(pdw);
+ closePrinterConnection(pdw);
+
+ Log(("# XawPrintDialogDestroy: done.\n"));
+}
+
+
+
+
diff --git a/printdialog.h b/printdialog.h
new file mode 100644
index 0000000..7ac8e48
--- /dev/null
+++ b/printdialog.h
@@ -0,0 +1,84 @@
+/*
+ * $Xorg: printdialog.h,v 1.1 2004/04/30 02:05:54 gisburn Exp $
+ *
+Copyright 2004 Roland Mainz <roland.mainz@nrubsig.org>
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ */
+
+#ifndef XMORE_PRINTDIALOG_H
+#define XMORE_PRINTDIALOG_H 1
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Shell.h>
+#include <X11/Xaw/Print.h>
+#include <X11/Xaw/Cardinals.h>
+#include <X11/Xaw/Form.h>
+#include <X11/XprintUtil/xprintutil.h>
+
+/* Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ background Background Pixel XtDefaultBackground
+ borderColor BorderColor Pixel XtDefaultForeground
+ borderWidth BorderWidth Dimension 1
+ destroyCallback Callback Pointer NULL
+ height Height Dimension computed at create
+ icon Icon Pixmap 0
+ label Label String NULL
+ mappedWhenManaged MappedWhenManaged Boolean True
+ sensitive Sensitive Boolean True
+ value Value String NULL
+ width Width Dimension computed at create
+ x Position Position 0
+ y Position Position 0
+
+*/
+
+#define XtCIcon "Icon"
+#define XtNicon "icon"
+
+#define XawNOkCallback "XawNOkCallback"
+#define XawNCancelCallback "XawNCancelCallback"
+
+typedef struct
+{
+ Display *pdpy;
+ XPContext pcontext;
+ const char *printToFileName;
+ Boolean printToFile;
+} XawPrintDialogCallbackStruct;
+
+typedef struct _PrintDialogClassRec *PrintDialogWidgetClass;
+typedef struct _PrintDialogRec *PrintDialogWidget;
+
+extern WidgetClass printDialogWidgetClass;
+
+_XFUNCPROTOBEGIN
+
+/* Prototypes */
+
+_XFUNCPROTOEND
+
+#endif /* _XawDialog_h */
diff --git a/printdialogprivates.h b/printdialogprivates.h
new file mode 100644
index 0000000..314a91c
--- /dev/null
+++ b/printdialogprivates.h
@@ -0,0 +1,176 @@
+/*
+ * $Xorg: printdialogprivates.h,v 1.1 2004/05/12 02:05:54 gisburn Exp $
+ *
+Copyright 2004 Roland Mainz <roland.mainz@nrubsig.org>
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ */
+
+#ifndef _XawPrintDialogP_h
+#define _XawPrintDialogP_h 1
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xos.h>
+#include <X11/Xmu/Misc.h>
+#include <X11/CoreP.h>
+#include <X11/Xaw/AsciiText.h>
+#include <X11/Xaw/Cardinals.h>
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/DialogP.h>
+#include <X11/Xaw/XawInit.h>
+#include <X11/Xaw/Dialog.h>
+#include <X11/Xaw/FormP.h>
+
+/* From Xaw/Privates.h */
+#ifndef XtWidth
+#define XtWidth(w) (((RectObj)w)->rectangle.width)
+#endif
+#ifndef XtHeight
+#define XtHeight(w) (((RectObj)w)->rectangle.height)
+#endif
+
+
+typedef struct {
+ XtPointer extension;
+} PrintDialogClassPart;
+
+typedef struct _PrintDialogClassRec {
+ CoreClassPart core_class;
+ CompositeClassPart composite_class;
+ ConstraintClassPart constraint_class;
+ FormClassPart form_class;
+ PrintDialogClassPart print_dialog_class;
+} PrintDialogClassRec;
+
+extern PrintDialogClassRec printDialogClassRec;
+
+typedef struct _PrintDialogPart {
+ /* resources */
+ String label; /* description of the dialog */
+ String value; /* for the user response */
+ Pixmap icon; /* icon bitmap */
+ XtCallbackList ok_callback,
+ cancel_callback;
+
+ /* private */
+ Widget iconW; /* widget to display the icon */
+
+ struct
+ {
+ Widget form,
+ innerform,
+ desclabel,
+ desc,
+ info,
+ namelabel,
+ name,
+ selectprinter,
+ filenamelabel,
+ filename,
+ selectfile,
+ printtoprinter,
+ printtofile,
+ ok,
+ setup,
+ cancel;
+ } main;
+
+ Bool printToFile;
+ char *filename;
+ Bool canPrint, /* can we print ? */
+ canReallyPrint; /* is it really save to print ? */
+
+ struct
+ {
+ Widget popup,
+ form,
+ list,
+ ok,
+ cancel;
+ } selectPrinter;
+
+ struct
+ {
+ Widget popup,
+ form,
+ paperlist,
+ resolutionlist,
+ orientationlist,
+ plexlist,
+ jobcopieslabel,
+ jobcopies,
+ ok,
+ cancel;
+ } setup;
+
+ struct
+ {
+ Widget dialog,
+ shell;
+ } selectFile;
+
+ XPPrinterList printerlist;
+ int num_printers;
+ String *widget_printerlist;
+
+ String printer_name;
+ Display *pdpy;
+ XPContext pcontext;
+
+ XpuMediumSourceSizeList paperlist;
+ int num_papers;
+ String *widget_paperlist;
+
+ XpuResolutionList resolutionlist;
+ int num_resolutions;
+ String *widget_resolutionlist;
+
+ XpuOrientationList orientationlist;
+ int num_orientations;
+ String *widget_orientationlist;
+
+ XpuPlexList plexlist;
+ int num_plex;
+ String *widget_plexlist;
+} PrintDialogPart;
+
+typedef struct _PrintDialogRec {
+ CorePart core;
+ CompositePart composite;
+ ConstraintPart constraint;
+ FormPart form;
+ PrintDialogPart printdialog;
+} PrintDialogRec;
+
+typedef struct {
+ XtPointer extension;
+} PrintDialogConstraintsPart;
+
+typedef struct _PrintDialogConstraintsRec {
+ FormConstraintsPart form;
+ PrintDialogConstraintsPart printdialog;
+} PrintDialogConstraintsRec, *PrintDialogConstraints;
+
+#endif /* !_XawPrintDialogP_h */
+
diff --git a/xmore.c b/xmore.c
new file mode 100644
index 0000000..1dae07f
--- /dev/null
+++ b/xmore.c
@@ -0,0 +1,200 @@
+/*
+ * $Xorg: xmore.c,v 1.1 2004/04/30 02:05:54 gisburn Exp $
+ *
+Copyright 2004 Roland Mainz <roland.mainz@nrubsig.org>
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ */
+
+/* Force ANSI C prototypes from X11 headers */
+#ifndef FUNCPROTO
+#define FUNCPROTO 15
+#endif /* !FUNCPROTO */
+
+#include <X11/StringDefs.h>
+#include <X11/Intrinsic.h>
+#include <X11/Shell.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/List.h>
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/AsciiText.h>
+
+#include "xmore.h"
+#include "printdialog.h"
+#include "print.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/* Turn a NULL pointer string into an empty string */
+#define NULLSTR(x) (((x)!=NULL)?(x):(""))
+
+#define Error(x) { printf x ; exit(EXIT_FAILURE); }
+#define Assertion(expr, msg) { if (!(expr)) { Error msg } }
+#define Log(x) { if(True) printf x; }
+
+/* Global vars */
+XtAppContext app;
+Widget printdialog_shell = NULL;
+Widget printdialog = NULL;
+Widget toplevel;
+const char *ProgramName; /* program name (from argv[0]) */
+const char *viewFileName; /* file to browse (from argv[1]) */
+char printJobNameBuffer[1024];
+
+static void
+quitXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ XtAppSetExitFlag(app);
+}
+
+static void
+printOKXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ XawPrintDialogCallbackStruct *pdcs = (XawPrintDialogCallbackStruct *)callData;
+
+ Log(("printOKXtProc: OK.\n"));
+
+ /* ||printJobNameBuffer| must live as long the print job prints
+ * because it is used for the job title AND the page headers... */
+ sprintf(printJobNameBuffer, "XMore print job %s", viewFileName);
+
+ DoPrint(toplevel, pdcs->pdpy, pdcs->pcontext,
+ printJobNameBuffer,
+ pdcs->printToFile?pdcs->printToFileName:NULL);
+
+ XtPopdown(printdialog_shell);
+}
+
+static void
+printCancelXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ Log(("printCancelXtProc: cancel.\n"));
+ XtPopdown(printdialog_shell);
+
+ Log(("destroying print dialog shell...\n"));
+ XtDestroyWidget(printdialog_shell);
+ printdialog_shell = NULL;
+ printdialog = NULL;
+ Log(("... done\n"));
+}
+
+static void
+printXtProc(Widget w, XtPointer client_data, XtPointer callData)
+{
+ Dimension width, height;
+ Position x, y;
+ Widget parent = toplevel;
+ puts("print!");
+
+ if (!printdialog) {
+ int n;
+ Arg args[20];
+
+ n = 0;
+ XtSetArg(args[n], XtNallowShellResize, True); n++;
+ printdialog_shell = XtCreatePopupShell("shell",
+ transientShellWidgetClass,
+ toplevel, args, n);
+ n = 0;
+ printdialog = XtCreateManagedWidget("printdialog", printDialogWidgetClass,
+ printdialog_shell, args, n);
+ XtAddCallback(printdialog, XawNOkCallback, printOKXtProc, NULL);
+ XtAddCallback(printdialog, XawNCancelCallback, printCancelXtProc, NULL);
+
+ XtRealizeWidget(printdialog_shell);
+ }
+
+ /* Center dialog */
+ XtVaGetValues(printdialog_shell,
+ XtNwidth, &width,
+ XtNheight, &height,
+ NULL);
+
+ x = (Position)(XWidthOfScreen( XtScreen(parent)) - width) / 2;
+ y = (Position)(XHeightOfScreen(XtScreen(parent)) - height) / 3;
+
+ XtVaSetValues(printdialog_shell,
+ XtNx, x,
+ XtNy, y,
+ NULL);
+
+ XtPopup(printdialog_shell, XtGrabNonexclusive);
+}
+
+
+int main( int argc, char *argv[] )
+{
+ Widget form;
+ Widget text;
+ Widget printbutton;
+ Widget quitbutton;
+ int n;
+ Arg args[8];
+
+ ProgramName = argv[0];
+
+ toplevel = XtAppInitialize(&app, "XMore", NULL, 0, &argc, argv, NULL, NULL, 0);
+
+ if (argc != 2)
+ {
+ printf("usage: %s [ x options ] filename\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ viewFileName = argv[1];
+
+ form = XtCreateManagedWidget("form", formWidgetClass, toplevel, NULL, 0);
+
+ n = 0;
+ XtSetArg(args[n], XtNtype, XawAsciiFile); n++;
+ XtSetArg(args[n], XtNstring, viewFileName); n++;
+ XtSetArg(args[n], XtNwidth, 500); n++;
+ XtSetArg(args[n], XtNheight, 600); n++;
+ XtSetArg(args[n], XtNscrollHorizontal, XawtextScrollWhenNeeded); n++;
+ XtSetArg(args[n], XtNscrollVertical, XawtextScrollAlways); n++;
+ text = XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, n);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, NULL); n++;
+ XtSetArg(args[n], XtNfromVert, text); n++;
+ XtSetArg(args[n], XtNlabel, "Print..."); n++;
+ printbutton = XtCreateManagedWidget("print", commandWidgetClass, form, args, n);
+ XtAddCallback(printbutton, XtNcallback, printXtProc, 0);
+
+ n = 0;
+ XtSetArg(args[n], XtNfromHoriz, printbutton); n++;
+ XtSetArg(args[n], XtNfromVert, text); n++;
+ XtSetArg(args[n], XtNlabel, "Quit"); n++;
+ quitbutton = XtCreateManagedWidget("quit", commandWidgetClass, form, args, n);
+ XtAddCallback(quitbutton, XtNcallback, quitXtProc, 0);
+
+ printdialog_shell = NULL;
+ printdialog = NULL;
+
+ XtRealizeWidget(toplevel);
+
+ XtAppMainLoop(app);
+
+ return EXIT_SUCCESS;
+}
+
diff --git a/xmore.h b/xmore.h
new file mode 100644
index 0000000..496aa15
--- /dev/null
+++ b/xmore.h
@@ -0,0 +1,35 @@
+/*
+ * $Xorg: xmore.h,v 1.1 2004/04/30 02:05:54 gisburn Exp $
+ *
+Copyright 2004 Roland Mainz <roland.mainz@nrubsig.org>
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ */
+
+#ifndef XMORE_XMORE_H
+#define XMORE_XMORE_H 1
+
+/* Global vars */
+extern const char *ProgramName; /* program name (from argv[0]) */
+extern const char *viewFileName; /* file to browse (from argv[1]) */
+
+#endif /* !XMORE_XMORE_H */
diff --git a/xmore.man b/xmore.man
new file mode 100644
index 0000000..33cf2d2
--- /dev/null
+++ b/xmore.man
@@ -0,0 +1,25 @@
+.\" This manpage has been automatically generated by docbook2man
+.\" from a DocBook document. This tool can be found at:
+.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "XMORE" "__mansuffix__" "24 May 2004" "" ""
+.SH NAME
+xmore \- plain text display program for the X Window System
+.SH SYNOPSIS
+
+\fBxmore\fR [ \fB\fIfilename\fB\fR]
+
+.SH "DESCRIPTION"
+.PP
+\fBxmore\fR is a plain text browser.
+.SH "ENVIRONMENT"
+.TP
+\fBXPSERVERLIST \fR
+\fB${XPSERVERLIST}\fR must be set,
+identifying the available Xprint servers.
+See \fBXprint\fR(__miscmansuffix__)
+for more details.
+.SH "SEE ALSO"
+.PP
+\fBX11\fR(__miscmansuffix__), \fBxman\fR(__mansuffix__)
diff --git a/xmore.sgml b/xmore.sgml
new file mode 100644
index 0000000..66b0914
--- /dev/null
+++ b/xmore.sgml
@@ -0,0 +1,82 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.2//EN" '/usr/share/sgml/docbook_4.2/docbook.dtd'>
+
+<!-- Process this file with DocBook tools to generate the output format
+(such as manual pages or HTML documents).
+
+Note that strings like __mansuffix__, __filemansuffix__, __libmansuffix__,
+__miscmansuffix__ etc. have to be replaced first (in theory that's the
+job of ENTITIES but some XML tools are highly allergic to such stuff... ;-().
+A quick way to do that is to filter this document via
+/usr/bin/sed "s/__mansuffix__/${MANSUFFIX}/g;s/__filemansuffix__/${FILEMANSUFFIX}/g;s/__libmansuffix__/${LIBMANSUFFIX}/g;s/__miscmansuffix__/${MISCMANSUFFIX}/g"
+assuming that env vars like MANSUFFIX etc. have been set to the matching
+manual volume numbers.
+ -->
+
+<refentry>
+ <refmeta>
+ <refentrytitle>xmore</refentrytitle>
+ <manvolnum>__mansuffix__</manvolnum>
+ </refmeta>
+ <refnamediv>
+ <refname>xmore</refname>
+
+ <refpurpose>plain text display program for the X Window System</refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>xmore</command>
+
+ <arg><option><replaceable>filename</replaceable></option></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>DESCRIPTION</title>
+
+ <para><command>xmore</command> is a plain text browser.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>ENVIRONMENT</title>
+ <variablelist>
+ <varlistentry>
+ <term><envar>XPSERVERLIST</envar>
+ </term>
+ <listitem>
+ <para>
+ <envar>${XPSERVERLIST}</envar> must be set,
+ identifying the available Xprint servers.
+ See <citerefentry><refentrytitle>Xprint</refentrytitle><manvolnum>__miscmansuffix__</manvolnum></citerefentry>
+ for more details.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+<!-- not yet
+ <refsect1>
+ <title>KNOWN BUGS</title>
+ <para>
+ </para>
+ </refsect1>
+-->
+
+ <refsect1>
+ <title>SEE ALSO</title>
+ <para>
+ <simplelist type="inline">
+ <!-- specific references -->
+ <!-- none -->
+
+ <!-- Xprint general references -->
+ <member><citerefentry><refentrytitle>X11</refentrytitle><manvolnum>__miscmansuffix__</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>xman</refentrytitle><manvolnum>__mansuffix__</manvolnum></citerefentry></member>
+ </simplelist>
+ </para>
+ </refsect1>
+
+</refentry>
+
+