wayland: Add Pantheon Shell protocol

Co-authored-by: Leonhard Kargl <leo.kargl@proton.me>
This commit is contained in:
Corentin Noël 2024-05-24 13:03:08 +02:00 committed by Leonhard
parent 7ac65758ed
commit c0f377b294
12 changed files with 677 additions and 1 deletions

View File

@ -51,6 +51,9 @@ all_doc_target = custom_target(
'--pkg', 'granite',
'--pkg', 'gnome-desktop-3.0',
'--pkg', 'gmodule-2.0',
'--pkg', 'wayland-server',
'--pkg', 'pantheon-desktop-shell',
'--vapidir=' + join_paths(meson.global_source_root(), 'protocol'),
'-o', '@OUTPUT@',
'@INPUT@'
],

View File

@ -182,6 +182,7 @@ if get_option('systemd')
endif
subdir('data')
subdir('protocol')
subdir('lib')
subdir('src')
subdir('daemon')

View File

@ -1,4 +1,5 @@
src/Dialogs.vala
src/PantheonShell.vala
src/ScreenshotManager.vala
src/WindowManager.vala
daemon/BackgroundMenu.vala

32
protocol/meson.build Normal file
View File

@ -0,0 +1,32 @@
dep_scanner = dependency('wayland-scanner', native: true)
prog_scanner = find_program(dep_scanner.get_variable(pkgconfig: 'wayland_scanner'))
protocol_file = files('pantheon-desktop-shell-v1.xml')
pantheon_desktop_shell_sources = []
pantheon_desktop_shell_sources += custom_target(
'pantheon-desktop-shell-server-protocol.h',
command: [ prog_scanner, 'server-header', '@INPUT@', '@OUTPUT@' ],
input: protocol_file,
output: 'pantheon-desktop-shell-server-protocol.h',
)
output_type = 'private-code'
if dep_scanner.version().version_compare('< 1.14.91')
output_type = 'code'
endif
pantheon_desktop_shell_sources += custom_target(
'pantheon-desktop-shell-protocol.c',
command: [ prog_scanner, output_type, '@INPUT@', '@OUTPUT@' ],
input: protocol_file,
output: 'pantheon-desktop-shell-protocol.c',
)
pantheon_desktop_shell_dep = declare_dependency(
dependencies: [
vala.find_library('pantheon-desktop-shell', dirs: meson.current_source_dir()),
dependency('wayland-server'),
],
include_directories: include_directories('.'),
sources: pantheon_desktop_shell_sources
)

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="pantheon_shell_v1">
<copyright><![CDATA[
SPDX-FileCopyrightText: 2023 Corentin Noël <tintou@noel.tf>
SPDX-License-Identifier: LGPL-2.1-or-later
]]></copyright>
<interface name="io_elementary_pantheon_shell_v1" version="1">
<description summary="create panel, widget and get more control">
This interface is used by the Pantheon Wayland shell to communicate with
the compositor.
</description>
<request name="get_panel">
<description summary="create a panel surface from a surface">
Create a panel surface from an existing surface.
</description>
<arg name="output" type="new_id" interface="io_elementary_pantheon_panel_v1"/>
<arg name="surface" type="object" interface="wl_surface"/>
</request>
<request name="get_widget">
<description summary="create a widget surface from a surface">
Create a desktop widget surface from an existing surface.
</description>
<arg name="output" type="new_id" interface="io_elementary_pantheon_widget_v1"/>
<arg name="surface" type="object" interface="wl_surface"/>
</request>
<request name="get_extended_behavior">
<description summary="create a desktop-specific surface from a surface">
Create a desktop-specific surface from an existing surface.
</description>
<arg name="output" type="new_id" interface="io_elementary_pantheon_extended_behavior_v1"/>
<arg name="surface" type="object" interface="wl_surface"/>
</request>
</interface>
<interface name="io_elementary_pantheon_panel_v1" version="1">
<request name="destroy" type="destructor"/>
<enum name="anchor">
<description summary="anchor">
The anchor is a placement hint to the compositor.
</description>
<entry name="top" value="0" summary="the top edge of the screen"/>
<entry name="bottom" value="1" summary="the bottom edge of the screen"/>
<entry name="left" value="2" summary="the left edge of the screen"/>
<entry name="right" value="3" summary="the right edge of the screen"/>
</enum>
<enum name="hide_mode">
<description summary="hide mode">
How the shell should handle the window.
</description>
<entry name="never" value="0" summary="make the surface exclusive"/>
<entry name="maximized_focus_window" value="1" summary="hide when the focused window is maximized"/>
<entry name="overlapping_focus_window" value="2" summary="hide when the focused window overlaps the surface"/>
<entry name="overlapping_window" value="3" summary="hide when any window overlaps the surface"/>
<entry name="always" value="4" summary="always hide and only show if requested by the user"/>
</enum>
<request name="set_anchor">
<description summary="set panel edge anchor">
Tell the shell which side of the screen the panel is
located. This is so that new windows do not overlap the panel
and maximized windows maximize properly.
</description>
<arg name="anchor" type="uint" enum="anchor" summary="anchor"/>
</request>
<request name="focus">
<description summary="request keyboard focus">
Request keyboard focus, taking it away from any other window.
Keyboard focus must always be manually be requested and is
- in contrast to normal windows - never automatically granted
by the compositor.
</description>
</request>
<request name="set_size">
<description summary="set size">
The given size is only used for exclusive zones and
collision tracking for auto hide. By default and if set
to -1 the size of the surface is used.
</description>
<arg name="width" type="int"/>
<arg name="height" type="int"/>
</request>
<request name="set_hide_mode">
<description summary="set panel hide mode">
Tell the shell when to hide the panel.
</description>
<arg name="hide_mode" type="uint" enum="hide_mode" summary="hide mode"/>
</request>
</interface>
<interface name="io_elementary_pantheon_widget_v1" version="1">
<request name="destroy" type="destructor"/>
</interface>
<interface name="io_elementary_pantheon_extended_behavior_v1" version="1">
<request name="destroy" type="destructor"/>
<request name="set_keep_above">
<description summary="set keep above">
Tell the shell to keep the surface above on all workspaces
</description>
</request>
</interface>
</protocol>

