mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-11-01 22:11:22 +01:00
177 lines
6.8 KiB
C
177 lines
6.8 KiB
C
// This file is generated by apc_parsers.py do not edit!
|
|
|
|
#pragma once
|
|
|
|
#include "base64.h"
|
|
|
|
static inline void
|
|
parse_dnd_code(PS *self, uint8_t *parser_buf, const size_t parser_buf_pos) {
|
|
unsigned int pos = 0;
|
|
size_t payload_start = 0;
|
|
enum PARSER_STATES { KEY, EQUAL, UINT, INT, FLAG, AFTER_VALUE, PAYLOAD };
|
|
enum PARSER_STATES state = KEY, value_state = FLAG;
|
|
DnDCommand g = {0};
|
|
unsigned int i, code;
|
|
uint64_t lcode;
|
|
bool is_negative;
|
|
(void)is_negative;
|
|
size_t sz;
|
|
|
|
enum KEYS { type = 't', more = 'm', client_id = 'i', operation = 'o', cell_x = 'x', cell_y = 'y', pixel_x = 'X', pixel_y = 'Y' };
|
|
|
|
enum KEYS key = 'a';
|
|
if (parser_buf[pos] == ';') state = AFTER_VALUE;
|
|
|
|
while (pos < parser_buf_pos) {
|
|
switch (state) {
|
|
case KEY:
|
|
key = parser_buf[pos++];
|
|
state = EQUAL;
|
|
switch (key) {
|
|
case type: value_state = FLAG; break;
|
|
case more: value_state = UINT; break;
|
|
case client_id: value_state = UINT; break;
|
|
case operation: value_state = UINT; break;
|
|
case cell_x: value_state = INT; break;
|
|
case cell_y: value_state = INT; break;
|
|
case pixel_x: value_state = INT; break;
|
|
case pixel_y: value_state = INT; break;
|
|
default: REPORT_ERROR("Malformed DnDCommand control block, invalid key character: 0x%x", key); return;
|
|
}
|
|
break;
|
|
|
|
case EQUAL:
|
|
if (parser_buf[pos++] != '=') {
|
|
REPORT_ERROR("Malformed DnDCommand control block, no = after key, found: 0x%x instead", parser_buf[pos - 1]);
|
|
return;
|
|
}
|
|
state = value_state;
|
|
break;
|
|
|
|
case FLAG:
|
|
switch (key) {
|
|
case type: {
|
|
g.type = parser_buf[pos++];
|
|
if (g.type != 'A' && g.type != 'E' && g.type != 'M' && g.type != 'P' && g.type != 'R' && g.type != 'a' && g.type != 'e' &&
|
|
g.type != 'k' && g.type != 'm' && (g.type < 'o' || g.type > 'r')) {
|
|
REPORT_ERROR("Malformed DnDCommand control block, unknown flag value for type: 0x%x", g.type);
|
|
return;
|
|
};
|
|
} break;
|
|
|
|
default: break;
|
|
}
|
|
state = AFTER_VALUE;
|
|
break;
|
|
|
|
case INT:
|
|
#define READ_UINT \
|
|
for (i = pos, lcode = 0; i < MIN(parser_buf_pos, pos + 10); i++) { \
|
|
uint8_t n = parser_buf[i] - '0'; \
|
|
if (n > 9) break; \
|
|
lcode = lcode * 10 + n; \
|
|
} \
|
|
if (i == pos) { \
|
|
REPORT_ERROR("Malformed DnDCommand control block, expecting an integer value for key: %c", key & 0xFF); \
|
|
return; \
|
|
} \
|
|
pos = i; \
|
|
if (lcode > UINT32_MAX) { \
|
|
REPORT_ERROR("Malformed DnDCommand control block, number is too large"); \
|
|
return; \
|
|
} \
|
|
code = lcode;
|
|
|
|
is_negative = false;
|
|
if (parser_buf[pos] == '-') {
|
|
is_negative = true;
|
|
pos++;
|
|
}
|
|
#define I(x) \
|
|
case x: g.x = is_negative ? 0 - (int32_t)code : (int32_t)code; break
|
|
READ_UINT;
|
|
switch (key) {
|
|
I(cell_x);
|
|
I(cell_y);
|
|
I(pixel_x);
|
|
I(pixel_y);
|
|
default: break;
|
|
}
|
|
state = AFTER_VALUE;
|
|
break;
|
|
#undef I
|
|
case UINT: READ_UINT;
|
|
#define U(x) \
|
|
case x: g.x = code; break
|
|
switch (key) {
|
|
U(more);
|
|
U(client_id);
|
|
U(operation);
|
|
default: break;
|
|
}
|
|
state = AFTER_VALUE;
|
|
break;
|
|
#undef U
|
|
#undef READ_UINT
|
|
|
|
case AFTER_VALUE:
|
|
switch (parser_buf[pos++]) {
|
|
default:
|
|
REPORT_ERROR("Malformed DnDCommand control block, expecting a : or semi-colon after a value, found: 0x%x", parser_buf[pos - 1]);
|
|
return;
|
|
case ':': state = KEY; break;
|
|
case ';': state = PAYLOAD; break;
|
|
}
|
|
break;
|
|
|
|
|
|
case PAYLOAD: {
|
|
sz = parser_buf_pos - pos;
|
|
payload_start = pos;
|
|
g.payload_sz = sz;
|
|
pos = parser_buf_pos;
|
|
} break;
|
|
|
|
|
|
} // end switch
|
|
} // end while
|
|
|
|
switch (state) {
|
|
case EQUAL: REPORT_ERROR("Malformed DnDCommand control block, no = after key"); return;
|
|
case INT:
|
|
case UINT: REPORT_ERROR("Malformed DnDCommand control block, expecting an integer value"); return;
|
|
case FLAG: REPORT_ERROR("Malformed DnDCommand control block, expecting a flag value"); return;
|
|
default: break;
|
|
}
|
|
|
|
REPORT_VA_COMMAND(
|
|
"K s {sc sI sI sI si si si si ss#}",
|
|
self->window_id,
|
|
"dnd_command",
|
|
|
|
"type",
|
|
g.type,
|
|
|
|
"more",
|
|
(unsigned int)g.more,
|
|
"client_id",
|
|
(unsigned int)g.client_id,
|
|
"operation",
|
|
(unsigned int)g.operation,
|
|
|
|
"cell_x",
|
|
(int)g.cell_x,
|
|
"cell_y",
|
|
(int)g.cell_y,
|
|
"pixel_x",
|
|
(int)g.pixel_x,
|
|
"pixel_y",
|
|
(int)g.pixel_y,
|
|
|
|
"",
|
|
(char *)parser_buf + payload_start,
|
|
g.payload_sz);
|
|
|
|
screen_handle_dnd_command(self->screen, &g, parser_buf + payload_start);
|
|
}
|