dbgwmem.c

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

C
1,074
字号
    }
    return( TRUE );
}

static void MemResize( a_window *wnd )
{
    mem_window          *mem = WndMem( wnd );
    int                 mult;
    wnd_line_piece      line;
    unsigned            curr_offset;

    curr_offset = MemCurrOffset( wnd );
    if( mem->stack ) {
        MemSetStartAddr( wnd, Context.stack, TRUE );
        WndZapped( wnd );
        return;
    }
    if( mem->piece_type == MemByteType ) {
        mult = 2;
    } else {
        mult = 1;
    }
    for( mem->items_per_line = MemData.info[ mem->piece_type ].items_per_line;
         mem->items_per_line > 1; --mem->items_per_line ) {
        MemGetLine( wnd, 0, mem->items_per_line*mult, &line );
        line.indent += WndExtentX( wnd, line.text );
        if( line.indent <= WndWidth( wnd ) ) break;
    }
    MemSetCurrent( wnd, curr_offset );
    MemRefresh( wnd );
}

static  WNDMENU MemMenuItem;
static void     MemMenuItem( a_window *wnd, unsigned id, int row, int piece )
{
    mem_window  *mem = WndMem( wnd );

    --piece;
    if( piece >= mem->items_per_line ) piece -= mem->items_per_line;
    switch( id ) {
    case MENU_INITIALIZE:
        WndMenuEnable( wnd, MENU_MEMORY_MODIFY, CanModify( wnd, row, piece ) );
        WndMenuEnable( wnd, MENU_MEMORY_LEFT, !mem->file );
        WndMenuEnable( wnd, MENU_MEMORY_RIGHT, !mem->file );
        WndMenuEnable( wnd, MENU_MEMORY_ASSEMBLY, !mem->file );
        WndMenuEnable( wnd, MENU_MEMORY_ADDRESS, !mem->file );
        WndMenuEnable( wnd, MENU_MEMORY_BREAK_WRITE, !mem->file );
        WndMenuEnable( wnd, MENU_MEMORY_FOLLOW_NEAR, !mem->file );
        WndMenuEnable( wnd, MENU_MEMORY_FOLLOW_FAR, !mem->file );
        WndMenuEnable( wnd, MENU_MEMORY_FOLLOW_CURSOR, !mem->file && WndHasCurrent( wnd ) || mem->total_size != 0 );
        WndMenuEnable( wnd, MENU_MEMORY_FOLLOW_SEGMENT, !mem->file );
        WndMenuEnable( wnd, MENU_MEMORY_HOME, !mem->file );
        WndMenuEnable( wnd, MENU_MEMORY_REPEAT, !mem->file &&
                            ( mem->u.m.follow || mem->total_size != 0 ) );
        WndMenuEnable( wnd, MENU_MEMORY_PREV, !mem->file && mem->u.m.backout );
        break;
    case MENU_MEMORY_ASSEMBLY:
        WndAsmInspect( AddrAddWrap( mem->u.m.addr, MemCurrOffset( wnd ) ) );
        break;
    case MENU_MEMORY_FOLLOW_FAR:
        DoFollow( wnd, "%%(.%o)" );
        break;
    case MENU_MEMORY_FOLLOW_NEAR:
        DoFollow( wnd, "*(.%o)" );
        break;
    case MENU_MEMORY_FOLLOW_SEGMENT:
        DoFollow( wnd, "(*(short*)(.%o)):0" );
        break;
    case MENU_MEMORY_FOLLOW_CURSOR:
        MemNewBackout( wnd );
        WndFree( mem->u.m.follow );
        mem->u.m.follow = NULL;
        if( WndHasCurrent( wnd ) ) {
            mem->total_size = MemCurrOffset( wnd );
        }
        MemFollow( wnd );
        break;
    case MENU_MEMORY_HOME:
        while( mem->u.m.backout != NULL ) {
            MemBackout( wnd );
        }
        MemSetStartAddr( wnd, mem->u.m.home, TRUE );
        MemSetCurrent( wnd, 0 );
        WndRepaint( wnd );
        break;
    case MENU_MEMORY_REPEAT:
        MemNewBackout( wnd );
        MemFollow( wnd );
        break;
    case MENU_MEMORY_PREV:
        MemBackout( wnd );
        break;
    case MENU_MEMORY_BREAK_WRITE:
        SetBreakWrite( wnd );
        break;
    case MENU_MEMORY_MODIFY:
        MemModify( wnd, row, piece+1 );
        break;
    case MENU_MEMORY_ADDRESS:
        MemGetNewAddr( wnd );
        break;
    case MENU_MEMORY_LEFT:
        MemScrollBytes( wnd, -mem->item_size, FALSE );
        WndNoSelect( wnd );
        WndRepaint( wnd );
        break;
    case MENU_MEMORY_RIGHT:
        MemScrollBytes( wnd, mem->item_size, FALSE );
        WndNoSelect( wnd );
        WndRepaint( wnd );
        break;
    default:
        MemSetType( wnd, PIECE_TYPE( id ) );
        MemResize( wnd );
        WndZapped( wnd );
        break;
    }
}

