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.
22 #include "osdep/timer.h"
23 #include "input/input.h"
24 #include "input/keycodes.h"
39 unsigned last_down_time
;
42 struct mp_fifo
*mp_fifo_create(struct MPOpts
*opts
)
44 struct mp_fifo
*fifo
= talloc_zero(NULL
, struct mp_fifo
);
46 /* Typical mouse wheel use will generate a sequence repeating 3 events:
47 * down, doubleclick, up, down, doubleclick, up, ...
48 * Normally only one of those event types triggers a command,
49 * so allow opts->key_fifo_size such repeats.
51 fifo
->max_up
= opts
->key_fifo_size
;
52 fifo
->size
= opts
->key_fifo_size
* 3;
53 fifo
->data
= talloc_array_ptrtype(fifo
, fifo
->data
, fifo
->size
);
57 static bool is_up(int code
)
59 return code
> 0 && !(code
& MP_KEY_DOWN
)
60 && !(code
>= MOUSE_BTN0_DBL
&& code
< MOUSE_BTN_DBL_END
);
63 static int fifo_peek(struct mp_fifo
*fifo
, int offset
)
65 return fifo
->data
[(fifo
->readpos
+ offset
) % fifo
->size
];
68 static int fifo_read(struct mp_fifo
*fifo
)
70 int code
= fifo_peek(fifo
, 0);
72 fifo
->readpos
%= fifo
->size
;
74 fifo
->num_up
-= is_up(code
);
75 assert(fifo
->num_entries
>= 0);
76 assert(fifo
->num_up
>= 0);
80 static void fifo_write(struct mp_fifo
*fifo
, int code
)
82 fifo
->data
[(fifo
->readpos
+ fifo
->num_entries
) % fifo
->size
] = code
;
84 fifo
->num_up
+= is_up(code
);
85 assert(fifo
->num_entries
<= fifo
->size
);
86 assert(fifo
->num_up
<= fifo
->max_up
);
89 static void mplayer_put_key_internal(struct mp_fifo
*fifo
, int code
)
91 // Clear key-down state if we're forced to drop entries
92 if (fifo
->num_entries
>= fifo
->size
- 1
93 || fifo
->num_up
>= fifo
->max_up
) {
94 if (fifo_peek(fifo
, fifo
->num_entries
- 1) != MP_INPUT_RELEASE_ALL
)
95 fifo_write(fifo
, MP_INPUT_RELEASE_ALL
);
97 fifo_write(fifo
, code
);
100 int mplayer_get_key(void *ctx
, int fd
)
102 struct mp_fifo
*fifo
= ctx
;
103 if (!fifo
->num_entries
)
104 return MP_INPUT_NOTHING
;
105 return fifo_read(fifo
);
108 static void put_double(struct mp_fifo
*fifo
, int code
)
110 if (code
>= MOUSE_BTN0
&& code
< MOUSE_BTN_END
)
111 mplayer_put_key_internal(fifo
, code
- MOUSE_BTN0
+ MOUSE_BTN0_DBL
);
114 void mplayer_put_key(struct mp_fifo
*fifo
, int code
)
116 unsigned now
= GetTimerMS();
117 int doubleclick_time
= fifo
->opts
->doubleclick_time
;
118 // ignore system-doubleclick if we generate these events ourselves
120 && (code
& ~MP_KEY_DOWN
) >= MOUSE_BTN0_DBL
121 && (code
& ~MP_KEY_DOWN
) < MOUSE_BTN_DBL_END
)
123 mplayer_put_key_internal(fifo
, code
);
124 if (code
& MP_KEY_DOWN
) {
125 code
&= ~MP_KEY_DOWN
;
126 if (fifo
->last_key_down
== code
127 && now
- fifo
->last_down_time
< doubleclick_time
)
128 put_double(fifo
, code
);
129 fifo
->last_key_down
= code
;
130 fifo
->last_down_time
= now
;