xref: /reactos/win32ss/gdi/ntgdi/wingl.c (revision 4561998a)
1 /*
2  * PROJECT:         ReactOS win32 kernel mode subsystem
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            win32ss/gdi/ntgdi/wingl.c
5  * PURPOSE:         WinGL API
6  * PROGRAMMER:
7  */
8 
9 #include <win32k.h>
10 
11 #define NDEBUG
12 #include <debug.h>
13 
14 static
15 INT
16 FASTCALL
17 IntGetipfdDevMax(PDC pdc)
18 {
19     INT Ret = 0;
20     PPDEVOBJ ppdev = pdc->ppdev;
21 
22     if (ppdev->flFlags & PDEV_META_DEVICE)
23     {
24         return 0;
25     }
26 
27     if (ppdev->DriverFunctions.DescribePixelFormat)
28     {
29         Ret = ppdev->DriverFunctions.DescribePixelFormat(
30                                                 ppdev->dhpdev,
31                                                 1,
32                                                 0,
33                                                 NULL);
34     }
35 
36     if (Ret) pdc->ipfdDevMax = Ret;
37 
38     return Ret;
39 }
40 
41 _Success_(return != 0)
42 __kernel_entry
43 INT
44 APIENTRY
45 NtGdiDescribePixelFormat(
46     _In_ HDC hdc,
47     _In_ INT ipfd,
48     _In_ UINT cjpfd,
49     _Out_writes_bytes_(cjpfd) PPIXELFORMATDESCRIPTOR ppfd)
50 {
51     PDC pdc;
52     PPDEVOBJ ppdev;
53     INT Ret = 0;
54     PIXELFORMATDESCRIPTOR pfdSafe;
55 
56     if ((ppfd == NULL) && (cjpfd != 0)) return 0;
57 
58     pdc = DC_LockDc(hdc);
59     if (!pdc)
60     {
61         EngSetLastError(ERROR_INVALID_HANDLE);
62         return 0;
63     }
64 
65     if (!pdc->ipfdDevMax)
66     {
67         if (!IntGetipfdDevMax(pdc))
68         {
69             /* EngSetLastError ? */
70             goto Exit;
71         }
72     }
73 
74     if (!ppfd)
75     {
76         Ret = pdc->ipfdDevMax;
77         goto Exit;
78     }
79 
80     if ((ipfd < 1) || (ipfd > pdc->ipfdDevMax))
81     {
82         EngSetLastError(ERROR_INVALID_PARAMETER);
83         goto Exit;
84     }
85 
86     ppdev = pdc->ppdev;
87 
88     if (ppdev->flFlags & PDEV_META_DEVICE)
89     {
90         UNIMPLEMENTED;
91         goto Exit;
92     }
93 
94     if (ppdev->DriverFunctions.DescribePixelFormat)
95     {
96         Ret = ppdev->DriverFunctions.DescribePixelFormat(
97                                                     ppdev->dhpdev,
98                                                     ipfd,
99                                                     sizeof(pfdSafe),
100                                                     &pfdSafe);
101     }
102 
103     if (Ret && cjpfd)
104     {
105         _SEH2_TRY
106         {
107             cjpfd = min(cjpfd, sizeof(PIXELFORMATDESCRIPTOR));
108             ProbeForWrite(ppfd, cjpfd, 1);
109             RtlCopyMemory(ppfd, &pfdSafe, cjpfd);
110         }
111         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
112         {
113             SetLastNtError(_SEH2_GetExceptionCode());
114         }
115         _SEH2_END;
116     }
117 
118 Exit:
119     DC_UnlockDc(pdc);
120     return Ret;
121 }
122 
123 
124 BOOL
125 APIENTRY
126 NtGdiSetPixelFormat(
127     _In_ HDC hdc,
128     _In_ INT ipfd)
129 {
130     PDC pdc;
131     PPDEVOBJ ppdev;
132     HWND hWnd;
133     PWNDOBJ pWndObj;
134     SURFOBJ *pso = NULL;
135     BOOL Ret = FALSE;
136 
137     DPRINT1("Setting pixel format from win32k!\n");
138 
139     pdc = DC_LockDc(hdc);
140     if (!pdc)
141     {
142         EngSetLastError(ERROR_INVALID_HANDLE);
143         return FALSE;
144     }
145 
146     if (!pdc->ipfdDevMax)
147         IntGetipfdDevMax(pdc);
148 
149     if ( ipfd < 1 ||
150         ipfd > pdc->ipfdDevMax )
151     {
152         EngSetLastError(ERROR_INVALID_PARAMETER);
153         goto Exit;
154     }
155 
156     UserEnterExclusive();
157     hWnd = UserGethWnd(hdc, &pWndObj);
158     UserLeave();
159 
160     if (!hWnd)
161     {
162         EngSetLastError(ERROR_INVALID_WINDOW_STYLE);
163         goto Exit;
164     }
165 
166     ppdev = pdc->ppdev;
167 
168     /*
169         WndObj is needed so exit on NULL pointer.
170     */
171     if (pWndObj)
172         pso = pWndObj->psoOwner;
173     else
174     {
175         EngSetLastError(ERROR_INVALID_PIXEL_FORMAT);
176         goto Exit;
177     }
178 
179     if (ppdev->flFlags & PDEV_META_DEVICE)
180     {
181         UNIMPLEMENTED;
182         goto Exit;
183     }
184 
185     if (ppdev->DriverFunctions.SetPixelFormat)
186     {
187         Ret = ppdev->DriverFunctions.SetPixelFormat(
188                                                 pso,
189                                                 ipfd,
190                                                 hWnd);
191     }
192 
193 Exit:
194     DC_UnlockDc(pdc);
195     return Ret;
196 }
197 
198 BOOL
199 APIENTRY
200 NtGdiSwapBuffers(
201     _In_ HDC hdc)
202 {
203     PDC pdc;
204     PPDEVOBJ ppdev;
205     HWND hWnd;
206     PWNDOBJ pWndObj;
207     SURFOBJ *pso = NULL;
208     BOOL Ret = FALSE;
209 
210     pdc = DC_LockDc(hdc);
211     if (!pdc)
212     {
213         EngSetLastError(ERROR_INVALID_HANDLE);
214         return FALSE;
215     }
216 
217     UserEnterExclusive();
218     hWnd = UserGethWnd(hdc, &pWndObj);
219     UserLeave();
220 
221     if (!hWnd)
222     {
223         EngSetLastError(ERROR_INVALID_WINDOW_STYLE);
224         goto Exit;
225     }
226 
227     ppdev = pdc->ppdev;
228 
229     /*
230         WndObj is needed so exit on NULL pointer.
231     */
232     if (pWndObj)
233         pso = pWndObj->psoOwner;
234     else
235     {
236         EngSetLastError(ERROR_INVALID_PIXEL_FORMAT);
237         goto Exit;
238     }
239 
240     if (ppdev->flFlags & PDEV_META_DEVICE)
241     {
242         UNIMPLEMENTED;
243         goto Exit;
244     }
245 
246     if (ppdev->DriverFunctions.SwapBuffers)
247     {
248         Ret = ppdev->DriverFunctions.SwapBuffers(pso, pWndObj);
249     }
250 
251 Exit:
252     DC_UnlockDc(pdc);
253     return Ret;
254 }
255 
256 /* EOF */
257