#ifndef _TERMIOS_H
#define _TERMIOS_H

#define TTY_BUF_SIZE 1024	// tty еĻȡ

/* 0x54 is just a magic number to make these relatively uniqe ('T') */
/* 0x54 ֻһħĿΪʹЩΨһ('T') */

// tty 豸ioctl ioctl ڵλС
// TC[*]ĺtty 
// ȡӦնtermios ṹеϢ(μtcgetattr())
#define TCGETS 0x5401
// Ӧնtermios ṹеϢ(μtcsetattr()TCSANOW)
#define TCSETS 0x5402
// նtermios Ϣ֮ǰҪȵȴݴ(ľ)޸Ĳ
// ӰҪʹʽ(μtcsetattr()TCSADRAIN ѡ)
#define TCSETSW 0x5403
// termios Ϣ֮ǰҪȵȴݴ꣬ˢ()С
// ãμtcsetattr()TCSAFLUSH ѡ
#define TCSETSF 0x5404
// ȡӦնtermio ṹеϢ(μtcgetattr())
#define TCGETA 0x5405
// Ӧնtermio ṹеϢ(μtcsetattr()TCSANOW ѡ)
#define TCSETA 0x5406
// նtermio Ϣ֮ǰҪȵȴݴ(ľ)޸Ĳ
// ӰҪʹʽ(μtcsetattr()TCSADRAIN ѡ)
#define TCSETAW 0x5407
// termio Ϣ֮ǰҪȵȴݴ꣬ˢ()С
// ãμtcsetattr()TCSAFLUSH ѡ
#define TCSETAF 0x5408
// ȴд()ֵ0һbreakμtcsendbreak()tcdrain()
#define TCSBRK 0x5409
// ʼ/ֹͣơֵ01¿2
// 룻3¿루μtcflow()
#define TCXONC 0x540A
//ˢдûͻյûжݡ0ˢ()У1
// ˢУ2ˢУμtcflush()
#define TCFLSH 0x540B
// TIOC[*]ĺtty 
// ն˴·רģʽ
#define TIOCEXCL 0x540C
// λն˴·רģʽ
#define TIOCNXCL 0x540D
// tty Ϊնˡ(TIOCNOTTY - ֹtty Ϊն)
#define TIOCSCTTY 0x540E
// ȡָն豸̵id(μtcgetpgrp())
#define TIOCGPGRP 0x540F
// ָն豸̵id(μtcsetpgrp())
#define TIOCSPGRP 0x5410
// лδͳַ
#define TIOCOUTQ 0x5411
// ģն롣һַָָΪװַնϼġû
// ڸÿնϾгûȨ޻жȨޡ
#define TIOCSTI 0x5412
// ȡն豸ڴСϢμwinsize ṹ
#define TIOCGWINSZ 0x5413
// ն豸ڴСϢμwinsize ṹ
#define TIOCSWINSZ 0x5414
// modem ״̬ߵĵǰ״̬λ־μ185-196 У
#define TIOCMGET 0x5415
// õmodem ״̬ߵ״̬(true false)(Individual control line Set)
#define TIOCMBIS 0x5416
// λmodem ״̬ߵ״̬(Individual control line clear)
#define TIOCMBIC 0x5417
// modem ״̬ߵ״̬ĳһλλmodem Ӧ״̬߽ΪЧ
#define TIOCMSET 0x5418
// ȡز־(1 - 0 - ر)
// ڱӵն˻豸ز־ǿģʹmodem ·ն˻豸
// ǹرյġΪʹioctl ãtty ·ӦO_NDELAY ʽ򿪵ģopen()
// Ͳȴز
#define TIOCGSOFTCAR 0x5419
// ز־(1 - 0 - ر)
#define TIOCSSOFTCAR 0x541A
// лδȡַĿ
#define TIOCINQ 0x541B

