aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am5
-rw-r--r--configure.ac20
-rw-r--r--doc/Contributing19
-rw-r--r--doc/doxygen/Makefile.am28
-rw-r--r--doc/doxygen/mainpage.dox22
-rw-r--r--doc/doxygen/wayland.doxygen.in6
-rw-r--r--doc/publican/protocol-to-docbook.xsl39
-rw-r--r--doc/publican/sources/Architecture.xml4
-rw-r--r--doc/publican/sources/Protocol.xml4
-rw-r--r--protocol/wayland.xml349
-rw-r--r--src/connection.c16
-rw-r--r--src/dtddata.S8
-rw-r--r--src/scanner.c340
-rw-r--r--src/wayland-client-core.h6
-rw-r--r--src/wayland-client.c172
-rw-r--r--src/wayland-client.h7
-rw-r--r--src/wayland-private.h12
-rw-r--r--src/wayland-server-core.h8
-rw-r--r--src/wayland-server.c16
-rw-r--r--src/wayland-server.h9
-rw-r--r--src/wayland-shm.c101
-rw-r--r--src/wayland-util.c17
-rw-r--r--src/wayland-util.h10
-rw-r--r--tests/display-test.c54
-rw-r--r--tests/headers-protocol-core-test.c7
-rw-r--r--tests/queue-test.c122
-rw-r--r--tests/resources-test.c10
-rw-r--r--tests/test-runner.c2
28 files changed, 1008 insertions, 405 deletions
diff --git a/Makefile.am b/Makefile.am
index e850abc..49e25a6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,11 +23,14 @@ pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA =
bin_PROGRAMS = wayland-scanner
-wayland_scanner_SOURCES = src/scanner.c src/dtddata.S
+wayland_scanner_SOURCES = src/scanner.c
wayland_scanner_CFLAGS = $(EXPAT_CFLAGS) $(LIBXML_CFLAGS) $(AM_CFLAGS)
wayland_scanner_LDADD = $(EXPAT_LIBS) $(LIBXML_LIBS) libwayland-util.la
pkgconfig_DATA += src/wayland-scanner.pc
+if DTD_VALIDATION
+wayland_scanner_SOURCES += src/dtddata.S
+endif
src/dtddata.o: protocol/wayland.dtd
if USE_HOST_SCANNER
diff --git a/configure.ac b/configure.ac
index 2469cdb..cf96529 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], [9])
-m4_define([wayland_micro_version], [91])
+m4_define([wayland_minor_version], [11])
+m4_define([wayland_micro_version], [0])
m4_define([wayland_version],
[wayland_major_version.wayland_minor_version.wayland_micro_version])
@@ -47,8 +47,17 @@ LT_INIT
PKG_PROG_PKG_CONFIG()
+AC_ARG_ENABLE([fatal-warnings],
+ AC_HELP_STRING([--enable-fatal-warnings],
+ [Build with -Werror]),
+ [enable_fatal_warnings=$enableval],
+ [enable_fatal_warnings=no])
+AS_IF([test x"$enable_fatal_warnings" != "xno"], [
+ WERROR_CFLAGS="-Werror"
+])
+
if test "x$GCC" = "xyes"; then
- GCC_CFLAGS="-Wall -Wextra -Wno-unused-parameter -g -Wstrict-prototypes -Wmissing-prototypes -fvisibility=hidden"
+ GCC_CFLAGS="$WERROR_CFLAGS -Wall -Wextra -Wno-unused-parameter -g -Wstrict-prototypes -Wmissing-prototypes -fvisibility=hidden"
fi
AC_SUBST(GCC_CFLAGS)
@@ -76,7 +85,7 @@ AC_ARG_ENABLE([dtd-validation],
[AC_HELP_STRING([--disable-dtd-validation],
[Disable DTD validation of the protocol])],
[],
- [enable_dtdvalidation=yes])
+ [enable_dtd_validation=yes])
AM_CONDITIONAL(USE_HOST_SCANNER, test "x$with_host_scanner" = xyes)
@@ -112,7 +121,8 @@ PKG_CHECK_MODULES(EXPAT, [expat], [],
AC_SUBST(EXPAT_LIBS)
])
-if test "x$enable_dtdvalidation" = "xyes"; then
+AM_CONDITIONAL([DTD_VALIDATION], [test "x$enable_dtd_validation" = "xyes"])
+if test "x$enable_dtd_validation" = "xyes"; then
PKG_CHECK_MODULES(LIBXML, [libxml-2.0])
AC_DEFINE(HAVE_LIBXML, 1, [libxml-2.0 is available])
AC_CONFIG_LINKS([src/wayland.dtd.embed:protocol/wayland.dtd])
diff --git a/doc/Contributing b/doc/Contributing
index fe90614..c790a07 100644
--- a/doc/Contributing
+++ b/doc/Contributing
@@ -22,14 +22,23 @@ The body of the commit message should describe what the patch changes
and why, and also note any particular side effects. This shouldn't be
empty on most of the cases. It shouldn't take a lot of effort to write
a commit message for an obvious change, so an empty commit message
-body is only acceptable if the questions "What?" and "Why" are already
+body is only acceptable if the questions "What?" and "Why?" are already
answered on the one-line summary.
The lines of the commit message should have at most 76 characters, to
cope with the way git log presents them.
-See [2] for a recommend reading on writing commit messages.
+See [2] for a recommended reading on writing commit messages.
+Your patches should also include a Signed-off-by line with your name and
+email address. If you're not the patch's original author, you should
+also gather S-o-b's by them (and/or whomever gave the patch to you.) The
+significance of this is that it certifies that you created the patch,
+that it was created under an appropriate open source license, or
+provided to you under those terms. This lets us indicate a chain of
+responsibility for the copyright status of the code.
+
+We won't reject patches that lack S-o-b, but it is strongly recommended.
== Tracking patches and following up ==
@@ -113,7 +122,7 @@ try to follow the rules below.
- indent with tabs, and a tab is always 8 characters wide
- opening braces are on the same line as the if statement;
- no braces in an if-body with just one statement;
-- if one of the branches of an if-else codition has braces, than the
+- if one of the branches of an if-else condition has braces, then the
other branch should also have braces;
- there is always an empty line between variable declarations and the
code;
@@ -138,7 +147,7 @@ my_function(void)
- lines should be less than 80 characters wide;
- when breaking lines with functions calls, the parameters are aligned
- with the opening parenthesis;
+ with the opening parentheses;
- when assigning a variable with the result of a function call, if the
line would be longer we break it around the equal '=' sign if it makes
sense;
@@ -157,7 +166,7 @@ Originally, X.org was covered under the MIT X11 license, but changed to
the MIT Expat license. Similarly, Wayland was covered initially as MIT
X11 licensed, but changed to the MIT Expat license, following in X.org's
footsteps. Other than wording, the two licenses are substantially the
-same, with the exeption of a no-advertising clause in X11 not included
+same, with the exception of a no-advertising clause in X11 not included
in Expat.
New source code files should specify the MIT Expat license in their
diff --git a/doc/doxygen/Makefile.am b/doc/doxygen/Makefile.am
index a8bb95f..c377353 100644
--- a/doc/doxygen/Makefile.am
+++ b/doc/doxygen/Makefile.am
@@ -1,7 +1,11 @@
.SUFFIXES = .gv .png .map
-noinst_DATA = xml/Client/index.xml xml/Server/index.xml
+noinst_DATA = \
+ xml/Client/index.xml \
+ xml/Server/index.xml \
+ html/Client/index.html \
+ html/Server/index.html
dist_noinst_DATA = wayland.doxygen.in
scanned_src_files_shared = \
@@ -27,6 +31,17 @@ scanned_src_files_man = \
$(top_srcdir)/src/wayland-client.h \
$(top_srcdir)/src/wayland-client-core.h
+extra_doxygen = \
+ mainpage.dox
+
+extra_doxygen_Server = \
+ $(top_builddir)/protocol/wayland-server-protocol.h \
+ $(extra_doxygen)
+
+extra_doxygen_Client = \
+ $(top_builddir)/protocol/wayland-client-protocol.h \
+ $(extra_doxygen)
+
diagramsdir := $(srcdir)/dot
diagramssrc := $(wildcard $(diagramsdir)/*.gv)
diagrams := $(patsubst $(diagramsdir)/%,xml/%,$(diagramssrc:.gv=.png))
@@ -38,7 +53,7 @@ diagram_maps := $(patsubst $(diagramsdir)/%,xml/%,$(diagramssrc:.gv=.map))
dist_man3_MANS = $(shell test -d man && find man/man3 -name "wl_*.3" -printf "man/man3/%P\n")
# Listing various directories that might need to be created.
-alldirs := xml xml/Client xml/Server man/man3
+alldirs := xml xml/Client xml/Server man/man3 html/Client html/Server
$(diagrams): $(diagramssrc)
@@ -51,6 +66,14 @@ xml/%/index.xml: $(top_srcdir)/src/scanner.c $(scanned_src_files_%) wayland.doxy
echo "INPUT= $(scanned_src_files_$*)"; \
) | $(DOXYGEN) -
+html/%/index.html: $(scanned_src_files_%) wayland.doxygen $(diagrams) $(diagram_maps) | html/%
+ $(AM_V_GEN)(cat wayland.doxygen; \
+ echo "PROJECT_NAME=\"Wayland $* API\""; \
+ echo "GENERATE_HTML=YES"; \
+ echo "HTML_OUTPUT=html/$*"; \
+ echo "INPUT= $(scanned_src_files_$*) $(extra_doxygen_$*)"; \
+ ) | $(DOXYGEN) -
+
man/man3/wl_display.3: $(top_srcdir)/src/scanner.c $(scanned_src_files_man) wayland.doxygen | man/man3
$(AM_V_GEN)(cat wayland.doxygen; \
echo "GENERATE_MAN=YES"; \
@@ -74,6 +97,7 @@ all-local: man/man3/wl_display.3
clean-local:
rm -rf xml/
+ rm -rf html/
rm -rf man/
EXTRA_DIST = $(diagramssrc)
diff --git a/doc/doxygen/mainpage.dox b/doc/doxygen/mainpage.dox
new file mode 100644
index 0000000..ca1da53
--- /dev/null
+++ b/doc/doxygen/mainpage.dox
@@ -0,0 +1,22 @@
+/**
+ * @mainpage
+ * Wayland protocol API documentation.
+ *
+ * This documentation is available for the Server- and the Client-side APIs.
+ *
+ * - <a href="../Server/index.html">Server-side API</a>
+ * - <a href="../Client/index.html">Client-side API</a>
+ *
+ * Further documentation about the architecture and principles of Wayland is
+ * available in the
+ * <a href="https://wayland.freedesktop.org/docs/html">Wayland Book</a>
+ *
+ * @section ifaces Interfaces
+ * For the list of available interfaces, please see the
+ * <a href="modules.html">modules</a> list.
+ *
+ * @section protocols Protocols
+ * For the list of protocols, please see the
+ * <a href="pages.html">Related Pages</a>.
+ *
+ */
diff --git a/doc/doxygen/wayland.doxygen.in b/doc/doxygen/wayland.doxygen.in
index fb76b12..9d7fa0c 100644
--- a/doc/doxygen/wayland.doxygen.in
+++ b/doc/doxygen/wayland.doxygen.in
@@ -13,4 +13,10 @@ MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
DOT_MULTI_TARGETS = YES
ALIASES += comment{1}="/* \1 *<!-- -->/"
+OPTIMIZE_OUTPUT_FOR_C = YES
+EXTRACT_ALL = YES
+EXTRACT_STATIC = YES
+# These must be set in the Makefile
GENERATE_HTML = NO
+GENERATE_XML = NO
+GENERATE_MAN = NO
diff --git a/doc/publican/protocol-to-docbook.xsl b/doc/publican/protocol-to-docbook.xsl
index fad207a..210e0db 100644
--- a/doc/publican/protocol-to-docbook.xsl
+++ b/doc/publican/protocol-to-docbook.xsl
@@ -102,12 +102,6 @@
<term><xsl:value-of select="@name"/></term>
<listitem>
<simpara>
- <xsl:if test="@enum">
- <link linkend="protocol-spec-{../../@name}-enum-{@enum}">
- <xsl:value-of select="@enum"/>
- </link>
- <xsl:text> </xsl:text>
- </xsl:if>
<xsl:value-of select="@type"/>
<xsl:if test="@summary" >
- <xsl:value-of select="@summary"/>
@@ -152,6 +146,37 @@
</varlistentry>
</xsl:template>
+<!-- enum and bitfield arguemnts -->
+<xsl:template match="arg[@enum]">
+ <varlistentry>
+ <term><xsl:value-of select="@name"/></term>
+ <listitem>
+ <simpara>
+ <xsl:choose>
+ <xsl:when test="contains(@enum, '.')">
+ <link linkend="protocol-spec-{substring-before(@enum, '.')}-enum-{substring-after(@enum, '.')}">
+ <xsl:value-of select="substring-before(@enum, '.')"/>
+ <xsl:text>::</xsl:text>
+ <xsl:value-of select="substring-after(@enum, '.')"/>
+ </link>
+ </xsl:when>
+ <xsl:otherwise>
+ <link linkend="protocol-spec-{../../@name}-enum-{@enum}">
+ <xsl:value-of select="../../@name"/>
+ <xsl:text>::</xsl:text>
+ <xsl:value-of select="@enum"/>
+ </link>
+ </xsl:otherwise>
+ </xsl:choose>
+ (<xsl:value-of select="@type"/>)
+ <xsl:if test="@summary" >
+ - <xsl:value-of select="@summary"/>
+ </xsl:if>
+ </simpara>
+ </listitem>
+ </varlistentry>
+</xsl:template>
+
<!-- Request/event list -->
<xsl:template match="request|event">
<section id="protocol-spec-{../@name}-{name()}-{@name}">
@@ -174,7 +199,7 @@
<!-- Enumeration -->
<xsl:template match="enum">
- <section id="protocol-spec-{../@name}-{name()}-{@name}">
+ <section id="protocol-spec-{../@name}-enum-{@name}">
<title>
<xsl:value-of select="../@name"/>::<xsl:value-of select="@name" />
<xsl:if test="@bitfield">
diff --git a/doc/publican/sources/Architecture.xml b/doc/publican/sources/Architecture.xml
index 5d9ada0..b8a104c 100644
--- a/doc/publican/sources/Architecture.xml
+++ b/doc/publican/sources/Architecture.xml
@@ -114,7 +114,7 @@
As suggested above, there are a few problems with this
approach. The X server doesn't have the information to
decide which window should receive the event, nor can it
- transform the screen coordinates to window local
+ transform the screen coordinates to window-local
coordinates. And even though X has handed responsibility for
the final painting of the screen to the compositing manager,
X still controls the front buffer and modesetting. Most of
@@ -172,7 +172,7 @@
in the scenegraph. Thus, the
compositor can pick the right window
and transform the screen coordinates
- to window local coordinates, by
+ to window-local coordinates, by
applying the inverse
transformations. The types of
transformation that can be applied
diff --git a/doc/publican/sources/Protocol.xml b/doc/publican/sources/Protocol.xml
index 66cebfb..ba6b5f1 100644
--- a/doc/publican/sources/Protocol.xml
+++ b/doc/publican/sources/Protocol.xml
@@ -199,7 +199,7 @@
Every interface is versioned and every protocol object implements a
particular version of its interface. For global objects, the maximum
version supported by the server is advertised with the global and the
- actual verion of the created protocol object is determined by the
+ actual version of the created protocol object is determined by the
version argument passed to wl_registry.bind(). For objects that are
not globals, their version is inferred from the object that created
them.
@@ -333,7 +333,7 @@
A seat represents a group of input devices including mice,
keyboards and touchscreens. It has a keyboard and pointer
focus. Seats are global objects. Pointer events are delivered
- in surface local coordinates.
+ in surface-local coordinates.
</para>
<para>
The compositor maintains an implicit grab when a button is
diff --git a/protocol/wayland.xml b/protocol/wayland.xml
index b223bb4..700ef03 100644
--- a/protocol/wayland.xml
+++ b/protocol/wayland.xml
@@ -67,12 +67,12 @@
where the error occurred, most often in response to a request
to that object. The code identifies the error and is defined
by the object interface. As such, each interface defines its
- own set of error codes. The message is an brief description
+ own set of error codes. The message is a brief description
of the error, for (debugging) convenience.
</description>
- <arg name="object_id" type="object"/>
- <arg name="code" type="uint"/>
- <arg name="message" type="string"/>
+ <arg name="object_id" type="object" summary="object where the error occurred"/>
+ <arg name="code" type="uint" summary="error code"/>
+ <arg name="message" type="string" summary="error description"/>
</event>
<enum name="error">
@@ -93,10 +93,10 @@
This event is used internally by the object ID management
logic. When a client deletes an object, the server will send
this event to acknowledge that it has seen the delete request.
- When the client receive this event, it will know that it can
+ When the client receives this event, it will know that it can
safely reuse the object ID.
</description>
- <arg name="id" type="uint" />
+ <arg name="id" type="uint" summary="deleted object id"/>
</event>
</interface>
@@ -141,9 +141,9 @@
the given name is now available, and it implements the
given version of the given interface.
</description>
- <arg name="name" type="uint"/>
- <arg name="interface" type="string"/>
- <arg name="version" type="uint"/>
+ <arg name="name" type="uint" summary="numeric name of the global object"/>
+ <arg name="interface" type="string" summary="interface implemented by the object"/>
+ <arg name="version" type="uint" summary="interface version"/>
</event>
<event name="global_remove">
@@ -159,7 +159,7 @@
ignored until the client destroys it, to avoid races between
the global going away and a client sending a request to it.
</description>
- <arg name="name" type="uint"/>
+ <arg name="name" type="uint" summary="numeric name of the global object"/>
</event>
</interface>
@@ -214,8 +214,8 @@
Create a wl_buffer object from the pool.
The buffer is created offset bytes into the pool and has
- width and height as specified. The stride arguments specifies
- the number of bytes from beginning of one row to the beginning
+ width and height as specified. The stride argument specifies
+ the number of bytes from the beginning of one row to the beginning
of the next. The format is the pixel format of the buffer and
must be one of those advertised through the wl_shm.format event.
@@ -229,7 +229,7 @@
<arg name="width" type="int"/>
<arg name="height" type="int"/>
<arg name="stride" type="int"/>
- <arg name="format" type="uint"/>
+ <arg name="format" type="uint" enum="wl_shm.format"/>
</request>
<request name="destroy" type="destructor">
@@ -367,7 +367,7 @@
can be used for buffers. Known formats include
argb8888 and xrgb8888.
</description>
- <arg name="format" type="uint" enum="format"/>
+ <arg name="format" type="uint" enum="format" summary="buffer pixel format"/>
</event>
</interface>
@@ -392,13 +392,13 @@
<event name="release">
<description summary="compositor releases buffer">
Sent when this wl_buffer is no longer used by the compositor.
- The client is now free to re-use or destroy this buffer and its
+ The client is now free to reuse or destroy this buffer and its
backing storage.
If a client receives a release event before the frame callback
requested in the same wl_surface.commit that attaches this
wl_buffer to a surface, then the client is immediately free to
- re-use the buffer and its backing storage, and does not need a
+ reuse the buffer and its backing storage, and does not need a
second buffer for the next surface content update. Typically
this is possible, when the compositor maintains a copy of the
wl_surface contents, e.g. as a GL texture. This is an important
@@ -407,7 +407,6 @@
</event>
</interface>
-
<interface name="wl_data_offer" version="3">
<description summary="offer to transfer data">
A wl_data_offer represents a piece of data offered for transfer
@@ -464,7 +463,7 @@
EOF and then closes its end, at which point the transfer is
complete.
- This request may happen multiple times for different mimetypes,
+ This request may happen multiple times for different mime types,
both before and after wl_data_device.drop. Drag-and-drop destination
clients may preemptively fetch data or examine it more closely to
determine acceptance.
@@ -485,7 +484,7 @@
event per offered mime type.
</description>
- <arg name="mime_type" type="string"/>
+ <arg name="mime_type" type="string" summary="offered mime type"/>
</event>
<!-- Version 3 additions -->
@@ -511,7 +510,7 @@
Sets the actions that the destination side client supports for
this operation. This request may trigger the emission of
wl_data_source.action and wl_data_offer.action events if the compositor
- need to change the selected action.
+ needs to change the selected action.
This request can be called multiple times throughout the
drag-and-drop operation, typically in response to wl_data_device.enter
@@ -550,7 +549,7 @@
will be sent right after wl_data_device.enter, or anytime the source
side changes its offered actions through wl_data_source.set_actions.
</description>
- <arg name="source_actions" type="uint"/>
+ <arg name="source_actions" type="uint" summary="actions offered by the data source"/>
</event>
<event name="action" since="3">
@@ -585,13 +584,13 @@
compositor shall no longer be able to induce a different action.
Upon "ask" actions, it is expected that the drag-and-drop destination
- may potentially choose different a different action and/or mime type,
+ may potentially choose a different action and/or mime type,
based on wl_data_offer.source_actions and finally chosen by the
user (e.g. popping up a menu with the available options). The
final wl_data_offer.set_actions and wl_data_offer.accept requests
must happen before the call to wl_data_offer.finish.
</description>
- <arg name="dnd_action" type="uint"/>
+ <arg name="dnd_action" type="uint" summary="action selected by the compositor"/>
</event>
</interface>
@@ -633,7 +632,7 @@
Used for feedback during drag-and-drop.
</description>
- <arg name="mime_type" type="string" allow-null="true"/>
+ <arg name="mime_type" type="string" allow-null="true" summary="mime type accepted by the target"/>
</event>
<event name="send">
@@ -643,8 +642,8 @@
close it.
</description>
- <arg name="mime_type" type="string"/>
- <arg name="fd" type="fd"/>
+ <arg name="mime_type" type="string" summary="mime type for the data"/>
+ <arg name="fd" type="fd" summary="file descriptor for the data"/>
</event>
<event name="cancelled">
@@ -654,7 +653,7 @@
- The data source has been replaced by another data source.
- The drag-and-drop operation was performed, but the drop destination
- did not accept any of the mimetypes offered through
+ did not accept any of the mime types offered through
wl_data_source.target.
- The drag-and-drop operation was performed, but the drop destination
did not select any of the actions present in the mask offered through
@@ -697,7 +696,7 @@
<description summary="the drag-and-drop operation physically finished">
The user performed the drop action. This event does not indicate
acceptance, wl_data_source.cancelled may still be emitted afterwards
- if the drop destination does not accept any mimetype.
+ if the drop destination does not accept any mime type.
However, this event might however not be received if the compositor
cancelled the drag-and-drop operation before this event could happen.
@@ -746,7 +745,7 @@
Clients can trigger cursor surface changes from this point, so
they reflect the current action.
</description>
- <arg name="dnd_action" type="uint"/>
+ <arg name="dnd_action" type="uint" summary="action selected by the compositor"/>
</event>
</interface>
@@ -821,22 +820,23 @@
mime types it offers.
</description>
- <arg name="id" type="new_id" interface="wl_data_offer"/>
+ <arg name="id" type="new_id" interface="wl_data_offer" summary="the new data_offer object"/>
</event>
<event name="enter">
<description summary="initiate drag-and-drop session">
This event is sent when an active drag-and-drop pointer enters
a surface owned by the client. The position of the pointer at
- enter time is provided by the x and y arguments, in surface
- local coordinates.
+ enter time is provided by the x and y arguments, in surface-local
+ coordinates.
</description>
- <arg name="serial" type="uint"/>
- <arg name="surface" type="object" interface="wl_surface"/>
- <arg name="x" type="fixed"/>
- <arg name="y" type="fixed"/>
- <arg name="id" type="object" interface="wl_data_offer" allow-null="true"/>
+ <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"/>
+ <arg name="y" type="fixed" summary="surface-local y coordinate"/>
+ <arg name="id" type="object" interface="wl_data_offer" allow-null="true"
+ summary="source data_offer object"/>
</event>
<event name="leave">
@@ -851,16 +851,16 @@
<description summary="drag-and-drop session motion">
This event is sent when the drag-and-drop pointer moves within
the currently focused surface. The new position of the pointer
- is provided by the x and y arguments, in surface local
+ is provided by the x and y arguments, in surface-local
coordinates.
</description>
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
- <arg name="x" type="fixed"/>
- <arg name="y" type="fixed"/>
+ <arg name="x" type="fixed" summary="surface-local x coordinate"/>
+ <arg name="y" type="fixed" summary="surface-local y coordinate"/>
</event>
<event name="drop">
- <description summary="end drag-and-drag session successfully">
+ <description summary="end drag-and-drop session successfully">
The event is sent when a drag-and-drop operation is ended
because the implicit grab is removed.
@@ -891,7 +891,8 @@
destroy the previous selection data_offer, if any, upon receiving
this event.
</description>
- <arg name="id" type="object" interface="wl_data_offer" allow-null="true"/>
+ <arg name="id" type="object" interface="wl_data_offer" allow-null="true"
+ summary="selection data_offer object"/>
</event>
<!-- Version 2 additions -->
@@ -910,6 +911,11 @@
copy-and-paste and drag-and-drop. These mechanisms are tied to
a wl_seat and this interface lets a client get a wl_data_device
corresponding to a wl_seat.
+
+ Depending on the version bound, the objects created from the bound
+ wl_data_device_manager object will have different requirements for
+ functioning properly. See wl_data_source.set_actions,
+ wl_data_offer.accept and wl_data_offer.finish for details.
</description>
<request name="create_data_source">
@@ -941,7 +947,7 @@
(source actions ∩ destination actions).
In addition, compositors may also pick different actions in
- reaction to key modifiers being pressed, one common design that
+ reaction to key modifiers being pressed. One common design that
is used in major toolkits (and the behavior recommended for
compositors) is:
@@ -989,7 +995,6 @@
</interface>
<interface name="wl_shell_surface" version="1">
-
<description summary="desktop-style metadata interface">
An interface that may be implemented by a wl_surface, for
implementations that provide a desktop-style user interface.
@@ -999,7 +1004,7 @@
metadata like title and class, etc.
On the server side the object is automatically destroyed when
- the related wl_surface is destroyed. On client side,
+ the related wl_surface is destroyed. On the client side,
wl_shell_surface_destroy() must be called before destroying
the wl_surface object.
</description>
@@ -1075,9 +1080,9 @@
<description summary="make the surface a transient surface">
Map the surface relative to an existing surface.
- The x and y arguments specify the locations of the upper left
+ The x and y arguments specify the location of the upper left
corner of the surface relative to the upper left corner of the
- parent surface, in surface local coordinates.
+ parent surface, in surface-local coordinates.
The flags argument controls details of the transient behaviour.
</description>
@@ -1116,7 +1121,7 @@
The framerate parameter is used only when the method is set
to "driver", to indicate the preferred framerate. A value of 0
- indicates that the app does not care about framerate. The
+ indicates that the client does not care about framerate. The
framerate is specified in mHz, that is framerate of 60000 is 60Hz.
A method of "scale" or "driver" implies a scaling operation of
@@ -1154,14 +1159,14 @@
be unmapped).
The popup grab continues until the window is destroyed or a
- mouse button is pressed in any other clients window. A click
- in any of the clients surfaces is reported as normal, however,
- clicks in other clients surfaces will be discarded and trigger
+ mouse button is pressed in any other client's window. A click
+ in any of the client's surfaces is reported as normal, however,
+ clicks in other clients' surfaces will be discarded and trigger
the callback.
- The x and y arguments specify the locations of the upper left
+ The x and y arguments specify the location of the upper left
corner of the surface relative to the upper left corner of the
- parent surface, in surface local coordinates.
+ parent surface, in surface-local coordinates.
</description>
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
@@ -1187,7 +1192,7 @@
on the next buffer attach to this surface.
A maximized surface typically fills the entire output it is
- bound to, except for desktop element such as panels. This is
+ bound to, except for desktop elements such as panels. This is
the main difference between a maximized shell surface and a
fullscreen shell surface.
@@ -1226,7 +1231,7 @@
Ping a client to check if it is receiving events and sending
requests. A client is expected to reply with a pong request.
</description>
- <arg name="serial" type="uint"/>
+ <arg name="serial" type="uint" summary="serial number of the ping"/>
</event>
<event name="configure">
@@ -1247,12 +1252,12 @@
event it received.
The width and height arguments specify the size of the window
- in surface local coordinates.
+ in surface-local coordinates.
</description>
- <arg name="edges" type="uint" enum="resize"/>
- <arg name="width" type="int"/>
- <arg name="height" type="int"/>
+ <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"/>
</event>
<event name="popup_done">
@@ -1270,11 +1275,11 @@
It has a location, size and pixel contents.
The size of a surface (and relative positions on it) is described
- in surface local coordinates, which may differ from the buffer
- local coordinates of the pixel content, in case a buffer_transform
+ in surface-local coordinates, which may differ from the buffer
+ coordinates of the pixel content, in case a buffer_transform
or a buffer_scale is used.
- A surface without a "role" is fairly useless, a compositor does
+ A surface without a "role" is fairly useless: a compositor does
not know where, when or how to present it. The role is the
purpose of a wl_surface. Examples of roles are a cursor for a
pointer (as set by wl_pointer.set_cursor), a drag icon
@@ -1332,7 +1337,7 @@
The x and y arguments specify the location of the new pending
buffer's upper left corner, relative to the current buffer's upper
- left corner, in surface local coordinates. In other words, the
+ left corner, in surface-local coordinates. In other words, the
x and y, combined with the new surface size define in which
directions the surface's size changes.
@@ -1350,7 +1355,7 @@
any time after the wl_surface.commit request. When the compositor
will not access the pixels anymore, it will send the
wl_buffer.release event. Only after receiving wl_buffer.release,
- the client may re-use the wl_buffer. A wl_buffer that has been
+ the client may reuse the wl_buffer. A wl_buffer that has been
attached and then replaced by another attach instead of committed
will not receive a release event, and is not used by the
compositor.
@@ -1378,7 +1383,7 @@
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.
The initial value for pending damage is empty: no damage.
wl_surface.damage adds pending damage: the new pending damage
@@ -1389,7 +1394,7 @@
damage as it repaints the surface.
Alternatively, damage can be posted with wl_surface.damage_buffer
- which uses buffer co-ordinates instead of surface co-ordinates,
+ which uses buffer coordinates instead of surface coordinates,
and is probably the preferred and intuitive way of doing this.
</description>
@@ -1401,7 +1406,7 @@
<request name="frame">
<description summary="request a frame throttling hint">
- Request a notification when it is a good time start drawing a new
+ Request a notification when it is a good time to start drawing a new
frame, by creating a frame callback. This is useful for throttling
redrawing operations, and driving animations.
@@ -1420,10 +1425,10 @@
will not send excessive updates, while still allowing
the highest possible update rate for clients that wait for the reply
before drawing again. The server should give some time for the client
- to draw and commit after sending the frame callback events to let them
+ to draw and commit after sending the frame callback events to let it
hit the next output refresh.
- A server should avoid signalling the frame callbacks if the
+ A server should avoid signaling the frame callbacks if the
surface is not visible in any way, e.g. the surface is off-screen,
or completely obscured by other opaque surfaces.
@@ -1444,12 +1449,12 @@
opaque content.
The opaque region is an optimization hint for the compositor
- that lets it optimize out redrawing of content behind opaque
+ that lets it optimize the redrawing of content behind opaque
regions. Setting an opaque region is not required for correct
behaviour, but marking transparent content as opaque will result
in repaint artifacts.
- The opaque region is specified in surface local coordinates.
+ The opaque region is specified in surface-local coordinates.
The compositor ignores the parts of the opaque region that fall
outside of the surface.
@@ -1460,7 +1465,7 @@
wl_surface.commit copies the pending region to the current region.
Otherwise, the pending and current regions are never changed.
- The initial value for opaque region is empty. Setting the pending
+ The initial value for an opaque region is empty. Setting the pending
opaque region has copy semantics, and the wl_region object can be
destroyed immediately. A NULL wl_region causes the pending opaque
region to be set to empty.
@@ -1478,7 +1483,7 @@
surface in the server surface stack. The compositor ignores the
parts of the input region that fall outside of the surface.
- The input region is specified in surface local coordinates.
+ The input region is specified in surface-local coordinates.
Input region is double-buffered state, see wl_surface.commit.
@@ -1488,7 +1493,7 @@
except cursor and icon surfaces are special cases, see
wl_pointer.set_cursor and wl_data_device.start_drag.
- The initial value for input region is infinite. That means the
+ The initial value for an input region is infinite. That means the
whole surface will accept input. Setting the pending input region
has copy semantics, and the wl_region object can be destroyed
immediately. A NULL wl_region causes the input region to be set
@@ -1501,13 +1506,13 @@
<request name="commit">
<description summary="commit pending surface state">
Surface state (input, opaque, and damage regions, attached buffers,
- etc.) is double-buffered. Protocol requests modify the pending
- state, as opposed to current state in use by the compositor. Commit
+ etc.) is double-buffered. Protocol requests modify the pending state,
+ as opposed to the current state in use by the compositor. A commit
request atomically applies all pending state, replacing the current
state. After commit, the new pending state is as documented for each
related request.
- On commit, a pending wl_buffer is applied first, all other state
+ On commit, a pending wl_buffer is applied first, and all other state
second. This means that all coordinates in double-buffered state are
relative to the new wl_buffer coming into use, except for
wl_surface.attach itself. If there is no pending wl_buffer, the
@@ -1528,7 +1533,7 @@
Note that a surface may be overlapping with zero or more outputs.
</description>
- <arg name="output" type="object" interface="wl_output"/>
+ <arg name="output" type="object" interface="wl_output" summary="output entered by the surface"/>
</event>
<event name="leave">
@@ -1537,7 +1542,7 @@
results in it no longer having any part of it within the scanout region
of an output.
</description>
- <arg name="output" type="object" interface="wl_output"/>
+ <arg name="output" type="object" interface="wl_output" summary="output left by the surface"/>
</event>
<!-- Version 2 additions -->
@@ -1559,7 +1564,7 @@
values are never changed.
The purpose of this request is to allow clients to render content
- according to the output transform, thus permiting the compositor to
+ according to the output transform, thus permitting the compositor to
use certain optimizations even if the display is rotated. Using
hardware overlays and scanning out a client buffer for fullscreen
surfaces are examples of such optimizations. Those optimizations are
@@ -1574,7 +1579,7 @@
wl_output.transform enum the invalid_transform protocol error
is raised.
</description>
- <arg name="transform" type="int"/>
+ <arg name="transform" type="int" enum="wl_output.transform"/>
</request>
<!-- Version 3 additions -->
@@ -1593,9 +1598,9 @@
Otherwise, the pending and current values are never changed.
The purpose of this request is to allow clients to supply higher
- resolution buffer data for use on high resolution outputs. Its
- intended that you pick the same buffer scale as the scale of the
- output that the surface is displayed on.This means the compositor
+ resolution buffer data for use on high resolution outputs. It is
+ intended that you pick the same buffer scale as the scale of the
+ output that the surface is displayed on. This means the compositor
can avoid scaling when rendering the surface on that output.
Note that if the scale is larger than 1, then you have to attach
@@ -1610,7 +1615,7 @@
<!-- Version 4 additions -->
<request name="damage_buffer" since="4">
- <description summary="mark part of the surface damaged using buffer co-ordinates">
+ <description summary="mark part of the surface damaged using buffer coordinates">
This request is used to describe the regions where the pending
buffer is different from the current surface contents, and where
the surface therefore needs to be repainted. The compositor
@@ -1629,14 +1634,14 @@
damage as it repaints the surface.
This request differs from wl_surface.damage in only one way - it
- takes damage in buffer co-ordinates instead of surface local
- co-ordinates. While this generally is more intuitive than surface
- co-ordinates, it is especially desirable when using wp_viewport
+ takes damage in buffer coordinates instead of surface-local
+ coordinates. While this generally is more intuitive than surface
+ coordinates, it is especially desirable when using wp_viewport
or when a drawing library (like EGL) is unaware of buffer scale
and buffer transform.
Note: Because buffer transformation changes and damage requests may
- be interleaved in the protocol stream, It is impossible to determine
+ be interleaved in the protocol stream, it is impossible to determine
the actual mapping between surface and buffer damage until
wl_surface.commit time. Therefore, compositors wishing to take both
kinds of damage into account will have to accumulate damage from the
@@ -1664,9 +1669,9 @@
This is a bitmask of capabilities this seat has; if a member is
set, then it is present on the seat.
</description>
- <entry name="pointer" value="1" summary="The seat has pointer devices"/>
- <entry name="keyboard" value="2" summary="The seat has one or more keyboards"/>
- <entry name="touch" value="4" summary="The seat has touch devices"/>
+ <entry name="pointer" value="1" summary="the seat has pointer devices"/>
+ <entry name="keyboard" value="2" summary="the seat has one or more keyboards"/>
+ <entry name="touch" value="4" summary="the seat has touch devices"/>
</enum>
<event name="capabilities">
@@ -1696,7 +1701,7 @@
The above behavior also applies to wl_keyboard and wl_touch with the
keyboard and touch capabilities, respectively.
</description>
- <arg name="capabilities" type="uint" enum="capability"/>
+ <arg name="capabilities" type="uint" enum="capability" summary="capabilities of the seat"/>
</event>
<request name="get_pointer">
@@ -1746,14 +1751,14 @@
identify which physical devices the seat represents. Based on
the seat configuration used by the compositor.
</description>
- <arg name="name" type="string"/>
+ <arg name="name" type="string" summary="seat identifier"/>
</event>
<!-- Version 5 additions -->
<request name="release" type="destructor" since="5">
<description summary="release the seat object">
- Using this request client can tell the server that it is not going to
+ Using this request a client can tell the server that it is not going to
use the seat object anymore.
</description>
</request>
@@ -1792,8 +1797,8 @@
The parameters hotspot_x and hotspot_y define the position of
the pointer surface relative to the pointer location. Its
top-left corner is always at (x, y) - (hotspot_x, hotspot_y),
- where (x, y) are the coordinates of the pointer location, in surface
- local coordinates.
+ where (x, y) are the coordinates of the pointer location, in
+ surface-local coordinates.
On surface.attach requests to the pointer surface, hotspot_x
and hotspot_y are decremented by the x and y parameters
@@ -1813,8 +1818,8 @@
<arg name="serial" type="uint" summary="serial of the enter event"/>
<arg name="surface" type="object" interface="wl_surface" allow-null="true"/>
- <arg name="hotspot_x" type="int" summary="x coordinate in surface-relative coordinates"/>
- <arg name="hotspot_y" type="int" summary="y coordinate in surface-relative coordinates"/>
+ <arg name="hotspot_x" type="int" summary="surface-local x coordinate"/>
+ <arg name="hotspot_y" type="int" summary="surface-local y coordinate"/>
</request>
<event name="enter">
@@ -1822,15 +1827,15 @@
Notification that this seat's pointer is focused on a certain
surface.
- When an seat's focus enters a surface, the pointer image
+ When a seat's focus enters a surface, the pointer image
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"/>
- <arg name="surface" type="object" interface="wl_surface"/>
- <arg name="surface_x" type="fixed" summary="x coordinate in surface-relative coordinates"/>
- <arg name="surface_y" type="fixed" summary="y coordinate in surface-relative coordinates"/>
+ <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"/>
+ <arg name="surface_y" type="fixed" summary="surface-local y coordinate"/>
</event>
<event name="leave">
@@ -1841,8 +1846,8 @@
The leave notification is sent before the enter notification
for the new focus.
</description>
- <arg name="serial" type="uint"/>
- <arg name="surface" type="object" interface="wl_surface"/>
+ <arg name="serial" type="uint" summary="serial number of the leave event"/>
+ <arg name="surface" type="object" interface="wl_surface" summary="surface left by the pointer"/>
</event>
<event name="motion">
@@ -1853,17 +1858,17 @@
</description>
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
- <arg name="surface_x" type="fixed" summary="x coordinate in surface-relative coordinates"/>
- <arg name="surface_y" type="fixed" summary="y coordinate in surface-relative coordinates"/>
+ <arg name="surface_x" type="fixed" summary="surface-local x coordinate"/>
+ <arg name="surface_y" type="fixed" summary="surface-local y coordinate"/>
</event>
<enum name="button_state">
<description summary="physical button state">
- Describes the physical state of a button which provoked the button
+ Describes the physical state of a button that produced the button
event.
</description>
- <entry name="released" value="0" summary="The button is not pressed"/>
- <entry name="pressed" value="1" summary="The button is pressed"/>
+ <entry name="released" value="0" summary="the button is not pressed"/>
+ <entry name="pressed" value="1" summary="the button is pressed"/>
</enum>
<event name="button">
@@ -1876,10 +1881,10 @@
granularity, with an undefined base.
</description>
- <arg name="serial" type="uint"/>
+ <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"/>
- <arg name="state" type="uint" enum="button_state"/>
+ <arg name="button" type="uint" summary="button that produced the event"/>
+ <arg name="state" type="uint" enum="button_state" summary="physical state of the button"/>
</event>
<enum name="axis">
@@ -1906,23 +1911,23 @@
choose to emit scroll events where the motion vector is
equivalent to a motion event vector.
- When applicable, clients can transform its view relative to the
+ 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"/>
- <arg name="value" type="fixed"/>
+ <arg name="axis" type="uint" enum="axis" summary="axis type"/>
+ <arg name="value" type="fixed" summary="length of vector in surface-local coordinate space"/>
</event>
<!-- Version 3 additions -->
<request name="release" type="destructor" since="3">
<description summary="release the pointer object">
- Using this request client can tell the server that it is not going to
+ Using this request a client can tell the server that it is not going to
use the pointer object anymore.
- This request destroys the pointer proxy object, so user must not call
+ This request destroys the pointer proxy object, so clients must not call
wl_pointer_destroy() after using this request.
</description>
</request>
@@ -1947,7 +1952,7 @@
When a wl_pointer.axis and a wl_pointer.axis_stop event occur within
the same frame, this indicates that axis movement in one axis has
stopped but continues in the other axis.
- When multiple wl_pointer.axis_stop events occur within in the same
+ When multiple wl_pointer.axis_stop events occur within the same
frame, this indicates that these axes stopped in the same instance.
A wl_pointer.frame event is sent for every logical event group,
@@ -1958,7 +1963,7 @@
The wl_pointer.enter and wl_pointer.leave events are logical events
generated by the compositor and not the hardware. These events are
also grouped by a wl_pointer.frame. When a pointer moves from one
- surface to the another, a compositor should group the
+ surface to another, a compositor should group the
wl_pointer.leave event within the same wl_pointer.frame.
However, a client must not rely on wl_pointer.leave and
wl_pointer.enter being in the same wl_pointer.frame.
@@ -1983,9 +1988,9 @@
the vertical motion of a device is converted to scroll events while
a button is held down.
</description>
- <entry name="wheel" value="0" summary="A physical wheel" />
- <entry name="finger" value="1" summary="Finger on a touch surface" />
- <entry name="continuous" value="2" summary="Continuous coordinate space"/>
+ <entry name="wheel" value="0" summary="a physical wheel" />
+ <entry name="finger" value="1" summary="finger on a touch surface" />
+ <entry name="continuous" value="2" summary="continuous coordinate space"/>
</enum>
<event name="axis_source" since="5">
@@ -2002,7 +2007,7 @@
If the source is wl_pointer axis_source.wheel or
wl_pointer.axis_source.continuous, a wl_pointer.axis_stop event may
- or may not be sent. Whether a compositor sends a axis_stop event
+ or may not be sent. Whether a compositor sends an axis_stop event
for these sources is hardware-specific and implementation-dependent;
clients must not rely on receiving an axis_stop event for these
scroll sources and should treat scroll sequences from these scroll
@@ -2015,7 +2020,7 @@
The order of wl_pointer.axis_discrete and wl_pointer.axis_source is
not guaranteed.
</description>
- <arg name="axis_source" type="uint" enum="axis_source"/>
+ <arg name="axis_source" type="uint" enum="axis_source" summary="source of the axis event"/>
</event>
<event name="axis_stop" since="5">
@@ -2033,7 +2038,7 @@
The timestamp is to be interpreted identical to the timestamp in the
wl_pointer.axis event. The timestamp value may be the same as a
- preceeding wl_pointer.axis event.
+ preceding wl_pointer.axis event.
</description>
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
<arg name="axis" type="uint" enum="axis" summary="the axis stopped with this event"/>
@@ -2062,14 +2067,14 @@
The discrete value carries the directional information. e.g. a value
of -2 is two steps towards the negative direction of this axis.
- The axis number is identical to the axis number in the associate
+ The axis number is identical to the axis number in the associated
axis event.
The order of wl_pointer.axis_discrete and wl_pointer.axis_source is
not guaranteed.
</description>
- <arg name="axis" type="uint" enum="axis" />
- <arg name="discrete" type="int"/>
+ <arg name="axis" type="uint" enum="axis" summary="axis type"/>
+ <arg name="discrete" type="int" summary="number of steps"/>
</event>
</interface>
@@ -2095,9 +2100,9 @@
This event provides a file descriptor to the client which can be
memory-mapped to provide a keyboard mapping description.
</description>
- <arg name="format" type="uint" enum="keymap_format"/>
- <arg name="fd" type="fd"/>
- <arg name="size" type="uint"/>
+ <arg name="format" type="uint" enum="keymap_format" summary="keymap format"/>
+ <arg name="fd" type="fd" summary="keymap file descriptor"/>
+ <arg name="size" type="uint" summary="keymap size, in bytes"/>
</event>
<event name="enter">
@@ -2105,8 +2110,8 @@
Notification that this seat's keyboard focus is on a certain
surface.
</description>
- <arg name="serial" type="uint"/>
- <arg name="surface" type="object" interface="wl_surface"/>
+ <arg name="serial" type="uint" summary="serial number of the enter event"/>
+ <arg name="surface" type="object" interface="wl_surface" summary="surface gaining keyboard focus"/>
<arg name="keys" type="array" summary="the currently pressed keys"/>
</event>
@@ -2118,13 +2123,13 @@
The leave notification is sent before the enter notification
for the new focus.
</description>
- <arg name="serial" type="uint"/>
- <arg name="surface" type="object" interface="wl_surface"/>
+ <arg name="serial" type="uint" summary="serial number of the leave event"/>
+ <arg name="surface" type="object" interface="wl_surface" summary="surface that lost keyboard focus"/>
</event>
<enum name="key_state">
<description summary="physical key state">
- Describes the physical state of a key which provoked the key event.
+ Describes the physical state of a key that produced the key event.
</description>
<entry name="released" value="0" summary="key is not pressed"/>
<entry name="pressed" value="1" summary="key is pressed"/>
@@ -2137,10 +2142,10 @@
granularity, with an undefined base.
</description>
- <arg name="serial" type="uint"/>
+ <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"/>
- <arg name="state" type="uint" enum="key_state"/>
+ <arg name="key" type="uint" summary="key that produced the event"/>
+ <arg name="state" type="uint" enum="key_state" summary="physical state of the key"/>
</event>
<event name="modifiers">
@@ -2149,11 +2154,11 @@
changed, and it should update its local state.
</description>
- <arg name="serial" type="uint"/>
- <arg name="mods_depressed" type="uint"/>
- <arg name="mods_latched" type="uint"/>
- <arg name="mods_locked" type="uint"/>
- <arg name="group" type="uint"/>
+ <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"/>
+ <arg name="mods_locked" type="uint" summary="locked modifiers"/>
+ <arg name="group" type="uint" summary="keyboard layout"/>
</event>
<!-- Version 3 additions -->
@@ -2202,37 +2207,37 @@
<event name="down">
<description summary="touch down event and beginning of a touch sequence">
A new touch point has appeared on the surface. This touch point is
- assigned a unique @id. Future events from this touchpoint reference
+ assigned a unique ID. Future events from this touch point reference
this ID. The ID ceases to be valid after a touch up event and may be
- re-used in the future.
+ reused in the future.
</description>
- <arg name="serial" type="uint"/>
+ <arg name="serial" type="uint" summary="serial number of the touch down event"/>
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
- <arg name="surface" type="object" interface="wl_surface"/>
+ <arg name="surface" type="object" interface="wl_surface" summary="surface touched"/>
<arg name="id" type="int" summary="the unique ID of this touch point"/>
- <arg name="x" type="fixed" summary="x coordinate in surface-relative coordinates"/>
- <arg name="y" type="fixed" summary="y coordinate in surface-relative coordinates"/>
+ <arg name="x" type="fixed" summary="surface-local x coordinate"/>
+ <arg name="y" type="fixed" summary="surface-local y coordinate"/>
</event>
<event name="up">
<description summary="end of a touch event sequence">
The touch point has disappeared. No further events will be sent for
- this touchpoint and the touch point's ID is released and may be
- re-used in a future touch down event.
+ this touch point and the touch point's ID is released and may be
+ reused in a future touch down event.
</description>
- <arg name="serial" type="uint"/>
+ <arg name="serial" type="uint" summary="serial number of the touch up event"/>
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
<arg name="id" type="int" summary="the unique ID of this touch point"/>
</event>
<event name="motion">
<description summary="update of touch point coordinates">
- A touchpoint has changed coordinates.
+ A touch point has changed coordinates.
</description>
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
<arg name="id" type="int" summary="the unique ID of this touch point"/>
- <arg name="x" type="fixed" summary="x coordinate in surface-relative coordinates"/>
- <arg name="y" type="fixed" summary="y coordinate in surface-relative coordinates"/>
+ <arg name="x" type="fixed" summary="surface-local x coordinate"/>
+ <arg name="y" type="fixed" summary="surface-local y coordinate"/>
</event>
<event name="frame">
@@ -2248,7 +2253,7 @@
particular gesture. Touch cancellation applies to all touch points
currently active on this client's surface. The client is
responsible for finalizing the touch points, future touch points on
- this surface may re-use the touch point ID.
+ this surface may reuse the touch point ID.
</description>
</event>
@@ -2263,7 +2268,7 @@
<description summary="compositor output region">
An output describes part of the compositor geometry. The
compositor works in the 'compositor coordinate system' and an
- output corresponds to rectangular area in that space that is
+ output corresponds to a rectangular area in that space that is
actually visible. This typically corresponds to a monitor that
displays part of the compositor space. This object is published
as global during start up, or when a monitor is hotplugged.
@@ -2291,7 +2296,7 @@
The flipped values correspond to an initial flip around a
vertical axis followed by rotation.
- The purpose is mainly to allow clients render accordingly and
+ The purpose is mainly to allow clients to render accordingly and
tell the compositor, so that for fullscreen surfaces, the
compositor will still be able to scan out directly from client
surfaces.
@@ -2356,7 +2361,7 @@
the output device. This is not necessarily the same as
the output size in the global compositor space. For instance,
the output may be scaled, as described in wl_output.scale,
- or transformed , as described in wl_output.transform.
+ or transformed, as described in wl_output.transform.
</description>
<arg name="flags" type="uint" enum="mode" summary="bitfield of mode flags"/>
<arg name="width" type="int" summary="width of the mode in hardware units"/>
@@ -2366,7 +2371,7 @@
<event name="done" since="2">
<description summary="sent all information about output">
- This event is sent after all other properties has been
+ This event is sent after all other properties have been
sent after binding to the output object and after any
other property changes done after that. This allows
changes to the output properties to be seen as
@@ -2434,7 +2439,6 @@
<arg name="width" type="int"/>
<arg name="height" type="int"/>
</request>
-
</interface>
<interface name="wl_subcompositor" version="1">
@@ -2485,7 +2489,7 @@
</description>
<arg name="id" type="new_id" interface="wl_subsurface"
- summary="the new subsurface object id"/>
+ summary="the new subsurface 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"
@@ -2507,7 +2511,7 @@
hidden, or if a NULL wl_buffer is applied. These rules apply
recursively through the tree of surfaces.
- The behaviour of wl_surface.commit request on a sub-surface
+ The behaviour of a wl_surface.commit request on a sub-surface
depends on the sub-surface's mode. The possible modes are
synchronized and desynchronized, see methods
wl_subsurface.set_sync and wl_subsurface.set_desync. Synchronized
@@ -2549,7 +2553,7 @@
<request name="destroy" type="destructor">
<description summary="remove sub-surface interface">
The sub-surface interface is removed from the wl_surface object
- that was turned into a sub-surface with
+ that was turned into a sub-surface with a
wl_subcompositor.get_subsurface request. The wl_surface's association
to the parent is deleted, and the wl_surface loses its role as
a sub-surface. The wl_surface is unmapped.
@@ -2564,7 +2568,7 @@
<request name="set_position">
<description summary="reposition the sub-surface">
This schedules a sub-surface position change.
- The sub-surface will be moved so, that its origin (top-left
+ The sub-surface will be moved so that its origin (top left
corner pixel) will be at the location x, y of the parent surface
coordinate system. The coordinates are not restricted to the parent
surface area. Negative values are allowed.
@@ -2581,8 +2585,8 @@
The initial position is 0, 0.
</description>
- <arg name="x" type="int" summary="coordinate in the parent surface"/>
- <arg name="y" type="int" summary="coordinate in the parent surface"/>
+ <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>
<request name="place_above">
@@ -2610,7 +2614,7 @@
<request name="place_below">
<description summary="restack the sub-surface">
- The sub-surface is placed just below of the reference surface.
+ The sub-surface is placed just below the reference surface.
See wl_subsurface.place_above.
</description>
@@ -2649,7 +2653,7 @@
If cached state exists when wl_surface.commit is called in
desynchronized mode, the pending state is added to the cached
- state, and applied as whole. This invalidates the cache.
+ state, and applied as a whole. This invalidates the cache.
Note: even if a sub-surface is set to desynchronized, a parent
sub-surface may override it to behave as synchronized. For details,
@@ -2659,7 +2663,6 @@
the cached state is applied on set_desync.
</description>
</request>
-
</interface>
</protocol>
diff --git a/src/connection.c b/src/connection.c
index 65b64e9..c3293a9 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -798,19 +798,6 @@ wl_connection_demarshal(struct wl_connection *connection,
}
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;
-}
-
-int
wl_closure_lookup_objects(struct wl_closure *closure, struct wl_map *objects)
{
struct wl_object *object;
@@ -838,7 +825,6 @@ wl_closure_lookup_objects(struct wl_closure *closure, struct wl_map *objects)
} else if (object == NULL && id != 0) {
wl_log("unknown object (%u), message %s(%s)\n",
id, message->name, message->signature);
- object = NULL;
errno = EINVAL;
return -1;
}
@@ -1137,7 +1123,7 @@ wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
return -1;
buffer_size = buffer_size_for_closure(closure);
- buffer = malloc(buffer_size * sizeof buffer[0]);
+ buffer = zalloc(buffer_size * sizeof buffer[0]);
if (buffer == NULL)
return -1;
diff --git a/src/dtddata.S b/src/dtddata.S
index 68e3435..ce51133 100644
--- a/src/dtddata.S
+++ b/src/dtddata.S
@@ -20,6 +20,14 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+/*
+ * Avoid executable stack.
+ * from: https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart
+ */
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
+
/* from: http://www.linuxjournal.com/content/embedding-file-executable-aka-hello-world-version-5967#comment-348129 */
.macro binfile name file
diff --git a/src/scanner.c b/src/scanner.c
index 1d626f4..5f06e8e 100644
--- a/src/scanner.c
+++ b/src/scanner.c
@@ -26,6 +26,7 @@
*/
#include "config.h"
+#include "wayland-version.h"
#include <stdbool.h>
#include <stdio.h>
@@ -40,13 +41,13 @@
#if HAVE_LIBXML
#include <libxml/parser.h>
-#endif
-
-#include "wayland-util.h"
/* Embedded wayland.dtd file, see dtddata.S */
extern char DTD_DATA_begin;
extern int DTD_DATA_len;
+#endif
+
+#include "wayland-util.h"
enum side {
CLIENT,
@@ -64,14 +65,23 @@ usage(int ret)
"headers, server headers, or protocol marshalling code.\n\n");
fprintf(stderr, "options:\n");
fprintf(stderr, " -h, --help display this help and exit.\n"
+ " -v, --version print the wayland library version that\n"
+ " the scanner was built against.\n"
" -c, --include-core-only include the core version of the headers,\n"
" that is e.g. wayland-client-core.h instead\n"
" of wayland-client.h.\n");
exit(ret);
}
+static int
+scanner_version(int ret)
+{
+ fprintf(stderr, "wayland-scanner %s\n", WAYLAND_VERSION);
+ exit(ret);
+}
+
static bool
-is_dtd_valid(FILE *input)
+is_dtd_valid(FILE *input, const char *filename)
{
bool rc = true;
#if HAVE_LIBXML
@@ -101,7 +111,7 @@ is_dtd_valid(FILE *input)
abort();
}
- doc = xmlCtxtReadFd(ctx, fd, "protocol", NULL, 0);
+ doc = xmlCtxtReadFd(ctx, fd, filename, NULL, 0);
if (!doc) {
fprintf(stderr, "Failed to read XML\n");
abort();
@@ -752,8 +762,8 @@ start_element(void *data, const char *element_name, const char **atts)
enumeration->bitfield = true;
else
fail(&ctx->loc,
- "invalid value (%s) for bitfield attribute (only true/false are accepted)",
- bitfield);
+ "invalid value (%s) for bitfield attribute (only true/false are accepted)",
+ bitfield);
wl_list_insert(ctx->interface->enumeration_list.prev,
&enumeration->link);
@@ -790,32 +800,68 @@ start_element(void *data, const char *element_name, const char **atts)
}
}
+static struct enumeration *
+find_enumeration(struct protocol *protocol,
+ struct interface *interface,
+ char *enum_attribute)
+{
+ struct interface *i;
+ struct enumeration *e;
+ char *enum_name;
+ uint idx = 0, j;
+
+ for (j = 0; j + 1 < strlen(enum_attribute); j++) {
+ if (enum_attribute[j] == '.') {
+ idx = j;
+ }
+ }
+
+ if (idx > 0) {
+ enum_name = enum_attribute + idx + 1;
+
+ wl_list_for_each(i, &protocol->interface_list, link)
+ if (strncmp(i->name, enum_attribute, idx) == 0)
+ wl_list_for_each(e, &i->enumeration_list, link)
+ if (strcmp(e->name, enum_name) == 0)
+ return e;
+ } else if (interface) {
+ enum_name = enum_attribute;
+
+ wl_list_for_each(e, &interface->enumeration_list, link)
+ if (strcmp(e->name, enum_name) == 0)
+ return e;
+ }
+
+ return NULL;
+}
+
static void
-verify_arguments(struct parse_context *ctx, struct wl_list *messages, struct wl_list *enumerations)
+verify_arguments(struct parse_context *ctx,
+ struct interface *interface,
+ struct wl_list *messages,
+ struct wl_list *enumerations)
{
struct message *m;
wl_list_for_each(m, messages, link) {
struct arg *a;
wl_list_for_each(a, &m->arg_list, link) {
- struct enumeration *e, *f;
+ struct enumeration *e;
if (!a->enumeration_name)
continue;
- f = NULL;
- wl_list_for_each(e, enumerations, link) {
- if(strcmp(e->name, a->enumeration_name) == 0)
- f = e;
- }
- if (f == NULL)
+ e = find_enumeration(ctx->protocol, interface,
+ a->enumeration_name);
+
+ if (e == NULL)
fail(&ctx->loc,
"could not find enumeration %s",
a->enumeration_name);
switch (a->type) {
case INT:
- if (f->bitfield)
+ if (e->bitfield)
fail(&ctx->loc,
"bitfield-style enum must only be referenced by uint");
break;
@@ -853,12 +899,13 @@ end_element(void *data, const XML_Char *name)
ctx->enumeration->name);
}
ctx->enumeration = NULL;
- } else if (strcmp(name, "interface") == 0) {
- struct interface *i = ctx->interface;
-
- verify_arguments(ctx, &i->request_list, &i->enumeration_list);
- verify_arguments(ctx, &i->event_list, &i->enumeration_list);
+ } else if (strcmp(name, "protocol") == 0) {
+ struct interface *i;
+ wl_list_for_each(i, &ctx->protocol->interface_list, link) {
+ verify_arguments(ctx, i, &i->request_list, &i->enumeration_list);
+ verify_arguments(ctx, i, &i->event_list, &i->enumeration_list);
+ }
}
}
@@ -877,6 +924,34 @@ character_data(void *data, const XML_Char *s, int len)
}
static void
+format_text_to_comment(const char *text, bool standalone_comment)
+{
+ int bol = 1, start = 0, i, length;
+ bool comment_started = !standalone_comment;
+
+ length = strlen(text);
+ for (i = 0; i <= length; i++) {
+ if (bol && (text[i] == ' ' || text[i] == '\t')) {
+ continue;
+ } else if (bol) {
+ bol = 0;
+ start = i;
+ }
+ if (text[i] == '\n' ||
+ (text[i] == '\0' && !(start == i))) {
+ printf("%s%s%.*s\n",
+ comment_started ? " *" : "/*",
+ i > start ? " " : "",
+ i - start, text + start);
+ bol = 1;
+ comment_started = true;
+ }
+ }
+ if (comment_started && standalone_comment)
+ printf(" */\n\n");
+}
+
+static void
emit_opcodes(struct wl_list *message_list, struct interface *interface)
{
struct message *m;
@@ -898,9 +973,11 @@ emit_opcode_versions(struct wl_list *message_list, struct interface *interface)
{
struct message *m;
- wl_list_for_each(m, message_list, link)
+ 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",
interface->uppercase_name, m->uppercase_name, m->since);
+ }
printf("\n");
}
@@ -940,6 +1017,7 @@ emit_stubs(struct wl_list *message_list, struct interface *interface)
struct arg *a, *ret;
int has_destructor, has_destroy;
+ printf("/** @ingroup iface_%s */\n", interface->name);
printf("static inline void\n"
"%s_set_user_data(struct %s *%s, void *user_data)\n"
"{\n"
@@ -948,6 +1026,7 @@ emit_stubs(struct wl_list *message_list, struct interface *interface)
interface->name, interface->name, interface->name,
interface->name);
+ printf("/** @ingroup iface_%s */\n", interface->name);
printf("static inline void *\n"
"%s_get_user_data(struct %s *%s)\n"
"{\n"
@@ -981,7 +1060,8 @@ emit_stubs(struct wl_list *message_list, struct interface *interface)
exit(EXIT_FAILURE);
}
- if (!has_destroy && strcmp(interface->name, "wl_display") != 0)
+ if (!has_destroy && strcmp(interface->name, "wl_display") != 0) {
+ printf("/** @ingroup iface_%s */\n", interface->name);
printf("static inline void\n"
"%s_destroy(struct %s *%s)\n"
"{\n"
@@ -990,6 +1070,7 @@ emit_stubs(struct wl_list *message_list, struct interface *interface)
"}\n\n",
interface->name, interface->name, interface->name,
interface->name);
+ }
if (wl_list_empty(message_list))
return;
@@ -1009,6 +1090,11 @@ emit_stubs(struct wl_list *message_list, struct interface *interface)
ret = a;
}
+ printf("/**\n"
+ " * @ingroup iface_%s\n", interface->name);
+ if (m->description && m->description->text)
+ format_text_to_comment(m->description->text, false);
+ printf(" */\n");
if (ret && ret->interface_name == NULL)
printf("static inline void *\n");
else if (ret)
@@ -1104,6 +1190,17 @@ emit_event_wrappers(struct wl_list *message_list, struct interface *interface)
return;
wl_list_for_each(m, message_list, link) {
+ printf("/**\n"
+ " * @ingroup iface_%s\n"
+ " * Sends an %s event to the client owning the resource.\n",
+ interface->name,
+ m->name);
+ printf(" * @param resource_ The client's resource\n");
+ wl_list_for_each(a, &m->arg_list, link) {
+ if (a->summary)
+ printf(" * @param %s %s\n", a->name, a->summary);
+ }
+ printf(" */\n");
printf("static inline void\n"
"%s_send_%s(struct wl_resource *resource_",
interface->name, m->name);
@@ -1150,28 +1247,23 @@ emit_enumerations(struct interface *interface)
if (desc) {
printf("/**\n");
- desc_dump(desc->summary,
- " * %s_%s - ",
- interface->name, e->name);
- wl_list_for_each(entry, &e->entry_list, link) {
- desc_dump(entry->summary,
- " * @%s_%s_%s: ",
- interface->uppercase_name,
- e->uppercase_name,
- entry->uppercase_name);
- }
- if (desc->text) {
- printf(" *\n");
- desc_dump(desc->text, " * ");
- }
+ printf(" * @ingroup iface_%s\n", interface->name);
+ format_text_to_comment(desc->summary, false);
+ if (desc->text)
+ format_text_to_comment(desc->text, false);
printf(" */\n");
}
printf("enum %s_%s {\n", interface->name, e->name);
- wl_list_for_each(entry, &e->entry_list, link)
+ wl_list_for_each(entry, &e->entry_list, link) {
+ if (entry->summary)
+ printf("\t/**\n"
+ "\t * %s\n"
+ "\t */\n", entry->summary);
printf("\t%s_%s_%s = %s,\n",
interface->uppercase_name,
e->uppercase_name,
entry->uppercase_name, entry->value);
+ }
printf("};\n");
printf("#endif /* %s_%s_ENUM */\n\n",
interface->uppercase_name, e->uppercase_name);
@@ -1188,20 +1280,11 @@ emit_structs(struct wl_list *message_list, struct interface *interface, enum sid
if (wl_list_empty(message_list))
return;
- if (interface->description) {
- struct description *desc = interface->description;
- printf("/**\n");
- desc_dump(desc->summary, " * %s - ", interface->name);
- wl_list_for_each(m, message_list, link) {
- struct description *mdesc = m->description;
- desc_dump(mdesc ? mdesc->summary : "(none)",
- " * @%s: ",
- m->name);
- }
- printf(" *\n");
- desc_dump(desc->text, " * ");
- printf(" */\n");
- }
+ printf("/**\n");
+ printf(" * @ingroup iface_%s\n", interface->name);
+ printf(" * @struct %s_%s\n", interface->name,
+ (side == SERVER) ? "interface" : "listener");
+ printf(" */\n");
printf("struct %s_%s {\n", interface->name,
(side == SERVER) ? "interface" : "listener");
@@ -1209,24 +1292,24 @@ emit_structs(struct wl_list *message_list, struct interface *interface, enum sid
struct description *mdesc = m->description;
printf("\t/**\n");
- desc_dump(mdesc ? mdesc->summary : "(none)",
- "\t * %s - ", m->name);
+ if (mdesc) {
+ if (mdesc->summary)
+ printf("\t * %s\n", mdesc->summary);
+ printf("\t *\n");
+ desc_dump(mdesc->text, "\t * ");
+ }
wl_list_for_each(a, &m->arg_list, link) {
if (side == SERVER && a->type == NEW_ID &&
a->interface_name == NULL)
- printf("\t * @interface: name of the objects interface\n"
- "\t * @version: version of the objects interface\n");
-
+ printf("\t * @param interface name of the objects interface\n"
+ "\t * @param version version of the objects interface\n");
- desc_dump(a->summary ? a->summary : "(none)",
- "\t * @%s: ", a->name);
- }
- if (mdesc) {
- printf("\t *\n");
- desc_dump(mdesc->text, "\t * ");
+ if (a->summary)
+ printf("\t * @param %s %s\n", a->name,
+ a->summary);
}
if (m->since > 1) {
- printf("\t * @since: %d\n", m->since);
+ printf("\t * @since %d\n", m->since);
}
printf("\t */\n");
printf("\tvoid (*%s)(", m->name);
@@ -1266,6 +1349,9 @@ emit_structs(struct wl_list *message_list, struct interface *interface, enum sid
printf("};\n\n");
if (side == CLIENT) {
+ printf("/**\n"
+ " * @ingroup %s_iface\n"
+ " */\n", interface->name);
printf("static inline int\n"
"%s_add_listener(struct %s *%s,\n"
"%sconst struct %s_listener *listener, void *data)\n"
@@ -1282,30 +1368,6 @@ emit_structs(struct wl_list *message_list, struct interface *interface, enum sid
}
static void
-format_copyright(const char *copyright)
-{
- int bol = 1, start = 0, i;
-
- for (i = 0; copyright[i]; i++) {
- if (bol && (copyright[i] == ' ' || copyright[i] == '\t')) {
- continue;
- } else if (bol) {
- bol = 0;
- start = i;
- }
-
- if (copyright[i] == '\n' || copyright[i] == '\0') {
- printf("%s%s%.*s\n",
- i == 0 ? "/*" : " *",
- i > start ? " " : "",
- i - start, copyright + start);
- bol = 1;
- }
- }
- printf(" */\n\n");
-}
-
-static void
emit_types_forward_declarations(struct protocol *protocol,
struct wl_list *message_list,
struct wl_array *types)
@@ -1358,6 +1420,46 @@ get_include_name(bool core, enum side side)
}
static void
+emit_mainpage_blurb(const struct protocol *protocol, enum side side)
+{
+ struct interface *i;
+
+ printf("/**\n"
+ " * @page page_%s The %s protocol\n",
+ protocol->name, protocol->name);
+
+ if (protocol->description) {
+ if (protocol->description->summary) {
+ printf(" * %s\n"
+ " *\n", protocol->description->summary);
+ }
+
+ if (protocol->description->text) {
+ printf(" * @section page_desc_%s Description\n", protocol->name);
+ format_text_to_comment(protocol->description->text, false);
+ printf(" *\n");
+ }
+ }
+
+ printf(" * @section page_ifaces_%s Interfaces\n", protocol->name);
+ wl_list_for_each(i, &protocol->interface_list, link) {
+ printf(" * - @subpage page_iface_%s - %s\n",
+ i->name,
+ i->description && i->description->summary ? i->description->summary : "");
+ }
+
+ if (protocol->copyright) {
+ printf(" * @section page_copyright_%s Copyright\n",
+ protocol->name);
+ printf(" * <pre>\n");
+ format_text_to_comment(protocol->copyright, false);
+ printf(" * </pre>\n");
+ }
+
+ printf(" */\n");
+}
+
+static void
emit_header(struct protocol *protocol, enum side side)
{
struct interface *i, *i_next;
@@ -1365,24 +1467,25 @@ emit_header(struct protocol *protocol, enum side side)
const char *s = (side == SERVER) ? "SERVER" : "CLIENT";
char **p, *prev;
- if (protocol->copyright)
- format_copyright(protocol->copyright);
+ printf("/* Generated by wayland-scanner %s */\n\n", WAYLAND_VERSION);
printf("#ifndef %s_%s_PROTOCOL_H\n"
"#define %s_%s_PROTOCOL_H\n"
"\n"
- "#ifdef __cplusplus\n"
- "extern \"C\" {\n"
- "#endif\n"
- "\n"
"#include <stdint.h>\n"
"#include <stddef.h>\n"
"#include \"%s\"\n\n"
- "struct wl_client;\n"
- "struct wl_resource;\n\n",
+ "#ifdef __cplusplus\n"
+ "extern \"C\" {\n"
+ "#endif\n\n",
protocol->uppercase_name, s,
protocol->uppercase_name, s,
get_include_name(protocol->core_headers, side));
+ if (side == SERVER)
+ printf("struct wl_client;\n"
+ "struct wl_resource;\n\n");
+
+ emit_mainpage_blurb(protocol, side);
wl_array_init(&types);
wl_list_for_each(i, &protocol->interface_list, link) {
@@ -1407,6 +1510,24 @@ emit_header(struct protocol *protocol, enum side side)
printf("\n");
wl_list_for_each(i, &protocol->interface_list, link) {
+ printf("/**\n"
+ " * @page page_iface_%s %s\n",
+ i->name, i->name);
+ if (i->description && i->description->text) {
+ printf(" * @section page_iface_%s_desc Description\n",
+ i->name);
+ format_text_to_comment(i->description->text, false);
+ }
+ printf(" * @section page_iface_%s_api API\n"
+ " * See @ref iface_%s.\n"
+ " */\n",
+ i->name, i->name);
+ printf("/**\n"
+ " * @defgroup iface_%s The %s interface\n",
+ i->name, i->name);
+ if (i->description && i->description->text)
+ format_text_to_comment(i->description->text, false);
+ printf(" */\n");
printf("extern const struct wl_interface "
"%s_interface;\n", i->name);
}
@@ -1549,8 +1670,10 @@ emit_code(struct protocol *protocol)
struct wl_array types;
char **p, *prev;
+ printf("/* Generated by wayland-scanner %s */\n\n", WAYLAND_VERSION);
+
if (protocol->copyright)
- format_copyright(protocol->copyright);
+ format_text_to_comment(protocol->copyright, true);
printf("#include <stdlib.h>\n"
"#include <stdint.h>\n"
@@ -1623,9 +1746,12 @@ int main(int argc, char *argv[])
struct parse_context ctx;
struct protocol protocol;
FILE *input = stdin;
+ char *input_filename = NULL;
int len;
void *buf;
- bool help = false, core_headers = false;
+ bool help = false;
+ bool core_headers = false;
+ bool version = false;
bool fail = false;
int opt;
enum {
@@ -1636,12 +1762,13 @@ int main(int argc, char *argv[])
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
{ "include-core-only", no_argument, NULL, 'c' },
{ 0, 0, NULL, 0 }
};
while (1) {
- opt = getopt_long(argc, argv, "hc", options, NULL);
+ opt = getopt_long(argc, argv, "hvc", options, NULL);
if (opt == -1)
break;
@@ -1650,6 +1777,9 @@ int main(int argc, char *argv[])
case 'h':
help = true;
break;
+ case 'v':
+ version = true;
+ break;
case 'c':
core_headers = true;
break;
@@ -1664,6 +1794,8 @@ int main(int argc, char *argv[])
if (help)
usage(EXIT_SUCCESS);
+ else if (version)
+ scanner_version(EXIT_SUCCESS);
else if ((argc != 1 && argc != 3) || fail)
usage(EXIT_FAILURE);
else if (strcmp(argv[0], "help") == 0)
@@ -1678,7 +1810,8 @@ int main(int argc, char *argv[])
usage(EXIT_FAILURE);
if (argc == 3) {
- input = fopen(argv[1], "r");
+ input_filename = argv[1];
+ input = fopen(input_filename, "r");
if (input == NULL) {
fprintf(stderr, "Could not open input file: %s\n",
strerror(errno));
@@ -1700,9 +1833,12 @@ int main(int argc, char *argv[])
/* initialize context */
memset(&ctx, 0, sizeof ctx);
ctx.protocol = &protocol;
- ctx.loc.filename = "<stdin>";
+ if (input == stdin)
+ ctx.loc.filename = "<stdin>";
+ else
+ ctx.loc.filename = input_filename;
- if (!is_dtd_valid(input)) {
+ if (!is_dtd_valid(input, ctx.loc.filename)) {
fprintf(stderr,
"*******************************************************\n"
"* *\n"
diff --git a/src/wayland-client-core.h b/src/wayland-client-core.h
index 91f7e7b..b1d6515 100644
--- a/src/wayland-client-core.h
+++ b/src/wayland-client-core.h
@@ -132,6 +132,12 @@ struct wl_proxy *
wl_proxy_create(struct wl_proxy *factory,
const struct wl_interface *interface);
+void *
+wl_proxy_create_wrapper(void *proxy);
+
+void
+wl_proxy_wrapper_destroy(void *proxy_wrapper);
+
struct wl_proxy *
wl_proxy_marshal_constructor(struct wl_proxy *proxy,
uint32_t opcode,
diff --git a/src/wayland-client.c b/src/wayland-client.c
index ef12bfc..03c087a 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -51,7 +51,8 @@
enum wl_proxy_flag {
WL_PROXY_FLAG_ID_DELETED = (1 << 0),
- WL_PROXY_FLAG_DESTROYED = (1 << 1)
+ WL_PROXY_FLAG_DESTROYED = (1 << 1),
+ WL_PROXY_FLAG_WRAPPER = (1 << 2),
};
struct wl_proxy {
@@ -177,7 +178,7 @@ display_protocol_error(struct wl_display *display, uint32_t code,
return;
/* set correct errno */
- if (wl_interface_equal(intf, &wl_display_interface)) {
+ if (intf && wl_interface_equal(intf, &wl_display_interface)) {
switch (code) {
case WL_DISPLAY_ERROR_INVALID_OBJECT:
case WL_DISPLAY_ERROR_INVALID_METHOD:
@@ -252,9 +253,6 @@ decrease_closure_args_refcount(struct wl_closure *closure)
}
}
-void
-proxy_destroy(struct wl_proxy *proxy);
-
static void
wl_event_queue_release(struct wl_event_queue *queue)
{
@@ -404,7 +402,7 @@ wl_proxy_create_for_id(struct wl_proxy *factory,
return proxy;
}
-void
+static void
proxy_destroy(struct wl_proxy *proxy)
{
if (proxy->flags & WL_PROXY_FLAG_ID_DELETED)
@@ -428,6 +426,8 @@ proxy_destroy(struct wl_proxy *proxy)
*
* \param proxy The proxy to be destroyed
*
+ * \c proxy must not be a proxy wrapper.
+ *
* \memberof wl_proxy
*/
WL_EXPORT void
@@ -435,6 +435,9 @@ wl_proxy_destroy(struct wl_proxy *proxy)
{
struct wl_display *display = proxy->display;
+ if (proxy->flags & WL_PROXY_FLAG_WRAPPER)
+ wl_abort("Tried to destroy wrapper with wl_proxy_destroy()\n");
+
pthread_mutex_lock(&display->mutex);
proxy_destroy(proxy);
pthread_mutex_unlock(&display->mutex);
@@ -455,12 +458,17 @@ wl_proxy_destroy(struct wl_proxy *proxy)
* \c n, \c implementation[n] should point to the handler of \c n for
* the given object.
*
+ * \c proxy must not be a proxy wrapper.
+ *
* \memberof wl_proxy
*/
WL_EXPORT int
wl_proxy_add_listener(struct wl_proxy *proxy,
void (**implementation)(void), void *data)
{
+ if (proxy->flags & WL_PROXY_FLAG_WRAPPER)
+ wl_abort("Proxy %p is a wrapper\n", proxy);
+
if (proxy->object.implementation || proxy->dispatcher) {
wl_log("proxy %p already has listener\n", proxy);
return -1;
@@ -507,6 +515,8 @@ wl_proxy_get_listener(struct wl_proxy *proxy)
* The exact details of dispatcher_data depend on the dispatcher used. This
* function is intended to be used by language bindings, not user code.
*
+ * \c proxy must not be a proxy wrapper.
+ *
* \memberof wl_proxy
*/
WL_EXPORT int
@@ -514,6 +524,9 @@ wl_proxy_add_dispatcher(struct wl_proxy *proxy,
wl_dispatcher_func_t dispatcher,
const void *implementation, void *data)
{
+ if (proxy->flags & WL_PROXY_FLAG_WRAPPER)
+ wl_abort("Proxy %p is a wrapper\n", proxy);
+
if (proxy->object.implementation || proxy->dispatcher) {
wl_log("proxy %p already has listener\n", proxy);
return -1;
@@ -568,7 +581,7 @@ create_outgoing_proxy(struct wl_proxy *proxy, const struct wl_message *message,
*
* For new-id arguments, this function will allocate a new wl_proxy
* and send the ID to the server. The new wl_proxy will be returned
- * on success or NULL on errror with errno set accordingly. The newly
+ * on success or NULL on error with errno set accordingly. The newly
* created proxy will inherit their version from their parent.
*
* \note This is intended to be used by language bindings and not in
@@ -603,7 +616,7 @@ wl_proxy_marshal_array_constructor(struct wl_proxy *proxy,
*
* For new-id arguments, this function will allocate a new wl_proxy
* and send the ID to the server. The new wl_proxy will be returned
- * on success or NULL on errror with errno set accordingly. The newly
+ * on success or NULL on error with errno set accordingly. The newly
* created proxy will have the version specified.
*
* \note This is intended to be used by language bindings and not in
@@ -698,7 +711,7 @@ wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...)
*
* For new-id arguments, this function will allocate a new wl_proxy
* and send the ID to the server. The new wl_proxy will be returned
- * on success or NULL on errror with errno set accordingly. The newly
+ * on success or NULL on error with errno set accordingly. The newly
* created proxy will inherit their version from their parent.
*
* \note This should not normally be used by non-generated code.
@@ -736,7 +749,7 @@ wl_proxy_marshal_constructor(struct wl_proxy *proxy, uint32_t opcode,
*
* For new-id arguments, this function will allocate a new wl_proxy
* and send the ID to the server. The new wl_proxy will be returned
- * on success or NULL on errror with errno set accordingly. The newly
+ * on success or NULL on error with errno set accordingly. The newly
* created proxy will have the version specified.
*
* \note This should not normally be used by non-generated code.
@@ -790,12 +803,26 @@ display_handle_error(void *data,
uint32_t code, const char *message)
{
struct wl_proxy *proxy = object;
+ uint32_t object_id;
+ const struct wl_interface *interface;
+
+ if (proxy) {
+ wl_log("%s@%u: error %d: %s\n",
+ proxy->object.interface->name,
+ proxy->object.id,
+ code, message);
- wl_log("%s@%u: error %d: %s\n",
- proxy->object.interface->name, proxy->object.id, code, message);
+ object_id = proxy->object.id;
+ interface = proxy->object.interface;
+ } else {
+ wl_log("[destroyed object]: error %d: %s\n",
+ code, message);
- display_protocol_error(display, code, proxy->object.id,
- proxy->object.interface);
+ object_id = 0;
+ interface = NULL;
+ }
+
+ display_protocol_error(display, code, object_id, interface);
}
static void
@@ -1072,14 +1099,23 @@ static const struct wl_callback_listener sync_listener = {
WL_EXPORT int
wl_display_roundtrip_queue(struct wl_display *display, struct wl_event_queue *queue)
{
+ struct wl_display *display_wrapper;
struct wl_callback *callback;
int done, ret = 0;
done = 0;
- callback = wl_display_sync(display);
+
+ display_wrapper = wl_proxy_create_wrapper(display);
+ if (!display_wrapper)
+ return -1;
+
+ wl_proxy_set_queue((struct wl_proxy *) display_wrapper, queue);
+ callback = wl_display_sync(display_wrapper);
+ wl_proxy_wrapper_destroy(display_wrapper);
+
if (callback == NULL)
return -1;
- wl_proxy_set_queue((struct wl_proxy *) callback, queue);
+
wl_callback_add_listener(callback, &sync_listener, &done);
while (!done && ret >= 0)
ret = wl_display_dispatch_queue(display, queue);
@@ -1573,7 +1609,7 @@ wl_display_poll(struct wl_display *display, short int events)
* the appropriate event queues. Finally, events on given event queue are
* dispatched. On failure -1 is returned and errno set appropriately.
*
- * In a multi threaded enviroment, do not manually wait using poll() (or
+ * In a multi threaded environment, do not manually wait using poll() (or
* equivalent) before calling this function, as doing so might cause a dead
* lock. If external reliance on poll() (or equivalent) is required, see
* wl_display_prepare_read_queue() of how to do so.
@@ -1678,7 +1714,7 @@ wl_display_dispatch_queue_pending(struct wl_display *display,
* the appropriate event queues. Finally, events on the default event queue
* are dispatched. On failure -1 is returned and errno set appropriately.
*
- * In a multi threaded enviroment, do not manually wait using poll() (or
+ * In a multi threaded environment, do not manually wait using poll() (or
* equivalent) before calling this function, as doing so might cause a dead
* lock. If external reliance on poll() (or equivalent) is required, see
* wl_display_prepare_read_queue() of how to do so.
@@ -1756,10 +1792,12 @@ wl_display_get_error(struct wl_display *display)
/** Retrieves the information about a protocol error:
*
* \param display The Wayland display
- * \param interface if not NULL, stores the interface where the error occurred
+ * \param interface if not NULL, stores the interface where the error occurred,
+ * or NULL, if unknown.
* \param id if not NULL, stores the object id that generated
- * the error. There's no guarantee the object is
- * still valid; the client must know if it deleted the object.
+ * the error, or 0, if the object id is unknown. There's no
+ * guarantee the object is still valid; the client must know
+ * if it deleted the object.
* \return The error code as defined in the interface specification.
*
* \code
@@ -1939,6 +1977,98 @@ wl_proxy_set_queue(struct wl_proxy *proxy, struct wl_event_queue *queue)
proxy->queue = &proxy->display->default_queue;
}
+/** Create a proxy wrapper for making queue assignments thread-safe
+ *
+ * \param proxy The proxy object to be wrapped
+ * \return A proxy wrapper for the given proxy or NULL on failure
+ *
+ * A proxy wrapper is type of 'struct wl_proxy' instance that can be used when
+ * sending requests instead of using the original proxy. A proxy wrapper does
+ * not have an implementation or dispatcher, and events received on the
+ * object is still emitted on the original proxy. Trying to set an
+ * implementation or dispatcher will have no effect but result in a warning
+ * being logged.
+ *
+ * Setting the proxy queue of the proxy wrapper will make new objects created
+ * using the proxy wrapper use the set proxy queue.
+ * Even though there is no implementation nor dispatcher, the proxy queue can
+ * be changed. This will affect the default queue of new objects created by
+ * requests sent via the proxy wrapper.
+ *
+ * A proxy wrapper can only be destroyed using wl_proxy_wrapper_destroy().
+ *
+ * A proxy wrapper must be destroyed before the proxy it was created from.
+ *
+ * If a user reads and dispatches events on more than one thread, it is
+ * necessary to use a proxy wrapper when sending requests on objects when the
+ * intention is that a newly created proxy is to use a proxy queue different
+ * from the proxy the request was sent on, as creating the new proxy and then
+ * setting the queue is not thread safe.
+ *
+ * For example, a module that runs using its own proxy queue that needs to
+ * do display roundtrip must wrap the wl_display proxy object before sending
+ * the wl_display.sync request. For example:
+ *
+ * \code
+ *
+ * struct wl_event_queue *queue = ...;
+ * struct wl_display *wrapped_display;
+ * struct wl_callback *callback;
+ *
+ * wrapped_display = wl_proxy_create_wrapper(display);
+ * wl_proxy_set_queue((struct wl_proxy *) wrapped_display, queue);
+ * callback = wl_display_sync(wrapped_display);
+ * wl_proxy_wrapper_destroy(wrapped_display);
+ * wl_callback_add_listener(callback, ...);
+ *
+ * \endcode
+ *
+ * \memberof wl_proxy
+ */
+WL_EXPORT void *
+wl_proxy_create_wrapper(void *proxy)
+{
+ struct wl_proxy *wrapped_proxy = proxy;
+ struct wl_proxy *wrapper;
+
+ wrapper = zalloc(sizeof *wrapper);
+ if (!wrapper)
+ return NULL;
+
+ pthread_mutex_lock(&wrapped_proxy->display->mutex);
+
+ wrapper->object.interface = wrapped_proxy->object.interface;
+ wrapper->object.id = wrapped_proxy->object.id;
+ wrapper->version = wrapped_proxy->version;
+ wrapper->display = wrapped_proxy->display;
+ wrapper->queue = wrapped_proxy->queue;
+ wrapper->flags = WL_PROXY_FLAG_WRAPPER;
+ wrapper->refcount = 1;
+
+ pthread_mutex_unlock(&wrapped_proxy->display->mutex);
+
+ return wrapper;
+}
+
+/** Destroy a proxy wrapper
+ * \param proxy_wrapper The proxy wrapper to be destroyed
+ *
+ * \memberof wl_proxy
+ */
+WL_EXPORT void
+wl_proxy_wrapper_destroy(void *proxy_wrapper)
+{
+ struct wl_proxy *wrapper = proxy_wrapper;
+
+ if (!(wrapper->flags & WL_PROXY_FLAG_WRAPPER))
+ wl_abort("Tried to destroy non-wrapper proxy with "
+ "wl_proxy_wrapper_destroy\n");
+
+ assert(wrapper->refcount == 1);
+
+ free(wrapper);
+}
+
WL_EXPORT void
wl_log_set_handler_client(wl_log_func_t handler)
{
diff --git a/src/wayland-client.h b/src/wayland-client.h
index 3856535..9f70fa3 100644
--- a/src/wayland-client.h
+++ b/src/wayland-client.h
@@ -23,8 +23,11 @@
* SOFTWARE.
*/
-
-/** Use of this header file is discouraged. Prefer including
+/** \file
+ *
+ * \brief Include the client API and protocol C API.
+ *
+ * \warning Use of this header file is discouraged. Prefer including
* wayland-client-core.h instead, which does not include the
* client protocol header and as such only defines the library
* API.
diff --git a/src/wayland-private.h b/src/wayland-private.h
index 994bc45..045109b 100644
--- a/src/wayland-private.h
+++ b/src/wayland-private.h
@@ -55,6 +55,10 @@ struct wl_object {
extern struct wl_object global_zombie_object;
#define WL_ZOMBIE_OBJECT ((void*)&global_zombie_object)
+int
+wl_interface_equal(const struct wl_interface *iface1,
+ const struct wl_interface *iface2);
+
/* Flags for wl_map_insert_new and wl_map_insert_at. Flags can be queried with
* wl_map_lookup_flags. The current implementation has room for 1 bit worth of
* flags. If more flags are ever added, the implementation of wl_map will have
@@ -99,14 +103,6 @@ wl_map_lookup_flags(struct wl_map *map, uint32_t i);
void
wl_map_for_each(struct wl_map *map, wl_iterator_func_t func, void *data);
-struct wl_connection;
-struct wl_closure;
-struct wl_proxy;
-
-int
-wl_interface_equal(const struct wl_interface *iface1,
- const struct wl_interface *iface2);
-
struct wl_connection *
wl_connection_create(int fd);
diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h
index e8e1e9c..fa7f394 100644
--- a/src/wayland-server-core.h
+++ b/src/wayland-server-core.h
@@ -26,15 +26,15 @@
#ifndef WAYLAND_SERVER_CORE_H
#define WAYLAND_SERVER_CORE_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include <sys/types.h>
#include <stdint.h>
#include "wayland-util.h"
#include "wayland-version.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
enum {
WL_EVENT_READABLE = 0x01,
WL_EVENT_WRITABLE = 0x02,
diff --git a/src/wayland-server.c b/src/wayland-server.c
index 6654cd7..f745e62 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -730,6 +730,11 @@ registry_bind(struct wl_client *client,
wl_resource_post_error(resource,
WL_DISPLAY_ERROR_INVALID_OBJECT,
"invalid global %s (%d)", interface, name);
+ else if (version == 0)
+ wl_resource_post_error(resource,
+ WL_DISPLAY_ERROR_INVALID_OBJECT,
+ "invalid version for global %s (%d): 0 is not a valid version",
+ interface, name);
else if (global->version < version)
wl_resource_post_error(resource,
WL_DISPLAY_ERROR_INVALID_OBJECT,
@@ -1268,17 +1273,18 @@ wl_display_add_socket_fd(struct wl_display *display, int sock_fd)
if (s == NULL)
return -1;
- /* Reuse the existing fd */
- s->fd = sock_fd;
-
- s->source = wl_event_loop_add_fd(display->loop, s->fd,
+ s->source = wl_event_loop_add_fd(display->loop, sock_fd,
WL_EVENT_READABLE,
socket_data, display);
if (s->source == NULL) {
wl_log("failed to establish event source\n");
+ wl_socket_destroy(s);
return -1;
}
+ /* Reuse the existing fd */
+ s->fd = sock_fd;
+
wl_list_insert(display->socket_list.prev, &s->link);
return 0;
@@ -1302,7 +1308,7 @@ wl_display_add_socket_fd(struct wl_display *display, int sock_fd)
* fails and returns -1.
*
* The length of socket path, i.e., the path set in XDG_RUNTIME_DIR and the
- * socket name, must not exceed the maxium length of a Unix socket path.
+ * socket name, must not exceed the maximum length of a Unix socket path.
* The function also fails if the user do not have write permission in the
* XDG_RUNTIME_DIR path or if the socket name is already in use.
*
diff --git a/src/wayland-server.h b/src/wayland-server.h
index b6d0e2b..3124703 100644
--- a/src/wayland-server.h
+++ b/src/wayland-server.h
@@ -23,10 +23,13 @@
* SOFTWARE.
*/
-
-/** Use of this header file is discouraged. Prefer including
+/** \file
+ *
+ * \brief Include the server API, deprecations and protocol C API.
+ *
+ * \warning Use of this header file is discouraged. Prefer including
* wayland-server-core.h instead, which does not include the
- * client protocol header and as such only defines the library
+ * server protocol header and as such only defines the library
* API, excluding the deprecated API below.
*/
diff --git a/src/wayland-shm.c b/src/wayland-shm.c
index 8e7adc9..5efbd70 100644
--- a/src/wayland-shm.c
+++ b/src/wayland-shm.c
@@ -52,9 +52,11 @@ static struct sigaction wl_shm_old_sigbus_action;
struct wl_shm_pool {
struct wl_resource *resource;
- int refcount;
+ int internal_refcount;
+ int external_refcount;
char *data;
int32_t size;
+ int32_t new_size;
};
struct wl_shm_buffer {
@@ -73,10 +75,37 @@ struct wl_shm_sigbus_data {
};
static void
-shm_pool_unref(struct wl_shm_pool *pool)
+shm_pool_finish_resize(struct wl_shm_pool *pool)
{
- pool->refcount--;
- if (pool->refcount)
+ void *data;
+
+ if (pool->size == pool->new_size)
+ return;
+
+ data = mremap(pool->data, pool->size, pool->new_size, MREMAP_MAYMOVE);
+ if (data == MAP_FAILED) {
+ wl_resource_post_error(pool->resource,
+ WL_SHM_ERROR_INVALID_FD,
+ "failed mremap");
+ return;
+ }
+
+ pool->data = data;
+ pool->size = pool->new_size;
+}
+
+static void
+shm_pool_unref(struct wl_shm_pool *pool, bool external)
+{
+ if (external) {
+ pool->external_refcount--;
+ if (pool->external_refcount == 0)
+ shm_pool_finish_resize(pool);
+ } else {
+ pool->internal_refcount--;
+ }
+
+ if (pool->internal_refcount + pool->external_refcount)
return;
munmap(pool->data, pool->size);
@@ -89,7 +118,7 @@ destroy_buffer(struct wl_resource *resource)
struct wl_shm_buffer *buffer = wl_resource_get_user_data(resource);
if (buffer->pool)
- shm_pool_unref(buffer->pool);
+ shm_pool_unref(buffer->pool, false);
free(buffer);
}
@@ -117,7 +146,7 @@ format_is_supported(struct wl_client *client, uint32_t format)
default:
formats = wl_display_get_additional_shm_formats(display);
wl_array_for_each(p, formats)
- if(*p == format)
+ if (*p == format)
return true;
}
@@ -162,13 +191,13 @@ shm_pool_create_buffer(struct wl_client *client, struct wl_resource *resource,
buffer->stride = stride;
buffer->offset = offset;
buffer->pool = pool;
- pool->refcount++;
+ pool->internal_refcount++;
buffer->resource =
wl_resource_create(client, &wl_buffer_interface, 1, id);
if (buffer->resource == NULL) {
wl_client_post_no_memory(client);
- shm_pool_unref(pool);
+ shm_pool_unref(pool, false);
free(buffer);
return;
}
@@ -183,7 +212,7 @@ destroy_pool(struct wl_resource *resource)
{
struct wl_shm_pool *pool = wl_resource_get_user_data(resource);
- shm_pool_unref(pool);
+ shm_pool_unref(pool, false);
}
static void
@@ -197,7 +226,6 @@ shm_pool_resize(struct wl_client *client, struct wl_resource *resource,
int32_t size)
{
struct wl_shm_pool *pool = wl_resource_get_user_data(resource);
- void *data;
if (size < pool->size) {
wl_resource_post_error(resource,
@@ -206,16 +234,15 @@ shm_pool_resize(struct wl_client *client, struct wl_resource *resource,
return;
}
- data = mremap(pool->data, pool->size, size, MREMAP_MAYMOVE);
- if (data == MAP_FAILED) {
- wl_resource_post_error(resource,
- WL_SHM_ERROR_INVALID_FD,
- "failed mremap");
- return;
- }
+ pool->new_size = size;
- pool->data = data;
- pool->size = size;
+ /* If the compositor has taken references on this pool it
+ * may be caching pointers into it. In that case we
+ * defer the resize (which may move the entire mapping)
+ * until the compositor finishes dereferencing the pool.
+ */
+ if (pool->external_refcount == 0)
+ shm_pool_finish_resize(pool);
}
struct wl_shm_pool_interface shm_pool_interface = {
@@ -230,28 +257,30 @@ shm_create_pool(struct wl_client *client, struct wl_resource *resource,
{
struct wl_shm_pool *pool;
- pool = malloc(sizeof *pool);
- if (pool == NULL) {
- wl_client_post_no_memory(client);
- goto err_close;
- }
-
if (size <= 0) {
wl_resource_post_error(resource,
WL_SHM_ERROR_INVALID_STRIDE,
"invalid size (%d)", size);
- goto err_free;
+ goto err_close;
}
- pool->refcount = 1;
+ pool = malloc(sizeof *pool);
+ if (pool == NULL) {
+ wl_client_post_no_memory(client);
+ goto err_close;
+ }
+
+ pool->internal_refcount = 1;
+ pool->external_refcount = 0;
pool->size = size;
+ pool->new_size = size;
pool->data = mmap(NULL, size,
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (pool->data == MAP_FAILED) {
wl_resource_post_error(resource,
WL_SHM_ERROR_INVALID_FD,
"failed mmap fd %d", fd);
- goto err_close;
+ goto err_free;
}
close(fd);
@@ -270,10 +299,10 @@ shm_create_pool(struct wl_client *client, struct wl_resource *resource,
return;
-err_close:
- close(fd);
err_free:
free(pool);
+err_close:
+ close(fd);
}
static const struct wl_shm_interface shm_interface = {
@@ -358,6 +387,11 @@ wl_shm_buffer_get_data(struct wl_shm_buffer *buffer)
if (!buffer->pool)
return NULL;
+ if (buffer->pool->external_refcount &&
+ (buffer->pool->size != buffer->pool->new_size))
+ wl_log("Buffer address requested when its parent pool "
+ "has an external reference and a deferred resize "
+ "pending.\n");
return buffer->pool->data + buffer->offset;
}
@@ -396,9 +430,10 @@ wl_shm_buffer_get_height(struct wl_shm_buffer *buffer)
WL_EXPORT struct wl_shm_pool *
wl_shm_buffer_ref_pool(struct wl_shm_buffer *buffer)
{
- assert(buffer->pool->refcount);
+ assert(buffer->pool->internal_refcount +
+ buffer->pool->external_refcount);
- buffer->pool->refcount++;
+ buffer->pool->external_refcount++;
return buffer->pool;
}
@@ -418,7 +453,7 @@ wl_shm_buffer_ref_pool(struct wl_shm_buffer *buffer)
WL_EXPORT void
wl_shm_pool_unref(struct wl_shm_pool *pool)
{
- shm_pool_unref(pool);
+ shm_pool_unref(pool, true);
}
static void
diff --git a/src/wayland-util.c b/src/wayland-util.c
index e782309..5bfb7e1 100644
--- a/src/wayland-util.c
+++ b/src/wayland-util.c
@@ -35,6 +35,19 @@
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)
{
@@ -123,11 +136,11 @@ wl_array_add(struct wl_array *array, size_t size)
if (array->alloc < alloc) {
if (array->alloc > 0)
data = realloc(array->data, alloc);
- else
+ else
data = malloc(alloc);
if (data == NULL)
- return 0;
+ return NULL;
array->data = data;
array->alloc = alloc;
}
diff --git a/src/wayland-util.h b/src/wayland-util.h
index 35b50ea..8da156c 100644
--- a/src/wayland-util.h
+++ b/src/wayland-util.h
@@ -31,15 +31,15 @@
#ifndef WAYLAND_UTIL_H
#define WAYLAND_UTIL_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include <math.h>
#include <stddef.h>
#include <inttypes.h>
#include <stdarg.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* GCC visibility */
#if defined(__GNUC__) && __GNUC__ >= 4
#define WL_EXPORT __attribute__ ((visibility("default")))
@@ -300,7 +300,7 @@ union wl_argument {
* A dispatcher takes five arguments: The first is the dispatcher-specific
* implementation data associated with the target object. The second is the
* object on which the callback is being invoked (either wl_proxy or
- * wl_resource). The third and fourth arguments are the opcode the wl_messsage
+ * wl_resource). The third and fourth arguments are the opcode the wl_message
* structure corresponding to the callback being emitted. The final argument
* is an array of arguments received from the other process via the wire
* protocol.
diff --git a/tests/display-test.c b/tests/display-test.c
index 1a6c345..17956db 100644
--- a/tests/display-test.c
+++ b/tests/display-test.c
@@ -211,8 +211,6 @@ find_client_info(struct display *d, struct wl_client *client)
{
struct client_info *ci;
- /* find the right client_info struct and save the
- * resource as its data, so that we can use it later */
wl_list_for_each(ci, &d->clients, link) {
if (ci->wl_client == client)
return ci;
@@ -235,6 +233,8 @@ bind_seat(struct wl_client *client, void *data,
res = wl_resource_create(client, &wl_seat_interface, vers, id);
assert(res);
+ /* save the resource as client's info data,
+ * so that we can use it later */
ci->data = res;
}
@@ -876,3 +876,53 @@ TEST(versions)
display_destroy(d);
}
+
+static void
+check_error_on_destroyed_object(void *data)
+{
+ struct client *c;
+ struct wl_seat *seat;
+ uint32_t id;
+ const struct wl_interface *intf;
+
+ c = client_connect();
+ seat = client_get_seat(c);
+
+ /* destroy the seat proxy. The display won't know
+ * about it yet, so it will post the error as usual */
+ wl_proxy_destroy((struct wl_proxy *) seat);
+
+ /* let display post the error. The error will
+ * be caught in stop_display while dispatching */
+ assert(stop_display(c, 1) == -1);
+
+ /* check the returned error. Since the object was destroyed,
+ * we don't know the interface and id */
+ assert(wl_display_get_error(c->wl_display) == EPROTO);
+ assert(wl_display_get_protocol_error(c->wl_display, &intf, &id) == 23);
+ assert(intf == NULL);
+ assert(id == 0);
+
+ client_disconnect_nocheck(c);
+}
+
+TEST(error_on_destroyed_object)
+{
+ struct client_info *cl;
+ struct display *d = display_create();
+
+ wl_global_create(d->wl_display, &wl_seat_interface,
+ 1, d, bind_seat);
+
+ cl = client_create_noarg(d, check_error_on_destroyed_object);
+ display_run(d);
+
+ /* did client bind to the seat? */
+ assert(cl->data);
+
+ /* post error on the destroyed object */
+ wl_resource_post_error((struct wl_resource *) cl->data,
+ 23, "Dummy error");
+ display_resume(d);
+ display_destroy(d);
+}
diff --git a/tests/headers-protocol-core-test.c b/tests/headers-protocol-core-test.c
index aabcb0b..5c2baf3 100644
--- a/tests/headers-protocol-core-test.c
+++ b/tests/headers-protocol-core-test.c
@@ -26,6 +26,13 @@
#include "wayland-client-protocol-core.h"
#include "wayland-server-protocol-core.h"
+#ifndef WAYLAND_CLIENT_CORE_H
+#error including wayland-client-protocol-core.h did not include wayland-client-core.h!
+#endif
+#ifndef WAYLAND_SERVER_CORE_H
+#error including wayland-server-protocol-core.h did not include wayland-server-core.h!
+#endif
+
#ifdef WAYLAND_CLIENT_H
#error including wayland-client-protocol-core.h included wayland-client.h!
#endif
diff --git a/tests/queue-test.c b/tests/queue-test.c
index 02865ae..932bc55 100644
--- a/tests/queue-test.c
+++ b/tests/queue-test.c
@@ -205,6 +205,104 @@ client_test_queue_roundtrip(void)
}
static void
+client_test_queue_proxy_wrapper(void)
+{
+ struct wl_event_queue *queue;
+ struct wl_display *display;
+ struct wl_display *display_wrapper;
+ struct wl_callback *callback;
+ bool done = false;
+
+ /*
+ * For an illustration of what usage would normally fail without using
+ * proxy wrappers, see the `client_test_queue_set_queue_race' test case.
+ */
+
+ display = wl_display_connect(NULL);
+ assert(display);
+
+ /* Pretend we are in a separate thread where a thread-local queue is
+ * used. */
+ queue = wl_display_create_queue(display);
+ assert(queue);
+
+ display_wrapper = wl_proxy_create_wrapper(display);
+ assert(display_wrapper);
+ wl_proxy_set_queue((struct wl_proxy *) display_wrapper, queue);
+ callback = wl_display_sync(display_wrapper);
+ wl_proxy_wrapper_destroy(display_wrapper);
+ assert(callback != NULL);
+
+ /* Pretend we are now another thread and dispatch the dispatch the main
+ * queue while also knowing our callback is read and queued. */
+ wl_display_roundtrip(display);
+
+ /* Make sure that the pretend-to-be main thread didn't dispatch our
+ * callback, behind our back. */
+ wl_callback_add_listener(callback, &sync_listener_roundtrip, &done);
+ wl_display_flush(display);
+
+ assert(!done);
+
+ /* Make sure that we eventually end up dispatching our callback. */
+ while (!done)
+ assert(wl_display_dispatch_queue(display, queue) != -1);
+
+ wl_callback_destroy(callback);
+ wl_event_queue_destroy(queue);
+
+ wl_display_disconnect(display);
+}
+
+static void
+client_test_queue_set_queue_race(void)
+{
+ struct wl_event_queue *queue;
+ struct wl_display *display;
+ struct wl_callback *callback;
+ bool done = false;
+
+ /*
+ * This test illustrates the multi threading scenario which would fail
+ * without doing what is done in the `client_test_queue_proxy_wrapper'
+ * test.
+ */
+
+ display = wl_display_connect(NULL);
+ assert(display);
+
+ /* Pretend we are in a separate thread where a thread-local queue is
+ * used. */
+ queue = wl_display_create_queue(display);
+ assert(queue);
+
+ callback = wl_display_sync(display);
+ assert(callback != NULL);
+
+ /* Pretend we are now another thread and dispatch the dispatch the main
+ * queue while also knowing our callback is read, queued on the wrong
+ * queue, and dispatched. */
+ wl_display_roundtrip(display);
+
+ /* Pretend we are back in the separate thread, and continue with setting
+ * up our callback. */
+ wl_callback_add_listener(callback, &sync_listener_roundtrip, &done);
+ wl_proxy_set_queue((struct wl_proxy *) callback, queue);
+
+ /* Roundtrip our separate thread queue to make sure any events are
+ * dispatched. */
+ wl_display_roundtrip_queue(display, queue);
+
+ /* Verify that the callback has indeed been dropped. */
+ assert(!done);
+
+ wl_callback_destroy(callback);
+ wl_event_queue_destroy(queue);
+
+ wl_display_disconnect(display);
+}
+
+static void
dummy_bind(struct wl_client *client,
void *data, uint32_t version, uint32_t id)
{
@@ -259,3 +357,27 @@ TEST(queue_roundtrip)
display_destroy(d);
}
+
+TEST(queue_set_queue_proxy_wrapper)
+{
+ struct display *d = display_create();
+
+ test_set_timeout(2);
+
+ client_create_noarg(d, client_test_queue_proxy_wrapper);
+ display_run(d);
+
+ display_destroy(d);
+}
+
+TEST(queue_set_queue_race)
+{
+ struct display *d = display_create();
+
+ test_set_timeout(2);
+
+ client_create_noarg(d, client_test_queue_set_queue_race);
+ display_run(d);
+
+ display_destroy(d);
+}
diff --git a/tests/resources-test.c b/tests/resources-test.c
index ea88afb..337f9f9 100644
--- a/tests/resources-test.c
+++ b/tests/resources-test.c
@@ -45,7 +45,7 @@ TEST(create_resource_tst)
client = wl_client_create(display, s[0]);
assert(client);
- res = wl_resource_create(client, &wl_display_interface, 4, 0);
+ res = wl_resource_create(client, &wl_seat_interface, 4, 0);
assert(res);
/* setters/getters */
@@ -105,7 +105,7 @@ TEST(destroy_res_tst)
client = wl_client_create(display, s[0]);
assert(client);
- res = wl_resource_create(client, &wl_display_interface, 4, 0);
+ res = wl_resource_create(client, &wl_seat_interface, 4, 0);
assert(res);
wl_resource_set_implementation(res, NULL, &destroyed, res_destroy_func);
wl_resource_add_destroy_listener(res, &destroy_listener);
@@ -119,7 +119,7 @@ TEST(destroy_res_tst)
assert(notify_called); /* check if signal was emitted */
assert(wl_client_get_object(client, id) == NULL);
- res = wl_resource_create(client, &wl_display_interface, 2, 0);
+ res = wl_resource_create(client, &wl_seat_interface, 2, 0);
assert(res);
destroyed = 0;
notify_called = 0;
@@ -149,13 +149,13 @@ TEST(create_resource_with_same_id)
client = wl_client_create(display, s[0]);
assert(client);
- res = wl_resource_create(client, &wl_display_interface, 2, 0);
+ res = wl_resource_create(client, &wl_seat_interface, 2, 0);
assert(res);
id = wl_resource_get_id(res);
assert(wl_client_get_object(client, id) == res);
/* this one should replace the old one */
- res2 = wl_resource_create(client, &wl_display_interface, 1, id);
+ res2 = wl_resource_create(client, &wl_seat_interface, 1, id);
assert(res2 != NULL);
assert(wl_client_get_object(client, id) == res2);
diff --git a/tests/test-runner.c b/tests/test-runner.c
index 742b4f0..4aa6667 100644
--- a/tests/test-runner.c
+++ b/tests/test-runner.c
@@ -205,7 +205,7 @@ run_test(const struct test *t)
t->run();
- /* turn off timeout (if any) after test completition */
+ /* turn off timeout (if any) after test completion */
if (timeouts_enabled)
alarm(0);