⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 edit.c

📁 在linux系统下实现了一个多人聊天工具的服务器端和客户端。该工具支持显示在线用户
💻 C
字号:
#include "global.h"

/*c=a/b when the remainder is greater
 * than one then c plus one*/
int up_round(int base,int cut)
{
	int temp;
	temp = base/cut;
	if(base%cut)
		temp++;
	return temp;
}


/*add one colum node*/
ecnode * add_cnode(ecnode * target)
{ 
	ecnode * temp = NULL;
	if((temp=(ecnode *)malloc(sizeof(ecnode))) == NULL)
		return (ecnode *)0;
	if(target == NULL) {
		temp->next = current_row->chead;
		temp->pre = NULL;
		current_row->chead = temp;
	} else if(target->next == NULL) {
		target->next = temp;
		temp->pre = target;
		temp->next = NULL;
	} else {
		temp->next = target->next;
		target->next->pre = temp;
		temp->pre = target;
		target->next = temp;
	}
	return temp;
}

/*delect one colum node*/
void dele_cnode(ecnode * target)
{
	if(target->pre == NULL) {
		current_row->chead = target->next;
		if(target->next != NULL) 
			target->next->pre = NULL;
	} else if(target->next == NULL) {
		target->pre->next = NULL;
	} else {
		target->pre->next = target->next;
		target->next->pre = target->pre;
	}
	free(target);
}

/*add one row node*/
ernode * add_rnode(ernode * target)
{
	ernode * temp = NULL;
	if((temp=(ernode *)malloc(sizeof(ernode)))==NULL)
		return (ernode *)0;
	if(target->next == 0) {
		temp->next = 0;
		target->next = temp;
		temp->pre = target;
		temp->chead = NULL;
		temp->num = 0;
		temp->line = 1;
	} else {
		temp->next = target->next;
		target->next->pre = temp;
		temp->pre = target;
		target->next = temp;
		temp->chead = NULL;
		temp->num = 0;
		temp->line = 1;
	}
	return temp;
}


/*delect one row node*/
void dele_rnode(ernode * target)
{
	if(target->pre == NULL)
		return;
	if(target->next == NULL) 
		target->pre->next = NULL;
	else {
		target->pre->next = target->next;
		target->next->pre = target->pre;
	}
	free(target);
}

/*do some initialization about the editor*/
void init_editor()
{
	current_row = NULL;
	current_col = NULL;
	if((current_row=(ernode *)malloc(sizeof(ernode)))==NULL) {
		fprintf(stderr,"malloc fail!\n");
		exit(1);
	}
	current_row->chead = NULL;
	current_row->num = 0;
	current_row->line = 1;
	current_row->pre = NULL;
	current_row->next = NULL;
	row_head = current_row;
	current_x = 0;
	current_y = 0;
	log_x = 0;
	line_num = 1;
}

/*when the user input an enter then it
 * will be handled here*/
int handle_add_enter(int ch)
{
	ecnode * ctemp = NULL;
	ernode * rtemp = NULL;
	int line;
	/*there have been MIN_EDITOR_ROWS lines
	 * in the edit window.*/
	if(line_num == MIN_EDITOR_ROWS) {
		if(current_row->line==1)
			return 0;
		else {
			line = up_round(log_x,COLS);
			if((current_row->line-line)*COLS <=
			    current_row->num-log_x)
				return 0;
			else {
				ctemp=add_cnode(current_col);
				ctemp->ch = '\n';
				if(current_col->ch=='\n')
					current_row->chead = ctemp;
				current_col = ctemp;
				rtemp = add_rnode(current_row);
				rtemp->num = current_row->num-log_x;
				current_row->num = log_x+1;
				if(current_row->line > 1)
					current_row->line--;
				current_row = rtemp;
				current_x = 0;
				log_x = 0;
				current_y++;
			}
		}
	} else {
		ctemp=add_cnode(current_col);
		ctemp->ch = '\n';
		if(!current_col)
			current_row->chead = ctemp;
		else if(current_col->ch=='\n')
			current_row->chead = ctemp;
		current_col = ctemp;
		rtemp = add_rnode(current_row);
		rtemp->chead = ctemp->next;
		rtemp->num = current_row->num-log_x;
		current_row->num = log_x+1;
		if(current_row->line > 1)
			current_row->line--;
		current_row = rtemp;
		current_x = 0;
		log_x = 0;
		current_y++;
	}
	line_num++;
	return 1;
}


/*when the user input a char then it
 * will be handled here*/
int handle_add_char(int ch)
{
	ecnode * ctemp = NULL;
	ernode * rtemp = NULL;
	int line = 0;
	if(line_num == MIN_EDITOR_ROWS) {
		if((current_row->line)*COLS-1 <
		    current_row->num+1) 
			return 0;
		else {
			ctemp = add_cnode(current_col);
			ctemp->ch = ch;
			if(current_col->ch=='\n')
				current_row->chead = ctemp;
			current_col = ctemp;
			current_row->num++;
			if(current_x+2 > COLS) {
				current_x = 0;
				current_y++;
			} else
				current_x++;
			log_x++;
		}
	} else {
		ctemp = add_cnode(current_col);
		ctemp->ch = ch;
		if(!current_col)
			current_row->chead = ctemp;
		else if(current_col->ch=='\n')
			current_row->chead = ctemp;
		current_col = ctemp;
		current_row->num++;
		line = up_round(current_row->num,COLS);
		if(line > current_row->line) {
			line_num++;
			current_row->line++;
		}
		if(current_x+2 > COLS) {
			current_x = 0;
			current_y++;
		} else
			current_x++;
		log_x++;
	}
	return 1;
}

