DIB Engine: implement most engine functions
[wine/hacks.git] / dlls / winedib.drv / dc.c
blob618467780221d361d9b70ef5b8aba75b0fcdf051
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 Adding TC_VA_ABLE forces to use gdi fonts always, so we can get an FT_Face
48 unsigned int text_caps = (TC_OP_CHARACTER | TC_OP_STROKE | TC_CP_STROKE |
49 TC_CR_ANY | TC_SA_DOUBLE | TC_SA_INTEGER |
50 TC_SA_CONTIN | TC_UA_ABLE | TC_SO_ABLE /* | TC_RA_ABLE */ | TC_VA_ABLE);
51 /* X11R6 adds TC_SF_X_YINDEP, Xrender adds TC_VA_ABLE */
54 static const WCHAR dpi_key_name[] = {'S','o','f','t','w','a','r','e','\\','F','o','n','t','s','\0'};
55 static const WCHAR dpi_value_name[] = {'L','o','g','P','i','x','e','l','s','\0'};
57 /******************************************************************************
58 * get_dpi
60 * get the dpi from the registry
62 static DWORD get_dpi( void )
64 DWORD dpi = 96;
65 HKEY hkey;
67 if (RegOpenKeyW(HKEY_CURRENT_CONFIG, dpi_key_name, &hkey) == ERROR_SUCCESS)
69 DWORD type, size, new_dpi;
71 size = sizeof(new_dpi);
72 if(RegQueryValueExW(hkey, dpi_value_name, NULL, &type, (void *)&new_dpi, &size) == ERROR_SUCCESS)
74 if(type == REG_DWORD && new_dpi != 0)
75 dpi = new_dpi;
77 RegCloseKey(hkey);
79 return dpi;
82 /**********************************************************************
83 * device_init
85 * Perform initializations needed upon creation of the first device.
87 static void device_init(void)
89 Display *display;
90 Screen *screen;
92 /* opens default X11 Display */
93 if( (display = XOpenDisplay(NULL)) == NULL)
94 return;
96 /* gets default screen */
97 screen = XDefaultScreenOfDisplay(display);
99 /* gets screen sizes */
100 screen_width = XWidthOfScreen(screen);
101 screen_height = XHeightOfScreen(screen);
103 /* not sure about these ones... */
104 screen_bpp = XDefaultDepthOfScreen(screen);
105 screen_depth = XPlanesOfScreen(screen);
106 virtual_screen_rect.left = 0;
107 virtual_screen_rect.top = 0;
108 virtual_screen_rect.right = screen_width;
109 virtual_screen_rect.bottom = screen_height;
111 /* dummy ? */
112 palette_size = 0;
114 /* Initialize device caps */
115 log_pixels_x = log_pixels_y = get_dpi();
116 horz_size = MulDiv( screen_width, 254, log_pixels_x * 10 );
117 vert_size = MulDiv( screen_height, 254, log_pixels_y * 10 );
119 device_init_done = TRUE;
122 /**********************************************************************
123 * DIBDRV_CreateDC
125 BOOL DIBDRV_CreateDC( HDC hdc, DIBDRVPHYSDEV **pdev, LPCWSTR driver, LPCWSTR device,
126 LPCWSTR output, const DEVMODEW* initData )
128 DIBDRVPHYSDEV *physDev;
129 PHYSDEV X11PhysDev;
131 MAYBE(TRACE("hdc:%p, pdev:%p, driver:%s, device:%s, output:%s, initData:%p\n",
132 hdc, pdev, debugstr_w(driver), debugstr_w(device), debugstr_w(output), initData));
134 /* allocates physical device */
135 physDev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DIBDRVPHYSDEV) );
136 if (!physDev)
137 return FALSE;
139 /* creates X11 physical device */
140 if(!_DIBDRV_GetDisplayDriver()->pCreateDC(hdc, &X11PhysDev, driver, device, output, initData))
142 HeapFree(GetProcessHeap(), 0, physDev);
143 return FALSE;
146 /* sets X11 Device pointer in DIB Engine device */
147 physDev->X11PhysDev = X11PhysDev;
149 /* stores the HDC */
150 physDev->hdc = hdc;
152 /* initializes device data (for GetDeviceCaps() )
153 on first DC creation */
154 if (!device_init_done)
155 device_init();
157 /* stock bitmap selected on DC creation */
158 physDev->hbitmap = GetStockObject(DEFAULT_BITMAP);
160 /* no DIB selected into DC on creation */
161 physDev->hasDIB = FALSE;
163 /* clear physical bitmap */
164 _DIBDRVBITMAP_Clear(&physDev->physBitmap);
166 /* clears pen and brush */
167 physDev->rop2 = R2_COPYPEN;
169 physDev->backgroundColor = 0;
170 _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->backgroundAnd, &physDev->backgroundXor);
172 physDev->penColor = 0;
173 _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->penAnd, &physDev->penXor);
175 physDev->brushColor = 0;
176 _DIBDRV_CalcAndXorMasks(physDev->rop2, 0, &physDev->brushAnd, &physDev->brushXor);
177 physDev->brushAnds = NULL;
178 physDev->brushXors = NULL;
180 physDev->brushStyle = BS_NULL;
182 physDev->isBrushBitmap = FALSE;
183 _DIBDRVBITMAP_Clear(&physDev->brushBitmap);
184 _DIBDRVBITMAP_Clear(&physDev->brushBmpCache);
186 /* text color */
187 physDev->textColor = 0;
188 physDev->textBackground = 0;
190 /* text color table for antialiased fonts */
191 memset(physDev->textColorTable, 0, 256);
193 /* freetype face associated to current DC HFONT */
194 physDev->face = NULL;
196 /* sets the result value and returns */
197 *pdev = physDev;
199 return TRUE;
202 /**********************************************************************
203 * DIBDRV_DeleteDC
205 BOOL DIBDRV_DeleteDC( DIBDRVPHYSDEV *physDev )
207 BOOL res;
209 MAYBE(TRACE("physDev:%p\n", physDev));
211 /* frees X11 device */
212 res = _DIBDRV_GetDisplayDriver()->pDeleteDC(physDev->X11PhysDev);
213 physDev->X11PhysDev = NULL;
215 /* frees physical bitmap */
216 _DIBDRVBITMAP_Free(&physDev->physBitmap);
218 /* frees brush bitmap */
219 _DIBDRVBITMAP_Free(&physDev->brushBitmap);
220 _DIBDRVBITMAP_Free(&physDev->brushBmpCache);
222 /* free brush ands and xors */
223 if(physDev->brushAnds)
225 HeapFree(GetProcessHeap(), 0, physDev->brushAnds);
226 HeapFree(GetProcessHeap(), 0, physDev->brushXors);
228 physDev->brushAnds = NULL;
229 physDev->brushXors = NULL;
231 /* frees DIB Engine device */
232 HeapFree(GetProcessHeap(), 0, physDev);
234 return res;
237 /**********************************************************************
238 * DIBDRV_ExtEscape
240 INT DIBDRV_ExtEscape( DIBDRVPHYSDEV *physDev, INT escape, INT in_count, LPCVOID in_data,
241 INT out_count, LPVOID out_data )
243 INT res;
245 MAYBE(TRACE("physDev:%p, escape:%d, in_count:%d, in_data:%p, out_count:%d, out_data:%p\n",
246 physDev, escape, in_count, in_data, out_count, out_data));
248 if(physDev->hasDIB)
250 /* DIB section selected in, use DIB Engine */
251 ONCE(FIXME("TEMPORARY - fallback to X11 driver\n"));
252 res = _DIBDRV_GetDisplayDriver()->pExtEscape(physDev->X11PhysDev, escape, in_count, in_data, out_count, out_data);
254 else
256 /* DDB selected in, use X11 driver */
257 res = _DIBDRV_GetDisplayDriver()->pExtEscape(physDev->X11PhysDev, escape, in_count, in_data, out_count, out_data);
259 return res;
262 /***********************************************************************
263 * DIBDRV_GetDeviceCaps
265 INT DIBDRV_GetDeviceCaps( DIBDRVPHYSDEV *physDev, INT cap )
267 INT res;
269 MAYBE(TRACE("physDev:%p, cap:%d\n", physDev, cap));
271 if(physDev->hasDIB)
273 /* DIB section selected in, use DIB Engine */
274 switch(cap)
276 case DRIVERVERSION:
277 res = 0x300;
278 break;
279 case TECHNOLOGY:
280 res = DT_RASDISPLAY;
281 break;
282 case HORZSIZE:
283 res = horz_size;
284 break;
285 case VERTSIZE:
286 res = vert_size;
287 break;
288 case HORZRES:
289 res = screen_width;
290 break;
291 case VERTRES:
292 res = screen_height;
293 break;
294 case DESKTOPHORZRES:
295 res = virtual_screen_rect.right - virtual_screen_rect.left;
296 break;
297 case DESKTOPVERTRES:
298 res = virtual_screen_rect.bottom - virtual_screen_rect.top;
299 break;
300 case BITSPIXEL:
301 res = screen_bpp;
302 break;
303 case PLANES:
304 res = 1;
305 break;
306 case NUMBRUSHES:
307 res = -1;
308 break;
309 case NUMPENS:
310 res = -1;
311 break;
312 case NUMMARKERS:
313 res = 0;
314 break;
315 case NUMFONTS:
316 res = 0;
317 break;
318 case NUMCOLORS:
319 /* MSDN: Number of entries in the device's color table, if the device has
320 * a color depth of no more than 8 bits per pixel.For devices with greater
321 * color depths, -1 is returned. */
322 res = (screen_depth > 8) ? -1 : (1 << screen_depth);
323 break;
324 case CURVECAPS:
325 res = (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
326 CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
327 break;
328 case LINECAPS:
329 res = (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
330 LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
331 break;
332 case POLYGONALCAPS:
333 res = (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
334 PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
335 break;
336 case TEXTCAPS:
337 res = text_caps;
338 break;
339 case CLIPCAPS:
340 res = CP_REGION;
341 break;
342 case RASTERCAPS:
343 res = (RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 | RC_DI_BITMAP |
344 RC_DIBTODEV | RC_BIGFONT | RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS |
345 (palette_size ? RC_PALETTE : 0));
346 break;
347 case SHADEBLENDCAPS:
348 res = (SB_GRAD_RECT | SB_GRAD_TRI | SB_CONST_ALPHA | SB_PIXEL_ALPHA);
349 case ASPECTX:
350 case ASPECTY:
351 res = 36;
352 break;
353 case ASPECTXY:
354 res = 51;
355 break;
356 case LOGPIXELSX:
357 res = log_pixels_x;
358 break;
359 case LOGPIXELSY:
360 res = log_pixels_y;
361 break;
362 case CAPS1:
363 FIXME("(%p): CAPS1 is unimplemented, will return 0\n", physDev->hdc );
364 /* please see wingdi.h for the possible bit-flag values that need
365 to be returned. */
366 res = 0;
367 break;
368 case SIZEPALETTE:
369 res = palette_size;
370 break;
371 case NUMRESERVED:
372 case COLORRES:
373 case PHYSICALWIDTH:
374 case PHYSICALHEIGHT:
375 case PHYSICALOFFSETX:
376 case PHYSICALOFFSETY:
377 case SCALINGFACTORX:
378 case SCALINGFACTORY:
379 case VREFRESH:
380 case BLTALIGNMENT:
381 res = 0;
382 break;
383 default:
384 FIXME("(%p): unsupported capability %d, will return 0\n", physDev->hdc, cap );
385 res = 0;
386 break;
389 else
391 /* DDB selected in, use X11 driver */
392 res = _DIBDRV_GetDisplayDriver()->pGetDeviceCaps(physDev->X11PhysDev, cap);
394 return res;