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 @note - captures terminal settings for stdin, stdout, and stderr */
45 return true;
46 tcgetattr(0, &shell_in_tioctl);
47 tcgetattr(1, &shell_out_tioctl);
48 tcgetattr(2, &shell_err_tioctl);
50 return true;
51}
52/** @brief restore_shell_tioctl() - restore shell terminal settings
53 @ingroup screen_io
54 @return - true on success
55 @note - restores terminal settings for stdin, stdout, and stderr */
58 return false;
59 tcsetattr(0, TCSANOW, &shell_in_tioctl);
60 tcsetattr(1, TCSANOW, &shell_out_tioctl);
61 tcsetattr(2, TCSANOW, &shell_err_tioctl);
62 return true;
63}
64/** @brief capture_curses_tioctl() - capture curses terminal settings
65 @ingroup screen_io
66 @return - true on success
67 @note - captures terminal settings for stdin, stdout, and stderr */
70 return true;
71 tcgetattr(0, &curses_in_tioctl);
72 tcgetattr(1, &curses_out_tioctl);
73 tcgetattr(2, &curses_err_tioctl);
75 return true;
76}
77/** @brief restore_curses_tioctl() - restore curses terminal settings
78 @ingroup screen_io
79 @return - true on success
80 @note - restores terminal settings for stdin, stdout, and stderr */
83 return false;
84 tcsetattr(0, TCSANOW, &curses_in_tioctl);
85 tcsetattr(1, TCSANOW, &curses_out_tioctl);
86 tcsetattr(2, TCSANOW, &curses_err_tioctl);
87
88 return true;
89}
90/** @brief set_sane_tioctl() - set terminal to sane settings for C-MENU
91 @ingroup screen_io
92 @param t_p - pointer to termios structure to modify
93 @return - true on success
94 @note - sets terminal to sane settings for C-MENU applications */
95bool set_sane_tioctl(struct termios *t_p) {
96 tcgetattr(0, t_p);
97 t_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | INPCK | ISTRIP | INLCR |
98 IGNCR | ICRNL | IXON | IXOFF);
99 t_p->c_iflag |= IUTF8;
100 t_p->c_oflag |= OPOST | ONLCR;
101 t_p->c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN);
102 t_p->c_lflag |= (ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK);
103 t_p->c_cflag &= ~(CSIZE | PARENB);
104 t_p->c_cflag |= CS8 | CLOCAL | CREAD;
105 tcsetattr(0, TCSANOW, t_p);
106 return true;
107}
108/** @brief mk_raw_tioctl() - set terminal to raw mode
109 @ingroup screen_io
110 @param t_p - pointer to termios structure to modify
111 @return - true on success
112 @note - unlike cfmakeraw(), this leaves ISIG enabled.
113 @note - cfmakeraw() disables ISIG, which prevents C-MENU from handling
114 signals like Ctrl-C. Instead of using cfmakeraw(), we manually set the
115 terminal to raw mode while leaving ISIG enabled.
116 @note - the following code is equivalent to cfmakeraw() but with ISIG left
117 enabled:
118 @code
119 t_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | INPCK | ISTRIP | INLCR |
120 IGNCR | ICRNL | IXON | IXOFF);
121 t_p->c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN);
122 t_p->c_cflag &= ~(CSIZE | PARENB);
123 t_p->c_cflag |= CS8 | CLOCAL;
124 @endcode
125 */
126bool mk_raw_tioctl(struct termios *t_p) {
127 tcgetattr(0, t_p);
128 t_p->c_lflag |= ISIG;
129 t_p->c_lflag &= ~(ECHO | ICANON);
130 t_p->c_cc[VMIN] = 1;
131 t_p->c_cc[VTIME] = 0;
132 tcsetattr(0, TCSAFLUSH, t_p);
133 return true;
134}
135/** @brief sget single character from terminal in raw mode
136 @ingroup screen_io
137 @return - the character read from terminal
138 @note restores terminal settings */
139char di_getch() {
140 struct termios org_tioctl, new_tioctl;
141 char buf;
142
143 if (tcgetattr(2, &org_tioctl) == -1) {
144 fprintf(stderr, "\ndi_getch: tcgetattr failed\n");
145 return (0);
146 }
147 new_tioctl = org_tioctl;
148 new_tioctl.c_lflag &= ~(ECHO | ICANON);
149 new_tioctl.c_cc[VMIN] = 1;
150 new_tioctl.c_cc[VTIME] = 0;
151 tcsetattr(2, TCSAFLUSH, &new_tioctl);
152 read(2, &buf, 1);
153 tcsetattr(2, TCSAFLUSH, &org_tioctl);
154 return (buf);
155}
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()
sget single character from terminal in raw mode
Definition scriou.c:139
bool restore_curses_tioctl()
restore_curses_tioctl() - restore curses terminal settings
Definition scriou.c:81
bool capture_curses_tioctl()
capture_curses_tioctl() - capture curses terminal settings
Definition scriou.c:68
bool mk_raw_tioctl(struct termios *)
mk_raw_tioctl() - set terminal to raw mode
Definition scriou.c:126
bool set_sane_tioctl(struct termios *)
set_sane_tioctl() - set terminal to sane settings for C-MENU
Definition scriou.c:95
bool restore_shell_tioctl()
restore_shell_tioctl() - restore shell terminal settings
Definition scriou.c:56