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

📄 help.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
		break;
	    case CHAR_BOLD_OFF:
		attrset (HELP_NORMAL_COLOR);
		break;
	    case '\n':
		line++;
		col = 0;
		break;
	    case '\t':
		col = (col/8 + 1) * 8;
		break;
	    case CHAR_MCLOGO:
	    case CHAR_TEXTONLY_START:
	    case CHAR_TEXTONLY_END:
		break;
	    case CHAR_XONLY_START:
		while (*p && *p != CHAR_NODE_END && *p != CHAR_XONLY_END)
		    p++;
		if (*p == CHAR_NODE_END || !*p)
		    p--;
		break;
	    default:
		if (!painting)
		    continue;
		if (col > HELP_WINDOW_WIDTH-1)
		    continue;

		dlg_move (h, line+2, col+2);
		if (acs){
		    if (c == ' ' || c == '.')
			addch (c);
		    else
#ifndef OS2_NT
#ifndef HAVE_SLANG
			addch (acs_map [c]);
#else
			SLsmg_draw_object (h->y + line + 2, h->x + col + 2, c);
#endif
#else
			addch (acs2pc (c));
#endif /* OS2_NT */
		} else
		    addch (c);
		col++;
		break;
	    }
	}
	last_shown = p;
	end_of_node = line < help_lines;
	attrset (HELP_NORMAL_COLOR);
	if (selected_item >= last_shown){
	    if (link_area != NULL){
		selected_item = link_area->link_name;
		repeat_paint = 1;
	    }
	    else
		selected_item = NULL;
	}
    } while (repeat_paint);

    /* Position the cursor over a nice link */
    if (active_col)
	dlg_move (h, active_line, active_col);
}

static int help_event (Gpm_Event *event, Widget *w)
{
    Link_Area *current_area;

    if (! (event->type & GPM_UP))
	return 0;

    /* The event is relative to the dialog window, adjust it: */
    event->y -= 2;

    if (event->buttons & GPM_B_RIGHT){
	currentpoint = startpoint = history [history_ptr].page;
	selected_item = history [history_ptr].link;
	history_ptr--;
	if (history_ptr < 0)
	    history_ptr = HISTORY_SIZE-1;

	help_callback (w->parent, 0, DLG_DRAW);
	return 0;
    }

    /* Test whether the mouse click is inside one of the link areas */
    current_area = link_area;
    while (current_area)
    {
	/* Test one line link area */
	if (event->y == current_area->y1 && event->x >= current_area->x1 &&
	    event->y == current_area->y2 && event->x <= current_area->x2)
	    break;
	/* Test two line link area */
	if (current_area->y1 + 1 == current_area->y2){
	    /* The first line */
	    if (event->y == current_area->y1 && event->x >= current_area->x1)
		break;
	    /* The second line */
	    if (event->y == current_area->y2 && event->x <= current_area->x2)
		break;
	}
	/* Mouse will not work with link areas of more than two lines */

	current_area = current_area -> next;
    }

    /* Test whether a link area was found */
    if (current_area){
	/* The click was inside a link area -> follow the link */
	history_ptr = (history_ptr+1) % HISTORY_SIZE;
	history [history_ptr].page = currentpoint;
	history [history_ptr].link = current_area->link_name;
	currentpoint = startpoint = help_follow_link (currentpoint, current_area->link_name);
	selected_item = NULL;
    } else{
	if (event->y < 0)
	    move_backward (help_lines - 1);
	else if (event->y >= help_lines)
	    move_forward (help_lines - 1);
	else if (event->y < help_lines/2)
	    move_backward (1);
	else
	    move_forward (1);
    }

    /* Show the new node */
    help_callback (w->parent, 0, DLG_DRAW);

    return 0;
}

/* show help */
void help_help_cmd (Dlg_head *h)
{
    history_ptr = (history_ptr+1) % HISTORY_SIZE;
    history [history_ptr].page = currentpoint;
    history [history_ptr].link = selected_item;
    currentpoint = startpoint = search_string (data, "[How to use help]") + 1;
    selected_item = NULL;
#ifndef HAVE_XVIEW
    help_callback (h, 0, DLG_DRAW);
#endif
}

void help_index_cmd (Dlg_head *h)
{
    char *new_item;

    history_ptr = (history_ptr+1) % HISTORY_SIZE;
    history [history_ptr].page = currentpoint;
    history [history_ptr].link = selected_item;
    currentpoint = startpoint = search_string (data, "[Help]") + 1;

    if (!(new_item = search_string (data, "[Contents]")))
	message (1, MSG_ERROR, _(" Can't find node [Contents] in help file "));
    else
	currentpoint = startpoint = new_item + 1;
    selected_item = NULL;
#ifndef HAVE_XVIEW
    help_callback (h, 0, DLG_DRAW);
#endif
}

static void quit_cmd (void *x)
{
    Dlg_head *h = (Dlg_head *) x;

    dlg_stop (x);
}

static void prev_node_cmd (Dlg_head *h)
{
    currentpoint = startpoint = history [history_ptr].page;
    selected_item = history [history_ptr].link;
    history_ptr--;
    if (history_ptr < 0)
	history_ptr = HISTORY_SIZE-1;

#ifndef HAVE_XVIEW
    help_callback (h, 0, DLG_DRAW);
#endif
}

static int md_callback (Dlg_head *h, Widget *w, int msg, int par)
{
    return default_proc (h, msg, par);
}

static Widget *mousedispatch_new (int y, int x, int yl, int xl)
{
    Widget *w = xmalloc (sizeof (Widget), "disp_new");

    init_widget (w, y, x, yl, xl,
		 (callback_fn) md_callback, 0, (mouse_h)  help_event, NULL);

    return w;
}

static int help_handle_key (struct Dlg_head *h, int c)
{
    char *new_item;

    if (c != KEY_UP && c != KEY_DOWN &&
	check_movement_keys (c, 1, help_lines, currentpoint,
			     (movefn) move_backward2,
			     (movefn) move_forward2,
			     (movefn) move_to_top,
			     (movefn) move_to_bottom))
	/* Nothing */;
    else switch (c){
    case 'l':
    case KEY_LEFT:
	prev_node_cmd (h);
	break;

    case '\n':
    case KEY_RIGHT:
	/* follow link */
	if (!selected_item){
#ifdef WE_WANT_TO_GO_BACKWARD_ON_KEY_RIGHT
	    /* Is there any reason why the right key would take us
	     * backward if there are no links selected?, I agree
	     * with Torben than doing nothing in this case is better
	     */
	    /* If there are no links, go backward in history */
	    history_ptr--;
	    if (history_ptr < 0)
		history_ptr = HISTORY_SIZE-1;

	    currentpoint = startpoint = history [history_ptr].page;
	    selected_item   = history [history_ptr].link;
#endif
	} else {
	    history_ptr = (history_ptr+1) % HISTORY_SIZE;
	    history [history_ptr].page = currentpoint;
	    history [history_ptr].link = selected_item;
	    currentpoint = startpoint = help_follow_link (currentpoint, selected_item) + 1;
	}
	selected_item = NULL;
	break;

    case KEY_DOWN:
    case '\t':
	/* select next link */
	new_item = select_next_link (startpoint, selected_item);
	if (new_item){
	    selected_item = new_item;
	    if (selected_item >= last_shown){
		if (c == KEY_DOWN)
		    move_forward (1);
		else
		    selected_item = NULL;
	    }
	} else if (c == KEY_DOWN)
	    move_forward (1);
	else
	    selected_item = NULL;
	break;

    case KEY_UP:
    case ALT ('\t'):
	/* select previous link */
	new_item = select_prev_link (startpoint, selected_item);
	selected_item = new_item;
	if (selected_item < currentpoint || selected_item >= last_shown){
	    if (c == KEY_UP)
		move_backward (1);
	    else{
		if (link_area != NULL)
		    selected_item = link_area->link_name;
		else
		    selected_item = NULL;
	    }
	}
	break;

    case 'n':
	/* Next node */
	new_item = currentpoint;
	while (*new_item && *new_item != CHAR_NODE_END)
	    new_item++;
	if (*++new_item == '['){
	    while (*new_item != ']')
		new_item++;
	    currentpoint = new_item + 2;
	    selected_item = NULL;
	}
	break;

    case 'p':
	/* Previous node */
	new_item = currentpoint;
	while (new_item > data + 1 && *new_item != CHAR_NODE_END)
	    new_item--;
	new_item--;
	while (new_item > data && *new_item != CHAR_NODE_END)
	    new_item--;
	while (*new_item != ']')
	    new_item++;
	currentpoint = new_item + 2;
	selected_item = NULL;
	break;

    case 'c':
	help_index_cmd (h);
	break;

    case ESC_CHAR:
    case XCTRL('g'):
	dlg_stop (h);
	break;

    default:
	return 0;

    }
    help_callback (h, 0, DLG_DRAW);
    return 1;
}

static int help_callback (struct Dlg_head *h, int id, int msg)
{
    switch (msg){
    case DLG_DRAW:
	attrset (HELP_NORMAL_COLOR);
	dlg_erase (h);
	draw_box (h, 1, 1, help_lines+2, HELP_WINDOW_WIDTH+2);
	attrset (COLOR_HOT_NORMAL);
	dlg_move (h, 1, (HELP_WINDOW_WIDTH - 1) / 2);
	addstr (_(" Help "));
	attrset (HELP_NORMAL_COLOR);
	show (h, currentpoint);
	break;

    case DLG_KEY:
	return help_handle_key (h, id);
    }
    return 0;
}

void interactive_display_finish (void)
{
    clear_link_areas ();
    free (data);
}

void interactive_display (char *filename, char *node)
{
    WButtonBar *help_bar;
    Widget     *md;

    if ((data = load_file (filename)) == 0){
	message (1, MSG_ERROR, _(" Can't open file %s \n %s "),
		 filename, unix_error_string (errno));
	return;
    }
    if (!(main = search_string (data, node))){
	message (1, MSG_ERROR, _(" Can't find node %s in help file "), node);
	interactive_display_finish ();
	return;
    }

#ifndef HAVE_X
    if (help_lines > LINES - 4)
	help_lines = LINES - 4;

    whelp = create_dlg (0, 0, help_lines+4, HELP_WINDOW_WIDTH+4, dialog_colors,
			help_callback, "[Help]", "help", DLG_TRYUP|DLG_CENTER);

    /* allow us to process the tab key */
    whelp->raw = 1;

#endif
    selected_item = search_string_node (main, STRING_LINK_START) - 1;
    currentpoint = startpoint = main + 1;

    for (history_ptr = HISTORY_SIZE; history_ptr;){
	history_ptr--;
	history [history_ptr].page = currentpoint;
	history [history_ptr].link = selected_item;
    }

#ifndef HAVE_X
    help_bar = buttonbar_new (keybar_visible);
    help_bar->widget.y -= whelp->y;
    help_bar->widget.x -= whelp->x;

    md       = mousedispatch_new (1, 1, help_lines, HELP_WINDOW_WIDTH-2);

    add_widget (whelp, help_bar);
    add_widget (whelp, md);

    define_label_data (whelp, (Widget *)NULL, 1, _("Help"),
		       (buttonbarfn) help_help_cmd, whelp);
    define_label_data (whelp, (Widget *)NULL, 2, _("Index"),
		       (buttonbarfn) help_index_cmd,whelp);
    define_label_data (whelp, (Widget *)NULL, 3, _("Prev"),
		       (buttonbarfn) prev_node_cmd, whelp);
    define_label (whelp, (Widget *) NULL, 4, "", 0);
    define_label (whelp, (Widget *) NULL, 5, "", 0);
    define_label (whelp, (Widget *) NULL, 6, "", 0);
    define_label (whelp, (Widget *) NULL, 7, "", 0);
    define_label (whelp, (Widget *) NULL, 8, "", 0);
    define_label (whelp, (Widget *) NULL, 9, "", 0);
    define_label_data (whelp, (Widget *) NULL, 10, _("Quit"), quit_cmd, whelp);

    run_dlg (whelp);
    interactive_display_finish ();
    destroy_dlg (whelp);
#else
    x_interactive_display ();
#endif
}

⌨️ 快捷键说明

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