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

📄 rxvtlib_menubar.c

📁 具有IDE功能的编辑器
💻 C
📖 第 1 页 / 共 4 页
字号:
#include "rxvtlib.h"/*--------------------------------*-C-*---------------------------------* * File:	menubar.c *----------------------------------------------------------------------* * $Id: menubar.c,v 1.27 1999/01/23 14:26:36 mason Exp $ * * Copyright (C) 1997,1998  mj olesen <olesen@me.QueensU.CA> * * 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. *----------------------------------------------------------------------* * refer.html (or refer.txt) contains up-to-date documentation.  The * summary that appears at the end of this file was taken from there. *----------------------------------------------------------------------*/#ifdef MENUBAR	/* okay to alter menu? *//* (l)eft, (u)p, (d)own, (r)ight *//* str[0] = strlen (str+1) */	/* currently active menu */#endif/*}}} */#ifdef MENUBAR/* * find an item called NAME in MENU *//* INTPROTO */menuitem_t     *menuitem_find (const menu_t * menu, const char *name){    menuitem_t     *item;    assert (name != NULL);    assert (menu != NULL);/* find the last item in the menu, this is good for separators */    for (item = menu->tail; item != NULL; item = item->prev) {	if (item->entry.type == MenuSubMenu) {	    if (!strcmp (name, (item->entry.submenu.menu)->name))		break;	} else if ((isSeparator (name) && isSeparator (item->name))		   || !strcmp (name, item->name))	    break;    }    return item;}#endif#ifdef MENUBAR/* * unlink ITEM from its MENU and free its memory *//* INTPROTO */void            rxvtlib_menuitem_free (rxvtlib *o, menu_t * menu, menuitem_t * item){/* disconnect */    menuitem_t     *prev, *next;    assert (menu != NULL);    prev = item->prev;    next = item->next;    if (prev != NULL)	prev->next = next;    if (next != NULL)	next->prev = prev;/* new head, tail */    if (menu->tail == item)	menu->tail = prev;    if (menu->head == item)	menu->head = next;    switch (item->entry.type) {    case MenuAction:    case MenuTerminalAction:	FREE (item->entry.action.str);	break;    case MenuSubMenu:	(void)rxvtlib_menu_delete (o, item->entry.submenu.menu);	break;    }    if (item->name != NULL)	FREE (item->name);    if (item->name2 != NULL)	FREE (item->name2);    FREE (item);}#endif#ifdef MENUBAR/* * sort command vs. terminal actions and * remove the first character of STR if it's '\0' *//* INTPROTO */int             action_type (action_t * action, unsigned char *str){    unsigned int    len;#if defined (DEBUG_MENU) || defined (DEBUG_MENUARROWS)    len = strlen (str);    fprintf (stderr, "(len %d) = %s\n", len, str);#else    len = Str_escaped ((char *)str);#endif    if (!len)	return -1;/* sort command vs. terminal actions */    action->type = MenuAction;    if (str[0] == '\0') {	/* the functional equivalent: memmove (str, str+1, len); */	unsigned char  *dst = (str);	unsigned char  *src = (str + 1);	unsigned char  *end = (str + len);	while (src <= end)	    *dst++ = *src++;	len--;			/* decrement length */	if (str[0] != '\0')	    action->type = MenuTerminalAction;    }    action->str = str;    action->len = len;    return 0;}#endif#ifdef MENUBAR/* INTPROTO */int             rxvtlib_action_dispatch (rxvtlib *o, action_t * action){    switch (action->type) {    case MenuTerminalAction:	rxvtlib_cmd_write (o, action->str, action->len);	break;    case MenuAction:	rxvtlib_tt_write (o, action->str, action->len);	break;    default:	return -1;	break;    }    return 0;}#endif#ifdef MENUBAR/* return the arrow index corresponding to NAME *//* INTPROTO */int             rxvtlib_menuarrow_find (rxvtlib *o, char name){    int             i;    for (i = 0; i < NARROWS; i++)	if (name == o->Arrows[i].name)	    return i;    return -1;}#endif#ifdef MENUBAR/* free the memory associated with arrow NAME of the current menubar *//* INTPROTO */void            rxvtlib_menuarrow_free (rxvtlib *o, char name){    int             i;    if (name) {	i = rxvtlib_menuarrow_find (o, name);	if (i >= 0) {	    action_t       *act = &(o->CurrentBar->arrows[i]);	    switch (act->type) {	    case MenuAction:	    case MenuTerminalAction:		FREE (act->str);		act->str = NULL;		act->len = 0;		break;	    }	    act->type = MenuLabel;	}    } else {	for (i = 0; i < NARROWS; i++)	    rxvtlib_menuarrow_free (o, o->Arrows[i].name);    }}#endif#ifdef MENUBAR/* INTPROTO */void            rxvtlib_menuarrow_add (rxvtlib *o, char *string){    int             i;    unsigned        xtra_len;    char           *p;    struct {	char           *str;	int             len;    } beg = {    NULL, 0}    , end = {    NULL, 0}    , *cur, parse[NARROWS];    MEMSET (parse, 0, sizeof (parse));/* fprintf(stderr, "add arrows = `%s'\n", string); */    for (p = string; p != NULL && *p; string = p) {	p = (string + 3);	/* fprintf(stderr, "parsing at %s\n", string); */	switch (string[1]) {	case 'b':	    cur = &beg;	    break;	case 'e':	    cur = &end;	    break;	default:	    i = rxvtlib_menuarrow_find (o, string[1]);	    if (i >= 0)		cur = &(parse[i]);	    else		continue;	/* not found */	    break;	}	string = p;	cur->str = string;	cur->len = 0;	if (cur == &end) {	    p = strchr (string, '\0');	} else {	    char           *next = string;	    while (1) {		p = strchr (next, '<');		if (p != NULL) {		    if (p[1] && p[2] == '>')			break;		    /* parsed */		} else {		    if (beg.str == NULL)	/* no end needed */			p = strchr (next, '\0');		    break;		}		next = (p + 1);	    }	}	if (p == NULL)	    return;	cur->len = (p - string);    }#ifdef DEBUG_MENUARROWS    cur = &beg;    fprintf (stderr, "<b>(len %d) = %.*s\n",	     cur->len, cur->len, (cur->str ? cur->str : ""));    for (i = 0; i < NARROWS; i++) {	cur = &(parse[i]);	fprintf (stderr, "<%c>(len %d) = %.*s\n",		 o->Arrows[i].name,		 cur->len, cur->len, (cur->str ? cur->str : ""));    }    cur = &end;    fprintf (stderr, "<e>(len %d) = %.*s\n",	     cur->len, cur->len, (cur->str ? cur->str : ""));#endif    xtra_len = (beg.len + end.len);    for (i = 0; i < NARROWS; i++) {	if (xtra_len || parse[i].len)	    rxvtlib_menuarrow_free (o, o->Arrows[i].name);    }    for (i = 0; i < NARROWS; i++) {	unsigned char  *str;	unsigned int    len;	if (!parse[i].len)	    continue;	str = MALLOC (parse[i].len + xtra_len + 1);	if (str == NULL)	    continue;	len = 0;	if (beg.len) {	    STRNCPY (str + len, beg.str, beg.len);	    len += beg.len;	}	STRNCPY (str + len, parse[i].str, parse[i].len);	len += parse[i].len;	if (end.len) {	    STRNCPY (str + len, end.str, end.len);	    len += end.len;	}	str[len] = '\0';#ifdef DEBUG_MENUARROWS	fprintf (stderr, "<%c>(len %d) = %s\n", o->Arrows[i].name, len, str);#endif	if (action_type (&(o->CurrentBar->arrows[i]), str) < 0)	    FREE (str);    }}#endif#ifdef MENUBAR/* INTPROTO */menuitem_t     *rxvtlib_menuitem_add (rxvtlib *o, menu_t * menu, const char *name,			      const char *name2, const char *action){    menuitem_t     *item;    unsigned int    len;    assert (name != NULL);    assert (action != NULL);    if (menu == NULL)	return NULL;    if (isSeparator (name)) {	/* add separator, no action */	name = "";	action = "";    } else {	/*	 * add/replace existing menu item	 */	item = menuitem_find (menu, name);	if (item != NULL) {	    if (item->name2 != NULL && name2 != NULL) {		FREE (item->name2);		item->len2 = 0;		item->name2 = NULL;	    }	    switch (item->entry.type) {	    case MenuAction:	    case MenuTerminalAction:		FREE (item->entry.action.str);		item->entry.action.str = NULL;		break;	    }	    goto Item_Found;	}    }/* allocate a new itemect */    if ((item = (menuitem_t *) MALLOC (sizeof (menuitem_t))) == NULL)	return NULL;    item->len2 = 0;    item->name2 = NULL;    len = strlen (name);    item->name = MALLOC (len + 1);    if (item->name != NULL) {	STRCPY (item->name, name);	if (name[0] == '.' && name[1] != '.')	    len = 0;		/* hidden menu name */    } else {	FREE (item);	return NULL;    }    item->len = len;/* add to tail of list */    item->prev = menu->tail;    item->next = NULL;    if (menu->tail != NULL)	(menu->tail)->next = item;    menu->tail = item;/* fix head */    if (menu->head == NULL)	menu->head = item;/* * add action */  Item_Found:    if (name2 != NULL && item->name2 == NULL) {	len = strlen (name2);	if (len == 0 || (item->name2 = MALLOC (len + 1)) == NULL) {	    len = 0;	    item->name2 = NULL;	} else {	    STRCPY (item->name2, name2);	}	item->len2 = len;    }    item->entry.type = MenuLabel;    len = strlen (action);    if (len == 0 && item->name2 != NULL) {	action = item->name2;	len = item->len2;    }    if (len) {	unsigned char  *str = MALLOC (len + 1);	if (str == NULL) {	    rxvtlib_menuitem_free (o, menu, item);	    return NULL;	}	STRCPY (str, action);	if (action_type (&(item->entry.action), str) < 0)	    FREE (str);    }/* new item and a possible increase in width */    if (menu->width < (item->len + item->len2))	menu->width = (item->len + item->len2);    return item;}#endif#ifdef MENUBAR/* * search for the base starting menu for NAME. * return a pointer to the portion of NAME that remains *//* INTPROTO */char           *rxvtlib_menu_find_base (rxvtlib *o, menu_t ** menu, char *path){    menu_t         *m = NULL;    menuitem_t     *item;    assert (menu != NULL);    assert (o->CurrentBar != NULL);    if (path[0] == '\0')	return path;    if (strchr (path, '/') != NULL) {	register char  *p = path;	while ((p = strchr (p, '/')) != NULL) {	    p++;	    if (*p == '/')		path = p;	}	if (path[0] == '/') {	    path++;	    *menu = NULL;	}	while ((p = strchr (path, '/')) != NULL) {	    p[0] = '\0';	    if (path[0] == '\0')		return NULL;	    if (!strcmp (path, DOT)) {		/* nothing to do */	    } else if (!strcmp (path, DOTS)) {		if (*menu != NULL)		    *menu = (*menu)->parent;	    } else {		path = rxvtlib_menu_find_base (o, menu, path);		if (path[0] != '\0') {	/* not found */		    p[0] = '/';	/* fix-up name again */		    return path;		}	    }	    path = (p + 1);	}    }    if (!strcmp (path, DOTS)) {	path += strlen (DOTS);	if (*menu != NULL)	    *menu = (*menu)->parent;	return path;    }/* find this menu */    if (*menu == NULL) {	for (m = o->CurrentBar->tail; m != NULL; m = m->prev) {	    if (!strcmp (path, m->name))		break;	}    } else {	/* find this menu */	for (item = (*menu)->tail; item != NULL; item = item->prev) {	    if (item->entry.type == MenuSubMenu		&& !strcmp (path, (item->entry.submenu.menu)->name)) {		m = (item->entry.submenu.menu);		break;	    }	}    }    if (m != NULL) {	*menu = m;	path += strlen (path);    }    return path;}#endif#ifdef MENUBAR/* * delete this entire menu *//* INTPROTO */menu_t         *rxvtlib_menu_delete (rxvtlib *o, menu_t * menu){    menu_t         *parent = NULL, *prev, *next;    menuitem_t     *item;    assert (o->CurrentBar != NULL);/* delete the entire menu */    if (menu == NULL)	return NULL;    parent = menu->parent;/* unlink MENU */    prev = menu->prev;    next = menu->next;    if (prev != NULL)	prev->next = next;    if (next != NULL)	next->prev = prev;/* fix the index */    if (parent == NULL) {	const int       len = (menu->len + HSPACE);	if (o->CurrentBar->tail == menu)	    o->CurrentBar->tail = prev;	if (o->CurrentBar->head == menu)	    o->CurrentBar->head = next;	for (next = menu->next; next != NULL; next = next->next)	    next->x -= len;    } else {	for (item = parent->tail; item != NULL; item = item->prev) {	    if (item->entry.type == MenuSubMenu		&& item->entry.submenu.menu == menu) {		item->entry.submenu.menu = NULL;		rxvtlib_menuitem_free (o, menu->parent, item);		break;

⌨️ 快捷键说明

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