diff --git a/xwords4/wince/ceblank.c b/xwords4/wince/ceblank.c index 76e2a1151..9c8430e79 100755 --- a/xwords4/wince/ceblank.c +++ b/xwords4/wince/ceblank.c @@ -31,13 +31,13 @@ loadLettersList( BlankDialogState* bState ) HWND hDlg = bState->dlgHdr.hDlg; CEAppGlobals* globals = bState->dlgHdr.globals; const XP_UCHAR4* texts = bState->texts; + UINT codePage = ceCurDictIsUTF8(globals)? CP_UTF8 : CP_ACP; for ( i = 0; i < nTiles; ++i ) { XP_U16 len; wchar_t widebuf[4]; - len = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, - texts[i], strlen(texts[i]), + len = MultiByteToWideChar( codePage, 0, texts[i], strlen(texts[i]), widebuf, VSIZE(widebuf) ); widebuf[len] = 0; @@ -63,8 +63,9 @@ showCurTray( HWND hDlg, BlankDialogState* bState ) XP_UCHAR labelBuf[48]; wchar_t widebuf[48]; XP_UCHAR* name; + CEAppGlobals* globals = bState->dlgHdr.globals; - name = bState->dlgHdr.globals->gameInfo.players[bState->playerNum].name; + name = globals->gameInfo.players[bState->playerNum].name; lenSoFar += XP_SNPRINTF( labelBuf + lenSoFar, sizeof(labelBuf) - lenSoFar, @@ -77,9 +78,8 @@ showCurTray( HWND hDlg, BlankDialogState* bState ) i==0?": ":", ", pi->curTiles[i] ); } - (void)MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, - labelBuf, lenSoFar + 1, - widebuf, + (void)MultiByteToWideChar( ceCurDictIsUTF8(globals)? CP_UTF8 : CP_ACP, + 0, labelBuf, lenSoFar + 1, widebuf, VSIZE(widebuf) + sizeof(widebuf[0]) ); SetDlgItemText( hDlg,IDC_PICKMSG, widebuf ); diff --git a/xwords4/wince/cedraw.c b/xwords4/wince/cedraw.c index ab9a55c36..6ed9325c6 100755 --- a/xwords4/wince/cedraw.c +++ b/xwords4/wince/cedraw.c @@ -89,7 +89,7 @@ typedef struct _FontCacheEntry { } FontCacheEntry; typedef struct _CeBMCacheEntry { - XP_UCHAR letters[4]; /* currently the max */ + const XP_UCHAR* letters; /* pointer into dict; don't free!!! */ HBITMAP bms[2]; } CeBMCacheEntry; @@ -99,6 +99,7 @@ struct CEDrawCtx { HWND mainWin; CEAppGlobals* globals; const DictionaryCtxt* dict; + UINT codePage; COLORREF prevBkColor; @@ -218,7 +219,7 @@ ceDrawTextClipped( HDC hdc, wchar_t* buf, XP_S16 len, XP_Bool clip, static void ceDrawLinesClipped( HDC hdc, const FontCacheEntry* fce, XP_UCHAR* buf, - XP_Bool clip, const RECT* bounds ) + UINT codePage, XP_Bool clip, const RECT* bounds ) { XP_U16 top = bounds->top; XP_U16 width = bounds->right - bounds->left; @@ -228,8 +229,7 @@ ceDrawLinesClipped( HDC hdc, const FontCacheEntry* fce, XP_UCHAR* buf, XP_U16 len = newline==NULL? strlen(buf): newline - buf; wchar_t widebuf[len]; - MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, buf, len, - widebuf, len ); + MultiByteToWideChar( codePage, 0, buf, len, widebuf, len ); ceDrawTextClipped( hdc, widebuf, len, clip, fce, bounds->left, top, width, DT_CENTER ); @@ -509,7 +509,7 @@ ceBestFitFont( CEDrawCtx* dctx, const XP_U16 soughtHeight, makeTestBuf( dctx, sample, VSIZE(sample), index ); len = 1 + strlen(sample); - MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sample, len, widebuf, len ); + MultiByteToWideChar( dctx->codePage, 0, sample, len, widebuf, len ); memBM = CreateCompatibleBitmap( memDC, testHeight, testHeight ); SelectObject( memDC, memBM ); @@ -626,25 +626,22 @@ checkBMCache( CEDrawCtx* dctx, HDC hdc, const XP_UCHAR* letters, { HBITMAP bm = NULL; CeBMCacheEntry* entry = NULL; - XP_U16 len = 1 + XP_STRLEN( letters ); XP_Bool canCache = XP_FALSE; XP_ASSERT( !!letters ); XP_ASSERT( index < 2 ); - if ( len <= sizeof( entry->letters ) ) { - XP_U16 ii; - for ( ii = 0, entry = dctx->bmCache; ii < VSIZE(dctx->bmCache); - ++ii, ++entry ) { - if ( 0 == entry->letters[0] ) { /* available */ - XP_MEMCPY( entry->letters, letters, len ); - canCache = XP_TRUE; - break; - } else if ( !XP_STRNCMP( entry->letters, letters, len ) ) { - canCache = XP_TRUE; - bm = entry->bms[index]; /* may be null */ - break; - } + XP_U16 ii; + for ( ii = 0, entry = dctx->bmCache; ii < VSIZE(dctx->bmCache); + ++ii, ++entry ) { + if ( !entry->letters ) { /* available */ + entry->letters = letters; + canCache = XP_TRUE; + break; + } else if ( entry->letters == letters ) { + canCache = XP_TRUE; + bm = entry->bms[index]; /* may be null */ + break; } } @@ -756,7 +753,7 @@ ceMeasureText( CEDrawCtx* dctx, HDC hdc, const FontCacheEntry* fce, XP_ASSERT( nextStr != str ); - MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, str, len, + MultiByteToWideChar( dctx->codePage, 0, str, len, widebuf, VSIZE(widebuf) ); GetTextExtentPoint32( hdc, widebuf, len, &size ); @@ -796,7 +793,7 @@ drawTextLines( CEDrawCtx* dctx, HDC hdc, const XP_UCHAR* text, XP_S16 padding, len = nextStr - text; } - MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, text, len, + MultiByteToWideChar( dctx->codePage, 0, text, len, widebuf, VSIZE(widebuf) ); textRt.bottom = textRt.top + dctx->miniLineHt; @@ -1043,7 +1040,7 @@ DRAW_FUNC_NAME(drawCell)( DrawCtx* p_dctx, const XP_Rect* xprect, } else if ( !isDragSrc && !!letters && (letters[0] != '\0') ) { wchar_t widebuf[4]; - MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, letters, -1, + MultiByteToWideChar( dctx->codePage, 0, letters, -1, widebuf, VSIZE(widebuf) ); ceDrawTextClipped( hdc, widebuf, -1, XP_FALSE, fce, xprect->left+1, xprect->top+2, xprect->width, DT_CENTER ); @@ -1170,8 +1167,7 @@ drawDrawTileGuts( DrawCtx* p_dctx, const XP_Rect* xprect, if ( !!bitmaps || !!letters ) { HFONT oldFont = SelectObject( hdc, fce->setFont ); - XP_U16 len = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, - letters, -1, + XP_U16 len = MultiByteToWideChar( dctx->codePage, 0, letters, -1, widebuf, VSIZE(widebuf) ); /* see if there's room to use text instead of bitmap */ @@ -1460,7 +1456,7 @@ DRAW_FUNC_NAME(drawRemText)( DrawCtx* p_dctx, const XP_Rect* rInner, fce = ceGetSizedFont( dctx, 0, 0, RFONTS_REM ); oldFont = SelectObject( hdc, fce->setFont ); - ceDrawLinesClipped( hdc, fce, buf, XP_TRUE, &rt ); + ceDrawLinesClipped( hdc, fce, buf, CP_ACP, XP_TRUE, &rt ); (void)SelectObject( hdc, oldFont ); } /* ce_draw_drawRemText */ @@ -1580,7 +1576,7 @@ DRAW_FUNC_NAME(score_drawPlayer)( DrawCtx* p_dctx, rt.bottom -= IS_TURN_VPAD; } - ceDrawLinesClipped( hdc, fce, buf, XP_TRUE, &rt ); + ceDrawLinesClipped( hdc, fce, buf, CP_ACP, XP_TRUE, &rt ); SelectObject( hdc, oldFont ); } /* ce_draw_score_drawPlayer */ @@ -1674,7 +1670,7 @@ DRAW_FUNC_NAME(drawTimer)( DrawCtx* p_dctx, const XP_Rect* rInner, oldFont = SelectObject( hdc, fce->setFont ); ++rt.top; - ceDrawLinesClipped( hdc, fce, buf, XP_TRUE, &rt ); + ceDrawLinesClipped( hdc, fce, buf, CP_ACP, XP_TRUE, &rt ); SelectObject( hdc, oldFont ); if ( !globals->hdc ) { @@ -1812,6 +1808,7 @@ DRAW_FUNC_NAME(dictChanged)( DrawCtx* p_dctx, const DictionaryCtxt* dict ) ceClearFontCache( dctx ); } dctx->dict = dict; + dctx->codePage = dict_isUTF8(dict)? CP_UTF8 : CP_ACP; } #ifdef DRAW_LINK_DIRECT diff --git a/xwords4/wince/cemain.c b/xwords4/wince/cemain.c index 607a7d941..0b1a725de 100755 --- a/xwords4/wince/cemain.c +++ b/xwords4/wince/cemain.c @@ -1,4 +1,4 @@ -/* -*- fill-column: 77; compile-command: "make -j TARGET_OS=wince DEBUG=TRUE" -*- */ +/* -*- fill-column: 77; compile-command: "make -j2 TARGET_OS=wince DEBUG=TRUE" -*- */ /* * Copyright 2002-2009 by Eric House (xwords@eehouse.org). All rights * reserved. @@ -2654,7 +2654,8 @@ messageBoxStream( CEAppGlobals* globals, XWStreamCtxt* stream, wchar_t* title, XP_UCHAR* buf = ceStreamToStrBuf( MPPARM(globals->mpool) stream ); int result; - result = ceMessageBoxChar( globals, buf, title, buttons ); + result = ceMessageBoxChar( globals, buf, ceCurDictIsUTF8(globals), + title, buttons ); XP_FREE( globals->mpool, buf ); return result; @@ -3259,69 +3260,69 @@ ce_util_getUserString( XW_UtilCtxt* XP_UNUSED(uc), XP_U16 stringCode ) { switch( stringCode ) { case STRD_REMAINING_TILES_ADD: - return (XP_UCHAR*)"+ %d [all remaining tiles]"; + return "+ %d [all remaining tiles]"; case STRD_UNUSED_TILES_SUB: - return (XP_UCHAR*)"- %d [unused tiles]"; + return "- %d [unused tiles]"; case STR_BONUS_ALL: - return (XP_UCHAR*)"Bonus for using all tiles: 50" XP_CR; + return "Bonus for using all tiles: 50" XP_CR; case STRD_TURN_SCORE: - return (XP_UCHAR*)"Score for turn: %d" XP_CR; + return "Score for turn: %d" XP_CR; case STR_COMMIT_CONFIRM: - return (XP_UCHAR*)"Commit the current move?" XP_CR; + return "Commit the current move?" XP_CR; case STR_LOCAL_NAME: - return (XP_UCHAR*)"%s"; + return "%s"; case STR_NONLOCAL_NAME: - return (XP_UCHAR*)"%s (remote)"; + return "%s (remote)"; case STRD_TIME_PENALTY_SUB: - return (XP_UCHAR*)" - %d [time]"; + return " - %d [time]"; case STRD_CUMULATIVE_SCORE: - return (XP_UCHAR*)"Cumulative score: %d" XP_CR; + return "Cumulative score: %d" XP_CR; case STRS_MOVE_ACROSS: - return (XP_UCHAR*)"move (from %s across)" XP_CR; + return "move (from %s across)" XP_CR; case STRS_MOVE_DOWN: - return (XP_UCHAR*)"move (from %s down)" XP_CR; + return "move (from %s down)" XP_CR; case STRS_TRAY_AT_START: - return (XP_UCHAR*)"Tray at start: %s" XP_CR; + return "Tray at start: %s" XP_CR; case STRS_NEW_TILES: - return (XP_UCHAR*)"New tiles: %s" XP_CR; + return "New tiles: %s" XP_CR; case STRSS_TRADED_FOR: - return (XP_UCHAR*)"Traded %s for %s."; + return "Traded %s for %s."; case STR_PASS: - return (XP_UCHAR*)"pass" XP_CR; + return "pass" XP_CR; case STR_PHONY_REJECTED: - return (XP_UCHAR*)"Illegal word in move; turn lost!" XP_CR; + return "Illegal word in move; turn lost!" XP_CR; case STRD_ROBOT_TRADED: - return (XP_UCHAR*)"Robot traded tiles %d this turn."; + return "Robot traded tiles %d this turn."; case STR_ROBOT_MOVED: - return (XP_UCHAR*)"The robot made this move:" XP_CR; + return "The robot made this move:" XP_CR; case STR_REMOTE_MOVED: - return (XP_UCHAR*)"Remote player made this move:" XP_CR; + return "Remote player made this move:" XP_CR; case STR_PASSED: - return (XP_UCHAR*)"Passed"; + return "Passed"; case STRSD_SUMMARYSCORED: - return (XP_UCHAR*)"%s:%d"; + return "%s:%d"; case STRD_TRADED: - return (XP_UCHAR*)"Traded %d"; + return "Traded %d"; case STR_LOSTTURN: - return (XP_UCHAR*)"Lost turn"; + return "Lost turn"; #ifndef XWFEATURE_STANDALONE_ONLY case STR_LOCALPLAYERS: - return (XP_UCHAR*)"Locl playrs:"; + return "Locl playrs:"; #endif case STR_TOTALPLAYERS: - return (XP_UCHAR*)"Player count:"; + return "Player count:"; case STRS_VALUES_HEADER: - return (XP_UCHAR*)"%s counts/values:" XP_CR; + return "%s counts/values:" XP_CR; default: XP_LOGF( "stringCode=%d", stringCode ); - return (XP_UCHAR*)"unknown code"; + return "unknown code"; } } /* ce_util_getUserString */ @@ -3357,7 +3358,8 @@ ce_util_warnIllegalWord( XW_UtilCtxt* uc, BadWordInfo* bwi, sprintf( msgBuf, "Word[s] %s not found in dictionary.", wordsBuf ); if ( turnLost ) { - ceMessageBoxChar( globals, msgBuf, L"Illegal word", + XP_Bool isUTF8 = ceCurDictIsUTF8( globals ); + ceMessageBoxChar( globals, msgBuf, isUTF8, L"Illegal word", MB_OK | MB_ICONHAND ); isOk = XP_TRUE; } else { diff --git a/xwords4/wince/ceprefs.c b/xwords4/wince/ceprefs.c index 94da0221e..2890a36f3 100755 --- a/xwords4/wince/ceprefs.c +++ b/xwords4/wince/ceprefs.c @@ -335,7 +335,8 @@ PrefsDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) if ( IS_SMARTPHONE(globals) ) { ceMessageBoxChar( globals, "This feature " "requires a touch screen.", - L"Sorry", MB_OK | MB_ICONHAND ); + XP_FALSE, L"Sorry", + MB_OK | MB_ICONHAND ); ceSetChecked( hDlg, IDC_CHECKHINTSLIMITS, XP_FALSE ); } break; diff --git a/xwords4/wince/cestrbx.c b/xwords4/wince/cestrbx.c index d53853a70..4a24f86a5 100755 --- a/xwords4/wince/cestrbx.c +++ b/xwords4/wince/cestrbx.c @@ -28,9 +28,8 @@ stuffTextInField( HWND hDlg, StrBoxState* state ) XP_U16 len, crlen; XP_UCHAR* sbuf; wchar_t* wbuf; -#ifdef MEM_DEBUG CEAppGlobals* globals = state->dlgHdr.globals; -#endif + UINT codePage = ceCurDictIsUTF8(globals)? CP_UTF8 : CP_ACP; sbuf = XP_MALLOC( globals->mpool, nBytes + 1 ); stream_getBytes( state->stream, sbuf, nBytes ); @@ -41,11 +40,9 @@ stuffTextInField( HWND hDlg, StrBoxState* state ) } sbuf[nBytes] = '\0'; - len = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sbuf, nBytes, - NULL, 0 ); + len = MultiByteToWideChar( codePage, 0, sbuf, nBytes, NULL, 0 ); wbuf = XP_MALLOC( globals->mpool, (len+1) * sizeof(*wbuf) ); - MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sbuf, nBytes, - wbuf, len ); + MultiByteToWideChar( codePage, 0, sbuf, nBytes, wbuf, len ); XP_FREE( globals->mpool, sbuf ); wbuf[len] = 0; diff --git a/xwords4/wince/ceutil.c b/xwords4/wince/ceutil.c index 98e00eb7a..f5c4650c1 100755 --- a/xwords4/wince/ceutil.c +++ b/xwords4/wince/ceutil.c @@ -881,17 +881,17 @@ ceGetPath( CEAppGlobals* globals, CePathType typ, int ceMessageBoxChar( CEAppGlobals* XP_UNUSED(globals), const XP_UCHAR* str, - const wchar_t* title, XP_U16 buttons ) + XP_Bool isUTF8, const wchar_t* title, XP_U16 buttons ) { HWND parent; /* Get the length required, then alloc and go. This is technically correct, but everywhere else I assume a 2:1 ratio for wchar_t:char. */ XP_U16 clen = 1 + strlen(str); - XP_U32 wlen = 1 + MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, str, - clen, NULL, 0 ); + UINT codePage = isUTF8? CP_UTF8:CP_ACP; + XP_U32 wlen = 1 + MultiByteToWideChar( codePage, 0, str, clen, NULL, 0 ); wchar_t widebuf[wlen]; - MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, str, clen, widebuf, wlen ); + MultiByteToWideChar( codePage, 0, str, clen, widebuf, wlen ); parent = GetForegroundWindow(); return MessageBox( parent, widebuf, title, buttons ); @@ -900,6 +900,21 @@ ceMessageBoxChar( CEAppGlobals* XP_UNUSED(globals), const XP_UCHAR* str, int ceOops( CEAppGlobals* globals, const XP_UCHAR* str ) { - return ceMessageBoxChar( globals, str, L"Oops!", + XP_Bool isUTF8 = ceCurDictIsUTF8( globals ); + return ceMessageBoxChar( globals, str, isUTF8, L"Oops!", MB_OK | MB_ICONHAND ); } + +XP_Bool +ceCurDictIsUTF8( CEAppGlobals* globals ) +{ + XP_Bool result = XP_FALSE; + const ModelCtxt* model = globals->game.model; + if ( !!model ) { + const DictionaryCtxt* dict = model_getDictionary( model ); + if ( !!dict ) { + result = dict_isUTF8( dict ); + } + } + return result; +} /* ceCurDictIsUTF8 */ diff --git a/xwords4/wince/ceutil.h b/xwords4/wince/ceutil.h index d7ac2e24b..fa050a5af 100755 --- a/xwords4/wince/ceutil.h +++ b/xwords4/wince/ceutil.h @@ -48,8 +48,9 @@ void ceGetItemRect( HWND hDlg, XP_U16 resID, RECT* rect ); void ceMoveItem( HWND hDlg, XP_U16 resID, XP_S16 byX, XP_S16 byY ); int ceMessageBoxChar( CEAppGlobals* globals, const XP_UCHAR* str, - const wchar_t* title, XP_U16 buttons ); + XP_Bool isUTF8, const wchar_t* title, XP_U16 buttons ); int ceOops( CEAppGlobals* globals, const XP_UCHAR* str ); +XP_Bool ceCurDictIsUTF8( CEAppGlobals* globals ); typedef enum { PREFS_FILE_PATH_L