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

📄 command.c

📁 multi-tabed terminal based on rxvt
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (		!ctrl && !meta /* NO ctrl or meta */		&& (		    XK_A == keysym || XK_a == keysym		    || XK_C == keysym || XK_c == keysym		    || XK_E == keysym || XK_e == keysym		    || XK_I == keysym || XK_i == keysym		    || XK_N == keysym || XK_n == keysym		    || XK_O == keysym || XK_o == keysym		    || XK_U == keysym || XK_u == keysym		    || XK_Y == keysym || XK_y == keysym		   )	   )	{	    register int    idx;	    KeySym  dk = 0;	    /* dead key + space -> dead key itself */	    switch (accent)	    {		case XK_dead_grave:	    /* ` */		    dk = XK_grave;		    break;		case XK_dead_acute:	    /* ' */		    dk = XK_acute;		    break;		case XK_dead_circumflex:    /* ^ */		    dk = XK_asciicircum;		    break;		case XK_dead_diaeresis:	    /* " */		    dk = XK_quotedbl;		    break;		case XK_dead_tilde:	    /* ~ */		    dk = XK_asciitilde;		    break;		default:		    assert(0);	    }	/* switch(accent) */	    for (idx = 0; idx < DEADKEY_CHAR_NUMBER; idx++)	    {		if (keysym == dkc_tab[idx].ks && dk == dkc_tab[idx].dk)		{		    kbuf[0] = (unsigned char) dkc_tab[idx].ach;		    break;		}	    }	    assert (0 != kbuf[0]);  /* impossible */	    len = 1;	    accent = 0;	/* clear accent anyway */	}   /* if */	else if (		    !ctrl && !meta	    /* NO ctrl or meta */		    && (XK_space == keysym || accent == keysym)		)	{	    KeySym  dk = 0;	    /*	     * dead key + space -> dead key itself	     * dead key ^ 2 -> dead key itself	     * change the keysym so as to print out the dead key	     */	    switch (accent)	    {		case XK_dead_grave:	    /* ` */		    keysym = dk = XK_grave;		    break;		case XK_dead_acute:	    /* ' */		    keysym = dk = XK_apostrophe;		    break;		case XK_dead_circumflex:    /* ^ */		    keysym = dk = XK_asciicircum;		    break;		case XK_dead_diaeresis:	    /* " */		    keysym = dk = XK_quotedbl;		    break;		case XK_dead_tilde:	    /* ~ */		    keysym = dk = XK_asciitilde;		    break;		default:		    assert(0);	    }	/* switch(accent) */	    kbuf[0] = (unsigned char) dk;	    len = 1;	    accent = 0;	/* clear accent anyway */	}	else if (		    !ctrl && !meta && 0 == len		    && (XK_Shift_L == keysym || XK_Shift_R == keysym)		)	{	    ;	/* do NOT clear accent when only shft is pressed */	}	else	{	    accent = 0;	/* clear accent anyway */	}    }	/* 0 != accent */#endif	/* USE_DEADKEY */    /*     * V: beginning of valid_keysym (1)     */#ifdef USE_XIM    if (valid_keysym)#endif	/* USE_XIM */    {	rxvt_dbgmsg ((DBG_DEBUG, DBG_COMMAND,  "ctrl-meta-shft-keysym: %d-%d-%d-%x\n", ctrl, meta, shft, (int) keysym));	/*	 * 2006-02-24 gi1242: Allow macros with no modifier pressed so that the	 * macro functionality will also generalize the keysym functionality.	 *	 * Since we use a binary search to look up macros, even if the user has	 * a very large list of macros the price we pay for looking them up will	 * be quite small. Thus using UNSHIFTED_MACROS does not hurt performance	 * much.	 */#ifndef UNSHIFTED_MACROS	if (ctrl || meta || shft)#endif	    if( rxvt_process_macros( r, keysym, ev ) )		return;	rxvt_dbgmsg ((DBG_DEBUG, DBG_COMMAND,  "bypass rxvt_process_macros\n"));	/*	 * 2006-02-24 gi1242: If you want to "hard code" a few macros into	 * mrxvt, do them here. The code for unshifted-scrollkeys etc used to be	 * here, and has now been removed.	 *	 * Rather than hardcode macros in, it is better to use the macro feature	 * and define your macros in the system wide config file.	 */#ifdef GREEK_SUPPORT	if (keysym == r->h->ks_greekmodeswith)	{	    r->h->greek_mode = !r->h->greek_mode;	    if (r->h->greek_mode)	    {		rxvt_xterm_seq(r, ATAB(r), XTerm_title,		    (greek_getmode() == GREEK_ELOT928 ?		    "[Greek: iso]" : "[Greek: ibm]"), CHAR_ST);		greek_reset();	    }	    else		rxvt_xterm_seq(r, ATAB(r), XTerm_title,		    APL_NAME "-" VERSION, CHAR_ST);	    return;	}#endif	/* GREEK_SUPPORT */	/*	 * At this point, all the keystrokes that have special meaning to us	 * have been handled. If we are in the hold mode, this is the keystroke	 * to exit. Otherwise, return here.	 */	if (AVTS(r)->hold > 1)	{	    rxvt_dbgmsg ((DBG_DEBUG, DBG_COMMAND,  "exit after hold\n"));	    if (keysym && len)		rxvt_remove_page (r, ATAB(r));	    return;	}	/*	 * A: begin 0xFFxx keysym	 */	if (keysym >= 0xff00 && keysym <= 0xffff)	{	    int	    newlen = rxvt_0xffxx_keypress (r, keysym,				ctrl, meta, shft, kbuf);	    if (-1 != newlen)		len = newlen;    #if 0 /* was ifdef META8_OPTION. */	    /* 2006-05-23 gi1242 Better to use modifier instead */	    /*	     * Pass meta for all function keys, if 'meta' option set	     */	    if (meta && (r->h->meta_char == 0x80) && len > 0)		kbuf[len - 1] |= 0x80;#endif	/* META8_OPTION */	}	/*	 * A: end of 0xFFxx keysym	 */	else if (ctrl && keysym == XK_minus)	{	    len = 1;	    kbuf[0] = '\037';	/* Ctrl-Minus generates ^_ (31) */	}	else if ( shft && keysym == XK_ISO_Left_Tab )	{	    /* Most keyboards send this keysym pressing Shift+Tab. */	    STRCPY( kbuf, "\033[Z");	    len = 3;	}#if defined(XK_dead_grave) && defined(XK_dead_horn)	/*	** ========================================================	** C: beginning of 0xFE50 - 0xFE62, dead keys	*/	else if (!ctrl && !meta &&  /* NO ctrl or meta */	    keysym >= XK_dead_grave && keysym <= XK_dead_horn)	{# ifdef USE_DEADKEY	    if (		    XK_dead_grave == keysym ||	    /* ` */		    XK_dead_acute == keysym ||	    /* ' */		    XK_dead_circumflex == keysym || /* ^ */		    XK_dead_diaeresis == keysym ||  /* " */		    XK_dead_tilde == keysym	    /* ~ */	       )	    {		len = 0;		accent = keysym;	    }# endif	/* USE_DEADKEY */	}	/*	** C: end of 0xFE50 - 0xFE62, dead keys	** ========================================================	*/#endif /* XK_dead_grave || XK_dead_horn */	else	{	    if ( meta )	    {		/*		 * If meta is pressed, then either set the 8th bit for all chars		 * in kbuf, or prefix it with C0_ESC, depending on the meta8		 * option.		 *		 * NOTE: This is not done for 0xffxx keys. Those should be		 * indicated with a modifier parameter, as Xterm does.		 */#ifdef META8_OPTION		if (r->h->meta_char == 0x80)	/* Set 8th bit */		{		    unsigned char  *ch;			    for (ch = kbuf; ch < kbuf + len; ch++)			*ch |= 0x80;		    meta = 0;		}		else				/* Prefix with C0_ESC */#endif	/* META8_OPTION */		{		    const unsigned char ch = C0_ESC;		    rxvt_dbgmsg ((DBG_DEBUG, DBG_COMMAND,  "Sending meta for keysym %lx\n", keysym));		    rxvt_tt_write(r, ATAB(r), &ch, 1);		}	    } /* if(meta) */#ifdef GREEK_SUPPORT	    if (r->h->greek_mode)		len = greek_xlat( (char*) kbuf, len);#endif	/* GREEK_SUPPORT */	}   /* else */    }    /*     * V: End of valid_keysym (1)     */    if (len <= 0)    {	rxvt_dbgmsg ((DBG_DEBUG, DBG_COMMAND,  "Returning on unmpapped keysym %lx\n", keysym));	return;		/* not mapped */    }    if (ISSET_OPTION(r, Opt_scrollTtyKeypress))    {	if (AVTS(r)->view_start)	{	    AVTS(r)->view_start = 0;	    AVTS(r)->want_refresh = 1;	}    }#ifdef DEBUG    if (debug_key)	    /* Display keyboard buffer contents */    {	unsigned char*	p;	int	        i;	rxvt_dbgmsg ((DBG_DEBUG, DBG_COMMAND, "key 0x%04X [%d]: `", (unsigned int) keysym, len));	for (i = 0, p = kbuf; i < len; i++, p++)	    rxvt_dbgmsg ((DBG_DEBUG, DBG_COMMAND, (*p >= ' ' && *p < '\177' ? "%c" : "\\%03o"), *p));	rxvt_dbgmsg ((DBG_DEBUG, DBG_COMMAND, "'\n"));    }#endif	/* DEBUG */    if (0 == STRCMP ("UTF-8", r->h->locale))    {	rxvt_msg (DBG_INFO, DBG_COMMAND, "UTF-8 string?");    }    rxvt_tt_write(r, ATAB(r), kbuf, (unsigned int)len);}/*}}} *//*{{{ rxvt_cmd_write(), rxvt_cmd_getc() *//* attempt to `write' count to the input buffer *//* EXTPROTO */voidrxvt_cmd_write( rxvt_t* r, int page, const unsigned char *str,	unsigned int count){    unsigned int    n, s;    unsigned char   *cmdbuf_base = PVTS(r, page)->cmdbuf_base,                    *cmdbuf_endp = PVTS(r, page)->cmdbuf_endp,                    *cmdbuf_ptr	= PVTS(r, page)->cmdbuf_escstart ? 			    PVTS(r, page)->cmdbuf_escstart :			    PVTS(r, page)->cmdbuf_ptr;    n = cmdbuf_ptr - cmdbuf_base;    s = cmdbuf_base + (BUFSIZ - 1) - cmdbuf_endp;    /*     * If there is not enough space to write our data, try using the unused     * space in the beginning.     */    if (n > 0 && s < count)    {	MEMMOVE(cmdbuf_base, cmdbuf_ptr,	    (unsigned int)(cmdbuf_endp - cmdbuf_ptr));	cmdbuf_ptr  -= n;	cmdbuf_endp -= n;	s += n;	if( PVTS(r, page)->cmdbuf_escstart )	    PVTS(r, page)->cmdbuf_escstart -= n;	if( PVTS(r, page)->cmdbuf_escfail )	    PVTS(r, page)->cmdbuf_escfail -= n;	PVTS(r, page)->cmdbuf_ptr = cmdbuf_ptr;    }    if (count > s)    {	rxvt_msg (DBG_ERROR, DBG_COMMAND, "data loss: cmd_write too large");	count = s;    }    for (; count--;)	*cmdbuf_endp++ = *str++;    PVTS(r, page)->cmdbuf_endp = cmdbuf_endp;    assert (PVTS(r, page)->cmdbuf_base <= PVTS(r, page)->cmdbuf_endp);}/* * Does a waitpid() on each child, and marks it as dead if it's dead. This * function is safe to call from anywhere. */voidrxvt_mark_dead_childs( rxvt_t *r ){    int	    i, j;    short   ndead_childs = r->ndead_childs;    rxvt_dbgmsg ((DBG_VERBOSE, DBG_COMMAND,  "rxvt_mark_dead_childs(): %d children are dead\n", r->ndead_childs));    /*     * Check processes running in each tab.     */    for (i = LTAB(r); i >= 0 ; i--)    {	int	    status, pid;	errno = 0;  /* Clear errno */	if(	     !PVTS(r, i)->dead	    &&	     (pid = waitpid( PVTS(r, i)->cmd_pid, &status, WNOHANG)) != 0	  )	{	    if( pid == -1 && errno == ECHILD )	    {		/*		 * Command in ith tab is not our child. The only way this can		 * happen is if we lost an SIGCHLD signal (e.g. if we receive a		 * SIGCHLD when it is blocked, say by our own SIGCHLD handler).		 */		rxvt_dbgmsg ((DBG_DEBUG, DBG_COMMAND,  "ECHILD error on waitpid(%d)\n", i ));		/* We have no way of getting the child's exit status now */		PVTS( r, i )->status = 0;	    }	    else	    {		/* Process in tab i is dead. */		r->ndead_childs--;			/* Reduce number of							   unprocessed dead vt's							   by one */		ndead_childs--;				/* This variable is safe							   from being modified							   in a signal */		PVTS( r, i )->status = status;		/* Save exit status */	    }	    /*	     * Regardless of losing SIGCHLD, we mark this tab as dead.	     */	    PVTS( r, i )->dead	    = 1;	/* Mark it as dead */	    PVTS( r, i )->hold	    = 1;	/* Hold it until it is cleaned						   up */	    r->cleanDeadChilds	    = 1;	/* Child has been marked as						   dead, but not cleaned out. */	}    }    /*     * Check processes we launched via rxvt_async_exec(). We don't care about     * status info here, so this is much simpler.     */    for( i=0, j=0; i < r->nAsyncChilds; )    {	if( waitpid( r->asyncChilds[i], NULL, WNOHANG ) != 0 )	{	    r->ndead_childs--;	    ndead_childs--;	    i++;	}		else	    r->asyncChilds[j++] = r->asyncChilds[i++];    }    r->nAsyncChilds -= (i-j);    if( r->ndead_childs < 0 )    {	/*	 * Oops. Some child died, but we never got a dead child signal on it. As	 * long as we got here, we're fine.	 *	 * NOTE: It is OK for ndead_childs < 0. r->ndead_childs is updated for	 * processes that die when we are in this function. ndead_childs is not.	 */	rxvt_dbgmsg ((DBG_DEBUG, DBG_COMMAND,   "Lost child signal." ));	r->ndead_childs = 0;

⌨️ 快捷键说明

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