diff options
Diffstat (limited to 'test/demo_menus.c')
-rw-r--r-- | test/demo_menus.c | 900 |
1 files changed, 0 insertions, 900 deletions
diff --git a/test/demo_menus.c b/test/demo_menus.c deleted file mode 100644 index 4d553e2..0000000 --- a/test/demo_menus.c +++ /dev/null @@ -1,900 +0,0 @@ -/**************************************************************************** - * Copyright (c) 2005-2007,2008 Free Software Foundation, Inc. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a * - * copy of this software and associated documentation files (the * - * "Software"), to deal in the Software without restriction, including * - * without limitation the rights to use, copy, modify, merge, publish, * - * distribute, distribute with modifications, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included * - * in all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * - * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - * * - * Except as contained in this notice, the name(s) of the above copyright * - * holders shall not be used in advertising or otherwise to promote the * - * sale, use or other dealings in this Software without prior written * - * authorization. * - ****************************************************************************/ -/* - * $Id: demo_menus.c,v 1.28 2008/08/23 20:31:54 tom Exp $ - * - * Demonstrate a variety of functions from the menu library. - * Thomas Dickey - 2005/4/9 - */ -/* -item_description - -item_init - -item_opts - -item_opts_off - -item_opts_on - -item_term - -item_userptr - -item_visible - -menu_back - -menu_fore - -menu_format - -menu_grey - -menu_init - -menu_opts - -menu_pad - -menu_request_by_name - -menu_request_name - -menu_sub - -menu_term - -menu_userptr - -set_current_item - -set_item_init - -set_item_opts - -set_item_term - -set_item_userptr - -set_menu_grey - -set_menu_init - -set_menu_items - -set_menu_opts - -set_menu_pad - -set_menu_pattern - -set_menu_spacing - -set_menu_term - -set_menu_userptr - -set_top_row - -top_row - -*/ - -#include <test.priv.h> - -#if USE_LIBMENU - -#include <menu.h> - -#include <sys/types.h> -#include <sys/stat.h> - -#ifdef NCURSES_VERSION -#ifdef TRACE -static unsigned save_trace = TRACE_ORDINARY | TRACE_CALLS; -extern unsigned _nc_tracing; -static MENU *mpTrace; -#endif -#else -#undef TRACE -#endif - -typedef enum { - eBanner = -1 - ,eFile - ,eSelect -#ifdef TRACE - ,eTrace -#endif - ,eMAX -} MenuNo; - -#define okMenuNo(n) (((n) > eBanner) && ((n) < eMAX)) - -#define MENU_Y 1 - -static MENU *mpBanner; -static MENU *mpFile; -static MENU *mpSelect; - -static bool loaded_file = FALSE; - -#if !HAVE_STRDUP -#define strdup my_strdup -static char * -strdup(char *s) -{ - char *p = typeMalloc(char, strlen(s) + 1); - if (p) - strcpy(p, s); - return (p); -} -#endif /* not HAVE_STRDUP */ - -/* Common function to allow ^T to toggle trace-mode in the middle of a test - * so that trace-files can be made smaller. - */ -static int -wGetchar(WINDOW *win) -{ - int c; -#ifdef TRACE - while ((c = wgetch(win)) == CTRL('T')) { - if (_nc_tracing) { - save_trace = _nc_tracing; - Trace(("TOGGLE-TRACING OFF")); - _nc_tracing = 0; - } else { - _nc_tracing = save_trace; - } - trace(_nc_tracing); - if (_nc_tracing) - Trace(("TOGGLE-TRACING ON")); - } -#else - c = wgetch(win); -#endif - return c; -} -#define Getchar() wGetchar(stdscr) - -static int -menu_virtualize(int c) -{ - int result; - - if (c == '\n' || c == KEY_EXIT) - result = (MAX_COMMAND + 1); - else if (c == 'u') - result = (REQ_SCR_ULINE); - else if (c == 'd') - result = (REQ_SCR_DLINE); - else if (c == 'b' || c == KEY_NPAGE) - result = (REQ_SCR_UPAGE); - else if (c == 'f' || c == KEY_PPAGE) - result = (REQ_SCR_DPAGE); - else if (c == 'l' || c == KEY_LEFT || c == KEY_BTAB) - result = (REQ_LEFT_ITEM); - else if (c == 'n' || c == KEY_DOWN) - result = (REQ_NEXT_ITEM); - else if (c == 'p' || c == KEY_UP) - result = (REQ_PREV_ITEM); - else if (c == 'r' || c == KEY_RIGHT || c == '\t') - result = (REQ_RIGHT_ITEM); - else if (c == ' ') - result = (REQ_TOGGLE_ITEM); - else { - if (c != KEY_MOUSE) - beep(); - result = (c); - } - return result; -} - -static int -menu_getc(MENU * m) -{ - return wGetchar(menu_win(m)); -} - -static int -menu_offset(MenuNo number) -{ - int result = 0; - - if (okMenuNo(number)) { - int spc_desc, spc_rows, spc_cols; - -#ifdef NCURSES_VERSION - menu_spacing(mpBanner, &spc_desc, &spc_rows, &spc_cols); -#else - spc_rows = 0; -#endif - - /* FIXME: MENU.itemlen seems the only way to get actual width of items */ - result = (number - (eBanner + 1)) * (mpBanner->itemlen + spc_rows); - } - return result; -} - -static MENU * -menu_create(ITEM ** items, int count, int ncols, MenuNo number) -{ - MENU *result; - WINDOW *menuwin; - int mrows, mcols; - int y = okMenuNo(number) ? MENU_Y : 0; - int x = menu_offset(number); - int margin = (y == MENU_Y) ? 1 : 0; - int maxcol = (ncols + x) < COLS ? ncols : (COLS - x - 1); - int maxrow = (count + 1) / ncols; - - if ((maxrow + y) >= (LINES - 4)) - maxrow = LINES - 4 - y; - - result = new_menu(items); - - if (has_colors()) { - set_menu_fore(result, COLOR_PAIR(1)); - set_menu_back(result, COLOR_PAIR(2)); - } - - set_menu_format(result, maxrow, maxcol); - scale_menu(result, &mrows, &mcols); - - if (mcols + (2 * margin + x) >= COLS) - mcols = COLS - (2 * margin + x); - -#ifdef TRACE - if (number == eTrace) - menu_opts_off(result, O_ONEVALUE); - else - menu_opts_on(result, O_ONEVALUE); -#endif - - menuwin = newwin(mrows + (2 * margin), mcols + (2 * margin), y, x); - set_menu_win(result, menuwin); - keypad(menuwin, TRUE); - if (margin) - box(menuwin, 0, 0); - - set_menu_sub(result, derwin(menuwin, mrows, mcols, margin, margin)); - - post_menu(result); - - return result; -} - -static void -menu_destroy(MENU * m) -{ - int count; - - Trace(("menu_destroy %p", m)); - if (m != 0) { - ITEM **items = menu_items(m); - const char *blob = 0; - - count = item_count(m); - Trace(("menu_destroy %p count %d", m, count)); - if ((count > 0) && (m == mpSelect)) { - blob = item_name(*items); - } - - unpost_menu(m); - free_menu(m); - - /* free the extra data allocated in build_select_menu() */ - if ((count > 0) && (m == mpSelect)) { - if (blob && loaded_file) { - Trace(("freeing blob %p", blob)); - free((char *) blob); - } - free(items); - } -#ifdef TRACE - if ((count > 0) && (m == mpTrace)) { - ITEM **ip = items; - while (*ip) - free(*ip++); - } -#endif - } -} - -/* force the given menu to appear */ -static void -menu_display(MENU * m) -{ - touchwin(menu_win(m)); - wrefresh(menu_win(m)); -} - -/*****************************************************************************/ - -static void -build_file_menu(MenuNo number) -{ - static CONST_MENUS char *labels[] = - { - "Exit", - (char *) 0 - }; - static ITEM *items[SIZEOF(labels)]; - - ITEM **ip = items; - CONST_MENUS char **ap; - - for (ap = labels; *ap; ap++) - *ip++ = new_item(*ap, ""); - *ip = (ITEM *) 0; - - mpFile = menu_create(items, SIZEOF(labels) - 1, 1, number); -} - -static int -perform_file_menu(int cmd) -{ - return menu_driver(mpFile, cmd); -} - -/*****************************************************************************/ - -static void -build_select_menu(MenuNo number, char *filename) -{ - static CONST_MENUS char *labels[] = - { - "Lions", - "Tigers", - "Bears", - "(Oh my!)", - "Newts", - "Platypi", - "Lemurs", - "(Oh really?!)", - "Leopards", - "Panthers", - "Pumas", - "Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs", - "Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs, Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs", - (char *) 0 - }; - static ITEM **items; - - ITEM **ip; - CONST_MENUS char **ap = 0; - CONST_MENUS char **myList = 0; - unsigned count = 0; - - if (filename != 0) { - struct stat sb; - if (stat(filename, &sb) == 0 - && (sb.st_mode & S_IFMT) == S_IFREG - && sb.st_size != 0) { - size_t size = (size_t) sb.st_size; - unsigned j, k; - char *blob = typeMalloc(char, size + 1); - CONST_MENUS char **list = typeCalloc(CONST_MENUS char *, size + 1); - - items = typeCalloc(ITEM *, size + 1); - Trace(("build_select_menu blob=%p, items=%p", blob, items)); - if (blob != 0 && list != 0) { - FILE *fp = fopen(filename, "r"); - if (fp != 0) { - if (fread(blob, sizeof(char), size, fp) == size) { - bool mark = TRUE; - for (j = k = 0; j < size; ++j) { - if (mark) { - list[k++] = blob + j; - mark = FALSE; - } - if (blob[j] == '\n') { - blob[j] = '\0'; - if (k > 0 && *list[k - 1] == '\0') - --k; - mark = TRUE; - } else if (blob[j] == '\t') { - blob[j] = ' '; /* menu items are printable */ - } - } - list[k] = 0; - count = k; - ap = myList = list; - } - fclose(fp); - } - loaded_file = TRUE; - } - } - } - if (ap == 0) { - count = SIZEOF(labels) - 1; - items = typeCalloc(ITEM *, count + 1); - ap = labels; - } - - ip = items; - while (*ap != 0) - *ip++ = new_item(*ap++, ""); - *ip = 0; - - mpSelect = menu_create(items, (int) count, 1, number); - if (myList != 0) - free(myList); -} - -static int -perform_select_menu(int cmd) -{ - return menu_driver(mpSelect, cmd); -} - -/*****************************************************************************/ - -#ifdef TRACE -#define T_TBL(name) { #name, name } -static struct { - const char *name; - unsigned mask; -} t_tbl[] = { - - T_TBL(TRACE_DISABLE), - T_TBL(TRACE_TIMES), - T_TBL(TRACE_TPUTS), - T_TBL(TRACE_UPDATE), - T_TBL(TRACE_MOVE), - T_TBL(TRACE_CHARPUT), - T_TBL(TRACE_ORDINARY), - T_TBL(TRACE_CALLS), - T_TBL(TRACE_VIRTPUT), - T_TBL(TRACE_IEVENT), - T_TBL(TRACE_BITS), - T_TBL(TRACE_ICALLS), - T_TBL(TRACE_CCALLS), - T_TBL(TRACE_DATABASE), - T_TBL(TRACE_ATTRS), - T_TBL(TRACE_MAXIMUM), - { - (char *) 0, 0 - } -}; - -static void -build_trace_menu(MenuNo number) -{ - static ITEM *items[SIZEOF(t_tbl)]; - - ITEM **ip = items; - int n; - - for (n = 0; t_tbl[n].name != 0; n++) - *ip++ = new_item(t_tbl[n].name, ""); - *ip = (ITEM *) 0; - - mpTrace = menu_create(items, SIZEOF(t_tbl) - 1, 2, number); -} - -static char * -tracetrace(unsigned tlevel) -{ - static char *buf; - int n; - - if (buf == 0) { - size_t need = 12; - for (n = 0; t_tbl[n].name != 0; n++) - need += strlen(t_tbl[n].name) + 2; - buf = typeMalloc(char, need); - } - sprintf(buf, "0x%02x = {", tlevel); - if (tlevel == 0) { - sprintf(buf + strlen(buf), "%s, ", t_tbl[0].name); - } else { - for (n = 1; t_tbl[n].name != 0; n++) - if ((tlevel & t_tbl[n].mask) == t_tbl[n].mask) { - strcat(buf, t_tbl[n].name); - strcat(buf, ", "); - } - } - if (buf[strlen(buf) - 2] == ',') - buf[strlen(buf) - 2] = '\0'; - return (strcat(buf, "}")); -} - -/* fake a dynamically reconfigurable menu using the 0th entry to deselect - * the others - */ -static bool -update_trace_menu(MENU * m) -{ - ITEM **items; - ITEM *i, **p; - bool changed = FALSE; - - items = menu_items(m); - i = current_item(m); - if (i == items[0]) { - if (item_value(i)) { - for (p = items + 1; *p != 0; p++) - if (item_value(*p)) { - set_item_value(*p, FALSE); - changed = TRUE; - } - } - } - return changed; -} - -static int -perform_trace_menu(int cmd) -/* interactively set the trace level */ -{ - ITEM **ip; - unsigned newtrace; - int result; - - for (ip = menu_items(mpTrace); *ip; ip++) { - unsigned mask = t_tbl[item_index(*ip)].mask; - if (mask == 0) - set_item_value(*ip, _nc_tracing == 0); - else if ((mask & _nc_tracing) == mask) - set_item_value(*ip, TRUE); - } - - result = menu_driver(mpTrace, cmd); - - if (result == E_OK) { - if (update_trace_menu(mpTrace) || cmd == REQ_TOGGLE_ITEM) { - newtrace = 0; - for (ip = menu_items(mpTrace); *ip; ip++) { - if (item_value(*ip)) - newtrace |= t_tbl[item_index(*ip)].mask; - } - trace(newtrace); - Trace(("trace level interactively set to %s", tracetrace(_nc_tracing))); - - (void) mvprintw(LINES - 2, 0, - "Trace level is %s\n", tracetrace(_nc_tracing)); - refresh(); - } - } - return result; -} -#endif /* TRACE */ - -/*****************************************************************************/ - -static int -menu_number(void) -{ - return item_index(current_item(mpBanner)) - (eBanner + 1); -} - -static MENU * -current_menu(void) -{ - MENU *result; - - switch (menu_number()) { - case eFile: - result = mpFile; - break; - case eSelect: - result = mpSelect; - break; -#ifdef TRACE - case eTrace: - result = mpTrace; - break; -#endif - default: - result = 0; - break; - } - return result; -} - -static void -build_menus(char *filename) -{ - static CONST_MENUS char *labels[] = - { - "File", - "Select", -#ifdef TRACE - "Trace", -#endif - (char *) 0 - }; - static ITEM *items[SIZEOF(labels)]; - - ITEM **ip = items; - CONST_MENUS char **ap; - - for (ap = labels; *ap; ap++) - *ip++ = new_item(*ap, ""); - *ip = (ITEM *) 0; - - mpBanner = menu_create(items, SIZEOF(labels) - 1, SIZEOF(labels) - 1, eBanner); - set_menu_mark(mpBanner, ">"); - - build_file_menu(eFile); - build_select_menu(eSelect, filename); -#ifdef TRACE - build_trace_menu(eTrace); -#endif -} - -static int -move_menu(MENU * menu, MENU * current, int by_y, int by_x) -{ - WINDOW *top_win = menu_win(menu); - WINDOW *sub_win = menu_sub(menu); - int y0, x0; - int y1, x1; - int result; - - getbegyx(top_win, y0, x0); - y0 += by_y; - x0 += by_x; - - getbegyx(sub_win, y1, x1); - y1 += by_y; - x1 += by_x; - - if ((result = mvwin(top_win, y0, x0)) != ERR) { -#if defined(NCURSES_VERSION_PATCH) && (NCURSES_VERSION_PATCH < 20060218) - sub_win->_begy = y1; - sub_win->_begx = x1; -#else - mvwin(sub_win, y1, x1); -#endif - if (menu == current) { - touchwin(top_win); - wnoutrefresh(top_win); - } - } - return result; -} - -/* - * Move the menus around on the screen, to test mvwin(). - */ -static void -move_menus(MENU * current, int by_y, int by_x) -{ - if (move_menu(mpBanner, current, by_y, by_x) != ERR) { - erase(); - wnoutrefresh(stdscr); - move_menu(mpFile, current, by_y, by_x); - move_menu(mpSelect, current, by_y, by_x); -#ifdef TRACE - move_menu(mpTrace, current, by_y, by_x); -#endif - doupdate(); - } -} - -static void -show_status(int ch, MENU * menu) -{ - move(LINES - 1, 0); - printw("key %s, menu %d, mark %s, match %s", - keyname(ch), - menu_number(), - menu_mark(menu), - menu_pattern(menu)); - clrtoeol(); - refresh(); -} - -static void -perform_menus(void) -{ - MENU *this_menu; - MENU *last_menu = mpFile; - int code = E_UNKNOWN_COMMAND; - int cmd; - int ch = ERR; - -#ifdef NCURSES_MOUSE_VERSION - mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0); -#endif - - menu_display(last_menu); - - for (;;) { - - if (ch != ERR) - show_status(ch, last_menu); - - ch = menu_getc(mpBanner); - - /* - * Provide for moving the menu around in the screen using shifted - * cursor keys. - */ - switch (ch) { - case KEY_SF: - move_menus(last_menu, 1, 0); - continue; - case KEY_SR: - move_menus(last_menu, -1, 0); - continue; - case KEY_SLEFT: - move_menus(last_menu, 0, -1); - continue; - case KEY_SRIGHT: - move_menus(last_menu, 0, 1); - continue; - } - cmd = menu_virtualize(ch); - - switch (cmd) { - /* - * The banner menu acts solely to select one of the other menus. - * Move between its items, wrapping at the left/right limits. - */ - case REQ_LEFT_ITEM: - case REQ_RIGHT_ITEM: - code = menu_driver(mpBanner, cmd); - if (code == E_REQUEST_DENIED) { - if (menu_number() > 0) - code = menu_driver(mpBanner, REQ_FIRST_ITEM); - else - code = menu_driver(mpBanner, REQ_LAST_ITEM); - } - break; - default: - switch (menu_number()) { - case eFile: - code = perform_file_menu(cmd); - break; - case eSelect: - code = perform_select_menu(cmd); - break; -#ifdef TRACE - case eTrace: - code = perform_trace_menu(cmd); - break; -#endif - } - - if ((code == E_REQUEST_DENIED) && (cmd == KEY_MOUSE)) { - code = menu_driver(mpBanner, cmd); - } - - break; - } - - if (code == E_OK) { - this_menu = current_menu(); - if (this_menu != last_menu) { - move(1, 0); - clrtobot(); - box(menu_win(this_menu), 0, 0); - refresh(); - - /* force the current menu to appear */ - menu_display(this_menu); - - last_menu = this_menu; - } - } - wrefresh(menu_win(last_menu)); - if (code == E_UNKNOWN_COMMAND - || code == E_NOT_POSTED) { - if (menu_number() == eFile) - break; - beep(); - } - if (code == E_REQUEST_DENIED) - beep(); - continue; - } - -#ifdef NCURSES_MOUSE_VERSION - mousemask(0, (mmask_t *) 0); -#endif -} - -static void -destroy_menus(void) -{ - menu_destroy(mpFile); - menu_destroy(mpSelect); -#ifdef TRACE - menu_destroy(mpTrace); -#endif - menu_destroy(mpBanner); -} - -#if HAVE_RIPOFFLINE -static int -rip_footer(WINDOW *win, int cols) -{ - wbkgd(win, A_REVERSE); - werase(win); - wmove(win, 0, 0); - wprintw(win, "footer: %d columns", cols); - wnoutrefresh(win); - return OK; -} - -static int -rip_header(WINDOW *win, int cols) -{ - wbkgd(win, A_REVERSE); - werase(win); - wmove(win, 0, 0); - wprintw(win, "header: %d columns", cols); - wnoutrefresh(win); - return OK; -} -#endif /* HAVE_RIPOFFLINE */ - -static void -usage(void) -{ - static const char *const tbl[] = - { - "Usage: demo_menus [options]" - ,"" - ,"Options:" -#if HAVE_RIPOFFLINE - ," -f rip-off footer line (can repeat)" - ," -h rip-off header line (can repeat)" -#endif -#ifdef TRACE - ," -t mask specify default trace-level (may toggle with ^T)" -#endif - }; - size_t n; - for (n = 0; n < SIZEOF(tbl); n++) - fprintf(stderr, "%s\n", tbl[n]); - ExitProgram(EXIT_FAILURE); -} - -int -main(int argc, char *argv[]) -{ - int c; - - setlocale(LC_ALL, ""); - - while ((c = getopt(argc, argv, "a:de:fhmp:s:t:")) != -1) { - switch (c) { -#if HAVE_RIPOFFLINE - case 'f': - ripoffline(-1, rip_footer); - break; - case 'h': - ripoffline(1, rip_header); - break; -#endif /* HAVE_RIPOFFLINE */ -#ifdef TRACE - case 't': - trace(strtoul(optarg, 0, 0)); - break; -#endif - default: - usage(); - } - } - - initscr(); - noraw(); - cbreak(); - noecho(); - - if (has_colors()) { - start_color(); - init_pair(1, COLOR_RED, COLOR_BLACK); - init_pair(2, COLOR_BLUE, COLOR_WHITE); - } - build_menus(argc > 1 ? argv[1] : 0); - perform_menus(); - destroy_menus(); - - endwin(); - ExitProgram(EXIT_SUCCESS); -} -#else -int -main(void) -{ - printf("This program requires the curses menu library\n"); - ExitProgram(EXIT_FAILURE); -} -#endif |