diff --git a/ChangeLog.txt b/ChangeLog.txt index f038a74239..b17cd05eaa 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,16 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2013-06-21 14:58 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * contrib/gtqtc/gtqtc.h + * contrib/gtqtc/gtqtc1.cpp + * replaced harbour oriented code with dedicated QT solution + for XWindow synchronization and clipboard selection. + + * doc/xhb-diff.txt + * updated section MULTI THREAD SUPPORT to make it more clear + for users and added information about SETKEY() and GTs. + 2013-06-19 14:31 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * include/hbapigt.h * include/hbgtcore.h diff --git a/contrib/gtqtc/gtqtc.h b/contrib/gtqtc/gtqtc.h index c25ad0f238..9d00702213 100644 --- a/contrib/gtqtc/gtqtc.h +++ b/contrib/gtqtc/gtqtc.h @@ -53,6 +53,7 @@ #define HB_GT_NAME QTC #include +#include #include #include @@ -381,7 +382,7 @@ class QTCWindow : public QMainWindow public: QTCWindow( PHB_GTQTC pQTC ); - virtual ~QTCWindow(); + virtual ~QTCWindow( void ); QTConsole * qConsole; void setWindowSize( void ); diff --git a/contrib/gtqtc/gtqtc1.cpp b/contrib/gtqtc/gtqtc1.cpp index 1e8783144d..64998bcbb3 100644 --- a/contrib/gtqtc/gtqtc1.cpp +++ b/contrib/gtqtc/gtqtc1.cpp @@ -60,23 +60,16 @@ static HB_GT_FUNCS SuperTable; #if defined( HB_OS_UNIX ) # if !defined( HB_QT_NEEDLOCKS ) # define HB_QT_NEEDLOCKS +# endif +# if !defined( HB_XLIB_NEEDLOCKS ) /* # define HB_XLIB_NEEDLOCKS */ # endif #endif #ifdef HB_QT_NEEDLOCKS -# include "hbthread.h" - static HB_CRITICAL_NEW( s_qtcMtx ); - static HB_THREAD_NO s_thNO = 0; - static HB_THREAD_NO s_thCount = 0; -# define HB_QTC_LOCK() do { if( s_thNO != hb_threadNO() ) { \ - hb_threadEnterCriticalSection( &s_qtcMtx ); \ - s_thNO = hb_threadNO(); } \ - ++s_thCount -# define HB_QTC_UNLOCK() if( --s_thCount == 0 ) { \ - s_thNO = 0; \ - hb_threadLeaveCriticalSection( &s_qtcMtx ); } \ - } while( 0 ) + static QMutex s_qMtx( QMutex::Recursive ); +# define HB_QTC_LOCK() do { s_qMtx.lock() +# define HB_QTC_UNLOCK() s_qMtx.unlock(); } while( 0 ) #else # define HB_QTC_LOCK() do {} while( 0 ) # define HB_QTC_UNLOCK() do {} while( 0 ) @@ -1967,7 +1960,6 @@ static HB_BOOL hb_gt_qtc_Info( PHB_GT pGT, int iType, PHB_GT_INFO pInfo ) pInfo->pResult = hb_gt_qtc_itemPutQString( pInfo->pResult, pQTC->wndTitle ); if( pInfo->pNewVal && HB_IS_STRING( pInfo->pNewVal ) ) { - /* store font status for next operation on fontsize */ hb_gt_qtc_itemGetQString( pInfo->pNewVal, pQTC->wndTitle ); if( pQTC->qWnd ) pQTC->qWnd->setWindowTitle( *pQTC->wndTitle ); @@ -2637,20 +2629,15 @@ static QRect hb_gt_qtc_unmapRect( PHB_GTQTC pQTC, const QRect & rc ) void QTConsole::copySelection( void ) { const QRect rc = hb_gt_qtc_mapRect( pQTC, image, selectRect ); - HB_SIZE nSize, nEol, nI, nE; int iRow, iCol; - const char * pszEol; - QChar * pBuffer; + QString qStrEol( hb_conNewLine() ); + QString qStr( "" ); - pszEol = hb_conNewLine(); - nEol = strlen( pszEol ); - nSize = rc.height() * ( rc.width() + nEol ); - pBuffer = ( QChar * ) hb_xgrab( sizeof( QChar ) * nSize ); + qStr.reserve( rc.height() * ( rc.width() + qStrEol.size() ) ); selectMode = false; update( hb_gt_qtc_unmapRect( pQTC, rc ) ); - nI = 0; for( iRow = rc.top(); iRow <= rc.bottom(); ++iRow ) { for( iCol = rc.left(); iCol <= rc.right(); ++iCol ) @@ -2661,14 +2648,13 @@ void QTConsole::copySelection( void ) if( !HB_GTSELF_GETSCRCHAR( pQTC->pGT, iRow, iCol, &iColor, &bAttr, &usChar ) ) break; - pBuffer[ nI++ ] = usChar; + qStr += ( QChar ) usChar; } if( rc.height() > 1 ) - for( nE = 0; nE < nEol; ++nE ) - pBuffer[ nI++ ] = pszEol[ nE ]; + qStr += qStrEol; } - QApplication::clipboard()->setText( QString( pBuffer, nI ) ); - hb_xfree( pBuffer ); + + QApplication::clipboard()->setText( qStr ); } void QTConsole::repaintChars( const QRect & rx ) diff --git a/doc/xhb-diff.txt b/doc/xhb-diff.txt index d5e0a58151..37479226f6 100644 --- a/doc/xhb-diff.txt +++ b/doc/xhb-diff.txt @@ -2037,14 +2037,13 @@ Most of core code had been rewritten to be reentrant safe so it does not have to be protected by any mutexes what greatly helps in scalability. Below is a short description which shows which resources are thread local which ones are shared and how they are initialized: - Thread attributes inherited from parent thread: + Thread local attributes inherited from parent thread: - code page - language - SETs - default RDD - - active GT driver/console window - I18N translation set - Thread attributes initialized to default value: + Thread local attributes initialized to default value: - public variable GetList := {} (of course if public variables are not shared with parent thread). @@ -2055,6 +2054,13 @@ are thread local which ones are shared and how they are initialized: - RDDI_* settings in core RDDs (some 3-rd party RDDs may use global settings) - thread static variables + - SETKEY() are reset to empty array (Clipper compatible automatic + binding between F1 key and HELP() if such function/procedure was + registered in HVM is done only for main thread). + Other thread local resources: + - memvar (public and private) variables (except the ones which + are shared with parent threads) + - work areas Resources which can be shared or copied form parent to child thread on user request when thread is created: - public variables @@ -2066,13 +2072,16 @@ are thread local which ones are shared and how they are initialized: - GT drivers - lang modules - codepage modules - Global resources: + - active GT driver/console window (by default GT is inherited + from parent thread so also all GT internal settings are shared + between threads using the same GT anyhow each thread can create + new GT and set it as its own GT driver - such functionality is + available only in this GTs which can use independent system + resources for input and output, i.e. separate windows in GUI + GTs like GTWVT, GTXWC, GTQTC or input/output handles in terminal + stream GTs like GTCGI, GTSTD, GTTRM). + Other global resources: - .prg static variables (Harbour core code does not use them) - Thread local resources: - - memvar (public and private) variables (except the ones which - are shared with parent threads) - - work areas - - thread static variables In practice the only one not synced automatically element in Harbour is write access to the same item with complex variable. This part have to be synced by user and automatic synchronization here will