diff options
Diffstat (limited to 'xpxthelloworld/xpxthelloworld.c')
-rw-r--r-- | xpxthelloworld/xpxthelloworld.c | 412 |
1 files changed, 412 insertions, 0 deletions
diff --git a/xpxthelloworld/xpxthelloworld.c b/xpxthelloworld/xpxthelloworld.c new file mode 100644 index 0000000..7eeaed2 --- /dev/null +++ b/xpxthelloworld/xpxthelloworld.c @@ -0,0 +1,412 @@ + +/* + * $Xorg: xpxthelloworld.c,v 1.1 2002/07/28 08:44:26 gisburn Exp $ + * + * xpxthelloworld - Xprint version of hello world using Athena widgets + * + * +Copyright 2002-2004 Roland Mainz <roland.mainz@nrubsig.org> + +All Rights Reserved. + +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. + * + * Author: Roland Mainz <roland.mainz@nrubsig.org> + */ + +#include <X11/IntrinsicP.h> +#include <X11/ShellP.h> +#include <X11/StringDefs.h> +#include <X11/Xaw/Label.h> + +#include <X11/XprintUtil/xprintutil.h> + +#include <stdlib.h> +#include <stdio.h> + +/* Turn a NULL pointer string into an empty string */ +#define NULLSTR(x) (((x)!=NULL)?(x):("")) + +#define Error(x) { printf x ; exit(EXIT_FAILURE); } +#define Log(x) { if(verbose) printf x; } + +/* Prototypes */ +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 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 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 ) + { + case XPStartJobNotify: + Log(("Starting page...\n")); + XpStartPage(pdpy, pdrawable); + break; + case XPEndJobNotify: + /* Job done... */ + done = True; + break; + case XPStartPageNotify: + Log(("Rendering page...\n")); + redisplayWidget(printwidget); + + Log(("Page end reached.\n")); + XpEndPage(pdpy); + break; + case XPEndPageNotify: + /* next page or exit */ + numpages++; + + if( numpages >= 1 ) + { + Log(("Finishing job...\n")); + XpEndJob(pdpy); + } + break; + default: + Log(("--> other XPPrintEvent event\n")); + break; + } + } + else + { + Log(("--> other event\n")); + } + } + } +} + +/* Code from the OpenMotif sources (XmRedisplayWidget) */ +static +void redisplayWidget(Widget widget) +{ + XExposeEvent xev ; + Region region ; + + xev.type = Expose ; + /* is this better than 0 ? shouldn't make much difference + * unless the expose method is very tricky... */ + xev.serial = LastKnownRequestProcessed(XtDisplay(widget)) ; + xev.send_event = False ; + xev.display = XtDisplay(widget); + xev.window = XtWindowOfObject(widget); /* work with gadget too */ + xev.x = 0 ; + xev.y = 0 ; + xev.width = widget->core.width ; + xev.height = widget->core.height ; + 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, "\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); + + if (!strncmp("-print", arg, len)) + { + 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; + } + 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); + + XpuFreePrinterList(plist); + } + else + { + Log(("Displaying on framebuffer Xserver\n")); + + retval = do_hello_world(argc, argv, NULL, NULL); + } + + return(retval); +} + +/* xt_xp_openapplication() - mainly identical to XtOpenApplication() but + * takes a |Display *| and |Screen *| as arguments, too... */ +static +Widget xt_xp_openapplication(XtAppContext *app_context_return, + Display *dpy, + Screen *screen, + String application_name, + String application_class, + WidgetClass widget_class, + int *argc, + String *argv) +{ + Widget toplevel; + Cardinal n; + Arg args[2]; + + XtToolkitInitialize(); + *app_context_return = XtCreateApplicationContext(); + if( *app_context_return == NULL ) + return NULL; + + XtDisplayInitialize(*app_context_return, dpy, + application_name, application_class, + NULL, 0, + argc, argv); + + n = 0; + XtSetArg(args[n], XtNscreen, screen); n++; + toplevel = XtAppCreateShell(application_name, + application_class, + widget_class, + dpy, + args, n); + + return toplevel; +} + +int do_hello_world( int argc, char *argv[], const char *printername, const char *toFile ) +{ + XtAppContext app; + Widget toplevel, + hello; + long dpi; + char fontname[256]; /* BUG: is this really big enougth ? */ + XFontStruct *labelFont; + Cardinal n; + Arg args[10]; + + if( doPrint ) + { + /* Get printer, either by "name" (foobar) or "name@display" (foobar@gaja:5) */ + if( XpuGetPrinter(printername, &pdpy, &pcontext) != 1 ) + Error(("XpuGetPrinter failure.\n")); + + if( XpQueryExtension(pdpy, &xp_eventbase, &xp_errorbase) == False ) + Error(("XpQueryExtension failure.\n")); + + XpSelectInput(pdpy, pcontext, XPPrintMask); + + /* 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, "Simple Xprint Athena widget demo"); + + /* Configuration done, set the context */ + XpSetContext(pdpy, pcontext); + + /* Get default printer resolution */ + if( XpuGetResolution(pdpy, pcontext, &dpi) != 1 ) + { + fprintf(stderr, "No default resolution for printer '%s'\n", printername); + XpuClosePrinterDisplay(pdpy, pcontext); + return(EXIT_FAILURE); + } + + pscreen = XpGetScreenOfContext(pdpy, pcontext); + } + else + { + pdpy = XOpenDisplay(NULL); + if( !pdpy ) + Error(("XOpenDisplay failure.\n")); + + dpi = 0; + + pscreen = XDefaultScreenOfDisplay(pdpy); + } + + toplevel = xt_xp_openapplication(&app, + pdpy, pscreen, + "xpxtawhenademo", "XpXtAthenaDemo", + applicationShellWidgetClass, + &argc, argv); + + if( !toplevel ) + Error(("xt_xp_openapplication failure.\n")); + + sprintf(fontname, "-*-*-*-*-*-*-*-180-%ld-%ld-*-*-iso8859-1", dpi, dpi); + labelFont = XLoadQueryFont(pdpy, fontname); + if( !labelFont ) + Error(("XLoadQueryFont failure.\n")); + + n = 0; + XtSetArg(args[n], XtNlabel, "Hello world\n" + "(Xprint/Athena widget version)"); n++; + XtSetArg(args[n], XtNfont, labelFont); n++; + hello = XtCreateManagedWidget( + "hello", /* arbitrary widget name */ + labelWidgetClass, /* widget class from Label.h */ + toplevel, /* parent widget*/ + args, /* argument list */ + n /* arg list size */ + ); + if( !hello ) + Error(("XtCreateManagedWidget failure.\n")); + + XtRealizeWidget(toplevel); + + if( doPrint ) + { + unsigned short pwidth, pheight; + XRectangle pagerect; + + pdpy = XtDisplay(toplevel); + pdrawable = XtWindow(toplevel); + if( !pdpy || !pdrawable ) + Error(("No display.\n")); + + /* Make sure that the Xt machinery is really using the right screen (assertion) ... */ + if( XpGetScreenOfContext(XtDisplay(toplevel), pcontext) != XtScreen(toplevel) ) + Error(("Widget's screen != print screen. BAD.\n")); + + /* Get the page dimensions and resize the widget based on that info ... */ + XpGetPageDimensions(pdpy, pcontext, &pwidth, &pheight, &pagerect); + XMoveResizeWindow(pdpy, pdrawable, pagerect.x, pagerect.y, pagerect.width, pagerect.height); + + /* ... and then start the print job. */ + if( toFile ) + { + printtofile_handle = XpuStartJobToFile(pdpy, pcontext, toFile); + if( !printtofile_handle ) + { + perror("XpuStartJobToFile failure"); + Error(("XpuStartJobToFile failure.")); + } + } + 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); + } + } + + /* 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; +} + |