mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-11-24 06:59:50 -05:00
Redesign the compositor / server interface.
This lets the compositor directly provide the implementation of the RMI objects for the surface object and a new compositor object. We avoid the manual forwarding of requests into the compositor and the clumsy compositor interface struct.
This commit is contained in:
parent
0ea4710b3d
commit
d2412e2c2e
9 changed files with 286 additions and 342 deletions
165
egl-compositor.c
165
egl-compositor.c
|
|
@ -89,10 +89,11 @@ struct egl_compositor {
|
|||
};
|
||||
|
||||
struct egl_surface {
|
||||
struct wl_surface base;
|
||||
struct egl_compositor *compositor;
|
||||
GLuint texture;
|
||||
struct wl_map map;
|
||||
EGLSurface surface;
|
||||
struct wl_surface *wl_surface;
|
||||
int width, height;
|
||||
struct wl_list link;
|
||||
};
|
||||
|
|
@ -102,6 +103,10 @@ struct screenshooter {
|
|||
struct egl_compositor *ec;
|
||||
};
|
||||
|
||||
struct screenshooter_interface {
|
||||
void (*shoot)(struct wl_client *client, struct screenshooter *shooter);
|
||||
};
|
||||
|
||||
static void
|
||||
screenshooter_shoot(struct wl_client *client, struct screenshooter *shooter)
|
||||
{
|
||||
|
|
@ -120,7 +125,7 @@ screenshooter_shoot(struct wl_client *client, struct screenshooter *shooter)
|
|||
}
|
||||
|
||||
static const struct wl_method screenshooter_methods[] = {
|
||||
{ "shoot", screenshooter_shoot, "", NULL }
|
||||
{ "shoot", "", NULL }
|
||||
};
|
||||
|
||||
static const struct wl_interface screenshooter_interface = {
|
||||
|
|
@ -129,6 +134,10 @@ static const struct wl_interface screenshooter_interface = {
|
|||
screenshooter_methods,
|
||||
};
|
||||
|
||||
struct screenshooter_interface screenshooter_implementation = {
|
||||
screenshooter_shoot
|
||||
};
|
||||
|
||||
static struct screenshooter *
|
||||
screenshooter_create(struct egl_compositor *ec)
|
||||
{
|
||||
|
|
@ -139,6 +148,7 @@ screenshooter_create(struct egl_compositor *ec)
|
|||
return NULL;
|
||||
|
||||
shooter->base.interface = &screenshooter_interface;
|
||||
shooter->base.implementation = (void(**)(void)) &screenshooter_implementation;
|
||||
shooter->ec = ec;
|
||||
|
||||
return shooter;
|
||||
|
|
@ -498,7 +508,8 @@ repaint(void *data)
|
|||
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
msecs = ts.tv_sec * 1000 + ts.tv_nsec / (1000 * 1000);
|
||||
wl_display_post_frame(ec->wl_display, ec->current_frame, msecs);
|
||||
wl_display_post_frame(ec->wl_display, &ec->base,
|
||||
ec->current_frame, msecs);
|
||||
ec->current_frame++;
|
||||
|
||||
wl_event_source_timer_update(ec->timer_source, 10);
|
||||
|
|
@ -518,36 +529,13 @@ schedule_repaint(struct egl_compositor *ec)
|
|||
wl_event_loop_add_idle(loop, repaint, ec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
notify_surface_create(struct wl_compositor *compositor,
|
||||
struct wl_surface *surface)
|
||||
{
|
||||
struct egl_compositor *ec = (struct egl_compositor *) compositor;
|
||||
struct egl_surface *es;
|
||||
|
||||
es = malloc(sizeof *es);
|
||||
if (es == NULL)
|
||||
return;
|
||||
|
||||
es->surface = EGL_NO_SURFACE;
|
||||
es->wl_surface = surface;
|
||||
wl_surface_set_data(surface, es);
|
||||
wl_list_insert(ec->surface_list.prev, &es->link);
|
||||
|
||||
glGenTextures(1, &es->texture);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_surface_destroy(struct wl_compositor *compositor,
|
||||
struct wl_surface *surface)
|
||||
surface_destroy(struct wl_client *client,
|
||||
struct wl_surface *surface)
|
||||
{
|
||||
struct egl_compositor *ec = (struct egl_compositor *) compositor;
|
||||
struct egl_surface *es;
|
||||
|
||||
es = wl_surface_get_data(surface);
|
||||
if (es == NULL)
|
||||
return;
|
||||
struct egl_surface *es = (struct egl_surface *) surface;
|
||||
struct egl_compositor *ec = es->compositor;
|
||||
|
||||
wl_list_remove(&es->link);
|
||||
egl_surface_destroy(es, ec);
|
||||
|
|
@ -556,16 +544,12 @@ notify_surface_destroy(struct wl_compositor *compositor,
|
|||
}
|
||||
|
||||
static void
|
||||
notify_surface_attach(struct wl_compositor *compositor,
|
||||
struct wl_surface *surface, uint32_t name,
|
||||
uint32_t width, uint32_t height, uint32_t stride)
|
||||
surface_attach(struct wl_client *client,
|
||||
struct wl_surface *surface, uint32_t name,
|
||||
uint32_t width, uint32_t height, uint32_t stride)
|
||||
{
|
||||
struct egl_compositor *ec = (struct egl_compositor *) compositor;
|
||||
struct egl_surface *es;
|
||||
|
||||
es = wl_surface_get_data(surface);
|
||||
if (es == NULL)
|
||||
return;
|
||||
struct egl_surface *es = (struct egl_surface *) surface;
|
||||
struct egl_compositor *ec = es->compositor;
|
||||
|
||||
if (es->surface != EGL_NO_SURFACE)
|
||||
eglDestroySurface(ec->display, es->surface);
|
||||
|
|
@ -584,30 +568,28 @@ notify_surface_attach(struct wl_compositor *compositor,
|
|||
}
|
||||
|
||||
static void
|
||||
notify_surface_map(struct wl_compositor *compositor,
|
||||
struct wl_surface *surface, struct wl_map *map)
|
||||
surface_map(struct wl_client *client,
|
||||
struct wl_surface *surface,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height)
|
||||
{
|
||||
struct egl_surface *es;
|
||||
struct egl_surface *es = (struct egl_surface *) surface;
|
||||
|
||||
es = wl_surface_get_data(surface);
|
||||
if (es == NULL)
|
||||
return;
|
||||
|
||||
es->map = *map;
|
||||
es->map.x = x;
|
||||
es->map.y = y;
|
||||
es->map.width = width;
|
||||
es->map.height = height;
|
||||
}
|
||||
|
||||
static void
|
||||
notify_surface_copy(struct wl_compositor *compositor,
|
||||
struct wl_surface *surface,
|
||||
int32_t dst_x, int32_t dst_y,
|
||||
uint32_t name, uint32_t stride,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height)
|
||||
surface_copy(struct wl_client *client,
|
||||
struct wl_surface *surface,
|
||||
int32_t dst_x, int32_t dst_y,
|
||||
uint32_t name, uint32_t stride,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height)
|
||||
{
|
||||
struct egl_compositor *ec = (struct egl_compositor *) compositor;
|
||||
struct egl_surface *es = (struct egl_surface *) surface;
|
||||
struct egl_compositor *ec = es->compositor;
|
||||
EGLSurface src;
|
||||
struct egl_surface *es;
|
||||
|
||||
es = wl_surface_get_data(surface);
|
||||
|
||||
/* FIXME: glCopyPixels should work, but then we'll have to
|
||||
* call eglMakeCurrent to set up the src and dest surfaces
|
||||
|
|
@ -623,23 +605,56 @@ notify_surface_copy(struct wl_compositor *compositor,
|
|||
}
|
||||
|
||||
static void
|
||||
notify_surface_damage(struct wl_compositor *compositor,
|
||||
struct wl_surface *surface,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height)
|
||||
surface_damage(struct wl_client *client,
|
||||
struct wl_surface *surface,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height)
|
||||
{
|
||||
/* FIXME: This need to take a damage region, of course. */
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
notify_commit(struct wl_compositor *compositor)
|
||||
const static struct wl_surface_interface surface_interface = {
|
||||
surface_destroy,
|
||||
surface_attach,
|
||||
surface_map,
|
||||
surface_copy,
|
||||
surface_damage
|
||||
};
|
||||
|
||||
static void
|
||||
compositor_create_surface(struct wl_client *client,
|
||||
struct wl_compositor *compositor, uint32_t id)
|
||||
{
|
||||
struct egl_compositor *ec = (struct egl_compositor *) compositor;
|
||||
struct egl_surface *es;
|
||||
|
||||
es = malloc(sizeof *es);
|
||||
if (es == NULL)
|
||||
/* FIXME: Send OOM event. */
|
||||
return;
|
||||
|
||||
es->compositor = ec;
|
||||
es->surface = EGL_NO_SURFACE;
|
||||
wl_list_insert(ec->surface_list.prev, &es->link);
|
||||
glGenTextures(1, &es->texture);
|
||||
wl_client_add_surface(client, &es->base,
|
||||
&surface_interface, id);
|
||||
}
|
||||
|
||||
static void
|
||||
compositor_commit(struct wl_client *client,
|
||||
struct wl_compositor *compositor, uint32_t key)
|
||||
{
|
||||
struct egl_compositor *ec = (struct egl_compositor *) compositor;
|
||||
|
||||
schedule_repaint(ec);
|
||||
|
||||
return ec->current_frame;
|
||||
wl_client_send_acknowledge(client, compositor, key, ec->current_frame);
|
||||
}
|
||||
|
||||
const static struct wl_compositor_interface compositor_interface = {
|
||||
compositor_create_surface,
|
||||
compositor_commit
|
||||
};
|
||||
|
||||
static struct egl_surface *
|
||||
pick_surface(struct egl_input_device *device)
|
||||
{
|
||||
|
|
@ -677,7 +692,7 @@ notify_motion(struct egl_input_device *device, int x, int y)
|
|||
if (es) {
|
||||
sx = (x - es->map.x) * es->width / es->map.width;
|
||||
sy = (y - es->map.y) * es->height / es->map.height;
|
||||
wl_surface_post_event(es->wl_surface, &device->base,
|
||||
wl_surface_post_event(&es->base, &device->base,
|
||||
WL_INPUT_MOTION, x, y, sx, sy);
|
||||
}
|
||||
|
||||
|
|
@ -715,7 +730,7 @@ notify_button(struct egl_input_device *device,
|
|||
sy = (device->y - es->map.y) * es->height / es->map.height;
|
||||
|
||||
/* FIXME: Swallow click on raise? */
|
||||
wl_surface_post_event(es->wl_surface, &device->base,
|
||||
wl_surface_post_event(&es->base, &device->base,
|
||||
WL_INPUT_BUTTON, button, state,
|
||||
device->x, device->y, sx, sy);
|
||||
|
||||
|
|
@ -737,29 +752,16 @@ notify_key(struct egl_input_device *device,
|
|||
schedule_repaint(ec);
|
||||
} else if (!wl_list_empty(&ec->surface_list)) {
|
||||
if (device->focus_surface != NULL)
|
||||
wl_surface_post_event(device->focus_surface->wl_surface,
|
||||
wl_surface_post_event(&device->focus_surface->base,
|
||||
&device->base,
|
||||
WL_INPUT_KEY, key, state);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_compositor_interface interface = {
|
||||
notify_surface_create,
|
||||
notify_surface_destroy,
|
||||
notify_surface_attach,
|
||||
notify_surface_map,
|
||||
notify_surface_copy,
|
||||
notify_surface_damage,
|
||||
notify_commit,
|
||||
};
|
||||
|
||||
struct evdev_input_device *
|
||||
evdev_input_device_create(struct egl_input_device *device,
|
||||
struct wl_display *display, const char *path);
|
||||
|
||||
void
|
||||
egl_device_get_position(struct egl_input_device *device, int32_t *x, int32_t *y);
|
||||
|
||||
static void
|
||||
create_input_device(struct egl_compositor *ec, const char *glob)
|
||||
{
|
||||
|
|
@ -984,7 +986,6 @@ egl_compositor_create(struct wl_display *display)
|
|||
if (ec == NULL)
|
||||
return NULL;
|
||||
|
||||
ec->base.interface = &interface;
|
||||
ec->wl_display = display;
|
||||
|
||||
ec->display = eglCreateDisplayNative(gem_device, "i965");
|
||||
|
|
@ -1027,6 +1028,8 @@ egl_compositor_create(struct wl_display *display)
|
|||
glOrtho(0, ec->width, ec->height, 0, 0, 1000.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
wl_display_set_compositor(display, &ec->base, &compositor_interface);
|
||||
|
||||
wl_list_init(&ec->input_device_list);
|
||||
for (i = 0; option_input_devices[i]; i++)
|
||||
create_input_device(ec, option_input_devices[i]);
|
||||
|
|
@ -1086,8 +1089,6 @@ int main(int argc, char *argv[])
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
wl_display_set_compositor(display, &ec->base);
|
||||
|
||||
if (wl_display_add_socket(display, socket_name, sizeof socket_name)) {
|
||||
fprintf(stderr, "failed to add socket: %m\n");
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue