├── tests
├── big.png
├── blue.png
├── tiny.png
├── scale.png
├── small.png
├── gradient.png
├── seat_test.png
├── basic_damage.png
├── scale_damage.png
├── seat_child.png
├── simple_test.dump
├── subsurface_1.png
├── damage_test_1.dump
├── damage_test_2.dump
├── argb8888_linear.dump
├── basic_test_card.png
├── buffer_scale_1_1.dump
├── buffer_scale_1_2.dump
├── buffer_scale_2_1.dump
├── buffer_scale_2_2.dump
├── cow_transparent.png
├── subsurface_base.png
├── subsurface_damage.png
├── viewporter_test.png
├── viewporter_test_1.png
├── argb8888_implicit.dump
├── buffer_scale_1_2_1.dump
├── buffer_scale_1_2_2.dump
├── buffer_scale_2_2_1.dump
├── buffer_scale_2_2_2.dump
├── buffer_scale_2_5_1.dump
├── buffer_scale_2_5_2.dump
├── subsurface_stack_1.png
├── subsurface_stack_2.png
├── subsurface_test_1.dump
├── subsurface_test_10.dump
├── subsurface_test_11.dump
├── subsurface_test_12.dump
├── subsurface_test_13.dump
├── subsurface_test_14.dump
├── subsurface_test_15.dump
├── subsurface_test_16.dump
├── subsurface_test_17.dump
├── subsurface_test_18.dump
├── subsurface_test_19.dump
├── subsurface_test_2.dump
├── subsurface_test_20.dump
├── subsurface_test_21.dump
├── subsurface_test_22.dump
├── subsurface_test_23.dump
├── subsurface_test_24.dump
├── subsurface_test_25.dump
├── subsurface_test_26.dump
├── subsurface_test_27.dump
├── subsurface_test_28.dump
├── subsurface_test_29.dump
├── subsurface_test_3.dump
├── subsurface_test_30.dump
├── subsurface_test_31.dump
├── subsurface_test_32.dump
├── subsurface_test_33.dump
├── subsurface_test_34.dump
├── subsurface_test_35.dump
├── subsurface_test_36.dump
├── subsurface_test_37.dump
├── subsurface_test_38.dump
├── subsurface_test_39.dump
├── subsurface_test_4.dump
├── subsurface_test_5.dump
├── subsurface_test_6.dump
├── subsurface_test_7.dump
├── subsurface_test_8.dump
├── subsurface_test_9.dump
├── single_pixel_buffer.dump
├── subsurface_1_complex.png
├── subsurface_1_damaged.png
├── transform_test_180_1.dump
├── transform_test_180_2.dump
├── transform_test_270_1.dump
├── transform_test_270_2.dump
├── transform_test_90_1.dump
├── transform_test_90_2.dump
├── subsurface_transparency.png
├── viewport_dest_200_150_1.dump
├── viewport_dest_200_150_2.dump
├── transform_test_flipped_1.dump
├── transform_test_flipped_2.dump
├── single_pixel_buffer_viewport.dump
├── transform_test_flipped_180_1.dump
├── transform_test_flipped_180_2.dump
├── transform_test_flipped_270_1.dump
├── transform_test_flipped_270_2.dump
├── transform_test_flipped_90_1.dump
├── transform_test_flipped_90_2.dump
├── viewport_src_50_50_200_200_1.dump
├── viewport_src_50_50_200_200_2.dump
├── subsurface_transparency_damage.png
├── viewport_src_50_50_200_200_dest_500_500_1.dump
├── viewport_src_50_50_200_200_dest_500_500_2.dump
├── viewport_src_50_50_200_200_dest_50_75_1.dump
├── viewport_src_50_50_200_200_dest_50_75_2.dump
├── viewport_src_250_50_200_200_dest_50_75_90cw_1.dump
├── viewport_src_250_50_200_200_dest_50_75_90cw_2.dump
├── svnignore.txt
├── README
├── run_tests.sh
├── imgview.c
├── Imakefile
├── test_harness.h
├── select_helper.c
├── simple_test.c
├── buffer_test.c
├── single_pixel_buffer_test.c
├── tearing_control_test.c
├── damage_test.c
└── select_helper_multiple.c
├── .gitignore
├── svnignore.txt
├── 12to11.conf
├── mime2.awk
├── mime0.awk
├── mime4.awk
├── mime3.awk
├── mime1.awk
├── modifiers.awk
├── shaders.awk
├── compositor.c
├── decoration.c
├── alloc.c
├── region.c
├── fence_ring.c
├── shaders.txt
├── buffer.c
├── single-pixel-buffer-v1.xml
├── ewmh.c
├── relative_pointer.c
├── idle-inhibit-unstable-v1.xml
├── buffer_release.c
├── xdg_wm.c
├── README
├── tearing-control-v1.xml
├── tearing_control.c
├── single_pixel_buffer.c
├── pointer_gestures.c
├── timer.c
├── relative-pointer-unstable-v1.xml
├── keyboard-shortcuts-inhibit-unstable-v1.xml
├── Imakefile
├── xdg-decoration-unstable-v1.xml
└── port_gnu.h
/tests/big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/big.png
--------------------------------------------------------------------------------
/tests/blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/blue.png
--------------------------------------------------------------------------------
/tests/tiny.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/tiny.png
--------------------------------------------------------------------------------
/tests/scale.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/scale.png
--------------------------------------------------------------------------------
/tests/small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/small.png
--------------------------------------------------------------------------------
/tests/gradient.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/gradient.png
--------------------------------------------------------------------------------
/tests/seat_test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/seat_test.png
--------------------------------------------------------------------------------
/tests/basic_damage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/basic_damage.png
--------------------------------------------------------------------------------
/tests/scale_damage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/scale_damage.png
--------------------------------------------------------------------------------
/tests/seat_child.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/seat_child.png
--------------------------------------------------------------------------------
/tests/simple_test.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/simple_test.dump
--------------------------------------------------------------------------------
/tests/subsurface_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_1.png
--------------------------------------------------------------------------------
/tests/damage_test_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/damage_test_1.dump
--------------------------------------------------------------------------------
/tests/damage_test_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/damage_test_2.dump
--------------------------------------------------------------------------------
/tests/argb8888_linear.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/argb8888_linear.dump
--------------------------------------------------------------------------------
/tests/basic_test_card.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/basic_test_card.png
--------------------------------------------------------------------------------
/tests/buffer_scale_1_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/buffer_scale_1_1.dump
--------------------------------------------------------------------------------
/tests/buffer_scale_1_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/buffer_scale_1_2.dump
--------------------------------------------------------------------------------
/tests/buffer_scale_2_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/buffer_scale_2_1.dump
--------------------------------------------------------------------------------
/tests/buffer_scale_2_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/buffer_scale_2_2.dump
--------------------------------------------------------------------------------
/tests/cow_transparent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/cow_transparent.png
--------------------------------------------------------------------------------
/tests/subsurface_base.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_base.png
--------------------------------------------------------------------------------
/tests/subsurface_damage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_damage.png
--------------------------------------------------------------------------------
/tests/viewporter_test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/viewporter_test.png
--------------------------------------------------------------------------------
/tests/viewporter_test_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/viewporter_test_1.png
--------------------------------------------------------------------------------
/tests/argb8888_implicit.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/argb8888_implicit.dump
--------------------------------------------------------------------------------
/tests/buffer_scale_1_2_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/buffer_scale_1_2_1.dump
--------------------------------------------------------------------------------
/tests/buffer_scale_1_2_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/buffer_scale_1_2_2.dump
--------------------------------------------------------------------------------
/tests/buffer_scale_2_2_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/buffer_scale_2_2_1.dump
--------------------------------------------------------------------------------
/tests/buffer_scale_2_2_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/buffer_scale_2_2_2.dump
--------------------------------------------------------------------------------
/tests/buffer_scale_2_5_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/buffer_scale_2_5_1.dump
--------------------------------------------------------------------------------
/tests/buffer_scale_2_5_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/buffer_scale_2_5_2.dump
--------------------------------------------------------------------------------
/tests/subsurface_stack_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_stack_1.png
--------------------------------------------------------------------------------
/tests/subsurface_stack_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_stack_2.png
--------------------------------------------------------------------------------
/tests/subsurface_test_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_1.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_10.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_10.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_11.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_11.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_12.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_12.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_13.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_13.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_14.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_14.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_15.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_15.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_16.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_16.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_17.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_17.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_18.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_18.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_19.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_19.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_2.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_20.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_20.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_21.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_21.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_22.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_22.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_23.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_23.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_24.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_24.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_25.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_25.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_26.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_26.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_27.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_27.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_28.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_28.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_29.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_29.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_3.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_3.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_30.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_30.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_31.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_31.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_32.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_32.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_33.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_33.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_34.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_34.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_35.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_35.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_36.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_36.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_37.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_37.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_38.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_38.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_39.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_39.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_4.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_4.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_5.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_5.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_6.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_6.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_7.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_7.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_8.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_8.dump
--------------------------------------------------------------------------------
/tests/subsurface_test_9.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_test_9.dump
--------------------------------------------------------------------------------
/tests/single_pixel_buffer.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/single_pixel_buffer.dump
--------------------------------------------------------------------------------
/tests/subsurface_1_complex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_1_complex.png
--------------------------------------------------------------------------------
/tests/subsurface_1_damaged.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_1_damaged.png
--------------------------------------------------------------------------------
/tests/transform_test_180_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/transform_test_180_1.dump
--------------------------------------------------------------------------------
/tests/transform_test_180_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/transform_test_180_2.dump
--------------------------------------------------------------------------------
/tests/transform_test_270_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/transform_test_270_1.dump
--------------------------------------------------------------------------------
/tests/transform_test_270_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/transform_test_270_2.dump
--------------------------------------------------------------------------------
/tests/transform_test_90_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/transform_test_90_1.dump
--------------------------------------------------------------------------------
/tests/transform_test_90_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/transform_test_90_2.dump
--------------------------------------------------------------------------------
/tests/subsurface_transparency.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_transparency.png
--------------------------------------------------------------------------------
/tests/viewport_dest_200_150_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/viewport_dest_200_150_1.dump
--------------------------------------------------------------------------------
/tests/viewport_dest_200_150_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/viewport_dest_200_150_2.dump
--------------------------------------------------------------------------------
/tests/transform_test_flipped_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/transform_test_flipped_1.dump
--------------------------------------------------------------------------------
/tests/transform_test_flipped_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/transform_test_flipped_2.dump
--------------------------------------------------------------------------------
/tests/single_pixel_buffer_viewport.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/single_pixel_buffer_viewport.dump
--------------------------------------------------------------------------------
/tests/transform_test_flipped_180_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/transform_test_flipped_180_1.dump
--------------------------------------------------------------------------------
/tests/transform_test_flipped_180_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/transform_test_flipped_180_2.dump
--------------------------------------------------------------------------------
/tests/transform_test_flipped_270_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/transform_test_flipped_270_1.dump
--------------------------------------------------------------------------------
/tests/transform_test_flipped_270_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/transform_test_flipped_270_2.dump
--------------------------------------------------------------------------------
/tests/transform_test_flipped_90_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/transform_test_flipped_90_1.dump
--------------------------------------------------------------------------------
/tests/transform_test_flipped_90_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/transform_test_flipped_90_2.dump
--------------------------------------------------------------------------------
/tests/viewport_src_50_50_200_200_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/viewport_src_50_50_200_200_1.dump
--------------------------------------------------------------------------------
/tests/viewport_src_50_50_200_200_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/viewport_src_50_50_200_200_2.dump
--------------------------------------------------------------------------------
/tests/subsurface_transparency_damage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/subsurface_transparency_damage.png
--------------------------------------------------------------------------------
/tests/viewport_src_50_50_200_200_dest_500_500_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/viewport_src_50_50_200_200_dest_500_500_1.dump
--------------------------------------------------------------------------------
/tests/viewport_src_50_50_200_200_dest_500_500_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/viewport_src_50_50_200_200_dest_500_500_2.dump
--------------------------------------------------------------------------------
/tests/viewport_src_50_50_200_200_dest_50_75_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/viewport_src_50_50_200_200_dest_50_75_1.dump
--------------------------------------------------------------------------------
/tests/viewport_src_50_50_200_200_dest_50_75_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/viewport_src_50_50_200_200_dest_50_75_2.dump
--------------------------------------------------------------------------------
/tests/viewport_src_250_50_200_200_dest_50_75_90cw_1.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/viewport_src_250_50_200_200_dest_50_75_90cw_1.dump
--------------------------------------------------------------------------------
/tests/viewport_src_250_50_200_200_dest_50_75_90cw_2.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/probonopd/12to11/master/tests/viewport_src_250_50_200_200_dest_50_75_90cw_2.dump
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *-*.c
2 | *-*.h
3 | viewporter.c
4 | viewporter.h
5 | *._man
6 | short_types.txt
7 | shaders.h
8 | transfer_atoms.h
9 | Makefile
10 | *.bak
11 | 12to11
12 | *.o
13 | vgcore*
14 | massif*
15 | callgrind*
16 | drm_modifiers.h
17 |
--------------------------------------------------------------------------------
/svnignore.txt:
--------------------------------------------------------------------------------
1 | *-*.c
2 | *-*.h
3 | viewporter.c
4 | viewporter.h
5 | *._man
6 | short_types.txt
7 | shaders.h
8 | transfer_atoms.h
9 | Makefile
10 | *.bak
11 | 12to11
12 | *.o
13 | vgcore*
14 | massif*
15 | callgrind*
16 | drm_modifiers.h
17 |
--------------------------------------------------------------------------------
/tests/svnignore.txt:
--------------------------------------------------------------------------------
1 | *-*.h
2 | *-*.c
3 | vgcore*
4 | simple_test
5 | damage_test
6 | transform_test
7 | viewporter_test
8 | subsurface_test
9 | scale_test
10 | seat_test
11 | dmabuf_test
12 | select_test
13 | select_helper
14 | select_helper_multiple
15 | xdg_activation_test
16 | single_pixel_buffer_test
17 | buffer_test
18 | tearing_control_test
19 | imgview
20 | reject.dump
21 | Makefile
22 | Makefile.bak
23 | viewporter.h
24 | viewporter.c
25 |
--------------------------------------------------------------------------------
/12to11.conf:
--------------------------------------------------------------------------------
1 | /* Edit this file if any of these libraries and tools are named differently
2 | on your system. */
3 |
4 | XCB = -lxcb
5 | XCB_SHM = -lxcb-shm
6 | XCB_DRI3 = -lxcb-dri3
7 | XCB_SHAPE = -lxcb-shape
8 | XCB_RANDR = -lxcb-randr
9 | WAYLAND_SERVER = -lwayland-server
10 | XCBLIB = -lX11-xcb
11 | PIXMAN = -lpixman-1
12 | DRM = -ldrm
13 | DRMFOURCCH = $(INCROOT)/libdrm/drm_fourcc.h
14 | DRMINCLUDES = -I$(INCROOT)/libdrm
15 | PIXMANINCLUDES = -I$(INCROOT)/pixman-1
16 | XPRESENTLIB = -lXpresent
17 | WAYLAND_SCANNER = wayland-scanner
18 | XSHMFENCELIB = -lxshmfence
19 |
20 | /* The following libraries are used for tests. */
21 |
22 | WAYLAND_CLIENT = -lwayland-client
23 | PNG = -lpng
24 | GBM = -lgbm
25 |
26 | XCOMM #define BuildTests
27 |
28 | /* Comment the following code if building without EGL support. */
29 |
30 | #define HaveEglSupport
31 | EGL = -lEGL
32 | GLES = -lGLESv2
33 |
34 | XCOMM Local Variables:
35 | XCOMM mode: makefile-imake
36 | XCOMM End:
37 |
--------------------------------------------------------------------------------
/mime2.awk:
--------------------------------------------------------------------------------
1 | # Wayland compositor running on top of an X server.
2 |
3 | # Copyright (C) 2022 to various contributors.
4 |
5 | # This file is part of 12to11.
6 |
7 | # 12to11 is free software: you can redistribute it and/or modify it
8 | # under the terms of the GNU General Public License as published by the
9 | # Free Software Foundation, either version 3 of the License, or (at your
10 | # option) any later version.
11 |
12 | # 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | # for more details.
16 |
17 | # You should have received a copy of the GNU General Public License
18 | # along with 12to11. If not, see .
19 |
20 | BEGIN {
21 | print "#define DirectTransferAtomNames \\"
22 | }
23 |
24 | / ([a-z]+\/[-+.[:alnum:]]+) / { # Leave 2 spaces before and 1 space after
25 | match ($0, / ([a-z]+\/[-+.[:alnum:]]+) /, array)
26 | printf " \"%s\",\\\n", array[1]
27 | }
28 |
29 | END {
30 | printf "\n"
31 | }
32 |
--------------------------------------------------------------------------------
/mime0.awk:
--------------------------------------------------------------------------------
1 | # Wayland compositor running on top of an X server.
2 |
3 | # Copyright (C) 2022 to various contributors.
4 |
5 | # This file is part of 12to11.
6 |
7 | # 12to11 is free software: you can redistribute it and/or modify it
8 | # under the terms of the GNU General Public License as published by the
9 | # Free Software Foundation, either version 3 of the License, or (at your
10 | # option) any later version.
11 |
12 | # 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | # for more details.
16 |
17 | # You should have received a copy of the GNU General Public License
18 | # along with 12to11. If not, see .
19 |
20 | BEGIN {
21 | print "/* Automatically generated file. Do not edit! */"
22 | print "#define DirectTransferMappings \\"
23 | }
24 |
25 | / ([a-z]+\/[-+.[:alnum:]]+) / { # Leave 2 spaces before and 1 space after
26 | match ($0, / ([a-z]+\/[-+.[:alnum:]]+) /, array)
27 | printf " { 0, \"%s\"},\\\n", array[1]
28 | }
29 |
30 | END {
31 | printf "\n"
32 | }
33 |
--------------------------------------------------------------------------------
/mime4.awk:
--------------------------------------------------------------------------------
1 | # Wayland compositor running on top of an X server.
2 |
3 | # Copyright (C) 2022 to various contributors.
4 |
5 | # This file is part of 12to11.
6 |
7 | # 12to11 is free software: you can redistribute it and/or modify it
8 | # under the terms of the GNU General Public License as published by the
9 | # Free Software Foundation, either version 3 of the License, or (at your
10 | # option) any later version.
11 |
12 | # 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | # for more details.
16 |
17 | # You should have received a copy of the GNU General Public License
18 | # along with 12to11. If not, see .
19 |
20 | BEGIN {
21 | print "#define DirectTransferAtoms \\"
22 | }
23 |
24 | / ([a-z]+\/[-+.[:alnum:]]+) / { # Leave 2 spaces before and 1 space after
25 | match ($0, / ([a-z]+\/[-+.[:alnum:]]+) /, array)
26 | name = array[1]
27 | gsub (/[[:punct:]]/, "_", name) # Convert to a valid atom name
28 | printf " %s, \\\n", name
29 | }
30 |
31 | END {
32 | print " dummy_atom"
33 | }
34 |
--------------------------------------------------------------------------------
/mime3.awk:
--------------------------------------------------------------------------------
1 | # Wayland compositor running on top of an X server.
2 |
3 | # Copyright (C) 2022 to various contributors.
4 |
5 | # This file is part of 12to11.
6 |
7 | # 12to11 is free software: you can redistribute it and/or modify it
8 | # under the terms of the GNU General Public License as published by the
9 | # Free Software Foundation, either version 3 of the License, or (at your
10 | # option) any later version.
11 |
12 | # 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | # for more details.
16 |
17 | # You should have received a copy of the GNU General Public License
18 | # along with 12to11. If not, see .
19 |
20 | BEGIN {
21 | print "#define DirectTransferAtomInit(list, base) \\"
22 | i = 0
23 | }
24 |
25 | / ([a-z]+\/[-+.[:alnum:]]+) / { # Leave 2 spaces before and 1 space after
26 | match ($0, / ([a-z]+\/[-+.[:alnum:]]+) /, array)
27 | name = array[1]
28 | gsub (/[[:punct:]]/, "_", name) # Convert to a valid atom name
29 | printf " %s = list[base + %d];\\\n", name, i++
30 | }
31 |
32 | END {
33 | printf "\n"
34 | }
35 |
--------------------------------------------------------------------------------
/mime1.awk:
--------------------------------------------------------------------------------
1 | # Wayland compositor running on top of an X server.
2 |
3 | # Copyright (C) 2022 to various contributors.
4 |
5 | # This file is part of 12to11.
6 |
7 | # 12to11 is free software: you can redistribute it and/or modify it
8 | # under the terms of the GNU General Public License as published by the
9 | # Free Software Foundation, either version 3 of the License, or (at your
10 | # option) any later version.
11 |
12 | # 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | # for more details.
16 |
17 | # You should have received a copy of the GNU General Public License
18 | # along with 12to11. If not, see .
19 |
20 | BEGIN {
21 | print "#define DirectTransferInitializer(table, start) \\"
22 | i = 0
23 | }
24 |
25 | / ([a-z]+\/[-+.[:alnum:]]+) / { # Leave 2 spaces before and 1 space after
26 | match ($0, / ([a-z]+\/[-+.[:alnum:]]+) /, array)
27 | name = array[1]
28 | gsub (/[[:punct:]]/, "_", name) # Convert to a valid atom name
29 | printf " table[%d + start].atom_flag = %s;\\\n", i++, name
30 | }
31 |
32 | END {
33 | printf "\n"
34 | }
35 |
--------------------------------------------------------------------------------
/modifiers.awk:
--------------------------------------------------------------------------------
1 | # Wayland compositor running on top of an X serer.
2 |
3 | # Copyright (C) 2022 to various contributors.
4 |
5 | # This file is part of 12to11.
6 |
7 | # 12to11 is free software: you can redistribute it and/or modify it
8 | # under the terms of the GNU General Public License as published by the
9 | # Free Software Foundation, either version 3 of the License, or (at your
10 | # option) any later version.
11 |
12 | # 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | # for more details.
16 |
17 | # You should have received a copy of the GNU General Public License
18 | # along with 12to11. If not, see .
19 |
20 | BEGIN {
21 | print "#define DrmModifiersList \\"
22 | };
23 |
24 | /^#define[[:space:]]+(I915|DRM)_FORMAT_MOD_[[:alnum:]_]+[[:space:]]+fourcc_mod_code(.*)$/ {
25 | printf (" { \"%s\", %s }, \\\n", $2, $2);
26 | }
27 |
28 | /^#define[[:space:]]+AMD_FMT_MOD_[[:alnum:]_]+[[:space:]]+(0x[[:xdigit:]]+|[:digit:]+)$/ {
29 | printf (" { \"%s\", %s | AMD_FMT_MOD }, \\\n", $2, $2);
30 | }
31 |
32 | END {
33 | printf (" { NULL, 0 },\n");
34 | }
35 |
36 | # Broadcom, ARM, etc modifiers not supported! Patches welcome.
37 |
--------------------------------------------------------------------------------
/tests/README:
--------------------------------------------------------------------------------
1 | This directory holds some work-in-progress code for testing the
2 | protocol translator. The current test suite is nowhere near
3 | comprehensive.
4 |
5 | Each test must be individually run on a system with an a8r8g8b8
6 | visual, GLOBAL_SCALE and OUTPUT_SCALE set to 1. They also rely on
7 | reference data; if some legitimate changes are made that affect test
8 | results, then the tests should be run with TEST_WRITE_REFERENCE=1,
9 | which will make the test binaries write out reference data to disk.
10 |
11 | When tests are being run, the tester must be very careful to not
12 | interfere with the test operation by moving or resizing the test
13 | window. A compositing manager should be running along with the test.
14 |
15 | These tests are supposed to test the functionality of the protocol
16 | translator by connecting to a running instance and validating the
17 | results of various high-level requests. In modern parlance, they
18 | would be ``integration tests''.
19 |
20 | Most likely, you do not want to run these tests manually, as the
21 | `run_tests.sh' script does all the setup for you.
22 |
23 | Please note that the EGL renderer currently does not pass some
24 | graphics tests, which is expected behavior, and that `select_test'
25 | must be run with no clipboard manager (or any other clients, for that
26 | matter) running.
27 |
--------------------------------------------------------------------------------
/shaders.awk:
--------------------------------------------------------------------------------
1 | # Wayland compositor running on top of an X serer.
2 |
3 | # Copyright (C) 2022 to various contributors.
4 |
5 | # This file is part of 12to11.
6 |
7 | # 12to11 is free software: you can redistribute it and/or modify it
8 | # under the terms of the GNU General Public License as published by the
9 | # Free Software Foundation, either version 3 of the License, or (at your
10 | # option) any later version.
11 |
12 | # 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | # for more details.
16 |
17 | # You should have received a copy of the GNU General Public License
18 | # along with 12to11. If not, see .
19 |
20 | /^\/\/==/ {
21 | if (in_program)
22 | {
23 | in_program = 0;
24 | print ";"
25 | }
26 | else
27 | {
28 | match ($0, /^\/\/== ([[:alnum:] ]+)/, array)
29 | in_program = ignore_line = 1;
30 |
31 | # Start a new shader; first, escape the name by replacing white
32 | # space with underscores.
33 | gsub (/[[:space:]]/, "_", array[1])
34 |
35 | # Next, make everything lowercase.
36 | array[1] = tolower (array[1]);
37 |
38 | printf "static const char *%s =\n", array[1]
39 | }
40 | }
41 |
42 | {
43 | if (ignore_line)
44 | ignore_line = 0;
45 | else if (in_program)
46 | {
47 | # Escape characters that can occur in regular GLSL programs but
48 | # must be escaped in C strings.
49 | string = $0
50 | gsub (/[\\"]/, "\\\\&", string)
51 | printf " \"%s\\n\"\n", string
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/compositor.c:
--------------------------------------------------------------------------------
1 | /* Wayland compositor running on top of an X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include "compositor.h"
21 |
22 | /* The compositor global. */
23 | static struct wl_global *global_compositor;
24 |
25 | static void
26 | CreateSurface (struct wl_client *client,
27 | struct wl_resource *resource,
28 | uint32_t id)
29 | {
30 | XLCreateSurface (client, resource, id);
31 | }
32 |
33 | static void
34 | CreateRegion (struct wl_client *client,
35 | struct wl_resource *resource,
36 | uint32_t id)
37 | {
38 | XLCreateRegion (client, resource, id);
39 | }
40 |
41 | static const struct wl_compositor_interface wl_compositor_impl =
42 | {
43 | .create_surface = CreateSurface,
44 | .create_region = CreateRegion,
45 | };
46 |
47 | static void
48 | HandleBind (struct wl_client *client, void *data,
49 | uint32_t version, uint32_t id)
50 | {
51 | struct wl_resource *resource;
52 |
53 | resource = wl_resource_create (client, &wl_compositor_interface,
54 | version, id);
55 |
56 | if (!resource)
57 | {
58 | wl_client_post_no_memory (client);
59 | return;
60 | }
61 |
62 | wl_resource_set_implementation (resource, &wl_compositor_impl,
63 | NULL, NULL);
64 | }
65 |
66 | void
67 | XLInitCompositor (void)
68 | {
69 | global_compositor
70 | = wl_global_create (compositor.wl_display,
71 | &wl_compositor_interface,
72 | 5, NULL, HandleBind);
73 | }
74 |
--------------------------------------------------------------------------------
/decoration.c:
--------------------------------------------------------------------------------
1 | /* Wayland compositor running on top of an X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include "compositor.h"
21 | #include "xdg-decoration-unstable-v1.h"
22 |
23 | /* The xdg_decoration_manager_v1 global. */
24 | static struct wl_global *decoration_manager_global;
25 |
26 | static void
27 | Destroy (struct wl_client *client, struct wl_resource *resource)
28 | {
29 | wl_resource_destroy (resource);
30 | }
31 |
32 | static void
33 | GetToplevelDecoration (struct wl_client *client, struct wl_resource *resource,
34 | uint32_t id, struct wl_resource *toplevel_resource)
35 | {
36 | XdgRoleImplementation *impl;
37 |
38 | impl = wl_resource_get_user_data (toplevel_resource);
39 | XLXdgToplevelGetDecoration (impl, resource, id);
40 | }
41 |
42 | static const struct zxdg_decoration_manager_v1_interface manager_impl =
43 | {
44 | .destroy = Destroy,
45 | .get_toplevel_decoration = GetToplevelDecoration,
46 | };
47 |
48 | static void
49 | HandleBind (struct wl_client *client, void *data, uint32_t version,
50 | uint32_t id)
51 | {
52 | struct wl_resource *resource;
53 |
54 | resource
55 | = wl_resource_create (client,
56 | &zxdg_decoration_manager_v1_interface,
57 | version, id);
58 |
59 | if (!resource)
60 | {
61 | wl_client_post_no_memory (client);
62 | return;
63 | }
64 |
65 | wl_resource_set_implementation (resource, &manager_impl, NULL, NULL);
66 | }
67 |
68 | void
69 | XLInitDecoration (void)
70 | {
71 | decoration_manager_global
72 | = wl_global_create (compositor.wl_display,
73 | &zxdg_decoration_manager_v1_interface,
74 | 1, NULL, HandleBind);
75 | }
76 |
--------------------------------------------------------------------------------
/tests/run_tests.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Tests for the Wayland compositor running on top of an X serer.
3 |
4 | # Copyright (C) 2022 to various contributors.
5 |
6 | # This file is part of 12to11.
7 |
8 | # 12to11 is free software: you can redistribute it and/or modify it
9 | # under the terms of the GNU General Public License as published by the
10 | # Free Software Foundation, either version 3 of the License, or (at your
11 | # option) any later version.
12 |
13 | # 12to11 is distributed in the hope that it will be useful, but WITHOUT
14 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 | # for more details.
17 |
18 | # You should have received a copy of the GNU General Public License
19 | # along with 12to11. If not, see .
20 |
21 | pushd "$(dirname $0)"
22 | declare -a standard_tests=(
23 | simple_test damage_test transform_test viewporter_test
24 | subsurface_test scale_test seat_test dmabuf_test
25 | xdg_activation_test single_pixel_buffer_test buffer_test
26 | tearing_control_test
27 | )
28 |
29 | make -C . "${standard_tests[@]}"
30 |
31 | export GLOBAL_SCALE=1
32 | export OUTPUT_SCALE=1
33 | exec 3< <(stdbuf -oL ../12to11 -printsocket)
34 | read -u 3 WAYLAND_DISPLAY
35 | export WAYLAND_DISPLAY
36 |
37 | echo "Compositor started at ${WAYLAND_DISPLAY}"
38 |
39 | for test_executable in "${standard_tests[@]}"
40 | do
41 | echo "Running test ${test_executable}"
42 |
43 | if ./${test_executable}; then
44 | echo "${test_executable} completed successfully"
45 | else
46 | echo "${test_executable} failed; see its output for more details"
47 | fi
48 | done
49 |
50 | echo "Starting Xvfb at :27"
51 |
52 | Xvfb :27 &
53 | sleep 1
54 | exec 4< <(DISPLAY=:27 stdbuf -oL ../12to11 -printsocket)
55 | read -u 4 WAYLAND_DISPLAY
56 | export WAYLAND_DISPLAY
57 |
58 | declare -a vfb_tests=(
59 | select_test
60 | )
61 |
62 | make -C . "${vfb_tests[@]}" select_helper select_helper_multiple
63 |
64 | echo "Compositor for vfb tests started at ${WAYLAND_DISPLAY}"
65 |
66 | for test_executable in "${vfb_tests[@]}"
67 | do
68 | echo "Running test ${test_executable}"
69 |
70 | if ./${test_executable}; then
71 | echo "${test_executable} completed successfully"
72 | else
73 | echo "${test_executable} failed; see its output for more details"
74 | fi
75 | done
76 |
77 | popd
78 |
79 | trap 'jobs -p | xargs kill' EXIT
80 |
--------------------------------------------------------------------------------
/alloc.c:
--------------------------------------------------------------------------------
1 | /* Wayland compositor running on top of an X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 |
25 | #include "compositor.h"
26 |
27 | void *
28 | XLMalloc (size_t size)
29 | {
30 | void *ptr;
31 |
32 | ptr = malloc (size);
33 |
34 | if (!ptr && size)
35 | {
36 | fprintf (stderr, "Allocation of %zu bytes failed\n",
37 | size);
38 | abort ();
39 | }
40 |
41 | return ptr;
42 | }
43 |
44 | void *
45 | XLSafeMalloc (size_t size)
46 | {
47 | return malloc (size);
48 | }
49 |
50 | void *
51 | XLCalloc (size_t nmemb, size_t size)
52 | {
53 | void *ptr;
54 |
55 | ptr = calloc (nmemb, size);
56 |
57 | if (!ptr && nmemb && size)
58 | {
59 | fprintf (stderr, "Allocation of %zu * %zu failed\n",
60 | nmemb, size);
61 | abort ();
62 | }
63 |
64 | return ptr;
65 | }
66 |
67 | void
68 | XLFree (void *ptr)
69 | {
70 | if (ptr)
71 | free (ptr);
72 | }
73 |
74 | char *
75 | XLStrdup (const char *data)
76 | {
77 | char *string;
78 |
79 | string = strdup (data);
80 |
81 | if (!string)
82 | {
83 | fprintf (stderr, "Allocation of %zu bytes failed\n",
84 | strlen (data));
85 | abort ();
86 | }
87 |
88 | return string;
89 | }
90 |
91 | void *
92 | XLRealloc (void *ptr, size_t size)
93 | {
94 | if (!ptr)
95 | return XLMalloc (size);
96 |
97 | ptr = realloc (ptr, size);
98 |
99 | if (size && !ptr)
100 | {
101 | fprintf (stderr, "Reallocation of %zu bytes failed\n", size);
102 | abort ();
103 | }
104 |
105 | /* Allow realloc to return NULL if size is also NULL. */
106 |
107 | return ptr;
108 | }
109 |
--------------------------------------------------------------------------------
/region.c:
--------------------------------------------------------------------------------
1 | /* Wayland compositor running on top of an X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include
21 |
22 | #include
23 |
24 | #include "compositor.h"
25 |
26 | static void
27 | DestroyRegion (struct wl_client *client, struct wl_resource *resource)
28 | {
29 | wl_resource_destroy (resource);
30 | }
31 |
32 | static void
33 | SubtractRegion (struct wl_client *client, struct wl_resource *resource,
34 | int32_t x, int32_t y, int32_t width, int32_t height)
35 | {
36 | pixman_region32_t *region, operand;
37 |
38 | region = wl_resource_get_user_data (resource);
39 | pixman_region32_init_rect (&operand, x, y, width, height);
40 | pixman_region32_subtract (region, region, &operand);
41 | }
42 |
43 | static void
44 | AddRegion (struct wl_client *client, struct wl_resource *resource,
45 | int32_t x, int32_t y, int32_t width, int32_t height)
46 | {
47 | pixman_region32_t *region, operand;
48 |
49 | region = wl_resource_get_user_data (resource);
50 | pixman_region32_init_rect (&operand, x, y, width, height);
51 | pixman_region32_union (region, region, &operand);
52 | }
53 |
54 | static const struct wl_region_interface wl_region_impl =
55 | {
56 | .destroy = DestroyRegion,
57 | .subtract = SubtractRegion,
58 | .add = AddRegion
59 | };
60 |
61 | static void
62 | HandleResourceDestroy (struct wl_resource *resource)
63 | {
64 | pixman_region32_t *region;
65 |
66 | region = wl_resource_get_user_data (resource);
67 | pixman_region32_fini (region);
68 | XLFree (region);
69 | }
70 |
71 | void
72 | XLCreateRegion (struct wl_client *client,
73 | struct wl_resource *resource,
74 | uint32_t id)
75 | {
76 | pixman_region32_t *region;
77 | struct wl_resource *region_resource;
78 |
79 | region = XLSafeMalloc (sizeof *region);
80 |
81 | if (!region)
82 | {
83 | wl_resource_post_no_memory (resource);
84 | return;
85 | }
86 |
87 | region_resource
88 | = wl_resource_create (client, &wl_region_interface,
89 | wl_resource_get_version (resource),
90 | id);
91 |
92 | if (!resource)
93 | {
94 | wl_resource_post_no_memory (resource);
95 | XLFree (region);
96 |
97 | return;
98 | }
99 |
100 | pixman_region32_init (region);
101 | wl_resource_set_implementation (region_resource,
102 | &wl_region_impl,
103 | region,
104 | HandleResourceDestroy);
105 | }
106 |
--------------------------------------------------------------------------------
/fence_ring.c:
--------------------------------------------------------------------------------
1 | /* Wayland compositor running on top of an X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include
21 |
22 | #include
23 |
24 | #include "compositor.h"
25 |
26 | #include
27 | #include
28 |
29 | #include
30 |
31 | struct _Fence
32 | {
33 | /* The xshmfence. */
34 | struct xshmfence *fence;
35 |
36 | /* The sync fence. */
37 | XSyncFence fence_id;
38 |
39 | /* The number of references to this fence. Incremented by
40 | FenceRetain, decremented by FenceRelease. */
41 | int refcount;
42 | };
43 |
44 | Fence *
45 | GetFence (void)
46 | {
47 | Fence *fence;
48 | int fd;
49 | Window drawable;
50 |
51 | drawable = DefaultRootWindow (compositor.display);
52 |
53 | /* Allocate a new fence. */
54 | fence = XLCalloc (1, sizeof *fence);
55 | fd = xshmfence_alloc_shm ();
56 |
57 | if (fd < 0)
58 | {
59 | perror ("xshmfence_alloc_shm");
60 | abort ();
61 | }
62 |
63 | /* Map it. */
64 | fence->fence = xshmfence_map_shm (fd);
65 |
66 | if (!fence->fence)
67 | {
68 | perror ("xshmfence_map_shm");
69 | abort ();
70 | }
71 |
72 | /* Upload the fence to the X server. XCB will close the file
73 | descriptor. */
74 | fence->fence_id = xcb_generate_id (compositor.conn);
75 |
76 | /* Make the file descriptor CLOEXEC, since it isn't closed
77 | immediately. */
78 | XLAddFdFlag (fd, FD_CLOEXEC, False);
79 | xcb_dri3_fence_from_fd (compositor.conn, drawable,
80 | fence->fence_id, 0, fd);
81 |
82 | /* Retain the fence. */
83 | FenceRetain (fence);
84 |
85 | /* Return the fence. */
86 | return fence;
87 | }
88 |
89 | void
90 | FenceAwait (Fence *fence)
91 | {
92 | /* Wait for the fence to be triggered. */
93 | xshmfence_await (fence->fence);
94 |
95 | /* Reset the fence. */
96 | xshmfence_reset (fence->fence);
97 | }
98 |
99 | void
100 | FenceRelease (Fence *fence)
101 | {
102 | if (--fence->refcount)
103 | return;
104 |
105 | /* Unmap the fence. */
106 | xshmfence_unmap_shm (fence->fence);
107 |
108 | /* Destroy the fence. */
109 | XSyncDestroyFence (compositor.display, fence->fence_id);
110 |
111 | /* Free the fence. */
112 | XLFree (fence);
113 | }
114 |
115 | void
116 | FenceRetain (Fence *fence)
117 | {
118 | fence->refcount++;
119 | }
120 |
121 | XSyncFence
122 | FenceToXFence (Fence *fence)
123 | {
124 | return fence->fence_id;
125 | }
126 |
--------------------------------------------------------------------------------
/shaders.txt:
--------------------------------------------------------------------------------
1 | // -*- glsl -*-
2 |
3 | // File containing GLSL shaders used to generate shaders.h.
4 |
5 | // At the start of each shader, write // followed by two equals signs,
6 | // followed by a space, the name of the shader and a newline.
7 | // Following that, write the shader code.
8 |
9 | // To terminate a shader, write // followed by another two equals
10 | // signs, this time without a trailing name or whitespace.
11 |
12 | //== Clear Rectangle Vertex Shader
13 | attribute vec2 pos;
14 |
15 | void
16 | main (void)
17 | {
18 | gl_Position = vec4 (pos.x, pos.y, 1.0, 1.0);
19 | }
20 | //==
21 |
22 | //== Clear Rectangle Fragment Shader
23 | void
24 | main (void)
25 | {
26 | gl_FragColor = vec4 (0.0, 0.0, 0.0, 0.0);
27 | }
28 | //==
29 |
30 | //== Composite Rectangle Vertex Shader
31 | precision mediump float;
32 | attribute vec2 pos;
33 | attribute vec2 texcoord;
34 | varying vec2 v_texcoord;
35 | uniform mat3 source;
36 |
37 | void
38 | main (void)
39 | {
40 | gl_Position = vec4 (pos.x, pos.y, 1.0, 1.0);
41 | v_texcoord = (source * vec3 (texcoord, 1.0)).xy;
42 | }
43 | //==
44 |
45 | //== Composite Rectangle Fragment Shader RGBA
46 | precision mediump float;
47 | uniform sampler2D texture;
48 | uniform bool invert_y;
49 | varying vec2 v_texcoord;
50 |
51 | void
52 | main (void)
53 | {
54 | vec2 texcoord;
55 |
56 | texcoord = v_texcoord;
57 |
58 | if (invert_y)
59 | texcoord = vec2 (texcoord.x, 1.0 - texcoord.y);
60 |
61 | gl_FragColor = texture2D (texture, texcoord);
62 | }
63 | //==
64 |
65 | //== Composite Rectangle Fragment Shader RGBX
66 | precision mediump float;
67 | uniform sampler2D texture;
68 | uniform mat3 source;
69 | uniform bool invert_y;
70 | varying vec2 v_texcoord;
71 |
72 | void
73 | main (void)
74 | {
75 | vec2 texcoord;
76 |
77 | texcoord = v_texcoord;
78 |
79 | if (invert_y)
80 | texcoord = vec2 (texcoord.x, 1.0 - texcoord.y);
81 |
82 | gl_FragColor = vec4 (texture2D (texture, texcoord).rgb, 1.0);
83 | }
84 | //==
85 |
86 | //== Composite Rectangle Fragment Shader External
87 | #extension GL_OES_EGL_image_external : require
88 |
89 | precision mediump float;
90 | uniform samplerExternalOES texture;
91 | uniform mat3 source;
92 | uniform bool invert_y;
93 | varying vec2 v_texcoord;
94 |
95 | void
96 | main (void)
97 | {
98 | vec2 texcoord;
99 |
100 | texcoord = v_texcoord;
101 |
102 | if (invert_y)
103 | texcoord = vec2 (texcoord.x, 1.0 - texcoord.y);
104 |
105 | gl_FragColor = texture2D (texture, texcoord);
106 | }
107 | //==
108 |
109 | //== Composite Rectangle Fragment Shader Single Pixel
110 | #extension GL_OES_EGL_image_external : require
111 |
112 | precision mediump float;
113 | uniform vec4 source_color;
114 | uniform mat3 source;
115 | uniform bool invert_y;
116 | varying vec2 v_texcoord;
117 |
118 | void
119 | main (void)
120 | {
121 | vec2 texcoord;
122 |
123 | texcoord = v_texcoord;
124 |
125 | if (invert_y)
126 | texcoord = vec2 (texcoord.x, 1.0 - texcoord.y);
127 |
128 | if (texcoord.x < 0.0 || texcoord.y < 0.0
129 | || texcoord.x > 1.0 || texcoord.y > 1.0)
130 | gl_FragColor = vec4 (0.0, 0.0, 0.0, 0.0);
131 | else
132 | gl_FragColor = source_color;
133 | }
134 | //==
135 |
--------------------------------------------------------------------------------
/buffer.c:
--------------------------------------------------------------------------------
1 | /* Wayland compositor running on top of an X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include
21 |
22 | #include "compositor.h"
23 |
24 | typedef struct _DestroyListener DestroyListener;
25 |
26 | struct _DestroyListener
27 | {
28 | /* Function to call. */
29 | ExtBufferFunc func;
30 |
31 | /* User data. */
32 | void *data;
33 | };
34 |
35 | void
36 | XLRetainBuffer (ExtBuffer *buffer)
37 | {
38 | buffer->funcs.retain (buffer);
39 | }
40 |
41 | void
42 | XLDereferenceBuffer (ExtBuffer *buffer)
43 | {
44 | buffer->funcs.dereference (buffer);
45 | }
46 |
47 | RenderBuffer
48 | XLRenderBufferFromBuffer (ExtBuffer *buffer)
49 | {
50 | return buffer->funcs.get_buffer (buffer);
51 | }
52 |
53 | unsigned int
54 | XLBufferWidth (ExtBuffer *buffer)
55 | {
56 | return buffer->funcs.width (buffer);
57 | }
58 |
59 | unsigned int
60 | XLBufferHeight (ExtBuffer *buffer)
61 | {
62 | return buffer->funcs.height (buffer);
63 | }
64 |
65 | void
66 | XLReleaseBuffer (ExtBuffer *buffer)
67 | {
68 | buffer->funcs.release (buffer);
69 | }
70 |
71 | void *
72 | XLBufferRunOnFree (ExtBuffer *buffer, ExtBufferFunc func,
73 | void *data)
74 | {
75 | DestroyListener *listener;
76 |
77 | listener = XLMalloc (sizeof *listener);
78 |
79 | listener->func = func;
80 | listener->data = data;
81 |
82 | buffer->destroy_listeners
83 | = XLListPrepend (buffer->destroy_listeners,
84 | listener);
85 |
86 | return listener;
87 | }
88 |
89 | void
90 | XLBufferCancelRunOnFree (ExtBuffer *buffer, void *key)
91 | {
92 | buffer->destroy_listeners
93 | = XLListRemove (buffer->destroy_listeners, key);
94 | XLFree (key);
95 | }
96 |
97 | void
98 | XLPrintBuffer (ExtBuffer *buffer)
99 | {
100 | if (buffer->funcs.print_buffer)
101 | buffer->funcs.print_buffer (buffer);
102 | }
103 |
104 | void
105 | ExtBufferDestroy (ExtBuffer *buffer)
106 | {
107 | XLList *listener;
108 | DestroyListener *item;
109 |
110 | /* Now run every destroy listener connected to this buffer. */
111 | for (listener = buffer->destroy_listeners;
112 | listener; listener = listener->next)
113 | {
114 | item = listener->data;
115 |
116 | item->func (buffer, item->data);
117 | }
118 |
119 | /* Free the label if present. */
120 | XLFree (buffer->label);
121 |
122 | /* Not very efficient, since the list is followed through twice, but
123 | destroy listener lists should always be small. */
124 | XLListFree (buffer->destroy_listeners, XLFree);
125 | }
126 |
--------------------------------------------------------------------------------
/single-pixel-buffer-v1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Copyright © 2022 Simon Ser
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a
7 | copy of this software and associated documentation files (the "Software"),
8 | to deal in the Software without restriction, including without limitation
9 | the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | and/or sell copies of the Software, and to permit persons to whom the
11 | Software is furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice (including the next
14 | paragraph) shall be included in all copies or substantial portions of the
15 | Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | DEALINGS IN THE SOFTWARE.
24 |
25 |
26 |
27 | This protocol extension allows clients to create single-pixel buffers.
28 |
29 | Compositors supporting this protocol extension should also support the
30 | viewporter protocol extension. Clients may use viewporter to scale a
31 | single-pixel buffer to a desired size.
32 |
33 | Warning! The protocol described in this file is currently in the testing
34 | phase. Backward compatible changes may be added together with the
35 | corresponding interface version bump. Backward incompatible changes can
36 | only be done by creating a new major version of the extension.
37 |
38 |
39 |
40 |
41 | The wp_single_pixel_buffer_manager_v1 interface is a factory for
42 | single-pixel buffers.
43 |
44 |
45 |
46 |
47 | Destroy the wp_single_pixel_buffer_manager_v1 object.
48 |
49 | The child objects created via this interface are unaffected.
50 |
51 |
52 |
53 |
54 |
55 | Create a single-pixel buffer from four 32-bit RGBA values.
56 |
57 | Unless specified in another protocol extension, the RGBA values use
58 | pre-multiplied alpha.
59 |
60 | The width and height of the buffer are 1.
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/ewmh.c:
--------------------------------------------------------------------------------
1 | /* Wayland compositor running on top of an X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include "compositor.h"
21 |
22 | /* Array of supported atoms. Free this with XFree. */
23 | static Atom *net_supported_atoms;
24 |
25 | /* Number of elements in that array. */
26 | int n_supported_atoms;
27 |
28 | static Window
29 | GetWmCheckWindow (void)
30 | {
31 | Window result;
32 | unsigned char *tmp_data;
33 | int rc, actual_format;
34 | unsigned long actual_size, bytes_remaining;
35 | Atom actual_type;
36 |
37 | tmp_data = NULL;
38 | rc = XGetWindowProperty (compositor.display,
39 | DefaultRootWindow (compositor.display),
40 | _NET_SUPPORTING_WM_CHECK,
41 | 0, 1, False, XA_WINDOW, &actual_type,
42 | &actual_format, &actual_size,
43 | &bytes_remaining, &tmp_data);
44 |
45 | if (rc != Success || actual_type != XA_WINDOW
46 | || actual_format != 32 || actual_size != 1
47 | || !tmp_data)
48 | {
49 | if (tmp_data)
50 | XFree (tmp_data);
51 |
52 | return None;
53 | }
54 |
55 | result = *(Window *) tmp_data;
56 | XFree (tmp_data);
57 |
58 | return result;
59 | }
60 |
61 | static Bool
62 | IsValidWmCheckWindow (Window window)
63 | {
64 | CatchXErrors ();
65 | XSelectInput (compositor.display, window,
66 | SubstructureNotifyMask);
67 | return !UncatchXErrors (NULL);
68 | }
69 |
70 | Bool
71 | XLWmSupportsHint (Atom hint)
72 | {
73 | Window wm_check_window;
74 | Bool errors;
75 | unsigned char *tmp_data;
76 | int rc, actual_format, i;
77 | unsigned long actual_size, bytes_remaining;
78 | Atom actual_type;
79 |
80 | /* Window manager restarts are not handled here, since the rest of
81 | the code cannot cope with that. */
82 |
83 | start_check:
84 | if (net_supported_atoms)
85 | {
86 | for (i = 0; i < n_supported_atoms; ++i)
87 | {
88 | if (net_supported_atoms[i] == hint)
89 | return True;
90 | }
91 |
92 | return False;
93 | }
94 |
95 | wm_check_window = GetWmCheckWindow ();
96 |
97 | if (!IsValidWmCheckWindow (wm_check_window))
98 | return False;
99 |
100 | tmp_data = NULL;
101 |
102 | CatchXErrors ();
103 | rc = XGetWindowProperty (compositor.display,
104 | DefaultRootWindow (compositor.display),
105 | _NET_SUPPORTED, 0, 4096, False, XA_ATOM,
106 | &actual_type, &actual_format, &actual_size,
107 | &bytes_remaining, &tmp_data);
108 | errors = UncatchXErrors (NULL);
109 |
110 | if (rc != Success || actual_type != XA_ATOM || errors)
111 | {
112 | if (tmp_data)
113 | XFree (tmp_data);
114 |
115 | return False;
116 | }
117 | else
118 | {
119 | net_supported_atoms = (Atom *) tmp_data;
120 | n_supported_atoms = actual_size;
121 |
122 | goto start_check;
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/relative_pointer.c:
--------------------------------------------------------------------------------
1 | /* Wayland compositor running on top of an X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include "compositor.h"
21 | #include "relative-pointer-unstable-v1.h"
22 |
23 | /* The zwp_relative_pointer_manager_v1 global. */
24 | static struct wl_global *relative_pointer_manager_global;
25 |
26 | static void
27 | DestroyRelativePointer (struct wl_client *client,
28 | struct wl_resource *resource)
29 | {
30 | wl_resource_destroy (resource);
31 | }
32 |
33 | static struct zwp_relative_pointer_v1_interface relative_pointer_impl =
34 | {
35 | .destroy = DestroyRelativePointer,
36 | };
37 |
38 | static void
39 | HandleRelativePointerResourceDestroy (struct wl_resource *resource)
40 | {
41 | RelativePointer *relative_pointer;
42 |
43 | relative_pointer = wl_resource_get_user_data (resource);
44 | XLSeatDestroyRelativePointer (relative_pointer);
45 | }
46 |
47 |
48 |
49 | static void
50 | Destroy (struct wl_client *client, struct wl_resource *resource)
51 | {
52 | wl_resource_destroy (resource);
53 | }
54 |
55 | static void
56 | GetRelativePointer (struct wl_client *client, struct wl_resource *resource,
57 | uint32_t id, struct wl_resource *pointer_resource)
58 | {
59 | struct wl_resource *relative_pointer_resource;
60 | Pointer *pointer;
61 | RelativePointer *relative_pointer;
62 | Seat *seat;
63 |
64 | pointer = wl_resource_get_user_data (pointer_resource);
65 | seat = XLPointerGetSeat (pointer);
66 | relative_pointer_resource
67 | = wl_resource_create (client, &zwp_relative_pointer_v1_interface,
68 | wl_resource_get_version (pointer_resource),
69 | id);
70 |
71 | if (!relative_pointer_resource)
72 | {
73 | wl_resource_post_no_memory (pointer_resource);
74 | return;
75 | }
76 |
77 | relative_pointer = XLSeatGetRelativePointer (seat,
78 | relative_pointer_resource);
79 | wl_resource_set_implementation (relative_pointer_resource,
80 | &relative_pointer_impl, relative_pointer,
81 | HandleRelativePointerResourceDestroy);
82 | }
83 |
84 | static const struct zwp_relative_pointer_manager_v1_interface manager_impl =
85 | {
86 | .destroy = Destroy,
87 | .get_relative_pointer = GetRelativePointer,
88 | };
89 |
90 | static void
91 | HandleBind (struct wl_client *client, void *data,
92 | uint32_t version, uint32_t id)
93 | {
94 | struct wl_resource *resource;
95 |
96 | resource = wl_resource_create (client,
97 | &zwp_relative_pointer_manager_v1_interface,
98 | version, id);
99 |
100 | if (!resource)
101 | {
102 | wl_client_post_no_memory (client);
103 | return;
104 | }
105 |
106 | wl_resource_set_implementation (resource, &manager_impl, NULL, NULL);
107 | }
108 |
109 | void
110 | XLInitRelativePointer (void)
111 | {
112 | relative_pointer_manager_global
113 | = wl_global_create (compositor.wl_display,
114 | &zwp_relative_pointer_manager_v1_interface,
115 | 1, NULL, HandleBind);
116 | }
117 |
118 | void
119 | XLRelativePointerSendRelativeMotion (struct wl_resource *resource,
120 | uint64_t microsecond_time, double dx,
121 | double dy)
122 | {
123 | uint32_t time_hi, time_lo;
124 |
125 | time_hi = microsecond_time >> 32;
126 | time_lo = microsecond_time & 0xffffffff;
127 |
128 | zwp_relative_pointer_v1_send_relative_motion (resource, time_hi, time_lo,
129 | wl_fixed_from_double (dx),
130 | wl_fixed_from_double (dy),
131 | wl_fixed_from_double (dx),
132 | wl_fixed_from_double (dy));
133 | }
134 |
--------------------------------------------------------------------------------
/idle-inhibit-unstable-v1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright © 2015 Samsung Electronics Co., Ltd
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a
8 | copy of this software and associated documentation files (the "Software"),
9 | to deal in the Software without restriction, including without limitation
10 | the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 | and/or sell copies of the Software, and to permit persons to whom the
12 | Software is furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice (including the next
15 | paragraph) shall be included in all copies or substantial portions of the
16 | Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 | DEALINGS IN THE SOFTWARE.
25 |
26 |
27 |
28 |
29 | This interface permits inhibiting the idle behavior such as screen
30 | blanking, locking, and screensaving. The client binds the idle manager
31 | globally, then creates idle-inhibitor objects for each surface.
32 |
33 | Warning! The protocol described in this file is experimental and
34 | backward incompatible changes may be made. Backward compatible changes
35 | may be added together with the corresponding interface version bump.
36 | Backward incompatible changes are done by bumping the version number in
37 | the protocol and interface names and resetting the interface version.
38 | Once the protocol is to be declared stable, the 'z' prefix and the
39 | version number in the protocol and interface names are removed and the
40 | interface version number is reset.
41 |
42 |
43 |
44 |
45 | Destroy the inhibit manager.
46 |
47 |
48 |
49 |
50 |
51 | Create a new inhibitor object associated with the given surface.
52 |
53 |
54 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | An idle inhibitor prevents the output that the associated surface is
63 | visible on from being set to a state where it is not visually usable due
64 | to lack of user interaction (e.g. blanked, dimmed, locked, set to power
65 | save, etc.) Any screensaver processes are also blocked from displaying.
66 |
67 | If the surface is destroyed, unmapped, becomes occluded, loses
68 | visibility, or otherwise becomes not visually relevant for the user, the
69 | idle inhibitor will not be honored by the compositor; if the surface
70 | subsequently regains visibility the inhibitor takes effect once again.
71 | Likewise, the inhibitor isn't honored if the system was already idled at
72 | the time the inhibitor was established, although if the system later
73 | de-idles and re-idles the inhibitor will take effect.
74 |
75 |
76 |
77 |
78 | Remove the inhibitor effect from the associated wl_surface.
79 |
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/buffer_release.c:
--------------------------------------------------------------------------------
1 | /* Wayland compositor running on top of an X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include "compositor.h"
21 |
22 | /* Simple helper code for managing buffer release in surfaces. */
23 |
24 | typedef struct _ReleaseLaterRecord ReleaseLaterRecord;
25 |
26 | struct _ReleaseLaterRecord
27 | {
28 | /* A monotonically (overflow aside) increasing identifier. */
29 | uint64_t id;
30 |
31 | /* The buffer that should be released upon receiving this
32 | message. */
33 | ExtBuffer *buffer;
34 |
35 | /* The idle callback, if any. */
36 | IdleCallbackKey key;
37 |
38 | /* The buffer release helper. */
39 | BufferReleaseHelper *helper;
40 |
41 | /* The next and last records. */
42 | ReleaseLaterRecord *next, *last;
43 | };
44 |
45 | struct _BufferReleaseHelper
46 | {
47 | /* Queue of buffers pending release. */
48 | ReleaseLaterRecord records;
49 |
50 | /* Callback run upon all buffers being released. */
51 | AllReleasedCallback callback;
52 |
53 | /* Data for that callback. */
54 | void *callback_data;
55 | };
56 |
57 | BufferReleaseHelper *
58 | MakeBufferReleaseHelper (AllReleasedCallback callback,
59 | void *callback_data)
60 | {
61 | BufferReleaseHelper *helper;
62 |
63 | helper = XLCalloc (1, sizeof *helper);
64 | helper->records.next = &helper->records;
65 | helper->records.last = &helper->records;
66 | helper->callback = callback;
67 | helper->callback_data = callback_data;
68 |
69 | return helper;
70 | }
71 |
72 | void
73 | FreeBufferReleaseHelper (BufferReleaseHelper *helper)
74 | {
75 | ReleaseLaterRecord *next, *last;
76 |
77 | /* Do an XSync, and then release all the records. */
78 | XSync (compositor.display, False);
79 |
80 | next = helper->records.next;
81 | while (next != &helper->records)
82 | {
83 | last = next;
84 | next = next->next;
85 |
86 | /* Cancel the idle callback if it already exists. */
87 | if (last->key)
88 | RenderCancelIdleCallback (last->key);
89 |
90 | /* Release the buffer now. */
91 | XLReleaseBuffer (last->buffer);
92 |
93 | /* Before freeing the record itself. */
94 | XLFree (last);
95 | }
96 |
97 | /* Free the helper. */
98 | XLFree (helper);
99 | }
100 |
101 | static void
102 | BufferIdleCallback (RenderBuffer buffer, void *data)
103 | {
104 | ReleaseLaterRecord *record;
105 | BufferReleaseHelper *helper;
106 |
107 | record = data;
108 | helper = record->helper;
109 |
110 | /* Release the buffer. */
111 | XLReleaseBuffer (record->buffer);
112 |
113 | /* Unlink and free the record. */
114 | record->next->last = record->last;
115 | record->last->next = record->next;
116 | XLFree (record);
117 |
118 | /* If there are no more records in the helper, run its
119 | all-released-callback. */
120 | if (helper->records.next == &helper->records)
121 | helper->callback (helper->callback_data);
122 | }
123 |
124 | void
125 | ReleaseBufferWithHelper (BufferReleaseHelper *helper, ExtBuffer *buffer,
126 | RenderTarget target)
127 | {
128 | ReleaseLaterRecord *record;
129 | RenderBuffer render_buffer;
130 |
131 | render_buffer = XLRenderBufferFromBuffer (buffer);
132 |
133 | record = XLCalloc (1, sizeof *record);
134 | record->next = helper->records.next;
135 | record->last = &helper->records;
136 | helper->records.next->last = record;
137 | helper->records.next = record;
138 |
139 | /* Now, the record is linked into the list. Record the buffer and
140 | add an idle callback. */
141 | record->buffer = buffer;
142 | record->key = RenderAddIdleCallback (render_buffer, target,
143 | BufferIdleCallback,
144 | record);
145 | record->helper = helper;
146 | }
147 |
--------------------------------------------------------------------------------
/xdg_wm.c:
--------------------------------------------------------------------------------
1 | /* Wayland compositor running on top of an X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include
21 |
22 | #include "compositor.h"
23 | #include "xdg-shell.h"
24 |
25 | /* The xdg_wm_base global. */
26 | static struct wl_global *global_xdg_wm_base;
27 |
28 | static void
29 | CreatePositioner (struct wl_client *client, struct wl_resource *resource,
30 | uint32_t id)
31 | {
32 | XLCreateXdgPositioner (client, resource, id);
33 | }
34 |
35 | static void
36 | GetXdgSurface (struct wl_client *client, struct wl_resource *resource,
37 | uint32_t id, struct wl_resource *surface_resource)
38 | {
39 | XLGetXdgSurface (client, resource, id, surface_resource);
40 | }
41 |
42 | static void
43 | Pong (struct wl_client *client, struct wl_resource *resource,
44 | uint32_t serial)
45 | {
46 | XdgWmBase *wm_base;
47 | XdgRoleList *role;
48 |
49 | /* Ping-pong implementation. Every time a ping request is received
50 | from the window manager, it is linked onto the list of all such
51 | requests on the toplevel. Then, ping is sent with a serial.
52 | Once the pong with the latest serial arrives from the client,
53 | pending requests are sent back to the window manager on all
54 | windows. */
55 | wm_base = wl_resource_get_user_data (resource);
56 |
57 | if (serial == wm_base->last_ping)
58 | {
59 | /* Reply to the ping events sent to each surface created with
60 | this wm_base. */
61 | role = wm_base->list.next;
62 | while (role != &wm_base->list)
63 | {
64 | XLXdgRoleReplyPing (role->role);
65 | role = role->next;
66 | }
67 | }
68 | }
69 |
70 | static void
71 | Destroy (struct wl_client *client, struct wl_resource *resource)
72 | {
73 | XdgWmBase *wm_base;
74 |
75 | /* If there are still xdg_surfaces created by this xdg_wm_base
76 | resource, post an error. */
77 | wm_base = wl_resource_get_user_data (resource);
78 |
79 | if (wm_base->list.next != &wm_base->list)
80 | wl_resource_post_error (resource, XDG_WM_BASE_ERROR_DEFUNCT_SURFACES,
81 | "surfaces created by this xdg_wm_base still"
82 | " exist, yet it is being destroyed");
83 |
84 | wl_resource_destroy (resource);
85 | }
86 |
87 | static const struct xdg_wm_base_interface xdg_wm_base_impl =
88 | {
89 | .destroy = Destroy,
90 | .create_positioner = CreatePositioner,
91 | .get_xdg_surface = GetXdgSurface,
92 | .pong = Pong,
93 | };
94 |
95 | static void
96 | HandleResourceDestroy (struct wl_resource *resource)
97 | {
98 | XdgWmBase *wm_base;
99 | XdgRoleList *role, *last;
100 |
101 | wm_base = wl_resource_get_user_data (resource);
102 |
103 | /* Detach each surface. */
104 | role = wm_base->list.next;
105 | while (role != &wm_base->list)
106 | {
107 | last = role;
108 | role = role->next;
109 |
110 | /* Complete all ping events. */
111 | XLXdgRoleReplyPing (last->role);
112 |
113 | /* Tell the surface to not bother unlinking itself. */
114 | last->next = NULL;
115 | last->last = NULL;
116 | last->role = NULL;
117 | }
118 |
119 | XLFree (wm_base);
120 | }
121 |
122 | static void
123 | HandleBind (struct wl_client *client, void *data,
124 | uint32_t version, uint32_t id)
125 | {
126 | XdgWmBase *wm_base;
127 |
128 | wm_base = XLSafeMalloc (sizeof *wm_base);
129 |
130 | if (!wm_base)
131 | {
132 | wl_client_post_no_memory (client);
133 | return;
134 | }
135 |
136 | memset (wm_base, 0, sizeof *wm_base);
137 | wm_base->resource
138 | = wl_resource_create (client, &xdg_wm_base_interface,
139 | version, id);
140 |
141 | if (!wm_base->resource)
142 | {
143 | XLFree (wm_base);
144 | wl_client_post_no_memory (client);
145 | return;
146 | }
147 |
148 | wl_resource_set_implementation (wm_base->resource, &xdg_wm_base_impl,
149 | wm_base, HandleResourceDestroy);
150 | wm_base->list.next = &wm_base->list;
151 | wm_base->list.last = &wm_base->list;
152 | }
153 |
154 | void
155 | XLInitXdgWM (void)
156 | {
157 | global_xdg_wm_base
158 | = wl_global_create (compositor.wl_display,
159 | &xdg_wm_base_interface,
160 | 5, NULL, HandleBind);
161 | }
162 |
163 | void
164 | XLXdgWmBaseSendPing (XdgWmBase *wm_base)
165 | {
166 | xdg_wm_base_send_ping (wm_base->resource,
167 | ++wm_base->last_ping);
168 | }
169 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | This is a tool for running Wayland applications on an X server,
2 | preferably with a compositing manager running.
3 |
4 | It is not yet complete. What is not yet implemented includes support
5 | for touchscreens, and device switching in dmabuf feedback.
6 |
7 | It is not portable to systems other than recent versions of GNU/Linux
8 | running the X.Org server 1.20 or later, and has not been tested on
9 | window (and compositing) managers other than GNOME Shell.
10 |
11 | It will not work very well unless the compositing manager supports the
12 | EWMH frame synchronization protocol.
13 |
14 | Building and running this tool requires the following X protocol
15 | extensions:
16 |
17 | Nonrectangular Window Shape Extension, version 1.1 or later
18 | MIT Shared Memory Extension, version 1.2 or later
19 | X Resize, Rotate and Reflect Extension, version 1.4 or later
20 | X Synchronization Extension, version 1.0 or later
21 | X Rendering Extension, version 1.2 or later
22 | X Input Extension, version 2.3 or later
23 | Direct Rendering Interface 3, version 1.2 or later
24 | X Fixes Extension, version 1.5 or later
25 | X Presentation Extension, version 1.0 or later
26 |
27 | In addition, it requires Xlib to be built with the XCB transport, and
28 | the XCB bindings for MIT-SHM and DRI3 to be available.
29 |
30 | Sometimes, it might be desirable to build with EGL, and use OpenGL ES
31 | 2.0 for i.e. YUV video format support. To do so, uncomment the block
32 | of code for EGL support in 12to11.conf before running `xmkmf'. This
33 | will additionally require the EGL and GLESv2 development files, and
34 | for the following EGL and GLES extensions to be present at runtime:
35 |
36 | EGL_EXT_platform_base
37 | EGL_EXT_device_query
38 | EGL_KHR_image_base
39 | EGL_EXT_image_dma_buf_import_modifiers
40 | EGL_EXT_image_dma_buf_import
41 | EGL_EXT_buffer_age
42 |
43 | GL_OES_EGL_image
44 | GL_OES_EGL_image_external
45 | GL_EXT_read_format_bgra
46 | GL_EXT_unpack_subimage
47 |
48 | After building with EGL support, the renderer must be enabled by
49 | setting the environment variable "RENDERER" to "egl", or by setting
50 | the "renderer" resource (class "Renderer") to "egl".
51 |
52 | The following Wayland protocols are implemented to a more-or-less
53 | complete degree:
54 |
55 | 'wl_output', version: 4
56 | 'wl_compositor', version: 5
57 | 'wl_shm', version: 1
58 | 'xdg_wm_base', version: 5
59 | 'wl_subcompositor', version: 1
60 | 'wl_seat', version: 8
61 | 'wl_data_device_manager', version: 3
62 | 'zwp_linux_dmabuf_v1', version: 4
63 | 'zwp_primary_selection_device_manager_v1', version: 1
64 | 'wp_viewporter', version: 1
65 | 'zxdg_decoration_manager_v1', version: 1
66 | 'zwp_text_input_manager_v3', version: 1
67 | 'wp_single_pixel_buffer_manager_v1', version: 1
68 | 'zwp_pointer_constraints_v1', version: 1
69 | 'zwp_relative_pointer_manager_v1', version: 1
70 | 'zwp_idle_inhibit_manager_v1', version: 1
71 | 'xdg_activation_v1', version: 1
72 | 'wp_tearing_control_manager_v1', version: 1
73 |
74 | When built with EGL, the following Wayland protocol is also supported:
75 |
76 | 'zwp_linux_explicit_synchronization_v1', version: 2
77 |
78 | When the X server supports version 1.6 or later of the X Resize,
79 | Rotate and Reflect Extension, the following Wayland protocol is also
80 | supported:
81 |
82 | 'wp_drm_lease_device_v1', version: 1
83 |
84 | When the X server supports version 2.4 or later of the X Input
85 | Extension, the following Wayland protocol is also supported:
86 |
87 | 'zwp_pointer_gestures_v1', version: 3
88 |
89 | This directory is organized as follows:
90 |
91 | Imakefile - the top level Makefile template
92 | 12to11.conf - configuration
93 | *.xml - Wayland protocol definition source
94 | *.c, *.h - C source code
95 | *.awk - scripts used to generate headers
96 | *.txt - text data used to generate some headers, i.e.
97 | those containing MIME types or shaders
98 |
99 | Building the source code is simple, provided that you have the
100 | necessary libwayland-server library, pixman, XCB, DRM, xshmfence, and
101 | X extension libraries installed:
102 |
103 | xmkmf # to generate the Makefile
104 | make # to build the binary
105 |
106 | wayland-scanner is also required when building from the repository.
107 |
108 | Running the binary should be simple as well:
109 |
110 | ./12to11
111 |
112 | Wayland programs will then run as regular X windows.
113 |
114 | Be sure to configure your system so that idle inhibition is reported
115 | correctly. For more details, see the description of the
116 | idleInhibitCommand resource in the manual page.
117 |
--------------------------------------------------------------------------------
/tests/imgview.c:
--------------------------------------------------------------------------------
1 | /* Tests for the Wayland compositor running on the X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include
21 |
22 | #include "test_harness.h"
23 |
24 | /* imgview -- simple viewer for .dump files. It opens each file as an
25 | argument and displays it in a window. */
26 |
27 | /* The display imgview is connected to. */
28 | static Display *display;
29 |
30 | /* The visual being used. */
31 | static Visual *visual;
32 |
33 | /* Various image parameters. */
34 | static int width, height, depth;
35 |
36 | static int
37 | get_depth_for_format (struct image_data_header *header)
38 | {
39 | switch (header->format)
40 | {
41 | case IMAGE_DATA_ARGB8888_LE:
42 | return 32;
43 |
44 | case IMAGE_DATA_XRGB8888_LE:
45 | return 24;
46 | }
47 |
48 | return 0;
49 | }
50 |
51 | static Visual *
52 | get_visual_for_format (struct image_data_header *header)
53 | {
54 | XVisualInfo template, *visuals;
55 | Visual *visual;
56 | unsigned long mask;
57 | int n_visuals;
58 |
59 | /* This isn't right if the pixel layout differs, but the program
60 | assumes that all 24-depth visuals are XRGB8888 and all 32-bit
61 | ones are ARGB8888. */
62 |
63 | template.screen = DefaultScreen (display);
64 | template.class = TrueColor;
65 |
66 | switch (header->format)
67 | {
68 | case IMAGE_DATA_ARGB8888_LE:
69 | template.depth = 32;
70 | break;
71 |
72 | case IMAGE_DATA_XRGB8888_LE:
73 | template.depth = 24;
74 | break;
75 | }
76 |
77 | mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
78 | visuals = XGetVisualInfo (display, mask, &template, &n_visuals);
79 |
80 | if (!n_visuals)
81 | {
82 | if (visuals)
83 | XFree (visuals);
84 |
85 | return NULL;
86 | }
87 |
88 | visual = visuals[0].visual;
89 | XFree (visuals);
90 | return visual;
91 | }
92 |
93 | static Pixmap
94 | get_image (const char *filename)
95 | {
96 | unsigned char *data;
97 | struct image_data_header header;
98 | XImage *image;
99 | Pixmap pixmap;
100 | GC gc;
101 |
102 | data = load_image_data (filename, &header);
103 |
104 | if (!data)
105 | return None;
106 |
107 | visual = get_visual_for_format (&header);
108 | depth = get_depth_for_format (&header);
109 |
110 | if (!depth || !visual)
111 | {
112 | free (data);
113 | return None;
114 | }
115 |
116 | image = XCreateImage (display, visual, depth, ZPixmap, 0,
117 | (char *) data, header.width,
118 | header.height, 8, header.stride);
119 | image->data = (char *) data;
120 |
121 | pixmap = XCreatePixmap (display, DefaultRootWindow (display),
122 | header.width, header.height, depth);
123 | gc = XCreateGC (display, pixmap, 0, NULL);
124 |
125 | /* Upload the image to the pixmap and free the GC. */
126 | XPutImage (display, pixmap, gc, image, 0, 0,
127 | 0, 0, header.width, header.height);
128 | XFreeGC (display, gc);
129 |
130 | /* Destroy the XImage data. */
131 | free (image->data);
132 | image->data = NULL;
133 |
134 | /* Destroy the XImage. */
135 | XDestroyImage (image);
136 |
137 | /* Set image params. */
138 | width = header.width;
139 | height = header.height;
140 | depth = depth;
141 |
142 | return pixmap;
143 | }
144 |
145 | static void
146 | loop_for_events (void)
147 | {
148 | XEvent event;
149 |
150 | while (true)
151 | XNextEvent (display, &event);
152 | }
153 |
154 | static void
155 | open_window (Pixmap image)
156 | {
157 | Window window;
158 | XSetWindowAttributes attrs;
159 | unsigned long flags;
160 |
161 | attrs.colormap = XCreateColormap (display,
162 | DefaultRootWindow (display),
163 | visual, AllocNone);
164 | /* This should be valid on any TrueColor visual. */
165 | attrs.border_pixel = 0;
166 | attrs.background_pixmap = image;
167 | attrs.cursor = None;
168 | flags = (CWColormap | CWBorderPixel | CWBackPixmap | CWCursor);
169 |
170 | window = XCreateWindow (display,
171 | DefaultRootWindow (display),
172 | 0, 0, width, height, 0, depth,
173 | InputOutput, visual, flags,
174 | &attrs);
175 | XMapRaised (display, window);
176 | }
177 |
178 | int
179 | main (int argc, char **argv)
180 | {
181 | Pixmap image;
182 | int i;
183 |
184 | if (argc < 2)
185 | return 1;
186 |
187 | display = XOpenDisplay (NULL);
188 |
189 | if (!display)
190 | return 1;
191 |
192 | for (i = 1; i < argc; ++i)
193 | {
194 | image = get_image (argv[i]);
195 |
196 | if (!image)
197 | continue;
198 |
199 | open_window (image);
200 | }
201 |
202 | loop_for_events ();
203 | }
204 |
--------------------------------------------------------------------------------
/tests/Imakefile:
--------------------------------------------------------------------------------
1 | #include "../12to11.conf"
2 |
3 | 12TO11ROOT = ..
4 | DEPLIBS = $(DEPXLIB)
5 | SYS_LIBRARIES = MathLibrary
6 | LOCAL_LIBRARIES = $(WAYLAND_CLIENT) $(XLIB) $(PNG)
7 | COMMONOBJS = test_harness.o
8 | COMMONSRCS = test_harness.c
9 | HEADER = test_harness.h
10 | GENFILES =
11 | EXTRA_DEFINES := -D_GNU_SOURCE -U_BSD_SOURCE -U_SVID_SOURCE
12 | INCLUDES := $(DRMINCLUDES) $(PIXMANINCLUDES)
13 |
14 | #define ScannerTarget(name) @@\
15 | name.h: $(12TO11ROOT)/name.xml @@\
16 | $(WAYLAND_SCANNER) client-header $< $@ @@\
17 | @@\
18 | name.c: $(12TO11ROOT)/name.xml name.h @@\
19 | $(WAYLAND_SCANNER) private-code $< $@ @@\
20 | @@\
21 | COMMONOBJS := $(COMMONOBJS) name.o @@\
22 | COMMONSRCS := $(COMMONSRCS) name.c @@\
23 | GENFILES := $(GENFILES) name.c name.h @@\
24 | HEADER := $(HEADER) name.h @@\
25 |
26 | ScannerTarget(12to11-test)
27 | ScannerTarget(viewporter)
28 | ScannerTarget(linux-dmabuf-unstable-v1)
29 | ScannerTarget(xdg-activation-v1)
30 | ScannerTarget(single-pixel-buffer-v1)
31 | ScannerTarget(tearing-control-v1)
32 |
33 | /* Not actually a test. */
34 | SRCS1 = $(COMMONSRCS) imgview.c
35 | OBJS1 = $(COMMONSRCS) imgview.o
36 | SRCS2 = $(COMMONSRCS) simple_test.c
37 | OBJS2 = $(COMMONOBJS) simple_test.o
38 | SRCS3 = $(COMMONSRCS) damage_test.c
39 | OBJS3 = $(COMMONOBJS) damage_test.o
40 | SRCS4 = $(COMMONSRCS) transform_test.c
41 | OBJS4 = $(COMMONSRCS) transform_test.o
42 | SRCS5 = $(COMMONSRCS) viewporter_test.c
43 | OBJS5 = $(COMMONSRCS) viewporter_test.o
44 | SRCS6 = $(COMMONSRCS) subsurface_test.c
45 | OBJS6 = $(COMMONSRCS) subsurface_test.o
46 | SRCS7 = $(COMMONSRCS) scale_test.c
47 | OBJS7 = $(COMMONSRCS) scale_test.o
48 | SRCS8 = $(COMMONSRCS) seat_test.c
49 | OBJS8 = $(COMMONSRCS) seat_test.o
50 | SRCS9 = $(COMMONSRCS) dmabuf_test.c
51 | OBJS9 = $(COMMONSRCS) dmabuf_test.o
52 | SRCS10 = $(COMMONSRCS) select_test.c
53 | OBJS10 = $(COMMONSRCS) select_test.o
54 | SRCS11 = select_helper.c
55 | OBJS11 = select_helper.o
56 | SRCS12 = select_helper_multiple.c
57 | OBJS12 = select_helper_multiple.o
58 | SRCS13 = $(COMMONSRCS) xdg_activation_test.c
59 | OBJS13 = $(COMMONSRCS) xdg_activation_test.o
60 | SRCS14 = $(COMMONSRCS) single_pixel_buffer_test.c
61 | OBJS14 = $(COMMONSRCS) single_pixel_buffer_test.o
62 | SRCS15 = $(COMMONSRCS) buffer_test.c
63 | OBJS15 = $(COMMONSRCS) buffer_test.o
64 | SRCS16 = $(COMMONSRCS) tearing_control_test.c
65 | OBJS16 = $(COMMONSRCS) tearing_control_test.o
66 | PROGRAMS = imgview simple_test damage_test transform_test viewporter_test subsurface_test scale_test seat_test dmabuf_test select_test select_helper select_helper_multiple xdg_activation_test single_pixel_buffer_test buffer_test tearing_control_test
67 |
68 | /* Make all objects depend on HEADER. */
69 | $(OBJS1): $(HEADER)
70 | $(OBJS2): $(HEADER)
71 | $(OBJS3): $(HEADER)
72 | $(OBJS4): $(HEADER)
73 | $(OBJS5): $(HEADER)
74 | $(OBJS6): $(HEADER)
75 | $(OBJS7): $(HEADER)
76 | $(OBJS8): $(HEADER)
77 | $(OBJS9): $(HEADER)
78 | $(OBJS10): $(HEADER)
79 | $(OBJS13): $(HEADER)
80 | $(OBJS14): $(HEADER)
81 | $(OBJS15): $(HEADER)
82 | $(OBJS16): $(HEADER)
83 |
84 | /* And depend on all sources and headers. */
85 | depend:: $(HEADER) $(COMMONSRCS)
86 |
87 | NormalProgramTarget(imgview,$(OBJS1),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
88 | NormalProgramTarget(simple_test,$(OBJS2),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
89 | NormalProgramTarget(damage_test,$(OBJS3),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
90 | NormalProgramTarget(transform_test,$(OBJS4),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
91 | NormalProgramTarget(viewporter_test,$(OBJS5),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
92 | NormalProgramTarget(subsurface_test,$(OBJS6),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
93 | NormalProgramTarget(scale_test,$(OBJS7),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
94 | NormalProgramTarget(seat_test,$(OBJS8),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
95 | NormalProgramTarget(dmabuf_test,$(OBJS9),NullParameter,$(LOCAL_LIBRARIES) $(GBM) $(DRM),NullParameter)
96 | NormalProgramTarget(select_test,$(OBJS10),NullParameter,$(LOCAL_LIBRARIES) ThreadsLibraries,NullParameter)
97 | NormalProgramTarget(select_helper,$(OBJS11),NullParameter,$(XLIB),NullParameter)
98 | NormalProgramTarget(select_helper_multiple,$(OBJS12),NullParameter,$(XLIB),NullParameter)
99 | NormalProgramTarget(xdg_activation_test,$(OBJS13),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
100 | NormalProgramTarget(single_pixel_buffer_test,$(OBJS14),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
101 | NormalProgramTarget(buffer_test,$(OBJS15),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
102 | NormalProgramTarget(tearing_control_test,$(OBJS16),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
103 | DependTarget3($(SRCS1),$(SRCS2),$(SRCS3))
104 | DependTarget3($(SRCS4),$(SRCS5),$(SRCS6))
105 | DependTarget3($(SRCS7),$(SRCS8),$(SRCS9))
106 | DependTarget3($(SRCS10),$(SRCS11),$(SRCS12))
107 | DependTarget3($(SRCS13),$(SRCS14),$(SRCS15))
108 | DependTarget3($(SRCS16),NullParameter,NullParameter)
109 |
110 | all:: $(PROGRAMS)
111 |
112 | clean::
113 | $(RM) $(GENFILES)
114 |
--------------------------------------------------------------------------------
/tests/test_harness.h:
--------------------------------------------------------------------------------
1 | /* Tests for the Wayland compositor running on the X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include
30 |
31 | #include
32 |
33 | #include
34 | #include
35 |
36 | #include "12to11-test.h"
37 |
38 | struct test_seat
39 | {
40 | /* The test seat, if any. */
41 | struct test_seat_controller *controller;
42 |
43 | /* The device manager, if any. */
44 | struct test_device_controller *device_controller;
45 |
46 | /* The seat resource itself. */
47 | struct wl_seat *seat;
48 |
49 | /* The wl_pointer resource. */
50 | struct wl_pointer *pointer;
51 |
52 | /* The keyboard resource. */
53 | struct wl_keyboard *keyboard;
54 |
55 | /* The device ID of the seat. */
56 | uint32_t device_id;
57 |
58 | /* The buttons currently held down. */
59 | unsigned char buttons;
60 | };
61 |
62 | struct test_display
63 | {
64 | /* The wayland display. */
65 | struct wl_display *display;
66 |
67 | /* The X display. */
68 | Display *x_display;
69 |
70 | /* List of pixmap formats. */
71 | XPixmapFormatValues *pixmap_formats;
72 |
73 | /* Number of pixmap formats. */
74 | int num_pixmap_formats;
75 |
76 | /* The registry and various Wayland interfaces. */
77 | struct wl_registry *registry;
78 | struct wl_compositor *compositor;
79 | struct wl_shm *shm;
80 | struct test_manager *test_manager;
81 |
82 | /* The test scale lock. */
83 | struct test_scale_lock *scale_lock;
84 |
85 | /* Test interfaces. */
86 | struct test_interface *interfaces;
87 |
88 | /* The test seat. */
89 | struct test_seat *seat;
90 |
91 | /* The number of such interfaces. */
92 | int num_test_interfaces;
93 |
94 | /* Internal field used by test_get_serial. */
95 | uint32_t serial;
96 | };
97 |
98 | struct test_interface
99 | {
100 | /* The name of the interface. */
101 | const char *interface;
102 |
103 | /* Pointer to the interface data. */
104 | void *data;
105 |
106 | /* Pointer to the interface. */
107 | const struct wl_interface *c_interface;
108 |
109 | /* The wanted version. */
110 | uint32_t version;
111 | };
112 |
113 | struct test_buffer
114 | {
115 | /* The associated struct wl_buffer. */
116 | struct wl_buffer *buffer;
117 |
118 | /* Whether or not the buffer is busy. */
119 | int is_busy;
120 | };
121 |
122 | struct image_data_header
123 | {
124 | /* Currently 1. High bit is byte order. */
125 | unsigned char version;
126 |
127 | /* The data format. Currently always 0. */
128 | unsigned char format;
129 |
130 | /* The width and height. */
131 | unsigned short width, height;
132 |
133 | /* Padding. */
134 | unsigned short pad1;
135 |
136 | /* The stride. */
137 | unsigned int stride;
138 | };
139 |
140 | enum image_data_format
141 | {
142 | /* Little-endian ARGB8888. */
143 | IMAGE_DATA_ARGB8888_LE,
144 | /* Little-endian XRGB8888. */
145 | IMAGE_DATA_XRGB8888_LE,
146 | };
147 |
148 | extern void die (const char *) __attribute__ ((noreturn));
149 | extern struct test_display *open_test_display (struct test_interface *, int);
150 | extern int get_shm_file_descriptor (void);
151 | extern size_t get_image_stride (struct test_display *, int, int);
152 | extern struct wl_buffer *upload_image_data (struct test_display *,
153 | const char *, int, int,
154 | int);
155 | extern void report_test_failure (const char *, ...)
156 | __attribute__ ((noreturn, format (gnu_printf, 1, 2)));
157 | extern void test_log (const char *, ...)
158 | __attribute__ ((format (gnu_printf, 1, 2)));
159 |
160 | extern bool make_test_surface (struct test_display *, struct wl_surface **,
161 | struct test_surface **);
162 | extern struct wl_buffer *load_png_image (struct test_display *, const char *);
163 | extern unsigned char *load_image_data (const char *,
164 | struct image_data_header *);
165 | extern void verify_image_data (struct test_display *, Window, const char *);
166 | extern void test_init (void);
167 | extern void test_complete (void) __attribute__ ((noreturn));
168 | extern void test_set_scale (struct test_display *, int);
169 | extern void test_init_seat (struct test_display *);
170 | extern uint32_t test_get_serial (struct test_display *);
171 | extern void verify_window_size (struct test_display *, Window, int, int);
172 | extern struct test_buffer *get_test_buffer (struct test_display *,
173 | struct wl_buffer *);
174 | extern void test_buffer_committed (struct test_buffer *);
175 | extern void verify_buffer_released (struct test_buffer *);
176 |
177 | #define ARRAYELTS(arr) (sizeof (arr) / sizeof (arr)[0])
178 |
179 | #if __GNUC__ >= 7
180 | #define FALLTHROUGH __attribute__ ((fallthrough))
181 | #else
182 | #define FALLTHROUGH ((void) 0)
183 | #endif
184 |
--------------------------------------------------------------------------------
/tests/select_helper.c:
--------------------------------------------------------------------------------
1 | /* Tests for the Wayland compositor running on the X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 |
25 | #include
26 | #include
27 |
28 | /* select_helper.c -- Read the data of the clipboard selection and
29 | print them to stdout.
30 |
31 | There must be three arguments: the name of the display, the
32 | timestamp at which the selection was acquired, and the target. */
33 |
34 | /* The display connected to. */
35 | static Display *display;
36 |
37 | /* The selection transfer window. */
38 | static Window selection_transfer_window;
39 |
40 | /* Various atoms. */
41 | static Atom CLIPBOARD, target_atom, INCR;
42 |
43 | static void
44 | wait_for_selection_notify (XEvent *event)
45 | {
46 | while (true)
47 | {
48 | XNextEvent (display, event);
49 |
50 | if (event->type == SelectionNotify
51 | && (event->xselection.requestor
52 | == selection_transfer_window)
53 | && (event->xselection.selection
54 | == CLIPBOARD)
55 | && (event->xselection.property
56 | == target_atom)
57 | && (event->xselection.target
58 | == target_atom))
59 | return;
60 | }
61 | }
62 |
63 | static void
64 | wait_for_new_value (XEvent *event, Atom property)
65 | {
66 | while (true)
67 | {
68 | XNextEvent (display, event);
69 |
70 | if (event->type == PropertyNotify
71 | && event->xproperty.atom == property
72 | && event->xproperty.state == PropertyNewValue)
73 | return;
74 | }
75 | }
76 |
77 | static size_t
78 | get_size_for_format (int format)
79 | {
80 | switch (format)
81 | {
82 | case 32:
83 | return sizeof (long);
84 |
85 | case 16:
86 | return sizeof (short int);
87 |
88 | case 8:
89 | return sizeof (char);
90 | }
91 |
92 | /* Should not actually happen. */
93 | return 0;
94 | }
95 |
96 | int
97 | main (int argc, char **argv)
98 | {
99 | XSetWindowAttributes attrs;
100 | unsigned long flags, timestamp;
101 | char *atom_names[3];
102 | Atom atoms[3], actual_type, property;
103 | XEvent event;
104 | int actual_format;
105 | unsigned long nitems, bytes_after;
106 | unsigned char *data;
107 |
108 | if (argc < 4)
109 | /* Not enough arguments were specified. */
110 | return 1;
111 |
112 | display = XOpenDisplay (argv[1]);
113 |
114 | if (!display)
115 | return 1;
116 |
117 | /* Make the window used to transfer selection data. */
118 | attrs.override_redirect = True;
119 | attrs.event_mask = PropertyChangeMask;
120 | flags = CWEventMask | CWOverrideRedirect;
121 |
122 | selection_transfer_window
123 | = XCreateWindow (display, DefaultRootWindow (display),
124 | -1, -1, 1, 1, 0, CopyFromParent, InputOnly,
125 | CopyFromParent, flags, &attrs);
126 |
127 | /* Get the time. */
128 | timestamp = strtoul (argv[2], NULL, 10);
129 |
130 | atom_names[0] = argv[3];
131 | atom_names[1] = (char *) "CLIPBOARD";
132 | atom_names[2] = (char *) "INCR";
133 | XInternAtoms (display, atom_names, 3, False, atoms);
134 | target_atom = atoms[0];
135 | CLIPBOARD = atoms[1];
136 | INCR = atoms[2];
137 |
138 | /* Now ask for CLIPBOARD. */
139 | XConvertSelection (display, CLIPBOARD, target_atom,
140 | target_atom, selection_transfer_window,
141 | timestamp);
142 |
143 | /* And wait for the SelectionNotify event. */
144 | wait_for_selection_notify (&event);
145 |
146 | /* Selection conversion failed. */
147 | if (event.xselection.property == None)
148 | return 1;
149 |
150 | property = event.xselection.property;
151 |
152 | XGetWindowProperty (display, selection_transfer_window,
153 | property, 0, 0xffffffff, True, AnyPropertyType,
154 | &actual_type, &actual_format, &nitems, &bytes_after,
155 | &data);
156 |
157 | if (!data || bytes_after)
158 | return 1;
159 |
160 | if (actual_type == INCR)
161 | {
162 | while (true)
163 | {
164 | XFree (data);
165 |
166 | wait_for_new_value (&event, property);
167 | XGetWindowProperty (display, selection_transfer_window, property, 0,
168 | 0xffffffff, True, AnyPropertyType, &actual_type,
169 | &actual_format, &nitems, &bytes_after, &data);
170 |
171 | if (!data)
172 | return 0;
173 |
174 | if (nitems)
175 | {
176 | /* Write the selection data to stdout. */
177 | if (fwrite (data, get_size_for_format (actual_format),
178 | nitems, stdout) != nitems)
179 | return 1;
180 |
181 | continue;
182 | }
183 |
184 | /* Selection transfer is complete. */
185 | fflush (stdout);
186 | return 0;
187 | }
188 | }
189 | else
190 | {
191 | /* Write the selection data to stdout. */
192 | if (fwrite (data, get_size_for_format (actual_format),
193 | nitems, stdout) != nitems)
194 | return 1;
195 |
196 | /* Return success. */
197 | fflush (stdout);
198 | return 0;
199 | }
200 | }
201 |
--------------------------------------------------------------------------------
/tearing-control-v1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Copyright © 2021 Xaver Hugl
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a
7 | copy of this software and associated documentation files (the "Software"),
8 | to deal in the Software without restriction, including without limitation
9 | the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | and/or sell copies of the Software, and to permit persons to whom the
11 | Software is furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice (including the next
14 | paragraph) shall be included in all copies or substantial portions of the
15 | Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | DEALINGS IN THE SOFTWARE.
24 |
25 |
26 |
27 |
28 | For some use cases like games or drawing tablets it can make sense to
29 | reduce latency by accepting tearing with the use of asynchronous page
30 | flips. This global is a factory interface, allowing clients to inform
31 | which type of presentation the content of their surfaces is suitable for.
32 |
33 | Graphics APIs like EGL or Vulkan, that manage the buffer queue and commits
34 | of a wl_surface themselves, are likely to be using this extension
35 | internally. If a client is using such an API for a wl_surface, it should
36 | not directly use this extension on that surface, to avoid raising a
37 | tearing_control_exists protocol error.
38 |
39 | Warning! The protocol described in this file is currently in the testing
40 | phase. Backward compatible changes may be added together with the
41 | corresponding interface version bump. Backward incompatible changes can
42 | only be done by creating a new major version of the extension.
43 |
44 |
45 |
46 |
47 | Destroy this tearing control factory object. Other objects, including
48 | wp_tearing_control_v1 objects created by this factory, are not affected
49 | by this request.
50 |
51 |
52 |
53 |
54 |
56 |
57 |
58 |
59 |
60 | Instantiate an interface extension for the given wl_surface to request
61 | asynchronous page flips for presentation.
62 |
63 | If the given wl_surface already has a wp_tearing_control_v1 object
64 | associated, the tearing_control_exists protocol error is raised.
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | An additional interface to a wl_surface object, which allows the client
74 | to hint to the compositor if the content on the surface is suitable for
75 | presentation with tearing.
76 | The default presentation hint is vsync. See presentation_hint for more
77 | details.
78 |
79 |
80 |
81 |
82 | This enum provides information for if submitted frames from the client
83 | may be presented with tearing.
84 |
85 |
86 |
87 | The content of this surface is meant to be synchronized to the
88 | vertical blanking period. This should not result in visible tearing
89 | and may result in a delay before a surface commit is presented.
90 |
91 |
92 |
93 |
94 | The content of this surface is meant to be presented with minimal
95 | latency and tearing is acceptable.
96 |
97 |
98 |
99 |
100 |
101 |
102 | Set the presentation hint for the associated wl_surface. This state is
103 | double-buffered and is applied on the next wl_surface.commit.
104 |
105 | The compositor is free to dynamically respect or ignore this hint based
106 | on various conditions like hardware capabilities, surface state and
107 | user preferences.
108 |
109 |
110 |
111 |
112 |
113 |
114 | Destroy this surface tearing object and revert the presentation hint to
115 | vsync. The change will be applied on the next wl_surface.commit.
116 |
117 |
118 |
119 |
120 |
121 |
--------------------------------------------------------------------------------
/tearing_control.c:
--------------------------------------------------------------------------------
1 | /* Wayland compositor running on top of an X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include
21 |
22 | #include "compositor.h"
23 | #include "tearing-control-v1.h"
24 |
25 | typedef struct _TearingControl TearingControl;
26 |
27 | struct _TearingControl
28 | {
29 | /* The associated surface. NULL when detached. */
30 | Surface *surface;
31 |
32 | /* The associated resource. */
33 | struct wl_resource *resource;
34 | };
35 |
36 | /* The tearing control manager. */
37 | static struct wl_global *tearing_control_manager_global;
38 |
39 |
40 |
41 | static void
42 | DestroyTearingControl (struct wl_client *client, struct wl_resource *resource)
43 | {
44 | TearingControl *control;
45 |
46 | control = wl_resource_get_user_data (resource);
47 |
48 | if (control->surface)
49 | {
50 | /* Reset the presentation hint. */
51 | control->surface->pending_state.presentation_hint
52 | = PresentationHintVsync;
53 | control->surface->pending_state.pending
54 | |= PendingPresentationHint;
55 | }
56 |
57 | wl_resource_destroy (resource);
58 | }
59 |
60 | static void
61 | SetPresentationHint (struct wl_client *client, struct wl_resource *resource,
62 | uint32_t hint)
63 | {
64 | TearingControl *control;
65 |
66 | control = wl_resource_get_user_data (resource);
67 |
68 | if (control->surface)
69 | {
70 | switch (hint)
71 | {
72 | case WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC:
73 | control->surface->pending_state.presentation_hint
74 | = PresentationHintAsync;
75 | break;
76 |
77 | default:
78 | control->surface->pending_state.presentation_hint
79 | = PresentationHintVsync;
80 | break;
81 | }
82 |
83 | control->surface->pending_state.pending |= PendingPresentationHint;
84 | }
85 | }
86 |
87 | static const struct wp_tearing_control_v1_interface control_impl =
88 | {
89 | .destroy = DestroyTearingControl,
90 | .set_presentation_hint = SetPresentationHint,
91 | };
92 |
93 | static void
94 | HandleResourceDestroy (struct wl_resource *resource)
95 | {
96 | TearingControl *control, **reference;
97 |
98 | control = wl_resource_get_user_data (resource);
99 |
100 | /* If the surface is still attached to the tearing control, remove
101 | it from the surface. */
102 |
103 | if (control->surface)
104 | {
105 | reference
106 | = XLSurfaceFindClientData (control->surface,
107 | TearingControlData);
108 | XLAssert (reference != NULL);
109 |
110 | *reference = NULL;
111 | }
112 |
113 | XLFree (control);
114 | }
115 |
116 |
117 |
118 | static void
119 | FreeTearingControlData (void *data)
120 | {
121 | TearingControl **control;
122 |
123 | control = data;
124 |
125 | if (!*control)
126 | return;
127 |
128 | /* Detach the surface from the tearing control. */
129 | (*control)->surface = NULL;
130 | }
131 |
132 | static void
133 | Destroy (struct wl_client *client, struct wl_resource *resource)
134 | {
135 | wl_resource_destroy (resource);
136 | }
137 |
138 | static void
139 | GetTearingControl (struct wl_client *client, struct wl_resource *resource,
140 | uint32_t id, struct wl_resource *surface_resource)
141 | {
142 | Surface *surface;
143 | TearingControl **control;
144 |
145 | surface = wl_resource_get_user_data (surface_resource);
146 | control = XLSurfaceGetClientData (surface, TearingControlData,
147 | sizeof *control,
148 | FreeTearingControlData);
149 |
150 | #define ControlExists \
151 | WP_TEARING_CONTROL_MANAGER_V1_ERROR_TEARING_CONTROL_EXISTS
152 |
153 | if (*control)
154 | {
155 | /* A tearing control resource already exists for this
156 | surface. */
157 | wl_resource_post_error (resource, ControlExists,
158 | "a wp_tearing_control_v1 resource already exists"
159 | " for the specified surface");
160 | return;
161 | }
162 |
163 | #undef ControlExists
164 |
165 | (*control) = XLCalloc (1, sizeof **control);
166 | (*control)->resource
167 | = wl_resource_create (client,
168 | &wp_tearing_control_v1_interface,
169 | wl_resource_get_version (resource), id);
170 |
171 | if (!(*control)->resource)
172 | {
173 | XLFree (*control);
174 | (*control) = NULL;
175 |
176 | wl_resource_post_no_memory (resource);
177 | return;
178 | }
179 |
180 | (*control)->surface = surface;
181 | wl_resource_set_implementation ((*control)->resource, &control_impl,
182 | (*control), HandleResourceDestroy);
183 | }
184 |
185 | static const struct wp_tearing_control_manager_v1_interface manager_impl =
186 | {
187 | .destroy = Destroy,
188 | .get_tearing_control = GetTearingControl,
189 | };
190 |
191 |
192 |
193 | static void
194 | HandleBind (struct wl_client *client, void *data,
195 | uint32_t version, uint32_t id)
196 | {
197 | struct wl_resource *resource;
198 |
199 | resource = wl_resource_create (client,
200 | &wp_tearing_control_manager_v1_interface,
201 | version, id);
202 |
203 | if (!resource)
204 | {
205 | wl_client_post_no_memory (client);
206 | return;
207 | }
208 |
209 | wl_resource_set_implementation (resource, &manager_impl,
210 | NULL, NULL);
211 | }
212 |
213 | void
214 | XLInitTearingControl (void)
215 | {
216 | tearing_control_manager_global
217 | = wl_global_create (compositor.wl_display,
218 | &wp_tearing_control_manager_v1_interface,
219 | 1, NULL, HandleBind);
220 | }
221 |
--------------------------------------------------------------------------------
/single_pixel_buffer.c:
--------------------------------------------------------------------------------
1 | /* Wayland compositor running on top of an X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include "compositor.h"
21 | #include "single-pixel-buffer-v1.h"
22 | #include "string.h"
23 |
24 | typedef struct _Buffer Buffer;
25 |
26 | struct _Buffer
27 | {
28 | /* The ExtBuffer associated with this buffer. */
29 | ExtBuffer buffer;
30 |
31 | /* The rendering buffer associated with this buffer. */
32 | RenderBuffer render_buffer;
33 |
34 | /* The wl_resource corresponding to this buffer. */
35 | struct wl_resource *resource;
36 |
37 | /* The number of references to this buffer. */
38 | int refcount;
39 | };
40 |
41 | /* The global wp_single_pixel_buffer_manager_v1 resource. */
42 | static struct wl_global *single_pixel_buffer_global;
43 |
44 | static void
45 | DestroyBuffer (struct wl_client *client, struct wl_resource *resource)
46 | {
47 | wl_resource_destroy (resource);
48 | }
49 |
50 | static const struct wl_buffer_interface single_pixel_buffer_impl =
51 | {
52 | .destroy = DestroyBuffer,
53 | };
54 |
55 | static void
56 | RetainBuffer (Buffer *buffer)
57 | {
58 | buffer->refcount++;
59 | }
60 |
61 | static void
62 | DereferenceBuffer (Buffer *buffer)
63 | {
64 | if (--buffer->refcount)
65 | return;
66 |
67 | RenderFreeSinglePixelBuffer (buffer->render_buffer);
68 | ExtBufferDestroy (&buffer->buffer);
69 | XLFree (buffer);
70 | }
71 |
72 | static void
73 | ReleaseBufferFunc (ExtBuffer *buffer)
74 | {
75 | if (((Buffer *) buffer)->resource)
76 | wl_buffer_send_release (((Buffer *) buffer)->resource);
77 | }
78 |
79 | static void
80 | RetainBufferFunc (ExtBuffer *buffer)
81 | {
82 | RetainBuffer ((Buffer *) buffer);
83 | }
84 |
85 | static void
86 | DereferenceBufferFunc (ExtBuffer *buffer)
87 | {
88 | DereferenceBuffer ((Buffer *) buffer);
89 | }
90 |
91 | static RenderBuffer
92 | GetBufferFunc (ExtBuffer *buffer)
93 | {
94 | return ((Buffer *) buffer)->render_buffer;
95 | }
96 |
97 | static unsigned int
98 | WidthFunc (ExtBuffer *buffer)
99 | {
100 | /* Single pixel buffers are always 1x1. */
101 | return 1;
102 | }
103 |
104 | static unsigned int
105 | HeightFunc (ExtBuffer *buffer)
106 | {
107 | /* Single pixel buffers are always 1x1. */
108 | return 1;
109 | }
110 |
111 | static void
112 | PrintBuffer (Buffer *buffer)
113 | {
114 | /* Not implemented. */
115 | }
116 |
117 | static void
118 | PrintBufferFunc (ExtBuffer *buffer)
119 | {
120 | PrintBuffer ((Buffer *) buffer);
121 | }
122 |
123 | static void
124 | HandleResourceDestroy (struct wl_resource *resource)
125 | {
126 | Buffer *buffer;
127 |
128 | buffer = wl_resource_get_user_data (resource);
129 | buffer->resource = NULL;
130 |
131 | DereferenceBuffer (buffer);
132 | }
133 |
134 |
135 |
136 | static void
137 | Destroy (struct wl_client *client, struct wl_resource *resource)
138 | {
139 | wl_resource_destroy (resource);
140 | }
141 |
142 | static void
143 | CreateU32RgbaBuffer (struct wl_client *client, struct wl_resource *resource,
144 | uint32_t id, uint32_t r, uint32_t g, uint32_t b,
145 | uint32_t a)
146 | {
147 | Buffer *buffer;
148 | Bool error;
149 |
150 | buffer = XLSafeMalloc (sizeof *buffer);
151 |
152 | if (!buffer)
153 | {
154 | wl_resource_post_no_memory (resource);
155 | return;
156 | }
157 |
158 | memset (buffer, 0, sizeof *buffer);
159 | buffer->resource = wl_resource_create (client, &wl_buffer_interface,
160 | wl_resource_get_version (resource),
161 | id);
162 |
163 | if (!buffer->resource)
164 | {
165 | out_of_memory:
166 | wl_resource_post_no_memory (resource);
167 | XLFree (buffer);
168 | return;
169 | }
170 |
171 | /* Now, create the render target. */
172 | error = False;
173 | buffer->render_buffer = RenderBufferFromSinglePixel (r, g, b, a,
174 | &error);
175 |
176 | if (error)
177 | /* We probably ran out of memory. */
178 | goto out_of_memory;
179 |
180 | buffer->refcount = 1;
181 |
182 | /* Initialize function pointers. */
183 | buffer->buffer.funcs.retain = RetainBufferFunc;
184 | buffer->buffer.funcs.dereference = DereferenceBufferFunc;
185 | buffer->buffer.funcs.get_buffer = GetBufferFunc;
186 | buffer->buffer.funcs.width = WidthFunc;
187 | buffer->buffer.funcs.height = HeightFunc;
188 | buffer->buffer.funcs.release = ReleaseBufferFunc;
189 | buffer->buffer.funcs.print_buffer = PrintBufferFunc;
190 |
191 | wl_resource_set_implementation (buffer->resource, &single_pixel_buffer_impl,
192 | buffer, HandleResourceDestroy);
193 | }
194 |
195 | static const struct wp_single_pixel_buffer_manager_v1_interface manager_impl =
196 | {
197 | .destroy = Destroy,
198 | .create_u32_rgba_buffer = CreateU32RgbaBuffer,
199 | };
200 |
201 | static void
202 | HandleBind (struct wl_client *client, void *data, uint32_t version,
203 | uint32_t id)
204 | {
205 | struct wl_resource *resource;
206 |
207 | resource = wl_resource_create (client,
208 | &wp_single_pixel_buffer_manager_v1_interface,
209 | version, id);
210 |
211 | if (!resource)
212 | {
213 | wl_client_post_no_memory (client);
214 | return;
215 | }
216 |
217 | wl_resource_set_implementation (resource, &manager_impl,
218 | NULL, NULL);
219 | }
220 |
221 | void
222 | XLInitSinglePixelBuffer (void)
223 | {
224 | single_pixel_buffer_global
225 | = wl_global_create (compositor.wl_display,
226 | &wp_single_pixel_buffer_manager_v1_interface,
227 | 1, NULL, HandleBind);
228 | }
229 |
--------------------------------------------------------------------------------
/pointer_gestures.c:
--------------------------------------------------------------------------------
1 | /* Wayland compositor running on top of an X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include "compositor.h"
21 | #include "pointer-gestures-unstable-v1.h"
22 |
23 | /* The struct zwp_pointer_gestures_v1 global. */
24 | static struct wl_global *pointer_gestures_global;
25 |
26 | static void
27 | DestroySwipeGesture (struct wl_client *client, struct wl_resource *resource)
28 | {
29 | wl_resource_destroy (resource);
30 | }
31 |
32 | static struct zwp_pointer_gesture_swipe_v1_interface gesture_swipe_impl =
33 | {
34 | .destroy = DestroySwipeGesture,
35 | };
36 |
37 | static void
38 | HandleSwipeGestureResourceDestroy (struct wl_resource *resource)
39 | {
40 | SwipeGesture *gesture;
41 |
42 | gesture = wl_resource_get_user_data (resource);
43 | XLSeatDestroySwipeGesture (gesture);
44 | }
45 |
46 |
47 |
48 | static void
49 | DestroyPinchGesture (struct wl_client *client, struct wl_resource *resource)
50 | {
51 | wl_resource_destroy (resource);
52 | }
53 |
54 | static struct zwp_pointer_gesture_pinch_v1_interface gesture_pinch_impl =
55 | {
56 | .destroy = DestroyPinchGesture,
57 | };
58 |
59 | static void
60 | HandlePinchGestureResourceDestroy (struct wl_resource *resource)
61 | {
62 | PinchGesture *gesture;
63 |
64 | gesture = wl_resource_get_user_data (resource);
65 | XLSeatDestroyPinchGesture (gesture);
66 | }
67 |
68 |
69 |
70 | static void
71 | DestroyHoldGesture (struct wl_client *client, struct wl_resource *resource)
72 | {
73 | wl_resource_destroy (resource);
74 | }
75 |
76 | static struct zwp_pointer_gesture_hold_v1_interface gesture_hold_impl =
77 | {
78 | .destroy = DestroyHoldGesture,
79 | };
80 |
81 |
82 |
83 | static void
84 | GetSwipeGesture (struct wl_client *client, struct wl_resource *resource,
85 | uint32_t id, struct wl_resource *pointer_resource)
86 | {
87 | struct wl_resource *gesture_resource;
88 | Pointer *pointer;
89 | Seat *seat;
90 | SwipeGesture *gesture_swipe;
91 |
92 | pointer = wl_resource_get_user_data (pointer_resource);
93 | seat = XLPointerGetSeat (pointer);
94 | gesture_resource
95 | = wl_resource_create (client,
96 | &zwp_pointer_gesture_swipe_v1_interface,
97 | wl_resource_get_version (resource), id);
98 |
99 | if (!gesture_resource)
100 | {
101 | wl_resource_post_no_memory (resource);
102 | return;
103 | }
104 |
105 | gesture_swipe = XLSeatGetSwipeGesture (seat, gesture_resource);
106 | wl_resource_set_implementation (gesture_resource, &gesture_swipe_impl,
107 | gesture_swipe,
108 | HandleSwipeGestureResourceDestroy);
109 | }
110 |
111 | static void
112 | GetPinchGesture (struct wl_client *client, struct wl_resource *resource,
113 | uint32_t id, struct wl_resource *pointer_resource)
114 | {
115 | struct wl_resource *gesture_resource;
116 | Pointer *pointer;
117 | Seat *seat;
118 | PinchGesture *gesture_pinch;
119 |
120 | pointer = wl_resource_get_user_data (pointer_resource);
121 | seat = XLPointerGetSeat (pointer);
122 | gesture_resource
123 | = wl_resource_create (client,
124 | &zwp_pointer_gesture_pinch_v1_interface,
125 | wl_resource_get_version (resource), id);
126 |
127 | if (!gesture_resource)
128 | {
129 | wl_resource_post_no_memory (resource);
130 | return;
131 | }
132 |
133 | gesture_pinch = XLSeatGetPinchGesture (seat, gesture_resource);
134 | wl_resource_set_implementation (gesture_resource, &gesture_pinch_impl,
135 | gesture_pinch,
136 | HandlePinchGestureResourceDestroy);
137 | }
138 |
139 | static void
140 | Release (struct wl_client *client, struct wl_resource *resource)
141 | {
142 | wl_resource_destroy (resource);
143 | }
144 |
145 | static void
146 | GetHoldGesture (struct wl_client *client, struct wl_resource *resource,
147 | uint32_t id, struct wl_resource *pointer_resource)
148 | {
149 | struct wl_resource *gesture_resource;
150 |
151 | /* Hold gestures are not supported by the X Input extension, so a
152 | dummy resource is created that just does nothing. */
153 | gesture_resource
154 | = wl_resource_create (client, &zwp_pointer_gesture_hold_v1_interface,
155 | wl_resource_get_version (resource), id);
156 |
157 | if (!gesture_resource)
158 | {
159 | wl_resource_post_no_memory (resource);
160 | return;
161 | }
162 |
163 | wl_resource_set_implementation (gesture_resource, &gesture_hold_impl,
164 | NULL, NULL);
165 | }
166 |
167 | static struct zwp_pointer_gestures_v1_interface pointer_gestures_impl =
168 | {
169 | .get_swipe_gesture = GetSwipeGesture,
170 | .get_pinch_gesture = GetPinchGesture,
171 | .release = Release,
172 | .get_hold_gesture = GetHoldGesture,
173 | };
174 |
175 | static void
176 | HandleBind (struct wl_client *client, void *data, uint32_t version,
177 | uint32_t id)
178 | {
179 | struct wl_resource *resource;
180 |
181 | resource = wl_resource_create (client, &zwp_pointer_gestures_v1_interface,
182 | version, id);
183 |
184 | if (!resource)
185 | {
186 | wl_client_post_no_memory (client);
187 | return;
188 | }
189 |
190 | wl_resource_set_implementation (resource, &pointer_gestures_impl,
191 | NULL, NULL);
192 | }
193 |
194 | void
195 | XLInitPointerGestures (void)
196 | {
197 | if (xi2_major > 2 || xi2_minor >= 4)
198 | /* Create the pointer gestures global. */
199 | pointer_gestures_global
200 | = wl_global_create (compositor.wl_display,
201 | &zwp_pointer_gestures_v1_interface,
202 | 3, NULL, HandleBind);
203 |
204 | /* Pointer gestures are not supported without XI 2.4 or later. */
205 | }
206 |
--------------------------------------------------------------------------------
/tests/simple_test.c:
--------------------------------------------------------------------------------
1 | /* Tests for the Wayland compositor running on the X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include "test_harness.h"
21 |
22 | enum test_kind
23 | {
24 | MAP_WINDOW_KIND,
25 | BASIC_TEST_CARD_IMAGE_KIND,
26 | };
27 |
28 | static const char *test_names[] =
29 | {
30 | "map_window",
31 | "basic_test_card_image",
32 | };
33 |
34 | #define LAST_TEST BASIC_TEST_CARD_IMAGE_KIND
35 |
36 | /* The display. */
37 | static struct test_display *display;
38 |
39 | /* Test interfaces. */
40 | static struct test_interface test_interfaces[] =
41 | {
42 | /* No interfaces yet. */
43 | };
44 |
45 | /* The test surface window. */
46 | static Window test_surface_window;
47 |
48 | /* The test surface and Wayland surface. */
49 | static struct test_surface *test_surface;
50 | static struct wl_surface *wayland_surface;
51 |
52 |
53 |
54 | /* Forward declarations. */
55 | static void submit_frame_callback (struct wl_surface *, enum test_kind);
56 | static void submit_surface_damage (struct wl_surface *, int, int, int, int);
57 |
58 |
59 |
60 | static void
61 | verify_single_step (enum test_kind kind)
62 | {
63 | switch (kind)
64 | {
65 | case BASIC_TEST_CARD_IMAGE_KIND:
66 | verify_image_data (display, test_surface_window,
67 | "simple_test.dump");
68 | break;
69 |
70 | default:
71 | break;
72 | }
73 |
74 | if (kind == LAST_TEST)
75 | test_complete ();
76 | }
77 |
78 | static void
79 | test_single_step (enum test_kind kind)
80 | {
81 | struct wl_buffer *buffer;
82 |
83 | test_log ("running test step: %s", test_names[kind]);
84 |
85 | switch (kind)
86 | {
87 | case MAP_WINDOW_KIND:
88 | buffer = load_png_image (display, "blue.png");
89 |
90 | if (!buffer)
91 | report_test_failure ("failed to load blue.png");
92 |
93 | wl_surface_attach (wayland_surface, buffer, 0, 0);
94 | submit_surface_damage (wayland_surface, 0, 0,
95 | INT_MAX, INT_MAX);
96 | wl_surface_commit (wayland_surface);
97 | wl_buffer_destroy (buffer);
98 | break;
99 |
100 | case BASIC_TEST_CARD_IMAGE_KIND:
101 | buffer = load_png_image (display, "basic_test_card.png");
102 |
103 | if (!buffer)
104 | report_test_failure ("failed to load basic_test_card.png");
105 |
106 | wl_surface_attach (wayland_surface, buffer, 0, 0);
107 | submit_frame_callback (wayland_surface, kind);
108 | submit_surface_damage (wayland_surface, 0, 0,
109 | INT_MAX, INT_MAX);
110 | wl_surface_commit (wayland_surface);
111 | wl_buffer_destroy (buffer);
112 | break;
113 | }
114 | }
115 |
116 | static void
117 | test_next_step (enum test_kind kind)
118 | {
119 | switch (kind)
120 | {
121 | default:
122 | break;
123 | }
124 | }
125 |
126 |
127 |
128 | static void
129 | handle_test_surface_mapped (void *data, struct test_surface *surface,
130 | uint32_t xid, const char *display_string)
131 | {
132 | /* Sleep for 1 second to ensure that the window is exposed and
133 | redirected. */
134 | sleep (1);
135 |
136 | /* Start the test. */
137 | test_surface_window = xid;
138 |
139 | /* Run the test again. */
140 | test_single_step (BASIC_TEST_CARD_IMAGE_KIND);
141 | }
142 |
143 | static void
144 | handle_test_surface_committed (void *data, struct test_surface *surface,
145 | uint32_t presentation_hint)
146 | {
147 |
148 | }
149 |
150 | static const struct test_surface_listener test_surface_listener =
151 | {
152 | handle_test_surface_mapped,
153 | NULL,
154 | handle_test_surface_committed,
155 | };
156 |
157 |
158 |
159 | static void
160 | handle_wl_callback_done (void *data, struct wl_callback *callback,
161 | uint32_t callback_data)
162 | {
163 | enum test_kind kind;
164 |
165 | /* kind is not a pointer. It is an enum test_kind stuffed into a
166 | pointer. */
167 | kind = (intptr_t) data;
168 |
169 | wl_callback_destroy (callback);
170 | verify_single_step (kind);
171 |
172 | /* Now run the next test in this sequence. */
173 | test_next_step (kind);
174 | }
175 |
176 | static const struct wl_callback_listener wl_callback_listener =
177 | {
178 | handle_wl_callback_done,
179 | };
180 |
181 |
182 |
183 | static void
184 | submit_frame_callback (struct wl_surface *surface, enum test_kind kind)
185 | {
186 | struct wl_callback *callback;
187 |
188 | callback = wl_surface_frame (surface);
189 | wl_callback_add_listener (callback, &wl_callback_listener,
190 | (void *) (intptr_t) kind);
191 | }
192 |
193 | static void
194 | submit_surface_damage (struct wl_surface *surface, int x, int y, int width,
195 | int height)
196 | {
197 | test_log ("damaging surface by %d, %d, %d, %d", x, y, width,
198 | height);
199 |
200 | wl_surface_damage (surface, x, y, width, height);
201 | }
202 |
203 | static void
204 | run_test (void)
205 | {
206 | if (!make_test_surface (display, &wayland_surface,
207 | &test_surface))
208 | report_test_failure ("failed to create test surface");
209 |
210 | test_surface_add_listener (test_surface, &test_surface_listener,
211 | NULL);
212 | test_single_step (MAP_WINDOW_KIND);
213 |
214 | while (true)
215 | {
216 | if (wl_display_dispatch (display->display) == -1)
217 | die ("wl_display_dispatch");
218 | }
219 | }
220 |
221 | int
222 | main (void)
223 | {
224 | test_init ();
225 | display = open_test_display (test_interfaces,
226 | ARRAYELTS (test_interfaces));
227 |
228 | if (!display)
229 | report_test_failure ("failed to open display");
230 |
231 | run_test ();
232 | }
233 |
--------------------------------------------------------------------------------
/tests/buffer_test.c:
--------------------------------------------------------------------------------
1 | /* Tests for the Wayland compositor running on the X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include "test_harness.h"
21 |
22 | /* Tests for buffer release. */
23 |
24 | enum test_kind
25 | {
26 | BUFFER_RELEASE_KIND,
27 | BUFFER_DESTROY_KIND,
28 | };
29 |
30 | static const char *test_names[] =
31 | {
32 | "buffer_release",
33 | "buffer_destroy",
34 | };
35 |
36 | #define LAST_TEST BUFFER_DESTROY_KIND
37 |
38 | /* The display. */
39 | static struct test_display *display;
40 |
41 | /* Test interfaces. */
42 | static struct test_interface test_interfaces[] =
43 | {
44 | /* No interfaces yet... */
45 | };
46 |
47 | /* The test surface and Wayland surface. */
48 | static struct test_surface *test_surface;
49 | static struct wl_surface *wayland_surface;
50 |
51 |
52 |
53 | /* Forward declarations. */
54 | static void wait_frame_callback (struct wl_surface *);
55 |
56 |
57 |
58 | static struct test_buffer *
59 | make_test_buffer (void)
60 | {
61 | struct wl_buffer *buffer;
62 | struct test_buffer *test_buffer;
63 | char *empty_data;
64 | size_t stride;
65 |
66 | stride = get_image_stride (display, 24, 1);
67 |
68 | if (!stride)
69 | report_test_failure ("unknown stride");
70 |
71 | empty_data = calloc (1, stride);
72 |
73 | if (!empty_data)
74 | report_test_failure ("failed to allocate buffer data");
75 |
76 | buffer = upload_image_data (display, empty_data, 1, 1, 24);
77 | free (empty_data);
78 |
79 | if (!buffer)
80 | report_test_failure ("failed to create single pixel buffer");
81 |
82 | test_buffer = get_test_buffer (display, buffer);
83 |
84 | if (!test_buffer)
85 | report_test_failure ("failed to create test buffer");
86 |
87 | return test_buffer;
88 | }
89 |
90 | static void
91 | test_single_step (enum test_kind kind)
92 | {
93 | struct test_buffer *buffers[1000];
94 | int i;
95 |
96 | again:
97 |
98 | test_log ("running test step: %s", test_names[kind]);
99 |
100 | switch (kind)
101 | {
102 | case BUFFER_RELEASE_KIND:
103 | /* Abuse the buffer release machinery. Repeatedly commit 1000
104 | buffers. Then, wait for a frame callback on the 1000th
105 | commit.
106 |
107 | Verify that the first 999 have been released. */
108 |
109 | for (i = 0; i < ARRAYELTS (buffers) - 1; ++i)
110 | {
111 | buffers[i] = make_test_buffer ();
112 | wl_surface_attach (wayland_surface, buffers[i]->buffer,
113 | 0, 0);
114 | test_buffer_committed (buffers[i]);
115 | wl_surface_commit (wayland_surface);
116 | }
117 |
118 | buffers[i] = make_test_buffer ();
119 | wl_surface_attach (wayland_surface, buffers[i]->buffer,
120 | 0, 0);
121 | test_buffer_committed (buffers[i]);
122 | wait_frame_callback (wayland_surface);
123 |
124 | for (i = 0; i < ARRAYELTS (buffers) - 1; ++i)
125 | verify_buffer_released (buffers[i]);
126 |
127 | kind = BUFFER_DESTROY_KIND;
128 | goto again;
129 |
130 | case BUFFER_DESTROY_KIND:
131 | /* Now do the same thing, but destroy every other wl_buffer. */
132 |
133 | for (i = 0; i < ARRAYELTS (buffers) - 1; ++i)
134 | {
135 | wl_surface_attach (wayland_surface, buffers[i]->buffer,
136 | 0, 0);
137 | test_buffer_committed (buffers[i]);
138 | wl_surface_commit (wayland_surface);
139 |
140 | if (i % 2)
141 | wl_buffer_destroy (buffers[i]->buffer);
142 |
143 | /* buffers[i] is intentionally "leaked". */
144 | buffers[i] = NULL;
145 | }
146 |
147 | wl_surface_attach (wayland_surface, buffers[i]->buffer,
148 | 0, 0);
149 | test_buffer_committed (buffers[i]);
150 | wait_frame_callback (wayland_surface);
151 |
152 | for (i = 0; i < ARRAYELTS (buffers) - 1; ++i)
153 | {
154 | if (buffers[i])
155 | verify_buffer_released (buffers[i]);
156 | }
157 | }
158 |
159 | if (kind == LAST_TEST)
160 | test_complete ();
161 | }
162 |
163 |
164 |
165 | static void
166 | handle_wl_callback_done (void *data, struct wl_callback *callback,
167 | uint32_t callback_data)
168 | {
169 | bool *flag;
170 |
171 | wl_callback_destroy (callback);
172 |
173 | /* Now tell wait_frame_callback to break out of the loop. */
174 | flag = data;
175 | *flag = true;
176 | }
177 |
178 | static const struct wl_callback_listener wl_callback_listener =
179 | {
180 | handle_wl_callback_done,
181 | };
182 |
183 |
184 |
185 | static void
186 | wait_frame_callback (struct wl_surface *surface)
187 | {
188 | struct wl_callback *callback;
189 | bool flag;
190 |
191 | /* Commit surface and wait for a frame callback. */
192 |
193 | callback = wl_surface_frame (surface);
194 | flag = false;
195 |
196 | wl_callback_add_listener (callback, &wl_callback_listener,
197 | &flag);
198 | wl_surface_commit (surface);
199 |
200 | while (!flag)
201 | {
202 | if (wl_display_dispatch (display->display) == -1)
203 | die ("wl_display_dispatch");
204 | }
205 | }
206 |
207 | static void
208 | run_test (void)
209 | {
210 | if (!make_test_surface (display, &wayland_surface,
211 | &test_surface))
212 | report_test_failure ("failed to create test surface");
213 |
214 | test_single_step (BUFFER_RELEASE_KIND);
215 |
216 | while (true)
217 | {
218 | if (wl_display_dispatch (display->display) == -1)
219 | die ("wl_display_dispatch");
220 | }
221 | }
222 |
223 | int
224 | main (void)
225 | {
226 | test_init ();
227 | display = open_test_display (test_interfaces,
228 | ARRAYELTS (test_interfaces));
229 |
230 | if (!display)
231 | report_test_failure ("failed to open display");
232 |
233 | run_test ();
234 | }
235 |
--------------------------------------------------------------------------------
/timer.c:
--------------------------------------------------------------------------------
1 | /* Wayland compositor running on top of an X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | /* Some of this file was taken from timespec-add.c and timespec-sub.c,
21 | part of gnulib, written by Paul Eggert . */
22 |
23 | #include "compositor.h"
24 |
25 | /* Linked list of all timers. */
26 | static Timer all_timers;
27 |
28 | struct _Timer
29 | {
30 | /* The next and last timers in this list. */
31 | Timer *next, *last;
32 |
33 | /* The repeat of this timer. */
34 | struct timespec repeat;
35 |
36 | /* The next time this timer should be run. */
37 | struct timespec next_time;
38 |
39 | /* The function that should be called when the timer is run. */
40 | void (*function) (Timer *, void *, struct timespec);
41 |
42 | /* User data associated with the timer. */
43 | void *timer_data;
44 | };
45 |
46 | struct timespec
47 | CurrentTimespec (void)
48 | {
49 | struct timespec timespec;
50 |
51 | clock_gettime (CLOCK_MONOTONIC, ×pec);
52 | return timespec;
53 | }
54 |
55 | struct timespec
56 | MakeTimespec (time_t s, long int ns)
57 | {
58 | struct timespec r;
59 |
60 | r.tv_sec = s;
61 | r.tv_nsec = ns;
62 |
63 | return r;
64 | }
65 |
66 | int
67 | TimespecCmp (struct timespec a, struct timespec b)
68 | {
69 | return (2 * SafeCmp (a.tv_sec, b.tv_sec)
70 | + SafeCmp (a.tv_nsec, b.tv_nsec));
71 | }
72 |
73 | struct timespec
74 | TimespecAdd (struct timespec a, struct timespec b)
75 | {
76 | time_t rs, bs, bs1;
77 | int ns, nsd, rns;
78 |
79 | rs = a.tv_sec;
80 | bs = b.tv_sec;
81 | ns = a.tv_nsec + b.tv_nsec;
82 | nsd = ns - 1000000000;
83 | rns = ns;
84 |
85 | if (0 < nsd)
86 | {
87 | rns = nsd;
88 |
89 | if (!IntAddWrapv (bs, 1, &bs1))
90 | bs = bs1;
91 | else if (rs < 0)
92 | rs++;
93 | else
94 | goto high_overflow;
95 | }
96 |
97 | if (IntAddWrapv (rs, bs, &rs))
98 | {
99 | if (bs < 0)
100 | {
101 | rs = TypeMinimum (time_t);
102 | rns = 0;
103 | }
104 | else
105 | {
106 | high_overflow:
107 | rs = TypeMaximum (time_t);
108 | rns = 1000000000 - 1;
109 | }
110 | }
111 |
112 | return MakeTimespec (rs, rns);
113 | }
114 |
115 | struct timespec
116 | TimespecSub (struct timespec a, struct timespec b)
117 | {
118 | time_t rs, bs, bs1;
119 | int ns, rns;
120 |
121 | rs = a.tv_sec;
122 | bs = b.tv_sec;
123 | ns = a.tv_nsec - b.tv_nsec;
124 | rns = ns;
125 |
126 | if (ns < 0)
127 | {
128 | rns = ns + 1000000000;
129 | if (!IntAddWrapv (bs, 1, &bs1))
130 | bs = bs1;
131 | else if (- TypeIsSigned (time_t) < rs)
132 | rs--;
133 | else
134 | goto low_overflow;
135 | }
136 |
137 | if (IntSubtractWrapv (rs, bs, &rs))
138 | {
139 | if (0 < bs)
140 | {
141 | low_overflow:
142 | rs = TypeMinimum (time_t);
143 | rns = 0;
144 | }
145 | else
146 | {
147 | rs = TypeMaximum (time_t);
148 | rns = 1000000000 - 1;
149 | }
150 | }
151 |
152 | return MakeTimespec (rs, rns);
153 | }
154 |
155 | Timer *
156 | AddTimer (void (*function) (Timer *, void *, struct timespec),
157 | void *data, struct timespec delay)
158 | {
159 | Timer *timer;
160 |
161 | timer = XLMalloc (sizeof *timer);
162 | timer->function = function;
163 | timer->timer_data = data;
164 | timer->repeat = delay;
165 | timer->next_time = TimespecAdd (CurrentTimespec (),
166 | delay);
167 |
168 | /* Chain the timer onto our list of timers. */
169 | timer->next = all_timers.next;
170 | timer->last = &all_timers;
171 |
172 | all_timers.next->last = timer;
173 | all_timers.next = timer;
174 |
175 | return timer;
176 | }
177 |
178 | Timer *
179 | AddTimerWithBaseTime (void (*function) (Timer *, void *, struct timespec),
180 | void *data, struct timespec delay, struct timespec base)
181 | {
182 | Timer *timer;
183 |
184 | timer = XLMalloc (sizeof *timer);
185 | timer->function = function;
186 | timer->timer_data = data;
187 | timer->repeat = delay;
188 | timer->next_time = TimespecAdd (base, delay);
189 |
190 | /* Chain the timer onto our list of timers. */
191 | timer->next = all_timers.next;
192 | timer->last = &all_timers;
193 |
194 | all_timers.next->last = timer;
195 | all_timers.next = timer;
196 |
197 | return timer;
198 | }
199 |
200 | void
201 | RemoveTimer (Timer *timer)
202 | {
203 | /* Start by removing the timer from the list of timers. This is
204 | only safe inside a timer callback our outside TimerCheck. */
205 | timer->next->last = timer->last;
206 | timer->last->next = timer->next;
207 |
208 | /* Then, free the timer. */
209 | XLFree (timer);
210 | }
211 |
212 | void
213 | RetimeTimer (Timer *timer)
214 | {
215 | timer->next_time = TimespecAdd (CurrentTimespec (),
216 | timer->repeat);
217 | }
218 |
219 | struct timespec
220 | TimerCheck (void)
221 | {
222 | struct timespec now, wait, temp;
223 | Timer *timer, *next;
224 | Bool flag;
225 |
226 | now = CurrentTimespec ();
227 | wait = MakeTimespec (TypeMaximum (time_t),
228 | 1000000000 - 1);
229 | timer = all_timers.next;
230 |
231 | while (timer != &all_timers)
232 | {
233 | /* Move the list forward first, so the timer callback can
234 | safely remove itself from the list. */
235 | next = timer->next;
236 | flag = False;
237 |
238 | if (TimespecCmp (timer->next_time, now) <= 0)
239 | {
240 | timer->next_time = TimespecAdd (timer->next_time,
241 | timer->repeat);
242 | flag = True;
243 | }
244 |
245 | temp = TimespecSub (timer->next_time, now);
246 |
247 | if (TimespecCmp (temp, wait) < 0)
248 | /* Wait is the time to wait until the next timer might
249 | fire. */
250 | wait = temp;
251 |
252 | if (flag)
253 | /* Run this function here instead, since it might remove the
254 | timer from the list. */
255 | timer->function (timer, timer->timer_data, now);
256 |
257 | timer = next;
258 | }
259 |
260 | return wait;
261 | }
262 |
263 | void
264 | XLInitTimers (void)
265 | {
266 | all_timers.next = &all_timers;
267 | all_timers.last = &all_timers;
268 | }
269 |
--------------------------------------------------------------------------------
/tests/single_pixel_buffer_test.c:
--------------------------------------------------------------------------------
1 | /* Tests for the Wayland compositor running on the X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include "test_harness.h"
21 | #include "single-pixel-buffer-v1.h"
22 | #include "viewporter.h"
23 |
24 | /* Tests for single pixel buffers. */
25 |
26 | enum test_kind
27 | {
28 | MAP_WINDOW_KIND,
29 | SINGLE_PIXEL_BUFFER_KIND,
30 | SINGLE_PIXEL_BUFFER_VIEWPORT_KIND,
31 | };
32 |
33 | static const char *test_names[] =
34 | {
35 | "map_window",
36 | "single_pixel_buffer",
37 | "single_pixel_buffer_viewport",
38 | };
39 |
40 | #define LAST_TEST SINGLE_PIXEL_BUFFER_VIEWPORT_KIND
41 |
42 | /* The display. */
43 | static struct test_display *display;
44 |
45 | /* The buffer manager. */
46 | static struct wp_single_pixel_buffer_manager_v1 *manager;
47 |
48 | /* The viewporter. */
49 | static struct wp_viewporter *viewporter;
50 |
51 | /* Test interfaces. */
52 | static struct test_interface test_interfaces[] =
53 | {
54 | { "wp_single_pixel_buffer_manager_v1", &manager,
55 | &wp_single_pixel_buffer_manager_v1_interface, 1, },
56 | { "wp_viewporter", &viewporter, &wp_viewporter_interface,
57 | 1, },
58 | };
59 |
60 | /* The test surface window. */
61 | static Window test_surface_window;
62 |
63 | /* The test surface and Wayland surface. */
64 | static struct test_surface *test_surface;
65 | static struct wl_surface *wayland_surface;
66 |
67 | /* The single pixel buffer. */
68 | static struct wl_buffer *single_pixel_buffer;
69 |
70 | /* The viewport. */
71 | static struct wp_viewport *viewport;
72 |
73 |
74 |
75 | /* Forward declarations. */
76 | static void wait_frame_callback (struct wl_surface *);
77 |
78 |
79 |
80 | static void
81 | test_single_step (enum test_kind kind)
82 | {
83 | test_log ("running test step: %s", test_names[kind]);
84 |
85 | switch (kind)
86 | {
87 | case MAP_WINDOW_KIND:
88 | wl_surface_attach (wayland_surface, single_pixel_buffer, 0, 0);
89 | wl_surface_damage (wayland_surface, 0, 0, 1, 1);
90 | wl_surface_commit (wayland_surface);
91 | break;
92 |
93 | case SINGLE_PIXEL_BUFFER_KIND:
94 | wait_frame_callback (wayland_surface);
95 | verify_image_data (display, test_surface_window,
96 | "single_pixel_buffer.dump");
97 | test_single_step (SINGLE_PIXEL_BUFFER_VIEWPORT_KIND);
98 | break;
99 |
100 | case SINGLE_PIXEL_BUFFER_VIEWPORT_KIND:
101 | wp_viewport_set_source (viewport,
102 | wl_fixed_from_double (0.0),
103 | wl_fixed_from_double (0.0),
104 | wl_fixed_from_double (1.0),
105 | wl_fixed_from_double (1.0));
106 | wp_viewport_set_destination (viewport, 275, 275);
107 | wait_frame_callback (wayland_surface);
108 |
109 | verify_image_data (display, test_surface_window,
110 | "single_pixel_buffer_viewport.dump");
111 | break;
112 | }
113 |
114 | if (kind == LAST_TEST)
115 | test_complete ();
116 | }
117 |
118 |
119 |
120 | static void
121 | handle_test_surface_mapped (void *data, struct test_surface *surface,
122 | uint32_t xid, const char *display_string)
123 | {
124 | /* Sleep for 1 second to ensure that the window is exposed and
125 | redirected. */
126 | sleep (1);
127 |
128 | /* Start the test. */
129 | test_surface_window = xid;
130 |
131 | /* Run the test again. */
132 | test_single_step (SINGLE_PIXEL_BUFFER_KIND);
133 | }
134 |
135 | static void
136 | handle_test_surface_committed (void *data, struct test_surface *surface,
137 | uint32_t presentation_hint)
138 | {
139 |
140 | }
141 |
142 | static const struct test_surface_listener test_surface_listener =
143 | {
144 | handle_test_surface_mapped,
145 | NULL,
146 | handle_test_surface_committed,
147 | };
148 |
149 |
150 |
151 | static void
152 | handle_wl_callback_done (void *data, struct wl_callback *callback,
153 | uint32_t callback_data)
154 | {
155 | bool *flag;
156 |
157 | wl_callback_destroy (callback);
158 |
159 | /* Now tell wait_frame_callback to break out of the loop. */
160 | flag = data;
161 | *flag = true;
162 | }
163 |
164 | static const struct wl_callback_listener wl_callback_listener =
165 | {
166 | handle_wl_callback_done,
167 | };
168 |
169 |
170 |
171 | static void
172 | wait_frame_callback (struct wl_surface *surface)
173 | {
174 | struct wl_callback *callback;
175 | bool flag;
176 |
177 | /* Commit surface and wait for a frame callback. */
178 |
179 | callback = wl_surface_frame (surface);
180 | flag = false;
181 |
182 | wl_callback_add_listener (callback, &wl_callback_listener,
183 | &flag);
184 | wl_surface_commit (surface);
185 |
186 | while (!flag)
187 | {
188 | if (wl_display_dispatch (display->display) == -1)
189 | die ("wl_display_dispatch");
190 | }
191 | }
192 |
193 | static void
194 | run_test (void)
195 | {
196 | if (!make_test_surface (display, &wayland_surface,
197 | &test_surface))
198 | report_test_failure ("failed to create test surface");
199 |
200 | test_surface_add_listener (test_surface, &test_surface_listener,
201 | NULL);
202 |
203 | /* Create the single pixel buffer. */
204 | single_pixel_buffer
205 | = wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (manager,
206 | 0xffffffff,
207 | 0xffffffff,
208 | 0x00000000,
209 | 0xffffffff);
210 | if (!single_pixel_buffer)
211 | report_test_failure ("failed to create single pixel buffer");
212 |
213 | /* And the viewport. */
214 | viewport = wp_viewporter_get_viewport (viewporter, wayland_surface);
215 |
216 | if (!viewport)
217 | report_test_failure ("failed to get viewport");
218 |
219 | test_single_step (MAP_WINDOW_KIND);
220 |
221 | while (true)
222 | {
223 | if (wl_display_dispatch (display->display) == -1)
224 | die ("wl_display_dispatch");
225 | }
226 | }
227 |
228 | int
229 | main (void)
230 | {
231 | test_init ();
232 | display = open_test_display (test_interfaces,
233 | ARRAYELTS (test_interfaces));
234 |
235 | if (!display)
236 | report_test_failure ("failed to open display");
237 |
238 | run_test ();
239 | }
240 |
--------------------------------------------------------------------------------
/tests/tearing_control_test.c:
--------------------------------------------------------------------------------
1 | /* Tests for the Wayland compositor running on the X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include "test_harness.h"
21 | #include "tearing-control-v1.h"
22 |
23 | /* Tests for buffer release. */
24 |
25 | enum test_kind
26 | {
27 | TEARING_CONTROL_KIND,
28 | TEARING_DESTROY_KIND,
29 | };
30 |
31 | static const char *test_names[] =
32 | {
33 | "tearing_control",
34 | "tearing_destroy",
35 | };
36 |
37 | #define LAST_TEST TEARING_DESTROY_KIND
38 |
39 | /* The display. */
40 | static struct test_display *display;
41 |
42 | /* The tearing control manager. */
43 | static struct wp_tearing_control_manager_v1 *manager;
44 |
45 | /* Test interfaces. */
46 | static struct test_interface test_interfaces[] =
47 | {
48 | { "wp_tearing_control_manager_v1", &manager,
49 | &wp_tearing_control_manager_v1_interface, 1, },
50 | };
51 |
52 | /* The test surface and Wayland surface. */
53 | static struct test_surface *test_surface;
54 | static struct wl_surface *wayland_surface;
55 |
56 | /* The tearing control. */
57 | static struct wp_tearing_control_v1 *tearing_control;
58 |
59 | /* The presentation hint used. 1 means async, and 0 means vsync. */
60 | static int used_presentation_mode;
61 |
62 |
63 |
64 | /* Forward declarations. */
65 | static void verify_async_used (void);
66 | static void verify_vsync_used (void);
67 |
68 |
69 |
70 | static struct test_buffer *
71 | make_test_buffer (void)
72 | {
73 | struct wl_buffer *buffer;
74 | struct test_buffer *test_buffer;
75 | char *empty_data;
76 | size_t stride;
77 |
78 | stride = get_image_stride (display, 24, 1);
79 |
80 | if (!stride)
81 | report_test_failure ("unknown stride");
82 |
83 | empty_data = calloc (1, stride);
84 |
85 | if (!empty_data)
86 | report_test_failure ("failed to allocate buffer data");
87 |
88 | buffer = upload_image_data (display, empty_data, 1, 1, 24);
89 | free (empty_data);
90 |
91 | if (!buffer)
92 | report_test_failure ("failed to create single pixel buffer");
93 |
94 | test_buffer = get_test_buffer (display, buffer);
95 |
96 | if (!test_buffer)
97 | report_test_failure ("failed to create test buffer");
98 |
99 | return test_buffer;
100 | }
101 |
102 | static void
103 | test_single_step (enum test_kind kind)
104 | {
105 | struct test_buffer *buffer;
106 |
107 | again:
108 |
109 | test_log ("running test step: %s", test_names[kind]);
110 |
111 | switch (kind)
112 | {
113 | case TEARING_CONTROL_KIND:
114 | #define VSYNC WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC
115 | wp_tearing_control_v1_set_presentation_hint (tearing_control,
116 | VSYNC);
117 | #undef VSYNC
118 | buffer = make_test_buffer ();
119 |
120 | /* Attach the buffer. */
121 | wl_surface_attach (wayland_surface, buffer->buffer, 0, 0);
122 | wl_surface_commit (wayland_surface);
123 |
124 | /* Now see what kind of presentation was used. */
125 | verify_vsync_used ();
126 |
127 | #define ASYNC WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC
128 | wp_tearing_control_v1_set_presentation_hint (tearing_control,
129 | ASYNC);
130 | #undef ASYNC
131 | wl_surface_commit (wayland_surface);
132 |
133 | /* Now verify that async presentation was used. */
134 | verify_async_used ();
135 |
136 | kind = TEARING_DESTROY_KIND;
137 | goto again;
138 |
139 | case TEARING_DESTROY_KIND:
140 | /* Destroy the tearing control resource. */
141 | wp_tearing_control_v1_destroy (tearing_control);
142 | wl_surface_commit (wayland_surface);
143 |
144 | /* Verify that the tearing hint reverted to vsync. */
145 | verify_vsync_used ();
146 | break;
147 | }
148 |
149 | if (kind == LAST_TEST)
150 | test_complete ();
151 | }
152 |
153 |
154 |
155 | static void
156 | handle_test_surface_mapped (void *data, struct test_surface *test_surface,
157 | uint32_t xid, const char *display_string)
158 | {
159 |
160 | }
161 |
162 | static void
163 | handle_test_surface_activated (void *data, struct test_surface *test_surface,
164 | uint32_t months, uint32_t milliseconds,
165 | struct wl_surface *activator_surface)
166 | {
167 |
168 | }
169 |
170 | static void
171 | handle_test_surface_committed (void *data, struct test_surface *test_surface,
172 | uint32_t presentation_hint)
173 | {
174 | used_presentation_mode = presentation_hint;
175 | }
176 |
177 | static const struct test_surface_listener test_surface_listener =
178 | {
179 | handle_test_surface_mapped,
180 | handle_test_surface_activated,
181 | handle_test_surface_committed,
182 | };
183 |
184 | static void
185 | verify_async_used (void)
186 | {
187 | wl_display_roundtrip (display->display);
188 |
189 | if (used_presentation_mode != 1)
190 | report_test_failure ("async presentation not used where expected!");
191 | }
192 |
193 | static void
194 | verify_vsync_used (void)
195 | {
196 | wl_display_roundtrip (display->display);
197 |
198 | if (used_presentation_mode == 1)
199 | report_test_failure ("vsync presentation not used where expected!");
200 | }
201 |
202 |
203 |
204 | static void
205 | run_test (void)
206 | {
207 | if (!make_test_surface (display, &wayland_surface,
208 | &test_surface))
209 | report_test_failure ("failed to create test surface");
210 |
211 | test_surface_add_listener (test_surface, &test_surface_listener,
212 | NULL);
213 |
214 | tearing_control
215 | = wp_tearing_control_manager_v1_get_tearing_control (manager,
216 | wayland_surface);
217 |
218 | if (!tearing_control)
219 | report_test_failure ("failed to create tearing control");
220 |
221 | test_single_step (TEARING_CONTROL_KIND);
222 |
223 | while (true)
224 | {
225 | if (wl_display_dispatch (display->display) == -1)
226 | die ("wl_display_dispatch");
227 | }
228 | }
229 |
230 | int
231 | main (void)
232 | {
233 | test_init ();
234 | display = open_test_display (test_interfaces,
235 | ARRAYELTS (test_interfaces));
236 |
237 | if (!display)
238 | report_test_failure ("failed to open display");
239 |
240 | run_test ();
241 | }
242 |
--------------------------------------------------------------------------------
/relative-pointer-unstable-v1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright © 2014 Jonas Ådahl
6 | Copyright © 2015 Red Hat Inc.
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a
9 | copy of this software and associated documentation files (the "Software"),
10 | to deal in the Software without restriction, including without limitation
11 | the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 | and/or sell copies of the Software, and to permit persons to whom the
13 | Software is furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice (including the next
16 | paragraph) shall be included in all copies or substantial portions of the
17 | Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 | DEALINGS IN THE SOFTWARE.
26 |
27 |
28 |
29 | This protocol specifies a set of interfaces used for making clients able to
30 | receive relative pointer events not obstructed by barriers (such as the
31 | monitor edge or other pointer barriers).
32 |
33 | To start receiving relative pointer events, a client must first bind the
34 | global interface "wp_relative_pointer_manager" which, if a compositor
35 | supports relative pointer motion events, is exposed by the registry. After
36 | having created the relative pointer manager proxy object, the client uses
37 | it to create the actual relative pointer object using the
38 | "get_relative_pointer" request given a wl_pointer. The relative pointer
39 | motion events will then, when applicable, be transmitted via the proxy of
40 | the newly created relative pointer object. See the documentation of the
41 | relative pointer interface for more details.
42 |
43 | Warning! The protocol described in this file is experimental and backward
44 | incompatible changes may be made. Backward compatible changes may be added
45 | together with the corresponding interface version bump. Backward
46 | incompatible changes are done by bumping the version number in the protocol
47 | and interface names and resetting the interface version. Once the protocol
48 | is to be declared stable, the 'z' prefix and the version number in the
49 | protocol and interface names are removed and the interface version number is
50 | reset.
51 |
52 |
53 |
54 |
55 | A global interface used for getting the relative pointer object for a
56 | given pointer.
57 |
58 |
59 |
60 |
61 | Used by the client to notify the server that it will no longer use this
62 | relative pointer manager object.
63 |
64 |
65 |
66 |
67 |
68 | Create a relative pointer interface given a wl_pointer object. See the
69 | wp_relative_pointer interface for more details.
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | A wp_relative_pointer object is an extension to the wl_pointer interface
79 | used for emitting relative pointer events. It shares the same focus as
80 | wl_pointer objects of the same seat and will only emit events when it has
81 | focus.
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 | Relative x/y pointer motion from the pointer of the seat associated with
91 | this object.
92 |
93 | A relative motion is in the same dimension as regular wl_pointer motion
94 | events, except they do not represent an absolute position. For example,
95 | moving a pointer from (x, y) to (x', y') would have the equivalent
96 | relative motion (x' - x, y' - y). If a pointer motion caused the
97 | absolute pointer position to be clipped by for example the edge of the
98 | monitor, the relative motion is unaffected by the clipping and will
99 | represent the unclipped motion.
100 |
101 | This event also contains non-accelerated motion deltas. The
102 | non-accelerated delta is, when applicable, the regular pointer motion
103 | delta as it was before having applied motion acceleration and other
104 | transformations such as normalization.
105 |
106 | Note that the non-accelerated delta does not represent 'raw' events as
107 | they were read from some device. Pointer motion acceleration is device-
108 | and configuration-specific and non-accelerated deltas and accelerated
109 | deltas may have the same value on some devices.
110 |
111 | Relative motions are not coupled to wl_pointer.motion events, and can be
112 | sent in combination with such events, but also independently. There may
113 | also be scenarios where wl_pointer.motion is sent, but there is no
114 | relative motion. The order of an absolute and relative motion event
115 | originating from the same physical motion is not guaranteed.
116 |
117 | If the client needs button events or focus state, it can receive them
118 | from a wl_pointer object of the same seat that the wp_relative_pointer
119 | object is associated with.
120 |
121 |
123 |
125 |
127 |
129 |
131 |
133 |
134 |
135 |
136 |
137 |
--------------------------------------------------------------------------------
/tests/damage_test.c:
--------------------------------------------------------------------------------
1 | /* Tests for the Wayland compositor running on the X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include "test_harness.h"
21 |
22 | enum test_kind
23 | {
24 | MAP_WINDOW_KIND,
25 | BASIC_TEST_CARD_IMAGE_KIND,
26 | BASIC_DAMAGE_KIND,
27 | };
28 |
29 | static const char *test_names[] =
30 | {
31 | "map_window",
32 | "basic_test_card_image",
33 | "basic_damage",
34 | };
35 |
36 | #define LAST_TEST BASIC_DAMAGE_KIND
37 |
38 | /* The display. */
39 | static struct test_display *display;
40 |
41 | /* Test interfaces. */
42 | static struct test_interface test_interfaces[] =
43 | {
44 | /* No interfaces yet. */
45 | };
46 |
47 | /* The test surface window. */
48 | static Window test_surface_window;
49 |
50 | /* The test surface and Wayland surface. */
51 | static struct test_surface *test_surface;
52 | static struct wl_surface *wayland_surface;
53 |
54 |
55 |
56 | /* Forward declarations. */
57 | static void submit_frame_callback (struct wl_surface *, enum test_kind);
58 | static void submit_surface_damage (struct wl_surface *, int, int, int, int);
59 |
60 |
61 |
62 | static void
63 | verify_single_step (enum test_kind kind)
64 | {
65 | switch (kind)
66 | {
67 | case BASIC_TEST_CARD_IMAGE_KIND:
68 | verify_image_data (display, test_surface_window,
69 | "damage_test_1.dump");
70 | break;
71 |
72 | case BASIC_DAMAGE_KIND:
73 | verify_image_data (display, test_surface_window,
74 | "damage_test_2.dump");
75 | break;
76 |
77 | default:
78 | break;
79 | }
80 |
81 | if (kind == LAST_TEST)
82 | test_complete ();
83 | }
84 |
85 | static void
86 | test_single_step (enum test_kind kind)
87 | {
88 | struct wl_buffer *buffer;
89 |
90 | test_log ("running test step: %s", test_names[kind]);
91 |
92 | switch (kind)
93 | {
94 | case MAP_WINDOW_KIND:
95 | buffer = load_png_image (display, "blue.png");
96 |
97 | if (!buffer)
98 | report_test_failure ("failed to load blue.png");
99 |
100 | wl_surface_attach (wayland_surface, buffer, 0, 0);
101 | submit_surface_damage (wayland_surface, 0, 0,
102 | INT_MAX, INT_MAX);
103 | wl_surface_commit (wayland_surface);
104 | wl_buffer_destroy (buffer);
105 | break;
106 |
107 | case BASIC_TEST_CARD_IMAGE_KIND:
108 | buffer = load_png_image (display, "basic_test_card.png");
109 |
110 | if (!buffer)
111 | report_test_failure ("failed to load basic_test_card.png");
112 |
113 | wl_surface_attach (wayland_surface, buffer, 0, 0);
114 | submit_frame_callback (wayland_surface, kind);
115 | submit_surface_damage (wayland_surface, 0, 0,
116 | INT_MAX, INT_MAX);
117 | wl_surface_commit (wayland_surface);
118 | wl_buffer_destroy (buffer);
119 | break;
120 |
121 | case BASIC_DAMAGE_KIND:
122 | buffer = load_png_image (display, "basic_damage.png");
123 |
124 | if (!buffer)
125 | report_test_failure ("failed to load basic_damage.png");
126 |
127 | wl_surface_attach (wayland_surface, buffer, 0, 0);
128 | submit_frame_callback (wayland_surface, kind);
129 | submit_surface_damage (wayland_surface, 49, 26, 57, 48);
130 | wl_surface_commit (wayland_surface);
131 | wl_buffer_destroy (buffer);
132 | break;
133 | }
134 | }
135 |
136 | static void
137 | test_next_step (enum test_kind kind)
138 | {
139 | switch (kind)
140 | {
141 | case BASIC_TEST_CARD_IMAGE_KIND:
142 | test_single_step (BASIC_DAMAGE_KIND);
143 | break;
144 |
145 | default:
146 | break;
147 | }
148 | }
149 |
150 |
151 |
152 | static void
153 | handle_test_surface_mapped (void *data, struct test_surface *surface,
154 | uint32_t xid, const char *display_string)
155 | {
156 | /* Sleep for 1 second to ensure that the window is exposed and
157 | redirected. */
158 | sleep (1);
159 |
160 | /* Start the test. */
161 | test_surface_window = xid;
162 |
163 | /* Run the test again. */
164 | test_single_step (BASIC_TEST_CARD_IMAGE_KIND);
165 | }
166 |
167 | static void
168 | handle_test_surface_committed (void *data, struct test_surface *surface,
169 | uint32_t presentation_hint)
170 | {
171 |
172 | }
173 |
174 | static const struct test_surface_listener test_surface_listener =
175 | {
176 | handle_test_surface_mapped,
177 | NULL,
178 | handle_test_surface_committed,
179 | };
180 |
181 |
182 |
183 | static void
184 | handle_wl_callback_done (void *data, struct wl_callback *callback,
185 | uint32_t callback_data)
186 | {
187 | enum test_kind kind;
188 |
189 | /* kind is not a pointer. It is an enum test_kind stuffed into a
190 | pointer. */
191 | kind = (intptr_t) data;
192 |
193 | wl_callback_destroy (callback);
194 | verify_single_step (kind);
195 |
196 | /* Now run the next test in this sequence. */
197 | test_next_step (kind);
198 | }
199 |
200 | static const struct wl_callback_listener wl_callback_listener =
201 | {
202 | handle_wl_callback_done,
203 | };
204 |
205 |
206 |
207 | static void
208 | submit_frame_callback (struct wl_surface *surface, enum test_kind kind)
209 | {
210 | struct wl_callback *callback;
211 |
212 | callback = wl_surface_frame (surface);
213 | wl_callback_add_listener (callback, &wl_callback_listener,
214 | (void *) (intptr_t) kind);
215 | }
216 |
217 | static void
218 | submit_surface_damage (struct wl_surface *surface, int x, int y, int width,
219 | int height)
220 | {
221 | test_log ("damaging surface by %d, %d, %d, %d", x, y, width,
222 | height);
223 |
224 | wl_surface_damage (surface, x, y, width, height);
225 | }
226 |
227 | static void
228 | run_test (void)
229 | {
230 | if (!make_test_surface (display, &wayland_surface,
231 | &test_surface))
232 | report_test_failure ("failed to create test surface");
233 |
234 | test_surface_add_listener (test_surface, &test_surface_listener,
235 | NULL);
236 | test_single_step (MAP_WINDOW_KIND);
237 |
238 | while (true)
239 | {
240 | if (wl_display_dispatch (display->display) == -1)
241 | die ("wl_display_dispatch");
242 | }
243 | }
244 |
245 | int
246 | main (void)
247 | {
248 | test_init ();
249 | display = open_test_display (test_interfaces,
250 | ARRAYELTS (test_interfaces));
251 |
252 | if (!display)
253 | report_test_failure ("failed to open display");
254 |
255 | run_test ();
256 | }
257 |
--------------------------------------------------------------------------------
/keyboard-shortcuts-inhibit-unstable-v1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Copyright © 2017 Red Hat Inc.
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a
8 | copy of this software and associated documentation files (the "Software"),
9 | to deal in the Software without restriction, including without limitation
10 | the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 | and/or sell copies of the Software, and to permit persons to whom the
12 | Software is furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice (including the next
15 | paragraph) shall be included in all copies or substantial portions of the
16 | Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 | DEALINGS IN THE SOFTWARE.
25 |
26 |
27 |
28 | This protocol specifies a way for a client to request the compositor
29 | to ignore its own keyboard shortcuts for a given seat, so that all
30 | key events from that seat get forwarded to a surface.
31 |
32 | Warning! The protocol described in this file is experimental and
33 | backward incompatible changes may be made. Backward compatible
34 | changes may be added together with the corresponding interface
35 | version bump.
36 | Backward incompatible changes are done by bumping the version
37 | number in the protocol and interface names and resetting the
38 | interface version. Once the protocol is to be declared stable,
39 | the 'z' prefix and the version number in the protocol and
40 | interface names are removed and the interface version number is
41 | reset.
42 |
43 |
44 |
45 |
46 | A global interface used for inhibiting the compositor keyboard shortcuts.
47 |
48 |
49 |
50 |
51 | Destroy the keyboard shortcuts inhibitor manager.
52 |
53 |
54 |
55 |
56 |
57 | Create a new keyboard shortcuts inhibitor object associated with
58 | the given surface for the given seat.
59 |
60 | If shortcuts are already inhibited for the specified seat and surface,
61 | a protocol error "already_inhibited" is raised by the compositor.
62 |
63 |
64 |
66 |
68 |
69 |
70 |
71 |
74 |
75 |
76 |
77 |
78 |
79 | A keyboard shortcuts inhibitor instructs the compositor to ignore
80 | its own keyboard shortcuts when the associated surface has keyboard
81 | focus. As a result, when the surface has keyboard focus on the given
82 | seat, it will receive all key events originating from the specified
83 | seat, even those which would normally be caught by the compositor for
84 | its own shortcuts.
85 |
86 | The Wayland compositor is however under no obligation to disable
87 | all of its shortcuts, and may keep some special key combo for its own
88 | use, including but not limited to one allowing the user to forcibly
89 | restore normal keyboard events routing in the case of an unwilling
90 | client. The compositor may also use the same key combo to reactivate
91 | an existing shortcut inhibitor that was previously deactivated on
92 | user request.
93 |
94 | When the compositor restores its own keyboard shortcuts, an
95 | "inactive" event is emitted to notify the client that the keyboard
96 | shortcuts inhibitor is not effectively active for the surface and
97 | seat any more, and the client should not expect to receive all
98 | keyboard events.
99 |
100 | When the keyboard shortcuts inhibitor is inactive, the client has
101 | no way to forcibly reactivate the keyboard shortcuts inhibitor.
102 |
103 | The user can chose to re-enable a previously deactivated keyboard
104 | shortcuts inhibitor using any mechanism the compositor may offer,
105 | in which case the compositor will send an "active" event to notify
106 | the client.
107 |
108 | If the surface is destroyed, unmapped, or loses the seat's keyboard
109 | focus, the keyboard shortcuts inhibitor becomes irrelevant and the
110 | compositor will restore its own keyboard shortcuts but no "inactive"
111 | event is emitted in this case.
112 |
113 |
114 |
115 |
116 | Remove the keyboard shortcuts inhibitor from the associated wl_surface.
117 |
118 |
119 |
120 |
121 |
122 | This event indicates that the shortcut inhibitor is active.
123 |
124 | The compositor sends this event every time compositor shortcuts
125 | are inhibited on behalf of the surface. When active, the client
126 | may receive input events normally reserved by the compositor
127 | (see zwp_keyboard_shortcuts_inhibitor_v1).
128 |
129 | This occurs typically when the initial request "inhibit_shortcuts"
130 | first becomes active or when the user instructs the compositor to
131 | re-enable and existing shortcuts inhibitor using any mechanism
132 | offered by the compositor.
133 |
134 |
135 |
136 |
137 |
138 | This event indicates that the shortcuts inhibitor is inactive,
139 | normal shortcuts processing is restored by the compositor.
140 |
141 |
142 |
143 |
144 |
--------------------------------------------------------------------------------
/tests/select_helper_multiple.c:
--------------------------------------------------------------------------------
1 | /* Tests for the Wayland compositor running on the X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 |
25 | #include
26 | #include
27 |
28 | /* select_helper_multiple.c -- Perform a request for multiple
29 | selections.
30 |
31 | There must be at least three arguments: the name of the display,
32 | the timestamp at which the selection was acquired, and the
33 | target(s). */
34 |
35 | /* The display connected to. */
36 | static Display *display;
37 |
38 | /* The selection transfer window. */
39 | static Window selection_transfer_window;
40 |
41 | /* Various atoms. */
42 | static Atom CLIPBOARD, INCR, MULTIPLE, ATOM_PAIR, *target_atoms;
43 |
44 | static void
45 | wait_for_selection_notify (XEvent *event)
46 | {
47 | while (true)
48 | {
49 | XNextEvent (display, event);
50 |
51 | if (event->type == SelectionNotify
52 | && (event->xselection.requestor
53 | == selection_transfer_window)
54 | && (event->xselection.selection
55 | == CLIPBOARD)
56 | && (event->xselection.property
57 | == MULTIPLE)
58 | && (event->xselection.target
59 | == MULTIPLE))
60 | return;
61 | }
62 | }
63 |
64 | static void
65 | wait_for_new_value (XEvent *event, Atom property)
66 | {
67 | while (true)
68 | {
69 | XNextEvent (display, event);
70 |
71 | if (event->type == PropertyNotify
72 | && event->xproperty.atom == property
73 | && event->xproperty.state == PropertyNewValue)
74 | return;
75 | }
76 | }
77 |
78 | static size_t
79 | get_size_for_format (int format)
80 | {
81 | switch (format)
82 | {
83 | case 32:
84 | return sizeof (long);
85 |
86 | case 16:
87 | return sizeof (short int);
88 |
89 | case 8:
90 | return sizeof (char);
91 | }
92 |
93 | /* Should not actually happen. */
94 | return 0;
95 | }
96 |
97 | int
98 | main (int argc, char **argv)
99 | {
100 | XSetWindowAttributes attrs;
101 | unsigned long flags, timestamp;
102 | char *atom_names[4];
103 | Atom atoms[4], actual_type, property, *parameters;
104 | XEvent event;
105 | int actual_format, i;
106 | unsigned long nitems, bytes_after;
107 | unsigned char *data;
108 |
109 | if (argc < 4)
110 | /* Not enough arguments were specified. */
111 | return 1;
112 |
113 | display = XOpenDisplay (argv[1]);
114 |
115 | if (!display)
116 | return 1;
117 |
118 | /* Make the window used to transfer selection data. */
119 | attrs.override_redirect = True;
120 | attrs.event_mask = PropertyChangeMask;
121 | flags = CWEventMask | CWOverrideRedirect;
122 |
123 | selection_transfer_window
124 | = XCreateWindow (display, DefaultRootWindow (display),
125 | -1, -1, 1, 1, 0, CopyFromParent, InputOnly,
126 | CopyFromParent, flags, &attrs);
127 |
128 | /* Get the time. */
129 | timestamp = strtoul (argv[2], NULL, 10);
130 |
131 | atom_names[0] = (char *) "CLIPBOARD";
132 | atom_names[1] = (char *) "INCR";
133 | atom_names[2] = (char *) "MULTIPLE";
134 | atom_names[3] = (char *) "ATOM_PAIR";
135 | XInternAtoms (display, atom_names, 4, False, atoms);
136 | CLIPBOARD = atoms[0];
137 | INCR = atoms[1];
138 | MULTIPLE = atoms[2];
139 | ATOM_PAIR = atoms[3];
140 |
141 | /* Intern the target atoms. */
142 | target_atoms = malloc (sizeof *target_atoms * argc - 3);
143 | XInternAtoms (display, &argv[3], argc - 3, False, target_atoms);
144 |
145 | /* Write each of the atoms as parameters before making the selection
146 | request. */
147 | atoms[0] = target_atoms[0];
148 | atoms[1] = target_atoms[0];
149 | XChangeProperty (display, selection_transfer_window, MULTIPLE,
150 | ATOM_PAIR, 32, PropModeReplace,
151 | (unsigned char *) atoms, 2);
152 |
153 | for (i = 1; i < argc - 3; ++i)
154 | {
155 | atoms[0] = target_atoms[i];
156 | atoms[1] = target_atoms[i];
157 | XChangeProperty (display, selection_transfer_window, MULTIPLE,
158 | ATOM_PAIR, 32, PropModeAppend,
159 | (unsigned char *) atoms, 2);
160 | }
161 |
162 | /* Now, request the selection. */
163 | XConvertSelection (display, CLIPBOARD, MULTIPLE,
164 | MULTIPLE, selection_transfer_window,
165 | timestamp);
166 |
167 | /* And wait for the SelectionNotify event. */
168 | wait_for_selection_notify (&event);
169 |
170 | /* Selection conversion failed. */
171 | if (event.xselection.property == None)
172 | return 1;
173 |
174 | /* Now, read the MULTIPLE property again. See which conversions
175 | were completed. */
176 | XGetWindowProperty (display, selection_transfer_window,
177 | event.xselection.property, 0, (argc - 3) * 2,
178 | True, ATOM_PAIR,
179 | &actual_type, &actual_format, &nitems,
180 | &bytes_after, &data);
181 |
182 | if (actual_format != 32 || actual_type != ATOM_PAIR
183 | || nitems != (argc - 3) * 2)
184 | return 1;
185 |
186 | parameters = (Atom *) data;
187 |
188 | for (i = 0; i < argc - 3; ++i)
189 | {
190 | if (!parameters[i * 2 + 1])
191 | continue;
192 |
193 | property = parameters[i * 2];
194 |
195 | XGetWindowProperty (display, selection_transfer_window,
196 | property, 0, 0xffffffff, True, AnyPropertyType,
197 | &actual_type, &actual_format, &nitems, &bytes_after,
198 | &data);
199 |
200 | if (!data || bytes_after)
201 | return 1;
202 |
203 | if (actual_type == INCR)
204 | {
205 | while (true)
206 | {
207 | XFree (data);
208 |
209 | wait_for_new_value (&event, property);
210 | XGetWindowProperty (display, selection_transfer_window, property, 0,
211 | 0xffffffff, True, AnyPropertyType, &actual_type,
212 | &actual_format, &nitems, &bytes_after, &data);
213 |
214 | if (!data)
215 | return 0;
216 |
217 | if (nitems)
218 | {
219 | /* Write the selection data to stdout. */
220 | if (fwrite (data, get_size_for_format (actual_format),
221 | nitems, stdout) != nitems)
222 | return 1;
223 |
224 | continue;
225 | }
226 |
227 | /* Selection transfer is complete. */
228 | fflush (stdout);
229 | break;
230 | }
231 | }
232 | else
233 | {
234 | /* Write the selection data to stdout. */
235 | if (fwrite (data, get_size_for_format (actual_format),
236 | nitems, stdout) != nitems)
237 | return 1;
238 |
239 | /* Return success. */
240 | fflush (stdout);
241 | }
242 | }
243 |
244 | return 0;
245 | }
246 |
--------------------------------------------------------------------------------
/Imakefile:
--------------------------------------------------------------------------------
1 | #include "12to11.conf"
2 |
3 | #ifndef HasPosixThreads
4 | #error "Posix threads are required"
5 | #endif
6 |
7 | SYS_LIBRARIES = MathLibrary ThreadsLibraries
8 | DEPLIBS = $(DEPXLIB) $(DEPEXTENSIONLIB) $(DEPXRANDRLIB) $(DEPXRENDERLIB) $(DEPXFIXESLIB) $(DEPXILIB) $(DEPXKBFILELIB)
9 | LOCAL_LIBRARIES = $(XLIB) $(EXTENSIONLIB) $(XCBLIB) $(XCB) $(XCB_SHM) $(XRANDRLIB) $(PIXMAN) $(XRENDERLIB) $(XILIB) $(XKBFILELIB) $(XFIXESLIB) $(XCB_DRI3) $(XCB_SHAPE) $(WAYLAND_SERVER) $(XCB_RANDR) $(DRM) $(XPRESENTLIB) $(XSHMFENCELIB)
10 | INCLUDES := $(DRMINCLUDES) $(PIXMANINCLUDES)
11 |
12 | #ifdef BuildTests
13 | # define IHaveSubdirs
14 | # define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)'
15 | SUBDIRS = tests
16 |
17 | MakeSubdirs($(SUBDIRS))
18 | DependSubdirs($(SUBDIRS))
19 | #endif
20 |
21 | SRCS = 12to11.c run.c alloc.c fns.c output.c compositor.c surface.c region.c shm.c atoms.c subcompositor.c positioner.c xdg_wm.c xdg_surface.c xdg_toplevel.c frame_clock.c xerror.c ewmh.c timer.c subsurface.c seat.c data_device.c xdg_popup.c dmabuf.c buffer.c select.c xdata.c xsettings.c dnd.c icon_surface.c primary_selection.c renderer.c picture_renderer.c explicit_synchronization.c transform.c wp_viewporter.c decoration.c text_input.c single_pixel_buffer.c drm_lease.c pointer_constraints.c time.c relative_pointer.c keyboard_shortcuts_inhibit.c idle_inhibit.c process.c fence_ring.c pointer_gestures.c test.c buffer_release.c xdg_activation.c tearing_control.c sync_source.c
22 | OBJS = 12to11.o run.o alloc.o fns.o output.o compositor.o surface.o region.o shm.o atoms.o subcompositor.o positioner.o xdg_wm.o xdg_surface.o xdg_toplevel.o frame_clock.o xerror.o ewmh.o timer.o subsurface.o seat.o data_device.o xdg_popup.o dmabuf.o buffer.o select.o xdata.o xsettings.o dnd.o icon_surface.o primary_selection.o renderer.o picture_renderer.o explicit_synchronization.o transform.o wp_viewporter.o decoration.o text_input.o single_pixel_buffer.o drm_lease.o pointer_constraints.o time.o relative_pointer.o keyboard_shortcuts_inhibit.o idle_inhibit.o process.o fence_ring.o pointer_gestures.o test.o buffer_release.o xdg_activation.o tearing_control.o sync_source.o
23 | GENHEADERS = transfer_atoms.h drm_modifiers.h
24 | HEADER = $(GENHEADERS) compositor.h
25 |
26 | #if defined LinuxArchitecture || defined GNUArchitecture
27 | EXTRA_DEFINES := -DPortFile=\"port_gnu.h\" -D_GNU_SOURCE -U_BSD_SOURCE -U_SVID_SOURCE
28 | DEPEND_DEFINES := -DPortFile=\"port_gnu.h\"
29 | #else
30 | # error "The protocol translator was not ported to your system"
31 | #endif
32 |
33 | #ifdef HaveEglSupport
34 |
35 | EGL_SRCS = egl.c
36 | EGL_OBJS = egl.o
37 | LOCAL_LIBRARIES ::= $(LOCAL_LIBRARIES) $(EGL) $(GLES)
38 | SRCS ::= $(SRCS) $(EGL_SRCS)
39 | OBJS ::= $(OBJS) $(EGL_OBJS)
40 | DEFINES ::= $(DEFINES) -DHaveEglSupport
41 |
42 | shaders.h: shaders.txt shaders.awk
43 | awk -f shaders.awk shaders.txt > $@
44 |
45 | depend:: shaders.h
46 |
47 | $(EGL_OBJS): shaders.h
48 |
49 | cleandir::
50 | $(RM) shaders.h
51 |
52 | #endif
53 |
54 | OPTIMIZE = -O0
55 | #if GccMajorVersion >= 10
56 | ANALYZE = -fanalyzer
57 | #endif
58 | #if GccMajorVersion >= 7
59 | CDEBUGFLAGS := -fno-common -Wall -Warith-conversion -Wdate-time -Wdisabled-optimization -Wdouble-promotion -Wduplicated-cond -Wextra -Wformat-signedness -Winit-self -Winvalid-pch -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wmissing-prototypes -Wnested-externs -Wnull-dereference -Wold-style-definition -Wopenmp-simd -Wpacked -Wpointer-arith -Wstrict-prototypes -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wsuggest-final-methods -Wsuggest-final-types -Wuninitialized -Wunknown-pragmas -Wunused-macros -Wvariadic-macros -Wvector-operation-performance -Wwrite-strings -Warray-bounds=2 -Wattribute-alias=2 -Wformat=2 -Wformat-truncation=2 -Wimplicit-fallthrough=5 -Wshift-overflow=2 -Wuse-after-free=3 -Wvla-larger-than=4031 -Wredundant-decls -Wno-missing-field-initializers -Wno-override-init -Wno-sign-compare -Wno-type-limits -Wno-unused-parameter -Wno-format-nonliteral -g3 $(OPTIMIZE) $(ANALYZE)
60 | #endif
61 |
62 | short_types.txt: media_types.txt
63 | XCOMM Remove all data types starting with application/vnd.
64 | XCOMM no program really uses them in clipboard data, and they
65 | XCOMM waste a lot of space on disk.
66 | sed '/application\/vnd/d' media_types.txt > $@
67 |
68 | transfer_atoms.h: short_types.txt mime0.awk mime1.awk mime2.awk mime3.awk \
69 | mime4.awk
70 | awk -f mime0.awk short_types.txt > $@
71 | awk -f mime1.awk short_types.txt >> $@
72 | awk -f mime2.awk short_types.txt >> $@
73 | awk -f mime3.awk short_types.txt >> $@
74 | awk -f mime4.awk short_types.txt >> $@
75 |
76 | drm_modifiers.h: modifiers.awk $(DRMFOURCCH)
77 | awk -f modifiers.awk $(DRMFOURCCH) > $@
78 |
79 | /* Now, define generated files. */
80 |
81 | #define ScannerTarget(name) @@\
82 | name.h: name.xml @@\
83 | $(WAYLAND_SCANNER) server-header $< $@ @@\
84 | @@\
85 | name.c: name.xml name.h @@\
86 | $(WAYLAND_SCANNER) private-code $< $@ @@\
87 | @@\
88 | GENHEADERS := $(GENHEADERS) name.h @@\
89 | OBJS := $(OBJS) name.o @@\
90 | SRCS := $(SRCS) name.c @@\
91 | GENSRCS := $(GENSRCS) name.c @@\
92 |
93 | ScannerTarget(linux-dmabuf-unstable-v1)
94 | ScannerTarget(xdg-shell)
95 | ScannerTarget(primary-selection-unstable-v1)
96 | ScannerTarget(linux-explicit-synchronization-unstable-v1)
97 | ScannerTarget(viewporter)
98 | ScannerTarget(xdg-decoration-unstable-v1)
99 | ScannerTarget(text-input-unstable-v3)
100 | ScannerTarget(single-pixel-buffer-v1)
101 | ScannerTarget(drm-lease-v1)
102 | ScannerTarget(pointer-constraints-unstable-v1)
103 | ScannerTarget(relative-pointer-unstable-v1)
104 | ScannerTarget(keyboard-shortcuts-inhibit-unstable-v1)
105 | ScannerTarget(idle-inhibit-unstable-v1)
106 | ScannerTarget(pointer-gestures-unstable-v1)
107 | ScannerTarget(12to11-test)
108 | ScannerTarget(xdg-activation-v1)
109 | ScannerTarget(tearing-control-v1)
110 |
111 | /* Make seat.o depend on test_seat.c, as it includes that. Both files
112 | are rather special. */
113 | seat.o: test_seat.c
114 |
115 | /* Make OBJS depend on scanner headers, and depend on both them and
116 | SRCS. */
117 | $(OBJS): $(GENHEADERS)
118 |
119 | /* depend somehow does not depend on SRCS, even though some of OBJS
120 | are generated. */
121 | depend:: $(GENHEADERS) $(SRCS)
122 |
123 | cleandir::
124 | $(RM) $(GENHEADERS) $(GENSRCS) short_types.txt 12to11.tar.gz
125 |
126 | ComplexProgramTarget(12to11)
127 |
128 | .PHONY: dist
129 | dist: 12to11.tar.gz
130 |
131 | DIST_FILES = Imakefile $(SRCS) media_types.txt shaders.txt *.awk *.xml 12to11.man README libraries.def *.h
132 |
133 | /* Include files generated by wayland-scanner, so the target does not
134 | need to have it installed. */
135 |
136 | 12to11.tar.gz: $(DIST_FILES)
137 | rm -rf 12to11.tar.gz
138 | tar -cvf 12to11.tar $(DIST_FILES)
139 | gzip 12to11.tar
140 | $(RM) 12to11.tar
141 |
--------------------------------------------------------------------------------
/xdg-decoration-unstable-v1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Copyright © 2018 Simon Ser
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a
7 | copy of this software and associated documentation files (the "Software"),
8 | to deal in the Software without restriction, including without limitation
9 | the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 | and/or sell copies of the Software, and to permit persons to whom the
11 | Software is furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice (including the next
14 | paragraph) shall be included in all copies or substantial portions of the
15 | Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | DEALINGS IN THE SOFTWARE.
24 |
25 |
26 |
27 |
28 | This interface allows a compositor to announce support for server-side
29 | decorations.
30 |
31 | A window decoration is a set of window controls as deemed appropriate by
32 | the party managing them, such as user interface components used to move,
33 | resize and change a window's state.
34 |
35 | A client can use this protocol to request being decorated by a supporting
36 | compositor.
37 |
38 | If compositor and client do not negotiate the use of a server-side
39 | decoration using this protocol, clients continue to self-decorate as they
40 | see fit.
41 |
42 | Warning! The protocol described in this file is experimental and
43 | backward incompatible changes may be made. Backward compatible changes
44 | may be added together with the corresponding interface version bump.
45 | Backward incompatible changes are done by bumping the version number in
46 | the protocol and interface names and resetting the interface version.
47 | Once the protocol is to be declared stable, the 'z' prefix and the
48 | version number in the protocol and interface names are removed and the
49 | interface version number is reset.
50 |
51 |
52 |
53 |
54 | Destroy the decoration manager. This doesn't destroy objects created
55 | with the manager.
56 |
57 |
58 |
59 |
60 |
61 | Create a new decoration object associated with the given toplevel.
62 |
63 | Creating an xdg_toplevel_decoration from an xdg_toplevel which has a
64 | buffer attached or committed is a client error, and any attempts by a
65 | client to attach or manipulate a buffer prior to the first
66 | xdg_toplevel_decoration.configure event must also be treated as
67 | errors.
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | The decoration object allows the compositor to toggle server-side window
77 | decorations for a toplevel surface. The client can request to switch to
78 | another mode.
79 |
80 | The xdg_toplevel_decoration object must be destroyed before its
81 | xdg_toplevel.
82 |
83 |
84 |
85 |
87 |
89 |
91 |
92 |
93 |
94 |
95 | Switch back to a mode without any server-side decorations at the next
96 | commit.
97 |
98 |
99 |
100 |
101 |
102 | These values describe window decoration modes.
103 |
104 |
106 |
108 |
109 |
110 |
111 |
112 | Set the toplevel surface decoration mode. This informs the compositor
113 | that the client prefers the provided decoration mode.
114 |
115 | After requesting a decoration mode, the compositor will respond by
116 | emitting an xdg_surface.configure event. The client should then update
117 | its content, drawing it without decorations if the received mode is
118 | server-side decorations. The client must also acknowledge the configure
119 | when committing the new content (see xdg_surface.ack_configure).
120 |
121 | The compositor can decide not to use the client's mode and enforce a
122 | different mode instead.
123 |
124 | Clients whose decoration mode depend on the xdg_toplevel state may send
125 | a set_mode request in response to an xdg_surface.configure event and wait
126 | for the next xdg_surface.configure event to prevent unwanted state.
127 | Such clients are responsible for preventing configure loops and must
128 | make sure not to send multiple successive set_mode requests with the
129 | same decoration mode.
130 |
131 |
132 |
133 |
134 |
135 |
136 | Unset the toplevel surface decoration mode. This informs the compositor
137 | that the client doesn't prefer a particular decoration mode.
138 |
139 | This request has the same semantics as set_mode.
140 |
141 |
142 |
143 |
144 |
145 | The configure event asks the client to change its decoration mode. The
146 | configured state should not be applied immediately. Clients must send an
147 | ack_configure in response to this event. See xdg_surface.configure and
148 | xdg_surface.ack_configure for details.
149 |
150 | A configure event can be sent at any time. The specified mode must be
151 | obeyed by the client.
152 |
153 |
154 |
155 |
156 |
157 |
--------------------------------------------------------------------------------
/port_gnu.h:
--------------------------------------------------------------------------------
1 | /* Wayland compositor running on top of an X server.
2 |
3 | Copyright (C) 2022 to various contributors.
4 |
5 | This file is part of 12to11.
6 |
7 | 12to11 is free software: you can redistribute it and/or modify it
8 | under the terms of the GNU General Public License as published by the
9 | Free Software Foundation, either version 3 of the License, or (at your
10 | option) any later version.
11 |
12 | 12to11 is distributed in the hope that it will be useful, but WITHOUT
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 | for more details.
16 |
17 | You should have received a copy of the GNU General Public License
18 | along with 12to11. If not, see . */
19 |
20 | /* Copyright (C) 2001-2022 Free Software Foundation, Inc.
21 |
22 | This program is free software: you can redistribute it and/or modify
23 | it under the terms of the GNU Lesser General Public License as
24 | published by the Free Software Foundation; either version 2.1 of the
25 | License, or (at your option) any later version.
26 |
27 | This program is distributed in the hope that it will be useful, but
28 | WITHOUT ANY WARRANTY; without even the implied warranty of
29 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 | Lesser General Public License for more details.
31 |
32 | You should have received a copy of the GNU Lesser General Public
33 | License along with this program.
34 |
35 | If not, see . */
36 |
37 | #ifndef IntAddWrapv
38 |
39 | #define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))
40 | #define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v))
41 | #define _GL_TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
42 | #define _GL_EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)
43 | #define _GL_TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)
44 |
45 | #define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \
46 | ((t) ((ut) (a) op (ut) (b)))
47 |
48 | #define _GL_INT_NEGATE_RANGE_OVERFLOW(a, min, max) \
49 | ((min) < 0 ? (a) < - (max) : 0 < (a))
50 |
51 | #define _GL_INT_MINIMUM(e) \
52 | (_GL_EXPR_SIGNED (e) \
53 | ? ~ _GL_SIGNED_INT_MAXIMUM (e) \
54 | : _GL_INT_CONVERT (e, 0))
55 |
56 | #define _GL_INT_MAXIMUM(e) \
57 | (_GL_EXPR_SIGNED (e) \
58 | ? _GL_SIGNED_INT_MAXIMUM (e) \
59 | : _GL_INT_NEGATE_CONVERT (e, 1))
60 |
61 | #define _GL_SIGNED_INT_MAXIMUM(e) \
62 | (((_GL_INT_CONVERT (e, 1) << (_GL_TYPE_WIDTH (+ (e)) - 2)) - 1) * 2 + 1)
63 |
64 | #define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \
65 | (overflow (a, b, tmin, tmax) \
66 | ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \
67 | : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0))
68 |
69 | # define _GL_INT_NEGATE_OVERFLOW(a) \
70 | _GL_INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))
71 |
72 | #define _GL_INT_ADD_RANGE_OVERFLOW(a, b, tmin, tmax) \
73 | ((b) < 0 \
74 | ? (((tmin) \
75 | ? ((_GL_EXPR_SIGNED (_GL_INT_CONVERT (a, (tmin) - (b))) || (b) < (tmin)) \
76 | && (a) < (tmin) - (b)) \
77 | : (a) <= -1 - (b)) \
78 | || ((_GL_EXPR_SIGNED (a) ? 0 <= (a) : (tmax) < (a)) && (tmax) < (a) + (b))) \
79 | : (a) < 0 \
80 | ? (((tmin) \
81 | ? ((_GL_EXPR_SIGNED (_GL_INT_CONVERT (b, (tmin) - (a))) || (a) < (tmin)) \
82 | && (b) < (tmin) - (a)) \
83 | : (b) <= -1 - (a)) \
84 | || ((_GL_EXPR_SIGNED (_GL_INT_CONVERT (a, b)) || (tmax) < (b)) \
85 | && (tmax) < (a) + (b))) \
86 | : (tmax) < (b) || (tmax) - (b) < (a))
87 | #define _GL_INT_SUBTRACT_RANGE_OVERFLOW(a, b, tmin, tmax) \
88 | (((a) < 0) == ((b) < 0) \
89 | ? ((a) < (b) \
90 | ? !(tmin) || -1 - (tmin) < (b) - (a) - 1 \
91 | : (tmax) < (a) - (b)) \
92 | : (a) < 0 \
93 | ? ((!_GL_EXPR_SIGNED (_GL_INT_CONVERT ((a) - (tmin), b)) && (a) - (tmin) < 0) \
94 | || (a) - (tmin) < (b)) \
95 | : ((! (_GL_EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \
96 | && _GL_EXPR_SIGNED (_GL_INT_CONVERT ((tmax) + (b), a))) \
97 | && (tmax) <= -1 - (b)) \
98 | || (tmax) + (b) < (a)))
99 | #define _GL_INT_MULTIPLY_RANGE_OVERFLOW(a, b, tmin, tmax) \
100 | ((b) < 0 \
101 | ? ((a) < 0 \
102 | ? (_GL_EXPR_SIGNED (_GL_INT_CONVERT (tmax, b)) \
103 | ? (a) < (tmax) / (b) \
104 | : ((_GL_INT_NEGATE_OVERFLOW (b) \
105 | ? _GL_INT_CONVERT (b, tmax) >> (_GL_TYPE_WIDTH (+ (b)) - 1) \
106 | : (tmax) / -(b)) \
107 | <= -1 - (a))) \
108 | : _GL_INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (b, tmin)) && (b) == -1 \
109 | ? (_GL_EXPR_SIGNED (a) \
110 | ? 0 < (a) + (tmin) \
111 | : 0 < (a) && -1 - (tmin) < (a) - 1) \
112 | : (tmin) / (b) < (a)) \
113 | : (b) == 0 \
114 | ? 0 \
115 | : ((a) < 0 \
116 | ? (_GL_INT_NEGATE_OVERFLOW (_GL_INT_CONVERT (a, tmin)) && (a) == -1 \
117 | ? (_GL_EXPR_SIGNED (b) ? 0 < (b) + (tmin) : -1 - (tmin) < (b) - 1) \
118 | : (tmin) / (a) < (b)) \
119 | : (tmax) / (b) < (a)))
120 |
121 | #define _GL_INT_OP_WRAPV(a, b, r, op, overflow) \
122 | (_Generic \
123 | (*(r), \
124 | signed char: \
125 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
126 | signed char, SCHAR_MIN, SCHAR_MAX), \
127 | unsigned char: \
128 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
129 | unsigned char, 0, UCHAR_MAX), \
130 | short int: \
131 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
132 | short int, SHRT_MIN, SHRT_MAX), \
133 | unsigned short int: \
134 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
135 | unsigned short int, 0, USHRT_MAX), \
136 | int: \
137 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
138 | int, INT_MIN, INT_MAX), \
139 | unsigned int: \
140 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
141 | unsigned int, 0, UINT_MAX), \
142 | long int: \
143 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
144 | long int, LONG_MIN, LONG_MAX), \
145 | unsigned long int: \
146 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
147 | unsigned long int, 0, ULONG_MAX), \
148 | long long int: \
149 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
150 | long long int, LLONG_MIN, LLONG_MAX), \
151 | unsigned long long int: \
152 | _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
153 | unsigned long long int, 0, ULLONG_MAX)))
154 |
155 | #define _GL_INT_ADD_WRAPV(a, b, r) \
156 | _GL_INT_OP_WRAPV (a, b, r, +, _GL_INT_ADD_RANGE_OVERFLOW)
157 | #define _GL_INT_SUBTRACT_WRAPV(a, b, r) \
158 | _GL_INT_OP_WRAPV (a, b, r, -, _GL_INT_SUBTRACT_RANGE_OVERFLOW)
159 | #define _GL_INT_MULTIPLY_WRAPV(a, b, r) \
160 | _GL_INT_OP_WRAPV (a, b, r, *, _GL_INT_MULTIPLY_RANGE_OVERFLOW)
161 |
162 | #define IntAddWrapv(a, b, r) _GL_INT_ADD_WRAPV (a, b, r)
163 | #define IntSubtractWrapv(a, b, r) _GL_INT_SUBTRACT_WRAPV (a, b, r)
164 | #define IntMultiplyWrapv(a, b, r) _GL_INT_MULTIPLY_WRAPV (a, b, r)
165 |
166 | #endif
167 |
168 | #ifndef Popcount
169 | #define NeedPortPopcount
170 |
171 | extern int PortPopcount (unsigned long long int);
172 |
173 | #define Popcount(number) (PortPopcount (number))
174 |
175 | #endif
176 |
--------------------------------------------------------------------------------