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

📄 macros.c

📁 Mrxvt是一个小巧
💻 C
📖 第 1 页 / 共 2 页
字号:
	if( r->nmacros == 0 ) return; /* Nothing to be done */	for( i = 0; i < r->nmacros; i++)	{		if(			 r->macros[i].action.type == MacroFnDummy			 || r->macros[i].keysym == None		  )		{			/*			 * Dummy macro needs to be deleted. Make sure this macro comes first			 * in the macro list.			 *			 * 2006-03-06 gi1242: Would be more efficient if we made sure that			 * this macro was last in the list, however that would involve			 * knowing what the max keysym value is. Could be different on			 * different architectures.			 */			r->macros[i].keysym		= 0;			r->macros[i].modFlags	= 0;			free( r->macros[i].action.str );			r->macros[i].action.str	= NULL; /* Probably unnecessary */			nDummyMacros++;		}	} /* for */	/*	 * The macro list now needs to be sorted on keysym. When we look for macros,	 * we assume the macro list is sorted, so we can use a binary search to	 * lookup macros quickly.	 */	qsort( r->macros, r->nmacros, sizeof( macros_t ), macro_cmp);	/* Remove dummy macros from our list */	MEMMOVE( r->macros, r->macros + nDummyMacros,			(r->nmacros - nDummyMacros) * sizeof( macros_t ) );	r->nmacros -= nDummyMacros;	/* Shrink our macros list */	if( r->nmacros < r->maxMacros )	{		r->macros = rxvt_realloc( r->macros, r->nmacros * sizeof( macros_t ));		r->maxMacros = r->nmacros;	}	DBG_MSG( 3, ( stderr, "Read %d macros. (Have space for %d macros)\n",				r->nmacros, r->maxMacros));#if 0	/* {{{ Debug info */	for( i=0; i < r->nmacros; i++)	{		DBG_TMSG( 3, ( stderr,				"%2d. Key 0x%08lx, Mods 0x%02hhx, Type %2hu, Action: %s\n",				i, r->macros[i].keysym, r->macros[i].modFlags,				r->macros[i].action.type, r->macros[i].action.str ) );	}#endif	/* }}} */}/* {{{1 rxvt_set_action( action, astring) * * Check what action is specified by astring, and assign respective values in * action. *  * The string astring might be modified, but can be freed immediately after * calling this function (regardless of wether it succeeds or not). *//* EXTPROTO */Boolrxvt_set_action		(action_t *action, char *astring){	unsigned short type, len;	DBG_MSG( 2, ( stderr, "Setting action '%s'\n", astring));	/*	 * Match head of "astring" to a name in macroNames to figure out the macro	 * type.	 */	for( type = 0; type < NMACRO_FUNCS; type++)	{		if( (len = rxvt_str_match( astring, macroNames[type])) )		{			/* Matched a macroName at the start of astring */			if( astring[len] && !isspace( astring[len] ) )				/* Not delimited by a space */				continue;			/* Skip macroName and delimiting spaces */			astring += len;			while( *astring && isspace( *astring ) ) astring++;			/* Exit for loop early */			break;		}	}	if( type == NMACRO_FUNCS )	{		rxvt_print_error( "Action %s is not of known type", astring);		return False; /* Failure: No matching macro name */	}	/*	 * Setup values in action	 */	action->type		= type;	/*	 * Interpolate escape sequences into action. XXX: Should we only do this for	 * MacroFnStr and MacroFnEsc?.	 */	len	= rxvt_str_escaped( astring );	/* All macros exept MacroFnStr and MacroFnEsc have null terminated string */	if( type != MacroFnStr && type != MacroFnEsc && len > 0 && astring[len-1] )		astring[ len++ ] = 0;	/* Since astring was null terminated,								   astring[len] is certainly part of the memory								   in astring. */	action->len		= len;	/* Set action->str. If any data is previously there, realloc it. */	if( len > 0 )	{		action->str = (unsigned char *) rxvt_realloc( action->str,												len * sizeof(unsigned char));		MEMCPY( action->str, astring, len);	}	else	{		free( action->str );		action->str = NULL;	}	return True;}/* {{{1 rxvt_process_macros( keysym, ev) * * Check to see if a macro key was pressed. If yes, exec the action and return * 1. Else return 0. * * 2006-02-24 gi1242: Take both a keysym, and a XKeyEvent argument because, the * caller might have modified keysym based on XIM. *//* EXTPROTO */intrxvt_process_macros( rxvt_t *r, KeySym keysym, XKeyEvent *ev){	macros_t	ck,				/* Storing the keysym and mods of the current								   key that's pressed. */				*macro;			/* Macro we find in our saved list corresponding								   to the current key press */	int			status;	if( r->nmacros == 0 )		return 0;	/* No macro processed */	/* Copy the modifier mask and keysym into ck */	ck.modFlags = 0;	if (ev->state & ShiftMask)				ck.modFlags |= MACRO_SHIFT;	if (ev->state & ControlMask)			ck.modFlags |= MACRO_CTRL;	if (ev->state & r->h->ModMetaMask)		ck.modFlags |= MACRO_META;	/* Use lowercase version so we can ignore caps lock */	ck.keysym = tolower( keysym );	/* Check if macro ck is in our list of macros. */	macro = bsearch( &ck, r->macros, r->nmacros, sizeof( macros_t ),				macro_cmp);	if (	     /*	      * No macro found.	      */	     macro == NULL	     || (	     	  /*	     	   * Primary only macro in secondary screen.	     	   */	     	  (macro->modFlags & MACRO_PRIMARY)	     	  && AVTS(r)->current_screen != PRIMARY	        )	     || (	     	  /*	     	   * When macros are disabled, only the toggle macros macro should	     	   * work.	     	   */	     	  ( r->Options2 & Opt2_disableMacros )	     	  && macro->action.type != MacroFnToggleMacros	        )	   )		return 0;	/* No macro processed */	do	  {		DBG_MSG( 3, ( stderr, "Processing macro #%d mods %02hhx\n",					macro - r->macros, macro->modFlags ) );		status = rxvt_dispatch_action( r, &(macro->action), (XEvent*) ev );	  }	while(		   status == 1		   && (macro - r->macros) < r->nmacros		   && MACRO_GET_NUMBER( (++macro)->modFlags ) 		 );	return status;}/* {{{1 rxvt_dispatch_action( action, ev) * * Exec the macro / menu action with type "type" and action "action". Returns 1 * on success, -1 on failure. *//* EXTPROTO */intrxvt_dispatch_action( rxvt_t *r, action_t *action, XEvent *ev){	switch( action->type )	{		case MacroFnEsc:			/* Send action to rxvt */			rxvt_cmd_write( r, ATAB(r), action->str, action->len);			break;		case MacroFnStr:			/* Send action to child process */			rxvt_tt_write( r, ATAB(r), action->str, action->len);			break;		case MacroFnNewTab:			if( action->str != NULL )			{				/*				 * If the first word is quoted, use that as the title. Don't be				 * fancy and check for nested quotes. That's probably				 * unnecessary.				 *				 * Everything after the first quoted word is the command. If				 * command starts with "!", then the shell is exec'ed before				 * running command.				 */				const int	MaxMacroTitle = 80;	/* Longest title we will have */				char		titlestring[MaxMacroTitle];				char		*command = (char *) action->str;				char		*title = NULL;				int			profile = 0;				/* See if a profile is specified */				if( *command == '-' )				{					profile = (int) ( *(++command) - '0' );					if( profile < 0 || profile >= MAX_PROFILES )						profile = AVTS(r)->profileNum;					/* Skip spaces */					if( *command  ) command++;					while( isspace( *command ) ) command++;				}				/* See if a title is specified */				if( *command == '"' )				{					int i;					/* Copy everything until first " into title */					for(						  i=0, command++;						  i < MaxMacroTitle - 2 && *command && *command != '"';						  i++, command++					   )						titlestring[i] = *command;					titlestring[i] = '\0'; /* Null terminate title */					title = titlestring;					/* Skip spaces after title */					if( *command ) command++;					while( isspace( *command ) ) command++;				}				/* Add page */				rxvt_append_page( r, profile, title,									*command ? command : NULL );			}			else				rxvt_append_page( r, 0, NULL, NULL);			break;		case MacroFnClose:			if( action->len > 0 && *(action->str) )			{				/* Close tab specified by str */				int tabno = atoi( (char*) action->str) - 1;				if( tabno == -1 ) tabno = ATAB(r);				if (					  tabno >=0 && tabno <=LTAB(r)					  && (						   !(r->Options2 & Opt2_protectSecondary)						   || PVTS(r, tabno)->current_screen == PRIMARY						 )				   )				{					rxvt_kill_page (r, tabno);				}			}			else				rxvt_exit_request( r );			break;		case MacroFnGoto:		{			/* Goto tab in position action->str */			int tabno;						if( action->str != NULL && *(action->str) )			{				tabno = atoi( (char*) action->str );				if( *(action->str)  == '+' || *(action->str) == '-' )				{					/*					 * Relative movement of tabs					 */					tabno += ATAB(r);					/* Wrap around */					tabno = tabno % (LTAB(r) + 1);					if( tabno < 0 ) tabno += LTAB(r) + 1;				}				else if( tabno == 0 )				{					/*					 * Previous active tab					 */					tabno = PTAB(r);				}				else if( --tabno > LTAB(r) )				{					/*					 * Absolute tab number. If we're too far to the right,					 * activate the last tab.					 */					tabno = LTAB(r);				}			}			else tabno = PTAB(r);			rxvt_activate_page( r, tabno);			break;		}		case MacroFnMove:			/* Move active tab to position in action->str */			if( action->len > 0 && *(action->str) )			{				short tabno = atoi( (char*) action->str );				if( *(action->str) == '+' || *(action->str) == '-' )					rxvt_tabbar_move_tab( r, tabno + ATAB(r));				else					rxvt_tabbar_move_tab( r, tabno-1 );			}			break;		case MacroFnScroll:			/* Scroll by an amount specified in action->str */			if( action->len > 1 )			{				int				amount		= abs( atoi( (char*) action->str ));				enum page_dirn	direction	= (*(action->str) == '-' ? UP : DN);				if( tolower( action->str[ action->len - 2] ) == 'p' )					/* scroll pages */					amount *=#ifdef PAGING_CONTEXT_LINES								r->TermWin.nrow - PAGING_CONTEXT_LINES#else								r->TermWin.nrow * 4 / 5#endif					;				rxvt_scr_page( r, ATAB(r), direction, amount);			}			break;#if 0		case MacroFnCopy:#endif		case MacroFnPaste:			if( ev != NULL )				rxvt_selection_request (r, ATAB(r), ev->xkey.time, 0, 0);			break;		case MacroFnToggleSubwin:			rxvt_toggle_subwin( r, action->str);			break;		case MacroFnFont:		{			const int MaxFontLen = 8;	/* Only need space for "#+xx" */			char fontname[MaxFontLen];			if( action->len >= MaxFontLen - 1 ) break;	/* Remember that														   action->len includes														   the trailing null														   char */			fontname[0] = FONT_CMD;						/* Internal prefix */			STRNCPY( fontname + 1, action->str, MaxFontLen - 1);			fontname[MaxFontLen - 1] = '\0';	/* Null terminate */			rxvt_resize_on_font( r, fontname );			break;		}		case MacroFnToggleVeryBold:			rxvt_toggle_verybold(r);			break;		case MacroFnToggleTransp:#ifdef TRANSPARENT			rxvt_toggle_transparency(r);#endif			break;		case MacroFnToggleBcst:			r->Options2 ^= Opt2_broadcast;			break;		case MacroFnToggleHold:			if (r->Options2 & Opt2_holdExit)			{				int	k;				for (k = LTAB(r); k>= 0; k --)					if (PVTS(r, k)->dead && PVTS(r, k)->hold > 1)						rxvt_remove_page (r, k);				r->Options2 &= ~Opt2_holdExit;			}			else				r->Options2 |= Opt2_holdExit;			break;		case MacroFnToggleFullscren:			ewmh_message( r->Xdisplay, XROOT, r->TermWin.parent,				XInternAtom( r->Xdisplay, "_NET_WM_STATE", True),				_NET_WM_STATE_TOGGLE,				XInternAtom( r->Xdisplay, "_NET_WM_STATE_FULLSCREEN", True),				0, 0, 0 );			break;		case MacroFnSetTitle:			if( action->str != NULL )				rxvt_tabbar_set_title( r, ATAB(r),						(unsigned char*) action->str);			else if( r->selection.text != NULL )				rxvt_tabbar_set_title( r, ATAB(r),						(const unsigned char TAINTED*) r->selection.text);			break;		case MacroFnPrintScreen:		{			/*			 * If first argument is "-scrollback", then dump the whole			 * scroll back buffer. The argument if any is the command to use for			 * the printer pipe.			 */			char	*s			= action->str;			int		pretty		= 0,					scrollback	= 0;			if( *s && *s == '-' )			{				while( *(++s) && !isspace( *s ) )				{					if( *s == 's' )						scrollback = 1;					else if( *s == 'p' )						pretty = 1;				}				while( isspace(*s) ) s++;			}			rxvt_scr_printscreen( r, ATAB(r), scrollback, pretty,					*s ? s : NULL );			break;		}		case MacroFnSaveConfig:		{			char	cfile[PATH_MAX] = "";			if( action->str != NULL )				STRNCPY( cfile, action->str, PATH_MAX-1 );			else			{				char*	home = getenv ("HOME");				if (NULL == home) return -1; /* Failure */				snprintf (cfile, PATH_MAX-1, "%s/%s", home,						".mrxvtrc.save");			}			cfile[PATH_MAX-1] = (char) 0;	/* Null terminate */			return rxvt_save_options (r, cfile) ? 1 : -1;			/* Not reached */		}		case MacroFnToggleMacros:			r->Options2 ^= Opt2_disableMacros;			break;		default:			assert( action->type < sizeof( macroNames ) / sizeof( char ** ) );			rxvt_print_error( "Macro type '%s' not implemented yet",					macroNames[action->type]);			return -1;	}	return 1;}/* }}} *//* vim: set fdm=marker: *//*----------------------- end-of-file (C source) -----------------------*/

⌨️ 快捷键说明

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