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

📄 command.c

📁 Mrxvt是一个小巧
💻 C
📖 第 1 页 / 共 5 页
字号:
			PVTS(r, page)->cmdbuf_endp - PVTS(r, page)->cmdbuf_ptr;		assert (n == BUFSIZ - 1);		assert (PVTS(r, page)->cmdbuf_ptr <				PVTS(r, page)->cmdbuf_endp);		MEMMOVE(PVTS(r, page)->cmdbuf_base, PVTS(r, page)->cmdbuf_ptr,			len);		PVTS(r, page)->cmdbuf_ptr = PVTS(r, page)->cmdbuf_base;		PVTS(r, page)->cmdbuf_endp -= n;		assert (PVTS(r, page)->cmdbuf_base <=			PVTS(r, page)->cmdbuf_endp);	}}/* * rxvt_cmd_getc() - Return next input character. * * Return the next input character after first passing any keyboard input to the * command. *//* INTPROTO */unsigned charrxvt_cmd_getc(rxvt_t *r, int* p_page){	int				page = *p_page;#define TIMEOUT_USEC	5000	fd_set			readfds;	int				quick_timeout, select_res;#ifdef POINTER_BLANK	int				want_motion_time = 0;#endif#ifdef CURSOR_BLINK	int				want_keypress_time = 0;#endif	struct timeval	value;#if defined(POINTER_BLANK) || defined(CURSOR_BLINK) || defined(TRANSPARENT)	struct timeval	tp;#endif	struct rxvt_hidden *h = r->h;	register int	i;	while (1)	{		/* loop until we can return something */		if (-1 != page)		{			assert (PVTS(r, page)->cmdbuf_base <=				PVTS(r, page)->cmdbuf_endp);			/* already have something in the buffer */			if (PVTS(r, page)->cmdbuf_ptr < PVTS(r, page)->cmdbuf_endp)				return *(PVTS(r, page)->cmdbuf_ptr)++;			/* output any pending chars of page's v_buffer */			if (PVTS(r, page)->v_bufstr < PVTS(r, page)->v_bufptr)				rxvt_tt_write(r, page, NULL, 0);		}		else		{			assert (AVTS(r)->cmdbuf_base <= AVTS(r)->cmdbuf_endp);			/* if -1 == page, we only process the active tab here */			if (AVTS(r)->cmdbuf_ptr < AVTS(r)->cmdbuf_endp)			{				*p_page = ATAB(r);				return *(AVTS(r)->cmdbuf_ptr)++;			}			/* output any pending chars of page's v_buffer */			if (AVTS(r)->v_bufstr < AVTS(r)->v_bufptr)				rxvt_tt_write(r, ATAB(r), NULL, 0);			/*			 * if there is no data in active tab, we go to process the X events			 * before trying to find a tab that has some input/output. this			 * should improve the response performance of the active tab.			 */		}#if defined(POINTER_BLANK) || defined(CURSOR_BLINK) || defined(TRANSPARENT)		/* presume == 0 implies time not yet retrieved */		tp.tv_sec = tp.tv_usec = 0;#endif	/* POINTER_BLANK || CURSOR_BLINK || TRANSPARENT*/#ifdef CURSOR_BLINK		want_keypress_time = 0;#endif	/* CURSOR_BLINK */#ifdef POINTER_BLANK		if (r->Options & Opt_pointerBlank)			want_motion_time = 0;#endif	/* POINTER_BLANK */		/* process all pending X events */		while (XPending(r->Xdisplay))		{			XEvent		  xev;			XNextEvent(r->Xdisplay, &xev);#ifdef CURSOR_BLINK			if ( (r->Options & Opt_cursorBlink) && xev.type == KeyPress )			{				if (h->hidden_cursor)				{					DBG_MSG(1, (stderr,"** hide cursor on keypress\n"));					h->hidden_cursor = 0;					h->want_refresh = 1;				}				want_keypress_time = 1;			}#endif	/* CURSOR_BLINK */#ifdef POINTER_BLANK			if ( (r->Options & Opt_pointerBlank) && (h->pointerBlankDelay > 0) )			{				if (						xev.type == MotionNotify || xev.type == ButtonPress						|| xev.type == ButtonRelease				   )				{					/* only work for current active tab */					if (AVTS(r)->hidden_pointer)						rxvt_pointer_unblank(r, ATAB(r));					want_motion_time = 1;				}				/* only work for current active tab */				if (xev.type == KeyPress &&					!AVTS(r)->hidden_pointer)					rxvt_pointer_blank(r, ATAB(r));			}#endif	/* POINTER_BLANK */#ifdef USE_XIM			if (r->h->Input_Context != NULL)			{				if (!XFilterEvent(&xev, xev.xany.window))					rxvt_process_x_event(r, &xev);				h->event_type = xev.type;			}			else#endif	/* USE_XIM */			rxvt_process_x_event(r, &xev);			/* In case button actions pushed chars to cmdbuf. */			if (-1 != page)			{				assert (PVTS(r, page)->cmdbuf_base <=					PVTS(r, page)->cmdbuf_endp);				if (PVTS(r, page)->cmdbuf_ptr <					PVTS(r, page)->cmdbuf_endp)					return *(PVTS(r, page)->cmdbuf_ptr)++;			}			else			{				assert (AVTS(r)->cmdbuf_base <= AVTS(r)->cmdbuf_endp);				/*				 * -1 == page, only try the active tab here. we will handle				 *  inactive tabs after processed all X events				 */				if (AVTS(r)->cmdbuf_ptr < AVTS(r)->cmdbuf_endp)				{					*p_page = ATAB(r);					return *(AVTS(r)->cmdbuf_ptr)++;				}				/*				 * Notice that there might be something BAD here: the active tab				 * is changed by user interaction and data are pushed into				 * previous active tab (now inactive). Need to study on this in				 * the future.				 */			}		}	/* while ((XPending(r->Xdisplay)) */		if (-1 == page)		{			/*			 * in case -1 == page, and there's no X events to process. we will			 * not go to the select call if there's already input/output in some			 * tabs. to reach here, we have tried active tab but with no luck.			 */			if (rxvt_find_cmd_child (r, p_page))				return *(PVTS(r, *p_page)->cmdbuf_ptr)++;		}#ifdef CURSOR_BLINK		if (want_keypress_time)		{			/* reset last cursor change time on keypress event */			(void) gettimeofday (&tp, NULL);			DBG_MSG(3, (stderr,"** init cursor time on keypress\n"));			h->lastcursorchange.tv_sec = tp.tv_sec;			h->lastcursorchange.tv_usec = tp.tv_usec;		}#endif	/* CURSOR_BLINK */#ifdef POINTER_BLANK		if ((r->Options & Opt_pointerBlank) && want_motion_time)		{			(void) gettimeofday (&tp, NULL);			h->lastmotion.tv_sec = tp.tv_sec;			h->lastmotion.tv_usec = tp.tv_usec;		}#endif	/* POINTER_BLANK */		/*		 * The command input buffer is empty and we have no pending X events		 */		quick_timeout = 0;#if defined(MOUSE_WHEEL) && defined(MOUSE_SLIP_WHEELING)		if (h->mouse_slip_wheel_speed)		{			quick_timeout = 1;			/* Only work for current active tab */			if (					!h->mouse_slip_wheel_delay--					&& rxvt_scr_page( r, ATAB(r),							h->mouse_slip_wheel_speed >0 ? UP : DN,							abs(h->mouse_slip_wheel_speed) )			   )			{				h->mouse_slip_wheel_delay = SCROLLBAR_CONTINUOUS_DELAY;				h->refresh_type |= SMOOTH_REFRESH;				h->want_refresh = 1;			}		}#endif /* MOUSE_WHEEL && MOUSE_SLIP_WHEELING */#ifdef SELECTION_SCROLLING		if (h->pending_scroll_selection)		{			quick_timeout = 1;			/* Only work for current active tab */			if (					!h->scroll_selection_delay--					&& rxvt_scr_page(r, ATAB(r), h->scroll_selection_dir,							h->scroll_selection_lines)			   )			{				rxvt_selection_extend(r, ATAB(r), h->selection_save_x,					h->selection_save_y, h->selection_save_state);				h->scroll_selection_delay = SCROLLBAR_CONTINUOUS_DELAY;				h->refresh_type |= SMOOTH_REFRESH;				h->want_refresh = 1;			}		}#endif	/* SELECTION_SCROLLING */#ifdef HAVE_SCROLLBARS# ifndef NO_SCROLLBAR_BUTTON_CONTINUAL_SCROLLING		if (scrollbar_isUp() || scrollbar_isDn())		{			quick_timeout = 1;			/* Only work for current active tab */			if (					!h->scroll_arrow_delay--					&& rxvt_scr_page(r, ATAB(r), scrollbar_isUp()?UP:DN, 1)			   )			{				h->scroll_arrow_delay = SCROLLBAR_CONTINUOUS_DELAY;				h->refresh_type |= SMOOTH_REFRESH;				h->want_refresh = 1;			}		}# endif	/* NO_SCROLLBAR_BUTTON_CONTINUAL_SCROLLING */#endif		/* Prepare to read in from children's file descriptors */		FD_ZERO(&readfds);		for (i = 0; i <= LTAB(r); i ++)		{			/* remember to skip held childrens */			if ((r->Options2 & Opt2_holdExit) && (PVTS(r, i)->hold > 1))			{				DBG_MSG(2,(stderr," not listen on vt[%d].cmd_fd\n",i));				continue;			}			FD_SET(PVTS(r, i)->cmd_fd, &readfds);			DBG_MSG(2, (stderr, " listen on vt[%d].cmd_fd = %d\n", i,				PVTS(r, i)->cmd_fd));		}		FD_SET(r->Xfd, &readfds);#ifdef HAVE_X11_SM_SMLIB_H		if (-1 != r->TermWin.ice_fd)			FD_SET(r->TermWin.ice_fd, &readfds);#endif		value.tv_usec = TIMEOUT_USEC;		value.tv_sec = 0;		if (!r->TermWin.mapped)			quick_timeout = 0;		else		{			quick_timeout |= (h->want_refresh || h->want_clip_refresh);#ifdef TRANSPARENT			quick_timeout |= h->want_full_refresh;#endif	/* TRANSPARENT */		}#if defined(POINTER_BLANK) || defined(CURSOR_BLINK) || defined(TRANSPARENT)		{			int			set_quick_timeout = 0;			long		csdiff, psdiff, bsdiff;			csdiff = psdiff = bsdiff = 60000000L;	/* or, say, LONG_MAX */# ifdef TRANSPARENT			/* Check if we should refresh our background */			if( h->lastCNotify.tv_sec )			{				gettimeofday( &tp, NULL);				bsdiff = (tp.tv_sec - h->lastCNotify.tv_sec) * 1000000L					+ tp.tv_usec - h->lastCNotify.tv_usec;				if( bsdiff > h->bgRefreshInterval)				{					bsdiff = 0;					h->lastCNotify.tv_sec = 0;					/* Only refresh bg image if we've moved. */					if( (	!r->h->bgGrabbed							|| r->h->prevPos.x		!= r->szHint.x							|| r->h->prevPos.y		!= r->szHint.y							|| r->h->prevPos.width	!= r->szHint.width							|| r->h->prevPos.height	!= r->szHint.height)						&&							rxvt_check_our_parents( r ))					{						h->want_full_refresh = 1;					}				}				else bsdiff = h->bgRefreshInterval - bsdiff;				DBG_MSG( 3, (stderr,							"Waiting %ld.%06ld seconds longer for bg refresh\n",							bsdiff / 1000000L, bsdiff % 1000000L));				set_quick_timeout = 1;			}# endif /* TRANSPARENT */# if defined(CURSOR_BLINK)			/*			 * Cursor only blinks when terminal window is focused.			 */			if ((r->Options & Opt_cursorBlink) && r->TermWin.focus)			{				DBG_MSG(3, (stderr,"** get cursor time on select\n"));				(void)gettimeofday(&tp, NULL);				csdiff = (tp.tv_sec - h->lastcursorchange.tv_sec) * 1000000L					 + tp.tv_usec - h->lastcursorchange.tv_usec;				if (csdiff > h->blinkInterval)				{					/* XXX: settable blink times */					h->lastcursorchange.tv_sec = tp.tv_sec;					h->lastcursorchange.tv_usec = tp.tv_usec;					h->hidden_cursor = !h->hidden_cursor;					DBG_MSG(3, (stderr, "%s\n", h->hidden_cursor ?						"** hide cursor" : "** show cursor"));					h->want_refresh = 1;					csdiff = 0;				}				else					csdiff = h->blinkInterval - csdiff;				set_quick_timeout = 1;			}# endif	/* CURSOR_BLINK */# if defined(POINTER_BLANK)			/*			 * If we haven't moved the pointer for a while			 */			if (					(r->Options & Opt_pointerBlank)					&& (h->pointerBlankDelay > 0)					&& (AVTS(r)->hidden_pointer == 0)			   )			{				long			pdelay;				DBG_MSG(3, (stderr,"** get pointer time on select\n"));				(void) gettimeofday(&tp, NULL);				psdiff = (tp.tv_sec - h->lastmotion.tv_sec) * 1000000L					 + tp.tv_usec - h->lastmotion.tv_usec;				pdelay = h->pointerBlankDelay * 1000000L;				/* only work for current active tab */				if (psdiff >= pdelay)					rxvt_pointer_blank(r, ATAB(r));				else				{					set_quick_timeout = 1;					psdiff = pdelay - psdiff;				}			}# endif	/* POINTER_BLANK */			if (!quick_timeout && set_quick_timeout)			{				MIN_IT(csdiff, bsdiff);				MIN_IT(csdiff, psdiff);				value.tv_sec =  csdiff / 1000000L;				value.tv_usec = csdiff % 1000000L;				quick_timeout = 1;			}		}#endif	/* POINTER_BLANK || CURSOR_BLINK || TRANSPARENT */		/* Now begin to read in from children's file descriptors */		DBG_MSG( 4, (stderr, "Waiting for %lumu for child\n",					quick_timeout ? value.tv_sec * 1000000LU + value.tv_usec :						ULONG_MAX));		if (				(select_res = select(r->num_fds, &readfds, NULL, NULL,										(quick_timeout ? &value : NULL))) == 0		   )		{			/*			 * select statement timed out - we're not hard and fast scrolling			 */			h->refresh_limit = 1;		}#ifdef CURSOR_BLINK		/*		 * 2006-02-16 gi1242: Unnecessary. We should only refresh when the		 * cursor changes state. (I.e on one of the timeouts). Refreshing always		 * wastes CPU.		 */#if 0		if (r->Options & Opt_cursorBlink)		 	h->want_refresh = 1;#endif#endif	/* CURSOR_BLINK */		/*		 * Handle the children that have generate input. Notice in this loop we		 * only process input, but do NOT determine the child we want to return.		 */		for (i = 0; i <= LTAB(r); i++)		{			int				n = 0;			unsigned int	count, bufsiz;			/* check next file descriptor if this one has nothing to read in. */			if (!FD_ISSET(PVTS(r, i)->cmd_fd, &readfds))				continue;			DBG_MSG(1, (stderr, "reading from shell %d\n", i));			/* check our command buffer before reading data */			rxvt_check_cmdbuf (r, i);			assert (PVTS(r, i)->cmdbuf_base <= PVTS(r, i)->cmdbuf_endp);			/* The buffer size is the buffer length - used length */			count = bufsiz = (BUFSIZ - 1) -				(PVTS(r, i)->cmdbuf_endp - PVTS(r, i)->cmdbuf_base);			while (count)			{				DBG_MSG(1, (stderr, "read maximal %u bytes\n", count));				errno = 0;	/* clear errno */				n = read (PVTS(r, i)->cmd_fd, PVTS(r, i)->cmdbuf_endp,						count);				DBG_MSG(1, (stderr, "read %d bytes\n", n));				if (n > 0)				{					/* Update count and buffer pointer */					count -= n;					PVTS(r, i)->cmdbuf_endp += n;					/*					 * check the file descriptor to see if there are further					 * input, this is to avoid blocking on read(), which seems					 * to be an issue when running mc in bash. this will waste					 * several CPU cycles, but it's safer than blocking.					 */					FD_ZERO(&readfds);					FD_SET(PVTS(r, i)->cmd_fd, &readfds);					value.tv_sec = 0;					value.tv_usec = 5;	/* time out, 5us */					select_res = select(r->num_fds, &readfds, NULL,						NULL, &value);					if (0 == select_res)					{						/* time-out, no further data to read */						DBG_MSG(1, (stderr, "no further data\n"));						break;					}					if (-1 == select_res)					{						/* error, stop reading */						DBG_MSG(1, (stderr, "select error\n"));

⌨️ 快捷键说明

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