blob: 24b16ef6dc8a84f3f64f0798889d041d0d718d87 [file] [log] [blame]
Alexandre Julliard401710d1993-09-04 10:09:32 +00001/*
2 * GDI Device Context functions
3 *
4 * Copyright 1993 Alexandre Julliard
Alexandre Julliard234bc241994-12-10 13:02:28 +00005 *
Alexandre Julliard7cbe6571995-01-09 18:21:16 +00006 */
7
Patrik Stridvalld96e1f11999-07-04 13:31:03 +00008#include "config.h"
9
Alexandre Julliard401710d1993-09-04 10:09:32 +000010#include <stdlib.h>
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000011#include <string.h>
Alexandre Julliard401710d1993-09-04 10:09:32 +000012#include "gdi.h"
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +000013#include "heap.h"
Alexandre Julliard15657091999-05-23 10:25:25 +000014#include "debugtools.h"
Alexandre Julliard234bc241994-12-10 13:02:28 +000015#include "font.h"
Huw D M Davies304d9a41999-09-13 15:15:45 +000016#include "callback.h"
Alexandre Julliard60ce85c1998-02-01 18:33:27 +000017#include "winerror.h"
Jeremy Whited3e22d92000-02-10 19:03:02 +000018#include "windef.h"
19#include "wingdi.h"
Patrik Stridvall8d8703c1999-02-04 14:05:38 +000020#include "wine/winuser16.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000021
Alexandre Julliard07e42132000-03-19 21:19:21 +000022DEFAULT_DEBUG_CHANNEL(dc);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000023
Alexandre Julliard44ed71f1997-12-21 19:17:50 +000024
25/***********************************************************************
Alexandre Julliardbf9130a1996-10-13 17:45:47 +000026 * DC_AllocDC
27 */
28DC *DC_AllocDC( const DC_FUNCTIONS *funcs )
29{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +000030 HDC hdc;
Alexandre Julliardbf9130a1996-10-13 17:45:47 +000031 DC *dc;
32
Alexandre Julliard2239abb2000-11-05 02:05:07 +000033 if (!(dc = GDI_AllocObject( sizeof(*dc), DC_MAGIC, &hdc ))) return NULL;
Alexandre Julliardbf9130a1996-10-13 17:45:47 +000034
Alexandre Julliard2239abb2000-11-05 02:05:07 +000035 dc->hSelf = hdc;
36 dc->funcs = funcs;
37 dc->physDev = NULL;
38 dc->saveLevel = 0;
39 dc->dwHookData = 0;
40 dc->hookProc = NULL;
41 dc->hookThunk = NULL;
42 dc->wndOrgX = 0;
43 dc->wndOrgY = 0;
44 dc->wndExtX = 1;
45 dc->wndExtY = 1;
46 dc->vportOrgX = 0;
47 dc->vportOrgY = 0;
48 dc->vportExtX = 1;
49 dc->vportExtY = 1;
50 dc->flags = 0;
Alexandre Julliard2239abb2000-11-05 02:05:07 +000051 dc->hClipRgn = 0;
52 dc->hVisRgn = 0;
53 dc->hGCClipRgn = 0;
54 dc->hPen = GetStockObject( BLACK_PEN );
55 dc->hBrush = GetStockObject( WHITE_BRUSH );
56 dc->hFont = GetStockObject( SYSTEM_FONT );
57 dc->hBitmap = 0;
58 dc->hDevice = 0;
59 dc->hPalette = GetStockObject( DEFAULT_PALETTE );
Huw D M Davies814654e2001-09-12 20:21:06 +000060 dc->gdiFont = 0;
Alexandre Julliard2239abb2000-11-05 02:05:07 +000061 dc->ROPmode = R2_COPYPEN;
62 dc->polyFillMode = ALTERNATE;
63 dc->stretchBltMode = BLACKONWHITE;
64 dc->relAbsMode = ABSOLUTE;
65 dc->backgroundMode = OPAQUE;
66 dc->backgroundColor = RGB( 255, 255, 255 );
67 dc->textColor = RGB( 0, 0, 0 );
68 dc->brushOrgX = 0;
69 dc->brushOrgY = 0;
70 dc->textAlign = TA_LEFT | TA_TOP | TA_NOUPDATECP;
71 dc->charExtra = 0;
72 dc->breakTotalExtra = 0;
73 dc->breakCount = 0;
74 dc->breakExtra = 0;
75 dc->breakRem = 0;
76 dc->totalExtent.left = 0;
77 dc->totalExtent.top = 0;
78 dc->totalExtent.right = 0;
79 dc->totalExtent.bottom = 0;
80 dc->bitsPerPixel = 1;
81 dc->MapMode = MM_TEXT;
82 dc->GraphicsMode = GM_COMPATIBLE;
83 dc->DCOrgX = 0;
84 dc->DCOrgY = 0;
85 dc->pAbortProc = NULL;
86 dc->CursPosX = 0;
87 dc->CursPosY = 0;
88 dc->ArcDirection = AD_COUNTERCLOCKWISE;
89 dc->xformWorld2Wnd.eM11 = 1.0f;
90 dc->xformWorld2Wnd.eM12 = 0.0f;
91 dc->xformWorld2Wnd.eM21 = 0.0f;
92 dc->xformWorld2Wnd.eM22 = 1.0f;
93 dc->xformWorld2Wnd.eDx = 0.0f;
94 dc->xformWorld2Wnd.eDy = 0.0f;
95 dc->xformWorld2Vport = dc->xformWorld2Wnd;
96 dc->xformVport2World = dc->xformWorld2Wnd;
97 dc->vport2WorldValid = TRUE;
98 PATH_InitGdiPath(&dc->path);
Alexandre Julliardbf9130a1996-10-13 17:45:47 +000099 return dc;
100}
101
102
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000103
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000104/***********************************************************************
105 * DC_GetDCPtr
106 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000107DC *DC_GetDCPtr( HDC hdc )
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000108{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000109 GDIOBJHDR *ptr = GDI_GetObjPtr( hdc, MAGIC_DONTCARE );
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000110 if (!ptr) return NULL;
Andreas Mohr007fb242000-09-16 20:53:51 +0000111 if ((GDIMAGIC(ptr->wMagic) == DC_MAGIC) ||
112 (GDIMAGIC(ptr->wMagic) == METAFILE_DC_MAGIC) ||
113 (GDIMAGIC(ptr->wMagic) == ENHMETAFILE_DC_MAGIC))
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000114 return (DC *)ptr;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000115 GDI_ReleaseObj( hdc );
Patrik Stridvalle4174d52000-05-18 00:51:52 +0000116 SetLastError( ERROR_INVALID_HANDLE );
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000117 return NULL;
118}
119
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000120/***********************************************************************
121 * DC_GetDCUpdate
122 *
123 * Retrieve a DC ptr while making sure the visRgn is updated.
124 * This function may call up to USER so the GDI lock should _not_
125 * be held when calling it.
126 */
127DC *DC_GetDCUpdate( HDC hdc )
128{
129 DC *dc = DC_GetDCPtr( hdc );
130 if (!dc) return NULL;
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000131 while (dc->flags & DC_DIRTY)
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000132 {
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000133 dc->flags &= ~DC_DIRTY;
134 if (!(dc->flags & (DC_SAVED | DC_MEMORY)))
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000135 {
136 DCHOOKPROC proc = dc->hookThunk;
137 if (proc)
138 {
139 DWORD data = dc->dwHookData;
140 GDI_ReleaseObj( hdc );
141 proc( hdc, DCHC_INVALIDVISRGN, data, 0 );
142 if (!(dc = DC_GetDCPtr( hdc ))) break;
143 /* otherwise restart the loop in case it became dirty again in the meantime */
144 }
145 }
146 }
147 return dc;
148}
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000149
150/***********************************************************************
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000151 * DC_InitDC
Alexandre Julliard401710d1993-09-04 10:09:32 +0000152 *
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000153 * Setup device-specific DC values for a newly created DC.
Alexandre Julliard401710d1993-09-04 10:09:32 +0000154 */
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000155void DC_InitDC( DC* dc )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000156{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000157 RealizeDefaultPalette16( dc->hSelf );
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000158 SetTextColor( dc->hSelf, dc->textColor );
159 SetBkColor( dc->hSelf, dc->backgroundColor );
160 SelectObject( dc->hSelf, dc->hPen );
161 SelectObject( dc->hSelf, dc->hBrush );
162 SelectObject( dc->hSelf, dc->hFont );
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000163 CLIPPING_UpdateGCRegion( dc );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000164}
165
166
167/***********************************************************************
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000168 * DC_InvertXform
169 *
170 * Computes the inverse of the transformation xformSrc and stores it to
171 * xformDest. Returns TRUE if successful or FALSE if the xformSrc matrix
172 * is singular.
173 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000174static BOOL DC_InvertXform( const XFORM *xformSrc, XFORM *xformDest )
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000175{
176 FLOAT determinant;
177
178 determinant = xformSrc->eM11*xformSrc->eM22 -
179 xformSrc->eM12*xformSrc->eM21;
180 if (determinant > -1e-12 && determinant < 1e-12)
181 return FALSE;
182
183 xformDest->eM11 = xformSrc->eM22 / determinant;
184 xformDest->eM12 = -xformSrc->eM12 / determinant;
185 xformDest->eM21 = -xformSrc->eM21 / determinant;
186 xformDest->eM22 = xformSrc->eM11 / determinant;
187 xformDest->eDx = -xformSrc->eDx * xformDest->eM11 -
188 xformSrc->eDy * xformDest->eM21;
189 xformDest->eDy = -xformSrc->eDx * xformDest->eM12 -
190 xformSrc->eDy * xformDest->eM22;
191
192 return TRUE;
193}
194
195
196/***********************************************************************
197 * DC_UpdateXforms
198 *
199 * Updates the xformWorld2Vport, xformVport2World and vport2WorldValid
200 * fields of the specified DC by creating a transformation that
201 * represents the current mapping mode and combining it with the DC's
202 * world transform. This function should be called whenever the
203 * parameters associated with the mapping mode (window and viewport
204 * extents and origins) or the world transform change.
205 */
206void DC_UpdateXforms( DC *dc )
207{
208 XFORM xformWnd2Vport;
209 FLOAT scaleX, scaleY;
210
211 /* Construct a transformation to do the window-to-viewport conversion */
212 scaleX = (FLOAT)dc->vportExtX / (FLOAT)dc->wndExtX;
213 scaleY = (FLOAT)dc->vportExtY / (FLOAT)dc->wndExtY;
214 xformWnd2Vport.eM11 = scaleX;
215 xformWnd2Vport.eM12 = 0.0;
216 xformWnd2Vport.eM21 = 0.0;
217 xformWnd2Vport.eM22 = scaleY;
218 xformWnd2Vport.eDx = (FLOAT)dc->vportOrgX -
219 scaleX * (FLOAT)dc->wndOrgX;
220 xformWnd2Vport.eDy = (FLOAT)dc->vportOrgY -
221 scaleY * (FLOAT)dc->wndOrgY;
222
223 /* Combine with the world transformation */
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000224 CombineTransform( &dc->xformWorld2Vport, &dc->xformWorld2Wnd,
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000225 &xformWnd2Vport );
226
227 /* Create inverse of world-to-viewport transformation */
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000228 dc->vport2WorldValid = DC_InvertXform( &dc->xformWorld2Vport,
229 &dc->xformVport2World );
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000230}
231
232
233/***********************************************************************
Alexandre Julliard401710d1993-09-04 10:09:32 +0000234 * GetDCState (GDI.179)
235 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000236HDC16 WINAPI GetDCState16( HDC16 hdc )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000237{
238 DC * newdc, * dc;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000239 HGDIOBJ handle;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000240
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000241 if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
242 if (!(newdc = GDI_AllocObject( sizeof(DC), DC_MAGIC, &handle )))
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000243 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000244 GDI_ReleaseObj( hdc );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000245 return 0;
246 }
Alexandre Julliard15657091999-05-23 10:25:25 +0000247 TRACE("(%04x): returning %04x\n", hdc, handle );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000248
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000249 newdc->flags = dc->flags | DC_SAVED;
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000250 newdc->hPen = dc->hPen;
251 newdc->hBrush = dc->hBrush;
252 newdc->hFont = dc->hFont;
253 newdc->hBitmap = dc->hBitmap;
254 newdc->hDevice = dc->hDevice;
255 newdc->hPalette = dc->hPalette;
256 newdc->totalExtent = dc->totalExtent;
257 newdc->bitsPerPixel = dc->bitsPerPixel;
258 newdc->ROPmode = dc->ROPmode;
259 newdc->polyFillMode = dc->polyFillMode;
260 newdc->stretchBltMode = dc->stretchBltMode;
261 newdc->relAbsMode = dc->relAbsMode;
262 newdc->backgroundMode = dc->backgroundMode;
263 newdc->backgroundColor = dc->backgroundColor;
264 newdc->textColor = dc->textColor;
265 newdc->brushOrgX = dc->brushOrgX;
266 newdc->brushOrgY = dc->brushOrgY;
267 newdc->textAlign = dc->textAlign;
268 newdc->charExtra = dc->charExtra;
269 newdc->breakTotalExtra = dc->breakTotalExtra;
270 newdc->breakCount = dc->breakCount;
271 newdc->breakExtra = dc->breakExtra;
272 newdc->breakRem = dc->breakRem;
273 newdc->MapMode = dc->MapMode;
274 newdc->GraphicsMode = dc->GraphicsMode;
Ulrich Weigandd4663661998-10-11 18:47:02 +0000275#if 0
276 /* Apparently, the DC origin is not changed by [GS]etDCState */
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000277 newdc->DCOrgX = dc->DCOrgX;
278 newdc->DCOrgY = dc->DCOrgY;
Ulrich Weigandd4663661998-10-11 18:47:02 +0000279#endif
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000280 newdc->CursPosX = dc->CursPosX;
281 newdc->CursPosY = dc->CursPosY;
282 newdc->ArcDirection = dc->ArcDirection;
283 newdc->xformWorld2Wnd = dc->xformWorld2Wnd;
284 newdc->xformWorld2Vport = dc->xformWorld2Vport;
285 newdc->xformVport2World = dc->xformVport2World;
286 newdc->vport2WorldValid = dc->vport2WorldValid;
287 newdc->wndOrgX = dc->wndOrgX;
288 newdc->wndOrgY = dc->wndOrgY;
289 newdc->wndExtX = dc->wndExtX;
290 newdc->wndExtY = dc->wndExtY;
291 newdc->vportOrgX = dc->vportOrgX;
292 newdc->vportOrgY = dc->vportOrgY;
293 newdc->vportExtX = dc->vportExtX;
294 newdc->vportExtY = dc->vportExtY;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000295
Alexandre Julliarda3960291999-02-26 11:11:13 +0000296 newdc->hSelf = (HDC)handle;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000297 newdc->saveLevel = 0;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000298
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000299 PATH_InitGdiPath( &newdc->path );
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000300
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000301 newdc->pAbortProc = NULL;
Gerard Patel5131f212000-06-12 21:52:58 +0000302 newdc->hookThunk = NULL;
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000303 newdc->hookProc = 0;
Huw D M Davies304d9a41999-09-13 15:15:45 +0000304
Alexandre Julliard491502b1997-11-01 19:08:16 +0000305 /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
306
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000307 newdc->hGCClipRgn = newdc->hVisRgn = 0;
308 if (dc->hClipRgn)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000309 {
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000310 newdc->hClipRgn = CreateRectRgn( 0, 0, 0, 0 );
311 CombineRgn( newdc->hClipRgn, dc->hClipRgn, 0, RGN_COPY );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000312 }
Alexandre Julliard349a9531997-02-02 19:01:52 +0000313 else
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000314 newdc->hClipRgn = 0;
Huw D M Davies814654e2001-09-12 20:21:06 +0000315
316 if(dc->gdiFont) {
317 WineEngAddRefFont(dc->gdiFont);
318 newdc->gdiFont = dc->gdiFont;
319 } else
320 newdc->gdiFont = 0;
321
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000322 GDI_ReleaseObj( handle );
323 GDI_ReleaseObj( hdc );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000324 return handle;
325}
326
327
328/***********************************************************************
329 * SetDCState (GDI.180)
330 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000331void WINAPI SetDCState16( HDC16 hdc, HDC16 hdcs )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000332{
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000333 DC *dc, *dcs;
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000334
335 if (!(dc = GDI_GetObjPtr( hdc, DC_MAGIC ))) return;
336 if (!(dcs = GDI_GetObjPtr( hdcs, DC_MAGIC )))
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000337 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000338 GDI_ReleaseObj( hdc );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000339 return;
340 }
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000341 if (!dcs->flags & DC_SAVED)
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000342 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000343 GDI_ReleaseObj( hdc );
344 GDI_ReleaseObj( hdcs );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000345 return;
346 }
Alexandre Julliard15657091999-05-23 10:25:25 +0000347 TRACE("%04x %04x\n", hdc, hdcs );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000348
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000349 dc->flags = dcs->flags & ~DC_SAVED;
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000350 dc->hDevice = dcs->hDevice;
351 dc->totalExtent = dcs->totalExtent;
352 dc->ROPmode = dcs->ROPmode;
353 dc->polyFillMode = dcs->polyFillMode;
354 dc->stretchBltMode = dcs->stretchBltMode;
355 dc->relAbsMode = dcs->relAbsMode;
356 dc->backgroundMode = dcs->backgroundMode;
357 dc->backgroundColor = dcs->backgroundColor;
358 dc->textColor = dcs->textColor;
359 dc->brushOrgX = dcs->brushOrgX;
360 dc->brushOrgY = dcs->brushOrgY;
361 dc->textAlign = dcs->textAlign;
362 dc->charExtra = dcs->charExtra;
363 dc->breakTotalExtra = dcs->breakTotalExtra;
364 dc->breakCount = dcs->breakCount;
365 dc->breakExtra = dcs->breakExtra;
366 dc->breakRem = dcs->breakRem;
367 dc->MapMode = dcs->MapMode;
368 dc->GraphicsMode = dcs->GraphicsMode;
Ulrich Weigandd4663661998-10-11 18:47:02 +0000369#if 0
370 /* Apparently, the DC origin is not changed by [GS]etDCState */
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000371 dc->DCOrgX = dcs->DCOrgX;
372 dc->DCOrgY = dcs->DCOrgY;
Ulrich Weigandd4663661998-10-11 18:47:02 +0000373#endif
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000374 dc->CursPosX = dcs->CursPosX;
375 dc->CursPosY = dcs->CursPosY;
376 dc->ArcDirection = dcs->ArcDirection;
377 dc->xformWorld2Wnd = dcs->xformWorld2Wnd;
378 dc->xformWorld2Vport = dcs->xformWorld2Vport;
379 dc->xformVport2World = dcs->xformVport2World;
380 dc->vport2WorldValid = dcs->vport2WorldValid;
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000381
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000382 dc->wndOrgX = dcs->wndOrgX;
383 dc->wndOrgY = dcs->wndOrgY;
384 dc->wndExtX = dcs->wndExtX;
385 dc->wndExtY = dcs->wndExtY;
386 dc->vportOrgX = dcs->vportOrgX;
387 dc->vportOrgY = dcs->vportOrgY;
388 dc->vportExtX = dcs->vportExtX;
389 dc->vportExtY = dcs->vportExtY;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000390
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000391 if (!(dc->flags & DC_MEMORY)) dc->bitsPerPixel = dcs->bitsPerPixel;
Ulrich Weigandd4663661998-10-11 18:47:02 +0000392
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000393 if (dcs->hClipRgn)
Ulrich Weigandd4663661998-10-11 18:47:02 +0000394 {
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000395 if (!dc->hClipRgn) dc->hClipRgn = CreateRectRgn( 0, 0, 0, 0 );
396 CombineRgn( dc->hClipRgn, dcs->hClipRgn, 0, RGN_COPY );
Ulrich Weigandd4663661998-10-11 18:47:02 +0000397 }
398 else
Ulrich Weigand7119a6e1998-11-01 14:05:33 +0000399 {
Dmitry Timoshkov698ef152001-06-25 20:08:44 +0000400 if (dc->hClipRgn) DeleteObject( dc->hClipRgn );
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000401 dc->hClipRgn = 0;
Ulrich Weigand7119a6e1998-11-01 14:05:33 +0000402 }
403 CLIPPING_UpdateGCRegion( dc );
Alexandre Julliard491502b1997-11-01 19:08:16 +0000404
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000405 SelectObject( hdc, dcs->hBitmap );
406 SelectObject( hdc, dcs->hBrush );
407 SelectObject( hdc, dcs->hFont );
408 SelectObject( hdc, dcs->hPen );
409 SetBkColor( hdc, dcs->backgroundColor);
410 SetTextColor( hdc, dcs->textColor);
411 GDISelectPalette16( hdc, dcs->hPalette, FALSE );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000412 GDI_ReleaseObj( hdcs );
413 GDI_ReleaseObj( hdc );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000414}
415
416
417/***********************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +0000418 * SaveDC (GDI.30)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000419 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000420INT16 WINAPI SaveDC16( HDC16 hdc )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000421{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000422 return (INT16)SaveDC( hdc );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000423}
424
425
426/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000427 * SaveDC (GDI32.@)
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000428 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000429INT WINAPI SaveDC( HDC hdc )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000430{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000431 HDC hdcs;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000432 DC * dc, * dcs;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000433 INT ret;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000434
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000435 dc = DC_GetDCUpdate( hdc );
Huw D M Davies7603dea1999-04-25 09:24:23 +0000436 if (!dc) return 0;
437
438 if(dc->funcs->pSaveDC)
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000439 {
440 ret = dc->funcs->pSaveDC( dc );
441 GDI_ReleaseObj( hdc );
442 return ret;
443 }
Huw D M Davies7603dea1999-04-25 09:24:23 +0000444
Alexandre Julliarda3960291999-02-26 11:11:13 +0000445 if (!(hdcs = GetDCState16( hdc )))
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000446 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000447 GDI_ReleaseObj( hdc );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000448 return 0;
449 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000450 dcs = GDI_GetObjPtr( hdcs, DC_MAGIC );
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000451
452 /* Copy path. The reason why path saving / restoring is in SaveDC/
453 * RestoreDC and not in GetDCState/SetDCState is that the ...DCState
454 * functions are only in Win16 (which doesn't have paths) and that
455 * SetDCState doesn't allow us to signal an error (which can happen
456 * when copying paths).
457 */
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000458 if (!PATH_AssignGdiPath( &dcs->path, &dc->path ))
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000459 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000460 GDI_ReleaseObj( hdc );
461 GDI_ReleaseObj( hdcs );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000462 DeleteDC( hdcs );
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000463 return 0;
464 }
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000465
Alexandre Julliard401710d1993-09-04 10:09:32 +0000466 dcs->header.hNext = dc->header.hNext;
467 dc->header.hNext = hdcs;
Alexandre Julliard15657091999-05-23 10:25:25 +0000468 TRACE("(%04x): returning %d\n", hdc, dc->saveLevel+1 );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000469 ret = ++dc->saveLevel;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000470 GDI_ReleaseObj( hdcs );
471 GDI_ReleaseObj( hdc );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000472 return ret;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000473}
474
475
476/***********************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +0000477 * RestoreDC (GDI.39)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000478 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000479BOOL16 WINAPI RestoreDC16( HDC16 hdc, INT16 level )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000480{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000481 return RestoreDC( hdc, level );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000482}
483
484
485/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000486 * RestoreDC (GDI32.@)
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000487 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000488BOOL WINAPI RestoreDC( HDC hdc, INT level )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000489{
490 DC * dc, * dcs;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000491 BOOL success;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000492
Alexandre Julliard15657091999-05-23 10:25:25 +0000493 TRACE("%04x %d\n", hdc, level );
Huw D M Davies7603dea1999-04-25 09:24:23 +0000494 dc = DC_GetDCPtr( hdc );
495 if(!dc) return FALSE;
496 if(dc->funcs->pRestoreDC)
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000497 {
498 success = dc->funcs->pRestoreDC( dc, level );
499 GDI_ReleaseObj( hdc );
500 return success;
501 }
Huw D M Davies7603dea1999-04-25 09:24:23 +0000502
Alexandre Julliard401710d1993-09-04 10:09:32 +0000503 if (level == -1) level = dc->saveLevel;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000504 if ((level < 1)
505 /* This pair of checks disagrees with MSDN "Platform SDK:
506 Windows GDI" July 2000 which says all negative values
507 for level will be interpreted as an instance relative
508 to the current state. Restricting it to just -1 does
509 not satisfy this */
510 || (level > dc->saveLevel))
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000511 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000512 GDI_ReleaseObj( hdc );
513 return FALSE;
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000514 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000515
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000516 success=TRUE;
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000517 while (dc->saveLevel >= level)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000518 {
Alexandre Julliard530ee841996-10-23 16:59:13 +0000519 HDC16 hdcs = dc->header.hNext;
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000520 if (!(dcs = GDI_GetObjPtr( hdcs, DC_MAGIC )))
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000521 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000522 GDI_ReleaseObj( hdc );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000523 return FALSE;
524 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000525 dc->header.hNext = dcs->header.hNext;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000526 if (--dc->saveLevel < level)
527 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000528 SetDCState16( hdc, hdcs );
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000529 if (!PATH_AssignGdiPath( &dc->path, &dcs->path ))
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000530 /* FIXME: This might not be quite right, since we're
531 * returning FALSE but still destroying the saved DC state */
532 success=FALSE;
533 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000534 GDI_ReleaseObj( hdcs );
Alexandre Julliard71743382001-08-16 19:01:23 +0000535 GDI_ReleaseObj( hdc );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000536 DeleteDC( hdcs );
Alexandre Julliard71743382001-08-16 19:01:23 +0000537 if (!(dc = DC_GetDCPtr( hdc ))) return FALSE;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000538 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000539 GDI_ReleaseObj( hdc );
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000540 return success;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000541}
542
543
544/***********************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +0000545 * CreateDC (GDI.53)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000546 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000547HDC16 WINAPI CreateDC16( LPCSTR driver, LPCSTR device, LPCSTR output,
Huw D M Daviese39b6761999-05-17 16:20:51 +0000548 const DEVMODEA *initData )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000549{
Dmitry Timoshkov270bc582001-04-16 18:56:45 +0000550 return CreateDCA( driver, device, output, initData );
551}
552
553/***********************************************************************
554 * CreateDCA (GDI32.@)
555 */
556HDC WINAPI CreateDCA( LPCSTR driver, LPCSTR device, LPCSTR output,
557 const DEVMODEA *initData )
558{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000559 HDC hdc;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000560 DC * dc;
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000561 const DC_FUNCTIONS *funcs;
Huw D M Daviese39b6761999-05-17 16:20:51 +0000562 char buf[300];
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000563
Alexandre Julliard658cdb42001-08-15 23:33:20 +0000564 GDI_CheckNotLock();
565
Phillip Ezolt3c41fab2000-08-01 02:15:34 +0000566 if (!device || !DRIVER_GetDriverName( device, buf, sizeof(buf) ))
Huw D M Daviese39b6761999-05-17 16:20:51 +0000567 strcpy(buf, driver);
568
Alexandre Julliard3dd63eb2001-07-27 19:37:31 +0000569 if (!(funcs = DRIVER_load_driver( buf )))
570 {
571 ERR( "no driver found for %s\n", buf );
572 return 0;
573 }
574 if (!(dc = DC_AllocDC( funcs )))
575 {
576 DRIVER_release_driver( funcs );
577 return 0;
578 }
579
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000580 dc->flags = 0;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000581
Alexandre Julliard15657091999-05-23 10:25:25 +0000582 TRACE("(driver=%s, device=%s, output=%s): returning %04x\n",
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000583 debugstr_a(driver), debugstr_a(device), debugstr_a(output), dc->hSelf );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000584
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000585 if (dc->funcs->pCreateDC &&
Huw D M Davies304d9a41999-09-13 15:15:45 +0000586 !dc->funcs->pCreateDC( dc, buf, device, output, initData ))
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000587 {
Alexandre Julliard15657091999-05-23 10:25:25 +0000588 WARN("creation aborted by device\n" );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000589 GDI_FreeObject( dc->hSelf, dc );
Alexandre Julliard3dd63eb2001-07-27 19:37:31 +0000590 DRIVER_release_driver( funcs );
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000591 return 0;
592 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000593
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000594 DC_InitDC( dc );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000595 hdc = dc->hSelf;
596 GDI_ReleaseObj( hdc );
597 return hdc;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000598}
599
600
601/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000602 * CreateDCW (GDI32.@)
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000603 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000604HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
605 const DEVMODEW *initData )
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000606{
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000607 LPSTR driverA = HEAP_strdupWtoA( GetProcessHeap(), 0, driver );
608 LPSTR deviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, device );
609 LPSTR outputA = HEAP_strdupWtoA( GetProcessHeap(), 0, output );
Dmitry Timoshkov270bc582001-04-16 18:56:45 +0000610 HDC res = CreateDCA( driverA, deviceA, outputA,
Huw D M Daviese39b6761999-05-17 16:20:51 +0000611 (const DEVMODEA *)initData /*FIXME*/ );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000612 HeapFree( GetProcessHeap(), 0, driverA );
613 HeapFree( GetProcessHeap(), 0, deviceA );
614 HeapFree( GetProcessHeap(), 0, outputA );
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000615 return res;
616}
617
618
619/***********************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +0000620 * CreateIC (GDI.153)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000621 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000622HDC16 WINAPI CreateIC16( LPCSTR driver, LPCSTR device, LPCSTR output,
Huw D M Daviese39b6761999-05-17 16:20:51 +0000623 const DEVMODEA* initData )
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000624{
625 /* Nothing special yet for ICs */
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000626 return CreateDC16( driver, device, output, initData );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000627}
628
629
630/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000631 * CreateICA (GDI32.@)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000632 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000633HDC WINAPI CreateICA( LPCSTR driver, LPCSTR device, LPCSTR output,
634 const DEVMODEA* initData )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000635{
636 /* Nothing special yet for ICs */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000637 return CreateDCA( driver, device, output, initData );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000638}
639
640
641/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000642 * CreateICW (GDI32.@)
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000643 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000644HDC WINAPI CreateICW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
645 const DEVMODEW* initData )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000646{
647 /* Nothing special yet for ICs */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000648 return CreateDCW( driver, device, output, initData );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000649}
650
651
652/***********************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +0000653 * CreateCompatibleDC (GDI.52)
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000654 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000655HDC16 WINAPI CreateCompatibleDC16( HDC16 hdc )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000656{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000657 return (HDC16)CreateCompatibleDC( hdc );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000658}
659
660
661/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000662 * CreateCompatibleDC (GDI32.@)
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000663 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000664HDC WINAPI CreateCompatibleDC( HDC hdc )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000665{
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000666 DC *dc, *origDC;
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000667 const DC_FUNCTIONS *funcs;
668
Alexandre Julliard658cdb42001-08-15 23:33:20 +0000669 GDI_CheckNotLock();
670
671 if ((origDC = GDI_GetObjPtr( hdc, DC_MAGIC )))
672 {
673 funcs = origDC->funcs;
674 GDI_ReleaseObj( hdc ); /* can't hold the lock while loading the driver */
675 funcs = DRIVER_get_driver( funcs );
676 }
Alexandre Julliard3dd63eb2001-07-27 19:37:31 +0000677 else funcs = DRIVER_load_driver( "DISPLAY" );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000678
Alexandre Julliard658cdb42001-08-15 23:33:20 +0000679 if (!funcs) return 0;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000680
Alexandre Julliard3dd63eb2001-07-27 19:37:31 +0000681 if (!(dc = DC_AllocDC( funcs )))
682 {
683 DRIVER_release_driver( funcs );
Alexandre Julliard3dd63eb2001-07-27 19:37:31 +0000684 return 0;
685 }
686
Alexandre Julliard15657091999-05-23 10:25:25 +0000687 TRACE("(%04x): returning %04x\n",
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000688 hdc, dc->hSelf );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000689
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000690 dc->flags = DC_MEMORY;
691 dc->bitsPerPixel = 1;
Alexandre Julliard78f9fae2001-08-17 00:07:13 +0000692 dc->hBitmap = GetStockObject( DEFAULT_BITMAP );
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000693
Noel Borthwick86b686f1999-06-05 08:52:30 +0000694 /* Copy the driver-specific physical device info into
695 * the new DC. The driver may use this read-only info
696 * while creating the compatible DC below. */
Alexandre Julliard658cdb42001-08-15 23:33:20 +0000697 if ((origDC = GDI_GetObjPtr( hdc, DC_MAGIC ))) dc->physDev = origDC->physDev;
Noel Borthwick86b686f1999-06-05 08:52:30 +0000698
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000699 if (dc->funcs->pCreateDC &&
700 !dc->funcs->pCreateDC( dc, NULL, NULL, NULL, NULL ))
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000701 {
Alexandre Julliard15657091999-05-23 10:25:25 +0000702 WARN("creation aborted by device\n");
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000703 GDI_FreeObject( dc->hSelf, dc );
Alexandre Julliard3dd63eb2001-07-27 19:37:31 +0000704 if (origDC) GDI_ReleaseObj( hdc );
Alexandre Julliard658cdb42001-08-15 23:33:20 +0000705 DRIVER_release_driver( funcs );
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000706 return 0;
707 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000708
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +0000709 DC_InitDC( dc );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000710 GDI_ReleaseObj( dc->hSelf );
711 if (origDC) GDI_ReleaseObj( hdc );
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000712 return dc->hSelf;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000713}
714
715
716/***********************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +0000717 * DeleteDC (GDI.68)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000718 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000719BOOL16 WINAPI DeleteDC16( HDC16 hdc )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000720{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000721 return DeleteDC( hdc );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000722}
723
724
725/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000726 * DeleteDC (GDI32.@)
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000727 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000728BOOL WINAPI DeleteDC( HDC hdc )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000729{
Alexandre Julliard658cdb42001-08-15 23:33:20 +0000730 const DC_FUNCTIONS *funcs = NULL;
731 DC * dc;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000732
Alexandre Julliard15657091999-05-23 10:25:25 +0000733 TRACE("%04x\n", hdc );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000734
Alexandre Julliard658cdb42001-08-15 23:33:20 +0000735 GDI_CheckNotLock();
736
737 if (!(dc = GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE;
738
Ulrich Weigande6ea9eb1999-05-08 09:50:52 +0000739 /* Call hook procedure to check whether is it OK to delete this DC */
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000740 if (dc->hookThunk && !(dc->flags & (DC_SAVED | DC_MEMORY)))
Ulrich Weigande6ea9eb1999-05-08 09:50:52 +0000741 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000742 DCHOOKPROC proc = dc->hookThunk;
743 if (proc)
744 {
745 DWORD data = dc->dwHookData;
746 GDI_ReleaseObj( hdc );
747 if (!proc( hdc, DCHC_DELETEDC, data, 0 )) return FALSE;
Alexandre Julliarde5661952001-10-02 21:40:11 +0000748 if (!(dc = DC_GetDCPtr( hdc ))) return TRUE; /* deleted by the hook */
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000749 }
Ulrich Weigande6ea9eb1999-05-08 09:50:52 +0000750 }
751
Alexandre Julliard401710d1993-09-04 10:09:32 +0000752 while (dc->saveLevel)
753 {
754 DC * dcs;
Alexandre Julliard530ee841996-10-23 16:59:13 +0000755 HDC16 hdcs = dc->header.hNext;
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000756 if (!(dcs = GDI_GetObjPtr( hdcs, DC_MAGIC ))) break;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000757 dc->header.hNext = dcs->header.hNext;
758 dc->saveLevel--;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000759 GDI_ReleaseObj( hdcs );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000760 DeleteDC( hdcs );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000761 }
762
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000763 if (!(dc->flags & DC_SAVED))
Alexandre Julliard401710d1993-09-04 10:09:32 +0000764 {
Alexandre Julliard4c186362000-10-29 01:22:15 +0000765 SelectObject( hdc, GetStockObject(BLACK_PEN) );
766 SelectObject( hdc, GetStockObject(WHITE_BRUSH) );
767 SelectObject( hdc, GetStockObject(SYSTEM_FONT) );
Uwe Bonnes8e5e0032001-08-20 19:17:28 +0000768 SelectObject( hdc, GetStockObject(DEFAULT_BITMAP) );
Alexandre Julliard658cdb42001-08-15 23:33:20 +0000769 funcs = dc->funcs;
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000770 if (dc->funcs->pDeleteDC) dc->funcs->pDeleteDC(dc);
Alexandre Julliard401710d1993-09-04 10:09:32 +0000771 }
Alexandre Julliardaca05781994-10-17 18:12:41 +0000772
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000773 if (dc->hClipRgn) DeleteObject( dc->hClipRgn );
774 if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
775 if (dc->hGCClipRgn) DeleteObject( dc->hGCClipRgn );
776 if (dc->pAbortProc) THUNK_Free( (FARPROC)dc->pAbortProc );
Ulrich Weigandf86aab81999-09-20 18:47:14 +0000777 if (dc->hookThunk) THUNK_Free( (FARPROC)dc->hookThunk );
Huw D M Davies814654e2001-09-12 20:21:06 +0000778 if (dc->gdiFont) WineEngDecRefFont( dc->gdiFont );
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000779 PATH_DestroyGdiPath(&dc->path);
Alexandre Julliard3dd63eb2001-07-27 19:37:31 +0000780
Alexandre Julliard658cdb42001-08-15 23:33:20 +0000781 GDI_FreeObject( hdc, dc );
782 if (funcs) DRIVER_release_driver( funcs ); /* do that after releasing the GDI lock */
783 return TRUE;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000784}
785
786
787/***********************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +0000788 * ResetDC (GDI.376)
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000789 */
Huw D M Daviese39b6761999-05-17 16:20:51 +0000790HDC16 WINAPI ResetDC16( HDC16 hdc, const DEVMODEA *devmode )
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000791{
Alexandre Julliard15657091999-05-23 10:25:25 +0000792 FIXME("stub\n" );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000793 return hdc;
794}
795
796
797/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000798 * ResetDCA (GDI32.@)
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000799 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000800HDC WINAPI ResetDCA( HDC hdc, const DEVMODEA *devmode )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000801{
Alexandre Julliard15657091999-05-23 10:25:25 +0000802 FIXME("stub\n" );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000803 return hdc;
804}
805
806
807/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000808 * ResetDCW (GDI32.@)
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000809 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000810HDC WINAPI ResetDCW( HDC hdc, const DEVMODEW *devmode )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000811{
Alexandre Julliard15657091999-05-23 10:25:25 +0000812 FIXME("stub\n" );
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000813 return hdc;
814}
815
816
817/***********************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +0000818 * GetDeviceCaps (GDI.80)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000819 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000820INT16 WINAPI GetDeviceCaps16( HDC16 hdc, INT16 cap )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000821{
Gerard Patelfeb87372000-09-07 18:37:52 +0000822 INT16 ret = GetDeviceCaps( hdc, cap );
823 /* some apps don't expect -1 and think it's a B&W screen */
824 if ((cap == NUMCOLORS) && (ret == -1)) ret = 2048;
825 return ret;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000826}
827
828
829/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000830 * GetDeviceCaps (GDI32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000831 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000832INT WINAPI GetDeviceCaps( HDC hdc, INT cap )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000833{
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000834 DC *dc;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000835 INT ret = 0;
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000836
Alexandre Julliard99bb9f92001-07-28 00:18:02 +0000837 if ((dc = DC_GetDCPtr( hdc )))
Huw D M Daviese39b6761999-05-17 16:20:51 +0000838 {
Alexandre Julliard99bb9f92001-07-28 00:18:02 +0000839 if (dc->funcs->pGetDeviceCaps) ret = dc->funcs->pGetDeviceCaps( dc, cap );
840 GDI_ReleaseObj( hdc );
Huw D M Daviese39b6761999-05-17 16:20:51 +0000841 }
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000842 return ret;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000843}
844
845
846/***********************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +0000847 * SetBkColor (GDI.1)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000848 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000849COLORREF WINAPI SetBkColor16( HDC16 hdc, COLORREF color )
Alexandre Julliard21979011997-03-05 08:22:35 +0000850{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000851 return SetBkColor( hdc, color );
Alexandre Julliard21979011997-03-05 08:22:35 +0000852}
853
854
855/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000856 * SetBkColor (GDI32.@)
Alexandre Julliard21979011997-03-05 08:22:35 +0000857 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000858COLORREF WINAPI SetBkColor( HDC hdc, COLORREF color )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000859{
860 COLORREF oldColor;
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000861 DC * dc = DC_GetDCPtr( hdc );
862
863 if (!dc) return 0x80000000;
864 if (dc->funcs->pSetBkColor)
865 oldColor = dc->funcs->pSetBkColor(dc, color);
866 else {
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000867 oldColor = dc->backgroundColor;
868 dc->backgroundColor = color;
Alexandre Julliard73450d61994-05-18 18:29:32 +0000869 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000870 GDI_ReleaseObj( hdc );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000871 return oldColor;
872}
873
874
875/***********************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +0000876 * SetTextColor (GDI.9)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000877 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000878COLORREF WINAPI SetTextColor16( HDC16 hdc, COLORREF color )
Alexandre Julliard21979011997-03-05 08:22:35 +0000879{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000880 return SetTextColor( hdc, color );
Alexandre Julliard21979011997-03-05 08:22:35 +0000881}
882
883
884/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000885 * SetTextColor (GDI32.@)
Alexandre Julliard21979011997-03-05 08:22:35 +0000886 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000887COLORREF WINAPI SetTextColor( HDC hdc, COLORREF color )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000888{
889 COLORREF oldColor;
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000890 DC * dc = DC_GetDCPtr( hdc );
891
892 if (!dc) return 0x80000000;
893 if (dc->funcs->pSetTextColor)
894 oldColor = dc->funcs->pSetTextColor(dc, color);
895 else {
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000896 oldColor = dc->textColor;
897 dc->textColor = color;
Alexandre Julliard73450d61994-05-18 18:29:32 +0000898 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000899 GDI_ReleaseObj( hdc );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000900 return oldColor;
901}
902
Alexandre Julliard401710d1993-09-04 10:09:32 +0000903/***********************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +0000904 * SetTextAlign (GDI.346)
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000905 */
Huw D M Davies7603dea1999-04-25 09:24:23 +0000906UINT16 WINAPI SetTextAlign16( HDC16 hdc, UINT16 align )
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000907{
Huw D M Davies7603dea1999-04-25 09:24:23 +0000908 return SetTextAlign( hdc, align );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000909}
910
911
912/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000913 * SetTextAlign (GDI32.@)
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000914 */
Huw D M Davies7603dea1999-04-25 09:24:23 +0000915UINT WINAPI SetTextAlign( HDC hdc, UINT align )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000916{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000917 UINT prevAlign;
Huw D M Davies7603dea1999-04-25 09:24:23 +0000918 DC *dc = DC_GetDCPtr( hdc );
919 if (!dc) return 0x0;
920 if (dc->funcs->pSetTextAlign)
921 prevAlign = dc->funcs->pSetTextAlign(dc, align);
922 else {
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000923 prevAlign = dc->textAlign;
924 dc->textAlign = align;
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000925 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000926 GDI_ReleaseObj( hdc );
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000927 return prevAlign;
928}
929
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000930/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000931 * GetDCOrgEx (GDI32.@)
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000932 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000933BOOL WINAPI GetDCOrgEx( HDC hDC, LPPOINT lpp )
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000934{
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000935 DC * dc;
Huw D M Davies9c68faa1998-11-25 12:36:03 +0000936
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000937 if (!lpp) return FALSE;
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000938 if (!(dc = DC_GetDCPtr( hDC ))) return FALSE;
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000939
Alexandre Julliard07e42132000-03-19 21:19:21 +0000940 lpp->x = lpp->y = 0;
941 if (dc->funcs->pGetDCOrgEx) dc->funcs->pGetDCOrgEx( dc, lpp );
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000942 lpp->x += dc->DCOrgX;
943 lpp->y += dc->DCOrgY;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000944 GDI_ReleaseObj( hDC );
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000945 return TRUE;
946}
947
948
949/***********************************************************************
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000950 * GetDCOrg (GDI.79)
951 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000952DWORD WINAPI GetDCOrg16( HDC16 hdc )
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000953{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000954 POINT pt;
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000955 if( GetDCOrgEx( hdc, &pt) )
956 return MAKELONG( (WORD)pt.x, (WORD)pt.y );
957 return 0;
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000958}
959
960
961/***********************************************************************
Alexandre Julliard401710d1993-09-04 10:09:32 +0000962 * SetDCOrg (GDI.117)
963 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000964DWORD WINAPI SetDCOrg16( HDC16 hdc, INT16 x, INT16 y )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000965{
966 DWORD prevOrg;
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000967 DC *dc = DC_GetDCPtr( hdc );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000968 if (!dc) return 0;
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000969 prevOrg = dc->DCOrgX | (dc->DCOrgY << 16);
970 dc->DCOrgX = x;
971 dc->DCOrgY = y;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000972 GDI_ReleaseObj( hdc );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000973 return prevOrg;
974}
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000975
976
977/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000978 * SetGraphicsMode (GDI32.@)
Alexandre Julliard17216f51997-10-12 16:30:17 +0000979 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000980INT WINAPI SetGraphicsMode( HDC hdc, INT mode )
Alexandre Julliard17216f51997-10-12 16:30:17 +0000981{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000982 INT ret = 0;
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000983 DC *dc = DC_GetDCPtr( hdc );
Alexandre Julliard60ce85c1998-02-01 18:33:27 +0000984
985 /* One would think that setting the graphics mode to GM_COMPATIBLE
986 * would also reset the world transformation matrix to the unity
987 * matrix. However, in Windows, this is not the case. This doesn't
988 * make a lot of sense to me, but that's the way it is.
989 */
Alexandre Julliard17216f51997-10-12 16:30:17 +0000990 if (!dc) return 0;
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000991 if ((mode > 0) || (mode <= GM_LAST))
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000992 {
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000993 ret = dc->GraphicsMode;
994 dc->GraphicsMode = mode;
995 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000996 GDI_ReleaseObj( hdc );
Alexandre Julliard17216f51997-10-12 16:30:17 +0000997 return ret;
998}
999
1000
1001/***********************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +00001002 * SetArcDirection (GDI.525)
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001003 */
1004INT16 WINAPI SetArcDirection16( HDC16 hdc, INT16 nDirection )
1005{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001006 return SetArcDirection( (HDC)hdc, (INT)nDirection );
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001007}
1008
1009
1010/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001011 * SetArcDirection (GDI32.@)
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001012 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001013INT WINAPI SetArcDirection( HDC hdc, INT nDirection )
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001014{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001015 DC * dc;
1016 INT nOldDirection = 0;
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001017
1018 if (nDirection!=AD_COUNTERCLOCKWISE && nDirection!=AD_CLOCKWISE)
1019 {
1020 SetLastError(ERROR_INVALID_PARAMETER);
1021 return 0;
1022 }
1023
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001024 if ((dc = DC_GetDCPtr( hdc )))
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001025 {
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001026 nOldDirection = dc->ArcDirection;
1027 dc->ArcDirection = nDirection;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001028 GDI_ReleaseObj( hdc );
1029 }
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001030 return nOldDirection;
1031}
1032
1033
1034/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001035 * GetWorldTransform (GDI32.@)
Alexandre Julliard17216f51997-10-12 16:30:17 +00001036 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001037BOOL WINAPI GetWorldTransform( HDC hdc, LPXFORM xform )
Alexandre Julliard17216f51997-10-12 16:30:17 +00001038{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001039 DC * dc;
1040 if (!xform) return FALSE;
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001041 if (!(dc = DC_GetDCPtr( hdc ))) return FALSE;
1042 *xform = dc->xformWorld2Wnd;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001043 GDI_ReleaseObj( hdc );
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001044 return TRUE;
1045}
1046
1047
1048/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001049 * SetWorldTransform (GDI32.@)
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001050 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001051BOOL WINAPI SetWorldTransform( HDC hdc, const XFORM *xform )
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001052{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001053 BOOL ret = FALSE;
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001054 DC *dc = DC_GetDCPtr( hdc );
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001055
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001056 if (!dc) return FALSE;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001057 if (!xform) goto done;
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001058
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001059 /* Check that graphics mode is GM_ADVANCED */
1060 if (dc->GraphicsMode!=GM_ADVANCED) goto done;
1061
1062 dc->xformWorld2Wnd = *xform;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001063 DC_UpdateXforms( dc );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001064 ret = TRUE;
1065 done:
1066 GDI_ReleaseObj( hdc );
1067 return ret;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001068}
1069
1070
1071/****************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001072 * ModifyWorldTransform [GDI32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001073 * Modifies the world transformation for a device context.
1074 *
1075 * PARAMS
1076 * hdc [I] Handle to device context
1077 * xform [I] XFORM structure that will be used to modify the world
1078 * transformation
1079 * iMode [I] Specifies in what way to modify the world transformation
1080 * Possible values:
1081 * MWT_IDENTITY
1082 * Resets the world transformation to the identity matrix.
1083 * The parameter xform is ignored.
1084 * MWT_LEFTMULTIPLY
1085 * Multiplies xform into the world transformation matrix from
1086 * the left.
1087 * MWT_RIGHTMULTIPLY
1088 * Multiplies xform into the world transformation matrix from
1089 * the right.
1090 *
1091 * RETURNS STD
1092 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001093BOOL WINAPI ModifyWorldTransform( HDC hdc, const XFORM *xform,
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001094 DWORD iMode )
1095{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001096 BOOL ret = FALSE;
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001097 DC *dc = DC_GetDCPtr( hdc );
1098
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001099 /* Check for illegal parameters */
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001100 if (!dc) return FALSE;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001101 if (!xform) goto done;
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001102
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001103 /* Check that graphics mode is GM_ADVANCED */
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001104 if (dc->GraphicsMode!=GM_ADVANCED) goto done;
1105
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001106 switch (iMode)
1107 {
1108 case MWT_IDENTITY:
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001109 dc->xformWorld2Wnd.eM11 = 1.0f;
1110 dc->xformWorld2Wnd.eM12 = 0.0f;
1111 dc->xformWorld2Wnd.eM21 = 0.0f;
1112 dc->xformWorld2Wnd.eM22 = 1.0f;
1113 dc->xformWorld2Wnd.eDx = 0.0f;
1114 dc->xformWorld2Wnd.eDy = 0.0f;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001115 break;
1116 case MWT_LEFTMULTIPLY:
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001117 CombineTransform( &dc->xformWorld2Wnd, xform,
1118 &dc->xformWorld2Wnd );
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001119 break;
1120 case MWT_RIGHTMULTIPLY:
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001121 CombineTransform( &dc->xformWorld2Wnd, &dc->xformWorld2Wnd,
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001122 xform );
1123 break;
1124 default:
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001125 goto done;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001126 }
1127
1128 DC_UpdateXforms( dc );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001129 ret = TRUE;
1130 done:
1131 GDI_ReleaseObj( hdc );
1132 return ret;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001133}
1134
1135
1136/****************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001137 * CombineTransform [GDI32.@]
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001138 * Combines two transformation matrices.
1139 *
1140 * PARAMS
1141 * xformResult [O] Stores the result of combining the two matrices
1142 * xform1 [I] Specifies the first matrix to apply
1143 * xform2 [I] Specifies the second matrix to apply
1144 *
1145 * REMARKS
1146 * The same matrix can be passed in for more than one of the parameters.
1147 *
1148 * RETURNS STD
1149 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001150BOOL WINAPI CombineTransform( LPXFORM xformResult, const XFORM *xform1,
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001151 const XFORM *xform2 )
1152{
1153 XFORM xformTemp;
1154
1155 /* Check for illegal parameters */
1156 if (!xformResult || !xform1 || !xform2)
1157 return FALSE;
1158
1159 /* Create the result in a temporary XFORM, since xformResult may be
1160 * equal to xform1 or xform2 */
1161 xformTemp.eM11 = xform1->eM11 * xform2->eM11 +
1162 xform1->eM12 * xform2->eM21;
1163 xformTemp.eM12 = xform1->eM11 * xform2->eM12 +
1164 xform1->eM12 * xform2->eM22;
1165 xformTemp.eM21 = xform1->eM21 * xform2->eM11 +
1166 xform1->eM22 * xform2->eM21;
1167 xformTemp.eM22 = xform1->eM21 * xform2->eM12 +
1168 xform1->eM22 * xform2->eM22;
1169 xformTemp.eDx = xform1->eDx * xform2->eM11 +
1170 xform1->eDy * xform2->eM21 +
1171 xform2->eDx;
1172 xformTemp.eDy = xform1->eDx * xform2->eM12 +
1173 xform1->eDy * xform2->eM22 +
1174 xform2->eDy;
1175
1176 /* Copy the result to xformResult */
1177 *xformResult = xformTemp;
1178
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001179 return TRUE;
Alexandre Julliard17216f51997-10-12 16:30:17 +00001180}
1181
1182
1183/***********************************************************************
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001184 * SetDCHook (GDI.190)
1185 */
Patrik Stridvall2b3aa612000-12-01 23:58:28 +00001186
Ulrich Weigandf86aab81999-09-20 18:47:14 +00001187/* ### start build ### */
1188extern WORD CALLBACK GDI_CallTo16_word_wwll(FARPROC16,WORD,WORD,LONG,LONG);
1189/* ### stop build ### */
Patrik Stridvall2b3aa612000-12-01 23:58:28 +00001190
1191/**********************************************************************/
1192
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001193BOOL16 WINAPI SetDCHook( HDC16 hdc, FARPROC16 hookProc, DWORD dwHookData )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001194{
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001195 DC *dc = DC_GetDCPtr( hdc );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001196 if (!dc) return FALSE;
Ulrich Weigandf86aab81999-09-20 18:47:14 +00001197
1198 /*
1199 * Note: We store the original SEGPTR 'hookProc' as we need to be
1200 * able to return it verbatim in GetDCHook,
1201 *
1202 * On the other hand, we still call THUNK_Alloc and store the
1203 * 32-bit thunk into another DC member, because THUNK_Alloc
1204 * recognizes the (typical) case that the 'hookProc' is indeed
1205 * the 16-bit API entry point of a built-in routine (e.g. DCHook16)
1206 *
1207 * We could perform that test every time the hook is about to
1208 * be called (or else we could live with the 32->16->32 detour),
1209 * but this way is the most efficient ...
1210 */
1211
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001212 dc->hookProc = hookProc;
1213 dc->dwHookData = dwHookData;
Ulrich Weigandf86aab81999-09-20 18:47:14 +00001214
1215 THUNK_Free( (FARPROC)dc->hookThunk );
1216 dc->hookThunk = (DCHOOKPROC)
1217 THUNK_Alloc( hookProc, (RELAY)GDI_CallTo16_word_wwll );
1218
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001219 GDI_ReleaseObj( hdc );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001220 return TRUE;
1221}
1222
1223
1224/***********************************************************************
1225 * GetDCHook (GDI.191)
1226 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001227DWORD WINAPI GetDCHook( HDC16 hdc, FARPROC16 *phookProc )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001228{
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001229 DC *dc = DC_GetDCPtr( hdc );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001230 if (!dc) return 0;
1231 *phookProc = dc->hookProc;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001232 GDI_ReleaseObj( hdc );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001233 return dc->dwHookData;
1234}
1235
1236
1237/***********************************************************************
1238 * SetHookFlags (GDI.192)
1239 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001240WORD WINAPI SetHookFlags16(HDC16 hDC, WORD flags)
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001241{
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001242 DC *dc = DC_GetDCPtr( hDC );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001243
Alexandre Julliard491502b1997-11-01 19:08:16 +00001244 if( dc )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001245 {
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001246 WORD wRet = dc->flags & DC_DIRTY;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001247
Alexandre Julliard491502b1997-11-01 19:08:16 +00001248 /* "Undocumented Windows" info is slightly confusing.
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001249 */
1250
Alexandre Julliard15657091999-05-23 10:25:25 +00001251 TRACE("hDC %04x, flags %04x\n",hDC,flags);
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001252
1253 if( flags & DCHF_INVALIDATEVISRGN )
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001254 dc->flags |= DC_DIRTY;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001255 else if( flags & DCHF_VALIDATEVISRGN || !flags )
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001256 dc->flags &= ~DC_DIRTY;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001257 GDI_ReleaseObj( hDC );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001258 return wRet;
1259 }
Alexandre Julliard491502b1997-11-01 19:08:16 +00001260 return 0;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001261}
1262
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00001263/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001264 * SetICMMode (GDI32.@)
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00001265 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001266INT WINAPI SetICMMode(HDC hdc, INT iEnableICM)
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00001267{
1268/*FIXME Asuming that ICM is always off, and cannot be turned on */
1269 if (iEnableICM == ICM_OFF) return ICM_OFF;
1270 if (iEnableICM == ICM_ON) return 0;
1271 if (iEnableICM == ICM_QUERY) return ICM_OFF;
1272 return 0;
1273}
1274
Marcus Meissner97827ea2000-10-13 20:22:59 +00001275/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001276 * GetDeviceGammaRamp (GDI32.@)
Marcus Meissner97827ea2000-10-13 20:22:59 +00001277 */
Ove Kaaven27398d42001-03-20 01:55:18 +00001278BOOL WINAPI GetDeviceGammaRamp(HDC hDC, LPVOID ptr)
1279{
1280 BOOL ret = FALSE;
1281 DC *dc = DC_GetDCPtr( hDC );
1282
1283 if( dc )
1284 {
1285 if (dc->funcs->pGetDeviceGammaRamp)
1286 ret = dc->funcs->pGetDeviceGammaRamp(dc, ptr);
1287 GDI_ReleaseObj( hDC );
1288 }
1289 return ret;
1290}
1291
1292/***********************************************************************
1293 * SetDeviceGammaRamp (GDI32.@)
1294 */
1295BOOL WINAPI SetDeviceGammaRamp(HDC hDC, LPVOID ptr)
1296{
1297 BOOL ret = FALSE;
1298 DC *dc = DC_GetDCPtr( hDC );
1299
1300 if( dc )
1301 {
1302 if (dc->funcs->pSetDeviceGammaRamp)
1303 ret = dc->funcs->pSetDeviceGammaRamp(dc, ptr);
1304 GDI_ReleaseObj( hDC );
1305 }
1306 return ret;
Marcus Meissner97827ea2000-10-13 20:22:59 +00001307}
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00001308
1309/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001310 * GetColorSpace (GDI32.@)
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00001311 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001312HCOLORSPACE WINAPI GetColorSpace(HDC hdc)
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00001313{
1314/*FIXME Need to to whatever GetColorSpace actually does */
1315 return 0;
1316}
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001317
1318/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001319 * CreateColorSpaceA (GDI32.@)
Gerard Patel82f37be2000-01-15 22:11:21 +00001320 */
1321HCOLORSPACE WINAPI CreateColorSpaceA( LPLOGCOLORSPACEA lpLogColorSpace )
1322{
1323 FIXME( "stub\n" );
1324 return 0;
1325}
1326
1327/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001328 * CreateColorSpaceW (GDI32.@)
Gerard Patel82f37be2000-01-15 22:11:21 +00001329 */
1330HCOLORSPACE WINAPI CreateColorSpaceW( LPLOGCOLORSPACEW lpLogColorSpace )
1331{
1332 FIXME( "stub\n" );
1333 return 0;
1334}
1335
1336/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001337 * DeleteColorSpace (GDI32.@)
Gerard Patel82f37be2000-01-15 22:11:21 +00001338 */
1339BOOL WINAPI DeleteColorSpace( HCOLORSPACE hColorSpace )
1340{
1341 FIXME( "stub\n" );
1342
Alexandre Julliard07e42132000-03-19 21:19:21 +00001343 return TRUE;
Gerard Patel82f37be2000-01-15 22:11:21 +00001344}
1345
1346/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001347 * SetColorSpace (GDI32.@)
Gerard Patel82f37be2000-01-15 22:11:21 +00001348 */
1349HCOLORSPACE WINAPI SetColorSpace( HDC hDC, HCOLORSPACE hColorSpace )
1350{
1351 FIXME( "stub\n" );
1352
1353 return hColorSpace;
1354}
1355
1356/***********************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +00001357 * GetBoundsRect (GDI.194)
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001358 */
1359UINT16 WINAPI GetBoundsRect16(HDC16 hdc, LPRECT16 rect, UINT16 flags)
1360{
Ulrich Weigande62cbca1998-11-26 15:06:47 +00001361 return DCB_RESET | DCB_DISABLE; /* bounding rectangle always empty and disabled*/
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001362}
1363
Ulrich Weigandd4663661998-10-11 18:47:02 +00001364/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001365 * GetBoundsRect (GDI32.@)
Paul Quinn1beaae51998-12-15 15:38:36 +00001366 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001367UINT WINAPI GetBoundsRect(HDC hdc, LPRECT rect, UINT flags)
Paul Quinn1beaae51998-12-15 15:38:36 +00001368{
Alexandre Julliard15657091999-05-23 10:25:25 +00001369 FIXME("(): stub\n");
Paul Quinn1beaae51998-12-15 15:38:36 +00001370 return DCB_RESET; /* bounding rectangle always empty */
1371}
1372
1373/***********************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +00001374 * SetBoundsRect (GDI.193)
Ulrich Weigandd4663661998-10-11 18:47:02 +00001375 */
François Gouget241c7301998-10-28 10:47:09 +00001376UINT16 WINAPI SetBoundsRect16(HDC16 hdc, const RECT16* rect, UINT16 flags)
Ulrich Weigandd4663661998-10-11 18:47:02 +00001377{
Ulrich Weigande62cbca1998-11-26 15:06:47 +00001378 if ( (flags & DCB_ACCUMULATE) || (flags & DCB_ENABLE) )
Alexandre Julliard15657091999-05-23 10:25:25 +00001379 FIXME("(%04x, %p, %04x): stub\n", hdc, rect, flags );
Ulrich Weigande62cbca1998-11-26 15:06:47 +00001380
1381 return DCB_RESET | DCB_DISABLE; /* bounding rectangle always empty and disabled*/
Ulrich Weigandd4663661998-10-11 18:47:02 +00001382}
1383
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001384/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001385 * SetBoundsRect (GDI32.@)
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001386 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001387UINT WINAPI SetBoundsRect(HDC hdc, const RECT* rect, UINT flags)
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001388{
Alexandre Julliard15657091999-05-23 10:25:25 +00001389 FIXME("(): stub\n");
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001390 return DCB_DISABLE; /* bounding rectangle always empty */
1391}
1392
Patrik Stridvalle4174d52000-05-18 00:51:52 +00001393
1394/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001395 * GetRelAbs (GDI32.@)
Patrik Stridvalle4174d52000-05-18 00:51:52 +00001396 */
1397INT WINAPI GetRelAbs( HDC hdc, DWORD dwIgnore )
1398{
Alexandre Julliard2239abb2000-11-05 02:05:07 +00001399 INT ret = 0;
1400 DC *dc = DC_GetDCPtr( hdc );
1401 if (dc) ret = dc->relAbsMode;
1402 GDI_ReleaseObj( hdc );
1403 return ret;
Patrik Stridvalle4174d52000-05-18 00:51:52 +00001404}
1405
Alexandre Julliard8da12c41999-01-17 16:55:11 +00001406/***********************************************************************
1407 * Death (GDI.121)
1408 *
1409 * Disables GDI, switches back to text mode.
1410 * We don't have to do anything here,
1411 * just let console support handle everything
1412 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001413void WINAPI Death16(HDC16 hDC)
Alexandre Julliard8da12c41999-01-17 16:55:11 +00001414{
Alexandre Julliard15657091999-05-23 10:25:25 +00001415 MESSAGE("Death(%04x) called. Application enters text mode...\n", hDC);
Alexandre Julliard8da12c41999-01-17 16:55:11 +00001416}
1417
1418/***********************************************************************
1419 * Resurrection (GDI.122)
1420 *
1421 * Restores GDI functionality
1422 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001423void WINAPI Resurrection16(HDC16 hDC,
Alexandre Julliard8da12c41999-01-17 16:55:11 +00001424 WORD w1, WORD w2, WORD w3, WORD w4, WORD w5, WORD w6)
1425{
Alexandre Julliard15657091999-05-23 10:25:25 +00001426 MESSAGE("Resurrection(%04x, %04x, %04x, %04x, %04x, %04x, %04x) called. Application left text mode.\n", hDC, w1, w2, w3, w4, w5, w6);
Alexandre Julliard8da12c41999-01-17 16:55:11 +00001427}
Huw D M Daviesf64e0d71999-11-21 00:49:50 +00001428
1429/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001430 * GetLayout (GDI32.@)
Huw D M Daviesf64e0d71999-11-21 00:49:50 +00001431 *
1432 * Gets left->right or right->left text layout flags of a dc.
1433 * win98 just returns 0 and sets ERROR_CALL_NOT_IMPLEMENTED so we do the same
1434 *
1435 */
1436DWORD WINAPI GetLayout(HDC hdc)
1437{
1438 FIXME("(%08x): stub\n", hdc);
1439 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1440 return 0;
1441}
1442
1443/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +00001444 * SetLayout (GDI32.@)
Huw D M Daviesf64e0d71999-11-21 00:49:50 +00001445 *
1446 * Sets left->right or right->left text layout flags of a dc.
1447 * win98 just returns 0 and sets ERROR_CALL_NOT_IMPLEMENTED so we do the same
1448 *
1449 */
1450DWORD WINAPI SetLayout(HDC hdc, DWORD layout)
1451{
1452 FIXME("(%08x,%08lx): stub\n", hdc, layout);
1453 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1454 return 0;
1455}