wndmenu.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 824 行 · 第 1/2 页

C
824
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Top level debugger menu.
*
****************************************************************************/


#include "dbgdefn.h"
#include "dbgtoggl.h"
#include "dbginfo.h"
#include "dbgtoken.h"
#include "dbgwind.h"
#include "dbgerr.h"
#include "trpcore.h"
#include "madcli.h"
#include <ctype.h>
#include <string.h>

extern a_window         *WndClassInspect( wnd_class class );
extern void             DebugExit( void );
extern void             DlgSource( void );
extern char             *ReScan( char * );
extern void             ProcSearchAll( void );
extern void             ProcWndSearch( a_window * );
extern void             ProcWndFindNext( a_window * );
extern void             ProcWndFindPrev( a_window * );
extern void             DlgOptSet( void );
extern void             DlgCmd( void );
extern void             DoSystem( char *, unsigned int, int );
extern void             ExecTrace( trace_cmd_type, debug_level );
extern unsigned         Go( bool );
extern void             ReStart( void );
extern bool             SetProgStartHook( bool );
extern void             GoToReturn( void );
extern void             DlgNewProg( void );
extern bool             DlgBreak( address );
extern void             BreakSave( bool );
extern void             ReplaySave( bool );
extern void             BrkEnableAll( void );
extern void             BrkDisableAll( void );
extern void             BrkClearAll( void );
extern void             ConfigSave( bool );
extern void             ReqEOC( void );
extern bool             ScanEOC( void );
extern unsigned         ScanCmd( char *cmd_table );
extern bool             ScanItem( bool, char **, unsigned int * );
extern wnd_class        ReqWndName( void );
extern char             *StrCopy( char *, char * );
extern void             FileBrowse( void );
extern void             LastMachState( void );
extern void             LastStackPos( void );
extern void             MoveStackPos( int by );
extern void             PosMachState( int rel_pos );
extern void             Flip( unsigned );
extern void             WndAsmInspect( address );
extern void             WndSrcInspect( address );
extern void             DlgAbout( void );
extern void             FontChange( void );
extern void             ToggleHardMode( void );
extern void             WndDumpPrompt( a_window * );
extern void             WndDumpLog( a_window * );
extern char             *GetCmdName( int );
extern void             DlgWndSet( void );
extern bool             VarInfoRelease( void );
extern void             SkipToAddr( address );
extern void             GoToAddr( address );
extern address          GetCodeDot( void );
extern void             ToggleBreak( address );
extern void             FuncNewMod( a_window *wnd, mod_handle mod );
extern void             GlobNewMod( a_window *wnd, mod_handle mod );
extern void             ModNewHandle( a_window *wnd, mod_handle mod );
extern void             GoHome( void );
extern void             DoProcHelp( gui_help_actions );
extern void             DlgBreakDLL( void );
extern bool             DebugScreen( void );
extern void             UnknownScreen( void );
extern bool             DlgCodeAddr( char *title, address *value );
extern bool             DlgDataAddr( char *title, address *value );
extern void             WndAddrInspect( address addr );
extern void             RegFindData( mad_type_kind kind, mad_reg_set_data const **pdata );

extern address          NilAddr;
extern debug_level      DbgLevel;
extern void             *BrkList;
extern system_config    SysConfig;

#include "menudef.h"
static gui_menu_struct FileMenu[] = {
    #include "mmfile.h"
};

static gui_menu_struct SearchMenu[] = {
    #include "mmsearch.h"
};

static gui_menu_struct RunMenu[] = {
    #include "mmrun.h"
};

static gui_menu_struct BreakMenu[] = {
    #include "mmbreak.h"
};

static gui_menu_struct CodeMenu[] = {
    #include "mmcode.h"
};

static gui_menu_struct DataMenu[] = {
    #include "mmdat.h"
};

static gui_menu_struct UndoMenu[] = {
    #include "mmundo.h"
};

static gui_menu_struct WindowMenu[] = {
    #include "mmwind.h"
};

static gui_menu_struct HelpMenu[] = {
    #include "mmhelp.h"
};

static gui_menu_struct DummyMenu;


