WISH: OnTheSpot editing, or maybe switch to miiiiiiif
WISH: just for fun, do shade and tint with XRender.
+ - optionally embed a perl interpreter, which can be used for more
+ intelligent/customized selection support, visual feedback, menus
+ etc. See the urxvtperl manpage.
+ - improved sched_yield support.
+
6.2 Mon Jan 2 16:03:01 CET 2006
- implemented intensityStyles option which enables/disables bold/blink
selecting high intensity foreground/background colours, suggested by
src/xdefaults.C
src/xpm.C
+src/urxvt.pm
+src/typemap
+src/rxvtperl.h
+src/rxvtperl.C
+
src/gentables
src/gencompose
src/genlinedraw
ECHO = @ECHO@
CMP = @CMP@
TBL = @TBL@
+PERL = @PERL@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL@ -m 755
INSTALL_DATA = @INSTALL@ -m 644
/* Define if you want extended chinese codesets */
#undef ENCODING_ZH_EXT
+/* Define if you can embed a perl interpreter */
+#undef ENABLE_PERL
+
/* Define if you don't need to use our replacement string functions */
#undef NO_STRINGS
support_8bitctrls=no
support_iso14755=yes
support_styles=yes
+support_perl=no
codesets=all
dnl# --------------------------------------------------------------------------
support_8bitctrls=no
support_iso14755=no
support_styles=no
+ support_perl=no
codesets=
fi
if test x$enableval = xyes; then
#support_8bitctrls=yes
support_iso14755=yes
support_styles=yes
+ support_perl=yes
codesets=all
fi
])
support_scroll_xterm=$enableval
fi])
+AC_ARG_ENABLE(perl,
+ [ --enable-perl enable embedded perl interpreter],
+ [if test x$enableval = xyes -o x$enableval = xno; then
+ support_perl=$enableval
+ fi])
+
AC_ARG_ENABLE(plain-scroll,
[ --enable-plain-scroll enable plain style scrollbar],
[if test x$enableval = xyes -o x$enableval = xno; then
esac
done
+IF_PERL=\#
+if test x$support_perl = xyes; then
+ AC_PATH_PROG(PERL, perl5)
+ AC_PATH_PROG(PERL, perl)
+
+ AC_MSG_CHECKING(for $PERL suitability)
+ if $PERL -MExtUtils::Embed -e "use v5.8" >/dev/null 2>/dev/null; then
+ AC_DEFINE(ENABLE_PERL, 1, Define if you can embed a perl interpreter)
+ IF_PERL=
+ PERL_O=rxvtperl.o
+ PERLFLAGS="`$PERL -MExtUtils::Embed -e ccopts`"
+ PERLLIB="`$PERL -MExtUtils::Embed -e ldopts`"
+ PERLARCHLIB="`$PERL -MConfig -e 'print $Config{archlib}'`"
+ AC_MSG_RESULT(ok)
+ else
+ AC_MSG_ERROR(no working perl found, or perl not version >= 5.8)
+ fi
+fi
+AC_SUBST(PERLLIB)
+AC_SUBST(PERLFLAGS)
+AC_SUBST(PERLARCHLIB)
+AC_SUBST(PERL)
+AC_SUBST(IF_PERL)
+AC_SUBST(PERL_O)
+
dnl> AC_CHECK_FUNCS(gettimeofday putenv select socket)
CFLAGS=${CFLAGS--O}
wtmp file: $rxvt_cv_path_wtmp
wtmpx file: $rxvt_cv_path_wtmpx
lastlog file: $rxvt_cv_path_lastlog
- ttys/ttytab file: $rxvt_cv_path_ttytab"
+ ttys/ttytab file: $rxvt_cv_path_ttytab
+ embedded perl: $support_perl"
echo
fi
if test x$term != x; then
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os VERSION DATE LSMDATE LIBVERSION CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX CPP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK LINKER CXXCPP EGREP INSTALL_LIBRXVT RXVTNAME MV RM CP LN SED ECHO CMP TBL TIC X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS XPM_CPPFLAGS XPM_CFLAGS XPM_LIBS rxvt_int16_typedef rxvt_uint16_typedef rxvt_int32_typedef rxvt_uint32_typedef rxvt_intp_define rxvt_u_intp_define DEBUG DINCLUDE DLIB include_stdint_h include_stdarg_h include_stdlib_h include_unistd_h include_string_h include_fcntl_h include_util_h include_assert_h include_sys_ioctl_h include_sys_select_h include_sys_strredir_h include_sys_time_h include_time_h LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os VERSION DATE LSMDATE LIBVERSION CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX CPP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AWK LINKER CXXCPP EGREP INSTALL_LIBRXVT RXVTNAME MV RM CP LN SED ECHO CMP TBL TIC X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS XPM_CPPFLAGS XPM_CFLAGS XPM_LIBS rxvt_int16_typedef rxvt_uint16_typedef rxvt_int32_typedef rxvt_uint32_typedef rxvt_intp_define rxvt_u_intp_define PERL PERLLIB PERLFLAGS PERLARCHLIB IF_PERL PERL_O DEBUG DINCLUDE DLIB include_stdint_h include_stdarg_h include_stdlib_h include_unistd_h include_string_h include_fcntl_h include_util_h include_assert_h include_sys_ioctl_h include_sys_select_h include_sys_strredir_h include_sys_time_h include_time_h LIBOBJS LTLIBOBJS'
ac_subst_files='MCOMMON'
# Initialize some variables set by options.
--enable-rxvt-scroll enable rxvt style scrollbar
--enable-next-scroll enable NeXT style scrollbar
--enable-xterm-scroll enable Xterm style scrollbar
+ --enable-perl enable embedded perl interpreter
--enable-plain-scroll enable plain style scrollbar
--enable-half-shadow use half width/height shadow on rxvt scrollbar
--enable-xim XIM (X Input Method) protocol support
support_8bitctrls=no
support_iso14755=yes
support_styles=yes
+support_perl=no
codesets=all
support_8bitctrls=no
support_iso14755=no
support_styles=no
+ support_perl=no
codesets=
fi
if test x$enableval = xyes; then
#support_8bitctrls=yes
support_iso14755=yes
support_styles=yes
+ support_perl=yes
codesets=all
fi
fi
fi;
+# Check whether --enable-perl or --disable-perl was given.
+if test "${enable_perl+set}" = set; then
+ enableval="$enable_perl"
+ if test x$enableval = xyes -o x$enableval = xno; then
+ support_perl=$enableval
+ fi
+fi;
+
# Check whether --enable-plain-scroll or --disable-plain-scroll was given.
if test "${enable_plain_scroll+set}" = set; then
enableval="$enable_plain_scroll"
esac
done
+IF_PERL=\#
+if test x$support_perl = xyes; then
+ # Extract the first word of "perl5", so it can be a program name with args.
+set dummy perl5; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_PERL+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $PERL in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+PERL=$ac_cv_path_PERL
+
+if test -n "$PERL"; then
+ echo "$as_me:$LINENO: result: $PERL" >&5
+echo "${ECHO_T}$PERL" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ # Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_PERL+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ case $PERL in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ ;;
+esac
+fi
+PERL=$ac_cv_path_PERL
+
+if test -n "$PERL"; then
+ echo "$as_me:$LINENO: result: $PERL" >&5
+echo "${ECHO_T}$PERL" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+ echo "$as_me:$LINENO: checking for $PERL suitability" >&5
+echo $ECHO_N "checking for $PERL suitability... $ECHO_C" >&6
+ if $PERL -MExtUtils::Embed -e "use v5.8" >/dev/null 2>/dev/null; then
+
+cat >>confdefs.h <<\_ACEOF
+#define ENABLE_PERL 1
+_ACEOF
+
+ IF_PERL=
+ PERL_O=rxvtperl.o
+ PERLFLAGS="`$PERL -MExtUtils::Embed -e ccopts`"
+ PERLLIB="`$PERL -MExtUtils::Embed -e ldopts`"
+ PERLARCHLIB="`$PERL -MConfig -e 'print $Config{archlib}'`"
+ echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+ else
+ { { echo "$as_me:$LINENO: error: no working perl found" >&5
+echo "$as_me: error: no working perl found" >&2;}
+ { (exit or perl not version >= 5.8); exit or perl not version >= 5.8; }; }
+ fi
+fi
+
+
+
+
+
+
+
CFLAGS=${CFLAGS--O}
LDFLAGS=${LDFLAGS--O}
s,@rxvt_uint32_typedef@,$rxvt_uint32_typedef,;t t
s,@rxvt_intp_define@,$rxvt_intp_define,;t t
s,@rxvt_u_intp_define@,$rxvt_u_intp_define,;t t
+s,@PERL@,$PERL,;t t
+s,@PERLLIB@,$PERLLIB,;t t
+s,@PERLFLAGS@,$PERLFLAGS,;t t
+s,@PERLARCHLIB@,$PERLARCHLIB,;t t
+s,@IF_PERL@,$IF_PERL,;t t
+s,@PERL_O@,$PERL_O,;t t
s,@DEBUG@,$DEBUG,;t t
s,@DINCLUDE@,$DINCLUDE,;t t
s,@DLIB@,$DLIB,;t t
wtmp file: $rxvt_cv_path_wtmp
wtmpx file: $rxvt_cv_path_wtmpx
lastlog file: $rxvt_cv_path_lastlog
- ttys/ttytab file: $rxvt_cv_path_ttytab"
+ ttys/ttytab file: $rxvt_cv_path_ttytab
+ embedded perl: $support_perl"
echo
fi
if test x$term != x; then
dummy:
COMMON = \
- command.o rxvtfont.o init.o logging.o \
+ command.o rxvtfont.o init.o logging.o @PERL_O@ \
main.o menubar.o misc.o netdisp.o ptytty.o screen.o \
scrollbar.o scrollbar-next.o scrollbar-rxvt.o scrollbar-xterm.o scrollbar-plain.o \
strings.o xdefaults.o xpm.o encoding.o rxvttoolkit.o rxvtutil.o iom.o keyboard.o
all: allbin
rxvt: rxvt.o $(COMMON)
- $(LINK) -o $@ $^ $(LIBS) $(XLIB) $(DLIB)
+ $(LINK) -o $@ $^ $(LIBS) $(XLIB) $(DLIB) @PERLLIB@
# $(LIBTOOL) --mode=link $(LINK) rxvt.o librxvt.la $(LIBS) $(XLIB) $(DLIB) -o $@
rxvtd: rxvtd.o $(COMMON) $(COMMON_DAEMON)
- $(LINK) -o $@ $^ $(LIBS) $(XLIB) $(DLIB)
+ $(LINK) -o $@ $^ $(LIBS) $(XLIB) $(DLIB) @PERLLIB@
# $(LIBTOOL) --mode=link $(LINK) rxvtd.o rxvtdaemon.o librxvt.la $(LIBS) $(XLIB) $(DLIB) -o $@
rxvtc: rxvtc.o $(COMMON_DAEMON)
$(INSTALL_PROGRAM) rxvtc $(RXVTC_BINNAME)
$(INSTALL_PROGRAM) rxvtd $(RXVTD_BINNAME)
+perlxsi.c: Makefile
+ $(PERL) -MExtUtils::Embed -e xsinit -- -std urxvt
+
+rxvtperl.C: rxvtperl.xs typemap
+ $(PERL) @PERLARCHLIB@/ExtUtils/xsubpp -C++ -typemap @PERLARCHLIB@/ExtUtils/typemap -typemap typemap -prototypes $< >$@
+
+rxvtperl.o: rxvtperl.C perlxsi.c
+ $(COMPILE) @PERLFLAGS@ -DLIBDIR="\"$(libdir)/urxvt\"" -c $<
+
depend:
makedepend -f Makefile.in -I. -Y *.C >/dev/null 2>&1
makedepend -f Makefile.in -I. -Y *.C -a -o .lo >/dev/null 2>&1
command.o: ../config.h rxvt.h rxvtlib.h ptytty.h feature.h encoding.h
command.o: rxvtfont.h rxvtutil.h rxvttoolkit.h iom.h iom_conf.h callback.h
-command.o: salloc.h menubar.h version.h command.h keyboard.h
+command.o: salloc.h menubar.h rxvtperl.h version.h command.h keyboard.h
encoding.o: ../config.h encoding.h table/iso8859_1.h table/iso8859_15.h
encoding.o: table/iso8859_2.h table/iso8859_3.h table/iso8859_4.h
encoding.o: table/iso8859_5.h table/iso8859_6.h table/iso8859_7.h
logging.o: salloc.h menubar.h logging.h
main.o: ../config.h rxvt.h rxvtlib.h ptytty.h feature.h encoding.h rxvtfont.h
main.o: rxvtutil.h rxvttoolkit.h iom.h iom_conf.h callback.h salloc.h
-main.o: menubar.h keyboard.h
+main.o: menubar.h keyboard.h rxvtperl.h
menubar.o: ../config.h rxvt.h rxvtlib.h ptytty.h feature.h encoding.h
menubar.o: rxvtfont.h rxvtutil.h rxvttoolkit.h iom.h iom_conf.h callback.h
menubar.o: salloc.h menubar.h version.h
rxvtfont.o: ../config.h rxvt.h rxvtlib.h ptytty.h feature.h encoding.h
rxvtfont.o: rxvtfont.h rxvtutil.h rxvttoolkit.h iom.h iom_conf.h callback.h
rxvtfont.o: salloc.h menubar.h table/linedraw.h
+rxvtperl.o: ../config.h rxvt.h rxvtlib.h ptytty.h feature.h encoding.h
+rxvtperl.o: rxvtfont.h rxvtutil.h rxvttoolkit.h iom.h iom_conf.h callback.h
+rxvtperl.o: salloc.h menubar.h rxvtperl.h perlxsi.c
rxvttoolkit.o: ../config.h rxvt.h rxvtlib.h ptytty.h feature.h encoding.h
rxvttoolkit.o: rxvtfont.h rxvtutil.h rxvttoolkit.h iom.h iom_conf.h
rxvttoolkit.o: callback.h salloc.h menubar.h
salloc.o: salloc.h
screen.o: ../config.h rxvt.h rxvtlib.h ptytty.h feature.h encoding.h
screen.o: rxvtfont.h rxvtutil.h rxvttoolkit.h iom.h iom_conf.h callback.h
-screen.o: salloc.h menubar.h salloc.C
+screen.o: salloc.h menubar.h rxvtperl.h salloc.C
scrollbar-next.o: ../config.h rxvt.h rxvtlib.h ptytty.h feature.h encoding.h
scrollbar-next.o: rxvtfont.h rxvtutil.h rxvttoolkit.h iom.h iom_conf.h
scrollbar-next.o: callback.h salloc.h menubar.h
command.lo: ../config.h rxvt.h rxvtlib.h ptytty.h feature.h encoding.h
command.lo: rxvtfont.h rxvtutil.h rxvttoolkit.h iom.h iom_conf.h callback.h
-command.lo: salloc.h menubar.h version.h command.h keyboard.h
+command.lo: salloc.h menubar.h rxvtperl.h version.h command.h keyboard.h
encoding.lo: ../config.h encoding.h table/iso8859_1.h table/iso8859_15.h
encoding.lo: table/iso8859_2.h table/iso8859_3.h table/iso8859_4.h
encoding.lo: table/iso8859_5.h table/iso8859_6.h table/iso8859_7.h
logging.lo: salloc.h menubar.h logging.h
main.lo: ../config.h rxvt.h rxvtlib.h ptytty.h feature.h encoding.h
main.lo: rxvtfont.h rxvtutil.h rxvttoolkit.h iom.h iom_conf.h callback.h
-main.lo: salloc.h menubar.h keyboard.h
+main.lo: salloc.h menubar.h keyboard.h rxvtperl.h
menubar.lo: ../config.h rxvt.h rxvtlib.h ptytty.h feature.h encoding.h
menubar.lo: rxvtfont.h rxvtutil.h rxvttoolkit.h iom.h iom_conf.h callback.h
menubar.lo: salloc.h menubar.h version.h
rxvtfont.lo: ../config.h rxvt.h rxvtlib.h ptytty.h feature.h encoding.h
rxvtfont.lo: rxvtfont.h rxvtutil.h rxvttoolkit.h iom.h iom_conf.h callback.h
rxvtfont.lo: salloc.h menubar.h table/linedraw.h
+rxvtperl.lo: ../config.h rxvt.h rxvtlib.h ptytty.h feature.h encoding.h
+rxvtperl.lo: rxvtfont.h rxvtutil.h rxvttoolkit.h iom.h iom_conf.h callback.h
+rxvtperl.lo: salloc.h menubar.h rxvtperl.h perlxsi.c
rxvttoolkit.lo: ../config.h rxvt.h rxvtlib.h ptytty.h feature.h encoding.h
rxvttoolkit.lo: rxvtfont.h rxvtutil.h rxvttoolkit.h iom.h iom_conf.h
rxvttoolkit.lo: callback.h salloc.h menubar.h
salloc.lo: salloc.h
screen.lo: ../config.h rxvt.h rxvtlib.h ptytty.h feature.h encoding.h
screen.lo: rxvtfont.h rxvtutil.h rxvttoolkit.h iom.h iom_conf.h callback.h
-screen.lo: salloc.h menubar.h salloc.C
+screen.lo: salloc.h menubar.h rxvtperl.h salloc.C
scrollbar-next.lo: ../config.h rxvt.h rxvtlib.h ptytty.h feature.h encoding.h
scrollbar-next.lo: rxvtfont.h rxvtutil.h rxvttoolkit.h iom.h iom_conf.h
scrollbar-next.lo: callback.h salloc.h menubar.h
*----------------------------------------------------------------------*/
/*{{{ includes: */
-#include "../config.h" /* NECESSARY */
-#include "rxvt.h" /* NECESSARY */
+#include "../config.h"
+#include "rxvt.h"
+#include "rxvtperl.h"
#include "version.h"
#include "command.h"
}
#endif
+#if HAVE_SCHED_YIELD
+static struct event_handler
+{
+ check_watcher cw_yield;
+
+ void yield (check_watcher &w)
+ {
+ sched_yield ();
+ w.stop ();
+ }
+
+ event_handler ()
+ : cw_yield (this, &event_handler::yield)
+ {
+ }
+} event_handler;
+#endif
+
bool
rxvt_term::pty_fill ()
{
else if (r < 0 && (errno == EAGAIN || errno == EINTR))
{
#if HAVE_SCHED_YIELD
- sched_yield ();
+ event_handler.cw_yield.start ();
#endif
}
else
{
focus = 1;
want_refresh = 1;
+
+ PERL_INVOKE ((this, HOOK_FOCUS_OUT, DT_END));
+
#if USE_XIM
if (Input_Context != NULL)
{
focus = 0;
want_refresh = 1;
+ PERL_INVOKE ((this, HOOK_FOCUS_OUT, DT_END));
+
#if ENABLE_FRILLS || ISO_14755
- iso14755buf = 0;
-#endif
-#if ENABLE_OVERLAY
- scr_overlay_off ();
+ if (iso14755buf)
+ {
+ iso14755buf = 0;
+# if ENABLE_OVERLAY
+ scr_overlay_off ();
+# endif
+ }
#endif
#if USE_XIM
if (Input_Context != NULL)
#ifndef KEYBOARD_H_
#define KEYBOARD_H_
+#ifdef KEYSYM_RESOURCE
+
#include <inttypes.h>
#include "feature.h"
#include "rxvtutil.h"
-#ifdef KEYSYM_RESOURCE
-
#define KEYSYM_HASH_BITS 4 /* lowest #bits of keysym is used as hash key */
#define KEYSYM_HASH_BUDGETS (1<<KEYSYM_HASH_BITS)
#define KEYSYM_HASH_MASK (KEYSYM_HASH_BUDGETS-1)
};
#endif /* KEYSYM_RESOURCE */
+
#endif /* KEYBOARD_H_ */
-// vim:et:sw=2
#include "../config.h" /* NECESSARY */
#include "rxvt.h" /* NECESSARY */
+#include "keyboard.h"
+#include "rxvtperl.h"
#include <limits>
# include <termios.h>
#endif
-#ifdef KEYSYM_RESOURCE
-# include "keyboard.h"
-#endif
-
vector<rxvt_term *> rxvt_term::termlist;
static char curlocale[128];
rxvt_term::~rxvt_term ()
{
+ PERL_INVOKE ((this, HOOK_DESTROY, DT_END));
+
termlist.erase (find (termlist.begin (), termlist.end(), this));
emergency_cleanup ();
scrollBar.setIdle (); /* set existence for size calculations */
#endif
+#if ENABLE_PERL
+ rxvt_perl.init ();
+#endif
+
+ PERL_INVOKE ((this, HOOK_INIT, DT_END));
+
create_windows (argc, argv);
dDisp;
check_ev.start ();
+ PERL_INVOKE ((this, HOOK_START, DT_END));
+
return true;
}
# undef USE_XGETDEFAULT
#endif
-#if ISO_14755
+#if defined (ISO_14755) || defined (ENABLE_PERL)
# define ENABLE_OVERLAY 1
#endif
log_callback *log_hook; // log error messages through this hook, if != 0
getfd_callback *getfd_hook; // convert remote to local fd, if != 0
+#if ENABLE_PERL
+ void *self; // perl's $self
+#endif
+
struct mbstate mbstate; // current input multibyte state
unsigned char want_refresh:1,
int selection_request_other (Atom target, int selnum);
void selection_clear ();
void selection_make (Time tm);
+ bool selection_grab (Time tm);
void selection_start_colrow (int col, int row);
void selection_delimit_word (enum page_dirn dirn, const row_col_t *mark, row_col_t *ret);
void selection_extend_colrow (int32_t col, int32_t row, int button3, int buttonpress, int clickchange);
--- /dev/null
+/*
+ * rxvtperl.h
+ */
+
+#ifndef RXVTPERL_H_
+#define RXVTPERL_H_
+
+#if ENABLE_PERL
+
+#include "rxvt.h"
+
+#define PERL_INVOKE(args) rxvt_perl.invoke args
+
+enum data_type {
+ DT_END,
+ DT_INT,
+ DT_LONG,
+};
+
+enum hook_type {
+ HOOK_LOAD,
+
+ HOOK_INIT,
+ HOOK_RESET,
+ HOOK_START,
+ HOOK_DESTROY,
+
+ HOOK_SEL_BEGIN,
+ HOOK_SEL_EXTEND,
+ HOOK_SEL_MAKE,
+ HOOK_SEL_GRAB,
+
+ HOOK_FOCUS_IN,
+ HOOK_FOCUS_OUT,
+
+ HOOK_VIEW_CHANGE,
+ HOOK_SCROLL_BACK,
+ HOOK_TTY_ACTIVITY,
+
+ HOOK_REFRESH_BEGIN,
+ HOOK_REFRESH_END,
+
+ HOOK_NUM,
+};
+
+struct rxvt_perl_interp
+{
+ rxvt_perl_interp ();
+ ~rxvt_perl_interp ();
+
+ bool should_invoke[HOOK_NUM];
+
+ void init ();
+ bool invoke (rxvt_term *term, hook_type htype, ...);
+};
+
+extern struct rxvt_perl_interp rxvt_perl;
+
+#else
+#define PERL_INVOKE(args) (void)0
+#endif
+
+#endif
+
--- /dev/null
+/*----------------------------------------------------------------------*
+ * File: rxvtperl.xs
+ *----------------------------------------------------------------------*
+ *
+ * All portions of code are copyright by their respective author/s.
+ * Copyright (c) 2005-2005 Marc Lehmann <pcg@goof.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *----------------------------------------------------------------------*/
+
+#define line_t perl_line_t
+#include <EXTERN.h>
+#include <perl.h>
+#include <XSUB.h>
+#undef line_t
+
+#include "../config.h"
+
+#include <cstdarg>
+
+#include "rxvt.h"
+#include "iom.h"
+#include "rxvtutil.h"
+#include "rxvtperl.h"
+
+#include "perlxsi.c"
+
+/////////////////////////////////////////////////////////////////////////////
+
+static wchar_t *
+sv2wcs (SV *sv)
+{
+ STRLEN len;
+ char *str = SvPVutf8 (sv, len);
+ return rxvt_utf8towcs (str, len);
+}
+
+static SV *
+new_ref (HV *hv, const char *klass)
+{
+ return sv_bless (newRV ((SV *)hv), gv_stashpv (klass, 1));
+}
+
+//TODO: use magic
+static SV *
+newSVptr (void *ptr, const char *klass)
+{
+ HV *hv = newHV ();
+ hv_store (hv, "_ptr", 4, newSViv ((long)ptr), 0);
+ return sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1));
+}
+
+static long
+SvPTR (SV *sv, const char *klass)
+{
+ if (!sv_derived_from (sv, klass))
+ croak ("object of type %s expected", klass);
+
+ IV iv = SvIV (*hv_fetch ((HV *)SvRV (sv), "_ptr", 4, 1));
+
+ if (!iv)
+ croak ("perl code used %s object, but C++ object is already destroyed, caught", klass);
+
+ return (long)iv;
+}
+
+#define newSVterm(term) SvREFCNT_inc ((SV *)term->self)
+#define SvTERM(sv) (rxvt_term *)SvPTR (sv, "urxvt::term")
+
+/////////////////////////////////////////////////////////////////////////////
+
+struct perl_watcher
+{
+ SV *cbsv;
+ HV *self;
+
+ perl_watcher ()
+ : cbsv (newSV (0))
+ {
+ }
+
+ ~perl_watcher ()
+ {
+ SvREFCNT_dec (cbsv);
+ }
+
+ void cb (SV *cb)
+ {
+ sv_setsv (cbsv, cb);
+ }
+
+ void invoke (const char *type, SV *self, int arg = -1);
+};
+
+void
+perl_watcher::invoke (const char *type, SV *self, int arg)
+{
+ dSP;
+
+ ENTER;
+ SAVETMPS;
+
+ PUSHMARK (SP);
+
+ XPUSHs (sv_2mortal (self));
+
+ if (arg >= 0)
+ XPUSHs (sv_2mortal (newSViv (arg)));
+
+ PUTBACK;
+ call_sv (cbsv, G_VOID | G_EVAL | G_DISCARD);
+ SPAGAIN;
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ if (SvTRUE (ERRSV))
+ rxvt_warn ("%s callback evaluation error: %s", type, SvPV_nolen (ERRSV));
+}
+
+#define newSVtimer(timer) new_ref (timer->self, "urxvt::timer")
+#define SvTIMER(sv) (timer *)SvPTR (sv, "urxvt::timer")
+
+struct timer : time_watcher, perl_watcher
+{
+ timer ()
+ : time_watcher (this, &timer::execute)
+ {
+ }
+
+ void execute (time_watcher &w)
+ {
+ invoke ("urxvt::timer", newSVtimer (this));
+ }
+};
+
+#define newSViow(iow) new_ref (iow->self, "urxvt::iow")
+#define SvIOW(sv) (iow *)SvPTR (sv, "urxvt::iow")
+
+struct iow : io_watcher, perl_watcher
+{
+ iow ()
+ : io_watcher (this, &iow::execute)
+ {
+ }
+
+ void execute (io_watcher &w, short revents)
+ {
+ invoke ("urxvt::iow", newSViow (this), revents);
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+struct rxvt_perl_interp rxvt_perl;
+
+static PerlInterpreter *perl;
+
+rxvt_perl_interp::rxvt_perl_interp ()
+{
+}
+
+rxvt_perl_interp::~rxvt_perl_interp ()
+{
+ if (perl)
+ {
+ perl_destruct (perl);
+ perl_free (perl);
+ }
+}
+
+void
+rxvt_perl_interp::init ()
+{
+ if (!perl)
+ {
+ char *argv[] = {
+ "",
+ "-edo '" LIBDIR "/urxvt.pm' or ($@ and die $@) or exit 1",
+ };
+
+ perl = perl_alloc ();
+ perl_construct (perl);
+
+ if (perl_parse (perl, xs_init, 2, argv, (char **)NULL)
+ || perl_run (perl))
+ {
+ rxvt_warn ("unable to initialize perl-interpreter, continuing without.\n");
+
+ perl_destruct (perl);
+ perl_free (perl);
+ perl = 0;
+ }
+ }
+}
+
+bool
+rxvt_perl_interp::invoke (rxvt_term *term, hook_type htype, ...)
+{
+ if (!perl)
+ return false;
+
+ if (htype == HOOK_INIT) // first hook ever called
+ term->self = (void *)newSVptr ((void *)term, "urxvt::term");
+ else if (htype == HOOK_DESTROY)
+ {
+ // TODO: clear magic
+ hv_clear ((HV *)SvRV ((SV *)term->self));
+ SvREFCNT_dec ((SV *)term->self);
+ }
+
+ if (!should_invoke [htype])
+ return false;
+
+ dSP;
+ va_list ap;
+
+ va_start (ap, htype);
+
+ ENTER;
+ SAVETMPS;
+
+ PUSHMARK (SP);
+
+ XPUSHs (sv_2mortal (newSVterm (term)));
+ XPUSHs (sv_2mortal (newSViv (htype)));
+
+ for (;;) {
+ data_type dt = (data_type)va_arg (ap, int);
+
+ switch (dt)
+ {
+ case DT_INT:
+ XPUSHs (sv_2mortal (newSViv (va_arg (ap, int))));
+ break;
+
+ case DT_LONG:
+ XPUSHs (sv_2mortal (newSViv (va_arg (ap, long))));
+ break;
+
+ case DT_END:
+ {
+ va_end (ap);
+
+ PUTBACK;
+ int count = call_pv ("urxvt::invoke", G_ARRAY | G_EVAL);
+ SPAGAIN;
+
+ if (count)
+ {
+ SV *status = POPs;
+ count = SvTRUE (status);
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ if (SvTRUE (ERRSV))
+ rxvt_warn ("perl hook %d evaluation error: %s", htype, SvPV_nolen (ERRSV));
+
+ return count;
+ }
+
+ default:
+ rxvt_fatal ("FATAL: unable to pass data type %d\n", dt);
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+MODULE = urxvt PACKAGE = urxvt
+
+PROTOTYPES: ENABLE
+
+BOOT:
+{
+# define set_hookname(sym) av_store (hookname, PP_CONCAT(HOOK_, sym), newSVpv (PP_STRINGIFY(sym), 0))
+ AV *hookname = get_av ("urxvt::HOOKNAME", 1);
+ set_hookname (LOAD);
+ set_hookname (INIT);
+ set_hookname (RESET);
+ set_hookname (START);
+ set_hookname (DESTROY);
+ set_hookname (SEL_BEGIN);
+ set_hookname (SEL_EXTEND);
+ set_hookname (SEL_MAKE);
+ set_hookname (SEL_GRAB);
+ set_hookname (FOCUS_IN);
+ set_hookname (FOCUS_OUT);
+ set_hookname (VIEW_CHANGE);
+ set_hookname (SCROLL_BACK);
+ set_hookname (TTY_ACTIVITY);
+ set_hookname (REFRESH_BEGIN);
+ set_hookname (REFRESH_END);
+
+ sv_setpv (get_sv ("urxvt::LIBDIR", 1), LIBDIR);
+}
+
+void
+set_should_invoke (int htype, int value)
+ CODE:
+ rxvt_perl.should_invoke [htype] = value;
+
+void
+warn (const char *msg)
+ CODE:
+ rxvt_warn ("%s", msg);
+
+void
+fatal (const char *msg)
+ CODE:
+ rxvt_fatal ("%s", msg);
+
+int
+wcswidth (SV *str)
+ CODE:
+{
+ wchar_t *wstr = sv2wcs (str);
+ RETVAL = wcswidth (wstr, wcslen (wstr));
+ free (wstr);
+}
+ OUTPUT:
+ RETVAL
+
+NV
+NOW ()
+ CODE:
+ RETVAL = NOW;
+ OUTPUT:
+ RETVAL
+
+MODULE = urxvt PACKAGE = urxvt::term
+
+void
+rxvt_term::selection_mark (...)
+ PROTOTYPE: $;$$
+ ALIAS:
+ selection_beg = 1
+ selection_end = 2
+ PPCODE:
+{
+ row_col_t &sel = ix == 1 ? THIS->selection.beg
+ : ix == 2 ? THIS->selection.end
+ : THIS->selection.mark;
+
+ if (GIMME_V != G_VOID)
+ {
+ EXTEND (SP, 2);
+ PUSHs (sv_2mortal (newSViv (sel.row)));
+ PUSHs (sv_2mortal (newSViv (sel.col)));
+ }
+
+ if (items == 3)
+ {
+ sel.row = clamp (SvIV (ST (1)), -THIS->nsaved, THIS->nrow - 1);
+ sel.col = clamp (SvIV (ST (2)), 0, THIS->ncol - 1);
+
+ if (ix)
+ THIS->want_refresh = 1;
+ }
+}
+
+int
+rxvt_term::selection_grab (int eventtime)
+
+void
+rxvt_term::selection (SV *newtext = 0)
+ PPCODE:
+{
+ if (GIMME_V != G_VOID)
+ {
+ char *sel = rxvt_wcstoutf8 (THIS->selection.text, THIS->selection.len);
+ SV *sv = newSVpv (sel, 0);
+ SvUTF8_on (sv);
+ free (sel);
+ XPUSHs (sv_2mortal (sv));
+ }
+
+ if (newtext)
+ {
+ free (THIS->selection.text);
+
+ THIS->selection.text = sv2wcs (newtext);
+ THIS->selection.len = wcslen (THIS->selection.text);
+ }
+}
+
+void
+rxvt_term::scr_overlay_new (int x, int y, int w, int h)
+
+void
+rxvt_term::scr_overlay_off ()
+
+void
+rxvt_term::scr_overlay_set_char (int x, int y, U32 text, U32 rend = OVERLAY_RSTYLE)
+ CODE:
+ THIS->scr_overlay_set (x, y, text, rend);
+
+void
+rxvt_term::scr_overlay_set (int x, int y, SV *text)
+ CODE:
+{
+ wchar_t *wtext = sv2wcs (text);
+ THIS->scr_overlay_set (x, y, wtext);
+ free (wtext);
+}
+
+MODULE = urxvt PACKAGE = urxvt::timer
+
+SV *
+timer::new ()
+ CODE:
+ timer *w = new timer;
+ RETVAL = newSVptr ((void *)w, "urxvt::timer");
+ w->self = (HV *)SvRV (RETVAL);
+ OUTPUT:
+ RETVAL
+
+timer *
+timer::cb (SV *cb)
+ CODE:
+ THIS->cb (cb);
+ RETVAL = THIS;
+ OUTPUT:
+ RETVAL
+
+NV
+timer::at ()
+ CODE:
+ RETVAL = THIS->at;
+ OUTPUT:
+ RETVAL
+
+timer *
+timer::set (NV tstamp)
+ CODE:
+ THIS->set (tstamp);
+ RETVAL = THIS;
+ OUTPUT:
+ RETVAL
+
+timer *
+timer::start (NV tstamp = THIS->at)
+ CODE:
+ THIS->start (tstamp);
+ RETVAL = THIS;
+ OUTPUT:
+ RETVAL
+
+timer *
+timer::stop ()
+ CODE:
+ THIS->stop ();
+ RETVAL = THIS;
+ OUTPUT:
+ RETVAL
+
+void
+timer::DESTROY ()
+
+MODULE = urxvt PACKAGE = urxvt::iow
+
+SV *
+iow::new ()
+ CODE:
+ iow *w = new iow;
+ RETVAL = newSVptr ((void *)w, "urxvt::iow");
+ w->self = (HV *)SvRV (RETVAL);
+ OUTPUT:
+ RETVAL
+
+iow *
+iow::cb (SV *cb)
+ CODE:
+ THIS->cb (cb);
+ RETVAL = THIS;
+ OUTPUT:
+ RETVAL
+
+iow *
+iow::fd (int fd)
+ CODE:
+ THIS->fd = fd;
+ RETVAL = THIS;
+ OUTPUT:
+ RETVAL
+
+iow *
+iow::events (short events)
+ CODE:
+ THIS->events = events;
+ RETVAL = THIS;
+ OUTPUT:
+ RETVAL
+
+iow *
+iow::start ()
+ CODE:
+ THIS->start ();
+ RETVAL = THIS;
+ OUTPUT:
+ RETVAL
+
+iow *
+iow::stop ()
+ CODE:
+ THIS->stop ();
+ RETVAL = THIS;
+ OUTPUT:
+ RETVAL
+
+void
+iow::DESTROY ()
+
+
#include <cstring>
+#define PP_CONCAT_(a, b) a ## b
+#define PP_CONCAT(a, b) PP_CONCAT_(a, b)
+#define PP_STRINGIFY_(a) #a
+#define PP_STRINGIFY(a) PP_STRINGIFY_(a)
+
extern class byteorder {
static unsigned int e; // at least 32 bits
public:
#include "../config.h" /* NECESSARY */
#include "rxvt.h" /* NECESSARY */
+#include "rxvtperl.h" /* NECESSARY */
#include <X11/Xmd.h> /* get the typedef for CARD32 */
tabs [col] = col % TABSIZE == 0;
tt_winch ();
+
+ PERL_INVOKE ((this, HOOK_RESET, DT_END));
}
/* ------------------------------------------------------------------------- */
&& (current_screen == PRIMARY || OPTION (Opt_secondaryScroll)))
{
nsaved = min (nsaved + count, saveLines);
+
+ PERL_INVOKE ((this, HOOK_SCROLL_BACK, DT_INT, count, DT_INT, nsaved, DT_END));
+
term_start = (term_start + count) % total_rows;
if (selection.op && current_screen == selection.screen)
int
rxvt_term::scr_changeview (unsigned int oldviewstart)
{
+ PERL_INVOKE ((this, HOOK_VIEW_CHANGE, DT_INT, view_start, DT_END));
+
if (view_start != oldviewstart)
{
want_refresh = 1;
/*
* B: reverse any characters which are selected
*/
+ PERL_INVOKE ((this, HOOK_REFRESH_BEGIN, DT_END));
scr_reverse_selection ();
/*
* H: cleanup selection
*/
scr_reverse_selection ();
+ PERL_INVOKE ((this, HOOK_REFRESH_END, DT_END));
if (refresh_type & SMOOTH_REFRESH)
XFlush (display->display);
if (selection.clicks == 4)
return; /* nothing selected, go away */
+ if (PERL_INVOKE ((this, HOOK_SEL_MAKE, DT_LONG, (long)tm, DT_END)))
+ return;
+
i = (selection.end.row - selection.beg.row + 1) * (ncol + 1);
new_selection_text = (wchar_t *)rxvt_malloc ((i + 4) * sizeof (wchar_t));
selection.len = ofs;
selection.text = (wchar_t *)rxvt_realloc (new_selection_text, (ofs + 1) * sizeof (wchar_t));
+ if (PERL_INVOKE ((this, HOOK_SEL_GRAB, DT_LONG, (long)tm, DT_END)))
+ return;
+
+ selection_grab (tm);
+}
+
+bool
+rxvt_term::selection_grab (Time tm)
+{
+ selection_time = tm;
+
XSetSelectionOwner (display->display, XA_PRIMARY, vt, tm);
if (XGetSelectionOwner (display->display, XA_PRIMARY) == vt)
- display->set_selection_owner (this);
+ {
+ display->set_selection_owner (this);
+ return true;
+ }
else
- rxvt_warn ("can't get primary selection, ignoring.\n");
+ return false;
#if 0
XTextProperty ct;
XFree (ct.value);
}
#endif
-
- selection_time = tm;
}
/* ------------------------------------------------------------------------- */
void
rxvt_term::scr_overlay_new (int x, int y, int w, int h)
{
- if (nrow < 3 || ncol < 3)
+ if (nrow < 1 || ncol < 1)
return;
want_refresh = 1;
};
}
-load_script $_ for grep -f $_, <$LIBDIR/perl-init/*>;
+load_script $_ for grep -f $_, <$LIBDIR/perl-ext/*>;
=back