[gdi32]
[reactos.git] / reactos / dll / win32 / gdi32 / misc / misc.c
1 /*
2 * ReactOS GDI lib
3 * Copyright (C) 2003 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /* $Id$
20 *
21 * PROJECT: ReactOS gdi32.dll
22 * FILE: lib/gdi32/misc/misc.c
23 * PURPOSE: Miscellaneous functions
24 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
25 * UPDATE HISTORY:
26 * 2004/09/04 Created
27 */
28
29 #include "precomp.h"
30
31 #define NDEBUG
32 #include <debug.h>
33
34 PGDI_TABLE_ENTRY GdiHandleTable = NULL;
35 PGDI_SHARED_HANDLE_TABLE GdiSharedHandleTable = NULL;
36 HANDLE CurrentProcessId = NULL;
37 DWORD GDI_BatchLimit = 1;
38
39
40 BOOL
41 WINAPI
42 GdiAlphaBlend(
43 HDC hDCDst,
44 int DstX,
45 int DstY,
46 int DstCx,
47 int DstCy,
48 HDC hDCSrc,
49 int SrcX,
50 int SrcY,
51 int SrcCx,
52 int SrcCy,
53 BLENDFUNCTION BlendFunction
54 )
55 {
56 if ( hDCSrc == NULL ) return FALSE;
57
58 if (GDI_HANDLE_GET_TYPE(hDCSrc) == GDI_OBJECT_TYPE_METADC) return FALSE;
59
60 return NtGdiAlphaBlend(
61 hDCDst,
62 DstX,
63 DstY,
64 DstCx,
65 DstCy,
66 hDCSrc,
67 SrcX,
68 SrcY,
69 SrcCx,
70 SrcCy,
71 BlendFunction,
72 0 );
73 }
74
75 /*
76 * @implemented
77 */
78 HGDIOBJ
79 WINAPI
80 GdiFixUpHandle(HGDIOBJ hGdiObj)
81 {
82 PGDI_TABLE_ENTRY Entry;
83
84 if (((ULONG_PTR)(hGdiObj)) & GDI_HANDLE_UPPER_MASK )
85 {
86 return hGdiObj;
87 }
88
89 /* FIXME is this right ?? */
90
91 Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj);
92
93 /* Rebuild handle for Object */
94 return hGdiObj = (HGDIOBJ)(((LONG_PTR)(hGdiObj)) | (Entry->Type << GDI_ENTRY_UPPER_SHIFT));
95 }
96
97 /*
98 * @implemented
99 */
100 PVOID
101 WINAPI
102 GdiQueryTable(VOID)
103 {
104 return (PVOID)GdiHandleTable;
105 }
106
107 BOOL GdiIsHandleValid(HGDIOBJ hGdiObj)
108 {
109 PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj);
110 // We are only looking for TYPE not the rest here, and why is FullUnique filled up with CRAP!?
111 // DPRINT1("FullUnique -> %x\n", Entry->FullUnique);
112 if((Entry->Type & GDI_ENTRY_BASETYPE_MASK) != 0 &&
113 ( (Entry->Type << GDI_ENTRY_UPPER_SHIFT) & GDI_HANDLE_TYPE_MASK ) ==
114 GDI_HANDLE_GET_TYPE(hGdiObj))
115 {
116 HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1);
117 if(pid == NULL || pid == CurrentProcessId)
118 {
119 return TRUE;
120 }
121 }
122 return FALSE;
123 }
124
125 BOOL GdiGetHandleUserData(HGDIOBJ hGdiObj, DWORD ObjectType, PVOID *UserData)
126 {
127 PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj);
128 if((Entry->Type & GDI_ENTRY_BASETYPE_MASK) == ObjectType &&
129 ( (Entry->Type << GDI_ENTRY_UPPER_SHIFT) & GDI_HANDLE_TYPE_MASK ) ==
130 GDI_HANDLE_GET_TYPE(hGdiObj))
131 {
132 HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1);
133 if(pid == NULL || pid == CurrentProcessId)
134 {
135 //
136 // Need to test if we have Read & Write access to the VM address space.
137 //
138 BOOL Result = TRUE;
139 if(Entry->UserData)
140 {
141 volatile CHAR *Current = (volatile CHAR*)Entry->UserData;
142 _SEH2_TRY
143 {
144 *Current = *Current;
145 }
146 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
147 {
148 Result = FALSE;
149 }
150 _SEH2_END
151 }
152 else
153 Result = FALSE; // Can not be zero.
154 if (Result) *UserData = Entry->UserData;
155 return Result;
156 }
157 }
158 SetLastError(ERROR_INVALID_PARAMETER);
159 return FALSE;
160 }
161
162 PLDC
163 FASTCALL
164 GdiGetLDC(HDC hDC)
165 {
166 PDC_ATTR Dc_Attr;
167 PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX((HGDIOBJ) hDC);
168 HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1);
169 // Don't check the mask, just the object type.
170 if ( Entry->ObjectType == GDIObjType_DC_TYPE &&
171 (pid == NULL || pid == CurrentProcessId) )
172 {
173 BOOL Result = TRUE;
174 if (Entry->UserData)
175 {
176 volatile CHAR *Current = (volatile CHAR*)Entry->UserData;
177 _SEH2_TRY
178 {
179 *Current = *Current;
180 }
181 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
182 {
183 Result = FALSE;
184 }
185 _SEH2_END
186 }
187 else
188 Result = FALSE;
189
190 if (Result)
191 {
192 Dc_Attr = (PDC_ATTR)Entry->UserData;
193 return Dc_Attr->pvLDC;
194 }
195 }
196 return NULL;
197 }
198
199 VOID GdiSAPCallback(PLDC pldc)
200 {
201 DWORD Time, NewTime = GetTickCount();
202
203 Time = NewTime - pldc->CallBackTick;
204
205 if ( Time < SAPCALLBACKDELAY) return;
206
207 pldc->CallBackTick = NewTime;
208
209 if ( !pldc->pAbortProc(pldc->hDC, 0) )
210 {
211 CancelDC(pldc->hDC);
212 AbortDoc(pldc->hDC);
213 }
214 }
215
216 /*
217 * @implemented
218 */
219 DWORD
220 WINAPI
221 GdiSetBatchLimit(DWORD Limit)
222 {
223 DWORD OldLimit = GDI_BatchLimit;
224
225 if ( (!Limit) ||
226 (Limit >= GDI_BATCH_LIMIT))
227 {
228 return Limit;
229 }
230
231 GdiFlush();
232 GDI_BatchLimit = Limit;
233 return OldLimit;
234 }
235
236
237 /*
238 * @implemented
239 */
240 DWORD
241 WINAPI
242 GdiGetBatchLimit()
243 {
244 return GDI_BatchLimit;
245 }
246
247 /*
248 * @unimplemented
249 */
250 BOOL
251 WINAPI
252 GdiReleaseDC(HDC hdc)
253 {
254 return 0;
255 }
256
257 INT
258 WINAPI
259 ExtEscape(HDC hDC,
260 int nEscape,
261 int cbInput,
262 LPCSTR lpszInData,
263 int cbOutput,
264 LPSTR lpszOutData)
265 {
266 return NtGdiExtEscape(hDC, NULL, 0, nEscape, cbInput, (LPSTR)lpszInData, cbOutput, lpszOutData);
267 }
268
269 /*
270 * @implemented
271 */
272 VOID
273 WINAPI
274 GdiSetLastError(DWORD dwErrCode)
275 {
276 NtCurrentTeb()->LastErrorValue = (ULONG) dwErrCode;
277 }
278
279 BOOL
280 WINAPI
281 GdiAddGlsBounds(HDC hdc,LPRECT prc)
282 {
283 //FIXME: Lookup what 0x8000 means
284 return NtGdiSetBoundsRect(hdc, prc, 0x8000 | DCB_ACCUMULATE ) ? TRUE : FALSE;
285 }
286
287 HGDIOBJ
288 FASTCALL
289 hGetPEBHandle(HANDLECACHETYPE Type, COLORREF cr)
290 {
291 return NULL;
292 }
293