summaryrefslogtreecommitdiff
path: root/doc/printing.txt
blob: ee7c08f8c63bc1a5620234d49b9b93388a4a98ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

* Print Properties

** How W97 does print properties

3 scopes:

	+ per document: each document has a page size setting, this is
	                constant, to avoid re-layout.
	+ per printer: there is a default 'paper size' setting, this
		       is (perhaps) analgous to gnome-cups-manager's
	+ per session: if you change the 'paper size' - it persists only
		       for that session, in effect with a copy of the	
		       settings for that printer.

	Since we 

** Issue

	Staroffice has a synchronous, modal properties dialog, that is
passed the PrinterInfo 'aInfo' structure in SalInfoPrinter::Setup,
then on exit JobData is transfered to the pJobSetup passed to
'::Setup' by 'copyJobDataToJobSetup'.

	Unfortunately, we can't do this - since gnome-print-manager
fires off a separate process that creates the dialog.

	We need to unwind what is done with that; and whether we can
simply delay that work until StartJob time - which (presumably) gets
the same pJobSetup.

	'Setup' is called by vcl/source/gdi/print.cxx (Setup), all the
data appears to be local. If the sal level data has changed;
'ImplUpdateJobSetupPaper' + ImplUpdatePageData + ImplUpdateFontList
are called.

	ImplUpdateJobSetupPaper pokes at and verifies the contents of
the JobSetup impl, to set standard page sizes etc. There is also a UNO
'UserSetupCompleted' callback, that seems to do what we want.

	It doesn't _look_ like we can do this in
'SalPrinter::StartJob' NB. SalPrinter != SalInfoPrinter. The
UserSetupCompleted code is used only for the remote appserver case.

	Somehow we need to turn modality on; spawn the manager
synchronously etc. - or can we hook into StartJob ?

	Then again - it seems there is no messing about in
printdlg.cxx's (ImplPRopertiesHdl) wrt. re-synching changed settings.
After running the dialog we get a Printer->EnablePrintFile (foo) call
svtools/source/dialog/printdlg.cxx (ImplFillDialogData).

	Need to test the 'print' button to make that work; and/or
ensure that we re-parse ppd files occasionally.

	Is 'Printer::StartJob' always called before
'Printer::GetPaperSize*' ? It seems 'StartJob' emits the 'StartPrint'
signal.

	Can we update the PrinterInfo from the maJobSetup
unconditionally after the StartJob there ? Testing made hader by
Print::GetPaperSize[Pixel] being inline.

	The safest path seems to be via. the dialog; with a new API
addition to print.hxx (& salprn.hxx). I wonder how the windows backend
deals with this.

	The OK button in the svtools dialog (if we have a TEMPPRINTER)
dows a SetPrinterProps on mpPrinter. If you hit properties - it
creates a TEMPPRINTER. Printer::SetPrinterProps does a 'SetJobSetup',
which does a 'mpInfoPrinter->SetPrinterData (new_setup)' if the
printer names are the same & refreshes everything nicely.

	ARGH - discovered that the settings are per document in some
sense, and not in fact printer properties - but document/printer
properties: Bother !

	sdraw: new drawing, Page -> User 21x29.7
	config printer: ->A5,landscape -> No effect on new drawing
	   -> print settings -> vanished => per document

	Set settings from 'spadmin' -> A5,landscape
	Re-run - it uses that paper size [!] - nice :-)


	It seems CreateInfoPrinter->getJobInfo->mergeToJobData is the
live path for interesting information getting to the job info.
	Also PrinterGfx::Init (JobData) -> ::InitForPrinter, grabs
pParser & mbUploadPS42Fonts [etc.]

	It seems the PPDContext - is the place where settings must
lurk; 'getPageSize', setValue etc.

	Is printerjob.cxx::InitPaperSize - a valid PPD the source of
our margin problems ? - are we marginalized by it ;-)

** ARGH ** Two copies of PPDContext / PPDParser
	etc. vcl/inc/ppdparser.hxx vs psprint/inc/psprint/ppdparser.hxx


cf. vcl/inc/jobset.h

-- 


* TODO
	+ get vcl/inc/salprn.hxx (SalPrinterQueueInfo):
		+ mnStatus
		+ mnJobs 
		+ printer tray listing ...
	+ re-architect API to provide a sensible callback system
	  and / or mapping
	+ bin all uses of salprnpsp.cxx (getPaLib)

* The hard-core printing seems to go to a buffer and in:

	printerjob.cxx (EndJob): we have a popen () on the shell
command's stuff, looks like we should instead do a 'cupsFoo' there.

* salprnpsp.cxx includes psprint/printerinfomanager.hxx - good [!]

	vcl/source/gdi/print[2].cxx implement printing code,

* GUI is defined in:

	svtools/source/dialogs/printdlg.src

* configuration

	It seems we use a separate config file to work out which
printers to show to the user - rather than just using the output of
the commands we use to interrogate the system ... [ most curious ]

* Printing seems to be used in:

	vcl/unx/source/gdi/salprnpsp.cxx,
	vcl/unx/inc/salprn.h (SalPrinterData) - 'm_bFax' eg.

	again, all ugly public structs.

