150276Speter/****************************************************************************
2184989Srafan * Copyright (c) 1998-2005,2008 Free Software Foundation, Inc.              *
350276Speter *                                                                          *
450276Speter * Permission is hereby granted, free of charge, to any person obtaining a  *
550276Speter * copy of this software and associated documentation files (the            *
650276Speter * "Software"), to deal in the Software without restriction, including      *
750276Speter * without limitation the rights to use, copy, modify, merge, publish,      *
850276Speter * distribute, distribute with modifications, sublicense, and/or sell       *
950276Speter * copies of the Software, and to permit persons to whom the Software is    *
1050276Speter * furnished to do so, subject to the following conditions:                 *
1150276Speter *                                                                          *
1250276Speter * The above copyright notice and this permission notice shall be included  *
1350276Speter * in all copies or substantial portions of the Software.                   *
1450276Speter *                                                                          *
1550276Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
1650276Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
1750276Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
1850276Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
1950276Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
2050276Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
2150276Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
2250276Speter *                                                                          *
2350276Speter * Except as contained in this notice, the name(s) of the above copyright   *
2450276Speter * holders shall not be used in advertising or otherwise to promote the     *
2550276Speter * sale, use or other dealings in this Software without prior written       *
2650276Speter * authorization.                                                           *
2750276Speter ****************************************************************************/
2850276Speter
2950276Speter/****************************************************************************
30166124Srafan *   Author:  Juergen Pfeifer, 1995,1997                                    *
3150276Speter ****************************************************************************/
3250276Speter
3350276Speter/***************************************************************************
3450276Speter* Module m_driver                                                          *
3550276Speter* Central dispatching routine                                              *
3650276Speter***************************************************************************/
3750276Speter
3850276Speter#include "menu.priv.h"
3950276Speter
40184989SrafanMODULE_ID("$Id: m_driver.c,v 1.27 2008/08/03 22:08:22 tom Exp $")
4150276Speter
4250276Speter/* Macros */
4350276Speter
4450276Speter/* Remove the last character from the match pattern buffer */
4550276Speter#define Remove_Character_From_Pattern(menu) \
4650276Speter  (menu)->pattern[--((menu)->pindex)] = '\0'
4750276Speter
4850276Speter/* Add a new character to the match pattern buffer */
4950276Speter#define Add_Character_To_Pattern(menu,ch) \
5050276Speter  { (menu)->pattern[((menu)->pindex)++] = (ch);\
5150276Speter    (menu)->pattern[(menu)->pindex] = '\0'; }
5250276Speter
5350276Speter/*---------------------------------------------------------------------------
5450276Speter|   Facility      :  libnmenu
5550276Speter|   Function      :  static bool Is_Sub_String(
5650276Speter|                           bool IgnoreCaseFlag,
5750276Speter|                           const char *part,
5850276Speter|                           const char *string)
5950276Speter|
6050276Speter|   Description   :  Checks whether or not part is a substring of string.
6150276Speter|
6250276Speter|   Return Values :  TRUE   - if it is a substring
6350276Speter|                    FALSE  - if it is not a substring
6450276Speter+--------------------------------------------------------------------------*/
65166124Srafanstatic bool
66166124SrafanIs_Sub_String(
67166124Srafan	       bool IgnoreCaseFlag,
68166124Srafan	       const char *part,
69166124Srafan	       const char *string
70166124Srafan)
7150276Speter{
72166124Srafan  assert(part && string);
73166124Srafan  if (IgnoreCaseFlag)
7450276Speter    {
75166124Srafan      while (*string && *part)
7650276Speter	{
77184989Srafan	  if (toupper(UChar(*string++)) != toupper(UChar(*part)))
78166124Srafan	    break;
7950276Speter	  part++;
8050276Speter	}
8150276Speter    }
8250276Speter  else
8350276Speter    {
84166124Srafan      while (*string && *part)
85166124Srafan	if (*part != *string++)
86166124Srafan	  break;
8750276Speter      part++;
8850276Speter    }
89166124Srafan  return ((*part) ? FALSE : TRUE);
9050276Speter}
9150276Speter
9250276Speter/*---------------------------------------------------------------------------
9350276Speter|   Facility      :  libnmenu
9450276Speter|   Function      :  int _nc_Match_Next_Character_In_Item_Name(
9550276Speter|                           MENU *menu,
9650276Speter|                           int  ch,
9750276Speter|                           ITEM **item)
9850276Speter|
9950276Speter|   Description   :  This internal routine is called for a menu positioned
10050276Speter|                    at an item with three different classes of characters:
10150276Speter|                       - a printable character; the character is added to
10250276Speter|                         the current pattern and the next item matching
10350276Speter|                         this pattern is searched.
10450276Speter|                       - NUL; the pattern stays as it is and the next item
10550276Speter|                         matching the pattern is searched
10650276Speter|                       - BS; the pattern stays as it is and the previous
10750276Speter|                         item matching the pattern is searched
10850276Speter|
10950276Speter|                       The item parameter contains on call a pointer to
11050276Speter|                       the item where the search starts. On return - if
11150276Speter|                       a match was found - it contains a pointer to the
11250276Speter|                       matching item.
11350276Speter|
11450276Speter|   Return Values :  E_OK        - an item matching the pattern was found
11550276Speter|                    E_NO_MATCH  - nothing found
11650276Speter+--------------------------------------------------------------------------*/
11776726SpeterNCURSES_EXPORT(int)
11876726Speter_nc_Match_Next_Character_In_Item_Name
119166124Srafan(MENU * menu, int ch, ITEM ** item)
12050276Speter{
12150276Speter  bool found = FALSE, passed = FALSE;
122166124Srafan  int idx, last;
12350276Speter
124166124Srafan  T((T_CALLED("_nc_Match_Next_Character(%p,%d,%p)"), menu, ch, item));
125166124Srafan
126166124Srafan  assert(menu && item && *item);
12750276Speter  idx = (*item)->index;
12850276Speter
129166124Srafan  if (ch && ch != BS)
13050276Speter    {
13150276Speter      /* if we become to long, we need no further checking : there can't be
132166124Srafan         a match ! */
133166124Srafan      if ((menu->pindex + 1) > menu->namelen)
13450276Speter	RETURN(E_NO_MATCH);
13550276Speter
136166124Srafan      Add_Character_To_Pattern(menu, ch);
13750276Speter      /* we artificially position one item back, because in the do...while
138166124Srafan         loop we start with the next item. This means, that with a new
139166124Srafan         pattern search we always start the scan with the actual item. If
140166124Srafan         we do a NEXT_PATTERN oder PREV_PATTERN search, we start with the
141166124Srafan         one after or before the actual item. */
14250276Speter      if (--idx < 0)
143166124Srafan	idx = menu->nitems - 1;
14450276Speter    }
14550276Speter
14650276Speter  last = idx;			/* this closes the cycle */
14750276Speter
148166124Srafan  do
149166124Srafan    {
150166124Srafan      if (ch == BS)
151166124Srafan	{			/* we have to go backward */
152166124Srafan	  if (--idx < 0)
153166124Srafan	    idx = menu->nitems - 1;
154166124Srafan	}
155166124Srafan      else
156166124Srafan	{			/* otherwise we always go forward */
157166124Srafan	  if (++idx >= menu->nitems)
158166124Srafan	    idx = 0;
159166124Srafan	}
160166124Srafan      if (Is_Sub_String((bool)((menu->opt & O_IGNORECASE) != 0),
161166124Srafan			menu->pattern,
162166124Srafan			menu->items[idx]->name.str)
16350276Speter	)
164166124Srafan	found = TRUE;
165166124Srafan      else
166166124Srafan	passed = TRUE;
167166124Srafan    }
168166124Srafan  while (!found && (idx != last));
16950276Speter
17050276Speter  if (found)
17150276Speter    {
172166124Srafan      if (!((idx == (*item)->index) && passed))
17350276Speter	{
17450276Speter	  *item = menu->items[idx];
17550276Speter	  RETURN(E_OK);
17650276Speter	}
17750276Speter      /* This point is reached, if we fully cycled through the item list
178166124Srafan         and the only match we found is the starting item. With a NEXT_PATTERN
179166124Srafan         or PREV_PATTERN scan this means, that there was no additional match.
180166124Srafan         If we searched with an expanded new pattern, we should never reach
181166124Srafan         this point, because if the expanded pattern matches also the actual
182166124Srafan         item we will find it in the first attempt (passed==FALSE) and we
183166124Srafan         will never cycle through the whole item array.
184166124Srafan       */
185166124Srafan      assert(ch == 0 || ch == BS);
18650276Speter    }
18750276Speter  else
18850276Speter    {
189166124Srafan      if (ch && ch != BS && menu->pindex > 0)
19050276Speter	{
19150276Speter	  /* if we had no match with a new pattern, we have to restore it */
19250276Speter	  Remove_Character_From_Pattern(menu);
19350276Speter	}
19450276Speter    }
19550276Speter  RETURN(E_NO_MATCH);
19650276Speter}
19750276Speter
19850276Speter/*---------------------------------------------------------------------------
19950276Speter|   Facility      :  libnmenu
20050276Speter|   Function      :  int menu_driver(MENU *menu, int c)
20150276Speter|
20250276Speter|   Description   :  Central dispatcher for the menu. Translates the logical
20350276Speter|                    request 'c' into a menu action.
20450276Speter|
20550276Speter|   Return Values :  E_OK            - success
20650276Speter|                    E_BAD_ARGUMENT  - invalid menu pointer
20750276Speter|                    E_BAD_STATE     - menu is in user hook routine
20850276Speter|                    E_NOT_POSTED    - menu is not posted
20950276Speter+--------------------------------------------------------------------------*/
21076726SpeterNCURSES_EXPORT(int)
211166124Srafanmenu_driver(MENU * menu, int c)
21250276Speter{
21350276Speter#define NAVIGATE(dir) \
21450276Speter  if (!item->dir)\
21550276Speter     result = E_REQUEST_DENIED;\
21650276Speter  else\
21750276Speter     item = item->dir
21850276Speter
21950276Speter  int result = E_OK;
22050276Speter  ITEM *item;
22150276Speter  int my_top_row, rdiff;
22250276Speter
223166124Srafan  T((T_CALLED("menu_driver(%p,%d)"), menu, c));
224166124Srafan
22550276Speter  if (!menu)
22650276Speter    RETURN(E_BAD_ARGUMENT);
22750276Speter
228166124Srafan  if (menu->status & _IN_DRIVER)
22950276Speter    RETURN(E_BAD_STATE);
230166124Srafan  if (!(menu->status & _POSTED))
23150276Speter    RETURN(E_NOT_POSTED);
23250276Speter
23350276Speter  item = menu->curitem;
23450276Speter
235166124Srafan  my_top_row = menu->toprow;
236166124Srafan  assert(item);
23750276Speter
238166124Srafan  if ((c > KEY_MAX) && (c <= MAX_MENU_COMMAND))
239166124Srafan    {
240166124Srafan      if (!((c == REQ_BACK_PATTERN)
241166124Srafan	    || (c == REQ_NEXT_MATCH) || (c == REQ_PREV_MATCH)))
242166124Srafan	{
243166124Srafan	  assert(menu->pattern);
244166124Srafan	  Reset_Pattern(menu);
245166124Srafan	}
24650276Speter
247166124Srafan      switch (c)
248166124Srafan	{
249166124Srafan	case REQ_LEFT_ITEM:
25050276Speter	    /*=================*/
251166124Srafan	  NAVIGATE(left);
252166124Srafan	  break;
25350276Speter
254166124Srafan	case REQ_RIGHT_ITEM:
25550276Speter	    /*==================*/
256166124Srafan	  NAVIGATE(right);
257166124Srafan	  break;
25850276Speter
259166124Srafan	case REQ_UP_ITEM:
26050276Speter	    /*===============*/
261166124Srafan	  NAVIGATE(up);
262166124Srafan	  break;
26350276Speter
264166124Srafan	case REQ_DOWN_ITEM:
26550276Speter	    /*=================*/
266166124Srafan	  NAVIGATE(down);
267166124Srafan	  break;
26850276Speter
269166124Srafan	case REQ_SCR_ULINE:
27050276Speter	    /*=================*/
27150276Speter	  if (my_top_row == 0 || !(item->up))
272166124Srafan	    result = E_REQUEST_DENIED;
273166124Srafan	  else
274166124Srafan	    {
275166124Srafan	      --my_top_row;
276166124Srafan	      item = item->up;
277166124Srafan	    }
278166124Srafan	  break;
27950276Speter
280166124Srafan	case REQ_SCR_DLINE:
28150276Speter	    /*=================*/
28250276Speter	  if ((my_top_row + menu->arows >= menu->rows) || !(item->down))
283166124Srafan	    {
284166124Srafan	      /* only if the menu has less items than rows, we can deny the
285166124Srafan	         request. Otherwise the epilogue of this routine adjusts the
286166124Srafan	         top row if necessary */
287166124Srafan	      result = E_REQUEST_DENIED;
288166124Srafan	    }
289166124Srafan	  else
290166124Srafan	    {
291166124Srafan	      my_top_row++;
29250276Speter	      item = item->down;
293166124Srafan	    }
294166124Srafan	  break;
29550276Speter
296166124Srafan	case REQ_SCR_DPAGE:
29750276Speter	    /*=================*/
29850276Speter	  rdiff = menu->rows - (menu->arows + my_top_row);
299166124Srafan	  if (rdiff > menu->arows)
300166124Srafan	    rdiff = menu->arows;
301166124Srafan	  if (rdiff <= 0)
302166124Srafan	    result = E_REQUEST_DENIED;
303166124Srafan	  else
304166124Srafan	    {
305166124Srafan	      my_top_row += rdiff;
306184989Srafan	      while (rdiff-- > 0 && item != 0 && item->down != 0)
307166124Srafan		item = item->down;
308166124Srafan	    }
309166124Srafan	  break;
31050276Speter
311166124Srafan	case REQ_SCR_UPAGE:
31250276Speter	    /*=================*/
31350276Speter	  rdiff = (menu->arows < my_top_row) ? menu->arows : my_top_row;
314166124Srafan	  if (rdiff <= 0)
315166124Srafan	    result = E_REQUEST_DENIED;
316166124Srafan	  else
317166124Srafan	    {
318166124Srafan	      my_top_row -= rdiff;
319184989Srafan	      while (rdiff-- > 0 && item != 0 && item->up != 0)
320166124Srafan		item = item->up;
321166124Srafan	    }
322166124Srafan	  break;
32350276Speter
324166124Srafan	case REQ_FIRST_ITEM:
32550276Speter	    /*==================*/
326166124Srafan	  item = menu->items[0];
327166124Srafan	  break;
32850276Speter
329166124Srafan	case REQ_LAST_ITEM:
33050276Speter	    /*=================*/
331166124Srafan	  item = menu->items[menu->nitems - 1];
332166124Srafan	  break;
33350276Speter
334166124Srafan	case REQ_NEXT_ITEM:
33550276Speter	    /*=================*/
336166124Srafan	  if ((item->index + 1) >= menu->nitems)
337166124Srafan	    {
338166124Srafan	      if (menu->opt & O_NONCYCLIC)
339166124Srafan		result = E_REQUEST_DENIED;
340166124Srafan	      else
341166124Srafan		item = menu->items[0];
342166124Srafan	    }
343166124Srafan	  else
344166124Srafan	    item = menu->items[item->index + 1];
345166124Srafan	  break;
34650276Speter
347166124Srafan	case REQ_PREV_ITEM:
34850276Speter	    /*=================*/
349166124Srafan	  if (item->index <= 0)
350166124Srafan	    {
351166124Srafan	      if (menu->opt & O_NONCYCLIC)
352166124Srafan		result = E_REQUEST_DENIED;
353166124Srafan	      else
354166124Srafan		item = menu->items[menu->nitems - 1];
355166124Srafan	    }
356166124Srafan	  else
357166124Srafan	    item = menu->items[item->index - 1];
358166124Srafan	  break;
35950276Speter
360166124Srafan	case REQ_TOGGLE_ITEM:
36150276Speter	    /*===================*/
362166124Srafan	  if (menu->opt & O_ONEVALUE)
363166124Srafan	    {
364166124Srafan	      result = E_REQUEST_DENIED;
365166124Srafan	    }
366166124Srafan	  else
367166124Srafan	    {
368166124Srafan	      if (menu->curitem->opt & O_SELECTABLE)
369166124Srafan		{
370166124Srafan		  menu->curitem->value = !menu->curitem->value;
371166124Srafan		  Move_And_Post_Item(menu, menu->curitem);
372166124Srafan		  _nc_Show_Menu(menu);
373166124Srafan		}
374166124Srafan	      else
375166124Srafan		result = E_NOT_SELECTABLE;
376166124Srafan	    }
377166124Srafan	  break;
37850276Speter
379166124Srafan	case REQ_CLEAR_PATTERN:
38050276Speter	    /*=====================*/
381166124Srafan	  /* already cleared in prologue */
382166124Srafan	  break;
38350276Speter
384166124Srafan	case REQ_BACK_PATTERN:
38550276Speter	    /*====================*/
386166124Srafan	  if (menu->pindex > 0)
387166124Srafan	    {
388166124Srafan	      assert(menu->pattern);
389166124Srafan	      Remove_Character_From_Pattern(menu);
390166124Srafan	      pos_menu_cursor(menu);
391166124Srafan	    }
392166124Srafan	  else
393166124Srafan	    result = E_REQUEST_DENIED;
394166124Srafan	  break;
39550276Speter
396166124Srafan	case REQ_NEXT_MATCH:
39750276Speter	    /*==================*/
398166124Srafan	  assert(menu->pattern);
399166124Srafan	  if (menu->pattern[0])
400166124Srafan	    result = _nc_Match_Next_Character_In_Item_Name(menu, 0, &item);
401166124Srafan	  else
402166124Srafan	    {
403166124Srafan	      if ((item->index + 1) < menu->nitems)
404166124Srafan		item = menu->items[item->index + 1];
405166124Srafan	      else
406166124Srafan		{
407166124Srafan		  if (menu->opt & O_NONCYCLIC)
408166124Srafan		    result = E_REQUEST_DENIED;
409166124Srafan		  else
410166124Srafan		    item = menu->items[0];
411166124Srafan		}
412166124Srafan	    }
413166124Srafan	  break;
41450276Speter
415166124Srafan	case REQ_PREV_MATCH:
41650276Speter	    /*==================*/
417166124Srafan	  assert(menu->pattern);
418166124Srafan	  if (menu->pattern[0])
419166124Srafan	    result = _nc_Match_Next_Character_In_Item_Name(menu, BS, &item);
420166124Srafan	  else
421166124Srafan	    {
422166124Srafan	      if (item->index)
423166124Srafan		item = menu->items[item->index - 1];
424166124Srafan	      else
425166124Srafan		{
426166124Srafan		  if (menu->opt & O_NONCYCLIC)
427166124Srafan		    result = E_REQUEST_DENIED;
428166124Srafan		  else
429166124Srafan		    item = menu->items[menu->nitems - 1];
430166124Srafan		}
431166124Srafan	    }
432166124Srafan	  break;
43350276Speter
434166124Srafan	default:
43550276Speter	    /*======*/
436166124Srafan	  result = E_UNKNOWN_COMMAND;
437166124Srafan	  break;
438166124Srafan	}
439166124Srafan    }
440166124Srafan  else
441166124Srafan    {				/* not a command */
442166124Srafan      if (!(c & ~((int)MAX_REGULAR_CHARACTER)) && isprint(UChar(c)))
443166124Srafan	result = _nc_Match_Next_Character_In_Item_Name(menu, c, &item);
44450276Speter#ifdef NCURSES_MOUSE_VERSION
445166124Srafan      else if (KEY_MOUSE == c)
446166124Srafan	{
447166124Srafan	  MEVENT event;
448166124Srafan	  WINDOW *uwin = Get_Menu_UserWin(menu);
44950276Speter
450166124Srafan	  getmouse(&event);
451166124Srafan	  if ((event.bstate & (BUTTON1_CLICKED |
452166124Srafan			       BUTTON1_DOUBLE_CLICKED |
453166124Srafan			       BUTTON1_TRIPLE_CLICKED))
454166124Srafan	      && wenclose(uwin, event.y, event.x))
455166124Srafan	    {			/* we react only if the click was in the userwin, that means
456166124Srafan				 * inside the menu display area or at the decoration window.
457166124Srafan				 */
458166124Srafan	      WINDOW *sub = Get_Menu_Window(menu);
459166124Srafan	      int ry = event.y, rx = event.x;	/* screen coordinates */
46050276Speter
461166124Srafan	      result = E_REQUEST_DENIED;
462166124Srafan	      if (mouse_trafo(&ry, &rx, FALSE))
463166124Srafan		{		/* rx, ry are now "curses" coordinates */
464166124Srafan		  if (ry < sub->_begy)
465166124Srafan		    {		/* we clicked above the display region; this is
466166124Srafan				 * interpreted as "scroll up" request
467166124Srafan				 */
468166124Srafan		      if (event.bstate & BUTTON1_CLICKED)
469166124Srafan			result = menu_driver(menu, REQ_SCR_ULINE);
470166124Srafan		      else if (event.bstate & BUTTON1_DOUBLE_CLICKED)
471166124Srafan			result = menu_driver(menu, REQ_SCR_UPAGE);
472166124Srafan		      else if (event.bstate & BUTTON1_TRIPLE_CLICKED)
473166124Srafan			result = menu_driver(menu, REQ_FIRST_ITEM);
474166124Srafan		      RETURN(result);
475166124Srafan		    }
476166124Srafan		  else if (ry > sub->_begy + sub->_maxy)
477166124Srafan		    {		/* we clicked below the display region; this is
478166124Srafan				 * interpreted as "scroll down" request
479166124Srafan				 */
480166124Srafan		      if (event.bstate & BUTTON1_CLICKED)
481166124Srafan			result = menu_driver(menu, REQ_SCR_DLINE);
482166124Srafan		      else if (event.bstate & BUTTON1_DOUBLE_CLICKED)
483166124Srafan			result = menu_driver(menu, REQ_SCR_DPAGE);
484166124Srafan		      else if (event.bstate & BUTTON1_TRIPLE_CLICKED)
485166124Srafan			result = menu_driver(menu, REQ_LAST_ITEM);
486166124Srafan		      RETURN(result);
487166124Srafan		    }
488166124Srafan		  else if (wenclose(sub, event.y, event.x))
489166124Srafan		    {		/* Inside the area we try to find the hit item */
490166124Srafan		      int i, x, y, err;
491166124Srafan
492166124Srafan		      ry = event.y;
493166124Srafan		      rx = event.x;
494166124Srafan		      if (wmouse_trafo(sub, &ry, &rx, FALSE))
495166124Srafan			{
496166124Srafan			  for (i = 0; i < menu->nitems; i++)
497166124Srafan			    {
498166124Srafan			      err = _nc_menu_cursor_pos(menu, menu->items[i],
499166124Srafan							&y, &x);
500166124Srafan			      if (E_OK == err)
501166124Srafan				{
502166124Srafan				  if ((ry == y) &&
503166124Srafan				      (rx >= x) &&
504166124Srafan				      (rx < x + menu->itemlen))
505166124Srafan				    {
506166124Srafan				      item = menu->items[i];
507166124Srafan				      result = E_OK;
508166124Srafan				      break;
509166124Srafan				    }
510166124Srafan				}
511166124Srafan			    }
512166124Srafan			  if (E_OK == result)
513166124Srafan			    {	/* We found an item, now we can handle the click.
51450276Speter				 * A single click just positions the menu cursor
51550276Speter				 * to the clicked item. A double click toggles
51650276Speter				 * the item.
51750276Speter				 */
518166124Srafan			      if (event.bstate & BUTTON1_DOUBLE_CLICKED)
519166124Srafan				{
520166124Srafan				  _nc_New_TopRow_and_CurrentItem(menu,
521166124Srafan								 my_top_row,
522166124Srafan								 item);
523166124Srafan				  menu_driver(menu, REQ_TOGGLE_ITEM);
524166124Srafan				  result = E_UNKNOWN_COMMAND;
525166124Srafan				}
526166124Srafan			    }
527166124Srafan			}
528166124Srafan		    }
529166124Srafan		}
530166124Srafan	    }
531166124Srafan	  else
532166124Srafan	    result = E_REQUEST_DENIED;
533166124Srafan	}
53450276Speter#endif /* NCURSES_MOUSE_VERSION */
535166124Srafan      else
536166124Srafan	result = E_UNKNOWN_COMMAND;
537166124Srafan    }
53850276Speter
539166124Srafan  if (E_OK == result)
54050276Speter    {
541166124Srafan      /* Adjust the top row if it turns out that the current item unfortunately
542166124Srafan         doesn't appear in the menu window */
543166124Srafan      if (item->y < my_top_row)
544166124Srafan	my_top_row = item->y;
545166124Srafan      else if (item->y >= (my_top_row + menu->arows))
546166124Srafan	my_top_row = item->y - menu->arows + 1;
54750276Speter
548166124Srafan      _nc_New_TopRow_and_CurrentItem(menu, my_top_row, item);
54950276Speter
55050276Speter    }
55150276Speter
55250276Speter  RETURN(result);
55350276Speter}
55450276Speter
55550276Speter/* m_driver.c ends here */
556