📄 command.c
字号:
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 + -