1568 lines
36 KiB
C
1568 lines
36 KiB
C
/*
|
|
* Copyright (C) 2004,2005,2006 Nils Faerber <nils.faerber@kernelconcepts.de>
|
|
* Parts for Stowaway (c) 2005 by Paul Eggleton
|
|
* See README for other authors
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/ioctl.h>
|
|
#include <fcntl.h>
|
|
#include <termios.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <limits.h>
|
|
#include <signal.h>
|
|
#include <linux/apm_bios.h>
|
|
#ifdef USELIRC
|
|
#include <lirc_client.h>
|
|
#endif
|
|
|
|
|
|
#include "keyboards.h"
|
|
#include "dev_uinput.h"
|
|
|
|
#ifndef PATH_MAX
|
|
#define PATH_MAX 1024
|
|
#endif
|
|
|
|
#define ARRAY_SIZE(A) (sizeof(A)/sizeof(A[0]))
|
|
|
|
char debug = 0;
|
|
int uindev = 0;
|
|
static int reinit = 0;
|
|
|
|
#define DEFAULT_TTS "/dev/ttyS0"
|
|
char TTY_PORT[PATH_MAX] = DEFAULT_TTS;
|
|
|
|
void handle_sigterm(int signal)
|
|
{
|
|
dev_uinput_close(uindev);
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
int open_serial(char *port, speed_t baud)
|
|
{
|
|
int fd, res;
|
|
struct termios ssetup;
|
|
|
|
fd=open(port, O_RDWR /*| O_NONBLOCK*/);
|
|
if (fd <= 0) {
|
|
perror("open serial");
|
|
fprintf(stderr,"opening %s failed\n", port);
|
|
return (-1);
|
|
}
|
|
|
|
res = tcgetattr(fd, &ssetup);
|
|
if (res < 0) {
|
|
perror("tcgetattr");
|
|
return (-1);
|
|
}
|
|
|
|
ssetup.c_iflag = 0L;
|
|
ssetup.c_oflag = 0L;
|
|
ssetup.c_cflag &= ~(CSTOPB|PARENB|CRTSCTS);
|
|
ssetup.c_cflag |= (CS8|CLOCAL);
|
|
ssetup.c_lflag = 0L;
|
|
ssetup.c_cc[VTIME] = 0;
|
|
ssetup.c_cc[VMIN] = 1;
|
|
cfsetispeed(&ssetup, baud);
|
|
cfsetospeed(&ssetup, baud);
|
|
|
|
res=tcsetattr(fd, TCSANOW, &ssetup);
|
|
if (res < 0) {
|
|
perror("tcsetattr");
|
|
return (-1);
|
|
}
|
|
|
|
return (fd);
|
|
}
|
|
|
|
|
|
#ifdef USELIRC
|
|
int lirc(char *progname)
|
|
{
|
|
struct lirc_config *config;
|
|
|
|
if (debug)
|
|
fprintf(stderr, "progname %s\n",progname);
|
|
if (lirc_init(progname,1) == -1) {
|
|
printf("failed to init lirc\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
if (debug)
|
|
fprintf(stderr, "in lirc\n");
|
|
if (lirc_readconfig(NULL,&config,NULL) == 0) {
|
|
int i, ret;
|
|
char *code, *c;
|
|
|
|
while (lirc_nextcode(&code) == 0) {
|
|
if (code == NULL)
|
|
continue;
|
|
while ((ret = lirc_code2char(config, code, &c)) == 0 &&
|
|
c != NULL) {
|
|
sscanf(c,"%x",&i);
|
|
if (debug)
|
|
fprintf(stderr, "%s %u\n",c,i);
|
|
dev_uinput_key(uindev, i, KEY_PRESSED);
|
|
dev_uinput_key(uindev, i, KEY_RELEASED);
|
|
if (debug)
|
|
fprintf(stderr, "Code : %s\n",c);
|
|
}
|
|
free(code);
|
|
if (ret == -1)
|
|
break;
|
|
}
|
|
lirc_freeconfig(config);
|
|
}
|
|
|
|
return lirc_deinit();
|
|
}
|
|
#endif
|
|
|
|
|
|
int compaq_foldable(void)
|
|
{
|
|
int fd;
|
|
unsigned char buf[16];
|
|
char fn=0;
|
|
|
|
fd = open_serial(TTY_PORT, B4800);
|
|
if (fd <= 0)
|
|
return (-1);
|
|
|
|
while (fd > 0) {
|
|
read (fd, buf, 2);
|
|
// fprintf(stderr, "0x%02x 0x%02x 0x%02x | ", buf[0], buf[1], ~buf[0]);
|
|
if (buf[0] == (unsigned char)~buf[1]) {
|
|
if (debug) fprintf(stderr, "press: %d ", buf[0]);
|
|
if (buf[0] == 0x02) {
|
|
fn=1;
|
|
continue;
|
|
}
|
|
if (fn)
|
|
buf[0] = foldable_function[buf[0]];
|
|
else
|
|
buf[0] = foldable_normal[buf[0]];
|
|
if (debug)
|
|
fprintf(stderr,"= 0x%02x\n", buf[0]);
|
|
if (buf[0] > 0)
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_PRESSED);
|
|
} else if (((unsigned char)buf[0] & (unsigned char)~0x80) == (unsigned char)~buf[1]) {
|
|
if (debug)
|
|
fprintf(stderr, "rel. : %d ", buf[0] & ~0x80);
|
|
if ((buf[0] & ~0x80) == 0x02) {
|
|
fn = 0;
|
|
continue;
|
|
}
|
|
if (fn)
|
|
buf[0] = foldable_function[(unsigned char)buf[0] & (unsigned char)~0x80];
|
|
else
|
|
buf[0] = foldable_normal[(unsigned char)buf[0] & (unsigned char)~0x80];
|
|
if (debug)
|
|
fprintf(stderr,"= 0x%02x\n", buf[0]);
|
|
if (buf[0] > 0)
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_RELEASED);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int lastChar = 0;
|
|
char shiftState = 0;
|
|
char altState = 0;
|
|
char ctrlState = 0;
|
|
|
|
//struct timeval tvlast;
|
|
//unsigned char lastkey;
|
|
|
|
int belkin_infrared(void)
|
|
{
|
|
int fd;
|
|
//unsigned char buf[16];
|
|
unsigned char buf;
|
|
unsigned char key;
|
|
unsigned int key_down;
|
|
unsigned int key_state;
|
|
unsigned char keycode;
|
|
int isChar = 0;
|
|
//struct timeval tv;
|
|
// gettimeofday(&tv, NULL);
|
|
|
|
|
|
fd = open_serial(TTY_PORT, B9600);
|
|
if (fd <= 0)
|
|
return (-1);
|
|
|
|
while (fd > 0) {
|
|
// read (fd, buf, 2);
|
|
// key = buf[1] & 0x7f;
|
|
// key_down = !(buf[1] & 0x80);
|
|
|
|
read (fd, &buf, 1);
|
|
key = buf & 0x7f;
|
|
key_down = !(buf & 0x80);
|
|
|
|
// keycode = belkin_irda_normal[key];
|
|
keycode = key;
|
|
switch (keycode) {
|
|
case 81: keycode = 16; break; //q -
|
|
case 87: keycode = 17; break; //w -
|
|
case 69: keycode = 18; break; //e -
|
|
case 82: keycode = 19; break; //r -
|
|
case 84: keycode = 20; break; //t -
|
|
case 89: keycode = 21; break; //y -
|
|
case 85: keycode = 22; break; //u -
|
|
case 73: keycode = 23; break; //i -
|
|
case 79: keycode = 24; break; //o -
|
|
case 80: keycode = 25; break; //p -
|
|
case 91: keycode = 26; break; //[ -
|
|
case 93: keycode = 27; break; //] -
|
|
case 13: keycode = 28; break; // ret -
|
|
|
|
case 94: keycode = 30; break; //a -
|
|
case 83: keycode = 31; break; //s -
|
|
case 68: keycode = 32; break; //d -
|
|
case 70: keycode = 33; break; //f -
|
|
case 71: keycode = 34; break; //g -
|
|
case 72: keycode = 35; break; //h
|
|
case 74: keycode = 36; break; //j -
|
|
case 75: keycode = 37; break; //k -
|
|
case 76: keycode = 38; break; //l -
|
|
case 59: keycode = 39; break; //;
|
|
case 44: keycode = 40; break; //' -
|
|
|
|
|
|
case 90: keycode = 44; break; //z -
|
|
case 88: keycode = 45; break; //x -
|
|
case 67: keycode = 46; break; //c -
|
|
case 86: keycode = 47; break; //v
|
|
case 66: keycode = 48; break; //b
|
|
case 78: keycode = 49; break; //n
|
|
case 77: keycode = 50; break; //m
|
|
case 60: keycode = 51; break; //,<
|
|
case 46: keycode = 52; break; //.>
|
|
case 47: keycode = 53; break; // /? -
|
|
|
|
|
|
case 27: keycode = 1; break; // til
|
|
case 49: keycode = 2; break; // 1
|
|
case 50: keycode = 3; break; // 2
|
|
case 51: keycode = 4; break; // 3
|
|
case 52: keycode = 5; break; // 4
|
|
case 53: keycode = 6; break; // 5
|
|
case 54: keycode = 7; break; // 6
|
|
case 55: keycode = 8; break; // 7
|
|
case 56: keycode = 9; break; // 8
|
|
case 57: keycode = 10; break; // 9
|
|
case 48: keycode = 11; break; // 0
|
|
case 45: keycode = 12; break; // -
|
|
case 61: keycode = 13; break; //-=
|
|
case 8: keycode = 14; break; // bkspace
|
|
case 9: keycode = 15; break; // tab
|
|
|
|
case 20: keycode = 58; break; // caps lock
|
|
case 16: // shift l -
|
|
case 18: keycode = 42;
|
|
break; // shift r
|
|
case 17: keycode = 29;
|
|
break; // ctrl
|
|
case 29: keycode = 56;
|
|
break; // alt
|
|
case 32: keycode = 57; break; // space -
|
|
case 33: keycode = 57; break; // space -
|
|
case 92: keycode = 43; break; // backslash bar -
|
|
case 19: keycode = 111; break; // del
|
|
case 37: keycode = 103; break; // right
|
|
case 38: keycode = 105; break; // up
|
|
case 39: keycode = 108; break; // left
|
|
case 40: keycode = 106; break; // down
|
|
|
|
//default: keycode =0; break;
|
|
|
|
|
|
//case 79: keycode = 24; break;
|
|
|
|
|
|
}
|
|
|
|
if ( /*(keycode >= 2 && keycode <=13) || */(keycode >= 16 && keycode <= 25)
|
|
|| (keycode >= 30 && keycode <= 38) || (keycode >= 44 && keycode <= 50))
|
|
{
|
|
isChar = 1;
|
|
if (debug && isChar) fprintf (stderr, "is char\n");
|
|
|
|
}
|
|
|
|
|
|
//if (debug)
|
|
// fprintf(stderr, "ctrl:%d alt:%d shift:%d\n", ctrlState, altState, shiftState);
|
|
|
|
// if (! isChar) {
|
|
if ( key_down )
|
|
key_state = KEY_PRESSED;
|
|
else
|
|
key_state = KEY_RELEASED;
|
|
if (lastChar == 64)
|
|
key_state = KEY_RELEASED;
|
|
|
|
if (debug)
|
|
fprintf(stderr,"event %d %d\n", key_state, keycode);
|
|
dev_uinput_key(uindev, (unsigned short)keycode, key_state);
|
|
lastChar = keycode;
|
|
/* } else {
|
|
if (! key_down && keycode == lastChar) {
|
|
if (shiftState) {
|
|
if (debug) fprintf(stderr,"release %d\n", 14);
|
|
dev_uinput_key(uindev, (unsigned short)14, KEY_RELEASED);
|
|
} else if (ctrlState || altState) {
|
|
if (debug) fprintf(stderr,"release %d\n", 19);
|
|
dev_uinput_key(uindev, (unsigned short)19, KEY_RELEASED);
|
|
}
|
|
|
|
if (debug && keycode)
|
|
fprintf(stderr,"press %d\n", keycode);
|
|
dev_uinput_key(uindev, (unsigned short)keycode, KEY_PRESSED);
|
|
if (debug && keycode)
|
|
fprintf(stderr,"release %d\n", keycode);
|
|
dev_uinput_key(uindev, (unsigned short)keycode, KEY_RELEASED);
|
|
if (debug && keycode)
|
|
fprintf(stderr,"release %d\n", keycode);
|
|
dev_uinput_key(uindev, (unsigned short)keycode, KEY_RELEASED);
|
|
}
|
|
lastChar = keycode;
|
|
}*/
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int freedom_keyboard(void)
|
|
{
|
|
int fd;
|
|
unsigned char buf[16];
|
|
unsigned char key;
|
|
unsigned int key_down;
|
|
unsigned char keycode;
|
|
|
|
fd = open_serial(TTY_PORT, B9600);
|
|
if (fd <= 0)
|
|
return (-1);
|
|
|
|
while (fd > 0) {
|
|
read (fd, buf, 1);
|
|
key = buf[0];
|
|
//keyboard sends n when pressing a key
|
|
// and n+63 when releasing the key
|
|
key_down = ( key < 63 );
|
|
if (!key_down)
|
|
key = (key-63)&0x3F; // convert key code for key up
|
|
keycode = freedom_kbd[key];
|
|
if (debug)
|
|
fprintf(stdout, "0x%02x 0x%02x\n", buf[0], keycode);
|
|
if ( key_down ) {
|
|
if (debug)
|
|
fprintf(stdout,"press %d\n", keycode);
|
|
dev_uinput_key(uindev, (unsigned short)keycode, KEY_PRESSED);
|
|
} else {
|
|
if (debug)
|
|
fprintf(stdout,"release %d\n", keycode);
|
|
dev_uinput_key(uindev, (unsigned short)keycode, KEY_RELEASED);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int select_read(int fd, int timeout_sec, int timeout_us)
|
|
{
|
|
fd_set fds;
|
|
struct timeval tv;
|
|
|
|
FD_ZERO(&fds);
|
|
FD_SET(fd, &fds);
|
|
tv.tv_sec = timeout_sec;
|
|
tv.tv_usec = timeout_us;
|
|
return select(fd+1, &fds, NULL, NULL, &tv);
|
|
}
|
|
|
|
|
|
int stowaway_init(int fd)
|
|
{
|
|
int status;
|
|
unsigned char buf[16];
|
|
|
|
ioctl(fd, TIOCMGET, &status);
|
|
status |= TIOCM_DTR; /* Set DTR */
|
|
status &= ~TIOCM_RTS; /* Clear RTS */
|
|
ioctl(fd, TIOCMSET, &status);
|
|
|
|
/* Unfortunately, DCD seems to be high all of the time on H3900, so the following can't be used */
|
|
/* ioctl(fd, TIOCMIWAIT, TIOCM_CAR */
|
|
/* So we just wait instead */
|
|
usleep(1000000);
|
|
|
|
ioctl(fd, TIOCMGET, &status);
|
|
status |= TIOCM_RTS; /* Set RTS */
|
|
ioctl(fd, TIOCMSET, &status);
|
|
/* Stowaway will send back 0xFA 0xFD indicating successful init */
|
|
if (select_read(fd, 2, 0)) {
|
|
read(fd, buf, 2);
|
|
if ((buf[0] == 0xFA) && (buf[0] == 0xFD))
|
|
if (debug)
|
|
fprintf(stderr, "keyboard initialised\n");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int open_apm(void)
|
|
{
|
|
int fd;
|
|
|
|
fd = open( "/dev/apm_bios", O_RDONLY | O_NONBLOCK );
|
|
if (fd <= 0)
|
|
return -1;
|
|
|
|
return fd;
|
|
}
|
|
|
|
|
|
int check_apm_resume(int fd)
|
|
{
|
|
apm_event_t ev;
|
|
int resumed;
|
|
|
|
resumed = 0;
|
|
while (read(fd, &ev, sizeof(apm_event_t)) > 0) {
|
|
if (ev == APM_NORMAL_RESUME)
|
|
resumed = 1;
|
|
}
|
|
|
|
return resumed;
|
|
}
|
|
|
|
|
|
void stowaway_sig(int sig)
|
|
{
|
|
reinit = 1;
|
|
}
|
|
|
|
|
|
int stowaway(void)
|
|
{
|
|
int fd, apm_fd;
|
|
unsigned char buf[16];
|
|
char fn=0;
|
|
struct sigaction act;
|
|
int rc;
|
|
|
|
fd = open_serial(TTY_PORT, B9600);
|
|
if (fd <= 0)
|
|
return (-1);
|
|
|
|
/* Make SIGHUP cause a reinit of the keyboard */
|
|
act.sa_handler = stowaway_sig;
|
|
sigemptyset(&act.sa_mask);
|
|
act.sa_flags = 0;
|
|
sigaction(SIGHUP, &act, NULL);
|
|
|
|
/* Open APM so we can listen for resume events */
|
|
apm_fd = open_apm();
|
|
|
|
while (fd > 0) {
|
|
|
|
stowaway_init(fd);
|
|
|
|
while (fd > 0) {
|
|
rc = select_read(fd, 0, 100000);
|
|
if (rc == -1) {
|
|
if (reinit) {
|
|
reinit = 0;
|
|
break;
|
|
} else {
|
|
perror("select");
|
|
return 1;
|
|
}
|
|
} else if (rc == 0) {
|
|
/* Timeout expired with nothing read, do APM resume check */
|
|
if ((apm_fd > 0) && (check_apm_resume(apm_fd)))
|
|
break;
|
|
continue;
|
|
}
|
|
|
|
rc = read (fd, buf, 1);
|
|
if (rc == -1) {
|
|
if (reinit) {
|
|
reinit = 0;
|
|
break;
|
|
} else {
|
|
perror("read");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if ( ((unsigned char)buf[0] & (unsigned char)0x80) == 0 ) {
|
|
if (debug)
|
|
fprintf(stderr, "press: %d\n", buf[0]);
|
|
if (buf[0] == 0x08) {
|
|
fn = 1;
|
|
continue;
|
|
}
|
|
if (fn)
|
|
buf[0] = stowaway_function[buf[0]];
|
|
else
|
|
buf[0] = stowaway_normal[buf[0]];
|
|
if (debug)
|
|
fprintf(stderr,"= 0x%02x\n", buf[0]);
|
|
if (buf[0] > 0)
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_PRESSED);
|
|
} else {
|
|
if (debug)
|
|
fprintf(stderr, "rel. : %d\n", buf[0] & ~0x80);
|
|
if ((buf[0] & ~0x80) == 0x08) {
|
|
fn = 0;
|
|
continue;
|
|
}
|
|
if (fn)
|
|
buf[0] = stowaway_function[(unsigned char)buf[0] & (unsigned char)~0x80];
|
|
else
|
|
buf[0] = stowaway_normal[(unsigned char)buf[0] & (unsigned char)~0x80];
|
|
if (debug)
|
|
fprintf(stderr,"= 0x%02x\n", buf[0]);
|
|
if (buf[0] > 0)
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_RELEASED);
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int stowawayxt(void)
|
|
{
|
|
#define STOWAWAYXT_GR_FN 33
|
|
#define STOWAWAYXT_BL_FN 34
|
|
|
|
int fd, apm_fd;
|
|
unsigned char buf[16];
|
|
char bluefn=0,greenfn=0;
|
|
struct sigaction act;
|
|
int rc;
|
|
|
|
fd = open_serial(TTY_PORT, B9600);
|
|
if (fd <= 0)
|
|
return (-1);
|
|
|
|
/* Make SIGHUP cause a reinit of the keyboard */
|
|
act.sa_handler = stowaway_sig;
|
|
sigemptyset(&act.sa_mask);
|
|
act.sa_flags = 0;
|
|
sigaction(SIGHUP, &act, NULL);
|
|
|
|
/* Open APM so we can listen for resume events */
|
|
apm_fd = open_apm();
|
|
|
|
while (fd > 0) {
|
|
stowaway_init(fd);
|
|
|
|
while (fd > 0) {
|
|
rc = select_read(fd, 0, 100000);
|
|
if (rc == -1) {
|
|
if (reinit) {
|
|
reinit = 0;
|
|
break;
|
|
} else {
|
|
perror("select");
|
|
return 1;
|
|
}
|
|
} else if (rc == 0) {
|
|
/* Timeout expired with nothing read, do APM resume check */
|
|
if ((apm_fd > 0) && (check_apm_resume(apm_fd)))
|
|
break;
|
|
continue;
|
|
}
|
|
|
|
rc = read (fd, buf, 1);
|
|
if (rc == -1) {
|
|
if (reinit) {
|
|
reinit = 0;
|
|
break;
|
|
} else {
|
|
perror("read");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if ( ((unsigned char)buf[0] & (unsigned char)0x80) == 0 ) {
|
|
/* KEY PRESSED */
|
|
if (debug)
|
|
fprintf(stderr, "press: %d\n", buf[0]);
|
|
if (buf[0] == STOWAWAYXT_BL_FN) {
|
|
bluefn = 1;
|
|
continue;
|
|
}
|
|
|
|
if (buf[0] == STOWAWAYXT_GR_FN) {
|
|
greenfn = 1;
|
|
dev_uinput_key(uindev,42,KEY_PRESSED);
|
|
continue;
|
|
}
|
|
|
|
if (bluefn)
|
|
buf[0] = stowawayxt_function[buf[0]];
|
|
else if (greenfn) {
|
|
buf[0] = stowawayxt_function[buf[0]];
|
|
/* fixup where green function is not shift blue function */
|
|
switch (buf[0]) {
|
|
case KEY_UP:
|
|
buf[0] = KEY_PAGEUP;
|
|
break;
|
|
case KEY_LEFT:
|
|
buf[0] = KEY_HOME;
|
|
break;
|
|
case KEY_DOWN:
|
|
buf[0] = KEY_PAGEDOWN;
|
|
break;
|
|
case KEY_RIGHT:
|
|
buf[0] = KEY_END;
|
|
break;
|
|
case KEY_INTL2:
|
|
buf[0] = KEY_INTL3;
|
|
break;
|
|
} /* /switch */
|
|
} else
|
|
buf[0]=stowawayxt_normal[buf[0]];
|
|
|
|
if (debug)
|
|
fprintf(stderr,"= 0x%02x\n", buf[0]);
|
|
if (buf[0] != KEY_RESERVED)
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_PRESSED);
|
|
|
|
} else {
|
|
/* KEY RELEASED */
|
|
if (debug)
|
|
fprintf(stderr, "rel. : %d\n", buf[0] & ~0x80);
|
|
|
|
if ((buf[0] & ~0x80) == STOWAWAYXT_BL_FN) {
|
|
bluefn = 0;
|
|
continue;
|
|
}
|
|
|
|
if ((buf[0] & ~0x80) == STOWAWAYXT_GR_FN) {
|
|
greenfn = 0;
|
|
dev_uinput_key(uindev,42,KEY_RELEASED);
|
|
continue;
|
|
}
|
|
|
|
if (bluefn)
|
|
buf[0] = stowawayxt_function[(unsigned char) buf[0] & (unsigned char)~0x80];
|
|
else if (greenfn) {
|
|
buf[0] = stowawayxt_function[(unsigned char) buf[0] & (unsigned char)~0x80];
|
|
|
|
/* fixup where green function is not shift blue function */
|
|
switch(buf[0]) {
|
|
case KEY_UP:
|
|
buf[0] = KEY_PAGEUP;
|
|
break;
|
|
case KEY_LEFT:
|
|
buf[0] = KEY_HOME;
|
|
break;
|
|
case KEY_DOWN:
|
|
buf[0] = KEY_PAGEDOWN;
|
|
break;
|
|
case KEY_RIGHT:
|
|
buf[0] = KEY_END;
|
|
break;
|
|
case KEY_INTL2:
|
|
buf[0] = KEY_INTL3;
|
|
break;
|
|
} /* /switch */
|
|
} else
|
|
buf[0] = stowawayxt_normal[(unsigned char)buf[0] & (unsigned char)~0x80];
|
|
|
|
if (debug)
|
|
fprintf(stderr,"= 0x%02x\n", buf[0]);
|
|
if (buf[0] != KEY_RESERVED)
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_RELEASED);
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int snapntype(void)
|
|
{
|
|
int fd;
|
|
unsigned char buf[16];
|
|
char symb=0;
|
|
|
|
fd = open_serial(TTY_PORT, B2400);
|
|
|
|
while (fd > 0) {
|
|
read (fd, buf, 1);
|
|
if (debug)
|
|
fprintf(stderr, "got %d\n", buf[0]);
|
|
if (buf[0] & 0x80) { /* release */
|
|
read(fd,buf+1,1);
|
|
buf[0] = buf[0] & 0x7f;
|
|
if (buf[0] == 27) {
|
|
symb = 0;
|
|
continue;
|
|
}
|
|
if (symb)
|
|
buf[0] = snapntype_symbol[buf[0]];
|
|
else
|
|
buf[0] = snapntype_normal[buf[0]];
|
|
if (debug)
|
|
fprintf(stderr, " release %d\n", buf[0]);
|
|
if (buf[0] != 0)
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_RELEASED);
|
|
} else { /* press */
|
|
if (buf[0] == 27) {
|
|
symb=1;
|
|
continue;
|
|
}
|
|
if (symb)
|
|
buf[0] = snapntype_symbol[buf[0]];
|
|
else
|
|
buf[0] = snapntype_normal[buf[0]];
|
|
if (debug)
|
|
fprintf(stderr, " press %d\n", buf[0]);
|
|
if (buf[0] != 0)
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_PRESSED);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int snapntypebt(void)
|
|
{
|
|
int fd;
|
|
unsigned char buf[16];
|
|
unsigned char key, last_key=0;
|
|
unsigned char pressed;
|
|
unsigned char fn = 0;
|
|
|
|
fd = open_serial(TTY_PORT, B9600);
|
|
|
|
while (fd > 0) {
|
|
read (fd, buf, 1);
|
|
read (fd, buf+1, 1);
|
|
if (debug)
|
|
fprintf(stderr, "got %02x%02x\n", buf[0],buf[1]);
|
|
if (buf[1] & 0x80) { /* release */
|
|
key = buf[1] & 0x7F;
|
|
|
|
if (key == 30) {
|
|
fn = 0;
|
|
if (last_key) {
|
|
dev_uinput_key(uindev, (unsigned short)snapntypebt_fn[last_key], KEY_RELEASED);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
pressed = KEY_RELEASED;
|
|
if (debug)
|
|
fprintf(stderr, " release:");
|
|
} else {
|
|
key = buf[1];
|
|
|
|
if (key == 30) {
|
|
fn = 1;
|
|
last_key = 0;
|
|
continue;
|
|
}
|
|
|
|
pressed = KEY_PRESSED;
|
|
if (debug)
|
|
fprintf(stderr, " press: ");
|
|
}
|
|
if (debug)
|
|
fprintf(stderr, " %d (%d)\n",key,snapntypebt_normal[key]);
|
|
|
|
if (!fn)
|
|
key = snapntypebt_normal[key];
|
|
else {
|
|
last_key = key;
|
|
key = snapntypebt_fn[key];
|
|
}
|
|
if (key != 0 && !debug)
|
|
dev_uinput_key(uindev, (unsigned short)key, pressed);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int hpslim(void)
|
|
{
|
|
int fd;
|
|
unsigned char cin;
|
|
unsigned char cnew;
|
|
char symb=0;
|
|
char shft=0;
|
|
char symshft=0;
|
|
char numlck=0;
|
|
|
|
fd = open_serial(TTY_PORT, B4800);
|
|
if (fd < 0)
|
|
return -1;
|
|
|
|
for (;;) {
|
|
if (read (fd, &cin, 1) < 0) {
|
|
perror(TTY_PORT);
|
|
return -1;
|
|
}
|
|
if (debug)
|
|
fprintf(stderr, "got %d 0x%x\n", cin,cin);
|
|
if (cin & 0x80) { /* release */
|
|
cin &= 0x7f;
|
|
switch (cin) {
|
|
case MKBD_HPS_FNKEY: /* Fn key release */
|
|
symb = 0;
|
|
continue;
|
|
case KEY_LEFTSHIFT:
|
|
case KEY_RIGHTSHIFT:
|
|
shft = 0;
|
|
break;
|
|
}
|
|
if (symb)
|
|
cnew = hpslim_symbol[cin];
|
|
else {
|
|
/* if numlock, convert QWERTYUIOP to 1-9,0 */
|
|
if (numlck && cin >= KEY_Q && cin <= KEY_P)
|
|
cnew = cin + KEY_1 - KEY_Q;
|
|
else
|
|
cnew = hpslim_normal[cin];
|
|
}
|
|
if (debug)
|
|
fprintf(stderr, " release cnew=%d 0x%x\n", cnew,cnew);
|
|
if (cnew != 0) {
|
|
dev_uinput_key(uindev, (unsigned short)cnew, KEY_RELEASED);
|
|
if (symshft)
|
|
dev_uinput_key(uindev, (unsigned short)KEY_RIGHTSHIFT, KEY_RELEASED);
|
|
symshft = 0;
|
|
// toggle numlck on release
|
|
if (cnew == KEY_NUMLOCK) numlck = !numlck;
|
|
}
|
|
} else { /* press */
|
|
switch (cin) {
|
|
case MKBD_HPS_FNKEY: /* Fn key press */
|
|
symb = 1;
|
|
continue;
|
|
case KEY_LEFTSHIFT:
|
|
case KEY_RIGHTSHIFT:
|
|
shft = 1;
|
|
break;
|
|
}
|
|
if (symb) {
|
|
/* if shift needed to get correct char */
|
|
symshft = hpslim_symshft[cin] && !shft;
|
|
cnew = hpslim_symbol[cin];
|
|
} else {
|
|
/* if numlock, convert QWERTYUIOP to 1-9,0 */
|
|
if (numlck && cin >= KEY_Q && cin <= KEY_P)
|
|
cnew = cin + KEY_1 - KEY_Q;
|
|
else
|
|
cnew = hpslim_normal[cin];
|
|
}
|
|
if (debug)
|
|
fprintf(stderr, " press cnew=%d 0x%x\n", cnew,cnew);
|
|
if (cnew != 0) {
|
|
if (symshft)
|
|
dev_uinput_key(uindev, (unsigned short)KEY_RIGHTSHIFT, KEY_PRESSED);
|
|
dev_uinput_key(uindev, (unsigned short)cnew, KEY_PRESSED);
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int smartbt(void)
|
|
{
|
|
int fd;
|
|
unsigned char buf[16];
|
|
|
|
fd = open_serial(TTY_PORT, B2400);
|
|
|
|
while (fd > 0) {
|
|
read (fd, buf, 1);
|
|
if (buf[0] > 126) {
|
|
if (debug)
|
|
fprintf(stderr, "error: unexpected char %d\n", buf[0]);
|
|
continue;
|
|
}
|
|
if (buf[0] > 63) {
|
|
/* release */
|
|
buf[0] = buf[0] - 63;
|
|
if (debug)
|
|
fprintf(stderr, "rel.: %d\n", buf[0]);
|
|
buf[0] = smartbt_normal[buf[0]];
|
|
if (debug)
|
|
fprintf(stderr,"= 0x%02x\n", buf[0]);
|
|
if (buf[0] > 0)
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_RELEASED);
|
|
} else {
|
|
/* press */
|
|
if (debug)
|
|
fprintf(stderr, "press: %d\n", buf[0]);
|
|
buf[0] = smartbt_normal[buf[0]];
|
|
if (debug)
|
|
fprintf(stderr,"= 0x%02x\n", buf[0]);
|
|
if (buf[0] > 0)
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_PRESSED);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int flexis(void)
|
|
{
|
|
int fd;
|
|
unsigned char buf[16];
|
|
char symb=0;
|
|
|
|
fd = open_serial(TTY_PORT, B9600);
|
|
|
|
while (fd > 0) {
|
|
read (fd, buf, 1);
|
|
if (debug)
|
|
fprintf(stderr, "got %d\n", buf[0]);
|
|
|
|
if (buf[0] & 0x80) { /* key press */
|
|
buf[0] = buf[0] & 0x7f;
|
|
|
|
if (symb)
|
|
buf[0] = flexis_fx100_function[buf[0]];
|
|
else
|
|
buf[0] = flexis_fx100_normal[buf[0]];
|
|
|
|
/* FIXME: function key */
|
|
/* FIXME: this code is a little broken, it should check scancode not keycode for set 1/2 */
|
|
|
|
if (buf[0] == KEY_LEFTSHIFT || buf[0] == KEY_RIGHTSHIFT ||
|
|
buf[0] == KEY_LEFTCTRL || buf[0] == KEY_RIGHTCTRL ||
|
|
buf[0] == KEY_LEFTALT || buf[0] == KEY_RIGHTALT ) {
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_PRESSED);
|
|
} else {
|
|
read(fd,buf+1,1);
|
|
if (debug)
|
|
fprintf(stderr, "got %d\n", buf[1]);
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_PRESSED);
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_RELEASED);
|
|
}
|
|
} else { /* release of key from Set 2 */
|
|
if (symb)
|
|
buf[0] = flexis_fx100_function[buf[0]];
|
|
else
|
|
buf[0] = flexis_fx100_normal[buf[0]];
|
|
if (buf[0] != 0)
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_RELEASED);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int benqgamepad(void) {
|
|
int fd;
|
|
unsigned char buf[16];
|
|
int i;
|
|
unsigned char keycode;
|
|
|
|
fd = open_serial(TTY_PORT, B4800);
|
|
|
|
while (fd > 0) {
|
|
keycode = 0;
|
|
read (fd, buf, 2);
|
|
if (buf[0] & 0x80) { /* release */
|
|
if (debug)
|
|
fprintf(stderr, "release: %d %d\n", buf[0], buf[1]);
|
|
buf[0] = buf[0] & 0x7f;
|
|
for (i=0; i<10; i++) {
|
|
if (benq_gamepad_map[i][0] == buf[0]) {
|
|
keycode = benq_gamepad_map[i][1];
|
|
break;
|
|
}
|
|
}
|
|
if (keycode != 0)
|
|
dev_uinput_key(uindev, (unsigned short)keycode, KEY_RELEASED);
|
|
|
|
} else {
|
|
if (debug)
|
|
fprintf(stderr, "press: %d %d\n", buf[0], buf[1]);
|
|
for (i=0; i<10; i++) {
|
|
if (benq_gamepad_map[i][0] == buf[0]) {
|
|
keycode = benq_gamepad_map[i][1];
|
|
break;
|
|
}
|
|
}
|
|
if (keycode != 0)
|
|
dev_uinput_key(uindev, (unsigned short)keycode, KEY_PRESSED);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int pocketvik(void)
|
|
{
|
|
int fd;
|
|
unsigned char buf[16];
|
|
unsigned char mods=0;
|
|
int res;
|
|
struct termios ssetup;
|
|
int i;
|
|
|
|
fd = open_serial(TTY_PORT, B57600);
|
|
|
|
/* PocketVIK needs CRTSCTS */
|
|
res = tcgetattr(fd, &ssetup);
|
|
if (res < 0) {
|
|
perror("tcgetattr");
|
|
return (-1);
|
|
}
|
|
ssetup.c_cflag |= CRTSCTS;
|
|
res = tcsetattr(fd, TCSANOW, &ssetup);
|
|
if (res < 0) {
|
|
perror("tcgetattr");
|
|
return (-1);
|
|
}
|
|
|
|
while (fd > 0) {
|
|
read (fd, buf, 1);
|
|
if (debug)
|
|
fprintf(stderr, "got %d\n", buf[0]);
|
|
|
|
if (buf[0] & 0x80) { /* press with modifiers */
|
|
mods = buf[0] & 0x7f;
|
|
read (fd, buf, 1);
|
|
} else
|
|
mods = 0;
|
|
|
|
if (mods & POCKETVIK_Fn)
|
|
buf[0] = pocketvik_function[buf[0]];
|
|
else
|
|
buf[0] = pocketvik_normal[buf[0]];
|
|
|
|
if (buf[0] != 0) {
|
|
if (debug)
|
|
fprintf(stderr, "press/release %d\n", buf[0]);
|
|
|
|
/* Modifiers down */
|
|
for ( i = 0 ; i < ARRAY_SIZE(pocketvik_modifiers) ; i++ ) {
|
|
if (pocketvik_modifiers[i].mask & mods)
|
|
dev_uinput_key(uindev, pocketvik_modifiers[i].key, KEY_PRESSED);
|
|
}
|
|
|
|
/* Key down */
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_PRESSED);
|
|
/* Key up */
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_RELEASED);
|
|
|
|
/* Modifiers up */
|
|
for (i = 0; i < ARRAY_SIZE(pocketvik_modifiers); i++ ) {
|
|
if (pocketvik_modifiers[i].mask & mods)
|
|
dev_uinput_key(uindev, pocketvik_modifiers[i].key, KEY_RELEASED);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int micro_foldaway(void) {
|
|
int fd;
|
|
unsigned char buf[16];
|
|
unsigned char lastkey = 0;
|
|
// char symb=0;
|
|
int checkkey = 0;
|
|
|
|
fd = open_serial(TTY_PORT, B9600);
|
|
|
|
while (fd > 0) {
|
|
read (fd, buf, 1);
|
|
if (debug)
|
|
fprintf(stderr, "got: %d\n", buf[0]);
|
|
if (buf[0] & 0x80) { /* possible release */
|
|
checkkey = (159 - buf[0]);
|
|
if (checkkey > 0 && checkkey <= 4) {
|
|
buf[0] = micro_foldaway_normal[159 - buf[0]];
|
|
dev_uinput_key(uindev, buf[0], KEY_RELEASED);
|
|
} else if (buf[0] == 133 && lastkey > 0) {
|
|
dev_uinput_key(uindev, lastkey, KEY_RELEASED);
|
|
lastkey = 0;
|
|
}
|
|
/* Eat repeated code */
|
|
read (fd, buf, 1);
|
|
} else {
|
|
checkkey = buf[0];
|
|
/* if (symb)
|
|
buf[0] = micro_foldaway_function[buf[0]];
|
|
else*/
|
|
buf[0] = micro_foldaway_normal[buf[0]];
|
|
|
|
if (buf[0] != 0) {
|
|
if (checkkey > 4)
|
|
lastkey = buf[0]; /* Not a modifier, record key */
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_PRESSED);
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int micro_datapad(void) {
|
|
int fd;
|
|
unsigned char buf[16];
|
|
unsigned char lastkey = 0;
|
|
int checkkey = 0;
|
|
|
|
fd = open_serial(TTY_PORT, B9600);
|
|
|
|
while (fd > 0) {
|
|
read (fd, buf, 1);
|
|
if (debug)
|
|
fprintf(stderr, "got: %d\n", buf[0]);
|
|
if (buf[0] & 0x80) { /* possible release */
|
|
checkkey = (159 - buf[0]);
|
|
if (checkkey > 0 && checkkey <= 4) {
|
|
buf[0] = micro_foldaway_normal[159 - buf[0]];
|
|
dev_uinput_key(uindev, buf[0], KEY_RELEASED);
|
|
} else if (buf[0] == 133 && lastkey > 0) {
|
|
dev_uinput_key(uindev, lastkey, KEY_RELEASED);
|
|
lastkey = 0;
|
|
}
|
|
/* Eat repeated code */
|
|
read (fd, buf, 1);
|
|
} else {
|
|
checkkey = buf[0];
|
|
/* if (symb)
|
|
buf[0]=micro_datapad_function[buf[0]];
|
|
else*/
|
|
buf[0] = micro_datapad_normal[buf[0]];
|
|
|
|
if (buf[0] != 0) {
|
|
if (checkkey > 4)
|
|
lastkey = buf[0]; /* Not a modifier, record key */
|
|
dev_uinput_key(uindev, (unsigned short)buf[0], KEY_PRESSED);
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int hp_bt_foldable(void){
|
|
int fd;
|
|
unsigned char buf[1];
|
|
unsigned char cnew;
|
|
char symb=0;
|
|
|
|
fd = open_serial(TTY_PORT, B9600);
|
|
if (fd < 0)
|
|
return -1;
|
|
|
|
for (;;) {
|
|
if (read (fd, buf, 1) < 0) {
|
|
perror(TTY_PORT);
|
|
return -1;
|
|
}
|
|
if (debug)
|
|
fprintf(stderr, "got %d (0x%x)\n", buf[0], buf[0]);
|
|
if (buf[0] & 0x80) { /* release */
|
|
buf[0] &= 0x7f;
|
|
if (buf[0] == 2) {
|
|
symb = 0;
|
|
continue;
|
|
}
|
|
if (symb)
|
|
cnew = btfoldable_function[buf[0]];
|
|
else
|
|
cnew = btfoldable_normal[buf[0]];
|
|
|
|
if (debug)
|
|
fprintf(stderr, " release cnew=%d (0x%x)\n", cnew, cnew);
|
|
if (cnew != 0)
|
|
dev_uinput_key(uindev, (unsigned short)cnew, KEY_RELEASED);
|
|
} else { /* press */
|
|
if (buf[0] == 2) {
|
|
symb = 1;
|
|
continue;
|
|
}
|
|
if (symb)
|
|
cnew = btfoldable_function[buf[0]];
|
|
else
|
|
cnew = btfoldable_normal[buf[0]];
|
|
if (debug)
|
|
fprintf(stderr, " press cnew=%d (0x%x)\n", cnew, cnew);
|
|
if (cnew != 0)
|
|
dev_uinput_key(uindev, (unsigned short)cnew, KEY_PRESSED);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int compaq_microkbd(void)
|
|
{
|
|
int fd;
|
|
unsigned char buf[2];
|
|
unsigned char cnew;
|
|
char symb=0;
|
|
|
|
fd = open_serial(TTY_PORT, B4800);
|
|
if (fd < 0)
|
|
return -1;
|
|
|
|
for (;;) {
|
|
if (read (fd, buf, 2) < 0) {
|
|
perror(TTY_PORT);
|
|
return -1;
|
|
}
|
|
if (debug)
|
|
fprintf(stderr, "got %d %d (0x%x 0x%x)\n", buf[0], buf[1], buf[0], buf[1]);
|
|
if (buf[0] & 0x80) { /* release */
|
|
buf[0] &= 0x7f;
|
|
if (buf[0] == 2) {
|
|
symb = 0;
|
|
continue;
|
|
}
|
|
if (symb)
|
|
cnew = compaq_function[buf[0]];
|
|
else
|
|
cnew = compaq_normal[buf[0]];
|
|
|
|
if (debug)
|
|
fprintf(stderr, " release cnew=%d (0x%x)\n", cnew, cnew);
|
|
if (cnew != 0)
|
|
dev_uinput_key(uindev, (unsigned short)cnew, KEY_RELEASED);
|
|
} else { /* press */
|
|
if (buf[0] == 2) {
|
|
symb = 1;
|
|
continue;
|
|
}
|
|
if (symb)
|
|
cnew = compaq_function[buf[0]];
|
|
else
|
|
cnew = compaq_normal[buf[0]];
|
|
if (debug)
|
|
fprintf(stderr, " press cnew=%d (0x%x)\n", cnew, cnew);
|
|
if (cnew != 0)
|
|
dev_uinput_key(uindev, (unsigned short)cnew, KEY_PRESSED);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int targus_infrared(void)
|
|
{
|
|
int fd;
|
|
unsigned char buf;
|
|
unsigned char key;
|
|
unsigned int key_down;
|
|
unsigned char keycode;
|
|
|
|
fd = open_serial(TTY_PORT, B9600);
|
|
if (fd <= 0)
|
|
return (-1);
|
|
|
|
while (fd > 0) {
|
|
read (fd, &buf, 1);
|
|
key = buf & 0x7f;
|
|
key_down = !(buf & 0x80);
|
|
// keycode = belkin_irda_normal[key];
|
|
keycode = key;
|
|
if (debug)
|
|
fprintf(stderr, "0x%02x 0x%02x\n", buf, key);
|
|
|
|
if ( key_down ) {
|
|
if (debug)
|
|
fprintf(stderr,"press %d\n", keycode);
|
|
dev_uinput_key(uindev, (unsigned short)keycode, KEY_PRESSED);
|
|
} else {
|
|
if (debug)
|
|
fprintf(stderr,"release %d\n", keycode);
|
|
dev_uinput_key(uindev, (unsigned short)keycode, KEY_RELEASED);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void print_usage(char *arg0)
|
|
{
|
|
fprintf (stderr, "kbdd %s\n", VERSION);
|
|
fprintf (stderr, "Usage:\n");
|
|
fprintf (stderr, "%s [-d] [-h] [-c <config file>] -p <serial-port> -t <kbd type>\n", arg0);
|
|
fprintf (stderr, "-d\tenable debugging output\n");
|
|
fprintf (stderr, "-h\tprint this help\n");
|
|
fprintf (stderr, "-c <config file>\n");
|
|
fprintf (stderr, "\tRead port and type from config file\n");
|
|
fprintf (stderr, "-p <serial-port>\n");
|
|
fprintf (stderr, "\tspecify serial port device, default %s\n", DEFAULT_TTS);
|
|
fprintf (stderr, "-t <kbd type>\n");
|
|
fprintf (stderr, "\tspecify the serial keyboard type, supported are:\n");
|
|
fprintf (stderr, "\tfoldable - Compaq/HP foldable keyboard\n");
|
|
fprintf (stderr, "\tstowaway - Targus Stowaway keyboard\n");
|
|
fprintf (stderr, "\tstowawayxt - Stowaway XT\n");
|
|
fprintf (stderr, "\tsnapntype - Snap'n'Type\n");
|
|
fprintf (stderr, "\tsnapntypebt - Snap'n'Type Bluetooth\n");
|
|
fprintf (stderr, "\thpslim - HP Slim keyboard\n");
|
|
fprintf (stderr, "\tsmartbt - Smart Bluetooth keyboard\n");
|
|
fprintf (stderr, "\tlirc - LIRC consumer IR\n");
|
|
fprintf (stderr, "\tbelkinir - Belkin IR (not IrDA)\n");
|
|
fprintf (stderr, "\tflexis - Flexis FX-100 keyboard\n");
|
|
fprintf (stderr, "\tg250 - Benq G250 gamepad\n");
|
|
fprintf (stderr, "\tpocketvik - GrandTec PocketVIK\n");
|
|
fprintf (stderr, "\tmicrofold - Micro Innovations Foldaway keyboard\n");
|
|
fprintf (stderr, "\tmicropad - Micro Innovations Datapad\n");
|
|
fprintf (stderr, "\tmicrokbd - Compaq MicroKeyboard\n");
|
|
fprintf (stderr, "\ttargusir - Targus Universal Wireless keyboard\n");
|
|
fprintf (stderr, "\tbtfoldable - HP iPAQ Bluetooth Foldable Keyboard\n\n");
|
|
fprintf (stderr, "\tfreedom - Freedom keyboard\n");
|
|
fprintf (stderr, "Example:\n\t%s -t foldable\n", arg0);
|
|
}
|
|
|
|
|
|
#define KBD_TYPE_NONE 0
|
|
#define KBD_TYPE_FOLDABLE 1
|
|
#define KBD_TYPE_SNAPNTYPE 2
|
|
#define KBD_TYPE_STOWAWAY 3
|
|
#define KBD_TYPE_STOWAWAYXT 4
|
|
#define KBD_TYPE_HPSLIM 5
|
|
#define KBD_TYPE_SMARTBT 6
|
|
#define KBD_TYPE_LIRC 7
|
|
#define KBD_TYPE_BELKINIR 8
|
|
#define KBD_TYPE_FLEXIS 9
|
|
#define KBD_TYPE_BENQ_GAMEPAD 10
|
|
#define KBD_TYPE_POCKETVIK 11
|
|
#define KBD_TYPE_MICRO_FOLDAWAY 12
|
|
#define KBD_TYPE_MICRO_DATAPAD 13
|
|
#define KBD_TYPE_COMPAQ_MICROKBD 14
|
|
#define KBD_TYPE_TARGUSIR 15
|
|
#define KBD_TYPE_SNAPNTYPEBT 16
|
|
#define KBD_TYPE_BTFOLDABLE 17
|
|
#define KBD_TYPE_FREEDOM 18
|
|
|
|
|
|
int find_kbd_type(const char *ktype)
|
|
{
|
|
if (strncmp("foldable", ktype, 8) == 0)
|
|
return KBD_TYPE_FOLDABLE;
|
|
else if (strncmp("snapntypebt", ktype, 11) == 0)
|
|
return KBD_TYPE_SNAPNTYPEBT;
|
|
else if (strncmp("snapntype", ktype, 9) == 0)
|
|
return KBD_TYPE_SNAPNTYPE;
|
|
else if (strncmp("stowawayxt", ktype, 10) == 0)
|
|
return KBD_TYPE_STOWAWAYXT;
|
|
else if (strncmp("stowaway", ktype, 8) == 0)
|
|
return KBD_TYPE_STOWAWAY;
|
|
else if (strncmp("hpslim", ktype, 6) == 0)
|
|
return KBD_TYPE_HPSLIM;
|
|
else if (strncmp("smartbt", ktype, 7) == 0)
|
|
return KBD_TYPE_SMARTBT;
|
|
else if (strncmp("flexis", ktype, 6) == 0)
|
|
return KBD_TYPE_FLEXIS;
|
|
else if (strncmp("lirc", ktype, 4) == 0)
|
|
return KBD_TYPE_LIRC;
|
|
else if (strncmp("belkinir", ktype, 8) == 0)
|
|
return KBD_TYPE_BELKINIR;
|
|
else if (strncmp("g250", ktype, 4) == 0)
|
|
return KBD_TYPE_BENQ_GAMEPAD;
|
|
else if (strncmp("pocketvik", ktype, 9) == 0)
|
|
return KBD_TYPE_POCKETVIK;
|
|
else if (strncmp("microfold", ktype, 9) == 0)
|
|
return KBD_TYPE_MICRO_FOLDAWAY;
|
|
else if (strncmp("micropad", ktype, 8) == 0)
|
|
return KBD_TYPE_MICRO_DATAPAD;
|
|
else if (strncmp("microkbd", ktype, 8) == 0)
|
|
return KBD_TYPE_COMPAQ_MICROKBD;
|
|
else if (strncmp("targusir", ktype, 8) == 0)
|
|
return KBD_TYPE_TARGUSIR;
|
|
else if (strncmp("btfoldable", ktype, 10) == 0)
|
|
return KBD_TYPE_BTFOLDABLE;
|
|
else if (strncmp("freedom", ktype, 7) == 0)
|
|
return KBD_TYPE_FREEDOM;
|
|
|
|
fprintf(stderr, "unrecognised keyboard type %s\n", ktype);
|
|
|
|
return KBD_TYPE_NONE;
|
|
}
|
|
|
|
|
|
void parse_config(const char *path, int *kbdtype, char port[])
|
|
{
|
|
char *needle;
|
|
FILE *fd;
|
|
char buf[PATH_MAX];
|
|
|
|
fd = fopen(path, "r");
|
|
if (!fd) {
|
|
fprintf(stderr, "could not open config file %s\n", path);
|
|
return;
|
|
}
|
|
|
|
while (!feof(fd)) {
|
|
fgets(buf, PATH_MAX, fd);
|
|
|
|
if (*buf == '#' || *buf == '\0') {
|
|
/* It's a comment or a blank line */
|
|
continue;
|
|
}
|
|
|
|
if ((needle = strstr(buf, "port:")) != 0) {
|
|
needle += 5;
|
|
/* Trim whitespaces */
|
|
while (isspace(*needle)) {
|
|
needle++;
|
|
}
|
|
while (isspace(needle[strlen(needle)-1])) {
|
|
needle[strlen(needle)-1] = '\0';
|
|
}
|
|
strncpy(port, needle, PATH_MAX);
|
|
} else if ((needle = strstr(buf, "type:")) != 0) {
|
|
needle += 5;
|
|
/* Trim whitespaces */
|
|
while (isspace(*needle)) {
|
|
needle++;
|
|
}
|
|
while (isspace(needle[strlen(needle)-1])) {
|
|
needle[strlen(needle)-1] = '\0';
|
|
}
|
|
*kbdtype = find_kbd_type(needle);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int optc;
|
|
int kbdtype=KBD_TYPE_NONE;
|
|
|
|
while ((optc = getopt(argc, argv, "c:t:p:dh")) != -1) {
|
|
switch ((char)optc) {
|
|
case 'h':
|
|
print_usage(argv[0]);
|
|
exit(1);
|
|
break;
|
|
case 'd':
|
|
debug = 1;
|
|
break;
|
|
case 't':
|
|
kbdtype = find_kbd_type(optarg);
|
|
break;
|
|
case 'p':
|
|
strncpy(TTY_PORT, optarg, PATH_MAX);
|
|
break;
|
|
case 'c':
|
|
parse_config(optarg, &kbdtype, TTY_PORT);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (kbdtype == 0) {
|
|
print_usage(argv[0]);
|
|
exit(1);
|
|
}
|
|
|
|
uindev = dev_uinput_init();
|
|
if (uindev <= 0) {
|
|
fprintf(stderr, "init uinput failed\n");
|
|
exit (1);
|
|
}
|
|
|
|
signal(SIGTERM, handle_sigterm);
|
|
|
|
if (kbdtype == KBD_TYPE_FOLDABLE)
|
|
compaq_foldable();
|
|
else if (kbdtype == KBD_TYPE_BTFOLDABLE)
|
|
hp_bt_foldable();
|
|
else if (kbdtype == KBD_TYPE_SNAPNTYPE)
|
|
snapntype();
|
|
else if (kbdtype == KBD_TYPE_SNAPNTYPEBT)
|
|
snapntypebt();
|
|
else if (kbdtype == KBD_TYPE_STOWAWAY)
|
|
stowaway();
|
|
else if (kbdtype == KBD_TYPE_STOWAWAYXT)
|
|
stowawayxt();
|
|
else if (kbdtype == KBD_TYPE_HPSLIM)
|
|
hpslim();
|
|
else if (kbdtype == KBD_TYPE_SMARTBT)
|
|
smartbt();
|
|
else if (kbdtype == KBD_TYPE_FLEXIS)
|
|
flexis();
|
|
else if (kbdtype == KBD_TYPE_BENQ_GAMEPAD)
|
|
benqgamepad();
|
|
else if (kbdtype == KBD_TYPE_POCKETVIK)
|
|
pocketvik();
|
|
else if (kbdtype == KBD_TYPE_MICRO_FOLDAWAY)
|
|
micro_foldaway();
|
|
else if (kbdtype == KBD_TYPE_MICRO_DATAPAD)
|
|
micro_datapad();
|
|
else if (kbdtype == KBD_TYPE_COMPAQ_MICROKBD)
|
|
compaq_microkbd();
|
|
else if (kbdtype == KBD_TYPE_LIRC)
|
|
#ifdef USELIRC
|
|
lirc(basename(argv[0]);
|
|
#else
|
|
{
|
|
fprintf(stderr, "keyboard type 'lirc' is not supported in this version\n");
|
|
exit(1);
|
|
}
|
|
#endif
|
|
else if (kbdtype == KBD_TYPE_BELKINIR)
|
|
belkin_infrared();
|
|
else if (kbdtype == KBD_TYPE_TARGUSIR)
|
|
targus_infrared();
|
|
else if (kbdtype == KBD_TYPE_FREEDOM)
|
|
freedom_keyboard();
|
|
|
|
return 0;
|
|
}
|