Takes print spooler functions out of win16drv.
[wine] / graphics / win16drv / init.c
1 /*
2  * Windows Device Context initialisation functions
3  *
4  * Copyright 1996 John Harvey
5  *           1998 Huw Davies
6  */
7
8 #include <string.h>
9 #include <ctype.h>
10 #include "windows.h"
11 #include "win16drv.h"
12 #include "gdi.h"
13 #include "bitmap.h"
14 #include "heap.h"
15 #include "color.h"
16 #include "font.h"
17 #include "options.h"
18 #include "xmalloc.h"
19 #include "debug.h"
20 #include "dc.h"
21
22 #define SUPPORT_REALIZED_FONTS 1
23 #pragma pack(1)
24 typedef struct
25 {
26   SHORT nSize;
27   SEGPTR lpindata;
28   SEGPTR lpFont;
29   SEGPTR lpXForm;
30   SEGPTR lpDrawMode;
31 } EXTTEXTDATA, *LPEXTTEXTDATA;
32 #pragma pack(4)
33
34 SEGPTR          win16drv_SegPtr_TextXForm;
35 LPTEXTXFORM16   win16drv_TextXFormP;
36 SEGPTR          win16drv_SegPtr_DrawMode;
37 LPDRAWMODE      win16drv_DrawModeP;
38
39
40 static BOOL32 WIN16DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device,
41                                  LPCSTR output, const DEVMODE16* initData );
42 static INT32 WIN16DRV_Escape( DC *dc, INT32 nEscape, INT32 cbInput, 
43                               SEGPTR lpInData, SEGPTR lpOutData );
44
45 static const DC_FUNCTIONS WIN16DRV_Funcs =
46 {
47     NULL,                            /* pArc */
48     NULL,                            /* pBitBlt */
49     NULL,                            /* pBitmapBits */
50     NULL,                            /* pChord */
51     NULL,                            /* pCreateBitmap */
52     WIN16DRV_CreateDC,               /* pCreateDC */
53     NULL,                            /* pDeleteDC */
54     NULL,                            /* pDeleteObject */
55     WIN16DRV_Ellipse,                /* pEllipse */
56     WIN16DRV_EnumDeviceFonts,        /* pEnumDeviceFonts */
57     WIN16DRV_Escape,                 /* pEscape */
58     NULL,                            /* pExcludeClipRect */
59     NULL,                            /* pExcludeVisRect */
60     NULL,                            /* pExtFloodFill */
61     WIN16DRV_ExtTextOut,             /* pExtTextOut */
62     WIN16DRV_GetCharWidth,           /* pGetCharWidth */
63     NULL,                            /* pGetPixel */
64     WIN16DRV_GetTextExtentPoint,     /* pGetTextExtentPoint */
65     WIN16DRV_GetTextMetrics,         /* pGetTextMetrics */
66     NULL,                            /* pIntersectClipRect */
67     NULL,                            /* pIntersectVisRect */
68     WIN16DRV_LineTo,                 /* pLineTo */
69     WIN16DRV_MoveToEx,               /* pMoveToEx */
70     NULL,                            /* pOffsetClipRgn */
71     NULL,                            /* pOffsetViewportOrgEx */
72     NULL,                            /* pOffsetWindowOrgEx */
73     NULL,                            /* pPaintRgn */
74     WIN16DRV_PatBlt,                 /* pPatBlt */
75     NULL,                            /* pPie */
76     NULL,                            /* pPolyPolygon */
77     NULL,                            /* pPolyPolyline */
78     WIN16DRV_Polygon,                /* pPolygon */
79     WIN16DRV_Polyline,               /* pPolyline */
80     NULL,                            /* pPolyBezier */
81     NULL,                            /* pRealizePalette */
82     WIN16DRV_Rectangle,              /* pRectangle */
83     NULL,                            /* pRestoreDC */
84     NULL,                            /* pRoundRect */
85     NULL,                            /* pSaveDC */
86     NULL,                            /* pScaleViewportExtEx */
87     NULL,                            /* pScaleWindowExtEx */
88     NULL,                            /* pSelectClipRgn */
89     WIN16DRV_SelectObject,           /* pSelectObject */
90     NULL,                            /* pSelectPalette */
91     NULL,                            /* pSetBkColor */
92     NULL,                            /* pSetBkMode */
93     NULL,                            /* pSetDeviceClipping */
94     NULL,                            /* pSetDIBitsToDevice */
95     NULL,                            /* pSetMapMode */
96     NULL,                            /* pSetMapperFlags */
97     NULL,                            /* pSetPixel */
98     NULL,                            /* pSetPolyFillMode */
99     NULL,                            /* pSetROP2 */
100     NULL,                            /* pSetRelAbs */
101     NULL,                            /* pSetStretchBltMode */
102     NULL,                            /* pSetTextAlign */
103     NULL,                            /* pSetTextCharacterExtra */
104     NULL,                            /* pSetTextColor */
105     NULL,                            /* pSetTextJustification */
106     NULL,                            /* pSetViewportExtEx */
107     NULL,                            /* pSetViewportOrgEx */
108     NULL,                            /* pSetWindowExtEx */
109     NULL,                            /* pSetWindowOrgEx */
110     NULL,                            /* pStretchBlt */
111     NULL                             /* pStretchDIBits */
112 };
113
114
115
116
117
118 /**********************************************************************
119  *           WIN16DRV_Init
120  */
121 BOOL32 WIN16DRV_Init(void)
122 {
123     return DRIVER_RegisterDriver( NULL /* generic driver */, &WIN16DRV_Funcs );
124         
125 }
126
127 /* Tempory functions, for initialising structures */
128 /* These values should be calculated, not hardcoded */
129 void InitTextXForm(LPTEXTXFORM16 lpTextXForm)
130 {
131     lpTextXForm->txfHeight      = 0x0001;
132     lpTextXForm->txfWidth       = 0x000c;
133     lpTextXForm->txfEscapement  = 0x0000;
134     lpTextXForm->txfOrientation = 0x0000;
135     lpTextXForm->txfWeight      = 0x0190;
136     lpTextXForm->txfItalic      = 0x00;
137     lpTextXForm->txfUnderline   = 0x00;
138     lpTextXForm->txfStrikeOut   = 0x00; 
139     lpTextXForm->txfOutPrecision = 0x02;
140     lpTextXForm->txfClipPrecision = 0x01;
141     lpTextXForm->txfAccelerator = 0x0001;
142     lpTextXForm->txfOverhang    = 0x0000;
143 }
144
145
146 void InitDrawMode(LPDRAWMODE lpDrawMode)
147 {
148     lpDrawMode->Rop2            = 0x000d;       
149     lpDrawMode->bkMode          = 0x0001;     
150     lpDrawMode->bkColor         = 0x3fffffff;    
151     lpDrawMode->TextColor       = 0x20000000;  
152     lpDrawMode->TBreakExtra     = 0x0000;
153     lpDrawMode->BreakExtra      = 0x0000; 
154     lpDrawMode->BreakErr        = 0x0000;   
155     lpDrawMode->BreakRem        = 0x0000;   
156     lpDrawMode->BreakCount      = 0x0000; 
157     lpDrawMode->CharExtra       = 0x0000;  
158     lpDrawMode->LbkColor        = 0x00ffffff;   
159     lpDrawMode->LTextColor      = 0x00000000;     
160 }
161
162 BOOL32 WIN16DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device, LPCSTR output,
163                           const DEVMODE16* initData )
164 {
165     LOADED_PRINTER_DRIVER *pLPD;
166     WORD wRet;
167     DeviceCaps *printerDevCaps;
168     int nPDEVICEsize;
169     PDEVICE_HEADER *pPDH;
170     WIN16DRV_PDEVICE *physDev;
171     char printerEnabled[20];
172     PROFILE_GetWineIniString( "wine", "printer", "off",
173                              printerEnabled, sizeof(printerEnabled) );
174     if (lstrcmpi32A(printerEnabled,"on"))
175     {
176         MSG("Printing disabled in wine.conf or .winerc file\n");
177         MSG("Use \"printer=on\" in the \"[wine]\" section to enable it.\n");
178         return FALSE;
179     }
180
181     TRACE(win16drv, "In creatdc for (%s,%s,%s) initData 0x%p\n",
182           driver, device, output, initData);
183
184     physDev = (WIN16DRV_PDEVICE *)HeapAlloc( SystemHeap, 0, sizeof(*physDev) );
185     if (!physDev) return FALSE;
186     dc->physDev = physDev;
187
188     pLPD = LoadPrinterDriver(driver);
189     if (pLPD == NULL)
190     {
191         WARN(win16drv, "Failed to find printer driver\n");
192         HeapFree( SystemHeap, 0, physDev );
193         return FALSE;
194     }
195     TRACE(win16drv, "windevCreateDC pLPD 0x%p\n", pLPD);
196
197     /* Now Get the device capabilities from the printer driver */
198     
199     printerDevCaps = (DeviceCaps *) xmalloc(sizeof(DeviceCaps));
200     memset(printerDevCaps, 0, sizeof(DeviceCaps));
201
202     /* Get GDIINFO which is the same as a DeviceCaps structure */
203     wRet = PRTDRV_Enable(printerDevCaps, GETGDIINFO, device, driver, output,NULL); 
204
205     /* Add this to the DC */
206     dc->w.devCaps = printerDevCaps;
207     dc->w.hVisRgn = CreateRectRgn32(0, 0, dc->w.devCaps->horzRes, dc->w.devCaps->vertRes);
208     dc->w.bitsPerPixel = dc->w.devCaps->bitsPixel;
209     
210     TRACE(win16drv, "Got devcaps width %d height %d bits %d planes %d\n",
211           dc->w.devCaps->horzRes, dc->w.devCaps->vertRes, 
212           dc->w.devCaps->bitsPixel, dc->w.devCaps->planes);
213
214     /* Now we allocate enough memory for the PDEVICE structure */
215     /* The size of this varies between printer drivers */
216     /* This PDEVICE is used by the printer DRIVER not by the GDI so must */
217     /* be accessable from 16 bit code */
218     nPDEVICEsize = dc->w.devCaps->pdeviceSize + sizeof(PDEVICE_HEADER);
219
220     /* TTD Shouldn't really do pointer arithmetic on segment points */
221     physDev->segptrPDEVICE = WIN16_GlobalLock16(GlobalAlloc16(GHND, nPDEVICEsize))+sizeof(PDEVICE_HEADER);
222     *((BYTE *)PTR_SEG_TO_LIN(physDev->segptrPDEVICE)+0) = 'N'; 
223     *((BYTE *)PTR_SEG_TO_LIN(physDev->segptrPDEVICE)+1) = 'B'; 
224
225     /* Set up the header */
226     pPDH = (PDEVICE_HEADER *)((BYTE*)PTR_SEG_TO_LIN(physDev->segptrPDEVICE) - sizeof(PDEVICE_HEADER)); 
227     pPDH->pLPD = pLPD;
228     
229     TRACE(win16drv, "PDEVICE allocated %08lx\n",(DWORD)(physDev->segptrPDEVICE));
230     
231     /* Now get the printer driver to initialise this data */
232     wRet = PRTDRV_Enable((LPVOID)physDev->segptrPDEVICE, INITPDEVICE, device, driver, output, NULL); 
233
234     physDev->FontInfo = NULL;
235     physDev->BrushInfo = NULL;
236     physDev->PenInfo = NULL;
237     win16drv_SegPtr_TextXForm = WIN16_GlobalLock16(GlobalAlloc16(GHND, sizeof(TEXTXFORM16)));
238     win16drv_TextXFormP = PTR_SEG_TO_LIN(win16drv_SegPtr_TextXForm);
239     
240     InitTextXForm(win16drv_TextXFormP);
241
242     /* TTD Lots more to do here */
243     win16drv_SegPtr_DrawMode = WIN16_GlobalLock16(GlobalAlloc16(GHND, sizeof(DRAWMODE)));
244     win16drv_DrawModeP = PTR_SEG_TO_LIN(win16drv_SegPtr_DrawMode);
245     
246     InitDrawMode(win16drv_DrawModeP);
247
248     return TRUE;
249 }
250
251 BOOL32 WIN16DRV_PatBlt( struct tagDC *dc, INT32 left, INT32 top,
252                         INT32 width, INT32 height, DWORD rop )
253 {
254   
255     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
256     BOOL32 bRet = 0;
257
258     bRet = PRTDRV_StretchBlt( physDev->segptrPDEVICE, left, top, width, height, (SEGPTR)NULL, 0, 0, width, height,
259                        PATCOPY, physDev->BrushInfo, win16drv_SegPtr_DrawMode, NULL);
260
261     return bRet;
262 }
263 /* 
264  * Escape (GDI.38)
265  */
266 static INT32 WIN16DRV_Escape( DC *dc, INT32 nEscape, INT32 cbInput, 
267                               SEGPTR lpInData, SEGPTR lpOutData )
268 {
269     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
270     int nRet = 0;
271
272     /* We should really process the nEscape parameter, but for now just
273        pass it all to the driver */
274     if (dc != NULL && physDev->segptrPDEVICE != 0)
275     {
276         switch(nEscape)
277           {
278           case ENABLEPAIRKERNING:
279             FIXME(win16drv,"Escape: ENABLEPAIRKERNING ignored.\n");
280             nRet = 1;
281             break;
282           case GETPAIRKERNTABLE:
283             FIXME(win16drv,"Escape: GETPAIRKERNTABLE ignored.\n");
284             nRet = 0;
285             break;
286           case SETABORTPROC: {
287                 /* FIXME: The AbortProc should be called:
288                 - After every write to printer port or spool file
289                 - Several times when no more disk space
290                 - Before every metafile record when GDI does banding
291                 */ 
292
293        /* save the callback address and call Control with hdc as lpInData */
294             HDC16 *seghdc = SEGPTR_NEW(HDC16);
295             *seghdc = dc->hSelf;
296             dc->w.lpfnPrint = (FARPROC16)lpInData;
297             nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
298                                   SEGPTR_GET(seghdc), lpOutData);
299             SEGPTR_FREE(seghdc);
300             break;
301           }
302
303           case NEXTBAND:
304             {
305               LPPOINT16 newInData =  SEGPTR_NEW(POINT16);
306
307               nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
308                                     SEGPTR_GET(newInData), lpOutData);
309               SEGPTR_FREE(newInData);
310               break;
311             }
312
313           case GETEXTENDEDTEXTMETRICS:
314             {
315               EXTTEXTDATA *textData = SEGPTR_NEW(EXTTEXTDATA);
316
317               textData->nSize = cbInput;
318               textData->lpindata = lpInData;
319               textData->lpFont = SEGPTR_GET( physDev->FontInfo );
320               textData->lpXForm = win16drv_SegPtr_TextXForm;
321               textData->lpDrawMode = win16drv_SegPtr_DrawMode;
322               nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
323                                     SEGPTR_GET(textData), lpOutData);
324               SEGPTR_FREE(textData);
325             }
326           break;
327           case STARTDOC:
328             nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
329                                   lpInData, lpOutData);
330             if (nRet != -1)
331             {
332               HDC32 *tmpHdc = SEGPTR_NEW(HDC32);
333
334 #define SETPRINTERDC SETABORTPROC
335
336               *tmpHdc = dc->hSelf;
337               PRTDRV_Control(physDev->segptrPDEVICE, SETPRINTERDC,
338                              SEGPTR_GET(tmpHdc), (SEGPTR)NULL);
339               SEGPTR_FREE(tmpHdc);
340             }
341             break;
342           default:
343             nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
344                                   lpInData, lpOutData);
345             break;
346         }
347     }
348     else
349         WARN(win16drv, "Escape(nEscape = %04x) - ???\n", nEscape);      
350     return nRet;
351 }
352