]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libsdl/lib/src/src/video/l4fb/SDL_l4fbevents.c
044694db773c501236f6866dc9c10c5274771e0a
[l4.git] / l4 / pkg / libsdl / lib / src / src / video / l4fb / SDL_l4fbevents.c
1 #include "SDL.h"
2 #include "SDL_sysevents.h"
3 #include "SDL_events_c.h"
4 #include "SDL_l4fbvideo.h"
5 #include <l4/sys/thread.h>
6 #include <l4/sys/factory.h>
7 #include <l4/sys/icu.h>
8
9 #include <l4/re/c/dataspace.h>
10 #include <l4/re/c/rm.h>
11 #include <l4/re/c/util/cap_alloc.h>
12 #include <l4/re/c/event.h>
13 #include <l4/re/c/event_buffer.h>
14 #include <l4/re/event_enums.h>
15 #include <l4/util/thread.h>
16
17 #include <pthread-l4.h>
18 #include <string.h>
19 #include <stdio.h>
20
21
22 l4_cap_idx_t pthread_getl4cap(pthread_t t);
23 static SDL_VideoDevice *dev;
24
25
26 static SDLKey keymap[L4RE_KEY_MAX];
27
28
29
30 void L4FB_PumpEvents(_THIS) {
31         (void)this;
32         INFO(LOG_Enter("");)
33         /* do nothing. */
34 }
35
36 void L4FB_InitOSKeymap(_THIS) {
37         (void)this;
38         INFO(LOG_Enter("");)
39
40         memset(keymap, 0, sizeof(keymap));
41
42         keymap[L4RE_KEY_ESC]        = SDLK_ESCAPE;
43         keymap[L4RE_KEY_ENTER]      = SDLK_RETURN;
44         keymap[L4RE_KEY_LEFTCTRL]   = SDLK_LCTRL;
45         keymap[L4RE_KEY_LEFTSHIFT]  = SDLK_LSHIFT;
46         keymap[L4RE_KEY_RIGHTSHIFT] = SDLK_RSHIFT;
47         keymap[L4RE_KEY_LEFTALT]    = SDLK_RALT;
48         keymap[L4RE_KEY_CAPSLOCK]   = SDLK_CAPSLOCK;
49         keymap[L4RE_KEY_Q] = SDLK_q;
50         keymap[L4RE_KEY_W] = SDLK_w;
51         keymap[L4RE_KEY_E] = SDLK_e;
52         keymap[L4RE_KEY_R] = SDLK_r;
53         keymap[L4RE_KEY_T] = SDLK_t;
54         keymap[L4RE_KEY_Y] = SDLK_y;
55         keymap[L4RE_KEY_U] = SDLK_u;
56         keymap[L4RE_KEY_I] = SDLK_i;
57         keymap[L4RE_KEY_O] = SDLK_o;
58         keymap[L4RE_KEY_P] = SDLK_p;
59         keymap[L4RE_KEY_A] = SDLK_a;
60         keymap[L4RE_KEY_S] = SDLK_s;
61         keymap[L4RE_KEY_D] = SDLK_d;
62         keymap[L4RE_KEY_F] = SDLK_f;
63         keymap[L4RE_KEY_G] = SDLK_g;
64         keymap[L4RE_KEY_H] = SDLK_h;
65         keymap[L4RE_KEY_J] = SDLK_j;
66         keymap[L4RE_KEY_K] = SDLK_k;
67         keymap[L4RE_KEY_L] = SDLK_l;
68         keymap[L4RE_KEY_Z] = SDLK_z;
69         keymap[L4RE_KEY_X] = SDLK_x;
70         keymap[L4RE_KEY_C] = SDLK_c;
71         keymap[L4RE_KEY_V] = SDLK_v;
72         keymap[L4RE_KEY_B] = SDLK_b;
73         keymap[L4RE_KEY_N] = SDLK_n;
74         keymap[L4RE_KEY_M] = SDLK_m;
75         keymap[L4RE_KEY_F1]  = SDLK_F1;
76         keymap[L4RE_KEY_F2]  = SDLK_F2;
77         keymap[L4RE_KEY_F3]  = SDLK_F3;
78         keymap[L4RE_KEY_F4]  = SDLK_F4;
79         keymap[L4RE_KEY_F5]  = SDLK_F5;
80         keymap[L4RE_KEY_F6]  = SDLK_F6;
81         keymap[L4RE_KEY_F7]  = SDLK_F7;
82         keymap[L4RE_KEY_F8]  = SDLK_F8;
83         keymap[L4RE_KEY_F9]  = SDLK_F9;
84         keymap[L4RE_KEY_F10] = SDLK_F10;
85         keymap[L4RE_KEY_F11] = SDLK_F11;
86         keymap[L4RE_KEY_F12] = SDLK_F12;
87         keymap[L4RE_KEY_NUMLOCK]    = SDLK_NUMLOCK;
88         keymap[L4RE_KEY_SCROLLLOCK] = SDLK_SCROLLOCK;
89         keymap[L4RE_KEY_KP0] = SDLK_KP0;
90         keymap[L4RE_KEY_KP1] = SDLK_KP1;
91         keymap[L4RE_KEY_KP2] = SDLK_KP2;
92         keymap[L4RE_KEY_KP3] = SDLK_KP3;
93         keymap[L4RE_KEY_KP4] = SDLK_KP4;
94         keymap[L4RE_KEY_KP5] = SDLK_KP5;
95         keymap[L4RE_KEY_KP6] = SDLK_KP6;
96         keymap[L4RE_KEY_KP7] = SDLK_KP7;
97         keymap[L4RE_KEY_KP8] = SDLK_KP8;
98         keymap[L4RE_KEY_KP9] = SDLK_KP9;
99         keymap[L4RE_KEY_KPMINUS]   = SDLK_KP_MINUS;
100         keymap[L4RE_KEY_KPPLUS]    = SDLK_KP_PLUS;
101         keymap[L4RE_KEY_KPDOT]     = SDLK_KP_PERIOD;
102         keymap[L4RE_KEY_KPENTER]   = SDLK_KP_ENTER;
103         keymap[L4RE_KEY_RIGHTCTRL] = SDLK_RCTRL;
104         keymap[L4RE_KEY_KPSLASH]   = SDLK_KP_DIVIDE;
105         keymap[L4RE_KEY_RIGHTALT]  = SDLK_RALT;
106         keymap[L4RE_KEY_HOME]      = SDLK_HOME;
107         keymap[L4RE_KEY_UP]        = SDLK_UP;
108         keymap[L4RE_KEY_PAGEUP]    = SDLK_PAGEDOWN;
109         keymap[L4RE_KEY_LEFT]      = SDLK_LEFT;
110         keymap[L4RE_KEY_RIGHT]     = SDLK_RIGHT;
111         keymap[L4RE_KEY_END]       = SDLK_END;
112         keymap[L4RE_KEY_DOWN]      = SDLK_DOWN;
113         keymap[L4RE_KEY_PAGEDOWN]  = SDLK_PAGEUP;
114         keymap[L4RE_KEY_INSERT]    = SDLK_INSERT;
115         keymap[L4RE_KEY_DELETE]    = SDLK_DELETE;
116         keymap[L4RE_KEY_PAUSE]     = SDLK_PAUSE;
117         keymap[L4RE_KEY_LEFTMETA]  = SDLK_LSUPER;
118         keymap[L4RE_KEY_RIGHTMETA] = SDLK_RSUPER;
119         keymap[L4RE_KEY_RIGHTALT]  = SDLK_MODE;
120         keymap[L4RE_KEY_SPACE]     = SDLK_SPACE;
121 }
122
123
124
125 static void event_callback(l4re_event_t *e) {
126         long code;
127         Uint8 state;
128         SDL_keysym key;
129         memset(&key, 0, sizeof(key));
130         switch (e->type) {
131                 case L4RE_EV_KEY:
132                         /* pressed or released? */
133                         state = e->value ? SDL_PRESSED : SDL_RELEASED;
134                         code = e->code;
135                         // set hardware code
136                         key.scancode = e->code;
137
138                         // look into keymap
139                         if (code>0 && code < L4RE_KEY_MAX)
140                                 key.sym = keymap[code];
141                         // or try to decode ascii
142 #if 0                   
143                         if (!key.sym) {
144                                 if (this->hidden->have_app) {
145                                         key.sym = dope_get_ascii(this->hidden->app_id, code);
146                                         key.unicode = key.sym;
147                                 }
148                         }
149 #endif
150
151                         // catch some cases by hand
152                         if (!key.sym) {
153                                 switch (code) {
154                                         case L4RE_BTN_LEFT:
155                                         case L4RE_BTN_RIGHT:
156                                         case L4RE_BTN_MIDDLE:
157                                         case L4RE_BTN_SIDE:
158                                         case L4RE_BTN_EXTRA:
159                                         case L4RE_BTN_FORWARD:
160                                         case L4RE_BTN_BACK:
161                                                 SDL_PrivateMouseButton(state, code-L4RE_BTN_MOUSE+1, 0, 0);
162                                                 break;
163                                         default:
164                                                 printf("unknown keycode: %li\n", code);
165                                 }
166                         }
167                         if (key.sym)
168                                 SDL_PrivateKeyboard(state, &key);
169                         break;
170                 case L4RE_EV_ABS:
171                         {
172                                 /* because we only get x OR y pos we have to remember the last
173                                  * y OR x value ... */
174                                 static Sint16 my_x, my_y;
175                                 
176                                 switch (e->code) {
177
178                                         case L4RE_ABS_X: 
179                                         {
180                                                 my_x = e->value - dev->hidden->x_offset;
181                                                 break;
182                                         }
183                                         case L4RE_ABS_Y:
184                                         {
185                                                 my_y = e->value- dev->hidden->y_offset;
186                                                 break;
187                                         }
188
189                                 }
190                                 
191                                 SDL_PrivateMouseMotion(0, 0, my_x, my_y);
192                         }
193                         break;
194                 case L4RE_EV_REL:
195                         {
196
197                                 switch (e->code)
198                                         {
199                                                 case L4RE_REL_X: 
200                                                         SDL_PrivateMouseMotion(0, 1, e->value, 0);
201                                                         break;
202                                                 case L4RE_REL_Y:
203                                                         SDL_PrivateMouseMotion(0, 1, 0, e->value);
204                                         }
205                                 break;
206                         }
207
208
209 //              case L4RE_EVENT_TYPE_COMMAND:
210 // broken: content of e->command.cmd is undefined
211 // but there was no useful code here anyway
212 //                      INFO(LOG("(\"%s\") L4RE_EVENT_TYPE_COMMAND: 0x%lx \"%s\"", cd->obj, e->command.cmd, e->command.cmd);)
213 //                      if (strcmp(e->command.cmd, "catch")==0) {
214 //                              // we gained control over the mouse :)
215 //                      } else if (strcmp(e->command.cmd, "discharge")==0) {
216 //                              // we have lost mouse control :(
217 //                      } else if (strcmp(e->command.cmd, "enter")==0) {
218 //                              // mouse is over vscreen
219 //                      } else if (strcmp(e->command.cmd, "leave")==0) {
220 //                              // mouse left vscreen
221 //                      } else {
222 //                              LOG("(\"%s\") unknown command \"%s\"", cd->obj, e->command.cmd);
223 //                      }
224 //                      break;
225                 default:
226                         printf("unknown event type %x\n", e->type);
227         }
228 }
229
230
231 static pthread_mutex_t ev_init_wait = PTHREAD_MUTEX_INITIALIZER;
232
233 static void * ev_loop(void * data)
234 {
235         SDL_VideoDevice * d = (SDL_VideoDevice *) data;
236
237         printf("Input handler thread started\n");
238
239         pthread_mutex_lock(&ev_init_wait);
240         pthread_mutex_unlock(&ev_init_wait);
241
242         l4re_event_buffer_consumer_process(&d->hidden->ev_buf,
243                                            d->hidden->ev_irq,
244                                            pthread_getl4cap(d->hidden->ev_thread),
245                                            event_callback);
246         printf("Input handler terminates\n");
247         return 0;
248 }
249
250
251
252
253 void L4FB_InstallEventHandler(_THIS)
254 {
255   INFO(LOG_Enter("");)
256   int ret;
257
258   L4FB_InitOSKeymap(this);
259
260   if (l4_is_invalid_cap(this->hidden->ev_ds = l4re_util_cap_alloc()))
261     {
262       /* TODO: handle ERROR */
263       printf("ERROR: ev_ds cap_alloc\n");
264       return;
265     }
266
267
268   if (l4_is_invalid_cap(this->hidden->ev_irq = l4re_util_cap_alloc()))
269     {
270       /* TODO: handle ERROR */
271       printf("ERROR: ev_irq cap_alloc\n");
272       return;
273     }
274
275   if ((ret = l4_error(l4_factory_create_irq(l4re_env()->factory, this->hidden->ev_irq))))
276     {
277       /* TODO: handle ERROR */
278       printf("ERROR: Creating irq: %d \n", ret);
279       return;
280     }
281   if ((ret = l4_error(l4_icu_bind(l4re_util_video_goos_fb_goos(&this->hidden->goosfb),
282             0, this->hidden->ev_irq))))
283     {
284       /* TODO: handle ERROR */
285       printf("ERROR: Creating irq: %d \n", ret);
286       return;
287     }
288   if ((ret = l4re_event_get(l4re_util_video_goos_fb_goos(&this->hidden->goosfb),
289           this->hidden->ev_ds)))
290     {
291       /* TODO: handle ERROR */
292       printf("ERROR: l4re_event_get: %d \n", ret);
293       return;
294     }
295
296   if (l4re_event_buffer_attach(&this->hidden->ev_buf, this->hidden->ev_ds, l4re_env()->rm))
297     {
298       /* TODO: handle ERROR */
299       printf("ERROR: l4re_buffer_attach \n");
300       return;
301     }
302
303
304   dev = this;
305   /* ev_loop needs to wait until pthread_create returns so that
306    * this->hidden->ev_thread is set, as it uses it */
307   pthread_mutex_lock(&ev_init_wait);
308   if (pthread_create(&this->hidden->ev_thread, NULL, ev_loop, (void*)this))
309     /* TODO: handle ERROR */
310     printf("ERROR: ev_thread create \n");
311   pthread_mutex_unlock(&ev_init_wait);
312 }
313
314 void L4FB_RemoveEventHandler(_THIS) {
315         (void)this;
316
317         /* TODO: Stop event thread */
318 }
319