Merge branch 'android_branch' into toolbar

Conflicts:
	xwords4/android/XWords4/jni/Android.mk
	xwords4/android/XWords4/jni/xwjni.c
	xwords4/android/XWords4/res/values/strings.xml
	xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardView.java
	xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/XwJNI.java
This commit is contained in:
Andy2 2010-07-16 06:32:32 -07:00
commit a99e8142b0
29 changed files with 322 additions and 121 deletions

View file

@ -21,8 +21,8 @@
to come from a domain that you own or have control over. -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.eehouse.android.xw4"
android:versionCode="5"
android:versionName="4.4 beta 11"
android:versionCode="6"
android:versionName="4.4 beta 12"
>
<uses-permission android:name="android.permission.INTERNET" />

View file

@ -11,4 +11,19 @@
android:textAppearance="?android:attr/textAppearanceLarge"
android:longClickable="true"
android:background="@android:drawable/list_selector_background"
/>
>
<TextView android:id="@+id/text_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<ImageButton android:id="@+id/hint_button_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_delete"
android:visibility="gone"
/>
</org.eehouse.android.xw4.XWListItem>

View file

@ -4,9 +4,6 @@
<item android:id="@+id/dicts_item_select"
android:title="@string/dicts_item_select"
/>
<item android:id="@+id/dicts_item_delete"
android:title="@string/dicts_item_delete"
/>
<item android:id="@+id/dicts_item_details"
android:title="@string/dicts_item_details"
/>

View file

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<!-- <item android:id="@+id/list_item_open" -->
<!-- android:title="@string/list_item_open" -->
<!-- /> -->
<item android:id="@+id/player_list_item_delete"
android:title="@string/list_item_delete"
/>
<item android:id="@+id/player_list_item_up"
android:title="@string/list_item_up"
/>
<item android:id="@+id/player_list_item_down"
android:title="@string/list_item_down"
/>
</menu>

View file

@ -13,6 +13,7 @@
<string name="key_ringer_zoom">key_ringer_zoom</string>
<string name="key_click_launches">key_click_launches</string>
<string name="key_hide_title">key_hide_title</string>
<string name="key_show_bonussum">key_show_bonussum</string>
<string name="key_player0">key_clr_player0</string>
<string name="key_player1">key_clr_player1</string>
<string name="key_player2">key_clr_player2</string>
@ -23,7 +24,7 @@
<string name="key_bonus_w3x">key_clr_bonus_w3x</string>
<string name="key_tile_back">key_clr_tile_back</string>
<string name="key_empty">key_clr_empty</string>
<string name="key_focus">key_clr_focus</string>
<string name="key_clr_crosshairs">key_clr_crosshairs</string>
<string name="key_relay_host">key_relay_host</string>
<string name="key_relay_port">key_relay_port</string>
<string name="key_sms_port">key_sms_port</string>

View file

@ -205,6 +205,11 @@
<string name="hide_title">Hide titlebar</string>
<string name="hide_title_summary">Hiding the game name lets the
board be slightly larger</string>
<string name="show_bonussum">Show bonus values</string>
<string name="show_bonussum_summary">Include text like "2W" on
empty bonus squares</string>
<string name="role_standalone">Standalone</string>
<string name="role_host">Host</string>
<string name="role_guest">Guest</string>
@ -270,10 +275,11 @@
<string name="bonus_w2x_summary">2W</string>
<string name="bonus_l3x_summary">3L</string>
<string name="bonus_w3x_summary">3W</string>
<string name="pts">pts</string>
<string name="trading_text">Exchanging tiles. Select\n\'Turn done\' when ready.</string>
<string name="tile_back">Tile background</string>
<string name="empty">Empty cell/background</string>
<string name="focus">Focus color</string>
<string name="clr_crosshairs">Crosshairs color</string>
<string name="advanced">Advanced</string>
<string name="advanced_summary">You may never need these...</string>
<string name="relay_host">Relay address</string>

View file

@ -57,6 +57,11 @@
android:summary="@string/hide_title_summary"
android:defaultValue="true"
/>
<CheckBoxPreference android:key="@string/key_show_bonussum"
android:title="@string/show_bonussum"
android:summary="@string/show_bonussum_summary"
android:defaultValue="true"
/>
<PreferenceScreen android:title="@string/prefs_colors"
android:summary="@string/prefs_colors_summary"
>
@ -106,8 +111,8 @@
android:defaultValue="0xFFFF99"
/>
<org.eehouse.android.xw4.EditColorPreference
android:key="@string/key_focus"
android:title="@string/focus"
android:key="@string/key_clr_crosshairs"
android:title="@string/clr_crosshairs"
android:defaultValue="0x7070FF"
/>
<org.eehouse.android.xw4.EditColorPreference

