Mon Jun 11 17:49:55 PDT 2001 Michael Jennings <mej@eterm.org>
Okay, first off, I removed 3 scaled backgrounds. See www.kainx.org or my post to enlightenment-devel for details. Second, I redid the default bindings for the mouse wheel. Basically, the wheel alone will scroll by pages. Ctrl+wheel will scroll by pages in groups of 5. Shift+wheel will scroll by a single line. If you hold down the Alt key, the same combinations will work the same way, but instead of scrolling within Eterm, they'll scroll the application in the terminal (by sending PgUp/PgDn and up/down arrows). This works in less, bash, and any other application which groks those keys. I also added a --without-mousewheel option to configure that will turn off the default scrollwheel bindings. Of course, you can always use action bindings in the config file to bind/rebind these any way you like. While I was at it, I found and fixed a bug in the handling of the Alt and Meta keys. I added a scroll() function to the script stuff which allows you to bind keys/buttons to scroll up and down. While I was at it, I added comments to script.c for each function you can use. And finally, the config file parser was moved to libast. SVN revision: 4806
This commit is contained in:
parent
d6cf164837
commit
c3f775c1b5
28
ChangeLog
28
ChangeLog
|
@ -4166,3 +4166,31 @@ Thu May 24 00:14:54 PDT 2001 Michael Jennings <mej@eterm.org>
|
|||
broken in Emacs (*grumble*). Works in gvim though.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Mon Jun 11 17:49:55 PDT 2001 Michael Jennings <mej@eterm.org>
|
||||
|
||||
Okay, first off, I removed 3 scaled backgrounds. See www.kainx.org or
|
||||
my post to enlightenment-devel for details.
|
||||
|
||||
Second, I redid the default bindings for the mouse wheel. Basically,
|
||||
the wheel alone will scroll by pages. Ctrl+wheel will scroll by pages
|
||||
in groups of 5. Shift+wheel will scroll by a single line. If you
|
||||
hold down the Alt key, the same combinations will work the same way,
|
||||
but instead of scrolling within Eterm, they'll scroll the application
|
||||
in the terminal (by sending PgUp/PgDn and up/down arrows). This works
|
||||
in less, bash, and any other application which groks those keys.
|
||||
|
||||
I also added a --without-mousewheel option to configure that will turn
|
||||
off the default scrollwheel bindings. Of course, you can always use
|
||||
action bindings in the config file to bind/rebind these any way you
|
||||
like.
|
||||
|
||||
While I was at it, I found and fixed a bug in the handling of the
|
||||
Alt and Meta keys.
|
||||
|
||||
I added a scroll() function to the script stuff which allows you to
|
||||
bind keys/buttons to scroll up and down. While I was at it, I added
|
||||
comments to script.c for each function you can use.
|
||||
|
||||
And finally, the config file parser was moved to libast.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
|
|
@ -361,6 +361,7 @@
|
|||
#undef UTMP_IDENT
|
||||
#undef WINDOWS_IDENT
|
||||
#undef HAVE_SAVED_UIDS
|
||||
#undef MOUSEWHEEL
|
||||
|
||||
|
||||
/* Leave that blank line there!! Autoheader needs it.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
DIRS = tile scale
|
||||
EXTRA_DIST = tile/014.jpg tile/circuit.jpg tile/giger1.jpg tile/40.jpg tile/blackstone.jpg \
|
||||
tile/nebula.jpg scale/fourthday.jpg scale/gaia.jpg scale/galleon.jpg scale/Dragon.jpg \
|
||||
tile/nebula.jpg scale/Dragon.jpg \
|
||||
README.backgrounds
|
||||
pixmapdir = $(pkgdatadir)/pix
|
||||
themedir = $(pkgdatadir)/themes
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 21 KiB |
Binary file not shown.
Before Width: | Height: | Size: 26 KiB |
Binary file not shown.
Before Width: | Height: | Size: 26 KiB |
11
configure.in
11
configure.in
|
@ -571,6 +571,17 @@ AC_ARG_WITH(end,
|
|||
AC_MSG_RESULT(default vt102)
|
||||
fi, AC_MSG_RESULT(default)
|
||||
)
|
||||
AC_MSG_CHECKING(if mousewheel support should be enabled)
|
||||
AC_ARG_WITH(mousewheel,
|
||||
[ --without-mousewheel disable built-in mousewheel support],
|
||||
if test "$withval" = "no"; then
|
||||
AC_MSG_RESULT(no)
|
||||
else
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(MOUSEWHEEL)
|
||||
fi, AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(MOUSEWHEEL)
|
||||
)
|
||||
MULTICHAR_ENCODING=""
|
||||
AC_MSG_CHECKING(for multi-charset support)
|
||||
AC_ARG_ENABLE(multi-charset,
|
||||
|
|
148
src/actions.c
148
src/actions.c
|
@ -96,72 +96,118 @@ action_find_match(unsigned short mod, unsigned char button, KeySym keysym)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
action_check_button(unsigned char button, int x_button)
|
||||
{
|
||||
/* The event we're looking at is a button press. Make sure the
|
||||
current action is also, and that it matches. Continue if not. */
|
||||
D_ACTIONS(("Checking button %d vs x_button %d\n", button, x_button));
|
||||
if (button == BUTTON_NONE) {
|
||||
/* It was a button press, and this action is not a button action. */
|
||||
return FALSE;
|
||||
}
|
||||
if ((button != BUTTON_ANY) && (button != x_button)) {
|
||||
/* It's a specific button, and the two don't match. */
|
||||
return FALSE;
|
||||
}
|
||||
D_ACTIONS(("Button match confirmed.\n"));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
action_check_keysym(KeySym keysym, KeySym x_keysym)
|
||||
{
|
||||
/* The event we're looking at is a key press. Make sure the
|
||||
current action is also, and that it matches. Continue if not. */
|
||||
D_ACTIONS(("Checking keysym 0x%08x vs x_keysym 0x%08x\n", keysym, x_keysym));
|
||||
if (keysym == None) {
|
||||
return FALSE;
|
||||
} else if (keysym != x_keysym) {
|
||||
return FALSE;
|
||||
}
|
||||
D_ACTIONS(("Keysym match confirmed.\n"));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
action_check_modifiers(unsigned short mod, int x_mod)
|
||||
{
|
||||
unsigned int m = (AltMask | MetaMask | NumLockMask);
|
||||
|
||||
/* When we do have to check the modifiers, we do so in this order to eliminate the
|
||||
most popular choices first. If any test fails, we return FALSE. */
|
||||
D_ACTIONS(("Checking modifier set 0x%08x (" MOD_FMT ") vs. X modifier set 0x%08x (" MOD_FMT ")\n",
|
||||
mod, SHOW_MODS(mod), x_mod, SHOW_X_MODS(x_mod)));
|
||||
if (mod != MOD_ANY) {
|
||||
/* LOGICAL_XOR() returns true if either the first parameter or the second parameter
|
||||
is true, but not both...just like XOR. If the mask we're looking for is set in
|
||||
mod but not in x_mod, or set in x_mod but not in mod, we don't have a match. */
|
||||
if (LOGICAL_XOR((mod & MOD_CTRL), (x_mod & ControlMask))) {
|
||||
return FALSE;
|
||||
}
|
||||
if (LOGICAL_XOR((mod & MOD_SHIFT), (x_mod & ShiftMask))) {
|
||||
return FALSE;
|
||||
}
|
||||
if (MetaMask != AltMask) {
|
||||
if (LOGICAL_XOR((mod & MOD_ALT), (x_mod & AltMask))) {
|
||||
return FALSE;
|
||||
}
|
||||
if (LOGICAL_XOR((mod & MOD_META), (x_mod & MetaMask))) {
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
if (LOGICAL_XOR((mod & (MOD_META | MOD_ALT)), (x_mod & (MetaMask | AltMask)))) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if (LOGICAL_XOR((mod & MOD_LOCK), (x_mod & LockMask))) {
|
||||
return FALSE;
|
||||
}
|
||||
/* These tests can't use LOGICAL_XOR because the second test has an additional
|
||||
restriction that the Mod?Mask cannot be set in m; i.e., we want to ignore
|
||||
any Mod?Mask assigned to Alt, Meta, or the NumLock On state. */
|
||||
if (((mod & MOD_MOD1) && !(x_mod & Mod1Mask)) || (!(mod & MOD_MOD1) && (x_mod & Mod1Mask) && !(Mod1Mask & m))) {
|
||||
return FALSE;
|
||||
}
|
||||
if (((mod & MOD_MOD2) && !(x_mod & Mod2Mask)) || (!(mod & MOD_MOD2) && (x_mod & Mod2Mask) && !(Mod2Mask & m))) {
|
||||
return FALSE;
|
||||
}
|
||||
if (((mod & MOD_MOD3) && !(x_mod & Mod3Mask)) || (!(mod & MOD_MOD3) && (x_mod & Mod3Mask) && !(Mod3Mask & m))) {
|
||||
return FALSE;
|
||||
}
|
||||
if (((mod & MOD_MOD4) && !(x_mod & Mod4Mask)) || (!(mod & MOD_MOD4) && (x_mod & Mod4Mask) && !(Mod4Mask & m))) {
|
||||
return FALSE;
|
||||
}
|
||||
if (((mod & MOD_MOD5) && !(x_mod & Mod5Mask)) || (!(mod & MOD_MOD5) && (x_mod & Mod5Mask) && !(Mod5Mask & m))) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
D_ACTIONS(("Modifier match confirmed.\n"));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
action_dispatch(event_t *ev, KeySym keysym)
|
||||
{
|
||||
action_t *action;
|
||||
unsigned int m = (AltMask | MetaMask | NumLockMask);
|
||||
|
||||
ASSERT_RVAL(ev != NULL, 0);
|
||||
ASSERT_RVAL(ev->xany.type == ButtonPress || ev->xany.type == KeyPress, 0);
|
||||
D_ACTIONS(("Event %8p: Button %d, Keysym 0x%08x, Key State 0x%08x\n", ev, ev->xbutton.button, keysym, ev->xkey.state));
|
||||
D_ACTIONS(("Event %8p: Button %d, Keysym 0x%08x, Key State 0x%08x (modifiers " MOD_FMT ")\n",
|
||||
ev, ev->xbutton.button, keysym, ev->xkey.state, SHOW_X_MODS(ev->xkey.state)));
|
||||
for (action = action_list; action; action = action->next) {
|
||||
D_ACTIONS(("Checking action. mod == 0x%08x, button == %d, keysym == 0x%08x\n", action->mod, action->button, action->keysym));
|
||||
/* The very first thing we do is match the event type to the type
|
||||
of the current action. This means that we'll only run through
|
||||
the modifier checks below if we absolutely have to. */
|
||||
if (ev->xany.type == ButtonPress) {
|
||||
/* The event we're looking at is a button press. Make sure the
|
||||
current action is also, and that it matches. Continue if not. */
|
||||
if ((action->button == BUTTON_NONE) || ((action->button != BUTTON_ANY) && (action->button != ev->xbutton.button))) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
/* The event we're looking at is a key press. Make sure the
|
||||
current action is also, and that it matches. Continue if not. */
|
||||
if (!(action->keysym) || (keysym != action->keysym)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
D_ACTIONS(("Button/key passed.\n"));
|
||||
if (action->mod != MOD_ANY) {
|
||||
/* When we do have to check the modifiers, we do so in
|
||||
this order to eliminate the most popular choices first. */
|
||||
if (LOGICAL_XOR((action->mod & MOD_CTRL), (ev->xkey.state & ControlMask))) {
|
||||
continue;
|
||||
}
|
||||
if (LOGICAL_XOR((action->mod & MOD_SHIFT), (ev->xkey.state & ShiftMask))) {
|
||||
continue;
|
||||
}
|
||||
if (LOGICAL_XOR((action->mod & MOD_ALT), (ev->xkey.state & AltMask))) {
|
||||
continue;
|
||||
}
|
||||
if (LOGICAL_XOR((action->mod & MOD_META), (ev->xkey.state & MetaMask))) {
|
||||
continue;
|
||||
}
|
||||
if (LOGICAL_XOR((action->mod & MOD_LOCK), (ev->xkey.state & LockMask))) {
|
||||
continue;
|
||||
}
|
||||
if (((action->mod & MOD_MOD1) && !(ev->xkey.state & Mod1Mask)) || (!(action->mod & MOD_MOD1) && (ev->xkey.state & Mod1Mask) && !(Mod1Mask & m))) {
|
||||
continue;
|
||||
}
|
||||
if (((action->mod & MOD_MOD2) && !(ev->xkey.state & Mod2Mask)) || (!(action->mod & MOD_MOD2) && (ev->xkey.state & Mod2Mask) && !(Mod2Mask & m))) {
|
||||
continue;
|
||||
}
|
||||
if (((action->mod & MOD_MOD3) && !(ev->xkey.state & Mod3Mask)) || (!(action->mod & MOD_MOD3) && (ev->xkey.state & Mod3Mask) && !(Mod3Mask & m))) {
|
||||
continue;
|
||||
}
|
||||
if (((action->mod & MOD_MOD4) && !(ev->xkey.state & Mod4Mask)) || (!(action->mod & MOD_MOD4) && (ev->xkey.state & Mod4Mask) && !(Mod4Mask & m))) {
|
||||
continue;
|
||||
}
|
||||
if (((action->mod & MOD_MOD5) && !(ev->xkey.state & Mod5Mask)) || (!(action->mod & MOD_MOD5) && (ev->xkey.state & Mod5Mask) && !(Mod5Mask & m))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((ev->xany.type == ButtonPress && action_check_button(action->button, ev->xbutton.button))
|
||||
|| (ev->xany.type == KeyPress && action_check_keysym(action->keysym, action->keysym))) {
|
||||
if (action_check_modifiers(action->mod, ev->xkey.state)) {
|
||||
D_ACTIONS(("Match found.\n"));
|
||||
/* If we've passed all the above tests, it's a match. Dispatch the handler. */
|
||||
return ((action->handler)(ev, action));
|
||||
}
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,10 @@ typedef enum {
|
|||
|
||||
#define LOGICAL_XOR(a, b) !(((a) && (b)) || (!(a) && !(b)))
|
||||
|
||||
#define SHOW_MODS(m) ((m & MOD_CTRL) ? 'C' : 'c'), ((m & MOD_SHIFT) ? 'S' : 's'), ((m & MOD_META) ? 'M' : 'm'), ((m & MOD_ALT) ? 'A' : 'a')
|
||||
#define SHOW_X_MODS(m) ((m & ControlMask) ? 'C' : 'c'), ((m & ShiftMask) ? 'S' : 's'), ((m & MetaMask) ? 'M' : 'm'), ((m & AltMask) ? 'A' : 'a')
|
||||
#define MOD_FMT "%c%c%c%c"
|
||||
|
||||
/************ Structures ************/
|
||||
typedef struct action_struct action_t;
|
||||
typedef unsigned char (*action_handler_t) (event_t *, action_t *);
|
||||
|
@ -87,6 +91,9 @@ extern unsigned char action_handle_echo(event_t *ev, action_t *action);
|
|||
extern unsigned char action_handle_script(event_t *ev, action_t *action);
|
||||
extern unsigned char action_handle_menu(event_t *ev, action_t *action);
|
||||
extern action_t *action_find_match(unsigned short mod, unsigned char button, KeySym keysym);
|
||||
extern unsigned char action_check_button(unsigned char button, int x_button);
|
||||
extern unsigned char action_check_keysym(KeySym keysym, KeySym x_keysym);
|
||||
extern unsigned char action_check_modifiers(unsigned short mod, int x_mod);
|
||||
extern unsigned char action_dispatch(event_t *ev, KeySym keysym);
|
||||
extern void action_add(unsigned short mod, unsigned char button, KeySym keysym, action_type_t type, void *param);
|
||||
|
||||
|
|
|
@ -80,7 +80,4 @@
|
|||
|
||||
# define DEBUG_X 9
|
||||
|
||||
# define DEBUG_PARSE 9999
|
||||
# define D_PARSE(x) D_NEVER(x)
|
||||
|
||||
#endif /* _ETERM_DEBUG_H */
|
||||
|
|
57
src/events.c
57
src/events.c
|
@ -640,24 +640,65 @@ handle_button_press(event_t *ev)
|
|||
}
|
||||
button_state.last_button_press = 3;
|
||||
break;
|
||||
#ifdef MOUSEWHEEL
|
||||
/* This section activates the following bindings:
|
||||
*
|
||||
* Mousewheel Up -- Scroll up 1 page
|
||||
* Ctrl + Mousewheel Up -- Scroll up 5 pages
|
||||
* Shift + Mousewheel Up -- Scroll up 1 line
|
||||
* Alt + Mousewheel Up -- Send PgUp to tty
|
||||
* Alt + Ctrl + Mousewheel Up -- Send 5 PgUp's to tty
|
||||
* Alt + Shift + Mousewheel Up -- Send Up Arrow to tty
|
||||
*
|
||||
* Mousewheel Down -- Scroll down 1 page
|
||||
* Ctrl + Mousewheel Down -- Scroll down 5 pages
|
||||
* Shift + Mousewheel Down -- Scroll down 1 line
|
||||
* Alt + Mousewheel Down -- Send PgDn to tty
|
||||
* Alt + Ctrl + Mousewheel Down -- Send 5 PgDn's to tty
|
||||
* Alt + Shift + Mousewheel Down -- Send Down Arrow to tty
|
||||
*
|
||||
* Note that the number of lines which constitute a "page" is equal to the number
|
||||
* of text rows in the terminal window. The context lines are subtracted out *after*
|
||||
* the conversion is done. In other words, scrolling 5 pages means scrolling
|
||||
* (5 * LINES_PER_PAGE) - CONTEXT_LINES
|
||||
* _not_
|
||||
* (LINES_PER_PAGE - CONTEXT_LINES) * 5
|
||||
*
|
||||
* This is also true for the scroll() function in script.c.
|
||||
*/
|
||||
case Button4:
|
||||
if ((button_state.last_button_press == 4) && (ev->xbutton.time - button_state.button_press < MULTICLICK_TIME)) {
|
||||
button_state.clicks++;
|
||||
if (action_check_modifiers(MOD_CTRL, ev->xbutton.state)) {
|
||||
scr_page(UP, (TermWin.nrow * 5) - CONTEXT_LINES);
|
||||
} else if (action_check_modifiers(MOD_SHIFT, ev->xbutton.state)) {
|
||||
scr_page(UP, 1);
|
||||
} else if (action_check_modifiers(MOD_ALT, ev->xbutton.state)) {
|
||||
tt_write("\033[5~", 4);
|
||||
} else if (action_check_modifiers((MOD_ALT | MOD_SHIFT), ev->xbutton.state)) {
|
||||
tt_write("\033[A", 3);
|
||||
} else if (action_check_modifiers((MOD_ALT | MOD_CTRL), ev->xbutton.state)) {
|
||||
tt_write("\033[5~\033[5~\033[5~\033[5~\033[5~", 20);
|
||||
} else {
|
||||
button_state.clicks = 1;
|
||||
scr_page(UP, TermWin.nrow - CONTEXT_LINES);
|
||||
}
|
||||
button_state.last_button_press = 4;
|
||||
scr_page(UP, ((ev->xbutton.state & ShiftMask) ? (1) : (TermWin.nrow - CONTEXT_LINES)) * ((button_state.clicks > 1) ? 3 : 1));
|
||||
break;
|
||||
case Button5:
|
||||
if ((button_state.last_button_press == 5) && (ev->xbutton.time - button_state.button_press < MULTICLICK_TIME)) {
|
||||
button_state.clicks++;
|
||||
if (action_check_modifiers(MOD_CTRL, ev->xbutton.state)) {
|
||||
scr_page(DN, (TermWin.nrow * 5) - CONTEXT_LINES);
|
||||
} else if (action_check_modifiers(MOD_SHIFT, ev->xbutton.state)) {
|
||||
scr_page(DN, 1);
|
||||
} else if (action_check_modifiers(MOD_ALT, ev->xbutton.state)) {
|
||||
tt_write("\033[6~", 4);
|
||||
} else if (action_check_modifiers((MOD_ALT | MOD_SHIFT), ev->xbutton.state)) {
|
||||
tt_write("\033[B", 3);
|
||||
} else if (action_check_modifiers((MOD_ALT | MOD_CTRL), ev->xbutton.state)) {
|
||||
tt_write("\033[6~\033[6~\033[6~\033[6~\033[6~", 20);
|
||||
} else {
|
||||
button_state.clicks = 1;
|
||||
scr_page(DN, TermWin.nrow - CONTEXT_LINES);
|
||||
}
|
||||
button_state.last_button_press = 5;
|
||||
scr_page(DN, ((ev->xbutton.state & ShiftMask) ? (1) : (TermWin.nrow - CONTEXT_LINES)) * ((button_state.clicks > 1) ? 3 : 1));
|
||||
break;
|
||||
#endif
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
|
955
src/options.c
955
src/options.c
File diff suppressed because it is too large
Load Diff
113
src/options.h
113
src/options.h
|
@ -28,21 +28,6 @@
|
|||
#include <X11/Intrinsic.h> /* Xlib, Xutil, Xresource, Xfuncproto */
|
||||
|
||||
/************ Macros and Definitions ************/
|
||||
#if defined(PATH_MAX) && (PATH_MAX < 255)
|
||||
# undef PATH_MAX
|
||||
#endif
|
||||
#ifndef PATH_MAX
|
||||
# define PATH_MAX 255
|
||||
#endif
|
||||
|
||||
#define CONF_BEGIN_CHAR ((char) 1)
|
||||
#define CONF_END_CHAR ((char) 2)
|
||||
|
||||
#define PARSE_TRY_USER_THEME ((unsigned char) 0x01)
|
||||
#define PARSE_TRY_DEFAULT_THEME ((unsigned char) 0x02)
|
||||
#define PARSE_TRY_NO_THEME ((unsigned char) 0x04)
|
||||
#define PARSE_TRY_ALL ((unsigned char) 0x07)
|
||||
|
||||
#define OPT_BOOLEAN 0x0001
|
||||
#define OPT_INTEGER 0x0002
|
||||
#define OPT_STRING 0x0004
|
||||
|
@ -92,10 +77,10 @@
|
|||
# define SAVE_THEME_CONFIG ((unsigned char) 1)
|
||||
# define SAVE_USER_CONFIG ((unsigned char) 0)
|
||||
|
||||
#define BOOL_OPT_ISTRUE(s) (!strcasecmp((s), true_vals[0]) || !strcasecmp((s), true_vals[1]) \
|
||||
|| !strcasecmp((s), true_vals[2]) || !strcasecmp((s), true_vals[3]))
|
||||
#define BOOL_OPT_ISFALSE(s) (!strcasecmp((s), false_vals[0]) || !strcasecmp((s), false_vals[1]) \
|
||||
|| !strcasecmp((s), false_vals[2]) || !strcasecmp((s), false_vals[3]))
|
||||
#define PARSE_TRY_USER_THEME ((unsigned char) 0x01)
|
||||
#define PARSE_TRY_DEFAULT_THEME ((unsigned char) 0x02)
|
||||
#define PARSE_TRY_NO_THEME ((unsigned char) 0x04)
|
||||
#define PARSE_TRY_ALL ((unsigned char) 0x07)
|
||||
|
||||
/* This defines how many mistakes to allow before giving up
|
||||
and printing the usage -- mej */
|
||||
|
@ -109,54 +94,6 @@
|
|||
} \
|
||||
} while(0)
|
||||
|
||||
/* The context table */
|
||||
#define ctx_name_to_id(the_id, n, i) do { \
|
||||
for ((i)=0; (i) <= ctx_idx; (i)++) { \
|
||||
if (!strcasecmp((n), context[(i)].name)) { \
|
||||
(the_id) = (i); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
if ((i) > ctx_idx) (the_id) = 0; \
|
||||
} while (0)
|
||||
#define ctx_id_to_name(id) (context[(id)].name)
|
||||
#define ctx_id_to_func(id) (context[(id)].handler)
|
||||
|
||||
/* The context state stack. This keeps track of the current context and each previous one. */
|
||||
#define ctx_push(ctx) conf_register_context_state(ctx)
|
||||
#define ctx_pop() (ctx_state_idx--)
|
||||
#define ctx_peek() (ctx_state[ctx_state_idx])
|
||||
#define ctx_peek_id() (ctx_state[ctx_state_idx].ctx_id)
|
||||
#define ctx_peek_state() (ctx_state[ctx_state_idx].state)
|
||||
#define ctx_peek_last_id() (ctx_state[(ctx_state_idx?ctx_state_idx-1:0)].ctx_id)
|
||||
#define ctx_peek_last_state() (ctx_state[(ctx_state_idx?ctx_state_idx-1:0)].state)
|
||||
#define ctx_poke_state(q) ((ctx_state[ctx_state_idx].state) = (q))
|
||||
#define ctx_get_depth() (ctx_state_idx)
|
||||
|
||||
/* The file state stack */
|
||||
#define FILE_SKIP_TO_END (0x01)
|
||||
#define FILE_PREPROC (0x02)
|
||||
#define file_push(f, p, o, l, fl) conf_register_fstate(f, p, o, l, fl)
|
||||
#define file_pop() (fstate_idx--)
|
||||
#define file_peek() (fstate[fstate_idx])
|
||||
#define file_peek_fp() (fstate[fstate_idx].fp)
|
||||
#define file_peek_path() (fstate[fstate_idx].path)
|
||||
#define file_peek_outfile() (fstate[fstate_idx].outfile)
|
||||
#define file_peek_line() (fstate[fstate_idx].line)
|
||||
#define file_peek_skip() (fstate[fstate_idx].flags & FILE_SKIP_TO_END)
|
||||
#define file_peek_preproc() (fstate[fstate_idx].flags & FILE_PREPROC)
|
||||
|
||||
#define file_poke_fp(f) ((fstate[fstate_idx].fp) = (f))
|
||||
#define file_poke_path(p) ((fstate[fstate_idx].path) = (p))
|
||||
#define file_poke_outfile(o) ((fstate[fstate_idx].outfile) = (o))
|
||||
#define file_poke_line(l) ((fstate[fstate_idx].line) = (l))
|
||||
#define file_skip_to_end() ((fstate[fstate_idx].flags) |= (FILE_SKIP_TO_END))
|
||||
#define file_poke_skip(s) do {if (s) {fstate[fstate_idx].flags |= FILE_SKIP_TO_END;} else {fstate[fstate_idx].flags &= ~(FILE_SKIP_TO_END);} } while (0)
|
||||
#define file_poke_preproc(s) do {if (s) {fstate[fstate_idx].flags |= FILE_PREPROC;} else {fstate[fstate_idx].flags &= ~(FILE_PREPROC);} } while (0)
|
||||
#define file_poke(f, p, o, l, fl) do {file_poke_fp(f); file_poke_path(p); file_poke_outfile(o); file_poke_line(l); fstate[fstate_idx].flags = (fl);} while (0)
|
||||
|
||||
#define file_inc_line() (fstate[fstate_idx].line++)
|
||||
|
||||
#define to_keysym(p,s) do { KeySym sym; \
|
||||
if (s && ((sym = XStringToKeysym(s)) != 0)) *p = sym; \
|
||||
} while (0)
|
||||
|
@ -165,40 +102,8 @@
|
|||
#define RESET_AND_ASSIGN(var, val) do {if ((var) != NULL) FREE(var); (var) = (val);} while (0)
|
||||
|
||||
/************ Structures ************/
|
||||
/* Contexts */
|
||||
typedef void * (*ctx_handler_t)(char *, void *);
|
||||
typedef struct context_struct {
|
||||
char *name;
|
||||
ctx_handler_t handler;
|
||||
} ctx_t;
|
||||
typedef struct ctx_state_struct {
|
||||
unsigned char ctx_id;
|
||||
void *state;
|
||||
} ctx_state_t;
|
||||
|
||||
/* Parser states */
|
||||
typedef struct file_state_struct {
|
||||
FILE *fp;
|
||||
char *path, *outfile;
|
||||
unsigned long line;
|
||||
unsigned char flags;
|
||||
} fstate_t;
|
||||
|
||||
/* Built-in functions */
|
||||
typedef char * (*eterm_func_ptr_t) (char *);
|
||||
typedef struct eterm_func_struct {
|
||||
char *name;
|
||||
eterm_func_ptr_t ptr;
|
||||
} eterm_func_t;
|
||||
|
||||
typedef struct conf_var_struct {
|
||||
char *var, *value;
|
||||
struct conf_var_struct *next;
|
||||
} conf_var_t;
|
||||
|
||||
/************ Variables ************/
|
||||
extern fstate_t *fstate;
|
||||
extern unsigned char fstate_idx;
|
||||
extern unsigned long Options, image_toggles;
|
||||
extern char *theme_dir, *user_dir;
|
||||
extern char **rs_exec_args; /* Args to exec (-e or --exec) */
|
||||
|
@ -255,16 +160,6 @@ _XFUNCPROTOBEGIN
|
|||
unsigned long num_words(const char *str);
|
||||
extern void get_initial_options(int, char **);
|
||||
extern void get_options(int, char **);
|
||||
extern void conf_init_subsystem(void);
|
||||
extern unsigned char conf_register_context(char *name, ctx_handler_t handler);
|
||||
extern unsigned char conf_register_fstate(FILE *fp, char *path, char *outfile, unsigned long line, unsigned char flags);
|
||||
extern unsigned char conf_register_builtin(char *name, eterm_func_ptr_t ptr);
|
||||
extern unsigned char conf_register_context_state(unsigned char ctx_id);
|
||||
extern void conf_free_subsystem(void);
|
||||
extern char *shell_expand(char *);
|
||||
extern char *conf_find_file(const char *file, const char *dir, const char *pathlist);
|
||||
extern FILE *open_config_file(char *name);
|
||||
extern char *conf_parse(char *conf_name, const char *dir, const char *path);
|
||||
extern char *conf_parse_theme(char **theme, char *conf_name, unsigned char fallback);
|
||||
extern void init_defaults(void);
|
||||
extern void post_parse(void);
|
||||
|
|
70
src/screen.c
70
src/screen.c
|
@ -225,7 +225,7 @@ scr_reset(void)
|
|||
D_SCREEN(("screen.text == %8p, screen.rend == %8p, swap.text == %8p, swap.rend == %8p\n", screen.text, screen.rend, swap.text, swap.rend));
|
||||
|
||||
/* we have fewer rows so fix up number of scrolled lines */
|
||||
MIN_IT(screen.row, TermWin.nrow - 1);
|
||||
UPPER_BOUND(screen.row, TermWin.nrow - 1);
|
||||
|
||||
} else if (TermWin.nrow > prev_nrow) {
|
||||
/* add rows */
|
||||
|
@ -583,7 +583,7 @@ scroll_text(int row1, int row2, int count, int spec)
|
|||
return 0;
|
||||
if ((count > 0) && (row1 == 0) && (current_screen == PRIMARY)) {
|
||||
TermWin.nscrolled += count;
|
||||
MIN_IT(TermWin.nscrolled, TermWin.saveLines);
|
||||
UPPER_BOUND(TermWin.nscrolled, TermWin.saveLines);
|
||||
} else if (!spec)
|
||||
row1 += TermWin.saveLines;
|
||||
row2 += TermWin.saveLines;
|
||||
|
@ -612,7 +612,7 @@ scroll_text(int row1, int row2, int count, int spec)
|
|||
|
||||
/* A: scroll up */
|
||||
|
||||
MIN_IT(count, row2 - row1 + 1);
|
||||
UPPER_BOUND(count, row2 - row1 + 1);
|
||||
|
||||
/* A1: Copy and blank out lines that will get clobbered by the rotation */
|
||||
for (i = 0, j = row1; i < count; i++, j++) {
|
||||
|
@ -708,10 +708,8 @@ scr_add_lines(const unsigned char *str, int nlines, int len)
|
|||
screen.row -= nlines;
|
||||
}
|
||||
}
|
||||
MIN_IT(screen.col, last_col - 1);
|
||||
MIN_IT(screen.row, TermWin.nrow - 1);
|
||||
/*MAX_IT(screen.row, 0); */
|
||||
MAX_IT(screen.row, -TermWin.nscrolled);
|
||||
UPPER_BOUND(screen.col, last_col - 1);
|
||||
BOUND(screen.row, -TermWin.nscrolled, TermWin.nrow - 1);
|
||||
|
||||
row = screen.row + TermWin.saveLines;
|
||||
if (screen.text[row] == NULL) {
|
||||
|
@ -755,7 +753,7 @@ scr_add_lines(const unsigned char *str, int nlines, int len)
|
|||
scr_tab(1);
|
||||
continue;
|
||||
case '\n':
|
||||
MAX_IT(stp[last_col], screen.col);
|
||||
LOWER_BOUND(stp[last_col], screen.col);
|
||||
screen.flags &= ~Screen_WrapNext;
|
||||
if (screen.row == screen.bscroll) {
|
||||
scroll_text(screen.tscroll, screen.bscroll, 1, 0);
|
||||
|
@ -769,7 +767,7 @@ scr_add_lines(const unsigned char *str, int nlines, int len)
|
|||
srp = screen.rend[row]; /* _must_ refresh */
|
||||
continue;
|
||||
case '\r':
|
||||
MAX_IT(stp[last_col], screen.col);
|
||||
LOWER_BOUND(stp[last_col], screen.col);
|
||||
screen.flags &= ~Screen_WrapNext;
|
||||
screen.col = 0;
|
||||
continue;
|
||||
|
@ -813,7 +811,7 @@ scr_add_lines(const unsigned char *str, int nlines, int len)
|
|||
screen.flags &= ~Screen_WrapNext;
|
||||
}
|
||||
}
|
||||
MAX_IT(stp[last_col], screen.col);
|
||||
LOWER_BOUND(stp[last_col], screen.col);
|
||||
if (screen.col == 0) {
|
||||
end.col = last_col - 1;
|
||||
end.row = screen.row - 1;
|
||||
|
@ -889,14 +887,11 @@ scr_tab(int count)
|
|||
void
|
||||
scr_gotorc(int row, int col, int relative)
|
||||
{
|
||||
D_SCREEN(("scr_gotorc(r:%d,c:%d,%d): from (r:%d,c:%d)\n", row, col, relative, screen.row, screen.col));
|
||||
|
||||
ZERO_SCROLLBACK;
|
||||
RESET_CHSTAT;
|
||||
|
||||
screen.col = ((relative & C_RELATIVE) ? (screen.col + col) : col);
|
||||
MAX_IT(screen.col, 0);
|
||||
MIN_IT(screen.col, TermWin.ncol - 1);
|
||||
BOUND(screen.col, 0, TermWin.ncol - 1);
|
||||
|
||||
if (screen.flags & Screen_WrapNext) {
|
||||
screen.flags &= ~Screen_WrapNext;
|
||||
|
@ -918,12 +913,11 @@ scr_gotorc(int row, int col, int relative)
|
|||
} else {
|
||||
if (screen.flags & Screen_Relative) { /* relative origin mode */
|
||||
screen.row = row + screen.tscroll;
|
||||
MIN_IT(screen.row, screen.bscroll);
|
||||
UPPER_BOUND(screen.row, screen.bscroll);
|
||||
} else
|
||||
screen.row = row;
|
||||
}
|
||||
MAX_IT(screen.row, 0);
|
||||
MIN_IT(screen.row, TermWin.nrow - 1);
|
||||
BOUND(screen.row, 0, TermWin.nrow - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -953,8 +947,7 @@ scr_index(int direction)
|
|||
blank_screen_mem(screen.text, screen.rend, dirn, rstyle);
|
||||
} else
|
||||
screen.row += dirn;
|
||||
MAX_IT(screen.row, 0);
|
||||
MIN_IT(screen.row, TermWin.nrow - 1);
|
||||
BOUND(screen.row, 0, TermWin.nrow - 1);
|
||||
CHECK_SELECTION;
|
||||
}
|
||||
|
||||
|
@ -982,7 +975,7 @@ scr_erase_line(int mode)
|
|||
case 0: /* erase to end of line */
|
||||
col = screen.col;
|
||||
num = TermWin.ncol - col;
|
||||
MIN_IT(screen.text[row][TermWin.ncol], col);
|
||||
UPPER_BOUND(screen.text[row][TermWin.ncol], col);
|
||||
break;
|
||||
case 1: /* erase to beginning of line */
|
||||
col = 0;
|
||||
|
@ -1050,7 +1043,7 @@ scr_erase_screen(int mode)
|
|||
return;
|
||||
}
|
||||
if (row >= 0 && row <= TermWin.nrow) { /* check OOB */
|
||||
MIN_IT(num, (TermWin.nrow - row));
|
||||
UPPER_BOUND(num, (TermWin.nrow - row));
|
||||
if (rstyle & RS_RVid || rstyle & RS_Uline)
|
||||
ren = -1;
|
||||
else {
|
||||
|
@ -1152,7 +1145,7 @@ scr_insdel_chars(int count, int insdel)
|
|||
return;
|
||||
|
||||
CHECK_SELECTION;
|
||||
MIN_IT(count, (TermWin.ncol - screen.col));
|
||||
UPPER_BOUND(count, (TermWin.ncol - screen.col));
|
||||
|
||||
row = screen.row + TermWin.saveLines;
|
||||
screen.flags &= ~Screen_WrapNext;
|
||||
|
@ -1164,7 +1157,7 @@ scr_insdel_chars(int count, int insdel)
|
|||
screen.rend[row][col] = screen.rend[row][col - count];
|
||||
}
|
||||
screen.text[row][TermWin.ncol] += count;
|
||||
MIN_IT(screen.text[row][TermWin.ncol], TermWin.ncol);
|
||||
UPPER_BOUND(screen.text[row][TermWin.ncol], TermWin.ncol);
|
||||
/* FALLTHROUGH */
|
||||
case ERASE:
|
||||
blank_line(&(screen.text[row][screen.col]),
|
||||
|
@ -1203,8 +1196,8 @@ scr_insdel_chars(int count, int insdel)
|
|||
void
|
||||
scr_scroll_region(int top, int bot)
|
||||
{
|
||||
MAX_IT(top, 0);
|
||||
MIN_IT(bot, TermWin.nrow - 1);
|
||||
LOWER_BOUND(top, 0);
|
||||
UPPER_BOUND(bot, TermWin.nrow - 1);
|
||||
if (top > bot)
|
||||
return;
|
||||
screen.tscroll = top;
|
||||
|
@ -1502,8 +1495,7 @@ scr_move_to(int y, int len)
|
|||
/ (len)) - (TermWin.nrow - 1);
|
||||
D_SCREEN(("scr_move_to(%d, %d) view_start:%d\n", y, len, TermWin.view_start));
|
||||
|
||||
MAX_IT(TermWin.view_start, 0);
|
||||
MIN_IT(TermWin.view_start, TermWin.nscrolled);
|
||||
BOUND(TermWin.view_start, 0, TermWin.nscrolled);
|
||||
|
||||
return (TermWin.view_start - start);
|
||||
}
|
||||
|
@ -2224,8 +2216,7 @@ scr_search_scrollback(char *str)
|
|||
} else {
|
||||
if (lrow != rows) {
|
||||
TermWin.view_start = rows - lrow - TermWin.nrow;
|
||||
LOWER_BOUND(TermWin.view_start, 0);
|
||||
UPPER_BOUND(TermWin.view_start, TermWin.nscrolled);
|
||||
BOUND(TermWin.view_start, 0, TermWin.nscrolled);
|
||||
D_SCREEN(("New view start is %d\n", TermWin.view_start));
|
||||
}
|
||||
}
|
||||
|
@ -2562,12 +2553,10 @@ selection_setclr(int set, int startr, int startc, int endr, int endc)
|
|||
}
|
||||
last_col = TermWin.ncol - 1;
|
||||
|
||||
MIN_IT(endc, last_col);
|
||||
MIN_IT(startr, TermWin.nrow - 1);
|
||||
MAX_IT(startr, -TermWin.nscrolled);
|
||||
MIN_IT(endr, TermWin.nrow - 1);
|
||||
MAX_IT(endr, -TermWin.nscrolled);
|
||||
MAX_IT(startc, 0);
|
||||
LOWER_BOUND(startc, 0);
|
||||
UPPER_BOUND(endc, last_col);
|
||||
BOUND(startr, -TermWin.nscrolled, TermWin.nrow - 1);
|
||||
BOUND(endr, -TermWin.nscrolled, TermWin.nrow - 1);
|
||||
|
||||
startr += TermWin.saveLines;
|
||||
endr += TermWin.saveLines;
|
||||
|
@ -2627,8 +2616,7 @@ selection_start_colrow(int col, int row)
|
|||
selection.end.row, selection.end.col);
|
||||
}
|
||||
selection.op = SELECTION_INIT;
|
||||
MAX_IT(row, 0);
|
||||
MIN_IT(row, TermWin.nrow - 1);
|
||||
BOUND(row, 0, TermWin.nrow - 1);
|
||||
|
||||
row -= TermWin.view_start;
|
||||
end_col = screen.text[row + TermWin.saveLines][TermWin.ncol];
|
||||
|
@ -2710,7 +2698,7 @@ selection_make(Time tm)
|
|||
end_col = selection.end.col + 1;
|
||||
} else
|
||||
i = 1;
|
||||
MIN_IT(end_col, TermWin.ncol);
|
||||
UPPER_BOUND(end_col, TermWin.ncol);
|
||||
for (; col < end_col; col++)
|
||||
*str++ = *t++;
|
||||
if (!(Options & Opt_select_trailing_spaces)) {
|
||||
|
@ -2971,8 +2959,7 @@ selection_extend(int x, int y, int flag)
|
|||
*/
|
||||
col = Pixel2Col(x);
|
||||
row = Pixel2Row(y);
|
||||
MAX_IT(row, 0);
|
||||
MIN_IT(row, TermWin.nrow - 1);
|
||||
BOUND(row, 0, TermWin.nrow - 1);
|
||||
if (((selection.clicks % 3) == 1) && !flag && (col == selection.mark.col && (row == selection.mark.row + TermWin.view_start))) {
|
||||
/* select nothing */
|
||||
selection_setclr(0, selection.beg.row, selection.beg.col,
|
||||
|
@ -3033,8 +3020,7 @@ selection_extend_colrow(int col, int row, int flag, int cont)
|
|||
return;
|
||||
}
|
||||
old_col = col;
|
||||
MAX_IT(col, -1);
|
||||
MIN_IT(col, TermWin.ncol);
|
||||
BOUND(col, -1, TermWin.ncol);
|
||||
old_beg.col = selection.beg.col;
|
||||
old_beg.row = selection.beg.row;
|
||||
old_end.col = selection.end.col;
|
||||
|
|
|
@ -29,11 +29,9 @@
|
|||
#define IS_CUT_BUFFER(a) (((a) >= XA_CUT_BUFFER0) && ((a) <= XA_CUT_BUFFER7))
|
||||
|
||||
#define ZERO_SCROLLBACK do { \
|
||||
D_SCREEN(("ZERO_SCROLLBACK()\n")); \
|
||||
if (Options & Opt_home_on_output) TermWin.view_start = 0; \
|
||||
} while (0)
|
||||
#define REFRESH_ZERO_SCROLLBACK do { \
|
||||
D_SCREEN(("REFRESH_ZERO_SCROLLBACK()\n")); \
|
||||
if (Options & Opt_home_on_output) TermWin.view_start = 0; \
|
||||
} while (0)
|
||||
#define CHECK_SELECTION do { \
|
||||
|
|
117
src/script.c
117
src/script.c
|
@ -50,6 +50,7 @@ static eterm_script_handler_t script_handlers[] =
|
|||
{ "paste", script_handler_paste },
|
||||
{ "quit", script_handler_exit },
|
||||
{ "save", script_handler_save },
|
||||
{ "scroll", script_handler_scroll },
|
||||
{ "search", script_handler_search },
|
||||
{ "spawn", script_handler_spawn },
|
||||
|
||||
|
@ -122,6 +123,18 @@ eterm_handle_winop(char *action)
|
|||
#endif
|
||||
|
||||
/********* HANDLERS **********/
|
||||
|
||||
/* copy(): Copy the current selection to the specified clipboard or cut
|
||||
* buffer
|
||||
*
|
||||
* Syntax: copy([ <buffer> ])
|
||||
*
|
||||
* <buffer> is either a number 0-7, in which case the selection is copied to
|
||||
* the the cut buffer specified, or one of the words "clipboard," "primary,"
|
||||
* or "secondary" (or any initial substring thereof), in which case the
|
||||
* selection is copied to the specified clipboard. The default buffer is
|
||||
* the "primary" buffer (XA_PRIMARY in Xlib-speak).
|
||||
*/
|
||||
void
|
||||
script_handler_copy(char **params)
|
||||
{
|
||||
|
@ -149,6 +162,15 @@ script_handler_copy(char **params)
|
|||
selection_copy(sel);
|
||||
}
|
||||
|
||||
/* exit(): Exit Eterm with an optional message or return code
|
||||
*
|
||||
* Syntax: exit([ { <msg> | <code> } ])
|
||||
*
|
||||
* <msg> is an optional exit message. <code> is a positive or
|
||||
* negative integer return code. Either one may be specified, but not
|
||||
* both. If neither is specified, Eterm exits with a return code of 0
|
||||
* and no message.
|
||||
*/
|
||||
void
|
||||
script_handler_exit(char **params)
|
||||
{
|
||||
|
@ -167,6 +189,17 @@ script_handler_exit(char **params)
|
|||
exit(code);
|
||||
}
|
||||
|
||||
/* paste(): Paste the contents of the specified clipboard or cut buffer
|
||||
* into the terminal window
|
||||
*
|
||||
* Syntax: paste([ <buffer> ])
|
||||
*
|
||||
* <buffer> is either a number 0-7, in which case the contents of the cut
|
||||
* buffer specified are pasted, or one of the words "clipboard," "primary,"
|
||||
* or "secondary" (or any initial substring thereof), in which case the
|
||||
* contents of the specified clipboard are pasted. The default buffer is
|
||||
* the "primary" buffer (XA_PRIMARY in Xlib-speak).
|
||||
*/
|
||||
void
|
||||
script_handler_paste(char **params)
|
||||
{
|
||||
|
@ -194,6 +227,16 @@ script_handler_paste(char **params)
|
|||
selection_paste(sel);
|
||||
}
|
||||
|
||||
/* save(): Save the current theme/user configuration
|
||||
*
|
||||
* Syntax: save([ { theme | user } ,] [ <filename> ])
|
||||
*
|
||||
* The "user" settings are saved by default, and the default
|
||||
* filename is user.cfg. So save() by itself will save the
|
||||
* current user settings to user.cfg. save(theme) will save
|
||||
* the theme settings instead; the default filename in that case
|
||||
* will be theme.cfg.
|
||||
*/
|
||||
void
|
||||
script_handler_save(char **params)
|
||||
{
|
||||
|
@ -208,12 +251,80 @@ script_handler_save(char **params)
|
|||
}
|
||||
}
|
||||
|
||||
/* scroll(): Scroll backward or forward in the scrollback buffer
|
||||
*
|
||||
* Syntax: scroll(N) or scroll(Nl) -- Scroll N lines
|
||||
* scroll(Np) -- Scroll N pages/screensful
|
||||
* scroll(Nb) -- Scroll N buffers
|
||||
*
|
||||
* N is a floating point number. Use a negative number to scroll
|
||||
* up and a positive number to scroll down. Fractions can be used
|
||||
* also (e.g., to scroll one half page, use scroll(0.5p)). It is
|
||||
* possible to spell out "lines," "pages," and "buffers" as well,
|
||||
* and the type may be passed as a second parameter if you wish.
|
||||
*/
|
||||
void
|
||||
script_handler_scroll(char **params)
|
||||
{
|
||||
char *type;
|
||||
double cnt_float;
|
||||
long count;
|
||||
int direction = DN;
|
||||
|
||||
if (params && *params) {
|
||||
cnt_float = strtod(params[0], &type);
|
||||
if (cnt_float == 0.0) {
|
||||
return;
|
||||
} else if (cnt_float < 0.0) {
|
||||
cnt_float = -cnt_float;
|
||||
direction = UP;
|
||||
}
|
||||
if (!type) {
|
||||
type = params[1];
|
||||
}
|
||||
if (type && *type) {
|
||||
for (; *type && !isalpha(*type); type++);
|
||||
if (str_leading_match("lines", type)) {
|
||||
count = (long) cnt_float;
|
||||
} else if (str_leading_match("pages", type) || str_leading_match("screens", type)) {
|
||||
count = (long) ((cnt_float * TermWin.nrow) - CONTEXT_LINES);
|
||||
} else if (str_leading_match("buffers", type)) {
|
||||
count = (long) (cnt_float * (TermWin.nrow + TermWin.saveLines));
|
||||
} else {
|
||||
print_error("Invalid modifier \"%s\" in scroll()\n", type);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
count = (long) cnt_float;
|
||||
}
|
||||
|
||||
if (count <= 0) {
|
||||
return;
|
||||
}
|
||||
scr_page(direction, count);
|
||||
}
|
||||
}
|
||||
|
||||
/* search(): Search the scrollback buffer for a string and highlight
|
||||
* any occurances of it.
|
||||
*
|
||||
* Syntax: search([ <str> ])
|
||||
*
|
||||
* <str> is an optional search string to highlight. If none is given,
|
||||
* search() will clear the previously-highlighted search term.
|
||||
*/
|
||||
void
|
||||
script_handler_search(char **params)
|
||||
{
|
||||
scr_search_scrollback(params ? params[0] : NULL);
|
||||
}
|
||||
|
||||
/* spawn(): Spawns a child process to execute a sub-command
|
||||
*
|
||||
* Syntax: spawn([ <command> ])
|
||||
*
|
||||
* If no command is specified, the default is to execute another Eterm.
|
||||
*/
|
||||
void
|
||||
script_handler_spawn(char **params)
|
||||
{
|
||||
|
@ -228,6 +339,12 @@ script_handler_spawn(char **params)
|
|||
}
|
||||
}
|
||||
|
||||
/* nop(): Do nothing
|
||||
*
|
||||
* Syntax: nop()
|
||||
*
|
||||
* This function can be used to cancel undesired default behavior.
|
||||
*/
|
||||
void
|
||||
script_handler_nop(char **params)
|
||||
{
|
||||
|
|
|
@ -47,6 +47,7 @@ extern void script_handler_copy(char **);
|
|||
extern void script_handler_exit(char **);
|
||||
extern void script_handler_paste(char **);
|
||||
extern void script_handler_save(char **);
|
||||
extern void script_handler_scroll(char **);
|
||||
extern void script_handler_search(char **);
|
||||
extern void script_handler_spawn(char **);
|
||||
extern void script_handler_nop(char **);
|
||||
|
|
|
@ -258,10 +258,10 @@ sb_handle_button_press(event_t *ev)
|
|||
if (scrollbar.type == SCROLLBAR_MOTIF || scrollbar.type == SCROLLBAR_NEXT) {
|
||||
if (scrollbar_is_above_anchor(ev->xany.window, ev->xbutton.y)) {
|
||||
scrollbar_draw_trough(IMAGE_STATE_CLICKED, 0);
|
||||
scr_page(UP, TermWin.nrow - 1);
|
||||
scr_page(UP, TermWin.nrow - CONTEXT_LINES);
|
||||
} else if (scrollbar_is_below_anchor(ev->xany.window, ev->xbutton.y)) {
|
||||
scrollbar_draw_trough(IMAGE_STATE_CLICKED, 0);
|
||||
scr_page(DN, TermWin.nrow - 1);
|
||||
scr_page(DN, TermWin.nrow - CONTEXT_LINES);
|
||||
} else {
|
||||
scrollbar_set_motion(1);
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ sb_handle_button_press(event_t *ev)
|
|||
|
||||
#ifdef XTERM_SCROLLBAR
|
||||
if (scrollbar.type == SCROLLBAR_XTERM) {
|
||||
scr_page((ev->xbutton.button == Button1 ? DN : UP), TermWin.nrow - 1);
|
||||
scr_page((ev->xbutton.button == Button1 ? DN : UP), TermWin.nrow - CONTEXT_LINES);
|
||||
}
|
||||
#endif /* XTERM_SCROLLBAR */
|
||||
break;
|
||||
|
|
|
@ -146,9 +146,6 @@ eterm_bootstrap(int argc, char *argv[])
|
|||
props[PROP_DND_PROTOCOL] = XInternAtom(Xdisplay, "DndProtocol", False);
|
||||
props[PROP_DND_SELECTION] = XInternAtom(Xdisplay, "DndSelection", False);
|
||||
|
||||
/* Initialize the parser */
|
||||
conf_init_subsystem();
|
||||
|
||||
if ((theme_dir = conf_parse_theme(&rs_theme, THEME_CFG, PARSE_TRY_ALL)) != NULL) {
|
||||
char *tmp;
|
||||
|
||||
|
|
|
@ -44,38 +44,6 @@
|
|||
#define MAX_COLS 250
|
||||
#define MAX_ROWS 128
|
||||
|
||||
#ifdef MIN
|
||||
# undef MIN
|
||||
#endif
|
||||
#ifdef MAX
|
||||
# undef MAX
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
# define MIN(a,b) __extension__ ({__typeof__(a) aa = (a); __typeof__(b) bb = (b); (aa < bb) ? (aa) : (bb);})
|
||||
# define MAX(a,b) __extension__ ({__typeof__(a) aa = (a); __typeof__(b) bb = (b); (aa > bb) ? (aa) : (bb);})
|
||||
# define LOWER_BOUND(current, other) __extension__ ({__typeof__(other) o = (other); ((current) < o) ? ((current) = o) : (current);})
|
||||
# define AT_LEAST(current, other) LOWER_BOUND(current, other)
|
||||
# define MAX_IT(current, other) LOWER_BOUND(current, other)
|
||||
# define UPPER_BOUND(current, other) __extension__ ({__typeof__(other) o = (other); ((current) > o) ? ((current) = o) : (current);})
|
||||
# define AT_MOST(current, other) UPPER_BOUND(current, other)
|
||||
# define MIN_IT(current, other) UPPER_BOUND(current, other)
|
||||
# define BOUND(val, min, max) __extension__ ({__typeof__(min) m1 = (min); __typeof__(max) m2 = (max); ((val) < m1) ? ((val) = m1) : (((val) > m2) ? ((val) = m2) : (val));})
|
||||
# define CONTAIN(val, min, max) BOUND(val, min, max)
|
||||
# define SWAP_IT(one, two, tmp) do {(tmp) = (one); (one) = (two); (two) = (tmp);} while (0)
|
||||
#else
|
||||
# define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
# define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
# define LOWER_BOUND(current, other) (((current) < (other)) ? ((current) = (other)) : (current))
|
||||
# define AT_LEAST(current, other) LOWER_BOUND(current, other)
|
||||
# define MAX_IT(current, other) LOWER_BOUND(current, other)
|
||||
# define UPPER_BOUND(current, other) (((current) > (other)) ? ((current) = (other)) : (current))
|
||||
# define AT_MOST(current, other) UPPER_BOUND(current, other)
|
||||
# define MIN_IT(current, other) UPPER_BOUND(current, other)
|
||||
# define BOUND(val, min, max) (((val) < (min)) ? ((val) = (min)) : (((val) > (max)) ? ((val) = (max)) : (val)))
|
||||
# define CONTAIN(val, min, max) BOUND(val, min, max)
|
||||
# define SWAP_IT(one, two, tmp) do {(tmp) = (one); (one) = (two); (two) = (tmp);} while (0)
|
||||
#endif
|
||||
|
||||
#define SHADOW 2
|
||||
|
||||
/* convert pixel dimensions to row/column values */
|
||||
|
|
Loading…
Reference in New Issue