File wlrctl-0.2.2~0.obscpio of Package wlrctl

07070100000000000081A400000000000000000000000164632F350000001C000000000000000000000000000000000000001A00000000wlrctl-0.2.2~0/.gitignorebuild
compile_commands.json
07070100000001000081A400000000000000000000000164632F350000042D000000000000000000000000000000000000001700000000wlrctl-0.2.2~0/LICENSEMIT License

Copyright (c) 2020 Ronan Pigott

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
07070100000002000081A400000000000000000000000164632F35000005D9000000000000000000000000000000000000001900000000wlrctl-0.2.2~0/README.md# wlrctl

wlrctl is a command line utility for miscellaneous wlroots Wayland extensions.

At this time, wlrctl supports the foreign-toplevel-mangement (window/toplevel command),
virtual-keyboard (keyboard command), and virtual-pointer (pointer command) protocols.

Requires wlroots 0.13+

## Installation

There is an AUR package for wlrctl [here][aur-wlrctl].
And an openSUSE package [here][os-wlrctl].

Otherwise, build with meson/ninja e.g.

    $ meson setup --prefix=/usr/local build
	$ ninja -C build install

## Features and Examples

wlrctl is still experimental, and has just a few basic features.
Check the man page wlrctl(1) for full details.

Some example uses are:

    $ wlrctl keyboard type 'Hello, world!'

... to type some text using a virtual keyboard.

    $ wlrctl pointer move 50 -70

... to move the cursor 50 pixels right and 70 pixels up.

    $ wlrctl window focus firefox || swaymsg exec firefox

... to focus firefox if it is running, otherwise start firefox.

    $ wlrctl toplevel waitfor mpv state:fullscreen && makoctl dismiss

... to dismiss desktop notifications when mpv becomes fullscreen


## Contributing

You can send patches to the [mailing list][list-wlrctl] or submit an issue on the
[issue tracker][todo-wlrctl].

[aur-wlrctl]: https://aur.archlinux.org/packages/wlrctl
[os-wlrctl]: https://build.opensuse.org/package/show/X11:Wayland/wlrctl
[todo-wlrctl]: https://todo.sr.ht/~brocellous/wlrctl
[list-wlrctl]: https://lists.sr.ht/~brocellous/public-inbox
07070100000003000081A400000000000000000000000164632F35000016AD000000000000000000000000000000000000002200000000wlrctl-0.2.2~0/ascii_raw_keymap.cconst char keymap_ascii_raw[] =
"xkb_keymap {\n"
"xkb_keycodes \"ascii\" {\n"
"	minimum = 8;\n"
"	maximum = 127;\n"
"\n"
"	<BKSP> = 8;\n"
"	<TAB>  = 9;\n"
"	<RTRN> = 10;\n"
"	<ESC>  = 27;\n"
"	<SPCE> = 32;\n"
"	<EXCL> = 33;\n"
"	<QDBL> = 34;\n"
"	<HASH> = 35;\n"
"	<DOLL> = 36;\n"
"	<PCNT> = 37;\n"
"	<AMP>  = 38;\n"
"	<APOS> = 39;\n"
"	<LPAR> = 40;\n"
"	<RPAR> = 41;\n"
"	<STAR> = 42;\n"
"	<PLUS> = 43;\n"
"	<COMM> = 44;\n"
"	<MIN>  = 45;\n"
"	<PRD>  = 46;\n"
"	<FWSL> = 47;\n"
"	<NUM0> = 48;\n"
"	<NUM1> = 49;\n"
"	<NUM2> = 50;\n"
"	<NUM3> = 51;\n"
"	<NUM4> = 52;\n"
"	<NUM5> = 53;\n"
"	<NUM6> = 54;\n"
"	<NUM7> = 55;\n"
"	<NUM8> = 56;\n"
"	<NUM9> = 57;\n"
"	<COLN> = 58;\n"
"	<SCLN> = 59;\n"
"	<LESS> = 60;\n"
"	<EQL>  = 61;\n"
"	<GRTR> = 62;\n"
"	<QUES> = 63;\n"
"	<ATSN> = 64;\n"
"	<KEYA> = 65;\n"
"	<KEYB> = 66;\n"
"	<KEYC> = 67;\n"
"	<KEYD> = 68;\n"
"	<KEYE> = 69;\n"
"	<KEYF> = 70;\n"
"	<KEYG> = 71;\n"
"	<KEYH> = 72;\n"
"	<KEYI> = 73;\n"
"	<KEYJ> = 74;\n"
"	<KEYK> = 75;\n"
"	<KEYL> = 76;\n"
"	<KEYM> = 77;\n"
"	<KEYN> = 78;\n"
"	<KEYO> = 79;\n"
"	<KEYP> = 80;\n"
"	<KEYQ> = 81;\n"
"	<KEYR> = 82;\n"
"	<KEYS> = 83;\n"
"	<KEYT> = 84;\n"
"	<KEYU> = 85;\n"
"	<KEYV> = 86;\n"
"	<KEYW> = 87;\n"
"	<KEYX> = 88;\n"
"	<KEYY> = 89;\n"
"	<KEYZ> = 90;\n"
"	<LBRA> = 91;\n"
"	<BKSL> = 92;\n"
"	<RBRA> = 93;\n"
"	<CRCM> = 94;\n"
"	<UNDR> = 95;\n"
"	<GRV>  = 96;\n"
"	<KEYa> = 97;\n"
"	<KEYb> = 98;\n"
"	<KEYc> = 99;\n"
"	<KEYd> = 100;\n"
"	<KEYe> = 101;\n"
"	<KEYf> = 102;\n"
"	<KEYg> = 103;\n"
"	<KEYh> = 104;\n"
"	<KEYi> = 105;\n"
"	<KEYj> = 106;\n"
"	<KEYk> = 107;\n"
"	<KEYl> = 108;\n"
"	<KEYm> = 109;\n"
"	<KEYn> = 110;\n"
"	<KEYo> = 111;\n"
"	<KEYp> = 112;\n"
"	<KEYq> = 113;\n"
"	<KEYr> = 114;\n"
"	<KEYs> = 115;\n"
"	<KEYt> = 116;\n"
"	<KEYu> = 117;\n"
"	<KEYv> = 118;\n"
"	<KEYw> = 119;\n"
"	<KEYx> = 120;\n"
"	<KEYy> = 121;\n"
"	<KEYz> = 122;\n"
"	<LBRC> = 123;\n"
"	<BAR>  = 124;\n"
"	<RBRC> = 125;\n"
"	<TLDE> = 126;\n"
"};\n"
"\n"
"xkb_types \"flat\" {\n"
"	virtual_modifiers NumLock;\n"
"\n"
"	type \"ONE_LEVEL\" {\n"
"		modifiers =none;\n"
"		level_name[1] = \"Any\";\n"
"	};\n"
"	type \"TWO_LEVEL\" {\n"
"		modifiers = Shift;\n"
"		map[Shift] = Level2;\n"
"		level_name[Level1] = \"Base\";\n"
"		level_name[Level2] = \"Shift\";\n"
"	};\n"
"	type \"ALPHABETIC\" {\n"
"		modifiers = Shift+Lock;\n"
"		map[Shift] = Level2;\n"
"		map[Lock] = Level2;\n"
"		level_name[Level1] = \"Base\";\n"
"		level_name[Level2] = \"Caps\";\n"
"	};\n"
"	type \"KEYPAD\" {\n"
"		modifiers = Shift+NumLock;\n"
"		map[None] = Level1;\n"
"		map[Shift] = Level2;\n"
"		map[NumLock] = Level2;\n"
"		map[Shift+NumLock] = Level1;\n"
"		level_name[Level1] = \"Base\";\n"
"		level_name[Level2] = \"Number\";\n"
"	};\n"
"};\n"
"\n"
"xkb_compatibility \"basic\" {\n"
"    virtual_modifiers NumLock;\n"
"\n"
"    interpret.useModMapMods = AnyLevel;\n"
"    interpret.repeat = False;\n"
"    interpret.locking = False;\n"
"    interpret Shift_Lock+AnyOf(Shift+Lock) {\n"
"        action = LockMods(modifiers=Shift);\n"
"    };\n"
"};\n"
"\n"
"xkb_symbols \"ascii\" {\n"
"	name[Group1]=\"ASCII RAW\";\n"
"\n"
"	key <BKSP> {[ BackSpace ]};\n"
"	key <TAB>  {[ Tab ]};\n"
"	key <RTRN> {[ Return ]};\n"
"	key <ESC>  {[ Escape ]};\n"
"	key <SPCE> {[ space ]};\n"
"	key <EXCL> {[ exclam ]};\n"
"	key <QDBL> {[ quotedbl ]};\n"
"	key <HASH> {[ numbersign ]};\n"
"	key <DOLL> {[ dollar ]};\n"
"	key <PCNT> {[ percent ]};\n"
"	key <AMP>  {[ ampersand ]};\n"
"	key <APOS> {[ apostrophe ]};\n"
"	key <LPAR> {[ parenleft ]};\n"
"	key <RPAR> {[ parenright ]};\n"
"	key <STAR> {[ asterisk ]};\n"
"	key <PLUS> {[ plus ]};\n"
"	key <COMM> {[ comma ]};\n"
"	key <MIN>  {[ minus ]};\n"
"	key <PRD>  {[ period ]};\n"
"	key <FWSL> {[ slash ]};\n"
"	key <NUM0> {[ 0 ]};\n"
"	key <NUM1> {[ 1 ]};\n"
"	key <NUM2> {[ 2 ]};\n"
"	key <NUM3> {[ 3 ]};\n"
"	key <NUM4> {[ 4 ]};\n"
"	key <NUM5> {[ 5 ]};\n"
"	key <NUM6> {[ 6 ]};\n"
"	key <NUM7> {[ 7 ]};\n"
"	key <NUM8> {[ 8 ]};\n"
"	key <NUM9> {[ 9 ]};\n"
"	key <COLN> {[ colon ]};\n"
"	key <SCLN> {[ semicolon ]};\n"
"	key <LESS> {[ less ]};\n"
"	key <EQL>  {[ equal ]};\n"
"	key <GRTR> {[ greater ]};\n"
"	key <QUES> {[ question ]};\n"
"	key <ATSN> {[ at ]};\n"
"	key <KEYA> {[ A ]};\n"
"	key <KEYB> {[ B ]};\n"
"	key <KEYC> {[ C ]};\n"
"	key <KEYD> {[ D ]};\n"
"	key <KEYE> {[ E ]};\n"
"	key <KEYF> {[ F ]};\n"
"	key <KEYG> {[ G ]};\n"
"	key <KEYH> {[ H ]};\n"
"	key <KEYI> {[ I ]};\n"
"	key <KEYJ> {[ J ]};\n"
"	key <KEYK> {[ K ]};\n"
"	key <KEYL> {[ L ]};\n"
"	key <KEYM> {[ M ]};\n"
"	key <KEYN> {[ N ]};\n"
"	key <KEYO> {[ O ]};\n"
"	key <KEYP> {[ P ]};\n"
"	key <KEYQ> {[ Q ]};\n"
"	key <KEYR> {[ R ]};\n"
"	key <KEYS> {[ S ]};\n"
"	key <KEYT> {[ T ]};\n"
"	key <KEYU> {[ U ]};\n"
"	key <KEYV> {[ V ]};\n"
"	key <KEYW> {[ W ]};\n"
"	key <KEYX> {[ X ]};\n"
"	key <KEYY> {[ Y ]};\n"
"	key <KEYZ> {[ Z ]};\n"
"	key <LBRA> {[ bracketleft ]};\n"
"	key <BKSL> {[ backslash ]};\n"
"	key <RBRA> {[ bracketright ]};\n"
"	key <CRCM> {[ asciicircum ]};\n"
"	key <UNDR> {[ underscore ]};\n"
"	key <GRV>  {[ grave ]};\n"
"	key <KEYa> {[ a ]};\n"
"	key <KEYb> {[ b ]};\n"
"	key <KEYc> {[ c ]};\n"
"	key <KEYd> {[ d ]};\n"
"	key <KEYe> {[ e ]};\n"
"	key <KEYf> {[ f ]};\n"
"	key <KEYg> {[ g ]};\n"
"	key <KEYh> {[ h ]};\n"
"	key <KEYi> {[ i ]};\n"
"	key <KEYj> {[ j ]};\n"
"	key <KEYk> {[ k ]};\n"
"	key <KEYl> {[ l ]};\n"
"	key <KEYm> {[ m ]};\n"
"	key <KEYn> {[ n ]};\n"
"	key <KEYo> {[ o ]};\n"
"	key <KEYp> {[ p ]};\n"
"	key <KEYq> {[ q ]};\n"
"	key <KEYr> {[ r ]};\n"
"	key <KEYs> {[ s ]};\n"
"	key <KEYt> {[ t ]};\n"
"	key <KEYu> {[ u ]};\n"
"	key <KEYv> {[ v ]};\n"
"	key <KEYw> {[ w ]};\n"
"	key <KEYx> {[ x ]};\n"
"	key <KEYy> {[ y ]};\n"
"	key <KEYz> {[ z ]};\n"
"	key <LBRC> {[ braceleft ]};\n"
"	key <BAR>  {[ bar ]};\n"
"	key <RBRC> {[ braceright ]};\n"
"	key <TLDE> {[ asciitilde ]};\n"
"};\n"
"};\n";
07070100000004000041ED00000000000000000000000164632F3500000000000000000000000000000000000000000000001B00000000wlrctl-0.2.2~0/completions07070100000005000041ED00000000000000000000000164632F3500000000000000000000000000000000000000000000001F00000000wlrctl-0.2.2~0/completions/zsh07070100000006000081A400000000000000000000000164632F350000070D000000000000000000000000000000000000002700000000wlrctl-0.2.2~0/completions/zsh/_wlrctl#compdef wlrctl

local cmd="$0"
typeset -A opt_args
__wlrctl() {
	"$cmd" "$@"
}

local -a wlrcmd_keyboard
_regex_words action 'keyboard action' \
	'type:Type an ascii string'
wlrcmd_keyboard=("$reply[@]")

local -a pointer_button
_regex_words button 'pointer button' 'left' 'right' 'middle' \
	'extra' 'side' 'forward' 'back'
