struct xwl_output *xwl_output;
+ int ret;
+
+ xwl_output = xwl_output_create(xwl_screen);
+ xwl_output->output = wl_registry_bind(xwl_screen->registry, xwl_global->id,
+ &wl_output_interface, 1);
+ wl_output_add_listener(xwl_output->output, &output_listener, xwl_output);
- if (strcmp (interface, "wl_output") == 0) {
- xwl_output = xwl_output_create(xwl_screen);
- xwl_output->output = wl_registry_bind(registry, id,
- &wl_output_interface, 1);
- wl_output_add_listener(xwl_output->output,
- &output_listener, xwl_output);
+ while (!xwl_screen->xwl_output) {
+ ret = wl_display_roundtrip(xwl_screen->display);
+ if (ret == -1)
+ FatalError("failed to dispatch Wayland events: %s\n",
+ strerror(errno));
}
}
-static const struct wl_registry_listener global_listener = {
- global_handler,
-};
-
void
xwayland_screen_preinit_output(struct xwl_screen *xwl_screen, ScrnInfoPtr
scrninfo)
{
- int ret;
-
xf86CrtcConfigInit(scrninfo, &config_funcs);
xf86CrtcSetSizeRange(scrninfo, 320, 200, 8192, 8192);
- xwl_screen->output_registry = wl_display_get_registry(xwl_screen->display);
- wl_registry_add_listener(xwl_screen->output_registry, &global_listener,
- xwl_screen);
-
- while (!xwl_screen->xwl_output) {
- ret = wl_display_roundtrip(xwl_screen->display);
- if (ret == -1)
- FatalError("failed to dispatch Wayland events: %s\n",
strerror(errno));
- }
+ xwl_output_bind(xwl_screen);
xf86InitialConfiguration(scrninfo, TRUE);
}
diff --git a/hw/xfree86/xwayland/xwayland-private.h
b/hw/xfree86/xwayland/xwayland-private.h
index 23263d0..2716ebe 100644
--- a/hw/xfree86/xwayland/xwayland-private.h
+++ b/hw/xfree86/xwayland/xwayland-private.h
@@ -38,6 +38,14 @@ struct xwl_window {
struct xwl_output;
+struct xwl_global {
+ uint32_t id;
+ char *interface;
+ uint32_t version;
+
+ struct xorg_list link;
+};
+
struct xwl_screen {
struct xwl_driver *driver;
ScreenPtr screen;
@@ -46,10 +54,10 @@ struct xwl_screen {
int wayland_fd;
struct xwl_output *xwl_output;
struct wl_display *display;
+
+ struct xorg_list global_list;
struct wl_registry *registry;
- struct wl_registry *drm_registry;
- struct wl_registry *input_registry;
- struct wl_registry *output_registry;
+
struct wl_compositor *compositor;
struct wl_drm *drm;
struct wl_shm *shm;
@@ -100,6 +108,9 @@ struct xwl_seat {
CursorPtr x_cursor;
};
+struct xwl_global *
+xwl_global_get(struct xwl_screen *xwl_screen, const char *interface);
+
struct xwl_screen *xwl_screen_get(ScreenPtr screen);
void xwayland_screen_preinit_output(struct xwl_screen *xwl_screen,
ScrnInfoPtr scrninfo);
@@ -111,12 +122,10 @@ struct xwl_output *xwl_output_create(struct xwl_screen
*xwl_screen);
void xwl_input_teardown(pointer p);
pointer xwl_input_setup(pointer module, pointer opts, int *errmaj, int
*errmin);
-void xwl_input_init(struct xwl_screen *screen);
Bool xwl_drm_initialised(struct xwl_screen *screen);
+void xwl_seat_bind(struct xwl_screen *screen);
void xwl_seat_set_cursor(struct xwl_seat *xwl_seat);
-extern const struct xserver_listener xwl_server_listener;
-
#endif /* _XWAYLAND_PRIVATE_H_ */
diff --git a/hw/xfree86/xwayland/xwayland.c b/hw/xfree86/xwayland/xwayland.c
index 98e036e..3396e5f 100644
--- a/hw/xfree86/xwayland/xwayland.c
+++ b/hw/xfree86/xwayland/xwayland.c
@@ -68,12 +68,23 @@ xserver_listen_socket(void *data, struct xserver *xserver,
int fd)
ListenOnOpenFD(fd, TRUE);
}
-const struct xserver_listener xwl_server_listener = {
+static const struct xserver_listener xwl_server_listener = {
xserver_client,
xserver_listen_socket
};
static void
+xwl_xserver_bind(struct xwl_screen *xwl_screen)
+{
+ struct xwl_global *xwl_global = xwl_global_get(xwl_screen, "xserver");
+
+ xwl_screen->xorg_server = wl_registry_bind(xwl_screen->registry,
+ xwl_global->id, &xserver_interface, 1);
+ xserver_add_listener(xwl_screen->xorg_server, &xwl_server_listener,
+ xwl_screen);
+}
+
+static void
xwl_input_delayed_init(void *data, struct wl_callback *callback, uint32_t
time)
{
struct xwl_screen *xwl_screen = data;
@@ -81,26 +92,59 @@ xwl_input_delayed_init(void *data, struct wl_callback
*callback, uint32_t time)
ErrorF("xwl_input_delayed_init\n");
wl_callback_destroy(callback);
- xwl_input_init(xwl_screen);
+
+ xwl_seat_bind(xwl_screen);
+ xwl_xserver_bind(xwl_screen);
}
static const struct wl_callback_listener delayed_init_listner = {
xwl_input_delayed_init
};
+struct xwl_global *
+xwl_global_get(struct xwl_screen *xwl_screen, const char *interface)
+{
+ struct xwl_global *xwl_global = NULL;
+
+ xorg_list_for_each_entry(xwl_global,
+ &xwl_screen->global_list, link) {
+ if (strcmp(xwl_global->interface, interface) == 0)
+ return xwl_global;
+ }
+
+ ErrorF("failed to find global object %s\n", interface);
+ return NULL;
+}
+
static void
registry_global(void *data, struct wl_registry *registry, uint32_t id,
const char *interface, uint32_t version)
{
struct xwl_screen *xwl_screen = data;
+ struct xwl_global *xwl_global;
if (strcmp (interface, "wl_compositor") == 0) {
xwl_screen->compositor =
wl_registry_bind(registry, id, &wl_compositor_interface, 1);
+ return;
} else if (strcmp(interface, "wl_shm") == 0) {
xwl_screen->shm =
wl_registry_bind(registry, id, &wl_shm_interface, 1);
+ return;
}
+
+ /* cache list of globals, so we can bind the interfaces later in a desired
+ * order */
+ xwl_global = calloc(sizeof *xwl_global, 1);
+ if (xwl_global == NULL) {
+ ErrorF("registry_global ENOMEM\n");
+ return ;
+ }
+ xwl_global->id = id;
+ xwl_global->interface = strdup(interface);
+ xwl_global->version = version;
+
+ xorg_list_add(&xwl_global->link, &xwl_screen->global_list);
}
static const struct wl_registry_listener registry_listener = {
@@ -233,6 +277,7 @@ xwl_screen_pre_init(ScrnInfoPtr scrninfo, struct xwl_screen
*xwl_screen,
xorg_list_init(&xwl_screen->seat_list);
xorg_list_init(&xwl_screen->damage_window_list);
xorg_list_init(&xwl_screen->window_list);
+ xorg_list_init(&xwl_screen->global_list);
xwl_screen->scrninfo = scrninfo;
xwl_screen->driver = driver;
xwl_screen->flags = flags;
@@ -287,6 +332,7 @@ void xwl_screen_close(struct xwl_screen *xwl_screen)
{
struct xwl_seat *xwl_seat, *itmp;
struct xwl_window *xwl_window, *wtmp;
+ struct xwl_global *xwl_global, *gtmp;
if (xwl_screen->registry)
wl_registry_destroy(xwl_screen->registry);
@@ -303,10 +349,16 @@ void xwl_screen_close(struct xwl_screen *xwl_screen)
wl_surface_destroy(xwl_window->surface);
free(xwl_window);
}
+ xorg_list_for_each_entry_safe(xwl_global, gtmp,
+ &xwl_screen->global_list, link) {
+ free(xwl_global->interface);
+ free(xwl_global);
+ }
xorg_list_init(&xwl_screen->seat_list);
xorg_list_init(&xwl_screen->damage_window_list);
xorg_list_init(&xwl_screen->window_list);
+ xorg_list_init(&xwl_screen->global_list);
wl_display_roundtrip(xwl_screen->display);
}