Annotation of othersrc/dist/cdk/demos/command.c, revision 1.1.1.1

1.1       garbled     1: #include <cdk.h>
                      2: 
                      3: #ifdef HAVE_XCURSES
                      4: char *XCursesProgramName="command";
                      5: #endif
                      6: 
                      7: /* Define some global variables. */
                      8: #define MAXHISTORY     5000
                      9: char *introductionMessage[] = {"<C></B/16>Little Command Interface", "",
                     10:                                "<C>Written by Mike Glover", "",
                     11:                                "<C>Type </B>help<!B> to get help."};
                     12: 
                     13: /* This structure is used for keeping command history. */
                     14: struct history_st {
                     15:    int count;
                     16:    int current;
                     17:    char *command[MAXHISTORY];
                     18: };
                     19: 
                     20: /* Define some local prototypes. */
                     21: char *uc (char *word);
                     22: void help (CDKENTRY *entry);
                     23: static BINDFN_PROTO(historyUpCB);
                     24: static BINDFN_PROTO(historyDownCB);
                     25: static BINDFN_PROTO(viewHistoryCB);
                     26: static BINDFN_PROTO(listHistoryCB);
                     27: static BINDFN_PROTO(jumpWindowCB);
                     28: 
                     29: /*
                     30:  * Written by: Mike Glover
                     31:  * Purpose:
                     32:  *             This creates a very simple command interface.
                     33:  */
                     34: int main(int argc, char **argv)
                     35: {
                     36:    /* Declare variables. */
                     37:    CDKSCREEN *cdkscreen                = 0;
                     38:    CDKSWINDOW *commandOutput   = 0;
                     39:    CDKENTRY *commandEntry      = 0;
                     40:    WINDOW *cursesWin           = 0;
                     41:    chtype *convert             = 0;
                     42:    char *command               = 0;
                     43:    char *upper                 = 0;
                     44:    char *prompt                        = "</B/24>Command >";
                     45:    char *title                 = "<C></B/5>Command Output Window";
                     46:    int promptLen               = 0;
                     47:    int commandFieldWidth       = 0;
                     48:    struct history_st history;
                     49:    char temp[600];
                     50:    int ret, junk;
                     51: 
                     52:    /* Set up the history. */
                     53:    history.current = 0;
                     54:    history.count = 0;
                     55: 
                     56:    /* Check the command line for options. */
                     57:    while (1)
                     58:    {
                     59:       /* Are there any more command line options to parse. */
                     60:       if ((ret = getopt (argc, argv, "t:p:")) == -1)
                     61:       {
                     62:         break;
                     63:       }
                     64:       switch (ret)
                     65:       {
                     66:         case 'p':
                     67:              prompt = copyChar (optarg);
                     68:              break;
                     69: 
                     70:         case 't':
                     71:              title = copyChar (optarg);
                     72:              break;
                     73: 
                     74:         default:
                     75:              break;
                     76:       }
                     77:    }
                     78: 
                     79:    /* Set up CDK. */
                     80:    cursesWin = initscr();
                     81:    cdkscreen = initCDKScreen (cursesWin);
                     82: 
                     83:    /* Start color. */
                     84:    initCDKColor();
                     85: 
                     86:    /* Create the scrolling window. */
                     87:    commandOutput = newCDKSwindow (cdkscreen, CENTER, TOP, -4, -2,
                     88:                                        title, 1000, TRUE, TRUE);
                     89: 
                     90:    /* Convert the prompt to a chtype and determine its length. */
                     91:    convert = char2Chtype (prompt, &promptLen, &junk);
                     92:    commandFieldWidth = COLS - promptLen - 4;
                     93:    freeChtype (convert);
                     94: 
                     95:    /* Create the entry field. */
                     96:    commandEntry = newCDKEntry (cdkscreen, CENTER, BOTTOM,
                     97:                                0, prompt, A_BOLD|COLOR_PAIR(8), COLOR_PAIR(24)|'_',
                     98:                                vMIXED, commandFieldWidth, 1, 512, FALSE, FALSE);
                     99: 
                    100:    /* Create the key bindings. */
                    101:    bindCDKObject (vENTRY, commandEntry, KEY_UP, historyUpCB, &history);
                    102:    bindCDKObject (vENTRY, commandEntry, KEY_DOWN, historyDownCB, &history);
                    103:    bindCDKObject (vENTRY, commandEntry, TAB, viewHistoryCB, commandOutput);
                    104:    bindCDKObject (vENTRY, commandEntry, CONTROL('^'), listHistoryCB, &history);
                    105:    bindCDKObject (vENTRY, commandEntry, CONTROL('G'), jumpWindowCB, commandOutput);
                    106:    bindCDKObject (vENTRY, commandEntry, KEY_PPAGE, jumpWindowCB, commandOutput);
                    107:    bindCDKObject (vENTRY, commandEntry, KEY_NPAGE, jumpWindowCB, commandOutput);
                    108: 
                    109:    /* Draw the screen. */
                    110:    refreshCDKScreen (cdkscreen);
                    111: 
                    112:    /* Show them who wrote this and how to get help. */
                    113:    popupLabel (cdkscreen, introductionMessage, 5);
                    114:    eraseCDKEntry (commandEntry);
                    115: 
                    116:    /* Do this forever. */
                    117:    for (;;)
                    118:    {
                    119:       /* Get the command. */
                    120:       drawCDKEntry (commandEntry, ObjOf(commandEntry)->box);
                    121:       command  = activateCDKEntry (commandEntry, 0);
                    122: 
                    123:       if (commandEntry->exitType == vESCAPE_HIT)
                    124:       {
                    125:         break;
                    126:       }
                    127: 
                    128:       upper    = uc (command);
                    129: 
                    130:       /* Check the output of the command. */
                    131:       if (strcmp (upper, "QUIT") == 0 ||
                    132:                strcmp (upper, "EXIT") == 0 ||
                    133:                strcmp (upper, "Q") == 0 ||
                    134:                strcmp (upper, "E") == 0)
                    135:       {
                    136:         break;
                    137:       }
                    138:       else if (strcmp (command, "clear") == 0)
                    139:       {
                    140:         /* Keep the history. */
                    141:         history.command[history.count] = copyChar (command);
                    142:         history.count++;
                    143:         history.current = history.count;
                    144: 
                    145:         cleanCDKSwindow (commandOutput);
                    146:         cleanCDKEntry (commandEntry);
                    147:       }
                    148:       else if (strcmp (command, "history") == 0)
                    149:       {
                    150:         /* Display the history list. */
                    151:         listHistoryCB (vENTRY, commandEntry, &history, 0);
                    152: 
                    153:         /* Keep the history. */
                    154:         history.command[history.count] = copyChar (command);
                    155:         history.count++;
                    156:         history.current = history.count;
                    157:       }
                    158:       else if (strcmp (command, "help") == 0)
                    159:       {
                    160:         /* Keep the history. */
                    161:         history.command[history.count] = copyChar (command);
                    162:         history.count++;
                    163:         history.current = history.count;
                    164: 
                    165:         /* Display the help. */
                    166:         help (commandEntry);
                    167: 
                    168:         /* Clean the entry field. */
                    169:         cleanCDKEntry (commandEntry);
                    170:         eraseCDKEntry (commandEntry);
                    171:       }
                    172:       else
                    173:       {
                    174:         /* Keep the history. */
                    175:         history.command[history.count] = copyChar (command);
                    176:         history.count++;
                    177:         history.current = history.count;
                    178: 
                    179:         /* Jump to the bottom of the scrolling window. */
                    180:         jumpToLineCDKSwindow (commandOutput, BOTTOM);
                    181: 
                    182:         /* Insert a line providing the command. */
                    183:         sprintf (temp, "Command: </R>%s", command);
                    184:         addCDKSwindow (commandOutput, temp, BOTTOM);
                    185: 
                    186:         /* Run the command. */
                    187:         execCDKSwindow (commandOutput, command, BOTTOM);
                    188: 
                    189:         /* Clean out the entry field. */
                    190:         cleanCDKEntry (commandEntry);
                    191:       }
                    192: 
                    193:       /* Clean up a little. */
                    194:       freeChar (upper);
                    195:    }
                    196: 
                    197:    /* All done. */
                    198:    destroyCDKEntry (commandEntry);
                    199:    destroyCDKSwindow (commandOutput);
                    200:    delwin (cursesWin);
                    201:    freeChar (upper);
                    202:    endCDK();
                    203:    exit (0);
                    204: }
                    205: 
                    206: /*
                    207:  * This is the callback for the down arrow.
                    208:  */
                    209: static void historyUpCB (EObjectType cdktype GCC_UNUSED, void *object, void *clientData, chtype key GCC_UNUSED)
                    210: {
                    211:    CDKENTRY *entry = (CDKENTRY *)object;
                    212:    struct history_st *history = (struct history_st *) clientData;
                    213: 
                    214:    /* Make sure we don't go out of bounds. */
                    215:    if (history->current == 0)
                    216:    {
                    217:       Beep();
                    218:       return;
                    219:    }
                    220: 
                    221:    /* Decrement the counter. */
                    222:    history->current--;
                    223: 
                    224:    /* Display the command. */
                    225:    setCDKEntryValue (entry, history->command[history->current]);
                    226:    drawCDKEntry (entry, ObjOf(entry)->box);
                    227: }
                    228: 
                    229: /*
                    230:  * This is the callback for the down arrow.
                    231:  */
                    232: static void historyDownCB (EObjectType cdktype GCC_UNUSED, void *object, void *clientData, chtype key GCC_UNUSED)
                    233: {
                    234:    CDKENTRY *entry = (CDKENTRY *)object;
                    235:    struct history_st *history = (struct history_st *) clientData;
                    236: 
                    237:    /* Make sure we don't go out of bounds. */
                    238:    if (history->current == history->count)
                    239:    {
                    240:       Beep();
                    241:       return;
                    242:    }
                    243: 
                    244:    /* Increment the counter... */
                    245:    history->current++;
                    246: 
                    247:    if (history->current == history->count)
                    248:    {
                    249:       /* If we are at the end, clear the entry field. */
                    250:       cleanCDKEntry (entry);
                    251:    }
                    252:    else
                    253:    {
                    254:       /* Display the command. */
                    255:       setCDKEntryValue (entry, history->command[history->current]);
                    256:    }
                    257:    drawCDKEntry (entry, ObjOf(entry)->box);
                    258: }
                    259: 
                    260: /*
                    261:  * This callback allows the user to play with the scrolling window.
                    262:  */
                    263: static void viewHistoryCB (EObjectType cdktype GCC_UNUSED, void *object, void *clientData, chtype key GCC_UNUSED)
                    264: {
                    265:    CDKSWINDOW *swindow = (CDKSWINDOW *)clientData;
                    266:    CDKENTRY *entry     = (CDKENTRY *)object;
                    267: 
                    268:    /* Let them play... */
                    269:    activateCDKSwindow (swindow, 0);
                    270: 
                    271:    /* Redraw the entry field. */
                    272:    drawCDKEntry (entry, ObjOf(entry)->box);
                    273: }
                    274: 
                    275: /*
                    276:  * This callback jumps to a line in the scrolling window.
                    277:  */
                    278: static void jumpWindowCB (EObjectType cdktype GCC_UNUSED, void *object, void *clientData, chtype key)
                    279: {
                    280:    CDKENTRY *entry     = (CDKENTRY *)object;
                    281:    CDKSWINDOW *swindow = (CDKSWINDOW *)clientData;
                    282:    CDKSCALE *scale     = 0;
                    283:    int line;
                    284: 
                    285:    if (key == KEY_PPAGE || key == KEY_NPAGE)
                    286:    {
                    287:       injectCDKSwindow (swindow, key);
                    288:    }
                    289:    else
                    290:    {
                    291:       /* Ask them which line they want to jump to. */
                    292:       scale = newCDKScale (ScreenOf(entry), CENTER, CENTER,
                    293:                        "<C>Jump To Which Line",
                    294:                        "Line",
                    295:                        A_NORMAL, 5,
                    296:                        0, 0, swindow->itemCount, 1, 2, TRUE, FALSE);
                    297: 
                    298:       /* Get the line. */
                    299:       line = activateCDKScale (scale, 0);
                    300: 
                    301:       /* Clean up. */
                    302:       destroyCDKScale (scale);
                    303: 
                    304:       /* Jump to the line. */
                    305:       jumpToLineCDKSwindow (swindow, line);
                    306:    }
                    307: 
                    308:    /* Redraw the widgets. */
                    309:    drawCDKEntry (entry, ObjOf(entry)->box);
                    310: }
                    311: 
                    312: /*
                    313:  * This callback allows the user to pick from the history list from a
                    314:  * scrolling list.
                    315:  */
                    316: static void listHistoryCB (EObjectType cdktype GCC_UNUSED, void *object, void *clientData, chtype key GCC_UNUSED)
                    317: {
                    318:    CDKENTRY *entry = (CDKENTRY *)object;
                    319:    struct history_st *history = (struct history_st *) clientData;
                    320:    CDKSCROLL *scrollList;
                    321:    int height = (history->count < 10 ? history->count+3 : 13);
                    322:    int selection;
                    323: 
                    324:    /* No history, no list. */
                    325:    if (history->count == 0)
                    326:    {
                    327:       /* Popup a little window telling the user there are no commands. */
                    328:       char *mesg[] = {"<C></B/16>No Commands Entered", "<C>No History"};
                    329:       popupLabel (ScreenOf(entry), mesg, 2);
                    330:    }
                    331:    else
                    332:    {
                    333:       /* Create the scrolling list of previous commands. */
                    334:       scrollList = newCDKScroll (ScreenOf(entry), CENTER, CENTER, RIGHT,
                    335:                                height, 20, "<C></B/29>Command History",
                    336:                                history->command, history->count,
                    337:                                NUMBERS, A_REVERSE, TRUE, FALSE);
                    338: 
                    339:       /* Get the command to execute. */
                    340:       selection = activateCDKScroll (scrollList, 0);
                    341:       destroyCDKScroll (scrollList);
                    342: 
                    343:       /* Check the results of the selection. */
                    344:       if (selection >= 0)
                    345:       {
                    346:         /* Get the command and stick it back in the entry field. */
                    347:         setCDKEntryValue (entry, history->command[selection]);
                    348:       }
                    349:    }
                    350: 
                    351:    /* Redraw the screen. */
                    352:    eraseCDKEntry (entry);
                    353:    drawCDKScreen (ScreenOf(entry));
                    354: }
                    355: 
                    356: /*
                    357:  * This function displays help.
                    358:  */
                    359: void help (CDKENTRY *entry)
                    360: {
                    361:    char *mesg[25];
                    362: 
                    363:    /* Create the help message. */
                    364:    mesg[0] = "<C></B/29>Help";
                    365:    mesg[1] = "";
                    366:    mesg[2] = "</B/24>When in the command line.";
                    367:    mesg[3] = "<B=history   > Displays the command history.";
                    368:    mesg[4] = "<B=Ctrl-^    > Displays the command history.";
                    369:    mesg[5] = "<B=Up Arrow  > Scrolls back one command.";
                    370:    mesg[6] = "<B=Down Arrow> Scrolls forward one command.";
                    371:    mesg[7] = "<B=Tab       > Activates the scrolling window.";
                    372:    mesg[8] = "<B=help      > Displays this help window.";
                    373:    mesg[9] = "";
                    374:    mesg[10] = "</B/24>When in the scrolling window.";
                    375:    mesg[11] = "<B=l or L    > Loads a file into the window.";
                    376:    mesg[12] = "<B=s or S    > Saves the contents of the window to a file.";
                    377:    mesg[13] = "<B=Up Arrow  > Scrolls up one line.";
                    378:    mesg[14] = "<B=Down Arrow> Scrolls down one line.";
                    379:    mesg[15] = "<B=Page Up   > Scrolls back one page.";
                    380:    mesg[16] = "<B=Page Down > Scrolls forward one page.";
                    381:    mesg[17] = "<B=Tab/Escape> Returns to the command line.";
                    382:    mesg[18] = "";
                    383:    mesg[19] = "<C> (</B/24>Refer to the scrolling window online manual for more help<!B!24>.)";
                    384:    popupLabel (ScreenOf(entry), mesg, 20);
                    385: }
                    386: 
                    387: /*
                    388:  * This converts a word to upper case.
                    389:  */
                    390: char *uc (char *word)
                    391: {
                    392:    char *upper = 0;
                    393:    int length  = 0;
                    394:    int x;
                    395: 
                    396:    /* Make sure the word is not null. */
                    397:    if (word == 0)
                    398:    {
                    399:       return 0;
                    400:    }
                    401:    length = strlen (word);
                    402: 
                    403:    /* Get the memory for the new word. */
                    404:    upper = (char *)malloc (sizeof (char *) * (length+2));
                    405:    if (upper == 0)
                    406:    {
                    407:       return (word);
                    408:    }
                    409: 
                    410:    /* Start converting the case. */
                    411:    for (x=0; x < length; x++)
                    412:    {
                    413:       if (isalpha ((int)word[x]))
                    414:       {
                    415:         upper[x] = toupper(word[x]);
                    416:       }
                    417:       else
                    418:       {
                    419:         upper[x] = word[x];
                    420:       }
                    421:    }
                    422:    upper[length] = '\0';
                    423:    return upper;
                    424: }

CVSweb <webmaster@jp.NetBSD.org>