⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wmenu.c

📁 详细介绍了一篇关于pci开发的接口芯片
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  CXL - Copyright (c) 1987-1989 by Mike Smedley - All Rights Reserved  */
/*  WMENU.C  -  wmenubeg()  starts a menu definition
                wmenuitem() defines a menu item
                wmenuend()  ends a menu definition
                wmenuget()  processes the defined menu      */

#include <conio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "cxldef.h"
#include "cxlkey.h"
#include "cxlmou.h"
#include "cxlvid.h"
#include "cxlwin.h"

/* prototypes for local functions */
static int              calc_bar_width(struct _menu_t *wmenu,
                                       struct _item_t *witem);
static int              calc_center_item(struct _item_t *item);
static void             call_after(struct _item_t *citem);
static void             call_before(struct _item_t *citem);
static void             call_func(void (*func)(void));
static void             close_window(WINDOW w);
static void             disp_item(struct _item_t *witem,int bar);
static struct _item_t  *down_item(struct _item_t *curr);
static struct _item_t  *first_item(void);
static void             free_menu(struct _menu_t *wmenu);
static struct _item_t  *goto_item(struct _item_t *citem,int which);
static void             hide_mouse_cursor(void);
static struct _item_t  *last_item(void);
static struct _item_t  *left_item(struct _item_t *curr);
static struct _item_t  *mouse_on_item(struct _menu_t *menu,int mrow,int mcol);
static void             post_move(struct _item_t *citem);
static void             pre_exit(WINDOW w,int close);
static void             pre_move(struct _item_t *citem);
static int              read_mouse(struct _item_t *citem);
static struct _item_t  *right_item(struct _item_t *curr);
static void             show_mouse_cursor(void);
static struct _item_t  *up_item(struct _item_t *curr);

/*---------------------------------------------------------------------------*/

/* menu item movement definitions */
#define ITM_LT  0
#define ITM_RT  1
#define ITM_UP  2
#define ITM_DN  3
#define ITM_FR  4
#define ITM_LS  5

/*---------------------------------------------------------------------------*/

/* array of function pointers to some of the item movement functions */
static struct _item_t *(*funcs[4])(struct _item_t *) =
    { left_item,right_item,up_item,down_item };

/* flag used for initial display of menu selections */
static int _Near _Cdecl dispdesc=YES;

/*---------------------------------------------------------------------------*/

int wmenubeg(int srow,int scol,int erow,int ecol,int btype,int battr,
             int wattr,void (*open)(void))
{
    struct _menu_t *wmenu;

    /* if this is a submenu, then make sure that it is under a menu item */
    if(_winfo.mlevel>_winfo.ilevel) return(_winfo.errno=W_NOITMDEF);

    /* allocate memory for new menu record */
    if((wmenu=malloc(sizeof(struct _menu_t)))==NULL)
        return(_winfo.errno=W_ALLOCERR);

    /* if menu is not a submenu, make it a new base menu record */
    if(!_winfo.mlevel) {
        if(_winfo.menu!=NULL) _winfo.menu->next=wmenu;
        wmenu->prev=_winfo.menu;
        wmenu->next=NULL;
        wmenu->parent=NULL;
        _winfo.menu=_winfo.cmenu=wmenu;
    }
    else {
        wmenu->parent=_winfo.cmenu;
        _winfo.cmenu=_winfo.cmenu->item->child=wmenu;
    }

    /* save info in menu record */
    wmenu->srow=srow;
    wmenu->scol=scol;
    wmenu->erow=erow;
    wmenu->ecol=ecol;
    wmenu->btype=btype;
    wmenu->battr=mapattr(battr);
    wmenu->wattr=mapattr(wattr);
    wmenu->open=open;
    wmenu->usecurr=NO;
    wmenu->item=NULL;

    /* increment menu level */
    _winfo.mlevel++;

    /* return normally */
    return(_winfo.errno=W_NOERROR);
}

/*---------------------------------------------------------------------------*/

int wmenuitem(int wrow,int wcol,char *str,int schar,int tagid,int fmask,
              void (*select)(void),unsigned hotkey,int help)
{
    struct _item_t *witem;

    /* make sure that wmenubeg() or wmenubegc() has been called */
    if(!_winfo.mlevel) return(_winfo.errno=W_NOMNUBEG);

    /* allocate memory for new item record */
    if((witem=malloc(sizeof(struct _item_t)))==NULL)
        return(_winfo.errno=W_ALLOCERR);

    /* add new menu item record to linked list */
    if(_winfo.cmenu->item!=NULL) _winfo.cmenu->item->next=witem;
    witem->prev=_winfo.cmenu->item;
    witem->next=NULL;
    _winfo.cmenu->item=witem;

    /* save info in item record */
    witem->wrow   = wrow;
    witem->wcol   = wcol;
    witem->str    = str;
    witem->schar  = schar;
    witem->tagid  = tagid;
    witem->fmask  = fmask;
    witem->select = select;
    witem->hotkey = hotkey;
    witem->desc   = NULL;
    witem->dwrow  = 0;
    witem->dwcol  = 0;
    witem->dattr  = 0;
    witem->redisp = NO;
    witem->help   = help;
    witem->child  = NULL;
    witem->before =
    witem->after  = NULL;

    /* set item level == menu level */
    _winfo.ilevel=_winfo.mlevel;

    /* return normally */
    return(_winfo.errno=W_NOERROR);
}

/*---------------------------------------------------------------------------*/

int wmenuend(int taginit,int menutype,int barwidth,int textpos,
             int textattr,int scharattr,int noselattr,int barattr)
{
    struct _item_t *item;
    int w_width,border,found;

    /* make sure at least 1 menu item has been defined */
    if(!_winfo.mlevel||_winfo.mlevel>_winfo.ilevel)
        return(_winfo.errno=W_NOITMDEF);

    /* make sure that the specified initial tagid matches the */
    /* tagid of one of the defined menu items in this menu    */
    for(found=NO,item=_winfo.cmenu->item;item!=NULL;item=item->prev) {
        if(item->tagid==taginit) {
            found=YES;
            break;
        }
    }
    if(!found) return(_winfo.errno=W_INVTAGID);

    /* if bar width > window width, then bar width = window width */
    border=(_winfo.cmenu->btype==5)?0:1;
    w_width=(_winfo.cmenu->ecol-border)-(_winfo.cmenu->scol+border)+1;
    if(barwidth>w_width) barwidth=w_width;

    /* add rest of menu information to menu record */
    _winfo.cmenu->citem     = NULL;
    _winfo.cmenu->tagcurr   = taginit;
    _winfo.cmenu->menutype  = menutype;
    _winfo.cmenu->barwidth  = barwidth;
    _winfo.cmenu->textpos   = barwidth?textpos:0;
    _winfo.cmenu->textattr  = mapattr(textattr);
    _winfo.cmenu->scharattr = mapattr(scharattr);
    _winfo.cmenu->noselattr = mapattr(noselattr);
    _winfo.cmenu->barattr   = _vinfo.mapattr?revsattr(_winfo.cmenu->textattr):
                              barattr;

    /* set current menu pointer to parent menu */
    if((_winfo.cmenu=_winfo.cmenu->parent)==NULL) _winfo.cmenu=_winfo.menu;

    /* decrement menu and item levels */
    _winfo.mlevel--;
    _winfo.ilevel--;

    /* return with no error */
    return(_winfo.errno=W_NOERROR);
}


/*---------------------------------------------------------------------------*/

int wmenuget(void)
{
    register unsigned int xch;
    register struct _item_t *citem;
    struct _item_t *item;
    int valid,pulldown=NO,menuerr,winerr,err;
    char ch;
    WINDOW w;

    /* make sure we have a defined menu */
    if(_winfo.cmenu==NULL) {
        _winfo.errno=W_NOMNUDEF;
        return(-1);
    }

    /* make sure that wmenuend() was called */
    if(_winfo.mlevel||_winfo.ilevel) {
        _winfo.errno=W_NOMNUEND;
        return(-1);
    }

    /* open menu's window (unless menu is to use current window) */
    if(!_winfo.cmenu->usecurr) {
        w=whandle();
        hide_mouse_cursor();
        if(!wopen(_winfo.cmenu->srow,_winfo.cmenu->scol,_winfo.cmenu->erow
          ,_winfo.cmenu->ecol,_winfo.cmenu->btype,_winfo.cmenu->battr
          ,_winfo.cmenu->wattr)) return(-1);
        show_mouse_cursor();

        /* save environment info, call menu open   */
        /* function, then restore environment info */
        if(_winfo.cmenu->open!=NULL) call_func(_winfo.cmenu->open);
    }

    /* if mouse cursor mode is on, show cursor */
    show_mouse_cursor();

    /* find first item in linked list */
    if((item=_winfo.cmenu->item)!=NULL) for(;item->prev!=NULL;item=item->prev);

    /* display all menu items */
    dispdesc=NO;
    valid=NO;
    while(item!=NULL) {
        disp_item(item,0);
        if(!(item->fmask&M_NOSEL)) valid=YES;
        item=item->next;
    }
    dispdesc=YES;

    /* make sure there is at least 1 selectable menu item */
    if(!valid) {
        pre_exit(w,YES);
        _winfo.errno=W_NOSELECT;
        return(-1);
    }

    /* search linked list of item records for the item matching    */
    /* the last item.  If there was no last item, search for       */
    /* the initial tag ID position.  If no initial tag ID position */
    /* was specified, then find the upper-leftmost menu item.      */
    citem=NULL;
    if(_winfo.cmenu->menutype&M_SAVE) {
        for(citem=_winfo.cmenu->item;citem!=NULL;citem=citem->prev) {
            if((_winfo.cmenu->citem==citem)&&
               (!(citem->fmask&M_NOSEL)))
                break;
        }
    }
    if(citem==NULL) {
        citem=wmenuifind(_winfo.cmenu->tagcurr);
        if((citem==NULL)||(citem->fmask&M_NOSEL)) citem=first_item();
    }

    /* call the current menu item's 'before'  */
    /* function and display current menu item */
    post_move(citem);

    /* main process of function */

    for(;;) {

        /* update current menu item and help category */
        _winfo.cmenu->citem=citem;
        _winfo.help=citem->help;

        /* read mouse/keyboard for keypress, then test the keypress */
        _kbinfo.inmenu=TRUE;
        xch=read_mouse(citem);
        citem=_winfo.cmenu->citem;
        if(!xch) xch=getxch();
        _kbinfo.inmenu=FALSE;
        switch(xch) {

            case 0x011b:    /* Esc */

                /* if Esc checking is on, erase selection bar, */
                /* free menu records and return to caller      */
                if(_winfo.esc||(_winfo.cmenu!=_winfo.menu)) {
                    pre_move(citem);
                    pre_exit(w,YES);
                    _winfo.errno=W_ESCPRESS;
                    return(-1);
                }
                break;

            case 0x4700:    /* Home */

                /* hide selection bar and find upper-leftmost menu item */
                citem=goto_item(citem,ITM_FR);
                break;

            case 0x4b00:    /* LeftArrow */

                /* if current menu is a pull-down menu,         */
                /* then erase selection bar, free menu records, */
                /* and return special code to caller            */
                if(_winfo.cmenu->menutype&M_PD) {
                    pre_move(citem);
                    pre_exit(w,YES);
                    _winfo.errno=W_NOERROR;
                    return(M_PREVPD);
                }

                /* if current menu is a horizontal menu, then hide */
                /* selection bar and find menu item to the left    */
                if(_winfo.cmenu->menutype&M_HORZ)
                    citem=goto_item(citem,ITM_LT);

                /* if pull-down menu flag is set, select this item */
                if(pulldown&&citem->child!=NULL) goto enter;
                break;

            case 0x4800:    /* UpArrow */

                /* if current menu is a vertical menu, then hide */
                /* selection bar and find menu item upwards      */
                if(_winfo.cmenu->menutype&(M_VERT|M_PD))
                    citem=goto_item(citem,ITM_UP);
                break;

            case 0x4d00:    /* RightArrow */

                /* if current menu is a pull-down menu,         */
                /* then erase selection bar, free menu records, */
                /* and return special code to caller            */
                if(_winfo.cmenu->menutype&M_PD) {
                    pre_move(citem);
                    pre_exit(w,YES);
                    _winfo.errno=W_NOERROR;
                    return(M_NEXTPD);
                }

                /* if current menu is a horizontal menu, then hide */
                /* selection bar and find menu item to the right   */
                if(_winfo.cmenu->menutype&M_HORZ)
                    citem=goto_item(citem,ITM_RT);

                /* if pulldown flag is set, then select this item */
                if(pulldown&&citem->child!=NULL) goto enter;
                break;

            case 0x5000:    /* DownArrow */

                /* if current item has a pull-down menu, select it */
                if(citem->fmask&M_HASPD) goto enter;

                /* if current menu is a vertical menu, then hide */
                /* selection bar and find menu item downwards    */
                if(_winfo.cmenu->menutype&(M_VERT|M_PD))
                    citem=goto_item(citem,ITM_DN);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -