Created
August 5, 2019 08:23
-
-
Save twaik/e9cf32cba07ccc8ff8dcc100f7440dd2 to your computer and use it in GitHub Desktop.
Wayland server protocol c++ scanner
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
}; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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