termios_speed
[svn42.git] / go / termios / termios.go
1 package termios
2
3 import (
4     "fmt";
5     "os";
6     "syscall";
7     "unsafe"
8     "errors"
9 )
10
11 // termios types
12 type cc_t byte
13 type speed_t uint
14 type tcflag_t uint
15
16 // termios constants
17 const (
18     BRKINT = tcflag_t (0000002)
19     ICRNL = tcflag_t (0000400)
20     INPCK = tcflag_t (0000020)
21     ISTRIP = tcflag_t (0000040)
22     IXON = tcflag_t (0002000)
23     OPOST = tcflag_t (0000001)
24     CS8 = tcflag_t (0000060)
25     ECHO = tcflag_t (0000010)
26     ICANON = tcflag_t (0000002)
27     IEXTEN = tcflag_t (0100000)
28     ISIG = tcflag_t (0000001)
29     VTIME = tcflag_t (5)
30     VMIN = tcflag_t (6)
31 )
32
33 const (
34     B0 = speed_t(0000000)         /* hang up */
35     B50 = speed_t(0000001)
36     B75 = speed_t(0000002)
37     B110 = speed_t(0000003)
38     B134 = speed_t(0000004)
39     B150 = speed_t(0000005)
40     B200 = speed_t(0000006)
41     B300 = speed_t(0000007)
42     B600 = speed_t(0000010)
43     B1200 = speed_t(0000011)
44     B1800 = speed_t(0000012)
45     B2400 = speed_t(0000013)
46     B4800 = speed_t(0000014)
47     B9600 = speed_t(0000015)
48     B19200 = speed_t(0000016)
49     B38400 = speed_t(0000017)
50     B57600 = speed_t(0010001)
51     B115200 = speed_t(0010002)
52     B230400 = speed_t(0010003)
53     B460800 = speed_t(0010004)
54     B500000 = speed_t(0010005)
55     B576000 = speed_t(0010006)
56     B921600 = speed_t(0010007)
57     B1000000 = speed_t(0010010)
58     B1152000 = speed_t(0010011)
59     B1500000 = speed_t(0010012)
60     B2000000 = speed_t(0010013)
61     B2500000 = speed_t(0010014)
62     B3000000 = speed_t(0010015)
63     B3500000 = speed_t(0010016)
64     B4000000 = speed_t(0010017)
65 )
66
67 const NCCS = 32
68 type termios struct {
69     c_iflag, c_oflag, c_cflag, c_lflag tcflag_t;
70     c_line cc_t;
71     c_cc [NCCS]cc_t;
72     c_ispeed, c_ospeed speed_t
73 }
74
75 // ioctl constants
76 const (
77     TCGETS = 0x5401
78     TCSETS = 0x5402
79 )
80
81 var (
82     orig_termios termios;
83     ttyfd uintptr = 0 // STDIN_FILENO
84 )
85
86 func Ttyfd(fd uintptr) {
87   ttyfd=fd
88 }
89
90 func getTermios (dst *termios) error {
91     r1, _, errno := syscall.Syscall (syscall.SYS_IOCTL,
92                                      uintptr (ttyfd), uintptr (TCGETS),
93                                      uintptr (unsafe.Pointer (dst)));
94
95     if err := os.NewSyscallError ("SYS_IOCTL", errno); errno!=0 && err != nil {
96         return err
97     }
98
99     if r1 != 0 {
100     //    return errors.New("Error")
101     }
102
103     return nil
104 }
105
106 func setTermios (src *termios) error {
107     r1, _, errno := syscall.Syscall (syscall.SYS_IOCTL,
108                                      uintptr (ttyfd), uintptr (TCSETS),
109                                      uintptr (unsafe.Pointer (src)));
110
111     if err := os.NewSyscallError ("SYS_IOCTL", errno); errno!=0 &&err != nil {
112         return err
113     }
114
115     if r1 != 0 {
116         return errors.New ("Error")
117     }
118
119     return nil
120 }
121
122 func tty_raw () error {
123     raw := orig_termios;
124
125     raw.c_iflag &= ^(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
126     raw.c_oflag &= ^(OPOST);
127     raw.c_cflag |= (CS8);
128     raw.c_lflag &= ^(ECHO | ICANON | IEXTEN | ISIG);
129
130     raw.c_cc[VMIN] = 1;
131     raw.c_cc[VTIME] = 0;
132
133     if err := setTermios (&raw); err != nil { return err }
134
135     return nil
136 }
137
138 func SetRaw () {
139     var (
140         err error
141     )
142
143     defer func () {
144         if err != nil { fmt.Printf ("SetRaw Error: %v\n",err) }
145     } ();
146
147     if err = getTermios (&orig_termios); err != nil { return }
148
149 //    defer func () {
150 //        err = setTermios (&orig_termios)
151 //    } ();
152
153     if err = tty_raw (); err != nil { return }
154     //if err = screenio (); err != nil { return }
155 }
156
157 func SetSpeed (speed speed_t) {
158     var err error
159
160     defer func () {
161         if err != nil { fmt.Printf ("SetSpeed Error: %v\n",err) }
162     } ();
163
164     if err = getTermios (&orig_termios); err != nil { return }
165     orig_termios.c_ispeed = speed
166     orig_termios.c_ospeed = speed
167     err = setTermios (&orig_termios)
168 }