native_x11.c revision 1f92cf55e1d19864a51e620a14c6912e94cd14ea
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
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#include <stdio.h>
26#include <string.h>
27#include "util/u_debug.h"
28#include "util/u_memory.h"
29#include "state_tracker/drm_api.h"
30#include "egllog.h"
31
32#include "native_x11.h"
33#include "x11_screen.h"
34
35#define X11_PROBE_MAGIC 0x11980BE /* "X11PROBE" */
36
37static struct drm_api *api;
38
39static void
40x11_probe_destroy(struct native_probe *nprobe)
41{
42   if (nprobe->data)
43      free(nprobe->data);
44   free(nprobe);
45}
46
47struct native_probe *
48native_create_probe(EGLNativeDisplayType 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
92enum native_probe_result
93native_get_probe_result(struct native_probe *nprobe)
94{
95   if (!nprobe || nprobe->magic != X11_PROBE_MAGIC)
96      return NATIVE_PROBE_UNKNOWN;
97
98   if (!api)
99      api = drm_api_create();
100
101   /* this is a software driver */
102   if (!api)
103      return NATIVE_PROBE_SUPPORTED;
104
105   /* the display does not support DRI2 or the driver mismatches */
106   if (!nprobe->data || strcmp(api->name, (const char *) nprobe->data) != 0)
107      return NATIVE_PROBE_FALLBACK;
108
109   return NATIVE_PROBE_EXACT;
110}
111
112const char *
113native_get_name(void)
114{
115   static char x11_name[32];
116
117   if (!api)
118      api = drm_api_create();
119
120   if (api)
121      snprintf(x11_name, sizeof(x11_name), "X11/%s", api->name);
122   else
123      snprintf(x11_name, sizeof(x11_name), "X11");
124
125   return x11_name;
126}
127
128struct native_display *
129native_create_display(EGLNativeDisplayType dpy,
130                      struct native_event_handler *event_handler)
131{
132   struct native_display *ndpy = NULL;
133   boolean force_sw;
134
135   if (!api)
136      api = drm_api_create();
137
138   force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
139   if (api && !force_sw) {
140      ndpy = x11_create_dri2_display(dpy, event_handler, api);
141   }
142
143   if (!ndpy) {
144      EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING;
145
146      _eglLog(level, "use software fallback");
147      ndpy = x11_create_ximage_display(dpy, event_handler);
148   }
149
150   return ndpy;
151}
152