]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4con/server/src/ev.c
c5ae56311e436f8e41d65e134b51ebeb90f3dc27
[l4.git] / l4 / pkg / l4con / server / src / ev.c
1 /**
2  * \file        l4con/server/src/ev.c
3  * \brief       mouse, keyboard, etc event stuff
4  *
5  * \date        2001
6  * \author      Christian Helmuth <ch12@os.inf.tu-dresden.de>
7  *              Frank Mehnert <fm3@os.inf.tu-dresden.de> */
8 /*
9  * (c) 2008-2009 Author(s)
10  *     economic rights: Technische Universität Dresden (Germany)
11  *
12  * This file is part of TUD:OS and distributed under the terms of the
13  * GNU General Public License 2.
14  * Please see the COPYING-GPL-2 file for details.
15  */
16
17 /* (c) 2003 'Technische Universitaet Dresden'
18  * This file is part of the con package, which is distributed under
19  * the terms of the GNU General Public License 2. Please see the
20  * COPYING file for details. */
21
22 #include <l4/l4con/l4con.h>
23 #include <l4/util/l4_macros.h>
24 #include <l4/input/libinput.h>
25 #include <l4/sys/kdebug.h>
26 #include <l4/sys/factory.h>
27 #include <l4/sys/icu.h>
28 #include <l4/re/env.h>
29 #include <l4/re/c/event_buffer.h>
30 #include <l4/re/c/util/cap_alloc.h>
31 #include <l4/re/c/util/video/goos_fb.h>
32
33 #include <pthread-l4.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36
37 #include "config.h"
38 #include "ev.h"
39 #include "main.h"
40 #include "vc.h"
41 #include "srv.h"
42
43 int nomouse, noshift, gen_abs_events;
44 int cur_abs_pos_x, cur_abs_pos_y;
45 static l4_cap_idx_t ev_ds, ev_irq;
46 static l4re_event_buffer_consumer_t ev_buf;
47
48 /** brief Key event handling -> distribution and switch */
49 static void
50 handle_event(struct l4input *ev)
51 {
52   static int altgr_down;
53   static int shift_down;
54   static struct l4input special_ev = { .type = 0xff };
55
56   if (ev->type == EV_KEY)
57     {
58       l4_umword_t keycode      = ev->code;
59       l4_umword_t down         = ev->value;
60       l4_umword_t special_down = 0;
61
62       if (nomouse && keycode >= BTN_MOUSE && keycode < BTN_TASK)
63         return;
64
65       if (keycode == KEY_RIGHTALT)
66         altgr_down = special_down = down;
67       else if (!noshift
68                && (keycode == KEY_LEFTSHIFT || keycode == KEY_RIGHTSHIFT))
69         shift_down = special_down = down;
70
71       if (special_down)
72         {
73           /* Defer sending of the special key until we know if we handle
74            * the next key completely in the server */
75           special_ev = *ev;
76           return;
77         }
78
79       if (down && (altgr_down || shift_down))
80         {
81           /* virtual console switching */
82           if (keycode >= KEY_F1 && keycode <= KEY_F10)
83             {
84               request_vc(keycode - KEY_F1 + 1);
85               special_ev.type = 0xff;
86               return;
87             }
88           if (keycode == KEY_LEFT)
89             {
90               request_vc_delta(-1);
91               special_ev.type = 0xff;
92               return;
93             }
94           if (keycode == KEY_RIGHT)
95             {
96               request_vc_delta(1);
97               special_ev.type = 0xff;
98               return;
99             }
100           if (keycode == KEY_F11 && altgr_down)
101             {
102               /* F11/Shift F11: increase/decrase brightness */
103               vc_brightness_contrast(shift_down ? -100 : 100, 0);
104               special_ev.type = 0xff;
105               return;
106             }
107           if (keycode == KEY_F12 && altgr_down)
108             {
109               /* F12/Shift F12: increase/decrase contrast */
110               vc_brightness_contrast(0, shift_down ? -100 : 100);
111               special_ev.type = 0xff;
112               return;
113             }
114           if (keycode == KEY_PAUSE && altgr_down)
115             {
116               cpu_load_history = 1-cpu_load_history;
117               return;
118             }
119 #ifndef L4BID_RELEASE_MODE
120           if (keycode == KEY_SYSRQ && altgr_down)
121             {
122               /* Magic SysReq -> enter_kdebug() */
123               enter_kdebug("AltGr + SysRq");
124               special_ev.type = 0xff;
125               return;
126             }
127 #endif
128         }
129
130       /* No special key, send deferred key event */
131       if (special_ev.type != 0xff)
132         {
133           send_event_client(vc[fg_vc], &special_ev);
134           special_ev.type = 0xff;
135         }
136     }
137   else if (ev->type == EV_REL || ev->type == EV_ABS)
138     {
139       /* mouse event */
140       if (nomouse)
141         return;
142
143       if (gen_abs_events && ev->type == EV_REL)
144         {
145           // for now we treat gen_abs_events to replace the relative events
146           ev->type = EV_ABS;
147           if (ev->code == 0)
148             {
149               cur_abs_pos_x += ev->value;
150               if (cur_abs_pos_x < 0)
151                 cur_abs_pos_x = 0;
152               else if ((unsigned)cur_abs_pos_x >= vc[fg_vc]->client_xres)
153                 cur_abs_pos_x = vc[fg_vc]->client_xres;
154               ev->value = cur_abs_pos_x;
155             }
156           else if (ev->code == 1)
157             {
158               cur_abs_pos_y += ev->value;
159               if (cur_abs_pos_y < 0)
160                 cur_abs_pos_y = 0;
161               else if ((unsigned)cur_abs_pos_y >= vc[fg_vc]->client_yres)
162                 cur_abs_pos_y = vc[fg_vc]->client_yres;
163               ev->value = cur_abs_pos_y;
164             }
165         }
166     }
167   else if (ev->type == EV_MSC)
168     {
169       /* ignored */
170       return;
171     }
172   else if (ev->type == EV_SYN)
173     {
174       /* Pass through */
175     }
176   else
177     {
178       printf("handle_event: Unknown event type %d\n", ev->type);
179       return;
180     }
181
182   send_event_client(vc[fg_vc], ev);
183 }
184
185 static void *ev_thread(void *d)
186 {
187   (void)d;
188   l4re_event_buffer_consumer_process(&ev_buf, ev_irq,
189                                      pthread_getl4cap(pthread_self()),
190                                      (void (*)(l4re_event_t *))handle_event);
191   return NULL;
192 }
193
194 #define Panic(a...) do { fprintf(stderr, a); exit(1); } while (0)
195
196 /** \brief event driver initialization
197  */
198 void
199 ev_init()
200 {
201   pthread_t t;
202
203   if (l4_is_invalid_cap(ev_ds = l4re_util_cap_alloc()))
204     Panic("Cap alloc failed");
205
206   if (l4_is_invalid_cap(ev_irq = l4re_util_cap_alloc()))
207     Panic("Cap alloc failed");
208
209   if (l4_error(l4_factory_create_irq(l4re_env()->factory, ev_irq)))
210     Panic("IRQ create failed");
211
212   if (l4_error(l4_icu_bind(l4re_util_video_goos_fb_goos(&goosfb), 0, ev_irq))
213       || l4re_event_get(l4re_util_video_goos_fb_goos(&goosfb), ev_ds)
214       || l4re_event_buffer_attach(&ev_buf, ev_ds, l4re_env()->rm))
215     {
216       // failed, try to start the hw driver
217       l4re_util_cap_free_um(ev_ds);
218       l4re_util_cap_free_um(ev_irq);
219
220       printf("Using l4input\n");
221       l4input_init(254, handle_event);
222       return;
223     }
224
225   printf("Using l4re-console event pass-through\n");
226
227   if (pthread_create(&t, NULL, ev_thread, NULL))
228     Panic("Thread creation failed\n");
229 }