dtelnet: shkeys.c

/* shkeys.c */

/* compile me: cc -o shkeys shkeys.c */

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

typedef struct ConstBuffData {
    const char *ptr;
    size_t len;
} ConstBuffData;

#define StaticConstBuffData(Name,Sname,Value) \
    static const char Sname [] = Value; \
    static const ConstBuffData Name = { (char *)Sname, sizeof (Sname)-1}

#define StaticConstBD(Name,Value) StaticConstBuffData(Name,N##Name,Value)

static int BuffDataBeg (const ConstBuffData *data, const ConstBuffData *beg)
{
    if (data->len < beg->len) return 0;
    return memcmp (data->ptr, beg->ptr, beg->len) == 0;
}

static struct {
    int kpam;
    int mouse;
    int mouse_x10;
} opt = {
    0,
    0,
    0
};

static void ParseArgs (int *pargc, char ***pargv);

#define ESC "\x1b"

static const struct {
    const char *KPAM;
    const char *KPNM;
    const char *MOUSE_ON;
    const char *MOUSE_OFF;
    const char *MOUSE_X10_ON;
    const char *MOUSE_X10_OFF;
} seq = {
    ESC "=",
    ESC ">",
    ESC "[?1000h",
    ESC "[?1000l",
    ESC "[?9h",
    ESC "[?9l"
};

static void PrintBlock (ConstBuffData *bd);
static void PrintSome (ConstBuffData *bd);

int main (int argc, char **argv)
{
    struct termios oldtio, newtio;
    int rc, rdlen, leave;
    char buf [12];
    ConstBuffData rest;

    ParseArgs (&argc, &argv);

    rc= tcgetattr (0, &oldtio);
    if (rc) {
        perror ("tcgetattr (0, &oldtio)");
    return 4;
    }
    memcpy (&newtio, &oldtio, sizeof (newtio));
    newtio.c_lflag &= ~(ISIG | ICANON | ECHO);
    newtio.c_iflag &= ~(INLCR | ICRNL | IXON | IXOFF);
    newtio.c_cflag &= ~(PARENB);
    newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS8;
    newtio.c_cc[VMIN] = 1;
    rc= tcsetattr (0, TCSAFLUSH, &newtio);
    if (rc) {
    perror ("tcsetattr (0, TCSAFLUSH, &newtio)");
    return 12;
    } 

    if (opt.kpam)  write (1, seq.KPAM, strlen (seq.KPAM));
    if      (opt.mouse)     write (1, seq.MOUSE_ON,     strlen (seq.MOUSE_ON));
    else if (opt.mouse_x10) write (1, seq.MOUSE_X10_ON, strlen (seq.MOUSE_X10_ON));

    printf ("Press any key to see codes, ctrl-D to terminate\n\n");

    for (leave= 0; ! leave; ) {
        rdlen= read (0, buf, sizeof (buf));
    if (rdlen<0) {
        perror ("read(0)");
        leave= 1; /* error */
        continue;
    } else if (rdlen==0) {
        leave= 1; /* EOF */
        continue;
    }

    rest.len= rdlen;
    rest.ptr= buf;

    PrintBlock (&rest);

    if (buf[0]==4) leave= 1; /* ctrl-D */
    }

    if      (opt.mouse)     write (1, seq.MOUSE_OFF,     strlen (seq.MOUSE_OFF));
    else if (opt.mouse_x10) write (1, seq.MOUSE_X10_OFF, strlen (seq.MOUSE_X10_OFF));
    if (opt.kpam)  write (1, seq.KPNM, strlen (seq.KPNM));

    rc= tcsetattr (0, TCSAFLUSH, &oldtio);
    if (rc) {
    perror ("tcsetattr (0, TCSAFLUSH, &oldtio)");
    return 12;
    }
    return 0;
}

static void PrintMouse (const char *from)
{
    int code, codeh, codel;
    int row, col;

    code= (unsigned char)from[3];
    col = (unsigned char)from[4] - 32;
    row = (unsigned char)from[5] - 32;

    codeh= code&0xe0;
    codel= code&0x03;

    printf ("Mouse event %02x:", code);

    if (codeh==0x20 && codel==0x03) {
    printf (" button release");

    } else if (codeh==0x20) {
    printf (" button #%d press", 1+codel);

    } else if (codeh==0x60) {
    printf (" button #%d press or wheel #%d %s"
        , 4+codel, 1+codel/2, codel%2==0? "up": "down");

    } else if (codeh==0x40) {
    printf (" press-and-move button #%d is down", 1+codel);

    } else if (codeh==0x80) {
    printf (" press-and-move button #%d is down or wheel #%d %s"
        , 4+codel, 1+codel/2, codel%2==0? "up": "down");
    }

    if (code&0x04) printf (" shift pressed");
    if (code&0x08) printf (" alt pressed");
    if (code&0x10) printf (" ctrl pressed");
    printf (" at row=%d col=%d", row, col);
    printf ("\n");
}

StaticConstBD (BMousePref, "\x1b[M");

static void PrintBlock (ConstBuffData *bd)
{
    ConstBuffData mybd;

    while (bd->len >= 6 && BuffDataBeg (bd, &BMousePref)) {
    mybd.ptr= bd->ptr;
    mybd.len= 6;
    bd->ptr += 6;
    bd->len -= 6;

    PrintMouse (mybd.ptr);
    PrintSome (&mybd);
    }
    if (bd->len) PrintSome (bd);
}

static void PrintSome (ConstBuffData *bd)
{
    size_t i;
    int c;
    char prbuff [128], *p;

    p= prbuff;
    for (i=0; i<bd->len; ++i) {
    c= (unsigned char)bd->ptr[i];
    if (c < ' ') {
        p += sprintf (p, "^%c",  c+64);
    } else if (c==0x7f) {
        p += sprintf (p, "^?");
    } else {
        p += sprintf (p, "%c", c);
    }
    }
    for (i=0; i<bd->len; ++i) {
    c= (unsigned char)bd->ptr[i];
    printf ("%-16s %3d 0x%02x 0%03o\n", prbuff, c, c, c);
    prbuff[0] = '\0';
    }
}

static void ParseArgs (int *pargc, char ***pargv)
{
    int argc;
    char **argv;
    int parse_arg;
    char *progname;

    argc = *pargc;
    argv = *pargv;
    parse_arg = 1;
    progname = argv[0];

    while (--argc && **++argv=='-' && parse_arg) {
    switch (argv[0][1]) {
    case 'k': case 'K':
         if (strcasecmp (argv[0], "-kpam")==0) {
        opt.kpam= 1;
        break;
         }
         goto UNKOPT;

    case 'm': case 'M':
         if (strcasecmp (argv[0], "-mouse")==0 ||
         strcasecmp (argv[0], "-mouse-x11")==0) {
        opt.mouse= 1;
        break;

         } else if (strcasecmp (argv[0], "-mouse-x10")==0) {
        opt.mouse_x10= 1;
        break;
         }
         goto UNKOPT;

    case 0:parse_arg = 0; break;
    case '-':
        if (argv[0][2]=='\0') {
        parse_arg = 0;
        break;
        }
        goto UNKOPT;

    default: UNKOPT:
        fprintf (stderr, "usage: %s [-kpam] [-mouse]'\n", *argv);
        exit (4);
    }
    }
    ++argc;
    *--argv = progname;
    *pargc = argc;
    *pargv = argv;
}

Copyright

http://dtelnet.sourceforge.net/shkeys.c

 

posted @ 2020-11-26 11:17  dong1  阅读(97)  评论(0编辑  收藏  举报