📄 command.c
字号:
/*--------------------------------*-C-*---------------------------------* * File: command.c *----------------------------------------------------------------------* * $Id: command.c,v 1.264 2003/03/26 05:59:49 gcw Exp $ * * All portions of code are copyright by their respective author/s. * Copyright (c) 1992 John Bovey, University of Kent at Canterbury <jdb@ukc.ac.uk> * - original version * Copyright (c) 1994 Robert Nation <nation@rocket.sanders.lockheed.com> * - extensive modifications * Copyright (c) 1995 Garrett D'Amore <garrett@netcom.com> * - vt100 printing * Copyright (c) 1995 Steven Hirsch <hirsch@emba.uvm.edu> * - X11 mouse report mode and support for * DEC "private mode" save/restore functions. * Copyright (c) 1995 Jakub Jelinek <jj@gnu.ai.mit.edu> * - key-related changes to handle Shift+function * keys properly. * Copyright (c) 1997 MJ Olesen <olesen@me.queensu.ca> * - extensive modifications * Copyright (c) 1997 Raul Garcia Garcia <rgg@tid.es> * - modification and cleanups for Solaris 2.x * and Linux 1.2.x * Copyright (c) 1997,1998 Oezguer Kesim <kesim@math.fu-berlin.de> * Copyright (c) 1998-2001 Geoff Wing <gcw@pobox.com> * - extensive modifications * Copyright (c) 1998 Alfredo K. Kojima <kojima@windowmaker.org> * Copyright (c) 2001 Marius Gedminas * - Ctrl/Mod4+Tab works like Meta+Tab (options) * * 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. *----------------------------------------------------------------------*//*{{{ includes: */#include "../config.h" /* NECESSARY */#include "rxvt.h" /* NECESSARY */#include "version.h"#include "command.h"/*----------------------------------------------------------------------*//*{{{ Convert the keypress event into a string *//* INTPROTO */voidrxvt_lookup_key(rxvt_t *r, XKeyEvent *ev){ int ctrl, meta, shft, len; unsigned int newlen; KeySym keysym;#ifdef DEBUG_CMD static int debug_key = 1; /* accessible by a debugger only */#endif#ifdef USE_XIM int valid_keysym;#endif unsigned char *kbuf = r->h->kbuf;/* * use Num_Lock to toggle Keypad on/off. If Num_Lock is off, allow an * escape sequence to toggle the Keypad. * * Always permit `shift' to override the current setting */ shft = (ev->state & ShiftMask); ctrl = (ev->state & ControlMask); meta = (ev->state & r->h->ModMetaMask); if (r->numlock_state || (ev->state & r->h->ModNumLockMask)) { r->numlock_state = (ev->state & r->h->ModNumLockMask); PrivMode((!r->numlock_state), PrivMode_aplKP); }#ifdef USE_XIM if (r->h->Input_Context != NULL) { Status status_return; kbuf[0] = '\0'; len = XmbLookupString(r->h->Input_Context, ev, (char *)kbuf, KBUFSZ, &keysym, &status_return); valid_keysym = ((status_return == XLookupKeySym) || (status_return == XLookupBoth)); } else { len = XLookupString(ev, (char *)kbuf, KBUFSZ, &keysym, &r->h->compose); valid_keysym = 1; }#else /* USE_XIM */ len = XLookupString(ev, (char *)kbuf, KBUFSZ, &keysym, &r->h->compose);/* * map unmapped Latin[2-4]/Katakana/Arabic/Cyrillic/Greek entries -> Latin1 * good for installations with correct fonts, but without XLOCALE */ if (!len) { if ((keysym >= 0x0100) && (keysym < 0x0800)) { kbuf[0] = (keysym & 0xFF); kbuf[1] = '\0'; len = 1; } else kbuf[0] = '\0'; }#endif /* USE_XIM */#ifdef USE_XIM if (valid_keysym)#endif {/* for some backwards compatibility */#if defined(HOTKEY_CTRL) || defined(HOTKEY_META)# ifdef HOTKEY_CTRL if (ctrl) {# else if (meta) {# endif if (keysym == r->h->ks_bigfont) { rxvt_change_font(r, 0, FONT_UP); return; } else if (keysym == r->h->ks_smallfont) { rxvt_change_font(r, 0, FONT_DN); return; } }#endif if (r->TermWin.saveLines) {#ifdef UNSHIFTED_SCROLLKEYS if (!ctrl && !meta) {#else if (IS_SCROLL_MOD) {#endif int lnsppg;#ifdef PAGING_CONTEXT_LINES lnsppg = r->TermWin.nrow - PAGING_CONTEXT_LINES;#else lnsppg = r->TermWin.nrow * 4 / 5;#endif if (keysym == XK_Prior) { rxvt_scr_page(r, UP, lnsppg); return; } else if (keysym == XK_Next) { rxvt_scr_page(r, DN, lnsppg); return; } }#ifdef SCROLL_ON_UPDOWN_KEYS if (IS_SCROLL_MOD) { if (keysym == XK_Up) { rxvt_scr_page(r, UP, 1); return; } else if (keysym == XK_Down) { rxvt_scr_page(r, DN, 1); return; } }#endif#ifdef SCROLL_ON_HOMEEND_KEYS if (IS_SCROLL_MOD) { if (keysym == XK_Home) { rxvt_scr_move_to(r, 0, 1); return; } else if (keysym == XK_End) { rxvt_scr_move_to(r, 1, 0); return; } }#endif } if (shft) { /* Shift + F1 - F10 generates F11 - F20 */ if (keysym >= XK_F1 && keysym <= XK_F10) { keysym += (XK_F11 - XK_F1); shft = 0; /* turn off Shift */ } else if (!ctrl && !meta && (r->h->PrivateModes & PrivMode_ShiftKeys)) { switch (keysym) { /* normal XTerm key bindings */ case XK_Insert: /* Shift+Insert = paste mouse selection */ rxvt_selection_request(r, ev->time, 0, 0); return; /* rxvt extras */ case XK_KP_Add: /* Shift+KP_Add = bigger font */ rxvt_change_font(r, 0, FONT_UP); return; case XK_KP_Subtract: /* Shift+KP_Subtract = smaller font */ rxvt_change_font(r, 0, FONT_DN); return; } } }#ifdef PRINTPIPE if (keysym == XK_Print) { rxvt_scr_printscreen(r, ctrl | shft); return; }#endif#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, XTerm_title, (greek_getmode() == GREEK_ELOT928 ? "[Greek: iso]" : "[Greek: ibm]"), CHAR_ST); greek_reset(); } else rxvt_xterm_seq(r, XTerm_title, APL_NAME "-" VERSION, CHAR_ST); return; }#endif if (keysym >= 0xFF00 && keysym <= 0xFFFF) {#ifdef KEYSYM_RESOURCE if (!(shft | ctrl) && r->h->Keysym_map[keysym & 0xFF] != NULL) { unsigned int l; const unsigned char *kbuf0; const unsigned char ch = C0_ESC; kbuf0 = (r->h->Keysym_map[keysym & 0xFF]); l = (unsigned int)*kbuf0++; /* escape prefix */ if (meta)# ifdef META8_OPTION if (r->h->meta_char == C0_ESC)# endif rxvt_tt_write(r, &ch, 1); rxvt_tt_write(r, kbuf0, l); return; } else#endif { newlen = 1; switch (keysym) {#ifndef NO_BACKSPACE_KEY case XK_BackSpace: if (r->h->PrivateModes & PrivMode_HaveBackSpace) { kbuf[0] = (!!(r->h->PrivateModes & PrivMode_BackSpace) ^ !!ctrl) ? '\b' : '\177'; kbuf[1] = '\0'; } else STRCPY(kbuf, r->h->key_backspace);# ifdef MULTICHAR_SET if ((r->Options & Opt_mc_hack) && r->screen.cur.col > 0) { int col, row; newlen = STRLEN(kbuf); col = r->screen.cur.col - 1; row = r->screen.cur.row + r->TermWin.saveLines; if (IS_MULTI2(r->screen.rend[row][col])) MEMMOVE(kbuf + newlen, kbuf, newlen + 1); }# endif break;#endif#ifndef NO_DELETE_KEY case XK_Delete: STRCPY(kbuf, r->h->key_delete);# ifdef MULTICHAR_SET if (r->Options & Opt_mc_hack) { int col, row; newlen = STRLEN(kbuf); col = r->screen.cur.col; row = r->screen.cur.row + r->TermWin.saveLines; if (IS_MULTI1(r->screen.rend[row][col])) MEMMOVE(kbuf + newlen, kbuf, newlen + 1); }# endif break;#endif case XK_Tab: if (shft) STRCPY(kbuf, "\033[Z"); else {#ifdef CTRL_TAB_MAKES_META if (ctrl) meta = 1;#endif#ifdef MOD4_TAB_MAKES_META if (ev->state & Mod4Mask) meta = 1;#endif 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 ((r->h->PrivateModes & PrivMode_aplKP) ? !shft : shft) { STRCPY(kbuf, "\033OZ"); kbuf[2] = ("txvr"[keysym - XK_KP_Left]); break; } else /* translate to std. cursor key */ keysym = XK_Left + (keysym - XK_KP_Left); /* FALLTHROUGH */#endif case XK_Up: /* "\033[A" */ case XK_Down: /* "\033[B" */ case XK_Right: /* "\033[C" */ case XK_Left: /* "\033[D" */ 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 (r->h->PrivateModes & PrivMode_aplCUR) kbuf[1] = 'O';#ifdef MULTICHAR_SET if (r->Options & Opt_mc_hack) { int col, row, m; col = r->screen.cur.col; row = r->screen.cur.row + r->TermWin.saveLines; m = 0; if (keysym == XK_Right && IS_MULTI1(r->screen.rend[row][col])) m = 1; else if (keysym == XK_Left) { if (col > 0) { if (IS_MULTI2(r->screen.rend[row][col - 1])) m = 1; } else if (r->screen.cur.row > 0) { col = r->screen.tlen[--row]; if (col == -1) col = r->TermWin.ncol - 1; else col--; if (col > 0 && IS_MULTI2(r->screen.rend[row][col])) m = 1; } } if (m) MEMMOVE(kbuf + 3, kbuf, 3 + 1); }#endif break;#ifndef UNSHIFTED_SCROLLKEYS# ifdef XK_KP_Prior case XK_KP_Prior: /* allow shift to override */ if ((r->h->PrivateModes & PrivMode_aplKP) ? !shft : shft) { STRCPY(kbuf, "\033Oy"); break; } /* FALLTHROUGH */# endif case XK_Prior: STRCPY(kbuf, "\033[5~"); break;# ifdef XK_KP_Next case XK_KP_Next: /* allow shift to override */ if ((r->h->PrivateModes & PrivMode_aplKP) ? !shft : shft) { STRCPY(kbuf, "\033Os"); break; } /* FALLTHROUGH */# endif case XK_Next: STRCPY(kbuf, "\033[6~"); break;#endif case XK_KP_Enter: /* allow shift to override */ if ((r->h->PrivateModes & PrivMode_aplKP) ? !shft : shft) { STRCPY(kbuf, "\033OM"); } else { kbuf[0] = '\r'; kbuf[1] = '\0'; } break;#ifdef XK_KP_Begin case XK_KP_Begin: STRCPY(kbuf, "\033Ou"); break; case XK_KP_Insert: STRCPY(kbuf, "\033Op"); break; case XK_KP_Delete: STRCPY(kbuf, "\033On"); break;#endif case XK_KP_F1: /* "\033OP" */ case XK_KP_F2: /* "\033OQ" */ case XK_KP_F3: /* "\033OR" */ case XK_KP_F4: /* "\033OS" */ STRCPY(kbuf, "\033OP"); kbuf[2] += (keysym - XK_KP_F1); break; case XK_KP_Multiply: /* "\033Oj" : "*" */ case XK_KP_Add: /* "\033Ok" : "+" */ case XK_KP_Separator: /* "\033Ol" : "," */ case XK_KP_Subtract: /* "\033Om" : "-" */ case XK_KP_Decimal: /* "\033On" : "." */ case XK_KP_Divide: /* "\033Oo" : "/" */ case XK_KP_0: /* "\033Op" : "0" */ case XK_KP_1: /* "\033Oq" : "1" */ case XK_KP_2: /* "\033Or" : "2" */ case XK_KP_3: /* "\033Os" : "3" */ case XK_KP_4: /* "\033Ot" : "4" */ case XK_KP_5: /* "\033Ou" : "5" */ case XK_KP_6: /* "\033Ov" : "6" */ case XK_KP_7: /* "\033Ow" : "7" */ case XK_KP_8: /* "\033Ox" : "8" */ case XK_KP_9: /* "\033Oy" : "9" */ /* allow shift to override */ if ((r->h->PrivateModes & PrivMode_aplKP) ? !shft : shft) { STRCPY(kbuf, "\033Oj"); kbuf[2] += (keysym - XK_KP_Multiply); } else { kbuf[0] = ('*' + (keysym - XK_KP_Multiply)); kbuf[1] = '\0'; } break; case XK_Find: STRCPY(kbuf, "\033[1~"); break; case XK_Insert: STRCPY(kbuf, "\033[2~"); break;#ifdef DXK_Remove /* support for DEC remove like key */ case DXK_Remove: /* FALLTHROUGH */#endif case XK_Execute: STRCPY(kbuf, "\033[3~"); break; case XK_Select: STRCPY(kbuf, "\033[4~"); break;#ifdef XK_KP_End case XK_KP_End: /* allow shift to override */ if ((r->h->PrivateModes & PrivMode_aplKP) ? !shft : shft) { STRCPY(kbuf, "\033Oq"); break; } /* FALLTHROUGH */#endif case XK_End: STRCPY(kbuf, KS_END); break;#ifdef XK_KP_Home case XK_KP_Home: /* allow shift to override */ if ((r->h->PrivateModes & PrivMode_aplKP) ? !shft : shft) { STRCPY(kbuf, "\033Ow"); break; } /* FALLTHROUGH */#endif case XK_Home: STRCPY(kbuf, KS_HOME); break;#define FKEY(n, fkey) \ sprintf((char *)kbuf,"\033[%2d~", (int)((n) + (keysym - fkey))) case XK_F1: /* "\033[11~" */ case XK_F2: /* "\033[12~" */ case XK_F3: /* "\033[13~" */ case XK_F4: /* "\033[14~" */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -