mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-28 09:58:30 +01:00
When internal focus reaches edge of object, move it back up and onto
the next object using a callback to the platform to determine what, if any, object is next. Adjust curses platform to cooperate. Works well. Palm is next.
This commit is contained in:
parent
005fd92fd4
commit
9a00908cdb
5 changed files with 127 additions and 113 deletions
108
common/board.c
108
common/board.c
|
@ -1,4 +1,4 @@
|
|||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||
E/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||
/*
|
||||
* Copyright 1997 - 2002 by Eric House (xwords@eehouse.org). All rights reserved.
|
||||
*
|
||||
|
@ -113,8 +113,7 @@ static XP_Bool advanceArrow( BoardCtxt* board );
|
|||
|
||||
#ifdef KEY_SUPPORT
|
||||
static XP_Bool getArrow( BoardCtxt* board, XP_U16* col, XP_U16* row );
|
||||
static XP_Bool board_moveArrow( BoardCtxt* board, XP_Key cursorKey,
|
||||
XP_Bool canCycle );
|
||||
static XP_Bool board_moveArrow( BoardCtxt* board, XP_Key cursorKey );
|
||||
|
||||
static XP_Bool setArrowVisibleFor( BoardCtxt* board, XP_U16 player,
|
||||
XP_Bool visible );
|
||||
|
@ -1921,6 +1920,9 @@ invalCell( BoardCtxt* board, XP_U16 col, XP_U16 row )
|
|||
{
|
||||
board->redrawFlags[row] |= 1 << col;
|
||||
|
||||
XP_ASSERT( col < MAX_ROWS );
|
||||
XP_ASSERT( row < MAX_ROWS );
|
||||
|
||||
/* if the trade window is up and this cell intersects it, set up to draw
|
||||
it again */
|
||||
if ( (board->trayVisState != TRAY_HIDDEN) && TRADE_IN_PROGRESS(board) ) {
|
||||
|
@ -1936,29 +1938,6 @@ invalCell( BoardCtxt* board, XP_U16 col, XP_U16 row )
|
|||
board->needsDrawing = XP_TRUE;
|
||||
} /* invalCell */
|
||||
|
||||
#ifdef KEYBOARD_NAV
|
||||
static XP_Bool
|
||||
focusNext( BoardCtxt* board )
|
||||
{
|
||||
BoardObjectType typ;
|
||||
switch ( board->focussed ) {
|
||||
case OBJ_SCORE:
|
||||
typ = OBJ_BOARD;
|
||||
break;
|
||||
case OBJ_BOARD:
|
||||
typ = OBJ_TRAY;
|
||||
break;
|
||||
case OBJ_TRAY:
|
||||
case OBJ_NONE:
|
||||
typ = OBJ_SCORE;
|
||||
break;
|
||||
}
|
||||
|
||||
board->focussed = typ;
|
||||
return XP_TRUE;
|
||||
} /* focusNext */
|
||||
#endif
|
||||
|
||||
#ifdef POINTER_SUPPORT
|
||||
static XP_Bool
|
||||
pointOnSomething( BoardCtxt* board, XP_U16 x, XP_U16 y, BoardObjectType* wp )
|
||||
|
@ -2738,6 +2717,10 @@ board_handleKey( BoardCtxt* board, XP_Key key )
|
|||
} else if ( board->focussed == OBJ_TRAY ) {
|
||||
result = tray_moveCursor( board, key );
|
||||
}
|
||||
} else {
|
||||
invalFocusOwner( board );
|
||||
shiftFocusUp( board, key );
|
||||
result = XP_TRUE;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
@ -2751,12 +2734,7 @@ board_handleKey( BoardCtxt* board, XP_Key key )
|
|||
|
||||
#ifdef KEYBOARD_NAV
|
||||
case XP_FOCUSCHANGE_KEY:
|
||||
invalFocusOwner( board );
|
||||
if ( board->focusHasDived ) {
|
||||
board->focusHasDived = XP_FALSE; /* come back up */
|
||||
} else if ( focusNext( board ) ) {
|
||||
invalFocusOwner( board );
|
||||
}
|
||||
shiftFocusUp( board, XP_CURSOR_KEY_RIGHT );
|
||||
result = XP_TRUE;
|
||||
break;
|
||||
|
||||
|
@ -2868,7 +2846,8 @@ board_focusChanged( BoardCtxt* board, BoardObjectType typ, XP_Bool gained )
|
|||
draw = invalFocusOwner( board ) || draw;
|
||||
}
|
||||
board->focussed = typ;
|
||||
XP_LOGF( "%s: set focussed to %d", __FUNCTION__, (int)typ );
|
||||
XP_LOGF( "%s: set focussed to %s", __FUNCTION__,
|
||||
BoardObjectType_2str(typ) );
|
||||
draw = invalFocusOwner( board ) || draw;
|
||||
board->focusHasDived = XP_FALSE;
|
||||
} else {
|
||||
|
@ -2897,12 +2876,27 @@ board_toggle_arrowDir( BoardCtxt* board )
|
|||
}
|
||||
} /* board_toggle_cursorDir */
|
||||
|
||||
void
|
||||
shiftFocusUp( BoardCtxt* board, XP_Key key )
|
||||
{
|
||||
BoardObjectType next = OBJ_NONE;
|
||||
util_notifyFocusChange( board->util, board->focussed, key, &next );
|
||||
|
||||
if ( board->focussed != next ) {
|
||||
(void)board_focusChanged( board, board->focussed, XP_FALSE );
|
||||
|
||||
board->focusHasDived = XP_FALSE;
|
||||
|
||||
(void)board_focusChanged( board, next, XP_TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
static XP_Bool
|
||||
moveScoreCursor( BoardCtxt* board, XP_Key key )
|
||||
{
|
||||
XP_Bool result = XP_TRUE;
|
||||
XP_U16 nPlayers = board->gi->nPlayers;
|
||||
XP_U16 scoreCursorLoc = board->scoreCursorLoc + nPlayers;
|
||||
XP_S16 scoreCursorLoc = board->scoreCursorLoc;
|
||||
|
||||
switch ( key ) {
|
||||
case XP_CURSOR_KEY_DOWN:
|
||||
|
@ -2916,7 +2910,11 @@ moveScoreCursor( BoardCtxt* board, XP_Key key )
|
|||
default:
|
||||
result = XP_FALSE;
|
||||
}
|
||||
board->scoreCursorLoc = scoreCursorLoc % nPlayers;
|
||||
if ( scoreCursorLoc < 0 || scoreCursorLoc >= nPlayers ) {
|
||||
shiftFocusUp( board, key );
|
||||
} else {
|
||||
board->scoreCursorLoc = scoreCursorLoc;
|
||||
}
|
||||
board->scoreBoardInvalid = XP_TRUE;
|
||||
|
||||
return result;
|
||||
|
@ -2931,17 +2929,16 @@ advanceArrow( BoardCtxt* board )
|
|||
|
||||
XP_ASSERT( board->trayVisState == TRAY_REVEALED );
|
||||
|
||||
return board_moveArrow( board, key, XP_FALSE );
|
||||
return board_moveArrow( board, key );
|
||||
} /* advanceArrow */
|
||||
|
||||
static XP_Bool
|
||||
figureNextLoc( BoardCtxt* board, XP_Key cursorKey, XP_Bool canCycle,
|
||||
figureNextLoc( BoardCtxt* board, XP_Key cursorKey, XP_Bool canShiftFocus,
|
||||
XP_Bool avoidOccupied, XP_U16* colP, XP_U16* rowP )
|
||||
{
|
||||
XP_S16 max;
|
||||
XP_S16* useWhat;
|
||||
XP_S16 end = 0;
|
||||
XP_U16 counter = 0;
|
||||
XP_S16 incr = 0;
|
||||
XP_U16 numCols, numRows;
|
||||
XP_Bool result = XP_FALSE;
|
||||
|
@ -2958,25 +2955,25 @@ figureNextLoc( BoardCtxt* board, XP_Key cursorKey, XP_Bool canCycle,
|
|||
case XP_CURSOR_KEY_DOWN:
|
||||
incr = 1;
|
||||
useWhat = (XP_S16*)rowP;
|
||||
max = numRows;
|
||||
max = numRows - 1;
|
||||
end = max;
|
||||
break;
|
||||
case XP_CURSOR_KEY_UP:
|
||||
incr = -1;
|
||||
useWhat = (XP_S16*)rowP;
|
||||
max = numRows;
|
||||
end = -1;
|
||||
max = numRows - 1;
|
||||
end = 0;
|
||||
break;
|
||||
case XP_CURSOR_KEY_LEFT:
|
||||
incr = -1;
|
||||
useWhat = (XP_S16*)colP;
|
||||
max = numCols;
|
||||
end = -1;
|
||||
max = numCols - 1;
|
||||
end = 0;
|
||||
break;
|
||||
case XP_CURSOR_KEY_RIGHT:
|
||||
incr = 1;
|
||||
useWhat = (XP_S16*)colP;
|
||||
max = numCols;
|
||||
max = numCols - 1;
|
||||
end = max;
|
||||
break;
|
||||
default:
|
||||
|
@ -2985,19 +2982,18 @@ figureNextLoc( BoardCtxt* board, XP_Key cursorKey, XP_Bool canCycle,
|
|||
|
||||
XP_ASSERT( incr != 0 );
|
||||
|
||||
for ( counter = max; ; --counter ) {
|
||||
|
||||
*useWhat += incr;
|
||||
|
||||
if ( (counter == 0) || (!canCycle && (*useWhat == end)) ) {
|
||||
for ( ; ; ) {
|
||||
if ( *useWhat == end ) {
|
||||
if ( canShiftFocus ) {
|
||||
shiftFocusUp( board, cursorKey );
|
||||
result = XP_TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*useWhat = (*useWhat + max) % max;
|
||||
|
||||
result = XP_TRUE;
|
||||
*useWhat += incr;
|
||||
if ( !avoidOccupied
|
||||
|| !cellOccupied( board, *colP, *rowP, XP_TRUE ) ) {
|
||||
result = XP_TRUE;
|
||||
|| !cellOccupied( board, *colP, *rowP, XP_TRUE ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3007,14 +3003,14 @@ figureNextLoc( BoardCtxt* board, XP_Key cursorKey, XP_Bool canCycle,
|
|||
} /* figureNextLoc */
|
||||
|
||||
static XP_Bool
|
||||
board_moveArrow( BoardCtxt* board, XP_Key cursorKey, XP_Bool canCycle )
|
||||
board_moveArrow( BoardCtxt* board, XP_Key cursorKey )
|
||||
{
|
||||
XP_U16 col, row;
|
||||
XP_Bool changed;
|
||||
|
||||
setArrowVisible( board, XP_TRUE );
|
||||
(void)getArrow( board, &col, &row );
|
||||
changed = figureNextLoc( board, cursorKey, canCycle, XP_TRUE, &col, &row );
|
||||
changed = figureNextLoc( board, cursorKey, XP_FALSE, XP_TRUE, &col, &row );
|
||||
if ( changed ) {
|
||||
(void)setArrow( board, col, row );
|
||||
}
|
||||
|
|
|
@ -199,6 +199,7 @@ XP_Bool rectsIntersect( XP_Rect* rect1, XP_Rect* rect2 );
|
|||
XP_Bool tray_moveCursor( BoardCtxt* board, XP_Key cursorKey );
|
||||
XP_Bool tray_keyAction( BoardCtxt* board );
|
||||
DrawFocusState dfsFor( BoardCtxt* board, BoardObjectType obj );
|
||||
void shiftFocusUp( BoardCtxt* board, XP_Key key );
|
||||
#else
|
||||
# define dfsFor( board, obj ) DFS_NONE
|
||||
#endif
|
||||
|
|
|
@ -617,33 +617,26 @@ tray_moveCursor( BoardCtxt* board, XP_Key cursorKey )
|
|||
{
|
||||
XP_Bool result;
|
||||
XP_U16 selPlayer = board->selPlayer;
|
||||
XP_U16 numTrayTiles = model_getNumTilesInTray( board->model,
|
||||
selPlayer );
|
||||
XP_U16 pos;
|
||||
TileBit newSel;
|
||||
TileBit oldSel = 1 << board->trayCursorLoc[selPlayer];
|
||||
|
||||
numTrayTiles = MAX_TRAY_TILES;
|
||||
|
||||
if ( cursorKey == XP_CURSOR_KEY_UP ) {
|
||||
result = board_moveDivider( board, XP_FALSE );
|
||||
} else if ( cursorKey == XP_CURSOR_KEY_DOWN ) {
|
||||
result = board_moveDivider( board, XP_TRUE );
|
||||
} else {
|
||||
pos = indexForBits( oldSel );
|
||||
XP_S16 pos;
|
||||
|
||||
pos += numTrayTiles; /* add what we'll mod by below: makes circular */
|
||||
if ( cursorKey == XP_CURSOR_KEY_LEFT ) {
|
||||
--pos;
|
||||
} else if ( cursorKey == XP_CURSOR_KEY_RIGHT ) {
|
||||
++pos;
|
||||
board_invalTrayTiles( board, 1 << board->trayCursorLoc[selPlayer] );
|
||||
|
||||
pos = board->trayCursorLoc[selPlayer];
|
||||
pos += cursorKey == XP_CURSOR_KEY_RIGHT ? 1 : -1;
|
||||
if ( pos < 0 || pos >= MAX_TRAY_TILES ) {
|
||||
shiftFocusUp( board, cursorKey );
|
||||
} else {
|
||||
board->trayCursorLoc[selPlayer] = pos;
|
||||
board_invalTrayTiles( board, 1 << pos );
|
||||
}
|
||||
|
||||
pos %= numTrayTiles;
|
||||
board->trayCursorLoc[selPlayer] = pos;
|
||||
newSel = 1 << pos;
|
||||
|
||||
board_invalTrayTiles( board, newSel | oldSel );
|
||||
board_invalTrayTiles( board, 1 << board->trayCursorLoc[selPlayer] );
|
||||
result = XP_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -155,6 +155,11 @@ typedef struct UtilVtable {
|
|||
void (*m_util_engineStarting)( XW_UtilCtxt* uc, XP_U16 nBlanks );
|
||||
void (*m_util_engineStopping)( XW_UtilCtxt* uc );
|
||||
#endif
|
||||
|
||||
#ifdef KEYBOARD_NAV
|
||||
void (*m_util_notifyFocusChange)( XW_UtilCtxt* uc, BoardObjectType cur,
|
||||
XP_Key key, BoardObjectType* next );
|
||||
#endif
|
||||
} UtilVtable;
|
||||
|
||||
|
||||
|
@ -241,4 +246,8 @@ struct XW_UtilCtxt {
|
|||
# define util_engineStopping( uc )
|
||||
# endif
|
||||
|
||||
# ifdef KEYBOARD_NAV
|
||||
# define util_notifyFocusChange( uc, c, k, n ) \
|
||||
(uc)->vtable->m_util_notifyFocusChange((uc),(c),(k),(n))
|
||||
# endif
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
|
||||
/* -*-mode: C; fill-column: 78; c-basic-offset: 4; compile-command: "make MEMDEBUG=TRUE"; -*- */
|
||||
/*
|
||||
* Copyright 2000 by Eric House (xwords@eehouse.org). All rights reserved.
|
||||
*
|
||||
|
@ -53,13 +53,20 @@
|
|||
#include "server.h"
|
||||
#include "memstream.h"
|
||||
#include "util.h"
|
||||
#include "dbgutil.h"
|
||||
|
||||
#define MENU_WINDOW_HEIGHT 5 /* three lines plus borders */
|
||||
#define INFINITE_TIMEOUT -1
|
||||
|
||||
CursesAppGlobals globals; /* must be global b/c of SIGWINCH_handler */
|
||||
|
||||
static void changeFocus( CursesAppGlobals* globals );
|
||||
static void changeMenuForFocus( CursesAppGlobals* globals,
|
||||
BoardObjectType obj );
|
||||
static XP_Bool handleLeft( CursesAppGlobals* globals );
|
||||
static XP_Bool handleRight( CursesAppGlobals* globals );
|
||||
static XP_Bool handleUp( CursesAppGlobals* globals );
|
||||
static XP_Bool handleDown( CursesAppGlobals* globals );
|
||||
|
||||
|
||||
#ifdef MEM_DEBUG
|
||||
# define MEMPOOL params->util->mpool,
|
||||
|
@ -220,6 +227,30 @@ curses_util_engineProgressCallback( XW_UtilCtxt* XP_UNUSED(uc) )
|
|||
return XP_TRUE;
|
||||
} /* curses_util_engineProgressCallback */
|
||||
|
||||
static void
|
||||
curses_util_notifyFocusChange( XW_UtilCtxt* uc, BoardObjectType cur,
|
||||
XP_Key key, BoardObjectType* nextP )
|
||||
{
|
||||
BoardObjectType nxt;
|
||||
CursesAppGlobals* globals;
|
||||
|
||||
XP_LOGF( "%s(%s)", __FUNCTION__, BoardObjectType_2str(cur) );
|
||||
XP_Bool forward = key == XP_CURSOR_KEY_DOWN
|
||||
|| key == XP_CURSOR_KEY_RIGHT;
|
||||
switch( cur ) {
|
||||
case OBJ_SCORE: nxt = forward? OBJ_TRAY : OBJ_BOARD; break;
|
||||
case OBJ_BOARD: nxt = forward? OBJ_SCORE : OBJ_TRAY; break;
|
||||
case OBJ_TRAY: nxt = forward? OBJ_BOARD : OBJ_SCORE; break;
|
||||
case OBJ_NONE: nxt = OBJ_BOARD;
|
||||
}
|
||||
|
||||
globals = (CursesAppGlobals*)uc->closure;
|
||||
changeMenuForFocus( globals, nxt );
|
||||
|
||||
*nextP = nxt;
|
||||
XP_LOGF( "%s()=>%s", __FUNCTION__, BoardObjectType_2str(*nextP) );
|
||||
}
|
||||
|
||||
#ifdef XWFEATURE_RELAY
|
||||
static void
|
||||
curses_util_setTimer( XW_UtilCtxt* uc, XWTimerReason why, XP_U16 when,
|
||||
|
@ -322,7 +353,6 @@ handleTab( CursesAppGlobals* globals )
|
|||
{
|
||||
globals->doDraw = board_handleKey( globals->cGlobals.game.board,
|
||||
XP_FOCUSCHANGE_KEY );
|
||||
changeFocus( globals );
|
||||
return XP_TRUE;
|
||||
} /* handleTab */
|
||||
|
||||
|
@ -416,6 +446,14 @@ MenuList sharedMenuList[] = {
|
|||
{ handleTab, "Change focus", "<tab>", '\t' },
|
||||
{ handleRet, "Click/tap", "<ret>", '\r' },
|
||||
{ handleHint, "Hint", "?", '?' },
|
||||
|
||||
#ifdef KEYBOARD_NAV
|
||||
{ handleLeft, "Left", "H", 'H' },
|
||||
{ handleRight, "Right", "L", 'L' },
|
||||
{ handleUp, "Up", "J", 'J' },
|
||||
{ handleDown, "Down", "K", 'K' },
|
||||
#endif
|
||||
|
||||
{ handleCommit, "Commit move", "C", 'C' },
|
||||
{ handleFlip, "Flip", "F", 'F' },
|
||||
{ handleToggleValues, "Show values", "V", 'V' },
|
||||
|
@ -436,22 +474,6 @@ handleLeft( CursesAppGlobals* globals )
|
|||
return XP_TRUE;
|
||||
} /* handleLeft */
|
||||
|
||||
static XP_Bool
|
||||
handleDivLeft( CursesAppGlobals* globals )
|
||||
{
|
||||
globals->doDraw = board_moveDivider( globals->cGlobals.game.board,
|
||||
XP_FALSE );
|
||||
return XP_TRUE;
|
||||
} /* handleDivLeft */
|
||||
|
||||
static XP_Bool
|
||||
handleDivRight( CursesAppGlobals* globals )
|
||||
{
|
||||
globals->doDraw = board_moveDivider( globals->cGlobals.game.board,
|
||||
XP_TRUE );
|
||||
return XP_TRUE;
|
||||
} /* handleDivRight */
|
||||
|
||||
static XP_Bool
|
||||
handleRight( CursesAppGlobals* globals )
|
||||
{
|
||||
|
@ -478,31 +500,17 @@ handleDown( CursesAppGlobals* globals )
|
|||
#endif
|
||||
|
||||
MenuList boardMenuList[] = {
|
||||
#ifdef KEYBOARD_NAV
|
||||
{ handleLeft, "Left", "H", 'H' },
|
||||
{ handleRight, "Right", "L", 'L' },
|
||||
{ handleUp, "Up", "J", 'J' },
|
||||
{ handleDown, "Down", "K", 'K' },
|
||||
#endif
|
||||
{ NULL, NULL, NULL, '\0'}
|
||||
};
|
||||
|
||||
MenuList scoreMenuList[] = {
|
||||
#ifdef KEYBOARD_NAV
|
||||
{ handleUp, "Up", "J", 'J' },
|
||||
{ handleDown, "Down", "K", 'K' },
|
||||
#endif
|
||||
{ NULL, NULL, NULL, '\0'}
|
||||
};
|
||||
|
||||
MenuList trayMenuList[] = {
|
||||
#ifdef KEYBOARD_NAV
|
||||
{ handleLeft, "Left", "H", 'H' },
|
||||
{ handleRight, "Right", "L", 'L' },
|
||||
{ handleDivLeft, "Div left", "{", '{' },
|
||||
{ handleDivRight, "Div right", "}", '}' },
|
||||
#endif
|
||||
{ handleJuggle, "Juggle", "J", 'J' },
|
||||
{ handleJuggle, "Juggle", "G", 'G' },
|
||||
{ handleHide, "[un]hIde", "I", 'I' },
|
||||
|
||||
{ NULL, NULL, NULL, '\0'}
|
||||
|
@ -556,6 +564,9 @@ drawMenuFromList( CursesAppGlobals* globals, MenuList* menuList )
|
|||
if ( !isShared ) {
|
||||
done = XP_TRUE;
|
||||
break;
|
||||
} else if ( menuList->handler == NULL ) {
|
||||
done = XP_TRUE;
|
||||
break;
|
||||
} else {
|
||||
isShared = XP_FALSE;
|
||||
entry = menuList;
|
||||
|
@ -563,6 +574,7 @@ drawMenuFromList( CursesAppGlobals* globals, MenuList* menuList )
|
|||
}
|
||||
}
|
||||
|
||||
XP_ASSERT( nLines > 0 );
|
||||
if ( line % nLines == 0 ) {
|
||||
line = 0;
|
||||
col += maxKey + maxCmd + 2;
|
||||
|
@ -802,11 +814,9 @@ blocking_gotEvent( CursesAppGlobals* globals, int* ch )
|
|||
} /* blocking_gotEvent */
|
||||
|
||||
static void
|
||||
changeFocus( CursesAppGlobals* globals )
|
||||
changeMenuForFocus( CursesAppGlobals* globals, BoardObjectType focussed )
|
||||
{
|
||||
#ifdef KEYBOARD_NAV
|
||||
BoardObjectType focussed =
|
||||
board_getFocusOwner( globals->cGlobals.game.board );
|
||||
if ( focussed == OBJ_TRAY ) {
|
||||
globals->menuList = trayMenuList;
|
||||
drawMenuFromList( globals, trayMenuList );
|
||||
|
@ -820,7 +830,7 @@ changeFocus( CursesAppGlobals* globals )
|
|||
XP_ASSERT(0);
|
||||
}
|
||||
#endif
|
||||
} /* changeFocus */
|
||||
} /* changeMenuForFocus */
|
||||
|
||||
#if 0
|
||||
static void
|
||||
|
@ -916,7 +926,12 @@ setupCursesUtilCallbacks( CursesAppGlobals* globals, XW_UtilCtxt* util )
|
|||
util->vtable->m_util_notifyGameOver = curses_util_notifyGameOver;
|
||||
util->vtable->m_util_hiliteCell = curses_util_hiliteCell;
|
||||
util->vtable->m_util_engineProgressCallback =
|
||||
curses_util_engineProgressCallback;
|
||||
curses_util_engineProgressCallback;
|
||||
|
||||
#ifdef KEYBOARD_NAV
|
||||
util->vtable->m_util_notifyFocusChange = curses_util_notifyFocusChange;
|
||||
#endif
|
||||
|
||||
#ifdef XWFEATURE_RELAY
|
||||
util->vtable->m_util_setTimer = curses_util_setTimer;
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue