2 * input_layer - Kernel ACPI Event Input Layer Interface
4 * Handles the details of getting kernel ACPI events from the input
5 * layer (/dev/input/event*).
7 * Inspired by (and in some cases blatantly lifted from) Vojtech Pavlik's
10 * Copyright (C) 2008, Ted Felix (www.tedfelix.com)
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include <linux/input.h>
40 #include "connection_list.h"
43 #define DIM(a) (sizeof(a) / sizeof(a[0]))
45 #define INPUT_LAYER_FS "/dev/input/event*"
47 /*-----------------------------------------------------------------*/
48 /* called when an input layer event is received */
49 void process_input(int fd)
51 struct input_event event;
54 nbytes = read(fd, &event, sizeof(event));
57 printf("Input layer connection closed.\n");
62 /* if it's a signal, bail */
66 printf("Input layer read error: %s (%d)\n",
67 strerror(errno), errno);
71 /* ??? Is it possible for a partial message to come across? */
72 /* If so, we've got more code to write... */
74 if (nbytes != sizeof(event)) {
75 printf("Input Layer unexpected Length\n");
76 printf(" Expected: %lu Got: %zd\n",
77 (unsigned long) sizeof(event), nbytes);
81 /* If the Escape key was pressed, set the exitflag to exit. */
82 if (event.type == EV_KEY &&
83 event.code == KEY_ESC &&
85 printf("Escape key pressed\n");
89 if (event.type == EV_SYN)
90 printf("Input Layer: Sync\n");
92 /* format and display the event struct in decimal */
93 printf("Input Layer: "
94 "Type: %hu Code: %hu Value: %d\n",
95 event.type, event.code, event.value);
98 #define BITS_PER_LONG (sizeof(long) * 8)
99 #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
100 #define OFF(x) ((x)%BITS_PER_LONG)
101 #define LONG(x) ((x)/BITS_PER_LONG)
102 #define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
104 /*-----------------------------------------------------------------*
105 * open each of the appropriate /dev/input/event* files for input */
106 void open_input(void)
108 char *filename = NULL;
113 int had_some_success = 0;
116 /* get all the matching event filenames */
117 glob(INPUT_LAYER_FS, 0, NULL, &globbuf);
119 /* for each event file */
120 for (i = 0; i < globbuf.gl_pathc; ++i)
122 filename = globbuf.gl_pathv[i];
124 fd = open(filename, O_RDONLY | O_NONBLOCK);
126 /* get this event file's name */
127 strcpy(evname, "Unknown");
128 ioctl(fd, EVIOCGNAME(sizeof(evname)), evname);
130 printf("%s (%s) opened successfully\n", filename, evname);
131 had_some_success = 1;
133 /* add a connection to the list */
135 c.process = process_input;
140 if (had_some_success == 1)
143 printf("open for %s failed: %s (%d)\n",
144 filename, strerror(errno2), errno2);
145 if (errno2 == EACCES)
146 printf(" (try running as root)\n");
147 if (errno2 == ENOENT)
148 printf(" (input layer driver may not be present)\n");