C-Menu 0.2.9
A User Interface Toolkit
Loading...
Searching...
No Matches
scriou.c
Go to the documentation of this file.
1/** @file scriou.c
2 @brief Screen IO Support for MENU
3 @author Bill Waller
4 Copyright (c) 2025
5 MIT License
6 billxwaller@gmail.com
7 @date 2026-02-09
8 */
9
10/** Terminal Handling
11 @defgroup screen_io Screen IO Support
12 @brief Provides Terminal Settings for C-MENU Applications and Restores
13 Terminal State on Exit
14 */
15
16#include "cm.h"
17#include <stdbool.h>
18#include <stdio.h>
19#include <termios.h>
20#include <unistd.h>
21
22struct termios shell_tioctl;
23struct termios curses_tioctl;
30bool set_sane_tioctl(struct termios *);
31bool mk_raw_tioctl(struct termios *);
32char di_getch();
33
35struct termios shell_in_tioctl, curses_in_tioctl;
36struct termios shell_out_tioctl, curses_out_tioctl;
37struct termios shell_err_tioctl, curses_err_tioctl;
38
39/** @brief capture_shell_tioctl() - capture shell terminal settings
40 @ingroup screen_io
41 @return - true on success
42 @details - captures terminal settings for stdin, stdout, and stderr */
45 return true;
46 fflush(NULL);
47 tcgetattr(0, &shell_in_tioctl);
48 tcgetattr(1, &shell_out_tioctl);
49 tcgetattr(2, &shell_err_tioctl);
51 return true;
52}
53/** @brief restore_shell_tioctl() - restore shell terminal settings
54 @ingroup screen_io
55 @return - true on success
56 @details - restores terminal settings for stdin, stdout, and stderr */
59 return false;
60 fflush(NULL);
61 tcsetattr(0, TCSANOW, &shell_in_tioctl);
62 tcsetattr(1, TCSANOW, &shell_out_tioctl);
63 tcsetattr(2, TCSANOW, &shell_err_tioctl);
64 return true;
65}
66/** @brief capture_curses_tioctl() - capture curses terminal settings
67 @ingroup screen_io
68 @return - true on success
69 @details - captures terminal settings for stdin, stdout, and stderr */
72 return true;
73 fflush(NULL);
74 tcgetattr(0, &curses_in_tioctl);
75 tcgetattr(1, &curses_out_tioctl);
76 tcgetattr(2, &curses_err_tioctl);
78 return true;
79}
80/** @brief restore_curses_tioctl() - restore curses terminal settings
81 @ingroup screen_io
82 @return - true on success
83 @details - restores terminal settings for stdin, stdout, and stderr */
86 return false;
87 fflush(NULL);
88 tcsetattr(0, TCSANOW, &curses_in_tioctl);
89 tcsetattr(1, TCSANOW, &curses_out_tioctl);
90 tcsetattr(2, TCSANOW, &curses_err_tioctl);
91
92 return true;
93}
94/** @brief set_sane_tioctl() - set terminal to sane settings for C-MENU
95 @ingroup screen_io
96 @param t_p - pointer to termios structure to modify
97 @return - true on success
98 @details - sets terminal to sane settings for C-MENU applications */
99bool set_sane_tioctl(struct termios *t_p) {
100 fflush(NULL);
101 tcgetattr(0, t_p);
102 t_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | INPCK | ISTRIP | INLCR |
103 IGNCR | ICRNL | IXON | IXOFF);
104 t_p->c_iflag |= IUTF8;
105 t_p->c_oflag |= OPOST | ONLCR;
106 t_p->c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN);
107 t_p->c_lflag |= (ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK);
108 t_p->c_cflag &= ~(CSIZE | PARENB);
109 t_p->c_cflag |= CS8 | CLOCAL | CREAD;
110 fflush(NULL);
111 tcsetattr(0, TCSANOW, t_p);
112 return true;
113}
114/** @brief mk_raw_tioctl() - set terminal to raw mode
115 @ingroup screen_io
116 @param t_p - pointer to termios structure to modify
117 @return - true on success
118 @details - unlike cfmakeraw(), this leaves ISIG enabled.
119 cfmakeraw() disables ISIG, which prevents C-MENU from handling
120 signals like Ctrl-C. Instead of using cfmakeraw(), we manually set the
121 terminal to raw mode while leaving ISIG enabled.
122 The following code is equivalent to cfmakeraw() but with ISIG left
123 enabled:
124 @code
125 t_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | INPCK | ISTRIP | INLCR |
126 IGNCR | ICRNL | IXON | IXOFF);
127 t_p->c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN);
128 t_p->c_cflag &= ~(CSIZE | PARENB);
129 t_p->c_cflag |= CS8 | CLOCAL;
130 @endcode
131 */
132bool mk_raw_tioctl(struct termios *t_p) {
133 fflush(NULL);
134 tcgetattr(0, t_p);
135 t_p->c_lflag |= ISIG;
136 t_p->c_lflag &= ~(ECHO | ICANON);
137 t_p->c_cc[VMIN] = 1;
138 t_p->c_cc[VTIME] = 0;
139 fflush(NULL);
140 tcsetattr(0, TCSAFLUSH, t_p);
141 fflush(NULL);
142 tcgetattr(2, t_p);
143 t_p->c_lflag |= ISIG;
144 t_p->c_lflag &= ~(ECHO | ICANON);
145 t_p->c_cc[VMIN] = 1;
146 t_p->c_cc[VTIME] = 0;
147 fflush(NULL);
148 tcsetattr(2, TCSAFLUSH, t_p);
149 return true;
150}
151/** @brief get single character from terminal in raw mode
152 @ingroup screen_io
153 @return - the character read from terminal
154 @details intended to be used when curses is not active
155 @note restores terminal settings before returning
156
157 */
158char di_getch() {
159 struct termios org_tioctl, new_tioctl;
160 char buf;
161
162 fflush(NULL);
163 if (tcgetattr(2, &org_tioctl) == -1) {
164 fprintf(stderr, "\ndi_getch: tcgetattr failed\n");
165 return (0);
166 }
167 new_tioctl = org_tioctl;
168 new_tioctl.c_lflag &= ~(ECHO | ICANON);
169 new_tioctl.c_cc[VMIN] = 1;
170 new_tioctl.c_cc[VTIME] = 0;
171 fflush(NULL);
172 tcsetattr(2, TCSAFLUSH, &new_tioctl);
173 read(2, &buf, 1);
174 fflush(NULL);
175 tcsetattr(2, TCSAFLUSH, &org_tioctl);
176 return (buf);
177}
bool f_have_shell_tioctl
Definition scriou.c:24
struct termios shell_tioctl curses_tioctl
Definition scriou.c:34
bool f_have_curses_tioctl
Definition scriou.c:25
struct termios shell_out_tioctl curses_out_tioctl
Definition scriou.c:36
struct termios shell_in_tioctl curses_in_tioctl
Definition scriou.c:35
struct termios shell_err_tioctl curses_err_tioctl
Definition scriou.c:37
struct termios shell_tioctl
Definition scriou.c:22
bool capture_shell_tioctl()
capture_shell_tioctl() - capture shell terminal settings
Definition scriou.c:43
char di_getch()
get single character from terminal in raw mode
Definition scriou.c:158
bool restore_curses_tioctl()
restore_curses_tioctl() - restore curses terminal settings
Definition scriou.c:84
bool capture_curses_tioctl()
capture_curses_tioctl() - capture curses terminal settings
Definition scriou.c:70
bool mk_raw_tioctl(struct termios *)
mk_raw_tioctl() - set terminal to raw mode
Definition scriou.c:132
bool set_sane_tioctl(struct termios *)
set_sane_tioctl() - set terminal to sane settings for C-MENU
Definition scriou.c:99
bool restore_shell_tioctl()
restore_shell_tioctl() - restore shell terminal settings
Definition scriou.c:57