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

📄 menubar.c

📁 rxvt经典的linux下的终端.小巧实用
💻 C
📖 第 1 页 / 共 4 页
字号:
		    bar->next->prev = bar;		    r->h->Nbars++;		}		r->h->CurrentBar = bar;	    }	    rxvt_menubar_clear(r);	}    }/* give menubar this name */    STRNCPY(r->h->CurrentBar->name, name, MAXNAME);    r->h->CurrentBar->name[MAXNAME - 1] = '\0';    return ret;}/* switch to a menu called NAME and remove it *//* INTPROTO */voidrxvt_menubar_remove(rxvt_t *r, const char *name){    bar_t          *bar;    if ((bar = rxvt_menubar_find(r, name)) == NULL)	return;    r->h->CurrentBar = bar;    do {	rxvt_menubar_clear(r);	/*	 * pop a menubar, clean it up first	 */	if (r->h->CurrentBar != NULL) {	    bar_t          *prev = r->h->CurrentBar->prev;	    bar_t          *next = r->h->CurrentBar->next;	    if (prev == next && prev == r->h->CurrentBar) {	/* only 1 left */		prev = NULL;		r->h->Nbars = 0;	/* safety */	    } else {		next->prev = prev;		prev->next = next;		r->h->Nbars--;	    }	    free(r->h->CurrentBar);	    r->h->CurrentBar = prev;	}    }    while (r->h->CurrentBar && !STRCMP(name, "*"));}/* INTPROTO */voidrxvt_action_decode(FILE *fp, action_t *act){    unsigned char  *str;    short           len;    if (act == NULL || (len = act->len) == 0 || (str = act->str) == NULL)	return;    if (act->type == MenuTerminalAction) {	fprintf(fp, "^@");	/* can strip trailing ^G from XTerm sequence */	if (str[0] == C0_ESC && str[1] == ']' && str[len - 1] == C0_BEL)	    len--;    } else if (str[0] == C0_ESC) {	switch (str[1]) {	case '[':	case ']':	    break;	case 'x':	    /* can strip trailing '\r' from M-x sequence */	    if (str[len - 1] == '\r')		len--;	    /* FALLTHROUGH */	default:	    fprintf(fp, "M-");	/* meta prefix */	    str++;	    len--;	    break;	}    }/* * control character form is preferred, since backslash-escaping * can be really ugly looking when the backslashes themselves also * have to be escaped to avoid Shell (or whatever scripting * language) interpretation */    while (len > 0) {	unsigned char   ch = *str++;	switch (ch) {	case C0_ESC:	    fprintf(fp, "\\E");	    break;		/* escape */	case '\r':	    fprintf(fp, "\\r");	    break;		/* carriage-return */	case '\\':	    fprintf(fp, "\\\\");	    break;		/* backslash */	case '^':	    fprintf(fp, "\\^");	    break;		/* caret */	case 127:	    fprintf(fp, "^?");	default:	    if (ch <= 31)		fprintf(fp, "^%c", ('@' + ch));	    else if (ch > 127)		fprintf(fp, "\\%o", ch);	    else		fprintf(fp, "%c", ch);	    break;	}	len--;    }    fprintf(fp, "\n");}/* INTPROTO */voidrxvt_menu_dump(FILE *fp, menu_t *menu){    menuitem_t     *item;/* create a new menu and clear it */    fprintf(fp, (menu->parent ? "./%s/*\n" : "/%s/*\n"), menu->name);    for (item = menu->head; item != NULL; item = item->next) {	switch (item->entry.type) {	case MenuSubMenu:	    if (item->entry.submenu.menu == NULL)		fprintf(fp, "> %s == NULL\n", item->name);	    else		rxvt_menu_dump(fp, item->entry.submenu.menu);	    break;	case MenuLabel:	    fprintf(fp, "{%s}\n", (STRLEN(item->name) ? item->name : "-"));	    break;	case MenuTerminalAction:	case MenuAction:	    fprintf(fp, "{%s}", item->name);	    if (item->name2 != NULL && STRLEN(item->name2))		fprintf(fp, "{%s}", item->name2);	    fprintf(fp, "\t");	    rxvt_action_decode(fp, &(item->entry.action));	    break;	}    }    fprintf(fp, (menu->parent ? "../\n" : "/\n\n"));}/* INTPROTO */voidrxvt_menubar_dump(rxvt_t *r, FILE *fp){    bar_t          *bar = r->h->CurrentBar;    time_t          t;    if (bar == NULL || fp == NULL)	return;    time(&t);    fprintf(fp,	    "# " APL_SUBCLASS " (%s)  Pid: %u\n# Date: %s\n\n",	    r->h->rs[Rs_name], (unsigned int)getpid(), ctime(&t));/* dump in reverse order */    bar = r->h->CurrentBar->prev;    do {	menu_t         *menu;	int             i;	fprintf(fp, "[menu:%s]\n", bar->name);	if (bar->title != NULL)	    fprintf(fp, "[title:%s]\n", bar->title);	for (i = 0; i < NARROWS; i++) {	    switch (bar->arrows[i].type) {	    case MenuTerminalAction:	    case MenuAction:		fprintf(fp, "<%c>", Arrows[i].name);		rxvt_action_decode(fp, &(bar->arrows[i]));		break;	    }	}	fprintf(fp, "\n");	for (menu = bar->head; menu != NULL; menu = menu->next)	    rxvt_menu_dump(fp, menu);	fprintf(fp, "\n[done:%s]\n\n", bar->name);	bar = bar->prev;    }    while (bar != r->h->CurrentBar->prev);}#endif				/* (MENUBAR_MAX > 1) *//* * read in menubar commands from FILENAME * ignore all input before the tag line [menu] or [menu:???] * * Note that since File_find () is used, FILENAME can be semi-colon * delimited such that the second part can refer to a tag * so that a large `database' of menus can be collected together * * FILENAME = "file" * FILENAME = "file;" *      read `file' starting with first [menu] or [menu:???] line * * FILENAME = "file;tag" *      read `file' starting with [menu:tag] *//* EXTPROTO */voidrxvt_menubar_read(rxvt_t *r, const char *filename){/* read in a menu from a file */    FILE           *fp;    char            buffer[256];    char           *p, *file, *tag = NULL;    file = (char *)rxvt_File_find(filename, ".menu", r->h->rs[Rs_path]);    if (file == NULL)	return;    fp = fopen(file, "rb");    free(file);    if (fp == NULL)	return;#if (MENUBAR_MAX > 1)/* semi-colon delimited */    if ((tag = STRCHR(filename, ';')) != NULL) {	tag++;	if (*tag == '\0')	    tag = NULL;    }#endif				/* (MENUBAR_MAX > 1) */#ifdef DEBUG_MENU    fprintf(stderr, "[read:%s]\n", p);    if (tag)	fprintf(stderr, "looking for [menu:%s]\n", tag);#endif    while ((p = fgets(buffer, sizeof(buffer), fp)) != NULL) {	int             n;	if ((n = rxvt_Str_match(p, "[menu")) != 0) {	    if (tag) {		/* looking for [menu:tag] */		if (p[n] == ':' && p[n + 1] != ']') {		    n++;		    n += rxvt_Str_match(p + n, tag);		    if (p[n] == ']') {#ifdef DEBUG_MENU			fprintf(stderr, "[menu:%s]\n", tag);#endif			break;		    }		}	    } else if (p[n] == ':' || p[n] == ']')		break;	}    }/* found [menu], [menu:???] tag */    while (p != NULL) {	int             n;#ifdef DEBUG_MENU	fprintf(stderr, "read line = %s\n", p);#endif	/* looking for [done:tag] or [done:] */	if ((n = rxvt_Str_match(p, "[done")) != 0) {	    if (p[n] == ']') {		r->h->menu_readonly = 1;		break;	    } else if (p[n] == ':') {		n++;		if (p[n] == ']') {		    r->h->menu_readonly = 1;		    break;		} else if (tag) {		    n += rxvt_Str_match(p + n, tag);		    if (p[n] == ']') {#ifdef DEBUG_MENU			fprintf(stderr, "[done:%s]\n", tag);#endif			r->h->menu_readonly = 1;			break;		    }		} else {		    /* what? ... skip this line */		    p[0] = COMMENT_CHAR;		}	    }	}	/*	 * remove leading/trailing space	 * and strip-off leading/trailing quotes	 * skip blank or comment lines	 */	rxvt_Str_trim(p);	if (*p && *p != '#') {	    r->h->menu_readonly = 0;	/* if case we read another file */	    rxvt_menubar_dispatch(r, p);	}	/* get another line */	p = fgets(buffer, sizeof(buffer), fp);    }    fclose(fp);}/* * user interface for building/deleting and otherwise managing menus *//* EXTPROTO */voidrxvt_menubar_dispatch(rxvt_t *r, char *str){    int             n, cmd;    char           *path, *name, *name2;    if (menubar_visible(r) && r->h->ActiveMenu != NULL)	rxvt_menubar_expose(r);    else	r->h->ActiveMenu = NULL;    cmd = *str;    switch (cmd) {    case '.':    case '/':			/* absolute & relative path */    case MENUITEM_BEG:		/* menuitem */	/* add `+' prefix for these cases */	cmd = '+';	break;    case '+':    case '-':	str++;			/* skip cmd character */	break;    case '<':#if (MENUBAR_MAX > 1)	if (r->h->CurrentBar == NULL)	    break;#endif				/* (MENUBAR_MAX > 1) */	if (str[1] && str[2] == '>')	/* arrow commands */	    rxvt_menuarrow_add(r, str);	break;    case '[':			/* extended command */	while (str[0] == '[') {	    char           *next = (++str);	/* skip leading '[' */	    if (str[0] == ':') {	/* [:command:] */		do {		    next++;		    if ((next = STRCHR(next, ':')) == NULL)			return;	/* parse error */		}		while (next[1] != ']');		/* remove and skip ':]' */		*next = '\0';		next += 2;	    } else {		if ((next = STRCHR(next, ']')) == NULL)		    return;	/* parse error */		/* remove and skip ']' */		*next = '\0';		next++;	    }	    if (str[0] == ':') {		int             saved;		/* try and dispatch it, regardless of read/write status */		saved = r->h->menu_readonly;		r->h->menu_readonly = 0;		rxvt_menubar_dispatch(r, str + 1);		r->h->menu_readonly = saved;	    }	    /* these ones don't require menu stacking */	    else if (!STRCMP(str, "clear")) {		rxvt_menubar_clear(r);	    } else if (!STRCMP(str, "done") || rxvt_Str_match(str, "done:")) {		r->h->menu_readonly = 1;	    } else if (!STRCMP(str, "show")) {		rxvt_map_menuBar(r, 1);		r->h->menu_readonly = 1;	    } else if (!STRCMP(str, "hide")) {		rxvt_map_menuBar(r, 0);		r->h->menu_readonly = 1;	    } else if ((n = rxvt_Str_match(str, "read:")) != 0) {		/* read in a menu from a file */		str += n;		rxvt_menubar_read(r, str);	    } else if ((n = rxvt_Str_match(str, "title:")) != 0) {		str += n;		if (r->h->CurrentBar != NULL && !r->h->menu_readonly) {		    if (*str) {			name = rxvt_realloc(r->h->CurrentBar->title,					    STRLEN(str) + 1);			if (name != NULL) {			    STRCPY(name, str);			    r->h->CurrentBar->title = name;			}			rxvt_menubar_expose(r);		    } else {			free(r->h->CurrentBar->title);			r->h->CurrentBar->title = NULL;		    }		}	    } else if ((n = rxvt_Str_match(str, "pixmap:")) != 0) {		str += n;		rxvt_xterm_seq(r, XTerm_Pixmap, str, CHAR_ST);	    }#if (MENUBAR_MAX > 1)	    else if ((n = rxvt_Str_match(str, "rm")) != 0) {		str += n;		switch (str[0]) {		case ':':		    str++;		/* FALLTHROUGH */		case '\0':		/* FALLTHROUGH */		case '*':		    rxvt_menubar_remove(r, str);		    break;		}		r->h->menu_readonly = 1;	    } else if ((n = rxvt_Str_match(str, "menu")) != 0) {		str += n;		switch (str[0]) {		case ':':		    str++;		    /* add/access menuBar */		    if (*str != '\0' && *str != '*')			rxvt_menubar_push(r, str);		    break;		default:		    if (r->h->CurrentBar == NULL) {			rxvt_menubar_push(r, "default");		    }		}		if (r->h->CurrentBar != NULL)		    r->h->menu_readonly = 0;	/* allow menu build commands */	    } else if (!STRCMP(str, "dump")) {		/* dump current menubars to a file */		FILE           *fp;		/* enough space to hold the results */		char            buffer[32];		sprintf(buffer, "/tmp/" APL_SUBCLASS "-%u",			(unsigned int)getpid());		if ((fp = fopen(buffer, "wb")) != NULL) {		    rxvt_xterm_seq(r, XTerm_title, buffer, CHAR_ST);		    rxvt_menubar_dump(r, fp);		    fclose(fp);		}	    } else if (!STRCMP(str, "next")) {		if (r->h->CurrentBar) {		    r->h->CurrentBar = r->h->CurrentBar->next;		    r->h->menu_readonly = 1;		}	    } else if (!STRCMP(str, "prev")) {		if (r->h->CurrentBar) {		    r->h->CurrentBar = r->h->CurrentBar->prev;		    r->h->menu_readonly = 1;		}	    } else if (!STRCMP(str, "swap")) {		/* swap the top 2 menus */		if (r->h->CurrentBar) {		    bar_t          *cbprev = r->h->CurrentBar->prev;		    bar_t          *cbnext = r->h->CurrentBar->next;		    cbprev->next = cbnext;		    cbnext->prev = cbprev;		    r->h->CurrentBar->next = cbprev;		    r->h->CurrentBar->prev = cbprev->prev;		    cbprev->prev->next = r->h->CurrentBar;		    cbprev->prev = r->h->CurrentBar;		    r->h->CurrentBar = cbprev;		    r->h->menu_readonly = 1;		}	    }#endif				/* (MENUBAR_MAX > 1) */	    str = next;	    r->h->BuildMenu = r->h->ActiveMenu = NULL;	    rxvt_menubar_expose(r);#ifdef DEBUG_MENUBAR_STACKING	    fprintf(stderr, "menus are read%s\n",		    r->h->menu_readonly ? "only" : "/write");#endif	}	return;	break;    }#if (MENUBAR_MAX > 1)    if (r->h->CurrentBar == NULL)	return;    if (r->h->menu_readonly) {#ifdef DEBUG_MENUBAR_STACKING	fprintf(stderr, "menus are read%s\n",		r->h->menu_readonly ? "only" : "/write");#endif	return;    }#endif				/* (MENUBAR_MAX > 1) */    switch (cmd) {    case '+':    case '-':	path = name = str;	name2 = NULL;	/* parse STR, allow spaces inside (name)  */	if (path[0] != '\0') {	    name = STRCHR(path, MENUITEM_BEG);	    str = STRCHR(path, MENUITEM_END);	    if (name != NULL || str != NULL) {		if (name == NULL || str == NULL || str <= (name + 1)		    || (name > path && name[-1] != '/')) {		    rxvt_print_error("menu error <%s>\n", path);		    break;		}		if (str[1] == MENUITEM_BEG) {		    name2 = (str + 2);		    str = STRCHR(name2, MENUITEM_END);		    if (str == NULL) {			rxvt_print_error("menu error <%s>\n", path);			break;		    }		    name2[-2] = '\0';	/* remove prev MENUITEM_END */		}		if (name > path && name[-1] == '/')		    name[-1] = '\0';		*name++ = '\0';	/* delimit */		*str++ = '\0';	/* delimit */		while (isspace(*str))

⌨️ 快捷键说明

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