gtk+ の broadway

OSC Tokyo 2012 Spring で WebBrowser 上で GNOME アプリを起動するデモを行いました。デモ時には epiphany で実施しましたが、最新の chromium-browser や firefox にも対応しているので、試してみてください。

デモ時に予想外に反響が良かったので、gtk+-3.3.18のソースコードを調べて見ました。調べたといっても、ちょっと調べただけで挫折したので、詳しく知りたければソースを読んでください。

WebBrowser 上で GNOME アプリを動かすには、gtk+-3.2 以上の configure 時に --enable-broadway オプションをつけてビルドする必要があります。これによって、 GDK_BACKENDS 変数に broadway が追加されます。configure.ac は以下のとおり。

AC_ARG_ENABLE(broadway-backend,
              [AS_HELP_STRING([--enable-broadway-backend],
                              [enable the broadway (HTML5) gdk backend])],
                              [backend_set=yes])
(省略)
if test "x$enable_broadway_backend" == xyes; then
  GDK_BACKENDS="$GDK_BACKENDS broadway"
  cairo_backends="$cairo_backends cairo"
  GDK_WINDOWING="$GDK_WINDOWING
#define GDK_WINDOWING_BROADWAY"
  GDK_EXTRA_LIBS="$GDK_EXTRA_LIBS -lz"
  AM_CONDITIONAL(USE_BROADWAY, true)
else
  AM_CONDITIONAL(USE_BROADWAY, false)
fi

前半がオプションの追加部分で、後半が GDK_BACKENDSにbroadwayを追加し、USE_BROADWAYをtrueにしている部分です。
これを受けて、gdk/Makefile.amで

if USE_BROADWAY
libgdk_3_la_LIBADD += broadway/libgdk-broadway.la
endif # USE_BROADWAY

のようにリンク時のライブラリが追加されます。

GDK_BACKEND の x11 と broadway を切り返るのは、gdk/gdkdisplaymanager.cのgdk_display_manager_get()関数です。

GdkDisplayManager*
gdk_display_manager_get (void)
{
  static GdkDisplayManager *manager = NULL;

  if (!manager)
    {
      const gchar *backend;

      backend = g_getenv ("GDK_BACKEND");
(省略)
#ifdef GDK_WINDOWING_X11
      if (backend == NULL || strcmp (backend, "x11") == 0)
        manager = g_object_new (gdk_x11_display_manager_get_type (), NULL);
      else
#endif
#ifdef GDK_WINDOWING_BROADWAY
      if (backend == NULL || strcmp (backend, "broadway") == 0)
        manager = g_object_new (gdk_broadway_display_manager_get_type (), NULL);
      else
#endif
      if (backend != NULL)
        g_error ("Unsupported GDK backend: %s", backend);
      else
        g_error ("No GDK backend found");
    }

  return manager;
}

最初に環境変数 GDM_BACKEND の値を読み込んで、broadwayなら gdk_broadway_display_manager_get_type() でGdkDisplayManagerを取得し、x11なら gdk_x11_display_manager_get_type() でGdkDisplayManagerを取得しています。
gdk_broadway_display_manager_get_type()は、gdk/broadway/gdkbroadwaydisplaymanager.h で宣言されていて、

#define GDK_TYPE_BROADWAY_DISPLAY_MANAGER    (gdk_broadway_display_manager_get_type ())
#define GDK_BROADWAY_DISPLAY_MANAGER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_BROADWAY_DISPLAY_MANAGER, GdkBroadwayDisplayManager))

#ifdef GDK_COMPILATION
typedef struct _GdkBroadwayDisplayManager GdkBroadwayDisplayManager;
#else
typedef GdkDisplayManager _GdkBroadwayDisplayManager;
#endif
typedef struct _GdkDisplayManagerClass GdkBroadwayDisplayManagerClass;

GType gdk_broadway_display_manager_get_type (void);

こんな感じで、宣言されています。しかし、実態を調べるためソースコードツリーで gdk_broadway_display_manager_get_type() を検索しても、実態が見つからないんですよね。ということで、なんかGTypeとして返して終了ってところでしょうか?

broadway 本体は、 gtk+-3.3.18/gdk/broadway 以下にあるので、気が向いたら眺めるつもりです。