1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2013 Keith Packard
3*61046927SAndroid Build Coastguard Worker * Copyright © 2015 Boyan Ding
4*61046927SAndroid Build Coastguard Worker *
5*61046927SAndroid Build Coastguard Worker * Permission to use, copy, modify, distribute, and sell this software and its
6*61046927SAndroid Build Coastguard Worker * documentation for any purpose is hereby granted without fee, provided that
7*61046927SAndroid Build Coastguard Worker * the above copyright notice appear in all copies and that both that copyright
8*61046927SAndroid Build Coastguard Worker * notice and this permission notice appear in supporting documentation, and
9*61046927SAndroid Build Coastguard Worker * that the name of the copyright holders not be used in advertising or
10*61046927SAndroid Build Coastguard Worker * publicity pertaining to distribution of the software without specific,
11*61046927SAndroid Build Coastguard Worker * written prior permission. The copyright holders make no representations
12*61046927SAndroid Build Coastguard Worker * about the suitability of this software for any purpose. It is provided "as
13*61046927SAndroid Build Coastguard Worker * is" without express or implied warranty.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16*61046927SAndroid Build Coastguard Worker * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17*61046927SAndroid Build Coastguard Worker * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18*61046927SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19*61046927SAndroid Build Coastguard Worker * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20*61046927SAndroid Build Coastguard Worker * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21*61046927SAndroid Build Coastguard Worker * OF THIS SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
25*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
26*61046927SAndroid Build Coastguard Worker #include <fcntl.h>
27*61046927SAndroid Build Coastguard Worker #include <unistd.h>
28*61046927SAndroid Build Coastguard Worker #include <xcb/xcb.h>
29*61046927SAndroid Build Coastguard Worker #include <xcb/dri3.h>
30*61046927SAndroid Build Coastguard Worker #include <xcb/present.h>
31*61046927SAndroid Build Coastguard Worker #include <xcb/xfixes.h>
32*61046927SAndroid Build Coastguard Worker #include "loader_x11.h"
33*61046927SAndroid Build Coastguard Worker /** x11_dri3_open
34*61046927SAndroid Build Coastguard Worker *
35*61046927SAndroid Build Coastguard Worker * Wrapper around xcb_dri3_open
36*61046927SAndroid Build Coastguard Worker */
37*61046927SAndroid Build Coastguard Worker int
x11_dri3_open(xcb_connection_t * conn,xcb_window_t root,uint32_t provider)38*61046927SAndroid Build Coastguard Worker x11_dri3_open(xcb_connection_t *conn,
39*61046927SAndroid Build Coastguard Worker xcb_window_t root,
40*61046927SAndroid Build Coastguard Worker uint32_t provider)
41*61046927SAndroid Build Coastguard Worker {
42*61046927SAndroid Build Coastguard Worker xcb_dri3_open_cookie_t cookie;
43*61046927SAndroid Build Coastguard Worker xcb_dri3_open_reply_t *reply;
44*61046927SAndroid Build Coastguard Worker xcb_xfixes_query_version_cookie_t fixes_cookie;
45*61046927SAndroid Build Coastguard Worker xcb_xfixes_query_version_reply_t *fixes_reply;
46*61046927SAndroid Build Coastguard Worker int fd;
47*61046927SAndroid Build Coastguard Worker const xcb_query_extension_reply_t *extension;
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker xcb_prefetch_extension_data(conn, &xcb_dri3_id);
50*61046927SAndroid Build Coastguard Worker extension = xcb_get_extension_data(conn, &xcb_dri3_id);
51*61046927SAndroid Build Coastguard Worker if (!(extension && extension->present))
52*61046927SAndroid Build Coastguard Worker return -1;
53*61046927SAndroid Build Coastguard Worker
54*61046927SAndroid Build Coastguard Worker cookie = xcb_dri3_open(conn,
55*61046927SAndroid Build Coastguard Worker root,
56*61046927SAndroid Build Coastguard Worker provider);
57*61046927SAndroid Build Coastguard Worker
58*61046927SAndroid Build Coastguard Worker reply = xcb_dri3_open_reply(conn, cookie, NULL);
59*61046927SAndroid Build Coastguard Worker
60*61046927SAndroid Build Coastguard Worker if (!reply || reply->nfd != 1) {
61*61046927SAndroid Build Coastguard Worker free(reply);
62*61046927SAndroid Build Coastguard Worker return -1;
63*61046927SAndroid Build Coastguard Worker }
64*61046927SAndroid Build Coastguard Worker
65*61046927SAndroid Build Coastguard Worker fd = xcb_dri3_open_reply_fds(conn, reply)[0];
66*61046927SAndroid Build Coastguard Worker free(reply);
67*61046927SAndroid Build Coastguard Worker fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
68*61046927SAndroid Build Coastguard Worker
69*61046927SAndroid Build Coastguard Worker /* let the server know our xfixes level */
70*61046927SAndroid Build Coastguard Worker fixes_cookie = xcb_xfixes_query_version(conn,
71*61046927SAndroid Build Coastguard Worker XCB_XFIXES_MAJOR_VERSION,
72*61046927SAndroid Build Coastguard Worker XCB_XFIXES_MINOR_VERSION);
73*61046927SAndroid Build Coastguard Worker fixes_reply = xcb_xfixes_query_version_reply(conn, fixes_cookie, NULL);
74*61046927SAndroid Build Coastguard Worker if (fixes_reply->major_version < 2) {
75*61046927SAndroid Build Coastguard Worker close(fd);
76*61046927SAndroid Build Coastguard Worker fd = -1;
77*61046927SAndroid Build Coastguard Worker }
78*61046927SAndroid Build Coastguard Worker free(fixes_reply);
79*61046927SAndroid Build Coastguard Worker
80*61046927SAndroid Build Coastguard Worker return fd;
81*61046927SAndroid Build Coastguard Worker }
82*61046927SAndroid Build Coastguard Worker
83*61046927SAndroid Build Coastguard Worker /* Only request versions of these protocols which we actually support. */
84*61046927SAndroid Build Coastguard Worker #define DRI3_SUPPORTED_MAJOR 1
85*61046927SAndroid Build Coastguard Worker #define PRESENT_SUPPORTED_MAJOR 1
86*61046927SAndroid Build Coastguard Worker
87*61046927SAndroid Build Coastguard Worker #ifdef HAVE_X11_DRM
88*61046927SAndroid Build Coastguard Worker #define DRI3_SUPPORTED_MINOR 2
89*61046927SAndroid Build Coastguard Worker #define PRESENT_SUPPORTED_MINOR 2
90*61046927SAndroid Build Coastguard Worker #else
91*61046927SAndroid Build Coastguard Worker #define PRESENT_SUPPORTED_MINOR 0
92*61046927SAndroid Build Coastguard Worker #define DRI3_SUPPORTED_MINOR 0
93*61046927SAndroid Build Coastguard Worker #endif
94*61046927SAndroid Build Coastguard Worker
95*61046927SAndroid Build Coastguard Worker bool
x11_dri3_check_multibuffer(xcb_connection_t * c,bool * err,bool * explicit_modifiers)96*61046927SAndroid Build Coastguard Worker x11_dri3_check_multibuffer(xcb_connection_t *c, bool *err, bool *explicit_modifiers)
97*61046927SAndroid Build Coastguard Worker {
98*61046927SAndroid Build Coastguard Worker xcb_dri3_query_version_cookie_t dri3_cookie;
99*61046927SAndroid Build Coastguard Worker xcb_dri3_query_version_reply_t *dri3_reply;
100*61046927SAndroid Build Coastguard Worker xcb_present_query_version_cookie_t present_cookie;
101*61046927SAndroid Build Coastguard Worker xcb_present_query_version_reply_t *present_reply;
102*61046927SAndroid Build Coastguard Worker xcb_generic_error_t *error;
103*61046927SAndroid Build Coastguard Worker const xcb_query_extension_reply_t *extension;
104*61046927SAndroid Build Coastguard Worker
105*61046927SAndroid Build Coastguard Worker xcb_prefetch_extension_data(c, &xcb_dri3_id);
106*61046927SAndroid Build Coastguard Worker xcb_prefetch_extension_data(c, &xcb_present_id);
107*61046927SAndroid Build Coastguard Worker
108*61046927SAndroid Build Coastguard Worker extension = xcb_get_extension_data(c, &xcb_dri3_id);
109*61046927SAndroid Build Coastguard Worker if (!(extension && extension->present))
110*61046927SAndroid Build Coastguard Worker goto error;
111*61046927SAndroid Build Coastguard Worker
112*61046927SAndroid Build Coastguard Worker extension = xcb_get_extension_data(c, &xcb_present_id);
113*61046927SAndroid Build Coastguard Worker if (!(extension && extension->present))
114*61046927SAndroid Build Coastguard Worker goto error;
115*61046927SAndroid Build Coastguard Worker
116*61046927SAndroid Build Coastguard Worker dri3_cookie = xcb_dri3_query_version(c,
117*61046927SAndroid Build Coastguard Worker DRI3_SUPPORTED_MAJOR,
118*61046927SAndroid Build Coastguard Worker DRI3_SUPPORTED_MINOR);
119*61046927SAndroid Build Coastguard Worker present_cookie = xcb_present_query_version(c,
120*61046927SAndroid Build Coastguard Worker PRESENT_SUPPORTED_MAJOR,
121*61046927SAndroid Build Coastguard Worker PRESENT_SUPPORTED_MINOR);
122*61046927SAndroid Build Coastguard Worker
123*61046927SAndroid Build Coastguard Worker dri3_reply = xcb_dri3_query_version_reply(c, dri3_cookie, &error);
124*61046927SAndroid Build Coastguard Worker if (!dri3_reply) {
125*61046927SAndroid Build Coastguard Worker free(error);
126*61046927SAndroid Build Coastguard Worker goto error;
127*61046927SAndroid Build Coastguard Worker }
128*61046927SAndroid Build Coastguard Worker
129*61046927SAndroid Build Coastguard Worker int dri3Major = dri3_reply->major_version;
130*61046927SAndroid Build Coastguard Worker int dri3Minor = dri3_reply->minor_version;
131*61046927SAndroid Build Coastguard Worker free(dri3_reply);
132*61046927SAndroid Build Coastguard Worker
133*61046927SAndroid Build Coastguard Worker present_reply = xcb_present_query_version_reply(c, present_cookie, &error);
134*61046927SAndroid Build Coastguard Worker if (!present_reply) {
135*61046927SAndroid Build Coastguard Worker free(error);
136*61046927SAndroid Build Coastguard Worker goto error;
137*61046927SAndroid Build Coastguard Worker }
138*61046927SAndroid Build Coastguard Worker int presentMajor = present_reply->major_version;
139*61046927SAndroid Build Coastguard Worker int presentMinor = present_reply->minor_version;
140*61046927SAndroid Build Coastguard Worker free(present_reply);
141*61046927SAndroid Build Coastguard Worker
142*61046927SAndroid Build Coastguard Worker #ifdef HAVE_X11_DRM
143*61046927SAndroid Build Coastguard Worker if (presentMajor > 1 || (presentMajor == 1 && presentMinor >= 2)) {
144*61046927SAndroid Build Coastguard Worker *explicit_modifiers = dri3Major > 1 || (dri3Major == 1 && dri3Minor >= 2);
145*61046927SAndroid Build Coastguard Worker if (dri3Major >= 1)
146*61046927SAndroid Build Coastguard Worker return true;
147*61046927SAndroid Build Coastguard Worker }
148*61046927SAndroid Build Coastguard Worker #endif
149*61046927SAndroid Build Coastguard Worker return false;
150*61046927SAndroid Build Coastguard Worker error:
151*61046927SAndroid Build Coastguard Worker *err = true;
152*61046927SAndroid Build Coastguard Worker return false;
153*61046927SAndroid Build Coastguard Worker }
154