From 62ad6298a589dd16820c7d0bbfcd2b5381a2589e Mon Sep 17 00:00:00 2001 From: Roland Mainz Date: Mon, 24 May 2004 03:17:44 +0000 Subject: Fix for http://pdx.freedesktop.org/cgi-bin/bugzilla/show_bug.cgi?id=611 - Adding simple text viewer (xmore) --- print.c | 353 +++++++++++++ print.h | 44 ++ printdialog.c | 1375 +++++++++++++++++++++++++++++++++++++++++++++++++ printdialog.h | 84 +++ printdialogprivates.h | 176 +++++++ xmore.c | 200 +++++++ xmore.h | 35 ++ xmore.man | 25 + xmore.sgml | 82 +++ 9 files changed, 2374 insertions(+) create mode 100644 print.c create mode 100644 print.h create mode 100644 printdialog.c create mode 100644 printdialog.h create mode 100644 printdialogprivates.h create mode 100644 xmore.c create mode 100644 xmore.h create mode 100644 xmore.man create mode 100644 xmore.sgml 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 + +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 +#include +#include +#include +#include + +#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 + +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 +#include +#include +#include +#include +#include + +/* 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 + +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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "printdialog.h" +#include "printdialogprivates.h" +#include "print.h" + +#include +#include +#include + +/* 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 + +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 +#include +#include +#include +#include +#include +#include + +/* 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 + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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 + +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 +#include +#include +#include +#include +#include +#include + +#include "xmore.h" +#include "printdialog.h" +#include "print.h" + +#include +#include + +/* 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 + +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: +.\" +.\" Please send any bug reports, improvements, comments, patches, +.\" etc. to Steve Cheng . +.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 @@ + + + + + + + xmore + __mansuffix__ + + + xmore + + plain text display program for the X Window System + + + + xmore + + + + + + DESCRIPTION + + xmore is a plain text browser. + + + + + + ENVIRONMENT + + + XPSERVERLIST + + + + ${XPSERVERLIST} must be set, + identifying the available Xprint servers. + See Xprint__miscmansuffix__ + for more details. + + + + + + + + + + SEE ALSO + + + + + + + X11__miscmansuffix__ + xman__mansuffix__ + + + + + + + -- cgit v1.2.3