#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: wsemul_vt100_keys.c,v 1.11 2010/02/10 19:39:39 drochner Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsdisplayvar.h>
#include <dev/wscons/wsksymvar.h>
#include <dev/wscons/wsksymdef.h>
#include <dev/wscons/wsemul_vt100var.h>
static const char *vt100_fkeys[] = {
"\033[11~",
"\033[12~",
"\033[13~",
"\033[14~",
"\033[15~",
"\033[17~",
"\033[18~",
"\033[19~",
"\033[20~",
"\033[21~",
"\033[23~",
"\033[24~",
"\033[25~",
"\033[26~",
"\033[28~",
"\033[29~",
"\033[31~",
"\033[32~",
"\033[33~",
"\033[34~",
};
static const char *vt100_pfkeys[] = {
"\033OP",
"\033OQ",
"\033OR",
"\033OS",
};
static const char *vt100_numpad[] = {
"\033Op",
"\033Oq",
"\033Or",
"\033Os",
"\033Ot",
"\033Ou",
"\033Ov",
"\033Ow",
"\033Ox",
"\033Oy",
};
int
wsemul_vt100_translate(void *cookie, keysym_t in, const char **out)
{
struct wsemul_vt100_emuldata *edp = cookie;
struct vt100base_data *vd = &edp->bd;
static char c;
if (KS_GROUP(in) == KS_GROUP_Plain) {
c = KS_VALUE(in);
*out = &c;
return (1);
}
if (in >= KS_f1 && in <= KS_f20) {
*out = vt100_fkeys[in - KS_f1];
return (5);
}
if (in >= KS_F1 && in <= KS_F20) {
*out = vt100_fkeys[in - KS_F1];
return (5);
}
if (in >= KS_KP_F1 && in <= KS_KP_F4) {
*out = vt100_pfkeys[in - KS_KP_F1];
return (3);
}
if (vd->flags & VTFL_APPLKEYPAD) {
if (in >= KS_KP_0 && in <= KS_KP_9) {
*out = vt100_numpad[in - KS_KP_0];
return (3);
}
switch (in) {
case KS_KP_Tab:
*out = "\033OI";
return (3);
case KS_KP_Enter:
*out = "\033OM";
return (3);
case KS_KP_Multiply:
*out = "\033Oj";
return (3);
case KS_KP_Add:
*out = "\033Ok";
return (3);
case KS_KP_Separator:
*out = "\033Ol";
return (3);
case KS_KP_Subtract:
*out = "\033Om";
return (3);
case KS_KP_Decimal:
*out = "\033On";
return (3);
case KS_KP_Divide:
*out = "\033Oo";
return (3);
}
} else {
if (!(in & 0x80)) {
c = in & 0xff;
*out = &c;
return (1);
}
}
switch (in) {
case KS_Help:
*out = vt100_fkeys[15 - 1];
return (5);
case KS_Execute:
*out = vt100_fkeys[16 - 1];
return (5);
case KS_Find:
*out = "\033[1~";
return (4);
case KS_Insert:
case KS_KP_Insert:
*out = "\033[2~";
return (4);
case KS_KP_Delete:
*out = "\033[3~";
return (4);
case KS_Select:
*out = "\033[4~";
return (4);
case KS_Prior:
case KS_KP_Prior:
*out = "\033[5~";
return (4);
case KS_Next:
case KS_KP_Next:
*out = "\033[6~";
return (4);
case KS_Home:
case KS_KP_Home:
*out = "\033[7~";
return (4);
case KS_End:
case KS_KP_End:
*out = "\033[8~";
return (4);
case KS_Up:
case KS_KP_Up:
if (vd->flags & VTFL_APPLCURSOR)
*out = "\033OA";
else
*out = "\033[A";
return (3);
case KS_Down:
case KS_KP_Down:
if (vd->flags & VTFL_APPLCURSOR)
*out = "\033OB";
else
*out = "\033[B";
return (3);
case KS_Left:
case KS_KP_Left:
if (vd->flags & VTFL_APPLCURSOR)
*out = "\033OD";
else
*out = "\033[D";
return (3);
case KS_Right:
case KS_KP_Right:
if (vd->flags & VTFL_APPLCURSOR)
*out = "\033OC";
else
*out = "\033[C";
return (3);
}
return (0);
}