14 #include <wayland-client.h>
15 #include "wayland-egl.h"
16 #include "wayland-egl-priv.h"
17 #include "wayland-drm-client-protocol.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
->fd
= -1;
106 egl_display
->device_name
= NULL
;
107 egl_display
->authenticated
= false;
109 egl_display
->glFlush
= (void (*)(void)) get_flush_address();
111 wl_display_add_global_listener(display
, wl_display_handle_global
,
118 wl_egl_display_destroy(struct wl_egl_display
*egl_display
)
121 free(egl_display
->device_name
);
122 close(egl_display
->fd
);
124 wl_drm_destroy(egl_display
->drm
);
130 wl_egl_window_resize(struct wl_egl_window
*egl_window
,
131 int width
, int height
,
134 egl_window
->width
= width
;
135 egl_window
->height
= height
;
140 WL_EGL_EXPORT
struct wl_egl_window
*
141 wl_egl_window_create(struct wl_egl_display
*egl_display
,
142 struct wl_surface
*surface
,
143 int width
, int height
,
144 struct wl_visual
*visual
)
146 struct wl_egl_window
*egl_window
;
148 egl_window
= malloc(sizeof *egl_window
);
152 egl_window
->surface
= surface
;
153 egl_window
->visual
= visual
;
154 wl_egl_window_resize(egl_window
, width
, height
, 0, 0);
155 egl_window
->attached_width
= 0;
156 egl_window
->attached_height
= 0;
162 wl_egl_window_destroy(struct wl_egl_window
*egl_window
)
168 wl_egl_window_get_attached_size(struct wl_egl_window
*egl_window
,
169 int *width
, int *height
)
172 *width
= egl_window
->attached_width
;
174 *height
= egl_window
->attached_height
;
177 WL_EGL_EXPORT
struct wl_egl_pixmap
*
178 wl_egl_pixmap_create(struct wl_egl_display
*egl_display
,
179 int width
, int height
,
180 struct wl_visual
*visual
, uint32_t flags
)
182 struct wl_egl_pixmap
*egl_pixmap
;
184 egl_pixmap
= malloc(sizeof *egl_pixmap
);
185 if (egl_pixmap
== NULL
)
188 egl_pixmap
->display
= egl_display
;
189 egl_pixmap
->width
= width
;
190 egl_pixmap
->height
= height
;
191 egl_pixmap
->visual
= visual
;
192 egl_pixmap
->name
= 0;
193 egl_pixmap
->stride
= 0;
195 egl_pixmap
->destroy
= NULL
;
201 wl_egl_pixmap_destroy(struct wl_egl_pixmap
*egl_pixmap
)
203 if (egl_pixmap
->destroy
)
204 egl_pixmap
->destroy(egl_pixmap
);
208 WL_EGL_EXPORT
struct wl_buffer
*
209 wl_egl_pixmap_create_buffer(struct wl_egl_display
*egl_display
,
210 struct wl_egl_pixmap
*egl_pixmap
)
212 if (egl_pixmap
->name
== 0)
215 return wl_drm_create_buffer(egl_display
->drm
, egl_pixmap
->name
,
216 egl_pixmap
->width
, egl_pixmap
->height
,
217 egl_pixmap
->stride
, egl_pixmap
->visual
);
221 wl_egl_pixmap_flush(struct wl_egl_display
*egl_display
,
222 struct wl_egl_pixmap
*egl_pixmap
)
224 if (egl_display
->glFlush
)
225 egl_display
->glFlush();