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

📄 view.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
	return init_growing_view (view, 0, filename);
    }

    /* First, try to open a compressed file */
    if (view->viewer_magic_flag && (is_gunzipable (view->file, &type)) != 0){
	close_view_file (view);
	if (vfs_file_is_local (filename)) {
	    char *tmp = name_quote (filename, 0);
	    cmd = copy_strings (decompress_command (type), " ", tmp, 0);
	    free (tmp);
	}
	else {
	    char *tmp;
	    if ((view->localcopy = mc_getlocalcopy (filename)) == 0)
		return set_view_init_error (view, _(" Can not fetch local copy ") );
	    tmp = name_quote (view->localcopy, 0);
	    cmd = copy_strings (decompress_command (type), " ", tmp, 0);
	    free (tmp);
	}
        return init_growing_view (view, cmd, filename);
    }

    /* Otherwise, the file wasn't compressed */
#ifdef HAVE_MMAP
    view->data = mc_mmap (0, view->s.st_size, PROT_READ, MAP_FILE | MAP_SHARED,
		          view->file, 0);
    if ((caddr_t) view->data == (caddr_t) -1){
	close_view_file (view);
/*	set_view_init_error (view, 0);
	return copy_strings (" Can't mmap file \n ",
			     unix_error_string (errno), " ", 0);*/
	return init_growing_view (view, 0, filename);

    }

    view->first = 0;
    view->bytes_read = view->s.st_size;
    view->mmapping = 1;
    return 0;
#else /* ! HAVE_MMAP */
	/*
	**	For those OS that dont provide mmap call. Try to load all the file
	**	into memory (alex@bcs.zaporizhzhe.ua)
	*/
	view->data = (char*) xmalloc (view->s.st_size, "load_view_file");
    if (view->data == NULL
		|| mc_lseek(view->file,0,0) != 0
		|| mc_read(view->file, view->data, view->s.st_size) != view->s.st_size
	) {
		if (view->data != NULL)
			free(view->data);
		close_view_file (view);
		return init_growing_view (view, 0, filename);
    }
    view->first = 0;
    view->bytes_read = view->s.st_size;
    return 0;
#endif
}

/* Return zero on success, -1 on failure */
int
do_view_init (WView *view, char *_command, char *_file, int start_line)
{
    char *error = 0;
    int i;

    if (view->view_active)
	view_done (view);

    /* Set up the state */
    view->block_ptr = 0;
    view->data = NULL;
    view->growing_buffer = 0;
    view->reading_pipe = 0;
    view->mmapping = 0;
    view->blocks = 0;
    view->block_ptr = 0;
    view->first = view->bytes_read = 0;
    view->last_byte = 0;
    view->filename = 0;
    view->localcopy = 0;
    view->command = 0;
    view->last = view->first + ((LINES-2) * view->bytes_per_line);

    /* Clear the markers */
    view->marker = 0;
    for (i = 0; i < 10; i++)
	view->marks [i] = 0;


    if (!view->have_frame){
	view->start_col = 0;
    }
    if (_command && (view->viewer_magic_flag || _file[0] == '\0'))
	error = init_growing_view (view, _command, _file);
    else
	error = load_view_file (view, _file);

    if (error){
	if (!view->have_frame){
	    message (1, MSG_ERROR, error);
	    free (error);
	    return -1;
	}
    }

    view->view_active = 1;
    view->filename = strdup (_file);
    if (_command)
    	view->command = strdup (_command);
    else
    	view->command = 0;
    view->search_start = view->start_display = view->start_save = view->first;
    view->found_len = 0;
    view->start_col = 0;
    view->last_search = 0;            /* Start a new search */

    /* Special case: The data points to the error message */
    if (error){
	view->data = error;
	view->s.st_size = view->bytes_read = strlen (view->data);
    }
    view->last_byte = view->first + view->s.st_size;

    if (start_line > 1 && !error){
        int saved_wrap_mode = view->wrap_mode;

        view->wrap_mode = 0;
	get_byte (view, 0);
	view_move_forward (view, start_line - 1);
        view->wrap_mode = saved_wrap_mode;
    }
    view->edit_cursor = view->first;
    view->file_dirty =  0;
    view->nib_shift = 0;
    view->view_side = view_side_left;
    view->change_list = NULL;

    return 0;
}


