From c8e91323cd7dde9c839627c8005d2e55f898c7a6 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Mon, 4 Jan 2010 12:11:08 +0000 Subject: [PATCH] 2010-01-04 13:10 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/src/rtl/gtxwc/gtxwc.c ! cleaned a little bit hack with euro sign support + added optional support for input respecting locale settings To enable it it's necessary to recompile GTXWC with HB_XWC_USE_LOCALE macro. It can be done globally using export UH_USER_CFLAGS=-DHB_XWC_USE_LOCALE and recompiling Harbour core code. When enabled GTXWC initialize locale at startup (LC_CTYPE only) what enable national keyboard layout support in default input context (XLookupString()). Current Harbour core code does not use any functions so enabling locale should not effect user national settings in HVM. Please test. --- harbour/ChangeLog | 15 +++++ harbour/src/rtl/gtxwc/gtxwc.c | 102 ++++++++++++++++++++++++---------- 2 files changed, 87 insertions(+), 30 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 9445774b85..02ecc928ae 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,21 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-01-04 13:10 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/src/rtl/gtxwc/gtxwc.c + ! cleaned a little bit hack with euro sign support + + added optional support for input respecting locale settings + To enable it it's necessary to recompile GTXWC with HB_XWC_USE_LOCALE + macro. It can be done globally using + export UH_USER_CFLAGS=-DHB_XWC_USE_LOCALE + and recompiling Harbour core code. + When enabled GTXWC initialize locale at startup (LC_CTYPE only) what + enable national keyboard layout support in default input context + (XLookupString()). Current Harbour core code does not use any + functions so enabling locale should not effect user + national settings in HVM. + Please test. + 2010-01-04 01:58 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) * contrib/hbide/hbide.hbp * contrib/hbide/hbide.prg diff --git a/harbour/src/rtl/gtxwc/gtxwc.c b/harbour/src/rtl/gtxwc/gtxwc.c index 172dc7fdcb..3049e773ca 100644 --- a/harbour/src/rtl/gtxwc/gtxwc.c +++ b/harbour/src/rtl/gtxwc/gtxwc.c @@ -55,7 +55,12 @@ /* NOTE: User programs should never call this layer directly! */ /* #define XWC_DEBUG */ +/* #define HB_XWC_USE_LOCALE */ + #include "gtxwc.h" +#ifdef HB_XWC_USE_LOCALE +# include +#endif static int s_GtId; static HB_GT_FUNCS SuperTable; @@ -340,6 +345,8 @@ typedef struct tag_x_wnddef using build in font ones */ BOOL fDrawBox; + /* locale set to UTF-8 */ + BOOL fUTF8; /* CodePage support */ PHB_CODEPAGE hostCDP; /* PHB_CODEPAGE outCDP; */ @@ -368,13 +375,13 @@ typedef struct tag_x_wnddef int mouseGotoRow; int mouseNumButtons; int mouseButtonsState; - BYTE mouseButtonsMap[XWC_MAX_BUTTONS]; + unsigned char mouseButtonsMap[XWC_MAX_BUTTONS]; Time mouseButtonsTime[XWC_MAX_BUTTONS]; /* current screen contents (attr<<24)|(color<<16)|char */ ULONG *pCurrScr; - /* character translation table, it changes BYTES in screen buffer into UNICODE or graphs primitives */ + /* character translation table, it changes characters in screen buffer into UNICODE or graphs primitives */ XWC_CharTrans charTrans[256]; BOOL fInvalidChr; @@ -1537,7 +1544,7 @@ static void hb_gt_xwc_BuildCharTrans( PXWND_DEF wnd ) for( i = 0; i < 256; i++ ) { - usCh16 = hb_cdpGetU16( wnd->hostCDP, TRUE, ( BYTE ) i ); + usCh16 = hb_cdpGetU16( wnd->hostCDP, TRUE, ( unsigned char ) i ); wnd->charTrans[ i ].type = CH_CHAR; wnd->charTrans[ i ].u.ch16 = usCh16; @@ -1668,8 +1675,8 @@ static void hb_gt_xwc_TranslateKey( PXWND_DEF wnd, int key ) static void hb_gt_xwc_ProcessKey( PXWND_DEF wnd, XKeyEvent *evt) { - unsigned char buf[5]; - KeySym outISO, out = XLookupKeysym( evt, 0 ); + unsigned char buf[ 16 ]; + KeySym outISO = 0, out = XLookupKeysym( evt, 0 ); int ikey = 0, n, i; #ifdef XWC_DEBUG @@ -1809,27 +1816,37 @@ static void hb_gt_xwc_ProcessKey( PXWND_DEF wnd, XKeyEvent *evt) we not check all modifiers in all possible keyboards */ if( ( n = XLookupString( evt, ( char * ) buf, sizeof(buf), &outISO, NULL ) ) <= 0 ) { +#ifndef HB_XWC_USE_LOCALE /* * This is a temporary hack for Latin-x input see gt_SetKeyCP */ if( outISO >= 0x0100 && outISO <= 0x0fff && ( outISO & 0x80 ) == 0x80 ) { - buf[0] = (BYTE) (outISO & 0xff); + buf[0] = ( unsigned char ) ( outISO & 0xff ); n = 1; } - if ( outISO == 0x20ac ) + /* hack for euro sign */ + else if( outISO == 0x20ac ) { - buf[0] = (BYTE) 0x80; - n = 1; + ikey = hb_cdpGetChar( wnd->hostCDP, FALSE, ( HB_WCHAR ) outISO ); + hb_gt_xwc_AddCharToInputQueue( wnd, ikey ); + return; } +#endif } + if( n > 0 ) { unsigned char keystr[ 32 ]; ULONG u = sizeof( keystr ); +#ifndef HB_XWC_USE_LOCALE hb_cdpnDup2( ( const char * ) buf, n, ( char * ) keystr, &u, wnd->inCDP, wnd->hostCDP ); +#else + hb_cdpnDup2( ( const char * ) buf, n, ( char * ) keystr, &u, + wnd->fUTF8 ? wnd->utf8CDP : wnd->inCDP, wnd->hostCDP ); +#endif n = ( int ) u; #ifdef XWC_DEBUG @@ -1901,9 +1918,7 @@ static void hb_gt_xwc_ProcessKey( PXWND_DEF wnd, XKeyEvent *evt) break; } if( ikey ) - { hb_gt_xwc_TranslateKey( wnd, ikey ); - } } /* *********************************************************************** */ @@ -2287,7 +2302,7 @@ static void hb_gt_xwc_WndProc( PXWND_DEF wnd, XEvent *evt ) static int hb_gt_xwc_GetColormapSize( PXWND_DEF wnd ) { XVisualInfo visInfo, *visInfoPtr; - int uiCMapSize = -1, nItems; + int iCMapSize = -1, nItems; visInfo.visualid = XVisualIDFromVisual( DefaultVisual( wnd->dpy, DefaultScreen( wnd->dpy ) ) ); @@ -2295,11 +2310,11 @@ static int hb_gt_xwc_GetColormapSize( PXWND_DEF wnd ) &visInfo, &nItems); if( nItems >= 1 ) { - uiCMapSize = visInfoPtr->colormap_size; + iCMapSize = visInfoPtr->colormap_size; } XFree( ( char * ) visInfoPtr ); - return uiCMapSize; + return iCMapSize; } /* *********************************************************************** */ @@ -2307,14 +2322,14 @@ static int hb_gt_xwc_GetColormapSize( PXWND_DEF wnd ) static BOOL hb_gt_xwc_AllocColor( PXWND_DEF wnd, XColor *pColor ) { BOOL fOK = FALSE; - int uiCMapSize; + int iCMapSize; if( XAllocColor( wnd->dpy, wnd->colorsmap, pColor ) != 0 ) { /* the exact color allocated */ fOK = TRUE; } - else if( ( uiCMapSize = hb_gt_xwc_GetColormapSize( wnd ) ) > 0 ) + else if( ( iCMapSize = hb_gt_xwc_GetColormapSize( wnd ) ) > 0 ) { /* try to find the best approximation of chosen color in * already allocated colors @@ -2322,23 +2337,23 @@ static BOOL hb_gt_xwc_AllocColor( PXWND_DEF wnd, XColor *pColor ) * Monish Shah's "find_closest_color()" for Vim 6.0, modified * with ideas from David Tong's "noflash" library ;-) */ - int i, uiClosestColor; + int i, iClosestColor; double dDiff, dDistance, dClosestColorDist = 0; XColor *colorTable; BYTE *checkTable; - colorTable = ( XColor * ) hb_xgrab( uiCMapSize * sizeof( XColor ) ); - checkTable = ( BYTE * ) hb_xgrab( uiCMapSize * sizeof( BYTE ) ); - for( i = 0; i < uiCMapSize; i++ ) + colorTable = ( XColor * ) hb_xgrab( iCMapSize * sizeof( XColor ) ); + checkTable = ( BYTE * ) hb_xgrab( iCMapSize * sizeof( BYTE ) ); + for( i = 0; i < iCMapSize; i++ ) { colorTable[i].pixel = (HB_GT_PIXELTYPE) i; checkTable[i] = FALSE; } - XQueryColors ( wnd->dpy, wnd->colorsmap, colorTable, uiCMapSize ); + XQueryColors ( wnd->dpy, wnd->colorsmap, colorTable, iCMapSize ); do { - uiClosestColor = -1; + iClosestColor = -1; /* * Look for the color that best approximates the desired one * and has not been checked so far and try to allocate it. @@ -2351,9 +2366,9 @@ static BOOL hb_gt_xwc_AllocColor( PXWND_DEF wnd, XColor *pColor ) * now we accept any valid color MAX_INT * MAX_INT * 3 < 1e20 */ dClosestColorDist = 1e20; - for( i = 0; i < uiCMapSize; i++ ) + for( i = 0; i < iCMapSize; i++ ) { - if( ! checkTable[uiClosestColor] ) + if( ! checkTable[iClosestColor] ) { /* * Use Euclidean distance in RGB space, weighted by Y (of YIQ) @@ -2368,23 +2383,23 @@ static BOOL hb_gt_xwc_AllocColor( PXWND_DEF wnd, XColor *pColor ) dDistance += dDiff * dDiff; if( dDistance < dClosestColorDist ) { - uiClosestColor = i; + iClosestColor = i; dClosestColorDist = dDistance; } } } - if( uiClosestColor > 0 ) + if( iClosestColor > 0 ) { - if( XAllocColor( wnd->dpy, wnd->colorsmap, &colorTable[uiClosestColor] ) != 0 ) + if( XAllocColor( wnd->dpy, wnd->colorsmap, &colorTable[iClosestColor] ) != 0 ) { - *pColor = colorTable[uiClosestColor]; + *pColor = colorTable[iClosestColor]; fOK = TRUE; break; } - checkTable[uiClosestColor] = TRUE; + checkTable[iClosestColor] = TRUE; } } - while( uiClosestColor > 0 ); + while( iClosestColor > 0 ); hb_xfree( colorTable ); hb_xfree( checkTable ); @@ -3166,6 +3181,28 @@ static void hb_gt_xwc_RequestSelection( PXWND_DEF wnd ) /* *********************************************************************** */ +static BOOL hb_gt_xwc_isUTF8( void ) +{ + BOOL fUTF8 = FALSE; + const char * szLang = getenv( "LANG" ); + + if( szLang ) + { + int i = ( int ) strlen( szLang ); + + if( i > 5 ) + { + fUTF8 = hb_stricmp( szLang + i - 5, ".UTF8" ) || + hb_stricmp( szLang + i - 6, ".UTF-8" ); + } + } + + return fUTF8; + +} + +/* *********************************************************************** */ + static PXWND_DEF hb_gt_xwc_CreateWndDef( PHB_GT pGT ) { PHB_FNAME pFileName; @@ -3182,6 +3219,7 @@ static PXWND_DEF hb_gt_xwc_CreateWndDef( PHB_GT pGT ) wnd->fResizable = TRUE; wnd->fClosable = TRUE; wnd->fWinResize = FALSE; + wnd->fUTF8 = hb_gt_xwc_isUTF8(); wnd->hostCDP = hb_vmCDP(); wnd->utf8CDP = hb_cdpFindExt( "UTF8" ); wnd->boxCDP = hb_cdpFind( "EN" ); @@ -3489,6 +3527,10 @@ static void hb_gt_xwc_Init( PHB_GT pGT, HB_FHANDLE hFilenoStdin, HB_FHANDLE hFil HB_TRACE(HB_TR_DEBUG, ("hb_gt_xwc_Init(%p,%p,%p,%p)", pGT, ( void * ) ( HB_PTRDIFF ) hFilenoStdin, ( void * ) ( HB_PTRDIFF ) hFilenoStdout, ( void * ) ( HB_PTRDIFF ) hFilenoStderr)); +#ifdef HB_XWC_USE_LOCALE + setlocale( LC_CTYPE, "" ); +#endif + HB_GTSUPER_INIT( pGT, hFilenoStdin, hFilenoStdout, hFilenoStderr ); #ifndef HB_XWC_XLIB_NEEDLOCKS