diff options
-rw-r--r-- | print.c | 353 | ||||
-rw-r--r-- | print.h | 44 | ||||
-rw-r--r-- | printdialog.c | 1375 | ||||
-rw-r--r-- | printdialog.h | 84 | ||||
-rw-r--r-- | printdialogprivates.h | 176 | ||||
-rw-r--r-- | xmore.c | 200 | ||||
-rw-r--r-- | xmore.h | 35 | ||||
-rw-r--r-- | xmore.man | 25 | ||||
-rw-r--r-- | xmore.sgml | 82 |
9 files changed, 2374 insertions, 0 deletions
@@ -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); + } +} + + @@ -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 */ + @@ -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; +} + @@ -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> + + |