Skip to content

Instantly share code, notes, and snippets.

@twaik
Created August 5, 2019 08:23
Show Gist options
  • Save twaik/e9cf32cba07ccc8ff8dcc100f7440dd2 to your computer and use it in GitHub Desktop.
Save twaik/e9cf32cba07ccc8ff8dcc100f7440dd2 to your computer and use it in GitHub Desktop.
Wayland server protocol c++ scanner
/*
* Copyright © 2008-2011 Kristian Høgsberg
* Copyright © 2011 Intel Corporation
* Copyright © 2015 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* 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.
*/
#include "config.h"
#include "wayland-version.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <getopt.h>
#include <limits.h>
#include <unistd.h>
#if HAVE_LIBXML
#include <libxml/parser.h>
/* Embedded wayland.dtd file, see dtddata.S */
extern char DTD_DATA_begin;
extern int DTD_DATA_len;
#endif
/* Expat must be included after libxml as both want to declare XMLCALL; see
* the Git commit that 'git blame' for this comment points to for more. */
#include <expat.h>
#include "wayland-util.h"
#define PROGRAM_NAME "wayland-scanner"
static int
usage(int ret)
{
fprintf(stderr, "usage: %s [OPTION] [client-header|server-header|private-code|public-code]"
" [input_file output_file]\n", PROGRAM_NAME);
fprintf(stderr, "\n");
fprintf(stderr, "Converts XML protocol descriptions supplied on "
"stdin or input file to client\n"
"headers, server headers, or protocol marshalling code.\n\n"
"Use \"public-code\" only if the marshalling code will be public - "
"aka DSO will export it while other components will be using it.\n"
"Using \"private-code\" is strongly recommended.\n\n");
fprintf(stderr, "options:\n");
fprintf(stderr, " -h, --help display this help and exit.\n"
" -v, --version print the wayland library version that\n"
" the scanner was built against.\n"
" -c, --include-core-only include the core version of the headers,\n"
" that is e.g. wayland-client-core.h instead\n"
" of wayland-client.h.\n"
" -s, --strict exit immediately with an error if DTD\n"
" verification fails.\n");
exit(ret);
}
static int
scanner_version(int ret)
{
fprintf(stderr, "%s %s\n", PROGRAM_NAME, WAYLAND_VERSION);
exit(ret);
}
static bool
is_dtd_valid(FILE *input, const char *filename)
{
bool rc = true;
#if HAVE_LIBXML
xmlParserCtxtPtr ctx = NULL;
xmlDocPtr doc = NULL;
xmlDtdPtr dtd = NULL;
xmlValidCtxtPtr dtdctx;
xmlParserInputBufferPtr buffer;
int fd = fileno(input);
dtdctx = xmlNewValidCtxt();
ctx = xmlNewParserCtxt();
if (!ctx || !dtdctx)
abort();
buffer = xmlParserInputBufferCreateMem(&DTD_DATA_begin,
DTD_DATA_len,
XML_CHAR_ENCODING_UTF8);
if (!buffer) {
fprintf(stderr, "Failed to init buffer for DTD.\n");
abort();
}
dtd = xmlIOParseDTD(NULL, buffer, XML_CHAR_ENCODING_UTF8);
if (!dtd) {
fprintf(stderr, "Failed to parse DTD.\n");
abort();
}
doc = xmlCtxtReadFd(ctx, fd, filename, NULL, 0);
if (!doc) {
fprintf(stderr, "Failed to read XML\n");
abort();
}
rc = xmlValidateDtd(dtdctx, doc, dtd);
xmlFreeDoc(doc);
xmlFreeParserCtxt(ctx);
xmlFreeDtd(dtd);
xmlFreeValidCtxt(dtdctx);
/* xmlIOParseDTD consumes buffer */
if (lseek(fd, 0, SEEK_SET) != 0) {
fprintf(stderr, "Failed to reset fd, output would be garbage.\n");
abort();
}
#endif
return rc;
}
#define XML_BUFFER_SIZE 4096
struct location {
const char *filename;
int line_number;
};
struct protocol {
char *name;
char *uppercase_name;
struct wl_list interface_list;
int type_index;
int null_run_length;
char *copyright;
bool core_headers;
};
struct interface {
struct location loc;
char *name;
char *uppercase_name;
int version;
int since;
struct wl_list request_list;
struct wl_list event_list;
struct wl_list enumeration_list;
struct wl_list link;
};
struct message {
struct location loc;
char *name;
char *uppercase_name;
struct wl_list arg_list;
struct wl_list link;
int arg_count;
int new_id_count;
int type_index;
int all_null;
int destructor;
int since;
};
enum arg_type {
NEW_ID,
INT,
UNSIGNED,
FIXED,
STRING,
OBJECT,
ARRAY,
FD
};
struct arg {
char *name;
enum arg_type type;
int nullable;
char *interface_name;
struct wl_list link;
char *enumeration_name;
};
struct enumeration {
char *name;
char *uppercase_name;
struct wl_list entry_list;
struct wl_list link;
bool bitfield;
int since;
};
struct entry {
char *name;
char *uppercase_name;
char *value;
int since;
struct wl_list link;
};
struct parse_context {
struct location loc;
XML_Parser parser;
struct protocol *protocol;
struct interface *interface;
struct message *message;
struct enumeration *enumeration;
char character_data[8192];
unsigned int character_data_length;
};
static void *
fail_on_null(void *p)
{
if (p == NULL) {
fprintf(stderr, "%s: out of memory\n", PROGRAM_NAME);
exit(EXIT_FAILURE);
}
return p;
}
static void *
zalloc(size_t s)
{
return calloc(s, 1);
}
static void *
xzalloc(size_t s)
{
return fail_on_null(zalloc(s));
}
static char *
xstrdup(const char *s)
{
return fail_on_null(strdup(s));
}
static char *
uppercase_dup(const char *src)
{
char *u;
int i;
u = xstrdup(src);
for (i = 0; u[i]; i++)
u[i] = toupper(u[i]);
u[i] = '\0';
return u;
}
static const char *indent(int n)
{
const char *whitespace[] = {
"\t\t\t\t\t\t\t\t\t\t\t\t",
"\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t ",
"\t\t\t\t\t\t\t\t\t\t\t\t "
};
return whitespace[n % 8] + 12 - n / 8;
}
static void
desc_dump(char *desc, const char *fmt, ...) WL_PRINTF(2, 3);
static void
desc_dump(char *desc, const char *fmt, ...)
{
/*va_list ap;
char buf[128], hang;
int col, i, j, k, startcol, newlines;
va_start(ap, fmt);
vsnprintf(buf, sizeof buf, fmt, ap);
va_end(ap);
for (i = 0, col = 0; buf[i] != '*'; i++) {
if (buf[i] == '\t')
col = (col + 8) & ~7;
else
col++;
}
printf("%s", buf);
if (!desc) {
printf("(none)\n");
return;
}
startcol = col;
col += strlen(&buf[i]);
if (col - startcol > 2)
hang = '\t';
else
hang = ' ';
for (i = 0; desc[i]; ) {
k = i;
newlines = 0;
while (desc[i] && isspace(desc[i])) {
if (desc[i] == '\n')
newlines++;
i++;
}
if (!desc[i])
break;
j = i;
while (desc[i] && !isspace(desc[i]))
i++;
if (newlines > 1)
printf("\n%s*", indent(startcol));
if (newlines > 1 || col + i - j > 72) {
printf("\n%s*%c", indent(startcol), hang);
col = startcol;
}
if (col > startcol && k > 0)
col += printf(" ");
col += printf("%.*s", i - j, &desc[j]);
}
putchar('\n');*/
}
static void __attribute__ ((noreturn))
fail(struct location *loc, const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
fprintf(stderr, "%s:%d: error: ",
loc->filename, loc->line_number);
vfprintf(stderr, msg, ap);
fprintf(stderr, "\n");
va_end(ap);
exit(EXIT_FAILURE);
}
static void
warn(struct location *loc, const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
fprintf(stderr, "%s:%d: warning: ",
loc->filename, loc->line_number);
vfprintf(stderr, msg, ap);
fprintf(stderr, "\n");
va_end(ap);
}
static bool
is_nullable_type(struct arg *arg)
{
switch (arg->type) {
/* Strings, objects, and arrays are possibly nullable */
case STRING:
case OBJECT:
case NEW_ID:
case ARRAY:
return true;
default:
return false;
}
}
static struct message *
create_message(struct location loc, const char *name)
{
struct message *message;
message = xzalloc(sizeof *message);
message->loc = loc;
message->name = xstrdup(name);
message->uppercase_name = uppercase_dup(name);
wl_list_init(&message->arg_list);
return message;
}
static void
free_arg(struct arg *arg)
{
free(arg->name);
free(arg->interface_name);
free(arg->enumeration_name);
free(arg);
}
static struct arg *
create_arg(const char *name)
{
struct arg *arg;
arg = xzalloc(sizeof *arg);
arg->name = xstrdup(name);
return arg;
}
static bool
set_arg_type(struct arg *arg, const char *type)
{
if (strcmp(type, "int") == 0)
arg->type = INT;
else if (strcmp(type, "uint") == 0)
arg->type = UNSIGNED;
else if (strcmp(type, "fixed") == 0)
arg->type = FIXED;
else if (strcmp(type, "string") == 0)
arg->type = STRING;
else if (strcmp(type, "array") == 0)
arg->type = ARRAY;
else if (strcmp(type, "fd") == 0)
arg->type = FD;
else if (strcmp(type, "new_id") == 0)
arg->type = NEW_ID;
else if (strcmp(type, "object") == 0)
arg->type = OBJECT;
else
return false;
return true;
}
static void
free_message(struct message *message)
{
struct arg *a, *a_next;
free(message->name);
free(message->uppercase_name);
wl_list_for_each_safe(a, a_next, &message->arg_list, link)
free_arg(a);
free(message);
}
static struct enumeration *
create_enumeration(const char *name)
{
struct enumeration *enumeration;
enumeration = xzalloc(sizeof *enumeration);
enumeration->name = xstrdup(name);
enumeration->uppercase_name = uppercase_dup(name);
enumeration->since = 1;
wl_list_init(&enumeration->entry_list);
return enumeration;
}
static struct entry *
create_entry(const char *name, const char *value)
{
struct entry *entry;
entry = xzalloc(sizeof *entry);
entry->name = xstrdup(name);
entry->uppercase_name = uppercase_dup(name);
entry->value = xstrdup(value);
return entry;
}
static void
free_entry(struct entry *entry)
{
free(entry->name);
free(entry->uppercase_name);
free(entry->value);
free(entry);
}
static void
free_enumeration(struct enumeration *enumeration)
{
struct entry *e, *e_next;
free(enumeration->name);
free(enumeration->uppercase_name);
wl_list_for_each_safe(e, e_next, &enumeration->entry_list, link)
free_entry(e);
free(enumeration);
}
static struct interface *
create_interface(struct location loc, const char *name, int version)
{
struct interface *interface;
interface = xzalloc(sizeof *interface);
interface->loc = loc;
interface->name = xstrdup(name);
interface->uppercase_name = uppercase_dup(name);
interface->version = version;
interface->since = 1;
wl_list_init(&interface->request_list);
wl_list_init(&interface->event_list);
wl_list_init(&interface->enumeration_list);
return interface;
}
static void
free_interface(struct interface *interface)
{
struct message *m, *next_m;
struct enumeration *e, *next_e;
free(interface->name);
free(interface->uppercase_name);
wl_list_for_each_safe(m, next_m, &interface->request_list, link)
free_message(m);
wl_list_for_each_safe(m, next_m, &interface->event_list, link)
free_message(m);
wl_list_for_each_safe(e, next_e, &interface->enumeration_list, link)
free_enumeration(e);
free(interface);
}
/* Convert string to unsigned integer
*
* Parses a non-negative base-10 number from the given string. If the
* specified string is blank, contains non-numerical characters, is out
* of range, or results in a negative number, -1 is returned to indicate
* an error.
*
* Upon error, this routine does not modify or set errno.
*
* Returns -1 on error, or a non-negative integer on success
*/
static int
strtouint(const char *str)
{
long int ret;
char *end;
int prev_errno = errno;
errno = 0;
ret = strtol(str, &end, 10);
if (errno != 0 || end == str || *end != '\0')
return -1;
/* check range */
if (ret < 0 || ret > INT_MAX) {
return -1;
}
errno = prev_errno;
return (int)ret;
}
static int
version_from_since(struct parse_context *ctx, const char *since)
{
int version;
if (since != NULL) {
version = strtouint(since);
if (version == -1) {
fail(&ctx->loc, "invalid integer (%s)\n", since);
} else if (version > ctx->interface->version) {
fail(&ctx->loc, "since (%u) larger than version (%u)\n",
version, ctx->interface->version);
}
} else {
version = 1;
}
return version;
}
static int is_interface_blacklisted(const char *iname) {
if (!iname) return 0;
if (
!strcmp(iname, "wl_display") ||
//!strcmp(iname, "wl_callback") ||
!strcmp(iname, "wl_registry") ||
!strcmp(iname, "wl_shm") ||
!strcmp(iname, "wl_shm_pool") ||
0) return 1;
return 0;
}
static void
start_element(void *data, const char *element_name, const char **atts)
{
struct parse_context *ctx = data;
struct interface *interface;
struct message *message;
struct arg *arg;
struct enumeration *enumeration;
struct entry *entry;
const char *name = NULL;
const char *type = NULL;
const char *interface_name = NULL;
const char *value = NULL;
const char *summary = NULL;
const char *since = NULL;
const char *allow_null = NULL;
const char *enumeration_name = NULL;
const char *bitfield = NULL;
int i, version = 0;
ctx->loc.line_number = XML_GetCurrentLineNumber(ctx->parser);
for (i = 0; atts[i]; i += 2) {
if (strcmp(atts[i], "name") == 0)
name = atts[i + 1];
if (strcmp(atts[i], "version") == 0) {
version = strtouint(atts[i + 1]);
if (version == -1)
fail(&ctx->loc, "wrong version (%s)", atts[i + 1]);
}
if (strcmp(atts[i], "type") == 0)
type = atts[i + 1];
if (strcmp(atts[i], "value") == 0)
value = atts[i + 1];
if (strcmp(atts[i], "interface") == 0)
interface_name = atts[i + 1];
if (strcmp(atts[i], "summary") == 0)
summary = atts[i + 1];
if (strcmp(atts[i], "since") == 0)
since = atts[i + 1];
if (strcmp(atts[i], "allow-null") == 0)
allow_null = atts[i + 1];
if (strcmp(atts[i], "enum") == 0)
enumeration_name = atts[i + 1];
if (strcmp(atts[i], "bitfield") == 0)
bitfield = atts[i + 1];
}
ctx->character_data_length = 0;
if (strcmp(element_name, "protocol") == 0) {
if (name == NULL)
fail(&ctx->loc, "no protocol name given");
ctx->protocol->name = xstrdup(name);
ctx->protocol->uppercase_name = uppercase_dup(name);
} else if (strcmp(element_name, "interface") == 0) {
if (name == NULL)
fail(&ctx->loc, "no interface name given");
if (version == 0)
fail(&ctx->loc, "no interface version given");
interface = create_interface(ctx->loc, name, version);
ctx->interface = interface;
if (!is_interface_blacklisted(name))
wl_list_insert(ctx->protocol->interface_list.prev,
&interface->link);
} else if (strcmp(element_name, "request") == 0 ||
strcmp(element_name, "event") == 0) {
if (is_interface_blacklisted(interface_name)) return;
if (name == NULL)
fail(&ctx->loc, "no request name given");
message = create_message(ctx->loc, name);
if (strcmp(element_name, "request") == 0)
wl_list_insert(ctx->interface->request_list.prev,
&message->link);
else
wl_list_insert(ctx->interface->event_list.prev,
&message->link);
if (type != NULL && strcmp(type, "destructor") == 0)
message->destructor = 1;
version = version_from_since(ctx, since);
if (version < ctx->interface->since)
warn(&ctx->loc, "since version not increasing\n");
ctx->interface->since = version;
message->since = version;
if (strcmp(name, "destroy") == 0 && !message->destructor)
fail(&ctx->loc, "destroy request should be destructor type");
ctx->message = message;
} else if (strcmp(element_name, "arg") == 0) {
if (is_interface_blacklisted(interface_name)) return;
if (name == NULL)
fail(&ctx->loc, "no argument name given");
arg = create_arg(name);
if (!set_arg_type(arg, type))
fail(&ctx->loc, "unknown type (%s)", type);
switch (arg->type) {
case NEW_ID:
ctx->message->new_id_count++;
/* fallthrough */
case OBJECT:
if (interface_name)
arg->interface_name = xstrdup(interface_name);
break;
default:
if (interface_name != NULL)
fail(&ctx->loc, "interface attribute not allowed for type %s", type);
break;
}
if (allow_null) {
if (strcmp(allow_null, "true") == 0)
arg->nullable = 1;
else if (strcmp(allow_null, "false") != 0)
fail(&ctx->loc,
"invalid value for allow-null attribute (%s)",
allow_null);
if (!is_nullable_type(arg))
fail(&ctx->loc,
"allow-null is only valid for objects, strings, and arrays");
}
if (enumeration_name == NULL || strcmp(enumeration_name, "") == 0)
arg->enumeration_name = NULL;
else
arg->enumeration_name = xstrdup(enumeration_name);
wl_list_insert(ctx->message->arg_list.prev, &arg->link);
ctx->message->arg_count++;
} else if (strcmp(element_name, "enum") == 0) {
if (is_interface_blacklisted(interface_name)) return;
if (name == NULL)
fail(&ctx->loc, "no enum name given");
enumeration = create_enumeration(name);
if (bitfield == NULL || strcmp(bitfield, "false") == 0)
enumeration->bitfield = false;
else if (strcmp(bitfield, "true") == 0)
enumeration->bitfield = true;
else
fail(&ctx->loc,
"invalid value (%s) for bitfield attribute (only true/false are accepted)",
bitfield);
wl_list_insert(ctx->interface->enumeration_list.prev,
&enumeration->link);
ctx->enumeration = enumeration;
} else if (strcmp(element_name, "entry") == 0) {
if (is_interface_blacklisted(interface_name)) return;
if (name == NULL)
fail(&ctx->loc, "no entry name given");
entry = create_entry(name, value);
version = version_from_since(ctx, since);
if (version < ctx->enumeration->since)
warn(&ctx->loc, "since version not increasing\n");
ctx->enumeration->since = version;
entry->since = version;
wl_list_insert(ctx->enumeration->entry_list.prev,
&entry->link);
}
}
static struct enumeration *
find_enumeration(struct protocol *protocol,
struct interface *interface,
char *enum_attribute)
{
struct interface *i;
struct enumeration *e;
char *enum_name;
uint32_t idx = 0, j;
for (j = 0; j + 1 < strlen(enum_attribute); j++) {
if (enum_attribute[j] == '.') {
idx = j;
}
}
if (idx > 0) {
enum_name = enum_attribute + idx + 1;
wl_list_for_each(i, &protocol->interface_list, link)
if (strncmp(i->name, enum_attribute, idx) == 0)
wl_list_for_each(e, &i->enumeration_list, link)
if (strcmp(e->name, enum_name) == 0)
return e;
} else if (interface) {
enum_name = enum_attribute;
wl_list_for_each(e, &interface->enumeration_list, link)
if (strcmp(e->name, enum_name) == 0)
return e;
}
return NULL;
}
static void
verify_arguments(struct parse_context *ctx,
struct interface *interface,
struct wl_list *messages,
struct wl_list *enumerations)
{
struct message *m;
wl_list_for_each(m, messages, link) {
struct arg *a;
wl_list_for_each(a, &m->arg_list, link) {
struct enumeration *e;
if (!a->enumeration_name)
continue;
e = find_enumeration(ctx->protocol, interface,
a->enumeration_name);
switch (a->type) {
case INT:
if (e && e->bitfield)
fail(&ctx->loc,
"bitfield-style enum must only be referenced by uint");
break;
case UNSIGNED:
break;
default:
fail(&ctx->loc,
"enumeration-style argument has wrong type");
}
}
}
}
static void
end_element(void *data, const XML_Char *name)
{
struct parse_context *ctx = data;
if (strcmp(name, "copyright") == 0) {
ctx->protocol->copyright =
strndup(ctx->character_data,
ctx->character_data_length);
} else if (strcmp(name, "description") == 0) {
} else if (strcmp(name, "request") == 0 ||
strcmp(name, "event") == 0) {
ctx->message = NULL;
} else if (strcmp(name, "enum") == 0) {
if (wl_list_empty(&ctx->enumeration->entry_list)) {
fail(&ctx->loc, "enumeration %s was empty",
ctx->enumeration->name);
}
ctx->enumeration = NULL;
} else if (strcmp(name, "protocol") == 0) {
struct interface *i;
wl_list_for_each(i, &ctx->protocol->interface_list, link) {
verify_arguments(ctx, i, &i->request_list, &i->enumeration_list);
verify_arguments(ctx, i, &i->event_list, &i->enumeration_list);
}
}
}
static void
character_data(void *data, const XML_Char *s, int len)
{
struct parse_context *ctx = data;
if (ctx->character_data_length + len > sizeof (ctx->character_data)) {
fprintf(stderr, "too much character data");
exit(EXIT_FAILURE);
}
memcpy(ctx->character_data + ctx->character_data_length, s, len);
ctx->character_data_length += len;
}
static void
emit_type(struct arg *a)
{
switch (a->type) {
default:
case INT:
case FD:
printf("int32_t ");
break;
case NEW_ID:
case UNSIGNED:
printf("uint32_t ");
break;
case FIXED:
printf("wl_fixed_t ");
break;
case STRING:
printf("const char *");
break;
case OBJECT:
printf("struct %s *", a->interface_name);
break;
case ARRAY:
printf("struct wl_array *");
break;
}
}
static void
emit_header_classes(struct wl_list *message_list_requests, struct wl_list *message_list_events, struct interface *interface)
{
struct message *m;
struct arg *a;
int n;
if (wl_list_empty(message_list_requests) && wl_list_empty(message_list_events))
return;
printf("class %s_t : public wl_resource_t {\n", interface->name);
printf("public:\n");
printf("\tvoid init() override;\n");
if (!wl_list_empty(message_list_requests)) {
wl_list_for_each(m, message_list_requests, link) {
printf("\tvirtual void request_%s(", m->name);
n = strlen(m->name) + 35;
wl_list_for_each(a, &m->arg_list, link) {
if (&a->link != m->arg_list.next)
printf(",\n%s", indent(n));
if (a->type == OBJECT)
printf("struct wl_resource *");
else if (a->type == NEW_ID && a->interface_name == NULL)
printf("const char *interface, uint32_t version, uint32_t ");
else
emit_type(a);
printf("%s", a->name);
}
printf(") = 0;\n");
}
}
if (!wl_list_empty(message_list_events)) {
wl_list_for_each(m, message_list_events, link) {
printf("\tvoid send_%s(", m->name);
wl_list_for_each(a, &m->arg_list, link) {
if (&a->link != m->arg_list.next)
printf(", ");
switch (a->type) {
case NEW_ID:
case OBJECT:
printf("struct wl_resource *");
break;
default:
emit_type(a);
}
printf("%s", a->name);
}
printf(");\n");
}
}
printf("};\n\n");
}
static void emit_code_init(struct wl_list *message_list_requests, struct wl_list *message_list_events, struct interface *interface)
{
printf("void %s_t::init() {\n", interface->name);
printf("\tinterface = &::%s_interface;\n", interface->name);
printf("\tversion = %d;\n", interface->version);
printf("\timplementation = ");
if (!wl_list_empty(message_list_requests)) printf("&%s_interface_implementation;\n", interface->name);
else printf("nullptr;\n");
printf("}\n\n");
}
static void
emit_source_classes(struct wl_list *message_list_requests, struct wl_list *message_list_events, struct interface *interface)
{
struct message *m;
struct arg *a;
int n;
if (!wl_list_empty(message_list_requests)) {
printf("\n");
wl_list_for_each(m, message_list_requests, link) {
printf("static void %s_request_%s(struct wl_client *client, struct wl_resource *resource", interface->name, m->name);
wl_list_for_each(a, &m->arg_list, link) {
printf(", ");
switch (a->type) {
case OBJECT:
printf("struct wl_resource *");
break;
default:
emit_type(a);
}
printf("%s", a->name);
}
printf(") {\n");
printf("\t%s_t* res = static_cast<%s_t*>(wl_resource_get_user_data(resource));\n", interface->name, interface->name);
printf("\tif (res == nullptr) return;\n\n");
printf("\tres->request_%s(", m->name);
wl_list_for_each(a, &m->arg_list, link) {
if (&a->link != m->arg_list.next)
printf(", ");
printf("%s", a->name);
}
printf(");\n}\n");
}
}
if (!wl_list_empty(message_list_requests)) {
printf("\n\nstruct %s_interface %s_interface_implementation = {\n", interface->name, interface->name);
wl_list_for_each(m, message_list_requests, link) {
printf("\t%s_request_%s", interface->name, m->name);
if (m->link.next != (message_list_requests))
printf(",");
printf("\n");
}
printf("};\n");
}
if (!wl_list_empty(message_list_events)) {
printf("\n");
wl_list_for_each(m, message_list_events, link) {
printf("void %s_t::send_%s(", interface->name, m->name);
wl_list_for_each(a, &m->arg_list, link) {
if (&a->link != m->arg_list.next)
printf(", ");
switch (a->type) {
case NEW_ID:
case OBJECT:
printf("struct wl_resource *");
break;
default:
emit_type(a);
}
printf("%s", a->name);
}
printf(") {\n");
printf("\t if (resource == nullptr) return;\n");
printf("\t %s_send_%s(resource", interface->name, m->name);
wl_list_for_each(a, &m->arg_list, link) {
printf(", %s", a->name);
}
printf(");\n}\n");
}
}
}
static void
emit_structs(struct wl_list *message_list, struct interface *interface)
{
struct message *m;
struct arg *a;
int n;
if (wl_list_empty(message_list))
return;
printf("struct %s_%s {\n", interface->name, "interface");
wl_list_for_each(m, message_list, link) {
printf("\tvoid (*%s)(", m->name);
n = strlen(m->name) + 17;
printf("struct wl_client *client,\n"
"%sstruct wl_resource *resource",
indent(n));
wl_list_for_each(a, &m->arg_list, link) {
printf(",\n%s", indent(n));
if (a->type == OBJECT)
printf("struct wl_resource *");
else if (a->type == NEW_ID && a->interface_name == NULL)
printf("void *");
else if (a->type == NEW_ID)
printf("struct %s *", a->interface_name);
else
emit_type(a);
printf("%s", a->name);
}
printf(");\n");
}
printf("};\n\n");
}
static void
emit_types_forward_declarations(struct protocol *protocol,
struct wl_list *message_list,
struct wl_array *types)
{
struct message *m;
struct arg *a;
int length;
char **p;
wl_list_for_each(m, message_list, link) {
length = 0;
m->all_null = 1;
wl_list_for_each(a, &m->arg_list, link) {
length++;
switch (a->type) {
case NEW_ID:
case OBJECT:
if (!a->interface_name)
continue;
m->all_null = 0;
p = fail_on_null(wl_array_add(types, sizeof *p));
*p = a->interface_name;
break;
default:
break;
}
}
if (m->all_null && length > protocol->null_run_length)
protocol->null_run_length = length;
}
}
static void
emit_header(struct protocol *protocol)
{
struct interface *i, *i_next;
struct wl_array types;
char **p, *prev;
printf("#pragma once\n");
printf("#include <wayland-server.hpp>\n");
wl_array_init(&types);
wl_list_for_each(i, &protocol->interface_list, link) {
emit_types_forward_declarations(protocol, &i->request_list, &types);
emit_types_forward_declarations(protocol, &i->event_list, &types);
}
wl_list_for_each(i, &protocol->interface_list, link) {
p = fail_on_null(wl_array_add(&types, sizeof *p));
*p = i->name;
}
wl_list_for_each_safe(i, i_next, &protocol->interface_list, link) {
emit_header_classes(&i->request_list, &i->event_list, i);
}
printf("\n");
wl_list_for_each_safe(i, i_next, &protocol->interface_list, link) {
printf("struct %s_interface;\n", i->name);
}
printf("\n");
wl_list_for_each_safe(i, i_next, &protocol->interface_list, link) {
if (!wl_list_empty(&i->request_list))
printf("extern struct %s_interface %s_interface_implementation;\n", i->name, i->name);
}
printf("\n");
}
static void
emit_null_run(struct protocol *protocol)
{
int i;
for (i = 0; i < protocol->null_run_length; i++)
printf("\tNULL,\n");
}
static void
emit_types(struct protocol *protocol, struct wl_list *message_list)
{
struct message *m;
struct arg *a;
wl_list_for_each(m, message_list, link) {
if (m->all_null) {
m->type_index = 0;
continue;
}
m->type_index =
protocol->null_run_length + protocol->type_index;
protocol->type_index += m->arg_count;
wl_list_for_each(a, &m->arg_list, link) {
switch (a->type) {
case NEW_ID:
case OBJECT:
if (a->interface_name)
printf("\t&%s_interface,\n",
a->interface_name);
else
printf("\tNULL,\n");
break;
default:
printf("\tNULL,\n");
break;
}
}
}
}
static void
emit_messages(struct wl_list *message_list,
struct interface *interface, const char *suffix)
{
struct message *m;
struct arg *a;
if (wl_list_empty(message_list))
return;
printf("static const struct wl_message "
"%s_%s[] = {\n",
interface->name, suffix);
wl_list_for_each(m, message_list, link) {
printf("\t{ \"%s\", \"", m->name);
if (m->since > 1)
printf("%d", m->since);
wl_list_for_each(a, &m->arg_list, link) {
if (is_nullable_type(a) && a->nullable)
printf("?");
switch (a->type) {
default:
case INT:
printf("i");
break;
case NEW_ID:
if (a->interface_name == NULL)
printf("su");
printf("n");
break;
case UNSIGNED:
printf("u");
break;
case FIXED:
printf("f");
break;
case STRING:
printf("s");
break;
case OBJECT:
printf("o");
break;
case ARRAY:
printf("a");
break;
case FD:
printf("h");
break;
}
}
printf("\", types + %d },\n", m->type_index);
}
printf("};\n\n");
}
static void
emit_code(struct protocol *protocol)
{
struct interface *i, *i_next;
struct wl_array types;
char **p, *prev;
printf("#include \"%s.hpp\"\n", protocol->name);
wl_array_init(&types);
wl_list_for_each(i, &protocol->interface_list, link) {
emit_types_forward_declarations(protocol, &i->request_list, &types);
emit_types_forward_declarations(protocol, &i->event_list, &types);
}
wl_list_for_each_safe(i, i_next, &protocol->interface_list, link) {
emit_source_classes(&i->request_list, &i->event_list, i);
}
wl_list_for_each_safe(i, i_next, &protocol->interface_list, link) {
emit_code_init(&i->request_list, &i->event_list, i);
}
}
static void
free_protocol(struct protocol *protocol)
{
free(protocol->name);
free(protocol->uppercase_name);
free(protocol->copyright);
}
int main(int argc, char *argv[])
{
struct parse_context ctx;
struct protocol protocol;
FILE *input = stdin;
char *input_filename = NULL;
int len;
void *buf;
bool help = false;
bool core_headers = false;
bool version = false;
bool strict = false;
bool fail = false;
int opt;
enum {
CLIENT_HEADER,
SERVER_HEADER,
PRIVATE_CODE,
PUBLIC_CODE,
CODE,
} mode;
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ "include-core-only", no_argument, NULL, 'c' },
{ "strict", no_argument, NULL, 's' },
{ 0, 0, NULL, 0 }
};
while (1) {
opt = getopt_long(argc, argv, "hvcs", options, NULL);
if (opt == -1)
break;
switch (opt) {
case 'h':
help = true;
break;
case 'v':
version = true;
break;
case 'c':
core_headers = true;
break;
case 's':
strict = true;
break;
default:
fail = true;
break;
}
}
argv += optind;
argc -= optind;
if (help)
usage(EXIT_SUCCESS);
else if (version)
scanner_version(EXIT_SUCCESS);
else if ((argc != 1 && argc != 3) || fail)
usage(EXIT_FAILURE);
else if (strcmp(argv[0], "help") == 0)
usage(EXIT_SUCCESS);
else if (strcmp(argv[0], "client-header") == 0)
mode = CLIENT_HEADER;
else if (strcmp(argv[0], "server-header") == 0)
mode = SERVER_HEADER;
else if (strcmp(argv[0], "private-code") == 0)
mode = PRIVATE_CODE;
else if (strcmp(argv[0], "public-code") == 0)
mode = PUBLIC_CODE;
else if (strcmp(argv[0], "code") == 0)
mode = CODE;
else
usage(EXIT_FAILURE);
if (argc == 3) {
input_filename = argv[1];
input = fopen(input_filename, "r");
if (input == NULL) {
fprintf(stderr, "Could not open input file: %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
}
/* initialize protocol structure */
memset(&protocol, 0, sizeof protocol);
wl_list_init(&protocol.interface_list);
protocol.core_headers = core_headers;
/* initialize context */
memset(&ctx, 0, sizeof ctx);
ctx.protocol = &protocol;
if (input == stdin)
ctx.loc.filename = "<stdin>";
else
ctx.loc.filename = input_filename;
if (!is_dtd_valid(input, ctx.loc.filename)) {
fprintf(stderr,
"*******************************************************\n"
"* *\n"
"* WARNING: XML failed validation against built-in DTD *\n"
"* *\n"
"*******************************************************\n");
if (strict) {
fclose(input);
exit(EXIT_FAILURE);
}
}
/* create XML parser */
ctx.parser = XML_ParserCreate(NULL);
XML_SetUserData(ctx.parser, &ctx);
if (ctx.parser == NULL) {
fprintf(stderr, "failed to create parser\n");
fclose(input);
exit(EXIT_FAILURE);
}
XML_SetElementHandler(ctx.parser, start_element, end_element);
XML_SetCharacterDataHandler(ctx.parser, character_data);
do {
buf = XML_GetBuffer(ctx.parser, XML_BUFFER_SIZE);
len = fread(buf, 1, XML_BUFFER_SIZE, input);
if (len < 0) {
fprintf(stderr, "fread: %m\n");
fclose(input);
exit(EXIT_FAILURE);
}
if (XML_ParseBuffer(ctx.parser, len, len == 0) == 0) {
fprintf(stderr,
"Error parsing XML at line %ld col %ld: %s\n",
XML_GetCurrentLineNumber(ctx.parser),
XML_GetCurrentColumnNumber(ctx.parser),
XML_ErrorString(XML_GetErrorCode(ctx.parser)));
fclose(input);
exit(EXIT_FAILURE);
}
} while (len > 0);
XML_ParserFree(ctx.parser);
char b[2048];
sprintf(b, "%s.hpp", protocol.name);
if (freopen(b, "w", stdout) == NULL) {
fprintf(stderr, "Could not open output file: %s\n",
strerror(errno));
fclose(input);
exit(EXIT_FAILURE);
}
emit_header(&protocol);
sprintf(b, "%s.cpp", protocol.name);
if (freopen(b, "w", stdout) == NULL) {
fprintf(stderr, "Could not open output file: %s\n",
strerror(errno));
fclose(input);
exit(EXIT_FAILURE);
}
emit_code(&protocol);
free_protocol(&protocol);
fclose(input);
return 0;
}
#pragma once
#include <wayland-server.h>
class wl_resource_t {
public:
wl_resource_t() {};
struct wl_display *display = nullptr;
struct wl_client *client = nullptr;
struct wl_resource *resource = nullptr;
bool is_valid() {
return (display != nullptr && client != nullptr && resource != nullptr);
};
operator struct wl_resource*() {
return resource;
};
operator struct wl_client*(){
return client;
};
template<typename type>
static void create(struct wl_client *client, uint32_t id) {
type* res = new type;
res->create(client, id, true);
};
void create(struct wl_client *client_, uint32_t id, bool free_on_destroy) {
init();
display = wl_client_get_display(client_);
client = client_;
resource = wl_resource_create(client, interface, version, id);
if (resource == nullptr) {
wl_client_post_no_memory(client);
return;
}
wl_resource_set_implementation(resource, implementation, this, (free_on_destroy)?annihilate:nullptr);
on_create();
};
template<typename type>
static void global_create(struct wl_display *display, void *data) {
type i;
i.init();
wl_global_create(display, i.interface, i.version, data, bind_global<type>);
};
template<typename type>
static void global_create(struct wl_display *display, wl_global_bind_func_t bind, void *data) {
type i;
i.init();
wl_global_create(display, i.interface, i.version, data, bind);
};
void destroy() {
if (is_valid()) {
static_cast<wl_resource_t*>(wl_resource_get_user_data(resource))->on_destroy();
wl_resource_destroy(resource);
display = nullptr;
resource = nullptr;
client = nullptr;
}
};
virtual void on_create() = 0;
virtual void on_destroy() = 0;
virtual void init() = 0;
static void annihilate(struct wl_resource* resource) {
wl_resource_t *res = static_cast<wl_resource_t*>(wl_resource_get_user_data(resource));
if (res != nullptr) delete res;
};
uint32_t next_serial() {
if (display == nullptr) return 0;
return wl_display_next_serial(display);
};
template<typename type>
static type* from_wl_resource(struct wl_resource *resource) {
if (resource == nullptr) return static_cast<type*>(nullptr);
return static_cast<type*>(wl_resource_get_user_data(resource));
};
virtual ~wl_resource_t() {};
private:
void non_virtual_init() { init(); };
template <typename type>
static void bind_global(struct wl_client *client, void *data, uint32_t version, uint32_t id) {
create<type>(client, id);
};
protected:
uint32_t version;
const void *implementation;
const struct wl_interface *interface;
};
struct wl_client_t: public wl_listener {
public:
struct wl_client* operator ()() {
return client;
};
virtual void on_destroy() = 0;
virtual ~wl_client_t();
private:
struct wl_client *client = nullptr;
static void destroyed_callback(struct wl_listener *listener, void *data) {
wl_client_t *c = static_cast<wl_client_t*>(listener);
if (c == nullptr) return;
c->on_destroy();
delete c;
};
};
#include "wayland.hpp"
void wl_callback_t::send_done(uint32_t callback_data) {
if (resource == nullptr) return;
wl_callback_send_done(resource, callback_data);
}
static void wl_compositor_request_create_surface(struct wl_client *client, struct wl_resource *resource, uint32_t id) {
wl_compositor_t* res = static_cast<wl_compositor_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_create_surface(id);
}
static void wl_compositor_request_create_region(struct wl_client *client, struct wl_resource *resource, uint32_t id) {
wl_compositor_t* res = static_cast<wl_compositor_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_create_region(id);
}
struct wl_compositor_interface wl_compositor_interface_implementation = {
wl_compositor_request_create_surface,
wl_compositor_request_create_region
};
static void wl_buffer_request_destroy(struct wl_client *client, struct wl_resource *resource) {
wl_buffer_t* res = static_cast<wl_buffer_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_destroy();
}
struct wl_buffer_interface wl_buffer_interface_implementation = {
wl_buffer_request_destroy
};
void wl_buffer_t::send_release() {
if (resource == nullptr) return;
wl_buffer_send_release(resource);
}
static void wl_data_offer_request_accept(struct wl_client *client, struct wl_resource *resource, uint32_t serial, const char *mime_type) {
wl_data_offer_t* res = static_cast<wl_data_offer_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_accept(serial, mime_type);
}
static void wl_data_offer_request_receive(struct wl_client *client, struct wl_resource *resource, const char *mime_type, int32_t fd) {
wl_data_offer_t* res = static_cast<wl_data_offer_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_receive(mime_type, fd);
}
static void wl_data_offer_request_destroy(struct wl_client *client, struct wl_resource *resource) {
wl_data_offer_t* res = static_cast<wl_data_offer_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_destroy();
}
static void wl_data_offer_request_finish(struct wl_client *client, struct wl_resource *resource) {
wl_data_offer_t* res = static_cast<wl_data_offer_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_finish();
}
static void wl_data_offer_request_set_actions(struct wl_client *client, struct wl_resource *resource, uint32_t dnd_actions, uint32_t preferred_action) {
wl_data_offer_t* res = static_cast<wl_data_offer_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_actions(dnd_actions, preferred_action);
}
struct wl_data_offer_interface wl_data_offer_interface_implementation = {
wl_data_offer_request_accept,
wl_data_offer_request_receive,
wl_data_offer_request_destroy,
wl_data_offer_request_finish,
wl_data_offer_request_set_actions
};
void wl_data_offer_t::send_offer(const char *mime_type) {
if (resource == nullptr) return;
wl_data_offer_send_offer(resource, mime_type);
}
void wl_data_offer_t::send_source_actions(uint32_t source_actions) {
if (resource == nullptr) return;
wl_data_offer_send_source_actions(resource, source_actions);
}
void wl_data_offer_t::send_action(uint32_t dnd_action) {
if (resource == nullptr) return;
wl_data_offer_send_action(resource, dnd_action);
}
static void wl_data_source_request_offer(struct wl_client *client, struct wl_resource *resource, const char *mime_type) {
wl_data_source_t* res = static_cast<wl_data_source_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_offer(mime_type);
}
static void wl_data_source_request_destroy(struct wl_client *client, struct wl_resource *resource) {
wl_data_source_t* res = static_cast<wl_data_source_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_destroy();
}
static void wl_data_source_request_set_actions(struct wl_client *client, struct wl_resource *resource, uint32_t dnd_actions) {
wl_data_source_t* res = static_cast<wl_data_source_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_actions(dnd_actions);
}
struct wl_data_source_interface wl_data_source_interface_implementation = {
wl_data_source_request_offer,
wl_data_source_request_destroy,
wl_data_source_request_set_actions
};
void wl_data_source_t::send_target(const char *mime_type) {
if (resource == nullptr) return;
wl_data_source_send_target(resource, mime_type);
}
void wl_data_source_t::send_send(const char *mime_type, int32_t fd) {
if (resource == nullptr) return;
wl_data_source_send_send(resource, mime_type, fd);
}
void wl_data_source_t::send_cancelled() {
if (resource == nullptr) return;
wl_data_source_send_cancelled(resource);
}
void wl_data_source_t::send_dnd_drop_performed() {
if (resource == nullptr) return;
wl_data_source_send_dnd_drop_performed(resource);
}
void wl_data_source_t::send_dnd_finished() {
if (resource == nullptr) return;
wl_data_source_send_dnd_finished(resource);
}
void wl_data_source_t::send_action(uint32_t dnd_action) {
if (resource == nullptr) return;
wl_data_source_send_action(resource, dnd_action);
}
static void wl_data_device_request_start_drag(struct wl_client *client, struct wl_resource *resource, struct wl_resource *source, struct wl_resource *origin, struct wl_resource *icon, uint32_t serial) {
wl_data_device_t* res = static_cast<wl_data_device_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_start_drag(source, origin, icon, serial);
}
static void wl_data_device_request_set_selection(struct wl_client *client, struct wl_resource *resource, struct wl_resource *source, uint32_t serial) {
wl_data_device_t* res = static_cast<wl_data_device_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_selection(source, serial);
}
static void wl_data_device_request_release(struct wl_client *client, struct wl_resource *resource) {
wl_data_device_t* res = static_cast<wl_data_device_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_release();
}
struct wl_data_device_interface wl_data_device_interface_implementation = {
wl_data_device_request_start_drag,
wl_data_device_request_set_selection,
wl_data_device_request_release
};
void wl_data_device_t::send_data_offer(struct wl_resource *id) {
if (resource == nullptr) return;
wl_data_device_send_data_offer(resource, id);
}
void wl_data_device_t::send_enter(uint32_t serial, struct wl_resource *surface, wl_fixed_t x, wl_fixed_t y, struct wl_resource *id) {
if (resource == nullptr) return;
wl_data_device_send_enter(resource, serial, surface, x, y, id);
}
void wl_data_device_t::send_leave() {
if (resource == nullptr) return;
wl_data_device_send_leave(resource);
}
void wl_data_device_t::send_motion(uint32_t time, wl_fixed_t x, wl_fixed_t y) {
if (resource == nullptr) return;
wl_data_device_send_motion(resource, time, x, y);
}
void wl_data_device_t::send_drop() {
if (resource == nullptr) return;
wl_data_device_send_drop(resource);
}
void wl_data_device_t::send_selection(struct wl_resource *id) {
if (resource == nullptr) return;
wl_data_device_send_selection(resource, id);
}
static void wl_data_device_manager_request_create_data_source(struct wl_client *client, struct wl_resource *resource, uint32_t id) {
wl_data_device_manager_t* res = static_cast<wl_data_device_manager_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_create_data_source(id);
}
static void wl_data_device_manager_request_get_data_device(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *seat) {
wl_data_device_manager_t* res = static_cast<wl_data_device_manager_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_get_data_device(id, seat);
}
struct wl_data_device_manager_interface wl_data_device_manager_interface_implementation = {
wl_data_device_manager_request_create_data_source,
wl_data_device_manager_request_get_data_device
};
static void wl_shell_request_get_shell_surface(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface) {
wl_shell_t* res = static_cast<wl_shell_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_get_shell_surface(id, surface);
}
struct wl_shell_interface wl_shell_interface_implementation = {
wl_shell_request_get_shell_surface
};
static void wl_shell_surface_request_pong(struct wl_client *client, struct wl_resource *resource, uint32_t serial) {
wl_shell_surface_t* res = static_cast<wl_shell_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_pong(serial);
}
static void wl_shell_surface_request_move(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat, uint32_t serial) {
wl_shell_surface_t* res = static_cast<wl_shell_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_move(seat, serial);
}
static void wl_shell_surface_request_resize(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat, uint32_t serial, uint32_t edges) {
wl_shell_surface_t* res = static_cast<wl_shell_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_resize(seat, serial, edges);
}
static void wl_shell_surface_request_set_toplevel(struct wl_client *client, struct wl_resource *resource) {
wl_shell_surface_t* res = static_cast<wl_shell_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_toplevel();
}
static void wl_shell_surface_request_set_transient(struct wl_client *client, struct wl_resource *resource, struct wl_resource *parent, int32_t x, int32_t y, uint32_t flags) {
wl_shell_surface_t* res = static_cast<wl_shell_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_transient(parent, x, y, flags);
}
static void wl_shell_surface_request_set_fullscreen(struct wl_client *client, struct wl_resource *resource, uint32_t method, uint32_t framerate, struct wl_resource *output) {
wl_shell_surface_t* res = static_cast<wl_shell_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_fullscreen(method, framerate, output);
}
static void wl_shell_surface_request_set_popup(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat, uint32_t serial, struct wl_resource *parent, int32_t x, int32_t y, uint32_t flags) {
wl_shell_surface_t* res = static_cast<wl_shell_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_popup(seat, serial, parent, x, y, flags);
}
static void wl_shell_surface_request_set_maximized(struct wl_client *client, struct wl_resource *resource, struct wl_resource *output) {
wl_shell_surface_t* res = static_cast<wl_shell_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_maximized(output);
}
static void wl_shell_surface_request_set_title(struct wl_client *client, struct wl_resource *resource, const char *title) {
wl_shell_surface_t* res = static_cast<wl_shell_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_title(title);
}
static void wl_shell_surface_request_set_class(struct wl_client *client, struct wl_resource *resource, const char *class_) {
wl_shell_surface_t* res = static_cast<wl_shell_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_class(class_);
}
struct wl_shell_surface_interface wl_shell_surface_interface_implementation = {
wl_shell_surface_request_pong,
wl_shell_surface_request_move,
wl_shell_surface_request_resize,
wl_shell_surface_request_set_toplevel,
wl_shell_surface_request_set_transient,
wl_shell_surface_request_set_fullscreen,
wl_shell_surface_request_set_popup,
wl_shell_surface_request_set_maximized,
wl_shell_surface_request_set_title,
wl_shell_surface_request_set_class
};
void wl_shell_surface_t::send_ping(uint32_t serial) {
if (resource == nullptr) return;
wl_shell_surface_send_ping(resource, serial);
}
void wl_shell_surface_t::send_configure(uint32_t edges, int32_t width, int32_t height) {
if (resource == nullptr) return;
wl_shell_surface_send_configure(resource, edges, width, height);
}
void wl_shell_surface_t::send_popup_done() {
if (resource == nullptr) return;
wl_shell_surface_send_popup_done(resource);
}
static void wl_surface_request_destroy(struct wl_client *client, struct wl_resource *resource) {
wl_surface_t* res = static_cast<wl_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_destroy();
}
static void wl_surface_request_attach(struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer, int32_t x, int32_t y) {
wl_surface_t* res = static_cast<wl_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_attach(buffer, x, y);
}
static void wl_surface_request_damage(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) {
wl_surface_t* res = static_cast<wl_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_damage(x, y, width, height);
}
static void wl_surface_request_frame(struct wl_client *client, struct wl_resource *resource, uint32_t callback) {
wl_surface_t* res = static_cast<wl_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_frame(callback);
}
static void wl_surface_request_set_opaque_region(struct wl_client *client, struct wl_resource *resource, struct wl_resource *region) {
wl_surface_t* res = static_cast<wl_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_opaque_region(region);
}
static void wl_surface_request_set_input_region(struct wl_client *client, struct wl_resource *resource, struct wl_resource *region) {
wl_surface_t* res = static_cast<wl_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_input_region(region);
}
static void wl_surface_request_commit(struct wl_client *client, struct wl_resource *resource) {
wl_surface_t* res = static_cast<wl_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_commit();
}
static void wl_surface_request_set_buffer_transform(struct wl_client *client, struct wl_resource *resource, int32_t transform) {
wl_surface_t* res = static_cast<wl_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_buffer_transform(transform);
}
static void wl_surface_request_set_buffer_scale(struct wl_client *client, struct wl_resource *resource, int32_t scale) {
wl_surface_t* res = static_cast<wl_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_buffer_scale(scale);
}
static void wl_surface_request_damage_buffer(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) {
wl_surface_t* res = static_cast<wl_surface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_damage_buffer(x, y, width, height);
}
struct wl_surface_interface wl_surface_interface_implementation = {
wl_surface_request_destroy,
wl_surface_request_attach,
wl_surface_request_damage,
wl_surface_request_frame,
wl_surface_request_set_opaque_region,
wl_surface_request_set_input_region,
wl_surface_request_commit,
wl_surface_request_set_buffer_transform,
wl_surface_request_set_buffer_scale,
wl_surface_request_damage_buffer
};
void wl_surface_t::send_enter(struct wl_resource *output) {
if (resource == nullptr) return;
wl_surface_send_enter(resource, output);
}
void wl_surface_t::send_leave(struct wl_resource *output) {
if (resource == nullptr) return;
wl_surface_send_leave(resource, output);
}
static void wl_seat_request_get_pointer(struct wl_client *client, struct wl_resource *resource, uint32_t id) {
wl_seat_t* res = static_cast<wl_seat_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_get_pointer(id);
}
static void wl_seat_request_get_keyboard(struct wl_client *client, struct wl_resource *resource, uint32_t id) {
wl_seat_t* res = static_cast<wl_seat_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_get_keyboard(id);
}
static void wl_seat_request_get_touch(struct wl_client *client, struct wl_resource *resource, uint32_t id) {
wl_seat_t* res = static_cast<wl_seat_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_get_touch(id);
}
static void wl_seat_request_release(struct wl_client *client, struct wl_resource *resource) {
wl_seat_t* res = static_cast<wl_seat_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_release();
}
struct wl_seat_interface wl_seat_interface_implementation = {
wl_seat_request_get_pointer,
wl_seat_request_get_keyboard,
wl_seat_request_get_touch,
wl_seat_request_release
};
void wl_seat_t::send_capabilities(uint32_t capabilities) {
if (resource == nullptr) return;
wl_seat_send_capabilities(resource, capabilities);
}
void wl_seat_t::send_name(const char *name) {
if (resource == nullptr) return;
wl_seat_send_name(resource, name);
}
static void wl_pointer_request_set_cursor(struct wl_client *client, struct wl_resource *resource, uint32_t serial, struct wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y) {
wl_pointer_t* res = static_cast<wl_pointer_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_cursor(serial, surface, hotspot_x, hotspot_y);
}
static void wl_pointer_request_release(struct wl_client *client, struct wl_resource *resource) {
wl_pointer_t* res = static_cast<wl_pointer_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_release();
}
struct wl_pointer_interface wl_pointer_interface_implementation = {
wl_pointer_request_set_cursor,
wl_pointer_request_release
};
void wl_pointer_t::send_enter(uint32_t serial, struct wl_resource *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) {
if (resource == nullptr) return;
wl_pointer_send_enter(resource, serial, surface, surface_x, surface_y);
}
void wl_pointer_t::send_leave(uint32_t serial, struct wl_resource *surface) {
if (resource == nullptr) return;
wl_pointer_send_leave(resource, serial, surface);
}
void wl_pointer_t::send_motion(uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) {
if (resource == nullptr) return;
wl_pointer_send_motion(resource, time, surface_x, surface_y);
}
void wl_pointer_t::send_button(uint32_t serial, uint32_t time, uint32_t button, uint32_t state) {
if (resource == nullptr) return;
wl_pointer_send_button(resource, serial, time, button, state);
}
void wl_pointer_t::send_axis(uint32_t time, uint32_t axis, wl_fixed_t value) {
if (resource == nullptr) return;
wl_pointer_send_axis(resource, time, axis, value);
}
void wl_pointer_t::send_frame() {
if (resource == nullptr) return;
wl_pointer_send_frame(resource);
}
void wl_pointer_t::send_axis_source(uint32_t axis_source) {
if (resource == nullptr) return;
wl_pointer_send_axis_source(resource, axis_source);
}
void wl_pointer_t::send_axis_stop(uint32_t time, uint32_t axis) {
if (resource == nullptr) return;
wl_pointer_send_axis_stop(resource, time, axis);
}
void wl_pointer_t::send_axis_discrete(uint32_t axis, int32_t discrete) {
if (resource == nullptr) return;
wl_pointer_send_axis_discrete(resource, axis, discrete);
}
static void wl_keyboard_request_release(struct wl_client *client, struct wl_resource *resource) {
wl_keyboard_t* res = static_cast<wl_keyboard_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_release();
}
struct wl_keyboard_interface wl_keyboard_interface_implementation = {
wl_keyboard_request_release
};
void wl_keyboard_t::send_keymap(uint32_t format, int32_t fd, uint32_t size) {
if (resource == nullptr) return;
wl_keyboard_send_keymap(resource, format, fd, size);
}
void wl_keyboard_t::send_enter(uint32_t serial, struct wl_resource *surface, struct wl_array *keys) {
if (resource == nullptr) return;
wl_keyboard_send_enter(resource, serial, surface, keys);
}
void wl_keyboard_t::send_leave(uint32_t serial, struct wl_resource *surface) {
if (resource == nullptr) return;
wl_keyboard_send_leave(resource, serial, surface);
}
void wl_keyboard_t::send_key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
if (resource == nullptr) return;
wl_keyboard_send_key(resource, serial, time, key, state);
}
void wl_keyboard_t::send_modifiers(uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {
if (resource == nullptr) return;
wl_keyboard_send_modifiers(resource, serial, mods_depressed, mods_latched, mods_locked, group);
}
void wl_keyboard_t::send_repeat_info(int32_t rate, int32_t delay) {
if (resource == nullptr) return;
wl_keyboard_send_repeat_info(resource, rate, delay);
}
static void wl_touch_request_release(struct wl_client *client, struct wl_resource *resource) {
wl_touch_t* res = static_cast<wl_touch_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_release();
}
struct wl_touch_interface wl_touch_interface_implementation = {
wl_touch_request_release
};
void wl_touch_t::send_down(uint32_t serial, uint32_t time, struct wl_resource *surface, int32_t id, wl_fixed_t x, wl_fixed_t y) {
if (resource == nullptr) return;
wl_touch_send_down(resource, serial, time, surface, id, x, y);
}
void wl_touch_t::send_up(uint32_t serial, uint32_t time, int32_t id) {
if (resource == nullptr) return;
wl_touch_send_up(resource, serial, time, id);
}
void wl_touch_t::send_motion(uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y) {
if (resource == nullptr) return;
wl_touch_send_motion(resource, time, id, x, y);
}
void wl_touch_t::send_frame() {
if (resource == nullptr) return;
wl_touch_send_frame(resource);
}
void wl_touch_t::send_cancel() {
if (resource == nullptr) return;
wl_touch_send_cancel(resource);
}
void wl_touch_t::send_shape(int32_t id, wl_fixed_t major, wl_fixed_t minor) {
if (resource == nullptr) return;
wl_touch_send_shape(resource, id, major, minor);
}
void wl_touch_t::send_orientation(int32_t id, wl_fixed_t orientation) {
if (resource == nullptr) return;
wl_touch_send_orientation(resource, id, orientation);
}
static void wl_output_request_release(struct wl_client *client, struct wl_resource *resource) {
wl_output_t* res = static_cast<wl_output_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_release();
}
struct wl_output_interface wl_output_interface_implementation = {
wl_output_request_release
};
void wl_output_t::send_geometry(int32_t x, int32_t y, int32_t physical_width, int32_t physical_height, int32_t subpixel, const char *make, const char *model, int32_t transform) {
if (resource == nullptr) return;
wl_output_send_geometry(resource, x, y, physical_width, physical_height, subpixel, make, model, transform);
}
void wl_output_t::send_mode(uint32_t flags, int32_t width, int32_t height, int32_t refresh) {
if (resource == nullptr) return;
wl_output_send_mode(resource, flags, width, height, refresh);
}
void wl_output_t::send_done() {
if (resource == nullptr) return;
wl_output_send_done(resource);
}
void wl_output_t::send_scale(int32_t factor) {
if (resource == nullptr) return;
wl_output_send_scale(resource, factor);
}
static void wl_region_request_destroy(struct wl_client *client, struct wl_resource *resource) {
wl_region_t* res = static_cast<wl_region_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_destroy();
}
static void wl_region_request_add(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) {
wl_region_t* res = static_cast<wl_region_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_add(x, y, width, height);
}
static void wl_region_request_subtract(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) {
wl_region_t* res = static_cast<wl_region_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_subtract(x, y, width, height);
}
struct wl_region_interface wl_region_interface_implementation = {
wl_region_request_destroy,
wl_region_request_add,
wl_region_request_subtract
};
static void wl_subcompositor_request_destroy(struct wl_client *client, struct wl_resource *resource) {
wl_subcompositor_t* res = static_cast<wl_subcompositor_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_destroy();
}
static void wl_subcompositor_request_get_subsurface(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface, struct wl_resource *parent) {
wl_subcompositor_t* res = static_cast<wl_subcompositor_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_get_subsurface(id, surface, parent);
}
struct wl_subcompositor_interface wl_subcompositor_interface_implementation = {
wl_subcompositor_request_destroy,
wl_subcompositor_request_get_subsurface
};
static void wl_subsurface_request_destroy(struct wl_client *client, struct wl_resource *resource) {
wl_subsurface_t* res = static_cast<wl_subsurface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_destroy();
}
static void wl_subsurface_request_set_position(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y) {
wl_subsurface_t* res = static_cast<wl_subsurface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_position(x, y);
}
static void wl_subsurface_request_place_above(struct wl_client *client, struct wl_resource *resource, struct wl_resource *sibling) {
wl_subsurface_t* res = static_cast<wl_subsurface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_place_above(sibling);
}
static void wl_subsurface_request_place_below(struct wl_client *client, struct wl_resource *resource, struct wl_resource *sibling) {
wl_subsurface_t* res = static_cast<wl_subsurface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_place_below(sibling);
}
static void wl_subsurface_request_set_sync(struct wl_client *client, struct wl_resource *resource) {
wl_subsurface_t* res = static_cast<wl_subsurface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_sync();
}
static void wl_subsurface_request_set_desync(struct wl_client *client, struct wl_resource *resource) {
wl_subsurface_t* res = static_cast<wl_subsurface_t*>(wl_resource_get_user_data(resource));
if (res == nullptr) return;
res->request_set_desync();
}
struct wl_subsurface_interface wl_subsurface_interface_implementation = {
wl_subsurface_request_destroy,
wl_subsurface_request_set_position,
wl_subsurface_request_place_above,
wl_subsurface_request_place_below,
wl_subsurface_request_set_sync,
wl_subsurface_request_set_desync
};
void wl_callback_t::init() {
interface = &::wl_callback_interface;
version = 1;
implementation = nullptr;
}
void wl_compositor_t::init() {
interface = &::wl_compositor_interface;
version = 4;
implementation = &wl_compositor_interface_implementation;
}
void wl_buffer_t::init() {
interface = &::wl_buffer_interface;
version = 1;
implementation = &wl_buffer_interface_implementation;
}
void wl_data_offer_t::init() {
interface = &::wl_data_offer_interface;
version = 3;
implementation = &wl_data_offer_interface_implementation;
}
void wl_data_source_t::init() {
interface = &::wl_data_source_interface;
version = 3;
implementation = &wl_data_source_interface_implementation;
}
void wl_data_device_t::init() {
interface = &::wl_data_device_interface;
version = 3;
implementation = &wl_data_device_interface_implementation;
}
void wl_data_device_manager_t::init() {
interface = &::wl_data_device_manager_interface;
version = 3;
implementation = &wl_data_device_manager_interface_implementation;
}
void wl_shell_t::init() {
interface = &::wl_shell_interface;
version = 1;
implementation = &wl_shell_interface_implementation;
}
void wl_shell_surface_t::init() {
interface = &::wl_shell_surface_interface;
version = 1;
implementation = &wl_shell_surface_interface_implementation;
}
void wl_surface_t::init() {
interface = &::wl_surface_interface;
version = 4;
implementation = &wl_surface_interface_implementation;
}
void wl_seat_t::init() {
interface = &::wl_seat_interface;
version = 4;
implementation = &wl_seat_interface_implementation;
}
void wl_pointer_t::init() {
interface = &::wl_pointer_interface;
version = 7;
implementation = &wl_pointer_interface_implementation;
}
void wl_keyboard_t::init() {
interface = &::wl_keyboard_interface;
version = 7;
implementation = &wl_keyboard_interface_implementation;
}
void wl_touch_t::init() {
interface = &::wl_touch_interface;
version = 7;
implementation = &wl_touch_interface_implementation;
}
void wl_output_t::init() {
interface = &::wl_output_interface;
version = 3;
implementation = &wl_output_interface_implementation;
}
void wl_region_t::init() {
interface = &::wl_region_interface;
version = 1;
implementation = &wl_region_interface_implementation;
}
void wl_subcompositor_t::init() {
interface = &::wl_subcompositor_interface;
version = 1;
implementation = &wl_subcompositor_interface_implementation;
}
void wl_subsurface_t::init() {
interface = &::wl_subsurface_interface;
version = 1;
implementation = &wl_subsurface_interface_implementation;
}
#pragma once
#include <wayland-server.hpp>
class wl_callback_t : public wl_resource_t {
public:
void init() override;
void send_done(uint32_t callback_data);
};
class wl_compositor_t : public wl_resource_t {
public:
void init() override;
virtual void request_create_surface(uint32_t id) = 0;
virtual void request_create_region(uint32_t id) = 0;
};
class wl_buffer_t : public wl_resource_t {
public:
void init() override;
virtual void request_destroy() = 0;
void send_release();
};
class wl_data_offer_t : public wl_resource_t {
public:
void init() override;
virtual void request_accept(uint32_t serial,
const char *mime_type) = 0;
virtual void request_receive(const char *mime_type,
int32_t fd) = 0;
virtual void request_destroy() = 0;
virtual void request_finish() = 0;
virtual void request_set_actions(uint32_t dnd_actions,
uint32_t preferred_action) = 0;
void send_offer(const char *mime_type);
void send_source_actions(uint32_t source_actions);
void send_action(uint32_t dnd_action);
};
class wl_data_source_t : public wl_resource_t {
public:
void init() override;
virtual void request_offer(const char *mime_type) = 0;
virtual void request_destroy() = 0;
virtual void request_set_actions(uint32_t dnd_actions) = 0;
void send_target(const char *mime_type);
void send_send(const char *mime_type, int32_t fd);
void send_cancelled();
void send_dnd_drop_performed();
void send_dnd_finished();
void send_action(uint32_t dnd_action);
};
class wl_data_device_t : public wl_resource_t {
public:
void init() override;
virtual void request_start_drag(struct wl_resource *source,
struct wl_resource *origin,
struct wl_resource *icon,
uint32_t serial) = 0;
virtual void request_set_selection(struct wl_resource *source,
uint32_t serial) = 0;
virtual void request_release() = 0;
void send_data_offer(struct wl_resource *id);
void send_enter(uint32_t serial, struct wl_resource *surface, wl_fixed_t x, wl_fixed_t y, struct wl_resource *id);
void send_leave();
void send_motion(uint32_t time, wl_fixed_t x, wl_fixed_t y);
void send_drop();
void send_selection(struct wl_resource *id);
};
class wl_data_device_manager_t : public wl_resource_t {
public:
void init() override;
virtual void request_create_data_source(uint32_t id) = 0;
virtual void request_get_data_device(uint32_t id,
struct wl_resource *seat) = 0;
};
class wl_shell_t : public wl_resource_t {
public:
void init() override;
virtual void request_get_shell_surface(uint32_t id,
struct wl_resource *surface) = 0;
};
class wl_shell_surface_t : public wl_resource_t {
public:
void init() override;
virtual void request_pong(uint32_t serial) = 0;
virtual void request_move(struct wl_resource *seat,
uint32_t serial) = 0;
virtual void request_resize(struct wl_resource *seat,
uint32_t serial,
uint32_t edges) = 0;
virtual void request_set_toplevel() = 0;
virtual void request_set_transient(struct wl_resource *parent,
int32_t x,
int32_t y,
uint32_t flags) = 0;
virtual void request_set_fullscreen(uint32_t method,
uint32_t framerate,
struct wl_resource *output) = 0;
virtual void request_set_popup(struct wl_resource *seat,
uint32_t serial,
struct wl_resource *parent,
int32_t x,
int32_t y,
uint32_t flags) = 0;
virtual void request_set_maximized(struct wl_resource *output) = 0;
virtual void request_set_title(const char *title) = 0;
virtual void request_set_class(const char *class_) = 0;
void send_ping(uint32_t serial);
void send_configure(uint32_t edges, int32_t width, int32_t height);
void send_popup_done();
};
class wl_surface_t : public wl_resource_t {
public:
void init() override;
virtual void request_destroy() = 0;
virtual void request_attach(struct wl_resource *buffer,
int32_t x,
int32_t y) = 0;
virtual void request_damage(int32_t x,
int32_t y,
int32_t width,
int32_t height) = 0;
virtual void request_frame(uint32_t callback) = 0;
virtual void request_set_opaque_region(struct wl_resource *region) = 0;
virtual void request_set_input_region(struct wl_resource *region) = 0;
virtual void request_commit() = 0;
virtual void request_set_buffer_transform(int32_t transform) = 0;
virtual void request_set_buffer_scale(int32_t scale) = 0;
virtual void request_damage_buffer(int32_t x,
int32_t y,
int32_t width,
int32_t height) = 0;
void send_enter(struct wl_resource *output);
void send_leave(struct wl_resource *output);
};
class wl_seat_t : public wl_resource_t {
public:
void init() override;
virtual void request_get_pointer(uint32_t id) = 0;
virtual void request_get_keyboard(uint32_t id) = 0;
virtual void request_get_touch(uint32_t id) = 0;
virtual void request_release() = 0;
void send_capabilities(uint32_t capabilities);
void send_name(const char *name);
};
class wl_pointer_t : public wl_resource_t {
public:
void init() override;
virtual void request_set_cursor(uint32_t serial,
struct wl_resource *surface,
int32_t hotspot_x,
int32_t hotspot_y) = 0;
virtual void request_release() = 0;
void send_enter(uint32_t serial, struct wl_resource *surface, wl_fixed_t surface_x, wl_fixed_t surface_y);
void send_leave(uint32_t serial, struct wl_resource *surface);
void send_motion(uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y);
void send_button(uint32_t serial, uint32_t time, uint32_t button, uint32_t state);
void send_axis(uint32_t time, uint32_t axis, wl_fixed_t value);
void send_frame();
void send_axis_source(uint32_t axis_source);
void send_axis_stop(uint32_t time, uint32_t axis);
void send_axis_discrete(uint32_t axis, int32_t discrete);
};
class wl_keyboard_t : public wl_resource_t {
public:
void init() override;
virtual void request_release() = 0;
void send_keymap(uint32_t format, int32_t fd, uint32_t size);
void send_enter(uint32_t serial, struct wl_resource *surface, struct wl_array *keys);
void send_leave(uint32_t serial, struct wl_resource *surface);
void send_key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state);
void send_modifiers(uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group);
void send_repeat_info(int32_t rate, int32_t delay);
};
class wl_touch_t : public wl_resource_t {
public:
void init() override;
virtual void request_release() = 0;
void send_down(uint32_t serial, uint32_t time, struct wl_resource *surface, int32_t id, wl_fixed_t x, wl_fixed_t y);
void send_up(uint32_t serial, uint32_t time, int32_t id);
void send_motion(uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y);
void send_frame();
void send_cancel();
void send_shape(int32_t id, wl_fixed_t major, wl_fixed_t minor);
void send_orientation(int32_t id, wl_fixed_t orientation);
};
class wl_output_t : public wl_resource_t {
public:
void init() override;
virtual void request_release() = 0;
void send_geometry(int32_t x, int32_t y, int32_t physical_width, int32_t physical_height, int32_t subpixel, const char *make, const char *model, int32_t transform);
void send_mode(uint32_t flags, int32_t width, int32_t height, int32_t refresh);
void send_done();
void send_scale(int32_t factor);
};
class wl_region_t : public wl_resource_t {
public:
void init() override;
virtual void request_destroy() = 0;
virtual void request_add(int32_t x,
int32_t y,
int32_t width,
int32_t height) = 0;
virtual void request_subtract(int32_t x,
int32_t y,
int32_t width,
int32_t height) = 0;
};
class wl_subcompositor_t : public wl_resource_t {
public:
void init() override;
virtual void request_destroy() = 0;
virtual void request_get_subsurface(uint32_t id,
struct wl_resource *surface,
struct wl_resource *parent) = 0;
};
class wl_subsurface_t : public wl_resource_t {
public:
void init() override;
virtual void request_destroy() = 0;
virtual void request_set_position(int32_t x,
int32_t y) = 0;
virtual void request_place_above(struct wl_resource *sibling) = 0;
virtual void request_place_below(struct wl_resource *sibling) = 0;
virtual void request_set_sync() = 0;
virtual void request_set_desync() = 0;
};
struct wl_callback_interface;
struct wl_compositor_interface;
struct wl_buffer_interface;
struct wl_data_offer_interface;
struct wl_data_source_interface;
struct wl_data_device_interface;
struct wl_data_device_manager_interface;
struct wl_shell_interface;
struct wl_shell_surface_interface;
struct wl_surface_interface;
struct wl_seat_interface;
struct wl_pointer_interface;
struct wl_keyboard_interface;
struct wl_touch_interface;
struct wl_output_interface;
struct wl_region_interface;
struct wl_subcompositor_interface;
struct wl_subsurface_interface;
extern struct wl_compositor_interface wl_compositor_interface_implementation;
extern struct wl_buffer_interface wl_buffer_interface_implementation;
extern struct wl_data_offer_interface wl_data_offer_interface_implementation;
extern struct wl_data_source_interface wl_data_source_interface_implementation;
extern struct wl_data_device_interface wl_data_device_interface_implementation;
extern struct wl_data_device_manager_interface wl_data_device_manager_interface_implementation;
extern struct wl_shell_interface wl_shell_interface_implementation;
extern struct wl_shell_surface_interface wl_shell_surface_interface_implementation;
extern struct wl_surface_interface wl_surface_interface_implementation;
extern struct wl_seat_interface wl_seat_interface_implementation;
extern struct wl_pointer_interface wl_pointer_interface_implementation;
extern struct wl_keyboard_interface wl_keyboard_interface_implementation;
extern struct wl_touch_interface wl_touch_interface_implementation;
extern struct wl_output_interface wl_output_interface_implementation;
extern struct wl_region_interface wl_region_interface_implementation;
extern struct wl_subcompositor_interface wl_subcompositor_interface_implementation;
extern struct wl_subsurface_interface wl_subsurface_interface_implementation;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment