Compare commits

..

No commits in common. "main" and "1.23.0" have entirely different histories.
main ... 1.23.0

38 changed files with 416 additions and 1972 deletions

View file

@ -43,7 +43,7 @@ include:
# API changes. If you need new features from ci-templates you must bump
# this to the current SHA you require from the ci-templates repo, however
# be aware that you may need to account for API changes when doing so.
ref: 48c2c583a865bd59be21e8938df247faf460099c
ref: b791bd48996e3ced9ca13f1c5ee82be8540b8adb
file:
- '/templates/debian.yml'
- '/templates/freebsd.yml'
@ -62,13 +62,6 @@ stages:
- "Build and test"
- "Other build configurations"
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_COMMIT_BRANCH
.ci-rules:
rules:
- when: on_success
@ -82,7 +75,7 @@ workflow:
FDO_DISTRIBUTION_EXEC: 'pip3 install --break-system-packages meson~=0.57.2'
# bump this tag every time you change something which requires rebuilding the
# base image
FDO_DISTRIBUTION_TAG: "2025-01-21.1"
FDO_DISTRIBUTION_TAG: "2024-03-28.2"
.debian-x86_64:
extends:
@ -101,7 +94,6 @@ workflow:
- .os-debian
variables:
BUILD_ARCH: "armv7"
FDO_DISTRIBUTION_PLATFORM: "linux/arm/v7"
# Does not inherit .ci-rules as we only want it to run in MR context.
@ -155,6 +147,7 @@ armv7-debian-container_prep:
stage: "Base container"
variables:
GIT_STRATEGY: none
FDO_BASE_IMAGE: "arm32v7/debian:$FDO_DISTRIBUTION_VERSION"
# Core build environment.
@ -306,11 +299,11 @@ armv7-release-debian-build:
.os-freebsd:
variables:
BUILD_OS: freebsd
FDO_DISTRIBUTION_VERSION: "14.3"
FDO_DISTRIBUTION_VERSION: "13.2"
FDO_DISTRIBUTION_PACKAGES: 'libxslt meson ninja pkgconf expat libffi libepoll-shim libxml2'
# bump this tag every time you change something which requires rebuilding the
# base image
FDO_DISTRIBUTION_TAG: "2025-07-20.0"
FDO_DISTRIBUTION_TAG: "2023-08-02.0"
# Don't build documentation since installing the required tools massively
# increases the VM image (and therefore container) size.
MESON_ARGS: "--fatal-meson-warnings -Dwerror=true -Ddocumentation=false"

View file

@ -29,6 +29,7 @@
* http://fontforge.org/pcf-format.html
*/
#include <assert.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>

View file