/* Both views */
/* Return zero on success, -1 on failure */
int
view_init (WView *view, char *_command, char *_file, int start_line)
{
    int cols;

    if (view->have_frame)
	cols = view->widget.cols - 2;
    else
	cols = view->widget.cols;

    view->bottom_first = -1;
    view->bytes_per_line = 2 * (cols - 7) / 9;
    view->bytes_per_line &= 0xfffc;
    view->dirty = max_dirt_limit + 1;	/* To force refresh */
    if (!view->view_active || strcmp (_file, view->filename) || altered_magic_flag)
	return do_view_init (view, _command, _file, start_line);
    else
	return 0;
}

/* }}} */

/* {{{ Screen update functions */

#ifndef HAVE_X
void
view_percent (WView *view, int p, int w)
{
    int percent;

    percent = (view->s.st_size == 0 || view->last_byte == view->last) ? 100 :
        (p > (INT_MAX/100) ?
         p / (view->s.st_size / 100) :
	 p * 100 / view->s.st_size);

#if 0
    percent = view->s.st_size == 0 ? 100 :
	(view->last_byte == view->last ? 100 :
	 (p)*100 / view->s.st_size);
#endif

    widget_move (view, view->have_frame, w - 5);
    printw ("%3d%% ", percent);
}

void
view_status (WView *view)
{
    int w = view->widget.cols - (view->have_frame * 2);
    int i;

    attrset (SELECTED_COLOR);
    widget_move (view, view->have_frame, view->have_frame);
    hline (' ', w);
    if (w > 6){
    	i = w > 24 ? 18 : w - 6;
    	printw (_("File: %s"), name_trunc (view->filename ? view->filename:
					view->command ? view->command:"", i));
    	if (w > 30){
    	    widget_move (view, view->have_frame, 24);
            if (view->hex_mode)
                printw (_("Offset 0x%08x"), view->edit_cursor);
            else
		printw (_("Col %d"), -view->start_col);
    	}
    	if (w > 60){
	    widget_move (view, view->have_frame, 42);
	    printw (_("%s bytes"), size_trunc (view->s.st_size));
        }
	if (w > 70){
	    printw (" ");
	    if (view->growing_buffer)
		addstr (_("  [grow]"));
	}
        if (w - i > 4)
            if (view->hex_mode)
                view_percent (view, view->edit_cursor - view->first, w);
            else
	        view_percent (view, view->start_display - view->first, w);
    }
    attrset (SELECTED_COLOR);
}

#define view_set_color(view,font) attrset (font)

static inline void
view_display_clean (WView *view, int height, int width)
{
    /* FIXME: Should I use widget_erase only and repaint the box? */
    if (view->have_frame){
	int i;

	draw_double_box (view->widget.parent, view->widget.y, view->widget.x,
		         view->widget.lines, view->widget.cols);
	for (i = 1; i < height; i++){
	    widget_move (view, i, 1);
	    printw ("%*s", width-1, "");
	}
    } else
	widget_erase ((Widget *) view);
}

#define view_add_character(view,c) addch (c)
#define view_add_string(view,s)    addstr (s)
#define view_gotoyx(v,r,c)    widget_move (v,r,c)
#endif

#ifndef HAVE_TK
/* Both the text mode and gnome editions use this */
#define BOLD_COLOR        MARKED_COLOR
#define UNDERLINE_COLOR   VIEW_UNDERLINED_COLOR
#define MARK_COLOR        SELECTED_COLOR
#define DEF_COLOR         NORMAL_COLOR
#endif

