term.c

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

C
1,114
字号
		case 2:			buf_ = (unsigned char *) s_malloc(strlen(buf) + strlen("Xyntherminal - "));			sprintf(buf_, "Xyntherminal - %s", buf);			s_window_set_title(window, buf_);			s_free(buf_);			break;	}	s_free(buf);}static void write_char (s_window_t *window, unsigned chr){        int x;        int y;        char *vbuf;	char str[2];        s_surface_t s;        unsigned char c;        unsigned int *mat;	c = (unsigned char) chr;	if (charset_G[charset]) {		if (c == 0x5f) {			chr = 0x7f;		} else if ((c > 0x5f) && (c < 0x7f)) {			chr = c - 0x5f;		} else {			chr = c;		}	} else {		chr = c;	}	str[0] = chr;	str[1] = '\0';	font->str = str;	s_font_get_glyph(font);	mat = font->img->rgba;        vbuf = (char *) s_malloc(window->surface->bytesperpixel * FONTW * FONTH + 1);        s_getsurfacevirtual(&s, FONTW, FONTH, window->surface->bitsperpixel, vbuf);	s_fillbox(&s, 0, 0, FONTW, FONTH, chr_attr.bg_color);	for (y = 0; y < font->img->h; y++) {		for (x = 0; x < font->img->w; x++) {			if (~*mat & 0xff) {				int r;				int g;				int b;				s_colorrgb(&s, chr_attr.fg_color, &r, &g, &b);				s_setpixelrgba(&s, x, y + FONTH - font->yMax - 4, r, g, b, *mat & 0xff);			} else {				s_setpixel(&s, x, y + FONTH - font->yMax - 4, chr_attr.bg_color);			}			mat++;		}	}        s_putbox(window->surface, (cursorx - 1) * FONTW, (cursory - 1) * FONTH, FONTW, FONTH, s.vbuf);	cursorx++;        s_free(vbuf);        font->str = NULL;	s_image_uninit(font->img);	s_image_init(&(font->img));}static void pfd_in_escape (s_window_t *window, int fd){        int pos;        int digit;        int question;        int carriage;        int backspace;        int verticaltab;        int narg = 0;	int args[16];        unsigned char chr;	for (pos = 0; pos < 16; pos++) {		args[pos] = 0;	}	chr = get_char(fd);	switch (chr) {		case '[': /* CSI */			narg = 0;			digit = 0;			question = 0;			carriage = 0;			backspace = 0;			verticaltab = 0;			chr = get_char(fd);			while (isdigit(chr) || (chr == ';') || (chr == '?') ||			       (chr == '\010') || (chr == '\013') || (chr == '\015')) {				if (chr == ';') {					args[narg] = 0;					digit = 0;				} else {					if (chr == '\010') {						backspace++;						if (!digit) {							while (backspace) {								cursorx--;								backspace--;							}						}					} else if (chr == '\015') {						carriage++;						if (!digit) {							while (carriage) {								carriage--;								cursorx = 1;							}						}					} else if (chr == '\013') {						verticaltab++;						if (!digit) {							while (verticaltab) {								cursory++;								verticaltab--;							}						}					} else if (chr == '?') {						question = 1;					} else {						if (!digit) {							narg++;						}						digit = 1;						args[narg - 1] *= 10;						args[narg - 1] += (chr - '0');					}				}				chr = get_char(fd);			}			switch (chr) {				case 'A': /* CUU Cursor Up */					cursor_up(args[0]);					break;				case 'B': /* CUD Cursor Down */					cursor_down(args[0]);					break;				case 'C': /* CUF Cursor Forward Right */					cursor_right(args[0]);					break;				case 'D': /* CUB Cursor Backward Left */					cursor_left(args[0]);					break;				case 'G': /* Cursor Move Col */					cursor_goto(args[0], cursory);					break;				case 'H': /* CUP Direct Cursor Addressing */				case 'f':					cursor_goto(args[1], args[0]);					break;				case 'J': /* ED Erase In Display */					erase_in_display(window, args[0]);					break;				case 'P': /* DCH Delete Character */					erase_chars(window, args[0]);					break;				case 'K': /* ED Erase In Line */					if (narg == 0) {						break;					}					erase_in_line(window, args[0]);					break;				case 'L': /* Insert Line */					insert_lines(window, args[0]);					break;				case 'M': /* Delete Line */					delete_lines(window, args[0]);					break;				case 'X': /* Erase Chars */					erase_chars_(window, args[0]);					break;				case 'c': /* DA Device Attributes */					if (narg == 0) {						device_attributes(fd);					}					break;				case 'd': /* Cursor Move Row */					cursor_goto(cursorx, args[0]);					break;				case 'g': /* TBC Tabulation clear */					tabulation_clear(args[0]);					break;				case 'h': /* Modes Set */					pos = narg;					while (pos > 0) {						modes_set(args[pos - 1]);						pos--;					}					break;				case 'l': /* Modes Reset */					pos = narg;					while (pos > 0) {						modes_reset(args[pos - 1]);						pos--;					}					break;				case 'm': /* SGR Set Graphics Rendition */					if (narg == 0) {						chr_attr_reset(window);					}					for (pos = 0; pos < narg; pos++) {						switch (args[pos]) {							case 0:								chr_attr_reset(window);								break;							case 1:								chr_attr_bold(1);								break;							case 4: /* underscode */							case 5: /* blinking */							case 7: /* display negative image */							case 22: /* display normal intensity */							case 24: /* not underlined */							case 25: /* not blinking */							case 27: /* display positive image */								break;							case 30 ... 37:								chr_attr_fg_color(window, args[pos] - 30);								break;							case 39:								chr_attr_fg_color(window, 8);								break;							case 40 ... 47:								chr_attr_bg_color(window, args[pos] - 40);								break;							case 49:								chr_attr_bg_color(window, 0);								break;//							default://								printf("m args : %d\n", args[pos]);						}					}					break;				case 'r': /* Scroll Region */					scroll_region(args[0], args[1]);					break;				default:					printf("Unknown CSI %c", chr);					if (narg) {						printf(" args :");						for (pos = 0; pos < narg; pos++) {							printf(" %d", args[pos]);						}					}					printf("\n");			}			while (backspace) {				cursorx--;				backspace--;			}			while (carriage) {				carriage--;				cursorx = 1;			}			while (verticaltab) {				cursory++;				verticaltab--;			}			break;		case '(': /* G0 */			set_charset(0, get_char(fd));			break;		case ')': /* G1 */			set_charset(1, get_char(fd));			break;		case '=': /* Set application keypad mode */			mode.application = 1;			break;		case '>': /* Set numeric keypad mode */			mode.application = 0;			break;		case 'M': /* Reverse Index */			cursory--;			if (cursory < 1) {				insert_lines(window, 1);				cursory = 1;			}			break;		case 'E': /* Next Line */			cursorx = 1;		case 'D': /* Index */			cursory++;			if (cursory > SCREENH) {				delete_lines(window, 1);				cursory = SCREENH;			}			break;		case 'H': /* HTS Horizontal tabulation set at current position */			tabulation_set_current();			break;		case '7': /* Save cursor position */			scursorx = cursorx;			scursory = cursory;			break;		case '8': /* Restore cursor position */			cursorx = scursorx;			cursory = scursory;			break;		case ']': /* Xterm Sequence */			digit = 0;			chr = get_char(fd);			while (isdigit(chr)) {				if (!digit) {					narg++;				}				digit = 1;				args[narg - 1] *= 10;				args[narg - 1] += (chr - '0');				chr = get_char(fd);			}			xterm_sequence(window, fd, args[0]);			break;		default:			printf("Unknown Sequence %c\n", chr);	}}static int pfd_in (s_window_t *window, int fd){        int x;        char chr;        char chr_ = 0;	char box[FONTW * SCREENW * FONTH * SCREENH * window->surface->bytesperpixel];        chr = get_char(fd);pdf_in_g0:	switch (chr) {		case '\000': /* null */		case '\001':			break;		case '\007': /* bell */			break;		case '\010': /* backspace */			cursorx--;			break;		case '\011': /* tab */			for (x = cursorx; x < SCREENW; x++) {				if (tabs_horizontal[cursory - 1][x]) {					cursorx = x + 1;					break;				}			}			break;		case '\016': /* charset G1 */			charset = 1;			break;		case '\017': /* charset G0 */			charset = 0;			break;		case '\033': /* escape */			pfd_in_escape(window, fd);			break;		case '\r':   /* carriage return */			cursorx = 1;			break;		case '\n':   /* return carriage */			if (mode.application == 0) {				cursorx = 1;			}			cursory++;			break;		default:			write_char(window, chr);	}	if (cursorx < 1) {		cursorx = 1;	}	if (cursorx > SCREENW) {		cursorx = 1;		if (mode.wraparound == 0) {			chr = get_char(fd);			if ((chr != '\n') && (chr != '\r') && (chr != '\033')) {				chr_ = 1;				cursory++;			}			if (chr == '\033') {				chr_ = 1;			}		}	}	if (cursory < 1) {		cursory = 1;	}	if (cursory > SCREENH) {		s_getbox(window->surface, 0, FONTH, FONTW * SCREENW, FONTH * (SCREENH - 1), box);		s_fillbox(window->surface, 0, FONTH * (SCREENH - 1), FONTW * SCREENW, FONTH, chr_attr.bg_color);//		s_putbox(window->surface, 0, 0, FONTW * SCREENW, FONTH * (SCREENH - 1), box);		s_putboxpart(window->surface, 0, 0, FONTW * SCREENW, FONTH * (SCREENH - 1), FONTW * SCREENW, FONTH * (SCREENH - 1), box, 0, 0);		cursory = SCREENH;	}	if (chr_) {		chr_ = 0;		goto pdf_in_g0;	}	return 0;}static int pfd_err (s_window_t *window, int fd){	exit(2);}static void atevent (s_window_t *window, s_event_t *event){        int i;	if (event->type & KEYBD_PRESSED) {		if (event->keybd->flag & KEYCODE_LCTRLF) {			for (i = 0; i < CTRLCODES; i++) {				if (ctrlcodes_c[i] == event->keybd->button) {				        write(cmd_fd, ctrlcodes_s[i], strlen(ctrlcodes_s[i]));					return;				}			}		}		if (isprint(event->keybd->ascii)) {			write(cmd_fd, &event->keybd->ascii, sizeof(int));		} else {			for (i = 0; i < KEYCODES; i++) {				if (keycodes_c[i] == event->keybd->button) {					write(cmd_fd, keycodes_s[i], strlen(keycodes_s[i]));					return;				}			}		}	}}static void term (s_window_t *window){        char **args;	s_pollfd_t *pfd;	get_pty();	if ((pid = fork()) < 0) {		printf("Could not fork()\n");		exit(2);	}	if (!pid) {		get_tty();		putenv("TERM=linux");		setenv("SDL_VIDEODRIVER", "xynth", 1);		chdir("~");		args = (char **) s_calloc(3, sizeof(char *));		args[0] = (char *) s_malloc(strlen("/bin/bash") + 1);		strcpy(args[0], "/bin/bash");		args[1] = NULL;		args[2] = NULL;		execvp("/bin/bash", args);		printf("Error executing %s\n", "/bin/bash");		exit(2);	}		s_pollfd_init(&pfd);	pfd->fd = cmd_fd;	pfd->pf_in = pfd_in;	pfd->pf_err = pfd_err;	s_client_atevent(window, atevent);	s_pollfd_add(window, pfd);	close(slave);	signal(SIGCHLD, sigchld_handler);}static void clean_vars (void){	int x;	int y;	pid = -1;	ptydev = NULL;	slave = -1;	cmd_fd = -1;	pw = NULL;	font = NULL;	cursorx = 1;	cursory = 1;	scursorx = 1;	scursory = 1;	charset = 0;	charset_G[0] = 0;	charset_G[1] = 0;	mode.wraparound = 0;	mode.application = 0;	chr_attr.bold = 0;	chr_attr.fg_color = 0;	chr_attr.bg_color = 0;	scroll_reg.y0 = 1;	scroll_reg.y1 = SCREENH;	for (y = 0; y < SCREENH; y++) {		for (x = 0; x < SCREENW; x++) {			tabs_horizontal[y][x] = 0;		}	}}int main (int argc, char *argv[]){	s_window_t *window;		clean_vars();	s_client_init(&window);	s_window_new(window, WINDOW_MAIN, NULL);	s_window_set_title(window, "Xyntherminal");	s_window_set_coor(window, 0, 100, 100, FONTW * SCREENW, FONTH * SCREENH);	s_window_set_coor(window, NO_FORM, window->surface->buf.x, window->surface->buf.y, FONTW * SCREENW, FONTH * SCREENH);	s_window_set_resizeable(window, 0);	s_free(window->surface->vbuf);	window->surface->vbuf = (char *) s_malloc(window->surface->buf.w * window->surface->buf.h * window->surface->bytesperpixel);	window->surface->width = window->surface->buf.w;	window->surface->height = window->surface->buf.h;        s_font_init(&font, "veramono.ttf");        s_font_set_size(font, FONTH);        	chr_attr_reset(window);	chr_attr_bg_color(window, 0);        term(window);	s_window_show(window);	s_client_main(window);	s_font_uninit(font);	return 0;}#if defined(SINGLE_APP)s_single_app_t single_term = {	term_main,	1,	{"term"}};#endif

⌨️ 快捷键说明

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