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

📄 help.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Hypertext file browser.
   Copyright (C) 1994, 1995 Miguel de Icaza.
   Copyright (C) 1994, 1995 Janne Kukonlehto

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

   Implements the hypertext file viewer.
   The hypertext file is a file that may have one or more nodes.  Each
   node ends with a ^D character and starts with a bracket, then the
   name of the node and then a closing bracket.

   Links in the hypertext file are specified like this: the text that
   will be highlighted should have a leading ^A, then it comes the
   text, then a ^B indicating that highlighting is done, then the name
   of the node you want to link to and then a ^C.

   The file must contain a ^D at the beginning and at the end of the
   file or the program will not be able to detect the end of file.

   Lazyness/widgeting attack: This file does use the dialog manager
   and uses mainly the dialog to achieve the help work.  there is only
   one specialized widget and it's only used to forward the mouse messages
   to the appropiate routine.

*/

#include <config.h>
#include "tty.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <malloc.h>
#include <errno.h>
#include <string.h>
#include "mad.h"
#include "color.h"
#include "util.h"
#include "dialog.h"
#include "win.h"
#include "global.h"
#include "mouse.h"
#include "key.h"	/* For mi_getch() */
#include "help.h"
#include "layout.h"		/* keybar_visible */
#include "x.h"
#include "dlg.h"		/* For Dlg_head */
#include "widget.h"		/* For Widget */

#ifdef HAVE_TK
#    include "tkmain.h"
#endif

#define MAXLINKNAME 80
#define HISTORY_SIZE 20
#define HELP_WINDOW_WIDTH 62

/* "$Id: help.c 15218 2005-05-11 16:50:39Z weiden $" */

static char *data;		/* Pointer to the loaded data file */
static int help_lines = 18;	/* Lines in help viewer */
static int  history_ptr;	/* For the history queue */
static char *main;		/* The main node */
static char *last_shown = 0;	/* Last byte shown in a screen */
static int end_of_node = 0;	/* Flag: the last character of the node shown? */
char *currentpoint, *startpoint;
static char *selected_item;

/* The widget variables */
static Dlg_head *whelp;

static struct {
    char *page;			/* Pointer to the selected page */
    char *link;			/* Pointer to the selected link */
} history [HISTORY_SIZE];

/* Link areas for the mouse */
typedef struct Link_Area {
    int x1, y1, x2, y2;
    char *link_name;
    struct Link_Area *next;
} Link_Area;

static Link_Area *link_area = NULL;
static int inside_link_area = 0;

static int help_callback (struct Dlg_head *h, int id, int msg);

#ifdef OS2_NT
struct {
    int acscode;
    int pccode;
} acs2pc_table [] = {
    { 'q',  0xC4 },
    { 'x',  0xB3 },
    { 'l',  0xDA },
    { 'k',  0xBF },
    { 'm',  0xC0 },
    { 'j',  0xD9 },
    { 'a',  0xB0 },
    { 'u',  0xB4 },
    { 't',  0xC3 },
    { 'w',  0xC2 },
    { 'v',  0xC1 },
    { 'n',  0xC5 },
    { 0, 0 } };

static int acs2pc (int acscode)
{
    int i;

    for (i = 0; acs2pc_table[i].acscode != 0; i++)
	if (acscode == acs2pc_table[i].acscode) {
	    return acs2pc_table[i].pccode;
	}
    return 0;
}
#endif

/* returns the position where text was found in the start buffer */
/* or 0 if not found */
char *search_string (char *start, char *text)
{
    char *d = text;
    char *e = start;

    /* fmt sometimes replaces a space with a newline in the help file */
    /* Replace the newlines in the link name with spaces to correct the situation */
    while (*d){
	if (*d == '\n')
	    *d = ' ';
	d++;
    }
    /* Do search */
    for (d = text; *e; e++){
	if (*d == *e)
	    d++;
	else
	    d = text;
	if (!*d)
	    return e+1;
    }
    return 0;
}

/* Searches text in the buffer pointed by start.  Search ends */
/* if the CHAR_NODE_END is found in the text.  Returns 0 on failure */
static char *search_string_node (char *start, char *text)
{
    char *d = text;
    char *e = start;

    if (!start)
	return 0;

    for (; *e && *e != CHAR_NODE_END; e++){
	if (*d == *e)
	    d++;
	else
	    d = text;
	if (!*d)
	    return e+1;
    }
    return 0;
}

/* Searches the_char in the buffer pointer by start and searches */
/* it can search forward (direction = 1) or backward (direction = -1) */
static char *search_char_node (char *start, char the_char, int direction)
{
    char *e;

    e = start;

    for (; *e && (*e != CHAR_NODE_END); e += direction){
	if (*e == the_char)
	    return e;
    }
    return 0;
}

/* Returns the new current pointer when moved lines lines */
static char *move_forward2 (char *c, int lines)
{
    char *p;
    int  line;

    currentpoint = c;
    for (line = 0, p = currentpoint; *p && *p != CHAR_NODE_END; p++){
	if (line == lines)
	    return currentpoint = p;
	if (*p == '\n')
	    line++;
    }
    return currentpoint = c;
}

