Release 961215
[wine/multimedia.git] / objects / dc.c
blob0d05d11bc499bca42f06576d8a5d8b8d08d8be69
1 /*
2 * GDI Device Context functions
4 * Copyright 1993 Alexandre Julliard
6 */
8 #include <stdlib.h>
9 #include <string.h>
10 #include "gdi.h"
11 #include "bitmap.h"
12 #include "metafile.h"
13 #include "stddebug.h"
14 #include "color.h"
15 #include "debug.h"
16 #include "font.h"
17 #include "xmalloc.h"
18 #include "string32.h"
20 extern void CLIPPING_UpdateGCRegion( DC * dc ); /* objects/clipping.c */
22 /* Default DC values */
23 static const WIN_DC_INFO DC_defaultValues =
25 0, /* flags */
26 NULL, /* devCaps */
27 0, /* hClipRgn */
28 0, /* hVisRgn */
29 0, /* hGCClipRgn */
30 STOCK_BLACK_PEN, /* hPen */
31 STOCK_WHITE_BRUSH, /* hBrush */
32 STOCK_SYSTEM_FONT, /* hFont */
33 0, /* hBitmap */
34 0, /* hFirstBitmap */
35 0, /* hDevice */
36 STOCK_DEFAULT_PALETTE, /* hPalette */
37 R2_COPYPEN, /* ROPmode */
38 ALTERNATE, /* polyFillMode */
39 BLACKONWHITE, /* stretchBltMode */
40 ABSOLUTE, /* relAbsMode */
41 OPAQUE, /* backgroundMode */
42 RGB( 255, 255, 255 ), /* backgroundColor */
43 RGB( 0, 0, 0 ), /* textColor */
44 0, /* backgroundPixel */
45 0, /* textPixel */
46 0, /* brushOrgX */
47 0, /* brushOrgY */
48 TA_LEFT | TA_TOP | TA_NOUPDATECP, /* textAlign */
49 0, /* charExtra */
50 0, /* breakTotalExtra */
51 0, /* breakCount */
52 0, /* breakExtra */
53 0, /* breakRem */
54 1, /* bitsPerPixel */
55 MM_TEXT, /* MapMode */
56 0, /* DCOrgX */
57 0, /* DCOrgY */
58 0, /* CursPosX */
59 0, /* CursPosY */
60 0, /* WndOrgX */
61 0, /* WndOrgY */
62 1, /* WndExtX */
63 1, /* WndExtY */
64 0, /* VportOrgX */
65 0, /* VportOrgY */
66 1, /* VportExtX */
67 1 /* VportExtY */
70 /* ROP code to GC function conversion */
71 const int DC_XROPfunction[16] =
73 GXclear, /* R2_BLACK */
74 GXnor, /* R2_NOTMERGEPEN */
75 GXandInverted, /* R2_MASKNOTPEN */
76 GXcopyInverted, /* R2_NOTCOPYPEN */
77 GXandReverse, /* R2_MASKPENNOT */
78 GXinvert, /* R2_NOT */
79 GXxor, /* R2_XORPEN */
80 GXnand, /* R2_NOTMASKPEN */
81 GXand, /* R2_MASKPEN */
82 GXequiv, /* R2_NOTXORPEN */
83 GXnoop, /* R2_NOP */
84 GXorInverted, /* R2_MERGENOTPEN */
85 GXcopy, /* R2_COPYPEN */
86 GXorReverse, /* R2_MERGEPENNOT */
87 GXor, /* R2_MERGEPEN */
88 GXset /* R2_WHITE */
92 /***********************************************************************
93 * DC_FillDevCaps
95 * Fill the device caps structure.
97 void DC_FillDevCaps( DeviceCaps * caps )
99 caps->version = 0x300;
100 caps->technology = DT_RASDISPLAY;
101 caps->horzSize = WidthMMOfScreen(screen) * screenWidth / WidthOfScreen(screen);
102 caps->vertSize = HeightMMOfScreen(screen) * screenHeight / HeightOfScreen(screen);
103 caps->horzRes = screenWidth;
104 caps->vertRes = screenHeight;
105 caps->bitsPixel = screenDepth;
106 caps->planes = 1;
107 caps->numBrushes = 16+6; /* 16 solid + 6 hatched brushes */
108 caps->numPens = 16; /* 16 solid pens */
109 caps->numMarkers = 0;
110 caps->numFonts = 0;
111 caps->numColors = 100;
112 caps->pdeviceSize = 0;
113 caps->curveCaps = CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES |
114 CC_WIDE | CC_STYLED | CC_WIDESTYLED |
115 CC_INTERIORS | CC_ROUNDRECT;
116 caps->lineCaps = LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
117 LC_STYLED | LC_WIDESTYLED | LC_INTERIORS;
118 caps->polygonalCaps = PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON |
119 PC_SCANLINE | PC_WIDE | PC_STYLED |
120 PC_WIDESTYLED | PC_INTERIORS;
121 caps->textCaps = TC_OP_CHARACTER | TC_OP_STROKE | TC_CP_STROKE |
122 TC_IA_ABLE | TC_UA_ABLE | TC_SO_ABLE | TC_RA_ABLE;
123 caps->clipCaps = CP_REGION;
124 caps->rasterCaps = RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 |
125 RC_DI_BITMAP | RC_DIBTODEV | RC_BIGFONT|
126 RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS;
128 if( !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
129 caps->rasterCaps |= RC_PALETTE;
131 caps->aspectX = 36; /* ?? */
132 caps->aspectY = 36; /* ?? */
133 caps->aspectXY = 51;
134 caps->logPixelsX = (int)(caps->horzRes * 25.4 / caps->horzSize);
135 caps->logPixelsY = (int)(caps->vertRes * 25.4 / caps->vertSize);
136 caps->sizePalette = (caps->rasterCaps & RC_PALETTE)
137 ? DefaultVisual(display,DefaultScreen(display))->map_entries
138 : 0;
139 caps->numReserved = 0;
140 caps->colorRes = 0;
144 /***********************************************************************
145 * DC_AllocDC
147 DC *DC_AllocDC( const DC_FUNCTIONS *funcs )
149 HDC16 hdc;
150 DC *dc;
152 if (!(hdc = GDI_AllocObject( sizeof(DC), DC_MAGIC ))) return NULL;
153 dc = (DC *) GDI_HEAP_LIN_ADDR( hdc );
155 dc->hSelf = hdc;
156 dc->funcs = funcs;
157 dc->physDev = NULL;
158 dc->saveLevel = 0;
159 dc->dwHookData = 0L;
160 dc->hookProc = NULL;
162 memcpy( &dc->w, &DC_defaultValues, sizeof(DC_defaultValues) );
163 return dc;
167 /***********************************************************************
168 * DC_GetDCPtr
170 DC *DC_GetDCPtr( HDC32 hdc )
172 GDIOBJHDR *ptr = (GDIOBJHDR *)GDI_HEAP_LIN_ADDR( hdc );
173 if ((ptr->wMagic == DC_MAGIC) || (ptr->wMagic == METAFILE_DC_MAGIC))
174 return (DC *)ptr;
175 return NULL;
179 /***********************************************************************
180 * DC_InitDC
182 * Setup device-specific DC values for a newly created DC.
184 void DC_InitDC( DC* dc )
186 RealizeDefaultPalette( dc->hSelf );
187 SetTextColor( dc->hSelf, dc->w.textColor );
188 SetBkColor( dc->hSelf, dc->w.backgroundColor );
189 SelectObject32( dc->hSelf, dc->w.hPen );
190 SelectObject32( dc->hSelf, dc->w.hBrush );
191 SelectObject32( dc->hSelf, dc->w.hFont );
192 CLIPPING_UpdateGCRegion( dc );
196 /***********************************************************************
197 * DC_SetupGCForPatBlt
199 * Setup the GC for a PatBlt operation using current brush.
200 * If fMapColors is TRUE, X pixels are mapped to Windows colors.
201 * Return FALSE if brush is BS_NULL, TRUE otherwise.
203 BOOL32 DC_SetupGCForPatBlt( DC * dc, GC gc, BOOL32 fMapColors )
205 XGCValues val;
206 unsigned long mask;
207 Pixmap pixmap = 0;
209 if (dc->u.x.brush.style == BS_NULL) return FALSE;
210 if (dc->u.x.brush.pixel == -1)
212 /* Special case used for monochrome pattern brushes.
213 * We need to swap foreground and background because
214 * Windows does it the wrong way...
216 val.foreground = dc->w.backgroundPixel;
217 val.background = dc->w.textPixel;
219 else
221 val.foreground = dc->u.x.brush.pixel;
222 val.background = dc->w.backgroundPixel;
224 if (fMapColors && COLOR_PixelToPalette)
226 val.foreground = COLOR_PixelToPalette[val.foreground];
227 val.background = COLOR_PixelToPalette[val.background];
230 if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc);
232 val.function = DC_XROPfunction[dc->w.ROPmode-1];
233 val.fill_style = dc->u.x.brush.fillStyle;
234 switch(val.fill_style)
236 case FillStippled:
237 case FillOpaqueStippled:
238 if (dc->w.backgroundMode==OPAQUE) val.fill_style = FillOpaqueStippled;
239 val.stipple = dc->u.x.brush.pixmap;
240 mask = GCStipple;
241 break;
243 case FillTiled:
244 if (fMapColors && COLOR_PixelToPalette)
246 register int x, y;
247 XImage *image;
248 pixmap = XCreatePixmap( display, rootWindow, 8, 8, screenDepth );
249 image = XGetImage( display, dc->u.x.brush.pixmap, 0, 0, 8, 8,
250 AllPlanes, ZPixmap );
251 for (y = 0; y < 8; y++)
252 for (x = 0; x < 8; x++)
253 XPutPixel( image, x, y,
254 COLOR_PixelToPalette[XGetPixel( image, x, y)] );
255 XPutImage( display, pixmap, gc, image, 0, 0, 0, 0, 8, 8 );
256 XDestroyImage( image );
257 val.tile = pixmap;
259 else val.tile = dc->u.x.brush.pixmap;
260 mask = GCTile;
261 break;
263 default:
264 mask = 0;
265 break;
267 val.ts_x_origin = dc->w.DCOrgX + dc->w.brushOrgX;
268 val.ts_y_origin = dc->w.DCOrgY + dc->w.brushOrgY;
269 val.fill_rule = (dc->w.polyFillMode==WINDING) ? WindingRule : EvenOddRule;
270 XChangeGC( display, gc,
271 GCFunction | GCForeground | GCBackground | GCFillStyle |
272 GCFillRule | GCTileStipXOrigin | GCTileStipYOrigin | mask,
273 &val );
274 if (pixmap) XFreePixmap( display, pixmap );
275 return TRUE;
279 /***********************************************************************
280 * DC_SetupGCForBrush
282 * Setup dc->u.x.gc for drawing operations using current brush.
283 * Return FALSE if brush is BS_NULL, TRUE otherwise.
285 BOOL32 DC_SetupGCForBrush( DC * dc )
287 return DC_SetupGCForPatBlt( dc, dc->u.x.gc, FALSE );
291 /***********************************************************************
292 * DC_SetupGCForPen
294 * Setup dc->u.x.gc for drawing operations using current pen.
295 * Return FALSE if pen is PS_NULL, TRUE otherwise.
297 BOOL32 DC_SetupGCForPen( DC * dc )
299 XGCValues val;
301 if (dc->u.x.pen.style == PS_NULL) return FALSE;
303 if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc);
305 if ((screenDepth <= 8) && /* FIXME: Should check for palette instead */
306 ((dc->w.ROPmode == R2_BLACK) || (dc->w.ROPmode == R2_WHITE)))
308 val.function = GXcopy;
309 val.foreground = COLOR_ToPhysical( NULL, (dc->w.ROPmode == R2_BLACK) ?
310 RGB(0,0,0) : RGB(255,255,255) );
312 else
314 val.function = DC_XROPfunction[dc->w.ROPmode-1];
315 val.foreground = dc->u.x.pen.pixel;
317 val.background = dc->w.backgroundPixel;
318 val.fill_style = FillSolid;
319 if ((dc->u.x.pen.style!=PS_SOLID) && (dc->u.x.pen.style!=PS_INSIDEFRAME))
321 XSetDashes( display, dc->u.x.gc, 0,
322 dc->u.x.pen.dashes, dc->u.x.pen.dash_len );
323 val.line_style = (dc->w.backgroundMode == OPAQUE) ?
324 LineDoubleDash : LineOnOffDash;
326 else val.line_style = LineSolid;
327 val.line_width = dc->u.x.pen.width;
328 val.cap_style = CapRound;
329 val.join_style = JoinMiter;
330 XChangeGC( display, dc->u.x.gc,
331 GCFunction | GCForeground | GCBackground | GCLineWidth |
332 GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle, &val );
333 return TRUE;
337 /***********************************************************************
338 * DC_SetupGCForText
340 * Setup dc->u.x.gc for text drawing operations.
341 * Return FALSE if the font is null, TRUE otherwise.
343 BOOL32 DC_SetupGCForText( DC * dc )
345 XGCValues val;
347 if (!dc->u.x.font.fstruct)
349 fprintf( stderr, "DC_SetupGCForText: fstruct is NULL. Please report this\n" );
350 return FALSE;
353 if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc);
355 val.function = GXcopy; /* Text is always GXcopy */
356 val.foreground = dc->w.textPixel;
357 val.background = dc->w.backgroundPixel;
358 val.fill_style = FillSolid;
359 val.font = dc->u.x.font.fstruct->fid;
360 XChangeGC( display, dc->u.x.gc,
361 GCFunction | GCForeground | GCBackground | GCFillStyle |
362 GCFont, &val );
363 return TRUE;
367 /***********************************************************************
368 * GetDCState (GDI.179)
370 HDC16 GetDCState( HDC16 hdc )
372 DC * newdc, * dc;
373 HGDIOBJ16 handle;
375 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
376 if (!(handle = GDI_AllocObject( sizeof(DC), DC_MAGIC ))) return 0;
377 newdc = (DC *) GDI_HEAP_LIN_ADDR( handle );
379 dprintf_dc(stddeb, "GetDCState(%04x): returning %04x\n", hdc, handle );
381 memset( &newdc->u.x, 0, sizeof(newdc->u.x) );
382 memcpy( &newdc->w, &dc->w, sizeof(dc->w) );
384 newdc->hSelf = (HDC32)handle;
385 newdc->saveLevel = 0;
386 newdc->w.flags |= DC_SAVED;
388 newdc->w.hGCClipRgn = 0;
389 newdc->w.hVisRgn = CreateRectRgn32( 0, 0, 0, 0 );
390 CombineRgn32( newdc->w.hVisRgn, dc->w.hVisRgn, 0, RGN_COPY );
391 if (dc->w.hClipRgn)
393 newdc->w.hClipRgn = CreateRectRgn32( 0, 0, 0, 0 );
394 CombineRgn32( newdc->w.hClipRgn, dc->w.hClipRgn, 0, RGN_COPY );
396 return handle;
400 /***********************************************************************
401 * SetDCState (GDI.180)
403 void SetDCState( HDC16 hdc, HDC16 hdcs )
405 DC *dc, *dcs;
407 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return;
408 if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) return;
409 if (!dcs->w.flags & DC_SAVED) return;
410 dprintf_dc(stddeb, "SetDCState: %04x %04x\n", hdc, hdcs );
412 dc->w.flags = dcs->w.flags & ~DC_SAVED;
413 dc->w.devCaps = dcs->w.devCaps;
414 dc->w.hFirstBitmap = dcs->w.hFirstBitmap;
415 dc->w.hDevice = dcs->w.hDevice;
416 dc->w.ROPmode = dcs->w.ROPmode;
417 dc->w.polyFillMode = dcs->w.polyFillMode;
418 dc->w.stretchBltMode = dcs->w.stretchBltMode;
419 dc->w.relAbsMode = dcs->w.relAbsMode;
420 dc->w.backgroundMode = dcs->w.backgroundMode;
421 dc->w.backgroundColor = dcs->w.backgroundColor;
422 dc->w.textColor = dcs->w.textColor;
423 dc->w.backgroundPixel = dcs->w.backgroundPixel;
424 dc->w.textPixel = dcs->w.textPixel;
425 dc->w.brushOrgX = dcs->w.brushOrgX;
426 dc->w.brushOrgY = dcs->w.brushOrgY;
427 dc->w.textAlign = dcs->w.textAlign;
428 dc->w.charExtra = dcs->w.charExtra;
429 dc->w.breakTotalExtra = dcs->w.breakTotalExtra;
430 dc->w.breakCount = dcs->w.breakCount;
431 dc->w.breakExtra = dcs->w.breakExtra;
432 dc->w.breakRem = dcs->w.breakRem;
433 dc->w.MapMode = dcs->w.MapMode;
434 dc->w.DCOrgX = dcs->w.DCOrgX;
435 dc->w.DCOrgY = dcs->w.DCOrgY;
436 dc->w.CursPosX = dcs->w.CursPosX;
437 dc->w.CursPosY = dcs->w.CursPosY;
438 dc->w.WndOrgX = dcs->w.WndOrgX;
439 dc->w.WndOrgY = dcs->w.WndOrgY;
440 dc->w.WndExtX = dcs->w.WndExtX;
441 dc->w.WndExtY = dcs->w.WndExtY;
442 dc->w.VportOrgX = dcs->w.VportOrgX;
443 dc->w.VportOrgY = dcs->w.VportOrgY;
444 dc->w.VportExtX = dcs->w.VportExtX;
445 dc->w.VportExtY = dcs->w.VportExtY;
447 if (!(dc->w.flags & DC_MEMORY)) dc->w.bitsPerPixel = dcs->w.bitsPerPixel;
448 CombineRgn32( dc->w.hVisRgn, dcs->w.hVisRgn, 0, RGN_COPY );
449 SelectClipRgn32( hdc, dcs->w.hClipRgn );
450 SelectObject32( hdc, dcs->w.hBitmap );
451 SelectObject32( hdc, dcs->w.hBrush );
452 SelectObject32( hdc, dcs->w.hFont );
453 SelectObject32( hdc, dcs->w.hPen );
454 GDISelectPalette( hdc, dcs->w.hPalette, FALSE );
458 /***********************************************************************
459 * SaveDC (GDI.30)
461 int SaveDC( HDC16 hdc )
463 HDC16 hdcs;
464 DC * dc, * dcs;
466 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
467 if (!dc)
469 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
470 if (!dc) return 0;
471 MF_MetaParam0(dc, META_SAVEDC);
472 return 1; /* ?? */
474 if (!(hdcs = GetDCState( hdc ))) return 0;
475 dcs = (DC *) GDI_HEAP_LIN_ADDR( hdcs );
476 dcs->header.hNext = dc->header.hNext;
477 dc->header.hNext = hdcs;
478 dprintf_dc(stddeb, "SaveDC(%04x): returning %d\n", hdc, dc->saveLevel+1 );
479 return ++dc->saveLevel;
483 /***********************************************************************
484 * RestoreDC (GDI.39)
486 BOOL RestoreDC( HDC16 hdc, short level )
488 DC * dc, * dcs;
490 dprintf_dc(stddeb, "RestoreDC: %04x %d\n", hdc, level );
491 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
492 if (!dc)
494 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
495 if (!dc) return FALSE;
496 if (level != -1) return FALSE;
497 MF_MetaParam1(dc, META_RESTOREDC, level);
498 return TRUE;
500 if (level == -1) level = dc->saveLevel;
501 if ((level < 1) || (level > (short)dc->saveLevel)) return FALSE;
503 while ((short)dc->saveLevel >= level)
505 HDC16 hdcs = dc->header.hNext;
506 if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) return FALSE;
507 dc->header.hNext = dcs->header.hNext;
508 if ((short)--dc->saveLevel < level) SetDCState( hdc, hdcs );
509 DeleteDC( hdcs );
511 return TRUE;
515 /***********************************************************************
516 * CreateDC16 (GDI.53)
518 HDC16 CreateDC16( LPCSTR driver, LPCSTR device, LPCSTR output,
519 const DEVMODE16 *initData )
521 DC * dc;
522 const DC_FUNCTIONS *funcs;
524 if (!(funcs = DRIVER_FindDriver( driver ))) return 0;
525 if (!(dc = DC_AllocDC( funcs ))) return 0;
526 dc->w.flags = 0;
528 dprintf_dc(stddeb, "CreateDC(%s %s %s): returning %04x\n",
529 driver, device, output, dc->hSelf );
531 if (dc->funcs->pCreateDC &&
532 !dc->funcs->pCreateDC( dc, driver, device, output, initData ))
534 dprintf_dc( stddeb, "CreateDC: creation aborted by device\n" );
535 GDI_HEAP_FREE( dc->hSelf );
536 return 0;
539 DC_InitDC( dc );
540 return dc->hSelf;
544 /***********************************************************************
545 * CreateDC32A (GDI32.)
547 HDC32 CreateDC32A( LPCSTR driver, LPCSTR device, LPCSTR output,
548 const DEVMODE32A *initData )
550 return CreateDC16( driver, device, output, (const DEVMODE16 *)initData );
554 /***********************************************************************
555 * CreateDC32W (GDI32.)
557 HDC32 CreateDC32W( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
558 const DEVMODE32W *initData )
560 LPSTR driverA = driver?STRING32_DupUniToAnsi(driver):NULL;
561 LPSTR deviceA = device?STRING32_DupUniToAnsi(device):NULL;
562 LPSTR outputA = output?STRING32_DupUniToAnsi(output):NULL;
563 HDC32 res;
565 res = CreateDC16( driverA, deviceA, outputA, (const DEVMODE16 *)initData );
566 if (driverA) free(driverA);
567 if (deviceA) free(deviceA);
568 if (outputA) free(outputA);
569 return res;
573 /***********************************************************************
574 * CreateIC (GDI.153)
576 HDC16 CreateIC( LPCSTR driver, LPCSTR device, LPCSTR output,
577 const DEVMODE16* initData )
579 /* Nothing special yet for ICs */
580 return CreateDC16( driver, device, output, initData );
584 /***********************************************************************
585 * CreateCompatibleDC (GDI.52)
587 HDC16 CreateCompatibleDC( HDC16 hdc )
589 DC *dc, *origDC;
590 HBITMAP16 hbitmap;
591 const DC_FUNCTIONS *funcs;
593 if ((origDC = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC ))) funcs = origDC->funcs;
594 else funcs = DRIVER_FindDriver( "DISPLAY" );
595 if (!funcs) return 0;
597 if (!(dc = DC_AllocDC( funcs ))) return 0;
599 dprintf_dc(stddeb, "CreateCompatibleDC(%04x): returning %04x\n",
600 hdc, dc->hSelf );
602 /* Create default bitmap */
603 if (!(hbitmap = CreateBitmap( 1, 1, 1, 1, NULL )))
605 GDI_HEAP_FREE( dc->hSelf );
606 return 0;
608 dc->w.flags = DC_MEMORY;
609 dc->w.bitsPerPixel = 1;
610 dc->w.hBitmap = hbitmap;
611 dc->w.hFirstBitmap = hbitmap;
613 if (dc->funcs->pCreateDC &&
614 !dc->funcs->pCreateDC( dc, NULL, NULL, NULL, NULL ))
616 dprintf_dc( stddeb, "CreateDC: creation aborted by device\n" );
617 DeleteObject32( hbitmap );
618 GDI_HEAP_FREE( dc->hSelf );
619 return 0;
622 DC_InitDC( dc );
623 return dc->hSelf;
627 /***********************************************************************
628 * DeleteDC (GDI.68)
630 BOOL DeleteDC( HDC16 hdc )
632 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
633 if (!dc) return FALSE;
635 dprintf_dc(stddeb, "DeleteDC: %04x\n", hdc );
637 while (dc->saveLevel)
639 DC * dcs;
640 HDC16 hdcs = dc->header.hNext;
641 if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) break;
642 dc->header.hNext = dcs->header.hNext;
643 dc->saveLevel--;
644 DeleteDC( hdcs );
647 if (!(dc->w.flags & DC_SAVED))
649 SelectObject32( hdc, STOCK_BLACK_PEN );
650 SelectObject32( hdc, STOCK_WHITE_BRUSH );
651 SelectObject32( hdc, STOCK_SYSTEM_FONT );
652 if (dc->w.flags & DC_MEMORY) DeleteObject32( dc->w.hFirstBitmap );
653 if (dc->funcs->pDeleteDC) dc->funcs->pDeleteDC(dc);
656 if (dc->w.hClipRgn) DeleteObject32( dc->w.hClipRgn );
657 if (dc->w.hVisRgn) DeleteObject32( dc->w.hVisRgn );
658 if (dc->w.hGCClipRgn) DeleteObject32( dc->w.hGCClipRgn );
660 return GDI_FreeObject( hdc );
664 /***********************************************************************
665 * ResetDC (GDI.376)
667 HDC16 ResetDC( HDC16 hdc, /* DEVMODE */ void *devmode )
669 fprintf( stderr, "ResetDC: empty stub!\n" );
670 return hdc;
674 /***********************************************************************
675 * GetDeviceCaps (GDI.80)
677 int GetDeviceCaps( HDC16 hdc, WORD cap )
679 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
680 if (!dc) return 0;
682 if (cap > sizeof(DeviceCaps)-sizeof(WORD)) return 0;
684 dprintf_dc(stddeb, "GetDeviceCaps(%04x,%d): returning %d\n",
685 hdc, cap, *(WORD *)(((char *)dc->w.devCaps) + cap) );
686 return *(WORD *)(((char *)dc->w.devCaps) + cap);
690 /***********************************************************************
691 * SetBkColor (GDI.1) (GDI32.305)
693 COLORREF SetBkColor( HDC32 hdc, COLORREF color )
695 COLORREF oldColor;
696 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
697 if (!dc)
699 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
700 if (!dc) return 0x80000000;
701 MF_MetaParam2(dc, META_SETBKCOLOR, HIWORD(color), LOWORD(color));
702 return 0; /* ?? */
705 oldColor = dc->w.backgroundColor;
706 dc->w.backgroundColor = color;
707 dc->w.backgroundPixel = COLOR_ToPhysical( dc, color );
708 return oldColor;
712 /***********************************************************************
713 * SetTextColor (GDI.9) (GDI32.338)
715 COLORREF SetTextColor( HDC32 hdc, COLORREF color )
717 COLORREF oldColor;
718 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
719 if (!dc)
721 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
722 if (!dc) return 0x80000000;
723 MF_MetaParam2(dc, META_SETTEXTCOLOR, HIWORD(color), LOWORD(color));
724 return 0; /* ?? */
727 oldColor = dc->w.textColor;
728 dc->w.textColor = color;
729 dc->w.textPixel = COLOR_ToPhysical( dc, color );
730 return oldColor;
734 /***********************************************************************
735 * SetTextAlign (GDI.346)
737 WORD SetTextAlign( HDC16 hdc, WORD textAlign )
739 WORD prevAlign;
740 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
741 if (!dc)
743 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ))) return 0;
744 MF_MetaParam1( dc, META_SETTEXTALIGN, textAlign );
745 return 1;
747 prevAlign = dc->w.textAlign;
748 dc->w.textAlign = textAlign;
749 return prevAlign;
753 /***********************************************************************
754 * GetDCOrgEx (GDI32.168)
756 BOOL32 GetDCOrgEx(HDC32 hDC, LPPOINT32 lpp)
758 DC * dc = (DC *) GDI_GetObjPtr( hDC, DC_MAGIC );
759 if (!dc || !lpp) return FALSE;
761 if (!(dc->w.flags & DC_MEMORY))
763 Window root;
764 int w, h, border, depth;
766 XGetGeometry( display, dc->u.x.drawable, &root,
767 &lpp->x, &lpp->y, &w, &h, &border, &depth );
769 else lpp->x = lpp->y = 0;
770 lpp->x += dc->w.DCOrgX; lpp->y += dc->w.DCOrgY;
771 return TRUE;
775 /***********************************************************************
776 * GetDCOrg (GDI.79)
778 DWORD GetDCOrg( HDC16 hdc )
780 POINT32 pt;
781 if( GetDCOrgEx( hdc, &pt) )
782 return MAKELONG( (WORD)pt.x, (WORD)pt.y );
783 return 0;
787 /***********************************************************************
788 * SetDCOrg (GDI.117)
790 DWORD SetDCOrg( HDC16 hdc, short x, short y )
792 DWORD prevOrg;
793 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
794 if (!dc) return 0;
795 prevOrg = dc->w.DCOrgX | (dc->w.DCOrgY << 16);
796 dc->w.DCOrgX = x;
797 dc->w.DCOrgY = y;
798 return prevOrg;
802 /***********************************************************************
803 * SetDCHook (GDI.190)
805 BOOL16 SetDCHook( HDC16 hdc, FARPROC16 hookProc, DWORD dwHookData )
807 DC *dc = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC );
809 dprintf_dc( stddeb, "SetDCHook: hookProc %08x, default is %08x\n",
810 (UINT32)hookProc, (UINT32)DCHook );
812 if (!dc) return FALSE;
813 dc->hookProc = hookProc;
814 dc->dwHookData = dwHookData;
815 return TRUE;
819 /***********************************************************************
820 * GetDCHook (GDI.191)
822 DWORD GetDCHook( HDC16 hdc, FARPROC16 *phookProc )
824 DC *dc = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC );
825 if (!dc) return 0;
826 *phookProc = dc->hookProc;
827 return dc->dwHookData;
831 /***********************************************************************
832 * SetHookFlags (GDI.192)
834 WORD SetHookFlags(HDC16 hDC, WORD flags)
836 DC* dc = (DC*)GDI_GetObjPtr( hDC, DC_MAGIC );
838 if( dc )
840 WORD wRet = dc->w.flags & DC_DIRTY;
842 /* "Undocumented Windows" info is slightly
843 * confusing
846 dprintf_dc(stddeb,"SetHookFlags: hDC %04x, flags %04x\n",hDC,flags);
848 if( flags & DCHF_INVALIDATEVISRGN )
849 dc->w.flags |= DC_DIRTY;
850 else if( flags & DCHF_VALIDATEVISRGN || !flags )
851 dc->w.flags &= ~DC_DIRTY;
852 return wRet;
854 return 0;