static WNDREFRESH StkRefresh;
static  void StkRefresh( a_window *wnd )
{
    MemSetStartAddr( wnd, Context.stack, TRUE );
    WndZapped( wnd );
}


static  WNDSCROLL       MemScroll;
static  int     MemScroll( a_window *wnd, int lines )
{
    int         tomove;
    long        offset;
    long        new;
    mem_window  *mem = WndMem( wnd );

    if( lines >= WND_MAX_ROW ) return( 0 ); // CTRL-END request
    if( mem->cursor_row != WND_NO_ROW &&
        mem->piece_type == MemByteType ) {
        WndPieceDirty( wnd, mem->cursor_row, mem->shadow_piece );
    }
    tomove = mem->items_per_line*mem->item_size*lines;
    if( mem->total_size != 0 ) return( 0 );
    if( mem->file ) {
        offset = mem->u.f.offset+tomove;
        if( offset < 0 ) offset = 0;
        new = SeekStream( mem->u.f.filehndl, offset, DIO_SEEK_ORG );
        if( new != offset ) return( 0 );
        if( ReadStream( mem->u.f.filehndl, TxtBuff, 1 ) != 1 ) return( 0 );
        mem->u.f.offset = offset;
        WndSetVScrollRange( wnd, WndRows( wnd ) * 2 );
        WndSetThumbPercent( wnd, ( offset * 100 ) / mem->u.f.size );
    } else {
        if( !MemScrollBytes( wnd, tomove, FALSE ) ) {
            lines = 0;
        }
    }
    WndRowDirty( wnd, -TITLE_SIZE );
    return( lines );
}

void InitMemWindow()
{
    int                 i;

    MemInitTypes( MAS_MEMORY | MTK_ALL, &MemData );
    MemTypeMenu = WndMustAlloc( MemData.num_types * sizeof( *MemTypeMenu ) );
    for( i = 0; i < MemData.num_types; ++i ) {
        MemTypeMenu[ i ].id = MENU_MEMORY_FIRST_TYPE + i;
        MemTypeMenu[ i ].style = GUI_ENABLED | WND_MENU_ALLOCATED;
        MemTypeMenu[ i ].label = DupStr( MemData.labels[ i ] );
        MemTypeMenu[ i ].hinttext = DupStr( LIT( Empty ) );
        MemTypeMenu[ i ].num_child_menus = 0;
        MemTypeMenu[ i ].child = NULL;
    }
    for( i = 0; i < ArraySize( MemMenu ); ++i ) {
        if( MemMenu[ i ].id == MENU_MEMORY_TYPE ) {
            MemMenu[ i ].child = MemTypeMenu;
            MemMenu[ i ].num_child_menus = MemData.num_types;
            break;
        }
    }
    MemByteType = 0;
    for( i = 0; i < MemData.num_types; ++i ) {
        if( MemData.info[ i ].item_size == 1 &&
            MemData.info[ i ].piece_radix == 16 ) {
            MemByteType = i;
            break;
        }
    }
}

void FiniMemWindow()
{
    WndFree( MemTypeMenu );
    MemFiniTypes( &MemData );
}

