/* * $XConsortium: input.c /main/21 1996/04/17 15:54:23 kaleb $ * $XFree86: xc/programs/xterm/input.c,v 3.11.2.4 1998/10/20 20:51:46 hohndel Exp $ */ /* * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of Digital Equipment * Corporation not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * * * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* input.c */ #include #include #if HAVE_X11_DECKEYSYM_H #include #endif #include #include static char *kypd_num = " XXXXXXXX\tXXX\rXXXxxxxXXXXXXXXXXXXXXXXXXXXX*+,-./0123456789XXX="; static char *kypd_apl = " ABCDEFGHIJKLMNOPQRSTUVWXYZ??????abcdefghijklmnopqrstuvwxyzXXX"; static char *cur = "HDACB FE"; static int decfuncvalue (KeySym keycode); static int sunfuncvalue (KeySym keycode); static void AdjustAfterInput (register TScreen *screen) { if(screen->scrollkey && screen->topline != 0) WindowScroll(screen, 0); if(screen->marginbell) { int col = screen->max_col - screen->nmarginbell; if(screen->bellarmed >= 0) { if(screen->bellarmed == screen->cur_row) { if(screen->cur_col >= col) { Bell(XkbBI_MarginBell,0); screen->bellarmed = -1; } } else screen->bellarmed = screen->cur_col < col ? screen->cur_row : -1; } else if(screen->cur_col < col) screen->bellarmed = screen->cur_row; } } /* returns true if the key is on the editing keypad */ static Boolean IsEditFunctionKey(KeySym keysym) { switch (keysym) { case XK_Prior: case XK_Next: case XK_Insert: case XK_Find: case XK_Select: #ifdef DXK_Remove case DXK_Remove: #endif #ifdef XK_KP_Delete case XK_KP_Delete: case XK_KP_Insert: #endif return True; default: return False; } } /* * Modifiers other than shift, control and numlock should be reserved for the * user. We use the first two explicitly to support VT220 keyboard, and the * third is used implicitly in keyboard configuration to make the keypad work. */ #define isModified(event) \ (event->state & \ (Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask )) void Input ( register TKeyboard *keyboard, register TScreen *screen, register XKeyEvent *event, Bool eightbit) { #define STRBUFSIZE 500 char strbuf[STRBUFSIZE]; register char *string; register int key = FALSE; int pty = screen->respond; int nbytes; KeySym keysym = 0; ANSI reply; int dec_code; /* Ignore characters typed at the keyboard */ if (keyboard->flags & MODE_KAM) return; #if OPT_I18N_SUPPORT if (screen->xic) { Status status_return; nbytes = XmbLookupString (screen->xic, event, strbuf, STRBUFSIZE, &keysym, &status_return); } else #endif { static XComposeStatus compose_status = {NULL, 0}; nbytes = XLookupString (event, strbuf, STRBUFSIZE, &keysym, &compose_status); } string = &strbuf[0]; reply.a_pintro = 0; reply.a_final = 0; reply.a_nparam = 0; reply.a_inters = 0; /* VT300 & up: backarrow toggle */ if ((nbytes == 1) && !isModified(event) && (((term->keyboard.flags & MODE_DECBKM) == 0) ^ ((event->state & ControlMask) != 0)) && (keysym == XK_BackSpace)) { strbuf[0] = '\177'; } #ifdef XK_KP_Home if (keysym >= XK_KP_Home && keysym <= XK_KP_Begin) { keysym += XK_Home - XK_KP_Home; } #endif #define VT52_KEYPAD \ if_OPT_VT52_MODE(screen,{ \ reply.a_type = ESC; \ reply.a_pintro = '?'; \ }) #define VT52_CURSOR_KEYS \ if_OPT_VT52_MODE(screen,{ \ reply.a_type = ESC; \ }) #if OPT_SUNPC_KBD /* make an DEC editing-keypad from a Sun or PC editing-keypad */ if (sunKeyboard && !isModified(event)) { switch (keysym) { case XK_Delete: #ifdef DXK_Remove keysym = DXK_Remove; #endif break; case XK_Home: keysym = XK_Find; break; case XK_End: keysym = XK_Select; break; } } #endif if (IsPFKey(keysym)) { reply.a_type = SS3; reply.a_final = keysym-XK_KP_F1+'P'; VT52_CURSOR_KEYS unparseseq(&reply, pty); key = TRUE; #if 0 /* OPT_SUNPC_KBD should suppress - but only for vt220 compatibility */ } else if (sunKeyboard && screen->old_fkeys == False && screen->ansi_level <= 1 && IsEditFunctionKey(keysym)) { key = FALSE; /* ignore editing-keypad in vt100 mode */ #endif } else if (IsCursorKey(keysym) && keysym != XK_Prior && keysym != XK_Next) { if (keyboard->flags & MODE_DECCKM) { reply.a_type = SS3; reply.a_final = cur[keysym-XK_Home]; VT52_CURSOR_KEYS unparseseq(&reply, pty); } else { reply.a_type = CSI; if_OPT_VT52_MODE(screen,{ reply.a_type = ESC; }) reply.a_final = cur[keysym-XK_Home]; unparseseq(&reply, pty); } key = TRUE; } else if (IsFunctionKey(keysym) || IsMiscFunctionKey(keysym) || IsEditFunctionKey(keysym)) { #if OPT_SUNPC_KBD if ((event->state & ControlMask) && sunKeyboard && (keysym >= XK_F1 && keysym <= XK_F12)) keysym += 12; #endif dec_code = decfuncvalue(keysym); if ((event->state & ShiftMask) && ((string = udk_lookup(dec_code, &nbytes)) != 0)) { while (nbytes-- > 0) unparseputc(*string++, pty); } #if OPT_VT52_MODE /* * Interpret F1-F4 as PF1-PF4 for VT52, VT100 */ else if (!sunFunctionKeys && screen->old_fkeys == False && (dec_code >= 11 && dec_code <= 14)) { reply.a_type = SS3; VT52_CURSOR_KEYS reply.a_final = dec_code - 11 + 'P'; unparseseq(&reply, pty); } #endif else { reply.a_type = CSI; reply.a_nparam = 1; if (sunFunctionKeys) { reply.a_param[0] = sunfuncvalue (keysym); reply.a_final = 'z'; } else { reply.a_param[0] = dec_code; reply.a_final = '~'; } if (reply.a_param[0] > 0) unparseseq(&reply, pty); } key = TRUE; } else if (IsKeypadKey(keysym)) { #if OPT_SUNPC_KBD /* * DEC keyboards don't have keypad(+), but do have keypad(,) * instead. Other (Sun, PC) keyboards commonly have keypad(+), * but no keypad(,) - it's a pain for users to work around. */ if (!sunFunctionKeys && !isModified(event) && sunKeyboard && keysym == XK_KP_Add) keysym = XK_KP_Separator; #endif if ((keyboard->flags & MODE_DECKPAM) != 0) { reply.a_type = SS3; reply.a_final = kypd_apl[keysym-XK_KP_Space]; VT52_KEYPAD unparseseq(&reply, pty); } else unparseputc(kypd_num[keysym-XK_KP_Space], pty); key = TRUE; } else if (nbytes > 0) { #if OPT_TEK4014 if(screen->TekGIN) { TekEnqMouse(*string++); TekGINoff(); nbytes--; } #endif if ((nbytes == 1) && eightbit) { if (screen->input_eight_bits) *string |= 0x80; /* turn on eighth bit */ else unparseputc (ESC, pty); /* escape */ } while (nbytes-- > 0) unparseputc(*string++, pty); key = TRUE; } if(key && !TEK4014_ACTIVE(screen)) AdjustAfterInput(screen); #ifdef ENABLE_PRINT if (keysym == XK_F2) TekPrint(); #endif return; } void StringInput ( register TScreen *screen, register char *string, size_t nbytes) { int pty = screen->respond; #if OPT_TEK4014 if(nbytes && screen->TekGIN) { TekEnqMouse(*string++); TekGINoff(); nbytes--; } #endif while (nbytes-- != 0) unparseputc(*string++, pty); if (!TEK4014_ACTIVE(screen)) AdjustAfterInput(screen); } /* These definitions are DEC-style (e.g., vt320) */ static int decfuncvalue (KeySym keycode) { switch (keycode) { case XK_F1: return(11); case XK_F2: return(12); case XK_F3: return(13); case XK_F4: return(14); case XK_F5: return(15); case XK_F6: return(17); case XK_F7: return(18); case XK_F8: return(19); case XK_F9: return(20); case XK_F10: return(21); case XK_F11: return(23); case XK_F12: return(24); case XK_F13: return(25); case XK_F14: return(26); case XK_F15: return(28); case XK_Help: return(28); case XK_F16: return(29); case XK_Menu: return(29); case XK_F17: return(31); case XK_F18: return(32); case XK_F19: return(33); case XK_F20: return(34); case XK_Find : return(1); case XK_Insert: return(2); case XK_Delete: return(3); #ifdef XK_KP_Insert case XK_KP_Insert: return(2); case XK_KP_Delete: return(3); #endif #ifdef DXK_Remove case DXK_Remove: return(3); #endif case XK_Select: return(4); case XK_Prior: return(5); case XK_Next: return(6); default: return(-1); } } static int sunfuncvalue (KeySym keycode) { switch (keycode) { case XK_F1: return(224); case XK_F2: return(225); case XK_F3: return(226); case XK_F4: return(227); case XK_F5: return(228); case XK_F6: return(229); case XK_F7: return(230); case XK_F8: return(231); case XK_F9: return(232); case XK_F10: return(233); case XK_F11: return(192); case XK_F12: return(193); case XK_F13: return(194); case XK_F14: return(195); case XK_F15: return(196); case XK_Help: return(196); case XK_F16: return(197); case XK_Menu: return(197); case XK_F17: return(198); case XK_F18: return(199); case XK_F19: return(200); case XK_F20: return(201); case XK_R1: return(208); case XK_R2: return(209); case XK_R3: return(210); case XK_R4: return(211); case XK_R5: return(212); case XK_R6: return(213); case XK_R7: return(214); case XK_R8: return(215); case XK_R9: return(216); case XK_R10: return(217); case XK_R11: return(218); case XK_R12: return(219); case XK_R13: return(220); case XK_R14: return(221); case XK_R15: return(222); case XK_Find : return(1); case XK_Insert: return(2); case XK_Delete: return(3); #ifdef XK_KP_Insert case XK_KP_Insert: return(2); case XK_KP_Delete: return(3); #endif #ifdef DXK_Remove case DXK_Remove: return(3); #endif case XK_Select: return(4); case XK_Prior: return(5); case XK_Next: return(6); default: return(-1); } }