Updated so it's in line with README.
[wine.git] / objects / dc.c
blobe06d67eced67c5ceb535ab0613ef2efed43c1c59
1 /*
2 * GDI Device Context functions
4 * Copyright 1993 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "config.h"
23 #include <stdlib.h>
24 #include <string.h>
25 #include "gdi.h"
26 #include "heap.h"
27 #include "wine/debug.h"
28 #include "font.h"
29 #include "winerror.h"
30 #include "windef.h"
31 #include "wingdi.h"
32 #include "wine/winuser16.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(dc);
36 /* ### start build ### */
37 extern WORD CALLBACK GDI_CallTo16_word_wwll(FARPROC16,WORD,WORD,LONG,LONG);
38 /* ### stop build ### */
40 static BOOL DC_DeleteObject( HGDIOBJ handle, void *obj );
42 static const struct gdi_obj_funcs dc_funcs =
44 NULL, /* pSelectObject */
45 NULL, /* pGetObject16 */
46 NULL, /* pGetObjectA */
47 NULL, /* pGetObjectW */
48 NULL, /* pUnrealizeObject */
49 DC_DeleteObject /* pDeleteObject */
52 /***********************************************************************
53 * DC_AllocDC
55 DC *DC_AllocDC( const DC_FUNCTIONS *funcs )
57 HDC hdc;
58 DC *dc;
60 if (!(dc = GDI_AllocObject( sizeof(*dc), DC_MAGIC, &hdc, &dc_funcs ))) return NULL;
62 dc->hSelf = hdc;
63 dc->funcs = funcs;
64 dc->physDev = NULL;
65 dc->saveLevel = 0;
66 dc->dwHookData = 0;
67 dc->hookProc = NULL;
68 dc->hookThunk = NULL;
69 dc->wndOrgX = 0;
70 dc->wndOrgY = 0;
71 dc->wndExtX = 1;
72 dc->wndExtY = 1;
73 dc->vportOrgX = 0;
74 dc->vportOrgY = 0;
75 dc->vportExtX = 1;
76 dc->vportExtY = 1;
77 dc->flags = 0;
78 dc->hClipRgn = 0;
79 dc->hVisRgn = 0;
80 dc->hGCClipRgn = 0;
81 dc->hPen = GetStockObject( BLACK_PEN );
82 dc->hBrush = GetStockObject( WHITE_BRUSH );
83 dc->hFont = GetStockObject( SYSTEM_FONT );
84 dc->hBitmap = 0;
85 dc->hDevice = 0;
86 dc->hPalette = GetStockObject( DEFAULT_PALETTE );
87 dc->gdiFont = 0;
88 dc->ROPmode = R2_COPYPEN;
89 dc->polyFillMode = ALTERNATE;
90 dc->stretchBltMode = BLACKONWHITE;
91 dc->relAbsMode = ABSOLUTE;
92 dc->backgroundMode = OPAQUE;
93 dc->backgroundColor = RGB( 255, 255, 255 );
94 dc->textColor = RGB( 0, 0, 0 );
95 dc->brushOrgX = 0;
96 dc->brushOrgY = 0;
97 dc->textAlign = TA_LEFT | TA_TOP | TA_NOUPDATECP;
98 dc->charExtra = 0;
99 dc->breakTotalExtra = 0;
100 dc->breakCount = 0;
101 dc->breakExtra = 0;
102 dc->breakRem = 0;
103 dc->totalExtent.left = 0;
104 dc->totalExtent.top = 0;
105 dc->totalExtent.right = 0;
106 dc->totalExtent.bottom = 0;
107 dc->bitsPerPixel = 1;
108 dc->MapMode = MM_TEXT;
109 dc->GraphicsMode = GM_COMPATIBLE;
110 dc->DCOrgX = 0;
111 dc->DCOrgY = 0;
112 dc->pAbortProc = NULL;
113 dc->CursPosX = 0;
114 dc->CursPosY = 0;
115 dc->ArcDirection = AD_COUNTERCLOCKWISE;
116 dc->xformWorld2Wnd.eM11 = 1.0f;
117 dc->xformWorld2Wnd.eM12 = 0.0f;
118 dc->xformWorld2Wnd.eM21 = 0.0f;
119 dc->xformWorld2Wnd.eM22 = 1.0f;
120 dc->xformWorld2Wnd.eDx = 0.0f;
121 dc->xformWorld2Wnd.eDy = 0.0f;
122 dc->xformWorld2Vport = dc->xformWorld2Wnd;
123 dc->xformVport2World = dc->xformWorld2Wnd;
124 dc->vport2WorldValid = TRUE;
125 PATH_InitGdiPath(&dc->path);
126 return dc;
131 /***********************************************************************
132 * DC_GetDCPtr
134 DC *DC_GetDCPtr( HDC hdc )
136 GDIOBJHDR *ptr = GDI_GetObjPtr( hdc, MAGIC_DONTCARE );
137 if (!ptr) return NULL;
138 if ((GDIMAGIC(ptr->wMagic) == DC_MAGIC) ||
139 (GDIMAGIC(ptr->wMagic) == METAFILE_DC_MAGIC) ||
140 (GDIMAGIC(ptr->wMagic) == ENHMETAFILE_DC_MAGIC))
141 return (DC *)ptr;
142 GDI_ReleaseObj( hdc );
143 SetLastError( ERROR_INVALID_HANDLE );
144 return NULL;
147 /***********************************************************************
148 * DC_GetDCUpdate
150 * Retrieve a DC ptr while making sure the visRgn is updated.
151 * This function may call up to USER so the GDI lock should _not_
152 * be held when calling it.
154 DC *DC_GetDCUpdate( HDC hdc )
156 DC *dc = DC_GetDCPtr( hdc );
157 if (!dc) return NULL;
158 while (dc->flags & DC_DIRTY)
160 dc->flags &= ~DC_DIRTY;
161 if (!(dc->flags & (DC_SAVED | DC_MEMORY)))
163 DCHOOKPROC proc = dc->hookThunk;
164 if (proc)
166 DWORD data = dc->dwHookData;
167 GDI_ReleaseObj( hdc );
168 proc( hdc, DCHC_INVALIDVISRGN, data, 0 );
169 if (!(dc = DC_GetDCPtr( hdc ))) break;
170 /* otherwise restart the loop in case it became dirty again in the meantime */
174 return dc;
178 /***********************************************************************
179 * DC_DeleteObject
181 static BOOL DC_DeleteObject( HGDIOBJ handle, void *obj )
183 GDI_ReleaseObj( handle );
184 return DeleteDC( handle );
188 /***********************************************************************
189 * DC_InitDC
191 * Setup device-specific DC values for a newly created DC.
193 void DC_InitDC( DC* dc )
195 RealizeDefaultPalette16( dc->hSelf );
196 SetTextColor( dc->hSelf, dc->textColor );
197 SetBkColor( dc->hSelf, dc->backgroundColor );
198 SelectObject( dc->hSelf, dc->hPen );
199 SelectObject( dc->hSelf, dc->hBrush );
200 SelectObject( dc->hSelf, dc->hFont );
201 CLIPPING_UpdateGCRegion( dc );
205 /***********************************************************************
206 * DC_InvertXform
208 * Computes the inverse of the transformation xformSrc and stores it to
209 * xformDest. Returns TRUE if successful or FALSE if the xformSrc matrix
210 * is singular.
212 static BOOL DC_InvertXform( const XFORM *xformSrc, XFORM *xformDest )
214 FLOAT determinant;
216 determinant = xformSrc->eM11*xformSrc->eM22 -
217 xformSrc->eM12*xformSrc->eM21;
218 if (determinant > -1e-12 && determinant < 1e-12)
219 return FALSE;
221 xformDest->eM11 = xformSrc->eM22 / determinant;
222 xformDest->eM12 = -xformSrc->eM12 / determinant;
223 xformDest->eM21 = -xformSrc->eM21 / determinant;
224 xformDest->eM22 = xformSrc->eM11 / determinant;
225 xformDest->eDx = -xformSrc->eDx * xformDest->eM11 -
226 xformSrc->eDy * xformDest->eM21;
227 xformDest->eDy = -xformSrc->eDx * xformDest->eM12 -
228 xformSrc->eDy * xformDest->eM22;
230 return TRUE;
234 /***********************************************************************
235 * DC_UpdateXforms
237 * Updates the xformWorld2Vport, xformVport2World and vport2WorldValid
238 * fields of the specified DC by creating a transformation that
239 * represents the current mapping mode and combining it with the DC's
240 * world transform. This function should be called whenever the
241 * parameters associated with the mapping mode (window and viewport
242 * extents and origins) or the world transform change.
244 void DC_UpdateXforms( DC *dc )
246 XFORM xformWnd2Vport;
247 FLOAT scaleX, scaleY;
249 /* Construct a transformation to do the window-to-viewport conversion */
250 scaleX = (FLOAT)dc->vportExtX / (FLOAT)dc->wndExtX;
251 scaleY = (FLOAT)dc->vportExtY / (FLOAT)dc->wndExtY;
252 xformWnd2Vport.eM11 = scaleX;
253 xformWnd2Vport.eM12 = 0.0;
254 xformWnd2Vport.eM21 = 0.0;
255 xformWnd2Vport.eM22 = scaleY;
256 xformWnd2Vport.eDx = (FLOAT)dc->vportOrgX -
257 scaleX * (FLOAT)dc->wndOrgX;
258 xformWnd2Vport.eDy = (FLOAT)dc->vportOrgY -
259 scaleY * (FLOAT)dc->wndOrgY;
261 /* Combine with the world transformation */
262 CombineTransform( &dc->xformWorld2Vport, &dc->xformWorld2Wnd,
263 &xformWnd2Vport );
265 /* Create inverse of world-to-viewport transformation */
266 dc->vport2WorldValid = DC_InvertXform( &dc->xformWorld2Vport,
267 &dc->xformVport2World );
271 /***********************************************************************
272 * GetDCState (GDI.179)
274 HDC16 WINAPI GetDCState16( HDC16 hdc )
276 DC * newdc, * dc;
277 HGDIOBJ handle;
279 if (!(dc = DC_GetDCPtr( hdc ))) return 0;
280 if (!(newdc = GDI_AllocObject( sizeof(DC), DC_MAGIC, &handle, &dc_funcs )))
282 GDI_ReleaseObj( hdc );
283 return 0;
285 TRACE("(%04x): returning %04x\n", hdc, handle );
287 newdc->flags = dc->flags | DC_SAVED;
288 newdc->hPen = dc->hPen;
289 newdc->hBrush = dc->hBrush;
290 newdc->hFont = dc->hFont;
291 newdc->hBitmap = dc->hBitmap;
292 newdc->hDevice = dc->hDevice;
293 newdc->hPalette = dc->hPalette;
294 newdc->totalExtent = dc->totalExtent;
295 newdc->bitsPerPixel = dc->bitsPerPixel;
296 newdc->ROPmode = dc->ROPmode;
297 newdc->polyFillMode = dc->polyFillMode;
298 newdc->stretchBltMode = dc->stretchBltMode;
299 newdc->relAbsMode = dc->relAbsMode;
300 newdc->backgroundMode = dc->backgroundMode;
301 newdc->backgroundColor = dc->backgroundColor;
302 newdc->textColor = dc->textColor;
303 newdc->brushOrgX = dc->brushOrgX;
304 newdc->brushOrgY = dc->brushOrgY;
305 newdc->textAlign = dc->textAlign;
306 newdc->charExtra = dc->charExtra;
307 newdc->breakTotalExtra = dc->breakTotalExtra;
308 newdc->breakCount = dc->breakCount;
309 newdc->breakExtra = dc->breakExtra;
310 newdc->breakRem = dc->breakRem;
311 newdc->MapMode = dc->MapMode;
312 newdc->GraphicsMode = dc->GraphicsMode;
313 #if 0
314 /* Apparently, the DC origin is not changed by [GS]etDCState */
315 newdc->DCOrgX = dc->DCOrgX;
316 newdc->DCOrgY = dc->DCOrgY;
317 #endif
318 newdc->CursPosX = dc->CursPosX;
319 newdc->CursPosY = dc->CursPosY;
320 newdc->ArcDirection = dc->ArcDirection;
321 newdc->xformWorld2Wnd = dc->xformWorld2Wnd;
322 newdc->xformWorld2Vport = dc->xformWorld2Vport;
323 newdc->xformVport2World = dc->xformVport2World;
324 newdc->vport2WorldValid = dc->vport2WorldValid;
325 newdc->wndOrgX = dc->wndOrgX;
326 newdc->wndOrgY = dc->wndOrgY;
327 newdc->wndExtX = dc->wndExtX;
328 newdc->wndExtY = dc->wndExtY;
329 newdc->vportOrgX = dc->vportOrgX;
330 newdc->vportOrgY = dc->vportOrgY;
331 newdc->vportExtX = dc->vportExtX;
332 newdc->vportExtY = dc->vportExtY;
334 newdc->hSelf = (HDC)handle;
335 newdc->saveLevel = 0;
337 PATH_InitGdiPath( &newdc->path );
339 newdc->pAbortProc = NULL;
340 newdc->hookThunk = NULL;
341 newdc->hookProc = 0;
343 /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
345 newdc->hGCClipRgn = newdc->hVisRgn = 0;
346 if (dc->hClipRgn)
348 newdc->hClipRgn = CreateRectRgn( 0, 0, 0, 0 );
349 CombineRgn( newdc->hClipRgn, dc->hClipRgn, 0, RGN_COPY );
351 else
352 newdc->hClipRgn = 0;
354 if(dc->gdiFont) {
355 newdc->gdiFont = dc->gdiFont;
356 } else
357 newdc->gdiFont = 0;
359 GDI_ReleaseObj( handle );
360 GDI_ReleaseObj( hdc );
361 return handle;
365 /***********************************************************************
366 * SetDCState (GDI.180)
368 void WINAPI SetDCState16( HDC16 hdc, HDC16 hdcs )
370 DC *dc, *dcs;
372 if (!(dc = DC_GetDCUpdate( hdc ))) return;
373 if (!(dcs = DC_GetDCPtr( hdcs )))
375 GDI_ReleaseObj( hdc );
376 return;
378 if (!dcs->flags & DC_SAVED)
380 GDI_ReleaseObj( hdc );
381 GDI_ReleaseObj( hdcs );
382 return;
384 TRACE("%04x %04x\n", hdc, hdcs );
386 dc->flags = dcs->flags & ~DC_SAVED;
387 dc->hDevice = dcs->hDevice;
388 dc->totalExtent = dcs->totalExtent;
389 dc->ROPmode = dcs->ROPmode;
390 dc->polyFillMode = dcs->polyFillMode;
391 dc->stretchBltMode = dcs->stretchBltMode;
392 dc->relAbsMode = dcs->relAbsMode;
393 dc->backgroundMode = dcs->backgroundMode;
394 dc->backgroundColor = dcs->backgroundColor;
395 dc->textColor = dcs->textColor;
396 dc->brushOrgX = dcs->brushOrgX;
397 dc->brushOrgY = dcs->brushOrgY;
398 dc->textAlign = dcs->textAlign;
399 dc->charExtra = dcs->charExtra;
400 dc->breakTotalExtra = dcs->breakTotalExtra;
401 dc->breakCount = dcs->breakCount;
402 dc->breakExtra = dcs->breakExtra;
403 dc->breakRem = dcs->breakRem;
404 dc->MapMode = dcs->MapMode;
405 dc->GraphicsMode = dcs->GraphicsMode;
406 #if 0
407 /* Apparently, the DC origin is not changed by [GS]etDCState */
408 dc->DCOrgX = dcs->DCOrgX;
409 dc->DCOrgY = dcs->DCOrgY;
410 #endif
411 dc->CursPosX = dcs->CursPosX;
412 dc->CursPosY = dcs->CursPosY;
413 dc->ArcDirection = dcs->ArcDirection;
414 dc->xformWorld2Wnd = dcs->xformWorld2Wnd;
415 dc->xformWorld2Vport = dcs->xformWorld2Vport;
416 dc->xformVport2World = dcs->xformVport2World;
417 dc->vport2WorldValid = dcs->vport2WorldValid;
419 dc->wndOrgX = dcs->wndOrgX;
420 dc->wndOrgY = dcs->wndOrgY;
421 dc->wndExtX = dcs->wndExtX;
422 dc->wndExtY = dcs->wndExtY;
423 dc->vportOrgX = dcs->vportOrgX;
424 dc->vportOrgY = dcs->vportOrgY;
425 dc->vportExtX = dcs->vportExtX;
426 dc->vportExtY = dcs->vportExtY;
428 if (!(dc->flags & DC_MEMORY)) dc->bitsPerPixel = dcs->bitsPerPixel;
430 if (dcs->hClipRgn)
432 if (!dc->hClipRgn) dc->hClipRgn = CreateRectRgn( 0, 0, 0, 0 );
433 CombineRgn( dc->hClipRgn, dcs->hClipRgn, 0, RGN_COPY );
435 else
437 if (dc->hClipRgn) DeleteObject( dc->hClipRgn );
438 dc->hClipRgn = 0;
440 CLIPPING_UpdateGCRegion( dc );
442 SelectObject( hdc, dcs->hBitmap );
443 SelectObject( hdc, dcs->hBrush );
444 SelectObject( hdc, dcs->hFont );
445 SelectObject( hdc, dcs->hPen );
446 SetBkColor( hdc, dcs->backgroundColor);
447 SetTextColor( hdc, dcs->textColor);
448 GDISelectPalette16( hdc, dcs->hPalette, FALSE );
449 GDI_ReleaseObj( hdcs );
450 GDI_ReleaseObj( hdc );
454 /***********************************************************************
455 * SaveDC (GDI.30)
457 INT16 WINAPI SaveDC16( HDC16 hdc )
459 return (INT16)SaveDC( hdc );
463 /***********************************************************************
464 * SaveDC (GDI32.@)
466 INT WINAPI SaveDC( HDC hdc )
468 HDC hdcs;
469 DC * dc, * dcs;
470 INT ret;
472 dc = DC_GetDCPtr( hdc );
473 if (!dc) return 0;
475 if(dc->funcs->pSaveDC)
477 ret = dc->funcs->pSaveDC( dc->physDev );
478 GDI_ReleaseObj( hdc );
479 return ret;
482 if (!(hdcs = GetDCState16( hdc )))
484 GDI_ReleaseObj( hdc );
485 return 0;
487 dcs = DC_GetDCPtr( hdcs );
489 /* Copy path. The reason why path saving / restoring is in SaveDC/
490 * RestoreDC and not in GetDCState/SetDCState is that the ...DCState
491 * functions are only in Win16 (which doesn't have paths) and that
492 * SetDCState doesn't allow us to signal an error (which can happen
493 * when copying paths).
495 if (!PATH_AssignGdiPath( &dcs->path, &dc->path ))
497 GDI_ReleaseObj( hdc );
498 GDI_ReleaseObj( hdcs );
499 DeleteDC( hdcs );
500 return 0;
503 dcs->header.hNext = dc->header.hNext;
504 dc->header.hNext = hdcs;
505 TRACE("(%04x): returning %d\n", hdc, dc->saveLevel+1 );
506 ret = ++dc->saveLevel;
507 GDI_ReleaseObj( hdcs );
508 GDI_ReleaseObj( hdc );
509 return ret;
513 /***********************************************************************
514 * RestoreDC (GDI.39)
516 BOOL16 WINAPI RestoreDC16( HDC16 hdc, INT16 level )
518 return RestoreDC( hdc, level );
522 /***********************************************************************
523 * RestoreDC (GDI32.@)
525 BOOL WINAPI RestoreDC( HDC hdc, INT level )
527 DC * dc, * dcs;
528 BOOL success;
530 TRACE("%04x %d\n", hdc, level );
531 dc = DC_GetDCUpdate( hdc );
532 if(!dc) return FALSE;
533 if(dc->funcs->pRestoreDC)
535 success = dc->funcs->pRestoreDC( dc->physDev, level );
536 GDI_ReleaseObj( hdc );
537 return success;
540 if (level == -1) level = dc->saveLevel;
541 if ((level < 1)
542 /* This pair of checks disagrees with MSDN "Platform SDK:
543 Windows GDI" July 2000 which says all negative values
544 for level will be interpreted as an instance relative
545 to the current state. Restricting it to just -1 does
546 not satisfy this */
547 || (level > dc->saveLevel))
549 GDI_ReleaseObj( hdc );
550 return FALSE;
553 success=TRUE;
554 while (dc->saveLevel >= level)
556 HDC16 hdcs = dc->header.hNext;
557 if (!(dcs = DC_GetDCPtr( hdcs )))
559 GDI_ReleaseObj( hdc );
560 return FALSE;
562 dc->header.hNext = dcs->header.hNext;
563 if (--dc->saveLevel < level)
565 SetDCState16( hdc, hdcs );
566 if (!PATH_AssignGdiPath( &dc->path, &dcs->path ))
567 /* FIXME: This might not be quite right, since we're
568 * returning FALSE but still destroying the saved DC state */
569 success=FALSE;
571 GDI_ReleaseObj( hdcs );
572 GDI_ReleaseObj( hdc );
573 DeleteDC( hdcs );
574 if (!(dc = DC_GetDCPtr( hdc ))) return FALSE;
576 GDI_ReleaseObj( hdc );
577 return success;
581 /***********************************************************************
582 * CreateDC (GDI.53)
584 HDC16 WINAPI CreateDC16( LPCSTR driver, LPCSTR device, LPCSTR output,
585 const DEVMODEA *initData )
587 return CreateDCA( driver, device, output, initData );
590 /***********************************************************************
591 * CreateDCA (GDI32.@)
593 HDC WINAPI CreateDCA( LPCSTR driver, LPCSTR device, LPCSTR output,
594 const DEVMODEA *initData )
596 HDC hdc;
597 DC * dc;
598 const DC_FUNCTIONS *funcs;
599 char buf[300];
601 GDI_CheckNotLock();
603 if (!device || !DRIVER_GetDriverName( device, buf, sizeof(buf) ))
604 strcpy(buf, driver);
606 if (!(funcs = DRIVER_load_driver( buf )))
608 ERR( "no driver found for %s\n", buf );
609 return 0;
611 if (!(dc = DC_AllocDC( funcs )))
613 DRIVER_release_driver( funcs );
614 return 0;
617 dc->flags = 0;
619 TRACE("(driver=%s, device=%s, output=%s): returning %04x\n",
620 debugstr_a(driver), debugstr_a(device), debugstr_a(output), dc->hSelf );
622 if (dc->funcs->pCreateDC &&
623 !dc->funcs->pCreateDC( dc, buf, device, output, initData ))
625 WARN("creation aborted by device\n" );
626 GDI_FreeObject( dc->hSelf, dc );
627 DRIVER_release_driver( funcs );
628 return 0;
631 dc->totalExtent.left = 0;
632 dc->totalExtent.top = 0;
633 dc->totalExtent.right = GetDeviceCaps( dc->hSelf, HORZRES );
634 dc->totalExtent.bottom = GetDeviceCaps( dc->hSelf, VERTRES );
635 dc->hVisRgn = CreateRectRgnIndirect( &dc->totalExtent );
637 DC_InitDC( dc );
638 hdc = dc->hSelf;
639 GDI_ReleaseObj( hdc );
640 return hdc;
644 /***********************************************************************
645 * CreateDCW (GDI32.@)
647 HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
648 const DEVMODEW *initData )
650 LPSTR driverA = HEAP_strdupWtoA( GetProcessHeap(), 0, driver );
651 LPSTR deviceA = HEAP_strdupWtoA( GetProcessHeap(), 0, device );
652 LPSTR outputA = HEAP_strdupWtoA( GetProcessHeap(), 0, output );
653 HDC res = CreateDCA( driverA, deviceA, outputA,
654 (const DEVMODEA *)initData /*FIXME*/ );
655 HeapFree( GetProcessHeap(), 0, driverA );
656 HeapFree( GetProcessHeap(), 0, deviceA );
657 HeapFree( GetProcessHeap(), 0, outputA );
658 return res;
662 /***********************************************************************
663 * CreateIC (GDI.153)
665 HDC16 WINAPI CreateIC16( LPCSTR driver, LPCSTR device, LPCSTR output,
666 const DEVMODEA* initData )
668 /* Nothing special yet for ICs */
669 return CreateDC16( driver, device, output, initData );
673 /***********************************************************************
674 * CreateICA (GDI32.@)
676 HDC WINAPI CreateICA( LPCSTR driver, LPCSTR device, LPCSTR output,
677 const DEVMODEA* initData )
679 /* Nothing special yet for ICs */
680 return CreateDCA( driver, device, output, initData );
684 /***********************************************************************
685 * CreateICW (GDI32.@)
687 HDC WINAPI CreateICW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
688 const DEVMODEW* initData )
690 /* Nothing special yet for ICs */
691 return CreateDCW( driver, device, output, initData );
695 /***********************************************************************
696 * CreateCompatibleDC (GDI.52)
698 HDC16 WINAPI CreateCompatibleDC16( HDC16 hdc )
700 return (HDC16)CreateCompatibleDC( hdc );
704 /***********************************************************************
705 * CreateCompatibleDC (GDI32.@)
707 HDC WINAPI CreateCompatibleDC( HDC hdc )
709 DC *dc, *origDC;
710 const DC_FUNCTIONS *funcs;
712 GDI_CheckNotLock();
714 if ((origDC = GDI_GetObjPtr( hdc, DC_MAGIC )))
716 funcs = origDC->funcs;
717 GDI_ReleaseObj( hdc ); /* can't hold the lock while loading the driver */
718 funcs = DRIVER_get_driver( funcs );
720 else funcs = DRIVER_load_driver( "DISPLAY" );
722 if (!funcs) return 0;
724 if (!(dc = DC_AllocDC( funcs )))
726 DRIVER_release_driver( funcs );
727 return 0;
730 TRACE("(%04x): returning %04x\n",
731 hdc, dc->hSelf );
733 dc->flags = DC_MEMORY;
734 dc->bitsPerPixel = 1;
735 dc->hBitmap = GetStockObject( DEFAULT_BITMAP );
737 /* Copy the driver-specific physical device info into
738 * the new DC. The driver may use this read-only info
739 * while creating the compatible DC below. */
740 if ((origDC = GDI_GetObjPtr( hdc, DC_MAGIC ))) dc->physDev = origDC->physDev;
742 if (dc->funcs->pCreateDC &&
743 !dc->funcs->pCreateDC( dc, NULL, NULL, NULL, NULL ))
745 WARN("creation aborted by device\n");
746 GDI_FreeObject( dc->hSelf, dc );
747 if (origDC) GDI_ReleaseObj( hdc );
748 DRIVER_release_driver( funcs );
749 return 0;
752 dc->totalExtent.left = 0;
753 dc->totalExtent.top = 0;
754 dc->totalExtent.right = 1; /* default bitmap is 1x1 */
755 dc->totalExtent.bottom = 1;
756 dc->hVisRgn = CreateRectRgnIndirect( &dc->totalExtent );
758 DC_InitDC( dc );
759 GDI_ReleaseObj( dc->hSelf );
760 if (origDC) GDI_ReleaseObj( hdc );
761 return dc->hSelf;
765 /***********************************************************************
766 * DeleteDC (GDI.68)
768 BOOL16 WINAPI DeleteDC16( HDC16 hdc )
770 return DeleteDC( hdc );
774 /***********************************************************************
775 * DeleteDC (GDI32.@)
777 BOOL WINAPI DeleteDC( HDC hdc )
779 const DC_FUNCTIONS *funcs = NULL;
780 DC * dc;
782 TRACE("%04x\n", hdc );
784 GDI_CheckNotLock();
786 if (!(dc = GDI_GetObjPtr( hdc, DC_MAGIC ))) return FALSE;
788 /* Call hook procedure to check whether is it OK to delete this DC */
789 if (dc->hookThunk && !(dc->flags & (DC_SAVED | DC_MEMORY)))
791 DCHOOKPROC proc = dc->hookThunk;
792 if (proc)
794 DWORD data = dc->dwHookData;
795 GDI_ReleaseObj( hdc );
796 if (!proc( hdc, DCHC_DELETEDC, data, 0 )) return FALSE;
797 if (!(dc = DC_GetDCPtr( hdc ))) return TRUE; /* deleted by the hook */
801 while (dc->saveLevel)
803 DC * dcs;
804 HDC16 hdcs = dc->header.hNext;
805 if (!(dcs = DC_GetDCPtr( hdcs ))) break;
806 dc->header.hNext = dcs->header.hNext;
807 dc->saveLevel--;
808 if (dcs->hClipRgn) DeleteObject( dcs->hClipRgn );
809 if (dcs->hVisRgn) DeleteObject( dcs->hVisRgn );
810 if (dcs->hGCClipRgn) DeleteObject( dcs->hGCClipRgn );
811 PATH_DestroyGdiPath(&dcs->path);
812 GDI_FreeObject( hdcs, dcs );
815 if (!(dc->flags & DC_SAVED))
817 SelectObject( hdc, GetStockObject(BLACK_PEN) );
818 SelectObject( hdc, GetStockObject(WHITE_BRUSH) );
819 SelectObject( hdc, GetStockObject(SYSTEM_FONT) );
820 SelectObject( hdc, GetStockObject(DEFAULT_BITMAP) );
821 funcs = dc->funcs;
822 if (dc->funcs->pDeleteDC) dc->funcs->pDeleteDC(dc->physDev);
825 if (dc->hClipRgn) DeleteObject( dc->hClipRgn );
826 if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
827 if (dc->hGCClipRgn) DeleteObject( dc->hGCClipRgn );
828 PATH_DestroyGdiPath(&dc->path);
830 GDI_FreeObject( hdc, dc );
831 if (funcs) DRIVER_release_driver( funcs ); /* do that after releasing the GDI lock */
832 return TRUE;
836 /***********************************************************************
837 * ResetDC (GDI.376)
839 HDC16 WINAPI ResetDC16( HDC16 hdc, const DEVMODEA *devmode )
841 return ResetDCA(hdc, devmode);
845 /***********************************************************************
846 * ResetDCA (GDI32.@)
848 HDC WINAPI ResetDCA( HDC hdc, const DEVMODEA *devmode )
850 DC *dc;
851 HDC ret = hdc;
853 if ((dc = DC_GetDCPtr( hdc )))
855 if (dc->funcs->pResetDC) ret = dc->funcs->pResetDC( dc->physDev, devmode );
856 GDI_ReleaseObj( hdc );
858 return ret;
862 /***********************************************************************
863 * ResetDCW (GDI32.@)
865 HDC WINAPI ResetDCW( HDC hdc, const DEVMODEW *devmode )
867 return ResetDCA(hdc, (const DEVMODEA*)devmode); /* FIXME */
871 /***********************************************************************
872 * GetDeviceCaps (GDI.80)
874 INT16 WINAPI GetDeviceCaps16( HDC16 hdc, INT16 cap )
876 INT16 ret = GetDeviceCaps( hdc, cap );
877 /* some apps don't expect -1 and think it's a B&W screen */
878 if ((cap == NUMCOLORS) && (ret == -1)) ret = 2048;
879 return ret;
883 /***********************************************************************
884 * GetDeviceCaps (GDI32.@)
886 INT WINAPI GetDeviceCaps( HDC hdc, INT cap )
888 DC *dc;
889 INT ret = 0;
891 if ((dc = DC_GetDCPtr( hdc )))
893 if (dc->funcs->pGetDeviceCaps) ret = dc->funcs->pGetDeviceCaps( dc->physDev, cap );
894 GDI_ReleaseObj( hdc );
896 return ret;
900 /***********************************************************************
901 * SetBkColor (GDI.1)
903 COLORREF WINAPI SetBkColor16( HDC16 hdc, COLORREF color )
905 return SetBkColor( hdc, color );
909 /***********************************************************************
910 * SetBkColor (GDI32.@)
912 COLORREF WINAPI SetBkColor( HDC hdc, COLORREF color )
914 COLORREF oldColor;
915 DC * dc = DC_GetDCPtr( hdc );
917 if (!dc) return CLR_INVALID;
918 oldColor = dc->backgroundColor;
919 if (dc->funcs->pSetBkColor)
921 color = dc->funcs->pSetBkColor(dc->physDev, color);
922 if (color == CLR_INVALID) /* don't change it */
924 color = oldColor;
925 oldColor = CLR_INVALID;
928 dc->backgroundColor = color;
929 GDI_ReleaseObj( hdc );
930 return oldColor;
934 /***********************************************************************
935 * SetTextColor (GDI.9)
937 COLORREF WINAPI SetTextColor16( HDC16 hdc, COLORREF color )
939 return SetTextColor( hdc, color );
943 /***********************************************************************
944 * SetTextColor (GDI32.@)
946 COLORREF WINAPI SetTextColor( HDC hdc, COLORREF color )
948 COLORREF oldColor;
949 DC * dc = DC_GetDCPtr( hdc );
951 if (!dc) return CLR_INVALID;
952 oldColor = dc->textColor;
953 if (dc->funcs->pSetTextColor)
955 color = dc->funcs->pSetTextColor(dc->physDev, color);
956 if (color == CLR_INVALID) /* don't change it */
958 color = oldColor;
959 oldColor = CLR_INVALID;
962 dc->textColor = color;
963 GDI_ReleaseObj( hdc );
964 return oldColor;
967 /***********************************************************************
968 * SetTextAlign (GDI.346)
970 UINT16 WINAPI SetTextAlign16( HDC16 hdc, UINT16 align )
972 return SetTextAlign( hdc, align );
976 /***********************************************************************
977 * SetTextAlign (GDI32.@)
979 UINT WINAPI SetTextAlign( HDC hdc, UINT align )
981 UINT prevAlign;
982 DC *dc = DC_GetDCPtr( hdc );
983 if (!dc) return 0x0;
984 if (dc->funcs->pSetTextAlign)
985 prevAlign = dc->funcs->pSetTextAlign(dc->physDev, align);
986 else {
987 prevAlign = dc->textAlign;
988 dc->textAlign = align;
990 GDI_ReleaseObj( hdc );
991 return prevAlign;
994 /***********************************************************************
995 * GetDCOrgEx (GDI32.@)
997 BOOL WINAPI GetDCOrgEx( HDC hDC, LPPOINT lpp )
999 DC * dc;
1001 if (!lpp) return FALSE;
1002 if (!(dc = DC_GetDCPtr( hDC ))) return FALSE;
1004 lpp->x = lpp->y = 0;
1005 if (dc->funcs->pGetDCOrgEx) dc->funcs->pGetDCOrgEx( dc->physDev, lpp );
1006 lpp->x += dc->DCOrgX;
1007 lpp->y += dc->DCOrgY;
1008 GDI_ReleaseObj( hDC );
1009 return TRUE;
1013 /***********************************************************************
1014 * GetDCOrg (GDI.79)
1016 DWORD WINAPI GetDCOrg16( HDC16 hdc )
1018 POINT pt;
1019 if( GetDCOrgEx( hdc, &pt) )
1020 return MAKELONG( (WORD)pt.x, (WORD)pt.y );
1021 return 0;
1025 /***********************************************************************
1026 * SetDCOrg (GDI.117)
1028 DWORD WINAPI SetDCOrg16( HDC16 hdc, INT16 x, INT16 y )
1030 DWORD prevOrg;
1031 DC *dc = DC_GetDCPtr( hdc );
1032 if (!dc) return 0;
1033 prevOrg = dc->DCOrgX | (dc->DCOrgY << 16);
1034 dc->DCOrgX = x;
1035 dc->DCOrgY = y;
1036 GDI_ReleaseObj( hdc );
1037 return prevOrg;
1041 /***********************************************************************
1042 * SetGraphicsMode (GDI32.@)
1044 INT WINAPI SetGraphicsMode( HDC hdc, INT mode )
1046 INT ret = 0;
1047 DC *dc = DC_GetDCPtr( hdc );
1049 /* One would think that setting the graphics mode to GM_COMPATIBLE
1050 * would also reset the world transformation matrix to the unity
1051 * matrix. However, in Windows, this is not the case. This doesn't
1052 * make a lot of sense to me, but that's the way it is.
1054 if (!dc) return 0;
1055 if ((mode > 0) || (mode <= GM_LAST))
1057 ret = dc->GraphicsMode;
1058 dc->GraphicsMode = mode;
1060 GDI_ReleaseObj( hdc );
1061 return ret;
1065 /***********************************************************************
1066 * SetArcDirection (GDI.525)
1068 INT16 WINAPI SetArcDirection16( HDC16 hdc, INT16 nDirection )
1070 return SetArcDirection( (HDC)hdc, (INT)nDirection );
1074 /***********************************************************************
1075 * SetArcDirection (GDI32.@)
1077 INT WINAPI SetArcDirection( HDC hdc, INT nDirection )
1079 DC * dc;
1080 INT nOldDirection = 0;
1082 if (nDirection!=AD_COUNTERCLOCKWISE && nDirection!=AD_CLOCKWISE)
1084 SetLastError(ERROR_INVALID_PARAMETER);
1085 return 0;
1088 if ((dc = DC_GetDCPtr( hdc )))
1090 nOldDirection = dc->ArcDirection;
1091 dc->ArcDirection = nDirection;
1092 GDI_ReleaseObj( hdc );
1094 return nOldDirection;
1098 /***********************************************************************
1099 * GetWorldTransform (GDI32.@)
1101 BOOL WINAPI GetWorldTransform( HDC hdc, LPXFORM xform )
1103 DC * dc;
1104 if (!xform) return FALSE;
1105 if (!(dc = DC_GetDCPtr( hdc ))) return FALSE;
1106 *xform = dc->xformWorld2Wnd;
1107 GDI_ReleaseObj( hdc );
1108 return TRUE;
1112 /***********************************************************************
1113 * SetWorldTransform (GDI32.@)
1115 BOOL WINAPI SetWorldTransform( HDC hdc, const XFORM *xform )
1117 BOOL ret = FALSE;
1118 DC *dc = DC_GetDCPtr( hdc );
1120 if (!dc) return FALSE;
1121 if (!xform) goto done;
1123 /* Check that graphics mode is GM_ADVANCED */
1124 if (dc->GraphicsMode!=GM_ADVANCED) goto done;
1126 dc->xformWorld2Wnd = *xform;
1127 DC_UpdateXforms( dc );
1128 ret = TRUE;
1129 done:
1130 GDI_ReleaseObj( hdc );
1131 return ret;
1135 /****************************************************************************
1136 * ModifyWorldTransform [GDI32.@]
1137 * Modifies the world transformation for a device context.
1139 * PARAMS
1140 * hdc [I] Handle to device context
1141 * xform [I] XFORM structure that will be used to modify the world
1142 * transformation
1143 * iMode [I] Specifies in what way to modify the world transformation
1144 * Possible values:
1145 * MWT_IDENTITY
1146 * Resets the world transformation to the identity matrix.
1147 * The parameter xform is ignored.
1148 * MWT_LEFTMULTIPLY
1149 * Multiplies xform into the world transformation matrix from
1150 * the left.
1151 * MWT_RIGHTMULTIPLY
1152 * Multiplies xform into the world transformation matrix from
1153 * the right.
1155 * RETURNS STD
1157 BOOL WINAPI ModifyWorldTransform( HDC hdc, const XFORM *xform,
1158 DWORD iMode )
1160 BOOL ret = FALSE;
1161 DC *dc = DC_GetDCPtr( hdc );
1163 /* Check for illegal parameters */
1164 if (!dc) return FALSE;
1165 if (!xform) goto done;
1167 /* Check that graphics mode is GM_ADVANCED */
1168 if (dc->GraphicsMode!=GM_ADVANCED) goto done;
1170 switch (iMode)
1172 case MWT_IDENTITY:
1173 dc->xformWorld2Wnd.eM11 = 1.0f;
1174 dc->xformWorld2Wnd.eM12 = 0.0f;
1175 dc->xformWorld2Wnd.eM21 = 0.0f;
1176 dc->xformWorld2Wnd.eM22 = 1.0f;
1177 dc->xformWorld2Wnd.eDx = 0.0f;
1178 dc->xformWorld2Wnd.eDy = 0.0f;
1179 break;
1180 case MWT_LEFTMULTIPLY:
1181 CombineTransform( &dc->xformWorld2Wnd, xform,
1182 &dc->xformWorld2Wnd );
1183 break;
1184 case MWT_RIGHTMULTIPLY:
1185 CombineTransform( &dc->xformWorld2Wnd, &dc->xformWorld2Wnd,
1186 xform );
1187 break;
1188 default:
1189 goto done;
1192 DC_UpdateXforms( dc );
1193 ret = TRUE;
1194 done:
1195 GDI_ReleaseObj( hdc );
1196 return ret;
1200 /****************************************************************************
1201 * CombineTransform [GDI32.@]
1202 * Combines two transformation matrices.
1204 * PARAMS
1205 * xformResult [O] Stores the result of combining the two matrices
1206 * xform1 [I] Specifies the first matrix to apply
1207 * xform2 [I] Specifies the second matrix to apply
1209 * REMARKS
1210 * The same matrix can be passed in for more than one of the parameters.
1212 * RETURNS STD
1214 BOOL WINAPI CombineTransform( LPXFORM xformResult, const XFORM *xform1,
1215 const XFORM *xform2 )
1217 XFORM xformTemp;
1219 /* Check for illegal parameters */
1220 if (!xformResult || !xform1 || !xform2)
1221 return FALSE;
1223 /* Create the result in a temporary XFORM, since xformResult may be
1224 * equal to xform1 or xform2 */
1225 xformTemp.eM11 = xform1->eM11 * xform2->eM11 +
1226 xform1->eM12 * xform2->eM21;
1227 xformTemp.eM12 = xform1->eM11 * xform2->eM12 +
1228 xform1->eM12 * xform2->eM22;
1229 xformTemp.eM21 = xform1->eM21 * xform2->eM11 +
1230 xform1->eM22 * xform2->eM21;
1231 xformTemp.eM22 = xform1->eM21 * xform2->eM12 +
1232 xform1->eM22 * xform2->eM22;
1233 xformTemp.eDx = xform1->eDx * xform2->eM11 +
1234 xform1->eDy * xform2->eM21 +
1235 xform2->eDx;
1236 xformTemp.eDy = xform1->eDx * xform2->eM12 +
1237 xform1->eDy * xform2->eM22 +
1238 xform2->eDy;
1240 /* Copy the result to xformResult */
1241 *xformResult = xformTemp;
1243 return TRUE;
1247 /***********************************************************************
1248 * SetDCHook (GDI32.@)
1250 * Note: this doesn't exist in Win32, we add it here because user32 needs it.
1252 BOOL WINAPI SetDCHook( HDC hdc, DCHOOKPROC hookProc, DWORD dwHookData )
1254 DC *dc = DC_GetDCPtr( hdc );
1256 if (!dc) return FALSE;
1257 dc->dwHookData = dwHookData;
1258 dc->hookThunk = hookProc;
1259 GDI_ReleaseObj( hdc );
1260 return TRUE;
1264 /* relay function to call the 16-bit DC hook proc */
1265 static BOOL16 WINAPI call_dc_hook16( HDC16 hdc, WORD code, DWORD data, LPARAM lParam )
1267 FARPROC16 proc = NULL;
1268 DC *dc = DC_GetDCPtr( hdc );
1269 if (!dc) return FALSE;
1270 proc = dc->hookProc;
1271 GDI_ReleaseObj( hdc );
1272 if (!proc) return FALSE;
1273 return GDI_CallTo16_word_wwll( proc, hdc, code, data, lParam );
1276 /***********************************************************************
1277 * SetDCHook (GDI.190)
1279 BOOL16 WINAPI SetDCHook16( HDC16 hdc, FARPROC16 hookProc, DWORD dwHookData )
1281 DC *dc = DC_GetDCPtr( hdc );
1282 if (!dc) return FALSE;
1284 dc->hookProc = hookProc;
1285 GDI_ReleaseObj( hdc );
1286 return SetDCHook( hdc, call_dc_hook16, dwHookData );
1290 /***********************************************************************
1291 * GetDCHook (GDI.191)
1293 DWORD WINAPI GetDCHook( HDC16 hdc, FARPROC16 *phookProc )
1295 DC *dc = DC_GetDCPtr( hdc );
1296 if (!dc) return 0;
1297 *phookProc = dc->hookProc;
1298 GDI_ReleaseObj( hdc );
1299 return dc->dwHookData;
1303 /***********************************************************************
1304 * SetHookFlags (GDI.192)
1306 WORD WINAPI SetHookFlags16(HDC16 hDC, WORD flags)
1308 DC *dc = DC_GetDCPtr( hDC );
1310 if( dc )
1312 WORD wRet = dc->flags & DC_DIRTY;
1314 /* "Undocumented Windows" info is slightly confusing.
1317 TRACE("hDC %04x, flags %04x\n",hDC,flags);
1319 if( flags & DCHF_INVALIDATEVISRGN )
1320 dc->flags |= DC_DIRTY;
1321 else if( flags & DCHF_VALIDATEVISRGN || !flags )
1322 dc->flags &= ~DC_DIRTY;
1323 GDI_ReleaseObj( hDC );
1324 return wRet;
1326 return 0;
1329 /***********************************************************************
1330 * SetICMMode (GDI32.@)
1332 INT WINAPI SetICMMode(HDC hdc, INT iEnableICM)
1334 /*FIXME Asuming that ICM is always off, and cannot be turned on */
1335 if (iEnableICM == ICM_OFF) return ICM_OFF;
1336 if (iEnableICM == ICM_ON) return 0;
1337 if (iEnableICM == ICM_QUERY) return ICM_OFF;
1338 return 0;
1341 /***********************************************************************
1342 * GetDeviceGammaRamp (GDI32.@)
1344 BOOL WINAPI GetDeviceGammaRamp(HDC hDC, LPVOID ptr)
1346 BOOL ret = FALSE;
1347 DC *dc = DC_GetDCPtr( hDC );
1349 if( dc )
1351 if (dc->funcs->pGetDeviceGammaRamp)
1352 ret = dc->funcs->pGetDeviceGammaRamp(dc->physDev, ptr);
1353 GDI_ReleaseObj( hDC );
1355 return ret;
1358 /***********************************************************************
1359 * SetDeviceGammaRamp (GDI32.@)
1361 BOOL WINAPI SetDeviceGammaRamp(HDC hDC, LPVOID ptr)
1363 BOOL ret = FALSE;
1364 DC *dc = DC_GetDCPtr( hDC );
1366 if( dc )
1368 if (dc->funcs->pSetDeviceGammaRamp)
1369 ret = dc->funcs->pSetDeviceGammaRamp(dc->physDev, ptr);
1370 GDI_ReleaseObj( hDC );
1372 return ret;
1375 /***********************************************************************
1376 * GetColorSpace (GDI32.@)
1378 HCOLORSPACE WINAPI GetColorSpace(HDC hdc)
1380 /*FIXME Need to to whatever GetColorSpace actually does */
1381 return 0;
1384 /***********************************************************************
1385 * CreateColorSpaceA (GDI32.@)
1387 HCOLORSPACE WINAPI CreateColorSpaceA( LPLOGCOLORSPACEA lpLogColorSpace )
1389 FIXME( "stub\n" );
1390 return 0;
1393 /***********************************************************************
1394 * CreateColorSpaceW (GDI32.@)
1396 HCOLORSPACE WINAPI CreateColorSpaceW( LPLOGCOLORSPACEW lpLogColorSpace )
1398 FIXME( "stub\n" );
1399 return 0;
1402 /***********************************************************************
1403 * DeleteColorSpace (GDI32.@)
1405 BOOL WINAPI DeleteColorSpace( HCOLORSPACE hColorSpace )
1407 FIXME( "stub\n" );
1409 return TRUE;
1412 /***********************************************************************
1413 * SetColorSpace (GDI32.@)
1415 HCOLORSPACE WINAPI SetColorSpace( HDC hDC, HCOLORSPACE hColorSpace )
1417 FIXME( "stub\n" );
1419 return hColorSpace;
1422 /***********************************************************************
1423 * GetBoundsRect (GDI.194)
1425 UINT16 WINAPI GetBoundsRect16(HDC16 hdc, LPRECT16 rect, UINT16 flags)
1427 return DCB_RESET | DCB_DISABLE; /* bounding rectangle always empty and disabled*/
1430 /***********************************************************************
1431 * GetBoundsRect (GDI32.@)
1433 UINT WINAPI GetBoundsRect(HDC hdc, LPRECT rect, UINT flags)
1435 FIXME("(): stub\n");
1436 return DCB_RESET; /* bounding rectangle always empty */
1439 /***********************************************************************
1440 * SetBoundsRect (GDI.193)
1442 UINT16 WINAPI SetBoundsRect16(HDC16 hdc, const RECT16* rect, UINT16 flags)
1444 if ( (flags & DCB_ACCUMULATE) || (flags & DCB_ENABLE) )
1445 FIXME("(%04x, %p, %04x): stub\n", hdc, rect, flags );
1447 return DCB_RESET | DCB_DISABLE; /* bounding rectangle always empty and disabled*/
1450 /***********************************************************************
1451 * SetBoundsRect (GDI32.@)
1453 UINT WINAPI SetBoundsRect(HDC hdc, const RECT* rect, UINT flags)
1455 FIXME("(): stub\n");
1456 return DCB_DISABLE; /* bounding rectangle always empty */
1460 /***********************************************************************
1461 * GetRelAbs (GDI32.@)
1463 INT WINAPI GetRelAbs( HDC hdc, DWORD dwIgnore )
1465 INT ret = 0;
1466 DC *dc = DC_GetDCPtr( hdc );
1467 if (dc) ret = dc->relAbsMode;
1468 GDI_ReleaseObj( hdc );
1469 return ret;
1472 /***********************************************************************
1473 * Death (GDI.121)
1475 * Disables GDI, switches back to text mode.
1476 * We don't have to do anything here,
1477 * just let console support handle everything
1479 void WINAPI Death16(HDC16 hDC)
1481 MESSAGE("Death(%04x) called. Application enters text mode...\n", hDC);
1484 /***********************************************************************
1485 * Resurrection (GDI.122)
1487 * Restores GDI functionality
1489 void WINAPI Resurrection16(HDC16 hDC,
1490 WORD w1, WORD w2, WORD w3, WORD w4, WORD w5, WORD w6)
1492 MESSAGE("Resurrection(%04x, %04x, %04x, %04x, %04x, %04x, %04x) called. Application left text mode.\n", hDC, w1, w2, w3, w4, w5, w6);
1495 /***********************************************************************
1496 * GetLayout (GDI32.@)
1498 * Gets left->right or right->left text layout flags of a dc.
1499 * win98 just returns 0 and sets ERROR_CALL_NOT_IMPLEMENTED so we do the same
1502 DWORD WINAPI GetLayout(HDC hdc)
1504 FIXME("(%08x): stub\n", hdc);
1505 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1506 return 0;
1509 /***********************************************************************
1510 * SetLayout (GDI32.@)
1512 * Sets left->right or right->left text layout flags of a dc.
1513 * win98 just returns 0 and sets ERROR_CALL_NOT_IMPLEMENTED so we do the same
1516 DWORD WINAPI SetLayout(HDC hdc, DWORD layout)
1518 FIXME("(%08x,%08lx): stub\n", hdc, layout);
1519 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1520 return 0;