📄 command.c
字号:
/*--------------------------------*-C-*---------------------------------* * File: command.c *----------------------------------------------------------------------* * * All portions of code are copyright by their respective author/s. * Copyright (c) 1992 John Bovey <jdb@ukc.ac.uk> * Copyright (c) 1994 Robert Nation <nation@rocket.sanders.lockheed.com> * Copyright (c) 1995 Garrett D'Amore <garrett@netcom.com> * Copyright (c) 1995 Steven Hirsch <hirsch@emba.uvm.edu> * Copyright (c) 1995 Jakub Jelinek <jj@gnu.ai.mit.edu> * Copyright (c) 1997 MJ Olesen <olesen@me.queensu.ca> * Copyright (c) 1997 Raul Garcia Garcia <rgg@tid.es> * Copyright (c) 1997,1998 Oezguer Kesim <kesim@math.fu-berlin.de> * Copyright (c) 1998-2001 Geoff Wing <gcw@pobox.com> * Copyright (c) 1998 Alfredo K. Kojima <kojima@windowmaker.org> * Copyright (c) 2001 Marius Gedminas <marius.gedminas@uosis.mif.vu.lt> * Copyright (c) 2003 Rob McMullen <robm@flipturn.org> * Copyright (c) 2004 Terry Griffin <griffint@pobox.com> * Copyright (c) 2005 Johann 'Mykraverk' Oskarsson * <johann@myrkraverk.com> * Copyright (c) 2004-2006 Jingmin Zhou <jimmyzhou@users.sourceforge.net> * Copyright (c) 2005-2006 Gautam Iyer <gi1242@users.sourceforge.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *----------------------------------------------------------------------*/#include "../config.h"#include "rxvt.h"#ifdef USE_DEADKEY/*** Deadkey sequences table.*/typedef struct _DeadKeyChar { KeySym ks; /* keysym */ KeySym dk; /* accent */ KeySym ach; /* accent keysym */} DeadKeyChar;static DeadKeyChar dkc_tab[] = { {XK_A, XK_grave, XK_Agrave}, {XK_A, XK_acute, XK_Aacute}, {XK_A, XK_apostrophe, XK_Aacute}, {XK_A, XK_asciicircum, XK_Acircumflex}, {XK_A, XK_asciitilde, XK_Atilde}, {XK_A, XK_quotedbl, XK_Adiaeresis}, {XK_a, XK_grave, XK_agrave}, {XK_a, XK_acute, XK_aacute}, {XK_a, XK_apostrophe, XK_aacute}, {XK_a, XK_asciicircum, XK_acircumflex}, {XK_a, XK_asciitilde, XK_atilde}, {XK_a, XK_quotedbl, XK_adiaeresis}, {XK_C, XK_grave, XK_Ccedilla}, {XK_C, XK_acute, XK_Ccedilla}, {XK_c, XK_grave, XK_ccedilla}, {XK_c, XK_acute, XK_ccedilla}, {XK_E, XK_grave, XK_Egrave}, {XK_E, XK_acute, XK_Eacute}, {XK_E, XK_apostrophe, XK_Eacute}, {XK_E, XK_asciicircum, XK_Ecircumflex}, {XK_E, XK_quotedbl, XK_Ediaeresis}, {XK_e, XK_grave, XK_egrave}, {XK_e, XK_acute, XK_eacute}, {XK_e, XK_apostrophe, XK_eacute}, {XK_e, XK_asciicircum, XK_ecircumflex}, {XK_e, XK_quotedbl, XK_ediaeresis}, {XK_I, XK_grave, XK_Igrave}, {XK_I, XK_acute, XK_Iacute}, {XK_I, XK_apostrophe, XK_Iacute}, {XK_I, XK_asciicircum, XK_Icircumflex}, {XK_I, XK_quotedbl, XK_Idiaeresis}, {XK_i, XK_grave, XK_igrave}, {XK_i, XK_acute, XK_iacute}, {XK_i, XK_apostrophe, XK_iacute}, {XK_i, XK_asciicircum, XK_icircumflex}, {XK_i, XK_quotedbl, XK_idiaeresis}, {XK_N, XK_asciitilde, XK_Ntilde}, {XK_n, XK_asciitilde, XK_ntilde}, {XK_O, XK_grave, XK_Ograve}, {XK_O, XK_acute, XK_Oacute}, {XK_O, XK_apostrophe, XK_Oacute}, {XK_O, XK_asciicircum, XK_Ocircumflex}, {XK_O, XK_asciitilde, XK_Otilde}, {XK_O, XK_quotedbl, XK_Odiaeresis}, {XK_o, XK_grave, XK_ograve}, {XK_o, XK_acute, XK_oacute}, {XK_o, XK_apostrophe, XK_oacute}, {XK_o, XK_asciicircum, XK_ocircumflex}, {XK_o, XK_asciitilde, XK_otilde}, {XK_o, XK_quotedbl, XK_odiaeresis}, {XK_U, XK_grave, XK_Ugrave}, {XK_U, XK_acute, XK_Uacute}, {XK_U, XK_apostrophe, XK_Uacute}, {XK_U, XK_asciicircum, XK_Ucircumflex}, {XK_U, XK_quotedbl, XK_Udiaeresis}, {XK_u, XK_grave, XK_ugrave}, {XK_u, XK_acute, XK_uacute}, {XK_u, XK_apostrophe, XK_uacute}, {XK_u, XK_asciicircum, XK_ucircumflex}, {XK_u, XK_quotedbl, XK_udiaeresis}, {XK_Y, XK_acute, XK_Yacute}, {XK_Y, XK_apostrophe, XK_Yacute}, {XK_y, XK_acute, XK_yacute}, {XK_y, XK_apostrophe, XK_yacute}, {XK_y, XK_quotedbl, XK_ydiaeresis}, {0, 0, 0},};# define DEADKEY_CHAR_NUMBER (int)((sizeof(dkc_tab) / sizeof(DeadKeyChar)))#endif /* USE_DEADKEY *//*--------------------------------------------------------------------* * BEGIN `INTERNAL' ROUTINE PROTOTYPES * *--------------------------------------------------------------------*/void rxvt_process_keypress (rxvt_t*, XKeyEvent*);void rxvt_clean_cmd_page (rxvt_t*);int static inline rxvt_cmdbuf_has_input ( rxvt_t *r, int page );int rxvt_find_cmd_child (rxvt_t*);void rxvt_check_cmdbuf (rxvt_t*, int);int rxvt_read_child_cmdfd (rxvt_t*, int, unsigned int);void rxvt_process_children_cmdfd (rxvt_t*, fd_set*);int rxvt_check_quick_timeout (rxvt_t*);int rxvt_adjust_quick_timeout (rxvt_t*, int, struct timeval*);void rxvt_refresh_vtscr_if_needed (rxvt_t*);unsigned char rxvt_cmd_getc (rxvt_t*, int* page);#ifdef POINTER_BLANKvoid rxvt_pointer_blank (rxvt_t*, int);#endifvoid rxvt_mouse_report (rxvt_t*, const XButtonEvent*);void rxvt_set_bg_focused (rxvt_t*, int, Bool);#if defined(MOUSE_WHEEL) && defined(MOUSE_SLIP_WHEELING)void rxvt_process_keyrelease (rxvt_t*, XKeyEvent*);#endifvoid rxvt_scrollbar_dispatcher (rxvt_t*, int, XButtonEvent*);void rxvt_process_buttonpress (rxvt_t*, int, XButtonEvent*);#ifdef MOUSE_WHEELvoid rxvt_process_wheel_button (rxvt_t*, int, XButtonEvent*);#endifvoid rxvt_process_buttonrelease (rxvt_t*, int, XButtonEvent*);void rxvt_process_clientmessage (rxvt_t*, XClientMessageEvent*);void rxvt_process_visibilitynotify (rxvt_t*, XVisibilityEvent*);#ifdef MONITOR_ENTER_LEAVEvoid rxvt_process_enter (rxvt_t*, XCrossingEvent*);void rxvt_process_leave (rxvt_t*, XCrossingEvent*);#endifvoid rxvt_change_colors_on_focus (rxvt_t*);void rxvt_process_focusin (rxvt_t*, XFocusChangeEvent*);void rxvt_process_focusout (rxvt_t*, XFocusChangeEvent*);int rxvt_calc_colrow (rxvt_t* r, unsigned int width, unsigned int height);void rxvt_resize_sub_windows (rxvt_t* r);void rxvt_resize_on_configure (rxvt_t* r, unsigned int width, unsigned int height);#ifndef NO_FRILLSBool getWMStruts (Display *dpy, Window w, CARD32 *left, CARD32 *right, CARD32 *top, CARD32 *bottom);#endifvoid rxvt_process_configurenotify (rxvt_t*, XConfigureEvent*);void rxvt_process_selectionnotify (rxvt_t*, XSelectionEvent*);void rxvt_process_propertynotify (rxvt_t*, XEvent*);void rxvt_process_expose (rxvt_t*, XEvent*);void rxvt_process_motionnotify (rxvt_t*, XEvent*);void rxvt_process_x_event (rxvt_t*, XEvent*);#ifdef PRINTPIPEvoid rxvt_process_print_pipe (rxvt_t*, int);#endifvoid rxvt_process_nonprinting (rxvt_t*, int, unsigned char);void rxvt_process_escape_vt52 (rxvt_t*, int, unsigned char);void rxvt_process_escape_seq (rxvt_t*, int);void rxvt_process_csi_seq (rxvt_t*, int);#ifndef NO_FRILLSvoid rxvt_process_window_ops (rxvt_t*, int, const int*, unsigned int);#endifunsigned char* rxvt_get_to_st (rxvt_t*, int, unsigned char*);void rxvt_process_dcs_seq (rxvt_t*, int);void rxvt_process_osc_seq (rxvt_t*, int);void rxvt_xwsh_seq (rxvt_t*, int, const char*);void rxvt_process_xwsh_seq (rxvt_t*, int);int rxvt_privcases (rxvt_t*, int, int, uint32_t);void rxvt_process_terminal_mode (rxvt_t*, int, int, int, unsigned int, const int*);void rxvt_process_sgr_mode (rxvt_t*, int, unsigned int, const int*);void rxvt_process_graphics (rxvt_t*, int);void rxvt_process_getc (rxvt_t*, int, unsigned char);/*--------------------------------------------------------------------* * END `INTERNAL' ROUTINE PROTOTYPES * *--------------------------------------------------------------------*//* {{{ Process keysyms between 0xff00 and 0xffff *//* * SET_TILDE_KEY_SEQ( kbuf, str): Copies a escape sequences (ending with ~) into * kbuf. * * Rxvt style modifiers: The trailing tilde is replaced with $, ^, or @ * depending on the modifier pressed: * * No modifier ~ * Shift $ * Ctrl ^ * Ctrl+Shift @ * * The meta modifier is ignored. * * Xterm style modifiers (if XTERM_KEYS is defined): Adds a parameter ";%d" * before the trailing "~" if a modifier is pressed: * * None Nothing is added. * Shift 2 = 1(None)+1(Shift) * Alt 3 = 1(None)+2(Alt) * Alt+Shift 4 = 1(None)+1(Shift)+2(Alt) * Ctrl 5 = 1(None)+4(Ctrl) * Ctrl+Shift 6 = 1(None)+1(Shift)+4(Ctrl) * Ctrl+Alt 7 = 1(None)+2(Alt)+4(Ctrl) * Ctrl+Alt+Shift 8 = 1(None)+1(Shift)+2(Alt)+4(Ctrl) * * This is better because DEC sequences that don't end in a tilde can also * contain a modifier parameter / number. NOTE: Xterm also has a bunch of * sequences when Meta is pressed, which we don't implement. * */#ifdef XTERM_KEYS# define SET_TILDE_KEY_SEQ( kbuf, str ) \ set_xterm_key_seq( (kbuf), str, str ";%d%c", '~', ctrl, meta, shft )#else# define SET_TILDE_KEY_SEQ( kbuf, str ) \ sprintf( kbuf, str "%c", shft ? (ctrl ? '@' : '$') : (ctrl ? '^' : '~') )#endif/* * Copies sequence into kbuf. * * If no modifiers (ctrl, meta, shft) are pressed, then the character suffix is * appended to umod_prefix, and copied into kbuf. * * Otherwise, mod_format is sprintf'ed into kbuf. The third arg to sprintf is * the modifier number (computed from which modifier is pressed in the same way * as xterm does). The fourth argument is the character suffix. *//* NOPROTO */voidset_xterm_key_seq( unsigned char *kbuf, const char *umod_prefix, const char *mod_prefix_format, char suffix, int ctrl, int meta, int shft){ if( ctrl || meta || shft ) sprintf( (char*) kbuf, mod_prefix_format, 1 + (shft ? 1 : 0) + (meta ? 2 : 0) + (ctrl ? 4 : 0), suffix ); else sprintf( (char*) kbuf, "%s%c", umod_prefix, suffix );}/* INTPRO */intrxvt_0xffxx_keypress (rxvt_t* r, KeySym keysym, int ctrl, int meta, int shft, unsigned char* kbuf){ /* * 2006-04-08 gi1242: The KeyPad is treated as follows: * * 1. If NumLock is on: Unmodified keys send the regular char. Modified * keys send the DEC sequence in private mode, and the regular char * in normal model. * * 2. If NumLock is off: Keys always send the DEC private mode * sequence. */ /* * B: beginning of a {} body */ unsigned int newlen = 1; rxvt_dbgmsg ((DBG_DEBUG, DBG_COMMAND, "0xffxx_keypress: (C%d, M%d, S%d) %lx ...", ctrl, meta, shft, keysym)); switch (keysym) {#ifndef NO_BACKSPACE_KEY case XK_BackSpace: { unsigned char *bsKbuf = kbuf; if ( meta# ifdef META8_OPTION && (r->h->meta_char == C0_ESC)# endif ) { /* 7bit mode. Prefix with C0_ESC */ *(bsKbuf++) = C0_ESC; newlen++; meta = 0; } if (ISSET_PMODE(r, ATAB(r), PrivMode_HaveBackSpace)) { bsKbuf[0] = (!!(ISSET_PMODE(r, ATAB(r),PrivMode_BackSpace)) ^ !!ctrl) ? '\b' : '\177'; bsKbuf[1] = '\0'; } else /* * If PrivMode_HaveBackSpace is unset, then h->key_backspace * will be a one character string. */ STRCPY( bsKbuf, r->h->key_backspace);# ifdef META8_OPTION if( meta ) /* We must be in 8bit mode if meta is set here */ *bsKbuf |= r->h->meta_char;# endif# ifdef MULTICHAR_SET if (ISSET_OPTION(r, Opt_mc_hack) && AVTS(r)->screen.cur.col > 0) { int col, row; newlen = STRLEN(kbuf); col = AVTS(r)->screen.cur.col - 1; row = AVTS(r)->screen.cur.row + AVTS(r)->saveLines; if (IS_MULTI2(AVTS(r)->screen.rend[row][col])) MEMMOVE(kbuf + newlen, kbuf, newlen + 1); }# endif /* MULTICHAR_SET */ break; }#endif /* !NO_BACKSPACE_KEY */ case XK_Tab: /* * 2006-04-07 gi1242: Shift tab is sometimes sent as ISO_Left_Tab, * which has keysym 0xfe20 (outside the 0xff00 -- 0xffff range). So * we have to process shift tab elsewhere. */ if (shft) STRCPY(kbuf, "\033[Z"); else {#ifdef CTRL_TAB_MAKES_META if (ctrl) meta = 1;#endif /* CTRL_TAB_MAKES_META */#ifdef MOD4_TAB_MAKES_META if (ev->state & Mod4Mask) meta = 1;#endif /* MOD4_TAB_MAKES_META */ newlen = 0; } break; case XK_Return: newlen = 0;#ifdef META8_OPTION if (r->h->meta_char == 0x80) /* * 2006-12-12 gi1242: In 8 bit mode, xterm sends 0x8d for * Alt+enter. Enter sends 0x0d. */ kbuf[newlen++] = meta ? (r->h->meta_char|C0_CR) : C0_CR; else#endif /* META8_OPTION */ { if( meta ) kbuf[newlen++] = C0_ESC; kbuf[newlen++] = C0_CR; } kbuf[newlen] = '\0'; break;#ifdef XK_KP_Left case XK_KP_Up: /* \033Ox or standard */ case XK_KP_Down: /* \033Or or standard */ case XK_KP_Right: /* \033Ov or standard */ case XK_KP_Left: /* \033Ot or standard */ /* * If numlock is on, we got here by pressing Shift + Keypad 8. * Cancel the Shift, and send the DEC terminal sequence. */ if( r->numlock_state ) shft = 0; if (ISSET_PMODE(r, ATAB(r), PrivMode_aplKP)) { set_xterm_key_seq( kbuf, "\033O", "\033O%d%c", "txvr"[keysym - XK_KP_Left], ctrl, meta, shft ); break; } /* translate to std. cursor key */ keysym = XK_Left + (keysym - XK_KP_Left); /* FALLTHROUGH */#endif /* XK_KP_Left */ case XK_Up: /* "\033[A" */ case XK_Down: /* "\033[B" */ case XK_Right: /* "\033[C" */ case XK_Left: /* "\033[D" */#ifdef XTERM_KEYS /* * Modified cursor keys are \e[1;%d%c, where %d is the modifier * number and %c is D, A, C or B for Up, Dn, Left / Right * resply. */ set_xterm_key_seq( kbuf, "\033[", "\033[1;%d%c", "DACB"[keysym - XK_Left], ctrl, meta, shft); if (ISSET_PMODE(r, ATAB(r), PrivMode_aplCUR) && !ctrl && !meta && !shft) /* * 2006-04-07 gi1242 XXX: Should we ignore the modifiers in * the private mode? */ kbuf[1] = 'O';#else STRCPY(kbuf, "\033[Z"); kbuf[2] = ("DACB"[keysym - XK_Left]); /* do Shift first */ if (shft) kbuf[2] = ("dacb"[keysym - XK_Left]); else if (ctrl) { kbuf[1] = 'O'; kbuf[2] = ("dacb"[keysym - XK_Left]); } else if (ISSET_PMODE(r, ATAB(r), PrivMode_aplCUR)) kbuf[1] = 'O';#endif#ifdef MULTICHAR_SET if (ISSET_OPTION(r, Opt_mc_hack)) { /* * If we're on a multibyte char, and we move left / right, then * duplicate the cursor key string. */ int col, row, m; col = AVTS(r)->screen.cur.col; row = AVTS(r)->screen.cur.row + AVTS(r)->saveLines; m = 0; if (keysym == XK_Right && IS_MULTI1(AVTS(r)->screen.rend[row][col]))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -