summaryrefslogtreecommitdiff
path: root/app/xterm/input.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/xterm/input.c')
-rw-r--r--app/xterm/input.c311
1 files changed, 184 insertions, 127 deletions
diff --git a/app/xterm/input.c b/app/xterm/input.c
index fc4740eef..60258b6a7 100644
--- a/app/xterm/input.c
+++ b/app/xterm/input.c
@@ -1,4 +1,4 @@
-/* $XTermId: input.c,v 1.334 2012/03/15 00:01:30 tom Exp $ */
+/* $XTermId: input.c,v 1.344 2012/11/23 18:43:35 tom Exp $ */
/*
* Copyright 1999-2011,2012 by Thomas E. Dickey
@@ -74,6 +74,10 @@
#include <X11/XF86keysym.h>
#endif
+#ifdef HAVE_XKBKEYCODETOKEYSYM
+#include <X11/XKBlib.h>
+#endif
+
#include <X11/Xutil.h>
#include <stdio.h>
#include <ctype.h>
@@ -201,21 +205,60 @@ AdjustAfterInput(XtermWidget xw)
/*
* Return true if the key is on the editing keypad. This overlaps with
- * IsCursorKey() and IsKeypadKey() and must be tested before those macro to
+ * IsCursorKey() and IsKeypadKey() and must be tested before those macros to
* distinguish it from them.
+ *
+ * VT220 emulation uses the VT100 numeric keypad as well as a 6-key
+ * editing keypad. Here's a picture of the VT220 editing keypad:
+ * +--------+--------+--------+
+ * | Find | Insert | Remove |
+ * +--------+--------+--------+
+ * | Select | Prev | Next |
+ * +--------+--------+--------+
+ *
+ * and the similar Sun and PC keypads:
+ * +--------+--------+--------+
+ * | Insert | Home | PageUp |
+ * +--------+--------+--------+
+ * | Delete | End | PageDn |
+ * +--------+--------+--------+
*/
static Bool
-IsEditFunctionKey(KeySym keysym)
+IsEditKeypad(XtermWidget xw, KeySym keysym)
{
+ Bool result;
+
switch (keysym) {
- case XK_Prior: /* editing keypad */
- case XK_Next: /* editing keypad */
- case XK_Insert: /* editing keypad */
- case XK_Find: /* editing keypad */
- case XK_Select: /* editing keypad */
+ case XK_Delete:
+ result = !xtermDeleteIsDEL(xw);
+ break;
+ case XK_Prior:
+ case XK_Next:
+ case XK_Insert:
+ case XK_Find:
+ case XK_Select:
#ifdef DXK_Remove
- case DXK_Remove: /* editing keypad */
+ case DXK_Remove:
#endif
+ result = True;
+ break;
+ default:
+ result = False;
+ break;
+ }
+ return result;
+}
+
+/*
+ * Editing-keypad, plus other editing keys which are not included in the
+ * other macros.
+ */
+static Bool
+IsEditFunctionKey(XtermWidget xw, KeySym keysym)
+{
+ Bool result;
+
+ switch (keysym) {
#ifdef XK_KP_Delete
case XK_KP_Delete: /* editing key on numeric keypad */
case XK_KP_Insert: /* editing key on numeric keypad */
@@ -223,10 +266,13 @@ IsEditFunctionKey(KeySym keysym)
#ifdef XK_ISO_Left_Tab
case XK_ISO_Left_Tab:
#endif
- return True;
+ result = True;
+ break;
default:
- return False;
+ result = IsEditKeypad(xw, keysym);
+ break;
}
+ return result;
}
#if OPT_MOD_FKEYS
@@ -301,24 +347,44 @@ IsControlAlias(KEY_DATA * kd)
* would be Home (XK_KP_Home). The other modifiers work, subject to the
* usual window-manager assignments.
*/
+#if OPT_SUNPC_KBD
+#define LegacyAllows(code) (!is_legacy || (code & xw->keyboard.modify_now.allow_keys) != 0)
+#else
+#define LegacyAllows(code) True
+#endif
+
static Bool
allowModifierParm(XtermWidget xw, KEY_DATA * kd)
{
TKeyboard *keyboard = &(xw->keyboard);
TScreen *screen = TScreenOf(xw);
int keypad_mode = ((keyboard->flags & MODE_DECKPAM) != 0);
-
+ int is_legacy = (keyboard->type == keyboardIsLegacy);
Bool result = False;
- (void) screen;
- if (!(IsKeypadKey(kd->keysym) && keypad_mode)
#if OPT_SUNPC_KBD
- && keyboard->type != keyboardIsVT220
+ if (keyboard->type == keyboardIsVT220)
+ is_legacy = True;
#endif
+
+ (void) screen;
#if OPT_VT52_MODE
- && screen->vtXX_level != 0
+ if (screen->vtXX_level != 0)
#endif
- ) {
+ {
+ if (IsCursorKey(kd->keysym) || IsEditFunctionKey(xw, kd->keysym)) {
+ result = LegacyAllows(2);
+ } else if (IsKeypadKey(kd->keysym)) {
+ if (keypad_mode) {
+ result = LegacyAllows(1);
+ }
+ } else if (IsFunctionKey(kd->keysym)) {
+ result = LegacyAllows(4);
+ } else if (IsMiscFunctionKey(kd->keysym)) {
+ result = LegacyAllows(8);
+ }
+ }
+ if (xw->keyboard.modify_now.other_keys != 0) {
result = True;
}
return result;
@@ -349,19 +415,15 @@ xtermParamToState(XtermWidget xw, unsigned param)
{
unsigned result = 0;
#if OPT_NUM_LOCK
- if (param > MOD_NONE
- && ((ShiftMask
- | ControlMask
- | xw->misc.alt_mods
- | xw->misc.meta_mods) & xw->misc.other_mods) == 0) {
+ if (param > MOD_NONE) {
if ((param - MOD_NONE) & MOD_SHIFT)
UIntSet(result, ShiftMask);
if ((param - MOD_NONE) & MOD_CTRL)
UIntSet(result, ControlMask);
if ((param - MOD_NONE) & MOD_ALT)
- UIntSet(result, xw->misc.alt_mods);
+ UIntSet(result, xw->work.alt_mods);
if ((param - MOD_NONE) & MOD_META)
- UIntSet(result, xw->misc.meta_mods);
+ UIntSet(result, xw->work.meta_mods);
}
#else
(void) xw;
@@ -383,23 +445,21 @@ xtermStateToParam(XtermWidget xw, unsigned state)
TRACE(("xtermStateToParam %#x\n", state));
#if OPT_NUM_LOCK
- if ((state & xw->misc.other_mods) == 0) {
- if (state & ShiftMask) {
- modify_parm += MOD_SHIFT;
- UIntClr(state, ShiftMask);
- }
- if (state & ControlMask) {
- modify_parm += MOD_CTRL;
- UIntClr(state, ControlMask);
- }
- if ((state & xw->misc.alt_mods) != 0) {
- modify_parm += MOD_ALT;
- UIntClr(state, xw->misc.alt_mods);
- }
- if ((state & xw->misc.meta_mods) != 0) {
- modify_parm += MOD_META;
- UIntClr(state, xw->misc.meta_mods);
- }
+ if (state & ShiftMask) {
+ modify_parm += MOD_SHIFT;
+ UIntClr(state, ShiftMask);
+ }
+ if (state & ControlMask) {
+ modify_parm += MOD_CTRL;
+ UIntClr(state, ControlMask);
+ }
+ if ((state & xw->work.alt_mods) != 0) {
+ modify_parm += MOD_ALT;
+ UIntClr(state, xw->work.alt_mods);
+ }
+ if ((state & xw->work.meta_mods) != 0) {
+ modify_parm += MOD_META;
+ UIntClr(state, xw->work.meta_mods);
}
if (modify_parm == MOD_NONE)
modify_parm = 0;
@@ -463,7 +523,7 @@ static unsigned
allowedCharModifiers(XtermWidget xw, unsigned state, KEY_DATA * kd)
{
#if OPT_NUM_LOCK
- unsigned a_or_m = (state & (xw->misc.meta_mods | xw->misc.alt_mods));
+ unsigned a_or_m = (state & (xw->work.meta_mods | xw->work.alt_mods));
#else
unsigned a_or_m = 0;
#endif
@@ -500,11 +560,11 @@ allowedCharModifiers(XtermWidget xw, unsigned state, KEY_DATA * kd)
}
#if OPT_NUM_LOCK
result = filterAltMeta(result,
- xw->misc.meta_mods,
+ xw->work.meta_mods,
TScreenOf(xw)->meta_sends_esc, kd);
if (TScreenOf(xw)->alt_is_not_meta) {
result = filterAltMeta(result,
- xw->misc.alt_mods,
+ xw->work.alt_mods,
TScreenOf(xw)->alt_sends_esc, kd);
}
#endif
@@ -534,16 +594,12 @@ ModifyOtherKeys(XtermWidget xw,
* Exclude the keys already covered by a modifier.
*/
if (kd->is_fkey
- || IsEditFunctionKey(kd->keysym)
+ || IsEditFunctionKey(xw, kd->keysym)
|| IsKeypadKey(kd->keysym)
|| IsCursorKey(kd->keysym)
|| IsPFKey(kd->keysym)
|| IsMiscFunctionKey(kd->keysym)
- || IsPrivateKeypadKey(kd->keysym)
-#if OPT_NUM_LOCK
- || (state & xw->misc.other_mods) != 0
-#endif
- ) {
+ || IsPrivateKeypadKey(kd->keysym)) {
result = False;
} else if (modify_parm != 0) {
if (IsBackarrowToggle(keyboard, kd->keysym, state)) {
@@ -790,73 +846,58 @@ xtermDeleteIsDEL(XtermWidget xw)
return result;
}
-void
-Input(XtermWidget xw,
- XKeyEvent * event,
- Bool eightbit)
+static Boolean
+lookupKeyData(KEY_DATA * kd, XtermWidget xw, XKeyEvent * event)
{
- Char *string;
-
- TKeyboard *keyboard = &(xw->keyboard);
TScreen *screen = TScreenOf(xw);
+ TKeyboard *keyboard = &(xw->keyboard);
+ Boolean result = True;
- int j;
- int key = False;
- ANSI reply;
- int dec_code;
- unsigned modify_parm = 0;
- int keypad_mode = ((keyboard->flags & MODE_DECKPAM) != 0);
- unsigned evt_state = event->state;
- unsigned mod_state;
- KEY_DATA kd;
-
- /* Ignore characters typed at the keyboard */
- if (keyboard->flags & MODE_KAM)
- return;
+ TRACE(("%s %#x\n", visibleEventType(event->type), event->keycode));
- kd.keysym = 0;
- kd.is_fkey = False;
+ kd->keysym = 0;
+ kd->is_fkey = False;
#if OPT_TCAP_QUERY
if (screen->tc_query_code >= 0) {
- kd.keysym = (KeySym) screen->tc_query_code;
- kd.is_fkey = screen->tc_query_fkey;
- if (kd.keysym != XK_BackSpace) {
- kd.nbytes = 0;
- kd.strbuf[0] = 0;
+ kd->keysym = (KeySym) screen->tc_query_code;
+ kd->is_fkey = screen->tc_query_fkey;
+ if (kd->keysym != XK_BackSpace) {
+ kd->nbytes = 0;
+ kd->strbuf[0] = 0;
} else {
- kd.nbytes = 1;
- kd.strbuf[0] = 8;
+ kd->nbytes = 1;
+ kd->strbuf[0] = 8;
}
} else
#endif
{
#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
TInput *input = lookupTInput(xw, (Widget) xw);
- if (input->xic) {
+ if (input && input->xic) {
Status status_return;
#if OPT_WIDE_CHARS
if (screen->utf8_mode) {
- kd.nbytes = Xutf8LookupString(input->xic, event,
- kd.strbuf, (int) sizeof(kd.strbuf),
- &kd.keysym, &status_return);
+ kd->nbytes = Xutf8LookupString(input->xic, event,
+ kd->strbuf, (int) sizeof(kd->strbuf),
+ &(kd->keysym), &status_return);
} else
#endif
{
- kd.nbytes = XmbLookupString(input->xic, event,
- kd.strbuf, (int) sizeof(kd.strbuf),
- &kd.keysym, &status_return);
+ kd->nbytes = XmbLookupString(input->xic, event,
+ kd->strbuf, (int) sizeof(kd->strbuf),
+ &(kd->keysym), &status_return);
}
#if OPT_MOD_FKEYS
/*
* Fill-in some code useful with IsControlAlias():
*/
if (status_return == XLookupBoth
- && kd.nbytes <= 1
- && !IsPredefinedKey(kd.keysym)
+ && kd->nbytes <= 1
+ && !IsPredefinedKey(kd->keysym)
&& (keyboard->modify_now.other_keys > 1)
- && !IsControlInput(&kd)) {
- kd.nbytes = 1;
- kd.strbuf[0] = (char) kd.keysym;
+ && !IsControlInput(kd)) {
+ kd->nbytes = 1;
+ kd->strbuf[0] = (char) kd->keysym;
}
#endif /* OPT_MOD_FKEYS */
} else
@@ -864,11 +905,40 @@ Input(XtermWidget xw,
{
static XComposeStatus compose_status =
{NULL, 0};
- kd.nbytes = XLookupString(event, kd.strbuf, (int) sizeof(kd.strbuf),
- &kd.keysym, &compose_status);
+ kd->nbytes = XLookupString(event,
+ kd->strbuf, (int) sizeof(kd->strbuf),
+ &(kd->keysym), &compose_status);
}
- kd.is_fkey = IsFunctionKey(kd.keysym);
+ kd->is_fkey = IsFunctionKey(kd->keysym);
}
+ return result;
+}
+
+void
+Input(XtermWidget xw,
+ XKeyEvent * event,
+ Bool eightbit)
+{
+ Char *string;
+
+ TKeyboard *keyboard = &(xw->keyboard);
+ TScreen *screen = TScreenOf(xw);
+
+ int j;
+ int key = False;
+ ANSI reply;
+ int dec_code;
+ unsigned modify_parm = 0;
+ int keypad_mode = ((keyboard->flags & MODE_DECKPAM) != 0);
+ unsigned evt_state = event->state;
+ unsigned mod_state;
+ KEY_DATA kd;
+
+ /* Ignore characters typed at the keyboard */
+ if (keyboard->flags & MODE_KAM)
+ return;
+
+ lookupKeyData(&kd, xw, event);
memset(&reply, 0, sizeof(reply));
@@ -888,7 +958,7 @@ Input(XtermWidget xw,
IsPFKey(kd.keysym) ? " PFKey" : "",
kd.is_fkey ? " FKey" : "",
IsMiscFunctionKey(kd.keysym) ? " MiscFKey" : "",
- IsEditFunctionKey(kd.keysym) ? " EditFkey" : ""));
+ IsEditFunctionKey(xw, kd.keysym) ? " EditFkey" : ""));
#if OPT_SUNPC_KBD
/*
@@ -934,7 +1004,7 @@ Input(XtermWidget xw,
if (kd.nbytes == 1
&& IsKeypadKey(kd.keysym)
&& xw->misc.real_NumLock
- && (xw->misc.num_lock & evt_state) != 0) {
+ && (xw->work.num_lock & evt_state) != 0) {
keypad_mode = 0;
TRACE(("...Input num_lock, force keypad_mode off\n"));
}
@@ -1093,7 +1163,7 @@ Input(XtermWidget xw,
modifyCursorKey(&reply,
((kd.is_fkey
|| IsMiscFunctionKey(kd.keysym)
- || IsEditFunctionKey(kd.keysym))
+ || IsEditFunctionKey(xw, kd.keysym))
? keyboard->modify_now.function_keys
: keyboard->modify_now.cursor_keys),
&modify_parm);
@@ -1101,7 +1171,7 @@ Input(XtermWidget xw,
unparseseq(xw, &reply);
} else if (((kd.is_fkey
|| IsMiscFunctionKey(kd.keysym)
- || IsEditFunctionKey(kd.keysym))
+ || IsEditFunctionKey(xw, kd.keysym))
#if OPT_MOD_FKEYS
&& !ModifyOtherKeys(xw, evt_state, &kd, modify_parm)
#endif
@@ -1247,9 +1317,9 @@ Input(XtermWidget xw,
*/
if (kd.nbytes != 0) {
if (screen->meta_sends_esc
- && (evt_state & xw->misc.meta_mods) != 0) {
+ && (evt_state & xw->work.meta_mods) != 0) {
TRACE(("...input-char is modified by META\n"));
- UIntClr(evt_state, xw->misc.meta_mods);
+ UIntClr(evt_state, xw->work.meta_mods);
eightbit = False;
prefix = ANSI_ESC;
} else if (eightbit) {
@@ -1257,8 +1327,8 @@ Input(XtermWidget xw,
TRACE(("...input-char is shifted by META\n"));
}
if (screen->alt_is_not_meta
- && (evt_state & xw->misc.alt_mods) != 0) {
- UIntClr(evt_state, xw->misc.alt_mods);
+ && (evt_state & xw->work.alt_mods) != 0) {
+ UIntClr(evt_state, xw->work.alt_mods);
if (screen->alt_sends_esc) {
TRACE(("...input-char is modified by ALT\n"));
eightbit = False;
@@ -1924,10 +1994,10 @@ addTranslation(XtermWidget xw, const char *fromString, const char *toString)
}
#endif
-#define SaveMask(name) xw->misc.name |= (unsigned) mask;\
- TRACE(("SaveMask(%s) %#x (%#x is%s modifier)\n", \
- #name, \
- xw->misc.name, (unsigned) mask, \
+#define SaveMask(name) xw->work.name |= (unsigned) mask;\
+ TRACE(("SaveMask(%#x -> %s) %#x (%#x is%s modifier)\n", \
+ (unsigned) keysym, #name, \
+ xw->work.name, (unsigned) mask, \
ModifierName((unsigned) mask)));
/*
* Determine which modifier mask (if any) applies to the Num_Lock keysym.
@@ -1996,7 +2066,11 @@ VTInitModifiers(XtermWidget xw)
continue;
for (l = 0; l < keysyms_per_keycode; ++l) {
+#ifdef HAVE_XKBKEYCODETOKEYSYM
+ keysym = XkbKeycodeToKeysym(dpy, code, 0, l);
+#else
keysym = XKeycodeToKeysym(dpy, code, l);
+#endif
if (keysym == NoSymbol) {
/* EMPTY */ ;
} else if (keysym == XK_Num_Lock) {
@@ -2005,23 +2079,6 @@ VTInitModifiers(XtermWidget xw)
SaveMask(alt_mods);
} else if (keysym == XK_Meta_L || keysym == XK_Meta_R) {
SaveMask(meta_mods);
- } else if (mask == ShiftMask
- && (keysym == XK_Shift_L
- || keysym == XK_Shift_R)) {
- /* EMPTY */ ;
- } else if (mask == ControlMask
- && (keysym == XK_Control_L
- || keysym == XK_Control_R)) {
- /* EMPTY */ ;
- } else if (mask == LockMask
- && (keysym == XK_Caps_Lock)) {
- /* EMPTY */ ;
- } else if (keysym == XK_Mode_switch
-#ifdef XK_ISO_Level3_Shift
- || keysym == XK_ISO_Level3_Shift
-#endif
- ) {
- SaveMask(other_mods);
}
}
}
@@ -2048,20 +2105,20 @@ VTInitModifiers(XtermWidget xw)
* If the Alt modifier is used in translations, we would rather not
* use it to modify function-keys when NumLock is active.
*/
- if ((xw->misc.alt_mods != 0)
+ if ((xw->work.alt_mods != 0)
&& xtermHasTranslation(xw, "alt", True)) {
TRACE(("ALT is used as a modifier in translations (ignore mask)\n"));
- xw->misc.alt_mods = 0;
+ xw->work.alt_mods = 0;
}
/*
* If the Meta modifier is used in translations, we would rather not
* use it to modify function-keys.
*/
- if ((xw->misc.meta_mods != 0)
+ if ((xw->work.meta_mods != 0)
&& xtermHasTranslation(xw, "meta", True)) {
TRACE(("META is used as a modifier in translations\n"));
- xw->misc.meta_mods = 0;
+ xw->work.meta_mods = 0;
}
}