- Fix typo: AbortProc returns TRUE to continue the print job or FALSE to cancel the...
[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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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 PGDI_TABLE_ENTRY GdiHandleTable = NULL;
32 PGDI_SHARED_HANDLE_TABLE GdiSharedHandleTable = NULL;
33 HANDLE CurrentProcessId = NULL;
34 DWORD GDI_BatchLimit = 1;
35
36
37 BOOL
38 WINAPI
39 GdiAlphaBlend(
40 HDC hDCDst,
41 int DstX,
42 int DstY,
43 int DstCx,
44 int DstCy,
45 HDC hDCSrc,
46 int SrcX,
47 int SrcY,
48 int SrcCx,
49 int SrcCy,
50 BLENDFUNCTION BlendFunction
51 )
52 {
53 if ( hDCSrc == NULL ) return FALSE;
54
55 if (GDI_HANDLE_GET_TYPE(hDCSrc) == GDI_OBJECT_TYPE_METADC) return FALSE;
56
57 return NtGdiAlphaBlend(
58 hDCDst,
59 DstX,
60 DstY,
61 DstCx,
62 DstCy,
63 hDCSrc,
64 SrcX,
65 SrcY,
66 SrcCx,
67 SrcCy,
68 BlendFunction,
69 0 );
70 }
71
72 /*
73 * @implemented
74 */
75 HGDIOBJ
76 WINAPI
77 GdiFixUpHandle(HGDIOBJ hGdiObj)
78 {
79 PGDI_TABLE_ENTRY Entry;
80
81 if (((ULONG_PTR)(hGdiObj)) & GDI_HANDLE_UPPER_MASK )
82 {
83 return hGdiObj;
84 }
85
86 /* FIXME is this right ?? */
87
88 Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj);
89
90 /* Rebuild handle for Object */
91 return hGdiObj = (HGDIOBJ)(((LONG_PTR)(hGdiObj)) | (Entry->Type << GDI_ENTRY_UPPER_SHIFT));
92 }
93
94 /*
95 * @implemented
96 */
97 PVOID
98 WINAPI
99 GdiQueryTable(VOID)
100 {
101 return (PVOID)GdiHandleTable;
102 }
103
104 BOOL GdiIsHandleValid(HGDIOBJ hGdiObj)
105 {
106 PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj);
107 // We are only looking for TYPE not the rest here, and why is FullUnique filled up with CRAP!?
108 // DPRINT1("FullUnique -> %x\n", Entry->FullUnique);
109 if((Entry->Type & GDI_ENTRY_BASETYPE_MASK) != 0 &&
110 ( (Entry->Type << GDI_ENTRY_UPPER_SHIFT) & GDI_HANDLE_TYPE_MASK ) ==
111 GDI_HANDLE_GET_TYPE(hGdiObj))
112 {
113 HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1);
114 if(pid == NULL || pid == CurrentProcessId)
115 {
116 return TRUE;
117 }
118 }
119 return FALSE;
120 }
121
122 BOOL GdiGetHandleUserData(HGDIOBJ hGdiObj, DWORD ObjectType, PVOID *UserData)
123 {
124 PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj);
125 if((Entry->Type & GDI_ENTRY_BASETYPE_MASK) == ObjectType &&
126 ( (Entry->Type << GDI_ENTRY_UPPER_SHIFT) & GDI_HANDLE_TYPE_MASK ) ==
127 GDI_HANDLE_GET_TYPE(hGdiObj))
128 {
129 HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1);
130 if(pid == NULL || pid == CurrentProcessId)
131 {
132 //
133 // Need to test if we have Read & Write access to the VM address space.
134 //
135 BOOL Result = TRUE;
136 if(Entry->UserData)
137 {
138 volatile CHAR *Current = (volatile CHAR*)Entry->UserData;
139 _SEH2_TRY
140 {
141 *Current = *Current;
142 }
143 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
144 {
145 Result = FALSE;
146 }
147 _SEH2_END
148 }
149 else
150 Result = FALSE; // Can not be zero.
151 if (Result) *UserData = Entry->UserData;
152 return Result;
153 }
154 }
155 SetLastError(ERROR_INVALID_PARAMETER);
156 return FALSE;
157 }
158
159 PLDC GdiGetLDC(HDC hDC)
160 {
161 PDC_ATTR Dc_Attr;
162 if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr))
163 return NULL;
164 return Dc_Attr->pvLDC;
165 }
166
167 VOID GdiSAPCallback(PLDC pldc)
168 {
169 DWORD Time, NewTime = GetTickCount();
170
171 Time = NewTime - pldc->CallBackTick;
172
173 if ( Time < SAPCALLBACKDELAY) return;
174
175 pldc->CallBackTick = NewTime;
176
177 if ( !pldc->pAbortProc(pldc->hDC, 0) )
178 {
179 CancelDC(pldc->hDC);
180 AbortDoc(pldc->hDC);
181 }
182 }
183
184 /*
185 * @implemented
186 */
187 DWORD
188 WINAPI
189 GdiSetBatchLimit(DWORD Limit)
190 {
191 DWORD OldLimit = GDI_BatchLimit;
192
193 if ( (!Limit) ||
194 (Limit >= GDI_BATCH_LIMIT))
195 {
196 return Limit;
197 }
198
199 GdiFlush();
200 GDI_BatchLimit = Limit;
201 return OldLimit;
202 }
203
204
205 /*
206 * @implemented
207 */
208 DWORD
209 WINAPI
210 GdiGetBatchLimit()
211 {
212 return GDI_BatchLimit;
213 }
214
215 /*
216 * @unimplemented
217 */
218 BOOL
219 WINAPI
220 GdiReleaseDC(HDC hdc)
221 {
222 return 0;
223 }
224
225 INT
226 WINAPI
227 ExtEscape(HDC hDC,
228 int nEscape,
229 int cbInput,
230 LPCSTR lpszInData,
231 int cbOutput,
232 LPSTR lpszOutData)
233 {
234 return NtGdiExtEscape(hDC, NULL, 0, nEscape, cbInput, (LPSTR)lpszInData, cbOutput, lpszOutData);
235 }
236
237 /*
238 * @implemented
239 */
240 VOID
241 WINAPI
242 GdiSetLastError(DWORD dwErrCode)
243 {
244 NtCurrentTeb()->LastErrorValue = (ULONG) dwErrCode;
245 }
246
247 BOOL
248 WINAPI
249 GdiAddGlsBounds(HDC hdc,LPRECT prc)
250 {
251 //FIXME: Lookup what 0x8000 means
252 return NtGdiSetBoundsRect(hdc, prc, 0x8000 | DCB_ACCUMULATE ) ? TRUE : FALSE;
253 }
254