Create a context for input.c state

Start moving static variables to a context struct. Only autorepeat
state is moved to the struct in this commit.

mp_input_check_interrupt now requires the context variable. Change
stream functions to pass it. It's still stored in a static variable in
stream/.
This commit is contained in:
Uoti Urpala 2008-04-30 07:15:52 +03:00
parent 56fec4dfdc
commit 9e9932d4d7
6 changed files with 80 additions and 59 deletions

View File

@ -25,6 +25,7 @@
#include "m_config.h"
#include "m_option.h"
#include "get_path.h"
#include "talloc.h"
#include "joystick.h"
@ -536,6 +537,14 @@ struct mp_cmd_bind_section {
mp_cmd_bind_section_t* next;
};
struct input_ctx {
// Autorepeat stuff
short ar_state;
mp_cmd_t *ar_cmd;
unsigned int last_ar;
};
// These are the user defined binds
static mp_cmd_bind_section_t* cmd_binds_section = NULL;
static char* section = NULL;
@ -559,10 +568,7 @@ static unsigned int cmd_queue_length = 0,cmd_queue_start = 0, cmd_queue_end = 0;
static int key_down[MP_MAX_KEY_DOWN];
static unsigned int num_key_down = 0, last_key_down = 0;
// Autorepeat stuff
static short ar_state = -1;
static mp_cmd_t* ar_cmd = NULL;
static unsigned int ar_delay = 100, ar_rate = 8, last_ar = 0;
static unsigned int ar_delay = 100, ar_rate = 8;
static int use_joystick = 1, use_lirc = 1, use_lircc = 1;
static char* config_file = "input.conf";
@ -1049,8 +1055,7 @@ mp_input_get_cmd_from_keys(int n,int* keys, int paused) {
}
static mp_cmd_t*
interpret_key(int code, int paused)
static mp_cmd_t* interpret_key(struct input_ctx *ictx, int code, int paused)
{
unsigned int j;
mp_cmd_t* ret;
@ -1079,7 +1084,7 @@ interpret_key(int code, int paused)
key_down[num_key_down] = code;
num_key_down++;
last_key_down = GetTimer();
ar_state = 0;
ictx->ar_state = 0;
return NULL;
}
// key released
@ -1105,40 +1110,41 @@ interpret_key(int code, int paused)
memmove(&key_down[j],&key_down[j+1],(num_key_down-(j+1))*sizeof(int));
num_key_down--;
last_key_down = 0;
ar_state = -1;
if(ar_cmd) {
mp_cmd_free(ar_cmd);
ar_cmd = NULL;
ictx->ar_state = -1;
if (ictx->ar_cmd) {
mp_cmd_free(ictx->ar_cmd);
ictx->ar_cmd = NULL;
}
return ret;
}
static mp_cmd_t *check_autorepeat(int paused)
static mp_cmd_t *check_autorepeat(struct input_ctx *ictx, int paused)
{
// No input : autorepeat ?
if(ar_rate > 0 && ar_state >=0 && num_key_down > 0 && ! (key_down[num_key_down-1] & MP_NO_REPEAT_KEY)) {
if (ar_rate > 0 && ictx->ar_state >=0 && num_key_down > 0
&& !(key_down[num_key_down-1] & MP_NO_REPEAT_KEY)) {
unsigned int t = GetTimer();
// First time : wait delay
if(ar_state == 0 && (t - last_key_down) >= ar_delay*1000) {
ar_cmd = mp_input_get_cmd_from_keys(num_key_down,key_down,paused);
if(!ar_cmd) {
ar_state = -1;
if (ictx->ar_state == 0 && (t - last_key_down) >= ar_delay*1000) {
ictx->ar_cmd = mp_input_get_cmd_from_keys(num_key_down,key_down,paused);
if (!ictx->ar_cmd) {
ictx->ar_state = -1;
return NULL;
}
ar_state = 1;
last_ar = t;
return mp_cmd_clone(ar_cmd);
ictx->ar_state = 1;
ictx->last_ar = t;
return mp_cmd_clone(ictx->ar_cmd);
// Then send rate / sec event
} else if(ar_state == 1 && (t -last_ar) >= 1000000/ar_rate) {
last_ar = t;
return mp_cmd_clone(ar_cmd);
} else if (ictx->ar_state == 1 && (t -ictx->last_ar) >= 1000000/ar_rate) {
ictx->last_ar = t;
return mp_cmd_clone(ictx->ar_cmd);
}
}
return NULL;
}
static mp_cmd_t *read_events(int time, int paused)
static mp_cmd_t *read_events(struct input_ctx *ictx, int time, int paused)
{
int i;
int got_cmd = 0;
@ -1206,7 +1212,7 @@ static mp_cmd_t *read_events(int time, int paused)
int code = key_fds[i].read_func.key(key_fds[i].ctx, key_fds[i].fd);
if (code >= 0) {
mp_cmd_t *ret = interpret_key(code, paused);
mp_cmd_t *ret = interpret_key(ictx, code, paused);
if (ret)
return ret;
}
@ -1219,7 +1225,7 @@ static mp_cmd_t *read_events(int time, int paused)
key_fds[i].dead = 1;
}
}
mp_cmd_t *autorepeat_cmd = check_autorepeat(paused);
mp_cmd_t *autorepeat_cmd = check_autorepeat(ictx, paused);
if (autorepeat_cmd)
return autorepeat_cmd;
@ -1279,8 +1285,9 @@ mp_input_get_queued_cmd(int peek_only) {
* \param peek_only when set, the returned command stays in the queue.
* Do not free the returned cmd whe you set this!
*/
mp_cmd_t*
mp_input_get_cmd(int time, int paused, int peek_only) {
mp_cmd_t *mp_input_get_cmd(struct input_ctx *ictx, int time, int paused,
int peek_only)
{
mp_cmd_t* ret = NULL;
mp_cmd_filter_t* cf;
int from_queue;
@ -1292,7 +1299,7 @@ mp_input_get_cmd(int time, int paused, int peek_only) {
ret = mp_input_get_queued_cmd(peek_only);
if(ret) break;
from_queue = 0;
ret = read_events(time, paused);
ret = read_events(ictx, time, paused);
if (!ret) {
from_queue = 1;
ret = mp_input_get_queued_cmd(peek_only);
@ -1660,8 +1667,13 @@ mp_input_get_section(void) {
return section;
}
void
mp_input_init(int use_gui) {
struct input_ctx *mp_input_init(int use_gui)
{
struct input_ctx *ictx = talloc_ptrtype(NULL, ictx);
*ictx = (struct input_ctx){
.ar_state = -1,
};
char* file;
#ifdef HAVE_NEW_GUI
@ -1671,7 +1683,7 @@ mp_input_init(int use_gui) {
file = config_file[0] != '/' ? get_path(config_file) : config_file;
if(!file)
return;
return ictx;
if( !mp_input_parse_config(file)) {
// free file if it was allocated by get_path(),
@ -1739,11 +1751,11 @@ mp_input_init(int use_gui) {
mp_msg(MSGT_INPUT,MSGL_ERR,MSGTR_INPUT_INPUT_ErrCantOpenFile,in_file,strerror(errno));
}
}
return ictx;
}
void
mp_input_uninit(void) {
void mp_input_uninit(struct input_ctx *ictx)
{
unsigned int i;
mp_cmd_bind_section_t* bind_section;
@ -1764,6 +1776,7 @@ mp_input_uninit(void) {
cmd_binds_section=bind_section;
}
cmd_binds_section=NULL;
talloc_free(ictx);
}
void
@ -1810,10 +1823,10 @@ static int mp_input_print_cmd_list(m_option_t* cfg) {
exit(0);
}
int
mp_input_check_interrupt(int time) {
int mp_input_check_interrupt(struct input_ctx *ictx, int time)
{
mp_cmd_t* cmd;
if((cmd = mp_input_get_cmd(time,0,1)) == NULL)
if ((cmd = mp_input_get_cmd(ictx, time, 0, 1)) == NULL)
return 0;
switch(cmd->id) {
case MP_CMD_QUIT:
@ -1824,7 +1837,7 @@ mp_input_check_interrupt(int time) {
return 1;
}
// remove the cmd from the queue
cmd = mp_input_get_cmd(time,0,0);
cmd = mp_input_get_cmd(ictx, time, 0, 0);
mp_cmd_free(cmd);
return 0;
}

View File

@ -171,6 +171,8 @@
#define MP_MAX_KEY_DOWN 32
#endif
struct input_ctx;
typedef union mp_cmd_arg_value {
int i;
float f;
@ -252,7 +254,7 @@ mp_input_queue_cmd(mp_cmd_t* cmd);
// This function retrieves the next available command waiting no more than time msec.
// If pause is true, the next input will always return a pause command.
mp_cmd_t*
mp_input_get_cmd(int time, int paused, int peek_only);
mp_input_get_cmd(struct input_ctx *ictx, int time, int paused, int peek_only);
mp_cmd_t*
mp_input_parse_cmd(char* str);
@ -286,15 +288,13 @@ char*
mp_input_get_section(void);
// When you create a new driver you should add it in these 2 functions.
void
mp_input_init(int use_gui);
struct input_ctx *mp_input_init(int use_gui);
void
mp_input_uninit(void);
void mp_input_uninit(struct input_ctx *ictx);
// Interruptible usleep: (used by libmpdemux)
int
mp_input_check_interrupt(int time);
mp_input_check_interrupt(struct input_ctx *ictx, int time);
extern int async_quit_request;

View File

@ -40,6 +40,7 @@ typedef struct MPContext {
struct m_config *mconfig;
struct vo_x11_state *x11_state;
struct mp_fifo *key_fifo;
struct input_ctx *input;
int osd_show_percentage;
int osd_function;
const ao_functions_t *audio_out;

View File

@ -647,7 +647,7 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask){
if(mask&INITIALIZED_INPUT){
mpctx->initialized_flags&=~INITIALIZED_INPUT;
current_module="uninit_input";
mp_input_uninit();
mp_input_uninit(mpctx->input);
#ifdef HAVE_MENU
if (use_menu)
menu_uninit();
@ -931,7 +931,7 @@ static void load_per_file_config (m_config_t* conf, const char *const file)
static int libmpdemux_was_interrupted(struct MPContext *mpctx, int eof)
{
mp_cmd_t* cmd;
if((cmd = mp_input_get_cmd(0,0,0)) != NULL) {
if((cmd = mp_input_get_cmd(mpctx->input, 0,0,0)) != NULL) {
switch(cmd->id) {
case MP_CMD_QUIT:
exit_player_with_rc(mpctx, MSGTR_Exit_quit, (cmd->nargs > 0)? cmd->args[0].v.i : 0);
@ -2349,10 +2349,10 @@ static void pause_loop(struct MPContext *mpctx)
if (mpctx->audio_out && mpctx->sh_audio)
mpctx->audio_out->pause(); // pause audio, keep data if possible
while ( (cmd = mp_input_get_cmd(20, 1, 1)) == NULL
while ( (cmd = mp_input_get_cmd(mpctx->input, 20, 1, 1)) == NULL
|| cmd->id == MP_CMD_SET_MOUSE_POS) {
if (cmd) {
cmd = mp_input_get_cmd(0,1,0);
cmd = mp_input_get_cmd(mpctx->input, 0,1,0);
mp_cmd_free(cmd);
continue;
}
@ -2373,7 +2373,7 @@ static void pause_loop(struct MPContext *mpctx)
usec_sleep(20000);
}
if (cmd && cmd->id == MP_CMD_PAUSE) {
cmd = mp_input_get_cmd(0,1,0);
cmd = mp_input_get_cmd(mpctx->input, 0,1,0);
mp_cmd_free(cmd);
}
mpctx->osd_function=OSD_PLAY;
@ -2875,14 +2875,14 @@ if(!codecs_file || !parse_codec_cfg(codecs_file)){
// Init input system
current_module = "init_input";
mp_input_init(use_gui);
mpctx->input = mp_input_init(use_gui);
mp_input_add_key_fd(-1,0,mplayer_get_key,NULL, mpctx->key_fifo);
if(slave_mode)
mp_input_add_cmd_fd(0,USE_SELECT,MP_INPUT_SLAVE_CMD_FUNC,NULL);
else if(!noconsolecontrols)
mp_input_add_key_fd(0, 1, read_keys, NULL, mpctx->key_fifo);
// Set the libstream interrupt callback
stream_set_interrupt_callback(mp_input_check_interrupt);
stream_set_interrupt_callback(mp_input_check_interrupt, mpctx->input);
#ifdef HAVE_MENU
if(use_menu) {
@ -2987,7 +2987,7 @@ if(!noconsolecontrols && !slave_mode){
usec_sleep(20000);
guiEventHandling();
guiGetEvent( guiReDraw,NULL );
if ( (cmd = mp_input_get_cmd(0,0,0)) != NULL) {
if ( (cmd = mp_input_get_cmd(mpctx->input, 0,0,0)) != NULL) {
guiGetEvent(guiIEvent, (char *)cmd->id);
mp_cmd_free(cmd);
}
@ -3020,7 +3020,7 @@ if(!noconsolecontrols && !slave_mode){
while (player_idle_mode && !mpctx->filename) {
play_tree_t * entry = NULL;
mp_cmd_t * cmd;
while (!(cmd = mp_input_get_cmd(0,1,0))) { // wait for command
while (!(cmd = mp_input_get_cmd(mpctx->input, 0,1,0))) { // wait for command
if (mpctx->video_out)
vo_check_events(mpctx->video_out);
usec_sleep(20000);
@ -3873,7 +3873,7 @@ if(step_sec>0) {
{
mp_cmd_t* cmd;
int brk_cmd = 0;
while( !brk_cmd && (cmd = mp_input_get_cmd(0,0,0)) != NULL) {
while( !brk_cmd && (cmd = mp_input_get_cmd(mpctx->input, 0,0,0)) != NULL) {
brk_cmd = run_command(mpctx, cmd);
mp_cmd_free(cmd);
if (brk_cmd == 2)

View File

@ -34,7 +34,9 @@
//#include "vcd_read_bincue.h"
static int (*stream_check_interrupt_cb)(int time) = NULL;
struct input_ctx;
static int (*stream_check_interrupt_cb)(struct input_ctx *ctx, int time);
static struct input_ctx *stream_check_interrupt_ctx;
extern const stream_info_t stream_info_vcd;
extern const stream_info_t stream_info_cdda;
@ -454,11 +456,14 @@ stream_t* new_ds_stream(demux_stream_t *ds) {
return s;
}
void stream_set_interrupt_callback(int (*cb)(int)) {
void stream_set_interrupt_callback(int (*cb)(struct input_ctx *, int),
struct input_ctx *ctx)
{
stream_check_interrupt_cb = cb;
stream_check_interrupt_ctx = ctx;
}
int stream_check_interrupt(int time) {
if(!stream_check_interrupt_cb) return 0;
return stream_check_interrupt_cb(time);
return stream_check_interrupt_cb(stream_check_interrupt_ctx, time);
}

View File

@ -300,7 +300,9 @@ stream_t* open_stream_full(char* filename,int mode, struct MPOpts *options, int*
stream_t* open_output_stream(char* filename,struct MPOpts *options);
/// Set the callback to be used by libstream to check for user
/// interruption during long blocking operations (cache filling, etc).
void stream_set_interrupt_callback(int (*cb)(int));
struct input_ctx;
void stream_set_interrupt_callback(int (*cb)(struct input_ctx*, int),
struct input_ctx *ctx);
/// Call the interrupt checking callback if there is one.
int stream_check_interrupt(int time);