Blame SOURCES/elinks-scroll.patch

ab432b
From f513964579f72fc77eea6e0961e49cc8299bf204 Mon Sep 17 00:00:00 2001
ab432b
From: Witold Filipczyk <witekfl@poczta.onet.pl>
ab432b
Date: Sun, 31 Aug 2008 14:23:28 +0200
ab432b
Subject: [PATCH] Use real_box in dialog.c.
ab432b
ab432b
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
ab432b
---
ab432b
 src/bfu/button.c       |   32 +++++++++++++-------------
ab432b
 src/bfu/button.h       |    3 +-
ab432b
 src/bfu/checkbox.c     |   13 +++++-----
ab432b
 src/bfu/checkbox.h     |    3 +-
ab432b
 src/bfu/dialog.c       |   59 ++++++++++++++++++++++++++++++++++-------------
ab432b
 src/bfu/dialog.h       |    2 +
ab432b
 src/bfu/group.c        |   18 +++++++-------
ab432b
 src/bfu/group.h        |    2 +-
ab432b
 src/bfu/inpfield.c     |   10 ++++----
ab432b
 src/bfu/inpfield.h     |    2 +-
ab432b
 src/bfu/listbox.c      |    3 +-
ab432b
 src/bfu/listbox.h      |    2 +-
ab432b
 src/bfu/text.c         |   16 +++++++-----
ab432b
 src/bfu/text.h         |    5 ++-
ab432b
 src/dialogs/download.c |   12 +++++-----
ab432b
 src/terminal/draw.c    |   36 +++++++++++++++++++++++++++++
ab432b
 src/terminal/draw.h    |   10 ++++++++
ab432b
 src/terminal/window.c  |   15 ++++++++++++
ab432b
 src/terminal/window.h  |    2 +
ab432b
 19 files changed, 170 insertions(+), 75 deletions(-)
ab432b
ab432b
diff --git a/src/bfu/button.c b/src/bfu/button.c
ab432b
index 8267c94..8e6ac62 100644
ab432b
--- a/src/bfu/button.c
ab432b
+++ b/src/bfu/button.c
ab432b
@@ -115,7 +115,7 @@ buttons_width(struct widget_data *widget_data, int n,
ab432b
 }
ab432b
 
ab432b
 void