static WNDCALLBACK MemEventProc;
static bool MemEventProc( a_window * wnd, gui_event gui_ev, void *parm )
{
    mem_window  *mem = WndMem( wnd );
    unsigned long old;
    int         i;

    parm=parm;
    switch( gui_ev ) {
    case GUI_INIT_WINDOW:
        if( mem->init_type != MAD_NIL_TYPE_HANDLE ) {
            mem->piece_type = MemByteType;
            for( i = 0; i < MemData.num_types; i++ ) {
                if( MemData.info[ i ].type == mem->init_type ) break;
            }
            if( i != MemData.num_types ) {
                mem->piece_type = i;
            }
        }
        MemSetType( wnd, mem->piece_type ); /* stashed here by Open routine */
        if( mem->file ) {
            mem->u.f.offset = 0;
            if( mem->u.f.filehndl != NIL_HANDLE ) {
                old = SeekStream( mem->u.f.filehndl, 0L, DIO_SEEK_END );
                mem->u.f.size = SeekStream( mem->u.f.filehndl, old, DIO_SEEK_ORG );
            }
        } else {
            mem->u.m.follow = NULL;
            mem->u.m.backout = NULL;
        }
        mem->total_size = 0;
        mem->cursor_row = WND_NO_ROW;
        mem->last_type_popup = 0;
        MemRefresh( wnd );
        /* fall through */
    case GUI_RESIZE:
        MemResize( wnd );
        WndFixedThumb( wnd );
        return( TRUE );
    case GUI_DESTROY :
        if( mem->file && mem->u.f.filehndl != NULL ) {
            FileClose( mem->u.f.filehndl );
        }
        if( !mem->file ) {
            WndFree( mem->u.m.contents );
            WndFree( mem->u.m.follow );
            while( mem->u.m.backout != NULL ) MemFreeBackout( mem );
        }
        WndFree( mem );
        return( TRUE );
    case GUI_NO_EVENT : // sent whenever WndDirtyCurr is called
        MemUpdateCursor( wnd );
        return( TRUE );
    }
    return( FALSE );
}

wnd_info BinInfo = {
    MemEventProc,
    MemRefresh,
    MemGetLine,
    MemMenuItem,
    MemScroll,
    NoBegPaint,
    NoEndPaint,
    MemModify,
    NoNumRows,
    NoNextRow,
    NoNotify,
    UP_RADIX_CHANGE,
    DefPopUp( MemMenu )
};

wnd_info MemInfo = {
    MemEventProc,
    MemRefresh,
    MemGetLine,
    MemMenuItem,
    MemScroll,
    NoBegPaint,
    NoEndPaint,
    MemModify,
    NoNumRows,
    NoNextRow,
    NoNotify,
    UP_RADIX_CHANGE+UP_MEM_CHANGE+UP_SYM_CHANGE+UP_NEW_PROGRAM,
    DefPopUp( MemMenu )
};

wnd_info StkInfo = {
    MemEventProc,
    StkRefresh,
    MemGetLine,
    MemMenuItem,
    MemScroll,
    NoBegPaint,
    NoEndPaint,
    MemModify,
    NoNumRows,
    NoNextRow,
    NoNotify,
    UP_RADIX_CHANGE+UP_MEM_CHANGE+UP_STACKPOS_CHANGE+UP_REG_CHANGE+UP_SYM_CHANGE+UP_NEW_PROGRAM,
    DefPopUp( MemMenu )
};

extern  a_window        *DoWndMemOpen( address addr, mad_type_handle type )
{
    mem_window  *mem;
    a_window    *wnd;

    MemValidAddr( addr );
    mem = WndMustAlloc( sizeof( mem_window ) );
    mem->u.m.addr = mem->u.m.home = addr;
    mem->u.m.contents = NULL;
    SetDataDot( addr );
    mem->file = FALSE;
    mem->stack = FALSE;
    mem->init_type = type;
    mem->piece_type = MemByteType;
    wnd = DbgTitleWndCreate( MemGetTitle( mem ), &MemInfo, WND_MEMORY, mem, &MemIcon, TITLE_SIZE, FALSE );
    return( wnd );
}

extern  a_window        *WndMemOpen()
{
    return( DoWndMemOpen( NilAddr, MAD_NIL_TYPE_HANDLE ) );
}


extern WNDOPEN WndStkOpen;
extern  a_window        *WndStkOpen()
{
    a_window    *wnd;
    mem_window  *mem;

    mem = WndMustAlloc( sizeof( mem_window ) );
    mem->u.m.addr = mem->u.m.home = Context.stack;
    mem->u.m.contents = NULL;
    mem->init_type = GetMADTypeHandleDefaultAt( Context.stack, MTK_INTEGER );
    mem->file = FALSE;
    mem->stack = TRUE;
    wnd = DbgTitleWndCreate( LIT( WindowStack ), &StkInfo, WND_STACK, mem, &StkIcon, TITLE_SIZE, FALSE );
    return( wnd );
}


extern  a_window        *DoWndBinOpen( char *name, handle filehndl )
{
    mem_window  *mem;
    a_window    *wnd;

    mem = WndMustAlloc( sizeof( mem_window ) );
    mem->file = TRUE;
    mem->stack = FALSE;
    mem->init_type = MAD_NIL_TYPE_HANDLE;
    mem->piece_type = MemByteType;
    mem->u.f.filehndl = filehndl;
    wnd = DbgTitleWndCreate( name, &BinInfo, WND_BINARY, mem, &MemIcon, TITLE_SIZE, FALSE );
    return( wnd );
}

⌨️ 快捷键说明

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