[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#809739: marked as done (cdebconf: text frontend: having a way to scroll among choices)



Your message dated Sun, 07 Feb 2016 12:52:50 +0000
with message-id <E1aSOpe-0008WJ-Ud@franck.debian.org>
and subject line Bug#809739: fixed in yoshimi 1.3.8.2-1
has caused the Debian Bug report #809739,
regarding cdebconf: text frontend: having a way to scroll among choices
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
809739: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=809739
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Source: cdebconf
Version: 0.201
Severity: normal
Tags: patch

Hello,

In the text frontend, when there are more choices than can fit in the
screen, the question and the first choices get lost in the backlog.
When lucky, the available backscroll is long enough, but that's not
guaranteed, notably with the every-increasing list of supported
languages :)

I have come up with some changes in the text frontend to make it only
display what can fit on the screen and provide shortcuts to circulate
among the list of available choices.  I have attached the patch, and put
a sample built image on
https://people.debian.org/~sthibault/tmp/mini-cdebconf-text-choices.iso
(select the "speech" boot menu entry to easy select the text frontend).

The idea is to make all functions that print text return the number of
printed lines, so that the printlist() function can be given the number
of lines it is allowed to print.  That works quite nicely.

For now I have used '(' and ')' as shortcuts for previous and next
choices, probably better shortcuts could be found ('<' is already
taken).  Also the banners "Other/Previous/Next choices are available
with" can probably be improved.

How do debian-boot people think about this?

Samuel

-- System Information:
Debian Release: stretch/sid
  APT prefers unstable-debug
  APT policy: (500, 'unstable-debug'), (500, 'oldoldstable'), (500, 'buildd-unstable'), (500, 'unstable'), (500, 'testing'), (500, 'stable'), (500, 'oldstable'), (1, 'experimental-debug'), (1, 'buildd-experimental'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.3.0-1-amd64 (SMP w/4 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

-- 
Samuel
In mutt, type cthis
Dans mutt, taper cceci
diff --git a/src/modules/frontend/text/cdebconf_text.h b/src/modules/frontend/text/cdebconf_text.h
index 7f7088d..a4ce753 100644
--- a/src/modules/frontend/text/cdebconf_text.h
+++ b/src/modules/frontend/text/cdebconf_text.h
@@ -5,6 +5,8 @@
 #define CHAR_GOBACK '<'
 #define CHAR_HELP '?'
 #define CHAR_CLEAR '!'
+#define CHAR_PREV '('
+#define CHAR_NEXT ')'
 
 int cdebconf_text_get_width(const char *text);
 
diff --git a/src/modules/frontend/text/text.c b/src/modules/frontend/text/text.c
index e90b837..d7a1da8 100644
--- a/src/modules/frontend/text/text.c
+++ b/src/modules/frontend/text/text.c
@@ -64,7 +64,7 @@ struct frontend_data {
 	char *previous_title;
 };
 
-typedef int (text_handler)(struct frontend *obj, struct question *q);
+typedef int (text_handler)(struct frontend *obj, unsigned printed, struct question *q);
 
 #define MAKE_UPPER(C) do { if (islower((int) C)) { C = (char) toupper((int) C); } } while(0)
 
@@ -102,13 +102,40 @@ static int getwidth(void)
 }
 
 /*
+ * Function: getheight
+ * Input: none
+ * Output: int - height of screen
+ * Description: get the height of the current terminal
+ * Assumptions: doesn't handle resizing; caches value on first call
+ */
+static int getheight(void)
+{
+	static int res = 25;
+	static int inited = 0;
+	int fd;
+	struct winsize ws;
+
+	if (inited == 0)
+	{
+		inited = 1;
+		if ((fd = open("/dev/tty", O_RDONLY)) > 0)
+		{
+			if (ioctl(fd, TIOCGWINSZ, &ws) == 0 && ws.ws_row > 0)
+				res = ws.ws_row;
+			close(fd);
+		}
+	}
+	return res;
+}
+
+/*
  * Function: wrap_print
  * Input: const char *str - string to display
- * Output: none
+ * Output: unsigned printed - number of printed lines
  * Description: prints a string to the screen with word wrapping 
  * Assumptions: string fits in <500 lines
  */
-static void wrap_print(const char *str)
+static unsigned wrap_print(const char *str)
 {
 	/* Simple greedy line-wrapper */
 	int i, lc;
@@ -121,20 +148,23 @@ static void wrap_print(const char *str)
 		printf("%s\n", lines[i]);
 		DELETE(lines[i]);
 	}
+	return lc;
 }
 
 /*
  * Function: text_handler_displaydesc
  * Input: struct frontend *obj - UI object
+ *        unsigned printed - number of already printed lines
  *        struct question *q - question for which to display the description
- * Output: none
+ * Output: unsigned - number of printed lines
  * Description: displays the description for a given question 
  * Assumptions: none
  */
