4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
7 * Stanislav Vorobiov <s.vorobiov@samsung.com>
8 * Jinhyung Jo <jinhyung.jo@samsung.com>
9 * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
34 #include "yagl_x11_display.h"
35 #include "yagl_x11_drawable.h"
36 #include "yagl_x11_image.h"
37 #include "yagl_native_platform.h"
39 #include "yagl_malloc.h"
40 #include "yagl_dri2.h"
41 #include "yagl_dri3.h"
43 #include <X11/Xutil.h>
44 #include <X11/extensions/XShm.h>
45 #include <sys/fcntl.h>
49 static int yagl_x11_display_dri2_authenticate(Display *x_dpy, uint32_t id)
51 if (!yagl_DRI2Authenticate(x_dpy,
52 RootWindow(x_dpy, DefaultScreen(x_dpy)),
54 fprintf(stderr, "Critical error! Failed to DRI2Authenticate on YaGL display, DRI2 not enabled ?\n");
61 static int yagl_x11_display_dri2_init(Display *x_dpy, char **dri_device)
64 int event_base, error_base;
65 int dri_major, dri_minor;
66 char *dri_driver = NULL;
70 YAGL_LOG_FUNC_SET(eglGetDisplay);
74 if (!yagl_DRI2QueryExtension(x_dpy, &event_base, &error_base)) {
75 fprintf(stderr, "Critical error! Failed to DRI2QueryExtension on YaGL display, DRI2 not enabled ?\n");
79 YAGL_LOG_TRACE("DRI2QueryExtension returned %d %d",
80 event_base, error_base);
82 if (!yagl_DRI2QueryVersion(x_dpy, &dri_major, &dri_minor)) {
83 fprintf(stderr, "Critical error! Failed to DRI2QueryVersion on YaGL display, DRI2 not enabled ?\n");
87 YAGL_LOG_TRACE("DRI2QueryVersion returned %d %d",
88 dri_major, dri_minor);
90 if (!yagl_DRI2Connect(x_dpy,
91 RootWindow(x_dpy, DefaultScreen(x_dpy)),
94 fprintf(stderr, "Critical error! Failed to DRI2Connect on YaGL display, DRI2 not enabled ?\n");
98 YAGL_LOG_TRACE("DRI2Connect returned %s %s",
99 dri_driver, *dri_device);
101 drm_fd = open(*dri_device, O_RDWR);
104 fprintf(stderr, "Critical error! Failed to open(\"%s\"): %s\n", *dri_device, strerror(errno));
108 memset(&magic, 0, sizeof(magic));
110 ret = drmGetMagic(drm_fd, &magic);
113 fprintf(stderr, "Critical error! drmGetMagic failed: %s\n", strerror(-ret));
117 if (!yagl_x11_display_dri2_authenticate(x_dpy, magic)) {
139 static int yagl_x11_display_authenticate(struct yagl_native_display *dpy,
142 struct yagl_x11_display *x11_dpy = (struct yagl_x11_display*)dpy;
143 Display *x_dpy = YAGL_X11_DPY(dpy->os_dpy);
145 if (!x11_dpy->dri3_supported) {
146 return yagl_x11_display_dri2_authenticate(x_dpy, id);
152 static struct yagl_native_drawable
153 *yagl_x11_display_wrap_window(struct yagl_native_display *dpy,
154 yagl_os_window os_window)
156 struct yagl_x11_display *x11_dpy = (struct yagl_x11_display*)dpy;
158 return x11_dpy->create_drawable(dpy, os_window, 0, 0);
161 static struct yagl_native_drawable
162 *yagl_x11_display_wrap_pixmap(struct yagl_native_display *dpy,
163 yagl_os_pixmap os_pixmap)
165 struct yagl_x11_display *x11_dpy = (struct yagl_x11_display*)dpy;
167 return x11_dpy->create_drawable(dpy, os_pixmap, 0, 1);
170 static struct yagl_native_drawable
171 *yagl_x11_display_create_pixmap(struct yagl_native_display *dpy,
176 struct yagl_x11_display *x11_dpy = (struct yagl_x11_display*)dpy;
177 struct yagl_native_drawable *drawable;
178 Display *x_dpy = YAGL_X11_DPY(dpy->os_dpy);
179 Pixmap x_pixmap = XCreatePixmap(x_dpy,
180 RootWindow(x_dpy, DefaultScreen(x_dpy)),
181 width, height, depth);
187 drawable = x11_dpy->create_drawable(dpy, (yagl_os_pixmap)x_pixmap, 1, 1);
190 XFreePixmap(x_dpy, x_pixmap);
197 static struct yagl_native_image
198 *yagl_x11_display_create_image(struct yagl_native_display *dpy,
203 return yagl_x11_image_create(dpy, width, height, depth);
206 static int yagl_x11_display_get_visual(struct yagl_native_display *dpy,
210 Display *x_dpy = YAGL_X11_DPY(dpy->os_dpy);
214 screen = XScreenNumberOfScreen(XDefaultScreenOfDisplay(x_dpy));
217 * 24-bit is the highest supported by soft framebuffer.
219 if (!XMatchVisualInfo(x_dpy, screen, 24, TrueColor, &vi)) {
223 *visual_id = XVisualIDFromVisual(vi.visual);
224 *visual_type = TrueColor;
229 static void yagl_x11_display_destroy(struct yagl_native_display *dpy)
231 struct yagl_x11_display *x11_dpy = (struct yagl_x11_display*)dpy;
232 Display *x_dpy = YAGL_X11_DPY(dpy->os_dpy);
235 int fd = dpy->drm_dev->fd;
236 vigs_drm_device_destroy(dpy->drm_dev);
240 yagl_native_display_cleanup(dpy);
242 if (x11_dpy->own_dpy) {
243 XCloseDisplay(x_dpy);
249 struct yagl_native_display *yagl_x11_display_create(struct yagl_native_platform *platform,
250 yagl_os_display os_dpy,
254 Display *x_dpy = YAGL_X11_DPY(os_dpy);
255 struct yagl_x11_display *dpy;
259 struct vigs_drm_device *drm_dev = NULL;
260 char *dri_device = NULL;
263 YAGL_LOG_FUNC_SET(eglGetDisplay);
265 dpy = yagl_malloc0(sizeof(*dpy));
267 dpy->own_dpy = own_dpy;
269 dpy->xshm_images_supported = XShmQueryVersion(x_dpy,
273 dpy->xshm_pixmaps_supported = pixmaps;
275 YAGL_LOG_DEBUG("XShm images are%s supported, version %d, %d (pixmaps = %d)",
276 (dpy->xshm_images_supported ? "" : " NOT"),
281 dpy->create_drawable = &yagl_x11_drawable_create;
284 int drm_fd = yagl_dri3_display_init(x_dpy, &dri_device);
287 YAGL_LOG_DEBUG("DRI3 init failed. Falling back to DRI2...");
289 drm_fd = yagl_x11_display_dri2_init(x_dpy, &dri_device);
296 dpy->create_drawable = &yagl_dri3_drawable_create;
297 dpy->dri3_supported = 1;
298 platform->buffer_age_supported = 1;
301 ret = vigs_drm_device_create(drm_fd, &drm_dev);
305 "Critical error! vigs_drm_device_create failed: %s\n",
314 yagl_native_display_init(&dpy->base,
320 dpy->base.authenticate = &yagl_x11_display_authenticate;
321 dpy->base.wrap_window = &yagl_x11_display_wrap_window;
322 dpy->base.wrap_pixmap = &yagl_x11_display_wrap_pixmap;
323 dpy->base.create_pixmap = &yagl_x11_display_create_pixmap;
324 dpy->base.create_image = &yagl_x11_display_create_image;
325 dpy->base.get_visual = &yagl_x11_display_get_visual;
326 dpy->base.destroy = &yagl_x11_display_destroy;