DIB Engine: fixes clipping, text and more
[wine/hacks.git] / dlls / winedib.drv / dc.c
blob9ffceee13a37d4e8f31bc717da3e3e760eba170b
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 /**********************************************************************
84 * device_init
86 * Perform initializations needed upon creation of the first device.
88 static void device_init(void)
90 Display *display;
91 Screen *screen;
93 /* opens default X11 Display */
94 if( (display = XOpenDisplay(NULL)) == NULL)
95 return;
97 /* gets default screen */
98 screen = XDefaultScreenOfDisplay(display);
100 /* gets screen sizes */
101 screen_width = XWidthOfScreen(screen);
102 screen_height = XHeightOfScreen(screen);
104 /* not sure about these ones... */
105 screen_bpp = XDefaultDepthOfScreen(screen);
106 screen_depth = XPlanesOfScreen(screen);
107 virtual_screen_rect.left = 0;
108 virtual_screen_rect.top = 0;
109 virtual_screen_rect.right = screen_width;
110 virtual_screen_rect.bottom = screen_height;
112 /* dummy ? */
113 palette_size = 0;
115 /* Initialize device caps */
116 log_pixels_x = log_pixels_y = get_dpi();
117 horz_size = MulDiv( screen_width, 254, log_pixels_x * 10 );
118 vert_size = MulDiv( screen_height, 254, log_pixels_y * 10 );
120 device_init_done = TRUE;
123 /* dummy null function for pen and brush */
124 static void dummy3(DIBDRVPHYSDEV *p, int a, int b, int c) {}
125 static void dummy4(DIBDRVPHYSDEV *p, int a, int b, int c, int d) {}
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 physDev->penColor = 0;
184 _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->penAnd, &physDev->penXor);
186 physDev->penStyle = PS_NULL;
187 physDev->penHLine = dummy3;
188 physDev->penVLine = dummy3;
189 physDev->penLine = dummy4;
190 physDev->penPattern = NULL;
192 physDev->brushColor = 0;
193 _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->brushAnd, &physDev->brushXor);
194 physDev->brushAnds = NULL;
195 physDev->brushXors = NULL;
197 physDev->brushStyle = BS_NULL;
198 physDev->brushHLine = dummy3;
200 physDev->isBrushBitmap = FALSE;
201 _DIBDRVBITMAP_Clear(&physDev->brushBitmap);
202 _DIBDRVBITMAP_Clear(&physDev->brushBmpCache);
204 /* text color */
205 physDev->textColor = 0;
206 physDev->textBackground = 0;
208 #ifdef DIBDRV_ANTIALIASED_FONTS
209 /* text color table for antialiased fonts */
210 memset(physDev->textColorTable, 0, 256);
211 #endif
213 /* freetype face associated to current DC HFONT */
214 physDev->face = NULL;
216 /* sets the result value and returns */
217 *pdev = physDev;
219 return TRUE;
222 /**********************************************************************
223 * DIBDRV_DeleteDC
225 BOOL DIBDRV_DeleteDC( DIBDRVPHYSDEV *physDev )
227 BOOL res;
229 MAYBE(TRACE("physDev:%p\n", physDev));
231 /* frees X11 device */
232 res = _DIBDRV_GetDisplayDriver()->pDeleteDC(physDev->X11PhysDev);
233 physDev->X11PhysDev = NULL;
235 /* frees physical bitmap */
236 _DIBDRVBITMAP_Free(&physDev->physBitmap);
238 /* frees brush bitmap */
239 _DIBDRVBITMAP_Free(&physDev->brushBitmap);
240 _DIBDRVBITMAP_Free(&physDev->brushBmpCache);
242 /* free brush ands and xors */
243 if(physDev->brushAnds)
245 HeapFree(GetProcessHeap(), 0, physDev->brushAnds);
246 HeapFree(GetProcessHeap(), 0, physDev->brushXors);
248 physDev->brushAnds = NULL;
249 physDev->brushXors = NULL;
251 /* frees clipping region */
252 DeleteObject(physDev->region);
253 if(physDev->regionData)
254 HeapFree(GetProcessHeap(), 0, physDev->regionData);
255 physDev->regionData = NULL;
256 physDev->regionRects = NULL;
257 physDev->regionRectCount = 0;
259 /* frees DIB Engine device */
260 HeapFree(GetProcessHeap(), 0, physDev);
262 return res;
265 /**********************************************************************
266 * DIBDRV_ExtEscape
268 INT DIBDRV_ExtEscape( DIBDRVPHYSDEV *physDev, INT escape, INT in_count, LPCVOID in_data,
269 INT out_count, LPVOID out_data )
271 INT res;
273 MAYBE(TRACE("physDev:%p, escape:%d, in_count:%d, in_data:%p, out_count:%d, out_data:%p\n",
274 physDev, escape, in_count, in_data, out_count, out_data));
276 if(physDev->hasDIB)
278 /* DIB section selected in, use DIB Engine */
279 ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
280 res = _DIBDRV_GetDisplayDriver()->pExtEscape(physDev->X11PhysDev, escape, in_count, in_data, out_count, out_data);
282 else
284 /* DDB selected in, use X11 driver */
285 res = _DIBDRV_GetDisplayDriver()->pExtEscape(physDev->X11PhysDev, escape, in_count, in_data, out_count, out_data);
287 return res;
290 /***********************************************************************
291 * DIBDRV_GetDeviceCaps
293 INT DIBDRV_GetDeviceCaps( DIBDRVPHYSDEV *physDev, INT cap )
295 INT res;
297 MAYBE(TRACE("physDev:%p, cap:%d\n", physDev, cap));
299 if(physDev->hasDIB)
301 /* DIB section selected in, use DIB Engine */
302 switch(cap)
304 case DRIVERVERSION:
305 res = 0x300;
306 break;
307 case TECHNOLOGY:
308 res = DT_RASDISPLAY;
309 break;
310 case HORZSIZE:
311 res = horz_size;
312 break;
313 case VERTSIZE:
314 res = vert_size;
315 break;
316 case HORZRES:
317 res = screen_width;
318 break;
319 case VERTRES:
320 res = screen_height;
321 break;
322 case DESKTOPHORZRES:
323 res = virtual_screen_rect.right - virtual_screen_rect.left;
324 break;
325 case DESKTOPVERTRES:
326 res = virtual_screen_rect.bottom - virtual_screen_rect.top;
327 break;
328 case BITSPIXEL:
329 res = screen_bpp;
330 break;
331 case PLANES:
332 res = 1;
333 break;
334 case NUMBRUSHES:
335 res = -1;
336 break;
337 case NUMPENS:
338 res = -1;
339 break;
340 case NUMMARKERS:
341 res = 0;
342 break;
343 case NUMFONTS:
344 res = 0;
345 break;
346 case NUMCOLORS:
347 /* MSDN: Number of entries in the device's color table, if the device has
348 * a color depth of no more than 8 bits per pixel.For devices with greater
349 * color depths, -1 is returned. */
350 res = (screen_depth > 8) ? -1 : (1 << screen_depth);
351 break;
352 case CURVECAPS:
353 res = (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
354 CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
355 break;
356 case LINECAPS:
357 res = (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
358 LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
359 break;
360 case POLYGONALCAPS:
361 res = (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
362 PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
363 break;
364 case TEXTCAPS:
365 res = text_caps;
366 break;
367 case CLIPCAPS:
368 res = CP_REGION;
369 break;
370 case RASTERCAPS:
371 res = (RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 | RC_DI_BITMAP |
372 RC_DIBTODEV | RC_BIGFONT | RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS |
373 (palette_size ? RC_PALETTE : 0));
374 break;
375 case SHADEBLENDCAPS:
376 res = (SB_GRAD_RECT | SB_GRAD_TRI | SB_CONST_ALPHA | SB_PIXEL_ALPHA);
377 case ASPECTX:
378 case ASPECTY:
379 res = 36;
380 break;
381 case ASPECTXY:
382 res = 51;
383 break;
384 case LOGPIXELSX:
385 res = log_pixels_x;
386 break;
387 case LOGPIXELSY:
388 res = log_pixels_y;
389 break;
390 case CAPS1:
391 FIXME("(%p): CAPS1 is unimplemented, will return 0\n", physDev->hdc );
392 /* please see wingdi.h for the possible bit-flag values that need
393 to be returned. */
394 res = 0;
395 break;
396 case SIZEPALETTE:
397 res = palette_size;
398 break;
399 case NUMRESERVED:
400 case COLORRES:
401 case PHYSICALWIDTH:
402 case PHYSICALHEIGHT:
403 case PHYSICALOFFSETX:
404 case PHYSICALOFFSETY:
405 case SCALINGFACTORX:
406 case SCALINGFACTORY:
407 case VREFRESH:
408 case BLTALIGNMENT:
409 res = 0;
410 break;
411 default:
412 FIXME("(%p): unsupported capability %d, will return 0\n", physDev->hdc, cap );
413 res = 0;
414 break;
417 else
419 /* DDB selected in, use X11 driver */
420 res = _DIBDRV_GetDisplayDriver()->pGetDeviceCaps(physDev->X11PhysDev, cap);
422 return res;