Index: xc/ChangeLog =================================================================== RCS file: /cvs/xorg/xc/ChangeLog,v retrieving revision 1.863 diff -u -2 -0 -r1.863 ChangeLog --- xc/ChangeLog 9 Apr 2005 06:42:12 -0000 1.863 +++ xc/ChangeLog 11 Apr 2005 00:59:21 -0000 @@ -1,20 +1,51 @@ +2005-04-10 Roland Mainz + * xc/programs/Xserver/Xprint/attributes.c + * xc/programs/glxgears/glxgears.c + * xc/programs/xdbedizzy/xdbedizzy.c + * xc/programs/xedit/Imakefile + * xc/programs/xedit/Xedit-xprint.ad + * xc/programs/xedit/util.c + * xc/programs/xedit/xedit.h + * xc/programs/xlogo/print.c + * xc/programs/xlogo/xlogo.c + * xc/programs/xlogo/xlogo.h + * xc/programs/xman/Imakefile + * xc/programs/xman/print.h + * xc/programs/xmore/Imakefile + * xc/programs/xmore/print.c + * xc/programs/xmore/print.h + * xc/programs/xmore/printdialog.c + * xc/programs/xphelloworld/xpawhelloworld/xpawhelloworld.c + * xc/programs/xphelloworld/xphelloworld/xphelloworld.c + * xc/programs/xphelloworld/xpsimplehelloworld/xpsimplehelloworld.c + * xc/programs/xphelloworld/xpxmhelloworld/xpxmhelloworld.c + * xc/programs/xphelloworld/xpxthelloworld/xpxthelloworld.c + bugzilla #790 (https://bugs.freedesktop.org/show_bug.cgi?id=790) + attachment #xxx (https://bugs.freedesktop.org/attachment.cgi?id=xxx) + Implement support client+Xserver support for passing output + (stdout+stderr) of the spooler command started by the Xprint + server back to the application using the "xp-spooler-command-results" + XPJobAttr attribute (applications can fetch the attribute value after + the XPEndJobNotify event was received; more details can be found + in http://xprint.mozdev.org/docs/dtprint_fspec.ps). + 2005-04-09 Roland Mainz * xc/programs/xman/buttons.c bugzilla #2942 (https://bugs.freedesktop.org/show_bug.cgi?id=2942) attachment #2360 (https://bugs.freedesktop.org/attachment.cgi?id=2360) Fix possible crash due uninitalised structure when "xman" opens the print dialog. 2005-04-05 Daniel Stone * programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c: Release SDA/SDL I2C lines from an asserted-low state after a DDC probe, which caused Apple Studio Display monitors to shut off after a second or so (Ben Herrenschmidt). 2005-04-04 Egbert Eich * programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c: (SavageInitAccel): Add ROP_NEEDS_SOURCE to Mono8x8PatternFill as S3 chips tend to lock up without it (Helmut Fahrion). Index: xc/programs/Xserver/Xprint/attributes.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/Xprint/attributes.c,v retrieving revision 1.8 diff -u -2 -0 -r1.8 attributes.c --- xc/programs/Xserver/Xprint/attributes.c 10 Jan 2005 18:47:55 -0000 1.8 +++ xc/programs/Xserver/Xprint/attributes.c 11 Apr 2005 00:59:30 -0000 @@ -48,40 +48,48 @@ #include #include #include #include #include #if (defined(sun) && defined(SVR4)) || (defined(SCO)) #include #endif #include "scrnintstr.h" #include #include "attributes.h" #include "Xlib.h" #include "Xresource.h" #include "Xrm.c" #include "spooler.h" +#ifndef MIN +#define MIN(a,b) (((a)<(b))?(a):(b)) +#endif +#ifndef MAX +#define MAX(a,b) (((a)>(b))?(a):(b)) +#endif + + static XrmDatabase CopyDb(XrmDatabase inDb); extern XrmDatabase XpSpoolerGetServerAttributes(void); static int attrGeneration = 0; typedef struct { XrmDatabase *pDb; char *qualifier; char *modelId; } DbEnumStruct; typedef struct { char *stringDb; int nextPos; int space; } StringDbStruct; typedef struct _printerAttrs { struct _printerAttrs *next; @@ -1067,138 +1075,247 @@ XpSpoolerGetServerAttributes(void) { char *totalAttrs, *localeName; XrmDatabase db; localeName = setlocale(LC_CTYPE, (char *)NULL); if(!localeName || strlen(localeName) == 0) localeName = "C"; if((totalAttrs = (char *)xalloc(strlen(serverAttrStr) + strlen(localeName) + 11)) == (char *)NULL) return (XrmDatabase)NULL; sprintf(totalAttrs, "%s\n%s\t%s", serverAttrStr, "*locale:", localeName); db = XrmGetStringDatabase(totalAttrs); xfree(totalAttrs); return db; } /* + * Tailf() works similar to "/bin/tail -f fd_in >fd_out" until + * the process |child| terminates (the child status is + * returned in |child_status|). + * This function is used to copy the stdout/stderr output of a + * child to fd_out until the child terminates. + */ +static +void Tailf(int fd_in, int fd_out, pid_t child, int *child_status) +{ + char b[256]; + ssize_t sz; + Bool childDone = FALSE; + struct timeval timeout; + long fpos = 0; /* XXX: this is not correct for largefile support */ + + timeout.tv_sec = 0; + timeout.tv_usec = 100000; + + for(;;) + { + /* Check whether the child is still alive or not */ + if (waitpid(child, child_status, WNOHANG) == child) + childDone = TRUE; + + /* Copy traffic from |fd_in| to |fd_out| + * (Note we have to use |pread()| here to avoid race conditions + * between a child process writing to the same file using the + * same file pointer (|dup(2)| and |fork(2)| just duplicate the + * file handle but not the pointer)). + */ + while ((sz = pread(fd_in, b, sizeof(b), fpos)) > 0) + { + fpos += sz; + write(fd_out, b, sz); + } + + if (childDone) + break; + + (void)select(0, NULL, NULL, NULL, &timeout); + } +} + +/* * SendFileToCommand takes three character pointers - the file name, * the command to execute, * and the "argv" style NULL-terminated vector of arguments for the command. * The command is exec'd, and the file contents are sent to the command * via stdin. * * WARNING: This function will try to adopt the userId of the supplied * user name prior to exec'ing the supplied command. */ static void SendFileToCommand( + XpContextPtr pContext, char *fileName, char *pCommand, char **argVector, char *userName) { pid_t childPid; int pipefd[2]; int status; struct stat statBuf; FILE *fp, *outPipe; + FILE *resFp; /* output from launched command */ + int resfd; + + resFp = tmpfile(); + if (resFp == NULL) + { + ErrorF("SendFileToCommand: Cannot open temporary file for command output\n"); + return; + } + resfd = fileno(resFp); if(pipe(pipefd)) - return; + { + ErrorF("SendFileToCommand: Cannot open pipe\n"); + fclose(resFp); + return; + } if(stat(fileName, &statBuf) < 0 || (int)statBuf.st_size == 0) { - close(pipefd[0]); - close(pipefd[1]); - return; + close(pipefd[0]); + close(pipefd[1]); + fclose(resFp); + return; } fp = fopen(fileName, "r"); if(fp == (FILE *)NULL) { + ErrorF("SendFileToCommand: Cannot open scratch spool file '%s'\n", fileName); close(pipefd[0]); close(pipefd[1]); + fclose(resFp); return; } if((childPid = fork()) == 0) { close(pipefd[1]); /* Replace current stdin with input from the pipe */ - close(0); + close(STDIN_FILENO); dup(pipefd[0]); close(pipefd[0]); - /* Close current stdout and redirect it to stderr */ - close(1); - dup(2); + /* Close current stdout and redirect it to resfd */ + close(STDOUT_FILENO); + dup(resfd); + + /* Close current stderr and redirect it to resfd + * (valgrind may not like that, in this case simply start it using + * % valgrind 50>/dev/tty --logfile-fd=50 ./Xprt ... #) + */ + close(STDERR_FILENO); + dup(resfd); + + fclose(resFp); /* * If a user name is specified, try to set our uid to match that * user name. This is to allow e.g. a banner page to show the * name of the printing user rather than the user who started * the print server. */ if(userName) { uid_t myUid; if((myUid = geteuid()) == (uid_t)0) { struct passwd *pPasswd; if((pPasswd = getpwnam(userName))) { if (setgid((gid_t)pPasswd->pw_gid) != 0) perror("SendFileToCommand: setgid() failure."); if (initgroups(userName, (gid_t)pPasswd->pw_gid) != 0) perror("SendFileToCommand: initgroups() failure."); if (setuid((uid_t)pPasswd->pw_uid) != 0) perror("SendFileToCommand: setuid() failure."); } } } /* return BadAlloc? */ if (execv(pCommand, argVector) == -1) { FatalError("unable to exec '%s'", pCommand); } } else { - int res; - (void) close(pipefd[0]); outPipe = fdopen(pipefd[1], "w"); (void) TransferBytes(fp, outPipe, (int)statBuf.st_size); (void) fclose(outPipe); (void) fclose(fp); - (void) waitpid(childPid, &status, 0); + /* Wait for spooler child (and send all it's output to stderr) */ + Tailf(resfd, STDERR_FILENO, childPid, &status); + + if (status != EXIT_SUCCESS) + { + ErrorF("SendFileToCommand: spooler command returned non-zero status %d.\n", status); + } + + /* Store "xp-spooler-command-results" XPJobAttr that the + * client can fetch it on demand */ + if ((fstat(resfd, &statBuf) >= 0) && (statBuf.st_size >= 0)) + { + long bufSize; + char *buf; + + bufSize = statBuf.st_size; + + /* Clamp buffer size to 4MB to prevent that we allocate giant + * buffers if the spooler goes mad and spams it's stdout/stderr + * channel. */ + bufSize = MIN(bufSize, 4*1024*1024); + + buf = xalloc(bufSize+1); + if (buf != NULL) + { + bufSize = pread(resfd, buf, bufSize, 0); + buf[bufSize]='\0'; + + /* XXX: This should be converted from local multibyte encoding to + * Compound Text encoding first */ + XpPutOneAttribute(pContext, XPJobAttr, "xp-spooler-command-results", buf); + + xfree(buf); + } + } + else + { + ErrorF("SendFileToCommand: fstat() failed.\n"); + } + + fclose(resFp); } return; } /* * ReplaceAllKeywords causes all the predefined keywords (e.g. %options%) * to be replaced with the appropriate values derived from the attribute * store for the supplied print context. The ReplaceAnyString utility * routine is used to perform the actual replacements. */ extern char *ReplaceAnyString(char *, char *, char *); static char * ReplaceAllKeywords( XpContextPtr pContext, char *command) { char *cmdOpt; cmdOpt = XpGetOneAttribute(pContext, XPPrinterAttr, @@ -1466,41 +1583,41 @@ if(cmdNam == (char *)NULL) return BadAlloc; for(i = 0; vector[i] != (char *)NULL; i++) { vector[i] = ReplaceAllKeywords(pContext, vector[i]); if(vector[i] == (char *)NULL) { xfree(cmdNam); for(i = 0; vector[i] != (char *)NULL; i++) xfree(vector[i]); xfree(vector); return BadAlloc; } } userName = XpGetOneAttribute(pContext, XPJobAttr, "job-owner"); if(userName != (char *)NULL && strlen(userName) == 0) userName = (char *)NULL; - SendFileToCommand(fileName, cmdNam, vector, userName); + SendFileToCommand(pContext, fileName, cmdNam, vector, userName); FreeVector(vector); xfree(cmdNam); return Success; } /* * SearchInputTrays() * * Given a tray, return the medium in the tray. Conversely, given a * medium, return a tray in which it can be found. In either case, * return NULL if the given tray or medium cannot be found. */ #define TRAY 0 #define MEDIUM 1 static char * SearchInputTrays(XpContextPtr pCon, int which, Index: xc/programs/glxgears/glxgears.c =================================================================== RCS file: /cvs/xorg/xc/programs/glxgears/glxgears.c,v retrieving revision 1.10 diff -u -2 -0 -r1.10 glxgears.c --- xc/programs/glxgears/glxgears.c 7 Mar 2005 19:39:57 -0000 1.10 +++ xc/programs/glxgears/glxgears.c 11 Apr 2005 00:59:33 -0000 @@ -49,40 +49,41 @@ #include #endif /* BUILD_PRINTSUPPORT */ #include #include #include #include #include #include #include #include #include #include #ifndef M_PI #define M_PI 3.14159265 #endif /* !M_PI */ /* Turn a NULL pointer string into an empty string */ #define NULLSTR(x) (((x)!=NULL)?(x):("")) #define Log(x) { if(verbose) printf x; } +#define Msg(x) { printf x; } /* Globla vars */ static const char *ProgramName; /* program name (from argv[0]) */ static Bool verbose = False; /* verbose output what the program is doing */ static int xp_event_base, /* XpExtension even base */ xp_error_base; /* XpExtension error base */ static double degperpage = 5.0; /* Rotate gears degree per page */ #define TIMING 1 #ifdef TIMING /* XXX this probably isn't very portable */ /* return current time (in seconds) */ static long current_time(void) { struct timeval tv; @@ -105,40 +106,68 @@ static void usage(void) { fprintf (stderr, "usage: %s [options]\n", ProgramName); fprintf (stderr, "-display\tSet X11 display for output.\n"); #ifdef BUILD_PRINTSUPPORT fprintf (stderr, "-print\t\tUse printer instead of video card for output.\n"); fprintf (stderr, "-printer printername\tname of printer to use.\n"); fprintf (stderr, "-printfile printername\tOutput file for print job.\n"); fprintf (stderr, "-numpages count\tNumber of pages to print.\n"); fprintf (stderr, "-degperpage deg\tRotate gears degree per page.\n"); #endif /* BUILD_PRINTSUPPORT */ fprintf (stderr, "-info\t\tPrint additional GLX information.\n"); fprintf (stderr, "-singletooth\tDraw only one tooth for each gear (for debugging etc.).\n"); fprintf (stderr, "-h\t\tPrint this help page.\n"); fprintf (stderr, "-v\t\tVerbose output.\n"); fprintf (stderr, "\n"); exit(EXIT_FAILURE); } +#ifdef BUILD_PRINTSUPPORT +static +void PrintSpoolerCommandResults( Display *pdpy, XPContext pcontext ) +{ + char *scr; + + scr = XpGetOneAttribute(pdpy, pcontext, XPJobAttr, "xp-spooler-command-results"); + if( scr ) + { + if( strlen(scr) > 0 ) + { + const char *msg = XpuCompoundTextToXmb(pdpy, scr); + if( msg ) + { + Msg(("Spooler command returned '%s'.\n", msg)); + XpuFreeXmbString(msg); + } + else + { + Msg(("Spooler command returned '%s' (unconverted).\n", scr)); + } + } + + XFree((void *)scr); + } +} +#endif /* BUILD_PRINTSUPPORT */ + static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; static GLint gear1, gear2, gear3; static GLfloat angle = 0.0; static GLint speed = 60; static int singletooth = 0, paused = 0; static GLboolean printInfo = GL_FALSE; /* * * Draw a gear wheel. You'll probably want to call this function when * building a display list since we do a lot of trig here. * * Input: inner_radius - radius of hole at center * outer_radius - radius at center of teeth * width - width of gear * teeth - number of teeth * tooth_depth - depth of tooth */ static void gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, @@ -843,35 +872,37 @@ glXDestroyContext(dpy, ctx); #ifdef BUILD_PRINTSUPPORT if (doPrint) { /* End the print job - the final results are sent by the X print * server to the spooler sub system. */ XpEndJob(dpy); XpuWaitForPrintNotify(dpy, xp_event_base, XPEndJobNotify); Log(("end job.\n")); if (toFile) { if (XpuWaitForPrintFileChild(printtofile_handle) != XPGetDocFinished) { fprintf(stderr, "%s: Error while printing to file.\n", ProgramName); XpuClosePrinterDisplay(dpy, pcontext); return EXIT_FAILURE; } } + PrintSpoolerCommandResults(dpy, pcontext); + XDestroyWindow(dpy, win); XpuClosePrinterDisplay(dpy, pcontext); XpuFreePrinterList(plist); } else #endif /* BUILD_PRINTSUPPORT */ { XDestroyWindow(dpy, win); XCloseDisplay(dpy); } return EXIT_SUCCESS; } Index: xc/programs/xdbedizzy/xdbedizzy.c =================================================================== RCS file: /cvs/xorg/xc/programs/xdbedizzy/xdbedizzy.c,v retrieving revision 1.2 diff -u -2 -0 -r1.2 xdbedizzy.c --- xc/programs/xdbedizzy/xdbedizzy.c 3 Jan 2005 01:06:35 -0000 1.2 +++ xc/programs/xdbedizzy/xdbedizzy.c 11 Apr 2005 00:59:35 -0000 @@ -35,40 +35,41 @@ * Adapted to use DBE for double buffering by Allen Leinwand, 2/24/1995 . * Print support added by Roland Mainz, 10/18/2004 * */ #include #include #include #include #include #include #include #include #include #include #include /* Turn a NULL pointer string into an empty string */ #define NULLSTR(x) (((x)!=NULL)?(x):("")) #define Log(x) { if(verbose) printf x; } +#define Msg(x) { printf x; } /* Global variables */ static char *ProgramName = NULL; static Display *dpy = NULL; static Screen *screen = NULL; static int screennum = -1; static XPContext pcontext = None; /* Xprint context */ static XRectangle winrect = { 0 }; static unsigned long c_black, c_pink, c_green, c_orange, c_blue; static Window win = None; static XID buf = None; static XdbeSwapInfo swapInfo = { 0 }; static GC gc_black, gc_pink, gc_green, gc_orange, gc_blue; static float rotation = 0.0; static float delta = 0.05; static float speed = 20.0; static Bool paused = False; static Bool manual_paused = False; static int xp_event_base, /* XpExtension even base */ xp_error_base; /* XpExtension error base */ @@ -404,59 +405,59 @@ break; } break; case Expose: Log(("Expose: rendering.\n")); /* Swallow any extra Expose events (only needed for video * display, the Xprint server is non-interactive and * therefore cannot create extra Expose events caused * by user input) */ if (!doPrint) { while (XCheckTypedEvent(dpy, Expose, &event)) ; } redraw(); break; case ButtonPress: switch (event.xbutton.button) { case 1: - printf("ButtonPress: faster: %g\n", delta); + Msg(("ButtonPress: faster: %g\n", delta)); delta += 0.005; break; case 2: - printf("ButtonPress: slower: %g\n", delta); + Msg(("ButtonPress: slower: %g\n", delta)); delta += -0.005; break; case 3: if (manual_paused) { - printf("ButtonPress: manual resume.\n"); + Msg(("ButtonPress: manual resume.\n")); manual_paused = False; } else { - printf("ButtonPress: manual pause.\n"); + Msg(("ButtonPress: manual pause.\n")); manual_paused = True; } } break; case KeyPress: - printf("KeyPress: done.\n"); + Msg(("KeyPress: done.\n")); done = True; break; case ConfigureNotify: Log(("ConfigureNotify: resizing.\n")); winrect.width = event.xconfigure.width; winrect.height = event.xconfigure.height; break; } } } } int main(int argc, char *argv[]) { int i; XSetWindowAttributes attrs; Visual *visual; Colormap cmap; XGCValues gcvals; @@ -765,45 +766,68 @@ } /* Create GCs, one per color (to avoid pipeline flushing * when the GC is changed) */ gcvals.line_width = (8L * ((dpi_x+dpi_y)/2L)) / 100L; /* scale line with DPI */ gcvals.cap_style = CapRound; #define CREATECOLORGC(cl) (gcvals.foreground = (cl), \ XCreateGC(dpy, win, GCForeground | GCLineWidth | GCCapStyle, &gcvals)) gc_black = CREATECOLORGC(c_black); gc_pink = CREATECOLORGC(c_pink); gc_green = CREATECOLORGC(c_green); gc_orange = CREATECOLORGC(c_orange); gc_blue = CREATECOLORGC(c_blue); #undef CREATECOLORGC XMapWindow(dpy, win); main_loop(); if (doPrint) { + char *scr; + /* End the print job - the final results are sent by the X print * server to the spooler sub system. */ Log(("finishing print job.\n")); + /* Job completed, check if there are any messages from the spooler command */ + scr = XpGetOneAttribute(dpy, pcontext, XPJobAttr, "xp-spooler-command-results"); + if( scr ) + { + if( strlen(scr) > 0 ) + { + const char *msg = XpuCompoundTextToXmb(dpy, scr); + if( msg ) + { + Msg(("Spooler command returned:\n%s", msg)); + XpuFreeXmbString(msg); + } + else + { + Msg(("Spooler command returned (unconverted):\n%s", scr)); + } + } + + XFree((void *)scr); + } + if (toFile) { if (XpuWaitForPrintFileChild(printtofile_handle) != XPGetDocFinished) { fprintf(stderr, "%s: Error while printing to file.\n", ProgramName); XpuClosePrinterDisplay(dpy, pcontext); return EXIT_FAILURE; } } XDestroyWindow(dpy, win); XpuClosePrinterDisplay(dpy, pcontext); XpuFreePrinterList(plist); } else { XDestroyWindow(dpy, win); XCloseDisplay(dpy); } Log(("Done.")); Index: xc/programs/xedit/Imakefile =================================================================== RCS file: /cvs/xorg/xc/programs/xedit/Imakefile,v retrieving revision 1.6 diff -u -2 -0 -r1.6 Imakefile --- xc/programs/xedit/Imakefile 2 Sep 2004 08:40:32 -0000 1.6 +++ xc/programs/xedit/Imakefile 11 Apr 2005 00:59:35 -0000 @@ -27,41 +27,41 @@ LISPLIBS = -Llisp -llisp -Llisp/mp -lmp -Llisp/re -lre LISP_SRC = lisp.c LISP_OBJ = lisp.o DEPLIBS = XawClientDepLibs $(SUBDIRS) LOCAL_LIBRARIES = $(LISPLIBS) $(PRINT_LIBS) XawClientLibs $(DLLIB) SYS_LIBRARIES = MathLibrary #if defined(LynxOSArchitecture) || defined(SVR3Architecture) || defined(LinuxArchitecture) RP_SRCS = realpath.c RP_OBJS = realpath.o RP_DEFINES = -DNEED_REALPATH #endif #if !HasStrcasecmp STRCCMP_SRCS = strcasecmp.c STRCCMP_OBJS = strcasecmp.o STRCCMP_DEFINES = -DNEED_STRCASECMP #endif SYS_SRCS = $(RP_SRCS) $(STRCCMP_SRCS) SYS_OBJS = $(RP_OBJS) $(STRCCMP_OBJS) SYS_DEFINES = $(RP_DEFINES) $(STRCCMP_DEFINES) - DEFINES = $(PRINT_DEFS) $(SIGNAL_DEFINES) $(SYS_DEFINES) + DEFINES = $(PRINT_DEFS) $(SIGNAL_DEFINES) $(SYS_DEFINES) -DXEDIT INCLUDES = -I. -Ilisp/re $(MISC_INCLUDES) SRCS = xedit.c commands.c util.c $(SYS_SRCS) ispell.c options.c \ hook.c $(PRINT_SRCS) $(LISP_SRC) OBJS = xedit.o commands.o util.o $(SYS_OBJS) ispell.o options.o \ hook.o $(PRINT_OBJS) $(LISP_OBJ) #ifdef XEditUseXprint LinkSourceFile(printdialog.c,../xmore) LinkSourceFile(printdialog.h,../xmore) LinkSourceFile(printdialogprivates.h,../xmore) LinkSourceFile(print.c,../xmore) LinkSourceFile(print.h,../xmore) LinkFile(Xedit.ad,Xedit-xprint.ad) #else LinkFile(Xedit.ad,Xedit-noxprint.ad) #endif /* XEditUseXprint */ #ifdef IHaveSubdirs ForceSubdirs($(SUBDIRS)) Index: xc/programs/xedit/Xedit-xprint.ad =================================================================== RCS file: /cvs/xorg/xc/programs/xedit/Xedit-xprint.ad,v retrieving revision 1.2 diff -u -2 -0 -r1.2 Xedit-xprint.ad --- xc/programs/xedit/Xedit-xprint.ad 3 Jan 2005 01:06:35 -0000 1.2 +++ xc/programs/xedit/Xedit-xprint.ad 11 Apr 2005 00:59:35 -0000 @@ -54,41 +54,41 @@ *positionWindow.label: error *positionWindow.justify: left *labelWindow*justify: center *labelWindow*label: no file yet *labelWindow.left: chainLeft *labelWindow.right: chainRight *quit.label: Quit *quit.tip: Close xedit window *save.label: Save *save.tip: Save current file *load.label: Load *load.tip: Load a new file *print.label: Print *print.tip: Print current file *buttons*orientation: horizontal *buttons*showGrip: False *buttons.min: 18 -*messageWindow.height: 50 +*messageWindow.height: 70 *messageWindow.min: 18 *Paned*Text*allowResize: True *messageWindow.autoFill: False *messageWindow.scrollVertical: Never *editWindow.autoFill: False *editWindow.scrollVertical: Always *editWindow.showGrip: True xedit.textSource*enableUndo: True *bc_label*label: Use Control-S and Control-R to Search. *bc_label*showGrip: False *bc_label.min: 18 *dirlabel.showGrip: False *dirlabel.min: 18 *dirlabel.max: 18 *dirwindow.defaultColumns: 0 @@ -136,46 +136,48 @@ *editMenu.modeMenuItem.label: Edit Mode *editModes.none.label: Plain/None *TransientShell*Text.translations: #override \ cS: no-op(r)\n\ cR: no-op(r)\n\ mI: no-op(r) *search.translations: #override \ :get-values(my, $w, width, $h, height)\ set-values(1, minWidth, $w, minHeight, $h, maxHeight, $h, allowShellResize, False) *insertFile.title: Insert File *insertFile.translations: #override \ :get-values(my, $w, width, $h, height)\ set-values(1, minWidth, $w, minHeight, $h, maxHeight, $h, allowShellResize, False) *baseTranslations: #override \ X,C:quit()\n\ X,S:save-file()\n\ +X,P:print-file()\n\ X,F:find-file()\n\ Escape: line-edit() *messageWindow.Translations: #override \ X,C:quit()\n\ X,S:save-file()\n\ +X,P:print-file()\n\ X,F:find-file()\n\ : no-op()\n\ : no-op()\n\ : set-keyboard-focus() select-start() *searchText.Translations: #override \ : no-op()\n\ : no-op()\n\ : set-keyboard-focus() select-start() *replaceText.Translations: #override \ : no-op()\n\ : no-op()\n\ : set-keyboard-focus() select-start() *editWindow.translations: #override \ X,E:lisp-eval()\n\ X,Tab:indent()\n\ X,:0:delete-window(current)\n\ X,:1:delete-window(other)\n\ @@ -229,41 +231,40 @@ c @Num_Lock:xedit-focus() popup-menu(fileMenu)\n\ c l: xedit-focus() popup-menu(fileMenu)\n\ c: xedit-focus() popup-menu(fileMenu)\n\ c l @Num_Lock:xedit-focus() popup-menu(editMenu)\n\ c @Num_Lock:xedit-focus() popup-menu(editMenu)\n\ c l: xedit-focus() popup-menu(editMenu)\n\ c: xedit-focus() popup-menu(editMenu)\n\ c l @Num_Lock:xedit-focus() popup-menu(optionsMenu)\n\ c @Num_Lock:xedit-focus() popup-menu(optionsMenu)\n\ c l:xedit-focus() popup-menu(optionsMenu)\n\ c: xedit-focus() popup-menu(optionsMenu)\n\ : xedit-focus() select-start() *filename.?.pieceSize: 256 *filename.translations: #override \ cS: no-op(r)\n\ cR: no-op(r)\n\ mI: no-op(r)\n\ cG: cancel-find-file()\n\ Return: load-file()\n\ -P: print-file()\n\ Tab: file-completion(h)\n\ Escape: cancel-find-file()\n\ : no-op()\n\ : no-op()\n\ : set-keyboard-focus() select-start() *ispell.translations: #override \ WM_PROTOCOLS: ispell(end) ! Sample dictionary, word chars and text mode resources setup !*ispell.dictionary: br !*ispell.dictionaries: br american americanmed+ english !*ispell*br.wordChars: áéíóúçÁÉÍÓÚÇàÀâêôÂÊÔüÜãõÃÕ- !*ispell.ispellCommand: /usr/local/bin/ispell -B -m !*ispell*text.skipLines: .# *ispell.geometry: 0x0 *ispell.minWidth: 320 *ispell.minHeight: 245 *ispell*Label.borderWidth: 0 Index: xc/programs/xedit/util.c =================================================================== RCS file: /cvs/xorg/xc/programs/xedit/util.c,v retrieving revision 1.3 diff -u -2 -0 -r1.3 util.c --- xc/programs/xedit/util.c 2 Sep 2004 08:40:32 -0000 1.3 +++ xc/programs/xedit/util.c 11 Apr 2005 00:59:35 -0000 @@ -40,58 +40,88 @@ /* * Prototypes */ static void SwitchSourceCallback(Widget, XtPointer, XtPointer); static int WindowIndex(Widget); static void ChangeTextWindow(Widget); /* * External */ extern void _XawTextShowPosition(TextWidget); /* * Initialization */ extern Widget scratch; extern Widget vpanes[2], labels[3], texts[3], forms[3]; extern XawTextWrapMode wrapmodes[3]; +#ifndef va_copy +# ifdef __va_copy +# define va_copy __va_copy +# else +# error "no working va_copy was found" +# endif +#endif + /* * Implementation */ void -XeditPrintf(char *str) +XeditPrintf(const char *format, ...) { - XawTextBlock text; + char *str; + size_t size; + va_list va, + va2; + XawTextBlock text; + + va_start(va, format); + + va_copy(va2, va); + size = vsnprintf(NULL, 0, format, va2); + va_end(va2); + + str = (char *)malloc(size + 1); + if (str == NULL) + return; + + vsnprintf(str, size + 1, format, va); + str[size] = 0; + + va_end(va); + XawTextPosition pos = XawTextSourceScan(XawTextGetSource(messwidget), 0, XawstAll, XawsdRight, 1, True); text.length = strlen(str); text.ptr = str; text.firstPos = 0; text.format = FMT8BIT; XawTextReplace(messwidget, pos, pos, &text); XawTextSetInsertionPoint(messwidget, pos + text.length); + + free(str); } Widget MakeCommandButton(Widget box, char *name, XtCallbackProc function) { Widget w = XtCreateManagedWidget(name, commandWidgetClass, box, NULL, ZERO); if (function != NULL) XtAddCallback(w, XtNcallback, function, (caddr_t) NULL); else XtVaSetValues(w, XtNsensitive, False, NULL); return w; } Widget MakeStringBox(Widget parent, String name, String string) { Arg args[5]; Cardinal numargs = 0; Widget StringW; Index: xc/programs/xedit/xedit.h =================================================================== RCS file: /cvs/xorg/xc/programs/xedit/xedit.h,v retrieving revision 1.5 diff -u -2 -0 -r1.5 xedit.h --- xc/programs/xedit/xedit.h 2 Sep 2004 08:40:32 -0000 1.5 +++ xc/programs/xedit/xedit.h 11 Apr 2005 00:59:35 -0000 @@ -12,40 +12,42 @@ * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR * ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. * * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS, * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT * SET FORTH ABOVE. * * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Digital Equipment Corporation not be * used in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. */ /* $XFree86: xc/programs/xedit/xedit.h,v 1.17 2002/10/06 17:11:39 paulo Exp $ */ #include +#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* for the property list definition */ #include @@ -89,41 +91,41 @@ extern Widget options_popup; extern struct _app_resources { Boolean enableBackups; char *backupNamePrefix; char *backupNameSuffix; xedit_hints hints; char *changed_pixmap_name; char *position_format; char *auto_replace; } app_resources; extern Widget topwindow, textwindow, labelwindow, filenamewindow, messwidget; extern Widget dirlabel, dirwindow; extern Boolean line_edit; /* externals in xedit.c */ void Feep(void); /* externals in util.c */ -void XeditPrintf(char*); +void XeditPrintf(const char *format, ...); Widget MakeCommandButton(Widget, char*, XtCallbackProc); Widget MakeStringBox(Widget, String, String); String GetString(Widget); FileAccess MaybeCreateFile(char*), CheckFilePermissions(char*, Boolean*); xedit_flist_item *AddTextSource(Widget, String, String, int, FileAccess); xedit_flist_item *FindTextSource(Widget, char*); Bool KillTextSource(xedit_flist_item*); char *ResolveName(char*); void DeleteWindow(Widget, XEvent*, String*, Cardinal*); void SplitWindow(Widget, XEvent*, String*, Cardinal*); void SwitchTextSource(xedit_flist_item*); void PopupMenu(Widget, XEvent*, String*, Cardinal*); void OtherWindow(Widget, XEvent*, String*, Cardinal*); void SwitchSource(Widget, XEvent*, String*, Cardinal*); void XeditFocus(Widget, XEvent*, String*, Cardinal*); void SwitchDirWindow(Bool); void DirWindow(Widget, XEvent*, String*, Cardinal*); /* externs in commands.c */ void DoQuit(Widget, XtPointer, XtPointer); Index: xc/programs/xlogo/print.c =================================================================== RCS file: /cvs/xorg/xc/programs/xlogo/print.c,v retrieving revision 1.2 diff -u -2 -0 -r1.2 print.c --- xc/programs/xlogo/print.c 3 Jan 2005 01:06:35 -0000 1.2 +++ xc/programs/xlogo/print.c 11 Apr 2005 00:59:36 -0000 @@ -94,47 +94,70 @@ AppPrintData *p = (AppPrintData *)client_data; Log(("--> PageSetupCB\n")); if (!psp->last_page_in_job) { Widget plogo; Log(("Creating print logo\n")); plogo = XtCreateManagedWidget("xlogo", logoWidgetClass, pshell, NULL, ZERO); /* Make sure that the Xt machinery is really using the right screen (assertion) */ if (XpGetScreenOfContext(XtDisplay(plogo), p->pcontext) != XtScreen(plogo)) Error(("Widget's screen != print screen. BAD.\n")); /* XLogo always only prints one page */ psp->last_page_in_job = True; } } void FinishPrinting(AppPrintData *p) { + char *scr; + if (p->printtofile_handle) { if (XpuWaitForPrintFileChild(p->printtofile_handle) != XPGetDocFinished) { fprintf(stderr, "%s: Error while printing to file.\n", ProgramName); } p->printtofile_handle = NULL; } + /* Job completed, check if there are any messages from the spooler command */ + scr = XpGetOneAttribute(p->pdpy, p->pcontext, XPJobAttr, "xp-spooler-command-results"); + if( scr ) + { + if( strlen(scr) > 0 ) + { + const char *msg = XpuCompoundTextToXmb(p->pdpy, scr); + if( msg ) + { + Msg(("Spooler command returned '%s'.\n", msg)); + XpuFreeXmbString(msg); + } + else + { + Msg(("Spooler command returned '%s' (unconverted).\n", scr)); + } + } + + XFree((void *)scr); + } + 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); } /* "Print once and exit"-mode ? */ if (userOptions.printAndExit) { XtAppSetExitFlag(XtWidgetToApplicationContext(p->toplevel)); } p->toplevel = NULL; p->isPrinting = False; Index: xc/programs/xlogo/xlogo.c =================================================================== RCS file: /cvs/xorg/xc/programs/xlogo/xlogo.c,v retrieving revision 1.6 diff -u -2 -0 -r1.6 xlogo.c --- xc/programs/xlogo/xlogo.c 2 Sep 2004 05:50:38 -0000 1.6 +++ xc/programs/xlogo/xlogo.c 11 Apr 2005 00:59:36 -0000 @@ -40,63 +40,65 @@ #include #endif #include #include /* Global vars*/ const char *ProgramName; /* program name (from argv[0]) */ static void quit(Widget w, XEvent *event, String *params, Cardinal *num_params); #ifdef INCLUDE_XPRINT_SUPPORT static void print(Widget w, XEvent *event, String *params, Cardinal *num_params); #endif /* INCLUDE_XPRINT_SUPPORT */ static XrmOptionDescRec options[] = { { "-shape", "*shapeWindow", XrmoptionNoArg, (XPointer) "on" }, #ifdef XRENDER {"-render", "*render",XrmoptionNoArg, "TRUE"}, {"-sharp", "*sharp", XrmoptionNoArg, "TRUE"}, #endif {"-v", "Verbose", XrmoptionNoArg, "TRUE"}, +{"-q", "Quiet", XrmoptionNoArg, "TRUE"}, #ifdef INCLUDE_XPRINT_SUPPORT {"-print", "Print", XrmoptionNoArg, "TRUE"}, {"-printer", "printer", XrmoptionSepArg, NULL}, {"-printfile", "printFile", XrmoptionSepArg, NULL}, #endif /* INCLUDE_XPRINT_SUPPORT */ }; static XtActionsRec actions[] = { {"quit", quit }, #ifdef INCLUDE_XPRINT_SUPPORT {"print", print} #endif /* INCLUDE_XPRINT_SUPPORT */ }; static Atom wm_delete_window; /* See xlogo.h */ XLogoResourceData userOptions; #define Offset(field) XtOffsetOf(XLogoResourceData, field) XtResource resources[] = { {"verbose", "Verbose", XtRBoolean, sizeof(Boolean), Offset(verbose), XtRImmediate, (XtPointer)False}, + {"quiet", "Quiet", XtRBoolean, sizeof(Boolean), Offset(quiet), XtRImmediate, (XtPointer)False}, #ifdef INCLUDE_XPRINT_SUPPORT {"print", "Print", XtRBoolean, sizeof(Boolean), Offset(printAndExit), XtRImmediate, (XtPointer)False}, {"printer", "Printer", XtRString, sizeof(String), Offset(printername), XtRImmediate, (XtPointer)NULL}, {"printFile", "PrintFile", XtRString, sizeof(String), Offset(printfile), XtRImmediate, (XtPointer)NULL} #endif /* INCLUDE_XPRINT_SUPPORT */ }; String fallback_resources[] = { "*iconPixmap: xlogo32", "*iconMask: xlogo32", "*baseTranslations: #override \\" #ifdef INCLUDE_XPRINT_SUPPORT "\tq: quit()\\n\\" "\tp: print()", #else /* !INCLUDE_XPRINT_SUPPORT */ "\tq: quit()", #endif /* !INCLUDE_XPRINT_SUPPORT */ NULL, }; @@ -111,40 +113,41 @@ save(Widget w, XtPointer client_data, XtPointer call_data) { return; } /* * Report the syntax for calling xlogo. */ static void Syntax(Widget toplevel) { Arg arg; SmcConn connection; String reasons[10]; int i, n = 0; reasons[n++] = "Usage: "; reasons[n++] = (String)ProgramName; reasons[n++] = " [-fg ] [-bg ] [-rv] [-bw ] [-bd ]\n"; + reasons[n++] = " [-v] [-q]\n"; reasons[n++] = " [-d []:[]]\n"; reasons[n++] = " [-g [][x][<+->[<+->]]]\n"; #ifdef INCLUDE_XPRINT_SUPPORT reasons[n++] = " [-print] [-printname ] [-printfile ]\n"; #endif /* INCLUDE_XPRINT_SUPPORT */ #ifdef XRENDER reasons[n++] = " [-render] [-sharp]\n"; #endif /* XRENDER */ reasons[n++] = " [-shape]\n\n"; XtSetArg(arg, XtNconnection, &connection); XtGetValues(toplevel, &arg, (Cardinal)1); if (connection) SmcCloseConnection(connection, n, reasons); else { for (i=0; i < n; i++) printf(reasons[i]); } exit(EXIT_FAILURE); } Index: xc/programs/xlogo/xlogo.h =================================================================== RCS file: /cvs/xorg/xc/programs/xlogo/xlogo.h,v retrieving revision 1.1 diff -u -2 -0 -r1.1 xlogo.h --- xc/programs/xlogo/xlogo.h 9 May 2004 00:36:41 -0000 1.1 +++ xc/programs/xlogo/xlogo.h 11 Apr 2005 00:59:36 -0000 @@ -18,34 +18,36 @@ 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 XLOGO_XLOGO_H #define XLOGO_XLOGO_H 1 #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 Log(x) { if(userOptions.verbose) printf x; } +#define Msg(x) { if((!userOptions.quiet) || userOptions.verbose) printf x; } typedef struct { Boolean verbose; + Boolean quiet; Boolean printAndExit; String printername; String printfile; } XLogoResourceData, *XLogoResourceDataPtr; /* Global vars */ extern const char *ProgramName; /* program name (from argv[0]) */ extern XLogoResourceData userOptions; #endif /* !XLOGO_XLOGO_H */ Index: xc/programs/xman/Imakefile =================================================================== RCS file: /cvs/xorg/xc/programs/xman/Imakefile,v retrieving revision 1.6 diff -u -2 -0 -r1.6 Imakefile --- xc/programs/xman/Imakefile 2 Sep 2004 08:40:33 -0000 1.6 +++ xc/programs/xman/Imakefile 11 Apr 2005 00:59:36 -0000 @@ -47,41 +47,41 @@ #if HasSnprintf SNPDEFINES = -DHAS_SNPRINTF #else SNPDEFINES = -Dsnprintf=XmuSnprintf #endif #ifdef XmanUseXprint PRINT_LIBS = -lXprintUtil $(XPLIB) PRINT_DEFS = -DINCLUDE_XPRINT_SUPPORT PRINT_SRCS = printdialog.c print.c PRINT_OBJS = printdialog.o print.o #endif /* XmanUseXprint */ OSMAJORVERSION = OSMajorVersion OSMINORVERSION = OSMinorVersion DEFINES = -DOSMAJORVERSION=$(OSMAJORVERSION) \ -DOSMINORVERSION=$(OSMINORVERSION) \ $(SNPDEFINES) $(HELPFILE) $(MANPATHS) $(MKSTEMP) $(GROFF) \ - $(PRINT_DEFS) $(MANCONFIGSTYLE) $(MANCONF) + $(PRINT_DEFS) $(MANCONFIGSTYLE) $(MANCONF) -DXMAN DEPLIBS = XawClientDepLibs LOCAL_LIBRARIES = $(PRINT_LIBS) XawClientLibs SRCS = ScrollByL.c handler.c man.c buttons.c help.c \ $(PRINT_SRCS) search.c globals.c main.c \ misc.c tkfuncs.c vendor.c OBJS = ScrollByL.o handler.o man.o buttons.o help.o \ $(PRINT_OBJS) search.o globals.o main.o \ misc.o tkfuncs.o vendor.o #ifdef XmanUseXprint LinkSourceFile(printdialog.c,../xmore) LinkSourceFile(printdialog.h,../xmore) LinkSourceFile(printdialogprivates.h,../xmore) LinkFile(Xman.ad,Xman-xprint.ad) #else LinkFile(Xman.ad,Xman-noxprint.ad) #endif /* XmanUseXprint */ ComplexProgramTarget(xman) Index: xc/programs/xman/print.h =================================================================== RCS file: /cvs/xorg/xc/programs/xman/print.h,v retrieving revision 1.2 diff -u -2 -0 -r1.2 print.h --- xc/programs/xman/print.h 3 Jan 2005 01:06:35 -0000 1.2 +++ xc/programs/xman/print.h 11 Apr 2005 00:59:36 -0000 @@ -18,31 +18,33 @@ 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 XMAN_PRINT_H #define XMAN_PRINT_H 1 #include #include #include #include #include #include +#define PrintMsg(x) { printf("xman: "); printf x ; } + /* Prototypes */ void DoPrintManpage(const char *programname, FILE *manpage, Widget toplevel, Display *pdpy, XPContext pcontext, XpuColorspaceRec *colorspace, XtCallbackProc printDisplayDestroyCallback, const char *jobTitle, const char *toFile); #endif /* !XMAN_PRINT_H */ Index: xc/programs/xmore/Imakefile =================================================================== RCS file: /cvs/xorg/xc/programs/xmore/Imakefile,v retrieving revision 1.2 diff -u -2 -0 -r1.2 Imakefile --- xc/programs/xmore/Imakefile 21 Jun 2004 14:32:46 -0000 1.2 +++ xc/programs/xmore/Imakefile 11 Apr 2005 00:59:36 -0000 @@ -1,18 +1,19 @@ XCOMM $Xorg: Imakefile,v 1.1 2004/05/09 07:54:52 gisburn Exp $ DEPLIBS = XawClientDepLibs XkbClientDepLibs LOCAL_LIBRARIES = -lXprintUtil $(XPLIB) XawClientLibs XkbClientLibs SRCS = xmore.c print.c printdialog.c OBJS = xmore.o print.o printdialog.o HEADERS = CDEBUGFLAGS = -g + DEFINES = -DXMORE ComplexProgramTarget(xmore) InstallAppDefaults(XMore) #ifdef HasDocBookTools all:: xmore.man xmore.html ConvertDocBookToManPage(xmore.sgml, xmore.man) ConvertDocBookToHTML(xmore.sgml, xmore.html) #endif /* HasDocBookTools */ Index: xc/programs/xmore/print.c =================================================================== RCS file: /cvs/xorg/xc/programs/xmore/print.c,v retrieving revision 1.6 diff -u -2 -0 -r1.6 print.c --- xc/programs/xmore/print.c 3 Jan 2005 01:06:36 -0000 1.6 +++ xc/programs/xmore/print.c 11 Apr 2005 00:59:37 -0000 @@ -15,40 +15,43 @@ 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; } +#ifdef XEDIT +#include "xedit.h" +#endif /* XEDIT */ #include "print.h" #include #include #include #include #include static Widget CreatePrintShell(Widget videoshell, Screen *pscreen, Visual *pvisual, String printshell_name, ArgList args, Cardinal numargs) { String videoname, videoclass; Widget pappshell, printshell; Display *pdpy = XDisplayOfScreen(pscreen); @@ -164,47 +167,70 @@ /* 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; } } } static void FinishPrinting(AppPrintData *p) { + char *scr; + if (p->printtofile_handle) { if (XpuWaitForPrintFileChild(p->printtofile_handle) != XPGetDocFinished) { - fprintf(stderr, "%s: Error while printing to file.\n", apd->programname); + PrintMsg(("Error while printing to file.\n")); } p->printtofile_handle = NULL; - } + } + + /* Job completed, check if there are any messages from the spooler command */ + scr = XpGetOneAttribute(p->pdpy, p->pcontext, XPJobAttr, "xp-spooler-command-results"); + if( scr ) + { + if( strlen(scr) > 0 ) + { + const char *msg = XpuCompoundTextToXmb(p->pdpy, scr); + if( msg ) + { + PrintMsg(("Spooler command returned:\n%s", msg)); + XpuFreeXmbString(msg); + } + else + { + PrintMsg(("Spooler command returned (unconverted):\n%s", scr)); + } + } + XFree((void *)scr); + } + if (p->printshell) { XtDestroyWidget(p->printshell); p->printshell = NULL; } /* Two issues here: * 1. The print display connection is owned by the print dialog * To avoid any problems with that use a callback back to the main * application which calls * |XawPrintDialogClosePrinterConnection(w, False)| to ask the * print dialog widget to close all print display resources and * disown the object. * 2. We have to use XpDestroyContext() and XtCloseDisplay() * instead of XpuClosePrinterDisplay() to make libXt happy... * * Call callback... */ (*apd->pdpyDestroyCallback)(NULL, NULL, NULL); /* HACK! */ /* ... and then get rid of the display */ if (p->pcontext != None) { @@ -271,56 +297,56 @@ } void DoPrintTextSource(const char *programname, Widget textsource, Widget toplevel, Display *pdpy, XPContext pcontext, XpuColorspaceRec *colorspace, XtCallbackProc pdpyDestroyCB, const char *jobtitle, const char *toFile) { long dpi_x = 0L, dpi_y = 0L; int n; Arg args[20]; XFontSet textfontset = NULL; XFontSetExtents *font_extents; apd->programname = programname; apd->pdpyDestroyCallback = pdpyDestroyCB; if (apd->isPrinting) { - fprintf(stderr, "%s: Already busy with printing.\n", apd->programname); + PrintMsg(("Already busy with printing.\n")); 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_x, &dpi_y) != 1) { - fprintf(stderr, "%s: No default resolution for printer.\n", apd->programname); + PrintMsg(("No default resolution for printer.\n")); XpuClosePrinterDisplay(pdpy, pcontext); return; } apd->toplevel = toplevel; apd->pdpy = pdpy; apd->pcontext = pcontext; apd->pscreen = XpGetScreenOfContext(pdpy, pcontext); apd->jobtitle = jobtitle; n = 0; /* Override any geometry resource settings as XawPrintShell adjusts it's size * to the current page siue when |XawPrintLAYOUTMODE_DRAWABLEAREA| or * |XawPrintLAYOUTMODE_PAGESIZE| are used. */ XtSetArg(args[n], XtNgeometry, "+0+0"); n++; XtSetArg(args[n], XawNlayoutMode, XawPrintLAYOUTMODE_DRAWABLEAREA); n++; if (colorspace) { printf("Setting visual to id=0x%lx.\n", colorspace->visualinfo.visualid); } apd->printshell = CreatePrintShell(toplevel, apd->pscreen, @@ -373,36 +399,37 @@ /* 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", apd->programname, toFile); + PrintMsg(("Printing to file '%s'...\n", toFile)); apd->printtofile_handle = XpuStartJobToFile(pdpy, pcontext, toFile); if (!apd->printtofile_handle) { perror("XpuStartJobToFile failure"); + PrintMsg(("Printing failed: XpuStartJobToFile\n")); apd->isPrinting = False; return; } } else { - printf("%s: Printing to printer...\n", apd->programname); + PrintMsg(("Printing to printer...\n")); XpuStartJobToSpooler(pdpy); } } Index: xc/programs/xmore/print.h =================================================================== RCS file: /cvs/xorg/xc/programs/xmore/print.h,v retrieving revision 1.4 diff -u -2 -0 -r1.4 print.h --- xc/programs/xmore/print.h 3 Jan 2005 01:06:36 -0000 1.4 +++ xc/programs/xmore/print.h 11 Apr 2005 00:59:37 -0000 @@ -18,31 +18,39 @@ 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 +#if defined(XMORE) +#define PrintMsg(x) { printf("xmore: "); printf x ; } +#elif defined(XEDIT) +#define PrintMsg(x) { XeditPrintf x ; } +#else +#error unknown application +#endif + /* Prototypes */ void DoPrintTextSource(const char *programname, Widget textsource, Widget toplevel, Display *pdpy, XPContext pcontext, XpuColorspaceRec *colorspace, XtCallbackProc printDisplayDestroyCallback, const char *jobTitle, const char *toFile); #endif /* !XMORE_PRINT_H */ Index: xc/programs/xmore/printdialog.c =================================================================== RCS file: /cvs/xorg/xc/programs/xmore/printdialog.c,v retrieving revision 1.5 diff -u -2 -0 -r1.5 printdialog.c --- xc/programs/xmore/printdialog.c 3 Jan 2005 01:06:36 -0000 1.5 +++ xc/programs/xmore/printdialog.c 11 Apr 2005 00:59:37 -0000 @@ -27,40 +27,43 @@ /* Force ANSI C prototypes from X11 headers */ #ifndef FUNCPROTO #define FUNCPROTO 15 #endif /* !FUNCPROTO */ #include #include #include #include #include #include #include #include #include #ifdef XKB #include #endif /* XKB */ +#ifdef XEDIT +#include "xedit.h" +#endif /* XEDIT */ #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 } } #ifdef DEBUG # define Log(x) { if(True) printf x; } #else # define Log(x) { if(False) printf x; } #endif /* DEBUG */ /* Local prototypes */ @@ -1007,43 +1010,42 @@ 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; } } else { - XtAppWarning(XtWidgetToApplicationContext(w), - "No Xprint servers could be found. " - "Check whether the XPSERVERLIST environment variable contains any valid Xprint server(s)."); + PrintMsg(("No Xprint servers could be found.\n" + "Check whether the XPSERVERLIST environment variable contains any valid Xprint server(s).\n")); } n = 0; XtSetArg(args[n], XtNborderWidth, 0); n++; pdp->main.form = XtCreateManagedWidget("main", formWidgetClass, (Widget)pdw, args, n); n = 0; pdp->main.innerform = XtCreateManagedWidget("innerform", formWidgetClass, pdp->main.form, args, n); n = 0; 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++; pdp->main.desclabel = XtCreateManagedWidget("desclabel", labelWidgetClass, pdp->main.innerform, args, n); n = 0; XtSetArg(args[n], XtNborderWidth, 0); n++; XtSetArg(args[n], XtNresizable, False); n++; XtSetArg(args[n], XtNjustify, XtJustifyLeft); n++; Index: xc/programs/xphelloworld/xpawhelloworld/xpawhelloworld.c =================================================================== RCS file: /cvs/xorg/xc/programs/xphelloworld/xpawhelloworld/xpawhelloworld.c,v retrieving revision 1.4 diff -u -2 -0 -r1.4 xpawhelloworld.c --- xc/programs/xphelloworld/xpawhelloworld/xpawhelloworld.c 3 Jan 2005 01:06:36 -0000 1.4 +++ xc/programs/xphelloworld/xpawhelloworld/xpawhelloworld.c 11 Apr 2005 00:59:38 -0000 @@ -35,67 +35,96 @@ * */ #include #include #include #include #include #include #include #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 Log(x) { if(verbose) printf x; } +#define Msg(x) { if(!quiet) printf x; } /* Prototypes */ static int do_hello_world( int argc, char *argv[], const char *printername, const char *toFile, const char *sample_string ); /* Global vars */ const char *ProgramName; /* program name (from argv[0]) */ Bool verbose = False; /* verbose output what the program is doing */ +Bool quiet = False; /* be quiet (no output except errors) */ Bool doPrint = False; /* Do we print on a printer ? */ Display *pdpy = NULL; /* (Paper) display */ Screen *pscreen = NULL; /* (Paper) screen (DDX-specific!) */ XPContext pcontext = None; /* Xprint context */ void *printtofile_handle = NULL; /* XprintUtil "context" when printing to file */ Drawable pdrawable = None; /* paper drawable */ static void usage( void ) { fprintf(stderr, "usage: %s [options] string\n", ProgramName); fprintf(stderr, "-print\tPrint via Xprint instead of displaying on the Xserver\n"); fprintf(stderr, "-printer printernname\tprinter to use\n"); fprintf(stderr, "-printfile file\tprint to file instead of printer\n"); fprintf(stderr, "-v\tverbose output\n"); + fprintf(stderr, "-q\tbe quiet (no output except errors)\n"); fprintf(stderr, "\n"); exit(EXIT_FAILURE); } +static +void PrintSpoolerCommandResults( Display *pdpy, XPContext pcontext ) +{ + char *scr; + + scr = XpGetOneAttribute(pdpy, pcontext, XPJobAttr, "xp-spooler-command-results"); + if( scr ) + { + if( strlen(scr) > 0 ) + { + const char *msg = XpuCompoundTextToXmb(pdpy, scr); + if( msg ) + { + Msg(("Spooler command returned '%s'.\n", msg)); + XpuFreeXmbString(msg); + } + else + { + Msg(("Spooler command returned '%s' (unconverted).\n", scr)); + } + } + + XFree((void *)scr); + } +} + int main( int argc, char *argv[] ) { const char *printername = NULL; /* printer to query */ const char *toFile = NULL; /* output file (instead of printer) */ XPPrinterList plist; /* list of printers */ int plist_count; /* number of entries in |plist|-array */ int i; int retval; const char *sample_string; ProgramName = argv[0]; if( argc < 2 ) { usage(); } for( i = 1 ; i < (argc-1) ; i++ ) { char *arg = argv[i]; @@ -105,40 +134,46 @@ { doPrint = True; } else if (!strncmp("-printer", arg, len)) { if (++i >= argc) usage(); printername = argv[i]; doPrint = True; } else if (!strncmp("-printfile", arg, len)) { if (++i >= argc) usage(); toFile = argv[i]; doPrint = True; } else if (!strncmp("-v", arg, len)) { verbose = True; + quiet = False; + } + else if (!strncmp("-q", arg, len)) + { + verbose = False; + quiet = True; } else { usage(); } } sample_string = argv[argc-1]; if( doPrint ) { plist = XpuGetPrinterList(printername, &plist_count); if (!plist) { fprintf(stderr, "%s: no printers found for printer spec \"%s\".\n", ProgramName, NULLSTR(printername)); exit(EXIT_FAILURE); } Log(("Using printer '%s'\n", plist[0].name)); @@ -401,30 +436,32 @@ Error(("XpuStartJobToFile failure.")); } } else { XpuStartJobToSpooler(pdpy); } } XtAppMainLoop(app); if( doPrint ) { if( toFile ) { if( XpuWaitForPrintFileChild(printtofile_handle) != XPGetDocFinished ) { fprintf(stderr, "%s: Error while printing to file.\n", ProgramName); } } - + + PrintSpoolerCommandResults(pdpy, pcontext); + /* We have to use XpDestroyContext() and XtCloseDisplay() instead * of XpuClosePrinterDisplay() to make libXt happy... */ if( pcontext != None ) XpDestroyContext(pdpy, pcontext); XtCloseDisplay(pdpy); } return EXIT_SUCCESS; } Index: xc/programs/xphelloworld/xphelloworld/xphelloworld.c =================================================================== RCS file: /cvs/xorg/xc/programs/xphelloworld/xphelloworld/xphelloworld.c,v retrieving revision 1.3 diff -u -2 -0 -r1.3 xphelloworld.c --- xc/programs/xphelloworld/xphelloworld/xphelloworld.c 3 Jan 2005 01:06:36 -0000 1.3 +++ xc/programs/xphelloworld/xphelloworld/xphelloworld.c 11 Apr 2005 00:59:38 -0000 @@ -20,69 +20,97 @@ 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. * * Author: Roland Mainz */ #include #include #include #include #include #include /* Turn a NULL pointer string into an empty string */ #define NULLSTR(x) (((x)!=NULL)?(x):("")) #define Log(x) { if(verbose) printf x; } +#define Msg(x) { if(!quiet) printf x; } const char *ProgramName; /* program name (from argv[0]) */ Bool verbose = False; /* verbose output what the program is doing */ +Bool quiet = False; /* be quiet (no output except errors) */ static void usage( void ) { fprintf (stderr, "usage: %s [options]\n", ProgramName); fprintf (stderr, "-printer printernname\tprinter to use\n"); fprintf (stderr, "-printargs args\t[ arg=value , ... ]\n"); fprintf (stderr, "\targs:\ttofile=\n"); fprintf (stderr, "\t\tpapersize=\n"); fprintf (stderr, "\t\torientation=\n"); fprintf (stderr, "\t\tresolution=\n"); fprintf (stderr, "\t\tplex=\n"); fprintf (stderr, "\t\ttitle=\n"); fprintf (stderr, "-v\tverbose output\n"); + fprintf (stderr, "-q\tbe quiet (no output except errors)\n"); fprintf (stderr, "-text \ttext to print (in ISO-8859-1)\n"); fprintf (stderr, "\n"); exit(EXIT_FAILURE); } static +void PrintSpoolerCommandResults( Display *pdpy, XPContext pcontext ) +{ + char *scr; + + scr = XpGetOneAttribute(pdpy, pcontext, XPJobAttr, "xp-spooler-command-results"); + if( scr ) + { + if( strlen(scr) > 0 ) + { + const char *msg = XpuCompoundTextToXmb(pdpy, scr); + if( msg ) + { + Msg(("Spooler command returned '%s'.\n", msg)); + XpuFreeXmbString(msg); + } + else + { + Msg(("Spooler command returned '%s' (unconverted).\n", scr)); + } + } + + XFree((void *)scr); + } +} + +static int do_hello_world( const char *printername, const char *printerargs, const char *hello_world_message ) { char *printerfile = NULL; Window pwin; XGCValues gcvalues; - XEvent ev; GC pgc; unsigned short dummy; XRectangle winrect; char fontname[256]; /* BUG: is this really big enougth ? */ XFontStruct *font; XpauContext *context; XpauFlags docvalueflags = 0UL; XpauDocValues x_docvalues; XpauDocValues *docvalues = &x_docvalues; XpAuErrorValue result; XpauFlags jobvalueflags = 0UL; XpauJobValues x_jobvalues; XpauJobValues *jobvalues = &x_jobvalues; memset(&x_jobvalues, 0, sizeof(x_jobvalues)); memset(&x_docvalues, 0, sizeof(x_docvalues)); context = XpauGetContext(printername); if( !context ) { @@ -170,45 +198,49 @@ XSetFont(context->pdpy, pgc, font->fid); if (!hello_world_message) hello_world_message = "hello world from X11 print system"; XDrawString(context->pdpy, pwin, pgc, 100, 100, hello_world_message, strlen(hello_world_message)); XpauEndPage(context); XpauWaitForPrintNotify(context, XPEndPageNotify); Log(("end page.\n")); Log(("end job.\n")); if( (result = XpauEndJob(context)) != XpAuError_success ) { fprintf(stderr, "%s: Error while printing: %s.\n", ProgramName, XpAuErrorValueToString(result)); XpauReleaseContext(context); return(EXIT_FAILURE); } XpauWaitForPrintNotify(context, XPEndJobNotify); - + + /* end of spooled job - get spooler command results and print them */ + PrintSpoolerCommandResults(context->pdpy, context->pcontext); + XpauReleaseContext(context); return(EXIT_SUCCESS); } + int main (int argc, char *argv[]) { const char *printername = NULL; /* printer to query */ const char *printargs = NULL; const char *hello_world_message = NULL; Bool use_threadsafe_api = False; /* Use threadsafe API (for debugging) */ XPPrinterList plist; /* list of printers */ int plist_count; /* number of entries in |plist|-array */ int i; int retval; ProgramName = argv[0]; for (i = 1; i < argc; i++) { char *arg = argv[i]; int len = strlen(arg); if (!strncmp("-printer", arg, len)) { @@ -220,40 +252,46 @@ { if (++i >= argc) usage(); printargs = argv[i]; } else if (!strncmp("-text", arg, len)) { if (++i >= argc) usage(); hello_world_message = argv[i]; } else if( !strncmp("-debug_use_threadsafe_api", arg, len) ) { use_threadsafe_api = True; } else if (!strncmp("-v", arg, len)) { verbose = True; + quiet = False; + } + else if (!strncmp("-q", arg, len)) + { + verbose = False; + quiet = True; } else { usage(); } } if( use_threadsafe_api ) { if( !XInitThreads() ) { fprintf(stderr, "%s: XInitThreads() failure.\n", ProgramName); exit(EXIT_FAILURE); } } plist = XpuGetPrinterList(printername, &plist_count); if (!plist) { fprintf(stderr, "%s: no printers found for printer spec \"%s\".\n", Index: xc/programs/xphelloworld/xpsimplehelloworld/xpsimplehelloworld.c =================================================================== RCS file: /cvs/xorg/xc/programs/xphelloworld/xpsimplehelloworld/xpsimplehelloworld.c,v retrieving revision 1.3 diff -u -2 -0 -r1.3 xpsimplehelloworld.c --- xc/programs/xphelloworld/xpsimplehelloworld/xpsimplehelloworld.c 3 Jan 2005 01:06:36 -0000 1.3 +++ xc/programs/xphelloworld/xpsimplehelloworld/xpsimplehelloworld.c 11 Apr 2005 00:59:38 -0000 @@ -21,53 +21,56 @@ 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. * * Author: Roland Mainz */ #include #include #include #include #include #include #include /* Turn a NULL pointer string into an empty string */ #define NULLSTR(x) (((x)!=NULL)?(x):("")) #define Log(x) { if(verbose) printf x; } +#define Msg(x) { if(!quiet) printf x; } static const char *ProgramName; /* program name (from argv[0]) */ static Bool verbose = False; /* verbose output what the program is doing */ +Bool quiet = False; /* be quiet (no output except errors) */ static void usage(void) { fprintf (stderr, "usage: %s [options]\n", ProgramName); fprintf (stderr, "-printer printernname\tprinter to use\n"); fprintf (stderr, "-printfile file\tprint to file instead of printer\n"); fprintf (stderr, "-embedpsl2data string\tPostScript level 2 fragment to embed\n" "\t\t(use 'xppsembeddemo1' to embed demo data)\n"); fprintf (stderr, "-v\tverbose output\n"); + fprintf (stderr, "-q\tbe quiet (no output except errors)\n"); fprintf (stderr, "\n"); exit(EXIT_FAILURE); } /* strstr(), case-insensitive */ static char *str_case_str(const char *s, const char *find) { size_t len; char c, sc; if ((c = tolower(*find++)) != '\0') { len = strlen(find); do { do { if ((sc = tolower(*s++)) == '\0') @@ -76,46 +79,46 @@ } while (strncasecmp(s, find, len) != 0); s--; } return ((char *)s); } static int do_hello_world(const char *printername, const char *printerfile, const char *psembeddata ) { Display *pdpy; /* X connection */ XPContext pcontext; /* Xprint context */ void *printtofile_handle; /* "context" when printing to file */ int xp_event_base, /* XpExtension even base */ xp_error_base; /* XpExtension error base */ long dpi_x = 0L, dpi_y = 0L; Screen *pscreen; int pscreennumber; Window pwin; XGCValues gcvalues; - XEvent ev; GC pgc; unsigned short dummy; XRectangle winrect; char fontname[256]; /* BUG: is this really big enougth ? */ XFontStruct *font; + char *scr; if( XpuGetPrinter(printername, &pdpy, &pcontext) != 1 ) { fprintf(stderr, "Cannot open printer '%s'\n", printername); return(EXIT_FAILURE); } if( XpQueryExtension(pdpy, &xp_event_base, &xp_error_base) == False ) { fprintf(stderr, "XpQueryExtension() failed.\n"); XpuClosePrinterDisplay(pdpy, pcontext); return(EXIT_FAILURE); } /* Listen to XP(Start|End)(Job|Doc|Page)Notify events). * This is mantatory as Xp(Start|End)(Job|Doc|Page) functions are _not_ * syncronous !! * Not waiting for such events may cause that subsequent data may be * destroyed/corrupted!! */ @@ -288,40 +291,61 @@ XpEndDoc(pdpy); XpuWaitForPrintNotify(pdpy, xp_event_base, XPEndDocNotify); #endif /* MULTIPLE_DOCUMENTS_IN_ONE_JOB */ /* End the print job - the final results are sent by the X print * server to the spooler sub system. */ XpEndJob(pdpy); XpuWaitForPrintNotify(pdpy, xp_event_base, XPEndJobNotify); Log(("end job.\n")); if( printerfile ) { if( XpuWaitForPrintFileChild(printtofile_handle) != XPGetDocFinished ) { fprintf(stderr, "%s: Error while printing to file.\n", ProgramName); XpuClosePrinterDisplay(pdpy, pcontext); return(EXIT_FAILURE); } } + + /* End of spooled job - get spooler command results and print them */ + scr = XpGetOneAttribute(pdpy, pcontext, XPJobAttr, "xp-spooler-command-results"); + if( scr ) + { + if( strlen(scr) > 0 ) + { + const char *msg = XpuCompoundTextToXmb(pdpy, scr); + if( msg ) + { + Msg(("Spooler command returned '%s'.\n", msg)); + XpuFreeXmbString(msg); + } + else + { + Msg(("Spooler command returned '%s' (unconverted).\n", scr)); + } + } + + XFree((void *)scr); + } XpuClosePrinterDisplay(pdpy, pcontext); return(EXIT_SUCCESS); } int main (int argc, char *argv[]) { const char *printername = NULL; /* printer to query */ const char *toFile = NULL; /* output file (instead of printer) */ const char *embedpsl2data = NULL; /* PS Level 2 code fragment for embedding in output */ XPPrinterList plist; /* list of printers */ int plist_count; /* number of entries in |plist|-array */ int i; int retval; ProgramName = argv[0]; for (i = 1; i < argc; i++) { char *arg = argv[i]; @@ -331,40 +355,46 @@ { if (++i >= argc) usage(); printername = argv[i]; } else if (!strncmp("-printfile", arg, len)) { if (++i >= argc) usage(); toFile = argv[i]; } else if (!strncmp("-embedpsl2data", arg, len)) { if (++i >= argc) usage(); embedpsl2data = argv[i]; } else if (!strncmp("-v", arg, len)) { verbose = True; + quiet = False; + } + else if (!strncmp("-q", arg, len)) + { + verbose = False; + quiet = True; } else { usage(); } } plist = XpuGetPrinterList(printername, &plist_count); if (!plist) { fprintf(stderr, "%s: no printers found for printer spec \"%s\".\n", ProgramName, NULLSTR(printername)); exit(EXIT_FAILURE); } Log(("Using printer '%s'\n", plist[0].name)); retval = do_hello_world(plist[0].name, toFile, embedpsl2data); XpuFreePrinterList(plist); Index: xc/programs/xphelloworld/xpxmhelloworld/xpxmhelloworld.c =================================================================== RCS file: /cvs/xorg/xc/programs/xphelloworld/xpxmhelloworld/xpxmhelloworld.c,v retrieving revision 1.3 diff -u -2 -0 -r1.3 xpxmhelloworld.c --- xc/programs/xphelloworld/xpxmhelloworld/xpxmhelloworld.c 3 Jan 2005 01:06:36 -0000 1.3 +++ xc/programs/xphelloworld/xpxmhelloworld/xpxmhelloworld.c 11 Apr 2005 00:59:38 -0000 @@ -32,67 +32,96 @@ * http://nscp.upenn.edu/aix4.3html/libs/motiftr/XmText.htm * */ #include #include #include #include #include #include #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 Log(x) { if(verbose) printf x; } +#define Msg(x) { if(!quiet) printf x; } /* Prototypes */ static int do_hello_world( int argc, char *argv[], const char *printername, const char *toFile, const char *sample_string ); /* Global vars */ const char *ProgramName; /* program name (from argv[0]) */ Bool verbose = False; /* verbose output what the program is doing */ +Bool quiet = False; /* be quiet (no output except errors) */ Bool doPrint = False; /* Do we print on a printer ? */ Display *pdpy = NULL; /* (Paper) display */ Screen *pscreen = NULL; /* (Paper) screen (DDX-specific!) */ XPContext pcontext = None; /* Xprint context */ void *printtofile_handle = NULL; /* XprintUtil "context" when printing to file */ Drawable pdrawable = None; /* paper drawable */ static void usage( void ) { fprintf(stderr, "usage: %s [options] string\n", ProgramName); fprintf(stderr, "-print\tPrint via Xprint instead of displaying on the Xserver\n"); fprintf(stderr, "-printer printernname\tprinter to use\n"); fprintf(stderr, "-printfile file\tprint to file instead of printer\n"); fprintf(stderr, "-v\tverbose output\n"); + fprintf(stderr, "-q\tbe quiet (no output except errors)\n"); fprintf(stderr, "\n"); exit(EXIT_FAILURE); } +static +void PrintSpoolerCommandResults( Display *pdpy, XPContext pcontext ) +{ + char *scr; + + scr = XpGetOneAttribute(pdpy, pcontext, XPJobAttr, "xp-spooler-command-results"); + if( scr ) + { + if( strlen(scr) > 0 ) + { + const char *msg = XpuCompoundTextToXmb(pdpy, scr); + if( msg ) + { + Msg(("Spooler command returned '%s'.\n", msg)); + XpuFreeXmbString(msg); + } + else + { + Msg(("Spooler command returned '%s' (unconverted).\n", scr)); + } + } + + XFree((void *)scr); + } +} + int main( int argc, char *argv[] ) { const char *printername = NULL; /* printer to query */ const char *toFile = NULL; /* output file (instead of printer) */ XPPrinterList plist; /* list of printers */ int plist_count; /* number of entries in |plist|-array */ int i; int retval; const char *sample_string; ProgramName = argv[0]; if( argc < 2 ) { usage(); } for( i = 1 ; i < (argc-1) ; i++ ) { char *arg = argv[i]; @@ -102,40 +131,46 @@ { doPrint = True; } else if (!strncmp("-printer", arg, len)) { if (++i >= argc) usage(); printername = argv[i]; doPrint = True; } else if (!strncmp("-printfile", arg, len)) { if (++i >= argc) usage(); toFile = argv[i]; doPrint = True; } else if (!strncmp("-v", arg, len)) { verbose = True; + quiet = False; + } + else if (!strncmp("-q", arg, len)) + { + verbose = False; + quiet = True; } else { usage(); } } sample_string = argv[argc-1]; if( doPrint ) { plist = XpuGetPrinterList(printername, &plist_count); if (!plist) { fprintf(stderr, "%s: no printers found for printer spec \"%s\".\n", ProgramName, NULLSTR(printername)); exit(EXIT_FAILURE); } Log(("Using printer '%s'\n", plist[0].name)); @@ -240,41 +275,41 @@ } Log(("PrintOnePageCB: done\n")); } static void PrintStartJobCB(Widget pshell, XtPointer context, XtPointer call_data) { XmPrintShellCallbackStruct *psp = (XmPrintShellCallbackStruct *)call_data; Log(("--> PrintStartJobCB\n")); } static void PrintEndJobCB(Widget pshell, XtPointer context, XtPointer call_data) { MyPrintCallbackData *mpcd = (MyPrintCallbackData *)context; XmPrintShellCallbackStruct *psp = (XmPrintShellCallbackStruct *)call_data; Log(("--> PrintEndJobCB\n")); - + /* We're done with printing, tell |XtAppMainLoop()| that it can exit */ XtAppSetExitFlag(mpcd->appcontext); } int do_hello_world( int argc, char *argv[], const char *printername, const char *toFile, const char *sample_string ) { XtAppContext app; Widget toplevel, shell, print_shell, hello; long dpi_x = 0L, dpi_y = 0L; char fontname[256]; /* BUG: is this really big enougth ? */ XFontStruct *textFont; XmFontList textFontList; Cardinal n; Arg args[10]; MyPrintCallbackData mpcd; @@ -420,31 +455,33 @@ Error(("XpuStartJobToFile failure.")); } } else { XpuStartJobToSpooler(pdpy); } } XtAppMainLoop(app); if( doPrint ) { if( toFile ) { if( XpuWaitForPrintFileChild(printtofile_handle) != XPGetDocFinished ) { fprintf(stderr, "%s: Error while printing to file.\n", ProgramName); } } + + PrintSpoolerCommandResults(pdpy, pcontext); /* We have to use XpDestroyContext() and XtCloseDisplay() instead * of XpuClosePrinterDisplay() to make libXt happy... */ if( pcontext != None ) XpDestroyContext(pdpy, pcontext); XtCloseDisplay(pdpy); } return EXIT_SUCCESS; } Index: xc/programs/xphelloworld/xpxthelloworld/xpxthelloworld.c =================================================================== RCS file: /cvs/xorg/xc/programs/xphelloworld/xpxthelloworld/xpxthelloworld.c,v retrieving revision 1.3 diff -u -2 -0 -r1.3 xpxthelloworld.c --- xc/programs/xphelloworld/xpxthelloworld/xpxthelloworld.c 3 Jan 2005 01:06:36 -0000 1.3 +++ xc/programs/xphelloworld/xpxthelloworld/xpxthelloworld.c 11 Apr 2005 00:59:38 -0000 @@ -24,62 +24,91 @@ in this Software without prior written authorization from The Open Group. * * Author: Roland Mainz */ #include #include #include #include #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 Log(x) { if(verbose) printf x; } +#define Msg(x) { if(!quiet) printf x; } -/* Prototypes */ +/* Local prototypes */ +static void PrintSpoolerCommandResults(Display *pdpy, XPContext pcontext); static void redisplayWidget(Widget widget); static void MyAppMainLoop(XtAppContext app, Widget printwidget); static int do_hello_world( int argc, char *argv[], const char *printername, const char *toFile ); /* Global vars */ const char *ProgramName; /* program name (from argv[0]) */ Bool verbose = False; /* verbose output what the program is doing */ +Bool quiet = False; /* be quiet (no output except errors) */ Bool done = False; /* Done with printing ? */ Bool doPrint = False; /* Do we print on a printer ? */ int xp_eventbase, /* XpExtension event base */ xp_errorbase; /* XpExtension error base */ Display *pdpy = NULL; /* (Paper) display */ Screen *pscreen = NULL; /* (Paper) screen (DDX-specific!) */ XPContext pcontext = None; /* Xprint context */ void *printtofile_handle = NULL; /* XprintUtil "context" when printing to file */ Drawable pdrawable = None; /* paper drawable */ int numpages = 0; /* pages being printed */ static +void PrintSpoolerCommandResults( Display *pdpy, XPContext pcontext ) +{ + char *scr; + + scr = XpGetOneAttribute(pdpy, pcontext, XPJobAttr, "xp-spooler-command-results"); + if( scr ) + { + if( strlen(scr) > 0 ) + { + const char *msg = XpuCompoundTextToXmb(pdpy, scr); + if( msg ) + { + Msg(("Spooler command returned '%s'.\n", msg)); + XpuFreeXmbString(msg); + } + else + { + Msg(("Spooler command returned '%s' (unconverted).\n", scr)); + } + } + + XFree((void *)scr); + } +} + +static void MyAppMainLoop(XtAppContext app, Widget printwidget) { XEvent xevent; /* process events. */ while( !done ) { XtAppNextEvent(app, &xevent); if( XtDispatchEvent(&xevent) == False ) { /* XpExtension event ? */ if( xevent.type == xp_eventbase+XPPrintNotify ) { XPPrintEvent *pev = (XPPrintEvent *)&xevent; Log(("--> got XPPrintEvent\n")); switch( pev->detail ) { @@ -142,40 +171,41 @@ xev.count = 0 ; region = XCreateRegion(); XtAddExposureToRegion((XEvent*)&xev, region); if (widget->core.widget_class->core_class.expose) (*(widget->core.widget_class->core_class.expose)) (widget, (XEvent*)&xev, region); XDestroyRegion(region); } static void usage( void ) { fprintf (stderr, "usage: %s [options]\n", ProgramName); fprintf (stderr, "-print\tPrint via Xprint instead of displaying on the Xserver\n"); fprintf (stderr, "-printer printernname\tprinter to use\n"); fprintf (stderr, "-printfile file\tprint to file instead of printer\n"); fprintf (stderr, "-v\tverbose output\n"); + fprintf (stderr, "-q\tbe quiet (no output except errors)\n"); fprintf (stderr, "\n"); exit(EXIT_FAILURE); } int main( int argc, char *argv[] ) { const char *printername = NULL; /* printer to query */ const char *toFile = NULL; /* output file (instead of printer) */ XPPrinterList plist; /* list of printers */ int plist_count; /* number of entries in |plist|-array */ int i; int retval; ProgramName = argv[0]; for( i = 1 ; i < argc ; i++ ) { char *arg = argv[i]; int len = strlen(arg); @@ -183,40 +213,46 @@ { doPrint = True; } else if (!strncmp("-printer", arg, len)) { if (++i >= argc) usage(); printername = argv[i]; doPrint = True; } else if (!strncmp("-printfile", arg, len)) { if (++i >= argc) usage(); toFile = argv[i]; doPrint = True; } else if (!strncmp("-v", arg, len)) { verbose = True; + quiet = False; + } + else if (!strncmp("-q", arg, len)) + { + verbose = False; + quiet = True; } else { usage(); } } if( doPrint ) { plist = XpuGetPrinterList(printername, &plist_count); if (!plist) { fprintf(stderr, "%s: no printers found for printer spec \"%s\".\n", ProgramName, NULLSTR(printername)); exit(EXIT_FAILURE); } Log(("Using printer '%s'\n", plist[0].name)); retval = do_hello_world(argc, argv, plist[0].name, toFile); @@ -383,31 +419,33 @@ } else { XpuStartJobToSpooler(pdpy); } numpages = 0; } MyAppMainLoop(app, toplevel); if( doPrint ) { if( toFile ) { if( XpuWaitForPrintFileChild(printtofile_handle) != XPGetDocFinished ) { fprintf(stderr, "%s: Error while printing to file.\n", ProgramName); } } + + PrintSpoolerCommandResults(pdpy, pcontext); /* We have to use XpDestroyContext() and XtCloseDisplay() instead * of XpuClosePrinterDisplay() to make libXt happy... */ if( pcontext != None ) XpDestroyContext(pdpy, pcontext); XtCloseDisplay(pdpy); } return EXIT_SUCCESS; }