Wed Mar 1 18:37:18 PST 2000 Michael Jennings <mej@eterm.org>
I'm still not done with the commenting work I've been doing, but I've made some fixes, so I figured it was time to commit what I've done so far. I've added support for multi-byte selection/pastes from programs like Netscape, thanks in part to a patch from Yasuyuki Furukawa <yasu@on.cs.keio.ac.jp>. I've also applied a bugfix for pty allocation on Irix from David Kaelbling <drk@sgi.com>, a display bugfix pointed out by Valdis Kletnieks <Valdis.Kletnieks@vt.edu>, and a fix for a missing menu in the auto theme discovered by someone on IRC. I've also added quite a few comments to term.c to help people grok the parsing of escape sequences a little better. SVN revision: 2168
This commit is contained in:
parent
d2ca8950e1
commit
8e9f100232
18
ChangeLog
18
ChangeLog
|
@ -3242,3 +3242,21 @@ Fri Feb 18 21:09:29 PST 2000 Michael Jennings <mej@eterm.org>
|
|||
functions to do it. :-)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Wed Mar 1 18:37:18 PST 2000 Michael Jennings <mej@eterm.org>
|
||||
|
||||
I'm still not done with the commenting work I've been doing, but I've
|
||||
made some fixes, so I figured it was time to commit what I've done so
|
||||
far.
|
||||
|
||||
I've added support for multi-byte selection/pastes from programs like
|
||||
Netscape, thanks in part to a patch from Yasuyuki Furukawa
|
||||
<yasu@on.cs.keio.ac.jp>. I've also applied a bugfix for pty
|
||||
allocation on Irix from David Kaelbling <drk@sgi.com>, a display
|
||||
bugfix pointed out by Valdis Kletnieks <Valdis.Kletnieks@vt.edu>, and
|
||||
a fix for a missing menu in the auto theme discovered by someone on
|
||||
IRC.
|
||||
|
||||
I've also added quite a few comments to term.c to help people grok
|
||||
the parsing of escape sequences a little better.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
|
|
@ -144,7 +144,7 @@ AC_TYPE_UID_T
|
|||
|
||||
dnl# Checks for library functions.
|
||||
AC_TYPE_SIGNAL
|
||||
AC_CHECK_FUNCS(atexit _exit unsetenv setutent seteuid memmove putenv strsep setresuid setresgid memmem usleep snprintf)
|
||||
AC_CHECK_FUNCS(atexit _exit unsetenv setutent seteuid memmove putenv strsep setresuid setresgid memmem usleep snprintf X11/Xmu/Atoms.h)
|
||||
dps_snprintf_oflow()
|
||||
|
||||
dnl# Check for the need for -lutil on BSD systems
|
||||
|
@ -586,7 +586,12 @@ echo " the --x-libraries parameter to configure.";
|
|||
AC_CHECK_LIB(Xext, XShapeQueryExtension, AC_DEFINE(HAVE_X_SHAPE_EXT), , $X_LIBS $SUBLIBS)
|
||||
|
||||
# check if we need X_LOCALE definition
|
||||
AC_CHECK_LIB(X11, _Xsetlocale, , AC_DEFINE(NO_XLOCALE), , $X_LIBS $SUBLIBS)
|
||||
AC_CHECK_LIB(X11, _Xsetlocale, , AC_DEFINE(NO_XLOCALE), $X_LIBS $SUBLIBS)
|
||||
|
||||
# For multibyte selection handling
|
||||
if test "$MULTICHAR_ENCODING" != "none"; then
|
||||
AC_CHECK_LIB(Xmu, XmuInternAtom, X_LIBS="-lXmu $X_LIBS", , $X_LIBS $SUBLIBS)
|
||||
fi
|
||||
|
||||
# check X11R6 for XIM
|
||||
if test "$XIM" = "TRUE"; then
|
||||
|
|
|
@ -1134,10 +1134,11 @@ __inline__ int sgi_get_pty(void);
|
|||
__inline__ int
|
||||
sgi_get_pty(void)
|
||||
{
|
||||
|
||||
int fd = -1;
|
||||
|
||||
privileges(INVOKE);
|
||||
ptydev = ttydev = _getpty(&fd, O_RDWR | O_NDELAY, 0620, 0);
|
||||
privileges(REVERT);
|
||||
return (ptydev == NULL ? -1 : fd);
|
||||
|
||||
}
|
||||
|
@ -2503,6 +2504,13 @@ cmd_getc(void)
|
|||
return (0);
|
||||
}
|
||||
|
||||
/* Put a character back in the buffer. Only use this once at a time. */
|
||||
void
|
||||
cmd_ungetc(void)
|
||||
{
|
||||
cmdbuf_ptr--;
|
||||
}
|
||||
|
||||
/* tt_write(), tt_printf() - output to command */
|
||||
/*
|
||||
* Send count characters directly to the command
|
||||
|
|
|
@ -266,9 +266,9 @@ if (test) PrivateModes |= (bit); else PrivateModes &= ~(bit);} while (0)
|
|||
# define SIG_RETURN(x) return
|
||||
#endif
|
||||
|
||||
#define CHARS_READ() (cmdbuf_ptr < cmdbuf_endp)
|
||||
#define CHARS_BUFFERED() (count != CMD_BUF_SIZE)
|
||||
#define RETURN_CHAR() do { refreshed = 0; return (*cmdbuf_ptr++); } while (0)
|
||||
#define CHARS_READ() (cmdbuf_ptr < cmdbuf_endp)
|
||||
#define CHARS_BUFFERED() (count != CMD_BUF_SIZE)
|
||||
#define RETURN_CHAR() do { refreshed = 0; return (*cmdbuf_ptr++); } while (0)
|
||||
|
||||
#ifdef REFRESH_DELAY
|
||||
# define REFRESH_DELAY_USEC (1000000/25)
|
||||
|
@ -364,6 +364,7 @@ extern unsigned int cmd_write(const unsigned char *, unsigned int);
|
|||
extern RETSIGTYPE check_pixmap_change(int);
|
||||
#endif
|
||||
extern unsigned char cmd_getc(void);
|
||||
extern void cmd_ungetc(void);
|
||||
extern void tt_write(const unsigned char *, unsigned int);
|
||||
extern void tt_printf(const unsigned char *, ...);
|
||||
extern void main_loop(void);
|
||||
|
|
|
@ -3568,7 +3568,6 @@ init_defaults(void)
|
|||
rs_name = StrDup(APL_NAME " " VERSION);
|
||||
Options = (Opt_scrollbar | Opt_select_trailing_spaces);
|
||||
Xdisplay = NULL;
|
||||
display_name = NULL;
|
||||
rs_term_name = NULL;
|
||||
#ifdef CUTCHAR_OPTION
|
||||
rs_cutchars = NULL;
|
||||
|
@ -3650,11 +3649,11 @@ post_parse(void)
|
|||
|
||||
#ifdef PRINTPIPE
|
||||
if (!rs_print_pipe)
|
||||
rs_print_pipe = PRINTPIPE;
|
||||
rs_print_pipe = StrDup(PRINTPIPE);
|
||||
#endif
|
||||
#ifdef CUTCHAR_OPTION
|
||||
if (!rs_cutchars)
|
||||
rs_cutchars = CUTCHARS;
|
||||
rs_cutchars = StrDup(CUTCHARS);
|
||||
#endif
|
||||
|
||||
#ifndef NO_BOLDFONT
|
||||
|
|
52
src/screen.c
52
src/screen.c
|
@ -24,6 +24,9 @@ static const char cvs_ident[] = "$Id$";
|
|||
#include <errno.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xmd.h> /* CARD32 */
|
||||
#ifdef HAVE_X11_XMU_ATOMS_H
|
||||
# include <X11/Xmu/Atoms.h>
|
||||
#endif
|
||||
|
||||
#include "../libmej/debug.h"
|
||||
#include "../libmej/mem.h"
|
||||
|
@ -2383,15 +2386,30 @@ selection_paste(Window win, unsigned prop, int Delete)
|
|||
if (prop == None)
|
||||
return;
|
||||
for (nread = 0, bytes_after = 1; bytes_after > 0;) {
|
||||
if ((XGetWindowProperty(Xdisplay, win, prop, (nread / 4), PROP_SIZE,
|
||||
Delete, AnyPropertyType, &actual_type, &actual_fmt,
|
||||
&nitems, &bytes_after, &data) != Success)) {
|
||||
if ((XGetWindowProperty(Xdisplay, win, prop, (nread / 4), PROP_SIZE, Delete, AnyPropertyType, &actual_type, &actual_fmt, &nitems, &bytes_after, &data) != Success)) {
|
||||
XFree(data);
|
||||
return;
|
||||
}
|
||||
nread += nitems;
|
||||
|
||||
PasteIt(data, nitems);
|
||||
if (actual_type == XA_STRING) {
|
||||
PasteIt(data, nitems);
|
||||
} else {
|
||||
int size, i, ret;
|
||||
XTextProperty xtextp;
|
||||
char **cl;
|
||||
|
||||
xtextp.value = data;
|
||||
xtextp.encoding = actual_type;
|
||||
xtextp.format = actual_fmt;
|
||||
xtextp.nitems = nitems;
|
||||
XmbTextPropertyToTextList(Xdisplay, &xtextp, &cl, &size);
|
||||
|
||||
for (i = 0 ; i < size ; i ++) {
|
||||
PasteIt(cl[i], strlen(cl[i]));
|
||||
}
|
||||
XFreeStringList(cl);
|
||||
}
|
||||
XFree(data);
|
||||
}
|
||||
}
|
||||
|
@ -2415,8 +2433,11 @@ selection_request(Time tm, int x, int y)
|
|||
selection_paste(Xroot, XA_CUT_BUFFER0, False);
|
||||
} else {
|
||||
prop = XInternAtom(Xdisplay, "VT_SELECTION", False);
|
||||
XConvertSelection(Xdisplay, XA_PRIMARY, XA_STRING, prop, TermWin.vt,
|
||||
tm);
|
||||
#ifdef MULTI_CHARSET
|
||||
XConvertSelection(Xdisplay, XA_PRIMARY, XA_COMPOUND_TEXT(Xdisplay), prop, TermWin.vt, tm);
|
||||
#else
|
||||
XConvertSelection(Xdisplay, XA_PRIMARY, XA_STRING, prop, TermWin.vt, tm);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3194,10 +3215,25 @@ selection_send(XSelectionRequestEvent * rq)
|
|||
(unsigned char *) target_list,
|
||||
(sizeof(target_list) / sizeof(target_list[0])));
|
||||
ev.xselection.property = rq->property;
|
||||
#ifdef MULTI_CHARSET
|
||||
} else if (rq->target == XA_STRING || rq->target == XA_TEXT(Xdisplay) || rq->target == XA_COMPOUND_TEXT(Xdisplay)) {
|
||||
XTextProperty xtextp;
|
||||
char *l[1];
|
||||
|
||||
*l = selection.text;
|
||||
xtextp.value = NULL;
|
||||
xtextp.nitems = 0;
|
||||
if (XmbTextListToTextProperty(Xdisplay, l, 1, XCompoundTextStyle, &xtextp) == Success) {
|
||||
if (xtextp.nitems > 0 && xtextp.value != NULL) {
|
||||
XChangeProperty(Xdisplay, rq->requestor, rq->property, XA_COMPOUND_TEXT(Xdisplay), 8, PropModeReplace, xtextp.value, xtextp.nitems);
|
||||
ev.xselection.property = rq->property;
|
||||
}
|
||||
}
|
||||
#else
|
||||
} else if (rq->target == XA_STRING) {
|
||||
XChangeProperty(Xdisplay, rq->requestor, rq->property, rq->target,
|
||||
8, PropModeReplace, selection.text, selection.len);
|
||||
XChangeProperty(Xdisplay, rq->requestor, rq->property, rq->target, 8, PropModeReplace, selection.text, selection.len);
|
||||
ev.xselection.property = rq->property;
|
||||
#endif
|
||||
}
|
||||
XSendEvent(Xdisplay, rq->requestor, False, 0, &ev);
|
||||
}
|
||||
|
|
184
src/term.c
184
src/term.c
|
@ -97,6 +97,13 @@ Pixel PixColors[NRS_COLORS + NSHADOWCOLORS];
|
|||
unsigned int MetaMask = 0, AltMask = 0, NumLockMask = 0;
|
||||
unsigned int modmasks[] = { Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask };
|
||||
|
||||
/* This function queries X to see which modifier keys (specifically Alt, Meta, and NumLock,
|
||||
since that's really all we care about) are bound to the 5 modifier masks. It then sets
|
||||
the variables MetaMask, AltMask, and NumLockMask to the appropriate modifier mask (e.g.,
|
||||
Mod1Mask). That way, we can use MetaMask in lookup_key() instead of using a specific
|
||||
ModMask. This function also handles fallbacks, so that if there is no Meta key, the Alt
|
||||
key will be used as Meta, and vice versa. get_modifiers() is called once on startup and
|
||||
after each MappingNotify event. */
|
||||
void
|
||||
get_modifiers(void)
|
||||
{
|
||||
|
@ -107,6 +114,8 @@ get_modifiers(void)
|
|||
|
||||
modmap = XGetModifierMapping(Xdisplay);
|
||||
kc = modmap->modifiermap;
|
||||
|
||||
/* For each of the 5 modifier masks... */
|
||||
for (i = Mod5MapIndex; i >= Mod1MapIndex; i--) {
|
||||
unsigned short j;
|
||||
register unsigned short k, l;
|
||||
|
@ -114,12 +123,14 @@ get_modifiers(void)
|
|||
k = i * modmap->max_keypermod;
|
||||
l = i - Mod1MapIndex;
|
||||
|
||||
/* Find each key bound to it... */
|
||||
for (j = 0; j < modmap->max_keypermod; j++, k++) {
|
||||
unsigned char match = 0;
|
||||
|
||||
if (kc[k] == 0) {
|
||||
break;
|
||||
}
|
||||
/* Check to see if it's one that we care about. */
|
||||
switch (XKeycodeToKeysym(Xdisplay, kc[k], 0)) {
|
||||
case XK_Meta_L:
|
||||
case XK_Meta_R:
|
||||
|
@ -144,6 +155,7 @@ get_modifiers(void)
|
|||
}
|
||||
}
|
||||
XFreeModifiermap(modmap);
|
||||
/* Fallbacks. */
|
||||
if (MetaMask == 0) {
|
||||
if (AltMask != 0) {
|
||||
D_X11(("Defaulted Meta key to match Alt mask\n"));
|
||||
|
@ -165,7 +177,14 @@ get_modifiers(void)
|
|||
#else
|
||||
# define LK_RET() return
|
||||
#endif
|
||||
/* Convert the keypress event into a string */
|
||||
|
||||
/* This function is called for every keypress event we receive. Its job is to convert
|
||||
the keypress into its corresponding action. It is responsible for calling the action
|
||||
bindings routine to see if there is an action binding for that keysym; if there is,
|
||||
this routine will exit. If not, it continues. It then uses the keysym to determine
|
||||
the action or escape sequence which should result from the keypress. Actions are
|
||||
performed and the event discarded. Escape sequences are generated and sent to the
|
||||
child process. */
|
||||
void
|
||||
lookup_key(XEvent * ev)
|
||||
{
|
||||
|
@ -185,15 +204,13 @@ lookup_key(XEvent * ev)
|
|||
static short greek_mode = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
/* Quick boolean variables tell us which modifier keys were pressed. */
|
||||
shft = (ev->xkey.state & ShiftMask);
|
||||
ctrl = (ev->xkey.state & ControlMask);
|
||||
meta = (ev->xkey.state & MetaMask);
|
||||
|
||||
/* The num lock key toggles application keypad
|
||||
mode. Num lock on, app. keypad mode off. */
|
||||
if (numlock_state || (ev->xkey.state & NumLockMask)) {
|
||||
numlock_state = (ev->xkey.state & NumLockMask);
|
||||
PrivMode((!numlock_state), PrivMode_aplKP);
|
||||
|
@ -203,8 +220,9 @@ lookup_key(XEvent * ev)
|
|||
Status status_return;
|
||||
|
||||
kbuf[0] = '\0';
|
||||
len = XmbLookupString(xim_input_context, &ev->xkey, (char *) kbuf,
|
||||
sizeof(short_buf), &keysym, &status_return);
|
||||
/* Lookup the string equivalent in terms of the XIM input context. */
|
||||
len = XmbLookupString(xim_input_context, &ev->xkey, (char *) kbuf, sizeof(short_buf), &keysym, &status_return);
|
||||
/* Whoops, it's too long. Allocate a new buffer and repeat the call. */
|
||||
if (status_return == XBufferOverflow) {
|
||||
kbuf = (unsigned char *) MALLOC(len + 1);
|
||||
kbuf_alloced = 1;
|
||||
|
@ -212,16 +230,15 @@ lookup_key(XEvent * ev)
|
|||
}
|
||||
valid_keysym = (status_return == XLookupKeySym) || (status_return == XLookupBoth);
|
||||
} else {
|
||||
/* No XIM input context. Do it the normal way. */
|
||||
len = XLookupString(&ev->xkey, (char *) kbuf, sizeof(short_buf), &keysym, NULL);
|
||||
valid_keysym = 1;
|
||||
}
|
||||
#else /* USE_XIM */
|
||||
/* Translate the key event into its corresponding string according to X. This also gets us a keysym. */
|
||||
len = XLookupString(&ev->xkey, (char *) kbuf, sizeof(kbuf), &keysym, NULL);
|
||||
|
||||
/*
|
||||
* have unmapped Latin[2-4] entries -> Latin1
|
||||
* good for installations with correct fonts, but without XLOCALE
|
||||
*/
|
||||
/* If there is no string and it's a Latin2-4 character, replace it with the Latin1 character instead. */
|
||||
if (!len && (keysym >= 0x0100) && (keysym < 0x0400)) {
|
||||
len = 1;
|
||||
kbuf[0] = (keysym & 0xff);
|
||||
|
@ -229,23 +246,28 @@ lookup_key(XEvent * ev)
|
|||
#endif /* USE_XIM */
|
||||
|
||||
#ifdef USE_XIM
|
||||
/* Don't do anything without a valid keysym. */
|
||||
if (valid_keysym) {
|
||||
#endif
|
||||
|
||||
/* Check for a corresponding action binding. If there is one, we're done with this event. */
|
||||
if (action_dispatch(ev, keysym)) {
|
||||
LK_RET();
|
||||
}
|
||||
/* If we're in pause mode, exit. */
|
||||
if (len && keypress_exit) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* This is a special mode that reports all extended keysyms (above 0xff00) to the application
|
||||
as escape sequences. Very few applications use it, but it can be a handy thing to have. */
|
||||
if ((Options & Opt_report_as_keysyms) && (keysym >= 0xff00)) {
|
||||
len = sprintf((char *) kbuf, "\033[k%X;%X~", (unsigned int) (ev->xkey.state & 0xff), (unsigned int) (keysym & 0xff));
|
||||
tt_write(kbuf, len);
|
||||
LK_RET();
|
||||
}
|
||||
#ifdef HOTKEY
|
||||
/* for some backwards compatibility */
|
||||
/* Ctrl-> and Ctrl-< should change font sizes. (Meta if HOTKEY has been changed to Meta.) */
|
||||
if (HOTKEY) {
|
||||
if (keysym == ks_bigfont) {
|
||||
change_font(0, BIGGER_FONT);
|
||||
|
@ -261,7 +283,7 @@ lookup_key(XEvent * ev)
|
|||
/* Shift + F1 - F10 generates F11 - F20 */
|
||||
if (keysym >= XK_F1 && keysym <= XK_F10) {
|
||||
keysym += (XK_F11 - XK_F1);
|
||||
shft = 0; /* turn off Shift */
|
||||
shft = 0;
|
||||
} else if (!ctrl && !meta && (PrivateModes & PrivMode_ShiftKeys)) {
|
||||
|
||||
int lnsppg; /* Lines per page to scroll */
|
||||
|
@ -273,32 +295,31 @@ lookup_key(XEvent * ev)
|
|||
#endif
|
||||
|
||||
switch (keysym) {
|
||||
/* normal XTerm key bindings */
|
||||
case XK_Prior: /* Shift+Prior = scroll back */
|
||||
case XK_Prior: /* Shift-PgUp scrolls up a page */
|
||||
if (TermWin.saveLines) {
|
||||
scr_page(UP, lnsppg);
|
||||
LK_RET();
|
||||
}
|
||||
break;
|
||||
|
||||
case XK_Next: /* Shift+Next = scroll forward */
|
||||
case XK_Next: /* Shift-PgDn scrolls down a page */
|
||||
if (TermWin.saveLines) {
|
||||
scr_page(DN, lnsppg);
|
||||
LK_RET();
|
||||
}
|
||||
break;
|
||||
|
||||
case XK_Insert: /* Shift+Insert = paste mouse selection */
|
||||
case XK_Insert: /* Shift-Ins pastes the current selection. */
|
||||
selection_request(ev->xkey.time, ev->xkey.x, ev->xkey.y);
|
||||
LK_RET();
|
||||
break;
|
||||
|
||||
case XK_KP_Add: /* Shift+KP_Add = bigger font */
|
||||
case XK_KP_Add: /* Shift-Plus on the keypad increases the font size */
|
||||
change_font(0, BIGGER_FONT);
|
||||
LK_RET();
|
||||
break;
|
||||
|
||||
case XK_KP_Subtract: /* Shift+KP_Subtract = smaller font */
|
||||
case XK_KP_Subtract: /* Shift-Minus on the keypad decreases the font size */
|
||||
change_font(0, SMALLER_FONT);
|
||||
LK_RET();
|
||||
break;
|
||||
|
@ -306,6 +327,7 @@ lookup_key(XEvent * ev)
|
|||
}
|
||||
}
|
||||
#ifdef UNSHIFTED_SCROLLKEYS
|
||||
/* Allow PgUp/PgDn by themselves to scroll. Not recommended. */
|
||||
else if (!ctrl && !meta) {
|
||||
switch (keysym) {
|
||||
case XK_Prior:
|
||||
|
@ -326,7 +348,7 @@ lookup_key(XEvent * ev)
|
|||
#endif
|
||||
|
||||
switch (keysym) {
|
||||
case XK_Print:
|
||||
case XK_Print: /* Print the screen contents out to the print pipe */
|
||||
#if DEBUG >= DEBUG_SELECTION
|
||||
if (debug_level >= DEBUG_SELECTION) {
|
||||
debug_selection();
|
||||
|
@ -356,14 +378,16 @@ lookup_key(XEvent * ev)
|
|||
TermWin.view_start = 0;
|
||||
}
|
||||
|
||||
if (keysym >= 0xFF00 && keysym <= 0xFFFF) {
|
||||
/* Process extended keysyms. This is where the conversion to escape sequences happens. */
|
||||
if (keysym >= 0xff00 && keysym <= 0xffff) {
|
||||
#ifdef KEYSYM_ATTRIBUTE
|
||||
if (!(shft | ctrl) && KeySym_map[keysym - 0xFF00] != NULL) {
|
||||
/* The "keysym" attribute in the config file gets handled here. */
|
||||
if (!(shft | ctrl) && KeySym_map[keysym - 0xff00] != NULL) {
|
||||
|
||||
const unsigned char *tmpbuf;
|
||||
unsigned int len;
|
||||
|
||||
tmpbuf = (KeySym_map[keysym - 0xFF00]);
|
||||
tmpbuf = (KeySym_map[keysym - 0xff00]);
|
||||
len = *tmpbuf++;
|
||||
|
||||
/* escape prefix */
|
||||
|
@ -380,6 +404,7 @@ lookup_key(XEvent * ev)
|
|||
LK_RET();
|
||||
} else
|
||||
#endif
|
||||
/* This is a big-ass switch statement that handles all the special keysyms */
|
||||
switch (keysym) {
|
||||
case XK_BackSpace:
|
||||
len = 1;
|
||||
|
@ -392,6 +417,7 @@ lookup_key(XEvent * ev)
|
|||
#endif
|
||||
break;
|
||||
|
||||
/* Tab key is normal unless it's shift-tab. */
|
||||
case XK_Tab:
|
||||
if (shft) {
|
||||
len = 3;
|
||||
|
@ -415,20 +441,19 @@ lookup_key(XEvent * ev)
|
|||
break;
|
||||
|
||||
#ifdef XK_KP_Left
|
||||
case XK_KP_Left: /* \033Ot or standard */
|
||||
case XK_KP_Up: /* \033Ox or standard */
|
||||
case XK_KP_Right: /* \033Ov or standard */
|
||||
case XK_KP_Down: /* \033Ow or standard */
|
||||
case XK_KP_Left: /* \033Ot or standard cursor key */
|
||||
case XK_KP_Up: /* \033Ox or standard cursor key */
|
||||
case XK_KP_Right: /* \033Ov or standard cursor key */
|
||||
case XK_KP_Down: /* \033Or or standard cursor key */
|
||||
if ((PrivateModes & PrivMode_aplKP) ? !shft : shft) {
|
||||
len = 3;
|
||||
strcpy(kbuf, "\033OZ");
|
||||
strcpy(kbuf, "\033OZ"); /* The Z is replaced by t, x, v, or r */
|
||||
kbuf[2] = ("txvr"[keysym - XK_KP_Left]);
|
||||
break;
|
||||
} else {
|
||||
/* translate to std. cursor key */
|
||||
keysym = XK_Left + (keysym - XK_KP_Left);
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
/* Continue on with the normal cursor keys... */
|
||||
#endif
|
||||
case XK_Left: /* "\033[D" */
|
||||
case XK_Up: /* "\033[A" */
|
||||
|
@ -446,6 +471,8 @@ lookup_key(XEvent * ev)
|
|||
kbuf[2] = ("dacb"[keysym - XK_Left]);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Keypad and normal PgUp/PgDn */
|
||||
#ifndef UNSHIFTED_SCROLLKEYS
|
||||
# ifdef XK_KP_Prior
|
||||
case XK_KP_Prior:
|
||||
|
@ -476,6 +503,8 @@ lookup_key(XEvent * ev)
|
|||
strcpy(kbuf, "\033[6~");
|
||||
break;
|
||||
#endif /* UNSHIFTED_SCROLLKEYS */
|
||||
|
||||
/* End key */
|
||||
#ifdef XK_KP_End
|
||||
case XK_KP_End:
|
||||
/* allow shift to override */
|
||||
|
@ -495,8 +524,8 @@ lookup_key(XEvent * ev)
|
|||
strcpy(kbuf, "\033[4~");
|
||||
break;
|
||||
|
||||
#ifdef DXK_Remove /* support for DEC remove like key */
|
||||
case DXK_Remove: /* drop */
|
||||
#ifdef DXK_Remove
|
||||
case DXK_Remove:
|
||||
#endif
|
||||
case XK_Execute:
|
||||
len = 4;
|
||||
|
@ -684,6 +713,7 @@ sprintf((char *) kbuf,"\033[%02d~", (int)((n) + (keysym - fkey))); \
|
|||
}
|
||||
#endif
|
||||
|
||||
/* All processed. If there's still no string, we're done. */
|
||||
if (len <= 0) {
|
||||
LK_RET();
|
||||
}
|
||||
|
@ -724,23 +754,29 @@ sprintf((char *) kbuf,"\033[%02d~", (int)((n) + (keysym - fkey))); \
|
|||
fprintf(stderr, "'\n");
|
||||
}
|
||||
#endif /* DEBUG_CMD */
|
||||
tt_write(kbuf, len);
|
||||
tt_write(kbuf, len); /* Send the resulting string to the child process */
|
||||
|
||||
LK_RET();
|
||||
}
|
||||
|
||||
/* print pipe */
|
||||
#ifdef PRINTPIPE
|
||||
/* Open the print pipe. */
|
||||
FILE *
|
||||
popen_printer(void)
|
||||
{
|
||||
FILE *stream = (FILE *) popen(rs_print_pipe, "w");
|
||||
FILE *stream;
|
||||
|
||||
if (stream == NULL)
|
||||
print_error("can't open printer pipe \"%s\" -- %s", rs_print_pipe, strerror(errno));
|
||||
if (((my_ruid != my_euid) || (my_rgid != my_egid)) && (strcmp(rs_print_pipe, PRINTPIPE))) {
|
||||
print_warning("Running setuid/setgid. Refusing to use custom printpipe.");
|
||||
RESET_AND_ASSIGN(rs_print_pipe, StrDup(PRINTPIPE));
|
||||
}
|
||||
if ((stream = (FILE *) popen(rs_print_pipe, "w")) == NULL) {
|
||||
print_error("Can't open printer pipe \"%s\" -- %s", rs_print_pipe, strerror(errno));
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
/* Close the print pipe. */
|
||||
int
|
||||
pclose_printer(FILE * stream)
|
||||
{
|
||||
|
@ -748,7 +784,7 @@ pclose_printer(FILE * stream)
|
|||
return pclose(stream);
|
||||
}
|
||||
|
||||
/* simulate attached vt100 printer */
|
||||
/* Print everything until we hit a \e[4i sequence. */
|
||||
void
|
||||
process_print_pipe(void)
|
||||
{
|
||||
|
@ -775,14 +811,18 @@ process_print_pipe(void)
|
|||
}
|
||||
#endif /* PRINTPIPE */
|
||||
|
||||
/* process escape sequences */
|
||||
/* This routine processes escape sequences; i.e., when a \033 character is encountered in the
|
||||
input stream, this function is called to process it. First, we get the next character off
|
||||
the input stream (the one after the ESC) and store it in ch. Then we proceed based on what
|
||||
ch is. Some escape sequences are only ESC followed by a single character, so the
|
||||
processing of those ends here. Others are longer and get passed on to other functions from
|
||||
this one. */
|
||||
void
|
||||
process_escape_seq(void)
|
||||
{
|
||||
unsigned char ch = cmd_getc();
|
||||
|
||||
switch (ch) {
|
||||
/* case 1: do_tek_mode (); break; */
|
||||
case '#':
|
||||
if (cmd_getc() == '8')
|
||||
scr_E();
|
||||
|
@ -838,11 +878,9 @@ process_escape_seq(void)
|
|||
case 'M':
|
||||
scr_index(DN);
|
||||
break;
|
||||
/*case 'N': scr_single_shift (2); break; */
|
||||
/*case 'O': scr_single_shift (3); break; */
|
||||
case 'Z':
|
||||
tt_printf((unsigned char *) ESCZ_ANSWER);
|
||||
break; /* steal obsolete ESC [ c */
|
||||
break;
|
||||
case '[':
|
||||
process_csi_seq();
|
||||
break;
|
||||
|
@ -861,7 +899,10 @@ process_escape_seq(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* process CSI (code sequence introducer) sequences `ESC[' */
|
||||
/* This function handles Code Sequence Introducer (CSI) escape sequences. At this point,
|
||||
we've read "\e[" from the input stream. CSI sequences take an arbitrary number of
|
||||
parameters and are used almost exclusively for terminal window navigation and
|
||||
manipulation. */
|
||||
void
|
||||
process_csi_seq(void)
|
||||
{
|
||||
|
@ -875,12 +916,12 @@ process_csi_seq(void)
|
|||
arg[1] = 0;
|
||||
|
||||
priv = 0;
|
||||
ch = cmd_getc();
|
||||
ch = cmd_getc(); /* Get the next character */
|
||||
if (ch >= '<' && ch <= '?') {
|
||||
priv = ch;
|
||||
priv = ch; /* DEC private mode sequence. Get next character. */
|
||||
ch = cmd_getc();
|
||||
}
|
||||
/* read any numerical arguments */
|
||||
/* Read semicolon-delimited numerical arguments, if any. */
|
||||
do {
|
||||
int n;
|
||||
|
||||
|
@ -892,64 +933,63 @@ process_csi_seq(void)
|
|||
if (ch == '\b') {
|
||||
scr_backspace();
|
||||
} else if (ch == 033) {
|
||||
process_escape_seq();
|
||||
cmd_ungetc(); /* New escape sequence starting in the middle of one. Punt. */
|
||||
return;
|
||||
} else if (ch < ' ') {
|
||||
scr_add_lines(&ch, 0, 1);
|
||||
scr_add_lines(&ch, 0, 1); /* Insert verbatim non-printable character (NPC) */
|
||||
return;
|
||||
}
|
||||
if (ch < '@')
|
||||
ch = cmd_getc();
|
||||
}
|
||||
while (ch >= ' ' && ch < '@');
|
||||
ch = cmd_getc(); /* Separator. Go to next digit or operation. */
|
||||
} while (ch >= ' ' && ch < '@');
|
||||
if (ch == 033) {
|
||||
process_escape_seq();
|
||||
cmd_ungetc();
|
||||
return;
|
||||
} else if (ch < ' ')
|
||||
return;
|
||||
return; /* An NPC. Punt. */
|
||||
|
||||
switch (ch) {
|
||||
#ifdef PRINTPIPE
|
||||
case 'i': /* printing */
|
||||
case 'i':
|
||||
switch (arg[0]) {
|
||||
case 0:
|
||||
scr_printscreen(0);
|
||||
scr_printscreen(0); /* Print screen "\e[0i" */
|
||||
break;
|
||||
case 5:
|
||||
process_print_pipe();
|
||||
process_print_pipe(); /* Start printing to print pipe "\e[5i" */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 'A':
|
||||
case 'e': /* up <n> */
|
||||
case 'e': /* Cursor up n lines "\e[<n>A" */
|
||||
scr_gotorc((arg[0] ? -arg[0] : -1), 0, RELATIVE);
|
||||
break;
|
||||
case 'B': /* down <n> */
|
||||
case 'B': /* Cursor down n lines "\e[<n>B" */
|
||||
scr_gotorc((arg[0] ? +arg[0] : +1), 0, RELATIVE);
|
||||
break;
|
||||
case 'C':
|
||||
case 'a': /* right <n> */
|
||||
case 'a': /* Cursor right n columns "\e[<n>C" */
|
||||
scr_gotorc(0, (arg[0] ? +arg[0] : +1), RELATIVE);
|
||||
break;
|
||||
case 'D': /* left <n> */
|
||||
case 'D': /* Cursor left n columns "\e[<n>D" */
|
||||
scr_gotorc(0, (arg[0] ? -arg[0] : -1), RELATIVE);
|
||||
break;
|
||||
case 'E': /* down <n> & to first column */
|
||||
case 'E': /* Cursor down n lines and to first column "\e[<n>E" */
|
||||
scr_gotorc((arg[0] ? +arg[0] : +1), 0, R_RELATIVE);
|
||||
break;
|
||||
case 'F': /* up <n> & to first column */
|
||||
case 'F': /* Cursor up n lines and to first column "\e[<n>F" */
|
||||
scr_gotorc((arg[0] ? -arg[0] : -1), 0, R_RELATIVE);
|
||||
break;
|
||||
case 'G':
|
||||
case '`': /* move to col <n> */
|
||||
case '`': /* Cursor to column n "\e[<n>G" */
|
||||
scr_gotorc(0, (arg[0] ? arg[0] - 1 : +1), R_RELATIVE);
|
||||
break;
|
||||
case 'd': /* move to row <n> */
|
||||
case 'd': /* Cursor to row n "\e[<n>d" */
|
||||
scr_gotorc((arg[0] ? arg[0] - 1 : +1), 0, C_RELATIVE);
|
||||
break;
|
||||
case 'H':
|
||||
case 'f': /* position cursor */
|
||||
case 'f': /* Cursor to row r, column c "\e[<r>;<c>H" */
|
||||
switch (nargs) {
|
||||
case 0:
|
||||
scr_gotorc(0, 0, 0);
|
||||
|
@ -962,16 +1002,16 @@ process_csi_seq(void)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 'I':
|
||||
case 'I': /* Tab right n tab stops "\e[<n>I" */
|
||||
scr_tab(arg[0] ? +arg[0] : +1);
|
||||
break;
|
||||
case 'Z':
|
||||
case 'Z': /* Tab left n tab stops "\e[<n>Z" */
|
||||
scr_tab(arg[0] ? -arg[0] : -1);
|
||||
break;
|
||||
case 'J':
|
||||
case 'J': /* Clear part or all of screen, depending on n "\e[<n>J" */
|
||||
scr_erase_screen(arg[0]);
|
||||
break;
|
||||
case 'K':
|
||||
case 'K': /* Clear part or all of line, depending on n "\e[<n>K" */
|
||||
scr_erase_line(arg[0]);
|
||||
break;
|
||||
case '@':
|
||||
|
|
|
@ -230,18 +230,19 @@ remove_utmp_entry(void)
|
|||
if (!ut_id[0])
|
||||
return; /* entry not made */
|
||||
|
||||
privileges(INVOKE);
|
||||
utmpname(UTMP_FILENAME);
|
||||
setutent();
|
||||
if (getutid(&utmp) == NULL)
|
||||
strncpy(utmp.ut_id, ut_id, sizeof(utmp.ut_id));
|
||||
utmp.ut_type = USER_PROCESS;
|
||||
if (getutid(&utmp) == NULL) {
|
||||
return;
|
||||
}
|
||||
utmp.ut_type = DEAD_PROCESS;
|
||||
utmp.ut_time = time(NULL);
|
||||
pututline(&utmp);
|
||||
getutmpx(&utmp, &utmpx);
|
||||
update_wtmp(WTMP_FILENAME, &utmpx);
|
||||
endutent();
|
||||
privileges(REVERT);
|
||||
|
||||
# else /* HAVE_UTMPX_H */
|
||||
struct utmp *putmp;
|
||||
|
@ -250,7 +251,6 @@ remove_utmp_entry(void)
|
|||
if (!ut_id[0])
|
||||
return; /* entry not made */
|
||||
|
||||
privileges(INVOKE);
|
||||
utmpname(UTMP_FILENAME);
|
||||
setutent();
|
||||
/*
|
||||
|
@ -269,7 +269,6 @@ remove_utmp_entry(void)
|
|||
}
|
||||
}
|
||||
endutent();
|
||||
privileges(REVERT);
|
||||
# endif /* HAVE_UTMPX_H */
|
||||
}
|
||||
# endif /* ifndef HAVE_UTEMPTER */
|
||||
|
|
|
@ -866,6 +866,27 @@ begin menu
|
|||
end
|
||||
end
|
||||
|
||||
begin menu
|
||||
title "Eterm Operations"
|
||||
begin menuitem
|
||||
text "Version"
|
||||
action string "\e[8n"
|
||||
end
|
||||
begin menuitem
|
||||
text "Status"
|
||||
action string "\e[9n"
|
||||
end
|
||||
separator
|
||||
begin menuitem
|
||||
text "Save Settings..."
|
||||
action string "\e]6;71\a"
|
||||
end
|
||||
begin menuitem
|
||||
text "Exit"
|
||||
action string "\e]6;70\a"
|
||||
end
|
||||
end
|
||||
|
||||
# This is the menu that gets called by Ctrl-Button3
|
||||
begin menu
|
||||
title Eterm
|
||||
|
|
Loading…
Reference in New Issue