📄 command.c
字号:
{ KeySym dk; /* * 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; } /* 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 */ { DBG_MSG( 3, (stderr, "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; DBG_MSG(2, (stderr, "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) { DBG_MSG(1, (stderr, "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; DBG_MSG( 5, ( stderr, "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(kbuf, len);#endif /* GREEK_SUPPORT */ } /* else */ } /* * V: End of valid_keysym (1) */ if (len <= 0) { DBG_MSG( 5, ( stderr, "Returning on unmpapped keysym %lx\n", keysym)); return; /* not mapped */ } if (r->Options & Opt_scrollTtyKeypress) { if (AVTS(r)->view_start) { AVTS(r)->view_start = 0; r->h->want_refresh = 1; } }#ifdef DEBUG_CMD if (debug_key) /* Display keyboard buffer contents */ { char *p; int i; fprintf(stderr, "key 0x%04X [%d]: `", (unsigned int) keysym, len); for (i = 0, p = kbuf; i < len; i++, p++) fprintf(stderr, (*p >= ' ' && *p < '\177' ? "%c" : "\\%03o"), *p); fprintf(stderr, "'\n"); }#endif /* DEBUG_CMD */ 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 */unsigned intrxvt_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; unsigned char* cmdbuf_endp = PVTS(r, page)->cmdbuf_endp; unsigned char* cmdbuf_ptr = PVTS(r, page)->cmdbuf_ptr; n = cmdbuf_ptr - cmdbuf_base; s = cmdbuf_base + (BUFSIZ - 1) - cmdbuf_endp; if (n > 0 && s < count) { MEMMOVE(cmdbuf_base, cmdbuf_ptr, (unsigned int)(cmdbuf_endp - cmdbuf_ptr)); cmdbuf_ptr = cmdbuf_base; cmdbuf_endp -= n; s += n; } if (count > s) { rxvt_print_error("data loss: cmd_write too large"); count = s; } for (; count--;) *cmdbuf_endp++ = *str++; PVTS(r, page)->cmdbuf_ptr = cmdbuf_ptr; PVTS(r, page)->cmdbuf_endp = cmdbuf_endp; assert (PVTS(r, page)->cmdbuf_base <= PVTS(r, page)->cmdbuf_endp); return 0;}/* * Be careful the time to call this function. Do NOT call it in rxvt_cmd_getc * because this can redirect command buffer input of one terminal to the other * terminals!!! *//* INTPROTO */voidrxvt_clean_cmd_page (rxvt_t* r){ int hold_msg = 0; /* whether title has been changed */ char* msg; /* hold message */ msg = (char*) r->h->rs[Rs_holdExitText]; if (NULL == msg) msg = " -- Terminal finished, ESC to exit"; DBG_MSG(1, (stderr, "%d children have died, clean cmd fd\n", r->vt_died)); while (r->vt_died > 0) { int dead; /* child that has died */ /* * We start from the last child because we need to move ahead after * removing dead child. This makes it much safer. * * Why do we need to restart dead value from LTAB(r) again? Because a * child may have died when we do something following and changed the * value of r->vt_died! This child may be later than any dead children * we have examined. */ for (dead = LTAB(r); dead >= 0; dead--) /* only dead children that are not held */ if (PVTS(r, dead)->dead && (!(r->Options2 & Opt2_holdExit) || (r->Options2 & Opt2_holdExit && 1 == PVTS(r, dead)->hold))) break; assert (dead <= LTAB(r)); /* in case */ if (1 == PVTS(r, dead)->hold) { DBG_MSG(1, (stderr, "hold child %d after it died\n", dead)); if (!hold_msg) { rxvt_set_term_title (r, (const unsigned char*) msg); rxvt_set_icon_name (r, (const unsigned char*) msg); hold_msg = 1; /* do not change title anymore */ } if (r->h->rs[Rs_holdExitText]) { /* print the holding exit text on screen */ rxvt_scr_add_lines(r, dead, (const unsigned char*) r->h->rs[Rs_holdExitText], 1, STRLEN(r->h->rs[Rs_holdExitText])); rxvt_scr_refresh (r, dead, SMOOTH_REFRESH); } /* increase hold number, so next iteration will skip it */ PVTS(r, dead)->hold ++; } else rxvt_remove_page (r, dead); /* reduce number of dead children by -1 */ r->vt_died --; } /* while loop */}/* INTPROTO */intrxvt_find_cmd_child (rxvt_t* r, int* p_page){ register int k; assert (NULL != p_page); assert (-1 == *p_page); /* in case */ if (r->vt_died > 0) { /* If a child has died, try to find and return it */ for (k = 0; k <= LTAB(r); k ++) { assert (PVTS(r, k)->cmdbuf_base <= PVTS(r, k)->cmdbuf_endp); if ( PVTS(r, k)->dead && !( (r->Options2 & Opt2_holdExit) && (PVTS(r, k)->hold > 1) ) ) { *PVTS(r, k)->cmdbuf_endp = (char) 0; *p_page = k; return 1; } /* output any pending chars of page's v_buffer */ if (PVTS(r, k)->v_bufstr < PVTS(r, k)->v_bufptr) rxvt_tt_write(r, k, NULL, 0); } /* for loop */ } else { /* * Reverse loop direction on each entry. It is used to avoid poor * performance on one side of a particularly busy tab if there are a lot * of activities in it. This problem is noticed by Carsten Menke * (sourceforge bug id 1102791) */ static int direction = 1; /* reverse the loop direction */ direction = !direction; if (0 == direction) { /* * try to find a child with input, from the left to the right */ for (k = 0; k <= LTAB(r); k ++) { assert (PVTS(r, k)->cmdbuf_base <= PVTS(r, k)->cmdbuf_endp); /* already have something in some page's buffer */ if (PVTS(r, k)->cmdbuf_ptr < PVTS(r, k)->cmdbuf_endp) { *p_page = k; return 1; } /* output any pending chars of page's v_buffer */ if (PVTS(r, k)->v_bufstr < PVTS(r, k)->v_bufptr) rxvt_tt_write(r, k, NULL, 0); } /* for loop */ } else { /* * Try to find a child with input, from the right to the left */ for (k = LTAB(r); k >= 0; k --) { assert (PVTS(r, k)->cmdbuf_base <= PVTS(r, k)->cmdbuf_endp); /* already have something in some page's buffer */ if (PVTS(r, k)->cmdbuf_ptr < PVTS(r, k)->cmdbuf_endp) { *p_page = k; return 1; } /* output any pending chars of page's v_buffer */ if (PVTS(r, k)->v_bufstr < PVTS(r, k)->v_bufptr) rxvt_tt_write(r, k, NULL, 0); } /* for loop */ } } return 0; /* not found */}/* INTPROTO */voidrxvt_check_cmdbuf (rxvt_t* r, int page){ if (PVTS(r, page)->cmdbuf_ptr == PVTS(r, page)->cmdbuf_endp) { /* * If there is no data in the buffer, reset it to the beginning of the * buffer. */ assert (PVTS(r, page)->cmdbuf_base <= PVTS(r, page)->cmdbuf_endp); PVTS(r, page)->cmdbuf_ptr = PVTS(r, page)->cmdbuf_endp = PVTS(r, page)->cmdbuf_base; assert (PVTS(r, page)->cmdbuf_base <= PVTS(r, page)->cmdbuf_endp); } else if ( (BUFSIZ - 1) == (PVTS(r, page)->cmdbuf_endp - PVTS(r, page)->cmdbuf_base) && (PVTS(r, page)->cmdbuf_ptr > PVTS(r, page)->cmdbuf_base) ) { /* * If there is space at beginning of the buffer, but not space at the * end of the buffer, move the content of buffer forward to free space */ unsigned int n = PVTS(r, page)->cmdbuf_ptr - PVTS(r, page)->cmdbuf_base; unsigned int len =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -