Merge to trunk HEAD(r36856)
[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 STDCALL
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 STDCALL
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 STDCALL
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 _SEH_TRY
140 {
141 *Current = *Current;
142 }
143 _SEH_HANDLE
144 {
145 Result = FALSE;
146 }
147 _SEH_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 /*
168 * @implemented
169 */
170 DWORD
171 STDCALL
172 GdiSetBatchLimit(DWORD Limit)
173 {
174 DWORD OldLimit = GDI_BatchLimit;
175
176 if ( (!Limit) ||
177 (Limit >= GDI_BATCH_LIMIT))
178 {
179 return Limit;
180 }
181
182 GdiFlush();
183 GDI_BatchLimit = Limit;
184 return OldLimit;
185 }
186
187
188 /*
189 * @implemented
190 */
191 DWORD
192 STDCALL
193 GdiGetBatchLimit()
194 {
195 return GDI_BatchLimit;
196 }
197
198 /*
199 * @unimplemented
200 */
201 BOOL
202 STDCALL
203 GdiReleaseDC(HDC hdc)
204 {
205 return 0;
206 }
207
208 INT
209 STDCALL
210 ExtEscape(HDC hDC,
211 int nEscape,
212 int cbInput,
213 LPCSTR lpszInData,
214 int cbOutput,
215 LPSTR lpszOutData)
216 {
217 return NtGdiExtEscape(hDC, NULL, 0, nEscape, cbInput, (LPSTR)lpszInData, cbOutput, lpszOutData);
218 }
219
220 /*
221 * @implemented
222 */
223 VOID
224 STDCALL
225 GdiSetLastError(DWORD dwErrCode)
226 {
227 NtCurrentTeb()->LastErrorValue = (ULONG) dwErrCode;
228 }
229
230 BOOL
231 STDCALL
232 GdiAddGlsBounds(HDC hdc,LPRECT prc)
233 {
234 //FIXME: Lookup what 0x8000 means
235 return NtGdiSetBoundsRect(hdc, prc, 0x8000 | DCB_ACCUMULATE ) ? TRUE : FALSE;
236 }
237