Update to MPlayer SVN rev 34180.
[vaapi:miks-mplayer.git] / mp_fifo.c
1 /*
2  * This file is part of MPlayer.
3  *
4  * MPlayer is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * MPlayer is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #include <stdlib.h>
20 #include "osdep/timer.h"
21 #include "input/input.h"
22 #include "input/mouse.h"
23 #include "mp_fifo.h"
24
25 int key_fifo_size = 7;
26 static int *key_fifo_data;
27 static unsigned key_fifo_read;
28 static unsigned key_fifo_write;
29 static int previous_down_key;
30
31 static void mplayer_put_key_internal(int code){
32   int fifo_free = key_fifo_read + key_fifo_size - key_fifo_write;
33   if (key_fifo_data == NULL)
34     key_fifo_data = malloc(key_fifo_size * sizeof(int));
35   if(!fifo_free) return; // FIFO FULL!!
36   // reserve some space for key release events to avoid stuck keys
37   // Make sure we do not reset key state because of a down event
38   if((code & MP_KEY_DOWN) && fifo_free <= (key_fifo_size >> 1))
39     return;
40   // in the worst case, just reset key state
41   if (fifo_free == 1) {
42     // ensure we do not only create MP_KEY_RELEASE_ALL events
43     if (previous_down_key & MP_KEY_RELEASE_ALL)
44       return;
45     // HACK: this ensures that a fifo size of 2 does
46     // not queue any key presses while still allowing
47     // the mouse wheel to work (which sends down and up
48     // at nearly the same time
49     if (code != previous_down_key)
50       code = 0;
51     code |= MP_KEY_RELEASE_ALL;
52   }
53   key_fifo_data[key_fifo_write % key_fifo_size]=code;
54   key_fifo_write++;
55   if (code & MP_KEY_DOWN)
56     previous_down_key = code & ~MP_KEY_DOWN;
57   else
58     previous_down_key = code & MP_KEY_RELEASE_ALL;
59 }
60
61 int mplayer_get_key(int fd){
62   int key;
63   if (key_fifo_data == NULL)
64     return MP_INPUT_NOTHING;
65   if(key_fifo_write==key_fifo_read) return MP_INPUT_NOTHING;
66   key=key_fifo_data[key_fifo_read % key_fifo_size];
67   key_fifo_read++;
68   return key;
69 }
70
71
72 unsigned doubleclick_time = 300;
73
74 static void put_double(int code) {
75   if (code >= MOUSE_BTN0 && code <= MOUSE_BTN_LAST)
76     mplayer_put_key_internal(code - MOUSE_BTN0 + MOUSE_BTN0_DBL);
77 }
78
79 void mplayer_put_key(int code) {
80   static unsigned last_key_time[2];
81   static int last_key[2];
82   unsigned now = GetTimerMS();
83   // ignore system-doubleclick if we generate these events ourselves
84   if (doubleclick_time &&
85       (code & ~MP_KEY_DOWN) >= MOUSE_BTN0_DBL &&
86       (code & ~MP_KEY_DOWN) <= MOUSE_BTN_LAST_DBL)
87     return;
88   mplayer_put_key_internal(code);
89   if (code & MP_KEY_DOWN) {
90     code &= ~MP_KEY_DOWN;
91     last_key[1] = last_key[0];
92     last_key[0] = code;
93     last_key_time[1] = last_key_time[0];
94     last_key_time[0] = now;
95     if (last_key[1] == code &&
96         now - last_key_time[1] < doubleclick_time)
97       put_double(code);
98     return;
99   }
100   if (last_key[0] == code && last_key[1] == code &&
101       now - last_key_time[1] < doubleclick_time)
102     put_double(code);
103 }