View File

@ -0,0 +1 @@
wayland-server

View File

@ -0,0 +1,79 @@
/*
* Copyright 2023 elementary, Inc. <https://elementary.io>
* Copyright 2023 Corentin Noël <tintou@noel.tf>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
namespace Pantheon.Desktop {
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "struct io_elementary_pantheon_shell_v1_interface")]
public struct ShellInterface {
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "io_elementary_pantheon_shell_v1_interface")]
public static Wl.Interface iface;
public Pantheon.Desktop.GetPanel get_panel;
public Pantheon.Desktop.GetWidget get_widget;
public Pantheon.Desktop.GetExtendedBehavior get_extended_behavior;
}
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "enum io_elementary_pantheon_panel_v1_anchor", cprefix="IO_ELEMENTARY_PANTHEON_PANEL_V1_ANCHOR_", has_type_id = false)]
public enum Anchor {
TOP,
BOTTOM,
LEFT,
RIGHT,
}
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "enum io_elementary_pantheon_panel_v1_hide_mode", cprefix="IO_ELEMENTARY_PANTHEON_PANEL_V1_HIDE_MODE_", has_type_id = false)]
public enum HideMode {
NEVER,
MAXIMIZED_FOCUS_WINDOW,
OVERLAPPING_FOCUS_WINDOW,
OVERLAPPING_WINDOW,
ALWAYS
}
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "struct io_elementary_pantheon_panel_v1_interface")]
public struct PanelInterface {
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "io_elementary_pantheon_panel_v1_interface")]
public static Wl.Interface iface;
public Destroy destroy;
public SetAnchor set_anchor;
public Focus focus;
public SetSize set_size;
public SetHideMode set_hide_mode;
}
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "struct io_elementary_pantheon_widget_v1_interface")]
public struct WidgetInterface {
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "io_elementary_pantheon_widget_v1_interface")]
public static Wl.Interface iface;
public Destroy destroy;
}
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "struct io_elementary_pantheon_extended_behavior_v1_interface")]
public struct ExtendedBehaviorInterface {
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "io_elementary_pantheon_extended_behavior_v1_interface")]
public static Wl.Interface iface;
public Destroy destroy;
public SetKeepAbove set_keep_above;
}
[CCode (has_target = false, has_typedef = false)]
public delegate void GetPanel (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface);
[CCode (has_target = false, has_typedef = false)]
public delegate void GetWidget (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface);
[CCode (has_target = false, has_typedef = false)]
public delegate void GetExtendedBehavior (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface);
[CCode (has_target = false, has_typedef = false)]
public delegate void SetAnchor (Wl.Client client, Wl.Resource resource, [CCode (type = "uint32_t")] Anchor anchor);
[CCode (has_target = false, has_typedef = false)]
public delegate void Focus (Wl.Client client, Wl.Resource resource);
[CCode (has_target = false, has_typedef = false)]
public delegate void SetSize (Wl.Client client, Wl.Resource resource, int width, int height);
[CCode (has_target = false, has_typedef = false)]
public delegate void SetHideMode (Wl.Client client, Wl.Resource resource, [CCode (type = "uint32_t")] HideMode hide_mode);
[CCode (has_target = false, has_typedef = false)]
public delegate void SetKeepAbove (Wl.Client client, Wl.Resource resource);
[CCode (has_target = false, has_typedef = false)]
public delegate void Destroy (Wl.Client client, Wl.Resource resource);
}

View File

@ -76,6 +76,9 @@ namespace Gala {
try {
ctx.start ();
if (ctx.get_compositor_type () == Meta.CompositorType.WAYLAND) {
Gala.init_pantheon_shell (ctx);
}
} catch (Error e) {
stderr.printf ("Failed to start: %s\n", e.message);
return Posix.EXIT_FAILURE;

314
src/PantheonShell.vala Normal file
View File

@ -0,0 +1,314 @@
/*
* Copyright 2023 elementary, Inc. <https://elementary.io>
* Copyright 2023 Corentin Noël <tintou@noel.tf>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
namespace Gala {
#if !HAS_MUTTER45
[Compact]
public class FakeMetaWaylandCompositor : GLib.Object {
// It is the third field and Vala adds a FakeMetaWaylandCompositorPrivate *priv
public Wl.Display wayland_display;
[CCode (cname = "meta_context_get_wayland_compositor")]
public extern static unowned Gala.FakeMetaWaylandCompositor from_context (Meta.Context context);
}
#endif
public static inline unowned Wl.Display? get_display_from_context (Meta.Context context) {
#if HAS_MUTTER45
unowned Meta.WaylandCompositor? compositor = context.get_wayland_compositor ();
if (compositor == null) {
return null;
}
return (Wl.Display) compositor.get_wayland_display ();
#else
unowned FakeMetaWaylandCompositor compositor = Gala.FakeMetaWaylandCompositor.from_context (context);
if (compositor == null) {
return null;
}
return compositor.wayland_display;
#endif
}
private static Pantheon.Desktop.ShellInterface wayland_pantheon_shell_interface;
private static Pantheon.Desktop.PanelInterface wayland_pantheon_panel_interface;
private static Pantheon.Desktop.WidgetInterface wayland_pantheon_widget_interface;
private static Pantheon.Desktop.ExtendedBehaviorInterface wayland_pantheon_extended_behavior_interface;
private static Wl.Global shell_global;
public void init_pantheon_shell (Meta.Context context) {
unowned Wl.Display? wl_disp = get_display_from_context (context);
if (wl_disp == null) {
debug ("Not running under Wayland, no Pantheon Shell protocol");
return;
}
wayland_pantheon_shell_interface = {
get_panel,
get_widget,
get_extended_behavior,
};
wayland_pantheon_panel_interface = {
destroy_panel_surface,
set_anchor,
focus,
set_size,
set_hide_mode,
};
wayland_pantheon_widget_interface = {
destroy_widget_surface,
};
wayland_pantheon_extended_behavior_interface = {
destroy_extended_behavior_surface,
set_keep_above,
};
PanelSurface.quark = GLib.Quark.from_string ("-gala-wayland-panel-surface-data");
shell_global = Wl.Global.create (wl_disp, ref Pantheon.Desktop.ShellInterface.iface, 1, (client, version, id) => {
unowned var resource = client.create_resource (ref Pantheon.Desktop.ShellInterface.iface, (int) version, id);
resource.set_implementation (&wayland_pantheon_shell_interface, null, (res) => {});
});
}
public class PanelSurface : GLib.Object {
public static GLib.Quark quark = 0;
public unowned GLib.Object? wayland_surface;
public PanelSurface (GLib.Object wayland_surface) {
this.wayland_surface = wayland_surface;
}
~PanelSurface () {
if (wayland_surface != null) {
wayland_surface.steal_qdata<unowned GLib.Object> (quark);
}
}
public void on_wayland_surface_disposed () {
wayland_surface = null;
}
}
public class WidgetSurface : GLib.Object {
public static GLib.Quark quark = 0;
public unowned GLib.Object? wayland_surface;
public WidgetSurface (GLib.Object wayland_surface) {
this.wayland_surface = wayland_surface;
}
~WidgetSurface () {
if (wayland_surface != null) {
wayland_surface.steal_qdata<unowned GLib.Object> (quark);
}
}
public void on_wayland_surface_disposed () {
wayland_surface = null;
}
}
public class ExtendedBehaviorSurface : GLib.Object {
public static GLib.Quark quark = 0;
public unowned GLib.Object? wayland_surface;
public ExtendedBehaviorSurface (GLib.Object wayland_surface) {
this.wayland_surface = wayland_surface;
}
~ExtendedBehaviorSurface () {
if (wayland_surface != null) {
wayland_surface.steal_qdata<unowned GLib.Object> (quark);
}
}
public void on_wayland_surface_disposed () {
wayland_surface = null;
}
}
static void unref_obj_on_destroy (Wl.Resource resource) {
resource.get_user_data<GLib.Object> ().unref ();
}
internal static void get_panel (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface_resource) {
unowned GLib.Object? wayland_surface = surface_resource.get_user_data<GLib.Object> ();
PanelSurface? panel_surface = wayland_surface.get_qdata (PanelSurface.quark);
if (panel_surface != null) {
surface_resource.post_error (
Wl.DisplayError.INVALID_OBJECT,
"io_elementary_pantheon_shell_v1_interface::get_panel already requested"
);
return;
}
panel_surface = new PanelSurface (wayland_surface);
unowned var panel_resource = client.create_resource (
ref Pantheon.Desktop.PanelInterface.iface,
resource.get_version (),
output
);
panel_resource.set_implementation (
&wayland_pantheon_panel_interface,
panel_surface.ref (),
unref_obj_on_destroy
);
wayland_surface.set_qdata_full (
PanelSurface.quark,
panel_surface,
(GLib.DestroyNotify) PanelSurface.on_wayland_surface_disposed
);
}
internal static void get_widget (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface_resource) {
unowned GLib.Object? wayland_surface = surface_resource.get_user_data<GLib.Object> ();
WidgetSurface? widget_surface = wayland_surface.get_qdata (WidgetSurface.quark);
if (widget_surface != null) {
surface_resource.post_error (
Wl.DisplayError.INVALID_OBJECT,
"io_elementary_pantheon_shell_v1_interface::get_widget already requested"
);
return;
}
widget_surface = new WidgetSurface (wayland_surface);
unowned var widget_resource = client.create_resource (
ref Pantheon.Desktop.WidgetInterface.iface,
resource.get_version (),
output
);
widget_resource.set_implementation (
&wayland_pantheon_widget_interface,
widget_surface.ref (),
unref_obj_on_destroy
);
wayland_surface.set_qdata_full (
WidgetSurface.quark,
widget_surface,
(GLib.DestroyNotify) WidgetSurface.on_wayland_surface_disposed
);
}
internal static void get_extended_behavior (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface_resource) {
unowned GLib.Object? wayland_surface = surface_resource.get_user_data<GLib.Object> ();
ExtendedBehaviorSurface? eb_surface = wayland_surface.get_qdata (ExtendedBehaviorSurface.quark);
if (eb_surface != null) {
surface_resource.post_error (
Wl.DisplayError.INVALID_OBJECT,
"io_elementary_pantheon_shell_v1_interface::get_extended_behavior already requested"
);
return;
}
eb_surface = new ExtendedBehaviorSurface (wayland_surface);
unowned var eb_resource = client.create_resource (
ref Pantheon.Desktop.ExtendedBehaviorInterface.iface,
resource.get_version (),
output
);
eb_resource.set_implementation (
&wayland_pantheon_extended_behavior_interface,
eb_surface.ref (),
unref_obj_on_destroy
);
wayland_surface.set_qdata_full (
ExtendedBehaviorSurface.quark,
eb_surface,
(GLib.DestroyNotify) ExtendedBehaviorSurface.on_wayland_surface_disposed
);
}
internal static void set_anchor (Wl.Client client, Wl.Resource resource, [CCode (type = "uint32_t")] Pantheon.Desktop.Anchor anchor) {
unowned PanelSurface? panel_surface = resource.get_user_data<PanelSurface> ();
if (panel_surface.wayland_surface == null) {
return;
}
Meta.Window? window;
panel_surface.wayland_surface.get ("window", out window, null);
if (window == null) {
return;
}
// TODO
}
internal static void focus (Wl.Client client, Wl.Resource resource) {
unowned PanelSurface? panel_surface = resource.get_user_data<PanelSurface> ();
if (panel_surface.wayland_surface == null) {
return;
}
Meta.Window? window;
panel_surface.wayland_surface.get ("window", out window, null);
if (window == null) {
return;
}
window.focus (window.get_display ().get_current_time ());
}
internal static void set_size (Wl.Client client, Wl.Resource resource, int width, int height) {
unowned PanelSurface? panel_surface = resource.get_user_data<PanelSurface> ();
if (panel_surface.wayland_surface == null) {
return;
}
Meta.Window? window;
panel_surface.wayland_surface.get ("window", out window, null);
if (window == null) {
return;
}
// TODO
}
internal static void set_hide_mode (Wl.Client client, Wl.Resource resource, [CCode (type = "uint32_t")] Pantheon.Desktop.HideMode hide_mode) {
unowned PanelSurface? panel_surface = resource.get_user_data<PanelSurface> ();
if (panel_surface.wayland_surface == null) {
return;
}
Meta.Window? window;
panel_surface.wayland_surface.get ("window", out window, null);
if (window == null) {
return;
}
// TODO
}
internal static void set_keep_above (Wl.Client client, Wl.Resource resource) {
unowned ExtendedBehaviorSurface? eb_surface = resource.get_user_data<ExtendedBehaviorSurface> ();
if (eb_surface.wayland_surface == null) {
return;
}
Meta.Window? window;
eb_surface.wayland_surface.get ("window", out window, null);
if (window == null) {
return;
}
window.make_above ();
}
internal static void destroy_panel_surface (Wl.Client client, Wl.Resource resource) {
resource.destroy ();
}
internal static void destroy_widget_surface (Wl.Client client, Wl.Resource resource) {
resource.destroy ();
}
internal static void destroy_extended_behavior_surface (Wl.Client client, Wl.Resource resource) {
resource.destroy ();
}
}

View File

@ -9,6 +9,7 @@ gala_bin_sources = files(
'Main.vala',
'MediaFeedback.vala',
'NotificationStack.vala',
'PantheonShell.vala',
'PluginManager.vala',
'ScreenSaverManager.vala',
'ScreenshotManager.vala',
@ -69,7 +70,7 @@ gala_bin_sources = files(
gala_bin = executable(
'gala',
gala_bin_sources,
dependencies: [gala_dep, gala_base_dep],
dependencies: [gala_dep, gala_base_dep, pantheon_desktop_shell_dep],
include_directories: config_inc_dir,
install_rpath: mutter_typelib_dir,
install: true,

1
vapi/wayland-server.deps Normal file
View File

@ -0,0 +1 @@
posix

125
vapi/wayland-server.vapi Normal file
View File

@ -0,0 +1,125 @@
/* wayland-server.vapi
*
* Copyright 2022 Corentin Noël <corentin.noel@collabora.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Authors:
* Corentin Noël <corentin.noel@collabora.com>
*/
[CCode (cprefix = "wl_", lower_case_cprefix = "wl_", cheader_filename = "wayland-server.h")]
namespace Wl {
[Compact]
[CCode (cname = "struct wl_display", free_function = "wl_display_destroy")]
public class Display {
[CCode (cname = "wl_display_create")]
public Display ();
public int add_socket (string name);
public unowned string add_socket_auto ();
public int add_socket_fd (int sock_fd);
public void terminate ();
public void run ();
public void flush_clients ();
public void destroy_clients ();
public uint32 get_serial ();
public uint32 next_serial ();
}
[Compact]
[CCode (cname = "struct wl_client", free_function = "wl_client_destroy")]
public class Client {
[CCode (cname = "wl_client_create")]
public Client (Wl.Display display, int fd);
public void flush ();
public void get_credentials (out Posix.pid_t pid, out Posix.uid_t uid, out Posix.gid_t gid);
public int get_fd ();
public unowned Wl.Display get_display ();
[CCode (cname = "wl_resource_create")]
public unowned Wl.Resource? create_resource (ref Wl.Interface interface, int version, uint32 id);
}
[Compact]
[CCode (cname = "struct wl_resource", free_function = "wl_resource_destroy")]
public class Resource {
public uint32 get_id ();
public unowned Wl.Client get_client ();
[CCode (simple_generics = true)]
public void set_user_data<T> (T? data);
[CCode (simple_generics = true)]
public unowned T? get_user_data<T> ();
public int get_version ();
public unowned string get_class ();
public void destroy ();
public void set_implementation (void* implementation, void* data, [CCode (delegate_target = false)] ResourceDestroyFunc destroy);
[PrintfFormat]
public void post_error(uint32 code, string format, ...);
}
[Compact]
[CCode (cname = "struct wl_interface")]
public class Interface {
public string name;
public int version;
[CCode (array_length = "method_count")]
public Wl.Message[] methods;
[CCode (array_length = "event_count")]
public Wl.Message[] events;
}
[Compact]
[CCode (cname = "struct wl_message")]
public class Message {
public string name;
public string signature;
[CCode (array_length = false)]
public Wl.Interface?[] types;
}
[Compact]
[CCode (cname = "struct wl_global", free_function = "wl_global_destroy")]
public class Global {
[CCode (cname = "wl_global_create")]
public static Wl.Global? create (Wl.Display display, ref Wl.Interface interface, int version, [CCode (delegate_target_pos = 3.9) ] Wl.GlobalBindFunc bind);
}
[CCode (cheader_filename = "wayland-server-protocol.h", cname = "enum wl_display_error", cprefix="WL_DISPLAY_ERROR_", has_type_id = false)]
public enum DisplayError {
INVALID_OBJECT,
INVALID_METHOD,
NO_MEMORY,
IMPLEMENTATION,
}
[CCode (cname = "wl_global_bind_func_t", instance_pos = 1.9)]
public delegate void GlobalBindFunc (Wl.Client client, uint32 version, uint32 id);
[CCode (cname = "wl_resource_destroy_func_t", has_target = false)]
public delegate void ResourceDestroyFunc (Wl.Resource resource);
[CCode (cname = "WAYLAND_VERSION_MAJOR")]
public const int VERSION_MAJOR;
[CCode (cname = "WAYLAND_VERSION_MINOR")]
public const int VERSION_MINOR;
[CCode (cname = "WAYLAND_VERSION_MICRO")]
public const int VERSION_MICRO;
[CCode (cname = "WAYLAND_VERSION")]
public const string VERSION;
}