N
hallo,
es ist schon ewig her, aber ich habe es nun geschafft und das Programm umgeändert. Jegliche Kritik ist gere Willkommen :). Es soll ja schließlich besser werden. Vorallem bei dem was alles in das Header File gehört und was nicht war ich mir nicht so sicher. Braucht jede Funktion einen Prototyp oder nur die, welche später von einem anderem Teil aufgerufen wird?
Hier ist die neue Version:
/* main.c
* "Thumb to keys" lets you use the buttons of your PDA for fast writing.
* First of all it translates the keypad direction into numbers
* "up + left" is one, "up" is two, "up + right" is tree and so on. After that
* it will allways look after combinations of two numbers to generate a key.
* the definition of the keys is on thumbscript.com or you can read the keytable
* struct.
*
* It is able to switch the behaviour of the buttons. If you are pressing the
* combination "9 4" in thumscript mode (the default mode on startup) you will
* get into the normal mode. You than can use your buttons as usual. If you
* want to get into the thumbscript mode you will need to press
* enter 5 times.
*
* Later there will be more possible keytables for your convenience.
*
* Use gcc -o thumb2keys keyevents_2_uinput.c \
* number_2_keyevents.c evdev_2_nubers.c main.c
* to compile it.
*
* You need to have uinput and evdev loaded or compiled in your kernel!
*
* Have fun!
*
* Some parts of this program are based on esekeyd, uinput_mouse.c and kbdd
* which are all licenced under GPL.
*
* This Code is licenced under GPL v2.
*
*
*/
#include "thumbkeys.h"
int main(){
// set keytable to thumbscript table
used_keytable=1;
// initialization of evdev and uinput
dev_event_init();
dev_uinput_init();
// start the translation
beginn_translation();
// close uinput and evdev
close(fp_uinput);
close(fp_event);
}
/* evdev_2_nubers.c
* Evdev 2 numbers. This part of the programm will read out the evdev and
* translate it to numbers (see main.c for explanation).
*
* At this state of the development you need to set the evdev path
* yourself at thumbkeys.h.
*
* This code is licenced under GPL v2.
*
*/
#include <fcntl.h>
#include <stdio.h>
#include "thumbkeys.h"
struct input_event ev;
struct keybuffer {
char up;
char down;
char left;
char right;
char enter;
};
struct keybuffer kbuffer = { 0,0,0,0,0 };
int numbers[2] = {0,0};
int fp_event = 0;
int count_enter = 0;
int dev_event_init(void){
if (!(fp_event = open(EV_FILE, O_RDONLY))) {
perror("failed to open event device");
return -1;
}
if ((ioctl(fp_event, EVIOCGRAB,1)) == -1) {
perror("failed to grab the device");
return -1;
}
}
void clear_kbuffer(void){
kbuffer.up = 0;
kbuffer.down = 0;
kbuffer.left = 0;
kbuffer.right = 0;
kbuffer.enter = 0;
}
int key_to_number(struct input_event ev) {
if (ev.value == 1) {
switch (ev.code) {
case KEY_UP:
kbuffer.up=1;
break;
case KEY_DOWN:
kbuffer.down=1;
break;
case KEY_LEFT:
kbuffer.left=1;
break;
case KEY_RIGHT:
kbuffer.right=1;
break;
case KEY_ENTER:
kbuffer.enter=1;
break;
}
}
if (ev.value == 0) {
if ( (kbuffer.up ==1) && (kbuffer.down ==0) && (kbuffer.left ==1) && (kbuffer.right ==0) && (kbuffer.enter ==0) ) {
clear_kbuffer();
return 1;
}
if ( (kbuffer.up ==1) && (kbuffer.down ==0) && (kbuffer.left ==0) && (kbuffer.right ==0) && (kbuffer.enter ==0) ) {
clear_kbuffer();
return 2;
}
if ( (kbuffer.up ==1) && (kbuffer.down ==0) && (kbuffer.left ==0) && (kbuffer.right ==1) && (kbuffer.enter ==0) ) {
clear_kbuffer();
return 3;
}
if ( (kbuffer.up ==0) && (kbuffer.down ==0) && (kbuffer.left ==1) && (kbuffer.right ==0) && (kbuffer.enter ==0) ) {
clear_kbuffer();
return 4;
}
if ( (kbuffer.up ==1) && (kbuffer.down ==1) && (kbuffer.left ==1) && (kbuffer.right ==1) || (kbuffer.enter ==1) ) {
clear_kbuffer();
return 5;
}
if ( (kbuffer.up ==0) && (kbuffer.down ==0) && (kbuffer.left ==0) && (kbuffer.right ==1) && (kbuffer.enter ==0) ) {
clear_kbuffer();
return 6;
}
if ( (kbuffer.up ==0) && (kbuffer.down ==1) && (kbuffer.left ==1) && (kbuffer.right ==0) && (kbuffer.enter ==0) ) {
clear_kbuffer();
return 7;
}
if ( (kbuffer.up ==0) && (kbuffer.down ==1) && (kbuffer.left ==0) && (kbuffer.right ==0) && (kbuffer.enter ==0) ) {
clear_kbuffer();
return 8;
}
if ( (kbuffer.up ==0) && (kbuffer.down ==1) && (kbuffer.left ==0) && (kbuffer.right ==1) && (kbuffer.enter ==0) ) {
clear_kbuffer();
return 9;
}
}
return 0;
}
void check_enter(struct input_event ev){
if ((ev.value == KEY_RELEASE) && (ev.code == KEY_ENTER)){
if (count_enter++ >=5){
used_keytable = 1;
count_enter = 0;
}
}
if ((ev.value == KEY_RELEASE) && (ev.code != KEY_ENTER))
count_enter = 0;
}
void key_2_key(struct input_event ev){
if (ev.value == KEY_PRESS)
key_press(ev.code);
if (ev.value == KEY_RELEASE)
key_release(ev.code);
if (ev.value == KEY_REPEAT)
key_autorepeat(ev.code);
}
void beginn_translation(void) {
int number = 0;
int i = 0;
while (read (fp_event,&ev, sizeof (struct input_event))) {
if (ev.type == EV_KEY) {
check_enter(ev);
if (used_keytable == 0)
key_2_key(ev);
else {
number = key_to_number(ev);
if (number != 0) {
switch (i) {
case 0:
numbers[i] = number;
i++;
break;
case 1:
numbers[i] = number;
i=0;
numbers_to_keyevents(numbers[0],numbers[1]);
break;
}
}
}
}
}
}
/* number_2_keyevents.c
* This is the number 2 keyevents part.
* You can easily extend it or change the key-combinations.
* Moreover it is planned to provide more keytables.
* The key-combinations are similar to the ones of thumbscript.com with some
* changes.
*
* This Code is licenced under GPL v2.
*
*/
#include <linux/input.h>
#include <stdio.h>
#include "thumbkeys.h"
int switch_table(int a){
/*
* This part is expandable. It is planed to offer more than
* one key-definition table. For that purpose we will save the table-number
* in the value of key_shifter.
*/
switch (a) {
case 0: used_keytable=0;
}
}
int numbers_to_keyevents(int a, int b) {
static int combo_key_counter;
static int combo_key_code[10];
struct keycodes {
int keycode;
int key_shifter;
int special;
};
struct keycodes keytable[9][9] =
{
{{KEY_LEFTCTRL,0,1},{KEY_V,0,0},{KEY_W,0,0},{KEY_P,0,0},{KEY_1,0,0},{KEY_Q,0,0},{KEY_X,0,0},{KEY_Y,0,0},{KEY_U,0,0}},
{{0,0,0},{KEY_LEFTSHIFT,0,1},{KEY_K,0,0},{KEY_J,0,0},{KEY_2,0,0},{KEY_L,0,0},{KEY_D,0,0},{KEY_I,0,0},{KEY_B,0,0}},
{{KEY_APOSTROPHE,KEY_LEFTSHIFT,0},{KEY_APOSTROPHE,0,0},{KEY_BACKSPACE,0,0},{3,0,0},{KEY_3,0,0},{KEY_G,0,0},{KEY_E,0,0},{KEY_F,0,0},{KEY_C,0,0}},
{{KEY_DOT,KEY_LEFTSHIFT,0},{KEY_EQUAL,0,0},{0,0,0},{KEY_TAB,0,0},{KEY_4,0,0},{KEY_O,0,0},{KEY_Z,0,0},{KEY_N,0,0},{KEY_H,0,0}},
{{KEY_1,KEY_LEFTSHIFT,0},{KEY_2,KEY_LEFTSHIFT,0},{KEY_3,KEY_LEFTSHIFT,0},{KEY_4,KEY_LEFTSHIFT,0},{KEY_5,0,0},{KEY_6,KEY_LEFTSHIFT,0},{KEY_7,KEY_LEFTSHIFT,0},{KEY_8,KEY_LEFTSHIFT,0},{KEY_5,KEY_LEFTSHIFT,0}},
{{KEY_ESC,0,0},{KEY_EQUAL,KEY_LEFTSHIFT,0},{KEY_COMMA,KEY_LEFTSHIFT,0},{KEY_0,0,0},{KEY_6,0,0},{KEY_ENTER,0,0},{0,0,0},{KEY_T,0,0},{KEY_S,0,0}},
{{KEY_0,KEY_LEFTSHIFT,0},{KEY_SLASH,KEY_LEFTSHIFT,0},{KEY_SLASH,0,0},{KEY_SEMICOLON,0,0},{KEY_7,0,0},{0,0,0},{KEY_COMMA,0,0},{KEY_M,0,0},{KEY_A,0,0}},
{{KEY_RIGHTBRACE,0,0},{KEY_BACKSLASH,KEY_LEFTSHIFT,0},{KEY_LEFTBRACE,0,0},{KEY_RIGHTBRACE,KEY_LEFTSHIFT,0},{KEY_8,0,0},{KEY_LEFTBRACE,KEY_LEFTSHIFT,0},{KEY_GRAVE,KEY_LEFTSHIFT,0},{KEY_SPACE,0,0},{KEY_R,0,0}},
{{KEY_BACKSLASH,0,0},{0,0,0},{KEY_9,KEY_LEFTSHIFT,0},{99999,0,0},{KEY_9,0,0},{KEY_SEMICOLON,KEY_LEFTSHIFT,0},{KEY_MINUS,KEY_LEFTSHIFT,0},{KEY_MINUS,0,0},{KEY_DOT,0,0}}
};
/* We need to decrease the input values about one. This is because we get
* numbers from 1 to 9. We will also check that we get only those values
*/
if (((a >0) && (a<10)) && ((b >0) && (b<10))) {
a--;
b--;
if (keytable[a][b].keycode !=0) { //Get rid of not defined combinations
/*
* If the keycode is 99999 we switch the keytable. I decided to use this
* because it is not defined. If I am wrong change it here and in the
* struct to some not defined value in input.h.
*/
if(keytable[a][b].keycode == 99999)
switch_table(keytable[a][b].key_shifter);
else if (keytable[a][b].keycode !=0) {
if (combo_key_counter !=0) {
if (keytable[a][b].key_shifter !=0) {
key_press(keytable[a][b].keycode);
combo_key_counter++;
combo_key_code[combo_key_counter]=keytable[a][b].keycode;
}
else if (keytable[a][b].key_shifter ==0) {
key_press(keytable[a][b].key_shifter);
key_press(keytable[a][b].keycode);
combo_key_code[combo_key_counter]=keytable[a][b].keycode;
combo_key_counter++;
combo_key_code[combo_key_counter]=keytable[a][b].key_shifter;
combo_key_counter++;
}
if (keytable[a][b].special!=1) {
combo_key_counter--;
while (combo_key_counter!=0) {
key_release(combo_key_code[combo_key_counter]);
combo_key_counter--;
}
}
}
else if (combo_key_counter==0) {
if (keytable[a][b].special==1) {
if (keytable[a][b].key_shifter !=0) {
key_press(keytable[a][b].key_shifter);
key_press(keytable[a][b].keycode);
combo_key_code[combo_key_counter]=keytable[a][b].keycode;
combo_key_counter++;
combo_key_code[combo_key_counter]=keytable[a][b].key_shifter;
combo_key_counter++;
}
else if (keytable[a][b].key_shifter ==0) {
key_press(keytable[a][b].keycode);
combo_key_code[combo_key_counter]=keytable[a][b].keycode;
combo_key_counter++;
}
}
else if (keytable[a][b].special==0){
if (keytable[a][b].key_shifter !=0) {
key_press(keytable[a][b].key_shifter);
key_press(keytable[a][b].keycode);
key_release(keytable[a][b].keycode);
key_release(keytable[a][b].key_shifter);
}
else if (keytable[a][b].key_shifter ==0){
key_press(keytable[a][b].keycode);
key_release(keytable[a][b].keycode);
}
}
}
}
}
}
}
/* keyevents_2_uinput.c
* Keyevents to uinput. This part creates a virtual keyboard for passing the
* keycodes to the input device.
*
* This Code is licenced under GPL v2.
*
*
*/
#include <linux/input.h>
#include <linux/uinput.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include "thumbkeys.h"
int dev_uinput_init(void) {
struct uinput_user_dev dev;
int aux;
fp_uinput = open("/dev/uinput", O_RDWR);
if (fp_uinput <= 0)
fp_uinput = open("/dev/misc/uinput", O_RDWR);
if (fp_uinput <= 0)
fp_uinput = open("/dev/devfs/misc/uinput", O_RDWR);
if (fp_uinput <= 0)
fp_uinput = open("/dev/input/uinput", O_RDWR);
if (fp_uinput <= 0) {
perror("failed to open the uinput device");
return -1;
}
memset(&dev, 0, sizeof(dev));
strncpy(dev.name, "Thumbscript", UINPUT_MAX_NAME_SIZE);
if (write(fp_uinput, &dev, sizeof(dev)) < 0) {
fprintf(stderr,"failed to write uinputdev");
close(fp_uinput);
return -1;
}
if (ioctl(fp_uinput, UI_SET_EVBIT, EV_KEY) != 0) {
close(fp_uinput);
return -1;
}
if (ioctl(fp_uinput, UI_SET_EVBIT, EV_REP) != 0) {
close(fp_uinput);
return -1;
}
for (aux = KEY_RESERVED; aux <= KEY_UNKNOWN; aux++)
if (ioctl(fp_uinput, UI_SET_KEYBIT, aux) != 0) {
close(fp_uinput);
return -1;
}
if (ioctl(fp_uinput, UI_DEV_CREATE) != 0) {
close(fp_uinput);
return -1;
}
}
void key_press(int code){
struct input_event event;
gettimeofday(&event.time, NULL);
event.type = EV_KEY;
event.code = code;
event.value = KEY_PRESS;
write(fp_uinput, &event, sizeof(event));
}
void key_release(int code){
struct input_event event;
gettimeofday(&event.time, NULL);
event.type = EV_KEY;
event.code = code;
event.value = KEY_RELEASE;
write(fp_uinput, &event, sizeof(event));
}
void key_autorepeat(int code){
struct input_event event;
gettimeofday(&event.time, NULL);
event.type = EV_KEY;
event.code = code;
event.value = KEY_REPEAT;
write(fp_uinput, &event, sizeof(event));
}
/*
* Header file
*
* This Code is licenced under GPL v2.
*
*/
#include <linux/input.h>
#include <sys/types.h>
int used_keytable;
// Definitions for number_2_keyevents.c
int switch_table(int a);
int numbers_to_keyevents(int a, int b);
static int combo_key_counter=0;
static int combo_key_code[10] = {0,0,0,0,0,0,0,0,0,0};
// Definitions for keyevents_2_uinput.c
#define KEY_PRESS 1
#define KEY_RELEASE 0
#define KEY_REPEAT 2
void key_press(int code);
void key_release(int code);
void key_autorepeat(int code);
int dev_uinput_init(void);
int dev_uinput_init(void);
int fp_uinput;
// Definitions for evdev_2_numbers
#define EV_FILE "/dev/input/event0"
void clear_kbuffer(void);
void beginn_translation(void);
void check_enter(struct input_event ev);
void key_2_key(struct input_event ev);
int key_to_number(struct input_event ev);
int dev_event_init(void);
int fp_event;
Vielen Dank für das Lesen.
nice