Update to new fd and wl_registry APIs

This commit updates the clients and the wayland compositor backend to
use the new wl_registry mechanism and the thread safe fd API.
dev
Kristian Høgsberg 12 years ago
parent 4e07236e87
commit fa80e11c84
  1. 13
      clients/desktop-shell.c
  2. 11
      clients/editor.c
  3. 13
      clients/keyboard.c
  4. 22
      clients/screenshot.c
  5. 37
      clients/simple-egl.c
  6. 43
      clients/simple-shm.c
  7. 39
      clients/simple-touch.c
  8. 9
      clients/tablet-shell.c
  9. 24
      clients/weston-info.c
  10. 133
      clients/window.c
  11. 12
      clients/window.h
  12. 8
      clients/wscreensaver.c
  13. 49
      src/compositor-wayland.c

@ -1021,21 +1021,21 @@ create_output(struct desktop *desktop, uint32_t id)
if (!output) if (!output)
return; return;
output->output = wl_display_bind(display_get_display(desktop->display), output->output =
id, &wl_output_interface); display_bind(desktop->display, id, &wl_output_interface, 1);
wl_list_insert(&desktop->outputs, &output->link); wl_list_insert(&desktop->outputs, &output->link);
} }
static void static void
global_handler(struct wl_display *display, uint32_t id, global_handler(struct display *display, uint32_t id,
const char *interface, uint32_t version, void *data) const char *interface, uint32_t version, void *data)
{ {
struct desktop *desktop = data; struct desktop *desktop = data;
if (!strcmp(interface, "desktop_shell")) { if (!strcmp(interface, "desktop_shell")) {
desktop->shell = desktop->shell = display_bind(desktop->display,
wl_display_bind(display, id, &desktop_shell_interface); id, &desktop_shell_interface, 1);
desktop_shell_add_listener(desktop->shell, &listener, desktop); desktop_shell_add_listener(desktop->shell, &listener, desktop);
} else if (!strcmp(interface, "wl_output")) { } else if (!strcmp(interface, "wl_output")) {
create_output(desktop, id); create_output(desktop, id);
@ -1092,8 +1092,7 @@ int main(int argc, char *argv[])
} }
display_set_user_data(desktop.display, &desktop); display_set_user_data(desktop.display, &desktop);
wl_display_add_global_listener(display_get_display(desktop.display), display_set_global_handler(desktop.display, global_handler);
global_handler, &desktop);
wl_list_for_each(output, &desktop.outputs, link) { wl_list_for_each(output, &desktop.outputs, link) {
struct wl_surface *surface; struct wl_surface *surface;

@ -835,14 +835,15 @@ editor_button_handler(struct widget *widget,
} }
static void static void
global_handler(struct wl_display *display, uint32_t id, global_handler(struct display *display, uint32_t name,
const char *interface, uint32_t version, void *data) const char *interface, uint32_t version, void *data)
{ {
struct editor *editor = data; struct editor *editor = data;
if (!strcmp(interface, "text_model_factory")) { if (!strcmp(interface, "text_model_factory")) {
editor->text_model_factory = wl_display_bind(display, id, editor->text_model_factory =
&text_model_factory_interface); display_bind(display, name,
&text_model_factory_interface, 1);
} }
} }
@ -856,9 +857,9 @@ main(int argc, char *argv[])
fprintf(stderr, "failed to create display: %m\n"); fprintf(stderr, "failed to create display: %m\n");
return -1; return -1;
} }
wl_display_add_global_listener(display_get_display(editor.display),
global_handler, &editor);
display_set_user_data(editor.display, &editor);
display_set_global_handler(editor.display, global_handler);
editor.window = window_create(editor.display); editor.window = window_create(editor.display);
editor.widget = frame_create(editor.window, &editor); editor.widget = frame_create(editor.window, &editor);

@ -395,15 +395,18 @@ static const struct input_method_listener input_method_listener = {
}; };
static void static void
global_handler(struct wl_display *display, uint32_t id, global_handler(struct display *display, uint32_t name,
const char *interface, uint32_t version, void *data) const char *interface, uint32_t version, void *data)
{ {
struct virtual_keyboard *keyboard = data; struct virtual_keyboard *keyboard = data;
if (!strcmp(interface, "input_panel")) { if (!strcmp(interface, "input_panel")) {
keyboard->input_panel = wl_display_bind(display, id, &input_panel_interface); keyboard->input_panel =
display_bind(display, name, &input_panel_interface, 1);
} else if (!strcmp(interface, "input_method")) { } else if (!strcmp(interface, "input_method")) {
keyboard->input_method = wl_display_bind(display, id, &input_method_interface); keyboard->input_method =
display_bind(display, name,
&input_method_interface, 1);
input_method_add_listener(keyboard->input_method, &input_method_listener, keyboard); input_method_add_listener(keyboard->input_method, &input_method_listener, keyboard);
} }
} }
@ -464,10 +467,8 @@ main(int argc, char *argv[])
virtual_keyboard.context = NULL; virtual_keyboard.context = NULL;
virtual_keyboard.preedit_string = NULL; virtual_keyboard.preedit_string = NULL;
wl_display_add_global_listener(display_get_display(virtual_keyboard.display),
global_handler, &virtual_keyboard);
display_set_user_data(virtual_keyboard.display, &virtual_keyboard); display_set_user_data(virtual_keyboard.display, &virtual_keyboard);
display_set_global_handler(virtual_keyboard.display, global_handler);
display_set_output_configure_handler(virtual_keyboard.display, handle_output_configure); display_set_output_configure_handler(virtual_keyboard.display, handle_output_configure);
display_run(virtual_keyboard.display); display_run(virtual_keyboard.display);

