Mercurial > mplayer.hg
comparison input/input.c @ 4589:4ce20c55a18a
Added support for key combination and mouse buttons key code
author | albeu |
---|---|
date | Fri, 08 Feb 2002 18:10:56 +0000 |
parents | 46c4e34b4e76 |
children | 610a11e4db36 |
comparison
equal
deleted
inserted
replaced
4588:84296c3c6ba4 | 4589:4ce20c55a18a |
---|---|
13 #include <fcntl.h> | 13 #include <fcntl.h> |
14 | 14 |
15 | 15 |
16 | 16 |
17 #include "input.h" | 17 #include "input.h" |
18 #include "mouse.h" | |
18 #ifdef MP_DEBUG | 19 #ifdef MP_DEBUG |
19 #include <assert.h> | 20 #include <assert.h> |
20 #endif | 21 #endif |
21 #include "../linux/getch2.h" | 22 #include "../linux/getch2.h" |
22 #include "../linux/keycodes.h" | 23 #include "../linux/keycodes.h" |
57 { MP_CMD_TV_STEP_CHANNEL_LIST, "tv_step_chanlist", 0, { {-1,{0}} } }, | 58 { MP_CMD_TV_STEP_CHANNEL_LIST, "tv_step_chanlist", 0, { {-1,{0}} } }, |
58 #endif | 59 #endif |
59 { 0, NULL, 0, {} } | 60 { 0, NULL, 0, {} } |
60 }; | 61 }; |
61 | 62 |
62 static mp_cmd_bind_t key_names[] = { | 63 static mp_key_name_t key_names[] = { |
63 { ' ', "SPACE" }, | 64 { ' ', "SPACE" }, |
64 { KEY_ENTER, "ENTER" }, | 65 { KEY_ENTER, "ENTER" }, |
65 { KEY_TAB, "TAB" }, | 66 { KEY_TAB, "TAB" }, |
66 { KEY_CTRL, "CTRL" }, | 67 { KEY_CTRL, "CTRL" }, |
67 { KEY_BACKSPACE, "BS" }, | 68 { KEY_BACKSPACE, "BS" }, |
74 { KEY_ESC, "ESC" }, | 75 { KEY_ESC, "ESC" }, |
75 { KEY_RIGHT, "RIGHT" }, | 76 { KEY_RIGHT, "RIGHT" }, |
76 { KEY_LEFT, "LEFT" }, | 77 { KEY_LEFT, "LEFT" }, |
77 { KEY_DOWN, "DOWN" }, | 78 { KEY_DOWN, "DOWN" }, |
78 { KEY_UP, "UP" }, | 79 { KEY_UP, "UP" }, |
80 { MOUSE_BTN0, "MOUSE_BTN0" }, | |
81 { MOUSE_BTN1, "MOUSE_BTN1" }, | |
82 { MOUSE_BTN2, "MOUSE_BTN2" }, | |
83 { MOUSE_BTN3, "MOUSE_BTN3" }, | |
84 { MOUSE_BTN4, "MOUSE_BTN4" }, | |
85 { MOUSE_BTN5, "MOUSE_BTN5" }, | |
86 { MOUSE_BTN6, "MOUSE_BTN6" }, | |
87 { MOUSE_BTN7, "MOUSE_BTN7" }, | |
88 { MOUSE_BTN8, "MOUSE_BTN8" }, | |
89 { MOUSE_BTN9, "MOUSE_BTN9" }, | |
79 #ifdef HAVE_JOYSTICK | 90 #ifdef HAVE_JOYSTICK |
80 { JOY_AXIS1_MINUS, "JOY_UP" }, | 91 { JOY_AXIS1_MINUS, "JOY_UP" }, |
81 { JOY_AXIS1_PLUS, "JOY_DOWN" }, | 92 { JOY_AXIS1_PLUS, "JOY_DOWN" }, |
82 { JOY_AXIS0_MINUS, "JOY_LEFT" }, | 93 { JOY_AXIS0_MINUS, "JOY_LEFT" }, |
83 { JOY_AXIS0_PLUS, "JOY_RIGHT" }, | 94 { JOY_AXIS0_PLUS, "JOY_RIGHT" }, |
118 }; | 129 }; |
119 | 130 |
120 // This is the default binding we use when no config file is here | 131 // This is the default binding we use when no config file is here |
121 | 132 |
122 static mp_cmd_bind_t def_cmd_binds[] = { | 133 static mp_cmd_bind_t def_cmd_binds[] = { |
123 { KEY_RIGHT, "seek 10" }, | 134 { { KEY_RIGHT, 0 }, "seek 10" }, |
124 { KEY_LEFT, "seek -10" }, | 135 { { KEY_LEFT, 0 }, "seek -10" }, |
125 { KEY_UP, "seek 60" }, | 136 { { KEY_UP, 0 }, "seek 60" }, |
126 { KEY_DOWN, "seek -60" }, | 137 { { KEY_DOWN, 0 }, "seek -60" }, |
127 { KEY_PAGE_UP, "seek 600" }, | 138 { { KEY_PAGE_UP, 0 }, "seek 600" }, |
128 { KEY_PAGE_DOWN, "seek -600" }, | 139 { { KEY_PAGE_DOWN, 0 }, "seek -600" }, |
129 { '+', "audio_delay 0.100" }, | 140 { { '+', 0 }, "audio_delay 0.100" }, |
130 { '-', "audio_delay -0.100" }, | 141 { { '-', 0 }, "audio_delay -0.100" }, |
131 { 'q', "quit" }, | 142 { { 'q', 0 }, "quit" }, |
132 { KEY_ESC, "quit" }, | 143 { { KEY_ESC, 0 }, "quit" }, |
133 { 'p', "pause" }, | 144 { { 'p', 0 }, "pause" }, |
134 { ' ', "pause" }, | 145 { { ' ', 0 }, "pause" }, |
135 { KEY_HOME, "pt_up_step 1" }, | 146 { { KEY_HOME, 0 }, "pt_up_step 1" }, |
136 { KEY_END, "pt_up_step -1" }, | 147 { { KEY_END, 0 }, "pt_up_step -1" }, |
137 { '>', "pt_step 1" }, | 148 { { '>', 0 }, "pt_step 1" }, |
138 { '<', "pt_step -1" }, | 149 { { '<', 0 }, "pt_step -1" }, |
139 { KEY_INS, "alt_src_step 1" }, | 150 { { KEY_INS, 0 }, "alt_src_step 1" }, |
140 { KEY_DEL, "alt_src_step -1" }, | 151 { { KEY_DEL, 0 }, "alt_src_step -1" }, |
141 { 'o', "osd" }, | 152 { { 'o', 0 }, "osd" }, |
142 { 'z', "sub_delay -0.1" }, | 153 { { 'z', 0 }, "sub_delay -0.1" }, |
143 { 'x', "sub_delay +0.1" }, | 154 { { 'x', 0 }, "sub_delay +0.1" }, |
144 { '9', "volume -1" }, | 155 { { '9', 0 }, "volume -1" }, |
145 { '/', "volume -1" }, | 156 { { '/', 0 }, "volume -1" }, |
146 { '0', "volume 1" }, | 157 { { '0', 0 }, "volume 1" }, |
147 { '*', "volume 1" }, | 158 { { '*', 0 }, "volume 1" }, |
148 { 'm', "use_master" }, | 159 { { 'm', 0 }, "use_master" }, |
149 { '1', "contrast -1" }, | 160 { { '1', 0 }, "contrast -1" }, |
150 { '2', "contrast 1" }, | 161 { { '2', 0 }, "contrast 1" }, |
151 { '3', "brightness -1" }, | 162 { { '3', 0 }, "brightness -1" }, |
152 { '4', "brightness 1" }, | 163 { { '4', 0 }, "brightness 1" }, |
153 { '5', "hue -1" }, | 164 { { '5', 0 }, "hue -1" }, |
154 { '6', "hue 1" }, | 165 { { '6', 0 }, "hue 1" }, |
155 { '7', "saturation -1" }, | 166 { { '7', 0 }, "saturation -1" }, |
156 { '8', "saturation 1" }, | 167 { { '8', 0 }, "saturation 1" }, |
157 { 'd', "frame_drop" }, | 168 { { 'd', 0 }, "frame_drop" }, |
158 #ifdef USE_TV | 169 #ifdef USE_TV |
159 { 'h', "tv_step_channel 1" }, | 170 { { 'h', 0 }, "tv_step_channel 1" }, |
160 { 'l', "tv_step_channel -1" }, | 171 { { 'l', 0 }, "tv_step_channel -1" }, |
161 { 'n', "tv_step_norm" }, | 172 { { 'n', 0 }, "tv_step_norm" }, |
162 { 'b', "tv_step_chanlist" }, | 173 { { 'b', 0 }, "tv_step_chanlist" }, |
163 #endif | 174 #endif |
164 #ifdef HAVE_JOYSTICK | 175 #ifdef HAVE_JOYSTICK |
165 { JOY_AXIS0_PLUS, "seek 10" }, | 176 { { JOY_AXIS0_PLUS, 0 }, "seek 10" }, |
166 { JOY_AXIS0_MINUS, "seek -10" }, | 177 { { JOY_AXIS0_MINUS, 0 }, "seek -10" }, |
167 { JOY_AXIS1_MINUS, "seek 60" }, | 178 { { JOY_AXIS1_MINUS, 0 }, "seek 60" }, |
168 { JOY_AXIS1_PLUS, "seek -60" }, | 179 { { JOY_AXIS1_PLUS, 0 }, "seek -60" }, |
169 { JOY_BTN0, "pause" }, | 180 { { JOY_BTN0, 0 }, "pause" }, |
170 { JOY_BTN1, "osd" }, | 181 { { JOY_BTN1, 0 }, "osd" }, |
171 { JOY_BTN2, "volume 1"}, | 182 { { JOY_BTN2, 0 }, "volume 1"}, |
172 { JOY_BTN3, "volume -1"}, | 183 { { JOY_BTN3, 0 }, "volume -1"}, |
173 #endif | 184 #endif |
174 { 0, NULL } | 185 { { 0 }, NULL } |
175 }; | 186 }; |
176 | 187 |
177 #ifndef MP_MAX_KEY_FD | 188 #ifndef MP_MAX_KEY_FD |
178 #define MP_MAX_KEY_FD 10 | 189 #define MP_MAX_KEY_FD 10 |
179 #endif | 190 #endif |
205 static unsigned int num_key_fd = 0; | 216 static unsigned int num_key_fd = 0; |
206 static mp_input_fd_t cmd_fds[MP_MAX_CMD_FD]; | 217 static mp_input_fd_t cmd_fds[MP_MAX_CMD_FD]; |
207 static unsigned int num_cmd_fd = 0; | 218 static unsigned int num_cmd_fd = 0; |
208 | 219 |
209 static int key_max_fd = -1, cmd_max_fd = -1; | 220 static int key_max_fd = -1, cmd_max_fd = -1; |
221 | |
222 // this is the key currently down | |
223 static int key_down[MP_MAX_KEY_DOWN]; | |
224 static unsigned int num_key_down = 0; | |
225 static short last_key_down = 0,key_was_down = 0; | |
210 | 226 |
211 static int | 227 static int |
212 mp_input_default_key_func(int fd); | 228 mp_input_default_key_func(int fd); |
213 | 229 |
214 | 230 |
497 } else { | 513 } else { |
498 FD_ZERO(&fds); | 514 FD_ZERO(&fds); |
499 } | 515 } |
500 | 516 |
501 for(i = last_loop + 1 ; i != last_loop ; i++) { | 517 for(i = last_loop + 1 ; i != last_loop ; i++) { |
502 int code = -1,j; | 518 int code = -1; |
519 unsigned int j; | |
503 | 520 |
504 if((unsigned int)i >= num_key_fd) { | 521 if((unsigned int)i >= num_key_fd) { |
505 i = -1; | 522 i = -1; |
506 last_loop++; | 523 last_loop++; |
507 continue; | 524 continue; |
513 if(code < 0) | 530 if(code < 0) |
514 code = MP_INPUT_NOTHING; | 531 code = MP_INPUT_NOTHING; |
515 } | 532 } |
516 else | 533 else |
517 code = ((mp_key_func_t)key_fds[i].read_func)(key_fds[i].fd); | 534 code = ((mp_key_func_t)key_fds[i].read_func)(key_fds[i].fd); |
518 | 535 if((code & ~MP_KEY_DOWN) < 0) { |
519 if(code < 0) { | |
520 if(code == MP_INPUT_ERROR) | 536 if(code == MP_INPUT_ERROR) |
521 printf("Error on key input fd %d\n",key_fds[i].fd); | 537 printf("Error on key input fd %d\n",key_fds[i].fd); |
522 else if(code == MP_INPUT_DEAD) { | 538 else if(code == MP_INPUT_DEAD) { |
523 printf("Dead key input on fd %d\n",key_fds[i].fd); | 539 printf("Dead key input on fd %d\n",key_fds[i].fd); |
524 key_fds[i].flags |= MP_FD_DEAD; | 540 key_fds[i].flags |= MP_FD_DEAD; |
525 } | 541 } |
526 continue; | 542 continue; |
527 } | 543 } |
544 if(code & MP_KEY_DOWN) { // key pushed | |
545 if(num_key_down > MP_MAX_KEY_DOWN) { | |
546 printf("Too much key down at the same time\n"); | |
547 continue; | |
548 } | |
549 code &= ~MP_KEY_DOWN; | |
550 key_down[num_key_down] = code; | |
551 num_key_down++; | |
552 last_key_down = 1; | |
553 continue; | |
554 } | |
555 key_was_down = 0; | |
556 if(num_key_down > 0) { // key released | |
557 for(j = 0; j < num_key_down; j++) { | |
558 if(key_down[j] == code) { // Remove the key from the current combination | |
559 if(j+1 < num_key_down) | |
560 memmove(&key_down[j],&key_down[j+1],(num_key_down-(j+1))*sizeof(int)); | |
561 num_key_down--; | |
562 key_was_down = 1; | |
563 break; | |
564 } | |
565 } | |
566 if(key_was_down && !last_key_down) // Ignore relaesing key part of the combination | |
567 continue; | |
568 last_key_down = 0; | |
569 } | |
528 if(paused) | 570 if(paused) |
529 return mp_input_parse_cmd("pause"); | 571 return mp_input_parse_cmd("pause"); |
530 for(j = 0; cmd_binds[j].cmd != NULL; j++) { | 572 for(j = 0; cmd_binds[j].cmd != NULL; j++) { |
531 if(cmd_binds[j].input == code) | 573 if(num_key_down > 0) { |
532 break; | 574 unsigned int found = 1,s; |
575 for(s = 0; cmd_binds[j].input[s+1] != 0; s++) { | |
576 if(cmd_binds[j].input[s] != key_down[s]) { | |
577 found = 0; | |
578 break; | |
579 } | |
580 } | |
581 if(found && s == num_key_down && cmd_binds[j].input[s] == code && cmd_binds[j].input[s+1] == 0) | |
582 break; | |
583 continue; | |
584 } else { | |
585 if(cmd_binds[j].input[0] == code && cmd_binds[j].input[1] == 0) | |
586 break; | |
587 } | |
533 } | 588 } |
534 if(cmd_binds[j].cmd == NULL) { | 589 if(cmd_binds[j].cmd == NULL) { |
535 printf("No bind found for key %d\n",code); | 590 printf("No bind found for key %d",num_key_down > 0 ? key_down[0] : code); |
591 if(num_key_down > 0) { | |
592 unsigned int s; | |
593 for(s=1; s < num_key_down; s++) | |
594 printf("-%d",key_down[s]); | |
595 printf("-%d",code); | |
596 } | |
597 printf(" \n"); | |
536 continue; | 598 continue; |
537 } | 599 } |
538 last_loop = i; | 600 last_loop = i; |
539 return mp_input_parse_cmd(cmd_binds[j].cmd); | 601 return mp_input_parse_cmd(cmd_binds[j].cmd); |
540 } | 602 } |
646 } | 708 } |
647 | 709 |
648 static int | 710 static int |
649 mp_input_get_key_from_name(char* name) { | 711 mp_input_get_key_from_name(char* name) { |
650 int i,ret = 0; | 712 int i,ret = 0; |
651 | |
652 if(strlen(name) == 1) { // Direct key code | 713 if(strlen(name) == 1) { // Direct key code |
653 (char)ret = name[0]; | 714 (char)ret = name[0]; |
654 return ret; | 715 return ret; |
655 } | 716 } |
656 | 717 |
657 for(i = 0; key_names[i].cmd != NULL; i++) { | 718 for(i = 0; key_names[i].name != NULL; i++) { |
658 if(strcasecmp(key_names[i].cmd,name) == 0) | 719 if(strcasecmp(key_names[i].name,name) == 0) |
659 return key_names[i].input; | 720 return key_names[i].key; |
660 } | 721 } |
661 | 722 |
662 return -1; | 723 return -1; |
724 } | |
725 | |
726 static int | |
727 mp_input_get_input_from_name(char* name,int* keys) { | |
728 char *end,*ptr; | |
729 int n=0; | |
730 | |
731 ptr = name; | |
732 n = 0; | |
733 for(end = strchr(ptr,'-') ; ptr != NULL ; end = strchr(ptr,'-')) { | |
734 if(end && end[1] != '\0') { | |
735 if(end[1] == '-') | |
736 end = &end[1]; | |
737 end[0] = '\0'; | |
738 } | |
739 keys[n] = mp_input_get_key_from_name(ptr); | |
740 if(keys[n] < 0) { | |
741 return 0; | |
742 } | |
743 n++; | |
744 if(end && end[1] != '\0' && n < MP_MAX_KEY_DOWN) | |
745 ptr = &end[1]; | |
746 else | |
747 break; | |
748 } | |
749 keys[n] = 0; | |
750 return 1; | |
663 } | 751 } |
664 | 752 |
665 static void | 753 static void |
666 mp_input_free_binds(mp_cmd_bind_t* binds) { | 754 mp_input_free_binds(mp_cmd_bind_t* binds) { |
667 int i; | 755 int i; |
680 #define BS_MAX 256 | 768 #define BS_MAX 256 |
681 #define SPACE_CHAR " \n\r\t" | 769 #define SPACE_CHAR " \n\r\t" |
682 | 770 |
683 static int | 771 static int |
684 mp_input_parse_config(char *file) { | 772 mp_input_parse_config(char *file) { |
685 int fd,code=-1; | 773 int fd; |
686 int bs = 0,r,eof = 0; | 774 int bs = 0,r,eof = 0; |
687 char *iter,*end; | 775 char *iter,*end; |
688 char buffer[BS_MAX]; | 776 char buffer[BS_MAX]; |
689 int n_binds = 0; | 777 int n_binds = 0, keys[MP_MAX_KEY_DOWN+1] = { 0 }; |
690 mp_cmd_bind_t* binds = NULL; | 778 mp_cmd_bind_t* binds = NULL; |
691 | 779 |
692 fd = open(file,O_RDONLY); | 780 fd = open(file,O_RDONLY); |
693 | 781 |
694 if(fd < 0) { | 782 if(fd < 0) { |
724 } | 812 } |
725 | 813 |
726 iter = buffer; | 814 iter = buffer; |
727 | 815 |
728 // Find the wanted key | 816 // Find the wanted key |
729 if(code < 0) { | 817 if(keys[0] == 0) { |
730 // Jump beginnig space | 818 // Jump beginnig space |
731 for( ; iter[0] != '\0' && strchr(SPACE_CHAR,iter[0]) != NULL ; iter++) | 819 for( ; iter[0] != '\0' && strchr(SPACE_CHAR,iter[0]) != NULL ; iter++) |
732 /* NOTHING */; | 820 /* NOTHING */; |
733 if(iter[0] == '\0') { // Buffer was full of space char | 821 if(iter[0] == '\0') { // Buffer was full of space char |
734 bs = 0; | 822 bs = 0; |
752 } | 840 } |
753 { | 841 { |
754 char name[end-iter+1]; | 842 char name[end-iter+1]; |
755 strncpy(name,iter,end-iter); | 843 strncpy(name,iter,end-iter); |
756 name[end-iter] = '\0'; | 844 name[end-iter] = '\0'; |
757 code = mp_input_get_key_from_name(name); | 845 if(! mp_input_get_input_from_name(name,keys)) { |
758 if(code < 0) { | |
759 printf("Unknow key %s\n",name); | 846 printf("Unknow key %s\n",name); |
760 mp_input_free_binds(binds); | 847 mp_input_free_binds(binds); |
761 return 0; | 848 return 0; |
762 } | 849 } |
763 } | 850 } |
768 } else { // Get the command | 855 } else { // Get the command |
769 while(iter[0] == ' ' || iter[0] == '\t') iter++; | 856 while(iter[0] == ' ' || iter[0] == '\t') iter++; |
770 // Found new line | 857 // Found new line |
771 if(iter[0] == '\n' || iter[0] == '\r') { | 858 if(iter[0] == '\n' || iter[0] == '\r') { |
772 printf("No command found for key (TODO)\n" /*mp_input_get_key_name(code)*/); | 859 printf("No command found for key (TODO)\n" /*mp_input_get_key_name(code)*/); |
773 code = -1; | 860 keys[0] = 0; |
774 if(iter > buffer) { | 861 if(iter > buffer) { |
775 memmove(buffer,iter,bs- (iter-buffer)); | 862 memmove(buffer,iter,bs- (iter-buffer)); |
776 bs -= (iter-buffer); | 863 bs -= (iter-buffer); |
777 } | 864 } |
778 continue; | 865 continue; |
793 char cmd[end-iter+1]; | 880 char cmd[end-iter+1]; |
794 strncpy(cmd,iter,end-iter); | 881 strncpy(cmd,iter,end-iter); |
795 cmd[end-iter] = '\0'; | 882 cmd[end-iter] = '\0'; |
796 //printf("Set bind %d => %s\n",code,cmd); | 883 //printf("Set bind %d => %s\n",code,cmd); |
797 binds = (mp_cmd_bind_t*)realloc(binds,(n_binds+2)*sizeof(mp_cmd_bind_t)); | 884 binds = (mp_cmd_bind_t*)realloc(binds,(n_binds+2)*sizeof(mp_cmd_bind_t)); |
798 binds[n_binds].input = code; | 885 memcpy(&binds[n_binds].input,keys,MP_MAX_KEY_DOWN+1); |
799 binds[n_binds].cmd = strdup(cmd); | 886 binds[n_binds].cmd = strdup(cmd); |
800 n_binds++; | 887 n_binds++; |
801 memset(&binds[n_binds],0,sizeof(mp_cmd_bind_t)); | 888 memset(&binds[n_binds],0,sizeof(mp_cmd_bind_t)); |
802 } | 889 } |
803 code = -1; | 890 keys[0] = 0; |
804 if(bs > (end-buffer)) | 891 if(bs > (end-buffer)) |
805 memmove(buffer,end,bs-(end-buffer)); | 892 memmove(buffer,end,bs-(end-buffer)); |
806 bs -= (end-buffer); | 893 bs -= (end-buffer); |
807 continue; | 894 continue; |
808 } | 895 } |