Implement DocumentProperties, DeviceCapabilities, beginnings of
[wine] / graphics / psdrv / driver.c
1 /*
2  * Exported functions from the PostScript driver.
3  *
4  * [Ext]DeviceMode, DeviceCapabilities, AdvancedSetupDialog. 
5  *
6  * Will need ExtTextOut for winword6 (urgh!)
7  *
8  * Copyright 1998  Huw D M Davies
9  *
10  */
11
12 #include <string.h>
13 #include "psdrv.h"
14 #include "debugtools.h"
15 #include "resource.h"
16 #include "winuser.h"
17 #include "winspool.h"
18
19 DEFAULT_DEBUG_CHANNEL(psdrv)
20
21
22 /************************************************************************
23  *
24  *              PSDRV_MergeDevmodes
25  *
26  * Updates dm1 with some fields from dm2
27  *
28  */
29 void PSDRV_MergeDevmodes(PSDRV_DEVMODEA *dm1, PSDRV_DEVMODEA *dm2,
30                          PRINTERINFO *pi)
31 {
32     /* some sanity checks here on dm2 */
33
34     if(dm2->dmPublic.dmFields & DM_ORIENTATION)
35         dm1->dmPublic.u1.s1.dmOrientation = dm2->dmPublic.u1.s1.dmOrientation;
36
37     /* NB PaperWidth is always < PaperLength */
38
39     if(dm2->dmPublic.dmFields & DM_PAPERSIZE) {
40         PAGESIZE *page;
41
42         for(page = pi->ppd->PageSizes; page; page = page->next) {
43             if(page->WinPage == dm2->dmPublic.u1.s1.dmPaperSize)
44                 break;
45         }
46         if(page) {
47             dm1->dmPublic.u1.s1.dmPaperSize = dm2->dmPublic.u1.s1.dmPaperSize;
48             dm1->dmPublic.u1.s1.dmPaperWidth = page->PaperDimension->x * 
49                                                                 254.0 / 72.0;
50             dm1->dmPublic.u1.s1.dmPaperLength = page->PaperDimension->y *
51                                                                 254.0 / 72.0;
52             TRACE("Changing page to %s %d x %d\n", page->FullName,
53                   dm1->dmPublic.u1.s1.dmPaperWidth,
54                   dm1->dmPublic.u1.s1.dmPaperLength );
55         } else {
56             TRACE("Trying to change to unsupported pagesize %d\n",
57                       dm2->dmPublic.u1.s1.dmPaperSize);
58         }
59     }
60
61     if(dm2->dmPublic.dmFields & DM_PAPERLENGTH) {
62         dm1->dmPublic.u1.s1.dmPaperLength = dm2->dmPublic.u1.s1.dmPaperLength; 
63         TRACE("Changing PaperLength to %d\n",
64               dm2->dmPublic.u1.s1.dmPaperLength);
65         FIXME("Changing PaperLength.  Do we adjust PaperSize?\n");
66     }
67
68     if(dm2->dmPublic.dmFields & DM_PAPERWIDTH) {
69         dm1->dmPublic.u1.s1.dmPaperWidth = dm2->dmPublic.u1.s1.dmPaperWidth; 
70         TRACE("Changing PaperWidth to %d\n",
71               dm2->dmPublic.u1.s1.dmPaperWidth);
72         FIXME("Changing PaperWidth.  Do we adjust PaperSize?\n");
73     }
74
75     if(dm2->dmPublic.dmFields & DM_SCALE) {
76         dm1->dmPublic.dmScale = dm2->dmPublic.dmScale;
77         TRACE("Changing Scale to %d\n", dm2->dmPublic.dmScale);
78     }
79
80     if(dm2->dmPublic.dmFields & DM_COPIES) {
81         dm1->dmPublic.dmCopies = dm2->dmPublic.dmCopies;
82         TRACE("Changing Copies to %d\n", dm2->dmPublic.dmCopies);
83     }
84
85     if(dm2->dmPublic.dmFields & DM_DEFAULTSOURCE) {
86         INPUTSLOT *slot;
87         
88         for(slot = pi->ppd->InputSlots; slot; slot = slot->next) {
89             if(slot->WinBin == dm2->dmPublic.dmDefaultSource)
90                 break;
91         }
92         if(slot) {
93             dm1->dmPublic.dmDefaultSource = dm2->dmPublic.dmDefaultSource;
94             TRACE("Changing bin to '%s'\n", slot->FullName);
95         } else {
96           TRACE("Trying to change to unsupported bin %d\n",
97                 dm2->dmPublic.dmDefaultSource);
98         }
99     }
100
101    if (dm2->dmPublic.dmFields & DM_DEFAULTSOURCE )
102        dm1->dmPublic.dmDefaultSource = dm2->dmPublic.dmDefaultSource;
103    if (dm2->dmPublic.dmFields & DM_PRINTQUALITY )
104        dm1->dmPublic.dmPrintQuality = dm2->dmPublic.dmPrintQuality;
105    if (dm2->dmPublic.dmFields & DM_COLOR )
106        dm1->dmPublic.dmColor = dm2->dmPublic.dmColor;
107    if (dm2->dmPublic.dmFields & DM_DUPLEX )
108        dm1->dmPublic.dmDuplex = dm2->dmPublic.dmDuplex;
109    if (dm2->dmPublic.dmFields & DM_YRESOLUTION )
110        dm1->dmPublic.dmYResolution = dm2->dmPublic.dmYResolution;
111    if (dm2->dmPublic.dmFields & DM_TTOPTION )
112        dm1->dmPublic.dmTTOption = dm2->dmPublic.dmTTOption;
113    if (dm2->dmPublic.dmFields & DM_COLLATE )
114        dm1->dmPublic.dmCollate = dm2->dmPublic.dmCollate;
115    if (dm2->dmPublic.dmFields & DM_FORMNAME )
116        strncpy(dm1->dmPublic.dmFormName, dm2->dmPublic.dmFormName, CCHFORMNAME);
117    if (dm2->dmPublic.dmFields & DM_BITSPERPEL )
118        dm1->dmPublic.dmBitsPerPel = dm2->dmPublic.dmBitsPerPel;
119    if (dm2->dmPublic.dmFields & DM_PELSWIDTH )
120        dm1->dmPublic.dmPelsWidth = dm2->dmPublic.dmPelsWidth;
121    if (dm2->dmPublic.dmFields & DM_PELSHEIGHT )
122        dm1->dmPublic.dmPelsHeight = dm2->dmPublic.dmPelsHeight;
123    if (dm2->dmPublic.dmFields & DM_DISPLAYFLAGS )
124        dm1->dmPublic.dmDisplayFlags = dm2->dmPublic.dmDisplayFlags;
125    if (dm2->dmPublic.dmFields & DM_DISPLAYFREQUENCY )
126        dm1->dmPublic.dmDisplayFrequency = dm2->dmPublic.dmDisplayFrequency;
127    if (dm2->dmPublic.dmFields & DM_POSITION )
128        dm1->dmPublic.u1.dmPosition = dm2->dmPublic.u1.dmPosition;
129    if (dm2->dmPublic.dmFields & DM_LOGPIXELS )
130        dm1->dmPublic.dmLogPixels = dm2->dmPublic.dmLogPixels;
131    if (dm2->dmPublic.dmFields & DM_ICMMETHOD )
132        dm1->dmPublic.dmICMMethod = dm2->dmPublic.dmICMMethod;
133    if (dm2->dmPublic.dmFields & DM_ICMINTENT )
134        dm1->dmPublic.dmICMIntent = dm2->dmPublic.dmICMIntent;
135    if (dm2->dmPublic.dmFields & DM_MEDIATYPE )
136        dm1->dmPublic.dmMediaType = dm2->dmPublic.dmMediaType;
137    if (dm2->dmPublic.dmFields & DM_DITHERTYPE )
138        dm1->dmPublic.dmDitherType = dm2->dmPublic.dmDitherType;
139    if (dm2->dmPublic.dmFields & DM_PANNINGWIDTH )
140        dm1->dmPublic.dmPanningWidth = dm2->dmPublic.dmPanningWidth;
141    if (dm2->dmPublic.dmFields & DM_PANNINGHEIGHT )
142        dm1->dmPublic.dmPanningHeight = dm2->dmPublic.dmPanningHeight;
143
144     return;
145 }
146
147
148 #if 0
149 /*******************************************************************
150  *
151  *              PSDRV_NewPrinterDlgProc32
152  *
153  *
154  */
155 LRESULT WINAPI PSDRV_NewPrinterDlgProc(HWND hWnd, UINT wMsg,
156                                             WPARAM wParam, LPARAM lParam)
157 {
158   switch (wMsg) {
159   case WM_INITDIALOG:
160     TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
161     ShowWindow(hWnd, SW_SHOWNORMAL);
162     return TRUE;
163  
164   case WM_COMMAND:
165     switch (LOWORD(wParam)) {
166     case IDOK:
167       EndDialog(hWnd, TRUE);
168       return TRUE;
169   
170     case IDCANCEL:
171       EndDialog(hWnd, FALSE);
172       return TRUE;
173     
174     default:
175       return FALSE;
176     }
177   
178   default:
179     return FALSE;
180   }
181 }
182
183 LRESULT WINAPI PSDRV_AdvancedSetupDlgProc(HWND hWnd, UINT wMsg,
184                                             WPARAM wParam, LPARAM lParam)
185 {
186   switch (wMsg) {
187   case WM_INITDIALOG:
188     TRACE("WM_INITDIALOG lParam=%08lX\n", lParam);
189     SendDlgItemMessageA(hWnd, 99, CB_ADDSTRING, 0, 
190                           (LPARAM)"Default Tray");
191     ShowWindow(hWnd, SW_SHOWNORMAL);
192     return TRUE;
193
194   case WM_COMMAND:
195     switch (LOWORD(wParam)) {
196     case IDOK:
197       EndDialog(hWnd, TRUE);
198       return TRUE;
199
200     case IDCANCEL:
201       EndDialog(hWnd, FALSE);
202       return TRUE;
203
204     case 200:
205       DialogBoxIndirectParamA( GetWindowLongA( hWnd, GWL_HINSTANCE ),
206                           SYSRES_GetResPtr( SYSRES_DIALOG_PSDRV_NEWPRINTER ),
207                           hWnd, PSDRV_NewPrinterDlgProc, (LPARAM) NULL );
208       return TRUE;
209
210     default:
211       return FALSE;
212     }
213
214   default:    
215     return FALSE;
216   }
217 }
218 #endif /* 0 */
219
220 /**************************************************************
221  *
222  *      PSDRV_AdvancedSetupDialog16     [WINEPS.93]
223  *
224  */
225 WORD WINAPI PSDRV_AdvancedSetupDialog16(HWND16 hwnd, HANDLE16 hDriver,
226                                          LPDEVMODEA devin, LPDEVMODEA devout)
227 {
228
229   TRACE("hwnd = %04x, hDriver = %04x devin=%p devout=%p\n", hwnd,
230         hDriver, devin, devout);
231   return IDCANCEL;
232
233
234 #if 0
235   return DialogBoxIndirectParamA( GetWindowLongA( hwnd, GWL_HINSTANCE ),
236         SYSRES_GetResPtr( SYSRES_DIALOG_PSDRV_ADVANCEDSETUP ),
237         hwnd, PSDRV_AdvancedSetupDlgProc, (LPARAM) NULL );
238 #endif
239
240
241 }
242
243 /***************************************************************
244  *
245  *      PSDRV_ExtDeviceMode16   [WINEPS.90]
246  *
247  * Just returns default devmode at the moment
248  */
249 INT16 WINAPI PSDRV_ExtDeviceMode16(HWND16 hwnd, HANDLE16 hDriver,
250                                    LPDEVMODEA lpdmOutput, LPSTR lpszDevice,
251                                    LPSTR lpszPort, LPDEVMODEA lpdmInput,
252                                    LPSTR lpszProfile, WORD fwMode)
253 {
254   PRINTERINFO *pi = PSDRV_FindPrinterInfo(lpszDevice);
255
256   TRACE("(hwnd=%04x, hDriver=%04x, devOut=%p, Device='%s', Port='%s', devIn=%p, Profile='%s', Mode=%04x)\n",
257 hwnd, hDriver, lpdmOutput, lpszDevice, lpszPort, lpdmInput, lpszProfile,
258 fwMode);
259
260   if(!fwMode)
261     return sizeof(DEVMODEA); /* Just copy dmPublic bit of PSDRV_DEVMODE */
262
263   if(fwMode & DM_PROMPT)
264     FIXME("Mode DM_PROMPT not implemented\n");
265
266   if(fwMode & DM_UPDATE)
267     FIXME("Mode DM_UPDATE.  Just do the same as DM_COPY\n");
268
269   if((fwMode & DM_MODIFY) && lpdmInput) {
270     TRACE("DM_MODIFY set. devIn->dmFields = %08lx\n", lpdmInput->dmFields);
271     PSDRV_MergeDevmodes(pi->Devmode, (PSDRV_DEVMODEA *)lpdmInput, pi);
272   }
273
274   if((fwMode & DM_COPY) || (fwMode & DM_UPDATE)) {
275     memcpy(lpdmOutput, pi->Devmode, sizeof(DEVMODEA));
276   }
277   return IDOK;
278 }
279
280 /**************************************************************
281  *
282  *       PSDRV_ExtDeviceMode
283  */
284 INT PSDRV_ExtDeviceMode(HWND hwnd, LPDEVMODEA lpdmOutput, LPSTR lpszDevice,
285                         LPSTR lpszPort, LPDEVMODEA lpdmInput,
286                         LPSTR lpszProfile, DWORD dwMode)
287 {
288     return PSDRV_ExtDeviceMode16(hwnd, 0, lpdmOutput, lpszDevice, lpszPort,
289                                  lpdmInput, lpszProfile, dwMode);
290 }
291
292 /***************************************************************
293  *
294  *      PSDRV_DeviceCapabilities16      [WINEPS.91]
295  *
296  */
297 DWORD WINAPI PSDRV_DeviceCapabilities16(LPCSTR lpszDevice, LPCSTR lpszPort,
298                                         WORD fwCapability, LPSTR lpszOutput,
299                                         LPDEVMODEA lpDevMode)
300 {
301   PRINTERINFO *pi;
302   DEVMODEA *lpdm;
303   pi = PSDRV_FindPrinterInfo(lpszDevice);
304   TRACE("Cap=%d. Got PrinterInfo = %p\n", fwCapability, pi);
305
306   lpdm = lpDevMode ? lpDevMode : (DEVMODEA *)pi->Devmode;
307
308   switch(fwCapability) {
309
310   case DC_PAPERS:
311     {
312       PAGESIZE *ps;
313       WORD *wp = (WORD *)lpszOutput;
314       int i = 0;
315
316       for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++)
317         if(lpszOutput != NULL)
318           *wp++ = ps->WinPage;
319       return i;
320     }
321
322   case DC_PAPERSIZE:
323     {
324       PAGESIZE *ps;
325       POINT16 *pt = (POINT16 *)lpszOutput;
326       int i = 0;
327
328       for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++)
329         if(lpszOutput != NULL) {
330           pt->x = ps->PaperDimension->x * 254.0 / 72.0;
331           pt->y = ps->PaperDimension->y * 254.0 / 72.0;
332           pt++;
333         }
334       return i;
335     }
336
337   case DC_PAPERNAMES:
338     {
339       PAGESIZE *ps;
340       char *cp = lpszOutput;
341       int i = 0;
342
343       for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++)
344         if(lpszOutput != NULL) {
345           strncpy(cp, ps->FullName, 64);
346           *(cp + 63) = '\0';
347           cp += 64;
348         }
349       return i;
350     }
351
352   case DC_ORIENTATION:
353     return pi->ppd->LandscapeOrientation ? pi->ppd->LandscapeOrientation : 90;
354
355   case DC_BINS:
356     {
357       INPUTSLOT *slot;
358       WORD *wp = (WORD *)lpszOutput;
359       int i = 0;
360
361       for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
362         if(lpszOutput != NULL)
363           *wp++ = slot->WinBin;
364       return i;
365     }
366
367   case DC_BINNAMES:
368     {
369       INPUTSLOT *slot;
370       char *cp = lpszOutput;
371       int i = 0;
372       
373       for(slot = pi->ppd->InputSlots; slot; slot = slot->next, i++)
374         if(lpszOutput != NULL) {
375           strncpy(cp, slot->FullName, 24);
376           *(cp + 23) = '\0';
377           cp += 24;
378         }
379       return i;
380     }
381
382   case DC_BINADJUST:
383     FIXME("DC_BINADJUST: stub.\n");
384     return DCBA_FACEUPNONE;
385
386   case DC_ENUMRESOLUTIONS:
387     {
388       LONG *lp = (LONG*)lpszOutput;
389
390       if(lpszOutput != NULL) {
391         lp[0] = (LONG)pi->ppd->DefaultResolution;
392         lp[1] = (LONG)pi->ppd->DefaultResolution;
393       }
394       return 1;
395     }
396
397   case DC_COPIES:
398     FIXME("DC_COPIES: returning %d.  Is this correct?\n", lpdm->dmCopies);
399     return lpdm->dmCopies;
400
401   case DC_DRIVER:
402     return lpdm->dmDriverVersion;
403
404   case DC_DATATYPE_PRODUCED:
405     FIXME("DATA_TYPE_PRODUCED: stub.\n");
406     return -1; /* simulate that the driver supports 'RAW' */
407
408   case DC_DUPLEX:
409     FIXME("DC_DUPLEX: returning %d.  Is this correct?\n", lpdm->dmDuplex);
410     return lpdm->dmDuplex;
411
412   case DC_EMF_COMPLIANT:
413     FIXME("DC_EMF_COMPLIANT: stub.\n");
414     return -1; /* simulate that the driver do not support EMF */
415
416   case DC_EXTRA:
417     return lpdm->dmDriverExtra;
418
419   case DC_FIELDS:
420     return lpdm->dmFields;
421
422   case DC_FILEDEPENDENCIES:
423     FIXME("DC_FILEDEPENDENCIES: stub.\n");
424     return 0;
425
426   case DC_MAXEXTENT:
427     {
428       PAGESIZE *ps;
429       int i;
430       POINT ptMax;
431       ptMax.x = ptMax.y = 0;
432
433       if(lpszOutput == NULL)
434         return -1;
435  
436       i = 0;
437       for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++) {
438         if(ps->PaperDimension->x > ptMax.x)
439           ptMax.x = ps->PaperDimension->x;
440         if(ps->PaperDimension->y > ptMax.y)
441           ptMax.y = ps->PaperDimension->y;
442       }
443       *((POINT*)lpszOutput) = ptMax;
444       return 1;
445     }
446
447   case DC_MINEXTENT:
448     {
449       PAGESIZE *ps;
450       int i;
451       POINT ptMax;
452       ptMax.x = ptMax.y = 0;
453
454       if(lpszOutput == NULL)
455         return -1;
456  
457       i = 0;
458       for(ps = pi->ppd->PageSizes; ps; ps = ps->next, i++) {
459         if(ps->PaperDimension->x > ptMax.x)
460           ptMax.x = ps->PaperDimension->x;
461         if(ps->PaperDimension->y > ptMax.y)
462           ptMax.y = ps->PaperDimension->y;
463       }
464       *((POINT*)lpszOutput) = ptMax;
465       return 1;
466     }
467
468   case DC_SIZE:
469     return lpdm->dmSize;
470
471   case DC_TRUETYPE:
472     FIXME("DC_TRUETYPE: stub\n");
473     return DCTT_SUBDEV;
474
475   case DC_VERSION:
476     return lpdm->dmSpecVersion;
477
478   default:
479     FIXME("Unsupported capability %d\n", fwCapability);
480   }
481   return -1;
482 }
483
484 /**************************************************************
485  *
486  *     PSDRV_DeviceCapabilities
487  */
488 DWORD PSDRV_DeviceCapabilities(LPCSTR lpszDevice, LPCSTR lpszPort,
489                                WORD fwCapability, LPSTR lpszOutput,
490                                LPDEVMODEA lpdm)
491 {
492   return PSDRV_DeviceCapabilities16(lpszDevice, lpszPort, fwCapability,
493                                     lpszOutput, lpdm);
494 }
495
496 /***************************************************************
497  *
498  *      PSDRV_DeviceMode16      [WINEPS.13]
499  *
500  */
501 void WINAPI PSDRV_DeviceMode16(HWND16 hwnd, HANDLE16 hDriver,
502 LPSTR lpszDevice, LPSTR lpszPort)
503 {
504     PSDRV_ExtDeviceMode16( hwnd, hDriver, NULL, lpszDevice, lpszPort, NULL, 
505                            NULL, DM_PROMPT );
506     return;
507 }