@ -109,23 +109,29 @@ static const struct screenshooter_listener screenshooter_listener = {
}; };
static void static void
handle_global(struct wl_display *display, uint32_t id, handle_global(void *data, struct wl_registry *registry,
const char *interface, uint32_t version, void *data) uint32_t name, const char *interface, uint32_t version)
{ {
static struct screenshooter_output *output; static struct screenshooter_output *output;
if (strcmp(interface, "wl_output") == 0) { if (strcmp(interface, "wl_output") == 0) {
output = malloc(sizeof *output); output = malloc(sizeof *output);
output->output = wl_display_bind(display, id, &wl_output_interface); output->output = wl_registry_bind(registry, name,
&wl_output_interface, 1);
wl_list_insert(&output_list, &output->link); wl_list_insert(&output_list, &output->link);
wl_output_add_listener(output->output, &output_listener, output); wl_output_add_listener(output->output, &output_listener, output);
} else if (strcmp(interface, "wl_shm") == 0) { } else if (strcmp(interface, "wl_shm") == 0) {
shm = wl_display_bind(display, id, &wl_shm_interface); shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
} else if (strcmp(interface, "screenshooter") == 0) { } else if (strcmp(interface, "screenshooter") == 0) {
screenshooter = wl_display_bind(display, id, &screenshooter_interface); screenshooter = wl_registry_bind(registry, name,
&screenshooter_interface, 1);
} }
} }
static const struct wl_registry_listener registry_listener = {
handle_global
};
static struct wl_buffer * static struct wl_buffer *
create_shm_buffer(int width, int height, void **data_out) create_shm_buffer(int width, int height, void **data_out)
{ {
@ -231,6 +237,7 @@ set_buffer_size(int *width, int *height)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct wl_display *display; struct wl_display *display;
struct wl_registry *registry;
struct screenshooter_output *output; struct screenshooter_output *output;
int width, height; int width, height;
@ -241,8 +248,9 @@ int main(int argc, char *argv[])
} }
wl_list_init(&output_list); wl_list_init(&output_list);
wl_display_add_global_listener(display, handle_global, &screenshooter); registry = wl_display_get_registry(display);
wl_display_iterate(display, WL_DISPLAY_READABLE); wl_registry_add_listener(registry, &registry_listener, NULL);
wl_display_dispatch(display);
wl_display_roundtrip(display); wl_display_roundtrip(display);
if (screenshooter == NULL) { if (screenshooter == NULL) {
fprintf(stderr, "display doesn't support screenshooter\n"); fprintf(stderr, "display doesn't support screenshooter\n");

@ -41,6 +41,7 @@ struct seat;
struct display { struct display {
struct wl_display *display; struct wl_display *display;
struct wl_registry *registry;
struct wl_compositor *compositor; struct wl_compositor *compositor;
struct wl_shell *shell; struct wl_shell *shell;
struct wl_seat *seat; struct wl_seat *seat;
@ -51,7 +52,6 @@ struct display {
EGLContext ctx; EGLContext ctx;
EGLConfig conf; EGLConfig conf;
} egl; } egl;
uint32_t mask;
struct window *window; struct window *window;
}; };
@ -545,31 +545,28 @@ static const struct wl_seat_listener seat_listener = {
}; };
static void static void
display_handle_global(struct wl_display *display, uint32_t id, registry_handle_global(void *data, struct wl_registry *registry,
const char *interface, uint32_t version, void *data) uint32_t name, const char *interface, uint32_t version)
{ {
struct display *d = data; struct display *d = data;
if (strcmp(interface, "wl_compositor") == 0) { if (strcmp(interface, "wl_compositor") == 0) {
d->compositor = d->compositor =
wl_display_bind(display, id, &wl_compositor_interface); wl_registry_bind(registry, name,
&wl_compositor_interface, 1);
} else if (strcmp(interface, "wl_shell") == 0) { } else if (strcmp(interface, "wl_shell") == 0) {
d->shell = wl_display_bind(display, id, &wl_shell_interface); d->shell = wl_registry_bind(registry, name,
&wl_shell_interface, 1);
} else if (strcmp(interface, "wl_seat") == 0) { } else if (strcmp(interface, "wl_seat") == 0) {
d->seat = wl_display_bind(d->display, id, &wl_seat_interface); d->seat = wl_registry_bind(registry, name,
&wl_seat_interface, 1);
wl_seat_add_listener(d->seat, &seat_listener, d); wl_seat_add_listener(d->seat, &seat_listener, d);
} }
} }
static int static const struct wl_registry_listener registry_listener = {
event_mask_update(uint32_t mask, void *data) registry_handle_global
{ };
struct display *d = data;
d->mask = mask;
return 0;
}
static void static void
signal_int(int signum) signal_int(int signum)
@ -615,11 +612,11 @@ main(int argc, char **argv)
display.display = wl_display_connect(NULL); display.display = wl_display_connect(NULL);
assert(display.display); assert(display.display);
wl_display_add_global_listener(display.display, display.registry = wl_display_get_registry(display.display);
display_handle_global, &display); wl_registry_add_listener(display.registry,
&registry_listener, &display);
wl_display_get_fd(display.display, event_mask_update, &display); wl_display_dispatch(display.display);
wl_display_iterate(display.display, WL_DISPLAY_READABLE);
init_egl(&display, window.opaque); init_egl(&display, window.opaque);
create_surface(&window); create_surface(&window);
@ -631,7 +628,7 @@ main(int argc, char **argv)
sigaction(SIGINT, &sigint, NULL); sigaction(SIGINT, &sigint, NULL);
while (running) while (running)
wl_display_iterate(display.display, display.mask); wl_display_dispatch(display.display);
fprintf(stderr, "simple-egl exiting\n"); fprintf(stderr, "simple-egl exiting\n");

@ -35,11 +35,11 @@
struct display { struct display {
struct wl_display *display; struct wl_display *display;
struct wl_registry *registry;
struct wl_compositor *compositor; struct wl_compositor *compositor;
struct wl_shell *shell; struct wl_shell *shell;
struct wl_shm *shm; struct wl_shm *shm;
uint32_t formats; uint32_t formats;
uint32_t mask;
}; };
struct window { struct window {
@ -242,31 +242,28 @@ struct wl_shm_listener shm_listenter = {
}; };
static void static void
display_handle_global(struct wl_display *display, uint32_t id, registry_handle_global(void *data, struct wl_registry *registry,
const char *interface, uint32_t version, void *data) uint32_t id, const char *interface, uint32_t version)
{ {
struct display *d = data; struct display *d = data;
if (strcmp(interface, "wl_compositor") == 0) { if (strcmp(interface, "wl_compositor") == 0) {
d->compositor = d->compositor =
wl_display_bind(display, id, &wl_compositor_interface); wl_registry_bind(registry,
id, &wl_compositor_interface, 1);
} else if (strcmp(interface, "wl_shell") == 0) { } else if (strcmp(interface, "wl_shell") == 0) {
d->shell = wl_display_bind(display, id, &wl_shell_interface); d->shell = wl_registry_bind(registry,
id, &wl_shell_interface, 1);
} else if (strcmp(interface, "wl_shm") == 0) { } else if (strcmp(interface, "wl_shm") == 0) {
d->shm = wl_display_bind(display, id, &wl_shm_interface); d->shm = wl_registry_bind(registry,
id, &wl_shm_interface, 1);
wl_shm_add_listener(d->shm, &shm_listenter, d); wl_shm_add_listener(d->shm, &shm_listenter, d);
} }
} }
static int static const struct wl_registry_listener registry_listener = {
event_mask_update(uint32_t mask, void *data) registry_handle_global
{ };
struct display *d = data;
d->mask = mask;
return 0;
}
static struct display * static struct display *
create_display(void) create_display(void)
@ -278,9 +275,15 @@ create_display(void)
assert(display->display); assert(display->display);
display->formats = 0; display->formats = 0;
wl_display_add_global_listener(display->display, display->registry = wl_display_get_registry(display->display);
display_handle_global, display); wl_registry_add_listener(display->registry,
wl_display_iterate(display->display, WL_DISPLAY_READABLE); &registry_listener, display);
wl_display_roundtrip(display->display);
if (display->shm == NULL) {
fprintf(stderr, "No wl_shm global\n");
exit(1);
}
wl_display_roundtrip(display->display); wl_display_roundtrip(display->display);
if (!(display->formats & (1 << WL_SHM_FORMAT_XRGB8888))) { if (!(display->formats & (1 << WL_SHM_FORMAT_XRGB8888))) {
@ -288,7 +291,7 @@ create_display(void)
exit(1); exit(1);
} }
wl_display_get_fd(display->display, event_mask_update, display); wl_display_get_fd(display->display);
return display; return display;
} }
@ -341,7 +344,7 @@ main(int argc, char **argv)
redraw(window, NULL, 0); redraw(window, NULL, 0);
while (running) while (running)
wl_display_iterate(display->display, display->mask); wl_display_dispatch(display->display);
fprintf(stderr, "simple-shm exiting\n"); fprintf(stderr, "simple-shm exiting\n");
destroy_window(window); destroy_window(window);

