~nloomans/ft_select

2e75cb9f27ad9eb723b601f132a4e1449d02a31f — Noah Loomans 1 year, 8 months ago 0c2485d
fix event norm
5 files changed, 156 insertions(+), 109 deletions(-)

M inc/event.h
A inc/handle.h
M meson.build
M src/event.c
A src/handle.c
M inc/event.h => inc/event.h +0 -6
@@ 17,12 17,6 @@
# include "action.h"
# include "error.h"

struct				s_event_signal_map
{
	bool		*global;
	t_action	action;
	void		(*handler)(int signum);
};

t_error				event_init(void);
t_error				event_next(t_action *dest);

A inc/handle.h => inc/handle.h +29 -0
@@ 0,0 1,29 @@
/* ************************************************************************** */
/*                                                                            */
/*                                                        ::::::::            */
/*   ft_select                                          :+:    :+:            */
/*                                                     +:+                    */
/*   Author: Noah Loomans                             +#+                     */
/*           <nloomans@student.codam.nl>             +#+                      */
/*                                                  #+#    #+#                */
/*   License: GPLv3                                ########   odam.nl         */
/*                                                                            */
/* ************************************************************************** */

#ifndef HANDLE_H
# define HANDLE_H

# include "action.h"
# include "read.h"

struct									s_handle_signal_map
{
	bool		*global;
	t_action	action;
	void		(*handler)(int signum);
};

extern const struct s_handle_signal_map	g_handle_signal_map[29];
extern const t_action 					g_handle_key_map[READ_TYPE_AMOUNT][256];

#endif