// ڴС(Window size)ԽṹڴڻпڻĻӦó
// ioctls еTIOCGWINSZ TIOCSWINSZ ȡЩϢ
struct winsize
{
  unsigned short ws_row;	// ַ
  unsigned short ws_col;	// ַ
  unsigned short ws_xpixel;	// ڿȣֵ
  unsigned short ws_ypixel;	// ڸ߶ȣֵ
};

// AT&T ϵͳV termio ṹ
#define NCC 8			// termio ṹпַĳȡ
struct termio
{
  unsigned short c_iflag;	/* input mode flags */// ģʽ־
  unsigned short c_oflag;	/* output mode flags */// ģʽ־
  unsigned short c_cflag;	/* control mode flags */// ģʽ־
  unsigned short c_lflag;	/* local mode flags */// ģʽ־
  unsigned char c_line;		/* line discipline */// ·̣ʣ
  unsigned char c_cc[NCC];	/* control characters */// ַ顣
};

// POSIX termios ṹ
#define NCCS 17			// termios ṹпַĳȡ
struct termios
{
  unsigned long c_iflag;	/* input mode flags */// ģʽ־
  unsigned long c_oflag;	/* output mode flags */// ģʽ־
  unsigned long c_cflag;	/* control mode flags */// ģʽ־
  unsigned long c_lflag;	/* local mode flags */// ģʽ־
  unsigned char c_line;		/* line discipline */// ·̣ʣ
  unsigned char c_cc[NCCS];	/* control characters */// ַ顣
};

/* c_cc characters *//* c_cc еַ */
// c_cc Ӧֵַ
#define VINTR 0			// c_cc[VINTR] = INTR (^C)\003жַ
#define VQUIT 1			// c_cc[VQUIT] = QUIT (^\)\034˳ַ
#define VERASE 2		// c_cc[VERASE] = ERASE (^H)\177ַ
#define VKILL 3			// c_cc[VKILL] = KILL (^U)\025ַֹ
#define VEOF 4			// c_cc[VEOF] = EOF (^D)\004ļַ
#define VTIME 5			// c_cc[VTIME] = TIME (\0)\0 ʱֵ(μ˵)
#define VMIN 6			// c_cc[VMIN] = MIN (\1)\1 ʱֵ
#define VSWTC 7			// c_cc[VSWTC] = SWTC (\0)\0 ַ
#define VSTART 8		// c_cc[VSTART] = START (^Q)\021ʼַ
#define VSTOP 9			// c_cc[VSTOP] = STOP (^S)\023ַֹͣ
#define VSUSP 10		// c_cc[VSUSP] = SUSP (^Z)\032ַ
#define VEOL 11			// c_cc[VEOL] = EOL (\0)\0 нַ
#define VREPRINT 12		// c_cc[VREPRINT] = REPRINT (^R)\022ʾַ
#define VDISCARD 13		// c_cc[VDISCARD] = DISCARD (^O)\017ַ
#define VWERASE 14		// c_cc[VWERASE] = WERASE (^W)\027ʲַ
#define VLNEXT 15		// c_cc[VLNEXT] = LNEXT (^V)\026һַ
#define VEOL2 16		// c_cc[VEOL2] = EOL2 (\0)\0 н2

/* c_iflag bits *//* c_iflag λ */
// termios ṹģʽֶc_iflag ֱ־ķų
#define IGNBRK 0000001		// ʱBREAK 
#define BRKINT 0000002		// BREAK ʱSIGINT źš
#define IGNPAR 0000004		// żУַ
#define PARMRK 0000010		// żУ
#define INPCK 0000020		// żУ顣
#define ISTRIP 0000040		// ַ8 λ
#define INLCR 0000100		// ʱзNL ӳɻسCR
#define IGNCR 0000200		// ԻسCR
#define ICRNL 0000400		// ʱسCR ӳɻзNL
#define IUCLC 0001000		// ʱдַתСдַ
#define IXON 0002000		// ʼ/ֹͣXON/XOFFơ
#define IXANY 0004000		// κַ
#define IXOFF 0010000		// ʼ/ֹͣXON/XOFFơ
#define IMAXBEL 0020000		// ʱ塣

