---
title: WWDC2000 Session 112
framework: wwdc
role: article
path: wwdc/wwdc2000-112
---

# 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
