1 /**
2  * Consoleur: a package for interaction with character-oriented terminal emulators
3  *
4  * Copyright: Maxim Freck, 2017.
5  * Authors:   Maxim Freck <maxim@freck.pp.ru>
6  * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7  */
8 module consoleur.core.termparam;
9 version(Posix) {
10 
11 import consoleur.core: STDIN_FILENO;
12 
13 ///Terminal parameters
14 enum Term: uint {
15 	quiet = 0b00000000_00000000_00000000_00000001,
16 	raw = 0b00000000_00000000_00000000_00000010,
17 	async = 0b00000000_00000000_00000000_00000100,
18 }
19 
20 /*******
21  * Structure with saved terminal parameters.
22  * Restores parameters during destruction.
23  */
24 struct SavedTermparam
25 {
26 	private import core.sys.posix.termios: TCSANOW, tcsetattr, termios;
27 
28 	private termios tsave = {};
29 	private bool restore = false;
30 
31 	///constructor
32 	this(bool r, termios s) @safe
33 	{
34 		tsave = s;
35 		restore = r;
36 	}
37 
38 	~this() @safe
39 	{
40 		restoreBack();
41 	}
42 
43 	/*******
44 	* Restores back previously saved terminal parameters
45 	*/
46 	void restoreBack() @trusted
47 	{
48 		if (restore) {
49 			tcsetattr(STDIN_FILENO, TCSANOW, &tsave);
50 			restore = false;
51 		}
52 	}
53 }
54 
55 /*******
56  * Sets new terminal parameters
57  *
58  * Returns: Structure with saved previous parameter set
59  */
60 SavedTermparam setTermparam(uint flags = 0, ubyte delay = 0) @trusted
61 {
62 	import core.sys.posix.termios: ECHO, ICANON, tcgetattr, TCSANOW, tcsetattr, termios, VMIN, VTIME;
63 
64 	termios told;
65 	termios tnew;
66 
67 	tcgetattr(STDIN_FILENO, &told);
68 	tnew = told;
69 
70 	if (flags & Term.quiet) {
71 		tnew.c_lflag &= ~ECHO;
72 	} else {
73 		tnew.c_lflag |= ECHO;
74 	}
75 
76 	if (flags & Term.raw) {
77 		tnew.c_lflag &= ~ICANON;
78 	} else {
79 		tnew.c_lflag |= ICANON;
80 	}
81 
82 	if (flags & Term.async) {
83 		tnew.c_cc[VMIN] = 0;
84 		tnew.c_cc[VTIME] = delay;
85 	} else {
86 		tnew.c_cc[VMIN] = 1;
87 		tnew.c_cc[VTIME] = 0;
88 	}
89 	
90 	if (tnew != told) {
91 		tcsetattr(STDIN_FILENO, TCSANOW, &tnew);
92 		return SavedTermparam(true, told);
93 	}
94 
95 	return SavedTermparam(false, told);
96 }
97 
98 }