Avoid TTY cursor blinking

Fixes: #26
This commit is contained in:
Johannes Marbach
2022-01-27 20:03:10 +01:00
parent f7217fc841
commit 00b5d83599
4 changed files with 161 additions and 4 deletions

30
main.c
View File

@@ -23,6 +23,7 @@
#include "indev.h"
#include "log.h"
#include "unl0kr.h"
#include "terminal.h"
#include "theme.h"
#include "themes.h"
@@ -32,6 +33,7 @@
#include "squeek2lvgl/sq2lv.h"
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -170,7 +172,14 @@ static void textarea_ready_cb(lv_event_t *event);
*
* @param textarea the textarea widget
*/
static void finish(lv_obj_t *textarea);
static void print_password_and_exit(lv_obj_t *textarea);
/**
* Handle termination signals sent to the process.
*
* @param signum the signal's number
*/
static void sigaction_handler(int signum);
/**
@@ -280,15 +289,20 @@ static void keyboard_value_changed_cb(lv_event_t *event) {
}
static void keyboard_ready_cb(lv_event_t *event) {
finish(lv_keyboard_get_textarea(lv_event_get_target(event)));
print_password_and_exit(lv_keyboard_get_textarea(lv_event_get_target(event)));
}
static void textarea_ready_cb(lv_event_t *event) {
finish(lv_event_get_target(event));
print_password_and_exit(lv_event_get_target(event));
}
static void finish(lv_obj_t *textarea) {
static void print_password_and_exit(lv_obj_t *textarea) {
printf("%s\n", lv_textarea_get_text(textarea));
sigaction_handler(SIGTERM);
}
static void sigaction_handler(int signum) {
ul_terminal_reset_current_terminal();
exit(0);
}
@@ -312,6 +326,14 @@ int main(int argc, char *argv[]) {
/* Parse config files */
ul_config_parse(cli_opts.config_files, cli_opts.num_config_files, &conf_opts);
/* Prepare current TTY and clean up on termination */
ul_terminal_prepare_current_terminal();
struct sigaction action;
memset(&action, 0, sizeof(action));
action.sa_handler = sigaction_handler;
sigaction(SIGINT, &action, NULL);
sigaction(SIGTERM, &action, NULL);
/* Initialise LVGL and set up logging callback */
lv_init();
lv_log_register_print_cb(ul_log_print_cb);

View File

@@ -35,6 +35,7 @@ unl0kr_sources = [
'log.c',
'main.c',
'sq2lv_layouts.c',
'terminal.c',
'theme.c',
'themes.c'
]

100
terminal.c Normal file
View File

@@ -0,0 +1,100 @@
/**
* Copyright 2021 Johannes Marbach
*
* This file is part of unl0kr, hereafter referred to as the program.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "terminal.h"
#include "log.h"
#include <fcntl.h>
#include <stdbool.h>
#include <unistd.h>
#include <linux/kd.h>
#include <sys/ioctl.h>
/**
* Static variables
*/
static int current_fd = -1;
/**
* Static prototypes
*/
/**
* Close the current file descriptor and reopen /dev/tty0.
*
* @return true if opening was successful, false otherwise
*/
static bool reopen_current_terminal(void);
/**
* Close the current file descriptor.
*/
static void close_current_terminal(void);
/**
* Static functions
*/
static bool reopen_current_terminal(void) {
close_current_terminal();
current_fd = open("/dev/tty0", O_RDWR);
if (current_fd < 0) {
ul_log(UL_LOG_LEVEL_WARNING, "Could not open /dev/tty0");
return false;
}
return true;
}
static void close_current_terminal(void) {
if (current_fd < 0) {
return;
}
close(current_fd);
current_fd = -1;
}
/**
* Public functions
*/
void ul_terminal_prepare_current_terminal(void) {
reopen_current_terminal();
if (current_fd < 0 || ioctl(current_fd, KDSETMODE, KD_GRAPHICS) != 0) {
ul_log(UL_LOG_LEVEL_WARNING, "Could not set current terminal to graphics mode");
}
}
void ul_terminal_reset_current_terminal(void) {
if (current_fd < 0 || ioctl(current_fd, KDSETMODE, KD_TEXT) != 0) {
ul_log(UL_LOG_LEVEL_WARNING, "Could not reset current terminal to text mode");
}
close_current_terminal();
}

34
terminal.h Normal file
View File

@@ -0,0 +1,34 @@
/**
* Copyright 2021 Johannes Marbach
*
* This file is part of unl0kr, hereafter referred to as the program.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef UL_TERMINAL_H
#define UL_TERMINAL_H
/**
* Prepare the current TTY for graphics output.
*/
void ul_terminal_prepare_current_terminal(void);
/**
* Reset the current TTY to text output.
*/
void ul_terminal_reset_current_terminal(void);
#endif /* UL_TERMINAL_H */