watch the accelerometer values on a thinkpad running openbsd and run a command on too much movement
1/* vim:ts=8
2 * $Id: movelock.c,v 1.4 2008/04/01 01:12:01 jcs Exp $
3 *
4 * movelock
5 * freak out when the accelerometer detects too much movement
6 *
7 * Copyright (c) 2005, 2008 joshua stein <jcs@jcs.org>
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <err.h>
34#include <errno.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <time.h>
38#include <unistd.h>
39#include <sys/param.h>
40#include <sys/sysctl.h>
41#include <sys/sensors.h>
42
43/* #define DEBUG 1 */
44
45/* program to run when we detect too much movement (lock x, halt -p, etc.) */
46#ifndef LOCK_PROG
47#define LOCK_PROG "xautolock -locknow"
48#endif
49
50/* how many seconds to check movement */
51#define MOVE_TIME 1
52
53/* maximum amount of movement allowed per MOVE_TIME */
54#define MOVE_THRESH_X 20
55#define MOVE_THRESH_Y 10
56
57/* MIB names for sensor (aps) device, X_VAR, and Y_VAR sensors */
58#define APS_DEV_NUM 0
59#define X_VAR_TYPE 10
60#define X_VAR_NUMT 2
61#define Y_VAR_TYPE 10
62#define Y_VAR_NUMT 3
63
64/* time to wait after allowing a second spawning of LOCK_PROG */
65#define LOCK_WAIT 3
66
67extern char *__progname;
68
69int64_t getsensor(int, int, int);
70void spawn(char *);
71
72int
73main(int argc, char *argv[])
74{
75 char *lockprog = LOCK_PROG;
76 int lastvalues[] = { -1, -1 };
77 int curvalues[] = { -1, -1 };
78 int curchanges[] = { 0, 0 };
79 time_t lasttime = 0, lastlock = 0;
80
81 for (;;) {
82 int newx, newy;
83 int reset = 0, dolock = 0;
84 time_t curtime;
85
86 /* X_VAR: hw.sensors.aps0.raw2 */
87 newx = getsensor(APS_DEV_NUM, X_VAR_TYPE, X_VAR_NUMT);
88
89 /* Y_VAR: hw.sensors.aps0.raw3 */
90 newy = getsensor(APS_DEV_NUM, Y_VAR_TYPE, Y_VAR_NUMT);
91
92 if (!newx || !newy)
93 goto wait;
94
95 if (lastvalues[0] == -1) {
96 /* initializing */
97 lastvalues[0] = curvalues[0] = newx;
98 lastvalues[1] = curvalues[1] = newy;
99
100 continue;
101 }
102
103 /* tally change amounts */
104 curchanges[0] += abs(newx - curvalues[0]);
105 curchanges[1] += abs(newy - curvalues[1]);
106
107 (void)time(&curtime);
108
109 if ((curchanges[0] > MOVE_THRESH_X) ||
110 (curchanges[1] > MOVE_THRESH_Y))
111 dolock++;
112 else if ((curtime - lasttime) >= MOVE_TIME)
113 reset++;
114
115 if (dolock || reset) {
116#ifdef DEBUG
117 printf("%d [%d], %d [%d]\n", newx, curchanges[0],
118 newy, curchanges[1]);
119#endif
120 lasttime = curtime;
121 lastvalues[0] = curvalues[0];
122 lastvalues[1] = curvalues[1];
123 curchanges[0] = curchanges[1] = 0;
124
125 if (dolock && ((curtime - lastlock) > LOCK_WAIT)) {
126 (void)spawn(lockprog);
127 (void)time(&lastlock);
128 }
129 }
130
131 curvalues[0] = newx;
132 curvalues[1] = newy;
133
134wait:
135 usleep(100);
136 }
137
138 exit(0);
139}
140
141int64_t
142getsensor(int dev, int type, int numt)
143{
144 int mib[5];
145 size_t slen;
146 struct sensor sensor;
147
148 slen = sizeof(sensor);
149
150 mib[0] = CTL_HW;
151 mib[1] = HW_SENSORS;
152 mib[2] = dev;
153 mib[3] = type;
154 mib[4] = numt;
155
156 if (sysctl(mib, 5, &sensor, &slen, NULL, 0) == -1)
157 err(1, "sysctl");
158
159 return (sensor.value);
160}
161
162void
163spawn(char *prog)
164{
165 printf("%s: executing \"%s\"\n", __progname, prog);
166
167 system(prog);
168}