9bf0ad811437405ae690b9b51bc8ac3d0278ca2f
[mesa.git] / src / gallium / state_trackers / egl / x11 / native_x11.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.8
4 *
5 * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25
26 #include <stdio.h>
27 #include <string.h>
28 #include "util/u_debug.h"
29 #include "util/u_memory.h"
30 #include "state_tracker/drm_api.h"
31 #include "egllog.h"
32
33 #include "native_x11.h"
34 #include "x11_screen.h"
35
36 #define X11_PROBE_MAGIC 0x11980BE /* "X11PROBE" */
37
38 static struct drm_api *api;
39
40 static void
41 x11_probe_destroy(struct native_probe *nprobe)
42 {
43 if (nprobe->data)
44 free(nprobe->data);
45 free(nprobe);
46 }
47
48 struct native_probe *
49 native_create_probe(EGLNativeDisplayType dpy)
50 {
51 struct native_probe *nprobe;
52 struct x11_screen *xscr;
53 int scr;
54 const char *driver_name = NULL;
55 Display *xdpy;
56
57 nprobe = CALLOC_STRUCT(native_probe);
58 if (!nprobe)
59 return NULL;
60
61 xdpy = dpy;
62 if (!xdpy) {
63 xdpy = XOpenDisplay(NULL);
64 if (!xdpy) {
65 free(nprobe);
66 return NULL;
67 }
68 }
69
70 scr = DefaultScreen(xdpy);
71 xscr = x11_screen_create(xdpy, scr);
72 if (xscr) {
73 if (x11_screen_support(xscr, X11_SCREEN_EXTENSION_DRI2)) {
74 driver_name = x11_screen_probe_dri2(xscr, NULL, NULL);
75 if (driver_name)
76 nprobe->data = strdup(driver_name);
77 }
78
79 x11_screen_destroy(xscr);
80 }
81
82 if (xdpy != dpy)
83 XCloseDisplay(xdpy);
84
85 nprobe->magic = X11_PROBE_MAGIC;
86 nprobe->display = dpy;
87
88 nprobe->destroy = x11_probe_destroy;
89
90 return nprobe;
91 }
92
93 enum native_probe_result
94 native_get_probe_result(struct native_probe *nprobe)
95 {
96 if (!nprobe || nprobe->magic != X11_PROBE_MAGIC)
97 return NATIVE_PROBE_UNKNOWN;
98
99 if (!api)
100 api = drm_api_create();
101
102 /* this is a software driver */
103 if (!api)
104 return NATIVE_PROBE_SUPPORTED;
105
106 /* the display does not support DRI2 or the driver mismatches */
107 if (!nprobe->data || strcmp(api->name, (const char *) nprobe->data) != 0)
108 return NATIVE_PROBE_FALLBACK;
109
110 return NATIVE_PROBE_EXACT;
111 }
112
113 const char *
114 native_get_name(void)
115 {
116 static char x11_name[32];
117
118 if (!api)
119 api = drm_api_create();
120
121 if (api)
122 snprintf(x11_name, sizeof(x11_name), "X11/%s", api->name);
123 else
124 snprintf(x11_name, sizeof(x11_name), "X11");
125
126 return x11_name;
127 }
128
129 struct native_display *
130 native_create_display(EGLNativeDisplayType dpy,
131 struct native_event_handler *event_handler)
132 {
133 struct native_display *ndpy = NULL;
134 boolean force_sw;
135
136 if (!api)
137 api = drm_api_create();
138
139 force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
140 if (api && !force_sw) {
141 ndpy = x11_create_dri2_display(dpy, event_handler, api);
142 }
143
144 if (!ndpy) {
145 EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING;
146
147 _eglLog(level, "use software fallback");
148 ndpy = x11_create_ximage_display(dpy, event_handler);
149 }
150
151 return ndpy;
152 }