static char *move_backward2 (char *c, int lines)
{
    char *p;
    int line;

    currentpoint = c;
    for (line = 0, p = currentpoint; *p && p >= data; p--){
	if (*p == CHAR_NODE_END)
	{
	    /* We reached the beginning of the node */
	    /* Skip the node headers */
	    while (*p != ']') p++;
	    return currentpoint = p + 2;
	}
	if (*(p - 1) == '\n')
	    line++;
	if (line == lines)
	    return currentpoint = p;
    }
    return currentpoint = c;
}

static void move_forward (int i)
{
    if (end_of_node)
	return;
    currentpoint = move_forward2 (currentpoint, i);
}

static void move_backward (int i)
{
    currentpoint = move_backward2 (currentpoint, ++i);
}

static void move_to_top (int dummy)
{
    while (currentpoint > data && *currentpoint != CHAR_NODE_END)
	currentpoint--;
    while (*currentpoint != ']')
	currentpoint++;
    currentpoint = currentpoint + 1;
    selected_item = NULL;
}

static void move_to_bottom (int dummy)
{
    while (*currentpoint && *currentpoint != CHAR_NODE_END)
	currentpoint++;
    currentpoint--;
    move_backward (help_lines - 1);
}

char *help_follow_link (char *start, char *selected_item)
{
    char link_name [MAXLINKNAME];
    char *p;
    int  i = 0;

    if (!selected_item)
	return start;

    for (p = selected_item; *p && *p != CHAR_NODE_END && *p != CHAR_LINK_POINTER; p++)
	;
    if (*p == CHAR_LINK_POINTER){
	link_name [0] = '[';
	for (i = 1; *p != CHAR_LINK_END && *p && *p != CHAR_NODE_END && i < MAXLINKNAME-3; )
	    link_name [i++] = *++p;
	link_name [i-1] = ']';
	link_name [i] = 0;
	p = search_string (data, link_name);
	if (p)
	    return p;
    }
    return _(" Help file format error\n\x4");	/*  */
}

static char *select_next_link (char *start, char *current_link)
{
    char *p;

    if (!current_link)
	return 0;

    p = search_string_node (current_link, STRING_LINK_END);
    if (!p)
	return NULL;
    p = search_string_node (p, STRING_LINK_START);
    if (!p)
	return NULL;
    return p - 1;
}

static char *select_prev_link (char *start, char *current_link)
{
    char *p;

    if (!current_link)
	return 0;

    p = current_link - 1;
    if (p <= start)
	return 0;

    p = search_char_node (p, CHAR_LINK_START, -1);
    return p;
}

static void start_link_area (int x, int y, char *link_name)
{
    Link_Area *new;

    if (inside_link_area)
	message (0, _(" Warning "), _(" Internal bug: Double start of link area "));

    /* Allocate memory for a new link area */
    new = (Link_Area*) xmalloc (sizeof (Link_Area), "Help, link_area");
    new->next = link_area;
    link_area = new;

    /* Save the beginning coordinates of the link area */
    link_area->x1 = x;
    link_area->y1 = y;

    /* Save the name of the destination anchor */
    link_area->link_name = link_name;

    inside_link_area = 1;
}

static void end_link_area (int x, int y)
{
    if (inside_link_area){
	/* Save the end coordinates of the link area */
	link_area->x2 = x;
	link_area->y2 = y;

	inside_link_area = 0;
    }
}

static void clear_link_areas (void)
{
    Link_Area *current;

    while (link_area){
	current = link_area;
	link_area = current -> next;
	free (current);
    }
    inside_link_area = 0;
}

static void show (Dlg_head *h, char *paint_start)
{
    char *p;
    int  col, line, c;
    int  painting = 1;
    int acs;			/* Flag: Alternate character set active? */
    int repeat_paint;
    int active_col, active_line;/* Active link position */

    do {

	line = col = acs = active_col = active_line = repeat_paint = 0;

	clear_link_areas ();
	if (selected_item < paint_start)
	    selected_item = NULL;

	for (p = paint_start; *p != CHAR_NODE_END && line < help_lines; p++){
	    c = *p;
	    switch (c){
	    case CHAR_LINK_START:
		if (selected_item == NULL)
		    selected_item = p;
		if (p == selected_item){
		    attrset (HELP_SLINK_COLOR);

		    /* Store the coordinates of the link */
		    active_col = col + 2;
		    active_line = line + 2;
		}
		else
		    attrset (HELP_LINK_COLOR);
		start_link_area (col, line, p);
		break;
	    case CHAR_LINK_POINTER:
		painting = 0;
		end_link_area (col - 1, line);
		break;
	    case CHAR_LINK_END:
		painting = 1;
		attrset (HELP_NORMAL_COLOR);
		break;
	    case CHAR_ALTERNATE:
		acs = 1;
		break;
	    case CHAR_NORMAL:
		acs = 0;
		break;
	    case CHAR_VERSION:
		dlg_move (h, line+2, col+2);
		addstr (VERSION);
		col += strlen (VERSION);
		break;
	    case CHAR_BOLD_ON:
		attrset (HELP_BOLD_COLOR);
		break;
	    case CHAR_ITALIC_ON:
		attrset (HELP_ITALIC_COLOR);

⌨️ 快捷键说明

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