rename DCs pDc_Attr to pdcattr, like in gdikdx.
[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 APIENTRY func_name( HDC hdc ) \
14 { \
15 func_type ft; \
16 PDC dc = DC_LockDc( hdc ); \
17 PDC_ATTR pdcattr; \
18 if (!dc) \
19 { \
20 SetLastWin32Error(ERROR_INVALID_HANDLE); \
21 return 0; \
22 } \
23 pdcattr = dc->pdcattr; \
24 ft = pdcattr->dc_field; \
25 DC_UnlockDc(dc); \
26 return ft; \
27 }
28
29 /* DC_GET_VAL_EX is used to define functions returning a POINT or a SIZE. It is
30 * important that the function has the right signature, for the implementation
31 * we can do whatever we want.
32 */
33 #define DC_GET_VAL_EX( FuncName, ret_x, ret_y, type, ax, ay ) \
34 VOID FASTCALL Int##FuncName ( PDC dc, LP##type pt) \
35 { \
36 PDC_ATTR pdcattr; \
37 ASSERT(dc); \
38 ASSERT(pt); \
39 pdcattr = dc->pdcattr; \
40 pt->ax = pdcattr->ret_x; \
41 pt->ay = pdcattr->ret_y; \
42 }
43
44 #if 0
45 BOOL APIENTRY 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 _SEH2_TRY \
63 { \
64 ProbeForWrite(pt, \
65 sizeof( type ), \
66 1); \
67 *pt = Safept; \
68 } \
69 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) \
70 { \
71 Status = _SEH2_GetExceptionCode(); \
72 } \
73 _SEH2_END; \
74 if(!NT_SUCCESS(Status)) \
75 { \
76 SetLastNtError(Status); \
77 return FALSE; \
78 } \
79 return TRUE; \
80 }
81 #endif
82
83 #define DC_SET_MODE( func_name, dc_field, min_val, max_val ) \
84 INT APIENTRY func_name( HDC hdc, INT mode ) \
85 { \
86 INT prevMode; \
87 PDC dc; \
88 PDC_ATTR pdcattr; \
89 if ((mode < min_val) || (mode > max_val)) \
90 { \
91 SetLastWin32Error(ERROR_INVALID_PARAMETER); \
92 return 0; \
93 } \
94 dc = DC_LockDc ( hdc ); \
95 if ( !dc ) \
96 { \
97 SetLastWin32Error(ERROR_INVALID_HANDLE); \
98 return 0; \
99 } \
100 pdcattr = dc->pdcattr; \
101 prevMode = pdcattr->dc_field; \
102 pdcattr->dc_field = mode; \
103 DC_UnlockDc ( dc ); \
104 return prevMode; \
105 }
106
107
108 static
109 VOID
110 CopytoUserDcAttr(PDC dc, PDC_ATTR pdcattr)
111 {
112 NTSTATUS Status = STATUS_SUCCESS;
113 dc->Dc_Attr.mxWorldToDevice = dc->DcLevel.mxWorldToDevice;
114 dc->Dc_Attr.mxDeviceToWorld = dc->DcLevel.mxDeviceToWorld;
115 dc->Dc_Attr.mxWorldToPage = dc->DcLevel.mxWorldToPage;
116
117 _SEH2_TRY
118 {
119 ProbeForWrite( pdcattr,
120 sizeof(DC_ATTR),
121 1);
122 RtlCopyMemory( pdcattr,
123 &dc->Dc_Attr,
124 sizeof(DC_ATTR));
125 }
126 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
127 {
128 Status = _SEH2_GetExceptionCode();
129 ASSERT(FALSE);
130 }
131 _SEH2_END;
132 }
133
134
135 BOOL
136 FASTCALL
137 DCU_SyncDcAttrtoUser(PDC dc)
138 {
139 PDC_ATTR pdcattr = dc->pdcattr;
140
141 if (pdcattr == &dc->Dc_Attr) return TRUE; // No need to copy self.
142 ASSERT(pdcattr);
143 CopytoUserDcAttr( dc, pdcattr);
144 return TRUE;
145 }
146
147 BOOL
148 FASTCALL
149 DCU_SynchDcAttrtoUser(HDC hDC)
150 {
151 BOOL Ret;
152 PDC pDC = DC_LockDc ( hDC );
153 if (!pDC) return FALSE;
154 Ret = DCU_SyncDcAttrtoUser(pDC);
155 DC_UnlockDc( pDC );
156 return Ret;
157 }
158
159
160 DC_GET_VAL( INT, IntGdiGetMapMode, iMapMode )
161 DC_GET_VAL( INT, IntGdiGetPolyFillMode, jFillMode )
162 DC_GET_VAL( COLORREF, IntGdiGetBkColor, crBackgroundClr )
163 DC_GET_VAL( INT, IntGdiGetBkMode, jBkMode )
164 DC_GET_VAL( INT, IntGdiGetROP2, jROP2 )
165 DC_GET_VAL( INT, IntGdiGetStretchBltMode, jStretchBltMode )
166 DC_GET_VAL( UINT, IntGdiGetTextAlign, lTextAlign )
167 DC_GET_VAL( COLORREF, IntGdiGetTextColor, crForegroundClr )
168
169 DC_GET_VAL_EX( GetViewportOrgEx, ptlViewportOrg.x, ptlViewportOrg.y, POINT, x, y )
170 DC_GET_VAL_EX( GetWindowExtEx, szlWindowExt.cx, szlWindowExt.cy, SIZE, cx, cy )
171 DC_GET_VAL_EX( GetWindowOrgEx, ptlWindowOrg.x, ptlWindowOrg.y, POINT, x, y )
172
173 DC_SET_MODE( IntGdiSetPolyFillMode, jFillMode, ALTERNATE, WINDING )
174 DC_SET_MODE( IntGdiSetROP2, jROP2, R2_BLACK, R2_WHITE )
175 DC_SET_MODE( IntGdiSetStretchBltMode, jStretchBltMode, BLACKONWHITE, HALFTONE )
176
177
178
179 COLORREF FASTCALL
180 IntGdiSetBkColor(HDC hDC, COLORREF color)
181 {
182 COLORREF oldColor;
183 PDC dc;
184 PDC_ATTR pdcattr;
185 HBRUSH hBrush;
186
187 if (!(dc = DC_LockDc(hDC)))
188 {
189 SetLastWin32Error(ERROR_INVALID_HANDLE);
190 return CLR_INVALID;
191 }
192 pdcattr = dc->pdcattr;
193 oldColor = pdcattr->crBackgroundClr;
194 pdcattr->crBackgroundClr = color;
195 pdcattr->ulBackgroundClr = (ULONG)color;
196 pdcattr->ulDirty_ &= ~(DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL); // Clear Flag if set.
197 hBrush = pdcattr->hbrush;
198 DC_UnlockDc(dc);
199 NtGdiSelectBrush(hDC, hBrush);
200 return oldColor;
201 }
202
203 INT FASTCALL
204 IntGdiSetBkMode(HDC hDC, INT Mode)
205 {
206 COLORREF oldMode;
207 PDC dc;
208 PDC_ATTR pdcattr;
209
210 if (!(dc = DC_LockDc(hDC)))
211 {
212 SetLastWin32Error(ERROR_INVALID_HANDLE);
213 return CLR_INVALID;
214 }
215 pdcattr = dc->pdcattr;
216 oldMode = pdcattr->lBkMode;
217 pdcattr->jBkMode = Mode;
218 pdcattr->lBkMode = Mode;
219 DC_UnlockDc(dc);
220 return oldMode;
221 }
222
223 UINT
224 FASTCALL
225 IntGdiSetTextAlign(HDC hDC,
226 UINT Mode)
227 {
228 UINT prevAlign;
229 DC *dc;
230 PDC_ATTR pdcattr;
231
232 dc = DC_LockDc(hDC);
233 if (!dc)
234 {
235 SetLastWin32Error(ERROR_INVALID_HANDLE);
236 return GDI_ERROR;
237 }
238 pdcattr = dc->pdcattr;
239 prevAlign = pdcattr->lTextAlign;
240 pdcattr->lTextAlign = Mode;
241 DC_UnlockDc( dc );
242 return prevAlign;
243 }
244
245 COLORREF
246 FASTCALL
247 IntGdiSetTextColor(HDC hDC,
248 COLORREF color)
249 {
250 COLORREF oldColor;
251 PDC dc = DC_LockDc(hDC);
252 PDC_ATTR pdcattr;
253 HBRUSH hBrush;
254
255 if (!dc)
256 {
257 SetLastWin32Error(ERROR_INVALID_HANDLE);
258 return CLR_INVALID;
259 }
260 pdcattr = dc->pdcattr;
261
262 oldColor = pdcattr->crForegroundClr;
263 pdcattr->crForegroundClr = color;
264 hBrush = pdcattr->hbrush;
265 pdcattr->ulDirty_ &= ~(DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL);
266 DC_UnlockDc( dc );
267 NtGdiSelectBrush(hDC, hBrush);
268 return oldColor;
269 }
270
271 VOID
272 FASTCALL
273 DCU_SetDcUndeletable(HDC hDC)
274 {
275 PDC dc = DC_LockDc(hDC);
276 if (!dc)
277 {
278 SetLastWin32Error(ERROR_INVALID_HANDLE);
279 return;
280 }
281
282 dc->fs |= DC_FLAG_PERMANENT;
283 DC_UnlockDc( dc );
284 return;
285 }