source: abuse/trunk/src/keydrv.cpp @ 97

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