View file

@ -45,6 +45,7 @@ public class BoardView extends View implements DrawCtx, BoardHandler,
private static final int k_miniPaddingV = 2;
private static final float MIN_FONT_DIPS = 14.0f;
private Context m_context;
private Paint m_drawPaint;
private Paint m_fillPaint;
private Paint m_strokePaint;
@ -159,6 +160,7 @@ public class BoardView extends View implements DrawCtx, BoardHandler,
private void init( Context context )
{
m_context = context;
final float scale = getResources().getDisplayMetrics().density;
m_defaultFontHt = (int)(MIN_FONT_DIPS * scale + 0.5f);
m_mediumFontHt = m_defaultFontHt * 3 / 2;
@ -190,14 +192,13 @@ public class BoardView extends View implements DrawCtx, BoardHandler,
m_otherColors = prefs.otherColors;
m_bonusSummaries = new String[5];
m_bonusSummaries[1] =
getResources().getString( R.string.bonus_l2x_summary );
m_bonusSummaries[2] =
getResources().getString( R.string.bonus_w2x_summary );
m_bonusSummaries[3] =
getResources().getString( R.string.bonus_l3x_summary );
m_bonusSummaries[4] =
getResources().getString( R.string.bonus_w3x_summary );
int[] ids = { R.string.bonus_l2x_summary,
R.string.bonus_w2x_summary ,
R.string.bonus_l3x_summary,
R.string.bonus_w3x_summary };
for ( int ii = 0; ii < ids.length; ++ii ) {
m_bonusSummaries[ ii+1 ] = getResources().getString( ids[ii] );
}
m_viewHandler = new Handler();
}
@ -466,7 +467,9 @@ public class BoardView extends View implements DrawCtx, BoardHandler,
backColor = m_otherColors[CommonPrefs.COLOR_BKGND];
} else {
backColor = m_bonusColors[bonus];
bonusStr = m_bonusSummaries[bonus];
if ( CommonPrefs.getShowBonusSumms(m_context) ) {
bonusStr = m_bonusSummaries[bonus];
}
}
} else if ( pending ) {
backColor = BLACK;
@ -484,7 +487,7 @@ public class BoardView extends View implements DrawCtx, BoardHandler,
} else if ( null != bonusStr ) {
m_fillPaint.setColor( GREY );
drawCentered( bonusStr, rect, m_fontDims );
}
}
} else {
m_fillPaint.setColor( foreColor );
drawCentered( text, rect, m_fontDims );
@ -493,14 +496,14 @@ public class BoardView extends View implements DrawCtx, BoardHandler,
if ( (CELL_ISBLANK & flags) != 0 ) {
markBlank( rect, pending );
}
// frame the cell
// frame the cell
m_canvas.drawRect( rect, m_strokePaint );
return true;
} // drawCell
public void drawBoardArrow ( Rect rect, int bonus, boolean vert,
int hintAtts, int flags )
public void drawBoardArrow( Rect rect, int bonus, boolean vert,
int hintAtts, int flags )
{
rect.inset( 2, 2 );
Drawable arrow = vert? m_downArrow : m_rightArrow;
@ -555,8 +558,12 @@ public class BoardView extends View implements DrawCtx, BoardHandler,
fillRect( rect, (0 == (flags & CELL_ISCURSOR))
? WHITE : m_otherColors[CommonPrefs.COLOR_FOCUS] );
m_fillPaint.setColor( m_playerColors[playerNum] );
rect.inset( 0, rect.height() / 4 );
rect.bottom -= rect.height() / 2;
drawCentered( text, rect, null );
rect.offset( 0, rect.height() );
drawCentered( getResources().getString( R.string.pts ), rect, null );
}
public String getMiniWText ( int textHint )
@ -624,7 +631,17 @@ public class BoardView extends View implements DrawCtx, BoardHandler,
}
m_canvas.drawRect( rect, m_strokePaint );
m_jniThread.handle( JNIThread.JNICmd.CMD_DRAW );
// Unlike other draw methods, this one is usually called from
// outside board_draw and so doesn't benefit from the canvas
// getting moved to the board. Set that up manually. Sending
// DRAW cmd as I used to do draws *everything* and may well
// overwrite the miniwindow.
m_viewHandler.post( new Runnable() {
public void run() {
BoardView.this.invalidate();
}
} );
}
public void objFinished( /*BoardObjectType*/int typ, Rect rect, int dfs )

