source: abuse/tags/0.7.0/src/keydrv.cpp @ 475

Last change on this file since 475 was 2, checked in by Sam Hocevar, 17 years ago
  • imported original 0.7.0 tarball
File size: 4.0 KB
Line 
1/*      Key driver, by Jonathan Clark
2          (portions from showkey.c)
3*/
4
5#include <stdio.h>
6#include <unistd.h>
7#include <getopt.h>
8#include <signal.h>
9#include <fcntl.h>
10#include <termios.h>
11#include <linux/kd.h>
12#include <linux/vt.h>
13#include <fcntl.h>
14#include <sys/stat.h>
15
16
17
18unsigned char keyboard_buf[16];
19
20#include <linux/keyboard.h>
21#include <sys/ioctl.h>
22#include <stdlib.h>
23#include <string.h>
24
25int fd,my_console=-1;
26struct termios old_term;
27
28void clean_up(int close_fd) {
29        ioctl(fd, KDSKBMODE, K_XLATE);
30
31        tcsetattr(fd, TCSAFLUSH, &old_term);
32        if (close_fd)
33          {
34            close(fd);
35            unlink("/tmp/jckey-driver");
36            exit(0);
37          }
38}
39
40void go_raw(int open_fd)
41{
42        struct termios new_term;
43        struct vt_stat v;
44        if (open_fd)
45        {
46                if ((fd = open("/dev/console", O_RDONLY)) < 0) {
47                        perror("/dev/console");
48                        exit(1);
49                }
50        }
51        if (my_console==-1)
52        {
53          ioctl(fd,VT_GETSTATE,&v);  /* see which console we are using */
54          my_console=v.v_active;
55        }
56        ioctl(fd,VT_WAITACTIVE,my_console);  /* wait for our console to come back */
57
58        tcgetattr(fd, &new_term);
59        tcgetattr(fd, &old_term);
60
61        new_term.c_lflag = new_term.c_lflag & ~ (ICANON | ECHO | ISIG );
62        new_term.c_cc[VMIN] = 1; //sizeof(keyboard_buf);
63        new_term.c_cc[VTIME] = 0;       /* 0.1 sec intercharacter timeout */
64
65        tcsetattr(fd, TCSAFLUSH, &new_term);
66        if (ioctl(fd, KDSKBMODE,
67                K_RAW)) {
68                perror("KDSKBMODE");
69                exit(1);
70        }
71        system("stty raw </dev/console >/dev/console");
72
73}
74
75void die(int x) {
76        fprintf(stderr,"die %d\n",x);
77   
78        clean_up(1);
79        exit(1);
80}
81
82int key_watch(int write_fd)
83{
84        unsigned char map[128];
85
86        int i, n,lalt,ralt,switch_to,lctrl,rctrl,up,quit;
87
88
89        /*
90                if we receive a signal, we want to exit nicely, in
91                order not to leave the keyboard in an unusable mode
92        */
93        signal(SIGHUP, die);
94        signal(SIGINT, die);
95        signal(SIGQUIT, die);
96        signal(SIGILL, die);
97        signal(SIGTRAP, die);
98        signal(SIGABRT, die);
99        signal(SIGIOT, die);
100        signal(SIGFPE, die);
101        signal(SIGKILL, die);
102        signal(SIGUSR1, die);
103        signal(SIGSEGV, die);
104        signal(SIGUSR2, die);
105        signal(SIGPIPE, die);
106        signal(SIGTERM, die);
107        signal(SIGSTKFLT, die);
108        /*signal(SIGCHLD, die);*/
109        signal(SIGCONT, die);
110        signal(SIGSTOP, die);
111        signal(SIGTSTP, die);
112        signal(SIGTTIN, die);
113        signal(SIGTTOU, die);
114
115        go_raw(1);
116        quit=lalt=ralt=lctrl=rctrl=0;
117        memset(map,0,128);
118        while (!quit) {
119                n = read(fd, keyboard_buf, sizeof(keyboard_buf));
120                for (i = 0; i < n; i++)
121                { up=!(keyboard_buf[i]&0x80);
122                  if ((keyboard_buf[i]&0x7f)==56) lalt=up;
123                  if ((keyboard_buf[i]&0x7f)==96) ralt=up;
124                  if ((keyboard_buf[i]&0x7f)==29) lctrl=up;
125                  if (up || up!=map[(keyboard_buf[i]&0x7f)])
126                  {
127                    map[(keyboard_buf[i]&0x7f)]=up;
128                    if (!write(write_fd,&keyboard_buf[i],1))
129                    {
130                      fprintf(stderr,"keydrv : unable to write to parent (cleaning up)\n");
131                      clean_up(1);
132                      exit(0);
133                    }
134                  }
135                }
136                for (i = 0; i < n; i++)
137                {
138                  if ((lalt || ralt) && (keyboard_buf[i]&0x7f)>=59 &&
139                      (keyboard_buf[i]&0x7f)<=68)
140                  {
141
142                    switch_to=(keyboard_buf[i]&0x7f)-58;
143                    clean_up(0);
144                   
145                    ioctl(fd,VT_ACTIVATE,switch_to);
146                    go_raw(0);
147                  }
148                  if ((lctrl || rctrl) && (keyboard_buf[i]&0x7f)==46)
149                  {
150                    fprintf(stderr,"^C\n"); fflush(stderr);
151                    quit=1;
152                  }
153                }
154
155        }
156        clean_up(1);
157        exit(0);
158}
159
160
161main()
162{
163  int f,chd;
164  unlink("/tmp/jckey-driver");
165  if (mkfifo("/tmp/jckey-driver",S_IRWXU))
166  { perror("Key driver : unable to make fifo /tmp/jckey-driver");
167    exit(1);
168  }
169  chd=fork();
170  if (chd)
171  { printf("%d\n",chd);
172    return 0;
173  }
174  f=open("/tmp/jckey-driver",O_WRONLY);
175  if (f<0)
176  { perror("/tmp/jckey-driver");
177    exit(1);
178  }
179  key_watch(f);
180  close(f);
181  unlink("/tmp/jckey-driver");
182}
Note: See TracBrowser for help on using the repository browser.