@ -36,6 +36,7 @@
struct touch { struct touch {
struct wl_display *display; struct wl_display *display;
struct wl_registry *registry;
struct wl_compositor *compositor; struct wl_compositor *compositor;
struct wl_shell *shell; struct wl_shell *shell;
struct wl_shm *shm; struct wl_shm *shm;
@ -47,7 +48,6 @@ struct touch {
struct wl_shell_surface *shell_surface; struct wl_shell_surface *shell_surface;
struct wl_buffer *buffer; struct wl_buffer *buffer;
int has_argb; int has_argb;
uint32_t mask;
int width, height; int width, height;
void *data; void *data;
}; };
@ -236,35 +236,33 @@ static const struct wl_shell_surface_listener shell_surface_listener = {
}; };
static void static void
handle_global(struct wl_display *display, uint32_t id, handle_global(void *data, struct wl_registry *registry,
const char *interface, uint32_t version, void *data) uint32_t name, const char *interface, uint32_t version)
{ {
struct touch *touch = data; struct touch *touch = data;
if (strcmp(interface, "wl_compositor") == 0) { if (strcmp(interface, "wl_compositor") == 0) {
touch->compositor = touch->compositor =
wl_display_bind(display, id, &wl_compositor_interface); wl_registry_bind(registry, name,
&wl_compositor_interface, 1);
} else if (strcmp(interface, "wl_shell") == 0) { } else if (strcmp(interface, "wl_shell") == 0) {
touch->shell = touch->shell =
wl_display_bind(display, id, &wl_shell_interface); wl_registry_bind(registry, name,
&wl_shell_interface, 1);
} else if (strcmp(interface, "wl_shm") == 0) { } else if (strcmp(interface, "wl_shm") == 0) {
touch->shm = wl_display_bind(display, id, &wl_shm_interface); touch->shm = wl_registry_bind(registry, name,
&wl_shm_interface, 1);
wl_shm_add_listener(touch->shm, &shm_listenter, touch); wl_shm_add_listener(touch->shm, &shm_listenter, touch);
} else if (strcmp(interface, "wl_seat") == 0) { } else if (strcmp(interface, "wl_seat") == 0) {
touch->seat = wl_display_bind(display, id, &wl_seat_interface); touch->seat = wl_registry_bind(registry, name,
&wl_seat_interface, 1);
wl_seat_add_listener(touch->seat, &seat_listener, touch); wl_seat_add_listener(touch->seat, &seat_listener, touch);
} }
} }
static int static const struct wl_registry_listener registry_listener = {
event_mask_update(uint32_t mask, void *data) handle_global
{ };
struct touch *touch = data;
touch->mask = mask;
return 0;
}
static struct touch * static struct touch *
touch_create(int width, int height) touch_create(int width, int height)
@ -276,8 +274,9 @@ touch_create(int width, int height)
assert(touch->display); assert(touch->display);
touch->has_argb = 0; touch->has_argb = 0;
wl_display_add_global_listener(touch->display, handle_global, touch); touch->registry = wl_display_get_registry(touch->display);
wl_display_iterate(touch->display, WL_DISPLAY_READABLE); wl_registry_add_listener(touch->registry, &registry_listener, touch);
wl_display_dispatch(touch->display);
wl_display_roundtrip(touch->display); wl_display_roundtrip(touch->display);
if (!touch->has_argb) { if (!touch->has_argb) {
@ -285,7 +284,7 @@ touch_create(int width, int height)
exit(1); exit(1);
} }
wl_display_get_fd(touch->display, event_mask_update, touch); wl_display_get_fd(touch->display);
touch->width = width; touch->width = width;
touch->height = height; touch->height = height;
@ -318,7 +317,7 @@ main(int argc, char **argv)
touch = touch_create(600, 500); touch = touch_create(600, 500);
while (true) while (true)
wl_display_iterate(touch->display, touch->mask); wl_display_dispatch(touch->display);
return 0; return 0;
} }