View file

@ -39,7 +39,8 @@ import android.content.SharedPreferences;
import junit.framework.Assert;
public class DictsActivity extends ListActivity
implements View.OnClickListener {
implements View.OnClickListener,
XWListItem.DeleteCallback {
String[] m_dicts;
private class DictListAdapter extends XWListAdapter {
@ -58,6 +59,12 @@ public class DictsActivity extends ListActivity
= (XWListItem)factory.inflate( R.layout.list_item, null );
view.setPosition( position );
view.setText( m_dicts[position] );
if ( !GameUtils.dictIsBuiltin( DictsActivity.this,
m_dicts[position] ) ) {
view.setDeleteCallback( DictsActivity.this );
}
return view;
}
}
@ -88,8 +95,8 @@ public class DictsActivity extends ListActivity
@Override
public void onCreateContextMenu( ContextMenu menu, View view,
ContextMenuInfo menuInfo ) {
ContextMenuInfo menuInfo )
{
super.onCreateContextMenu( menu, view, menuInfo );
MenuInflater inflater = getMenuInflater();
@ -97,12 +104,6 @@ public class DictsActivity extends ListActivity
AdapterView.AdapterContextMenuInfo info
= (AdapterView.AdapterContextMenuInfo)menuInfo;
String dict = m_dicts[info.position];
if ( GameUtils.dictIsBuiltin( this, dict ) ) {
MenuItem item = menu.findItem( R.id.dicts_item_delete );
item.setVisible( false );
}
}
@Override
@ -127,11 +128,6 @@ public class DictsActivity extends ListActivity
editor.putString( key, m_dicts[info.position] );
editor.commit();
break;
case R.id.dicts_item_delete:
GameUtils.deleteDict( this, m_dicts[info.position] );
mkListAdapter();
handled = true;
break;
case R.id.dicts_item_details:
Utils.notImpl( this );
break;
@ -140,6 +136,13 @@ public class DictsActivity extends ListActivity
return handled;
}
// DeleteCallback interface
public void deleteCalled( int myPosition )
{
GameUtils.deleteDict( this, m_dicts[myPosition] );
mkListAdapter();
}
private void mkListAdapter()
{
m_dicts = GameUtils.dictList( this );

View file

@ -41,8 +41,6 @@ import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuInflater;
import android.view.KeyEvent;
import android.widget.Spinner;
@ -56,7 +54,8 @@ import junit.framework.Assert;
import org.eehouse.android.xw4.jni.*;
import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole;
public class GameConfig extends Activity implements View.OnClickListener {
public class GameConfig extends Activity implements View.OnClickListener,
XWListItem.DeleteCallback {
private static final int PLAYER_EDIT = 1;
private static final int ROLE_EDIT_RELAY = 2;
@ -453,42 +452,12 @@ public class GameConfig extends Activity implements View.OnClickListener {
setTitle( String.format( fmt, GameUtils.gameName( this, m_path ) ) );
} // onCreate
@Override
public void onCreateContextMenu( ContextMenu menu, View view,
ContextMenuInfo menuInfo ) {
MenuInflater inflater = getMenuInflater();
inflater.inflate( R.menu.players_list_item_menu, menu );
m_whichPlayer = ((XWListItem)view).getPosition();
}
@Override
public boolean onContextItemSelected( MenuItem item )
// DeleteCallback interface
public void deleteCalled( int myPosition )
{
boolean handled = true;
boolean changed = false;
switch (item.getItemId()) {
// case R.id.player_list_item_edit:
// showDialog( PLAYER_EDIT );
// break;
case R.id.player_list_item_delete:
changed = m_gi.delete( m_whichPlayer );
break;
case R.id.player_list_item_up:
changed = m_gi.moveUp( m_whichPlayer );
break;
case R.id.player_list_item_down:
changed = m_gi.moveDown( m_whichPlayer );
break;
default:
handled = false;
}
if ( changed ) {
if ( m_gi.delete( myPosition ) ) {
loadPlayers();
}
return handled;
}
public void onClick( View view )
@ -560,8 +529,11 @@ public class GameConfig extends Activity implements View.OnClickListener {
view.setPosition( ii );
view.setText( names[ii] );
view.setGravity( Gravity.CENTER );
// only enable delete if one will remain
if ( 1 < names.length ) {
view.setDeleteCallback( this );
}
registerForContextMenu( view );
view.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick( View view ) {

View file

@ -146,6 +146,9 @@ public class GamesList extends ListActivity {
{
MenuInflater inflater = getMenuInflater();
inflater.inflate( R.menu.games_list_item_menu, menu );
if ( CommonPrefs.getClickLaunches( this ) ) {
menu.removeItem( R.id.list_item_play );
}
}
@Override

View file

@ -64,7 +64,7 @@ public class PrefsActivity extends PreferenceActivity
R.string.key_bonus_w2x,
R.string.key_bonus_w3x,
R.string.key_tile_back,
R.string.key_focus,
R.string.key_clr_crosshairs,
R.string.key_empty,
};
for ( int colorKey : colorKeys ) {

View file

@ -23,5 +23,5 @@ package org.eehouse.android.xw4;
public interface XWConstants {
public static final String GAME_EXTN = ".xwg";
public static final String DICT_EXTN = ".xwd";
public static final String VERSION_STR = "4.4 beta 11";
public static final String VERSION_STR = "4.4 beta 12";
}

View file

@ -20,18 +20,48 @@
package org.eehouse.android.xw4;
import android.widget.LinearLayout;
import android.view.View;
import android.widget.TextView;
import android.widget.ImageButton;
import android.content.Context;
import android.util.AttributeSet;
import android.graphics.Rect;
public class XWListItem extends TextView {
public class XWListItem extends LinearLayout {
private int m_position;
private ImageButton m_button;
private Context m_context;
DeleteCallback m_cb;
public interface DeleteCallback {
void deleteCalled( int myPosition );
}
public XWListItem( Context cx, AttributeSet as ) {
super( cx, as );
m_context = cx;
}
public int getPosition() { return m_position; }
public void setPosition( int indx ) { m_position = indx; }
public void setText( String text )
{
TextView view = (TextView)getChildAt( 0 );
view.setText( text );
}
public void setDeleteCallback( DeleteCallback cb )
{
m_cb = cb;
ImageButton button = (ImageButton)getChildAt( 1 );
button.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick( View view ) {
m_cb.deleteCalled( m_position );
}
} );
button.setVisibility( View.VISIBLE );
}
}

View file

@ -100,7 +100,7 @@ public class CommonPrefs {
int idsOther[] = { R.string.key_tile_back,
R.string.key_empty,
R.string.key_focus,
R.string.key_clr_crosshairs,
};
for ( int ii = 0; ii < idsOther.length; ++ii ) {
otherColors[ii] = prefToColor( context, sp, idsOther[ii] );
@ -222,6 +222,11 @@ public class CommonPrefs {
return getBoolean( context, R.string.key_click_launches, false );
}
public static boolean getShowBonusSumms( Context context )
{
return getBoolean( context, R.string.key_show_bonussum, false );
}
private static boolean getBoolean( Context context, int keyID,
boolean defaultValue )
{

View file

@ -146,6 +146,7 @@ public class XwJNI {
public static native boolean board_beginTrade( int gamePtr );
public static native String board_formatRemainingTiles( int gamePtr );
public static native int board_visTileCount( int gamePtr );
public static native boolean board_canHint( int gamePtr );
public static native boolean board_canShuffle( int gamePtr );

View file

@ -935,7 +935,12 @@ timerFiredForPen( BoardCtxt* board )
coordToCell( board, board->penDownX, board->penDownY, &col, &row );
if ( dragDropIsBeingDragged( board, col, row, NULL ) ) {
/* even if we aren't calling dragDropSetAdd we want to avoid
putting up a sqare bonus if we're on a sqare with
something that can be dragged */
#ifdef XWFEATURE_RAISETILE
draw = dragDropSetAdd( board );
#endif
} else {
XWBonusType bonus;
bonus = util_getSquareBonus( board->util, board->model,
@ -1037,6 +1042,7 @@ p_board_timerFired( void* closure, XWTimerReason why )
return draw;
} /* board_timerFired */
#ifdef XWFEATURE_RAISETILE
static XP_Bool
p_tray_timerFired( void* closure, XWTimerReason why )
{
@ -1047,6 +1053,7 @@ p_tray_timerFired( void* closure, XWTimerReason why )
}
return draw;
}
#endif
void
board_pushTimerSave( BoardCtxt* board )
@ -1321,6 +1328,28 @@ invalCellsUnderRect( BoardCtxt* board, const XP_Rect* rect )
}
} /* invalCellsUnderRect */
#ifdef XWFEATURE_CROSSHAIRS
void
invalCol( BoardCtxt* board, XP_U16 col )
{
XP_U16 row;
XP_U16 nCols = model_numCols(board->model);
for ( row = 0; row < nCols; ++row ) {
invalCell( board, col, row );
}
}
void
invalRow( BoardCtxt* board, XP_U16 row )
{
XP_U16 col;
XP_U16 nCols = model_numCols(board->model);
for ( col = 0; col < nCols; ++col ) {
invalCell( board, col, row );
}
}
#endif
void
board_invalRect( BoardCtxt* board, XP_Rect* rect )
{
@ -2189,10 +2218,10 @@ handleLikeDown( BoardCtxt* board, BoardObjectType onWhich, XP_U16 x, XP_U16 y )
case OBJ_TRAY:
if ( (board->trayVisState == TRAY_REVEALED)
&& !board->selInfo->tradeInProgress ) {
#ifdef XWFEATURE_RAISETILE
util_setTimer( board->util, TIMER_PENDOWN, 0,
p_tray_timerFired, board );
#endif
result = dragDropStart( board, OBJ_TRAY, x, y ) || result;
}
break;

View file

@ -310,11 +310,17 @@ drawBoard( BoardCtxt* board )
CellFlags flags = CELL_NONE;
bonus = util_getSquareBonus( board->util, model, col, row );
hintAtts = figureHintAtts( board, col, row );
if ( 0 ) {
#ifdef KEYBOARD_NAV
if ( cellFocused( board, col, row ) ) {
} else if ( cellFocused( board, col, row ) ) {
flags |= CELL_ISCURSOR;
}
#endif
#ifdef XWFEATURE_CROSSHAIRS
} else if ( dragDropInCrosshairs( board, col, row ) ) {
flags |= CELL_ISCURSOR;
#endif
}
draw_drawBoardArrow( board->draw, &arrowRect, bonus,
arrow->vert, hintAtts, flags );
}
@ -426,6 +432,11 @@ drawCell( BoardCtxt* board, XP_U16 col, XP_U16 row, XP_Bool skipBlanks )
flags |= CELL_ISCURSOR;
}
#endif
#ifdef XWFEATURE_CROSSHAIRS
if ( dragDropInCrosshairs( board, col, row ) ) {
flags |= CELL_ISCURSOR;
}
#endif
success = draw_drawCell( board->draw, &cellRect, textP, bptr,
tile, owner, bonus, hintAtts, flags );

View file

@ -63,8 +63,15 @@ typedef struct _DragState {
Tile tile; /* cache rather than lookup in model */
DragObjInfo start;
DragObjInfo cur;
#ifdef XWFEATURE_RAISETILE
XP_U16 yyAdd;
#endif
#ifdef XWFEATURE_CROSSHAIRS
struct {
XP_S16 col;
XP_S16 row;
} crosshairs;
#endif
} DragState;
typedef struct _BoardArrow { /* gets flipped along with board */
@ -257,6 +264,11 @@ void invalCellRegion( BoardCtxt* board, XP_U16 colA, XP_U16 rowA, XP_U16 colB,
XP_U16 rowB );
void invalCell( BoardCtxt* board, XP_U16 col, XP_U16 row );
void invalDragObj( BoardCtxt* board, const DragObjInfo* di );
#ifdef XWFEATURE_CROSSHAIRS
void invalCol( BoardCtxt* board, XP_U16 col );
void invalRow( BoardCtxt* board, XP_U16 row );
#endif
void invalTrayTilesAbove( BoardCtxt* board, XP_U16 tileIndex );
void invalTrayTilesBetween( BoardCtxt* board, XP_U16 tileIndex1,
XP_U16 tileIndex2 );

View file

@ -1,4 +1,4 @@
/* -*-mode: C; fill-column: 78; compile-command: "cd ../linux && make MEMDEBUG=TRUE"; -*- */
/* -*-mode: C; fill-column: 78; compile-command: "cd ../linux && make MEMDEBUG=TRUE -j3"; -*- */
/*
* Copyright 1997 - 2010 by Eric House (xwords@eehouse.org). All rights
* reserved.
@ -40,6 +40,16 @@ static void invalHintRectDiffs( BoardCtxt* board, const DragObjInfo* cur,
static void setLimitsFrom( const BoardCtxt* board, BdHintLimits* limits );
#endif
#ifdef XWFEATURE_CROSSHAIRS
static void crosshairs_init( BoardCtxt* board );
static XP_Bool crosshairs_set( BoardCtxt* board, XP_S16 col, XP_S16 row );
static void crosshairs_clear( BoardCtxt* board );
#else
# define crosshairs_init( board )
# define crosshairs_set( board, col, row ) XP_FALSE;
# define crosshairs_clear( board )
#endif
static void startScrollTimerIf( BoardCtxt* board );
XP_Bool
@ -66,6 +76,8 @@ ddStartBoard( BoardCtxt* board, XP_U16 xx, XP_U16 yy )
found = coordToCell( board, xx, yy, &col, &row );
XP_ASSERT( found );
crosshairs_init( board );
(void)crosshairs_set( board, col, row );
trayVisible = board->trayVisState == TRAY_REVEALED;
if ( trayVisible && holdsPendingTile( board, col, row ) ) {
@ -281,11 +293,14 @@ dragDropEnd( BoardCtxt* board, XP_U16 xx, XP_U16 yy, XP_Bool* dragged )
invalDragObj( board, &ds->cur );
invalDragObj( board, &ds->start );
}
crosshairs_clear( board );
ds->dtype = DT_NONE;
return XP_TRUE;
} /* dragDropEnd */
#ifdef XWFEATURE_RAISETILE
XP_Bool
dragDropSetAdd( BoardCtxt* board )
{
@ -303,6 +318,7 @@ dragDropSetAdd( BoardCtxt* board )
}
return draw;
}
#endif
XP_Bool
dragDropGetBoardTile( const BoardCtxt* board, XP_U16* col, XP_U16* row )
@ -438,8 +454,11 @@ dragDropContinueImpl( BoardCtxt* board, XP_U16 xx, XP_U16 yy,
XP_Bool moving = XP_FALSE;
DragObjInfo newInfo;
DragState* ds = &board->dragState;
XP_Bool draw = XP_FALSE;
#ifdef XWFEATURE_RAISETILE
yy -= ds->yyAdd;
#endif
(void)pointOnSomething( board, xx, yy, &newInfo.obj );
if ( !!onWhichP ) {
@ -449,6 +468,8 @@ dragDropContinueImpl( BoardCtxt* board, XP_U16 xx, XP_U16 yy,
if ( newInfo.obj == OBJ_BOARD ) {
(void)coordToCell( board, xx, yy, &newInfo.u.board.col,
&newInfo.u.board.row );
draw = crosshairs_set( board, newInfo.u.board.col,
newInfo.u.board.row );
}
if ( ds->dtype == DT_DIVIDER ) {
@ -519,6 +540,7 @@ dragDropContinueImpl( BoardCtxt* board, XP_U16 xx, XP_U16 yy,
}
if ( moving ) {
draw = XP_TRUE;
if ( !ds->didMove ) {
/* This is the first time we've moved!!! Kill any future timers,
and if there's a window up kill it.*/
@ -530,7 +552,7 @@ dragDropContinueImpl( BoardCtxt* board, XP_U16 xx, XP_U16 yy,
}
}
return moving;
return draw;
} /* dragDropContinueImpl */
static void
@ -619,6 +641,61 @@ startScrollTimerIf( BoardCtxt* board )
}
} /* startScrollTimerIf */
#ifdef XWFEATURE_CROSSHAIRS
XP_Bool
dragDropInCrosshairs( const BoardCtxt* board, XP_U16 col, XP_U16 row )
{
XP_Bool result = dragDropInProgress( board );
if ( result ) {
const DragState* ds = &board->dragState;
result = ds->crosshairs.col == col
|| ds->crosshairs.row == row;
}
return result;
} /* dragDropInCrosshairs */
static void
crosshairs_init( BoardCtxt* board )
{
DragState* ds = &board->dragState;
ds->crosshairs.col = ds->crosshairs.col = -1;
}
static XP_Bool
crosshairs_set( BoardCtxt* board, XP_S16 col, XP_S16 row )
{
XP_Bool changed = XP_FALSE;
DragState* ds = &board->dragState;
if ( ds->crosshairs.col != col ) {
if ( ds->crosshairs.col >= 0 ) {
invalCol( board, ds->crosshairs.col );
}
if ( col >= 0 ) {
invalCol( board, col );
}
ds->crosshairs.col = col;
changed = XP_TRUE;
}
if ( ds->crosshairs.row != row ) {
if ( ds->crosshairs.row >= 0 ) {
invalRow( board, ds->crosshairs.row );
}
if ( row >= 0 ) {
invalRow( board, row );
}
ds->crosshairs.row = row;
changed = XP_TRUE;
}
return changed;
}
static void
crosshairs_clear( BoardCtxt* board )
{
crosshairs_set( board, -1, -1 );
}
#endif
#ifdef CPLUS
}
#endif

View file

@ -36,7 +36,9 @@ XP_Bool dragDropStart( BoardCtxt* board, BoardObjectType obj,
XP_Bool dragDropContinue( BoardCtxt* board, XP_U16 xx, XP_U16 yy );
XP_Bool dragDropEnd( BoardCtxt* board, XP_U16 xx, XP_U16 yy, XP_Bool* dragged );
#ifdef XWFEATURE_RAISETILE
XP_Bool dragDropSetAdd( BoardCtxt* board );
#endif
XP_Bool dragDropGetBoardTile( const BoardCtxt* board, XP_U16* col, XP_U16* row );
XP_Bool dragDropIsBeingDragged( const BoardCtxt* board, XP_U16 col, XP_U16 row,
@ -54,8 +56,10 @@ XP_Bool dragDropIsDividerDrag( const BoardCtxt* board );
XP_Bool dragDropGetHintLimits( const BoardCtxt* board, BdHintLimits* limits );
#endif
void dragDropTileInfo( const BoardCtxt* board, Tile* tile, XP_Bool* isBlank );
#ifdef XWFEATURE_CROSSHAIRS
XP_Bool dragDropInCrosshairs( const BoardCtxt* board, XP_U16 col, XP_U16 row );
#endif
#ifdef CPLUS
}

5
xwords4/dawg/.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
*.bin
*.xwd
*.stamp
*.dict.gz
dict2dawg

View file

@ -2,3 +2,4 @@
obj_linux_memdbg
*.xwg
obj_linux_rel
*.xwd

View file

@ -80,7 +80,9 @@ ifdef DO_GTK
DEFINES += -DXWFEATURE_SEARCHLIMIT
endif
DEFINES += -DFEATURE_TRAY_EDIT
#DEFINES += -DXWFEATURE_RAISETILE
#DEFINES += -DDRAW_WITH_PRIMITIVES
DEFINES += -DXWFEATURE_CROSSHAIRS
ifdef CURSES_CELL_HT
DEFINES += -DCURSES_CELL_HT=$(CURSES_CELL_HT)

View file

@ -2,3 +2,4 @@
xwrelay.log
xwrelay.pid
xwrelay
xwrelay.conf

View file

@ -328,7 +328,8 @@ CookieRef::removeSocket( int socket )
}
}
} else {
logf( XW_LOGERROR, "%s: no socket %d to remove", __func__, socket );
logf( XW_LOGERROR, "%s: no socket %d to remove", __func__,
socket );
}
}
@ -555,7 +556,6 @@ CookieRef::handleEvents()
case XWA_SEND_NO_ROOM:
send_denied( &evt, XWRELAY_ERROR_NO_ROOM );
removeSocket( evt.u.rmsock.socket );
break;
case XWA_SEND_DUP_ROOM:
send_denied( &evt, XWRELAY_ERROR_DUP_ROOM );
@ -647,6 +647,10 @@ CookieRef::handleEvents()
}
m_curState = nextState;
} else {
logf( XW_LOGERROR, "unable to find transition "
"from %s on event %s", stateString(m_curState),
eventString(evt.type) );
}
}
m_in_handleEvents = false;
@ -731,7 +735,7 @@ CookieRef::increasePlayerCounts( const CRefEvent* evt, bool reconn )
HostID hid = evt->u.con.srcID;
int seed = evt->u.con.seed;
CRefEvent newevt;
bool addHost = true;
bool addHost = false;
assert( hid <= 4 );
@ -754,28 +758,43 @@ CookieRef::increasePlayerCounts( const CRefEvent* evt, bool reconn )
if ( reconn ) {
if ( nPlayersS > 0 ) {
assert( 0 == m_nPlayersSought );
if ( 0 != m_nPlayersSought ) {
logf( XW_LOGERROR,
"already have m_nPlayersSought: %d but new value %d",
m_nPlayersSought, nPlayersS );
goto drop;
}
m_nPlayersSought = nPlayersS;
}
if ( 0 != m_nPlayersSought &&
m_nPlayersHere + nPlayersH > m_nPlayersSought ) {
logf( XW_LOGERROR, "too many new players provided: %d > %d",
m_nPlayersHere + nPlayersH, m_nPlayersSought );
goto drop;
}
m_nPlayersHere += nPlayersH;
assert( 0 == m_nPlayersSought || m_nPlayersHere <= m_nPlayersSought );
if ( m_nPlayersHere == m_nPlayersSought ) {
newevt.type = XWE_ALLHERE;
} else {
newevt.type = XWE_SOMEMISSING;
}
addHost = true;
} else if ( nPlayersS > 0 ) { /* a host; init values */
assert( m_nPlayersSought == 0 );
assert( m_nPlayersHere == 0 );
if ( m_nPlayersSought != 0 || m_nPlayersHere != 0 ) {
logf( XW_LOGERROR, "cref in bad state: m_nPlayersSought: %d; "
"m_nPlayersHere: %d", m_nPlayersSought, m_nPlayersHere );
goto drop;
}
m_nPlayersHere = nPlayersH;
m_nPlayersSought = nPlayersS;
addHost = true;
} else { /* a guest */
assert( reconn || m_nPlayersSought != 0 ); /* host better be here */
if ( m_nPlayersSought < m_nPlayersHere + nPlayersH ) { /* too many;
reject */
newevt.type = XWE_TOO_MANY;
addHost = false;
} else {
m_nPlayersHere += nPlayersH;
if ( m_nPlayersHere == m_nPlayersSought ) { /* complete! */
@ -784,6 +803,7 @@ CookieRef::increasePlayerCounts( const CRefEvent* evt, bool reconn )
} else {
newevt.type = XWE_SOMEMISSING;
}
addHost = true;
}
}
@ -803,6 +823,7 @@ CookieRef::increasePlayerCounts( const CRefEvent* evt, bool reconn )
logf( XW_LOGVERBOSE1, "%s: here=%d; total=%d", __func__,
m_nPlayersHere, m_nPlayersSought );
}
drop:
return addHost;
} /* increasePlayerCounts */

