Index: xc/programs/glxgears/Imakefile =================================================================== RCS file: /cvs/xorg/xc/programs/glxgears/Imakefile,v retrieving revision 1.1.4.1 diff -u -r1.1.4.1 Imakefile --- a/xc/programs/glxgears/Imakefile 5 Mar 2004 13:41:14 -0000 1.1.4.1 +++ b/xc/programs/glxgears/Imakefile 23 Apr 2004 08:09:11 -0000 @@ -2,7 +2,7 @@ XCOMM $XFree86: xc/programs/glxinfo/Imakefile,v 1.3 2001/03/21 20:56:32 dawes Exp $ #include DEPLIBS = $(DEPGLXLIB) $(DEPXLIB) -LOCAL_LIBRARIES = $(GLXLIB) $(XLIB) +LOCAL_LIBRARIES = $(GLXLIB) -lXp -lXprintUtil $(XLIB) SYS_LIBRARIES = MathLibrary SimpleProgramTarget(glxgears) Index: xc/programs/glxgears/glxgears.c =================================================================== RCS file: /cvs/xorg/xc/programs/glxgears/glxgears.c,v retrieving revision 1.1.4.2 diff -u -r1.1.4.2 glxgears.c --- a/xc/programs/glxgears/glxgears.c 5 Mar 2004 13:41:14 -0000 1.1.4.2 +++ b/xc/programs/glxgears/glxgears.c 23 Apr 2004 08:09:11 -0000 @@ -30,24 +30,37 @@ */ -#include -#include -#include -#include #include +#include +#include #include #include #include +#include +#include +#include +#include +#include +#include +/* XXX this probably isn't very portable */ +#include +#include -#define BENCHMARK +/* Turn a NULL pointer string into an empty string */ +#define NULLSTR(x) (((x)!=NULL)?(x):("")) -#ifdef BENCHMARK +#define Log(x) { if(verbose) printf x; } -/* XXX this probably isn't very portable */ +static const char *ProgramName; /* program name (from argv[0]) */ +static Bool verbose = False; /* verbose output what the program is doing */ -#include -#include +int xp_event_base, /* XpExtension even base */ + xp_error_base; /* XpExtension error base */ + +#define BENCHMARK + +#ifdef BENCHMARK /* return current time (in seconds) */ static int @@ -311,7 +324,7 @@ * Return the window and context handles. */ static void -make_window( Display *dpy, const char *name, +make_window( Display *dpy, Screen *scr, const char *name, int x, int y, int width, int height, Window *winRet, GLXContext *ctxRet) { @@ -330,8 +343,8 @@ GLXContext ctx; XVisualInfo *visinfo; - scrnum = DefaultScreen( dpy ); - root = RootWindow( dpy, scrnum ); + scrnum = XScreenNumberOfScreen(scr); + root = XRootWindow( dpy, scrnum ); visinfo = glXChooseVisual( dpy, scrnum, attrib ); if (!visinfo) { @@ -346,7 +359,7 @@ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; - win = XCreateWindow( dpy, root, 0, 0, width, height, + win = XCreateWindow( dpy, root, x, y, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr ); @@ -379,7 +392,9 @@ static void event_loop(Display *dpy, Window win) { - while (1) { + int numpages = 0; + + while (numpages < 22) { while (XPending(dpy) > 0) { XEvent event; XNextEvent(dpy, &event); @@ -422,9 +437,22 @@ /* next frame */ angle += 2.0; + if( numpages > 0 ) + { + puts("endpage\n"); + XpEndPage(dpy); + XpuWaitForPrintNotify(dpy, xp_event_base, XPEndPageNotify); + + puts("startpage\n"); + XpStartPage(dpy, win); + XpuWaitForPrintNotify(dpy, xp_event_base, XPStartPageNotify); + } + numpages++; + draw(); glXSwapBuffers(dpy, win); - + XFlush(dpy); + /* calc framerate */ { static int t0 = -1; @@ -453,32 +481,138 @@ main(int argc, char *argv[]) { Display *dpy; + XPContext pcontext; /* Xprint context */ + void *printtofile_handle = NULL; /* "context" when printing to file */ + long dpi; + Screen *pscreen; + int pscreennumber; Window win; GLXContext ctx; char *dpyName = NULL; GLboolean printInfo = GL_FALSE; int i; + 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 retval; + unsigned short dummy; + XRectangle winrect; + ProgramName = argv[0]; + for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "-display") == 0) { - dpyName = argv[i+1]; - i++; + char *arg = argv[i]; + int len = strlen(arg); + + if (!strncmp("-printer", arg, len)) + { + if (++i >= argc) + exit(EXIT_FAILURE); + printername = argv[i]; + } + else if (!strncmp("-printfile", arg, len)) + { + if (++i >= argc) + exit(EXIT_FAILURE); + toFile = argv[i]; + } + else if (!strncmp("-v", arg, len)) + { + verbose = True; } else if (strcmp(argv[i], "-info") == 0) { printInfo = GL_TRUE; } } - dpy = XOpenDisplay(dpyName); - if (!dpy) { - printf("Error: couldn't open display %s\n", dpyName); - return -1; - } + plist = XpuGetPrinterList(printername, &plist_count); - make_window(dpy, "glxgears", 0, 0, 300, 300, &win, &ctx); + if (!plist) { + fprintf(stderr, "%s: no printers found for printer spec \"%s\".\n", + ProgramName, NULLSTR(printername)); + exit(EXIT_FAILURE); + } + + printername = plist[0].name; + + Log(("Using printer '%s'\n", printername)); + + if( XpuGetPrinter(printername, &dpy, &pcontext) != 1 ) + { + fprintf(stderr, "Cannot open printer '%s'\n", printername); + return(EXIT_FAILURE); + } + + if( XpQueryExtension(dpy, &xp_event_base, &xp_error_base) == False ) + { + fprintf(stderr, "XpQueryExtension() failed.\n"); + XpuClosePrinterDisplay(dpy, 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!! + */ + XpSelectInput(dpy, pcontext, XPPrintMask); + + /* Set job title */ + XpuSetJobTitle(dpy, pcontext, "glxgears for Xprint"); + + /* Set print context + * Note that this modifies the available fonts, including builtin printer prints. + * All XListFonts()/XLoadFont() stuff should be done _after_ setting the print + * context to obtain the proper fonts. + */ + XpSetContext(dpy, pcontext); + + /* Get default printer reolution */ + if( XpuGetResolution(dpy, pcontext, &dpi) != 1 ) + { + fprintf(stderr, "No default resolution for printer '%s'.\n", printername); + XpuClosePrinterDisplay(dpy, pcontext); + return(EXIT_FAILURE); + } + + if( toFile ) + { + Log(("starting job (to file '%s').\n", toFile)); + printtofile_handle = XpuStartJobToFile(dpy, pcontext, toFile); + if( !printtofile_handle ) + { + fprintf(stderr, "%s: Error: %s while trying to print to file.\n", + ProgramName, strerror(errno)); + XpuClosePrinterDisplay(dpy, pcontext); + return(EXIT_FAILURE); + } + + XpuWaitForPrintNotify(dpy, xp_event_base, XPStartJobNotify); + } + else + { + Log(("starting job.\n")); + XpuStartJobToSpooler(dpy); + XpuWaitForPrintNotify(dpy, xp_event_base, XPStartJobNotify); + } + + pscreen = XpGetScreenOfContext(dpy, pcontext); + pscreennumber = XScreenNumberOfScreen(pscreen); + + /* Obtain some info about page geometry */ + XpGetPageDimensions(dpy, pcontext, &dummy, &dummy, &winrect); + + winrect.width /= 2; + winrect.height /= 2; + winrect.x += winrect.width / 2; + winrect.y += winrect.height / 2; + + make_window(dpy, pscreen, "glxgears", winrect.x, winrect.y, winrect.width, winrect.height, &win, &ctx); XMapWindow(dpy, win); glXMakeCurrent(dpy, win, ctx); - reshape(300, 300); + reshape(winrect.width, winrect.height); if (printInfo) { printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); @@ -489,11 +623,38 @@ init(); + puts("startpage\n"); + XpStartPage(dpy, win); + XpuWaitForPrintNotify(dpy, xp_event_base, XPStartPageNotify); + event_loop(dpy, win); + XpEndPage(dpy); + XpuWaitForPrintNotify(dpy, xp_event_base, XPEndPageNotify); + glXDestroyContext(dpy, ctx); XDestroyWindow(dpy, win); - XCloseDisplay(dpy); - return 0; + /* 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); + } + } + + XpuClosePrinterDisplay(dpy, pcontext); + + XpuFreePrinterList(plist); + + return retval; }