3410ee9d8346f95e32c4995367ee7411da8cd7c0
[scilab.git] / scilab / modules / console / src / c / cmdLine / initConsoleMode.c
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2011 - DIGITEO - Karim Mamode
4 *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13 */
14
15 #include <termios.h>
16 #include <curses.h>
17 #include <term.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <errno.h>
23 #include "sci_malloc.h"
24 #include "cliDisplayManagement.h"
25 #include "initConsoleMode.h"
26
27 static void canonicMode(struct termios *t)
28 {
29     t->c_lflag |= ICANON;       /* Set CANON flag */
30     t->c_lflag |= ECHO;         /* Print character when a key is pressed */
31 }
32
33 static void rawMode(struct termios *t)
34 {
35     t->c_lflag &= ~ICANON;      /* take off CANON flag */
36     t->c_lflag &= ~ECHO;        /* Do not print character when a key is pressed */
37     t->c_cc[VMIN] = 1;          /* Wait 1 charater before leaving getwchar */
38     t->c_cc[VTIME] = 0;         /* Wait 0 second before leaving getwchar */
39 }
40
41 /* Save Shell Attribute To reset it when exit */
42 static void saveAndResetShellAttr(struct termios *shellAttr)
43 {
44     static struct termios *savedAttr = NULL;
45
46     if (savedAttr == NULL && shellAttr != NULL)
47     {
48         savedAttr = MALLOC(sizeof(*savedAttr));
49         *savedAttr = *shellAttr;
50     }
51     else if (shellAttr == NULL && savedAttr != NULL)
52     {
53         if (tcsetattr(0, TCSAFLUSH, savedAttr) == -1)
54         {
55             fprintf(stderr, "Cannot reset the shell attributes: %s\n", strerror(errno));
56         }
57         FREE(savedAttr);
58         savedAttr = NULL;
59     }
60 }
61
62 static void saveShellAttr(struct termios *shellAttr)
63 {
64     saveAndResetShellAttr(shellAttr);
65 }
66
67 static void resetShellAttr(void)
68 {
69     saveAndResetShellAttr(NULL);
70 }
71
72 /* Set Raw mode or Canonic Mode */
73 int setAttr(int bin)
74 {
75     struct termios shellAttr;
76
77     if (getCLIColor() == FALSE)
78     {
79         return 0;
80     }
81
82     if (bin == ATTR_RESET)
83     {
84         resetShellAttr();
85         return 0;
86     }
87     if (tcgetattr(0, &shellAttr) == -1)
88     {
89         fprintf(stderr, "Cannot access to the term attributes: %s\n", strerror(errno));
90         return -1;
91     }
92     saveShellAttr(&shellAttr);
93     if (bin == CANON)
94     {
95         canonicMode(&shellAttr);
96     }
97     else if (bin == RAW)
98     {
99         rawMode(&shellAttr);
100     }
101     if (tcsetattr(0, TCSAFLUSH, &shellAttr) == -1)
102     {
103         fprintf(stderr, "Cannot change the term attributes: %s\n", strerror(errno));
104         return -1;
105     }
106     return 0;
107 }
108
109 /* Initialise console mode */
110 int initConsoleMode(int bin)
111 {
112     /* TODO: Check more term */
113     if (tgetent(NULL, getenv("TERM")) == ERR && tgetent(NULL, "xterm") == ERR)
114     {
115         fprintf(stderr, "Cannot initialise termcaps.\nPlease check your variable TERM in your environment.\n");
116         return -1;
117     }
118
119     if (!isatty(fileno(stdin)))
120     {
121         /* We are in a pipe, no need to init the console */
122         return 0;
123     }
124
125     return setAttr(bin);
126 }