/*if the char being deleted is an enter
 * then it will be handle here.*/
int handle_dele_enter()
{
	int line;
	/*the enter is at the beginng of
	 * the window*/
	if(!current_col->pre) {
		dele_cnode(current_col);
		log_x = 0;
		current_x = 0;
		current_y = 0;
		line_num--;
		current_row = current_row->pre;
		current_row->num = current_row->next->num;
		current_row->chead = current_row->next->chead;
		current_row->line = current_row->next->line;
		dele_rnode(current_row->next);
		current_col = NULL;
	/*the enter is the tail of the link*/
	} else if(current_col->next == NULL) {
		if(current_row->pre->chead->ch ==
		   '\n') {
			current_col = current_col->pre;
			dele_cnode(current_col->next);
			current_y--;
			current_x = 0;
			log_x = 0;
			line_num--;
			current_row=current_row->pre;
			current_row->chead=current_row->next->chead;
			current_row->num = current_row->next->num;
			current_row->line=current_row->next->line;
			dele_rnode(current_row->next);
		} else {
			current_col = current_col->pre;
			dele_cnode(current_col->next);
			current_y--;
			line_num--;
			current_row=current_row->pre;
			//current_row->num+=current_row->next->num;
			current_row->num--;
			log_x = current_row->num;
			current_x = (current_row->num%COLS);
			dele_rnode(current_row->next);
		}
	/*the enter is at the middle of the link*/
	} else {
		current_col = current_col->pre;
		dele_cnode(current_col->next);
		current_row=current_row->pre;
		log_x = current_row->num-1;
		current_x = (current_row->num%COLS)-1;
		current_row->num+=current_row->next->num;
		current_row->num--;
		line = up_round(current_row->num,COLS);
		if(line <= current_row->next->line) {
			line_num--;
		}
		current_row->line = line;
		current_y--;
		dele_rnode(current_row->next);
	}
	return 1;
}


/*if the char being deleted is not an enter
 * then it will be handle here.*/
int handle_dele_char()
{	
	int line;
	/*the char is at the beginning of the link*/
	if(!current_col->pre) {
		current_row->chead = current_col->next;
		dele_cnode(current_col);
		log_x = 0;
		current_x = 0;
		current_row->num--;
		current_col = NULL;
	/*the char is not at the beginning of the link*/
	} else {
		current_col = current_col->pre;
		dele_cnode(current_col->next);
		log_x--;
		if(current_x == 0)
			current_y--;
		current_x = (log_x%COLS);
		current_row->num--;
		if(current_x != 0) {
			line = up_round(current_row->num,COLS);
			if(line < current_row->line) {
				line_num--;
				if(current_row->line > 1)
					current_row->line--;
			}
		}
	}
	return 1;
}

/*add the current input into the link*/
int add_one(int ch)
{
	/*if the char is an enter*/
	if(ch == FKEY_ENTER || ch == '\n') {
		return handle_add_enter(ch);
	/*if the char is not an enter*/
	} else {		
		return handle_add_char(ch);
	}
}

/*delete the char before cursor in the link*/
int dele_one()
{
	char ch;
	if(!current_col)
		return 0;
	ch = current_col->ch;
	/*if the char is an enter*/
	if(ch == FKEY_ENTER || ch == '\n') {
		return handle_dele_enter();
	/*if the char is not an enter*/
	} else {		
		return handle_dele_char();
	}
}

/*move the cursor one step rightwards*/
void move_left()
{
	if(current_x == 0) {
		if(current_y == 0)
			return;
		else if(current_col->ch == '\n') {
			current_y--;
			current_row = current_row->pre;
			current_col = current_col->pre;
			current_x = (current_row->num%COLS)-1;
			log_x = current_row->num - 1;
		} else {
			current_y--;
			current_col = current_col->pre;
			log_x--;
			current_x = log_x%COLS;
		}
	} else {
		current_x--;
		log_x--;
		current_col = current_col->pre;
	}
}

/*move the cursor one step leftwards*/
void move_right()
{
	if(!current_row->chead)
		return;
	else if(!current_col) {
		current_col = current_row->chead;
		if(current_col->ch == '\n') {
			current_row = current_row->next;
			current_x = 0;
			log_x = 0;
			current_y++;
		} else {
			current_x++;
			log_x++;
		}
	} else if(!current_col->next)
		return;
	else if(current_col->next->ch == '\n') {
		current_row = current_row->next;
		current_col = current_col->next;
		current_x = 0;
		log_x = 0;
		current_y++;
	} else if(current_x == COLS-1){
		current_col = current_col->next;
		current_x = 0;
		log_x++;
		current_y++;
	} else {
		current_col = current_col->next;
		current_x++;
		log_x++;
	}
}