/* c_oflag bits *//* c_oflag λ */
// termios ṹģʽֶc_oflag ֱ־ķų
#define OPOST 0000001		// ִ
#define OLCUC 0000002		// ʱСдַתɴдַ
#define ONLCR 0000004		// ʱзNL ӳɻس-зCR-NL
#define OCRNL 0000010		// ʱسCR ӳɻзNL
#define ONOCR 0000020		// 0 вسCR
#define ONLRET 0000040		// зNL ִлسĹܡ
#define OFILL 0000100		// ӳʱʹַʹʱӳ١
#define OFDEL 0000200		// ַASCII DELδãʹASCII NULL
#define NLDLY 0000400		// ѡӳ١
#define NL0 0000000		// ӳ0
#define NL1 0000400		// ӳ1
#define CRDLY 0003000		// ѡسӳ١
#define CR0 0000000		// سӳ0
#define CR1 0001000		// سӳ1
#define CR2 0002000		// سӳ2
#define CR3 0003000		// سӳ3
#define TABDLY 0014000		// ѡˮƽƱӳ١
#define TAB0 0000000		// ˮƽƱӳ0
#define TAB1 0004000		// ˮƽƱӳ1
#define TAB2 0010000		// ˮƽƱӳ2
#define TAB3 0014000		// ˮƽƱӳ3
#define XTABS 0014000		// ƱTAB ɿո񣬸ֵʾո
#define BSDLY 0020000		// ѡ˸ӳ١
#define BS0 0000000		// ˸ӳ0
#define BS1 0020000		// ˸ӳ1
#define VTDLY 0040000		// Ʊӳ١
#define VT0 0000000		// Ʊӳ0
#define VT1 0040000		// Ʊӳ1
#define FFDLY 0040000		// ѡҳӳ١
#define FF0 0000000		// ҳӳ0
#define FF1 0040000		// ҳӳ1

/* c_cflag bit meaning *//* c_cflag λĺ */
// termios ṹпģʽ־ֶc_cflag ־ķų8 
#define CBAUD 0000017		// λ롣
#define B0 0000000 /* hang up */	/* Ҷ· */
#define B50 0000001		//  50
#define B75 0000002		//  75
#define B110 0000003		//  110
#define B134 0000004		//  134
#define B150 0000005		//  150
#define B200 0000006		//  200
#define B300 0000007		//  300
#define B600 0000010		//  600
#define B1200 0000011		//  1200
#define B1800 0000012		//  1800
#define B2400 0000013		//  2400
#define B4800 0000014		//  4800
#define B9600 0000015		//  9600
#define B19200 0000016		//  19200
#define B38400 0000017		//  38400
#define EXTA B19200		// չA
#define EXTB B38400		// չB
#define CSIZE 0000060		// ַλ롣
#define CS5 0000000		// ÿַ5 λ
#define CS6 0000020		// ÿַ6 λ
#define CS7 0000040		// ÿַ7 λ
#define CS8 0000060		// ÿַ8 λ
#define CSTOPB 0000100		// ֹͣλ1 
#define CREAD 0000200		// ա
#define CPARENB 0000400		// ʱżλʱżУ顣
#define CPARODD 0001000		// /УУ顣
#define HUPCL 0002000		// ̹رպҶϡ
#define CLOCAL 0004000		// Եƽ(modem)·
#define CIBAUD 03600000 /* input baud rate (not used) */	/* 벨(δʹ) */
#define CRTSCTS 020000000000 /* flow control */	/*  */

#define PARENB CPARENB		// ʱżλʱżУ顣
#define PARODD CPARODD		// /УУ顣

