]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/mag/include/server/input_driver
update
[l4.git] / l4 / pkg / mag / include / server / input_driver
1 // vi:ft=cpp
2 /*
3  * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
4  *          Alexander Warg <warg@os.inf.tu-dresden.de>
5  *     economic rights: Technische Universität Dresden (Germany)
6  *
7  * This file is part of TUD:OS and distributed under the terms of the
8  * GNU General Public License 2.
9  * Please see the COPYING-GPL-2 file for details.
10  */
11 #pragma once
12
13 #include <l4/mag/server/user_state>
14 #include <l4/mag/server/plugin>
15
16 #include <l4/re/event_enums.h>
17
18 namespace Mag_server {
19
20 template<int Max_axis>
21 class Motion_merger
22 {
23 private:
24   unsigned long _changed;
25   int _v[Max_axis];
26
27   enum Type
28   {
29     T_none = 0,
30     T_abs  = 1,
31     T_rel  = 2,
32   };
33
34   Type axis_inf(unsigned char axis) const
35   { return Type((_changed >> (2*axis)) & 3); }
36
37   void set_axis_inf(unsigned char axis, Type t)
38   { _changed |= ((unsigned long)t) << (axis*2); }
39
40 public:
41   Motion_merger() : _changed(0) {}
42
43   void reset() { _changed = 0; }
44
45
46
47   bool handle(User_state::Event const &e)
48   {
49     if (!(e.payload.type == L4RE_EV_REL || e.payload.type == L4RE_EV_ABS))
50       return false;
51
52     if (e.payload.code >= Max_axis)
53       return false;
54
55     unsigned char ax = e.payload.code;
56
57     if (axis_inf(ax) == T_none && e.payload.type == L4RE_EV_REL)
58       {
59         _v[ax] = 0;
60         set_axis_inf(ax, T_rel);
61       }
62
63     switch (e.payload.type)
64       {
65       case L4RE_EV_REL:
66         _v[ax] += e.payload.value;
67         break;
68       case L4RE_EV_ABS:
69         _v[ax] = e.payload.value;
70         set_axis_inf(ax, T_abs);
71         break;
72       }
73
74     return true;
75   }
76
77   bool set_event(unsigned char axis, User_state::Event *e)
78   {
79     unsigned i = axis_inf(axis);
80     if (!i)
81       return false;
82
83     if (i & T_abs)
84       e->payload.type = L4RE_EV_ABS;
85     else
86       e->payload.type = L4RE_EV_REL;
87
88     e->payload.code = axis;
89     e->payload.value = _v[axis];
90
91     return true;
92   }
93
94   template< typename I, typename T >
95   I merge(I const &s, I const &e, T *last_time)
96   {
97     for (I i = s; i != e; ++i)
98       if (handle(*i))
99         {
100           *last_time = i->time;
101           i->free();
102         }
103       else
104         return i;
105
106     return e;
107   }
108
109   template< typename E, typename I, typename F >
110   void process(I const &s, I const &end, F const &f)
111   {
112     for (I e = s; e != end; ++e)
113       {
114         E me;
115         me.payload.stream_id = e->payload.stream_id;
116         e = merge(e, end, &me.time);
117
118         for (unsigned i = 0; i < Max_axis; ++i)
119           if (set_event(i, &me))
120             f(me);
121
122         if (e != end)
123           {
124             reset();
125             f(*e);
126           }
127         else
128           break;
129         e->free();
130       }
131   }
132 };
133
134 class Motion_fwd
135 {
136 public:
137   template< /*typename E,*/ typename I, typename F >
138   void process(I const &s, I const &end, F const &f)
139   {
140     for (I e = s; e != end; ++e)
141       {
142         f(*e);
143         e->free();
144       }
145   }
146 };
147
148 class Input_driver : public Plugin
149 {
150 protected:
151   Core_api *_core;
152
153 private:
154   Input_driver *_next_active;
155
156 public:
157   explicit Input_driver(char const *name)
158   : Plugin(name), _core(0), _next_active(0)
159   {}
160
161   char const *type() const { return "input-driver"; }
162   Input_driver *next_active() const { return _next_active; }
163   virtual void poll_events() = 0;
164   virtual int probe() = 0;
165
166   void start(Core_api *core)
167   {
168     _core = core;
169     if (probe() == 0)
170       {
171         _next_active = core->input_drivers();
172         core->add_input_driver(this);
173       }
174   }
175
176   virtual ~Input_driver() {}
177 };
178
179 }