1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-28 01:35:32 +00:00

bug 181: Allow edit textareas using an external editor on slave terminals.

Added EVENT_TEXTAREA used to notify the master terminal
about end of execution of an external program on a slave terminal.
The format of data sent to the master terminal by exec_on_slave_terminal
has changed. Now after 0, fg the value of term is sent.
Therfore this release of ELinks is incompatible with previous releases.

Patch by Witold Filipczyk, taken from his witekfl branch.

Conflicts:

	src/viewer/text/textarea.c
This commit is contained in:
Miciah Dashiel Butler Masters 2007-09-01 03:08:47 +00:00 committed by Miciah Dashiel Butler Masters
parent 69cf0d06e2
commit 1000f88748
11 changed files with 100 additions and 55 deletions

View File

@ -460,6 +460,8 @@ dialog_func(struct window *win, struct term_event *ev)
case EVENT_ABORT:
dialog_ev_abort(dlg_data);
break;
case EVENT_TEXTAREA:
break;
}
}

View File

@ -281,6 +281,7 @@ hierbox_dialog_event_handler(struct dialog_data *dlg_data)
case EVENT_RESIZE:
case EVENT_REDRAW:
case EVENT_MOUSE:
case EVENT_TEXTAREA:
return EVENT_NOT_PROCESSED;
case EVENT_ABORT:

View File

@ -729,6 +729,7 @@ kbd_listbox(struct dialog_data *dlg_data, struct widget_data *widget_data)
case EVENT_REDRAW:
case EVENT_MOUSE:
case EVENT_ABORT:
case EVENT_TEXTAREA:
break;
}

View File

@ -1006,6 +1006,8 @@ menu_handler(struct window *win, struct term_event *ev)
case EVENT_ABORT:
free_menu_items(menu->items);
break;
case EVENT_TEXTAREA:
break;
}
}
@ -1343,6 +1345,7 @@ mainmenu_handler(struct window *win, struct term_event *ev)
break;
case EVENT_ABORT:
case EVENT_TEXTAREA:
break;
}
}

View File

@ -1283,6 +1283,8 @@ tabwin_func(struct window *tab, struct term_event *ev)
assert(ses->tab == get_current_tab(ses->tab->term));
send_event(ses, ev);
break;
case EVENT_TEXTAREA:
break;
}
}

View File

@ -31,6 +31,7 @@
#include "util/memory.h"
#include "util/snprintf.h"
#include "util/string.h"
#include "viewer/text/textarea.h"
#include "viewer/timer.h"
@ -118,6 +119,7 @@ term_send_event(struct terminal *term, struct term_event *ev)
case EVENT_MOUSE:
case EVENT_KBD:
case EVENT_ABORT:
case EVENT_TEXTAREA:
assert(!list_empty(term->windows));
if_assert_failed break;
@ -443,6 +445,10 @@ invalid_utf8_start_byte:
case EVENT_ABORT:
destroy_terminal(term);
return 0;
case EVENT_TEXTAREA:
if (textarea_editor)
textarea_edit(1, ilev->info.textarea, NULL, NULL, NULL);
break;
default:
ERROR(gettext("Bad event %d"), ilev->ev);

View File

@ -20,6 +20,7 @@ enum term_event_type {
EVENT_REDRAW,
EVENT_RESIZE,
EVENT_ABORT,
EVENT_TEXTAREA,
};
/** An event received from a terminal. This type can be changed
@ -58,6 +59,9 @@ struct interlink_event {
/* ::EVENT_INIT, ::EVENT_RESIZE, ::EVENT_REDRAW */
#define interlink_event_size term_event_size
struct interlink_event_size size;
/* EVENT_TEXTAREA */
struct terminal *textarea;
} info;
};

View File

@ -42,6 +42,8 @@
#include "util/time.h"
struct itrm *ditrm = NULL;
static struct terminal *slave_term;
static unsigned char *term_addr = (unsigned char *)&slave_term;
static void free_itrm(struct itrm *);
static void in_kbd(struct itrm *);
@ -352,10 +354,17 @@ handle_trm(int std_in, int std_out, int sock_in, int sock_out, int ctl_in,
static void
unblock_itrm_x(void *h)
{
struct interlink_event ev;
close_handle(h);
if (!ditrm) return;
unblock_itrm();
resize_terminal();
memset(&ev, 0, sizeof(ev));
ev.ev = EVENT_TEXTAREA;
ev.info.textarea = slave_term;
itrm_queue_event(ditrm, (char *) &ev, sizeof(ev));
}
@ -549,6 +558,9 @@ has_nul_byte:
}
RD(fg);
for (i = 0; i < sizeof(slave_term); i++) {
RD(term_addr[i]);
}
if (!init_string(&path)) goto free_and_return;

View File

@ -203,7 +203,7 @@ unblock_terminal(struct terminal *term)
unblock_itrm();
redraw_terminal_cls(term);
if (textarea_editor) /* XXX */
textarea_edit(1, NULL, NULL, NULL, NULL);
textarea_edit(1, term, NULL, NULL, NULL);
}
@ -256,15 +256,16 @@ exec_on_slave_terminal( struct terminal *term,
unsigned char *delete, int dlen,
enum term_exec fg)
{
int data_size = plen + dlen + 1 /* 0 */ + 1 /* fg */ + 2 /* 2 null char */;
int data_size = sizeof(term) + plen + dlen + 1 /* 0 */ + 1 /* fg */ + 2 /* 2 null char */;
unsigned char *data = fmem_alloc(data_size);
if (!data) return;
data[0] = 0;
data[1] = fg;
memcpy(data + 2, path, plen + 1);
memcpy(data + 2 + plen + 1, delete, dlen + 1);
memcpy(data + 2, &term, sizeof(term));
memcpy(data + 2 + sizeof(term), path, plen + 1);
memcpy(data + 2 + sizeof(term) + plen + 1, delete, dlen + 1);
hard_write(term->fdout, data, data_size);
fmem_free(data);
}

