File: | src/lib/libmenu/m_driver.c |
Warning: | line 545, column 11 Access to field 'y' results in a dereference of a null pointer (loaded from variable 'item') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: m_driver.c,v 1.8 2010/01/12 23:22:07 nicm Exp $ */ | |||
2 | ||||
3 | /**************************************************************************** | |||
4 | * Copyright (c) 1998-2005,2008 Free Software Foundation, Inc. * | |||
5 | * * | |||
6 | * Permission is hereby granted, free of charge, to any person obtaining a * | |||
7 | * copy of this software and associated documentation files (the * | |||
8 | * "Software"), to deal in the Software without restriction, including * | |||
9 | * without limitation the rights to use, copy, modify, merge, publish, * | |||
10 | * distribute, distribute with modifications, sublicense, and/or sell * | |||
11 | * copies of the Software, and to permit persons to whom the Software is * | |||
12 | * furnished to do so, subject to the following conditions: * | |||
13 | * * | |||
14 | * The above copyright notice and this permission notice shall be included * | |||
15 | * in all copies or substantial portions of the Software. * | |||
16 | * * | |||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * | |||
18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * | |||
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * | |||
20 | * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * | |||
21 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * | |||
22 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * | |||
23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * | |||
24 | * * | |||
25 | * Except as contained in this notice, the name(s) of the above copyright * | |||
26 | * holders shall not be used in advertising or otherwise to promote the * | |||
27 | * sale, use or other dealings in this Software without prior written * | |||
28 | * authorization. * | |||
29 | ****************************************************************************/ | |||
30 | ||||
31 | /**************************************************************************** | |||
32 | * Author: Juergen Pfeifer, 1995,1997 * | |||
33 | ****************************************************************************/ | |||
34 | ||||
35 | /*************************************************************************** | |||
36 | * Module m_driver * | |||
37 | * Central dispatching routine * | |||
38 | ***************************************************************************/ | |||
39 | ||||
40 | #include "menu.priv.h" | |||
41 | ||||
42 | MODULE_ID("$Id: m_driver.c,v 1.8 2010/01/12 23:22:07 nicm Exp $") | |||
43 | ||||
44 | /* Macros */ | |||
45 | ||||
46 | /* Remove the last character from the match pattern buffer */ | |||
47 | #define Remove_Character_From_Pattern(menu)(menu)->pattern[--((menu)->pindex)] = '\0' \ | |||
48 | (menu)->pattern[--((menu)->pindex)] = '\0' | |||
49 | ||||
50 | /* Add a new character to the match pattern buffer */ | |||
51 | #define Add_Character_To_Pattern(menu,ch){ (menu)->pattern[((menu)->pindex)++] = (ch); (menu)-> pattern[(menu)->pindex] = '\0'; } \ | |||
52 | { (menu)->pattern[((menu)->pindex)++] = (ch);\ | |||
53 | (menu)->pattern[(menu)->pindex] = '\0'; } | |||
54 | ||||
55 | /*--------------------------------------------------------------------------- | |||
56 | | Facility : libnmenu | |||
57 | | Function : static bool Is_Sub_String( | |||
58 | | bool IgnoreCaseFlag, | |||
59 | | const char *part, | |||
60 | | const char *string) | |||
61 | | | |||
62 | | Description : Checks whether or not part is a substring of string. | |||
63 | | | |||
64 | | Return Values : TRUE - if it is a substring | |||
65 | | FALSE - if it is not a substring | |||
66 | +--------------------------------------------------------------------------*/ | |||
67 | static bool_Bool | |||
68 | Is_Sub_String( | |||
69 | bool_Bool IgnoreCaseFlag, | |||
70 | const char *part, | |||
71 | const char *string | |||
72 | ) | |||
73 | { | |||
74 | assert(part && string)((void)0); | |||
75 | if (IgnoreCaseFlag) | |||
76 | { | |||
77 | while (*string && *part) | |||
78 | { | |||
79 | if (toupper(UChar(*string++)((unsigned char)(*string++))) != toupper(UChar(*part)((unsigned char)(*part)))) | |||
80 | break; | |||
81 | part++; | |||
82 | } | |||
83 | } | |||
84 | else | |||
85 | { | |||
86 | while (*string && *part) | |||
87 | if (*part != *string++) | |||
88 | break; | |||
89 | part++; | |||
90 | } | |||
91 | return ((*part) ? FALSE0 : TRUE1); | |||
92 | } | |||
93 | ||||
94 | /*--------------------------------------------------------------------------- | |||
95 | | Facility : libnmenu | |||
96 | | Function : int _nc_Match_Next_Character_In_Item_Name( | |||
97 | | MENU *menu, | |||
98 | | int ch, | |||
99 | | ITEM **item) | |||
100 | | | |||
101 | | Description : This internal routine is called for a menu positioned | |||
102 | | at an item with three different classes of characters: | |||
103 | | - a printable character; the character is added to | |||
104 | | the current pattern and the next item matching | |||
105 | | this pattern is searched. | |||
106 | | - NUL; the pattern stays as it is and the next item | |||
107 | | matching the pattern is searched | |||
108 | | - BS; the pattern stays as it is and the previous | |||
109 | | item matching the pattern is searched | |||
110 | | | |||
111 | | The item parameter contains on call a pointer to | |||
112 | | the item where the search starts. On return - if | |||
113 | | a match was found - it contains a pointer to the | |||
114 | | matching item. | |||
115 | | | |||
116 | | Return Values : E_OK - an item matching the pattern was found | |||
117 | | E_NO_MATCH - nothing found | |||
118 | +--------------------------------------------------------------------------*/ | |||
119 | NCURSES_EXPORT(int)int | |||
120 | _nc_Match_Next_Character_In_Item_Name | |||
121 | (MENU * menu, int ch, ITEM ** item) | |||
122 | { | |||
123 | bool_Bool found = FALSE0, passed = FALSE0; | |||
124 | int idx, last; | |||
125 | ||||
126 | T((T_CALLED("_nc_Match_Next_Character(%p,%d,%p)"), menu, ch, item)); | |||
127 | ||||
128 | assert(menu && item && *item)((void)0); | |||
129 | idx = (*item)->index; | |||
130 | ||||
131 | if (ch && ch != BS(8)) | |||
132 | { | |||
133 | /* if we become to long, we need no further checking : there can't be | |||
134 | a match ! */ | |||
135 | if ((menu->pindex + 1) > menu->namelen) | |||
136 | RETURN(E_NO_MATCH)return( ((*__errno())=((-9))) ); | |||
137 | ||||
138 | Add_Character_To_Pattern(menu, ch){ (menu)->pattern[((menu)->pindex)++] = (ch); (menu)-> pattern[(menu)->pindex] = '\0'; }; | |||
139 | /* we artificially position one item back, because in the do...while | |||
140 | loop we start with the next item. This means, that with a new | |||
141 | pattern search we always start the scan with the actual item. If | |||
142 | we do a NEXT_PATTERN oder PREV_PATTERN search, we start with the | |||
143 | one after or before the actual item. */ | |||
144 | if (--idx < 0) | |||
145 | idx = menu->nitems - 1; | |||
146 | } | |||
147 | ||||
148 | last = idx; /* this closes the cycle */ | |||
149 | ||||
150 | do | |||
151 | { | |||
152 | if (ch == BS(8)) | |||
153 | { /* we have to go backward */ | |||
154 | if (--idx < 0) | |||
155 | idx = menu->nitems - 1; | |||
156 | } | |||
157 | else | |||
158 | { /* otherwise we always go forward */ | |||
159 | if (++idx >= menu->nitems) | |||
160 | idx = 0; | |||
161 | } | |||
162 | if (Is_Sub_String((bool_Bool)((menu->opt & O_IGNORECASE(0x08)) != 0), | |||
163 | menu->pattern, | |||
164 | menu->items[idx]->name.str) | |||
165 | ) | |||
166 | found = TRUE1; | |||
167 | else | |||
168 | passed = TRUE1; | |||
169 | } | |||
170 | while (!found && (idx != last)); | |||
171 | ||||
172 | if (found) | |||
173 | { | |||
174 | if (!((idx == (*item)->index) && passed)) | |||
175 | { | |||
176 | *item = menu->items[idx]; | |||
177 | RETURN(E_OK)return( ((*__errno())=((0))) ); | |||
178 | } | |||
179 | /* This point is reached, if we fully cycled through the item list | |||
180 | and the only match we found is the starting item. With a NEXT_PATTERN | |||
181 | or PREV_PATTERN scan this means, that there was no additional match. | |||
182 | If we searched with an expanded new pattern, we should never reach | |||
183 | this point, because if the expanded pattern matches also the actual | |||
184 | item we will find it in the first attempt (passed==FALSE) and we | |||
185 | will never cycle through the whole item array. | |||
186 | */ | |||
187 | assert(ch == 0 || ch == BS)((void)0); | |||
188 | } | |||
189 | else | |||
190 | { | |||
191 | if (ch && ch != BS(8) && menu->pindex > 0) | |||
192 | { | |||
193 | /* if we had no match with a new pattern, we have to restore it */ | |||
194 | Remove_Character_From_Pattern(menu)(menu)->pattern[--((menu)->pindex)] = '\0'; | |||
195 | } | |||
196 | } | |||
197 | RETURN(E_NO_MATCH)return( ((*__errno())=((-9))) ); | |||
198 | } | |||
199 | ||||
200 | /*--------------------------------------------------------------------------- | |||
201 | | Facility : libnmenu | |||
202 | | Function : int menu_driver(MENU *menu, int c) | |||
203 | | | |||
204 | | Description : Central dispatcher for the menu. Translates the logical | |||
205 | | request 'c' into a menu action. | |||
206 | | | |||
207 | | Return Values : E_OK - success | |||
208 | | E_BAD_ARGUMENT - invalid menu pointer | |||
209 | | E_BAD_STATE - menu is in user hook routine | |||
210 | | E_NOT_POSTED - menu is not posted | |||
211 | +--------------------------------------------------------------------------*/ | |||
212 | NCURSES_EXPORT(int)int | |||
213 | menu_driver(MENU * menu, int c) | |||
214 | { | |||
215 | #define NAVIGATE(dir)if (!item->dir) result = (-12); else item = item->dir \ | |||
216 | if (!item->dir)\ | |||
217 | result = E_REQUEST_DENIED(-12);\ | |||
218 | else\ | |||
219 | item = item->dir | |||
220 | ||||
221 | int result = E_OK(0); | |||
222 | ITEM *item; | |||
223 | int my_top_row, rdiff; | |||
224 | ||||
225 | T((T_CALLED("menu_driver(%p,%d)"), menu, c)); | |||
226 | ||||
227 | if (!menu) | |||
| ||||
228 | RETURN(E_BAD_ARGUMENT)return( ((*__errno())=((-2))) ); | |||
229 | ||||
230 | if (menu->status & _IN_DRIVER(0x02U)) | |||
231 | RETURN(E_BAD_STATE)return( ((*__errno())=((-5))) ); | |||
232 | if (!(menu->status & _POSTED(0x01U))) | |||
233 | RETURN(E_NOT_POSTED)return( ((*__errno())=((-7))) ); | |||
234 | ||||
235 | item = menu->curitem; | |||
236 | ||||
237 | my_top_row = menu->toprow; | |||
238 | assert(item)((void)0); | |||
239 | ||||
240 | if ((c > KEY_MAX0777) && (c <= MAX_MENU_COMMAND(0777 + 17))) | |||
241 | { | |||
242 | if (!((c == REQ_BACK_PATTERN(0777 + 15)) | |||
243 | || (c == REQ_NEXT_MATCH(0777 + 16)) || (c == REQ_PREV_MATCH(0777 + 17)))) | |||
244 | { | |||
245 | assert(menu->pattern)((void)0); | |||
246 | Reset_Pattern(menu){ (menu)->pindex = 0; (menu)->pattern[0] = '\0'; }; | |||
247 | } | |||
248 | ||||
249 | switch (c) | |||
250 | { | |||
251 | case REQ_LEFT_ITEM(0777 + 1): | |||
252 | /*=================*/ | |||
253 | NAVIGATE(left)if (!item->left) result = (-12); else item = item->left; | |||
254 | break; | |||
255 | ||||
256 | case REQ_RIGHT_ITEM(0777 + 2): | |||
257 | /*==================*/ | |||
258 | NAVIGATE(right)if (!item->right) result = (-12); else item = item->right; | |||
259 | break; | |||
260 | ||||
261 | case REQ_UP_ITEM(0777 + 3): | |||
262 | /*===============*/ | |||
263 | NAVIGATE(up)if (!item->up) result = (-12); else item = item->up; | |||
264 | break; | |||
265 | ||||
266 | case REQ_DOWN_ITEM(0777 + 4): | |||
267 | /*=================*/ | |||
268 | NAVIGATE(down)if (!item->down) result = (-12); else item = item->down; | |||
269 | break; | |||
270 | ||||
271 | case REQ_SCR_ULINE(0777 + 5): | |||
272 | /*=================*/ | |||
273 | if (my_top_row == 0 || !(item->up)) | |||
274 | result = E_REQUEST_DENIED(-12); | |||
275 | else | |||
276 | { | |||
277 | --my_top_row; | |||
278 | item = item->up; | |||
279 | } | |||
280 | break; | |||
281 | ||||
282 | case REQ_SCR_DLINE(0777 + 6): | |||
283 | /*=================*/ | |||
284 | if ((my_top_row + menu->arows >= menu->rows) || !(item->down)) | |||
285 | { | |||
286 | /* only if the menu has less items than rows, we can deny the | |||
287 | request. Otherwise the epilogue of this routine adjusts the | |||
288 | top row if necessary */ | |||
289 | result = E_REQUEST_DENIED(-12); | |||
290 | } | |||
291 | else | |||
292 | { | |||
293 | my_top_row++; | |||
294 | item = item->down; | |||
295 | } | |||
296 | break; | |||
297 | ||||
298 | case REQ_SCR_DPAGE(0777 + 7): | |||
299 | /*=================*/ | |||
300 | rdiff = menu->rows - (menu->arows + my_top_row); | |||
301 | if (rdiff > menu->arows) | |||
302 | rdiff = menu->arows; | |||
303 | if (rdiff <= 0) | |||
304 | result = E_REQUEST_DENIED(-12); | |||
305 | else | |||
306 | { | |||
307 | my_top_row += rdiff; | |||
308 | while (rdiff-- > 0 && item != 0 && item->down != 0) | |||
309 | item = item->down; | |||
310 | } | |||
311 | break; | |||
312 | ||||
313 | case REQ_SCR_UPAGE(0777 + 8): | |||
314 | /*=================*/ | |||
315 | rdiff = (menu->arows < my_top_row) ? menu->arows : my_top_row; | |||
316 | if (rdiff <= 0) | |||
317 | result = E_REQUEST_DENIED(-12); | |||
318 | else | |||
319 | { | |||
320 | my_top_row -= rdiff; | |||
321 | while (rdiff-- > 0 && item != 0 && item->up != 0) | |||
322 | item = item->up; | |||
323 | } | |||
324 | break; | |||
325 | ||||
326 | case REQ_FIRST_ITEM(0777 + 9): | |||
327 | /*==================*/ | |||
328 | item = menu->items[0]; | |||
329 | break; | |||
330 | ||||
331 | case REQ_LAST_ITEM(0777 + 10): | |||
332 | /*=================*/ | |||
333 | item = menu->items[menu->nitems - 1]; | |||
334 | break; | |||
335 | ||||
336 | case REQ_NEXT_ITEM(0777 + 11): | |||
337 | /*=================*/ | |||
338 | if ((item->index + 1) >= menu->nitems) | |||
339 | { | |||
340 | if (menu->opt & O_NONCYCLIC(0x20)) | |||
341 | result = E_REQUEST_DENIED(-12); | |||
342 | else | |||
343 | item = menu->items[0]; | |||
344 | } | |||
345 | else | |||
346 | item = menu->items[item->index + 1]; | |||
347 | break; | |||
348 | ||||
349 | case REQ_PREV_ITEM(0777 + 12): | |||
350 | /*=================*/ | |||
351 | if (item->index <= 0) | |||
352 | { | |||
353 | if (menu->opt & O_NONCYCLIC(0x20)) | |||
354 | result = E_REQUEST_DENIED(-12); | |||
355 | else | |||
356 | item = menu->items[menu->nitems - 1]; | |||
357 | } | |||
358 | else | |||
359 | item = menu->items[item->index - 1]; | |||
360 | break; | |||
361 | ||||
362 | case REQ_TOGGLE_ITEM(0777 + 13): | |||
363 | /*===================*/ | |||
364 | if (menu->opt & O_ONEVALUE(0x01)) | |||
365 | { | |||
366 | result = E_REQUEST_DENIED(-12); | |||
367 | } | |||
368 | else | |||
369 | { | |||
370 | if (menu->curitem->opt & O_SELECTABLE(0x01)) | |||
371 | { | |||
372 | menu->curitem->value = !menu->curitem->value; | |||
373 | Move_And_Post_Item(menu, menu->curitem){wmove((menu)->win,(menu)->spc_rows*(menu->curitem)-> y,((menu)->itemlen+(menu)->spc_cols)*(menu->curitem) ->x); _nc_Post_Item((menu),(menu->curitem));}; | |||
374 | _nc_Show_Menu(menu); | |||
375 | } | |||
376 | else | |||
377 | result = E_NOT_SELECTABLE(-10); | |||
378 | } | |||
379 | break; | |||
380 | ||||
381 | case REQ_CLEAR_PATTERN(0777 + 14): | |||
382 | /*=====================*/ | |||
383 | /* already cleared in prologue */ | |||
384 | break; | |||
385 | ||||
386 | case REQ_BACK_PATTERN(0777 + 15): | |||
387 | /*====================*/ | |||
388 | if (menu->pindex > 0) | |||
389 | { | |||
390 | assert(menu->pattern)((void)0); | |||
391 | Remove_Character_From_Pattern(menu)(menu)->pattern[--((menu)->pindex)] = '\0'; | |||
392 | pos_menu_cursor(menu); | |||
393 | } | |||
394 | else | |||
395 | result = E_REQUEST_DENIED(-12); | |||
396 | break; | |||
397 | ||||
398 | case REQ_NEXT_MATCH(0777 + 16): | |||
399 | /*==================*/ | |||
400 | assert(menu->pattern)((void)0); | |||
401 | if (menu->pattern[0]) | |||
402 | result = _nc_Match_Next_Character_In_Item_Name(menu, 0, &item); | |||
403 | else | |||
404 | { | |||
405 | if ((item->index + 1) < menu->nitems) | |||
406 | item = menu->items[item->index + 1]; | |||
407 | else | |||
408 | { | |||
409 | if (menu->opt & O_NONCYCLIC(0x20)) | |||
410 | result = E_REQUEST_DENIED(-12); | |||
411 | else | |||
412 | item = menu->items[0]; | |||
413 | } | |||
414 | } | |||
415 | break; | |||
416 | ||||
417 | case REQ_PREV_MATCH(0777 + 17): | |||
418 | /*==================*/ | |||
419 | assert(menu->pattern)((void)0); | |||
420 | if (menu->pattern[0]) | |||
421 | result = _nc_Match_Next_Character_In_Item_Name(menu, BS(8), &item); | |||
422 | else | |||
423 | { | |||
424 | if (item->index) | |||
425 | item = menu->items[item->index - 1]; | |||
426 | else | |||
427 | { | |||
428 | if (menu->opt & O_NONCYCLIC(0x20)) | |||
429 | result = E_REQUEST_DENIED(-12); | |||
430 | else | |||
431 | item = menu->items[menu->nitems - 1]; | |||
432 | } | |||
433 | } | |||
434 | break; | |||
435 | ||||
436 | default: | |||
437 | /*======*/ | |||
438 | result = E_UNKNOWN_COMMAND(-8); | |||
439 | break; | |||
440 | } | |||
441 | } | |||
442 | else | |||
443 | { /* not a command */ | |||
444 | if (!(c & ~((int)MAX_REGULAR_CHARACTER(0xff))) && isprint(UChar(c)((unsigned char)(c)))) | |||
445 | result = _nc_Match_Next_Character_In_Item_Name(menu, c, &item); | |||
446 | #ifdef NCURSES_MOUSE_VERSION1 | |||
447 | else if (KEY_MOUSE0631 == c) | |||
448 | { | |||
449 | MEVENT event; | |||
450 | WINDOW *uwin = Get_Menu_UserWin(menu)((menu)->userwin ? (menu)->userwin : stdscr); | |||
451 | ||||
452 | getmouse(&event); | |||
453 | if ((event.bstate & (BUTTON1_CLICKED((004L) << (((1) - 1) * 6)) | | |||
454 | BUTTON1_DOUBLE_CLICKED((010L) << (((1) - 1) * 6)) | | |||
455 | BUTTON1_TRIPLE_CLICKED((020L) << (((1) - 1) * 6)))) | |||
456 | && wenclose(uwin, event.y, event.x)) | |||
457 | { /* we react only if the click was in the userwin, that means | |||
458 | * inside the menu display area or at the decoration window. | |||
459 | */ | |||
460 | WINDOW *sub = Get_Menu_Window(menu)((menu)->usersub ? (menu)->usersub : ((menu)->userwin ? (menu)->userwin : stdscr)); | |||
461 | int ry = event.y, rx = event.x; /* screen coordinates */ | |||
462 | ||||
463 | result = E_REQUEST_DENIED(-12); | |||
464 | if (mouse_trafo(&ry, &rx, FALSE)wmouse_trafo(stdscr,&ry,&rx,0)) | |||
465 | { /* rx, ry are now "curses" coordinates */ | |||
466 | if (ry < sub->_begy) | |||
467 | { /* we clicked above the display region; this is | |||
468 | * interpreted as "scroll up" request | |||
469 | */ | |||
470 | if (event.bstate & BUTTON1_CLICKED((004L) << (((1) - 1) * 6))) | |||
471 | result = menu_driver(menu, REQ_SCR_ULINE(0777 + 5)); | |||
472 | else if (event.bstate & BUTTON1_DOUBLE_CLICKED((010L) << (((1) - 1) * 6))) | |||
473 | result = menu_driver(menu, REQ_SCR_UPAGE(0777 + 8)); | |||
474 | else if (event.bstate & BUTTON1_TRIPLE_CLICKED((020L) << (((1) - 1) * 6))) | |||
475 | result = menu_driver(menu, REQ_FIRST_ITEM(0777 + 9)); | |||
476 | RETURN(result)return( ((*__errno())=(result)) ); | |||
477 | } | |||
478 | else if (ry > sub->_begy + sub->_maxy) | |||
479 | { /* we clicked below the display region; this is | |||
480 | * interpreted as "scroll down" request | |||
481 | */ | |||
482 | if (event.bstate & BUTTON1_CLICKED((004L) << (((1) - 1) * 6))) | |||
483 | result = menu_driver(menu, REQ_SCR_DLINE(0777 + 6)); | |||
484 | else if (event.bstate & BUTTON1_DOUBLE_CLICKED((010L) << (((1) - 1) * 6))) | |||
485 | result = menu_driver(menu, REQ_SCR_DPAGE(0777 + 7)); | |||
486 | else if (event.bstate & BUTTON1_TRIPLE_CLICKED((020L) << (((1) - 1) * 6))) | |||
487 | result = menu_driver(menu, REQ_LAST_ITEM(0777 + 10)); | |||
488 | RETURN(result)return( ((*__errno())=(result)) ); | |||
489 | } | |||
490 | else if (wenclose(sub, event.y, event.x)) | |||
491 | { /* Inside the area we try to find the hit item */ | |||
492 | int i, x, y, err; | |||
493 | ||||
494 | ry = event.y; | |||
495 | rx = event.x; | |||
496 | if (wmouse_trafo(sub, &ry, &rx, FALSE0)) | |||
497 | { | |||
498 | for (i = 0; i < menu->nitems; i++) | |||
499 | { | |||
500 | err = _nc_menu_cursor_pos(menu, menu->items[i], | |||
501 | &y, &x); | |||
502 | if (E_OK(0) == err) | |||
503 | { | |||
504 | if ((ry == y) && | |||
505 | (rx >= x) && | |||
506 | (rx < x + menu->itemlen)) | |||
507 | { | |||
508 | item = menu->items[i]; | |||
509 | result = E_OK(0); | |||
510 | break; | |||
511 | } | |||
512 | } | |||
513 | } | |||
514 | if (E_OK(0) == result) | |||
515 | { /* We found an item, now we can handle the click. | |||
516 | * A single click just positions the menu cursor | |||
517 | * to the clicked item. A double click toggles | |||
518 | * the item. | |||
519 | */ | |||
520 | if (event.bstate & BUTTON1_DOUBLE_CLICKED((010L) << (((1) - 1) * 6))) | |||
521 | { | |||
522 | _nc_New_TopRow_and_CurrentItem(menu, | |||
523 | my_top_row, | |||
524 | item); | |||
525 | menu_driver(menu, REQ_TOGGLE_ITEM(0777 + 13)); | |||
526 | result = E_UNKNOWN_COMMAND(-8); | |||
527 | } | |||
528 | } | |||
529 | } | |||
530 | } | |||
531 | } | |||
532 | } | |||
533 | else | |||
534 | result = E_REQUEST_DENIED(-12); | |||
535 | } | |||
536 | #endif /* NCURSES_MOUSE_VERSION */ | |||
537 | else | |||
538 | result = E_UNKNOWN_COMMAND(-8); | |||
539 | } | |||
540 | ||||
541 | if (E_OK(0) == result
| |||
542 | { | |||
543 | /* Adjust the top row if it turns out that the current item unfortunately | |||
544 | doesn't appear in the menu window */ | |||
545 | if (item->y < my_top_row) | |||
| ||||
546 | my_top_row = item->y; | |||
547 | else if (item->y >= (my_top_row + menu->arows)) | |||
548 | my_top_row = item->y - menu->arows + 1; | |||
549 | ||||
550 | _nc_New_TopRow_and_CurrentItem(menu, my_top_row, item); | |||
551 | ||||
552 | } | |||
553 | ||||
554 | RETURN(result)return( ((*__errno())=(result)) ); | |||
555 | } | |||
556 | ||||
557 | /* m_driver.c ends here */ |