/* c_lflag bits *//* c_lflag λ */
// termios ṹбģʽ־ֶc_lflag ķų
#define ISIG 0000001		// յַINTRQUITSUSP DSUSPӦźš
#define ICANON 0000002		// 淶ģʽģʽ
#define XCASE 0000004		// ICANONնǴдַġ
#define ECHO 0000010		// ַ
#define ECHOE 0000020		// ICANONERASE/WERASE ǰһַ/ʡ
#define ECHOK 0000040		// ICANONKILL ַǰС
#define ECHONL 0000100		// ICANONʹECHO ûпҲNL ַ
#define NOFLSH 0000200		// SIGINT SIGQUIT źʱˢУ
// SIGSUSP źʱˢС
#define TOSTOP 0000400		// SIGTTOU źŵ̵̨Ľ飬ų́ͼд
// ԼĿնˡ
#define ECHOCTL 0001000		// ECHOTABNLSTART STOP ASCII
// źŽԳ^X ʽX ֵǿƷ+0x40
#define ECHOPRT 0002000		// ICANON IECHOַڲʱʾ
#define ECHOKE 0004000		// ICANONKILL ͨϵַԡ
#define FLUSHO 0010000		// ˢ¡ͨDISCARD ַñ־ת
#define PENDIN 0040000		// һַǶʱеַԡ
#define IEXTEN 0100000		// ʵʱ봦

/* modem lines *//* modem ·źŷų */
#define TIOCM_LE 0x001		// ·(Line Enable)
#define TIOCM_DTR 0x002		// ն˾(Data Terminal Ready)
#define TIOCM_RTS 0x004		// (Request to Send)
#define TIOCM_ST 0x008		// ݷ(Serial Transfer)[??]
#define TIOCM_SR 0x010		// ݽ(Serial Receive)[??]
#define TIOCM_CTS 0x020		// (Clear To Send)
#define TIOCM_CAR 0x040		// ز(Carrier Detect)
#define TIOCM_RNG 0x080		// ָʾ(Ring indicate)
#define TIOCM_DSR 0x100		// 豸(Data Set Ready)
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG

/* tcflow() and TCXONC use these *//* tcflow()TCXONC ʹЩų */
#define TCOOFF 0		// 
#define TCOON 1			// 
#define TCIOFF 2		// ϵͳһSTOP ַʹ豸ֹͣϵͳݡ
#define TCION 3			// ϵͳһSTART ַʹ豸ʼϵͳݡ

/* tcflush() and TCFLSH use these *//* tcflush()TCFLSH ʹЩų */
#define TCIFLUSH 0		// յݵ
#define TCOFLUSH 1		// дݵ͡
#define TCIOFLUSH 2		// յݵдݵ͡

/* tcsetattr uses these *//* tcsetattr()ʹЩų */
#define TCSANOW 0		// ı
#define TCSADRAIN 1		// ıд֮
#define TCSAFLUSH 2		// ıд֮нյ
// ûжȡݱ֮

typedef int speed_t;		// ֵ͡

// termios_p ָtermios ṹеĽղʡ
extern speed_t cfgetispeed (struct termios *termios_p);
// termios_p ָtermios ṹеķͲʡ
extern speed_t cfgetospeed (struct termios *termios_p);
// termios_p ָtermios ṹеĽղΪspeed
extern int cfsetispeed (struct termios *termios_p, speed_t speed);
// termios_p ָtermios ṹеķͲΪspeed
extern int cfsetospeed (struct termios *termios_p, speed_t speed);
// ȴfildes ָдݱͳȥ
extern int tcdrain (int fildes);
// /fildes ָݵĽպͷ͡
extern int tcflow (int fildes, int action);
// fildes ָдûԼյûжȡݡ
extern int tcflush (int fildes, int queue_selector);
// ȡfildes ӦĲ䱣termios_p ָĵط
extern int tcgetattr (int fildes, struct termios *termios_p);
// նʹ첽ݴ䣬һʱһϵ0 ֵλ
extern int tcsendbreak (int fildes, int duration);
// ʹtermios ṹָtermios_p ָݣնصĲ
extern int tcsetattr (int fildes, int optional_actions,
		      struct termios *termios_p);

#endif
