blob: 4c7e7f08b7b516816c5e09aeef36622aed1e790b [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
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000010#ifndef X_DISPLAY_MISSING
Patrik Stridvall8d8703c1999-02-04 14:05:38 +000011#include "ts_xlib.h"
12#include "x11drv.h"
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000013#endif /* !defined(X_DISPLAY_MISSING) */
Patrik Stridvall8d8703c1999-02-04 14:05:38 +000014
Alexandre Julliard401710d1993-09-04 10:09:32 +000015#include <stdlib.h>
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000016#include <string.h>
Alexandre Julliarda845b881998-06-01 10:44:35 +000017#include "dc.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000018#include "gdi.h"
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +000019#include "heap.h"
Alexandre Julliard15657091999-05-23 10:25:25 +000020#include "debugtools.h"
Alexandre Julliard234bc241994-12-10 13:02:28 +000021#include "font.h"
Huw D M Davies304d9a41999-09-13 15:15:45 +000022#include "callback.h"
Alexandre Julliard60ce85c1998-02-01 18:33:27 +000023#include "winerror.h"
Patrik Stridvall8d8703c1999-02-04 14:05:38 +000024#include "wine/winuser16.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000025
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000026DEFAULT_DEBUG_CHANNEL(dc)
27
Alexandre Julliard401710d1993-09-04 10:09:32 +000028/***********************************************************************
Alexandre Julliard44ed71f1997-12-21 19:17:50 +000029 * DC_Init_DC_INFO
30 *
31 * Fill the WIN_DC_INFO structure.
32 */
33static void DC_Init_DC_INFO( WIN_DC_INFO *win_dc_info )
34{
Alexandre Julliarddadf78f1998-05-17 17:13:43 +000035 win_dc_info->flags = 0;
36 win_dc_info->devCaps = NULL;
37 win_dc_info->hClipRgn = 0;
38 win_dc_info->hVisRgn = 0;
39 win_dc_info->hGCClipRgn = 0;
40 win_dc_info->hPen = STOCK_BLACK_PEN;
41 win_dc_info->hBrush = STOCK_WHITE_BRUSH;
42 win_dc_info->hFont = STOCK_SYSTEM_FONT;
43 win_dc_info->hBitmap = 0;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +000044 win_dc_info->hDevice = 0;
45 win_dc_info->hPalette = STOCK_DEFAULT_PALETTE;
46 win_dc_info->ROPmode = R2_COPYPEN;
47 win_dc_info->polyFillMode = ALTERNATE;
48 win_dc_info->stretchBltMode = BLACKONWHITE;
49 win_dc_info->relAbsMode = ABSOLUTE;
50 win_dc_info->backgroundMode = OPAQUE;
51 win_dc_info->backgroundColor = RGB( 255, 255, 255 );
52 win_dc_info->textColor = RGB( 0, 0, 0 );
Alexandre Julliarddadf78f1998-05-17 17:13:43 +000053 win_dc_info->brushOrgX = 0;
54 win_dc_info->brushOrgY = 0;
55 win_dc_info->textAlign = TA_LEFT | TA_TOP | TA_NOUPDATECP;
56 win_dc_info->charExtra = 0;
57 win_dc_info->breakTotalExtra = 0;
58 win_dc_info->breakCount = 0;
59 win_dc_info->breakExtra = 0;
60 win_dc_info->breakRem = 0;
61 win_dc_info->bitsPerPixel = 1;
62 win_dc_info->MapMode = MM_TEXT;
63 win_dc_info->GraphicsMode = GM_COMPATIBLE;
64 win_dc_info->DCOrgX = 0;
65 win_dc_info->DCOrgY = 0;
Huw D M Davies304d9a41999-09-13 15:15:45 +000066 win_dc_info->pAbortProc = NULL;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +000067 win_dc_info->CursPosX = 0;
68 win_dc_info->CursPosY = 0;
69 win_dc_info->ArcDirection = AD_COUNTERCLOCKWISE;
70 win_dc_info->xformWorld2Wnd.eM11 = 1.0f;
71 win_dc_info->xformWorld2Wnd.eM12 = 0.0f;
72 win_dc_info->xformWorld2Wnd.eM21 = 0.0f;
73 win_dc_info->xformWorld2Wnd.eM22 = 1.0f;
74 win_dc_info->xformWorld2Wnd.eDx = 0.0f;
75 win_dc_info->xformWorld2Wnd.eDy = 0.0f;
76 win_dc_info->xformWorld2Vport = win_dc_info->xformWorld2Wnd;
77 win_dc_info->xformVport2World = win_dc_info->xformWorld2Wnd;
78 win_dc_info->vport2WorldValid = TRUE;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +000079
80 PATH_InitGdiPath(&win_dc_info->path);
81}
82
83
84/***********************************************************************
Alexandre Julliardbf9130a1996-10-13 17:45:47 +000085 * DC_AllocDC
86 */
87DC *DC_AllocDC( const DC_FUNCTIONS *funcs )
88{
89 HDC16 hdc;
90 DC *dc;
91
92 if (!(hdc = GDI_AllocObject( sizeof(DC), DC_MAGIC ))) return NULL;
Alexandre Julliard670cdc41997-08-24 16:00:30 +000093 dc = (DC *) GDI_HEAP_LOCK( hdc );
Alexandre Julliardbf9130a1996-10-13 17:45:47 +000094
95 dc->hSelf = hdc;
96 dc->funcs = funcs;
97 dc->physDev = NULL;
98 dc->saveLevel = 0;
99 dc->dwHookData = 0L;
100 dc->hookProc = NULL;
Ulrich Weigandf86aab81999-09-20 18:47:14 +0000101 dc->hookThunk = NULL;
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000102 dc->wndOrgX = 0;
103 dc->wndOrgY = 0;
104 dc->wndExtX = 1;
105 dc->wndExtY = 1;
106 dc->vportOrgX = 0;
107 dc->vportOrgY = 0;
108 dc->vportExtX = 1;
109 dc->vportExtY = 1;
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000110
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000111 DC_Init_DC_INFO( &dc->w );
112
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000113 return dc;
114}
115
116
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000117
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000118/***********************************************************************
119 * DC_GetDCPtr
120 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000121DC *DC_GetDCPtr( HDC hdc )
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000122{
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000123 GDIOBJHDR *ptr = (GDIOBJHDR *)GDI_HEAP_LOCK( hdc );
Alexandre Julliard9ea19e51997-01-01 17:29:55 +0000124 if (!ptr) return NULL;
Huw D M Davies7603dea1999-04-25 09:24:23 +0000125 if ((ptr->wMagic == DC_MAGIC) || (ptr->wMagic == METAFILE_DC_MAGIC) ||
126 (ptr->wMagic == ENHMETAFILE_DC_MAGIC))
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000127 return (DC *)ptr;
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000128 GDI_HEAP_UNLOCK( hdc );
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000129 return NULL;
130}
131
132
133/***********************************************************************
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000134 * DC_InitDC
Alexandre Julliard401710d1993-09-04 10:09:32 +0000135 *
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000136 * Setup device-specific DC values for a newly created DC.
Alexandre Julliard401710d1993-09-04 10:09:32 +0000137 */
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000138void DC_InitDC( DC* dc )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000139{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000140 RealizeDefaultPalette16( dc->hSelf );
141 SetTextColor( dc->hSelf, dc->w.textColor );
142 SetBkColor( dc->hSelf, dc->w.backgroundColor );
143 SelectObject( dc->hSelf, dc->w.hPen );
144 SelectObject( dc->hSelf, dc->w.hBrush );
145 SelectObject( dc->hSelf, dc->w.hFont );
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000146 CLIPPING_UpdateGCRegion( dc );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000147}
148
149
150/***********************************************************************
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000151 * DC_InvertXform
152 *
153 * Computes the inverse of the transformation xformSrc and stores it to
154 * xformDest. Returns TRUE if successful or FALSE if the xformSrc matrix
155 * is singular.
156 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000157static BOOL DC_InvertXform( const XFORM *xformSrc, XFORM *xformDest )
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000158{
159 FLOAT determinant;
160
161 determinant = xformSrc->eM11*xformSrc->eM22 -
162 xformSrc->eM12*xformSrc->eM21;
163 if (determinant > -1e-12 && determinant < 1e-12)
164 return FALSE;
165
166 xformDest->eM11 = xformSrc->eM22 / determinant;
167 xformDest->eM12 = -xformSrc->eM12 / determinant;
168 xformDest->eM21 = -xformSrc->eM21 / determinant;
169 xformDest->eM22 = xformSrc->eM11 / determinant;
170 xformDest->eDx = -xformSrc->eDx * xformDest->eM11 -
171 xformSrc->eDy * xformDest->eM21;
172 xformDest->eDy = -xformSrc->eDx * xformDest->eM12 -
173 xformSrc->eDy * xformDest->eM22;
174
175 return TRUE;
176}
177
178
179/***********************************************************************
180 * DC_UpdateXforms
181 *
182 * Updates the xformWorld2Vport, xformVport2World and vport2WorldValid
183 * fields of the specified DC by creating a transformation that
184 * represents the current mapping mode and combining it with the DC's
185 * world transform. This function should be called whenever the
186 * parameters associated with the mapping mode (window and viewport
187 * extents and origins) or the world transform change.
188 */
189void DC_UpdateXforms( DC *dc )
190{
191 XFORM xformWnd2Vport;
192 FLOAT scaleX, scaleY;
193
194 /* Construct a transformation to do the window-to-viewport conversion */
195 scaleX = (FLOAT)dc->vportExtX / (FLOAT)dc->wndExtX;
196 scaleY = (FLOAT)dc->vportExtY / (FLOAT)dc->wndExtY;
197 xformWnd2Vport.eM11 = scaleX;
198 xformWnd2Vport.eM12 = 0.0;
199 xformWnd2Vport.eM21 = 0.0;
200 xformWnd2Vport.eM22 = scaleY;
201 xformWnd2Vport.eDx = (FLOAT)dc->vportOrgX -
202 scaleX * (FLOAT)dc->wndOrgX;
203 xformWnd2Vport.eDy = (FLOAT)dc->vportOrgY -
204 scaleY * (FLOAT)dc->wndOrgY;
205
206 /* Combine with the world transformation */
207 CombineTransform( &dc->w.xformWorld2Vport, &dc->w.xformWorld2Wnd,
208 &xformWnd2Vport );
209
210 /* Create inverse of world-to-viewport transformation */
211 dc->w.vport2WorldValid = DC_InvertXform( &dc->w.xformWorld2Vport,
212 &dc->w.xformVport2World );
213}
214
215
216/***********************************************************************
Alexandre Julliard401710d1993-09-04 10:09:32 +0000217 * GetDCState (GDI.179)
218 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000219HDC16 WINAPI GetDCState16( HDC16 hdc )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000220{
221 DC * newdc, * dc;
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000222 HGDIOBJ16 handle;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000223
224 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000225 if (!(handle = GDI_AllocObject( sizeof(DC), DC_MAGIC )))
226 {
227 GDI_HEAP_UNLOCK( hdc );
228 return 0;
229 }
230 newdc = (DC *) GDI_HEAP_LOCK( handle );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000231
Alexandre Julliard15657091999-05-23 10:25:25 +0000232 TRACE("(%04x): returning %04x\n", hdc, handle );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000233
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000234 newdc->w.flags = dc->w.flags | DC_SAVED;
235 newdc->w.devCaps = dc->w.devCaps;
236 newdc->w.hPen = dc->w.hPen;
237 newdc->w.hBrush = dc->w.hBrush;
238 newdc->w.hFont = dc->w.hFont;
239 newdc->w.hBitmap = dc->w.hBitmap;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000240 newdc->w.hDevice = dc->w.hDevice;
241 newdc->w.hPalette = dc->w.hPalette;
Ulrich Weigand27bb3621998-10-14 18:06:44 +0000242 newdc->w.totalExtent = dc->w.totalExtent;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000243 newdc->w.bitsPerPixel = dc->w.bitsPerPixel;
244 newdc->w.ROPmode = dc->w.ROPmode;
245 newdc->w.polyFillMode = dc->w.polyFillMode;
246 newdc->w.stretchBltMode = dc->w.stretchBltMode;
247 newdc->w.relAbsMode = dc->w.relAbsMode;
248 newdc->w.backgroundMode = dc->w.backgroundMode;
249 newdc->w.backgroundColor = dc->w.backgroundColor;
250 newdc->w.textColor = dc->w.textColor;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000251 newdc->w.brushOrgX = dc->w.brushOrgX;
252 newdc->w.brushOrgY = dc->w.brushOrgY;
253 newdc->w.textAlign = dc->w.textAlign;
254 newdc->w.charExtra = dc->w.charExtra;
255 newdc->w.breakTotalExtra = dc->w.breakTotalExtra;
256 newdc->w.breakCount = dc->w.breakCount;
257 newdc->w.breakExtra = dc->w.breakExtra;
258 newdc->w.breakRem = dc->w.breakRem;
259 newdc->w.MapMode = dc->w.MapMode;
260 newdc->w.GraphicsMode = dc->w.GraphicsMode;
Ulrich Weigandd4663661998-10-11 18:47:02 +0000261#if 0
262 /* Apparently, the DC origin is not changed by [GS]etDCState */
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000263 newdc->w.DCOrgX = dc->w.DCOrgX;
264 newdc->w.DCOrgY = dc->w.DCOrgY;
Ulrich Weigandd4663661998-10-11 18:47:02 +0000265#endif
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000266 newdc->w.CursPosX = dc->w.CursPosX;
267 newdc->w.CursPosY = dc->w.CursPosY;
268 newdc->w.ArcDirection = dc->w.ArcDirection;
269 newdc->w.xformWorld2Wnd = dc->w.xformWorld2Wnd;
270 newdc->w.xformWorld2Vport = dc->w.xformWorld2Vport;
271 newdc->w.xformVport2World = dc->w.xformVport2World;
272 newdc->w.vport2WorldValid = dc->w.vport2WorldValid;
273 newdc->wndOrgX = dc->wndOrgX;
274 newdc->wndOrgY = dc->wndOrgY;
275 newdc->wndExtX = dc->wndExtX;
276 newdc->wndExtY = dc->wndExtY;
277 newdc->vportOrgX = dc->vportOrgX;
278 newdc->vportOrgY = dc->vportOrgY;
279 newdc->vportExtX = dc->vportExtX;
280 newdc->vportExtY = dc->vportExtY;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000281
Alexandre Julliarda3960291999-02-26 11:11:13 +0000282 newdc->hSelf = (HDC)handle;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000283 newdc->saveLevel = 0;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000284
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000285 PATH_InitGdiPath( &newdc->w.path );
286
Huw D M Davies304d9a41999-09-13 15:15:45 +0000287 newdc->w.pAbortProc = NULL;
288
Alexandre Julliard491502b1997-11-01 19:08:16 +0000289 /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
290
291 newdc->w.hGCClipRgn = newdc->w.hVisRgn = 0;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000292 if (dc->w.hClipRgn)
293 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000294 newdc->w.hClipRgn = CreateRectRgn( 0, 0, 0, 0 );
295 CombineRgn( newdc->w.hClipRgn, dc->w.hClipRgn, 0, RGN_COPY );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000296 }
Alexandre Julliard349a9531997-02-02 19:01:52 +0000297 else
298 newdc->w.hClipRgn = 0;
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000299 GDI_HEAP_UNLOCK( handle );
300 GDI_HEAP_UNLOCK( hdc );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000301 return handle;
302}
303
304
305/***********************************************************************
306 * SetDCState (GDI.180)
307 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000308void WINAPI SetDCState16( HDC16 hdc, HDC16 hdcs )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000309{
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000310 DC *dc, *dcs;
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000311
Alexandre Julliard401710d1993-09-04 10:09:32 +0000312 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return;
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000313 if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC )))
314 {
315 GDI_HEAP_UNLOCK( hdc );
316 return;
317 }
318 if (!dcs->w.flags & DC_SAVED)
319 {
320 GDI_HEAP_UNLOCK( hdc );
321 GDI_HEAP_UNLOCK( hdcs );
322 return;
323 }
Alexandre Julliard15657091999-05-23 10:25:25 +0000324 TRACE("%04x %04x\n", hdc, hdcs );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000325
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000326 dc->w.flags = dcs->w.flags & ~DC_SAVED;
327 dc->w.devCaps = dcs->w.devCaps;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000328 dc->w.hDevice = dcs->w.hDevice;
Ulrich Weigand27bb3621998-10-14 18:06:44 +0000329 dc->w.totalExtent = dcs->w.totalExtent;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000330 dc->w.ROPmode = dcs->w.ROPmode;
331 dc->w.polyFillMode = dcs->w.polyFillMode;
332 dc->w.stretchBltMode = dcs->w.stretchBltMode;
333 dc->w.relAbsMode = dcs->w.relAbsMode;
334 dc->w.backgroundMode = dcs->w.backgroundMode;
335 dc->w.backgroundColor = dcs->w.backgroundColor;
336 dc->w.textColor = dcs->w.textColor;
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000337 dc->w.brushOrgX = dcs->w.brushOrgX;
338 dc->w.brushOrgY = dcs->w.brushOrgY;
339 dc->w.textAlign = dcs->w.textAlign;
340 dc->w.charExtra = dcs->w.charExtra;
341 dc->w.breakTotalExtra = dcs->w.breakTotalExtra;
342 dc->w.breakCount = dcs->w.breakCount;
343 dc->w.breakExtra = dcs->w.breakExtra;
344 dc->w.breakRem = dcs->w.breakRem;
345 dc->w.MapMode = dcs->w.MapMode;
346 dc->w.GraphicsMode = dcs->w.GraphicsMode;
Ulrich Weigandd4663661998-10-11 18:47:02 +0000347#if 0
348 /* Apparently, the DC origin is not changed by [GS]etDCState */
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000349 dc->w.DCOrgX = dcs->w.DCOrgX;
350 dc->w.DCOrgY = dcs->w.DCOrgY;
Ulrich Weigandd4663661998-10-11 18:47:02 +0000351#endif
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000352 dc->w.CursPosX = dcs->w.CursPosX;
353 dc->w.CursPosY = dcs->w.CursPosY;
354 dc->w.ArcDirection = dcs->w.ArcDirection;
355 dc->w.xformWorld2Wnd = dcs->w.xformWorld2Wnd;
356 dc->w.xformWorld2Vport = dcs->w.xformWorld2Vport;
357 dc->w.xformVport2World = dcs->w.xformVport2World;
358 dc->w.vport2WorldValid = dcs->w.vport2WorldValid;
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000359
Alexandre Julliarddadf78f1998-05-17 17:13:43 +0000360 dc->wndOrgX = dcs->wndOrgX;
361 dc->wndOrgY = dcs->wndOrgY;
362 dc->wndExtX = dcs->wndExtX;
363 dc->wndExtY = dcs->wndExtY;
364 dc->vportOrgX = dcs->vportOrgX;
365 dc->vportOrgY = dcs->vportOrgY;
366 dc->vportExtX = dcs->vportExtX;
367 dc->vportExtY = dcs->vportExtY;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000368
Alexandre Julliard139a4b11996-11-02 14:24:07 +0000369 if (!(dc->w.flags & DC_MEMORY)) dc->w.bitsPerPixel = dcs->w.bitsPerPixel;
Ulrich Weigandd4663661998-10-11 18:47:02 +0000370
371 if (dcs->w.hClipRgn)
372 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000373 if (!dc->w.hClipRgn) dc->w.hClipRgn = CreateRectRgn( 0, 0, 0, 0 );
374 CombineRgn( dc->w.hClipRgn, dcs->w.hClipRgn, 0, RGN_COPY );
Ulrich Weigandd4663661998-10-11 18:47:02 +0000375 }
376 else
Ulrich Weigand7119a6e1998-11-01 14:05:33 +0000377 {
378 if (dc->w.hClipRgn) DeleteObject16( dc->w.hClipRgn );
Ulrich Weigandd4663661998-10-11 18:47:02 +0000379 dc->w.hClipRgn = 0;
Ulrich Weigand7119a6e1998-11-01 14:05:33 +0000380 }
381 CLIPPING_UpdateGCRegion( dc );
Alexandre Julliard491502b1997-11-01 19:08:16 +0000382
Alexandre Julliarda3960291999-02-26 11:11:13 +0000383 SelectObject( hdc, dcs->w.hBitmap );
384 SelectObject( hdc, dcs->w.hBrush );
385 SelectObject( hdc, dcs->w.hFont );
386 SelectObject( hdc, dcs->w.hPen );
387 SetBkColor( hdc, dcs->w.backgroundColor);
388 SetTextColor( hdc, dcs->w.textColor);
389 GDISelectPalette16( hdc, dcs->w.hPalette, FALSE );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000390 GDI_HEAP_UNLOCK( hdc );
391 GDI_HEAP_UNLOCK( hdcs );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000392}
393
394
395/***********************************************************************
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000396 * SaveDC16 (GDI.30)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000397 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000398INT16 WINAPI SaveDC16( HDC16 hdc )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000399{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000400 return (INT16)SaveDC( hdc );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000401}
402
403
404/***********************************************************************
405 * SaveDC32 (GDI32.292)
406 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000407INT WINAPI SaveDC( HDC hdc )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000408{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000409 HDC hdcs;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000410 DC * dc, * dcs;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000411 INT ret;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000412
Huw D M Davies7603dea1999-04-25 09:24:23 +0000413 dc = DC_GetDCPtr( hdc );
414 if (!dc) return 0;
415
416 if(dc->funcs->pSaveDC)
417 return dc->funcs->pSaveDC( dc );
418
Alexandre Julliarda3960291999-02-26 11:11:13 +0000419 if (!(hdcs = GetDCState16( hdc )))
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000420 {
421 GDI_HEAP_UNLOCK( hdc );
422 return 0;
423 }
424 dcs = (DC *) GDI_HEAP_LOCK( hdcs );
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000425
426 /* Copy path. The reason why path saving / restoring is in SaveDC/
427 * RestoreDC and not in GetDCState/SetDCState is that the ...DCState
428 * functions are only in Win16 (which doesn't have paths) and that
429 * SetDCState doesn't allow us to signal an error (which can happen
430 * when copying paths).
431 */
432 if (!PATH_AssignGdiPath( &dcs->w.path, &dc->w.path ))
433 {
434 GDI_HEAP_UNLOCK( hdc );
435 GDI_HEAP_UNLOCK( hdcs );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000436 DeleteDC( hdcs );
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000437 return 0;
438 }
439
Alexandre Julliard401710d1993-09-04 10:09:32 +0000440 dcs->header.hNext = dc->header.hNext;
441 dc->header.hNext = hdcs;
Alexandre Julliard15657091999-05-23 10:25:25 +0000442 TRACE("(%04x): returning %d\n", hdc, dc->saveLevel+1 );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000443 ret = ++dc->saveLevel;
444 GDI_HEAP_UNLOCK( hdcs );
445 GDI_HEAP_UNLOCK( hdc );
446 return ret;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000447}
448
449
450/***********************************************************************
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000451 * RestoreDC16 (GDI.39)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000452 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000453BOOL16 WINAPI RestoreDC16( HDC16 hdc, INT16 level )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000454{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000455 return RestoreDC( hdc, level );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000456}
457
458
459/***********************************************************************
460 * RestoreDC32 (GDI32.290)
461 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000462BOOL WINAPI RestoreDC( HDC hdc, INT level )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000463{
464 DC * dc, * dcs;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000465 BOOL success;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000466
Alexandre Julliard15657091999-05-23 10:25:25 +0000467 TRACE("%04x %d\n", hdc, level );
Huw D M Davies7603dea1999-04-25 09:24:23 +0000468 dc = DC_GetDCPtr( hdc );
469 if(!dc) return FALSE;
470 if(dc->funcs->pRestoreDC)
471 return dc->funcs->pRestoreDC( dc, level );
472
Alexandre Julliard401710d1993-09-04 10:09:32 +0000473 if (level == -1) level = dc->saveLevel;
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000474 if ((level < 1) || (level > dc->saveLevel))
475 {
476 GDI_HEAP_UNLOCK( hdc );
477 return FALSE;
478 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000479
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000480 success=TRUE;
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000481 while (dc->saveLevel >= level)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000482 {
Alexandre Julliard530ee841996-10-23 16:59:13 +0000483 HDC16 hdcs = dc->header.hNext;
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000484 if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC )))
485 {
486 GDI_HEAP_UNLOCK( hdc );
487 return FALSE;
488 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000489 dc->header.hNext = dcs->header.hNext;
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000490 if (--dc->saveLevel < level)
491 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000492 SetDCState16( hdc, hdcs );
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000493 if (!PATH_AssignGdiPath( &dc->w.path, &dcs->w.path ))
494 /* FIXME: This might not be quite right, since we're
495 * returning FALSE but still destroying the saved DC state */
496 success=FALSE;
497 }
Alexandre Julliarda3960291999-02-26 11:11:13 +0000498 DeleteDC( hdcs );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000499 }
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000500 GDI_HEAP_UNLOCK( hdc );
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000501 return success;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000502}
503
504
505/***********************************************************************
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000506 * CreateDC16 (GDI.53)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000507 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000508HDC16 WINAPI CreateDC16( LPCSTR driver, LPCSTR device, LPCSTR output,
Huw D M Daviese39b6761999-05-17 16:20:51 +0000509 const DEVMODEA *initData )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000510{
511 DC * dc;
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000512 const DC_FUNCTIONS *funcs;
Huw D M Daviese39b6761999-05-17 16:20:51 +0000513 char buf[300];
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000514
Huw D M Daviese39b6761999-05-17 16:20:51 +0000515 if (device) {
516 if(!DRIVER_GetDriverName( device, buf, sizeof(buf) )) return 0;
517 } else
518 strcpy(buf, driver);
519
520 if (!(funcs = DRIVER_FindDriver( buf ))) return 0;
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000521 if (!(dc = DC_AllocDC( funcs ))) return 0;
522 dc->w.flags = 0;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000523
Alexandre Julliard15657091999-05-23 10:25:25 +0000524 TRACE("(driver=%s, device=%s, output=%s): returning %04x\n",
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000525 debugstr_a(driver), debugstr_a(device), debugstr_a(output), dc->hSelf );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000526
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000527 if (dc->funcs->pCreateDC &&
Huw D M Davies304d9a41999-09-13 15:15:45 +0000528 !dc->funcs->pCreateDC( dc, buf, device, output, initData ))
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000529 {
Alexandre Julliard15657091999-05-23 10:25:25 +0000530 WARN("creation aborted by device\n" );
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000531 GDI_HEAP_FREE( dc->hSelf );
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000532 return 0;
533 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000534
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000535 DC_InitDC( dc );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000536 GDI_HEAP_UNLOCK( dc->hSelf );
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000537 return dc->hSelf;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000538}
539
540
541/***********************************************************************
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000542 * CreateDC32A (GDI32.)
543 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000544HDC WINAPI CreateDCA( LPCSTR driver, LPCSTR device, LPCSTR output,
545 const DEVMODEA *initData )
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000546{
Huw D M Daviese39b6761999-05-17 16:20:51 +0000547 return CreateDC16( driver, device, output, (const DEVMODEA *)initData );
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000548}
549
550
551/***********************************************************************
552 * CreateDC32W (GDI32.)
553 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000554HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
555 const DEVMODEW *initData )
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000556{
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000557 LPSTR driverA = HEAP_strdupWtoA( GetProcessHeap(), 0, driver );
558 LPSTR deviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, device );
559 LPSTR outputA = HEAP_strdupWtoA( GetProcessHeap(), 0, output );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000560 HDC res = CreateDC16( driverA, deviceA, outputA,
Huw D M Daviese39b6761999-05-17 16:20:51 +0000561 (const DEVMODEA *)initData /*FIXME*/ );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000562 HeapFree( GetProcessHeap(), 0, driverA );
563 HeapFree( GetProcessHeap(), 0, deviceA );
564 HeapFree( GetProcessHeap(), 0, outputA );
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000565 return res;
566}
567
568
569/***********************************************************************
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000570 * CreateIC16 (GDI.153)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000571 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000572HDC16 WINAPI CreateIC16( LPCSTR driver, LPCSTR device, LPCSTR output,
Huw D M Daviese39b6761999-05-17 16:20:51 +0000573 const DEVMODEA* initData )
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000574{
575 /* Nothing special yet for ICs */
Alexandre Julliardb1bac321996-12-15 19:45:59 +0000576 return CreateDC16( driver, device, output, initData );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000577}
578
579
580/***********************************************************************
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000581 * CreateIC32A (GDI32.49)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000582 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000583HDC WINAPI CreateICA( LPCSTR driver, LPCSTR device, LPCSTR output,
584 const DEVMODEA* initData )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000585{
586 /* Nothing special yet for ICs */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000587 return CreateDCA( driver, device, output, initData );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000588}
589
590
591/***********************************************************************
592 * CreateIC32W (GDI32.50)
593 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000594HDC WINAPI CreateICW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
595 const DEVMODEW* initData )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000596{
597 /* Nothing special yet for ICs */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000598 return CreateDCW( driver, device, output, initData );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000599}
600
601
602/***********************************************************************
603 * CreateCompatibleDC16 (GDI.52)
604 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000605HDC16 WINAPI CreateCompatibleDC16( HDC16 hdc )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000606{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000607 return (HDC16)CreateCompatibleDC( hdc );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000608}
609
610
611/***********************************************************************
612 * CreateCompatibleDC32 (GDI32.31)
613 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000614HDC WINAPI CreateCompatibleDC( HDC hdc )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000615{
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000616 DC *dc, *origDC;
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000617 const DC_FUNCTIONS *funcs;
618
619 if ((origDC = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC ))) funcs = origDC->funcs;
620 else funcs = DRIVER_FindDriver( "DISPLAY" );
621 if (!funcs) return 0;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000622
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000623 if (!(dc = DC_AllocDC( funcs ))) return 0;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000624
Alexandre Julliard15657091999-05-23 10:25:25 +0000625 TRACE("(%04x): returning %04x\n",
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000626 hdc, dc->hSelf );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000627
Alexandre Julliard401710d1993-09-04 10:09:32 +0000628 dc->w.flags = DC_MEMORY;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000629 dc->w.bitsPerPixel = 1;
Gerard Pateld1795f62000-01-09 20:52:53 +0000630 dc->w.hBitmap = hPseudoStockBitmap;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000631
Noel Borthwick86b686f1999-06-05 08:52:30 +0000632 /* Copy the driver-specific physical device info into
633 * the new DC. The driver may use this read-only info
634 * while creating the compatible DC below. */
635 if (origDC)
636 dc->physDev = origDC->physDev;
637
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000638 if (dc->funcs->pCreateDC &&
639 !dc->funcs->pCreateDC( dc, NULL, NULL, NULL, NULL ))
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000640 {
Alexandre Julliard15657091999-05-23 10:25:25 +0000641 WARN("creation aborted by device\n");
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000642 GDI_HEAP_FREE( dc->hSelf );
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000643 return 0;
644 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000645
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +0000646 DC_InitDC( dc );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000647 GDI_HEAP_UNLOCK( dc->hSelf );
Alexandre Julliardbf9130a1996-10-13 17:45:47 +0000648 return dc->hSelf;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000649}
650
651
652/***********************************************************************
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000653 * DeleteDC16 (GDI.68)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000654 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000655BOOL16 WINAPI DeleteDC16( HDC16 hdc )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000656{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000657 return DeleteDC( hdc );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000658}
659
660
661/***********************************************************************
662 * DeleteDC32 (GDI32.67)
663 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000664BOOL WINAPI DeleteDC( HDC hdc )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000665{
Ulrich Weigande6ea9eb1999-05-08 09:50:52 +0000666 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000667 if (!dc) return FALSE;
668
Alexandre Julliard15657091999-05-23 10:25:25 +0000669 TRACE("%04x\n", hdc );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000670
Ulrich Weigande6ea9eb1999-05-08 09:50:52 +0000671 /* Call hook procedure to check whether is it OK to delete this DC */
Ulrich Weigandf86aab81999-09-20 18:47:14 +0000672 if ( dc->hookThunk && !(dc->w.flags & (DC_SAVED | DC_MEMORY))
673 && dc->hookThunk( hdc, DCHC_DELETEDC, dc->dwHookData, 0 ) == FALSE )
Ulrich Weigande6ea9eb1999-05-08 09:50:52 +0000674 {
675 GDI_HEAP_UNLOCK( hdc );
676 return FALSE;
677 }
678
Alexandre Julliard401710d1993-09-04 10:09:32 +0000679 while (dc->saveLevel)
680 {
681 DC * dcs;
Alexandre Julliard530ee841996-10-23 16:59:13 +0000682 HDC16 hdcs = dc->header.hNext;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000683 if (!(dcs = (DC *) GDI_GetObjPtr( hdcs, DC_MAGIC ))) break;
684 dc->header.hNext = dcs->header.hNext;
685 dc->saveLevel--;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000686 DeleteDC( hdcs );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000687 }
688
689 if (!(dc->w.flags & DC_SAVED))
690 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000691 SelectObject( hdc, STOCK_BLACK_PEN );
692 SelectObject( hdc, STOCK_WHITE_BRUSH );
693 SelectObject( hdc, STOCK_SYSTEM_FONT );
Alexandre Julliard0e270f41996-08-24 18:26:35 +0000694 if (dc->funcs->pDeleteDC) dc->funcs->pDeleteDC(dc);
Alexandre Julliard401710d1993-09-04 10:09:32 +0000695 }
Alexandre Julliardaca05781994-10-17 18:12:41 +0000696
Alexandre Julliarda3960291999-02-26 11:11:13 +0000697 if (dc->w.hClipRgn) DeleteObject( dc->w.hClipRgn );
698 if (dc->w.hVisRgn) DeleteObject( dc->w.hVisRgn );
699 if (dc->w.hGCClipRgn) DeleteObject( dc->w.hGCClipRgn );
Huw D M Davies304d9a41999-09-13 15:15:45 +0000700 if (dc->w.pAbortProc) THUNK_Free( (FARPROC)dc->w.pAbortProc );
Ulrich Weigandf86aab81999-09-20 18:47:14 +0000701 if (dc->hookThunk) THUNK_Free( (FARPROC)dc->hookThunk );
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000702 PATH_DestroyGdiPath(&dc->w.path);
703
Alexandre Julliard401710d1993-09-04 10:09:32 +0000704 return GDI_FreeObject( hdc );
705}
706
707
708/***********************************************************************
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000709 * ResetDC16 (GDI.376)
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000710 */
Huw D M Daviese39b6761999-05-17 16:20:51 +0000711HDC16 WINAPI ResetDC16( HDC16 hdc, const DEVMODEA *devmode )
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000712{
Alexandre Julliard15657091999-05-23 10:25:25 +0000713 FIXME("stub\n" );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000714 return hdc;
715}
716
717
718/***********************************************************************
719 * ResetDC32A (GDI32.287)
720 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000721HDC WINAPI ResetDCA( HDC hdc, const DEVMODEA *devmode )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000722{
Alexandre Julliard15657091999-05-23 10:25:25 +0000723 FIXME("stub\n" );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000724 return hdc;
725}
726
727
728/***********************************************************************
729 * ResetDC32W (GDI32.288)
730 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000731HDC WINAPI ResetDCW( HDC hdc, const DEVMODEW *devmode )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000732{
Alexandre Julliard15657091999-05-23 10:25:25 +0000733 FIXME("stub\n" );
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000734 return hdc;
735}
736
737
738/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000739 * GetDeviceCaps16 (GDI.80)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000740 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000741INT16 WINAPI GetDeviceCaps16( HDC16 hdc, INT16 cap )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000742{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000743 return GetDeviceCaps( hdc, cap );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000744}
745
746
747/***********************************************************************
748 * GetDeviceCaps32 (GDI32.171)
749 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000750INT WINAPI GetDeviceCaps( HDC hdc, INT cap )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000751{
752 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000753 INT ret;
Huw D M Daviese39b6761999-05-17 16:20:51 +0000754 POINT pt;
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000755
Alexandre Julliard401710d1993-09-04 10:09:32 +0000756 if (!dc) return 0;
757
Huw D M Daviese39b6761999-05-17 16:20:51 +0000758 /* Device capabilities for the printer */
759 switch (cap)
760 {
761 case PHYSICALWIDTH:
762 if(Escape(hdc, GETPHYSPAGESIZE, 0, NULL, (LPVOID)&pt) > 0)
763 return pt.x;
764 case PHYSICALHEIGHT:
765 if(Escape(hdc, GETPHYSPAGESIZE, 0, NULL, (LPVOID)&pt) > 0)
766 return pt.y;
767 case PHYSICALOFFSETX:
768 if(Escape(hdc, GETPRINTINGOFFSET, 0, NULL, (LPVOID)&pt) > 0)
769 return pt.x;
770 case PHYSICALOFFSETY:
771 if(Escape(hdc, GETPRINTINGOFFSET, 0, NULL, (LPVOID)&pt) > 0)
772 return pt.y;
773 case SCALINGFACTORX:
774 if(Escape(hdc, GETSCALINGFACTOR, 0, NULL, (LPVOID)&pt) > 0)
775 return pt.x;
776 case SCALINGFACTORY:
777 if(Escape(hdc, GETSCALINGFACTOR, 0, NULL, (LPVOID)&pt) > 0)
778 return pt.y;
779 }
780
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000781 if ((cap < 0) || (cap > sizeof(DeviceCaps)-sizeof(WORD)))
782 {
783 GDI_HEAP_UNLOCK( hdc );
784 return 0;
785 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000786
Alexandre Julliard15657091999-05-23 10:25:25 +0000787 TRACE("(%04x,%d): returning %d\n",
Alexandre Julliard401710d1993-09-04 10:09:32 +0000788 hdc, cap, *(WORD *)(((char *)dc->w.devCaps) + cap) );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000789 ret = *(WORD *)(((char *)dc->w.devCaps) + cap);
790 GDI_HEAP_UNLOCK( hdc );
791 return ret;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000792}
793
794
795/***********************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +0000796 * SetBkColor16 (GDI.1)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000797 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000798COLORREF WINAPI SetBkColor16( HDC16 hdc, COLORREF color )
Alexandre Julliard21979011997-03-05 08:22:35 +0000799{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000800 return SetBkColor( hdc, color );
Alexandre Julliard21979011997-03-05 08:22:35 +0000801}
802
803
804/***********************************************************************
805 * SetBkColor32 (GDI32.305)
806 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000807COLORREF WINAPI SetBkColor( HDC hdc, COLORREF color )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000808{
809 COLORREF oldColor;
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000810 DC * dc = DC_GetDCPtr( hdc );
811
812 if (!dc) return 0x80000000;
813 if (dc->funcs->pSetBkColor)
814 oldColor = dc->funcs->pSetBkColor(dc, color);
815 else {
816 oldColor = dc->w.backgroundColor;
817 dc->w.backgroundColor = color;
Alexandre Julliard73450d61994-05-18 18:29:32 +0000818 }
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000819 GDI_HEAP_UNLOCK( hdc );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000820 return oldColor;
821}
822
823
824/***********************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +0000825 * SetTextColor16 (GDI.9)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000826 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000827COLORREF WINAPI SetTextColor16( HDC16 hdc, COLORREF color )
Alexandre Julliard21979011997-03-05 08:22:35 +0000828{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000829 return SetTextColor( hdc, color );
Alexandre Julliard21979011997-03-05 08:22:35 +0000830}
831
832
833/***********************************************************************
834 * SetTextColor32 (GDI32.338)
835 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000836COLORREF WINAPI SetTextColor( HDC hdc, COLORREF color )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000837{
838 COLORREF oldColor;
Alexandre Julliarda0d77311998-09-13 16:32:00 +0000839 DC * dc = DC_GetDCPtr( hdc );
840
841 if (!dc) return 0x80000000;
842 if (dc->funcs->pSetTextColor)
843 oldColor = dc->funcs->pSetTextColor(dc, color);
844 else {
845 oldColor = dc->w.textColor;
846 dc->w.textColor = color;
Alexandre Julliard73450d61994-05-18 18:29:32 +0000847 }
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000848 GDI_HEAP_UNLOCK( hdc );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000849 return oldColor;
850}
851
Alexandre Julliard401710d1993-09-04 10:09:32 +0000852/***********************************************************************
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000853 * SetTextAlign16 (GDI.346)
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000854 */
Huw D M Davies7603dea1999-04-25 09:24:23 +0000855UINT16 WINAPI SetTextAlign16( HDC16 hdc, UINT16 align )
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000856{
Huw D M Davies7603dea1999-04-25 09:24:23 +0000857 return SetTextAlign( hdc, align );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000858}
859
860
861/***********************************************************************
Huw D M Davies7603dea1999-04-25 09:24:23 +0000862 * SetTextAlign (GDI32.336)
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000863 */
Huw D M Davies7603dea1999-04-25 09:24:23 +0000864UINT WINAPI SetTextAlign( HDC hdc, UINT align )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000865{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000866 UINT prevAlign;
Huw D M Davies7603dea1999-04-25 09:24:23 +0000867 DC *dc = DC_GetDCPtr( hdc );
868 if (!dc) return 0x0;
869 if (dc->funcs->pSetTextAlign)
870 prevAlign = dc->funcs->pSetTextAlign(dc, align);
871 else {
872 prevAlign = dc->w.textAlign;
873 dc->w.textAlign = align;
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000874 }
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000875 GDI_HEAP_UNLOCK( hdc );
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000876 return prevAlign;
877}
878
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000879/***********************************************************************
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000880 * GetDCOrgEx (GDI32.168)
881 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000882BOOL WINAPI GetDCOrgEx( HDC hDC, LPPOINT lpp )
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000883{
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000884 DC * dc;
Huw D M Davies9c68faa1998-11-25 12:36:03 +0000885
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000886 if (!lpp) return FALSE;
887 if (!(dc = (DC *) GDI_GetObjPtr( hDC, DC_MAGIC ))) return FALSE;
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000888
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000889#ifndef X_DISPLAY_MISSING
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000890 if (!(dc->w.flags & DC_MEMORY))
891 {
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000892 X11DRV_PDEVICE *physDev;
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000893 Window root;
894 int w, h, border, depth;
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000895
896 physDev = (X11DRV_PDEVICE *) dc->physDev;
897
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000898 /* FIXME: this is not correct for managed windows */
Huw D M Davies9c68faa1998-11-25 12:36:03 +0000899 TSXGetGeometry( display, physDev->drawable, &root,
Marcus Meissnerde43ef41999-02-28 19:56:59 +0000900 (int*)&lpp->x, (int*)&lpp->y, &w, &h, &border, &depth );
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000901 }
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000902 else
903#endif /* !defined(X_DISPLAY_MISSING) */
904 lpp->x = lpp->y = 0;
905
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000906 lpp->x += dc->w.DCOrgX; lpp->y += dc->w.DCOrgY;
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000907 GDI_HEAP_UNLOCK( hDC );
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000908 return TRUE;
909}
910
911
912/***********************************************************************
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000913 * GetDCOrg (GDI.79)
914 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000915DWORD WINAPI GetDCOrg16( HDC16 hdc )
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000916{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000917 POINT pt;
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000918 if( GetDCOrgEx( hdc, &pt) )
919 return MAKELONG( (WORD)pt.x, (WORD)pt.y );
920 return 0;
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +0000921}
922
923
924/***********************************************************************
Alexandre Julliard401710d1993-09-04 10:09:32 +0000925 * SetDCOrg (GDI.117)
926 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000927DWORD WINAPI SetDCOrg16( HDC16 hdc, INT16 x, INT16 y )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000928{
929 DWORD prevOrg;
930 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
931 if (!dc) return 0;
932 prevOrg = dc->w.DCOrgX | (dc->w.DCOrgY << 16);
933 dc->w.DCOrgX = x;
934 dc->w.DCOrgY = y;
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000935 GDI_HEAP_UNLOCK( hdc );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000936 return prevOrg;
937}
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000938
939
940/***********************************************************************
Alexandre Julliard17216f51997-10-12 16:30:17 +0000941 * GetGraphicsMode (GDI32.188)
942 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000943INT WINAPI GetGraphicsMode( HDC hdc )
Alexandre Julliard17216f51997-10-12 16:30:17 +0000944{
945 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
946 if (!dc) return 0;
947 return dc->w.GraphicsMode;
948}
949
950
951/***********************************************************************
952 * SetGraphicsMode (GDI32.317)
953 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000954INT WINAPI SetGraphicsMode( HDC hdc, INT mode )
Alexandre Julliard17216f51997-10-12 16:30:17 +0000955{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000956 INT ret;
Alexandre Julliard17216f51997-10-12 16:30:17 +0000957 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
Alexandre Julliard60ce85c1998-02-01 18:33:27 +0000958
959 /* One would think that setting the graphics mode to GM_COMPATIBLE
960 * would also reset the world transformation matrix to the unity
961 * matrix. However, in Windows, this is not the case. This doesn't
962 * make a lot of sense to me, but that's the way it is.
963 */
964
Alexandre Julliard17216f51997-10-12 16:30:17 +0000965 if (!dc) return 0;
966 if ((mode <= 0) || (mode > GM_LAST)) return 0;
967 ret = dc->w.GraphicsMode;
968 dc->w.GraphicsMode = mode;
969 return ret;
970}
971
972
973/***********************************************************************
Alexandre Julliard60ce85c1998-02-01 18:33:27 +0000974 * GetArcDirection16 (GDI.524)
975 */
976INT16 WINAPI GetArcDirection16( HDC16 hdc )
977{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000978 return GetArcDirection( (HDC)hdc );
Alexandre Julliard60ce85c1998-02-01 18:33:27 +0000979}
980
981
982/***********************************************************************
983 * GetArcDirection32 (GDI32.141)
984 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000985INT WINAPI GetArcDirection( HDC hdc )
Alexandre Julliard60ce85c1998-02-01 18:33:27 +0000986{
987 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
988
989 if (!dc)
990 return 0;
991
992 return dc->w.ArcDirection;
993}
994
995
996/***********************************************************************
997 * SetArcDirection16 (GDI.525)
998 */
999INT16 WINAPI SetArcDirection16( HDC16 hdc, INT16 nDirection )
1000{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001001 return SetArcDirection( (HDC)hdc, (INT)nDirection );
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001002}
1003
1004
1005/***********************************************************************
1006 * SetArcDirection32 (GDI32.302)
1007 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001008INT WINAPI SetArcDirection( HDC hdc, INT nDirection )
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001009{
1010 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
Alexandre Julliarda3960291999-02-26 11:11:13 +00001011 INT nOldDirection;
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001012
1013 if (!dc)
1014 return 0;
1015
1016 if (nDirection!=AD_COUNTERCLOCKWISE && nDirection!=AD_CLOCKWISE)
1017 {
1018 SetLastError(ERROR_INVALID_PARAMETER);
1019 return 0;
1020 }
1021
1022 nOldDirection = dc->w.ArcDirection;
1023 dc->w.ArcDirection = nDirection;
1024
1025 return nOldDirection;
1026}
1027
1028
1029/***********************************************************************
Alexandre Julliard17216f51997-10-12 16:30:17 +00001030 * GetWorldTransform (GDI32.244)
1031 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001032BOOL WINAPI GetWorldTransform( HDC hdc, LPXFORM xform )
Alexandre Julliard17216f51997-10-12 16:30:17 +00001033{
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001034 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1035
1036 if (!dc)
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001037 return FALSE;
1038 if (!xform)
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001039 return FALSE;
1040
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001041 *xform = dc->w.xformWorld2Wnd;
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001042
1043 return TRUE;
1044}
1045
1046
1047/***********************************************************************
1048 * SetWorldTransform (GDI32.346)
1049 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001050BOOL WINAPI SetWorldTransform( HDC hdc, const XFORM *xform )
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001051{
1052 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1053
1054 if (!dc)
1055 {
1056 SetLastError( ERROR_INVALID_HANDLE );
1057 return FALSE;
1058 }
1059
1060 if (!xform)
1061 return FALSE;
1062
1063 /* Check that graphics mode is GM_ADVANCED */
1064 if (dc->w.GraphicsMode!=GM_ADVANCED)
1065 return FALSE;
1066
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001067 dc->w.xformWorld2Wnd = *xform;
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001068
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001069 DC_UpdateXforms( dc );
1070
1071 return TRUE;
1072}
1073
1074
1075/****************************************************************************
1076 * ModifyWorldTransform [GDI32.253]
1077 * Modifies the world transformation for a device context.
1078 *
1079 * PARAMS
1080 * hdc [I] Handle to device context
1081 * xform [I] XFORM structure that will be used to modify the world
1082 * transformation
1083 * iMode [I] Specifies in what way to modify the world transformation
1084 * Possible values:
1085 * MWT_IDENTITY
1086 * Resets the world transformation to the identity matrix.
1087 * The parameter xform is ignored.
1088 * MWT_LEFTMULTIPLY
1089 * Multiplies xform into the world transformation matrix from
1090 * the left.
1091 * MWT_RIGHTMULTIPLY
1092 * Multiplies xform into the world transformation matrix from
1093 * the right.
1094 *
1095 * RETURNS STD
1096 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001097BOOL WINAPI ModifyWorldTransform( HDC hdc, const XFORM *xform,
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001098 DWORD iMode )
1099{
1100 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1101
1102 /* Check for illegal parameters */
1103 if (!dc)
1104 {
1105 SetLastError( ERROR_INVALID_HANDLE );
1106 return FALSE;
1107 }
1108 if (!xform)
1109 return FALSE;
1110
1111 /* Check that graphics mode is GM_ADVANCED */
1112 if (dc->w.GraphicsMode!=GM_ADVANCED)
1113 return FALSE;
1114
1115 switch (iMode)
1116 {
1117 case MWT_IDENTITY:
1118 dc->w.xformWorld2Wnd.eM11 = 1.0f;
1119 dc->w.xformWorld2Wnd.eM12 = 0.0f;
1120 dc->w.xformWorld2Wnd.eM21 = 0.0f;
1121 dc->w.xformWorld2Wnd.eM22 = 1.0f;
1122 dc->w.xformWorld2Wnd.eDx = 0.0f;
1123 dc->w.xformWorld2Wnd.eDy = 0.0f;
1124 break;
1125 case MWT_LEFTMULTIPLY:
1126 CombineTransform( &dc->w.xformWorld2Wnd, xform,
1127 &dc->w.xformWorld2Wnd );
1128 break;
1129 case MWT_RIGHTMULTIPLY:
1130 CombineTransform( &dc->w.xformWorld2Wnd, &dc->w.xformWorld2Wnd,
1131 xform );
1132 break;
1133 default:
1134 return FALSE;
1135 }
1136
1137 DC_UpdateXforms( dc );
1138
1139 return TRUE;
1140}
1141
1142
1143/****************************************************************************
1144 * CombineTransform [GDI32.20]
1145 * Combines two transformation matrices.
1146 *
1147 * PARAMS
1148 * xformResult [O] Stores the result of combining the two matrices
1149 * xform1 [I] Specifies the first matrix to apply
1150 * xform2 [I] Specifies the second matrix to apply
1151 *
1152 * REMARKS
1153 * The same matrix can be passed in for more than one of the parameters.
1154 *
1155 * RETURNS STD
1156 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001157BOOL WINAPI CombineTransform( LPXFORM xformResult, const XFORM *xform1,
Alexandre Julliarddadf78f1998-05-17 17:13:43 +00001158 const XFORM *xform2 )
1159{
1160 XFORM xformTemp;
1161
1162 /* Check for illegal parameters */
1163 if (!xformResult || !xform1 || !xform2)
1164 return FALSE;
1165
1166 /* Create the result in a temporary XFORM, since xformResult may be
1167 * equal to xform1 or xform2 */
1168 xformTemp.eM11 = xform1->eM11 * xform2->eM11 +
1169 xform1->eM12 * xform2->eM21;
1170 xformTemp.eM12 = xform1->eM11 * xform2->eM12 +
1171 xform1->eM12 * xform2->eM22;
1172 xformTemp.eM21 = xform1->eM21 * xform2->eM11 +
1173 xform1->eM22 * xform2->eM21;
1174 xformTemp.eM22 = xform1->eM21 * xform2->eM12 +
1175 xform1->eM22 * xform2->eM22;
1176 xformTemp.eDx = xform1->eDx * xform2->eM11 +
1177 xform1->eDy * xform2->eM21 +
1178 xform2->eDx;
1179 xformTemp.eDy = xform1->eDx * xform2->eM12 +
1180 xform1->eDy * xform2->eM22 +
1181 xform2->eDy;
1182
1183 /* Copy the result to xformResult */
1184 *xformResult = xformTemp;
1185
Alexandre Julliard60ce85c1998-02-01 18:33:27 +00001186 return TRUE;
Alexandre Julliard17216f51997-10-12 16:30:17 +00001187}
1188
1189
1190/***********************************************************************
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001191 * SetDCHook (GDI.190)
1192 */
Ulrich Weigandf86aab81999-09-20 18:47:14 +00001193/* ### start build ### */
1194extern WORD CALLBACK GDI_CallTo16_word_wwll(FARPROC16,WORD,WORD,LONG,LONG);
1195/* ### stop build ### */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001196BOOL16 WINAPI SetDCHook( HDC16 hdc, FARPROC16 hookProc, DWORD dwHookData )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001197{
Alexandre Julliardbf9130a1996-10-13 17:45:47 +00001198 DC *dc = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001199 if (!dc) return FALSE;
Ulrich Weigandf86aab81999-09-20 18:47:14 +00001200
1201 /*
1202 * Note: We store the original SEGPTR 'hookProc' as we need to be
1203 * able to return it verbatim in GetDCHook,
1204 *
1205 * On the other hand, we still call THUNK_Alloc and store the
1206 * 32-bit thunk into another DC member, because THUNK_Alloc
1207 * recognizes the (typical) case that the 'hookProc' is indeed
1208 * the 16-bit API entry point of a built-in routine (e.g. DCHook16)
1209 *
1210 * We could perform that test every time the hook is about to
1211 * be called (or else we could live with the 32->16->32 detour),
1212 * but this way is the most efficient ...
1213 */
1214
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001215 dc->hookProc = hookProc;
1216 dc->dwHookData = dwHookData;
Ulrich Weigandf86aab81999-09-20 18:47:14 +00001217
1218 THUNK_Free( (FARPROC)dc->hookThunk );
1219 dc->hookThunk = (DCHOOKPROC)
1220 THUNK_Alloc( hookProc, (RELAY)GDI_CallTo16_word_wwll );
1221
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001222 GDI_HEAP_UNLOCK( hdc );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001223 return TRUE;
1224}
1225
1226
1227/***********************************************************************
1228 * GetDCHook (GDI.191)
1229 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001230DWORD WINAPI GetDCHook( HDC16 hdc, FARPROC16 *phookProc )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001231{
Alexandre Julliardbf9130a1996-10-13 17:45:47 +00001232 DC *dc = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001233 if (!dc) return 0;
1234 *phookProc = dc->hookProc;
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001235 GDI_HEAP_UNLOCK( hdc );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001236 return dc->dwHookData;
1237}
1238
1239
1240/***********************************************************************
1241 * SetHookFlags (GDI.192)
1242 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001243WORD WINAPI SetHookFlags16(HDC16 hDC, WORD flags)
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001244{
Alexandre Julliard491502b1997-11-01 19:08:16 +00001245 DC* dc = (DC*)GDI_GetObjPtr( hDC, DC_MAGIC );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001246
Alexandre Julliard491502b1997-11-01 19:08:16 +00001247 if( dc )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001248 {
1249 WORD wRet = dc->w.flags & DC_DIRTY;
1250
Alexandre Julliard491502b1997-11-01 19:08:16 +00001251 /* "Undocumented Windows" info is slightly confusing.
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001252 */
1253
Alexandre Julliard15657091999-05-23 10:25:25 +00001254 TRACE("hDC %04x, flags %04x\n",hDC,flags);
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001255
1256 if( flags & DCHF_INVALIDATEVISRGN )
1257 dc->w.flags |= DC_DIRTY;
1258 else if( flags & DCHF_VALIDATEVISRGN || !flags )
1259 dc->w.flags &= ~DC_DIRTY;
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001260 GDI_HEAP_UNLOCK( hDC );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001261 return wRet;
1262 }
Alexandre Julliard491502b1997-11-01 19:08:16 +00001263 return 0;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001264}
1265
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00001266/***********************************************************************
1267 * SetICMMode (GDI32.318)
1268 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001269INT WINAPI SetICMMode(HDC hdc, INT iEnableICM)
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00001270{
1271/*FIXME Asuming that ICM is always off, and cannot be turned on */
1272 if (iEnableICM == ICM_OFF) return ICM_OFF;
1273 if (iEnableICM == ICM_ON) return 0;
1274 if (iEnableICM == ICM_QUERY) return ICM_OFF;
1275 return 0;
1276}
1277
1278
1279/***********************************************************************
1280 * GetColorSpace (GDI32.165)
1281 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001282HCOLORSPACE WINAPI GetColorSpace(HDC hdc)
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00001283{
1284/*FIXME Need to to whatever GetColorSpace actually does */
1285 return 0;
1286}
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001287
1288/***********************************************************************
Gerard Patel82f37be2000-01-15 22:11:21 +00001289 * CreateColorSpaceA (GDI32.???)
1290 */
1291HCOLORSPACE WINAPI CreateColorSpaceA( LPLOGCOLORSPACEA lpLogColorSpace )
1292{
1293 FIXME( "stub\n" );
1294 return 0;
1295}
1296
1297/***********************************************************************
1298 * CreateColorSpaceW (GDI32.???)
1299 */
1300HCOLORSPACE WINAPI CreateColorSpaceW( LPLOGCOLORSPACEW lpLogColorSpace )
1301{
1302 FIXME( "stub\n" );
1303 return 0;
1304}
1305
1306/***********************************************************************
1307 * DeleteColorSpace (GDI32.???)
1308 */
1309BOOL WINAPI DeleteColorSpace( HCOLORSPACE hColorSpace )
1310{
1311 FIXME( "stub\n" );
1312
1313 return True;
1314}
1315
1316/***********************************************************************
1317 * SetColorSpace (GDI32.???)
1318 */
1319HCOLORSPACE WINAPI SetColorSpace( HDC hDC, HCOLORSPACE hColorSpace )
1320{
1321 FIXME( "stub\n" );
1322
1323 return hColorSpace;
1324}
1325
1326/***********************************************************************
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001327 * GetBoundsRect16 (GDI.194)
1328 */
1329UINT16 WINAPI GetBoundsRect16(HDC16 hdc, LPRECT16 rect, UINT16 flags)
1330{
Ulrich Weigande62cbca1998-11-26 15:06:47 +00001331 return DCB_RESET | DCB_DISABLE; /* bounding rectangle always empty and disabled*/
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001332}
1333
Ulrich Weigandd4663661998-10-11 18:47:02 +00001334/***********************************************************************
Paul Quinn1beaae51998-12-15 15:38:36 +00001335 * GetBoundsRect32 (GDI32.147)
1336 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001337UINT WINAPI GetBoundsRect(HDC hdc, LPRECT rect, UINT flags)
Paul Quinn1beaae51998-12-15 15:38:36 +00001338{
Alexandre Julliard15657091999-05-23 10:25:25 +00001339 FIXME("(): stub\n");
Paul Quinn1beaae51998-12-15 15:38:36 +00001340 return DCB_RESET; /* bounding rectangle always empty */
1341}
1342
1343/***********************************************************************
Ulrich Weigandd4663661998-10-11 18:47:02 +00001344 * SetBoundsRect16 (GDI.193)
1345 */
François Gouget241c7301998-10-28 10:47:09 +00001346UINT16 WINAPI SetBoundsRect16(HDC16 hdc, const RECT16* rect, UINT16 flags)
Ulrich Weigandd4663661998-10-11 18:47:02 +00001347{
Ulrich Weigande62cbca1998-11-26 15:06:47 +00001348 if ( (flags & DCB_ACCUMULATE) || (flags & DCB_ENABLE) )
Alexandre Julliard15657091999-05-23 10:25:25 +00001349 FIXME("(%04x, %p, %04x): stub\n", hdc, rect, flags );
Ulrich Weigande62cbca1998-11-26 15:06:47 +00001350
1351 return DCB_RESET | DCB_DISABLE; /* bounding rectangle always empty and disabled*/
Ulrich Weigandd4663661998-10-11 18:47:02 +00001352}
1353
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001354/***********************************************************************
1355 * SetBoundsRect32 (GDI32.307)
1356 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001357UINT WINAPI SetBoundsRect(HDC hdc, const RECT* rect, UINT flags)
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001358{
Alexandre Julliard15657091999-05-23 10:25:25 +00001359 FIXME("(): stub\n");
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001360 return DCB_DISABLE; /* bounding rectangle always empty */
1361}
1362
Alexandre Julliard8da12c41999-01-17 16:55:11 +00001363/***********************************************************************
1364 * Death (GDI.121)
1365 *
1366 * Disables GDI, switches back to text mode.
1367 * We don't have to do anything here,
1368 * just let console support handle everything
1369 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001370void WINAPI Death16(HDC16 hDC)
Alexandre Julliard8da12c41999-01-17 16:55:11 +00001371{
Alexandre Julliard15657091999-05-23 10:25:25 +00001372 MESSAGE("Death(%04x) called. Application enters text mode...\n", hDC);
Alexandre Julliard8da12c41999-01-17 16:55:11 +00001373}
1374
1375/***********************************************************************
1376 * Resurrection (GDI.122)
1377 *
1378 * Restores GDI functionality
1379 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001380void WINAPI Resurrection16(HDC16 hDC,
Alexandre Julliard8da12c41999-01-17 16:55:11 +00001381 WORD w1, WORD w2, WORD w3, WORD w4, WORD w5, WORD w6)
1382{
Alexandre Julliard15657091999-05-23 10:25:25 +00001383 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 +00001384}
Huw D M Daviesf64e0d71999-11-21 00:49:50 +00001385
1386/***********************************************************************
1387 * GetLayout (GDI32.321)
1388 *
1389 * Gets left->right or right->left text layout flags of a dc.
1390 * win98 just returns 0 and sets ERROR_CALL_NOT_IMPLEMENTED so we do the same
1391 *
1392 */
1393DWORD WINAPI GetLayout(HDC hdc)
1394{
1395 FIXME("(%08x): stub\n", hdc);
1396 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1397 return 0;
1398}
1399
1400/***********************************************************************
1401 * SetLayout (GDI32.450)
1402 *
1403 * Sets left->right or right->left text layout flags of a dc.
1404 * win98 just returns 0 and sets ERROR_CALL_NOT_IMPLEMENTED so we do the same
1405 *
1406 */
1407DWORD WINAPI SetLayout(HDC hdc, DWORD layout)
1408{
1409 FIXME("(%08x,%08lx): stub\n", hdc, layout);
1410 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1411 return 0;
1412}