gui_menu_struct WndMainMenu[] = {
    MENU_CASCADE( MENU_MAIN_FILE, MainMenuFile, FileMenu )
    MENU_CASCADE( MENU_MAIN_RUN, MainMenuRun, RunMenu )
    MENU_CASCADE( MENU_MAIN_BREAK, MainMenuBreak, BreakMenu )
    MENU_CASCADE( MENU_MAIN_CODE, MainMenuCode, CodeMenu )
    MENU_CASCADE( MENU_MAIN_DATA, MainMenuData, DataMenu )
    MENU_CASCADE( MENU_MAIN_UNDO, MainMenuUndo, UndoMenu )
    MENU_CASCADE( MENU_MAIN_SEARCH, MainMenuSearch, SearchMenu )
    MENU_CASCADE( MENU_MAIN_WINDOW, MainMenuWindow, WindowMenu )
    MENU_CASCADE( MENU_MAIN_ACTION, MainMenuAction, &DummyMenu )
    MENU_CASCADE( MENU_MAIN_HELP, MainMenuHelp, HelpMenu )
};

int     WndNumMenus = { WndMenuSize( WndMainMenu ) };

wnd_info *WndInfoTab[] = {
#define pick( a,b,c,d,e,f ) &d,
#include "wndnames.h"
};

char MainTab[] = { "MAin\0" };

extern void PlayDead( bool dead )
{
    WndIgnoreAllEvents = dead;
    #if defined(__GUI__) && (defined(__WINDOWS__) || defined(__NT__))
        if( dead ) {
            UnknownScreen(); // the trap file might steal focus!
        } else {
            DebugScreen();
        }
    #endif
}


static bool StrAmpEqual( char *str, char *menu, int len )
{
    char        *p;
    char        menu_accel;

    while( *str == ' ' ) {
        ++str;
        --len;
    }
    // first look for a matching accelerator character
    menu_accel = 0;
    for( p = str; *p; ++p ) {
        if( *p == '&' ) {
            menu_accel = tolower( p[1] );
            break;
        }
    }
    if( menu_accel ) {
        for( p = menu; *p; ++p ) {
            if( *p == '&' ) {
                if( tolower( p[1] ) == menu_accel ) return( TRUE );
                break;
            }
        }
    }
    while( len > 0 && str[ len-1 ] == ' ' ) {
        --len;
    }
    while( --len >= 0 ) {
        if( *menu == '&' ) ++menu;
        if( tolower( *menu ) != tolower( *str ) ) return( FALSE );
        if( *menu == '\0' ) return( FALSE );
        ++menu;
        ++str;
    }
    return( TRUE );
}

static gui_menu_struct *FindMainMenu( gui_menu_struct *main, int size )
{
    char                *start;
    unsigned            len;

    if( !ScanItem( TRUE, &start, &len ) ) return( NULL );
    while( --size >= 0 ) {
        if( StrAmpEqual( start, main->label, len ) ) break;
        ++main;
    }
    if( size < 0 ) return( NULL );
    return( main );
}


char *GetMenuLabel( unsigned size,
                    gui_menu_struct *menu, unsigned id, char *buff, bool strip_amp )
{
    char        *p;

    while( size != 0 ) {
        if( menu->id == id ) {
            for( p = menu->label; *p != '\0'; ++p ) {
                if( *p == '&' && strip_amp ) continue;
                if( *p == '\t' ) break;
                *buff++ = *p;
            }
            *buff = '\0';
            return( buff );
        }
        if( menu->num_child_menus != 0 ) {
            p = GetMenuLabel( menu->num_child_menus, menu->child, id, buff, strip_amp );
            if( p != NULL ) return( p );
        }
        --size;
        ++menu;
    }
    return( NULL );
}

static gui_menu_struct *FindSubMenu( char *start, unsigned len, gui_menu_struct *child, int size )
{
    gui_menu_struct     *sub;

    while( --size >= 0 ) {
        if( StrAmpEqual( start, child->label, len ) ) {
            return( child );
        }
        if( child->num_child_menus != NULL ) {
            sub = FindSubMenu( start, len, child->child, child->num_child_menus );
            if( sub != NULL ) return( sub );
        }
        ++child;
    }
    return( NULL );
}

#ifdef DEADCODE
int FindMenuLen( gui_menu_struct *child )
{
    char        *p;

    p = child->label + strlen( child->label ) - 1;
    while( *p == ' ' ) --p;
    if( *p == ')' ) {
        while( *p != '(' ) --p;
        --p;
        while( *p == ' ' ) --p;
    }
    return( p - child->label + 1 );
}
#endif


void AccelMenuItem( gui_menu_struct *menu, bool is_main )
{
    a_window    *wnd = WndFindActive();

    if( is_main ) {
        WndMainMenuProc( wnd, menu->id );
    } else {
        WndKeyPopUp( wnd, menu );
        WndNoSelect( wnd );
    }
}

static bool DoProcAccel( bool add_to_menu, gui_menu_struct **menu,
                  gui_menu_struct **parent, int *num_siblings, wnd_class class )
{
    gui_menu_struct     *main;
    gui_menu_struct     *child;
    wnd_info            *info;
    a_window            *wnd;
    char                *start;
    unsigned            len;

    *menu = *parent = NULL;
    child = NULL;
    if( ScanCmd( MainTab ) ) {
        main = FindMainMenu( WndMainMenu, ArraySize( WndMainMenu ) );
        if( main == NULL ) {
            if( add_to_menu ) return( TRUE );
            Error( ERR_NONE, LIT( ERR_WANT_MENU_ITEM ) );
        }
        if( ScanItem( TRUE, &start, &len ) ) {
            child = FindSubMenu( start, len, main->child, main->num_child_menus );
        }
        if( child == NULL ) {
            if( add_to_menu ) return( TRUE );
            Error( ERR_NONE, LIT( ERR_WANT_MENU_ITEM ) );
        }
        *menu = child;
        *parent = main->child;
        *num_siblings = main->num_child_menus;
        if( add_to_menu ) return( TRUE );
        ReqEOC();
        AccelMenuItem( child, TRUE );
    } else {
        info = WndInfoTab[ class ];
        if( ScanItem( TRUE, &start, &len ) ) {
            child = FindSubMenu( start, len, info->popupmenu, info->num_popups );
        }
        if( child == NULL ) {
            if( add_to_menu ) return( FALSE );
            Error( ERR_NONE, LIT( ERR_WANT_MENU_ITEM ) );
        }
        *menu = child;
        *parent = info->popupmenu;
        *num_siblings = info->num_popups;
        if( add_to_menu ) return( FALSE );
        wnd = WndFindActive();
        if( WndClass( wnd ) != class ) Error( ERR_NONE, LIT( ERR_MACRO_NOT_VALID ) );
        ReqEOC();
        AccelMenuItem( child, FALSE );
    }
    return( FALSE );
}

extern void ProcAccel( void )
{
    gui_menu_struct     *menu,*parent;
    int                 num_sibs;

    DoProcAccel( FALSE, &menu, &parent, &num_sibs, WndClass( WndFindActive() ));
}

static void FreeLabels( gui_menu_struct *menu, int num_menus )
{
    while( --num_menus >= 0 ) {
        if( menu->id != MENU_MAIN_ACTION && menu->child != NULL ) {
            FreeLabels( menu->child, menu->num_child_menus );
        }
        if( menu->style & WND_MENU_ALLOCATED ) {
            menu->style &= ~WND_MENU_ALLOCATED;
            WndFree( menu->label );
            WndFree( menu->hinttext );
        }
        ++menu;
    }
}


static void LoadLabels( gui_menu_struct *menu, int num_menus )
{
    while( --num_menus >= 0 ) {
        if( menu->child != NULL ) {
            LoadLabels( menu->child, menu->num_child_menus );
        }
        if( !( menu->style & (GUI_SEPARATOR|WND_MENU_ALLOCATED) ) ) {
            menu->label = WndLoadString( (int)menu->label );
            menu->hinttext = WndLoadString( (int)menu->hinttext );
            menu->style |= WND_MENU_ALLOCATED;
        }
        ++menu;
    }
}

void SetBrkMenuItems( void )
{
    bool        on;

    on = ( BrkList != NULL );
    WndEnableMainMenu( MENU_MAIN_BREAK_CLEAR_ALL, on );
    WndEnableMainMenu( MENU_MAIN_BREAK_DISABLE_ALL, on );
    WndEnableMainMenu( MENU_MAIN_BREAK_ENABLE_ALL, on );
    WndEnableMainMenu( MENU_MAIN_BREAK_SAVE_ALL, on );
}

void SetLogMenuItems( bool active )

⌨️ 快捷键说明

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