* Trace through a print toolbar item:

	sfx2/source/view/viewprn.cxx (DoPrint):
	sends an 'SFX_EVENT_PRINTDOC' to the SfxApp (OnPrint?) - untraceable

	SfxPrinter ...

* In the short term

	We can just support CUPS - and have nasty ugly printer
selection, but ensure that it actually works.

** Paths:
	+ source/printer/printerinfomanager.cxx
	none of the code is privatized - all hacky public structs [!]

** What does 'padmin' do ?

	Run 'spadmin' from program/ - a separate GUI, seemingly
inaccessible from the main app - we prolly don't want to ship /
support that.

	CUPS provides duplicate functionality here - so we just need
to bin spadmin.

** Postscript Prinder Description (PPD) files ...

	CUPS provides some PPD file handling (remote printers ?) -
OO.o also provides PPD stuff, do we need both ?

* How to port printing to libgnomeprint

	We need to attack printergfx.hxx - and progressively re-write
source/printergfx/common_gfx.cxx.


* How Printing works ...

OutputDevice::
	Implemented in vcl/source/gdi/outdev*
	Proxies rendering onto the mpGraphics context

class OutputDevice : public Resource
{
    friend class Window;
    friend class VirtualDevice;
    friend class Printer;
    friend class ImplQPrinter;
    friend class OpenGL;

private:
#ifndef REMOTE_APPSERVER
    SalGraphics*        mpGraphics;
#else
    ImplServerGraphics* mpGraphics;
#endif

	The SalGraphics comes from 'salgdi.hxx':

vcl/unx/source/gdi/salgdi.h

	Which implements:

vcl/inc/salgdi.hxx for X


psprint/inc/psprint/printerjob.hxx:

	SalGraphics * StartPage (const JobData& rJobSetup, sal_Bool bNewJobData);

seems to implement

vcl/inc/salprn.hxx

	class SalPrinter

vcl/inc/impprn.hxx

	class ImplQPrinter : public Printer

vcl/inc/print.hxx

	class Printer : public OutputDevice

vcl/inc/gdi/print.cxx: fetch an mpGraphics context:

	// we need a graphics
	if ( !ImplGetGraphics() )

vcl/source/gdi/outdev.cxx (ImplGetGraphics):

	else if ( meOutDevType == OUTDEV_PRINTER )
	{
		Printer* pPrinter = (Printer*)this;

		if ( pPrinter->mpJobGraphics )
			mpGraphics = pPrinter->mpJobGraphics;

[ vcl/source/gdi/print.cxx (StartPage): 

	if ( mpPrinter || mpQPrinter )
	{
		if ( mpPrinter )
		{
			SalGraphics* pGraphics = mpPrinter->StartPage( maJobSetup.ImplGetConstData(), mbNewJobSetup );
			if ( pGraphics )
			{
				ImplReleaseGraphics();
				mpJobGraphics = pGraphics;
			}
			mbDevOutput = TRUE;
		}
		else
		{
			ImplGetGraphics();
			mpJobGraphics = mpGraphics;
		}

	...
]

		else if ( pPrinter->mpDisplayDev )
		{
			VirtualDevice* pVirDev = pPrinter->mpDisplayDev;
			mpGraphics = pVirDev->mpVirDev->GetGraphics();

[ vcl/source/gdi/print.cxx (ImplInitDisplay):

	if ( pWindow )
		mpDisplayDev = new VirtualDevice( *pWindow );
	else
		mpDisplayDev = new VirtualDevice();

]

			while ( !mpGraphics )
			{
				if ( !pSVData->maGDIData.mpLastVirGraphics )
					break;
				pSVData->maGDIData.mpLastVirGraphics->ImplReleaseGraphics();
				mpGraphics = pVirDev->mpVirDev->GetGraphics();
			}
			if ( mpGraphics )
			{
				mpNextGraphics = pSVData->maGDIData.mpFirstVirGraphics;
				pSVData->maGDIData.mpFirstVirGraphics = this;
				if ( mpNextGraphics )
					mpNextGraphics->mpPrevGraphics = this;
				if ( !pSVData->maGDIData.mpLastVirGraphics )
					pSVData->maGDIData.mpLastVirGraphics = this;
			}
		}
		else
		{
			mpGraphics = pPrinter->mpInfoPrinter->GetGraphics();
			while ( !mpGraphics )
			{
				if ( !pSVData->maGDIData.mpLastPrnGraphics )
					break;
				pSVData->maGDIData.mpLastPrnGraphics->ImplReleaseGraphics();
				mpGraphics = pPrinter->mpInfoPrinter->GetGraphics();
			}
			if ( mpGraphics )
			{
				mpNextGraphics = pSVData->maGDIData.mpFirstPrnGraphics;
				pSVData->maGDIData.mpFirstPrnGraphics = this;
				if ( mpNextGraphics )
					mpNextGraphics->mpPrevGraphics = this;
				if ( !pSVData->maGDIData.mpLastPrnGraphics )
					pSVData->maGDIData.mpLastPrnGraphics = this;
			}
		}
	}