/*move the cursor one step upwards*/
void move_up()
{
	int i;
	int temp;
	if(current_y == 0)
		return;
	else {
		if(log_x > COLS) {
			for(i = 0; i < COLS; i++) 
				current_col = current_col->pre;
			current_y--;
			log_x -= COLS;
		} else {
			current_row=current_row->pre;
			temp = current_row->num%COLS-1;
			if(temp > current_x) {
				current_y--;
				current_col = current_row->chead;
				for(i = 0; i < current_row->num-
				    (temp-current_x)-2; i++)
					current_col = current_col->next;
				log_x = current_row->num-(temp-current_x)-1;
			} else {
				current_y--;
				current_x = temp;
				log_x = current_row->num-1;
				current_col = current_row->chead;
				while(current_col->ch!='\n')
					current_col=current_col->next;
				current_col = current_col->pre;
			}
		}
	}
}


/*move the cursor one step downwards*/
void move_down()
{
	int i;
	int temp;
	if(current_y == line_num-1)
		return;
	else {
		if(current_row->num-log_x>=COLS) {
			for(i = 0; i < COLS; i++) 
				current_col = current_col->next;
			current_y++;
			log_x += COLS;
		} else {
			current_row=current_row->next;
			temp = current_row->num;
			if(temp > current_x) {
				current_y++;
				current_col = current_row->chead;
				if(current_x == 0)
					current_col = current_col->pre;
				else 
					for(i = 0; i < current_x-1; i++)
						current_col = current_col->next;
				log_x = current_x;
			} else {
				current_y++;
				current_x = temp;
				log_x = current_x;
				current_col = current_row->chead;
				while(current_col->next && current_col->
					next->ch!='\n')
					current_col=current_col->next;
			}
		}
	}
}

/*destroy the structure of the editor.
 * (two double links)*/
void destroy_editor()
{
	ernode * rp1;
	ernode * rp2;
	ecnode * cp1;
	ecnode * cp2;
	rp1 = rp2 = row_head;
	if(row_head)
		cp1 = cp2 = row_head->chead;
	else
		cp1 = NULL;
	while(rp1) {
		rp2 = rp1->next;
		free(rp1);
		rp1 = rp2;
	}
	while(cp1) {
		cp2 = cp1->next;
		free(cp1);
		cp1 = cp2;
	}
}

/*to see whether the input char is allowed*/
int allow_input(int ch)
{
	switch(ch) {
	case '`':case '@':case '#':case '$':
	case '~':case '%':case '^':case '&':
	case '!':case '*':case '(':case ')':
	case '-':case '_':case '+':case '=':
	case '\\':case '|':case '{':case '}':
	case '[':case ']':case '\'':case '"':
	case ',':case '<':case '.':case '>':
	case ';':case ':':case '/':case '?':
	case ' ':case '\n':case FKEY_ENTER:
		return 1;
		break;
	default:
		if(ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9')
			return 1;
		else 
			return 0;
		break;
	}
	return 0;
}

void editor()
{
	int kbinput;
	int i;
	ecnode * p;
	init_editor();
	while(1) {
		kbinput = wgetch(editwin);
		if(kbinput == '\t')
			kbinput = ' ';
		switch(kbinput) {
			//case 'q':
			//	destroy_struct();
			//	destroy_editor();
			//	finish();
			//	return;
			//	break;
			case KEY_BACKSPACE:
				dele_one();
				break;
			case KEY_LEFT:
				move_left();
				wmove(editwin,current_y,current_x);
				wrefresh(editwin);
				continue;
				break;
			case KEY_RIGHT:
				move_right();
				wmove(editwin,current_y,current_x);
				wrefresh(editwin);
				continue;
				break;
			case KEY_UP:
				move_up();
				wmove(editwin,current_y,current_x);
				wrefresh(editwin);
				continue;
				break;
			case KEY_DOWN:
				move_down();
				wmove(editwin,current_y,current_x);
				wrefresh(editwin);
				continue;
				break;
			case FKEY_C_S:
				destroy_editor();
				return;
				break;
			default:
				if(!allow_input(kbinput))
					continue;
				else if(!add_one(kbinput))
					continue;
				break;
		}/*print the input*/
		p = row_head->chead;
		i = 0;
		while(p) {
			key_buffer[i] = p->ch;
			i++;
			p = p->next;
		}
		key_buffer[i] = '\0';
		wclear(editwin);
		mvwprintw(editwin,0,0,"%s",key_buffer);
		wmove(editwin,current_y,current_x);
		wrefresh(editwin);
	}
}


/*handle the user input from the keyboard*/
void * thread_keyboard()
{
	int c;
	while(1) {
		wclear(editwin);
		wrefresh(editwin);
		init_editor();
		editor();
		c = handle_cmd();
		if(!c) {
			send_mes(key_buffer,serfd);
			break;
		} else if(c < 0)
			send_mes(key_buffer,serfd);
	}
	close(serfd);
	finish();
}

⌨️ 快捷键说明

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