Compare commits

..

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

235 changed files with 10127 additions and 45242 deletions

View file

@ -1,24 +0,0 @@
root = true
[*]
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = tab
indent_size = 8
max_line_length = 80
[*.{xml,xsl}]
indent_style = space
indent_size = 2
tab_width = 8
[*.py]
indent_style = space
indent_size = 4
[*.yml]
indent_style = space
indent_size = 2
max_line_length = off

View file

@ -1,4 +0,0 @@
# Use the following command to ignore the following commits in git blame:
# git config blame.ignoreRevsFile .git-blame-ignore-revs
77b9eb76369e27142b8be296b5f2eb1ca466272a # protocol: reindent wayland.xml

54
.gitignore vendored
View file

@ -1,8 +1,58 @@
*.announce
*.sig
*.deps
*.jpg
*.la
*.lo
*.o
*.pc
*.so
*.swp
*.3
*.7
*.log
*.trs
*.tar.xz
*~
.libs
.dirstamp
cscope.out
ctags
/aclocal.m4
/wayland-scanner.m4
/autom4te.cache
/compile
/config.guess
/config.h
/config.h.in
/config.log
/config.mk
/config.status
/config.sub
/configure
/depcomp
/install-sh
/libtool
/ltmain.sh
/missing
/stamp-h1
/test-driver
Makefile
Makefile.in
array-test
client-test
connection-test
display-test
event-loop-test
exec-fd-leak-checker
fixed-benchmark
fixed-test
list-test
map-test
message-test
os-wrappers-test
queue-test
resources-test
sanity-test
signal-test
socket-test
wayland-scanner
protocol/*.[ch]

View file

@ -1,356 +0,0 @@
# This file uses the freedesktop ci-templates to build Wayland and run our
# tests in CI.
#
# ci-templates uses a multi-stage build process. First, the base container
# image is built which contains the core distribution, the toolchain, and
# all our build dependencies. This container is aggressively cached; if a
# container image matching $FDO_DISTRIBUTION_TAG is found in either the
# upstream repo (wayland/weston) or the user's downstream repo, it is
# reused for the build. This gives us predictability of build and far
# quicker runtimes, however it means that any changes to the base container
# must also change $FDO_DISTRIBUTION_TAG. When changing this, please use
# the current date as well as a unique build identifier.
#
# After the container is either rebuilt (tag mismatch) or reused (tag
# previously used), the build stage executes within this container.
#
# The final stage is used to expose documentation and coverage information,
# including publishing documentation to the public site when built on the
# main branch.
#
# Apart from the 'variables', 'include', and 'stages' top-level anchors,
# everything not beginning with a dot ('.') is the name of a job which will
# be executed as part of CI, unless the rules specify that it should not be
# run.
#
# Variables prefixed with CI_ are generally provided by GitLab itself;
# variables prefixed with FDO_ and templates prefixed by .fdo are provided
# by the ci-templates.
#
# For more information on GitLab CI, including the YAML syntax, see:
# https://docs.gitlab.com/ee/ci/yaml/README.html
#
# Note that freedesktop.org uses the 'Community Edition' of GitLab, so features
# marked as 'premium' or 'ultimate' are not available to us.
#
# For more information on ci-templates, see:
# - documentation at https://freedesktop.pages.freedesktop.org/ci-templates/
# - repo at https://gitlab.freedesktop.org/freedesktop/ci-templates/
include:
- project: 'freedesktop/ci-templates'
# Here we use a fixed ref in order to isolate ourselves from ci-templates
# 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
file:
- '/templates/debian.yml'
- '/templates/freebsd.yml'
- '/templates/ci-fairy.yml'
variables:
FDO_UPSTREAM_REPO: wayland/wayland
FDO_REPO_SUFFIX: "$BUILD_OS/$BUILD_ARCH"
# Define the build stages. These are used for UI grouping as well as
# dependencies.
stages:
- "Merge request checks"
- "Base container"
- "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
# Base variables used for anything using a Debian environment
.os-debian:
variables:
BUILD_OS: debian
FDO_DISTRIBUTION_VERSION: trixie
FDO_DISTRIBUTION_PACKAGES: 'build-essential pkg-config libexpat1-dev libffi-dev libxml2-dev doxygen graphviz xmlto xsltproc docbook-xsl mdbook meson ninja-build'
# bump this tag every time you change something which requires rebuilding the
# base image
FDO_DISTRIBUTION_TAG: "2026-01-31.0"
.debian-x86_64:
extends:
- .os-debian
variables:
BUILD_ARCH: "x86-64"
.debian-aarch64:
extends:
- .os-debian
variables:
BUILD_ARCH: "aarch64"
.debian-armv7:
extends:
- .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.
check-commit:
extends:
- .fdo.ci-fairy
stage: "Merge request checks"
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: always
- when: never
script:
- ci-fairy check-commits --signed-off-by --junit-xml=results.xml
variables:
GIT_DEPTH: 100
artifacts:
reports:
junit: results.xml
# Build our base container image, which contains the core distribution, the
# toolchain, and all our build dependencies. This will be reused in the build
# stage.
x86_64-debian-container_prep:
extends:
- .ci-rules
- .debian-x86_64
- .fdo.container-build@debian
stage: "Base container"
variables:
GIT_STRATEGY: none
aarch64-debian-container_prep:
extends:
- .ci-rules
- .debian-aarch64
- .fdo.container-build@debian
tags:
- aarch64
stage: "Base container"
variables:
GIT_STRATEGY: none
armv7-debian-container_prep:
extends:
- .ci-rules
- .debian-armv7
- .fdo.container-build@debian
tags:
- aarch64
stage: "Base container"
variables:
GIT_STRATEGY: none
# Core build environment.
.build-env:
variables:
MESON_BUILD_TYPE: "-Dbuildtype=debug -Doptimization=0 -Db_sanitize=address,undefined -Ddocbook_validation=true"
# See https://gitlab.freedesktop.org/wayland/wayland/-/merge_requests/154
ASAN_OPTIONS: "detect_odr_violation=0"
before_script:
- export BUILD_ID="wayland-$CI_JOB_NAME"
- export PREFIX="${CI_PROJECT_DIR}/prefix-${BUILD_ID}"
- export BUILDDIR="${CI_PROJECT_DIR}/build-${BUILD_ID}"
- mkdir "$BUILDDIR" "$PREFIX"
# Build variants to be stacked on as required.
.build-release:
stage: "Other build configurations"
variables:
MESON_BUILD_TYPE: "-Dbuildtype=release"
# OS/architecture-specific variants
.build-env-debian-x86_64:
extends:
- .fdo.suffixed-image@debian
- .debian-x86_64
- .build-env
needs:
- job: x86_64-debian-container_prep
artifacts: false
.build-env-debian-aarch64:
extends:
- .fdo.suffixed-image@debian
- .debian-aarch64
- .build-env
variables:
# At least with the versions we have, the LSan runtime makes fork unusably
# slow on AArch64, which is bad news since the test suite decides to fork
# for every single subtest. For now, in order to get AArch64 builds and
# tests into CI, just assume that we're not going to leak any more on
# AArch64 than we would on ARMv7 or x86-64.
ASAN_OPTIONS: "detect_leaks=0,detect_odr_violation=0"
tags:
- aarch64
needs:
- job: aarch64-debian-container_prep
artifacts: false
.build-env-debian-armv7:
extends:
- .fdo.suffixed-image@debian
- .debian-armv7
- .build-env
tags:
- aarch64
needs:
- job: armv7-debian-container_prep
artifacts: false
# Full build and test.
.do-build:
extends:
- .ci-rules
stage: "Build and test"
script:
- meson setup $BUILDDIR --prefix="$PREFIX" -Dicon_directory=/usr/share/X11/icons --fatal-meson-warnings -Dwerror=true ${MESON_BUILD_TYPE}
- ninja -C $BUILDDIR -k0 -j${FDO_CI_CONCURRENT:-4}
- meson test -C $BUILDDIR --num-processes ${FDO_CI_CONCURRENT:-4}
- ninja -C $BUILDDIR install
- ninja -C $BUILDDIR clean
artifacts:
name: wayland-$CI_JOB_NAME
when: always
paths:
- build-*/meson-logs
- prefix-*
reports:
junit: build-*/meson-logs/testlog.junit.xml
# Full build and test.
.do-build-qemu:
extends:
- .ci-rules
stage: "Build and test"
script:
# Start the VM and copy our workspace to the VM
- /app/vmctl start
- scp -r $PWD "vm:"
# The `set +e is needed to ensure that we always copy the meson logs back to
# the workspace to see details about the failed tests.
- |
set +e
/app/vmctl exec "pkg info; cd $CI_PROJECT_NAME ; meson setup $BUILDDIR --prefix=$PREFIX $MESON_BUILD_TYPE $MESON_ARGS && ninja -C $BUILDDIR -j${FDO_CI_CONCURRENT:-4}"
/app/vmctl exec "meson test --print-errorlogs -C $BUILDDIR --num-processes ${FDO_CI_CONCURRENT:-4}" && touch .tests-successful
set -ex
scp -r vm:$BUILDDIR/meson-logs .
/app/vmctl exec "ninja -C $BUILDDIR install"
mkdir -p $PREFIX && scp -r vm:$PREFIX/ $PREFIX/
# Finally, shut down the VM.
- /app/vmctl stop
- test -f .tests-successful || exit 1
artifacts:
name: wayland-$CI_JOB_NAME
when: always
paths:
- meson-logs
- prefix-*
reports:
junit: meson-logs/testlog.junit.xml
# Full build and test.
x86_64-debian-build:
extends:
- .build-env-debian-x86_64
- .do-build
x86_64-release-debian-build:
extends:
- .build-env-debian-x86_64
- .do-build
- .build-release
aarch64-debian-build:
extends:
- .build-env-debian-aarch64
- .do-build
aarch64-release-debian-build:
extends:
- .build-env-debian-aarch64
- .do-build
- .build-release
armv7-debian-build:
extends:
- .build-env-debian-armv7
- .do-build
armv7-release-debian-build:
extends:
- .build-env-debian-armv7
- .do-build
- .build-release
# Base variables used for anything using a FreeBSD environment
.os-freebsd:
variables:
BUILD_OS: freebsd
FDO_DISTRIBUTION_VERSION: "14.4"
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: "2026-03-10.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"
.freebsd-x86_64:
extends:
- .os-freebsd
variables:
BUILD_ARCH: "x86_64"
x86_64-freebsd-container_prep:
extends:
- .ci-rules
- .freebsd-x86_64
- .fdo.qemu-build@freebsd@x86_64
stage: "Base container"
variables:
GIT_STRATEGY: none
.build-env-freebsd-x86_64:
variables:
# Compiling with ASan+UBSan appears to trigger an infinite loop in the
# compiler shipped with FreeBSD 13.0, so we only use UBSan here.
# Additionally, sanitizers can't be used with b_lundef on FreeBSD.
MESON_BUILD_TYPE: "-Dbuildtype=debug -Db_sanitize=undefined -Db_lundef=false"
extends:
- .fdo.suffixed-image@freebsd
- .freebsd-x86_64
- .build-env
needs:
- job: x86_64-freebsd-container_prep
artifacts: false
# Full build and test.
x86_64-freebsd-build:
extends:
- .build-env-freebsd-x86_64
- .do-build-qemu
x86_64-release-freebsd-build:
extends:
- .build-env-freebsd-x86_64
- .do-build-qemu
- .build-release

View file

@ -1,8 +0,0 @@
<!--
This repository is for the Wayland protocol description and the libwayland IPC helper
library only. Issues with Wayland during day-to-day usage are almost
certainly a bug in your compositor and **not** a bug with in this
repository.
Please remove this comment before filing your issue.
-->

View file

@ -1,3 +0,0 @@
Faith Ekstrand <faith@gfxstrand.net> <jason@jlekstrand.net>
Faith Ekstrand <faith@gfxstrand.net> <jason.ekstrand@intel.com>
Faith Ekstrand <faith@gfxstrand.net> <jason.ekstrand@collabora.com>

View file

@ -1,33 +0,0 @@
# This is a set of bugbot commands for issues and merge requests - setting any of the
# bugbot::foo labels will trigger gitlab-triage to run with this ruleset (well, the
# one we have on the main branch at the time)
#
# Note that for adding labels, the label must first created in the project.
resource_rules:
issues:
rules:
- name: "Close bugs that aren't Wayland bugs"
conditions:
labels:
- "bugbot::not-wayland"
actions:
remove_labels:
- "bugbot::not-wayland"
comment: |
Thank you for the report, but your issue does not look like it would belong here. Sorry.
This repository is for the Wayland protocol specification and the
low-level C library that deals with the protocol.
This issue here is a bug not with the protocol itself but with either
- your compositor or desktop environment's implementation of the Wayland protocol and surrounding functionality,
- the individual application that triggers this issue, or
- the kernel driver used by your hardware
Please file the issue against your compositor/desktop environment, the application
or the kernel drivers instead, whichever seems more likely to you. If you are not sure,
file an issue against the application.
status: "close"
merge_requests:
rules:
[]

View file

@ -1,344 +0,0 @@
Contributing to Wayland
=======================
Sending patches
---------------
Patches should be sent via
[GitLab merge requests](https://docs.gitlab.com/ce/gitlab-basics/add-merge-request.html).
Wayland is
[hosted on freedesktop.org's GitLab](https://gitlab.freedesktop.org/wayland/wayland/):
in order to submit code, you should create an account on this GitLab instance,
fork the core Wayland repository, push your changes to a branch in your new
repository, and then submit these patches for review through a merge request.
Wayland formerly accepted patches via `git-send-email`, sent to
**wayland-devel@lists.freedesktop.org**; these were
[tracked using Patchwork](https://patchwork.freedesktop.org/project/wayland/).
Some old patches continue to be sent this way, and we may accept small new
patches sent to the list, but please send all new patches through GitLab merge
requests.
Formatting and separating commits
---------------------------------
Unlike many projects using GitHub and GitLab, Wayland has a
[linear, 'recipe' style history](http://www.bitsnbites.eu/git-history-work-log-vs-recipe/).
This means that every commit should be small, digestible, stand-alone, and
functional. Rather than a purely chronological commit history like this:
connection: plug a fd leak
plug another fd leak
connection: init fds to -1
close all fds
refactor checks into a new function
don't close fds we handed out
we aim to have a clean history which only reflects the final state, broken up
into functional groupings:
connection: Refactor out closure allocation
connection: Clear fds we shouldn't close to -1
connection: Make wl_closure_destroy() close fds of undispatched closures
This ensures that the final patch series only contains the final state,
without the changes and missteps taken along the development process.
The first line of a commit message should contain a prefix indicating
what part is affected by the patch followed by one sentence that
describes the change. For examples:
protocol: Support scaled outputs and surfaces
and
doc: generate server documentation from XML too
If in doubt what prefix to use, look at other commits that change the
same file(s) as the patch being sent.
The body of the commit message should describe what the patch changes
and why, and also note any particular side effects. This shouldn't be
empty on most of the cases. It shouldn't take a lot of effort to write
a commit message for an obvious change, so an empty commit message
body is only acceptable if the questions "What?" and "Why?" are already
answered on the one-line summary.
The lines of the commit message should have at most 76 characters, to
cope with the way git log presents them.
See [notes on commit messages] for a recommended reading on writing commit
messages.
Your patches should also include a Signed-off-by line with your name and
email address. If you're not the patch's original author, you should
also gather S-o-b's by them (and/or whomever gave the patch to you.) The
significance of this is that it certifies that you created the patch,
that it was created under an appropriate open source license, or
provided to you under those terms. This lets us indicate a chain of
responsibility for the copyright status of the code.
We won't reject patches that lack S-o-b, but it is strongly recommended.
When you re-send patches, revised or not, it would be very good to document the
changes compared to the previous revision in the commit message and/or the
merge request. If you have already received Reviewed-by or Acked-by tags, you
should evaluate whether they still apply and include them in the respective
commit messages. Otherwise the tags may be lost, reviewers miss the credit they
deserve, and the patches may cause redundant review effort.
Tracking patches and following up
---------------------------------
Once submitted to GitLab, your patches will be reviewed by the Wayland
development team on GitLab. Review may be entirely positive and result in your
code landing instantly, in which case, great! You're done. However, we may ask
you to make some revisions: fixing some bugs we've noticed, working to a
slightly different design, or adding documentation and tests.
If you do get asked to revise the patches, please bear in mind the notes above.
You should use `git rebase -i` to make revisions, so that your patches follow
the clear linear split documented above. Following that split makes it easier
for reviewers to understand your work, and to verify that the code you're
submitting is correct.
A common request is to split single large patch into multiple patches. This can
happen, for example, if when adding a new feature you notice a bug elsewhere
which you need to fix to progress. Separating these changes into separate
commits will allow us to verify and land the bugfix quickly, pushing part of
your work for the good of everyone, whilst revision and discussion continues on
the larger feature part. It also allows us to direct you towards reviewers who
best understand the different areas you are working on.
When you have made any requested changes, please rebase the commits, verify
that they still individually look good, then force-push your new branch to
GitLab. This will update the merge request and notify everyone subscribed to
your merge request, so they can review it again.
There are also
[many GitLab CLI clients](https://about.gitlab.com/applications/#cli-clients),
if you prefer to avoid the web interface. It may be difficult to follow review
comments without using the web interface though, so we do recommend using this
to go through the review process, even if you use other clients to track the
list of available patches.
Coding style
------------
You should follow the style of the file you're editing. In general, we
try to follow the rules below.
**Note: this file uses spaces due to markdown rendering issues for tabs.
Code must be implemented using tabs.**
- indent with tabs, and a tab is always 8 characters wide
- opening braces are on the same line as the if statement;
- no braces in an if-body with just one statement;
- if one of the branches of an if-else condition has braces, then the
other branch should also have braces;
- there is always an empty line between variable declarations and the
code;
```c
static int
my_function(void)
{
int a = 0;
if (a)
b();
else
c();
if (a) {
b();
c();
} else {
d();
}
}
```
- lines should be less than 80 characters wide;
- when breaking lines with functions calls, the parameters are aligned
with the opening parentheses;
- when assigning a variable with the result of a function call, if the
line would be longer we break it around the equal '=' sign if it makes
sense;
```c
long_variable_name =
function_with_a_really_long_name(parameter1, parameter2,
parameter3, parameter4);
x = function_with_a_really_long_name(parameter1, parameter2,
parameter3, parameter4);
```
Conduct
=======
As a freedesktop.org project, Wayland follows the Contributor Covenant,
found at:
https://www.freedesktop.org/wiki/CodeOfConduct
Please conduct yourself in a respectful and civilised manner when
interacting with community members on mailing lists, IRC, or bug
trackers. The community represents the project as a whole, and abusive
or bullying behaviour is not tolerated by the project.
Licensing
=========
Wayland is licensed with the intention to be usable anywhere X.org is.
Originally, X.org was covered under the MIT X11 license, but changed to
the MIT Expat license. Similarly, Wayland was covered initially as MIT
X11 licensed, but changed to the MIT Expat license, following in X.org's
footsteps. Other than wording, the two licenses are substantially the
same, with the exception of a no-advertising clause in X11 not included
in Expat.
New source code files should specify the MIT Expat license in their
boilerplate, as part of the copyright statement.
Review
======
All patches, even trivial ones, require at least one positive review
(Reviewed-by). Additionally, if no Reviewed-by's have been given by
people with commit access, there needs to be at least one Acked-by from
someone with commit access. A person with commit access is expected to be
able to evaluate the patch with respect to the project scope and architecture.
The below review guidelines are intended to be interpreted in spirit, not by
the letter. There may be circumstances where some guidelines are better
ignored. We rely very much on the judgement of reviewers and commit rights
holders.
During review, the following matters should be checked:
- The commit message explains why the change is being made.
- The code fits the project's scope.
- The code license is the same MIT licence the project generally uses.
- Stable ABI or API is not broken.
- Stable ABI or API additions must be justified by actual use cases, not only
by speculation. They must also be documented, and it is strongly recommended to
include tests exercising the additions in the test suite.
- The code fits the existing software architecture, e.g. no layering
violations.
- The code is correct and does not introduce new failures for existing users,
does not add new corner-case bugs, and does not introduce new compiler
warnings.
- The patch does what it says in the commit message and changes nothing else.
- The patch is a single logical change. If the commit message addresses
multiple points, it is a hint that the commit might need splitting up.
- A bug fix should target the underlying root cause instead of hiding symptoms.
If a complete fix is not practical, partial fixes are acceptable if they come
with code comments and filed Gitlab issues for the remaining bugs.
- The bug root cause rule applies to external software components as well, e.g.
do not work around kernel driver issues in userspace.
- The test suite passes.
- The code does not depend on API or ABI which has no working free open source
implementation.
- The code is not dead or untestable. E.g. if there are no free open source
software users for it then it is effectively dead code.
- The code is written to be easy to understand, or if code cannot be clear
enough on its own there are code comments to explain it.
- The code is minimal, i.e. prefer refactor and re-use when possible unless
clarity suffers.
- The code adheres to the style guidelines.
- In a patch series, every intermediate step adheres to the above guidelines.
Commit rights
=============
Commit rights will be granted to anyone who requests them and fulfills the
below criteria:
- Submitted some (10 as a rule of thumb) non-trivial (not just simple
spelling fixes and whitespace adjustment) patches that have been merged
already.
- Are actively participating in public discussions about their work (on the
mailing list or IRC). This should not be interpreted as a requirement to
review other peoples patches but just make sure that patch submission isn't
one-way communication. Cross-review is still highly encouraged.
- Will be regularly contributing further patches. This includes regular
contributors to other parts of the open source graphics stack who only
do the occasional development in this project.
- Agrees to use their commit rights in accordance with the documented merge
criteria, tools, and processes.
To apply for commit rights, create a new issue in gitlab for the respective
project and give it the "accounts" label.
Committers are encouraged to request their commit rights get removed when they
no longer contribute to the project. Commit rights will be reinstated when they
come back to the project.
Maintainers and committers should encourage contributors to request commit
rights, especially junior contributors tend to underestimate their skills.
Stabilising for releases
========================
A release cycle ends with a stable release which also starts a new cycle and
lifts any code freezes. Gradual code freezing towards a stable release starts
with an alpha release. The release stages of a cycle are:
- **Alpha release**:
Signified by version number #.#.91.
Major features must have landed before this. Major features include
invasive code motion and refactoring, high risk changes, and new stable
library ABI.
- **Beta release**:
Signified by version number #.#.92.
Minor features must have landed before this. Minor features include all
new features that are not major, low risk changes, clean-ups, and
documentation. Stable ABI that was new in the alpha release can be removed
before a beta release if necessary.
- **Release candidates (RC)**:
Signified by version number #.#.93 and up to #.#.99.
Bug fixes that are not release critical must have landed before this.
Release critical bug fixes can still be landed after this, but they may
call for another RC.
- **Stable release**:
Signified by version number #.#.0.
Ideally no changes since the last RC.
Mind that version #.#.90 is never released. It is used during development when
no code freeze is in effect. Stable branches and point releases are not covered
by the above.
[git documentation]: http://git-scm.com/documentation
[notes on commit messages]: http://who-t.blogspot.de/2009/12/on-commit-messages.html

39
COPYING
View file

@ -3,27 +3,20 @@ Copyright © 2010-2012 Intel Corporation
Copyright © 2011 Benjamin Franzke
Copyright © 2012 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:
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that copyright
notice and this permission notice appear in supporting documentation, and
that the name of the copyright holders not be used in advertising or
publicity pertaining to distribution of the software without specific,
written prior permission. The copyright holders make no representations
about the suitability of this software for any purpose. It is provided "as
is" without express or implied warranty.
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.
---
The above is the version of the MIT "Expat" License used by X.org:
http://cgit.freedesktop.org/xorg/xserver/tree/COPYING
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
OF THIS SOFTWARE.

198
Makefile.am Normal file
View file

@ -0,0 +1,198 @@
if BUILD_DOCS
SUBDIRS = doc
endif
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
aclocaldir = $(datadir)/aclocal
dist_aclocal_DATA = wayland-scanner.m4
dist_pkgdata_DATA = \
wayland-scanner.mk \
protocol/wayland.xml \
protocol/wayland.dtd
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA =
lib_LTLIBRARIES = libwayland-server.la libwayland-client.la
noinst_LTLIBRARIES = libwayland-util.la
include_HEADERS = \
src/wayland-util.h \
src/wayland-server.h \
src/wayland-client.h \
src/wayland-egl.h \
src/wayland-version.h
nodist_include_HEADERS = \
protocol/wayland-server-protocol.h \
protocol/wayland-client-protocol.h
libwayland_util_la_SOURCES = \
src/connection.c \
src/wayland-util.c \
src/wayland-util.h \
src/wayland-os.c \
src/wayland-os.h \
src/wayland-private.h
libwayland_server_la_CFLAGS = $(FFI_CFLAGS) $(GCC_CFLAGS) -pthread
libwayland_server_la_LIBADD = $(FFI_LIBS) libwayland-util.la -lrt -lm
libwayland_server_la_LDFLAGS = -version-info 1:0:1
libwayland_server_la_SOURCES = \
src/wayland-server.c \
src/wayland-shm.c \
src/event-loop.c
nodist_libwayland_server_la_SOURCES = \
protocol/wayland-server-protocol.h \
protocol/wayland-protocol.c
libwayland_client_la_CFLAGS = $(FFI_CFLAGS) $(GCC_CFLAGS) -pthread
libwayland_client_la_LIBADD = $(FFI_LIBS) libwayland-util.la -lrt -lm
libwayland_client_la_LDFLAGS = -version-info 3:0:3
libwayland_client_la_SOURCES = \
src/wayland-client.c
nodist_libwayland_client_la_SOURCES = \
protocol/wayland-client-protocol.h \
protocol/wayland-protocol.c
pkgconfig_DATA += src/wayland-client.pc src/wayland-server.pc
if ENABLE_SCANNER
wayland_scanner = $(top_builddir)/wayland-scanner
bin_PROGRAMS = wayland-scanner
wayland_scanner_SOURCES = src/scanner.c
wayland_scanner_LDADD = $(EXPAT_LIBS) libwayland-util.la
$(BUILT_SOURCES) : wayland-scanner
pkgconfig_DATA += src/wayland-scanner.pc
else
wayland_scanner = wayland-scanner
endif
protocol/%-protocol.c : $(top_srcdir)/protocol/%.xml
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && $(wayland_scanner) code < $< > $@
protocol/%-server-protocol.h : $(top_srcdir)/protocol/%.xml
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && $(wayland_scanner) server-header < $< > $@
protocol/%-client-protocol.h : $(top_srcdir)/protocol/%.xml
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && $(wayland_scanner) client-header < $< > $@
BUILT_SOURCES = \
$(nodist_libwayland_server_la_SOURCES) \
$(nodist_libwayland_client_la_SOURCES)
CLEANFILES = $(BUILT_SOURCES)
DISTCLEANFILES = src/wayland-version.h
EXTRA_DIST = src/wayland-version.h.in
lib_LTLIBRARIES += libwayland-cursor.la
include_HEADERS += cursor/wayland-cursor.h
libwayland_cursor_la_SOURCES = \
cursor/wayland-cursor.c \
cursor/os-compatibility.c \
cursor/os-compatibility.h \
cursor/cursor-data.h \
cursor/xcursor.c \
cursor/xcursor.h
libwayland_cursor_la_LIBADD = libwayland-client.la
pkgconfig_DATA += cursor/wayland-cursor.pc
libwayland_cursor_la_CFLAGS = \
$(GCC_CFLAGS) \
-I$(top_builddir)/src \
-I$(top_srcdir)/src \
-DICONDIR=\"$(ICONDIR)\"
TESTS = \
array-test \
client-test \
display-test \
connection-test \
event-loop-test \
fixed-test \
list-test \
map-test \
os-wrappers-test \
sanity-test \
socket-test \
queue-test \
signal-test \
resources-test \
message-test
check_PROGRAMS = \
$(TESTS) \
exec-fd-leak-checker
noinst_PROGRAMS = \
fixed-benchmark
check_LTLIBRARIES = libtest-runner.la
libtest_runner_la_SOURCES = \
tests/test-runner.c \
tests/test-runner.h \
tests/test-helpers.c \
tests/test-compositor.h \
tests/test-compositor.c
libtest_runner_la_LIBADD = \
libwayland-util.la \
libwayland-client.la \
libwayland-server.la \
-lrt -ldl $(FFI_LIBS)
array_test_SOURCES = tests/array-test.c
array_test_LDADD = libtest-runner.la
client_test_SOURCES = tests/client-test.c
client_test_LDADD = libtest-runner.la
display_test_SOURCES = tests/display-test.c
display_test_LDADD = libtest-runner.la
connection_test_SOURCES = tests/connection-test.c
connection_test_LDADD = libtest-runner.la
event_loop_test_SOURCES = tests/event-loop-test.c
event_loop_test_LDADD = libtest-runner.la
fixed_test_SOURCES = tests/fixed-test.c
fixed_test_LDADD = libtest-runner.la
list_test_SOURCES = tests/list-test.c
list_test_LDADD = libtest-runner.la
map_test_SOURCES = tests/map-test.c
map_test_LDADD = libtest-runner.la
sanity_test_SOURCES = tests/sanity-test.c
sanity_test_LDADD = libtest-runner.la
socket_test_SOURCES = tests/socket-test.c
socket_test_LDADD = libtest-runner.la
queue_test_SOURCES = tests/queue-test.c
queue_test_LDADD = libtest-runner.la
signal_test_SOURCES = tests/signal-test.c
signal_test_LDADD = libtest-runner.la
resources_test_SOURCES = tests/resources-test.c
resources_test_LDADD = libtest-runner.la
message_test_SOURCES = tests/message-test.c
message_test_LDADD = libtest-runner.la
fixed_benchmark_SOURCES = tests/fixed-benchmark.c
fixed_benchmark_LDADD = libtest-runner.la
os_wrappers_test_SOURCES = tests/os-wrappers-test.c
os_wrappers_test_LDADD = libtest-runner.la
AM_CPPFLAGS = \
-I$(top_builddir)/src \
-I$(top_srcdir)/src \
-I$(top_builddir)/protocol
AM_CFLAGS = $(GCC_CFLAGS) $(FFI_CFLAGS)
exec_fd_leak_checker_SOURCES = tests/exec-fd-leak-checker.c
exec_fd_leak_checker_LDADD = libtest-runner.la

View file

@ -1,4 +1,4 @@
# Wayland
What is Wayland
Wayland is a project to define a protocol for a compositor to talk to
its clients as well as a library implementation of the protocol. The
@ -17,14 +17,19 @@ protocol does not handle rendering, which is one of the features that
makes wayland so simple. All clients are expected to handle rendering
themselves, typically through cairo or OpenGL.
The weston compositor is a reference implementation of a wayland
compositor and the weston repository also includes a few example
clients.
Building the wayland libraries is fairly simple, aside from libffi,
they don't have many dependencies:
$ git clone https://gitlab.freedesktop.org/wayland/wayland
$ git clone git://anongit.freedesktop.org/wayland/wayland
$ cd wayland
$ meson build/ --prefix=PREFIX
$ ninja -C build/ install
$ ./autogen.sh --prefix=PREFIX
$ make
$ make install
where PREFIX is where you want to install the libraries.
See https://wayland.freedesktop.org for documentation.
where PREFIX is where you want to install the libraries. See
http://wayland.freedesktop.org for more complete build instructions
for wayland, weston, xwayland and various toolkits.

149
TODO Normal file
View file

@ -0,0 +1,149 @@
Core wayland protocol
- Maybe try to make remote wayland actually happen, to see if there
is something in the protocol/architecture that makes it harder than
it should be.
ICCCM
- mime-type guidelines for data_source (ie, both dnd and selection):
recommended types for text or images, types that a clipboard
manager must support, mime-types must be listed in preferred order
- we need a "no kb focus please" mechanism. Or should this be
implicit in a specific surface type?
EWMH
- configure should provide dx_left, dx_right, dy_top, dy_bottom, or
dx, dy, width and height.
- move to workspace, keep on top, on all workspaces, minimize etc
requests for implementing client side window menu? or just make a
"show window menu" request to let the compositor display and manage
a popup window?
- window move and resize functionality for kb and touch.
- Protocol for specifying title bar rectangle (for moving
unresponsive apps). Rectangle for close button, so we can popup
force-close dialog if application doesn't respond to ping event
when user clicks there. We could use the region mechanism here
too.
- popup placement protocol logic.
- subsurface mechanism. we need this for cases where we would use an
X subwindow for gl or video other different visual type.
EGL/gbm
- Land Robert Braggs EGL extensions: frame age, swap with damage
- Make it possible to share buffers from compositor to clients.
Tricky part here is how to indicate to EGL on the server side that
it should make an EGLImage available to a client. We'll need a
"create a wl_buffer for this EGLImage for this client" kind of
entry point.
- Protocol for arbitrating access to scanout buffers (physically
contiguous memory). When a client goes fullscreen (or ideally as
the compositor starts the animation that will make it fullscreen)
we send a "give up your scanout buffer" to the current fullscreen
client (if any) and when the client acks that we send a "try to
allocate a scanout buffer now" event to the fullscreen-to-be
client.
Misc
- glyph cache
- Needs a mechanism to pass buffers to client.
buffer = drm.create_buffer(); /* buffer with stuff in it */
cache.upload(buffer, x, y, width, height, int hash)
drm.buffer: id, name, stride etc /* event to announce cache buffer */
cache.image: hash, buffer, x, y, stride /* event to announce
* location in cache */
cache.reject: hash /* no upload for you! */
cache.retire: buffer /* cache has stopped using buffer, please
* reupload whatever you had in that buffer */
- A "please suspend" event from the compositor, to indicate to an
application that it's no longer visible/active. Or maybe discard
buffer, as in "wayland discarded your buffer, it's no longer
visible, you can stop updating it now.", reattach, as in "oh hey,
I'm about to show your buffer that I threw away, what was it
again?". for wayland system compositor vt switcing, for example,
to be able to throw away the surfaces in the session we're
switching away from. for minimized windows that we don't want live
thumb nails for. etc.
Clients and ports
- port gtk+
- draw window decorations in gtkwindow.c
- Details about pointer grabs. wayland doesn't have active grabs,
menus will behave subtly different. Under X, clicking a menu
open grabs the pointer and clicking outside the window pops down
the menu and swallows the click. without active grabs we can't
swallow the click. I'm sure there much more...
- dnd, copy-paste
- Investigate DirectFB on Wayland (or is that Wayland on DirectFB?)
- SDL port, bnf has work in progress here:
http://cgit.freedesktop.org/~bnf/sdl-wayland/
Ideas
- A wayland settings protocol to tell clients about themes (icons,
cursors, widget themes), fonts details (family, hinting
preferences) etc. Just send all settings at connect time, send
updates when a setting change. Getting a little close to gconf
here, but could be pretty simple:
interface "settings":
event int_value(string name, int value)
event string_value(string name, string value)
but maybe it's better to just require that clients get that from
somewhere else (gconf/dbus).
Crazy ideas
- AF_WAYLAND - A new socket type. Eliminate compositor context
switch by making kernel understand enough of wayland that it can
forward input events as wayland events and do page flipping in
response to surface_attach requests:
- ioctl(wayland_fd, "surface_attach to object 5 should do a kms page
flip on ctrc 2");
- what about multiple crtcs? what about frame event for other
clients?
- forward these input devices to the client
- "scancode 124 pressed or released with scan codes 18,22 and 30
held down gives control back to userspace wayland.
- what about maintaining cursor position? what about pointer
acceleration? maybe this only works in "client cursor mode",
where wayland hides the cursor and only sends relative events?
Solves the composited cursor problem. How does X show its
cursor then?
- Probably not worth it.

9
autogen.sh Executable file
View file

@ -0,0 +1,9 @@
#! /bin/sh
test -n "$srcdir" || srcdir=`dirname "$0"`
test -n "$srcdir" || srcdir=.
(
cd "$srcdir" &&
autoreconf --force -v --install
) || exit
test -n "$NOCONFIGURE" || "$srcdir/configure" "$@"

143
configure.ac Normal file
View file

@ -0,0 +1,143 @@
AC_PREREQ([2.64])
m4_define([wayland_major_version], [1])
m4_define([wayland_minor_version], [6])
m4_define([wayland_micro_version], [0])
m4_define([wayland_version],
[wayland_major_version.wayland_minor_version.wayland_micro_version])
AC_INIT([wayland],
[wayland_version],
[https://bugs.freedesktop.org/enter_bug.cgi?product=Wayland&component=wayland&version=wayland_version],
[wayland],
[http://wayland.freedesktop.org/])
AC_SUBST([WAYLAND_VERSION_MAJOR], [wayland_major_version])
AC_SUBST([WAYLAND_VERSION_MINOR], [wayland_minor_version])
AC_SUBST([WAYLAND_VERSION_MICRO], [wayland_micro_version])
AC_SUBST([WAYLAND_VERSION], [wayland_version])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz subdir-objects])
AM_SILENT_RULES([yes])
# Check for programs
AC_PROG_CC
# Initialize libtool
LT_PREREQ([2.2])
LT_INIT
PKG_PROG_PKG_CONFIG()
PKG_CHECK_MODULES(FFI, [libffi])
if test "x$GCC" = "xyes"; then
GCC_CFLAGS="-Wall -Wextra -Wno-unused-parameter -g -Wstrict-prototypes -Wmissing-prototypes -fvisibility=hidden"
fi
AC_SUBST(GCC_CFLAGS)
AC_CHECK_FUNCS([accept4 mkostemp posix_fallocate])
AC_CHECK_DECL(SFD_CLOEXEC,[],
[AC_MSG_ERROR("SFD_CLOEXEC is needed to compile wayland")],
[[#include <sys/signalfd.h>]])
AC_CHECK_DECL(TFD_CLOEXEC,[],
[AC_MSG_ERROR("TFD_CLOEXEC is needed to compile wayland")],
[[#include <sys/timerfd.h>]])
AC_CHECK_DECL(CLOCK_MONOTONIC,[],
[AC_MSG_ERROR("CLOCK_MONOTONIC is needed to compile wayland")],
[[#include <time.h>]])
AC_CHECK_HEADERS([execinfo.h])
AC_ARG_ENABLE([scanner],
[AC_HELP_STRING([--disable-scanner],
[Disable compilation of wayland-scanner])],
[],
[enable_scanner=yes])
AC_ARG_ENABLE([documentation],
[AC_HELP_STRING([--disable-documentation],
[Disable building the documentation])],
[],
[enable_documentation=yes])
AM_CONDITIONAL(ENABLE_SCANNER, test "x$enable_scanner" = xyes)
AC_ARG_WITH(icondir, [ --with-icondir=<dir> Look for cursor icons here],
[ ICONDIR=$withval],
[ ICONDIR=${datadir}/icons])
AC_SUBST([ICONDIR])
EXPAT_LIB=""
AC_ARG_WITH(expat, [ --with-expat=<dir> Use expat from here],
[ expat=$withval
CPPFLAGS="$CPPFLAGS -I$withval/include"
LDFLAGS="$LDFLAGS -L$withval/lib" ] )
if test "x$enable_scanner" = "xyes"; then
AC_CHECK_HEADERS(expat.h, [AC_DEFINE(HAVE_EXPAT_H)],
[AC_MSG_ERROR([Can't find expat.h. Please install expat.])])
AC_CHECK_LIB(expat, XML_ParserCreate, [EXPAT_LIBS="-lexpat"],
[AC_MSG_ERROR([Can't find expat library. Please install expat.])])
AC_SUBST(EXPAT_LIBS)
fi
AC_PATH_PROG(XSLTPROC, xsltproc)
AM_CONDITIONAL([HAVE_XSLTPROC], [test "x$XSLTPROC" != "x"])
AC_MSG_CHECKING([for docbook manpages stylesheet])
MANPAGES_STYLESHEET=http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl
AC_PATH_PROGS_FEATURE_CHECK([XSLTPROC_TMP], [xsltproc],
AS_IF([`"$ac_path_XSLTPROC_TMP" --nonet "$MANPAGES_STYLESHEET" > /dev/null 2>&1`],
[HAVE_MANPAGES_STYLESHEET=yes]))
if test "x$HAVE_MANPAGES_STYLESHEET" = "xyes"; then
AM_CONDITIONAL([HAVE_MANPAGES_STYLESHEET], true)
AC_SUBST(MANPAGES_STYLESHEET)
AC_MSG_RESULT([yes])
else
AM_CONDITIONAL([HAVE_MANPAGES_STYLESHEET], false)
AC_MSG_RESULT([no])
fi
AM_CONDITIONAL(BUILD_DOCS, [test x$enable_documentation = xyes])
if test "x$enable_documentation" = "xyes"; then
AC_PATH_PROG(DOXYGEN, doxygen)
if test "x$DOXYGEN" = "x"; then
AC_MSG_ERROR([Documentation build requested but doxygen not found. Install doxygen or disable the documentation using --disable-documentation])
fi
AC_PATH_PROG(PUBLICAN, publican)
if test "x$PUBLICAN" != "x"; then
PUBLICAN_VERSION=[`$PUBLICAN -v | sed -e 's/version=v\?\([0-9]*\.[0-9]*\).*/\1/'`]
if test [ 1 -eq `echo "${PUBLICAN_VERSION} < 2.8" | bc` ]; then
AC_MSG_ERROR([Publican version is not supported. Install publican >= 2.8 or disable the documentation using --disable-documentation])
fi
fi
AC_CONFIG_FILES([
doc/doxygen/wayland.doxygen
])
fi
AM_CONDITIONAL([HAVE_PUBLICAN], [test "x$PUBLICAN" != "x"])
AC_CONFIG_FILES([Makefile
cursor/wayland-cursor.pc
cursor/wayland-cursor-uninstalled.pc
doc/Makefile
doc/publican/Makefile
doc/doxygen/Makefile
doc/man/Makefile
src/wayland-server-uninstalled.pc
src/wayland-client-uninstalled.pc
src/wayland-scanner-uninstalled.pc
src/wayland-server.pc
src/wayland-client.pc
src/wayland-scanner.pc
src/wayland-version.h])
AC_OUTPUT

View file

@ -1,26 +1,23 @@
/*
* Copyright © 2012 Philipp Brüschweiler
*
* 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:
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* 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.
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
/*
@ -29,6 +26,7 @@
* http://fontforge.org/pcf-format.html
*/
#include <assert.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
@ -332,38 +330,30 @@ reconstruct_glyph(struct glyph *cursor, struct glyph *mask, char *name,
}
}
/*
* Originally from
* http://cgit.freedesktop.org/xorg/lib/libXfont/tree/src/builtins/fonts.c
* Changed to the MIT "Expat" style license for Wayland..
*/
/* From http://cgit.freedesktop.org/xorg/lib/libXfont/tree/src/builtins/fonts.c */
static const char cursor_licence[] =
"/*\n"
"* Copyright 1999 SuSE, Inc.\n"
"*\n"
"* Permission is hereby granted, free of charge, to any person obtaining\n"
"* a copy of this software and associated documentation files (the\n"
"* \"Software\"), to deal in the Software without restriction, including\n"
"* without limitation the rights to use, copy, modify, merge, publish,\n"
"* distribute, sublicense, and/or sell copies of the Software, and to\n"
"* permit persons to whom the Software is furnished to do so, subject to\n"
"* the following conditions:\n"
"*\n"
"* The above copyright notice and this permission notice (including the\n"
"* next paragraph) shall be included in all copies or substantial\n"
"* portions of the Software.\n"
"*\n"
"* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n"
"* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n"
"* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n"
"* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\n"
"* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\n"
"* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n"
"* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n"
"* SOFTWARE.\n"
"*\n"
"* Author: Keith Packard, SuSE, Inc.\n"
"*/\n";
"* Copyright 1999 SuSE, Inc.\n"
"*\n"
"* Permission to use, copy, modify, distribute, and sell this software and its\n"
"* documentation for any purpose is hereby granted without fee, provided that\n"
"* the above copyright notice appear in all copies and that both that\n"
"* copyright notice and this permission notice appear in supporting\n"
"* documentation, and that the name of SuSE not be used in advertising or\n"
"* publicity pertaining to distribution of the software without specific,\n"
"* written prior permission. SuSE makes no representations about the\n"
"* suitability of this software for any purpose. It is provided \"as is\"\n"
"* without express or implied warranty.\n"
"*\n"
"* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL\n"
"* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE\n"
"* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n"
"* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION\n"
"* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN\n"
"* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n"
"*\n"
"* Author: Keith Packard, SuSE, Inc.\n"
"*/\n";
static void
write_output_file(struct reconstructed_glyph *glyphs, int n)
@ -498,11 +488,6 @@ output_interesting_cursors()
struct reconstructed_glyph *glyphs =
malloc(n * sizeof(*glyphs));
if (!glyphs) {
printf("reconstructed_glyph malloc failed\n");
abort();
}
for (i = 0; i < n; ++i) {
struct glyph *cursor, *mask;
find_cursor_and_mask(interesting_cursors[i].source_name,

View file

@ -1,32 +1,26 @@
/*
* Copyright 1999 SuSE, Inc.
*
* 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:
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of SuSE not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. SuSE makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* 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.
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Keith Packard, SuSE, Inc.
*/
#include <stdint.h>
static uint32_t cursor_data[] = {
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@ -551,19 +545,4 @@ static struct cursor_metadata {
{ "xterm", 9, 16, 4, 8, 2400 },
{ "hand1", 13, 16, 12, 0, 2544 },
{ "watch", 16, 16, 15, 9, 2752 },
/* https://www.freedesktop.org/wiki/Specifications/cursor-spec/ */
{ "sw-resize", 16, 16, 1, 14, 0 },
{ "se-resize", 16, 16, 14, 14, 256 },
{ "s-resize", 15, 16, 7, 14, 512 },
{ "all-scroll", 16, 16, 8, 8, 752 },
{ "default", 10, 16, 1, 1, 1008 },
{ "w-resize", 16, 15, 1, 7, 1168 },
{ "e-resize", 16, 15, 14, 7, 1408 },
{ "nw-resize", 16, 16, 1, 1, 1648 },
{ "ne-resize", 16, 16, 14, 1, 1904 },
{ "n-resize", 15, 16, 7, 1, 2160 },
{ "text", 9, 16, 4, 8, 2400 },
{ "pointer", 13, 16, 12, 0, 2544 },
{ "wait", 16, 16, 15, 9, 2752 },
};

View file

@ -1,47 +0,0 @@
icondir = get_option('icon_directory')
if icondir == ''
icondir = join_paths(get_option('prefix'), get_option('datadir'), 'icons')
endif
if wayland_version[0] != '1'
# The versioning used for the shared libraries assumes that the major
# version of Wayland as a whole will increase to 2 if and only if there
# is an ABI break, at which point we should probably bump the SONAME of
# all libraries to .so.2. For more details see
# https://gitlab.freedesktop.org/wayland/wayland/-/merge_requests/177
error('We probably need to bump the SONAME of libwayland-cursor')
endif
wayland_cursor = library(
'wayland-cursor',
sources: [
'wayland-cursor.c',
'os-compatibility.c',
'xcursor.c',
],
# To avoid an unnecessary SONAME bump, wayland 1.x.y produces
# libwayland-cursor.so.0.x.y.
version: '.'.join(['0', wayland_version[1], wayland_version[2]]),
dependencies: [ wayland_client_dep ],
c_args: [ '-DICONDIR="@0@"'.format(icondir) ],
install: true,
)
install_headers('wayland-cursor.h')
pkgconfig.generate(
name: 'Wayland Cursor',
description: 'Wayland cursor helper library',
version: meson.project_version(),
libraries: wayland_cursor,
filebase: 'wayland-cursor',
)
wayland_cursor_dep = declare_dependency(
link_with: wayland_cursor,
include_directories: [ root_inc, include_directories('.') ],
)
if meson.version().version_compare('>= 0.54.0')
meson.override_dependency('wayland-cursor', wayland_cursor_dep)
endif

View file

@ -1,50 +1,35 @@
/*
* Copyright © 2012 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:
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* 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.
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#define _GNU_SOURCE
#include "config.h"
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_MEMFD_CREATE
#include <sys/mman.h>
#endif
/* Fallback to no flag when missing the definition */
#ifndef MFD_NOEXEC_SEAL
#define MFD_NOEXEC_SEAL 0
#endif
#include "config.h"
#include "os-compatibility.h"
#ifndef HAVE_MKOSTEMP
@ -108,115 +93,53 @@ create_tmpfile_cloexec(char *tmpname)
*
* If the C library implements posix_fallocate(), it is used to
* guarantee that disk space is available for the file at the
* given size. If disk space is insufficient, errno is set to ENOSPC.
* given size. If disk space is insufficent, errno is set to ENOSPC.
* If posix_fallocate() is not supported, program may receive
* SIGBUS on accessing mmap()'ed file contents instead.
*
* If the C library implements memfd_create(), it is used to create the
* file purely in memory, without any backing file name on the file
* system, and then sealing off the possibility of shrinking it. This
* can then be checked before accessing mmap()'ed file contents, to
* make sure SIGBUS can't happen. It also avoids requiring
* XDG_RUNTIME_DIR.
*/
int
os_create_anonymous_file(off_t size)
{
static const char template[] = "/wayland-cursor-shared-XXXXXX";
static const char template[] = "/weston-shared-XXXXXX";
const char *path;
char *name;
size_t name_size;
int fd;
int ret;
#ifdef HAVE_MEMFD_CREATE
/*
* Linux kernels older than 6.3 reject MFD_NOEXEC_SEAL with EINVAL.
* Try first *with* it, and if that fails, try again *without* it.
*/
errno = 0;
fd = memfd_create(
"wayland-cursor",
MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_NOEXEC_SEAL);
if (fd < 0 && errno == EINVAL && MFD_NOEXEC_SEAL != 0) {
fd = memfd_create(
"wayland-cursor",
MFD_CLOEXEC | MFD_ALLOW_SEALING);
path = getenv("XDG_RUNTIME_DIR");
if (!path) {
errno = ENOENT;
return -1;
}
if (fd >= 0) {
/* We can add this seal before calling posix_fallocate(), as
* the file is currently zero-sized anyway.
*
* There is also no need to check for the return value, we
* couldn't do anything with it anyway.
*/
fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);
} else
#endif
{
path = getenv("XDG_RUNTIME_DIR");
if (!path || path[0] != '/') {
errno = ENOENT;
return -1;
}
name = malloc(strlen(path) + sizeof(template));
if (!name)
return -1;
name_size = strlen(path) + sizeof(template);
name = malloc(name_size);
if (!name)
return -1;
strcpy(name, path);
strcat(name, template);
snprintf(name, name_size, "%s%s", path, template);
fd = create_tmpfile_cloexec(name);
fd = create_tmpfile_cloexec(name);
free(name);
free(name);
if (fd < 0)
return -1;
if (fd < 0)
return -1;
#ifdef HAVE_POSIX_FALLOCATE
ret = posix_fallocate(fd, 0, size);
if (ret != 0) {
close(fd);
errno = ret;
return -1;
}
if (os_resize_anonymous_file(fd, size) < 0) {
#else
ret = ftruncate(fd, size);
if (ret < 0) {
close(fd);
return -1;
}
#endif
return fd;
}
int
os_resize_anonymous_file(int fd, off_t size)
{
#ifdef HAVE_POSIX_FALLOCATE
sigset_t mask;
sigset_t old_mask;
/*
* posix_fallocate() might be interrupted, so we need to check
* for EINTR and retry in that case.
* However, in the presence of an alarm, the interrupt may trigger
* repeatedly and prevent a large posix_fallocate() to ever complete
* successfully, so we need to first block SIGALRM to prevent
* this.
*/
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
sigprocmask(SIG_BLOCK, &mask, &old_mask);
/*
* Filesystems that do not support fallocate will return EINVAL or
* EOPNOTSUPP. In this case we need to fall back to ftruncate
*/
do {
errno = posix_fallocate(fd, 0, size);
} while (errno == EINTR);
sigprocmask(SIG_SETMASK, &old_mask, NULL);
if (errno == 0)
return 0;
else if (errno != EINVAL && errno != EOPNOTSUPP)
return -1;
#endif
if (ftruncate(fd, size) < 0)
return -1;
return 0;
}

View file

@ -1,26 +1,23 @@
/*
* Copyright © 2012 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:
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* 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.
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#ifndef OS_COMPATIBILITY_H
@ -31,7 +28,4 @@
int
os_create_anonymous_file(off_t size);
int
os_resize_anonymous_file(int fd, off_t size);
#endif /* OS_COMPATIBILITY_H */

View file

@ -0,0 +1,8 @@
libdir=@abs_builddir@/.libs
includedir=@abs_srcdir@
Name: Wayland Cursor
Description: Wayland cursor helper library (not installed)
Version: @WAYLAND_VERSION@
Cflags: -I${includedir}
Libs: -L${libdir} -lwayland-cursor

View file

@ -1,36 +1,31 @@
/*
* Copyright © 2012 Intel Corporation
*
* 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:
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* 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.
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "config.h"
#include "xcursor.h"
#include "wayland-cursor.h"
#include "wayland-client.h"
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
@ -69,16 +64,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:
@ -89,16 +79,22 @@ err_free:
static int
shm_pool_resize(struct shm_pool *pool, int size)
{
if (os_resize_anonymous_file(pool->fd, size) < 0)
if (ftruncate(pool->fd, size) < 0)
return 0;
#ifdef HAVE_POSIX_FALLOCATE
errno = posix_fallocate(pool->fd, 0, size);
if (errno != 0)
return 0;
#endif
wl_shm_pool_resize(pool->pool, size);
munmap(pool->data, pool->size);
pool->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
pool->fd, 0);
if (pool->data == MAP_FAILED)
if (pool->data == (void *)-1)
return 0;
pool->size = size;
@ -135,6 +131,7 @@ struct wl_cursor_theme {
struct wl_cursor **cursors;
struct wl_shm *shm;
struct shm_pool *pool;
char *name;
int size;
};
@ -157,32 +154,32 @@ struct cursor {
* the returned buffer.
*/
WL_EXPORT struct wl_buffer *
wl_cursor_image_get_buffer(struct wl_cursor_image *image)
wl_cursor_image_get_buffer(struct wl_cursor_image *_img)
{
struct cursor_image *img = (struct cursor_image *) image;
struct wl_cursor_theme *theme = img->theme;
struct cursor_image *image = (struct cursor_image *) _img;
struct wl_cursor_theme *theme = image->theme;
if (!img->buffer) {
img->buffer =
if (!image->buffer) {
image->buffer =
wl_shm_pool_create_buffer(theme->pool->pool,
img->offset,
image->width, image->height,
image->width * 4,
image->offset,
_img->width, _img->height,
_img->width * 4,
WL_SHM_FORMAT_ARGB8888);
};
return img->buffer;
return image->buffer;
}
static void
wl_cursor_image_destroy(struct wl_cursor_image *image)
wl_cursor_image_destroy(struct wl_cursor_image *_img)
{
struct cursor_image *img = (struct cursor_image *) image;
struct cursor_image *image = (struct cursor_image *) _img;
if (img->buffer)
wl_buffer_destroy(img->buffer);
if (image->buffer)
wl_buffer_destroy(image->buffer);
free(img);
free(image);
}
static void
@ -193,7 +190,6 @@ wl_cursor_destroy(struct wl_cursor *cursor)
for (i = 0; i < cursor->image_count; i++)
wl_cursor_image_destroy(cursor->images[i]);
free(cursor->images);
free(cursor->name);
free(cursor);
}
@ -257,10 +253,13 @@ err_free_cursor:
}
static void
load_fallback_theme(struct wl_cursor_theme *theme)
load_default_theme(struct wl_cursor_theme *theme)
{
uint32_t i;
free(theme->name);
theme->name = strdup("default");
theme->cursor_count = ARRAY_LENGTH(cursor_metadata);
theme->cursors = malloc(theme->cursor_count * sizeof(*theme->cursors));
@ -280,13 +279,12 @@ load_fallback_theme(struct wl_cursor_theme *theme)
}
static struct wl_cursor *
wl_cursor_create_from_xcursor_images(struct xcursor_images *images,
wl_cursor_create_from_xcursor_images(XcursorImages *images,
struct wl_cursor_theme *theme)
{
struct cursor *cursor;
struct cursor_image *image;
size_t size;
int i;
int i, size;
cursor = malloc(sizeof *cursor);
if (!cursor)
@ -316,12 +314,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);
@ -347,34 +340,33 @@ wl_cursor_create_from_xcursor_images(struct xcursor_images *images,
}
static void
load_callback(struct xcursor_images *images, void *data)
load_callback(XcursorImages *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);
XcursorImagesDestroy(images);
return;
}
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;
}
}
xcursor_images_destroy(images);
XcursorImagesDestroy(images);
}
/** Load a cursor theme to memory shared with the compositor
@ -397,31 +389,30 @@ 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";
theme->name = strdup(name);
if (!theme->name)
goto out_error_name;
theme->size = size;
theme->cursor_count = 0;
theme->cursors = NULL;
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);
if (theme->cursor_count == 0)
xcursor_load_theme(NULL, size, load_callback, theme);
if (theme->cursor_count == 0)
load_fallback_theme(theme);
load_default_theme(theme);
return theme;
err:
out_error_pool:
free(theme->name);
out_error_name:
free(theme);
return NULL;
}
@ -440,6 +431,7 @@ wl_cursor_theme_destroy(struct wl_cursor_theme *theme)
shm_pool_destroy(theme->pool);
free(theme->name);
free(theme->cursors);
free(theme);
}
@ -466,67 +458,28 @@ wl_cursor_theme_get_cursor(struct wl_cursor_theme *theme,
}
/** Find the frame for a given elapsed time in a cursor animation
* as well as the time left until next cursor change.
*
* \param cursor The cursor
* \param time Elapsed time in ms since the beginning of the animation
* \param duration pointer to uint32_t to store time left for this image or
* zero if the cursor won't change.
* \param time Elapsed time since the beginning of the animation
*
* \return The index of the image that should be displayed for the
* given time in the cursor animation.
*/
WL_EXPORT int
wl_cursor_frame_and_duration(struct wl_cursor *cursor, uint32_t time,
uint32_t *duration)
wl_cursor_frame(struct wl_cursor *_cursor, uint32_t time)
{
struct cursor *cur = (struct cursor *) cursor;
struct cursor *cursor = (struct cursor *) _cursor;
uint32_t t;
int i;
if (cur->cursor.image_count == 1 || cur->total_delay == 0) {
if (duration)
*duration = 0;
if (cursor->cursor.image_count == 1)
return 0;
}
i = 0;
t = time % cur->total_delay;
t = time % cursor->total_delay;
/* If there is a 0 delay in the image set then this
* loop breaks on it and we display that cursor until
* time % cursor->total_delay wraps again.
* Since a 0 delay is silly, and we've never actually
* seen one in a cursor file, we haven't bothered to
* "fix" this.
*/
while (t - cur->cursor.images[i]->delay < t)
t -= cur->cursor.images[i++]->delay;
if (!duration)
return i;
/* Make sure we don't accidentally tell the caller this is
* a static cursor image.
*/
if (t >= cur->cursor.images[i]->delay)
*duration = 1;
else
*duration = cur->cursor.images[i]->delay - t;
while (t - cursor->cursor.images[i]->delay < t)
t -= cursor->cursor.images[i++]->delay;
return i;
}
/** Find the frame for a given elapsed time in a cursor animation
*
* \param cursor The cursor
* \param time Elapsed time in ms since the beginning of the animation
*
* \return The index of the image that should be displayed for the
* given time in the cursor animation.
*/
WL_EXPORT int
wl_cursor_frame(struct wl_cursor *cursor, uint32_t time)
{
return wl_cursor_frame_and_duration(cursor, time, NULL);
}

View file

@ -1,26 +1,23 @@
/*
* Copyright © 2012 Intel Corporation
*
* 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:
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* 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.
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#ifndef WAYLAND_CURSOR_H
@ -33,42 +30,23 @@ extern "C" {
#endif
struct wl_cursor_theme;
struct wl_buffer;
struct wl_shm;
/** A still image part of a cursor
*
* Use `wl_cursor_image_get_buffer()` to get the corresponding `struct
* wl_buffer` to attach to your `struct wl_surface`. */
struct wl_cursor_image {
/** Actual width */
uint32_t width;
/** Actual height */
uint32_t height;
/** Hot spot x (must be inside image) */
uint32_t hotspot_x;
/** Hot spot y (must be inside image) */
uint32_t hotspot_y;
/** Animation delay to next frame (ms) */
uint32_t delay;
uint32_t width; /* actual width */
uint32_t height; /* actual height */
uint32_t hotspot_x; /* hot spot x (must be inside image) */
uint32_t hotspot_y; /* hot spot y (must be inside image) */
uint32_t delay; /* animation delay to next frame (ms) */
};
/** A cursor, as returned by `wl_cursor_theme_get_cursor()` */
struct wl_cursor {
/** How many images there are in this cursors animation */
unsigned int image_count;
/** The array of still images composing this animation */
struct wl_cursor_image **images;
/** The name of this cursor */
char *name;
};
struct wl_shm;
struct wl_cursor_theme *
wl_cursor_theme_load(const char *name, int size, struct wl_shm *shm);
@ -85,10 +63,6 @@ wl_cursor_image_get_buffer(struct wl_cursor_image *image);
int
wl_cursor_frame(struct wl_cursor *cursor, uint32_t time);
int
wl_cursor_frame_and_duration(struct wl_cursor *cursor, uint32_t time,
uint32_t *duration);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,10 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: Wayland Cursor
Description: Wayland cursor helper library
Version: @WAYLAND_VERSION@
Cflags: -I${includedir}
Libs: -L${libdir} -lwayland-cursor

File diff suppressed because it is too large Load diff

View file

@ -1,58 +1,62 @@
/*
* Copyright © 2002 Keith Packard
*
* 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:
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* 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.
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef XCURSOR_H
#define XCURSOR_H
#include <stdint.h>
typedef int XcursorBool;
typedef unsigned int XcursorUInt;
struct xcursor_image {
uint32_t version; /* version of the image data */
uint32_t size; /* nominal size for matching */
uint32_t width; /* actual width */
uint32_t height; /* actual height */
uint32_t xhot; /* hot spot x (must be inside image) */
uint32_t yhot; /* hot spot y (must be inside image) */
uint32_t delay; /* animation delay to next frame (ms) */
uint32_t *pixels; /* pointer to pixels */
};
typedef XcursorUInt XcursorDim;
typedef XcursorUInt XcursorPixel;
typedef struct _XcursorImage {
XcursorUInt version; /* version of the image data */
XcursorDim size; /* nominal size for matching */
XcursorDim width; /* actual width */
XcursorDim height; /* actual height */
XcursorDim xhot; /* hot spot x (must be inside image) */
XcursorDim yhot; /* hot spot y (must be inside image) */
XcursorUInt delay; /* animation delay to next frame (ms) */
XcursorPixel *pixels; /* pointer to pixels */
} XcursorImage;
/*
* Other data structures exposed by the library API
*/
struct xcursor_images {
int nimage; /* number of images */
struct xcursor_image **images; /* array of XcursorImage pointers */
char *name; /* name used to load images */
};
typedef struct _XcursorImages {
int nimage; /* number of images */
XcursorImage **images; /* array of XcursorImage pointers */
char *name; /* name used to load images */
} XcursorImages;
XcursorImages *
XcursorLibraryLoadImages (const char *file, const char *theme, int size);
void
xcursor_images_destroy(struct xcursor_images *images);
XcursorImagesDestroy (XcursorImages *images);
void
xcursor_load_theme(const char *theme, int size,
void (*load_callback)(struct xcursor_images *, void *),
void *user_data);
void (*load_callback)(XcursorImages *, void *),
void *user_data);
#endif

83
doc/Contributing Normal file
View file

@ -0,0 +1,83 @@
= Contributing to Wayland =
== Sending patches ==
Patches should be sent to wayland-devel@lists.freedesktop.org, using
git send-email. See git's documentation for help [1].
The first line of a commit message should contain a prefix indicating
what part is affected by the patch followed by one sentence that
describes the change. For examples:
protocol: Support scaled outputs and surfaces
and
doc: generate server documentation from XML too
If in doubt what prefix to use, look at other commits that change the
same file(s) as the patch being sent.
The body of the commit message should describe what the patch changes
and why, and also note any particular side effects. This shouldn't be
empty on most of the cases. It shouldn't take a lot of effort to write
a commit message for an obvious change, so an empty commit message
body is only acceptable if the questions "What?" and "Why" are already
answered on the one-line summary.
The lines of the commit message should have at most 76 characters, to
cope with the way git log presents them.
See [2] for a recommend reading on writing commit messages.
== Coding style ==
You should follow the style of the file you're editing. In general, we
try to follow the rules below.
- indent with tabs, and a tab is always 8 characters wide
- opening braces are on the same line as the if statement;
- no braces in an if-body with just one statement;
- if one of the branches of an if-else codition has braces, than the
other branch should also have braces;
- there is always an empty line between variable declarations and the
code;
static int
my_function(void)
{
int a = 0;
if (a)
b();
else
c();
if (a) {
b();
c();
} else {
d();
}
}
- lines should be less than 80 characters wide;
- when breaking lines with functions calls, the parameters are aligned
with the opening parenthesis;
- when assigning a variable with the result of a function call, if the
line would be longer we break it around the equal '=' sign if it makes
sense;
long_variable_name =
function_with_a_really_long_name(parameter1, parameter2,
parameter3, parameter4);
x = function_with_a_really_long_name(parameter1, parameter2,
parameter3, parameter4);
== References ==
[1] http://git-scm.com/documentation
[2] http://who-t.blogspot.de/2009/12/on-commit-messages.html

3
doc/Makefile.am Normal file
View file

@ -0,0 +1,3 @@
SUBDIRS = doxygen publican man
EXTRA_DIST = Contributing

1
doc/book/.gitignore vendored
View file

@ -1 +0,0 @@
/book

View file

@ -1,9 +0,0 @@
[book]
title = "Wayland"
authors = ["Kristian Høgsberg"]
language = "en"
[output.html]
git-repository-url = "https://gitlab.freedesktop.org/wayland/wayland"
edit-url-template = "https://gitlab.freedesktop.org/wayland/wayland/-/edit/main/doc/book/{path}"
site-url = "/docs/book/"

File diff suppressed because it is too large Load diff

View file

@ -1,198 +0,0 @@
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/29.0.3 Chrome/140.0.7339.249 Electron/38.7.0 Safari/537.36" version="29.0.3" pages="6">
<diagram name="state 1" id="9R2pyHIIQvV-60tET7sh">
<mxGraphModel dx="446" dy="299" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="Vljyf9wL_jF0PBdsZ3ZJ-56" value="1" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="1">
<mxGeometry x="119" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="Vljyf9wL_jF0PBdsZ3ZJ-57" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="20" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="Vljyf9wL_jF0PBdsZ3ZJ-58" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="Vljyf9wL_jF0PBdsZ3ZJ-59" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="105" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="Vljyf9wL_jF0PBdsZ3ZJ-60" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="100" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="Vljyf9wL_jF0PBdsZ3ZJ-61" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="185" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="Vljyf9wL_jF0PBdsZ3ZJ-62" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="180" width="40" height="40" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="J0DvB8TbWnCMMz7TEYbc" name="state 2">
<mxGraphModel dx="446" dy="299" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="NNa_h0o6fpdAX9mVI6Ni-1" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0.45,0],[0.75,0],[1,0],[1,1],[0.62,1],[0,1],[0,1],[0,1],[0,0.2],[0,0],[0.24,0]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="1">
<mxGeometry x="110" y="20" width="50" height="40" as="geometry" />
</mxCell>
<mxCell id="NNa_h0o6fpdAX9mVI6Ni-2" value="1" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="1">
<mxGeometry x="119" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="NNa_h0o6fpdAX9mVI6Ni-3" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="20" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="NNa_h0o6fpdAX9mVI6Ni-4" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="NNa_h0o6fpdAX9mVI6Ni-5" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="105" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="NNa_h0o6fpdAX9mVI6Ni-6" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="100" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="NNa_h0o6fpdAX9mVI6Ni-7" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="185" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="NNa_h0o6fpdAX9mVI6Ni-8" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="180" width="40" height="40" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="ySO0QrqtFkECLiZt7iPp" name="state 3">
<mxGraphModel dx="701" dy="470" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="pI76myQ_i7gC2-BWcum8-1" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="20" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="pI76myQ_i7gC2-BWcum8-2" value="&lt;b&gt;1&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="pI76myQ_i7gC2-BWcum8-3" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="105" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="pI76myQ_i7gC2-BWcum8-4" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="100" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="pI76myQ_i7gC2-BWcum8-5" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="185" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="pI76myQ_i7gC2-BWcum8-6" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="180" width="40" height="40" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="Kx24UVXuaWmlcUcIS4GM" name="state 4">
<mxGraphModel dx="446" dy="299" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="v1jzpavZj8JK8wO-OO9X-1" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="20" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="v1jzpavZj8JK8wO-OO9X-2" value="&lt;b&gt;1&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="v1jzpavZj8JK8wO-OO9X-3" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="105" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="v1jzpavZj8JK8wO-OO9X-4" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="100" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="v1jzpavZj8JK8wO-OO9X-5" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="185" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="v1jzpavZj8JK8wO-OO9X-6" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="180" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="v1jzpavZj8JK8wO-OO9X-7" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="1">
<mxGeometry x="120" y="185" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="v1jzpavZj8JK8wO-OO9X-8" value="B" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;strokeWidth=1;shape=mxgraph.flowchart.on-page_reference;strokeColor=#b85450;fillColor=#f8cecc;labelPosition=center;align=center;dashed=1;fontStyle=1;spacing=0;spacingBottom=2;" vertex="1" parent="1">
<mxGeometry x="120" y="180" width="14" height="14" as="geometry" />
</mxCell>
<mxCell id="v1jzpavZj8JK8wO-OO9X-9" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0.45,0],[0.75,0],[1,0],[1,1],[0.62,1],[0,1],[0,1],[0,1],[0,0.2],[0,0],[0.24,0]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="1">
<mxGeometry x="110" y="180" width="50" height="40" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="0yCGw3I3AjIYRBlyI2Mm" name="state 5">
<mxGraphModel dx="446" dy="299" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="z-ZDJLvQiKHsJtFRiBHY-1" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0.45,0],[0.75,0],[1,0],[1,1],[0.62,1],[0,1],[0,1],[0,1],[0,0.2],[0,0],[0.24,0]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="1">
<mxGeometry x="102" y="170" width="148" height="60" as="geometry" />
</mxCell>
<mxCell id="z-ZDJLvQiKHsJtFRiBHY-2" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0.45,0],[0.75,0],[1,0],[1,1],[0.62,1],[0,1],[0,1],[0,1],[0,0.2],[0,0],[0.24,0]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="1">
<mxGeometry x="110" y="180" width="50" height="40" as="geometry" />
</mxCell>
<mxCell id="z-ZDJLvQiKHsJtFRiBHY-3" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="1">
<mxGeometry x="120" y="185" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="z-ZDJLvQiKHsJtFRiBHY-4" value="B" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;strokeWidth=1;shape=mxgraph.flowchart.on-page_reference;strokeColor=#b85450;fillColor=#f8cecc;labelPosition=center;align=center;dashed=1;fontStyle=1;spacing=0;spacingBottom=2;" vertex="1" parent="1">
<mxGeometry x="120" y="180" width="14" height="14" as="geometry" />
</mxCell>
<mxCell id="z-ZDJLvQiKHsJtFRiBHY-5" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="20" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="z-ZDJLvQiKHsJtFRiBHY-6" value="&lt;b&gt;1&lt;br&gt;&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="z-ZDJLvQiKHsJtFRiBHY-7" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="105" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="z-ZDJLvQiKHsJtFRiBHY-8" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="100" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="z-ZDJLvQiKHsJtFRiBHY-9" value="&lt;b&gt;&lt;br&gt;&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="185" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="z-ZDJLvQiKHsJtFRiBHY-10" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="180" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="z-ZDJLvQiKHsJtFRiBHY-11" value="3" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="1">
<mxGeometry x="200" y="185" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="z-ZDJLvQiKHsJtFRiBHY-12" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="1" source="z-ZDJLvQiKHsJtFRiBHY-11" target="z-ZDJLvQiKHsJtFRiBHY-3">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="209" y="160" as="sourcePoint" />
<mxPoint x="159" y="160" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="rl79urPFriLDlxviKeb4" name="state 6">
<mxGraphModel dx="446" dy="299" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="-BeM0r6oPtfcQ-rT40E6-1" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="20" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="-BeM0r6oPtfcQ-rT40E6-2" value="&lt;b&gt;1&lt;br&gt;&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="-BeM0r6oPtfcQ-rT40E6-3" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="105" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="-BeM0r6oPtfcQ-rT40E6-4" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="100" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="-BeM0r6oPtfcQ-rT40E6-5" value="&lt;b&gt;2, 3&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="185" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="-BeM0r6oPtfcQ-rT40E6-6" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="180" width="40" height="40" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View file

@ -1,207 +0,0 @@
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/29.0.3 Chrome/140.0.7339.249 Electron/38.7.0 Safari/537.36" version="29.0.3" pages="5">
<diagram name="state 1" id="W-2uyegr0hxMwi0Wm8H9">
<mxGraphModel dx="452" dy="307" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="B5W2QRrcq4c7WbW7dQDT-1" value="1" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#D5E8D4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="1">
<mxGeometry x="120" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="B5W2QRrcq4c7WbW7dQDT-2" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="20" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="B5W2QRrcq4c7WbW7dQDT-3" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="B5W2QRrcq4c7WbW7dQDT-4" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="105" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="B5W2QRrcq4c7WbW7dQDT-5" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="100" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="B5W2QRrcq4c7WbW7dQDT-6" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="185" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="B5W2QRrcq4c7WbW7dQDT-7" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="180" width="40" height="40" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="GeoL4XoRYetvg1q4LOzn" name="state 2">
<mxGraphModel dx="452" dy="307" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="JhubsHDD-TggGAyBPSTr-1" value="1" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#D5E8D4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="1">
<mxGeometry x="120" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="JhubsHDD-TggGAyBPSTr-2" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="20" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="JhubsHDD-TggGAyBPSTr-3" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="JhubsHDD-TggGAyBPSTr-4" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="105" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="JhubsHDD-TggGAyBPSTr-5" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="100" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="JhubsHDD-TggGAyBPSTr-6" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="185" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="JhubsHDD-TggGAyBPSTr-7" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="180" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="JhubsHDD-TggGAyBPSTr-8" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#D5E8D4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="1">
<mxGeometry x="120" y="105" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="JhubsHDD-TggGAyBPSTr-9" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="1" source="JhubsHDD-TggGAyBPSTr-8" target="JhubsHDD-TggGAyBPSTr-1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="302.5" y="130" as="sourcePoint" />
<mxPoint x="252.5" y="130" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="svgPSnmsjaSZccQ20U9g" name="state 3">
<mxGraphModel dx="452" dy="307" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="2cyrzz5kdchdPGbAOOf7-1" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="20" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="2cyrzz5kdchdPGbAOOf7-2" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="2cyrzz5kdchdPGbAOOf7-3" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="105" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="2cyrzz5kdchdPGbAOOf7-4" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="100" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="2cyrzz5kdchdPGbAOOf7-5" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="185" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="2cyrzz5kdchdPGbAOOf7-6" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="180" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="2cyrzz5kdchdPGbAOOf7-7" value="1" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#D5E8D4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="1">
<mxGeometry x="120" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="2cyrzz5kdchdPGbAOOf7-8" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#D5E8D4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="1">
<mxGeometry x="120" y="105" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="2cyrzz5kdchdPGbAOOf7-9" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="1" source="2cyrzz5kdchdPGbAOOf7-8" target="2cyrzz5kdchdPGbAOOf7-7">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="302" y="130" as="sourcePoint" />
<mxPoint x="252" y="130" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="2cyrzz5kdchdPGbAOOf7-10" value="3" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#D5E8D4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="1">
<mxGeometry x="200" y="105" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="2cyrzz5kdchdPGbAOOf7-11" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="1" source="2cyrzz5kdchdPGbAOOf7-10" target="2cyrzz5kdchdPGbAOOf7-8">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="199.5" y="140" as="sourcePoint" />
<mxPoint x="199.5" y="90" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="ddwt5pxY8eCGA5Yld8Ut" name="state 4">
<mxGraphModel dx="452" dy="307" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="XKeFNdCRafvIn0IOzWkK-1" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0.45,0],[0.46,0.36],[1,0.36],[1,1],[0.62,1],[0.54,1],[0.54,0.64],[0,0.64],[0,0.2],[0,0],[0.24,0]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="1">
<mxGeometry x="110" y="10" width="130" height="220" as="geometry" />
</mxCell>
<mxCell id="XKeFNdCRafvIn0IOzWkK-2" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="20" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="XKeFNdCRafvIn0IOzWkK-3" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="XKeFNdCRafvIn0IOzWkK-4" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="105" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="XKeFNdCRafvIn0IOzWkK-5" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="100" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="XKeFNdCRafvIn0IOzWkK-6" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="185" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="XKeFNdCRafvIn0IOzWkK-7" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="180" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="XKeFNdCRafvIn0IOzWkK-8" value="4" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="1">
<mxGeometry x="200" y="185" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="XKeFNdCRafvIn0IOzWkK-9" value="1" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#D5E8D4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="1">
<mxGeometry x="120" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="XKeFNdCRafvIn0IOzWkK-10" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#D5E8D4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="1">
<mxGeometry x="120" y="105" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="XKeFNdCRafvIn0IOzWkK-11" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="1" source="XKeFNdCRafvIn0IOzWkK-10" target="XKeFNdCRafvIn0IOzWkK-9">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="303" y="130" as="sourcePoint" />
<mxPoint x="253" y="130" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="XKeFNdCRafvIn0IOzWkK-12" value="3" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#D5E8D4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="1">
<mxGeometry x="200" y="105" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="XKeFNdCRafvIn0IOzWkK-13" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="1" source="XKeFNdCRafvIn0IOzWkK-12" target="XKeFNdCRafvIn0IOzWkK-10">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="200.5" y="140" as="sourcePoint" />
<mxPoint x="200.5" y="90" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="XKeFNdCRafvIn0IOzWkK-14" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="1" source="XKeFNdCRafvIn0IOzWkK-8" target="XKeFNdCRafvIn0IOzWkK-12">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="310.5" y="150" as="sourcePoint" />
<mxPoint x="260.5" y="150" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="yHjaI6yTqZ63goZKKFoW" name="state 5">
<mxGraphModel dx="452" dy="307" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="yybNvkjd9s6HATvzKrxT-1" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="20" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="yybNvkjd9s6HATvzKrxT-2" value="&lt;b&gt;1&lt;br&gt;&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="25" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="yybNvkjd9s6HATvzKrxT-3" value="&lt;b&gt;2, 3&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="105" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="yybNvkjd9s6HATvzKrxT-4" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="100" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="yybNvkjd9s6HATvzKrxT-5" value="&lt;b&gt;4&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="1">
<mxGeometry x="45" y="185" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="yybNvkjd9s6HATvzKrxT-6" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="1">
<mxGeometry y="180" width="40" height="40" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View file

@ -1,500 +0,0 @@
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.1.1 Chrome/132.0.6834.210 Electron/34.3.3 Safari/537.36" version="26.1.1" pages="5">
<diagram name="state 1" id="piv4MB1wSOUai22uoHMj">
<mxGraphModel dx="1149" dy="774" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="BNEKj4FSaMJSDyX3_cBq-27" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="10" y="10" width="390" height="220" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-1" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0,0],[0.75,0],[1,0],[1,1],[0.21,1],[0,1],[0,1],[0,0.73],[0.64,0.73],[0.64,0.27],[0,0.27]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry x="100" width="140" height="220" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-2" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0.45,0],[0.75,0],[1,0],[1,1],[0.62,1],[0,1],[0,1],[0,1],[0,0.2],[0,0],[0.24,0]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry x="110" y="170" width="50" height="40" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-3" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry y="10" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-4" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry x="45" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-5" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry x="120" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-6" value="3" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry x="200" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-7" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="BNEKj4FSaMJSDyX3_cBq-27" source="BNEKj4FSaMJSDyX3_cBq-6" target="BNEKj4FSaMJSDyX3_cBq-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="190" y="70" as="sourcePoint" />
<mxPoint x="140" y="70" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-8" value="5" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry x="280" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-9" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="BNEKj4FSaMJSDyX3_cBq-27" source="BNEKj4FSaMJSDyX3_cBq-8" target="BNEKj4FSaMJSDyX3_cBq-6">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="270" y="30" as="sourcePoint" />
<mxPoint x="240" y="40" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-10" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry x="45" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-11" value="4" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry x="200" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-12" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry y="90" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-13" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry x="45" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-14" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry y="170" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-15" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="BNEKj4FSaMJSDyX3_cBq-27" source="BNEKj4FSaMJSDyX3_cBq-11" target="BNEKj4FSaMJSDyX3_cBq-6">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="290" y="40" as="sourcePoint" />
<mxPoint x="240" y="40" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-16" value="7" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry x="280" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-17" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="BNEKj4FSaMJSDyX3_cBq-27" source="BNEKj4FSaMJSDyX3_cBq-16">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="270" y="110" as="sourcePoint" />
<mxPoint x="230" y="110" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-18" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="BNEKj4FSaMJSDyX3_cBq-27" source="BNEKj4FSaMJSDyX3_cBq-16" target="BNEKj4FSaMJSDyX3_cBq-8">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="225" y="105" as="sourcePoint" />
<mxPoint x="225" y="55" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-19" value="8" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry x="360" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-20" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="BNEKj4FSaMJSDyX3_cBq-27" source="BNEKj4FSaMJSDyX3_cBq-19">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="350" y="30" as="sourcePoint" />
<mxPoint x="310" y="30" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-21" value="6" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry x="200" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-22" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="BNEKj4FSaMJSDyX3_cBq-27" source="BNEKj4FSaMJSDyX3_cBq-21">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="225" y="105" as="sourcePoint" />
<mxPoint x="215" y="125" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-23" value="1" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry x="120" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-24" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="BNEKj4FSaMJSDyX3_cBq-27" source="BNEKj4FSaMJSDyX3_cBq-21" target="BNEKj4FSaMJSDyX3_cBq-23">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="145" y="105" as="sourcePoint" />
<mxPoint x="135" y="125" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-25" value="B" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;strokeWidth=1;shape=mxgraph.flowchart.on-page_reference;strokeColor=#b85450;fillColor=#f8cecc;labelPosition=center;align=center;dashed=1;fontStyle=1;spacing=0;spacingBottom=2;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry x="120" y="170" width="14" height="14" as="geometry" />
</mxCell>
<mxCell id="BNEKj4FSaMJSDyX3_cBq-26" value="B" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;strokeWidth=1;shape=mxgraph.flowchart.on-page_reference;strokeColor=#b85450;fillColor=#f8cecc;labelPosition=center;align=center;dashed=1;fontStyle=1;spacing=0;spacingBottom=2;" vertex="1" parent="BNEKj4FSaMJSDyX3_cBq-27">
<mxGeometry x="200" y="90" width="14" height="14" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="AmVTVAnnSdh7PAwgHQ-J" name="state 2">
<mxGraphModel dx="1149" dy="774" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="-tglhTkY9j0lAeJh4ESk-26" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="10" y="10" width="390" height="220" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-1" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0.45,0],[0.75,0],[1,0],[1,1],[0.62,1],[0,1],[0,1],[0,1],[0,0.2],[0,0],[0.24,0]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry x="111" y="170" width="50" height="40" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-2" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0,0],[0.75,0],[1,0],[1,1],[0.21,1],[0,1],[0,1],[0,0.73],[0.64,0.73],[0.64,0.27],[0,0.27]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry x="101" width="140" height="220" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-3" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry y="10" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-4" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry x="45" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-5" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry x="120" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-6" value="3" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry x="200" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-7" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="-tglhTkY9j0lAeJh4ESk-26" source="-tglhTkY9j0lAeJh4ESk-6" target="-tglhTkY9j0lAeJh4ESk-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="190" y="70" as="sourcePoint" />
<mxPoint x="140" y="70" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-8" value="5" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry x="280" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-9" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="-tglhTkY9j0lAeJh4ESk-26" source="-tglhTkY9j0lAeJh4ESk-8" target="-tglhTkY9j0lAeJh4ESk-6">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="270" y="30" as="sourcePoint" />
<mxPoint x="240" y="40" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-10" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry x="45" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-11" value="4" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry x="200" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-12" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry y="90" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-13" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry x="45" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-14" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry y="170" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-15" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="-tglhTkY9j0lAeJh4ESk-26" source="-tglhTkY9j0lAeJh4ESk-11" target="-tglhTkY9j0lAeJh4ESk-6">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="290" y="40" as="sourcePoint" />
<mxPoint x="240" y="40" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-16" value="7" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry x="280" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-17" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="-tglhTkY9j0lAeJh4ESk-26" source="-tglhTkY9j0lAeJh4ESk-16">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="270" y="110" as="sourcePoint" />
<mxPoint x="230" y="110" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-18" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="-tglhTkY9j0lAeJh4ESk-26" source="-tglhTkY9j0lAeJh4ESk-16" target="-tglhTkY9j0lAeJh4ESk-8">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="225" y="105" as="sourcePoint" />
<mxPoint x="225" y="55" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-19" value="8" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry x="360" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-20" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="-tglhTkY9j0lAeJh4ESk-26" source="-tglhTkY9j0lAeJh4ESk-19">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="350" y="30" as="sourcePoint" />
<mxPoint x="310" y="30" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-21" value="6" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry x="200" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-22" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="-tglhTkY9j0lAeJh4ESk-26" source="-tglhTkY9j0lAeJh4ESk-21">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="225" y="105" as="sourcePoint" />
<mxPoint x="215" y="125" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-23" value="1" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry x="120" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-24" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="-tglhTkY9j0lAeJh4ESk-26" source="-tglhTkY9j0lAeJh4ESk-21" target="-tglhTkY9j0lAeJh4ESk-23">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="145" y="105" as="sourcePoint" />
<mxPoint x="135" y="125" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="-tglhTkY9j0lAeJh4ESk-25" value="B" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;strokeWidth=1;shape=mxgraph.flowchart.on-page_reference;strokeColor=#b85450;fillColor=#f8cecc;labelPosition=center;align=center;dashed=1;fontStyle=1;spacing=0;spacingBottom=2;" vertex="1" parent="-tglhTkY9j0lAeJh4ESk-26">
<mxGeometry x="200" y="90" width="14" height="14" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="TJGIR_aT1lfBzh5hI3th" name="state 3">
<mxGraphModel dx="1149" dy="774" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="kDi60eDrDWeN_IZO_Oer-23" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="10" y="20" width="390" height="200" as="geometry" />
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-1" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0.45,0],[0.75,0],[1,0],[1,1],[0.62,1],[0.62,0.2],[0.62,0.2],[0.62,0.2],[0,0.2],[0,0],[0.24,0]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="kDi60eDrDWeN_IZO_Oer-23">
<mxGeometry x="110" width="130" height="200" as="geometry" />
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-2" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="kDi60eDrDWeN_IZO_Oer-23">
<mxGeometry width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-3" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="kDi60eDrDWeN_IZO_Oer-23">
<mxGeometry x="45" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-4" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="kDi60eDrDWeN_IZO_Oer-23">
<mxGeometry x="120" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-5" value="3" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="kDi60eDrDWeN_IZO_Oer-23">
<mxGeometry x="200" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-6" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="kDi60eDrDWeN_IZO_Oer-23" source="kDi60eDrDWeN_IZO_Oer-5" target="kDi60eDrDWeN_IZO_Oer-4">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="190" y="60" as="sourcePoint" />
<mxPoint x="140" y="60" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-7" value="5" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="kDi60eDrDWeN_IZO_Oer-23">
<mxGeometry x="280" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-8" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="kDi60eDrDWeN_IZO_Oer-23" source="kDi60eDrDWeN_IZO_Oer-7" target="kDi60eDrDWeN_IZO_Oer-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="270" y="20" as="sourcePoint" />
<mxPoint x="240" y="30" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-9" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="kDi60eDrDWeN_IZO_Oer-23">
<mxGeometry x="45" y="85" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-10" value="4" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="kDi60eDrDWeN_IZO_Oer-23">
<mxGeometry x="200" y="85" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-11" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="kDi60eDrDWeN_IZO_Oer-23">
<mxGeometry y="80" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-12" value="&lt;b&gt;1&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="kDi60eDrDWeN_IZO_Oer-23">
<mxGeometry x="45" y="165" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-13" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="kDi60eDrDWeN_IZO_Oer-23">
<mxGeometry y="160" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-14" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="kDi60eDrDWeN_IZO_Oer-23" source="kDi60eDrDWeN_IZO_Oer-10" target="kDi60eDrDWeN_IZO_Oer-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="290" y="30" as="sourcePoint" />
<mxPoint x="240" y="30" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-15" value="7" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="kDi60eDrDWeN_IZO_Oer-23">
<mxGeometry x="280" y="85" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-16" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="kDi60eDrDWeN_IZO_Oer-23" source="kDi60eDrDWeN_IZO_Oer-15">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="270" y="100" as="sourcePoint" />
<mxPoint x="230" y="100" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-17" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="kDi60eDrDWeN_IZO_Oer-23" source="kDi60eDrDWeN_IZO_Oer-15" target="kDi60eDrDWeN_IZO_Oer-7">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="225" y="95" as="sourcePoint" />
<mxPoint x="225" y="45" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-18" value="8" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="kDi60eDrDWeN_IZO_Oer-23">
<mxGeometry x="360" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-19" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="kDi60eDrDWeN_IZO_Oer-23" source="kDi60eDrDWeN_IZO_Oer-18">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="350" y="20" as="sourcePoint" />
<mxPoint x="310" y="20" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-20" value="6" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="kDi60eDrDWeN_IZO_Oer-23">
<mxGeometry x="200" y="165" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-21" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="kDi60eDrDWeN_IZO_Oer-23" source="kDi60eDrDWeN_IZO_Oer-20">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="225" y="95" as="sourcePoint" />
<mxPoint x="215" y="115" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="kDi60eDrDWeN_IZO_Oer-22" value="B" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;strokeWidth=1;shape=mxgraph.flowchart.on-page_reference;strokeColor=#b85450;fillColor=#f8cecc;labelPosition=center;align=center;dashed=1;fontStyle=1;spacing=0;spacingBottom=2;" vertex="1" parent="kDi60eDrDWeN_IZO_Oer-23">
<mxGeometry x="200" y="80" width="14" height="14" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="8tl_i4AG-ByblRdbeoAc" name="state 4">
<mxGraphModel dx="1149" dy="774" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-22" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="10" y="20" width="390" height="200" as="geometry" />
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-1" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0.45,0],[0.75,0],[1,0],[1,1],[0.62,1],[0.62,0.2],[0.62,0.2],[0.62,0.2],[0,0.2],[0,0],[0.24,0]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="KFU6xLtBjxV3UyIQiZ9u-22">
<mxGeometry x="110" width="130" height="200" as="geometry" />
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-2" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="KFU6xLtBjxV3UyIQiZ9u-22">
<mxGeometry width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-3" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="KFU6xLtBjxV3UyIQiZ9u-22">
<mxGeometry x="45" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-4" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="KFU6xLtBjxV3UyIQiZ9u-22">
<mxGeometry x="120" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-5" value="3" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="KFU6xLtBjxV3UyIQiZ9u-22">
<mxGeometry x="200" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-6" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="KFU6xLtBjxV3UyIQiZ9u-22" source="KFU6xLtBjxV3UyIQiZ9u-5" target="KFU6xLtBjxV3UyIQiZ9u-4">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="190" y="60" as="sourcePoint" />
<mxPoint x="140" y="60" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-7" value="5" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="KFU6xLtBjxV3UyIQiZ9u-22">
<mxGeometry x="280" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-8" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="KFU6xLtBjxV3UyIQiZ9u-22" source="KFU6xLtBjxV3UyIQiZ9u-7" target="KFU6xLtBjxV3UyIQiZ9u-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="270" y="20" as="sourcePoint" />
<mxPoint x="240" y="30" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-9" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="KFU6xLtBjxV3UyIQiZ9u-22">
<mxGeometry x="45" y="85" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-10" value="4" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="KFU6xLtBjxV3UyIQiZ9u-22">
<mxGeometry x="200" y="85" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-11" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="KFU6xLtBjxV3UyIQiZ9u-22">
<mxGeometry y="80" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-12" value="&lt;b&gt;1&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="KFU6xLtBjxV3UyIQiZ9u-22">
<mxGeometry x="45" y="165" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-13" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="KFU6xLtBjxV3UyIQiZ9u-22">
<mxGeometry y="160" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-14" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="KFU6xLtBjxV3UyIQiZ9u-22" source="KFU6xLtBjxV3UyIQiZ9u-10" target="KFU6xLtBjxV3UyIQiZ9u-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="290" y="30" as="sourcePoint" />
<mxPoint x="240" y="30" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-15" value="7" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="KFU6xLtBjxV3UyIQiZ9u-22">
<mxGeometry x="280" y="85" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-16" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="KFU6xLtBjxV3UyIQiZ9u-22" source="KFU6xLtBjxV3UyIQiZ9u-15">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="270" y="100" as="sourcePoint" />
<mxPoint x="230" y="100" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-17" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="KFU6xLtBjxV3UyIQiZ9u-22" source="KFU6xLtBjxV3UyIQiZ9u-15" target="KFU6xLtBjxV3UyIQiZ9u-7">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="225" y="95" as="sourcePoint" />
<mxPoint x="225" y="45" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-18" value="8" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="KFU6xLtBjxV3UyIQiZ9u-22">
<mxGeometry x="360" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-19" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="KFU6xLtBjxV3UyIQiZ9u-22" source="KFU6xLtBjxV3UyIQiZ9u-18">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="350" y="20" as="sourcePoint" />
<mxPoint x="310" y="20" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-20" value="6" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="KFU6xLtBjxV3UyIQiZ9u-22">
<mxGeometry x="200" y="165" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="KFU6xLtBjxV3UyIQiZ9u-21" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="KFU6xLtBjxV3UyIQiZ9u-22" source="KFU6xLtBjxV3UyIQiZ9u-20">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="225" y="95" as="sourcePoint" />
<mxPoint x="215" y="115" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="I_Id2mCzoGFMSwHJqH5q" name="state 5">
<mxGraphModel dx="1149" dy="774" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="YIpS9g6xBEaVuflAf0iO-12" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="10" y="20" width="231" height="200" as="geometry" />
</mxCell>
<mxCell id="YIpS9g6xBEaVuflAf0iO-1" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="YIpS9g6xBEaVuflAf0iO-12">
<mxGeometry width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="YIpS9g6xBEaVuflAf0iO-2" value="&lt;b&gt;2, 3&lt;br&gt;&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="YIpS9g6xBEaVuflAf0iO-12">
<mxGeometry x="45" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="YIpS9g6xBEaVuflAf0iO-3" value="5" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="YIpS9g6xBEaVuflAf0iO-12">
<mxGeometry x="121" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="YIpS9g6xBEaVuflAf0iO-4" value="&lt;b&gt;4&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="YIpS9g6xBEaVuflAf0iO-12">
<mxGeometry x="45" y="85" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="YIpS9g6xBEaVuflAf0iO-5" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="YIpS9g6xBEaVuflAf0iO-12">
<mxGeometry y="80" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="YIpS9g6xBEaVuflAf0iO-6" value="&lt;b&gt;1, 6&lt;br&gt;&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="YIpS9g6xBEaVuflAf0iO-12">
<mxGeometry x="45" y="165" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="YIpS9g6xBEaVuflAf0iO-7" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="YIpS9g6xBEaVuflAf0iO-12">
<mxGeometry y="160" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="YIpS9g6xBEaVuflAf0iO-8" value="7" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="YIpS9g6xBEaVuflAf0iO-12">
<mxGeometry x="121" y="85" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="YIpS9g6xBEaVuflAf0iO-9" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="YIpS9g6xBEaVuflAf0iO-12" source="YIpS9g6xBEaVuflAf0iO-8" target="YIpS9g6xBEaVuflAf0iO-3">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="66" y="95" as="sourcePoint" />
<mxPoint x="66" y="45" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="YIpS9g6xBEaVuflAf0iO-10" value="8" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="YIpS9g6xBEaVuflAf0iO-12">
<mxGeometry x="201" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="YIpS9g6xBEaVuflAf0iO-11" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="YIpS9g6xBEaVuflAf0iO-12" source="YIpS9g6xBEaVuflAf0iO-10">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="191" y="20" as="sourcePoint" />
<mxPoint x="151" y="20" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View file

@ -1,287 +0,0 @@
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.1.1 Chrome/132.0.6834.210 Electron/34.3.3 Safari/537.36" version="26.1.1" pages="3">
<diagram id="8Eo1AGRWHWefgpNjroBf" name="state 1">
<mxGraphModel dx="1070" dy="732" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="lMObtAj2JowYBNsHivty-26" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="10" y="10" width="390" height="220" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-1" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0,0],[0.75,0],[1,0],[1,1],[0.21,1],[0,1],[0,1],[0,0.73],[0.64,0.73],[0.64,0.27],[0,0.27]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry x="100" width="140" height="220" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-2" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0.45,0],[0.75,0],[1,0],[1,1],[0.62,1],[0,1],[0,1],[0,1],[0,0.2],[0,0],[0.24,0]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry x="110" y="170" width="50" height="40" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-3" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry y="10" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-4" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry x="45" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-5" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry x="120" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-6" value="3" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry x="200" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-7" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="lMObtAj2JowYBNsHivty-26" source="lMObtAj2JowYBNsHivty-6" target="lMObtAj2JowYBNsHivty-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="190" y="70" as="sourcePoint" />
<mxPoint x="140" y="70" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-8" value="5" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry x="280" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-9" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="lMObtAj2JowYBNsHivty-26" source="lMObtAj2JowYBNsHivty-8" target="lMObtAj2JowYBNsHivty-6">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="270" y="30" as="sourcePoint" />
<mxPoint x="240" y="40" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-10" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry x="45" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-11" value="4" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry x="200" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-12" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry y="90" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-13" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry x="45" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-14" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry y="170" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-15" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="lMObtAj2JowYBNsHivty-26" source="lMObtAj2JowYBNsHivty-11" target="lMObtAj2JowYBNsHivty-6">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="290" y="40" as="sourcePoint" />
<mxPoint x="240" y="40" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-16" value="7" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry x="280" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-17" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="lMObtAj2JowYBNsHivty-26" source="lMObtAj2JowYBNsHivty-16">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="270" y="110" as="sourcePoint" />
<mxPoint x="230" y="110" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-18" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="lMObtAj2JowYBNsHivty-26" source="lMObtAj2JowYBNsHivty-16" target="lMObtAj2JowYBNsHivty-8">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="225" y="105" as="sourcePoint" />
<mxPoint x="225" y="55" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-19" value="8" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry x="360" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-20" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="lMObtAj2JowYBNsHivty-26" source="lMObtAj2JowYBNsHivty-19">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="350" y="30" as="sourcePoint" />
<mxPoint x="310" y="30" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-21" value="6" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry x="200" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-22" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="lMObtAj2JowYBNsHivty-26" source="lMObtAj2JowYBNsHivty-21">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="225" y="105" as="sourcePoint" />
<mxPoint x="215" y="125" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-23" value="1" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry x="120" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-24" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="lMObtAj2JowYBNsHivty-26" source="lMObtAj2JowYBNsHivty-21" target="lMObtAj2JowYBNsHivty-23">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="145" y="105" as="sourcePoint" />
<mxPoint x="135" y="125" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="lMObtAj2JowYBNsHivty-25" value="B" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;strokeWidth=1;shape=mxgraph.flowchart.on-page_reference;strokeColor=#b85450;fillColor=#f8cecc;labelPosition=center;align=center;dashed=1;fontStyle=1;spacing=0;spacingBottom=2;" vertex="1" parent="lMObtAj2JowYBNsHivty-26">
<mxGeometry x="120" y="170" width="14" height="14" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="ZB54035AOYvPo9_0UTcb" name="state 2">
<mxGraphModel dx="1070" dy="732" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="mpJY2JbuI38zzk8to14d-25" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="10" y="10" width="390" height="220" as="geometry" />
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-1" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0,0],[0.75,0],[1,0],[1,1],[0.21,1],[0,1],[0,1],[0,0.73],[0.64,0.73],[0.64,0.27],[0,0.27]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="mpJY2JbuI38zzk8to14d-25">
<mxGeometry x="101" width="140" height="220" as="geometry" />
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-2" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="mpJY2JbuI38zzk8to14d-25">
<mxGeometry y="10" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-3" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="mpJY2JbuI38zzk8to14d-25">
<mxGeometry x="45" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-4" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="mpJY2JbuI38zzk8to14d-25">
<mxGeometry x="120" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-5" value="3" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="mpJY2JbuI38zzk8to14d-25">
<mxGeometry x="200" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-6" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="mpJY2JbuI38zzk8to14d-25" source="mpJY2JbuI38zzk8to14d-5" target="mpJY2JbuI38zzk8to14d-4">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="190" y="70" as="sourcePoint" />
<mxPoint x="140" y="70" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-7" value="5" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="mpJY2JbuI38zzk8to14d-25">
<mxGeometry x="280" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-8" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="mpJY2JbuI38zzk8to14d-25" source="mpJY2JbuI38zzk8to14d-7" target="mpJY2JbuI38zzk8to14d-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="270" y="30" as="sourcePoint" />
<mxPoint x="240" y="40" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-9" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="mpJY2JbuI38zzk8to14d-25">
<mxGeometry x="45" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-10" value="4" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="mpJY2JbuI38zzk8to14d-25">
<mxGeometry x="200" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-11" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="mpJY2JbuI38zzk8to14d-25">
<mxGeometry y="90" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-12" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="mpJY2JbuI38zzk8to14d-25">
<mxGeometry x="45" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-13" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="mpJY2JbuI38zzk8to14d-25">
<mxGeometry y="170" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-14" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="mpJY2JbuI38zzk8to14d-25" source="mpJY2JbuI38zzk8to14d-10" target="mpJY2JbuI38zzk8to14d-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="290" y="40" as="sourcePoint" />
<mxPoint x="240" y="40" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-15" value="7" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="mpJY2JbuI38zzk8to14d-25">
<mxGeometry x="280" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-16" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="mpJY2JbuI38zzk8to14d-25" source="mpJY2JbuI38zzk8to14d-15">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="270" y="110" as="sourcePoint" />
<mxPoint x="230" y="110" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-17" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="mpJY2JbuI38zzk8to14d-25" source="mpJY2JbuI38zzk8to14d-15" target="mpJY2JbuI38zzk8to14d-7">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="225" y="105" as="sourcePoint" />
<mxPoint x="225" y="55" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-18" value="8" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="mpJY2JbuI38zzk8to14d-25">
<mxGeometry x="360" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-19" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="mpJY2JbuI38zzk8to14d-25" source="mpJY2JbuI38zzk8to14d-18">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="350" y="30" as="sourcePoint" />
<mxPoint x="310" y="30" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-20" value="6" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="mpJY2JbuI38zzk8to14d-25">
<mxGeometry x="200" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-21" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="mpJY2JbuI38zzk8to14d-25" source="mpJY2JbuI38zzk8to14d-20">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="225" y="105" as="sourcePoint" />
<mxPoint x="215" y="125" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-22" value="1" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="mpJY2JbuI38zzk8to14d-25">
<mxGeometry x="120" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-23" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="mpJY2JbuI38zzk8to14d-25" source="mpJY2JbuI38zzk8to14d-20" target="mpJY2JbuI38zzk8to14d-22">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="145" y="105" as="sourcePoint" />
<mxPoint x="135" y="125" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="mpJY2JbuI38zzk8to14d-24" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0.45,0],[0.75,0],[1,0],[1,1],[0.62,1],[0,1],[0,1],[0,1],[0,0.2],[0,0],[0.24,0]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="mpJY2JbuI38zzk8to14d-25">
<mxGeometry x="111" y="170" width="50" height="40" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram name="state 3" id="pfYS2UsdWF6MnEGA_9M5">
<mxGraphModel dx="1070" dy="732" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="G2f_uyPNZEB1i5etgh__-147" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="10" y="20" width="230" height="200" as="geometry" />
</mxCell>
<mxCell id="G2f_uyPNZEB1i5etgh__-136" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="G2f_uyPNZEB1i5etgh__-147">
<mxGeometry width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="G2f_uyPNZEB1i5etgh__-137" value="&lt;b&gt;2, 3&lt;br&gt;&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="G2f_uyPNZEB1i5etgh__-147">
<mxGeometry x="45" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="G2f_uyPNZEB1i5etgh__-138" value="5" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="G2f_uyPNZEB1i5etgh__-147">
<mxGeometry x="120" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="G2f_uyPNZEB1i5etgh__-139" value="&lt;b&gt;4&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="G2f_uyPNZEB1i5etgh__-147">
<mxGeometry x="45" y="85" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="G2f_uyPNZEB1i5etgh__-140" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="G2f_uyPNZEB1i5etgh__-147">
<mxGeometry y="80" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="G2f_uyPNZEB1i5etgh__-141" value="&lt;b&gt;1, 6&lt;br&gt;&lt;/b&gt;" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="G2f_uyPNZEB1i5etgh__-147">
<mxGeometry x="45" y="165" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="G2f_uyPNZEB1i5etgh__-142" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="G2f_uyPNZEB1i5etgh__-147">
<mxGeometry y="160" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="G2f_uyPNZEB1i5etgh__-143" value="7" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="G2f_uyPNZEB1i5etgh__-147">
<mxGeometry x="120" y="85" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="G2f_uyPNZEB1i5etgh__-144" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="G2f_uyPNZEB1i5etgh__-147" source="G2f_uyPNZEB1i5etgh__-143" target="G2f_uyPNZEB1i5etgh__-138">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="65" y="95" as="sourcePoint" />
<mxPoint x="65" y="45" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="G2f_uyPNZEB1i5etgh__-145" value="8" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="G2f_uyPNZEB1i5etgh__-147">
<mxGeometry x="200" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="G2f_uyPNZEB1i5etgh__-146" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="G2f_uyPNZEB1i5etgh__-147" source="G2f_uyPNZEB1i5etgh__-145">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="190" y="20" as="sourcePoint" />
<mxPoint x="150" y="20" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View file

@ -1,223 +0,0 @@
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.1.1 Chrome/132.0.6834.210 Electron/34.3.3 Safari/537.36" version="26.1.1" pages="3">
<diagram name="state 1" id="VrdkUToxpVwyLyul_Cfd">
<mxGraphModel dx="1070" dy="732" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="oHeAk4B_Z_e2L7biMZUw-16" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="10" y="10" width="230" height="220" as="geometry" />
</mxCell>
<mxCell id="oHeAk4B_Z_e2L7biMZUw-1" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0.24,0],[1,0],[1,0.4],[1,1],[0.48,1],[0,1],[0,0.75],[0,0.73],[0.02,0.5],[0,0.25],[0,0]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="oHeAk4B_Z_e2L7biMZUw-16">
<mxGeometry x="101" width="70" height="220" as="geometry" />
</mxCell>
<mxCell id="oHeAk4B_Z_e2L7biMZUw-2" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="oHeAk4B_Z_e2L7biMZUw-16">
<mxGeometry y="10" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="oHeAk4B_Z_e2L7biMZUw-3" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="oHeAk4B_Z_e2L7biMZUw-16">
<mxGeometry x="45" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="oHeAk4B_Z_e2L7biMZUw-4" value="1" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="oHeAk4B_Z_e2L7biMZUw-16">
<mxGeometry x="120" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="oHeAk4B_Z_e2L7biMZUw-5" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="oHeAk4B_Z_e2L7biMZUw-16">
<mxGeometry x="45" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="oHeAk4B_Z_e2L7biMZUw-6" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="oHeAk4B_Z_e2L7biMZUw-16">
<mxGeometry y="90" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="oHeAk4B_Z_e2L7biMZUw-7" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="oHeAk4B_Z_e2L7biMZUw-16">
<mxGeometry x="45" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="oHeAk4B_Z_e2L7biMZUw-8" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="oHeAk4B_Z_e2L7biMZUw-16">
<mxGeometry y="170" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="oHeAk4B_Z_e2L7biMZUw-9" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="oHeAk4B_Z_e2L7biMZUw-16">
<mxGeometry x="120" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="oHeAk4B_Z_e2L7biMZUw-10" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="oHeAk4B_Z_e2L7biMZUw-16" source="oHeAk4B_Z_e2L7biMZUw-9" target="oHeAk4B_Z_e2L7biMZUw-4">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="65" y="105" as="sourcePoint" />
<mxPoint x="65" y="55" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="oHeAk4B_Z_e2L7biMZUw-11" value="3" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="oHeAk4B_Z_e2L7biMZUw-16">
<mxGeometry x="200" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="oHeAk4B_Z_e2L7biMZUw-12" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="oHeAk4B_Z_e2L7biMZUw-16" source="oHeAk4B_Z_e2L7biMZUw-11">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="190" y="30" as="sourcePoint" />
<mxPoint x="150" y="30" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="oHeAk4B_Z_e2L7biMZUw-13" value="4" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="oHeAk4B_Z_e2L7biMZUw-16">
<mxGeometry x="120" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="oHeAk4B_Z_e2L7biMZUw-14" value="B" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;strokeWidth=1;shape=mxgraph.flowchart.on-page_reference;strokeColor=#b85450;fillColor=#f8cecc;labelPosition=center;align=center;dashed=1;fontStyle=1;spacing=0;spacingBottom=2;" vertex="1" parent="oHeAk4B_Z_e2L7biMZUw-16">
<mxGeometry x="120" y="170" width="14" height="14" as="geometry" />
</mxCell>
<mxCell id="oHeAk4B_Z_e2L7biMZUw-15" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="oHeAk4B_Z_e2L7biMZUw-16" source="oHeAk4B_Z_e2L7biMZUw-13" target="oHeAk4B_Z_e2L7biMZUw-9">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="199.43" y="182" as="sourcePoint" />
<mxPoint x="199.43" y="132" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="dumz7MtjuSRbbVgNawrV" name="state 2">
<mxGraphModel dx="1070" dy="732" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="n_ChFhbu9l9toi0L3hxX-16" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="10" y="10" width="230" height="220" as="geometry" />
</mxCell>
<mxCell id="n_ChFhbu9l9toi0L3hxX-1" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0.24,0],[1,0],[1,0.4],[1,1],[0.48,1],[0,1],[0,0.75],[0,0.73],[0.02,0.5],[0,0.25],[0,0]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="n_ChFhbu9l9toi0L3hxX-16">
<mxGeometry x="101" width="70" height="220" as="geometry" />
</mxCell>
<mxCell id="n_ChFhbu9l9toi0L3hxX-2" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="n_ChFhbu9l9toi0L3hxX-16">
<mxGeometry y="10" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="n_ChFhbu9l9toi0L3hxX-3" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="n_ChFhbu9l9toi0L3hxX-16">
<mxGeometry x="45" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="n_ChFhbu9l9toi0L3hxX-4" value="1" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="n_ChFhbu9l9toi0L3hxX-16">
<mxGeometry x="120" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="n_ChFhbu9l9toi0L3hxX-5" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="n_ChFhbu9l9toi0L3hxX-16">
<mxGeometry x="45" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="n_ChFhbu9l9toi0L3hxX-6" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="n_ChFhbu9l9toi0L3hxX-16">
<mxGeometry y="90" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="n_ChFhbu9l9toi0L3hxX-7" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="n_ChFhbu9l9toi0L3hxX-16">
<mxGeometry x="45" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="n_ChFhbu9l9toi0L3hxX-8" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="n_ChFhbu9l9toi0L3hxX-16">
<mxGeometry y="170" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="n_ChFhbu9l9toi0L3hxX-9" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="n_ChFhbu9l9toi0L3hxX-16">
<mxGeometry x="120" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="n_ChFhbu9l9toi0L3hxX-10" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="n_ChFhbu9l9toi0L3hxX-16" source="n_ChFhbu9l9toi0L3hxX-9" target="n_ChFhbu9l9toi0L3hxX-4">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="65" y="105" as="sourcePoint" />
<mxPoint x="65" y="55" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="n_ChFhbu9l9toi0L3hxX-11" value="3" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="n_ChFhbu9l9toi0L3hxX-16">
<mxGeometry x="200" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="n_ChFhbu9l9toi0L3hxX-12" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="n_ChFhbu9l9toi0L3hxX-16" source="n_ChFhbu9l9toi0L3hxX-11">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="190" y="30" as="sourcePoint" />
<mxPoint x="150" y="30" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="n_ChFhbu9l9toi0L3hxX-13" value="4" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="n_ChFhbu9l9toi0L3hxX-16">
<mxGeometry x="120" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="n_ChFhbu9l9toi0L3hxX-14" value="B" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;strokeWidth=1;shape=mxgraph.flowchart.on-page_reference;strokeColor=#b85450;fillColor=#f8cecc;labelPosition=center;align=center;dashed=1;fontStyle=1;spacing=0;spacingBottom=2;" vertex="1" parent="n_ChFhbu9l9toi0L3hxX-16">
<mxGeometry x="120" y="170" width="14" height="14" as="geometry" />
</mxCell>
<mxCell id="n_ChFhbu9l9toi0L3hxX-15" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="n_ChFhbu9l9toi0L3hxX-16" source="n_ChFhbu9l9toi0L3hxX-13" target="n_ChFhbu9l9toi0L3hxX-9">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="199.43000000000006" y="182" as="sourcePoint" />
<mxPoint x="199.43000000000006" y="132" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="UgwmXKjNo72Kti5tnIX_" name="state 3">
<mxGraphModel dx="1070" dy="732" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="PkcBEfq_iBlsM-m9fPOb-20" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="10" y="10" width="230" height="220" as="geometry" />
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-2" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0.24,0],[1,0],[1,0.4],[1,1],[0.48,1],[0,1],[0,0.75],[0,0.73],[0.02,0.5],[0,0.25],[0,0]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="PkcBEfq_iBlsM-m9fPOb-20">
<mxGeometry x="100" width="70" height="220" as="geometry" />
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-3" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="PkcBEfq_iBlsM-m9fPOb-20">
<mxGeometry y="10" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-4" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="PkcBEfq_iBlsM-m9fPOb-20">
<mxGeometry x="45" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-5" value="1" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="PkcBEfq_iBlsM-m9fPOb-20">
<mxGeometry x="120" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-6" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="PkcBEfq_iBlsM-m9fPOb-20">
<mxGeometry x="45" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-7" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="PkcBEfq_iBlsM-m9fPOb-20">
<mxGeometry y="90" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-8" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="PkcBEfq_iBlsM-m9fPOb-20">
<mxGeometry x="45" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-9" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="PkcBEfq_iBlsM-m9fPOb-20">
<mxGeometry y="170" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-10" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="PkcBEfq_iBlsM-m9fPOb-20">
<mxGeometry x="120" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-11" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="PkcBEfq_iBlsM-m9fPOb-20" source="PkcBEfq_iBlsM-m9fPOb-10" target="PkcBEfq_iBlsM-m9fPOb-5">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="65" y="105" as="sourcePoint" />
<mxPoint x="65" y="55" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-12" value="3" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="PkcBEfq_iBlsM-m9fPOb-20">
<mxGeometry x="200" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-13" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="PkcBEfq_iBlsM-m9fPOb-20" source="PkcBEfq_iBlsM-m9fPOb-12">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="190" y="30" as="sourcePoint" />
<mxPoint x="150" y="30" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-14" value="5" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="PkcBEfq_iBlsM-m9fPOb-20">
<mxGeometry x="200" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-15" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="PkcBEfq_iBlsM-m9fPOb-20" source="PkcBEfq_iBlsM-m9fPOb-14">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="146" y="25" as="sourcePoint" />
<mxPoint x="151" y="110" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-16" value="4" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;plain-blue;gradientColor=none;fillColor=#B5E3Fe;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="PkcBEfq_iBlsM-m9fPOb-20">
<mxGeometry x="120" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-17" value="B" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;strokeWidth=1;shape=mxgraph.flowchart.on-page_reference;strokeColor=#b85450;fillColor=#f8cecc;labelPosition=center;align=center;dashed=1;fontStyle=1;spacing=0;spacingBottom=2;" vertex="1" parent="PkcBEfq_iBlsM-m9fPOb-20">
<mxGeometry x="120" y="170" width="14" height="14" as="geometry" />
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-18" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="PkcBEfq_iBlsM-m9fPOb-20" source="PkcBEfq_iBlsM-m9fPOb-16">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="199.43000000000006" y="182" as="sourcePoint" />
<mxPoint x="135" y="125" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="PkcBEfq_iBlsM-m9fPOb-19" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="PkcBEfq_iBlsM-m9fPOb-20" source="PkcBEfq_iBlsM-m9fPOb-14" target="PkcBEfq_iBlsM-m9fPOb-12">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="440" y="230" as="sourcePoint" />
<mxPoint x="311" y="230" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View file

@ -1,203 +0,0 @@
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.1.1 Chrome/132.0.6834.210 Electron/34.3.3 Safari/537.36" version="26.1.1" pages="3">
<diagram name="state 1" id="w7PF-E3A9k5X4TpleA9C">
<mxGraphModel dx="1070" dy="774" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="sifWEnGrpBqlT8R1-RFs-15" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="10" y="20" width="310" height="200" as="geometry" />
</mxCell>
<mxCell id="sifWEnGrpBqlT8R1-RFs-1" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="sifWEnGrpBqlT8R1-RFs-15">
<mxGeometry width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="sifWEnGrpBqlT8R1-RFs-2" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="sifWEnGrpBqlT8R1-RFs-15">
<mxGeometry x="45" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="sifWEnGrpBqlT8R1-RFs-3" value="1" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="sifWEnGrpBqlT8R1-RFs-15">
<mxGeometry x="120" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="sifWEnGrpBqlT8R1-RFs-4" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="sifWEnGrpBqlT8R1-RFs-15">
<mxGeometry x="45" y="85" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="sifWEnGrpBqlT8R1-RFs-5" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="sifWEnGrpBqlT8R1-RFs-15">
<mxGeometry y="80" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="sifWEnGrpBqlT8R1-RFs-6" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="sifWEnGrpBqlT8R1-RFs-15">
<mxGeometry x="45" y="165" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="sifWEnGrpBqlT8R1-RFs-7" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="sifWEnGrpBqlT8R1-RFs-15">
<mxGeometry y="160" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="sifWEnGrpBqlT8R1-RFs-8" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="sifWEnGrpBqlT8R1-RFs-15">
<mxGeometry x="120" y="85" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="sifWEnGrpBqlT8R1-RFs-9" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="sifWEnGrpBqlT8R1-RFs-15" source="sifWEnGrpBqlT8R1-RFs-8" target="sifWEnGrpBqlT8R1-RFs-3">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="65" y="95" as="sourcePoint" />
<mxPoint x="65" y="45" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="sifWEnGrpBqlT8R1-RFs-10" value="3" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="sifWEnGrpBqlT8R1-RFs-15">
<mxGeometry x="200" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="sifWEnGrpBqlT8R1-RFs-11" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="sifWEnGrpBqlT8R1-RFs-15" source="sifWEnGrpBqlT8R1-RFs-10">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="190" y="20" as="sourcePoint" />
<mxPoint x="150" y="20" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="sifWEnGrpBqlT8R1-RFs-12" value="B" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;strokeWidth=1;shape=mxgraph.flowchart.on-page_reference;strokeColor=#b85450;fillColor=#f8cecc;labelPosition=center;align=center;dashed=1;fontStyle=1;spacing=0;spacingBottom=2;" vertex="1" parent="sifWEnGrpBqlT8R1-RFs-15">
<mxGeometry x="120" y="80" width="14" height="14" as="geometry" />
</mxCell>
<mxCell id="sifWEnGrpBqlT8R1-RFs-13" value="4" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="sifWEnGrpBqlT8R1-RFs-15">
<mxGeometry x="280" y="5" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="sifWEnGrpBqlT8R1-RFs-14" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="sifWEnGrpBqlT8R1-RFs-15" source="sifWEnGrpBqlT8R1-RFs-13" target="sifWEnGrpBqlT8R1-RFs-10">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="290" y="59.659999999999854" as="sourcePoint" />
<mxPoint x="240" y="59.659999999999854" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="8cHA4ecnVEcz090J-liN" name="state 2">
<mxGraphModel dx="1070" dy="774" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="OwjlZwffn-Y4nYBfrumN-16" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="10" y="10" width="311" height="210" as="geometry" />
</mxCell>
<mxCell id="OwjlZwffn-Y4nYBfrumN-1" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="OwjlZwffn-Y4nYBfrumN-16">
<mxGeometry y="10" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="OwjlZwffn-Y4nYBfrumN-2" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="OwjlZwffn-Y4nYBfrumN-16">
<mxGeometry x="45" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="OwjlZwffn-Y4nYBfrumN-3" value="1" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="OwjlZwffn-Y4nYBfrumN-16">
<mxGeometry x="120" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="OwjlZwffn-Y4nYBfrumN-4" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="OwjlZwffn-Y4nYBfrumN-16">
<mxGeometry x="45" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="OwjlZwffn-Y4nYBfrumN-5" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="OwjlZwffn-Y4nYBfrumN-16">
<mxGeometry y="90" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="OwjlZwffn-Y4nYBfrumN-6" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="OwjlZwffn-Y4nYBfrumN-16">
<mxGeometry x="45" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="OwjlZwffn-Y4nYBfrumN-7" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="OwjlZwffn-Y4nYBfrumN-16">
<mxGeometry y="170" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="OwjlZwffn-Y4nYBfrumN-8" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#B5E3FE;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="OwjlZwffn-Y4nYBfrumN-16">
<mxGeometry x="120" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="OwjlZwffn-Y4nYBfrumN-9" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="OwjlZwffn-Y4nYBfrumN-16" source="OwjlZwffn-Y4nYBfrumN-8" target="OwjlZwffn-Y4nYBfrumN-3">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="65" y="105" as="sourcePoint" />
<mxPoint x="65" y="55" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="OwjlZwffn-Y4nYBfrumN-10" value="3" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="OwjlZwffn-Y4nYBfrumN-16">
<mxGeometry x="200" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="OwjlZwffn-Y4nYBfrumN-11" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="OwjlZwffn-Y4nYBfrumN-16" source="OwjlZwffn-Y4nYBfrumN-10">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="190" y="30" as="sourcePoint" />
<mxPoint x="150" y="30" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="OwjlZwffn-Y4nYBfrumN-12" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0.24,0],[1,0],[1,0.4],[1,1],[0.48,1],[0,1],[0,0.75],[0,0.73],[0.02,0.5],[0,0.25],[0,0]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="OwjlZwffn-Y4nYBfrumN-16">
<mxGeometry x="101" width="70" height="140" as="geometry" />
</mxCell>
<mxCell id="OwjlZwffn-Y4nYBfrumN-13" value="B" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;strokeWidth=1;shape=mxgraph.flowchart.on-page_reference;strokeColor=#b85450;fillColor=#f8cecc;labelPosition=center;align=center;dashed=1;fontStyle=1;spacing=0;spacingBottom=2;" vertex="1" parent="OwjlZwffn-Y4nYBfrumN-16">
<mxGeometry x="121" y="90" width="14" height="14" as="geometry" />
</mxCell>
<mxCell id="OwjlZwffn-Y4nYBfrumN-14" value="4" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="OwjlZwffn-Y4nYBfrumN-16">
<mxGeometry x="281" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="OwjlZwffn-Y4nYBfrumN-15" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="OwjlZwffn-Y4nYBfrumN-16" source="OwjlZwffn-Y4nYBfrumN-14" target="OwjlZwffn-Y4nYBfrumN-10">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="291" y="69.65999999999985" as="sourcePoint" />
<mxPoint x="231" y="30" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="9Yl-pgUNl23KlRTR3j43" name="state 3">
<mxGraphModel dx="1070" dy="774" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="450" pageHeight="250" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="3Z5IVvEdUQoImQymVIXm-16" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="10" y="10" width="310" height="210" as="geometry" />
</mxCell>
<mxCell id="3Z5IVvEdUQoImQymVIXm-1" value="" style="verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.polygon;polyCoords=[[0.24,0],[1,0],[1,0.4],[1,1],[0.48,1],[0,1],[0,0.75],[0,0.73],[0.02,0.5],[0,0.25],[0,0]];polyline=0;fillColor=none;dashed=1;strokeColor=#CC00CC;strokeWidth=2;perimeterSpacing=0;shadow=1;sketch=1;curveFitting=1;jiggle=2;fixDash=0;container=0;dropTarget=0;" vertex="1" parent="3Z5IVvEdUQoImQymVIXm-16">
<mxGeometry x="101" width="70" height="140" as="geometry" />
</mxCell>
<mxCell id="3Z5IVvEdUQoImQymVIXm-2" value="SS2" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="3Z5IVvEdUQoImQymVIXm-16">
<mxGeometry y="10" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="3Z5IVvEdUQoImQymVIXm-3" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="3Z5IVvEdUQoImQymVIXm-16">
<mxGeometry x="45" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="3Z5IVvEdUQoImQymVIXm-4" value="1" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#d5e8d4;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="3Z5IVvEdUQoImQymVIXm-16">
<mxGeometry x="120" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="3Z5IVvEdUQoImQymVIXm-5" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="3Z5IVvEdUQoImQymVIXm-16">
<mxGeometry x="45" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="3Z5IVvEdUQoImQymVIXm-6" value="SS1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="3Z5IVvEdUQoImQymVIXm-16">
<mxGeometry y="90" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="3Z5IVvEdUQoImQymVIXm-7" value="" style="whiteSpace=wrap;html=1;aspect=fixed;labelBackgroundColor=none;fillColor=#ffe6cc;strokeColor=#d79b00;" vertex="1" parent="3Z5IVvEdUQoImQymVIXm-16">
<mxGeometry x="45" y="175" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="3Z5IVvEdUQoImQymVIXm-8" value="T1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;fontSize=14;fontStyle=1;fontFamily=Courier New;" vertex="1" parent="3Z5IVvEdUQoImQymVIXm-16">
<mxGeometry y="170" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="3Z5IVvEdUQoImQymVIXm-9" value="2" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#B5E3FE;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="3Z5IVvEdUQoImQymVIXm-16">
<mxGeometry x="120" y="95" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="3Z5IVvEdUQoImQymVIXm-10" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;" edge="1" parent="3Z5IVvEdUQoImQymVIXm-16" source="3Z5IVvEdUQoImQymVIXm-9" target="3Z5IVvEdUQoImQymVIXm-4">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="65" y="105" as="sourcePoint" />
<mxPoint x="65" y="55" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="3Z5IVvEdUQoImQymVIXm-11" value="3" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#B5E3FE;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="3Z5IVvEdUQoImQymVIXm-16">
<mxGeometry x="200" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="3Z5IVvEdUQoImQymVIXm-12" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="3Z5IVvEdUQoImQymVIXm-16" source="3Z5IVvEdUQoImQymVIXm-11">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="190" y="30" as="sourcePoint" />
<mxPoint x="150" y="30" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="3Z5IVvEdUQoImQymVIXm-13" value="B" style="verticalLabelPosition=middle;verticalAlign=middle;html=1;strokeWidth=1;shape=mxgraph.flowchart.on-page_reference;strokeColor=#b85450;fillColor=#f8cecc;labelPosition=center;align=center;dashed=1;fontStyle=1;spacing=0;spacingBottom=2;" vertex="1" parent="3Z5IVvEdUQoImQymVIXm-16">
<mxGeometry x="120" y="90" width="14" height="14" as="geometry" />
</mxCell>
<mxCell id="3Z5IVvEdUQoImQymVIXm-14" value="4" style="verticalLabelPosition=middle;verticalAlign=middle;strokeWidth=4;shape=mxgraph.flowchart.on-page_reference;fillColor=#B5E3FE;strokeColor=#000000;labelPosition=center;align=center;html=1;fontSize=18;fontStyle=1;spacingBottom=3;" vertex="1" parent="3Z5IVvEdUQoImQymVIXm-16">
<mxGeometry x="280" y="15" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="3Z5IVvEdUQoImQymVIXm-15" value="" style="endArrow=open;html=1;rounded=0;strokeWidth=3;curved=0;endFill=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="3Z5IVvEdUQoImQymVIXm-16" source="3Z5IVvEdUQoImQymVIXm-14" target="3Z5IVvEdUQoImQymVIXm-11">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="270" y="30" as="sourcePoint" />
<mxPoint x="230" y="30" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View file

@ -1,36 +0,0 @@
digraph arch_wayland {
edge[
fontname="DejaVu Sans",
dir="both",
arrowtail="dot",
arrowsize=.5,
fontname="DejaVu Sans",
fontsize="18",
]
node[
color=none,
margin=0,
fontname="DejaVu Sans",
fontsize="18",
]
c1 [label=<<TABLE STYLE="rounded" BGCOLOR="#ffbc00"><TR><TD>Wayland Client</TD></TR></TABLE>>, URL="#c1"]
c2 [label=<<TABLE STYLE="rounded" BGCOLOR="#ffbc00"><TR><TD>Wayland Client</TD></TR></TABLE>>, URL="#c2"]
comp [tooltip="Wayland Compositor", label=<<TABLE STYLE="rounded" BGCOLOR="#ffbc00"><TR><TD><BR/>Wayland<BR/>Compositor<BR/><BR/></TD></TR></TABLE>>, URL="#comp"]
impl [tooltip="KMS evdev Kernel", label=<<TABLE STYLE="rounded" BGCOLOR="#ffbc00"><TR><TD>KMS</TD><TD>evdev</TD></TR><TR><TD COLSPAN="2">Kernel</TD></TR></TABLE>>, URL="#impl"]
c1 -> comp [taillabel="③", labeldistance=2.5, URL="#step_3"];
c2 -> comp;
comp -> c1 [label="②", URL="#step_2"];
comp -> c2;
comp -> impl [xlabel = "④", URL="#step_4"];
comp -> impl [style = invis, label=" "];
impl -> comp [xlabel = "①", URL="#step_1"];
c1 -> c2 [style=invis];
}

View file

@ -1,53 +0,0 @@
digraph arch_x {
edge[
fontname="DejaVu Sans",
dir="both",
arrowtail="dot",
arrowsize=.5,
fontname="DejaVu Sans",
fontsize="18",
]
node[
shape="none",
color=none,
margin=0,
fontname="DejaVu Sans",
fontsize="18",
]
{
rank=same;
c1 [label=<<TABLE STYLE="rounded" BGCOLOR="#ffbc00"><TR><TD>X Client</TD></TR></TABLE>>, URL="#c1"]
c3 [label=<<TABLE STYLE="rounded" BGCOLOR="#ffbc00"><TR><TD>X Client</TD></TR></TABLE>>, URL="#c3"]
}
c2 [label=<<TABLE STYLE="rounded" BGCOLOR="#ffbc00"><TR><TD>X Client</TD></TR></TABLE>>, URL="#c2"]
{
rank=same;
xserver [tooltip="X Server", label=<<TABLE STYLE="rounded" BGCOLOR="#ffbc00"><TR><TD><BR/>X Server<BR/><BR/></TD></TR></TABLE>>, URL="#xserver"]
comp [tooltip="Compositor", label=<<TABLE STYLE="rounded" BGCOLOR="#ffbc00"><TR><TD><BR/>Compositor<BR/><BR/></TD></TR></TABLE>>, URL="#comp"]
}
impl [tooltip="KMS evdev Kernel", label=<<TABLE STYLE="rounded" BGCOLOR="#ffbc00"><TR><TD>KMS</TD><TD>evdev</TD></TR><TR><TD COLSPAN="2">Kernel</TD></TR></TABLE>>, URL="#impl"]
c1 -> xserver [taillabel="③", labeldistance=2, URL="#step_3"];
c2 -> xserver;
c3 -> xserver;
xserver -> c1 [taillabel="②", labeldistance=2, URL="#step_2"];
xserver -> c2;
xserver -> c3;
xserver -> impl [taillabel="⑥", labeldistance=1.75, URL="#step_6"];
xserver -> impl [style=invis, label=" "];
impl -> xserver [taillabel="①", labeldistance=1.75, URL="#step_1"];
xserver -> comp [style=invis];
xserver -> comp [taillabel="④", labeldistance=1.75, labelangle=-45, URL="#step_4"];
comp -> xserver [taillabel="⑤", URL="#step_5"];
comp -> xserver [style=invis]
c1 -> c2 [style=invis];
c3 -> c2 [style=invis];
}

View file

@ -1,58 +0,0 @@
srcs = files(
'src/Protocol.md',
'src/Foreword.md',
'src/Xwayland.md',
'src/SUMMARY.md',
'src/Content_Updates.md',
'src/Color.md',
'src/Message_XML.md',
'src/Architecture.md',
'src/Introduction.md',
'src/images/content-updates/sync-to-desync-subsurf-3.png',
'src/images/content-updates/sync-subsurf-case2-2.png',
'src/images/content-updates/simple-synchronized-state-4.png',
'src/images/content-updates/sync-subsurf-case2-3.png',
'src/images/content-updates/sync-to-desync-transition-2.png',
'src/images/content-updates/simple-desynchronized-state-4.png',
'src/images/content-updates/simple-synchronized-state-3.png',
'src/images/content-updates/simple-synchronized-state-1.png',
'src/images/content-updates/sync-subsurf-case1-4.png',
'src/images/content-updates/sync-to-desync-subsurf-1.png',
'src/images/content-updates/simple-desynchronized-state-1.png',
'src/images/content-updates/simple-desynchronized-state-3.png',
'src/images/content-updates/simple-desynchronized-state-6.png',
'src/images/content-updates/sync-subsurf-case1-2.png',
'src/images/content-updates/sync-subsurf-case1-1.png',
'src/images/content-updates/simple-synchronized-state-5.png',
'src/images/content-updates/simple-synchronized-state-2.png',
'src/images/content-updates/simple-desynchronized-state-2.png',
'src/images/content-updates/content-update-legend.png',
'src/images/content-updates/sync-to-desync-subsurf-2.png',
'src/images/content-updates/sync-to-desync-transition-3.png',
'src/images/content-updates/sync-subsurf-case2-1.png',
'src/images/content-updates/sync-subsurf-case1-5.png',
'src/images/content-updates/sync-subsurf-case1-3.png',
'src/images/content-updates/simple-desynchronized-state-5.png',
'src/images/content-updates/sync-to-desync-transition-1.png',
'src/images/icon.svg',
'src/images/x-architecture.png',
'src/images/wayland.png',
'src/images/wayland-architecture.png',
'src/images/xwayland-architecture.png',
'src/Compositors.md',
)
custom_target(
'Wayland-book',
command: [
mdbook,
'build',
'-d', meson.current_build_dir() / 'book',
meson.current_source_dir(),
],
depend_files: srcs,
output: 'book',
build_by_default: true,
install: true,
install_dir: publican_install_prefix,
)

View file

@ -1,215 +0,0 @@
# Wayland Architecture
## X vs. Wayland Architecture
A good way to understand the Wayland architecture and how it is different from X
is to follow an event from the input device to the point where the change it
affects appears on screen.
This is where we are now with X:
**X architecture diagram**
![](images/x-architecture.png)
1. The kernel gets an event from an input device and sends it to X through the
evdev input driver. The kernel does all the hard work here by driving the
device and translating the different device specific event protocols to the
linux evdev input event standard.
2. The X server determines which window the event affects and sends it to the
clients that have selected for the event in question on that window. The X
server doesn't actually know how to do this right, since the window location
on screen is controlled by the compositor and may be transformed in a number
of ways that the X server doesn't understand (scaled down, rotated, wobbling,
etc).
3. The client looks at the event and decides what to do. Often the UI will have
to change in response to the event - perhaps a check box was clicked or the
pointer entered a button that must be highlighted. Thus the client sends a
rendering request back to the X server.
4. When the X server receives the rendering request, it sends it to the driver
to let it program the hardware to do the rendering. The X server also
calculates the bounding region of the rendering, and sends that to the
compositor as a damage event.
5. The damage event tells the compositor that something changed in the window
and that it has to recomposite the part of the screen where that window is
visible. The compositor is responsible for rendering the entire screen
contents based on its scenegraph and the contents of the X windows. Yet, it
has to go through the X server to render this.
6. The X server receives the rendering requests from the compositor and either
copies the compositor back buffer to the front buffer or does a pageflip. In
the general case, the X server has to do this step so it can account for
overlapping windows, which may require clipping and determine whether or not
it can page flip. However, for a compositor, which is always fullscreen, this
is another unnecessary context switch.
As suggested above, there are a few problems with this approach. The X server
doesn't have the information to decide which window should receive the event,
nor can it transform the screen coordinates to window-local coordinates. And
even though X has handed responsibility for the final painting of the screen to
the compositing manager, X still controls the front buffer and modesetting. Most
of the complexity that the X server used to handle is now available in the
kernel or self contained libraries (KMS, evdev, mesa, fontconfig, freetype,
cairo, Qt etc). In general, the X server is now just a middle man that
introduces an extra step between applications and the compositor and an extra
step between the compositor and the hardware.
In Wayland the compositor is the display server. We transfer the control of KMS
and evdev to the compositor. The Wayland protocol lets the compositor send the
input events directly to the clients and lets the client send the damage event
directly to the compositor:
**Wayland architecture diagram**
![](images/wayland-architecture.png)
1. The kernel gets an event and sends it to the compositor. This is similar to
the X case, which is great, since we get to reuse all the input drivers in
the kernel.
2. The compositor looks through its scenegraph to determine which window should
receive the event. The scenegraph corresponds to what's on screen and the
compositor understands the transformations that it may have applied to the
elements in the scenegraph. Thus, the compositor can pick the right window
and transform the screen coordinates to window-local coordinates, by applying
the inverse transformations. The types of transformation that can be applied
to a window is only restricted to what the compositor can do, as long as it
can compute the inverse transformation for the input events.
3. As in the X case, when the client receives the event, it updates the UI in
response. But in the Wayland case, the rendering happens in the client, and
the client just sends a request to the compositor to indicate the region that
was updated.
4. The compositor collects damage requests from its clients and then
recomposites the screen. The compositor can then directly issue an ioctl to
schedule a pageflip with KMS.
## Wayland Rendering
One of the details I left out in the above overview is how clients actually
render under Wayland. By removing the X server from the picture we also removed
the mechanism by which X clients typically render. But there's another mechanism
that we're already using with DRI2 under X: direct rendering. With direct
rendering, the client and the server share a video memory buffer. The client
links to a rendering library such as OpenGL that knows how to program the
hardware and renders directly into the buffer. The compositor in turn can take
the buffer and use it as a texture when it composites the desktop. After the
initial setup, the client only needs to tell the compositor which buffer to use
and when and where it has rendered new content into it.
This leaves an application with two ways to update its window contents:
1. Render the new content into a new buffer and tell the compositor to use that
instead of the old buffer. The application can allocate a new buffer every
time it needs to update the window contents or it can keep two (or more)
buffers around and cycle between them. The buffer management is entirely
under application control.
2. Render the new content into the buffer that it previously told the compositor
to to use. While it's possible to just render directly into the buffer shared
with the compositor, this might race with the compositor. What can happen is
that repainting the window contents could be interrupted by the compositor
repainting the desktop. If the application gets interrupted just after
clearing the window but before rendering the contents, the compositor will
texture from a blank buffer. The result is that the application window will
flicker between a blank window or half-rendered content. The traditional way
to avoid this is to render the new content into a back buffer and then copy
from there into the compositor surface. The back buffer can be allocated on
the fly and just big enough to hold the new content, or the application can
keep a buffer around. Again, this is under application control.
In either case, the application must tell the compositor which area of the
surface holds new contents. When the application renders directly to the shared
buffer, the compositor needs to be noticed that there is new content. But also
when exchanging buffers, the compositor doesn't assume anything changed, and
needs a request from the application before it will repaint the desktop. The
idea that even if an application passes a new buffer to the compositor, only a
small part of the buffer may be different, like a blinking cursor or a spinner.
## Accelerated GPU Buffer Exchange
Clients
[exchange](https://docs.kernel.org/userspace-api/dma-buf-alloc-exchange.html)
GPU buffers with the compositor as dma-buf file descriptors, which are universal
handles that are independent of any particular rendering API or memory
allocator. The
[linux-dmabuf-v1](https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/stable/linux-dmabuf/linux-dmabuf-v1.xml)
protocol is used to turn one or more dma-buf FDs into a
[wl_buffer](https://wayland.app/protocols/wayland#wl_buffer).
If the client uses the
[Vulkan](https://docs.vulkan.org/spec/latest/chapters/VK_KHR_surface/wsi.html)
or
[EGL](https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_platform_wayland.txt)
(via
[wayland-egl](https://gitlab.freedesktop.org/wayland/wayland/-/tree/main/egl))
window-system integration (WSI), this is done transparently by the WSI.
Clients can alternatively allocate and import dma-bufs themselves using the GBM
library, Vulkan, udmabuf, or dma-buf heaps.
- Using GBM, the client can allocate a gbm_bo and export one or more dma-buf FDs
from it.
- Using Vulkan, the client can create a VkDeviceMemory object and use
[VK_EXT_external_memory_dma_buf](https://docs.vulkan.org/refpages/latest/refpages/source/VK_EXT_external_memory_dma_buf.html)
and
[VK_EXT_image_drm_format_modifier](https://docs.vulkan.org/refpages/latest/refpages/source/VK_EXT_image_drm_format_modifier.html)
to export a dma-buf FD from it.
- [udmabuf](https://lwn.net/Articles/749206/) can be used to create dma-buf FDs
from linear host memory.
- [Dma-buf heaps](https://docs.kernel.org/userspace-api/dma-buf-heaps.html) can
be used by privileged applications to create dma-buf FDs on embedded devices.
Compositors use
[VK_EXT_external_memory_dma_buf](https://docs.vulkan.org/refpages/latest/refpages/source/VK_EXT_external_memory_dma_buf.html)
and
[VK_EXT_image_drm_format_modifier](https://docs.vulkan.org/refpages/latest/refpages/source/VK_EXT_image_drm_format_modifier.html)
or
[EGL_EXT_image_dma_buf_import](https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import.txt)
and
[EGL_EXT_image_dma_buf_import_modifiers](https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import_modifiers.txt)
to import the dma-bufs provided by the client into their own Vulkan or EGL
renderers.
Clients do not need to wait for the GPU to finish rendering before submitting
dma-bufs to the compositor. Clients can use the
[linux-drm-syncobj-v1](https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml)
protocol to exchange DRM synchronization objects with the compositor. These
objects are used to asynchronously signal ownership transfer of buffers from
clients to the compositor and vice versa. The WSIs do this transparently.
If the linux-drm-syncobj-v1 protocol is not supported by the compositor, clients
and compositors can use the
[DMA_BUF_IOCTL_EXPORT_SYNC_FILE](https://docs.kernel.org/driver-api/dma-buf.html#c.dma_buf_export_sync_file)
and
[DMA_BUF_IOCTL_IMPORT_SYNC_FILE](https://docs.kernel.org/driver-api/dma-buf.html#c.dma_buf_import_sync_file)
ioctls to access and create implicit synchronization barriers.
## Display Programming
Compositors enumerate DRM KMS devices using
[udev](https://en.wikipedia.org/wiki/Udev). Udev also notifies compositors of
KMS device and display hotplug events.
Access to DRM KMS device ioctls is privileged. Since compositors usually run as
unprivileged applications, they typically gain access to a privileged file
descriptor using the
[TakeDevice](https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.login1.html#Session%20Objects)
method provided by logind.
Using the file descriptor, compositors use KMS
[ioctls](https://docs.kernel.org/gpu/drm-kms.html) to enumerate the available
displays.
Compositors use [atomic mode
setting](https://docs.kernel.org/gpu/drm-kms.html#atomic-mode-setting) to change
the buffer shown by the display, to change the display's resolution, to enable
or disable HDR, and so on.

View file

@ -1,100 +0,0 @@
# Color management
## Overview
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
([stimuli](https://cie.co.at/eilvterm/17-23-002)) 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.
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.
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.
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.
## Protocol Interfaces
Color management interfaces in Wayland and divided into two protocols:
[color-management](https://gitlab.freedesktop.org/wayland/wayland-protocols/-/tree/main/staging/color-management?ref_type=heads)
and
[color-representation](https://gitlab.freedesktop.org/wayland/wayland-protocols/-/tree/main/staging/color-representation?ref_type=heads).
They are designed to work together, but they can also be used independently when
the other one is not needed.
### Color-management
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.
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 _image description_ object. Clients
can create image description objects and tag `wl_surface`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 `wl_surface`, and
that preference can change over time, e.g. when the `wl_surface` is moved from
one `wl_output` to another. Following the compositor's preference may provide
advantages in image quality and power consumption.
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.
### Color-representation
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
`wl_surface` with color-representation metadata to tell the compositor what kind
of pixel data will be displayed through the wl_surface.
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.

View file

@ -1,76 +0,0 @@
# Types of Compositors
Compositors come in different types, depending on which role they play in the
overall architecture of the OS. For instance, a [system
compositor](#system-compositor) can be used for booting the system, handling
multiple user switching, a possible console terminal emulator and so forth. A
different compositor, a [session compositor](#session-compositor) would provide
the actual desktop environment. There are many ways for different types of
compositors to co-exist.
In this section, we introduce three types of Wayland compositors relying on
[libwayland-server](https://gitlab.freedesktop.org/wayland/wayland).
## System Compositor
A system compositor can run from early boot until shutdown. It effectively
replaces the kernel vt system, and can tie in with the systems graphical boot
setup and multiseat support.
A system compositor can host different types of session compositors, and let us
switch between multiple sessions (fast user switching, or secure/personal
desktop switching).
A linux implementation of a system compositor will typically use libudev, egl,
kms, evdev and cairo.
For fullscreen clients, the system compositor can reprogram the video scanout
address to read directly from the client provided buffer.
## Session Compositor
A session compositor is responsible for a single user session. If a system
compositor is present, the session compositor will run nested under the system
compositor. Nesting is feasible because the protocol is asynchronous; roundtrips
would be too expensive when nesting is involved. If no system compositor is
present, a session compositor can run directly on the hardware.
X applications can continue working under a session compositor by means of a
root-less X server that is activated on demand.
Possible examples for session compositors include
- gnome-shell
- moblin
- kwin
- kmscon
- rdp session
- Weston with X11 or Wayland backend is a session compositor nested in another
session compositor.
- fullscreen X session under Wayland
## Embedding Compositor
X11 lets clients embed windows from other clients, or lets clients copy pixmap
contents rendered by another client into their window. This is often used for
applets in a panel, browser plugins and similar. Wayland doesn't directly allow
this, but clients can communicate GEM buffer names out-of-band, for example,
using D-Bus, or command line arguments when the panel launches the applet.
Another option is to use a nested Wayland instance. For this, the Wayland server
will have to be a library that the host application links to. The host
application will then pass the Wayland server socket name to the embedded
application, and will need to implement the Wayland compositor interface. The
host application composites the client surfaces as part of its window, that is,
in the web page or in the panel. The benefit of nesting the Wayland server is
that it provides the requests the embedded client needs to inform the host about
buffer updates and a mechanism for forwarding input events from the host
application.
An example for this kind of setup is firefox embedding the flash player as a
kind of special-purpose compositor.

View file

@ -1,214 +0,0 @@
# Content Updates
## Overview
In the Wayland protocol, requests are asynchronous but take effect immediately
when the compositor receives them. However, some requests on surfaces are not
applied immediately but are instead double-buffered to allow atomic changes.
These double-buffered changes are committed through the wl_surface.commit
request, which creates a Content Update.
Content Updates encapsulate all double-buffered state changes and can be applied
by the compositor. The complexity arises when considering subsurfaces, which can
operate in synchronized mode. When a subsurface is synchronized, its Content
Updates must be applied atomically together with the parent surface's state.
This synchronization can extend through an entire tree of subsurfaces, where
child subsurfaces inherit the synchronized behavior from their parents.
Historically, Content Updates from synchronized subsurfaces were merged into the
pending state of the parent surface on commit. However, the introduction of
constraints—which can defer the application of Content Updates—necessitated a
more sophisticated model. This led to the implementation of per-surface queues
of Content Updates, with dependencies between Content Updates across different
queues. This queuing model maintains backwards compatibility with the earlier
approach of merging Content Updates into the parent's pending state on commit.
The core protocol defines the semantics of Content Updates using per-surface
queues, but compositors that do not need to support constraints may implement
the simpler legacy model where synchronized subsurface states are merged
directly into the parent's pending state.
## Rules
The core protocol specifies the behavior in wl_subsurface and wl_surface.commit.
The behavior can be summarized by the following rules:
1. Content Updates (CU) contain all double-buffered state of the surface and
selected state from their direct children.
2. Surfaces which are effectively synchronized create Synchronized Content
Updates (SCU), otherwise they create Desync Content Updates (DCU).
3. When a CU is created, it gets a dependency on the previous CU of the same
queues (if it exists).
4. When a CU is created, it gets a dependency on the last SCU of direct child
surfaces that are not reachable (if they exists).
5. The CUs and their dependencies form a DAG, where CUs are nodes and
dependencies are edges.
6. All DCUs starting from the front of the queues until the first SCU or the
back of the queue is reached are candidates.
7. If the maximal DAG that's reachable from a candidate (candidate DAG) does not
have any constraints, then this DAG can be applied.
8. A DAG is applied atomically by recursively applying a content update without
dependencies and removing it from the DAG.
9. Surfaces transition from effectively sync to effectively desync after their
parents.
10. When a surface transitions to effectively desync, all SCUs in its queue
which are not reachable by a DCU become DCUs.
## Examples
These examples should help to build an intuition for how content updates
actually behave. They cover the interesting edge cases, such as subsurfaces with
constraints, and transitioning from a sync subsurface to a desync one.
In all the examples below, the surface T1 refers to a toplevel surface, SS1
refers to a sub-surface which is a child of T1, and SS2 refers to a sub-surface
which is a child of SS1.
### Legend
![](images/content-updates/content-update-legend.png)
### Simple Desynchronized Case
1. SS2 is effectively desynchronized and commits. This results in the
desynchronized content update (DCU) _1_.
![](images/content-updates/simple-desynchronized-state-1.png)
2. DCU _1_ is a candidate, and the candidate DAG reachable from DCU _1_ is only DCU
_1_ itself. DCU _1_ and thus the candidate DAG does not have any constraints and
can be applied.
![](images/content-updates/simple-desynchronized-state-2.png)
3. The content updates of the candidate DAG get applied to the surface atomically.
![](images/content-updates/simple-desynchronized-state-3.png)
4. T1 commits a DCU with a _buffer-sync_ constraint. It is a candidate but its DAG
can't be applied because it contains a constraint.
![](images/content-updates/simple-desynchronized-state-4.png)
5. T1 commits another CU (DCU _3_) which is added at the end of the queue, with a
dependency to the previous CU (DCU _2_). Both DCU _2_ and DCU _3_ are
candidates, but both DAGs contain DCU _2_ with a constraint, and can't be
applied.
![](images/content-updates/simple-desynchronized-state-5.png)
6. When the constraint gets cleared, both DAGs can be applied to the surface
atomitcally (either only _2_, or _2_ and _3_).
![](images/content-updates/simple-desynchronized-state-6.png)
### Simple Synchronized Case
1. SS1 and SS2 are effectively synchronized. SS2 commits SCU _1_.
![](images/content-updates/simple-synchronized-state-1.png)
2. SS1 commits SCU _2_. The direct child surfaces SS2 has the last SCU _1_ in its
queue, which is not reachable. This creates a dependency from SCU _2_ to SCU
_1_.
![](images/content-updates/simple-synchronized-state-2.png)
3. SS1 commits SCU _3_. The direct child surfaces SS2 has the last SCU _1_ in its
queue, which is already reachable by SCU _2_. No dependency to SCU _1_ is
created. A dependency to the previous CU of the same queue (SCU _2_) is created.
![](images/content-updates/simple-synchronized-state-3.png)
4. T1 commit DCU _4_. It is a candidate, its DAG does not contain any constraint
and it can be applied.
![](images/content-updates/simple-synchronized-state-4.png)
5. The DAG gets applied to the surfaces atomically.
![](images/content-updates/simple-synchronized-state-5.png)
### Complex Synchronized Subsurface Case 1
1. Every DCU (_1_ and _6_) contain CUs with constraints in their candidate DAG
![](images/content-updates/sync-subsurf-case1-1.png)
2. Waiting until the _buffer-sync_ constrain on CU _1_ is cleared, the candidate
DAG of CU _1_ does not contain constraints and can be applied
![](images/content-updates/sync-subsurf-case1-2.png)
3. That leaves the candidate DAG of CU _6_ which still contains another CU with a
_buffer-sync_ constrain
![](images/content-updates/sync-subsurf-case1-3.png)
4. Waiting until the _buffer-sync_ constrain on CU _6_ is cleared, the candidate
DAG of _6_ does not contain CUs with constraints and can be applied.
![](images/content-updates/sync-subsurf-case1-4.png)
5. There is no DCU left and no constraint remaining. Nothing more can be applied
without a new CU.
![](images/content-updates/sync-subsurf-case1-5.png)
### Complex Synchronized Subsurface Case 2
1. Both DCUs (_1_ and _6_) have a reachable DAG containing CU _1_ with a constraint
![](images/content-updates/sync-subsurf-case2-1.png)
2. Waiting until the _buffer-sync_ constrain on _1_ is cleared, both DAGs contain
no CU with constraints and can be applied in any order
![](images/content-updates/sync-subsurf-case2-2.png)
3. That leaves the same state as in the previous case
![](images/content-updates/sync-subsurf-case2-3.png)
### Synchronized to Desynchronized Subsurface
1. There is one DCU (_4_) with its reachable DAG that cannot be applied because CU
_4_ contains a constraint
![](images/content-updates/sync-to-desync-subsurf-1.png)
2. Surface _SS1_ transitions from effectively synchronized to effectively
desynchronized. SCU _2_ is reachable by DCU _4_ so nothing changes.
![](images/content-updates/sync-to-desync-subsurf-2.png)
3. Surface _SS1_ provides a new DCU (_5_) but because the CU before (_2_) is a
Synchronized CU, it is not a candidate
![](images/content-updates/sync-to-desync-subsurf-3.png)
### Synchronized to Desynchronized Transition
1. There are four SCUs and all surfaces are effectively synchronized.
![](images/content-updates/sync-to-desync-transition-1.png)
2. Surface _SS1_ transitions to effectively desynchronized and SCU _2_ becomes a
DCU because it is not reachable from a DCU
![](images/content-updates/sync-to-desync-transition-2.png)
3. Surface _SS2_ transitions to effectively desynchronized. SCUs _3_ and _4_ become
DCUs because they are not reachable from a DCU. SCU _1_ does not change because
it is reachable by DCU _2_.
![](images/content-updates/sync-to-desync-transition-3.png)

View file

@ -1,86 +0,0 @@
<img style="display: block; margin: auto;" src="images/wayland.png">
# Preface
This document describes the Wayland architecture and Wayland model of operation.
This document is aimed primarily at Wayland developers and those looking to
program with it; it does not cover application development.
There have been many contributors to this document and since this is only the
first edition many errors are expected to be found. We appreciate corrections.
Yours, the Wayland open-source community November 2012
## Protocol Documentation
This document does not describe the semantics of individual messages sent
between compositors and clients. Consult the following documents to learn about
concrete Wayland interfaces, requests, and events.
- [wayland.xml] - The official documentation of the core protocol.
- [wayland-protocols] - Standardized Wayland extension protocols.
- [wayland.app] - A community-maintained website that renders these protocols,
and many more, as easily accessible HTML pages.
[wayland.xml]: https://gitlab.freedesktop.org/wayland/wayland/-/blob/main/protocol/wayland.xml
[wayland-protocols]: https://gitlab.freedesktop.org/wayland/wayland-protocols
[wayland.app]: https://wayland.app
## About the Book
This book is written in markdown and converted to HTML using
[mdbook](https://rust-lang.github.io/mdBook).
It supports the [CommonMark](https://commonmark.org/) dialect of markdown plus a number of
widely supported extensions:
- `~~strikethrough~~`
- ```markdown
footnotes[^note]
[^note]: text
```
- ```markdown
| Tables | Header2 |
|--------|---------|
| abc | def |
```
- ```markdown
- [x] Task lists
- [ ] Incomplete task
```
- ```markdown
definition lists
: This is the definition of a
definition list
```
- ```markdown
> [!NOTE]
> Admonitions
```
The full list of extensions is documented
[here](https://rust-lang.github.io/mdBook/format/markdown.html#extensions).
## Copyright
Copyright © 2012 Kristian Høgsberg
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.

View file

@ -1,73 +0,0 @@
# Introduction
## Motivation
Most Linux and Unix-based systems rely on the X Window System (or simply _X_) as
the low-level protocol for building bitmap graphics interfaces. On these
systems, the X stack has grown to encompass functionality arguably belonging in
client libraries, helper libraries, or the host operating system kernel. Support
for things like PCI resource management, display configuration management,
direct rendering, and memory management has been integrated into the X stack,
imposing limitations like limited support for standalone applications,
duplication in other projects (e.g. the Linux fb layer or the DirectFB project),
and high levels of complexity for systems combining multiple elements (for
example radeon memory map handling between the fb driver and X driver, or VT
switching).
Moreover, X has grown to incorporate modern features like offscreen rendering
and scene composition, but subject to the limitations of the X architecture. For
example, the X implementation of composition adds additional context switches
and makes things like input redirection difficult.
![](images/x-architecture.png)
The diagram above illustrates the central role of the X server and compositor in
operations, and the steps required to get contents on to the screen.
Over time, X developers came to understand the shortcomings of this approach and
worked to split things up. Over the past several years, a lot of functionality
has moved out of the X server and into client-side libraries or kernel drivers.
One of the first components to move out was font rendering, with freetype and
fontconfig providing an alternative to the core X fonts. Direct rendering OpenGL
as a graphics driver in a client side library went through some iterations,
ending up as DRI2, which abstracted most of the direct rendering buffer
management from client code. Then cairo came along and provided a modern 2D
rendering library independent of X, and compositing managers took over control
of the rendering of the desktop as toolkits like GTK+ and Qt moved away from
using X APIs for rendering. Recently, memory and display management have moved
to the Linux kernel, further reducing the scope of X and its driver stack. The
end result is a highly modular graphics stack.
## The compositing manager as the display server
Wayland is a new display server and compositing protocol, and Weston is the
implementation of this protocol which builds on top of all the components above.
We are trying to distill out the functionality in the X server that is still
used by the modern Linux desktop. This turns out to be not a whole lot.
Applications can allocate their own off-screen buffers and render their window
contents directly, using hardware accelerated libraries like libGL, or high
quality software implementations like those found in Cairo. In the end, whats
needed is a way to present the resulting window surface for display, and a way
to receive and arbitrate input among multiple clients. This is what Wayland
provides, by piecing together the components already in the eco-system in a
slightly different way.
X will always be relevant, in the same way Fortran compilers and VRML browsers
are, but its time that we think about moving it out of the critical path and
provide it as an optional component for legacy applications.
Overall, the philosophy of Wayland is to provide clients with a way to manage
windows and how their contents are displayed. Rendering is left to clients, and
system wide memory management interfaces are used to pass buffer handles between
clients and the compositing manager.
![](images/wayland-architecture.png)
The figure above illustrates how Wayland clients interact with a Wayland server.
Note that window management and composition are handled entirely in the server,
significantly reducing complexity while marginally improving performance through
reduced context switching. The resulting system is easier to build and extend
than a similar X system, because often changes need only be made in one place.
Or in the case of protocol extensions, two (rather than 3 or 4 in the X case
where window management and/or composition handling may also need to be
updated).

View file

@ -1,515 +0,0 @@
# Message Definition Language
## Overview
The fundamentals of the Wayland protocol are explained in [Wayland Protocol and
Model of Operation](Protocol.md). This chapter formally defines the language
used to define Wayland protocols.
Wayland is an object-oriented protocol. Each object follows exactly one
interface. An interface is a collection of message and enumeration definitions.
A message can be either a request (sent by a client) or an event (sent by a
server). A message can have arguments. All arguments are typed.
## XML Elements
### protocol
```
protocol ::= (copyright?, description? interface+)
```
`protocol` is the root element in a Wayland protocol XML file. Code generation
tools may optionally use the protocol `name` in API symbol names. The XML file
name should be similar to the protocol name.
The description element should be used to document the intended purpose of the
protocol, give an overview, and give any development stage notices if
applicable.
The copyright element should be used to indicate the copyrights and the license
of the XML file.
**Required attributes**
`name`="`cname`"
: The name of the protocol (a.k.a protocol extension). The name must start
with one of the ASCII characters a-z, A-Z, or underscore, and the following
characters may additionally include numbers 0-9.
The name should be globally unique. Protocols to be included in
[wayland-protocols](https://gitlab.freedesktop.org/wayland/wayland-protocols)
must follow the naming rules set there. Other protocols should use a unique
prefix for the name, e.g. referring to the owning project's name.
### copyright
Parent elements: protocol
```
copyright ::= #PCDATA
```
Contains free-form, pre-formatted text for copyright and license notices.
### description
Parent elements: protocol, interface, request, event, arg, enum, entry
```
description ::= #PCDATA
```
Contains human-readable documentation for its parent element. May contain
formatted text, including paragraphs and bulleted lists.
**Optional attributes**
`summary`="`summary`"
: A short (half a line at most) description of the documented element.
When a description element is used, it is recommended to not use the
`summary` attribute of the parent element.
### interface
Parent elements: protocol
```
interface ::= (description?, (request|event|enum)+)
```
An interface element contains the requests and events that form the interface.
Enumerations can also be defined with enum elements. These all belong into the
namespace of the interface. Code generation tools may use the interface `name`
in API symbol names.
Interfaces form an ancestry tree. Aside from
[wl_display](https://wayland.app/protocols/wayland#wl_display), new protocol
objects are always created through an existing protocol object that may be
referred to as _the factory object_. This can happen in one of two ways: the
factory object's interface either defines or does not define the new object's
interface.
When the factory interface defines the new object's interface, the new object
also inherits the factory object's interface version number. This number defines
the interface version of the new object. The factory object is referred to as
_the parent object_ and the factory interface is referred to as _the parent
interface_. This forms the ancestry tree of interfaces.
When the factory interface does not define the new object's interface, both the
interface name and the version must be communicated explicitly. The foremost
example of this is
[wl_registry.bind](https://wayland.app/protocols/wayland#wl_registry:request:bind).
In this case the terms "parent" or "ancestor" are not used. Interfaces that are
advertised through
[wl_registry](https://wayland.app/protocols/wayland#wl_registry) are called
_global interfaces_, or globals for short.
If objects having the interface can cause protocol errors, the protocol error
codes must be defined within the interface with an enum element with its `name`
set to `"error"`. Protocol error codes are always specific to the interface of
the object referred to in
[wl_display.error](https://wayland.app/protocols/wayland#wl_display:event:error).
The description element should be used to describe the purpose and the general
usage of the interface.
**Required attributes**
`name`="`cname`"
: The name of the interface. The name must start with one of the ASCII
characters a-z, A-Z, or underscore, and the following characters may
additionally include numbers 0-9. The name must be unique in the
protocol, and preferably it should also be globally unique to avoid API
conflicts in language bindings of multiple protocols.
Protocols to be included in
[wayland-protocols](https://gitlab.freedesktop.org/wayland/wayland-protocols)
must follow the interface naming rules set there. Other protocols should use
a unique prefix for the name, e.g. referring to the owning project's name.
`version`="`V`"
: The interface's latest version number `V` must be an integer greater than
zero. An interface element defines all versions of the interface from 1 to
`V` inclusive. The contents of each interface version are defined in each of
the request, event, enum and entry elements using the attributes `since` and
`deprecated-since`, and in the specification text.
When an interface is extended, the version number must be incremented on all
the interfaces part of the same interface ancestry tree. The exception to
this rule are interfaces which are forever stuck to version 1, which is
usually caused by having multiple parent interfaces with independent
ancestor global interfaces. In this case, the `frozen="true"` attribute
described below should be used.
A protocol object may have any defined version of the interface. The version
of the object is determined at runtime either by inheritance from another
protocol object or explicitly.
It is possible for a protocol object to have a version higher than defined
by its interface. This may happen when the interface is stuck at version 1
as per above. It may also happen when a protocol XML file has not been
thoroughly updated as required. In such cases the object shall function as
with the highest defined interface version.
**Optional attributes**
`frozen`="`true`"
: The interface is frozen and forever stuck at version 1.
This attribute should be applied to interfaces that have multiple parent
interfaces with independent ancestor global interfaces, for example
`wl_buffer` and `wl_callback`.
### request
Parent elements: interface
```
request ::= (description?, arg*)
```
Defines a request, a message from a client to a server. Requests are always
associated with a specific protocol object.
Requests are automatically assigned opcodes in the order they appear inside the
interface element. Therefore the only backwards-compatible way to add requests
to an interface is to add them to the end. Any event elements do not interfere
with request opcode assignments.
The arg elements declare the request's arguments. There can be 0 to 20 arguments
for a request. The order of arg inside the request element defines the order of
the arguments on the wire. All declared arguments are mandatory, and extra
arguments are not allowed on the wire.
The description element should be used to document the request.
**Required attributes**
`name`="`cname`"
: The name of the request. The name must start with one of the ASCII
characters a-z, A-Z, or underscore, and the following characters may
additionally include numbers 0-9. The name must be unique within
all requests and events in the containing interface.
Code and language binding generators may use the name in the API they
create. The `name` of the containing interface provides the namespace for
requests.
**Optional attributes**
`type`="`destructor`"
: When this attribute is present, the request is a destructor: it shall
destroy the protocol object it is sent on. Protocol IPC libraries may use
this for bookkeeping protocol object lifetimes.
Libwayland-client uses this information to ignore incoming events for
destroyed protocol objects. Such events may occur due to a natural race
condition between the client destroying a protocol object and the server
sending events before processing the destroy request.
`since`="`S`"
: `S` must be an integer greater than zero. If `since` is not specified,
`since="1"` is assumed.
This request was added in interface `version` `S`. The request does not
exist if the protocol object has a bound version smaller than `S`. Attempts
to use it in such a case shall raise the protocol error
`wl_display.error.invalid_method`.
`deprecated-since`="`D`"
: `D` must be an integer greater than the value of `since`. If
`deprecated-since` is not specified, then the request is not deprecated in
any version of the containing interface.
This request was deprecated in interface `version` `D` and above, and should
not be sent on protocol objects of such version. This is informational.
Compositors must still be prepared to handle the request unless specified
otherwise.
### event
Parent elements: interface
```
event ::= (description?, arg*)
```
Defines an event, a message from a server to a client. Events are always
associated with a specific protocol object.
Events are automatically assigned opcodes in the order they appear inside the
interface element. Therefore the only backwards-compatible way to add events to
an interface is to add them to the end. Any request elements do not interfere
with event opcode assignments.
The arg elements declare the event's arguments. There can be 0 to 20 arguments
for an event. The order of arg inside the event element defines the order of the
arguments on the wire. All declared arguments are mandatory, and extra arguments
are not allowed on the wire.
The description element should be used to document the event.
**Required attributes**
`name`="`cname`"
: The name of the event. The name must start with one of the ASCII characters
a-z, A-Z, or underscore, and the following characters may additionally
include numbers 0-9. The name must be unique within all requests and events
in the containing interface.
Code and language binding generators may use the name in the API they
create. The `name` of the containing interface provides the namespace for
events.
**Optional attributes**
`type`="`destructor`"
: When this attribute is present, the event is a destructor: it shall destroy
the protocol object it is sent on. Protocol IPC libraries may use this for
bookkeeping protocol object lifetimes.
> [!WARNING]
> Destructor events are an underdeveloped feature in Wayland. They can be
> used only on client-created protocol objects, and it is the protocol
> designer's responsibility to design such a message exchange that race
> conditions cannot occur. The main problem would be a client sending a
> request at the same time as the server is sending a destructor event. The
> server will consider the protocol object to be already invalid or even
> recycled when it proceeds to process the request. This often results in
> protocol errors, but under specific conditions it might also result in
> silently incorrect behavior.
>
> Destructor events should not be used in new protocols. If a destructor
> event is necessary, the simplest way to avoid these problems is to have
> the interface not contain any requests.
`since`="`S`"
: `S` must be an integer greater than zero. If `since` is not specified,
`since="1"` is assumed.
This event was added in interface `version` `S`. The event does not exist if
the protocol object has a bound version smaller than `S`.
`deprecated-since`="`D`"
: `D` must be an integer greater than the value of `since`. If
`deprecated-since` is not specified, then the event is not deprecated in any
version of the containing interface.
This event was deprecated in interface `version` `D` and above, and should
not be sent on protocol objects of such version. This is informational.
Clients must still be prepared to receive this event unless otherwise
specified.
### arg
Parent elements: request, event
```
arg ::= description?
```
This element declares one argument for the request or the event.
**Required attributes**
`name`="`cname`"
: The name of the argument. The name must start with one of the ASCII
characters a-z, A-Z, or underscore, and the following characters may
additionally include numbers 0-9. The name must be unique within
all the arguments of the parent element.
`type`="`T`"
: The type `T` of the argument datum must be one of:
`int`
: 32-bit signed integer.
`uint`
: 32-bit unsigned integer.
`fixed`
: Signed 24.8-bit fixed-point value.
`string`
: UTF-8 encoded string value, NUL byte terminated. Interior NUL bytes are
not allowed.
`array`
: A byte array of arbitrary data.
`fd`
: A file descriptor.
The file descriptor must be open and valid on send. It is not possible
to pass a null value.
`new_id`
: Creates a new protocol object. A request or an event may have at most
one `new_id` argument.
If `interface` is specified, the new protocol object shall have the
specified interface, and the new object's (interface) version shall be
the version of the object on which the request or event is being sent.
If `interface` is not specified, the request shall implicitly have two
additional arguments: A `string` for an interface name, and a `uint` for
the new object's version. Leaving the interface unspecified is reserved
for special use,
[wl_registry.bind](https://wayland.app/protocols/wayland#wl_registry:request:bind)
for example.
> [!NOTE]
> An event argument must always specify the `new_id` `interface`.
`object`
: Reference to an existing protocol object.
The attribute `interface` should be specified. Otherwise IPC libraries
cannot enforce the interface, and checking the interface falls on user
code and specification text.
**Optional attributes**
`summary`="`summary`"
: A short (half a line at most) description. This attribute should not be used
if a description is used.
`interface`="`iface`"
: If given, `iface` must be the `name` of some interface, and `type` of this
argument must be either `"object"` or `"new_id"`. This indicates that the
existing or new object must have the interface `iface`. Use for other
argument types is forbidden.
> [!NOTE]
> If an interface from another protocol is used, then this creates a
> dependency between the protocols. If an application generates code for one
> protocol, then it must also generate code for all dependencies. Therefore
> this would not be a backwards compatible change.
`allow-null`="`true`" | "`false`"
: Whether the argument value can be null on send. Defaults to `"false"`,
meaning it is illegal to send a null value. Can be used only when `type` is
`"string"` or `"object"`.
> [!NOTE]
> Even though this attribute can be used to forbid a compositor from sending
> a null object as an event argument, an IPC library implementation may not
> protect the client from receiving a null object. This can happen with
> libwayland-client when the client has destroyed the protocol object before
> dispatching an event that referred to it in an argument.
`enum`="`enum-cname-suffix`"
: If specified, indicates that the argument value should come from the enum
named `enum-cname-suffix`. If the enumeration is a bitfield, then `type`
must be `"uint"`. Otherwise `type` must be either `"uint"` or `"int"`.
The name `enum-cname-suffix` refers to an enum in the same interface by
default. If it is necessary to refer to an enumeration from another
interface, the interface name can be given with a period:
```
`enum`="`iface`.`enum-cname-suffix`"
```
> [!NOTE]
> This attribute alone does not automatically restrict the legal values for
> this argument. If values from outside of the enumeration need to be
> forbidden, that must be specified explicitly in the documentation.
>
> A common design pattern is to have the server advertise the supported
> enumeration or bit values with events and explicitly forbid clients from
> using any other values in requests. This also requires a protocol error
> code to be specified with the error enum to be raised if a client uses an
> illegal value, see [interface](#interface).
### enum
Parent elements: protocol
```
enum ::= (description?, entry*)
```
This tag defines an enumeration of integer values. Enumerations are merely a
syntactic construct to give names to arbitrary integer constants. Each constant
is listed as an entry with its name. There are two types of enumerations:
regular enumerations and bitfields.
Regular enumerations do not use `bitfield` attribute, or they set it to
`"false"`. The set of pre-defined values that belong to a regular enumeration is
exactly the set of values listed as entry elements after the protocol object
version is taken into account. See the entry attributes `since` and
`deprecated-since`.
Bitfields set `bitfield` to `"true"`. The set of values that belong to a
bitfield enumeration are all the values that can be formed by the bitwise-or
operator from the set of values listed as entry elements like in the regular
enumeration. Usually also zero is implicitly included.
All the values in a regular enumeration must be either signed or unsigned 32-bit
integers. All the values in a bitfield enumeration must be unsigned 32-bit
integers.
**Required attributes**
`name`="`cname-suffix`"
: The name of the enumeration. The name must contain only the ASCII characters
a-z, A-Z, 0-9, or underscore. The name cannot be empty. The name must be
unique within all enumerations in the containing interface. The name is used
as the namespace for all the contained entry elements.
**Optional attributes**
`since`="`S`"
: `S` must be an integer greater than zero. If `since` is not specified,
`since="1"` is assumed.
This enumeration was added in interface `version` `S`. The enumeration does
not exist if the protocol object has a bound version smaller than `S`.
`bitfield`="`true`" | "`false`"
: Specifies if this enumeration is a bitfield. Defaults to `"false"`.
### entry
Parent elements: enum
```
entry ::= description?
```
Defines a name for an integer constant and makes it part of the set of values of
the containing enumeration.
**Required attributes**
`name`="`cname-suffix`"
: The name of a value in an enumeration. The name must contain only the ASCII
characters a-z, A-Z, 0-9, or underscore. The name cannot be empty. The name
must be unique within all entry elements in the containing enum.
`value`="`V`"
: An integer value. The value can be given in decimal, hexadecimal, or octal
representation.
**Optional attributes**
`summary`="`summary`"
: A short (half a line at most) description. This attribute should not be used
if a description is used.
`since`="`S`"
: `S` must be an integer greater than zero. If `since` is not specified,
`since="1"` is assumed.
This value was added in interface `version` `S`.
`deprecated-since`="`D`"
: `D` must be an integer greater than the value of `since`. If
`deprecated-since` is not specified, then the value is not deprecated in any
version of the containing interface.
This value was removed in interface `version` `D`. This does not make the
value automatically illegal to use, see [arg](#arg) attribute `enum`.

View file

@ -1,371 +0,0 @@
# Wayland Protocol and Model of Operation
## Basic Principles
The Wayland protocol is an asynchronous object oriented protocol. All requests
are method invocations on some object. The requests include an object ID that
uniquely identifies an object on the server. Each object implements an interface
and the requests include an opcode that identifies which method in the interface
to invoke.
The protocol is message-based. A message sent by a client to the server is
called request. A message from the server to a client is called event. A message
has a number of arguments, each of which has a certain type (see [Wire
Format](#wire-format) for a list of argument types).
Additionally, the protocol can specify `enum`s which associate names to specific
numeric enumeration values. These are primarily just descriptive in nature: at
the wire format level enums are just integers. But they also serve a secondary
purpose to enhance type safety or otherwise add context for use in language
bindings or other such code. This latter usage is only supported so long as code
written before these attributes were introduced still works after; in other
words, adding an enum should not break API, otherwise it puts backwards
compatibility at risk.
`enum`s can be defined as just a set of integers, or as bitfields. This is
specified via the `bitfield` boolean attribute in the `enum` definition. If this
attribute is true, the enum is intended to be accessed primarily using bitwise
operations, for example when arbitrarily many choices of the enum can be ORed
together; if it is false, or the attribute is omitted, then the enum arguments
are a just a sequence of numerical values.
The `enum` attribute can be used on either `uint` or `int` arguments, however if
the `enum` is defined as a `bitfield`, it can only be used on `uint` args.
The server sends back events to the client, each event is emitted from an
object. Events can be error conditions. The event includes the object ID and the
event opcode, from which the client can determine the type of event. Events are
generated both in response to requests (in which case the request and the event
constitutes a round trip) or spontaneously when the server state changes.
- State is broadcast on connect, events are sent out when state changes. Clients
must listen for these changes and cache the state. There is no need (or
mechanism) to query server state.
- The server will broadcast the presence of a number of global objects, which in
turn will broadcast their current state.
## Code Generation
The interfaces, requests and events are defined in
[protocol/wayland.xml](https://gitlab.freedesktop.org/wayland/wayland/-/blob/main/protocol/wayland.xml).
This xml is used to generate the function prototypes that can be used by clients
and compositors.
The protocol entry points are generated as inline functions which just wrap the
`wl_proxy_*` functions. The inline functions aren't part of the library ABI and
language bindings should generate their own stubs for the protocol entry points
from the xml.
## Wire Format
The protocol is sent over a UNIX domain stream socket, where the endpoint
usually is named `wayland-0` (although it can be changed via _WAYLAND_DISPLAY_
in the environment). Beginning in Wayland 1.15, implementations can optionally
support server socket endpoints located at arbitrary locations in the filesystem
by setting _WAYLAND_DISPLAY_ to the absolute path at which the server endpoint
listens. The socket may also be provided through file descriptor inheritance, in
which case _WAYLAND_SOCKET_ is set.
Every message is structured as 32-bit words; values are represented in the
host's byte-order. The message header has 2 words in it:
- The first word is the sender's object ID (32-bit).
- The second has 2 parts of 16-bit. The upper 16-bits are the message size in
bytes, starting at the header (i.e. it has a minimum value of 8).The lower is
the request/event opcode.
The payload describes the request/event arguments. Every argument is always
aligned to 32-bits. Where padding is required, the value of padding bytes is
undefined. There is no prefix that describes the type, but it is inferred
implicitly from the xml specification.
The representation of argument types are as follows:
int
uint
: The value is the 32-bit value of the signed/unsigned int.
fixed
: Signed 24.8 decimal numbers. It is a signed decimal type which offers a sign
bit, 23 bits of integer precision and 8 bits of decimal precision. This is
exposed as an opaque struct with conversion helpers to and from double and
int on the C API side.
string
: 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.
object
: 32-bit object ID. A null value is represented with an ID of 0.
new_id
: The 32-bit object ID. Generally, the interface used for the new object is
inferred from the xml, but in the case where it's not specified, a new_id is
preceded by a `string` specifying the interface name, and a `uint`
specifying the version.
array
: Starts with 32-bit array size in bytes, followed by the array contents
verbatim, and finally padding to a 32-bit boundary.
fd
: The file descriptor is not stored in the message buffer, but in the
ancillary data of the UNIX domain socket message (msg_control).
The protocol does not specify the exact position of the ancillary data in the
stream, except that the order of file descriptors is the same as the order of
messages and `fd` arguments within messages on the wire.
In particular, it means that any byte of the stream, even the message header,
may carry the ancillary data with file descriptors.
Clients and compositors should queue incoming data until they have whole
messages to process, as file descriptors may arrive earlier or later than the
corresponding data bytes.
## Versioning
Every interface is versioned and every protocol object implements a particular
version of its interface. For global objects, the maximum version supported by
the server is advertised with the global and the actual version of the created
protocol object is determined by the version argument passed to
wl_registry.bind(). For objects that are not globals, their version is inferred
from the object that created them.
In order to keep things sane, this has a few implications for interface
versions:
- The object creation hierarchy must be a tree. Otherwise, inferring object
versions from the parent object becomes a much more difficult to properly
track.
- When the version of an interface increases, so does the version of its parent
(recursively until you get to a global interface)
- A global interface's version number acts like a counter for all of its child
interfaces. Whenever a child interface gets modified, the global parent's
interface version number also increases (see above). The child interface then
takes on the same version number as the new version of its parent global
interface.
To illustrate the above, consider the wl_compositor interface. It has two
children, wl_surface and wl_region. As of wayland version 1.2, wl_surface and
wl_compositor are both at version 3. If something is added to the wl_region
interface, both wl_region and wl_compositor will get bumpped to version 4. If,
afterwards, wl_surface is changed, both wl_compositor and wl_surface will be at
version 5. In this way the global interface version is used as a sort of
"counter" for all of its child interfaces. This makes it very simple to know the
version of the child given the version of its parent. The child is at the
highest possible interface version that is less than or equal to its parent's
version.
It is worth noting a particular exception to the above versioning scheme. The
wl_display (and, by extension, wl_registry) interface cannot change because it
is the core protocol object and its version is never advertised nor is there a
mechanism to request a different version.
## Connect Time
There is no fixed connection setup information, the server emits multiple events
at connect time, to indicate the presence and properties of global objects:
outputs, compositor, input devices.
## Security and Authentication
- mostly about access to underlying buffers, need new drm auth mechanism (the
grant-to ioctl idea), need to check the cmd stream?
- getting the server socket depends on the compositor type, could be a system
wide name, through fd passing on the session dbus. or the client is forked by
the compositor and the fd is already opened.
## Creating Objects
Each object has a unique ID. The IDs are allocated by the entity creating the
object (either client or server). IDs allocated by the client are in the range
[1, 0xfeffffff] while IDs allocated by the server are in the range [0xff000000,
0xffffffff]. The 0 ID is reserved to represent a null or non-existent object.
For efficiency purposes, the IDs are densely packed in the sense that the ID N
will not be used until N-1 has been used. This ordering is not merely a
guideline, but a strict requirement, and there are implementations of the
protocol that rigorously enforce this rule, including the ubiquitous libwayland.
## Compositor
The compositor is a global object, advertised at connect time.
See [wl_compositor](https://wayland.app/protocols/wayland#wl_compositor) for the
protocol description.
## Surfaces
A surface manages a rectangular grid of pixels that clients create for
displaying their content to the screen. Clients don't know the global position
of their surfaces, and cannot access other clients' surfaces.
Once the client has finished writing pixels, it 'commits' the buffer; this
permits the compositor to access the buffer and read the pixels. When the
compositor is finished, it releases the buffer back to the client.
See [wl_surface](https://wayland.app/protocols/wayland#wl_surface) for the
protocol description.
## Input
A seat represents a group of input devices including mice, keyboards and
touchscreens. It has a keyboard and pointer focus. Seats are global objects.
Pointer events are delivered in surface-local coordinates.
The compositor maintains an implicit grab when a button is pressed, to ensure
that the corresponding button release event gets delivered to the same surface.
But there is no way for clients to take an explicit grab. Instead, surfaces can
be mapped as 'popup', which combines transient window semantics with a pointer
grab.
To avoid race conditions, input events that are likely to trigger further
requests (such as button presses, key events, pointer motions) carry serial
numbers, and requests such as wl_surface.set_popup require that the serial
number of the triggering event is specified. The server maintains a
monotonically increasing counter for these serial numbers.
Input events also carry timestamps with millisecond granularity. Their base is
undefined, so they can't be compared against system time (as obtained with
clock_gettime or gettimeofday). They can be compared with each other though, and
for instance be used to identify sequences of button presses as double or triple
clicks.
See [wl_seat](https://wayland.app/protocols/wayland#wl_seat) for the protocol
description.
Talk about:
- keyboard map, change events
- xkb on Wayland
- multi pointer Wayland
A surface can change the pointer image when the surface is the pointer focus of
the input device. Wayland doesn't automatically change the pointer image when a
pointer enters a surface, but expects the application to set the cursor it wants
in response to the pointer focus and motion events. The rationale is that a
client has to manage changing pointer images for UI elements within the surface
in response to motion events anyway, so we'll make that the only mechanism for
setting or changing the pointer image. If the server receives a request to set
the pointer image after the surface loses pointer focus, the request is ignored.
To the client this will look like it successfully set the pointer image.
Setting the pointer image to NULL causes the cursor to be hidden.
The compositor will revert the pointer image back to a default image when no
surface has the pointer focus for that device.
What if the pointer moves from one window which has set a special pointer image
to a surface that doesn't set an image in response to the motion event? The new
surface will be stuck with the special pointer image. We can't just revert the
pointer image on leaving a surface, since if we immediately enter a surface that
sets a different image, the image will flicker. If a client does not set a
pointer image when the pointer enters a surface, the pointer stays with the
image set by the last surface that changed it, possibly even hidden. Such a
client is likely just broken.
## Output
An output is a global object, advertised at connect time or as it comes and
goes.
See [wl_output](https://wayland.app/protocols/wayland#wl_output) for the
protocol description.
- laid out in a big (compositor) coordinate system
- basically xrandr over Wayland
- geometry needs position in compositor coordinate system
- events to advertise available modes, requests to move and change modes
## Data sharing between clients
The Wayland protocol provides clients a mechanism for sharing data that allows
the implementation of copy-paste and drag-and-drop. The client providing the
data creates a `wl_data_source` object and the clients obtaining the data will
see it as `wl_data_offer` object. This interface allows the clients to agree on
a mutually supported mime type and transfer the data via a file descriptor that
is passed through the protocol.
The next section explains the negotiation between data source and data offer
objects. [Data devices](#data-devices) explains how these objects are created
and passed to different clients using the `wl_data_device` interface that
implements copy-paste and drag-and-drop support.
See [wl_data_offer](https://wayland.app/protocols/wayland#wl_data_offer),
[wl_data_source](https://wayland.app/protocols/wayland#wl_data_source),
[wl_data_device](https://wayland.app/protocols/wayland#wl_data_device) and
[wl_data_device_manager](https://wayland.app/protocols/wayland#wl_data_device_manager)
for protocol descriptions.
MIME is defined in RFC's 2045-2049. A [registry of MIME
types](https://www.iana.org/assignments/media-types/media-types.xhtml) is
maintained by the Internet Assigned Numbers Authority (IANA).
### Data negotiation
A client providing data to other clients will create a `wl_data_source` object
and advertise the mime types for the formats it supports for that data through
the `wl_data_source.offer` request. On the receiving end, the data offer object
will generate one `wl_data_offer.offer` event for each supported mime type.
The actual data transfer happens when the receiving client sends a
`wl_data_offer.receive` request. This request takes a mime type and a file
descriptor as arguments. This request will generate a `wl_data_source.send`
event on the sending client with the same arguments, and the latter client is
expected to write its data to the given file descriptor using the chosen mime
type.
### Data devices
Data devices glue data sources and offers together. A data device is associated
with a `wl_seat` and is obtained by the clients using the
`wl_data_device_manager` factory object, which is also responsible for creating
data sources.
Clients are informed of new data offers through the `wl_data_device.data_offer`
event. After this event is generated the data offer will advertise the available
mime types. New data offers are introduced prior to their use for copy-paste or
drag-and-drop.
#### Selection
Each data device has a selection data source. Clients create a data source
object using the device manager and may set it as the current selection for a
given data device. Whenever the current selection changes, the client with
keyboard focus receives a `wl_data_device.selection` event. This event is also
generated on a client immediately before it receives keyboard focus.
The data offer is introduced with `wl_data_device.data_offer` event before the
selection event.
#### Drag and Drop
A drag-and-drop operation is started using the `wl_data_device.start_drag`
request. This requests causes a pointer grab that will generate enter, motion
and leave events on the data device. A data source is supplied as argument to
start_drag, and data offers associated with it are supplied to clients surfaces
under the pointer in the `wl_data_device.enter` event. The data offer is
introduced to the client prior to the enter event with the
`wl_data_device.data_offer` event.
Clients are expected to provide feedback to the data sending client by calling
the `wl_data_offer.accept` request with a mime type it accepts. If none of the
advertised mime types is supported by the receiving client, it should supply
NULL to the accept request. The accept request causes the sending client to
receive a `wl_data_source.target` event with the chosen mime type.
When the drag ends, the receiving client receives a `wl_data_device.drop` event
at which it is expected to transfer the data using the `wl_data_offer.receive`
request.

View file

@ -1,12 +0,0 @@
# Summary
[Foreword](Foreword.md)
- [Introduction](./Introduction.md)
- [Types of Compositors](./Compositors.md)
- [Wayland Architecture](./Architecture.md)
- [Wayland Protocol and Model of Operation](./Protocol.md)
- [Message Definition Language](./Message_XML.md)
- [X11 Application Support](./Xwayland.md)
- [Content Updates](./Content_Updates.md)
- [Color management](./Color.md)

View file

@ -1,120 +0,0 @@
# X11 Application Support
## Introduction
Being able to run existing X11 applications is crucial for the adoption of
Wayland, especially on desktops, as there will always be X11 applications that
have not been or cannot be converted into Wayland applications, and throwing
them all away would be prohibitive. Therefore a Wayland compositor often needs
to support running X11 applications.
X11 and Wayland are different enough that there is no "simple" way to translate
between them. Most of X11 is uninteresting to a Wayland compositor. That,
combined with the gigantic implementation effort needed to support X11, makes it
intractable to just write X11 support directly in a Wayland compositor. The
implementation would be nothing short of a real X11 server.
Therefore, Wayland compositors should use Xwayland, the X11 server that lives in
the Xorg server source code repository and shares most of the implementation
with the Xorg server. Xwayland is a complete X11 server, just like Xorg is, but
instead of driving the displays and opening input devices, it acts as a Wayland
client. The rest of this chapter talks about how Xwayland works.
For integration and architecture reasons, while Xwayland is a Wayland client of
the Wayland compositor, the Wayland compositor is an X11 client of Xwayland.
This circular dependency requires special care from the Wayland compositor.
## Two Modes for Foreign Windows
In general, windows from a foreign window system can be presented in one of two
ways: rootless and rootful (not rootless).
In rootful mode, the foreign window system as a whole is represented as a window
(or more) of its own. You have a native window, inside which all the foreign
windows are. The advantage of this approach in Xwayland's case is that you can
run your favourite X11 window manager to manage your X11 applications. The
disadvantage is that the foreign windows do not integrate with the native
desktop. Therefore this mode is not usually used.
In rootless mode, each foreign window is a first-class resident among the native
windows. Foreign windows are not confined inside a native window but act as if
they were native windows. The advantage is that one can freely stack and mix
native and foreign windows, which is not possible in rootful mode. The
disadvantage is that this mode is harder to implement and fundamental
differences in window systems may prevent some things from working. With
rootless Xwayland, the Wayland compositor must take the role as the X11 window
manager, and one cannot use any other X11 window manager in its place.
This chapter concentrates on the rootless mode, and ignores the rootful mode.
## Architecture
A Wayland compositor usually takes care of launching Xwayland. Xwayland works in
cooperation with a Wayland compositor as follows:
**Xwayland architecture diagram**
![](images/xwayland-architecture.png)
An X11 application connects to Xwayland just like it would connect to any X
server. Xwayland processes all the X11 requests. On the other end, Xwayland is a
Wayland client that connects to the Wayland compositor.
The X11 window manager (XWM) is an integral part of the Wayland compositor. XWM
uses the usual X11 window management protocol to manage all X11 windows in
Xwayland. Most importantly, XWM acts as a bridge between Xwayland window state
and the Wayland compositor's window manager (WWM). This way WWM can manage all
windows, both native Wayland and X11 (Xwayland) windows. This is very important
for a coherent user experience.
Since Xwayland uses Wayland for input and output, it does not have any use for
the device drivers that Xorg uses. None of the xf86-video-* or xf86-input-*
modules are used. There also is no configuration file for the Xwayland server.
For optional hardware accelerated rendering, Xwayland uses GLAMOR.
A Wayland compositor usually spawns only one Xwayland instance. This is because
many X11 applications assume they can communicate with other X11 applications
through the X server, and this requires a shared X server instance. This also
means that Xwayland does not protect nor isolate X11 clients from each other,
unless the Wayland compositor specifically chooses to break the X11 client
intercommunications by spawning application specific Xwayland instances. X11
clients are naturally isolated from Wayland clients.
Xwayland compatibility compared to a native X server will probably never reach
100%. Desktop environment (DE) components, specifically X11 window managers, are
practically never supported. An X11 window manager would not know about native
Wayland windows, so it could manage only X11 windows. On the other hand, there
must be an XWM that reserves the exclusive window manager role so that the
Wayland compositor could show the X11 windows appropriately. For other DE
components, like pagers and panels, adding the necessary interfaces to support
them in WWM through XWM is often considered not worthwhile.
## X Window Manager (XWM)
From the X11 point of view, the X window manager (XWM) living inside a Wayland
compositor is just like any other window manager. The difference is mostly in
which process it resides in, and the few extra conventions in the X11 protocol
to support Wayland window management (WWM) specifically.
There are two separate asynchronous communication channels between Xwayland and
a Wayland compositor: one uses the Wayland protocol, and the other one, solely
for XWM, uses X11 protocol. This setting demands great care from the XWM
implementation to avoid (random) deadlocks with Xwayland. It is often nearly
impossible to prove that synchronous or blocking X11 calls from XWM cannot cause
a deadlock, and therefore it is strongly recommended to make all X11
communications asynchronous. All Wayland communications are already asynchronous
by design.
### Window identification
In Xwayland, an X11 window may have a corresponding wl_surface object in
Wayland. The wl_surface object is used for input and output: it is referenced by
input events and used to provide the X11 window content to the Wayland
compositor. The X11 window and the wl_surface live in different protocol
streams, and they need to be matched for XWM to do its job.
When Xwayland creates a wl_surface on Wayland, it will also send an X11
ClientMessage of type atom "WL_SURFACE_ID" to the X11 window carrying the
wl_surface Wayland object ID as the first 32-bit data element. This is how XWM
can associate a wl_surface with an X11 window. Note that the request to create a
wl_surface and the ID message may arrive in any order in the Wayland compositor.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

View file

@ -1,3 +1,2 @@
doxygen_sqlite3.db
html/
wayland.doxygen
xml/

53
doc/doxygen/Makefile.am Normal file
View file

@ -0,0 +1,53 @@
noinst_DATA = xml/client/index.xml xml/server/index.xml
dist_noinst_DATA = wayland.doxygen.in
scanned_src_files_shared = \
$(top_srcdir)/src/wayland-util.c \
$(top_srcdir)/src/wayland-util.h
scanned_src_files_client = \
$(scanned_src_files_shared) \
$(top_srcdir)/src/wayland-client.c \
$(top_srcdir)/src/wayland-client.h
scanned_src_files_server = \
$(scanned_src_files_shared) \
$(top_srcdir)/src/wayland-server.c \
$(top_srcdir)/src/wayland-server.h \
$(top_srcdir)/src/wayland-shm.c
# find all man/man3/wl_foo.3 pages
# for this to work, we need to create them before the man target (hence
# all-local below)
dist_man3_MANS = $(shell test -d man && find man/man3 -name "wl_*.3" -printf "man/man3/%P\n")
xml/client/index.xml: $(scanned_src_files_client) wayland.doxygen
$(AM_V_GEN)$(MKDIR_P) xml/client && \
(cat wayland.doxygen; \
echo "GENERATE_XML=YES"; \
echo "XML_OUTPUT=xml/client"; \
echo "INPUT= $(scanned_src_files_client)"; \
) | doxygen -
xml/server/index.xml: $(scanned_src_files_server) wayland.doxygen
$(AM_V_GEN)$(MKDIR_P) xml/server && \
(cat wayland.doxygen; \
echo "GENERATE_XML=YES"; \
echo "XML_OUTPUT=xml/server"; \
echo "INPUT= $(scanned_src_files_server)"; \
) | doxygen -
man/man3/wl_display.3: $(scanned_src_files_client) $(scanned_src_files_server)
$(AM_V_GEN)(cat wayland.doxygen; \
echo "GENERATE_MAN=YES"; \
echo "MAN_OUTPUT=man"; \
echo "JAVADOC_AUTOBRIEF=NO"; \
echo "INPUT= $^"; \
) | doxygen -
# there is no man-local
all-local: man/man3/wl_display.3
clean-local:
rm -rf xml/
rm -rf man/

View file

@ -1,105 +0,0 @@
#!/usr/bin/env python3
import argparse
import datetime
import errno
import os
import subprocess
import sys
# Custom configuration for each documentation format
doxygen_templates = {
'xml': [
'GENERATE_XML=YES\n',
'XML_OUTPUT={format}/{section}\n',
'INPUT= {files}\n',
],
'html': [
'GENERATE_HTML=YES\n',
'HTML_OUTPUT={format}/{section}\n',
'PROJECT_NAME=\"Wayland {section} API\"\n',
'INPUT= {files}\n',
],
'man': [
'GENERATE_MAN=YES\n',
'MAN_OUTPUT={format}\n',
'MAN_SUBDIR=.\n',
'JAVADOC_AUTOBRIEF=NO\n',
'INPUT= {files}\n',
],
}
def load_doxygen_file(doxyfile):
with open(doxyfile, 'r') as f:
res = f.readlines()
return res
def get_template(outformat):
for (k,v) in doxygen_templates.items():
if outformat.startswith(k):
return v
def gen_doxygen_file(data, outformat, section, files):
for l in get_template(outformat):
data.append(l.format(format=outformat, section=section, files=' '.join(files)))
return data
parser = argparse.ArgumentParser(description='Generate docs with Doxygen')
parser.add_argument('doxygen_file',
help='The doxygen file to use')
parser.add_argument('files',
help='The list of files to parse',
metavar='FILES',
nargs='+')
parser.add_argument('--builddir',
help='The build directory',
metavar='DIR',
default='.')
parser.add_argument('--section',
help='The section to build',
metavar='NAME',
default='Client')
parser.add_argument('--output-format',
help='The output format: xml, html, man',
metavar='FORMAT',
default='xml')
parser.add_argument('--stamp',
help='Stamp file to output',
metavar='STAMP_FILE',
nargs='?',
type=argparse.FileType('w'))
args = parser.parse_args()
# Merge the doxyfile with our custom templates
conf = load_doxygen_file(args.doxygen_file)
conf = gen_doxygen_file(conf, args.output_format, args.section, args.files)
# Doxygen is not clever enough to create the directories it
# needs beforehand
try:
os.makedirs(os.path.join(args.builddir, args.output_format))
except OSError as e:
if e.errno != errno.EEXIST:
raise e
# Run Doxygen with the generated doxyfile
cmd = subprocess.Popen(['doxygen', '-'], stdin=subprocess.PIPE)
cmd.stdin.write(''.join(conf).encode('utf-8'))
cmd.stdin.close()
if cmd.wait() != 0:
sys.exit(1)
# This is a bit of a hack; Doxygen will generate way more files than we
# want to install, but there's no way to know how many at configuration
# time. Since we want to install only the wl_* man pages anyway, we can
# delete the other files and let Meson install the whole man3 subdirectory
if args.output_format.startswith('man'):
manpath = os.path.join(args.builddir, args.output_format)
for filename in os.listdir(manpath):
full_path = os.path.join(manpath, filename)
if not filename.startswith('wl_'):
os.remove(full_path)
if args.stamp:
args.stamp.write(str(datetime.datetime.now()))

View file

@ -1,23 +0,0 @@
/**
* @mainpage
* Wayland protocol API documentation.
*
* This documentation is available for the Server- and the Client-side APIs.
*
* - <a href="../Server/index.html">Server-side API</a>
* - <a href="../Client/index.html">Client-side API</a>
* - <a href="../Cursor/index.html">Cursor helper library API</a>
*
* Further documentation about the architecture and principles of Wayland is
* available on the
* <a href="https://wayland.freedesktop.org">website</a>.
*
* @section ifaces Interfaces
* For the list of available interfaces, please see the
* <a href="modules.html">modules</a> list.
*
* @section protocols Protocols
* For the list of protocols, please see the
* <a href="pages.html">Related Pages</a>.
*
*/

View file

@ -1,105 +0,0 @@
# Here be dragons
doxygen_conf = configuration_data()
doxygen_conf.set('VERSION', meson.project_version())
doxygen_conf.set('top_builddir', meson.project_build_root())
wayland_doxygen = configure_file(
input: 'wayland.doxygen.in',
output: 'wayland.doxygen',
configuration: doxygen_conf,
)
shared_files = files([
'../../src/wayland-util.h',
])
client_files = files([
'../../src/wayland-client.c',
'../../src/wayland-client.h',
'../../src/wayland-client-core.h',
])
server_files = files([
'../../src/event-loop.c',
'../../src/wayland-server.c',
'../../src/wayland-server.h',
'../../src/wayland-server-core.h',
'../../src/wayland-shm.c',
])
cursor_files = files([
'../../cursor/wayland-cursor.c',
'../../cursor/wayland-cursor.h',
])
extra_client_files = [
'mainpage.dox',
wayland_client_protocol_h,
]
extra_server_files = [
'mainpage.dox',
wayland_server_protocol_h,
]
extra_cursor_files = [
'mainpage.dox',
]
gen_doxygen = find_program('gen-doxygen.py')
subdir('xml')
formats = {
'html': {
'Client': shared_files + client_files + extra_client_files,
'Server': shared_files + server_files + extra_server_files,
'Cursor': shared_files + cursor_files + extra_cursor_files,
},
}
foreach f_name, sections: formats
foreach s_name, s_files: sections
t_name = '@0@-@1@-doc'.format(f_name, s_name)
# We do not really need an output file, but Meson
# will complain if one is not set, so we use a
# dummy 'stamp' file
stamp = join_paths(meson.current_build_dir(), '@0@.stamp'.format(t_name))
custom_target(
t_name,
command: [
gen_doxygen,
# XXX pass doxygen path as argument
'--builddir=@OUTDIR@',
'--section=@0@'.format(s_name),
'--output-format=@0@'.format(f_name),
'--stamp=@0@'.format(stamp),
wayland_doxygen,
'@INPUT@',
],
input: s_files,
output: '@0@.stamp'.format(t_name),
build_by_default: true,
)
endforeach
endforeach
man_files = shared_files + server_files + client_files + cursor_files
stamp = join_paths(meson.current_build_dir(), 'man3.stamp')
custom_target(
'man-pages-3',
command: [
gen_doxygen,
'--builddir=@OUTDIR@',
'--output-format=man3',
'--stamp=@0@'.format(stamp),
wayland_doxygen,
'@INPUT@',
],
input: man_files,
output: 'man3',
build_by_default: true,
install: true,
install_dir: join_paths(get_option('prefix'), get_option('mandir')),
)

File diff suppressed because it is too large Load diff

View file

@ -1,17 +0,0 @@
tgt = custom_target(
'xml-Client-doc',
command: [
gen_doxygen,
# XXX pass doxygen path as argument
'--builddir=@OUTDIR@',
'--section=Client',
'--output-format=xml',
wayland_doxygen,
'@INPUT@',
],
input: [ shared_files, client_files ],
output: [ 'combine.xslt', 'index.xml' ],
)
doxygen_Client_combine_xslt = tgt[0]
doxygen_Client_index_xml = tgt[1]

View file

@ -1,17 +0,0 @@
tgt = custom_target(
'xml-Server-doc',
command: [
gen_doxygen,
# XXX pass doxygen path as argument
'--builddir=@OUTDIR@',
'--section=Server',
'--output-format=xml',
wayland_doxygen,
'@INPUT@',
],
input: [ shared_files, server_files ],
output: [ 'combine.xslt', 'index.xml' ],
)
doxygen_Server_combine_xslt = tgt[0]
doxygen_Server_index_xml = tgt[1]

View file

@ -1,2 +0,0 @@
subdir('Client')
subdir('Server')

51
doc/man/Makefile.am Normal file
View file

@ -0,0 +1,51 @@
#
# This generates man-pages out of the Docbook XML files. Simply add your files
# to the $MANPAGES array. If aliases are created, please add them to the
# MANPAGES_ALIASES array so they get installed correctly.
#
MANPAGES = \
wl_display_connect.3
MANPAGES_ALIASES = \
wl_display_connect_to_fd.3
XML_FILES = \
${patsubst %.1,%.xml,${patsubst %.3,%.xml,${patsubst %.5,%.xml,${patsubst %.7,%.xml,$(MANPAGES)}}}}
CLEANFILES =
EXTRA_DIST = $(XML_FILES)
if HAVE_XSLTPROC
if HAVE_MANPAGES_STYLESHEET
CLEANFILES += $(MANPAGES) $(MANPAGES_ALIASES)
EXTRA_DIST += $(MANPAGES) $(MANPAGES_ALIASES)
dist_man_MANS = $(MANPAGES) $(MANPAGES_ALIASES)
XSLTPROC_FLAGS = \
--stringparam man.authors.section.enabled 0 \
--stringparam man.copyright.section.enabled 0 \
--stringparam funcsynopsis.style ansi \
--stringparam man.output.quietly 1 \
--nonet
XSLTPROC_PROCESS_MAN = \
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
$(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) $(MANPAGES_STYLESHEET) $< && \
$(SED) -i -e 's/^\.so \(.*\)\.\(.\)$$/\.so man\2\/\1\.\2/' $(MANPAGES_ALIASES)
%.1: %.xml
$(XSLTPROC_PROCESS_MAN)
%.3: %.xml
$(XSLTPROC_PROCESS_MAN)
%.5: %.xml
$(XSLTPROC_PROCESS_MAN)
%.7: %.xml
$(XSLTPROC_PROCESS_MAN)
wl_display_connect_to_fd.3: wl_display_connect.3
endif # HAVE_MANPAGES_STYLESHEET
endif # HAVE_XSLTPROC

View file

@ -0,0 +1,88 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
Written 2012 by David Herrmann <dh.herrmann@googlemail.com>
Dedicated to the Public Domain
-->
<refentry id="wl_display_connect">
<refentryinfo>
<title>wl_display_connect</title>
<productname>wayland-client</productname>
<date>September 2012</date>
<authorgroup>
<author>
<contrib>Developer</contrib>
<firstname>David</firstname>
<surname>Herrmann</surname>
<email>dh.herrmann@googlemail.com</email>
</author>
</authorgroup>
</refentryinfo>
<refmeta>
<refentrytitle>wl_display_connect</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname>wl_display_connect</refname>
<refname>wl_display_connect_to_fd</refname>
<refpurpose>Connect to a Wayland socket</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;wayland-client.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>struct wl_display *<function>wl_display_connect</function></funcdef>
<paramdef>const char *<parameter>name</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>struct wl_display *<function>wl_display_connect_to_fd</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><function>wl_display_connect</function> connects to a Wayland socket
that was previously opened by a Wayland server. The server socket must
be placed in <envar>XDG_RUNTIME_DIR</envar> for this function to
find it. The <varname>name</varname> argument specifies the name of
the socket or <constant>NULL</constant> to use the default (which is
<constant>"wayland-0"</constant>). The environment variable
<envar>WAYLAND_DISPLAY</envar> replaces the default value. If
<envar>WAYLAND_SOCKET</envar> is set, this function behaves like
<function>wl_display_connect_to_fd</function> with the file-descriptor
number taken from the environment variable.</para>
<para><function>wl_display_connect_to_fd</function> connects to a Wayland
socket with an explicit file-descriptor. The file-descriptor is passed
as argument <varname>fd</varname>.</para>
</refsect1>
<refsect1>
<title>Return Value</title>
<para><function>wl_display_connect</function> and
<function>wl_display_connect_to_fd</function> return a new display
context object or NULL on failure. <varname>errno</varname> is set
correspondingly.</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>wayland-client</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>wl_display_disconnect</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>wl_display_iterate</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>

View file

@ -1,43 +0,0 @@
if not get_option('libraries')
error('-Ddocumentation=true requires -Dlibraries=true')
endif
dot = find_program('dot')
doxygen = find_program('doxygen')
xsltproc = find_program('xsltproc')
xmlto = find_program('xmlto')
mdbook = find_program('mdbook')
cmd = run_command(doxygen, '--version', check: true)
message('doxygen: ' + cmd.stdout().strip())
vers = cmd.stdout().strip()
if vers.version_compare('< 1.6.0')
error('Doxygen 1.6 or later is required for building documentation, found @0@.'.format(vers))
endif
cmd = run_command(dot, '-V', check: true)
message('dot: ' + cmd.stderr().strip())
vers = cmd.stderr().split('version')[1].strip().split(' ')[0]
if vers.version_compare('< 2.26.0')
error('Dot (Graphviz) 2.26 or later is required for building documentation, found @0@.'.format(vers))
endif
manpage_xsl = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl'
cmd = run_command(xsltproc, '--nonet', manpage_xsl, check: false)
if cmd.returncode() != 0
error('The style sheet for man pages providing "@0@" was not found.'.format(manpage_xsl))
endif
publican_install_prefix = join_paths(
get_option('prefix'),
get_option('datadir'),
'doc',
meson.project_name(),
'Wayland', 'en-US'
)
publican_html_dir = 'html'
subdir('doxygen')
subdir('publican')
subdir('book')

View file

@ -1,92 +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">
<!ENTITY doxygen SYSTEM "ClientAPI.xml">
%BOOK_ENTITIES;
]>
<appendix id="sect-Library-Client">
<title>Client API</title>
<section><title>Introduction</title>
<para>
The open-source reference implementation of Wayland protocol is
split in two C libraries, libwayland-client and <link
linkend="sect-Library-Server">libwayland-server</link>. Their main
responsibility is to handle the Inter-process communication
(<emphasis>IPC</emphasis>) with each other, therefore guaranteeing
the protocol objects marshaling and messages synchronization.
</para>
<para>
A client uses libwayland-client to communicate with one or more
wayland servers. A <link
linkend="Client-classwl__display">wl_display</link> object is
created and manages each open connection to a server. At least one
<link linkend="Client-classwl__event__queue">wl_event_queue</link>
object is created for each wl_display, this holds events as they
are received from the server until they can be
processed. Multi-threading is supported by creating an additional
wl_event_queue for each additional thread, each object can have
its events placed in a particular queue, so potentially a
different thread could be made to handle the events for each
object created.
</para>
<para>
Though some convenience functions are provided, libwayland-client
is designed to allow the calling code to wait for events, so that
different polling mechanisms can be used. A file descriptor is
provided, when it becomes ready for reading the calling code can
ask libwayland-client to read the available events from it into
the wl_event_queue objects.
</para>
<para>
The library only provides low-level access to the wayland objects.
Each object created by the client is represented by a <link
linkend="Client-classwl__proxy">wl_proxy</link> object that this
library creates. This includes the id that is actually
communicated over the socket to the server, a void* data pointer
that is intended to point at a client's representation of the
object, and a pointer to a static <link
linkend="Client-structwl__interface">wl_interface</link> object,
which is generated from the xml and identifies the object's class
and can be used for introspection into the messages and events.
</para>
<para>
Messages are sent by calling wl_proxy_marshal. This will write a
message to the socket, by using the message id and the
wl_interface to identify the types of each argument and convert
them into stream format. Most software will call type-safe
wrappers generated from the xml description of the <link
linkend="appe-Wayland-Protocol">Wayland protocols</link>. For
instance the C header file generated from the xml defines the
following inline function to transmit the <link
linkend="protocol-spec-wl_surface-request-attach">wl_surface::attach</link>
message:
</para>
<programlisting>static inline void
wl_surface_attach(struct wl_surface *wl_surface, struct wl_buffer *buffer, int32_t x, int32_t y)
{
wl_proxy_marshal((struct wl_proxy *) wl_surface, WL_SURFACE_ATTACH, buffer, x, y);
}</programlisting>
<para>
Events (messages from the server) are handled by calling a
"dispatcher" callback the client stores in the wl_proxy for each
event. A language binding for a string-based interpreter, such as
CPython, might have a dispatcher that uses the event name from the
wl_interface to identify the function to call. The default
dispatcher uses the message id number to index an array of
functions pointers, called a wl_listener, and the wl_interface to
convert data from the stream into arguments to the function. The
C header file generated from the xml defines a per-class structure
that forces the function pointers to be of the correct type, for
instance the <link
linkend="protocol-spec-wl_surface-event-enter">wl_surface::enter</link>
event defines this pointer in the wl_surface_listener object:
</para>
<programlisting>struct wl_surface_listener {
void (*enter)(void *data, struct wl_surface *, struct wl_output *);
...
}</programlisting>
<para>
</para>
</section>
&doxygen;
</appendix>

135
doc/publican/Makefile.am Normal file
View file

@ -0,0 +1,135 @@
# Documentation is built with publican
# https://fedorahosted.org/publican/
# Publican takes docbook-style input files and compiles them to various
# output formats.
#
# How this build works:
# * the main target is Wayland, documentation ends up in $(builddir)/Wayland/
# * hand-written chapters are located in sources
# Publican does not take a source path, so to support out-of-tree builds
# these are copied to $(builddir)/en-US which is the actual directory
# Publican uses.
# * ProtocolSpec.xml is generated from $(top_srcdir)/protocol/wayland.xml,
# changed into docbook via XSLT and saved in $(builddir)/en-US/
# * ProtocolInterfaces.xml, same as above, uses a different XSLT
# * WaylandClientAPI.xml is generated from the doxygen output and saved in
# $(builddir)/en-US
# * WaylandServerAPI.xml is generated from the doxygen output and saved in
# $(builddir)/en-US
# * run Publican on en-US
publican_sources = \
$(srcdir)/sources/Wayland.ent \
$(srcdir)/sources/Wayland.xml \
$(srcdir)/sources/Book_Info.xml \
$(srcdir)/sources/Author_Group.xml \
$(srcdir)/sources/Foreword.xml \
$(srcdir)/sources/Preface.xml \
$(srcdir)/sources/Revision_History.xml \
$(srcdir)/sources/Introduction.xml \
$(srcdir)/sources/Architecture.xml \
$(srcdir)/sources/Protocol.xml \
$(srcdir)/sources/Library.xml \
$(srcdir)/sources/Compositors.xml \
$(srcdir)/sources/images/icon.svg \
$(srcdir)/sources/images/wayland-architecture.png \
$(srcdir)/sources/images/wayland.png \
$(srcdir)/sources/images/x-architecture.png
if HAVE_PUBLICAN
if HAVE_XSLTPROC
noinst_DATA = Wayland $(publican_targets)
pubdir = $(docdir)/Wayland/en-US
publican_targets = $(publican_sources:$(srcdir)/sources%=$(builddir)/en-US%) \
en-US/ProtocolSpec.xml en-US/ProtocolInterfaces.xml \
en-US/WaylandClientAPI.xml en-US/WaylandServerAPI.xml
# The Protocol.xml is purely generated and required before running publican
en-US/ProtocolSpec.xml: $(top_srcdir)/protocol/wayland.xml $(srcdir)/protocol-to-docbook.xsl
$(AM_V_GEN)$(MKDIR_P) en-US/images
$(AM_V_GEN)$(XSLTPROC) $(srcdir)/protocol-to-docbook.xsl \
$(top_srcdir)/protocol/wayland.xml > en-US/ProtocolSpec.xml
en-US/ProtocolInterfaces.xml: $(top_srcdir)/protocol/wayland.xml $(srcdir)/protocol-interfaces-to-docbook.xsl
$(AM_V_GEN)$(MKDIR_P) en-US/images
$(AM_V_GEN)$(XSLTPROC) $(srcdir)/protocol-interfaces-to-docbook.xsl \
$(top_srcdir)/protocol/wayland.xml > en-US/ProtocolInterfaces.xml
# * we don't want wayland-{server|client}_8h.xml to avoid duplicating output methods,
# move it out of the way first.
# * use doxygen's combine.xslt to merge the xml files into one single file
# * move wayland-<foo>_8h.xml back to its original location
en-US/%API.xml.tmp:
$(AM_V_GEN)mv $(top_builddir)/doc/doxygen/xml/$*/wayland-$*_8h.xml \
$(top_builddir)/doc/doxygen/xml/
$(AM_V_GEN)$(XSLTPROC) $(top_builddir)/doc/doxygen/xml/$*/combine.xslt \
$(top_builddir)/doc/doxygen/xml/$*/index.xml > $@
$(AM_V_GEN)mv $(top_builddir)/doc/doxygen/xml/wayland-$*_8h.xml \
$(top_builddir)/doc/doxygen/xml/$*
# WaylandClientAPI.xml:
# merge doxygen xml files into one single file, then transform the combined XML file into docbook format
en-US/WaylandClientAPI.xml: en-US/clientAPI.xml.tmp $(top_builddir)/doc/doxygen/xml/client/index.xml $(srcdir)/doxygen-to-publican.xsl
$(AM_V_GEN)$(XSLTPROC) --stringparam which Client $(srcdir)/doxygen-to-publican.xsl \
$(builddir)/en-US/clientAPI.xml.tmp > en-US/WaylandClientAPI.xml
# WaylandServerAPI.xml: see WaylandClientAPI.xml
en-US/WaylandServerAPI.xml: en-US/serverAPI.xml.tmp $(top_builddir)/doc/doxygen/xml/client/index.xml $(srcdir)/doxygen-to-publican.xsl
$(AM_V_GEN)$(XSLTPROC) --stringparam which Server $(srcdir)/doxygen-to-publican.xsl \
$(builddir)/en-US/serverAPI.xml.tmp > en-US/WaylandServerAPI.xml
# Copy the sources source files into en-US destination
# This is required for out-of-source-tree build as publican does not allow us
# to specify the location of the source code.
$(builddir)/en-US/%: $(srcdir)/sources/% en-US/ProtocolSpec.xml en-US/ProtocolInterfaces.xml en-US/WaylandClientAPI.xml $(publican_sources)
$(AM_V_GEN)cp -f $< $@
$(AM_V_GEN)chmod a+w $@
# Run publican for the builddir on the generated (or copied) source
# The output formats are generated in the Wayland sub directory. Also, we need
# to use a tmp publican.cfg cause 'publican rename' modifies the original.
Wayland: $(publican_targets)
$(AM_V_GEN)cp -f $(srcdir)/publican.cfg $(builddir)/publican-copy.cfg
$(AM_V_GEN)$(PUBLICAN) rename --name Wayland \
--version "$(WAYLAND_VERSION_MAJOR).$(WAYLAND_VERSION_MINOR)" \
--config $(builddir)/publican-copy.cfg
$(AM_V_GEN)$(PUBLICAN) build --quiet --langs en-US --pdftool fop --formats html,pdf \
--config $(builddir)/publican-copy.cfg
@touch Wayland
CLEANFILES = en-US/ProtocolSpec.xml en-US/ProtocolInterfaces.xml en-US/WaylandClientAPI.xml $(publican_targets)
clean-local:
$(AM_V_at)rm -fr $(builddir)/en-US
$(AM_V_at)rm -fr $(builddir)/Wayland
$(AM_V_at)rm -fr $(builddir)/publican-copy.cfg
install-data-local:
test -z "$(pubdir)/html/Common_Content/css" || $(mkdir_p) "$(DESTDIR)$(pubdir)/html/Common_Content/css"
test -z "$(pubdir)/html/Common_Content/images" || $(mkdir_p) "$(DESTDIR)$(pubdir)/html/Common_Content/images"
test -z "$(pubdir)/html/images" || $(mkdir_p) "$(DESTDIR)$(pubdir)/html/images"
test -z "$(pubdir)/html-pdf/Common_Content/css" || $(mkdir_p) "$(DESTDIR)$(pubdir)/html-pdf/Common_Content/css"
test -z "$(pubdir)/html-pdf/Common_Content/images" || $(mkdir_p) "$(DESTDIR)$(pubdir)/html-pdf/Common_Content/images"
test -z "$(pubdir)/html-pdf/images" || $(mkdir_p) "$(DESTDIR)$(pubdir)/html-pdf/images"
test -z "$(pubdir)/pdf" || $(mkdir_p) "$(DESTDIR)$(pubdir)/pdf"
test -z "$(pubdir)/xml/Common_Content/css" || $(mkdir_p) "$(DESTDIR)$(pubdir)/xml/Common_Content/css"
test -z "$(pubdir)/xml/Common_Content/images" || $(mkdir_p) "$(DESTDIR)$(pubdir)/xml/Common_Content/images"
test -z "$(pubdir)/xml/images" || $(mkdir_p) "$(DESTDIR)$(pubdir)/xml/images"
list=`find $(builddir)/Wayland/en-US -type f -not -path '$(builddir)/Wayland/en-US/xml_tmp*'`; \
for p in $$list; do \
echo " $(INSTALL_DATA) '$$p' '$(DESTDIR)$(docdir)/$$p'"; \
$(INSTALL_DATA) "$$p" "$(DESTDIR)$(docdir)/$$p"; \
done;
uninstall-local:
@if test -n $(DESTDIR)$(docdir); then \
if test -d $(DESTDIR)$(docdir); then \
echo " rm -fr $(DESTDIR)$(docdir)/Wayland;"; \
rm -fr $(DESTDIR)$(docdir)/Wayland; \
fi; \
fi;
endif
endif
EXTRA_DIST = $(publican_sources) publican.cfg protocol-to-docbook.xsl protocol-interfaces-to-docbook.xsl doxygen-to-publican.xsl

View file

@ -1,49 +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">
<!ENTITY doxygen SYSTEM "ServerAPI.xml">
%BOOK_ENTITIES;
]>
<appendix id="sect-Library-Server">
<title>Server API</title>
<section><title>Introduction</title>
<para>
The open-source reference implementation of Wayland protocol is
split in two C libraries, <link
linkend="sect-Library-Client">libwayland-client</link> and
libwayland-server. Their main responsibility is to handle the
Inter-process communication (<emphasis>IPC</emphasis>) with each
other, therefore guaranteeing the protocol objects marshaling and
messages synchronization.
</para>
<para>
The server library is designed to work much like libwayland-client,
although it is considerably complicated due to the server needing
to support multiple versions of the protocol. It is best to learn
libwayland-client first.
</para>
<para>
Each open socket to a client is represented by a <link
linkend="Server-structwl__client">wl_client</link>. The equivalent
of the <link linkend="Client-classwl__proxy">wl_proxy</link> that
libwayland-client uses to represent an object is <link
linkend="Server-structwl__resource">wl_resource</link> for
client-created objects, and <link
linkend="Server-structwl__global">wl_global</link> for objects
created by the server.
</para>
<para>
Often a server is also a client for another Wayland server, and
thus must link with both libwayland-client and libwayland-server.
This produces some type name conflicts (such as the <link
linkend="Client-classwl__display">client wl_display</link> and
<link linkend="Server-structwl__display">server wl_display</link>,
but the duplicate-but-not-the-same types are opaque, and accessed
only inside the correct library where it came from. Naturally that
means that the program writer needs to always know if a pointer to
a wl_display is for the server or client side and use the
corresponding functions.
</para>
</section>
&doxygen;
</appendix>

View file

@ -1,12 +0,0 @@
<?xml version='1.0' encoding='utf-8' ?>
<!DOCTYPE book 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;
]>
<book>
<xi:include href="Book_Info.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="Foreword.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"/>
</book>

View file

@ -0,0 +1,166 @@
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:param name="which" />
<xsl:template match="/">
<!-- insert docbook's DOCTYPE blurb -->
<xsl:text disable-output-escaping = "yes"><![CDATA[
<!DOCTYPE appendix 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;
]>
]]></xsl:text>
<section id="sect-Library-$which">
<xsl:attribute name="id">sect-Library-<xsl:value-of select="$which"/></xsl:attribute>
<title><xsl:value-of select="$which"/> API</title>
<para>Following is the Wayland library classes for the <xsl:value-of select="$which"/>
(<emphasis>libwayland-<xsl:value-of select="translate($which, 'SC', 'sc')"/></emphasis>).
Note that most of the procedures are related with IPC, which is the main responsibility of
the library.
</para>
<xsl:if test="/doxygen/compounddef[@kind='class']">
<para>
<variablelist>
<xsl:apply-templates select="/doxygen/compounddef" />
</variablelist>
</para>
</xsl:if>
<para>Methods for the respective classes.</para>
<para>
<variablelist>
<xsl:apply-templates select="/doxygen/compounddef/sectiondef/memberdef" />
</variablelist>
</para>
</section>
</xsl:template>
<xsl:template match="parameteritem">
<varlistentry>
<term>
<xsl:value-of select="parameternamelist/parametername"/>
</term>
<listitem>
<para>
<xsl:value-of select="parameterdescription/para"/>
</para>
</listitem>
</varlistentry>
</xsl:template>
<xsl:template match="parameterlist">
<xsl:if test="parameteritem">
<variablelist>
<xsl:apply-templates select="parameteritem" />
</variablelist>
</xsl:if>
</xsl:template>
<xsl:template match="ref">
<emphasis><xsl:value-of select="." /></emphasis>
</xsl:template>
<xsl:template match="simplesect[@kind='return']">
<variablelist>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
<xsl:value-of select="." />
</para>
</listitem>
</varlistentry>
</variablelist>
</xsl:template>
<xsl:template match="simplesect[@kind='see']">
<itemizedlist>
<listitem>
<para>
See also:
<xsl:for-each select="para/ref">
<emphasis><xsl:value-of select="."/><xsl:text> </xsl:text></emphasis>
</xsl:for-each>
</para>
</listitem>
</itemizedlist>
</xsl:template>
<xsl:template match="simplesect[@kind='since']">
<itemizedlist>
<listitem>
<para>
Since: <xsl:value-of select="para"/>
</para>
</listitem>
</itemizedlist>
</xsl:template>
<xsl:template match="simplesect[@kind='note']">
<emphasis>Note: <xsl:value-of select="."/></emphasis>
</xsl:template>
<xsl:template match="programlisting">
<programlisting><xsl:value-of select="."/></programlisting>
</xsl:template>
<!-- this opens a para for each detaileddescription/para. I could not find a
way to extract the right text for the description from the
source otherwise. Downside: we can't use para for return value, "see
also", etc. because they're already inside a para. So they're lists.
It also means we don't control the order of when something is added to
the output, it matches the input file
-->
<xsl:template match="detaileddescription/para">
<para><xsl:apply-templates /></para>
</xsl:template>
<xsl:template match="detaileddescription">
<xsl:apply-templates select="para" />
</xsl:template>
<!-- methods -->
<xsl:template match="memberdef" >
<xsl:if test="@kind = 'function' and @static = 'no'">
<varlistentry>
<term>
<xsl:value-of select="name"/>
- <xsl:value-of select="briefdescription" />
</term>
<listitem>
<para>
<synopsis>
<xsl:value-of select="definition"/><xsl:value-of select="argsstring"/>
</synopsis>
</para>
<xsl:apply-templates select="detaileddescription" />
</listitem>
</varlistentry>
</xsl:if>
</xsl:template>
<!-- classes -->
<xsl:template match="compounddef" >
<xsl:if test="@kind = 'class' ">
<varlistentry>
<term>
<xsl:value-of select="compoundname" />
<xsl:if test="briefdescription">
- <xsl:value-of select="briefdescription" />
</xsl:if>
</term>
<listitem>
<xsl:for-each select="detaileddescription/para">
<para><xsl:value-of select="." /></para>
</xsl:for-each>
</listitem>
</varlistentry>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

File diff suppressed because it is too large Load diff

View file

@ -1,3 +0,0 @@
@import url("common.css");
@import url("overrides.css");
@import url("lang.css");

View file

@ -1,11 +0,0 @@
foreach src : files([
'common.css',
'default.css',
])
name = fs.name(src)
publican_inputs += fs.copyfile(
name,
install: true,
install_dir: publican_install_prefix + '/html/css',
)
endforeach

View file

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0" width="32" height="32" id="svg3017">
<defs id="defs3019">
<linearGradient id="linearGradient2381">
<stop id="stop2383" style="stop-color:#ffffff;stop-opacity:1" offset="0"/>
<stop id="stop2385" style="stop-color:#ffffff;stop-opacity:0" offset="1"/>
</linearGradient>
<linearGradient x1="296.4996" y1="188.81061" x2="317.32471" y2="209.69398" id="linearGradient2371" xlink:href="#linearGradient2381" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.90776,0,0,0.90776,24.35648,49.24131)"/>
</defs>
<g transform="matrix(0.437808,-0.437808,0.437808,0.437808,-220.8237,43.55311)" id="g5089">
<path d="m 8.4382985,-6.28125 c -0.6073916,0 -4.3132985,5.94886271 -4.3132985,8.25 l 0,26.71875 c 0,0.846384 0.5818159,1.125 1.15625,1.125 l 25.5625,0 c 0.632342,0 1.125001,-0.492658 1.125,-1.125 l 0,-5.21875 0.28125,0 c 0.49684,0 0.906249,-0.409411 0.90625,-0.90625 l 0,-27.9375 c 0,-0.4968398 -0.40941,-0.90625 -0.90625,-0.90625 l -23.8117015,0 z" transform="translate(282.8327,227.1903)" id="path5091" style="fill:#5c5c4f;stroke:#000000;stroke-width:3.23021388;stroke-miterlimit:4;stroke-dasharray:none"/>
<rect width="27.85074" height="29.369793" rx="1.1414107" ry="1.1414107" x="286.96509" y="227.63805" id="rect5093" style="fill:#032c87"/>
<path d="m 288.43262,225.43675 25.2418,0 0,29.3698 -26.37615,0.0241 1.13435,-29.39394 z" id="rect5095" style="fill:#ffffff"/>
<path d="m 302.44536,251.73726 c 1.38691,7.85917 -0.69311,11.28365 -0.69311,11.28365 2.24384,-1.60762 3.96426,-3.47694 4.90522,-5.736 0.96708,2.19264 1.83294,4.42866 4.27443,5.98941 0,0 -1.59504,-7.2004 -1.71143,-11.53706 l -6.77511,0 z" id="path5097" style="fill:#a70000;fill-opacity:1;stroke-width:2"/>
<rect width="25.241802" height="29.736675" rx="0.89682275" ry="0.89682275" x="290.73544" y="220.92249" id="rect5099" style="fill:#809cc9"/>
<path d="m 576.47347,725.93939 6.37084,0.41502 0.4069,29.51809 c -1.89202,-1.31785 -6.85427,-3.7608 -8.26232,-1.68101 l 0,-26.76752 c 0,-0.82246 0.66212,-1.48458 1.48458,-1.48458 z" transform="matrix(0.499065,-0.866565,0,1,0,0)" id="rect5101" style="fill:#4573b3;fill-opacity:1"/>
<path d="m 293.2599,221.89363 20.73918,0 c 0.45101,0 0.8141,0.3631 0.8141,0.81411 0.21547,6.32836 -19.36824,21.7635 -22.36739,17.59717 l 0,-17.59717 c 0,-0.45101 0.3631,-0.81411 0.81411,-0.81411 z" id="path5103" style="opacity:0.65536726;fill:url(#linearGradient2371);fill-opacity:1"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -1,11 +0,0 @@
foreach src : files([
'icon.svg',
'wayland.png',
])
name = fs.name(src)
publican_inputs += fs.copyfile(
name,
install: true,
install_dir: publican_install_prefix + '/html/images',
)
endforeach

Some files were not shown because too many files have changed in this diff Show more