ab432b
-dlg_format_buttons(struct terminal *term,
ab432b
+dlg_format_buttons(struct terminal *term, struct dialog_data *dlg_data,
ab432b
 		   struct widget_data *widget_data, int n,
ab432b
 		   int x, int *y, int w, int *rw, enum format_align align, int format_only)
ab432b
 {
ab432b
@@ -212,7 +212,7 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
ab432b
 	}
ab432b
 
ab432b
 
ab432b
-	draw_text(term, pos->x, pos->y, BUTTON_LEFT, BUTTON_LEFT_LEN, 0, color);
ab432b
+	draw_text2(term, dlg_data, pos->x, pos->y, BUTTON_LEFT, BUTTON_LEFT_LEN, 0, color);
ab432b
 	if (len > 0) {
ab432b
 		unsigned char *text = widget_data->widget->text;
ab432b
 		int hk_pos = widget_data->widget->info.button.hotkey_pos;
ab432b
@@ -236,15 +236,15 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
ab432b
 								NULL);
ab432b
 
ab432b
 				if (hk_pos)
ab432b
-					draw_text(term, x, pos->y,
ab432b
+					draw_text2(term, dlg_data, x, pos->y,
ab432b
 						  text, hk_pos, 0, color);
ab432b
 
ab432b
-				draw_text(term, x + cells_to_hk, pos->y,
ab432b
+				draw_text2(term, dlg_data, x + cells_to_hk, pos->y,
ab432b
 					  &text[hk_pos + 1], hk_bytes,
ab432b
 					  attr, shortcut_color);
ab432b
 
ab432b
 				if (right > 1)
ab432b
-					draw_text(term, x+cells_to_hk+hk_cells,
ab432b
+					draw_text2(term, dlg_data, x+cells_to_hk+hk_cells,
ab432b
 						  pos->y,
ab432b
 						  &text[hk_pos + hk_bytes + 1],
ab432b
 						  right - 1, 0, color);
ab432b
@@ -257,11 +257,11 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
ab432b
 							 len - hk_width,
ab432b
 							 NULL);
ab432b
 
ab432b
-				draw_text(term, x, pos->y,
ab432b
+				draw_text2(term, dlg_data, x, pos->y,
ab432b
 					  text, hk_len,
ab432b
 					  attr, shortcut_color);
ab432b
 
ab432b
-				draw_text(term, x + hk_width, pos->y,
ab432b
+				draw_text2(term, dlg_data, x + hk_width, pos->y,
ab432b
 					  &text[hk_len], len_to_display,
ab432b
 					  0, color);
ab432b
 			}
ab432b
@@ -271,18 +271,18 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
ab432b
 			int right = widget_data->widget->info.button.truetextlen - hk_pos - 1;
ab432b
 
ab432b
 			if (hk_pos) {
ab432b
-				draw_text(term, x, pos->y, text, hk_pos, 0, color);
ab432b
+				draw_text2(term, dlg_data, x, pos->y, text, hk_pos, 0, color);
ab432b
 			}
ab432b
-			draw_text(term, x + hk_pos, pos->y,
ab432b
+			draw_text2(term, dlg_data, x + hk_pos, pos->y,
ab432b
 				  &text[hk_pos + 1], 1, attr, shortcut_color);
ab432b
 			if (right > 1) {
ab432b
-				draw_text(term, x + hk_pos + 1, pos->y,
ab432b
+				draw_text2(term, dlg_data, x + hk_pos + 1, pos->y,
ab432b
 					  &text[hk_pos + 2], right - 1, 0, color);
ab432b
 			}
ab432b
 
ab432b
 		} else {
ab432b
-			draw_text(term, x, pos->y, text, 1, attr, shortcut_color);
ab432b
-			draw_text(term, x + 1, pos->y, &text[1], len - 1, 0, color);
ab432b
+			draw_text2(term, dlg_data, x, pos->y, text, 1, attr, shortcut_color);
ab432b
+			draw_text2(term, dlg_data, x + 1, pos->y, &text[1], len - 1, 0, color);
ab432b
 		}
ab432b
 	}
ab432b
 #ifdef CONFIG_UTF8
ab432b
@@ -290,15 +290,15 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
ab432b
 		int text_cells = utf8_ptr2cells(widget_data->widget->text, NULL);
ab432b
 		int hk = (widget_data->widget->info.button.hotkey_pos >= 0);
ab432b
 
ab432b
-		draw_text(term, x + text_cells - hk, pos->y,
ab432b
+		draw_text2(term, dlg_data, x + text_cells - hk, pos->y,
ab432b
 			  BUTTON_RIGHT, BUTTON_RIGHT_LEN, 0, color);
ab432b
 	} else
ab432b
 #endif /* CONFIG_UTF8 */
ab432b
-		draw_text(term, x + len, pos->y, BUTTON_RIGHT,
ab432b
+		draw_text2(term, dlg_data, x + len, pos->y, BUTTON_RIGHT,
ab432b
 			  BUTTON_RIGHT_LEN, 0, color);
ab432b
 	if (sel) {
ab432b
-		set_cursor(term, x, pos->y, 1);
ab432b
-		set_window_ptr(dlg_data->win, pos->x, pos->y);
ab432b
+		set_cursor2(term, dlg_data, x, pos->y, 1);
ab432b
+		set_window_ptr2(dlg_data, dlg_data->win, pos->x, pos->y);
ab432b
 	}
ab432b
 	return EVENT_PROCESSED;
ab432b
 }
ab432b
diff --git a/src/bfu/button.h b/src/bfu/button.h
ab432b
index e6e907d..de986c8 100644
ab432b
--- a/src/bfu/button.h
ab432b
+++ b/src/bfu/button.h
ab432b
@@ -5,6 +5,7 @@
ab432b
 #include "util/align.h"
ab432b
 
ab432b
 struct dialog;
ab432b
+struct dialog_data;
ab432b
 struct terminal;
ab432b
 struct widget_data;
ab432b
 
ab432b
@@ -89,6 +90,6 @@ void add_dlg_button_do(struct dialog *dlg, unsigned char *text, int flags, widge
ab432b
 #endif
ab432b
 
ab432b
 extern const struct widget_ops button_ops;
ab432b
-void dlg_format_buttons(struct terminal *, struct widget_data *, int, int, int *, int, int *, enum format_align, int);
ab432b
+void dlg_format_buttons(struct terminal *, struct dialog_data *, struct widget_data *, int, int, int *, int, int *, enum format_align, int);
ab432b
 
ab432b
 #endif
ab432b
diff --git a/src/bfu/checkbox.c b/src/bfu/checkbox.c
ab432b
index 7ed97e0..d7c974b 100644
ab432b
--- a/src/bfu/checkbox.c
ab432b
+++ b/src/bfu/checkbox.c
ab432b
@@ -36,7 +36,7 @@ add_dlg_radio_do(struct dialog *dlg, unsigned char *text,
ab432b
 }
ab432b
 
ab432b
 void
ab432b
-dlg_format_checkbox(struct terminal *term,
ab432b
+dlg_format_checkbox(struct terminal *term, struct dialog_data *dlg_data,
ab432b
 		    struct widget_data *widget_data,
ab432b
 		    int x, int *y, int w, int *rw,
ab432b
 		    enum format_align align, int format_only)
ab432b
@@ -49,7 +49,7 @@ dlg_format_checkbox(struct terminal *term,
ab432b
 
ab432b
 	if (text && *text) {
ab432b
 		if (rw) *rw -= CHECKBOX_LS;
ab432b
-		dlg_format_text_do(term, text, x + CHECKBOX_LS, y,
ab432b
+		dlg_format_text_do(term, dlg_data, text, x + CHECKBOX_LS, y,
ab432b
 				   w - CHECKBOX_LS, rw,
ab432b
 				   get_bfu_color(term, "dialog.checkbox-label"),
ab432b
 				   align, format_only);
ab432b
@@ -78,11 +78,11 @@ display_checkbox(struct dialog_data *dlg_data, struct widget_data *widget_data)
ab432b
 	else
ab432b
 		text = widget_data->widget->info.checkbox.gid ? "( )" : "[ ]";
ab432b
 
ab432b
-	draw_text(term, pos->x, pos->y, text, CHECKBOX_LEN, 0, color);
ab432b
+	draw_text2(term, dlg_data, pos->x, pos->y, text, CHECKBOX_LEN, 0, color);
ab432b
 
ab432b
 	if (selected) {
ab432b
-		set_cursor(term, pos->x + 1, pos->y, 1);
ab432b
-		set_window_ptr(dlg_data->win, pos->x, pos->y);
ab432b
+		set_cursor2(term, dlg_data, pos->x + 1, pos->y, 1);
ab432b
+		set_window_ptr2(dlg_data, dlg_data->win, pos->x, pos->y);
ab432b
 	}
ab432b
 
ab432b
 	return EVENT_PROCESSED;
ab432b
@@ -128,7 +128,6 @@ mouse_checkbox(struct dialog_data *dlg_data, struct widget_data *widget_data)
ab432b
 static widget_handler_status_T
ab432b
 select_checkbox(struct dialog_data *dlg_data, struct widget_data *widget_data)
ab432b
 {
ab432b
-
ab432b
 	if (!widget_data->widget->info.checkbox.gid) {
ab432b
 		/* Checkbox. */
ab432b
 		int *cdata = (int *) widget_data->cdata;
ab432b
@@ -159,8 +158,8 @@ select_checkbox(struct dialog_data *dlg_data, struct widget_data *widget_data)
ab432b
 		}
ab432b
 		widget_data->info.checkbox.checked = 1;
ab432b
 	}
ab432b
-
ab432b
 	display_widget(dlg_data, widget_data);
ab432b
+
ab432b
 	return EVENT_PROCESSED;
ab432b
 }
ab432b
 
ab432b
diff --git a/src/bfu/checkbox.h b/src/bfu/checkbox.h
ab432b
index 573f1d2..b4e65ce 100644
ab432b
--- a/src/bfu/checkbox.h
ab432b
+++ b/src/bfu/checkbox.h
ab432b
@@ -2,6 +2,7 @@
ab432b
 #define EL__BFU_CHECKBOX_H
ab432b
 
ab432b
 struct dialog;
ab432b
+struct dialog_data;
ab432b
 struct terminal;
ab432b
 struct widget_data;
ab432b
 
ab432b
@@ -30,7 +31,7 @@ void add_dlg_radio_do(struct dialog *dlg, unsigned char *text, int groupid, int
ab432b
 extern const struct widget_ops checkbox_ops;
ab432b
 
ab432b
 void
ab432b
-dlg_format_checkbox(struct terminal *term,
ab432b
+dlg_format_checkbox(struct terminal *term, struct dialog_data *dlg_data,
ab432b
 		    struct widget_data *widget_data,
ab432b
 		    int x, int *y, int w, int *rw,
ab432b
 		    enum format_align align, int format_only);
ab432b
diff --git a/src/bfu/dialog.c b/src/bfu/dialog.c
ab432b
index b2df9f8..414283f 100644
ab432b
--- a/src/bfu/dialog.c
ab432b
+++ b/src/bfu/dialog.c
ab432b
@@ -82,20 +82,18 @@ redraw_dialog(struct dialog_data *dlg_data, int layout)
ab432b
 	}
ab432b
 
ab432b
 	if (!dlg_data->dlg->layout.only_widgets) {
ab432b
-		struct box box;
ab432b
-
ab432b
-		set_box(&box,
ab432b
+		set_box(&dlg_data->real_box,
ab432b
 			dlg_data->box.x + (DIALOG_LEFT_BORDER + 1),
ab432b
 			dlg_data->box.y + (DIALOG_TOP_BORDER + 1),
ab432b
 			dlg_data->box.width - 2 * (DIALOG_LEFT_BORDER + 1),
ab432b
 			dlg_data->box.height - 2 * (DIALOG_TOP_BORDER + 1));
ab432b
 
ab432b
-		draw_border(term, &box, get_bfu_color(term, "dialog.frame"), DIALOG_FRAME);
ab432b
+		draw_border(term, &dlg_data->real_box, get_bfu_color(term, "dialog.frame"), DIALOG_FRAME);
ab432b
 
ab432b
 		assert(dlg_data->dlg->title);
ab432b
 
ab432b
 		title_color = get_bfu_color(term, "dialog.title");
ab432b
-		if (title_color && box.width > 2) {
ab432b
+		if (title_color && dlg_data->real_box.width > 2) {
ab432b
 			unsigned char *title = dlg_data->dlg->title;
ab432b
 			int titlelen = strlen(title);
ab432b
 			int titlecells = titlelen;
ab432b
@@ -107,7 +105,7 @@ redraw_dialog(struct dialog_data *dlg_data, int layout)
ab432b
 							    &title[titlelen]);
ab432b
 #endif /* CONFIG_UTF8 */
ab432b
 
ab432b
-			titlecells = int_min(box.width - 2, titlecells);
ab432b
+			titlecells = int_min(dlg_data->real_box.width - 2, titlecells);
ab432b
 
ab432b
 #ifdef CONFIG_UTF8
ab432b
 			if (term->utf8_cp)
ab432b
@@ -115,13 +113,13 @@ redraw_dialog(struct dialog_data *dlg_data, int layout)
ab432b
 							    NULL);
ab432b
 #endif /* CONFIG_UTF8 */
ab432b
 
ab432b
-			x = (box.width - titlecells) / 2 + box.x;
ab432b
-			y = box.y - 1;
ab432b
+			x = (dlg_data->real_box.width - titlecells) / 2 + dlg_data->real_box.x;
ab432b
+			y = dlg_data->real_box.y - 1;
ab432b
 
ab432b
 
ab432b
-			draw_text(term, x - 1, y, " ", 1, 0, title_color);
ab432b
-			draw_text(term, x, y, title, titlelen, 0, title_color);
ab432b
-			draw_text(term, x + titlecells, y, " ", 1, 0,
ab432b
+			draw_text2(term, dlg_data, x - 1, y, " ", 1, 0, title_color);
ab432b
+			draw_text2(term, dlg_data, x, y, title, titlelen, 0, title_color);
ab432b
+			draw_text2(term, dlg_data, x + titlecells, y, " ", 1, 0,
ab432b
 				  title_color);
ab432b
 		}
ab432b
 	}
ab432b
@@ -181,6 +179,23 @@ init_widget(struct dialog_data *dlg_data, int i)
ab432b
 	return widget_data;
ab432b
 }
ab432b
 
ab432b
+static int
ab432b
+check_range(struct dialog_data *dlg_data, struct widget_data *widget_data)
ab432b
+{
ab432b
+	if (!dlg_data->dlg->layout.only_widgets) {
ab432b
+		struct box *box = &widget_data->box;
ab432b
+		struct box *dlgbox = &dlg_data->real_box;
ab432b
+		int y = box->y - dlgbox->y;
ab432b
+
ab432b
+		if ((y < dlg_data->y) || (y >= dlg_data->y + dlgbox->height)) {
ab432b
+			dlg_data->y = y / dlgbox->height  * dlgbox->height;
ab432b
+			redraw_dialog(dlg_data, 0);
ab432b
+			return 1;
ab432b
+		}
ab432b
+	}
ab432b
+	return 0;
ab432b
+}
ab432b
+
ab432b
 void
ab432b
 select_widget(struct dialog_data *dlg_data, struct widget_data *widget_data)
ab432b
 {
ab432b
@@ -190,6 +205,9 @@ select_widget(struct dialog_data *dlg_data, struct widget_data *widget_data)
ab432b
 
ab432b
 	dlg_data->selected_widget_id = widget_data - dlg_data->widgets_data;
ab432b
 
ab432b
+	if (check_range(dlg_data, widget_data))
ab432b
+		return;
ab432b
+
ab432b
 	display_widget(dlg_data, previously_selected_widget);
ab432b
 	display_widget(dlg_data, widget_data);
ab432b
 }
ab432b
@@ -228,6 +246,11 @@ cycle_widget_focus(struct dialog_data *dlg_data, int direction)
ab432b
 	} while (!widget_is_focusable(selected_widget(dlg_data))
ab432b
 		 && dlg_data->selected_widget_id != prev_selected);
ab432b
 
ab432b
+	if (check_range(dlg_data, selected_widget(dlg_data))) {
ab432b
+		redraw_from_window(dlg_data->win);
ab432b
+		return;
ab432b
+	}
ab432b
+
ab432b
 	display_widget(dlg_data, previously_selected_widget);
ab432b
 	display_widget(dlg_data, selected_widget(dlg_data));
ab432b
 	redraw_from_window(dlg_data->win);
ab432b
@@ -238,6 +261,7 @@ dialog_ev_init(struct dialog_data *dlg_data)
ab432b
 {
ab432b
 	int i;
ab432b
 
ab432b
+	dlg_data->y = 0;
ab432b
 	/* TODO: foreachback_widget() */
ab432b
 	for (i = dlg_data->number_of_widgets - 1; i >= 0; i--) {
ab432b
 		struct widget_data *widget_data;
ab432b
@@ -421,6 +445,7 @@ dialog_ev_abort(struct dialog_data *dlg_data)
ab432b
 	}
ab432b
 
ab432b
 	freeml(dlg_data->ml);
ab432b
+	dlg_data->y = 0;
ab432b
 }
ab432b
 
ab432b
 /* TODO: use EVENT_PROCESSED/EVENT_NOT_PROCESSED. */
ab432b
@@ -554,17 +579,17 @@ format_widgets(struct terminal *term, struct dialog_data *dlg_data,
ab432b
 		switch (wdata->widget->type) {
ab432b
 		case WIDGET_FIELD_PASS:
ab432b
 		case WIDGET_FIELD:
ab432b
-			dlg_format_field(term, wdata, x, y, w, rw, ALIGN_LEFT,
ab432b
+			dlg_format_field(term, dlg_data, wdata, x, y, w, rw, ALIGN_LEFT,
ab432b
 					 format_only);
ab432b
 			break;
ab432b
 
ab432b
 		case WIDGET_LISTBOX:
ab432b
-			dlg_format_listbox(term, wdata, x, y, w, h, rw,
ab432b
+			dlg_format_listbox(term, dlg_data, wdata, x, y, w, h, rw,
ab432b
 					   ALIGN_LEFT, format_only);
ab432b
 			break;
ab432b
 
ab432b
 		case WIDGET_TEXT:
ab432b
-			dlg_format_text(term, wdata, x, y, w, rw, h,
ab432b
+			dlg_format_text(term, dlg_data, wdata, x, y, w, rw, h,
ab432b
 					format_only);
ab432b
 			break;
ab432b
 
ab432b
@@ -583,7 +608,7 @@ format_widgets(struct terminal *term, struct dialog_data *dlg_data,
ab432b
 						break;
ab432b
 				}
ab432b
 
ab432b
-				dlg_format_group(term, wdata, size, x, y, w, rw,
ab432b
+				dlg_format_group(term, dlg_data, wdata, size, x, y, w, rw,
ab432b
 						 format_only);
ab432b
 				wdata += size - 1;
ab432b
 
ab432b
@@ -591,7 +616,7 @@ format_widgets(struct terminal *term, struct dialog_data *dlg_data,
ab432b
 
ab432b
 				/* No horizontal space between checkboxes belonging to
ab432b
 				 * the same group. */
ab432b
-				dlg_format_checkbox(term, wdata, x, y, w, rw,
ab432b
+				dlg_format_checkbox(term, dlg_data, wdata, x, y, w, rw,
ab432b
 						    ALIGN_LEFT, format_only);
ab432b
 				if (widgets > 1
ab432b
 				    && group == widget_has_group(&wdata[1]))
ab432b
@@ -603,7 +628,7 @@ format_widgets(struct terminal *term, struct dialog_data *dlg_data,
ab432b
 		/* We assume that the buttons are all stuffed at the very end
ab432b
 		 * of the dialog. */
ab432b
 		case WIDGET_BUTTON:
ab432b
-			dlg_format_buttons(term, wdata, widgets,
ab432b
+			dlg_format_buttons(term, dlg_data, wdata, widgets,
ab432b
 					   x, y, w, rw, ALIGN_CENTER, format_only);
ab432b
 			return;
ab432b
 		}
ab432b
diff --git a/src/bfu/dialog.h b/src/bfu/dialog.h
ab432b
index b0cde3b..bec914c 100644
ab432b
--- a/src/bfu/dialog.h
ab432b
+++ b/src/bfu/dialog.h
ab432b
@@ -100,6 +100,8 @@ struct dialog_data {
ab432b
 	struct memory_list *ml;
ab432b
 
ab432b
 	struct box box;
ab432b
+	struct box real_box;
ab432b
+	int y;
ab432b
 	int number_of_widgets;
ab432b
 	int selected_widget_id;
ab432b
 	struct term_event *term_event;
ab432b
diff --git a/src/bfu/group.c b/src/bfu/group.c
ab432b
index cc4c6d8..15bd827 100644
ab432b
--- a/src/bfu/group.c
ab432b
+++ b/src/bfu/group.c
ab432b
@@ -20,7 +20,7 @@
ab432b
 #define CHECKBOX_LEN 3  /* "[X]" or "(X)" */
ab432b
 
ab432b
 void
ab432b
-dlg_format_group(struct terminal *term,
ab432b
+dlg_format_group(struct terminal *term, struct dialog_data *dlg_data,
ab432b
 		 struct widget_data *widget_data,
ab432b
 		 int n, int x, int *y, int w, int *rw, int format_only)
ab432b
 {
ab432b
@@ -87,14 +87,14 @@ dlg_format_group(struct terminal *term,
ab432b
 								text,
ab432b
 								label_length,
ab432b
 								NULL);
ab432b
-						draw_text(term, xpos + width
ab432b
+						draw_text2(term, dlg_data, xpos + width
ab432b
 								+ label_padding,
ab432b
 							  *y, text, lb, 0,
ab432b
 							  color);
ab432b
 					} else
ab432b
 #endif /* CONFIG_UTF8 */
ab432b
 					{
ab432b
-						draw_text(term, xpos + width
ab432b
+						draw_text2(term, dlg_data, xpos + width
ab432b
 								+ label_padding,
ab432b
 							  *y, text,
ab432b
 							  label_length, 0,
ab432b
@@ -113,12 +113,12 @@ dlg_format_group(struct terminal *term,
ab432b
 								text,
ab432b
 								label_length,
ab432b
 								NULL);
ab432b
-						draw_text(term, xpos, *y,
ab432b
+						draw_text2(term, dlg_data, xpos, *y,
ab432b
 							  text, lb, 0, color);
ab432b
 					} else
ab432b
 #endif /* CONFIG_UTF8 */
ab432b
 					{
ab432b
-						draw_text(term, xpos, *y,
ab432b
+						draw_text2(term, dlg_data, xpos, *y,
ab432b
 							  text, label_length,
ab432b
 							  0, color);
ab432b
 					}
ab432b
@@ -155,11 +155,11 @@ group_layouter(struct dialog_data *dlg_data)
ab432b
 #endif /* CONFIG_UTF8 */
ab432b
 		rw = int_min(w, strlen(dlg_data->dlg->title));
ab432b
 
ab432b
-	dlg_format_group(term, dlg_data->widgets_data, n,
ab432b
+	dlg_format_group(term, dlg_data, dlg_data->widgets_data, n,
ab432b
 			 0, &y, w, &rw, 1);
ab432b
 
ab432b
 	y++;
ab432b
-	dlg_format_buttons(term, dlg_data->widgets_data + n, 2, 0, &y, w,
ab432b
+	dlg_format_buttons(term, dlg_data, dlg_data->widgets_data + n, 2, 0, &y, w,
ab432b
 			   &rw, ALIGN_CENTER, 1);
ab432b
 
ab432b
 	w = rw;
ab432b
@@ -167,10 +167,10 @@ group_layouter(struct dialog_data *dlg_data)
ab432b
 	draw_dialog(dlg_data, w, y);
ab432b
 
ab432b
 	y = dlg_data->box.y + DIALOG_TB + 1;
ab432b
-	dlg_format_group(term, dlg_data->widgets_data, n,
ab432b
+	dlg_format_group(term, dlg_data, dlg_data->widgets_data, n,
ab432b
 			 dlg_data->box.x + DIALOG_LB, &y, w, NULL, 0);
ab432b
 
ab432b
 	y++;
ab432b
-	dlg_format_buttons(term, dlg_data->widgets_data + n, 2,
ab432b
+	dlg_format_buttons(term, dlg_data, dlg_data->widgets_data + n, 2,
ab432b
 			   dlg_data->box.x + DIALOG_LB, &y, w, &rw, ALIGN_CENTER, 0);
ab432b
 }
ab432b
diff --git a/src/bfu/group.h b/src/bfu/group.h
ab432b
index 0de645d..9b92c2a 100644
ab432b
--- a/src/bfu/group.h
ab432b
+++ b/src/bfu/group.h
ab432b
@@ -5,7 +5,7 @@ struct dialog_data;
ab432b
 struct terminal;
ab432b
 struct widget_data;
ab432b
 
ab432b
-void dlg_format_group(struct terminal *term,
ab432b
+void dlg_format_group(struct terminal *term, struct dialog_data *dlg_data,
ab432b
 		 struct widget_data *widget_data,
ab432b
 		 int n, int x, int *y, int w, int *rw, int format_only);
ab432b
 
ab432b
diff --git a/src/bfu/inpfield.c b/src/bfu/inpfield.c
ab432b
index 4c0dcd2..0a9c63e 100644
ab432b
--- a/src/bfu/inpfield.c
ab432b
+++ b/src/bfu/inpfield.c
ab432b
@@ -103,7 +103,7 @@ check_nonempty(struct dialog_data *dlg_data, struct widget_data *widget_data)
ab432b
 }
ab432b
 
ab432b
 void
ab432b
-dlg_format_field(struct terminal *term,
ab432b
+dlg_format_field(struct terminal *term, struct dialog_data *dlg_data,
ab432b
 		 struct widget_data *widget_data,
ab432b
 		 int x, int *y, int w, int *rw, enum format_align align, int format_only)
ab432b
 {
ab432b
@@ -132,7 +132,7 @@ dlg_format_field(struct terminal *term,
ab432b
 	if (label && *label) {
ab432b
 		if (!format_only) text_color = get_bfu_color(term, "dialog.text");
ab432b
 
ab432b
-		dlg_format_text_do(term, label, x, y, w, rw, text_color, ALIGN_LEFT, format_only);
ab432b
+		dlg_format_text_do(term, dlg_data, label, x, y, w, rw, text_color, ALIGN_LEFT, format_only);
ab432b
 	}
ab432b
 
ab432b
 	/* XXX: We want the field and label on the same line if the terminal
ab432b
@@ -140,7 +140,7 @@ dlg_format_field(struct terminal *term,
ab432b
 	if (label && *label && float_label) {
ab432b
 		if (widget_data->widget->info.field.flags & INPFIELD_FLOAT) {
ab432b
 			(*y) -= INPUTFIELD_HEIGHT;
ab432b
-			dlg_format_text_do(term, INPUTFIELD_FLOAT_SEPARATOR,
ab432b
+			dlg_format_text_do(term, dlg_data, INPUTFIELD_FLOAT_SEPARATOR,
ab432b
 					   x + label_width, y, w, rw,
ab432b
 					   text_color, ALIGN_LEFT, format_only);
ab432b
 			w -= INPUTFIELD_FLOAT_SEPARATOR_LEN + INPUTFIELD_FLOATLABEL_PADDING;
ab432b
@@ -312,7 +312,7 @@ display_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data,
ab432b
 			if (term->utf8_cp)
ab432b
 				w = utf8_cells2bytes(text, w, NULL);
ab432b
 #endif /* CONFIG_UTF8 */
ab432b
-			draw_text(term, widget_data->box.x, widget_data->box.y,
ab432b
+			draw_text2(term, dlg_data, widget_data->box.x, widget_data->box.y,
ab432b
 				  text, w, 0, color);
ab432b
 		} else {
ab432b
 			struct box box;
ab432b
@@ -763,7 +763,7 @@ input_line_layouter(struct dialog_data *dlg_data)
ab432b
 		- ses->status.show_status_bar
ab432b
 		- ses->status.show_tabs_bar;
ab432b
 
ab432b
-	dlg_format_field(win->term, dlg_data->widgets_data, 0,
ab432b
+	dlg_format_field(win->term, dlg_data, dlg_data->widgets_data, 0,
ab432b
 			 &y, win->term->width, NULL, ALIGN_LEFT, 0);
ab432b
 }
ab432b
 
ab432b
diff --git a/src/bfu/inpfield.h b/src/bfu/inpfield.h
ab432b
index d45a902..fb2270e 100644
ab432b
--- a/src/bfu/inpfield.h
ab432b
+++ b/src/bfu/inpfield.h
ab432b
@@ -62,7 +62,7 @@ extern const struct widget_ops field_pass_ops;
ab432b
 widget_handler_status_T check_number(struct dialog_data *, struct widget_data *);
ab432b
 widget_handler_status_T check_nonempty(struct dialog_data *, struct widget_data *);
ab432b
 
ab432b
-void dlg_format_field(struct terminal *, struct widget_data *, int, int *, int, int *, enum format_align, int format_only);
ab432b
+void dlg_format_field(struct terminal *, struct dialog_data *, struct widget_data *, int, int *, int, int *, enum format_align, int format_only);
ab432b
 
ab432b
 void input_field(struct terminal *, struct memory_list *, int, unsigned char *,
ab432b
 		 unsigned char *, unsigned char *, unsigned char *, void *,
ab432b
diff --git a/src/bfu/listbox.c b/src/bfu/listbox.c
ab432b
index 7ec1b66..e4de12f 100644
ab432b
--- a/src/bfu/listbox.c
ab432b
+++ b/src/bfu/listbox.c
ab432b
@@ -41,7 +41,8 @@ get_listbox_widget_data(struct widget_data *widget_data)
ab432b
 
ab432b
 /* Layout for generic boxes */
ab432b
 void
ab432b
-dlg_format_listbox(struct terminal *term, struct widget_data *widget_data,
ab432b
+dlg_format_listbox(struct terminal *term, struct dialog_data *dlg_data,
ab432b
+		   struct widget_data *widget_data,
ab432b
 	           int x, int *y, int w, int max_height, int *rw,
ab432b
 	           enum format_align align, int format_only)
ab432b
 {
ab432b
diff --git a/src/bfu/listbox.h b/src/bfu/listbox.h
ab432b
index c3599e5..63b8be4 100644
ab432b
--- a/src/bfu/listbox.h
ab432b
+++ b/src/bfu/listbox.h
ab432b
@@ -133,7 +133,7 @@ struct listbox_item {
ab432b
 
ab432b
 extern const struct widget_ops listbox_ops;
ab432b
 
ab432b
-void dlg_format_listbox(struct terminal *, struct widget_data *, int, int *, int, int, int *, enum format_align, int format_only);
ab432b
+void dlg_format_listbox(struct terminal *, struct dialog_data *, struct widget_data *, int, int *, int, int, int *, enum format_align, int format_only);
ab432b
 
ab432b
 struct listbox_item *traverse_listbox_items_list(struct listbox_item *, struct listbox_data *, int, int, int (*)(struct listbox_item *, void *, int *), void *);
ab432b
 
ab432b
diff --git a/src/bfu/text.c b/src/bfu/text.c
ab432b
index e8be019..3d2895e 100644
ab432b
--- a/src/bfu/text.c
ab432b
+++ b/src/bfu/text.c
ab432b
@@ -211,7 +211,8 @@ split_lines(struct widget_data *widget_data, int max_width)
ab432b
 
ab432b
 /* Format text according to dialog box and alignment. */
ab432b
 void
ab432b
-dlg_format_text_do(struct terminal *term, unsigned char *text,
ab432b
+dlg_format_text_do(struct terminal *term, struct dialog_data *dlg_data,
ab432b
+		unsigned char *text,
ab432b
 		int x, int *y, int width, int *real_width,
ab432b
 		struct color_pair *color, enum format_align align,
ab432b
 		int format_only)
ab432b
@@ -255,12 +256,13 @@ dlg_format_text_do(struct terminal *term, unsigned char *text,
ab432b
 
ab432b
 		assert(cells <= width && shift < width);
ab432b
 
ab432b
-		draw_text(term, x + shift, *y, text, line_width, 0, color);
ab432b
+		draw_text2(term, dlg_data, x + shift, *y, text, line_width, 0, color);
ab432b
 	}
ab432b
 }
ab432b
 
ab432b
 void
ab432b
-dlg_format_text(struct terminal *term, struct widget_data *widget_data,
ab432b
+dlg_format_text(struct terminal *term, struct dialog_data *dlg_data,
ab432b
+		struct widget_data *widget_data,
ab432b
 		int x, int *y, int width, int *real_width, int max_height,
ab432b
 		int format_only)
ab432b
 {
ab432b
@@ -335,7 +337,7 @@ dlg_format_text(struct terminal *term, struct widget_data *widget_data,
ab432b
 		widget_data->info.text.current = 0;
ab432b
 	}
ab432b
 
ab432b
-	dlg_format_text_do(term, text,
ab432b
+	dlg_format_text_do(term, dlg_data, text,
ab432b
 		x, y, width, real_width,
ab432b
 		get_bfu_color(term, "dialog.text"),
ab432b
 		widget_data->widget->info.text.align, format_only);
ab432b
@@ -395,8 +397,8 @@ display_text(struct dialog_data *dlg_data, struct widget_data *widget_data)
ab432b
 
ab432b
 	/* Hope this is at least a bit reasonable. Set cursor
ab432b
 	 * and window pointer to start of the first text line. */
ab432b
-	set_cursor(win->term, widget_data->box.x, widget_data->box.y, 1);
ab432b
-	set_window_ptr(win, widget_data->box.x, widget_data->box.y);
ab432b
+	set_cursor2(win->term, dlg_data, widget_data->box.x, widget_data->box.y, 1);
ab432b
+	set_window_ptr2(dlg_data, win, widget_data->box.x, widget_data->box.y);
ab432b
 
ab432b
 	return EVENT_PROCESSED;
ab432b
 }
ab432b
@@ -423,7 +425,7 @@ format_and_display_text(struct widget_data *widget_data,
ab432b
 	draw_box(term, &widget_data->box, ' ', 0,
ab432b
 		 get_bfu_color(term, "dialog.generic"));
ab432b
 
ab432b
-	dlg_format_text(term, widget_data,
ab432b
+	dlg_format_text(term, dlg_data, widget_data,
ab432b
 			widget_data->box.x, &y, widget_data->box.width, NULL,
ab432b
 			height, 0);
ab432b
 
ab432b
diff --git a/src/bfu/text.h b/src/bfu/text.h
ab432b
index 8dd3365..b181c1a 100644
ab432b
--- a/src/bfu/text.h
ab432b
+++ b/src/bfu/text.h
ab432b
@@ -4,6 +4,7 @@
ab432b
 #include "util/color.h"
ab432b
 
ab432b
 struct dialog;
ab432b
+struct dialog_data;
ab432b
 struct terminal;
ab432b
 
ab432b
 struct widget_info_text	{
ab432b
@@ -45,12 +46,12 @@ void add_dlg_text(struct dialog *dlg, unsigned char *text,
ab432b
 		  enum format_align align, int bottom_pad);
ab432b
 
ab432b
 extern const struct widget_ops text_ops;
ab432b
-void dlg_format_text_do(struct terminal *term,
ab432b
+void dlg_format_text_do(struct terminal *term, struct dialog_data *dlg_data,
ab432b
 		    unsigned char *text, int x, int *y, int w, int *rw,
ab432b
 		    struct color_pair *scolor, enum format_align align, int format_only);
ab432b
 
ab432b
 void
ab432b
-dlg_format_text(struct terminal *term, struct widget_data *widget_data,
ab432b
+dlg_format_text(struct terminal *term, struct dialog_data *dlg_data, struct widget_data *widget_data,
ab432b
 		int x, int *y, int dlg_width, int *real_width, int height, int format_only);
ab432b
 
ab432b
 #define text_is_scrollable(widget_data) \
ab432b
diff --git a/src/dialogs/download.c b/src/dialogs/download.c
ab432b
index 0116578..b90f047 100644
ab432b
--- a/src/dialogs/download.c
ab432b
+++ b/src/dialogs/download.c
ab432b
@@ -157,7 +157,7 @@ download_dialog_layouter(struct dialog_data *dlg_data)
ab432b
 		int_lower_bound(&w, DOWN_DLG_MIN);
ab432b
 	}
ab432b
 
ab432b
-	dlg_format_text_do(term, url, 0, &y, w, &rw,
ab432b
+	dlg_format_text_do(term, dlg_data, url, 0, &y, w, &rw,
ab432b
 			dialog_text_color, ALIGN_LEFT, 1);
ab432b
 
ab432b
 	y++;
ab432b
@@ -166,11 +166,11 @@ download_dialog_layouter(struct dialog_data *dlg_data)
ab432b
 #if CONFIG_BITTORRENT
ab432b
 	if (bittorrent) y += 2;
ab432b
 #endif
ab432b
-	dlg_format_text_do(term, msg, 0, &y, w, &rw,
ab432b
+	dlg_format_text_do(term, dlg_data, msg, 0, &y, w, &rw,
ab432b
 			dialog_text_color, ALIGN_LEFT, 1);
ab432b
 
ab432b
 	y++;
ab432b
-	dlg_format_buttons(term, dlg_data->widgets_data,
ab432b
+	dlg_format_buttons(term, dlg_data, dlg_data->widgets_data,
ab432b
 			   dlg_data->number_of_widgets, 0, &y, w,
ab432b
 			   &rw, ALIGN_CENTER, 1);
ab432b
 
ab432b
@@ -190,7 +190,7 @@ download_dialog_layouter(struct dialog_data *dlg_data)
ab432b
 
ab432b
 	y = dlg_data->box.y + DIALOG_TB + 1;
ab432b
 	x = dlg_data->box.x + DIALOG_LB;
ab432b
-	dlg_format_text_do(term, url, x, &y, w, NULL,
ab432b
+	dlg_format_text_do(term, dlg_data, url, x, &y, w, NULL,
ab432b
 			dialog_text_color, ALIGN_LEFT, 0);
ab432b
 
ab432b
 	if (show_meter) {
ab432b
@@ -207,11 +207,11 @@ download_dialog_layouter(struct dialog_data *dlg_data)
ab432b
 	}
ab432b
 #endif
ab432b
 	y++;
ab432b
-	dlg_format_text_do(term, msg, x, &y, w, NULL,
ab432b
+	dlg_format_text_do(term, dlg_data, msg, x, &y, w, NULL,
ab432b
 			dialog_text_color, ALIGN_LEFT, 0);
ab432b
 
ab432b
 	y++;
ab432b
-	dlg_format_buttons(term, dlg_data->widgets_data,
ab432b
+	dlg_format_buttons(term, dlg_data, dlg_data->widgets_data,
ab432b
 			   dlg_data->number_of_widgets, x, &y, w,
ab432b
 			   NULL, ALIGN_CENTER, 0);
ab432b
 
ab432b
diff --git a/src/terminal/draw.c b/src/terminal/draw.c
ab432b
index b3b3706..267d9ac 100644
ab432b
--- a/src/terminal/draw.c
ab432b
+++ b/src/terminal/draw.c
ab432b
@@ -7,6 +7,7 @@
ab432b
 
ab432b
 #include "elinks.h"
ab432b
 
ab432b
+#include "bfu/dialog.h"
ab432b
 #include "config/options.h"
ab432b
 #include "intl/charsets.h"
ab432b
 #include "terminal/color.h"
ab432b
@@ -559,6 +560,23 @@ draw_text(struct terminal *term, int x, int y,
ab432b
 }
ab432b
 
ab432b
 void
ab432b
+draw_text2(struct terminal *term, struct dialog_data *dlg_data, int x, int y,
ab432b
+	  unsigned char *text, int length,
ab432b
+	  enum screen_char_attr attr, struct color_pair *color)
ab432b
+{
ab432b
+	struct box *box = &dlg_data->real_box;
ab432b
+
ab432b
+	if (box->height) {
ab432b
+		int y_max = box->y + box->height;
ab432b
+
ab432b
+		y -= dlg_data->y;
ab432b
+		if (y < box->y || y >= y_max) return;
ab432b
+	}
ab432b
+	draw_text(term, x, y, text, length, attr, color);
ab432b
+}
ab432b
+
ab432b
+
ab432b
+void
ab432b
 set_cursor(struct terminal *term, int x, int y, int blockable)
ab432b
 {
ab432b
 	assert(term && term->screen);
ab432b
@@ -580,6 +598,24 @@ set_cursor(struct terminal *term, int x, int y, int blockable)
ab432b
 }
ab432b
 
ab432b
 void
ab432b
+set_cursor2(struct terminal *term, struct dialog_data *dlg_data, int x, int y, int blockable)
ab432b
+{
ab432b
+	struct box *box = &dlg_data->real_box;
ab432b
+
ab432b
+	assert(term && term->screen);
ab432b
+	if_assert_failed return;
ab432b
+
ab432b
+	if (box->height) {
ab432b
+		int y_max = box->y + box->height;
ab432b
+
ab432b
+		y -= dlg_data->y;
ab432b
+		if (y < box->y || y >= y_max) return;
ab432b
+	}
ab432b
+	set_cursor(term, x, y, blockable);
ab432b
+}
ab432b
+
ab432b
+
ab432b
+void
ab432b
 clear_terminal(struct terminal *term)
ab432b
 {
ab432b
 	struct box box;
ab432b
diff --git a/src/terminal/draw.h b/src/terminal/draw.h
ab432b
index 6dcd31a..20fba4e 100644
ab432b
--- a/src/terminal/draw.h
ab432b
+++ b/src/terminal/draw.h
ab432b
@@ -4,6 +4,7 @@
ab432b
 #include "intl/charsets.h" /* unicode_val_T */
ab432b
 
ab432b
 struct color_pair;
ab432b
+struct dialog_data;
ab432b
 struct box;
ab432b
 struct terminal;
ab432b
 
ab432b
@@ -280,6 +281,12 @@ void draw_text(struct terminal *term, int x, int y,
ab432b
 	       enum screen_char_attr attr,
ab432b
 	       struct color_pair *color);
ab432b
 
ab432b
+/** Draws text for dialogs. */
ab432b
+void draw_text2(struct terminal *term, struct dialog_data *dlg_data, int x, int y,
ab432b
+	  unsigned char *text, int length,
ab432b
+	  enum screen_char_attr attr, struct color_pair *color);
ab432b
+
ab432b
+
ab432b
 /** Draws @a length chars from @a line on the screen.  */
ab432b
 void draw_line(struct terminal *term, int x, int y, int length,
ab432b
 	       struct screen_char *line);
ab432b
@@ -289,6 +296,9 @@ void draw_line(struct terminal *term, int x, int y, int length,
ab432b
  * bottom right corner of the screen. */
ab432b
 void set_cursor(struct terminal *term, int x, int y, int blockable);
ab432b
 
ab432b
+/* set cursor for dialogs */
ab432b
+void set_cursor2(struct terminal *term, struct dialog_data *dlg_data, int x, int y, int blockable);
ab432b
+
ab432b
 /** Blanks the screen. */
ab432b
 void clear_terminal(struct terminal *);
ab432b
 
ab432b
diff --git a/src/terminal/window.c b/src/terminal/window.c
ab432b
index 9ac7191..934207d 100644
ab432b
--- a/src/terminal/window.c
ab432b
+++ b/src/terminal/window.c
ab432b
@@ -7,6 +7,7 @@
ab432b
 
ab432b
 #include "elinks.h"
ab432b
 
ab432b
+#include "bfu/dialog.h"
ab432b
 #include "bfu/menu.h"
ab432b
 #include "terminal/event.h"
ab432b
 #include "terminal/tab.h"
ab432b
@@ -227,3 +228,17 @@ would_window_receive_keypresses(const struct window *win)
ab432b
 	return 1;
ab432b
 }
ab432b
 #endif	/* CONFIG_SCRIPTING_SPIDERMONKEY */
ab432b
+
ab432b
+void
ab432b
+set_window_ptr2(struct dialog_data *dlg_data, struct window *window, int x, int y)
ab432b
+{
ab432b
+	struct box *box = &dlg_data->real_box;
ab432b
+
ab432b
+	if (box->height) {
ab432b
+		int y_max = box->y + box->height;
ab432b
+
ab432b
+		y -= dlg_data->y;
ab432b
+		if (y < box->y || y >= y_max) return;
ab432b
+	}
ab432b
+	set_window_ptr(window, x, y);
ab432b
+}
ab432b
diff --git a/src/terminal/window.h b/src/terminal/window.h
ab432b
index 8bb329d..c8250ac 100644
ab432b
--- a/src/terminal/window.h
ab432b
+++ b/src/terminal/window.h
ab432b
@@ -3,6 +3,7 @@
ab432b
 
ab432b
 #include "util/lists.h"
ab432b
 
ab432b
+struct dialog_data;
ab432b
 struct term_event;
ab432b
 struct terminal;
ab432b
 struct window;
ab432b
@@ -73,6 +74,7 @@ void add_window(struct terminal *, window_handler_T, void *);
ab432b
 void delete_window(struct window *);
ab432b
 void delete_window_ev(struct window *, struct term_event *ev);
ab432b
 #define set_window_ptr(window, x_, y_) do { (window)->x = (x_); (window)->y = (y_); } while (0)
ab432b
+void set_window_ptr2(struct dialog_data *dlg_data, struct window *window, int x, int y);
ab432b
 void get_parent_ptr(struct window *, int *, int *);
ab432b
 
ab432b
 void add_empty_window(struct terminal *, void (*)(void *), void *);
ab432b
-- 
ab432b
1.7.1
ab432b