View file

@ -137,8 +137,8 @@ printCrefs( FILE* fil, const CrefMgrInfo* info, bool isLocal )
fprintf( fil, "</tr>\n" );
time_t curTime = uptime();
unsigned int ii;
for ( ii = 0; ii < info->m_crefInfo.size(); ++ii ) {
int ii;
for ( ii = info->m_crefInfo.size() - 1; ii >= 0; --ii ) {
const CrefInfo* crefInfo = &info->m_crefInfo[ii];
char conntime[32];

View file

@ -148,11 +148,6 @@ getFromTable( XW_RELAY_STATE curState, XW_RELAY_EVENT curEvent,
++stp;
}
if ( !found ) {
logf( XW_LOGERROR, "==> ERROR :: unable to find transition from %s "
"on event %s",
stateString(curState), eventString(curEvent) );
}
return found;
} /* getFromTable */

View file

@ -363,6 +363,9 @@ processReconnect( unsigned char* bufp, int bufLen, int socket )
&& getNetShort( &bufp, end, &gameSeed )
&& readStr( &bufp, end, connName, sizeof(connName) ) ) {
static pthread_mutex_t s_newCookieLock = PTHREAD_MUTEX_INITIALIZER;
MutexLock ml( &s_newCookieLock );
SafeCref scr( cookie[0]? cookie : NULL,
connName[0]? connName : NULL,
srcID, socket, nPlayersH,
@ -903,8 +906,9 @@ main( int argc, char** argv )
int newSock = accept( listener, (sockaddr*)&newaddr,
&siz );
logf( XW_LOGINFO, "accepting connection from %s",
inet_ntoa(newaddr.sin_addr) );
logf( XW_LOGINFO,
"accepting connection from %s on socket %d",
inet_ntoa(newaddr.sin_addr), newSock );
tPool->AddSocket( newSock );
--retval;