On 11/22/2012 10:08 PM, Tiago Vignatti wrote:
Signed-off-by: Tiago Vignatti <[email protected]>
---

Hi Kristian, I guess that was the idea we discussed on IRC?

I kept the same order of the interfaces being bound, without thinking whether
their were the most efficient or something; we we'll have to overhaul the
WM and X server binding anyway when the next protocol comes in so I hope this
is okay for now.

[...]

diff --git a/hw/xfree86/xwayland/xwayland-output.c 
b/hw/xfree86/xwayland/xwayland-output.c
index 8f087f6..00b410b 100644
--- a/hw/xfree86/xwayland/xwayland-output.c
+++ b/hw/xfree86/xwayland/xwayland-output.c
@@ -267,43 +267,33 @@ static const struct wl_output_listener output_listener = {
  };

  static void
-global_handler(void *data, struct wl_registry *registry, uint32_t id,
-              const char *interface, uint32_t version)
+xwl_output_bind(struct xwl_screen *xwl_screen)
  {
-    struct xwl_screen *xwl_screen = data;
+    struct xwl_global *xwl_global = xwl_global_get(xwl_screen, "wl_output");

In the case of multiple outputs, the global handler would be called multiple times, but now xwl_global_get() will only return the first output. So with this change you only ever create one output.

From a quick glance at the code, however, it doesn't look like it handled multiple outputs properly before.

Cheers,
Ander

      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);
  }


_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to