fdopen: don't rewind the file after creating the FILE* handle. Added
[wine] / dlls / gdi / win16drv / init.c
1 /*
2  * Windows Device Context initialisation functions
3  *
4  * Copyright 1996 John Harvey
5  *           1998 Huw Davies
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23 #include "wine/port.h"
24
25 #include <ctype.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "winreg.h"
30 #include "win16drv/win16drv.h"
31 #include "gdi.h"
32 #include "bitmap.h"
33 #include "wine/debug.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(win16drv);
36
37 #define SUPPORT_REALIZED_FONTS 1
38 #include "pshpack1.h"
39 typedef struct
40 {
41   SHORT nSize;
42   SEGPTR lpindata;
43   SEGPTR lpFont;
44   SEGPTR lpXForm;
45   SEGPTR lpDrawMode;
46 } EXTTEXTDATA, *LPEXTTEXTDATA;
47 #include "poppack.h"
48
49 SEGPTR          win16drv_SegPtr_TextXForm;
50 LPTEXTXFORM16   win16drv_TextXFormP;
51 SEGPTR          win16drv_SegPtr_DrawMode;
52 LPDRAWMODE      win16drv_DrawModeP;
53
54
55 static BOOL WIN16DRV_CreateDC( DC *dc, PHYSDEV *pdev, LPCSTR driver, LPCSTR device,
56                                  LPCSTR output, const DEVMODEA* initData );
57 static INT WIN16DRV_GetDeviceCaps( PHYSDEV dev, INT cap );
58 static INT WIN16DRV_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_data,
59                                INT out_count, LPVOID out_data );
60
61 static const DC_FUNCTIONS WIN16DRV_Funcs =
62 {
63     NULL,                            /* pAbortDoc */
64     NULL,                            /* pAbortPath */
65     NULL,                            /* pAngleArc */
66     NULL,                            /* pArc */
67     NULL,                            /* pArcTo */
68     NULL,                            /* pBeginPath */
69     NULL,                            /* pBitBlt */
70     NULL,                            /* pChoosePixelFormat */
71     NULL,                            /* pChord */
72     NULL,                            /* pCloseFigure */
73     NULL,                            /* pCreateBitmap */
74     WIN16DRV_CreateDC,               /* pCreateDC */
75     NULL,                            /* pCreateDIBSection */
76     NULL,                            /* pDeleteBitmap */
77     NULL,                            /* pDeleteDC */
78     NULL,                            /* pDescribePixelFormat */
79     WIN16DRV_DeviceCapabilities,     /* pDeviceCapabilities */
80     WIN16DRV_Ellipse,                /* pEllipse */
81     NULL,                            /* pEndDoc */
82     NULL,                            /* pEndPage */
83     NULL,                            /* pEndPath */
84     WIN16DRV_EnumDeviceFonts,        /* pEnumDeviceFonts */
85     NULL,                            /* pExcludeClipRect */
86     WIN16DRV_ExtDeviceMode,          /* pExtDeviceMode */
87     WIN16DRV_ExtEscape,              /* pExtEscape */
88     NULL,                            /* pExtFloodFill */
89     NULL,                            /* pExtSelectClipRgn */
90     WIN16DRV_ExtTextOut,             /* pExtTextOut */
91     NULL,                            /* pFillPath */
92     NULL,                            /* pFillRgn */
93     NULL,                            /* pFlattenPath */
94     NULL,                            /* pFrameRgn */
95     NULL,                            /* pGetBitmapBits */
96     WIN16DRV_GetCharWidth,           /* pGetCharWidth */
97     NULL,                            /* pGetDCOrgEx */
98     NULL,                            /* pGetDIBColorTable */
99     NULL,                            /* pGetDIBits */
100     WIN16DRV_GetDeviceCaps,          /* pGetDeviceCaps */
101     NULL,                            /* pGetDeviceGammaRamp */
102     NULL,                            /* pGetNearestColor */
103     NULL,                            /* pGetPixel */
104     NULL,                            /* pGetPixelFormat */
105     NULL,                            /* pGetSystemPaletteEntries */
106     WIN16DRV_GetTextExtentPoint,     /* pGetTextExtentPoint */
107     WIN16DRV_GetTextMetrics,         /* pGetTextMetrics */
108     NULL,                            /* pIntersectClipRect */
109     NULL,                            /* pInvertRgn */
110     WIN16DRV_LineTo,                 /* pLineTo */
111     NULL,                            /* pMoveTo */
112     NULL,                            /* pOffsetClipRgn */
113     NULL,                            /* pOffsetViewportOrgEx */
114     NULL,                            /* pOffsetWindowOrgEx */
115     NULL,                            /* pPaintRgn */
116     WIN16DRV_PatBlt,                 /* pPatBlt */
117     NULL,                            /* pPie */
118     NULL,                            /* pPolyBezier */
119     NULL,                            /* pPolyBezierTo */
120     NULL,                            /* pPolyDraw */
121     NULL,                            /* pPolyPolygon */
122     NULL,                            /* pPolyPolyline */
123     WIN16DRV_Polygon,                /* pPolygon */
124     WIN16DRV_Polyline,               /* pPolyline */
125     NULL,                            /* pPolylineTo */
126     NULL,                            /* pRealizeDefaultPalette */
127     NULL,                            /* pRealizePalette */
128     WIN16DRV_Rectangle,              /* pRectangle */
129     NULL,                            /* pResetDC */
130     NULL,                            /* pRestoreDC */
131     NULL,                            /* pRoundRect */
132     NULL,                            /* pSaveDC */
133     NULL,                            /* pScaleViewportExtEx */
134     NULL,                            /* pScaleWindowExtEx */
135     WIN16DRV_SelectBitmap,           /* pSelectBitmap */
136     WIN16DRV_SelectBrush,            /* pSelectBrush */
137     NULL,                            /* pSelectClipPath */
138     WIN16DRV_SelectFont,             /* pSelectFont */
139     NULL,                            /* pSelectPalette */
140     WIN16DRV_SelectPen,              /* pSelectPen */
141     NULL,                            /* pSetBitmapBits */
142     NULL,                            /* pSetBkColor */
143     NULL,                            /* pSetBkMode */
144     NULL,                            /* pSetDCOrg */
145     NULL,                            /* pSetDIBColorTable */
146     NULL,                            /* pSetDIBits */
147     NULL,                            /* pSetDIBitsToDevice */
148     NULL,                            /* pSetDeviceClipping */
149     NULL,                            /* pSetDeviceGammaRamp */
150     NULL,                            /* pSetMapMode */
151     NULL,                            /* pSetMapperFlags */
152     NULL,                            /* pSetPixel */
153     NULL,                            /* pSetPixelFormat */
154     NULL,                            /* pSetPolyFillMode */
155     NULL,                            /* pSetROP2 */
156     NULL,                            /* pSetRelAbs */
157     NULL,                            /* pSetStretchBltMode */
158     NULL,                            /* pSetTextAlign */
159     NULL,                            /* pSetTextCharacterExtra */
160     NULL,                            /* pSetTextColor */
161     NULL,                            /* pSetTextJustification */
162     NULL,                            /* pSetViewportExtEx */
163     NULL,                            /* pSetViewportOrgEx */
164     NULL,                            /* pSetWindowExtEx */
165     NULL,                            /* pSetWindowOrgEx */
166     NULL,                            /* pStartDoc */
167     NULL,                            /* pStartPage */
168     NULL,                            /* pStretchBlt */
169     NULL,                            /* pStretchDIBits */
170     NULL,                            /* pStrokeAndFillPath */
171     NULL,                            /* pStrokePath */
172     NULL,                            /* pSwapBuffers */
173     NULL                             /* pWidenPath */
174 };
175
176
177 /**********************************************************************
178  *           WIN16DRV_Init
179  */
180 const DC_FUNCTIONS *WIN16DRV_Init(void)
181 {
182     static int enabled = -1;
183
184     if (enabled == -1)
185     {
186         char printerEnabled[20];
187         HKEY hkey;
188
189         /* default value */
190         strcpy( printerEnabled, "off" );
191         if(!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\wine", &hkey))
192         {
193             DWORD type, count = sizeof(printerEnabled);
194             RegQueryValueExA(hkey, "printer", 0, &type, printerEnabled, &count);
195             RegCloseKey(hkey);
196         }
197         enabled = !strcasecmp( printerEnabled, "on" );
198         if (!enabled)
199         {
200             MESSAGE("Printing disabled in wine.conf or .winerc file\n");
201             MESSAGE("Use \"printer=on\" in the \"[wine]\" section to enable it.\n");
202         }
203     }
204
205     return enabled ? &WIN16DRV_Funcs : NULL;
206 }
207
208 /* Tempory functions, for initialising structures */
209 /* These values should be calculated, not hardcoded */
210 void InitTextXForm(LPTEXTXFORM16 lpTextXForm)
211 {
212     lpTextXForm->txfHeight      = 0x0001;
213     lpTextXForm->txfWidth       = 0x000c;
214     lpTextXForm->txfEscapement  = 0x0000;
215     lpTextXForm->txfOrientation = 0x0000;
216     lpTextXForm->txfWeight      = 0x0190;
217     lpTextXForm->txfItalic      = 0x00;
218     lpTextXForm->txfUnderline   = 0x00;
219     lpTextXForm->txfStrikeOut   = 0x00;
220     lpTextXForm->txfOutPrecision = 0x02;
221     lpTextXForm->txfClipPrecision = 0x01;
222     lpTextXForm->txfAccelerator = 0x0001;
223     lpTextXForm->txfOverhang    = 0x0000;
224 }
225
226
227 void InitDrawMode(LPDRAWMODE lpDrawMode)
228 {
229     lpDrawMode->Rop2            = 0x000d;
230     lpDrawMode->bkMode          = 0x0001;
231     lpDrawMode->bkColor         = 0x3fffffff;
232     lpDrawMode->TextColor       = 0x20000000;
233     lpDrawMode->TBreakExtra     = 0x0000;
234     lpDrawMode->BreakExtra      = 0x0000;
235     lpDrawMode->BreakErr        = 0x0000;
236     lpDrawMode->BreakRem        = 0x0000;
237     lpDrawMode->BreakCount      = 0x0000;
238     lpDrawMode->CharExtra       = 0x0000;
239     lpDrawMode->LbkColor        = 0x00ffffff;
240     lpDrawMode->LTextColor      = 0x00000000;
241     lpDrawMode->ICMCXform       = 0; /* ? */
242     lpDrawMode->StretchBltMode  = STRETCH_ANDSCANS;
243     lpDrawMode->eMiterLimit     = 1;
244 }
245
246 BOOL WIN16DRV_CreateDC( DC *dc, PHYSDEV *pdev, LPCSTR driver, LPCSTR device, LPCSTR output,
247                         const DEVMODEA* initData )
248 {
249     LOADED_PRINTER_DRIVER *pLPD;
250     WORD wRet;
251     int nPDEVICEsize;
252     PDEVICE_HEADER *pPDH;
253     WIN16DRV_PDEVICE *physDev;
254
255     TRACE("In creatdc for (%s,%s,%s) initData %p\n",
256           driver, device, output, initData);
257
258     physDev = (WIN16DRV_PDEVICE *)HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev) );
259     if (!physDev) return FALSE;
260     *pdev = (PHYSDEV)physDev;
261     physDev->hdc = dc->hSelf;
262     physDev->dc = dc;
263
264     pLPD = LoadPrinterDriver(driver);
265     if (pLPD == NULL)
266     {
267         WARN("Failed to find printer driver\n");
268         HeapFree( GetProcessHeap(), 0, physDev );
269         return FALSE;
270     }
271     TRACE("windevCreateDC pLPD %p\n", pLPD);
272
273     /* Now Get the device capabilities from the printer driver */
274     memset( &physDev->DevCaps, 0, sizeof(physDev->DevCaps) );
275     if(!output) output = "LPT1:";
276
277     /* Get GDIINFO which is the same as a DeviceCaps structure */
278     wRet = PRTDRV_Enable(&physDev->DevCaps, GETGDIINFO, device, driver, output,NULL);
279
280     /* Add this to the DC */
281     dc->bitsPerPixel = physDev->DevCaps.bitsPixel;
282
283     TRACE("Got devcaps width %d height %d bits %d planes %d\n",
284           physDev->DevCaps.horzRes, physDev->DevCaps.vertRes,
285           physDev->DevCaps.bitsPixel, physDev->DevCaps.planes);
286
287     /* Now we allocate enough memory for the PDEVICE structure */
288     /* The size of this varies between printer drivers */
289     /* This PDEVICE is used by the printer DRIVER not by the GDI so must */
290     /* be accessable from 16 bit code */
291     nPDEVICEsize = physDev->DevCaps.pdeviceSize + sizeof(PDEVICE_HEADER);
292
293     /* TTD Shouldn't really do pointer arithmetic on segment points */
294     physDev->segptrPDEVICE = K32WOWGlobalLock16(GlobalAlloc16(GHND, nPDEVICEsize))+sizeof(PDEVICE_HEADER);
295     *((BYTE *)MapSL(physDev->segptrPDEVICE)+0) = 'N';
296     *((BYTE *)MapSL(physDev->segptrPDEVICE)+1) = 'B';
297
298     /* Set up the header */
299     pPDH = (PDEVICE_HEADER *)((BYTE*)MapSL(physDev->segptrPDEVICE) - sizeof(PDEVICE_HEADER));
300     pPDH->pLPD = pLPD;
301
302     TRACE("PDEVICE allocated %08lx\n",(DWORD)(physDev->segptrPDEVICE));
303
304     /* Now get the printer driver to initialise this data */
305     wRet = PRTDRV_Enable((LPVOID)physDev->segptrPDEVICE, INITPDEVICE, device, driver, output, NULL);
306
307     physDev->FontInfo = NULL;
308     physDev->BrushInfo = NULL;
309     physDev->PenInfo = NULL;
310     win16drv_SegPtr_TextXForm = K32WOWGlobalLock16(GlobalAlloc16(GHND, sizeof(TEXTXFORM16)));
311     win16drv_TextXFormP = MapSL(win16drv_SegPtr_TextXForm);
312
313     InitTextXForm(win16drv_TextXFormP);
314
315     /* TTD Lots more to do here */
316     win16drv_SegPtr_DrawMode = K32WOWGlobalLock16(GlobalAlloc16(GHND, sizeof(DRAWMODE)));
317     win16drv_DrawModeP = MapSL(win16drv_SegPtr_DrawMode);
318
319     InitDrawMode(win16drv_DrawModeP);
320
321     return TRUE;
322 }
323
324 BOOL WIN16DRV_PatBlt( PHYSDEV dev, INT left, INT top, INT width, INT height, DWORD rop )
325 {
326
327     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dev;
328     BOOL bRet = 0;
329
330     bRet = PRTDRV_StretchBlt( physDev->segptrPDEVICE, left, top, width, height, (SEGPTR)NULL, 0, 0, width, height,
331                        PATCOPY, physDev->BrushInfo, win16drv_SegPtr_DrawMode, NULL);
332
333     return bRet;
334 }
335
336
337 /***********************************************************************
338  *           WIN16DRV_GetDeviceCaps
339  */
340 static INT WIN16DRV_GetDeviceCaps( PHYSDEV dev, INT cap )
341 {
342     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dev;
343     if (cap >= PHYSICALWIDTH || (cap % 2))
344     {
345         FIXME("(%p): unsupported capability %d, will return 0\n", physDev->hdc, cap );
346         return 0;
347     }
348     return *((WORD *)&physDev->DevCaps + (cap / 2));
349 }
350
351
352 /***********************************************************************
353  *           WIN16DRV_ExtEscape
354  */
355 static INT WIN16DRV_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_data,
356                                INT out_count, LPVOID out_data )
357 {
358 #if 0
359     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
360     int nRet = 0;
361
362     /* We should really process the nEscape parameter, but for now just
363        pass it all to the driver */
364     if (dc != NULL && physDev->segptrPDEVICE != 0)
365     {
366         switch(nEscape)
367           {
368           case ENABLEPAIRKERNING:
369             FIXME("Escape: ENABLEPAIRKERNING ignored.\n");
370             nRet = 1;
371             break;
372           case GETPAIRKERNTABLE:
373             FIXME("Escape: GETPAIRKERNTABLE ignored.\n");
374             nRet = 0;
375             break;
376           case SETABORTPROC: {
377                 /* FIXME: The AbortProc should be called:
378                 - After every write to printer port or spool file
379                 - Several times when no more disk space
380                 - Before every metafile record when GDI does banding
381                 */
382
383        /* Call Control with hdc as lpInData */
384             HDC16 *seghdc = SEGPTR_NEW(HDC16);
385             *seghdc = dc->hSelf;
386             nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
387                                   SEGPTR_GET(seghdc), lpOutData);
388             SEGPTR_FREE(seghdc);
389             break;
390           }
391
392           case NEXTBAND:
393             {
394               LPPOINT16 newInData =  SEGPTR_NEW(POINT16);
395
396               nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
397                                     SEGPTR_GET(newInData), lpOutData);
398               SEGPTR_FREE(newInData);
399               break;
400             }
401
402           case GETEXTENDEDTEXTMETRICS:
403             {
404               EXTTEXTDATA *textData = SEGPTR_NEW(EXTTEXTDATA);
405
406               textData->nSize = cbInput;
407               textData->lpindata = lpInData;
408               textData->lpFont = SEGPTR_GET( physDev->FontInfo );
409               textData->lpXForm = win16drv_SegPtr_TextXForm;
410               textData->lpDrawMode = win16drv_SegPtr_DrawMode;
411               nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
412                                     SEGPTR_GET(textData), lpOutData);
413               SEGPTR_FREE(textData);
414             }
415           break;
416           case STARTDOC:
417             {
418               /* lpInData is not necessarily \0 terminated so make it so */
419               char *cp = SEGPTR_ALLOC(cbInput + 1);
420               memcpy(cp, MapSL(lpInData), cbInput);
421               cp[cbInput] = '\0';
422
423               nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
424                                     SEGPTR_GET(cp), lpOutData);
425               SEGPTR_FREE(cp);
426               if (nRet != -1)
427                 {
428                   HDC *tmpHdc = SEGPTR_NEW(HDC);
429
430 #define SETPRINTERDC SETABORTPROC
431
432                   *tmpHdc = dc->hSelf;
433                   PRTDRV_Control(physDev->segptrPDEVICE, SETPRINTERDC,
434                                  SEGPTR_GET(tmpHdc), (SEGPTR)NULL);
435                   SEGPTR_FREE(tmpHdc);
436                 }
437             }
438             break;
439           default:
440             nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
441                                   lpInData, lpOutData);
442             break;
443         }
444     }
445     else
446         WARN("Escape(nEscape = %04x) - ???\n", nEscape);
447     return nRet;
448 #endif
449     /* FIXME: should convert args to SEGPTR and redo all the above */
450     FIXME("temporarily broken, please fix\n");
451     return 0;
452 }