comparison input/input.c @ 4418:8141d2c399e4

A new configurable input system and joystick support for this system
author albeu
date Wed, 30 Jan 2002 12:46:03 +0000
parents
children 5105f5da01d6
comparison
equal deleted inserted replaced
4417:4f507d28716d 4418:8141d2c399e4
1 #include "../config.h"
2
3 #ifdef HAVE_NEW_INPUT
4
5 #include <stdlib.h>
6 #include <string.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <errno.h>
10 #include <signal.h>
11 #include <sys/types.h>
12 #include <fcntl.h>
13
14
15
16 #include "input.h"
17 #ifdef MP_DEBUG
18 #include <assert.h>
19 #endif
20 #include "../linux/getch2.h"
21 #include "../linux/keycodes.h"
22 #include "../linux/timer.h"
23
24 #ifdef HAVE_JOYSTICK
25 #include "joystick.h"
26 #endif
27
28 // If the args field is not NULL, the command will only be passed if
29 // an argument exist.
30
31 static mp_cmd_t mp_cmds[] = {
32 { MP_CMD_SEEK, "seek", 1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
33 { MP_CMD_AUDIO_DELAY, "audio_delay", 1, { {MP_CMD_ARG_FLOAT,{0}}, {-1,{0}} } },
34 { MP_CMD_QUIT, "quit", 0, { {-1,{0}} } },
35 { MP_CMD_PAUSE, "pause", 0, { {-1,{0}} } },
36 { MP_CMD_GRAB_FRAMES, "grap_frames",0, { {-1,{0}} } },
37 { MP_CMD_PLAY_TREE_STEP, "pt_step",1, { { MP_CMD_ARG_INT ,{0}}, {-1,{0}} } },
38 { MP_CMD_PLAY_TREE_UP_STEP, "pt_up_step",1, { { MP_CMD_ARG_INT,{0} }, {-1,{0}} } },
39 { MP_CMD_PLAY_ALT_SRC_STEP, "alt_src_step",1, { { MP_CMD_ARG_INT,{0} }, {-1,{0}} } },
40 { MP_CMD_SUB_DELAY, "sub_delay",1, { {MP_CMD_ARG_FLOAT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
41 { MP_CMD_OSD, "osd",0, { {MP_CMD_ARG_INT,{-1}}, {-1,{0}} } },
42 { MP_CMD_VOLUME, "volume", 1, { { MP_CMD_ARG_INT,{0} }, {-1,{0}} } },
43 { MP_CMD_MIXER_USEMASTER, "use_master", 0, { {-1,{0}} } },
44 { MP_CMD_CONTRAST, "contrast",1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
45 { MP_CMD_BRIGHTNESS, "brightness",1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
46 { MP_CMD_HUE, "hue",1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
47 { MP_CMD_SATURATION, "saturation",1, { {MP_CMD_ARG_INT,{0}}, {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
48 { MP_CMD_FRAMEDROPPING, "frame_drop",0, { { MP_CMD_ARG_INT,{-1} }, {-1,{0}} } },
49 #ifdef USE_TV
50 { MP_CMD_TV_STEP_CHANNEL, "tv_step_channel", 1, { { MP_CMD_ARG_INT ,{0}}, {-1,{0}} }},
51 { MP_CMD_TV_STEP_NORM, "tv_step_norm",0, { {-1,{0}} } },
52 { MP_CMD_TV_STEP_CHANNEL_LIST, "tv_step_chanlist", 0, { {-1,{0}} } },
53 #endif
54 { 0, NULL, 0, {} }
55 };
56
57 static mp_cmd_bind_t key_names[] = {
58 { ' ', "SPACE" },
59 { KEY_ENTER, "ENTER" },
60 { KEY_TAB, "TAB" },
61 { KEY_CTRL, "CTRL" },
62 { KEY_BACKSPACE, "BS" },
63 { KEY_DELETE, "DEL" },
64 { KEY_INSERT, "INS" },
65 { KEY_HOME, "HOME" },
66 { KEY_END, "END" },
67 { KEY_PAGE_UP, "PGUP" },
68 { KEY_PAGE_DOWN, "PGDWN" },
69 { KEY_ESC, "ESC" },
70 { KEY_RIGHT, "RIGHT" },
71 { KEY_LEFT, "LEFT" },
72 { KEY_DOWN, "DOWN" },
73 { KEY_UP, "UP" },
74 #ifdef HAVE_JOYSTICK
75 { JOY_UP, "JOY_UP" },
76 { JOY_DOWN, "JOY_DOWN" },
77 { JOY_LEFT, "JOY_LEFT" },
78 { JOY_RIGHT, "JOY_RIGHT" },
79 { JOY_BTN0, "JOY_BTN0" },
80 { JOY_BTN1, "JOY_BTN1" },
81 { JOY_BTN2, "JOY_BTN2" },
82 { JOY_BTN3, "JOY_BTN3" },
83 { JOY_BTN4, "JOY_BTN4" },
84 { JOY_BTN5, "JOY_BTN5" },
85 { JOY_BTN6, "JOY_BTN6" },
86 { JOY_BTN7, "JOY_BTN7" },
87 { JOY_BTN8, "JOY_BTN8" },
88 { JOY_BTN9, "JOY_BTN9" },
89 #endif
90 { 0, NULL }
91 };
92
93 // This is the default binding we use when no config file is here
94
95 static mp_cmd_bind_t def_cmd_binds[] = {
96 { KEY_RIGHT, "seek 10" },
97 { KEY_LEFT, "seek -10" },
98 { KEY_UP, "seek 60" },
99 { KEY_DOWN, "seek -60" },
100 { KEY_PAGE_UP, "seek 600" },
101 { KEY_PAGE_DOWN, "seek -600" },
102 { '+', "audio_delay 0.100" },
103 { '-', "audio_delay -0.100" },
104 { 'q', "quit" },
105 { KEY_ESC, "quit" },
106 { 'p', "pause" },
107 { ' ', "pause" },
108 { KEY_HOME, "pt_up_step 1" },
109 { KEY_END, "pt_up_step -1" },
110 { '>', "pt_step 1" },
111 { '<', "pt_step -1" },
112 { KEY_INS, "alt_src_step 1" },
113 { KEY_DEL, "alt_src_step -1" },
114 { 'o', "osd" },
115 { 'z', "sub_delay -0.1" },
116 { 'x', "sub_delay +0.1" },
117 { '9', "volume -1" },
118 { '/', "volume -1" },
119 { '0', "volume 1" },
120 { '*', "volume 1" },
121 { 'm', "use_master" },
122 { '1', "contrast -1" },
123 { '2', "contrast 1" },
124 { '3', "brightness -1" },
125 { '4', "brightness 1" },
126 { '5', "hue -1" },
127 { '6', "hue 1" },
128 { '7', "saturation -1" },
129 { '8', "saturation 1" },
130 { 'd', "frame_drop" },
131 #ifdef USE_TV
132 { 'h', "tv_step_channel 1" },
133 { 'l', "tv_step_channel -1" },
134 { 'n', "tv_step_norm" },
135 { 'b', "tv_step_chanlist" },
136 #endif
137 { 0, NULL }
138 };
139
140 #ifndef MP_MAX_KEY_FD
141 #define MP_MAX_KEY_FD 10
142 #endif
143
144 #ifndef MP_MAX_CMD_FD
145 #define MP_MAX_CMD_FD 10
146 #endif
147
148 #define MP_FD_EOF (1<<0)
149 #define MP_FD_DROP (1<<1)
150 #define MP_FD_DEAD (1<<2)
151 #define MP_FD_GOT_CMD (1<<3)
152 #define MP_FD_NO_SELECT (1<<4)
153
154 typedef struct mp_input_fd {
155 int fd;
156 void* read_func;
157 mp_close_func_t close_func;
158 int flags;
159 // This fields are for the cmd fds
160 char* buffer;
161 int pos,size;
162 } mp_input_fd_t;
163
164
165 static mp_cmd_bind_t* cmd_binds = def_cmd_binds;
166
167 static mp_input_fd_t key_fds[MP_MAX_KEY_FD];
168 static unsigned int num_key_fd = 0;
169 static mp_input_fd_t cmd_fds[MP_MAX_CMD_FD];
170 static unsigned int num_cmd_fd = 0;
171
172 static int key_max_fd = -1, cmd_max_fd = -1;
173
174 static int
175 mp_input_default_key_func(int fd);
176
177
178 int
179 mp_input_add_cmd_fd(int fd, int select, mp_cmd_func_t read_func, mp_close_func_t close_func) {
180 if(num_cmd_fd == MP_MAX_CMD_FD) {
181 printf("Too much command fd, unable to register fd %d\n",fd);
182 return 0;
183 }
184
185 memset(&cmd_fds[num_cmd_fd],0,sizeof(mp_input_fd_t));
186 cmd_fds[num_cmd_fd].fd = fd;
187 cmd_fds[num_cmd_fd].read_func = read_func ? read_func : (mp_cmd_func_t)read;
188 cmd_fds[num_cmd_fd].close_func = close_func;
189 if(!select)
190 cmd_fds[num_cmd_fd].flags = MP_FD_NO_SELECT;
191 num_cmd_fd++;
192 if(fd > cmd_max_fd)
193 cmd_max_fd = fd;
194
195 return 1;
196 }
197
198 void
199 mp_input_rm_cmd_fd(int fd) {
200 unsigned int i;
201
202 for(i = 0; i < num_cmd_fd; i++) {
203 if(cmd_fds[i].fd == fd)
204 break;
205 }
206 if(i == num_cmd_fd)
207 return;
208 if(cmd_fds[i].close_func)
209 cmd_fds[i].close_func(cmd_fds[i].fd);
210
211 if(i + 1 < num_cmd_fd)
212 memmove(&cmd_fds[i],&cmd_fds[i+1],(num_cmd_fd - i - 1)*sizeof(mp_input_fd_t));
213 num_cmd_fd--;
214 }
215
216 void
217 mp_input_rm_key_fd(int fd) {
218 unsigned int i;
219
220 for(i = 0; i < num_key_fd; i++) {
221 if(key_fds[i].fd == fd)
222 break;
223 }
224 if(i == num_key_fd)
225 return;
226 if(key_fds[i].close_func)
227 key_fds[i].close_func(key_fds[i].fd);
228
229 if(i + 1 < num_key_fd)
230 memmove(&key_fds[i],&key_fds[i+1],(num_key_fd - i - 1)*sizeof(mp_input_fd_t));
231 num_key_fd--;
232 }
233
234 int
235 mp_input_add_key_fd(int fd, int select, mp_key_func_t read_func, mp_close_func_t close_func) {
236 if(num_key_fd == MP_MAX_KEY_FD) {
237 printf("Too much key fd, unable to register fd %d\n",fd);
238 return 0;
239 }
240
241 memset(&key_fds[num_key_fd],0,sizeof(mp_input_fd_t));
242 key_fds[num_key_fd].fd = fd;
243 key_fds[num_key_fd].read_func = read_func ? read_func : mp_input_default_key_func;
244 key_fds[num_key_fd].close_func = close_func;
245 if(!select)
246 key_fds[num_key_fd].flags |= MP_FD_NO_SELECT;
247 num_key_fd++;
248 if(fd > key_max_fd)
249 key_max_fd = fd;
250
251 return 1;
252 }
253
254
255
256 static mp_cmd_t*
257 mp_input_parse_cmd(char* str) {
258 int i,l;
259 char *ptr,*e;
260 mp_cmd_t *cmd, *cmd_def;
261
262 #ifdef MP_DEBUG
263 assert(str != NULL);
264 #endif
265
266 ptr = strchr(str,' ');
267 if(ptr)
268 l = ptr-str;
269 else
270 l = strlen(str);
271
272 if(l == 0)
273 return NULL;
274
275 for(i=0; mp_cmds[i].name != NULL; i++) {
276 if(strncasecmp(mp_cmds[i].name,str,l) == 0)
277 break;
278 }
279
280 if(mp_cmds[i].name == NULL)
281 return NULL;
282
283 cmd_def = &mp_cmds[i];
284
285 cmd = (mp_cmd_t*)malloc(sizeof(mp_cmd_t));
286 cmd->id = cmd_def->id;
287 cmd->name = strdup(cmd_def->name);
288
289 ptr = str;
290
291 for(i=0; ptr && i < MP_CMD_MAX_ARGS; i++) {
292 ptr = strchr(ptr,' ');
293 if(!ptr) break;
294 while(ptr[0] == ' ') ptr++;
295 if(ptr[0] == '\0') break;
296 switch(cmd_def->args[i].type) {
297 case MP_CMD_ARG_INT:
298 errno = 0;
299 cmd->args[i].v.i = atoi(ptr);
300 if(errno != 0) {
301 printf("Command %s : argument %d isn't an integer\n",cmd_def->name,i+1);
302 ptr = NULL;
303 }
304 break;
305 case MP_CMD_ARG_FLOAT:
306 errno = 0;
307 cmd->args[i].v.f = atof(ptr);
308 if(errno != 0) {
309 printf("Command %s : argument %d isn't a float\n",cmd_def->name,i+1);
310 ptr = NULL;
311 }
312 break;
313 case MP_CMD_ARG_STRING:
314 e = strchr(ptr,' ');
315 if(!e) e = ptr+strlen(ptr);
316 l = e-ptr;
317 cmd->args[i].v.s = (char*)malloc((l+1)*sizeof(char));
318 strncpy(cmd->args[i].v.s,ptr,l);
319 cmd->args[i].v.s[l] = '\0';
320 break;
321 case -1:
322 ptr = NULL;
323 default :
324 printf("Unknow argument %d\n",i);
325 }
326 }
327 cmd->nargs = i;
328
329 if(cmd_def->nargs > cmd->nargs) {
330 printf("Got [%s] but\n",str);
331 printf("Command %s require at least %d arguments, we found only %d so far\n",cmd_def->name,cmd_def->nargs,cmd->nargs);
332 mp_cmd_free(cmd);
333 return NULL;
334 }
335
336 for( ; i < MP_CMD_MAX_ARGS && cmd_def->args[i].type != -1 ; i++)
337 memcpy(&cmd->args[i].v,&cmd_def->args[i].v,sizeof(mp_cmd_arg_value_t));
338
339 return cmd;
340 }
341
342 static int
343 mp_input_default_key_func(int fd) {
344 int r,code=0;
345 unsigned int l;
346 l = 0;
347 while(l < sizeof(int)) {
348 r = read(fd,(&code)+l,sizeof(int)-l);
349 if(r <= 0)
350 break;
351 l +=r;
352 }
353 return code;
354 }
355
356 #define MP_CMD_MAX_SIZE 256
357
358 static int
359 mp_input_read_cmd(mp_input_fd_t* mp_fd, char** ret) {
360 char* end;
361 (*ret) = NULL;
362
363 if(!mp_fd->buffer) {
364 mp_fd->buffer = (char*)malloc(MP_CMD_MAX_SIZE*sizeof(char));
365 mp_fd->pos = 0;
366 mp_fd->size = MP_CMD_MAX_SIZE;
367 }
368
369 if(mp_fd->size - mp_fd->pos == 0) {
370 printf("Cmd buffer of fd %d is full : dropping content\n",mp_fd->fd);
371 mp_fd->pos = 0;
372 mp_fd->flags |= MP_FD_DROP;
373 }
374
375 while( !(mp_fd->flags & MP_FD_EOF) && (mp_fd->size - mp_fd->pos > 1) ) {
376 int r = ((mp_cmd_func_t)mp_fd->read_func)(mp_fd->fd,mp_fd->buffer+mp_fd->pos,mp_fd->size - 1 - mp_fd->pos);
377 if(r < 0) {
378 if(errno == EINTR)
379 continue;
380 else if(errno == EAGAIN)
381 break;
382 printf("Error while reading cmd fd %d : %s\n",mp_fd->fd,strerror(errno));
383 return MP_INPUT_ERROR;
384 } else if(r == 0) {
385 mp_fd->flags |= MP_FD_EOF;
386 break;
387 }
388 mp_fd->pos += r;
389 break;
390 }
391
392
393 while(1) {
394 int l = 0;
395 mp_fd->buffer[mp_fd->pos] = '\0';
396 end = strchr(mp_fd->buffer,'\n');
397 if(!end)
398 break;
399 else if((*ret)) {
400 mp_fd->flags |= MP_FD_GOT_CMD;
401 break;
402 }
403
404 l = end - mp_fd->buffer;
405
406 if( ! (mp_fd->flags & MP_FD_DROP)) {
407 (*ret) = (char*)malloc((l+1)*sizeof(char));
408 strncpy((*ret),mp_fd->buffer,l);
409 (*ret)[l] = '\0';
410 } else {
411 mp_fd->flags &= ~MP_FD_DROP;
412 }
413 if( mp_fd->pos - (l+1) > 0)
414 memmove(mp_fd->buffer,end,mp_fd->pos-(l+1));
415 mp_fd->pos -= l+1;
416 }
417
418 if(*ret)
419 return 1;
420 else
421 return MP_INPUT_NOTHING;
422 }
423
424 static mp_cmd_t*
425 mp_input_read_keys(int time,int paused) {
426 fd_set fds;
427 struct timeval tv;
428 int i,n=0;
429 static int last_loop = 0;
430
431 if(num_key_fd == 0)
432 return NULL;
433
434 FD_ZERO(&fds);
435 for(i = 0; (unsigned int)i < num_key_fd; i++) {
436 if( (key_fds[i].flags & MP_FD_DEAD) ) {
437 mp_input_rm_key_fd(key_fds[i].fd);
438 i--;
439 continue;
440 } else if(key_fds[i].flags & MP_FD_NO_SELECT)
441 continue;
442
443 FD_SET(key_fds[i].fd,&fds);
444 n++;
445 }
446
447 if(n > 0 ) {
448
449 tv.tv_sec=time/1000;
450 tv.tv_usec = (time%1000)*1000;
451
452 while(1) {
453 if(select(key_max_fd+1,&fds,NULL,NULL,&tv) < 0) {
454 if(errno == EINTR)
455 continue;
456 printf("Select error : %s\n",strerror(errno));
457 }
458 break;
459 }
460 } else {
461 FD_ZERO(&fds);
462 }
463
464 for(i = last_loop + 1 ; i != last_loop ; i++) {
465 int code = -1,j;
466
467 if((unsigned int)i >= num_key_fd) {
468 i = -1;
469 last_loop++;
470 continue;
471 }
472 if(! (key_fds[i].flags & MP_FD_NO_SELECT) && ! FD_ISSET(key_fds[i].fd,&fds))
473 continue;
474 if(key_fds[i].fd == 0) { // stdin is handled by getch2
475 code = getch2(time);
476 if(code < 0)
477 code = MP_INPUT_NOTHING;
478 }
479 else
480 code = ((mp_key_func_t)key_fds[i].read_func)(key_fds[i].fd);
481
482 if(code < 0) {
483 if(code == MP_INPUT_ERROR)
484 printf("Error on key input fd %d\n",key_fds[i].fd);
485 else if(code == MP_INPUT_DEAD) {
486 printf("Dead key input on fd %d\n",key_fds[i].fd);
487 key_fds[i].flags |= MP_FD_DEAD;
488 }
489 continue;
490 }
491 if(paused)
492 return mp_input_parse_cmd("pause");
493 for(j = 0; cmd_binds[j].cmd != NULL; j++) {
494 if(cmd_binds[j].input == code)
495 break;
496 }
497 if(cmd_binds[j].cmd == NULL)
498 continue;
499 last_loop = i;
500 return mp_input_parse_cmd(cmd_binds[j].cmd);
501 }
502
503 last_loop = 0;
504 return NULL;
505 }
506
507 static mp_cmd_t*
508 mp_input_read_cmds(int time) {
509 fd_set fds;
510 struct timeval tv;
511 int i,n = 0;
512 mp_cmd_t* ret;
513 static int last_loop = 0;
514
515 if(num_cmd_fd == 0)
516 return NULL;
517
518 FD_ZERO(&fds);
519 for(i = 0; (unsigned int)i < num_cmd_fd ; i++) {
520 if( (cmd_fds[i].flags & MP_FD_DEAD) || (cmd_fds[i].flags & MP_FD_EOF) ) {
521 mp_input_rm_cmd_fd(cmd_fds[i].fd);
522 i--;
523 continue;
524 } else if(cmd_fds[i].flags & MP_FD_NO_SELECT)
525 continue;
526 FD_SET(cmd_fds[i].fd,&fds);
527 n++;
528 }
529
530 if(n > 0) {
531
532 tv.tv_sec=time/1000;
533 tv.tv_usec = (time%1000)*1000;
534
535 while(1) {
536 if((i = select(cmd_max_fd+1,&fds,NULL,NULL,&tv)) <= 0) {
537 if(i < 0) {
538 if(errno == EINTR)
539 continue;
540 printf("Select error : %s\n",strerror(errno));
541 }
542 return NULL;
543 }
544 break;
545 }
546 } else {
547 FD_ZERO(&fds);
548 }
549
550 for(i = last_loop + 1; i != last_loop ; i++) {
551 int r = 0;
552 char* cmd;
553 if((unsigned int)i >= num_cmd_fd) {
554 i = -1;
555 last_loop++;
556 continue;
557 }
558 if( ! (cmd_fds[i].flags & MP_FD_NO_SELECT) && ! FD_ISSET(cmd_fds[i].fd,&fds) && ! (cmd_fds[i].flags & MP_FD_GOT_CMD) )
559 continue;
560
561 r = mp_input_read_cmd(&cmd_fds[i],&cmd);
562 if(r < 0) {
563 if(r == MP_INPUT_ERROR)
564 printf("Error on cmd fd %d\n",cmd_fds[i].fd);
565 else if(r == MP_INPUT_DEAD)
566 cmd_fds[i].flags |= MP_FD_DEAD;
567 continue;
568 }
569 ret = mp_input_parse_cmd(cmd);
570 free(cmd);
571 if(!ret)
572 continue;
573 last_loop = i;
574 return ret;
575 }
576
577 last_loop = 0;
578 return NULL;
579 }
580
581 mp_cmd_t*
582 mp_input_get_cmd(int time, int paused) {
583 mp_cmd_t* ret;
584
585 ret = mp_input_read_keys(time,paused);
586 if(ret)
587 return ret;
588
589 return mp_input_read_cmds(time);
590 }
591
592 void
593 mp_cmd_free(mp_cmd_t* cmd) {
594 int i;
595 #ifdef MP_DEBUG
596 assert(cmd != NULL);
597 #endif
598
599 if(cmd->name)
600 free(cmd->name);
601
602 for(i=0; i < MP_CMD_MAX_ARGS && cmd->args[i].type != -1; i++) {
603 if(cmd->args[i].type == MP_CMD_ARG_STRING)
604 free(cmd->args[i].v.s);
605 }
606 free(cmd);
607 }
608
609 static int
610 mp_input_get_key_from_name(char* name) {
611 int i,ret = 0;
612
613 if(strlen(name) == 1) { // Direct key code
614 (char)ret = name[0];
615 return ret;
616 }
617
618 for(i = 0; key_names[i].cmd != NULL; i++) {
619 if(strcasecmp(key_names[i].cmd,name) == 0)
620 return key_names[i].input;
621 }
622
623 return -1;
624 }
625
626 static void
627 mp_input_free_binds(mp_cmd_bind_t* binds) {
628 int i;
629
630 if(!binds)
631 return;
632
633 for(i = 0; binds[i].cmd != NULL; i++)
634 free(binds[i].cmd);
635
636 free(binds);
637
638 }
639
640
641 #define BS_MAX 256
642 #define SPACE_CHAR " \n\r\t"
643
644 static void
645 mp_input_parse_config(char *file) {
646 int fd,code=-1;
647 int bs = 0,r,eof = 0;
648 char *iter,*end;
649 char buffer[BS_MAX];
650 int n_binds = 0;
651 mp_cmd_bind_t* binds = NULL;
652
653 fd = open(file,O_RDONLY);
654
655 if(fd < 0) {
656 printf("Can't open input config file %s : %s\n",file,strerror(errno));
657 return;
658 }
659
660 printf("Parsing input config file %s\n",file);
661
662 while(1) {
663 if(! eof && bs < BS_MAX-1) {
664 if(bs > 0) bs--;
665 r = read(fd,buffer+bs,BS_MAX-1-bs);
666 if(r < 0) {
667 if(errno == EINTR)
668 continue;
669 printf("Error while reading input config file %s : %s\n",file,strerror(errno));
670 mp_input_free_binds(binds);
671 return;
672 } else if(r == 0)
673 eof = 1;
674 else {
675 bs += r+1;
676 buffer[bs-1] = '\0';
677 }
678 }
679 // Empty buffer : return
680 if(bs <= 1) {
681 printf("Input config file %s parsed : %d binds\n",file,n_binds);
682 if(binds)
683 cmd_binds = binds;
684 return;
685 }
686
687 iter = buffer;
688
689 // Find the wanted key
690 if(code < 0) {
691 // Jump beginnig space
692 for( ; iter[0] != '\0' && strchr(SPACE_CHAR,iter[0]) != NULL ; iter++)
693 /* NOTHING */;
694 if(iter[0] == '\0') { // Buffer was full of space char
695 bs = 0;
696 continue;
697 }
698 // Find the end of the key code name
699 for(end = iter; end[0] != '\0' && strchr(SPACE_CHAR,end[0]) == NULL ; end++)
700 /*NOTHING */;
701 if(end[0] == '\0') { // Key name don't fit in the buffer
702 if(buffer == iter) {
703 if(eof && (buffer-iter) == bs)
704 printf("Unfinished binding %s\n",iter);
705 else
706 printf("Buffer is too small for this key name : %s\n",iter);
707 mp_input_free_binds(binds);
708 return;
709 }
710 memmove(buffer,iter,end-iter);
711 bs = end-iter;
712 continue;
713 }
714 {
715 char name[end-iter+1];
716 strncpy(name,iter,end-iter);
717 name[end-iter] = '\0';
718 code = mp_input_get_key_from_name(name);
719 if(code < 0) {
720 printf("Unknow key %s\n",name);
721 mp_input_free_binds(binds);
722 return;
723 }
724 }
725 if( bs > (end-buffer))
726 memmove(buffer,end,bs - (end-buffer));
727 bs -= end-buffer;
728 continue;
729 } else { // Get the command
730 while(iter[0] == ' ' || iter[0] == '\t') iter++;
731 // Found new line
732 if(iter[0] == '\n' || iter[0] == '\r') {
733 printf("No command found for key (TODO)\n" /*mp_input_get_key_name(code)*/);
734 code = -1;
735 if(iter > buffer) {
736 memmove(buffer,iter,bs- (iter-buffer));
737 bs -= (iter-buffer);
738 }
739 continue;
740 }
741 for(end = iter ; end[0] != '\n' && end[0] != '\r' && end[0] != '\0' ; end++)
742 /* NOTHING */;
743 if(end[0] == '\0' && ! (eof && (end - buffer) == bs)) {
744 if(iter == buffer) {
745 printf("Buffer is too small for command %s\n",buffer);
746 mp_input_free_binds(binds);
747 return;
748 }
749 memmove(buffer,iter,end - iter);
750 bs = end - iter;
751 continue;
752 }
753 {
754 char cmd[end-iter+1];
755 strncpy(cmd,iter,end-iter);
756 cmd[end-iter] = '\0';
757 //printf("Set bind %d => %s\n",code,cmd);
758 binds = (mp_cmd_bind_t*)realloc(binds,(n_binds+2)*sizeof(mp_cmd_bind_t));
759 binds[n_binds].input = code;
760 binds[n_binds].cmd = strdup(cmd);
761 n_binds++;
762 memset(&binds[n_binds],0,sizeof(mp_cmd_bind_t));
763 }
764 code = -1;
765 if(bs > (end-buffer))
766 memmove(buffer,end,bs-(end-buffer));
767 bs -= (end-buffer);
768 continue;
769 }
770 }
771 printf("What are we doing here ?\n");
772 }
773
774 extern char *get_path(char *filename);
775
776 void
777 mp_input_init(void) {
778 char* file;
779
780 file = get_path("input.conf");
781 if(!file)
782 return;
783
784 mp_input_parse_config(file);
785
786 #ifdef HAVE_JOYSTICK
787 {
788 int fd = mp_input_joystick_init(NULL);
789 if(fd < 0)
790 printf("Can't init input joystick\n");
791 else
792 mp_input_add_key_fd(fd,1,mp_input_joystick_read,(mp_close_func_t)close);
793 }
794 #endif
795
796 }
797
798 #endif /* HAVE_NEW_INPUT */