st/egl: Introduce native_platform.
[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 <string.h>
27 #include "util/u_debug.h"
28 #include "util/u_memory.h"
29 #include "util/u_string.h"
30 #include "egllog.h"
31
32 #include "native_x11.h"
33 #include "x11_screen.h"
34
35 #include "state_tracker/drm_driver.h"
36
37 #define X11_PROBE_MAGIC 0x11980BE /* "X11PROBE" */
38
39 static void
40 x11_probe_destroy(struct native_probe *nprobe)
41 {
42 if (nprobe->data)
43 FREE(nprobe->data);
44 FREE(nprobe);
45 }
46
47 static struct native_probe *
48 x11_create_probe(void *dpy)
49 {
50 struct native_probe *nprobe;
51 struct x11_screen *xscr;
52 int scr;
53 const char *driver_name = NULL;
54 Display *xdpy;
55
56 nprobe = CALLOC_STRUCT(native_probe);
57 if (!nprobe)
58 return NULL;
59
60 xdpy = dpy;
61 if (!xdpy) {
62 xdpy = XOpenDisplay(NULL);
63 if (!xdpy) {
64 FREE(nprobe);
65 return NULL;
66 }
67 }
68
69 scr = DefaultScreen(xdpy);
70 xscr = x11_screen_create(xdpy, scr);
71 if (xscr) {
72 if (x11_screen_support(xscr, X11_SCREEN_EXTENSION_DRI2)) {
73 driver_name = x11_screen_probe_dri2(xscr, NULL, NULL);
74 if (driver_name)
75 nprobe->data = strdup(driver_name);
76 }
77
78 x11_screen_destroy(xscr);
79 }
80
81 if (xdpy != dpy)
82 XCloseDisplay(xdpy);
83
84 nprobe->magic = X11_PROBE_MAGIC;
85 nprobe->display = dpy;
86
87 nprobe->destroy = x11_probe_destroy;
88
89 return nprobe;
90 }
91
92 static enum native_probe_result
93 x11_get_probe_result(struct native_probe *nprobe)
94 {
95 if (!nprobe || nprobe->magic != X11_PROBE_MAGIC)
96 return NATIVE_PROBE_UNKNOWN;
97
98 /* this is a software driver */
99 if (!driver_descriptor.create_screen)
100 return NATIVE_PROBE_SUPPORTED;
101
102 /* the display does not support DRI2 or the driver mismatches */
103 if (!nprobe->data || strcmp(driver_descriptor.name, (const char *) nprobe->data) != 0)
104 return NATIVE_PROBE_FALLBACK;
105
106 return NATIVE_PROBE_EXACT;
107 }
108
109 static struct native_display *
110 native_create_display(void *dpy, struct native_event_handler *event_handler)
111 {
112 struct native_display *ndpy = NULL;
113 boolean force_sw;
114
115 force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
116 if (!driver_descriptor.create_screen)
117 force_sw = TRUE;
118
119 if (!force_sw) {
120 ndpy = x11_create_dri2_display((Display *) dpy, event_handler);
121 }
122
123 if (!ndpy) {
124 EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING;
125
126 _eglLog(level, "use software fallback");
127 ndpy = x11_create_ximage_display((Display *) dpy, event_handler);
128 }
129
130 return ndpy;
131 }
132
133 static void
134 x11_init_platform(struct native_platform *nplat)
135 {
136 static char x11_name[32];
137
138 if (nplat->name)
139 return;
140
141 util_snprintf(x11_name, sizeof(x11_name), "X11/%s", driver_descriptor.name);
142
143 nplat->name = x11_name;
144 nplat->create_probe = x11_create_probe;
145 nplat->get_probe_result = x11_get_probe_result;
146 nplat->create_display = native_create_display;
147 }
148
149 static struct native_platform x11_platform;
150
151 const struct native_platform *
152 native_get_platform(void)
153 {
154 x11_init_platform(&x11_platform);
155 return &x11_platform;
156 }