[Xprint] Application printing using Xprint
Roland Mainz
roland.mainz at nrubsig.org
Sun Apr 24 00:59:36 EDT 2005
Martin Deppe wrote:
> I just subscribed to this list because I got xprint knowing a few days
> ago and tried to create little program using xprint to print something
> from inside my application.
>
> I have been looking for the documentation of the client functions and
> some sample source code. I found something, but nothing that really
> helped me to finish my little applictation successfully.
>
> I hope my "problem" is very easy to answer and the answer is as easy as
> the question. Maybe someone can point me to some sample source code in
> which a connection to the X print server is being established, some more
> initializations are done, a job is being started, a page is being
> opened, some output (such as text and - more important - graphics, such
> as lines and points) is being done and then everything that has been
> started is being completed so that the data can be show on my printer.
>
> What I found were some sources that needed GL-something, xpu-something,
> xpt-something or whatever, which I didn't have and didn't find. The
> xprintutils, which I downloaded didn't compile so that I couldn't use
> them as a blueprint for my own application.
Which compile error did you get for the XprintUtils stuff ?
> Here is the code I wanted to use to print some lines on the printer:
> -----------------------------------------------------------------------------------------------------------------------------
> void printDrawing(void)
> {
> Display *pdsp;
> Window pwin;
> Screen *pScreen;
> XPContext pContext;
> XGCValues values;
> unsigned long valuemask = 0;
> GC gc;
> XRectangle rect;
> unsigned short width, height;
> int rc;
>
> if (!printingAvailable)
> {
> chkPrinter(0);
> return;
> }
>
> pdsp = XOpenDisplay(":33");
Uhm... you may want to use the XprintUtils libraries's |XpuGetPrinter()|
instead of |XOpenDisplay()| - the XprintUtils function parses the
XPSERVLIST/LPDEST environment variables and returns a |Display *| and
|XPContext| based on the name given as argument (if you don't give an
argument it just uses the default printer as defined by |LPDEST|&co.,
otherwise the first printer in the list returns by the first Xprint
server specified by XPSERVERLIST).
The XprintUtils source can be found at
http://cvs.freedesktop.org/xorg/xc/lib/XprintUtil/ (this is no dynamic
library yet as the API is not stable (yet), just add it to your
codebase... :)
> if (pdsp == NULL)
> {
> fprintf(stderr, "could not connect to X printserver (again)\n");
> return;
> }
>
> pContext = XpCreateContext(pdsp, prtName);
> fprintf(stderr, "pContext=%d\n", pContext);
> XpSetContext(pdsp, pContext); // void XpSetContext()
> gc = XCreateGC(pdsp, pwin, valuemask, &values);
|pwin| seems to be undefined at this point... that cannot work...
> fprintf(stderr, "XCreateGC()=%d\n", gc); // debug output
> if (gc < 0)
> fprintf(stderr, "XCreateGC failed - cannot process print request\n");
Uhm... AFAIK this should be |gc == 0| (or |gc == None| - which is the
same) ...
> else
> {
> XpStartJob(pdsp, XPSpool); // void XpStartJob()
> fprintf(stderr, "XpStartJob()\n"); // debug output
>
> // Generate the first page
> pScreen = XpGetScreenOfContext(pdsp, pContext);
> fprintf(stderr, "XpGetScreen()=%d\n", pScreen); // debug output
> fprintf(stderr, "XpGetPageDimensions()=%d\n",
> XpGetPageDimensions(pdsp, pContext, &width, &height, &rect)); // debug
> output included
> pwin = XCreateSimpleWindow(pdsp, RootWindowOfScreen(pScreen),
> rect.x, rect.y, rect.width, rect.height, 2,
> BlackPixelOfScreen(pScreen),
> WhitePixelOfScreen(pScreen));
> fprintf(stderr, "pwin=%d\n", pwin); // debug output
>
> XpStartPage(pdsp, pwin);
> fprintf(stderr, "XDrawLine=%d\n", XDrawLine(pdsp, pwin, gc, 20,
> 20, 120, 120));
> fprintf(stderr, "XDrawLine=%d\n", XDrawLine(pdsp, pwin, gc, 120,
> 120, 20, 20));
> fprintf(stderr, "XDrawLine=%d\n", XDrawLine(pdsp, pwin, gc, 20,
> 20, 120, 20));
> fprintf(stderr, "XDrawLine=%d\n", XDrawLine(pdsp, pwin, gc, 20,
> 120, 120, 120));
>
> XpEndPage(pdsp);
> XFreeGC(pdsp, gc); /* free the GC */
>
> // End the print job - the final results are sent by the X print
> server to the spooler sub system.
> XpEndJob(pdsp);
AFAIK you should always wait here for the |XPEndJobNotify| event -
otherwise the |XpDestroyContext()| may kill the print job while it is
being prepared for spooling.
Normally the sequence looks like this:
-- snip --
XpEndJob(xparms.d);
XpuWaitForPrintNotify(xparms.d, xparms.xp_event_base,
XPEndJobNotify);
<do more cleanup if you were printing to a file>
XpDestroyContext()
-- snip --
> }
> XpDestroyContext(pdsp, pContext);
> XCloseDisplay(pdsp);
> }
> -----------------------------------------------------------------------------------------------------------------------------
>
> I hope that the code is not to confusing and someone can tell me, why I
> get some response from the printer, but no page out of it.
See above - you created an invalid GC which could not be used
afterwards. Additionally you didn't wait for print job completion which
may lead to a race condition - depending on the time the finalisation
needed you may not get a print job delivered to the printer (I've seen
that with Hitatchis Xprint server where the OpenGL engine runs in a
seperate thread and therefore the GL rendering may complete async to the
main server rendering).
> I could connect to the X print server and get a list of my available
> printers. I could start a job and a page, but I didn't get anything else
> out of the printer than the initialization of it, after which it simply
> stopped doing anything again, as if I wouldn't have done anything.
>
> The debug output of this code was:
> -----------------------------------------------------------------------------------------------------------------------------
> pContext=2097153
> XCreateGC()=134588832
> 1: X-Server Error code: BadDrawable (invalid Pixmap or Window parameter)
The bad thing happens here already with the GC...
> XpStartJob()
> XpGetScreen()=134588368
> XpGetPageDimensions()=1
> pwin=2097155
> XDrawLine=1
> XDrawLine=1
> XDrawLine=1
> XDrawLine=1
> 2: X-Server Error code: BadGC (invalid GC parameter)
> 3: X-Server Error code: BadGC (invalid GC parameter)
> -----------------------------------------------------------------------------------------------------------------------------
BTW: See
http://cvs.freedesktop.org/xorg/xc/programs/xphelloworld/xpsimplehelloworld/xpsimplehelloworld.c?rev=1.4&view=markup
for the source code of a similar example...
----
Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 7950090
(;O/ \/ \O;)
More information about the Xprint
mailing list