term.c

来自「CS架构的多平台的GUI系统」· C语言 代码 · 共 1,114 行 · 第 1/2 页

C
1,114
字号
/***************************************************************************    begin                : Thu Jan 30 2003    copyright            : (C) 2003 - 2005 by Alper Akcan    email                : distchx@yahoo.com ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU Lesser General Public License as        * *   published by the Free Software Foundation; either version 2.1 of the  * *   License, or (at your option) any later version.                       * *                                                                         * ***************************************************************************/#include <fcntl.h>#include <ctype.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <signal.h>#include <sys/wait.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/types.h>#include "xynth_.h"static pid_t pid;static char *ptydev;static int slave;static int cmd_fd;struct passwd *pw;static s_font_t *font;static int cursorx = 1;static int cursory = 1;static int scursorx = 1;static int scursory = 1;static int colors[9] = {0x000000, /* black   */		        0xB41818, /* red     */		        0x18B218, /* green   */		        0xFFFF52, /* yellow  */		        0x1818B4, /* blue    */		        0xFF5552, /* magenta */		        0x18B2B4, /* cyan    */		        0xB4B2B4, /* white   */		        0x18F218};/* default */static int charset = 0;static int charset_G[2] = {0, 0};static struct {	int wraparound;	int application;} mode = {0, 0};static struct {	int bold;	int fg_color;	int bg_color;} chr_attr;#define FONTW	10#define FONTH	16#define SCREENW	80#define SCREENH	25static struct {	int y0;	int y1;} scroll_reg = {1, SCREENH};extern int getpt (void);extern int grantpt (int);extern int unlockpt (int);#define CTRLCODES	51static S_KEYCODE_CODE ctrlcodes_c[CTRLCODES] = {S_KEYCODE_a, S_KEYCODE_A, S_KEYCODE_b, S_KEYCODE_B, S_KEYCODE_c, S_KEYCODE_C,						S_KEYCODE_d, S_KEYCODE_D, S_KEYCODE_e, S_KEYCODE_E, S_KEYCODE_f, S_KEYCODE_F,						S_KEYCODE_g, S_KEYCODE_G, S_KEYCODE_h, S_KEYCODE_H, S_KEYCODE_k, S_KEYCODE_K,						S_KEYCODE_l, S_KEYCODE_L, S_KEYCODE_n, S_KEYCODE_N, S_KEYCODE_o, S_KEYCODE_O,						S_KEYCODE_p, S_KEYCODE_P, S_KEYCODE_q, S_KEYCODE_Q, S_KEYCODE_r, S_KEYCODE_R,						S_KEYCODE_s, S_KEYCODE_S, S_KEYCODE_t, S_KEYCODE_T, S_KEYCODE_u, S_KEYCODE_U,						S_KEYCODE_v, S_KEYCODE_V, S_KEYCODE_w, S_KEYCODE_W, S_KEYCODE_x, S_KEYCODE_X,						S_KEYCODE_y, S_KEYCODE_Y, S_KEYCODE_z, S_KEYCODE_Z,						S_KEYCODE_BRACKETLEFT, S_KEYCODE_BACKSLASH, S_KEYCODE_BRACKETRIGHT,						S_KEYCODE_ASCIICIRCUM, S_KEYCODE_UNDERSCORE};static char *ctrlcodes_s[CTRLCODES] = {"\001", "\001", "\002", "\002", "\003", "\003",				       "\004", "\004", "\005", "\005", "\006", "\006",				       "\007", "\007", "\010", "\010", "\013", "\013",				       "\014", "\014", "\016", "\016", "\017", "\017",				       "\020", "\020", "\021", "\021", "\022", "\022",				       "\023", "\023", "\024", "\024", "\025", "\025",				       "\026", "\026", "\027", "\027", "\030", "\030",				       "\031", "\031", "\032", "\032",				       "\033", "\034", "\035",				       "\036", "\037"};#define KEYCODES	27static S_KEYCODE_CODE keycodes_c[KEYCODES] = {S_KEYCODE_F1, S_KEYCODE_F2, S_KEYCODE_F3, S_KEYCODE_F4, S_KEYCODE_F5,					      S_KEYCODE_F6, S_KEYCODE_F7, S_KEYCODE_F8, S_KEYCODE_F9, S_KEYCODE_F10,                                              S_KEYCODE_F11, S_KEYCODE_F12, S_KEYCODE_TAB, S_KEYCODE_END, S_KEYCODE_HOME,                                              S_KEYCODE_UP, S_KEYCODE_DOWN, S_KEYCODE_LEFT, S_KEYCODE_RIGHT, S_KEYCODE_RETURN,                                              S_KEYCODE_DELETE, S_KEYCODE_INSERT, S_KEYCODE_REMOVE, S_KEYCODE_ESCAPE,                                              S_KEYCODE_PAGEUP, S_KEYCODE_PAGEDOWN, S_KEYCODE_KP_ENTER};static char *keycodes_s[KEYCODES] = {"\033[[A", "\033[[B", "\033[[C", "\033[[D", "\033[[E", "\033[17~", "\033[18~",				     "\033[19~", "\033[20~", "\033[21~", "\033[23~", "\033[24~", "\t", "\033[4~",				     "\033[1~", "\033[A", "\033[B", "\033[D", "\033[C", "\n", "\010", "\033[2~",				     "\033[3~", "\033", "\033[5~", "\033[6~", "\n"};static int tabs_horizontal[SCREENH][SCREENW];static void sigchld_handler (int a){	int status = 0;	if (waitpid(pid, &status, 0) < 0) {		printf("Waiting for pid %hd failed\n", pid);		exit(1);	}	if (WIFEXITED(status)) {		if (WEXITSTATUS(status)) {			printf("Process %hd exited with non-zero status %d\n", pid, WEXITSTATUS(status));			exit(1);		}	} else if (WIFSIGNALED(status)) {		printf("Process %hd was killed by signal %d\n", pid, WTERMSIG(status));		exit(1);	} else {		printf("Process %hd terminated abnormally\n", pid);		exit(1);	}	printf("Child exited normally\n");	exit(0);}static void get_pty (void){        int fd;	extern char *ptsname();	if ((fd = getpt()) >= 0) {		if ((grantpt(fd) == 0) && (unlockpt(fd) == 0)) {			ptydev = ptsname(fd);			if ((slave = open(ptydev, O_RDWR | O_NOCTTY)) < 0) {				printf("Error opening slave pty\n");				exit(2);			}			cmd_fd = fd;			return;		}		close(fd);	}	printf("Can not open pseudo-tty\n");	exit(2);}static void get_tty (void){	int i;	struct winsize w;	for (i = 0; i < 100 ; i++) {		if (i != slave) {			close(i);		}	}	cmd_fd = slave;	setsid(); /* create a new process group */	dup2(cmd_fd, 0);	dup2(cmd_fd, 1);	dup2(cmd_fd, 2);	if (ioctl(cmd_fd, TIOCSCTTY, NULL) < 0) {		printf("Couldn't set controlling terminal\n");		exit(2);	}	w.ws_row = SCREENH;	w.ws_col = SCREENW;	w.ws_xpixel = 0;	w.ws_ypixel = 0;	if (ioctl(cmd_fd, TIOCSWINSZ, &w) < 0) {		printf("Couldn't set window size\n");		exit(2);	}}static char get_char (int fd){        int r;        int f;	char c = 0;		r = read(fd, &c, 1);	if (r <= 0) {		fcntl(fd, F_GETFL, &f);		if (f & O_NONBLOCK) {			printf("Could not read input fd\n");			exit(2);		}	}	return c;}static void cursor_up (int n){	if (n == 0) {		n = 1;	}	cursory -= n;	if (cursory < 1) {		cursory = 1;	}}static void cursor_down (int n){	if (n == 0) {		n = 1;	}	cursory += n;	if (cursory > SCREENH) {		cursory = SCREENH;	}}static void cursor_left (int n){	if (n == 0) {		n = 1;	}	cursorx -= n;	if (cursorx < 1) {		cursorx = 1;	}}static void cursor_right (int n){	if (n == 0) {		n = 1;	}	cursorx += n;	if (cursorx > SCREENW) {		cursorx = SCREENW;	}}static void cursor_goto (int x, int y){	cursorx = x;	if (cursorx < 1) {		cursorx = 1;	}	if (cursorx > SCREENW) {		cursorx = SCREENW;	}	cursory = y;	if (cursory < 1) {		cursory = 1;	}	if (cursory > SCREENH) {		cursory = SCREENH;	}}static void erase_in_display (s_window_t *window, int v){        int x = 0;        int y = 0;        int w = 0;        int h = 0;	switch (v) {		case 0: /* Erase from line active position to the end of screen */			x = (cursorx - 1) * FONTW;			y = (cursory - 1) * FONTH;			w = FONTW * SCREENW - x;			h = FONTH * SCREENH - y;			break;		case 1: /* Erase from start position to the active position */			x = 0;			y = 0;			w = (cursorx - 1) * FONTW;			h = (cursory - 1) * FONTH;			break;		case 2: /* Erase all of the display -- all lines erased, changed to single width, and the cursor does not move */			x = 0;			y = 0;			w = FONTW * SCREENW;			h = FONTH * SCREENH;			break;	}	s_fillbox(window->surface, x, y, w, h, chr_attr.bg_color);}static void erase_in_line (s_window_t *window, int v){        int x = 0;        int y = 0;        int w = 0;        int h = 0;	switch (v) {		case 0: /* Erase from line active position to the end of line */			x = (cursorx - 1) * FONTW;			y = (cursory - 1) * FONTH;			w = FONTW * SCREENW - x;			h = FONTH;			break;		case 1: /* Erase from start position to the active position */			x = 0;			y = (cursory - 1) * FONTH;			w = (cursorx - 1) * FONTW;			h = FONTH;			break;		case 2: /* Erase all of the line */			x = 0;			y = (cursory - 1) * FONTH;			w = FONTW * SCREENW;			h = FONTH;			break;	}	s_fillbox(window->surface, x, y, w, h, chr_attr.bg_color);}static void erase_chars (s_window_t *window, int c){        int x = 0;        int y = 0;        int w = 0;        int h = 0;        char *box;                box = (char *) s_malloc(SCREENW * FONTW * SCREENH * FONTH * window->surface->bytesperpixel + 1);        /* Erase [c] character(s) from line active position.*/	if (c == 0) {		c = 1;	}	x = (cursorx - 1) * FONTW;	y = (cursory - 1) * FONTH;	w = FONTW * c;	h = FONTH;	s_getbox(window->surface, x + w, y, (FONTW * SCREENW) - x - w, h, box);	erase_in_line(window, 0);	s_putbox(window->surface, x, y, (FONTW * SCREENW) - x - w, h, box);		s_free(box);}static void erase_chars_ (s_window_t *window, int c){        int x = 0;        int y = 0;        int w = 0;        int h = 0;        /* Erase [c] character(s) from line active position.*/	if (c == 0) {		c = 1;	}	x = (cursorx - 1) * FONTW;	y = (cursory - 1) * FONTH;	w = FONTW * c;	h = FONTH;	s_fillbox(window->surface, x, y, w, h, chr_attr.bg_color);}static void device_attributes (int fd){	/*	   No options			"\033[?1;0c"	   Processor option (STP)	"\033[?1;1c"	   Advanced video option (AVO)	"\033[?1;2c"	   AVO and STP			"\033[?1;3c"	   Graphics option (GO)		"\033[?1;4c"	   GO and STP			"\033[?1;5c"	   GO and AVO			"\033[?1;6c"	   GO, STP, and AVO		"\033[?1;7c"	*/	char *chr = "\033[?1;2c";	write(fd, chr, strlen(chr));}static void modes_set (int set){	switch (set) {		case 7:			mode.wraparound = 1;			return;	}	printf("Modes Set %d\n", set);}static void modes_reset (int reset){	switch (reset) {		case 7:			mode.wraparound = 0;			return;	}	printf("Modes Reset %d\n", reset);}static void chr_attr_fg_color (s_window_t *window, int c){	chr_attr.fg_color = colors[c];	chr_attr.fg_color = s_rgbcolor(window->surface, (colors[c] >> 16) & 0xFF, (colors[c] >> 8) & 0xFF, (colors[c] >> 0) & 0xFF);}static void chr_attr_bg_color (s_window_t *window, int c){	chr_attr.bg_color = colors[c];	chr_attr.bg_color = s_rgbcolor(window->surface, (colors[c] >> 16) & 0xFF, (colors[c] >> 8) & 0xFF, (colors[c] >> 0) & 0xFF);}static void chr_attr_bold (int b){	switch (b) {		case 0://			s_font_set(&font, FONTR);			break;		case 1://			s_font_set(&font, FONTB);			break;	}}static void chr_attr_reset (s_window_t *window){        chr_attr_bold(0);	chr_attr_fg_color(window, 8);}static void set_charset (int g, unsigned char which){	switch (which) {		case '0': /* graphics  */			charset_G[g] = 1;			break;		case 'B': /* iso8859-1 */			charset_G[g] = 0;			break;		default:			printf("Charset unknown %c\n", which);	}}static void insert_lines (s_window_t *window, int lines){	int i = lines;	char box[FONTW * SCREENW * (scroll_reg.y1 - scroll_reg.y0) * FONTH * window->surface->bytesperpixel];        while (i--) {		s_getbox(window->surface, 0, (scroll_reg.y0 - 1) * FONTH, FONTW * SCREENW, (scroll_reg.y1 - scroll_reg.y0) * FONTH, box);		s_fillbox(window->surface, 0, (scroll_reg.y0 - 1) * FONTH, FONTW * SCREENW, FONTH, chr_attr.bg_color);		s_putbox(window->surface, 0, (scroll_reg.y0) * FONTH, FONTW * SCREENW, (scroll_reg.y1 - scroll_reg.y0) * FONTH, box);	}}static void delete_lines (s_window_t *window, int lines){        int i = lines;	char box[FONTW * SCREENW * (scroll_reg.y1 - scroll_reg.y0) * FONTH * window->surface->bytesperpixel];        while (i--) {		s_getbox(window->surface, 0, (scroll_reg.y0) * FONTH, FONTW * SCREENW, (scroll_reg.y1 - scroll_reg.y0) * FONTH, box);		s_fillbox(window->surface, 0, (scroll_reg.y1 - 1) * FONTH, FONTW * SCREENW, FONTH, chr_attr.bg_color);		s_putbox(window->surface, 0, (scroll_reg.y0 - 1) * FONTH, FONTW * SCREENW, (scroll_reg.y1 - scroll_reg.y0) * FONTH, box);	}}static void scroll_region (int y0, int y1){	if (y0 <= 0) {		scroll_reg.y0 = 1;	} else {		scroll_reg.y0 = y0;	}	if (y1 <= 0) {		scroll_reg.y1 = SCREENH;	} else {		scroll_reg.y1 = y1;	}}static void tabulation_clear (int g){        int x = cursorx - 1;        int y = cursory - 1;	switch (g) {		case 0: /* Clear horizontal tab stop at current position */			tabs_horizontal[y][x] = 0;			break;		case 1: /* Clear vertical tab stop at current line */		case 2: /* Clear all horizontal tab stops at current line only */			break;		case 3: /* Clear all tab stops in the terminal */			for (y = 0; y < SCREENH; y++) {				for (x = 0; x < SCREENW; x++) {					tabs_horizontal[y][x] = 0;				}			}			break;	}}static void tabulation_set_current (void){        int x = cursorx - 1;        int y = cursory - 1;	tabs_horizontal[y][x] = 1;}static void xterm_sequence (s_window_t *window, int fd, int op){	int len;	int buflen;	unsigned char c;	unsigned char *buf;	unsigned char *buf_;	buflen = 20;	buf = (unsigned char *) s_malloc(sizeof(unsigned char) * buflen);	c = get_char(fd);	for (len = 0; c != '\007'; len++) {		if (len > buflen) {			buflen <<= 1;			buf = (unsigned char *) s_realloc(buf, buflen);		}		buf[len] = c;		c = get_char(fd);	}	buf[++len] = c; 	printf("Xterm Sequence %d, arg: %s\n", op, buf);	switch (op) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?