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