bug_16190 fixed
[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 #include "scilines.h"
27
28 static void canonicMode(struct termios *t)
29 {
30     t->c_lflag |= ICANON;       /* Set CANON flag */
31     t->c_lflag |= ECHO;         /* Print character when a key is pressed */
32 }
33
34 static void rawMode(struct termios *t)
35 {
36     t->c_lflag &= ~ICANON;      /* take off CANON flag */
37     t->c_lflag &= ~ECHO;        /* Do not print character when a key is pressed */
38     t->c_cc[VMIN] = 1;          /* Wait 1 charater before leaving getwchar */
39     t->c_cc[VTIME] = 0;         /* Wait 0 second before leaving getwchar */
40 }
41
42 /* Save Shell Attribute To reset it when exit */
43 static void saveAndResetShellAttr(struct termios *shellAttr)
44 {
45     static struct termios *savedAttr = NULL;
46
47     if (savedAttr == NULL && shellAttr != NULL)
48     {
49         savedAttr = MALLOC(sizeof(*savedAttr));
50         *savedAttr = *shellAttr;
51     }
52     else if (shellAttr == NULL && savedAttr != NULL)
53     {
54         if (tcsetattr(0, TCSAFLUSH, savedAttr) == -1)
55         {
56             fprintf(stderr, "Cannot reset the shell attributes: %s\n", strerror(errno));
57         }
58         FREE(savedAttr);
59         savedAttr = NULL;
60     }
61 }
62
63 static void saveShellAttr(struct termios *shellAttr)
64 {
65     saveAndResetShellAttr(shellAttr);
66 }
67
68 static void resetShellAttr(void)
69 {
70     saveAndResetShellAttr(NULL);
71 }
72
73 /* Set Raw mode or Canonic Mode */
74 int setAttr(int bin)
75 {
76     struct termios shellAttr;
77
78     if (getCLIColor() == FALSE)
79     {
80         return 0;
81     }
82
83     if (bin == ATTR_RESET)
84     {
85         resetShellAttr();
86         return 0;
87     }
88     if (tcgetattr(0, &shellAttr) == -1)
89     {
90         fprintf(stderr, "Cannot access to the term attributes: %s\n", strerror(errno));
91         return -1;
92     }
93     saveShellAttr(&shellAttr);
94     if (bin == CANON)
95     {
96         canonicMode(&shellAttr);
97     }
98     else if (bin == RAW)
99     {
100         rawMode(&shellAttr);
101     }
102     if (tcsetattr(0, TCSAFLUSH, &shellAttr) == -1)
103     {
104         fprintf(stderr, "Cannot change the term attributes: %s\n", strerror(errno));
105         return -1;
106     }
107     return 0;
108 }
109
110 /* Initialise console mode */
111 int initConsoleMode(int bin)
112 {
113     /* TODO: Check more term */
114     if (tgetent(NULL, getenv("TERM")) == ERR && tgetent(NULL, "xterm") == ERR)
115     {
116         fprintf(stderr, "Cannot initialise termcaps.\nPlease check your variable TERM in your environment.\n");
117         return -1;
118     }
119
120     if (!isatty(fileno(stdin)))
121     {
122         /* We are in a pipe, no need to init the console */
123         return 0;
124     }
125
126     // set default lines at startup
127     scilinesdefault();
128
129     return setAttr(bin);
130 }