Hi,

Simon Perreault wrote [2012-01-23 21:44+0100]:
> /etc/kbdtype contains "cf". I tried playing with kbd and wsconsctl.

I'm not an expert, but i'll append something for you to play with
even more.  Maybe it'll help you.
Otherwise wait for the answer of someone who actually is an
expert.

> Everything seems normal except the above mentioned keys that do
> nothing.

If the program you are working with is eight bit clean (ksh(1)
doesn't work, csh(1) does), maybe it's the mapping.

AFAIK there is no way, neither in base nor in packages, to print
out the actually used scancodes of the keyboards' keys.
After i've messed up another keyboard-related question last week
or so (;>) i've sat down and wrote a small thing which prints out
the currently used ones, so that it's possible to compare them
with the output of

    $ sudo wsconsctl keyboard.map

Note that this is intermediate version, don't type too fast
(ridiculous buffer handling) etc., but i haven't had time to
polish it.  But "it works".
IMHO a subset of that should be part of wsconsctl(8), btw.

Hope that helps,
good night and ciao,

--steffen
-- >8 --
/* wscons_scankey, a yet not finished "showkey"-thing.
 * Compile:
 *      $ gcc -W -Wall -pedantic -ansi -o wscons_scankey wscons_scankey.c
 * Use (not on pseudo-terminal):
 *      $ ./wscons_scankey [krtv]  # default = k
 */

#include <err.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

#include <termios.h>
#include <unistd.h>

#include <sys/ioctl.h>
#include <sys/time.h>

#include <dev/wscons/wsconsio.h>

static struct termios   tios_orig, tios_raw;
static int              no_raw;

static void     onsig(int sig);
static void     rawinit(void), rawon(void), rawoff(void);

static void
onsig(int sig)
{
        rawoff();
        exit(! (sig == SIGALRM));
}

static void
rawinit(void)
{
        if (tcgetattr(STDIN_FILENO, &tios_orig) < 0)
                err(3, "Can't query terminal attributes");
        tios_raw = tios_orig;
        (void)cfmakeraw(&tios_raw);
        return;
}

static void
rawon(void)
{
        auto int arg = WSKBD_RAW;

        if (tcsetattr(STDIN_FILENO, TCSANOW, &tios_raw) < 0)
                err(3, "Can't set terminal attributes");

        if (! no_raw && ioctl(STDIN_FILENO, WSKBDIO_SETMODE, &arg) < 0) {
                int x = errno;
                (void)tcsetattr(STDIN_FILENO, TCSANOW, &tios_orig);
                errno = x;
                err(3,  "Can't put keyboard in raw mode ("
                        "needs the WSDISPLAY_COMPAT_RAWKBD kernel option)");
        }
        return;
}

static void
rawoff(void)
{
        auto int arg = WSKBD_TRANSLATED;

        if (! no_raw)
                (void)ioctl(STDIN_FILENO, WSKBDIO_SETMODE, &arg);
        (void)tcsetattr(STDIN_FILENO, TCSANOW, &tios_orig);
        return;
}

int
main(int argc, char **argv)
{
        enum { MODE_KEYCODE, MODE_RAW, MODE_VALUE } mode = MODE_KEYCODE;
        ssize_t br, i;
        auto struct sigaction sa;
        auto struct itimerval it;
        auto char buf[64];

        if (argc > 1)
                switch (**++argv) {
                case 'k':
                        mode = MODE_KEYCODE;
                        break;
                case 't':
                        no_raw = 1;
                        /* FALLTHRU */
                case 'r':
                        mode = MODE_RAW;
                        break;
                case 'v':
                        mode = MODE_VALUE;
                        no_raw = 1;
                        break;
                default:
                        mode = -1;
                        break;
                }
        if ((int)mode < 0)
                errx(1, "Usage: wscons_showkey [krtv] "
                        "(keycode, raw, termios-raw, value)");

        if (!isatty(STDIN_FILENO))
                err(1, "STDIN is not a terminal");
        rawinit();

        sa.sa_handler = &onsig;
        sa.sa_flags = 0;
        (void)sigfillset(&sa.sa_mask);
        for (i = 0; i < _NSIG; ++i)
                if (sigaction((int)i + 1, &sa, NULL) < 0 && i == SIGALRM)
                        err(2, "Can't install SIGALRM signal handler");

        printf( "You may now use the keyboard;\n"
                "After five seconds of inactivity the program terminates\n");
        for (;;) {
                it.it_value.tv_sec = 5;
                it.it_value.tv_usec = 0;
                it.it_interval.tv_sec = it.it_interval.tv_usec = 0;
                if (setitimer(ITIMER_REAL, &it, NULL) < 0)
                        err(2, "Can't install wakeup timer");

                rawon();
                br = read(STDIN_FILENO, buf, sizeof buf - 1);
                rawoff();
                if (br <= 0)
                        break;

                /* src/sys/dev/wscons/wsksymdef.h */
                switch (mode) {
                case MODE_KEYCODE: {
                        unsigned int rc, c;
                        const char *meta;
                        for (i = 0; i < br; ++i) {
                                rc = c = (unsigned char)buf[i];
                                if ((c & 0xF0) == 0xE0) {
                                        if (br - i < 2) {
                                                printf("Faulty keycode, I\n");
                                                continue;
                                        }
                                        c <<= 8;
                                        c |= (unsigned char)buf[++i];
                                        rc = c;
                                        c &= 0x0FFF;
                                } else if ((c & 0xF8) == 0xF0) {
                                        if (br - i < 2) {
                                                printf("Faulty keycode, II\n");
                                                continue;
                                        }
                                        c = (unsigned char)buf[++i];
                                        rc <<= 8;
                                        rc |= c;
                                }
                                meta = (c & 0x80) ? "press" : "release";
                                c &= ~0x80;
                                printf("Keyscan 0x%04X: code: %4u/0x%04X %s\n",
                                        rc, c, c, meta);
                        }
                }       break;
                case MODE_RAW:
                        for (i = 0; i < br; ++i)
                                printf("0x%02hhX ", buf[i]);
                        printf("\n");
                        break;
                case MODE_VALUE:
                        for (i = 0; i < br; ++i)
                                printf("%4hhd 0%03hho 0x%02hhX  ",
                                        buf[i], buf[i], buf[i]);
                        printf("\n");
                        break;
                }
        }
        (void)setitimer(ITIMER_REAL, NULL, NULL);

        return 0;
}

Reply via email to