Release 961222
[wine/multimedia.git] / objects / dc.c
blobcfe93a195923c8c53f279c581d974560c2c12d99
1 /*
2 * GDI Device Context functions
4 * Copyright 1993 Alexandre Julliard
6 */
8 #define NO_TRANSITION_TYPES /* This file is Win32-clean */
9 #include <stdlib.h>
10 #include <string.h>
11 #include "gdi.h"
12 #include "bitmap.h"
13 #include "heap.h"
14 #include "metafile.h"
15 #include "stddebug.h"
16 #include "color.h"
17 #include "debug.h"
18 #include "font.h"
19 #include "xmalloc.h"
21 extern void CLIPPING_UpdateGCRegion( DC * dc ); /* objects/clipping.c */
23 /* Default DC values */
24 static const WIN_DC_INFO DC_defaultValues =
26 0, /* flags */
27 NULL, /* devCaps */
28 0, /* hClipRgn */
29 0, /* hVisRgn */
30 0, /* hGCClipRgn */
31 STOCK_BLACK_PEN, /* hPen */
32 STOCK_WHITE_BRUSH, /* hBrush */
33 STOCK_SYSTEM_FONT, /* hFont */
34 0, /* hBitmap */
35 0, /* hFirstBitmap */
36 0, /* hDevice */
37 STOCK_DEFAULT_PALETTE, /* hPalette */
38 R2_COPYPEN, /* ROPmode */
39 ALTERNATE, /* polyFillMode */
40 BLACKONWHITE, /* stretchBltMode */
41 ABSOLUTE, /* relAbsMode */
42 OPAQUE, /* backgroundMode */
43 RGB( 255, 255, 255 ), /* backgroundColor */
44 RGB( 0, 0, 0 ), /* textColor */
45 0, /* backgroundPixel */
46 0, /* textPixel */
47 0, /* brushOrgX */
48 0, /* brushOrgY */
49 TA_LEFT | TA_TOP | TA_NOUPDATECP, /* textAlign */
50 0, /* charExtra */
51 0, /* breakTotalExtra */
52 0, /* breakCount */
53 0, /* breakExtra */
54 0, /* breakRem */
55 1, /* bitsPerPixel */
56 MM_TEXT, /* MapMode */
57 0, /* DCOrgX */
58 0, /* DCOrgY */
59 0, /* CursPosX */
60 0 /* CursPosY */
63 /* ROP code to GC function conversion */
64 const int DC_XROPfunction[16] =
66 GXclear, /* R2_BLACK */
67 GXnor, /* R2_NOTMERGEPEN */
68 GXandInverted, /* R2_MASKNOTPEN */
69 GXcopyInverted, /* R2_NOTCOPYPEN */
70 GXandReverse, /* R2_MASKPENNOT */
71 GXinvert, /* R2_NOT */
72 GXxor, /* R2_XORPEN */
73 GXnand, /* R2_NOTMASKPEN */
74 GXand, /* R2_MASKPEN */
75 GXequiv, /* R2_NOTXORPEN */
76 GXnoop, /* R2_NOP */
77 GXorInverted, /* R2_MERGENOTPEN */
78 GXcopy, /* R2_COPYPEN */
79 GXorReverse, /* R2_MERGEPENNOT */
80 GXor, /* R2_MERGEPEN */
81 GXset /* R2_WHITE */
85 /***********************************************************************
86 * DC_FillDevCaps
88 * Fill the device caps structure.
90 void DC_FillDevCaps( DeviceCaps * caps )
92 caps->version = 0x300;
93 caps->technology = DT_RASDISPLAY;
94 caps->horzSize = WidthMMOfScreen(screen) * screenWidth / WidthOfScreen(screen);
95 caps->vertSize = HeightMMOfScreen(screen) * screenHeight / HeightOfScreen(screen);
96 caps->horzRes = screenWidth;
97 caps->vertRes = screenHeight;
98 caps->bitsPixel = screenDepth;
99 caps->planes = 1;
100 caps->numBrushes = 16+6; /* 16 solid + 6 hatched brushes */
101 caps->numPens = 16; /* 16 solid pens */
102 caps->numMarkers = 0;
103 caps->numFonts = 0;
104 caps->numColors = 100;
105 caps->pdeviceSize = 0;
106 caps->curveCaps = CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES |
107 CC_WIDE | CC_STYLED | CC_WIDESTYLED |
108 CC_INTERIORS | CC_ROUNDRECT;
109 caps->lineCaps = LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
110 LC_STYLED | LC_WIDESTYLED | LC_INTERIORS;
111 caps->polygonalCaps = PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON |
112 PC_SCANLINE | PC_WIDE | PC_STYLED |
113 PC_WIDESTYLED | PC_INTERIORS;
114 caps->textCaps = TC_OP_CHARACTER | TC_OP_STROKE | TC_CP_STROKE |
115 TC_IA_ABLE | TC_UA_ABLE | TC_SO_ABLE | TC_RA_ABLE;
116 caps->clipCaps = CP_REGION;
117 caps->rasterCaps = RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 |
118 RC_DI_BITMAP | RC_DIBTODEV | RC_BIGFONT|
119 RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS;
121 if( !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
122 caps->rasterCaps |= RC_PALETTE;
124 caps->aspectX = 36; /* ?? */
125 caps->aspectY = 36; /* ?? */
126 caps->aspectXY = 51;
127 caps->logPixelsX = (int)(caps->horzRes * 25.4 / caps->horzSize);
128 caps->logPixelsY = (int)(caps->vertRes * 25.4 / caps->vertSize);
129 caps->sizePalette = (caps->rasterCaps & RC_PALETTE)
130 ? DefaultVisual(display,DefaultScreen(display))->map_entries
131 : 0;
132 caps->numReserved = 0;
133 caps->colorRes = 0;
137 /***********************************************************************
138 * DC_AllocDC
140 DC *DC_AllocDC( const DC_FUNCTIONS *funcs )
142 HDC16 hdc;
143 DC *dc;
145 if (!(hdc = GDI_AllocObject( sizeof(DC), DC_MAGIC ))) return NULL;
146 dc = (DC *) GDI_HEAP_LIN_ADDR( hdc );
148 dc->hSelf = hdc;
149 dc->funcs = funcs;
150 dc->physDev = NULL;
151 dc->saveLevel = 0;
152 dc->dwHookData = 0L;
153 dc->hookProc = NULL;
154 dc->wndOrgX = 0;
155 dc->wndOrgY = 0;
156 dc->wndExtX = 1;
157 dc->wndExtY = 1;
158 dc->vportOrgX = 0;
159 dc->vportOrgY = 0;
160 dc->vportExtX = 1;
161 dc->vportExtY = 1;
163 memcpy( &dc->w, &DC_defaultValues, sizeof(DC_defaultValues) );
164 return dc;
168 /***********************************************************************
169 * DC_GetDCPtr
171 DC *DC_GetDCPtr( HDC32 hdc )
173 GDIOBJHDR *ptr = (GDIOBJHDR *)GDI_HEAP_LIN_ADDR( hdc );
174 if ((ptr->wMagic == DC_MAGIC) || (ptr->wMagic == METAFILE_DC_MAGIC))
175 return (DC *)ptr;
176 return NULL;
180 /***********************************************************************
181 * DC_InitDC
183 * Setup device-specific DC values for a newly created DC.
185 void DC_InitDC( DC* dc )
187 RealizeDefaultPalette( dc->hSelf );
188 SetTextColor( dc->hSelf, dc->w.textColor );
189 SetBkColor( dc->hSelf, dc->w.backgroundColor );
190 SelectObject32( dc->hSelf, dc->w.hPen );
191 SelectObject32( dc->hSelf, dc->w.hBrush );
192 SelectObject32( dc->hSelf, dc->w.hFont );
193 CLIPPING_UpdateGCRegion( dc );
197 /***********************************************************************
198 * DC_SetupGCForPatBlt
200 * Setup the GC for a PatBlt operation using current brush.
201 * If fMapColors is TRUE, X pixels are mapped to Windows colors.
202 * Return FALSE if brush is BS_NULL, TRUE otherwise.
204 BOOL32 DC_SetupGCForPatBlt( DC * dc, GC gc, BOOL32 fMapColors )
206 XGCValues val;
207 unsigned long mask;
208 Pixmap pixmap = 0;
210 if (dc->u.x.brush.style == BS_NULL) return FALSE;
211 if (dc->u.x.brush.pixel == -1)
213 /* Special case used for monochrome pattern brushes.
214 * We need to swap foreground and background because
215 * Windows does it the wrong way...
217 val.foreground = dc->w.backgroundPixel;
218 val.background = dc->w.textPixel;
220 else
222 val.foreground = dc->u.x.brush.pixel;
223 val.background = dc->w.backgroundPixel;
225 if (fMapColors && COLOR_PixelToPalette)
227 val.foreground = COLOR_PixelToPalette[val.foreground];
228 val.background = COLOR_PixelToPalette[val.background];
231 if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc);
233 val.function = DC_XROPfunction[dc->w.ROPmode-1];
234 val.fill_style = dc->u.x.brush.fillStyle;
235 switch(val.fill_style)
237 case FillStippled:
238 case FillOpaqueStippled:
239 if (dc->w.backgroundMode==OPAQUE) val.fill_style = FillOpaqueStippled;
240 val.stipple = dc->u.x.brush.pixmap;
241 mask = GCStipple;
242 break;
244 case FillTiled:
245 if (fMapColors && COLOR_PixelToPalette)
247 register int x, y;
248 XImage *image;
249 pixmap = XCreatePixmap( display, rootWindow, 8, 8, screenDepth );
250 image = XGetImage( display, dc->u.x.brush.pixmap, 0, 0, 8, 8,
251 AllPlanes, ZPixmap );
252 for (y = 0; y < 8; y++)
253 for (x = 0; x < 8; x++)
254 XPutPixel( image, x, y,
255 COLOR_PixelToPalette[XGetPixel( image, x, y)] );
256 XPutImage( display, pixmap, gc, image, 0, 0, 0, 0, 8, 8 );
257 XDestroyImage( image );
258 val.tile = pixmap;
260 else val.tile = dc->u.x.brush.pixmap;
261 mask = GCTile;
262 break;
264 default:
265 mask = 0;
266 break;
268 val.ts_x_origin = dc->w.DCOrgX + dc->w.brushOrgX;
269 val.ts_y_origin = dc->w.DCOrgY + dc->w.brushOrgY;
270 val.fill_rule = (dc->w.polyFillMode==WINDING) ? WindingRule : EvenOddRule;
271 XChangeGC( display, gc,
272 GCFunction | GCForeground | GCBackground | GCFillStyle |
273 GCFillRule | GCTileStipXOrigin | GCTileStipYOrigin | mask,
274 &val );
275 if (pixmap) XFreePixmap( display, pixmap );
276 return TRUE;
280 /***********************************************************************
281 * DC_SetupGCForBrush
283 * Setup dc->u.x.gc for drawing operations using current brush.
284 * Return FALSE if brush is BS_NULL, TRUE otherwise.
286 BOOL32 DC_SetupGCForBrush( DC * dc )
288 return DC_SetupGCForPatBlt( dc, dc->u.x.gc, FALSE );
292 /***********************************************************************
293 * DC_SetupGCForPen
295 * Setup dc->u.x.gc for drawing operations using current pen.
296 * Return FALSE if pen is PS_NULL, TRUE otherwise.
298 BOOL32 DC_SetupGCForPen( DC * dc )
300 XGCValues val;
302 if (dc->u.x.pen.style == PS_NULL) return FALSE;
304 if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc);
306 if ((screenDepth <= 8) && /* FIXME: Should check for palette instead */
307 ((dc->w.ROPmode == R2_BLACK) || (dc->w.ROPmode == R2_WHITE)))
309 val.function = GXcopy;
310 val.foreground = COLOR_ToPhysical( NULL, (dc->w.ROPmode == R2_BLACK) ?
311 RGB(0,0,0) : RGB(255,255,255) );
313 else
315 val.function = DC_XROPfunction[dc->w.ROPmode-1];
316 val.foreground = dc->u.x.pen.pixel;
318 val.background = dc->w.backgroundPixel;
319 val.fill_style = FillSolid;
320 if ((dc->u.x.pen.style!=PS_SOLID) && (dc->u.x.pen.style!=PS_INSIDEFRAME))
322 XSetDashes( display, dc->u.x.gc, 0,
323 dc->u.x.pen.dashes, dc->u.x.pen.dash_len );
324 val.line_style = (dc->w.backgroundMode == OPAQUE) ?
325 LineDoubleDash : LineOnOffDash;
327 else val.line_style = LineSolid;
328 val.line_width = dc->u.x.pen.width;
329 val.cap_style = CapRound;
330 val.join_style = JoinMiter;
331 XChangeGC( display, dc->u.x.gc,
332 GCFunction | GCForeground | GCBackground | GCLineWidth |
333 GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle, &val );
334 return TRUE;
338 /***********************************************************************
339 * DC_SetupGCForText
341 * Setup dc->u.x.gc for text drawing operations.
342 * Return FALSE if the font is null, TRUE otherwise.
344 BOOL32 DC_SetupGCForText( DC * dc )
346 XGCValues val;
348 if (!dc->u.x.font.fstruct)
350 fprintf( stderr, "DC_SetupGCForText: fstruct is NULL. Please report this\n" );
351 return FALSE;
354 if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc);
356 val.function = GXcopy; /* Text is always GXcopy */
357 val.foreground = dc->w.textPixel;
358 val.background = dc->w.backgroundPixel;
359 val.fill_style = FillSolid;
360 val.font = dc->u.x.font.fstruct->fid;
361 XChangeGC( display, dc->u.x.gc,
362 GCFunction | GCForeground | GCBackground | GCFillStyle |
363 GCFont, &val );
364 return TRUE;
368 /***********************************************************************
369 * GetDCState (GDI.179)
371 HDC16 GetDCState( HDC16 hdc )
373 DC * newdc, * dc;
374 HGDIOBJ16 handle;
376 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
377 if (!(handle = GDI_AllocObject( sizeof(DC), DC_MAGIC ))) return 0;
378 newdc = (DC *) GDI_HEAP_LIN_ADDR( handle );
380 dprintf_dc(stddeb, "GetDCState(%04x): returning %04x\n", hdc, handle );
382 memset( &newdc->u.x, 0, sizeof(newdc->u.x) );
383 newdc->w.flags = dc->w.flags | DC_SAVED;
384 newdc->w.devCaps = dc->w.devCaps;
385 newdc->w.hPen = dc->w.hPen;
386 newdc->w.hBrush = dc->w.hBrush;
387 newdc->w.hFont = dc->w.hFont;
388 newdc->w.hBitmap = dc->w.hBitmap;
389 newdc->w.hFirstBitmap = dc->w.hFirstBitmap;
390 newdc->w.hDevice = dc->w.hDevice;
391 newdc->w.hPalette = dc->w.hPalette;
392 newdc->w.bitsPerPixel = dc->w.bitsPerPixel;
393 newdc->w.ROPmode = dc->w.ROPmode;
394 newdc->w.polyFillMode = dc->w.polyFillMode;
395 newdc->w.stretchBltMode = dc->w.stretchBltMode;
396 newdc->w.relAbsMode = dc->w.relAbsMode;
397 newdc->w.backgroundMode = dc->w.backgroundMode;
398 newdc->w.backgroundColor = dc->w.backgroundColor;
399 newdc->w.textColor = dc->w.textColor;
400 newdc->w.backgroundPixel = dc->w.backgroundPixel;
401 newdc->w.textPixel = dc->w.textPixel;
402 newdc->w.brushOrgX = dc->w.brushOrgX;
403 newdc->w.brushOrgY = dc->w.brushOrgY;
404 newdc->w.textAlign = dc->w.textAlign;
405 newdc->w.charExtra = dc->w.charExtra;
406 newdc->w.breakTotalExtra = dc->w.breakTotalExtra;
407 newdc->w.breakCount = dc->w.breakCount;
408 newdc->w.breakExtra = dc->w.breakExtra;
409 newdc->w.breakRem = dc->w.breakRem;
410 newdc->w.MapMode = dc->w.MapMode;
411 newdc->w.DCOrgX = dc->w.DCOrgX;
412 newdc->w.DCOrgY = dc->w.DCOrgY;
413 newdc->w.CursPosX = dc->w.CursPosX;
414 newdc->w.CursPosY = dc->w.CursPosY;
415 newdc->wndOrgX = dc->wndOrgX;
416 newdc->wndOrgY = dc->wndOrgY;
417 newdc->wndExtX = dc->wndExtX;
418 newdc->wndExtY = dc->wndExtY;
419 newdc->vportOrgX = dc->vportOrgX;
420 newdc->vportOrgY = dc->vportOrgY;
421 newdc->vportExtX = dc->vportExtX;
422 newdc->vportExtY = dc->vportExtY;
424 newdc->hSelf = (HDC32)handle;
425 newdc->saveLevel = 0;
427 newdc->w.hGCClipRgn = 0;
428 newdc->w.hVisRgn = CreateRectRgn32( 0, 0, 0, 0 );
429 CombineRgn32( newdc->w.hVisRgn, dc->w.hVisRgn, 0, RGN_COPY );
430 if (dc->w.hClipRgn)
432 newdc->w.hClipRgn = CreateRectRgn32( 0, 0, 0, 0 );
433 CombineRgn32( newdc->w.hClipRgn, dc->w.hClipRgn, 0, RGN_COPY );
435 return handle;
439 /***********************************************************************
440 * SetDCState (GDI.180)
442 void SetDCState( HDC16 hdc, HDC16 hdcs )
444 DC *dc, *dcs;
446 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return;
447 if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) return;
448 if (!dcs->w.flags & DC_SAVED) return;
449 dprintf_dc(stddeb, "SetDCState: %04x %04x\n", hdc, hdcs );
451 dc->w.flags = dcs->w.flags & ~DC_SAVED;
452 dc->w.devCaps = dcs->w.devCaps;
453 dc->w.hFirstBitmap = dcs->w.hFirstBitmap;
454 dc->w.hDevice = dcs->w.hDevice;
455 dc->w.ROPmode = dcs->w.ROPmode;
456 dc->w.polyFillMode = dcs->w.polyFillMode;
457 dc->w.stretchBltMode = dcs->w.stretchBltMode;
458 dc->w.relAbsMode = dcs->w.relAbsMode;
459 dc->w.backgroundMode = dcs->w.backgroundMode;
460 dc->w.backgroundColor = dcs->w.backgroundColor;
461 dc->w.textColor = dcs->w.textColor;
462 dc->w.backgroundPixel = dcs->w.backgroundPixel;
463 dc->w.textPixel = dcs->w.textPixel;
464 dc->w.brushOrgX = dcs->w.brushOrgX;
465 dc->w.brushOrgY = dcs->w.brushOrgY;
466 dc->w.textAlign = dcs->w.textAlign;
467 dc->w.charExtra = dcs->w.charExtra;
468 dc->w.breakTotalExtra = dcs->w.breakTotalExtra;
469 dc->w.breakCount = dcs->w.breakCount;
470 dc->w.breakExtra = dcs->w.breakExtra;
471 dc->w.breakRem = dcs->w.breakRem;
472 dc->w.MapMode = dcs->w.MapMode;
473 dc->w.DCOrgX = dcs->w.DCOrgX;
474 dc->w.DCOrgY = dcs->w.DCOrgY;
475 dc->w.CursPosX = dcs->w.CursPosX;
476 dc->w.CursPosY = dcs->w.CursPosY;
478 dc->wndOrgX = dcs->wndOrgX;
479 dc->wndOrgY = dcs->wndOrgY;
480 dc->wndExtX = dcs->wndExtX;
481 dc->wndExtY = dcs->wndExtY;
482 dc->vportOrgX = dcs->vportOrgX;
483 dc->vportOrgY = dcs->vportOrgY;
484 dc->vportExtX = dcs->vportExtX;
485 dc->vportExtY = dcs->vportExtY;
487 if (!(dc->w.flags & DC_MEMORY)) dc->w.bitsPerPixel = dcs->w.bitsPerPixel;
488 CombineRgn32( dc->w.hVisRgn, dcs->w.hVisRgn, 0, RGN_COPY );
489 SelectClipRgn32( hdc, dcs->w.hClipRgn );
490 SelectObject32( hdc, dcs->w.hBitmap );
491 SelectObject32( hdc, dcs->w.hBrush );
492 SelectObject32( hdc, dcs->w.hFont );
493 SelectObject32( hdc, dcs->w.hPen );
494 GDISelectPalette( hdc, dcs->w.hPalette, FALSE );
498 /***********************************************************************
499 * SaveDC16 (GDI.30)
501 INT16 SaveDC16( HDC16 hdc )
503 return (INT16)SaveDC32( hdc );
507 /***********************************************************************
508 * SaveDC32 (GDI32.292)
510 INT32 SaveDC32( HDC32 hdc )
512 HDC32 hdcs;
513 DC * dc, * dcs;
515 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
516 if (!dc)
518 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
519 if (!dc) return 0;
520 MF_MetaParam0(dc, META_SAVEDC);
521 return 1; /* ?? */
523 if (!(hdcs = GetDCState( hdc ))) return 0;
524 dcs = (DC *) GDI_HEAP_LIN_ADDR( hdcs );
525 dcs->header.hNext = dc->header.hNext;
526 dc->header.hNext = hdcs;
527 dprintf_dc(stddeb, "SaveDC(%04x): returning %d\n", hdc, dc->saveLevel+1 );
528 return ++dc->saveLevel;
532 /***********************************************************************
533 * RestoreDC16 (GDI.39)
535 BOOL16 RestoreDC16( HDC16 hdc, INT16 level )
537 return RestoreDC32( hdc, level );
541 /***********************************************************************
542 * RestoreDC32 (GDI32.290)
544 BOOL32 RestoreDC32( HDC32 hdc, INT32 level )
546 DC * dc, * dcs;
548 dprintf_dc(stddeb, "RestoreDC: %04x %d\n", hdc, level );
549 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
550 if (!dc)
552 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
553 if (!dc) return FALSE;
554 if (level != -1) return FALSE;
555 MF_MetaParam1(dc, META_RESTOREDC, level);
556 return TRUE;
558 if (level == -1) level = dc->saveLevel;
559 if ((level < 1) || (level > dc->saveLevel)) return FALSE;
561 while (dc->saveLevel >= level)
563 HDC16 hdcs = dc->header.hNext;
564 if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) return FALSE;
565 dc->header.hNext = dcs->header.hNext;
566 if (--dc->saveLevel < level) SetDCState( hdc, hdcs );
567 DeleteDC32( hdcs );
569 return TRUE;
573 /***********************************************************************
574 * CreateDC16 (GDI.53)
576 HDC16 CreateDC16( LPCSTR driver, LPCSTR device, LPCSTR output,
577 const DEVMODE16 *initData )
579 DC * dc;
580 const DC_FUNCTIONS *funcs;
582 if (!(funcs = DRIVER_FindDriver( driver ))) return 0;
583 if (!(dc = DC_AllocDC( funcs ))) return 0;
584 dc->w.flags = 0;
586 dprintf_dc(stddeb, "CreateDC(%s %s %s): returning %04x\n",
587 driver, device, output, dc->hSelf );
589 if (dc->funcs->pCreateDC &&
590 !dc->funcs->pCreateDC( dc, driver, device, output, initData ))
592 dprintf_dc( stddeb, "CreateDC: creation aborted by device\n" );
593 GDI_HEAP_FREE( dc->hSelf );
594 return 0;
597 DC_InitDC( dc );
598 return dc->hSelf;
602 /***********************************************************************
603 * CreateDC32A (GDI32.)
605 HDC32 CreateDC32A( LPCSTR driver, LPCSTR device, LPCSTR output,
606 const DEVMODE32A *initData )
608 return CreateDC16( driver, device, output, (const DEVMODE16 *)initData );
612 /***********************************************************************
613 * CreateDC32W (GDI32.)
615 HDC32 CreateDC32W( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
616 const DEVMODE32W *initData )
618 LPSTR driverA = HEAP_strdupWtoA( GetProcessHeap(), 0, driver );
619 LPSTR deviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, device );
620 LPSTR outputA = HEAP_strdupWtoA( GetProcessHeap(), 0, output );
621 HDC32 res = CreateDC16( driverA, deviceA, outputA,
622 (const DEVMODE16 *)initData /*FIXME*/ );
623 HeapFree( GetProcessHeap(), 0, driverA );
624 HeapFree( GetProcessHeap(), 0, deviceA );
625 HeapFree( GetProcessHeap(), 0, outputA );
626 return res;
630 /***********************************************************************
631 * CreateIC16 (GDI.153)
633 HDC16 CreateIC16( LPCSTR driver, LPCSTR device, LPCSTR output,
634 const DEVMODE16* initData )
636 /* Nothing special yet for ICs */
637 return CreateDC16( driver, device, output, initData );
641 /***********************************************************************
642 * CreateIC32A (GDI32.49)
644 HDC32 CreateIC32A( LPCSTR driver, LPCSTR device, LPCSTR output,
645 const DEVMODE32A* initData )
647 /* Nothing special yet for ICs */
648 return CreateDC32A( driver, device, output, initData );
652 /***********************************************************************
653 * CreateIC32W (GDI32.50)
655 HDC32 CreateIC32W( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
656 const DEVMODE32W* initData )
658 /* Nothing special yet for ICs */
659 return CreateDC32W( driver, device, output, initData );
663 /***********************************************************************
664 * CreateCompatibleDC16 (GDI.52)
666 HDC16 CreateCompatibleDC16( HDC16 hdc )
668 return (HDC16)CreateCompatibleDC32( hdc );
672 /***********************************************************************
673 * CreateCompatibleDC32 (GDI32.31)
675 HDC32 CreateCompatibleDC32( HDC32 hdc )
677 DC *dc, *origDC;
678 HBITMAP32 hbitmap;
679 const DC_FUNCTIONS *funcs;
681 if ((origDC = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC ))) funcs = origDC->funcs;
682 else funcs = DRIVER_FindDriver( "DISPLAY" );
683 if (!funcs) return 0;
685 if (!(dc = DC_AllocDC( funcs ))) return 0;
687 dprintf_dc(stddeb, "CreateCompatibleDC(%04x): returning %04x\n",
688 hdc, dc->hSelf );
690 /* Create default bitmap */
691 if (!(hbitmap = CreateBitmap( 1, 1, 1, 1, NULL )))
693 GDI_HEAP_FREE( dc->hSelf );
694 return 0;
696 dc->w.flags = DC_MEMORY;
697 dc->w.bitsPerPixel = 1;
698 dc->w.hBitmap = hbitmap;
699 dc->w.hFirstBitmap = hbitmap;
701 if (dc->funcs->pCreateDC &&
702 !dc->funcs->pCreateDC( dc, NULL, NULL, NULL, NULL ))
704 dprintf_dc(stddeb, "CreateCompatibleDC: creation aborted by device\n");
705 DeleteObject32( hbitmap );
706 GDI_HEAP_FREE( dc->hSelf );
707 return 0;
710 DC_InitDC( dc );
711 return dc->hSelf;
715 /***********************************************************************
716 * DeleteDC16 (GDI.68)
718 BOOL16 DeleteDC16( HDC16 hdc )
720 return DeleteDC32( hdc );
724 /***********************************************************************
725 * DeleteDC32 (GDI32.67)
727 BOOL32 DeleteDC32( HDC32 hdc )
729 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
730 if (!dc) return FALSE;
732 dprintf_dc(stddeb, "DeleteDC: %04x\n", hdc );
734 while (dc->saveLevel)
736 DC * dcs;
737 HDC16 hdcs = dc->header.hNext;
738 if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) break;
739 dc->header.hNext = dcs->header.hNext;
740 dc->saveLevel--;
741 DeleteDC32( hdcs );
744 if (!(dc->w.flags & DC_SAVED))
746 SelectObject32( hdc, STOCK_BLACK_PEN );
747 SelectObject32( hdc, STOCK_WHITE_BRUSH );
748 SelectObject32( hdc, STOCK_SYSTEM_FONT );
749 if (dc->w.flags & DC_MEMORY) DeleteObject32( dc->w.hFirstBitmap );
750 if (dc->funcs->pDeleteDC) dc->funcs->pDeleteDC(dc);
753 if (dc->w.hClipRgn) DeleteObject32( dc->w.hClipRgn );
754 if (dc->w.hVisRgn) DeleteObject32( dc->w.hVisRgn );
755 if (dc->w.hGCClipRgn) DeleteObject32( dc->w.hGCClipRgn );
757 return GDI_FreeObject( hdc );
761 /***********************************************************************
762 * ResetDC16 (GDI.376)
764 HDC16 ResetDC16( HDC16 hdc, const DEVMODE16 *devmode )
766 fprintf( stderr, "ResetDC16: empty stub!\n" );
767 return hdc;
771 /***********************************************************************
772 * ResetDC32A (GDI32.287)
774 HDC32 ResetDC32A( HDC32 hdc, const DEVMODE32A *devmode )
776 fprintf( stderr, "ResetDC32A: empty stub!\n" );
777 return hdc;
781 /***********************************************************************
782 * ResetDC32W (GDI32.288)
784 HDC32 ResetDC32W( HDC32 hdc, const DEVMODE32W *devmode )
786 fprintf( stderr, "ResetDC32A: empty stub!\n" );
787 return hdc;
791 /***********************************************************************
792 * GetDeviceCaps (GDI.80)
794 int GetDeviceCaps( HDC16 hdc, WORD cap )
796 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
797 if (!dc) return 0;
799 if (cap > sizeof(DeviceCaps)-sizeof(WORD)) return 0;
801 dprintf_dc(stddeb, "GetDeviceCaps(%04x,%d): returning %d\n",
802 hdc, cap, *(WORD *)(((char *)dc->w.devCaps) + cap) );
803 return *(WORD *)(((char *)dc->w.devCaps) + cap);
807 /***********************************************************************
808 * SetBkColor (GDI.1) (GDI32.305)
810 COLORREF SetBkColor( HDC32 hdc, COLORREF color )
812 COLORREF oldColor;
813 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
814 if (!dc)
816 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
817 if (!dc) return 0x80000000;
818 MF_MetaParam2(dc, META_SETBKCOLOR, HIWORD(color), LOWORD(color));
819 return 0; /* ?? */
822 oldColor = dc->w.backgroundColor;
823 dc->w.backgroundColor = color;
824 dc->w.backgroundPixel = COLOR_ToPhysical( dc, color );
825 return oldColor;
829 /***********************************************************************
830 * SetTextColor (GDI.9) (GDI32.338)
832 COLORREF SetTextColor( HDC32 hdc, COLORREF color )
834 COLORREF oldColor;
835 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
836 if (!dc)
838 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
839 if (!dc) return 0x80000000;
840 MF_MetaParam2(dc, META_SETTEXTCOLOR, HIWORD(color), LOWORD(color));
841 return 0; /* ?? */
844 oldColor = dc->w.textColor;
845 dc->w.textColor = color;
846 dc->w.textPixel = COLOR_ToPhysical( dc, color );
847 return oldColor;
851 /***********************************************************************
852 * SetTextAlign16 (GDI.346)
854 UINT16 SetTextAlign16( HDC16 hdc, UINT16 textAlign )
856 return SetTextAlign32( hdc, textAlign );
860 /***********************************************************************
861 * SetTextAlign32 (GDI32.336)
863 UINT32 SetTextAlign32( HDC32 hdc, UINT32 textAlign )
865 UINT32 prevAlign;
866 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
867 if (!dc)
869 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ))) return 0;
870 MF_MetaParam1( dc, META_SETTEXTALIGN, textAlign );
871 return 1;
873 prevAlign = dc->w.textAlign;
874 dc->w.textAlign = textAlign;
875 return prevAlign;
879 /***********************************************************************
880 * GetDCOrgEx (GDI32.168)
882 BOOL32 GetDCOrgEx( HDC32 hDC, LPPOINT32 lpp )
884 DC * dc = (DC *) GDI_GetObjPtr( hDC, DC_MAGIC );
885 if (!dc || !lpp) return FALSE;
887 if (!(dc->w.flags & DC_MEMORY))
889 Window root;
890 int w, h, border, depth;
891 /* FIXME: this is not correct for managed windows */
892 XGetGeometry( display, dc->u.x.drawable, &root,
893 &lpp->x, &lpp->y, &w, &h, &border, &depth );
895 else lpp->x = lpp->y = 0;
896 lpp->x += dc->w.DCOrgX; lpp->y += dc->w.DCOrgY;
897 return TRUE;
901 /***********************************************************************
902 * GetDCOrg (GDI.79)
904 DWORD GetDCOrg( HDC16 hdc )
906 POINT32 pt;
907 if( GetDCOrgEx( hdc, &pt) )
908 return MAKELONG( (WORD)pt.x, (WORD)pt.y );
909 return 0;
913 /***********************************************************************
914 * SetDCOrg (GDI.117)
916 DWORD SetDCOrg( HDC16 hdc, INT16 x, INT16 y )
918 DWORD prevOrg;
919 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
920 if (!dc) return 0;
921 prevOrg = dc->w.DCOrgX | (dc->w.DCOrgY << 16);
922 dc->w.DCOrgX = x;
923 dc->w.DCOrgY = y;
924 return prevOrg;
928 /***********************************************************************
929 * SetDCHook (GDI.190)
931 BOOL16 SetDCHook( HDC16 hdc, FARPROC16 hookProc, DWORD dwHookData )
933 DC *dc = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC );
935 dprintf_dc( stddeb, "SetDCHook: hookProc %08x, default is %08x\n",
936 (UINT32)hookProc, (UINT32)DCHook );
938 if (!dc) return FALSE;
939 dc->hookProc = hookProc;
940 dc->dwHookData = dwHookData;
941 return TRUE;
945 /***********************************************************************
946 * GetDCHook (GDI.191)
948 DWORD GetDCHook( HDC16 hdc, FARPROC16 *phookProc )
950 DC *dc = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC );
951 if (!dc) return 0;
952 *phookProc = dc->hookProc;
953 return dc->dwHookData;
957 /***********************************************************************
958 * SetHookFlags (GDI.192)
960 WORD SetHookFlags(HDC16 hDC, WORD flags)
962 DC* dc = (DC*)GDI_GetObjPtr( hDC, DC_MAGIC );
964 if( dc )
966 WORD wRet = dc->w.flags & DC_DIRTY;
968 /* "Undocumented Windows" info is slightly
969 * confusing
972 dprintf_dc(stddeb,"SetHookFlags: hDC %04x, flags %04x\n",hDC,flags);
974 if( flags & DCHF_INVALIDATEVISRGN )
975 dc->w.flags |= DC_DIRTY;
976 else if( flags & DCHF_VALIDATEVISRGN || !flags )
977 dc->w.flags &= ~DC_DIRTY;
978 return wRet;
980 return 0;