@ -438,14 +438,15 @@ launcher_section_done(void *data)
} }
static void static void
global_handler(struct wl_display *display, uint32_t id, global_handler(struct display *display, uint32_t name,
const char *interface, uint32_t version, void *data) const char *interface, uint32_t version, void *data)
{ {
struct tablet *tablet = data; struct tablet *tablet = data;
if (!strcmp(interface, "tablet_shell")) { if (!strcmp(interface, "tablet_shell")) {
tablet->tablet_shell = tablet->tablet_shell =
wl_display_bind(display, id, &tablet_shell_interface); display_bind(display, name,
&tablet_shell_interface, 1);
tablet_shell_add_listener(tablet->tablet_shell, tablet_shell_add_listener(tablet->tablet_shell,
&tablet_shell_listener, tablet); &tablet_shell_listener, tablet);
} }
@ -466,8 +467,8 @@ int main(int argc, char *argv[])
tablet.display = display; tablet.display = display;
wl_display_add_global_listener(display_get_display(tablet.display), display_set_user_data(tablet.display, &tablet);
global_handler, &tablet); display_set_global_handler(tablet.display, global_handler);
tablet.homescreen = homescreen_create(&tablet); tablet.homescreen = homescreen_create(&tablet);
tablet_shell_set_homescreen(tablet.tablet_shell, tablet_shell_set_homescreen(tablet.tablet_shell,

@ -88,6 +88,7 @@ struct seat_info {
struct weston_info { struct weston_info {
struct wl_display *display; struct wl_display *display;
struct wl_registry *registry;
struct wl_list infos; struct wl_list infos;
bool roundtrip_needed; bool roundtrip_needed;
@ -264,7 +265,8 @@ add_seat_info(struct weston_info *info, uint32_t id, uint32_t version)
init_global_info(info, &seat->global, id, "wl_seat", version); init_global_info(info, &seat->global, id, "wl_seat", version);
seat->global.print = print_seat_info; seat->global.print = print_seat_info;
seat->seat = wl_display_bind(info->display, id, &wl_seat_interface); seat->seat = wl_registry_bind(info->registry,
id, &wl_seat_interface, 1);
wl_seat_add_listener(seat->seat, &seat_listener, seat); wl_seat_add_listener(seat->seat, &seat_listener, seat);
info->roundtrip_needed = true; info->roundtrip_needed = true;
@ -293,7 +295,8 @@ add_shm_info(struct weston_info *info, uint32_t id, uint32_t version)
shm->global.print = print_shm_info; shm->global.print = print_shm_info;
wl_list_init(&shm->formats); wl_list_init(&shm->formats);
shm->shm = wl_display_bind(info->display, id, &wl_shm_interface); shm->shm = wl_registry_bind(info->registry,
id, &wl_shm_interface, 1);
wl_shm_add_listener(shm->shm, &shm_listener, shm); wl_shm_add_listener(shm->shm, &shm_listener, shm);
info->roundtrip_needed = true; info->roundtrip_needed = true;
@ -350,8 +353,8 @@ add_output_info(struct weston_info *info, uint32_t id, uint32_t version)
wl_list_init(&output->modes); wl_list_init(&output->modes);
output->output = wl_display_bind(info->display, id, output->output = wl_registry_bind(info->registry, id,
&wl_output_interface); &wl_output_interface, 1);
wl_output_add_listener(output->output, &output_listener, wl_output_add_listener(output->output, &output_listener,
output); output);
@ -369,8 +372,8 @@ add_global_info(struct weston_info *info, uint32_t id,
} }
static void static void
global_handler(struct wl_display *display, uint32_t id, global_handler(void *data, struct wl_registry *registry, uint32_t id,
const char *interface, uint32_t version, void *data) const char *interface, uint32_t version)
{ {
struct weston_info *info = data; struct weston_info *info = data;
@ -384,6 +387,10 @@ global_handler(struct wl_display *display, uint32_t id,
add_global_info(info, id, interface, version); add_global_info(info, id, interface, version);
} }
static const struct wl_registry_listener registry_listener = {
global_handler
};
static void static void
print_infos(struct wl_list *infos) print_infos(struct wl_list *infos)
{ {
@ -406,9 +413,8 @@ main(int argc, char **argv)
wl_list_init(&info.infos); wl_list_init(&info.infos);
wl_display_add_global_listener(info.display, info.registry = wl_display_get_registry(info.display);
global_handler, wl_registry_add_listener(info.registry, &registry_listener, &info);
&info);
do { do {
info.roundtrip_needed = false; info.roundtrip_needed = false;

@ -30,6 +30,7 @@
#include <string.h> #include <string.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h>
#include <math.h> #include <math.h>
#include <assert.h> #include <assert.h>
#include <time.h> #include <time.h>
@ -69,8 +70,16 @@
struct shm_pool; struct shm_pool;
struct global {
uint32_t name;
char *interface;
uint32_t version;
struct wl_list link;
};
struct display { struct display {
struct wl_display *display; struct wl_display *display;
struct wl_registry *registry;
struct wl_compositor *compositor; struct wl_compositor *compositor;
struct wl_shell *shell; struct wl_shell *shell;
struct wl_shm *shm; struct wl_shm *shm;
@ -85,7 +94,6 @@ struct display {
int display_fd; int display_fd;
uint32_t display_fd_events; uint32_t display_fd_events;
uint32_t mask;
struct task display_task; struct task display_task;
int epoll_fd; int epoll_fd;
@ -93,6 +101,7 @@ struct display {
int running; int running;
struct wl_list global_list;
struct wl_list window_list; struct wl_list window_list;
struct wl_list input_list; struct wl_list input_list;
struct wl_list output_list; struct wl_list output_list;
@ -107,6 +116,7 @@ struct display {
PFNEGLDESTROYIMAGEKHRPROC destroy_image; PFNEGLDESTROYIMAGEKHRPROC destroy_image;
display_output_handler_t output_configure_handler; display_output_handler_t output_configure_handler;
display_global_handler_t global_handler;
void *user_data; void *user_data;
@ -3495,7 +3505,7 @@ display_add_output(struct display *d, uint32_t id)
memset(output, 0, sizeof *output); memset(output, 0, sizeof *output);
output->display = d; output->display = d;
output->output = output->output =
wl_display_bind(d->display, id, &wl_output_interface); wl_registry_bind(d->registry, id, &wl_output_interface, 1);
wl_list_insert(d->output_list.prev, &output->link); wl_list_insert(d->output_list.prev, &output->link);
wl_output_add_listener(output->output, &output_listener, output); wl_output_add_listener(output->output, &output_listener, output);
@ -3512,6 +3522,22 @@ output_destroy(struct output *output)
free(output); free(output);
} }
void
display_set_global_handler(struct display *display,
display_global_handler_t handler)
{
struct global *global;
display->global_handler = handler;
if (!handler)
return;
wl_list_for_each(global, &display->global_list, link)
display->global_handler(display,
global->name, global->interface,
global->version, display->user_data);
}
void void
display_set_output_configure_handler(struct display *display, display_set_output_configure_handler(struct display *display,
display_output_handler_t handler) display_output_handler_t handler)
@ -3590,7 +3616,7 @@ display_add_input(struct display *d, uint32_t id)
memset(input, 0, sizeof *input); memset(input, 0, sizeof *input);
input->display = d; input->display = d;
input->seat = wl_display_bind(d->display, id, &wl_seat_interface); input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, 1);
input->pointer_focus = NULL; input->pointer_focus = NULL;
input->keyboard_focus = NULL; input->keyboard_focus = NULL;
wl_list_insert(d->input_list.prev, &input->link); wl_list_insert(d->input_list.prev, &input->link);
@ -3640,7 +3666,8 @@ static void
init_workspace_manager(struct display *d, uint32_t id) init_workspace_manager(struct display *d, uint32_t id)
{ {
d->workspace_manager = d->workspace_manager =
wl_display_bind(d->display, id, &workspace_manager_interface); wl_registry_bind(d->registry, id,
&workspace_manager_interface, 1);
if (d->workspace_manager != NULL) if (d->workspace_manager != NULL)
workspace_manager_add_listener(d->workspace_manager, workspace_manager_add_listener(d->workspace_manager,
&workspace_manager_listener, &workspace_manager_listener,
@ -3648,35 +3675,57 @@ init_workspace_manager(struct display *d, uint32_t id)
} }
static void static void
display_handle_global(struct wl_display *display, uint32_t id, registry_handle_global(void *data, struct wl_registry *registry, uint32_t id,
const char *interface, uint32_t version, void *data) const char *interface, uint32_t version)
{ {
struct display *d = data; struct display *d = data;
struct global *global;
global = malloc(sizeof *global);
global->name = id;
global->interface = strdup(interface);
global->version = version;
wl_list_insert(d->global_list.prev, &global->link);
if (strcmp(interface, "wl_compositor") == 0) { if (strcmp(interface, "wl_compositor") == 0) {
d->compositor = d->compositor = wl_registry_bind(registry, id,
wl_display_bind(display, id, &wl_compositor_interface); &wl_compositor_interface, 1);
} else if (strcmp(interface, "wl_output") == 0) { } else if (strcmp(interface, "wl_output") == 0) {
display_add_output(d, id); display_add_output(d, id);
} else if (strcmp(interface, "wl_seat") == 0) { } else if (strcmp(interface, "wl_seat") == 0) {
display_add_input(d, id); display_add_input(d, id);
} else if (strcmp(interface, "wl_shell") == 0) { } else if (strcmp(interface, "wl_shell") == 0) {
d->shell = wl_display_bind(display, id, &wl_shell_interface); d->shell = wl_registry_bind(registry,
id, &wl_shell_interface, 1);
} else if (strcmp(interface, "wl_shm") == 0) { } else if (strcmp(interface, "wl_shm") == 0) {
d->shm = wl_display_bind(display, id, &wl_shm_interface); d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
} else if (strcmp(interface, "wl_data_device_manager") == 0) { } else if (strcmp(interface, "wl_data_device_manager") == 0) {
d->data_device_manager = d->data_device_manager =
wl_display_bind(display, id, wl_registry_bind(registry, id,
&wl_data_device_manager_interface); &wl_data_device_manager_interface, 1);
} else if (strcmp(interface, "text_cursor_position") == 0) { } else if (strcmp(interface, "text_cursor_position") == 0) {
d->text_cursor_position = d->text_cursor_position =
wl_display_bind(display, id, wl_registry_bind(registry, id,
&text_cursor_position_interface); &text_cursor_position_interface, 1);
} else if (strcmp(interface, "workspace_manager") == 0) { } else if (strcmp(interface, "workspace_manager") == 0) {
init_workspace_manager(d, id); init_workspace_manager(d, id);
} }
if (d->global_handler)
d->global_handler(d, id, interface, version, d->user_data);
}
void *
display_bind(struct display *display, uint32_t name,
const struct wl_interface *interface, uint32_t version)
{
return wl_registry_bind(display->registry, name, interface, version);
} }
static const struct wl_registry_listener registry_listener = {
registry_handle_global
};
#ifdef HAVE_CAIRO_EGL #ifdef HAVE_CAIRO_EGL
static int static int
init_egl(struct display *d) init_egl(struct display *d)
@ -3767,21 +3816,13 @@ fini_egl(struct display *display)
} }
#endif #endif
static int
event_mask_update(uint32_t mask, void *data)
{
struct display *d = data;
d->mask = mask;
return 0;
}
static void static void
handle_display_data(struct task *task, uint32_t events) handle_display_data(struct task *task, uint32_t events)
{ {
struct display *display = struct display *display =
container_of(task, struct display, display_task); container_of(task, struct display, display_task);
struct epoll_event ep;
int ret;
display->display_fd_events = events; display->display_fd_events = events;
@ -3790,7 +3831,21 @@ handle_display_data(struct task *task, uint32_t events)
return; return;
} }
wl_display_iterate(display->display, display->mask); if (events & EPOLLIN)
wl_display_dispatch(display->display);
if (events & EPOLLOUT) {
ret = wl_display_flush(display->display);
if (ret == 0) {
ep.events = EPOLLIN | EPOLLERR | EPOLLHUP;
ep.data.ptr = &display->display_task;
epoll_ctl(display->epoll_fd, EPOLL_CTL_MOD,
display->display_fd, &ep);
} else if (ret == -1 && errno != EAGAIN) {
display_exit(display);
return;
}
}
} }
struct display * struct display *
@ -3811,7 +3866,7 @@ display_create(int argc, char *argv[])
} }
d->epoll_fd = os_epoll_create_cloexec(); d->epoll_fd = os_epoll_create_cloexec();
d->display_fd = wl_display_get_fd(d->display, event_mask_update, d); d->display_fd = wl_display_get_fd(d->display);
d->display_task.run = handle_display_data; d->display_task.run = handle_display_data;
display_watch_fd(d, d->display_fd, EPOLLIN | EPOLLERR | EPOLLHUP, display_watch_fd(d, d->display_fd, EPOLLIN | EPOLLERR | EPOLLHUP,
&d->display_task); &d->display_task);
@ -3819,6 +3874,7 @@ display_create(int argc, char *argv[])
wl_list_init(&d->deferred_list); wl_list_init(&d->deferred_list);
wl_list_init(&d->input_list); wl_list_init(&d->input_list);
wl_list_init(&d->output_list); wl_list_init(&d->output_list);
wl_list_init(&d->global_list);
d->xkb_context = xkb_context_new(0); d->xkb_context = xkb_context_new(0);
if (d->xkb_context == NULL) { if (d->xkb_context == NULL) {
@ -3829,12 +3885,9 @@ display_create(int argc, char *argv[])
d->workspace = 0; d->workspace = 0;
d->workspace_count = 1; d->workspace_count = 1;
/* Set up listener so we'll catch all events. */ d->registry = wl_display_get_registry(d->display);
wl_display_add_global_listener(d->display, wl_registry_add_listener(d->registry, &registry_listener, d);
display_handle_global, d); wl_display_dispatch(d->display);
/* Process connection events. */
wl_display_iterate(d->display, WL_DISPLAY_READABLE);
#ifdef HAVE_CAIRO_EGL #ifdef HAVE_CAIRO_EGL
if (init_egl(d) < 0) if (init_egl(d) < 0)
return NULL; return NULL;
@ -4052,12 +4105,10 @@ display_run(struct display *display)
{ {
struct task *task; struct task *task;
struct epoll_event ep[16]; struct epoll_event ep[16];
int i, count; int i, count, ret;
display->running = 1; display->running = 1;
while (1) { while (1) {
wl_display_flush(display->display);
while (!wl_list_empty(&display->deferred_list)) { while (!wl_list_empty(&display->deferred_list)) {
task = container_of(display->deferred_list.prev, task = container_of(display->deferred_list.prev,
struct task, link); struct task, link);
@ -4068,7 +4119,17 @@ display_run(struct display *display)
if (!display->running) if (!display->running)
break; break;
wl_display_flush(display->display); ret = wl_display_flush(display->display);
if (ret < 0 && errno == EAGAIN) {
ep[0].events =
EPOLLIN | EPOLLOUT | EPOLLERR | EPOLLHUP;
ep[0].data.ptr = &display->display_task;
epoll_ctl(display->epoll_fd, EPOLL_CTL_MOD,
display->display_fd, &ep[0]);
} else if (ret < 0) {
break;
}
count = epoll_wait(display->epoll_fd, count = epoll_wait(display->epoll_fd,
ep, ARRAY_LENGTH(ep), -1); ep, ARRAY_LENGTH(ep), -1);

@ -73,6 +73,18 @@ display_get_output(struct display *display);
uint32_t uint32_t
display_get_serial(struct display *display); display_get_serial(struct display *display);
typedef void (*display_global_handler_t)(struct display *display,
uint32_t name,
const char *interface,
uint32_t version, void *data);
void
display_set_global_handler(struct display *display,
display_global_handler_t handler);
void *
display_bind(struct display *display, uint32_t name,
const struct wl_interface *interface, uint32_t version);
typedef void (*display_output_handler_t)(struct output *output, void *data); typedef void (*display_output_handler_t)(struct output *output, void *data);
/* /*

@ -288,14 +288,14 @@ init_wscreensaver(struct wscreensaver *wscr, struct display *display)
} }
static void static void
global_handler(struct wl_display *display, uint32_t id, global_handler(struct display *display, uint32_t name,
const char *interface, uint32_t version, void *data) const char *interface, uint32_t version, void *data)
{ {
struct wscreensaver *screensaver = data; struct wscreensaver *screensaver = data;
if (!strcmp(interface, "screensaver")) { if (!strcmp(interface, "screensaver")) {
screensaver->interface = screensaver->interface =
wl_display_bind(display, id, &screensaver_interface); display_bind(display, name, &screensaver_interface, 1);
} }
} }
@ -321,8 +321,8 @@ int main(int argc, char *argv[])
if (!demo_mode) { if (!demo_mode) {
/* iterates already known globals immediately */ /* iterates already known globals immediately */
wl_display_add_global_listener(display_get_display(d), display_set_user_data(d, &screensaver);
global_handler, &screensaver); display_set_global_handler(d, global_handler);
if (!screensaver.interface) { if (!screensaver.interface) {
fprintf(stderr, fprintf(stderr,
"Server did not offer screensaver interface," "Server did not offer screensaver interface,"

@ -48,6 +48,7 @@ struct wayland_compositor {
struct { struct {
struct wl_display *wl_display; struct wl_display *wl_display;
struct wl_registry *registry;
struct wl_compositor *compositor; struct wl_compositor *compositor;
struct wl_shell *shell; struct wl_shell *shell;
struct wl_output *output; struct wl_output *output;
@ -730,8 +731,8 @@ display_add_seat(struct wayland_compositor *c, uint32_t id)
weston_seat_init(&input->base, &c->base); weston_seat_init(&input->base, &c->base);
input->compositor = c; input->compositor = c;
input->seat = wl_display_bind(c->parent.wl_display, id, input->seat = wl_registry_bind(c->parent.registry, id,
&wl_seat_interface); &wl_seat_interface, 1);
wl_list_insert(c->input_list.prev, &input->link); wl_list_insert(c->input_list.prev, &input->link);
wl_seat_add_listener(input->seat, &seat_listener, input); wl_seat_add_listener(input->seat, &seat_listener, input);
@ -739,37 +740,32 @@ display_add_seat(struct wayland_compositor *c, uint32_t id)
} }
static void static void
display_handle_global(struct wl_display *display, uint32_t id, registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
const char *interface, uint32_t version, void *data) const char *interface, uint32_t version)
{ {
struct wayland_compositor *c = data; struct wayland_compositor *c = data;
if (strcmp(interface, "wl_compositor") == 0) { if (strcmp(interface, "wl_compositor") == 0) {
c->parent.compositor = c->parent.compositor =
wl_display_bind(display, id, &wl_compositor_interface); wl_registry_bind(registry, name,
&wl_compositor_interface, 1);
} else if (strcmp(interface, "wl_output") == 0) { } else if (strcmp(interface, "wl_output") == 0) {
c->parent.output = c->parent.output =
wl_display_bind(display, id, &wl_output_interface); wl_registry_bind(registry, name,
&wl_output_interface, 1);
wl_output_add_listener(c->parent.output, &output_listener, c); wl_output_add_listener(c->parent.output, &output_listener, c);
} else if (strcmp(interface, "wl_shell") == 0) { } else if (strcmp(interface, "wl_shell") == 0) {
c->parent.shell = c->parent.shell =
wl_display_bind(display, id, &wl_shell_interface); wl_registry_bind(registry, name,
&wl_shell_interface, 1);
} else if (strcmp(interface, "wl_seat") == 0) { } else if (strcmp(interface, "wl_seat") == 0) {
display_add_seat(c, id); display_add_seat(c, name);
} }
} }
static int static const struct wl_registry_listener registry_listener = {
update_event_mask(uint32_t mask, void *data) registry_handle_global
{ };
struct wayland_compositor *c = data;
c->parent.event_mask = mask;
if (c->parent.wl_source)
wl_event_source_fd_update(c->parent.wl_source, mask);
return 0;
}
static int static int
wayland_compositor_handle_event(int fd, uint32_t mask, void *data) wayland_compositor_handle_event(int fd, uint32_t mask, void *data)
@ -777,9 +773,9 @@ wayland_compositor_handle_event(int fd, uint32_t mask, void *data)
struct wayland_compositor *c = data; struct wayland_compositor *c = data;
if (mask & WL_EVENT_READABLE) if (mask & WL_EVENT_READABLE)
wl_display_iterate(c->parent.wl_display, WL_DISPLAY_READABLE); wl_display_dispatch(c->parent.wl_display);
if (mask & WL_EVENT_WRITABLE) if (mask & WL_EVENT_WRITABLE)
wl_display_iterate(c->parent.wl_display, WL_DISPLAY_WRITABLE); wl_display_flush(c->parent.wl_display);
return 1; return 1;
} }
@ -826,10 +822,9 @@ wayland_compositor_create(struct wl_display *display,
} }
wl_list_init(&c->input_list); wl_list_init(&c->input_list);
wl_display_add_global_listener(c->parent.wl_display, c->parent.registry = wl_display_get_registry(c->parent.wl_display);
display_handle_global, c); wl_registry_add_listener(c->parent.registry, &registry_listener, c);
wl_display_dispatch(c->parent.wl_display);
wl_display_iterate(c->parent.wl_display, WL_DISPLAY_READABLE);
c->base.wl_display = display; c->base.wl_display = display;
if (wayland_compositor_init_egl(c) < 0) if (wayland_compositor_init_egl(c) < 0)
@ -856,9 +851,9 @@ wayland_compositor_create(struct wl_display *display,
loop = wl_display_get_event_loop(c->base.wl_display); loop = wl_display_get_event_loop(c->base.wl_display);
fd = wl_display_get_fd(c->parent.wl_display, update_event_mask, c); fd = wl_display_get_fd(c->parent.wl_display);
c->parent.wl_source = c->parent.wl_source =
wl_event_loop_add_fd(loop, fd, c->parent.event_mask, wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
wayland_compositor_handle_event, c); wayland_compositor_handle_event, c);
if (c->parent.wl_source == NULL) if (c->parent.wl_source == NULL)
goto err_display; goto err_display;

Loading…
Cancel
Save