#ifndef PORT_HAS_VIEW_FREEZE
#    define view_freeze(view)
#    define view_thaw(view)
#endif

#ifdef HAVE_GNOME
#    define PICK_COLOR(a,b) BOLD_COLOR : DEF_COLOR
#else
#    define PICK_COLOR(a,b) a : b
#endif

/* Shows the file pointed to by *start_display on view_win */
static long
display (WView *view)
{
#ifdef HAVE_X
#   define frame_shift  0
#   define STATUS_LINES 0
#else
    const int frame_shift = view->have_frame;
#   define STATUS_LINES 1
#endif
    int col = 0 + frame_shift;
    int row = STATUS_LINES + frame_shift;
    int height, width;
    long from;
    int c;
    int boldflag = 0;
    struct hexedit_change_node *curr = view->change_list;

    height = view->widget.lines - frame_shift;
    width = view->widget.cols - frame_shift;
    from = view->start_display;
    view_set_color (view, DEF_COLOR);

    view_freeze (view);
    view_display_clean (view, height, width);

    /* Optionally, display a ruler */
    if ((!view->hex_mode) && (ruler)){
	char r_buff[4];
	int cl;

	view_set_color (view, BOLD_COLOR);
	for (c = frame_shift; c < width; c++) {
	    cl = c-view->start_col;
	    if (ruler == 1)
		view_gotoyx (view, row, c);
	    else
		view_gotoyx (view, row+height-2, c);
	    r_buff[0] = '-';
	    if ((cl % 10) == 0)
		r_buff[0] = '|';
	    else
		if ((cl % 5) == 0)
		    r_buff[0] = '*';
	    view_add_character (view, r_buff[0]);
	    if ((cl != 0) && (cl % 10) == 0){
		sprintf(r_buff, "%03d", cl);
		if (ruler == 1)
		    widget_move (view, row + 1, c - 1);
		else
		    widget_move (view, row + height - 3, c - 1);
                view_add_string (view, r_buff);
	    }
	}
	view_set_color (view, DEF_COLOR);
	if (ruler == 1)
	    row += 2;
	else
	    height -= 2;
    }

    /* Find the first displayable changed byte */
    while (curr) {
        if (curr->offset < from)
            curr = curr->next;
        else
            break;
    }
    if (view->hex_mode){
        char hex_buff[10];   /* A temporary buffer for sprintf and mvwaddstr */
        int bytes;	     /* Number of bytes already printed on the line */

	/* Start of text column */
        int text_start = width - view->bytes_per_line - 1 + frame_shift;

        for (;row < height && from < view->last_byte; row++){
            /* Print the hex offset */
            sprintf (hex_buff, "%05X", (int) (from - view->first));
	    widget_move (view, row, frame_shift);
            view_add_string (view, hex_buff);

            /* Hex dump starts from column seven */
            col = 7;

            /* Each hex number is two digits */
            hex_buff[2] = 0;
            for (bytes = 0; bytes < view->bytes_per_line
		 && from < view->last_byte; bytes++, from++){
                /* Display and mark changed bytes */
                if (curr && from == curr->offset) {
                    c = curr->value;
                    curr = curr->next;
                    boldflag = 3;
                    view_set_color (view, 7);
                } else
                c = (unsigned char) get_byte (view, from);

	    	if (view->found_len && from >= view->search_start
		    && from < view->search_start + view->found_len){
	    	    boldflag = 1;
		    view_set_color (view, BOLD_COLOR);
	    	}
                /* Display the navigation cursor */
                if (from == view->edit_cursor) {
		    if (view->view_side == view_side_left){
			view->cursor_row = row;
			view->cursor_col = col;
		    }
                    boldflag = 2;
                    view_set_color (view, view->view_side == view_side_left ? PICK_COLOR (15, 31));
                }

                /* Print a hex number (sprintf is too slow) */
                hex_buff [0] = hex_char [(c >> 4)];
                hex_buff [1] = hex_char [c & 15];
		view_gotoyx (view, row, col);
                view_add_string (view, hex_buff);
                col += 3;
                /* Turn off the cursor or changed byte highlighting here */
                if (boldflag > 1)
                    view_set_color (view, DEF_COLOR);
                if ((bytes & 3) == 3 && bytes + 1 < view->bytes_per_line){
                    /* Turn off the search highlighting */
                    if (boldflag == 1 &&
                            from == view->search_start + view->found_len - 1)
                        view_set_color (view, DEF_COLOR);

                    /* Hex numbers are printed in the groups of four */
                    /* Groups are separated by a vline */

                    view_add_character (view, ' ');
                    one_vline ();
		    view_gotoyx (view, row, col + 1);
                    col += 2;

                    if (boldflag && from==view->search_start+view->found_len-1)
                    	view_set_color (view, BOLD_COLOR);

                }
                if (boldflag && from < view->search_start + view->found_len - 1
                    && bytes != view->bytes_per_line - 1)
                    view_add_character (view, ' ');

                /* Print the corresponding ascii character */
		view_gotoyx (view, row, text_start + bytes);

                if (!is_printable (c))
                    c = '.';
                switch (boldflag) {
                    default:
                        break;
                    case 1:
                        view_set_color (view, BOLD_COLOR);
                        goto setcursor;
                    case 2:
                        view_set_color (view, view->view_side == view_side_left ? PICK_COLOR (31, 15));
                        goto setcursor;
                    case 3:
                        view_set_color (view, 7);

                    setcursor:
		    if (view->view_side == view_side_right){
			view->cursor_col = text_start + bytes;
			view->cursor_row = row;
		    }
		}
		view_add_character (view, c);

                if (boldflag){
                    boldflag = 0;
                    view_set_color (view, DEF_COLOR);
                }
            }
        }
    } else {
        if (view->growing_buffer && from == view->last_byte)
            get_byte (view, from);
    	for (; row < height && from < view->last_byte; from++){
	    c = get_byte (view, from);
    	    if ((c == '\n') || (col == width && view->wrap_mode)){
       	        col = frame_shift;
       	        row++;
		if (c == '\n' || row >= height)
		    continue;
       	    }
	    if (c == '\r')
		continue;
       	    if (c == '\t'){
       	        col = ((col - frame_shift)/8)*8 + 8 + frame_shift;
       	        continue;
       	    }
	    if (view->viewer_nroff_flag && c == '\b'){
	    	if (from + 1 < view->last_byte
		    && is_printable (get_byte (view, from + 1)) &&
	    	    from > view->first
		    && is_printable (get_byte (view, from - 1)))
		{
		    if (col <= frame_shift){
		    	/* So it has to be wrap_mode - do not need to check for it */
		    	if (row == 1 + frame_shift){
		    	    from++;
		    	    continue; /* There had to be a bold character on the rightmost position
		    	    		 of the previous undisplayed line */
		    	}
		    	row--;
		    	col = width;
		    }
		    col--;
		    boldflag = 1;
		    if (get_byte (view, from - 1) == '_' && get_byte (view, from + 1) != '_')
		    	view_set_color (view, UNDERLINE_COLOR);
		    else
		    	view_set_color (view, BOLD_COLOR);
		    continue;
		}
	    }
	    if (view->found_len && from >= view->search_start
		&& from < view->search_start + view->found_len){
	    	boldflag = 1;
		view_set_color (view, MARK_COLOR);
	    }
       	    if (col >= frame_shift-view->start_col
		&& col < width-view->start_col)
	    {
		view_gotoyx (view, row, col+view->start_col);
       		if (!is_printable (c))
		    c = '.';

		view_add_character (view, c);
       	    }
	    col++;
	    if (boldflag){
		boldflag = 0;

⌨️ 快捷键说明

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