1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-09-28 03:06:20 -04: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.
This commit is contained in:
Witold Filipczyk 2007-07-12 21:20:58 +02:00 committed by Witold Filipczyk
parent 4cca8f1a2c
commit 6bc992250b
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

@ -1290,6 +1290,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

@ -30,6 +30,7 @@
#include "util/memory.h"
#include "util/snprintf.h"
#include "util/string.h"
#include "viewer/text/textarea.h"
#include "viewer/timer.h"
@ -116,6 +117,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;
@ -439,6 +441,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

@ -19,6 +19,7 @@ enum term_event_type {
EVENT_REDRAW,
EVENT_RESIZE,
EVENT_ABORT,
EVENT_TEXTAREA,
};
struct term_event {
@ -51,6 +52,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

@ -40,6 +40,8 @@
/* TODO: move stuff from here to itrm.{c,h} and mouse.{c,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 *);
@ -348,10 +350,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));
}
@ -545,6 +554,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

@ -202,7 +202,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);
}
@ -255,15 +255,16 @@ exec_on_slave_terminal( struct terminal *term,
unsigned char *delete, int dlen,
int 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

@ -151,6 +151,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) \
@ -574,16 +587,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")) {
@ -593,61 +599,70 @@ 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 = get_opt_str("document.browse.forms.editor");
unsigned char *ex;
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;
}
if (!ed || !*ed) {
ed = getenv("EDITOR");
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;
}
if (fs_) fs = fs_;
if (doc_view_) doc_view = doc_view_;
if (fs_) td->fs = fs_;
if (doc_view_) td->doc_view = doc_view_;
if (link_) {
link = link_;
fc_maxlength = get_link_form_control(link_)->maxlength;
td->link = link_;
td->fc_maxlength = get_link_form_control(link_)->maxlength;
}
if (term_) term = term_;
if (term_) td->term = term_;
add_to_list(textarea_list, td);
exec_on_terminal(term, ex, "", 1);
exec_on_terminal(td->term, ex, "", 1);
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"
@ -656,27 +671,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 */