- Less STDCALL, more WINAPI/NTAPI/APIENTRY
[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 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
46 #if 0
47 BOOL APIENTRY NtGdi##FuncName ( HDC hdc, LP##type pt ) \
48 { \
49 NTSTATUS Status = STATUS_SUCCESS; \
50 type Safept; \
51 PDC dc; \
52 if(!pt) \
53 { \
54 SetLastWin32Error(ERROR_INVALID_PARAMETER); \
55 return FALSE; \
56 } \
57 if(!(dc = DC_LockDc(hdc))) \
58 { \
59 SetLastWin32Error(ERROR_INVALID_HANDLE); \
60 return FALSE; \
61 } \
62 Int##FuncName( dc, &Safept); \
63 DC_UnlockDc(dc); \
64 _SEH_TRY \
65 { \
66 ProbeForWrite(pt, \
67 sizeof( type ), \
68 1); \
69 *pt = Safept; \
70 } \
71 _SEH_HANDLE \
72 { \
73 Status = _SEH_GetExceptionCode(); \
74 } \
75 _SEH_END; \
76 if(!NT_SUCCESS(Status)) \
77 { \
78 SetLastNtError(Status); \
79 return FALSE; \
80 } \
81 return TRUE; \
82 }
83 #endif
84
85 #define DC_SET_MODE( func_name, dc_field, min_val, max_val ) \
86 INT APIENTRY func_name( HDC hdc, INT mode ) \
87 { \
88 INT prevMode; \
89 PDC dc; \
90 PDC_ATTR Dc_Attr; \
91 if ((mode < min_val) || (mode > max_val)) \
92 { \
93 SetLastWin32Error(ERROR_INVALID_PARAMETER); \
94 return 0; \
95 } \
96 dc = DC_LockDc ( hdc ); \
97 if ( !dc ) \
98 { \
99 SetLastWin32Error(ERROR_INVALID_HANDLE); \
100 return 0; \
101 } \
102 Dc_Attr = dc->pDc_Attr; \
103 if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr; \
104 prevMode = Dc_Attr->dc_field; \
105 Dc_Attr->dc_field = mode; \
106 DC_UnlockDc ( dc ); \
107 return prevMode; \
108 }
109
110
111 static
112 VOID
113 CopytoUserDcAttr(PDC dc, PDC_ATTR Dc_Attr)
114 {
115 NTSTATUS Status = STATUS_SUCCESS;
116 dc->Dc_Attr.mxWorldToDevice = dc->DcLevel.mxWorldToDevice;
117 dc->Dc_Attr.mxDeviceToWorld = dc->DcLevel.mxDeviceToWorld;
118 dc->Dc_Attr.mxWorldToPage = dc->DcLevel.mxWorldToPage;
119
120 _SEH_TRY
121 {
122 ProbeForWrite( Dc_Attr,
123 sizeof(DC_ATTR),
124 1);
125 RtlCopyMemory( Dc_Attr,
126 &dc->Dc_Attr,
127 sizeof(DC_ATTR));
128 }
129 _SEH_HANDLE
130 {
131 Status = _SEH_GetExceptionCode();
132 }
133 _SEH_END;
134 }
135
136
137 BOOL
138 FASTCALL
139 DCU_SyncDcAttrtoUser(PDC dc)
140 {
141 PDC_ATTR Dc_Attr = dc->pDc_Attr;
142
143 if (Dc_Attr == ((PDC_ATTR)&dc->Dc_Attr)) return TRUE; // No need to copy self.
144
145 if (!Dc_Attr) return FALSE;
146 else
147 CopytoUserDcAttr( dc, Dc_Attr);
148 return TRUE;
149 }
150
151 BOOL
152 FASTCALL
153 DCU_SynchDcAttrtoUser(HDC hDC)
154 {
155 BOOL Ret;
156 PDC pDC = DC_LockDc ( hDC );
157 if (!pDC) return FALSE;
158 Ret = DCU_SyncDcAttrtoUser(pDC);
159 DC_UnlockDc( pDC );
160 return Ret;
161 }
162
163
164 DC_GET_VAL( INT, IntGdiGetMapMode, iMapMode )
165 DC_GET_VAL( INT, IntGdiGetPolyFillMode, jFillMode )
166 DC_GET_VAL( COLORREF, IntGdiGetBkColor, crBackgroundClr )
167 DC_GET_VAL( INT, IntGdiGetBkMode, jBkMode )
168 DC_GET_VAL( INT, IntGdiGetROP2, jROP2 )
169 DC_GET_VAL( INT, IntGdiGetStretchBltMode, jStretchBltMode )
170 DC_GET_VAL( UINT, IntGdiGetTextAlign, lTextAlign )
171 DC_GET_VAL( COLORREF, IntGdiGetTextColor, crForegroundClr )
172
173 DC_GET_VAL_EX( GetViewportExtEx, szlViewportExt.cx, szlViewportExt.cy, SIZE, cx, cy )
174 DC_GET_VAL_EX( GetViewportOrgEx, ptlViewportOrg.x, ptlViewportOrg.y, POINT, x, y )
175 DC_GET_VAL_EX( GetWindowExtEx, szlWindowExt.cx, szlWindowExt.cy, SIZE, cx, cy )
176 DC_GET_VAL_EX( GetWindowOrgEx, ptlWindowOrg.x, ptlWindowOrg.y, POINT, x, y )
177
178 DC_SET_MODE( IntGdiSetPolyFillMode, jFillMode, ALTERNATE, WINDING )
179 DC_SET_MODE( IntGdiSetROP2, jROP2, R2_BLACK, R2_WHITE )
180 DC_SET_MODE( IntGdiSetStretchBltMode, jStretchBltMode, BLACKONWHITE, HALFTONE )
181
182
183
184 COLORREF FASTCALL
185 IntGdiSetBkColor(HDC hDC, COLORREF color)
186 {
187 COLORREF oldColor;
188 PDC dc;
189 PDC_ATTR Dc_Attr;
190 HBRUSH hBrush;
191
192 if (!(dc = DC_LockDc(hDC)))
193 {
194 SetLastWin32Error(ERROR_INVALID_HANDLE);
195 return CLR_INVALID;
196 }
197 Dc_Attr = dc->pDc_Attr;
198 if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
199 oldColor = Dc_Attr->crBackgroundClr;
200 Dc_Attr->crBackgroundClr = color;
201 Dc_Attr->ulBackgroundClr = (ULONG)color;
202 Dc_Attr->ulDirty_ &= ~(DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL); // Clear Flag if set.
203 hBrush = Dc_Attr->hbrush;
204 DC_UnlockDc(dc);
205 NtGdiSelectBrush(hDC, hBrush);
206 return oldColor;
207 }
208
209 INT FASTCALL
210 IntGdiSetBkMode(HDC hDC, INT Mode)
211 {
212 COLORREF oldMode;
213 PDC dc;
214 PDC_ATTR Dc_Attr;
215
216 if (!(dc = DC_LockDc(hDC)))
217 {
218 SetLastWin32Error(ERROR_INVALID_HANDLE);
219 return CLR_INVALID;
220 }
221 Dc_Attr = dc->pDc_Attr;
222 if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
223 oldMode = Dc_Attr->lBkMode;
224 Dc_Attr->jBkMode = Mode;
225 Dc_Attr->lBkMode = Mode;
226 DC_UnlockDc(dc);
227 return oldMode;
228 }
229
230 UINT
231 FASTCALL
232 IntGdiSetTextAlign(HDC hDC,
233 UINT Mode)
234 {
235 UINT prevAlign;
236 DC *dc;
237 PDC_ATTR Dc_Attr;
238
239 dc = DC_LockDc(hDC);
240 if (!dc)
241 {
242 SetLastWin32Error(ERROR_INVALID_HANDLE);
243 return GDI_ERROR;
244 }
245 Dc_Attr = dc->pDc_Attr;
246 if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
247 prevAlign = Dc_Attr->lTextAlign;
248 Dc_Attr->lTextAlign = Mode;
249 DC_UnlockDc( dc );
250 return prevAlign;
251 }
252
253 COLORREF
254 FASTCALL
255 IntGdiSetTextColor(HDC hDC,
256 COLORREF color)
257 {
258 COLORREF oldColor;
259 PDC dc = DC_LockDc(hDC);
260 PDC_ATTR Dc_Attr;
261 HBRUSH hBrush;
262
263 if (!dc)
264 {
265 SetLastWin32Error(ERROR_INVALID_HANDLE);
266 return CLR_INVALID;
267 }
268 Dc_Attr = dc->pDc_Attr;
269 if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
270
271 oldColor = Dc_Attr->crForegroundClr;
272 Dc_Attr->crForegroundClr = color;
273 hBrush = Dc_Attr->hbrush;
274 Dc_Attr->ulDirty_ &= ~(DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL);
275 DC_UnlockDc( dc );
276 NtGdiSelectBrush(hDC, hBrush);
277 return oldColor;
278 }
279
280 VOID
281 FASTCALL
282 DCU_SetDcUndeletable(HDC hDC)
283 {
284 PDC dc = DC_LockDc(hDC);
285 if (!dc)
286 {
287 SetLastWin32Error(ERROR_INVALID_HANDLE);
288 return;
289 }
290
291 dc->DC_Flags |= DC_FLAG_PERMANENT;
292 DC_UnlockDc( dc );
293 return;
294 }