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

📄 options.c

📁 一个很有名的浏览器
💻 C
📖 第 1 页 / 共 2 页
字号:
				}			}			free_options_tree(option->value.tree, recursive);			mem_free(option->value.tree);			break;		default:			break;	}	if (option->box_item)		done_listbox_item(&option_browser, option->box_item);	if (option->flags & OPT_ALLOC) {		mem_free_if(option->name);		mem_free(option);	} else if (!option->capt) {		/* We are probably dealing with a built-in autocreated option		 * that will be attempted to be deleted when shutting down. */		/* Clear it so nothing will be done later. */		memset(option, 0, sizeof(*option));	}}voidmark_option_as_deleted(struct option *option){	if (option->type == OPT_TREE) {		struct option *unmarked;		assert(option->value.tree);		foreach (unmarked, *option->value.tree)			mark_option_as_deleted(unmarked);	}	if (option->box_item) {		done_listbox_item(&option_browser, option->box_item);		option->box_item = NULL;	}	option->flags |= (OPT_TOUCHED | OPT_DELETED);}voiddelete_option(struct option *option){	delete_option_do(option, 1);}struct option *copy_option(struct option *template){	struct option *option = mem_calloc(1, sizeof(*option));	if (!option) return NULL;	option->name = null_or_stracpy(template->name);	option->flags = (template->flags | OPT_ALLOC);	option->type = template->type;	option->min = template->min;	option->max = template->max;	option->capt = template->capt;	option->desc = template->desc;	option->change_hook = template->change_hook;	option->box_item = init_option_listbox_item(option);	if (option->box_item) {		if (template->box_item) {			option->box_item->type = template->box_item->type;			option->box_item->depth = template->box_item->depth;		}	}	if (option_types[template->type].dup) {		option_types[template->type].dup(option, template);	} else {		option->value = template->value;	}	return option;}struct list_head *init_options_tree(void){	struct list_head *ptr = mem_alloc(sizeof(*ptr));	if (ptr) init_list(*ptr);	return ptr;}/* Some default pre-autocreated options. Doh. */static inline voidregister_autocreated_options(void){	/* TODO: Use table-driven initialization. --jonas */	get_opt_int("terminal.linux.type") = 2;	get_opt_int("terminal.linux.colors") = 1;	get_opt_bool("terminal.linux.m11_hack") = 1;	get_opt_int("terminal.vt100.type") = 1;	get_opt_int("terminal.vt110.type") = 1;	get_opt_int("terminal.xterm.type") = 1;	get_opt_bool("terminal.xterm.underline") = 1;	get_opt_int("terminal.xterm-color.type") = 1;	get_opt_int("terminal.xterm-color.colors") = COLOR_MODE_16;	get_opt_bool("terminal.xterm-color.underline") = 1;#ifdef CONFIG_256_COLORS	get_opt_int("terminal.xterm-256color.type") = 1;	get_opt_int("terminal.xterm-256color.colors") = COLOR_MODE_256;	get_opt_bool("terminal.xterm-256color.underline") = 1;#endif}static struct option_info config_options_info[];extern struct option_info cmdline_options_info[];static struct change_hook_info change_hooks[];voidinit_options(void){	cmdline_options = add_opt_tree_tree(&options_root, "", "",					    "cmdline", 0, "");	register_options(cmdline_options_info, cmdline_options);	config_options = add_opt_tree_tree(&options_root, "", "",					 "config", OPT_SORT, "");	config_options->flags |= OPT_LISTBOX;	config_options->box_item = &option_browser.root;	register_options(config_options_info, config_options);	register_autocreated_options();	register_change_hooks(change_hooks);}static voidfree_options_tree(struct list_head *tree, int recursive){	while (!list_empty(*tree))		delete_option_do(tree->next, recursive);}voiddone_options(void){	unregister_options(config_options_info, config_options);	unregister_options(cmdline_options_info, cmdline_options);	config_options->box_item = NULL;	free_options_tree(&options_root_tree, 0);}voidregister_change_hooks(struct change_hook_info *change_hooks){	int i;	for (i = 0; change_hooks[i].name; i++) {		struct option *option = get_opt_rec(config_options,						    change_hooks[i].name);		assert(option);		option->change_hook = change_hooks[i].change_hook;	}}voidunmark_options_tree(struct list_head *tree){	struct option *option;	foreach (option, *tree) {		option->flags &= ~OPT_WATERMARK;		if (option->type == OPT_TREE)			unmark_options_tree(option->value.tree);	}}voidwatermark_deleted_options(struct list_head *tree){	struct option *option;	foreach (option, *tree) {		if (option->flags & OPT_DELETED)			option->flags |= OPT_WATERMARK;		else if (option->type == OPT_TREE)			watermark_deleted_options(option->value.tree);	}}static intcheck_nonempty_tree(struct list_head *options){	struct option *opt;	foreach (opt, *options) {		if (opt->type == OPT_TREE) {			if (check_nonempty_tree(opt->value.tree))				return 1;		} else if (!(opt->flags & OPT_WATERMARK)) {			return 1;		}	}	return 0;}voidsmart_config_string(struct string *str, int print_comment, int i18n,		    struct list_head *options, unsigned char *path, int depth,		    void (*fn)(struct string *, struct option *,			       unsigned char *, int, int, int, int)){	struct option *option;	foreach (option, *options) {		int do_print_comment = 1;		if (option->flags & OPT_HIDDEN ||		    option->flags & OPT_WATERMARK ||		    option->type == OPT_ALIAS ||		    !strcmp(option->name, "_template_"))			continue;		/* Is there anything to be printed anyway? */		if (option->type == OPT_TREE		    && !check_nonempty_tree(option->value.tree))			continue;		/* We won't pop out the description when we're in autocreate		 * category and not template. It'd be boring flood of		 * repetitive comments otherwise ;). */		/* This print_comment parameter is weird. If it is negative, it		 * means that we shouldn't print comments at all. If it is 1,		 * we shouldn't print comment UNLESS the option is _template_		 * or not-an-autocreating-tree (it is set for the first-level		 * autocreation tree). When it is 2, we can print out comments		 * normally. */		/* It is still broken somehow, as it didn't work for terminal.*		 * (the first autocreated level) by the time I wrote this. Good		 * summer job for bored mad hackers with spare boolean mental		 * power. I have better things to think about, personally.		 * Maybe we should just mark autocreated options somehow ;). */		if (!print_comment || (print_comment == 1					&& (strcmp(option->name, "_template_")					    && (option->flags & OPT_AUTOCREATE					        && option->type == OPT_TREE))))			do_print_comment = 0;		/* Pop out the comment */		/* For config file, we ignore do_print_comment everywhere		 * except 1, but sometimes we want to skip the option totally.		 */		fn(str, option, path, depth,		   option->type == OPT_TREE ? print_comment					    : do_print_comment,		   0, i18n);		fn(str, option, path, depth, do_print_comment, 1, i18n);		/* And the option itself */		if (option_types[option->type].write) {			fn(str, option, path, depth,			   do_print_comment, 2, i18n);		} else if (option->type == OPT_TREE) {			struct string newpath;			int pc = print_comment;			if (!init_string(&newpath)) continue; /* OK? */			if (pc == 2 && option->flags & OPT_AUTOCREATE)				pc = 1;			else if (pc == 1 && strcmp(option->name, "_template_"))				pc = 0;			fn(str, option, path, depth, /*pc*/1, 3, i18n);			if (path) {				add_to_string(&newpath, path);				add_char_to_string(&newpath, '.');			}			add_to_string(&newpath, option->name);			smart_config_string(str, pc, i18n, option->value.tree,					    newpath.source, depth + 1, fn);			done_string(&newpath);			fn(str, option, path, depth, /*pc*/1, 3, i18n);		}		/* TODO: We should maybe clear the touched flag only when really		 * saving the stuff...? --pasky */		option->flags &= ~OPT_TOUCHED;	}}static intchange_hook_cache(struct session *ses, struct option *current, struct option *changed){	shrink_memory(0);	return 0;}static intchange_hook_connection(struct session *ses, struct option *current, struct option *changed){	register_bottom_half((void (*)(void *)) check_queue, NULL);	return 0;}static intchange_hook_html(struct session *ses, struct option *current, struct option *changed){	draw_formatted(ses, 1);	load_frames(ses, ses->doc_view);	process_file_requests(ses);	print_screen_status(ses);	return 0;}static intchange_hook_insert_mode(struct session *ses, struct option *current, struct option *changed){	update_status();	return 0;}static intchange_hook_active_link(struct session *ses, struct option *current, struct option *changed){	if (!global_doc_opts) return 0;	global_doc_opts->active_link_fg = get_opt_color("document.browse.links.active_link.colors.text");	global_doc_opts->active_link_bg = get_opt_color("document.browse.links.active_link.colors.background");	global_doc_opts->color_active_link = get_opt_bool("document.browse.links.active_link.enable_color");	global_doc_opts->invert_active_link = get_opt_bool("document.browse.links.active_link.invert");	global_doc_opts->underline_active_link = get_opt_bool("document.browse.links.active_link.underline");	global_doc_opts->bold_active_link = get_opt_bool("document.browse.links.active_link.bold");	return 0;}static intchange_hook_terminal(struct session *ses, struct option *current, struct option *changed){	cls_redraw_all_terminals();	return 0;}static intchange_hook_ui(struct session *ses, struct option *current, struct option *changed){	update_status();	return 0;}/* Bit 2 of show means we should always set visibility, otherwise we set it * only on templates. */static voidupdate_visibility(struct list_head *tree, int show){	struct option *opt;	foreach (opt, *tree) {		if (!strcmp(opt->name, "_template_")) {			if (opt->box_item)				opt->box_item->visible = (show & 1);			if (opt->type == OPT_TREE)				update_visibility(opt->value.tree, show | 2);		} else {			if (opt->box_item && (show & 2))				opt->box_item->visible = (show & 1);			if (opt->type == OPT_TREE)				update_visibility(opt->value.tree, show);		}	}}voidupdate_options_visibility(void){	update_visibility(config_options->value.tree,			  get_opt_bool("config.show_template"));}static intchange_hook_stemplate(struct session *ses, struct option *current, struct option *changed){	update_visibility(config_options->value.tree, changed->value.number);	return 0;}static intchange_hook_language(struct session *ses, struct option *current, struct option *changed){#ifdef ENABLE_NLS	set_language(changed->value.number);#endif	return 0;}static struct change_hook_info change_hooks[] = {	{ "config.show_template",	change_hook_stemplate },	{ "connection",			change_hook_connection },	{ "document.browse",		change_hook_html },	{ "document.browse.forms.insert_mode",					change_hook_insert_mode },	{ "document.browse.links.active_link",					change_hook_active_link },	{ "document.cache",		change_hook_cache },	{ "document.codepage",		change_hook_html },	{ "document.colors",		change_hook_html },	{ "document.html",		change_hook_html },	{ "document.plain",		change_hook_html },	{ "terminal",			change_hook_terminal },	{ "ui.language",		change_hook_language },	{ "ui",				change_hook_ui },	{ NULL,				NULL },};intcommit_option_values(struct option_resolver *resolvers,		     struct option *root, union option_value *values, int size){	int touched = 0;	int i;	assert(resolvers && root && values && size);	for (i = 0; i < size; i++) {		unsigned char *name = resolvers[i].name;		struct option *option = get_opt_rec(root, name);		int id = resolvers[i].id;		if (memcmp(&option->value, &values[id], sizeof(union option_value))) {			option->value = values[id];			option->flags |= OPT_TOUCHED;			touched++;		}	}	return touched;}voidcheckout_option_values(struct option_resolver *resolvers,		       struct option *root,		       union option_value *values, int size){	int i;	for (i = 0; i < size; i++) {		unsigned char *name = resolvers[i].name;		struct option *option = get_opt_rec(root, name);		int id = resolvers[i].id;		values[id] = option->value;	}}/********************************************************************** Options values**********************************************************************/#include "config/options.inc"voidregister_options(struct option_info info[], struct option *tree){	int i;	for (i = 0; info[i].path; i++) {		struct option *option = &info[i].option;		unsigned char *string;		debug_check_option_syntax(option);		if (option->type != OPT_ALIAS		    && ((tree->flags & OPT_LISTBOX)			|| (option->flags & OPT_LISTBOX))) {			option->box_item = init_option_listbox_item(option);			if (!option->box_item) {				delete_option(option);				continue;			}		}		switch (option->type) {			case OPT_TREE:				option->value.tree = init_options_tree();				if (!option->value.tree) {					delete_option(option);					continue;				}				break;			case OPT_STRING:				string = mem_alloc(MAX_STR_LEN);				if (!string) {					delete_option(option);					continue;				}				safe_strncpy(string, option->value.string, MAX_STR_LEN);				option->value.string = string;				break;			case OPT_COLOR:				string = option->value.string;				assert(string);				decode_color(string, strlen(string),						&option->value.color);				break;			case OPT_CODEPAGE:				string = option->value.string;				assert(string);				option->value.number = get_cp_index(string);				break;			case OPT_BOOL:			case OPT_INT:			case OPT_LONG:			case OPT_LANGUAGE:			case OPT_COMMAND:			case OPT_ALIAS:				break;		}		add_opt_rec(tree, info[i].path, option);	}}voidunregister_options(struct option_info info[], struct option *tree){	int i = 0;	/* We need to remove the options in inverse order to the order how we	 * added them. */	while (info[i].path) i++;	for (i--; i >= 0; i--)		delete_option_do(&info[i].option, 0);}

⌨️ 快捷键说明

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