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