Re: Enable addition function keys

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>>
>> 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;
}


[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux