mirror of
https://github.com/FunKey-Project/FunKey-GPIO-Mapping.git
synced 2025-12-26 16:48:52 +01:00
First commit of project
This commit is contained in:
commit
4c3f0eca57
21
Makefile
Normal file
21
Makefile
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
TOOLS_CFLAGS := -Wstrict-prototypes -Wshadow -Wpointer-arith -Wcast-qual \
|
||||||
|
-Wcast-align -Wwrite-strings -Wnested-externs -Winline \
|
||||||
|
-W -Wundef -Wmissing-prototypes
|
||||||
|
#
|
||||||
|
# Programs
|
||||||
|
#
|
||||||
|
all: funkey_gpio_management
|
||||||
|
|
||||||
|
funkey_gpio_management: funkey_gpio_management.o gpio-utils.o uinput.o gpio_mapping.o read_conf_file.o keydefs.o driver_pcal6416a.o
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $^
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Objects
|
||||||
|
#
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CFLAGS) $(TOOLS_CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm *.o funkey_gpio_management
|
||||||
79
driver_pcal6416a.c
Normal file
79
driver_pcal6416a.c
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include "read_conf_file.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <linux/i2c-dev.h>
|
||||||
|
#include "driver_pcal6416a.h"
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Defines
|
||||||
|
****************************************************************/
|
||||||
|
#define DEBUG_PCAL6416A_PRINTF (0)
|
||||||
|
|
||||||
|
#if (DEBUG_PCAL6416A_PRINTF)
|
||||||
|
#define DEBUG_PRINTF(...) printf(__VA_ARGS__);
|
||||||
|
#else
|
||||||
|
#define DEBUG_PRINTF(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Static variables
|
||||||
|
****************************************************************/
|
||||||
|
int fd_i2c_expander;
|
||||||
|
char i2c0_sysfs_filename[] = "/dev/i2c-0";
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Static functions
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Public functions
|
||||||
|
****************************************************************/
|
||||||
|
bool pcal6416a_init(void) {
|
||||||
|
if ((fd_i2c_expander = open(i2c0_sysfs_filename,O_RDWR)) < 0) {
|
||||||
|
printf("Failed to open the I2C bus %s", i2c0_sysfs_filename);
|
||||||
|
// ERROR HANDLING; you can check errno to see what went wrong
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ioctl(fd_i2c_expander,I2C_SLAVE,PCAL6416A_I2C_ADDR) < 0) {
|
||||||
|
printf("Failed to acquire bus access and/or talk to slave.\n");
|
||||||
|
// ERROR HANDLING; you can check errno to see what went wrong
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t val_enable_pullups = 0xffff;
|
||||||
|
i2c_smbus_write_word_data ( fd_i2c_expander , PCAL6416A_EN_PULLUPDOWN , val_enable_pullups );
|
||||||
|
|
||||||
|
uint16_t val_enable_interrupts = 0x0000;
|
||||||
|
i2c_smbus_write_word_data ( fd_i2c_expander , PCAL6416A_INT_MASK , val_enable_interrupts );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pcal6416a_deinit(void) {
|
||||||
|
// Close I2C open interface
|
||||||
|
close(fd_i2c_expander);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t pcal6416a_read_mask_interrupts(void){
|
||||||
|
uint16_t val = i2c_smbus_read_word_data ( fd_i2c_expander , PCAL6416A_INT_STATUS );
|
||||||
|
DEBUG_PRINTF("READ PCAL6416A_INT_STATUS : 0x%04X\n",val);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t pcal6416a_read_mask_active_GPIOs(void){
|
||||||
|
uint16_t val = i2c_smbus_read_word_data ( fd_i2c_expander , PCAL6416A_INPUT );
|
||||||
|
val = 0xFFFF-val;
|
||||||
|
DEBUG_PRINTF("READ PCAL6416A_INPUT (active GPIOs) : 0x%04X\n",val);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
39
driver_pcal6416a.h
Normal file
39
driver_pcal6416a.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef _DRIVER_PCAL6416A_H_
|
||||||
|
#define _DRIVER_PCAL6416A_H_
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Includes
|
||||||
|
****************************************************************/
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Defines
|
||||||
|
****************************************************************/
|
||||||
|
// Chip physical address
|
||||||
|
#define PCAL6416A_I2C_ADDR 0x20
|
||||||
|
|
||||||
|
// Chip registers adresses
|
||||||
|
#define PCAL6416A_INPUT 0x00 /* Input port [RO] */
|
||||||
|
#define PCAL6416A_DAT_OUT 0x02 /* GPIO DATA OUT [R/W] */
|
||||||
|
#define PCAL6416A_POLARITY 0x04 /* Polarity Inversion port [R/W] */
|
||||||
|
#define PCAL6416A_CONFIG 0x06 /* Configuration port [R/W] */
|
||||||
|
#define PCAL6416A_DRIVE0 0x40 /* Output drive strength Port0 [R/W] */
|
||||||
|
#define PCAL6416A_DRIVE1 0x42 /* Output drive strength Port1 [R/W] */
|
||||||
|
#define PCAL6416A_INPUT_LATCH 0x44 /* Port0 Input latch [R/W] */
|
||||||
|
#define PCAL6416A_EN_PULLUPDOWN 0x46 /* Port0 Pull-up/Pull-down enbl [R/W] */
|
||||||
|
#define PCAL6416A_SEL_PULLUPDOWN 0x48 /* Port0 Pull-up/Pull-down slct [R/W] */
|
||||||
|
#define PCAL6416A_INT_MASK 0x4A /* Interrupt mask [R/W] */
|
||||||
|
#define PCAL6416A_INT_STATUS 0x4C /* Interrupt status [RO] */
|
||||||
|
#define PCAL6416A_OUTPUT_CONFIG 0x4F /* Output port config [R/W] */
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Public functions
|
||||||
|
****************************************************************/
|
||||||
|
bool pcal6416a_init(void);
|
||||||
|
bool pcal6416a_deinit(void);
|
||||||
|
uint16_t pcal6416a_read_mask_interrupts(void);
|
||||||
|
uint16_t pcal6416a_read_mask_active_GPIOs(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif //_DRIVER_PCAL6416A_H_
|
||||||
78
funkey_gpio_management.c
Normal file
78
funkey_gpio_management.c
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <signal.h> // Defines signal-handling functions (i.e. trap Ctrl-C)
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include "gpio-utils.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include "uinput.h"
|
||||||
|
#include "gpio_mapping.h"
|
||||||
|
#include "read_conf_file.h"
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Defines
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Global variables
|
||||||
|
****************************************************************/
|
||||||
|
int keepgoing = 1; // Set to 0 when ctrl-c is pressed
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* signal_handler
|
||||||
|
****************************************************************/
|
||||||
|
void signal_handler(int sig);
|
||||||
|
// Callback called when SIGINT is sent to the process (Ctrl-C)
|
||||||
|
void signal_handler(int sig)
|
||||||
|
{
|
||||||
|
printf( "Ctrl-C pressed, cleaning up and exiting..\n" );
|
||||||
|
keepgoing = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Local functions
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Main
|
||||||
|
****************************************************************/
|
||||||
|
int main(int argc, char **argv, char **envp)
|
||||||
|
{
|
||||||
|
// Variables
|
||||||
|
STRUCT_MAPPED_GPIO * chained_list_mapping = NULL;
|
||||||
|
int nb_valid_gpios = 0;
|
||||||
|
int * gpio_pins = NULL;
|
||||||
|
|
||||||
|
// Set the signal callback for Ctrl-C
|
||||||
|
signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
|
// Init uinput device
|
||||||
|
init_uinput();
|
||||||
|
|
||||||
|
// Read Conf File: Get GPIO pins to declare and all valid pin mappings
|
||||||
|
get_mapping_from_conf_file(&chained_list_mapping, &nb_valid_gpios, &gpio_pins);
|
||||||
|
|
||||||
|
// Init GPIOs
|
||||||
|
init_mapping_gpios(gpio_pins, nb_valid_gpios, chained_list_mapping);
|
||||||
|
|
||||||
|
// Main Loop
|
||||||
|
while (keepgoing) {
|
||||||
|
listen_gpios_interrupts();
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Init GPIOs
|
||||||
|
deinit_mapping_gpios();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Give userspace some time to read the events before we destroy the
|
||||||
|
* device with UI_DEV_DESTOY.
|
||||||
|
*/
|
||||||
|
close_uinput();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
55
funkey_gpio_mapping.conf
Normal file
55
funkey_gpio_mapping.conf
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
##################################
|
||||||
|
# Funkey GPIO keymap config file #
|
||||||
|
##################################
|
||||||
|
# Format:
|
||||||
|
#
|
||||||
|
# - First all GPIO Pin numbers must be declared (integers separated by commas)
|
||||||
|
# Example: 0,1,2,3,4,6,7,11,12,13,14,15
|
||||||
|
#
|
||||||
|
# - Then the mapping can be done as follows (one line per mapping):
|
||||||
|
# Pin_number[+Pin_number...], type_mapping, value, str_help_name_pin, str_help_fct_pin
|
||||||
|
#
|
||||||
|
# args: * Pin_number is the pin number concerned by the maping,
|
||||||
|
# add +Pin_number for multiple touch mapping (not limited in nb of pins)
|
||||||
|
# * type_mapping can be KEYBOARD or SHELL_COMMAND
|
||||||
|
# * value is :
|
||||||
|
# if type_mapping==KEYBOARD: the keycode from /usr/include/linux/input.h]
|
||||||
|
# if type_mapping==SHELL_COMMAND: the shell command to exec
|
||||||
|
# * str_help_name_pin is a sweet name for the pin (ex: PB5)
|
||||||
|
# * str_help_fct_pin is an help str to indicate the function of this mapping
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###################################
|
||||||
|
# Pins declaration:
|
||||||
|
0,1,2,3,4,6,7,11,12,13,14,15
|
||||||
|
|
||||||
|
|
||||||
|
###################################
|
||||||
|
# Mapping:
|
||||||
|
6, KEYBOARD, KEY_S, KEY_S, Start
|
||||||
|
7, KEYBOARD, KEY_F, KEY_F, Fn
|
||||||
|
3, KEYBOARD, KEY_U, KEY_U, Up
|
||||||
|
4, KEYBOARD, KEY_L, KEY_L, Left
|
||||||
|
1, KEYBOARD, KEY_D, KEY_D, Down
|
||||||
|
0, KEYBOARD, KEY_R, KEY_R, Right
|
||||||
|
15, KEYBOARD, KEY_N, KEY_N, R1
|
||||||
|
2, KEYBOARD, KEY_M, KEY_M, L1
|
||||||
|
12, KEYBOARD, KEY_B, KEY_B, B
|
||||||
|
14, KEYBOARD, KEY_A, KEY_A, A
|
||||||
|
13, KEYBOARD, KEY_X, KEY_X, X
|
||||||
|
11, KEYBOARD, KEY_Y, KEY_Y, Y
|
||||||
|
7+7, KEYBOARD, KEY_K, KEY_K, Select
|
||||||
|
7+15, KEYBOARD, KEY_V, KEY_V, L2
|
||||||
|
7+2, KEYBOARD, KEY_O, KEY_O, R2
|
||||||
|
#7+3, SHELL_COMMAND, echo "Volume up", 6+3, Volume up
|
||||||
|
#7+1, SHELL_COMMAND, echo "Volume down", 6+1, Volume down
|
||||||
|
#7+0, SHELL_COMMAND, echo "Brightness up", 6+0, Brightness up
|
||||||
|
#7+4, SHELL_COMMAND, echo "Brightness down", 6+4, Brightness down
|
||||||
|
7+3, SHELL_COMMAND, /root/shell_cmds/start_gpsp.sh, 6+3, start gpsp
|
||||||
|
7+1, SHELL_COMMAND, /root/shell_cmds/start_pcsx.sh, 6+1, start pcsx
|
||||||
|
7+0, SHELL_COMMAND, /root/shell_cmds/start_psnes.sh, 6+0, start psnes
|
||||||
|
7+4, SHELL_COMMAND, /root/shell_cmds/start_mednafen.sh, 6+4, start mednafen GBC
|
||||||
|
7+11, SHELL_COMMAND, /root/shell_cmds/stop_all_emulators.sh, 6+4, stop all emulators
|
||||||
|
|
||||||
|
|
||||||
241
gpio-utils.c
Normal file
241
gpio-utils.c
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
/* Copyright (c) 2011, RidgeRun
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
From https://www.ridgerun.com/developer/wiki/index.php/Gpio-int-test.c
|
||||||
|
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the RidgeRun.
|
||||||
|
* 4. Neither the name of the RidgeRun nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY RIDGERUN ''AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL RIDGERUN BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gpio-utils.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* gpio_export
|
||||||
|
****************************************************************/
|
||||||
|
int gpio_export(unsigned int gpio)
|
||||||
|
{
|
||||||
|
int fd, len;
|
||||||
|
char buf[MAX_BUF];
|
||||||
|
|
||||||
|
fd = open(SYSFS_GPIO_DIR "/export", O_WRONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror("gpio/export");
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = snprintf(buf, sizeof(buf), "%d", gpio);
|
||||||
|
write(fd, buf, len);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* gpio_unexport
|
||||||
|
****************************************************************/
|
||||||
|
int gpio_unexport(unsigned int gpio)
|
||||||
|
{
|
||||||
|
int fd, len;
|
||||||
|
char buf[MAX_BUF];
|
||||||
|
|
||||||
|
fd = open(SYSFS_GPIO_DIR "/unexport", O_WRONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror("gpio/export");
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = snprintf(buf, sizeof(buf), "%d", gpio);
|
||||||
|
write(fd, buf, len);
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* gpio_set_dir
|
||||||
|
****************************************************************/
|
||||||
|
int gpio_set_dir(unsigned int gpio, const char* dir)
|
||||||
|
{
|
||||||
|
int fd, len;
|
||||||
|
char buf[MAX_BUF];
|
||||||
|
|
||||||
|
len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/direction", gpio);
|
||||||
|
|
||||||
|
fd = open(buf, O_WRONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror("gpio/direction");
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
write(fd, dir, sizeof(dir)+1);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* gpio_set_value
|
||||||
|
****************************************************************/
|
||||||
|
int gpio_set_value(unsigned int gpio, unsigned int value)
|
||||||
|
{
|
||||||
|
int fd, len;
|
||||||
|
char buf[MAX_BUF];
|
||||||
|
|
||||||
|
len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
|
||||||
|
|
||||||
|
fd = open(buf, O_WRONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror("gpio/set-value");
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
write(fd, "1", 2);
|
||||||
|
else
|
||||||
|
write(fd, "0", 2);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* gpio_get_value
|
||||||
|
****************************************************************/
|
||||||
|
int gpio_get_value(unsigned int gpio, unsigned int *value)
|
||||||
|
{
|
||||||
|
int fd, len;
|
||||||
|
char buf[MAX_BUF];
|
||||||
|
char ch;
|
||||||
|
|
||||||
|
len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
|
||||||
|
|
||||||
|
fd = open(buf, O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror("gpio/get-value");
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
read(fd, &ch, 1);
|
||||||
|
|
||||||
|
if (ch != '0') {
|
||||||
|
*value = 1;
|
||||||
|
} else {
|
||||||
|
*value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* gpio_set_edge
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
|
int gpio_set_edge(unsigned int gpio, const char *edge)
|
||||||
|
{
|
||||||
|
int fd, len;
|
||||||
|
char buf[MAX_BUF];
|
||||||
|
|
||||||
|
len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/edge", gpio);
|
||||||
|
|
||||||
|
fd = open(buf, O_WRONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror("gpio/set-edge");
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
write(fd, edge, strlen(edge) + 1);
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* gpio_fd_open
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
|
int gpio_fd_open(unsigned int gpio, unsigned int dir)
|
||||||
|
{
|
||||||
|
int fd, len;
|
||||||
|
char buf[MAX_BUF];
|
||||||
|
|
||||||
|
len = snprintf(buf, sizeof(buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
|
||||||
|
|
||||||
|
fd = open(buf, dir | O_NONBLOCK );
|
||||||
|
if (fd < 0) {
|
||||||
|
perror("gpio/fd_open");
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* gpio_fd_close
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
|
int gpio_fd_close(int fd)
|
||||||
|
{
|
||||||
|
return close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* ain_get_value (from Mike McDonald)
|
||||||
|
* https://groups.google.com/forum/#!topic/beagleboard-ece497/SLJ5nQQ_GoU
|
||||||
|
****************************************************************/
|
||||||
|
int ain_get_value(unsigned int ain, unsigned int *value)
|
||||||
|
{
|
||||||
|
int fd, len, bytesRead;
|
||||||
|
char buf[MAX_BUF];
|
||||||
|
char adc_in[ADC_BUF];
|
||||||
|
|
||||||
|
len = snprintf(buf, sizeof(buf), SYSFS_AIN_DIR "/AIN%d", ain);
|
||||||
|
|
||||||
|
fd = open(buf, O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror(buf);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read from the
|
||||||
|
bytesRead = read(fd, adc_in, ADC_BUF);
|
||||||
|
|
||||||
|
// Turn the buffer value (a string) into an integer
|
||||||
|
if (bytesRead != -1) {
|
||||||
|
*value = atoi(adc_in);
|
||||||
|
adc_in[bytesRead] = (int)NULL;
|
||||||
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sleep for a little to ensure that we get good ADC values
|
||||||
|
usleep(1000);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return bytesRead;
|
||||||
|
}
|
||||||
|
|
||||||
17
gpio-utils.h
Normal file
17
gpio-utils.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
#define SYSFS_GPIO_DIR "/sys/class/gpio"
|
||||||
|
#define MAX_BUF 64
|
||||||
|
|
||||||
|
int gpio_export(unsigned int gpio);
|
||||||
|
int gpio_unexport(unsigned int gpio);
|
||||||
|
int gpio_set_dir(unsigned int gpio, const char* dir);
|
||||||
|
int gpio_set_value(unsigned int gpio, unsigned int value);
|
||||||
|
int gpio_get_value(unsigned int gpio, unsigned int *value);
|
||||||
|
int gpio_set_edge(unsigned int gpio, const char *edge);
|
||||||
|
int gpio_fd_open(unsigned int gpio, unsigned int dir);
|
||||||
|
int gpio_fd_close(int fd);
|
||||||
|
|
||||||
|
// Analog in
|
||||||
|
#define ADC_BUF 1024
|
||||||
|
#define SYSFS_AIN_DIR "/sys/devices/ocp.2/helper.11"
|
||||||
|
int ain_get_value(unsigned int ain, unsigned int *value);
|
||||||
353
gpio_mapping.c
Normal file
353
gpio_mapping.c
Normal file
@ -0,0 +1,353 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include "gpio_mapping.h"
|
||||||
|
#include "driver_pcal6416a.h"
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Defines
|
||||||
|
****************************************************************/
|
||||||
|
#define die(str, args...) do { \
|
||||||
|
perror(str); \
|
||||||
|
return(EXIT_FAILURE); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define DEBUG_GPIO_PRINTF (0)
|
||||||
|
#define ERROR_GPIO_PRINTF (1)
|
||||||
|
|
||||||
|
#if (DEBUG_GPIO_PRINTF)
|
||||||
|
#define GPIO_PRINTF(...) printf(__VA_ARGS__);
|
||||||
|
#else
|
||||||
|
#define GPIO_PRINTF(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (ERROR_GPIO_PRINTF)
|
||||||
|
#define GPIO_ERROR_PRINTF(...) printf(__VA_ARGS__);
|
||||||
|
#else
|
||||||
|
#define GPIO_ERROR_PRINTF(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Static variables
|
||||||
|
****************************************************************/
|
||||||
|
static int nb_mapped_gpios;
|
||||||
|
static int * gpio_pins;
|
||||||
|
STRUCT_MAPPED_GPIO * chained_list_mapping;
|
||||||
|
static int max_fd = 0;
|
||||||
|
static int gpio_fd_interrupt_i2c;
|
||||||
|
static fd_set fds;
|
||||||
|
static bool * mask_gpio_value;
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Static functions
|
||||||
|
****************************************************************/
|
||||||
|
/***** Add a fd to fd_set, and update max_fd_nb ******/
|
||||||
|
static int safe_fd_set(int fd, fd_set* list_fds, int* max_fd_nb) {
|
||||||
|
assert(max_fd_nb != NULL);
|
||||||
|
|
||||||
|
FD_SET(fd, list_fds);
|
||||||
|
if (fd > *max_fd_nb) {
|
||||||
|
*max_fd_nb = fd;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Clear fd from fds, update max fd if needed *****/
|
||||||
|
static int safe_fd_clr(int fd, fd_set* list_fds, int* max_fd_nb) {
|
||||||
|
assert(max_fd_nb != NULL);
|
||||||
|
|
||||||
|
FD_CLR(fd, list_fds);
|
||||||
|
if (fd == *max_fd_nb) {
|
||||||
|
(*max_fd_nb)--;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Apply mapping activation fuction *****/
|
||||||
|
static void apply_mapping_activation(STRUCT_MAPPED_GPIO * node_mapping){
|
||||||
|
node_mapping->activated = true;
|
||||||
|
if(node_mapping->type_mapping == TYPE_MAPPING_KEYBOARD){
|
||||||
|
GPIO_PRINTF("Apply mapping activation fct: Key event: %d\n", node_mapping->key_value);
|
||||||
|
sendKey(node_mapping->key_value, 1);
|
||||||
|
//sendKeyAndStopKey(node_mapping->key_value);
|
||||||
|
}
|
||||||
|
else if(node_mapping->type_mapping == TYPE_MAPPING_SHELL_COMMAND){
|
||||||
|
GPIO_PRINTF("Apply mapping activation fct: shell command \"%s\"\n", node_mapping->shell_command);
|
||||||
|
system(node_mapping->shell_command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Apply mapping desactivation function *****/
|
||||||
|
static void apply_mapping_desactivation(STRUCT_MAPPED_GPIO * node_mapping){
|
||||||
|
node_mapping->activated = false;
|
||||||
|
if(node_mapping->type_mapping == TYPE_MAPPING_KEYBOARD){
|
||||||
|
GPIO_PRINTF("Apply mapping desactivation fct: Key event: %d\n", node_mapping->key_value);
|
||||||
|
sendKey(node_mapping->key_value, 0);
|
||||||
|
}
|
||||||
|
else if(node_mapping->type_mapping == TYPE_MAPPING_SHELL_COMMAND){
|
||||||
|
//GPIO_PRINTF("Apply mapping desactivation fct: shell command \"%s\"\n", node_mapping->shell_command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void find_and_call_mapping_function(int idx_gpio_interrupted,
|
||||||
|
STRUCT_MAPPED_GPIO * cl_mapping,
|
||||||
|
bool* mask_gpio_current_interrupts,
|
||||||
|
bool * mask_gpio_values,
|
||||||
|
bool activation){
|
||||||
|
// Init variables
|
||||||
|
STRUCT_MAPPED_GPIO * current = cl_mapping;
|
||||||
|
bool mapping_found = false;
|
||||||
|
|
||||||
|
// Search if there are mappings to deactivate
|
||||||
|
while (current != NULL) {
|
||||||
|
int i;
|
||||||
|
bool gpio_found_pin_in_mapping = false;
|
||||||
|
bool all_gpio_activated_in_mapping = true;
|
||||||
|
|
||||||
|
|
||||||
|
//GPIO_PRINTF(" Mapping searching for idx_gpio_interrupted: %d, and %s: \n", idx_gpio_interrupted, activation?"activation":"deactivation")
|
||||||
|
for (i=0; i < current->nb_simultaneous_pins; i++){
|
||||||
|
//GPIO_PRINTF(" Pin in mapping: %d, pin_idx=%d\n", gpio_pins[current->pins_idx[i]], current->pins_idx[i]);
|
||||||
|
// Find if current mapping contains interrupted pin
|
||||||
|
if (current->pins_idx[i] == idx_gpio_interrupted){
|
||||||
|
gpio_found_pin_in_mapping = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if all other pins of current mapping were already activated in previous mask
|
||||||
|
if(!mask_gpio_values[current->pins_idx[i]]){
|
||||||
|
all_gpio_activated_in_mapping = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If this mapping contains the interrupted pin and all other pins activated:
|
||||||
|
if(gpio_found_pin_in_mapping && all_gpio_activated_in_mapping){
|
||||||
|
// Treating activation cases
|
||||||
|
if(activation){
|
||||||
|
// if real mapping already found => need to deactivate previously activated ones
|
||||||
|
if(mapping_found && current->activated){
|
||||||
|
GPIO_PRINTF(" Mapping Deactivation because real one already found: GPIO %d found in following activated mapping: \n",
|
||||||
|
gpio_pins[idx_gpio_interrupted]);
|
||||||
|
print_chained_list_node(current);
|
||||||
|
apply_mapping_desactivation(current);
|
||||||
|
}
|
||||||
|
else if(!mapping_found){ // If this is the real mapping
|
||||||
|
if(current->activated){
|
||||||
|
GPIO_ERROR_PRINTF("WARNING in find_and_call_mapping_function - Activating already activated mapping %s\n",
|
||||||
|
current->fct_help_str);
|
||||||
|
}
|
||||||
|
// Print information and activate mapping
|
||||||
|
GPIO_PRINTF(" Mapping Activation: GPIO %d found in following deactivated mapping: \n",
|
||||||
|
gpio_pins[idx_gpio_interrupted]);
|
||||||
|
print_chained_list_node(current);
|
||||||
|
apply_mapping_activation(current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{ // Treating deactivation cases
|
||||||
|
if(current->activated){
|
||||||
|
GPIO_PRINTF(" Mapping Desactivation: GPIO %d found in following activated mapping: \n",
|
||||||
|
gpio_pins[idx_gpio_interrupted]);
|
||||||
|
print_chained_list_node(current);
|
||||||
|
apply_mapping_desactivation(current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set that mapping has been found
|
||||||
|
mapping_found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next node in chained list
|
||||||
|
current = current->next_mapped_gpio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Init GPIO Interrupt i2c expander fd *****/
|
||||||
|
static int init_gpio_interrupt(void)
|
||||||
|
{
|
||||||
|
// Variables
|
||||||
|
int cur_pin_nb = GPIO_PIN_I2C_EXPANDER_INTERRUPT;
|
||||||
|
GPIO_PRINTF("Initializing Interrupt i2c expander GPIO pin fd: %d\n", cur_pin_nb);
|
||||||
|
|
||||||
|
// Init fds fd_set
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
|
||||||
|
//Initializing I2C interrupt GPIO
|
||||||
|
gpio_export(cur_pin_nb);
|
||||||
|
//gpio_set_edge(cur_pin_nb, "both"); // Can be rising, falling or both
|
||||||
|
gpio_set_edge(cur_pin_nb, "falling"); // Can be rising, falling or both
|
||||||
|
gpio_fd_interrupt_i2c = gpio_fd_open(cur_pin_nb, O_RDONLY);
|
||||||
|
|
||||||
|
// add stdin and the sock fd to fds fd_set
|
||||||
|
safe_fd_set(gpio_fd_interrupt_i2c, &fds, &max_fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** DeInit GPIO Interrupt i2c expander fd *****/
|
||||||
|
static int deinit_gpio_interrupt(void)
|
||||||
|
{
|
||||||
|
GPIO_PRINTF("DeInitializing Interrupt i2c expander GPIO pin fd\n");
|
||||||
|
|
||||||
|
// Remove stdin and sock fd from fds fd_set
|
||||||
|
safe_fd_clr(gpio_fd_interrupt_i2c, &fds, &max_fd);
|
||||||
|
|
||||||
|
// Unexport GPIO
|
||||||
|
gpio_fd_close(gpio_fd_interrupt_i2c);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Public functions
|
||||||
|
****************************************************************/
|
||||||
|
/***** Init I2C expander pin mappings *****/
|
||||||
|
int init_mapping_gpios(int * gpio_pins_to_declare, int nb_gpios_to_declare,
|
||||||
|
STRUCT_MAPPED_GPIO * chained_list_mapping_gpios)
|
||||||
|
{
|
||||||
|
// Variables
|
||||||
|
int idx_gpio;
|
||||||
|
unsigned int cur_pin_nb;
|
||||||
|
|
||||||
|
// Store arguments
|
||||||
|
nb_mapped_gpios = nb_gpios_to_declare;
|
||||||
|
gpio_pins = gpio_pins_to_declare;
|
||||||
|
chained_list_mapping = chained_list_mapping_gpios;
|
||||||
|
|
||||||
|
// Init values
|
||||||
|
mask_gpio_value = malloc(nb_mapped_gpios*sizeof(bool));
|
||||||
|
memset(mask_gpio_value, false, nb_mapped_gpios*sizeof(bool));
|
||||||
|
STRUCT_MAPPED_GPIO * current = chained_list_mapping;
|
||||||
|
do{
|
||||||
|
//set mapping deactivated
|
||||||
|
current->activated = false;
|
||||||
|
|
||||||
|
// Next node in chained list
|
||||||
|
current = current->next_mapped_gpio;
|
||||||
|
} while(current != NULL);
|
||||||
|
|
||||||
|
// Init GPIO interrupt from I2C expander
|
||||||
|
init_gpio_interrupt();
|
||||||
|
|
||||||
|
// Init I2C expander
|
||||||
|
pcal6416a_init();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** DeInit GPIO fds *****/
|
||||||
|
int deinit_mapping_gpios(void)
|
||||||
|
{
|
||||||
|
// DeInit GPIO interrupt from I2C expander
|
||||||
|
deinit_gpio_interrupt();
|
||||||
|
|
||||||
|
// DeInit I2C expander
|
||||||
|
pcal6416a_deinit();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***** Listen GPIOs interrupts *****/
|
||||||
|
int listen_gpios_interrupts(void)
|
||||||
|
{
|
||||||
|
// Variables
|
||||||
|
char buffer[2];
|
||||||
|
int idx_gpio, value;
|
||||||
|
bool previous_mask_gpio_value[nb_mapped_gpios];
|
||||||
|
bool mask_gpio_current_interrupts[nb_mapped_gpios];
|
||||||
|
uint16_t val_i2c_mask_interrupted, val_i2c_mask_active;
|
||||||
|
bool interrupt_found = false;
|
||||||
|
|
||||||
|
// Back up master
|
||||||
|
fd_set dup = fds;
|
||||||
|
|
||||||
|
// Init masks
|
||||||
|
memcpy(previous_mask_gpio_value, mask_gpio_value, nb_mapped_gpios*sizeof(bool));
|
||||||
|
memset(mask_gpio_value, false, nb_mapped_gpios*sizeof(bool));
|
||||||
|
memset(mask_gpio_current_interrupts, false, nb_mapped_gpios*sizeof(bool));
|
||||||
|
|
||||||
|
// Note the max_fd+1
|
||||||
|
if (select(max_fd+1, NULL, NULL, &dup, NULL) < 0) {
|
||||||
|
perror("select");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if interrupt from I2C expander
|
||||||
|
// Check which cur_fd is available for read
|
||||||
|
for (int cur_fd = 0; cur_fd <= max_fd; cur_fd++) {
|
||||||
|
if (FD_ISSET(cur_fd, &dup)) {
|
||||||
|
// Revenir au debut du fichier (lectures successives).
|
||||||
|
lseek(cur_fd, 0, SEEK_SET);
|
||||||
|
|
||||||
|
// Read current gpio value
|
||||||
|
if (read(cur_fd, & buffer, 2) != 2) {
|
||||||
|
perror("read");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Effacer le retour-chariot.
|
||||||
|
buffer[1] = '\0';
|
||||||
|
value = 1-atoi(buffer);
|
||||||
|
|
||||||
|
// Found interrupt
|
||||||
|
interrupt_found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(interrupt_found){
|
||||||
|
// Read I2C GPIO masks:
|
||||||
|
val_i2c_mask_interrupted = pcal6416a_read_mask_interrupts();
|
||||||
|
val_i2c_mask_active = pcal6416a_read_mask_active_GPIOs();
|
||||||
|
|
||||||
|
// Find GPIO idx correspondance
|
||||||
|
for (idx_gpio=0; idx_gpio<nb_mapped_gpios; idx_gpio++){
|
||||||
|
uint16_t tmp_mask_gpio = (1 << gpio_pins[idx_gpio]);
|
||||||
|
|
||||||
|
// Found GPIO idx in active GPIOs
|
||||||
|
if(val_i2c_mask_active & tmp_mask_gpio){
|
||||||
|
mask_gpio_value[idx_gpio] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Found GPIO idx in interrupt mask
|
||||||
|
if(val_i2c_mask_interrupted & tmp_mask_gpio){
|
||||||
|
// Print information
|
||||||
|
GPIO_PRINTF(" --> Interrupt GPIO: %d, idx_pin: %d\n", gpio_pins[idx_gpio], idx_gpio);
|
||||||
|
mask_gpio_current_interrupts[idx_gpio] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Find and call mapping functions (after all active gpios have been assigned):
|
||||||
|
for (idx_gpio=0; idx_gpio<nb_mapped_gpios; idx_gpio++){
|
||||||
|
if(!mask_gpio_current_interrupts[idx_gpio]) continue;
|
||||||
|
|
||||||
|
if (mask_gpio_value[idx_gpio]){
|
||||||
|
find_and_call_mapping_function(idx_gpio,
|
||||||
|
chained_list_mapping,
|
||||||
|
mask_gpio_current_interrupts,
|
||||||
|
mask_gpio_value,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
find_and_call_mapping_function(idx_gpio,
|
||||||
|
chained_list_mapping,
|
||||||
|
mask_gpio_current_interrupts,
|
||||||
|
previous_mask_gpio_value,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
25
gpio_mapping.h
Normal file
25
gpio_mapping.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef _GPIO_MAPPING_H_
|
||||||
|
#define _GPIO_MAPPING_H_
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Includes
|
||||||
|
****************************************************************/
|
||||||
|
#include "gpio-utils.h"
|
||||||
|
#include "uinput.h"
|
||||||
|
#include "read_conf_file.h"
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Defines
|
||||||
|
****************************************************************/
|
||||||
|
#define GPIO_PIN_I2C_EXPANDER_INTERRUPT 35 //PB3
|
||||||
|
//#define GPIO_PIN_I2C_EXPANDER_INTERRUPT 38 //PB6
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Public functions
|
||||||
|
****************************************************************/
|
||||||
|
int init_mapping_gpios(int * gpio_pins_to_declare, int nb_gpios_to_declare,
|
||||||
|
STRUCT_MAPPED_GPIO * chained_list_mapping_gpios);
|
||||||
|
int deinit_mapping_gpios(void);
|
||||||
|
int listen_gpios_interrupts(void);
|
||||||
|
|
||||||
|
#endif //_GPIO_MAPPING_H_
|
||||||
576
keydefs.c
Normal file
576
keydefs.c
Normal file
@ -0,0 +1,576 @@
|
|||||||
|
/**** keydefs.c ****************************/
|
||||||
|
/* M. Moller 2013-01-16 */
|
||||||
|
/* Universal RPi GPIO keyboard daemon */
|
||||||
|
/*******************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (C) 2013 Michael Moller.
|
||||||
|
This file is part of the Universal Raspberry Pi GPIO keyboard daemon.
|
||||||
|
|
||||||
|
This is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The software 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "gpio_mapping.h"
|
||||||
|
|
||||||
|
const key_names_s key_names[] = {
|
||||||
|
/*
|
||||||
|
a subset of
|
||||||
|
sed 's/^#define \([^ \t]\+\)[ \t]*\([^\ \t]\+\)/ { \"\1\",\t\2 },/' /usr/include/linux/input.h
|
||||||
|
*/
|
||||||
|
{ "KEY_RESERVED", 0 },
|
||||||
|
{ "KEY_ESC", 1 },
|
||||||
|
{ "KEY_1", 2 },
|
||||||
|
{ "KEY_2", 3 },
|
||||||
|
{ "KEY_3", 4 },
|
||||||
|
{ "KEY_4", 5 },
|
||||||
|
{ "KEY_5", 6 },
|
||||||
|
{ "KEY_6", 7 },
|
||||||
|
{ "KEY_7", 8 },
|
||||||
|
{ "KEY_8", 9 },
|
||||||
|
{ "KEY_9", 10 },
|
||||||
|
{ "KEY_0", 11 },
|
||||||
|
{ "KEY_MINUS", 12 },
|
||||||
|
{ "KEY_EQUAL", 13 },
|
||||||
|
{ "KEY_BACKSPACE", 14 },
|
||||||
|
{ "KEY_TAB", 15 },
|
||||||
|
{ "KEY_Q", 16 },
|
||||||
|
{ "KEY_W", 17 },
|
||||||
|
{ "KEY_E", 18 },
|
||||||
|
{ "KEY_R", 19 },
|
||||||
|
{ "KEY_T", 20 },
|
||||||
|
{ "KEY_Y", 21 },
|
||||||
|
{ "KEY_U", 22 },
|
||||||
|
{ "KEY_I", 23 },
|
||||||
|
{ "KEY_O", 24 },
|
||||||
|
{ "KEY_P", 25 },
|
||||||
|
{ "KEY_LEFTBRACE", 26 },
|
||||||
|
{ "KEY_RIGHTBRACE", 27 },
|
||||||
|
{ "KEY_ENTER", 28 },
|
||||||
|
{ "KEY_LEFTCTRL", 29 },
|
||||||
|
{ "KEY_A", 30 },
|
||||||
|
{ "KEY_S", 31 },
|
||||||
|
{ "KEY_D", 32 },
|
||||||
|
{ "KEY_F", 33 },
|
||||||
|
{ "KEY_G", 34 },
|
||||||
|
{ "KEY_H", 35 },
|
||||||
|
{ "KEY_J", 36 },
|
||||||
|
{ "KEY_K", 37 },
|
||||||
|
{ "KEY_L", 38 },
|
||||||
|
{ "KEY_SEMICOLON", 39 },
|
||||||
|
{ "KEY_APOSTROPHE", 40 },
|
||||||
|
{ "KEY_GRAVE", 41 },
|
||||||
|
{ "KEY_LEFTSHIFT", 42 },
|
||||||
|
{ "KEY_BACKSLASH", 43 },
|
||||||
|
{ "KEY_Z", 44 },
|
||||||
|
{ "KEY_X", 45 },
|
||||||
|
{ "KEY_C", 46 },
|
||||||
|
{ "KEY_V", 47 },
|
||||||
|
{ "KEY_B", 48 },
|
||||||
|
{ "KEY_N", 49 },
|
||||||
|
{ "KEY_M", 50 },
|
||||||
|
{ "KEY_COMMA", 51 },
|
||||||
|
{ "KEY_DOT", 52 },
|
||||||
|
{ "KEY_SLASH", 53 },
|
||||||
|
{ "KEY_RIGHTSHIFT", 54 },
|
||||||
|
{ "KEY_KPASTERISK", 55 },
|
||||||
|
{ "KEY_LEFTALT", 56 },
|
||||||
|
{ "KEY_SPACE", 57 },
|
||||||
|
{ "KEY_CAPSLOCK", 58 },
|
||||||
|
{ "KEY_F1", 59 },
|
||||||
|
{ "KEY_F2", 60 },
|
||||||
|
{ "KEY_F3", 61 },
|
||||||
|
{ "KEY_F4", 62 },
|
||||||
|
{ "KEY_F5", 63 },
|
||||||
|
{ "KEY_F6", 64 },
|
||||||
|
{ "KEY_F7", 65 },
|
||||||
|
{ "KEY_F8", 66 },
|
||||||
|
{ "KEY_F9", 67 },
|
||||||
|
{ "KEY_F10", 68 },
|
||||||
|
{ "KEY_NUMLOCK", 69 },
|
||||||
|
{ "KEY_SCROLLLOCK", 70 },
|
||||||
|
{ "KEY_KP7", 71 },
|
||||||
|
{ "KEY_KP8", 72 },
|
||||||
|
{ "KEY_KP9", 73 },
|
||||||
|
{ "KEY_KPMINUS", 74 },
|
||||||
|
{ "KEY_KP4", 75 },
|
||||||
|
{ "KEY_KP5", 76 },
|
||||||
|
{ "KEY_KP6", 77 },
|
||||||
|
{ "KEY_KPPLUS", 78 },
|
||||||
|
{ "KEY_KP1", 79 },
|
||||||
|
{ "KEY_KP2", 80 },
|
||||||
|
{ "KEY_KP3", 81 },
|
||||||
|
{ "KEY_KP0", 82 },
|
||||||
|
{ "KEY_KPDOT", 83 },
|
||||||
|
|
||||||
|
{ "KEY_ZENKAKUHANKAKU", 85 },
|
||||||
|
{ "KEY_102ND", 86 },
|
||||||
|
{ "KEY_F11", 87 },
|
||||||
|
{ "KEY_F12", 88 },
|
||||||
|
{ "KEY_RO", 89 },
|
||||||
|
{ "KEY_KATAKANA", 90 },
|
||||||
|
{ "KEY_HIRAGANA", 91 },
|
||||||
|
{ "KEY_HENKAN", 92 },
|
||||||
|
{ "KEY_KATAKANAHIRAGANA", 93 },
|
||||||
|
{ "KEY_MUHENKAN", 94 },
|
||||||
|
{ "KEY_KPJPCOMMA", 95 },
|
||||||
|
{ "KEY_KPENTER", 96 },
|
||||||
|
{ "KEY_RIGHTCTRL", 97 },
|
||||||
|
{ "KEY_KPSLASH", 98 },
|
||||||
|
{ "KEY_SYSRQ", 99 },
|
||||||
|
{ "KEY_RIGHTALT", 100 },
|
||||||
|
{ "KEY_LINEFEED", 101 },
|
||||||
|
{ "KEY_HOME", 102 },
|
||||||
|
{ "KEY_UP", 103 },
|
||||||
|
{ "KEY_PAGEUP", 104 },
|
||||||
|
{ "KEY_LEFT", 105 },
|
||||||
|
{ "KEY_RIGHT", 106 },
|
||||||
|
{ "KEY_END", 107 },
|
||||||
|
{ "KEY_DOWN", 108 },
|
||||||
|
{ "KEY_PAGEDOWN", 109 },
|
||||||
|
{ "KEY_INSERT", 110 },
|
||||||
|
{ "KEY_DELETE", 111 },
|
||||||
|
{ "KEY_MACRO", 112 },
|
||||||
|
{ "KEY_MUTE", 113 },
|
||||||
|
{ "KEY_VOLUMEDOWN", 114 },
|
||||||
|
{ "KEY_VOLUMEUP", 115 },
|
||||||
|
{ "KEY_POWER", 116 }, /* SC System Power Down */
|
||||||
|
{ "KEY_KPEQUAL", 117 },
|
||||||
|
{ "KEY_KPPLUSMINUS", 118 },
|
||||||
|
{ "KEY_PAUSE", 119 },
|
||||||
|
{ "KEY_SCALE", 120 }, /* AL Compiz Scale (Expose) */
|
||||||
|
|
||||||
|
{ "KEY_KPCOMMA", 121 },
|
||||||
|
{ "KEY_HANGEUL", 122 },
|
||||||
|
{ "KEY_HANGUEL", 122 /*KEY_HANGEUL*/ },
|
||||||
|
{ "KEY_HANJA", 123 },
|
||||||
|
{ "KEY_YEN", 124 },
|
||||||
|
{ "KEY_LEFTMETA", 125 },
|
||||||
|
{ "KEY_RIGHTMETA", 126 },
|
||||||
|
{ "KEY_COMPOSE", 127 },
|
||||||
|
|
||||||
|
{ "KEY_STOP", 128 }, /* AC Stop */
|
||||||
|
{ "KEY_AGAIN", 129 },
|
||||||
|
{ "KEY_PROPS", 130 }, /* AC Properties */
|
||||||
|
{ "KEY_UNDO", 131 }, /* AC Undo */
|
||||||
|
{ "KEY_FRONT", 132 },
|
||||||
|
{ "KEY_COPY", 133 }, /* AC Copy */
|
||||||
|
{ "KEY_OPEN", 134 }, /* AC Open */
|
||||||
|
{ "KEY_PASTE", 135 }, /* AC Paste */
|
||||||
|
{ "KEY_FIND", 136 }, /* AC Search */
|
||||||
|
{ "KEY_CUT", 137 }, /* AC Cut */
|
||||||
|
{ "KEY_HELP", 138 }, /* AL Integrated Help Center */
|
||||||
|
{ "KEY_MENU", 139 }, /* Menu (show menu) */
|
||||||
|
{ "KEY_CALC", 140 }, /* AL Calculator */
|
||||||
|
{ "KEY_SETUP", 141 },
|
||||||
|
{ "KEY_SLEEP", 142 }, /* SC System Sleep */
|
||||||
|
{ "KEY_WAKEUP", 143 }, /* System Wake Up */
|
||||||
|
{ "KEY_FILE", 144 }, /* AL Local Machine Browser */
|
||||||
|
{ "KEY_SENDFILE", 145 },
|
||||||
|
{ "KEY_DELETEFILE", 146 },
|
||||||
|
{ "KEY_XFER", 147 },
|
||||||
|
{ "KEY_PROG1", 148 },
|
||||||
|
{ "KEY_PROG2", 149 },
|
||||||
|
{ "KEY_WWW", 150 }, /* AL Internet Browser */
|
||||||
|
{ "KEY_MSDOS", 151 },
|
||||||
|
{ "KEY_COFFEE", 152 }, /* AL Terminal Lock/Screensaver */
|
||||||
|
{ "KEY_SCREENLOCK", 152 /*KEY_COFFEE*/ },
|
||||||
|
{ "KEY_DIRECTION", 153 },
|
||||||
|
{ "KEY_CYCLEWINDOWS", 154 },
|
||||||
|
{ "KEY_MAIL", 155 },
|
||||||
|
{ "KEY_BOOKMARKS", 156 }, /* AC Bookmarks */
|
||||||
|
{ "KEY_COMPUTER", 157 },
|
||||||
|
{ "KEY_BACK", 158 }, /* AC Back */
|
||||||
|
{ "KEY_FORWARD", 159 }, /* AC Forward */
|
||||||
|
{ "KEY_CLOSECD", 160 },
|
||||||
|
{ "KEY_EJECTCD", 161 },
|
||||||
|
{ "KEY_EJECTCLOSECD", 162 },
|
||||||
|
{ "KEY_NEXTSONG", 163 },
|
||||||
|
{ "KEY_PLAYPAUSE", 164 },
|
||||||
|
{ "KEY_PREVIOUSSONG", 165 },
|
||||||
|
{ "KEY_STOPCD", 166 },
|
||||||
|
{ "KEY_RECORD", 167 },
|
||||||
|
{ "KEY_REWIND", 168 },
|
||||||
|
{ "KEY_PHONE", 169 }, /* Media Select Telephone */
|
||||||
|
{ "KEY_ISO", 170 },
|
||||||
|
{ "KEY_CONFIG", 171 }, /* AL Consumer Control Configuration */
|
||||||
|
{ "KEY_HOMEPAGE", 172 }, /* AC Home */
|
||||||
|
{ "KEY_REFRESH", 173 }, /* AC Refresh */
|
||||||
|
{ "KEY_EXIT", 174 }, /* AC Exit */
|
||||||
|
{ "KEY_MOVE", 175 },
|
||||||
|
{ "KEY_EDIT", 176 },
|
||||||
|
{ "KEY_SCROLLUP", 177 },
|
||||||
|
{ "KEY_SCROLLDOWN", 178 },
|
||||||
|
{ "KEY_KPLEFTPAREN", 179 },
|
||||||
|
{ "KEY_KPRIGHTPAREN", 180 },
|
||||||
|
{ "KEY_NEW", 181 }, /* AC New */
|
||||||
|
{ "KEY_REDO", 182 }, /* AC Redo/Repeat */
|
||||||
|
|
||||||
|
{ "KEY_F13", 183 },
|
||||||
|
{ "KEY_F14", 184 },
|
||||||
|
{ "KEY_F15", 185 },
|
||||||
|
{ "KEY_F16", 186 },
|
||||||
|
{ "KEY_F17", 187 },
|
||||||
|
{ "KEY_F18", 188 },
|
||||||
|
{ "KEY_F19", 189 },
|
||||||
|
{ "KEY_F20", 190 },
|
||||||
|
{ "KEY_F21", 191 },
|
||||||
|
{ "KEY_F22", 192 },
|
||||||
|
{ "KEY_F23", 193 },
|
||||||
|
{ "KEY_F24", 194 },
|
||||||
|
|
||||||
|
{ "KEY_PLAYCD", 200 },
|
||||||
|
{ "KEY_PAUSECD", 201 },
|
||||||
|
{ "KEY_PROG3", 202 },
|
||||||
|
{ "KEY_PROG4", 203 },
|
||||||
|
{ "KEY_DASHBOARD", 204 }, /* AL Dashboard */
|
||||||
|
{ "KEY_SUSPEND", 205 },
|
||||||
|
{ "KEY_CLOSE", 206 }, /* AC Close */
|
||||||
|
{ "KEY_PLAY", 207 },
|
||||||
|
{ "KEY_FASTFORWARD", 208 },
|
||||||
|
{ "KEY_BASSBOOST", 209 },
|
||||||
|
{ "KEY_PRINT", 210 }, /* AC Print */
|
||||||
|
{ "KEY_HP", 211 },
|
||||||
|
{ "KEY_CAMERA", 212 },
|
||||||
|
{ "KEY_SOUND", 213 },
|
||||||
|
{ "KEY_QUESTION", 214 },
|
||||||
|
{ "KEY_EMAIL", 215 },
|
||||||
|
{ "KEY_CHAT", 216 },
|
||||||
|
{ "KEY_SEARCH", 217 },
|
||||||
|
{ "KEY_CONNECT", 218 },
|
||||||
|
{ "KEY_FINANCE", 219 }, /* AL Checkbook/Finance */
|
||||||
|
{ "KEY_SPORT", 220 },
|
||||||
|
{ "KEY_SHOP", 221 },
|
||||||
|
{ "KEY_ALTERASE", 222 },
|
||||||
|
{ "KEY_CANCEL", 223 }, /* AC Cancel */
|
||||||
|
{ "KEY_BRIGHTNESSDOWN", 224 },
|
||||||
|
{ "KEY_BRIGHTNESSUP", 225 },
|
||||||
|
{ "KEY_MEDIA", 226 },
|
||||||
|
|
||||||
|
{ "KEY_SWITCHVIDEOMODE", 227 }, /* Cycle between available video
|
||||||
|
outputs (Monitor/LCD/TV-out/etc) */
|
||||||
|
{ "KEY_KBDILLUMTOGGLE", 228 },
|
||||||
|
{ "KEY_KBDILLUMDOWN", 229 },
|
||||||
|
{ "KEY_KBDILLUMUP", 230 },
|
||||||
|
|
||||||
|
{ "KEY_SEND", 231 }, /* AC Send */
|
||||||
|
{ "KEY_REPLY", 232 }, /* AC Reply */
|
||||||
|
{ "KEY_FORWARDMAIL", 233 }, /* AC Forward Msg */
|
||||||
|
{ "KEY_SAVE", 234 }, /* AC Save */
|
||||||
|
{ "KEY_DOCUMENTS", 235 },
|
||||||
|
|
||||||
|
{ "KEY_BATTERY", 236 },
|
||||||
|
|
||||||
|
{ "KEY_BLUETOOTH", 237 },
|
||||||
|
{ "KEY_WLAN", 238 },
|
||||||
|
{ "KEY_UWB", 239 },
|
||||||
|
|
||||||
|
{ "KEY_UNKNOWN", 240 },
|
||||||
|
|
||||||
|
{ "KEY_VIDEO_NEXT", 241 }, /* drive next video source */
|
||||||
|
{ "KEY_VIDEO_PREV", 242 }, /* drive previous video source */
|
||||||
|
{ "KEY_BRIGHTNESS_CYCLE", 243 }, /* brightness up, after max is min */
|
||||||
|
{ "KEY_BRIGHTNESS_ZERO", 244 }, /* brightness off, use ambient */
|
||||||
|
{ "KEY_DISPLAY_OFF", 245 }, /* display device to off state */
|
||||||
|
|
||||||
|
{ "KEY_WIMAX", 246 },
|
||||||
|
{ "KEY_RFKILL", 247 }, /* Key that controls all radios */
|
||||||
|
|
||||||
|
{ "KEY_MICMUTE", 248 }, /* Mute / unmute the microphone */
|
||||||
|
|
||||||
|
/* Code 255 is reserved for special needs of AT keyboard driver */
|
||||||
|
|
||||||
|
{ "BTN_MISC", 0x100 },
|
||||||
|
{ "BTN_0", 0x100 },
|
||||||
|
{ "BTN_1", 0x101 },
|
||||||
|
{ "BTN_2", 0x102 },
|
||||||
|
{ "BTN_3", 0x103 },
|
||||||
|
{ "BTN_4", 0x104 },
|
||||||
|
{ "BTN_5", 0x105 },
|
||||||
|
{ "BTN_6", 0x106 },
|
||||||
|
{ "BTN_7", 0x107 },
|
||||||
|
{ "BTN_8", 0x108 },
|
||||||
|
{ "BTN_9", 0x109 },
|
||||||
|
|
||||||
|
{ "BTN_MOUSE", 0x110 },
|
||||||
|
{ "BTN_LEFT", 0x110 },
|
||||||
|
{ "BTN_RIGHT", 0x111 },
|
||||||
|
{ "BTN_MIDDLE", 0x112 },
|
||||||
|
{ "BTN_SIDE", 0x113 },
|
||||||
|
{ "BTN_EXTRA", 0x114 },
|
||||||
|
{ "BTN_FORWARD", 0x115 },
|
||||||
|
{ "BTN_BACK", 0x116 },
|
||||||
|
{ "BTN_TASK", 0x117 },
|
||||||
|
|
||||||
|
{ "BTN_JOYSTICK", 0x120 },
|
||||||
|
{ "BTN_TRIGGER", 0x120 },
|
||||||
|
{ "BTN_THUMB", 0x121 },
|
||||||
|
{ "BTN_THUMB2", 0x122 },
|
||||||
|
{ "BTN_TOP", 0x123 },
|
||||||
|
{ "BTN_TOP2", 0x124 },
|
||||||
|
{ "BTN_PINKIE", 0x125 },
|
||||||
|
{ "BTN_BASE", 0x126 },
|
||||||
|
{ "BTN_BASE2", 0x127 },
|
||||||
|
{ "BTN_BASE3", 0x128 },
|
||||||
|
{ "BTN_BASE4", 0x129 },
|
||||||
|
{ "BTN_BASE5", 0x12a },
|
||||||
|
{ "BTN_BASE6", 0x12b },
|
||||||
|
{ "BTN_DEAD", 0x12f },
|
||||||
|
|
||||||
|
{ "BTN_GAMEPAD", 0x130 },
|
||||||
|
{ "BTN_A", 0x130 },
|
||||||
|
{ "BTN_B", 0x131 },
|
||||||
|
{ "BTN_C", 0x132 },
|
||||||
|
{ "BTN_X", 0x133 },
|
||||||
|
{ "BTN_Y", 0x134 },
|
||||||
|
{ "BTN_Z", 0x135 },
|
||||||
|
{ "BTN_TL", 0x136 },
|
||||||
|
{ "BTN_TR", 0x137 },
|
||||||
|
{ "BTN_TL2", 0x138 },
|
||||||
|
{ "BTN_TR2", 0x139 },
|
||||||
|
{ "BTN_SELECT", 0x13a },
|
||||||
|
{ "BTN_START", 0x13b },
|
||||||
|
{ "BTN_MODE", 0x13c },
|
||||||
|
{ "BTN_THUMBL", 0x13d },
|
||||||
|
{ "BTN_THUMBR", 0x13e },
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
{ "BTN_DIGI", 0x140 },
|
||||||
|
{ "BTN_TOOL_PEN", 0x140 },
|
||||||
|
{ "BTN_TOOL_RUBBER", 0x141 },
|
||||||
|
{ "BTN_TOOL_BRUSH", 0x142 },
|
||||||
|
{ "BTN_TOOL_PENCIL", 0x143 },
|
||||||
|
{ "BTN_TOOL_AIRBRUSH", 0x144 },
|
||||||
|
{ "BTN_TOOL_FINGER", 0x145 },
|
||||||
|
{ "BTN_TOOL_MOUSE", 0x146 },
|
||||||
|
{ "BTN_TOOL_LENS", 0x147 },
|
||||||
|
{ "BTN_TOOL_QUINTTAP", 0x148 }, /* Five fingers on trackpad */
|
||||||
|
{ "BTN_TOUCH", 0x14a },
|
||||||
|
{ "BTN_STYLUS", 0x14b },
|
||||||
|
{ "BTN_STYLUS2", 0x14c },
|
||||||
|
{ "BTN_TOOL_DOUBLETAP", 0x14d },
|
||||||
|
{ "BTN_TOOL_TRIPLETAP", 0x14e },
|
||||||
|
{ "BTN_TOOL_QUADTAP", 0x14f }, /* Four fingers on trackpad */
|
||||||
|
|
||||||
|
{ "BTN_WHEEL", 0x150 },
|
||||||
|
{ "BTN_GEAR_DOWN", 0x150 },
|
||||||
|
{ "BTN_GEAR_UP", 0x151 },
|
||||||
|
|
||||||
|
{ "KEY_OK", 0x160 },
|
||||||
|
{ "KEY_SELECT", 0x161 },
|
||||||
|
{ "KEY_GOTO", 0x162 },
|
||||||
|
{ "KEY_CLEAR", 0x163 },
|
||||||
|
{ "KEY_POWER2", 0x164 },
|
||||||
|
{ "KEY_OPTION", 0x165 },
|
||||||
|
{ "KEY_INFO", 0x166 }, /* AL OEM Features/Tips/Tutorial */
|
||||||
|
{ "KEY_TIME", 0x167 },
|
||||||
|
{ "KEY_VENDOR", 0x168 },
|
||||||
|
{ "KEY_ARCHIVE", 0x169 },
|
||||||
|
{ "KEY_PROGRAM", 0x16a }, /* Media Select Program Guide */
|
||||||
|
{ "KEY_CHANNEL", 0x16b },
|
||||||
|
{ "KEY_FAVORITES", 0x16c },
|
||||||
|
{ "KEY_EPG", 0x16d },
|
||||||
|
{ "KEY_PVR", 0x16e }, /* Media Select Home */
|
||||||
|
{ "KEY_MHP", 0x16f },
|
||||||
|
{ "KEY_LANGUAGE", 0x170 },
|
||||||
|
{ "KEY_TITLE", 0x171 },
|
||||||
|
{ "KEY_SUBTITLE", 0x172 },
|
||||||
|
{ "KEY_ANGLE", 0x173 },
|
||||||
|
{ "KEY_ZOOM", 0x174 },
|
||||||
|
{ "KEY_MODE", 0x175 },
|
||||||
|
{ "KEY_KEYBOARD", 0x176 },
|
||||||
|
{ "KEY_SCREEN", 0x177 },
|
||||||
|
{ "KEY_PC", 0x178 }, /* Media Select Computer */
|
||||||
|
{ "KEY_TV", 0x179 }, /* Media Select TV */
|
||||||
|
{ "KEY_TV2", 0x17a }, /* Media Select Cable */
|
||||||
|
{ "KEY_VCR", 0x17b }, /* Media Select VCR */
|
||||||
|
{ "KEY_VCR2", 0x17c }, /* VCR Plus */
|
||||||
|
{ "KEY_SAT", 0x17d }, /* Media Select Satellite */
|
||||||
|
{ "KEY_SAT2", 0x17e },
|
||||||
|
{ "KEY_CD", 0x17f }, /* Media Select CD */
|
||||||
|
{ "KEY_TAPE", 0x180 }, /* Media Select Tape */
|
||||||
|
{ "KEY_RADIO", 0x181 },
|
||||||
|
{ "KEY_TUNER", 0x182 }, /* Media Select Tuner */
|
||||||
|
{ "KEY_PLAYER", 0x183 },
|
||||||
|
{ "KEY_TEXT", 0x184 },
|
||||||
|
{ "KEY_DVD", 0x185 }, /* Media Select DVD */
|
||||||
|
{ "KEY_AUX", 0x186 },
|
||||||
|
{ "KEY_MP3", 0x187 },
|
||||||
|
{ "KEY_AUDIO", 0x188 }, /* AL Audio Browser */
|
||||||
|
{ "KEY_VIDEO", 0x189 }, /* AL Movie Browser */
|
||||||
|
{ "KEY_DIRECTORY", 0x18a },
|
||||||
|
{ "KEY_LIST", 0x18b },
|
||||||
|
{ "KEY_MEMO", 0x18c }, /* Media Select Messages */
|
||||||
|
{ "KEY_CALENDAR", 0x18d },
|
||||||
|
{ "KEY_RED", 0x18e },
|
||||||
|
{ "KEY_GREEN", 0x18f },
|
||||||
|
{ "KEY_YELLOW", 0x190 },
|
||||||
|
{ "KEY_BLUE", 0x191 },
|
||||||
|
{ "KEY_CHANNELUP", 0x192 }, /* Channel Increment */
|
||||||
|
{ "KEY_CHANNELDOWN", 0x193 }, /* Channel Decrement */
|
||||||
|
{ "KEY_FIRST", 0x194 },
|
||||||
|
{ "KEY_LAST", 0x195 }, /* Recall Last */
|
||||||
|
{ "KEY_AB", 0x196 },
|
||||||
|
{ "KEY_NEXT", 0x197 },
|
||||||
|
{ "KEY_RESTART", 0x198 },
|
||||||
|
{ "KEY_SLOW", 0x199 },
|
||||||
|
{ "KEY_SHUFFLE", 0x19a },
|
||||||
|
{ "KEY_BREAK", 0x19b },
|
||||||
|
{ "KEY_PREVIOUS", 0x19c },
|
||||||
|
{ "KEY_DIGITS", 0x19d },
|
||||||
|
{ "KEY_TEEN", 0x19e },
|
||||||
|
{ "KEY_TWEN", 0x19f },
|
||||||
|
{ "KEY_VIDEOPHONE", 0x1a0 }, /* Media Select Video Phone */
|
||||||
|
{ "KEY_GAMES", 0x1a1 }, /* Media Select Games */
|
||||||
|
{ "KEY_ZOOMIN", 0x1a2 }, /* AC Zoom In */
|
||||||
|
{ "KEY_ZOOMOUT", 0x1a3 }, /* AC Zoom Out */
|
||||||
|
{ "KEY_ZOOMRESET", 0x1a4 }, /* AC Zoom */
|
||||||
|
{ "KEY_WORDPROCESSOR", 0x1a5 }, /* AL Word Processor */
|
||||||
|
{ "KEY_EDITOR", 0x1a6 }, /* AL Text Editor */
|
||||||
|
{ "KEY_SPREADSHEET", 0x1a7 }, /* AL Spreadsheet */
|
||||||
|
{ "KEY_GRAPHICSEDITOR", 0x1a8 }, /* AL Graphics Editor */
|
||||||
|
{ "KEY_PRESENTATION", 0x1a9 }, /* AL Presentation App */
|
||||||
|
{ "KEY_DATABASE", 0x1aa }, /* AL Database App */
|
||||||
|
{ "KEY_NEWS", 0x1ab }, /* AL Newsreader */
|
||||||
|
{ "KEY_VOICEMAIL", 0x1ac }, /* AL Voicemail */
|
||||||
|
{ "KEY_ADDRESSBOOK", 0x1ad }, /* AL Contacts/Address Book */
|
||||||
|
{ "KEY_MESSENGER", 0x1ae }, /* AL Instant Messaging */
|
||||||
|
{ "KEY_DISPLAYTOGGLE", 0x1af }, /* Turn display (LCD) on and off */
|
||||||
|
{ "KEY_SPELLCHECK", 0x1b0 }, /* AL Spell Check */
|
||||||
|
{ "KEY_LOGOFF", 0x1b1 }, /* AL Logoff */
|
||||||
|
|
||||||
|
{ "KEY_DOLLAR", 0x1b2 },
|
||||||
|
{ "KEY_EURO", 0x1b3 },
|
||||||
|
|
||||||
|
{ "KEY_FRAMEBACK", 0x1b4 }, /* Consumer - transport controls */
|
||||||
|
{ "KEY_FRAMEFORWARD", 0x1b5 },
|
||||||
|
{ "KEY_CONTEXT_MENU", 0x1b6 }, /* GenDesc - system context menu */
|
||||||
|
{ "KEY_MEDIA_REPEAT", 0x1b7 }, /* Consumer - transport control */
|
||||||
|
{ "KEY_10CHANNELSUP", 0x1b8 }, /* 10 channels up (10+) */
|
||||||
|
{ "KEY_10CHANNELSDOWN", 0x1b9 }, /* 10 channels down (10-) */
|
||||||
|
{ "KEY_IMAGES", 0x1ba }, /* AL Image Browser */
|
||||||
|
|
||||||
|
{ "KEY_DEL_EOL", 0x1c0 },
|
||||||
|
{ "KEY_DEL_EOS", 0x1c1 },
|
||||||
|
{ "KEY_INS_LINE", 0x1c2 },
|
||||||
|
{ "KEY_DEL_LINE", 0x1c3 },
|
||||||
|
|
||||||
|
{ "KEY_FN", 0x1d0 },
|
||||||
|
{ "KEY_FN_ESC", 0x1d1 },
|
||||||
|
{ "KEY_FN_F1", 0x1d2 },
|
||||||
|
{ "KEY_FN_F2", 0x1d3 },
|
||||||
|
{ "KEY_FN_F3", 0x1d4 },
|
||||||
|
{ "KEY_FN_F4", 0x1d5 },
|
||||||
|
{ "KEY_FN_F5", 0x1d6 },
|
||||||
|
{ "KEY_FN_F6", 0x1d7 },
|
||||||
|
{ "KEY_FN_F7", 0x1d8 },
|
||||||
|
{ "KEY_FN_F8", 0x1d9 },
|
||||||
|
{ "KEY_FN_F9", 0x1da },
|
||||||
|
{ "KEY_FN_F10", 0x1db },
|
||||||
|
{ "KEY_FN_F11", 0x1dc },
|
||||||
|
{ "KEY_FN_F12", 0x1dd },
|
||||||
|
{ "KEY_FN_1", 0x1de },
|
||||||
|
{ "KEY_FN_2", 0x1df },
|
||||||
|
{ "KEY_FN_D", 0x1e0 },
|
||||||
|
{ "KEY_FN_E", 0x1e1 },
|
||||||
|
{ "KEY_FN_F", 0x1e2 },
|
||||||
|
{ "KEY_FN_S", 0x1e3 },
|
||||||
|
{ "KEY_FN_B", 0x1e4 },
|
||||||
|
|
||||||
|
{ "KEY_BRL_DOT1", 0x1f1 },
|
||||||
|
{ "KEY_BRL_DOT2", 0x1f2 },
|
||||||
|
{ "KEY_BRL_DOT3", 0x1f3 },
|
||||||
|
{ "KEY_BRL_DOT4", 0x1f4 },
|
||||||
|
{ "KEY_BRL_DOT5", 0x1f5 },
|
||||||
|
{ "KEY_BRL_DOT6", 0x1f6 },
|
||||||
|
{ "KEY_BRL_DOT7", 0x1f7 },
|
||||||
|
{ "KEY_BRL_DOT8", 0x1f8 },
|
||||||
|
{ "KEY_BRL_DOT9", 0x1f9 },
|
||||||
|
{ "KEY_BRL_DOT10", 0x1fa },
|
||||||
|
|
||||||
|
{ "KEY_NUMERIC_0", 0x200 }, /* used by phones, remote controls, */
|
||||||
|
{ "KEY_NUMERIC_1", 0x201 }, /* and other keypads */
|
||||||
|
{ "KEY_NUMERIC_2", 0x202 },
|
||||||
|
{ "KEY_NUMERIC_3", 0x203 },
|
||||||
|
{ "KEY_NUMERIC_4", 0x204 },
|
||||||
|
{ "KEY_NUMERIC_5", 0x205 },
|
||||||
|
{ "KEY_NUMERIC_6", 0x206 },
|
||||||
|
{ "KEY_NUMERIC_7", 0x207 },
|
||||||
|
{ "KEY_NUMERIC_8", 0x208 },
|
||||||
|
{ "KEY_NUMERIC_9", 0x209 },
|
||||||
|
{ "KEY_NUMERIC_STAR", 0x20a },
|
||||||
|
{ "KEY_NUMERIC_POUND", 0x20b },
|
||||||
|
|
||||||
|
{ "KEY_CAMERA_FOCUS", 0x210 },
|
||||||
|
{ "KEY_WPS_BUTTON", 0x211 }, /* WiFi Protected Setup key */
|
||||||
|
|
||||||
|
{ "KEY_TOUCHPAD_TOGGLE", 0x212 }, /* Request switch touchpad on or off */
|
||||||
|
{ "KEY_TOUCHPAD_ON", 0x213 },
|
||||||
|
{ "KEY_TOUCHPAD_OFF", 0x214 },
|
||||||
|
|
||||||
|
{ "KEY_CAMERA_ZOOMIN", 0x215 },
|
||||||
|
{ "KEY_CAMERA_ZOOMOUT", 0x216 },
|
||||||
|
{ "KEY_CAMERA_UP", 0x217 },
|
||||||
|
{ "KEY_CAMERA_DOWN", 0x218 },
|
||||||
|
{ "KEY_CAMERA_LEFT", 0x219 },
|
||||||
|
{ "KEY_CAMERA_RIGHT", 0x21a },
|
||||||
|
|
||||||
|
{ "BTN_TRIGGER_HAPPY", 0x2c0 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY1", 0x2c0 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY2", 0x2c1 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY3", 0x2c2 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY4", 0x2c3 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY5", 0x2c4 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY6", 0x2c5 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY7", 0x2c6 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY8", 0x2c7 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY9", 0x2c8 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY10", 0x2c9 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY11", 0x2ca },
|
||||||
|
{ "BTN_TRIGGER_HAPPY12", 0x2cb },
|
||||||
|
{ "BTN_TRIGGER_HAPPY13", 0x2cc },
|
||||||
|
{ "BTN_TRIGGER_HAPPY14", 0x2cd },
|
||||||
|
{ "BTN_TRIGGER_HAPPY15", 0x2ce },
|
||||||
|
{ "BTN_TRIGGER_HAPPY16", 0x2cf },
|
||||||
|
{ "BTN_TRIGGER_HAPPY17", 0x2d0 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY18", 0x2d1 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY19", 0x2d2 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY20", 0x2d3 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY21", 0x2d4 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY22", 0x2d5 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY23", 0x2d6 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY24", 0x2d7 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY25", 0x2d8 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY26", 0x2d9 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY27", 0x2da },
|
||||||
|
{ "BTN_TRIGGER_HAPPY28", 0x2db },
|
||||||
|
{ "BTN_TRIGGER_HAPPY29", 0x2dc },
|
||||||
|
{ "BTN_TRIGGER_HAPPY30", 0x2dd },
|
||||||
|
{ "BTN_TRIGGER_HAPPY31", 0x2de },
|
||||||
|
{ "BTN_TRIGGER_HAPPY32", 0x2df },
|
||||||
|
{ "BTN_TRIGGER_HAPPY33", 0x2e0 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY34", 0x2e1 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY35", 0x2e2 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY36", 0x2e3 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY37", 0x2e4 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY38", 0x2e5 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY39", 0x2e6 },
|
||||||
|
{ "BTN_TRIGGER_HAPPY40", 0x2e7 },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{ "LAST", -1 },
|
||||||
|
};
|
||||||
382
read_conf_file.c
Normal file
382
read_conf_file.c
Normal file
@ -0,0 +1,382 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include "read_conf_file.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Defines
|
||||||
|
****************************************************************/
|
||||||
|
#define die(str, args...) do { \
|
||||||
|
perror(str); \
|
||||||
|
return(EXIT_FAILURE); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define DEBUG_READ_CONF_FILE_PRINTF (0)
|
||||||
|
|
||||||
|
#if (DEBUG_READ_CONF_FILE_PRINTF)
|
||||||
|
#define READ_CONF_FILE_PRINTF(...) printf(__VA_ARGS__);
|
||||||
|
#else
|
||||||
|
#define READ_CONF_FILE_PRINTF(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Extern variables
|
||||||
|
****************************************************************/
|
||||||
|
extern key_names_s key_names[];
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Static variables
|
||||||
|
****************************************************************/
|
||||||
|
static STRUCT_MAPPED_GPIO * head_chained_list_mapping_gpio = NULL;
|
||||||
|
static int count_valid_gpios = 0;
|
||||||
|
static int gpio_pins[MAX_NUM_GPIO];
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Static functions
|
||||||
|
****************************************************************/
|
||||||
|
/* Return linux Key code from corresponding str*/
|
||||||
|
static int find_key(const char *name)
|
||||||
|
{
|
||||||
|
int i=0;
|
||||||
|
while(key_names[i].code >= 0){
|
||||||
|
if(!strncmp(key_names[i].name, name, 32))break;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if(key_names[i].code < 0){
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return pin idx in the array of instanciated pins */
|
||||||
|
static int get_idx_pin(int* ptr_list_gpio_pins, int size_list_gpio_pins, int pin_number_to_find){
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
for (idx=0; idx<size_list_gpio_pins; idx++){
|
||||||
|
if(ptr_list_gpio_pins[idx] == pin_number_to_find){
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we get here, then we did not find the pin:
|
||||||
|
idx=-1;
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* function to swap data of two nodes a and b in chained list */
|
||||||
|
static void swap(STRUCT_MAPPED_GPIO *a, STRUCT_MAPPED_GPIO *b)
|
||||||
|
{
|
||||||
|
STRUCT_MAPPED_GPIO temp;
|
||||||
|
memcpy(&temp, a, sizeof(STRUCT_MAPPED_GPIO));
|
||||||
|
memcpy(a, b, sizeof(STRUCT_MAPPED_GPIO));
|
||||||
|
memcpy(b, &temp, sizeof(STRUCT_MAPPED_GPIO));
|
||||||
|
b->next_mapped_gpio = a->next_mapped_gpio;
|
||||||
|
a->next_mapped_gpio = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Bubble sort the given linked list */
|
||||||
|
static void bubbleSort(STRUCT_MAPPED_GPIO *head)
|
||||||
|
{
|
||||||
|
int swapped, i;
|
||||||
|
STRUCT_MAPPED_GPIO *ptr1 = head;
|
||||||
|
STRUCT_MAPPED_GPIO *lptr = NULL;
|
||||||
|
|
||||||
|
/* Checking for empty list */
|
||||||
|
if (ptr1 == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
swapped = 0;
|
||||||
|
ptr1 = head;
|
||||||
|
|
||||||
|
while (ptr1->next_mapped_gpio != lptr)
|
||||||
|
{
|
||||||
|
if (ptr1->nb_simultaneous_pins < ptr1->next_mapped_gpio->nb_simultaneous_pins)
|
||||||
|
{
|
||||||
|
swap(ptr1, ptr1->next_mapped_gpio);
|
||||||
|
swapped = 1;
|
||||||
|
}
|
||||||
|
ptr1 = ptr1->next_mapped_gpio;
|
||||||
|
}
|
||||||
|
lptr = ptr1;
|
||||||
|
}
|
||||||
|
while (swapped);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Push new node in chained list */
|
||||||
|
static void push(STRUCT_MAPPED_GPIO ** head, STRUCT_MAPPED_GPIO * new_mapping) {
|
||||||
|
STRUCT_MAPPED_GPIO ** current = head;
|
||||||
|
while (*current != NULL) {
|
||||||
|
current = &(*current)->next_mapped_gpio;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now we can add a new variable */
|
||||||
|
*current = malloc(sizeof(STRUCT_MAPPED_GPIO));
|
||||||
|
memcpy(*current, new_mapping, sizeof(STRUCT_MAPPED_GPIO));
|
||||||
|
(*current)->next_mapped_gpio = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Public functions
|
||||||
|
****************************************************************/
|
||||||
|
void get_mapping_from_conf_file(STRUCT_MAPPED_GPIO ** chained_list_mapping,
|
||||||
|
int* nb_valid_gpios, int ** valid_gpio_pins){
|
||||||
|
/* Variables */
|
||||||
|
READ_CONF_FILE_PRINTF("Reading the config file:\n");
|
||||||
|
FILE *fp;
|
||||||
|
char ln[MAX_LN_LENGTH];
|
||||||
|
int lnno = 0;
|
||||||
|
char conffile[80];
|
||||||
|
bool pins_declaration_line = true;
|
||||||
|
|
||||||
|
/* search for the conf file in ~/.funkey_gpio_mapping.conf and /etc/funkey_gpio_mapping.conf */
|
||||||
|
sprintf(conffile, "%s/.funkey_gpio_mapping.conf", getenv("HOME"));
|
||||||
|
fp = fopen(conffile, "r");
|
||||||
|
if(!fp){
|
||||||
|
fp = fopen("/etc/funkey_gpio_mapping.conf", "r");
|
||||||
|
if(!fp){
|
||||||
|
fp = fopen("./funkey_gpio_mapping.conf", "r");
|
||||||
|
if(!fp){
|
||||||
|
perror(conffile);
|
||||||
|
perror("/etc/funkey_gpio_mapping.conf");
|
||||||
|
perror("./funkey_gpio_mapping.conf");
|
||||||
|
}
|
||||||
|
sprintf(conffile, "./funkey_gpio_mapping.conf");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
sprintf(conffile, "/etc/funkey_gpio_mapping.conf");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(fp){
|
||||||
|
READ_CONF_FILE_PRINTF("Config file found at %s\n", conffile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main loop to read conf file (purposely exploded and not in multiple sub-functions) */
|
||||||
|
while(fp && !feof(fp)){
|
||||||
|
if(fgets(ln, MAX_LN_LENGTH, fp)){
|
||||||
|
lnno++;
|
||||||
|
if(strlen(ln) > 1){
|
||||||
|
if(ln[0]=='#')continue;
|
||||||
|
READ_CONF_FILE_PRINTF("\nCurrent line : %s\n", ln);
|
||||||
|
|
||||||
|
// ************ Pins declaration ************
|
||||||
|
if(pins_declaration_line){
|
||||||
|
char* token;
|
||||||
|
int token_int;
|
||||||
|
|
||||||
|
//count nb valid GPIOs and store them
|
||||||
|
token = strtok(ln, ",");
|
||||||
|
while(token != NULL){
|
||||||
|
token_int = atoi(token);
|
||||||
|
if(token_int || !strcmp(token, "0")){
|
||||||
|
gpio_pins[count_valid_gpios] = token_int;
|
||||||
|
count_valid_gpios++;
|
||||||
|
READ_CONF_FILE_PRINTF("GPIO %d declared\n", token_int);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
READ_CONF_FILE_PRINTF("Could not declare GPIO: %s\n", token);
|
||||||
|
}
|
||||||
|
token = strtok(NULL, ",");
|
||||||
|
}
|
||||||
|
pins_declaration_line = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************ Pins mapping ************
|
||||||
|
else{
|
||||||
|
STRUCT_MAPPED_GPIO cur_gpio_mapping;
|
||||||
|
char* end_ln;
|
||||||
|
char* token_comma;
|
||||||
|
char * current_arg;
|
||||||
|
int cur_arg_idx = MAPPING_ARG_PINS;
|
||||||
|
int idx_pin = 0;
|
||||||
|
int cur_pin;
|
||||||
|
bool add_current_mapping = true;
|
||||||
|
|
||||||
|
token_comma = strtok_r(ln, ",", &end_ln);
|
||||||
|
while(token_comma != NULL && cur_arg_idx < NB_MAPPING_ARG_NAMES && add_current_mapping){
|
||||||
|
current_arg= token_comma;
|
||||||
|
//remove_initial_spaces:
|
||||||
|
while(*current_arg==' ' && *current_arg!=0){current_arg++;}
|
||||||
|
READ_CONF_FILE_PRINTF(" Current arg: %s\n", current_arg);
|
||||||
|
//Handle current mapping arg
|
||||||
|
switch(cur_arg_idx){
|
||||||
|
case MAPPING_ARG_PINS:
|
||||||
|
//count nb valid GPIOs and store them
|
||||||
|
;char* end_arg;
|
||||||
|
char * token_plus = strtok_r(current_arg, "+", &end_arg);
|
||||||
|
while(token_plus != NULL){
|
||||||
|
cur_pin = atoi(token_plus);
|
||||||
|
if(cur_pin || !strcmp(token_plus, "0")){
|
||||||
|
int idx_cur_pin = get_idx_pin(gpio_pins, count_valid_gpios, cur_pin);
|
||||||
|
if(idx_cur_pin == -1){
|
||||||
|
READ_CONF_FILE_PRINTF(" Could not find GPIO: %s in previously instanciated GPIOs\n", token_plus);
|
||||||
|
add_current_mapping = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cur_gpio_mapping.pins_idx[idx_pin] = idx_cur_pin;
|
||||||
|
idx_pin++;
|
||||||
|
READ_CONF_FILE_PRINTF(" GPIO %d in current mapping\n", cur_pin);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
READ_CONF_FILE_PRINTF(" Could not find GPIO: %s\n", token_plus);
|
||||||
|
add_current_mapping = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
token_plus = strtok_r(NULL, "+", &end_arg);//strtok_r(NULL, ",");
|
||||||
|
}
|
||||||
|
cur_gpio_mapping.nb_simultaneous_pins = idx_pin;
|
||||||
|
break;
|
||||||
|
case MAPPING_ARG_TYPE:
|
||||||
|
if(!strcmp(current_arg, "KEYBOARD")){
|
||||||
|
cur_gpio_mapping.type_mapping = TYPE_MAPPING_KEYBOARD;
|
||||||
|
}
|
||||||
|
else if(!strcmp(current_arg, "SHELL_COMMAND")){
|
||||||
|
cur_gpio_mapping.type_mapping = TYPE_MAPPING_SHELL_COMMAND;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
READ_CONF_FILE_PRINTF(" %s is not a valid mapping type\n", current_arg);
|
||||||
|
add_current_mapping = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MAPPING_ARG_VALUE:
|
||||||
|
switch (cur_gpio_mapping.type_mapping){
|
||||||
|
case TYPE_MAPPING_KEYBOARD:
|
||||||
|
cur_gpio_mapping.key_value = find_key(current_arg);
|
||||||
|
if(!cur_gpio_mapping.key_value){
|
||||||
|
READ_CONF_FILE_PRINTF(" Could not find Key: %s\n", current_arg);
|
||||||
|
add_current_mapping = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TYPE_MAPPING_SHELL_COMMAND:
|
||||||
|
cur_gpio_mapping.shell_command = malloc(strlen(current_arg)*sizeof(char));
|
||||||
|
strcpy(cur_gpio_mapping.shell_command, current_arg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
READ_CONF_FILE_PRINTF(" %d is not a valid mapping type\n", cur_gpio_mapping.type_mapping);
|
||||||
|
add_current_mapping = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MAPPING_ARG_STR_HELP_PIN_NAME:
|
||||||
|
if(!strlen(current_arg)) continue;
|
||||||
|
cur_gpio_mapping.pin_help_str = malloc(strlen(current_arg)*sizeof(char));
|
||||||
|
strcpy(cur_gpio_mapping.pin_help_str, current_arg);
|
||||||
|
break;
|
||||||
|
case MAPPING_ARG_STR_HELP_PIN_FCT:
|
||||||
|
if(!strlen(current_arg)) continue;
|
||||||
|
cur_gpio_mapping.fct_help_str = malloc(strlen(current_arg)*sizeof(char));
|
||||||
|
strcpy(cur_gpio_mapping.fct_help_str, current_arg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//next arg
|
||||||
|
token_comma = strtok_r(NULL, ",", &end_ln);
|
||||||
|
cur_arg_idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(add_current_mapping){
|
||||||
|
push(&head_chained_list_mapping_gpio, &cur_gpio_mapping);
|
||||||
|
READ_CONF_FILE_PRINTF("Current Mapping added successfully\n\n");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
READ_CONF_FILE_PRINTF("Current Mapping not added\n\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
READ_CONF_FILE_PRINTF("Sorting Chained list...\n");
|
||||||
|
bubbleSort(head_chained_list_mapping_gpio);
|
||||||
|
print_all_chained_list(head_chained_list_mapping_gpio);
|
||||||
|
print_gpios(gpio_pins, count_valid_gpios);
|
||||||
|
|
||||||
|
if(fp){
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return parameters */
|
||||||
|
*chained_list_mapping = head_chained_list_mapping_gpio;
|
||||||
|
*nb_valid_gpios = count_valid_gpios;
|
||||||
|
*valid_gpio_pins = gpio_pins;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Print all chained list content */
|
||||||
|
void print_all_chained_list(STRUCT_MAPPED_GPIO * head){
|
||||||
|
STRUCT_MAPPED_GPIO * current = head;
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
READ_CONF_FILE_PRINTF("Printing Chained list:\n ");
|
||||||
|
while (current != NULL) {
|
||||||
|
READ_CONF_FILE_PRINTF("Chained list Mapping GPIOs, idx: %d\n", idx);
|
||||||
|
|
||||||
|
print_chained_list_node(current);
|
||||||
|
|
||||||
|
idx++;
|
||||||
|
current = current->next_mapped_gpio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Print one chained list node */
|
||||||
|
void print_chained_list_node(STRUCT_MAPPED_GPIO * node){
|
||||||
|
// Print Pins:
|
||||||
|
if(node->nb_simultaneous_pins > 1){
|
||||||
|
READ_CONF_FILE_PRINTF(" %d Simultaneous pins at following idx: [", node->nb_simultaneous_pins);
|
||||||
|
int i;
|
||||||
|
for (i=0; i < node->nb_simultaneous_pins; i++){
|
||||||
|
READ_CONF_FILE_PRINTF("%d%s", node->pins_idx[i], (i==node->nb_simultaneous_pins-1)?"]\n":",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
READ_CONF_FILE_PRINTF(" idx pin: %d\n", node->pins_idx[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type mapping and Value
|
||||||
|
if (node->type_mapping == TYPE_MAPPING_KEYBOARD){
|
||||||
|
READ_CONF_FILE_PRINTF(" Type mapping: TYPE_MAPPING_KEYBOARD\n");
|
||||||
|
READ_CONF_FILE_PRINTF(" Key: %d\n", node->key_value);
|
||||||
|
}
|
||||||
|
else if (node->type_mapping == TYPE_MAPPING_SHELL_COMMAND){
|
||||||
|
READ_CONF_FILE_PRINTF(" Type mapping: TYPE_MAPPING_SHELL_COMMAND\n");
|
||||||
|
READ_CONF_FILE_PRINTF(" Shell command: %s\n", node->shell_command);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pin help String
|
||||||
|
if(node->pin_help_str[0]){
|
||||||
|
READ_CONF_FILE_PRINTF(" Pins: %s\n", node->pin_help_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function help String
|
||||||
|
if(node->fct_help_str[0]){
|
||||||
|
READ_CONF_FILE_PRINTF(" Function: %s\n", node->fct_help_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_gpios(int * valid_gpio_pins, int nb_valid_gpios){
|
||||||
|
READ_CONF_FILE_PRINTF("GPIO pins:\n[");
|
||||||
|
for(int i = 0; i< nb_valid_gpios; i++) {
|
||||||
|
READ_CONF_FILE_PRINTF("%d%s", valid_gpio_pins[i], (i==nb_valid_gpios-1)?"]\n":",");
|
||||||
|
}
|
||||||
|
}
|
||||||
74
read_conf_file.h
Normal file
74
read_conf_file.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#ifndef _READ_CONF_FILE_H_
|
||||||
|
#define _READ_CONF_FILE_H_
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Includes
|
||||||
|
****************************************************************/
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Defines
|
||||||
|
****************************************************************/
|
||||||
|
#define MAX_NUM_GPIO 32
|
||||||
|
|
||||||
|
#define MAX_SIMULTANEOUS_GPIO 12
|
||||||
|
|
||||||
|
#define MAX_LENGTH_STR_PINS 48
|
||||||
|
#define MAX_LENGTH_STR_TYPE 16
|
||||||
|
#define MAX_LENGTH_STR_VALUE 256
|
||||||
|
#define MAX_LENGTH_STR_HELP_PIN_NAME 48
|
||||||
|
#define MAX_LENGTH_STR_HELP_PIN_FCT 256
|
||||||
|
#define MAX_LN_LENGTH (MAX_LENGTH_STR_PINS+\
|
||||||
|
MAX_LENGTH_STR_TYPE+\
|
||||||
|
MAX_LENGTH_STR_VALUE+\
|
||||||
|
MAX_LENGTH_STR_HELP_PIN_NAME+\
|
||||||
|
MAX_LENGTH_STR_HELP_PIN_FCT)
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
TYPE_MAPPING_KEYBOARD,
|
||||||
|
TYPE_MAPPING_SHELL_COMMAND,
|
||||||
|
NB_TYPE_MAPPING,
|
||||||
|
} ENUM_TYPE_MAPPING;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
MAPPING_ARG_PINS = 0,
|
||||||
|
MAPPING_ARG_TYPE,
|
||||||
|
MAPPING_ARG_VALUE,
|
||||||
|
MAPPING_ARG_STR_HELP_PIN_NAME,
|
||||||
|
MAPPING_ARG_STR_HELP_PIN_FCT,
|
||||||
|
NB_MAPPING_ARG_NAMES,
|
||||||
|
} ENUM_MAPPING_ARGS_NAMES;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
char name[32];
|
||||||
|
int code;
|
||||||
|
}key_names_s;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct gpio_mapping_s{
|
||||||
|
int pins_idx[MAX_SIMULTANEOUS_GPIO];
|
||||||
|
int nb_simultaneous_pins;
|
||||||
|
ENUM_TYPE_MAPPING type_mapping;
|
||||||
|
int key_value;
|
||||||
|
char *shell_command;
|
||||||
|
char *pin_help_str;
|
||||||
|
char *fct_help_str;
|
||||||
|
struct gpio_mapping_s * next_mapped_gpio;
|
||||||
|
bool activated;
|
||||||
|
}STRUCT_MAPPED_GPIO;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Public functions
|
||||||
|
****************************************************************/
|
||||||
|
void get_mapping_from_conf_file(STRUCT_MAPPED_GPIO ** chained_list_mapping,
|
||||||
|
int* nb_valid_gpios, int ** valid_gpio_pins);
|
||||||
|
void print_all_chained_list(STRUCT_MAPPED_GPIO * head);
|
||||||
|
void print_chained_list_node(STRUCT_MAPPED_GPIO * node);
|
||||||
|
void print_gpios(int * valid_gpio_pins, int nb_valid_gpios);
|
||||||
|
|
||||||
|
#endif //_READ_CONF_FILE_H_
|
||||||
230
uinput.c
Normal file
230
uinput.c
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
/**** uinput.c *****************************/
|
||||||
|
/* M. Moller 2013-01-16 */
|
||||||
|
/* Universal RPi GPIO keyboard daemon */
|
||||||
|
/*******************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (C) 2013 Michael Moller.
|
||||||
|
This file is part of the Universal Raspberry Pi GPIO keyboard daemon.
|
||||||
|
|
||||||
|
This is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The software 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; 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 <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <linux/uinput.h>
|
||||||
|
//#include "config.h"
|
||||||
|
//include "daemon.h"
|
||||||
|
#include "uinput.h"
|
||||||
|
|
||||||
|
static int sendRel(int dx, int dy);
|
||||||
|
static int sendSync(void);
|
||||||
|
|
||||||
|
static struct input_event uidev_ev;
|
||||||
|
static int uidev_fd;
|
||||||
|
/*static keyinfo_s lastkey;*/
|
||||||
|
|
||||||
|
#define die(str, args...) do { \
|
||||||
|
perror(str); \
|
||||||
|
return(EXIT_FAILURE); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define DEBUG_UINPUT_PRINTF (0)
|
||||||
|
#if DEBUG_UINPUT_PRINTF
|
||||||
|
#define UINPUT_PRINTF(...) printf(__VA_ARGS__);
|
||||||
|
#else
|
||||||
|
#define UINPUT_PRINTF(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int init_uinput(void)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct uinput_user_dev uidev;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
|
||||||
|
if(fd < 0)
|
||||||
|
die("/dev/uinput");
|
||||||
|
|
||||||
|
if(ioctl(fd, UI_SET_EVBIT, EV_KEY) < 0)
|
||||||
|
die("error: ioctl");
|
||||||
|
if(ioctl(fd, UI_SET_EVBIT, EV_REP) < 0)
|
||||||
|
die("error: ioctl");
|
||||||
|
if(ioctl(fd, UI_SET_KEYBIT, BTN_LEFT) < 0)
|
||||||
|
die("error: ioctl");
|
||||||
|
|
||||||
|
if(ioctl(fd, UI_SET_EVBIT, EV_REL) < 0)
|
||||||
|
die("error: ioctl");
|
||||||
|
if(ioctl(fd, UI_SET_RELBIT, REL_X) < 0)
|
||||||
|
die("error: ioctl");
|
||||||
|
if(ioctl(fd, UI_SET_RELBIT, REL_Y) < 0)
|
||||||
|
die("error: ioctl");
|
||||||
|
|
||||||
|
/* don't forget to add all the keys! */
|
||||||
|
for(i=0; i<256; i++){
|
||||||
|
if(ioctl(fd, UI_SET_KEYBIT, i) < 0)
|
||||||
|
die("error: ioctl");
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&uidev, 0, sizeof(uidev));
|
||||||
|
snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-sample");
|
||||||
|
uidev.id.bustype = BUS_USB;
|
||||||
|
uidev.id.vendor = 0x1;
|
||||||
|
uidev.id.product = 0x1;
|
||||||
|
uidev.id.version = 1;
|
||||||
|
|
||||||
|
/*if(write(fd, &uidev, sizeof(uidev)) < 0)
|
||||||
|
die("error: write");*/
|
||||||
|
|
||||||
|
if(ioctl(fd, UI_DEV_SETUP, &uidev) < 0)
|
||||||
|
die("error: ioctl");
|
||||||
|
|
||||||
|
if(ioctl(fd, UI_DEV_CREATE) < 0)
|
||||||
|
die("error: ioctl");
|
||||||
|
|
||||||
|
uidev_fd = fd;
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_uinput(void)
|
||||||
|
{
|
||||||
|
int dx, dy;
|
||||||
|
int i,k;
|
||||||
|
|
||||||
|
//srand(time(NULL));
|
||||||
|
int op = 1;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
//switch(rand() % 4) {
|
||||||
|
switch(op) {
|
||||||
|
case 0:
|
||||||
|
dx = -10;
|
||||||
|
dy = -1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
dx = 10;
|
||||||
|
dy = 1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
dx = -1;
|
||||||
|
dy = 10;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
dx = 1;
|
||||||
|
dy = -10;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*k = send_gpio_keys(21, 1);
|
||||||
|
sendKey(k, 0);*/
|
||||||
|
sendKey(KEY_D, 0);
|
||||||
|
|
||||||
|
for(i = 0; i < 20; i++) {
|
||||||
|
//sendKey(KEY_D, 1);
|
||||||
|
//sendKey(KEY_D, 0);
|
||||||
|
sendRel(dx, dy);
|
||||||
|
|
||||||
|
usleep(15000);
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int close_uinput(void)
|
||||||
|
{
|
||||||
|
sleep(2);
|
||||||
|
|
||||||
|
if(ioctl(uidev_fd, UI_DEV_DESTROY) < 0)
|
||||||
|
die("error: ioctl");
|
||||||
|
|
||||||
|
close(uidev_fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sendKey(int key, int value)
|
||||||
|
{
|
||||||
|
struct input_event ie;
|
||||||
|
//memset(&uidev_ev, 0, sizeof(struct input_event));
|
||||||
|
//gettimeofday(&uidev_ev.time, NULL);
|
||||||
|
ie.type = EV_KEY;
|
||||||
|
ie.code = key;
|
||||||
|
ie.value = value;
|
||||||
|
ie.time.tv_sec = 0;
|
||||||
|
ie.time.tv_usec = 0;
|
||||||
|
UINPUT_PRINTF("sendKey: %d = %d\n", key, value);
|
||||||
|
if(write(uidev_fd, &ie, sizeof(struct input_event)) < 0)
|
||||||
|
die("error: write");
|
||||||
|
|
||||||
|
sendSync();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sendKeyAndStopKey(int key)
|
||||||
|
{
|
||||||
|
sendKey(key, 1);
|
||||||
|
sendKey(key, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sendRel(int dx, int dy)
|
||||||
|
{
|
||||||
|
memset(&uidev_ev, 0, sizeof(struct input_event));
|
||||||
|
uidev_ev.type = EV_REL;
|
||||||
|
uidev_ev.code = REL_X;
|
||||||
|
uidev_ev.value = dx;
|
||||||
|
if(write(uidev_fd, &uidev_ev, sizeof(struct input_event)) < 0)
|
||||||
|
die("error: write");
|
||||||
|
|
||||||
|
memset(&uidev_ev, 0, sizeof(struct input_event));
|
||||||
|
uidev_ev.type = EV_REL;
|
||||||
|
uidev_ev.code = REL_Y;
|
||||||
|
uidev_ev.value = dy;
|
||||||
|
if(write(uidev_fd, &uidev_ev, sizeof(struct input_event)) < 0)
|
||||||
|
die("error: write");
|
||||||
|
|
||||||
|
sendSync();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sendSync(void)
|
||||||
|
{
|
||||||
|
UINPUT_PRINTF("sendSync\n");
|
||||||
|
//memset(&uidev_ev, 0, sizeof(struct input_event));
|
||||||
|
struct input_event ie;
|
||||||
|
ie.type = EV_SYN;
|
||||||
|
ie.code = SYN_REPORT;
|
||||||
|
ie.value = 0;
|
||||||
|
ie.time.tv_sec = 0;
|
||||||
|
ie.time.tv_usec = 0;
|
||||||
|
if(write(uidev_fd, &ie, sizeof(struct input_event)) < 0)
|
||||||
|
die("error: sendSync - write");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
37
uinput.h
Normal file
37
uinput.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/**** uinput.h *****************************/
|
||||||
|
/* M. Moller 2013-01-16 */
|
||||||
|
/* Universal RPi GPIO keyboard daemon */
|
||||||
|
/*******************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (C) 2013 Michael Moller.
|
||||||
|
This file is part of the Universal Raspberry Pi GPIO keyboard daemon.
|
||||||
|
|
||||||
|
This is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The software 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _UINPUT_H_
|
||||||
|
#define _UINPUT_H_
|
||||||
|
|
||||||
|
int init_uinput(void);
|
||||||
|
int test_uinput(void);
|
||||||
|
int close_uinput(void);
|
||||||
|
int send_gpio_keys(int gpio, int value);
|
||||||
|
int sendKey(int key, int value);
|
||||||
|
int sendKeyAndStopKey(int key);
|
||||||
|
//void get_last_key(keyinfo_s *kp);
|
||||||
|
|
||||||
|
#endif //_UINPUT_H_
|
||||||
Loading…
x
Reference in New Issue
Block a user