@ -27,7 +27,6 @@
#include "xcursor.h"
#include "wayland-cursor.h"
#include "wayland-client.h"
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@ -69,16 +68,11 @@ shm_pool_create(struct wl_shm *shm, int size)
goto err_close;
pool->pool = wl_shm_create_pool(shm, pool->fd, size);
if (!pool->pool)
goto err_unmap;
pool->size = size;
pool->used = 0;
return pool;
err_unmap:
munmap(pool->data, size);
err_close:
close(pool->fd);
err_free:
@ -285,8 +279,7 @@ wl_cursor_create_from_xcursor_images(struct xcursor_images *images,
{
struct cursor *cursor;
struct cursor_image *image;
size_t size;
int i;
int i, size;
cursor = malloc(sizeof *cursor);
if (!cursor)
@ -316,12 +309,7 @@ wl_cursor_create_from_xcursor_images(struct xcursor_images *images,
image->image.hotspot_y = images->images[i]->yhot;
image->image.delay = images->images[i]->delay;
size = (size_t) image->image.width * image->image.height * 4;
if (size > INT_MAX) {
free(image);
break;
}
size = image->image.width * image->image.height * 4;
image->offset = shm_pool_allocate(theme->pool, size);
if (image->offset < 0) {
free(image);
@ -351,8 +339,6 @@ load_callback(struct xcursor_images *images, void *data)
{
struct wl_cursor_theme *theme = data;
struct wl_cursor *cursor;
struct wl_cursor **p;
size_t s;
if (wl_cursor_theme_get_cursor(theme, images->name)) {
xcursor_images_destroy(images);
@ -362,14 +348,15 @@ load_callback(struct xcursor_images *images, void *data)
cursor = wl_cursor_create_from_xcursor_images(images, theme);
if (cursor) {
s = theme->cursor_count + 1;
p = realloc(theme->cursors, s * sizeof theme->cursors[0]);
theme->cursor_count++;
theme->cursors =
realloc(theme->cursors,
theme->cursor_count * sizeof theme->cursors[0]);
if (p == NULL) {
if (theme->cursors == NULL) {
theme->cursor_count--;
free(cursor);
} else {
theme->cursor_count = s;
theme->cursors = p;
theme->cursors[theme->cursor_count - 1] = cursor;
}
}
@ -397,9 +384,6 @@ wl_cursor_theme_load(const char *name, int size, struct wl_shm *shm)
if (!theme)
return NULL;
if (size < 0 || (size > 0 && INT_MAX / size / 4 < size))
goto err;
if (!name)
name = "default";
@ -409,7 +393,7 @@ wl_cursor_theme_load(const char *name, int size, struct wl_shm *shm)
theme->pool = shm_pool_create(shm, size * size * 4);
if (!theme->pool)
goto err;
goto out_error_pool;
xcursor_load_theme(name, size, load_callback, theme);
@ -421,7 +405,7 @@ wl_cursor_theme_load(const char *name, int size, struct wl_shm *shm)
return theme;
err:
out_error_pool:
free(theme);
return NULL;
}

View file

@ -259,8 +259,6 @@ xcursor_read_file_header(FILE *file)
return NULL;
if (!xcursor_read_uint(file, &head.ntoc))
return NULL;
if (head.header < XCURSOR_FILE_HEADER_LEN)
return NULL;
skip = head.header - XCURSOR_FILE_HEADER_LEN;
if (skip)
if (fseek(file, skip, SEEK_CUR) == EOF)
@ -573,7 +571,7 @@ xcursor_build_theme_dir(const char *dir, const char *theme)
* add space for any needed directory separators, one per component,
* and one for the trailing null
*/
full_size = (size_t) 1 + homelen + 1 + dirlen + 1 + themelen + 1;
full_size = 1 + homelen + 1 + dirlen + 1 + themelen + 1;
full = malloc(full_size);
if (!full)
return NULL;
@ -688,15 +686,11 @@ load_all_cursors_from_dir(const char *path, int size,
void *user_data)
{
FILE *f;
DIR *dir;
DIR *dir = opendir(path);
struct dirent *ent;
char *full;
struct xcursor_images *images;
if (!path)
return;
dir = opendir(path);
if (!dir)
return;
@ -804,14 +798,14 @@ xcursor_load_theme_protected(const char *theme, int size,
free(xcursor_path);
}
/** Load all the cursors of a theme
/** Load all the cursor of a theme
*
* This function loads all the cursor images of a given theme and its
* inherited themes. Each cursor is loaded into a struct xcursor_images object
* inherited themes. Each cursor is loaded into an struct xcursor_images object
* which is passed to the caller's load callback. If a cursor appears
* more than once across all the inherited themes, the load callback
* will be called multiple times, with possibly different struct xcursor_images
* objects which have the same name. The user is expected to destroy the
* object which have the same name. The user is expected to destroy the
* struct xcursor_images objects passed to the callback with
* xcursor_images_destroy().
*

View file

@ -1,139 +0,0 @@
<?xml version='1.0' encoding='utf-8' ?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "Wayland.ent">
%BOOK_ENTITIES;
]>
<chapter id="chap-Color-Management">
<title>Color management</title>
<section id="sect-Color-Management-preface">
<title>Overview</title>
<para>
Color management in Wayland considers only displays. All pictures in
Wayland are always display-referred, meaning that the pixel values are
intended as-is for some specific display where they would produce the
light emissions (<ulink
url="https://cie.co.at/eilvterm/17-23-002">stimuli</ulink>) the picture's
author desired. Wayland does not support displaying "raw" camera or
scanner images as they are not display-referred, nor are they even
pictures without complex and subjective processing.
</para>
<para>
Stimuli — the picture itself — are only half of the picture reproduction.
The other half is the environment where a display is viewed. A striking
example is comparing a brightly lit office to a dark movie theater, the
stimuli required to produce a good reading of the picture is greatly
different. Therefore display-referred does not include only the display
but the viewing environment as well.
</para>
<para>
Window systems have been very well capable of operating without any
explicit consideration to color management. This is because there used to
be the implicit assumption of the standard display, the sRGB display,
which all computer monitors implemented, more or less. The viewing
environment was and still is accounted by adjusting the display and/or the
room to produce a workable experience. Pictures are authored on a computer
system by drawing, painting and adjusting the picture until it looks right
on the author's monitor. This implicitly builds the standard display and
environment assumption into the picture data. Deviations from the sRGB
specification were minor enough that they often did not matter if not in a
professional context like the printing industry. Displaying video material
required some more attention to the details, because video and television
standards differ enough from the sRGB display. What really made explicit
color management a hard requirement for entertainment is the coming of
wide color gamut (WCG) and high dynamic range (HDR) materials and
displays.
</para>
<para>
The color management design in Wayland follows the general Wayland design
principles: compositors tell clients what would be the optimal thing to
do, clients tell the compositors what kind of pictures they are actually
producing, and then compositors display those pictures the best they can.
</para>
</section>
<section id="sect-Color-Management-Protocol">
<title>Protocol Interfaces</title>
<para>
Color management interfaces in Wayland and divided into two protocols:
<ulink url="https://gitlab.freedesktop.org/wayland/wayland-protocols/-/tree/main/staging/color-management?ref_type=heads">color-management</ulink>
and
<ulink url="https://gitlab.freedesktop.org/wayland/wayland-protocols/-/tree/main/staging/color-representation?ref_type=heads">color-representation</ulink>.
They are designed to work together, but they can also be used
independently when the other one is not needed.
</para>
<section id="sect-Color-Management-Protocol-color-management">
<title>Color-management</title>
<para>
Color management protocol has two main purposes. First, it puts the
responsibility of color management on the compositor. This means that
clients do not necessarily need to care about color management at all,
and can display just fine by using the traditional standard display
assumption even when the actual display is wildly different. Clients
can also choose to target some other assumed display and let the
compositor handle it, or they can explicitly render for the actual
display at hand. Second, when the window system has multiple different
monitors, and a wl_surface happens to span more than one monitor, the
compositor can display the surface content correctly on all spanned
monitors simultaneously, as much as physically possible.
</para>
<para>
Color-management protocol concentrates on colorimetry: when you have a
pixel with RGB values, what stimulus do those values represent. The
stimulus definition follows the CIE 1931 two-degree observer model. Some
core concepts here are color primaries, white point, transfer function,
and dynamic range. The viewing environment is represented in an
extremely simplified way as the reference white luminance. The
connection between pixel RGB values and stimulus plus viewing
environment is recorded in an <emphasis>image description</emphasis>
object. Clients can create image description objects and tag
<code>wl_surface</code>s with them, to indicate what kind of surface
content there will be. Clients can also ask what image description the
compositor would prefer to have on the <code>wl_surface</code>, and that
preference can change over time, e.g. when the <code>wl_surface</code>
is moved from one
<code>wl_output</code> to another. Following the compositor's preference
may provide advantages in image quality and power consumption.
</para>
<para>
Image description objects can come in two flavors: parametric and
ICC-based. The above was written with parametric image descriptions in
mind, and they have first-class support for HDR. ICC-based image
descriptions are wrapping an ICC profile and have no other data. ICC
profiles are the standard tool for standard dynamic range (SDR) display
color management. This means the capabilities between the two flavors
differ, and one cannot always be replaced by the other. Compositor
support for each flavor is optional.
</para>
</section>
<section id="sect-Color-Management-Protocol-color-representation">
<title>Color-representation</title>
<para>
Color-representation protocol deals with (potentially sub-sampled)
YCbCr-RGB conversion, quantization range, and the inclusion of alpha in
the RGB color channels, a.k.a. pre-multiplication. There are several
different specifications on how an YCbCr-like (including ICtCp) signal,
with chroma sub-sampling or not, is created from a full-resolution RGB
image. Again, a client can tag a <code>wl_surface</code> with
color-representation metadata to tell the compositor what kind of pixel
data will be displayed through the wl_surface.
</para>
<para>
The main purpose of color-representation is to correctly off-load the
YCbCr-RGB conversion to the compositor, which can then opportunistically
off-load it further to very power-efficient fixed-function circuitry in
a display controller. This can significantly reduce power consumption
when watching videos compared to using a GPU for the same, and on some
embedded hardware platforms it is a hard requirement for processing high
resolution video.
</para>
</section>
</section>
</chapter>

View file

@ -87,7 +87,7 @@
</para>
<para>
Overall, the philosophy of Wayland is to provide clients with a way to
manage windows and how their contents are displayed. Rendering is left
manage windows and how their contents is displayed. Rendering is left
to clients, and system wide memory management interfaces are used to
pass buffer handles between clients and the compositing manager.
</para>

View file

@ -97,9 +97,7 @@
in the environment). Beginning in Wayland 1.15, implementations can
optionally support server socket endpoints located at arbitrary
locations in the filesystem by setting <emphasis>WAYLAND_DISPLAY</emphasis>
to the absolute path at which the server endpoint listens. The socket may
also be provided through file descriptor inheritance, in which case
<emphasis>WAYLAND_SOCKET</emphasis> is set.
to the absolute path at which the server endpoint listens.
</para>
<para>
Every message is structured as 32-bit words; values are represented in the
@ -152,10 +150,9 @@
<listitem>
<para>
Starts with an unsigned 32-bit length (including null terminator),
followed by the UTF-8 encoded string contents, including
terminating null byte, then padding to a 32-bit boundary. A null
value is represented with a length of 0. Interior null bytes are
not permitted.
followed by the string contents, including terminating null byte,
then padding to a 32-bit boundary. A null value is represented
with a length of 0.
</para>
</listitem>
</varlistentry>

View file

@ -12,7 +12,6 @@
<xi:include href="Architecture.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Protocol.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Xwayland.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Color.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="ProtocolSpec.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Client.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="Server.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>

View file

@ -54,7 +54,6 @@ publican_sources = [
'Protocol.xml',
'Xwayland.xml',
'Compositors.xml',
'Color.xml',
'Client.xml',
'Server.xml'
]

View file

@ -22,7 +22,6 @@ if get_option('tests')
test(
'wayland-egl symbols check',
find_program('wayland-egl-symbols-check'),
depends: wayland_egl,
env: [
'WAYLAND_EGL_LIB=@0@'.format(wayland_egl_shared.full_path()),
'NM=@0@'.format(nm_path)

View file

@ -1,6 +1,6 @@
project(
'wayland', 'c',
version: '1.24.90',
version: '1.23.0',
license: 'MIT',
meson_version: '>= 0.57.0',
default_options: [
@ -46,7 +46,6 @@ have_funcs = [
'memfd_create',
'mremap',
'strndup',
'gettid',
]
foreach f: have_funcs
config_h.set('HAVE_' + f.underscorify().to_upper(), cc.has_function(f))
@ -132,9 +131,7 @@ if get_option('scanner')
'wayland-scanner.mk',
'protocol/wayland.xml',
'protocol/wayland.dtd',
],
install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'wayland'),
)
])
install_data(
[ 'wayland-scanner.m4' ],

View file

@ -501,10 +501,8 @@
<event name="release">
<description summary="compositor releases buffer">
Sent when this wl_buffer is no longer used by the compositor.
For more information on when release events may or may not be sent,
and what consequences it has, please see the description of
wl_surface.attach.
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
@ -1506,8 +1504,7 @@
the delivery of wl_buffer.release events becomes undefined. A well
behaved client should not rely on wl_buffer.release events in this
case. Alternatively, a client could create multiple wl_buffer objects
from the same backing storage or use a protocol extension providing
per-commit release notifications.
from the same backing storage or use wp_linux_buffer_release.
Destroying the wl_buffer after wl_buffer.release does not change
the surface contents. Destroying the wl_buffer before wl_buffer.release
@ -1835,9 +1832,6 @@
x and y, combined with the new surface size define in which
directions the surface's size changes.
The exact semantics of wl_surface.offset are role-specific. Refer to
the documentation of specific roles for more information.
Surface location offset is double-buffered state, see
wl_surface.commit.
@ -1886,7 +1880,7 @@
</event>
</interface>
<interface name="wl_seat" version="10">
<interface name="wl_seat" version="9">
<description summary="group of input devices">
A seat is a group of keyboards, pointer and touch devices. This
object is published as a global during start up, or when such a
@ -1914,10 +1908,9 @@
<event name="capabilities">
<description summary="seat capabilities changed">
This is sent on binding to the seat global or whenever a seat gains
or loses the pointer, keyboard or touch capabilities.
The argument is a capability enum containing the complete set of
capabilities this seat has.
This is emitted whenever a seat gains or loses the pointer,
keyboard or touch capabilities. The argument is a capability
enum containing the complete set of capabilities this seat has.
When the pointer capability is added, a client may create a
wl_pointer object using the wl_seat.get_pointer request. This object
@ -1999,9 +1992,9 @@
The same seat names are used for all clients. Thus, the name can be
shared across processes to refer to a specific wl_seat global.
The name event is sent after binding to the seat global, and should be sent
before announcing capabilities. This event only sent once per seat object,
and the name does not change over the lifetime of the wl_seat global.
The name event is sent after binding to the seat global. This event is
only sent once per seat object, and the name does not change over the
lifetime of the wl_seat global.
Compositors may re-use the same seat name if the wl_seat global is
destroyed and re-created later.
@ -2020,7 +2013,7 @@
</interface>
<interface name="wl_pointer" version="10">
<interface name="wl_pointer" version="9">
<description summary="pointer input device">
The wl_pointer interface represents one or more input devices,
such as mice, which control the pointer location and pointer_focus
@ -2433,7 +2426,7 @@
</event>
</interface>
<interface name="wl_keyboard" version="10">
<interface name="wl_keyboard" version="9">
<description summary="keyboard input device">
The wl_keyboard interface represents one or more keyboards
associated with a seat.
@ -2486,9 +2479,6 @@
the surface argument and the keys currently logically down to the keys
in the keys argument. The compositor must not send this event if the
wl_keyboard already had an active surface immediately before this event.
Clients should not use the list of pressed keys to emulate key-press
events. The order of keys in the list is unspecified.
</description>
<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"/>
@ -2515,18 +2505,9 @@
<enum name="key_state">
<description summary="physical key state">
Describes the physical state of a key that produced the key event.
Since version 10, the key can be in a "repeated" pseudo-state which
means the same as "pressed", but is used to signal repetition in the
key event.
The key may only enter the repeated state after entering the pressed
state and before entering the released state. This event may be
generated multiple times while the key is down.
</description>
<entry name="released" value="0" summary="key is not pressed"/>
<entry name="pressed" value="1" summary="key is pressed"/>
<entry name="repeated" value="2" summary="key was repeated" since="10"/>
</enum>
<event name="key">
@ -2549,11 +2530,6 @@
compositor must not send this event if state is pressed (resp. released)
and the key was already logically down (resp. was not logically down)
immediately before this event.
Since version 10, compositors may send key events with the "repeated"
key state when a wl_keyboard.repeat_info event with a rate argument of
0 has been received. This allows the compositor to take over the
responsibility of key repetition.
</description>
<arg name="serial" type="uint" summary="serial number of the key event"/>
<arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
@ -2614,7 +2590,7 @@
</event>
</interface>
<interface name="wl_touch" version="10">
<interface name="wl_touch" version="9">
<description summary="touchscreen input device">
The wl_touch interface represents a touchscreen
associated with a seat.
@ -3269,31 +3245,4 @@
</request>
</interface>
<interface name="wl_fixes" version="1">
<description summary="wayland protocol fixes">
This global fixes problems with other core-protocol interfaces that
cannot be fixed in these interfaces themselves.
</description>
<request name="destroy" type="destructor">
<description summary="destroys this object"/>
</request>
<request name="destroy_registry">
<description summary="destroy a wl_registry">
This request destroys a wl_registry object.
The client should no longer use the wl_registry after making this
request.
The compositor will emit a wl_display.delete_id event with the object ID
of the registry and will no longer emit any events on the registry. The
client should re-use the object ID once it receives the
wl_display.delete_id event.
</description>
<arg name="registry" type="object" interface="wl_registry"
summary="the registry to destroy"/>
</request>
</interface>
</protocol>

View file

@ -26,8 +26,7 @@
#define _GNU_SOURCE
#include "../config.h"
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <stdint.h>
@ -76,8 +75,7 @@ struct wl_connection {
static inline size_t
size_pot(uint32_t size_bits)
{
if (!(size_bits < 8 * sizeof(size_t)))
wl_abort("Too many bits for size_t\n");
assert(size_bits < 8 * sizeof(size_t));
return ((size_t)1) << size_bits;
}
@ -262,7 +260,7 @@ ring_buffer_ensure_space(struct wl_ring_buffer *b, size_t count)
* allowed).
*/
if (net_size > size_pot(size_bits)) {
wl_log("Data too big for buffer (%zu + %zu > %zu).\n",
wl_log("Data too big for buffer (%d + %zd > %zd).\n",
ring_buffer_size(b), count, size_pot(size_bits));
errno = E2BIG;
return -1;
@ -930,7 +928,7 @@ wl_connection_demarshal(struct wl_connection *connection,
for (i = 0; i < count; i++) {
signature = get_next_argument(signature, &arg);
if (arg.type != WL_ARG_FD && p >= end) {
if (arg.type != WL_ARG_FD && p + 1 > end) {
wl_log("message too short, "
"object (%d), message %s(%s)\n",
closure->sender_id, message->name,
@ -977,7 +975,7 @@ wl_connection_demarshal(struct wl_connection *connection,
s = (char *) p;
if (s[length - 1] != '\0') {
if (length > 0 && s[length - 1] != '\0') {
wl_log("string not nul-terminated, "
"message %s(%s)\n",
message->name, message->signature);
@ -985,14 +983,6 @@ wl_connection_demarshal(struct wl_connection *connection,
goto err;
}
if (strlen(s) != length - 1) {
wl_log("string has embedded nul at offset %zu, "
"message %s(%s)\n", strlen(s),
message->name, message->signature);
errno = EINVAL;
goto err;
}
closure->args[i].s = s;
p = next;
break;
@ -1231,11 +1221,6 @@ wl_closure_invoke(struct wl_closure *closure, uint32_t flags,
count + 2, &ffi_type_void, ffi_types);
implementation = target->implementation;
if (!implementation) {
wl_abort("Implementation of resource %d of %s is NULL\n",
target->id, target->interface->name);
}
if (!implementation[opcode]) {
wl_abort("listener function for opcode %u of %s is NULL\n",
opcode, target->interface->name);
@ -1358,7 +1343,7 @@ serialize_closure(struct wl_closure *closure, uint32_t *buffer,
if (arg.type == WL_ARG_FD)
continue;
if (p >= end)
if (p + 1 > end)
goto overflow;
switch (arg.type) {
@ -1386,7 +1371,7 @@ serialize_closure(struct wl_closure *closure, uint32_t *buffer,
size = strlen(closure->args[i].s) + 1;
*p++ = size;
if (div_roundup(size, sizeof *p) > (uint32_t)(end - p))
if (p + div_roundup(size, sizeof *p) > end)
goto overflow;
memcpy(p, closure->args[i].s, size);
@ -1401,7 +1386,7 @@ serialize_closure(struct wl_closure *closure, uint32_t *buffer,
size = closure->args[i].a->size;
*p++ = size;
if (div_roundup(size, sizeof *p) > (uint32_t)(end - p))
if (p + div_roundup(size, sizeof *p) > end)
goto overflow;
if (size != 0)
@ -1493,56 +1478,11 @@ wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection)
return result;
}
bool
wl_check_env_token(const char *env, const char *token)
{
const char *ptr = env;
size_t token_len;
if (env == NULL)
return false;
token_len = strlen(token);
// Scan the string for comma-separated tokens and look for a match.
while (true) {
const char *end;
size_t len;
// Skip over any leading separators.
while (*ptr == ',')
ptr++;
if (*ptr == '\x00')
return false;
end = strchr(ptr + 1, ',');
// If there isn't another separarator, then the rest of the string
// is one token.
if (end == NULL)
return (strcmp(ptr, token) == 0);
len = end - ptr;
if (len == token_len && memcmp(ptr, token, len) == 0) {
return true;
}
// Skip to the next token.
ptr += len;
}
return false;
}
void
wl_closure_print(struct wl_closure *closure, struct wl_object *target,
int send, int discarded, uint32_t (*n_parse)(union wl_argument *arg),
const char *queue_name, int color)
const char *queue_name)
{
#if defined(HAVE_GETTID)
static int include_tid = -1;
#endif // defined(HAVE_GETTID)
int i;
struct argument_details arg;
const char *signature = closure->message->signature;
@ -1559,40 +1499,17 @@ wl_closure_print(struct wl_closure *closure, struct wl_object *target,
clock_gettime(CLOCK_REALTIME, &tp);
time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
fprintf(f, "%s[%7u.%03u] ",
color ? WL_DEBUG_COLOR_GREEN : "",
time / 1000, time % 1000);
#if defined(HAVE_GETTID)
if (include_tid < 0) {
include_tid = wl_check_env_token(getenv("WAYLAND_DEBUG"), "thread_id");
}
fprintf(f, "[%7u.%03u] ", time / 1000, time % 1000);
if (include_tid) {
fprintf(f, "%sTID#%d ",
color ? WL_DEBUG_COLOR_CYAN : "",
(int) gettid());
}
#endif
if (queue_name)
fprintf(f, "{%s} ", queue_name);
if (queue_name) {
fprintf(f, "%s{%s} ",
color ? WL_DEBUG_COLOR_YELLOW : "",
queue_name);
}
fprintf(f, "%s%s%s%s%s%s%s#%u%s.%s%s(",
color ? WL_DEBUG_COLOR_RED : "",
fprintf(f, "%s%s%s#%u.%s(",
discarded ? "discarded " : "",
color ? WL_DEBUG_COLOR_RESET : "",
send ? " -> " : "",
color ? WL_DEBUG_COLOR_BLUE : "",
target->interface->name,
color ? WL_DEBUG_COLOR_MAGENTA : "",
target->id,
color ? WL_DEBUG_COLOR_CYAN : "",
closure->message->name,
color ? WL_DEBUG_COLOR_RESET : "");
target->interface->name, target->id,
closure->message->name);
for (i = 0; i < closure->count; i++) {
signature = get_next_argument(signature, &arg);
@ -1657,7 +1574,7 @@ wl_closure_print(struct wl_closure *closure, struct wl_object *target,
}
}
fprintf(f, ")%s\n", color ? WL_DEBUG_COLOR_RESET : "");
fprintf(f, ")\n");
if (fclose(f) == 0) {
fprintf(stderr, "%s", buffer);

View file

@ -23,6 +23,7 @@
* SOFTWARE.
*/
#include <assert.h>
#include <stddef.h>
#include <stdio.h>
#include <errno.h>
@ -38,7 +39,6 @@
#include <sys/signalfd.h>
#include <sys/timerfd.h>
#include <unistd.h>
#include "timespec-util.h"
#include "wayland-util.h"
#include "wayland-private.h"
#include "wayland-server-core.h"
@ -447,8 +447,7 @@ wl_timer_heap_disarm(struct wl_timer_heap *timers,
struct wl_event_source_timer *last_end_evt;
int old_source_idx;
if (!(source->heap_idx >= 0))
wl_abort("Timer has already been disarmed\n");
assert(source->heap_idx >= 0);
old_source_idx = source->heap_idx;
source->heap_idx = -1;
@ -477,8 +476,7 @@ wl_timer_heap_arm(struct wl_timer_heap *timers,
struct wl_event_source_timer *source,
struct timespec deadline)
{
if (!(source->heap_idx == -1))
wl_abort("Timer is already armed\n");
assert(source->heap_idx == -1);
source->deadline = deadline;
timers->data[timers->active] = source;
@ -974,6 +972,57 @@ wl_event_loop_dispatch_idle(struct wl_event_loop *loop)
}
}
static int
timespec_to_ms(struct timespec value)
{
return (value.tv_sec * 1000) + (value.tv_nsec / 1000000);
}
static struct timespec
ms_to_timespec(int ms)
{
struct timespec val;
val.tv_sec = ms / 1000;
val.tv_nsec = (ms % 1000) * 1000000;
return val;
}
static struct timespec
timespec_normalize(struct timespec value)
{
struct timespec result = value;
while (result.tv_nsec >= 1000000000) {
result.tv_nsec -= 1000000000;
result.tv_sec++;
}
while (result.tv_nsec < 0) {
result.tv_nsec += 1000000000;
result.tv_sec--;
}
return result;
}
static struct timespec
timespec_add(struct timespec a, struct timespec b)
{
struct timespec result;
result.tv_sec = a.tv_sec + b.tv_sec;
result.tv_nsec = a.tv_nsec + b.tv_nsec;
return timespec_normalize(result);
}
static struct timespec
timespec_sub(struct timespec a, struct timespec b)
{
struct timespec result;
result.tv_sec = a.tv_sec - b.tv_sec;
result.tv_nsec = a.tv_nsec - b.tv_nsec;
return timespec_normalize(result);
}
/** Wait for events and dispatch them
*
* \param loop The event loop whose sources to wait for.
@ -1002,15 +1051,13 @@ wl_event_loop_dispatch(struct wl_event_loop *loop, int timeout)
int i, count;
bool has_timers = false;
bool use_timeout = timeout > 0;
struct timespec now;
struct timespec deadline = {0};
struct timespec result;
struct timespec now, end;
wl_event_loop_dispatch_idle(loop);
if (use_timeout) {
clock_gettime(CLOCK_MONOTONIC, &now);
timespec_add_msec(&deadline, &now, timeout);
end = timespec_add(now, ms_to_timespec(timeout));
}
while (true) {
@ -1022,8 +1069,7 @@ wl_event_loop_dispatch(struct wl_event_loop *loop, int timeout)
if (use_timeout) {
clock_gettime(CLOCK_MONOTONIC, &now);
timespec_sub(&result, &deadline, &now);
timeout = timespec_to_msec(&result);
timeout = timespec_to_ms(timespec_sub(end, now));
if (timeout <= 0) {
/* too late */
count = 0;

View file

@ -212,7 +212,6 @@ if get_option('libraries')
description: 'Server side implementation of the Wayland protocol',
version: meson.project_version(),
filebase: 'wayland-server',
libraries: mathlib_dep,
variables: [
'datarootdir=' + join_paths('${prefix}', get_option('datadir')),
'pkgdatadir=' + join_paths('${pc_sysrootdir}${datarootdir}', meson.project_name())
@ -252,7 +251,6 @@ if get_option('libraries')
description: 'Wayland client side library',
version: meson.project_version(),
filebase: 'wayland-client',
libraries: mathlib_dep,
variables: [
'datarootdir=' + join_paths('${prefix}', get_option('datadir')),
'pkgdatadir=' + join_paths('${pc_sysrootdir}${datarootdir}', meson.project_name())

View file

@ -1378,58 +1378,6 @@ emit_event_wrappers(struct wl_list *message_list, struct interface *interface)
}
}
static void
emit_validator(struct interface *interface, struct enumeration *e)
{
struct entry *entry;
printf("#ifndef %s_%s_ENUM_IS_VALID\n",
interface->uppercase_name, e->uppercase_name);
printf("#define %s_%s_ENUM_IS_VALID\n",
interface->uppercase_name, e->uppercase_name);
printf("/**\n"
" * @ingroup iface_%s\n"
" * Validate a %s %s value.\n"
" *\n"
" * @return true on success, false on error.\n"
" * @ref %s_%s\n"
" */\n"
"static inline bool\n"
"%s_%s_is_valid(uint32_t value, uint32_t version) {\n",
interface->name, interface->name, e->name,
interface->name, e->name,
interface->name, e->name);
if (e->bitfield) {
printf(" uint32_t valid = 0;\n");
wl_list_for_each(entry, &e->entry_list, link) {
printf(" if (version >= %d)\n"
" valid |= %s_%s_%s;\n",
entry->since,
interface->uppercase_name, e->uppercase_name,
entry->uppercase_name);
}
printf(" return (value & ~valid) == 0;\n");
} else {
printf(" switch (value) {\n");
wl_list_for_each(entry, &e->entry_list, link) {
printf(" case %s%s_%s_%s:\n"
" return version >= %d;\n",
entry->value[0] == '-' ? "(uint32_t)" : "",
interface->uppercase_name, e->uppercase_name,
entry->uppercase_name, entry->since);
}
printf(" default:\n"
" return false;\n"
" }\n");
}
printf("}\n");
printf("#endif /* %s_%s_ENUM_IS_VALID */\n\n",
interface->uppercase_name, e->uppercase_name);
}
static void
emit_enumerations(struct interface *interface, bool with_validators)
{
@ -1491,11 +1439,35 @@ emit_enumerations(struct interface *interface, bool with_validators)
}
if (with_validators) {
printf("/**\n"
" * @ingroup iface_%s\n"
" * Validate a %s %s value.\n"
" *\n"
" * @return true on success, false on error.\n"
" * @ref %s_%s\n"
" */\n"
"static inline bool\n"
"%s_%s_is_valid(uint32_t value, uint32_t version) {\n"
" switch (value) {\n",
interface->name, interface->name, e->name,
interface->name, e->name,
interface->name, e->name);
wl_list_for_each(entry, &e->entry_list, link) {
printf(" case %s%s_%s_%s:\n"
" return version >= %d;\n",
entry->value[0] == '-' ? "(uint32_t)" : "",
interface->uppercase_name, e->uppercase_name,
entry->uppercase_name, entry->since);
}
printf(" default:\n"
" return false;\n"
" }\n"
"}\n");
}
printf("#endif /* %s_%s_ENUM */\n\n",
interface->uppercase_name, e->uppercase_name);
if (with_validators)
emit_validator(interface, e);
}
}

View file

@ -1,311 +0,0 @@
/*
* Copyright © 2014 - 2015 Collabora, Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef TIMESPEC_UTIL_H
#define TIMESPEC_UTIL_H
#include <stdint.h>
#include <assert.h>
#include <time.h>
#include <stdbool.h>
#define NSEC_PER_SEC 1000000000
/* Subtract timespecs
*
* \param r[out] result: a - b
* \param a[in] operand
* \param b[in] operand
*/
static inline void
timespec_sub(struct timespec *r,
const struct timespec *a, const struct timespec *b)
{
r->tv_sec = a->tv_sec - b->tv_sec;
r->tv_nsec = a->tv_nsec - b->tv_nsec;
if (r->tv_nsec < 0) {
r->tv_sec--;
r->tv_nsec += NSEC_PER_SEC;
}
}
/* Add a nanosecond value to a timespec
*
* \param r[out] result: a + b
* \param a[in] base operand as timespec
* \param b[in] operand in nanoseconds
*/
static inline void
timespec_add_nsec(struct timespec *r, const struct timespec *a, int64_t b)
{
r->tv_sec = a->tv_sec + (b / NSEC_PER_SEC);
r->tv_nsec = a->tv_nsec + (b % NSEC_PER_SEC);
if (r->tv_nsec >= NSEC_PER_SEC) {
r->tv_sec++;
r->tv_nsec -= NSEC_PER_SEC;
} else if (r->tv_nsec < 0) {
r->tv_sec--;
r->tv_nsec += NSEC_PER_SEC;
}
}
/* Add a millisecond value to a timespec
*
* \param r[out] result: a + b
* \param a[in] base operand as timespec
* \param b[in] operand in milliseconds
*/
static inline void
timespec_add_msec(struct timespec *r, const struct timespec *a, int64_t b)
{
timespec_add_nsec(r, a, b * 1000000);
}
/* Convert timespec to nanoseconds
*
* \param a timespec
* \return nanoseconds
*/
static inline int64_t
timespec_to_nsec(const struct timespec *a)
{
return (int64_t)a->tv_sec * NSEC_PER_SEC + a->tv_nsec;
}
/* Subtract timespecs and return result in nanoseconds
*
* \param a[in] operand
* \param b[in] operand
* \return to_nanoseconds(a - b)
*/
static inline int64_t
timespec_sub_to_nsec(const struct timespec *a, const struct timespec *b)
{
struct timespec r;
timespec_sub(&r, a, b);
return timespec_to_nsec(&r);
}
/* Convert timespec to milliseconds
*
* \param a timespec
* \return milliseconds
*
* Rounding to integer milliseconds happens always down (floor()).
*/
static inline int64_t
timespec_to_msec(const struct timespec *a)
{
return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000;
}
/* Subtract timespecs and return result in milliseconds
*
* \param a[in] operand
* \param b[in] operand
* \return to_milliseconds(a - b)
*/
static inline int64_t
timespec_sub_to_msec(const struct timespec *a, const struct timespec *b)
{
return timespec_sub_to_nsec(a, b) / 1000000;
}
/* Convert timespec to microseconds
*
* \param a timespec
* \return microseconds
*
* Rounding to integer microseconds happens always down (floor()).
*/
static inline int64_t
timespec_to_usec(const struct timespec *a)
{
return (int64_t)a->tv_sec * 1000000 + a->tv_nsec / 1000;
}
/* Convert timespec to protocol data
*
* \param a timespec
* \param tv_sec_hi[out] the high bytes of the seconds part
* \param tv_sec_lo[out] the low bytes of the seconds part
* \param tv_nsec[out] the nanoseconds part
*
* The input timespec must be normalized (the nanoseconds part should
* be less than 1 second) and non-negative.
*/
static inline void
timespec_to_proto(const struct timespec *a, uint32_t *tv_sec_hi,
uint32_t *tv_sec_lo, uint32_t *tv_nsec)
{
assert(a->tv_sec >= 0);
assert(a->tv_nsec >= 0 && a->tv_nsec < NSEC_PER_SEC);
uint64_t sec64 = a->tv_sec;
*tv_sec_hi = sec64 >> 32;
*tv_sec_lo = sec64 & 0xffffffff;
*tv_nsec = a->tv_nsec;
}
/* Convert nanoseconds to timespec
*
* \param a timespec
* \param b nanoseconds
*/
static inline void
timespec_from_nsec(struct timespec *a, int64_t b)
{
a->tv_sec = b / NSEC_PER_SEC;
a->tv_nsec = b % NSEC_PER_SEC;
}
/* Convert microseconds to timespec
*
* \param a timespec
* \param b microseconds
*/
static inline void
timespec_from_usec(struct timespec *a, int64_t b)
{
timespec_from_nsec(a, b * 1000);
}
/* Convert milliseconds to timespec
*
* \param a timespec
* \param b milliseconds
*/
static inline void
timespec_from_msec(struct timespec *a, int64_t b)
{
timespec_from_nsec(a, b * 1000000);
}
/* Convert protocol data to timespec
*
* \param a[out] timespec
* \param tv_sec_hi the high bytes of seconds part
* \param tv_sec_lo the low bytes of seconds part
* \param tv_nsec the nanoseconds part
*/
static inline void
timespec_from_proto(struct timespec *a, uint32_t tv_sec_hi,
uint32_t tv_sec_lo, uint32_t tv_nsec)
{
a->tv_sec = ((uint64_t)tv_sec_hi << 32) + tv_sec_lo;
a->tv_nsec = tv_nsec;
}
/* Check if a timespec is zero
*
* \param a timespec
* \return whether the timespec is zero
*/
static inline bool
timespec_is_zero(const struct timespec *a)
{
return a->tv_sec == 0 && a->tv_nsec == 0;
}
/* Check if two timespecs are equal
*
* \param a[in] timespec to check
* \param b[in] timespec to check
* \return whether timespecs a and b are equal
*/
static inline bool
timespec_eq(const struct timespec *a, const struct timespec *b)
{
return a->tv_sec == b->tv_sec &&
a->tv_nsec == b->tv_nsec;
}
/* Convert milli-Hertz to nanoseconds
*
* \param mhz frequency in mHz, not zero
* \return period in nanoseconds
*/
static inline int64_t
millihz_to_nsec(uint32_t mhz)
{
assert(mhz > 0);
return 1000000000000LL / mhz;
}
/**
* Checks whether a timespec value is after another
*
* \param a[in] timespec to compare
* \param b[in] timespec to compare
* \return whether a is after b
*/
static inline bool
timespec_after(const struct timespec *a, const struct timespec *b)
{
return (a->tv_sec == b->tv_sec) ?
(a->tv_nsec > b->tv_nsec) :
(a->tv_sec > b->tv_sec);
}
/**
* Add timespecs
*
* \param r[out] result: a + b
* \param a[in] operand
* \param b[in] operand
*/
static inline void
timespec_add(struct timespec *r,
const struct timespec *a, const struct timespec *b)
{
r->tv_sec = a->tv_sec + b->tv_sec;
r->tv_nsec = a->tv_nsec + b->tv_nsec;
if (r->tv_nsec > NSEC_PER_SEC) {
r->tv_sec++;
r->tv_nsec -= NSEC_PER_SEC;
}
}
/**
* Saturating timespec subtraction
*
* \param r[out] result: max(a - b, 0)
* \param a[in] operand
* \param b[in] operand
*/
static inline void
timespec_sub_saturate(struct timespec *r,
const struct timespec *a, const struct timespec *b)
{
timespec_sub(r, a, b);
if (r->tv_sec < 0) {
r->tv_sec = 0;
r->tv_nsec = 0;
}
}
#endif /* TIMESPEC_UTIL_H */

View file

@ -34,8 +34,6 @@
extern "C" {
#endif
struct timespec;
/** \class wl_proxy
*
* \brief Represents a protocol object on the client side.
@ -221,9 +219,6 @@ wl_proxy_get_tag(struct wl_proxy *proxy);
const char *
wl_proxy_get_class(struct wl_proxy *proxy);
const struct wl_interface *
wl_proxy_get_interface(struct wl_proxy *proxy);
struct wl_display *
wl_proxy_get_display(struct wl_proxy *proxy);
@ -255,29 +250,13 @@ int
wl_display_dispatch_queue(struct wl_display *display,
struct wl_event_queue *queue);
int
wl_display_dispatch_timeout(struct wl_display *display,
const struct timespec *timeout);
int
wl_display_dispatch_queue_timeout(struct wl_display *display,
struct wl_event_queue *queue,
const struct timespec *timeout);
int
wl_display_dispatch_queue_pending(struct wl_display *display,
struct wl_event_queue *queue);
int
wl_display_dispatch_queue_pending_single(struct wl_display *display,
struct wl_event_queue *queue);
int
wl_display_dispatch_pending(struct wl_display *display);
int
wl_display_dispatch_pending_single(struct wl_display *display);
int
wl_display_get_error(struct wl_display *display);

View file

@ -37,6 +37,7 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <ctype.h>
#include <assert.h>
#include <fcntl.h>
#include <poll.h>
#include <pthread.h>
@ -45,7 +46,6 @@
#include "wayland-os.h"
#include "wayland-client.h"
#include "wayland-private.h"
#include "timespec-util.h"
/** \cond */
@ -115,7 +115,6 @@ struct wl_display {
/** \endcond */
static int debug_client = 0;
static int debug_color = 0;
/**
* This helper function wakes up all threads that are
@ -236,16 +235,13 @@ wl_event_queue_init(struct wl_event_queue *queue,
static void
wl_proxy_unref(struct wl_proxy *proxy)
{
if (!(proxy->refcount > 0))
wl_abort("Proxy requested for unref has no references\n");
assert(proxy->refcount > 0);
if (--proxy->refcount > 0)
return;
/* If we get here, the client must have explicitly requested
* deletion. */
if (!(proxy->flags & WL_PROXY_FLAG_DESTROYED))
wl_abort("Proxy with no references not yet explicitly"
"destroyed\n");
assert(proxy->flags & WL_PROXY_FLAG_DESTROYED);
free(proxy);
}
@ -675,9 +671,6 @@ wl_proxy_add_listener(struct wl_proxy *proxy,
* This function is useful in clients with multiple listeners on the same
* interface to allow the identification of which code to execute.
*
* If \ref wl_proxy_add_dispatcher was used, this function returns the
* dispatcher_data pointer instead.
*
* \memberof wl_proxy
*/
WL_EXPORT const void *
@ -921,29 +914,21 @@ wl_proxy_marshal_array_flags(struct wl_proxy *proxy, uint32_t opcode,
closure = wl_closure_marshal(&proxy->object, opcode, args, message);
if (closure == NULL) {
wl_log("Error marshalling request for %s.%s: %s\n",
proxy->object.interface->name, message->name,
strerror(errno));
wl_log("Error marshalling request: %s\n", strerror(errno));
display_fatal_error(proxy->display, errno);
goto err_unlock;
}
if (debug_client) {
struct wl_event_queue *queue;
const char *queue_name = NULL;
queue = wl_proxy_get_queue(proxy);
if (queue)
queue_name = wl_event_queue_get_name(queue);
wl_closure_print(closure, &proxy->object, true, false, NULL,
queue_name, debug_color);
wl_event_queue_get_name(queue));
}
if (wl_closure_send(closure, proxy->display->connection)) {
wl_log("Error sending request for %s.%s: %s\n",
proxy->object.interface->name, message->name,
strerror(errno));
wl_log("Error sending request: %s\n", strerror(errno));
display_fatal_error(proxy->display, errno);
}
@ -1187,8 +1172,7 @@ connect_to_socket(const char *name)
"%s", name) + 1;
}
if (!(name_size > 0))
wl_abort("Error assigning path name for socket connection\n");
assert(name_size > 0);
if (name_size > (int)sizeof addr.sun_path) {
if (!path_is_absolute) {
wl_log("error: socket path \"%s/%s\" plus null terminator"
@ -1230,23 +1214,10 @@ wl_display_connect_to_fd(int fd)
{
struct wl_display *display;
const char *debug;
const char *no_color;
const char *force_color;
no_color = getenv("NO_COLOR");
force_color = getenv("FORCE_COLOR");
debug = getenv("WAYLAND_DEBUG");
if (debug && (wl_check_env_token(debug, "client") || wl_check_env_token(debug, "1"))) {
if (debug && (strstr(debug, "client") || strstr(debug, "1")))
debug_client = 1;
if (isatty(fileno(stderr)))
debug_color = 1;
}
if (force_color && force_color[0] != '\0')
debug_color = 1;
if (no_color && no_color[0] != '\0')
debug_color = 0;
display = zalloc(sizeof *display);
if (display == NULL) {
@ -1578,28 +1549,6 @@ queue_event(struct wl_display *display, int len)
id = p[0];
opcode = p[1] & 0xffff;
size = p[1] >> 16;
/*
* If the message is larger than the maximum size of the
* connection buffer, the connection buffer will fill to
* its max size and stay there, with no message ever
* successfully being processed. If the user of
* libwayland-client uses a level-triggered event loop,
* this will cause the client to enter a loop that
* consumes CPU. To avoid this, immediately drop the
* connection. Since the maximum size of a message should
* not depend on the max buffer size chosen by the client,
* always compare the message size against the
* limit enforced by libwayland 1.22 and below (4096),
* rather than the actual value the client chose.
*/
if (size > WL_MAX_MESSAGE_SIZE) {
wl_log("Message length %u exceeds limit %d\n",
size, WL_MAX_MESSAGE_SIZE);
errno = E2BIG;
return -1;
}
if (len < size)
return 0;
@ -1614,16 +1563,12 @@ queue_event(struct wl_display *display, int len)
if (debug_client) {
clock_gettime(CLOCK_REALTIME, &tp);
time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
fprintf(stderr, "%s[%7u.%03u] %sdiscarded %s[%s]%s#%u%s.[event %d]%s"
fprintf(stderr, "[%7u.%03u] discarded [%s]#%d.[event %d]"
"(%d fd, %d byte)\n",
debug_color ? WL_DEBUG_COLOR_GREEN : "",
time / 1000, time % 1000,
debug_color ? WL_DEBUG_COLOR_RED : "",
debug_color ? WL_DEBUG_COLOR_BLUE : "",
zombie ? "zombie" : "unknown",
debug_color ? WL_DEBUG_COLOR_MAGENTA : "", id,
debug_color ? WL_DEBUG_COLOR_BLUE : "", opcode,
debug_color ? WL_DEBUG_COLOR_RESET : "",
id, opcode,
num_zombie_fds, size);
}
if (num_zombie_fds > 0)
@ -1708,7 +1653,7 @@ dispatch_event(struct wl_display *display, struct wl_event_queue *queue)
!(proxy->dispatcher || proxy->object.implementation);
wl_closure_print(closure, &proxy->object, false, discarded,
id_from_object, queue->name, debug_color);
id_from_object, queue->name);
}
if (proxy_destroyed) {
@ -1882,34 +1827,6 @@ err:
return -1;
}
static int
dispatch_queue_single(struct wl_display *display, struct wl_event_queue *queue)
{
if (display->last_error)
goto err;
while (!wl_list_empty(&display->display_queue.event_list)) {
dispatch_event(display, &display->display_queue);
if (display->last_error)
goto err;
}
if (!wl_list_empty(&queue->event_list)) {
dispatch_event(display, queue);
if (display->last_error)
goto err;
return 1;
} else {
return 0;
}
err:
errno = display->last_error;
return -1;
}
/** Prepare to read events from the display's file descriptor to a queue
*
* \param display The display context object
@ -2025,142 +1942,20 @@ wl_display_cancel_read(struct wl_display *display)
}
static int
wl_display_poll(struct wl_display *display,
short int events,
const struct timespec *timeout)
wl_display_poll(struct wl_display *display, short int events)
{
int ret;
struct pollfd pfd[1];
struct timespec now;
struct timespec deadline = {0};
struct timespec result;
struct timespec *remaining_timeout = NULL;
if (timeout) {
clock_gettime(CLOCK_MONOTONIC, &now);
timespec_add(&deadline, &now, timeout);
}
pfd[0].fd = display->fd;
pfd[0].events = events;
do {
if (timeout) {
clock_gettime(CLOCK_MONOTONIC, &now);
timespec_sub_saturate(&result, &deadline, &now);
remaining_timeout = &result;
}
ret = ppoll(pfd, 1, remaining_timeout, NULL);
ret = poll(pfd, 1, -1);
} while (ret == -1 && errno == EINTR);
return ret;
}
/** Dispatch events in an event queue with a timeout
*
* \param display The display context object
* \param queue The event queue to dispatch
* \param timeout A timeout describing how long the call should block trying to
* dispatch events
* \return The number of dispatched events on success, -1 on failure
*
* This function behaves identical to wl_display_dispatch_queue() except
* that it also takes a timeout and returns 0 if the timeout elapsed.
*
* Passing NULL as a timeout means an infinite timeout. An empty timespec
* causes wl_display_dispatch_queue_timeout() to return immediately even if no
* events have been dispatched.
*
* If a timeout is passed to wl_display_dispatch_queue_timeout() it is updated
* to the remaining time.
*
* \sa wl_display_dispatch_queue()
*
* \memberof wl_display
*/
WL_EXPORT int
wl_display_dispatch_queue_timeout(struct wl_display *display,
struct wl_event_queue *queue,
const struct timespec *timeout)
{
int ret;
struct timespec now;
struct timespec deadline = {0};
struct timespec result;
struct timespec *remaining_timeout = NULL;
if (timeout) {
clock_gettime(CLOCK_MONOTONIC, &now);
timespec_add(&deadline, &now, timeout);
}
if (wl_display_prepare_read_queue(display, queue) == -1)
return wl_display_dispatch_queue_pending(display, queue);
while (true) {
ret = wl_display_flush(display);
if (ret != -1 || errno != EAGAIN)
break;
if (timeout) {
clock_gettime(CLOCK_MONOTONIC, &now);
timespec_sub_saturate(&result, &deadline, &now);
remaining_timeout = &result;
}
ret = wl_display_poll(display, POLLOUT, remaining_timeout);
if (ret <= 0) {
wl_display_cancel_read(display);
return ret;
}
}
/* Don't stop if flushing hits an EPIPE; continue so we can read any
* protocol error that may have triggered it. */
if (ret < 0 && errno != EPIPE) {
wl_display_cancel_read(display);
return -1;
}
while (true) {
if (timeout) {
clock_gettime(CLOCK_MONOTONIC, &now);
timespec_sub_saturate(&result, &deadline, &now);
remaining_timeout = &result;
}
ret = wl_display_poll(display, POLLIN, remaining_timeout);
if (ret <= 0) {
wl_display_cancel_read(display);
break;
}
ret = wl_display_read_events(display);
if (ret == -1)
break;
ret = wl_display_dispatch_queue_pending(display, queue);
if (ret != 0)
break;
/* We managed to read data from the display but there is no
* complete event to dispatch yet. Try reading again. */
if (wl_display_prepare_read_queue(display, queue) == -1)
return wl_display_dispatch_queue_pending(display, queue);
}
return ret;
}
WL_EXPORT int
wl_display_dispatch_timeout(struct wl_display *display,
const struct timespec *timeout)
{
return wl_display_dispatch_queue_timeout(display,
&display->default_queue,
timeout);
}
/** Dispatch events in an event queue
*
* \param display The display context object
@ -2192,8 +1987,8 @@ wl_display_dispatch_timeout(struct wl_display *display,
* \note Since Wayland 1.5 the display has an extra queue
* for its own events (i. e. delete_id). This queue is dispatched always,
* no matter what queue we passed as an argument to this function.
* That means that this function can return even when it has not dispatched any
* event for the given queue.
* That means that this function can return non-0 value even when it
* haven't dispatched any event for the given queue.
*
* \sa wl_display_dispatch(), wl_display_dispatch_pending(),
* wl_display_dispatch_queue_pending(), wl_display_prepare_read_queue()
@ -2206,10 +2001,37 @@ wl_display_dispatch_queue(struct wl_display *display,
{
int ret;
ret = wl_display_dispatch_queue_timeout(display, queue, NULL);
assert(ret == -1 || ret > 0);
if (wl_display_prepare_read_queue(display, queue) == -1)
return wl_display_dispatch_queue_pending(display, queue);
return ret;
while (true) {
ret = wl_display_flush(display);
if (ret != -1 || errno != EAGAIN)
break;
if (wl_display_poll(display, POLLOUT) == -1) {
wl_display_cancel_read(display);
return -1;
}
}
/* Don't stop if flushing hits an EPIPE; continue so we can read any
* protocol error that may have triggered it. */
if (ret < 0 && errno != EPIPE) {
wl_display_cancel_read(display);
return -1;
}
if (wl_display_poll(display, POLLIN) == -1) {
wl_display_cancel_read(display);
return -1;
}
if (wl_display_read_events(display) == -1)
return -1;
return wl_display_dispatch_queue_pending(display, queue);
}
/** Dispatch pending events in an event queue
@ -2240,34 +2062,6 @@ wl_display_dispatch_queue_pending(struct wl_display *display,
return ret;
}
/** Dispatch at most one pending event in an event queue
*
* \param display The display context object
* \param queue The event queue to dispatch
* \return The number of dispatched events (0 or 1) on success or -1 on failure
*
* Dispatch at most one pending event for objects assigned to the given
* event queue. On failure -1 is returned and errno set appropriately.
* If there are no events queued, this function returns immediately.
*
* \memberof wl_display
* \since 1.25.0
*/
WL_EXPORT int
wl_display_dispatch_queue_pending_single(struct wl_display *display,
struct wl_event_queue *queue)
{
int ret;
pthread_mutex_lock(&display->mutex);
ret = dispatch_queue_single(display, queue);
pthread_mutex_unlock(&display->mutex);
return ret;
}
/** Process incoming events
*
* \param display The display context object
@ -2328,25 +2122,6 @@ wl_display_dispatch_pending(struct wl_display *display)
&display->default_queue);
}
/** Dispatch at most one pending event in the default event queue.
*
* \param display The display context object
* \return The number of dispatched events (0 or 1) on success or -1 on failure
*
* Dispatch at most one pending event for objects assigned to the default
* event queue. On failure -1 is returned and errno set appropriately.
* If there are no events queued, this function returns immediately.
*
* \memberof wl_display
* \since 1.25.0
*/
WL_EXPORT int
wl_display_dispatch_pending_single(struct wl_display *display)
{
return wl_display_dispatch_queue_pending_single(display,
&display->default_queue);
}
/** Retrieve the last error that occurred on a display
*
* \param display The display context object
@ -2628,20 +2403,6 @@ wl_proxy_get_class(struct wl_proxy *proxy)
return proxy->object.interface->name;
}
/** Get the interface of a proxy object
*
* \param proxy The proxy object
* \return The interface of the object associated with the proxy
*
* \memberof wl_proxy
* \since 1.24
*/
WL_EXPORT const struct wl_interface *
wl_proxy_get_interface(struct wl_proxy *proxy)
{
return proxy->object.interface;
}
/** Get the display of a proxy object
*
* \param proxy The proxy object
@ -2692,9 +2453,7 @@ wl_proxy_set_queue(struct wl_proxy *proxy, struct wl_event_queue *queue)
wl_list_remove(&proxy->queue_link);
if (queue) {
if (!(proxy->display == queue->display))
wl_abort("Proxy and queue point to different "
"wl_displays");
assert(proxy->display == queue->display);
proxy->queue = queue;
} else {
proxy->queue = &proxy->display->default_queue;
@ -2822,8 +2581,7 @@ wl_proxy_wrapper_destroy(void *proxy_wrapper)
wl_abort("Tried to destroy non-wrapper proxy with "
"wl_proxy_wrapper_destroy\n");
if (!(wrapper->refcount == 1))
wl_abort("Expected proxy wrapper's refcount to be 1\n");
assert(wrapper->refcount == 1);
pthread_mutex_lock(&wrapper->display->mutex);

View file

@ -49,17 +49,6 @@
#define WL_CLOSURE_MAX_ARGS 20
#define WL_BUFFER_DEFAULT_SIZE_POT 12
#define WL_BUFFER_DEFAULT_MAX_SIZE (1 << WL_BUFFER_DEFAULT_SIZE_POT)
#if WL_BUFFER_DEFAULT_MAX_SIZE < WL_MAX_MESSAGE_SIZE
# error default buffer cannot hold maximum-sized message
#endif
#define WL_DEBUG_COLOR_RESET "\e[0m"
#define WL_DEBUG_COLOR_RED "\e[31m"
#define WL_DEBUG_COLOR_GREEN "\e[32m"
#define WL_DEBUG_COLOR_YELLOW "\e[33m"
#define WL_DEBUG_COLOR_BLUE "\e[34m"
#define WL_DEBUG_COLOR_MAGENTA "\e[35m"
#define WL_DEBUG_COLOR_CYAN "\e[36m"
/**
* Argument types used in signatures.
@ -237,14 +226,11 @@ wl_closure_send(struct wl_closure *closure, struct wl_connection *connection);
int
wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection);
bool
wl_check_env_token(const char *env, const char *token);
void
wl_closure_print(struct wl_closure *closure,
struct wl_object *target, int send, int discarded,
uint32_t (*n_parse)(union wl_argument *arg),
const char *queue_name, int color);
const char *queue_name);
void
wl_closure_destroy(struct wl_closure *closure);

View file

@ -227,7 +227,7 @@ typedef void (*wl_global_bind_func_t)(struct wl_client *client, void *data,
uint32_t version, uint32_t id);
uint32_t
wl_display_get_serial(const struct wl_display *display);
wl_display_get_serial(struct wl_display *display);
uint32_t
wl_display_next_serial(struct wl_display *display);
@ -324,7 +324,7 @@ void
wl_client_flush(struct wl_client *client);
void
wl_client_get_credentials(const struct wl_client *client,
wl_client_get_credentials(struct wl_client *client,
pid_t *pid, uid_t *uid, gid_t *gid);
int
@ -550,10 +550,7 @@ void
wl_resource_queue_event_array(struct wl_resource *resource,
uint32_t opcode, union wl_argument *args);
void
wl_resource_post_error_vargs(struct wl_resource *resource,
uint32_t code, const char *msg, va_list argp);
/* msg is a printf format string, variable args are its args. */
void
wl_resource_post_error(struct wl_resource *resource,
uint32_t code, const char *msg, ...) WL_PRINTF(3, 4);
@ -586,7 +583,7 @@ void
wl_resource_destroy(struct wl_resource *resource);
uint32_t
wl_resource_get_id(const struct wl_resource *resource);
wl_resource_get_id(struct wl_resource *resource);
struct wl_list *
wl_resource_get_link(struct wl_resource *resource);
@ -607,7 +604,7 @@ void *
wl_resource_get_user_data(struct wl_resource *resource);
int
wl_resource_get_version(const struct wl_resource *resource);
wl_resource_get_version(struct wl_resource *resource);
void
wl_resource_set_destructor(struct wl_resource *resource,
@ -617,12 +614,8 @@ int
wl_resource_instance_of(struct wl_resource *resource,
const struct wl_interface *interface,
const void *implementation);
const char *
wl_resource_get_class(const struct wl_resource *resource);
const struct wl_interface *
wl_resource_get_interface(struct wl_resource *resource);
wl_resource_get_class(struct wl_resource *resource);
void
wl_resource_add_destroy_listener(struct wl_resource *resource,
@ -658,22 +651,16 @@ void *
wl_shm_buffer_get_data(struct wl_shm_buffer *buffer);
int32_t
wl_shm_buffer_get_stride(const struct wl_shm_buffer *buffer);
wl_shm_buffer_get_stride(struct wl_shm_buffer *buffer);
uint32_t
wl_shm_buffer_get_format(const struct wl_shm_buffer *buffer);
wl_shm_buffer_get_format(struct wl_shm_buffer *buffer);
int32_t
wl_shm_buffer_get_width(const struct wl_shm_buffer *buffer);
wl_shm_buffer_get_width(struct wl_shm_buffer *buffer);
int32_t
wl_shm_buffer_get_height(const struct wl_shm_buffer *buffer);
struct wl_shm_buffer *
wl_shm_buffer_ref(struct wl_shm_buffer *buffer);
void
wl_shm_buffer_unref(struct wl_shm_buffer *buffer);
wl_shm_buffer_get_height(struct wl_shm_buffer *buffer);
struct wl_shm_pool *
wl_shm_buffer_ref_pool(struct wl_shm_buffer *buffer);
@ -687,11 +674,10 @@ wl_display_init_shm(struct wl_display *display);
uint32_t *
wl_display_add_shm_format(struct wl_display *display, uint32_t format);
WL_DEPRECATED
struct wl_shm_buffer *
wl_shm_buffer_create(struct wl_client *client,
uint32_t id, int32_t width, int32_t height,
int32_t stride, uint32_t format);
int32_t stride, uint32_t format) WL_DEPRECATED;
void
wl_log_set_handler_server(wl_log_func_t handler);

View file

@ -37,6 +37,7 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <dlfcn.h>
#include <assert.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/eventfd.h>
@ -149,7 +150,6 @@ struct wl_protocol_logger {
};
static int debug_server = 0;
static int debug_color = 0;
static void
log_closure(struct wl_resource *resource,
@ -161,7 +161,7 @@ log_closure(struct wl_resource *resource,
struct wl_protocol_logger_message message;
if (debug_server)
wl_closure_print(closure, object, send, false, NULL, NULL, debug_color);
wl_closure_print(closure, object, send, false, NULL, NULL);
if (!wl_list_empty(&display->protocol_loggers)) {
message.resource = resource;
@ -288,16 +288,7 @@ wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...)
wl_resource_queue_event_array(resource, opcode, args);
}
/** Post a protocol error
*
* \param resource The resource object
* \param code The error code
* \param msg The error message format string
* \param argp The format string argument list
*
* \memberof wl_resource
*/
WL_EXPORT void
static void
wl_resource_post_error_vargs(struct wl_resource *resource,
uint32_t code, const char *msg, va_list argp)
{
@ -319,17 +310,9 @@ wl_resource_post_error_vargs(struct wl_resource *resource,
wl_resource_post_event(client->display_resource,
WL_DISPLAY_ERROR, resource, code, buffer);
client->error = true;
}
/** Post a protocol error
*
* \param resource The resource object
* \param code The error code
* \param msg The error message format string
* \param ... The format string arguments
*
* \memberof wl_resource
*/
WL_EXPORT void
wl_resource_post_error(struct wl_resource *resource,
uint32_t code, const char *msg, ...)
@ -398,29 +381,6 @@ wl_client_connection_data(int fd, uint32_t mask, void *data)
wl_connection_copy(connection, p, sizeof p);
opcode = p[1] & 0xffff;
size = p[1] >> 16;
/*
* If the message is larger than the maximum size of the
* connection buffer, the connection buffer will fill to
* its max size and stay there, with no message ever
* successfully being processed. Since libwayland-server
* uses level-triggered epoll, it will cause the server to
* enter a loop that consumes CPU. To avoid this,
* immediately disconnect the client with a protocol
* error. Since the maximum size of a message should not
* depend on the buffer size chosen by the compositor,
* always compare the message size against the
* limit enforced by libwayland 1.22 and below (4096),
* rather than the actual value the compositor chose.
*/
if (size > WL_MAX_MESSAGE_SIZE) {
wl_resource_post_error(client->display_resource,
WL_DISPLAY_ERROR_INVALID_METHOD,
"message length %u exceeds %d",
size, WL_MAX_MESSAGE_SIZE);
break;
}
if (len < size)
break;
@ -643,7 +603,7 @@ err_client:
* \memberof wl_client
*/
WL_EXPORT void
wl_client_get_credentials(const struct wl_client *client,
wl_client_get_credentials(struct wl_client *client,
pid_t *pid, uid_t *uid, gid_t *gid)
{
if (pid)
@ -823,7 +783,7 @@ wl_resource_destroy(struct wl_resource *resource)
}
WL_EXPORT uint32_t
wl_resource_get_id(const struct wl_resource *resource)
wl_resource_get_id(struct wl_resource *resource)
{
return resource->object.id;
}
@ -877,7 +837,7 @@ wl_resource_get_user_data(struct wl_resource *resource)
}
WL_EXPORT int
wl_resource_get_version(const struct wl_resource *resource)
wl_resource_get_version(struct wl_resource *resource)
{
return resource->version;
}
@ -924,25 +884,11 @@ wl_resource_get_destroy_listener(struct wl_resource *resource,
* \memberof wl_resource
*/
WL_EXPORT const char *
wl_resource_get_class(const struct wl_resource *resource)
wl_resource_get_class(struct wl_resource *resource)
{
return resource->object.interface->name;
}
/** Get the interface of a resource object
*
* \param resource The resource object
* \return The interface of the object associated with the resource
*
* \memberof wl_resource
* \since 1.24
*/
WL_EXPORT const struct wl_interface *
wl_resource_get_interface(struct wl_resource *resource)
{
return resource->object.interface;
}
/**
* Add a listener to be called at the beginning of wl_client destruction
*
@ -1192,23 +1138,10 @@ wl_display_create(void)
{
struct wl_display *display;
const char *debug;
const char *no_color;
const char *force_color;
no_color = getenv("NO_COLOR");
force_color = getenv("FORCE_COLOR");
debug = getenv("WAYLAND_DEBUG");
if (debug && (wl_check_env_token(debug, "server") || wl_check_env_token(debug, "1"))) {
if (debug && (strstr(debug, "server") || strstr(debug, "1")))
debug_server = 1;
if (isatty(fileno(stderr)))
debug_color = 1;
}
if (force_color && force_color[0] != '\0')
debug_color = 1;
if (no_color && no_color[0] != '\0')
debug_color = 0;
display = zalloc(sizeof *display);
if (display == NULL)
@ -1547,7 +1480,7 @@ wl_global_set_user_data(struct wl_global *global, void *data)
* \memberof wl_display
*/
WL_EXPORT uint32_t
wl_display_get_serial(const struct wl_display *display)
wl_display_get_serial(struct wl_display *display)
{
return display->serial;
}
@ -1584,8 +1517,7 @@ wl_display_terminate(struct wl_display *display)
display->run = false;
ret = write(display->terminate_efd, &terminate, sizeof(terminate));
if (ret < 0 && errno != EAGAIN)
wl_abort("Write failed at shutdown\n");
assert (ret >= 0 || errno == EAGAIN);
}
WL_EXPORT void
@ -1782,8 +1714,7 @@ wl_socket_init_for_display_name(struct wl_socket *s, const char *name)
name_size = snprintf(s->addr.sun_path, sizeof s->addr.sun_path,
"%s%s%s", runtime_dir, separator, name) + 1;
if (!(name_size > 0))
wl_abort("Error assigning path name for socket address\n");
assert(name_size > 0);
if (name_size > (int)sizeof s->addr.sun_path) {
wl_log("error: socket path \"%s%s%s\" plus null terminator"
" exceeds 108 bytes\n", runtime_dir, separator, name);
@ -1831,24 +1762,6 @@ _wl_display_add_socket(struct wl_display *display, struct wl_socket *s)
return 0;
}
/** Automatically pick a Wayland display socket for the clients to connect to.
*
* \param display Wayland display to which the socket should be added.
* \return The socket name if success. NULL if failed.
*
* This adds a Unix socket to Wayland display which can be used by clients to
* connect to Wayland display. The name of the socket is chosen automatically
* as the first available name in the sequence "wayland-0", "wayland-1",
* "wayland-2", ..., "wayland-32".
*
* The string returned by this function is owned by the library and should
* not be freed.
*
* \sa wl_display_add_socket
*
* \memberof wl_display
*/
WL_EXPORT const char *
wl_display_add_socket_auto(struct wl_display *display)
{
@ -2129,7 +2042,7 @@ wl_log_set_handler_server(wl_log_func_t handler)
* \param func The function to call to log a new protocol message
* \param user_data The user data pointer to pass to \a func
*
* \return The protocol logger object on success, NULL on failure.
* \return The protol logger object on success, NULL on failure.
*
* \sa wl_protocol_logger_destroy
*
@ -2570,10 +2483,9 @@ wl_priv_signal_final_emit(struct wl_priv_signal *signal, void *data)
/** \cond */ /* Deprecated functions below. */
WL_DEPRECATED
uint32_t
wl_client_add_resource(struct wl_client *client,
struct wl_resource *resource);
struct wl_resource *resource) WL_DEPRECATED;
WL_EXPORT uint32_t
wl_client_add_resource(struct wl_client *client,
@ -2602,12 +2514,11 @@ wl_client_add_resource(struct wl_client *client,
return resource->object.id;
}
WL_DEPRECATED
struct wl_resource *
wl_client_add_object(struct wl_client *client,
const struct wl_interface *interface,
const void *implementation,
uint32_t id, void *data);
uint32_t id, void *data) WL_DEPRECATED;
WL_EXPORT struct wl_resource *
wl_client_add_object(struct wl_client *client,
@ -2626,11 +2537,10 @@ wl_client_add_object(struct wl_client *client,
return resource;
}
WL_DEPRECATED
struct wl_resource *
wl_client_new_object(struct wl_client *client,
const struct wl_interface *interface,
const void *implementation, void *data);
const void *implementation, void *data) WL_DEPRECATED;
WL_EXPORT struct wl_resource *
wl_client_new_object(struct wl_client *client,
@ -2689,11 +2599,10 @@ wl_client_get_user_data(struct wl_client *client)
return client->data;
}
WL_DEPRECATED
struct wl_global *
wl_display_add_global(struct wl_display *display,
const struct wl_interface *interface,
void *data, wl_global_bind_func_t bind);
void *data, wl_global_bind_func_t bind) WL_DEPRECATED;
WL_EXPORT struct wl_global *
wl_display_add_global(struct wl_display *display,
@ -2703,10 +2612,9 @@ wl_display_add_global(struct wl_display *display,
return wl_global_create(display, interface, interface->version, data, bind);
}
WL_DEPRECATED
void
wl_display_remove_global(struct wl_display *display,
struct wl_global *global);
struct wl_global *global) WL_DEPRECATED;
WL_EXPORT void
wl_display_remove_global(struct wl_display *display, struct wl_global *global)

View file

@ -70,35 +70,30 @@ struct wl_resource {
void *data;
};
WL_DEPRECATED
uint32_t
wl_client_add_resource(struct wl_client *client,
struct wl_resource *resource);
struct wl_resource *resource) WL_DEPRECATED;
WL_DEPRECATED
struct wl_resource *
wl_client_add_object(struct wl_client *client,
const struct wl_interface *interface,
const void *implementation,
uint32_t id, void *data);
uint32_t id, void *data) WL_DEPRECATED;
WL_DEPRECATED
struct wl_resource *
wl_client_new_object(struct wl_client *client,
const struct wl_interface *interface,
const void *implementation, void *data);
const void *implementation, void *data) WL_DEPRECATED;
WL_DEPRECATED
struct wl_global *
wl_display_add_global(struct wl_display *display,
const struct wl_interface *interface,
void *data,
wl_global_bind_func_t bind);
wl_global_bind_func_t bind) WL_DEPRECATED;
WL_DEPRECATED
void
wl_display_remove_global(struct wl_display *display,
struct wl_global *global);
struct wl_global *global) WL_DEPRECATED;
#endif

View file

@ -40,6 +40,7 @@
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <assert.h>
#include <signal.h>
#include <pthread.h>
#include <errno.h>
@ -84,10 +85,6 @@ struct wl_shm_pool {
*/
struct wl_shm_buffer {
struct wl_resource *resource;
int internal_refcount;
int external_refcount;
struct wl_client *client;
struct wl_listener client_destroy_listener;
int32_t width, height;
int32_t stride;
uint32_t format;
@ -147,16 +144,12 @@ shm_pool_unref(struct wl_shm_pool *pool, bool external)
{
if (external) {
pool->external_refcount--;
if (pool->external_refcount < 0)
wl_abort("Requested to unref an external reference to "
"pool but none found\n");
assert(pool->external_refcount >= 0);
if (pool->external_refcount == 0)
shm_pool_finish_resize(pool);
} else {
pool->internal_refcount--;
if (pool->internal_refcount < 0)
wl_abort("Requested to unref an internal reference to "
"pool but none found\n");
assert(pool->internal_refcount >= 0);
}
if (pool->internal_refcount + pool->external_refcount > 0)
@ -169,38 +162,13 @@ shm_pool_unref(struct wl_shm_pool *pool, bool external)
free(pool);
}
static void
shm_buffer_unref(struct wl_shm_buffer *buffer, bool external)
{
if (external) {
buffer->external_refcount--;
if (buffer->external_refcount < 0) {
wl_abort("Requested to unref an external reference to "
"buffer but none found\n");
}
} else {
buffer->internal_refcount--;
if (buffer->internal_refcount < 0) {
wl_abort("Requested to unref an internal reference to "
"buffer but none found\n");
}
}
if (buffer->internal_refcount + buffer->external_refcount > 0)
return;
if (buffer->client)
wl_list_remove(&buffer->client_destroy_listener.link);
shm_pool_unref(buffer->pool, false);
free(buffer);
}
static void
destroy_buffer(struct wl_resource *resource)
{
struct wl_shm_buffer *buffer = wl_resource_get_user_data(resource);
shm_buffer_unref(buffer, false);
shm_pool_unref(buffer->pool, false);
free(buffer);
}
static void
@ -234,17 +202,6 @@ format_is_supported(struct wl_client *client, uint32_t format)
return false;
}
static void
shm_buffer_client_destroy_notify(struct wl_listener *listener, void *data)
{
struct wl_shm_buffer *buffer =
wl_container_of(listener, buffer, client_destroy_listener);
buffer->client = NULL;
wl_list_remove(&buffer->client_destroy_listener.link);
}
static void
shm_pool_create_buffer(struct wl_client *client, struct wl_resource *resource,
uint32_t id, int32_t offset,
@ -277,14 +234,6 @@ shm_pool_create_buffer(struct wl_client *client, struct wl_resource *resource,
return;
}
buffer->client = client;
buffer->client_destroy_listener.notify =
shm_buffer_client_destroy_notify;
wl_client_add_destroy_listener(buffer->client,
&buffer->client_destroy_listener);
buffer->internal_refcount = 1;
buffer->external_refcount = 0;
buffer->width = width;
buffer->height = height;
buffer->format = format;
@ -492,7 +441,7 @@ wl_shm_buffer_get(struct wl_resource *resource)
}
WL_EXPORT int32_t
wl_shm_buffer_get_stride(const struct wl_shm_buffer *buffer)
wl_shm_buffer_get_stride(struct wl_shm_buffer *buffer)
{
return buffer->stride;
}
@ -509,8 +458,8 @@ wl_shm_buffer_get_stride(const struct wl_shm_buffer *buffer)
* SIGBUS signals. This can happen if the client claims that the
* buffer is larger than it is or if something truncates the
* underlying file. To prevent this signal from causing the compositor
* to crash you should call wl_shm_buffer_begin_access() and
* wl_shm_buffer_end_access() around code that reads from the memory.
* to crash you should call wl_shm_buffer_begin_access and
* wl_shm_buffer_end_access around code that reads from the memory.
*
* \memberof wl_shm_buffer
*/
@ -526,62 +475,23 @@ wl_shm_buffer_get_data(struct wl_shm_buffer *buffer)
}
WL_EXPORT uint32_t
wl_shm_buffer_get_format(const struct wl_shm_buffer *buffer)
wl_shm_buffer_get_format(struct wl_shm_buffer *buffer)
{
return buffer->format;
}
WL_EXPORT int32_t
wl_shm_buffer_get_width(const struct wl_shm_buffer *buffer)
wl_shm_buffer_get_width(struct wl_shm_buffer *buffer)
{
return buffer->width;
}
WL_EXPORT int32_t
wl_shm_buffer_get_height(const struct wl_shm_buffer *buffer)
wl_shm_buffer_get_height(struct wl_shm_buffer *buffer)
{
return buffer->height;
}
/** Reference a shm_buffer
*
* \param buffer The buffer object
*
* Returns a pointer to the buffer and increases the refcount.
*
* The compositor must remember to call wl_shm_buffer_unref() when
* it no longer needs the reference to ensure proper destruction
* of the buffer.
*
* \memberof wl_shm_buffer
* \sa wl_shm_buffer_unref
*/
WL_EXPORT struct wl_shm_buffer *
wl_shm_buffer_ref(struct wl_shm_buffer *buffer)
{
buffer->external_refcount++;
return buffer;
}
/** Unreference a shm_buffer
*
* \param buffer The buffer object
*
* Drops a reference to a buffer object.
*
* This is only necessary if the compositor has explicitly
* taken a reference with wl_shm_buffer_ref(), otherwise
* the buffer will be automatically destroyed when appropriate.
*
* \memberof wl_shm_buffer
* \sa wl_shm_buffer_ref
*/
WL_EXPORT void
wl_shm_buffer_unref(struct wl_shm_buffer *buffer)
{
shm_buffer_unref(buffer, true);
}
/** Get a reference to a shm_buffer's shm_pool
*
* \param buffer The buffer object
@ -589,7 +499,7 @@ wl_shm_buffer_unref(struct wl_shm_buffer *buffer)
* Returns a pointer to a buffer's shm_pool and increases the
* shm_pool refcount.
*
* The compositor must remember to call wl_shm_pool_unref() when
* The compositor must remember to call wl_shm_pool_unref when
* it no longer needs the reference to ensure proper destruction
* of the pool.
*
@ -599,6 +509,9 @@ wl_shm_buffer_unref(struct wl_shm_buffer *buffer)
WL_EXPORT struct wl_shm_pool *
wl_shm_buffer_ref_pool(struct wl_shm_buffer *buffer)
{
assert(buffer->pool->internal_refcount +
buffer->pool->external_refcount);
buffer->pool->external_refcount++;
return buffer->pool;
}
@ -700,7 +613,7 @@ init_sigbus_data_key(void)
* In order to make the compositor robust against clients that change
* the size of the underlying file or lie about its size, you should
* protect access to the buffer by calling this function before
* reading from the memory and call wl_shm_buffer_end_access()
* reading from the memory and call wl_shm_buffer_end_access
* afterwards. This will install a signal handler for SIGBUS which
* will prevent the compositor from crashing.
*
@ -711,15 +624,15 @@ init_sigbus_data_key(void)
*
* If a SIGBUS signal is received for an address within the range of
* the SHM pool of the given buffer then the client will be sent an
* error event when wl_shm_buffer_end_access() is called. If the signal
* error event when wl_shm_buffer_end_access is called. If the signal
* is for an address outside that range then the signal handler will
* reraise the signal which would will likely cause the compositor to
* terminate.
*
* It is safe to nest calls to these functions as long as the nested
* calls are all accessing the same pool. The number of calls to
* wl_shm_buffer_end_access() must match the number of calls to
* wl_shm_buffer_begin_access(). These functions are thread-safe and it
* calls are all accessing the same buffer. The number of calls to
* wl_shm_buffer_end_access must match the number of calls to
* wl_shm_buffer_begin_access. These functions are thread-safe and it
* is allowed to simultaneously access different buffers or the same
* buffer from multiple threads.
*
@ -745,19 +658,18 @@ wl_shm_buffer_begin_access(struct wl_shm_buffer *buffer)
pthread_setspecific(wl_shm_sigbus_data_key, sigbus_data);
}
if (!(sigbus_data->current_pool == NULL ||
sigbus_data->current_pool == pool))
wl_abort("Incorrect pool passed for current thread\n");
assert(sigbus_data->current_pool == NULL ||
sigbus_data->current_pool == pool);
sigbus_data->current_pool = pool;
sigbus_data->access_count++;
}
/** Ends the access to a buffer started by wl_shm_buffer_begin_access()
/** Ends the access to a buffer started by wl_shm_buffer_begin_access
*
* \param buffer The SHM buffer
*
* This should be called after wl_shm_buffer_begin_access() once the
* This should be called after wl_shm_buffer_begin_access once the
* buffer is no longer being accessed. If a SIGBUS signal was
* generated in-between these two calls then the resource for the
* given buffer will be sent an error.
@ -774,22 +686,13 @@ wl_shm_buffer_end_access(struct wl_shm_buffer *buffer)
return;
sigbus_data = pthread_getspecific(wl_shm_sigbus_data_key);
if (!(sigbus_data && sigbus_data->access_count >= 1))
wl_abort("sigbus_data is NULL or wl_shm_buffer_begin_access "
"wasn't called before\n");
assert(sigbus_data && sigbus_data->access_count >= 1);
if (--sigbus_data->access_count == 0) {
if (sigbus_data->fallback_mapping_used) {
if (buffer->resource) {
wl_resource_post_error(buffer->resource,
WL_SHM_ERROR_INVALID_FD,
"error accessing SHM buffer");
} else if (buffer->client) {
wl_client_post_implementation_error(buffer->client,
"Error accessing SHM buffer of a "
"wl_buffer resource which has "
"already been destroyed");
}
wl_resource_post_error(buffer->resource,
WL_SHM_ERROR_INVALID_FD,
"error accessing SHM buffer");
sigbus_data->fallback_mapping_used = 0;
}

View file

@ -48,7 +48,7 @@ extern "C" {
#endif
/** Deprecated attribute */
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) || (defined(__cplusplus) && __cplusplus >= 201402L)
#if __STDC_VERSION__ >= 202311L
#define WL_DEPRECATED [[deprecated]]
#elif defined(__GNUC__) && __GNUC__ >= 4
#define WL_DEPRECATED __attribute__ ((deprecated))
@ -70,7 +70,7 @@ extern "C" {
#define WL_PRINTF(x, y)
#endif
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
#if __STDC_VERSION__ >= 202311L
#define WL_TYPEOF(expr) typeof(expr)
#else
#define WL_TYPEOF(expr) __typeof__(expr)
@ -90,14 +90,6 @@ extern "C" {
*/
struct wl_object;
/**
* The maximum size of a protocol message.
*
* If a message size exceeds this value, the connection will be dropped.
* Servers will send an invalid_method error before disconnecting.
*/
#define WL_MAX_MESSAGE_SIZE 4096
/**
* Protocol message signature
*
@ -643,7 +635,7 @@ wl_fixed_to_double(wl_fixed_t f)
static inline wl_fixed_t
wl_fixed_from_double(double d)
{
return (wl_fixed_t) (round(d * 256.0));
return (wl_fixed_t) (d * 256.0);
}
/**

View file

@ -686,7 +686,7 @@ TEST(connection_marshal_big_enough)
TEST(connection_marshal_unbounded_boundary_size)
{
/* A string of length 8178 requires a buffer size of exactly 2^13. */
/* A string of lenth 8178 requires a buffer size of exactly 2^13. */
struct marshal_data data;
char *big_string = malloc(8178);
assert(big_string);

View file

@ -901,10 +901,6 @@ enum wl_display_error {
*/
WL_DISPLAY_ERROR_NO_MEMORY = 2,
};
#endif /* WL_DISPLAY_ERROR_ENUM */
#ifndef WL_DISPLAY_ERROR_ENUM_IS_VALID
#define WL_DISPLAY_ERROR_ENUM_IS_VALID
/**
* @ingroup iface_wl_display
* Validate a wl_display error value.
@ -925,7 +921,7 @@ wl_display_error_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_DISPLAY_ERROR_ENUM_IS_VALID */
#endif /* WL_DISPLAY_ERROR_ENUM */
/**
* @ingroup iface_wl_display
@ -1198,10 +1194,6 @@ enum wl_shm_error {
*/
WL_SHM_ERROR_INVALID_FD = 2,
};
#endif /* WL_SHM_ERROR_ENUM */
#ifndef WL_SHM_ERROR_ENUM_IS_VALID
#define WL_SHM_ERROR_ENUM_IS_VALID
/**
* @ingroup iface_wl_shm
* Validate a wl_shm error value.
@ -1222,7 +1214,7 @@ wl_shm_error_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_SHM_ERROR_ENUM_IS_VALID */
#endif /* WL_SHM_ERROR_ENUM */
#ifndef WL_SHM_FORMAT_ENUM
#define WL_SHM_FORMAT_ENUM
@ -1474,10 +1466,6 @@ enum wl_shm_format {
*/
WL_SHM_FORMAT_YVU444 = 0x34325659,
};
#endif /* WL_SHM_FORMAT_ENUM */
#ifndef WL_SHM_FORMAT_ENUM_IS_VALID
#define WL_SHM_FORMAT_ENUM_IS_VALID
/**
* @ingroup iface_wl_shm
* Validate a wl_shm format value.
@ -1608,7 +1596,7 @@ wl_shm_format_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_SHM_FORMAT_ENUM_IS_VALID */
#endif /* WL_SHM_FORMAT_ENUM */
/**
* @ingroup iface_wl_shm
@ -1718,10 +1706,6 @@ enum wl_data_offer_error {
*/
WL_DATA_OFFER_ERROR_INVALID_OFFER = 3,
};
#endif /* WL_DATA_OFFER_ERROR_ENUM */
#ifndef WL_DATA_OFFER_ERROR_ENUM_IS_VALID
#define WL_DATA_OFFER_ERROR_ENUM_IS_VALID
/**
* @ingroup iface_wl_data_offer
* Validate a wl_data_offer error value.
@ -1744,7 +1728,7 @@ wl_data_offer_error_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_DATA_OFFER_ERROR_ENUM_IS_VALID */
#endif /* WL_DATA_OFFER_ERROR_ENUM */
/**
* @ingroup iface_wl_data_offer
@ -1956,10 +1940,6 @@ enum wl_data_source_error {
*/
WL_DATA_SOURCE_ERROR_INVALID_SOURCE = 1,
};
#endif /* WL_DATA_SOURCE_ERROR_ENUM */
#ifndef WL_DATA_SOURCE_ERROR_ENUM_IS_VALID
#define WL_DATA_SOURCE_ERROR_ENUM_IS_VALID
/**
* @ingroup iface_wl_data_source
* Validate a wl_data_source error value.
@ -1978,7 +1958,7 @@ wl_data_source_error_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_DATA_SOURCE_ERROR_ENUM_IS_VALID */
#endif /* WL_DATA_SOURCE_ERROR_ENUM */
/**
* @ingroup iface_wl_data_source
@ -2150,10 +2130,6 @@ enum wl_data_device_error {
*/
WL_DATA_DEVICE_ERROR_ROLE = 0,
};
#endif /* WL_DATA_DEVICE_ERROR_ENUM */
#ifndef WL_DATA_DEVICE_ERROR_ENUM_IS_VALID
#define WL_DATA_DEVICE_ERROR_ENUM_IS_VALID
/**
* @ingroup iface_wl_data_device
* Validate a wl_data_device error value.
@ -2170,7 +2146,7 @@ wl_data_device_error_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_DATA_DEVICE_ERROR_ENUM_IS_VALID */
#endif /* WL_DATA_DEVICE_ERROR_ENUM */
/**
* @ingroup iface_wl_data_device
@ -2411,10 +2387,6 @@ enum wl_data_device_manager_dnd_action {
*/
WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK = 4,
};
#endif /* WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM */
#ifndef WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM_IS_VALID
#define WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM_IS_VALID
/**
* @ingroup iface_wl_data_device_manager
* Validate a wl_data_device_manager dnd_action value.
@ -2424,18 +2396,20 @@ enum wl_data_device_manager_dnd_action {
*/
static inline bool
wl_data_device_manager_dnd_action_is_valid(uint32_t value, uint32_t version) {
uint32_t valid = 0;
if (version >= 1)
valid |= WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
if (version >= 1)
valid |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
if (version >= 1)
valid |= WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
if (version >= 1)
valid |= WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK;
return (value & ~valid) == 0;
switch (value) {
case WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE:
return version >= 1;
case WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY:
return version >= 1;
case WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE:
return version >= 1;
case WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK:
return version >= 1;
default:
return false;
}
}
#endif /* WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM_IS_VALID */
#endif /* WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM */
/**
* @ingroup iface_wl_data_device_manager
@ -2482,10 +2456,6 @@ enum wl_shell_error {
*/
WL_SHELL_ERROR_ROLE = 0,
};
#endif /* WL_SHELL_ERROR_ENUM */
#ifndef WL_SHELL_ERROR_ENUM_IS_VALID
#define WL_SHELL_ERROR_ENUM_IS_VALID
/**
* @ingroup iface_wl_shell
* Validate a wl_shell error value.
@ -2502,7 +2472,7 @@ wl_shell_error_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_SHELL_ERROR_ENUM_IS_VALID */
#endif /* WL_SHELL_ERROR_ENUM */
/**
* @ingroup iface_wl_shell
@ -2581,10 +2551,6 @@ enum wl_shell_surface_resize {
*/
WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT = 10,
};
#endif /* WL_SHELL_SURFACE_RESIZE_ENUM */
#ifndef WL_SHELL_SURFACE_RESIZE_ENUM_IS_VALID
#define WL_SHELL_SURFACE_RESIZE_ENUM_IS_VALID
/**
* @ingroup iface_wl_shell_surface
* Validate a wl_shell_surface resize value.
@ -2594,28 +2560,30 @@ enum wl_shell_surface_resize {
*/
static inline bool
wl_shell_surface_resize_is_valid(uint32_t value, uint32_t version) {
uint32_t valid = 0;
if (version >= 1)
valid |= WL_SHELL_SURFACE_RESIZE_NONE;
if (version >= 1)
valid |= WL_SHELL_SURFACE_RESIZE_TOP;
if (version >= 1)
valid |= WL_SHELL_SURFACE_RESIZE_BOTTOM;
if (version >= 1)
valid |= WL_SHELL_SURFACE_RESIZE_LEFT;
if (version >= 1)
valid |= WL_SHELL_SURFACE_RESIZE_TOP_LEFT;
if (version >= 1)
valid |= WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT;
if (version >= 1)
valid |= WL_SHELL_SURFACE_RESIZE_RIGHT;
if (version >= 1)
valid |= WL_SHELL_SURFACE_RESIZE_TOP_RIGHT;
if (version >= 1)
valid |= WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT;
return (value & ~valid) == 0;
switch (value) {
case WL_SHELL_SURFACE_RESIZE_NONE:
return version >= 1;
case WL_SHELL_SURFACE_RESIZE_TOP:
return version >= 1;
case WL_SHELL_SURFACE_RESIZE_BOTTOM:
return version >= 1;
case WL_SHELL_SURFACE_RESIZE_LEFT:
return version >= 1;
case WL_SHELL_SURFACE_RESIZE_TOP_LEFT:
return version >= 1;
case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT:
return version >= 1;
case WL_SHELL_SURFACE_RESIZE_RIGHT:
return version >= 1;
case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT:
return version >= 1;
case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT:
return version >= 1;
default:
return false;
}
}
#endif /* WL_SHELL_SURFACE_RESIZE_ENUM_IS_VALID */
#endif /* WL_SHELL_SURFACE_RESIZE_ENUM */
#ifndef WL_SHELL_SURFACE_TRANSIENT_ENUM
#define WL_SHELL_SURFACE_TRANSIENT_ENUM
@ -2632,10 +2600,6 @@ enum wl_shell_surface_transient {
*/
WL_SHELL_SURFACE_TRANSIENT_INACTIVE = 0x1,
};
#endif /* WL_SHELL_SURFACE_TRANSIENT_ENUM */
#ifndef WL_SHELL_SURFACE_TRANSIENT_ENUM_IS_VALID
#define WL_SHELL_SURFACE_TRANSIENT_ENUM_IS_VALID
/**
* @ingroup iface_wl_shell_surface
* Validate a wl_shell_surface transient value.
@ -2645,12 +2609,14 @@ enum wl_shell_surface_transient {
*/
static inline bool
wl_shell_surface_transient_is_valid(uint32_t value, uint32_t version) {
uint32_t valid = 0;
if (version >= 1)
valid |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE;
return (value & ~valid) == 0;
switch (value) {
case WL_SHELL_SURFACE_TRANSIENT_INACTIVE:
return version >= 1;
default:
return false;
}
}
#endif /* WL_SHELL_SURFACE_TRANSIENT_ENUM_IS_VALID */
#endif /* WL_SHELL_SURFACE_TRANSIENT_ENUM */
#ifndef WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM
#define WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM
@ -2680,10 +2646,6 @@ enum wl_shell_surface_fullscreen_method {
*/
WL_SHELL_SURFACE_FULLSCREEN_METHOD_FILL = 3,
};
#endif /* WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM */
#ifndef WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM_IS_VALID
#define WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM_IS_VALID
/**
* @ingroup iface_wl_shell_surface
* Validate a wl_shell_surface fullscreen_method value.
@ -2706,7 +2668,7 @@ wl_shell_surface_fullscreen_method_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM_IS_VALID */
#endif /* WL_SHELL_SURFACE_FULLSCREEN_METHOD_ENUM */
/**
* @ingroup iface_wl_shell_surface
@ -3038,10 +3000,6 @@ enum wl_surface_error {
*/
WL_SURFACE_ERROR_INVALID_TRANSFORM = 1,
};
#endif /* WL_SURFACE_ERROR_ENUM */
#ifndef WL_SURFACE_ERROR_ENUM_IS_VALID
#define WL_SURFACE_ERROR_ENUM_IS_VALID
/**
* @ingroup iface_wl_surface
* Validate a wl_surface error value.
@ -3060,7 +3018,7 @@ wl_surface_error_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_SURFACE_ERROR_ENUM_IS_VALID */
#endif /* WL_SURFACE_ERROR_ENUM */
/**
* @ingroup iface_wl_surface
@ -3519,10 +3477,6 @@ enum wl_seat_capability {
*/
WL_SEAT_CAPABILITY_TOUCH = 4,
};
#endif /* WL_SEAT_CAPABILITY_ENUM */
#ifndef WL_SEAT_CAPABILITY_ENUM_IS_VALID
#define WL_SEAT_CAPABILITY_ENUM_IS_VALID
/**
* @ingroup iface_wl_seat
* Validate a wl_seat capability value.
@ -3532,16 +3486,18 @@ enum wl_seat_capability {
*/
static inline bool
wl_seat_capability_is_valid(uint32_t value, uint32_t version) {
uint32_t valid = 0;
if (version >= 1)
valid |= WL_SEAT_CAPABILITY_POINTER;
if (version >= 1)
valid |= WL_SEAT_CAPABILITY_KEYBOARD;
if (version >= 1)
valid |= WL_SEAT_CAPABILITY_TOUCH;
return (value & ~valid) == 0;
switch (value) {
case WL_SEAT_CAPABILITY_POINTER:
return version >= 1;
case WL_SEAT_CAPABILITY_KEYBOARD:
return version >= 1;
case WL_SEAT_CAPABILITY_TOUCH:
return version >= 1;
default:
return false;
}
}
#endif /* WL_SEAT_CAPABILITY_ENUM_IS_VALID */
#endif /* WL_SEAT_CAPABILITY_ENUM */
/**
* @ingroup iface_wl_seat
@ -3665,10 +3621,6 @@ enum wl_pointer_error {
*/
WL_POINTER_ERROR_ROLE = 0,
};
#endif /* WL_POINTER_ERROR_ENUM */
#ifndef WL_POINTER_ERROR_ENUM_IS_VALID
#define WL_POINTER_ERROR_ENUM_IS_VALID
/**
* @ingroup iface_wl_pointer
* Validate a wl_pointer error value.
@ -3685,7 +3637,7 @@ wl_pointer_error_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_POINTER_ERROR_ENUM_IS_VALID */
#endif /* WL_POINTER_ERROR_ENUM */
#ifndef WL_POINTER_BUTTON_STATE_ENUM
#define WL_POINTER_BUTTON_STATE_ENUM
@ -3706,10 +3658,6 @@ enum wl_pointer_button_state {
*/
WL_POINTER_BUTTON_STATE_PRESSED = 1,
};
#endif /* WL_POINTER_BUTTON_STATE_ENUM */
#ifndef WL_POINTER_BUTTON_STATE_ENUM_IS_VALID
#define WL_POINTER_BUTTON_STATE_ENUM_IS_VALID
/**
* @ingroup iface_wl_pointer
* Validate a wl_pointer button_state value.
@ -3728,7 +3676,7 @@ wl_pointer_button_state_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_POINTER_BUTTON_STATE_ENUM_IS_VALID */
#endif /* WL_POINTER_BUTTON_STATE_ENUM */
#ifndef WL_POINTER_AXIS_ENUM
#define WL_POINTER_AXIS_ENUM
@ -3748,10 +3696,6 @@ enum wl_pointer_axis {
*/
WL_POINTER_AXIS_HORIZONTAL_SCROLL = 1,
};
#endif /* WL_POINTER_AXIS_ENUM */
#ifndef WL_POINTER_AXIS_ENUM_IS_VALID
#define WL_POINTER_AXIS_ENUM_IS_VALID
/**
* @ingroup iface_wl_pointer
* Validate a wl_pointer axis value.
@ -3770,7 +3714,7 @@ wl_pointer_axis_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_POINTER_AXIS_ENUM_IS_VALID */
#endif /* WL_POINTER_AXIS_ENUM */
#ifndef WL_POINTER_AXIS_SOURCE_ENUM
#define WL_POINTER_AXIS_SOURCE_ENUM
@ -3818,10 +3762,6 @@ enum wl_pointer_axis_source {
* @ingroup iface_wl_pointer
*/
#define WL_POINTER_AXIS_SOURCE_WHEEL_TILT_SINCE_VERSION 6
#endif /* WL_POINTER_AXIS_SOURCE_ENUM */
#ifndef WL_POINTER_AXIS_SOURCE_ENUM_IS_VALID
#define WL_POINTER_AXIS_SOURCE_ENUM_IS_VALID
/**
* @ingroup iface_wl_pointer
* Validate a wl_pointer axis_source value.
@ -3844,7 +3784,7 @@ wl_pointer_axis_source_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_POINTER_AXIS_SOURCE_ENUM_IS_VALID */
#endif /* WL_POINTER_AXIS_SOURCE_ENUM */
/**
* @ingroup iface_wl_pointer
@ -4105,10 +4045,6 @@ enum wl_keyboard_keymap_format {
*/
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 = 1,
};
#endif /* WL_KEYBOARD_KEYMAP_FORMAT_ENUM */
#ifndef WL_KEYBOARD_KEYMAP_FORMAT_ENUM_IS_VALID
#define WL_KEYBOARD_KEYMAP_FORMAT_ENUM_IS_VALID
/**
* @ingroup iface_wl_keyboard
* Validate a wl_keyboard keymap_format value.
@ -4127,7 +4063,7 @@ wl_keyboard_keymap_format_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_KEYBOARD_KEYMAP_FORMAT_ENUM_IS_VALID */
#endif /* WL_KEYBOARD_KEYMAP_FORMAT_ENUM */
#ifndef WL_KEYBOARD_KEY_STATE_ENUM
#define WL_KEYBOARD_KEY_STATE_ENUM
@ -4147,10 +4083,6 @@ enum wl_keyboard_key_state {
*/
WL_KEYBOARD_KEY_STATE_PRESSED = 1,
};
#endif /* WL_KEYBOARD_KEY_STATE_ENUM */
#ifndef WL_KEYBOARD_KEY_STATE_ENUM_IS_VALID
#define WL_KEYBOARD_KEY_STATE_ENUM_IS_VALID
/**
* @ingroup iface_wl_keyboard
* Validate a wl_keyboard key_state value.
@ -4169,7 +4101,7 @@ wl_keyboard_key_state_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_KEYBOARD_KEY_STATE_ENUM_IS_VALID */
#endif /* WL_KEYBOARD_KEY_STATE_ENUM */
/**
* @ingroup iface_wl_keyboard
@ -4495,10 +4427,6 @@ enum wl_output_subpixel {
*/
WL_OUTPUT_SUBPIXEL_VERTICAL_BGR = 5,
};
#endif /* WL_OUTPUT_SUBPIXEL_ENUM */
#ifndef WL_OUTPUT_SUBPIXEL_ENUM_IS_VALID
#define WL_OUTPUT_SUBPIXEL_ENUM_IS_VALID
/**
* @ingroup iface_wl_output
* Validate a wl_output subpixel value.
@ -4525,7 +4453,7 @@ wl_output_subpixel_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_OUTPUT_SUBPIXEL_ENUM_IS_VALID */
#endif /* WL_OUTPUT_SUBPIXEL_ENUM */
#ifndef WL_OUTPUT_TRANSFORM_ENUM
#define WL_OUTPUT_TRANSFORM_ENUM
@ -4579,10 +4507,6 @@ enum wl_output_transform {
*/
WL_OUTPUT_TRANSFORM_FLIPPED_270 = 7,
};
#endif /* WL_OUTPUT_TRANSFORM_ENUM */
#ifndef WL_OUTPUT_TRANSFORM_ENUM_IS_VALID
#define WL_OUTPUT_TRANSFORM_ENUM_IS_VALID
/**
* @ingroup iface_wl_output
* Validate a wl_output transform value.
@ -4613,7 +4537,7 @@ wl_output_transform_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_OUTPUT_TRANSFORM_ENUM_IS_VALID */
#endif /* WL_OUTPUT_TRANSFORM_ENUM */
#ifndef WL_OUTPUT_MODE_ENUM
#define WL_OUTPUT_MODE_ENUM
@ -4634,10 +4558,6 @@ enum wl_output_mode {
*/
WL_OUTPUT_MODE_PREFERRED = 0x2,
};
#endif /* WL_OUTPUT_MODE_ENUM */
#ifndef WL_OUTPUT_MODE_ENUM_IS_VALID
#define WL_OUTPUT_MODE_ENUM_IS_VALID
/**
* @ingroup iface_wl_output
* Validate a wl_output mode value.
@ -4647,14 +4567,16 @@ enum wl_output_mode {
*/
static inline bool
wl_output_mode_is_valid(uint32_t value, uint32_t version) {
uint32_t valid = 0;
if (version >= 1)
valid |= WL_OUTPUT_MODE_CURRENT;
if (version >= 1)
valid |= WL_OUTPUT_MODE_PREFERRED;
return (value & ~valid) == 0;
switch (value) {
case WL_OUTPUT_MODE_CURRENT:
return version >= 1;
case WL_OUTPUT_MODE_PREFERRED:
return version >= 1;
default:
return false;
}
}
#endif /* WL_OUTPUT_MODE_ENUM_IS_VALID */
#endif /* WL_OUTPUT_MODE_ENUM */
/**
* @ingroup iface_wl_output
@ -4822,10 +4744,6 @@ enum wl_subcompositor_error {
*/
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE = 0,
};
#endif /* WL_SUBCOMPOSITOR_ERROR_ENUM */
#ifndef WL_SUBCOMPOSITOR_ERROR_ENUM_IS_VALID
#define WL_SUBCOMPOSITOR_ERROR_ENUM_IS_VALID
/**
* @ingroup iface_wl_subcompositor
* Validate a wl_subcompositor error value.
@ -4842,7 +4760,7 @@ wl_subcompositor_error_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_SUBCOMPOSITOR_ERROR_ENUM_IS_VALID */
#endif /* WL_SUBCOMPOSITOR_ERROR_ENUM */
/**
* @ingroup iface_wl_subcompositor
@ -4897,10 +4815,6 @@ enum wl_subsurface_error {
*/
WL_SUBSURFACE_ERROR_BAD_SURFACE = 0,
};
#endif /* WL_SUBSURFACE_ERROR_ENUM */
#ifndef WL_SUBSURFACE_ERROR_ENUM_IS_VALID
#define WL_SUBSURFACE_ERROR_ENUM_IS_VALID
/**
* @ingroup iface_wl_subsurface
* Validate a wl_subsurface error value.
@ -4917,7 +4831,7 @@ wl_subsurface_error_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* WL_SUBSURFACE_ERROR_ENUM_IS_VALID */
#endif /* WL_SUBSURFACE_ERROR_ENUM */
/**
* @ingroup iface_wl_subsurface

View file

@ -106,29 +106,6 @@ enum intf_A_foo {
#define INTF_A_FOO_DEPRECATED_SINCE_VERSION 2
#endif /* INTF_A_FOO_ENUM */
#ifndef INTF_A_BAR_ENUM
#define INTF_A_BAR_ENUM
enum intf_A_bar {
/**
* this is the first
*/
INTF_A_BAR_FIRST = 0x01,
/**
* this is the second
*/
INTF_A_BAR_SECOND = 0x02,
/**
* this is the third
* @since 2
*/
INTF_A_BAR_THIRD = 0x04,
};
/**
* @ingroup iface_intf_A
*/
#define INTF_A_BAR_THIRD_SINCE_VERSION 2
#endif /* INTF_A_BAR_ENUM */
/**
* @ingroup iface_intf_A
* @struct intf_A_listener

View file

@ -106,29 +106,6 @@ enum intf_A_foo {
#define INTF_A_FOO_DEPRECATED_SINCE_VERSION 2
#endif /* INTF_A_FOO_ENUM */
#ifndef INTF_A_BAR_ENUM
#define INTF_A_BAR_ENUM
enum intf_A_bar {
/**
* this is the first
*/
INTF_A_BAR_FIRST = 0x01,
/**
* this is the second
*/
INTF_A_BAR_SECOND = 0x02,
/**
* this is the third
* @since 2
*/
INTF_A_BAR_THIRD = 0x04,
};
/**
* @ingroup iface_intf_A
*/
#define INTF_A_BAR_THIRD_SINCE_VERSION 2
#endif /* INTF_A_BAR_ENUM */
/**
* @ingroup iface_intf_A
* @struct intf_A_listener

View file

@ -107,10 +107,6 @@ enum intf_A_foo {
* @ingroup iface_intf_A
*/
#define INTF_A_FOO_DEPRECATED_SINCE_VERSION 2
#endif /* INTF_A_FOO_ENUM */
#ifndef INTF_A_FOO_ENUM_IS_VALID
#define INTF_A_FOO_ENUM_IS_VALID
/**
* @ingroup iface_intf_A
* Validate a intf_A foo value.
@ -135,52 +131,7 @@ intf_A_foo_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* INTF_A_FOO_ENUM_IS_VALID */
#ifndef INTF_A_BAR_ENUM
#define INTF_A_BAR_ENUM
enum intf_A_bar {
/**
* this is the first
*/
INTF_A_BAR_FIRST = 0x01,
/**
* this is the second
*/
INTF_A_BAR_SECOND = 0x02,
/**
* this is the third
* @since 2
*/
INTF_A_BAR_THIRD = 0x04,
};
/**
* @ingroup iface_intf_A
*/
#define INTF_A_BAR_THIRD_SINCE_VERSION 2
#endif /* INTF_A_BAR_ENUM */
#ifndef INTF_A_BAR_ENUM_IS_VALID
#define INTF_A_BAR_ENUM_IS_VALID
/**
* @ingroup iface_intf_A
* Validate a intf_A bar value.
*
* @return true on success, false on error.
* @ref intf_A_bar
*/
static inline bool
intf_A_bar_is_valid(uint32_t value, uint32_t version) {
uint32_t valid = 0;
if (version >= 1)
valid |= INTF_A_BAR_FIRST;
if (version >= 1)
valid |= INTF_A_BAR_SECOND;
if (version >= 2)
valid |= INTF_A_BAR_THIRD;
return (value & ~valid) == 0;
}
#endif /* INTF_A_BAR_ENUM_IS_VALID */
#endif /* INTF_A_FOO_ENUM */
/**
* @ingroup iface_intf_A

View file

@ -107,10 +107,6 @@ enum intf_A_foo {
* @ingroup iface_intf_A
*/
#define INTF_A_FOO_DEPRECATED_SINCE_VERSION 2
#endif /* INTF_A_FOO_ENUM */
#ifndef INTF_A_FOO_ENUM_IS_VALID
#define INTF_A_FOO_ENUM_IS_VALID
/**
* @ingroup iface_intf_A
* Validate a intf_A foo value.
@ -135,52 +131,7 @@ intf_A_foo_is_valid(uint32_t value, uint32_t version) {
return false;
}
}
#endif /* INTF_A_FOO_ENUM_IS_VALID */
#ifndef INTF_A_BAR_ENUM
#define INTF_A_BAR_ENUM
enum intf_A_bar {
/**
* this is the first
*/
INTF_A_BAR_FIRST = 0x01,
/**
* this is the second
*/
INTF_A_BAR_SECOND = 0x02,
/**
* this is the third
* @since 2
*/
INTF_A_BAR_THIRD = 0x04,
};
/**
* @ingroup iface_intf_A
*/
#define INTF_A_BAR_THIRD_SINCE_VERSION 2
#endif /* INTF_A_BAR_ENUM */
#ifndef INTF_A_BAR_ENUM_IS_VALID
#define INTF_A_BAR_ENUM_IS_VALID
/**
* @ingroup iface_intf_A
* Validate a intf_A bar value.
*
* @return true on success, false on error.
* @ref intf_A_bar
*/
static inline bool
intf_A_bar_is_valid(uint32_t value, uint32_t version) {
uint32_t valid = 0;
if (version >= 1)
valid |= INTF_A_BAR_FIRST;
if (version >= 1)
valid |= INTF_A_BAR_SECOND;
if (version >= 2)
valid |= INTF_A_BAR_THIRD;
return (value & ~valid) == 0;
}
#endif /* INTF_A_BAR_ENUM_IS_VALID */
#endif /* INTF_A_FOO_ENUM */
/**
* @ingroup iface_intf_A

View file

@ -58,12 +58,5 @@
<entry name="negative" value="-1" since="2" summary="this is a negative value"/>
<entry name="deprecated" value="3" since="2" deprecated-since="3" summary="this is a deprecated value"/>
</enum>
<enum name="bar" bitfield="true">
<entry name="first" value="0x01" summary="this is the first"/>
<entry name="second" value="0x02" summary="this is the second"/>
<entry name="third" value="0x04" since="2" summary="this is the third"/>
</enum>
</interface>
</protocol>

View file

@ -924,7 +924,7 @@ TEST(versions)
}
static void
check_error_on_destroyed_object(void)
check_error_on_destroyed_object(void *data)
{
struct client *c;
struct wl_seat *seat;
@ -1043,7 +1043,7 @@ TEST(filtered_global_is_hidden)
1, d, bind_data_offer);
wl_display_set_global_filter(d->wl_display, global_filter, NULL);
client_create(d, get_globals, NULL);
client_create_noarg(d, get_globals);
display_run(d);
wl_global_destroy(g);
@ -1052,13 +1052,13 @@ TEST(filtered_global_is_hidden)
}
static void
get_dynamic_globals(void)
get_dynamic_globals(void *data)
{
struct client *c = client_connect();
struct wl_registry *registry;
registry = wl_display_get_registry(c->wl_display);
wl_registry_add_listener(registry, &registry_listener_filtered, NULL);
wl_registry_add_listener(registry, &registry_listener_filtered, data);
wl_display_roundtrip(c->wl_display);
/* Wait for the server to create a new global */
@ -1206,7 +1206,7 @@ static const struct wl_registry_listener zombie_fd_registry_listener = {
};
static void
zombie_client(void)
zombie_client(void *data)
{
struct client *c = client_connect();
struct wl_registry *registry;
@ -1376,7 +1376,7 @@ static const struct wl_registry_listener double_zombie_fd_registry_listener = {
};
static void
double_zombie_client(void)
double_zombie_client(void *data)
{
struct client *c = client_connect();
struct wl_registry *registry;
@ -1436,7 +1436,7 @@ static const struct wl_registry_listener bind_interface_mismatch_registry_listen
};
static void
registry_bind_interface_mismatch_client(void)
registry_bind_interface_mismatch_client(void *data)
{
struct client *c = client_connect();
struct wl_registry *registry;
@ -1598,7 +1598,7 @@ static const struct wl_registry_listener global_remove_before_registry_listener
};
static void
global_remove_before_client(void)
global_remove_before_client(void *data)
{
struct client *c = client_connect();
struct wl_registry *registry;
@ -1648,7 +1648,7 @@ static const struct wl_registry_listener global_remove_after_registry_listener =
};
static void
global_remove_after_client(void)
global_remove_after_client(void *data)
{
struct client *c = client_connect();
struct wl_registry *registry;
@ -1695,75 +1695,6 @@ TEST(global_remove)
display_destroy(d);
}
static void
dispatch_single_read_events(struct wl_display *d)
{
if (wl_display_prepare_read(d) < 0) {
return;
}
int ret = 0;
do {
ret = wl_display_flush(d);
} while (ret < 0 && (errno == EINTR || errno == EAGAIN));
assert(ret >= 0);
struct pollfd pfd[1];
pfd[0].fd = wl_display_get_fd(d);
pfd[0].events = POLLIN;
do {
ret = poll(pfd, 1, -1);
} while (ret < 0 && errno == EINTR);
assert(ret > 0);
wl_display_read_events(d);
}
static void
dispatch_single_client(void)
{
struct client *c = client_connect();
assert(wl_display_dispatch_pending_single(c->wl_display) == 0);
struct wl_registry *registry = wl_display_get_registry(c->wl_display);
dispatch_single_read_events(c->wl_display);
// [1815110.061] {Default Queue} wl_registry#3.global(1, "test", 1)
assert(wl_display_dispatch_pending_single(c->wl_display) == 1);
dispatch_single_read_events(c->wl_display);
// [1815110.067] {Default Queue} wl_registry#3.global(2, "wl_seat", 1)
assert(wl_display_dispatch_pending_single(c->wl_display) == 1);
// No more events
assert(wl_display_dispatch_pending_single(c->wl_display) == 0);
wl_registry_destroy(registry);
client_disconnect(c);
}
TEST(dispatch_single)
{
struct display *d = display_create();
struct wl_global *global = wl_global_create(d->wl_display,
&wl_seat_interface,
1, d, bind_seat);
client_create_noarg(d, dispatch_single_client);
display_run(d);
wl_global_destroy(global);
display_destroy(d);
}
static void
terminate_display(void *arg)
{

View file

@ -10,19 +10,4 @@ main(int argc, char *argv[]) {
assert(intf_A_foo_is_valid(INTF_A_FOO_THIRD, 2));
assert(intf_A_foo_is_valid(INTF_A_FOO_NEGATIVE, 2));
assert(intf_A_bar_is_valid(INTF_A_BAR_FIRST, 1));
assert(intf_A_bar_is_valid(INTF_A_BAR_FIRST, 2));
assert(intf_A_bar_is_valid(INTF_A_BAR_SECOND, 1));
assert(intf_A_bar_is_valid(INTF_A_BAR_SECOND, 2));
assert(intf_A_bar_is_valid(INTF_A_BAR_FIRST | INTF_A_BAR_SECOND, 1));
assert(intf_A_bar_is_valid(INTF_A_BAR_FIRST | INTF_A_BAR_SECOND, 2));
assert(!intf_A_bar_is_valid(INTF_A_BAR_THIRD, 1));
assert(!intf_A_bar_is_valid(INTF_A_BAR_FIRST | INTF_A_BAR_THIRD, 1));
assert(intf_A_bar_is_valid(INTF_A_BAR_THIRD, 2));
assert(intf_A_bar_is_valid(INTF_A_BAR_FIRST | INTF_A_BAR_THIRD, 2));
assert(!intf_A_bar_is_valid(0xFF, 1));
assert(!intf_A_bar_is_valid(0xFF, 2));
}

View file

@ -54,7 +54,7 @@ tests_protocol_c = custom_target(
output: 'tests-protocol.c'
)
exec_fd_leak_checker = executable(
executable(
'exec-fd-leak-checker',
'exec-fd-leak-checker.c',
dependencies: test_runner_dep
@ -96,116 +96,78 @@ if get_option('scanner')
endif
tests = {
'array-test': {},
'client-test': {
'extra_sources': [ wayland_server_protocol_h ],
},
'display-test': {
'extra_sources': [
wayland_client_protocol_h,
wayland_server_protocol_h,
tests_server_protocol_h,
tests_client_protocol_c,
tests_protocol_c,
],
},
'connection-test': {
'extra_sources': [
wayland_client_protocol_h,
wayland_server_protocol_h,
],
},
'event-loop-test': {
'extra_sources': [ wayland_server_protocol_h ],
},
'fixed-test': {},
'interface-test': {
'extra_sources': [ wayland_client_protocol_h ],
},
'list-test': {},
'map-test': {},
'sanity-test' : {
'extra_sources': [
wayland_client_protocol_h,
wayland_server_protocol_h,
],
'runtime_deps': [ exec_fd_leak_checker ],
},
'socket-test': {
'extra_sources': [
wayland_client_protocol_h,
wayland_server_protocol_h,
],
},
'queue-test': {
'extra_sources': [
wayland_client_protocol_h,
wayland_server_protocol_h,
],
},
'signal-test': {
'extra_sources': [ wayland_server_protocol_h ],
},
'newsignal-test': {
'extra_sources': [
# wayland-server.c is needed here to access wl_priv_* functions
files('../src/wayland-server.c'),
wayland_server_protocol_h,
],
},
'resources-test': {
'extra_sources': [ wayland_server_protocol_h ],
},
'message-test': {
'extra_sources': [
wayland_client_protocol_h,
wayland_server_protocol_h,
],
},
'compositor-introspection-test': {
'extra_sources': [
wayland_client_protocol_h,
wayland_server_protocol_h,
],
},
'protocol-logger-test': {
'extra_sources': [
wayland_client_protocol_h,
wayland_server_protocol_h,
],
},
'headers-test': {
'extra_sources': [
wayland_client_protocol_h,
wayland_server_protocol_h,
'headers-protocol-test.c',
wayland_client_protocol_core_h,
wayland_server_protocol_core_h,
'headers-protocol-core-test.c',
],
},
'os-wrappers-test': {
'runtime_deps': [ exec_fd_leak_checker ],
},
'proxy-test': {
'extra_sources': [
wayland_client_protocol_h,
wayland_server_protocol_h,
],
},
'enum-validator-test': {},
'array-test': [],
'client-test': [ wayland_server_protocol_h ],
'display-test': [
wayland_client_protocol_h,
wayland_server_protocol_h,
tests_server_protocol_h,
tests_client_protocol_c,
tests_protocol_c,
],
'connection-test': [
wayland_client_protocol_h,
wayland_server_protocol_h,
],
'event-loop-test': [ wayland_server_protocol_h ],
'fixed-test': [],
'interface-test': [ wayland_client_protocol_h ],
'list-test': [],
'map-test': [],
'sanity-test' : [
wayland_client_protocol_h,
wayland_server_protocol_h,
],
'socket-test': [
wayland_client_protocol_h,
wayland_server_protocol_h,
],
'queue-test': [
wayland_client_protocol_h,
wayland_server_protocol_h,
],
'signal-test': [ wayland_server_protocol_h ],
'newsignal-test': [
# wayland-server.c is needed here to access wl_priv_* functions
files('../src/wayland-server.c'),
wayland_server_protocol_h,
],
'resources-test': [ wayland_server_protocol_h ],
'message-test': [
wayland_client_protocol_h,
wayland_server_protocol_h,
],
'compositor-introspection-test': [
wayland_client_protocol_h,
wayland_server_protocol_h,
],
'protocol-logger-test': [
wayland_client_protocol_h,
wayland_server_protocol_h,
],
'headers-test': [
wayland_client_protocol_h,
wayland_server_protocol_h,
'headers-protocol-test.c',
wayland_client_protocol_core_h,
wayland_server_protocol_core_h,
'headers-protocol-core-test.c',
],
'os-wrappers-test': [],
'proxy-test': [
wayland_client_protocol_h,
wayland_server_protocol_h,
],
'enum-validator-test': [],
}
foreach test_name, test_extras : tests
test_extra_sources = test_extras.get('extra_sources', [])
test_runtime_deps = test_extras.get('runtime_deps', [])
foreach test_name, test_extra_sources: tests
test_sources = [ test_name + '.c' ] + test_extra_sources
test_deps = [test_runner_dep, epoll_dep]
bin = executable(test_name, test_sources, dependencies: test_deps)
test(
test_name,
bin,
depends: test_runtime_deps,
env: [
'TEST_SRC_DIR=@0@'.format(meson.current_source_dir()),
'TEST_BUILD_DIR=@0@'.format(meson.current_build_dir()),

View file

@ -40,7 +40,6 @@
#include "wayland-server.h"
#include "test-runner.h"
#include "test-compositor.h"
#include "../src/timespec-util.h"
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
@ -572,68 +571,6 @@ client_test_queue_names(void)
wl_display_disconnect(display);
}
static void
dispatch_timeout_sync_callback(void *data, struct wl_callback *callback,
uint32_t serial)
{
bool *done = data;
*done = true;
wl_callback_destroy(callback);
}
static const struct wl_callback_listener dispatch_timeout_sync_listener = {
dispatch_timeout_sync_callback
};
static void
client_test_queue_dispatch_simple(void)
{
struct wl_display *display;
struct timespec timeout;
struct wl_callback *callback;
bool done = false;
int ret = 0;
display = wl_display_connect(NULL);
assert(display);
callback = wl_display_sync(display);
assert(callback != NULL);
wl_callback_add_listener(callback, &dispatch_timeout_sync_listener, &done);
timespec_from_msec(&timeout, 1000);
while (!done) {
ret = wl_display_dispatch_timeout(display, &timeout);
assert(ret > 0);
}
wl_display_disconnect(display);
exit(0);
}
static void
client_test_queue_dispatch_timeout(void)
{
struct wl_display *display;
struct timespec timeout;
int ret = 0;
display = wl_display_connect(NULL);
assert(display);
timespec_from_msec(&timeout, 100);
ret = wl_display_dispatch_timeout(display, &timeout);
assert(ret == 0);
wl_display_disconnect(display);
exit(0);
}
static void
dummy_bind(struct wl_client *client,
void *data, uint32_t version, uint32_t id)
@ -772,27 +709,3 @@ TEST(queue_names)
display_destroy(d);
}
TEST(queue_dispatch_simple)
{
struct display *d = display_create();
test_set_timeout(2);
client_create_noarg(d, client_test_queue_dispatch_simple);
display_run(d);
display_destroy(d);
}
TEST(queue_dispatch_timeout)
{
struct display *d = display_create();
test_set_timeout(2);
client_create_noarg(d, client_test_queue_dispatch_timeout);
display_run(d);
display_destroy(d);
}

View file

@ -507,7 +507,7 @@ static const struct wl_registry_listener registry_listener =
NULL
};
struct client *client_connect(void)
struct client *client_connect()
{
struct wl_registry *reg;
struct client *c = calloc(1, sizeof *c);

View file

@ -118,17 +118,5 @@ struct client_info *client_create_with_name(struct display *d,
void *data,
const char *name);
#define client_create(d, c, data) client_create_with_name((d), (c), data, (#c))
static inline void noarg_cb(void *data)
{
void (*cb)(void) = data;
cb();
}
static inline struct client_info *client_create_with_name_noarg(struct display *d,
void (*client_main)(void),
const char *name)
{
return client_create_with_name(d, noarg_cb, client_main, name);
}
#define client_create_noarg(d, c) \
client_create_with_name_noarg((d), (c), (#c))
client_create_with_name((d), (void(*)(void *)) (c), NULL, (#c))