WWDC2000 Session 112
Transcript
Kind: captions
Language: en
ladies and gentlemen please welcome
manager for the
Group Paul dan bold thank you
okay that's me how many people came to
the pudding session this morning reckon
that's most so you saw a lot of the
things that we can do with printing
specifically on 10 this morning and the
focus for this session is going to be on
how you do that so we're going to be
looking at some code will start off and
take you through some of the session ap
is if you've got carbon lip let's see
the only 11 build you'll probably seen
them in the header files certainly there
in CP 3 and DP for so we would like you
to start using them and will take you
through those and the next thing we'll
do is we'll show you how we were able to
display the print dialog the sheets and
that's something you saw this morning
and they're not going to talk a little
bit about the issues to do with the
print dialog and issues for people who
want to do non-printing type
applications but still using printing
system or printing without at you I will
talk a little bit about poster printing
and then I guess the main topic for
today is how to write a plug-in how to
add a panel to the print dialog and if
we have time we'll have a Q&A session
although i should point out now we could
have feedback form later on this
afternoon quite a lot of the things
we've got to show you today don't look
too good with 36 points on the
powerpoint slide so we're using our
favorite application project builder and
taking you through some code so back by
popular demand to talk about the session
API so you got Alan Alan back from the
printing team he's going to take that
first topic thank you Paul so basically
what I'm first I want to go through is
basically the major objects that are
used an application with deal with when
you're printing through the carbon
printing manager the first two or
basically the PM page full C p.m. page
format and the PM princess print
settings these basically replace the old
128 bite print records
which we are so glad to get rid of the
PM page format is basically relevant to
all the options that are dealing with
the page setup dialog and basically is
how basically is how it relates to
imaging of the documents pages that is
basically what should be saved in the
what is being saved in the page format
object it this object should be
flattened and stayed with the document
kind of like the old print record was
and another point to be made about this
is you can use the accessor functions to
get the data out of the object without
or outside of the BPM began to p.m. and
calls and one last thing about this is
it is extensible with application data
then we have the print settings again
which basically is normally not saved
with the document and here again that it
is extensible with application data
thirdly is the PM print context
basically this is an opaque graph port
that is used to image pages within the
print loop then we come with the PM
print session this is the major change
that we've added to the PM application h
PM application since last WWDC it
enables the application to have multiple
concurrent printing sessions it's also
needed to enable the document mobile
printing which we which I demoed this
morning for multi-threaded apps each
thread can have one or more of these
sessions attached to it but mostly
threaded apps kindle a session cannot be
shared between these multiple threads
p.m. page format and PM print settings
objects can be shared between multiple
print sessions and lastly I like to
point out that a session can only
display one printing dialogue at a time
in other words you can't have a in the
document mol
case you can have one document showing a
print dialog another document showing
another print dialog sharing the same
session that's that's not allowed then
we go to the PM dialogue which is
basically our objects for the print
dialog and then lastly we have the PM
printer which basically represents the
target printer use the accessor
functions of this object to get specific
features about the printer such as like
driver version resolution PPD file
that's associated with it now I'd like
to go talk the difference between the
mapping between the session and non
session ap is basically as you can tell
from the slide there's basically a
one-to-one mapping p.m. begin is this
nap 2pm create session pmn maps the PM
release and basically the rest of them
are the same API just with a session
added to the name and a session the PM
session as basically the first parameter
to any of these calls with that I would
like to go over to demo machine and show
you our side-by-side comparison of these
of a PM session and PM non session and
p.m. session apps by a demo machine on
both here we are okay basically here we
have this is the print loop this is our
sample print loop in the non session
case and here we should have the session
in the width using session so basically
they're basically the same let's go
scroll down a bit there's this okay
here's remain so everything starts and
let's go over here and scroll down here
there we go
basically here we have the PM begin on
this side and the PM create session over
here and then basically go down on
through and then we basically we convert
the old print record and then the do the
do the page setup dialog over here it's
the same thing except we have p.m.
session convert old front record which
we can see passes in the print session
that's the first parameter and do the
same thing down here is page setup and
print dialog now we'll just go on down
to the issue the same thing we have
basically in the pay stub dialogue we're
trying to create a page format object
then basically and this this one here is
not a session based API and let's go
over here precious basically the non
session way of doing it is doing it p.m.
new page format and with sessions it is
a PM create page format and then
basically they would go down and
validate the session the validate the
page format and then here in the session
case we just passed the print session
and then the same thing with the print
dialog basically we try to create a new
print a new p.m. setting here we do a
new print settings and here here we do
it to create with wishes the session API
and the new print settings is a non non
session API and do a validate one thing
that we like to encourage our developers
application developers to do is before
putting up the print dialog to basically
set the page range in the page format
this allows us when we put up the dialog
to give some clues of the user as in the
length of the document so if you ever
wants to do a page range he actually we
can actually tell the user you know what
the last page of the document is and
they will get some clue as to what they
might want to input into those to edit
boxes then here we just threw the prepn
print dialog and
here we do the p.m. session from
dialogue and then another thing I want
to talk to is about the new basically
how we're recommending the new print
loop basically get them synchronize a
little bit better okay so basically here
we do the get adjusted paper wrecked and
then basically get the first page I
don't think we want to make sure that we
remember to do is to only print the
pages that the user has specified don't
don't expect the printing system to skip
pages that are not in the page range
that the user specified so we will print
every page out of school to or less
image to us then basically okay here's
the actual print loop over here
here we have the begin document p.m.
session begin document p.m. session end
document basically then we loop through
the pages start the PM begin page and
now we're here is the PM session begin
page another thing that you have to make
sure you do is make sure you set the
port between before drawing each of the
pages we cannot guarantee that the port
is the correct port of dirt during your
draw during during your draw page so as
yet remember to make sure you set the
port basically here we do the draw page
and then we're going to start backing
out which is the P in session end page
and document and then basically at the
end report any errors one thing I do
want to remind you of is another thing
on remind you of is art the objects are
rough counted so basically you can see
here when we're done doing the print
loop we do a release of the page format
a release of the print settings and
finally a release of the print session
that you've created ruff ruff counting
is happening so we want to make sure
remember to release the objects that
that you've created and that's basically
all I would like to talk to about the
print loop to go back to the slide
so basically some summary points hints
and tips for covering printing as I said
before remember to set the printing port
with each call to PM begin pay after the
call to pin begin page remember to spool
only the pages selected by the user we
will print every page at a school to us
a third point is on Mac os10 let us
display the schooling progress dialog we
will be putting up the progress dialog
and that will be the way that the user
will be able to cancel the spooling of
the job and then call p.m. session set
error to for any errors during dead
occurred during page drawing we cannot
detect every error that meet you may
encounter when you're drawing your pages
such as QT errors or something of the
sort so therefore make sure that you set
this if you call p.m. session set error
then the print we will cancel out of the
print loop and you can deal with you can
deal with the error especially all on
the basic carbon printing now like to
talk about the printing dialog using
getting the printing guide will show up
as sheets basically we have two new AP
is that were asking developers to use
the first one is p.m. session use sheets
basically three basic parameters which
is first one is the session which I
talked about second one is the document
window that is the document window that
you want the sheet to appear attached to
so basically it's basically just the
window that the document basically
basically gets your document window and
the third parameter is basically a proc
pointer upp and this is what gets called
when the user dismisses the dialogues
one thing to remember about when you're
using sheets your call to p.m. session
print dialog is that will return
immediately to you as in before be
before if you don't use this call the
basically the call 2pm print dialog will
not return until the user has dismissed
the dialogue so if you're using sheet
that will turn it return immediately to
you and the sheet done proc will get
called when your user distance of the
dialogue and this is a sample of a sheet
done call back Rock what we give what we
get back to you when users this is a
dialogue is they took the print session
again the document window that's of that
the dialogue was attached to again so
you can get any data you need to and the
last parameter is accepted which
basically did the user canceled or print
out of the dialogue now I'd like to do
again is show you how easy it is we go
back to the demo machine how easy it is
to convert your app to using sheets if
you're already using the set if you're
already using the session a p-i-m-p have
your application split up correctly or
factored not correctly but factor in a
way that makes this easy basically this
is basically the same front loop that I
showed before the only where is it the
beginning of course
well the difference is when we make the
window we were going to save some saw
save some stuff off into a document info
you know record if we're saving out the
page format and the other things that
you may need and setting it to the rough
count in the window that way during our
call back we will be able to extract
this information out of out of the
window so basically let me just run it
first to show you that when you're not
using sheets let's go ahead and run it
just a silly you know hello world sample
app go to print and it's the modal
application mole it is you know it is
true the only application loaded on like
eight and nine or did it go there it is
so we'll just cancel this and quit so 24
to make this use sheets what I will do
in here it is before I call p.m. session
print dialog i am going to basically
create a upp or create my diet you move
my dialogue done croc upp make the call
to p.m. session news sheets basically
i'm giving it this print session the
parent window that i wanted to display
against and our upp and then i want to
comment out these two lines where we
actually the print that was actually
done because this will be called i will
show you this instead will be called an
hour call back proc which is right above
this basically here's our print dialog
done print dialog done proc basically if
it's accepted the user said print
extract our document info pointer out of
the way out of the rough con and if i
got the guy got the information i just
do the front loop passing in the page
format and print settings so with that
done I can just
compile it
come on
it's linking and stuff okay now we can
run it and I do print magically we are
now printing it as a sheet everything
you get from sheets are there summary
everything like that so as you see in
this little sample if your print loop is
factored out of your dupe out of showing
your print dialog it's not that much if
you're and you're already using sessions
there is not that much more work needed
to get your dialogue or you're getting
the print dialog to show as sheets so if
we could have to go back to the slides
like to summarize go back to the slides
I could summarize basically when you're
what's some of the key points of using
dialog sheets first point is p.m.
session page setup dialog and p.m.
session print like return immediately to
the caller that means the values that
the PM print settings and PM page
formatted objects that are passed into
it are not really valid until the your
callback croc is called yeah that's the
next point is basically not battle until
your done proc is called and last
point about dialog sheets creating
dialogues that are customized by the
ependymal method will not be shown the
sheets even if the call is made to use
sheets there's a different API which is
dialogue main dial dialogue and it
dialogue main those calls will go
through the normal what will a cute
normally and basically the dialogues
will appear as the modal dialogues with
that like the hand back to Paul
Paul where are you oh there and you will
think about an organization issues okay
so I'm going to try not to confuse you
I'll probably confuse myself I'm going
to try to go through some user interface
issues with carbon printing there's a
couple of things have come up and
discussions with developers in the past
year so i think it's worth going through
some of these there are some developers
who want to print without user interface
at all there are others who decide that
the page setup dialog just make sense
for them because they have their own
document format dialog or equivalent and
there are others that want to do things
like for example configure a printer or
download songs to printer they want to
use the printing system but they have no
need for for any of our user interface
elements so I've start off with just a
reminder of a pointer meet this morning
that like many other things in carbon
we've decided or rather it's been
decided that we should split our headers
and our frameworks into two so we have
p.m. applications which used to contain
everything now just contains the
function prototypes for all the h atom
and print dialog our calls pretty much
everything else is being put into p.m.
core so there's all the access of
functions or the functions to create and
deal with the page format objects and
print settings objects and lots of all
our constants and type data etc and TM
definitions so if you have got need to
print without a UI there's no need for
you to compile against link or load the
UI related framework
now this is what I'm going to get
tripped up but I'm going to attempt to
avoid stating the obvious or to explain
why we have a page setup dialog why we
have a print dialog why the two are
different and why it's not a good idea
to try to link the two together but what
we're trying to do to address some of
the needs that you have so simply put
the page setup dialog is all about
defining the parameters of the logical
page into which your applications going
to image its document and I think most
people understand that but obviously for
a lot of users they associate page setup
with what they're going to do
subsequently at print time so it makes
sense for them to pick a paper size as a
document size and for that reason we
have a pop-up in the page setup dialog
which those printers so you can format
documents for a particular printer and
we have a paper size pop up scaling
orientation etc so that's well known and
I think well understood and related to
by the average user an in theory those
settings are quite independent of what
you'll do a print time and of course the
print dialog is for things that really
have very little to do with how the
contents of the documents are imaged you
pick the number of copies in the page
range etc the two I distinct but of
course the distinctions often probably
lost on users of some applications and
because users quite often I guess
besides that are going to print to a
different printer at print time some
applications have allows you to place
which room and get back to the page
setup dialog from the print dialog so
we're going to try to address this issue
by providing an API and providing a
facility for you to load a paper
selection pde in other words an extra
panel in the print dialog which can be
used as they do to pick a paper size to
pick an orientation possibly scaling etc
and to avoid the need to ever switch
back to page setup so not in DP for bit
in the subsequent release we will add
another API to the growing list of API
us we have the printing it will allow
you to tell the printing system to load
this panel and I think it will take care
of the needs that some of you have felt
in the past to provide a button to take
you back to page setup from the print
dialog so there's a couple of
repercussions of doing this if you can
pick a paper type an orientation of
print time maybe you think you don't
need a page setup dialog and there's
some applications which I mentioned have
their own document setup or document
formatting dialogues which often overlap
the functionality as a page setup dialog
so we are quite happy if you choose to
live without a page setup dialog because
it makes sense he or your users if you
do that though you've got to take to
make two choices you can either call the
PM application ap is to emulate what
happens at page setup time to set a page
size or other paper size as gaining an
orientation or you can bypass the thing
altogether and call this API which we've
got this bit here p.m. CET adjusted pay
direct which just goes straight to the
heart of things and defines a logical
page into which your applications and
images document content but the thing is
that you do have to call either the
api's that emulate what happens to the
page setup time or this other API
because you can't go into the print
dialog pretty certain i can't go to
print if you haven't created a valid
p.m. page format object
if you if you do this sort of thing of
course you're you're incurring page to
paper mapping code at print time because
of course you are now allowed to create
a document which doesn't match cleanly
to the pages each decided to print it on
and you can decide of course whether
scaling is appropriate to fits of
documents to the paper or whether you
want to clip or tile there are various
solutions what we're going to do in the
print center application is provide a UI
so the user generically can tell the
printing system how you should by
default deal with these page to pay for
mapping issues so maybe I'm printing to
an a for printer and I'm always getting
documents that were formatted for us
later well I might just say that I want
the printing system to always scale the
pages for me and I would do that by a
print center of course applications I
want to get in the get into control this
so we'll also be adding an API again
post VP for which they would allow you
to tell the printing system how you want
us to do the page to pay for mapping so
hopefully that addresses some of the
issues that have been floating around
between the developers an apple over the
last year those set of issues to do with
printing as I mentioned is what if you
want to write a utility that downloads
wants the printer what happens if you
want to write a a utility to configure a
printer or to calibrate a printer in the
past people have written standalone
applications to do that and in the past
a lot of applications sorry lot of
printers have had nights user-friendly
applicable connection and that has been
fairly straightforward but now we're
dealing with printers they have USB
connections they have I think in future
will cease or the firewire printers
you've got different network protocols
so if you're writing one of these
utilities you've got to face the fact
that you might have to communicate to
the printer over there is channel
and then you look at tioga and you say
well we've got all these nice io modules
why can't we just use those and our
answer is that well maybe you could and
we could publicize the api's that host
io modules and prints browse modules etc
but our preferred solution is to let you
write plugins for print center so that
if you need to write a font downloading
utility or printer calibration utility
you do that at the plug-in instead of a
standalone application so we'd encourage
you if you're if you're in that sort of
business come and talk to us or email us
and let us know what you want to do and
of course I think long term you may have
to open up some of these api so
certainly short term our strategy is to
use print center as a host for those
sort of operations the last thing we've
got here on the UI front is really a
word of warning to anybody who wants to
print without the user interface there
are AP is that we provided therein p.m.
core that allow you to do things the
obvious things like set the number of
page number of copies you want to print
to the page range but of course we if
you'll notice we haven't provided API so
that you can set layout options for
doing an up or printing the cover page
etc and we could we could add those of
course but it's not in our plans if you
think you want to print without the
print dialog and you need access to that
for the functionality then you should
talk to us of course there is a
workaround which is user you I create
those settings save them off flattened
print settings objects and then use them
in your you wireless printing utility
but I think you realize that for basic
you wireless printing you shouldn't have
the full set of features that you get if
you display a printer on
okay my second topic is for people who
either like to generate their own post
script or occasionally find themselves
planning documents containing postscript
like eps graphics and it might be
interesting just to get a show of hands
how many people write applications to
generate their own post it fair few
maybe 20 30 people in the audience and
how many of you have applications which
can take an eps graphic into a document
and then you have to deal with printing
there okay same number okay so as you
probably know when you print through or
think as I pointed out when you print
through tioga on 10 you're effectively
printing to a quick-draw printer because
by default we turn quick drawing to PDF
and then we turn PDF into PostScript or
bits so if you want to generate your own
post script or if you want to hand eps
into a school file you're going to have
to use some of the api's that i've
listed here and i'll take you to them
fairly quickly first of all the
something we put in the original version
of the carbon printing header file p.m.
is postscript driver I'll Mac OS 8 and 9
if you call that all the carbon printing
manager does is just check the WD fields
with the print record the current driver
and if it's free you know you're
printing to the laserwriter driver or
maybe Adobe's driver and will return
true is there a return for that call you
call that routine on 10 though it always
return false because as I said by
default we're a quick draw we behave as
a quick tour printer and we only turn
quick draw calls at the bottom next
level into into PDF so what do you do
about it well you should start looking
at what we call the document format AP
is and therefore of them first one on
the list is get document format
generation and what that will do is that
will return to you the list of school
file format that the print job creature
in the converter are able of able to
generate for
you get document for my generation
actually returns to you the current
flavor of school file format that will
be generated and like it's not the
result of that call will be PDF actually
we return a mine type that is the result
will tell you that it's PDF by default
set document format generation is a way
to tell the printing system I want to
fix less full file format so you can
specify PDF you can also specify pics
with postscript and we are architected
to support other school file formats
going forward the first routine you
likely to call though is sketch document
format supported because what that tells
you is what sort of school file formats
can be accepted by the the converter and
the Prince of module associated with my
current printer so I'm printing to a
raster printer there's no point in
thinking that you can generate a
postscript school file because we don't
have by default in the system opposed to
a trip but if you're printing to a
poster printer you call this routine
you're likely to get back a list that
says PDF and picked with PostScript so
if you call this API you'll get back
that list and then you can go and call
the the API both back and say I want to
generate a pic with subscript school
file and generate my own post script or
including eps graphics in the job stream
the large routine their p.m. session is
document format supported is just a
shorthand way of finding out if a
particular school file format is
available to you so basically with these
AP is you can put toga printing on ten
into what I call the laserwriter eight
compatibility mode it will get the print
job creator to use laserwriter 840 code
to generate a pic with post get full
file and downstream at the server end of
tioga will turn that in to post it for
you if you don't call these api by
default we sit in the quick tour
bottleneck use core graphics to generate
a PDF full file and then downstream we
can turn that into other bits or into
postscript
the last batch of API is pretty
straightforward they replace or rather
they they make it a little bit more easy
to use the old post cryptic comment
mechanisms using these in your page
drawing codes you can insert PostScript
into the school file and in a moment
I'll show you a little bit of code to
demonstrate how this document format
api's works I'm going to talk about one
more issue here first so the previous
API is all about putting PostScript in
the spool file and they're really
talking about doing things with
PostScript of the page level that
difficult or impossible to do with quick
draw and that only goes so far and there
are people who want to have finer
control over the PostScript they put
into the spool file and the post clipper
get sent to the printer you know the
common case is you want to add your own
prospect in the prologue of the job or
you want to get in there and change or
add post group to the documental page
setup thoughts the postscript file
because your UI for printing allows you
to do things like invokes and trapping
in the red for example so we need a way
beyond the the api's I just showed you
to tell the printing system to put
PostScript in different sections of the
final output the prototype shown here is
a work in progress so he may change the
name but I think the arguments are
pretty solid basically it's a way for
you at the in your printing code to add
a bunch of post code snippets to the job
and send it downstream so those posted
significant can be added as appropriate
places in the final output the center to
the poster printer and that's the eff
array is an array of CF dictionaries and
ETF dictionary contains the tag or a
keyword and a snippet of PostScript and
if you look at the tech notes as
mentioned here it's all about writing
post gets out put filters to lose weight
rx7 you will see that
certainly the back of the techno there's
a big long set of tables which lists all
these tags and they map pretty closely
to Adobe's document structure and
conventions they identify specific
points in the postscript job and
basically all you would need to do is
create a list of postcode snippets that
you want inserted at these points in the
postscript file and hand out to the
printing system basically attach it to
the print settings object when you're
printing and what we will do at the
server side of clogher when we get this
dictionary is we will dutifully go and
insert your post code snippet in the
postscript stream that we send to the
printer if you're interested in using
this API you should certainly talk to us
because it's a work in progress it
obviously has used the high end printing
applications I think I know who you guys
are but just in case I miss anybody make
it known that you're interested in this
API and will work with you and get it
right so the first one is introduced
into probably the next version of
macular thing that goes out to
developers so lastly if we can just
switch over to the demo machine which
demo machine
this one okay I'm just going to show you
that some of those document format calls
show you how easy it is to I can find it
bear with me a moment sample code for
print sample okay
alright so hopefully that point is okay
find is my friend well we don't have a
pop-up get the functions
ok
all I'm going to show you here is the
sort of codes that you would use if you
want you to tell the printing system to
generate a pic with posted school file
instead of a PDF full file first point I
want to make clear is that if you're
going to use code like this you don't
want to be calling this inside you're
certainly not inside your page drawing
part of the print loop you need to call
this before you even invoke the print
dialog because you're telling us to
generate the pics with postscript spool
file when we bug the print dialog we
need to know whether we can enable the
preview button and we of course know how
to preview PDF but we don't have
anything right now which will preview
pigs with PostScript so if you called
the API to tell us to generate a non PDF
full file will be disabling the preview
button and then it's a an exercise for
the reader to write your own pics with
PostScript previewer so the first
interesting call is 2 p.m. session get
formats get document formats supported
basically here we're just providing
we're just getting back a list it's an
array of spear strings that we get back
as a result of calling this and what's
happening under the hood is that we're
going to the printer module and the
converter that belongs to the current
printer which is associated with the
conference session finding out what it
can do and returning that that list is
42 spool file formats to the caller next
we could just going to go through this
list we see how many are supported
typically if you've got a poster printer
at the this is your current printer num
supported formats will probably be three
and three is because the first result
will be the default full file format the
second one will will be PDF and the
third one will probably be picked with
PostScript but you want to make sure so
we go through this array and we check
each entry in the array to see if
it matches the string / KPM document
format text PS which is defined in p.m.
definitions and that's the fun is a mime
type so it's amputation / pic PS if we
find a match then we call this routine
p.m. CET document format generation and
just scroll across a little bit here
what we're doing is we're saying for
this print session I want you to
generate a pic with post-its full file
so I want you to go into laser ridereid
compatibility mode and I didn't expand
upon it but this third argument is there
to provide you with a list of graphic
context that you're going to be using to
draw your pages by default and null
means the default I'm just going to be
using a quick tour context to draw my
pages but I can provide it with I can I
can tell the printing system I'm going
to beat all my pages with core graphics
so I'll just tell it that I wanted to
call graphics context or i can say i
want to use a combo of the two so I can
use those quick tour and core graphics
to image my document during the print
loop and I think if you went to earlier
sessions you'll know that a lot of the
core graphics api's are being opened up
for you to use even within carbon
applications that's pretty much it the
rest of this routine just cleans up and
higher up in the code but I don't think
I need to show you in the page showing
portion of this sample code we omit
postscript and that goes into the school
file so with that
I think we can go back to the slides
Simone's just to summarize so for
typical applications printing on 10 hi
ogre appears of the quick-draw printer
so you can't send PostScript by pic
comment PDF is the mainstream school
file format and we'd rather equity use
PDF of course I've got lots of
advantages like you can preview it and
it's page independent etc and resolution
independent if you want to generate your
own post script and certainly we
understand a lot of applications today
do that and we'll probably do that for
through a while we are allowing you to
do that and that's where those document
format a POS come in and lastly if you
want to do more advanced postscript
printing as the prototype api that i
showed on a previous slide we will be
introducing that if you think you're
going to use it then let us know because
we'll work with you and make sure the
api meets your needs and now we're going
to go on something very exciting we're
going to talk about how to write a
plug-in to extend the print dialog with
the page setup dialog them for that I'm
going to bring Mike Conley on stage it's
going to take you through all the nifty
code
your gadgets so first all thank Paul for
leaving me with plenty of time to
provide you in I glazing detail some of
the code and information about how to
write print dialogue extensions for thai
Yoga printing dialogues so you may have
member this slide from the beginning of
the session or the first session this
morning and I won't go into too much
detail about it except as I need to pad
the rest of the session the first method
which is no longer supported as you know
or not snow long as part of it is no
longer encouraged is the ependymal
method of extending a dialogue and we
won't talk about that much because
everybody knows how to do that and you
know what the downsides on that are
which are basically you don't get sheets
and you don't get status in the status
panel and all that good stuff the print
dialog extensions are the the preferred
way of extending dialogues in tioga and
the new Mac os10 printing manager
there's only support on a Mac os10 so
you don't get them on OS 9 they are
compatible with document local printing
so you get cheats and you have multiple
print dialogue open at the same time
same with page setup you can organize
your controls in your user face into
multiple panels with different titles on
each panel so the user has probably a
better user experience rather than
having everything crammed in one
dialogue if you're an application or a
printing module you can override the
controls in the printing dialogues
applications can override controls and
page setup and the printing modules can
override controls in both in printing
only application can also override
controls in the print dialog and
eventually hopefully fairly soon we will
have implemented code to handle inter
tendencies between the extensions so if
you have user options to depend on other
user options in the dialog we will
notify you when you need to up
your settings because something else has
changed so what does the printing dialog
extension look like all the printing
dialog extensions are based on CF plug
in CF plug-in is the preferred mechanism
for creating plug in code modules on OS
10 and it is to some extent based on I'm
actually to a large extent based on the
microsoft com plug-in model so on this
diagram here gives you sort of a real
basic overview of what that might look
like the primary entry point for any CF
plugin is the factory function the
purpose of the factory function is
returned and instance of an interface
and once you get that you can then go
ahead and get a reference into the
pointer of the function pointer table
for your plug-in or rather the host can
get that so you publish you basically
export a single a single entry point
which is your factory function and then
when we load your CF plug-in we do all
the work to get a hold of your function
table and jump into your routine inside
your plug-in you'll have the I unknown
interface this is a little piece of code
sits up the top of your CF plug-in and
provides the support for the CF plug-in
mechanism itself that handles ref
counting increment and decrement and it
also handles a query interface function
which gets to the interface the PD the
rest of your interface goes in they blow
that there are some pieces that are
specific to the printing manager so any
pre manager plugin will use these
particular functions and then following
that are the functions specific to your
particular plugin so for printing dialog
extensions you'd have the pde interface
functions there if you were doing a
different kind of plug in like a printer
browser module plugin you would have the
p the printer browser module api
influent it there and then of course the
rest of it is the implementation of all
that good stuff
just a quick note on terminology we tend
to use the words PDE or terms PDE and
user option sort of interchangeably a
user option is really a collection of
controls that appears in single panel in
the printing dialog whereas a PDE
technically is the plug-in that
implements those controls and in fact
one plugin can implement more than one
set of user option so even though it
tends to be a one-to-one mapping it
doesn't necessarily have to be and just
thought I'd point that out in case
anybody's confused though why we
sometimes call them user options we
sometimes call them PDAs there's a
distinction so how do you load a PE well
applications register their pdes with CF
plug in before you open up the dialogue
and then the printing manager will go
ahead and collect all the information
about them that it needs to it'll
actually load them and put them into the
dialogue as the dialogue comes up if
you're a printer module we will load
your plug-in for you so in CF parlance
application pdes tend to be dynamically
loaded and printer module pd's are
static that is their loading and the
registration occurs is all set up on the
disc whereas an application go ahead and
register the pd dynamically at runtime
and finally if you're an application
also when you load your user options
they will in the hierarchy of things
override any other user options that are
the same type printer modules comes
second and then finally the system user
options come laugh so here's the CF
plug-in API as I mentioned earlier the
first thing is a factory function which
as I said returns essentially a pointer
into a table that contains these three
other functions which is query interface
add ref and release so what you have to
do is a plug-in writers implement these
what we have to do on our end in the
printing dialogue and for any other of
our host software that that modes
plugins is call your factory function to
get back this pointer block into these
into these routines
the main one that's of really at real
interest is query interface because
that's the method that we use to get
ahold of the actual instance for the API
that we're looking for in this case
printing dialogue extension address and
release are there for ref counting and
[Music]
well bookkeeping pretty manager plugin
api okay all printing manager plugins
have to have the same have to have these
three functions implemented at the top
of their list of functions the first one
is get api version which as you might
guess returns you returns to us the
version of the API that you were using
when you created your plug-in and you
get that from the header file and you
just return that constant that way we
know you know what we're calling in to
retain and release again our ref
counting and that's those are
implemented separately in the event that
you use two separate objects to store
the function tables for your I unknown
versus your PDA interface so we can do
ref counting on the two for you if it
turns out that's not the case and
internally you just tie them together
and make them count the same thing so
you have different ways you can
implement that printing dialogue
extension API okay so this is the
actually important part prologue is the
first function that you get called or
first function viewers that will get
called by the printing dialogue when
they come up and load your plug-in
prologue allows us to acquire
information about your plug-in from you
we will get things from you like the
Creator code for your for your printer
module or from regular application a
type code that identifies what kind of
user options you're implementing so we
know whether or not you're going to
override somebody Apple will provide a
list of types for our Universal and
standard user options so Universal
things like page range of copies or
orientation things like that so that if
you want to override those you would
provide a user
option with the same type and we would
know to replace that we place ours with
that in addition let's say there's some
other oh yes you'll laugh you'll get or
you'll pass us the dimensions of your
user interface so we know what the
maximum range that you want to display
in our and one or two other things that
I can't remember off hand and right so
if you ask for more space than we can
provide you we won't load you right now
will call your terminate function and
tell you why and then you can go ahead
and redesign your user interface to sit
in a little smaller space to the extent
possible we will always try and
accommodate you initialize then gets
called if we get your stuff and
everything's cool we'll call your
initialize function and one of the
things we'll pass to you is a reference
which you need to store and pass back to
us anytime you call into any printing
manager functions that your plug-in may
have to call and we can talk about that
in a second oh and one of the other
things you'll get past which you can
supply to us and your prologue function
is a context value so you create a
context value basically a rest con you
can do anything you want 32-bit value
you pass it to us in the prologue call
and we will pass it to you and every
subsequent call we make to you so you
can store global data or whatever you
want to in that so it initialize time
then that's your time to go ahead and
load your controls we also supply you a
user payne reference a reference to a
control manager user pain into which you
have to embed all of your controls so
all of your controls for your PDE will
be embedded controls they will use the
control manager sorry the carbon event
model to receive events the application
does not have to support the carbon
event model but your pdes do so so you
embed those in your in that pain that
pain is the determines the pain that
will be displayed when the user selects
the panel from the
menu in the in the dialog box just
before your your panel becomes visible
you'll get an open call so you can do
anything you might want to do just
before your panel goes invisible you'll
get a close call just in case there's
anything you want to do and let's see
gets a sink is an interesting one think
is the call you get when we want you to
either read from or write to the session
objects the ether the page formatting
object or the Prince Prince settings
object and so this is how you'll get one
of these shortly after the initialized
call and you will be able then to
initialize your control likewise when
your controls change you can request a
sink call if you detect that something
has changed that you want to notify us
about and when you request that sink
call that's one of those callbacks I was
just telling you about you pass your
reference you will then get a call into
your sink function so that you can then
update the page format or print settings
object depending on which dialog you're
in this function becomes even more
interesting later on when we provide
dependency handling which house you can
talk about a little bit later get
summary text is the mechanism by which
you provide text for the summary panel
so you will provide to us a title for
each setting in your user option and the
actual human readable value for that
setting so if you wanted to have like
print quality you would have you know
high medium low or something like that
mention the closed function already
terminate is which gets called when
we're about to unload your printer
browser of printer dialog printing
dialog extension printer browser module
has roughly the same API so get confused
will also tell you why we're closing you
down so we'll pass you a status
conditions so you'll know why it
happened in case you know for instance
as I said earlier if you ask for too
much real estate will give you an error
conditions as why
oh boy okay get my hand so if we can go
to the demo mix number two
[Music]
alright so this is basically a very
simple printing dialogue extension it
has a single control in it for destroy
basically for demonstration purposes up
at the top of the function we're going
to well we all our declarations and all
that good stuff oh yeah obviously do we
do we actually define this part we
define a part of earlier right thanks
stay out farther today today we talked
about it in the custom info.plist file
for your plugin if you're doing a
printer module printing dialogue
extension you have to define these
various tags in your plist file this ID
is the ID for your factory function and
you specify the name of the actual
faculty function here then down below
you tell it which type of plug in that
factory function can return API
instances for and here's the here's the
same ID for the factory function here
and here and this is the type for the
Pring dialogue extension plug in so all
of your printing dial extensions will
have this value on the left and then
you'll have an ID for your plug-in
factory on the right we make some notice
in here about how you may want to during
your prologue call open up your resource
for it to get data for your controls and
so forth and so on and you can do that
with some sample code here we show you
how to define a bundle identifier which
has to be specified in the CP a plist
file and then from inside the code you
can actually do see a fun we'll get
buggle with identifier you pass
that bundle identifier and you'll get a
bundle reference and then you can do CS
bundle open bundle resource map to
actually get the resource file and you
get back a resource manager reference
number just like the good old days and
then you can do cure res file and all
that good stuff and UCF bungle to close
the resource map again so up at the top
of the file we have the address function
for the I unknown interface and you'll
notice that it basically takes this
takes this object here and then
increments the ref count field in it so
add rep just increments the ref count
and release will decrement the ref count
and at zero it will unregister the
factory and run with this unregistered
the instance for the factory function so
that's pretty much standard boilerplate
any CF plug-in that you do is I have to
do the same thing so I encourage you to
go read the CF plug-in documentation for
how to do this eventually it was hoped
that the project builder system will be
able to generate CF plugins directly and
a lot of this sort of crusty stuff at
the top will be taken care of for you by
the compiler and linker then following
that we have the printing managers
pretty manager plugin api for retain and
release which do very much the same
thing get api version here basically
takes a PM plugin api version object and
populate it with the constants from the
header so you just load this thing up
and then you return it these values are
very much so very similar to the verse
strain or the first resource values that
we've been using all along in mac OS a
create plug-in interface that one's been
a whole lot of time looking at the CF
plugging stuff but basically you create
away with what's called a V table that
terminology is vector table
pretty common for C++ sort of stuff but
basically can create this function
pointer table and you populate it with
pointers to your various functions and
you return a pointer to that as part of
the query interface call when would see
when we call you into your query
interface function asking for specific
API will get back pointer into that
function table and that way we'll be
able to have access then to all your all
your printing dialogues tensioning API
functions so here's the factory function
and it creates the I unknown v table
that we initially get back through which
we call query interface one of the
interesting things about query interface
i guess i'll just point out real quick
the extent that anything about Forry
interface is interesting is that it goes
ahead and it compares it looks the type
of API that you're asking for and
returns the appropriate pointer based on
which type you asked for so a given
factory function can return different
kinds of api's depending on your plugin
in this case you likely only have the
one but see if plugin allows you have
more than one in there again this is the
way you would implement perhaps more
than one user option in a given PDE
right you'd have a factory function that
would return more interfaces or you have
more than yeah you'd be able to turn
more than one so the first of the
printing dialog extension functions that
we're interested here is the prologue
and as you can see okay so we have to
creator the context code that we expect
back from you the Creator user option
kind a title that's what I forgot either
it's something and the max and min
extent the title is the title that
you're going to see in the pop-up menu
for universal and standard user options
we provide the title and we'll simply
ignore anything you pass back so the
title really is meaningful only if
you're implementing a custom pringle
extension the intent is to provide a
uniform constant location to search for
it to for the user to be able to find
certain types of features like print
quality or paper stores so
we'll provide the title localize it and
all that good stuff and the state views
of trouble if that's all you're doing is
is overriding an existing one or
providing a standard one you're doing a
custom you're on your own you provide it
the title will display it so we
initialize our context we fill in our
Max and mins we get our title with CF
string up here and put in a creator and
if we had an error we return an error so
next thing we get is an extra lies call
and we pass in that context code that
you supplied us with also some flags
which tell you certain things about or
we get back from you certain flags which
will tell us what you'd like to be able
to do and various other things those
flags are defined in the header file we
pass through your reference number so
that's your special reference number
don't lose it and we give you a user
pain into which you can draw and the
print session so you can get your
initialization from the print session
objects there so you check first thing
you do is you get your context you check
make sure your constants context is cool
if you need to you can save off a copy
of a pointer to the window by Ewing kit
controlling owner from the user pain get
your boundaries for your user paying
here and save those off and sit right
here we're keeping a copy of them around
this function here is our internal
function it gets our little it just gets
a rectangle that defines the bounds of
our control and then we create a new
control right here and we save our
reference off inside our context the
next thing we do is we embed our control
into the user pain and we make our
control visible because the user pain
will be invisible your control won't
show up until we decide to show it so
you go ahead and set yours to be visible
as soon as you've embedded it
and that way when it when we bring up
the user pain it will actually show up
if you make your control invisible then
you could make it visible when you get
your open call but makes life easier for
you if you just do it right away and we
don't have any particular flags to set
here so we just do that and we make an
internal call to our own our own sync
function inside this PDE here to
initialize our values so you can reuse
your code that way so that work I get
summary text again you get your context
let's too far and we expect back from
you a couple of CF array reps so you're
going to create two arrays one array of
titles when array of summary strings and
the title corresponds to the particular
control that of control and summary
string will tell us what the value of
that control or what the setting on that
control is and we will display all that
text in the summary pain so you'll get a
call to get summary text when the user
actually brings up the summary pain if
the user never does it you'll never see
this call again you see up to create the
array get your control value push your
strings in here here's your future title
for the control and stick them in the
pointers provided and return sync gives
you a context and a print session so
from the print session you can get all
the relevant objects which you need
reference in order to get your control
settings and a boolean to reinitialize
the plugin okay so bhuiyan tells you
which way you're going whether you're
reading or writing okay if it's true
you're reading if it's false you're
writing so and so here we go we do a
there are a number of ways they're going
to be probably somewhat slicker ways to
get the get the print objects out of the
print session in the final api's but
right now we just grab them out of there
and then we do a p.m ticket get boolean
to find out what our setting is and then
we set the control value to
one of the two values to a fault
essentially this else statement is the
elf that says okay so that's if we were
if we were reading if we're writing
where you go to the control we get the
control value and then we set the ticket
the print settings ticket either with
the true or false value here's the open
call and as you can see we decided that
we really don't need to do anything when
you open call come but there it is
anyway you still have to implement it I
mean if you don't implement it on the
pointer is null then we won't obviously
be calling you but you know be nice to
so there is there if you need it to
explain just a hook and clothes same
thing we decided we didn't need to do
anything there and terminate as you can
see we get a status and the context so
the status will tell you why you're
being terminated and if you've been a
good boy or girl you'll get a no error
there and then we find if you do get an
error there there's not a whole lot you
can do about it it's purely for your
information so we mainly a debugging
tool so that you know what you've done
something wrong something of course that
everything survived long enough for us
actually to call you at that point so
let's see now you dispose of your
control dispose of your context and
return any we have some of our internal
functions how we initialize our context
to just do a new pointer and so forth so
I think that's that's enough of that so
we came back to the slides please
so summary with printing all extensions
use standard control manager calls
you'll be using you'll be embedding your
controls into a user pain so that we can
show it and hide it easily and we don't
have to know anything about what your
hierarchy looks like use the carpet
event model handle events for the most
part you probably won't even need to
handle events unless you're doing
something special with a control where
you actually need to intercept events
and so forth if you do you need to write
an event handler apps do not need to
support the carbon event model in order
to use these but the pd itself does so
even if you're not you know you even
application that's using the old style
events you'll still work fine if you
have your own pd's you want to load them
and get events and all that that'll all
work you synchronize with the PM session
object the page format and print
settings object in your sink call either
reading or writing data and provide
useful summary text for the user useful
localized summary text so that when
bring your user brings up a summary pain
you'll be able to tell at a glance what
your settings are keeping short and
sweet but informative don't write tones
and tones and stuff more don't don't
draw outside your user pain please don't
draw in our dialogue don't try to talk
to other pdes don't talk to strangers
right we are going to provide you with a
mechanism to register dependencies on
other piece on other types of user
options and we will automatically call
your sync function when those
dependencies are triggered so don't go
trying to read other people's data to
try and figure out what's going on will
will let you know don't don't write
another PDE data don't go messing around
with somebody else's settings behind
their back because then we don't know
that that's happened and they don't know
that that's happened and everybody gets
really confused and things get messy if
you have a user pain user panel controls
in there try not to scroll controls
scrolling controls is around
on these days try to fit everything into
your panel if you need another panel
make another panel you have as many as
you like and don't bring up lots of
extra dialogue to try and like get more
stuff on the screen if you can you know
it's an alert is one thing that's fine
but you know don't like have lots and
lots of dialogues we need more dialogues
at another panel you can have too many
do I and at that I'm going to turn it
back over to fall who's right here
someplace thanks so I just got two
things down to what might get to say
first is that we don't have it posted
yet but I believe in a week or two
you'll find on the carbon documentation
site there will be a very comprehensive
and complete right up on how to develop
pdes and we'll get that sample code out
to you and I think you'll find it rather
easy to write and I would say just
showing how easy it is to write that a
few months ago I was I guess brave
enough to try to write one when the code
wasn't nearly as organized as as it is
now and I even got my panel up on the on
the screen course in so today and I
think we've deleted it that just proves
that is easy to do now we would have had
a Q&A session but the clock in front of
me saying that we've got that's the 38
seconds to go so there's a feedback
forum and I wish I could tell you where
it was maybe the next slide will tell us
okay in a two so if you have more
questions about printing and it's
certainly if you have questions about
graphics or anything relating to the two
I'll ask you to join us at five o'clock
in hawley to thank you very much
Oh Diane never heat chalo young men
dying in the street