📄 winio.c
字号:
#include <termios.h>
#include <term.h>
#include <curses.h>
#include <stdio.h>
#include <stdlib.h>
#include "global.h"
#define MAX_LINE 100
struct termios oldterm; /*The user's original term settings*/
/*convert a string to an integer*/
int get_int(char * str)
{
int i = 0;
int j = 0;
char digit[20];
while(str[i]&&!isdigit(str[i]))
i++;
while(isdigit(str[i]))
digit[j++] = str[i++];
if(j == 0)
return -1;
digit[j] = '\0';
i = atoi(digit);
return i;
}
/*do some initialization of the windows*/
/*three windows*/
void window_ini()
{
int i = 0;
char message[] = "The window is too small,please make it larger";
char temp[] = "Press <C-S> to send message:";
if((showwinrows = LINES-MIN_EDITOR_ROWS-1)<MIN_SHOW_ROWS) {
fprintf(stderr,"%s\n",message);
exit(1);
}
//showErrorM(message);
/* Setup the show window*/
showwin = newwin(showwinrows, COLS, 0, 0);
/* Setup the main edit window */
editwin = newwin(MIN_EDITOR_ROWS,COLS,showwinrows+1,0);
/* Setup the middle window*/
midwin = newwin(1,COLS,showwinrows,0);
wclear(showwin);
wclear(editwin);
wclear(midwin);
wattron(midwin,A_REVERSE);
if(COLS > 28) {
for(i = 0; i < 28; i++)
mvwaddch(midwin,0,i,temp[i]);
for(;i < COLS; i++)
mvwaddch(midwin,0,i,' ');
} else {
for(i = 0; i < COLS; i++)
mvwaddch(midwin,0,i,' ');
}
wattroff(midwin,A_REVERSE);
wrefresh(midwin);
wrefresh(editwin);
keypad(editwin, TRUE);
keypad(editwin,TRUE);
}
/*let the setting of term retun to the old one*/
void finish()
{
nocbreak();
nl();
echo();
endwin();
noraw();
/* Restore the old term settings */
tcsetattr(0, TCSANOW, &oldterm);
exit(0);
}
/*allocate some memory for the structure for the
* show window and do some initializaton of the
* associated pointers*/
void init_struct()
{
int i;
rnode * pre;
rnode * p;
if((top=(rnode *)malloc(sizeof(rnode)))==NULL) {
fprintf(stderr,"malloc fail!\n");
exit(1);
}
if((top->mes=(char *)malloc(MAX_LINE*sizeof(char)))==NULL) {
fprintf(stderr,"malloc fail!\n");
exit(1);
}
pre = top;
for(i = 0; i < showwinrows; i++) {
if((p=(rnode *)malloc(sizeof(rnode)))==NULL) {
fprintf(stderr,"malloc fail!\n");
exit(1);
}
if((p->mes=(char *)malloc(MAX_LINE*sizeof(char)))==NULL) {
fprintf(stderr,"malloc fail!\n");
exit(1);
}
pre->next = p;
pre = p;
}
pre->next = top;
bott = top;
rowcount = 0;
}
/*destroy the show window structure*/
void destroy_struct()
{
int i;
rnode * pre;
rnode * p;
p = top;
pre = top;
for(i = 0; i < showwinrows-1; i++) {
pre = p->next;
free(p->mes);
free(p);
p = pre;
}
free(p->mes);
free(p);
}
/*copy the message received from the server to the
* the structure in a special form*/
void insert_input(char * mes)
{
int n;
char * p;
int l = 0;
int j,k;
p = mes;
while(1) {
n = strlen(p);
if(n == 1 && p[0] == '\n')
break;
j = l+COLS;
if(n > COLS) {
j = l+COLS-1;
while(mes[j]!=' '&&
j > l+COLS/2)
j--;
if(j == l+COLS/2)
j = l+COLS-1;
}
k = 0;
while(mes[l]&&j > l) {
if(mes[l]=='\n') {
l++;
break;
}
bott->mes[k] = mes[l];
k++;
l++;
}
p = &mes[l];
bott->mes[k] = '\0';
if(show_line == showwinrows)
top = top->next;
else
show_line++;
bott = bott->next;
if(!mes[l])
break;
}
}
/*display the message received from the server
* in the show window*/
void display()
{
int i = 0;
rnode * p;
p = top;
while(p != bott) {
mvwprintw(showwin,i,0,"%s\n",p->mes);
i++;
p = p->next;
}
wrefresh(showwin);
wrefresh(editwin);
}
/*to see whether the message is an error message
* and display the meaning of the message*/
void check_error(char *mes,int i)
{
int k = 0;
int j = 0;
int err,n;
char name[MAXNAME];
// /*divide the message*/
// while(mess_buffer[i][j]==' '||mess_buffer[i][j]=='\t')
// j++;
// if(mess_buffer[i][j] == '<') {
// while(mess_buffer[i][j]&&mess_buffer[i][j]!='>')
// mes[k++] = mess_buffer[i][j++];
// if(mess_buffer[i][j]!='>') {
// fprintf(stderr,"Unknown message!\n");
// exit(1);
// }
// mes[k++] = '>';
// mes[k++] = ' ';
// }
// while(mess_buffer[i][j]&&mess_buffer[i][j]!='\n')
// j++;
// if(mess_buffer[i][j]!='\n') {
// fprintf(stderr,"Unacceptable message!\n");
// exit(1);
// }
// j++;
// while(mess_buffer[i][j]==' '||mess_buffer[i][j]=='\t')
// j++;
while(mess_buffer[i][j])
mes[k++] = mess_buffer[i][j++];
mes[k] = '\0';
if(strncmp(mes,"ERR:",4)==0) {
/*classify the error message*/
err = get_int(&mes[4]);
if(err > 0) {
if(err == 101) {
sprintf(mes,"server: nickname exists!\n");
berror = 1;
} else if(err == 102) {
sprintf(mes,"server: command not supported!\n");
} else if(err == 103) {
sprintf(mes,"server: no such user!\n");
} else if(err == 104) {
fprintf(stderr,"max connections exhausted!\n");
berror = 1;
}
}
}
}
/*handle the input from the server and
* display them*/
void * thread_display()
{
int i;
char mes[MAX_MES];
while(1) {
sem_wait(&full);
sem_wait(&mutex);
check_error(mes,mess_out);
mess_out = (mess_out+1)%MAX_SHOW_BUFF;
sem_post(&mutex);
sem_post(&empty);
insert_input(mes);
display();
if(enable_log) {
do_log(mes);
}
if(berror) {
sleep(1);
finish();
exit(1);
}
}
}
/*handle the screen input and output*/
void * thread_screen(void *arg)
{
pthread_t tid_keyboard;
pthread_t tid_display;
struct termios term;
int res;
/*First back up the old settings so they can be restored*/
tcgetattr(0, &oldterm);
term = oldterm;
term.c_cc[VINTR] = _POSIX_VDISABLE;
term.c_cc[VQUIT] = _POSIX_VDISABLE;
term.c_lflag &= ~IEXTEN;
tcsetattr(0, TCSANOW, &term);
/*now ncurses init stuff*/
initscr();
savetty();
nonl();
cbreak();
noecho();
raw();
window_ini();
init_struct();
/*create two thread. one for the show window displaying
* the input message and the other one is used to handle
* the user input*/
if((res=pthread_create(&tid_display,NULL/*&thread_attr*/,&thread_display,
NULL)) != 0) {
fprintf(stderr,"Creating thread fail!\n");
exit(1);
}
if((res=pthread_create(&tid_keyboard,NULL/*&thread_attr*/,&thread_keyboard,
NULL)) != 0) {
fprintf(stderr,"Creating thread fail!\n");
exit(1);
}
pthread_join(tid_display, NULL);
pthread_join(tid_keyboard, NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -