home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name MNMCHKEY - Match a key to a specification.
- *
- * Synopsis presult = mnmchkey (pmenu, pkey, ch, scan, perror);
- *
- * BKEYMAP *presult Pointer to the key in the
- * menu's key list which matches
- * ch and scan, or NIL for
- * failure.
- * BMENU *pmenu Pointer to menu in which to
- * search key list. Needed if we
- * get to the end of the key list
- * and have to wrap around.
- * BKEYMAP *pkey Pointer to key in list to start
- * search at, or NIL to start at
- * first key.
- * int ch, Character code and scan code to
- * scan search for in key list.
- * int *pcode Pointer to variable to return
- * error code in. NIL if error code
- * should not be returned.
- *
- * Description MNMCHKEY searches from a given point in the key
- * list of a menu for a keymap entry matching a
- * particular specification.
- *
- * It only matches enabled keys (keys without the
- * MN_DISABLE bit set).
- *
- * It skips keys with the same row, col, and action
- * fields as those in pkey. This enables menus
- * such as the following to work:
- *
- * +--------+
- * | Quit | <-- bound to "Qq"
- * | Create | <-- bound to "Cc"
- * | Close | <-- bound to "Cc"
- * +--------+
- *
- * The way this works is that the highlight bar moves
- * to "Create" the first time upper or lower-case "C"
- * is pressed, and then alternates between "Create"
- * and "Close" as "C"'s are pressed.
- *
- * Returns presult Pointer to BKEYMAP found, or
- * NIL if failure.
- *
- * Version 6.00 (C)Copyright Blaise Computing Inc. 1987,1989
- *
- **/
-
-
- #include <bkeybrd.h>
- #include <bmenu.h>
-
- #define TRUE 1
- #define FALSE 0
-
-
- const BKEYMAP *mnmchkey (pmenu, pkey, ch, scan, pcode)
- const BMENU *pmenu;
- const BKEYMAP *pkey;
- int ch, scan;
- int *pcode;
- {
- BKEYMAP *pstart = (pkey == NIL) ? (pmenu->pkeys) : (pkey);
- BKEYMAP *qkey = pstart;
- BKEYMAP *rkey = NIL;
- BKEYMAP *skey = NIL;
- int done = FALSE;
- int first = TRUE;
-
- if (pcode != NIL)
- *pcode = WN_NO_ERROR;
-
- /* Exit immediately if there is no key list. */
- if (pstart == NIL)
- return (NIL);
-
- /* Check each key list entry to see if it matches */
- /* the given specification. */
- for (;
- !done;
- qkey = qkey->next)
- {
- if (qkey == NIL)
- qkey = pmenu->pkeys;
-
- if ((qkey == pstart) && !first)
- done = TRUE;
-
- /* Check key signature. */
- if (qkey->signature != MN_KEY_SIGN)
- {
- if (pcode != NIL)
- *pcode = MN_BAD_KEY;
-
- wnreterr (MN_BAD_KEY);
- }
-
- /* If *qkey is not disabled, */
- if (( !(qkey->action & MN_DISABLE)) &&
- ( !(qkey->action & MN_TEMP_DISABLE)) &&
- /* and the character and scan codes match the ones */
- /* we are looking for, save a pointer to it. */
- ((qkey->ch == ch) && (qkey->scan == scan)))
-
- skey = qkey;
-
- /* If *qkey is not disabled, */
- if (( !(qkey->action & MN_DISABLE)) &&
- ( !(qkey->action & MN_TEMP_DISABLE)) &&
- /* and the character and scan codes match the ones */
- /* we are looking for, */
- ((qkey->ch == ch) && (qkey->scan == scan)) &&
- /* and at least one of the following is true: */
- /* 1. There was no previous key; */
- ((pkey == NIL) ||
- /* 2. We went all the way around the list and the */
- /* key we were given at first is the only one */
- /* which matches the specification; */
- ((qkey == pkey) && !first) ||
- /* 3. At least one component of the key we are */
- /* looking at is different from that of the key */
- /* we were given to start with. */
- (pkey->row != qkey->row) ||
- (pkey->col != qkey->col) ||
- (pkey->action != qkey->action)))
- {
- rkey = qkey;
- done = TRUE;
- }
-
- first = FALSE;
- }
-
- return ((rkey == NIL) ? skey : rkey);
- }