1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-07-16 15:04:37 -04:00

Merge with /srv/git/elinks.git

This commit is contained in:
Petr Baudis 2006-10-12 11:11:05 +02:00 committed by Petr Baudis
commit 647db326fb
97 changed files with 17102 additions and 7413 deletions

View File

@ -192,6 +192,9 @@ Flemming Frandsen <ff@partyticket.net>
Frédéric L. W. Meunier <0@pervalidus.tk>
Minor documentation updates
Friedel Wolff <fwolff@translate.org.za>
Afrikaans translation
Fuzzy European King <james@place.org>
Fixed lua stack overflow
@ -288,6 +291,7 @@ Karel Kulhavy <clock@atrey.karlin.mff.cuni.cz>
Karel Zak <kzak@redhat.com>
Support for negotiate-auth based on GSSAPI
Minor bug fixes
Karsten Schölzel <kuser@gmx.de>
Event system chief engineer

View File

@ -21,6 +21,7 @@ exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datarootdir = @datarootdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
@ -38,10 +39,14 @@ ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
# The INSTALL substituted by configure can be either absolute or
# relative to the top build directory. Adjust it so that it can
# be used in build subdirectories.
INSTALL = $(if $(patsubst /%,,$(firstword @INSTALL@)),$(top_builddir)/)@INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
UNINSTALL = rm -f
host = @host@
@ -155,8 +160,9 @@ CONFIG_SMB = @CONFIG_SMB@
CONFIG_SPIDERMONKEY = @CONFIG_SPIDERMONKEY@
CONFIG_SSL = @CONFIG_SSL@
CONFIG_SYSMOUSE = @CONFIG_SYSMOUSE@
CONFIG_TRUE_COLOR = @CONFIG_TRUE_COLOR@
CONFIG_URI_REWRITE = @CONFIG_URI_REWRITE@
CONFIG_UTF_8 = @CONFIG_UTF_8@
CONFIG_UTF8 = @CONFIG_UTF8@
CONFIG_XBEL_BOOKMARKS = @CONFIG_XBEL_BOOKMARKS@
CONFIG_XMLTO = @CONFIG_XMLTO@
CONFIG_GSSAPI = @CONFIG_GSSAPI@

View File

@ -8,6 +8,7 @@ ifdef MAKE_COLOR
PO_COLOR = $(shell tput setaf 6)
LINK_COLOR = $(shell tput bold;tput setaf 4)
INSTALL_COLOR = $(shell tput setaf 3)
UNINSTALL_COLOR = $(shell tput setaf 1)
END_COLOR = $(shell tput sgr0)
endif
@ -65,6 +66,8 @@ quiet_cmd_installdata = " [$(INSTALL_COLOR)INSTALL$(END_COLOR)] $(RELPATH)
quiet_cmd_installprog = " [$(INSTALL_COLOR)INSTALL$(END_COLOR)] $(RELPATH)$(2) -> $(3)"
cmd_installprog = $(INSTALL_PROGRAM) $(2) $(3)
quiet_cmd_uninstall = " [$(UNINSTALL_COLOR)UNINSTALL$(END_COLOR)] $(3)/$(2)"
cmd_uninstall = $(UNINSTALL) $(3)/$(2)
#############################################################################
# Special handling of conditional variables
@ -166,6 +169,19 @@ ifdef MAN5
$(call ncmd,installdata,$(file),$(DESTDIR)$(mandir)/man5);)
endif
uninstall-default:
ifdef PROGS
@$(foreach file,$(PROGS), \
$(call ncmd,uninstall,$(file),$(DESTDIR)$(bindir));)
endif
ifdef MAN1
@$(foreach file,$(MAN1), \
$(call ncmd,uninstall,$(file),$(DESTDIR)$(mandir)/man1);)
endif
ifdef MAN5
@$(foreach file,$(MAN5), \
$(call ncmd,uninstall,$(file),$(DESTDIR)$(mandir)/man5);)
endif
##############################################################################
# Auto-testing infrastructure
@ -205,7 +221,7 @@ endif
#############################################################################
# Basic recursion and dependencies setup
RULES = all install clean cleanall init check test
RULES = all install clean cleanall init check test uninstall
RULES_LOCAL = $(addsuffix -local,$(RULES))
RULES_REC = $(addsuffix -recursive,$(RULES))
@ -238,6 +254,7 @@ cleanall: $(call rule_deps,cleanall)
init: $(call rule_deps,init)
check: $(call rule_deps,check)
test: $(call rule_deps,test)
uninstall: $(call rule_deps,uninstall)
#############################################################################
# Misc

View File