-static void text_handler_displaydesc(struct frontend *obj, struct question *q) 
+static unsigned text_handler_displaydesc(struct frontend *obj, unsigned printed, struct question *q) 
 {
 	char *descr = q_get_description(obj, q);
 	char *ext_descr = q_get_extended_description(obj, q);
+	printed = 0;
 	if (strcmp(q->template->type, "note") == 0 ||
 	    strcmp(q->template->type, "error") == 0)
 	{
@@ -143,17 +173,19 @@ static void text_handler_displaydesc(struct frontend *obj, struct question *q)
 		else
 			printf("%s", descr);
 		printf("\n\n");
+		printed += 2;
 		if (*ext_descr)
-			wrap_print(ext_descr);
+			printed += wrap_print(ext_descr);
 	}
 	else
 	{
 		if (*ext_descr)
-			wrap_print(ext_descr);
-		wrap_print(descr);
+			printed += wrap_print(ext_descr);
+		printed += wrap_print(descr);
 	}
 	free(descr);
 	free(ext_descr);
+	return printed;
 }
 
 static void
@@ -163,21 +195,24 @@ get_answer(char *answer, int size)
 	CHOMP(answer);
 }
 
-static void
+static unsigned
 show_help (struct frontend *obj, struct question *q)
 {
 	char *descr = q_get_description(obj, q);
 	char *help = q_get_help(obj, q);
+	unsigned printed = 0;
 	if (*help) {
 		struct question *help_q = obj->qdb->methods.get(obj->qdb, help);
 		if (help_q) {
 			char *help_descr = q_get_description(obj, help_q);
 			char *help_ext_descr = q_get_extended_description(obj, help_q);
-			wrap_print(help_descr);
+			printed += wrap_print(help_descr);
 			printf("\n");
+			printed++;
 			if (*help_ext_descr) {
-				wrap_print(help_ext_descr);
+				printed += wrap_print(help_ext_descr);
 				printf("\n");
+				printed++;
 			}
 			free(help_ext_descr);
 			free(help_descr);
@@ -186,13 +221,16 @@ show_help (struct frontend *obj, struct question *q)
 		free(help);
 	}
 	printf("%s\n", question_get_text(obj, "debconf/text-help-keystrokes", "KEYSTROKES:"));
+	printed++;
 	printf(" ");
 	printf(question_get_text(obj, "debconf/text-help-keystroke", "'%c'"), CHAR_HELP);
 	printf(" %s\n", question_get_text(obj, "debconf/text-help-help", "Display this help message"));
+	printed++;
 	if (obj->methods.can_go_back (obj, q)) {
 		printf(" ");
 		printf(question_get_text(obj, "debconf/text-help-keystroke", "'%c'"), CHAR_GOBACK);
 		printf(" %s\n", question_get_text(obj, "debconf/text-help-goback", "Go back to previous question"));
+		printed++;
 	}
 	if (strcmp(q->template->type, "string") == 0 ||
 	    strcmp(q->template->type, "password") == 0 ||
@@ -200,9 +238,11 @@ show_help (struct frontend *obj, struct question *q)
 		printf(" ");
 		printf(question_get_text(obj, "debconf/text-help-keystroke", "'%c'"), CHAR_CLEAR);
 		printf(" %s\n", question_get_text(obj, "debconf/text-help-clear", "Select an empty entry"));
+		printed++;
 	}
-	wrap_print(descr);
+	printed += wrap_print(descr);
 	free(descr);
+	return printed;
 }
 
 struct choices {
@@ -213,8 +253,21 @@ struct choices {
 	int *tindex;
 };
 
-static void
-printlist (struct frontend *obj, struct question *q, const struct choices *choices)
+/*
+ * Function: printlist
+ * Input: struct frontend *obj - UI object
+ *        unsigned max_lines - maximum number of lines to print
+ *        unsigned start - which line of choices should be printed first.
+ *        struct question *q - question for which to display the description
+ * Output: bool - whether we managed to print all choices from 'start' to last or not
+ * Description: displays the description for a given question
+ * Assumptions: none
+ *
+ * If it didn't fit, it will have printed a one-line comment about it, thus one
+ * line of choices less.
+ */
+static unsigned
+printlist (struct frontend *obj, unsigned max_lines, unsigned start, struct question *q, const struct choices *choices)
 {
 	int choice_min = -1;
 	int num_cols, num_lines;
@@ -229,6 +282,7 @@ printlist (struct frontend *obj, struct question *q, const struct choices *choic
 	int width = getwidth();
 	char **fchoices = malloc(sizeof(char *) * choices->count);
 	int horiz = 0;
+	bool all = false;
 
 	if (getenv("DEBCONF_TEXT_HORIZ"))
 		horiz = 1;
@@ -304,6 +358,7 @@ printlist (struct frontend *obj, struct question *q, const struct choices *choic
 		num_lines = choices->count;
 		num_cols = 1;
 	}
+
 	output = malloc(sizeof(char *) * num_lines);
 	for (i = 0; i < num_lines; i++)
 	{
@@ -337,27 +392,57 @@ printlist (struct frontend *obj, struct question *q, const struct choices *choic
 			max_len = 0;
 		}
 	}
-	for (l = 0; l < num_lines; l++)
+
+	if (max_lines >= num_lines - start)
+	{
+		/* More than enough room */
+		max_lines = num_lines - start;
+		all = true;
+	}
+	else
+		/* Keep one line for the "more choices" prompt */
+		max_lines--;
+	/* Don't display the beginning */
+	for (l = 0; l < start; l++)
+		free(output[l]);
+	/* Display only what fits in the screen */
+	for ( ; l < start + max_lines; l++)
 	{
 		printf("%s\n", output[l]);
 		free(output[l]);
 	}
+	/* Don't display the end */
+	for ( ; l < num_lines; l++)
+		free(output[l]);
+
 	free(output);
 	free(col_width);
 	for (i = 0; i < choices->count; i++)
 		free(fchoices[i]);
 	free(fchoices);
+
+	if (start > 0 && !all)
+		printf(question_get_text(obj, "debconf/text-help-otherchoices", "Other choices are available with '%c' and '%c'"), CHAR_PREV, CHAR_NEXT);
+	if (start > 0 && all)
+		printf(question_get_text(obj, "debconf/text-help-prevchoices", "Previous choices are available with '%c'"), CHAR_PREV);
+	if (start == 0 && !all)
+		printf(question_get_text(obj, "debconf/text-help-nextchoices", "Next choices are available with '%c'"), CHAR_NEXT);
+	if (start > 0 || !all)
+		printf("\n");
+
+	return all;
 }
 
 /*
  * Function: text_handler_boolean
  * Input: struct frontend *obj - frontend object
+ *        unsigned printed - number of already printed lines
  *        struct question *q - question to ask
  * Output: int - DC_OK, DC_NOTOK, DC_GOBACK
  * Description: handler for the boolean question type
  * Assumptions: none
  */
-static int text_handler_boolean(struct frontend *obj, struct question *q)
+static int text_handler_boolean(struct frontend *obj, unsigned printed, struct question *q)
 {
 	char buf[30];
 	int ans = 0;
@@ -385,7 +470,7 @@ static int text_handler_boolean(struct frontend *obj, struct question *q)
 					"Prompt: '%c' for help> "), CHAR_HELP);
 		get_answer(buf, sizeof(buf));
 		if (buf[0] == CHAR_HELP && buf[1] == 0)
-			show_help(obj, q);
+			printed += show_help(obj, q);
 		else if (obj->methods.can_go_back (obj, q) &&
 		         buf[0] == CHAR_GOBACK && buf[1] == 0)
 			return DC_GOBACK;
@@ -433,6 +518,7 @@ static void choices_delete(struct choices *c)
 /*
  * Function: choices_get
  * Input: struct frontend *obj - frontend object
+ *        unsigned printed - number of already printed lines
  *        struct question *q - question to ask
  * Output: struct choices * - choices values, translations, indices, and select
  * Description: retrieve question choices, translations, indices
@@ -480,12 +566,13 @@ static struct choices *choices_get(struct frontend *obj, struct question *q)
 /*
  * Function: text_handler_multiselect
  * Input: struct frontend *obj - frontend object
+ *        unsigned printed - number of already printed lines
  *        struct question *q - question to ask
  * Output: int - DC_OK, DC_NOTOK
  * Description: handler for the multiselect question type
  * Assumptions: none
  */
-static int text_handler_multiselect(struct frontend *obj, struct question *q)
+static int text_handler_multiselect(struct frontend *obj, unsigned printed, struct question *q)
 {
 	struct choices *choices = NULL;
 	char **defaults;
@@ -493,6 +580,8 @@ static int text_handler_multiselect(struct frontend *obj, struct question *q)
 	char answer[4096] = {0};
 	int i, j, dcount, choice;
 	int ret = DC_OK;
+	unsigned start = 0;
+	bool all;
 
 	choices = choices_get(obj, q);
 	if (choices == NULL)
@@ -525,13 +614,14 @@ static int text_handler_multiselect(struct frontend *obj, struct question *q)
 		}
 
   DISPLAY:
-	printlist (obj, q, choices);
+	all = printlist (obj, getheight() - printed - 1, start, q, choices);
 	printf(question_get_text(obj, "debconf/text-prompt-default-string", 
 		"Prompt: '%c' for help, default=%s> "), CHAR_HELP, defval);
 	get_answer(answer, sizeof(answer));
 	if (answer[0] == CHAR_HELP && answer[1] == 0)
 	{
-		show_help(obj, q);
+		printed = 0;
+		printed += show_help(obj, q);
 		goto DISPLAY;
 	}
 	else if (answer[0] == CHAR_CLEAR && answer[1] == 0)
@@ -545,6 +635,27 @@ static int text_handler_multiselect(struct frontend *obj, struct question *q)
 		ret = DC_GOBACK;
 		goto CleanUp_DEFVAL;
 	}
+	else if (answer[0] == CHAR_NEXT && answer[1] == 0)
+	{
+		if (!all)
+			start += getheight() - printed - 2;
+		printed = 0;
+		goto DISPLAY;
+	}
+	else if (answer[0] == CHAR_PREV && answer[1] == 0)
+	{
+		/* Note: 'printed' may not always contain the same value, when
+		 * the title banner is not printed again notably.  This however
+		 * only happens once, the second time the question in answered,
+		 * and start will have then been 0 already so this does not
+		 * pose problem.  */
+		if (start <= getheight() - printed - 2)
+			start = 0;
+		else
+			start -= getheight() - printed - 2;
+		printed = 0;
+		goto DISPLAY;
+	}
 
 	if (!(ISEMPTY(answer)))
 	{
@@ -580,6 +691,7 @@ static int text_handler_multiselect(struct frontend *obj, struct question *q)
 /*
  * Function: text_handler_select
  * Input: struct frontend *obj - frontend object
+ *        unsigned printed - number of already printed lines
  *        struct question *q - question to ask
  * Output: int - DC_OK, DC_NOTOK
  * Description: handler for the select question type
@@ -587,13 +699,15 @@ static int text_handler_multiselect(struct frontend *obj, struct question *q)
  *
  * TODO: factor common code with multiselect
  */
-static int text_handler_select(struct frontend *obj, struct question *q)
+static int text_handler_select(struct frontend *obj, unsigned printed, struct question *q)
 {
 	struct choices *choices = NULL;
 	char answer[128];
 	int i, choice, def = -1;
 	const char *defval;
 	int ret = DC_OK;
+	unsigned start = 0;
+	bool all;
 
 	choices = choices_get(obj, q);
 	if (choices == NULL)
@@ -617,7 +731,7 @@ static int text_handler_select(struct frontend *obj, struct question *q)
 	i = 0;
 	choice = -1;
 	do {
-		printlist (obj, q, choices);
+		all = printlist (obj, getheight() - printed - 1, start, q, choices);
 		if (def >= 0 && choices->choices_translated[def]) {
 			printf(question_get_text(obj, "debconf/text-prompt-default", 
 				"Prompt: '%c' for help, default=%d> "),
@@ -629,7 +743,7 @@ static int text_handler_select(struct frontend *obj, struct question *q)
 		get_answer(answer, sizeof(answer));
 		if (answer[0] == CHAR_HELP)
 		{
-			show_help(obj, q);
+			printed += show_help(obj, q);
 			continue;
 		}
 		if (obj->methods.can_go_back (obj, q) &&
@@ -638,6 +752,27 @@ static int text_handler_select(struct frontend *obj, struct question *q)
 			ret = DC_GOBACK;
 			goto CleanUp_SELECTED;
 		}
+		else if (answer[0] == CHAR_NEXT && answer[1] == 0)
+		{
+			if (!all)
+				start += getheight() - printed - 2;
+			printed = 0;
+			continue;
+		}
+		else if (answer[0] == CHAR_PREV && answer[1] == 0)
+		{
+			/* Note: 'printed' may not always contain the same value, when
+			 * the title banner is not printed again notably.  This however
+			 * only happens once, the second time the question in answered,
+			 * and start will have then been 0 already so this does not
+			 * pose problem.  */
+			if (start < getheight() - printed - 2)
+				start = 0;
+			else
+				start -= getheight() - printed - 2;
+			printed = 0;
+			continue;
+		}
 		if (ISEMPTY(answer))
 			choice = def;
 		else {
@@ -653,6 +788,7 @@ static int text_handler_select(struct frontend *obj, struct question *q)
 				}
 			}
 		}
+		printed = 0;
 	} while (choice < 0 || choice >= choices->count);
 	question_setvalue(q, choices->choices[choices->tindex[choice]]);
 
@@ -665,12 +801,13 @@ static int text_handler_select(struct frontend *obj, struct question *q)
 /*
  * Function: text_handler_note
  * Input: struct frontend *obj - frontend object
+ *        unsigned printed - number of already printed lines
  *        struct question *q - question to ask
  * Output: int - DC_OK, DC_NOTOK, DC_GOBACK
  * Description: handler for the note question type
  * Assumptions: none
  */
-static int text_handler_note(struct frontend *obj, struct question *q)
+static int text_handler_note(struct frontend *obj, unsigned printed, struct question *q)
 {
 	char buf[100] = {0};
 	printf("%s ", question_get_text(obj, "debconf/cont-prompt",
@@ -680,7 +817,7 @@ static int text_handler_note(struct frontend *obj, struct question *q)
 	{
 		get_answer(buf, sizeof(buf));
 		if (buf[0] == CHAR_HELP && buf[1] == 0)
-			show_help(obj, q);
+			printed += show_help(obj, q);
 		else if (obj->methods.can_go_back (obj, q) &&
 		         buf[0] == CHAR_GOBACK && buf[1] == 0)
 			return DC_GOBACK;
@@ -693,6 +830,7 @@ static int text_handler_note(struct frontend *obj, struct question *q)
 /*
  * Function: text_handler_password
  * Input: struct frontend *obj - frontend object
+ *        unsigned printed - number of already printed lines
  *        struct question *q - question to ask
  * Output: int - DC_OK, DC_NOTOK
  * Description: handler for the password question type
@@ -700,7 +838,7 @@ static int text_handler_note(struct frontend *obj, struct question *q)
  *
  * TODO: this can be *MUCH* improved. no editing is possible right now
  */
-static int text_handler_password(struct frontend *obj, struct question *q)
+static int text_handler_password(struct frontend *obj, unsigned printed, struct question *q)
 {
 	struct termios oldt, newt;
 	char passwd[256] = {0};
@@ -729,7 +867,7 @@ static int text_handler_password(struct frontend *obj, struct question *q)
 		passwd[i] = 0;
 		tcsetattr(0, TCSANOW, &oldt);
 		if (passwd[0] == CHAR_HELP && passwd[1] == 0)
-			show_help(obj, q);
+			printed += show_help(obj, q);
 		else
 			break;
 	}
@@ -746,12 +884,13 @@ static int text_handler_password(struct frontend *obj, struct question *q)
 /*
  * Function: text_handler_string
  * Input: struct frontend *obj - frontend object
+ *        unsigned printed - number of already printed lines
  *        struct question *q - question to ask
  * Output: int - DC_OK, DC_NOTOK
  * Description: handler for the string question type
  * Assumptions: none
  */
-static int text_handler_string(struct frontend *obj, struct question *q)
+static int text_handler_string(struct frontend *obj, unsigned printed, struct question *q)
 {
 	char buf[1024] = {0};
 	const char *defval = question_getvalue(q, "");
@@ -763,7 +902,7 @@ static int text_handler_string(struct frontend *obj, struct question *q)
 		fflush(stdout);
 		get_answer(buf, sizeof(buf));
 		if (buf[0] == CHAR_HELP && buf[1] == 0)
-			show_help(obj, q);
+			printed += show_help(obj, q);
 		else
 			break;
 	}
@@ -784,27 +923,29 @@ static int text_handler_string(struct frontend *obj, struct question *q)
 /*
  * Function: text_handler_text
  * Input: struct frontend *obj - frontend object
+ *        unsigned printed - number of already printed lines
  *        struct question *q - question to ask
  * Output: int - DC_OK, DC_NOTOK, DC_GOBACK
  * Description: handler for the text question type
  * Assumptions: none
  */
-static int text_handler_text(struct frontend *obj, struct question *q)
+static int text_handler_text(struct frontend *obj, unsigned printed, struct question *q)
 {
-	return text_handler_note(obj, q);
+	return text_handler_note(obj, printed, q);
 }
 
 /*
  * Function: text_handler_error
  * Input: struct frontend *obj - frontend object
+ *        unsigned printed - number of already printed lines
  *        struct question *q - question to ask
  * Output: int - DC_OK, DC_NOTOK, DC_GOBACK
  * Description: handler for the error question type. Currently equal to _note
  * Assumptions: none
  */
-static int text_handler_error(struct frontend *obj, struct question *q)
+static int text_handler_error(struct frontend *obj, unsigned printed, struct question *q)
 {
-	return text_handler_note(obj, q);
+	return text_handler_note(obj, printed, q);
 }
 
 /* ----------------------------------------------------------------------- */
@@ -867,6 +1008,7 @@ static int text_shutdown(struct frontend *obj)
 /*
  * Function: text_can_go_back
  * Input: struct frontend *obj - frontend object
+ *        unsigned printed - number of already printed lines
  *        struct question *q - question object
  * Output: int - DC_OK, DC_NOTOK
  * Description: tells whether confmodule supports backing up
@@ -881,6 +1023,7 @@ text_can_go_back(struct frontend *obj, struct question *q)
 /*
  * Function: text_can_align
  * Input: struct frontend *obj - frontend object
+ *        unsigned printed - number of already printed lines
  *        struct question *q - question object
  * Output: int - DC_OK, DC_NOTOK
  * Description: tells whether confmodule supports aligning columns
@@ -929,12 +1072,14 @@ static int text_go(struct frontend *obj)
 	struct question *q = obj->questions;
 	int i;
 	int ret = DC_OK;
+	unsigned printed;
 
 	while (q != NULL) {
 		for (i = 0; i < DIM(question_handlers); i++) {
 			text_handler *handler;
 			struct plugin *plugin = NULL;
 
+			printed = 0;
 			if (*question_handlers[i].type)
 				handler = question_handlers[i].handler;
 			else {
@@ -968,12 +1113,13 @@ static int text_go(struct frontend *obj)
 					memset(underline, '-', underline_len);
 					underline[underline_len] = '\0';
 					printf("%s\n%s\n\n", obj->title, underline);
+					printed += 3;
 					free(underline);
 					free(data->previous_title);
 					data->previous_title = strdup(obj->title);
 				}
-				text_handler_displaydesc(obj, q);
-				ret = handler(obj, q);
+				printed += text_handler_displaydesc(obj, printed, q);
+				ret = handler(obj, printed, q);
 				putchar('\n');
 				if (ret == DC_OK)
 					frontend_qdb_set(obj->qdb, q, 0);

--- End Message ---
--- Begin Message ---
Source: yoshimi
Source-Version: 1.3.8.2-1

We believe that the bug you reported is fixed in the latest version of
yoshimi, which is due to be installed in the Debian FTP archive.

A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to 809739@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Sebastian Ramacher <sramacher@debian.org> (supplier of updated yoshimi package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmaster@ftp-master.debian.org)


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Format: 1.8
Date: Sun, 07 Feb 2016 13:31:08 +0100
Source: yoshimi
Binary: yoshimi yoshimi-data
Architecture: source all
Version: 1.3.8.2-1
Distribution: unstable
Urgency: medium
Maintainer: Debian Multimedia Maintainers <pkg-multimedia-maintainers@lists.alioth.debian.org>
Changed-By: Sebastian Ramacher <sramacher@debian.org>
Description:
 yoshimi    - software synthesizer based on ZynAddSubFX
 yoshimi-data - Presets for Yoshimi
Closes: 809739
Changes:
 yoshimi (1.3.8.2-1) unstable; urgency=medium
 .
   * Team upload.
 .
   [ Alessio Treglia ]
   * Remove myself from Uploaders.
 .
   [ Sebastian Ramacher ]
   * New upstream release.
     - Fix cmake issues. (Closes: #809739)
   * Switch to automatic dbg packages
   * debian/yoshimi.install: Use upstream manpage and desktop file.
   * debian/yoshimi-data.install: Update paths.
   * debian/copyright: Update copyright info.
   * debian/control:
     - Update Vcs-Git.
     - Update B-D for new upstream version.
     - Stricter dependency on data package.
     - Bump Standards-Version.
   * debian/patches/manpage-fixes.patch: Fix lintian warnings for manpage.
Checksums-Sha1:
 2ccd481045daead6ce060826908be7f9a86d21ac 2285 yoshimi_1.3.8.2-1.dsc
 567ba1c3d31206ef1ffbbe9f3486e631f26303fe 3576344 yoshimi_1.3.8.2.orig.tar.bz2
 bd0e75c4b468f693250cd2cfc6a235db71929bdc 5176 yoshimi_1.3.8.2-1.debian.tar.xz
 26bcc40c50d11f60eacc8e63db7aab7e1ff6e42d 2118940 yoshimi-data_1.3.8.2-1_all.deb
Checksums-Sha256:
 f17e679c6b51cb5d4e9468b6d6792dacd1138855f26227b14b63bfa02e9f2768 2285 yoshimi_1.3.8.2-1.dsc
 28778202d1840120347802c591e216eac1ec211b022a374de973dab08da58472 3576344 yoshimi_1.3.8.2.orig.tar.bz2
 8bef869bb7fe709382a89d571b3bdf16e23ac10d873163aecc320d8305ae2325 5176 yoshimi_1.3.8.2-1.debian.tar.xz
 2db486becbfd2f522b603e46f3a564a18bf98c3737db1111d473bd8298a3bcff 2118940 yoshimi-data_1.3.8.2-1_all.deb
Files:
 510a65c49f4fee547c1b2ea40edc0371 2285 sound optional yoshimi_1.3.8.2-1.dsc
 8b26d46297b3820156501b3e8a183b93 3576344 sound optional yoshimi_1.3.8.2.orig.tar.bz2
 44e69e8b6a1fbd0631131683773b6759 5176 sound optional yoshimi_1.3.8.2-1.debian.tar.xz
 ea206dd885025621ceed92233f1fd61f 2118940 sound optional yoshimi-data_1.3.8.2-1_all.deb

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAEBCAAGBQJWtzleAAoJEGny/FFupxmT+QIP/AtoSmbGYxh9g2l3sFEuD9S2
4MvxjjPm5zt4iGN7xEk8ytwqhxZTVS4kO2q4gG/5hUjZtnNBK34HaKqKEzzkeWC0
iCw1fnWJLMhL39fLOpe8iOTWCv7lcPWDewyosptTz2ZfYJosXuVvfwOHI2HsTXKQ
NsHf5yYy2v3s+6ni4qiFMfkBENp0Vs+ppSQYHgF88uhsdG6Rh0ZjoEyYy5+7LG0K
zCjgbHpfOFy6Q+aAiA524d2jFGuB8xkyAgqavjFmY75nSDNuyxKf8vRYFSq1HZzJ
4F1fwqkbOepsHJ/F2tJDK66dZiJ/jGGud99QIyYqUCi4Pbbx/y0xbuwrcps6ZVGO
XadmYQlqR7za6DIK/UfIaBageHFcejIrfMjmfWoWuYJj4GPFeQakBXO7iJx5yQ1V
+jAQtvbrNCns/QEybJSpt0oKjn/+UCpgjhAMvXvDzXiCnyOsTxRpmjF9jvoFIwwx
ivkw7rNSI8V3iqHk1+QCRBOpppbssmC/QaikPemACDzmTRdzCkO+gcFSY3XQnlVQ
ZSq5lpYW1FkL8BYgYZejoXHOu9kFgSu72mq1UYaexdKZ8JX+ZkIAtXYmJ16DaqnP
CHQ3wtX2xosO4T8qLJZgljTzAv9Z6/BLfMohwedPZV6cXk7L9cQfvS0CqBu93hbL
Fz3FEVlEQNn79DkuezwJ
=53Y8
-----END PGP SIGNATURE-----

--- End Message ---

Reply to: