Functional specification
33
CDE/Motif PST
CDEnext
XpStartJob
and
XpEndJob
.
XpGetDocumentData
always returns immediately; if an error occurs
and the callbacks cannot be registered,
NULL
is returned, otherwise a non-
NULL
is returned and the
callbacks will be called sometime after the return from
XpGetDocumentData
. This producer/consumer
model is initiated when
XpStartJob
is called by the producer with
save_data
equal
XPGetData
,
and is subsequently enabled when
XpGetDocumentData
is called by the consumer.
Once
XpGetDocumentData
is called on
data_display
,
data_display
cannot be used for any
additional X requests until
finish_proc
is called and returns. Further,
data_display
cannot be
closed from within
save_proc
or
finish_proc
. To avoid deadlock, the producer and consumer must
run in separate processes, or in separate threads of a single process.
After
XpGetDocumentData
successfully registers the callbacks (ie, it returns non-
NULL
), any
generated X errors (for example,
BadAlloc
) or Xp errors (for example,
XPBadContext
or
XPBadSequence
) that are the result of
XpGetDocumentData
will cause the appropriate errors to be
generated (see
XSetErrorHandler
), and will cause
finish_proc
to be called with a status of
XPGetDocError
. Any other activities (for example, a separate process destroying the print context) that
prove fatal to the progress of
XpGetDocumentData
will also cause
finish_proc
to be called with a
status of
XPGetDocError
.
If
XpGetDocumentData
is called prior to
XpStartJob
, then a
XPBadSequence
error is generated
and
finish_proc
is called with
XPGetDocError
. If
XpGetDocumentData
is called after
XpStartJob
and
save_data
was specified as
XPSpool
, then a
XPBadSequence
error is generated
and
finish_proc
is called with
XPGetDocError
. If the producer starts generating data, and a
consumer has not been established or the consumer cannot consume data quickly enough, then the
producer's display connection will be blocked by the X Print Server.
save_proc
, as registered by
XpGetDocumentData
, is repeatedly called on each block of document
data sent by the X Print Server until either
XpEndJob
or
XpCancelJob
is called. Each block provided
to
data
will be
data_len
bytes in length, and the memory for
data
itself will be owned by
XpGetDocumentData
, so
save_proc
should copy
data
to another location before returning. After
the last block of data has been delivered to
save_proc
,
finish_proc
is called with final status. The
signatures for
save_proc
and
finish_proc
are defined in
<X11/extensions/Print.h>
as
follows:
typedef void (*XPSaveProc)( Display
*data_display,
XPContext
context,
unsigned char
*data,
unsigned long
data_len,
XPointer
client_data);
typedef void (*XPFinishProc)( Display
*data_display,
XPContext
context,
XPGetDocStatus
status,
XPointer
client_data);
Until
XpEndJob
or
XpCancelJob
is called, it is possible that various
XPPrintNotify
events will be
generated (for example, a page has been canceled). It is left as an exercise to the consumer (or producer)
whether to select for these events and terminate
save_proc
(by calling
XpEndJob
or
XpCancelJob
)
in response to canceled pages or documents. Since data is considered opaque until the print job completes
successfully (i.e. no cancellations), and there is no correlation between the sequence of data blocks and
received events, and the consumer may not be able to interpret the byte stream, consumers may want to
terminate
save_proc
upon receipt of cancellation events.