View File

@ -152,6 +152,7 @@ empty_window_handler(struct window *win, struct term_event *ev)
return;
case EVENT_KBD:
case EVENT_MOUSE:
case EVENT_TEXTAREA:
/* Silence compiler warnings */
break;
}

View File

@ -29,6 +29,7 @@
#include "terminal/window.h"
#include "util/error.h"
#include "util/file.h"
#include "util/lists.h"
#include "util/memory.h"
#include "util/string.h"
#include "viewer/action.h"
@ -47,6 +48,18 @@ struct line_info {
#endif /* CONFIG_UTF8 */
};
struct textarea_data {
LIST_HEAD(struct textarea_data);
size_t fc_maxlength;
struct form_state *fs;
struct terminal *term;
struct document_view *doc_view;
struct link *link;
unsigned char *fn;
};
static INIT_LIST_HEAD(textarea_list); /* struct textarea_data */
/** We add two extra entries to the table so the ending info can be added
* without reallocating. */
#define realloc_line_info(info, size) \
@ -577,16 +590,9 @@ void
textarea_edit(int op, struct terminal *term_, struct form_state *fs_,
struct document_view *doc_view_, struct link *link_)
{
static size_t fc_maxlength;
static struct form_state *fs;
static struct terminal *term;
static struct document_view *doc_view;
static struct link *link;
static unsigned char *fn;
struct textarea_data *td;
assert (op == 0 || op == 1);
if_assert_failed return;
assert (op == 1 || term_);
assert ((op == 0 || op == 1) && term_);
if_assert_failed return;
if (op == 0 && get_cmd_opt_bool("anonymous")) {
@ -596,20 +602,20 @@ textarea_edit(int op, struct terminal *term_, struct form_state *fs_,
return;
}
if (op == 0 && !term_->master) {
info_box(term_, 0, N_("Error"), ALIGN_CENTER,
N_("You can do this only on the master terminal"));
return;
}
if (op == 0 && !textarea_editor) {
if (op == 0) {
unsigned char *ed;
unsigned char *ex;
assert(fs_ && doc_view_ && link_ && term_);
fn = save_textarea_file(fs_->value);
if (!fn) return;
td = mem_calloc(1, sizeof(*td));
if (!td) return;
td->fn = save_textarea_file(fs_->value);
if (!td->fn) {
mem_free(td);
return;
}
ed = get_opt_str("document.browse.forms.editor",
doc_view_->session);
@ -618,41 +624,50 @@ textarea_edit(int op, struct terminal *term_, struct form_state *fs_,
if (!ed || !*ed) ed = "vi";
}
ex = straconcat(ed, " ", fn, (unsigned char *) NULL);
ex = straconcat(ed, " ", td->fn, (unsigned char *) NULL);
if (!ex) {
unlink(fn);
unlink(td->fn);
goto free_and_return;
}
fs = fs_;
doc_view = doc_view_;
link = link_;
fc_maxlength = get_link_form_control(link_)->maxlength;
term = term_;
td->fs = fs_;
td->doc_view = doc_view_;
td->link = link_;
td->fc_maxlength = get_link_form_control(link_)->maxlength;
td->term = term_;
add_to_list(textarea_list, td);
exec_on_terminal(term, ex, "", TERM_EXEC_FG);
exec_on_terminal(td->term, ex, "", TERM_EXEC_FG);
mem_free(ex);
textarea_editor = 1;
textarea_editor++;
return;
} else if (op == 1 && fs) {
} else if (op == 1) {
int found = 0;
struct string file;
if (!init_string(&file)
|| !add_file_to_string(&file, fn)) {
textarea_editor = 0;
goto free_and_return;
foreach (td, textarea_list) {
if (td->term == term_) {
found = 1;
break;
}
}
if (!found) return;
if (file.length > fc_maxlength) {
file.source[fc_maxlength] = '\0';
if (!td->fs || !init_string(&file)
|| !add_file_to_string(&file, td->fn))
goto end;
if (file.length > td->fc_maxlength) {
file.source[td->fc_maxlength] = '\0';
/* Casting size_t fc_maxlength to unsigned int
* and formatting it with "%u" is safe,
* because fc_maxlength is smaller than
* file.length, which is an int. */
info_box(term, MSGBOX_FREE_TEXT, N_("Warning"),
info_box(td->term, MSGBOX_FREE_TEXT, N_("Warning"),
ALIGN_CENTER,
msg_text(term,
msg_text(td->term,
N_("You have exceeded the textarea's"
" size limit: your input is %d"
" bytes, but the maximum is %u"
@ -661,27 +676,24 @@ textarea_edit(int op, struct terminal *term_, struct form_state *fs_,
" but you can still recover the"
" text that you entered from"
" this file: %s"), file.length,
(unsigned int) fc_maxlength, fn));
(unsigned int) td->fc_maxlength, td->fn));
} else {
unlink(fn);
unlink(td->fn);
}
mem_free(fs->value);
fs->value = file.source;
fs->state = file.length;
mem_free(td->fs->value);
td->fs->value = file.source;
td->fs->state = file.length;
if (doc_view && link)
draw_form_entry(term, doc_view, link);
textarea_editor = 0;
goto free_and_return;
if (td->doc_view && td->link)
draw_form_entry(td->term, td->doc_view, td->link);
}
return;
end:
del_from_list(td);
textarea_editor--;
free_and_return:
mem_free_set(&fn, NULL);
fs = NULL;
mem_free(td->fn);
mem_free(td);
}
/* menu_func_T */