/* $Id: input.c,v 1.4 2007-08-28 09:19:50 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
size_t input_sequence(
u_char *, size_t, u_char *, u_char *, uint16_t **, u_int *);
int input_control(
u_char **, size_t *, struct buffer *, struct screen *, u_char);
int input_pair_private(
u_char **, size_t *, struct buffer *, struct screen *, u_char);
int input_pair_standard(
u_char **, size_t *, struct buffer *, struct screen *, u_char);
int input_pair_control(
u_char **, size_t *, struct buffer *, struct screen *, u_char);
int input_control_sequence(
u_char **, size_t *, struct buffer *, struct screen *);
int input_check_one(uint16_t *, u_int, uint16_t *, uint16_t);
int input_check_one2(
uint16_t *, u_int, uint16_t *, uint16_t, uint16_t, uint16_t);
int input_check_two(
uint16_t *, u_int, uint16_t *, uint16_t, uint16_t *, uint16_t);
struct input_key {
int key;
const char *string;
};
struct input_key input_keys[] = {
{ KEYC_BACKSPACE, "" },
{ KEYC_DC, "[3~" },
{ KEYC_DOWN, "OB" },
{ KEYC_F1, "OP" },
{ KEYC_F10, "[21~" },
{ KEYC_F11, "[23~" },
{ KEYC_F12, "[24~" },
{ KEYC_F2, "OQ" },
{ KEYC_F3, "OR" },
{ KEYC_F4, "OS" },
{ KEYC_F5, "[15~" },
{ KEYC_F6, "[17~" },
{ KEYC_F7, "[18~" },
{ KEYC_F8, "[19~" },
{ KEYC_F9, "[20~" },
{ KEYC_HOME, "[1~" },
{ KEYC_IC, "[2~" },
{ KEYC_LEFT, "OD" },
{ KEYC_LL, "[4~" },
{ KEYC_NPAGE, "[6~" },
{ KEYC_PPAGE, "[5~" },
{ KEYC_RIGHT, "OC" },
{ KEYC_UP, "OA" }
};
/*
* This parses CSI escape sequences into a code and a block of uint16_t
* arguments. buf must be the next byte after the \e[ and len the remaining
* data.
*/
size_t
input_sequence(u_char *buf, size_t len,
u_char *code, u_char *private, uint16_t **argv, u_int *argc)
{
char ch;
u_char *ptr, *saved;
const char *errstr;
*code = 0;
*argc = 0;
*argv = NULL;
if (len == 0)
return (0);
saved = buf;
/*
* 0x3c (<) to 0x3f (?) mark private sequences when appear as the first
* character.
*/
*private = '\0';
if (*buf >= '<' && *buf <= '?') {
*private = *buf;
buf++; len--;
} else if (*buf < '0' || *buf > ';')
goto complete;
while (len > 0) {
/*
* Every parameter substring is bytes from 0x30 (0) to 0x3a (:),
* terminated by 0x3b (;). 0x3a is an internal seperator.
*/
/* Find the end of the substring. */
ptr = buf;
while (len != 0 && *ptr >= '0' && *ptr <= '9') {
ptr++;
len--;
}
if (len == 0)
break;
/* An 0x3a is unsupported. */
if (*ptr == ':')
goto invalid;
/* Create a new argument. */
(*argc)++;
*argv = xrealloc(*argv, *argc, sizeof **argv);
/* Fill in argument value. */
errstr = NULL;
if (ptr == buf)
(*argv)[*argc - 1] = UINT16_MAX;
else {
ch = *ptr; *ptr = '\0';
(*argv)[*argc - 1] =
strtonum(buf, 0, UINT16_MAX - 1, &errstr);
*ptr = ch;
}
buf = ptr;
/* If the conversion had errors, abort now. */
if (errstr != NULL)
goto invalid;
/* Break for any non-terminator. */
if (*buf != ';')
goto complete;
buf++; len--;
}
if (len == 0)
goto incomplete;
complete:
/* Valid final characters are 0x40 (@) to 0x7e (~). */
if (*buf < '@' || *buf > '~')
goto invalid;
*code = *buf;
return (buf -