commands: Allow cycling subtitles backwards with 'J'
[mplayer/glamo.git] / mp_fifo.c
blob4c8e9c64968e4ee4da02d98366d9046bbee64efb
1 /*
2 * This file is part of MPlayer.
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.
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.
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.
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 #include "talloc.h"
25 #include "options.h"
28 struct mp_fifo {
29 struct MPOpts *opts;
30 int *data;
31 int readpos;
32 int writepos;
33 int size;
34 unsigned last_key_time[2];
35 int last_key[2];
38 struct mp_fifo *mp_fifo_create(struct MPOpts *opts)
40 struct mp_fifo *fifo = talloc_zero(NULL, struct mp_fifo);
41 fifo->opts = opts;
42 fifo->size = opts->key_fifo_size;
43 fifo->data = talloc_array_ptrtype(fifo, fifo->data, fifo->size);
44 return fifo;
47 static void mplayer_put_key_internal(struct mp_fifo *fifo, int code)
49 int fifo_free = fifo->readpos - fifo->writepos - 1;
50 if (fifo_free < 0)
51 fifo_free += fifo->size;
52 if (!fifo_free)
53 return; // FIFO FULL!!
54 // reserve some space for key release events to avoid stuck keys
55 if((code & MP_KEY_DOWN) && fifo_free < (fifo->size >> 1))
56 return;
57 fifo->data[fifo->writepos++] = code;
58 fifo->writepos %= fifo->size;
61 int mplayer_get_key(void *ctx, int fd)
63 struct mp_fifo *fifo = ctx;
64 if (fifo->writepos == fifo->readpos)
65 return MP_INPUT_NOTHING;
66 int key = fifo->data[fifo->readpos++];
67 fifo->readpos %= fifo->size;
68 return key;
71 static void put_double(struct mp_fifo *fifo, int code)
73 if (code >= MOUSE_BTN0 && code <= MOUSE_BTN9)
74 mplayer_put_key_internal(fifo, code - MOUSE_BTN0 + MOUSE_BTN0_DBL);
77 void mplayer_put_key(struct mp_fifo *fifo, int code)
79 unsigned now = GetTimerMS();
80 int doubleclick_time = fifo->opts->doubleclick_time;
81 // ignore system-doubleclick if we generate these events ourselves
82 if (doubleclick_time
83 && (code & ~MP_KEY_DOWN) >= MOUSE_BTN0_DBL
84 && (code & ~MP_KEY_DOWN) <= MOUSE_BTN9_DBL)
85 return;
86 mplayer_put_key_internal(fifo, code);
87 if (code & MP_KEY_DOWN) {
88 code &= ~MP_KEY_DOWN;
89 fifo->last_key[1] = fifo->last_key[0];
90 fifo->last_key[0] = code;
91 fifo->last_key_time[1] = fifo->last_key_time[0];
92 fifo->last_key_time[0] = now;
93 if (fifo->last_key[1] == code
94 && now - fifo->last_key_time[1] < doubleclick_time)
95 put_double(fifo, code);
96 return;
98 if (fifo->last_key[0] == code && fifo->last_key[1] == code
99 && now - fifo->last_key_time[1] < doubleclick_time)
100 put_double(fifo, code);