📄 xcurse.c
字号:
/* $Header: /home/hugh/sources/aee/RCS/Xcurse.c,v 1.36 1998/12/29 05:27:05 hugh Exp hugh $*/char *XCURSE_copyright_notice = "Copyright (c) 1987, 1988, 1991, 1992, 1994, 1995, 1996, 1998 Hugh Mahon.";char *XCURSE_version_string = "@(#) Xcurse.c $Revision: 1.36 $";#include "Xcurse.h"#include <X11/Xutil.h>#include <X11/keysym.h>#include <X11/keysymdef.h>#include "aee.h"#ifdef HAS_STDLIB#include <stdlib.h>#endif#if defined(__STDC__)#include <stdarg.h>#else#include <varargs.h>#endif#ifdef HAS_UNISTD#include <unistd.h>#endif#ifdef HAS_SYS_IOCTL#include <sys/ioctl.h>#endif#ifndef min#define min(a, b) ((a) < (b) ? (a) : (b))#endif /* min */extern int eightbit;static WINDOW *virtual_scr;WINDOW *curscr;WINDOW *stdscr;WINDOW *last_window_refreshed;WINDOW *clear_win;char *new_curse = "February 1988";int STAND = FALSE; /* is standout mode activated? */int Curr_x; /* current x position on screen */int Curr_y; /* current y position on the screen */int LINES;int COLS;int initialized = FALSE; /* tells whether new_curse is initialized */int Repaint_screen; /* if an operation to change screen impossible, repaint screen */int Num_bits; /* number of bits per character */int XKey_vals[] = { 84, 83, 82, 81, 89, 90, 91, 92, 0, 0, 0, 0, 134, 133, 132, 135, 127, 119, 111, 103, 102, 110, 94, 0, 0, 0, 0, 255};/* | names of keys used below obtained through XKeysymToString() */char *Key_strings[] = { "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "Up", "Down", "Left", "Right", "Next", "Prior", "Delete", "hpDeleteLine", "hpInsertLine", "Insert", "End", "hpInsertChar", "hpDeleteChar", "BackSpace", "Home", NULL };int Key_vals[] = { KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), KEY_F(11), KEY_F(12), KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_NPAGE, KEY_PPAGE, KEY_DC, KEY_DL, KEY_IL, KEY_IC, KEY_EOL, KEY_IC, KEY_DC, KEY_BACKSPACE, KEY_HOME};/* the following data should go into a data structure in a future version */Window wid; /* window id */Display *dp; /* display pointer */int Xscreen; /* screen */char *font_name; /* name of font to use */XFontStruct *xaefont; /* font information */int fontwidth, fontheight; /* font information */XSetWindowAttributes win_attrib; /* window attributes */XEvent event; /* event */XKeyEvent *keyevent; /* keyboard event structure */char *background; /* name of background color */char *foreground; /* name of foreground color */char *geometry; /* height, width, xoffset, yoffset */char reverse_video; /* reverse fore- and back-ground */int fore_pixel; /* the pixel value of the foreground color */int back_pixel; /* the pixel value of the background color */int temp_pixel; /* temporary storage */XColor Fore_color; /* struct holding foreground color values */XColor Back_color; /* struct holding background color values */XColor exact_def_return;Pixmap Fore_pixmap; /* foreground pixmap */Pixmap Back_pixmap; /* background pixmap */short bits;Colormap colormap;GC gc, revgc, cursor_gc, cursor_revgc;XGCValues gcvalues;/* end of information to be put into a data structure at a future date */Pixmap Temp_pixmap; /* temporary storage, used when reversing colors */int xtemp, ytemp;#define icon_width 48#define icon_height 48static char icon_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0xf8, 0x03, 0x00, 0x04, 0x20, 0x00, 0x06, 0x0c, 0x00, 0x04, 0x20, 0x00, 0x01, 0x10, 0x00, 0x02, 0x40, 0x80, 0x00, 0x20, 0x00, 0x02, 0x40, 0x40, 0x00, 0x40, 0x00, 0x03, 0x80, 0x40, 0x00, 0x40, 0x00, 0xff, 0xff, 0x20, 0x00, 0x80, 0x80, 0x00, 0x00, 0x21, 0x00, 0x80, 0x80, 0x00, 0x00, 0xe1, 0xff, 0xff, 0x40, 0x00, 0x00, 0x22, 0x00, 0x80, 0x20, 0x00, 0x00, 0x26, 0x00, 0x00, 0x20, 0x00, 0x00, 0x24, 0x00, 0x00, 0x10, 0x00, 0x00, 0x24, 0x00, 0x00, 0x10, 0x00, 0x00, 0x48, 0x00, 0x00, 0x08, 0x00, 0x00, 0x48, 0x00, 0x00, 0x08, 0x00, 0x00, 0x90, 0x00, 0x10, 0x04, 0x00, 0x00, 0x10, 0x01, 0x08, 0x04, 0x00, 0x00, 0x20, 0x06, 0x04, 0x02, 0x00, 0x00, 0x20, 0xf8, 0x03};Pixmap pixmap;int *virtual_lines;/* | Copy the contents of one window to another. */void copy_window(origin, destination)WINDOW *origin, *destination;{ int row, column; struct _line *orig, *dest; orig = origin->first_line; dest = destination->first_line; for (row = 0; row < (min(origin->Num_lines, destination->Num_lines)); row++) { for (column = 0; column < (min(origin->Num_cols, destination->Num_cols)); column++) { dest->row[column] = orig->row[column]; dest->attributes[column] = orig->attributes[column]; } dest->changed = orig->changed; dest->scroll = orig->scroll; dest->last_char = min(orig->last_char, destination->Num_cols); orig = orig->next_screen; dest = dest->next_screen; } destination->LX = min((destination->Num_cols - 1), origin->LX); destination->LY = min((destination->Num_lines - 1), origin->LY); destination->Attrib = origin->Attrib; destination->scroll_up = origin->scroll_up; destination->scroll_down = origin->scroll_down; destination->SCROLL_CLEAR = origin->SCROLL_CLEAR;}void reinitscr() { WINDOW *local_virt; WINDOW *local_std; WINDOW *local_cur; local_virt = newwin(LINES, COLS, 0, 0); local_std = newwin(LINES, COLS, 0, 0); local_cur = newwin(LINES, COLS, 0, 0); copy_window(virtual_scr, local_virt); copy_window(stdscr, local_std); copy_window(curscr, local_cur); delwin(virtual_scr); delwin(stdscr); delwin(curscr); virtual_scr = local_virt; stdscr = local_std; curscr = local_cur; free(virtual_lines); virtual_lines = (int *) malloc(LINES * (sizeof(int)));}int argc1;char **argv1;void get_options(argc, argv) /* get arguments from original command line */int argc;char *argv[];{ char *buff; char *extens; int count; int ret_val; struct files *temp_names; int *x_off, *y_off; buff = ae_basename(argv[0]); if (!strcmp(buff, "rxae")) { restricted = TRUE; change_dir_allowed = FALSE; } argc1 = argc; argv1 = argv; x_off = (int *) &xtemp; y_off = (int *) &ytemp; if ((dp = XOpenDisplay(0)) == NULL) { printf("could not open display\n"); exit(-1); } Xscreen = DefaultScreen(dp); geometry = NULL; reverse_video = FALSE; foreground = NULL; background = NULL; font_name = NULL; get_defaults(); top_of_stack = NULL; echo_flag = TRUE; journ_on = TRUE; input_file = FALSE; recv_file = FALSE; recover = FALSE; count = 1; while (count < argc) { buff = argv[count]; if (*buff == '-') /* options */ { ++buff; if (*buff == 'j') /* turn off recover file */ journ_on = FALSE; else if (*buff == 'r') /* recover from bad exit */ recover = TRUE; else if (*buff == 'e') /* turn off echo in init file */ echo_flag = FALSE; else if (*buff == 'R') reverse_video = TRUE; else if (*buff == 'i') /* turn off info window */ info_window = FALSE; else if (!strcmp(argv[count], "-text")) { text_only = TRUE; } else if (!strcmp(argv[count], "-binary")) { text_only = FALSE; } else if (*buff == 't') /* expand tabs to spaces */ expand = TRUE; else if (*buff == 'n') /* turn off highlighting on menus*/ nohighlight = TRUE; else if (!strcmp(argv[count], "-fg")) { count++; foreground = argv[count]; } else if (!strcmp(argv[count], "-bg")) { count++; background = argv[count]; } else if (!strcmp(argv[count], "-fn")) { count++; font_name = argv[count]; } else if (!strncmp(buff, "geometry", strlen(buff))) { count++; geometry = argv[count]; } } else if (*buff == '+') { buff++; start_at_line = buff; } else /* if the argument wasn't an option, must be a file name, right? */ { if (top_of_stack == NULL) temp_names = top_of_stack = name_alloc(); else { temp_names->next_name = name_alloc(); temp_names = temp_names->next_name; } temp_names->next_name = NULL; extens = temp_names->name = xalloc(strlen(buff) + 1); while (*buff != (char) NULL) { *extens = *buff; buff++; extens++; } *extens = (char) NULL; input_file = TRUE; recv_file = TRUE; } count++; } if (geometry != NULL) ret_val = XParseGeometry(geometry, x_off, y_off, &COLS, &LINES); if (COLS == 0) COLS = 80; if (LINES == 0) LINES = 24; if (xtemp == 0) xtemp = 10; if (ytemp == 0) ytemp = 15; win_height = LINES; win_width = COLS;/* if (top_of_stack == NULL) { fprintf(stderr, usage_str, argv[0]); exit(0); }*/}void get_defaults(){ char *temp; geometry = XGetDefault(dp, "xae", "geometry"); foreground = XGetDefault(dp, "xae", "foreground"); background = XGetDefault(dp, "xae", "background"); font_name = XGetDefault(dp, "xae", "font"); temp = XGetDefault(dp, "xae", "ReverseVideo"); if ((temp != NULL) && (!strcmp(temp, "on"))) reverse_video = TRUE;}void initscr(cols, lines) /* initialize terminal for operations */int cols, lines;{ int temp_val; XSizeHints xsh; XWMHints wmHints;#ifdef DEBUG{/* | The following code will start an hpterm which will in turn execute | a debugger and "adopt" the process, so it can be debugged. */ int child_id; char command_line[256]; child_id = getpid(); if (!fork()) { sprintf(command_line, "hpterm -fg wheat -bg DarkSlateGrey -n %s -e xdb %s -P %d", "hello", "xae", child_id); execl("/bin/sh", "sh", "-c", command_line, NULL); fprintf(stderr, "could not exec new window\n"); exit(1); }/* | When in debugger, set child_id to zero (p child_id=0) to continue | executing the software. */ while (child_id != 0) ;}#endif LINES = lines; COLS = cols; keyevent = (XKeyEvent *) &event; back_pixel = XWhitePixel(dp, Xscreen); fore_pixel = XBlackPixel(dp, Xscreen); colormap = XDefaultColormap(dp, Xscreen); if (DisplayPlanes(dp, Xscreen) > 1) { if (foreground == NULL) foreground = "white"; if (XParseColor(dp, colormap, foreground, &Fore_color) != 0) { XAllocColor(dp, colormap, &Fore_color); fore_pixel = Fore_color.pixel; } if (background == NULL) background = "#6B002F003100"; if (XParseColor(dp, colormap, background, &Back_color) != 0) { XAllocColor(dp, colormap, &Back_color); back_pixel = Back_color.pixel; } } if (reverse_video) { temp_pixel = fore_pixel; fore_pixel = back_pixel; back_pixel = temp_pixel; bits = 0x99; } if (font_name == NULL) { font_name = "6x10"; if ((XDisplayHeight(dp, Xscreen) > (LINES * 15)) && (XDisplayWidth(dp, Xscreen) > (COLS * 9))) font_name = "9x15"; } if ((xaefont = XLoadQueryFont(dp, font_name)) == NULL) { printf("could not open font \"%s\" \n", font_name); exit(-1); } fontwidth = xaefont->max_bounds.rbearing - xaefont->min_bounds.lbearing; fontheight = xaefont->max_bounds.ascent + xaefont->max_bounds.descent; if (xtemp < 0) { temp_val = XDisplayWidth(dp, Xscreen); xtemp = temp_val - ((COLS*fontwidth) - xtemp); } if (ytemp < 0) { temp_val = XDisplayHeight(dp, Xscreen); ytemp = (temp_val + ytemp) - (LINES*fontheight); } if ((wid = XCreateWindow(dp, RootWindow(dp, Xscreen), xtemp, ytemp, (COLS*fontwidth), (LINES*fontheight), 2, DefaultDepth(dp, Xscreen), InputOutput, DefaultVisual(dp, Xscreen), (CWBackPixel | CWColormap), &win_attrib)) == (Window) NULL) { printf("could not create window \n"); exit(-1); }/* | Try to set up some default values and icon information */ pixmap = XCreateBitmapFromData(dp, wid, icon_bits, icon_width, icon_height); xsh.height = fontheight * LINES; xsh.width = fontwidth * COLS; xsh.base_height = xsh.height; xsh.base_width = xsh.width; xsh.max_width = XDisplayWidth(dp, DefaultScreen(dp)); xsh.max_height = XDisplayHeight(dp, DefaultScreen(dp)); xsh.min_height = fontheight * 24; xsh.min_width = fontwidth * 40; xsh.x = xtemp; xsh.y = ytemp; xsh.width_inc = fontwidth; xsh.height_inc = fontheight; xsh.flags = (USPosition | PSize | PResizeInc ); XSetStandardProperties(dp, wid, "xae", "xae", pixmap, argv1, argc1, &xsh); win_attrib.override_redirect = FALSE; XSetWindowBackground(dp, wid, back_pixel); XChangeWindowAttributes (dp, wid, CWOverrideRedirect, &win_attrib); gcvalues.font = xaefont->fid; gcvalues.foreground = fore_pixel; gcvalues.background = back_pixel; gcvalues.function = GXcopy; gc = XCreateGC(dp, wid, (GCFont | GCForeground | GCBackground | GCFunction), &gcvalues); gcvalues.background = fore_pixel; gcvalues.foreground = back_pixel; revgc = XCreateGC(dp, wid, (GCFont | GCForeground | GCBackground | GCFunction), &gcvalues); gcvalues.foreground = fore_pixel; gcvalues.background = back_pixel; gcvalues.function = GXcopy; cursor_gc = XCreateGC(dp, wid, (GCFont | GCForeground | GCBackground | GCFunction), &gcvalues); gcvalues.background = fore_pixel; gcvalues.foreground = back_pixel; cursor_revgc = XCreateGC(dp, wid, (GCFont | GCForeground | GCBackground | GCFunction), &gcvalues); XSetLineAttributes(dp, gc, 1, LineSolid, CapButt, JoinMiter); XSetLineAttributes(dp, revgc, 1, LineSolid, CapButt, JoinMiter); XSetLineAttributes(dp, cursor_gc, 1, LineSolid, CapButt, JoinMiter); XSetLineAttributes(dp, cursor_revgc, 1, LineSolid, CapButt, JoinMiter); XMapWindow(dp, wid); XStoreName(dp, wid, "xae"); wmHints.initial_state = NormalState; wmHints.icon_pixmap = pixmap; wmHints.flags = IconPixmapHint | StateHint; XSetWMHints(dp, wid, &wmHints); XSelectInput(dp, wid, (KeyPress | ButtonPress | ButtonRelease | Expose)); XFlush(dp); Key_Get(); virtual_lines = (int *) malloc(LINES * (sizeof(int))); virtual_scr = newwin(LINES, COLS, 0, 0); stdscr = newwin(LINES, COLS, 0, 0); curscr = newwin(LINES, COLS, 0, 0); wmove(stdscr, 0, 0); werase(stdscr); Repaint_screen = TRUE; initialized = TRUE;}void Key_Get(){ int counter; for (counter = 0; Key_strings[counter] != NULL; counter++) XKey_vals[counter] = XStringToKeysym(Key_strings[counter]);}struct _line *Screenalloc(columns)int columns;{ int i; struct _line *tmp; tmp = (struct _line *) malloc(sizeof (struct _line)); tmp->row = malloc(columns + 1); tmp->attributes = malloc(columns + 1); tmp->prev_screen = NULL; tmp->next_screen = NULL; for (i = 0; i < columns; i++) { tmp->row[i] = ' '; tmp->attributes[i] = (char) NULL; } tmp->scroll = tmp->changed = FALSE; tmp->row[0] = (char) NULL; tmp->attributes[0] = (char) NULL; tmp->row[columns] = (char) NULL; tmp->attributes[columns] = (char) NULL; tmp->last_char = 0; return(tmp);}WINDOW *newwin(lines, cols, start_l, start_c)int lines, cols; /* number of lines and columns to be in window */int start_l, start_c; /* starting line and column to be inwindow */{ WINDOW *Ntemp; struct _line *temp_screen; int i; Ntemp = (WINDOW *) malloc(sizeof(WINDOW)); Ntemp->SR = start_l; Ntemp->SC = start_c; Ntemp->Num_lines = lines; Ntemp->Num_cols = cols; Ntemp->LX = 0; Ntemp->LY = 0; Ntemp->scroll_down = Ntemp->scroll_up = 0; Ntemp->SCROLL_CLEAR = FALSE; Ntemp->Attrib = FALSE; Ntemp->first_line = temp_screen = Screenalloc(cols); Ntemp->first_line->number = 0; Ntemp->line_array = (struct _line **) malloc(LINES * sizeof(struct _line *)); Ntemp->line_array[0] = Ntemp->first_line; for (i = 1; i < lines; i++) { temp_screen->next_screen = Screenalloc(cols); temp_screen->next_screen->number = i; temp_screen->next_screen->prev_screen = temp_screen; temp_screen = temp_screen->next_screen; Ntemp->line_array[i] = temp_screen; } Ntemp->first_line->prev_screen = NULL; temp_screen->next_screen = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -