pax_global_header 0000666 0000000 0000000 00000000064 14536573575 0014536 g ustar 00root root 0000000 0000000 52 comment=111dc970660e08654ec9532ac22ba62efedf204a
wlcs-1.7.0/ 0000775 0000000 0000000 00000000000 14536573575 0012513 5 ustar 00root root 0000000 0000000 wlcs-1.7.0/.github/ 0000775 0000000 0000000 00000000000 14536573575 0014053 5 ustar 00root root 0000000 0000000 wlcs-1.7.0/.github/workflows/ 0000775 0000000 0000000 00000000000 14536573575 0016110 5 ustar 00root root 0000000 0000000 wlcs-1.7.0/.github/workflows/ppa-upload.yml 0000664 0000000 0000000 00000002274 14536573575 0020702 0 ustar 00root root 0000000 0000000 name: PPA Upload
on:
push:
branches:
- main
- release/[0-9]+.[0-9]+
tags:
- v[0-9]+.[0-9]+.[0-9]+
jobs:
PPAUpload:
strategy:
fail-fast: true
matrix:
release:
- "22.04"
- "23.04"
- "23.10"
- "devel"
runs-on: ubuntu-latest
env:
DEBFULLNAME: "Mir CI Bot"
DEBEMAIL: "mir-ci-bot@canonical.com"
steps:
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v3
with:
gpg-private-key: ${{ secrets.MIR_BOT_GPG_PRIVATE_KEY }}
- name: Check out code
uses: actions/checkout@v3
with:
# Need full history for version determination
fetch-depth: 0
- name: Install dependencies
run: |
sudo apt-get install --no-install-recommends --yes \
debhelper \
devscripts \
dput \
python3-launchpadlib
- name: Set up Launchpad credentials
uses: DamianReeves/write-file-action@v1.0
with:
path: lp_credentials
contents: ${{ secrets.LAUNCHPAD_CREDENTIALS }}
- name: Upload to PPA
env:
RELEASE: ${{ matrix.release }}
run: tools/ppa-upload.sh lp_credentials
wlcs-1.7.0/.github/workflows/spread.yml 0000664 0000000 0000000 00000002562 14536573575 0020116 0 ustar 00root root 0000000 0000000 name: Spread
concurrency:
group: ${{ github.workflow }}-${{ github.event.number && format('pr{0}', github.event.number) || github.run_id }}
cancel-in-progress: true
on:
push:
branches:
- main
- release/[0-9]+.[0-9]+
tags:
- v[0-9]+[0-9]+.[0-9]+
merge_group:
types: [checks_requested]
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
jobs:
BuildAndTest:
strategy:
fail-fast: false
matrix:
spread-task:
- lxd:ubuntu-22.04:...:gcc
- lxd:ubuntu-23.04:...:gcc
- lxd:ubuntu-23.10:...:gcc
- lxd:ubuntu-23.10:...:clang
- lxd:fedora-37:...:gcc
- lxd:fedora-38:...:gcc
- lxd:fedora-39:...:gcc
- lxd:fedora-rawhide:...:gcc
- lxd:alpine-3.18:...:gcc
- lxd:ubuntu-devel:...:gcc
- lxd:ubuntu-devel:...:clang
- lxd:alpine-edge:...:gcc
runs-on: ubuntu-latest
env:
DEBFULLNAME: "Mir CI Bot"
DEBEMAIL: "mir-ci-bot@canonical.com"
steps:
- name: Set up LXD
uses: canonical/setup-lxd@main
- name: Set up Spread
run: |
set -euo pipefail
sudo snap install spread-mir-ci
sudo snap run lxd init --auto
- name: Check out code
uses: actions/checkout@v3
- name: Run Spread task
run: snap run spread-mir-ci.spread -v ${{ matrix.spread-task }}
wlcs-1.7.0/.github/workflows/tarball.yml 0000664 0000000 0000000 00000002745 14536573575 0020264 0 ustar 00root root 0000000 0000000 name: Build a tarball
on:
push:
tags:
- v[0-9]+.[0-9]+.[0-9]+
workflow_dispatch:
inputs:
version:
description: The version to build the tarball for
required: true
jobs:
BuildTarball:
runs-on: ubuntu-latest
steps:
- name: Determine version to build
id: get-version
run: |
if ${{ github.event_name == 'push' }}; then
version="$( echo '${{ github.ref }}' | sed 's@^refs/tags/v@@' )"
else
version='${{ inputs.version }}'
fi
# assert it's a version number
set -x
[[ ${version} =~ ^[0-9]+.[0-9]+.[0-9]+$ ]] && echo "version=${version}" >> $GITHUB_OUTPUT
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v5
with:
gpg_private_key: ${{ secrets.MIR_BOT_GPG_PRIVATE_KEY }}
- name: Check out code
uses: actions/checkout@v3
with:
ref: v${{ steps.get-version.outputs.version }}
- name: Build the tarball
run: |
./tools/make_release_tarball --skip-checks
gpg --detach-sig --sign --output wlcs-${{ steps.get-version.outputs.version }}.tar.xz.asc wlcs-${{ steps.get-version.outputs.version }}.tar.xz
- name: Store the tarball and signature
uses: actions/upload-artifact@v3
with:
name: wlcs-${{ steps.get-version.outputs.version }}
path: |
wlcs-${{ steps.get-version.outputs.version }}.tar.xz
wlcs-${{ steps.get-version.outputs.version }}.tar.xz.asc
wlcs-1.7.0/.gitignore 0000664 0000000 0000000 00000000043 14536573575 0014500 0 ustar 00root root 0000000 0000000 .idea/
/build/
/cmake-build-debug/
wlcs-1.7.0/CMakeLists.txt 0000664 0000000 0000000 00000023703 14536573575 0015260 0 ustar 00root root 0000000 0000000 # Copyright © 2017 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
# Authored by: Thomas Voss ,
# Alan Griffiths ,
# Christopher James Halse Rogers
cmake_minimum_required(VERSION 3.5)
cmake_policy(SET CMP0015 NEW)
cmake_policy(SET CMP0022 NEW)
project(wlcs VERSION 1.7.0)
add_definitions(-D_GNU_SOURCE)
add_definitions(-D_FILE_OFFSET_BITS=64)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
include(GNUInstallDirs)
find_package(PkgConfig)
#include (Doxygen.cmake)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread -g -Werror -Wall -pedantic -Wextra -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -g -Werror -Wall -fno-strict-aliasing -pedantic -Wnon-virtual-dtor -Wextra -fPIC")
if ("${CMAKE_SHARED_LINKER_FLAGS}" MATCHES ".*-fsanitize=.*")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
else()
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--as-needed -Wl,--no-undefined")
endif()
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-Wgnu-zero-variadic-macro-arguments HAVE_W_GNU_VARIADIC_MACROS)
if (HAVE_W_GNU_VARIADIC_MACROS)
# GTest's parametrised test macro tweaks this warning
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=gnu-zero-variadic-macro-arguments")
endif ()
include(CheckCXXSymbolExists)
list(APPEND CMAKE_REQUIRED_HEADERS ${GTEST_INCLUDE_DIRECTORIES})
check_cxx_symbol_exists(INSTANTIATE_TEST_SUITE_P "gtest/gtest.h" HAVE_INSTANTIATE_TEST_SUITE_P)
if (NOT HAVE_INSTANTIATE_TEST_SUITE_P)
#GTest conveniently renamed INSTANTIATE_TEST_CASE_P and then deprecated it.
add_definitions(-DINSTANTIATE_TEST_SUITE_P=INSTANTIATE_TEST_CASE_P)
endif()
find_package(Boost)
find_package(GtestGmock)
pkg_check_modules(WAYLAND_CLIENT REQUIRED wayland-client)
pkg_check_modules(WAYLAND_SERVER REQUIRED wayland-server)
pkg_check_modules(WAYLAND_SCANNER REQUIRED wayland-scanner)
include_directories(include)
include_directories(${Boost_INCLUDE_DIRS})
include_directories(${GMOCK_INCLUDE_DIR} ${GTEST_INCLUDE_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
set(PROTOCOL_SOURCES "")
execute_process(
COMMAND wayland-scanner --version
OUTPUT_VARIABLE WAYLAND_SCANNER_VERSION_OUTPUT
ERROR_VARIABLE WAYLAND_SCANNER_VERSION_OUTPUT
)
separate_arguments(WAYLAND_SCANNER_VERSION_OUTPUT)
list(LENGTH WAYLAND_SCANNER_VERSION_OUTPUT VERSION_STRING_COMPONENTS)
list(GET WAYLAND_SCANNER_VERSION_OUTPUT 1 VERSION_STRING)
string(STRIP ${VERSION_STRING} VERSION_STRING)
if (NOT(VERSION_STRING_COMPONENTS EQUAL 2))
message(AUTHOR_WARNING "Failed to parse wayland-scanner --version output")
endif()
if (VERSION_STRING VERSION_GREATER 1.14.91)
message(STATUS "Found wayland-scanner version ${VERSION_STRING}, using private-code mode")
set(WAYLAND_SCANNER_CODE_GENERATION_TYPE "private-code")
else()
message(STATUS "Found wayland-scanner version ${VERSION_STRING}, using (old) code mode")
set(WAYLAND_SCANNER_CODE_GENERATION_TYPE "code")
endif()
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/generated)
macro(GENERATE_PROTOCOL PROTOCOL_NAME)
set(PROTOCOL_PATH "${CMAKE_CURRENT_SOURCE_DIR}/src/protocol/${PROTOCOL_NAME}.xml")
set(OUTPUT_PATH_C "${CMAKE_CURRENT_BINARY_DIR}/generated/${PROTOCOL_NAME}.c")
set(OUTPUT_PATH_SERVER_H "${CMAKE_CURRENT_BINARY_DIR}/generated/${PROTOCOL_NAME}-server.h")
set(OUTPUT_PATH_CLIENT_H "${CMAKE_CURRENT_BINARY_DIR}/generated/${PROTOCOL_NAME}-client.h")
add_custom_command(OUTPUT "${OUTPUT_PATH_C}"
VERBATIM
COMMAND "wayland-scanner" "--include-core-only" ${WAYLAND_SCANNER_CODE_GENERATION_TYPE} "${PROTOCOL_PATH}" "${OUTPUT_PATH_C}"
DEPENDS "${PROTOCOL_PATH}"
)
add_custom_command(OUTPUT "${OUTPUT_PATH_SERVER_H}"
VERBATIM
COMMAND "wayland-scanner" "--include-core-only" "server-header" "${PROTOCOL_PATH}" "${OUTPUT_PATH_SERVER_H}"
DEPENDS "${PROTOCOL_PATH}"
)
add_custom_command(OUTPUT "${OUTPUT_PATH_CLIENT_H}"
VERBATIM
COMMAND "wayland-scanner" "--include-core-only" "client-header" "${PROTOCOL_PATH}" "${OUTPUT_PATH_CLIENT_H}"
DEPENDS "${PROTOCOL_PATH}"
)
list(APPEND PROTOCOL_SOURCES ${OUTPUT_PATH_C} ${OUTPUT_PATH_CLIENT_H})
endmacro()
GENERATE_PROTOCOL(gtk-primary-selection)
GENERATE_PROTOCOL(primary-selection-unstable-v1)
GENERATE_PROTOCOL(wayland)
GENERATE_PROTOCOL(xdg-shell-unstable-v6)
GENERATE_PROTOCOL(xdg-shell)
GENERATE_PROTOCOL(wlr-layer-shell-unstable-v1)
GENERATE_PROTOCOL(xdg-output-unstable-v1)
GENERATE_PROTOCOL(wlr-foreign-toplevel-management-unstable-v1)
GENERATE_PROTOCOL(pointer-constraints-unstable-v1)
GENERATE_PROTOCOL(relative-pointer-unstable-v1)
GENERATE_PROTOCOL(text-input-unstable-v2)
GENERATE_PROTOCOL(text-input-unstable-v3)
GENERATE_PROTOCOL(input-method-unstable-v1)
GENERATE_PROTOCOL(input-method-unstable-v2)
GENERATE_PROTOCOL(wlr-virtual-pointer-unstable-v1)
option(WLCS_BUILD_ASAN "Build a test runner with AddressSanitizer annotations" ON)
option(WLCS_BUILD_TSAN "Build a test runner with ThreadSanitizer annotations" ON)
option(WLCS_BUILD_UBSAN "Build a test runner with UndefinedBehaviourSanitizer annotations" ON)
set(WLCS_TESTS
tests/test_bad_buffer.cpp
tests/pointer_constraints.cpp
tests/copy_cut_paste.cpp
tests/gtk_primary_selection.cpp
tests/test_surface_events.cpp
tests/touches.cpp
tests/wl_output.cpp
tests/surface_input_regions.cpp
tests/frame_submission.cpp
tests/primary_selection.cpp
tests/relative_pointer.cpp
tests/subsurfaces.cpp
tests/xdg_surface_v6.cpp
tests/xdg_toplevel_v6.cpp
tests/xdg_surface_stable.cpp
tests/xdg_toplevel_stable.cpp
tests/xdg_popup.cpp
tests/wlr_layer_shell_v1.cpp
tests/xdg_output_v1.cpp
tests/wlr_foreign_toplevel_management_v1.cpp
tests/self_test.cpp
tests/text_input_v3_with_input_method_v2.cpp
tests/wlr_virtual_pointer_v1.cpp
tests/text_input_v2_with_input_method_v1.cpp
)
set(
WLCS_SOURCES
include/wlcs/display_server.h
include/wlcs/pointer.h
include/wlcs/touch.h
include/helpers.h
include/wl_handle.h
include/in_process_server.h
include/pointer_constraints_unstable_v1.h
include/primary_selection.h
include/relative_pointer_unstable_v1.h
include/xdg_shell_v6.h
include/xdg_shell_stable.h
include/xdg_output_v1.h
include/version_specifier.h
include/wl_interface_descriptor.h
include/layer_shell_v1.h
include/surface_builder.h
include/input_method.h
src/data_device.cpp
src/gtk_primary_selection.cpp
src/helpers.cpp
src/in_process_server.cpp
src/xdg_shell_v6.cpp
src/xdg_shell_stable.cpp
src/layer_shell_v1.cpp
src/main.cpp
src/pointer_constraints_unstable_v1.cpp
src/primary_selection.cpp
src/shared_library.cpp
src/relative_pointer_unstable_v1.cpp
src/xfail_supporting_test_listener.h
src/xfail_supporting_test_listener.cpp
src/termcolor.hpp
src/thread_proxy.h
src/xdg_output_v1.cpp
src/version_specifier.cpp
src/surface_builder.cpp
src/input_method.cpp
${PROTOCOL_SOURCES}
${WLCS_TESTS}
)
# g++ 9.4 (on 20.04) hates the MOCK_METHOD macro
if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10)
# Neither gnu-zero-variadic-macro-arguments nor variadic-macro help,
# we just have to drop pedantic...
set_property(SOURCE ${WLCS_TESTS} PROPERTY COMPILE_OPTIONS -Wno-pedantic)
endif()
add_library(test_c_compile OBJECT src/test_c_compile.c)
add_executable(wlcs ${WLCS_SOURCES})
set(EXECUTABLE_TARGETS wlcs)
if (WLCS_BUILD_ASAN)
add_executable(wlcs.asan ${WLCS_SOURCES})
target_compile_options(wlcs.asan PUBLIC -fsanitize=address -fno-omit-frame-pointer)
set_target_properties(
wlcs.asan
PROPERTIES
LINK_FLAGS -fsanitize=address)
# Explicitly linking with the sanitiser is harmless
target_link_libraries(wlcs.asan asan)
list(APPEND EXECUTABLE_TARGETS wlcs.asan)
endif()
if (WLCS_BUILD_TSAN)
add_executable(wlcs.tsan ${WLCS_SOURCES})
target_compile_options(wlcs.tsan PUBLIC -fsanitize=thread -fno-omit-frame-pointer)
set_target_properties(
wlcs.tsan
PROPERTIES
LINK_FLAGS -fsanitize=thread)
# Explicitly linking with the sanitiser is harmless.
target_link_libraries(wlcs.tsan tsan)
list(APPEND EXECUTABLE_TARGETS wlcs.tsan)
endif()
if (WLCS_BUILD_UBSAN)
add_executable(wlcs.ubsan ${WLCS_SOURCES})
target_compile_options(wlcs.ubsan PUBLIC -fsanitize=undefined)
set_target_properties(
wlcs.ubsan
PROPERTIES
LINK_FLAGS -fsanitize=undefined)
# Unsure quite why explicitly linking with ubsan is required, but here we are…
target_link_libraries(wlcs.ubsan ubsan)
list(APPEND EXECUTABLE_TARGETS wlcs.ubsan)
endif()
foreach(TARGET IN LISTS EXECUTABLE_TARGETS)
target_link_libraries(
${TARGET}
${WAYLAND_CLIENT_LDFLAGS} ${WAYLAND_CLIENT_LIBRARIES}
${WAYLAND_SERVER_LDFLAGS} ${WAYLAND_CLIENT_LIBRARIES}
dl
${GMOCK_LIBRARY}
${GTEST_LIBRARY}
)
endforeach(TARGET)
install(
TARGETS ${EXECUTABLE_TARGETS}
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/wlcs
)
install(
DIRECTORY include/wlcs
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
include(JoinPaths)
join_paths(PKGCONFIG_BINDIR "\${prefix}" "${CMAKE_INSTALL_BINDIR}")
join_paths(PKGCONFIG_LIBEXECDIR "\${prefix}" "${CMAKE_INSTALL_LIBEXECDIR}")
join_paths(PKGCONFIG_INCLUDEDIR "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
configure_file(
wlcs.pc.in
${CMAKE_CURRENT_BINARY_DIR}/wlcs.pc
@ONLY
)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/wlcs.pc
DESTINATION
${CMAKE_INSTALL_LIBDIR}/pkgconfig/
)
wlcs-1.7.0/COPYING.GPL2 0000664 0000000 0000000 00000043254 14536573575 0014261 0 ustar 00root root 0000000 0000000 GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
wlcs-1.7.0/COPYING.GPL3 0000664 0000000 0000000 00000104374 14536573575 0014263 0 ustar 00root root 0000000 0000000
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
wlcs-1.7.0/README.rst 0000664 0000000 0000000 00000004461 14536573575 0014207 0 ustar 00root root 0000000 0000000 ==============================
Wayland Conformance Test Suite
==============================
``wlcs`` aspires to be a protocol-conformance-verifying test suite usable by
Wayland compositor implementors.
It is growing out of porting the existing Weston test suite to be run
in `Mir's `_ test suite,
but it is designed to be usable by any compositor.
There have been a number of previous attempts at a Wayland compositor test
suite - the `Wayland Functional Integration Test Suite `_,
and the `Weston test suite `_
are a couple of examples.
What sets ``wlcs`` apart from the graveyard of existing test suites is its
integration method.
Previous test suites have used a Wayland protocol extension
to interrogate the compositor state. This obviously requires that compositors
implement that protocol, means that tests only have access to information
provided by that protocol, and the IPC means that there isn't a canonical
happens-before ordering available.
Instead, ``wlcs`` relies on compositors providing an integration module,
providing ``wlcs`` with API hooks to start a compositor, connect a client,
move a window, and so on. This makes both writing and debugging tests easier -
the tests are (generally) in the same address space as the compositor, so there
is a consistent global clock available, it's easier to poke around in
compositor internals, and standard debugging tools can follow control flow from
the test client to the compositor and back again.
Usage
-----
In order for ``wlcs`` to test your compositor you need to provide an
integration module. This needs to implement the interfaces found in
``include/wlcs``. If your integration module is
``awesome_compositor_wlcs_integration.so``, then running ``wlcs
awesome_compositor_wlcs_integration.so`` will load and run all the tests.
Development
-----------
``wlcs`` requires a small number of hooks into your compositor to drive the
tests - it needs to know how to start and stop the mainloop, to get an fd to
connect a client to, and so on.
To access these hooks, ``wlcs`` looks for a symbol ``wlcs_server_integration``
of type ``struct WlcsServerIntegration const`` (defined in
``include/wlcs/display_server.h``) in your integration module.
wlcs-1.7.0/cmake/ 0000775 0000000 0000000 00000000000 14536573575 0013573 5 ustar 00root root 0000000 0000000 wlcs-1.7.0/cmake/FindGtestGmock.cmake 0000664 0000000 0000000 00000005322 14536573575 0017447 0 ustar 00root root 0000000 0000000 include(FindPackageHandleStandardArgs)
find_package(GTest)
if (NOT GTEST_FOUND)
include(ExternalProject)
find_path(GTEST_ROOT
NAMES CMakeLists.txt
PATHS /usr/src/gtest /usr/src/googletest/googletest/
DOC "Path to GTest CMake project")
ExternalProject_Add(GTest PREFIX ./gtest
SOURCE_DIR ${GTEST_ROOT}
CMAKE_ARGS
-DCMAKE_CXX_COMPILER_WORKS=1
-DCMAKE_CXX_FLAGS='${CMAKE_CXX_FLAGS}'
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
INSTALL_COMMAND true
BUILD_BYPRODUCTS
${CMAKE_CURRENT_BINARY_DIR}/gtest/src/GTest-build/libgtest.a
${CMAKE_CURRENT_BINARY_DIR}/gtest/src/GTest-build/libgtest_main.a
${CMAKE_CURRENT_BINARY_DIR}/gtest/src/GMock-build/libgmock.a)
ExternalProject_Get_Property(GTest binary_dir)
add_library(gtest UNKNOWN IMPORTED)
set_target_properties(gtest PROPERTIES IMPORTED_LOCATION ${binary_dir}/libgtest.a)
add_dependencies(gtest GTest)
set(GTEST_LIBRARY "gtest")
add_library(gtest_main UNKNOWN IMPORTED)
set_target_properties(gtest_main PROPERTIES IMPORTED_LOCATION ${binary_dir}/libgtest_main.a)
add_dependencies(gtest_main GTest)
set(GTEST_MAIN_LIBRARY "gtest_main")
set(GTEST_BOTH_LIBRARIES ${GTEST_LIBRARY} ${GTEST_MAIN_LIBRARY})
find_path(GTEST_INCLUDE_DIRS NAMES gtest/gtest.h)
find_package_handle_standard_args(GTest GTEST_LIBRARY GTEST_BOTH_LIBRARIES GTEST_INCLUDE_DIRS)
endif()
# Upstream GTestConfig.cmake doesn't provide GTEST_LIBRARY but GTEST_LIBRARIES
# CMake 3.20+ uses the upstream gtest config if possible.
if (NOT DEFINED GTEST_LIBRARY)
set(GTEST_LIBRARY ${GTEST_LIBRARIES})
endif()
find_file(GMOCK_SOURCE
NAMES gmock-all.cc
DOC "GMock source"
PATHS /usr/src/googletest/googlemock/src/ /usr/src/gmock/ /usr/src/gmock/src)
if (EXISTS ${GMOCK_SOURCE})
find_path(GMOCK_INCLUDE_DIR gmock/gmock.h PATHS /usr/src/googletest/googlemock/include)
add_library(GMock STATIC ${GMOCK_SOURCE})
if (EXISTS /usr/src/googletest/googlemock/src)
set_source_files_properties(${GMOCK_SOURCE} PROPERTIES COMPILE_FLAGS "-I/usr/src/googletest/googlemock")
endif()
if (EXISTS /usr/src/gmock/src)
set_source_files_properties(${GMOCK_SOURCE} PROPERTIES COMPILE_FLAGS "-I/usr/src/gmock")
endif()
find_package_handle_standard_args(GMock DEFAULT_MSG GMOCK_INCLUDE_DIR)
set(GMOCK_LIBRARY GMock)
else()
# Assume gmock is no longer source, we'll find out soon enough if that's wrong
add_custom_target(GMock)
string(REPLACE gtest gmock GMOCK_LIBRARY ${GTEST_LIBRARY})
endif()
set(GMOCK_LIBRARIES ${GTEST_BOTH_LIBRARIES} ${GMOCK_LIBRARY})
wlcs-1.7.0/cmake/JoinPaths.cmake 0000664 0000000 0000000 00000001461 14536573575 0016476 0 ustar 00root root 0000000 0000000 # This module provides function for joining paths
# known from most languages
#
# SPDX-License-Identifier: (MIT OR CC0-1.0)
# Copyright 2020 Jan Tojnar
# https://github.com/jtojnar/cmake-snips
#
# Modelled after Python’s os.path.join
# https://docs.python.org/3.7/library/os.path.html#os.path.join
# Windows not supported
function(join_paths joined_path first_path_segment)
set(temp_path "${first_path_segment}")
foreach(current_segment IN LISTS ARGN)
if(NOT ("${current_segment}" STREQUAL ""))
if(IS_ABSOLUTE "${current_segment}")
set(temp_path "${current_segment}")
else()
set(temp_path "${temp_path}/${current_segment}")
endif()
endif()
endforeach()
set(${joined_path} "${temp_path}" PARENT_SCOPE)
endfunction()
wlcs-1.7.0/debian/ 0000775 0000000 0000000 00000000000 14536573575 0013735 5 ustar 00root root 0000000 0000000 wlcs-1.7.0/debian/changelog 0000664 0000000 0000000 00000012444 14536573575 0015614 0 ustar 00root root 0000000 0000000 wlcs (1.7.0-0ubuntu0) UNRELEASED; urgency=medium
* New upstream release. Notable changes:
+ New tests for input-method-v1 (#302)
+ Handle incomplete logical pointer/touch events better (#313)
+ XdgToplevelStable: Fix race in .configure handling (#318)
+ helpers: avoid triggering a kernel warning (#320)
+ InProcessServer: Fix xdg_shell window construction (#324)
+ XdgSurfaceStable: Fix configure event logic
-- Michał Sawicz Tue, 05 Dec 2023 13:52:28 +0100
wlcs (1.6.1-0ubuntu0) UNRELEASED; urgency=medium
* Bump project version in CMakeLists.txt
-- Michał Sawicz Tue, 10 Oct 2023 12:14:27 +0200
wlcs (1.6.0-0ubuntu0) UNRELEASED; urgency=medium
* New upstream release. Notable changes:
+ Update wayland.xml to latest
+ XDG stable: use mock methods instead of notification lists
+ Test popup constraint_adjustment
+ Tests for XDG shell (stable) version 5
+ Test that text input is entered after child window is closed
+ Copy geometry headers from Mir
+ Test popups are dismissed in the correct order
+ Test buffer can be deleted after it's attached
+ Less flaky synchronization for VirtualPointerV1Test (#297, #294)
+ VirtualPointerV1Test: no-events-sent test fails if events are sent (#296)
+ Fix various frame-event misunderstandings
+ Change remaining std::experimental::optionals to std::optional
-- Alan Griffiths Mon, 17 Jul 2023 13:12:00 +0100
wlcs (1.5.0-0ubuntu0) UNRELEASED; urgency=medium
* New upstream release. Notable changes:
+ Tests for zwlr_virtual_pointer_v1
+ Use maximum shared version when binding globals (Fixes #234)
+ Make zxdg_shell_v6 ExpectedlyNotSupported if not in supported_extensions
(Fixes #237)
+ Destroy xdg_toplevel before xdg_surface on cleanup
+ Fixup CMakeLists.txt so tests can use MOCK_METHOD
+ c++20
+ Fix BadBufferTest.test_truncated_shm_file protocol error
+ Fix CMake install dir usage in pkgconfig, honour CMAKE_INSTALL_INCLUDEDIR
-- Alan Griffiths Fri, 6 Jan 2023 11:40:13 +0000
wlcs (1.4.0-0ubuntu0) UNRELEASED; urgency=medium
* New upstream release. Notable changes:
+ Add tests for zwp_text_input_unstable_v3
+ Add tests for zwp_input_method_unstable_v2
+ Add tests for zwlr_layer_shell_v1 version 4
+ Drop requriement for compositors to implement wl_shell. Tests which
require an arbitrary "visible surface" should now only require one
of xdg_shell, xdg_shell_unstable_v6, or wl_shell.
+ Fix expectations of keyboard focus for xdg_popup tests to match the
protocol. NOTE: These tests will fail on many compositors, including
Weston, as is is common to not follow the protocol correctly here.
-- Christopher James Halse Rogers Fri, 25 Feb 2022 15:33:24 +1100
wlcs (1.3.0-0ubuntu0) groovy; urgency=medium
* New upstream release. Notable changes:
+ Check Cursor movement is not propagating to clients correctly when
zwp_relative_pointer_manager_v1 is enabled
+ Support getting the latest serial sent from the compositor (useful for
popup grabs, and possibly other things in the future). Adding `wl_keyboard`
makes sure new surfaces have a serial once they're focused, and provides
access to keyboard focus
+ Test that correct input event is used for interactive move
+ Fix FindGtestGmock.cmake for new cmake (Fixes the build on Alpine Linux)
+ Test that layer surfaces are correctly reconfigured
+ Add tests for popup done event
+ Test surfaces get enter/leave events
+ Test version 2 and 3 features of zwlr_layer_shell_v1
+ Destroy subsurfaces
+ Show surface type names in paramaterized touch tests
-- Alan Griffiths Thu, 27 May 2021 13:13:13 +0100
wlcs (1.2.1-0ubuntu0) groovy; urgency=medium
* New upstream release. Notable changes:
+ Fix cut & paste test
-- Alan Griffiths Fri, 19 Feb 2021 11:11:11 +0000
wlcs (1.2.0-0ubuntu0) groovy; urgency=medium
* New upstream release. Notable changes:
+ Add tests for wlr_layer_shell_unstable_v1
+ Build fixes for Musl libc; WLCS now builds on Alpine. Thanks, Luca Weiss
+ More XDG Shell tests, particularly around protocol errors,
window-geometry, and input edge-cases.
+ Add tests for wlr_foreign_toplevel_management_unstable_v1
+ Many improvements to wl_subsurface tests. Notably this fixes a
misinterpretation of the protocol which lead to testing incorrect
behaviour.
-- Christopher James Halse Rogers Mon, 31 Aug 2020 16:39:21 +1000
wlcs (1.1.0-0ubuntu0) eoan; urgency=medium
* New upstream release. Relevant upstream changes:
+ Document the compositor-integration version macros
+ Add tests for the wl_output protocol
+ More tests for XDG Shell, particularly around popups and window movement
+ Add tests for wp_primary_selection_unstable_v1 protocol
+ Add tests for gdk_primary_selection protocol
+ Lots of build fixes for !Ubuntu systems. Thanks, Neal Gompa!
-- Christopher James Halse Rogers Tue, 23 Jul 2019 10:37:52 +1000
wlcs (1.0-0ubuntu0) disco; urgency=medium
* Initial release
-- Christopher James Halse Rogers Tue, 08 Jan 2019 11:32:06 +1100
wlcs-1.7.0/debian/compat 0000664 0000000 0000000 00000000003 14536573575 0015134 0 ustar 00root root 0000000 0000000 10
wlcs-1.7.0/debian/control 0000664 0000000 0000000 00000001561 14536573575 0015343 0 ustar 00root root 0000000 0000000 Source: wlcs
Priority: optional
Maintainer: Christopher James Halse Rogers
Build-Depends:
debhelper (>= 9),
cmake,
libboost-dev,
libgtest-dev,
libwayland-dev,
pkg-config,
google-mock
Standards-Version: 4.1.3
Section: devel
Homepage: https://github.com/MirServer/wlcs
Vcs-Browser: https://salsa.debian.org/mir-server-team/wlcs
Vcs-Git: https://salsa.debian.org/mir-server-team/wlcs.git
Package: wlcs
Section: devel
Architecture: any
Multi-Arch: same
Depends: ${misc:Depends}, ${shlibs:Depends}
Description: Wayland Conformance Suite's
wlcs aspires to be a protocol-conformance-verifying test suite usable by
Wayland compositor implementations.
.
This package contains the headers necessary for a Wayland compositor to
provide the integration module needed to run wlcs tests, and the test
runner binary needed to run the tests against the compositor.
wlcs-1.7.0/debian/copyright 0000664 0000000 0000000 00000005664 14536573575 0015703 0 ustar 00root root 0000000 0000000 Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: wlcs
Source: https://github.com/MirServer/wlcs
Files: *
Copyright: 2017-2019 Canonical, Ltd
License: GPL-3
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as
published by the Free Software Foundation.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
On Debian systems, the full text of the GNU General Public
License version 3 can be found in the file
`/usr/share/common-licenses/GPL-3'.
Files: tests/test_bad_buffer.cpp
tests/test_surface_events.cpp
xdg_popup_stable.cpp
xdg_popup_v6.cpp
xdg_surface_stable.cpp
xdg_surface_v6.cpp
xdg_toplevel_stable.cpp
xdg_toplevel_v6.cpp
Copyright: 2012 Intel Corporation
2013 Collabora, Ltd.
2017-2018 Canonical Ltd.
License: Expat
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.
Files: debian/*
Copyright: 2019 Christopher James Halse Rogers
License: GPL-2+
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
wlcs-1.7.0/debian/rules 0000775 0000000 0000000 00000002126 14536573575 0015016 0 ustar 00root root 0000000 0000000 #!/usr/bin/make -f
include /usr/share/dpkg/default.mk
# see FEATURE AREAS in dpkg-buildflags(1)
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
COMMON_CONFIGURE_OPTIONS =\
-DWLCS_BUILD_ASAN=ON \
-DWLCS_BUILD_UBSAN=ON \
-DWLCS_BUILD_TSAN=ON
ifneq ($(filter i386 armhf, $(DEB_HOST_ARCH)),)
# i386 and armhf do not have tsan
COMMON_CONFIGURE_OPTIONS += -DWLCS_BUILD_TSAN=OFF
endif
ifeq ($(DEB_HOST_ARCH), riscv64)
# riscv64 does not have sanitizers
ifeq ($(DEB_DISTRIBUTION), focal)
COMMON_CONFIGURE_OPTIONS += -DWLCS_BUILD_ASAN=OFF
endif
COMMON_CONFIGURE_OPTIONS += -DWLCS_BUILD_UBSAN=OFF
COMMON_CONFIGURE_OPTIONS += -DWLCS_BUILD_TSAN=OFF
endif
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105329
ifeq ($(DEB_HOST_ARCH), ppc64el)
ifneq ($(shell gcc --version | grep '1[23].[[:digit:]]\+.[[:digit:]]\+$$'),)
export DEB_CFLAGS_MAINT_APPEND = -O2
export DEB_CXXFLAGS_MAINT_APPEND = -O2
export DEB_FCFLAGS_MAINT_APPEND = -O2
export DEB_FFLAGS_MAINT_APPEND = -O2
endif
endif
override_dh_auto_configure:
dh_auto_configure -- $(COMMON_CONFIGURE_OPTIONS)
%:
dh $@
wlcs-1.7.0/debian/source/ 0000775 0000000 0000000 00000000000 14536573575 0015235 5 ustar 00root root 0000000 0000000 wlcs-1.7.0/debian/source/format 0000664 0000000 0000000 00000000004 14536573575 0016442 0 ustar 00root root 0000000 0000000 1.0
wlcs-1.7.0/debian/upstream/ 0000775 0000000 0000000 00000000000 14536573575 0015575 5 ustar 00root root 0000000 0000000 wlcs-1.7.0/debian/upstream/signing-key.asc 0000664 0000000 0000000 00000056015 14536573575 0020520 0 ustar 00root root 0000000 0000000 -----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBFmTm/8BEACni7C38F6eITa90TlDHp1m5zMzF1ZMAjTJpiV43KRubeDnYmoo
HUkH0TtXlA5KY/LotWE8IupNtrf1c+17JvbhYYH+gKg3rLdHt2hinQxoNT4ncalt
BzTvq0YOrQGba6uSq4FMjbIhRMPjQLLWxnn3abtIh33y9d9HPMYRF1SG/VliLiwp
KC0zdiHssMFMaZwqSNowhffR4MZCcijxZbyJ1/2UbnK4u7Y6p0VkkmyNmlPXVPFn
cfbxJohaUwj/cphVDJQ0pDZm0FnNDJzfYU8E7Cx5uBEGOauAGj1vkHeVZ9SG512u
F6T1rFj5eaGWcsjIkIuTq5/i6FJf+tvod7/Ugpjf98KZ40Gf/m6iaZErzWg225II
9A7L/1C+Izy3orvxKeCuBCiGo2kzW+POcdp/h2Oc9cGAu88W8OcBSaxxxebsggV4
3Zn9kxA5ZmTnc/2AOOHvN6GcvDASvAHUq8yZSmAdiCtkimlpJ9G9v54Y+vc8Ptuu
hqV/0uL21qFDxBeh7h6QTS9V+aZF98SbYra0dW1ufYMwHn0Vv33N3XuY0Tf+E9bi
Fc/TLDl1yQMWzl/mq9PNzyZMMUF4bmNyLX64GhJIXQ0ZAEh/S/y8TMpehjP/KK2e
WnXUQiWgNXwPxra6mk24K2k2LCHCVxan+nt5cyrETr8VxMJ0bcpMaG9CXwARAQAB
tDBDaHJpc3RvcGhlciBKYW1lcyBIYWxzZSBSb2dlcnMgPHJhb2ZAdWJ1bnR1LmNv
bT6JAhwEEAEKAAYFAlmo+VQACgkQGLP1D+WSPBiqlQ/+LitTooxk3zjg4xo3P7cf
enG1mF1fu/JonyLT+m5mJJ064ZiZ0ywldT5zwmHTFQAr2Z5S6aNg4o8MmeA9JjpL
LAX1kclD7a2/o33vyoRfE2EabYQkVI0qJgG0YxP0Uip070p6kBZHc9CsvBxiWn5c
k8bIW+LfEQwPT3HtvYFUBmFsrayHifvyV0nWfGKVzNHcpwdYqSHNKjM8EeY9lunv
/zNJMRUTPfhfD05FiyaUXCJyadXJ+IQxrG/wo7hKQcofopZQyMNZrT4LKq7KqFV9
5tLaS74GzFX3L6m0cVlsGP0UrBWUPemex7Ui4gIbdUG/gRy4I5PS6D79ADoH0vIH
1IKd095LQcudIgCGZyUQabFx6vIC8FMbqK49jndFk6ZbmBZXRWxKK0M2B4Bnlp87
+dJKXcvN5/lbt/7X3U3Q1IjbzCjPST7Rr+LvPpOK8RxrPwNBYa7ogrZWSoM5uPN4
1jBDnVQiQ024LL9EMtr8IL1NjIFZHmRraokv8F+8Vk/MB8sxzQRl4Kuhj/Q/vVJY
UeijijhAyzEBoYN45BNVENq9NaMeeeArYeIrsX8QhbqMSB790ZuUgNaDemz6WDgL
wdybapwmOrWy/r8gHFox7ldkuSZS9vKGGrOJhS2vsnV0L95iEy4irm5iY/fqCW9n
Y8xtzwQ2wZLUKCnCN65BfTeJAjoEEwEKACQFAlmToAoCGwMFCQGLggAICwkIBw0M
CwoFFQoJCAsCHgECF4AACgkQoF7vcIbXMkKW6g/+ModoGKhi52wClyQnaMUzYVgB
xyO5iqJHLC+D90FN0fIpL0R6sTUwZ4ac/ymg9PfjZeoPtDcbFI0C93M+isCnoo9r
/IJsanSaoZhLJKlZ5XrLuQg/TRqMhMP+/xmjl9c0zkYFnTS5gdaTiSGhqn1OLoFM
z01fixlf3Q/Ej9Auw+YUE6bCMMqh3bbh4qInfd0o8GrvubtMeekhzasH2avQvrfV
zSx/WKf3Sz4Np4iq943fxDgswbeCZcAliFBEZ+wME4/+7LXW3DrZCMEY81USv1T0
c+bIkI+A5Dupi1+iWqUfiQyVW6nocU+Hj6NjA0PfYJxeJX8+0xzB1m4FyJklUaJ/
OEEs5NA5+8iQbSFDAnqb376IQJX/P2clEyR3oGkzZOFGYNJcNJpLxk/BBgkPYZ2v
LsC3eXykA81S7mbpiWIGUlEL9/LAIdEVYLiBp1+XzSwsPa3ME6y3OQHXLjrEPeYD
AKZWBZDkYF/F2IxFiCSJ6P+gzQD67xOPF7cxsG/iIeVuLvxDylkrPweYyTgMqx09
ouirVW5VRlbVQVhviPTunwUofKZm18zyfpOEJ4e6+26Adsy45D1ziji8ZCbxchFd
quUPdu/VaxA957qAuveG0R8YQEG+MNvj6V+C3zzIvoiJo2t0V75KNZ033AKn16in
eGErY2ad84SLYxin3GSJAlEEEwEKADsCGwMICwkIBw0MCwoFFQoJCAsCHgECF4AW
IQQLDTVq0FnH2jOBvhGgXu9whtcyQgUCWx9paQUJA2ZpXQAKCRCgXu9whtcyQuiD
EACO0apBWPXR2AguczFY/pNpVEq7OyqP13uZbNcT1c48CBcLGy197MDBdfIwIPWF
dTrGUq7g9YTnhwAsjpi07ito57B/VY+lYEPOFqM0taY5k9sCubsJsnukpiHap+lX
YfZ4VrZUfcOIzAGb/rxevyhJq1S8ddmRy7dXUvRnYgOwqB71wbL3yd1tazO0sz1f
aCHqtXZfpHrCCwDxePjMLCrTDfe0CGUk7d25Vkf+wIFuxRdMZLEwCuhhiLeJg0Hw
Vn452MtiRLr+CqVzDLbA8jUDoygWheoIjzEOZCE13nBEPD59me/DKib1b6Q72ZXJ
HLEs7aOi7Rf6lCPIxivHK520BSjVjeejBlTikODgDmo7QiAv5GGa/uJEgBN/Bslv
RlRIQzmO1oKeD4EjruZtm1jomTQO9137raK5xeUJS1r4UyUhm6Eoz6gbVfEEhdrZ
gdL/E37Q6zDcRt+qXG/IfRblggLKiHTUE47HZNxuGxvNf4LlFQcmlX+gH4b8oDAw
4qJMPZlYzKY/3z7grLXukISQa2YdLEdDRuWiQUzWFsK3Baord4VezOnooEXqX9ut
uzksTYU7Uud+ZSZ5gW7apF+a5DLaY9LKsFxKhtc0wD4yRGW6ieCv68AN3+eJ/ehI
IdmsVOQD29UZYvcdpuUe+AkE69ttDZPy83jW9rgYdfho1IkCUQQTAQoAOwIbAwgL
CQgHDQwLCgUVCgkICwIeAQIXgBYhBAsNNWrQWcfaM4G+EaBe73CG1zJCBQJbYVZ7
BQkCuwh2AAoJEKBe73CG1zJCxOsP/iEgsz2i4zTnn/Zr90WotWXSG8gNsaNq+F7U
aIWwTYBrRtIFnHPBePmVfNX1AQCTKdvHARXMLNaT49t5PeoLwPMhj1LN+80VYfVZ
ZLN2mRxHQRfd6gE/oisGGc5jnYIatwFIJ5RKq/sRCU9r2yp3rOceLwBdDw/BcPnE
dIBfN43rWmBNVI0HeUZyAhO+FABSQpnYiOuEpvYAoYLJroWvTXPT7nKpoAp6pTg+
61MBzv4ZLkw3B0d7Dk3bKUPLnTeljv4CbtA8F8WZj9T69nk7az3gwnXITO+/taOM
UCYz10WJNVNJl2qdwdUTNOv/+PvVjZ5iUjy5zGEiMUgurFvodSKITVvrzmmAb0nr
QgzzQFk2B0sFyYoPo47edz/CN9tC2+WB+VTX+RBgNR+fuQYR1VZX0c1GVNTbjqii
JJC+t86PSzl5DD6GcjbuB/PswLwQ9im3zhBwtf0rg7SAAIl8FfKc6xAbbeQJsbQ5
yW2ABIRCW0ZzgrP8+kQV9zsFK84mjLX1w8R0QVAgr+RvY6i0R1r7Ih91Vz3f7MIm
WMKR2TPaaBNzVkgZChilJUzQKmgB8SxNGMRvSQ3VQkzsef7xwoPiL/vsK5/EB2fC
c9amkFjQIDYDG8o2uIRLCmUP5bjtigLD7WDNsancD+qfrK2IIK2XBnbp0GPSiLii
i9MdSQiBiQJRBBMBCgA7AhsDCAsJCAcNDAsKBRUKCQgLAh4BAheAFiEECw01atBZ
x9ozgb4RoF7vcIbXMkIFAlwtcIIFCQOHInkACgkQoF7vcIbXMkJWog/+P8x/xr9Q
ZqV4uHQZf6OJs+PmxppmkiyOi5TU10VfKMB3WX+SsZa4S3NL8LAnfwaRN2IfdZul
NLh0LIE0HQAUoU+2iWtb0Obna9xXHyydkVAMKtMqqlbCKRjv//ElVoouFALnM6nA
MmlfMKrE21pkXin/umkPI7OnmHOzc/I201sV3Wp1Ql/G8RROeu0nJayFSGz9Basx
leby24k9N0y3B7Mk/ft9xUVGnHVrycxDFXVmxff2wF49bVXE98eUlyqQziXMUtJf
U6h7bWoSCmQkl4r2sR8Lz0Zmq2JiZhI7KYbPxfr4spGhIgijD+7ht6fUK4mdPnyq
WEO/mcQKMLo5CYCFvIXDCM2PJx/3EAucDUrlPR901zq10vY/wtEzKFOtpmfNts8/
8JtNHTBsERvdXhXwBg0GJ4ZTB8dFPr4oQeX53kTw33FTgGy6RWSU8j6ruc+GG9bA
NbJSGvJPWXhC2fkxxTO8et79RmX8RIP21xhEtnEXWmYIfmcxRmZDjMquYIQBioUd
1Ec956GyjAmZIdoBqLwPX+NKpN3d7ZaqU+g+MPLCfzSc1pEpDNF26oJWmD9N2kSe
xzoDLa9PTEKTSMlMXuiIlEgVTCsrgGo/GilSzEyoS7vPLsGPySC6CZ548HnUz2N5
ddRsrpJF2iHTiHFRItjcDYmA+FF3pd0MKLyJAlEEEwEKADsCGwMICwkIBw0MCwoF
FQoJCAsCHgECF4AWIQQLDTVq0FnH2jOBvhGgXu9whtcyQgUCXJRzQQUJA+4lJAAK
CRCgXu9whtcyQlaDD/9DlY/Zm/5uHsFjpDcrVdLMJizfRGKTm4mMPyK6inamF4h9
0zFJhSRCKMJSKV5fvrJ54CdRc835wtMzG3DxU6YioHAuyPwcJv6rut3OPqDuH/0i
rSL8bwB+GjAtlTO2xT48pm1IFlzdiGOQNhFAzwxX7jFJbyYkbwT8w1h8EnBrLUwR
/7rlTXXTZtjga43gjPX1RSA9RuUGB4uUNVT+hmBt/W+hpCVcV4f6eV3E1UoWHAEH
6bEKyeo4Rv4DGoM5UEYzCL3QVKvEfuo0GQcBprsNCo+fQPHpNLf+ZAvqARZVzpsG
q9OiS0PMjDL6nLf1H8ehMQek2EUAS4nRJBH49AKJvz+MThI8peNqNpttnMXu2zO3
kdV5VagHdyFsUmmz9QdptBU//VMIrasxw/drOVyTEY+XFeSW23KoQrIuSPoXuH/4
J/M/AlZlZNa4KMOqdVddl19cp2DGPr9lYsnG2XwzNqlJ3WyiWJhRIeRUf8Sr1s01
cigOHuh4eWWUMBpWG5i1ZgvCbXhLAMEjsk+NAykY1hmLH4XblEk+1TtFTKWxZ9B5
MuA6ZoSfwnWyCmWKFZG7q6la2zIhxhBu8CrnretNZIpYgW/6dvYW19i+9qLI7xH7
SYWoLavlbZ2QLWjbOBRFB5Hp4+xw1i3ehr2Q8NPvH8vaqXBq8Upcl4sHa0Vn87Q1
Q2hyaXN0b3BoZXIgSmFtZXMgSGFsc2UgUm9nZXJzIDxjaHJpc0Bjb29wZXJ0ZWFt
Lm5ldD6JAhwEEAEKAAYFAlmo+VQACgkQGLP1D+WSPBjcSRAAxuqbAvHu3MhkRevx
aPfC4kEk2yY0i4JzEk2Wr8KKqvkdKTwcM1B7X6lzh4ZX9QakOgpzlRIgFj16jGyU
3eOFhRvdNp+lgB6ZgK4+kAGckM/UiCgQfmDL2yFgkUKlnrMoUgiSa8ZmqsF6waZ3
NFqOlRMCGRDs8bPcOyv7mEcuqE/nVmQ8j8Q29f1DcnVe/nlBInO12TV0Ofbhoz/z
vV1ClYyMm+JDUrQE1ozDf6aoXhwJfJHNJCJxII9GQUxT/ke76rt8DgpLfK0xGw3I
qwCqiYyyp8N9F5n4odkvNED3X/uoJb6gs+YLIKOIBBvLEoGIlm76yOBpyNEYpdLZ
YFXYk+mEA069AdHsYoQGB3n9kFJMyDeyRct2TEurXiMWsRV5zOmpaMta1xNnyAg8
XfN0FHO6jEj0HSmcZ+MUxeed8nMk3YasJyp9mhppog4WnomUYLlZ41rCaVbPgJ8j
0MR360nMHKZKyEVImUHtsLuCyGk+kHuxh3o7j9Wr2nVGYjrmKAEWKomlvFsEtUW9
ZnvXAjhQesLefJAXKovmuk1lRFPWuOEVcs74372zSP0sQPQKg01CKiPDyALTQIhE
4zKHZPa6N7HK5DbDzAIXS1RFePLqbQNJ25bBxhBmvWq7Tu3frmJHNQA8GuzDC1Rc
XBQQUigpnoRN35RbDUj9u3jX7qWJAj0EEwEKACcCGwMFCQGLggAICwkIBw0MCwoF
FQoJCAsCHgECF4AFAlmTo9cCGQEACgkQoF7vcIbXMkL6YxAAhTUZMMa5nPKC2IYN
c9AS2jhkssKfUMslM/hn5R8Iw20mlfLuN186UzAR7zr6INWyQ44aXZehLdDU41o2
xXZR0IZ08Ys0cG1xIvxwsyr2jKOCTwDb3K499tGZa7rTlvhYm5GwOWGs/onF1JZt
2asn5yYPOtmb66bwoPkFRyiMP3feI/o47eus2rVU9dMQ82YJ58CBCVvxq0BQAZdq
NzhmxYN0QK90zgn0IiAu4Och1iFEW1VnvfdHO79y7xi7TiEXilBr/I5nMsqdaNrT
8ErtGHTZ95yAClhWcwUEVCrMJaikfnImGdfQA0vHIc8ke9iRJfbWZKLZQBDtNCo7
MiDd5tyyVrGfQBjN6Vy+CHIHDCYEpJP2WlUl5QO0LMyAJNqBOF4JRAHC9HH3rqDt
4mUy0OIm/XzBMMSFAVPb9uGhvN5im1AYxx7ilyatLO/NPFGGy/sNTn5+joZZIJmK
QjhIL8tOrZYrpn2jH0FSCG/ftM/phRSaHowBn8RqZs5n0JXfZahbj/wxjCFF2KH8
0yOnYXn5mUZsvX6Y37T2DXokLcQVO3l6/sgO5qV4jOjJbsRm5t22O7KBIgIX4PTa
4Gsl0WeDz2ysujcLaIZvXWgpYDVMMCNAu8H5UhDFs1EUc2stNogP3TbwYgdvFnyg
drjvcIREs0IA+1H1SaXPtLeM2PSJAlQEEwEKAD4CGwMICwkIBw0MCwoFFQoJCAsC
HgECF4ACGQEWIQQLDTVq0FnH2jOBvhGgXu9whtcyQgUCWx9pXAUJA2ZpXQAKCRCg
Xu9whtcyQrAGD/4itne5M74b0J3FfwLuRdJuK+LkL90zFLJy3JkVw6Xcmk45/RwY
KsG3b2RlqzuX+ETgeF9Ov0Wk7L5I/LrRGR3kT1U6MalexVxrG8M5/34sVRqKNanO
AC6Pecduh+O7SH+FBDR68/qJTYAgjnJ7sYNENJwHTZxFa8FuRbFOum5p4kmAZrCF
BvjCQFUPv35rjSe9ZnUOaMY9lEIr/Q5cDUHm4AVIfOfeUjb09FXxmUi3K46smj2Y
IRTHya5zUr8cJDney9pafJrNi+RUkwG4qDTRpVKLD1k3BlItZ/gcN8wvP+/TM3Gx
g9B8XjxntTvFU4qRQfDclZtTRXHg2ceBTg0G2CvTF3FD3YYOtljhg2SeObjGxiF7
6fTphzIPmSbHocXx4O5up1TVx63QFBvx5nQ09jCXYsAXAR2QmDUal5xRp5TOJgCn
+0KmmYzcmz3FEGJwWPq3D+23q3x6LN8JKWHQbpA04+K5QXRwN53vC+hYHru4tFhO
bG0bt5EsoYPTDI6rB53ZJbikyIcqyvMGnmA1A6OfdMiMxgPfvlf+4VP1GU+NYFKm
Seju2bfEM8L4xFLPUMUr/7BQhV2YCYsUd2FZ2yYjfzrgO6iAJ5eQtjv4suTg5WnD
olsc/TC+9BAJIDFfOgm8YqHB1c2N7eIDOH9KayMOx3B1l+67/kD4aOJzbYkCVAQT
AQoAPgIbAwgLCQgHDQwLCgUVCgkICwIeAQIXgAIZARYhBAsNNWrQWcfaM4G+EaBe
73CG1zJCBQJbYVZ1BQkCuwh2AAoJEKBe73CG1zJCbmMQAI9qmpmQ3F6on2X82Bej
VjixhCAr/gY7+MB9b9up4S8QdrJ1l8UE+BQdbFoHdQoE9iVxxKBwC888TK25clYs
111aw9YI3bWEcLbylqa+8aHSrj0g3BL84z2pwZzGO7bm9zhjMOW0311h71qYa5x8
vi0Ukkkxb3vHo5EvT6gBu1yBGy1nHtHEEHfoxy3SdSxiCb4hJ02Fpn9AQksJ9hCN
yz7Yvj5/g76dFINOiCDaT3gQ7IHqa9Rquq7M7smeZ92W31oEhvcTuw5nmHEmx3sx
pLHPa3vpgDK1UHdco9bhBiO9YmhGfxa1tEKPb306e55WZZSdMT8e4b03hpk39mdJ
5aL80cKk3ZxFia6yEU8W664wprI4ysVgT6Y0CGv53P9iRo/7F4/foNVY+Lhk4mCt
/k2hyW7MrxH/JVT76Di1RUsDvEAgHB/NHRDkbVJFHhxrMdd8Yy8S1WLlqTjtPrdm
IHI5sIzkxmv4AesdA/2CRyBWWxLyBKRvhXxICholEkM/aj+HKmIKGwSVjqxbV7Ud
lpRH39+t1ZuBWvT4sW4pDkebfN6/pyeWRprcjCWl/oF72bLkLXH+yeHnYf7gai9m
o6+7XEiS4QYKlNad3X5pypuz14KdpdhzE9vnDqGjQbZ8b04ZMZYEX89T8AKDAdNV
geXKe5KXsw3e4+1amP+kgQICiQJUBBMBCgA+AhsDCAsJCAcNDAsKBRUKCQgLAh4B
AheAAhkBFiEECw01atBZx9ozgb4RoF7vcIbXMkIFAlwtcHgFCQOHInkACgkQoF7v
cIbXMkImvA/8CCW63v4QV/ZBDR2yWmrTM7EiN2eiBOl9THHWLQrzoDVnVaWQSjZf
w/irEyy5QkyqnlD3BxhVBCF5v+KvB3Ydk+iZ2z5zVR/sJAUy6b18AX8pErJZzCM7
33AEVCTeEuQRIORZG0haGHsIyG5k/wmm6FHYapYS23koMFb9E3Fx5oHS+kQ7+4Lw
9MQfUfV3bC+4Aq99fU1XYIZFSbp1Veu+0e+tIlAKSWVQzx2dyiBoQTj96AEu1QUe
cXDZ5faO9O/HMhBVMDVJQDMwrPG5uYI9E4Vv3B3r3hThIFPpJi4YVqPfiNt3xpok
lV9K+Nkw+Ti1GvLNgwV9pcq49B3QB8BTXF2XDUsnD5l0xsKpg8DAmyHMGavQoMsF
o33RgMkVezhZsYrsh0hHXqqYUY8idKctsmtLHVvgPeYXIyDP2wMdDbaOF6zqk6hv
yM8JBfTArXxpI6deuQdNrPsCqW/uq/HmyPHQKuu05GnODpv+RlZvCcCf5o7bKc4W
nJxZlZeq7fYAbXqJEv7r6dV5wq4OrBlJsZILuCrdyxOmiiO1EDHCOJdqNkAAAvZu
t3fqHE5Frl5RBPWl/163AwP635MjbwNQpmSpuu6pVsjGTDeonXzWDlh+tdjhrz7O
vRhkcHgwsYov+wF2Fj8sZDQuniMTmvY5Hz71YlDcNuyvhVqc80l5tpyJAlQEEwEK
AD4CGwMICwkIBw0MCwoFFQoJCAsCHgECF4ACGQEWIQQLDTVq0FnH2jOBvhGgXu9w
htcyQgUCXJRzIwUJA+4lJAAKCRCgXu9whtcyQh+LD/0XbhrHnaRSC8ZVAG8fmn77
Kb0o7fCPwW/CqMEkq26TI2Ze/qAV2J5Iu54BHl35Q8D92OmfqIoKOum5WnPeUKaZ
MA2gUiOJvnabo+ufFY59dWp2v6KxtfTP0cWtnkdIeAIq1UdhTv7VL7EZ3igunlBY
NdGxOqBtJDGvRcdiCpWK4PvHVcnk3m7XdZmt1+/S26kLNGMgJ9dwgB+ct4GdpQAI
aDGEpO9BKSjKlybRvJQBofDt3FKB5ozFseTHqCN36AcHznJDbImP5/pG01FlDi8i
MMqR2QAKcGBa966NKXEGMHG1KKI2VLN/HePcSw5ooGUV+CAdhYJunaLegfhG2rOJ
fn1tPsWchYHpUjV1sD92A6ePLLqKTXBm4Zx+65akn/7I5q7xJ14IBBDuy3q6PhYJ
81bQYysQz347CORFBXS6yBZhUI8UBism/IYqPfBjCE0Eximi6U8UknfWItdszLVC
P5u7d8j6yFNd60/MxTABkUQ8tZK/N2eePUBQBeLggl4cVr7z0TnfimAce+X14dnO
xmXfRzgenmG5mnQocAX8hne7KX7Dc0nCVDwZLTg0ZvrRQ2GfazmhWehxYyh4mWf6
Ku8D39sW+eimrnvOdK8NRBTFsJAdSF+BaH8V5ouV1M+fy/ZNY4Z6Grc9/osJlhFd
QwRmGLakWbvUUo6v+vQo8rRHQ2hyaXN0b3BoZXIgSmFtZXMgSGFsc2UgUm9nZXJz
IDxjaHJpc3RvcGhlci5oYWxzZS5yb2dlcnNAY2Fub25pY2FsLmNvbT6JAhwEEAEK
AAYFAlmo+VQACgkQGLP1D+WSPBjdFBAAo3cJg0YIWU5DTZ65zpDSehSFo8ND2Paq
PAwUO4LAVk84uoHD6y9AjklyG999wVnjSs7cq07jvJr5A2zyq1lTr7cAcIXvZLVz
t7Jde7VukTORomvhVgfs2O5MQbsw/VS4k5EVu+Z95z9BBrsOfcTqhMpkplPcMZ5P
EvVBlWJ/XrxoJMroX0QVL5fADbQ25KgbARMvi/rFELtEFpjfsAh/gyR+Ki6cje+N
wisqulplwX9/j0g0ylm+W2py7pPMCKYWTtsSMzeToswwKJMc0BpK693+gelLbK4s
sB2DEAgLdeIi4UF+L8+gsIUodqdRH89J7vV4C1xkfFLV0r6aacuZiJFUyeCP3K89
Pw5P+4rGTmwlDUlqzvQK6X/cEwYqiRnFKV1JiYEnrBBceWHJsFuErlvQ+qUX8vcR
VnTF5zu0MzYRS1WDVfrjjHTrfTdPUdSJjIPzL2AfIx4npFARHIj4R09ZJcVwcvou
Rg1ISqUySfPDbt7ol0EokxlTmWW9VF574P31WaABu+WL7c2aSljMS2AwtLOvr+KF
fFyoIZJZnz1XGrzSuwp1Fun48ZhDw9IqFvhyUEgWFSPFw+8DturB3NBu0Za0/lrr
NzbFIYxzyvwQ3KFDBTcSafgcFodw03pvJAK0VgPm3acHDSVHj51F3eMH1RlMAxyz
dSfE2Yh7OryJAjoEEwEKACQFAlmToCMCGwMFCQGLggAICwkIBw0MCwoFFQoJCAsC
HgECF4AACgkQoF7vcIbXMkLvgQ//W70n4+9dtmD2+Q0e0E3fqGVIndCSojVHQjJI
uytRCAxuS1UCGAkO6/kT+0iIMSfw+NuzkeWjf+mvezhQSG5OllFYsSONVOmN7mSB
2oUxNN/oZ6Cma/eWwOABtwIMWCcJaXQ6iBryhf1zRFrFpCVqheyq+dEKRJmCO5Ty
cb22LEeEBiVa2q+jgjW7vA3ds+oUXEcqxEclFofXbktbfHjjsDNg27s0ZGh9/Yj2
+OsgF9R/oejnJgBUoXESW1OkRvG6mI+6WRJIjjMHhvOAAcvvMGADzIniVjialXaL
sWZiceJ5apuv19kKLdmBd5CRFRdxFdfDP0Dkc51Y+DkEXt+xiUHkDJQRoseuijiP
6c4CGmBwA0Tmz6xCXuFpoEfuxRYXFfu2m0DiQXunpjIXQ76uVqe3PMKtm2mQFaNl
NaNTvbC1UXIUCC420gBLOExUSjQ+SJ5L6bM2gwciwJhG+EfexgfVefkIqbtO8ZQJ
lfIQQJiAJwzAmQqwSrEkPz1f6uTFq7aogK7hCZD6WcamGezqeb0dp1jdL28d3BbS
Fze+jbNgrMD2LLrdoOitdEUFicaYfFc1K6IS6HYpviMTHVgt8KHllKsprKS63M3Y
rgFHgm8xxGVKfe9iWa6dtM9b3PZ3XJ77uFHje0xkpEcqzkj2s9O2xM1URKSqRV9F
OHGBUtiJAlEEEwEKADsCGwMICwkIBw0MCwoFFQoJCAsCHgECF4AWIQQLDTVq0FnH
2jOBvhGgXu9whtcyQgUCWx9paQUJA2ZpXQAKCRCgXu9whtcyQluIEACGndwTsQSD
YvTG+ibyToIOjDm1XbjiORc7vhqCImg0l1esaEKf1nPOch1KqK7rTTh+qcjsgzXc
AMhxzQCvbHwpQFycmZSjSlWSk3C19uAMXyEM66s4yBjpVc5MlGRgbbAYB0ooiOm9
eRgjgrqEtrQMWrDkk1/8n6pyyCmkrWVh8Mp1v8NccPAoWsyAzJNhWqaxxMvRxgjH
GwdfbdRVWCtgv6oeZq0eypLL9rqir2KzKZxillgdeOlw69THa++/Ejpq1CEYdPt/
VqTB1pLQm8u8eHg6wz44AN+Lr1WShX+TR3aVaiIhbbE0YwlDI9sGBgnanN/i9CaM
WYMjOUucj3czHd2jVBMksQ6Rkz3OSbrFroKg/jNUNqbWh+HY43UjDIdiq06+gFIq
Tu/xM1JRUwN1BXg3Xml/fY160JbruzvvN6hEzmBFa9Xhq0Airk/032A+Qsw04yh9
YaIJuajrNk82ee/f6gSlzcCAmSZIdTlF85lg0/kpRJTbtiWNyP9HeHSyR7h20JVm
Xys2k8SrYI36Bzo92bbryRNmHB4t28VthqsH9l8OvjGY/jRogQsVW9Qx8YnCM/bZ
vgaAHNdmjO2N3TM5jY5+PkxiDbrCPr1/T/hr4znfPXgolLFkZrCqY1HCVHXlVZw9
WaQeONDxc+rEmsx/EMZs5GHq/X4hKGBcb4kCUQQTAQoAOwIbAwgLCQgHDQwLCgUV
CgkICwIeAQIXgBYhBAsNNWrQWcfaM4G+EaBe73CG1zJCBQJbYVZ7BQkCuwh2AAoJ
EKBe73CG1zJCFXgQAJWZLYyQikx54xeU7OcHdUzcc6nmoaseOMTpd3I9Mt3d0CBn
8JQOEDCTQCz4qHRthsdXgz6pxjjl59K3tv6qkCd/un7RZIW1xfGKgHL7yWv1EKiP
flheszCD0uRBSoVR3qfBNruD9yy2+NrzDyzajo9N8jPnCdP45VY/V+3UhyXpUJhG
18ryv2XPqRlUIFw2QVIwc8ff3i+Tk7zF/Pf896sS66vf7JI4Q5NNgNygEUXsCj0q
DVKpv8/2XdTEc68FWTbdwDLNoXkBRkFhvLH1XVnq7JiUouWn0ELk/Da1IvbJwoZ1
MrlzkSpspcwhmChMHAJcrS6dxMjiyo9M8fbfPfKTQOvr9P4M00i9EWHKgILJEDC2
Gaa8IHihhgbGSdas71jRJWytr1EjOmT82pGzYOUE9OR8pjbj2o+14J8AQGAKHGla
yrSLi21RxrO3ozdOLAS8JFdveOTAYTfViSijbxRcufh0GMFPmA39CqsDNSM7SkkC
gHeiKztR2S5VxKCnAixy2kYxAp1gRMgYFvFECrEP+5x5LQtis36Xv9uh3km4ee/H
ZKEPisLku5c2XGNJsxscl68c9Um4Ike5zgY4D59rowg219RxrJvJkf7EgRuhhJQx
IPdrOLqK1/qu+RH7n/YOO3lyH918LbPzVWeNlYGnJzg2wrWgTg8YCwMwfJOriQJR
BBMBCgA7AhsDCAsJCAcNDAsKBRUKCQgLAh4BAheAFiEECw01atBZx9ozgb4RoF7v
cIbXMkIFAlwtcIIFCQOHInkACgkQoF7vcIbXMkKS6A//UjHAFAIqFi7C3/AlgA8z
GPpCoBeC8hTOGV0c7IGkkhjK0+4gfW9Qj6wMMew/yM4+wSbqtAhATEPLDg9k6LFr
Xn0jTq/mU+zFTLFq+OHk1cmteqgm+uNVS9F/u6gfPKw5KPEsjihuP0JFSQ4o14rO
qyvL4McLEeZW79pJKsUbqKgWGFKJKN7i739HM2MsvLlhhLw572XOdztH0KYy5Blg
qJECerbRd7NwzlcavckW5x7OS9TSwYivqh37mRA9DbMBcOHyDA+ptsntJKBSOD1E
mrSnM8/RSlIXaCinBpdd2D/MkK+44yu/l1XcWq5kt+oQ2pykYJIu3g50LlmCI+3s
DKXT6X+qy4i0SdVP0sggYe+Wij8X8pUqwnje9s8RykDAuQWpQNbm7xo547aGz+/1
Q7ghZydw0qlEtLbageJ2BdK1DmDvJZIHHNkxgheEc7y5pjf9d1Xww1pZ1l8rCHNu
m0mgBZoL3Pd2yAqk5Ec1raG0VJiL/UcO456Qsftko3JhyH5IRYlM/blssnd8eIl0
3509MUMHCJMG2GZDriEc8Qo2f4jqlW72DMeKX+cYBJQcFszu/HGP5ROi8/YIYXym
HYmiWiZc8sgQielHim93ZiIpt28qywBNnGUmYBvr6e2tNAIbIZqExFfGmC9JW6/+
WsoaHfh20D3IGrCKZdIqobeJAlEEEwEKADsCGwMICwkIBw0MCwoFFQoJCAsCHgEC
F4AWIQQLDTVq0FnH2jOBvhGgXu9whtcyQgUCXJRzQQUJA+4lJAAKCRCgXu9whtcy
QpwLD/wMnETj7elIrz4dgsiymRXF09yEgegI4D8xqm3IbXhx3FaVcOJCjuFADWlw
HUAIQBb9n2oVHEK1WkjBlEpTP15DqQe04ZjX+f8PCaPxooNn3WZLXUR2ilEwTvbg
lYT/7y1BLFjW9K0ecaxFTRzja38v3OzNy5wGD0GePbuFDuzVhYRX55wDMgobNq8C
wa0b4F2skyHBzr9IAkB6RZuxN2Ab0dIobYsQZsVOSxAyXzEdt1J9V0rd+TnOMmeZ
VzwuiVTKZvEZuUj8wWlpAffHoSjuzHP2Pa/rlmGrFlZ2A5Bm33Phm822lLLfQwGl
Eli8N6bBGki8EZhe35PCy+yIJI4DWaXS6w7r95YcKoGWuLgzVSYuHEC+9LIs+qat
lojMWSBGl7NTyXHUJ4J2lh1gJSqEzvWvTdD8iCky4WLXmrvHC9Y1S8AgJcqN2jEL
OaUYCw59VhuHqKKirx8XOhqHCQMgkoy9n+0PtzgVkAxND6NtfjeqFTUJHT7YrrZu
XZyhWe7gUtrhzUXaIXh3gAyeaCMH7AnrDOv35hLjq4jv/8nTIV/q7ubSVfQIN2oV
MIGlbFaxRKKSvMu1c9QhMPzPcu9dKe9P40DxhZ/Mko2EsEgrMm2M0g6dajeufQy6
RX7EFbVrKmq3wV3Z0o3WwP0BsoRl+8FWqxCDSMY/SlbZ/ymN6bkCDQRZk6PlARAA
0wwhX7Rq3xrEaZ2+LmgB8iwgBXOFGZ5/cTIC25gRB8MahJj2JmCuTHaV1Q8p3Dma
+hu46QziTm8IjN52ITJPF+Q7RkrGscIaAEZJ8yko7wT7nC7V7x2poDYQJZNoB3tY
kPfyrI/WT7w641LskUiQ1JkMK0e2iASwTZoiLHADN2e/jHusWafDBDqd3ZYEFXfo
zV6iw3ciF2u5ZiDQ8jU8iTrKZA9PvHcr4ifmqhE0ZT5u+ytXaRKH1l18U1dvSHCN
+ryt/sr3Ow1O12XxqjRU8WTOTaSrEoDpEmheuUGfupJXFE+G1pRc9RGtzChTobzo
tyReRb5ZjgnESdakQHsJXOTE4pJLfpeBawnJOk/jbvR9v8NOSK5MUirgDkG16EHa
o62MtND9fnVVZXDQ8xbASLLDvs7Svhu+AgvgIKjkb/DNq8PhJboAkfwfn+JiMv8i
ckDCwNQn/kZdpOEZsZ7/xjJsddud5LMy6FdYSA3GZuNNyQI035GJT3IDRhR94DyM
0qzq5mBqGrWYxrRPP5Yzvvc/0nTiNs8G4Tb+0PvodETFWcgGZEakKOdYOfd+nwA8
8SmihaM0g+tReCUGm0fZCI6hZkirhJC35FQG4GOe1zvtV1WeinkpF66WNZzNr/D+
2EUBEryHTLI4pqMH8o15V40R6U3YyAE0YCqey5iU770AEQEAAYkEWwQYAQoAJgIb
AhYhBAsNNWrQWcfaM4G+EaBe73CG1zJCBQJbYVeQBQkCuwGrAinBXSAEGQEKAAYF
AlmTo+UACgkQ1NtKn10ETxqZVg/+JcV6XanyDRdzZmNHkO7BS6DqL+hv+bKce794
tzzNpJ9WIZPqa/t8YcL22z7UNT1FxCYVsgYCJ47n2LIlVBSc0gVc+yqPgNad9w/5
PzHbC3vW5HtQzAqDdcVIDa595qDk4J9cuSFFu165bNs+8eEgHagcOVeZ/KufALjw
srKHcEGm8M+A8aQwtvDHCfmxDJ8OwgyfuvTQYKCn/xTLR3p98apOC/Jf91he11io
AHwrJ9LJsWw4IwCVFy+/vKNvpTj+vGcoro5JhjmV/HCRTYRMO9Jfdam/ZtsXK53M
ea28oUJiphFTRBlTEjt8g6BonLNdBuL/Z8jBtrfopaq4lfEQynOAZb8koDnOZWfR
9UiIL0lXM5CqpZYOiRG4sMa1P0kDH2s+oKbMs0DfuAl0DdpjUrUEKGuu0K82+u0p
q3v9J8B4rzIV3ZNLS6Z99+jCbIBrQiaHNffIWLP/9Hqd6R7fkfP9dj38pvfH4YvJ
yqz1oqtYB1dyQquxaOr0plO0DO+E8lVxDqCrEkztk0idSsAib/7iXQVFNuxZuVFi
bNBWS4ndq3mGO4iYP5QT0oP9oJD/cCGHmDSvS78GZ25M8Nsww2/sXl2Ph6a6+2kU
dQxQoRJF+J2M4eeoiE86L3ZrpQDjkexqaBC7PvuXplL3QhxaDTKr5REdyll/Ppjd
Ni3GLMcJEKBe73CG1zJCeLsP/iZBv60aJB+AKQEijm4AkA2yrGOcJr9/hVbSxS4/
aW3jXI3Js3+44nwsMYTYHG2ZUhwikG0whnfy9ZvIzOPaKh6IZM+qE+okAMnlu50a
QU5BaH/lFVRiGmz0G/1+S/EWwU8jlqlQBVOVXRkxhu5EB7ZoKJ5U11XOLkB+fPxS
yVGq22PTLJ+FBcCXP9kY/X5bMSUq39txfxwqGkdSiAhK4Vp2nz/ZJyNNm/IyK/AL
Dci/zJdF4OXZ60d048dSamUN56/EtIM0BhaNwBove4gpsnIOjCHmQ5Y4l+5a38ge
WxL8sWmUP5Zm0HU8XLyKBiTKDLJc5tGDHSGQuKmimXJ+MMtzpmU160pf9lO1XqJO
riIAYmqRCuLap5b/mfC7cRLRtr4D6O21wkft8EI6B9T8WzgpDjwnwN1aufrWFvZV
4KXPG5splUwGKHhm27EWQ/F+jhARliSpZBxnEtcqz4jPLNs6hAM4/tsUR8NLDeOQ
+i2Q8iIz8EMb5tYfGeNFGOU/Bp98hMEvL7FPPBNiLgVWF+3XWnwPp1LrtrHSGrRc
Xg0MY/w+3OJtXfe9p+irFIFOnMyYKLYJ0N91Nk3t0a7qvzsyq/1opO+IAoi1Ioea
0WVRIvpcGh5beEV5aRtGFZuUDAie0rOcQHbZDMuFv9uTrFpyGGR0K7FA1+jN3aXq
GtRAiQRbBBgBCgAmAhsCFiEECw01atBZx9ozgb4RoF7vcIbXMkIFAlyUc04FCQPu
HWkCKcFdIAQZAQoABgUCWZOj5QAKCRDU20qfXQRPGplWD/4lxXpdqfINF3NmY0eQ
7sFLoOov6G/5spx7v3i3PM2kn1Yhk+pr+3xhwvbbPtQ1PUXEJhWyBgInjufYsiVU
FJzSBVz7Ko+A1p33D/k/MdsLe9bke1DMCoN1xUgNrn3moOTgn1y5IUW7Xrls2z7x
4SAdqBw5V5n8q58AuPCysodwQabwz4DxpDC28McJ+bEMnw7CDJ+69NBgoKf/FMtH
en3xqk4L8l/3WF7XWKgAfCsn0smxbDgjAJUXL7+8o2+lOP68ZyiujkmGOZX8cJFN
hEw70l91qb9m2xcrncx5rbyhQmKmEVNEGVMSO3yDoGics10G4v9nyMG2t+ilqriV
8RDKc4BlvySgOc5lZ9H1SIgvSVczkKqllg6JEbiwxrU/SQMfaz6gpsyzQN+4CXQN
2mNStQQoa67Qrzb67Smre/0nwHivMhXdk0tLpn336MJsgGtCJoc198hYs//0ep3p
Ht+R8/12Pfym98fhi8nKrPWiq1gHV3JCq7Fo6vSmU7QM74TyVXEOoKsSTO2TSJ1K
wCJv/uJdBUU27Fm5UWJs0FZLid2reYY7iJg/lBPSg/2gkP9wIYeYNK9LvwZnbkzw
2zDDb+xeXY+Hprr7aRR1DFChEkX4nYzh56iITzovdmulAOOR7GpoELs++5emUvdC
HFoNMqvlER3KWX8+mN02LcYsxwkQoF7vcIbXMkLCSQ/+P4offtEj5dxqb/fism9S
sqvW1OPR0xCmF5yEqFF7OPdJZGNeU3VDPl5uhOHYYqSDBo8B8iC9pmANTlQoZOJ4
KyGiuFIXEK6MTFd1bks4k/87aDKqvFWL/BoRoVs1AGvuCbufkC3NperiXsO6m4TS
Nmgw7yydyKyqN927Hh0fjoo6OmrcWRwRTmrmt/gPyRJMQagvexsG6amsNN6ya3rL
8VNZxegQCF2SrpIQsjt57GzdGk7+hhWpTPEny9JdcDM4tF88YTEgS28kYOS3m7Jm
6x9UhQPIcL8egrr6h3vatlg3Mj7IapUsQIVgzWjnZnAloVVv7ZQOnv04spakNEDf
Ph/zJ2fujGxhVYrj9Q18YZXVz1zAOC6EPoRUAxL9eb4B3MFmmTMZq0Y45CYZ0S/1
gtK+D1H1kCuQznGQ0z53YQkFJzTf28ITXtAKW/6A5uz1f197RNx5Y+KD53tWNBla
nZedNiIkiHybGf2KgBHMUujpVWZVVHgpM5x9wbPuuUrRQ/52iVyUErAtbsdUgQMU
kzMOiLgjTZAz70WI2qNbx2ttSFFrSTy9udy48blZrQ2ZpGdfnOhiVHCnlYxiKeqM
S9d3+mGJpqwSvBLwymHgtI0r2AJoO+6mSPNPSrO0U0u0hv3/lOrXg59Z0GR/YzUZ
UZ6AwcpvNrQOlok+WfYliFC5Ag0EWZOkSgEQAN7JyINQoAd4lKY3+26eiLKanA0u
BAsTu1XpnFa21verGnISXncrvSlvTHveGrPrHhu+mq1jZftfCpIBfRTg8xyz3OG0
wnnCGFosvK3fZsfOr+ORCcQFxVVzF9cueXCIqatpFdvHA8FUuN03MJ1nrMGFz2d9
XI5yUDzVNHNjaIYM3w0RPg4q1vg4xL+KKWW6Fs1cSvtN8nCjHgZTJ41E2udyHS29
LL6cIaho49qIIdfwScXpMpghlIHxe55M8ARF92BsOUpBUr2J4nRh0U26Opy4CXmE
wAoylwj5MXixAfdSMUl8a3lDXx4/RHTo9PCSyCDygBe/dYS4EygdVvmeIit1anai
muS8iPfe1VpbdNQPcRQkfL2fYkd0NYNMFx998fBdVPSJH/wq6d6JTCv5VLmyHprU
ON9cVpMLFXMkxqhmL/KreczhiTv8oQuk+RiRLWOkN+sfAOhcLHymIA7gufBt8Iw+
ggUAJOxWoA6QUAsRwor7nCi1EPENKYkEH0dosJZl3NDxjbhhH4tUqznQ+EOGg0dW
2EWtZBPlocjLiMhE7EwKoHY2u/Y7w9Hh/8Bnj/fWXUyhIaVWhkzYISvroGb2YIne
BwJn1cCacofCegBoXF2PeMgDNSPkD5OFzcxvgtNmOqtSZPtfo174/f/f3SMlfPJF
AGMnCcs1I0DqMvPfABEBAAGJAjwEGAEKACYCGwwWIQQLDTVq0FnH2jOBvhGgXu9w
htcyQgUCW2FXkAUJArsBRgAKCRCgXu9whtcyQjBED/48SjmzZKXzJkHUrgOKyIiJ
r3ELJ2DoHkUlGhWceoftZILEajoynDmJ/uM/d8x19H61i73VQmHVopi/x5mXNJOM
QccU5zvQdrXRW3Z106ct0tgaMW23zJP3YSQeXNJfu2ou+zQQwp7wt8I+62tLLlX7
5BzrVVGyagRKu/JOJu0M1w6zNpGvXzYBXJ2WvuVEhDKzfqaWIt4wjAqGqjTmbA7S
2DWg8BxFxY+pz02V1bx7tjK/Ap11wBJiCH1VMG6+rOPurMXa4Jei879IDUXGGQqd
7jy68x2Tjsy7DLhPSdZTN4DO8Y4od2MQKFRSTQNuR89yHqM9RU5Vi023qxq5EX2I
rq0Tl/MM4NwYPLJ4snOWE5WjfJSyAoV81fJQJLYaeO2w1b8JkRC0orD7QUyZNB/T
9Q8MsNW1qDvwoSDNJw9DmyYcUhea0guLSlhGQjlDsvwVfuOoiAaf837UA8ed6o3v
KSRh63SUj9DXI8RRct3IajAvSrzmZK8/9JBgCVRVWNQRpJ2bQfremsSA3uLW3GFb
DFusS2QSx6hh8joVSNR1wV8tXeVKC+1g6zZwSRQWB5do0oN/uzZPxfX9HNh9JcsV
M0X4dYExSqRa35XkheqWVsmzdXHaiza6A1va3uobMbt/CI2+BxnRu+WIbCUx2na2
VdS4pue6E5t3F4N0z5Tc64kCPAQYAQoAJgIbDBYhBAsNNWrQWcfaM4G+EaBe73CG
1zJCBQJclHNZBQkD7h0PAAoJEKBe73CG1zJC0noP/is42EQ7yl3aill/BBqdMr+z
54+W40afIxEr71k87zMSVjQGl5pg2+b4vq8stYbd4IcelOSatAWaq5XvXkc92yLE
OdBjO67bDxm2uZQN3JzB24PbLaQm6s45sk2sCX68wJt3ld+uIO2Xs6cO4YsQdjpl
vuo8HuTk8LHciNfHlQUaYjZJ8yL+mpAt4ER4QCHGpcpaMhFWPaP0UloMnU4LeCaQ
DRpUdkw6/OZ7el4XQ04HOZIVpflR4qZ8fzUcNKt3PcAfvhv5Fau6p2AHLLiSFJwx
p4iTzmdRw6F5fArQmSGqFsmpDrQ469ycRqSXg6PNfZkTcVgLLJi5JswqLFCdvJa/
9F/06l5x6XF8KZDbaie/UkTN69UCvquyZFT0DsS1hxq02m53pMkhXEYzefvsP+/8
IiZCN8Eu0Pq2zQJqd/LaWNHhyQ+zvKxnYR5ihytzrLpQLDmYTFM3SCeJVBAEbClt
PJBGFbICUaPmMKVAlAFA0RlWpJEWdtSzifGFGr7VwH3kntTTY5udWK6DQalcWkp/
W49EfXcMGCBhaHPuWjZyeEkWbcHJyvoRwkFQVfZ32+RXxC+tp8el/aCoYpQYo0uW
Em70HEep28wJ7Qvv45ICRYXBrSST7IDynTggbRoutWowNQwTjSVTyWk3hKnZZDem
LwndVGKu0Gcmoj3BlqmguQINBFmTpMEBEAC4g2QIYGwCmfKYhtvM7ZeA9NMk725E
bocvUvZtbk2kgqT92iYulkOxvkY3Ish+kBYhBkQWNh+U+ilLc6kdd+zsxxctJAiT
9gSSMM9gz9cCG+ZXcYzqVFC/+7CuJGyHsd5KVPObSWelrRFN4EU80qS41yRADuR0
2zxYoNkbK1UERYV+exsWNcaLHh4Jl9I7odNHuty0D6+qHSG7AIEZHd3Wo/dkHkt6
NyuyTy7ZfxEGUmQIyvWAX5ESl6gjrYEaDn4sEcNGx6rbj1qs3kdUg20fZDzRL14v
F4rXBHTRYHwLBPtxW5RvaqZZY1K1DN4jIOAL5BpMWVAwMDK6+ku3s72eQRziAl4P
NljXxuBlI4UFtosZ1pVAS7S4aL3/rt/jwac65r3eoG5rc+/5jsyl5X6mKRLlH7Jt
QAu3QJdhy2XrhL/EpRoEC4XqqExBaDT64uPqRqGuv7UrFGyggTOTBRhu3ylpQflI
iN528yKorc+KQy8uS3ypBc6xLEI8vVWcb5PwEbplFeXTCaGld8G6q5AggYiTgg51
T0S7XMY4Cu0nI3b5TIivBSoArVhtYrV9WTRMDRV1CtJfeI7p4F6O9d1uMu8JIeuy
/bqV2DrjSIEHaU7iBJl+YXnfczgYXBRJpbQaw6VB92vHnXLbenlimYQnB0Tt87mE
9V5VLsiI6bA6PwARAQABiQI8BBgBCgAmAhsgFiEECw01atBZx9ozgb4RoF7vcIbX
MkIFAlthV5AFCQK7AM8ACgkQoF7vcIbXMkIoRw/+P1GnVZmshOVDl8qsljv3mz95
8QjeXZu28kcZEujzQR2eDjoYmTR0HIKX7EXjklQwKPtS9OKvLNeBXA5/qWpg6Eiz
XcZj++H6PX0B4AAzV6XhRGJfmpHtdVJr6POnBThfebGs7DK9rXPX8GQN15MLxu4W
wDW79CazJKIEHIPnsfPwpLUntJxIagcAsqHia/xMlGNJea8G0oGv9XlGXNW0oSBv
HBz5NGkc82nayh/8SnJa4FTHkk3mhGHyfXHOKoI+OoUT5d8Rex7YTNOZWokFYEdq
wWBLRXnJ2fYot5pRk6lt1wPDLObc1UyfHNcopgPFeEUiwAFS9hYp/CUNjsMtnZkR
+4QaGBXSymEKY1LaFDY20sJKKV1Jf1axH7bxVOXoaZcSTMAbA7tAr9ceTNyFXitV
yxa6EpdpKXcXswpNT4hBI8Ep8jkTu9CXmmIJN6/QpTkS0ggHcjClEhlSwQmNyjmC
Zm7PRLn3FSREyLpHvYhyT13Uk4MMHybb3lficDJSOzPyrpfj7JpTVrvAMKrXTD8z
yhpET3l19+1BCYfnzCiH1Ryo10UU0WFR96aQEvAk25+iGIABOwmSNx5+toUl6h6Z
muBtyTgkxTEWvgBkc6rYBHa510iwxnoZExhpFkIjy1aRt94Wozm0G8zBwhDVzTSi
1AUXB4rc1He6dmefjQiJAjwEGAEKACYCGyAWIQQLDTVq0FnH2jOBvhGgXu9whtcy
QgUCXJRzaAUJA+4cpwAKCRCgXu9whtcyQtEvD/9DbVWLPtFLmd1Kxhe5uZUaiO1O
hcWX8zrjtJ08JBI/fQbwakVqZeDCXvk+E3zkql8dIMnXXpz2lirIUolzCSiuXrDX
SUXpBy1PSC0/HLml+/C8g9/Xwh7WiFlGGZv8YuggEP5z3xdXQpR2B9gtKOv7oUwo
vt/TmXqY0btT1TGGghJ9a/Z5PmUOIub2m+IMNWoqvXggim1OajxnrremPKDvC+XI
ccbT5kuclAhHJkxMJdEbB3QVGVmGsd26VcC8JqoczAmbZgcz+aTeaLb0hI2hxDVQ
aYcUs0XM/5s+f7f5qU9Le9oyDm9OJ49tS3vnW/vy8h3YeWU6AidPNwU1q9amcrmd
5XNXv8TXK1zKj3jdReCjyV5vFGan0Db9fewddNa7lkX8UoFiyWru4FSyHhy0krf0
W5D9D2M7Gpvu50VdBsjOBGqg1O1gHTNUIghRMSQKYlP7OF0k10AJngyk9+v7snXW
0B9Semadwpw02YOcVc1G/zj4+vsyeV12dv1Mxq5+pGCMjUAIHNCa+2GWY4Bgg5DI
Yy0Z6naCgl9lUaT9i0JIJuyZUkK+g9HFGOnEsM0bR/vYSB28HNE8N6W/+HYTbtaH
l5XY1qpzdwyC9JyQcLY0PFELkdHSvQ/HyUmGjfnNqNWhy7YMn9jlWTiMlf8f3rS7
cRWQ6eS6adR9VqmKfg==
=Ot1v
-----END PGP PUBLIC KEY BLOCK-----
wlcs-1.7.0/debian/watch 0000664 0000000 0000000 00000000263 14536573575 0014767 0 ustar 00root root 0000000 0000000 # Compulsory line, this is a version 4 file
version=4
version=4
opts="pgpsigurlmangle=s/$/.asc/" \
https://github.com/MirServer/wlcs/releases/latest .*/wlcs-(\d\S+)\.tar\.xz
wlcs-1.7.0/example/ 0000775 0000000 0000000 00000000000 14536573575 0014146 5 ustar 00root root 0000000 0000000 wlcs-1.7.0/example/mir_integration.cpp 0000664 0000000 0000000 00000065547 14536573575 0020065 0 ustar 00root root 0000000 0000000 /*
* Copyright © 2017 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authored by: Christopher James Halse Rogers
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "display_server.h"
#include "pointer.h"
#include "touch.h"
#include "mutex.h"
#include "mir/fd.h"
#include "mir/server.h"
#include "mir/options/option.h"
#include "mir_test_framework/async_server_runner.h"
#include "mir_test_framework/headless_display_buffer_compositor_factory.h"
#include "mir_test_framework/executable_path.h"
#include "mir_test_framework/stub_server_platform_factory.h"
#include "mir_test_framework/fake_input_device.h"
#include "mir/input/device_capability.h"
#include "mir/input/input_device_info.h"
#include "mir/test/doubles/mock_gl.h"
#include "mir/frontend/session.h"
#include "mir/scene/session_listener.h"
#include "mir/scene/surface.h"
#include "mir/scene/session.h"
#include "mir/test/signal.h"
namespace mtf = mir_test_framework;
namespace mi = mir::input;
namespace mf = mir::frontend;
using namespace std::chrono_literals;
namespace std
{
// std::chrono::nanoseconds doesn't have a standard hash<> implementation?!
template<>
struct hash<::std::chrono::nanoseconds>
{
typedef std::chrono::nanoseconds argument_type;
typedef size_t result_type;
result_type operator()(argument_type const& arg) const noexcept
{
/*
* The underlying type of std::chrono::nanoseconds is guaranteed to be an
* integer of at least 50-something bits, which will already have a perfectly
* functional std::hash<> implementation…
*/
return std::hash{}(arg.count());
}
};
}
namespace
{
auto constexpr a_long_time = 5s;
using ClientFd = int;
class ResourceMapper : public mir::scene::SessionListener
{
public:
ResourceMapper()
: listeners{&this->state}
{
}
void starting(std::shared_ptr const&) override
{
}
void stopping(std::shared_ptr const&) override
{
}
void focused(std::shared_ptr const&) override
{
}
void unfocused() override
{
}
void surface_created(
mir::scene::Session&,
std::shared_ptr const& surface) override
{
auto state_accessor = state.lock();
if (std::this_thread::get_id() == state_accessor->wayland_thread)
{
if (listeners.last_wl_window == nullptr)
{
BOOST_THROW_EXCEPTION((
std::runtime_error{
"Called Shell::create_surface() without first creating a wl_shell_surface?"}));
}
auto stream = surface->primary_buffer_stream();
auto wl_surface = state_accessor->stream_map.at(stream);
state_accessor->surface_map[wl_surface] = surface;
}
}
void destroying_surface(
mir::scene::Session&,
std::shared_ptr const&) override
{
// TODO: Maybe delete from map?
}
void buffer_stream_created(
mir::scene::Session&,
std::shared_ptr const& stream) override
{
auto state_accessor = state.lock();
if (std::this_thread::get_id() == state_accessor->wayland_thread)
{
if (listeners.last_wl_surface == nullptr)
{
BOOST_THROW_EXCEPTION((
std::runtime_error{"BufferStream created without first constructing a wl_surface?"}));
}
state_accessor->stream_map[stream] = listeners.last_wl_surface;
listeners.last_wl_surface = nullptr;
}
}
void buffer_stream_destroyed(
mir::scene::Session&,
std::shared_ptr const& stream) override
{
state.lock()->stream_map.erase(stream);
}
void init(wl_display* display)
{
state.lock()->wayland_thread = std::this_thread::get_id();
listeners.client_listener.notify = &client_created;
wl_display_add_client_created_listener(display, &listeners.client_listener);
}
std::weak_ptr surface_for_resource(wl_resource* surface)
{
if (strcmp(wl_resource_get_class(surface), "wl_surface") != 0)
{
BOOST_THROW_EXCEPTION((
std::logic_error{
std::string{"Expected a wl_surface, got: "} +
wl_resource_get_class(surface)
}));
}
auto state_accessor = state.lock();
return state_accessor->surface_map.at(surface);
}
wl_client* client_for_fd(int client_socket)
{
return listeners.state->lock()->client_session_map.at(client_socket);
}
void associate_client_socket(int client_socket)
{
auto state_accessor = state.wait_for(
[](State& state) { return static_cast(state.latest_client) ; },
std::chrono::seconds{30});
state_accessor->client_session_map[client_socket] = state_accessor->latest_client.value();
state_accessor->latest_client = {};
}
private:
struct Listeners;
struct ResourceListener
{
ResourceListener(Listeners* const listeners)
: listeners{listeners}
{
}
wl_listener resource_listener;
Listeners* const listeners;
};
struct State
{
std::thread::id wayland_thread;
std::unordered_map> surface_map;
std::unordered_map, wl_resource*> stream_map;
std::optional latest_client;
std::unordered_map client_session_map;
std::unordered_map resource_listener;
};
wlcs::WaitableMutex state;
struct Listeners
{
Listeners(wlcs::WaitableMutex* const state)
: state{state}
{
}
wl_listener client_listener;
wl_resource* last_wl_surface{nullptr};
wl_resource* last_wl_window{nullptr};
wlcs::WaitableMutex* const state;
} listeners;
static void resource_created(wl_listener* listener, void* ctx)
{
auto resource = static_cast(ctx);
ResourceListener* resource_listener;
resource_listener =
wl_container_of(listener, resource_listener, resource_listener);
bool const is_surface = strcmp(
wl_resource_get_class(resource),
"wl_surface") == 0;
bool const is_window = strcmp(
wl_resource_get_class(resource),
"wl_shell_surface") == 0 ||
strcmp(
wl_resource_get_class(resource),
"zxdg_surface_v6") == 0;
if (is_surface)
{
resource_listener->listeners->last_wl_surface = resource;
}
else if (is_window)
{
resource_listener->listeners->last_wl_window = resource;
}
}
static void client_created(wl_listener* listener, void* ctx)
{
auto client = static_cast(ctx);
Listeners* listeners;
listeners =
wl_container_of(listener, listeners, client_listener);
wl_listener* resource_listener;
{
auto state_accessor = listeners->state->lock();
state_accessor->latest_client = client;
auto rl = state_accessor->resource_listener.emplace(client, listeners);
rl.first->second.resource_listener.notify = &resource_created;
resource_listener = &rl.first->second.resource_listener;
}
listeners->state->notify_all();
wl_client_add_resource_created_listener(client, resource_listener);
}
};
namespace
{
class WaylandExecutor : public mir::Executor
{
public:
void spawn (std::function&& work) override
{
{
std::lock_guard lock{mutex};
workqueue.emplace_back(std::move(work));
}
if (auto err = eventfd_write(notify_fd, 1))
{
BOOST_THROW_EXCEPTION((std::system_error{err, std::system_category(), "eventfd_write failed to notify event loop"}));
}
}
/**
* Get an Executor which dispatches onto a wl_event_loop
*
* \note The executor may outlive the wl_event_loop, but no tasks will be dispatched
* after the wl_event_loop is destroyed.
*
* \param [in] loop The event loop to dispatch on
* \return An Executor that queues onto the wl_event_loop
*/
static std::shared_ptr executor_for_event_loop(wl_event_loop* loop)
{
if (auto notifier = wl_event_loop_get_destroy_listener(loop, &on_display_destruction))
{
DestructionShim* shim;
shim = wl_container_of(notifier, shim, destruction_listener);
return shim->executor;
}
else
{
auto const executor = std::shared_ptr{new WaylandExecutor{loop}};
auto shim = std::make_unique(executor);
shim->destruction_listener.notify = &on_display_destruction;
wl_event_loop_add_destroy_listener(loop, &(shim.release())->destruction_listener);
return executor;
}
}
private:
WaylandExecutor(wl_event_loop* loop)
: notify_fd{eventfd(0, EFD_CLOEXEC | EFD_SEMAPHORE | EFD_NONBLOCK)},
notify_source{wl_event_loop_add_fd(loop, notify_fd, WL_EVENT_READABLE, &on_notify, this)}
{
if (notify_fd == mir::Fd::invalid)
{
BOOST_THROW_EXCEPTION((std::system_error{
errno,
std::system_category(),
"Failed to create IPC pause notification eventfd"}));
}
}
std::function get_work()
{
std::lock_guard lock{mutex};
if (!workqueue.empty())
{
auto const work = std::move(workqueue.front());
workqueue.pop_front();
return work;
}
return {};
}
static int on_notify(int fd, uint32_t, void* data)
{
auto executor = static_cast(data);
eventfd_t unused;
if (auto err = eventfd_read(fd, &unused))
{
mir::log(
mir::logging::Severity::error,
"wlcs-integration",
"eventfd_read failed to consume wakeup notification: %s (%i)",
strerror(err),
err);
}
std::unique_lock lock{executor->mutex};
while (auto work = executor->get_work())
{
try
{
work();
}
catch(...)
{
mir::log(
mir::logging::Severity::critical,
"wlcs-integration",
std::current_exception(),
"Exception processing Wayland event loop work item");
}
}
return 0;
}
static void on_display_destruction(wl_listener* listener, void*)
{
DestructionShim* shim;
shim = wl_container_of(listener, shim, destruction_listener);
{
std::lock_guard lock{shim->executor->mutex};
wl_event_source_remove(shim->executor->notify_source);
}
delete shim;
}
std::recursive_mutex mutex;
mir::Fd const notify_fd;
std::deque> workqueue;
wl_event_source* const notify_source;
struct DestructionShim
{
explicit DestructionShim(std::shared_ptr const& executor)
: executor{executor}
{
}
std::shared_ptr const executor;
wl_listener destruction_listener;
};
static_assert(
std::is_standard_layout::value,
"DestructionShim must be Standard Layout for wl_container_of to be defined behaviour");
};
}
class InputEventListener;
struct MirWlcsDisplayServer : mtf::AsyncServerRunner
{
testing::NiceMock mockgl;
std::shared_ptr const resource_mapper{std::make_shared()};
std::shared_ptr event_listener;
std::shared_ptr executor;
std::atomic cursor_x{0}, cursor_y{0};
mir::test::Signal started;
};
class InputEventListener : public mir::input::SeatObserver
{
public:
InputEventListener(MirWlcsDisplayServer& runner)
: runner{runner}
{
}
std::shared_ptr expect_event_with_time(
std::chrono::nanoseconds event_time)
{
auto done_signal = std::make_shared();
expected_events.lock()->insert(std::make_pair(event_time, done_signal));
return done_signal;
}
void seat_add_device(uint64_t /*id*/) override
{
}
void seat_remove_device(uint64_t /*id*/) override
{
}
void seat_dispatch_event(std::shared_ptr const& event) override
{
auto iev = mir_event_get_input_event(event.get());
auto event_time = std::chrono::nanoseconds{mir_input_event_get_event_time(iev)};
auto expected_events_accessor = expected_events.lock();
if (expected_events_accessor->count(event_time))
{
expected_events_accessor->at(event_time)->raise();
expected_events_accessor->erase(event_time);
}
}
void seat_set_key_state(
uint64_t /*id*/,
std::vector const& /*scan_codes*/) override
{
}
void seat_set_pointer_state(
uint64_t /*id*/,
unsigned /*buttons*/) override
{
}
void seat_set_cursor_position(
float cursor_x,
float cursor_y) override
{
runner.cursor_x = cursor_x;
runner.cursor_y = cursor_y;
}
void seat_set_confinement_region_called(
mir::geometry::Rectangles const& /*regions*/) override
{
}
void seat_reset_confinement_regions() override
{
}
private:
wlcs::Mutex>> expected_events;
MirWlcsDisplayServer& runner;
};
template
void emit_mir_event(MirWlcsDisplayServer* runner,
mir::UniqueModulePtr& emitter,
T event)
{
auto event_time = std::chrono::duration_cast(
std::chrono::steady_clock::now().time_since_epoch());
auto event_sent = runner->event_listener->expect_event_with_time(event_time);
emitter->emit_event(event.with_event_time(event_time));
EXPECT_THAT(event_sent->wait_for(a_long_time), testing::Eq(true)) << "fake event failed to go through";
}
}
void wlcs_server_start(WlcsDisplayServer* server)
{
auto runner = reinterpret_cast(server);
runner->start_server();
runner->started.wait_for(a_long_time);
}
void wlcs_server_stop(WlcsDisplayServer* server)
{
auto runner = reinterpret_cast(server);
runner->stop_server();
}
WlcsDisplayServer* wlcs_create_server(int argc, char const** argv)
{
auto runner = new MirWlcsDisplayServer;
runner->add_to_environment("MIR_SERVER_PLATFORM_GRAPHICS_LIB", mtf::server_platform("graphics-dummy.so").c_str());
runner->add_to_environment("MIR_SERVER_PLATFORM_INPUT_LIB", mtf::server_platform("input-stub.so").c_str());
runner->add_to_environment("MIR_SERVER_ENABLE_KEY_REPEAT", "false");
runner->add_to_environment("MIR_SERVER_NO_FILE", "");
runner->add_to_environment("MIR_SERVER_WAYLAND_SOCKET_NAME", "wlcs-tests");
runner->add_to_environment("WAYLAND_DISPLAY", "wlcs-tests");
runner->server.override_the_display_buffer_compositor_factory([]
{
return std::make_shared();
});
runner->server.override_the_session_listener(
[runner]()
{
return runner->resource_mapper;
});
runner->event_listener = std::make_shared(*runner);
runner->server.set_command_line(argc, argv);
runner->server.add_init_callback(
[runner]()
{
runner->server.run_on_wayland_display(
[runner](auto wayland_display)
{
runner->resource_mapper->init(wayland_display);
runner->executor = WaylandExecutor::executor_for_event_loop(
wl_display_get_event_loop(wayland_display));
// Execute all observations on the Wayland event loop…
runner->server.the_seat_observer_registrar()->register_interest(
runner->event_listener,
*runner->executor);
runner->started.raise();
});
});
runner->server.wrap_cursor_listener(
[runner](auto const& wrappee)
{
class ListenerWrapper : public mir::input::CursorListener
{
public:
ListenerWrapper(
MirWlcsDisplayServer* runner,
std::shared_ptr const& wrapped)
: runner{runner},
wrapped{wrapped}
{
}
void cursor_moved_to(float abs_x, float abs_y) override
{
runner->cursor_x = abs_x;
runner->cursor_y = abs_y;
wrapped->cursor_moved_to(abs_x, abs_y);
}
private:
MirWlcsDisplayServer* const runner;
std::shared_ptr const wrapped;
};
return std::make_shared(runner, wrappee);
});
return reinterpret_cast(runner);
}
void wlcs_destroy_server(WlcsDisplayServer* server)
{
auto runner = reinterpret_cast(server);
delete runner;
}
int wlcs_server_create_client_socket(WlcsDisplayServer* server)
{
auto runner = reinterpret_cast(server);
try
{
auto client_fd = fcntl(
runner->server.open_wayland_client_socket(),
F_DUPFD_CLOEXEC,
3);
runner->resource_mapper->associate_client_socket(client_fd);
return client_fd;
}
catch (std::exception const&)
{
mir::log(
mir::logging::Severity::critical,
"wlcs-bindings",
std::current_exception(),
"Failed to create Wayland client socket");
}
return -1;
}
struct FakePointer
{
decltype(mtf::add_fake_input_device(mi::InputDeviceInfo())) pointer;
MirWlcsDisplayServer* runner;
};
WlcsPointer* wlcs_server_create_pointer(WlcsDisplayServer* server)
{
auto runner = reinterpret_cast(server);
auto constexpr uid = "mouse-uid";
class DeviceObserver : public mir::input::InputDeviceObserver
{
public:
DeviceObserver(std::shared_ptr const& done)
: done{done}
{
}
void device_added(std::shared_ptr const& device) override
{
if (device->unique_id() == uid)
seen_device = true;
}
void device_changed(std::shared_ptr const&) override
{
}
void device_removed(std::shared_ptr const&) override
{
}
void changes_complete() override
{
if (seen_device)
done->raise();
}
private:
std::shared_ptr const done;
bool seen_device{false};
};
auto mouse_added = std::make_shared();
auto observer = std::make_shared(mouse_added);
runner->server.the_input_device_hub()->add_observer(observer);
auto fake_mouse = mtf::add_fake_input_device(
mi::InputDeviceInfo{"mouse", uid, mi::DeviceCapability::pointer});
mouse_added->wait_for(a_long_time);
runner->executor->spawn([observer=std::move(observer), the_input_device_hub=runner->server.the_input_device_hub()]
{ the_input_device_hub->remove_observer(observer); });
auto fake_pointer = new FakePointer;
fake_pointer->runner = runner;
fake_pointer->pointer = std::move(fake_mouse);
return reinterpret_cast(fake_pointer);
}
void wlcs_destroy_pointer(WlcsPointer* pointer)
{
delete reinterpret_cast(pointer);
}
void wlcs_pointer_move_relative(WlcsPointer* pointer, wl_fixed_t x, wl_fixed_t y)
{
auto device = reinterpret_cast(pointer);
auto event = mir::input::synthesis::a_pointer_event()
.with_movement(wl_fixed_to_int(x), wl_fixed_to_int(y));
emit_mir_event(device->runner, device->pointer, event);
}
void wlcs_pointer_move_absolute(WlcsPointer* pointer, wl_fixed_t x, wl_fixed_t y)
{
auto device = reinterpret_cast(pointer);
auto rel_x = wl_fixed_to_double(x) - device->runner->cursor_x;
auto rel_y = wl_fixed_to_double(y) - device->runner->cursor_y;
wlcs_pointer_move_relative(pointer, wl_fixed_from_double(rel_x), wl_fixed_from_double(rel_y));
}
void wlcs_pointer_button_down(WlcsPointer* pointer, int button)
{
auto device = reinterpret_cast(pointer);
auto event = mir::input::synthesis::a_button_down_event()
.of_button(button);
emit_mir_event(device->runner, device->pointer, event);
}
void wlcs_pointer_button_up(WlcsPointer* pointer, int button)
{
auto device = reinterpret_cast(pointer);
auto event = mir::input::synthesis::a_button_up_event()
.of_button(button);
emit_mir_event(device->runner, device->pointer, event);
}
struct FakeTouch
{
decltype(mtf::add_fake_input_device(mi::InputDeviceInfo())) touch;
int last_x{0}, last_y{0};
MirWlcsDisplayServer* runner;
};
WlcsTouch* wlcs_server_create_touch(WlcsDisplayServer* server)
{
auto runner = reinterpret_cast(server);
auto constexpr uid = "touch-uid";
class DeviceObserver : public mir::input::InputDeviceObserver
{
public:
DeviceObserver(std::shared_ptr const& done)
: done{done}
{
}
void device_added(std::shared_ptr const& device) override
{
if (device->unique_id() == uid)
seen_device = true;
}
void device_changed(std::shared_ptr const&) override
{
}
void device_removed(std::shared_ptr const&) override
{
}
void changes_complete() override
{
if (seen_device)
done->raise();
}
private:
std::shared_ptr const done;
bool seen_device{false};
};
auto touch_added = std::make_shared();
auto observer = std::make_shared(touch_added);
runner->server.the_input_device_hub()->add_observer(observer);
auto fake_touch_dev = mtf::add_fake_input_device(
mi::InputDeviceInfo{"touch", uid, mi::DeviceCapability::multitouch});
touch_added->wait_for(a_long_time);
runner->executor->spawn([observer=std::move(observer), the_input_device_hub=runner->server.the_input_device_hub()]
{ the_input_device_hub->remove_observer(observer); });
auto fake_touch = new FakeTouch;
fake_touch->runner = runner;
fake_touch->touch = std::move(fake_touch_dev);
return reinterpret_cast(fake_touch);
}
void wlcs_destroy_touch(WlcsTouch* touch)
{
delete reinterpret_cast(touch);
}
void wlcs_touch_down(WlcsTouch* touch, int x, int y)
{
auto device = reinterpret_cast(touch);
device->last_x = x;
device->last_y = y;
auto event = mir::input::synthesis::a_touch_event()
.with_action(mir::input::synthesis::TouchParameters::Action::Tap)
.at_position({x, y});
emit_mir_event(device->runner, device->touch, event);
}
void wlcs_touch_move(WlcsTouch* touch, int x, int y)
{
auto device = reinterpret_cast(touch);
device->last_x = x;
device->last_y = y;
auto event = mir::input::synthesis::a_touch_event()
.with_action(mir::input::synthesis::TouchParameters::Action::Move)
.at_position({x, y});
emit_mir_event(device->runner, device->touch, event);
}
void wlcs_touch_up(WlcsTouch* touch)
{
auto device = reinterpret_cast(touch);
auto event = mir::input::synthesis::a_touch_event()
.with_action(mir::input::synthesis::TouchParameters::Action::Release)
.at_position({device->last_x, device->last_y});
emit_mir_event(device->runner, device->touch, event);
}
void wlcs_server_position_window_absolute(WlcsDisplayServer* server, wl_display* client, wl_surface* surface, int x, int y)
{
auto runner = reinterpret_cast(server);
try
{
auto const fd = wl_display_get_fd(client);
auto const client = runner->resource_mapper->client_for_fd(fd);
auto const id = wl_proxy_get_id(reinterpret_cast(surface));
auto resource = wl_client_get_object(client, id);
auto mir_surface = runner->resource_mapper->surface_for_resource(resource);
if (auto live_surface = mir_surface.lock())
{
live_surface->move_to(mir::geometry::Point{x, y});
}
else
{
abort();
// TODO: log? Error handling?
}
}
catch(std::out_of_range const&)
{
abort();
// TODO: Error handling.
}
}
wlcs-1.7.0/include/ 0000775 0000000 0000000 00000000000 14536573575 0014136 5 ustar 00root root 0000000 0000000 wlcs-1.7.0/include/active_listeners.h 0000664 0000000 0000000 00000002532 14536573575 0017654 0 ustar 00root root 0000000 0000000 /*
* Copyright © 2019 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authored by: Alan Griffiths
*/
#ifndef WLCS_ACTIVE_LISTENERS_H
#define WLCS_ACTIVE_LISTENERS_H
#include
#include
namespace wlcs
{
class ActiveListeners
{
public:
void add(void* listener)
{
std::lock_guard lock{mutex};
listeners.insert(listener);
}
void del(void* listener)
{
std::lock_guard lock{mutex};
listeners.erase(listener);
}
bool includes(void* listener) const
{
std::lock_guard lock{mutex};
return listeners.find(listener) != end(listeners);
}
private:
std::mutex mutable mutex;
std::set listeners;
};
}
#endif //WLCS_ACTIVE_LISTENERS_H
wlcs-1.7.0/include/data_device.h 0000664 0000000 0000000 00000012334 14536573575 0016542 0 ustar 00root root 0000000 0000000 /*
* Copyright © 2018 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authored by: Alan Griffiths
*/
#ifndef WLCS_DATA_DEVICE_H
#define WLCS_DATA_DEVICE_H
#include "active_listeners.h"
#include "wl_interface_descriptor.h"
#include "wl_handle.h"
#include
#include
namespace wlcs
{
WLCS_CREATE_INTERFACE_DESCRIPTOR(wl_data_device_manager)
class DataSource
{
public:
DataSource() = default;
explicit DataSource(struct wl_data_source* ds) : self{ds, deleter} {}
operator struct wl_data_source*() const { return self.get(); }
void reset() { self.reset(); }
void reset(struct wl_data_source* ds) { self.reset(ds, deleter); }
friend void wl_data_source_destroy(DataSource const&) = delete;
private:
static void deleter(struct wl_data_source* ds) { wl_data_source_destroy(ds); }
std::shared_ptr self;
};
struct DataDeviceListener
{
DataDeviceListener(struct wl_data_device* data_device)
{
active_listeners.add(this);
wl_data_device_add_listener(data_device, &thunks, this);
}
virtual ~DataDeviceListener() { active_listeners.del(this); }
DataDeviceListener(DataDeviceListener const&) = delete;
DataDeviceListener& operator=(DataDeviceListener const&) = delete;
virtual void data_offer(
struct wl_data_device* wl_data_device,
struct wl_data_offer* id);
virtual void enter(
struct wl_data_device* wl_data_device,
uint32_t serial,
struct wl_surface* surface,
wl_fixed_t x,
wl_fixed_t y,
struct wl_data_offer* id);
virtual void leave(struct wl_data_device* wl_data_device);
virtual void motion(
struct wl_data_device* wl_data_device,
uint32_t time,
wl_fixed_t x,
wl_fixed_t y);
virtual void drop(struct wl_data_device* wl_data_device);
virtual void selection(
struct wl_data_device* wl_data_device,
struct wl_data_offer* id);
private:
static void data_offer(
void* data,
struct wl_data_device* wl_data_device,
struct wl_data_offer* id);
static void enter(
void* data,
struct wl_data_device* wl_data_device,
uint32_t serial,
struct wl_surface* surface,
wl_fixed_t x,
wl_fixed_t y,
struct wl_data_offer* id);
static void leave(void* data, struct wl_data_device* wl_data_device);
static void motion(
void* data,
struct wl_data_device* wl_data_device,
uint32_t time,
wl_fixed_t x,
wl_fixed_t y);
static void drop(void* data, struct wl_data_device* wl_data_device);
static void selection(
void* data,
struct wl_data_device* wl_data_device,
struct wl_data_offer* id);
static ActiveListeners active_listeners;
constexpr static wl_data_device_listener thunks =
{
&data_offer,
&enter,
&leave,
&motion,
&drop,
&selection
};
};
struct DataOfferListener
{
DataOfferListener() { active_listeners.add(this); }
virtual ~DataOfferListener() { active_listeners.del(this); }
DataOfferListener(DataOfferListener const&) = delete;
DataOfferListener& operator=(DataOfferListener const&) = delete;
void listen_to(struct wl_data_offer* data_offer)
{
wl_data_offer_add_listener(data_offer, &thunks, this);
}
virtual void offer(struct wl_data_offer* data_offer, char const* mime_type);
virtual void source_actions(struct wl_data_offer* data_offer, uint32_t dnd_actions);
virtual void action(struct wl_data_offer* data_offer, uint32_t dnd_action);
private:
static void offer(void* data, struct wl_data_offer* data_offer, char const* mime_type);
static void source_actions(void* data, struct wl_data_offer* data_offer, uint32_t dnd_actions);
static void action(void* data, struct wl_data_offer* data_offer, uint32_t dnd_action);
static ActiveListeners active_listeners;
constexpr static wl_data_offer_listener thunks =
{
&offer,
&source_actions,
&action
};
};
class DataDevice
{
public:
DataDevice() = default;
explicit DataDevice(struct wl_data_device* dd) : self{dd, deleter} {}
operator struct wl_data_device*() const { return self.get(); }
void reset() { self.reset(); }
void reset(struct wl_data_device* dd) { self.reset(dd, deleter); }
friend void wl_data_device_destroy(DataDevice const&) = delete;
private:
static void deleter(struct wl_data_device* dd) { wl_data_device_destroy(dd); }
std::shared_ptr self;
};
}
#endif //WLCS_DATA_DEVICE_H
wlcs-1.7.0/include/geometry/ 0000775 0000000 0000000 00000000000 14536573575 0015771 5 ustar 00root root 0000000 0000000 wlcs-1.7.0/include/geometry/dimensions.h 0000664 0000000 0000000 00000025722 14536573575 0020322 0 ustar 00root root 0000000 0000000 /*
* Copyright © Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License version 2 or 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*/
#ifndef WLCS_GEOMETRY_DIMENSIONS_H_
#define WLCS_GEOMETRY_DIMENSIONS_H_
#include "forward.h"
#include
#include
#include
namespace wlcs
{
namespace generic
{
template
/// Wraps a geometry value and prevents it from being accidentally used for invalid operations (such as setting a
/// width to a height or adding two x positions together). Of course, explicit casts are possible to get around
/// these restrictions (see the as_*() functions).
struct Value
{
using ValueType = T;
using TagType = Tag;
template
constexpr typename std::enable_if::value, int>::type as_int() const
{
return this->value;
}
template
constexpr typename std::enable_if::value, uint32_t>::type as_uint32_t() const
{
return this->value;
}
constexpr T as_value() const noexcept
{
return value;
}
constexpr Value() noexcept : value{} {}
Value& operator=(Value const& that) noexcept
{
value = that.value;
return *this;
}
constexpr Value(Value const& that) noexcept
: value{that.value}
{
}
template
explicit constexpr Value(Value const& value) noexcept
: value{static_cast(value.as_value())}
{
}
template::value, bool>::type = true>
explicit constexpr Value(U const& value) noexcept
: value{static_cast(value)}
{
}
inline constexpr auto operator == (Value const& rhs) const -> bool
{
return value == rhs.as_value();
}
inline constexpr auto operator != (Value const& rhs) const -> bool
{
return value != rhs.as_value();
}
inline constexpr auto operator <= (Value const& rhs) const -> bool
{
return value <= rhs.as_value();
}
inline constexpr auto operator >= (Value const& rhs) const -> bool
{
return value >= rhs.as_value();
}
inline constexpr auto operator < (Value const& rhs) const -> bool
{
return value < rhs.as_value();
}
inline constexpr auto operator > (Value const& rhs) const -> bool
{
return value > rhs.as_value();
}
protected:
T value;
};
template
std::ostream& operator<<(std::ostream& out, Value const& value)
{
out << value.as_value();
return out;
}
// Adding deltas is fine
template
inline constexpr DeltaX operator+(DeltaX lhs, DeltaX rhs){ return DeltaX(lhs.as_value() + rhs.as_value()); }
template
inline constexpr DeltaY operator+(DeltaY lhs, DeltaY rhs) { return DeltaY(lhs.as_value() + rhs.as_value()); }
template
inline constexpr DeltaX operator-(DeltaX lhs, DeltaX rhs) { return DeltaX(lhs.as_value() - rhs.as_value()); }
template
inline constexpr DeltaY operator-(DeltaY lhs, DeltaY rhs) { return DeltaY(lhs.as_value() - rhs.as_value()); }
template
inline constexpr DeltaX operator-(DeltaX rhs) { return DeltaX(-rhs.as_value()); }
template
inline constexpr DeltaY operator-(DeltaY rhs) { return DeltaY(-rhs.as_value()); }
template
inline DeltaX& operator+=(DeltaX& lhs, DeltaX rhs) { return lhs = lhs + rhs; }
template
inline DeltaY& operator+=(DeltaY& lhs, DeltaY rhs) { return lhs = lhs + rhs; }
template
inline DeltaX& operator-=(DeltaX& lhs, DeltaX rhs) { return lhs = lhs - rhs; }
template
inline DeltaY& operator-=(DeltaY& lhs, DeltaY rhs) { return lhs = lhs - rhs; }
// Adding deltas to co-ordinates is fine
template
inline constexpr X operator+(X lhs, DeltaX rhs) { return X(lhs.as_value() + rhs.as_value()); }
template
inline constexpr Y operator+(Y lhs, DeltaY rhs) { return Y(lhs.as_value() + rhs.as_value()); }
template
inline constexpr X operator-(X lhs, DeltaX rhs) { return X(lhs.as_value() - rhs.as_value()); }
template
inline constexpr Y operator-(Y lhs, DeltaY rhs) { return Y(lhs.as_value() - rhs.as_value()); }
template
inline X& operator+=(X& lhs, DeltaX rhs) { return lhs = lhs + rhs; }
template
inline Y& operator+=(Y& lhs, DeltaY rhs) { return lhs = lhs + rhs; }
template
inline X& operator-=(X& lhs, DeltaX rhs) { return lhs = lhs - rhs; }
template
inline Y& operator-=(Y& lhs, DeltaY rhs) { return lhs = lhs - rhs; }
// Adding deltas to generic::Width and generic::Height is fine
template
inline constexpr Width operator+(Width lhs, DeltaX rhs) { return Width(lhs.as_value() + rhs.as_value()); }
template
inline constexpr Height operator+(Height