~ubuntu-branches/debian/sid/ncurses/sid-200908151543

« back to all changes in this revision

Viewing changes to test/demo_menus.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2008-12-14 21:06:00 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20081214210600-2rdjwvpplgvh3zeb
Tags: 5.7+20081213-1
MergingĀ upstreamĀ versionĀ 5.7+20081213.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
 * Copyright (c) 2005-2007,2008 Free Software Foundation, Inc.              *
 
3
 *                                                                          *
 
4
 * Permission is hereby granted, free of charge, to any person obtaining a  *
 
5
 * copy of this software and associated documentation files (the            *
 
6
 * "Software"), to deal in the Software without restriction, including      *
 
7
 * without limitation the rights to use, copy, modify, merge, publish,      *
 
8
 * distribute, distribute with modifications, sublicense, and/or sell       *
 
9
 * copies of the Software, and to permit persons to whom the Software is    *
 
10
 * furnished to do so, subject to the following conditions:                 *
 
11
 *                                                                          *
 
12
 * The above copyright notice and this permission notice shall be included  *
 
13
 * in all copies or substantial portions of the Software.                   *
 
14
 *                                                                          *
 
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
 
16
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
 
17
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
 
18
 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
 
19
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
 
20
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
 
21
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
 
22
 *                                                                          *
 
23
 * Except as contained in this notice, the name(s) of the above copyright   *
 
24
 * holders shall not be used in advertising or otherwise to promote the     *
 
25
 * sale, use or other dealings in this Software without prior written       *
 
26
 * authorization.                                                           *
 
27
 ****************************************************************************/
1
28
/*
2
 
 * $Id: demo_menus.c,v 1.13 2005/10/01 15:54:31 tom Exp $
 
29
 * $Id: demo_menus.c,v 1.28 2008/08/23 20:31:54 tom Exp $
3
30
 *
4
31
 * Demonstrate a variety of functions from the menu library.
5
32
 * Thomas Dickey - 2005/4/9
18
45
menu_format                     -
19
46
menu_grey                       -
20
47
menu_init                       -
21
 
menu_mark                       -
22
48
menu_opts                       -
23
49
menu_pad                        -
24
 
menu_pattern                    -
25
50
menu_request_by_name            -
26
51
menu_request_name               -
27
52
menu_sub                        -
65
90
#endif
66
91
 
67
92
typedef enum {
68
 
    eUnknown = -1
69
 
    ,eFile = 0
 
93
    eBanner = -1
 
94
    ,eFile
70
95
    ,eSelect
71
96
#ifdef TRACE
72
97
    ,eTrace
73
98
#endif
 
99
    ,eMAX
74
100
} MenuNo;
75
101
 
 
102
#define okMenuNo(n) (((n) > eBanner) && ((n) < eMAX))
 
103
 
76
104
#define MENU_Y  1
77
105
 
78
106
static MENU *mpBanner;
79
107
static MENU *mpFile;
80
108
static MENU *mpSelect;
81
109
 
 
110
static bool loaded_file = FALSE;
 
111
 
82
112
#if !HAVE_STRDUP
83
113
#define strdup my_strdup
84
114
static char *
85
115
strdup(char *s)
86
116
{
87
 
    char *p = (char *) malloc(strlen(s) + 1);
 
117
    char *p = typeMalloc(char, strlen(s) + 1);
88
118
    if (p)
89
119
        strcpy(p, s);
90
120
    return (p);
102
132
    while ((c = wgetch(win)) == CTRL('T')) {
103
133
        if (_nc_tracing) {
104
134
            save_trace = _nc_tracing;
105
 
            _tracef("TOGGLE-TRACING OFF");
 
135
            Trace(("TOGGLE-TRACING OFF"));
106
136
            _nc_tracing = 0;
107
137
        } else {
108
138
            _nc_tracing = save_trace;
109
139
        }
110
140
        trace(_nc_tracing);
111
141
        if (_nc_tracing)
112
 
            _tracef("TOGGLE-TRACING ON");
 
142
            Trace(("TOGGLE-TRACING ON"));
113
143
    }
114
144
#else
115
145
    c = wgetch(win);
162
192
{
163
193
    int result = 0;
164
194
 
165
 
    if ((int) number >= 0) {
 
195
    if (okMenuNo(number)) {
166
196
        int spc_desc, spc_rows, spc_cols;
167
197
 
168
198
#ifdef NCURSES_VERSION
172
202
#endif
173
203
 
174
204
        /* FIXME: MENU.itemlen seems the only way to get actual width of items */
175
 
        result = number * (mpBanner->itemlen + spc_rows);
 
205
        result = (number - (eBanner + 1)) * (mpBanner->itemlen + spc_rows);
