Index: xc/programs/Imakefile =================================================================== RCS file: /cvs/xorg/xc/programs/Imakefile,v retrieving revision 1.2 diff -u -2 -0 -r1.2 Imakefile --- a/xc/programs/Imakefile 23 Apr 2004 18:44:35 -0000 1.2 +++ b/xc/programs/Imakefile 9 May 2004 20:40:23 -0000 @@ -112,31 +112,31 @@ FCLANGDIR = fc-lang #endif #if BuildServersOnly || !BuildClients SUBDIRS = $(XSSRCDIR) #else SUBDIRS = \ appres bdftopcf bitmap \ $(SCREENSAVESRCDIR) editres $(FCDIRS) $(FCLANGDIR) fslsfonts fstobdf \ iceauth ico listres luit \ $(MAKEPSRESDIR) $(DPSCLIENTDIRS) \ $(MKCFMSRCDIR) \ mkfontdir $(MKFONTSCALEDIR) oclock $(PROXYMGRSRCDIR) \ $(RGBSRCDIR) $(RSTARTSRCDIR) showfont \ $(SMPROXYSRCDIR) $(TWMSRCDIR) viewres x11perf xauth xbiff xcalc \ xclipboard xclock \ xcmsdb $(XCONSOLESRCDIR) xditview $(XDMSRCDIR) xdpyinfo \ $(XF86DGASRCDIR) xedit xev xeyes xfd xfontsel $(XFSSRCDIR) xfsinfo \ $(XFINDPROXYSRCDIR) $(XFWPSRCDIR) $(XGAMMASRCDIR) xgc $(XHOSTSRCDIR) \ $(XINITSRCDIR) $(XKBSRCDIRS) xkill $(XLOADDIR) xlogo xlsatoms \ - xlsclients xlsfonts xmag xman xmessage xmh xmodmap xprop xrdb \ + xlsclients xlsfonts xmag xman xmore xmessage xmh xmodmap xprop xrdb \ xrefresh $(XRXSRCDIR) xset \ xsetroot $(XSMSRCDIR) xstdcmap $(XINPUTCLIENTDIRS) \ $(XTERMSRCDIR) $(XTRAPCLIENTDIRS) $(XVIDTUNESRCDIR) xwd xwininfo xwud \ $(XPMCLIENTDIRS) $(XVINFOSRCDIR) \ $(XSSRCDIR) $(XASSRCDIR) $(LBXPROXYSRCDIR) $(XPSRCDIRS) $(SCRIPTSDIR) \ $(GLXCLIENTDIRS) $(XRANDRDIR) $(XCURSORGENDIR) #endif MakeSubdirs($(SUBDIRS)) DependSubdirs($(SUBDIRS)) Index: xc/programs/xmore/Imakefile =================================================================== RCS file: xc/programs/xmore/Imakefile diff -N xc/programs/xmore/Imakefile --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/programs/xmore/Imakefile 9 May 2004 20:40:33 -0000 @@ -0,0 +1,11 @@ +XCOMM $Xorg: Imakefile,v 1.1 2004/05/09 07:54:52 gisburn Exp $ + + DEPLIBS = XawClientDepLibs XkbClientDepLibs +LOCAL_LIBRARIES = XawClientLibs XkbClientLibs -lXprintUtil + SRCS = xmore.c print.c printdialog.c + OBJS = xmore.o print.o printdialog.o + HEADERS = + CDEBUGFLAGS = -g + +ComplexProgramTarget(xmore) +InstallAppDefaults(XMore) Index: xc/programs/xmore/print.c =================================================================== RCS file: xc/programs/xmore/print.c diff -N xc/programs/xmore/print.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/programs/xmore/print.c 9 May 2004 20:40:33 -0000 @@ -0,0 +1,348 @@ +/* + * $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 + +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; +} 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 SetLabelText(Widget label, const char *text) +{ + int n; + Arg args[2]; + + n = 0; + XtSetArg(args[n], XtNlabel, text); n++; + XtSetValues(label, args, n); +} + +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); +#if 0 + char buffer[256]; + sprintf(buffer, "Page: %d/%d", currpage, p->numpages); + SetLabelText(apd->content.pageheaderlabel, buffer); +#endif + + /* 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; + } + + if (p->pdpy) { + /* We have to use XpDestroyContext() and XtCloseDisplay() instead + * of XpuClosePrinterDisplay() to make libXt happy... */ + if (p->pcontext != None) + XpDestroyContext(p->pdpy, p->pcontext); + XtCloseDisplay(p->pdpy); + } + + 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 *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, "XMore print job"); + + /* 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->printshell = CreatePrintShell(toplevel, apd->pscreen, "Print", NULL, 0); + + n = 0; + apd->content.form = XtCreateManagedWidget("form", formWidgetClass, apd->printshell, args, n); + + textfont = GetPrintTextFont(pdpy, dpi); + +/* XXX: the page header label does not work... it consumes 1/2 of the form + * widget (= ~~half the page) */ +#if 0 + 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], XtNfont, textfont); n++; /* fontset would be better */ + XtSetArg(args[n], XtNlabel, "Page: n/n"); n++; + apd->content.pageheaderlabel = XtCreateManagedWidget("pageinfo", labelWidgetClass, apd->content.form, args, n); +#endif + + 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++; + XtSetArg(args[n], XtNfromHoriz, NULL); n++; + XtSetArg(args[n], XtNfromVert, apd->content.pageheaderlabel); n++; + 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); + } +} + + Index: xc/programs/xmore/print.h =================================================================== RCS file: xc/programs/xmore/print.h diff -N xc/programs/xmore/print.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/programs/xmore/print.h 9 May 2004 20:40:33 -0000 @@ -0,0 +1,41 @@ +/* + * $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 *toFile); + +#endif /* !XMORE_PRINT_H */ Index: xc/programs/xmore/printdialog.c =================================================================== RCS file: xc/programs/xmore/printdialog.c diff -N xc/programs/xmore/printdialog.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/programs/xmore/printdialog.c 9 May 2004 20:40:33 -0000 @@ -0,0 +1,583 @@ +/* + * $Xorg: printdialog.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 "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; } + + +typedef struct +{ + Widget toplevel; + + Widget printDialogPopup, + printDialogForm, + printDialogPrinterListLabel, + printDialogPrinterList, + printDialogDestinationList, + printDialogButtonOK, + printDialogButtonSetup, + printDialogButtonCancel; + + Widget printSetupPopup, + printSetupForm, + printSetupPaperList, + printSetupOrientationList, + printSetupPlexList, + printSetupButtonOK, + printSetupButtonCancel; + + XPPrinterList printerlist; + int num_printers; + String *widget_printerlist; + + String printer_name; + Display *pdpy; + XPContext pcontext; + + XpuMediumSourceSizeList paperlist; + int num_papers; + String *widget_paperlist; + + XpuOrientationList orientationlist; + int num_orientations; + String *widget_orientationlist; + + XpuPlexList plexlist; + int num_plex; + String *widget_plexlist; +} printdialogcontext; + +char *listwidget_nulllist[] = { NULL }; + + +char *destinationslist[] = { "Print to Printer", "Print to file", NULL }; + +/* Local prototypes */ +String *xpprinterlist_to_widget_printerlist(XPPrinterList printerlist, int num_printers); +String *xppaperlist_to_widget_paperlist(XpuMediumSourceSizeList paperlist, int num_papers); +String *xporientationlist_to_widget_orientationlist(XpuOrientationList orientationlist, int num_orientations); +String *xpplexlist_to_widget_paperlist(XpuPlexList plexlist, int num_plex); +Widget buildPrintSetupDialog(printdialogcontext *pdc); +void closePrinterConnection(printdialogcontext *pdc); +Bool openPrinterConnection(printdialogcontext *pdc); +void destroyPrintSetupDialog(printdialogcontext *pdc); + + +static void +printSetupClose(printdialogcontext *pdc) +{ + if (pdc->printSetupPopup) { + XtPopdown(pdc->printSetupPopup); + } +} + +static void +printSetupOKXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + printdialogcontext *pdc = (printdialogcontext *)client_data; + Log(("## printSetupOK: closing print setup!\n")); + + printSetupClose(pdc); +} + +static void +printSetupCancelXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + printdialogcontext *pdc = (printdialogcontext *)client_data; + Log(("## printSetupCancel: closing print setup!\n")); + + printSetupClose(pdc); + + /* Close connection to get rid of the current settings and open a + * new one to load the printer defaults */ + closePrinterConnection(pdc); + openPrinterConnection(pdc); +} + +static void +printCancelXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + printdialogcontext *pdc = (printdialogcontext *)client_data; + + printSetupClose(pdc); + XtPopdown(pdc->printDialogPopup); +} + +static void +printOKXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + printdialogcontext *pdc = (printdialogcontext *)client_data; + Log(("## printing!\n")); + + DoPrint(pdc->toplevel, pdc->pdpy, pdc->pcontext, NULL); + + printSetupClose(pdc); + XtPopdown(pdc->printDialogPopup); +} + +static void +printSetupXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + printdialogcontext *pdc = (printdialogcontext *)client_data; + Dimension width, + height; + Position x, + y; + Widget parent = pdc->printDialogPopup; + + Log(("## setup!\n")); + + if (!pdc->printSetupPopup) { + if (buildPrintSetupDialog(pdc) == NULL) { + Log(("printSetupXtProc: buildPrintSetupDialog failure.\n")); + return; + } + } + + /* Center dialog */ + XtVaGetValues(pdc->printSetupPopup, + XtNwidth, &width, + XtNheight, &height, + NULL); + + x = (Position)(XWidthOfScreen( XtScreen(parent)) - width) / 2; + y = (Position)(XHeightOfScreen(XtScreen(parent)) - height) / 3; + + XtVaSetValues(pdc->printSetupPopup, + XtNx, x, + XtNy, y, + NULL); + + XtPopup(pdc->printSetupPopup, XtGrabNonexclusive); +} + +static void +printDialogPrinterSelectedXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + printdialogcontext *pdc = (printdialogcontext *)client_data; + XawListReturnStruct *lrs = (XawListReturnStruct *)callData; + + Log(("## user selected a printer\n")); + + Log(("selected printer is '%s'\n", lrs->string)); + + if (pdc->printer_name) + free(pdc->printer_name); + pdc->printer_name = strdup(lrs->string); + + openPrinterConnection(pdc); +} + + +static void +printSetupPaperSelectedXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + printdialogcontext *pdc = (printdialogcontext *)client_data; + XawListReturnStruct *lrs = (XawListReturnStruct *)callData; + + Log(("selected paper is '%s'/'%d'\n", lrs->string, lrs->list_index)); + Assertion(lrs->list_index < pdc->num_papers, (("Error: lrs->list_index < pdc->num_papers\n"))); + XpuSetDocMediumSourceSize(pdc->pdpy, pdc->pcontext, &pdc->paperlist[lrs->list_index]); +} + +static void +printSetupOrientationSelectedXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + printdialogcontext *pdc = (printdialogcontext *)client_data; + XawListReturnStruct *lrs = (XawListReturnStruct *)callData; + + Log(("selected orientation is '%s'/'%d'\n", lrs->string, lrs->list_index)); + Assertion(lrs->list_index < pdc->num_orientations, (("Error: lrs->list_index < pdc->num_orientations\n"))); + XpuSetDocOrientation(pdc->pdpy, pdc->pcontext, &pdc->orientationlist[lrs->list_index]); +} + +static void +printSetupPlexSelectedXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + printdialogcontext *pdc = (printdialogcontext *)client_data; + XawListReturnStruct *lrs = (XawListReturnStruct *)callData; + + Log(("selected plex is '%s'/'%d'\n", lrs->string, lrs->list_index)); + Assertion(lrs->list_index < pdc->num_plex, (("Error: lrs->list_index < pdc->num_plex\n"))); + XpuSetDocPlex(pdc->pdpy, pdc->pcontext, &pdc->plexlist[lrs->list_index]); +} + +void closePrinterConnection(printdialogcontext *pdc) +{ + int n; + Arg args[20]; + + destroyPrintSetupDialog(pdc); + + if (pdc->paperlist) { + XpuFreeMediumSourceSizeList(pdc->paperlist); + pdc->paperlist = NULL; + } + + if (pdc->widget_paperlist) { + free(pdc->widget_paperlist); + pdc->widget_paperlist = NULL; + } + + if (pdc->orientationlist) { + XpuFreeOrientationList(pdc->orientationlist); + pdc->orientationlist = NULL; + } + + if (pdc->widget_orientationlist) { + free(pdc->widget_orientationlist); + pdc->widget_orientationlist = NULL; + } + + if (pdc->plexlist) { + XpuFreePlexList(pdc->plexlist); + pdc->plexlist = NULL; + } + + if (pdc->widget_plexlist) { + free(pdc->widget_plexlist); + pdc->widget_plexlist = NULL; + } + + if (pdc->pdpy) { + XpuClosePrinterDisplay(pdc->pdpy, pdc->pcontext); + pdc->pdpy = NULL; + pdc->pcontext = None; + } + + /* Disable "Print..." button */ + n = 0; + XtSetArg(args[n], XtNsensitive, False); n++; + XtSetValues(pdc->printDialogButtonOK, args, n); + XtSetValues(pdc->printDialogButtonSetup, args, n); +} + + +Bool openPrinterConnection(printdialogcontext *pdc) +{ + int n; + Arg args[20]; + + closePrinterConnection(pdc); + + if (!pdc->printer_name) { + Log(("# error: openPrinterConnection: No printer name.\n")); + return False; + } + + if (XpuGetPrinter(pdc->printer_name, &pdc->pdpy, &pdc->pcontext) == False) { + Log(("openPrinterConnection: could not open printer.\n")); + return False; + } + + pdc->paperlist = XpuGetMediumSourceSizeList(pdc->pdpy, pdc->pcontext, &pdc->num_papers); + pdc->orientationlist = XpuGetOrientationList(pdc->pdpy, pdc->pcontext, &pdc->num_orientations); + pdc->plexlist = XpuGetPlexList(pdc->pdpy, pdc->pcontext, &pdc->num_plex); + + pdc->widget_paperlist = xppaperlist_to_widget_paperlist(pdc->paperlist, pdc->num_papers); + pdc->widget_orientationlist = xporientationlist_to_widget_orientationlist(pdc->orientationlist, pdc->num_orientations); + pdc->widget_plexlist = xpplexlist_to_widget_paperlist(pdc->plexlist, pdc->num_plex); + + /* Enable "Print..." button */ + n = 0; + XtSetArg(args[n], XtNsensitive, True); n++; + XtSetValues(pdc->printDialogButtonOK, args, n); + XtSetValues(pdc->printDialogButtonSetup, args, n); + + return True; +} + +#undef DEFAULT_WIDTH +#define DEFAULT_WIDTH 100 + +void destroyPrintSetupDialog(printdialogcontext *pdc) +{ + if (pdc->printSetupPopup) { + XtDestroyWidget(pdc->printSetupPopup); + } + + /* |XtDestroyWidget(pdc->printSetupPopup);| above will recursively destroy + * all children so we only have to reset the pointers here... */ + pdc->printSetupPopup = NULL; + pdc->printSetupForm = NULL; + pdc->printSetupPaperList = NULL; + pdc->printSetupOrientationList = NULL; + pdc->printSetupPlexList = NULL; + pdc->printSetupButtonOK = NULL; + pdc->printSetupButtonCancel = NULL; +} + +Widget buildPrintSetupDialog(printdialogcontext *pdc) +{ + int n; + Arg args[20]; + Widget listform; + + if (!pdc->pdpy) { + Log(("buildPrintSetupDialog: no printer connection.\n")); + /* ToDo: Ring bell! */ + return NULL; + } + + n = 0; + XtSetArg(args[n], XtNallowShellResize, True); n++; + pdc->printSetupPopup = XtCreatePopupShell("printSetupPopup", transientShellWidgetClass, pdc->printDialogPopup, args, n); + + n = 0; + pdc->printSetupForm = XtCreateManagedWidget("printSetupForm", formWidgetClass, pdc->printSetupPopup, args, n); + + n = 0; + listform = XtCreateManagedWidget("printSetupListForm", formWidgetClass, pdc->printSetupForm, 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, pdc->widget_paperlist); n++; + XtSetArg(args[n], XtNwidth, DEFAULT_WIDTH); n++; + pdc->printSetupPaperList = XtCreateManagedWidget("printSetupPaperList", listWidgetClass, listform, args, n); + XtAddCallback(pdc->printSetupPaperList, XtNcallback, printSetupPaperSelectedXtProc, pdc); + + n = 0; + XtSetArg(args[n], XtNresizable, True); n++; + XtSetArg(args[n], XtNforceColumns, True); n++; + XtSetArg(args[n], XtNdefaultColumns, 1); n++; + XtSetArg(args[n], XtNfromHoriz, pdc->printSetupPaperList); n++; + XtSetArg(args[n], XtNfromVert, NULL); n++; + XtSetArg(args[n], XtNlist, pdc->widget_orientationlist); n++; + XtSetArg(args[n], XtNwidth, DEFAULT_WIDTH); n++; + pdc->printSetupOrientationList = XtCreateManagedWidget("printSetupOrientationList", listWidgetClass, listform, args, n); + XtAddCallback(pdc->printSetupOrientationList, XtNcallback, printSetupOrientationSelectedXtProc, pdc); + + n = 0; + XtSetArg(args[n], XtNresizable, True); n++; + XtSetArg(args[n], XtNforceColumns, True); n++; + XtSetArg(args[n], XtNdefaultColumns, 1); n++; + XtSetArg(args[n], XtNfromHoriz, pdc->printSetupOrientationList); n++; + XtSetArg(args[n], XtNfromVert, NULL); n++; + XtSetArg(args[n], XtNlist, pdc->widget_plexlist); n++; + XtSetArg(args[n], XtNwidth, DEFAULT_WIDTH); n++; + pdc->printSetupPlexList = XtCreateManagedWidget("printSetupPlexList", listWidgetClass, listform, args, n); + XtAddCallback(pdc->printSetupPlexList, XtNcallback, printSetupPlexSelectedXtProc, pdc); + + n = 0; + XtSetArg(args[n], XtNfromHoriz, NULL); n++; + XtSetArg(args[n], XtNfromVert, listform); n++; + XtSetArg(args[n], XtNlabel, "OK"); n++; + pdc->printSetupButtonOK = XtCreateManagedWidget("printSetupButtonOK", commandWidgetClass, pdc->printSetupForm, args, n); + XtAddCallback(pdc->printSetupButtonOK, XtNcallback, printSetupOKXtProc, pdc); + + n = 0; + XtSetArg(args[n], XtNfromHoriz, pdc->printSetupButtonOK); n++; + XtSetArg(args[n], XtNfromVert, listform); n++; + XtSetArg(args[n], XtNlabel, "Cancel"); n++; + pdc->printSetupButtonCancel = XtCreateManagedWidget("printSetupButtonCancel", commandWidgetClass, pdc->printSetupForm, args, n); + XtAddCallback(pdc->printSetupButtonCancel, XtNcallback, printSetupCancelXtProc, pdc); + + return pdc->printSetupPopup; +} + +#undef DEFAULT_WIDTH +#define DEFAULT_WIDTH 250 + +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; +} + + +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; +} + +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; +} + +String *xpplexlist_to_widget_paperlist(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; +} + +Widget buildPrintDialog(Widget toplevel) +{ + int n; + Arg args[20]; + + printdialogcontext *pdc = malloc(sizeof(printdialogcontext)); + if(!pdc) + return NULL; + memset(pdc, 0, sizeof(printdialogcontext)); + + pdc->printerlist = XpuGetPrinterList(NULL, &pdc->num_printers); + pdc->widget_printerlist = xpprinterlist_to_widget_printerlist(pdc->printerlist, pdc->num_printers); + + pdc->toplevel = toplevel; + + n = 0; + XtSetArg(args[n], XtNallowShellResize, True); n++; + pdc->printDialogPopup = XtCreatePopupShell("printDialogPopup", transientShellWidgetClass, pdc->toplevel, args, n); + + n = 0; + pdc->printDialogForm = XtCreateManagedWidget("printDialogForm", formWidgetClass, pdc->printDialogPopup, 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, XtJustifyCenter); n++; + XtSetArg(args[n], XtNwidth, DEFAULT_WIDTH); n++; + XtSetArg(args[n], XtNlabel, "Printer name:"); n++; + pdc->printDialogPrinterListLabel = XtCreateManagedWidget("printDialogPrinterListLabel", labelWidgetClass, pdc->printDialogForm, 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, pdc->printDialogPrinterListLabel); n++; + XtSetArg(args[n], XtNlist, pdc->widget_printerlist); n++; + XtSetArg(args[n], XtNwidth, DEFAULT_WIDTH); n++; + pdc->printDialogPrinterList = XtCreateManagedWidget("printDialogPrinterList", listWidgetClass, pdc->printDialogForm, args, n); + XtAddCallback(pdc->printDialogPrinterList, XtNcallback, printDialogPrinterSelectedXtProc, pdc); + + n = 0; + XtSetArg(args[n], XtNresizable, False); n++; + XtSetArg(args[n], XtNforceColumns, False); n++; + XtSetArg(args[n], XtNdefaultColumns, 2); n++; + XtSetArg(args[n], XtNfromHoriz, NULL); n++; + XtSetArg(args[n], XtNfromVert, pdc->printDialogPrinterList); n++; + XtSetArg(args[n], XtNlist, &destinationslist); n++; + XtSetArg(args[n], XtNwidth, DEFAULT_WIDTH); n++; + XtSetArg(args[n], XtNverticalList, False); n++; + pdc->printDialogDestinationList = XtCreateManagedWidget("printDialogDestinationList", listWidgetClass, pdc->printDialogForm, args, n); + + n = 0; + XtSetArg(args[n], XtNfromHoriz, NULL); n++; + XtSetArg(args[n], XtNfromVert, pdc->printDialogDestinationList); n++; + XtSetArg(args[n], XtNlabel, "Print"); n++; + XtSetArg(args[n], XtNsensitive, False); n++; /* dsiabled by default, we will enable it later whe there is a valid printer selected */ + pdc->printDialogButtonOK = XtCreateManagedWidget("printDialogButtonOK", commandWidgetClass, pdc->printDialogForm, args, n); + XtAddCallback(pdc->printDialogButtonOK, XtNcallback, printOKXtProc, pdc); + + n = 0; + XtSetArg(args[n], XtNfromHoriz, pdc->printDialogButtonOK); n++; + XtSetArg(args[n], XtNfromVert, pdc->printDialogDestinationList); n++; + XtSetArg(args[n], XtNlabel, "Setup..."); n++; + XtSetArg(args[n], XtNsensitive, False); n++; /* dsiabled by default, we will enable it later whe there is a valid printer selected */ + pdc->printDialogButtonSetup = XtCreateManagedWidget("printDialogButtonSetup", commandWidgetClass, pdc->printDialogForm, args, n); + XtAddCallback(pdc->printDialogButtonSetup, XtNcallback, printSetupXtProc, pdc); + + n = 0; + XtSetArg(args[n], XtNfromHoriz, pdc->printDialogButtonSetup); n++; + XtSetArg(args[n], XtNfromVert, pdc->printDialogDestinationList); n++; + XtSetArg(args[n], XtNlabel, "Cancel"); n++; + pdc->printDialogButtonCancel = XtCreateManagedWidget("printDialogButtonCancel", commandWidgetClass, pdc->printDialogForm, args, n); + XtAddCallback(pdc->printDialogButtonCancel, XtNcallback, printCancelXtProc, pdc); + + return pdc->printDialogPopup; +} + + + + Index: xc/programs/xmore/printdialog.h =================================================================== RCS file: xc/programs/xmore/printdialog.h diff -N xc/programs/xmore/printdialog.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/programs/xmore/printdialog.h 9 May 2004 20:40:33 -0000 @@ -0,0 +1,42 @@ +/* + * $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 + +/* Prototypes */ +Widget buildPrintDialog(Widget toplevel); + + +#endif /* !XMORE_PRINTDIALOG_H */ Index: xc/programs/xmore/xmore.c =================================================================== RCS file: xc/programs/xmore/xmore.c diff -N xc/programs/xmore/xmore.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/programs/xmore/xmore.c 9 May 2004 20:40:33 -0000 @@ -0,0 +1,145 @@ +/* + * $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 +#include + +/* Global vars */ +XtAppContext app; +Widget printdialog = NULL; +Widget toplevel; +const char *ProgramName; /* program name (from argv[0]) */ +const char *viewFileName; /* file to browse (from argv[1]) */ + + +static void +quitXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + XtAppSetExitFlag(app); +} + +static void +printXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + Dimension width, height; + Position x, y; + Widget parent = toplevel; + puts("print!"); + + if (!printdialog) { + printdialog = buildPrintDialog(toplevel); + } + + /* Center dialog */ + XtVaGetValues(printdialog, + XtNwidth, &width, + XtNheight, &height, + NULL); + + x = (Position)(XWidthOfScreen( XtScreen(parent)) - width) / 2; + y = (Position)(XHeightOfScreen(XtScreen(parent)) - height) / 3; + + XtVaSetValues(printdialog, + XtNx, x, + XtNy, y, + NULL); + + XtPopup(printdialog, 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 = NULL; + + XtRealizeWidget(toplevel); + + XtAppMainLoop(app); + + return EXIT_SUCCESS; +} + Index: xc/programs/xmore/xmore.h =================================================================== RCS file: xc/programs/xmore/xmore.h diff -N xc/programs/xmore/xmore.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ b/xc/programs/xmore/xmore.h 9 May 2004 20:40:33 -0000 @@ -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 */