Merge branch 'android_branch' into android_thumbnail

Conflicts:
	xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/XwJNI.java
This commit is contained in:
Eric House 2013-11-04 06:20:53 -08:00
commit 9c9a04025a
23 changed files with 664 additions and 237 deletions

View file

@ -4,17 +4,17 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
COMMON_PATH=../../../common
local_C_INCLUDES+= \
LOCAL_C_INCLUDES+= \
-I$(LOCAL_PATH)/$(COMMON_PATH) \
-I$(LOCAL_PATH)/../../../relay \
local_LDLIBS += -llog
LOCAL_LDLIBS += -llog
ifeq ($(BUILD_TARGET),debug)
local_DEBUG = -DMEM_DEBUG -DDEBUG -DENABLE_LOGGING -DCOMMS_CHECKSUM -Wno-unused-but-set-variable
LOCAL_DEBUG = -DMEM_DEBUG -DDEBUG -DENABLE_LOGGING -DCOMMS_CHECKSUM -Wno-unused-but-set-variable
endif
local_DEFINES += \
$(local_DEBUG) \
LOCAL_DEFINES += \
$(LOCAL_DEBUG) \
-DXWFEATURE_RELAY \
-DXWFEATURE_SMS \
-DXWFEATURE_COMMSACK \
@ -37,12 +37,14 @@ local_DEFINES += \
-DHASH_STREAM \
-DXWFEATURE_BASE64 \
-DXWFEATURE_DEVID \
-DCOMMON_LAYOUT \
-DINITIAL_CLIENT_VERS=${INITIAL_CLIENT_VERS} \
-DRELAY_ROOM_DEFAULT=\"\" \
-D__LITTLE_ENDIAN \
ifeq ($(CHAT_ENABLED),true)
local_DEFINES += -DXWFEATURE_CHAT
LOCAL_DEFINES += -DXWFEATURE_CHAT
endif
ifeq ($(THUMBNAIL_ENABLED),true)
local_DEFINES += -DXWFEATURE_ACTIVERECT
@ -50,7 +52,7 @@ endif
# -DXWFEATURE_SCOREONEPASS \
local_SRC_FILES += \
LOCAL_SRC_FILES += \
xwjni.c \
utilwrapper.c \
drawwrapper.c \
@ -61,7 +63,7 @@ local_SRC_FILES += \
COMMON_PATH=../../../common
common_SRC_FILES += \
COMMON_SRC_FILES += \
$(COMMON_PATH)/boarddrw.c \
$(COMMON_PATH)/scorebdp.c \
$(COMMON_PATH)/dragdrpp.c \
@ -84,9 +86,12 @@ common_SRC_FILES += \
$(COMMON_PATH)/dbgutil.c \
LOCAL_CFLAGS+=$(local_C_INCLUDES) $(local_DEFINES) -Wall
LOCAL_SRC_FILES := $(linux_SRC_FILES) $(local_SRC_FILES) $(common_SRC_FILES)
LOCAL_CFLAGS+=$(LOCAL_C_INCLUDES) $(LOCAL_DEFINES)
LOCAL_SRC_FILES := $(linux_SRC_FILES) $(LOCAL_SRC_FILES) $(COMMON_SRC_FILES)
LOCAL_MODULE := xwjni
LOCAL_LDLIBS := -L${SYSROOT}/usr/lib -llog -lz
include $(BUILD_SHARED_LIBRARY)
COMMON_SRC_FILES :=
COMMON_PATH :=

View file

@ -0,0 +1 @@
APP_ABI := armeabi x86

View file

@ -88,6 +88,30 @@ getInt( JNIEnv* env, jobject obj, const char* name )
return result;
}
void
getInts( JNIEnv* env, void* cobj, jobject jobj, const SetInfo* sis, XP_U16 nSis )
{
int ii;
for ( ii = 0; ii < nSis; ++ii ) {
const SetInfo* si = &sis[ii];
uint8_t* ptr = ((uint8_t*)cobj) + si->offset;
int val = getInt( env, jobj, si->name );
switch( si->siz ) {
case 4:
*(uint32_t*)ptr = val;
break;
case 2:
*(uint16_t*)ptr = val;
break;
case 1:
*ptr = val;
break;
}
/* XP_LOGF( "%s: wrote int %s of size %d with val %d at offset %d", */
/* __func__, si->name, si->siz, val, si->offset ); */
}
}
void
setInt( JNIEnv* env, jobject obj, const char* name, int value )
{
@ -99,6 +123,34 @@ setInt( JNIEnv* env, jobject obj, const char* name, int value )
deleteLocalRef( env, cls );
}
void
setInts( JNIEnv* env, jobject jobj, void* cobj, const SetInfo* sis, XP_U16 nSis )
{
int ii;
for ( ii = 0; ii < nSis; ++ii ) {
const SetInfo* si = &sis[ii];
uint8_t* ptr = ((uint8_t*)cobj) + si->offset;
int val;
switch( si->siz ) {
case 4:
val = *(uint32_t*)ptr;
break;
case 2:
val = *(uint16_t*)ptr;
break;
case 1:
val = *ptr;
break;
default:
val = 0;
XP_ASSERT(0);
}
setInt( env, jobj, si->name, val );
/* XP_LOGF( "%s: read int %s of size %d with val %d from offset %d", */
/* __func__, si->name, si->siz, val, si->offset ); */
}
}
bool
setBool( JNIEnv* env, jobject obj, const char* name, bool value )
{
@ -114,6 +166,19 @@ setBool( JNIEnv* env, jobject obj, const char* name, bool value )
return success;
}
void
setBools( JNIEnv* env, jobject jobj, void* cobj, const SetInfo* sis, XP_U16 nSis )
{
int ii;
for ( ii = 0; ii < nSis; ++ii ) {
const SetInfo* si = &sis[ii];
XP_Bool val = *(XP_Bool*)(((uint8_t*)cobj)+si->offset);
setBool( env, jobj, si->name, val );
/* XP_LOGF( "%s: read bool %s with val %d from offset %d", __func__, */
/* si->name, val, si->offset ); */
}
}
bool
setString( JNIEnv* env, jobject obj, const char* name, const XP_UCHAR* value )
{
@ -210,6 +275,19 @@ getBool( JNIEnv* env, jobject obj, const char* name )
return result;
}
void
getBools( JNIEnv* env, void* cobj, jobject jobj, const SetInfo* sis, XP_U16 nSis )
{
int ii;
for ( ii = 0; ii < nSis; ++ii ) {
const SetInfo* si = &sis[ii];
XP_Bool val = getBool( env, jobj, si->name );
*(XP_Bool*)(((uint8_t*)cobj)+si->offset) = val;
/* XP_LOGF( "%s: wrote bool %s with val %d at offset %d", __func__, */
/* si->name, val, si->offset ); */
}
}
jintArray
makeIntArray( JNIEnv *env, int siz, const jint* vals )
{

View file

@ -33,10 +33,28 @@
void and_send_on_close( XWStreamCtxt* stream, void* closure );
XWStreamCtxt* and_empty_stream( MPFORMAL AndGlobals* globals );
typedef struct _SetInfo {
const char* name;
int offset;
int siz;
} SetInfo;
#define ARR_MEMBER(obj, fld) { .name = #fld, \
.offset = OFFSET_OF(obj, fld), \
.siz = sizeof(((obj *)0)->fld) \
}
int getInt( JNIEnv* env, jobject obj, const char* name );
void setInt( JNIEnv* env, jobject obj, const char* name, int value );
void setInts( JNIEnv* env, jobject jobj, void* cobj,
const SetInfo* sis, XP_U16 nSis );
void getInts( JNIEnv* env, void* cobj, jobject jobj,
const SetInfo* sis, XP_U16 nSis );
bool getBool( JNIEnv* env, jobject obj, const char* name );
void getBools( JNIEnv* env, void* cobj, jobject jobj,
const SetInfo* sis, XP_U16 nSis );
bool setBool( JNIEnv* env, jobject obj, const char* name, bool value );
void setBools( JNIEnv* env, jobject jobj, void* cobj,
const SetInfo* sis, XP_U16 nSis );
bool setString( JNIEnv* env, jobject obj, const char* name, const XP_UCHAR* value );
void getString( JNIEnv* env, jobject jlp, const char* name, XP_UCHAR* buf,
int bufLen );

View file

@ -39,47 +39,54 @@
#include "jniutlswrapper.h"
#include "paths.h"
static const SetInfo gi_ints[] = {
ARR_MEMBER( CurGameInfo, nPlayers )
,ARR_MEMBER( CurGameInfo, gameSeconds )
,ARR_MEMBER( CurGameInfo, boardSize )
,ARR_MEMBER( CurGameInfo, gameID )
,ARR_MEMBER( CurGameInfo, dictLang )
};
static const SetInfo gi_bools[] = {
ARR_MEMBER( CurGameInfo, hintsNotAllowed )
,ARR_MEMBER( CurGameInfo, timerEnabled )
,ARR_MEMBER( CurGameInfo, allowPickTiles )
,ARR_MEMBER( CurGameInfo, allowHintRect )
};
static CurGameInfo*
makeGI( MPFORMAL JNIEnv* env, jobject j_gi )
makeGI( MPFORMAL JNIEnv* env, jobject jgi )
{
CurGameInfo* gi = (CurGameInfo*)XP_CALLOC( mpool, sizeof(*gi) );
XP_UCHAR buf[256]; /* in case needs whole path */
gi->nPlayers = getInt( env, j_gi, "nPlayers");
gi->gameSeconds = getInt( env, j_gi, "gameSeconds");
gi->boardSize = getInt( env, j_gi, "boardSize" );
getInts( env, (void*)gi, jgi, gi_ints, VSIZE(gi_ints) );
getBools( env, (void*)gi, jgi, gi_bools, VSIZE(gi_bools) );
/* Unlike on other platforms, gi is created without a call to
game_makeNewGame, which sets gameID. So check here if it's still unset
and if necessary set it -- including back in the java world. */
gi->gameID = getInt( env, j_gi, "gameID" );
if ( 0 == gi->gameID ) {
while ( 0 == gi->gameID ) {
gi->gameID = getCurSeconds( env );
}
setInt( env, j_gi, "gameID", gi->gameID );
setInt( env, jgi, "gameID", gi->gameID );
}
gi->dictLang = getInt( env, j_gi, "dictLang" );
gi->hintsNotAllowed = getBool( env, j_gi, "hintsNotAllowed" );
gi->timerEnabled = getBool( env, j_gi, "timerEnabled" );
gi->allowPickTiles = getBool( env, j_gi, "allowPickTiles" );
gi->allowHintRect = getBool( env, j_gi, "allowHintRect" );
gi->phoniesAction =
jenumFieldToInt( env, j_gi, "phoniesAction",
jenumFieldToInt( env, jgi, "phoniesAction",
PKG_PATH("jni/CurGameInfo$XWPhoniesChoice") );
gi->serverRole =
jenumFieldToInt( env, j_gi, "serverRole",
jenumFieldToInt( env, jgi, "serverRole",
PKG_PATH("jni/CurGameInfo$DeviceRole"));
getString( env, j_gi, "dictName", buf, VSIZE(buf) );
getString( env, jgi, "dictName", buf, VSIZE(buf) );
gi->dictName = copyString( mpool, buf );
XP_ASSERT( gi->nPlayers <= MAX_NUM_PLAYERS );
jobject jplayers;
if ( getObject( env, j_gi, "players", "[L" PKG_PATH("jni/LocalPlayer") ";",
if ( getObject( env, jgi, "players", "[L" PKG_PATH("jni/LocalPlayer") ";",
&jplayers ) ) {
int ii;
for ( ii = 0; ii < gi->nPlayers; ++ii ) {
@ -114,14 +121,10 @@ static void
setJGI( JNIEnv* env, jobject jgi, const CurGameInfo* gi )
{
// set fields
setInt( env, jgi, "nPlayers", gi->nPlayers );
setInt( env, jgi, "gameSeconds", gi->gameSeconds );
setInt( env, jgi, "boardSize", gi->boardSize );
setInt( env, jgi, "gameID", gi->gameID );
setInt( env, jgi, "dictLang", gi->dictLang );
setBool( env, jgi, "hintsNotAllowed", gi->hintsNotAllowed );
setBool( env, jgi, "timerEnabled", gi->timerEnabled );
setBool( env, jgi, "allowPickTiles", gi->allowPickTiles );
setInts( env, jgi, (void*)gi, gi_ints, VSIZE(gi_ints) );
setBools( env, jgi, (void*)gi, gi_bools, VSIZE(gi_bools) );
setString( env, jgi, "dictName", gi->dictName );
intToJenumField( env, jgi, gi->phoniesAction, "phoniesAction",
@ -155,6 +158,36 @@ setJGI( JNIEnv* env, jobject jgi, const CurGameInfo* gi )
}
} /* setJGI */
#ifdef COMMON_LAYOUT
static const SetInfo bd_ints[] = {
ARR_MEMBER( BoardDims, left )
,ARR_MEMBER( BoardDims, top )
,ARR_MEMBER( BoardDims, width )
,ARR_MEMBER( BoardDims, height )
,ARR_MEMBER( BoardDims, scoreHt )
,ARR_MEMBER( BoardDims, boardHt )
,ARR_MEMBER( BoardDims, trayTop )
,ARR_MEMBER( BoardDims, trayHt )
,ARR_MEMBER( BoardDims, cellSize )
,ARR_MEMBER( BoardDims, maxCellSize )
,ARR_MEMBER( BoardDims, timerWidth )
};
static void
dimsJToC( JNIEnv* env, BoardDims* out, jobject jdims )
{
getInts( env, (void*)out, jdims, bd_ints, VSIZE(bd_ints) );
}
static void
dimsCtoJ( JNIEnv* env, jobject jdims, const BoardDims* in )
{
LOG_FUNC();
setInts( env, jdims, (void*)in, bd_ints, VSIZE(bd_ints) );
LOG_RETURN_VOID();
}
#endif
static void
destroyGI( MPFORMAL CurGameInfo** gip )
{
@ -598,6 +631,47 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1draw
return result;
}
#ifdef COMMON_LAYOUT
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1figureLayout
( JNIEnv* env, jclass C, jint gamePtr, jobject jgi, jint fontHt, jint fontWidth,
jboolean squareTiles, jobject jbounds, jobject jdims )
{
LOG_FUNC();
XWJNI_START();
CurGameInfo* gi = makeGI( MPPARM(mpool) env, jgi );
XP_Rect bounds;
bounds.left = getInt( env, jbounds, "left" );
bounds.top = getInt( env, jbounds, "top" );
bounds.width = getInt( env, jbounds, "right" ) - bounds.left;
bounds.height = getInt( env, jbounds, "bottom" ) - bounds.top;
BoardDims dims;
board_figureLayout( state->game.board, gi, 150, 200, fontHt, fontWidth,
squareTiles, &bounds, ((!!jdims) ? &dims : NULL) );
destroyGI( MPPARM(mpool) &gi );
if ( !!jdims ) {
dimsCtoJ( env, jdims, &dims );
}
XWJNI_END();
LOG_RETURN_VOID();
}
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1applyLayout
( JNIEnv* env, jclass C, jint gamePtr, jobject jdims )
{
XWJNI_START();
BoardDims dims;
dimsJToC( env, &dims, jdims );
board_applyLayout( state->game.board, &dims );
XWJNI_END();
}
#endif
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1setPos
(JNIEnv *env, jclass C, jint gamePtr, jint left, jint top, jint width,

View file

@ -104,6 +104,7 @@
<string name="key_na_browseall">key_na_browseall</string>
<string name="key_na_values">key_na_values</string>
<string name="key_enable_debug">key_enable_debug</string>
<string name="key_enable_commlayt">key_enable_commlayt</string>
<string name="key_download_path">key_download_path</string>
<!-- Nor is my email address -->

View file

@ -307,6 +307,11 @@
android:summary="Menuitems etc."
android:defaultValue="false"
/>
<CheckBoxPreference android:key="@string/key_enable_commlayt"
android:title="Use common layout"
android:summary="(rather than android-specific)"
android:defaultValue="false"
/>
<!-- For broken devices like my Blaze 4G that report a download
directory that doesn't exist, allow users to set it. Mine:

View file

@ -23,6 +23,7 @@ package org.eehouse.android.xw4;
// Why does this have to be its own class...
public class BoardDims {
public int left, top;
public int width, height; // of the bitmap
public int scoreHt;
public int boardHt;

View file

@ -73,6 +73,7 @@ public class BoardView extends View implements BoardHandler, SyncedDraw {
private int m_lastSecsLeft;
private int m_lastTimerPlayer;
private int m_pendingScore;
private boolean m_useCommon;
private CommsAddrRec.CommsConnType m_connType =
CommsAddrRec.CommsConnType.COMMS_CONN_NONE;
@ -188,6 +189,9 @@ public class BoardView extends View implements BoardHandler, SyncedDraw {
int heightMode = View.MeasureSpec.getMode( heightMeasureSpec );
// printMode( "heightMode", heightMode );
m_useCommon =
XWPrefs.getPrefsBoolean( m_context,
R.string.key_enable_commlayt, false );
BoardDims dims = figureBoardDims( width, height );
// If I let the spec tell me whether I can reduce the width
// then I don't change it on the second pass, but if I ignore
@ -247,80 +251,91 @@ public class BoardView extends View implements BoardHandler, SyncedDraw {
private BoardDims figureBoardDims( int width, int height )
{
BoardDims result = new BoardDims();
int nCells = m_gi.boardSize;
int maxCellSize = 4 * m_defaultFontHt;
int trayHt;
int scoreHt;
int wantHt;
int nToScroll;
boolean squareTiles = XWPrefs.getSquareTiles( m_context );
for ( boolean firstPass = true; ; ) {
result.width = width;
Paint paint = new Paint();
paint.setTextSize( m_mediumFontHt );
paint.getTextBounds( "-00:00", 0, 6, m_boundsScratch );
int timerWidth = m_boundsScratch.width();
int cellSize = width / nCells;
if ( cellSize > maxCellSize ) {
cellSize = maxCellSize;
if ( m_useCommon ) {
Rect bounds = new Rect( 0, 0, width, height );
int fontWidth = timerWidth / 6;
XwJNI.board_figureLayout( m_jniGamePtr, m_gi, m_defaultFontHt,
fontWidth, squareTiles, bounds, result );
} else {
int nCells = m_gi.boardSize;
int maxCellSize = 4 * m_defaultFontHt;
int trayHt;
int scoreHt;
int wantHt;
int nToScroll;
int boardWidth = nCells * cellSize;
result.width = boardWidth;
}
result.maxCellSize = maxCellSize;
for ( boolean firstPass = true; ; ) {
result.width = width;
// Now determine if vertical scrolling will be necessary.
// There's a minimum tray and scoreboard height. If we can
// fit them and all cells no scrolling's needed. Otherwise
// determine the minimum number that must be hidden to fit.
// Finally grow scoreboard and tray to use whatever's left.
trayHt = 2 * cellSize;
scoreHt = (cellSize * 3) / 2;
wantHt = trayHt + scoreHt + (cellSize * nCells);
if ( wantHt <= height ) {
nToScroll = 0;
} else {
// Scrolling's required if we use cell width sufficient to
// fill the screen. But perhaps we don't need to.
int cellWidth = 2 * (height / ( 4 + 3 + (2*nCells)));
if ( firstPass && cellWidth >= m_defaultFontHt ) {
firstPass = false;
width = nCells * cellWidth;
continue;
int cellSize = width / nCells;
if ( cellSize > maxCellSize ) {
cellSize = maxCellSize;
int boardWidth = nCells * cellSize;
result.width = boardWidth;
}
result.maxCellSize = maxCellSize;
// Now determine if vertical scrolling will be necessary.
// There's a minimum tray and scoreboard height. If we can
// fit them and all cells no scrolling's needed. Otherwise
// determine the minimum number that must be hidden to fit.
// Finally grow scoreboard and tray to use whatever's left.
trayHt = 2 * cellSize;
scoreHt = (cellSize * 3) / 2;
wantHt = trayHt + scoreHt + (cellSize * nCells);
if ( wantHt <= height ) {
nToScroll = 0;
} else {
nToScroll = nCells - ((height - trayHt - scoreHt) / cellSize);
// Scrolling's required if we use cell width sufficient to
// fill the screen. But perhaps we don't need to.
int cellWidth = 2 * (height / ( 4 + 3 + (2*nCells)));
if ( firstPass && cellWidth >= m_defaultFontHt ) {
firstPass = false;
width = nCells * cellWidth;
continue;
} else {
nToScroll = nCells - ((height - trayHt - scoreHt) / cellSize);
}
}
}
int heightUsed = trayHt + scoreHt + (nCells - nToScroll) * cellSize;
int heightLeft = height - heightUsed;
if ( 0 < heightLeft ) {
if ( heightLeft > (cellSize * 3 / 2) ) {
heightLeft = cellSize * 3 / 2;
int heightUsed = trayHt + scoreHt + (nCells - nToScroll) * cellSize;
int heightLeft = height - heightUsed;
if ( 0 < heightLeft ) {
if ( heightLeft > (cellSize * 3 / 2) ) {
heightLeft = cellSize * 3 / 2;
}
heightLeft /= 3;
scoreHt += heightLeft;
trayHt += heightLeft * 2;
if ( squareTiles && trayHt > (width / 7) ) {
trayHt = width / 7;
}
heightUsed = trayHt + scoreHt + ((nCells - nToScroll) * cellSize);
}
heightLeft /= 3;
scoreHt += heightLeft;
trayHt += heightLeft * 2;
if ( XWPrefs.getSquareTiles( m_context )
&& trayHt > (width / 7) ) {
trayHt = width / 7;
result.trayHt = trayHt;
result.scoreHt = scoreHt;
result.boardHt = cellSize * nCells;
result.trayTop = scoreHt + (cellSize * (nCells-nToScroll));
result.height = heightUsed;
result.cellSize = cellSize;
if ( m_gi.timerEnabled ) {
result.timerWidth = timerWidth;
}
heightUsed = trayHt + scoreHt + ((nCells - nToScroll) * cellSize);
break;
}
result.trayHt = trayHt;
result.scoreHt = scoreHt;
result.boardHt = cellSize * nCells;
result.trayTop = scoreHt + (cellSize * (nCells-nToScroll));
result.height = heightUsed;
result.cellSize = cellSize;
if ( m_gi.timerEnabled ) {
Paint paint = new Paint();
paint.setTextSize( m_mediumFontHt );
paint.getTextBounds( "-00:00", 0, 6, m_boundsScratch );
result.timerWidth = m_boundsScratch.width();
}
break;
}
return result;
@ -362,7 +377,8 @@ public class BoardView extends View implements BoardHandler, SyncedDraw {
XwJNI.board_setDraw( m_jniGamePtr, m_canvas );
// need to synchronize??
m_jniThread.handle( JNIThread.JNICmd.CMD_LAYOUT, dims );
m_jniThread.handle( JNIThread.JNICmd.CMD_LAYOUT, dims,
m_useCommon );
m_jniThread.handle( JNIThread.JNICmd.CMD_DRAW );
layoutDone = true;
}

View file

@ -233,32 +233,36 @@ public class JNIThread extends Thread {
Message.obtain( m_handler, DIALOG, titleArg, 0, text ).sendToTarget();
}
private void doLayout( BoardDims dims )
private void doLayout( BoardDims dims, boolean useCommon )
{
int scoreWidth = dims.width - dims.cellSize;
ConnStatusHandler.setRect( scoreWidth, 0, scoreWidth + dims.cellSize,
dims.scoreHt );
if ( useCommon ) {
XwJNI.board_applyLayout( m_jniGamePtr, dims );
} else {
int scoreWidth = dims.width - dims.cellSize;
ConnStatusHandler.setRect( scoreWidth, 0, scoreWidth + dims.cellSize,
dims.scoreHt );
if ( m_gi.timerEnabled ) {
scoreWidth -= dims.timerWidth;
XwJNI.board_setTimerLoc( m_jniGamePtr, scoreWidth, 0,
dims.timerWidth, dims.scoreHt );
}
XwJNI.board_setScoreboardLoc( m_jniGamePtr, 0, 0, scoreWidth,
dims.scoreHt, true );
if ( m_gi.timerEnabled ) {
scoreWidth -= dims.timerWidth;
XwJNI.board_setTimerLoc( m_jniGamePtr, scoreWidth, 0,
dims.timerWidth, dims.scoreHt );
}
XwJNI.board_setScoreboardLoc( m_jniGamePtr, 0, 0, scoreWidth,
dims.scoreHt, true );
// Have no idea why I was doing -1 below, but it breaks layout
// for small (QVGA) boards. If it needs to be done, do it
// early in figureBoardDims so the calculations that follow
// are consistent.
XwJNI.board_setPos( m_jniGamePtr, 0, dims.scoreHt,
dims.width/*-1*/, dims.boardHt, dims.maxCellSize,
false );
// Have no idea why I was doing -1 below, but it breaks layout
// for small (QVGA) boards. If it needs to be done, do it
// early in figureBoardDims so the calculations that follow
// are consistent.
XwJNI.board_setPos( m_jniGamePtr, 0, dims.scoreHt,
dims.width/*-1*/, dims.boardHt, dims.maxCellSize,
false );
XwJNI.board_setTrayLoc( m_jniGamePtr, 0, dims.trayTop,
dims.width/*-1*/, dims.trayHt, kMinDivWidth );
XwJNI.board_setTrayLoc( m_jniGamePtr, 0, dims.trayTop,
dims.width/*-1*/, dims.trayHt, kMinDivWidth );
XwJNI.board_invalAll( m_jniGamePtr );
XwJNI.board_invalAll( m_jniGamePtr );
}
}
private boolean nextSame( JNICmd cmd )
@ -358,7 +362,7 @@ public class JNIThread extends Thread {
break;
case CMD_LAYOUT:
doLayout( (BoardDims)args[0] );
doLayout( (BoardDims)args[0], (Boolean)args[1] );
draw = true;
// check and disable zoom button at limit
handle( JNICmd.CMD_ZOOM, 0 );

View file

@ -21,7 +21,7 @@
package org.eehouse.android.xw4.jni;
import android.graphics.Rect;
import org.eehouse.android.xw4.BoardDims;
// Collection of native methods
public class XwJNI {
@ -148,6 +148,15 @@ public class XwJNI {
public static native void board_setDraw( int gamePtr, DrawCtx draw );
public static native void board_invalAll( int gamePtr );
public static native boolean board_draw( int gamePtr );
// Only if COMMON_LAYOUT defined
public static native void board_figureLayout( int gamePtr, CurGameInfo gi,
int fontHt, int fontWidth,
boolean squareTiles,
Rect bounds, BoardDims dims );
// Only if COMMON_LAYOUT defined
public static native void board_applyLayout( int gamePtr, BoardDims dims );
public static native void board_setPos( int gamePtr, int left, int top,
int width, int height,
int maxCellHt, boolean lefty );

View file

@ -389,6 +389,123 @@ board_reset( BoardCtxt* board )
setTimerIf( board );
} /* board_reset */
#ifdef COMMON_LAYOUT
void
board_figureLayout( BoardCtxt* board, const CurGameInfo* gi,
XP_U16 scorePct, XP_U16 trayPct,
XP_U16 fontHt, XP_U16 fontWidth, XP_Bool squareTiles,
const XP_Rect* bounds, BoardDims* dimsp )
{
BoardDims ldims;
XP_MEMSET( &ldims, 0, sizeof(ldims) );
XP_U16 nCells = gi->boardSize;
XP_U16 maxCellSize = 4 * fontHt;
XP_U16 trayHt;
XP_U16 scoreHt;
XP_U16 wantHt;
XP_U16 nToScroll;
XP_Bool firstPass;
ldims.left = bounds->left;
ldims.top = bounds->top;
for ( firstPass = XP_TRUE; ; ) {
ldims.width = bounds->width;
XP_U16 cellSize = bounds->width / nCells;
if ( cellSize > maxCellSize ) {
cellSize = maxCellSize;
XP_U16 boardWidth = nCells * cellSize;
ldims.width = boardWidth;
}
ldims.maxCellSize = maxCellSize;
// Now determine if vertical scrolling will be necessary.
// There's a minimum tray and scoreboard height. If we can
// fit them and all cells no scrolling's needed. Otherwise
// determine the minimum number that must be hidden to fit.
// Finally grow scoreboard and tray to use whatever's left.
scoreHt = (scorePct * cellSize) / 100;
trayHt = (trayPct * cellSize) / 100;
wantHt = trayHt + scoreHt + (cellSize * nCells);
if ( wantHt <= bounds->height ) {
nToScroll = 0;
} else {
// Scrolling's required if we use cell width sufficient to
// fill the screen. But perhaps we don't need to.
int cellWidth = 2 * (bounds->height / ( 4 + 3 + (2*nCells)));
if ( firstPass && cellWidth >= fontHt ) {
firstPass = XP_FALSE;
ldims.width = nCells * cellWidth;
continue;
} else {
nToScroll = nCells -
((bounds->height - trayHt - scoreHt) / cellSize);
}
}
XP_U16 heightUsed = trayHt + scoreHt + (nCells - nToScroll) * cellSize;
XP_U16 heightLeft = bounds->height - heightUsed;
if ( 0 < heightLeft ) {
if ( heightLeft > (cellSize * 3 / 2) ) {
heightLeft = cellSize * 3 / 2;
}
heightLeft /= 3;
if ( 0 < scorePct ) {
scoreHt += heightLeft;
}
if ( 0 < trayPct ) {
trayHt += heightLeft * 2;
}
if ( squareTiles && trayHt > (bounds->width / 7) ) {
trayHt = bounds->width / 7;
}
heightUsed = trayHt + scoreHt + ((nCells - nToScroll) * cellSize);
}
ldims.trayHt = trayHt;
ldims.scoreHt = scoreHt;
ldims.boardHt = cellSize * nCells;
ldims.trayTop = scoreHt + (cellSize * (nCells-nToScroll));
ldims.height = heightUsed;
ldims.cellSize = cellSize;
if ( gi->timerEnabled ) {
ldims.timerWidth = fontWidth * XP_STRLEN("-00:00");
}
break;
}
if ( !!dimsp ) {
XP_MEMCPY( dimsp, &ldims, sizeof(ldims) );
} else {
board_applyLayout( board, &ldims );
}
}
void
board_applyLayout( BoardCtxt* board, const BoardDims* dims )
{
board_setPos( board, dims->left, dims->top + dims->scoreHt,
dims->width, dims->top + dims->scoreHt + dims->boardHt,
dims->maxCellSize, XP_FALSE );
board_setScoreboardLoc( board, dims->left, dims->top,
dims->width - dims->timerWidth,
dims->scoreHt, XP_TRUE );
board_setTimerLoc( board, dims->left + dims->width - dims->timerWidth,
dims->top, dims->timerWidth, dims->scoreHt );
board_setTrayLoc( board, dims->left, dims->trayTop,
dims->width, dims->trayHt, dims->width / 20 );
}
#endif
void
board_setPos( BoardCtxt* board, XP_U16 left, XP_U16 top,
XP_U16 width, XP_U16 height, XP_U16 maxCellSz,

View file

@ -22,6 +22,7 @@
#include "comtypes.h"
#include "model.h"
#include "gameinfo.h"
#include "server.h"
#include "draw.h"
#include "xwstream.h"
@ -57,7 +58,6 @@ typedef enum {
/* typedef struct BoardCtxt BoardCtxt; */
BoardCtxt* board_make( MPFORMAL ModelCtxt* model, ServerCtxt* server,
DrawCtx* draw, XW_UtilCtxt* util );
BoardCtxt* board_makeFromStream( MPFORMAL XWStreamCtxt* stream,
@ -70,10 +70,45 @@ void board_destroy( BoardCtxt* board );
void board_writeToStream( const BoardCtxt* board, XWStreamCtxt* stream );
void board_reset( BoardCtxt* board );
/* Layout. Either done internally or by client */
#ifdef COMMON_LAYOUT
typedef struct _BoardDims {
XP_U16 left, top;
XP_U16 width, height;
XP_U16 scoreHt;
XP_U16 boardHt;
XP_U16 trayTop, trayHt;
XP_U16 cellSize, maxCellSize;
XP_U16 timerWidth;
} BoardDims;
void board_figureLayout( BoardCtxt* board, const CurGameInfo* gi,
XP_U16 scorePct, XP_U16 trayPct,
XP_U16 fontHt, XP_U16 fontWidth,
XP_Bool squareTiles, const XP_Rect* bounds,
/* out */ BoardDims* dims );
void board_applyLayout( BoardCtxt* board, const BoardDims* dims );
#endif
/* These four aren't needed if COMMON_LAYOUT defined */
void board_setPos( BoardCtxt* board, XP_U16 left, XP_U16 top,
XP_U16 width, XP_U16 height, XP_U16 maxCellSize,
XP_Bool leftHanded );
void board_reset( BoardCtxt* board );
void board_setScoreboardLoc( BoardCtxt* board,
XP_U16 scoreLeft, XP_U16 scoreTop,
XP_U16 scoreWidth, XP_U16 scoreHeight,
XP_Bool divideHorizontally );
void board_setTimerLoc( BoardCtxt* board,
XP_U16 timerLeft, XP_U16 timerTop,
XP_U16 timerWidth, XP_U16 timerHeight );
void board_setTrayLoc( BoardCtxt* board, XP_U16 trayLeft, XP_U16 trayTop,
XP_U16 trayWidth, XP_U16 trayHeight,
XP_U16 minDividerWidth );
/* Vertical scroll support; offset is in rows, not pixels */
XP_Bool board_setYOffset( BoardCtxt* board, XP_U16 newOffset );
@ -88,13 +123,6 @@ XP_Bool board_canHint( const BoardCtxt* board );
/* zoomBy: >0: zoom in; < 0: zoom out; 0: query only */
XP_Bool board_zoom( BoardCtxt* board, XP_S16 zoomBy, XP_Bool* canInOut );
void board_setScoreboardLoc( BoardCtxt* board,
XP_U16 scoreLeft, XP_U16 scoreTop,
XP_U16 scoreWidth, XP_U16 scoreHeight,
XP_Bool divideHorizontally );
void board_setTimerLoc( BoardCtxt* board,
XP_U16 timerLeft, XP_U16 timerTop,
XP_U16 timerWidth, XP_U16 timerHeight );
void board_invalAll( BoardCtxt* board );
void board_invalRect( BoardCtxt* board, XP_Rect* rect );
#ifdef XWFEATURE_ACTIVERECT
@ -124,7 +152,6 @@ BoardObjectType board_getFocusOwner( BoardCtxt* board );
void board_hiliteCellAt( BoardCtxt* board, XP_U16 col, XP_U16 row );
void board_resetEngine( BoardCtxt* board );
XP_Bool board_commitTurn( BoardCtxt* board );
@ -156,9 +183,6 @@ XP_Bool board_focusChanged( BoardCtxt* board, BoardObjectType typ,
/******************** Tray methods ********************/
#define NO_TILES ((TileBit)0)
void board_setTrayLoc( BoardCtxt* board, XP_U16 trayLeft, XP_U16 trayTop,
XP_U16 trayWidth, XP_U16 trayHeight,
XP_U16 minDividerWidth );
XP_Bool board_hideTray( BoardCtxt* board );
XP_Bool board_showTray( BoardCtxt* board );
XW_TrayVisState board_getTrayVisState( const BoardCtxt* board );

View file

@ -240,7 +240,7 @@ typedef struct _PlayerDicts {
# define DEBUG_ASSIGN(a,b)
#endif
#define OFFSET_OF(typ,var) ((XP_U16)&(((typ*) 0)->var))
#define OFFSET_OF(typ,var) ((XP_U32)&(((typ*) 0)->var))
#ifndef RELAY_NAME_DEFAULT
# define RELAY_NAME_DEFAULT "eehouse.org"

View file

@ -21,6 +21,7 @@
#ifndef _GAME_H_
#define _GAME_H_
#include "gameinfo.h"
#include "model.h"
#include "board.h"
#include "comms.h"
@ -31,40 +32,6 @@
extern "C" {
#endif
typedef struct LocalPlayer {
XP_UCHAR* name;
XP_UCHAR* password;
XP_UCHAR* dictName;
XP_U16 secondsUsed;
XP_Bool isLocal;
XP_U8 robotIQ; /* 0 means not a robot; 1-100 means how
dumb is it with 1 meaning very smart */
} LocalPlayer;
#define LP_IS_ROBOT(lp) ((lp)->robotIQ != 0)
#define LP_IS_LOCAL(lp) ((lp)->isLocal)
#define DUMB_ROBOT 0
#define SMART_ROBOT 1
typedef struct CurGameInfo {
XP_UCHAR* dictName;
LocalPlayer players[MAX_NUM_PLAYERS];
XP_U32 gameID; /* uniquely identifies game */
XP_U16 gameSeconds; /* for timer */
XP_LangCode dictLang;
XP_U8 nPlayers;
XP_U8 boardSize;
DeviceRole serverRole;
XP_Bool hintsNotAllowed;
XP_Bool timerEnabled;
XP_Bool allowPickTiles;
XP_Bool allowHintRect;
XWPhoniesChoice phoniesAction;
XP_Bool confirmBTConnect; /* only used for BT */
} CurGameInfo;
typedef struct _GameStateInfo {
XP_U16 visTileCount;
XW_TrayVisState trayVisState;

68
xwords4/common/gameinfo.h Normal file
View file

@ -0,0 +1,68 @@
/* -*- compile-command: "cd ../linux && make -j3 MEMDEBUG=TRUE"; -*- */
/*
* Copyright 2001-2013 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _GAMEINFO_H_
#define _GAMEINFO_H_
#include "server.h"
#ifdef CPLUS
extern "C" {
#endif
typedef struct LocalPlayer {
XP_UCHAR* name;
XP_UCHAR* password;
XP_UCHAR* dictName;
XP_U16 secondsUsed;
XP_Bool isLocal;
XP_U8 robotIQ; /* 0 means not a robot; 1-100 means how
dumb is it with 1 meaning very smart */
} LocalPlayer;
#define LP_IS_ROBOT(lp) ((lp)->robotIQ != 0)
#define LP_IS_LOCAL(lp) ((lp)->isLocal)
#define DUMB_ROBOT 0
#define SMART_ROBOT 1
typedef struct CurGameInfo {
XP_UCHAR* dictName;
LocalPlayer players[MAX_NUM_PLAYERS];
XP_U32 gameID; /* uniquely identifies game */
XP_U16 gameSeconds; /* for timer */
XP_LangCode dictLang;
XP_U8 nPlayers;
XP_U8 boardSize;
DeviceRole serverRole;
XP_Bool hintsNotAllowed;
XP_Bool timerEnabled;
XP_Bool allowPickTiles;
XP_Bool allowHintRect;
XWPhoniesChoice phoniesAction;
XP_Bool confirmBTConnect; /* only used for BT */
} CurGameInfo;
#ifdef CPLUS
}
#endif
#endif

View file

@ -280,51 +280,55 @@ drawScoreBoard( BoardCtxt* board )
totalDim += isVertical ? dp->height : dp->width;
}
gotPct = (*adjustDim * 100) / totalDim;
for ( dp = datum, ii = 0; ii < nPlayers; ++ii, ++dp ) {
if ( isVertical ) {
dp->height = (dp->height * gotPct) / 100;
} else {
dp->width = (dp->width * gotPct) / 100;
if ( 0 < totalDim ) {
gotPct = (*adjustDim * 100) / totalDim;
for ( dp = datum, ii = 0; ii < nPlayers; ++ii, ++dp ) {
if ( isVertical ) {
dp->height = (dp->height * gotPct) / 100;
} else {
dp->width = (dp->width * gotPct) / 100;
}
}
}
scoreRect = board->scoreBdBounds; /* reset */
scoreRect = board->scoreBdBounds; /* reset */
/* at this point, the scoreRect should be anchored at the
scoreboard rect's upper left. */
/* at this point, the scoreRect should be anchored at the
scoreboard rect's upper left. */
if ( remDim > 0 ) {
XP_Rect innerRect;
*adjustDim = remDim;
centerIn( &innerRect, &scoreRect, remWidth, remHeight );
draw_drawRemText( board->draw, &innerRect, &scoreRect,
nTilesInPool, focusAll || remFocussed );
*adjustPt += remDim;
if ( remDim > 0 ) {
XP_Rect innerRect;
*adjustDim = remDim;
centerIn( &innerRect, &scoreRect, remWidth, remHeight );
draw_drawRemText( board->draw, &innerRect, &scoreRect,
nTilesInPool,
focusAll || remFocussed );
*adjustPt += remDim;
#ifdef KEYBOARD_NAV
board->remRect = scoreRect;
/* Hack: don't let the cursor disappear if Rem: goes
away */
} else if ( board->scoreCursorLoc == CURSOR_LOC_REM ) {
board->scoreCursorLoc = selPlayer + 1;
board->remRect = scoreRect;
/* Hack: don't let the cursor disappear if Rem: goes
away */
} else if ( board->scoreCursorLoc == CURSOR_LOC_REM ) {
board->scoreCursorLoc = selPlayer + 1;
#endif
}
}
board->remDim = remDim;
board->remDim = remDim;
for ( dp = datum, ii = 0; ii < nPlayers; ++dp, ++ii ) {
XP_Rect innerRect;
XP_U16 dim = isVertical? dp->height:dp->width;
*adjustDim = board->pti[ii].scoreDims = dim;
for ( dp = datum, ii = 0; ii < nPlayers; ++dp, ++ii ) {
XP_Rect innerRect;
XP_U16 dim = isVertical? dp->height:dp->width;
*adjustDim = board->pti[ii].scoreDims = dim;
centerIn( &innerRect, &scoreRect, dp->width, dp->height );
draw_score_drawPlayer( board->draw, &innerRect, &scoreRect,
gotPct, &dp->dsi );
centerIn( &innerRect, &scoreRect, dp->width,
dp->height );
draw_score_drawPlayer( board->draw, &innerRect,
&scoreRect, gotPct, &dp->dsi );
#ifdef KEYBOARD_NAV
XP_MEMCPY( &board->pti[ii].scoreRects, &scoreRect,
sizeof(scoreRect) );
XP_MEMCPY( &board->pti[ii].scoreRects, &scoreRect,
sizeof(scoreRect) );
#endif
*adjustPt += *adjustDim;
*adjustPt += *adjustDim;
}
}
draw_objFinished( board->draw, OBJ_SCORE,

View file

@ -328,9 +328,11 @@ drawPendingScore( BoardCtxt* board, XP_S16 turnScore, XP_Bool hasCursor )
XP_Rect lastTileR;
figureTrayTileRect( board, MAX_TRAY_TILES-1, &lastTileR );
draw_score_pendingScore( board->draw, &lastTileR, turnScore,
selPlayer, curTurn,
hasCursor?CELL_ISCURSOR:CELL_NONE );
if ( 0 < lastTileR.width && 0 < lastTileR.height ) {
draw_score_pendingScore( board->draw, &lastTileR, turnScore,
selPlayer, curTurn,
hasCursor?CELL_ISCURSOR:CELL_NONE );
}
}
} /* drawPendingScore */
@ -509,7 +511,9 @@ dividerMoved( BoardCtxt* board, XP_U8 newLoc )
void
board_invalTrayTiles( BoardCtxt* board, TileBit what )
{
board->trayInvalBits |= what;
if ( 0 < board->trayBounds.width && 0 < board->trayBounds.height ) {
board->trayInvalBits |= what;
}
} /* invalTrayTiles */
void

View file

@ -116,6 +116,7 @@ DEFINES += -DXWFEATURE_COMMSACK
#DEFINES += -DXWFEATURE_ACTIVERECT
DEFINES += -DCOMMS_XPORT_FLAGSPROC
DEFINES += -DINITIAL_CLIENT_VERS=2
DEFINES += -DCOMMON_LAYOUT
# MAX_ROWS controls STREAM_VERS_BIGBOARD and with it move hashing
DEFINES += -DMAX_ROWS=32

View file

@ -1635,8 +1635,12 @@ passKeyToBoard( CursesAppGlobals* globals, char ch )
static void
positionSizeStuff( CursesAppGlobals* globals, int width, int height )
{
XP_U16 cellWidth, cellHt, scoreLeft, scoreWidth;
BoardCtxt* board = globals->cGlobals.game.board;
#ifdef COMMON_LAYOUT
XP_USE( width );
XP_USE( height );
#else
XP_U16 cellWidth, cellHt, scoreLeft, scoreWidth;
int remWidth = width;
int nRows = globals->cGlobals.gi->boardSize;
@ -1680,7 +1684,7 @@ positionSizeStuff( CursesAppGlobals* globals, int width, int height )
/* no divider -- yet */
/* board_setTrayVisible( globals.board, XP_TRUE, XP_FALSE ); */
#endif
board_invalAll( board );
} /* positionSizeStuff */

View file

@ -598,7 +598,36 @@ static gboolean
configure_event( GtkWidget* widget, GdkEventConfigure* XP_UNUSED(event),
GtkGameGlobals* globals )
{
short bdWidth, bdHeight;
if ( globals->draw == NULL ) {
createOrLoadObjects( globals );
}
CommonGlobals* cGlobals = &globals->cGlobals;
BoardCtxt* board = cGlobals->game.board;
short bdWidth = widget->allocation.width - (GTK_RIGHT_MARGIN
+ GTK_BOARD_LEFT_MARGIN);
short bdHeight = widget->allocation.height - (GTK_TOP_MARGIN + GTK_BOTTOM_MARGIN)
- GTK_MIN_TRAY_SCALEV - GTK_BOTTOM_MARGIN;
#ifdef COMMON_LAYOUT
XP_ASSERT( !cGlobals->params->verticalScore ); /* not supported */
XP_Rect rect = { .left = GTK_BOARD_LEFT, .top = GTK_HOR_SCORE_TOP,
.width = bdWidth, .height = bdHeight
};
BoardDims dims;
board_figureLayout( board, cGlobals->gi,
#if 1
150, 200,
#else
0, 0,
#endif
16, 16,
XP_FALSE, &rect, &dims );
board_applyLayout( board, &dims );
#else
short timerLeft, timerTop;
gint hscale, vscale;
gint trayTop;
@ -607,48 +636,39 @@ configure_event( GtkWidget* widget, GdkEventConfigure* XP_UNUSED(event),
gint nCols;
gint nRows;
if ( globals->draw == NULL ) {
createOrLoadObjects( globals );
}
nCols = globals->cGlobals.gi->boardSize;
nCols = cGlobals->gi->boardSize;
nRows = nCols;
bdWidth = widget->allocation.width - (GTK_RIGHT_MARGIN
+ GTK_BOARD_LEFT_MARGIN);
if ( globals->cGlobals.params->verticalScore ) {
if ( cGlobals->params->verticalScore ) {
bdWidth -= GTK_VERT_SCORE_WIDTH;
}
bdHeight = widget->allocation.height - (GTK_TOP_MARGIN + GTK_BOTTOM_MARGIN)
- GTK_MIN_TRAY_SCALEV - GTK_BOTTOM_MARGIN;
hscale = bdWidth / nCols;
if ( 0 != globals->cGlobals.params->nHidden ) {
if ( 0 != cGlobals->params->nHidden ) {
vscale = hscale;
} else {
vscale = (bdHeight / (nCols + GTK_TRAY_HT_ROWS)); /* makd tray height
3x cell height */
}
if ( !globals->cGlobals.params->verticalScore ) {
if ( !cGlobals->params->verticalScore ) {
boardTop += GTK_HOR_SCORE_HEIGHT;
}
trayTop = boardTop + (vscale * nRows);
/* move tray up if part of board's meant to be hidden */
trayTop -= vscale * globals->cGlobals.params->nHidden;
board_setPos( globals->cGlobals.game.board, GTK_BOARD_LEFT, boardTop,
trayTop -= vscale * cGlobals->params->nHidden;
board_setPos( board, GTK_BOARD_LEFT, boardTop,
hscale * nCols, vscale * nRows, hscale * 4, XP_FALSE );
/* board_setScale( globals->cGlobals.game.board, hscale, vscale ); */
globals->gridOn = XP_TRUE;
/* board_setScale( board, hscale, vscale ); */
if ( !!globals->cGlobals.game.comms ) {
if ( !!cGlobals->game.comms ) {
netStatWidth = GTK_NETSTAT_WIDTH;
}
timerTop = GTK_TIMER_TOP;
if ( globals->cGlobals.params->verticalScore ) {
if ( cGlobals->params->verticalScore ) {
timerLeft = GTK_BOARD_LEFT + (hscale*nCols) + 1;
board_setScoreboardLoc( globals->cGlobals.game.board,
board_setScoreboardLoc( board,
timerLeft,
GTK_VERT_SCORE_TOP,
GTK_VERT_SCORE_WIDTH,
@ -658,7 +678,7 @@ configure_event( GtkWidget* widget, GdkEventConfigure* XP_UNUSED(event),
} else {
timerLeft = GTK_BOARD_LEFT + (hscale*nCols)
- GTK_TIMER_WIDTH - netStatWidth;
board_setScoreboardLoc( globals->cGlobals.game.board,
board_setScoreboardLoc( board,
GTK_BOARD_LEFT, GTK_HOR_SCORE_TOP,
timerLeft-GTK_BOARD_LEFT,
GTK_HOR_SCORE_HEIGHT,
@ -667,24 +687,26 @@ configure_event( GtkWidget* widget, GdkEventConfigure* XP_UNUSED(event),
}
/* Still pending: do this for the vertical score case */
if ( globals->cGlobals.game.comms ) {
if ( cGlobals->game.comms ) {
globals->netStatLeft = timerLeft + GTK_TIMER_WIDTH;
globals->netStatTop = 0;
}
board_setTimerLoc( globals->cGlobals.game.board, timerLeft, timerTop,
board_setTimerLoc( board, timerLeft, timerTop,
GTK_TIMER_WIDTH, GTK_HOR_SCORE_HEIGHT );
board_setTrayLoc( globals->cGlobals.game.board, GTK_TRAY_LEFT, trayTop,
board_setTrayLoc( board, GTK_TRAY_LEFT, trayTop,
hscale * nCols, vscale * GTK_TRAY_HT_ROWS + 10,
GTK_DIVIDER_WIDTH );
#endif
globals->gridOn = XP_TRUE;
setCtrlsForTray( globals );
board_invalAll( globals->cGlobals.game.board );
board_invalAll( board );
XP_Bool inOut[2];
board_zoom( globals->cGlobals.game.board, 0, inOut );
board_zoom( board, 0, inOut );
setZoomButtons( globals, inOut );
return TRUE;

View file

@ -56,6 +56,7 @@ gtkInsetRect( XP_Rect* r, short i )
r->left += i;
i *= 2;
XP_ASSERT( r->height >= i && r->width >= i );
r->width -= i;
r->height -= i;
} /* gtkInsetRect */

View file

@ -989,7 +989,10 @@ send_or_close( CommonGlobals* cGlobals, const XP_U8* buf, size_t len )
cGlobals->socket = -1;
/* delete all pending packets since the socket's bad */
g_slist_free_full( cGlobals->packetQueue, free_elem_proc );
for ( GSList* iter = cGlobals->packetQueue; !!iter; iter = iter->next ) {
free_elem_proc( iter->data );
}
g_slist_free( cGlobals->packetQueue );
cGlobals->packetQueue = NULL;
}
LOG_RETURNF( "%d", success );