Module Name: src
Committed By: jdc
Date: Thu Aug 9 06:46:37 UTC 2012
Modified Files:
src/lib/libcurses [netbsd-6]: get_wch.c
src/lib/libmenu [netbsd-6]: internals.c
Log Message:
Pull up revisions:
src/lib/libcurses/get_wch.c revision 1.10
src/lib/libmenu/internals.c revisions 1.14,1.15
(requested by blymn in ticket #459).
* Size argument for memset when clearing cbuf was wrong, cbuf is an array
of char not int so memset was stomping memory past the end of the array.
Use sizeof properly to correctly determine the amount of memory to clear.
Extraneous whitespace removal.
* Corrected menu drawing when O_ROWMAJOR is not set
* Corrected menu item neighbour calculation so it works when O_ROWMAJOR
is set and unset. This corrects item navigation which was previously
broken when O_ROWMAJOR was not set.
This resolves lib/46620.
To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.9.8.1 src/lib/libcurses/get_wch.c
cvs rdiff -u -r1.13 -r1.13.42.1 src/lib/libmenu/internals.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libcurses/get_wch.c
diff -u src/lib/libcurses/get_wch.c:1.9 src/lib/libcurses/get_wch.c:1.9.8.1
--- src/lib/libcurses/get_wch.c:1.9 Thu Dec 16 17:42:28 2010
+++ src/lib/libcurses/get_wch.c Thu Aug 9 06:46:37 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: get_wch.c,v 1.9 2010/12/16 17:42:28 wiz Exp $ */
+/* $NetBSD: get_wch.c,v 1.9.8.1 2012/08/09 06:46:37 jdc Exp $ */
/*
* Copyright (c) 2005 The NetBSD Foundation Inc.
@@ -36,7 +36,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: get_wch.c,v 1.9 2010/12/16 17:42:28 wiz Exp $");
+__RCSID("$NetBSD: get_wch.c,v 1.9.8.1 2012/08/09 06:46:37 jdc Exp $");
#endif /* not lint */
#include <string.h>
@@ -67,7 +67,7 @@ void
__init_get_wch(SCREEN *screen)
{
wstate = INKEY_NORM;
- memset( &screen->cbuf, 0, MAX_CBUF_SIZE * sizeof( int ));
+ memset( &screen->cbuf, 0, sizeof(screen->cbuf));
screen->cbuf_head = screen->cbuf_tail = screen->cbuf_cur = 0;
}
#endif /* HAVE_WCHAR */
Index: src/lib/libmenu/internals.c
diff -u src/lib/libmenu/internals.c:1.13 src/lib/libmenu/internals.c:1.13.42.1
--- src/lib/libmenu/internals.c:1.13 Fri Nov 24 19:46:58 2006
+++ src/lib/libmenu/internals.c Thu Aug 9 06:46:37 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: internals.c,v 1.13 2006/11/24 19:46:58 christos Exp $ */
+/* $NetBSD: internals.c,v 1.13.42.1 2012/08/09 06:46:37 jdc Exp $ */
/*-
* Copyright (c) 1998-1999 Brett Lymn ([email protected], [email protected])
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: internals.c,v 1.13 2006/11/24 19:46:58 christos Exp $");
+__RCSID("$NetBSD: internals.c,v 1.13.42.1 2012/08/09 06:46:37 jdc Exp $");
#include <menu.h>
#include <ctype.h>
@@ -37,9 +37,7 @@ __RCSID("$NetBSD: internals.c,v 1.13 200
/* internal function prototypes */
static void
-_menui_calc_neighbours(MENU *menu, int item_no, int cycle, int item_rows,
- int item_cols, ITEM **next, ITEM **prev,
- ITEM **major_next, ITEM **major_prev);
+_menui_calc_neighbours(MENU *menu, int item_no);
static void _menui_redraw_menu(MENU *menu, int old_top_row, int old_cur_item);
/*
@@ -52,9 +50,8 @@ static void _menui_redraw_menu(MENU *men
int
_menui_stitch_items(MENU *menu)
{
- int i, cycle, row_major;
+ int i, row_major;
- cycle = ((menu->opts & O_NONCYCLIC) != O_NONCYCLIC);
row_major = ((menu->opts & O_ROWMAJOR) == O_ROWMAJOR);
if (menu->posted == 1)
@@ -62,41 +59,14 @@ _menui_stitch_items(MENU *menu)
if (menu->items == NULL)
return E_BAD_ARGUMENT;
- if (row_major) {
- menu->item_rows = menu->item_count / menu->cols;
- menu->item_cols = menu->cols;
- if (menu->item_count > (menu->item_rows * menu->item_cols))
- menu->item_rows += 1;
- } else {
- menu->item_cols = menu->item_count / menu->rows;
- menu->item_rows = menu->rows;
- if (menu->item_count > (menu->item_rows * menu->item_cols))
- menu->item_cols += 1;
- }
-
+ menu->item_rows = menu->item_count / menu->cols;
+ menu->item_cols = menu->cols;
+ if (menu->item_count > (menu->item_rows * menu->item_cols))
+ menu->item_rows += 1;
_menui_max_item_size(menu);
for (i = 0; i < menu->item_count; i++) {
- /* Calculate the neighbours. The ugliness here deals with
- * the differing menu layout styles. The layout affects
- * the neighbour calculation so we change the arguments
- * around depending on the layout style.
- */
- _menui_calc_neighbours(menu, i, cycle,
- (row_major) ? menu->item_rows
- : menu->item_cols,
- (row_major) ? menu->item_cols
- : menu->item_rows,
- (row_major) ? &menu->items[i]->right
- : &menu->items[i]->down,
- (row_major) ? &menu->items[i]->left
- : &menu->items[i]->up,
- (row_major) ? &menu->items[i]->down
- : &menu->items[i]->right,
- (row_major) ? &menu->items[i]->up
- : &menu->items[i]->left);
-
/* fill in the row and column value of the item */
if (row_major) {
menu->items[i]->row = i / menu->item_cols;
@@ -105,125 +75,200 @@ _menui_stitch_items(MENU *menu)
menu->items[i]->row = i % menu->item_rows;
menu->items[i]->col = i / menu->item_rows;
}
+
+ _menui_calc_neighbours(menu, i);
}
-
+
return E_OK;
}
/*
- * Calculate the neighbours for an item in menu. This routine deliberately
- * does not refer to up/down/left/right as these concepts depend on the menu
- * layout style (row major or not). By arranging the arguments in the right
- * order the caller can generate the neighbours for either menu layout style.
+ * Calculate the neighbours for an item in menu.
*/
static void
-_menui_calc_neighbours(MENU *menu, int item_no, int cycle, int item_rows,
- int item_cols, ITEM **next, ITEM **prev,
- ITEM **major_next, ITEM **major_prev)
+_menui_calc_neighbours(MENU *menu, int item_no)
{
- int neighbour;
+ int neighbour, cycle, row_major, edge;
+ ITEM *item;
- if (item_rows < 2) {
+ row_major = ((menu->opts & O_ROWMAJOR) == O_ROWMAJOR);
+ cycle = ((menu->opts & O_NONCYCLIC) != O_NONCYCLIC);
+ item = menu->items[item_no];
+
+ if (menu->item_rows < 2) {
if (cycle) {
- *major_next = menu->items[item_no];
- *major_prev = menu->items[item_no];
+ item->up = item;
+ item->down = item;
} else {
- *major_next = NULL;
- *major_prev = NULL;
+ item->up = NULL;
+ item->down = NULL;
}
} else {
- neighbour = item_no + item_cols;
- if (neighbour >= menu->item_count) {
- if (cycle) {
- if (item_rows == 2) {
- neighbour = item_no - item_cols;
- if (neighbour < 0)
- neighbour = item_no;
- *major_next = menu->items[neighbour];
- } else {
- *major_next =
- menu->items[item_no % item_cols];
- }
+
+ /* up */
+ if (menu->item_cols < 2) {
+ if (item_no == 0) {
+ if (cycle)
+ item->up =
+ menu->items[menu->item_count - 1];
+ else
+ item->up = NULL;
} else
- *major_next = NULL;
- } else
- *major_next = menu->items[neighbour];
-
-
- neighbour = item_no - item_cols;
- if (neighbour < 0) {
- if (cycle) {
- if (item_rows == 2) {
- neighbour = item_no + item_cols;
+ item->up = menu->items[item_no - 1];
+ } else {
+ edge = 0;
+ if (row_major) {
+ if (item->row == 0) {
+ neighbour =
+ (menu->item_rows - 1) * menu->item_cols
+ + item->col;
if (neighbour >= menu->item_count)
- neighbour = item_no;
- *major_prev = menu->items[neighbour];
- } else {
- neighbour = item_no +
- (item_rows - 1) * item_cols;
-
+ neighbour -= menu->item_cols;
+ edge = 1;
+ } else
+ neighbour = item_no - menu->item_cols;
+ } else {
+ if (item->row == 0) {
+ neighbour = menu->item_rows * item->col
+ + menu->item_rows - 1;
if (neighbour >= menu->item_count)
- neighbour = item_no +
- (item_rows - 2)
- * item_cols;
-
- *major_prev = menu->items[neighbour];
- }
+ neighbour = menu->item_count - 1;
+ edge = 1;
+ } else
+ neighbour = item_no - 1;
+ }
+
+
+ item->up = menu->items[neighbour];
+ if ((!cycle) && (edge == 1))
+ item->up = NULL;
+ }
+
+ /* Down */
+ if (menu->item_cols < 2) {
+ if (item_no == (menu->item_count - 1)) {
+ if (cycle)
+ item->down = menu->items[0];
+ else
+ item->down = NULL;
} else
- *major_prev = NULL;
- } else
- *major_prev = menu->items[neighbour];
- }
-
- if ((item_no % item_cols) == 0) {
- if (cycle) {
- if (item_cols < 2) {
- *prev = menu->items[item_no];
+ item->down = menu->items[item_no + 1];
+ } else {
+ edge = 0;
+ if (row_major) {
+ if (item->row == menu->item_rows - 1) {
+ neighbour = item->col;
+ edge = 1;
+ } else {
+ neighbour = item_no + menu->item_cols;
+ if (neighbour >= menu->item_count) {
+ neighbour = item->col;
+ edge = 1;
+ }
+ }
} else {
- neighbour = item_no + item_cols - 1;
- if (neighbour >= menu->item_count) {
- if (item_cols == 2) {
- *prev = menu->items[item_no];
- } else {
- *prev = menu->items[menu->item_count - 1];
+ if (item->row == menu->item_rows - 1) {
+ neighbour = item->col * menu->item_rows;
+ edge = 1;
+ } else {
+ neighbour = item_no + 1;
+ if (neighbour >= menu->item_count) {
+ neighbour = item->col
+ * menu->item_rows;
+ edge = 1;
}
- } else
- *prev = menu->items[neighbour];
+ }
}
- } else
- *prev = NULL;
- } else
- *prev = menu->items[item_no - 1];
-
- if ((item_no % item_cols) == (item_cols - 1)) {
+
+ item->down = menu->items[neighbour];
+ if ((!cycle) && (edge == 1))
+ item->down = NULL;
+ }
+ }
+
+ if (menu->item_cols < 2) {
if (cycle) {
- if (item_cols < 2) {
- *next = menu->items[item_no];
+ item->left = item;
+ item->right = item;
+ } else {
+ item->left = NULL;
+ item->right = NULL;
+ }
+ } else {
+ /* left */
+ if (menu->item_rows < 2) {
+ if (item_no == 0) {
+ if (cycle)
+ item->left =
+ menu->items[menu->item_count - 1];
+ else
+ item->left = NULL;
+ } else
+ item->left = menu->items[item_no - 1];
+ } else {
+ edge = 0;
+ if (row_major) {
+ if (item->col == 0) {
+ neighbour = item_no + menu->cols - 1;
+ if (neighbour >= menu->item_count)
+ neighbour = menu->item_count - 1;
+ edge = 1;
+ } else
+ neighbour = item_no - 1;
} else {
- neighbour = item_no - item_cols + 1;
- if (neighbour >= menu->item_count) {
- if (item_cols == 2) {
- *next = menu->items[item_no];
- } else {
- neighbour = item_cols * item_no / item_cols;
-
- *next = menu->items[neighbour];
- }
+ if (item->col == 0) {
+ neighbour = menu->item_rows
+ * (menu->item_cols - 1) + item->row;
+ if (neighbour >= menu->item_count)
+ neighbour -= menu->item_rows;
+ edge = 1;
} else
- *next = menu->items[neighbour];
+ neighbour = item_no - menu->item_rows;
}
- } else
- *next = NULL;
- } else {
- neighbour = item_no + 1;
- if (neighbour >= menu->item_count) {
- if (cycle) {
- neighbour = item_cols * (item_rows - 1);
- *next = menu->items[neighbour];
+
+ item->left = menu->items[neighbour];
+ if ((!cycle) && (edge == 1))
+ item->left = NULL;
+ }
+
+ /* right */
+ if (menu->item_rows < 2) {
+ if (item_no == menu->item_count - 1) {
+ if (cycle)
+ item->right = menu->items[0];
+ else
+ item->right = NULL;
} else
- *next = NULL;
- } else
- *next = menu->items[neighbour];
+ item->right = menu->items[item_no + 1];
+ } else {
+ edge = 0;
+ if (row_major) {
+ if (item->col == menu->item_cols - 1) {
+ neighbour = item_no - menu->item_cols
+ + 1;
+ edge = 1;
+ } else if (item_no == menu->item_count - 1) {
+ neighbour = item->row * menu->item_cols;
+ edge = 1;
+ } else
+ neighbour = item_no + 1;
+ } else {
+ if (item->col == menu->item_cols - 1) {
+ neighbour = item->row;
+ edge = 1;
+ } else {
+ neighbour = item_no + menu->item_rows;
+ if (neighbour >= menu->item_count) {
+ neighbour = item->row;
+ edge = 1;
+ }
+ }
+ }
+
+ item->right = menu->items[neighbour];
+ if ((!cycle) && (edge == 1))
+ item->right = NULL;
+ }
}
}
@@ -235,7 +280,7 @@ int
_menui_goto_item(MENU *menu, ITEM *item, int new_top_row)
{
int old_top_row = menu->top_row, old_cur_item = menu->cur_item;
-
+
/* If we get a null then the menu is not cyclic so deny request */
if (item == NULL)
return E_REQUEST_DENIED;
@@ -249,7 +294,7 @@ _menui_goto_item(MENU *menu, ITEM *item,
if ((menu->posted == 1) && (menu->menu_init != NULL))
menu->menu_init(menu);
}
-
+
/* this looks like wasted effort but it can happen.... */
if (menu->cur_item != item->index) {
@@ -262,10 +307,10 @@ _menui_goto_item(MENU *menu, ITEM *item,
if (menu->posted == 1)
_menui_redraw_menu(menu, old_top_row, old_cur_item);
-
+
if ((menu->posted == 1) && (menu->item_init != NULL))
menu->item_init(menu);
-
+
}
menu->in_init = 0;
@@ -283,7 +328,7 @@ _menui_match_items(MENU *menu, int direc
int i, caseless;
caseless = ((menu->opts & O_IGNORECASE) == O_IGNORECASE);
-
+
i = menu->cur_item;
if (direction == MATCH_NEXT_FORWARD) {
if (++i >= menu->item_count) i = 0;
@@ -291,7 +336,7 @@ _menui_match_items(MENU *menu, int direc
if (--i < 0) i = menu->item_count - 1;
}
-
+
do {
if (menu->items[i]->name.length >= menu->plen) {
/* no chance if pattern is longer */
@@ -313,7 +358,7 @@ _menui_match_items(MENU *menu, int direc
}
}
}
-
+
if ((direction == MATCH_FORWARD) ||
(direction == MATCH_NEXT_FORWARD)) {
if (++i >= menu->item_count) i = 0;
@@ -327,7 +372,7 @@ _menui_match_items(MENU *menu, int direc
}
/*
- * Attempt to match the pattern buffer against the items. If c is a
+ * Attempt to match the pattern buffer against the items. If c is a
* printable character then add it to the pattern buffer prior to
* performing the match. Direction determines the direction of matching.
* If the match is successful update the item_matched variable with the
@@ -360,7 +405,7 @@ _menui_match_pattern(MENU *menu, int c,
menu->pattern[--menu->plen] = '\0';
return E_NO_MATCH;
}
-
+
if (_menui_match_items(menu, direction,
item_matched) == E_NO_MATCH) {
menu->pattern[--menu->plen] = '\0';
@@ -384,9 +429,9 @@ void
_menui_draw_item(MENU *menu, int item)
{
int j, pad_len, mark_len;
-
+
mark_len = max(menu->mark.length, menu->unmark.length);
-
+
wmove(menu->scrwin,
menu->items[item]->row - menu->top_row,
menu->items[item]->col * (menu->col_width + 1));
@@ -422,12 +467,12 @@ _menui_draw_item(MENU *menu, int item)
for (j = menu->unmark.length; j < mark_len; j++)
waddch(menu->scrwin, ' ');
}
-
+
/* add the menu name */
for (j=0; j < menu->items[item]->name.length; j++)
waddch(menu->scrwin,
menu->items[item]->name.string[j]);
-
+
pad_len = menu->col_width - menu->items[item]->name.length
- mark_len - 1;
if ((menu->opts & O_SHOWDESC) == O_SHOWDESC) {
@@ -443,7 +488,7 @@ _menui_draw_item(MENU *menu, int item)
waddch(menu->scrwin, ' ');
}
menu->items[item]->visible = 1;
-
+
/* kill any special attributes... */
wattrset(menu->scrwin, menu->back);
@@ -459,7 +504,7 @@ _menui_draw_item(MENU *menu, int item)
menu->items[item]->col * (menu->col_width + 1) - 1);
waddch(menu->scrwin, ' ');
}
-
+
/* and position the cursor nicely */
pos_menu_cursor(menu);
}
@@ -470,66 +515,76 @@ _menui_draw_item(MENU *menu, int item)
int
_menui_draw_menu(MENU *menu)
{
- int rowmajor, i, j, max_items, last_item, row = -1, col = -1;
-
+ int rowmajor, i, j, k, row = -1, col = -1, stride;
+ int incr, cur_row, offset, row_count;
+
rowmajor = ((menu->opts & O_ROWMAJOR) == O_ROWMAJOR);
- for (i = 0; i < menu->item_count; i++) {
+ if (rowmajor) {
+ stride = 1;
+ incr = menu->item_cols;
+ } else {
+ stride = menu->item_rows;
+ incr = 1;
+ }
+ row_count = 0;
+
+ for (i = 0; i < menu->item_count; i += incr) {
if (menu->items[i]->row == menu->top_row)
break;
- menu->items[i]->visible = 0;
+ row_count++;
+ for (j = 0; j < menu->item_cols; j++) {
+ offset = j * stride + i;
+ if (offset >= menu->item_count)
+ break; /* done */
+ menu->items[offset]->visible = 0;
+ }
}
wmove(menu->scrwin, 0, 0);
menu->col_width = getmaxx(menu->scrwin) / menu->cols;
- max_items = menu->rows * menu->cols;
- last_item = ((max_items + i) > menu->item_count) ? menu->item_count :
- (max_items + i);
-
- for (; i < last_item; i++) {
- if (i > menu->item_count) {
- /* no more items to draw, write background blanks */
- wattrset(menu->scrwin, menu->back);
- if (row < 0) {
- row = menu->items[menu->item_count - 1]->row;
- col = menu->items[menu->item_count - 1]->col;
- }
-
- if (rowmajor) {
- col++;
- if (col > menu->cols) {
- col = 0;
- row++;
+ for (cur_row = 0; cur_row < menu->rows; cur_row++) {
+ for (j = 0; j < menu->cols; j++) {
+ offset = j * stride + i;
+ if (offset >= menu->item_count) {
+ /* no more items to draw, write background blanks */
+ wattrset(menu->scrwin, menu->back);
+ if (row < 0) {
+ row = menu->items[menu->item_count - 1]->row;
+ col = menu->items[menu->item_count - 1]->col;
}
+
+ wmove(menu->scrwin, cur_row,
+ j * (menu->col_width + 1));
+ for (k = 0; k < menu->col_width; k++)
+ waddch(menu->scrwin, ' ');
} else {
- row++;
- if (row > menu->rows) {
- row = 0;
- col++;
- }
+ _menui_draw_item(menu, offset);
}
- wmove(menu->scrwin, row,
- col * (menu->col_width + 1));
- for (j = 0; j < menu->col_width; j++)
- waddch(menu->scrwin, ' ');
- } else {
- _menui_draw_item(menu, i);
-
}
+ i += incr;
+ row_count++;
}
- if (last_item < menu->item_count) {
- for (j = last_item; j < menu->item_count; j++)
- menu->items[j]->visible = 0;
+ if (row_count < menu->item_rows) {
+ for (cur_row = row_count; cur_row < menu->item_rows; cur_row++) {
+ for (j = 0; j < menu->item_cols; j++) {
+ offset = j * stride + i;
+ if (offset >= menu->item_count)
+ break; /* done */
+ menu->items[offset]->visible = 0;
+ }
+ i += incr;
+ }
}
-
+
return E_OK;
}
-
+
/*
* Calculate the widest menu item and stash it in the menu struct.
*
@@ -540,7 +595,7 @@ _menui_max_item_size(MENU *menu)
int i, with_desc, width;
with_desc = ((menu->opts & O_SHOWDESC) == O_SHOWDESC);
-
+
for (i = 0; i < menu->item_count; i++) {
width = menu->items[i]->name.length
+ max(menu->mark.length, menu->unmark.length);