aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Kempin <denniskempin@google.com>2016-12-08 13:42:04 -0800
committerDennis Kempin <denniskempin@google.com>2016-12-19 19:31:19 +0000
commit293a0fb21eafd159514a0ac98d687669f9bb55b1 (patch)
tree5547dca72dec04a2143d536f72269b793a8bef54
parentcf7e256453b7b59d456aff9a28823751ceee908d (diff)
downloadwayland-293a0fb21eafd159514a0ac98d687669f9bb55b1.tar.gz
external/wayland: Uprev to 6a18a87727c64719c68168568b9ab1e4d7c2d9c1
This is the version of wayland used by chrome, which includes a required update to the wl_touch protocol to v6. Bug: 33457871 Test: None Change-Id: I8fe14f1161766e5f5046181473e1d87c547eae74
-rw-r--r--Makefile.am16
-rw-r--r--configure.ac4
-rw-r--r--cursor/cursor-data.h2
-rw-r--r--cursor/wayland-cursor.c1
-rw-r--r--doc/publican/doxygen-to-publican.xsl2
-rw-r--r--doc/publican/sources/Book_Info.xml2
-rw-r--r--protocol/wayland.xml522
-rw-r--r--src/connection.c2
-rw-r--r--src/event-loop.c12
-rw-r--r--src/scanner.c38
-rw-r--r--src/wayland-client-core.h3
-rw-r--r--src/wayland-private.h10
-rw-r--r--src/wayland-server-core.h115
-rw-r--r--src/wayland-server.c281
-rw-r--r--src/wayland-server.h3
-rw-r--r--src/wayland-shm.c4
-rw-r--r--src/wayland-util.c54
-rw-r--r--src/wayland-util.h427
-rw-r--r--tests/array-test.c34
-rw-r--r--tests/compositor-introspection-test.c172
-rw-r--r--tests/connection-test.c1
-rw-r--r--tests/display-test.c2
-rw-r--r--tests/event-loop-test.c1
-rw-r--r--tests/exec-fd-leak-checker.c2
-rw-r--r--tests/list-test.c13
-rw-r--r--tests/map-test.c1
-rw-r--r--tests/message-test.c37
-rw-r--r--tests/os-wrappers-test.c1
-rw-r--r--tests/protocol-logger-test.c148
-rw-r--r--tests/queue-test.c1
-rw-r--r--tests/resources-test.c1
-rw-r--r--tests/test-compositor.c1
-rw-r--r--tests/test-compositor.h1
-rw-r--r--tests/test-runner.c3
34 files changed, 1541 insertions, 376 deletions
diff --git a/Makefile.am b/Makefile.am
index 49e25a6..d35231c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -144,7 +144,7 @@ libwayland_cursor_la_CFLAGS = \
-DICONDIR=\"$(ICONDIR)\"
-TESTS = \
+built_test_programs = \
array-test \
client-test \
display-test \
@@ -160,14 +160,18 @@ TESTS = \
signal-test \
resources-test \
message-test \
- headers-test
+ headers-test \
+ compositor-introspection-test \
+ protocol-logger-test
if ENABLE_CPP_TEST
-TESTS += cpp-compile-test
+built_test_programs += cpp-compile-test
endif
+TESTS = $(built_test_programs)
+
check_PROGRAMS = \
- $(TESTS) \
+ $(built_test_programs) \
exec-fd-leak-checker
noinst_PROGRAMS = \
@@ -217,6 +221,10 @@ resources_test_SOURCES = tests/resources-test.c
resources_test_LDADD = libtest-runner.la
message_test_SOURCES = tests/message-test.c
message_test_LDADD = libtest-runner.la
+compositor_introspection_test_SOURCES = tests/compositor-introspection-test.c
+compositor_introspection_test_LDADD = libtest-runner.la
+protocol_logger_test_SOURCES = tests/protocol-logger-test.c
+protocol_logger_test_LDADD = libtest-runner.la
headers_test_SOURCES = tests/headers-test.c \
tests/headers-protocol-test.c \
tests/headers-protocol-core-test.c
diff --git a/configure.ac b/configure.ac
index cf96529..6cda418 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,8 +1,8 @@
AC_PREREQ([2.64])
m4_define([wayland_major_version], [1])
-m4_define([wayland_minor_version], [11])
-m4_define([wayland_micro_version], [0])
+m4_define([wayland_minor_version], [12])
+m4_define([wayland_micro_version], [90])
m4_define([wayland_version],
[wayland_major_version.wayland_minor_version.wayland_micro_version])
diff --git a/cursor/cursor-data.h b/cursor/cursor-data.h
index 0d03cd5..dd7a80a 100644
--- a/cursor/cursor-data.h
+++ b/cursor/cursor-data.h
@@ -25,6 +25,8 @@
* Author: Keith Packard, SuSE, Inc.
*/
+#include <stdint.h>
+
static uint32_t cursor_data[] = {
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
diff --git a/cursor/wayland-cursor.c b/cursor/wayland-cursor.c
index 18abe87..d40c5c8 100644
--- a/cursor/wayland-cursor.c
+++ b/cursor/wayland-cursor.c
@@ -29,6 +29,7 @@
#include "wayland-client.h"
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
diff --git a/doc/publican/doxygen-to-publican.xsl b/doc/publican/doxygen-to-publican.xsl
index 7c3b507..e13dcd7 100644
--- a/doc/publican/doxygen-to-publican.xsl
+++ b/doc/publican/doxygen-to-publican.xsl
@@ -101,7 +101,7 @@
<!-- methods -->
<xsl:template match="memberdef" >
- <xsl:if test="@kind = 'function' and @static = 'no' or
+ <xsl:if test="@kind = 'function' and @static = 'no' and @prot = 'public' or
@kind !='function' and normalize-space(briefdescription) != ''">
<varlistentry id="{$which}-{@id}">
<term>
diff --git a/doc/publican/sources/Book_Info.xml b/doc/publican/sources/Book_Info.xml
index e9e5ff0..0b7bf07 100644
--- a/doc/publican/sources/Book_Info.xml
+++ b/doc/publican/sources/Book_Info.xml
@@ -5,7 +5,7 @@
]>
<bookinfo id="book-Wayland-Wayland">
<title>Wayland</title>
- <subtitle>The Wayland display server</subtitle>
+ <subtitle>The Wayland Protocol</subtitle>
<productname>Documentation</productname>
<productnumber>0.1</productnumber>
<edition>1</edition>
diff --git a/protocol/wayland.xml b/protocol/wayland.xml
index 700ef03..8311a18 100644
--- a/protocol/wayland.xml
+++ b/protocol/wayland.xml
@@ -48,7 +48,8 @@
The callback_data passed in the callback is the event serial.
</description>
- <arg name="callback" type="new_id" interface="wl_callback"/>
+ <arg name="callback" type="new_id" interface="wl_callback"
+ summary="callback object for the sync request"/>
</request>
<request name="get_registry">
@@ -57,7 +58,8 @@
to list and bind the global objects available from the
compositor.
</description>
- <arg name="registry" type="new_id" interface="wl_registry"/>
+ <arg name="registry" type="new_id" interface="wl_registry"
+ summary="global registry object"/>
</request>
<event name="error">
@@ -96,14 +98,14 @@
When the client receives this event, it will know that it can
safely reuse the object ID.
</description>
- <arg name="id" type="uint" summary="deleted object id"/>
+ <arg name="id" type="uint" summary="deleted object ID"/>
</event>
</interface>
<interface name="wl_registry" version="1">
<description summary="global registry object">
- The global registry object. The server has a number of global
- objects that are available to all clients. These objects
+ The singleton global registry object. The server has a number of
+ global objects that are available to all clients. These objects
typically represent an actual object in the server (for example,
an input device) or they are singleton objects that provide
extension functionality.
@@ -129,8 +131,8 @@
Binds a new, client-created object to the server using the
specified name as the identifier.
</description>
- <arg name="name" type="uint" summary="unique name for the object"/>
- <arg name="id" type="new_id"/>
+ <arg name="name" type="uint" summary="unique numeric name of the object"/>
+ <arg name="id" type="new_id" summary="bounded object"/>
</request>
<event name="global">
@@ -168,11 +170,12 @@
Clients can handle the 'done' event to get notified when
the related request is done.
</description>
+
<event name="done">
<description summary="done event">
- Notify the client when the related request is done.
+ Notify the client when the related request is done.
</description>
- <arg name="callback_data" type="uint" summary="request-specific data for the wl_callback"/>
+ <arg name="callback_data" type="uint" summary="request-specific data for the callback"/>
</event>
</interface>
@@ -187,14 +190,14 @@
<description summary="create new surface">
Ask the compositor to create a new surface.
</description>
- <arg name="id" type="new_id" interface="wl_surface"/>
+ <arg name="id" type="new_id" interface="wl_surface" summary="the new surface"/>
</request>
<request name="create_region">
<description summary="create new region">
Ask the compositor to create a new region.
</description>
- <arg name="id" type="new_id" interface="wl_region"/>
+ <arg name="id" type="new_id" interface="wl_region" summary="the new region"/>
</request>
</interface>
@@ -223,13 +226,12 @@
so it is valid to destroy the pool immediately after creating
a buffer from it.
</description>
-
- <arg name="id" type="new_id" interface="wl_buffer"/>
- <arg name="offset" type="int"/>
- <arg name="width" type="int"/>
- <arg name="height" type="int"/>
- <arg name="stride" type="int"/>
- <arg name="format" type="uint" enum="wl_shm.format"/>
+ <arg name="id" type="new_id" interface="wl_buffer" summary="buffer to create"/>
+ <arg name="offset" type="int" summary="buffer byte offset within the pool"/>
+ <arg name="width" type="int" summary="buffer width, in pixels"/>
+ <arg name="height" type="int" summary="buffer height, in pixels"/>
+ <arg name="stride" type="int" summary="number of bytes from the beginning of one row to the beginning of the next row"/>
+ <arg name="format" type="uint" enum="wl_shm.format" summary="buffer pixel format"/>
</request>
<request name="destroy" type="destructor">
@@ -249,14 +251,13 @@
created, but using the new size. This request can only be
used to make the pool bigger.
</description>
-
- <arg name="size" type="int"/>
+ <arg name="size" type="int" summary="new size of the pool, in bytes"/>
</request>
</interface>
<interface name="wl_shm" version="1">
<description summary="shared memory support">
- A global singleton object that provides support for shared
+ A singleton global object that provides support for shared
memory.
Clients can create wl_shm_pool objects using the create_pool
@@ -278,73 +279,74 @@
<enum name="format">
<description summary="pixel formats">
- This describes the memory layout of an individual pixel.
-
- All renderers should support argb8888 and xrgb8888 but any other
- formats are optional and may not be supported by the particular
- renderer in use.
- </description>
- <entry name="argb8888" value="0" summary="32-bit ARGB format"/>
- <entry name="xrgb8888" value="1" summary="32-bit RGB format"/>
- <!-- The drm format codes match the #defines in drm_fourcc.h.
- The formats actually supported by the compositor will be
- reported by the format event. -->
- <entry name="c8" value="0x20203843"/>
- <entry name="rgb332" value="0x38424752"/>
- <entry name="bgr233" value="0x38524742"/>
- <entry name="xrgb4444" value="0x32315258"/>
- <entry name="xbgr4444" value="0x32314258"/>
- <entry name="rgbx4444" value="0x32315852"/>
- <entry name="bgrx4444" value="0x32315842"/>
- <entry name="argb4444" value="0x32315241"/>
- <entry name="abgr4444" value="0x32314241"/>
- <entry name="rgba4444" value="0x32314152"/>
- <entry name="bgra4444" value="0x32314142"/>
- <entry name="xrgb1555" value="0x35315258"/>
- <entry name="xbgr1555" value="0x35314258"/>
- <entry name="rgbx5551" value="0x35315852"/>
- <entry name="bgrx5551" value="0x35315842"/>
- <entry name="argb1555" value="0x35315241"/>
- <entry name="abgr1555" value="0x35314241"/>
- <entry name="rgba5551" value="0x35314152"/>
- <entry name="bgra5551" value="0x35314142"/>
- <entry name="rgb565" value="0x36314752"/>
- <entry name="bgr565" value="0x36314742"/>
- <entry name="rgb888" value="0x34324752"/>
- <entry name="bgr888" value="0x34324742"/>
- <entry name="xbgr8888" value="0x34324258"/>
- <entry name="rgbx8888" value="0x34325852"/>
- <entry name="bgrx8888" value="0x34325842"/>
- <entry name="abgr8888" value="0x34324241"/>
- <entry name="rgba8888" value="0x34324152"/>
- <entry name="bgra8888" value="0x34324142"/>
- <entry name="xrgb2101010" value="0x30335258"/>
- <entry name="xbgr2101010" value="0x30334258"/>
- <entry name="rgbx1010102" value="0x30335852"/>
- <entry name="bgrx1010102" value="0x30335842"/>
- <entry name="argb2101010" value="0x30335241"/>
- <entry name="abgr2101010" value="0x30334241"/>
- <entry name="rgba1010102" value="0x30334152"/>
- <entry name="bgra1010102" value="0x30334142"/>
- <entry name="yuyv" value="0x56595559"/>
- <entry name="yvyu" value="0x55595659"/>
- <entry name="uyvy" value="0x59565955"/>
- <entry name="vyuy" value="0x59555956"/>
- <entry name="ayuv" value="0x56555941"/>
- <entry name="nv12" value="0x3231564e"/>
- <entry name="nv21" value="0x3132564e"/>
- <entry name="nv16" value="0x3631564e"/>
- <entry name="nv61" value="0x3136564e"/>
- <entry name="yuv410" value="0x39565559"/>
- <entry name="yvu410" value="0x39555659"/>
- <entry name="yuv411" value="0x31315559"/>
- <entry name="yvu411" value="0x31315659"/>
- <entry name="yuv420" value="0x32315559"/>
- <entry name="yvu420" value="0x32315659"/>
- <entry name="yuv422" value="0x36315559"/>
- <entry name="yvu422" value="0x36315659"/>
- <entry name="yuv444" value="0x34325559"/>
- <entry name="yvu444" value="0x34325659"/>
+ This describes the memory layout of an individual pixel.
+
+ All renderers should support argb8888 and xrgb8888 but any other
+ formats are optional and may not be supported by the particular
+ renderer in use.
+
+ The drm format codes match the macros defined in drm_fourcc.h.
+ The formats actually supported by the compositor will be
+ reported by the format event.
+ </description>
+ <entry name="argb8888" value="0" summary="32-bit ARGB format, [31:0] A:R:G:B 8:8:8:8 little endian"/>
+ <entry name="xrgb8888" value="1" summary="32-bit RGB format, [31:0] x:R:G:B 8:8:8:8 little endian"/>
+ <entry name="c8" value="0x20203843" summary="8-bit color index format, [7:0] C"/>
+ <entry name="rgb332" value="0x38424752" summary="8-bit RGB format, [7:0] R:G:B 3:3:2"/>
+ <entry name="bgr233" value="0x38524742" summary="8-bit BGR format, [7:0] B:G:R 2:3:3"/>
+ <entry name="xrgb4444" value="0x32315258" summary="16-bit xRGB format, [15:0] x:R:G:B 4:4:4:4 little endian"/>
+ <entry name="xbgr4444" value="0x32314258" summary="16-bit xBGR format, [15:0] x:B:G:R 4:4:4:4 little endian"/>
+ <entry name="rgbx4444" value="0x32315852" summary="16-bit RGBx format, [15:0] R:G:B:x 4:4:4:4 little endian"/>
+ <entry name="bgrx4444" value="0x32315842" summary="16-bit BGRx format, [15:0] B:G:R:x 4:4:4:4 little endian"/>
+ <entry name="argb4444" value="0x32315241" summary="16-bit ARGB format, [15:0] A:R:G:B 4:4:4:4 little endian"/>
+ <entry name="abgr4444" value="0x32314241" summary="16-bit ABGR format, [15:0] A:B:G:R 4:4:4:4 little endian"/>
+ <entry name="rgba4444" value="0x32314152" summary="16-bit RBGA format, [15:0] R:G:B:A 4:4:4:4 little endian"/>
+ <entry name="bgra4444" value="0x32314142" summary="16-bit BGRA format, [15:0] B:G:R:A 4:4:4:4 little endian"/>
+ <entry name="xrgb1555" value="0x35315258" summary="16-bit xRGB format, [15:0] x:R:G:B 1:5:5:5 little endian"/>
+ <entry name="xbgr1555" value="0x35314258" summary="16-bit xBGR 1555 format, [15:0] x:B:G:R 1:5:5:5 little endian"/>
+ <entry name="rgbx5551" value="0x35315852" summary="16-bit RGBx 5551 format, [15:0] R:G:B:x 5:5:5:1 little endian"/>
+ <entry name="bgrx5551" value="0x35315842" summary="16-bit BGRx 5551 format, [15:0] B:G:R:x 5:5:5:1 little endian"/>
+ <entry name="argb1555" value="0x35315241" summary="16-bit ARGB 1555 format, [15:0] A:R:G:B 1:5:5:5 little endian"/>
+ <entry name="abgr1555" value="0x35314241" summary="16-bit ABGR 1555 format, [15:0] A:B:G:R 1:5:5:5 little endian"/>
+ <entry name="rgba5551" value="0x35314152" summary="16-bit RGBA 5551 format, [15:0] R:G:B:A 5:5:5:1 little endian"/>
+ <entry name="bgra5551" value="0x35314142" summary="16-bit BGRA 5551 format, [15:0] B:G:R:A 5:5:5:1 little endian"/>
+ <entry name="rgb565" value="0x36314752" summary="16-bit RGB 565 format, [15:0] R:G:B 5:6:5 little endian"/>
+ <entry name="bgr565" value="0x36314742" summary="16-bit BGR 565 format, [15:0] B:G:R 5:6:5 little endian"/>
+ <entry name="rgb888" value="0x34324752" summary="24-bit RGB format, [23:0] R:G:B little endian"/>
+ <entry name="bgr888" value="0x34324742" summary="24-bit BGR format, [23:0] B:G:R little endian"/>
+ <entry name="xbgr8888" value="0x34324258" summary="32-bit xBGR format, [31:0] x:B:G:R 8:8:8:8 little endian"/>
+ <entry name="rgbx8888" value="0x34325852" summary="32-bit RGBx format, [31:0] R:G:B:x 8:8:8:8 little endian"/>
+ <entry name="bgrx8888" value="0x34325842" summary="32-bit BGRx format, [31:0] B:G:R:x 8:8:8:8 little endian"/>
+ <entry name="abgr8888" value="0x34324241" summary="32-bit ABGR format, [31:0] A:B:G:R 8:8:8:8 little endian"/>
+ <entry name="rgba8888" value="0x34324152" summary="32-bit RGBA format, [31:0] R:G:B:A 8:8:8:8 little endian"/>
+ <entry name="bgra8888" value="0x34324142" summary="32-bit BGRA format, [31:0] B:G:R:A 8:8:8:8 little endian"/>
+ <entry name="xrgb2101010" value="0x30335258" summary="32-bit xRGB format, [31:0] x:R:G:B 2:10:10:10 little endian"/>
+ <entry name="xbgr2101010" value="0x30334258" summary="32-bit xBGR format, [31:0] x:B:G:R 2:10:10:10 little endian"/>
+ <entry name="rgbx1010102" value="0x30335852" summary="32-bit RGBx format, [31:0] R:G:B:x 10:10:10:2 little endian"/>
+ <entry name="bgrx1010102" value="0x30335842" summary="32-bit BGRx format, [31:0] B:G:R:x 10:10:10:2 little endian"/>
+ <entry name="argb2101010" value="0x30335241" summary="32-bit ARGB format, [31:0] A:R:G:B 2:10:10:10 little endian"/>
+ <entry name="abgr2101010" value="0x30334241" summary="32-bit ABGR format, [31:0] A:B:G:R 2:10:10:10 little endian"/>
+ <entry name="rgba1010102" value="0x30334152" summary="32-bit RGBA format, [31:0] R:G:B:A 10:10:10:2 little endian"/>
+ <entry name="bgra1010102" value="0x30334142" summary="32-bit BGRA format, [31:0] B:G:R:A 10:10:10:2 little endian"/>
+ <entry name="yuyv" value="0x56595559" summary="packed YCbCr format, [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian"/>
+ <entry name="yvyu" value="0x55595659" summary="packed YCbCr format, [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian"/>
+ <entry name="uyvy" value="0x59565955" summary="packed YCbCr format, [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian"/>
+ <entry name="vyuy" value="0x59555956" summary="packed YCbCr format, [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian"/>
+ <entry name="ayuv" value="0x56555941" summary="packed AYCbCr format, [31:0] A:Y:Cb:Cr 8:8:8:8 little endian"/>
+ <entry name="nv12" value="0x3231564e" summary="2 plane YCbCr Cr:Cb format, 2x2 subsampled Cr:Cb plane"/>
+ <entry name="nv21" value="0x3132564e" summary="2 plane YCbCr Cb:Cr format, 2x2 subsampled Cb:Cr plane"/>
+ <entry name="nv16" value="0x3631564e" summary="2 plane YCbCr Cr:Cb format, 2x1 subsampled Cr:Cb plane"/>
+ <entry name="nv61" value="0x3136564e" summary="2 plane YCbCr Cb:Cr format, 2x1 subsampled Cb:Cr plane"/>
+ <entry name="yuv410" value="0x39565559" summary="3 plane YCbCr format, 4x4 subsampled Cb (1) and Cr (2) planes"/>
+ <entry name="yvu410" value="0x39555659" summary="3 plane YCbCr format, 4x4 subsampled Cr (1) and Cb (2) planes"/>
+ <entry name="yuv411" value="0x31315559" summary="3 plane YCbCr format, 4x1 subsampled Cb (1) and Cr (2) planes"/>
+ <entry name="yvu411" value="0x31315659" summary="3 plane YCbCr format, 4x1 subsampled Cr (1) and Cb (2) planes"/>
+ <entry name="yuv420" value="0x32315559" summary="3 plane YCbCr format, 2x2 subsampled Cb (1) and Cr (2) planes"/>
+ <entry name="yvu420" value="0x32315659" summary="3 plane YCbCr format, 2x2 subsampled Cr (1) and Cb (2) planes"/>
+ <entry name="yuv422" value="0x36315559" summary="3 plane YCbCr format, 2x1 subsampled Cb (1) and Cr (2) planes"/>
+ <entry name="yvu422" value="0x36315659" summary="3 plane YCbCr format, 2x1 subsampled Cr (1) and Cb (2) planes"/>
+ <entry name="yuv444" value="0x34325559" summary="3 plane YCbCr format, non-subsampled Cb (1) and Cr (2) planes"/>
+ <entry name="yvu444" value="0x34325659" summary="3 plane YCbCr format, non-subsampled Cr (1) and Cb (2) planes"/>
</enum>
<request name="create_pool">
@@ -355,10 +357,9 @@
objects. The server will mmap size bytes of the passed file
descriptor, to use as backing memory for the pool.
</description>
-
- <arg name="id" type="new_id" interface="wl_shm_pool"/>
- <arg name="fd" type="fd"/>
- <arg name="size" type="int"/>
+ <arg name="id" type="new_id" interface="wl_shm_pool" summary="pool to create"/>
+ <arg name="fd" type="fd" summary="file descriptor for the pool"/>
+ <arg name="size" type="int" summary="pool size, in bytes"/>
</request>
<event name="format">
@@ -445,9 +446,8 @@
wl_data_source.cancelled. Clients may still use this event in
conjunction with wl_data_source.action for feedback.
</description>
-
- <arg name="serial" type="uint"/>
- <arg name="mime_type" type="string" allow-null="true"/>
+ <arg name="serial" type="uint" summary="serial number of the accept request"/>
+ <arg name="mime_type" type="string" allow-null="true" summary="mime type accepted by the client"/>
</request>
<request name="receive">
@@ -468,8 +468,8 @@
clients may preemptively fetch data or examine it more closely to
determine acceptance.
</description>
- <arg name="mime_type" type="string"/>
- <arg name="fd" type="fd"/>
+ <arg name="mime_type" type="string" summary="mime type desired by receiver"/>
+ <arg name="fd" type="fd" summary="file descriptor for data transfer"/>
</request>
<request name="destroy" type="destructor">
@@ -483,7 +483,6 @@
Sent immediately after creating the wl_data_offer object. One
event per offered mime type.
</description>
-
<arg name="mime_type" type="string" summary="offered mime type"/>
</event>
@@ -539,8 +538,8 @@
This request can only be made on drag-and-drop offers, a protocol error
will be raised otherwise.
</description>
- <arg name="dnd_actions" type="uint"/>
- <arg name="preferred_action" type="uint"/>
+ <arg name="dnd_actions" type="uint" summary="actions supported by the destination client"/>
+ <arg name="preferred_action" type="uint" summary="action preferred by the destination client"/>
</request>
<event name="source_actions" since="3">
@@ -615,7 +614,7 @@
advertised to targets. Can be called several times to offer
multiple types.
</description>
- <arg name="mime_type" type="string"/>
+ <arg name="mime_type" type="string" summary="mime type offered by the data source"/>
</request>
<request name="destroy" type="destructor">
@@ -631,7 +630,6 @@
Used for feedback during drag-and-drop.
</description>
-
<arg name="mime_type" type="string" allow-null="true" summary="mime type accepted by the target"/>
</event>
@@ -641,7 +639,6 @@
specified mime type over the passed file descriptor, then
close it.
</description>
-
<arg name="mime_type" type="string" summary="mime type for the data"/>
<arg name="fd" type="fd" summary="file descriptor for the data"/>
</event>
@@ -689,7 +686,7 @@
wl_data_device.start_drag. Attempting to use the source other than
for drag-and-drop will raise a protocol error.
</description>
- <arg name="dnd_actions" type="uint"/>
+ <arg name="dnd_actions" type="uint" summary="actions supported by the data source"/>
</request>
<event name="dnd_drop_performed" since="3">
@@ -792,10 +789,10 @@
as an icon ends, the current and pending input regions become
undefined, and the wl_surface is unmapped.
</description>
- <arg name="source" type="object" interface="wl_data_source" allow-null="true"/>
- <arg name="origin" type="object" interface="wl_surface"/>
- <arg name="icon" type="object" interface="wl_surface" allow-null="true"/>
- <arg name="serial" type="uint" summary="serial of the implicit grab on the origin"/>
+ <arg name="source" type="object" interface="wl_data_source" allow-null="true" summary="data source for the eventual transfer"/>
+ <arg name="origin" type="object" interface="wl_surface" summary="surface where the drag originates"/>
+ <arg name="icon" type="object" interface="wl_surface" allow-null="true" summary="drag-and-drop icon surface"/>
+ <arg name="serial" type="uint" summary="serial number of the implicit grab on the origin"/>
</request>
<request name="set_selection">
@@ -805,8 +802,8 @@
To unset the selection, set the source to NULL.
</description>
- <arg name="source" type="object" interface="wl_data_source" allow-null="true"/>
- <arg name="serial" type="uint" summary="serial of the event that triggered this request"/>
+ <arg name="source" type="object" interface="wl_data_source" allow-null="true" summary="data source for the selection"/>
+ <arg name="serial" type="uint" summary="serial number of the event that triggered this request"/>
</request>
<event name="data_offer">
@@ -819,7 +816,6 @@
object will send out data_offer.offer events to describe the
mime types it offers.
</description>
-
<arg name="id" type="new_id" interface="wl_data_offer" summary="the new data_offer object"/>
</event>
@@ -830,7 +826,6 @@
enter time is provided by the x and y arguments, in surface-local
coordinates.
</description>
-
<arg name="serial" type="uint" summary="serial number of the enter event"/>
<arg name="surface" type="object" interface="wl_surface" summary="client surface entered"/>
<arg name="x" type="fixed" summary="surface-local x coordinate"/>
@@ -922,15 +917,15 @@
<description summary="create a new data source">
Create a new data source.
</description>
- <arg name="id" type="new_id" interface="wl_data_source"/>
+ <arg name="id" type="new_id" interface="wl_data_source" summary="data source to create"/>
</request>
<request name="get_data_device">
<description summary="create a new data device">
Create a new data device for a given seat.
</description>
- <arg name="id" type="new_id" interface="wl_data_device"/>
- <arg name="seat" type="object" interface="wl_seat"/>
+ <arg name="id" type="new_id" interface="wl_data_device" summary="data device to create"/>
+ <arg name="seat" type="object" interface="wl_seat" summary="seat associated with the data device"/>
</request>
<!-- Version 3 additions -->
@@ -961,10 +956,10 @@
or drags initiated with other buttons than BTN_LEFT to specific
actions (e.g. "ask").
</description>
- <entry name="none" value="0"/>
- <entry name="copy" value="1"/>
- <entry name="move" value="2"/>
- <entry name="ask" value="4"/>
+ <entry name="none" value="0" summary="no action"/>
+ <entry name="copy" value="1" summary="copy action"/>
+ <entry name="move" value="2" summary="move action"/>
+ <entry name="ask" value="4" summary="ask action"/>
</enum>
</interface>
@@ -989,8 +984,8 @@
Only one shell surface can be associated with a given surface.
</description>
- <arg name="id" type="new_id" interface="wl_shell_surface"/>
- <arg name="surface" type="object" interface="wl_surface"/>
+ <arg name="id" type="new_id" interface="wl_shell_surface" summary="shell surface to create"/>
+ <arg name="surface" type="object" interface="wl_surface" summary="surface to be given the shell surface role"/>
</request>
</interface>
@@ -1014,7 +1009,7 @@
A client must respond to a ping event with a pong request or
the client may be deemed unresponsive.
</description>
- <arg name="serial" type="uint" summary="serial of the ping event"/>
+ <arg name="serial" type="uint" summary="serial number of the ping event"/>
</request>
<request name="move">
@@ -1025,8 +1020,8 @@
The server may ignore move requests depending on the state of
the surface (e.g. fullscreen or maximized).
</description>
- <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
- <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
+ <arg name="seat" type="object" interface="wl_seat" summary="seat whose pointer is used"/>
+ <arg name="serial" type="uint" summary="serial number of the implicit grab on the pointer"/>
</request>
<enum name="resize" bitfield="true">
@@ -1036,15 +1031,15 @@
use this information to adapt its behavior, e.g. choose
an appropriate cursor image.
</description>
- <entry name="none" value="0"/>
- <entry name="top" value="1"/>
- <entry name="bottom" value="2"/>
- <entry name="left" value="4"/>
- <entry name="top_left" value="5"/>
- <entry name="bottom_left" value="6"/>
- <entry name="right" value="8"/>
- <entry name="top_right" value="9"/>
- <entry name="bottom_right" value="10"/>
+ <entry name="none" value="0" summary="no edge"/>
+ <entry name="top" value="1" summary="top edge"/>
+ <entry name="bottom" value="2" summary="bottom edge"/>
+ <entry name="left" value="4" summary="left edge"/>
+ <entry name="top_left" value="5" summary="top and left edges"/>
+ <entry name="bottom_left" value="6" summary="bottom and left edges"/>
+ <entry name="right" value="8" summary="right edge"/>
+ <entry name="top_right" value="9" summary="top and right edges"/>
+ <entry name="bottom_right" value="10" summary="bottom and right edges"/>
</enum>
<request name="resize">
@@ -1055,8 +1050,8 @@
The server may ignore resize requests depending on the state of
the surface (e.g. fullscreen or maximized).
</description>
- <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
- <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
+ <arg name="seat" type="object" interface="wl_seat" summary="seat whose pointer is used"/>
+ <arg name="serial" type="uint" summary="serial number of the implicit grab on the pointer"/>
<arg name="edges" type="uint" enum="resize" summary="which edge or corner is being dragged"/>
</request>
@@ -1086,11 +1081,10 @@
The flags argument controls details of the transient behaviour.
</description>
-
- <arg name="parent" type="object" interface="wl_surface"/>
- <arg name="x" type="int"/>
- <arg name="y" type="int"/>
- <arg name="flags" type="uint" enum="transient"/>
+ <arg name="parent" type="object" interface="wl_surface" summary="parent surface"/>
+ <arg name="x" type="int" summary="surface-local x coordinate"/>
+ <arg name="y" type="int" summary="surface-local y coordinate"/>
+ <arg name="flags" type="uint" enum="transient" summary="transient surface behavior"/>
</request>
<enum name="fullscreen_method">
@@ -1141,9 +1135,10 @@
with the dimensions for the output on which the surface will
be made fullscreen.
</description>
- <arg name="method" type="uint" enum="fullscreen_method"/>
- <arg name="framerate" type="uint"/>
- <arg name="output" type="object" interface="wl_output" allow-null="true"/>
+ <arg name="method" type="uint" enum="fullscreen_method" summary="method for resolving size conflict"/>
+ <arg name="framerate" type="uint" summary="framerate in mHz"/>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"
+ summary="output on which the surface is to be fullscreen"/>
</request>
<request name="set_popup">
@@ -1168,13 +1163,12 @@
corner of the surface relative to the upper left corner of the
parent surface, in surface-local coordinates.
</description>
-
- <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
- <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
- <arg name="parent" type="object" interface="wl_surface"/>
- <arg name="x" type="int"/>
- <arg name="y" type="int"/>
- <arg name="flags" type="uint" enum="transient"/>
+ <arg name="seat" type="object" interface="wl_seat" summary="seat whose pointer is used"/>
+ <arg name="serial" type="uint" summary="serial number of the implicit grab on the pointer"/>
+ <arg name="parent" type="object" interface="wl_surface" summary="parent surface"/>
+ <arg name="x" type="int" summary="surface-local x coordinate"/>
+ <arg name="y" type="int" summary="surface-local y coordinate"/>
+ <arg name="flags" type="uint" enum="transient" summary="transient surface behavior"/>
</request>
<request name="set_maximized">
@@ -1198,7 +1192,8 @@
The details depend on the compositor implementation.
</description>
- <arg name="output" type="object" interface="wl_output" allow-null="true"/>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"
+ summary="output on which the surface is to be maximized"/>
</request>
<request name="set_title">
@@ -1211,7 +1206,7 @@
The string must be encoded in UTF-8.
</description>
- <arg name="title" type="string"/>
+ <arg name="title" type="string" summary="surface title"/>
</request>
<request name="set_class">
@@ -1223,7 +1218,7 @@
file name (or the full path if it is a non-standard location) of
the application's .desktop file as the class.
</description>
- <arg name="class_" type="string"/>
+ <arg name="class_" type="string" summary="surface class"/>
</request>
<event name="ping">
@@ -1254,7 +1249,6 @@
The width and height arguments specify the size of the window
in surface-local coordinates.
</description>
-
<arg name="edges" type="uint" enum="resize" summary="how the surface was resized"/>
<arg name="width" type="int" summary="new width of the surface"/>
<arg name="height" type="int" summary="new height of the surface"/>
@@ -1368,10 +1362,10 @@
If wl_surface.attach is sent with a NULL wl_buffer, the
following wl_surface.commit will remove the surface content.
</description>
-
- <arg name="buffer" type="object" interface="wl_buffer" allow-null="true"/>
- <arg name="x" type="int"/>
- <arg name="y" type="int"/>
+ <arg name="buffer" type="object" interface="wl_buffer" allow-null="true"
+ summary="buffer of surface contents"/>
+ <arg name="x" type="int" summary="surface-local x coordinate"/>
+ <arg name="y" type="int" summary="surface-local y coordinate"/>
</request>
<request name="damage">
@@ -1383,7 +1377,8 @@
Damage is double-buffered state, see wl_surface.commit.
- The damage rectangle is specified in surface-local coordinates.
+ The damage rectangle is specified in surface-local coordinates,
+ where x and y specify the upper left corner of the damage rectangle.
The initial value for pending damage is empty: no damage.
wl_surface.damage adds pending damage: the new pending damage
@@ -1397,11 +1392,10 @@
which uses buffer coordinates instead of surface coordinates,
and is probably the preferred and intuitive way of doing this.
</description>
-
- <arg name="x" type="int"/>
- <arg name="y" type="int"/>
- <arg name="width" type="int"/>
- <arg name="height" type="int"/>
+ <arg name="x" type="int" summary="surface-local x coordinate"/>
+ <arg name="y" type="int" summary="surface-local y coordinate"/>
+ <arg name="width" type="int" summary="width of damage rectangle"/>
+ <arg name="height" type="int" summary="height of damage rectangle"/>
</request>
<request name="frame">
@@ -1439,8 +1433,7 @@
The callback_data passed in the callback is the current time, in
milliseconds, with an undefined base.
</description>
-
- <arg name="callback" type="new_id" interface="wl_callback"/>
+ <arg name="callback" type="new_id" interface="wl_callback" summary="callback object for the frame request"/>
</request>
<request name="set_opaque_region">
@@ -1470,8 +1463,8 @@
destroyed immediately. A NULL wl_region causes the pending opaque
region to be set to empty.
</description>
-
- <arg name="region" type="object" interface="wl_region" allow-null="true"/>
+ <arg name="region" type="object" interface="wl_region" allow-null="true"
+ summary="opaque region of the surface"/>
</request>
<request name="set_input_region">
@@ -1499,8 +1492,8 @@
immediately. A NULL wl_region causes the input region to be set
to infinite.
</description>
-
- <arg name="region" type="object" interface="wl_region" allow-null="true"/>
+ <arg name="region" type="object" interface="wl_region" allow-null="true"
+ summary="input region of the surface"/>
</request>
<request name="commit">
@@ -1579,7 +1572,8 @@
wl_output.transform enum the invalid_transform protocol error
is raised.
</description>
- <arg name="transform" type="int" enum="wl_output.transform"/>
+ <arg name="transform" type="int" enum="wl_output.transform"
+ summary="transform for interpreting buffer contents"/>
</request>
<!-- Version 3 additions -->
@@ -1610,7 +1604,8 @@
If scale is not positive the invalid_scale protocol error is
raised.
</description>
- <arg name="scale" type="int"/>
+ <arg name="scale" type="int"
+ summary="positive scale for interpreting buffer contents"/>
</request>
<!-- Version 4 additions -->
@@ -1623,7 +1618,8 @@
Damage is double-buffered state, see wl_surface.commit.
- The damage rectangle is specified in buffer coordinates.
+ The damage rectangle is specified in buffer coordinates,
+ where x and y specify the upper left corner of the damage rectangle.
The initial value for pending damage is empty: no damage.
wl_surface.damage_buffer adds pending damage: the new pending
@@ -1648,15 +1644,14 @@
two requests separately and only transform from one to the other
after receiving the wl_surface.commit.
</description>
-
- <arg name="x" type="int"/>
- <arg name="y" type="int"/>
- <arg name="width" type="int"/>
- <arg name="height" type="int"/>
+ <arg name="x" type="int" summary="buffer-local x coordinate"/>
+ <arg name="y" type="int" summary="buffer-local y coordinate"/>
+ <arg name="width" type="int" summary="width of damage rectangle"/>
+ <arg name="height" type="int" summary="height of damage rectangle"/>
</request>
</interface>
- <interface name="wl_seat" version="5">
+ <interface name="wl_seat" version="6">
<description summary="group of input devices">
A seat is a group of keyboards, pointer and touch devices. This
object is published as a global during start up, or when such a
@@ -1714,7 +1709,7 @@
It is a protocol violation to issue this request on a seat that has
never had the pointer capability.
</description>
- <arg name="id" type="new_id" interface="wl_pointer"/>
+ <arg name="id" type="new_id" interface="wl_pointer" summary="seat pointer"/>
</request>
<request name="get_keyboard">
@@ -1727,7 +1722,7 @@
It is a protocol violation to issue this request on a seat that has
never had the keyboard capability.
</description>
- <arg name="id" type="new_id" interface="wl_keyboard"/>
+ <arg name="id" type="new_id" interface="wl_keyboard" summary="seat keyboard"/>
</request>
<request name="get_touch">
@@ -1740,7 +1735,7 @@
It is a protocol violation to issue this request on a seat that has
never had the touch capability.
</description>
- <arg name="id" type="new_id" interface="wl_touch"/>
+ <arg name="id" type="new_id" interface="wl_touch" summary="seat touch interface"/>
</request>
<!-- Version 2 additions -->
@@ -1765,7 +1760,7 @@
</interface>
- <interface name="wl_pointer" version="5">
+ <interface name="wl_pointer" version="6">
<description summary="pointer input device">
The wl_pointer interface represents one or more input devices,
such as mice, which control the pointer location and pointer_focus
@@ -1815,9 +1810,9 @@
cursor ends, the current and pending input regions become
undefined, and the wl_surface is unmapped.
</description>
-
- <arg name="serial" type="uint" summary="serial of the enter event"/>
- <arg name="surface" type="object" interface="wl_surface" allow-null="true"/>
+ <arg name="serial" type="uint" summary="serial number of the enter event"/>
+ <arg name="surface" type="object" interface="wl_surface" allow-null="true"
+ summary="pointer surface"/>
<arg name="hotspot_x" type="int" summary="surface-local x coordinate"/>
<arg name="hotspot_y" type="int" summary="surface-local y coordinate"/>
</request>
@@ -1831,7 +1826,6 @@
is undefined and a client should respond to this event by setting
an appropriate pointer image with the set_cursor request.
</description>
-
<arg name="serial" type="uint" summary="serial number of the enter event"/>
<arg name="surface" type="object" interface="wl_surface" summary="surface entered by the pointer"/>
<arg name="surface_x" type="fixed" summary="surface-local x coordinate"/>
@@ -1856,7 +1850,6 @@
surface_x and surface_y are the location relative to the
focused surface.
</description>
-
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
<arg name="surface_x" type="fixed" summary="surface-local x coordinate"/>
<arg name="surface_y" type="fixed" summary="surface-local y coordinate"/>
@@ -1880,7 +1873,6 @@
The time argument is a timestamp with millisecond
granularity, with an undefined base.
</description>
-
<arg name="serial" type="uint" summary="serial number of the button event"/>
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
<arg name="button" type="uint" summary="button that produced the event"/>
@@ -1891,8 +1883,8 @@
<description summary="axis types">
Describes the axis types of scroll events.
</description>
- <entry name="vertical_scroll" value="0"/>
- <entry name="horizontal_scroll" value="1"/>
+ <entry name="vertical_scroll" value="0" summary="vertical axis"/>
+ <entry name="horizontal_scroll" value="1" summary="horizontal axis"/>
</enum>
<event name="axis">
@@ -1914,7 +1906,6 @@
When applicable, a client can transform its content relative to the
scroll distance.
</description>
-
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
<arg name="axis" type="uint" enum="axis" summary="axis type"/>
<arg name="value" type="fixed" summary="length of vector in surface-local coordinate space"/>
@@ -2078,7 +2069,7 @@
</event>
</interface>
- <interface name="wl_keyboard" version="5">
+ <interface name="wl_keyboard" version="6">
<description summary="keyboard input device">
The wl_keyboard interface represents one or more keyboards
associated with a seat.
@@ -2141,7 +2132,6 @@
The time argument is a timestamp with millisecond
granularity, with an undefined base.
</description>
-
<arg name="serial" type="uint" summary="serial number of the key event"/>
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
<arg name="key" type="uint" summary="key that produced the event"/>
@@ -2153,7 +2143,6 @@
Notifies clients that the modifier and/or group state has
changed, and it should update its local state.
</description>
-
<arg name="serial" type="uint" summary="serial number of the modifiers event"/>
<arg name="mods_depressed" type="uint" summary="depressed modifiers"/>
<arg name="mods_latched" type="uint" summary="latched modifiers"/>
@@ -2184,7 +2173,6 @@
so clients should continue listening for the event past the creation
of wl_keyboard.
</description>
-
<arg name="rate" type="int"
summary="the rate of repeating keys in characters per second"/>
<arg name="delay" type="int"
@@ -2192,7 +2180,7 @@
</event>
</interface>
- <interface name="wl_touch" version="5">
+ <interface name="wl_touch" version="6">
<description summary="touchscreen input device">
The wl_touch interface represents a touchscreen
associated with a seat.
@@ -2242,7 +2230,14 @@
<event name="frame">
<description summary="end of touch frame event">
- Indicates the end of a contact point list.
+ Indicates the end of a set of events that logically belong together.
+ A client is expected to accumulate the data in all events within the
+ frame before proceeding.
+
+ A wl_touch.frame terminates at least one event but otherwise no
+ guarantee is provided about the set of events within a frame. A client
+ must assume that any state not updated in a frame is unchanged from the
+ previously known state.
</description>
</event>
@@ -2262,9 +2257,74 @@
<request name="release" type="destructor" since="3">
<description summary="release the touch object"/>
</request>
+
+ <!-- Version 6 additions -->
+
+ <event name="shape" since="6">
+ <description summary="update shape of touch point">
+ Sent when a touchpoint has changed its shape.
+
+ This event does not occur on its own. It is sent before a
+ wl_touch.frame event and carries the new shape information for
+ any previously reported, or new touch points of that frame.
+
+ Other events describing the touch point such as wl_touch.down,
+ wl_touch.motion or wl_touch.orientation may be sent within the
+ same wl_touch.frame. A client should treat these events as a single
+ logical touch point update. The order of wl_touch.shape,
+ wl_touch.orientation and wl_touch.motion is not guaranteed.
+ A wl_touch.down event is guaranteed to occur before the first
+ wl_touch.shape event for this touch ID but both events may occur within
+ the same wl_touch.frame.
+
+ A touchpoint shape is approximated by an ellipse through the major and
+ minor axis length. The major axis length describes the longer diameter
+ of the ellipse, while the minor axis length describes the shorter
+ diameter. Major and minor are orthogonal and both are specified in
+ surface-local coordinates. The center of the ellipse is always at the
+ touchpoint location as reported by wl_touch.down or wl_touch.move.
+
+ This event is only sent by the compositor if the touch device supports
+ shape reports. The client has to make reasonable assumptions about the
+ shape if it did not receive this event.
+ </description>
+ <arg name="id" type="int" summary="the unique ID of this touch point"/>
+ <arg name="major" type="fixed" summary="length of the major axis in surface-local coordinates"/>
+ <arg name="minor" type="fixed" summary="length of the minor axis in surface-local coordinates"/>
+ </event>
+
+ <event name="orientation" since="6">
+ <description summary="update orientation of touch point">
+ Sent when a touchpoint has changed its orientation.
+
+ This event does not occur on its own. It is sent before a
+ wl_touch.frame event and carries the new shape information for
+ any previously reported, or new touch points of that frame.
+
+ Other events describing the touch point such as wl_touch.down,
+ wl_touch.motion or wl_touch.shape may be sent within the
+ same wl_touch.frame. A client should treat these events as a single
+ logical touch point update. The order of wl_touch.shape,
+ wl_touch.orientation and wl_touch.motion is not guaranteed.
+ A wl_touch.down event is guaranteed to occur before the first
+ wl_touch.orientation event for this touch ID but both events may occur
+ within the same wl_touch.frame.
+
+ The orientation describes the clockwise angle of a touchpoint's major
+ axis to the positive surface y-axis and is normalized to the -180 to
+ +180 degree range. The granularity of orientation depends on the touch
+ device, some devices only support binary rotation values between 0 and
+ 90 degrees.
+
+ This event is only sent by the compositor if the touch device supports
+ orientation reports.
+ </description>
+ <arg name="id" type="int" summary="the unique ID of this touch point"/>
+ <arg name="orientation" type="fixed" summary="angle between major axis and positive surface y-axis in degrees"/>
+ </event>
</interface>
- <interface name="wl_output" version="2">
+ <interface name="wl_output" version="3">
<description summary="compositor output region">
An output describes part of the compositor geometry. The
compositor works in the 'compositor coordinate system' and an
@@ -2279,12 +2339,12 @@
This enumeration describes how the physical
pixels on an output are laid out.
</description>
- <entry name="unknown" value="0"/>
- <entry name="none" value="1"/>
- <entry name="horizontal_rgb" value="2"/>
- <entry name="horizontal_bgr" value="3"/>
- <entry name="vertical_rgb" value="4"/>
- <entry name="vertical_bgr" value="5"/>
+ <entry name="unknown" value="0" summary="unknown geometry"/>
+ <entry name="none" value="1" summary="no geometry"/>
+ <entry name="horizontal_rgb" value="2" summary="horizontal RGB"/>
+ <entry name="horizontal_bgr" value="3" summary="horizontal BGR"/>
+ <entry name="vertical_rgb" value="4" summary="vertical RGB"/>
+ <entry name="vertical_bgr" value="5" summary="vertical BGR"/>
</enum>
<enum name="transform">
@@ -2301,15 +2361,14 @@
compositor will still be able to scan out directly from client
surfaces.
</description>
-
- <entry name="normal" value="0"/>
- <entry name="90" value="1"/>
- <entry name="180" value="2"/>
- <entry name="270" value="3"/>
- <entry name="flipped" value="4"/>
- <entry name="flipped_90" value="5"/>
- <entry name="flipped_180" value="6"/>
- <entry name="flipped_270" value="7"/>
+ <entry name="normal" value="0" summary="no transform"/>
+ <entry name="90" value="1" summary="90 degrees counter-clockwise"/>
+ <entry name="180" value="2" summary="180 degrees counter-clockwise"/>
+ <entry name="270" value="3" summary="270 degrees counter-clockwise"/>
+ <entry name="flipped" value="4" summary="180 degree flip around a vertical axis"/>
+ <entry name="flipped_90" value="5" summary="flip and rotate 90 degrees counter-clockwise"/>
+ <entry name="flipped_180" value="6" summary="flip and rotate 180 degrees counter-clockwise"/>
+ <entry name="flipped_270" value="7" summary="flip and rotate 270 degrees counter-clockwise"/>
</enum>
<event name="geometry">
@@ -2369,6 +2428,8 @@
<arg name="refresh" type="int" summary="vertical refresh rate in mHz"/>
</event>
+ <!-- Version 2 additions -->
+
<event name="done" since="2">
<description summary="sent all information about output">
This event is sent after all other properties have been
@@ -2402,6 +2463,15 @@
</description>
<arg name="factor" type="int" summary="scaling factor of output"/>
</event>
+
+ <!-- Version 3 additions -->
+
+ <request name="release" type="destructor" since="3">
+ <description summary="release the output object">
+ Using this request a client can tell the server that it is not going to
+ use the output object anymore.
+ </description>
+ </request>
</interface>
<interface name="wl_region" version="1">
@@ -2422,22 +2492,20 @@
<description summary="add rectangle to region">
Add the specified rectangle to the region.
</description>
-
- <arg name="x" type="int"/>
- <arg name="y" type="int"/>
- <arg name="width" type="int"/>
- <arg name="height" type="int"/>
+ <arg name="x" type="int" summary="region-local x coordinate"/>
+ <arg name="y" type="int" summary="region-local y coordinate"/>
+ <arg name="width" type="int" summary="rectangle width"/>
+ <arg name="height" type="int" summary="rectangle height"/>
</request>
<request name="subtract">
<description summary="subtract rectangle from region">
Subtract the specified rectangle from the region.
</description>
-
- <arg name="x" type="int"/>
- <arg name="y" type="int"/>
- <arg name="width" type="int"/>
- <arg name="height" type="int"/>
+ <arg name="x" type="int" summary="region-local x coordinate"/>
+ <arg name="y" type="int" summary="region-local y coordinate"/>
+ <arg name="width" type="int" summary="rectangle width"/>
+ <arg name="height" type="int" summary="rectangle height"/>
</request>
</interface>
@@ -2487,9 +2555,8 @@
must not have an existing wl_subsurface object. Otherwise a protocol
error is raised.
</description>
-
<arg name="id" type="new_id" interface="wl_subsurface"
- summary="the new subsurface object ID"/>
+ summary="the new sub-surface object ID"/>
<arg name="surface" type="object" interface="wl_surface"
summary="the surface to be turned into a sub-surface"/>
<arg name="parent" type="object" interface="wl_surface"
@@ -2584,7 +2651,6 @@
The initial position is 0, 0.
</description>
-
<arg name="x" type="int" summary="x coordinate in the parent surface"/>
<arg name="y" type="int" summary="y coordinate in the parent surface"/>
</request>
@@ -2607,7 +2673,6 @@
A new sub-surface is initially added as the top-most in the stack
of its siblings and parent.
</description>
-
<arg name="sibling" type="object" interface="wl_surface"
summary="the reference surface"/>
</request>
@@ -2617,7 +2682,6 @@
The sub-surface is placed just below the reference surface.
See wl_subsurface.place_above.
</description>
-
<arg name="sibling" type="object" interface="wl_surface"
summary="the reference surface"/>
</request>
diff --git a/src/connection.c b/src/connection.c
index c3293a9..5c3d187 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -392,7 +392,7 @@ wl_connection_queue(struct wl_connection *connection,
return wl_buffer_put(&connection->out, data, count);
}
-static int
+int
wl_message_count_arrays(const struct wl_message *message)
{
int i, arrays;
diff --git a/src/event-loop.c b/src/event-loop.c
index ea27b69..6130d2a 100644
--- a/src/event-loop.c
+++ b/src/event-loop.c
@@ -28,6 +28,7 @@
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
+#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <sys/socket.h>
@@ -36,8 +37,9 @@
#include <sys/signalfd.h>
#include <sys/timerfd.h>
#include <unistd.h>
+#include "wayland-util.h"
#include "wayland-private.h"
-#include "wayland-server.h"
+#include "wayland-server-core.h"
#include "wayland-os.h"
struct wl_event_loop {
@@ -227,7 +229,7 @@ struct wl_event_source_signal {
static int
wl_event_source_signal_dispatch(struct wl_event_source *source,
- struct epoll_event *ep)
+ struct epoll_event *ep)
{
struct wl_event_source_signal *signal_source =
(struct wl_event_source_signal *) source;
@@ -249,9 +251,9 @@ struct wl_event_source_interface signal_source_interface = {
WL_EXPORT struct wl_event_source *
wl_event_loop_add_signal(struct wl_event_loop *loop,
- int signal_number,
- wl_event_loop_signal_func_t func,
- void *data)
+ int signal_number,
+ wl_event_loop_signal_func_t func,
+ void *data)
{
struct wl_event_source_signal *source;
sigset_t mask;
diff --git a/src/scanner.c b/src/scanner.c
index 5f06e8e..a239c71 100644
--- a/src/scanner.c
+++ b/src/scanner.c
@@ -31,6 +31,7 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdarg.h>
+#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
@@ -49,6 +50,8 @@ extern int DTD_DATA_len;
#include "wayland-util.h"
+#define PROGRAM_NAME "wayland-scanner"
+
enum side {
CLIENT,
SERVER,
@@ -57,8 +60,8 @@ enum side {
static int
usage(int ret)
{
- fprintf(stderr, "usage: ./scanner [OPTION] [client-header|server-header|code]"
- " [input_file output_file]\n");
+ fprintf(stderr, "usage: %s [OPTION] [client-header|server-header|code]"
+ " [input_file output_file]\n", PROGRAM_NAME);
fprintf(stderr, "\n");
fprintf(stderr, "Converts XML protocol descriptions supplied on "
"stdin or input file to client\n"
@@ -76,7 +79,7 @@ usage(int ret)
static int
scanner_version(int ret)
{
- fprintf(stderr, "wayland-scanner %s\n", WAYLAND_VERSION);
+ fprintf(stderr, "%s %s\n", PROGRAM_NAME, WAYLAND_VERSION);
exit(ret);
}
@@ -236,7 +239,7 @@ static void *
fail_on_null(void *p)
{
if (p == NULL) {
- fprintf(stderr, "wayland-scanner: out of memory\n");
+ fprintf(stderr, "%s: out of memory\n", PROGRAM_NAME);
exit(EXIT_FAILURE);
}
@@ -574,8 +577,17 @@ free_interface(struct interface *interface)
free(interface);
}
-/* convert string to unsigned integer,
- * in the case of error, return -1 */
+/* Convert string to unsigned integer
+ *
+ * Parses a non-negative base-10 number from the given string. If the
+ * specified string is blank, contains non-numerical characters, is out
+ * of range, or results in a negative number, -1 is returned to indicate
+ * an error.
+ *
+ * Upon error, this routine does not modify or set errno.
+ *
+ * Returns -1 on error, or a non-negative integer on success
+ */
static int
strtouint(const char *str)
{
@@ -808,7 +820,7 @@ find_enumeration(struct protocol *protocol,
struct interface *i;
struct enumeration *e;
char *enum_name;
- uint idx = 0, j;
+ uint32_t idx = 0, j;
for (j = 0; j + 1 < strlen(enum_attribute); j++) {
if (enum_attribute[j] == '.') {
@@ -962,7 +974,7 @@ emit_opcodes(struct wl_list *message_list, struct interface *interface)
opcode = 0;
wl_list_for_each(m, message_list, link)
- printf("#define %s_%s\t%d\n",
+ printf("#define %s_%s %d\n",
interface->uppercase_name, m->uppercase_name, opcode++);
printf("\n");
@@ -975,7 +987,7 @@ emit_opcode_versions(struct wl_list *message_list, struct interface *interface)
wl_list_for_each(m, message_list, link) {
printf("/**\n * @ingroup iface_%s\n */\n", interface->name);
- printf("#define %s_%s_SINCE_VERSION\t%d\n",
+ printf("#define %s_%s_SINCE_VERSION %d\n",
interface->uppercase_name, m->uppercase_name, m->since);
}
@@ -1350,7 +1362,7 @@ emit_structs(struct wl_list *message_list, struct interface *interface, enum sid
if (side == CLIENT) {
printf("/**\n"
- " * @ingroup %s_iface\n"
+ " * @ingroup iface_%s\n"
" */\n", interface->name);
printf("static inline int\n"
"%s_add_listener(struct %s *%s,\n"
@@ -1467,7 +1479,7 @@ emit_header(struct protocol *protocol, enum side side)
const char *s = (side == SERVER) ? "SERVER" : "CLIENT";
char **p, *prev;
- printf("/* Generated by wayland-scanner %s */\n\n", WAYLAND_VERSION);
+ printf("/* Generated by %s %s */\n\n", PROGRAM_NAME, WAYLAND_VERSION);
printf("#ifndef %s_%s_PROTOCOL_H\n"
"#define %s_%s_PROTOCOL_H\n"
@@ -1542,10 +1554,12 @@ emit_header(struct protocol *protocol, enum side side)
emit_structs(&i->request_list, i, side);
emit_opcodes(&i->event_list, i);
emit_opcode_versions(&i->event_list, i);
+ emit_opcode_versions(&i->request_list, i);
emit_event_wrappers(&i->event_list, i);
} else {
emit_structs(&i->event_list, i, side);
emit_opcodes(&i->request_list, i);
+ emit_opcode_versions(&i->event_list, i);
emit_opcode_versions(&i->request_list, i);
emit_stubs(&i->request_list, i);
}
@@ -1670,7 +1684,7 @@ emit_code(struct protocol *protocol)
struct wl_array types;
char **p, *prev;
- printf("/* Generated by wayland-scanner %s */\n\n", WAYLAND_VERSION);
+ printf("/* Generated by %s %s */\n\n", PROGRAM_NAME, WAYLAND_VERSION);
if (protocol->copyright)
format_text_to_comment(protocol->copyright, true);
diff --git a/src/wayland-client-core.h b/src/wayland-client-core.h
index b1d6515..03e781b 100644
--- a/src/wayland-client-core.h
+++ b/src/wayland-client-core.h
@@ -26,6 +26,7 @@
#ifndef WAYLAND_CLIENT_CORE_H
#define WAYLAND_CLIENT_CORE_H
+#include <stdint.h>
#include "wayland-util.h"
#include "wayland-version.h"
@@ -150,10 +151,12 @@ wl_proxy_marshal_constructor_versioned(struct wl_proxy *proxy,
const struct wl_interface *interface,
uint32_t version,
...);
+
struct wl_proxy *
wl_proxy_marshal_array_constructor(struct wl_proxy *proxy,
uint32_t opcode, union wl_argument *args,
const struct wl_interface *interface);
+
struct wl_proxy *
wl_proxy_marshal_array_constructor_versioned(struct wl_proxy *proxy,
uint32_t opcode,
diff --git a/src/wayland-private.h b/src/wayland-private.h
index 045109b..676b181 100644
--- a/src/wayland-private.h
+++ b/src/wayland-private.h
@@ -30,11 +30,15 @@
#include <stdarg.h>
#include <stdlib.h>
+#include <stdint.h>
#define WL_HIDE_DEPRECATED 1
#include "wayland-util.h"
+/* Invalid memory address */
+#define WL_ARRAY_POISON_PTR (void *) 4
+
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
#define container_of(ptr, type, member) ({ \
@@ -74,7 +78,8 @@ struct wl_map {
uint32_t free_list;
};
-typedef void (*wl_iterator_func_t)(void *element, void *data);
+typedef enum wl_iterator_result (*wl_iterator_func_t)(void *element,
+ void *data);
void
wl_map_init(struct wl_map *map, uint32_t side);
@@ -158,6 +163,9 @@ int
arg_count_for_signature(const char *signature);
int
+wl_message_count_arrays(const struct wl_message *message);
+
+int
wl_message_get_since(const struct wl_message *message);
void
diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h
index fa7f394..2c215e4 100644
--- a/src/wayland-server-core.h
+++ b/src/wayland-server-core.h
@@ -42,8 +42,6 @@ enum {
WL_EVENT_ERROR = 0x08
};
-struct wl_event_loop;
-struct wl_event_source;
typedef int (*wl_event_loop_fd_func_t)(int fd, uint32_t mask, void *data);
typedef int (*wl_event_loop_timer_func_t)(void *data);
typedef int (*wl_event_loop_signal_func_t)(int signal_number, void *data);
@@ -71,9 +69,9 @@ wl_event_loop_add_timer(struct wl_event_loop *loop,
struct wl_event_source *
wl_event_loop_add_signal(struct wl_event_loop *loop,
- int signal_number,
- wl_event_loop_signal_func_t func,
- void *data);
+ int signal_number,
+ wl_event_loop_signal_func_t func,
+ void *data);
int
wl_event_source_timer_update(struct wl_event_source *source,
@@ -85,7 +83,6 @@ wl_event_source_remove(struct wl_event_source *source);
void
wl_event_source_check(struct wl_event_source *source);
-
int
wl_event_loop_dispatch(struct wl_event_loop *loop, int timeout);
@@ -100,20 +97,16 @@ wl_event_loop_add_idle(struct wl_event_loop *loop,
int
wl_event_loop_get_fd(struct wl_event_loop *loop);
-struct wl_client;
-struct wl_display;
struct wl_listener;
-struct wl_resource;
-struct wl_global;
+
typedef void (*wl_notify_func_t)(struct wl_listener *listener, void *data);
void
wl_event_loop_add_destroy_listener(struct wl_event_loop *loop,
- struct wl_listener * listener);
+ struct wl_listener *listener);
struct wl_listener *
-wl_event_loop_get_destroy_listener(
- struct wl_event_loop *loop,
+wl_event_loop_get_destroy_listener(struct wl_event_loop *loop,
wl_notify_func_t notify);
struct wl_display *
@@ -143,6 +136,8 @@ wl_display_run(struct wl_display *display);
void
wl_display_flush_clients(struct wl_display *display);
+struct wl_client;
+
typedef void (*wl_global_bind_func_t)(struct wl_client *client, void *data,
uint32_t version, uint32_t id);
@@ -156,6 +151,10 @@ void
wl_display_add_destroy_listener(struct wl_display *display,
struct wl_listener *listener);
+void
+wl_display_add_client_created_listener(struct wl_display *display,
+ struct wl_listener *listener);
+
struct wl_listener *
wl_display_get_destroy_listener(struct wl_display *display,
wl_notify_func_t notify);
@@ -172,6 +171,21 @@ wl_global_destroy(struct wl_global *global);
struct wl_client *
wl_client_create(struct wl_display *display, int fd);
+struct wl_list *
+wl_display_get_client_list(struct wl_display *display);
+
+struct wl_list *
+wl_client_get_link(struct wl_client *client);
+
+struct wl_client *
+wl_client_from_link(struct wl_list *link);
+
+/** Iterate over a list of clients. */
+#define wl_client_for_each(client, list) \
+ for (client = wl_client_from_link((list)->next); \
+ wl_client_get_link(client) != (list); \
+ client = wl_client_from_link(wl_client_get_link(client)->next))
+
void
wl_client_destroy(struct wl_client *client);
@@ -199,6 +213,19 @@ wl_client_get_object(struct wl_client *client, uint32_t id);
void
wl_client_post_no_memory(struct wl_client *client);
+void
+wl_client_add_resource_created_listener(struct wl_client *client,
+ struct wl_listener *listener);
+
+typedef enum wl_iterator_result (*wl_client_for_each_resource_iterator_func_t)(
+ struct wl_resource *resource,
+ void *user_data);
+
+void
+wl_client_for_each_resource(struct wl_client *client,
+ wl_client_for_each_resource_iterator_func_t iterator,
+ void *user_data);
+
/** \class wl_listener
*
* \brief A single listener for Wayland signals
@@ -360,16 +387,17 @@ void
wl_resource_queue_event(struct wl_resource *resource,
uint32_t opcode, ...);
-void wl_resource_queue_event_array(struct wl_resource *resource,
- uint32_t opcode, union wl_argument *args);
+void
+wl_resource_queue_event_array(struct wl_resource *resource,
+ uint32_t opcode, union wl_argument *args);
/* msg is a printf format string, variable args are its args. */
void
wl_resource_post_error(struct wl_resource *resource,
- uint32_t code, const char *msg, ...)
- __attribute__ ((format (printf, 3, 4)));
+ uint32_t code, const char *msg, ...) WL_PRINTF(3, 4);
-void wl_resource_post_no_memory(struct wl_resource *resource);
+void
+wl_resource_post_no_memory(struct wl_resource *resource);
struct wl_display *
wl_client_get_display(struct wl_client *client);
@@ -378,11 +406,13 @@ struct wl_resource *
wl_resource_create(struct wl_client *client,
const struct wl_interface *interface,
int version, uint32_t id);
+
void
wl_resource_set_implementation(struct wl_resource *resource,
const void *implementation,
void *data,
wl_resource_destroy_func_t destroy);
+
void
wl_resource_set_dispatcher(struct wl_resource *resource,
wl_dispatcher_func_t dispatcher,
@@ -392,33 +422,46 @@ wl_resource_set_dispatcher(struct wl_resource *resource,
void
wl_resource_destroy(struct wl_resource *resource);
+
uint32_t
wl_resource_get_id(struct wl_resource *resource);
+
struct wl_list *
wl_resource_get_link(struct wl_resource *resource);
+
struct wl_resource *
wl_resource_from_link(struct wl_list *resource);
+
struct wl_resource *
wl_resource_find_for_client(struct wl_list *list, struct wl_client *client);
+
struct wl_client *
wl_resource_get_client(struct wl_resource *resource);
+
void
wl_resource_set_user_data(struct wl_resource *resource, void *data);
+
void *
wl_resource_get_user_data(struct wl_resource *resource);
+
int
wl_resource_get_version(struct wl_resource *resource);
+
void
wl_resource_set_destructor(struct wl_resource *resource,
wl_resource_destroy_func_t destroy);
+
int
wl_resource_instance_of(struct wl_resource *resource,
const struct wl_interface *interface,
const void *implementation);
+const char *
+wl_resource_get_class(struct wl_resource *resource);
void
wl_resource_add_destroy_listener(struct wl_resource *resource,
- struct wl_listener * listener);
+ struct wl_listener *listener);
+
struct wl_listener *
wl_resource_get_destroy_listener(struct wl_resource *resource,
wl_notify_func_t notify);
@@ -436,8 +479,8 @@ wl_resource_get_destroy_listener(struct wl_resource *resource,
resource = tmp, \
tmp = wl_resource_from_link(wl_resource_get_link(resource)->next))
-struct wl_shm_pool;
-struct wl_shm_buffer;
+struct wl_shm_buffer *
+wl_shm_buffer_get(struct wl_resource *resource);
void
wl_shm_buffer_begin_access(struct wl_shm_buffer *buffer);
@@ -445,9 +488,6 @@ wl_shm_buffer_begin_access(struct wl_shm_buffer *buffer);
void
wl_shm_buffer_end_access(struct wl_shm_buffer *buffer);
-struct wl_shm_buffer *
-wl_shm_buffer_get(struct wl_resource *resource);
-
void *
wl_shm_buffer_get_data(struct wl_shm_buffer *buffer);
@@ -480,7 +520,32 @@ wl_shm_buffer_create(struct wl_client *client,
uint32_t id, int32_t width, int32_t height,
int32_t stride, uint32_t format) WL_DEPRECATED;
-void wl_log_set_handler_server(wl_log_func_t handler);
+void
+wl_log_set_handler_server(wl_log_func_t handler);
+
+enum wl_protocol_logger_type {
+ WL_PROTOCOL_LOGGER_REQUEST,
+ WL_PROTOCOL_LOGGER_EVENT,
+};
+
+struct wl_protocol_logger_message {
+ struct wl_resource *resource;
+ int message_opcode;
+ const struct wl_message *message;
+ int arguments_count;
+ const union wl_argument *arguments;
+};
+
+typedef void (*wl_protocol_logger_func_t)(void *user_data,
+ enum wl_protocol_logger_type direction,
+ const struct wl_protocol_logger_message *message);
+
+struct wl_protocol_logger *
+wl_display_add_protocol_logger(struct wl_display *display,
+ wl_protocol_logger_func_t, void *user_data);
+
+void
+wl_protocol_logger_destroy(struct wl_protocol_logger *logger);
#ifdef __cplusplus
}
diff --git a/src/wayland-server.c b/src/wayland-server.c
index f745e62..9d7d9c1 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -43,9 +43,9 @@
#include <sys/file.h>
#include <sys/stat.h>
+#include "wayland-util.h"
#include "wayland-private.h"
#include "wayland-server.h"
-#include "wayland-server-protocol.h"
#include "wayland-os.h"
/* This is the size of the char array in struct sock_addr_un.
@@ -81,6 +81,7 @@ struct wl_client {
struct wl_signal destroy_signal;
struct ucred ucred;
int error;
+ struct wl_signal resource_created_signal;
};
struct wl_display {
@@ -94,8 +95,10 @@ struct wl_display {
struct wl_list global_list;
struct wl_list socket_list;
struct wl_list client_list;
+ struct wl_list protocol_loggers;
struct wl_signal destroy_signal;
+ struct wl_signal create_client_signal;
struct wl_array additional_shm_formats;
};
@@ -121,8 +124,42 @@ struct wl_resource {
wl_dispatcher_func_t dispatcher;
};
+struct wl_protocol_logger {
+ struct wl_list link;
+ wl_protocol_logger_func_t func;
+ void *user_data;
+};
+
static int debug_server = 0;
+static void
+log_closure(struct wl_resource *resource,
+ struct wl_closure *closure, int send)
+{
+ struct wl_object *object = &resource->object;
+ struct wl_display *display = resource->client->display;
+ struct wl_protocol_logger *protocol_logger;
+ struct wl_protocol_logger_message message;
+
+ if (debug_server)
+ wl_closure_print(closure, object, send);
+
+ if (!wl_list_empty(&display->protocol_loggers)) {
+ message.resource = resource;
+ message.message_opcode = closure->opcode;
+ message.message = closure->message;
+ message.arguments_count = closure->count;
+ message.arguments = closure->args;
+ wl_list_for_each(protocol_logger,
+ &display->protocol_loggers, link) {
+ protocol_logger->func(protocol_logger->user_data,
+ send ? WL_PROTOCOL_LOGGER_EVENT :
+ WL_PROTOCOL_LOGGER_REQUEST,
+ &message);
+ }
+ }
+}
+
WL_EXPORT void
wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode,
union wl_argument *args)
@@ -141,8 +178,7 @@ wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode,
if (wl_closure_send(closure, resource->client->connection))
resource->client->error = 1;
- if (debug_server)
- wl_closure_print(closure, object, true);
+ log_closure(resource, closure, true);
wl_closure_destroy(closure);
}
@@ -181,8 +217,7 @@ wl_resource_queue_event_array(struct wl_resource *resource, uint32_t opcode,
if (wl_closure_queue(closure, resource->client->connection))
resource->client->error = 1;
- if (debug_server)
- wl_closure_print(closure, object, true);
+ log_closure(resource, closure, true);
wl_closure_destroy(closure);
}
@@ -329,8 +364,7 @@ wl_client_connection_data(int fd, uint32_t mask, void *data)
break;
}
- if (debug_server)
- wl_closure_print(closure, object, false);
+ log_closure(resource, closure, false);
if ((resource_flags & WL_MAP_ENTRY_LEGACY) ||
resource->dispatcher == NULL) {
@@ -406,6 +440,9 @@ bind_display(struct wl_client *client, struct wl_display *display);
* wl_display_connect_to_fd() on the client side or used with the
* WAYLAND_SOCKET environment variable on the client side.
*
+ * Listeners added with wl_display_add_client_created_listener() will
+ * be notified by this function after the client is fully constructed.
+ *
* On failure this function sets errno accordingly and returns NULL.
*
* \memberof wl_display
@@ -420,6 +457,7 @@ wl_client_create(struct wl_display *display, int fd)
if (client == NULL)
return NULL;
+ wl_signal_init(&client->resource_created_signal);
client->display = display;
client->source = wl_event_loop_add_fd(display->loop, fd,
WL_EVENT_READABLE,
@@ -448,6 +486,8 @@ wl_client_create(struct wl_display *display, int fd)
wl_list_insert(display->client_list.prev, &client->link);
+ wl_signal_emit(&display->create_client_signal, client);
+
return client;
err_map:
@@ -557,7 +597,7 @@ wl_resource_post_no_memory(struct wl_resource *resource)
WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
}
-static void
+static enum wl_iterator_result
destroy_resource(void *element, void *data)
{
struct wl_resource *resource = element;
@@ -572,6 +612,8 @@ destroy_resource(void *element, void *data)
if (!(flags & WL_MAP_ENTRY_LEGACY))
free(resource);
+
+ return WL_ITERATOR_CONTINUE;
}
WL_EXPORT void
@@ -684,6 +726,18 @@ wl_resource_get_destroy_listener(struct wl_resource *resource,
return wl_signal_get(&resource->destroy_signal, notify);
}
+/** Retrieve the interface name (class) of a resource object.
+ *
+ * \param resource The resource object
+ *
+ * \memberof wl_resource
+ */
+WL_EXPORT const char *
+wl_resource_get_class(struct wl_resource *resource)
+{
+ return resource->object.interface->name;
+}
+
WL_EXPORT void
wl_client_add_destroy_listener(struct wl_client *client,
struct wl_listener *listener)
@@ -711,6 +765,7 @@ wl_client_destroy(struct wl_client *client)
wl_event_source_remove(client->source);
close(wl_connection_destroy(client->connection));
wl_list_remove(&client->link);
+ wl_list_remove(&client->resource_created_signal.listener_list);
free(client);
}
@@ -862,8 +917,10 @@ wl_display_create(void)
wl_list_init(&display->socket_list);
wl_list_init(&display->client_list);
wl_list_init(&display->registry_resource_list);
+ wl_list_init(&display->protocol_loggers);
wl_signal_init(&display->destroy_signal);
+ wl_signal_init(&display->create_client_signal);
display->id = 1;
display->serial = 0;
@@ -937,6 +994,8 @@ wl_display_destroy(struct wl_display *display)
wl_array_release(&display->additional_shm_formats);
+ wl_list_remove(&display->protocol_loggers);
+
free(display);
}
@@ -1353,6 +1412,24 @@ wl_display_add_destroy_listener(struct wl_display *display,
wl_signal_add(&display->destroy_signal, listener);
}
+/** Registers a listener for the client connection signal.
+ * When a new client object is created, \a listener will be notified, carrying
+ * a pointer to the new wl_client object.
+ *
+ * \ref wl_client_create
+ * \ref wl_display
+ * \ref wl_listener
+ *
+ * \param display The display object
+ * \param listener Signal handler object
+ */
+WL_EXPORT void
+wl_display_add_client_created_listener(struct wl_display *display,
+ struct wl_listener *listener)
+{
+ wl_signal_add(&display->create_client_signal, listener);
+}
+
WL_EXPORT struct wl_listener *
wl_display_get_destroy_listener(struct wl_display *display,
wl_notify_func_t notify)
@@ -1383,6 +1460,18 @@ wl_resource_set_dispatcher(struct wl_resource *resource,
resource->destroy = destroy;
}
+/** Create a new resource object
+ *
+ * \param client The client owner of the new resource.
+ * \param interface The interface of the new resource.
+ * \param version The version of the new resource.
+ * \param id The id of the new resource. If 0, an available id will be used.
+ *
+ * Listeners added with \a wl_client_add_resource_created_listener will be
+ * notified at the end of this function.
+ *
+ * \memberof wl_resource
+ */
WL_EXPORT struct wl_resource *
wl_resource_create(struct wl_client *client,
const struct wl_interface *interface,
@@ -1417,6 +1506,7 @@ wl_resource_create(struct wl_client *client,
return NULL;
}
+ wl_signal_emit(&client->resource_created_signal, resource);
return resource;
}
@@ -1426,6 +1516,62 @@ wl_log_set_handler_server(wl_log_func_t handler)
wl_log_handler = handler;
}
+/** Adds a new protocol logger.
+ *
+ * When a new protocol message arrives or is sent from the server
+ * all the protocol logger functions will be called, carrying the
+ * \a user_data pointer, the type of the message (request or
+ * event) and the actual message.
+ * The lifetime of the messages passed to the logger function ends
+ * when they return so the messages cannot be stored and accessed
+ * later.
+ *
+ * \a errno is set on error.
+ *
+ * \param display The display object
+ * \param func The function to call to log a new protocol message
+ * \param user_data The user data pointer to pass to \a func
+ *
+ * \return The protol logger object on success, NULL on failure.
+ *
+ * \sa wl_protocol_logger_destroy
+ *
+ * \memberof wl_display
+ */
+WL_EXPORT struct wl_protocol_logger *
+wl_display_add_protocol_logger(struct wl_display *display,
+ wl_protocol_logger_func_t func, void *user_data)
+{
+ struct wl_protocol_logger *logger;
+
+ logger = malloc(sizeof *logger);
+ if (!logger)
+ return NULL;
+
+ logger->func = func;
+ logger->user_data = user_data;
+ wl_list_insert(&display->protocol_loggers, &logger->link);
+
+ return logger;
+}
+
+/** Destroys a protocol logger.
+ *
+ * This function destroys a protocol logger and removes it from the display
+ * it was added to with \a wl_display_add_protocol_logger.
+ * The \a logger object becomes invalid after calling this function.
+ *
+ * \sa wl_display_add_protocol_logger
+ *
+ * \memberof wl_protocol_logger
+ */
+WL_EXPORT void
+wl_protocol_logger_destroy(struct wl_protocol_logger *logger)
+{
+ wl_list_remove(&logger->link);
+ free(logger);
+}
+
/** Add support for a wl_shm pixel format
*
* \param display The display object
@@ -1470,6 +1616,8 @@ wl_display_add_shm_format(struct wl_display *display, uint32_t format)
*
* \sa wl_display_add_shm_format()
*
+ * \private
+ *
* \memberof wl_display
*/
struct wl_array *
@@ -1478,6 +1626,123 @@ wl_display_get_additional_shm_formats(struct wl_display *display)
return &display->additional_shm_formats;
}
+/** Get the list of currently connected clients
+ *
+ * \param display The display object
+ *
+ * This function returns a pointer to the list of clients currently
+ * connected to the display. You can iterate on the list by using
+ * the \a wl_client_for_each macro.
+ * The returned value is valid for the lifetime of the \a display.
+ * You must not modify the returned list, but only access it.
+ *
+ * \sa wl_client_for_each()
+ * \sa wl_client_get_link()
+ * \sa wl_client_from_link()
+ *
+ * \memberof wl_display
+ */
+WL_EXPORT struct wl_list *
+wl_display_get_client_list(struct wl_display *display)
+{
+ return &display->client_list;
+}
+
+/** Get the link by which a client is inserted in the client list
+ *
+ * \param client The client object
+ *
+ * \sa wl_client_for_each()
+ * \sa wl_display_get_client_list()
+ * \sa wl_client_from_link()
+ *
+ * \memberof wl_client
+ */
+WL_EXPORT struct wl_list *
+wl_client_get_link(struct wl_client *client)
+{
+ return &client->link;
+}
+
+/** Get a wl_client by its link
+ *
+ * \param link The link of a wl_client
+ *
+ * \sa wl_client_for_each()
+ * \sa wl_display_get_client_list()
+ * \sa wl_client_get_link()
+ *
+ * \memberof wl_client
+ */
+WL_EXPORT struct wl_client *
+wl_client_from_link(struct wl_list *link)
+{
+ return container_of(link, struct wl_client, link);
+}
+
+/** Add a listener for the client's resource creation signal
+ *
+ * \param client The client object
+ * \param listener The listener to be added
+ *
+ * When a new resource is created for this client the listener
+ * will be notified, carrying the new resource as the data argument.
+ *
+ * \memberof wl_client
+ */
+WL_EXPORT void
+wl_client_add_resource_created_listener(struct wl_client *client,
+ struct wl_listener *listener)
+{
+ wl_signal_add(&client->resource_created_signal, listener);
+}
+
+struct wl_resource_iterator_context {
+ void *user_data;
+ wl_client_for_each_resource_iterator_func_t it;
+};
+
+static enum wl_iterator_result
+resource_iterator_helper(void *res, void *user_data)
+{
+ struct wl_resource_iterator_context *context = user_data;
+ struct wl_resource *resource = res;
+
+ return context->it(resource, context->user_data);
+}
+
+/** Iterate over all the resources of a client
+ *
+ * \param client The client object
+ * \param iterator The iterator function
+ * \param user_data The user data pointer
+ *
+ * The function pointed by \a iterator will be called for each
+ * resource owned by the client. The \a user_data will be passed
+ * as the second argument of the iterator function.
+ * If the \a iterator function returns \a WL_ITERATOR_CONTINUE the iteration
+ * will continue, if it returns \a WL_ITERATOR_STOP it will stop.
+ *
+ * Creating and destroying resources while iterating is safe, but new
+ * resources may or may not be picked up by the iterator.
+ *
+ * \sa wl_iterator_result
+ *
+ * \memberof wl_client
+ */
+WL_EXPORT void
+wl_client_for_each_resource(struct wl_client *client,
+ wl_client_for_each_resource_iterator_func_t iterator,
+ void *user_data)
+{
+ struct wl_resource_iterator_context context = {
+ .user_data = user_data,
+ .it = iterator,
+ };
+
+ wl_map_for_each(&client->objects, resource_iterator_helper, &context);
+}
+
/** \cond */ /* Deprecated functions below. */
uint32_t
diff --git a/src/wayland-server.h b/src/wayland-server.h
index 3124703..f11fb4d 100644
--- a/src/wayland-server.h
+++ b/src/wayland-server.h
@@ -36,6 +36,7 @@
#ifndef WAYLAND_SERVER_H
#define WAYLAND_SERVER_H
+#include <stdint.h>
#include "wayland-server-core.h"
#ifdef __cplusplus
@@ -65,7 +66,6 @@ struct wl_buffer {
uint32_t busy_count;
} WL_DEPRECATED;
-
uint32_t
wl_client_add_resource(struct wl_client *client,
struct wl_resource *resource) WL_DEPRECATED;
@@ -75,6 +75,7 @@ wl_client_add_object(struct wl_client *client,
const struct wl_interface *interface,
const void *implementation,
uint32_t id, void *data) WL_DEPRECATED;
+
struct wl_resource *
wl_client_new_object(struct wl_client *client,
const struct wl_interface *interface,
diff --git a/src/wayland-shm.c b/src/wayland-shm.c
index 5efbd70..8e2ef77 100644
--- a/src/wayland-shm.c
+++ b/src/wayland-shm.c
@@ -33,6 +33,7 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
@@ -40,6 +41,7 @@
#include <signal.h>
#include <pthread.h>
+#include "wayland-util.h"
#include "wayland-private.h"
#include "wayland-server.h"
@@ -245,7 +247,7 @@ shm_pool_resize(struct wl_client *client, struct wl_resource *resource,
shm_pool_finish_resize(pool);
}
-struct wl_shm_pool_interface shm_pool_interface = {
+static const struct wl_shm_pool_interface shm_pool_interface = {
shm_pool_create_buffer,
shm_pool_destroy,
shm_pool_resize
diff --git a/src/wayland-util.c b/src/wayland-util.c
index 5bfb7e1..077fec7 100644
--- a/src/wayland-util.c
+++ b/src/wayland-util.c
@@ -33,21 +33,6 @@
#include "wayland-util.h"
#include "wayland-private.h"
-struct wl_object global_zombie_object;
-
-int
-wl_interface_equal(const struct wl_interface *a, const struct wl_interface *b)
-{
- /* In most cases the pointer equality test is sufficient.
- * However, in some cases, depending on how things are split
- * across shared objects, we can end up with multiple
- * instances of the interface metadata constants. So if the
- * pointers match, the interfaces are equal, if they don't
- * match we have to compare the interface names.
- */
- return a == b || strcmp(a->name, b->name) == 0;
-}
-
WL_EXPORT void
wl_list_init(struct wl_list *list)
{
@@ -117,6 +102,7 @@ WL_EXPORT void
wl_array_release(struct wl_array *array)
{
free(array->data);
+ array->data = WL_ARRAY_POISON_PTR;
}
WL_EXPORT void *
@@ -167,6 +153,21 @@ wl_array_copy(struct wl_array *array, struct wl_array *source)
/** \cond */
+struct wl_object global_zombie_object;
+
+int
+wl_interface_equal(const struct wl_interface *a, const struct wl_interface *b)
+{
+ /* In most cases the pointer equality test is sufficient.
+ * However, in some cases, depending on how things are split
+ * across shared objects, we can end up with multiple
+ * instances of the interface metadata constants. So if the
+ * pointers match, the interfaces are equal, if they don't
+ * match we have to compare the interface names.
+ */
+ return a == b || strcmp(a->name, b->name) == 0;
+}
+
union map_entry {
uintptr_t next;
void *data;
@@ -359,27 +360,34 @@ wl_map_lookup_flags(struct wl_map *map, uint32_t i)
return 0;
}
-static void
+static enum wl_iterator_result
for_each_helper(struct wl_array *entries, wl_iterator_func_t func, void *data)
{
union map_entry *start, *end, *p;
+ enum wl_iterator_result ret = WL_ITERATOR_CONTINUE;
start = entries->data;
end = (union map_entry *) ((char *) entries->data + entries->size);
for (p = start; p < end; p++)
- if (p->data && !map_entry_is_free(*p))
- func(map_entry_get_data(*p), data);
+ if (p->data && !map_entry_is_free(*p)) {
+ ret = func(map_entry_get_data(*p), data);
+ if (ret != WL_ITERATOR_CONTINUE)
+ break;
+ }
+
+ return ret;
}
WL_EXPORT void
wl_map_for_each(struct wl_map *map, wl_iterator_func_t func, void *data)
{
- for_each_helper(&map->client_entries, func, data);
- for_each_helper(&map->server_entries, func, data);
-}
+ enum wl_iterator_result ret;
-/** \endcond */
+ ret = for_each_helper(&map->client_entries, func, data);
+ if (ret == WL_ITERATOR_CONTINUE)
+ for_each_helper(&map->server_entries, func, data);
+}
static void
wl_log_stderr_handler(const char *fmt, va_list arg)
@@ -410,3 +418,5 @@ wl_abort(const char *fmt, ...)
abort();
}
+
+/** \endcond */
diff --git a/src/wayland-util.h b/src/wayland-util.h
index 8da156c..50f3372 100644
--- a/src/wayland-util.h
+++ b/src/wayland-util.h
@@ -40,30 +40,105 @@
extern "C" {
#endif
-/* GCC visibility */
+/** Visibility attribute */
#if defined(__GNUC__) && __GNUC__ >= 4
#define WL_EXPORT __attribute__ ((visibility("default")))
#else
#define WL_EXPORT
#endif
-/* Deprecated attribute */
+/** Deprecated attribute */
#if defined(__GNUC__) && __GNUC__ >= 4
#define WL_DEPRECATED __attribute__ ((deprecated))
#else
#define WL_DEPRECATED
#endif
-/* Printf annotation */
+/**
+ * Printf-style argument attribute
+ *
+ * \param x Ordinality of the format string argument
+ * \param y Ordinality of the argument to check against the format string
+ *
+ * \sa https://gcc.gnu.org/onlinedocs/gcc-3.2.1/gcc/Function-Attributes.html
+ */
#if defined(__GNUC__) && __GNUC__ >= 4
#define WL_PRINTF(x, y) __attribute__((__format__(__printf__, x, y)))
#else
#define WL_PRINTF(x, y)
#endif
+/**
+ * Protocol message signature
+ *
+ * A wl_message describes the signature of an actual protocol message, such as a
+ * request or event, that adheres to the Wayland protocol wire format. The
+ * protocol implementation uses a wl_message within its demarshal machinery for
+ * decoding messages between a compositor and its clients. In a sense, a
+ * wl_message is to a protocol message like a class is to an object.
+ *
+ * The `name` of a wl_message is the name of the corresponding protocol message.
+ * The `signature` is an ordered list of symbols representing the data types
+ * of message arguments and, optionally, a protocol version and indicators for
+ * nullability. A leading integer in the `signature` indicates the _since_
+ * version of the protocol message. A `?` preceding a data type symbol indicates
+ * that the following argument type is nullable. When no arguments accompany a
+ * message, `signature` is an empty string.
+ *
+ * * `i`: int
+ * * `u`: uint
+ * * `f`: fixed
+ * * `s`: string
+ * * `o`: object
+ * * `n`: new_id
+ * * `a`: array
+ * * `h`: fd
+ * * `?`: following argument is nullable
+ *
+ * While demarshaling primitive arguments is straightforward, when demarshaling
+ * messages containing `object` or `new_id` arguments, the protocol
+ * implementation often must determine the type of the object. The `types` of a
+ * wl_message is an array of wl_interface references that correspond to `o` and
+ * `n` arguments in `signature`, with `NULL` placeholders for arguments with
+ * non-object types.
+ *
+ * Consider the protocol event wl_display `delete_id` that has a single `uint`
+ * argument. The wl_message is:
+ *
+ * \code
+ * { "delete_id", "u", [NULL] }
+ * \endcode
+ *
+ * Here, the message `name` is `"delete_id"`, the `signature` is `"u"`, and the
+ * argument `types` is `[NULL]`, indicating that the `uint` argument has no
+ * corresponding wl_interface since it is a primitive argument.
+ *
+ * In contrast, consider a `wl_foo` interface supporting protocol request `bar`
+ * that has existed since version 2, and has two arguments: a `uint` and an
+ * object of type `wl_baz_interface` that may be `NULL`. Such a `wl_message`
+ * might be:
+ *
+ * \code
+ * { "bar", "2u?o", [NULL, &wl_baz_interface] }
+ * \endcode
+ *
+ * Here, the message `name` is `"bar"`, and the `signature` is `"2u?o"`. Notice
+ * how the `2` indicates the protocol version, the `u` indicates the first
+ * argument type is `uint`, and the `?o` indicates that the second argument
+ * is an object that may be `NULL`. Lastly, the argument `types` array indicates
+ * that no wl_interface corresponds to the first argument, while the type
+ * `wl_baz_interface` corresponds to the second argument.
+ *
+ * \sa wl_argument
+ * \sa wl_interface
+ * \sa <a href="https://wayland.freedesktop.org/docs/html/ch04.html#sect-Protocol-Wire-Format">Wire Format</a>
+ */
struct wl_message {
+ /** Message name */
const char *name;
+ /** Message signature */
const char *signature;
+ /** Object argument interfaces */
const struct wl_interface **types;
};
@@ -78,73 +153,150 @@ struct wl_interface {
/** \class wl_list
*
- * \brief doubly-linked list
+ * \brief Doubly-linked list
+ *
+ * On its own, an instance of `struct wl_list` represents the sentinel head of
+ * a doubly-linked list, and must be initialized using wl_list_init().
+ * When empty, the list head's `next` and `prev` members point to the list head
+ * itself, otherwise `next` references the first element in the list, and `prev`
+ * refers to the last element in the list.
+ *
+ * Use the `struct wl_list` type to represent both the list head and the links
+ * between elements within the list. Use wl_list_empty() to determine if the
+ * list is empty in O(1).
+ *
+ * All elements in the list must be of the same type. The element type must have
+ * a `struct wl_list` member, often named `link` by convention. Prior to
+ * insertion, there is no need to initialize an element's `link` - invoking
+ * wl_list_init() on an individual list element's `struct wl_list` member is
+ * unnecessary if the very next operation is wl_list_insert(). However, a
+ * common idiom is to initialize an element's `link` prior to removal - ensure
+ * safety by invoking wl_list_init() before wl_list_remove().
*
- * The list head is of "struct wl_list" type, and must be initialized
- * using wl_list_init(). All entries in the list must be of the same
- * type. The item type must have a "struct wl_list" member. This
- * member will be initialized by wl_list_insert(). There is no need to
- * call wl_list_init() on the individual item. To query if the list is
- * empty in O(1), use wl_list_empty().
+ * Consider a list reference `struct wl_list foo_list`, an element type as
+ * `struct element`, and an element's link member as `struct wl_list link`.
*
- * Let's call the list reference "struct wl_list foo_list", the item type as
- * "item_t", and the item member as "struct wl_list link".
+ * The following code initializes a list and adds three elements to it.
*
- * The following code will initialize a list:
* \code
* struct wl_list foo_list;
*
- * struct item_t {
- * int foo;
- * struct wl_list link;
+ * struct element {
+ * int foo;
+ * struct wl_list link;
* };
- * struct item_t item1, item2, item3;
+ * struct element e1, e2, e3;
*
* wl_list_init(&foo_list);
- * wl_list_insert(&foo_list, &item1.link); // Pushes item1 at the head
- * wl_list_insert(&foo_list, &item2.link); // Pushes item2 at the head
- * wl_list_insert(&item2.link, &item3.link); // Pushes item3 after item2
+ * wl_list_insert(&foo_list, &e1.link); // e1 is the first element
+ * wl_list_insert(&foo_list, &e2.link); // e2 is now the first element
+ * wl_list_insert(&e2.link, &e3.link); // insert e3 after e2
* \endcode
*
- * The list now looks like [item2, item3, item1]
+ * The list now looks like <em>[e2, e3, e1]</em>.
+ *
+ * The `wl_list` API provides some iterator macros. For example, to iterate
+ * a list in ascending order:
*
- * Iterate the list in ascending order:
* \code
- * item_t *item;
- * wl_list_for_each(item, foo_list, link) {
- * Do_something_with_item(item);
+ * struct element *e;
+ * wl_list_for_each(e, foo_list, link) {
+ * do_something_with_element(e);
* }
* \endcode
+ *
+ * See the documentation of each iterator for details.
+ * \sa http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/list.h
*/
struct wl_list {
struct wl_list *prev;
struct wl_list *next;
};
+/**
+ * Initializes the list.
+ *
+ * \param list List to initialize
+ *
+ * \memberof wl_list
+ */
void
wl_list_init(struct wl_list *list);
+/**
+ * Inserts an element into the list, after the element represented by \p list.
+ * When \p list is a reference to the list itself (the head), set the containing
+ * struct of \p elm as the first element in the list.
+ *
+ * \note If \p elm is already part of a list, inserting it again will lead to
+ * list corruption.
+ *
+ * \param list List element after which the new element is inserted
+ * \param elm Link of the containing struct to insert into the list
+ *
+ * \memberof wl_list
+ */
void
wl_list_insert(struct wl_list *list, struct wl_list *elm);
+/**
+ * Removes an element from the list.
+ *
+ * \note This operation leaves \p elm in an invalid state.
+ *
+ * \param elm Link of the containing struct to remove from the list
+ *
+ * \memberof wl_list
+ */
void
wl_list_remove(struct wl_list *elm);
+/**
+ * Determines the length of the list.
+ *
+ * \note This is an O(n) operation.
+ *
+ * \param list List whose length is to be determined
+ *
+ * \return Number of elements in the list
+ *
+ * \memberof wl_list
+ */
int
wl_list_length(const struct wl_list *list);
+/**
+ * Determines if the list is empty.
+ *
+ * \param list List whose emptiness is to be determined
+ *
+ * \return 1 if empty, or 0 if not empty
+ *
+ * \memberof wl_list
+ */
int
wl_list_empty(const struct wl_list *list);
+/**
+ * Inserts all of the elements of one list into another, after the element
+ * represented by \p list.
+ *
+ * \note This leaves \p other in an invalid state.
+ *
+ * \param list List element after which the other list elements will be inserted
+ * \param other List of elements to insert
+ *
+ * \memberof wl_list
+ */
void
wl_list_insert_list(struct wl_list *list, struct wl_list *other);
/**
- * Retrieves a pointer to the containing struct of a given member item.
+ * Retrieves a pointer to a containing struct, given a member name.
*
- * This macro allows conversion from a pointer to a item to its containing
+ * This macro allows "conversion" from a pointer to a member to its containing
* struct. This is useful if you have a contained item like a wl_list,
- * wl_listener, or wl_signal, provided via a callback or other means and would
+ * wl_listener, or wl_signal, provided via a callback or other means, and would
* like to retrieve the struct that contains it.
*
* To demonstrate, the following example retrieves a pointer to
@@ -152,41 +304,82 @@ wl_list_insert_list(struct wl_list *list, struct wl_list *other);
*
* \code
* struct example_container {
- * struct wl_listener destroy_listener;
- * // other members...
+ * struct wl_listener destroy_listener;
+ * // other members...
* };
*
* void example_container_destroy(struct wl_listener *listener, void *data)
* {
- * struct example_container *ctr;
+ * struct example_container *ctr;
*
- * ctr = wl_container_of(listener, ctr, destroy_listener);
- * // destroy ctr...
+ * ctr = wl_container_of(listener, ctr, destroy_listener);
+ * // destroy ctr...
* }
* \endcode
*
- * \param ptr A valid pointer to the contained item.
+ * \note `sample` need not be a valid pointer. A null or uninitialised pointer
+ * is sufficient.
*
- * \param sample A pointer to the type of content that the list item
- * stores. Sample does not need be a valid pointer; a null or
- * an uninitialised pointer will suffice.
+ * \param ptr Valid pointer to the contained member
+ * \param sample Pointer to a struct whose type contains \p ptr
+ * \param member Named location of \p ptr within the \p sample type
*
- * \param member The named location of ptr within the sample type.
- *
- * \return The container for the specified pointer.
+ * \return The container for the specified pointer
*/
#define wl_container_of(ptr, sample, member) \
(__typeof__(sample))((char *)(ptr) - \
offsetof(__typeof__(*sample), member))
-/* If the above macro causes problems on your compiler you might be
- * able to find an alternative name for the non-standard __typeof__
- * operator and add a special case here */
+/**
+ * Iterates over a list.
+ *
+ * This macro expresses a for-each iterator for wl_list. Given a list and
+ * wl_list link member name (often named `link` by convention), this macro
+ * assigns each element in the list to \p pos, which can then be referenced in
+ * a trailing code block. For example, given a wl_list of `struct message`
+ * elements:
+ *
+ * \code
+ * struct message {
+ * char *contents;
+ * wl_list link;
+ * };
+ *
+ * struct wl_list *message_list;
+ * // Assume message_list now "contains" many messages
+ *
+ * struct message *m;
+ * wl_list_for_each(m, message_list, link) {
+ * do_something_with_message(m);
+ * }
+ * \endcode
+ *
+ * \param pos Cursor that each list element will be assigned to
+ * \param head Head of the list to iterate over
+ * \param member Name of the link member within the element struct
+ *
+ * \relates wl_list
+ */
#define wl_list_for_each(pos, head, member) \
for (pos = wl_container_of((head)->next, pos, member); \
&pos->member != (head); \
pos = wl_container_of(pos->member.next, pos, member))
+/**
+ * Iterates over a list, safe against removal of the list element.
+ *
+ * \note Only removal of the current element, \p pos, is safe. Removing
+ * any other element during traversal may lead to a loop malfunction.
+ *
+ * \sa wl_list_for_each()
+ *
+ * \param pos Cursor that each list element will be assigned to
+ * \param tmp Temporary pointer of the same type as \p pos
+ * \param head Head of the list to iterate over
+ * \param member Name of the link member within the element struct
+ *
+ * \relates wl_list
+ */
#define wl_list_for_each_safe(pos, tmp, head, member) \
for (pos = wl_container_of((head)->next, pos, member), \
tmp = wl_container_of((pos)->member.next, tmp, member); \
@@ -194,11 +387,37 @@ wl_list_insert_list(struct wl_list *list, struct wl_list *other);
pos = tmp, \
tmp = wl_container_of(pos->member.next, tmp, member))
+/**
+ * Iterates backwards over a list.
+ *
+ * \sa wl_list_for_each()
+ *
+ * \param pos Cursor that each list element will be assigned to
+ * \param head Head of the list to iterate over
+ * \param member Name of the link member within the element struct
+ *
+ * \relates wl_list
+ */
#define wl_list_for_each_reverse(pos, head, member) \
for (pos = wl_container_of((head)->prev, pos, member); \
&pos->member != (head); \
pos = wl_container_of(pos->member.prev, pos, member))
+/**
+ * Iterates backwards over a list, safe against removal of the list element.
+ *
+ * \note Only removal of the current element, \p pos, is safe. Removing
+ * any other element during traversal may lead to a loop malfunction.
+ *
+ * \sa wl_list_for_each()
+ *
+ * \param pos Cursor that each list element will be assigned to
+ * \param tmp Temporary pointer of the same type as \p pos
+ * \param head Head of the list to iterate over
+ * \param member Name of the link member within the element struct
+ *
+ * \relates wl_list
+ */
#define wl_list_for_each_reverse_safe(pos, tmp, head, member) \
for (pos = wl_container_of((head)->prev, pos, member), \
tmp = wl_container_of((pos)->member.prev, tmp, member); \
@@ -206,33 +425,111 @@ wl_list_insert_list(struct wl_list *list, struct wl_list *other);
pos = tmp, \
tmp = wl_container_of(pos->member.prev, tmp, member))
+/**
+ * \class wl_array
+ *
+ * Dynamic array
+ *
+ * A wl_array is a dynamic array that can only grow until released. It is
+ * intended for relatively small allocations whose size is variable or not known
+ * in advance. While construction of a wl_array does not require all elements to
+ * be of the same size, wl_array_for_each() does require all elements to have
+ * the same type and size.
+ *
+ */
struct wl_array {
size_t size;
size_t alloc;
void *data;
};
-#define wl_array_for_each(pos, array) \
- for (pos = (array)->data; \
- (const char *) pos < ((const char *) (array)->data + (array)->size); \
- (pos)++)
-
+/**
+ * Initializes the array.
+ *
+ * \param array Array to initialize
+ *
+ * \memberof wl_array
+ */
void
wl_array_init(struct wl_array *array);
+/**
+ * Releases the array data.
+ *
+ * \note Leaves the array in an invalid state.
+ *
+ * \param array Array whose data is to be released
+ *
+ * \memberof wl_array
+ */
void
wl_array_release(struct wl_array *array);
+/**
+ * Increases the size of the array by \p size bytes.
+ *
+ * \param array Array whose size is to be increased
+ * \param size Number of bytes to increase the size of the array by
+ *
+ * \return A pointer to the beginning of the newly appended space, or NULL when
+ * resizing fails.
+ *
+ * \memberof wl_array
+ */
void *
wl_array_add(struct wl_array *array, size_t size);
+/**
+ * Copies the contents of \p source to \p array.
+ *
+ * \param array Destination array to copy to
+ * \param source Source array to copy from
+ *
+ * \return 0 on success, or -1 on failure
+ *
+ * \memberof wl_array
+ */
int
wl_array_copy(struct wl_array *array, struct wl_array *source);
+/**
+ * Iterates over an array.
+ *
+ * This macro expresses a for-each iterator for wl_array. It assigns each
+ * element in the array to \p pos, which can then be referenced in a trailing
+ * code block. \p pos must be a pointer to the array element type, and all
+ * array elements must be of the same type and size.
+ *
+ * \param pos Cursor that each array element will be assigned to
+ * \param array Array to iterate over
+ *
+ * \relates wl_array
+ * \sa wl_list_for_each()
+ */
+#define wl_array_for_each(pos, array) \
+ for (pos = (array)->data; \
+ (const char *) pos < ((const char *) (array)->data + (array)->size); \
+ (pos)++)
+
+/**
+ * Fixed-point number
+ *
+ * A `wl_fixed_t` is a 24.8 signed fixed-point number with a sign bit, 23 bits
+ * of integer precision and 8 bits of decimal precision. Consider `wl_fixed_t`
+ * as an opaque struct with methods that facilitate conversion to and from
+ * `double` and `int` types.
+ */
typedef int32_t wl_fixed_t;
+/**
+ * Converts a fixed-point number to a floating-point number.
+ *
+ * \param f Fixed-point number to convert
+ *
+ * \return Floating-point representation of the fixed-point argument
+ */
static inline double
-wl_fixed_to_double (wl_fixed_t f)
+wl_fixed_to_double(wl_fixed_t f)
{
union {
double d;
@@ -244,6 +541,13 @@ wl_fixed_to_double (wl_fixed_t f)
return u.d - (3LL << 43);
}
+/**
+ * Converts a floating-point number to a fixed-point number.
+ *
+ * \param d Floating-point number to convert
+ *
+ * \return Fixed-point representation of the floating-point argument
+ */
static inline wl_fixed_t
wl_fixed_from_double(double d)
{
@@ -257,12 +561,26 @@ wl_fixed_from_double(double d)
return u.i;
}
+/**
+ * Converts a fixed-point number to an integer.
+ *
+ * \param f Fixed-point number to convert
+ *
+ * \return Integer component of the fixed-point argument
+ */
static inline int
wl_fixed_to_int(wl_fixed_t f)
{
return f / 256;
}
+/**
+ * Converts an integer to a fixed-point number.
+ *
+ * \param i Integer to convert
+ *
+ * \return Fixed-point representation of the integer argument
+ */
static inline wl_fixed_t
wl_fixed_from_int(int i)
{
@@ -311,6 +629,17 @@ typedef int (*wl_dispatcher_func_t)(const void *, void *, uint32_t,
typedef void (*wl_log_func_t)(const char *, va_list) WL_PRINTF(1, 0);
+/** \enum wl_iterator_result
+ *
+ * This enum represents the return value of an iterator function.
+ */
+enum wl_iterator_result {
+ /** Stop the iteration */
+ WL_ITERATOR_STOP,
+ /** Continue the iteration */
+ WL_ITERATOR_CONTINUE
+};
+
#ifdef __cplusplus
}
#endif
diff --git a/tests/array-test.c b/tests/array-test.c
index fe53240..eda610b 100644
--- a/tests/array-test.c
+++ b/tests/array-test.c
@@ -25,24 +25,36 @@
#include <stdlib.h>
#include <assert.h>
+#include <string.h>
+#include "wayland-util.h"
#include "wayland-private.h"
#include "test-runner.h"
TEST(array_init)
{
- const int iterations = 4122; /* this is arbitrary */
- int i;
+ struct wl_array array;
- /* Init array an arbitray amount of times and verify the
- * defaults are sensible. */
+ /* fill with garbage to emulate uninitialized memory */
+ memset(&array, 0x57, sizeof array);
- for (i = 0; i < iterations; i++) {
- struct wl_array array;
- wl_array_init(&array);
- assert(array.size == 0);
- assert(array.alloc == 0);
- assert(array.data == 0);
- }
+ wl_array_init(&array);
+ assert(array.size == 0);
+ assert(array.alloc == 0);
+ assert(array.data == 0);
+}
+
+TEST(array_release)
+{
+ struct wl_array array;
+ void *ptr;
+
+ wl_array_init(&array);
+ ptr = wl_array_add(&array, 1);
+ assert(ptr != NULL);
+ assert(array.data != NULL);
+
+ wl_array_release(&array);
+ assert(array.data == WL_ARRAY_POISON_PTR);
}
TEST(array_add)
diff --git a/tests/compositor-introspection-test.c b/tests/compositor-introspection-test.c
new file mode 100644
index 0000000..83194ce
--- /dev/null
+++ b/tests/compositor-introspection-test.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright © 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.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.
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "wayland-client.h"
+#include "wayland-server.h"
+#include "test-runner.h"
+
+/* Ensure the connection doesn't fail due to lack of XDG_RUNTIME_DIR. */
+static const char *
+require_xdg_runtime_dir(void)
+{
+ char *val = getenv("XDG_RUNTIME_DIR");
+ assert(val && "set $XDG_RUNTIME_DIR to run this test");
+
+ return val;
+}
+
+struct compositor {
+ struct wl_display *display;
+ struct wl_listener listener;
+ struct wl_client *client;
+};
+
+static void
+client_created(struct wl_listener *listener, void *data)
+{
+ struct compositor *c = wl_container_of(listener, c, listener);
+ c->client = data;
+}
+
+static void
+check_client_list(struct compositor *compositor)
+{
+ struct wl_list *client_list;
+ struct wl_client *client, *client_it;
+ int num_clients = 0;
+
+ client_list = wl_display_get_client_list(compositor->display);
+ wl_client_for_each(client_it, client_list) {
+ num_clients++;
+ client = client_it;
+ }
+ assert(num_clients == 1);
+ /* 'client_it' is not valid here, so we took a copy of the client in the loop.
+ * We could also do this assert in the loop directly, but in case it fails it is
+ * easier to understand the problem when we know that the previous assert passed,
+ * so that there is only one client but the wrong one. */
+ assert(compositor->client == client);
+}
+
+static const char *
+setup_compositor(struct compositor *compositor)
+{
+ const char *socket;
+
+ require_xdg_runtime_dir();
+
+ compositor->display = wl_display_create();
+ socket = wl_display_add_socket_auto(compositor->display);
+
+ compositor->listener.notify = client_created;
+ wl_display_add_client_created_listener(compositor->display, &compositor->listener);
+
+ return socket;
+}
+
+static void
+cleanup_compositor(struct compositor *compositor)
+{
+ wl_client_destroy(compositor->client);
+ wl_display_destroy(compositor->display);
+}
+
+TEST(new_client_connect)
+{
+ const char *socket;
+ struct compositor compositor = { 0 };
+ struct {
+ struct wl_display *display;
+ } client;
+
+ socket = setup_compositor(&compositor);
+
+ client.display = wl_display_connect(socket);
+
+ wl_event_loop_dispatch(wl_display_get_event_loop(compositor.display), 100);
+
+ assert(compositor.client != NULL);
+
+ check_client_list(&compositor);
+
+
+
+ wl_display_disconnect(client.display);
+ cleanup_compositor(&compositor);
+}
+
+struct resource_listener {
+ struct wl_listener listener;
+ int count;
+};
+
+static void
+resource_created(struct wl_listener *listener, void *data)
+{
+ struct resource_listener *l;
+ l = wl_container_of(listener, l, listener);
+ l->count++;
+}
+
+TEST(new_resource)
+{
+ const char *socket;
+ struct compositor compositor = { 0 };
+ struct {
+ struct wl_display *display;
+ struct wl_callback *cb;
+ } client;
+ struct resource_listener resource_listener;
+
+ socket = setup_compositor(&compositor);
+ client.display = wl_display_connect(socket);
+ wl_event_loop_dispatch(wl_display_get_event_loop(compositor.display), 100);
+
+ resource_listener.count = 0;
+ resource_listener.listener.notify = resource_created;
+ wl_client_add_resource_created_listener(compositor.client,
+ &resource_listener.listener);
+
+ client.cb = wl_display_sync(client.display);
+ wl_display_flush(client.display);
+ wl_event_loop_dispatch(wl_display_get_event_loop(compositor.display), 100);
+
+ assert(resource_listener.count == 1);
+
+ wl_callback_destroy(client.cb);
+ wl_display_disconnect(client.display);
+ cleanup_compositor(&compositor);
+
+ /* This is defined to be safe also after client destruction */
+ wl_list_remove(&resource_listener.listener.link);
+}
diff --git a/tests/connection-test.c b/tests/connection-test.c
index 5d97fd9..3e34f77 100644
--- a/tests/connection-test.c
+++ b/tests/connection-test.c
@@ -27,6 +27,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
+#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <sys/socket.h>
diff --git a/tests/display-test.c b/tests/display-test.c
index 17956db..0c4df16 100644
--- a/tests/display-test.c
+++ b/tests/display-test.c
@@ -28,6 +28,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
+#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <sys/socket.h>
@@ -37,7 +38,6 @@
#include <sys/stat.h>
#include <pthread.h>
#include <poll.h>
-#include <stdbool.h>
#include "wayland-private.h"
#include "wayland-server.h"
diff --git a/tests/event-loop-test.c b/tests/event-loop-test.c
index ae5ff94..33566b4 100644
--- a/tests/event-loop-test.c
+++ b/tests/event-loop-test.c
@@ -25,6 +25,7 @@
*/
#include <stdlib.h>
+#include <stdint.h>
#include <assert.h>
#include <unistd.h>
#include <signal.h>
diff --git a/tests/exec-fd-leak-checker.c b/tests/exec-fd-leak-checker.c
index 0c69da3..5f3b395 100644
--- a/tests/exec-fd-leak-checker.c
+++ b/tests/exec-fd-leak-checker.c
@@ -37,7 +37,7 @@ parse_count(const char *str, int *value)
long v;
errno = 0;
- v = strtol(str, &end, 0);
+ v = strtol(str, &end, 10);
if ((errno == ERANGE && (v == LONG_MAX || v == LONG_MIN)) ||
(errno != 0 && v == 0) ||
(end == str) ||
diff --git a/tests/list-test.c b/tests/list-test.c
index 21ca4ec..0752618 100644
--- a/tests/list-test.c
+++ b/tests/list-test.c
@@ -57,6 +57,19 @@ TEST(list_insert)
assert(e.link.prev == &list);
}
+TEST(list_length)
+{
+ struct wl_list list;
+ struct element e;
+
+ wl_list_init(&list);
+ assert(wl_list_length(&list) == 0);
+ wl_list_insert(&list, &e.link);
+ assert(wl_list_length(&list) == 1);
+ wl_list_remove(&e.link);
+ assert(wl_list_length(&list) == 0);
+}
+
TEST(list_iterator)
{
struct wl_list list;
diff --git a/tests/map-test.c b/tests/map-test.c
index d259048..8ecc1aa 100644
--- a/tests/map-test.c
+++ b/tests/map-test.c
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
#include <assert.h>
#include "wayland-private.h"
#include "test-runner.h"
diff --git a/tests/message-test.c b/tests/message-test.c
index cb08f90..389f788 100644
--- a/tests/message-test.c
+++ b/tests/message-test.c
@@ -51,3 +51,40 @@ TEST(message_version)
messages[i].expected_version);
}
}
+
+TEST(message_count_arrays)
+{
+ unsigned int i;
+ struct wl_message fake_messages[] = {
+ { "empty", "", NULL },
+ { "non_present", "iufsonh", NULL },
+ { "leading", "aiufsonh", NULL},
+ { "trailing", "iufsonha", NULL },
+ { "middle", "iufasonh", NULL },
+ { "multiple", "aaiufaasonhaa", NULL },
+ { "leading_version", "2aaiufaasonhaa", NULL },
+ { "among_nullables", "iufsa?oa?nah", NULL },
+ { "all_mixed", "2aiufas?oa?na", NULL },
+ };
+ const struct {
+ const struct wl_message *message;
+ int expected_array_count;
+ } messages[] = {
+ { &wl_pointer_interface.events[WL_POINTER_ENTER], 0 },
+ { &wl_keyboard_interface.events[WL_KEYBOARD_ENTER], 1 },
+ { &fake_messages[0], 0 },
+ { &fake_messages[1], 0 },
+ { &fake_messages[2], 1 },
+ { &fake_messages[3], 1 },
+ { &fake_messages[4], 1 },
+ { &fake_messages[5], 6 },
+ { &fake_messages[6], 6 },
+ { &fake_messages[7], 3 },
+ { &fake_messages[8], 4 }
+ };
+
+ for (i = 0; i < ARRAY_LENGTH(messages); ++i) {
+ assert(wl_message_count_arrays(messages[i].message) ==
+ messages[i].expected_array_count);
+ }
+}
diff --git a/tests/os-wrappers-test.c b/tests/os-wrappers-test.c
index b636b62..102622c 100644
--- a/tests/os-wrappers-test.c
+++ b/tests/os-wrappers-test.c
@@ -27,6 +27,7 @@
#define _GNU_SOURCE
#include <stdlib.h>
+#include <stdint.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/tests/protocol-logger-test.c b/tests/protocol-logger-test.c
new file mode 100644
index 0000000..80c74aa
--- /dev/null
+++ b/tests/protocol-logger-test.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright © 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.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.
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "wayland-client.h"
+#include "wayland-server.h"
+#include "test-runner.h"
+
+/* Ensure the connection doesn't fail due to lack of XDG_RUNTIME_DIR. */
+static const char *
+require_xdg_runtime_dir(void)
+{
+ char *val = getenv("XDG_RUNTIME_DIR");
+ assert(val && "set $XDG_RUNTIME_DIR to run this test");
+
+ return val;
+}
+
+struct compositor {
+ struct wl_display *display;
+ struct wl_event_loop *loop;
+ int message;
+ struct wl_client *client;
+};
+
+struct message {
+ enum wl_protocol_logger_type type;
+ const char *class;
+ int opcode;
+ const char *message_name;
+ int args_count;
+} messages[] = {
+ {
+ .type = WL_PROTOCOL_LOGGER_REQUEST,
+ .class = "wl_display",
+ .opcode = 0,
+ .message_name = "sync",
+ .args_count = 1,
+ },
+ {
+ .type = WL_PROTOCOL_LOGGER_EVENT,
+ .class = "wl_callback",
+ .opcode = 0,
+ .message_name = "done",
+ .args_count = 1,
+ },
+ {
+ .type = WL_PROTOCOL_LOGGER_EVENT,
+ .class = "wl_display",
+ .opcode = 1,
+ .message_name = "delete_id",
+ .args_count = 1,
+ },
+};
+
+static void
+logger_func(void *user_data, enum wl_protocol_logger_type type,
+ const struct wl_protocol_logger_message *message)
+{
+ struct compositor *c = user_data;
+ struct message *msg = &messages[c->message++];
+
+ assert(msg->type == type);
+ assert(strcmp(msg->class, wl_resource_get_class(message->resource)) == 0);
+ assert(msg->opcode == message->message_opcode);
+ assert(strcmp(msg->message_name, message->message->name) == 0);
+ assert(msg->args_count == message->arguments_count);
+
+ c->client = wl_resource_get_client(message->resource);
+}
+
+static void
+callback_done(void *data, struct wl_callback *cb, uint32_t time)
+{
+ wl_callback_destroy(cb);
+}
+
+static const struct wl_callback_listener callback_listener = {
+ callback_done,
+};
+
+TEST(logger)
+{
+ test_set_timeout(1);
+
+ const char *socket;
+ struct compositor compositor = { 0 };
+ struct {
+ struct wl_display *display;
+ struct wl_callback *cb;
+ } client;
+ struct wl_protocol_logger *logger;
+
+ require_xdg_runtime_dir();
+
+ compositor.display = wl_display_create();
+ compositor.loop = wl_display_get_event_loop(compositor.display);
+ socket = wl_display_add_socket_auto(compositor.display);
+
+ logger = wl_display_add_protocol_logger(compositor.display,
+ logger_func, &compositor);
+
+ client.display = wl_display_connect(socket);
+ client.cb = wl_display_sync(client.display);
+ wl_callback_add_listener(client.cb, &callback_listener, NULL);
+ wl_display_flush(client.display);
+
+ while (compositor.message < 3) {
+ wl_event_loop_dispatch(compositor.loop, -1);
+ wl_display_flush_clients(compositor.display);
+ }
+
+ wl_display_dispatch(client.display);
+ wl_display_disconnect(client.display);
+
+ wl_client_destroy(compositor.client);
+ wl_protocol_logger_destroy(logger);
+ wl_display_destroy(compositor.display);
+}
diff --git a/tests/queue-test.c b/tests/queue-test.c
index 932bc55..86a3602 100644
--- a/tests/queue-test.c
+++ b/tests/queue-test.c
@@ -24,6 +24,7 @@
*/
#include <stdlib.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
diff --git a/tests/resources-test.c b/tests/resources-test.c
index 337f9f9..59d8beb 100644
--- a/tests/resources-test.c
+++ b/tests/resources-test.c
@@ -26,6 +26,7 @@
#include <assert.h>
#include <sys/socket.h>
#include <unistd.h>
+#include <stdint.h>
#include "wayland-server.h"
#include "test-runner.h"
diff --git a/tests/test-compositor.c b/tests/test-compositor.c
index b01e8af..0631f61 100644
--- a/tests/test-compositor.c
+++ b/tests/test-compositor.c
@@ -28,6 +28,7 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <stdint.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
diff --git a/tests/test-compositor.h b/tests/test-compositor.h
index 526e912..876d0c0 100644
--- a/tests/test-compositor.h
+++ b/tests/test-compositor.h
@@ -23,6 +23,7 @@
* SOFTWARE.
*/
+#include <stdint.h>
#include <unistd.h>
#include "wayland-server.h"
diff --git a/tests/test-runner.c b/tests/test-runner.c
index 4aa6667..82a0a7b 100644
--- a/tests/test-runner.c
+++ b/tests/test-runner.c
@@ -226,10 +226,11 @@ set_xdg_runtime_dir(void)
xrd_env = getenv("XDG_RUNTIME_DIR");
/* if XDG_RUNTIME_DIR is not set in environ, fallback to /tmp */
- assert((snprintf(xdg_runtime_dir, PATH_MAX, "%s/wayland-tests",
+ assert((snprintf(xdg_runtime_dir, PATH_MAX, "%s/wayland-tests-XXXXXX",
xrd_env ? xrd_env : "/tmp") < PATH_MAX)
&& "test error: XDG_RUNTIME_DIR too long");
+ assert(mkdtemp(xdg_runtime_dir) && "test error: mkdtemp failed");
if (mkdir(xdg_runtime_dir, 0700) == -1)
if (errno != EEXIST) {
perror("Creating XDG_RUNTIME_DIR");