M meson.build => meson.build +1 -0
@@ 35,6 35,7 @@ src_files = files([
  'src/derive_rows.c',
  'src/error.c',
  'src/event.c',
  'src/handle.c',
  'src/list2.c',
  'src/read.c',
  'src/state.c',

M src/event.c => src/event.c +12 -103
@@ 23,121 23,30 @@
#include "terminal.h"
#include "action.h"
#include "read.h"
#include "handle.h"
#include "error.h"

bool							g_event_sigwinch = false;
bool							g_event_sigcont = false;

static void						handle_generic(int signum);

static void						handle_suspend(int signum)
{
	struct termios attr;

	(void)signum;
	terminal_configure(TERMINAL_CONFIGURE_RESTORE);
	signal(SIGTSTP, SIG_DFL);
	tcgetattr(STDIN_FILENO, &attr);
	ioctl(STDIN_FILENO, TIOCSTI, (char[]){attr.c_cc[VSUSP], '\0'});
}

static void						handle_continue(int signum)
{
	(void)signum;
	terminal_configure(TERMINAL_CONFIGURE_SETUP);
	signal(SIGTSTP, handle_suspend);
	handle_generic(signum);
}

static void						handle_exit_signal(int signum)
{
	terminal_configure(TERMINAL_CONFIGURE_RESTORE);
	ft_dprintf(STDERR_FILENO, "ft_select: received '%s' signal, exiting...\n",
		sys_siglist[signum]);
	exit(1);
}

const struct s_event_signal_map	g_event_signal_map[] = {
	[SIGHUP]	= { .handler = handle_exit_signal },
	[SIGINT]	= { .handler = handle_exit_signal },
	[SIGQUIT]	= { .handler = handle_exit_signal },
	[SIGILL]	= { .handler = handle_exit_signal },
	[SIGTRAP]	= { .handler = handle_exit_signal },
	[SIGABRT]	= { .handler = handle_exit_signal },
	[SIGFPE]	= { .handler = handle_exit_signal },
	[SIGBUS]	= { .handler = handle_exit_signal },
	[SIGSEGV]	= { .handler = handle_exit_signal },
	[SIGSYS]	= { .handler = handle_exit_signal },
	[SIGPIPE]	= { .handler = handle_exit_signal },
	[SIGALRM]	= { .handler = handle_exit_signal },
	[SIGTERM]	= { .handler = handle_exit_signal },
	[SIGTSTP]	= { .handler = handle_suspend },
	[SIGCONT]	= {
		.handler = handle_continue,
		.global = &g_event_sigcont,
		.action = action_update_size,
	},
	[SIGTTIN]	= { .handler = handle_exit_signal },
	[SIGTTOU]	= { .handler = handle_exit_signal },
	[SIGXCPU]	= { .handler = handle_exit_signal },
	[SIGXFSZ]	= { .handler = handle_exit_signal },
	[SIGVTALRM]	= { .handler = handle_exit_signal },
	[SIGPROF]	= { .handler = handle_exit_signal },
	[SIGWINCH]	= {
		.global = &g_event_sigwinch,
		.action = action_update_size
	},

#ifdef SIGEMT

	[SIGEMT]	= { .handler = handle_exit_signal },

#endif
};

static void						handle_generic(int signum)
{
	*g_event_signal_map[signum].global = true;
	*g_handle_signal_map[signum].global = true;
}

const t_action	g_event_key_map[READ_TYPE_AMOUNT][128] = {
	[READ_TYPE_REG] = {
		['q'] = action_quit,
		['j'] = action_down,
		['k'] = action_up,
		['h'] = action_left,
		['l'] = action_right,
		[' '] = action_select,
		['\x7f'] = action_delete,
		['\n'] = action_confirm,
	},
	[READ_TYPE_ESC] = {
		['A'] = action_up,
		['B'] = action_down,
		['D'] = action_left,
		['C'] = action_right,
	},
	[READ_TYPE_ESC_SQL] = {
		['3'] = action_delete,
	},
};

t_error							event_init(void)
{
	size_t	signum;

	signum = 0;
	while (signum < sizeof(g_event_signal_map) / sizeof(*g_event_signal_map))
	while (signum < sizeof(g_handle_signal_map) / sizeof(*g_handle_signal_map))
	{
		if (g_event_signal_map[signum].handler)
		if (g_handle_signal_map[signum].handler)
		{
			if (signal(signum, g_event_signal_map[signum].handler) == SIG_ERR)
			if (signal(signum, g_handle_signal_map[signum].handler) == SIG_ERR)
			{
				return (errorf("unable to bind signal %d: %s",
					signum, strerror(errno)));
			}
		}
		else if (g_event_signal_map[signum].action)
		else if (g_handle_signal_map[signum].action)
		{
			if (signal(signum, handle_generic) == SIG_ERR)
			{


@@ 155,13 64,13 @@ static t_action					next_signal(void)
	size_t	signum;

	signum = 0;
	while (signum < sizeof(g_event_signal_map) / sizeof(*g_event_signal_map))
	while (signum < sizeof(g_handle_signal_map) / sizeof(*g_handle_signal_map))
	{
		if (g_event_signal_map[signum].action &&
			*g_event_signal_map[signum].global)
		if (g_handle_signal_map[signum].action &&
			*g_handle_signal_map[signum].global)
		{
			*g_event_signal_map[signum].global = false;
			return (g_event_signal_map[signum].action);
			*g_handle_signal_map[signum].global = false;
			return (g_handle_signal_map[signum].action);
		}
		signum++;
	}


@@ 175,7 84,7 @@ static t_error					next_key(t_action *dest)
	seq = read_seq();
	if (is_error(seq.error))
		return (errorf("failed to read input sequence: %s", seq.error.msg));
	*dest = g_event_key_map[seq.type][(unsigned char)seq.c];
	*dest = g_handle_key_map[seq.type][(unsigned char)seq.c];
	return (ERROR_NULL);
}


A src/handle.c => src/handle.c +114 -0
@@ 0,0 1,114 @@
/* ************************************************************************** */
/*                                                                            */
/*                                                        ::::::::            */
/*   ft_select                                          :+:    :+:            */
/*                                                     +:+                    */
/*   Author: Noah Loomans                             +#+                     */
/*           <nloomans@student.codam.nl>             +#+                      */
/*                                                  #+#    #+#                */
/*   License: GPLv3                                ########   odam.nl         */
/*                                                                            */
/* ************************************************************************** */

#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <stdbool.h>
#include <ft_printf.h>
#include "terminal.h"
#include "handle.h"
#include "read.h"

bool								g_handle_sigwinch = false;
bool								g_handle_sigcont = false;

static void							handle_suspend(int signum)
{
	struct termios attr;

	(void)signum;
	terminal_configure(TERMINAL_CONFIGURE_RESTORE);
	signal(SIGTSTP, SIG_DFL);
	tcgetattr(STDIN_FILENO, &attr);
	ioctl(STDIN_FILENO, TIOCSTI, (char[]){attr.c_cc[VSUSP], '\0'});
}

static void							handle_continue(int signum)
{
	terminal_configure(TERMINAL_CONFIGURE_SETUP);
	signal(SIGTSTP, handle_suspend);
	*g_handle_signal_map[signum].global = true;
}

static void							handle_exit_signal(int signum)
{
	terminal_configure(TERMINAL_CONFIGURE_RESTORE);
	ft_dprintf(STDERR_FILENO, "ft_select: received '%s' signal, exiting...\n",
		sys_siglist[signum]);
	exit(1);
}

const struct s_handle_signal_map	g_handle_signal_map[29] = {
	[SIGHUP]	= { .handler = handle_exit_signal },
	[SIGINT]	= { .handler = handle_exit_signal },
	[SIGQUIT]	= { .handler = handle_exit_signal },
	[SIGILL]	= { .handler = handle_exit_signal },
	[SIGTRAP]	= { .handler = handle_exit_signal },
	[SIGABRT]	= { .handler = handle_exit_signal },
	[SIGFPE]	= { .handler = handle_exit_signal },
	[SIGBUS]	= { .handler = handle_exit_signal },
	[SIGSEGV]	= { .handler = handle_exit_signal },
	[SIGSYS]	= { .handler = handle_exit_signal },
	[SIGPIPE]	= { .handler = handle_exit_signal },
	[SIGALRM]	= { .handler = handle_exit_signal },
	[SIGTERM]	= { .handler = handle_exit_signal },
	[SIGTSTP]	= { .handler = handle_suspend },
	[SIGCONT]	= {
		.handler = handle_continue,
		.global = &g_handle_sigcont,
		.action = action_update_size,
	},
	[SIGTTIN]	= { .handler = handle_exit_signal },
	[SIGTTOU]	= { .handler = handle_exit_signal },
	[SIGXCPU]	= { .handler = handle_exit_signal },
	[SIGXFSZ]	= { .handler = handle_exit_signal },
	[SIGVTALRM]	= { .handler = handle_exit_signal },
	[SIGPROF]	= { .handler = handle_exit_signal },
	[SIGWINCH]	= {
		.global = &g_handle_sigwinch,
		.action = action_update_size
	},

/*
** SIGEMT is not POSIX and doesn't exist on Linux
*/
#ifdef SIGEMT

	[SIGEMT]	= { .handler = handle_exit_signal },

#endif

};

const t_action						g_handle_key_map[READ_TYPE_AMOUNT][256] = {
	[READ_TYPE_REG] = {
		['q'] = action_quit,
		['j'] = action_down,
		['k'] = action_up,
		['h'] = action_left,
		['l'] = action_right,
		[' '] = action_select,
		['\x7f'] = action_delete,
		['\n'] = action_confirm,
	},
	[READ_TYPE_ESC] = {
		['A'] = action_up,
		['B'] = action_down,
		['D'] = action_left,
		['C'] = action_right,
	},
	[READ_TYPE_ESC_SQL] = {
		['3'] = action_delete,
	},
};