pointer_button=("$reply[@]")

local -a wlrcmd_pointer
_regex_words action 'pointer action' \
	'click:Click a pointer button:$pointer_button' \
	'move:Move the cursor' \
	'scroll:Imitate a swipe scroll'
wlrcmd_pointer=("$reply[@]")

(( $+functions[_wlr_toplevel_attr] )) || _wlr_toplevel_attr() {
	local -a windows matchspecs
	windows=(${(@f)"$(__wlrctl toplevel list)"})
	matchspecs=( app_id:${^windows%%: *} title:${^windows#*: } )
	matchspecs+=( state:{{un,}minimized,{un,}maximized,{in,}active,{un,}fullscreen} )
	_multi_parts ':' matchspecs
}
local -a wlrcmd_toplevel_attr=(/$'[^\0]#\0'/ ':_wlr_toplevel_attr' '#')

local -a wlrcmd_toplevel
_regex_words action 'toplevel action' 'maximize' 'minimize' 'focus' \
	'activate' 'fullscreen' 'close' 'list' 'find' 'wait' 'waitfor'
wlrcmd_toplevel=( "$reply[@]" "$wlrcmd_toplevel_attr[@]" )

local -a wlrcmd_output
_regex_words action 'output action' \
	'list:List the avaialble output names'
wlrcmd_output=("$reply[@]")

local -a wlrcmd
_regex_words commands 'wlr command' \
	'keyboard:Control a virtual keyboard:$wlrcmd_keyboard' \
	'pointer:Control a virtual pointer:$wlrcmd_pointer' \
	{window,toplevel}':Manage windows:$wlrcmd_toplevel' \
	'output:Manage outputs:$wlrcmd_output'
wlrcmd=( /$'[^\0]#\0'/ "$reply[@]" )
_regex_arguments _wlrcmd "$wlrcmd[@]"

_arguments -S \
	'(-h --help)'{-h,--help}'[Show a help message and exit]' \
	'(-v --version)'{-v,--version}'[Show a version number and exit]' \
	'*::wlr command:= _wlrcmd'
07070100000007000041ED00000000000000000000000164632F3500000000000000000000000000000000000000000000001700000000wlrctl-0.2.2~0/include07070100000008000081A400000000000000000000000164632F350000026C000000000000000000000000000000000000002000000000wlrctl-0.2.2~0/include/common.h#ifndef WLRCTL_COMMON_H
#define WLRCTL_COMMON_H

#include <stdbool.h>

enum wlrctl_command {
	WLRCTL_COMMAND_UNSPEC = 0,
	WLRCTL_COMMAND_KEYBOARD,
	WLRCTL_COMMAND_POINTER,
	WLRCTL_COMMAND_TOPLEVEL,
	WLRCTL_COMMAND_OUTPUT,
};

struct wlrctl {
	// Globals
	struct wl_display *display;
	struct wl_registry *registry;
	struct wl_seat *seat;
	struct zwp_virtual_keyboard_manager_v1 *vkbd_mgr;
	struct zwlr_foreign_toplevel_manager_v1 *ftl_mgr;
	struct zwlr_virtual_pointer_manager_v1 *vp_mgr;
	struct zwlr_output_manager_v1 *output_mgr;

	// State
	bool running, failed;
	enum wlrctl_command cmd_type;
	void *cmd;
};

#endif
07070100000009000081A400000000000000000000000164632F350000023A000000000000000000000000000000000000002200000000wlrctl-0.2.2~0/include/keyboard.h#ifndef WLRCTL_DEV_KEYBOARD_H
#define WLRCTL_DEV_KEYBOARD_H

enum keyboard_action {
	KEYBOARD_ACTION_UNSPEC = 0,
	KEYBOARD_ACTION_TYPE,
};

struct wlrctl_keyboard_command {
	enum keyboard_action action;
	char *text;
	int mods_depressed;

	struct zwp_virtual_keyboard_v1 *device;
	struct xkb_context *xkb_context;
	struct {
		uint32_t format;
		uint32_t size;
		int fd;
	} keymap;
	struct wlrctl *state;
};

void prepare_keyboard(struct wlrctl *state, int argc, char *argv[]);
void run_keyboard(struct wlrctl *state);
void destroy_keyboard(struct wlrctl *state);

#endif
0707010000000A000081A400000000000000000000000164632F35000004E6000000000000000000000000000000000000002000000000wlrctl-0.2.2~0/include/output.h#ifndef WLRCTL_OUTPUT_H
#define WLRCTL_OUTPUT_H

enum output_action {
	OUTPUT_ACTION_LIST = 1,

	OUTPUT_ACTION_CONFIGURE,
	OUTPUT_ACTION_UNSPEC
};

enum output_cfg_action {
	OUTPUT_CFG_ACTION_SHOW = 1,
	OUTPUT_CFG_ACTION_SET_MODE,
	OUTPUT_CFG_ACTION_SET_CUSTOM_MODE,
	OUTPUT_CFG_ACTION_SET_POSITION,
	OUTPUT_CFG_ACTION_SET_TRANSFORM,
	OUTPUT_CFG_ACTION_SET_SCALE,

	OUTPUT_CFG_ACTION_UNSPEC
};

struct wlrctl_output_command {
	enum output_action action;
	char *ident;
	enum output_cfg_action cfg_action;
	struct wl_list heads;
	struct wlrctl *state;
};

struct head_data {
	char name[24];
	char model[16];
	char make[56];
	char serial[16];
	char *description;
	int32_t x, y, width, height;
	struct wl_list modes;
	bool enabled;
	struct mode_data *current_mode;
	enum wl_output_transform transform;
	double scale;
	struct wl_list link;
	struct wlrctl_output_command *cmd;
};

struct mode_data {
	int32_t width, height;
	int32_t refresh;
	bool preferred;
	struct head_data *head;
	struct wl_list link; //head_data::modes
	struct zwlr_output_mode_v1 *mode;
};

void prepare_output(struct wlrctl *state, int argc, char **argv);
void run_output(struct wlrctl *state);
void stop_output(struct wlrctl *state);
void destroy_output(struct wlrctl *state);

#endif
0707010000000B000081A400000000000000000000000164632F3500000200000000000000000000000000000000000000002100000000wlrctl-0.2.2~0/include/pointer.h#ifndef WLRCTL_DEV_POINTER_H
#define WLRCTL_DEV_POINTER_H

enum pointer_action {
	POINTER_ACTION_UNSPEC = 0,
	POINTER_ACTION_CLICK,
	POINTER_ACTION_MOTION,
	POINTER_ACTION_SCROLL,
};

struct wlrctl_pointer_command {
	enum pointer_action action;
	uint32_t button;
	wl_fixed_t dx, dy;

	struct zwlr_virtual_pointer_v1 *device;
	struct wlrctl *state;
};

void prepare_pointer(struct wlrctl *state, int argc, char *argv[]);
void run_pointer(struct wlrctl *state);
void destroy_pointer(struct wlrctl *state);

#endif
0707010000000C000081A400000000000000000000000164632F350000058B000000000000000000000000000000000000002200000000wlrctl-0.2.2~0/include/toplevel.h#ifndef WLRCTL_TOPLEVEL_H
#define WLRCTL_TOPLEVEL_H

enum toplevel_attr {
	TOPLEVEL_ATTR_UNSPEC     = 0,
	TOPLEVEL_ATTR_APPID      = 1<<1,
	TOPLEVEL_ATTR_TITLE      = 1<<2,
	TOPLEVEL_ATTR_MAXIMIZED  = 1<<3,
	TOPLEVEL_ATTR_MINIMIZED  = 1<<4,
	TOPLEVEL_ATTR_ACTIVATED  = 1<<5,
	TOPLEVEL_ATTR_FULLSCREEN = 1<<6,
};

enum toplevel_action {
	TOPLEVEL_ACTION_UNSPEC = 0,
	TOPLEVEL_ACTION_ACTIVATE,
	TOPLEVEL_ACTION_CLOSE,
	TOPLEVEL_ACTION_FIND,
	TOPLEVEL_ACTION_FULLSCREEN,
	TOPLEVEL_ACTION_LIST,
	TOPLEVEL_ACTION_MAXIMIZE,
	TOPLEVEL_ACTION_MINIMIZE,
	TOPLEVEL_ACTION_WAIT,
	TOPLEVEL_ACTION_WAITFOR,
};

struct toplevel_matchspec {
	unsigned int attrs;
	// toplevel attr
	struct wl_array app_ids;
	struct wl_array titles;
	// toplevel state
	bool maximized;
	bool minimized;
	bool activated;
	bool fullscreen;
};

struct wlrctl_toplevel_command {
	enum toplevel_action action;
	struct toplevel_matchspec matchspec;
	struct wl_list toplevels;
	bool any;
	bool complete;
	int waiting;
	struct wlrctl *state;
};


struct toplevel_data {
	char *app_id;
	char *title;
	struct wl_array state;
	struct zwlr_foreign_toplevel_handle_v1 *parent;
	struct wl_list link;
	struct wlrctl_toplevel_command *cmd;
	bool matched, done;
};

void prepare_toplevel(struct wlrctl *state, int argc, char **argv);
void run_toplevel(struct wlrctl *state);
void stop_toplevel(struct wlrctl *state);
void destroy_toplevel(struct wlrctl *state);

#endif
0707010000000D000081A400000000000000000000000164632F35000000D8000000000000000000000000000000000000001E00000000wlrctl-0.2.2~0/include/util.h#ifndef WLRCTL_UTIL_H
#define WLRCTL_UTIL_H

struct token {
	const char *name;
	int value;
};


int matchtok(const struct token tokens[], const char *name);

int timestamp();

void die(const char *fmt, ...);

#endif
0707010000000E000081A400000000000000000000000164632F35000012A5000000000000000000000000000000000000001A00000000wlrctl-0.2.2~0/keyboard.c#define _GNU_SOURCE
#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <wayland-client.h>
#include <xkbcommon/xkbcommon.h>
#include "common.h"
#include "keyboard.h"
#include "util.h"

#include "virtual-keyboard-unstable-v1-client-protocol.h"

extern const char keymap_ascii_raw[];

static void
get_keymap(struct wlrctl_keyboard_command *cmd)
{
	int size = strlen(keymap_ascii_raw) + 1;
#if defined(MEMFD_CREATE)
	int fd = memfd_create("keymap", 0);
#elif defined(__FreeBSD__)
	// memfd_create on FreeBSD 13 is SHM_ANON without sealing support
	int fd = shm_open(SHM_ANON, O_RDWR, 0600);
#else
	char name[] = "/tmp/keymap-XXXXXX";
	int fd = mkstemp(name);
	unlink(name);
#endif
	if(ftruncate(fd, size) < 0) {
		die("Could not allocate shm for keymap\n");
	};

	void *keymap_data =
		mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
	strcpy(keymap_data, keymap_ascii_raw);
	munmap(keymap_data, size);

	cmd->keymap.format = WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1;
	cmd->keymap.fd = fd;
	cmd->keymap.size = size;
}

static void
send_key(struct zwp_virtual_keyboard_v1 *kbd, char c)
{
	zwp_virtual_keyboard_v1_key(kbd, timestamp(), c - 8, WL_KEYBOARD_KEY_STATE_PRESSED);
	zwp_virtual_keyboard_v1_key(kbd, timestamp(), c - 8, WL_KEYBOARD_KEY_STATE_RELEASED);
}

static void
keyboard_type(struct wlrctl_keyboard_command *cmd, const char *text)
{
	int len = strlen(text);
	for (int i = 0; i < len; i++) {
		send_key(cmd->device, text[i]);
	}
}

static void
complete_keyboard(void *data, struct wl_callback *callback, uint32_t serial)
{
	struct wlrctl *state = data;
	wl_callback_destroy(callback);
	state->running = false;
	destroy_keyboard(state);
}

static struct wl_callback_listener completed_listener = {
	.done = complete_keyboard
};

static enum keyboard_action
parse_action(const char *action)
{
	static const struct token actions[] = {
		{"type", KEYBOARD_ACTION_TYPE},
		{NULL, KEYBOARD_ACTION_UNSPEC}
	};
	return matchtok(actions, action);
}

static bool
is_ascii(const char str[])
{
	for (int i = 0; str[i] != '\0'; i++) {
		if (str[i] < 0) {
			return false;
		}
	}
	return true;
}

void
prepare_keyboard(struct wlrctl *state, int argc, char *argv[])
{
	struct wlrctl_keyboard_command *cmd =
		calloc(1, sizeof (struct wlrctl_keyboard_command));
	assert(cmd);

	if (argc == 0) {
		die("Missing keyboard action\n");
	}

	char *action = argv[0];
	cmd->action = parse_action(action);

	switch (cmd->action) {
	case KEYBOARD_ACTION_TYPE:
		if (argc < 2) {
			die("Missing text to type!\n");
		}
		if (is_ascii(argv[1])) {
			cmd->mods_depressed = 0;
			cmd->text = strdup(argv[1]);
		} else {
			die("Only ascii strings are currently supported\n");
		}
		if (argc >= 3 && strcmp(argv[2], "modifiers")) {
			die("Invalid argument: '%s'\n", argv[2]);
		} else if (argc == 3) {
			die("No modifiers provided\n");
		} else if (argc == 4) {
			char *keys = (char *)malloc(strlen(argv[3]) + 1);
			strcpy(keys, argv[3]);
			char *key;
			key = strtok(keys, ",");
			while (key != NULL) {
				for (size_t i = 0; i < strlen(key); i++) {
					key[i] = toupper((unsigned char) key[i]);
				}
				if (strcmp(key, "SHIFT") == 0) {
					cmd->mods_depressed |= 1;
				} else if (strcmp(key, "CTRL") == 0) {
					cmd->mods_depressed |= 4;
				} else if (strcmp(key, "ALT") == 0) {
					cmd->mods_depressed |= 8;
				} else if (strcmp(key, "SUPER") == 0) {
					cmd->mods_depressed |= 64;
				} else {
					die("Unsupported modifier: '%s'\n", key);
				}
				key = strtok(NULL, ",");
			}
			free(keys);
		} else if (argc >= 5) {
			die("Invalid argument: '%s'\n", argv[4]);
		}
		break;
	case KEYBOARD_ACTION_UNSPEC:
		die("Unknown keyboard action: '%s'\n", action);
		break;
	}

	cmd->state = state;
	state->cmd = cmd;
}

void
run_keyboard(struct wlrctl *state)
{
	struct wlrctl_keyboard_command *cmd = state->cmd;

	cmd->device =
	zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(
		state->vkbd_mgr, state->seat
	);

	cmd->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
	get_keymap(cmd);

	zwp_virtual_keyboard_v1_keymap(cmd->device,
		cmd->keymap.format, cmd->keymap.fd, cmd->keymap.size
	);
	close(cmd->keymap.fd);

	switch (cmd->action) {
	case KEYBOARD_ACTION_TYPE:
		zwp_virtual_keyboard_v1_modifiers(cmd->device, cmd->mods_depressed, 0, 0, 0);
		keyboard_type(cmd, cmd->text);
		break;
	default:
		break;
	}

	struct wl_callback *callback = wl_display_sync(state->display);
	wl_callback_add_listener(callback, &completed_listener, state);
}

void destroy_keyboard(struct wlrctl *state)
{
	struct wlrctl_keyboard_command *cmd = state->cmd;
	zwp_virtual_keyboard_v1_destroy(cmd->device);
	free(cmd);
}
0707010000000F000081A400000000000000000000000164632F35000014FE000000000000000000000000000000000000001600000000wlrctl-0.2.2~0/main.c#include <assert.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <xkbcommon/xkbcommon.h>
#include <wayland-client.h>
#include "common.h"
#include "keyboard.h"
#include "pointer.h"
#include "toplevel.h"
#include "output.h"
#include "util.h"

#include "virtual-keyboard-unstable-v1-client-protocol.h"
#include "wlr-virtual-pointer-unstable-v1-client-protocol.h"
#include "wlr-foreign-toplevel-management-unstable-v1-client-protocol.h"
#include "wlr-output-management-unstable-v1-client-protocol.h"

static void noop() {}

static void
registry_handle_global(void *data, struct wl_registry *registry,
		uint32_t name, const char *interface, uint32_t version)
{
	struct wlrctl *state = data;

	// Bind wl_seat
	if (strcmp(interface, wl_seat_interface.name) == 0) {
		state->seat = wl_registry_bind(
			registry, name, &wl_seat_interface, 7
		);
	}

	// Bind zwp_virtual_keyboard_manager_v1
	if (strcmp(interface, zwp_virtual_keyboard_manager_v1_interface.name) == 0) {
		if (state->cmd_type == WLRCTL_COMMAND_KEYBOARD) {
			state->vkbd_mgr = wl_registry_bind(
				registry, name, &zwp_virtual_keyboard_manager_v1_interface, 1
			);
		}
	}
	
	// Bind zwlr_virtual_pointer_manager_v1
	if (strcmp(interface, zwlr_virtual_pointer_manager_v1_interface.name) == 0) {
		if (state->cmd_type == WLRCTL_COMMAND_POINTER) {
			state->vp_mgr = wl_registry_bind(
				registry, name, &zwlr_virtual_pointer_manager_v1_interface, 2
			);
		}
	}

	// Bind zwlr_foreign_toplevel_manager_v1
	if (strcmp(interface, zwlr_foreign_toplevel_manager_v1_interface.name) == 0) {
		if (state->cmd_type == WLRCTL_COMMAND_TOPLEVEL) {
			state->ftl_mgr = wl_registry_bind(
				registry, name, &zwlr_foreign_toplevel_manager_v1_interface, 3
			);
		}
	}

	// Bind zwlr_output_manager_v1
	if (strcmp(interface, zwlr_output_manager_v1_interface.name) == 0) {
		if (state->cmd_type == WLRCTL_COMMAND_OUTPUT) {
			state->output_mgr = wl_registry_bind(
				registry, name, &zwlr_output_manager_v1_interface, 2
			);
		}
	}
}

static const struct wl_registry_listener
wl_registry_listener = {
	.global = registry_handle_global,
	.global_remove = noop,
};

static bool
prepare_command(struct wlrctl *state, int argc, char *argv[])
{
	char *command = argv[0];
	static const struct token commands[] = {
		{"keyboard", WLRCTL_COMMAND_KEYBOARD},
		{"pointer",  WLRCTL_COMMAND_POINTER },
		{"toplevel", WLRCTL_COMMAND_TOPLEVEL},
		{"window",   WLRCTL_COMMAND_TOPLEVEL},
		{"output",   WLRCTL_COMMAND_OUTPUT  },
		{NULL, WLRCTL_COMMAND_UNSPEC},
	};

	state->cmd_type = matchtok(commands, command);
	switch (state->cmd_type) {
	case WLRCTL_COMMAND_KEYBOARD:
		prepare_keyboard(state, argc - 1, argv + 1);
		break;
	case WLRCTL_COMMAND_POINTER:
		prepare_pointer(state, argc - 1, argv + 1);
		break;
	case WLRCTL_COMMAND_TOPLEVEL:
		prepare_toplevel(state, argc - 1, argv + 1);
		break;
	case WLRCTL_COMMAND_OUTPUT:
		prepare_output(state, argc - 1, argv + 1);
		break;
	case WLRCTL_COMMAND_UNSPEC:
		return false;
	}
	return true;
}

int
main(int argc, char *argv[])
{
	struct wlrctl state = {0};

	// Usage
	static struct option long_options[] = {
		{"help", no_argument, 0, 'h'},
		{"version", no_argument, 0, 'v'},
		{0, 0, 0, 0}
	};

	const char *usage = 
		"Usage: wlrctl [options] [keyboard|pointer|toplevel] <action>\n"
		"\n"
		"  -h, --help     Show a help message and quit\n"
		"  -v, --version  Show a version number and quit\n"
		;

	// Only allow options up front, so getopt doesn't
	// get mad about negative numbers
	int cmd_idx = 1;
	for ( ; cmd_idx < argc; cmd_idx++ ) {
		if (*argv[cmd_idx] != '-') {
			break;
		}
	}

	// Option args
	int c;
	while (true) {
		int optind = 0;
		c = getopt_long(cmd_idx, argv, "hv", long_options, &optind);
		if (c == -1) {
			break;
		}

		switch (c) {
		case 'h':
			puts(usage);
			return EXIT_SUCCESS;
		case 'v':
			printf("wlrctl v%s\n", WLRCTL_VERSION);
			return EXIT_SUCCESS;
		default:
			puts(usage);
			return EXIT_FAILURE;
		}
	}
	if (optind == argc) {
		puts(usage);
		return EXIT_FAILURE;
	}

	// Positional args
	if (!prepare_command(&state, argc - optind, argv + optind)) {
		fprintf(stderr, "Unknown command: '%s'\n", argv[optind]);
		puts(usage);
		return EXIT_FAILURE;
	}

	// Bind Globals
	state.running = true;
	state.display = wl_display_connect(NULL);
	assert(state.display);
	state.registry = wl_display_get_registry(state.display);
	wl_registry_add_listener(state.registry, &wl_registry_listener, &state);
	wl_display_roundtrip(state.display);

	switch (state.cmd_type) {
	case WLRCTL_COMMAND_KEYBOARD:
		if (!state.vkbd_mgr) {
			die("Virtual Keyboard interface not found!\n");
		}
		run_keyboard(&state);
		break;
	case WLRCTL_COMMAND_POINTER:
		if (!state.vp_mgr) {
			die("Virtual Pointer interface not found!\n");
		}
		run_pointer(&state);
		break;
	case WLRCTL_COMMAND_TOPLEVEL:
		if (!state.ftl_mgr) {
			die("Foreign Toplevel Management interface not found!\n");
		}
		run_toplevel(&state);
		break;
	case WLRCTL_COMMAND_OUTPUT:
		if (!state.output_mgr) {
			die("Output Management interface not found!\n");
		}
		run_output(&state);
		break;
	case WLRCTL_COMMAND_UNSPEC:
		// unreachable
		assert(false);
	}

	while (state.running) {
		if (wl_display_dispatch(state.display) < 0) {
			break;
		};
	}

	return state.failed ? EXIT_FAILURE : EXIT_SUCCESS;
}
07070100000010000081A400000000000000000000000164632F35000006C6000000000000000000000000000000000000001B00000000wlrctl-0.2.2~0/meson.buildproject(
	'wlrctl',
	'c',
	version: '0.2.2',
	license: 'MIT',
	default_options: [
		'c_std=c11',
		'warning_level=2',
		'werror=true',
	],
)

cc = meson.get_compiler('c')

datadir = get_option('datadir')
prefix = get_option('prefix')


add_project_arguments('-Wno-unused-parameter', language: 'c')
add_project_arguments('-Wno-missing-braces', language: 'c')

version = '"@0@"'.format(meson.project_version())
add_project_arguments('-DWLRCTL_VERSION=@0@'.format(version), language: 'c')

if cc.has_function('memfd_create')
  add_project_arguments('-DMEMFD_CREATE', language: 'c')
endif

xkbcommon = dependency('xkbcommon')
wayland_client = dependency('wayland-client')

subdir('protocol')

src_files = [
	'main.c',
	'ascii_raw_keymap.c',
	'keyboard.c',
	'pointer.c',
	'toplevel.c',
	'output.c',
	'util.c',
]

includes = include_directories('include')

executable(
	'wlrctl',
	files(src_files),
	dependencies: [
		client_protos,
		wayland_client,
		xkbcommon,
	],
	include_directories: [includes],
	install: true
)

scdoc = dependency('scdoc', native: true, required: get_option('man-pages'))
if scdoc.found()
	scdoc_cmd = find_program(scdoc.get_pkgconfig_variable('scdoc'), native: true)
	sh = find_program('sh', native: true)
	mandir = get_option('mandir')
	output = 'wlrctl.1'
	custom_target(
		output,
		input: 'wlrctl.1.scd',
		output: output,
		command: [sh, '-c', '@0@ < @INPUT@ > @1@'.format(scdoc_cmd.path(), output)],
		install: true,
		install_dir: '@0@/man1'.format(mandir)
	)
endif

if get_option('zsh-completions')
	zsh_completions = files('completions/zsh/_wlrctl')
	zsh_install_dir = join_paths(datadir, 'zsh', 'site-functions')
	install_data(zsh_completions, install_dir: zsh_install_dir)
endif


# vim: set ts=4 sw=4:
07070100000011000081A400000000000000000000000164632F35000000C3000000000000000000000000000000000000002100000000wlrctl-0.2.2~0/meson_options.txtoption('zsh-completions', type: 'boolean', value: true, description: 'Install zsh shell completions.')
option('man-pages', type: 'feature', value: 'auto', description: 'Install the manual page')
07070100000012000081A400000000000000000000000164632F35000028E4000000000000000000000000000000000000001800000000wlrctl-0.2.2~0/output.c#define _XOPEN_SOURCE 500
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wayland-client.h>
#include "common.h"
#include "output.h"
#include "util.h"
#include "wlr-output-management-unstable-v1-client-protocol.h"

static enum output_action
parse_action(const char *action)
{
	static const struct token actions[] = {
		{"list", OUTPUT_ACTION_LIST},
		{NULL, OUTPUT_ACTION_CONFIGURE}
	};
	return matchtok(actions, action);
}

static enum output_cfg_action
parse_cfg_action(const char *action)
{
	static const struct token actions[] = {
		{"show",            OUTPUT_CFG_ACTION_SHOW},
		{"set-mode",        OUTPUT_CFG_ACTION_SET_MODE},
		{"set-custom-mode", OUTPUT_CFG_ACTION_SET_CUSTOM_MODE},
		{"set-position",    OUTPUT_CFG_ACTION_SET_POSITION},
		{"set-transform",   OUTPUT_CFG_ACTION_SET_TRANSFORM},
		{"set-scale",       OUTPUT_CFG_ACTION_SET_SCALE},
		{NULL, OUTPUT_CFG_ACTION_UNSPEC}
	};

	return matchtok(actions, action);
}

static struct mode_data *
mode_data_create(struct head_data *head_data) {
	struct mode_data *mode_data = calloc(1, sizeof (struct mode_data));
	assert(mode_data);
	mode_data->head = head_data;
	wl_list_insert(&head_data->modes, &mode_data->link);
	return mode_data;
}

static void
mode_data_destroy(struct mode_data *mode_data) {
	free(mode_data);
}

static void
zwlr_output_mode_v1_handle_size(
	void *data,
	struct zwlr_output_mode_v1 *mode,
	int32_t width, int32_t height
	)
{
	struct mode_data *mode_data = data;
	mode_data->width = width;
	mode_data->height = height;
}

static void
zwlr_output_mode_v1_handle_refresh(
	void *data,
	struct zwlr_output_mode_v1 *mode,
	int32_t refresh
	)
{
	struct mode_data *mode_data = data;
	mode_data->refresh = refresh;
}

static void
zwlr_output_mode_v1_handle_preferred(
	void *data,
	struct zwlr_output_mode_v1 *mode
	)
{
	struct mode_data *mode_data = data;
	mode_data->preferred = true;
}

static void
zwlr_output_mode_v1_handle_finished(
	void *data,
	struct zwlr_output_mode_v1 *mode
	)
{
	struct mode_data *mode_data = data;
	struct mode_data *other, *tmp;
	wl_list_for_each_safe(other, tmp, &mode_data->head->modes, link) {
		if (other == mode_data) {
			wl_list_remove(&other->link);
			mode_data_destroy(mode_data);
		}
	}
}

static struct zwlr_output_mode_v1_listener
zwlr_output_mode_v1_listener = {
	.size = zwlr_output_mode_v1_handle_size,
	.refresh = zwlr_output_mode_v1_handle_refresh,
	.preferred = zwlr_output_mode_v1_handle_preferred,
	.finished = zwlr_output_mode_v1_handle_finished,
};

static struct head_data *
head_data_create(struct wlrctl_output_command *cmd) {
	struct head_data *head_data = calloc(1, sizeof (struct head_data));
	assert(head_data);
	wl_list_init(&head_data->modes);
	wl_list_insert(&cmd->heads, &head_data->link);
	head_data->cmd = cmd;
	return head_data;
}

static void
head_data_destroy(struct head_data *head_data) {
	free(head_data->description);
	free(head_data);
}

static void
zwlr_output_head_v1_handle_name(
	void *data,
	struct zwlr_output_head_v1 *head,
	const char *name
	)
{
	struct head_data *head_data = data;
	strncpy(head_data->name, name, 24);
	head_data->name[24 - 1] = '\0';
}

static void
zwlr_output_head_v1_handle_make(
	void *data,
	struct zwlr_output_head_v1 *head,
	const char *make
	)
{
	struct head_data *head_data = data;
	strncpy(head_data->make, make, 56);
	head_data->make[56 - 1] = '\0';
}

static void
zwlr_output_head_v1_handle_model(
	void *data,
	struct zwlr_output_head_v1 *head,
	const char *model
	)
{
	struct head_data *head_data = data;
	strncpy(head_data->model, model, 16);
	head_data->model[16 - 1] = '\0';
}

static void
zwlr_output_head_v1_handle_serial_number(
	void *data,
	struct zwlr_output_head_v1 *head,
	const char *serial
	)
{
	struct head_data *head_data = data;
	strncpy(head_data->serial, serial, 16);
	head_data->serial[16 - 1] = '\0';
}

static void
wlrctl_output_head_v1_handle_physical_size(
	void *data,
	struct zwlr_output_head_v1 *head,
	int32_t width, int32_t height
	)
{
	struct head_data *head_data = data;
	head_data->width = width;
	head_data->height = height;
}

static void
wlrctl_output_head_v1_handle_enabled(
	void *data,
	struct zwlr_output_head_v1 *head,
	int32_t enabled
	)
{
	struct head_data *head_data = data;
	head_data->enabled = enabled;
}

static void
wlrctl_output_head_v1_handle_position(
	void *data,
	struct zwlr_output_head_v1 *head,
	int32_t x, int32_t y
	)
{
	struct head_data *head_data = data;
	head_data->x = x;
	head_data->y = y;
}

static void
wlrctl_output_head_v1_handle_transform(
	void *data,
	struct zwlr_output_head_v1 *head,
	int32_t transform
	)
{
	struct head_data *head_data = data;
	head_data->transform = transform;
}

static void
zwlr_output_head_v1_handle_description(
	void *data,
	struct zwlr_output_head_v1 *head,
	const char *description
	)
{
	struct head_data *head_data = data;
	head_data->description = strdup(description);
}

static void
zwlr_output_head_v1_handle_scale(
	void *data,
	struct zwlr_output_head_v1 *head,
	wl_fixed_t scale
	)
{
	struct head_data *head_data = data;
	head_data->scale = wl_fixed_to_double(scale);
}

static void
zwlr_output_head_v1_handle_finished(
	void *data,
	struct zwlr_output_head_v1 *head
	)
{
	struct head_data *head_data = data;
	struct head_data *other, *tmp;
	wl_list_for_each_safe(other, tmp, &head_data->cmd->heads, link) {
		if (other == head_data) {
			wl_list_remove(&other->link);
			head_data_destroy(other);
		}
	}
}

static void
zwlr_output_head_v1_handle_mode(
	void *data,
	struct zwlr_output_head_v1 *head,
	struct zwlr_output_mode_v1 *mode
	)
{
	struct head_data *head_data = data;
	struct mode_data *mode_data = mode_data_create(head_data);
	mode_data->mode = mode;
	zwlr_output_mode_v1_add_listener(
		mode,
		&zwlr_output_mode_v1_listener,
		mode_data
	);
}

static void
zwlr_output_head_v1_handle_current_mode(
	void *data,
	struct zwlr_output_head_v1 *head,
	struct zwlr_output_mode_v1 *mode
	)
{
	struct head_data *head_data = data;
	struct mode_data *mode_data;
	wl_list_for_each(mode_data, &head_data->modes, link) {
		if (mode_data->mode == mode) {
			head_data->current_mode = mode_data;
			return;
		}
	}
}

static struct zwlr_output_head_v1_listener
zwlr_output_head_v1_listener = {
	.name = zwlr_output_head_v1_handle_name,
	.description = zwlr_output_head_v1_handle_description,
	.physical_size = wlrctl_output_head_v1_handle_physical_size,
	.mode = zwlr_output_head_v1_handle_mode,
	.enabled = wlrctl_output_head_v1_handle_enabled,
	.current_mode = zwlr_output_head_v1_handle_current_mode,
	.position = wlrctl_output_head_v1_handle_position,
	.transform = wlrctl_output_head_v1_handle_transform,
	.scale = zwlr_output_head_v1_handle_scale,
	.finished = zwlr_output_head_v1_handle_finished,
	.make = zwlr_output_head_v1_handle_make,
	.model = zwlr_output_head_v1_handle_model,
	.serial_number = zwlr_output_head_v1_handle_serial_number,
};

static void zwlr_output_manager_v1_handle_head(
	void *data,
	struct zwlr_output_manager_v1 *manager,
	struct zwlr_output_head_v1 *head
	)
{
	struct wlrctl *state = data;
	struct wlrctl_output_command *cmd = state->cmd;
	struct head_data *head_data = head_data_create(cmd);
	zwlr_output_head_v1_add_listener(
		head,
		&zwlr_output_head_v1_listener,
		head_data
	);
}

static void
zwlr_output_manager_v1_handle_finished(
	void *data,
	struct zwlr_output_manager_v1 *manager
	)
{
	struct wlrctl *state = data;
	state->running = false;
	destroy_output(state);
}

static void
do_output_cfg_action(struct wlrctl_output_command *cmd,
	struct head_data *head_data
	)
{
	switch (cmd->cfg_action) {
	default:
		puts("Not implemented");
		break;
	case OUTPUT_CFG_ACTION_UNSPEC:
		// unreachable
		assert(false);
	}
}



static void
zwlr_output_manager_v1_handle_done(void *user_data,
	struct zwlr_output_manager_v1 *manager,
	uint32_t serial
	)
{
	struct wlrctl *state = user_data;
	struct wlrctl_output_command *cmd = state->cmd;

	struct head_data *data;
	switch (cmd->action) {
	case OUTPUT_ACTION_LIST:
		wl_list_for_each(data, &cmd->heads, link) {
			printf("%s \"%s %s\"", data->name, data->make, data->model);
			if (data->current_mode) {
				struct mode_data *mode = data->current_mode;
				printf(" (%dx%d %.3fHz)", mode->width, mode->height, mode->refresh / 1000.0);
			} else if (!data->enabled) {
				printf(" (disabled)");
			}
			printf("\n");
		}
		break;
	case OUTPUT_ACTION_CONFIGURE:;
		struct head_data *head_data = NULL;
		wl_list_for_each(data, &cmd->heads, link) {
			if (strcmp(data->name, cmd->ident) == 0) {
				head_data = data;
			}
		}
		if (head_data) {
			do_output_cfg_action(cmd, head_data);
		} else {
			die("No matching outputs\n");
		}
		break;
	case OUTPUT_ACTION_UNSPEC:
		// unreachable
		assert(false);
	}
}

static struct zwlr_output_manager_v1_listener
zwlr_output_manager_v1_listener = {
	.head = zwlr_output_manager_v1_handle_head,
	.done = zwlr_output_manager_v1_handle_done,
	.finished = zwlr_output_manager_v1_handle_finished,
};

void
prepare_output(struct wlrctl *state, int argc, char *argv[])
{
	struct wlrctl_output_command *cmd =
		calloc(1, sizeof (struct wlrctl_output_command));
	assert(cmd);

	wl_list_init(&cmd->heads);
	if (argc == 0) {
		die("Missing output action or identifier\n");
	}

	char *action = argv[0];
	cmd->action = parse_action(action);
	if (cmd->action == OUTPUT_ACTION_CONFIGURE) {
		if (argc < 2 ) {
			cmd->cfg_action = OUTPUT_CFG_ACTION_SHOW;
		} else {
			cmd->cfg_action = parse_cfg_action(argv[1]);
			if (cmd->cfg_action == OUTPUT_CFG_ACTION_UNSPEC) {
				die("Unknown output configurataion '%s'\n", argv[1]);
			}
		}
		cmd->ident = strdup(argv[0]);
	}

	state->cmd = cmd;
	cmd->state = state;
}

void
stop_output(struct wlrctl *state)
{
	zwlr_output_manager_v1_stop(state->output_mgr);
}

void
complete_output(void *data, struct wl_callback *callback, uint32_t serial)
{
	struct wlrctl *state = data;
	// struct wlrctl_output_command *cmd = state->cmd;
	wl_callback_destroy(callback);
	stop_output(state);
}

void
run_output(struct wlrctl *state)
{
	// struct wlrctl_output_command *cmd = state->cmd;
	zwlr_output_manager_v1_add_listener(
		state->output_mgr,
		&zwlr_output_manager_v1_listener,
		state
	);
	stop_output(state);
}

void
destroy_output(struct wlrctl *state)
{
	struct wlrctl_output_command *cmd = state->cmd;
	struct head_data *data, *tmp;
	wl_list_for_each_safe(data, tmp, &cmd->heads, link) {
		wl_list_remove(&data->link);
		head_data_destroy(data);
	}
	free(cmd->ident);
	free(cmd);
}
07070100000013000081A400000000000000000000000164632F3500001409000000000000000000000000000000000000001900000000wlrctl-0.2.2~0/pointer.c#include <assert.h>
#include <linux/input-event-codes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wayland-client.h>
#include <wayland-util.h>
#include "common.h"
#include "pointer.h"
#include "util.h"

#include "wlr-virtual-pointer-unstable-v1-client-protocol.h"


static enum pointer_action
parse_action(const char *action)
{
	static const struct token actions[] = {
		{"click",  POINTER_ACTION_CLICK },
		{"motion", POINTER_ACTION_MOTION},
		{"move",   POINTER_ACTION_MOTION},
		{"scroll", POINTER_ACTION_SCROLL},
		{NULL, POINTER_ACTION_UNSPEC}
	};

	return matchtok(actions, action);
}

static uint32_t
parse_button(const char *button)
{
	static const struct token buttons[] = {
		{"left",    BTN_LEFT   },
		{"right",   BTN_RIGHT  },
		{"middle",  BTN_MIDDLE },
		{"extra",   BTN_EXTRA  }, 
		{"side",    BTN_SIDE   },
		{"forward", BTN_FORWARD},
		{"back",    BTN_BACK   },
		{NULL, 0}
	};

	return matchtok(buttons, button);
}

static void
parse_fixed(const char *d, wl_fixed_t *fixed)
{
	char *end;
	int val = strtod(d, &end);
	if (end == d || *end){
		die("Bad value: '%s'\n", d);
	} else {
		*fixed = wl_fixed_from_double(val);
	}
}


void
prepare_pointer(struct wlrctl *state, int argc, char *argv[])
{
	struct wlrctl_pointer_command *cmd = calloc(1, sizeof (struct wlrctl_pointer_command));
	assert(cmd);

	const char *action = argv[0];
	cmd->action = parse_action(action);
	switch (cmd->action) {
	case POINTER_ACTION_CLICK:
		if (argc < 2) {
			cmd->button = BTN_LEFT;
		} else {
			const char *button = argv[1];
			cmd->button = parse_button(button);
			if (!cmd->button) {
				die("Unknown button: '%s'\n", button);
			}
		}
		break;
	case POINTER_ACTION_MOTION:
		switch (argc) {
		case 1:
			break;
		case 2:
			parse_fixed(argv[1], &cmd->dx);
			break;
		case 3:
			parse_fixed(argv[1], &cmd->dx);
			parse_fixed(argv[2], &cmd->dy);
			break;
		default:
			die("Extra argument: '%s'\n", argv[3]);
		}
		break;
	case POINTER_ACTION_SCROLL:
		switch (argc) {
		case 1:
			break;
		case 2:
			parse_fixed(argv[1], &cmd->dy);
			break;
		case 3:
			parse_fixed(argv[1], &cmd->dy);
			parse_fixed(argv[2], &cmd->dx);
			break;
		default:
			die("Extra argument: '%s'\n", argv[3]);
		}
		break;
	case POINTER_ACTION_UNSPEC:
		die("Unknown pointer action: '%s'\n", action);
	}

	state->cmd = cmd;
	cmd->state = state;
}

static void
complete_pointer(void *data, struct wl_callback *callback, uint32_t serial)
{
	struct wlrctl *state = data;
	wl_callback_destroy(callback);
	state->running = false;
	destroy_pointer(state);
}

static struct wl_callback_listener completed_listener = {
	.done = complete_pointer
};

static void
pointer_press(struct zwlr_virtual_pointer_v1 *vptr, uint32_t button)
{
	zwlr_virtual_pointer_v1_button(vptr, timestamp(), button, WL_POINTER_BUTTON_STATE_PRESSED);
	zwlr_virtual_pointer_v1_frame(vptr);
}

static void
pointer_release(struct zwlr_virtual_pointer_v1 *vptr, uint32_t button)
{
	zwlr_virtual_pointer_v1_button(vptr, timestamp(), button, WL_POINTER_BUTTON_STATE_RELEASED);
	zwlr_virtual_pointer_v1_frame(vptr);
}

static void
pointer_move(struct zwlr_virtual_pointer_v1 *vptr, wl_fixed_t dx, wl_fixed_t dy)
{
	if (!dx && !dy) {
		return;
	} else {
		zwlr_virtual_pointer_v1_motion(vptr, timestamp(), dx, dy);
		zwlr_virtual_pointer_v1_frame(vptr);
	}
}

static void
pointer_scroll(struct zwlr_virtual_pointer_v1 *vptr, wl_fixed_t dy, wl_fixed_t dx)
{
	if (!dx && !dy) {
		return;
	}
	if (dx) {
		zwlr_virtual_pointer_v1_axis_source(vptr, WL_POINTER_AXIS_SOURCE_FINGER);
		zwlr_virtual_pointer_v1_axis(vptr, timestamp(), WL_POINTER_AXIS_HORIZONTAL_SCROLL, dx);
	}
	if (dy) {
		zwlr_virtual_pointer_v1_axis_source(vptr, WL_POINTER_AXIS_SOURCE_FINGER);
		zwlr_virtual_pointer_v1_axis(vptr, timestamp(), WL_POINTER_AXIS_VERTICAL_SCROLL, dy);
	}
	zwlr_virtual_pointer_v1_frame(vptr);
	if (dx) {
		zwlr_virtual_pointer_v1_axis_source(vptr, WL_POINTER_AXIS_SOURCE_FINGER);
		zwlr_virtual_pointer_v1_axis_stop(vptr, timestamp(), WL_POINTER_AXIS_HORIZONTAL_SCROLL);
	}
	if (dy) {
		zwlr_virtual_pointer_v1_axis_source(vptr, WL_POINTER_AXIS_SOURCE_FINGER);
		zwlr_virtual_pointer_v1_axis_stop(vptr, timestamp(), WL_POINTER_AXIS_VERTICAL_SCROLL);
	}
	zwlr_virtual_pointer_v1_frame(vptr);
}

void
run_pointer(struct wlrctl *state)
{
	struct wlrctl_pointer_command *cmd = state->cmd;
	cmd->device =
	zwlr_virtual_pointer_manager_v1_create_virtual_pointer(
		state->vp_mgr, state->seat
	);
	switch (cmd->action) {
	case POINTER_ACTION_CLICK:
		pointer_press(cmd->device, cmd->button);
		pointer_release(cmd->device, cmd->button);
		break;
	case POINTER_ACTION_MOTION:
		pointer_move(cmd->device, cmd->dx, cmd->dy);
		break;
	case POINTER_ACTION_SCROLL:
		pointer_scroll(cmd->device, cmd->dy, cmd->dx);
		break;
	case POINTER_ACTION_UNSPEC:
		// Unreachable
		assert(false);
	}
	struct wl_callback *callback = wl_display_sync(state->display);
	wl_callback_add_listener(callback, &completed_listener, state);
}

void
destroy_pointer(struct wlrctl *state)
{
	struct wlrctl_pointer_command *cmd = state->cmd;
	zwlr_virtual_pointer_v1_destroy(cmd->device);
	free(cmd);
}
07070100000014000041ED00000000000000000000000164632F3500000000000000000000000000000000000000000000001800000000wlrctl-0.2.2~0/protocol07070100000015000081A400000000000000000000000164632F350000042D000000000000000000000000000000000000002400000000wlrctl-0.2.2~0/protocol/meson.build# wl_protocol_dir = wayland_protos.get_variable(pkgconfig: 'pkgdatadir')

wayland_scanner = find_program('wayland-scanner')

wayland_scanner_code = generator(
	wayland_scanner,
	output: '@BASENAME@-protocol.c',
	arguments: ['private-code', '@INPUT@', '@OUTPUT@'],
)

wayland_scanner_client = generator(
	wayland_scanner,
	output: '@BASENAME@-client-protocol.h',
	arguments: ['client-header', '@INPUT@', '@OUTPUT@'],
)

protocols = [
	'virtual-keyboard-unstable-v1.xml',
	'wlr-virtual-pointer-unstable-v1.xml',
	'wlr-foreign-toplevel-management-unstable-v1.xml',
	'wlr-output-management-unstable-v1.xml',
]

client_protos_src = []
client_protos_headers = []
foreach xml : protocols
	client_protos_src += wayland_scanner_code.process(xml)
	client_protos_headers += wayland_scanner_client.process(xml)
endforeach

lib_client_protos = static_library(
	'client_protos',
	client_protos_src + client_protos_headers,
	dependencies: [wayland_client]
)

client_protos = declare_dependency(
	link_with: lib_client_protos,
	sources: client_protos_headers,
)

# vim: set ts=4 sw=4:
07070100000016000081A400000000000000000000000164632F3500001316000000000000000000000000000000000000003900000000wlrctl-0.2.2~0/protocol/virtual-keyboard-unstable-v1.xml<?xml version="1.0" encoding="UTF-8"?>
<protocol name="virtual_keyboard_unstable_v1">
  <copyright>
    Copyright © 2008-2011  Kristian Høgsberg
    Copyright © 2010-2013  Intel Corporation
    Copyright © 2012-2013  Collabora, Ltd.
    Copyright © 2018       Purism SPC

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice (including the next
    paragraph) shall be included in all copies or substantial portions of the
    Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
  </copyright>

  <interface name="zwp_virtual_keyboard_v1" version="1">
    <description summary="virtual keyboard">
      The virtual keyboard provides an application with requests which emulate
      the behaviour of a physical keyboard.

      This interface can be used by clients on its own to provide raw input
      events, or it can accompany the input method protocol.
    </description>

    <request name="keymap">
      <description summary="keyboard mapping">
        Provide a file descriptor to the compositor which can be
        memory-mapped to provide a keyboard mapping description.

        Format carries a value from the keymap_format enumeration.
      </description>
      <arg name="format" type="uint" summary="keymap format"/>
      <arg name="fd" type="fd" summary="keymap file descriptor"/>
      <arg name="size" type="uint" summary="keymap size, in bytes"/>
    </request>

    <enum name="error">
      <entry name="no_keymap" value="0" summary="No keymap was set"/>
    </enum>

    <request name="key">
      <description summary="key event">
        A key was pressed or released.
        The time argument is a timestamp with millisecond granularity, with an
        undefined base. All requests regarding a single object must share the
        same clock.

        Keymap must be set before issuing this request.

        State carries a value from the key_state enumeration.
      </description>
      <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
      <arg name="key" type="uint" summary="key that produced the event"/>
      <arg name="state" type="uint" summary="physical state of the key"/>
    </request>

    <request name="modifiers">
      <description summary="modifier and group state">
        Notifies the compositor that the modifier and/or group state has
        changed, and it should update state.

        The client should use wl_keyboard.modifiers event to synchronize its
        internal state with seat state.

        Keymap must be set before issuing this request.
      </description>
      <arg name="mods_depressed" type="uint" summary="depressed modifiers"/>
      <arg name="mods_latched" type="uint" summary="latched modifiers"/>
      <arg name="mods_locked" type="uint" summary="locked modifiers"/>
      <arg name="group" type="uint" summary="keyboard layout"/>
    </request>

    <request name="destroy" type="destructor" since="1">
      <description summary="destroy the virtual keyboard keyboard object"/>
    </request>
  </interface>

  <interface name="zwp_virtual_keyboard_manager_v1" version="1">
    <description summary="virtual keyboard manager">
      A virtual keyboard manager allows an application to provide keyboard
      input events as if they came from a physical keyboard.
    </description>

    <enum name="error">
      <entry name="unauthorized" value="0" summary="client not authorized to use the interface"/>
    </enum>

    <request name="create_virtual_keyboard">
      <description summary="Create a new virtual keyboard">
        Creates a new virtual keyboard associated to a seat.

        If the compositor enables a keyboard to perform arbitrary actions, it
        should present an error when an untrusted client requests a new
        keyboard.
      </description>
      <arg name="seat" type="object" interface="wl_seat"/>
      <arg name="id" type="new_id" interface="zwp_virtual_keyboard_v1"/>
    </request>
  </interface>
</protocol>
07070100000017000081A400000000000000000000000164632F3500002D12000000000000000000000000000000000000004800000000wlrctl-0.2.2~0/protocol/wlr-foreign-toplevel-management-unstable-v1.xml<?xml version="1.0" encoding="UTF-8"?>
<protocol name="wlr_foreign_toplevel_management_unstable_v1">
  <copyright>
    Copyright © 2018 Ilia Bozhinov

    Permission to use, copy, modify, distribute, and sell this
    software and its documentation for any purpose is hereby granted
    without fee, provided that the above copyright notice appear in
    all copies and that both that copyright notice and this permission
    notice appear in supporting documentation, and that the name of
    the copyright holders not be used in advertising or publicity
    pertaining to distribution of the software without specific,
    written prior permission.  The copyright holders make no
    representations about the suitability of this software for any
    purpose.  It is provided "as is" without express or implied
    warranty.

    THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
    SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
    FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
    SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
    AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
    THIS SOFTWARE.
  </copyright>

  <interface name="zwlr_foreign_toplevel_manager_v1" version="3">
    <description summary="list and control opened apps">
      The purpose of this protocol is to enable the creation of taskbars
      and docks by providing them with a list of opened applications and
      letting them request certain actions on them, like maximizing, etc.

      After a client binds the zwlr_foreign_toplevel_manager_v1, each opened
      toplevel window will be sent via the toplevel event
    </description>

    <event name="toplevel">
      <description summary="a toplevel has been created">
        This event is emitted whenever a new toplevel window is created. It
        is emitted for all toplevels, regardless of the app that has created
        them.

        All initial details of the toplevel(title, app_id, states, etc.) will
        be sent immediately after this event via the corresponding events in
        zwlr_foreign_toplevel_handle_v1.
      </description>
      <arg name="toplevel" type="new_id" interface="zwlr_foreign_toplevel_handle_v1"/>
    </event>

    <request name="stop">
      <description summary="stop sending events">
        Indicates the client no longer wishes to receive events for new toplevels.
        However the compositor may emit further toplevel_created events, until
        the finished event is emitted.

        The client must not send any more requests after this one.
      </description>
    </request>

    <event name="finished">
      <description summary="the compositor has finished with the toplevel manager">
        This event indicates that the compositor is done sending events to the
        zwlr_foreign_toplevel_manager_v1. The server will destroy the object
        immediately after sending this request, so it will become invalid and
        the client should free any resources associated with it.
      </description>
    </event>
  </interface>

  <interface name="zwlr_foreign_toplevel_handle_v1" version="3">
    <description summary="an opened toplevel">
      A zwlr_foreign_toplevel_handle_v1 object represents an opened toplevel
      window. Each app may have multiple opened toplevels.

      Each toplevel has a list of outputs it is visible on, conveyed to the
      client with the output_enter and output_leave events.
    </description>

    <event name="title">
      <description summary="title change">
        This event is emitted whenever the title of the toplevel changes.
      </description>
      <arg name="title" type="string"/>
    </event>

    <event name="app_id">
      <description summary="app-id change">
        This event is emitted whenever the app-id of the toplevel changes.
      </description>
      <arg name="app_id" type="string"/>
    </event>

    <event name="output_enter">
      <description summary="toplevel entered an output">
        This event is emitted whenever the toplevel becomes visible on
        the given output. A toplevel may be visible on multiple outputs.
      </description>
      <arg name="output" type="object" interface="wl_output"/>
    </event>

    <event name="output_leave">
      <description summary="toplevel left an output">
        This event is emitted whenever the toplevel stops being visible on
        the given output. It is guaranteed that an entered-output event
        with the same output has been emitted before this event.
      </description>
      <arg name="output" type="object" interface="wl_output"/>
    </event>

    <request name="set_maximized">
      <description summary="requests that the toplevel be maximized">
        Requests that the toplevel be maximized. If the maximized state actually
        changes, this will be indicated by the state event.
      </description>
    </request>

    <request name="unset_maximized">
      <description summary="requests that the toplevel be unmaximized">
        Requests that the toplevel be unmaximized. If the maximized state actually
        changes, this will be indicated by the state event.
      </description>
    </request>

    <request name="set_minimized">
      <description summary="requests that the toplevel be minimized">
        Requests that the toplevel be minimized. If the minimized state actually
        changes, this will be indicated by the state event.
      </description>
    </request>

    <request name="unset_minimized">
      <description summary="requests that the toplevel be unminimized">
        Requests that the toplevel be unminimized. If the minimized state actually
        changes, this will be indicated by the state event.
      </description>
    </request>

    <request name="activate">
      <description summary="activate the toplevel">
        Request that this toplevel be activated on the given seat.
        There is no guarantee the toplevel will be actually activated.
      </description>
      <arg name="seat" type="object" interface="wl_seat"/>
    </request>

    <enum name="state">
      <description summary="types of states on the toplevel">
        The different states that a toplevel can have. These have the same meaning
        as the states with the same names defined in xdg-toplevel
      </description>

      <entry name="maximized"  value="0" summary="the toplevel is maximized"/>
      <entry name="minimized"  value="1" summary="the toplevel is minimized"/>
      <entry name="activated"  value="2" summary="the toplevel is active"/>
      <entry name="fullscreen" value="3" summary="the toplevel is fullscreen" since="2"/>
    </enum>

    <event name="state">
      <description summary="the toplevel state changed">
        This event is emitted immediately after the zlw_foreign_toplevel_handle_v1
        is created and each time the toplevel state changes, either because of a
        compositor action or because of a request in this protocol.
      </description>

      <arg name="state" type="array"/>
    </event>

    <event name="done">
      <description summary="all information about the toplevel has been sent">
        This event is sent after all changes in the toplevel state have been
        sent.

        This allows changes to the zwlr_foreign_toplevel_handle_v1 properties
        to be seen as atomic, even if they happen via multiple events.
      </description>
    </event>

    <request name="close">
      <description summary="request that the toplevel be closed">
        Send a request to the toplevel to close itself. The compositor would
        typically use a shell-specific method to carry out this request, for
        example by sending the xdg_toplevel.close event. However, this gives
        no guarantees the toplevel will actually be destroyed. If and when
        this happens, the zwlr_foreign_toplevel_handle_v1.closed event will
        be emitted.
      </description>
    </request>

    <request name="set_rectangle">
      <description summary="the rectangle which represents the toplevel">
        The rectangle of the surface specified in this request corresponds to
        the place where the app using this protocol represents the given toplevel.
        It can be used by the compositor as a hint for some operations, e.g
        minimizing. The client is however not required to set this, in which
        case the compositor is free to decide some default value.

        If the client specifies more than one rectangle, only the last one is
        considered.

        The dimensions are given in surface-local coordinates.
        Setting width=height=0 removes the already-set rectangle.
      </description>

      <arg name="surface" type="object" interface="wl_surface"/>
      <arg name="x" type="int"/>
      <arg name="y" type="int"/>
      <arg name="width" type="int"/>
      <arg name="height" type="int"/>
    </request>

    <enum name="error">
      <entry name="invalid_rectangle" value="0"
        summary="the provided rectangle is invalid"/>
    </enum>

    <event name="closed">
      <description summary="this toplevel has been destroyed">
        This event means the toplevel has been destroyed. It is guaranteed there
        won't be any more events for this zwlr_foreign_toplevel_handle_v1. The
        toplevel itself becomes inert so any requests will be ignored except the
        destroy request.
      </description>
    </event>

    <request name="destroy" type="destructor">
      <description summary="destroy the zwlr_foreign_toplevel_handle_v1 object">
        Destroys the zwlr_foreign_toplevel_handle_v1 object.

        This request should be called either when the client does not want to
        use the toplevel anymore or after the closed event to finalize the
        destruction of the object.
      </description>
    </request>

    <!-- Version 2 additions -->

    <request name="set_fullscreen" since="2">
      <description summary="request that the toplevel be fullscreened">
        Requests that the toplevel be fullscreened on the given output. If the
        fullscreen state and/or the outputs the toplevel is visible on actually
        change, this will be indicated by the state and output_enter/leave
        events.

        The output parameter is only a hint to the compositor. Also, if output
        is NULL, the compositor should decide which output the toplevel will be
        fullscreened on, if at all.
      </description>
      <arg name="output" type="object" interface="wl_output" allow-null="true"/>
    </request>

    <request name="unset_fullscreen" since="2">
      <description summary="request that the toplevel be unfullscreened">
        Requests that the toplevel be unfullscreened. If the fullscreen state
        actually changes, this will be indicated by the state event.
      </description>
    </request>

    <!-- Version 3 additions -->

    <event name="parent" since="3">
      <description summary="parent change">
        This event is emitted whenever the parent of the toplevel changes.

        No event is emitted when the parent handle is destroyed by the client.
      </description>
      <arg name="parent" type="object" interface="zwlr_foreign_toplevel_handle_v1" allow-null="true"/>
    </event>
  </interface>
</protocol>
07070100000018000081A400000000000000000000000164632F3500005DFA000000000000000000000000000000000000003E00000000wlrctl-0.2.2~0/protocol/wlr-output-management-unstable-v1.xml<?xml version="1.0" encoding="UTF-8"?>
<protocol name="wlr_output_management_unstable_v1">
  <copyright>
    Copyright © 2019 Purism SPC

    Permission to use, copy, modify, distribute, and sell this
    software and its documentation for any purpose is hereby granted
    without fee, provided that the above copyright notice appear in
    all copies and that both that copyright notice and this permission
    notice appear in supporting documentation, and that the name of
    the copyright holders not be used in advertising or publicity
    pertaining to distribution of the software without specific,
    written prior permission.  The copyright holders make no
    representations about the suitability of this software for any
    purpose.  It is provided "as is" without express or implied
    warranty.

    THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
    SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
    FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
    SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
    AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
    THIS SOFTWARE.
  </copyright>

  <description summary="protocol to configure output devices">
    This protocol exposes interfaces to obtain and modify output device
    configuration.

    Warning! The protocol described in this file is experimental and
    backward incompatible changes may be made. Backward compatible changes
    may be added together with the corresponding interface version bump.
    Backward incompatible changes are done by bumping the version number in
    the protocol and interface names and resetting the interface version.
    Once the protocol is to be declared stable, the 'z' prefix and the
    version number in the protocol and interface names are removed and the
    interface version number is reset.
  </description>

  <interface name="zwlr_output_manager_v1" version="2">
    <description summary="output device configuration manager">
      This interface is a manager that allows reading and writing the current
      output device configuration.

      Output devices that display pixels (e.g. a physical monitor or a virtual
      output in a window) are represented as heads. Heads cannot be created nor
      destroyed by the client, but they can be enabled or disabled and their
      properties can be changed. Each head may have one or more available modes.

      Whenever a head appears (e.g. a monitor is plugged in), it will be
      advertised via the head event. Immediately after the output manager is
      bound, all current heads are advertised.

      Whenever a head's properties change, the relevant wlr_output_head events
      will be sent. Not all head properties will be sent: only properties that
      have changed need to.

      Whenever a head disappears (e.g. a monitor is unplugged), a
      wlr_output_head.finished event will be sent.

      After one or more heads appear, change or disappear, the done event will
      be sent. It carries a serial which can be used in a create_configuration
      request to update heads properties.

      The information obtained from this protocol should only be used for output
      configuration purposes. This protocol is not designed to be a generic
      output property advertisement protocol for regular clients. Instead,
      protocols such as xdg-output should be used.
    </description>

    <event name="head">
      <description summary="introduce a new head">
        This event introduces a new head. This happens whenever a new head
        appears (e.g. a monitor is plugged in) or after the output manager is
        bound.
      </description>
      <arg name="head" type="new_id" interface="zwlr_output_head_v1"/>
    </event>

    <event name="done">
      <description summary="sent all information about current configuration">
        This event is sent after all information has been sent after binding to
        the output manager object and after any subsequent changes. This applies
        to child head and mode objects as well. In other words, this event is
        sent whenever a head or mode is created or destroyed and whenever one of
        their properties has been changed. Not all state is re-sent each time
        the current configuration changes: only the actual changes are sent.

        This allows changes to the output configuration to be seen as atomic,
        even if they happen via multiple events.

        A serial is sent to be used in a future create_configuration request.
      </description>
      <arg name="serial" type="uint" summary="current configuration serial"/>
    </event>

    <request name="create_configuration">
      <description summary="create a new output configuration object">
        Create a new output configuration object. This allows to update head
        properties.
      </description>
      <arg name="id" type="new_id" interface="zwlr_output_configuration_v1"/>
      <arg name="serial" type="uint"/>
    </request>

    <request name="stop">
      <description summary="stop sending events">
        Indicates the client no longer wishes to receive events for output
        configuration changes. However the compositor may emit further events,
        until the finished event is emitted.

        The client must not send any more requests after this one.
      </description>
    </request>

    <event name="finished">
      <description summary="the compositor has finished with the manager">
        This event indicates that the compositor is done sending manager events.
        The compositor will destroy the object immediately after sending this
        event, so it will become invalid and the client should release any
        resources associated with it.
      </description>
    </event>
  </interface>

  <interface name="zwlr_output_head_v1" version="2">
    <description summary="output device">
      A head is an output device. The difference between a wl_output object and
      a head is that heads are advertised even if they are turned off. A head
      object only advertises properties and cannot be used directly to change
      them.

      A head has some read-only properties: modes, name, description and
      physical_size. These cannot be changed by clients.

      Other properties can be updated via a wlr_output_configuration object.

      Properties sent via this interface are applied atomically via the
      wlr_output_manager.done event. No guarantees are made regarding the order
      in which properties are sent.
    </description>

    <event name="name">
      <description summary="head name">
        This event describes the head name.

        The naming convention is compositor defined, but limited to alphanumeric
        characters and dashes (-). Each name is unique among all wlr_output_head
        objects, but if a wlr_output_head object is destroyed the same name may
        be reused later. The names will also remain consistent across sessions
        with the same hardware and software configuration.

        Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do
        not assume that the name is a reflection of an underlying DRM
        connector, X11 connection, etc.

        If the compositor implements the xdg-output protocol and this head is
        enabled, the xdg_output.name event must report the same name.

        The name event is sent after a wlr_output_head object is created. This
        event is only sent once per object, and the name does not change over
        the lifetime of the wlr_output_head object.
      </description>
      <arg name="name" type="string"/>
    </event>

    <event name="description">
      <description summary="head description">
        This event describes a human-readable description of the head.

        The description is a UTF-8 string with no convention defined for its
        contents. Examples might include 'Foocorp 11" Display' or 'Virtual X11
        output via :1'. However, do not assume that the name is a reflection of
        the make, model, serial of the underlying DRM connector or the display
        name of the underlying X11 connection, etc.

        If the compositor implements xdg-output and this head is enabled,
        the xdg_output.description must report the same description.

        The description event is sent after a wlr_output_head object is created.
        This event is only sent once per object, and the description does not
        change over the lifetime of the wlr_output_head object.
      </description>
      <arg name="description" type="string"/>
    </event>

    <event name="physical_size">
      <description summary="head physical size">
        This event describes the physical size of the head. This event is only
        sent if the head has a physical size (e.g. is not a projector or a
        virtual device).
      </description>
      <arg name="width" type="int" summary="width in millimeters of the output"/>
      <arg name="height" type="int" summary="height in millimeters of the output"/>
    </event>

    <event name="mode">
      <description summary="introduce a mode">
        This event introduces a mode for this head. It is sent once per
        supported mode.
      </description>
      <arg name="mode" type="new_id" interface="zwlr_output_mode_v1"/>
    </event>

    <event name="enabled">
      <description summary="head is enabled or disabled">
        This event describes whether the head is enabled. A disabled head is not
        mapped to a region of the global compositor space.

        When a head is disabled, some properties (current_mode, position,
        transform and scale) are irrelevant.
      </description>
      <arg name="enabled" type="int" summary="zero if disabled, non-zero if enabled"/>
    </event>

    <event name="current_mode">
      <description summary="current mode">
        This event describes the mode currently in use for this head. It is only
        sent if the output is enabled.
      </description>
      <arg name="mode" type="object" interface="zwlr_output_mode_v1"/>
    </event>

    <event name="position">
      <description summary="current position">
        This events describes the position of the head in the global compositor
        space. It is only sent if the output is enabled.
      </description>
      <arg name="x" type="int"
        summary="x position within the global compositor space"/>
      <arg name="y" type="int"
        summary="y position within the global compositor space"/>
    </event>

    <event name="transform">
      <description summary="current transformation">
        This event describes the transformation currently applied to the head.
        It is only sent if the output is enabled.
      </description>
      <arg name="transform" type="int" enum="wl_output.transform"/>
    </event>

    <event name="scale">
      <description summary="current scale">
        This events describes the scale of the head in the global compositor
        space. It is only sent if the output is enabled.
      </description>
      <arg name="scale" type="fixed"/>
    </event>

    <event name="finished">
      <description summary="the head has been destroyed">
        The compositor will destroy the object immediately after sending this
        event, so it will become invalid and the client should release any
        resources associated with it.
      </description>
    </event>

    <!-- Version 2 additions -->
    <event name="make" since="2">
      <description summary="head manufacturer">
        This event describes the manufacturer of the head.

        This must report the same make as the wl_output interface does in its
        geometry event.

        Together with the model and serial_number events the purpose is to
        allow clients to recognize heads from previous sessions and for example
        load head-specific configurations back.

        It is not guaranteed this event will be ever sent. A reason for that
        can be that the compositor does not have information about the make of
        the head or the definition of a make is not sensible in the current
        setup, for example in a virtual session. Clients can still try to
        identify the head by available information from other events but should
        be aware that there is an increased risk of false positives.

        It is not recommended to display the make string in UI to users. For
        that the string provided by the description event should be preferred.
      </description>
      <arg name="make" type="string"/>
    </event>

    <event name="model" since="2">
      <description summary="head model">
        This event describes the model of the head.

        This must report the same model as the wl_output interface does in its
        geometry event.

        Together with the make and serial_number events the purpose is to
        allow clients to recognize heads from previous sessions and for example
        load head-specific configurations back.

        It is not guaranteed this event will be ever sent. A reason for that
        can be that the compositor does not have information about the model of
        the head or the definition of a model is not sensible in the current
        setup, for example in a virtual session. Clients can still try to
        identify the head by available information from other events but should
        be aware that there is an increased risk of false positives.

        It is not recommended to display the model string in UI to users. For
        that the string provided by the description event should be preferred.
      </description>
      <arg name="model" type="string"/>
    </event>

    <event name="serial_number" since="2">
      <description summary="head serial number">
        This event describes the serial number of the head.

        Together with the make and model events the purpose is to allow clients
        to recognize heads from previous sessions and for example load head-
        specific configurations back.

        It is not guaranteed this event will be ever sent. A reason for that
        can be that the compositor does not have information about the serial
        number of the head or the definition of a serial number is not sensible
        in the current setup. Clients can still try to identify the head by
        available information from other events but should be aware that there
        is an increased risk of false positives.

        It is not recommended to display the serial_number string in UI to
        users. For that the string provided by the description event should be
        preferred.
      </description>
      <arg name="serial_number" type="string"/>
    </event>
  </interface>

  <interface name="zwlr_output_mode_v1" version="2">
    <description summary="output mode">
      This object describes an output mode.

      Some heads don't support output modes, in which case modes won't be
      advertised.

      Properties sent via this interface are applied atomically via the
      wlr_output_manager.done event. No guarantees are made regarding the order
      in which properties are sent.
    </description>

    <event name="size">
      <description summary="mode size">
        This event describes the mode size. The size is given in physical
        hardware units of the output device. This is not necessarily the same as
        the output size in the global compositor space. For instance, the output
        may be scaled or transformed.
      </description>
      <arg name="width" type="int" summary="width of the mode in hardware units"/>
      <arg name="height" type="int" summary="height of the mode in hardware units"/>
    </event>

    <event name="refresh">
      <description summary="mode refresh rate">
        This event describes the mode's fixed vertical refresh rate. It is only
        sent if the mode has a fixed refresh rate.
      </description>
      <arg name="refresh" type="int" summary="vertical refresh rate in mHz"/>
    </event>

    <event name="preferred">
      <description summary="mode is preferred">
        This event advertises this mode as preferred.
      </description>
    </event>

    <event name="finished">
      <description summary="the mode has been destroyed">
        The compositor will destroy the object immediately after sending this
        event, so it will become invalid and the client should release any
        resources associated with it.
      </description>
    </event>
  </interface>

  <interface name="zwlr_output_configuration_v1" version="2">
    <description summary="output configuration">
      This object is used by the client to describe a full output configuration.

      First, the client needs to setup the output configuration. Each head can
      be either enabled (and configured) or disabled. It is a protocol error to
      send two enable_head or disable_head requests with the same head. It is a
      protocol error to omit a head in a configuration.

      Then, the client can apply or test the configuration. The compositor will
      then reply with a succeeded, failed or cancelled event. Finally the client
      should destroy the configuration object.
    </description>

    <enum name="error">
      <entry name="already_configured_head" value="1"
        summary="head has been configured twice"/>
      <entry name="unconfigured_head" value="2"
        summary="head has not been configured"/>
      <entry name="already_used" value="3"
        summary="request sent after configuration has been applied or tested"/>
    </enum>

    <request name="enable_head">
      <description summary="enable and configure a head">
        Enable a head. This request creates a head configuration object that can
        be used to change the head's properties.
      </description>
      <arg name="id" type="new_id" interface="zwlr_output_configuration_head_v1"
        summary="a new object to configure the head"/>
      <arg name="head" type="object" interface="zwlr_output_head_v1"
        summary="the head to be enabled"/>
    </request>

    <request name="disable_head">
      <description summary="disable a head">
        Disable a head.
      </description>
      <arg name="head" type="object" interface="zwlr_output_head_v1"
        summary="the head to be disabled"/>
    </request>

    <request name="apply">
      <description summary="apply the configuration">
        Apply the new output configuration.

        In case the configuration is successfully applied, there is no guarantee
        that the new output state matches completely the requested
        configuration. For instance, a compositor might round the scale if it
        doesn't support fractional scaling.

        After this request has been sent, the compositor must respond with an
        succeeded, failed or cancelled event. Sending a request that isn't the
        destructor is a protocol error.
      </description>
    </request>

    <request name="test">
      <description summary="test the configuration">
        Test the new output configuration. The configuration won't be applied,
        but will only be validated.

        Even if the compositor succeeds to test a configuration, applying it may
        fail.

        After this request has been sent, the compositor must respond with an
        succeeded, failed or cancelled event. Sending a request that isn't the
        destructor is a protocol error.
      </description>
    </request>

    <event name="succeeded">
      <description summary="configuration changes succeeded">
        Sent after the compositor has successfully applied the changes or
        tested them.

        Upon receiving this event, the client should destroy this object.

        If the current configuration has changed, events to describe the changes
        will be sent followed by a wlr_output_manager.done event.
      </description>
    </event>

    <event name="failed">
      <description summary="configuration changes failed">
        Sent if the compositor rejects the changes or failed to apply them. The
        compositor should revert any changes made by the apply request that
        triggered this event.

        Upon receiving this event, the client should destroy this object.
      </description>
    </event>

    <event name="cancelled">
      <description summary="configuration has been cancelled">
        Sent if the compositor cancels the configuration because the state of an
        output changed and the client has outdated information (e.g. after an
        output has been hotplugged).

        The client can create a new configuration with a newer serial and try
        again.

        Upon receiving this event, the client should destroy this object.
      </description>
    </event>

    <request name="destroy" type="destructor">
      <description summary="destroy the output configuration">
        Using this request a client can tell the compositor that it is not going
        to use the configuration object anymore. Any changes to the outputs
        that have not been applied will be discarded.

        This request also destroys wlr_output_configuration_head objects created
        via this object.
      </description>
    </request>
  </interface>

  <interface name="zwlr_output_configuration_head_v1" version="2">
    <description summary="head configuration">
      This object is used by the client to update a single head's configuration.

      It is a protocol error to set the same property twice.
    </description>

    <enum name="error">
      <entry name="already_set" value="1" summary="property has already been set"/>
      <entry name="invalid_mode" value="2" summary="mode doesn't belong to head"/>
      <entry name="invalid_custom_mode" value="3" summary="mode is invalid"/>
      <entry name="invalid_transform" value="4" summary="transform value outside enum"/>
      <entry name="invalid_scale" value="5" summary="scale negative or zero"/>
    </enum>

    <request name="set_mode">
      <description summary="set the mode">
        This request sets the head's mode.
      </description>
      <arg name="mode" type="object" interface="zwlr_output_mode_v1"/>
    </request>

    <request name="set_custom_mode">
      <description summary="set a custom mode">
        This request assigns a custom mode to the head. The size is given in
        physical hardware units of the output device. If set to zero, the
        refresh rate is unspecified.

        It is a protocol error to set both a mode and a custom mode.
      </description>
      <arg name="width" type="int" summary="width of the mode in hardware units"/>
      <arg name="height" type="int" summary="height of the mode in hardware units"/>
      <arg name="refresh" type="int" summary="vertical refresh rate in mHz or zero"/>
    </request>

    <request name="set_position">
      <description summary="set the position">
        This request sets the head's position in the global compositor space.
      </description>
      <arg name="x" type="int" summary="x position in the global compositor space"/>
      <arg name="y" type="int" summary="y position in the global compositor space"/>
    </request>

    <request name="set_transform">
      <description summary="set the transform">
        This request sets the head's transform.
      </description>
      <arg name="transform" type="int" enum="wl_output.transform"/>
    </request>

    <request name="set_scale">
      <description summary="set the scale">
        This request sets the head's scale.
      </description>
      <arg name="scale" type="fixed"/>
    </request>
  </interface>
</protocol>
07070100000019000081A400000000000000000000000164632F3500001AEF000000000000000000000000000000000000003C00000000wlrctl-0.2.2~0/protocol/wlr-virtual-pointer-unstable-v1.xml<?xml version="1.0" encoding="UTF-8"?>
<protocol name="wlr_virtual_pointer_unstable_v1">
  <copyright>
    Copyright © 2019 Josef Gajdusek

    Permission is hereby granted, free of charge, to any person obtaining a
    copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice (including the next
    paragraph) shall be included in all copies or substantial portions of the
    Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
  </copyright>

  <interface name="zwlr_virtual_pointer_v1" version="2">
    <description summary="virtual pointer">
      This protocol allows clients to emulate a physical pointer device. The
      requests are mostly mirror opposites of those specified in wl_pointer.
    </description>

    <enum name="error">
      <entry name="invalid_axis" value="0"
        summary="client sent invalid axis enumeration value" />
      <entry name="invalid_axis_source" value="1"
        summary="client sent invalid axis source enumeration value" />
    </enum>

    <request name="motion">
      <description summary="pointer relative motion event">
        The pointer has moved by a relative amount to the previous request.

        Values are in the global compositor space.
      </description>
      <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
      <arg name="dx" type="fixed" summary="displacement on the x-axis"/>
      <arg name="dy" type="fixed" summary="displacement on the y-axis"/>
    </request>

    <request name="motion_absolute">
      <description summary="pointer absolute motion event">
        The pointer has moved in an absolute coordinate frame.

        Value of x can range from 0 to x_extent, value of y can range from 0
        to y_extent.
      </description>
      <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
      <arg name="x" type="uint" summary="position on the x-axis"/>
      <arg name="y" type="uint" summary="position on the y-axis"/>
      <arg name="x_extent" type="uint" summary="extent of the x-axis"/>
      <arg name="y_extent" type="uint" summary="extent of the y-axis"/>
    </request>

    <request name="button">
      <description summary="button event">
        A button was pressed or released.
      </description>
      <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
      <arg name="button" type="uint" summary="button that produced the event"/>
      <arg name="state" type="uint" enum="wl_pointer.button_state" summary="physical state of the button"/>
    </request>

    <request name="axis">
      <description summary="axis event">
        Scroll and other axis requests.
      </description>
      <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
      <arg name="axis" type="uint" enum="wl_pointer.axis" summary="axis type"/>
      <arg name="value" type="fixed" summary="length of vector in touchpad coordinates"/>
    </request>

    <request name="frame">
      <description summary="end of a pointer event sequence">
        Indicates the set of events that logically belong together.
      </description>
    </request>

    <request name="axis_source">
      <description summary="axis source event">
        Source information for scroll and other axis.
      </description>
      <arg name="axis_source" type="uint" enum="wl_pointer.axis_source" summary="source of the axis event"/>
    </request>

    <request name="axis_stop">
      <description summary="axis stop event">
        Stop notification for scroll and other axes.
      </description>
      <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
      <arg name="axis" type="uint" enum="wl_pointer.axis" summary="the axis stopped with this event"/>
    </request>

    <request name="axis_discrete">
      <description summary="axis click event">
        Discrete step information for scroll and other axes.

        This event allows the client to extend data normally sent using the axis
        event with discrete value.
      </description>
      <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
      <arg name="axis" type="uint" enum="wl_pointer.axis" summary="axis type"/>
      <arg name="value" type="fixed" summary="length of vector in touchpad coordinates"/>
      <arg name="discrete" type="int" summary="number of steps"/>
    </request>

    <request name="destroy" type="destructor" since="1">
      <description summary="destroy the virtual pointer object"/>
    </request>
  </interface>

  <interface name="zwlr_virtual_pointer_manager_v1" version="2">
    <description summary="virtual pointer manager">
      This object allows clients to create individual virtual pointer objects.
    </description>

    <request name="create_virtual_pointer">
      <description summary="Create a new virtual pointer">
        Creates a new virtual pointer. The optional seat is a suggestion to the
        compositor.
      </description>
      <arg name="seat" type="object" interface="wl_seat" allow-null="true"/>
      <arg name="id" type="new_id" interface="zwlr_virtual_pointer_v1"/>
    </request>

    <request name="destroy" type="destructor" since="1">
      <description summary="destroy the virtual pointer manager"/>
    </request>

    <!-- Version 2 additions -->
    <request name="create_virtual_pointer_with_output" since="2">
      <description summary="Create a new virtual pointer">
        Creates a new virtual pointer. The seat and the output arguments are
        optional. If the seat argument is set, the compositor should assign the
        input device to the requested seat. If the output argument is set, the
        compositor should map the input device to the requested output.
      </description>
      <arg name="seat" type="object" interface="wl_seat" allow-null="true"/>
      <arg name="output" type="object" interface="wl_output" allow-null="true"/>
      <arg name="id" type="new_id" interface="zwlr_virtual_pointer_v1"/>
    </request>
  </interface>
</protocol>
0707010000001A000081A400000000000000000000000164632F3500002D82000000000000000000000000000000000000001A00000000wlrctl-0.2.2~0/toplevel.c#define _DEFAULT_SOURCE
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <wayland-client.h>
#include "common.h"
#include "toplevel.h"
#include "util.h"

#include "wlr-foreign-toplevel-management-unstable-v1-client-protocol.h"

static void noop() {}

static enum toplevel_action
parse_action(const char *action)
{
	static const struct token actions[] = {
		{"activate",   TOPLEVEL_ACTION_ACTIVATE  },
		{"close",      TOPLEVEL_ACTION_CLOSE     },
		{"find",       TOPLEVEL_ACTION_FIND      },
		{"focus",      TOPLEVEL_ACTION_ACTIVATE  },
		{"fullscreen", TOPLEVEL_ACTION_FULLSCREEN},
		{"list",       TOPLEVEL_ACTION_LIST      },
		{"maximize",   TOPLEVEL_ACTION_MAXIMIZE  },
		{"minimize",   TOPLEVEL_ACTION_MINIMIZE  },
		{"wait",       TOPLEVEL_ACTION_WAIT      },
		{"waitfor",    TOPLEVEL_ACTION_WAITFOR   },
		{NULL, TOPLEVEL_ACTION_UNSPEC}
	};

	return matchtok(actions, action);
}

static enum toplevel_attr
parse_state(const char *state, bool *enabled){
	static const struct token states[] = {
		{"maximized",  TOPLEVEL_ATTR_MAXIMIZED },
		{"minimized",  TOPLEVEL_ATTR_MINIMIZED },
		{"activated",  TOPLEVEL_ATTR_ACTIVATED },
		{"active",     TOPLEVEL_ATTR_ACTIVATED },
		{"focused",    TOPLEVEL_ATTR_ACTIVATED },
		{"fullscreen", TOPLEVEL_ATTR_FULLSCREEN},
		{NULL, TOPLEVEL_ATTR_UNSPEC}
	};
	if (strncmp(state, "-", 1) == 0) {
		*enabled = false;
		state += 1;
	} else if (
		strncmp(state, "in", 2) == 0 ||
		strncmp(state, "un", 2) == 0 ) {
		*enabled = false;
		state += 2;
	} else {
		*enabled = true;
	}
	return matchtok(states, state);
}

static void
append(struct wl_array *arr, char *str)
{
	char **p = wl_array_add(arr, sizeof (char *));
	if (!p) {
		die("Could not allocate pointer for matchspec\n");
	} else {
		*p = str;
	}
}

static bool
contains_value(struct wl_array *arr, int value) {
	if (!value) {
		return false;
	}

	int *cursor;
	wl_array_for_each(cursor, arr) {
		if (*cursor == value) {
			return true;
		}
	}
	return false;
}

static bool
contains_str(struct wl_array *arr, char *str)
{
	if (!str) {
		return false;
	}

	char **cursor;
	wl_array_for_each(cursor, arr) {
		if (strcmp(str, *cursor) == 0) {
			return true;
		}
	}
	return false;
}

static void
matchspec_init(struct toplevel_matchspec *matchspec)
{
	wl_array_init(&matchspec->app_ids);
	wl_array_init(&matchspec->titles);
}

static void
matchspec_release(struct toplevel_matchspec *matchspec)
{
	wl_array_release(&matchspec->app_ids);
	wl_array_release(&matchspec->titles);
}

static void
matchspec_add_match(struct toplevel_matchspec *matchspec, char *match)
{
	char *value = match;
	char *attr = strsep(&value, ":");
	if (!value) {
		matchspec->attrs |= TOPLEVEL_ATTR_APPID;
		append(&matchspec->app_ids, attr);
		return;
	}

	bool enabled = true;
	struct token attrs[] = {
		{"app-id", TOPLEVEL_ATTR_APPID         },
		{"app_id", TOPLEVEL_ATTR_APPID         },
		{"title",  TOPLEVEL_ATTR_TITLE         },
		{"state",  parse_state(value, &enabled)},
		{NULL, TOPLEVEL_ATTR_UNSPEC}
	};
	enum toplevel_attr pattr = matchtok(attrs, attr);

	switch (pattr) {
	case TOPLEVEL_ATTR_APPID:
		matchspec->attrs |= pattr;
		append(&matchspec->app_ids, value);
		return;
	case TOPLEVEL_ATTR_TITLE:
		matchspec->attrs |= pattr;
		append(&matchspec->titles, value);
		return;
	case TOPLEVEL_ATTR_MAXIMIZED:
		matchspec->attrs |= pattr;
		matchspec->maximized = enabled;
		break;
	case TOPLEVEL_ATTR_MINIMIZED:
		matchspec->attrs |= pattr;
		matchspec->minimized = enabled;
		break;
	case TOPLEVEL_ATTR_ACTIVATED:
		matchspec->attrs |= pattr;
		matchspec->activated = enabled;
		break;
	case TOPLEVEL_ATTR_FULLSCREEN:
		matchspec->attrs |= pattr;
		matchspec->fullscreen = enabled;
		break;
	case TOPLEVEL_ATTR_UNSPEC:
	default:
		die("Unknown attribute: '%s:%s'\n", attr, value);
	}

	return;
}

static bool
is_matched(struct toplevel_data *data)
{
	struct toplevel_matchspec *matchspec = &data->cmd->matchspec;
	if (matchspec->attrs & TOPLEVEL_ATTR_APPID) {
		if (!contains_str(&matchspec->app_ids, data->app_id)) {
			return false;
		}
	}
	if (matchspec->attrs & TOPLEVEL_ATTR_TITLE) {
		if (!contains_str(&matchspec->titles, data->title)) {
			return false;
		}
	}
	if (matchspec->attrs & TOPLEVEL_ATTR_MAXIMIZED) {
		if (contains_value(&data->state,
			ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED) ^
			matchspec->maximized) {
			return false;
		}
	}
	if (matchspec->attrs & TOPLEVEL_ATTR_MINIMIZED) {
		if (contains_value(&data->state,
			ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MINIMIZED) ^
			matchspec->minimized) {
			return false;
		}
	}
	if (matchspec->attrs & TOPLEVEL_ATTR_ACTIVATED) {
		if (contains_value(&data->state,
			ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED) ^
			matchspec->activated) {
			return false;
		}
	}
	if (matchspec->attrs & TOPLEVEL_ATTR_FULLSCREEN) {
		if (contains_value(&data->state,
			ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN) ^
			matchspec->fullscreen) {
			return false;
		}
	}
	return true;
}

struct toplevel_data *
toplevel_data_create(struct wlrctl_toplevel_command *cmd)
{
	struct toplevel_data *data = calloc(1, sizeof (struct toplevel_data));
	if (!data) {
		die("Failed to allocate toplevel data\n");
	}
	
	wl_array_init(&data->state);
	data->cmd = cmd;
	wl_list_insert(&cmd->toplevels, &data->link);

	return data;
}

void
toplevel_data_destroy(struct toplevel_data *data)
{
	free(data->app_id);
	free(data->title);
	wl_array_release(&data->state);
	free(data);
}

static void
zwlr_foreign_toplevel_handle_v1_handle_title(void *user_data,
	struct zwlr_foreign_toplevel_handle_v1 *toplevel,
	const char *title
	)
{
	struct toplevel_data *data = user_data;
	data->title = strdup(title);
}

static void
zwlr_foreign_toplevel_handle_v1_handle_app_id(void *user_data,
	struct zwlr_foreign_toplevel_handle_v1 *toplevel,
	const char *app_id
	)
{
	struct toplevel_data *data = user_data;
	data->app_id = strdup(app_id);
}

static void
zwlr_foreign_toplevel_handle_v1_handle_state(void *user_data,
	struct zwlr_foreign_toplevel_handle_v1 *toplevel,
	struct wl_array *state
	)
{
	struct toplevel_data *data = user_data;
	wl_array_copy(&data->state, state);
}

static void
zwlr_foreign_toplevel_handle_v1_handle_done(void *user_data,
	struct zwlr_foreign_toplevel_handle_v1 *toplevel
	)
{
	struct toplevel_data *data = user_data;
	if (data->cmd->action != TOPLEVEL_ACTION_WAITFOR && data->done) {
		return;
	} else {
		data->done = true;
	}

	if (data->cmd->complete || !is_matched(data)) {
		return;
	} else {
		data->cmd->any = true;
		data->matched = true;
	}

	switch (data->cmd->action) {
	case TOPLEVEL_ACTION_MINIMIZE:
		zwlr_foreign_toplevel_handle_v1_set_minimized(toplevel);
		break;
	case TOPLEVEL_ACTION_MAXIMIZE:
		zwlr_foreign_toplevel_handle_v1_set_maximized(toplevel);
		break;
	case TOPLEVEL_ACTION_ACTIVATE:
		zwlr_foreign_toplevel_handle_v1_activate(toplevel, data->cmd->state->seat);
		data->cmd->complete = true;
		stop_toplevel(data->cmd->state);
		break;
	case TOPLEVEL_ACTION_FULLSCREEN:
		zwlr_foreign_toplevel_handle_v1_set_fullscreen(toplevel, NULL);
		break;
	case TOPLEVEL_ACTION_CLOSE:
		zwlr_foreign_toplevel_handle_v1_close(toplevel);
		break;
	case TOPLEVEL_ACTION_LIST:
		if (data->app_id) {
			printf("%s: %s\n", data->app_id, data->title ? data->title : "");
		}
		break;
	case TOPLEVEL_ACTION_FIND:
	case TOPLEVEL_ACTION_WAITFOR:
		data->cmd->complete = true;
		stop_toplevel(data->cmd->state);
		break;
	case TOPLEVEL_ACTION_WAIT:
		data->cmd->waiting++;
		break;
	case TOPLEVEL_ACTION_UNSPEC:
		// unreachable
		assert(false);
	}
}

static void
zwlr_foreign_toplevel_handle_v1_handle_closed(
	void *user_data, struct zwlr_foreign_toplevel_handle_v1 *toplevel)
{
	struct toplevel_data *data = user_data;
	zwlr_foreign_toplevel_handle_v1_destroy(toplevel);
	if (data->cmd->complete || !data->matched) {
		return;
	}
	if (data->cmd->action == TOPLEVEL_ACTION_WAIT) {
		data->cmd->waiting--;
		if (data->cmd->waiting <= 0) {
			data->cmd->complete = true;
			stop_toplevel(data->cmd->state);
		}
	}
}

static void
zwlr_foreign_toplevel_handle_v1_handle_parent(
	void *user_data, struct zwlr_foreign_toplevel_handle_v1 *toplevel,
	struct zwlr_foreign_toplevel_handle_v1 *parent)
{
	struct toplevel_data *data = user_data;
	data->parent = parent;
}

static struct zwlr_foreign_toplevel_handle_v1_listener
zwlr_foreign_toplevel_handle_v1_listener = {
	.title = zwlr_foreign_toplevel_handle_v1_handle_title,
	.app_id = zwlr_foreign_toplevel_handle_v1_handle_app_id,
	.output_enter = noop,
	.output_leave = noop,
	.state = zwlr_foreign_toplevel_handle_v1_handle_state,
	.done = zwlr_foreign_toplevel_handle_v1_handle_done,
	.closed = zwlr_foreign_toplevel_handle_v1_handle_closed,
	.parent = zwlr_foreign_toplevel_handle_v1_handle_parent,
};

static void
zwlr_foreign_toplevel_manager_v1_handle_toplevel(
	void *data,
	struct zwlr_foreign_toplevel_manager_v1 *manager,
	struct zwlr_foreign_toplevel_handle_v1 *toplevel
	)
{
	struct wlrctl *state = data;
	struct wlrctl_toplevel_command *cmd = state->cmd;
	struct toplevel_data *toplevel_data = toplevel_data_create(cmd);
	zwlr_foreign_toplevel_handle_v1_add_listener(
		toplevel,
		&zwlr_foreign_toplevel_handle_v1_listener,
		toplevel_data
	);
}

static void
zwlr_foreign_toplevel_manager_v1_handle_finished(
	void *data,
	struct zwlr_foreign_toplevel_manager_v1 *manager
	)
{
	struct wlrctl *state = data;
	state->running = false;
	destroy_toplevel(state);
}

static struct zwlr_foreign_toplevel_manager_v1_listener
zwlr_foreign_toplevel_manager_v1_listener = {
	.toplevel = zwlr_foreign_toplevel_manager_v1_handle_toplevel,
	.finished = zwlr_foreign_toplevel_manager_v1_handle_finished,
};

void
prepare_toplevel(struct wlrctl *state, int argc, char *argv[])
{
	struct wlrctl_toplevel_command *cmd = calloc(1, sizeof (struct wlrctl_toplevel_command));
	assert(cmd);

	wl_list_init(&cmd->toplevels);
	matchspec_init(&cmd->matchspec);

	if (argc == 0) {
		die("Missing toplevel action\n");
	}

	char *action = argv[0];
	cmd->action = parse_action(action);
	if (!cmd->action) {
		die("Unknown toplevel action: '%s'\n", action);
	}

	for (int i = 1; i < argc; i++) {
		matchspec_add_match(&cmd->matchspec, argv[i]);
	}

	state->cmd = cmd;
	cmd->state = state;
}

void
stop_toplevel(struct wlrctl *state)
{
	zwlr_foreign_toplevel_manager_v1_stop(state->ftl_mgr);
}

void
complete_toplevel(void *data, struct wl_callback *callback, uint32_t serial)
{
	struct wlrctl *state = data;
	struct wlrctl_toplevel_command *cmd = state->cmd;
	wl_callback_destroy(callback);
	if (cmd->action == TOPLEVEL_ACTION_WAITFOR ||
		(cmd->action == TOPLEVEL_ACTION_WAIT && (cmd->waiting > 0))) {
		return;
	}
	if (!cmd->complete) {
		cmd->complete = true;
		cmd->state->failed = !cmd->any;
		stop_toplevel(state);
	}
}

static struct wl_callback_listener complete_listener = {
	.done = complete_toplevel
};

void
run_toplevel(struct wlrctl *state)
{
	struct wlrctl_toplevel_command *cmd = state->cmd;
	zwlr_foreign_toplevel_manager_v1_add_listener(
		state->ftl_mgr,
		&zwlr_foreign_toplevel_manager_v1_listener,
		state
	);
	if (cmd->action == TOPLEVEL_ACTION_LIST) {
		stop_toplevel(state);
	} else {
		struct wl_callback *complete = wl_display_sync(state->display);
		wl_callback_add_listener(complete, &complete_listener, state);
	}
}

void
destroy_toplevel(struct wlrctl *state)
{
	struct wlrctl_toplevel_command *cmd = state->cmd;

	matchspec_release(&cmd->matchspec);

	// Release toplevels
	struct toplevel_data *data, *tmp;
	wl_list_for_each_safe(data, tmp, &cmd->toplevels, link) {
		wl_list_remove(&data->link);
		toplevel_data_destroy(data);
	}
	free(cmd);
}
0707010000001B000081A400000000000000000000000164632F3500000283000000000000000000000000000000000000001600000000wlrctl-0.2.2~0/util.c#define _POSIX_C_SOURCE 200112L
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
#include "util.h"

int
matchtok(const struct token tokens[], const char *name)
{
	const struct token *tok;
	for (tok = tokens; tok->name != NULL; tok++) {
		if (strcmp(tok->name, name) == 0) {
			break;
		}
	}
	return tok->value;
}

int
timestamp()
{
	struct timespec tp;
	clock_gettime(CLOCK_MONOTONIC, &tp);
	int ms = 1000 * tp.tv_sec + tp.tv_nsec / 1000000;
	return ms;
}

void
die(const char *fmt, ...)
{
	va_list args;
	va_start(args, fmt);
	vfprintf(stderr, fmt, args);
	va_end(args);
	exit(EXIT_FAILURE);
}
0707010000001C000081A400000000000000000000000164632F3500000B6B000000000000000000000000000000000000001C00000000wlrctl-0.2.2~0/wlrctl.1.scdwlrctl(1)

# NAME

wlrctl - A command line utility for miscellaneous wlroots extensions

# SYNOPSIS

wlrctl [options...] [command]

# OPTIONS

*-h, --help*
	Show a help message and quit.

*-v, --version*
	Show the wlrctl version and quit.

# COMMANDS

*keyboard* <action>
	Use a virtual keyboard.

*pointer* <action>
	Use a virtual pointer device.

*window|toplevel* <action>
	Use the foreign toplevel interface.

*output* { <action> | <identifier> [config_action] }
	Use the output management interface.

# KEYBOARD ACTIONS

*type* <string> [modifiers ...]
	Send a string to be typed into the focused client

	*modifiers* <SHIFT,CTRL,ALT,SUPER>
	Comma-separated list of modifiers that will be depressed on the
	virtual keyboard while string is being typed.

# POINTER ACTIONS

*click* [button]
	Click a mouse button. If unspecified, clicks the default (left) button.

*move* <dx> <dy>
	Move the cursor. _dx_ is the displacement in positive-right direction,
	_dy_ is the displacement in the positive-downward direction. Negative
	numbers are allowed. Units are pixels.

*scroll* <dy> <dx>
	Scroll the cursor. _dy_ is the amount of vertical scroll, _dx_ is the
	amount of horizontal scroll. Negative numbers are allowed.

# TOPLEVEL ACTIONS

*minimize* [matches...]
	Instruct the compositor to minimize matching windows.

*maximize* [matches...]
	Instruct the compositor to maximize matching windows.

*fullscreen* [matches...]
	Instruct the compositor to fullscreen matching windows.

*focus* [matches...]
	Instruct the compositor to focus matching windows.

*find* [matches...]
	Exit with a successful return code iff there is at least one window
	matching the provided criteria.

*wait* [matches...]
	Wait to return a successful return code until all the matching windows
	have closed. If there are no matches, exit with a failing return code
	immediately.

*waitfor* [matches...]
	Wait to return a successful return code until there is at least one
	window that matches the requested criteria.

# OUTPUT ACTIONS

*list*
	List the names of all known outputs

# TOPLEVEL MATCHSPEC

A match is a colon separated attribute/value pair. e.g. To match a firefox
window, a suitable match value is _app\_id:firefox_. You may give any number of
match specifiers, and a window must match all of them to be considered. If the
app\_id or title keys are specified more than once, a window may match any of
the given values. Otherwise later key value pairs override previous ones. A
match without a key is assumed to be an app_id, so just _firefox_ works in the
example above.

Currently supported attributes are: _app_id_, _title_, and _state_.

Supported state values are: _maximized_, _minimized_, _active_, and
_fullscreen_, and their negations: _unmaximized_, _unminimized_, _inactive_,
and _unfullscreen_.  You can also use a '-' prefix, for example
_state:-fullscreen_.

# AUTHOR

Written by Ronan Pigott <rpigott@berkeley.edu>
07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!216 blocks
openSUSE Build Service is sponsored by