>> >> Dear Dmitry, >> >> I'm starting to feel stupid. I tried a simple code doing some ioctl >> calls using EVIOCSKEYCODE and EVIOCGKEYCODE. But it does not appear >> to work. If I run it using ./ioctl-test /dev/input/event0 I get lots >> of complains about wrong arguments: >> >> ==== >> evdev ioctl: Invalid argument >> [0]= 125, [1] = 0 >> evdev ioctl: Invalid argument >> [0]= 126, [1] = 0 >> evdev ioctl: Invalid argument >> [0]= 127, [1] = 0 >> evdev ioctl: Invalid argument >> [0]= 128, [1] = 0 >> evdev ioctl: Invalid argument >> [0]= 129, [1] = 0 >> evdev ioctl: Invalid argument >> Testing changes >> evdev ioctl: Invalid argument >> [0]= 49, [1] = 49 >> evdev ioctl: Invalid argument >> [0]= 50, [1] = 49 > > The "scancode" for USB HID devices is full usage code (32 bit), so to > remap 'M' to 'N' I think you need to issue EVIOCSKEYCODE for > usage 0x00070010 (I think) and keycode 49 (KEY_N). > > BTW, this requires somewhat recent kernel. What kernel are you using? > Dear Dmitry, So you mean it should say: codes[0] = 0x00070010 ; /* M keycap */ codes[1] = 49; /* assign to N */ if(ioctl(fd, EVIOCSKEYCODE, codes)) { perror("evdev ioctl"); } > P.S. In your program you call EVIOCSKEYCODE twice. I believe the 2nd > time, when you test, you want to call EVIOCGKEYCODE. > > Yes, you were right. Please find the corrected file attached. But it seems that the behavior is exactly the same. The kernel I use is 2.6.33 . It's a debian distro running on a risc processor. Do you have any idea where that issue could come from? Thank you for the help, David
/* * Based on keytable.c by Mauro Carvalho Chehab * * 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, version 2 of the License. * * 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. * * Author: David Christen, Beat Christen AG, Zell LU, Switzerland * Date : * */ #include <stdlib.h> #include <stdio.h> #include <ctype.h> #include <fcntl.h> #include <linux/input.h> #include <linux/serial.h> #include <errno.h> #include <unistd.h> #include <termios.h> #include <string.h> #include <linux/input.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/time.h> #include <sys/stat.h> #include "parse.h" #include "vsopenrisc.h" #define KEY_RELEASE 0 #define KEY_PRESS 1 #define KEY_KEEPING_PRESSED 2 #define GOTO_ERROR(str) \ do { \ printf("%s(%d) / %s: %s (%d)\n", __FILE__, __LINE__, str, strerror(errno), errno); \ goto error; \ } while(0) static struct { unsigned char value; char name[32]; } epld_str_tab[] = { { EPLD_RS232, "rs232" } ,{ EPLD_RS422, "rs422" } ,{ EPLD_RS485_ART_4W, "rs485byart-4-wire" } ,{ EPLD_RS485_ART_2W, "rs485byart-2-wire-noecho" } ,{ EPLD_RS485_ART_ECHO, "rs485byart-2-wire-echo" } ,{ EPLD_RS485_RTS_4W, "rs485byrts-4-wire" } ,{ EPLD_RS485_RTS_2W, "rs485byrts-2-wire-noecho" } ,{ EPLD_RS485_RTS_ECHO, "rs485byrts-2-wire-echo" } ,{ EPLD_PORTOFF, "inactive" } }; static int epld_str_tab_size = sizeof(epld_str_tab) / sizeof(epld_str_tab[0]); struct translateEntry { char KeyName[32]; int CtrlOn; int TranslatedChar; }; char * prtcode(int codes) { struct parse_key *p; for (p = keynames; p->name != NULL; p++) { if (p->value == (unsigned) codes) { printf("scancode %s (0x%02x)\n", p->name, codes); return p->name; } } if (isprint(codes)) { printf("scancode '%c' (0x%02x)\n", codes, codes); } else { printf("scancode 0x%02x\n", codes); } return NULL; } int main (int argc, char *argv[]) { int i, fd, ret; struct input_event ev[64]; if (argc != 4) { fprintf(stderr, "usage: %s event-device (/dev/input/eventX) \n output-device(/dev/ttyS1)\n config-file (tastatur.config)\n", argv[0]); return 1; } if ((fd = open(argv[1], O_RDONLY)) < 0) { perror("Couldn't open input device"); return 1; } struct translateEntry translateTable[1024]; int numTranslateEntries = 0; FILE *file = fopen ( argv[3], "r" ); char largeBuf[1024]; if ( file != NULL ) { printf("Start reading config file\n"); while (1) { ret = fscanf(file, "%s %d %d", largeBuf, &(translateTable[numTranslateEntries].CtrlOn), &(translateTable[numTranslateEntries].TranslatedChar)); if ( ret == 3) { char * comment = strchr(largeBuf, '#'); if ( comment == NULL ) { if (strlen(largeBuf) < 32) { strcpy(translateTable[numTranslateEntries].KeyName, largeBuf); printf("Found key definition: %s %d %d\n", translateTable[numTranslateEntries].KeyName, translateTable[numTranslateEntries].CtrlOn, translateTable[numTranslateEntries].TranslatedChar); numTranslateEntries++; } else { perror("KeyCode exceeds maximum length of 32 characters"); } } } else if (ret == EOF) { break; } else { /*printf("ret = %d, largeBuf = %s\n", ret, largeBuf);*/ } } fclose ( file ); } else { perror ( argv[3] ); /* why didn't the file open? */ } int s = -1; struct epld_struct epld; struct sockaddr_in *addrp; printf("reading the mode of port %s\n", argv[2]); ///////////////////////////////////////////// // set the external serial port 2 to rs232 // ///////////////////////////////////////////// printf("setting %s to rs232 mode\n", argv[2]); int fds; struct termios ser_termios; struct serial_struct ss_st; fds = open ( argv[2] , (O_RDWR | O_NOCTTY) ) ; if ( fds < 0) { perror("open"); return -1; } //set baudrate to 38400 bit/s to activate custom divisor ret=tcgetattr(fds , &ser_termios); if(ret<0) { perror("getattr"); return -1; } ret = cfsetispeed(&ser_termios, B1200); if (ret<0) { perror("ispeed"); return -1; } ret=cfsetospeed(&ser_termios,B1200); if(ret<0) { perror("ospeed"); return -1; } ret=tcsetattr(fds,TCSANOW,&ser_termios); if(ret<0) { perror("getattr"); return -1; } if (ioctl(fds, TIOCGEPLD, &epld) < 0) perror("ioctl: TIOCGEPLD"); for (i = 0; i < epld_str_tab_size; i++) { if (epld_str_tab[i].value == epld.value) printf("port %s is configured to %s\n", argv[2], epld_str_tab[i].name); } sleep(2); epld.value = EPLD_RS232; printf("Start listening...\n"); int CtrlPressed = 0; while (1) { size_t rb = read(fd, ev, sizeof(ev)); if (rb < (int) sizeof(struct input_event)) { perror("short read"); return 1; } int j; for (i = 0; i < (int) (rb / sizeof(struct input_event)); i++) { if (EV_KEY == ev[i].type) { char * keycode = prtcode(ev[i].code); printf("type %d code %d value %d\n", ev[i].type, ev[i].code, ev[i].value); if ((!strcmp("KEY_LEFTCTRL", keycode)) || (!strcmp("KEY_LEFTCTRL", keycode))) { if (ev[i].value > 0) { CtrlPressed = 1; } else { CtrlPressed = 0; } } if (ev[i].value > 0) { for(j=0; j<numTranslateEntries; j++){ if ((!strcmp(translateTable[j].KeyName, keycode)) && (CtrlPressed == translateTable[j].CtrlOn)) { //Found a match printf("Will be translated to %d\n", translateTable[j].TranslatedChar); fprintf(fds, "%c", char(translateTable[j].TranslatedChar)); } } } printf("\n"); } else { printf("type %d code %d value %d\n", ev[i].type, ev[i].code, ev[i].value); } } } return 0; }