DIB Engine: fixes against wine tests
[wine/hacks.git] / dlls / winedib.drv / dc.c
blobf5324b0e58202eb1c60611d800d1f7d9e68becfa
1 /*
2 * DIB driver initialization functions
4 * Copyright 2009 Massimo Del Fedele
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include "wine/port.h"
24 #include "dibdrv.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
29 /* some screen caps */
30 static unsigned int screen_width;
31 static unsigned int screen_height;
32 static unsigned int screen_bpp;
33 static unsigned int screen_depth;
34 static RECT virtual_screen_rect;
36 /* a few dynamic device caps */
37 static int log_pixels_x; /* pixels per logical inch in x direction */
38 static int log_pixels_y; /* pixels per logical inch in y direction */
39 static int horz_size; /* horz. size of screen in millimeters */
40 static int vert_size; /* vert. size of screen in millimeters */
41 static int palette_size;
42 static int device_init_done;
44 /* NOTE :
45 Removing TC_RA_ABLE avoids bitmapped fonts, so FT_Face is always non-NULL
46 UPDATE : remove TC_RA_ABLE seems unneeded
47 Adding TC_VA_ABLE forces to use gdi fonts always, so we can get an FT_Face
49 unsigned int text_caps = (TC_OP_CHARACTER | TC_OP_STROKE | TC_CP_STROKE |
50 TC_CR_ANY | TC_SA_DOUBLE | TC_SA_INTEGER |
51 TC_SA_CONTIN | TC_UA_ABLE | TC_SO_ABLE | TC_RA_ABLE | TC_VA_ABLE);
52 /* X11R6 adds TC_SF_X_YINDEP, Xrender adds TC_VA_ABLE */
55 static const WCHAR dpi_key_name[] = {'S','o','f','t','w','a','r','e','\\','F','o','n','t','s','\0'};
56 static const WCHAR dpi_value_name[] = {'L','o','g','P','i','x','e','l','s','\0'};
58 /******************************************************************************
59 * get_dpi
61 * get the dpi from the registry
63 static DWORD get_dpi( void )
65 DWORD dpi = 96;
66 HKEY hkey;
68 if (RegOpenKeyW(HKEY_CURRENT_CONFIG, dpi_key_name, &hkey) == ERROR_SUCCESS)
70 DWORD type, size, new_dpi;
72 size = sizeof(new_dpi);
73 if(RegQueryValueExW(hkey, dpi_value_name, NULL, &type, (void *)&new_dpi, &size) == ERROR_SUCCESS)
75 if(type == REG_DWORD && new_dpi != 0)
76 dpi = new_dpi;
78 RegCloseKey(hkey);
80 return dpi;
83 /* dummy function for pen/brush drawing primitives initializations */
84 static void dummy4(DIBDRVPHYSDEV *physDev, int a, int b, int c) {} ;
85 static void dummy5(DIBDRVPHYSDEV *physDev, int a, int b, int c, int d) {} ;
87 /**********************************************************************
88 * device_init
90 * Perform initializations needed upon creation of the first device.
92 static void device_init(void)
94 Display *display;
95 Screen *screen;
97 /* opens default X11 Display */
98 if( (display = XOpenDisplay(NULL)) == NULL)
99 return;
101 /* gets default screen */
102 screen = XDefaultScreenOfDisplay(display);
104 /* gets screen sizes */
105 screen_width = XWidthOfScreen(screen);
106 screen_height = XHeightOfScreen(screen);
108 /* not sure about these ones... */
109 screen_bpp = XDefaultDepthOfScreen(screen);
110 screen_depth = XPlanesOfScreen(screen);
111 virtual_screen_rect.left = 0;
112 virtual_screen_rect.top = 0;
113 virtual_screen_rect.right = screen_width;
114 virtual_screen_rect.bottom = screen_height;
116 /* dummy ? */
117 palette_size = 0;
119 /* Initialize device caps */
120 log_pixels_x = log_pixels_y = get_dpi();
121 horz_size = MulDiv( screen_width, 254, log_pixels_x * 10 );
122 vert_size = MulDiv( screen_height, 254, log_pixels_y * 10 );
124 device_init_done = TRUE;
127 /**********************************************************************
128 * DIBDRV_CreateDC
130 BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR device,
131 LPCWSTR output, const DEVMODEW* initData )
133 DIBDRVPHYSDEV *physDev;
134 PHYSDEV X11PhysDev;
136 MAYBE(TRACE("hdc:%p, pdev:%p, driver:%s, device:%s, output:%s, initData:%p\n",
137 hdc, pdev, debugstr_w(driver), debugstr_w(device), debugstr_w(output), initData));
139 /* allocates physical device */
140 physDev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DIBDRVPHYSDEV) );
141 if (!physDev)
142 return FALSE;
144 /* creates X11 physical device */
145 if(!_DIBDRV_GetDisplayDriver()->pCreateDC(hdc, &X11PhysDev, driver, device, output, initData))
147 HeapFree(GetProcessHeap(), 0, physDev);
148 return FALSE;
151 /* sets X11 Device pointer in DIB Engine device */
152 physDev->X11PhysDev = X11PhysDev;
154 /* stores the HDC */
155 physDev->hdc = hdc;
157 /* initializes device data (for GetDeviceCaps() )
158 on first DC creation */
159 if (!device_init_done)
160 device_init();
162 /* stock bitmap selected on DC creation */
163 physDev->hbitmap = GetStockObject(DEFAULT_BITMAP);
165 /* no DIB selected into DC on creation */
166 physDev->hasDIB = FALSE;
168 /* clear physical bitmap */
169 _DIBDRVBITMAP_Clear(&physDev->physBitmap);
171 /* clears pen and brush */
172 physDev->rop2 = R2_COPYPEN;
174 /* clipping region */
175 physDev->region = CreateRectRgn( 0, 0, 0, 0 );
176 physDev->regionData = NULL;
177 physDev->regionRects = NULL;
178 physDev->regionRectCount = 0;
180 physDev->backgroundColor = 0;
181 _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->backgroundAnd, &physDev->backgroundXor);
183 /* stock pen */
184 physDev->penStyle = PS_NULL;
185 physDev->penColor = 0;
186 physDev->penColorref = 0;
187 _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->penAnd, &physDev->penXor);
188 physDev->penHLine = dummy4;
189 physDev->penVLine = dummy4;
190 physDev->penLine = dummy5;
191 physDev->penPattern = NULL;
193 /* stock brush */
194 physDev->brushStyle = BS_NULL;
195 physDev->brushColor = 0x0;
196 physDev->brushColorref = 0x0;
197 _DIBDRV_CalcAndXorMasks(physDev->rop2, 0x0, &physDev->brushAnd, &physDev->brushXor);
198 physDev->brushAnds = NULL;
199 physDev->brushXors = NULL;
200 physDev->brushHLine = dummy4;
202 physDev->isBrushBitmap = FALSE;
203 _DIBDRVBITMAP_Clear(&physDev->brushBitmap);
204 _DIBDRVBITMAP_Clear(&physDev->brushBmpCache);
206 /* text color */
207 physDev->textColor = 0;
208 physDev->textBackground = 0;
210 #ifdef DIBDRV_ANTIALIASED_FONTS
211 /* text color table for antialiased fonts */
212 memset(physDev->textColorTable, 0, 256);
213 #endif
215 /* freetype face associated to current DC HFONT */
216 physDev->face = NULL;
218 /* sets the result value and returns */
219 *pdev = physDev;
221 return TRUE;
224 /**********************************************************************
225 * DIBDRV_DeleteDC
227 BOOL DIBDRV_DeleteDC( DIBDRVPHYSDEV *physDev )
229 BOOL res;
231 MAYBE(TRACE("physDev:%p\n", physDev));
233 /* frees X11 device */
234 res = _DIBDRV_GetDisplayDriver()->pDeleteDC(physDev->X11PhysDev);
235 physDev->X11PhysDev = NULL;
237 /* frees physical bitmap */
238 _DIBDRVBITMAP_Free(&physDev->physBitmap);
240 /* frees brush bitmap */
241 _DIBDRVBITMAP_Free(&physDev->brushBitmap);
242 _DIBDRVBITMAP_Free(&physDev->brushBmpCache);
244 /* free brush ands and xors */
245 if(physDev->brushAnds)
247 HeapFree(GetProcessHeap(), 0, physDev->brushAnds);
248 HeapFree(GetProcessHeap(), 0, physDev->brushXors);
250 physDev->brushAnds = NULL;
251 physDev->brushXors = NULL;
253 /* frees clipping region */
254 DeleteObject(physDev->region);
255 if(physDev->regionData)
256 HeapFree(GetProcessHeap(), 0, physDev->regionData);
257 physDev->regionData = NULL;
258 physDev->regionRects = NULL;
259 physDev->regionRectCount = 0;
261 /* frees DIB Engine device */
262 HeapFree(GetProcessHeap(), 0, physDev);
264 return res;
267 /**********************************************************************
268 * DIBDRV_ExtEscape
270 INT DIBDRV_ExtEscape( DIBDRVPHYSDEV *physDev, INT escape, INT in_count, LPCVOID in_data,
271 INT out_count, LPVOID out_data )
273 INT res;
275 MAYBE(TRACE("physDev:%p, escape:%d, in_count:%d, in_data:%p, out_count:%d, out_data:%p\n",
276 physDev, escape, in_count, in_data, out_count, out_data));
278 if(physDev->hasDIB)
280 /* DIB section selected in, use DIB Engine */
281 ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
282 res = _DIBDRV_GetDisplayDriver()->pExtEscape(physDev->X11PhysDev, escape, in_count, in_data, out_count, out_data);
284 else
286 /* DDB selected in, use X11 driver */
287 res = _DIBDRV_GetDisplayDriver()->pExtEscape(physDev->X11PhysDev, escape, in_count, in_data, out_count, out_data);
289 return res;
292 /***********************************************************************
293 * DIBDRV_GetDeviceCaps
295 INT DIBDRV_GetDeviceCaps( DIBDRVPHYSDEV *physDev, INT cap )
297 INT res;
299 MAYBE(TRACE("physDev:%p, cap:%d\n", physDev, cap));
301 if(physDev->hasDIB)
303 /* DIB section selected in, use DIB Engine */
304 switch(cap)
306 case DRIVERVERSION:
307 res = 0x300;
308 break;
309 case TECHNOLOGY:
310 res = DT_RASDISPLAY;
311 break;
312 case HORZSIZE:
313 res = horz_size;
314 break;
315 case VERTSIZE:
316 res = vert_size;
317 break;
318 case HORZRES:
319 res = screen_width;
320 break;
321 case VERTRES:
322 res = screen_height;
323 break;
324 case DESKTOPHORZRES:
325 res = virtual_screen_rect.right - virtual_screen_rect.left;
326 break;
327 case DESKTOPVERTRES:
328 res = virtual_screen_rect.bottom - virtual_screen_rect.top;
329 break;
330 case BITSPIXEL:
331 res = screen_bpp;
332 break;
333 case PLANES:
334 res = 1;
335 break;
336 case NUMBRUSHES:
337 res = -1;
338 break;
339 case NUMPENS:
340 res = -1;
341 break;
342 case NUMMARKERS:
343 res = 0;
344 break;
345 case NUMFONTS:
346 res = 0;
347 break;
348 case NUMCOLORS:
349 /* MSDN: Number of entries in the device's color table, if the device has
350 * a color depth of no more than 8 bits per pixel.For devices with greater
351 * color depths, -1 is returned. */
352 res = (screen_depth > 8) ? -1 : (1 << screen_depth);
353 break;
354 case CURVECAPS:
355 res = (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
356 CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
357 break;
358 case LINECAPS:
359 res = (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
360 LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
361 break;
362 case POLYGONALCAPS:
363 res = (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
364 PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
365 break;
366 case TEXTCAPS:
367 res = text_caps;
368 break;
369 case CLIPCAPS:
370 res = CP_REGION;
371 break;
372 case RASTERCAPS:
373 res = (RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 | RC_DI_BITMAP |
374 RC_DIBTODEV | RC_BIGFONT | RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS |
375 (palette_size ? RC_PALETTE : 0));
376 break;
377 case SHADEBLENDCAPS:
378 res = (SB_GRAD_RECT | SB_GRAD_TRI | SB_CONST_ALPHA | SB_PIXEL_ALPHA);
379 case ASPECTX:
380 case ASPECTY:
381 res = 36;
382 break;
383 case ASPECTXY:
384 res = 51;
385 break;
386 case LOGPIXELSX:
387 res = log_pixels_x;
388 break;
389 case LOGPIXELSY:
390 res = log_pixels_y;
391 break;
392 case CAPS1:
393 FIXME("(%p): CAPS1 is unimplemented, will return 0\n", physDev->hdc );
394 /* please see wingdi.h for the possible bit-flag values that need
395 to be returned. */
396 res = 0;
397 break;
398 case SIZEPALETTE:
399 res = palette_size;
400 break;
401 case NUMRESERVED:
402 case COLORRES:
403 case PHYSICALWIDTH:
404 case PHYSICALHEIGHT:
405 case PHYSICALOFFSETX:
406 case PHYSICALOFFSETY:
407 case SCALINGFACTORX:
408 case SCALINGFACTORY:
409 case VREFRESH:
410 case BLTALIGNMENT:
411 res = 0;
412 break;
413 default:
414 FIXME("(%p): unsupported capability %d, will return 0\n", physDev->hdc, cap );
415 res = 0;
416 break;
419 else
421 /* DDB selected in, use X11 driver */
422 res = _DIBDRV_GetDisplayDriver()->pGetDeviceCaps(physDev->X11PhysDev, cap);
424 return res;