Bring back ext2 code from branch
[reactos.git] / reactos / subsystems / win32 / win32k / objects / dcutil.c
1
2 #include <w32k.h>
3
4 #define NDEBUG
5 #include <debug.h>
6
7 /*
8 * DC device-independent Get/SetXXX functions
9 * (RJJ) swiped from WINE
10 */
11
12 #define DC_GET_VAL( func_type, func_name, dc_field ) \
13 func_type STDCALL func_name( HDC hdc ) \
14 { \
15 func_type ft; \
16 PDC dc = DC_LockDc( hdc ); \
17 PDC_ATTR Dc_Attr; \
18 if (!dc) \
19 { \
20 SetLastWin32Error(ERROR_INVALID_HANDLE); \
21 return 0; \
22 } \
23 Dc_Attr = dc->pDc_Attr; \
24 if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr; \
25 ft = Dc_Attr->dc_field; \
26 DC_UnlockDc(dc); \
27 return ft; \
28 }
29
30 /* DC_GET_VAL_EX is used to define functions returning a POINT or a SIZE. It is
31 * important that the function has the right signature, for the implementation
32 * we can do whatever we want.
33 */
34 #define DC_GET_VAL_EX( FuncName, ret_x, ret_y, type, ax, ay ) \
35 VOID FASTCALL Int##FuncName ( PDC dc, LP##type pt) \
36 { \
37 PDC_ATTR Dc_Attr; \
38 ASSERT(dc); \
39 ASSERT(pt); \
40 Dc_Attr = dc->pDc_Attr; \
41 if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr; \
42 pt->ax = Dc_Attr->ret_x; \
43 pt->ay = Dc_Attr->ret_y; \
44 } \
45 BOOL STDCALL NtGdi##FuncName ( HDC hdc, LP##type pt ) \
46 { \
47 NTSTATUS Status = STATUS_SUCCESS; \
48 type Safept; \
49 PDC dc; \
50 if(!pt) \
51 { \
52 SetLastWin32Error(ERROR_INVALID_PARAMETER); \
53 return FALSE; \
54 } \
55 if(!(dc = DC_LockDc(hdc))) \
56 { \
57 SetLastWin32Error(ERROR_INVALID_HANDLE); \
58 return FALSE; \
59 } \
60 Int##FuncName( dc, &Safept); \
61 DC_UnlockDc(dc); \
62 _SEH_TRY \
63 { \
64 ProbeForWrite(pt, \
65 sizeof( type ), \
66 1); \
67 *pt = Safept; \
68 } \
69 _SEH_HANDLE \
70 { \
71 Status = _SEH_GetExceptionCode(); \
72 } \
73 _SEH_END; \
74 if(!NT_SUCCESS(Status)) \
75 { \
76 SetLastNtError(Status); \
77 return FALSE; \
78 } \
79 return TRUE; \
80 }
81
82 #define DC_SET_MODE( func_name, dc_field, min_val, max_val ) \
83 INT STDCALL func_name( HDC hdc, INT mode ) \
84 { \
85 INT prevMode; \
86 PDC dc; \
87 PDC_ATTR Dc_Attr; \
88 if ((mode < min_val) || (mode > max_val)) \
89 { \
90 SetLastWin32Error(ERROR_INVALID_PARAMETER); \
91 return 0; \
92 } \
93 dc = DC_LockDc ( hdc ); \
94 if ( !dc ) \
95 { \
96 SetLastWin32Error(ERROR_INVALID_HANDLE); \
97 return 0; \
98 } \
99 Dc_Attr = dc->pDc_Attr; \
100 if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr; \
101 prevMode = Dc_Attr->dc_field; \
102 Dc_Attr->dc_field = mode; \
103 DC_UnlockDc ( dc ); \
104 return prevMode; \
105 }
106
107
108 static
109 VOID
110 CopytoUserDcAttr(PDC dc, PDC_ATTR Dc_Attr)
111 {
112 XForm2MatrixS( &dc->Dc_Attr.mxWorldToDevice, &dc->w.xformWorld2Vport);
113 XForm2MatrixS( &dc->Dc_Attr.mxDevicetoWorld, &dc->w.xformVport2World);
114 XForm2MatrixS( &dc->Dc_Attr.mxWorldToPage, &dc->w.xformWorld2Wnd);
115 MmCopyToCaller(Dc_Attr, &dc->Dc_Attr, sizeof(DC_ATTR));
116 }
117
118
119 BOOL
120 FASTCALL
121 DCU_SyncDcAttrtoUser(PDC dc)
122 {
123 PDC_ATTR Dc_Attr = dc->pDc_Attr;
124
125 if (Dc_Attr == ((PDC_ATTR)&dc->Dc_Attr)) return TRUE; // No need to copy self.
126
127 if (!Dc_Attr) return FALSE;
128 else
129 CopytoUserDcAttr( dc, Dc_Attr);
130 return TRUE;
131 }
132
133 BOOL
134 FASTCALL
135 DCU_SynchDcAttrtoUser(HDC hDC)
136 {
137 BOOL Ret;
138 PDC pDC = DC_LockDc ( hDC );
139 if (!pDC) return FALSE;
140 Ret = DCU_SyncDcAttrtoUser(pDC);
141 DC_UnlockDc( pDC );
142 return Ret;
143 }
144
145
146 DC_GET_VAL( INT, NtGdiGetMapMode, iMapMode )
147 DC_GET_VAL( INT, NtGdiGetPolyFillMode, jFillMode )
148 DC_GET_VAL( COLORREF, NtGdiGetBkColor, crBackgroundClr )
149 DC_GET_VAL( INT, NtGdiGetBkMode, jBkMode )
150 DC_GET_VAL( INT, NtGdiGetROP2, jROP2 )
151 DC_GET_VAL( INT, NtGdiGetStretchBltMode, jStretchBltMode )
152 DC_GET_VAL( UINT, NtGdiGetTextAlign, lTextAlign )
153 DC_GET_VAL( COLORREF, NtGdiGetTextColor, crForegroundClr )
154
155 DC_GET_VAL_EX( GetViewportExtEx, szlViewportExt.cx, szlViewportExt.cy, SIZE, cx, cy )
156 DC_GET_VAL_EX( GetViewportOrgEx, ptlViewportOrg.x, ptlViewportOrg.y, POINT, x, y )
157 DC_GET_VAL_EX( GetWindowExtEx, szlWindowExt.cx, szlWindowExt.cy, SIZE, cx, cy )
158 DC_GET_VAL_EX( GetWindowOrgEx, ptlWindowOrg.x, ptlWindowOrg.y, POINT, x, y )
159
160 DC_SET_MODE( NtGdiSetPolyFillMode, jFillMode, ALTERNATE, WINDING )
161 DC_SET_MODE( NtGdiSetROP2, jROP2, R2_BLACK, R2_WHITE )
162 DC_SET_MODE( NtGdiSetStretchBltMode, jStretchBltMode, BLACKONWHITE, HALFTONE )
163
164
165
166 COLORREF FASTCALL
167 NtGdiSetBkColor(HDC hDC, COLORREF color)
168 {
169 COLORREF oldColor;
170 PDC dc;
171 PDC_ATTR Dc_Attr;
172 HBRUSH hBrush;
173
174 if (!(dc = DC_LockDc(hDC)))
175 {
176 SetLastWin32Error(ERROR_INVALID_HANDLE);
177 return CLR_INVALID;
178 }
179 Dc_Attr = dc->pDc_Attr;
180 if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
181 oldColor = Dc_Attr->crBackgroundClr;
182 Dc_Attr->crBackgroundClr = color;
183 Dc_Attr->ulBackgroundClr = (ULONG)color;
184 Dc_Attr->ulDirty_ &= ~DIRTY_LINE; // Clear Flag if set.
185 hBrush = Dc_Attr->hbrush;
186 DC_UnlockDc(dc);
187 NtGdiSelectBrush(hDC, hBrush);
188 return oldColor;
189 }
190
191 INT FASTCALL
192 NtGdiSetBkMode(HDC hDC, INT Mode)
193 {
194 COLORREF oldMode;
195 PDC dc;
196 PDC_ATTR Dc_Attr;
197
198 if (!(dc = DC_LockDc(hDC)))
199 {
200 SetLastWin32Error(ERROR_INVALID_HANDLE);
201 return CLR_INVALID;
202 }
203 Dc_Attr = dc->pDc_Attr;
204 if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
205 oldMode = Dc_Attr->lBkMode;
206 Dc_Attr->jBkMode = Mode;
207 Dc_Attr->lBkMode = Mode;
208 DC_UnlockDc(dc);
209 return oldMode;
210 }
211
212 UINT
213 FASTCALL
214 NtGdiSetTextAlign(HDC hDC,
215 UINT Mode)
216 {
217 UINT prevAlign;
218 DC *dc;
219 PDC_ATTR Dc_Attr;
220
221 dc = DC_LockDc(hDC);
222 if (!dc)
223 {
224 SetLastWin32Error(ERROR_INVALID_HANDLE);
225 return GDI_ERROR;
226 }
227 Dc_Attr = dc->pDc_Attr;
228 if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
229 prevAlign = Dc_Attr->lTextAlign;
230 Dc_Attr->lTextAlign = Mode;
231 DC_UnlockDc( dc );
232 return prevAlign;
233 }
234
235 COLORREF
236 FASTCALL
237 NtGdiSetTextColor(HDC hDC,
238 COLORREF color)
239 {
240 COLORREF oldColor;
241 PDC dc = DC_LockDc(hDC);
242 PDC_ATTR Dc_Attr;
243 HBRUSH hBrush;
244
245 if (!dc)
246 {
247 SetLastWin32Error(ERROR_INVALID_HANDLE);
248 return CLR_INVALID;
249 }
250 Dc_Attr = dc->pDc_Attr;
251 if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
252
253 oldColor = Dc_Attr->crForegroundClr;
254 Dc_Attr->crForegroundClr = color;
255 hBrush = Dc_Attr->hbrush;
256 DC_UnlockDc( dc );
257 NtGdiSelectBrush(hDC, hBrush);
258 return oldColor;
259 }
260
261 VOID
262 FASTCALL
263 DCU_SetDcUndeletable(HDC hDC)
264 {
265 PDC dc = DC_LockDc(hDC);
266 if (!dc)
267 {
268 SetLastWin32Error(ERROR_INVALID_HANDLE);
269 return;
270 }
271
272 dc->DC_Flags |= DC_FLAG_PERMANENT;
273 DC_UnlockDc( dc );
274 return;
275 }