native_x11.c revision ea05299ce54ea0463626277907cab8e849884740
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
39static void
40x11_probe_destroy(struct native_probe *nprobe)
41{
42   if (nprobe->data)
43      FREE(nprobe->data);
44   FREE(nprobe);
45}
46
47static struct native_probe *
48x11_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
92static enum native_probe_result
93x11_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
109static struct native_display *
110native_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
133static void
134x11_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
149static struct native_platform x11_platform;
150
151const struct native_platform *
152native_get_x11_platform(void)
153{
154   x11_init_platform(&x11_platform);
155   return &x11_platform;
156}
157