176
206
    }
177
207
    return result;
178
208
}
183
213
    MENU *result;
184
214
    WINDOW *menuwin;
185
215
    int mrows, mcols;
186
 
    int y = ((int) number >= 0) ? MENU_Y : 0;
 
216
    int y = okMenuNo(number) ? MENU_Y : 0;
187
217
    int x = menu_offset(number);
188
218
    int margin = (y == MENU_Y) ? 1 : 0;
189
219
    int maxcol = (ncols + x) < COLS ? ncols : (COLS - x - 1);
228
258
static void
229
259
menu_destroy(MENU * m)
230
260
{
231
 
    ITEM **ip;
232
261
    int count;
233
262
 
 
263
    Trace(("menu_destroy %p", m));
234
264
    if (m != 0) {
235
 
        delwin(menu_win(m));
 
265
        ITEM **items = menu_items(m);
 
266
        const char *blob = 0;
236
267
 
237
 
        ip = menu_items(m);
238
268
        count = item_count(m);
 
269
        Trace(("menu_destroy %p count %d", m, count));
 
270
        if ((count > 0) && (m == mpSelect)) {
 
271
            blob = item_name(*items);
 
272
        }
239
273
 
 
274
        unpost_menu(m);
240
275
        free_menu(m);
241
 
#if 0
242
 
        if (count > 0) {
243
 
            while (*ip) {
244
 
                _tracef("freeing item %d:%d", ip - menu_items(m), count);
245
 
                free_item(*ip++);
 
276
 
 
277
        /* free the extra data allocated in build_select_menu() */
 
278
        if ((count > 0) && (m == mpSelect)) {
 
279
            if (blob && loaded_file) {
 
280
                Trace(("freeing blob %p", blob));
 
281
                free((char *) blob);
246
282
            }
 
283
            free(items);
 
284
        }
 
285
#ifdef TRACE
 
286
        if ((count > 0) && (m == mpTrace)) {
 
287
            ITEM **ip = items;
 
288
            while (*ip)
 
289
                free(*ip++);
247
290
        }
248
291
#endif
249
292
    }
262
305
static void
263
306
build_file_menu(MenuNo number)
264
307
{
265
 
    static const char *labels[] =
 
308
    static CONST_MENUS char *labels[] =
266
309
    {
267
310
        "Exit",
268
311
        (char *) 0
270
313
    static ITEM *items[SIZEOF(labels)];
271
314
 
272
315
    ITEM **ip = items;
273
 
    const char **ap;
 
316
    CONST_MENUS char **ap;
274
317
 
275
318
    for (ap = labels; *ap; ap++)
276
319
        *ip++ = new_item(*ap, "");
290
333
static void
291
334
build_select_menu(MenuNo number, char *filename)
292
335
{
293
 
    static const char *labels[] =
 
336
    static CONST_MENUS char *labels[] =
294
337
    {
295
338
        "Lions",
296
339
        "Tigers",
310
353
    static ITEM **items;
311
354
 
312
355
    ITEM **ip;
313
 
    const char **ap = 0;
 
356
    CONST_MENUS char **ap = 0;
 
357
    CONST_MENUS char **myList = 0;
314
358
    unsigned count = 0;
315
359
 
316
360
    if (filename != 0) {
318
362
        if (stat(filename, &sb) == 0
319
363
            && (sb.st_mode & S_IFMT) == S_IFREG
320
364
            && sb.st_size != 0) {
321
 
            unsigned size = sb.st_size;
 
365
            size_t size = (size_t) sb.st_size;
322
366
            unsigned j, k;
323
 
            char *blob = malloc(size + 1);
324
 
            const char **list = (const char **) calloc(sizeof(*list), size + 1);
 
367
            char *blob = typeMalloc(char, size + 1);
 
368
            CONST_MENUS char **list = typeCalloc(CONST_MENUS char *, size + 1);
325
369
 
326
 
            items = (ITEM **) calloc(sizeof(ITEM *), size + 1);
 
370
            items = typeCalloc(ITEM *, size + 1);
 
371
            Trace(("build_select_menu blob=%p, items=%p", blob, items));
327
372
            if (blob != 0 && list != 0) {
328
373
                FILE *fp = fopen(filename, "r");
329
374
                if (fp != 0) {
345
390
                        }
346
391
                        list[k] = 0;
347
392
                        count = k;
348
 
                        ap = list;
 
393
                        ap = myList = list;
349
394
                    }
350
395
                    fclose(fp);
351
396
                }
 
397
                loaded_file = TRUE;
352
398
            }
353
399
        }
354
400
    }
355
401
    if (ap == 0) {
356
402
        count = SIZEOF(labels) - 1;
357
 
        items = (ITEM **) calloc(count + 1, sizeof(*items));
 
403
        items = typeCalloc(ITEM *, count + 1);
358
404
        ap = labels;
359
405
    }
360
406
 
364
410
    *ip = 0;
365
411
 
366
412
    mpSelect = menu_create(items, (int) count, 1, number);
 
413
    if (myList != 0)
 
414
        free(myList);
367
415
}
368
416
 
369
417
static int
427
475
        size_t need = 12;
428
476
        for (n = 0; t_tbl[n].name != 0; n++)
429
477
            need += strlen(t_tbl[n].name) + 2;
430
 
        buf = (char *) malloc(need);
 
478
        buf = typeMalloc(char, need);
431
479
    }
432
480
    sprintf(buf, "0x%02x = {", tlevel);
433
481
    if (tlevel == 0) {
494
542
                    newtrace |= t_tbl[item_index(*ip)].mask;
495
543
            }
496
544
            trace(newtrace);
497
 
            _tracef("trace level interactively set to %s", tracetrace(_nc_tracing));
 
545
            Trace(("trace level interactively set to %s", tracetrace(_nc_tracing)));
498
546
 
499
547
            (void) mvprintw(LINES - 2, 0,
500
548
                            "Trace level is %s\n", tracetrace(_nc_tracing));
510
558
static int
511
559
menu_number(void)
512
560
{
513
 
    return item_index(current_item(mpBanner));
 
561
    return item_index(current_item(mpBanner)) - (eBanner + 1);
514
562
}
515
563
 
516
564
static MENU *
540
588
static void
541
589
build_menus(char *filename)
542
590
{
543
 
    static const char *labels[] =
 
591
    static CONST_MENUS char *labels[] =
544
592
    {
545
593
        "File",
546
594
        "Select",
552
600
    static ITEM *items[SIZEOF(labels)];
553
601
 
554
602
    ITEM **ip = items;
555
 
    const char **ap;
 
603
    CONST_MENUS char **ap;
556
604
 
557
605
    for (ap = labels; *ap; ap++)
558
606
        *ip++ = new_item(*ap, "");
559
607
    *ip = (ITEM *) 0;
560
608
 
561
 
    mpBanner = menu_create(items, SIZEOF(labels) - 1, SIZEOF(labels) - 1, eUnknown);
 
609
    mpBanner = menu_create(items, SIZEOF(labels) - 1, SIZEOF(labels) - 1, eBanner);
562
610
    set_menu_mark(mpBanner, ">");
563
611
 
564
612
    build_file_menu(eFile);
568
616
#endif
569
617
}
570
618
 
 
619
static int
 
620
move_menu(MENU * menu, MENU * current, int by_y, int by_x)
 
621
{
 
622
    WINDOW *top_win = menu_win(menu);
 
623
    WINDOW *sub_win = menu_sub(menu);
 
624
    int y0, x0;
 
625
    int y1, x1;
 
626
    int result;
 
627
 
 
628
    getbegyx(top_win, y0, x0);
 
629
    y0 += by_y;
 
630
    x0 += by_x;
 
631
 
 
632
    getbegyx(sub_win, y1, x1);
 
633
    y1 += by_y;
 
634
    x1 += by_x;
 
635
 
 
636
    if ((result = mvwin(top_win, y0, x0)) != ERR) {
 
637
#if defined(NCURSES_VERSION_PATCH) && (NCURSES_VERSION_PATCH < 20060218)
 
638
        sub_win->_begy = y1;
 
639
        sub_win->_begx = x1;
 
640
#else
 
641
        mvwin(sub_win, y1, x1);
 
642
#endif
 
643
        if (menu == current) {
 
644
            touchwin(top_win);
 
645
            wnoutrefresh(top_win);
 
646
        }
 
647
    }
 
648
    return result;
 
649
}
 
650
 
 
651
/*
 
652
 * Move the menus around on the screen, to test mvwin().
 
653
 */
 
654
static void
 
655
move_menus(MENU * current, int by_y, int by_x)
 
656
{
 
657
    if (move_menu(mpBanner, current, by_y, by_x) != ERR) {
 
658
        erase();
 
659
        wnoutrefresh(stdscr);
 
660
        move_menu(mpFile, current, by_y, by_x);
 
661
        move_menu(mpSelect, current, by_y, by_x);
 
662
#ifdef TRACE
 
663
        move_menu(mpTrace, current, by_y, by_x);
 
664
#endif
 
665
        doupdate();
 
666
    }
 
667
}
 
668
 
 
669
static void
 
670
show_status(int ch, MENU * menu)
 
671
{
 
672
    move(LINES - 1, 0);
 
673
    printw("key %s, menu %d, mark %s, match %s",
 
674
           keyname(ch),
 
675
           menu_number(),
 
676
           menu_mark(menu),
 
677
           menu_pattern(menu));
 
678
    clrtoeol();
 
679
    refresh();
 
680
}
 
681
 
571
682
static void
572
683
perform_menus(void)
573
684
{
574
685
    MENU *this_menu;
575
686
    MENU *last_menu = mpFile;
576
 
    int code = E_UNKNOWN_COMMAND, cmd, ch;
 
687
    int code = E_UNKNOWN_COMMAND;
 
688
    int cmd;
 
689
    int ch = ERR;
577
690
 
578
691
#ifdef NCURSES_MOUSE_VERSION
579
692
    mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0);
582
695
    menu_display(last_menu);
583
696
 
584
697
    for (;;) {
 
698
 
 
699
        if (ch != ERR)
 
700
            show_status(ch, last_menu);
 
701
 
585
702
        ch = menu_getc(mpBanner);
 
703
 
 
704
        /*
 
705
         * Provide for moving the menu around in the screen using shifted
 
706
         * cursor keys.
 
707
         */
 
708
        switch (ch) {
 
709
        case KEY_SF:
 
710
            move_menus(last_menu, 1, 0);
 
711
            continue;
 
712
        case KEY_SR:
 
713
            move_menus(last_menu, -1, 0);
 
714
            continue;
 
715
        case KEY_SLEFT:
 
716
            move_menus(last_menu, 0, -1);
 
717
            continue;
 
718
        case KEY_SRIGHT:
 
719
            move_menus(last_menu, 0, 1);
 
720
            continue;
 
721
        }
586
722
        cmd = menu_virtualize(ch);
587
723
 
588
724
        switch (cmd) {
664
800
    menu_destroy(mpBanner);
665
801
}
666
802
 
 
803
#if HAVE_RIPOFFLINE
 
804
static int
 
805
rip_footer(WINDOW *win, int cols)
 
806
{
 
807
    wbkgd(win, A_REVERSE);
 
808
    werase(win);
 
809
    wmove(win, 0, 0);
 
810
    wprintw(win, "footer: %d columns", cols);
 
811
    wnoutrefresh(win);
 
812
    return OK;
 
813
}
 
814
 
 
815
static int
 
816
rip_header(WINDOW *win, int cols)
 
817
{
 
818
    wbkgd(win, A_REVERSE);
 
819
    werase(win);
 
820
    wmove(win, 0, 0);
 
821
    wprintw(win, "header: %d columns", cols);
 
822
    wnoutrefresh(win);
 
823
    return OK;
 
824
}
 
825
#endif /* HAVE_RIPOFFLINE */
 
826
 
 
827
static void
 
828
usage(void)
 
829
{
 
830
    static const char *const tbl[] =
 
831
    {
 
832
        "Usage: demo_menus [options]"
 
833
        ,""
 
834
        ,"Options:"
 
835
#if HAVE_RIPOFFLINE
 
836
        ,"  -f       rip-off footer line (can repeat)"
 
837
        ,"  -h       rip-off header line (can repeat)"
 
838
#endif
 
839
#ifdef TRACE
 
840
        ,"  -t mask  specify default trace-level (may toggle with ^T)"
 
841
#endif
 
842
    };
 
843
    size_t n;
 
844
    for (n = 0; n < SIZEOF(tbl); n++)
 
845
        fprintf(stderr, "%s\n", tbl[n]);
 
846
    ExitProgram(EXIT_FAILURE);
 
847
}
 
848
 
667
849
int
668
850
main(int argc, char *argv[])
669
851
{
 
852
    int c;
 
853
 
670
854
    setlocale(LC_ALL, "");
671
855
 
 
856
    while ((c = getopt(argc, argv, "a:de:fhmp:s:t:")) != -1) {
 
857
        switch (c) {
 
858
#if HAVE_RIPOFFLINE
 
859
        case 'f':
 
860
            ripoffline(-1, rip_footer);
 
861
            break;
 
862
        case 'h':
 
863
            ripoffline(1, rip_header);
 
864
            break;
 
865
#endif /* HAVE_RIPOFFLINE */
 
866
#ifdef TRACE
 
867
        case 't':
 
868
            trace(strtoul(optarg, 0, 0));
 
869
            break;
 
870
#endif
 
871
        default:
 
872
            usage();
 
873
        }
 
874
    }
 
875
 
672
876
    initscr();
673
877
    noraw();
674
878
    cbreak();
684
888
    destroy_menus();
685
889
 
686
890
    endwin();
687
 
    return EXIT_SUCCESS;
 
891
    ExitProgram(EXIT_SUCCESS);
688
892
}
689
893
#else
690
894
int