minishell/line/src/line_internals.c
2024-07-30 17:14:34 +02:00

120 lines
3.4 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* line_internals.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/11 18:18:46 by maiboyer #+# #+# */
/* Updated: 2024/07/30 17:08:24 by rparodi ### ########.fr */
/* */
/* ************************************************************************** */
#include "line/_line_functions.h"
#include "line/_line_internal.h"
#include "line/_line_structs.h"
#include "me/printf/printf.h"
#include "me/types.h"
#include <sys/ioctl.h>
#include <errno.h>
/* ======================= Low level terminal handling ====================== */
/* Use the ESC [6n escape sequence to query the horizontal cursor position
* and return it. On error -1 is returned, on success the position of the
* cursor. */
/*t_error line_get_cursor_position( \
t_fd *input, t_fd *output, t_u32 *column_out)
{
char buf[32];
t_u32 i;
t_i32 cols;
t_i32 rows;
i = 0;
if (write_fd(output, (t_u8 *)"\x1b[6n", 4, NULL))
return (ERROR);
while (i < sizeof(buf) - 1)
{
if (read_fd(input, (t_u8 *)(buf + i), 1, NULL))
break ;
if (buf[i] == 'R')
break ;
i++;
}
buf[i] = '\0';
if (buf[0] != K_ESC && buf[1] != '[')
return (ERROR);
if (sscanf(buf + 2, "%d;%d", &rows, &cols) != 2)
return (ERROR);
return (*column_out = cols, NO_ERROR);
}
*/
/* Try to get the number of columns in the current terminal, or assume 80
* if it fails. */
/*
// This was inside the if body
t_u32 cols;
t_u32 start;
if (line_get_cursor_position(input, output, &start))
return (80);
me_printf_fd(output, "\x1b[999C");
if (line_get_cursor_position(input, output, &cols))
return (80);
if (cols > start)
me_printf_fd(output, "\x1b[%dD", cols - start);
*/
t_u32 line_get_columns(t_fd *input, t_fd *output)
{
struct winsize ws;
(void)(input);
(void)(output);
if (ioctl(1, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0)
{
return (80);
}
else
return (ws.ws_col);
}
/* Clear the screen. Used to handle ctrl+l */
void line_clear_screen(t_fd *output)
{
me_printf_fd(output, "\x1b[H\x1b[2J");
}
/* Raw mode: 1960 magic shit. */
t_error line_enable_raw_mode(t_fd *fd)
{
struct termios raw;
t_raw_mode_state *raw_state;
raw_state = get_raw_mode_state();
if (!isatty(fd->fd))
return (errno = ENOTTY, ERROR);
if (tcgetattr(fd->fd, &raw_state->state) == -1)
return (errno = ENOTTY, ERROR);
raw = raw_state->state;
raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
raw.c_oflag &= ~(OPOST);
raw.c_cflag |= (CS8);
raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
raw.c_cc[VMIN] = 1;
raw.c_cc[VTIME] = 0;
if (tcsetattr(fd->fd, TCSAFLUSH, &raw) < 0)
return (errno = ENOTTY, ERROR);
raw_state->enabled = true;
return (NO_ERROR);
}
void line_disable_raw_mode(t_fd *fd)
{
t_raw_mode_state *state;
state = get_raw_mode_state();
if (state->enabled && tcsetattr(fd->fd, TCSAFLUSH, &state->state) != -1)
state->enabled = false;
}