@ -23,21 +23,54 @@ for i in $codepages; do
echo "/*** $i ***/"
echo
echo 'struct table_entry table_'$i' [] = {'
sed '1,2d
/^[ ]*\(#.*\)\{,1\}$/d
h
s/^[^#]*//
s!#[ ]*\(.*\)!/* \1 */!
x
s/#.*//
y/Xabcdef/xABCDEF/
/^0x[01234567]/d
/[^0x0123456789ABCDEF ]/d
G
s/\n//' "$i.cp" | {
for left in 8 9 A B C D E F; do
for right in 0 1 2 3 4 5 6 7 8 9 A B C D E F; do
eval "high0x$left$right="
done
done
table=
highuse=
while read byte unicode comment; do
if eval "[ \"\$high$byte\" ]"; then
table="$table {$byte, $unicode},${comment+ }$comment
"
else
eval "high$byte=\"\$unicode,\${comment+ }\$comment\""
highuse=1
fi
done
if [ "$highuse" ]; then
printf "const uint16_t highhalf_%s [] = {\n" "$i"
for left in 8 9 A B C D E F; do
for right in 0 1 2 3 4 5 6 7 8 9 A B C D E F; do
eval "printf \"\\t/* %s */ %s\\n\" \"0x$left$right\" \"\${high0x$left$right:-0xFFFF,}\""
done
done
printf "};\n\n"
else
printf "#define highhalf_%s highhalf_NULL\n\n" "$i"
fi
if [ "$table" ]; then
printf "const struct table_entry table_%s [] = {\n%s\t{0, 0}\n};\n" "$i" "$table"
else
printf "#define table_%s table_NULL\n" "$i"
fi
printf "\n"
}
# TODO: Comments inside of the structure are ugliness in a pure clean
# form, and my aesthetical feeling shivers upon glancing at it. However
# we should handle commentless records. A loop with read inside would
# be ideal, I suppose. --pasky
tail -n +3 $i.cp | sed 's/# *\(.*\) *$/\/* \1 *\/ /' | grep '^0x[89a-zA-Z]' \
| sed 's/[ ][ ]*/ /g' | sed 's/[ ]*$/ },/' | sed 's/ /, /' \
| sed 's/^[ ]*/ {/' | grep '.*,.*,'
echo ' {0, 0}'
echo '};'
echo
echo 'unsigned char *aliases_'$i' [] = {'
echo 'unsigned char *const aliases_'$i' [] = {'
head -n 2 $i.cp | tail -n +2 | sed 's/ \+/ /g; s/ $//; s/\", /\",£/g; s/$/,/' | tr "£" "\n" \
| sed 's/^/£/g' | tr "£" "\t"
echo ' NULL
@ -45,11 +78,21 @@ for i in $codepages; do
n=`expr $n + 1`
done
printf "\n/*** NULL ***/\n\n"
printf "const uint16_t highhalf_NULL [] = {\n"
for r in `seq 16`; do
printf "\t0xFFFF,0xFFFF,0xFFFF,0xFFFF, 0xFFFF,0xFFFF,0xFFFF,0xFFFF,\n"
done
printf "};\n\n"
printf "const struct table_entry table_NULL [] = {\n"
printf "\t{0, 0}\n"
printf "};\n"
echo
echo 'struct codepage_desc codepages [] = {'
echo 'const struct codepage_desc codepages [] = {'
for i in $codepages; do
echo ' {"'`head -n 1 $i.cp`'", aliases_'$i', table_'$i'},'
echo ' {"'`head -n 1 $i.cp`'", aliases_'$i', highhalf_'$i', table_'$i'},'
done
echo ' {NULL, NULL, NULL}'

View File

@ -32,4 +32,4 @@ koi8_u
koi8_ru
tcvn5712
viscii
utf_8
utf8

View File

@ -168,7 +168,7 @@ AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_HEADER_TIME
AC_CHECK_HEADERS(wctype.h)
AC_CHECK_HEADERS(wctype.h wchar.h)
AC_CHECK_HEADERS(fcntl.h limits.h time.h unistd.h)
AC_CHECK_HEADERS(sigaction.h)
AC_CHECK_HEADERS(arpa/inet.h)
@ -228,6 +228,32 @@ EL_CHECK_CODE([variadic macros], HAVE_VARIADIC_MACROS,
[a("foo");a("%s","bar");a("%s%s","baz","quux");])
dnl Check for -rdynamic
dnl
dnl gcc -rdynamic calls ld -export-dynamic, which adds all symbols of
dnl the executable to its dynamic symbol table. ELinks uses this for
dnl two purposes:
dnl
dnl 1. If ELinks detects a bug, it can try to display a backtrace by
dnl calling backtrace_symbols_fd() in the GNU libc. The glibc-2.3.6
dnl manual states users of GNU ld must pass -rdynamic to make the
dnl symbols available to the program.
dnl
dnl 2. It would eventually be nice to dynamically load shared
dnl libraries as plugins (bug 73). The plugins must be able to
dnl call ELinks functions. This can be implemented either by
dnl registering all callable functions in ELinks-specific data
dnl structures, or by letting the dynamic linker handle them.
dnl The latter way requires something equivalent to -rdynamic.
dnl
dnl Because backtraces are not needed for correct operation, and bug
dnl 73 is not yet being fixed, the configure script and makefiles
dnl should not complain to the user if they find that -rdynamic does
dnl not work. Besides, it was reported at elinks-users on 2006-09-12
dnl that gcc-3.4.2 with "ld: Software Generation Utilities - Solaris
dnl Link Editors: 5.8-1.284" on Sun Solaris 8 Sparc does not support
dnl -rdynamic but does something equivalent automatically. (This was
dnl tested with "nm -D elinks | grep redraw_from_window".)
dnl
dnl FIXME: This check doesn't work. Something to do with the compiler
dnl happily ignoring it and stderr not being checked for error messages.
AC_MSG_CHECKING([for -rdynamic])
@ -253,7 +279,7 @@ AC_FUNC_MMAP
AC_FUNC_STRFTIME
AC_CHECK_FUNCS(cfmakeraw gethostbyaddr herror strerror)
AC_CHECK_FUNCS(popen uname access chmod alarm timegm mremap)
AC_CHECK_FUNCS(strcasecmp strncasecmp strcasestr strstr strchr strrchr)
AC_CHECK_FUNCS(strcasecmp strncasecmp strcasestr strstr strchr strrchr wcwidth)
AC_CHECK_FUNCS(memmove bcopy stpcpy strdup index isdigit mempcpy memrchr)
AC_CHECK_FUNCS(snprintf vsnprintf asprintf vasprintf)
AC_CHECK_FUNCS(getifaddrs getpwnam inet_pton inet_ntop)
@ -812,7 +838,7 @@ if test "$enable_python" = "yes"; then
cat <<EOF
***********************************************************************
The Python support is incomplete and not so well integrated to ELinks
yet. That means, e.g.., that you have no Python console and there might
yet. That means, e.g., that you have no Python console and there might
not be all the necessary hooks. Also, the Python interface is not too
well tested (success stories heartily welcomed!).
***********************************************************************
@ -1131,7 +1157,7 @@ dnl ===================================================================
dnl Gettext grey zone. Beware.
dnl ===================================================================
ALL_LINGUAS="be bg ca cs da de el es et fi fr gl hr hu id is it lt nl nb pl pt pt_BR ro ru sk sr sv tr uk"
ALL_LINGUAS="af be bg ca cs da de el es et fi fr gl hr hu id is it lt nl nb pl pt pt_BR ro ru sk sr sv tr uk"
AM_GNU_GETTEXT
@ -1239,6 +1265,8 @@ EL_ARG_ENABLE(CONFIG_88_COLORS, 88-colors, [88 colors],
EL_ARG_ENABLE(CONFIG_256_COLORS, 256-colors, [256 colors],
[ --enable-256-colors enable 256 color support])
EL_ARG_ENABLE(CONFIG_TRUE_COLOR, true-color, [true color],
[ --enable-true-color enable true color support])
EL_ARG_ENABLE(CONFIG_EXMODE, exmode, [Exmode interface],
[ --enable-exmode enable exmode (CLI) interface])
@ -1279,7 +1307,7 @@ EL_ARG_ENABLE(CONFIG_OWN_LIBC, own-libc, [Own libc stubs],
EL_ARG_ENABLE(CONFIG_SMALL, small, [Small binary],
[ --enable-small reduce binary size as far as possible (but see the bottom of doc/small.txt!)])
EL_ARG_ENABLE(CONFIG_UTF_8, utf-8, [UTF-8],
EL_ARG_ENABLE(CONFIG_UTF8, utf-8, [UTF-8],
[ --enable-utf-8 enable UTF-8 support])

View File

@ -1,11 +1,12 @@
import re
import sys
dumbprefixes = {
"7th" : "http://7thguard.net/",
"b" : "http://babelfish.altavista.com/babelfish/tr",
"bz" : "http://bugzilla.elinks.cz",
"bug" : "http://bugzilla.elinks.cz",
"d" : "http://www.dict.org",
"b" : "http://babelfish.altavista.com/babelfish/tr/",
"bz" : "http://bugzilla.elinks.cz/",
"bug" : "http://bugzilla.elinks.cz/",
"d" : "http://www.dict.org/",
"g" : "http://www.google.com/",
"gg" : "http://www.google.com/",
"go" : "http://www.google.com/",
@ -21,6 +22,14 @@ dumbprefixes = {
"sd" : "http://www.slashdot.org/"
}
cygwin = re.compile("cygwin\.com")
cygwin_sub1 = re.compile('<body bgcolor="#000000" color="#000000"')
cygwin_sub2 = '<body bgcolor="#ffffff" color="#000000"'
mbank = re.compile('^https://www\.mbank\.com\.pl/ib_navibar_3\.asp')
mbank_sub1 = re.compile('<td valign="top"><img')
mbank_sub2 = '<tr><td valign="top"><img'
google_redirect = re.compile('^http://www\.google\.com/url\?sa=D&q=(.*)')
def goto_url_hook(url, current_url):
global dumbprefixes
@ -30,14 +39,17 @@ def goto_url_hook(url, current_url):
return None
def follow_url_hook(url):
m = google_redirect.search(url)
if m:
return m.group(1)
return None
def pre_format_html_hook(url, html):
if re.search("cygwin\.com", url):
html2 = re.sub("<body bgcolor=\"#000000\" color=\"#000000\"", "<body bgcolor=\"#ffffff\" color=\"#000000\"", html)
if cygwin.search(url):
html2 = cygwin_sub1.sub(cygwin_sub2, html)
return html2
if re.search("https://www.mbank.com.pl/ib_navibar_3.asp", url):
html2 = re.sub("<td valign=\"top\"><img", "<tr><td valign=\"top\"><img", html)
if mbank.search(url):
html2 = mbank_sub1.sub(mbank_sub2, html)
return html2
return None

View File

@ -21,14 +21,14 @@ Below is a template showing how to read the event information
Name: <event name>
Managed By: <what part of the code registers and unregister the event>
Arguments:
<the order and type of the arguments>
Triggered When:
<short description of when the event is triggered>
Arguments:
<the order and type of the arguments>
Description:
<description of the arguments, what the event does etc.>
@ -113,6 +113,47 @@ Description:
Open Lua console dialog.
-------------------------------------------------------------------------------
Name: flush-caches
Managed By: The scripting subsystem/backends
Triggered When:
Elinks is going to free its caches. This happens when the user chooses
ACT_MAIN_CACHE_MINIMIZE, but currently also on ACT_MAIN_FORGET_CREDENTIALS
and when ELinks is quitting.
Arguments:
None
Description:
If scripting backends hold pointers to cache entries, they should try
to release those pointers so that ELinks can free the entries. This
may involve a full garbage collection. Also, if backends have some
caches of their own, they should flush them.
-------------------------------------------------------------------------------
Name: follow-url
Managed By: The scripting subsystem/backends
Triggered When:
The user decides to load some document by following a link, entering an URL
in the goto URL dialog, loading frames from a frameset (?) etc.
Arguments:
unsigned char **url, struct session *ses
Description:
If another URL than @url should be followed it is passed by setting @url.
If @url is changed the event propagation should be ended.
Valid values for @url includes:
- leaving @url unchanged if the original URL should be followed;
- NULL if no URL should be followed; or
- a dynamically allocated new URL to be followed instead.
-------------------------------------------------------------------------------
Name: free-history
Managed By: The scripting subsystem/backends
@ -128,6 +169,24 @@ Description:
Allow a subsystem to free its history lists.
-------------------------------------------------------------------------------
Name: get-proxy
Managed By: The scripting subsystem/backends
Triggered When:
Determining what proxy, if any, should be used to load a requested URL.
Arguments:
unsigned char **new_proxy_url, unsigned char *url
Description:
Possible values for @new_proxy_url includes:
- a dynamically allocated string with the format proxy:port;
- an empty string (dynamically allocated!) to use no proxy; or
- NULL to use the default proxies.
-------------------------------------------------------------------------------
Name: goto-url
Managed By: The scripting subsystem/backends
@ -154,45 +213,6 @@ Description:
NULL the hook handler should assume no current URI and no suitable UI set up
(i.e., starting up yet or -dump).
-------------------------------------------------------------------------------
Name: follow-url
Managed By: The scripting subsystem/backends
Triggered When:
The user decides to load some document by following a link, entering an URL
in the goto URL dialog, loading frames from a frameset (?) etc.
Arguments:
unsigned char **url, struct session *ses
Description:
If another URL than @url should be followed it is passed by setting @url.
If @url is changed the event propagation should be ended.
Valid values for @url includes:
- leaving @url unchanged if the original URL should be followed;
- NULL if no URL should be followed; or
- a dynamically allocated new URL to be followed instead.
-------------------------------------------------------------------------------
Name: get-proxy
Managed By: The scripting subsystem/backends
Triggered When:
Determining what proxy, if any, should be used to load a requested URL.
Arguments:
unsigned char **new_proxy_url, unsigned char *url
Description:
Possible values for @new_proxy_url includes:
- a dynamically allocated string with the format proxy:port;
- an empty string (dynamically allocated!) to use no proxy; or
- NULL to use the default proxies.
-------------------------------------------------------------------------------
Name: periodic-saving
Managed By: No maintainer but used by lowlevel/timer.*

View File

@ -497,6 +497,14 @@ CONFIG_88_COLORS=no
CONFIG_256_COLORS=no
### True color
#
# Define to add support for True color. Note that only terminal capable to show
# it is konsole from kdebase-3.5.4. This mode eats a lot of memory.
#
# Default: disabled
CONFIG_TRUE_COLOR=no
### Ex-mode Interface
#
@ -618,7 +626,7 @@ CONFIG_SMALL=no
#
# Default: disabled
CONFIG_UTF_8=no
CONFIG_UTF8=no

View File

@ -108,6 +108,11 @@ install-local: all-local
$(call ncmd,installdata,$(lang).gmo,$(DESTDIR)$(localedir)/$(lang)/LC_MESSAGES/$(PACKAGE).mo); \
)
uninstall-local:
@$(foreach lang,$(basename $(if $(strip $(PO)),$(PO),$(CATALOGS))), \
$(call ncmd,uninstall,$(PACKAGE).mo,$(DESTDIR)$(localedir)/$(lang)/LC_MESSAGES); \
)
clean-local:
@rm -f $(PACKAGE).po *.new.po $(srcdir)$(POTFILES_ABS_LIST)

7965
po/af.po Normal file

File diff suppressed because it is too large Load Diff

2032
po/fi.po

File diff suppressed because it is too large Load Diff

873
po/fr.po

File diff suppressed because it is too large Load Diff

1122
po/pl.po

File diff suppressed because it is too large Load Diff

View File

@ -77,7 +77,7 @@ add_dlg_button_do(struct dialog *dlg, unsigned char *text, int flags,
}
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
static void
buttons_width(struct widget_data *widget_data, int n,
int *minwidth, int *maxwidth, int utf8)
@ -85,25 +85,25 @@ buttons_width(struct widget_data *widget_data, int n,
static void
buttons_width(struct widget_data *widget_data, int n,
int *minwidth, int *maxwidth)
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
int maxw = -BUTTON_HSPACING;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
int button_lr_len = utf8_ptr2cells(BUTTON_LEFT, NULL)
+ utf8_ptr2cells(BUTTON_RIGHT, NULL);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
assert(n > 0);
if_assert_failed return;
while (n--) {
int minw;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (utf8)
minw = utf8_ptr2cells((widget_data++)->widget->text, NULL)
+ BUTTON_HSPACING + button_lr_len;
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
minw = (widget_data++)->widget->info.button.textlen
+ BUTTON_HSPACING + BUTTON_LR_LEN;
@ -128,41 +128,41 @@ dlg_format_buttons(struct terminal *term,
while (i2 < n) {
mw = 0;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
buttons_width(widget_data1, i2 - i1 + 1, NULL, &mw,
term->utf8);
#else
buttons_width(widget_data1, i2 - i1 + 1, NULL, &mw);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
if (mw <= w) i2++;
else break;
}
mw = 0;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
buttons_width(widget_data1, i2 - i1, NULL, &mw, term->utf8);
#else
buttons_width(widget_data1, i2 - i1, NULL, &mw);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
if (rw) int_bounds(rw, mw, w);
if (!format_only) {
int i;
int p = x + (align == ALIGN_CENTER ? (w - mw) / 2 : 0);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
int button_lr_len = utf8_ptr2cells(BUTTON_LEFT, NULL)
+ utf8_ptr2cells(BUTTON_RIGHT, NULL);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
for (i = i1; i < i2; i++) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
set_box(&widget_data[i].box,
p, *y,
utf8_ptr2cells(widget_data[i].widget->text, NULL)
+ button_lr_len, BUTTON_HEIGHT);
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
set_box(&widget_data[i].box,
p, *y,
widget_data[i].widget->info.button.textlen
@ -195,7 +195,7 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
}
if (!color || !shortcut_color) return EVENT_PROCESSED;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
int button_left_len = utf8_ptr2cells(BUTTON_LEFT, NULL);
int button_right_len = utf8_ptr2cells(BUTTON_RIGHT, NULL);
@ -205,7 +205,7 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
(button_left_len + button_right_len);
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
x = pos->x + BUTTON_LEFT_LEN;
len = widget_data->box.width - BUTTON_LR_LEN;
@ -221,7 +221,7 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
attr = get_opt_bool("ui.dialogs.underline_button_shortcuts")
? SCREEN_ATTR_UNDERLINE : 0;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
if (hk_pos >= 0) {
int hk_bytes = utf8charlen(&text[hk_pos+1]);
@ -266,7 +266,7 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
0, color);
}
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
if (hk_pos >= 0) {
int right = widget_data->widget->info.button.truetextlen - hk_pos - 1;
@ -285,7 +285,7 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
draw_text(term, x + 1, pos->y, &text[1], len - 1, 0, color);
}
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
int text_cells = utf8_ptr2cells(widget_data->widget->text, NULL);
int hk = (widget_data->widget->info.button.hotkey_pos >= 0);
@ -293,7 +293,7 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
draw_text(term, x + text_cells - hk, pos->y,
BUTTON_RIGHT, BUTTON_RIGHT_LEN, 0, color);
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
draw_text(term, x + len, pos->y, BUTTON_RIGHT,
BUTTON_RIGHT_LEN, 0, color);
if (sel) {

View File

@ -101,19 +101,19 @@ redraw_dialog(struct dialog_data *dlg_data, int layout)
int titlecells = titlelen;
int x, y;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
titlecells = utf8_ptr2cells(title,
&title[titlelen]);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
titlecells = int_min(box.width - 2, titlecells);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
titlelen = utf8_cells2bytes(title, titlecells,
NULL);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
x = (box.width - titlecells) / 2 + box.x;
y = box.y - 1;
@ -285,34 +285,58 @@ select_button_by_flag(struct dialog_data *dlg_data, int flag)
static void
select_button_by_key(struct dialog_data *dlg_data)
{
unsigned char key;
term_event_char_T key;
#ifdef CONFIG_UTF8
int codepage;
#endif
struct widget_data *widget_data;
struct term_event *ev = dlg_data->term_event;
if (!check_kbd_label_key(ev)) return;
#ifdef CONFIG_UTF8
key = unicode_fold_label_case(get_kbd_key(ev));
codepage = get_opt_codepage_tree(dlg_data->win->term->spec, "charset");
#else
key = toupper(get_kbd_key(ev));
#endif
foreach_widget(dlg_data, widget_data) {
int hk_pos;
unsigned char *hk_ptr;
term_event_char_T hk_char;
if (widget_data->widget->type != WIDGET_BUTTON)
continue;
hk_ptr = widget_data->widget->text;
if (!*hk_ptr)
continue;
/* We first try to match marked hotkey if there is
* one else we fallback to first character in button
* name. */
hk_pos = widget_data->widget->info.button.hotkey_pos;
if (hk_pos >= 0) {
if (toupper(widget_data->widget->text[hk_pos + 1]) != key)
continue;
} else {
if (toupper(widget_data->widget->text[0]) != key)
continue;
}
if (hk_pos >= 0)
hk_ptr += hk_pos + 1;
select_dlg_item(dlg_data, widget_data);
break;
#ifdef CONFIG_UTF8
hk_char = cp_to_unicode(codepage, &hk_ptr,
strchr(hk_ptr, '\0'));
/* hk_char can be UCS_NO_CHAR only if the text of the
* widget is not in the expected codepage. */
assert(hk_char != UCS_NO_CHAR);
if_assert_failed continue;
hk_char = unicode_fold_label_case(hk_char);
#else
hk_char = toupper(*hk_ptr);
#endif
if (hk_char == key) {
select_dlg_item(dlg_data, widget_data);
break;
}
}
}
@ -593,11 +617,11 @@ generic_dialog_layouter(struct dialog_data *dlg_data)
int height = dialog_max_height(term);
int x = 0, y, rw;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
rw = int_min(w, utf8_ptr2cells(dlg_data->dlg->title, NULL));
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
rw = int_min(w, strlen(dlg_data->dlg->title));
y = dlg_data->dlg->layout.padding_top ? 0 : -1;
@ -638,15 +662,15 @@ draw_dialog(struct dialog_data *dlg_data, int width, int height)
/* Draw shadow */
draw_shadow(term, &dlg_data->box,
get_bfu_color(term, "dialog.shadow"), 2, 1);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
fix_dwchar_around_box(term, &dlg_data->box, 0, 2, 1);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
else if(term->utf8)
fix_dwchar_around_box(term, &dlg_data->box, 0, 0, 0);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
}
static void

View File

@ -39,14 +39,14 @@ dlg_format_group(struct terminal *term,
int label_length;
int label_padding;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
if (text && *text)
label_length = utf8_ptr2cells(text, NULL);
else
label_length = 0;
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
label_length = (text && *text) ? strlen(text) : 0;
label_padding = (label_length > 0);
@ -54,12 +54,12 @@ dlg_format_group(struct terminal *term,
if (widget_data->widget->type == WIDGET_CHECKBOX) {
width = CHECKBOX_LEN;
} else if (widget_is_textfield(widget_data)) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
width = utf8_ptr2cells(widget_data->widget->data,
NULL);
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
width = widget_data->widget->datalen;
} else {
/* TODO: handle all widget types. */
@ -81,7 +81,7 @@ dlg_format_group(struct terminal *term,
if (widget_data->widget->type == WIDGET_CHECKBOX) {
/* Draw text at right of checkbox. */
if (label_length) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
int lb = utf8_cells2bytes(
text,
@ -92,7 +92,7 @@ dlg_format_group(struct terminal *term,
*y, text, lb, 0,
color);
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
draw_text(term, xpos + width
+ label_padding,
@ -107,7 +107,7 @@ dlg_format_group(struct terminal *term,
} else if (widget_is_textfield(widget_data)) {
/* Draw label at left of widget. */
if (label_length) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
int lb = utf8_cells2bytes(
text,
@ -116,7 +116,7 @@ dlg_format_group(struct terminal *term,
draw_text(term, xpos, *y,
text, lb, 0, color);
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
draw_text(term, xpos, *y,
text, label_length,
@ -148,11 +148,11 @@ group_layouter(struct dialog_data *dlg_data)
int y = 0;
int n = dlg_data->number_of_widgets - 2;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
rw = int_min(w, utf8_ptr2cells(dlg_data->dlg->title, NULL));
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
rw = int_min(w, strlen(dlg_data->dlg->title));
dlg_format_group(term, dlg_data->widgets_data, n,

View File

@ -122,10 +122,15 @@ refresh_hotkeys(struct terminal *term, struct menu *menu)
}
static int
check_hotkeys_common(struct menu *menu, unsigned char hotkey, struct terminal *term,
check_hotkeys_common(struct menu *menu, term_event_char_T hotkey, struct terminal *term,
int check_mode)
{
#ifdef CONFIG_UTF8
unicode_val_T key = unicode_fold_label_case(hotkey);
int codepage = get_opt_codepage_tree(term->spec, "charset");
#else
unsigned char key = toupper(hotkey);
#endif
int i = menu->selected;
int start;
@ -138,6 +143,9 @@ check_hotkeys_common(struct menu *menu, unsigned char hotkey, struct terminal *t
do {
struct menu_item *item;
unsigned char *text;
#ifdef CONFIG_UTF8
unicode_val_T items_hotkey;
#endif
int found;
if (++i == menu->size) i = 0;
@ -150,6 +158,8 @@ check_hotkeys_common(struct menu *menu, unsigned char hotkey, struct terminal *t
if (mi_text_translate(item)) text = _(text, term);
if (!text || !*text) continue;
/* Change @text to point to the character that should
* be compared to @key. */
if (check_mode == 0) {
/* Does the key (upcased) matches one of the
* hotkeys in menu ? */
@ -158,14 +168,26 @@ check_hotkeys_common(struct menu *menu, unsigned char hotkey, struct terminal *t
#ifdef CONFIG_DEBUG
if (key_pos < 0) key_pos = -key_pos;
#endif
found = (key_pos && (toupper(text[key_pos]) == key));
if (!key_pos) continue;
text += key_pos;
} else {
/* Does the key (upcased) matches first letter
* of menu item left text ? */
found = (toupper(*text) == key);
}
/* Compare @key to the character to which @text points. */
#ifdef CONFIG_UTF8
items_hotkey = cp_to_unicode(codepage, &text,
strchr(text, '\0'));
/* items_hotkey can be UCS_NO_CHAR only if the text of
* the menu item is not in the expected codepage. */
assert(items_hotkey != UCS_NO_CHAR);
if_assert_failed continue;
found = (unicode_fold_label_case(items_hotkey) == key);
#else
found = (toupper(*text) == key);
#endif
if (found) {
menu->selected = i;
return 1;
@ -178,7 +200,7 @@ check_hotkeys_common(struct menu *menu, unsigned char hotkey, struct terminal *t
/* Returns true if a hotkey was found in the menu, and set menu->selected. */
int
check_hotkeys(struct menu *menu, unsigned char key, struct terminal *term)
check_hotkeys(struct menu *menu, term_event_char_T key, struct terminal *term)
{
return check_hotkeys_common(menu, key, term, 0);
}
@ -188,7 +210,7 @@ check_hotkeys(struct menu *menu, unsigned char key, struct terminal *term)
* to selected entry.
* It returns 1 if found and set menu->selected. */
int
check_not_so_hot_keys(struct menu *menu, unsigned char key, struct terminal *term)
check_not_so_hot_keys(struct menu *menu, term_event_char_T key, struct terminal *term)
{
return check_hotkeys_common(menu, key, term, 1);
}

View File

@ -3,6 +3,8 @@
#ifndef EL__BFU_HOTKEY_H
#define EL__BFU_HOTKEY_H
#include "terminal/kbd.h"
struct menu;
struct terminal;
@ -13,7 +15,7 @@ void clear_hotkeys_cache(struct menu *menu);
#endif
void refresh_hotkeys(struct terminal *term, struct menu *menu);
/* int is_hotkey(struct menu_item *item, unsigned char key, struct terminal *term); */
int check_hotkeys(struct menu *menu, unsigned char hotkey, struct terminal *term);
int check_not_so_hot_keys(struct menu *menu, unsigned char key, struct terminal *term);
int check_hotkeys(struct menu *menu, term_event_char_T hotkey, struct terminal *term);
int check_not_so_hot_keys(struct menu *menu, term_event_char_T key, struct terminal *term);
#endif

View File

@ -266,11 +266,11 @@ display_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data,
struct terminal *term = dlg_data->win->term;
struct color_pair *color;
int sel = is_selected_widget(dlg_data, widget_data);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
int len = 0, left = 0;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
unsigned char *t = widget_data->cdata;
int p = widget_data->info.field.cpos;
@ -280,7 +280,7 @@ display_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data,
int_lower_bound(&left, 0);
widget_data->info.field.vpos = utf8_cells2bytes(t, left, NULL);
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
int_bounds(&widget_data->info.field.vpos,
widget_data->info.field.cpos - widget_data->box.width + 1,
@ -297,21 +297,21 @@ display_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data,
unsigned char *text = widget_data->cdata + widget_data->info.field.vpos;
int len, w;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8 && !hide)
len = utf8_ptr2cells(text, NULL);
else if (term->utf8)
len = utf8_ptr2chars(text, NULL);
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
len = strlen(text);
w = int_min(len, widget_data->box.width);
if (!hide) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
w = utf8_cells2bytes(text, w, NULL);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
draw_text(term, widget_data->box.x, widget_data->box.y,
text, w, 0, color);
} else {
@ -327,11 +327,11 @@ display_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data,
if (sel) {
int x;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
x = widget_data->box.x + len - left;
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
x = widget_data->box.x + widget_data->info.field.cpos - widget_data->info.field.vpos;
set_cursor(term, x, widget_data->box.y, 0);
@ -473,15 +473,15 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
case ACT_EDIT_RIGHT:
if (widget_data->info.field.cpos < strlen(widget_data->cdata)) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
unsigned char *next = widget_data->cdata + widget_data->info.field.cpos;
unsigned char *end = strchr(next, '\0');
utf_8_to_unicode(&next, end);
utf8_to_unicode(&next, end);
widget_data->info.field.cpos = (int)(next - widget_data->cdata);
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
widget_data->info.field.cpos++;
}
@ -491,7 +491,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
case ACT_EDIT_LEFT:
if (widget_data->info.field.cpos > 0)
widget_data->info.field.cpos--;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (widget_data->info.field.cpos && term->utf8) {
unsigned char *t = widget_data->cdata;
unsigned char *t2 = t;
@ -504,7 +504,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
widget_data->info.field.cpos = (int)(t2 - t);
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
goto display_field;
case ACT_EDIT_HOME:
@ -516,7 +516,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
goto display_field;
case ACT_EDIT_BACKSPACE:
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (widget_data->info.field.cpos && term->utf8) {
/* XXX: stolen from src/viewer/text/form.c */
/* FIXME: This isn't nice. We remove last byte
@ -528,7 +528,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
int old = widget_data->info.field.cpos;
while(1) {
data = utf_8_to_unicode(&text, end);
data = utf8_to_unicode(&text, end);
if (data == UCS_NO_CHAR)
break;
}
@ -543,7 +543,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
}
goto display_field;
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
if (widget_data->info.field.cpos) {
memmove(widget_data->cdata + widget_data->info.field.cpos - 1,
widget_data->cdata + widget_data->info.field.cpos,
@ -558,20 +558,20 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
if (widget_data->info.field.cpos >= cdata_len) goto display_field;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
unsigned char *end = widget_data->cdata + cdata_len;
unsigned char *text = widget_data->cdata + widget_data->info.field.cpos;
unsigned char *old = text;
utf_8_to_unicode(&text, end);
utf8_to_unicode(&text, end);
if (old != text) {
memmove(old, text,
(int)(end - text) + 1);
}
goto display_field;
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
memmove(widget_data->cdata + widget_data->info.field.cpos,
widget_data->cdata + widget_data->info.field.cpos + 1,
cdata_len - widget_data->info.field.cpos + 1);
@ -680,12 +680,12 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
if (check_kbd_textinput_key(ev)) {
unsigned char *text = widget_data->cdata;
int textlen = strlen(text);
#ifdef CONFIG_UTF_8
const unsigned char *ins = encode_utf_8(get_kbd_key(ev));
#ifdef CONFIG_UTF8
const unsigned char *ins = encode_utf8(get_kbd_key(ev));
int inslen = utf8charlen(ins);
#else /* !CONFIG_UTF_8 */
#else /* !CONFIG_UTF8 */
const int inslen = 1;
#endif /* !CONFIG_UTF_8 */
#endif /* !CONFIG_UTF8 */
if (textlen >= widget_data->widget->datalen - inslen)
goto display_field;
@ -695,11 +695,11 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
text += widget_data->info.field.cpos;
memmove(text + inslen, text, textlen + 1);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
memcpy(text, ins, inslen);
#else /* !CONFIG_UTF_8 */
#else /* !CONFIG_UTF8 */
*text = get_kbd_key(ev);
#endif /* !CONFIG_UTF_8 */
#endif /* !CONFIG_UTF8 */
widget_data->info.field.cpos += inslen;
goto display_field;
}

View File

@ -462,11 +462,11 @@ display_listbox_item(struct listbox_item *item, void *data_, int *offset)
len = strlen(text);
int_upper_bound(&len, int_max(0, data->widget_data->box.width - depth * 5));
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (data->term->utf8)
len_bytes = utf8_cells2bytes(text, len, NULL);
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
len_bytes = len;
draw_text(data->term, x, y, text, len_bytes, 0, text_color);

View File

@ -200,12 +200,12 @@ get_menuitem_text_width(struct terminal *term, struct menu_item *mi)
if (!text[0]) return 0;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
return L_TEXT_SPACE + utf8_ptr2cells(text, NULL)
- !!mi->hotkey_pos + R_TEXT_SPACE;
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
return L_TEXT_SPACE + strlen(text)
- !!mi->hotkey_pos + R_TEXT_SPACE;
}
@ -382,13 +382,13 @@ draw_menu_left_text(struct terminal *term, unsigned char *text, int len,
if (len < 0) len = strlen(text);
if (!len) return;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
max_len = utf8_cells2bytes(text, w, NULL);
if (max_len <= 0)
return;
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
max_len = w;
if (len > max_len) len = max_len;
@ -410,7 +410,7 @@ draw_menu_left_text_hk(struct terminal *term, unsigned char *text,
int xbase = x + L_TEXT_SPACE;
int w = width - (L_TEXT_SPACE + R_TEXT_SPACE);
int hk_state = 0;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
unsigned char *text2, *end;
#endif
@ -430,9 +430,9 @@ draw_menu_left_text_hk(struct terminal *term, unsigned char *text,
hk_color_sel = tmp;
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) goto utf8;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
for (x = 0; x - !!hk_state < w && (c = text[x]); x++) {
if (!hk_state && x == hotkey_pos - 1) {
@ -454,14 +454,14 @@ draw_menu_left_text_hk(struct terminal *term, unsigned char *text,
}
return;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
utf8:
end = strchr(text, '\0');
text2 = text;
for (x = 0; x - !!hk_state < w && *text2; x++) {
unicode_val_T data;
data = utf_8_to_unicode(&text2, end);
data = utf8_to_unicode(&text2, end);
if (!hk_state && (int)(text2 - text) == hotkey_pos) {
hk_state = 1;
continue;
@ -517,7 +517,7 @@ utf8:
}
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
}
static inline void
@ -560,15 +560,15 @@ display_menu(struct terminal *term, struct menu *menu)
/* Draw shadow */
draw_shadow(term, &menu->box,
get_bfu_color(term, "dialog.shadow"), 2, 1);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
fix_dwchar_around_box(term, &box, 1, 2, 1);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
else if(term->utf8)
fix_dwchar_around_box(term, &box, 1, 0, 0);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
menu_height = box.height;
box.height = 1;
@ -869,8 +869,8 @@ static void
search_menu(struct menu *menu)
{
struct terminal *term = menu->win->term;
struct window *tab = get_current_tab(term);
struct session *ses = tab ? tab->data : NULL;
struct window *current_tab = get_current_tab(term);
struct session *ses = current_tab ? current_tab->data : NULL;
unsigned char *prompt = _("Search menu/", term);
if (menu->size < 1 || !ses) return;
@ -948,7 +948,7 @@ menu_kbd_handler(struct menu *menu, struct term_event *ev)
default:
{
int key = get_kbd_key(ev);
term_event_key_T key = get_kbd_key(ev);
if (is_kbd_fkey(key)
|| check_kbd_modifier(ev, KBD_MOD_ALT)) {
@ -1114,23 +1114,23 @@ display_mainmenu(struct terminal *term, struct menu *menu)
text = _(text, term);
textlen = strlen(text) - !!l;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
screencnt = utf8_ptr2cells(text, NULL) - !!l;
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
screencnt = textlen;
if (selected) {
color = selected_color;
box.x = p;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
box.width = L_MAINTEXT_SPACE + L_TEXT_SPACE
+ screencnt
+ R_TEXT_SPACE + R_MAINTEXT_SPACE;
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
box.width = L_MAINTEXT_SPACE + L_TEXT_SPACE
+ textlen
+ R_TEXT_SPACE + R_MAINTEXT_SPACE;
@ -1163,7 +1163,7 @@ display_mainmenu(struct terminal *term, struct menu *menu)
menu->last = i - 1;
int_lower_bound(&menu->last, menu->first);
if (menu->last < menu->size - 1) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
struct screen_char *schar;

View File

@ -36,13 +36,13 @@ add_dlg_text(struct dialog *dlg, unsigned char *text,
}
/* Returns length of substring (from start of @text) before a split. */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
static inline int
split_line(unsigned char *text, int max_width, int *cells, int utf8)
#else
static inline int
split_line(unsigned char *text, int max_width, int *cells)
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
unsigned char *split = text;
int cells_save = *cells;
@ -52,7 +52,7 @@ split_line(unsigned char *text, int max_width, int *cells)
while (*split && *split != '\n') {
unsigned char *next_split;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (utf8) {
unsigned char *next_char_begin = split
+ utf8charlen(split);
@ -74,7 +74,7 @@ split_line(unsigned char *text, int max_width, int *cells)
next_char_begin += utf8charlen(next_split);
}
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
next_split = split + 1;
@ -88,7 +88,7 @@ split_line(unsigned char *text, int max_width, int *cells)
* meaning there's no splittable substring under
* requested width. */
if (split == text) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (utf8) {
int m_bytes = utf8_cells2bytes(text,
max_width,
@ -97,7 +97,7 @@ split_line(unsigned char *text, int max_width, int *cells)
cells_save = utf8_ptr2cells(text,
split);
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
split = &text[max_width];
cells_save = max_width;
@ -106,9 +106,9 @@ split_line(unsigned char *text, int max_width, int *cells)
/* FIXME: Function ispunct won't work correctly
* with UTF-8 characters. We need some similar
* function for UTF-8 characters. */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (!utf8)
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
/* Give preference to split on a
* punctuation if any. Note that most
@ -150,13 +150,13 @@ split_line(unsigned char *text, int max_width, int *cells)
#define realloc_lines(x, o, n) mem_align_alloc(x, o, n, LINES_GRANULARITY)
/* Find the start of each line with the current max width */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
static unsigned char **
split_lines(struct widget_data *widget_data, int max_width, int utf8)
#else
static unsigned char **
split_lines(struct widget_data *widget_data, int max_width)
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
unsigned char *text = widget_data->widget->text;
unsigned char **lines = (unsigned char **) widget_data->cdata;
@ -175,7 +175,7 @@ split_lines(struct widget_data *widget_data, int max_width)
if (isspace(*text)) text++;
if (!*text) break;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
width = split_line(text, max_width, &cells, utf8);
#else
width = split_line(text, max_width, &cells);
@ -228,11 +228,11 @@ dlg_format_text_do(struct terminal *term, unsigned char *text,
firstline = 0;
if (!*text) break;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
line_width = split_line(text, width, &cells, term->utf8);
#else
line_width = split_line(text, width, &cells);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* split_line() may return 0. */
if (line_width < 1) {
@ -286,7 +286,7 @@ dlg_format_text(struct terminal *term, struct widget_data *widget_data,
/* Ensure that the current split is valid but don't
* split if we don't have to */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (widget_data->box.width != width
&& !split_lines(widget_data, width, term->utf8))
return;

7
src/cache/cache.c vendored
View File

@ -181,6 +181,13 @@ get_validated_cache_entry(struct uri *uri, enum cache_mode cache_mode)
if (!cached || cached->incomplete)
return NULL;
if (uri->protocol == PROTOCOL_HTTP || uri->protocol == PROTOCOL_HTTPS
|| uri->protocol == PROTOCOL_FILE /* CGI */) {
if (cached->last_modified && cache_mode == CACHE_MODE_NORMAL)
return NULL;
}
/* A bit of a gray zone. Delete the entry if the it has the stricktest
* cache mode and we don't want the most aggressive mode or we have to
* remove the redirect or the entry expired. Please enlighten me.

View File

@ -817,26 +817,41 @@ really_add_keybinding(void *data, unsigned char *keystroke)
struct kbdbind_add_hop *hop = data;
action_id_T action_id;
/* check_keystroke() has parsed @keystroke to @hop->kbd. */
if (keybinding_exists(hop->keymap_id, &hop->kbd, &action_id)
&& action_id != ACT_MAIN_NONE) {
struct kbdbind_add_hop *new_hop;
struct string canonical;
/* Same keystroke for same action, just return. */
if (action_id == hop->action_id) return;
/* @*hop is on the memory_list of the input_dialog,
* which will be closed when this function returns. */
new_hop = new_hop_from(hop);
if (!new_hop) return; /* out of mem */
/* Try to convert the parsed keystroke back to a
* string, so that the "Keystroke already used" box
* displays the same canonical name as the keybinding
* manager does. If something goes wrong here, then
* canonical.length will probably be 0, in which case
* we'll use the original @keystroke string instead. */
if (init_string(&canonical))
add_keystroke_to_string(&canonical, &hop->kbd, 0);
msg_box(new_hop->term, getml(new_hop, NULL), MSGBOX_FREE_TEXT,
N_("Keystroke already used"), ALIGN_CENTER,
msg_text(new_hop->term, N_("The keystroke \"%s\" "
"is currently used for \"%s\".\n"
"Are you sure you want to replace it?"),
keystroke, get_action_name(hop->keymap_id, action_id)),
"is currently used for \"%s\".\n"
"Are you sure you want to replace it?"),
canonical.length ? canonical.source : keystroke,
get_action_name(hop->keymap_id, action_id)),
new_hop, 2,
N_("~Yes"), really_really_add_keybinding, B_ENTER,
N_("~No"), NULL, B_ESC);
done_string(&canonical); /* safe even if init failed */
return;
}
@ -870,7 +885,7 @@ push_kbdbind_add_button(struct dialog_data *dlg_data,
if (!item || !item->depth) {
info_box(term, 0, N_("Add keybinding"), ALIGN_CENTER,
N_("Need to select a keymap."));
N_("Need to select an action."));
return EVENT_PROCESSED;
}
@ -892,16 +907,15 @@ push_kbdbind_add_button(struct dialog_data *dlg_data,
}
text = msg_text(term,
"Action: %s\n"
"Keymap: %s\n"
"\n"
"Keystroke should be written in the format: "
"[Prefix-]Key\n"
"Prefix: Shift, Ctrl, Alt\n"
"Key: a,b,c,...,1,2,3,...,Space,Up,PageDown,"
"Tab,Enter,Insert,F5,..."
"\n\n"
"Keystroke",
N_("Action: %s\n"
"Keymap: %s\n"
"\n"
"Keystroke should be written in the format: "
"[Shift-][Ctrl-][Alt-]Key\n"
"Key: a,b,c,...,1,2,3,...,Space,Up,PageDown,"
"Tab,Enter,Insert,F5,..."
"\n\n"
"Keystroke"),
get_action_name(hop->keymap_id, hop->action_id),
get_keymap_name(hop->keymap_id));

View File

@ -108,7 +108,7 @@ free_keybinding(struct keybinding *keybinding)
}
#ifdef CONFIG_SCRIPTING
/* TODO: unref function must be implemented. */
/* TODO: unref function must be implemented. This is part of bug 810. */
/* if (keybinding->event != EVENT_NONE)
scripting_unref(keybinding->event); */
#endif
@ -206,7 +206,7 @@ kbd_nm_lookup(enum keymap_id keymap_id, unsigned char *name)
}
static struct keybinding *
kbd_stroke_lookup(enum keymap_id keymap_id, unsigned char *keystroke_str)
kbd_stroke_lookup(enum keymap_id keymap_id, const unsigned char *keystroke_str)
{
struct term_event_keyboard kbd;
@ -230,7 +230,7 @@ static struct keymap keymap_table[] = {
static struct action *
get_action_from_keystroke(enum keymap_id keymap_id,
unsigned char *keystroke_str)
const unsigned char *keystroke_str)
{
struct keybinding *keybinding = kbd_stroke_lookup(keymap_id,
keystroke_str);
@ -240,7 +240,7 @@ get_action_from_keystroke(enum keymap_id keymap_id,
unsigned char *
get_action_name_from_keystroke(enum keymap_id keymap_id,
unsigned char *keystroke_str)
const unsigned char *keystroke_str)
{
struct action *action = get_action_from_keystroke(keymap_id,
keystroke_str);
@ -354,8 +354,8 @@ static struct key key_table[] = {
{ NULL, 0 }
};
long
read_key(unsigned char *key_str)
term_event_key_T
read_key(const unsigned char *key_str)
{
struct key *key;
@ -366,38 +366,70 @@ read_key(unsigned char *key_str)
if (!strcasecmp(key->str, key_str))
return key->num;
return -1;
return KBD_UNDEF;
}
/* Parse the string @s as the name of a keystroke.
* Write the parsed key and modifiers to *@kbd.
* Return >=0 on success, <0 on error. */
int
parse_keystroke(unsigned char *s, struct term_event_keyboard *kbd)
parse_keystroke(const unsigned char *s, struct term_event_keyboard *kbd)
{
if (!strncasecmp(s, "Shift", 5) && (s[5] == '-' || s[5] == '+')) {
/* Shift+a == shiFt-a == Shift-a */
memcpy(s, "Shift-", 6);
kbd->modifier = KBD_MOD_SHIFT;
s += 6;
kbd->modifier = KBD_MOD_NONE;
while (1) {
if (!strncasecmp(s, "Shift", 5) && (s[5] == '-' || s[5] == '+')) {
/* Shift+a == shiFt-a == Shift-a */
kbd->modifier |= KBD_MOD_SHIFT;
s += 6;
} else if (!strncasecmp(s, "Ctrl", 4) && (s[4] == '-' || s[4] == '+')) {
/* Ctrl+a == ctRl-a == Ctrl-a */
memcpy(s, "Ctrl-", 5);
kbd->modifier = KBD_MOD_CTRL;
s += 5;
/* Ctrl-a == Ctrl-A */
if (s[0] && !s[1]) s[0] = toupper(s[0]);
} else if (!strncasecmp(s, "Ctrl", 4) && (s[4] == '-' || s[4] == '+')) {
/* Ctrl+a == ctRl-a == Ctrl-a */
kbd->modifier |= KBD_MOD_CTRL;
s += 5;
} else if (!strncasecmp(s, "Alt", 3) && (s[3] == '-' || s[3] == '+')) {
/* Alt+a == aLt-a == Alt-a */
memcpy(s, "Alt-", 4);
kbd->modifier = KBD_MOD_ALT;
s += 4;
} else if (!strncasecmp(s, "Alt", 3) && (s[3] == '-' || s[3] == '+')) {
/* Alt+a == aLt-a == Alt-a */
kbd->modifier |= KBD_MOD_ALT;
s += 4;
} else {
/* No modifier. */
kbd->modifier = KBD_MOD_NONE;
} else {
/* No modifier. */
break;
}
}
kbd->key = read_key(s);
if ((kbd->modifier & KBD_MOD_CTRL) != 0
&& is_kbd_character(kbd->key) && kbd->key <= 0x7F) {
/* Convert Ctrl-letter keystrokes to upper case,
* e.g. Ctrl-a to Ctrl-A. Do this because terminals
* typically generate the same ASCII control
* characters regardless of Shift and Caps Lock.
*
* However, that applies only to ASCII letters. For
* other Ctrl-letter combinations, there seems to be
* no standard of what the terminal should generate.
* Because it is possible that the terminal does not
* fold case then, ELinks should treat upper-case and
* lower-case variants of such keystrokes as different
* and let the user bind them to separate actions.
* Besides, toupper() might not understand the charset
* of kbd->key.
*
* FIXME: Actually, it is possible that some terminals
* preserve case in all Ctrl-letter keystrokes, even
* for ASCII letters. In particular, the Win32
* console API looks like it might do this. When the
* terminal handling part of ELinks is eventually
* extended to fully support that, it could be a good
* idea to change parse_keystroke() not to fold case,
* and instead make kbd_ev_lookup() or its callers
* search for different variants of the keystroke if
* the original one is not bound to any action. */
kbd->key = toupper(kbd->key);
}
return (kbd->key == KBD_UNDEF) ? -1 : 0;
}
@ -546,7 +578,7 @@ free_keymaps(struct module *xxx)
#ifdef CONFIG_SCRIPTING
static unsigned char *
bind_key_to_event(unsigned char *ckmap, unsigned char *ckey, int event)
bind_key_to_event(unsigned char *ckmap, const unsigned char *ckey, int event)
{
struct term_event_keyboard kbd;
action_id_T action_id;
@ -568,7 +600,7 @@ bind_key_to_event(unsigned char *ckmap, unsigned char *ckey, int event)
}
int
bind_key_to_event_name(unsigned char *ckmap, unsigned char *ckey,
bind_key_to_event_name(unsigned char *ckmap, const unsigned char *ckey,
unsigned char *event_name, unsigned char **err)
{
int event_id;
@ -680,6 +712,7 @@ static struct default_kb default_main_keymap[] = {
{ { KBD_RIGHT, KBD_MOD_CTRL }, ACT_MAIN_LINK_FOLLOW_RELOAD },
{ { KBD_TAB, KBD_MOD_NONE }, ACT_MAIN_FRAME_NEXT },
{ { KBD_TAB, KBD_MOD_ALT }, ACT_MAIN_FRAME_PREV },
{ { KBD_TAB, KBD_MOD_SHIFT}, ACT_MAIN_FRAME_PREV },
{ { KBD_UP, KBD_MOD_NONE }, ACT_MAIN_MOVE_LINK_PREV },
{ { 0, 0 }, 0 }
};
@ -717,6 +750,7 @@ static struct default_kb default_edit_keymap[] = {
{ { KBD_RIGHT, KBD_MOD_NONE }, ACT_EDIT_RIGHT },
{ { KBD_TAB, KBD_MOD_NONE }, ACT_EDIT_NEXT_ITEM },
{ { KBD_TAB, KBD_MOD_ALT }, ACT_EDIT_PREVIOUS_ITEM },
{ { KBD_TAB, KBD_MOD_SHIFT}, ACT_EDIT_PREVIOUS_ITEM },
{ { KBD_UP, KBD_MOD_NONE }, ACT_EDIT_UP },
{ { 0, 0 }, 0 }
};
@ -753,6 +787,7 @@ static struct default_kb default_menu_keymap[] = {
{ { KBD_RIGHT, KBD_MOD_NONE }, ACT_MENU_RIGHT },
{ { KBD_TAB, KBD_MOD_NONE }, ACT_MENU_NEXT_ITEM },
{ { KBD_TAB, KBD_MOD_ALT }, ACT_MENU_PREVIOUS_ITEM },
{ { KBD_TAB, KBD_MOD_SHIFT}, ACT_MENU_PREVIOUS_ITEM },
{ { KBD_UP, KBD_MOD_NONE }, ACT_MENU_UP },
{ { 0, 0 }, 0}
};
@ -863,7 +898,7 @@ get_aliased_action(enum keymap_id keymap_id, unsigned char *action_str)
/* Return 0 when ok, something strange otherwise. */
int
bind_do(unsigned char *keymap_str, unsigned char *keystroke_str,
bind_do(unsigned char *keymap_str, const unsigned char *keystroke_str,
unsigned char *action_str, int is_system_conf)
{
enum keymap_id keymap_id;
@ -887,7 +922,7 @@ bind_do(unsigned char *keymap_str, unsigned char *keystroke_str,
}
unsigned char *
bind_act(unsigned char *keymap_str, unsigned char *keystroke_str)
bind_act(unsigned char *keymap_str, const unsigned char *keystroke_str)
{
enum keymap_id keymap_id;
unsigned char *action;

View File

@ -123,7 +123,7 @@ struct action *get_action(enum keymap_id keymap_id, action_id_T action_id);
unsigned char *get_action_name(enum keymap_id keymap_id, action_id_T action_id);
action_id_T get_action_from_string(enum keymap_id keymap_id, unsigned char *str);
unsigned char *get_action_name_from_keystroke(enum keymap_id keymap_id,
unsigned char *keystroke_str);
const unsigned char *keystroke_str);
static inline unsigned int
action_is_anonymous_safe(enum keymap_id keymap_id, action_id_T action_id)
@ -173,16 +173,23 @@ action_requires_form(enum keymap_id keymap_id, action_id_T action_id)
return action && (action->flags & ACTION_REQUIRE_FORM);
}
long read_key(unsigned char *);
term_event_key_T read_key(const unsigned char *);
unsigned char *get_keymap_name(enum keymap_id);
int parse_keystroke(unsigned char *, struct term_event_keyboard *);
int parse_keystroke(const unsigned char *, struct term_event_keyboard *);
void add_keystroke_to_string(struct string *str, struct term_event_keyboard *kbd, int escape);
/* void add_accesskey_to_string(struct string *str, unicode_val_T accesskey); */
#define add_accesskey_to_string(str, accesskey) do { \
struct term_event_keyboard kbd; \
kbd.key = accesskey; /* FIXME: unicode_val_T to int */ \
kbd.modifier = 0; \
/* FIXME: #ifndef CONFIG_UTF8, kbd.key is encoded in \
* the charset of the terminal, so accesskey should be \
* converted from unicode_val_T to that. \
* #ifdef CONFIG_UTF8, the code is correct. */ \
kbd.key = accesskey; \
/* try_document_key() recognizes only Alt-accesskey \
* combos. */ \
kbd.modifier = KBD_MOD_ALT; \
add_keystroke_to_string(str, &kbd, 0); \
} while (0)
@ -190,12 +197,12 @@ action_id_T kbd_action(enum keymap_id, struct term_event *, int *);
struct keybinding *kbd_ev_lookup(enum keymap_id, struct term_event_keyboard *kbd, int *);
struct keybinding *kbd_nm_lookup(enum keymap_id, unsigned char *);
int bind_do(unsigned char *, unsigned char *, unsigned char *, int);
unsigned char *bind_act(unsigned char *, unsigned char *);
int bind_do(unsigned char *, const unsigned char *, unsigned char *, int);
unsigned char *bind_act(unsigned char *, const unsigned char *);
void bind_config_string(struct string *);
#ifdef CONFIG_SCRIPTING
int bind_key_to_event_name(unsigned char *, unsigned char *, unsigned char *,
int bind_key_to_event_name(unsigned char *, const unsigned char *, unsigned char *,
unsigned char **);
#endif

View File

@ -103,7 +103,7 @@ static struct option_info config_options_info[] = {
"at all unless you are sure what are you doing.\n"
"Note that you can also force a given protocol\n"
"to be used on a per-connection basis by using an URL\n"
"in the style of i.e. http4://elinks.or.cz/.")),
"in the style of e.g. http4://elinks.cz/.")),
#else
INIT_OPT_BOOL("connection", N_("Try IPv4 when connecting"),
"try_ipv4", 0, 1,
@ -111,7 +111,7 @@ static struct option_info config_options_info[] = {
"Do not touch this option.\n"
"Note that you can also force a given protocol\n"
"to be used on a per-connection basis by using an URL\n"
"in the style of i.e. http4://elinks.or.cz/.")),
"in the style of e.g. http4://elinks.cz/.")),
#endif
#ifdef CONFIG_IPV6
@ -120,7 +120,7 @@ static struct option_info config_options_info[] = {
N_("Whether to try to connect to a host over IPv6.\n"
"Note that you can also force a given protocol\n"
"to be used on a per-connection basis by using an URL\n"
"in the style of i.e. http6://elinks.or.cz/.")),
"in the style of e.g. http6://elinks.cz/.")),
#endif
INIT_OPT_INT("connection", N_("Timeout for non-restartable connections"),
@ -636,7 +636,8 @@ static struct option_info config_options_info[] = {
* the INIT_OPT_INT macro; that wouldn't be standard C.
* And they especially cannot be inside the argument list of N_;
* xgettext (GNU gettext-tools) 0.14.3 wouldn't support that. */
#if defined(CONFIG_88_COLORS) && defined(CONFIG_256_COLORS)
/* FIXME: It's totally brainless --witekfl */
#if defined(CONFIG_88_COLORS) && defined(CONFIG_256_COLORS) && !defined(CONFIG_TRUE_COLOR)
INIT_OPT_INT("document.dump", N_("Color mode"),
"color_mode", 0, -1, 3, -1,
N_("Color mode for dumps:\n"
@ -645,7 +646,7 @@ static struct option_info config_options_info[] = {
"1 is 16 color mode\n"
"2 is 88 color mode\n"
"3 is 256 color mode")),
#elif defined(CONFIG_88_COLORS) /* && !defined(CONFIG_256_COLORS) */
#elif defined(CONFIG_88_COLORS) && !defined(CONFIG_256_COLORS) && !defined(CONFIG_TRUE_COLOR)
INIT_OPT_INT("document.dump", N_("Color mode"),
"color_mode", 0, -1, 2, -1,
N_("Color mode for dumps:\n"
@ -653,7 +654,7 @@ static struct option_info config_options_info[] = {
"0 is mono mode\n"
"1 is 16 color mode\n"
"2 is 88 color mode")),
#elif defined(CONFIG_256_COLORS) /* && !defined(CONFIG_88_COLORS) */
#elif defined(CONFIG_256_COLORS) && !defined(CONFIG_88_COLORS) && !defined(CONFIG_TRUE_COLOR)
INIT_OPT_INT("document.dump", N_("Color mode"),
"color_mode", 0, -1, 2, -1,
N_("Color mode for dumps:\n"
@ -661,15 +662,50 @@ static struct option_info config_options_info[] = {
"0 is mono mode\n"
"1 is 16 color mode\n"
"2 is 256 color mode")),
#else /* !defined(CONFIG_88_COLORS) && !defined(CONFIG_256_COLORS) */
#elif !defined(CONFIG_88_COLORS) && !defined(CONFIG_256_COLORS) && !defined(CONFIG_TRUE_COLOR)
INIT_OPT_INT("document.dump", N_("Color mode"),
"color_mode", 0, -1, 1, -1,
N_("Color mode for dumps:\n"
"-1 is standard dump mode\n"
"0 is mono mode\n"
"1 is 16 color mode")),
#elif defined(CONFIG_88_COLORS) && defined(CONFIG_256_COLORS) && defined(CONFIG_TRUE_COLOR)
INIT_OPT_INT("document.dump", N_("Color mode"),
"color_mode", 0, -1, 4, -1,
N_("Color mode for dumps:\n"
"-1 is standard dump mode\n"
"0 is mono mode\n"
"1 is 16 color mode\n"
"2 is 88 color mode\n"
"3 is 256 color mode\n"
"4 is true color mode")),
#elif defined(CONFIG_88_COLORS) && !defined(CONFIG_256_COLORS) && defined(CONFIG_TRUE_COLOR)
INIT_OPT_INT("document.dump", N_("Color mode"),
"color_mode", 0, -1, 3, -1,
N_("Color mode for dumps:\n"
"-1 is standard dump mode\n"
"0 is mono mode\n"
"1 is 16 color mode\n"
"2 is 88 color mode\n"
"3 is true color mode")),
#elif defined(CONFIG_256_COLORS) && !defined(CONFIG_88_COLORS) && defined(CONFIG_TRUE_COLOR)
INIT_OPT_INT("document.dump", N_("Color mode"),
"color_mode", 0, -1, 3, -1,
N_("Color mode for dumps:\n"
"-1 is standard dump mode\n"
"0 is mono mode\n"
"1 is 16 color mode\n"
"2 is 256 color mode\n"
"3 is true color mode")),
#elif !defined(CONFIG_88_COLORS) && !defined(CONFIG_256_COLORS) && defined(CONFIG_TRUE_COLOR)
INIT_OPT_INT("document.dump", N_("Color mode"),
"color_mode", 0, -1, 2, -1,
N_("Color mode for dumps:\n"
"-1 is standard dump mode\n"
"0 is mono mode\n"
"1 is 16 color mode\n"
"2 is true color mode")),
#endif /* !defined(CONFIG_88_COLORS) && !defined(CONFIG_256_COLORS) */
INIT_OPT_STRING("document.dump", N_("Footer"),
"footer", 0, "",
N_("Footer string used in dumps. %u is substituted by URL.")),
@ -862,7 +898,8 @@ static struct option_info config_options_info[] = {
"output to the terminal. The color modes are:\n"
"0 is mono mode, only 2 colors are used\n"
"1 is 16 color mode, uses the common ANSI colors\n"
"2 is 256 color mode, uses XTerm RGB codes")),
"2 is 256 color mode, uses XTerm RGB codes\n"
"3 is true color mode, uses konsole RGB codes.")),
INIT_OPT_BOOL("terminal._template_", N_("Transparency"),
"transparency", 0, 1,

View File

@ -145,11 +145,11 @@ download_dialog_layouter(struct dialog_data *dlg_data)
mem_free(msg);
return;
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
decode_uri(url);
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
decode_uri_for_display(url);
url_len = strlen(url);
@ -302,11 +302,11 @@ get_file_download_text(struct listbox_item *item, struct terminal *term)
uristring = get_uri_string(file_download->uri, URI_PUBLIC);
if (uristring) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
decode_uri(uristring);
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
decode_uri_for_display(uristring);
}

View File

@ -218,7 +218,7 @@ tab_menu(struct session *ses, int x, int y, int place_above_cursor)
{
/* [gettext_accelerator_context(tab_menu)] */
struct menu_item *menu;
int tabs;
int tabs_count;
#ifdef CONFIG_BOOKMARKS
int anonymous = get_cmd_opt_bool("anonymous");
#endif
@ -226,7 +226,7 @@ tab_menu(struct session *ses, int x, int y, int place_above_cursor)
assert(ses && ses->tab);
if_assert_failed return;
tabs = number_of_tabs(ses->tab->term);
tabs_count = number_of_tabs(ses->tab->term);
menu = new_menu(FREE_LIST);
if (!menu) return;
@ -255,14 +255,14 @@ tab_menu(struct session *ses, int x, int y, int place_above_cursor)
/* Keep tab related operations below this separator */
add_menu_separator(&menu);
if (tabs > 1) {
if (tabs_count > 1) {
add_menu_action(&menu, N_("Nex~t tab"), ACT_MAIN_TAB_NEXT);
add_menu_action(&menu, N_("Pre~v tab"), ACT_MAIN_TAB_PREV);
}
add_menu_action(&menu, N_("~Close tab"), ACT_MAIN_TAB_CLOSE);
if (tabs > 1) {
if (tabs_count > 1) {
add_menu_action(&menu, N_("C~lose all tabs but the current"),
ACT_MAIN_TAB_CLOSE_ALL_BUT_CURRENT);
#ifdef CONFIG_BOOKMARKS
@ -364,7 +364,7 @@ do_file_menu(struct terminal *term, void *xxx, void *ses_)
if (o) {
SET_MENU_ITEM(e, N_("Open ~new window"), NULL, ACT_MAIN_OPEN_NEW_WINDOW,
open_in_new_window, send_open_new_window,
(o - 1) ? SUBMENU : 0, 0, HKS_SHOW);
(o - 1) ? SUBMENU : 0, HKS_SHOW, 0);
e++;
}
@ -382,14 +382,14 @@ do_file_menu(struct terminal *term, void *xxx, void *ses_)
x = 1;
if (!anonymous && can_open_os_shell(term->environment)) {
SET_MENU_ITEM(e, N_("~OS shell"), NULL, ACT_MAIN_OPEN_OS_SHELL,
NULL, NULL, 0, 0, HKS_SHOW);
NULL, NULL, 0, HKS_SHOW, 0);
e++;
x = 0;
}
if (can_resize_window(term->environment)) {
SET_MENU_ITEM(e, N_("Resize t~erminal"), NULL, ACT_MAIN_TERMINAL_RESIZE,
NULL, NULL, 0, 0, HKS_SHOW);
NULL, NULL, 0, HKS_SHOW, 0);
e++;
x = 0;
}
@ -581,11 +581,11 @@ query_file(struct session *ses, struct uri *uri, void *data,
add_mime_filename_to_string(&def, uri);
/* Remove the %-ugliness for display */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (ses->tab->term->utf8)
decode_uri_string(&def);
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
decode_uri_string_for_display(&def);
if (interactive) {

View File

@ -60,9 +60,9 @@ charset_list(struct terminal *term, void *xxx, void *ses_)
if (!name) break;
#ifndef CONFIG_UTF_8
#ifndef CONFIG_UTF8
if (is_cp_utf8(i)) continue;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
items++;
add_to_menu(&mi, name, NULL, ACT_MAIN_NONE,
@ -131,14 +131,26 @@ push_save_button(struct dialog_data *dlg_data, struct widget_data *button)
return EVENT_PROCESSED;
}
#if defined(CONFIG_88_COLORS) && defined(CONFIG_256_COLORS)
#define TERMOPT_WIDGETS_COUNT 21
#elif defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS)
#define TERMOPT_WIDGETS_COUNT 20
#if defined(CONFIG_88_COLORS)
#define RADIO_88 1
#else
#define TERMOPT_WIDGETS_COUNT 19
#define RADIO_88 0
#endif
#if defined(CONFIG_256_COLORS)
#define RADIO_256 1
#else
#define RADIO_256 0
#endif
#if defined(CONFIG_TRUE_COLOR)
#define RADIO_TRUE 1
#else
#define RADIO_TRUE 0
#endif
#define TERMOPT_WIDGETS_COUNT (19 + RADIO_88 + RADIO_256 + RADIO_TRUE)
#define TERM_OPTION_VALUE_SIZE (sizeof(union option_value) * TERM_OPTIONS)
void
@ -209,7 +221,9 @@ terminal_options(struct terminal *term, void *xxx, struct session *ses)
#ifdef CONFIG_256_COLORS
add_dlg_radio(dlg, _("256 colors", term), 2, COLOR_MODE_256, &values[TERM_OPT_COLORS].number);
#endif
#ifdef CONFIG_TRUE_COLOR
add_dlg_radio(dlg, _("true color", term), 2, COLOR_MODE_TRUE_COLOR, &values[TERM_OPT_COLORS].number);
#endif
add_dlg_checkbox(dlg, _("Switch fonts for line drawing", term), &values[TERM_OPT_M11_HACK].number);
add_dlg_checkbox(dlg, _("Restrict frames in cp850/852", term), &values[TERM_OPT_RESTRICT_852].number);
add_dlg_checkbox(dlg, _("Block cursor", term), &values[TERM_OPT_BLOCK_CURSOR].number);

View File

@ -74,7 +74,7 @@ update_status(void)
int set_window_title = get_opt_bool("ui.window_title");
int insert_mode = get_opt_bool("document.browse.forms.insert_mode");
struct session *ses;
int tabs = 1;
int tabs_count = 1;
struct terminal *term = NULL;
foreach (ses, sessions) {
@ -85,7 +85,7 @@ update_status(void)
* tab sessions share the same term. */
if (ses->tab->term != term) {
term = ses->tab->term;
tabs = number_of_tabs(term);
tabs_count = number_of_tabs(term);
}
if (status->force_show_title_bar >= 0)
@ -102,8 +102,8 @@ update_status(void)
dirty = 1;
}
if (show_tabs(show_tabs_bar, tabs) != status->show_tabs_bar) {
status->show_tabs_bar = show_tabs(show_tabs_bar, tabs);
if (show_tabs(show_tabs_bar, tabs_count) != status->show_tabs_bar) {
status->show_tabs_bar = show_tabs(show_tabs_bar, tabs_count);
dirty = 1;
}
@ -419,7 +419,7 @@ display_title_bar(struct session *ses, struct terminal *term)
int maxlen = int_max(term->width - 4 - buflen, 0);
int titlelen, titlewidth;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
titlewidth = utf8_ptr2cells(document->title, NULL);
titlewidth = int_min(titlewidth, maxlen);
@ -427,7 +427,7 @@ display_title_bar(struct session *ses, struct terminal *term)
titlelen = utf8_cells2bytes(document->title,
titlewidth, NULL);
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
titlewidth = int_min(strlen(document->title), maxlen);
titlelen = titlewidth;
@ -444,14 +444,14 @@ display_title_bar(struct session *ses, struct terminal *term)
if (title.length) {
int x;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
x = int_max(term->width - 1
- utf8_ptr2cells(title.source,
title.source
+ title.length), 0);
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
x = int_max(term->width - 1 - title.length, 0);
draw_text(term, x, 0, title.source, title.length, 0,

View File

@ -118,7 +118,7 @@ struct link {
#define get_link_name(link) \
(!link_is_form(link) ? (link)->data.name : NULL)
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
struct search {
int x, y;
signed int n; /* RAM is cheap nowadays */
@ -182,7 +182,7 @@ struct document {
struct search **slines1;
struct search **slines2;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
unsigned char buf[7];
unsigned char buf_length;
#endif
@ -231,7 +231,9 @@ void shrink_format_cache(int);
extern struct module document_module;
/* FIXME: support for entities and all Unicode characters.
* For now, we only support simple printable character. */
* (Unpaired surrogates should be rejected, so that the ECMAScript
* interface can convert the access key to UTF-16.)
* For now, we only support simple printable character. */
#define accesskey_string_to_unicode(s) (((s)[0] && !(s)[1] && isprint((s)[0])) ? (s)[0] : 0)
#endif

View File

@ -261,10 +261,10 @@ render_dom_line(struct dom_renderer *renderer, struct screen_char *template,
struct conv_table *convert = renderer->convert_table;
enum convert_string_mode mode = renderer->convert_mode;
int x, charlen;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
int utf8 = document->options.utf8;
unsigned char *end;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
assert(renderer && template && string && length);
@ -280,9 +280,9 @@ render_dom_line(struct dom_renderer *renderer, struct screen_char *template,
add_search_node(renderer, length);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
end = string + length;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
for (x = 0, charlen = 1; x < length;x += charlen, renderer->canvas_x++) {
unsigned char *text = &string[x];
@ -307,11 +307,11 @@ render_dom_line(struct dom_renderer *renderer, struct screen_char *template,
break;
}
default:
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (utf8) {
unicode_val_T data;
charlen = utf8charlen(text);
data = utf_8_to_unicode(&text, end);
data = utf8_to_unicode(&text, end);
template->data = (unicode_val_T)data;
@ -324,7 +324,7 @@ render_dom_line(struct dom_renderer *renderer, struct screen_char *template,
}
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
template->data = isscreensafe(*text) ? *text:'.';
}
@ -1050,9 +1050,9 @@ render_dom_document(struct cache_entry *cached, struct document *document,
init_dom_renderer(&renderer, document, buffer, convert_table);
document->bgcolor = document->options.default_bg;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
document->options.utf8 = is_cp_utf8(document->options.cp);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
if (document->options.plain)
parser_type = SGML_PARSER_STREAM;

View File

@ -497,12 +497,12 @@ end_parse:
max_width = 0;
for (i = 0; i < order; i++) {
if (!labels[i]) continue;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (html_context->options->utf8)
int_lower_bound(&max_width,
utf8_ptr2cells(labels[i], NULL));
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
int_lower_bound(&max_width, strlen(labels[i]));
}

View File

@ -210,7 +210,7 @@ realloc_spaces(struct part *part, int length)
if (!ALIGN_SPACES(&part->spaces, part->spaces_len, length))
return -1;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (!ALIGN_SPACES(&part->char_width, part->spaces_len, length))
return -1;
#endif
@ -379,7 +379,7 @@ get_format_screen_char(struct html_context *html_context,
return &schar_cache;
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
/* First possibly do the format change and then find out what coordinates
* to use since sub- or superscript might change them */
static inline int
@ -422,7 +422,7 @@ set_hline(struct html_context *html_context, unsigned char *chars, int charslen,
}
part->document->buf_length = i;
part->document->buf[i] = '\0';
data = utf_8_to_unicode(&buf_ptr, buf_ptr + i);
data = utf8_to_unicode(&buf_ptr, buf_ptr + i);
if (data != UCS_NO_CHAR) {
part->document->buf_length = 0;
goto good_char;
@ -440,7 +440,7 @@ set_hline(struct html_context *html_context, unsigned char *chars, int charslen,
chars++;
} else {
part->spaces[x] = (*chars == ' ');
data = utf_8_to_unicode(&chars, end);
data = utf8_to_unicode(&chars, end);
if (data == UCS_NO_CHAR) {
if (charslen == 1) {
/* HR */
@ -454,7 +454,7 @@ set_hline(struct html_context *html_context, unsigned char *chars, int charslen,
continue;
} else {
unsigned char i;
broken_char: /* broken char */
for (i = 0; chars < end;i++) {
part->document->buf[i] = *chars++;
}
@ -467,9 +467,7 @@ good_char:
schar->data = (unicode_val_T)data;
part->char_width[x] = 2;
copy_screen_chars(&POS(x++, y), schar, 1);
data = utf_8_to_unicode(&chars, end);
if (data == UCS_NO_CHAR) goto broken_char;
schar->data = (unicode_val_T)data;
schar->data = UCS_NO_CHAR;
part->spaces[x] = 0;
part->char_width[x] = 0;
} else {
@ -503,13 +501,13 @@ good_char:
unicode_val_T data;
part->spaces[x] = (*chars == ' ');
data = utf_8_to_unicode(&chars, end);
data = utf8_to_unicode(&chars, end);
part->char_width[x] = unicode_to_cell(data);
if (part->char_width[x] == 2) {
x++;
part->spaces[x] = 0;
part->char_width[x] = 0;
data = utf_8_to_unicode(&chars, end);
data = utf8_to_unicode(&chars, end);
}
if (data == UCS_NO_CHAR) {
/* this is at the end only */
@ -567,7 +565,7 @@ set_hline(struct html_context *html_context, unsigned char *chars, int charslen,
}
}
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
static void
move_links(struct html_context *html_context, int xf, int yf, int xt, int yt)
@ -799,7 +797,7 @@ split_line_at(struct html_context *html_context, int width)
if (part->document) {
assert(part->document->data);
if_assert_failed return 0;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (html_context->options->utf8
&& width < part->spaces_len && part->char_width[width] == 2) {
move_chars(html_context, width, part->cy, par_format.leftmargin, part->cy + 1);
@ -815,7 +813,7 @@ split_line_at(struct html_context *html_context, int width)
}
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (!(html_context->options->utf8
&& width < part->spaces_len
&& part->char_width[width] == 2))
@ -826,7 +824,7 @@ split_line_at(struct html_context *html_context, int width)
if (tmp > 0) {
/* 0 is possible and I'm paranoid ... --Zas */
memmove(part->spaces, part->spaces + width, tmp);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
memmove(part->char_width, part->char_width + width, tmp);
#endif
}
@ -834,7 +832,7 @@ split_line_at(struct html_context *html_context, int width)
assert(tmp >= 0);
if_assert_failed tmp = 0;
memset(part->spaces + tmp, 0, width);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
memset(part->char_width + tmp, 0, width);
#endif
@ -843,7 +841,7 @@ split_line_at(struct html_context *html_context, int width)
assertm(tmp > 0, "part->spaces_len - par_format.leftmargin == %d", tmp);
/* So tmp is zero, memmove() should survive that. Don't recover. */
memmove(part->spaces + par_format.leftmargin, part->spaces, tmp);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
memmove(part->char_width + par_format.leftmargin, part->char_width, tmp);
#endif
}
@ -883,7 +881,7 @@ split_line(struct html_context *html_context)
assert(part);
if_assert_failed return 0;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (html_context->options->utf8) {
for (x = overlap(par_format); x >= par_format.leftmargin; x--) {
@ -1343,7 +1341,7 @@ done_link_state_info(void)
sizeof(renderer_context.link_state_info));
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
static inline void
process_link(struct html_context *html_context, enum link_state link_state,
unsigned char *chars, int charslen, int cells)
@ -1351,7 +1349,7 @@ process_link(struct html_context *html_context, enum link_state link_state,
static inline void
process_link(struct html_context *html_context, enum link_state link_state,
unsigned char *chars, int charslen)
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
struct part *part = html_context->part;
struct link *link;
@ -1403,9 +1401,9 @@ process_link(struct html_context *html_context, enum link_state link_state,
if (x_offset) {
charslen -= x_offset;
chars += x_offset;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
cells -= x_offset;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
}
link = new_link(html_context, chars, charslen);
@ -1420,17 +1418,17 @@ process_link(struct html_context *html_context, enum link_state link_state,
}
/* Add new canvas positions to the link. */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (realloc_points(link, link->npoints + cells))
#else
if (realloc_points(link, link->npoints + charslen))
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
struct point *point = &link->points[link->npoints];
int x = X(part->cx) + x_offset;
int y = Y(part->cy);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
link->npoints += cells;
for (; cells > 0; cells--, point++, x++)
@ -1438,7 +1436,7 @@ process_link(struct html_context *html_context, enum link_state link_state,
link->npoints += charslen;
for (; charslen > 0; charslen--, point++, x++)
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
point->x = x;
point->y = y;
@ -1490,9 +1488,9 @@ put_chars(struct html_context *html_context, unsigned char *chars, int charslen)
{
enum link_state link_state;
struct part *part;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
int cells;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
assert(html_context);
if_assert_failed return;
@ -1551,21 +1549,21 @@ put_chars(struct html_context *html_context, unsigned char *chars, int charslen)
else if (html_context->options->links_numbering)
put_link_number(html_context);
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
cells =
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
set_hline(html_context, chars, charslen, link_state);
if (link_state != LINK_STATE_NONE) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
process_link(html_context, link_state, chars, charslen,
cells);
#else
process_link(html_context, link_state, chars, charslen);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (renderer_context.nowrap
&& part->cx + cells > overlap(par_format))
return;
@ -1577,7 +1575,7 @@ put_chars(struct html_context *html_context, unsigned char *chars, int charslen)
return;
part->cx += charslen;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
renderer_context.nobreak = 0;
@ -1594,11 +1592,11 @@ put_chars(struct html_context *html_context, unsigned char *chars, int charslen)
}
assert(charslen > 0);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
part->xa += cells;
#else
part->xa += charslen;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
int_lower_bound(&part->max_width, part->xa
+ par_format.leftmargin + par_format.rightmargin
- (chars[charslen - 1] == ' '
@ -1657,7 +1655,7 @@ end:
part->cx = -1;
part->xa = 0;
memset(part->spaces, 0, part->spaces_len);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
memset(part->char_width, 0, part->spaces_len);
#endif
}
@ -2079,7 +2077,7 @@ format_html_part(struct html_context *html_context,
done_link_state_info();
mem_free_if(part->spaces);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
mem_free_if(part->char_width);
#endif
@ -2165,9 +2163,9 @@ render_html_document(struct cache_entry *cached, struct document *document,
&document->cp,
&document->cp_status,
document->options.hard_assume);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
html_context->options->utf8 = is_cp_utf8(document->options.cp);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
if (title.length) {
document->title = convert_string(renderer_context.convert_table,

View File

@ -23,7 +23,7 @@ struct part {
unsigned char *spaces;
int spaces_len;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
unsigned char *char_width;
#endif

View File

@ -101,9 +101,9 @@ struct document_options {
unsigned int no_cache:1;
unsigned int gradual_rerendering:1;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
unsigned int utf8:1;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* Active link coloring */
/* This is mostly here to make use of this option cache so link
* drawing is faster. --jonas */

View File

@ -234,9 +234,9 @@ add_document_line(struct plain_renderer *renderer,
struct screen_char *template = &renderer->template;
struct screen_char saved_renderer_template = *template;
struct screen_char *pos, *startpos;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
int utf8 = document->options.utf8;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
int cells = 0;
int lineno = renderer->lineno;
int expanded = 0;
@ -253,13 +253,13 @@ add_document_line(struct plain_renderer *renderer,
unsigned char line_char = line[line_pos];
int charlen = 1;
int cell = 1;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
unicode_val_T data;
if (utf8) {
unsigned char *line_char2 = &line[line_pos];
charlen = utf8charlen(&line_char);
data = utf_8_to_unicode(&line_char2, &line[width]);
data = utf8_to_unicode(&line_char2, &line[width]);
if (data == UCS_NO_CHAR) {
line_pos += charlen;
@ -268,7 +268,7 @@ add_document_line(struct plain_renderer *renderer,
cell = unicode_to_cell(data);
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
if (line_char == ASCII_TAB
&& (line_pos + charlen == width
@ -313,13 +313,13 @@ add_document_line(struct plain_renderer *renderer,
unsigned char next_char, prev_char;
int charlen = 1;
int cell = 1;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
unicode_val_T data;
if (utf8) {
unsigned char *line_char2 = &line[line_pos];
charlen = utf8charlen(&line_char);
data = utf_8_to_unicode(&line_char2, &line[width]);
data = utf8_to_unicode(&line_char2, &line[width]);
if (data == UCS_NO_CHAR) {
line_pos += charlen;
@ -328,7 +328,7 @@ add_document_line(struct plain_renderer *renderer,
cell = unicode_to_cell(data);
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
prev_char = line_pos > 0 ? line[line_pos - 1] : '\0';
next_char = (line_pos + charlen < width) ?
@ -433,11 +433,11 @@ add_document_line(struct plain_renderer *renderer,
cells += added_chars - 1;
pos += added_chars;
} else {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (utf8) {
unsigned char *text = &line[line_pos];
unicode_val_T data =
utf_8_to_unicode(&text,
utf8_to_unicode(&text,
&line[width]);
if (data == UCS_NO_CHAR) {
@ -455,7 +455,7 @@ add_document_line(struct plain_renderer *renderer,
cell++;
}
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
if (!isscreensafe(line_char))
line_char = '.';
@ -520,7 +520,7 @@ add_document_lines(struct plain_renderer *renderer)
int length = renderer->length;
int was_empty_line = 0;
int was_wrapped = 0;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
int utf8 = is_cp_utf8(renderer->document->cp);
#endif
for (; length > 0; renderer->lineno++) {
@ -552,10 +552,10 @@ add_document_lines(struct plain_renderer *renderer)
only_spaces = 0;
was_spaces = 0;
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (utf8) {
unsigned char *text = &source[width];
unicode_val_T data = utf_8_to_unicode(&text,
unicode_val_T data = utf8_to_unicode(&text,
&source[length]);
if (data == UCS_NO_CHAR) return;
@ -563,7 +563,7 @@ add_document_lines(struct plain_renderer *renderer)
cells += unicode_to_cell(data);
width += utf8charlen(&source[width]);
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
cells++;
width++;
@ -651,9 +651,9 @@ render_plain_document(struct cache_entry *cached, struct document *document,
document->bgcolor = document->options.default_bg;
document->width = 0;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
document->options.utf8 = is_cp_utf8(document->options.cp);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* Setup the style */
init_template(&renderer.template, &document->options);

View File

@ -346,11 +346,11 @@ render_document(struct view_state *vs, struct document_view *doc_view,
document->title = get_uri_string(document->uri, components);
if (document->title) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (doc_view->document->options.utf8)
decode_uri(document->title);
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
decode_uri_for_display(document->title);
}
}

View File

@ -60,6 +60,7 @@ static void
see_init(struct module *xxx)
{
init_intern_strings();
SEE_system.periodic = checktime;
}
static void

View File

@ -56,7 +56,7 @@ static void js_document_writeln(struct SEE_interpreter *, struct SEE_object *, s
void location_goto(struct document_view *, unsigned char *);
struct SEE_objectclass js_document_object_class = {
NULL,
"document",
document_get,
document_put,
document_canput,
@ -83,7 +83,6 @@ document_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *str;
unsigned char *string;
checktime(interp);
SEE_SET_UNDEFINED(res);
if (p == s_cookie) {
@ -175,7 +174,6 @@ document_put(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_value res;
unsigned char *string;
checktime(interp);
if (p == s_forms) {
SEE_ToObject(interp, val, &res);
doc->forms = res.u.object;
@ -238,7 +236,6 @@ js_document_write_do(struct SEE_interpreter *interp, struct SEE_object *self,
set_led_value(vs->doc_view->session->status.ecmascript_led, 'J');
#endif
checktime(interp);
SEE_SET_BOOLEAN(res, 0);
}
@ -262,7 +259,6 @@ static int
document_canput(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
if (p == s_location || p == s_url || p == s_cookie)
return 1;
return 0;
@ -272,7 +268,6 @@ static int
document_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
/* all unknown properties return UNDEFINED value */
return 1;
}
@ -288,7 +283,6 @@ init_js_document_object(struct ecmascript_interpreter *interpreter)
struct js_document_object);
doc->object.objectclass = &js_document_object_class;
doc->object.objectclass->Class = s_document;
doc->object.Prototype = NULL;
SEE_SET_OBJECT(&v, (struct SEE_object *)doc);

View File

@ -77,7 +77,7 @@ static void js_form_submit(struct SEE_interpreter *, struct SEE_object *, struct
struct SEE_objectclass js_input_object_class = {
NULL,
"input",
input_get,
input_put,
input_canput,
@ -91,7 +91,7 @@ struct SEE_objectclass js_input_object_class = {
};
struct SEE_objectclass js_form_elems_class = {
NULL,
"elements",
form_elems_get,
SEE_no_put,
SEE_no_canput,
@ -105,7 +105,7 @@ struct SEE_objectclass js_form_elems_class = {
};
struct SEE_objectclass js_forms_object_class = {
NULL,
"forms",
forms_get,
SEE_no_put,
SEE_no_canput,
@ -119,7 +119,7 @@ struct SEE_objectclass js_forms_object_class = {
};
struct SEE_objectclass js_form_class = {
NULL,
"form",
form_get,
form_put,
form_canput,
@ -176,22 +176,21 @@ input_get(struct SEE_interpreter *interp, struct SEE_object *o,
assert(fc);
assert(fc->form && fs);
checktime(interp);
linknum = get_form_control_link(document, fc);
/* Hiddens have no link. */
if (linknum >= 0) link = &document->links[linknum];
SEE_SET_UNDEFINED(res);
if (p == s_accessKey) {
struct string keystr;
struct SEE_string *keystr;
if (!link)
return;
init_string(&keystr);
add_accesskey_to_string(&keystr, link->accesskey);
str = string_to_SEE_string(interp, keystr.source);
SEE_SET_STRING(res, str);
done_string(&keystr);
keystr = SEE_string_new(interp, 0);
if (link->accesskey)
append_unicode_to_SEE_string(interp, keystr,
link->accesskey);
SEE_SET_STRING(res, keystr);
} else if (p == s_alt) {
str = string_to_SEE_string(interp, fc->alt);
SEE_SET_STRING(res, str);
@ -279,19 +278,22 @@ input_put(struct SEE_interpreter *interp, struct SEE_object *o,
assert(fc);
assert(fc->form && fs);
checktime(interp);
linknum = get_form_control_link(document, fc);
/* Hiddens have no link. */
if (linknum >= 0) link = &document->links[linknum];
if (p == s_accessKey) {
if (link) {
string = SEE_value_to_unsigned_char(interp, val);
if (!string)
return;
link->accesskey = accesskey_string_to_unicode(string);
mem_free(string);
}
struct SEE_value conv;
unicode_val_T accesskey;
SEE_ToString(interp, val, &conv);
if (conv.u.string->length)
accesskey = SEE_string_to_unicode(interp, conv.u.string);
else
accesskey = 0;
if (link)
link->accesskey = accesskey;
} else if (p == s_alt) {
string = SEE_value_to_unsigned_char(interp, val);
mem_free_set(&fc->alt, string);
@ -348,7 +350,6 @@ js_input_blur(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
checktime(interp);
SEE_SET_BOOLEAN(res, 0);
/* We are a text-mode browser and there *always* has to be something
* selected. So we do nothing for now. (That was easy.) */
@ -369,7 +370,6 @@ js_input_click(struct SEE_interpreter *interp, struct SEE_object *self,
struct form_control *fc;
int linknum;
checktime(interp);
SEE_SET_BOOLEAN(res, 0);
assert(fs);
fc = find_form_control(document, fs);
@ -403,7 +403,6 @@ js_input_focus(struct SEE_interpreter *interp, struct SEE_object *self,
struct form_control *fc;
int linknum;
checktime(interp);
SEE_SET_BOOLEAN(res, 0);
assert(fs);
fc = find_form_control(document, fs);
@ -423,7 +422,6 @@ js_input_select(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_object *thisobj, int argc, struct SEE_value **argv,
struct SEE_value *res)
{
checktime(interp);
SEE_SET_BOOLEAN(res, 0);
/* We support no text selecting yet. So we do nothing for now.
* (That was easy, too.) */
@ -433,7 +431,6 @@ static int
input_canput(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
return 1;
}
@ -442,7 +439,6 @@ input_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
/* all unknown properties return UNDEFINED value */
checktime(interp);
return 1;
}
@ -452,7 +448,6 @@ js_get_input_object(struct SEE_interpreter *interp, struct js_form *jsform,
{
struct js_input *jsinput;
checktime(interp);
#if 0
if (fs->ecmascript_obj)
@ -464,7 +459,6 @@ js_get_input_object(struct SEE_interpreter *interp, struct js_form *jsform,
jsinput = SEE_NEW(interp, struct js_input);
jsinput->object.objectclass = &js_input_object_class;
jsinput->object.objectclass->Class = s_input;
jsinput->object.Prototype = NULL;
jsinput->blur = SEE_cfunction_make(interp, js_input_blur, s_blur, 0);
@ -483,7 +477,6 @@ static struct js_input *
js_get_form_control_object(struct SEE_interpreter *interp, struct js_form *jsform,
enum form_type type, struct form_state *fs)
{
checktime(interp);
switch (type) {
case FC_TEXT:
case FC_PASSWORD:
@ -529,7 +522,6 @@ js_form_elems_item(struct SEE_interpreter *interp, struct SEE_object *self,
int counter = -1;
int index;
checktime(interp);
SEE_SET_UNDEFINED(res);
if (argc < 1)
return;
@ -569,7 +561,6 @@ js_form_elems_namedItem(struct SEE_interpreter *interp, struct SEE_object *self,
struct form_control *fc;
unsigned char *string;
checktime(interp);
SEE_SET_UNDEFINED(res);
if (argc < 1)
return;
@ -603,7 +594,6 @@ form_elems_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct form_view *fv = parent_form->fv;
struct form *form = find_form_by_form_view(document, fv);
checktime(interp);
if (p == s_length) {
SEE_number_t length = list_size(&form->items);
SEE_SET_NUMBER(res, length);
@ -635,7 +625,6 @@ static int
form_elems_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
/* all unknown properties return UNDEFINED value */
return 1;
}
@ -655,7 +644,6 @@ js_forms_item(struct SEE_interpreter *interp, struct SEE_object *self,
int counter = -1;
int index;
checktime(interp);
SEE_SET_UNDEFINED(res);
if (argc < 1)
return;
@ -691,7 +679,6 @@ js_forms_namedItem(struct SEE_interpreter *interp, struct SEE_object *self,
struct form *form;
unsigned char *string;
checktime(interp);
SEE_SET_UNDEFINED(res);
if (argc < 1)
return;
@ -723,7 +710,6 @@ forms_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct document *document = doc_view->document;
struct js_forms_object *fo = (struct js_forms_object *)o;
checktime(interp);
if (p == s_length) {
SEE_number_t length = list_size(&document->forms);
SEE_SET_NUMBER(res, length);
@ -756,7 +742,6 @@ static int
forms_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
/* all unknown properties return UNDEFINED value */
return 1;
}
@ -775,7 +760,6 @@ form_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct form *form = find_form_by_form_view(doc_view->document, fv);
struct SEE_string *str;
checktime(interp);
SEE_SET_UNDEFINED(res);
if (p == s_action) {
@ -822,7 +806,6 @@ form_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct js_form_elems *jsfe = SEE_NEW(interp, struct js_form_elems);
jsfe->object.objectclass = &js_form_elems_class;
jsfe->object.objectclass->Class = s_elements;
jsfe->object.Prototype = NULL;
jsfe->parent = js_form;
jsfe->item = SEE_cfunction_make(interp, js_form_elems_item, s_item, 1);
@ -867,7 +850,6 @@ form_put(struct SEE_interpreter *interp, struct SEE_object *o,
struct form *form = find_form_by_form_view(doc_view->document, fv);
unsigned char *string = SEE_value_to_unsigned_char(interp, val);
checktime(interp);
if (!string)
return;
@ -905,7 +887,6 @@ static int
form_canput(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
return 1;
}
@ -913,7 +894,6 @@ static int
form_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
return 1;
}
@ -931,7 +911,6 @@ js_form_reset(struct SEE_interpreter *interp, struct SEE_object *self,
assert(form);
checktime(interp);
do_reset_form(doc_view, form);
draw_forms(doc_view->session->tab->term, doc_view);
SEE_SET_BOOLEAN(res, 0);
@ -951,7 +930,6 @@ js_form_submit(struct SEE_interpreter *interp, struct SEE_object *self,
struct form *form = find_form_by_form_view(doc_view->document, fv);
assert(form);
checktime(interp);
submit_given_form(ses, doc_view, form, 0);
SEE_SET_BOOLEAN(res, 0);
}
@ -961,7 +939,6 @@ struct js_form *js_get_form_object(struct SEE_interpreter *interp,
{
struct js_form *js_form;
checktime(interp);
#if 0
if (fv->ecmascript_obj)
return fv->ecmascript_obj;
@ -971,7 +948,6 @@ struct js_form *js_get_form_object(struct SEE_interpreter *interp,
* should be its parent, but gimme DOM first. --pasky */
js_form = SEE_NEW(interp, struct js_form);
js_form->object.objectclass = &js_form_class;
js_form->object.objectclass->Class = s_form;
js_form->object.Prototype = NULL; /* TODO: use prototype for form */
js_form->parent = doc;
js_form->reset = SEE_cfunction_make(interp, js_form_reset, s_reset, 0);
@ -992,7 +968,6 @@ init_js_forms_object(struct ecmascript_interpreter *interpreter)
struct js_forms_object);
forms->object.objectclass = &js_forms_object_class;
forms->object.objectclass->Class = s_forms;
forms->object.Prototype = NULL;
SEE_OBJECT_GET(interp, interp->Global, s_document, &document);

View File

@ -101,3 +101,46 @@ string_to_SEE_string(struct SEE_interpreter *interp, unsigned char *s)
str->data[i] = s[i];
return str;
}
void
append_unicode_to_SEE_string(struct SEE_interpreter *interp,
struct SEE_string *str,
unicode_val_T u)
{
/* This is supposed to make a string from which
* SEE_string_to_unicode() can get the original @u back.
* If @u is a surrogate, then that is not possible, so
* throw an error instead. */
if (u <= 0xFFFF && !is_utf16_surrogate(u)) {
SEE_string_addch(str, u);
} else if (needs_utf16_surrogates(u)) {
SEE_string_addch(str, get_utf16_high_surrogate(u));
SEE_string_addch(str, get_utf16_low_surrogate(u));
} else {
/* str->interpreter exists but is not documented, so don't
* use it; use a separate @interp parameter instead.
* Also, SEE does not support "%lX". */
SEE_error_throw(interp, interp->RangeError,
"UTF-16 cannot encode U+%.4X",
(unsigned int) u);
}
}
unicode_val_T
SEE_string_to_unicode(struct SEE_interpreter *interp, struct SEE_string *S)
{
/* This implementation ignores extra characters in the string. */
if (S->length < 1) {
SEE_error_throw(interp, interp->Error,
"String is empty");
} else if (!is_utf16_surrogate(S->data[0])) {
return S->data[0];
} else if (S->length >= 2
&& is_utf16_high_surrogate(S->data[0])
&& is_utf16_low_surrogate(S->data[1])) {
return join_utf16_surrogates(S->data[0], S->data[1]);
} else {
SEE_error_throw(interp, interp->Error,
"Invalid UTF-16 sequence");
}
}

View File

@ -1,6 +1,8 @@
#ifndef EL__ECMASCRIPT_SEE_INPUT_H
#define EL__ECMASCRIPT_SEE_INPUT_H
#include "intl/charsets.h"
struct SEE_interpreter;
struct SEE_string;
struct SEE_value;
@ -9,5 +11,8 @@ struct SEE_input *SEE_input_elinks(struct SEE_interpreter *, unsigned char *);
unsigned char *SEE_string_to_unsigned_char(struct SEE_string *);
unsigned char *SEE_value_to_unsigned_char(struct SEE_interpreter *, struct SEE_value *);
struct SEE_string *string_to_SEE_string(struct SEE_interpreter *, unsigned char *);
void append_unicode_to_SEE_string(struct SEE_interpreter *, struct SEE_string *,
unicode_val_T);
unicode_val_T SEE_string_to_unicode(struct SEE_interpreter *, struct SEE_string *);
#endif

View File

@ -80,7 +80,7 @@ struct delayed_goto {
};
struct SEE_objectclass js_history_object_class = {
NULL,
"history",
history_get,
SEE_no_put,
SEE_no_canput,
@ -94,7 +94,7 @@ struct SEE_objectclass js_history_object_class = {
};
struct SEE_objectclass js_location_object_class = {
NULL,
"location",
location_get,
location_put,
location_canput,
@ -160,7 +160,6 @@ history_get(struct SEE_interpreter *interp, struct SEE_object *o,
{
struct js_history_object *history = (struct js_history_object *)o;
checktime(interp);
if (p == s_back) {
SEE_SET_OBJECT(res, history->back);
} else if (p == s_forward) {
@ -176,7 +175,6 @@ static int
history_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
if (p == s_back || p == s_forward || p == s_go)
return 1;
return 0;
@ -206,7 +204,6 @@ js_history_forward(struct SEE_interpreter *interp, struct SEE_object *self,
struct document_view *doc_view = vs->doc_view;
struct session *ses = doc_view->session;
checktime(interp);
SEE_SET_NULL(res);
go_unback(ses);
}
@ -224,7 +221,6 @@ js_history_go(struct SEE_interpreter *interp, struct SEE_object *self,
int index;
struct location *loc;
checktime(interp);
SEE_SET_NULL(res);
if (argc < 1)
return;
@ -259,7 +255,6 @@ js_location_toString(struct SEE_interpreter *interp, struct SEE_object *self,
struct SEE_string *str = string_to_SEE_string(interp, string);
mem_free_if(string);
checktime(interp);
SEE_SET_STRING(res, str);
}
@ -270,7 +265,6 @@ location_get(struct SEE_interpreter *interp, struct SEE_object *o,
{
struct js_location_object *loc = (struct js_location_object *)o;
checktime(interp);
if (p == s_toString || p == s_toLocaleString) {
SEE_SET_OBJECT(res, loc->toString);
} else if (p == s_href) {
@ -290,7 +284,6 @@ static void
location_put(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *val, int attr)
{
checktime(interp);
if (p == s_href) {
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
@ -306,7 +299,6 @@ static int
location_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
if (p == s_toString || p == s_toLocaleString || p == s_href)
return 1;
return 0;
@ -316,7 +308,6 @@ static int
location_canput(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
if (p == s_href)
return 1;
return 0;
@ -332,7 +323,6 @@ init_js_history_object(struct ecmascript_interpreter *interpreter)
struct js_history_object);
history->object.objectclass = &js_history_object_class;
history->object.objectclass->Class = s_history;
history->object.Prototype = NULL;
SEE_SET_OBJECT(&v, (struct SEE_object *)history);
@ -353,7 +343,6 @@ init_js_location_object(struct ecmascript_interpreter *interpreter)
struct js_location_object);
loc->object.objectclass = &js_location_object_class;
loc->object.objectclass->Class = s_location;
loc->object.Prototype = NULL;
SEE_SET_OBJECT(&v, (struct SEE_object *)loc);

View File

@ -50,7 +50,7 @@ static void navigator_get(struct SEE_interpreter *, struct SEE_object *, struct
static int navigator_hasproperty(struct SEE_interpreter *, struct SEE_object *, struct SEE_string *);
struct SEE_objectclass js_navigator_object_class = {
NULL,
"navigator",
navigator_get,
SEE_no_put,
SEE_no_canput,
@ -69,7 +69,6 @@ navigator_get(struct SEE_interpreter *interp, struct SEE_object *o,
{
struct SEE_string *str;
checktime(interp);
SEE_SET_UNDEFINED(res);
if (p == s_appCodeName) {
SEE_SET_STRING(res, s_Mozilla);
@ -122,7 +121,6 @@ static int
navigator_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
if (p == s_appCodeName || p == s_appName || p == s_appVersion
|| p == s_language || p == s_platform || p == s_userAgent)
return 1;
@ -142,7 +140,6 @@ init_js_navigator_object(struct ecmascript_interpreter *interpreter)
navigator = SEE_NEW(interp, struct SEE_object);
navigator->objectclass = &js_navigator_object_class;
navigator->objectclass->Class = s_navigator;
navigator->Prototype = NULL;
SEE_SET_OBJECT(&v, navigator);

View File

@ -1,4 +1,5 @@
#include <see/see.h>
#include "ecmascript/see/strings.h"
struct SEE_string *s_window;
struct SEE_string *s_closed;
@ -95,293 +96,102 @@ struct SEE_string *s_hidden;
struct SEE_string *s_timeout;
void
init_intern_strings(void)
{
static SEE_char_t SA_window[] = {'w','i','n','d','o','w'};
static struct SEE_string S_window = SEE_STRING_DECL(SA_window);
static SEE_char_t SA_closed[] = {'c','l','o','s','e','d'};
static struct SEE_string S_closed = SEE_STRING_DECL(SA_closed);
static SEE_char_t SA_parent[] = {'p','a','r','e','n','t'};
static struct SEE_string S_parent = SEE_STRING_DECL(SA_parent);
static SEE_char_t SA_self[] = {'s','e','l','f'};
static struct SEE_string S_self = SEE_STRING_DECL(SA_self);
static SEE_char_t SA_top[] = {'t','o','p'};
static struct SEE_string S_top = SEE_STRING_DECL(SA_top);
static SEE_char_t SA_alert[] ={'a','l','e','r','t'};
static struct SEE_string S_alert = SEE_STRING_DECL(SA_alert);
static SEE_char_t SA_open[] ={'o','p','e','n'};
static struct SEE_string S_open = SEE_STRING_DECL(SA_open);
s_window = SEE_intern_global("window");
s_closed = SEE_intern_global("closed");
s_parent = SEE_intern_global("parent");
s_self = SEE_intern_global("self");
s_top = SEE_intern_global("top");
s_alert = SEE_intern_global("alert");
s_open = SEE_intern_global("open");
static SEE_char_t SA_menubar[] = {'m','e','n','u','b','a','r'};
static struct SEE_string S_menubar = SEE_STRING_DECL(SA_menubar);
s_menubar = SEE_intern_global("menubar");
static SEE_char_t SA_statusbar[] = {'s','t','a','t','u','s','b','a','r'};
static struct SEE_string S_statusbar = SEE_STRING_DECL(SA_statusbar);
static SEE_char_t SA_visible[] = {'v','i','s','i','b','l','e'};
static struct SEE_string S_visible = SEE_STRING_DECL(SA_visible);
s_statusbar = SEE_intern_global("statusbar");
s_visible = SEE_intern_global("visible");
static SEE_char_t SA_navigator[] ={'n','a','v','i','g','a','t','o','r'};
static struct SEE_string S_navigator = SEE_STRING_DECL(SA_navigator);
static SEE_char_t SA_appCodeName[] ={'a','p','p','C','o','d','e','N','a','m','e'};
static struct SEE_string S_appCodeName = SEE_STRING_DECL(SA_appCodeName);
static SEE_char_t SA_appName[] ={'a','p','p','N','a','m','e'};
static struct SEE_string S_appName = SEE_STRING_DECL(SA_appName);
static SEE_char_t SA_appVersion[] ={'a','p','p','V','e','r','s','i','o','n'};
static struct SEE_string S_appVersion = SEE_STRING_DECL(SA_appVersion);
static SEE_char_t SA_language[] ={'l','a','n','g','u','a','g','e'};
static struct SEE_string S_language = SEE_STRING_DECL(SA_language);
static SEE_char_t SA_platform[] ={'p','l','a','t','f','o','r','m'};
static struct SEE_string S_platform = SEE_STRING_DECL(SA_platform);
static SEE_char_t SA_userAgent[] ={'u','s','e','r','A','g','e','n','t'};
static struct SEE_string S_userAgent = SEE_STRING_DECL(SA_userAgent);
s_navigator = SEE_intern_global("navigator");
s_appCodeName = SEE_intern_global("appCodeName");
s_appName = SEE_intern_global("appName");
s_appVersion = SEE_intern_global("appVersion");
s_language = SEE_intern_global("language");
s_platform = SEE_intern_global("platform");
s_userAgent = SEE_intern_global("userAgent");
static SEE_char_t SA_history[] ={'h','i','s','t','o','r','y'};
static struct SEE_string S_history = SEE_STRING_DECL(SA_history);
static SEE_char_t SA_back[] ={'b','a','c','k'};
static struct SEE_string S_back = SEE_STRING_DECL(SA_back);
static SEE_char_t SA_forward[] ={'f','o','r','w','a','r','d'};
static struct SEE_string S_forward = SEE_STRING_DECL(SA_forward);
static SEE_char_t SA_go[] ={'g','o'};
static struct SEE_string S_go = SEE_STRING_DECL(SA_go);
s_history = SEE_intern_global("history");
s_back = SEE_intern_global("back");
s_forward = SEE_intern_global("forward");
s_go = SEE_intern_global("go");
static SEE_char_t SA_location[] ={'l','o','c','a','t','i','o','n'};
static struct SEE_string S_location = SEE_STRING_DECL(SA_location);
static SEE_char_t SA_href[] ={'h','r','e','f'};
static struct SEE_string S_href = SEE_STRING_DECL(SA_href);
static SEE_char_t SA_toString[] ={'t','o','S','t','r','i','n','g'};
static struct SEE_string S_toString = SEE_STRING_DECL(SA_toString);
static SEE_char_t SA_toLocaleString[] ={'t','o','L','o','c','a','l','e','S','t','r','i','n','g'};
static struct SEE_string S_toLocaleString = SEE_STRING_DECL(SA_toLocaleString);
s_location = SEE_intern_global("location");
s_href = SEE_intern_global("href");
s_toString = SEE_intern_global("toString");
s_toLocaleString = SEE_intern_global("toLocaleString");
static SEE_char_t SA_input[] ={'i','n','p','u','t'};
static struct SEE_string S_input = SEE_STRING_DECL(SA_input);
static SEE_char_t SA_accessKey[] ={'a','c','c','e','s','s','K','e','y'};
static struct SEE_string S_accessKey = SEE_STRING_DECL(SA_accessKey);
static SEE_char_t SA_alt[] ={'a','l','t'};
static struct SEE_string S_alt = SEE_STRING_DECL(SA_alt);
static SEE_char_t SA_checked[] ={'c','h','e','c','k','e','d'};
static struct SEE_string S_checked = SEE_STRING_DECL(SA_checked);
static SEE_char_t SA_defaultChecked[] ={'d','e','f','a','u','l','t','C','h','e','c','k','e','d'};
static struct SEE_string S_defaultChecked = SEE_STRING_DECL(SA_defaultChecked);
static SEE_char_t SA_defaultValue[] ={'d','e','f','a','u','l','t','V','a','l','u','e'};
static struct SEE_string S_defaultValue = SEE_STRING_DECL(SA_defaultValue);
static SEE_char_t SA_disabled[] ={'d','i','s','a','b','l','e','d'};
static struct SEE_string S_disabled = SEE_STRING_DECL(SA_disabled);
static SEE_char_t SA_form[] ={'f','o','r','m'};
static struct SEE_string S_form = SEE_STRING_DECL(SA_form);
static SEE_char_t SA_maxLength[] ={'m','a','x','L','e','n','g','t','h'};
static struct SEE_string S_maxLength = SEE_STRING_DECL(SA_maxLength);
static SEE_char_t SA_name[] ={'n','a','m','e'};
static struct SEE_string S_name = SEE_STRING_DECL(SA_name);
static SEE_char_t SA_readonly[] ={'r','e','a','d','o','n','l','y'};
static struct SEE_string S_readonly = SEE_STRING_DECL(SA_readonly);
static SEE_char_t SA_size[] ={'s','i','z','e'};
static struct SEE_string S_size = SEE_STRING_DECL(SA_size);
static SEE_char_t SA_src[] ={'s','r','c'};
static struct SEE_string S_src = SEE_STRING_DECL(SA_src);
static SEE_char_t SA_tabindex[] ={'t','a','b','i','n','d','e','x'};
static struct SEE_string S_tabindex = SEE_STRING_DECL(SA_tabindex);
static SEE_char_t SA_type[] ={'t','y','p','e'};
static struct SEE_string S_type = SEE_STRING_DECL(SA_type);
static SEE_char_t SA_value[] ={'v','a','l','u','e'};
static struct SEE_string S_value = SEE_STRING_DECL(SA_value);
static SEE_char_t SA_blur[] ={'b','l','u','r'};
static struct SEE_string S_blur = SEE_STRING_DECL(SA_blur);
static SEE_char_t SA_click[] ={'c','l','i','c','k'};
static struct SEE_string S_click = SEE_STRING_DECL(SA_click);
static SEE_char_t SA_focus[] ={'f','o','c','u','s'};
static struct SEE_string S_focus = SEE_STRING_DECL(SA_focus);
static SEE_char_t SA_select[] ={'s','e','l','e','c','t'};
static struct SEE_string S_select = SEE_STRING_DECL(SA_select);
static SEE_char_t SA_selectedIndex[] ={'s','e','l','e','c','t','e','d','I','n','d','e','x'};
static struct SEE_string S_selectedIndex = SEE_STRING_DECL(SA_selectedIndex);
s_input = SEE_intern_global("input");
s_accessKey = SEE_intern_global("accessKey");
s_alt = SEE_intern_global("alt");
s_checked = SEE_intern_global("checked");
s_defaultChecked = SEE_intern_global("defaultChecked");
s_defaultValue = SEE_intern_global("defaultValue");
s_disabled = SEE_intern_global("disabled");
s_form = SEE_intern_global("form");
s_maxLength = SEE_intern_global("maxLength");
s_name = SEE_intern_global("name");
s_readonly = SEE_intern_global("readonly");
s_size = SEE_intern_global("size");
s_src = SEE_intern_global("src");
s_tabindex = SEE_intern_global("tabindex");
s_type = SEE_intern_global("type");
s_value = SEE_intern_global("value");
s_blur = SEE_intern_global("blur");
s_click = SEE_intern_global("click");
s_focus = SEE_intern_global("focus");
s_select = SEE_intern_global("select");
s_selectedIndex = SEE_intern_global("selectedIndex");
static SEE_char_t SA_elements[] ={'e','l','e','m','e','n','t','s'};
static struct SEE_string S_elements = SEE_STRING_DECL(SA_elements);
static SEE_char_t SA_item[] ={'i','t','e','m'};
static struct SEE_string S_item = SEE_STRING_DECL(SA_item);
static SEE_char_t SA_namedItem[] ={'n','a','m','e','d','I','t','e','m'};
static struct SEE_string S_namedItem = SEE_STRING_DECL(SA_namedItem);
static SEE_char_t SA_length[] ={'l','e','n','g','t','h'};
static struct SEE_string S_length = SEE_STRING_DECL(SA_length);
s_elements = SEE_intern_global("elements");
s_item = SEE_intern_global("item");
s_namedItem = SEE_intern_global("namedItem");
s_length = SEE_intern_global("length");
static SEE_char_t SA_action[] ={'a','c','t','i','o','n'};
static struct SEE_string S_action = SEE_STRING_DECL(SA_action);
static SEE_char_t SA_encoding[] ={'e','n','c','o','d','i','g'};
static struct SEE_string S_encoding = SEE_STRING_DECL(SA_encoding);
static SEE_char_t SA_method[] ={'m','e','t','h','o','d'};
static struct SEE_string S_method = SEE_STRING_DECL(SA_method);
static SEE_char_t SA_target[] ={'t','a','r','g','e','t'};
static struct SEE_string S_target = SEE_STRING_DECL(SA_target);
static SEE_char_t SA_reset[] ={'r','e','s','e','t'};
static struct SEE_string S_reset = SEE_STRING_DECL(SA_reset);
static SEE_char_t SA_submit[] ={'s','u','b','m','i','t'};
static struct SEE_string S_submit = SEE_STRING_DECL(SA_submit);
s_action = SEE_intern_global("action");
s_encoding = SEE_intern_global("encoding");
s_method = SEE_intern_global("method");
s_target = SEE_intern_global("target");
s_reset = SEE_intern_global("reset");
s_submit = SEE_intern_global("submit");
static SEE_char_t SA_forms[] ={'f','o','r','m','s'};
static struct SEE_string S_forms = SEE_STRING_DECL(SA_forms);
s_forms = SEE_intern_global("forms");
static SEE_char_t SA_document[] = {'d','o','c','u','m','e','n','t'};
static struct SEE_string S_document = SEE_STRING_DECL(SA_document);
static SEE_char_t SA_referrer[] ={'r','e','f','e','r','r','e','r'};
static struct SEE_string S_referrer = SEE_STRING_DECL(SA_referrer);
static SEE_char_t SA_title[] ={'t','i','t','l','e'};
static struct SEE_string S_title = SEE_STRING_DECL(SA_title);
static SEE_char_t SA_url[] ={'u','r','l'};
static struct SEE_string S_url = SEE_STRING_DECL(SA_url);
static SEE_char_t SA_write[] = {'w','r','i','t','e'};
static struct SEE_string S_write = SEE_STRING_DECL(SA_write);
static SEE_char_t SA_writeln[] = {'w','r','i','t','e','l','n'};
static struct SEE_string S_writeln = SEE_STRING_DECL(SA_writeln);
s_document = SEE_intern_global("document");
s_referrer = SEE_intern_global("referrer");
s_title = SEE_intern_global("title");
s_url = SEE_intern_global("url");
s_write = SEE_intern_global("write");
s_writeln = SEE_intern_global("writeln");
static SEE_char_t SA_Mozilla[] = {'M','o','z','i','l','l','a'};
static struct SEE_string S_Mozilla = SEE_STRING_DECL(SA_Mozilla);
static SEE_char_t SA_ELinks_[] = {'E','L','i','n','k','s',' ','(',
'r','o','u','g','h','l','y',' ','c','o','m','p','a','t','i','b','l','e',
' ','w','i','t','h',' ','N','e','t','s','c','a','p','e',' ',
'N','a','v','i','g','a','t','o','r',',',' ','M','o','z','i','l','l','a',
' ','a','n','d',' ','M','i','c','r','o','s','o','f','t',' ',
'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r',')'};
static struct SEE_string S_ELinks_ = SEE_STRING_DECL(SA_ELinks_);
s_Mozilla = SEE_intern_global("Mozilla");
s_ELinks_ = SEE_intern_global("ELinks (roughly compatible with Netscape Navigator Mozilla and Microsoft Internet Explorer)");
s_cookie = SEE_intern_global("cookie");
static SEE_char_t SA_cookie[] = {'c','o','o','k','i','e'};
static struct SEE_string S_cookie = SEE_STRING_DECL(SA_cookie);
s_GET = SEE_intern_global("GET");
s_POST = SEE_intern_global("POST");
s_application_ = SEE_intern_global("application/x-www-form-urlencoded");
s_multipart_ = SEE_intern_global("multipart/form-data");
s_textplain = SEE_intern_global("text/plain");
static SEE_char_t SA_GET[] = {'G','E','T'};
static struct SEE_string S_GET = SEE_STRING_DECL(SA_GET);
static SEE_char_t SA_POST[] = {'P','O','S','T'};
static struct SEE_string S_POST = SEE_STRING_DECL(SA_POST);
s_text = SEE_intern_global("text");
s_password = SEE_intern_global("password");
s_file = SEE_intern_global("file");
s_checkbox = SEE_intern_global("checkbox");
s_radio = SEE_intern_global("radio");
s_image = SEE_intern_global("image");
s_button = SEE_intern_global("button");
s_hidden = SEE_intern_global("hidden");
static SEE_char_t SA_application_[] = {'a','p','p','l','i','c','a','t',
'i','o','n','/','x','-','w','w','w','-','f','o','r','m','-','u','r','l',
'e','n','c','o','d','e','d'};
static struct SEE_string S_application_ = SEE_STRING_DECL(SA_application_);
static SEE_char_t SA_multipart_[] = {'m','u','l','t','i','p','a','r','t','/',
'f','o','r','m','-','d','a','t','a'};
static struct SEE_string S_multipart_ = SEE_STRING_DECL(SA_multipart_);
static SEE_char_t SA_textplain[] = {'t','e','x','t','/','p','l','a','i','n'};
static struct SEE_string S_textplain = SEE_STRING_DECL(SA_textplain);
static SEE_char_t SA_text[] = {'t','e','x','t'};
static struct SEE_string S_text = SEE_STRING_DECL(SA_text);
static SEE_char_t SA_password[] = {'p','a','s','s','w','o','r','d'};
static struct SEE_string S_password = SEE_STRING_DECL(SA_password);
static SEE_char_t SA_file[] = {'f','i','l','e'};
static struct SEE_string S_file = SEE_STRING_DECL(SA_file);
static SEE_char_t SA_checkbox[] = {'c','h','e','c','k','b','o','x'};
static struct SEE_string S_checkbox = SEE_STRING_DECL(SA_checkbox);
static SEE_char_t SA_radio[] = {'r','a','d','i','o'};
static struct SEE_string S_radio = SEE_STRING_DECL(SA_radio);
static SEE_char_t SA_image[] = {'i','m','a','g','e'};
static struct SEE_string S_image = SEE_STRING_DECL(SA_image);
static SEE_char_t SA_button[] = {'b','u','t','t','o','n'};
static struct SEE_string S_button = SEE_STRING_DECL(SA_button);
static SEE_char_t SA_hidden[] = {'h','i','d','d','e','n'};
static struct SEE_string S_hidden = SEE_STRING_DECL(SA_hidden);
static SEE_char_t SA_timeout[] = {'t','i','m','e','o','u','t'};
static struct SEE_string S_timeout = SEE_STRING_DECL(SA_timeout);
SEE_intern_global(s_window = &S_window);
SEE_intern_global(s_closed = &S_closed);
SEE_intern_global(s_parent = &S_parent);
SEE_intern_global(s_self = &S_self);
SEE_intern_global(s_top = &S_top);
SEE_intern_global(s_alert = &S_alert);
SEE_intern_global(s_open = &S_open);
SEE_intern_global(s_menubar = &S_menubar);
SEE_intern_global(s_statusbar = &S_statusbar);
SEE_intern_global(s_visible = &S_visible);
SEE_intern_global(s_navigator = &S_navigator);
SEE_intern_global(s_appCodeName = &S_appCodeName);
SEE_intern_global(s_appName = &S_appName);
SEE_intern_global(s_appVersion = &S_appVersion);
SEE_intern_global(s_language = &S_language);
SEE_intern_global(s_platform = &S_platform);
SEE_intern_global(s_userAgent = &S_userAgent);
SEE_intern_global(s_history = &S_history);
SEE_intern_global(s_back = &S_back);
SEE_intern_global(s_forward = &S_forward);
SEE_intern_global(s_go = &S_go);
SEE_intern_global(s_location = &S_location);
SEE_intern_global(s_href = &S_href);
SEE_intern_global(s_toString = &S_toString);
SEE_intern_global(s_toLocaleString = &S_toLocaleString);
SEE_intern_global(s_input = &S_input);
SEE_intern_global(s_accessKey = &S_accessKey);
SEE_intern_global(s_alt = &S_alt);
SEE_intern_global(s_checked = &S_checked);
SEE_intern_global(s_defaultChecked = &S_defaultChecked);
SEE_intern_global(s_defaultValue = &S_defaultValue);
SEE_intern_global(s_disabled = &S_disabled);
SEE_intern_global(s_form = &S_form);
SEE_intern_global(s_maxLength = &S_maxLength);
SEE_intern_global(s_name = &S_name);
SEE_intern_global(s_readonly = &S_readonly);
SEE_intern_global(s_size = &S_size);
SEE_intern_global(s_src = &S_src);
SEE_intern_global(s_tabindex = &S_tabindex);
SEE_intern_global(s_type = &S_type);
SEE_intern_global(s_value = &S_value);
SEE_intern_global(s_blur = &S_blur);
SEE_intern_global(s_click = &S_click);
SEE_intern_global(s_focus = &S_focus);
SEE_intern_global(s_select = &S_select);
SEE_intern_global(s_selectedIndex = &S_selectedIndex);
SEE_intern_global(s_elements = &S_elements);
SEE_intern_global(s_item = &S_item);
SEE_intern_global(s_namedItem = &S_namedItem);
SEE_intern_global(s_length = &S_length);
SEE_intern_global(s_action = &S_action);
SEE_intern_global(s_encoding = &S_encoding);
SEE_intern_global(s_method = &S_method);
SEE_intern_global(s_target = &S_target);
SEE_intern_global(s_reset = &S_reset);
SEE_intern_global(s_submit = &S_submit);
SEE_intern_global(s_forms = &S_forms);
SEE_intern_global(s_document = &S_document);
SEE_intern_global(s_referrer = &S_referrer);
SEE_intern_global(s_title = &S_title);
SEE_intern_global(s_url = &S_url);
SEE_intern_global(s_write = &S_write);
SEE_intern_global(s_writeln = &S_writeln);
SEE_intern_global(s_Mozilla = &S_Mozilla);
SEE_intern_global(s_ELinks_ = &S_ELinks_);
SEE_intern_global(s_cookie = &S_cookie);
SEE_intern_global(s_GET = &S_GET);
SEE_intern_global(s_POST = &S_POST);
SEE_intern_global(s_application_ = &S_application_);
SEE_intern_global(s_multipart_ = &S_multipart_);
SEE_intern_global(s_textplain = &S_textplain);
SEE_intern_global(s_text = &S_text);
SEE_intern_global(s_password = &S_password);
SEE_intern_global(s_file = &S_file);
SEE_intern_global(s_checkbox = &S_checkbox);
SEE_intern_global(s_radio = &S_radio);
SEE_intern_global(s_image = &S_image);
SEE_intern_global(s_button = &S_button);
SEE_intern_global(s_hidden = &S_hidden);
SEE_intern_global(s_timeout = &S_timeout);
s_timeout = SEE_intern_global("timeout");
}

View File

@ -57,7 +57,7 @@ struct js_unibar_object {
};
struct SEE_objectclass js_menubar_object_class = {
NULL,
"menubar",
unibar_get,
unibar_put,
unibar_canput,
@ -71,7 +71,7 @@ struct SEE_objectclass js_menubar_object_class = {
};
struct SEE_objectclass js_statusbar_object_class = {
NULL,
"statusbar",
unibar_get,
unibar_put,
unibar_canput,
@ -95,7 +95,6 @@ unibar_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct js_unibar_object *obj = (struct js_unibar_object *)o;
unsigned char bar = obj->bar;
checktime(interp);
if (p == s_visible) {
#define unibar_fetch(bar) \
SEE_SET_BOOLEAN(res, status->force_show_##bar##_bar >= 0 \
@ -122,8 +121,7 @@ static void
unibar_put(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *val, int attr)
{
checktime(interp);
if (p == s_location) {
if (p == s_visible) {
struct global_object *g = (struct global_object *)interp;
struct view_state *vs = g->win->vs;
struct document_view *doc_view = vs->doc_view;
@ -151,7 +149,6 @@ static int
unibar_canput(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
if (p == s_visible)
return 1;
return 0;
@ -161,7 +158,6 @@ static int
unibar_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
if (p == s_visible)
return 1;
return 0;
@ -178,7 +174,6 @@ init_js_menubar_object(struct ecmascript_interpreter *interpreter)
menu = SEE_NEW(interp, struct js_unibar_object);
menu->object.objectclass = &js_menubar_object_class;
menu->object.objectclass->Class = s_menubar;
menu->object.Prototype = NULL;
menu->bar = 't';
@ -197,7 +192,6 @@ init_js_statusbar_object(struct ecmascript_interpreter *interpreter)
status = SEE_NEW(interp, struct js_unibar_object);
status->object.objectclass = &js_statusbar_object_class;
status->object.objectclass->Class = s_statusbar;
status->object.Prototype = NULL;
status->bar = 's';

View File

@ -58,7 +58,7 @@ static void js_window_open(struct SEE_interpreter *, struct SEE_object *, struct
void location_goto(struct document_view *, unsigned char *);
struct SEE_objectclass js_window_object_class = {
NULL,
"window",
window_get,
window_put,
window_canput,
@ -100,7 +100,6 @@ window_get(struct SEE_interpreter *interp, struct SEE_object *o,
struct js_window_object *win = (struct js_window_object *)o;
struct view_state *vs = win->vs;
checktime(interp);
if (p == s_closed) {
SEE_SET_BOOLEAN(res, 0);
} else if (p == s_self || p == s_parent || p == s_top) {
@ -157,7 +156,6 @@ static void
window_put(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p, struct SEE_value *val, int attr)
{
checktime(interp);
if (p == s_location) {
struct js_window_object *win = (struct js_window_object *)o;
struct view_state *vs = win->vs;
@ -175,7 +173,6 @@ static int
window_canput(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
if (p == s_location)
return 1;
return 0;
@ -185,7 +182,6 @@ static int
window_hasproperty(struct SEE_interpreter *interp, struct SEE_object *o,
struct SEE_string *p)
{
checktime(interp);
/* all unknown properties return UNDEFINED value */
return 1;
}
@ -201,7 +197,6 @@ js_window_alert(struct SEE_interpreter *interp, struct SEE_object *self,
struct view_state *vs = win->vs;
unsigned char *string;
checktime(interp);
SEE_SET_BOOLEAN(res, 1);
if (argc < 1)
return;
@ -236,7 +231,6 @@ js_window_open(struct SEE_interpreter *interp, struct SEE_object *self,
static time_t ratelimit_start;
static int ratelimit_count;
#endif
checktime(interp);
SEE_SET_OBJECT(res, (struct SEE_object *)win);
if (get_opt_bool("ecmascript.block_window_opening")) {
#ifdef CONFIG_LEDS
@ -329,7 +323,6 @@ init_js_window_object(struct ecmascript_interpreter *interpreter)
g->win = SEE_NEW(interp, struct js_window_object);
g->win->object.objectclass = &js_window_object_class;
g->win->object.objectclass->Class = s_window;
g->win->object.Prototype = NULL;
g->win->vs = interpreter->vs;

View File

@ -117,6 +117,9 @@ static const JSFunctionSpec input_funcs[] = {
{ NULL }
};
static JSString *unicode_to_jsstring(JSContext *ctx, unicode_val_T u);
static unicode_val_T jsval_to_accesskey(JSContext *ctx, jsval *vp);
static JSBool
input_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
{
@ -146,14 +149,19 @@ input_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
switch (JSVAL_TO_INT(id)) {
case JSP_INPUT_ACCESSKEY:
{
struct string keystr;
JSString *keystr;
if (!link) break;
init_string(&keystr);
add_accesskey_to_string(&keystr, link->accesskey);
string_to_jsval(ctx, vp, keystr.source);
done_string(&keystr);
if (!link->accesskey) {
*vp = JS_GetEmptyStringValue(ctx);
} else {
keystr = unicode_to_jsstring(ctx, link->accesskey);
if (keystr)
*vp = STRING_TO_JSVAL(keystr);
else
return JS_FALSE;
}
break;
}
case JSP_INPUT_ALT:
@ -246,6 +254,7 @@ input_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
struct form_control *fc = find_form_control(document, fs);
int linknum;
struct link *link = NULL;
unicode_val_T accesskey;
assert(fc);
assert(fc->form && fs);
@ -259,8 +268,11 @@ input_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
switch (JSVAL_TO_INT(id)) {
case JSP_INPUT_ACCESSKEY:
if (link)
link->accesskey = accesskey_string_to_unicode(jsval_to_string(ctx, vp));
accesskey = jsval_to_accesskey(ctx, vp);
if (accesskey == UCS_NO_CHAR)
return JS_FALSE;
else if (link)
link->accesskey = accesskey;
break;
case JSP_INPUT_ALT:
mem_free_set(&fc->alt, stracpy(jsval_to_string(ctx, vp)));
@ -970,3 +982,57 @@ forms_namedItem(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *r
return JS_TRUE;
}
static JSString *
unicode_to_jsstring(JSContext *ctx, unicode_val_T u)
{
jschar buf[2];
/* This is supposed to make a string from which
* jsval_to_accesskey() can get the original @u back.
* If @u is a surrogate, then that is not possible, so
* return NULL to indicate an error instead.
*
* If JS_NewUCStringCopyN hits a null character, it truncates
* the string there and pads it with more nulls. However,
* that is not a problem here, because if there is a null
* character in buf[], then it must be the only character. */
if (u <= 0xFFFF && !is_utf16_surrogate(u)) {
buf[0] = u;
return JS_NewUCStringCopyN(ctx, buf, 1);
} else if (needs_utf16_surrogates(u)) {
buf[0] = get_utf16_high_surrogate(u);
buf[1] = get_utf16_low_surrogate(u);
return JS_NewUCStringCopyN(ctx, buf, 2);
} else {
return NULL;
}
}
/* Convert the string *@vp to an access key. Return 0 for no access
* key, UCS_NO_CHAR on error, or the access key otherwise. */
static unicode_val_T
jsval_to_accesskey(JSContext *ctx, jsval *vp)
{
size_t len;
const jschar *chr;
/* Convert the value in place, to protect the result from GC. */
if (JS_ConvertValue(ctx, *vp, JSTYPE_STRING, vp) == JS_FALSE)
return UCS_NO_CHAR;
len = JS_GetStringLength(JSVAL_TO_STRING(*vp));
chr = JS_GetStringChars(JSVAL_TO_STRING(*vp));
/* This implementation ignores extra characters in the string. */
if (len < 1)
return 0; /* which means no access key */
if (!is_utf16_surrogate(chr[0]))
return chr[0];
if (len >= 2
&& is_utf16_high_surrogate(chr[0])
&& is_utf16_low_surrogate(chr[1]))
return join_utf16_surrogates(chr[0], chr[1]);
JS_ReportError(ctx, "Invalid UTF-16 sequence");
return UCS_NO_CHAR; /* which the caller will reject */
}

View File

@ -10,6 +10,9 @@
#include <ctype.h>
#include <stdlib.h>
#if HAVE_WCHAR_H
#include <wchar.h>
#endif
#if HAVE_WCTYPE_H
#include <wctype.h>
#endif
@ -30,13 +33,35 @@
struct table_entry {
unsigned char c;
unicode_val_T u;
/* This should in principle be unicode_val_T, but because all
* the values currently in codepage.inc fit in 16 bits, we can
* as well use uint16_t and halve sizeof(struct table_entry)
* from 8 bytes to 4. Should other characters ever be needed,
* unicode_val_T u : 24 might be a possibility, although it
* seems a little unportable as bitfields are in principle
* restricted to int, which may be 16-bit. */
uint16_t u;
};
struct codepage_desc {
unsigned char *name;
unsigned char **aliases;
struct table_entry *table;
unsigned char *const *aliases;
/* The Unicode mappings of codepage bytes 0x80...0xFF.
* (0x00...0x7F are assumed to be ASCII in all codepages.)
* Because all current values fit in 16 bits, we store them as
* uint16_t rather than unicode_val_T. If the codepage does
* not use some byte, then @highhalf maps that byte to 0xFFFF,
* which C code converts to UCS_REPLACEMENT_CHARACTER where
* appropriate. (U+FFFF is reserved and will never be
* assigned as a character.) */
const uint16_t *highhalf;
/* If some byte in the codepage corresponds to multiple Unicode
* characters, then the preferred character is in @highhalf
* above, and the rest are listed here in @extra. This table
* is not used for translating from the codepage to Unicode. */
const struct table_entry *table;
};
#include "intl/codepage.inc"
@ -135,6 +160,7 @@ static const unicode_val_T strange_chars[32] = {
};
#define SYSTEM_CHARSET_FLAG 128
#define is_cp_ptr_utf8(cp_ptr) ((cp_ptr)->aliases == aliases_utf8)
unsigned char *
u2cp_(unicode_val_T u, int to, int no_nbsp_hack)
@ -146,10 +172,10 @@ u2cp_(unicode_val_T u, int to, int no_nbsp_hack)
to &= ~SYSTEM_CHARSET_FLAG;
#ifdef CONFIG_UTF_8
if (codepages[to].table == table_utf_8)
return encode_utf_8(u);
#endif /* CONFIG_UTF_8 */
#ifdef CONFIG_UTF8
if (is_cp_ptr_utf8(&codepages[to]))
return encode_utf8(u);
#endif /* CONFIG_UTF8 */
/* To mark non breaking spaces, we use a special char NBSP_CHAR. */
if (u == 0xa0) return no_nbsp_hack ? " " : NBSP_CHAR_STRING;
@ -162,7 +188,10 @@ u2cp_(unicode_val_T u, int to, int no_nbsp_hack)
return u2cp_(strange, to, no_nbsp_hack);
}
if (u < 0xFFFF)
for (j = 0; j < 0x80; j++)
if (codepages[to].highhalf[j] == u)
return strings[0x80 + j];
for (j = 0; codepages[to].table[j].c; j++)
if (codepages[to].table[j].u == u)
return strings[codepages[to].table[j].c];
@ -175,13 +204,13 @@ u2cp_(unicode_val_T u, int to, int no_nbsp_hack)
static unsigned char utf_buffer[7];
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
inline unsigned char *
encode_utf_8(unicode_val_T u)
encode_utf8(unicode_val_T u)
#else
static unsigned char *
encode_utf_8(unicode_val_T u)
#endif /* CONFIG_UTF_8 */
encode_utf8(unicode_val_T u)
#endif /* CONFIG_UTF8 */
{
memset(utf_buffer, 0, 7);
@ -215,7 +244,7 @@ encode_utf_8(unicode_val_T u)
return utf_buffer;
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
/* Number of bytes utf8 character indexed by first byte. Illegal bytes are
* equal ones and handled different. */
static char utf8char_len_tab[256] = {
@ -281,7 +310,7 @@ utf8_char2cells(unsigned char *utf8_char, unsigned char *end)
if(!utf8_char || !end)
return -1;
u = utf_8_to_unicode(&utf8_char, end);
u = utf8_to_unicode(&utf8_char, end);
return unicode_to_cell(u);
}
@ -376,10 +405,151 @@ utf8_cells2bytes(unsigned char *string, int max_cells, unsigned char *end)
return bytes;
}
/* Take @max steps forward from @string in the specified @way, but
* not going past @end. Return the resulting address. Store the
* number of steps taken to *@count, unless @count is NULL.
*
* This assumes the text is valid UTF-8, and @string and @end point to
* character boundaries. If not, it doesn't crash but the results may
* be inconsistent.
*
* This function can do some of the same jobs as utf8charlen(),
* utf8_cells2bytes(), and strlen_utf8(). */
unsigned char *
utf8_step_forward(unsigned char *string, unsigned char *end,
int max, enum utf8_step way, int *count)
{
int steps = 0;
unsigned char *current = string;
assert(string);
assert(max >= 0);
if_assert_failed goto invalid_arg;
if (end == NULL)
end = strchr(string, '\0');
switch (way) {
case utf8_step_characters:
while (steps < max && current < end) {
++current;
if (utf8_islead(*current))
++steps;
}
break;
case utf8_step_cells_fewer:
case utf8_step_cells_more:
while (steps < max) {
unicode_val_T u;
unsigned char *prev = current;
int width;
u = utf8_to_unicode(&current, end);
if (u == UCS_NO_CHAR) {
/* Assume the incomplete sequence
* costs one cell. */
current = end;
++steps;
break;
}
width = unicode_to_cell(u);
if (way == utf8_step_cells_fewer
&& steps + width > max) {
/* Back off. */
current = prev;
break;
}
steps += width;
}
break;
default:
INTERNAL("impossible enum utf8_step");
}
invalid_arg:
if (count)
*count = steps;
return current;
}
/* Take @max steps backward from @string in the specified @way, but
* not going past @start. Return the resulting address. Store the
* number of steps taken to *@count, unless @count is NULL.
*
* This assumes the text is valid UTF-8, and @string and @start point
* to character boundaries. If not, it doesn't crash but the results
* may be inconsistent.
*
* This function can do some of the same jobs as utf8_prevchar(). */
unsigned char *
utf8_step_backward(unsigned char *string, unsigned char *start,
int max, enum utf8_step way, int *count)
{
int steps = 0;
unsigned char *current = string;
assert(string);
assert(start);
assert(max >= 0);
if_assert_failed goto invalid_arg;
switch (way) {
case utf8_step_characters:
while (steps < max && current > start) {
--current;
if (utf8_islead(*current))
++steps;
}
break;
case utf8_step_cells_fewer:
case utf8_step_cells_more:
while (steps < max) {
unsigned char *prev = current;
unsigned char *look;
unicode_val_T u;
int width;
if (current <= start)
break;
do {
--current;
} while (current > start && !utf8_islead(*current));
look = current;
u = utf8_to_unicode(&look, prev);
if (u == UCS_NO_CHAR) {
/* Assume the incomplete sequence
* costs one cell. */
width = 1;
} else
width = unicode_to_cell(u);
if (way == utf8_step_cells_fewer
&& steps + width > max) {
/* Back off. */
current = prev;
break;
}
steps += width;
}
break;
default:
INTERNAL("impossible enum utf8_step");
}
invalid_arg:
if (count)
*count = steps;
return current;
}
/*
* Find out number of standard terminal collumns needed for displaying symbol
* (glyph) which represents Unicode character c.
* TODO: Use wcwidth when it is available.
*
* @return 2 for double-width glyph, 1 for others.
* TODO: May be extended to return 0 for zero-width glyphs
@ -388,6 +558,10 @@ utf8_cells2bytes(unsigned char *string, int max_cells, unsigned char *end)
inline int
unicode_to_cell(unicode_val_T c)
{
#if __STDC_ISO_10646__ && HAVE_WCWIDTH
if (wcwidth(c) >= 2)
return 2;
#else /* !__STDC_ISO_10646__ || !HAVE_WCWIDTH */
if (c >= 0x1100
&& (c <= 0x115f /* Hangul Jamo */
|| c == 0x2329
@ -403,13 +577,13 @@ unicode_to_cell(unicode_val_T c)
|| (c >= 0x20000 && c <= 0x2fffd)
|| (c >= 0x30000 && c <= 0x3fffd)))
return 2;
#endif /* !__STDC_ISO_10646__ || !HAVE_WCWIDTH */
return 1;
}
/* Fold the case of a Unicode character, so that hotkeys in labels can
* be compared case-insensitively. This should be called only if
* check_kbd_label_key(c) is true. It is unspecified whether the
* be compared case-insensitively. It is unspecified whether the
* result will be in upper or lower case. */
unicode_val_T
unicode_fold_label_case(unicode_val_T c)
@ -429,7 +603,7 @@ unicode_fold_label_case(unicode_val_T c)
}
inline unicode_val_T
utf_8_to_unicode(unsigned char **string, unsigned char *end)
utf8_to_unicode(unsigned char **string, unsigned char *end)
{
unsigned char *str = *string;
unicode_val_T u;
@ -480,23 +654,19 @@ utf_8_to_unicode(unsigned char **string, unsigned char *end)
*string = str + length;
return u;
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* Slow algorithm, the common part of cp2u and cp2utf_8. */
/* The common part of cp2u and cp2utf_8. */
static unicode_val_T
cp2u_shared(const struct codepage_desc *from, unsigned char c)
{
int j;
unicode_val_T u = from->highhalf[c - 0x80];
for (j = 0; from->table[j].c; j++)
if (from->table[j].c == c)
return from->table[j].u;
return UCS_NO_CHAR;
if (u == 0xFFFF) u = UCS_REPLACEMENT_CHARACTER;
return u;
}
#ifdef CONFIG_UTF_8
/* Slow algorithm, used for converting input from the terminal. */
/* Used for converting input from the terminal. */
unicode_val_T
cp2u(int from, unsigned char c)
{
@ -504,30 +674,48 @@ cp2u(int from, unsigned char c)
/* UTF-8 is a multibyte codepage and cannot be handled with
* this function. */
assert(codepages[from].table != table_utf_8);
if_assert_failed return UCS_NO_CHAR;
assert(!is_cp_ptr_utf8(&codepages[from]));
if_assert_failed return UCS_REPLACEMENT_CHARACTER;
if (c < 0x80) return c;
else return cp2u_shared(&codepages[from], c);
}
#endif /* CONFIG_UTF_8 */
/* This slow and ugly code is used by the terminal utf_8_io */
unsigned char *
cp2utf_8(int from, int c)
cp2utf8(int from, int c)
{
from &= ~SYSTEM_CHARSET_FLAG;
if (codepages[from].table == table_utf_8 || c < 128)
if (is_cp_ptr_utf8(&codepages[from]) || c < 128)
return strings[c];
return encode_utf_8(cp2u_shared(&codepages[from], c));
return encode_utf8(cp2u_shared(&codepages[from], c));
}
static void
add_utf_8(struct conv_table *ct, unicode_val_T u, unsigned char *str)
#ifdef CONFIG_UTF8
unicode_val_T
cp_to_unicode(int codepage, unsigned char **string, unsigned char *end)
{
unsigned char *p = encode_utf_8(u);
unicode_val_T ret;
if (is_cp_utf8(codepage))
return utf8_to_unicode(string, end);
if (*string >= end)
return UCS_NO_CHAR;
ret = cp2u(codepage, **string);
++*string;
return ret;
}
#endif /* CONFIG_UTF8 */
static void
add_utf8(struct conv_table *ct, unicode_val_T u, unsigned char *str)
{
unsigned char *p = encode_utf8(u);
while (p[1]) {
if (ct[*p].t) ct = ct[*p].u.tbl;
@ -567,7 +755,7 @@ free_utf_table(void)
}
static struct conv_table *
get_translation_table_to_utf_8(int from)
get_translation_table_to_utf8(int from)
{
int i;
static int lfr = -1;
@ -575,6 +763,7 @@ get_translation_table_to_utf_8(int from)
if (from == -1) return NULL;
from &= ~SYSTEM_CHARSET_FLAG;
if (from == lfr) return utf_table;
lfr = from;
if (utf_table_init)
memset(utf_table, 0, sizeof(utf_table)),
utf_table_init = 0;
@ -584,21 +773,27 @@ get_translation_table_to_utf_8(int from)
for (i = 0; i < 128; i++)
utf_table[i].u.str = strings[i];
if (codepages[from].table == table_utf_8) {
if (is_cp_ptr_utf8(&codepages[from])) {
for (i = 128; i < 256; i++)
utf_table[i].u.str = stracpy(strings[i]);
return utf_table;
}
for (i = 128; i < 256; i++)
utf_table[i].u.str = NULL;
for (i = 128; i < 256; i++) {
unicode_val_T u = codepages[from].highhalf[i - 0x80];
if (u == 0xFFFF)
utf_table[i].u.str = NULL;
else
utf_table[i].u.str = stracpy(encode_utf8(u));
}
for (i = 0; codepages[from].table[i].c; i++) {
unicode_val_T u = codepages[from].table[i].u;
if (!utf_table[codepages[from].table[i].c].u.str)
utf_table[codepages[from].table[i].c].u.str =
stracpy(encode_utf_8(u));
stracpy(encode_utf8(u));
}
for (i = 128; i < 256; i++)
@ -637,40 +832,41 @@ get_translation_table(int from, int to)
}
if (/*from == to ||*/ from == -1 || to == -1)
return NULL;
if (codepages[to].table == table_utf_8)
return get_translation_table_to_utf_8(from);
if (is_cp_ptr_utf8(&codepages[to]))
return get_translation_table_to_utf8(from);
if (from == lfr && to == lto)
return table;
lfr = from;
lto = to;
new_translation_table(table);
if (codepages[from].table == table_utf_8) {
if (is_cp_ptr_utf8(&codepages[from])) {
int i;
for (i = 0x80; i <= 0xFF; i++)
if (codepages[to].highhalf[i - 0x80] != 0xFFFF)
add_utf8(table,
codepages[to].highhalf[i - 0x80],
strings[i]);
for (i = 0; codepages[to].table[i].c; i++)
add_utf_8(table, codepages[to].table[i].u,
strings[codepages[to].table[i].c]);
add_utf8(table, codepages[to].table[i].u,
strings[codepages[to].table[i].c]);
for (i = 0; unicode_7b[i].x != -1; i++)
if (unicode_7b[i].x >= 0x80)
add_utf_8(table, unicode_7b[i].x,
unicode_7b[i].s);
add_utf8(table, unicode_7b[i].x,
unicode_7b[i].s);
} else {
int i;
for (i = 128; i < 256; i++) {
int j;
if (codepages[from].highhalf[i - 0x80] != 0xFFFF) {
unsigned char *u;
for (j = 0; codepages[from].table[j].c; j++) {
if (codepages[from].table[j].c == i) {
unsigned char *u;
u = u2cp(codepages[from].table[j].u, to);
if (u) table[i].u.str = u;
break;
}
u = u2cp(codepages[from].highhalf[i - 0x80], to);
if (u) table[i].u.str = u;
}
}
}
@ -741,12 +937,12 @@ get_entity_string(const unsigned char *str, const int strlen, int encoding)
if (strlen <= 0) return NULL;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
/* TODO: caching UTF-8 */
encoding &= ~SYSTEM_CHARSET_FLAG;
if (codepages[encoding].table == table_utf_8)
if (is_cp_ptr_utf8(&codepages[encoding]))
goto skip;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
if (first_time) {
memset(&nb_entity_cache, 0, ENTITY_CACHE_MAXLEN * sizeof(unsigned int));
@ -801,9 +997,9 @@ get_entity_string(const unsigned char *str, const int strlen, int encoding)
fprintf(stderr, "miss\n");
#endif
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
skip:
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
if (*str == '#') { /* Numeric entity. */
int l = (int) strlen;
unsigned char *st = (unsigned char *) str;
@ -855,11 +1051,11 @@ skip:
if (element) result = u2cp(element->c, encoding);
}
#ifdef CONFIG_UTF_8
if (codepages[encoding].table == table_utf_8) {
#ifdef CONFIG_UTF8
if (is_cp_ptr_utf8(&codepages[encoding])) {
return result;
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
end:
/* Take care of potential buffer overflow. */
if (strlen < sizeof(entity_cache[slen][0].str)) {
@ -1102,7 +1298,7 @@ charsets_list_next(void)
if (!codepages[i_name].name) return NULL;
kv.key = codepages[i_name].aliases[i_alias];
kv.data = &codepages[i_name];
kv.data = (void *) &codepages[i_name]; /* cast away const */
if (codepages[i_name].aliases[i_alias + 1])
i_alias++;
@ -1122,7 +1318,7 @@ static struct fastfind_index ff_charsets_index
int
get_cp_index(unsigned char *name)
{
struct codepage_desc *codepage;
const struct codepage_desc *codepage;
int syscp = 0;
if (!strcasecmp(name, "System")) {
@ -1188,5 +1384,5 @@ int
is_cp_utf8(int cp_index)
{
cp_index &= ~SYSTEM_CHARSET_FLAG;
return codepages[cp_index].table == table_utf_8;
return is_cp_ptr_utf8(&codepages[cp_index]);
}

View File

@ -3,7 +3,17 @@
typedef uint32_t unicode_val_T;
/* UCS/Unicode replacement character. */
/* U+FFFD REPLACEMENT CHARACTER. Used when no Unicode mapping is
* known for a byte in a codepage, or when invalid UTF-8 is received
* from a terminal. After generating the character, ELinks then
* treats it like any other Unicode character. The user can also type
* this character directly, and it can occur in documents. */
#define UCS_REPLACEMENT_CHARACTER ((unicode_val_T) 0xFFFD)
/* A special value that fits in unicode_val_T but is outside the range
* of Unicode characters. utf8_to_unicode and cp_to_unicode return
* this if the input is too short. This is also used as a placeholder
* for the second cell of a double-cell character. */
#define UCS_NO_CHAR ((unicode_val_T) 0xFFFFFFFD)
/* &nbsp; replacement character. See u2cp(). */
@ -53,22 +63,43 @@ unsigned char *get_cp_name(int);
unsigned char *get_cp_mime_name(int);
int is_cp_utf8(int);
void free_conv_table(void);
#ifdef CONFIG_UTF_8
inline unsigned char *encode_utf_8(unicode_val_T);
#ifdef CONFIG_UTF8
inline unsigned char *encode_utf8(unicode_val_T);
inline unsigned char *utf8_prevchar(unsigned char *, int, unsigned char *);
inline int utf8charlen(const unsigned char *);
int utf8_char2cells(unsigned char *, unsigned char *);
int utf8_ptr2cells(unsigned char *, unsigned char *);
int utf8_ptr2chars(unsigned char *, unsigned char *);
int utf8_cells2bytes(unsigned char *, int, unsigned char *);
/* How utf8_step_forward and utf8_step_backward count steps. */
enum utf8_step {
/* Each step is one character, even if it is a combining or
* double-width character. */
utf8_step_characters,
/* Each step is one cell. If the specified number of steps
* would end in the middle of a double-width character, do not
* include the character. */
utf8_step_cells_fewer,
/* Each step is one cell. If the specified number of steps
* would end in the middle of a double-width character,
* include the whole character. */
utf8_step_cells_more
};
unsigned char *utf8_step_forward(unsigned char *, unsigned char *,
int, enum utf8_step, int *);
unsigned char *utf8_step_backward(unsigned char *, unsigned char *,
int, enum utf8_step, int *);
inline int unicode_to_cell(unicode_val_T);
unicode_val_T unicode_fold_label_case(unicode_val_T);
inline int strlen_utf8(unsigned char **);
inline unicode_val_T utf_8_to_unicode(unsigned char **, unsigned char *);
unicode_val_T cp2u(int, unsigned char);
#endif /* CONFIG_UTF_8 */
inline unicode_val_T utf8_to_unicode(unsigned char **, unsigned char *);
unicode_val_T cp_to_unicode(int, unsigned char **, unsigned char *);
#endif /* CONFIG_UTF8 */
unsigned char *cp2utf_8(int, int);
unicode_val_T cp2u(int, unsigned char);
unsigned char *cp2utf8(int, int);
unsigned char *u2cp_(unicode_val_T, int, int no_nbsp_hack);
#define u2cp(u, to) u2cp_(u, to, 0)
@ -77,4 +108,16 @@ unsigned char *u2cp_(unicode_val_T, int, int no_nbsp_hack);
void init_charsets_lookup(void);
void free_charsets_lookup(void);
/* UTF-16 encodes each Unicode character U+0000...U+FFFF as a single
* 16-bit code unit, and each character U+10000...U+10FFFF as a pair
* of two code units: a high surrogate followed by a low surrogate.
* The range U+D800...U+DFFF is reserved for these surrogates. */
#define is_utf16_surrogate(u) (((u) & 0xFFFFF800) == 0xD800)
#define is_utf16_high_surrogate(u) (((u) & 0xFFFFFC00) == 0xD800)
#define is_utf16_low_surrogate(u) (((u) & 0xFFFFFC00) == 0xDC00)
#define join_utf16_surrogates(high,low) (0x10000 + (((high) - 0xD800L) << 10) + ((low) - 0xDC00))
#define needs_utf16_surrogates(u) ((uint32_t) ((u) - 0x10000) < 0x100000)
#define get_utf16_high_surrogate(u) (0xD800 + (((u) - 0x10000) >> 10))
#define get_utf16_low_surrogate(u) (0xDC00 + ((u) & 0x3FF))
#endif

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,7 @@ struct language languages[] = {
{N_("System"), "system"},
{N_("English"), "en"},
{N_("Afrikaans"), "af"},
{N_("Belarusian"), "be"},
{N_("Brazilian Portuguese"), "pt-BR"},
{N_("Bulgarian"), "bg"},

View File

@ -60,7 +60,8 @@ int register_event(unsigned char *name);
/* This unregisters an event number @event, freeing the resources it
* occupied, chain of associated hooks and unallocating the event id for
* further recyclation. */
* further recyclation.
* Bug 810: unregister_event has not yet been implemented. */
int unregister_event(int event);
int register_event_hook(int id, event_hook_T callback, int priority, void *data);

View File

@ -306,6 +306,13 @@ terminate_all_subsystems(void)
void
shrink_memory(int whole)
{
#ifdef CONFIG_SCRIPTING
/* The SMJS pre-format-html hook constructs an SMJS object for
* each cache entry. Give all scripting modules a cue to garbage
* collect any such objects so that the entries can be freed. */
if (whole)
trigger_event_name("flush-caches");
#endif
shrink_dns_cache(whole);
shrink_format_cache(whole);
garbage_collection(whole);

View File

@ -119,7 +119,7 @@ get_dyn_full_version(struct terminal *term, int more)
#ifndef CONFIG_MOUSE
comma, _("No mouse", term),
#endif
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
comma, "UTF-8",
#endif
comma,

View File

@ -32,6 +32,10 @@
#endif
#endif /* HAVE_GETIFADDRS */
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include "elinks.h"
#include "config/options.h"
@ -275,7 +279,7 @@ get_pasv_socket(struct socket *ctrl_socket, struct sockaddr_storage *addr)
struct sockaddr *pasv_addr = (struct sockaddr *) addr;
size_t addrlen;
int sock = -1;
int len;
socklen_t len;
#ifdef CONFIG_IPV6
struct sockaddr_in6 bind_addr6;
@ -449,7 +453,7 @@ static void
connected(struct socket *socket)
{
int err = 0;
int len = sizeof(err);
socklen_t len = sizeof(err);
assertm(socket->connect_info, "Lost connect_info!");
if_assert_failed return;

View File

@ -37,6 +37,13 @@
#define IP_ADDRESS_BUFFER_SIZE INET_ADDRSTRLEN
#endif
#ifndef PF_INET
#define PF_INET AF_INET
#endif
#ifndef PF_INET6
#define PF_INET6 AF_INET6
#endif
/* Attempt to workaround the EINTR mess. */
#if defined(EINTR) && !defined(CONFIG_OS_WIN32)

View File

@ -570,13 +570,41 @@ resize_window(int width, int height, int old_width, int old_height)
}
if (!x_error && status) {
double ratio_width = (double) attributes.width / old_width;
double ratio_height = (double) attributes.height / old_height;
XSizeHints *size_hints;
long mask;
int px_width = 0;
int px_height = 0;
width = (int) ((double) width * ratio_width);
height = (int) ((double) height * ratio_height);
/* With xterm 210, a window with 80x24 characters at
* a 6x13 font appears to have 484x316 pixels; both
* the width and height include four extra pixels.
* Computing a new size by scaling these values often
* results in windows that cannot display as many
* characters as was intended. We can do better if we
* can find out the actual size of character cells.
* If the terminal emulator has set a window size
* increment, assume that is the cell size. */
size_hints = XAllocSizeHints();
if (size_hints != NULL
&& XGetWMNormalHints(display, window, size_hints, &mask)
&& (mask & PResizeInc) != 0) {
px_width = attributes.width
+ (width - old_width) * size_hints->width_inc;
px_height = attributes.height
+ (height - old_height) * size_hints->height_inc;
}
if (px_width <= 0 || px_height <= 0) {
double ratio_width = (double) attributes.width / old_width;
double ratio_height = (double) attributes.height / old_height;
status = XResizeWindow(display, window, width, height);
px_width = (int) ((double) width * ratio_width);
px_height = (int) ((double) height * ratio_height);
}
if (size_hints)
XFree(size_hints);
status = XResizeWindow(display, window, px_width, px_height);
while (!x_error && !status) {
Window root, parent, *children;
unsigned int num_children;
@ -588,7 +616,7 @@ resize_window(int width, int height, int old_width, int old_height)
if (parent == root || parent == 0)
break;
window = parent;
status = XResizeWindow(display, window, width, height);
status = XResizeWindow(display, window, px_width, px_height);
}
}

View File

@ -78,7 +78,12 @@ sig_tstp(struct terminal *term)
if (!fork()) {
sleep(1);
kill(pid, SIGCONT);
exit(0);
/* Use _exit() rather than exit(), so that atexit
* functions are not called, and stdio output buffers
* are not flushed. Any such things must have been
* inherited from the parent process, which will take
* care of them when appropriate. */
_exit(0);
}
#endif
raise(SIGSTOP);

View File

@ -109,6 +109,7 @@ about_protocol_handler(struct connection *conn)
str = page->string;
len = strlen(str);
add_fragment(cached, 0, str, len);
conn->from = len;
break;
}
}

View File

@ -15,6 +15,10 @@
#include <netinet/in.h> /* OS/2 needs this after sys/types.h */
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include "elinks.h"
#include "protocol/bittorrent/bencoding.h"

View File

@ -574,11 +574,11 @@ bittorrent_message_dialog(struct session *ses, void *data)
uristring = get_uri_string(message->uri, URI_PUBLIC);
if (uristring) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (ses->tab->term->utf8)
decode_uri(uristring);
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
decode_uri_for_display(uristring);
add_format_to_string(&string,
_("Unable to retrieve %s", ses->tab->term),
@ -724,11 +724,11 @@ bittorrent_query_callback(void *data, enum connection_state state,
/* Let's make the filename pretty for display & save */
/* TODO: The filename can be the empty string here. See bug 396. */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
decode_uri_string(&filename);
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
decode_uri_string_for_display(&filename);
}

View File

@ -792,7 +792,7 @@ ftp_send_retr_req(struct connection *conn, int state)
/* Parse RETR response and return file size or -1 on error. */
static off_t
get_filesize_from_RETR(unsigned char *data, int data_len)
get_filesize_from_RETR(unsigned char *data, int data_len, int *resume)
{
off_t file_len;
int pos;
@ -801,6 +801,7 @@ get_filesize_from_RETR(unsigned char *data, int data_len)
/* Getting file size from text response.. */
/* 150 Opening BINARY mode data connection for hello-1.0-1.1.diff.gz (16452 bytes). */
*resume = 0;
for (pos = 0; pos < data_len && data[pos] != ASCII_LF; pos++)
if (data[pos] == '(')
pos_file_len = pos;
@ -825,6 +826,7 @@ get_filesize_from_RETR(unsigned char *data, int data_len)
kbytes++;
size = strtod((const char *)kbytes, &endptr);
if (endptr == (char *)kbytes) return -1;
*resume = 1;
return (off_t)(size * 1024.0);
}
@ -972,12 +974,16 @@ ftp_retr_file(struct socket *socket, struct read_buffer *rb)
* get filesize if needed. */
if (!ftp->dir && conn->est_length == -1) {
off_t file_len;
int res;
file_len = get_filesize_from_RETR(rb->data, rb->length);
file_len = get_filesize_from_RETR(rb->data, rb->length, &res);
if (file_len > 0) {
/* FIXME: ..when downloads resuming
* implemented.. */
conn->est_length = file_len + conn->progress->start;
/* This is right for vsftpd.
* Show me urls where this is wrong. --witekfl */
conn->est_length = res ?
file_len + conn->progress->start : file_len;
}
}
}

View File

@ -571,6 +571,8 @@ http_send_header(struct socket *socket)
return;
}
if (!conn->cached) conn->cached = find_in_cache(uri);
talking_to_proxy = IS_PROXY_URI(conn->uri) && !conn->socket->ssl;
use_connect = connection_is_https_proxy(conn) && !conn->socket->ssl;

View File

@ -268,6 +268,7 @@ run_lua_func(va_list ap, void *data)
return EVENT_HOOK_STATUS_NEXT;
}
/* bind_key (keymap, keystroke, function) */
static int
l_bind_key(LS)
{
@ -284,12 +285,22 @@ l_bind_key(LS)
if (!init_string(&event_name)) goto lua_error;
/* ELinks will need to call the Lua function when the user
* presses the key. However, ELinks cannot store a pointer
* to the function, because the C API of Lua does not provide
* one. Instead, ask the "reference system" of Lua to
* generate an integer key that ELinks can store.
*
* TODO: If l_bind_key() succeeds, then the function will
* never be removed from the reference system again, because
* the rest of ELinks does not tell this module if the
* keybinding is removed. This is part of bug 810. */
lua_pushvalue(S, 3);
ref = luaL_ref(S, LUA_REGISTRYINDEX);
add_format_to_string(&event_name, "lua-run-func %i", ref);
event_id = bind_key_to_event_name((unsigned char *) lua_tostring(S, 1),
(unsigned char *) lua_tostring(S, 2),
(const unsigned char *) lua_tostring(S, 2),
event_name.source, &err);
done_string(&event_name);

View File

@ -89,10 +89,26 @@ end:
return ret;
}
static enum evhook_status
script_hook_flush_caches(va_list ap, void *data)
{
/* script_hook_pre_format_html() calls smjs_get_cache_entry_object()
* for each struct cache_entry. The resulting SMJS objects hold
* references to the structs, and these references prevent ELinks
* from freeing the cache entries. (The resource info dialog shows
* that the entries are "in use".) SMJS does not immediately collect
* these objects as garbage. If we're really trying to flush the
* caches then ask SMJS to run a check. */
if (smjs_ctx)
JS_GC(smjs_ctx);
return EVENT_HOOK_STATUS_NEXT;
}
struct event_hook_info smjs_scripting_hooks[] = {
{ "goto-url", 0, script_hook_url, "goto_url_hook" },
{ "follow-url", 0, script_hook_url, "follow_url_hook" },
{ "pre-format-html", 0, script_hook_pre_format_html, NULL },
{ "flush-caches", 0, script_hook_flush_caches, NULL },
NULL_EVENT_HOOK_INFO,
};

View File

@ -17,7 +17,7 @@ static JSBool
keymap_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
{
unsigned char *action_str;
unsigned char *keystroke_str;
const unsigned char *keystroke_str;
int *data = JS_GetPrivate(ctx, obj);
enum keymap_id keymap_id = *data;
@ -64,7 +64,7 @@ keymap_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
int *data = JS_GetPrivate(ctx, obj);
enum keymap_id keymap_id = *data;
unsigned char *keymap_str;
unsigned char *keystroke_str;
const unsigned char *keystroke_str;
/* Ugly fact: we need to get the string from the id to give to bind_do,
* which will of course then convert the string back to an id... */

View File

@ -1134,11 +1134,11 @@ do_type_query(struct type_query *type_query, unsigned char *ct, struct mime_hand
/* Let's make the filename pretty for display & save */
/* TODO: The filename can be the empty string here. See bug 396. */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
decode_uri_string(&filename);
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
decode_uri_string_for_display(&filename);
}

View File

@ -221,9 +221,9 @@ get_master_session(void)
foreach (ses, sessions)
if (ses->tab->term->master) {
struct window *tab = get_current_tab(ses->tab->term);
struct window *current_tab = get_current_tab(ses->tab->term);
return tab ? tab->data : NULL;
return current_tab ? current_tab->data : NULL;
}
return NULL;
@ -268,11 +268,11 @@ print_error_dialog(struct session *ses, enum connection_state state,
uristring = uri ? get_uri_string(uri, URI_PUBLIC) : NULL;
if (uristring) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (ses->tab->term->utf8)
decode_uri(uristring);
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
decode_uri_for_display(uristring);
add_format_to_string(&msg,
_("Unable to retrieve %s", ses->tab->term),

View File

@ -539,8 +539,8 @@ loading_callback(struct download *download, struct session *ses)
}
if (is_in_result_state(download->state) && download->state != S_OK) {
print_error_dialog(ses, download->state, download->conn->uri,
download->pri);
print_error_dialog(ses, download->state,
download->conn ? download->conn->uri : NULL, download->pri);
if (d == DO_MOVE_ABORT) reload(ses, CACHE_MODE_NORMAL);
}

View File

@ -269,15 +269,7 @@ set_term_color16(struct screen_char *schar, enum color_flags flags,
if (use_inverse(bg, fg)) {
schar->attr |= SCREEN_ATTR_STANDOUT;
}
#if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS)
/* With 256 color support we use memcmp() when comparing color in
* terminal/screen.c:add_char*() so we need to clear this byte. */
TERM_COLOR_FOREGROUND(schar->color) = (fg & TERM_COLOR_MASK);
TERM_COLOR_BACKGROUND(schar->color) = bg;
#else
schar->color[0] = (bg << 4 | fg);
#endif
}
void
@ -325,6 +317,24 @@ set_term_color(struct screen_char *schar, struct color_pair *pair,
/* TODO: Handle decrease lightness by converting to
* hue-ligthness-saturation color model */
break;
#endif
#ifdef CONFIG_TRUE_COLOR
case COLOR_MODE_TRUE_COLOR:
/* TODO: make it better */
if (pair->foreground == pair->background && (flags & COLOR_ENSURE_CONTRAST)) {
if (flags & COLOR_ENSURE_INVERTED_CONTRAST) {
pair->background = (pair->foreground == 0) ? 0xffffff : 0;
} else {
pair->foreground = (pair->background == 0) ? 0xffffff : 0;
}
}
schar->color[0] = (pair->foreground >> 16) & 255; /* r */
schar->color[1] = (pair->foreground >> 8) & 255; /* g */
schar->color[2] = pair->foreground & 255; /* b */
schar->color[3] = (pair->background >> 16) & 255; /* r */
schar->color[4] = (pair->background >> 8) & 255; /* g */
schar->color[5] = pair->background & 255; /* b */
return;
#endif
case COLOR_MODE_DUMP:
return;
@ -368,9 +378,13 @@ set_term_color(struct screen_char *schar, struct color_pair *pair,
}
}
TERM_COLOR_FOREGROUND(schar->color) = fg;
TERM_COLOR_BACKGROUND(schar->color) = bg;
TERM_COLOR_FOREGROUND_256(schar->color) = fg;
TERM_COLOR_BACKGROUND_256(schar->color) = bg;
break;
#endif
#ifdef CONFIG_TRUE_COLOR
case COLOR_MODE_TRUE_COLOR:
return;
#endif
case COLOR_MODE_MONO:
case COLOR_MODE_16:

View File

@ -15,12 +15,11 @@ struct screen_char;
#define TERM_COLOR_MASK 0x07
#if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS)
#define TERM_COLOR_FOREGROUND(color) ((color)[0])
#define TERM_COLOR_BACKGROUND(color) ((color)[1])
#else
#define TERM_COLOR_FOREGROUND(color) ((color)[0] & TERM_COLOR_MASK)
#define TERM_COLOR_BACKGROUND(color) (((color)[0] >> 4) & TERM_COLOR_MASK)
#define TERM_COLOR_FOREGROUND_256(color) ((color)[0])
#define TERM_COLOR_BACKGROUND_256(color) ((color)[1])
#endif
#define TERM_COLOR_FOREGROUND_16(color) ((color)[0] & TERM_COLOR_MASK)
#define TERM_COLOR_BACKGROUND_16(color) (((color)[0] >> 4) & TERM_COLOR_MASK)
/* Bit flags to control how the colors are handled. */
enum color_flags {
@ -51,7 +50,9 @@ enum color_mode {
#ifdef CONFIG_256_COLORS
COLOR_MODE_256,
#endif
#ifdef CONFIG_TRUE_COLOR
COLOR_MODE_TRUE_COLOR,
#endif
COLOR_MODES, /* XXX: Keep last */
};

View File

@ -22,10 +22,12 @@
int_bounds(&(y), 0, (term)->height - 1); \
} while (0)
#if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS)
#define clear_screen_char_color(schar) do { memset((schar)->color, 0, 2); } while (0)
#if SCREEN_COLOR_SIZE > 1
#define clear_screen_char_color(schar) \
do { memset((schar)->color, 0, SCREEN_COLOR_SIZE); } while (0)
#else
#define clear_screen_char_color(schar) do { (schar)->color[0] = 0; } while (0)
#define clear_screen_char_color(schar) \
do { (schar)->color[0] = 0; } while (0)
#endif
@ -103,11 +105,11 @@ draw_char_color(struct terminal *term, int x, int y, struct color_pair *color)
}
void
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
draw_char_data(struct terminal *term, int x, int y, unicode_val_T data)
#else
draw_char_data(struct terminal *term, int x, int y, unsigned char data)
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
struct screen_char *screen_char = get_char(term, x, y);
@ -115,7 +117,7 @@ draw_char_data(struct terminal *term, int x, int y, unsigned char data)
screen_char->data = data;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
#ifdef CONFIG_DEBUG
/* Detect attempt to draw double-width char on the last
* column of terminal. */
@ -125,7 +127,7 @@ draw_char_data(struct terminal *term, int x, int y, unsigned char data)
if (data == UCS_NO_CHAR)
screen_char->attr = 0;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
set_screen_dirty(term->screen, y, y);
}
@ -145,7 +147,7 @@ draw_line(struct terminal *term, int x, int y, int l, struct screen_char *line)
size = int_min(l, term->width - x);
if (size == 0) return;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
struct screen_char *sc;
@ -248,7 +250,7 @@ draw_border(struct terminal *term, struct box *box,
set_screen_dirty(term->screen, borderbox.y, borderbox.y + borderbox.height);
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
/* Checks cells left and right to the box for broken double-width chars.
* Replace it with ' '.
* 1+---+3
@ -319,7 +321,7 @@ fix_dwchar_around_box(struct terminal *term, struct box *box, int border,
}
#endif
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
void
draw_char(struct terminal *term, int x, int y,
unicode_val_T data, enum screen_char_attr attr,
@ -329,7 +331,7 @@ void
draw_char(struct terminal *term, int x, int y,
unsigned char data, enum screen_char_attr attr,
struct color_pair *color)
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
struct screen_char *screen_char = get_char(term, x, y);
@ -405,7 +407,7 @@ draw_shadow(struct terminal *term, struct box *box,
draw_box(term, &dbox, ' ', 0, color);
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
static void
draw_text_utf8(struct terminal *term, int x, int y,
unsigned char *text, int length,
@ -421,7 +423,7 @@ draw_text_utf8(struct terminal *term, int x, int y,
if (length <= 0) return;
if (x >= term->width) return;
data = utf_8_to_unicode(&text, end);
data = utf8_to_unicode(&text, end);
if (data == UCS_NO_CHAR) return;
start = get_char(term, x, y);
if (color) {
@ -454,7 +456,7 @@ draw_text_utf8(struct terminal *term, int x, int y,
x++;
for (; x < term->width; x++, pos++) {
data = utf_8_to_unicode(&text, end);
data = utf8_to_unicode(&text, end);
if (data == UCS_NO_CHAR) break;
if (color) copy_screen_chars(pos, start, 1);
@ -477,7 +479,7 @@ draw_text_utf8(struct terminal *term, int x, int y,
set_screen_dirty(term->screen, y, y);
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
void
draw_text(struct terminal *term, int x, int y,
@ -490,12 +492,12 @@ draw_text(struct terminal *term, int x, int y,
assert(text && length >= 0);
if_assert_failed return;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
draw_text_utf8(term, x, y, text, length, attr, color);
return;
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
if (length <= 0) return;
pos = get_char(term, x, y);

View File

@ -7,6 +7,16 @@ struct color_pair;
struct box;
struct terminal;
#if defined(CONFIG_TRUE_COLOR)
/* 0, 1, 2 - rgb foreground; 3, 4, 5 - rgb background */
#define SCREEN_COLOR_SIZE 6
#elif defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS)
/* 0 is foreground; 1 is background */
#define SCREEN_COLOR_SIZE 2
#else
#define SCREEN_COLOR_SIZE 1
#endif
/* All attributes should fit inside an unsigned char. */
/* XXX: The bold mask is used as part of the color encoding. */
enum screen_char_attr {
@ -21,21 +31,17 @@ enum screen_char_attr {
/* One position in the terminal screen's image. */
struct screen_char {
/* Contains either character value or frame data. */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
unicode_val_T data;
#else
unsigned char data;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* Attributes are screen_char_attr bits. */
unsigned char attr;
/* The encoded fore- and background color. */
#if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS)
unsigned char color[2];
#else
unsigned char color[1];
#endif
/* The fore- and background color. */
unsigned char color[SCREEN_COLOR_SIZE];
};
#define copy_screen_chars(to, from, amount) \
@ -208,11 +214,11 @@ void draw_char_color(struct terminal *term, int x, int y,
struct color_pair *color);
/* Sets the data of a screen position. */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
void draw_char_data(struct terminal *term, int x, int y, unicode_val_T data);
#else
void draw_char_data(struct terminal *term, int x, int y, unsigned char data);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* Sets the data to @border and of a screen position. */
void draw_border_char(struct terminal *term, int x, int y,
@ -223,7 +229,7 @@ void draw_border_cross(struct terminal *, int x, int y,
enum border_cross_direction, struct color_pair *color);
/* Draws a char. */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
void draw_char(struct terminal *term, int x, int y,
unicode_val_T data, enum screen_char_attr attr,
struct color_pair *color);
@ -231,7 +237,7 @@ void draw_char(struct terminal *term, int x, int y,
void draw_char(struct terminal *term, int x, int y,
unsigned char data, enum screen_char_attr attr,
struct color_pair *color);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* Draws area defined by @box using the same colors and attributes. */
void draw_box(struct terminal *term, struct box *box,
@ -246,10 +252,10 @@ void draw_shadow(struct terminal *term, struct box *box,
void draw_border(struct terminal *term, struct box *box,
struct color_pair *color, int width);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
void fix_dwchar_around_box(struct terminal *term, struct box *box, int border,
int shadow_width, int shadow_height);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* Draws @length chars from @text. */
void draw_text(struct terminal *term, int x, int y,

View File

@ -43,14 +43,14 @@ struct terminal_interlink {
struct {
unicode_val_T ucs;
int len;
int min;
unicode_val_T min;
/* Modifier keys from the key event that carried the
* first byte of the character. We need this because
* ELinks sees e.g. ESC U+00F6 as 0x1B 0xC3 0xB6 and
* converts it to Alt-0xC3 0xB6, attaching the
* modifier to the first byte only. */
int modifier;
} utf_8;
term_event_modifier_T modifier;
} utf8;
/* This is the queue of events as coming from the other ELinks instance
* owning the hosting terminal. */
@ -133,14 +133,15 @@ term_send_event(struct terminal *term, struct term_event *ev)
}
static void
term_send_ucs(struct terminal *term, unicode_val_T u, int modifier)
term_send_ucs(struct terminal *term, unicode_val_T u,
term_event_modifier_T modifier)
{
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
struct term_event ev;
set_kbd_term_event(&ev, u, modifier);
term_send_event(term, &ev);
#else /* !CONFIG_UTF_8 */
#else /* !CONFIG_UTF8 */
struct term_event ev;
unsigned char *recoded;
@ -152,7 +153,7 @@ term_send_ucs(struct terminal *term, unicode_val_T u, int modifier)
term_send_event(term, &ev);
recoded++;
}
#endif /* !CONFIG_UTF_8 */
#endif /* !CONFIG_UTF8 */
}
static void
@ -177,12 +178,12 @@ check_terminal_name(struct terminal *term, struct terminal_info *info)
object_unlock(term->spec);
term->spec = get_opt_rec(config_options, name);
object_lock(term->spec);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
/* Probably not best place for set this. But now we finally have
* term->spec and term->utf8 should be set before decode session info.
* --Scrool */
term->utf8 = get_opt_bool_tree(term->spec, "utf_8_io");
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
}
#ifdef CONFIG_MOUSE
@ -235,7 +236,7 @@ handle_interlink_event(struct terminal *term, struct interlink_event *ilev)
* terminal screen before decoding the session info so that
* handling of bad URL syntax by openning msg_box() will be
* possible. */
set_init_term_event(&tev,
set_init_term_event(&tev,
ilev->info.size.width,
ilev->info.size.height);
term_send_event(term, &tev);
@ -277,7 +278,7 @@ handle_interlink_event(struct terminal *term, struct interlink_event *ilev)
{
int utf8_io = -1;
int key = ilev->info.keyboard.key;
int modifier = ilev->info.keyboard.modifier;
term_event_modifier_T modifier = ilev->info.keyboard.modifier;
if (key >= 0x100)
key = -key;
@ -294,7 +295,7 @@ handle_interlink_event(struct terminal *term, struct interlink_event *ilev)
}
/* Character Conversions. */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
/* struct term_event_keyboard carries UCS-4.
* - If the "utf_8_io" option (i.e. term->utf8) is
* true or the "charset" option refers to UTF-8,
@ -316,7 +317,7 @@ handle_interlink_event(struct terminal *term, struct interlink_event *ilev)
* - Otherwise, handle_interlink_event() passes the
* bytes straight through. */
utf8_io = get_opt_bool_tree(term->spec, "utf_8_io");
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* In UTF-8 byte sequences that have more than one byte, the
* first byte is between 0xC0 and 0xFF and the remaining bytes
@ -324,34 +325,38 @@ handle_interlink_event(struct terminal *term, struct interlink_event *ilev)
* it is between 0x00 and 0x7F and it is straight ASCII.
* (All 'betweens' are inclusive.) */
if (interlink->utf_8.len) {
if (interlink->utf8.len) {
/* A previous call to handle_interlink_event
* got a UTF-8 start byte. */
if (key >= 0x80 && key <= 0xBF && utf8_io) {
/* This is a UTF-8 continuation byte. */
interlink->utf_8.ucs <<= 6;
interlink->utf_8.ucs |= key & 0x3F;
if (! --interlink->utf_8.len) {
unicode_val_T u = interlink->utf_8.ucs;
interlink->utf8.ucs <<= 6;
interlink->utf8.ucs |= key & 0x3F;
if (! --interlink->utf8.len) {
unicode_val_T u = interlink->utf8.ucs;
if (u < interlink->utf_8.min)
u = UCS_NO_CHAR;
/* UTF-8 allows neither overlong
* sequences nor surrogates. */
if (u < interlink->utf8.min
|| is_utf16_surrogate(u))
u = UCS_REPLACEMENT_CHARACTER;
term_send_ucs(term, u,
term->interlink->utf_8.modifier);
term->interlink->utf8.modifier);
}
break;
} else {
/* The byte sequence for this character is
* ending prematurely. Send UCS_NO_CHAR for the
* terminated character, but don't break; let
* this byte be handled below. */
/* The byte sequence for this character
* is ending prematurely. Send
* UCS_REPLACEMENT_CHARACTER for the
* terminated character, but don't break;
* let this byte be handled below. */
interlink->utf_8.len = 0;
term_send_ucs(term, UCS_NO_CHAR,
term->interlink->utf_8.modifier);
interlink->utf8.len = 0;
term_send_ucs(term, UCS_REPLACEMENT_CHARACTER,
term->interlink->utf8.modifier);
}
}
@ -361,7 +366,7 @@ handle_interlink_event(struct terminal *term, struct interlink_event *ilev)
* UTF-8 start and continuation bytes or UTF-8 I/O mode
* is disabled. */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (key >= 0 && key <= 0xFF && !utf8_io) {
/* Not special and UTF-8 mode is disabled:
* recode from the terminal charset to UCS-4. */
@ -372,7 +377,7 @@ handle_interlink_event(struct terminal *term, struct interlink_event *ilev)
term_send_ucs(term, key, modifier);
break;
}
#endif /* !CONFIG_UTF_8 */
#endif /* !CONFIG_UTF8 */
/* It must be special (e.g., F1 or Enter)
* or a single-byte UTF-8 character. */
@ -383,27 +388,44 @@ handle_interlink_event(struct terminal *term, struct interlink_event *ilev)
} else if ((key & 0xC0) == 0xC0 && (key & 0xFE) != 0xFE) {
/* This is a UTF-8 start byte. */
unsigned int mask, cov = 0x80;
/* Minimum character values for UTF-8 octet
* sequences of each length, from RFC 2279.
* According to the RFC, UTF-8 decoders should
* reject characters that are encoded with
* more octets than necessary. (RFC 3629,
* which ELinks does not yet otherwise follow,
* tightened the "should" to "MUST".) */
static const unicode_val_T min[] = {
0x00000080, /* ... 0x000007FF with 2 octets */
0x00000800, /* ... 0x0000FFFF with 3 octets */
0x00010000, /* ... 0x001FFFFF with 4 octets */
0x00200000, /* ... 0x03FFFFFF with 5 octets */
0x04000000 /* ... 0x7FFFFFFF with 6 octets */
};
unsigned int mask;
int len = 0;
/* The number of 1's between the first bit and first
* 0 bit (exclusive) is the number of remaining
* continuation bytes in the encoding of the character
* that is now being processed, which number will be
* stored in interlink->utf_8.len. */
for (mask = 0x80; key & mask; mask >>= 1) {
/* Set @len = the number of contiguous 1's
* in the most significant bits of the first
* octet, i.e. @key. It is also the number
* of octets in the character. Leave @mask
* pointing to the first 0 bit found. */
for (mask = 0x80; key & mask; mask >>= 1)
len++;
interlink->utf_8.min = cov;
cov = 1 << (1 + 5 * len);
}
interlink->utf_8.len = len - 1;
interlink->utf_8.ucs = key & (mask - 1);
interlink->utf_8.modifier = modifier;
/* This will hold because @key was checked above. */
assert(len >= 2 && len <= 6);
if_assert_failed goto invalid_utf8_start_byte;
interlink->utf8.min = min[len - 2];
interlink->utf8.len = len - 1;
interlink->utf8.ucs = key & (mask - 1);
interlink->utf8.modifier = modifier;
break;
}
term_send_ucs(term, UCS_NO_CHAR, modifier);
invalid_utf8_start_byte:
term_send_ucs(term, UCS_REPLACEMENT_CHARACTER, modifier);
break;
}

View File

@ -71,17 +71,21 @@ set_mouse_interlink_event(struct interlink_event *ev, int x, int y, unsigned int
}
static inline void
set_kbd_term_event(struct term_event *ev, int key, int modifier)
set_kbd_term_event(struct term_event *ev, int key,
term_event_modifier_T modifier)
{
memset(ev, 0, sizeof(*ev));
ev->ev = EVENT_KBD;
kbd_set(&ev->info.keyboard, key, modifier);
}
/* @key can be e.g. KBD_ENTER as in term_event_keyboard.key.
* This function then sets ev->info.keyboard.key = -KBD_ENTER. */
/* @key can be either an 8-bit byte or a value from enum term_event_special_key.
* In the latter case, this function negates the value, unless it is KBD_UNDEF.
* For example, key == KBD_ENTER results in ev->info.keyboard.key = -KBD_ENTER.
* This mapping keeps the interlink protocol compatible with ELinks 0.11. */
static inline void
set_kbd_interlink_event(struct interlink_event *ev, int key, int modifier)
set_kbd_interlink_event(struct interlink_event *ev, int key,
term_event_modifier_T modifier)
{
memset(ev, 0, sizeof(*ev));
ev->ev = EVENT_KBD;
@ -166,17 +170,7 @@ void in_term(struct terminal *);
#define check_kbd_modifier(event, mod) (kbd_modifier_is(&(event)->info.keyboard, (mod)))
#define check_kbd_textinput_key(event) (get_kbd_key(event) >= ' ' && check_kbd_modifier(event, KBD_MOD_NONE))
#ifdef CONFIG_UTF_8
/* We must currently limit hotkeys of labels to ASCII, because
* get_kbd_key(event) is in UCS-4 and various event handlers pass it
* to toupper() if check_kbd_label_key() returns true.
* TO DO: Change the event handlers to use unicode_fold_label_case()
* instead. The code that extracts the hotkey from the label string
* will also have to be changed. */
#define check_kbd_label_key(event) (get_kbd_key(event) > ' ' && get_kbd_key(event) <= 0x7F)
#else /* !CONFIG_UTF_8 */
#define check_kbd_label_key(event) (get_kbd_key(event) > ' ')
#endif /* !CONFIG_UTF_8 */
#define check_kbd_label_key(event) (get_kbd_key(event) > ' ' && (check_kbd_modifier(event, KBD_MOD_NONE) || check_kbd_modifier(event, KBD_MOD_ALT)))
/* For mouse events handling */

View File

@ -48,6 +48,14 @@ static int process_queue(struct itrm *);
static void handle_itrm_stdin(struct itrm *);
static void unhandle_itrm_stdin(struct itrm *);
#ifdef CONFIG_DEBUG
/* This hack makes GCC put enum term_event_special_key in the debug
* information even though it is not otherwise used. The const
* prevents an unused-variable warning. */
static const enum term_event_special_key dummy_term_event_special_key;
#endif
int
is_blocked(void)
{
@ -198,7 +206,7 @@ resize_terminal(void)
itrm_queue_event(ditrm, (char *) &ev, sizeof(ev));
}
static void
void
get_terminal_name(unsigned char name[MAX_TERM_LEN])
{
unsigned char *term = getenv("TERM");
@ -684,6 +692,26 @@ decode_terminal_escape_sequence(struct itrm *itrm, struct interlink_event *ev)
fflush(stderr);
#endif
/* The following information should be listed for each escape
* sequence recognized here:
*
* 1. Which control function ECMA-48 assigns to the sequence.
* Put parentheses around this if the control function
* seems unrelated to how ELinks actually treats the
* sequence. Write "private" if it is a control sequence
* reserved for private or experimental use in ECMA-48.
* (Those have a Final Byte in the range 0x70 to 0x7F,
* optionally preceded by a single Intermediate Byte 0x20.)
*
* 2. The capname used by Terminfo, if any. These should help
* when ELinks is eventually changed to read escape
* sequences from Terminfo (bug 96).
*
* 3. The $TERM identifier of some terminal that generates
* this escape sequence with the meaning expected by
* ELinks. Escape sequences with no known terminal may end
* up being removed from ELinks when bug 96 is fixed.
*/
switch (c) { /* ECMA-48 Terminfo $TERM */
case 0: return -1; /* ------- -------- ----- */
case 'A': kbd.key = KBD_UP; break; /* CUU kcuu1 vt200 */
@ -709,6 +737,9 @@ decode_terminal_escape_sequence(struct itrm *itrm, struct interlink_event *ev)
case 'W': kbd.key = KBD_F11; break; /* (CTC) kf11 cons25 */
case 'X': kbd.key = KBD_F12; break; /* (ECH) kf12 cons25 */
case 'Z': /* CBT kcbt cons25 */
kbd.key = KBD_TAB; kbd.modifier = KBD_MOD_SHIFT; break;
case 'z': switch (v) { /* private */
case 247: kbd.key = KBD_INS; break; /* kich1 */
case 214: kbd.key = KBD_HOME; break; /* khome sun */
@ -833,8 +864,14 @@ decode_terminal_application_key(struct itrm *itrm, struct interlink_event *ev)
}
/* Initialize *@ev to match the byte @key received from the terminal.
* Actually, @key could also be a value from enum term_event_special_key;
* but callers that use those values generally don't need the mapping
* provided by this function, so they call set_kbd_interlink_event()
* directly. */
static void
set_kbd_event(struct interlink_event *ev, int key, int modifier)
set_kbd_event(struct interlink_event *ev,
int key, term_event_modifier_T modifier)
{
switch (key) {
case ASCII_TAB:
@ -865,7 +902,7 @@ set_kbd_event(struct interlink_event *ev, int key, int modifier)
default:
if (key < ' ') {
key += 'A' - 1;
modifier = KBD_MOD_CTRL;
modifier |= KBD_MOD_CTRL;
}
}
@ -1018,7 +1055,7 @@ process_queue(struct itrm *itrm)
if (ev.ev == EVENT_MOUSE || ev.info.keyboard.key != KBD_UNDEF)
itrm_queue_event(itrm, (char *) &ev, sizeof(ev));
return_without_event:
return_without_event:
if (el == -1) {
install_timer(&itrm->timer, ESC_TIMEOUT, (void (*)(void *)) kbd_timeout,
itrm);

View File

@ -1,66 +1,117 @@
#ifndef EL__TERMINAL_KBD_H
#define EL__TERMINAL_KBD_H
#include "intl/charsets.h"
struct itrm;
/* A character received from a terminal. */
#ifdef CONFIG_UTF8
typedef unicode_val_T term_event_char_T; /* in UCS-4 */
#else
typedef unsigned char term_event_char_T; /* in the charset of the terminal */
#endif
/* A key received from a terminal, without modifiers. The value is
* either from term_event_char_T or from enum term_event_special_key.
* To check which one it is, use is_kbd_character().
*
* Values <= -0x100 are special; from enum term_event_special_key.
* Values between -0xFF and -2 are not used yet; treat as special.
* Value == -1 is KBD_UNDEF; not sent via socket.
* Values >= 0 are characters; from term_event_char_T.
*
* Any at least 32-bit signed integer type would work here; using an
* exact-width type hurts portability in principle, but some other
* parts of ELinks already require the existence of uint32_t. */
typedef int32_t term_event_key_T;
/* Values for term_event_keyboard.modifier and
* interlink_event_keyboard.modifier */
typedef enum {
KBD_MOD_NONE = 0,
KBD_MOD_SHIFT = 1,
KBD_MOD_CTRL = 2,
KBD_MOD_ALT = 4
} term_event_modifier_T;
/* A key received from a terminal, with modifiers. */
struct term_event_keyboard {
/* Values <= -0x100 are special; e.g. KBD_ENTER.
* Values between -0xFF and -2 are not used yet; treat as special.
* Value == -1 is KBD_UNDEF; not sent via socket.
* Values >= 0 are characters received from the terminal;
* in UCS-4 #ifdef CONFIG_UTF_8. */
int key;
int modifier;
term_event_key_T key;
term_event_modifier_T modifier;
};
/* Like struct term_event_keyboard but used in the interlink protocol
* between ELinks processes. Because the processes may be running
* different versions of ELinks, especially if a new version has just
* been installed, this structure should be kept binary compatible as
* long as possible. See bug 793 for a list of pending changes to the
* protocol. */
struct interlink_event_keyboard {
/* Values <= -2 are not used, for ELinks 0.11 compatibility.
/* This is like term_event_key_T but carries individual bytes
* rather than entire characters, and uses different values
* for special keys.
*
* Values <= -2 are not used, for ELinks 0.11 compatibility.
* Value == -1 is KBD_UNDEF; not sent via socket.
* Values between 0 and 0xFF are bytes received from the terminal.
* Values >= 0x100 are special; e.g. -KBD_ENTER. */
* Values >= 0x100 are special; absolute values of constants
* from enum term_event_special_key, e.g. -KBD_ENTER. */
int key;
/* The values are from term_event_modifier_T, but the type
* must be int so that the representation remains compatible
* with ELinks 0.11. */
int modifier;
};
#define KBD_UNDEF -1
/* Codes of special keys, for use in term_event_key_T.
* The enum has a tag mainly to let you cast numbers to it in GDB and see
* their names. ELinks doesn't use this enum type as term_event_key_T,
* because it might be 16-bit and Unicode characters wouldn't then fit. */
enum term_event_special_key {
KBD_UNDEF = -1,
#define KBD_ENTER (-0x100)
#define KBD_BS (-0x101)
#define KBD_TAB (-0x102)
#define KBD_ESC (-0x103)
#define KBD_LEFT (-0x104)
#define KBD_RIGHT (-0x105)
#define KBD_UP (-0x106)
#define KBD_DOWN (-0x107)
#define KBD_INS (-0x108)
#define KBD_DEL (-0x109)
#define KBD_HOME (-0x10a)
#define KBD_END (-0x10b)
#define KBD_PAGE_UP (-0x10c)
#define KBD_PAGE_DOWN (-0x10d)
KBD_ENTER = -0x100,
KBD_BS = -0x101,
KBD_TAB = -0x102,
KBD_ESC = -0x103,
KBD_LEFT = -0x104,
KBD_RIGHT = -0x105,
KBD_UP = -0x106,
KBD_DOWN = -0x107,
KBD_INS = -0x108,
KBD_DEL = -0x109,
KBD_HOME = -0x10a,
KBD_END = -0x10b,
KBD_PAGE_UP = -0x10c,
KBD_PAGE_DOWN = -0x10d,
#define KBD_F1 (-0x120)
#define KBD_F2 (-0x121)
#define KBD_F3 (-0x122)
#define KBD_F4 (-0x123)
#define KBD_F5 (-0x124)
#define KBD_F6 (-0x125)
#define KBD_F7 (-0x126)
#define KBD_F8 (-0x127)
#define KBD_F9 (-0x128)
#define KBD_F10 (-0x129)
#define KBD_F11 (-0x12a)
#define KBD_F12 (-0x12b)
static inline int is_kbd_fkey(int key) { return key <= KBD_F1 && key >= KBD_F12; }
KBD_F1 = -0x120,
KBD_F2 = -0x121,
KBD_F3 = -0x122,
KBD_F4 = -0x123,
KBD_F5 = -0x124,
KBD_F6 = -0x125,
KBD_F7 = -0x126,
KBD_F8 = -0x127,
KBD_F9 = -0x128,
KBD_F10 = -0x129,
KBD_F11 = -0x12a,
KBD_F12 = -0x12b,
KBD_CTRL_C = -0x200
};
static inline int is_kbd_fkey(term_event_key_T key) { return key <= KBD_F1 && key >= KBD_F12; }
#define number_to_kbd_fkey(num) (KBD_F1 - (num) + 1)
#define kbd_fkey_to_number(key) (KBD_F1 - (key) + 1)
#define KBD_CTRL_C (-0x200)
#define KBD_MOD_NONE 0
#define KBD_MOD_SHIFT 1
#define KBD_MOD_CTRL 2
#define KBD_MOD_ALT 4
/* int is_kbd_character(term_event_key_T key);
* Check whether @key is a character or a special key.
* Return true if @key is a character from term_event_char_T.
* (The character is not necessarily printable.)
* Return false if @key is a special key from enum term_event_special_key. */
#define is_kbd_character(key) ((key) >= 0)
void
handle_trm(int std_in, int std_out, int sock_in, int sock_out, int ctl_in,
@ -74,6 +125,7 @@ void resize_terminal(void);
void dispatch_special(unsigned char *);
void kbd_ctrl_c(void);
int is_blocked(void);
void get_terminal_name(unsigned char *);
#define kbd_get_key(kbd_) ((kbd_)->key)
#define kbd_key_is(kbd_, key) (kbd_get_key(kbd_) == (key))

View File

@ -31,7 +31,7 @@
unsigned char frame_dumb[48] = " ||||++||++++++--|-+||++--|-+----++++++++ ";
static unsigned char frame_vt100[48] = "aaaxuuukkuxkjjjkmvwtqnttmlvwtqnvvwwmmllnnjla ";
#ifndef CONFIG_UTF_8
#ifndef CONFIG_UTF8
/* For UTF8 I/O */
static unsigned char frame_vt100_u[48] = {
177, 177, 177, 179, 180, 180, 180, 191,
@ -41,7 +41,7 @@ static unsigned char frame_vt100_u[48] = {
193, 194, 194, 192, 192, 218, 218, 197,
197, 217, 218, 177, 32, 32, 32, 32
};
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
static unsigned char frame_freebsd[48] = {
130, 138, 128, 153, 150, 150, 150, 140,
@ -81,12 +81,12 @@ static struct string m11_hack_frame_seqs[] = {
/* begin border: */ TERM_STRING("\033[11m"),
};
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
static struct string utf8_linux_frame_seqs[] = {
/* end border: */ TERM_STRING("\033[10m\033%G"),
/* begin border: */ TERM_STRING("\033%@\033[11m"),
};
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
static struct string vt100_frame_seqs[] = {
/* end border: */ TERM_STRING("\x0f"),
@ -109,12 +109,12 @@ struct screen_driver {
* uniquely identify the screen_driver. */
enum term_mode_type type;
#ifndef CONFIG_UTF_8
#ifndef CONFIG_UTF8
/* Charsets when doing UTF8 I/O. */
/* [0] is the common charset and [1] is the frame charset.
* Test wether to use UTF8 I/O using the use_utf8_io() macro. */
int charsets[2];
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* The frame translation table. May be NULL. */
unsigned char *frame;
@ -131,10 +131,10 @@ struct screen_driver {
/* These are directly derived from the terminal options. */
unsigned int transparent:1;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
/* UTF-8 I/O */
unsigned int utf8:1;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* The terminal._template_ name. */
unsigned char name[1]; /* XXX: Keep last! */
@ -143,81 +143,81 @@ struct screen_driver {
static struct screen_driver dumb_screen_driver = {
NULL_LIST_HEAD,
/* type: */ TERM_DUMB,
#ifndef CONFIG_UTF_8
#ifndef CONFIG_UTF8
/* charsets: */ { -1, -1 }, /* No UTF8 I/O */
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* frame: */ frame_dumb,
/* frame_seqs: */ NULL,
/* underline: */ underline_seqs,
/* color_mode: */ COLOR_MODE_16,
/* transparent: */ 1,
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
/* utf-8: */ 0,
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
};
static struct screen_driver vt100_screen_driver = {
NULL_LIST_HEAD,
/* type: */ TERM_VT100,
#ifndef CONFIG_UTF_8
#ifndef CONFIG_UTF8
/* charsets: */ { -1, -1 }, /* No UTF8 I/O */
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* frame: */ frame_vt100,
/* frame_seqs: */ vt100_frame_seqs,
/* underline: */ underline_seqs,
/* color_mode: */ COLOR_MODE_16,
/* transparent: */ 1,
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
/* utf-8: */ 0,
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
};
static struct screen_driver linux_screen_driver = {
NULL_LIST_HEAD,
/* type: */ TERM_LINUX,
#ifndef CONFIG_UTF_8
#ifndef CONFIG_UTF8
/* charsets: */ { -1, -1 }, /* No UTF8 I/O */
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* frame: */ NULL, /* No restrict_852 */
/* frame_seqs: */ NULL, /* No m11_hack */
/* underline: */ underline_seqs,
/* color_mode: */ COLOR_MODE_16,
/* transparent: */ 1,
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
/* utf-8: */ 0,
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
};
static struct screen_driver koi8_screen_driver = {
NULL_LIST_HEAD,
/* type: */ TERM_KOI8,
#ifndef CONFIG_UTF_8
#ifndef CONFIG_UTF8
/* charsets: */ { -1, -1 }, /* No UTF8 I/O */
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* frame: */ frame_koi,
/* frame_seqs: */ NULL,
/* underline: */ underline_seqs,
/* color_mode: */ COLOR_MODE_16,
/* transparent: */ 1,
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
/* utf-8: */ 0,
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
};
static struct screen_driver freebsd_screen_driver = {
NULL_LIST_HEAD,
/* type: */ TERM_FREEBSD,
#ifndef CONFIG_UTF_8
#ifndef CONFIG_UTF8
/* charsets: */ { -1, -1 }, /* No UTF8 I/O */
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* frame: */ frame_freebsd,
/* frame_seqs: */ NULL, /* No m11_hack */
/* underline: */ underline_seqs,
/* color_mode: */ COLOR_MODE_16,
/* transparent: */ 1,
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
/* utf-8: */ 0,
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
};
/* XXX: Keep in sync with enum term_mode_type. */
@ -229,22 +229,22 @@ static struct screen_driver *screen_drivers[] = {
/* TERM_FREEBSD: */ &freebsd_screen_driver,
};
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
#define use_utf8_io(driver) ((driver)->utf8)
#else
#define use_utf8_io(driver) ((driver)->charsets[0] != -1)
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
static INIT_LIST_HEAD(active_screen_drivers);
static void
update_screen_driver(struct screen_driver *driver, struct option *term_spec)
{
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
driver->utf8 = get_opt_bool_tree(term_spec, "utf_8_io");
#else
int utf8_io = get_opt_bool_tree(term_spec, "utf_8_io");
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
driver->color_mode = get_opt_int_tree(term_spec, "colors");
driver->transparent = get_opt_bool_tree(term_spec, "transparency");
@ -255,7 +255,7 @@ update_screen_driver(struct screen_driver *driver, struct option *term_spec)
driver->underline = NULL;
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (driver->type == TERM_LINUX) {
if (get_opt_bool_tree(term_spec, "restrict_852"))
driver->frame = frame_restrict;
@ -312,7 +312,7 @@ update_screen_driver(struct screen_driver *driver, struct option *term_spec)
driver->frame = frame_vt100;
}
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
}
static int
@ -351,9 +351,9 @@ add_screen_driver(enum term_mode_type type, struct terminal *term, int env_len)
term->spec->change_hook = screen_driver_change_hook;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
term->utf8 = use_utf8_io(driver);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
return driver;
}
@ -373,9 +373,9 @@ get_screen_driver(struct terminal *term)
/* Some simple probably useless MRU ;) */
move_to_top_of_list(active_screen_drivers, driver);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
term->utf8 = use_utf8_io(driver);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
return driver;
}
@ -422,27 +422,103 @@ struct screen_state {
unsigned char bold;
unsigned char attr;
/* Following should match struct screen_char color field. */
#if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS)
unsigned char color[2];
#else
unsigned char color[1];
#endif
unsigned char color[SCREEN_COLOR_SIZE];
};
#if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS)
#define compare_color(a, b) ((a)[0] == (b)[0] && (a)[1] == (b)[1])
#define copy_color(a, b) do { (a)[0] = (b)[0]; (a)[1] = (b)[1]; } while (0)
#if defined(CONFIG_TRUE_COLOR)
#define INIT_SCREEN_STATE { 0xFF, 0xFF, 0xFF, 0, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} }
#elif defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS)
#define INIT_SCREEN_STATE { 0xFF, 0xFF, 0xFF, 0, { 0xFF, 0xFF } }
#else
#define compare_color(a, b) ((a)[0] == (b)[0])
#define copy_color(a, b) do { (a)[0] = (b)[0]; } while (0)
#define INIT_SCREEN_STATE { 0xFF, 0xFF, 0xFF, 0, { 0xFF } }
#endif
#define compare_bg_color(a, b) (TERM_COLOR_BACKGROUND(a) == TERM_COLOR_BACKGROUND(b))
#define compare_fg_color(a, b) (TERM_COLOR_FOREGROUND(a) == TERM_COLOR_FOREGROUND(b))
#ifdef CONFIG_TRUE_COLOR
static inline int
compare_color_true(unsigned char *a, unsigned char *b)
{
return !memcmp(a, b, 6);
}
#ifdef CONFIG_UTF_8
static inline int
compare_bg_color_true(unsigned char *a, unsigned char *b)
{
return (a[3] == b[3] && a[4] == b[4] && a[5] == b[5]);
}
static inline int
compare_fg_color_true(unsigned char *a, unsigned char *b)
{
return (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);
}
static inline void
copy_color_true(unsigned char *a, unsigned char *b)
{
memcpy(a, b, 6);
}
static inline int
background_is_black(unsigned char *a)
{
static unsigned char b[6] = {0, 0, 0, 0, 0, 0};
return compare_bg_color_true(a, b);
}
#endif
#if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS)
static inline int
compare_color_256(unsigned char *a, unsigned char *b)
{
return (a[0] == b[0] && a[1] == b[1]);
}
static inline int
compare_bg_color_256(unsigned char *a, unsigned char *b)
{
return (a[1] == b[1]);
}
static inline int
compare_fg_color_256(unsigned char *a, unsigned char *b)
{
return (a[0] == b[0]);
}
static inline void
copy_color_256(unsigned char *a, unsigned char *b)
{
a[0] = b[0];
a[1] = b[1];
}
#endif
static inline int
compare_color_16(unsigned char *a, unsigned char *b)
{
return (a[0] == b[0]);
}
static inline int
compare_bg_color_16(unsigned char *a, unsigned char *b)
{
return (TERM_COLOR_BACKGROUND_16(a) == TERM_COLOR_BACKGROUND_16(b));
}
static inline int
compare_fg_color_16(unsigned char *a, unsigned char *b)
{
return (TERM_COLOR_FOREGROUND_16(a) == TERM_COLOR_FOREGROUND_16(b));
}
static inline void
copy_color_16(unsigned char *a, unsigned char *b)
{
a[0] = b[0];
}
#ifdef CONFIG_UTF8
static inline void
add_char_data(struct string *screen, struct screen_driver *driver,
unicode_val_T data, unsigned char border)
@ -450,7 +526,7 @@ add_char_data(struct string *screen, struct screen_driver *driver,
static inline void
add_char_data(struct string *screen, struct screen_driver *driver,
unsigned char data, unsigned char border)
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
if (!isscreensafe(data)) {
add_char_to_string(screen, ' ');
@ -461,17 +537,17 @@ add_char_data(struct string *screen, struct screen_driver *driver,
data = driver->frame[data - 176];
if (use_utf8_io(driver)) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (border)
add_char_to_string(screen, (unsigned char)data);
else
if (data != UCS_NO_CHAR)
add_to_string(screen, encode_utf_8(data));
add_to_string(screen, encode_utf8(data));
#else
int charset = driver->charsets[!!border];
add_to_string(screen, cp2utf_8(charset, data));
#endif /* CONFIG_UTF_8 */
add_to_string(screen, cp2utf8(charset, data));
#endif /* CONFIG_UTF8 */
return;
}
@ -488,9 +564,9 @@ add_char16(struct string *screen, struct screen_driver *driver,
unsigned char bold = (ch->attr & SCREEN_ATTR_BOLD);
if (
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
(!use_utf8_io(driver) || ch->data != UCS_NO_CHAR) &&
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
border != state->border && driver->frame_seqs
) {
state->border = border;
@ -498,9 +574,9 @@ add_char16(struct string *screen, struct screen_driver *driver,
}
if (
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
(!use_utf8_io(driver) || ch->data != UCS_NO_CHAR) &&
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
underline != state->underline && driver->underline
) {
state->underline = underline;
@ -508,9 +584,9 @@ add_char16(struct string *screen, struct screen_driver *driver,
}
if (
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
(!use_utf8_io(driver) || ch->data != UCS_NO_CHAR) &&
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
bold != state->bold
) {
state->bold = bold;
@ -523,20 +599,20 @@ add_char16(struct string *screen, struct screen_driver *driver,
}
if (
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
(!use_utf8_io(driver) || ch->data != UCS_NO_CHAR) &&
#endif /* CONFIG_UTF_8 */
!compare_color(ch->color, state->color)
#endif /* CONFIG_UTF8 */
!compare_color_16(ch->color, state->color)
) {
copy_color(state->color, ch->color);
copy_color_16(state->color, ch->color);
add_bytes_to_string(screen, "\033[0", 3);
if (driver->color_mode == COLOR_MODE_16) {
unsigned char code[6] = ";30;40";
unsigned char bgcolor = TERM_COLOR_BACKGROUND(ch->color);
unsigned char bgcolor = TERM_COLOR_BACKGROUND_16(ch->color);
code[2] += TERM_COLOR_FOREGROUND(ch->color);
code[2] += TERM_COLOR_FOREGROUND_16(ch->color);
if (!driver->transparent || bgcolor != 0) {
code[5] += bgcolor;
@ -630,9 +706,9 @@ add_char256(struct string *screen, struct screen_driver *driver,
unsigned char attr_delta = (ch->attr ^ state->attr);
if (
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
(!use_utf8_io(driver) || ch->data != UCS_NO_CHAR) &&
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
attr_delta
) {
if ((attr_delta & SCREEN_ATTR_FRAME) && driver->frame_seqs) {
@ -658,12 +734,12 @@ add_char256(struct string *screen, struct screen_driver *driver,
}
if (
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
(!use_utf8_io(driver) || ch->data != UCS_NO_CHAR) &&
#endif /* CONFIG_UTF_8 */
!compare_color(ch->color, state->color)
#endif /* CONFIG_UTF8 */
!compare_color_256(ch->color, state->color)
) {
copy_color(state->color, ch->color);
copy_color_256(state->color, ch->color);
add_foreground_color(screen, color256_seqs, ch);
if (!driver->transparent || ch->color[1] != 0) {
@ -683,7 +759,122 @@ add_char256(struct string *screen, struct screen_driver *driver,
}
#endif
#define add_chars(image_, term_, driver_, state_, ADD_CHAR) \
#ifdef CONFIG_TRUE_COLOR
static struct string color_true_seqs[] = {
/* foreground: */ TERM_STRING("\033[0;38;2"),
/* background: */ TERM_STRING("\033[48;2"),
};
#define add_true_background_color(str, seq, chr) add_char_true_color(str, &(seq)[1], &(chr)->color[3])
#define add_true_foreground_color(str, seq, chr) add_char_true_color(str, &(seq)[0], &(chr)->color[0])
static inline void
add_char_true_color(struct string *screen, struct string *seq, unsigned char *colors)
{
unsigned char color_buf[3];
int i;
check_string_magic(seq);
add_string_to_string(screen, seq);
for (i = 0; i < 3; i++) {
unsigned char *color_pos = color_buf;
int color_len = 1;
unsigned char color = colors[i];
add_char_to_string(screen, ';');
if (color < 10) {
color_pos += 2;
} else {
int color2;
++color_len;
if (color < 100) {
++color_pos;
} else {
++color_len;
if (color < 200) {
color_buf[0] = '1';
color -= 100;
} else {
color_buf[0] = '2';
color -= 200;
}
}
color2 = (color % 10);
color /= 10;
color_buf[1] = '0' + color;
color = color2;
}
color_buf[2] = '0' + color;
add_bytes_to_string(screen, color_pos, color_len);
}
add_char_to_string(screen, 'm');
}
/* Time critical section. */
static inline void
add_char_true(struct string *screen, struct screen_driver *driver,
struct screen_char *ch, struct screen_state *state)
{
unsigned char attr_delta = (ch->attr ^ state->attr);
if (
#ifdef CONFIG_UTF8
(!use_utf8_io(driver) || ch->data != UCS_NO_CHAR) &&
#endif /* CONFIG_UTF8 */
attr_delta
) {
if ((attr_delta & SCREEN_ATTR_FRAME) && driver->frame_seqs) {
state->border = !!(ch->attr & SCREEN_ATTR_FRAME);
add_term_string(screen, driver->frame_seqs[state->border]);
}
if ((attr_delta & SCREEN_ATTR_UNDERLINE) && driver->underline) {
state->underline = !!(ch->attr & SCREEN_ATTR_UNDERLINE);
add_term_string(screen, driver->underline[state->underline]);
}
if (attr_delta & SCREEN_ATTR_BOLD) {
if (ch->attr & SCREEN_ATTR_BOLD) {
add_bytes_to_string(screen, "\033[1m", 4);
} else {
/* Force repainting of the other attributes. */
state->color[0] = ch->color[0] + 1;
}
}
state->attr = ch->attr;
}
if (
#ifdef CONFIG_UTF8
(!use_utf8_io(driver) || ch->data != UCS_NO_CHAR) &&
#endif /* CONFIG_UTF8 */
!compare_color_true(ch->color, state->color)
) {
copy_color_true(state->color, ch->color);
add_true_foreground_color(screen, color_true_seqs, ch);
if (!driver->transparent || !background_is_black(ch->color)) {
add_true_background_color(screen, color_true_seqs, ch);
}
if (ch->attr & SCREEN_ATTR_BOLD)
add_bytes_to_string(screen, "\033[1m", 4);
if (ch->attr & SCREEN_ATTR_UNDERLINE && driver->underline) {
state->underline = !!(ch->attr & SCREEN_ATTR_UNDERLINE);
add_term_string(screen, driver->underline[state->underline]);
}
}
add_char_data(screen, driver, ch->data, ch->attr & SCREEN_ATTR_FRAME);
}
#endif
#define add_chars(image_, term_, driver_, state_, ADD_CHAR, compare_bg_color, compare_fg_color) \
{ \
struct terminal_screen *screen = (term_)->screen; \
int y = screen->dirty_from; \
@ -763,16 +954,21 @@ redraw_screen(struct terminal *term)
switch (driver->color_mode) {
case COLOR_MODE_MONO:
case COLOR_MODE_16:
add_chars(&image, term, driver, &state, add_char16);
add_chars(&image, term, driver, &state, add_char16, compare_bg_color_16, compare_fg_color_16);
break;
#ifdef CONFIG_88_COLORS
case COLOR_MODE_88:
add_chars(&image, term, driver, &state, add_char256);
add_chars(&image, term, driver, &state, add_char256, compare_bg_color_256, compare_fg_color_256);
break;
#endif
#ifdef CONFIG_256_COLORS
case COLOR_MODE_256:
add_chars(&image, term, driver, &state, add_char256);
add_chars(&image, term, driver, &state, add_char256, compare_bg_color_256, compare_fg_color_256);
break;
#endif
#ifdef CONFIG_TRUE_COLOR
case COLOR_MODE_TRUE_COLOR:
add_chars(&image, term, driver, &state, add_char_true, compare_bg_color_true, compare_fg_color_true);
break;
#endif
case COLOR_MODES:

View File

@ -51,7 +51,8 @@ init_tab(struct terminal *term, void *data, window_handler_T handler)
* above it if it were inactive, or below if it were active. */
assert(term->main_menu == NULL);
pos = (struct window *) term->windows.prev;
found_pos:
found_pos:
add_at_pos(pos, win);
assert_window_stacking(term);
@ -129,27 +130,19 @@ get_tab_number_by_xpos(struct terminal *term, int xpos)
return -1;
}
/* if @tabs > 0, then it is taken as the result of a recent
/* if @tabs_count > 0, then it is taken as the result of a recent
* call to number_of_tabs() so it just uses this value. */
void
switch_to_tab(struct terminal *term, int tab, int tabs)
switch_to_tab(struct terminal *term, int tab, int tabs_count)
{
if (tabs < 0) tabs = number_of_tabs(term);
if (tabs_count < 0) tabs_count = number_of_tabs(term);
if (tabs > 1) {
if (tab >= tabs) {
if (get_opt_bool("ui.tabs.wraparound"))
tab = tab % tabs;
else
tab = tabs - 1;
}
if (tab < 0) {
if (get_opt_bool("ui.tabs.wraparound"))
tab = tabs + tab % tabs;
else
tab = 0;
}
if (tabs_count > 1) {
if (get_opt_bool("ui.tabs.wraparound")) {
tab %= tabs_count;
if (tab < 0) tab += tabs_count;
} else
int_bounds(&tab, 0, tabs_count - 1);
} else tab = 0;
if (tab != term->current_tab) {
@ -163,16 +156,16 @@ void
switch_current_tab(struct session *ses, int direction)
{
struct terminal *term = ses->tab->term;
int num_tabs = number_of_tabs(term);
int tabs_count = number_of_tabs(term);
int count;
if (num_tabs < 2)
if (tabs_count < 2)
return;
count = eat_kbd_repeat_count(ses);
if (count) direction *= count;
switch_to_tab(term, term->current_tab + direction, num_tabs);
switch_to_tab(term, term->current_tab + direction, tabs_count);
}
static void
@ -182,9 +175,9 @@ really_close_tab(struct session *ses)
struct window *current_tab = get_current_tab(term);
if (ses->tab == current_tab) {
int num_tabs = number_of_tabs(term);
int tabs_count = number_of_tabs(term);
switch_to_tab(term, term->current_tab - 1, num_tabs - 1);
switch_to_tab(term, term->current_tab - 1, tabs_count - 1);
}
delete_window(ses->tab);
@ -194,9 +187,9 @@ void
close_tab(struct terminal *term, struct session *ses)
{
/* [gettext_accelerator_context(close_tab)] */
int num_tabs = number_of_tabs(term);
int tabs_count = number_of_tabs(term);
if (num_tabs < 2) {
if (tabs_count < 2) {
query_exit(ses);
return;
}
@ -218,16 +211,22 @@ static void
really_close_tabs(struct session *ses)
{
struct terminal *term = ses->tab->term;
struct window *current = get_current_tab(term);
struct window *current_tab = get_current_tab(term);
struct window *tab;
foreach_tab (tab, term->windows) {
if (tab == current) continue;
if (tab == current_tab) continue;
/* Update the current tab counter so assertions in the
* delete_window() call-chain will hold, namely the one in
* get_tab_by_number(). */
if (term->current_tab > 0)
term->current_tab--;
tab = tab->prev;
delete_window(tab->next);
}
term->current_tab = 0;
redraw_terminal(term);
}

View File

@ -38,9 +38,29 @@
INIT_LIST_HEAD(terminals);
static void check_if_no_terminal(void);
#if 0
static int
was_utf8(int in, int out)
{
/* Taken from setedit.
* Set cursor in the up left corner. Write "\357\200\240" == U+F020.
* Read cursor position. For UTF-8 x will be 2.
* For normal mode it will be 4. */
static unsigned char *str = "\033[1;1H\357\200\240\033[6n";
unsigned char buf[20];
int x, y;
hard_write(out, str, strlen(str));
buf[0] = '\0';
read(in, buf, 6);
if (sscanf(buf,"\033[%d;%dR",&y,&x)==2) {
if (x > 2) return 0;
}
return 1;
}
#endif
void
redraw_terminal(struct terminal *term)
@ -72,6 +92,7 @@ cls_redraw_all_terminals(void)
struct terminal *
init_term(int fdin, int fdout)
{
unsigned char name[MAX_TERM_LEN + 9] = "terminal.";
struct terminal *term = mem_calloc(1, sizeof(*term));
if (!term) {
@ -91,9 +112,18 @@ init_term(int fdin, int fdout)
term->fdout = fdout;
term->master = (term->fdout == get_output_handle());
term->blocked = -1;
term->spec = get_opt_rec(config_options, "terminal._template_");
get_terminal_name(name + 9);
term->spec = get_opt_rec(config_options, name);
object_lock(term->spec);
#if 0
/* The hack to restore console in the right mode */
if (get_opt_int_tree(term->spec, "type") == TERM_LINUX) {
term->linux_was_utf8 = was_utf8(get_input_handle(), term->fdout);
}
#endif
add_to_list(terminals, term);
set_handlers(fdin, (select_handler_T) in_term, NULL,
@ -141,6 +171,17 @@ destroy_terminal(struct terminal *term)
del_from_list(term);
close(term->fdin);
#if 0
/* This code doesn't work with slave terminals. */
if (get_opt_int_tree(term->spec, "type") == TERM_LINUX) {
if (term->linux_was_utf8) {
hard_write(term->fdout, "\033%G", 3);
} else {
hard_write(term->fdout, "\033%@", 3);
}
}
#endif
if (term->fdout != 1) {
if (term->fdout != term->fdin) close(term->fdout);
} else {

View File

@ -126,10 +126,13 @@ struct terminal {
* work and even maintaining these structures ;-). */
unsigned int master:1;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
/* Indicates whether UTF-8 I/O is used */
unsigned int utf8:1;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* Indicates whether Linux console was in UTF-8 mode on startup */
unsigned int linux_was_utf8:1;
/* The current tab number. */
int current_tab;

View File

@ -28,6 +28,13 @@ col_is_in_box(struct box *box, int x)
return (x >= box->x && x < box->x + box->width);
}
/* Mainly intended for use with double-width characters. */
static inline int
colspan_is_in_box(struct box *box, int x, int span)
{
return (x >= box->x && x + span <= box->x + box->width);
}
static inline void
set_box(struct box *box, int x, int y, int width, int height)

View File

@ -69,9 +69,8 @@ enum secsave_errno secsave_errno = SS_ERR_NONE;
/* Open a file for writing in a secure way. It returns a pointer to a structure
* secure_save_info on success, or NULL on failure. */
static struct secure_save_info *
secure_open_umask(unsigned char *file_name, mode_t mask)
secure_open_umask(unsigned char *file_name)
{
mode_t saved_mask;
struct stat st;
struct secure_save_info *ssi;
@ -144,8 +143,6 @@ secure_open_umask(unsigned char *file_name, mode_t mask)
}
}
saved_mask = umask(mask);
if (ssi->secure_save) {
/* We use a random name for temporary file, mkstemp() opens
* the file and return a file descriptor named fd, which is
@ -187,8 +184,6 @@ secure_open_umask(unsigned char *file_name, mode_t mask)
}
}
umask(saved_mask);
return ssi;
free_file_name:
@ -206,12 +201,20 @@ end:
struct secure_save_info *
secure_open(unsigned char *file_name)
{
struct secure_save_info *ssi;
mode_t saved_mask;
#ifdef CONFIG_OS_WIN32
/* There is neither S_IRWXG nor S_IRWXO under crossmingw32-gcc */
return secure_open_umask(file_name, 0177);
const mode_t mask = 0177;
#else
return secure_open_umask(file_name, S_IXUSR | S_IRWXG | S_IRWXO);
const mode_t mask = S_IXUSR | S_IRWXG | S_IRWXO;
#endif
saved_mask = umask(mask);
ssi = secure_open_umask(file_name);
umask(saved_mask);
return ssi;
}
/* Close a file opened with secure_open, and return 0 on success, errno

View File

@ -55,6 +55,9 @@ static int dump_to_file_16(struct document *document, int fd);
#if defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS)
static int dump_to_file_256(struct document *document, int fd);
#endif
#ifdef CONFIG_TRUE_COLOR
static int dump_to_file_true_color(struct document *document, int fd);
#endif
/* This dumps the given @cached's source onto @fd nothing more. It returns 0 if it
* all went fine and 1 if something isn't quite right and we should terminate
@ -141,6 +144,11 @@ dump_formatted(int fd, struct download *download, struct cache_entry *cached)
case COLOR_MODE_256:
dump_to_file_256(formatted.document, fd);
break;
#endif
#ifdef CONFIG_TRUE_COLOR
case COLOR_MODE_TRUE_COLOR:
dump_to_file_true_color(formatted.document, fd);
break;
#endif
default:
break;
@ -347,10 +355,10 @@ add_document_to_string(struct string *string, struct document *document)
assert(string && document);
if_assert_failed return NULL;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (is_cp_utf8(document->options.cp))
goto utf_8;
#endif /* CONFIG_UTF_8 */
goto utf8;
#endif /* CONFIG_UTF8 */
for (y = 0; y < document->height; y++) {
int white = 0;
@ -384,9 +392,9 @@ add_document_to_string(struct string *string, struct document *document)
add_char_to_string(string, '\n');
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
goto end;
utf_8:
utf8:
for (y = 0; y < document->height; y++) {
struct screen_char *pos = document->data[y].chars;
int white = 0;
@ -414,7 +422,7 @@ utf_8:
if (frame)
add_char_to_string(string, data);
else
add_to_string(string, encode_utf_8(data));
add_to_string(string, encode_utf8(data));
}
}
}
@ -422,7 +430,7 @@ utf_8:
add_char_to_string(string, '\n');
}
end:
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
return string;
}
@ -701,6 +709,137 @@ fail:
#endif /* defined(CONFIG_88_COLORS) || defined(CONFIG_256_COLORS) */
#ifdef CONFIG_TRUE_COLOR
static int
write_true_color(unsigned char *str, unsigned char *color, int fd, unsigned char *buf, int *bptr)
{
unsigned char bufor[24];
unsigned char *data = bufor;
snprintf(bufor, 24, "\033[%s;2;%d;%d;%dm", str, color[0], color[1], color[2]);
while(*data) {
if (write_char(*data++, fd, buf, bptr)) return -1;
}
return 0;
}
static int
dump_to_file_true_color(struct document *document, int fd)
{
static unsigned char color[6] = {255, 255, 255, 0, 0, 0};
int y;
int bptr = 0;
unsigned char *buf = mem_alloc(D_BUF);
unsigned char *foreground = &color[0];
unsigned char *background = &color[3];
int width = get_opt_int("document.dump.width");
if (!buf) return -1;
for (y = 0; y < document->height; y++) {
int white = 0;
int x;
write_true_color("38", foreground, fd, buf, &bptr);
write_true_color("48", background, fd, buf, &bptr);
for (x = 0; x < document->data[y].length; x++) {
unsigned char c;
unsigned char attr = document->data[y].chars[x].attr;
unsigned char *new_foreground = &document->data[y].chars[x].color[0];
unsigned char *new_background = &document->data[y].chars[x].color[3];
if (memcmp(foreground, new_foreground, 3)) {
foreground = new_foreground;
if (write_true_color("38", foreground, fd, buf, &bptr))
goto fail;
}
if (memcmp(background, new_background, 3)) {
background = new_background;
if (write_true_color("48", background, fd, buf, &bptr))
goto fail;
}
c = document->data[y].chars[x].data;
if ((attr & SCREEN_ATTR_FRAME)
&& c >= 176 && c < 224)
c = frame_dumb[c - 176];
if (c <= ' ') {
/* Count spaces. */
white++;
continue;
}
/* Print spaces if any. */
while (white) {
if (write_char(' ', fd, buf, &bptr))
goto fail;
white--;
}
/* Print normal char. */
if (write_char(c, fd, buf, &bptr))
goto fail;
}
for (;x < width; x++) {
if (write_char(' ', fd, buf, &bptr))
goto fail;
}
/* Print end of line. */
if (write_char('\n', fd, buf, &bptr))
goto fail;
}
if (hard_write(fd, buf, bptr) != bptr) {
fail:
mem_free(buf);
return -1;
}
if (document->nlinks && get_opt_bool("document.dump.references")) {
int x;
unsigned char *header = "\nReferences\n\n Visible links\n";
int headlen = strlen(header);
if (hard_write(fd, header, headlen) != headlen)
goto fail;
for (x = 0; x < document->nlinks; x++) {
struct link *link = &document->links[x];
unsigned char *where = link->where;
if (!where) continue;
if (document->options.links_numbering) {
if (link->title && *link->title)
snprintf(buf, D_BUF, "%4d. %s\n\t%s\n",
x + 1, link->title, where);
else
snprintf(buf, D_BUF, "%4d. %s\n",
x + 1, where);
} else {
if (link->title && *link->title)
snprintf(buf, D_BUF, " . %s\n\t%s\n",
link->title, where);
else
snprintf(buf, D_BUF, " . %s\n", where);
}
bptr = strlen(buf);
if (hard_write(fd, buf, bptr) != bptr)
goto fail;
}
}
mem_free(buf);
return 0;
}
#endif /* CONFIG_TRUE_COLOR */
int
dump_to_file(struct document *document, int fd)
{
@ -710,10 +849,10 @@ dump_to_file(struct document *document, int fd)
if (!buf) return -1;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (is_cp_utf8(document->options.cp))
goto utf_8;
#endif /* CONFIG_UTF_8 */
goto utf8;
#endif /* CONFIG_UTF8 */
for (y = 0; y < document->height; y++) {
int white = 0;
@ -751,9 +890,9 @@ dump_to_file(struct document *document, int fd)
if (write_char('\n', fd, buf, &bptr))
goto fail;
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
goto ref;
utf_8:
utf8:
for (y = 0; y < document->height; y++) {
int white = 0;
int x;
@ -768,7 +907,7 @@ utf_8:
&& c >= 176 && c < 224)
c = frame_dumb[c - 176];
else {
unsigned char *utf8_buf = encode_utf_8(c);
unsigned char *utf8_buf = encode_utf8(c);
while (*utf8_buf) {
if (write_char(*utf8_buf++,
@ -799,16 +938,15 @@ utf_8:
if (write_char('\n', fd, buf, &bptr))
goto fail;
}
#endif /* CONFIG_UTF_8 */
ref:
#endif /* CONFIG_UTF8 */
if (hard_write(fd, buf, bptr) != bptr) {
fail:
mem_free(buf);
return -1;
}
#ifdef CONFIG_UTF_8
ref:
#endif /* CONFIG_UTF_8 */
if (document->nlinks && get_opt_bool("document.dump.references")) {
int x;
unsigned char *header = "\nReferences\n\n Visible links\n";

View File

@ -163,22 +163,15 @@ init_form_state(struct form_control *fc, struct form_state *fs)
case FC_TEXTAREA:
fs->value = stracpy(fc->default_value);
fs->state = strlen(fc->default_value);
#ifdef CONFIG_UTF_8
if (fc->type == FC_TEXT)
fs->state_cell = utf8_ptr2cells(fs->value, NULL);
if (fc->type == FC_PASSWORD)
fs->state_cell = utf8_ptr2chars(fs->value, NULL);
#ifdef CONFIG_UTF8
if (fc->type == FC_TEXTAREA)
fs->state_cell = 0;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
fs->vpos = 0;
break;
case FC_FILE:
fs->value = stracpy("");
fs->state = 0;
#ifdef CONFIG_UTF_8
fs->state_cell = 0;
#endif /* CONFIG_UTF_8 */
fs->vpos = 0;
break;
case FC_SELECT:
@ -341,9 +334,10 @@ draw_form_entry(struct terminal *term, struct document_view *doc_view,
dy = box->y - vs->y;
switch (fc->type) {
unsigned char *s;
#ifdef CONFIG_UTF_8
unsigned char *text, *end;
#endif /* CONFIG_UTF_8 */
#ifdef CONFIG_UTF8
unsigned char *text, *end, *last_in_view;
int retried;
#endif /* CONFIG_UTF8 */
int len;
int i, x, y;
@ -357,9 +351,9 @@ draw_form_entry(struct terminal *term, struct document_view *doc_view,
break;
x = link->points[0].x + dx;
#ifdef CONFIG_UTF_8
if (term->utf8) goto utf_8;
#endif /* CONFIG_UTF_8 */
#ifdef CONFIG_UTF8
if (term->utf8) goto utf8;
#endif /* CONFIG_UTF8 */
int_bounds(&fs->vpos, fs->state - fc->size + 1, fs->state);
len = strlen(fs->value) - fs->vpos;
@ -377,43 +371,123 @@ draw_form_entry(struct terminal *term, struct document_view *doc_view,
draw_char_data(term, x, y, data);
}
break;
#ifdef CONFIG_UTF_8
utf_8:
end = NULL; /* Shut up the compiler. */
int_bounds(&fs->vpos, fs->state_cell - fc->size + 1, fs->state_cell);
if (fc->type == FC_PASSWORD)
len = utf8_ptr2chars(fs->value + fs->vpos, NULL);
else
len = utf8_ptr2cells(fs->value + fs->vpos, NULL);
#ifdef CONFIG_UTF8
utf8:
retried = 0;
retry_after_scroll:
text = fs->value;
end = strchr(text, '\0');
if (!text) text = "";
len = strlen(text);
int_bounds(&fs->state, 0, len);
int_bounds(&fs->vpos, 0, fs->state);
end = text + len;
text += fs->vpos;
last_in_view = NULL;
for (i = 0; i < fc->size; i++, x++) {
for (i = 0; i < fc->size; ) {
unicode_val_T data;
int cells, cell;
unsigned char *maybe_in_view = text;
if (!col_is_in_box(box, x)) continue;
if (fs->value && i >= -fs->vpos && i < len) {
if (fc->type != FC_PASSWORD)
data = utf_8_to_unicode(&text, end);
else
data = '*';
} else
data = utf8_to_unicode(&text, end);
if (data == UCS_NO_CHAR) /* end of string */
data = '_';
else if (fc->type == FC_PASSWORD)
data = '*';
if (unicode_to_cell(data) == 2) {
if (i + 1 < fc->size) {
draw_char_data(term, x++, y, data);
data = UCS_NO_CHAR;
i++;
} else
data = ' ';
cells = unicode_to_cell(data);
if (i + cells <= fc->size) {
last_in_view = maybe_in_view;
if (colspan_is_in_box(box, x + i, cells)) {
/* The character fits completely.
* Draw the character, and mark any
* further cells with UCS_NO_CHAR. */
draw_char_data(term, x + i, y, data);
for (cell = 1; cell < cells; cell++)
draw_char_data(term, x + i + cell,
y, UCS_NO_CHAR);
goto drew_char;
}
}
/* The character does not fit completely.
* Write spaces to the cells that do fit. */
for (cell = 0; cell < cells; cell++) {
if (col_is_in_box(box, x + i + cell)
&& i + cell < fc->size)
draw_char_data(term,
x + i + cell,
y, ' ');
}
drew_char:
i += cells;
}
/* The int_bounds calls above ensured that the
* insertion point cannot be at the left side
* of the scrolled-visible part of the text.
* However it can still be at the right side.
* Check whether we need to change fs->vpos.
*
* This implementation attempts to follow
* these rules:
* - If the insertion point is at the end of
* the string, leave at least one empty cell
* so that there is a place for the cursor.
* - If a character follows the insertion
* point, make that character fully visible;
* note the character may be double-width.
* - If fc->size < 2, it is not possible to
* make a double-width character fully
* visible. In this case, it is OK if the
* output is ugly, but ELinks must not fall
* into an infinite loop or crash.
* - The length of the string should not affect
* how long this function takes. The width
* of the widget naturally will.
* - Optimize the case where fields are drawn
* several times without being modified.
*
* It follows that:
* - If the "for i" loop above hit UCS_NO_CHAR,
* then there is no need to scroll.
* - When the string ends with a double-width
* character that fits in only partially,
* then text==end, but the field may have
* to be scrolled. */
if (fs->value && last_in_view
&& last_in_view < fs->value + fs->state) {
unsigned char *ptr = fs->value + fs->state;
int cells = fc->size;
enum utf8_step how = (fc->type == FC_PASSWORD)
? utf8_step_characters
: utf8_step_cells_fewer;
/* The insertion point is at the right
* side of the scrolled-visible part
* of the text. Decide a new fs->vpos
* by counting cells backwards from
* @ptr. But first advance @ptr past
* the character that follows the
* insertion point, so that it will be
* fully displayed. If there is no
* such character, reserve one cell
* for the cursor anyway. */
if (utf8_to_unicode(&ptr, end) == UCS_NO_CHAR)
--cells;
ptr = utf8_step_backward(ptr, fs->value,
cells, how, NULL);
if (fs->vpos != ptr - fs->value) {
fs->vpos = ptr - fs->value;
retried = 1;
goto retry_after_scroll;
}
draw_char_data(term, x, y, data);
}
break;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
case FC_TEXTAREA:
draw_textarea(term, fs, doc_view, link);
break;
@ -432,9 +506,9 @@ utf_8:
else
/* XXX: when can this happen? --pasky */
s = "";
#ifdef CONFIG_UTF_8
if (term->utf8) goto utf_8_select;
#endif /* CONFIG_UTF_8 */
#ifdef CONFIG_UTF8
if (term->utf8) goto utf8_select;
#endif /* CONFIG_UTF8 */
len = s ? strlen(s) : 0;
for (i = 0; i < link->npoints; i++) {
x = link->points[i].x + dx;
@ -443,8 +517,8 @@ utf_8:
draw_char_data(term, x, y, i < len ? s[i] : '_');
}
break;
#ifdef CONFIG_UTF_8
utf_8_select:
#ifdef CONFIG_UTF8
utf8_select:
text = s;
end = strchr(s, '\0');
len = utf8_ptr2cells(text, end);
@ -456,7 +530,7 @@ utf_8_select:
if (i < len) {
int cell;
data = utf_8_to_unicode(&s, end);
data = utf8_to_unicode(&s, end);
cell = unicode_to_cell(data);
if (i + 1 < len && cell == 2) {
draw_char_data(term, x++, y, data);
@ -472,7 +546,7 @@ utf_8_select:
}
}
break;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
case FC_SUBMIT:
case FC_IMAGE:
case FC_RESET:
@ -1282,9 +1356,9 @@ field_op(struct session *ses, struct document_view *doc_view,
unsigned char *text;
int length;
enum frame_event_status status = FRAME_EVENT_REFRESH;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
int utf8 = ses->tab->term->utf8;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
assert(ses && doc_view && link && ev);
if_assert_failed return FRAME_EVENT_OK;
@ -1304,32 +1378,22 @@ field_op(struct session *ses, struct document_view *doc_view,
switch (action_id) {
case ACT_EDIT_LEFT:
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (fc->type == FC_TEXTAREA) {
status = textarea_op_left(fs, fc, utf8);
break;
}
if (utf8) {
int old_state = fs->state;
unsigned char *new_value;
int cells;
new_value = utf8_prevchar(fs->value + fs->state, 1, fs->value);
fs->state = new_value - fs->value;
if (old_state != fs->state) {
if (fc->type == FC_PASSWORD)
cells = 1;
else
cells = utf8_char2cells(new_value, NULL);
fs->state_cell = int_max(fs->state_cell - cells, 0);
}
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
fs->state = int_max(fs->state - 1, 0);
break;
case ACT_EDIT_RIGHT:
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (fc->type == FC_TEXTAREA) {
status = textarea_op_right(fs, fc, utf8);
break;
@ -1337,28 +1401,19 @@ field_op(struct session *ses, struct document_view *doc_view,
if (utf8) {
unsigned char *text = fs->value + fs->state;
unsigned char *end = strchr(text, '\0');
int old_state = fs->state;
unicode_val_T data = utf_8_to_unicode(&text, end);
utf8_to_unicode(&text, end);
fs->state = (int)(text - fs->value);
if (old_state != fs->state) {
if (fc->type == FC_PASSWORD)
fs->state_cell = int_min(fs->state_cell + 1,
utf8_ptr2cells(fs->value, NULL));
else
fs->state_cell += unicode_to_cell(data);
}
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
fs->state = int_min(fs->state + 1, strlen(fs->value));
break;
case ACT_EDIT_HOME:
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (fc->type == FC_TEXTAREA) {
status = textarea_op_home(fs, fc, utf8);
} else {
fs->state = 0;
fs->state_cell = 0;
}
#else
if (fc->type == FC_TEXTAREA) {
@ -1367,79 +1422,60 @@ field_op(struct session *ses, struct document_view *doc_view,
fs->state = 0;
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
break;
case ACT_EDIT_UP:
if (fc->type != FC_TEXTAREA)
status = FRAME_EVENT_IGNORED;
else
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
status = textarea_op_up(fs, fc, utf8);
#else
status = textarea_op_up(fs, fc);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
break;
case ACT_EDIT_DOWN:
if (fc->type != FC_TEXTAREA)
status = FRAME_EVENT_IGNORED;
else
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
status = textarea_op_down(fs, fc, utf8);
#else
status = textarea_op_down(fs, fc);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
break;
case ACT_EDIT_END:
if (fc->type == FC_TEXTAREA) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
status = textarea_op_end(fs, fc, utf8);
#else
status = textarea_op_end(fs, fc);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
} else {
fs->state = strlen(fs->value);
#ifdef CONFIG_UTF_8
if (utf8 && fc->type != FC_PASSWORD)
fs->state_cell = utf8_ptr2cells(fs->value,
fs->value + fs->state);
else if(utf8)
fs->state_cell = utf8_ptr2chars(fs->value,
fs->value + fs->state);
#endif /* CONFIG_UTF_8 */
}
break;
case ACT_EDIT_BEGINNING_OF_BUFFER:
if (fc->type == FC_TEXTAREA) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
status = textarea_op_bob(fs, fc, utf8);
fs->state_cell = 0;
#else
status = textarea_op_bob(fs, fc);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
} else {
fs->state = 0;
}
#ifdef CONFIG_UTF_8
fs->state_cell = 0;
#endif /* CONFIG_UTF_8 */
break;
case ACT_EDIT_END_OF_BUFFER:
if (fc->type == FC_TEXTAREA) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
status = textarea_op_eob(fs, fc, utf8);
#else
status = textarea_op_eob(fs, fc);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
} else {
fs->state = strlen(fs->value);
#ifdef CONFIG_UTF_8
if (utf8 && fc->type != FC_PASSWORD)
fs->state_cell = utf8_ptr2cells(fs->value,
fs->value + fs->state);
else if(utf8)
fs->state_cell = utf8_ptr2chars(fs->value,
fs->value + fs->state);
#endif /* CONFIG_UTF_8 */
}
break;
case ACT_EDIT_OPEN_EXTERNAL:
@ -1457,9 +1493,10 @@ field_op(struct session *ses, struct document_view *doc_view,
if (!form_field_is_readonly(fc))
fs->value[0] = 0;
fs->state = 0;
#ifdef CONFIG_UTF_8
fs->state_cell = 0;
#endif /* CONFIG_UTF_8 */
#ifdef CONFIG_UTF8
if (fc->type == FC_TEXTAREA)
fs->state_cell = 0;
#endif /* CONFIG_UTF8 */
break;
case ACT_EDIT_PASTE_CLIPBOARD:
if (form_field_is_readonly(fc)) break;
@ -1475,27 +1512,21 @@ field_op(struct session *ses, struct document_view *doc_view,
fs->value = v;
memmove(v, text, length + 1);
fs->state = strlen(fs->value);
#ifdef CONFIG_UTF_8
if(utf8 && fc->type == FC_PASSWORD)
fs->state_cell = utf8_ptr2chars(fs->value,
fs->value + fs->state);
else if (utf8 && fc->type == FC_TEXTAREA)
#ifdef CONFIG_UTF8
if (utf8 && fc->type == FC_TEXTAREA)
fs->state_cell = 0;
else if (utf8)
fs->state_cell = utf8_ptr2cells(fs->value,
fs->value + fs->state);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
}
}
mem_free(text);
break;
case ACT_EDIT_ENTER:
if (fc->type == FC_TEXTAREA) {
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
status = textarea_op_enter(fs, fc, utf8);
#else
status = textarea_op_enter(fs, fc);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
break;
}
@ -1520,7 +1551,7 @@ field_op(struct session *ses, struct document_view *doc_view,
status = FRAME_EVENT_OK;
break;
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (utf8) {
int old_state = fs->state;
unsigned char *new_value;
@ -1531,15 +1562,11 @@ field_op(struct session *ses, struct document_view *doc_view,
if (old_state != fs->state) {
if (fc->type == FC_TEXTAREA)
fs->state_cell = 0;
else if (fc->type == FC_PASSWORD)
fs->state_cell = int_max(fs->state_cell - 1, 0);
else
fs->state_cell -= utf8_char2cells(new_value, NULL);
length = strlen(fs->value + old_state) + 1;
memmove(new_value, fs->value + old_state, length);
}
} else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
length = strlen(fs->value + fs->state) + 1;
text = fs->value + fs->state;
@ -1559,20 +1586,20 @@ field_op(struct session *ses, struct document_view *doc_view,
status = FRAME_EVENT_OK;
break;
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (utf8) {
unsigned char *end = fs->value + length;
unsigned char *text = fs->value + fs->state;
unsigned char *old = text;
utf_8_to_unicode(&text, end);
utf8_to_unicode(&text, end);
if (old != text) {
memmove(old, text,
(int)(end - text) + 1);
}
break;
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
text = fs->value + fs->state;
memmove(text, text + 1, length - fs->state);
@ -1602,18 +1629,12 @@ field_op(struct session *ses, struct document_view *doc_view,
memmove(text, fs->value + fs->state, length);
fs->state = (int) (text - fs->value);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (utf8) {
if(fc->type == FC_PASSWORD)
fs->state_cell = utf8_ptr2cells(fs->value,
fs->value + fs->state);
else if (fc->type == FC_TEXTAREA)
if (fc->type == FC_TEXTAREA)
fs->state_cell = 0;
else
fs->state_cell = utf8_ptr2cells(fs->value,
fs->value + fs->state);
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
break;
case ACT_EDIT_KILL_TO_EOL:
if (form_field_is_readonly(fc)) {
@ -1712,17 +1733,17 @@ field_op(struct session *ses, struct document_view *doc_view,
}
if (form_field_is_readonly(fc)
#ifndef CONFIG_UTF_8
#ifndef CONFIG_UTF8
|| strlen(fs->value) >= fc->maxlength
|| !insert_in_string(&fs->value, fs->state, "?", 1)
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
)
{
status = FRAME_EVENT_OK;
break;
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
{
/* The charset of the terminal; we assume
* fs->value is in this charset.
@ -1740,16 +1761,12 @@ field_op(struct session *ses, struct document_view *doc_view,
}
fs->state += length;
if (fc->type == FC_PASSWORD)
fs->state_cell += (is_cp_utf8(cp) ? 1 : length);
else if (fc->type == FC_TEXTAREA)
if (fc->type == FC_TEXTAREA)
fs->state_cell = 0;
else
fs->state_cell += (is_cp_utf8(cp) ? unicode_to_cell(get_kbd_key(ev)) : length);
}
#else
fs->value[fs->state++] = get_kbd_key(ev);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
break;
}

View File

@ -37,11 +37,28 @@ struct form_state {
int position;
enum form_type type;
/* For FC_TEXT, FC_PASSWORD, and FC_FILE, @value is the text
* string that the user can edit. The string is null-terminated;
* its length is not stored separately. The size of the buffer
* is not stored anywhere; extending the string always requires
* calling realloc(). The string is not normally allowed to grow
* past @form_control.maxlength bytes (not counting the null),
* but there may be ways to get longer strings. */
unsigned char *value;
/* For FC_TEXT, FC_PASSWORD, and FC_FILE, @state is the byte
* position of the insertion point in @value.
* For FC_CHECKBOX and FC_RADIO, @state is 1 or 0.
* For FC_SELECT, @state is the index of the selected item
* in @form_control.labels. */
int state;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
/* For FC_TEXT, FC_PASSWORD, and FC_FILE, @state_cell is not
* used. */
int state_cell;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* For FC_TEXT, FC_PASSWORD, and FC_FILE, @vpos is the index
* of the first displayed byte in @value. It should never be
* in the middle of a character. */
int vpos;
int vypos;

View File

@ -114,9 +114,9 @@ get_link_cursor_offset(struct document_view *doc_view, struct link *link)
{
struct form_control *fc;
struct form_state *fs;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
int utf8 = doc_view->document->options.utf8;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
switch (link->type) {
case LINK_CHECKBOX:
@ -128,21 +128,30 @@ get_link_cursor_offset(struct document_view *doc_view, struct link *link)
case LINK_FIELD:
fc = get_link_form_control(link);
fs = find_form_state(doc_view, fc);
#ifdef CONFIG_UTF_8
if (utf8) {
return fs ? fs->state_cell - fs->vpos : 0;
} else
#endif /* CONFIG_UTF_8 */
return fs ? fs->state - fs->vpos : 0;
if (!fs || !fs->value)
return 0;
#ifdef CONFIG_UTF8
else if (utf8) {
unsigned char *scroll = fs->value + fs->vpos;
unsigned char *point = fs->value + fs->state;
if (fs->type == FC_PASSWORD)
return utf8_ptr2chars(scroll, point);
else
return utf8_ptr2cells(scroll, point);
}
#endif /* CONFIG_UTF8 */
else
return fs->state - fs->vpos;
case LINK_AREA:
fc = get_link_form_control(link);
fs = find_form_state(doc_view, fc);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
return fs ? area_cursor(fc, fs, utf8) : 0;
#else
return fs ? area_cursor(fc, fs) : 0;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
case LINK_HYPERTEXT:
case LINK_MAP:
@ -293,6 +302,7 @@ draw_link(struct terminal *term, struct document_view *doc_view,
ch = get_char(term, x + xpos, y + ypos);
copy_struct(ch, &doc_view->document->data[y].chars[x]);
set_screen_dirty(term->screen, y + ypos, y + ypos);
}
}
}
@ -1178,26 +1188,38 @@ enum frame_event_status
try_document_key(struct session *ses, struct document_view *doc_view,
struct term_event *ev)
{
long key;
unicode_val_T key;
int passed = -1;
int i; /* GOD I HATE C! --FF */ /* YEAH, BRAINFUCK RULEZ! --pasky */
assert(ses && doc_view && doc_view->document && doc_view->vs && ev);
if_assert_failed return FRAME_EVENT_IGNORED;
if (!check_kbd_modifier(ev, KBD_MOD_ALT)) {
/* We accept those only in alt-combo. */
if (!check_kbd_modifier(ev, KBD_MOD_ALT)
|| !is_kbd_character(get_kbd_key(ev))) {
/* We accept only alt-character combos. */
return FRAME_EVENT_IGNORED;
}
/* The key is a character. Convert it to Unicode so that it
* can be compared with link.accesskey. */
#ifdef CONFIG_UTF8
key = get_kbd_key(ev);
#else /* !CONFIG_UTF8 */
key = cp2u(get_opt_codepage_tree(ses->tab->term->spec,
"charset"),
get_kbd_key(ev));
#endif /* !CONFIG_UTF8 */
/* If @key now is 0 (which is used in link.accesskey if there
* is no access key) or UCS_REPLACEMENT_CHARACTER, then the
* results may be a little odd, but not really harmful. */
/* Run through all the links and see if one of them is bound to the
* key we test.. */
key = get_kbd_key(ev);
for (i = 0; i < doc_view->document->nlinks; i++) {
struct link *link = &doc_view->document->links[i];
if (key == link->accesskey) { /* FIXME: key vs unicode ... */
if (key == link->accesskey) {
if (passed != i && i <= doc_view->vs->current_link) {
/* This is here in order to rotate between
* links with same accesskey. */
@ -1380,9 +1402,9 @@ get_current_link_title(struct document_view *doc_view)
doc_view->document->options.cp,
CSM_DEFAULT, NULL, NULL, NULL);
/* Remove illicit chars. */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (link_title && !doc_view->document->options.utf8)
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
for (src = link_title; *src; src++)
if (!isprint(*src) || iscntrl(*src))
*src = '*';
@ -1435,11 +1457,11 @@ get_current_link_info(struct session *ses, struct document_view *doc_view)
add_char_to_string(&str, ')');
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8)
decode_uri_string(&str);
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
decode_uri_string_for_display(&str);
return str.source;
}

View File

@ -10,7 +10,7 @@
#include <ctype.h> /* tolower(), isprint() */
#if defined(CONFIG_UTF_8) && defined(HAVE_WCTYPE_H)
#if defined(CONFIG_UTF8) && defined(HAVE_WCTYPE_H)
#include <wctype.h>
#endif
@ -51,7 +51,7 @@
static INIT_INPUT_HISTORY(search_history);
#undef UCHAR
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
#define UCHAR unicode_val_T
#else
#define UCHAR unsigned char
@ -456,7 +456,7 @@ is_in_range_regex(struct document *document, int y, int height,
static UCHAR *
memacpy_u(unsigned char *text, int textlen, int utf8)
{
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
UCHAR *mem = mem_alloc((textlen + 1) * sizeof(UCHAR));
if (!mem) return NULL;
@ -464,7 +464,7 @@ memacpy_u(unsigned char *text, int textlen, int utf8)
int i;
for (i = 0; i < textlen; i++)
mem[i] = utf_8_to_unicode(&text, text + 7);
mem[i] = utf8_to_unicode(&text, text + 7);
} else {
int i;
@ -481,7 +481,7 @@ memacpy_u(unsigned char *text, int textlen, int utf8)
static int
strlen_u(unsigned char *text, int utf8)
{
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (utf8)
return strlen_utf8(&text);
#endif
@ -500,7 +500,7 @@ lowered_string(unsigned char *text, int textlen, int utf8)
ret = memacpy_u(text, textlen, utf8);
if (ret && textlen) {
do {
#if defined(CONFIG_UTF_8) && defined(HAVE_WCTYPE_H)
#if defined(CONFIG_UTF8) && defined(HAVE_WCTYPE_H)
ret[textlen] = utf8 ? towlower(ret[textlen]) : tolower(ret[textlen]);
#else
ret[textlen] = tolower(ret[textlen]);
@ -530,7 +530,7 @@ is_in_range_plain(struct document *document, int y, int height,
* trivial, probably a starter; very fast as well) or Turbo-BM (or
* maybe some other Boyer-Moore variant, I don't feel that strong in
* this area), hmm? >:) --pasky */
#if defined(CONFIG_UTF_8) && defined(HAVE_WCTYPE_H)
#if defined(CONFIG_UTF8) && defined(HAVE_WCTYPE_H)
#define maybe_tolower(c) (case_sensitive ? (c) : utf8 ? towlower(c) : tolower(c))
#else
#define maybe_tolower(c) (case_sensitive ? (c) : tolower(c))
@ -579,7 +579,7 @@ is_in_range(struct document *document, int y, int height,
assert(document && text && min && max);
if_assert_failed return -1;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
utf8 = document->options.utf8;
#endif
*min = INT_MAX, *max = 0;
@ -619,7 +619,7 @@ get_searched_plain(struct document_view *doc_view, struct point **pt, int *pl,
xoffset = box->x - doc_view->vs->x;
yoffset = box->y - doc_view->vs->y;
#if defined(CONFIG_UTF_8) && defined(HAVE_WCTYPE_H)
#if defined(CONFIG_UTF8) && defined(HAVE_WCTYPE_H)
#define maybe_tolower(c) (case_sensitive ? (c) : utf8 ? towlower(c) : tolower(c))
#else
#define maybe_tolower(c) (case_sensitive ? (c) : tolower(c))
@ -777,7 +777,7 @@ draw_searched(struct terminal *term, struct document_view *doc_view)
if (!has_search_word(doc_view))
return;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
utf8 = doc_view->document->options.utf8;
#endif
get_searched(doc_view, &pt, &len, utf8);
@ -924,7 +924,7 @@ static int
find_next_link_in_search(struct document_view *doc_view, int direction)
{
int utf8 = 0;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
utf8 = doc_view->document->options.utf8;
#endif
@ -1627,12 +1627,13 @@ search_dlg_do(struct terminal *term, struct memory_list *ml,
unsigned char *field;
struct search_dlg_hop *hop;
unsigned char *text = _("Search for text", term);
struct option *search_options;
hop = mem_calloc(1, sizeof(*hop));
if (!hop) return;
checkout_option_values(resolvers, get_opt_rec(config_options,
"document.browse.search"),
search_options = get_opt_rec(config_options, "document.browse.search");
checkout_option_values(resolvers, search_options,
hop->values, SEARCH_OPTIONS);
hop->data = data;

View File

@ -40,11 +40,11 @@
struct line_info {
int start;
int end;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
int last_char_width;
int split_prev:1;
int split_next:1;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
};
/* We add two extra entries to the table so the ending info can be added
@ -52,7 +52,7 @@ struct line_info {
#define realloc_line_info(info, size) \
mem_align_alloc(info, size, (size) + 3, 0xFF)
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
/* Allocates a line_info table describing the layout of the textarea buffer.
*
* @width is max width and the offset at which text will be wrapped
@ -134,7 +134,7 @@ format_textutf8(unsigned char *text, int width, enum form_wrap wrap, int format)
return line;
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* Allocates a line_info table describing the layout of the textarea buffer.
*
@ -226,7 +226,7 @@ get_textarea_line_number(struct line_info *line, int cursor_position)
/* Fixes up the vpos and vypos members of the form_state. Returns the
* logical position in the textarea view. */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
int
area_cursor(struct form_control *fc, struct form_state *fs, int utf8)
{
@ -313,7 +313,7 @@ area_cursor(struct form_control *fc, struct form_state *fs)
}
#endif
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
static void
draw_textarea_utf8(struct terminal *term, struct form_state *fs,
struct document_view *doc_view, struct link *link)
@ -367,7 +367,7 @@ draw_textarea_utf8(struct terminal *term, struct form_state *fs,
if (i >= -fs->vpos && text < end) {
int cell;
data = utf_8_to_unicode(&text, end);
data = utf8_to_unicode(&text, end);
cell = unicode_to_cell(data);
if (cell == 2) {
draw_char_data(term, x++, y, data);
@ -395,7 +395,7 @@ draw_textarea_utf8(struct terminal *term, struct form_state *fs,
mem_free(linex);
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
void
draw_textarea(struct terminal *term, struct form_state *fs,
@ -411,12 +411,12 @@ draw_textarea(struct terminal *term, struct form_state *fs,
assert(term && doc_view && doc_view->document && doc_view->vs && link);
if_assert_failed return;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (term->utf8) {
draw_textarea_utf8(term, fs, doc_view, link);
return;
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
fc = get_link_form_control(link);
assertm(fc, "link %d has no form control", (int) (link - doc_view->document->links));
if_assert_failed return;
@ -426,11 +426,11 @@ draw_textarea(struct terminal *term, struct form_state *fs,
vy = doc_view->vs->y;
if (!link->npoints) return;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
area_cursor(fc, fs, 0);
#else
area_cursor(fc, fs);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
linex = format_text(fs->value, fc->cols, fc->wrap, 0);
if (!linex) return;
line = linex;
@ -686,7 +686,7 @@ menu_textarea_edit(struct terminal *term, void *xxx, void *ses_)
textarea_edit(0, term, fs, doc_view, link);
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
static enum frame_event_status
textarea_op(struct form_state *fs, struct form_control *fc, int utf8,
int (*do_op)(struct form_state *, struct line_info *, int, int))
@ -743,9 +743,9 @@ textarea_op(struct form_state *fs, struct form_control *fc,
return fs->state == state ? FRAME_EVENT_OK : FRAME_EVENT_REFRESH;
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
void
new_pos(struct form_state *fs, struct line_info *line, int current, int max_cells)
{
@ -754,34 +754,34 @@ new_pos(struct form_state *fs, struct line_info *line, int current, int max_cell
int cells = 0;
while(cells < max_cells) {
unicode_val_T data = utf_8_to_unicode(&text, end);
unicode_val_T data = utf8_to_unicode(&text, end);
if (data == UCS_NO_CHAR) break;
cells += unicode_to_cell(data);
}
fs->state = (int)(text - fs->value);
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
static int
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
do_op_home(struct form_state *fs, struct line_info *line, int current, int utf8)
#else
do_op_home(struct form_state *fs, struct line_info *line, int current)
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
if (current == -1)
return 0;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (utf8)
fs->state = line[current - !!fs->state_cell].start;
else
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
fs->state = line[current].start;
return 0;
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
static int
do_op_up(struct form_state *fs, struct line_info *line, int current, int utf8)
{
@ -835,9 +835,9 @@ do_op_up(struct form_state *fs, struct line_info *line, int current)
int_upper_bound(&fs->state, line[current-1].end);
return 0;
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
static int
do_op_down(struct form_state *fs, struct line_info *line, int current, int utf8)
{
@ -889,9 +889,9 @@ do_op_down(struct form_state *fs, struct line_info *line, int current)
int_upper_bound(&fs->state, line[current+1].end);
return 0;
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
static int
do_op_end(struct form_state *fs, struct line_info *line, int current, int utf8)
{
@ -937,14 +937,14 @@ do_op_end(struct form_state *fs, struct line_info *line, int current)
}
return 0;
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
static int
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
do_op_bob(struct form_state *fs, struct line_info *line, int current, int utf8)
#else
do_op_bob(struct form_state *fs, struct line_info *line, int current)
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
if (current == -1) return 0;
@ -954,11 +954,11 @@ do_op_bob(struct form_state *fs, struct line_info *line, int current)
}
static int
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
do_op_eob(struct form_state *fs, struct line_info *line, int current, int utf8)
#else
do_op_eob(struct form_state *fs, struct line_info *line, int current)
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
if (current == -1) {
fs->state = strlen(fs->value);
@ -974,7 +974,7 @@ do_op_eob(struct form_state *fs, struct line_info *line, int current)
return 0;
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
enum frame_event_status
textarea_op_home(struct form_state *fs, struct form_control *fc, int utf8)
{
@ -986,9 +986,9 @@ textarea_op_home(struct form_state *fs, struct form_control *fc)
{
return textarea_op(fs, fc, do_op_home);
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
enum frame_event_status
textarea_op_up(struct form_state *fs, struct form_control *fc, int utf8)
{
@ -1000,9 +1000,9 @@ textarea_op_up(struct form_state *fs, struct form_control *fc)
{
return textarea_op(fs, fc, do_op_up);
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
enum frame_event_status
textarea_op_down(struct form_state *fs, struct form_control *fc, int utf8)
{
@ -1014,9 +1014,9 @@ textarea_op_down(struct form_state *fs, struct form_control *fc)
{
return textarea_op(fs, fc, do_op_down);
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
enum frame_event_status
textarea_op_end(struct form_state *fs, struct form_control *fc, int utf8)
{
@ -1028,11 +1028,11 @@ textarea_op_end(struct form_state *fs, struct form_control *fc)
{
return textarea_op(fs, fc, do_op_end);
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* Set the form state so the cursor is on the first line of the buffer.
* Preserve the column if possible. */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
enum frame_event_status
textarea_op_bob(struct form_state *fs, struct form_control *fc, int utf8)
{
@ -1044,13 +1044,13 @@ textarea_op_bob(struct form_state *fs, struct form_control *fc)
{
return textarea_op(fs, fc, do_op_bob);
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
/* Set the form state so the cursor is on the last line of the buffer. Preserve
* the column if possible. This is done by getting current and last line and
* then shifting the state by the delta of both lines start position bounding
* the whole thing to the end of the last line. */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
enum frame_event_status
textarea_op_eob(struct form_state *fs, struct form_control *fc, int utf8)
{
@ -1062,14 +1062,14 @@ textarea_op_eob(struct form_state *fs, struct form_control *fc)
{
return textarea_op(fs, fc, do_op_eob);
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
enum frame_event_status
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
textarea_op_enter(struct form_state *fs, struct form_control *fc, int utf8)
#else
textarea_op_enter(struct form_state *fs, struct form_control *fc)
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
{
assert(fs && fs->value && fc);
if_assert_failed return FRAME_EVENT_OK;
@ -1083,7 +1083,7 @@ textarea_op_enter(struct form_state *fs, struct form_control *fc)
return FRAME_EVENT_REFRESH;
}
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
static int
do_op_left(struct form_state *fs, struct line_info *line, int current, int utf8)
{
@ -1135,7 +1135,7 @@ do_op_right(struct form_state *fs, struct line_info *line, int current, int utf8
text = fs->value + fs->state;
end = strchr(text, '\0');
old_state = fs->state;
utf_8_to_unicode(&text, end);
utf8_to_unicode(&text, end);
fs->state = text - fs->value;
@ -1147,9 +1147,9 @@ do_op_right(struct form_state *fs, struct line_info *line, int current, int utf8
return 0;
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
enum frame_event_status
textarea_op_left(struct form_state *fs, struct form_control *fc, int utf8)
{
@ -1161,7 +1161,7 @@ textarea_op_right(struct form_state *fs, struct form_control *fc, int utf8)
{
return textarea_op(fs, fc, utf8, do_op_right);
}
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
void
set_textarea(struct document_view *doc_view, int direction)
@ -1169,9 +1169,9 @@ set_textarea(struct document_view *doc_view, int direction)
struct form_control *fc;
struct form_state *fs;
struct link *link;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
int utf8 = doc_view->document->options.utf8;
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
assert(doc_view && doc_view->vs && doc_view->document);
assert(direction == 1 || direction == -1);
@ -1192,7 +1192,7 @@ set_textarea(struct document_view *doc_view, int direction)
/* Depending on which way we entered the textarea move cursor so that
* it is available at end or start. */
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
if (direction == 1)
textarea_op_eob(fs, fc, utf8);
else
@ -1202,5 +1202,5 @@ set_textarea(struct document_view *doc_view, int direction)
textarea_op_eob(fs, fc);
else
textarea_op_bob(fs, fc);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
}

View File

@ -13,11 +13,11 @@ struct link;
struct session;
struct terminal;
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
int area_cursor(struct form_control *fc, struct form_state *fs, int utf8);
#else
int area_cursor(struct form_control *fc, struct form_state *fs);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
void draw_textarea(struct terminal *term, struct form_state *fs, struct document_view *doc_view, struct link *link);
unsigned char *encode_textarea(struct submitted_value *sv);
@ -25,7 +25,7 @@ extern int textarea_editor;
void textarea_edit(int, struct terminal *, struct form_state *, struct document_view *, struct link *);
void menu_textarea_edit(struct terminal *term, void *xxx, void *ses_);
#ifdef CONFIG_UTF_8
#ifdef CONFIG_UTF8
enum frame_event_status textarea_op_home(struct form_state *fs, struct form_control *fc, int utf8);
enum frame_event_status textarea_op_up(struct form_state *fs, struct form_control *fc, int utf8);
enum frame_event_status textarea_op_down(struct form_state *fs, struct form_control *fc, int utf8);
@ -43,7 +43,7 @@ enum frame_event_status textarea_op_end(struct form_state *fs, struct form_contr
enum frame_event_status textarea_op_bob(struct form_state *fs, struct form_control *fc);
enum frame_event_status textarea_op_eob(struct form_state *fs, struct form_control *fc);
enum frame_event_status textarea_op_enter(struct form_state *fs, struct form_control *fc);
#endif /* CONFIG_UTF_8 */
#endif /* CONFIG_UTF8 */
void set_textarea(struct document_view *doc_view, int direction);

View File

@ -637,7 +637,20 @@ enum frame_event_status
try_mark_key(struct session *ses, struct document_view *doc_view,
struct term_event *ev)
{
unsigned char mark = get_kbd_key(ev);
term_event_key_T key = get_kbd_key(ev);
unsigned char mark;
/* set_mark and goto_mark allow only a subset of the ASCII
* character repertoire as mark characters. If get_kbd_key(ev)
* is something else (i.e. a special key or a non-ASCII
* character), map it to an ASCII character that the functions
* will not accept, so the results are consistent.
* When CONFIG_UTF8 is not defined, this assumes that codes
* 0 to 0x7F in all codepages match ASCII. */
if (key >= 0 && key <= 0x7F)
mark = (unsigned char) key;
else
mark = 0;
switch (ses->kbdprefix.mark) {
case KP_MARK_NOTHING:
@ -1042,15 +1055,15 @@ send_mouse_event(struct session *ses, struct document_view *doc_view,
/* Handle tabs navigation if tabs bar is displayed. */
if (ses->status.show_tabs_bar && is_mouse_on_tab_bar(ses, mouse)) {
int tab_num = get_tab_number_by_xpos(term, mouse->x);
struct window *tab = get_current_tab(term);
struct window *current_tab = get_current_tab(term);
if (check_mouse_action(ev, B_UP)) {
if (check_mouse_button(ev, B_MIDDLE)
&& term->current_tab == tab_num
&& mouse->y == term->prev_mouse_event.y) {
if (tab->data == ses) ses = NULL;
if (current_tab->data == ses) ses = NULL;
close_tab(term, tab->data);
close_tab(term, current_tab->data);
}
return ses;
@ -1068,7 +1081,7 @@ send_mouse_event(struct session *ses, struct document_view *doc_view,
if (check_mouse_button(ev, B_MIDDLE)) {
do_not_ignore_next_mouse_event(term);
} else if (check_mouse_button(ev, B_RIGHT)) {
tab_menu(tab->data, mouse->x, mouse->y, 1);
tab_menu(current_tab->data, mouse->x, mouse->y, 1);
}
}
@ -1157,7 +1170,8 @@ quit:
if (check_kbd_key(ev, KBD_CTRL_C)) goto quit;
if (get_kbd_modifier(ev) & KBD_MOD_ALT) {
/* Ctrl-Alt-F should not open the File menu like Alt-f does. */
if (check_kbd_modifier(ev, KBD_MOD_ALT)) {
struct window *win;
get_kbd_modifier(ev) &= ~KBD_MOD_ALT;

View File

@ -0,0 +1,109 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"
"http://www.w3.org/TR/REC-html40/strict.dtd">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Script-Type" content="application/ecmascript">
<title>ECMAScript accessKey tests</title>
<h1>ECMAScript accessKey tests</h1>
<h2>Set valid access keys and read them back</h2>
<p>This does not automatically test that the assigned access keys
actually work.</p>
<form name="form1" action="#">
<p><input type="button" onclick="run1()" value="Test"> <input id="result1" value="not run">
<input type="reset">
<table>
<tr><td><input id="a1" accesskey="a"><td><td>empty string
<tr><td><input id="b1" accesskey="b"><td>U+0020<td>must not become "Space"
<tr><td><input id="c1" accesskey="c"><td>U+0025<td>ASCII punctuation
<tr><td><input id="d1" accesskey="d"><td>U+007A<td>ASCII letter
<tr><td><input id="e1" accesskey="e"><td>U+00E5<td>Latin-1
<tr><td><input id="f1" accesskey="f"><td>U+0161<td>Latin-9
<tr><td><input id="g1" accesskey="g"><td>U+3042<td>Hiragana
<tr><td><input id="h1" accesskey="h"><td>U+10A55<td>Kharoshthi
</table>
</form>
<script type="application/ecmascript">
function run1() {
var form = window.document.forms["form1"];
form.elements["result1"].value = "running";
var ok = true;
var probe = function(element, accessKey) {
element.accessKey = accessKey;
if (element.accessKey != accessKey) {
ok = false;
element.value = "failed " + accessKey + "/" + element.accessKey;
} else {
element.value = "passed " + accessKey + "/" + element.accessKey;
}
}
probe(form.elements["a1"], "");
probe(form.elements["b1"], " ");
probe(form.elements["c1"], "%");
probe(form.elements["d1"], "z");
probe(form.elements["e1"], "\u00E5");
probe(form.elements["f1"], "\u0161");
probe(form.elements["g1"], "\u3042");
probe(form.elements["h1"], "\uD802\uDE55");
form.elements["result1"].value = ok ? "passed" : "failed";
return false;
}
</script>
<h2>These might throw errors</h2>
<form name="form2" action="#">
<table>
<tr><td><input type="button" value="Test" onclick='run2("a2",-273.15)'><td><input id="a2"><td>number -273.15
<tr><td><input type="button" value="Test" onclick='run2("b2","\u0000")'><td><input id="b2"><td>U+0000
<tr><td><input type="button" value="Test" onclick='run2("c2","\u0001")'><td><input id="c2"><td>U+0001
<tr><td><input type="button" value="Test" onclick='run2("d2","\u000A")'><td><input id="d2"><td>U+000A
<tr><td><input type="button" value="Test" onclick='run2("e2","hyi")'><td><input id="e2"><td>"hyi"
<tr><td><input type="reset">
</table>
</form>
<script type="application/ecmascript">
function run2(name, accessKey) {
var form = window.document.forms["form2"];
var element = form.elements[name];
element.accessKey = accessKey;
if (element.accessKey != accessKey)
element.value = "different " + accessKey + "/" + element.accessKey;
else
element.value = "same " + accessKey + "/" + element.accessKey;
return false;
}
</script>
<h2>Invalid uses of surrogates</h2>
<form name="form3" action="#">
<table>
<tr><td><input type="button" value="Test" onclick='run3("a3","\uD800")'><td><input id="a3"><td>U+D800
<tr><td><input type="button" value="Test" onclick='run3("b3","\uD800.")'><td><input id="b3"><td>U+D800 U+002E
<tr><td><input type="button" value="Test" onclick='run3("c3","\uD800\uD800")'><td><input id="c3"><td>U+D800 U+D800
<tr><td><input type="button" value="Test" onclick='run3("d3","\uD800\uDBFF")'><td><input id="d3"><td>U+D800 U+DBFF
<tr><td><input type="button" value="Test" onclick='run3("e3","\uD800\uE000")'><td><input id="e3"><td>U+D800 U+E000
<tr><td><input type="button" value="Test" onclick='run3("f3","\uDBFF\uDBFF")'><td><input id="f3"><td>U+DBFF U+DBFF
<tr><td><input type="button" value="Test" onclick='run3("g3","\uDC00")'><td><input id="g3"><td>U+DC00
<tr><td><input type="button" value="Test" onclick='run3("h3","\uDC00.")'><td><input id="h3"><td>U+DC00 U+002E
<tr><td><input type="button" value="Test" onclick='run3("i3","\uDC00\uD800")'><td><input id="i3"><td>U+DC00 U+D800
<tr><td><input type="button" value="Test" onclick='run3("j3","\uDC00\uDBFF")'><td><input id="j3"><td>U+DC00 U+DBFF
<tr><td><input type="button" value="Test" onclick='run3("k3","\uDC00\uDC00")'><td><input id="k3"><td>U+DC00 U+DC00
<tr><td><input type="button" value="Test" onclick='run3("l3","\uDC00\uDFFF")'><td><input id="l3"><td>U+DC00 U+DFFF
<tr><td><input type="button" value="Test" onclick='run3("m3","\uDC00\uFF20")'><td><input id="m3"><td>U+DC00 U+FF20
<tr><td><input type="button" value="Test" onclick='run3("n3","\uDFFF")'><td><input id="n3"><td>U+DFFF
<tr><td><input type="button" value="Test" onclick='run3("o3","\uDFFF\uDFFF")'><td><input id="o3"><td>U+DFFF U+DFFF
<tr><td><input type="reset">
</table>
</form>
<script type="application/ecmascript">
function run3(name, accessKey) {
var form = window.document.forms["form3"];
var element = form.elements[name];
element.accessKey = accessKey;
if (element.accessKey != accessKey)
element.value = "different " + accessKey + "/" + element.accessKey;
else
element.value = "same " + accessKey + "/" + element.accessKey;
return false;
}
</script>