14 #include <wayland-client.h>
17 #include "wayland-egl.h"
18 #include "wayland-egl-priv.h"
21 drm_handle_device(void *data
, struct wl_drm
*drm
, const char *device
)
23 struct wl_egl_display
*egl_display
= data
;
26 egl_display
->device_name
= strdup(device
);
28 egl_display
->fd
= open(egl_display
->device_name
, O_RDWR
);
30 if (egl_display
->fd
== -1) {
31 fprintf(stderr
, "wayland-egl: could not open %s (%s)",
32 egl_display
->device_name
, strerror(errno
));
35 drmGetMagic(egl_display
->fd
, &magic
);
36 wl_drm_authenticate(egl_display
->drm
, magic
);
40 drm_handle_authenticated(void *data
, struct wl_drm
*drm
)
42 struct wl_egl_display
*egl_display
= data
;
44 egl_display
->authenticated
= true;
47 static const struct wl_drm_listener drm_listener
= {
49 drm_handle_authenticated
53 wl_display_handle_global(struct wl_display
*display
, uint32_t id
,
54 const char *interface
, uint32_t version
, void *data
)
56 struct wl_egl_display
*egl_display
= data
;
58 if (strcmp(interface
, "drm") == 0) {
59 egl_display
->drm
= wl_drm_create(display
, id
);
60 wl_drm_add_listener(egl_display
->drm
, &drm_listener
,
65 /* stolen from egl_dri2:dri2_load() */
69 void *(*get_proc_address
)(const char *procname
);
71 handle
= dlopen(NULL
, RTLD_LAZY
| RTLD_GLOBAL
);
73 get_proc_address
= (void* (*)(const char *))
74 dlsym(handle
, "_glapi_get_proc_address");
75 /* no need to keep a reference */
80 * If glapi is not available, loading DRI drivers will fail. Ideally, we
81 * should load one of libGL, libGLESv1_CM, or libGLESv2 and go on. But if
82 * the app has loaded another one of them with RTLD_LOCAL, there may be
83 * unexpected behaviors later because there will be two copies of glapi
84 * (with global variables of the same names!) in the memory.
86 if (!get_proc_address
) {
87 fprintf(stderr
, "failed to find _glapi_get_proc_address");
91 return get_proc_address("glFlush");
94 WL_EGL_EXPORT
struct wl_egl_display
*
95 wl_egl_display_create(struct wl_display
*display
)
97 struct wl_egl_display
*egl_display
;
99 egl_display
= malloc(sizeof *egl_display
);
103 egl_display
->display
= display
;
104 egl_display
->drm
= NULL
;
105 egl_display
->device_name
= NULL
;
106 egl_display
->authenticated
= false;
108 egl_display
->glFlush
= (void (*)(void)) get_flush_address();
110 wl_display_add_global_listener(display
, wl_display_handle_global
,
117 wl_egl_display_destroy(struct wl_egl_display
*egl_display
)
120 free(egl_display
->device_name
);
121 close(egl_display
->fd
);
123 wl_drm_destroy(egl_display
->drm
);
129 wl_egl_window_resize(struct wl_egl_window
*egl_window
,
130 int width
, int height
,
133 egl_window
->width
= width
;
134 egl_window
->height
= height
;
139 WL_EGL_EXPORT
struct wl_egl_window
*
140 wl_egl_window_create(struct wl_surface
*surface
,
141 int width
, int height
,
142 struct wl_visual
*visual
)
144 struct wl_egl_window
*egl_window
;
146 egl_window
= malloc(sizeof *egl_window
);
150 egl_window
->surface
= surface
;
151 egl_window
->visual
= visual
;
152 wl_egl_window_resize(egl_window
, width
, height
, 0, 0);
153 egl_window
->attached_width
= 0;
154 egl_window
->attached_height
= 0;
160 wl_egl_window_destroy(struct wl_egl_window
*egl_window
)
166 wl_egl_window_get_attached_size(struct wl_egl_window
*egl_window
,
167 int *width
, int *height
)
170 *width
= egl_window
->attached_width
;
172 *height
= egl_window
->attached_height
;
175 WL_EGL_EXPORT
struct wl_egl_pixmap
*
176 wl_egl_pixmap_create(struct wl_egl_display
*egl_display
,
177 int width
, int height
,
178 struct wl_visual
*visual
, uint32_t flags
)
180 struct wl_egl_pixmap
*egl_pixmap
;
182 egl_pixmap
= malloc(sizeof *egl_pixmap
);
183 if (egl_pixmap
== NULL
)
186 egl_pixmap
->display
= egl_display
;
187 egl_pixmap
->width
= width
;
188 egl_pixmap
->height
= height
;
189 egl_pixmap
->visual
= visual
;
190 egl_pixmap
->name
= 0;
191 egl_pixmap
->stride
= 0;
193 egl_pixmap
->destroy
= NULL
;
199 wl_egl_pixmap_destroy(struct wl_egl_pixmap
*egl_pixmap
)
201 if (egl_pixmap
->destroy
)
202 egl_pixmap
->destroy(egl_pixmap
);
206 WL_EGL_EXPORT
struct wl_buffer
*
207 wl_egl_pixmap_create_buffer(struct wl_egl_display
*egl_display
,
208 struct wl_egl_pixmap
*egl_pixmap
)
210 if (egl_pixmap
->name
== 0)
213 return wl_drm_create_buffer(egl_display
->drm
, egl_pixmap
->name
,
214 egl_pixmap
->width
, egl_pixmap
->height
,
215 egl_pixmap
->stride
, egl_pixmap
->visual
);
219 wl_egl_pixmap_flush(struct wl_egl_display
*egl_display
,
220 struct wl_egl_pixmap
*egl_pixmap
)
222 if (egl_display
->glFlush
)
223 egl_display
->glFlush();