1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2014 Jon Turney
3b8e80941Smrg *
4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
6b8e80941Smrg * to deal in the Software without restriction, including without limitation
7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
10b8e80941Smrg *
11b8e80941Smrg * The above copyright notice and this permission notice (including the next
12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the
13b8e80941Smrg * Software.
14b8e80941Smrg *
15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21b8e80941Smrg * IN THE SOFTWARE.
22b8e80941Smrg */
23b8e80941Smrg
24b8e80941Smrg/* THIS IS NOT AN X CONSORTIUM STANDARD */
25b8e80941Smrg
26b8e80941Smrg#include <X11/Xlibint.h>
27b8e80941Smrg#include <X11/extensions/Xext.h>
28b8e80941Smrg#include <X11/extensions/extutil.h>
29b8e80941Smrg#include "windowsdristr.h"
30b8e80941Smrg#include "xwindowsdri.h"
31b8e80941Smrg#include <stdio.h>
32b8e80941Smrg
33b8e80941Smrgstatic XExtensionInfo _windowsdri_info_data;
34b8e80941Smrgstatic XExtensionInfo *windowsdri_info = &_windowsdri_info_data;
35b8e80941Smrgstatic char *windowsdri_extension_name = WINDOWSDRINAME;
36b8e80941Smrg
37b8e80941Smrg#define WindowsDRICheckExtension(dpy,i,val) \
38b8e80941Smrg  XextCheckExtension (dpy, i, windowsdri_extension_name, val)
39b8e80941Smrg
40b8e80941Smrg/*****************************************************************************
41b8e80941Smrg *                                                                           *
42b8e80941Smrg *                         private utility routines                          *
43b8e80941Smrg *                                                                           *
44b8e80941Smrg *****************************************************************************/
45b8e80941Smrg
46b8e80941Smrgstatic int close_display(Display * dpy, XExtCodes * extCodes);
47b8e80941Smrg
48b8e80941Smrgstatic /* const */ XExtensionHooks windowsdri_extension_hooks = {
49b8e80941Smrg   NULL,                        /* create_gc */
50b8e80941Smrg   NULL,                        /* copy_gc */
51b8e80941Smrg   NULL,                        /* flush_gc */
52b8e80941Smrg   NULL,                        /* free_gc */
53b8e80941Smrg   NULL,                        /* create_font */
54b8e80941Smrg   NULL,                        /* free_font */
55b8e80941Smrg   close_display,               /* close_display */
56b8e80941Smrg   NULL,                        /* wire_to_event */
57b8e80941Smrg   NULL,                        /* event_to_wire */
58b8e80941Smrg   NULL,                        /* error */
59b8e80941Smrg   NULL,                        /* error_string */
60b8e80941Smrg};
61b8e80941Smrg
62b8e80941Smrgstatic
63b8e80941SmrgXEXT_GENERATE_FIND_DISPLAY(find_display, windowsdri_info,
64b8e80941Smrg                           windowsdri_extension_name,
65b8e80941Smrg                           &windowsdri_extension_hooks,
66b8e80941Smrg                           WindowsDRINumberEvents, NULL)
67b8e80941Smrg
68b8e80941Smrgstatic
69b8e80941SmrgXEXT_GENERATE_CLOSE_DISPLAY(close_display, windowsdri_info)
70b8e80941Smrg
71b8e80941Smrg/*****************************************************************************
72b8e80941Smrg *                                                                           *
73b8e80941Smrg *                 public Windows-DRI Extension routines                     *
74b8e80941Smrg *                                                                           *
75b8e80941Smrg *****************************************************************************/
76b8e80941Smrg
77b8e80941Smrg#if 0
78b8e80941Smrg#include <stdio.h>
79b8e80941Smrg#define TRACE(msg, ...)  fprintf(stderr, "WindowsDRI" msg "\n", ##__VA_ARGS__);
80b8e80941Smrg#else
81b8e80941Smrg#define TRACE(msg, ...)
82b8e80941Smrg#endif
83b8e80941Smrg
84b8e80941SmrgBool
85b8e80941SmrgXWindowsDRIQueryExtension(dpy, event_basep, error_basep)
86b8e80941Smrg     Display *dpy;
87b8e80941Smrg     int *event_basep, *error_basep;
88b8e80941Smrg{
89b8e80941Smrg   XExtDisplayInfo *info = find_display(dpy);
90b8e80941Smrg
91b8e80941Smrg   TRACE("QueryExtension:");
92b8e80941Smrg   if (XextHasExtension(info)) {
93b8e80941Smrg      *event_basep = info->codes->first_event;
94b8e80941Smrg      *error_basep = info->codes->first_error;
95b8e80941Smrg      TRACE("QueryExtension: return True");
96b8e80941Smrg      return True;
97b8e80941Smrg   }
98b8e80941Smrg   else {
99b8e80941Smrg      TRACE("QueryExtension: return False");
100b8e80941Smrg      return False;
101b8e80941Smrg   }
102b8e80941Smrg}
103b8e80941Smrg
104b8e80941SmrgBool
105b8e80941SmrgXWindowsDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
106b8e80941Smrg     Display *dpy;
107b8e80941Smrg     int *majorVersion;
108b8e80941Smrg     int *minorVersion;
109b8e80941Smrg     int *patchVersion;
110b8e80941Smrg{
111b8e80941Smrg   XExtDisplayInfo *info = find_display(dpy);
112b8e80941Smrg   xWindowsDRIQueryVersionReply rep;
113b8e80941Smrg   xWindowsDRIQueryVersionReq *req;
114b8e80941Smrg
115b8e80941Smrg   TRACE("QueryVersion:");
116b8e80941Smrg   WindowsDRICheckExtension(dpy, info, False);
117b8e80941Smrg
118b8e80941Smrg   LockDisplay(dpy);
119b8e80941Smrg   GetReq(WindowsDRIQueryVersion, req);
120b8e80941Smrg   req->reqType = info->codes->major_opcode;
121b8e80941Smrg   req->driReqType = X_WindowsDRIQueryVersion;
122b8e80941Smrg   if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
123b8e80941Smrg      UnlockDisplay(dpy);
124b8e80941Smrg      SyncHandle();
125b8e80941Smrg      TRACE("QueryVersion: return False");
126b8e80941Smrg      return False;
127b8e80941Smrg   }
128b8e80941Smrg   *majorVersion = rep.majorVersion;
129b8e80941Smrg   *minorVersion = rep.minorVersion;
130b8e80941Smrg   *patchVersion = rep.patchVersion;
131b8e80941Smrg   UnlockDisplay(dpy);
132b8e80941Smrg   SyncHandle();
133b8e80941Smrg   TRACE("QueryVersion: %d.%d.%d", *majorVersion, *minorVersion, *patchVersion);
134b8e80941Smrg   return True;
135b8e80941Smrg}
136b8e80941Smrg
137b8e80941SmrgBool
138b8e80941SmrgXWindowsDRIQueryDirectRenderingCapable(dpy, screen, isCapable)
139b8e80941Smrg     Display *dpy;
140b8e80941Smrg     int screen;
141b8e80941Smrg     Bool *isCapable;
142b8e80941Smrg{
143b8e80941Smrg   XExtDisplayInfo *info = find_display(dpy);
144b8e80941Smrg   xWindowsDRIQueryDirectRenderingCapableReply rep;
145b8e80941Smrg   xWindowsDRIQueryDirectRenderingCapableReq *req;
146b8e80941Smrg
147b8e80941Smrg   TRACE("QueryDirectRenderingCapable:");
148b8e80941Smrg   WindowsDRICheckExtension(dpy, info, False);
149b8e80941Smrg
150b8e80941Smrg   LockDisplay(dpy);
151b8e80941Smrg   GetReq(WindowsDRIQueryDirectRenderingCapable, req);
152b8e80941Smrg   req->reqType = info->codes->major_opcode;
153b8e80941Smrg   req->driReqType = X_WindowsDRIQueryDirectRenderingCapable;
154b8e80941Smrg   req->screen = screen;
155b8e80941Smrg   if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
156b8e80941Smrg      UnlockDisplay(dpy);
157b8e80941Smrg      SyncHandle();
158b8e80941Smrg      TRACE("QueryDirectRenderingCapable: return False");
159b8e80941Smrg      return False;
160b8e80941Smrg   }
161b8e80941Smrg   *isCapable = rep.isCapable;
162b8e80941Smrg   UnlockDisplay(dpy);
163b8e80941Smrg   SyncHandle();
164b8e80941Smrg   TRACE("QueryDirectRenderingCapable:return True");
165b8e80941Smrg   return True;
166b8e80941Smrg}
167b8e80941Smrg
168b8e80941SmrgBool
169b8e80941SmrgXWindowsDRIQueryDrawable(Display *dpy, int screen, Drawable drawable,
170b8e80941Smrg                        unsigned int * type, void ** handle)
171b8e80941Smrg{
172b8e80941Smrg   XExtDisplayInfo *info = find_display(dpy);
173b8e80941Smrg   xWindowsDRIQueryDrawableReply rep;
174b8e80941Smrg   xWindowsDRIQueryDrawableReq *req;
175b8e80941Smrg
176b8e80941Smrg   TRACE("QueryDrawable: XID %lx", drawable);
177b8e80941Smrg   WindowsDRICheckExtension(dpy, info, False);
178b8e80941Smrg
179b8e80941Smrg   LockDisplay(dpy);
180b8e80941Smrg   GetReq(WindowsDRIQueryDrawable, req);
181b8e80941Smrg   req->reqType = info->codes->major_opcode;
182b8e80941Smrg   req->driReqType = X_WindowsDRIQueryDrawable;
183b8e80941Smrg   req->screen = screen;
184b8e80941Smrg   req->drawable = drawable;
185b8e80941Smrg
186b8e80941Smrg   if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
187b8e80941Smrg      UnlockDisplay(dpy);
188b8e80941Smrg      SyncHandle();
189b8e80941Smrg      TRACE("QueryDrawable: return False");
190b8e80941Smrg      return False;
191b8e80941Smrg   }
192b8e80941Smrg
193b8e80941Smrg   *type = rep.drawable_type;
194b8e80941Smrg
195b8e80941Smrg   // Note that despite being a derived type of void *, HANDLEs are defined to
196b8e80941Smrg   // be a sign-extended 32 bit value (so they can be passed to 32-bit
197b8e80941Smrg   // processes safely)
198b8e80941Smrg   *handle = (void *)(intptr_t)rep.handle;
199b8e80941Smrg
200b8e80941Smrg   UnlockDisplay(dpy);
201b8e80941Smrg   SyncHandle();
202b8e80941Smrg   TRACE("QueryDrawable: type %d, handle %p", *type, *handle);
203b8e80941Smrg   return True;
204b8e80941Smrg}
205b8e80941Smrg
206b8e80941SmrgBool
207b8e80941SmrgXWindowsDRIFBConfigToPixelFormat(Display *dpy, int screen, int fbConfigID,
208b8e80941Smrg                                int *pxfi)
209b8e80941Smrg{
210b8e80941Smrg   XExtDisplayInfo *info = find_display(dpy);
211b8e80941Smrg   xWindowsDRIFBConfigToPixelFormatReply rep;
212b8e80941Smrg   xWindowsDRIFBConfigToPixelFormatReq *req;
213b8e80941Smrg
214b8e80941Smrg   TRACE("FBConfigToPixelFormat: fbConfigID 0x%x", fbConfigID);
215b8e80941Smrg   WindowsDRICheckExtension(dpy, info, False);
216b8e80941Smrg
217b8e80941Smrg   LockDisplay(dpy);
218b8e80941Smrg   GetReq(WindowsDRIFBConfigToPixelFormat, req);
219b8e80941Smrg   req->reqType = info->codes->major_opcode;
220b8e80941Smrg   req->driReqType = X_WindowsDRIFBConfigToPixelFormat;
221b8e80941Smrg   req->screen = screen;
222b8e80941Smrg   req->fbConfigID = fbConfigID;
223b8e80941Smrg
224b8e80941Smrg   if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
225b8e80941Smrg      UnlockDisplay(dpy);
226b8e80941Smrg      SyncHandle();
227b8e80941Smrg      TRACE("FBConfigToPixelFormat: return False");
228b8e80941Smrg      return False;
229b8e80941Smrg   }
230b8e80941Smrg
231b8e80941Smrg   *pxfi = rep.pixelFormatIndex;
232b8e80941Smrg
233b8e80941Smrg   UnlockDisplay(dpy);
234b8e80941Smrg   SyncHandle();
235b8e80941Smrg   TRACE("FBConfigToPixelFormat: pixelformatindex %d", *pxfi);
236b8e80941Smrg   return True;
237b8e80941Smrg}
238