📄 xcurse.c
字号:
value = 0; while ((*fpoint >= '0') && (*fpoint <= '9')) { value = (value * 8) + (*fpoint - '0'); fpoint++; } waddch(window, value); } fpoint++; } else waddch(window, *fpoint++); }#ifdef __STDC__ va_end(ap);#endif /* __STDC__ */}void iout(window, value, base) /* output characters */WINDOW *window;int value;int base; /* base of number to be printed */{ int i; if ((i = value / base) != 0) iout(window, i, base); waddch(window, ((value % base) + '0'));}int Comp_line(line1, line2) /* compare lines */struct _line *line1;struct _line *line2;{ int count1; int i; char *att1, *att2; char *c1, *c2; if (line1->last_char != line2->last_char) return(2); c1 = line1->row; c2 = line2->row; att1 = line1->attributes; att2 = line2->attributes; i = 0; while ((c1[i] != (char) NULL) && (c2[i] != (char) NULL) && (c1[i] == c2[i]) && (att1[i] == att2[i])) i++; count1 = i + 1; if ((count1 == 1) && (c1[i] == (char) NULL) && (c2[i] == (char) NULL)) count1 = 0; /* both lines blank */ else if ((c1[i] == (char) NULL) && (c2[i] == (char) NULL)) count1 = -1; /* equal */ else count1 = 1; /* lines unequal */ return(count1);}struct _line *Insert_line(row, end_row, window) /* insert line into screen */int row;int end_row;WINDOW *window;{ int i; struct _line *tmp; struct _line *tmp1; int wind_y_offset; for (i = 0, tmp = curscr->first_line; i < window->SR; i++) tmp = tmp->next_screen; if ((end_row + window->SR) == 0) curscr->first_line = curscr->first_line->next_screen; top_of_win = tmp; for (i = 0, tmp = top_of_win; (tmp->next_screen != NULL) && (i < end_row); i++) tmp = tmp->next_screen; if (tmp->prev_screen != NULL) tmp->prev_screen->next_screen = tmp->next_screen; if (tmp->next_screen != NULL) tmp->next_screen->prev_screen = tmp->prev_screen; tmp1 = tmp; clear_line(tmp, 0, window->Num_cols); tmp1->number = -1; for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++) tmp = tmp->next_screen; top_of_win = tmp; for (i = 0, tmp = top_of_win; i < row; i++) tmp = tmp->next_screen; if ((tmp->prev_screen != NULL) && (window->Num_lines > 0)) tmp->prev_screen->next_screen = tmp1; tmp1->prev_screen = tmp->prev_screen; tmp->prev_screen = tmp1; tmp1->next_screen = tmp; if ((row + window->SR) == 0) curscr->first_line = tmp1; if (tmp1->next_screen != NULL) tmp1 = tmp1->next_screen; wind_y_offset = window->SR * fontheight; XCopyArea(dp, wid, wid, gc, 0, (wind_y_offset + (row * fontheight)), (COLS * fontwidth), ((end_row - row) * fontheight), 0, (wind_y_offset + ((1 + row) * fontheight))); XClearArea(dp, wid, 0, (wind_y_offset + (row * fontheight)), (COLS * fontwidth), fontheight, FALSE); XFlush(dp); for (i = 0, top_of_win = curscr->first_line; (top_of_win->next_screen != NULL) && (i < window->SR); i++) top_of_win = top_of_win->next_screen; return(tmp1);}struct _line *Delete_line(row, end_row, window) /* delete a line on screen */int row;int end_row;WINDOW *window;{ int i; struct _line *tmp; struct _line *tmp1; struct _line *tmp2; int wind_y_offset; i = 0; tmp = curscr->first_line; while (i < window->SR) { i++; tmp = tmp->next_screen; } top_of_win = tmp; if ((row + window->SR) == 0) curscr->first_line = top_of_win->next_screen; for (i = 0, tmp = top_of_win; i < row; i++) tmp = tmp->next_screen; if (tmp->prev_screen != NULL) tmp->prev_screen->next_screen = tmp->next_screen; if (tmp->next_screen != NULL) tmp->next_screen->prev_screen = tmp->prev_screen; tmp2 = tmp->next_screen; tmp1 = tmp; clear_line(tmp1, 0, window->Num_cols); tmp1->number = -1; for (i = 0, tmp = curscr->first_line; (tmp->next_screen != NULL) && (i < window->SR); i++) tmp = tmp->next_screen; top_of_win = tmp; for (i = 0, tmp = top_of_win; (i < end_row) && (tmp->next_screen != NULL); i++) tmp = tmp->next_screen; tmp1->next_screen = tmp; tmp1->prev_screen = tmp->prev_screen; if (tmp1->prev_screen != NULL) tmp1->prev_screen->next_screen = tmp1; tmp->prev_screen = tmp1; wind_y_offset = window->SR * fontheight; XCopyArea(dp, wid, wid, gc, 0, (wind_y_offset + ((row + 1) * fontheight)), (COLS * fontwidth), ((end_row - row) * fontheight), 0, (wind_y_offset + (row * fontheight))); XClearArea(dp, wid, 0, (wind_y_offset + (end_row * fontheight)), (COLS * fontwidth), fontheight, FALSE); XFlush(dp);/* if (row == (window->Num_lines-1)) tmp2 = tmp1; if ((row + window->SR) == 0) curscr->first_line = top_of_win = tmp2;*/ return(tmp2);}void CLEAR_TO_EOL(window, row, column)WINDOW *window;int row, column;{ int x, y, width, height; struct _line *tmp1; for (y = 0, tmp1 = curscr->first_line; (y < (window->SR+row)) && (tmp1->next_screen != NULL); y++) tmp1 = tmp1->next_screen; for (x = column; x<window->Num_cols; x++) { tmp1->row[x] = ' '; tmp1->attributes[x] = (char) NULL; } tmp1->row[column] = (char) NULL; tmp1->last_char = column; if (column <= tmp1->last_char) { x = column * fontwidth; y = (row + window->SR) * fontheight; width = (COLS - column) * fontwidth; height = fontheight; XClearArea(dp, wid, x, y, width, height, FALSE); }}void doupdate(){ WINDOW *window; int similar; int diff; int begin_old, begin_new; int count1, j; int i; int from_top, tmp_ft, offset; int changed; int first_same; /* first line from bottom where diffs occur */ int last_same; /* first line from top which is same */ int bottom; struct _line *curr; struct _line *virt; struct _line *old; struct _line *new; struct _line *old1, *new1; char *cur_lin; char *vrt_lin; char *cur_att; char *vrt_att; window = virtual_scr; if (Repaint_screen) { for (i = 0, curr = curscr->first_line; i < curscr->Num_lines; i++, curr = curr->next_screen) { Position(curscr, i, 0); for (j = 0; (curr->row[j] != (char) NULL) && (j < curscr->Num_cols); j++) { Char_out(curr->row[j], curr->attributes[j], curr->row, curr->attributes, j); } if (STAND) STAND = FALSE; } Repaint_screen = FALSE; } similar = 0; diff = FALSE; top_of_win = curscr->first_line; for (from_top = 0, curr = top_of_win, virt = window->first_line; from_top < window->Num_lines; from_top++) { virtual_lines[from_top] = TRUE; if ((similar = Comp_line(curr, virt)) > 0) { virtual_lines[from_top] = FALSE; diff = TRUE; } curr = curr->next_screen; virt = virt->next_screen; } from_top = 0; virt = window->first_line; curr = top_of_win; similar = 0; /* | if the window has lines that are different */ if (diff) { last_same = -1; changed = FALSE; for (first_same = window->Num_lines; (first_same > from_top) && (virtual_lines[first_same - 1]); first_same--) ; for (last_same = 0; (last_same < window->Num_lines) && (virtual_lines[last_same] == FALSE); last_same++) ; while (from_top < first_same) /* check entire lines for diffs */ { if (from_top >= last_same) { for (last_same = from_top; (last_same < window->Num_lines) && (virtual_lines[last_same] == FALSE); last_same++) ; } if (!virtual_lines[from_top]) { diff = TRUE; /* | check for lines deleted (scroll up) */ for (tmp_ft = from_top+1, old = curr->next_screen; ((window->scroll_up) && (diff) && (tmp_ft < last_same) && (!virtual_lines[tmp_ft])); tmp_ft++) { if ((Comp_line(old, virt) == -1) && (!virtual_lines[from_top])) { /* | Find the bottom of the | area that should be | scrolled. */ for (bottom = tmp_ft, old1 = old, new1 = virt, count1 = 0; (bottom < window->Num_lines) && (Comp_line(old1, new1) <= 0); bottom++, old1 = old1->next_screen, new1 = new1->next_screen, count1++) ; if (count1 > 3) { for (offset = (tmp_ft - from_top); (offset > 0); offset--) { old = Delete_line(from_top, min((bottom - 1), (window->Num_lines - 1)), window); diff = FALSE; } top_of_win = curscr->first_line; curr = top_of_win; for (offset = 0; offset < from_top; offset++) curr = curr->next_screen; for (offset = from_top, old=curr, new=virt; offset < window->Num_lines; old=old->next_screen, new=new->next_screen, offset++) { similar = Comp_line(old, new); virtual_lines[offset] = (similar > 0 ? FALSE : TRUE); } } } else old = old->next_screen; } /* | check for lines inserted (scroll down) */ for (tmp_ft = from_top-1, old = curr->prev_screen; ((window->scroll_down) && (tmp_ft >= 0) && (diff) && (!virtual_lines[tmp_ft])); tmp_ft--) { if (Comp_line(old, virt) == -1) { /* | Find the bottom of the | area that should be | scrolled. */ for (bottom = from_top, old1 = old, new1 = virt, count1 = 0; (bottom < window->Num_lines) && (Comp_line(old1, new1) <= 0); bottom++, old1 = old1->next_screen, new1 = new1->next_screen, count1++) ; if (count1 > 3) { for (offset = (from_top - tmp_ft); (offset > 0); offset--) { old = Insert_line(tmp_ft, min((bottom - 1), (window->Num_lines -1)), window); diff = FALSE; } top_of_win = curscr->first_line; curr = top_of_win; for (offset = 0; offset < from_top; offset++) curr = curr->next_screen; for (offset = from_top, old=curr, new=virt; offset < window->Num_lines; old=old->next_screen, new=new->next_screen, offset++) { similar = Comp_line(old, new); virtual_lines[offset] = (similar > 0 ? FALSE : TRUE); } } } else old = old->prev_screen; } } from_top++; curr = curr->next_screen; virt = virt->next_screen; } } for (from_top = 0, curr = curscr->first_line; from_top < window->SR; from_top++) curr = curr->next_screen; top_of_win = curr; for (from_top = 0, curr = top_of_win, virt = window->first_line; from_top < window->Num_lines; from_top++, curr = curr->next_screen, virt = virt->next_screen) { if (Comp_line(curr, virt) > 0) { j = 0; cur_lin = curr->row; cur_att = curr->attributes; vrt_lin = virt->row; vrt_att = virt->attributes; while ((j < window->Num_cols) && (vrt_lin[j] != (char) NULL)) { while ((cur_lin[j] == vrt_lin[j]) && (cur_att[j] == vrt_att[j]) && (j < window->Num_cols) && (vrt_lin[j] != (char) NULL)) j++; begin_old = j; begin_new = j; if ((j < window->Num_cols) && (vrt_lin[j] != (char) NULL)) { Position(window, from_top, begin_old); for (j = begin_old; (vrt_lin[j] != (char) NULL) && (j < window->Num_cols); j++) Char_out(vrt_lin[j], vrt_att[j], cur_lin, cur_att, j); } } if ((vrt_lin[j] == (char) NULL) && (cur_lin[j] != (char) NULL))/* if (j < curr->last_char) */ { Position(window, from_top, j); CLEAR_TO_EOL(window, from_top, j); } if (STAND) { STAND = FALSE; } curr->last_char = virt->last_char; virt->number = from_top; } } for (count1 = 0, virt = window->first_line; count1 < window->Num_lines; count1++) { window->line_array[count1] = virt; virt = virt->next_screen; } cursor(window, window->LY, window->LX, FALSE, FALSE);}void Position(window, row, col) /* position the cursor for output on the screen */WINDOW *window;int row;int col;{ int pos_row; int pos_column; pos_row = row + window->SR; pos_column = col + window->SC; Curr_x = pos_column; Curr_y = pos_row;}/* | the following routines are responsible for actually handling window | output */void Char_out(newc, newatt, line, attrib, offset) /* output character with proper attribute */char newc;char newatt;char *line;char *attrib;int offset;{ int x, y; if ((newatt) && (!STAND)) STAND = TRUE; else if ((STAND) && (!newatt)) STAND = FALSE; if (!((Curr_y >= (LINES - 1)) && (Curr_x >= (COLS - 1)))) { x = Curr_x * fontwidth; y = Curr_y * fontheight + xaefont->ascent; if (!STAND) XDrawImageString(dp, wid, gc, x, y, &newc, 1); else XDrawImageString(dp, wid, revgc, x, y, &newc, 1); Curr_x++; line[offset] = newc; attrib[offset] = newatt; }}void draw_cursor(visible)int visible; /* specify if cursor is to be visible */{ cursor(virtual_scr, virtual_scr->LY, virtual_scr->LX, FALSE, visible);}void cursor(window, row, col, erase, visible) /* draw the cursor at the designated position */WINDOW *window;int row;int col;int erase; /* erase the cursor on the screen */int visible;{ int x, y, y1; int reverse; int pos_row; int pos_column; static int last_row = -1; static int last_col = -1; static int last_x = -1; static int last_y = -1; struct _line *tmp1; char output_char; static int cursor_state = TRUE; if ((erase) && (last_row == -1)) return; tmp1 = curscr->first_line; if (erase) { Curr_x = last_col; Curr_y = last_row; /* | make sure the previous cursor position is still within | the window, since a resize could have made the window | smaller */ if ((Curr_y >= window->Num_lines) || (Curr_x >= window->Num_cols)) return; tmp1 = window->line_array[last_row]; } else { pos_row = row + window->SR; pos_column = col + window->SC; last_col = Curr_x = pos_column; last_row = Curr_y = pos_row; /* | make sure the previous cursor position is still within | the window, since a resize could have made the window | smaller */ if ((Curr_y >= window->Num_lines) || (Curr_x >= window->Num_cols)) return; tmp1 = window->line_array[pos_row]; } output_char = tmp1->row[Curr_x]; reverse = (tmp1->attributes[last_col] & A_STANDOUT); if (tmp1->row[Curr_x] == (char) NULL) { output_char = ' '; reverse = 0; } x = Curr_x * fontwidth; y = Curr_y * fontheight + xaefont->ascent; y1 = (1 + Curr_y) * fontheight ; if (erase) { if (!reverse) { XDrawImageString(dp, wid, gc, x, y, &output_char, 1); } else { XDrawImageString(dp, wid, revgc, x, y, &output_char, 1); } } else { if ((last_y == last_row) && (last_x == last_col)) { if ((cursor_state) && (!visible)) { if (reverse) XDrawImageString(dp, wid, revgc, x, y, &output_char, 1); else XDrawImageString(dp, wid, gc, x, y, &output_char, 1); } else { if (reverse) XDrawLine(dp, wid, cursor_revgc, x, y1, x, (y1 - fontheight)); else XDrawLine(dp, wid, cursor_gc, x, y1, x, (y1 - fontheight)); } cursor_state = !cursor_state; } else { XDrawLine(dp, wid, cursor_gc, x, y1, x, (y1 - fontheight)); cursor_state = TRUE; } if (visible) cursor_state = TRUE; last_y = last_row; last_x = last_col; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -