native_x11.c revision 870a9d643b1f256e6a379d96a325284dd2f7eeea
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 "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
38static struct drm_api *api;
39
40static void
41x11_probe_destroy(struct native_probe *nprobe)
42{
43   if (nprobe->data)
44      FREE(nprobe->data);
45   FREE(nprobe);
46}
47
48struct native_probe *
49native_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
93enum native_probe_result
94native_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
113const char *
114native_get_name(void)
115{
116   static char x11_name[32];
117
118   if (!api)
119      api = drm_api_create();
120
121   if (api)
122      util_snprintf(x11_name, sizeof(x11_name), "X11/%s", api->name);
123   else
124      util_snprintf(x11_name, sizeof(x11_name), "X11");
125
126   return x11_name;
127}
128
129struct native_display *
130native_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}
153