From a68eec838f885a4915ddae19cce17815ba927f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Czerpak?= Date: Mon, 17 Oct 2022 19:17:26 +0200 Subject: [PATCH] 2022-10-17 19:17 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * include/hbvm.h * include/harbour.hbx * src/harbour.def * src/vm/hvm.c + added new C function: extern HB_EXPORT HB_BOOL hb_vmSetKeyPool( HB_BOOL fEnable ); It allows to disable keyboard pooling by GT driver in main HVM loop. It's important in programs which mix GT terminal with GUI library which use common event loop. Many GUI objects are not reentrant safe and activating event loop during big changes may cause crash. Such things can happen in applications which try to mix HBQT and GTQTC. To avoid such problems before PRG code is called it's enough to disable keyboard pooling in main HVM loop, eg. if( hb_vmRequestReenter() ) { HB_BOOL fKeyPool = hb_vmSetKeyPool( HB_FALSE ); hb_vmPushEvalSym(); hb_vmPush( pBlockItm ); hb_vmSend( 0 ); hb_vmSetKeyPool( fKeyPool ); hb_vmRequestRestore(); } + added new PRG function: __vmKeyPool( [] ) -> It's PRG interface to above C function. If application uses GT driver and GUI library using the same event loop and such GUI library does not disable keyboard pooling in main HVM loop before PRG code is activated then it's enough to call this function at the beginning of application, eg. PROCEDURE INIT Clip() __vmKeyPool( .f. ) RETURN With above peace of code you can mix HBQT or other QT wrapper with GTQTC. --- ChangeLog.txt | 35 +++++++++++++++++++++++++++++++ include/harbour.hbx | 1 + include/hbvm.h | 2 ++ src/harbour.def | 2 ++ src/vm/hvm.c | 51 +++++++++++++++++++++++++++++++++++++-------- 5 files changed, 82 insertions(+), 9 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 4643587824..a5ea948ee5 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -414,6 +414,41 @@ 2016-07-04 19:01 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) https://github.com/harbour/core/commit/8465bce36bbfab6026673f1c597a91028f96079a +2022-10-17 19:17 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * include/hbvm.h + * include/harbour.hbx + * src/harbour.def + * src/vm/hvm.c + + added new C function: + extern HB_EXPORT HB_BOOL hb_vmSetKeyPool( HB_BOOL fEnable ); + It allows to disable keyboard pooling by GT driver in main HVM loop. + It's important in programs which mix GT terminal with GUI library + which use common event loop. Many GUI objects are not reentrant + safe and activating event loop during big changes may cause crash. + Such things can happen in applications which try to mix HBQT + and GTQTC. To avoid such problems before PRG code is called it's + enough to disable keyboard pooling in main HVM loop, eg. + if( hb_vmRequestReenter() ) + { + HB_BOOL fKeyPool = hb_vmSetKeyPool( HB_FALSE ); + hb_vmPushEvalSym(); + hb_vmPush( pBlockItm ); + hb_vmSend( 0 ); + hb_vmSetKeyPool( fKeyPool ); + hb_vmRequestRestore(); + } + + added new PRG function: + __vmKeyPool( [] ) -> + It's PRG interface to above C function. If application uses GT driver + and GUI library using the same event loop and such GUI library does not + disable keyboard pooling in main HVM loop before PRG code is activated + then it's enough to call this function at the beginning of application, + eg. + PROCEDURE INIT Clip() + __vmKeyPool( .f. ) + RETURN + With above peace of code you can mix HBQT or other QT wrapper with GTQTC. + 2019-12-03 11:42 UTC+0100 Maurizio la Cecilia (m.lacecilia/at/gmail.com) * ChangeLog.txt * restored UTF-8 encoding after previous wrong commit (Sorry!!!) diff --git a/include/harbour.hbx b/include/harbour.hbx index dbcd1ab2ff..ffc11a60fd 100644 --- a/include/harbour.hbx +++ b/include/harbour.hbx @@ -1605,6 +1605,7 @@ DYNAMIC __TypeFile DYNAMIC __vmCountThreads DYNAMIC __vmItemID DYNAMIC __vmItemRefs +DYNAMIC __vmKeyPool DYNAMIC __vmModulesVerify DYNAMIC __vmNoInternals DYNAMIC __Wait diff --git a/include/hbvm.h b/include/hbvm.h index 64941c55e3..a44c788a65 100644 --- a/include/hbvm.h +++ b/include/hbvm.h @@ -130,6 +130,8 @@ extern HB_EXPORT HB_BOOL hb_vmTryEval( PHB_ITEM * pResult, PHB_ITEM pItem, HB_ extern HB_EXPORT HB_BOOL hb_vmIsActive( void ); extern HB_EXPORT HB_BOOL hb_vmIsReady( void ); +extern HB_EXPORT HB_BOOL hb_vmSetKeyPool( HB_BOOL fEnable ); + /* Return values of hb_vmRequestQuery() */ #define HB_QUIT_REQUESTED 1 /* immediately quit the application */ #define HB_BREAK_REQUESTED 2 /* break to nearest RECOVER/END sequence */ diff --git a/src/harbour.def b/src/harbour.def index 97e2eb5378..8a0d118ff2 100644 --- a/src/harbour.def +++ b/src/harbour.def @@ -1936,6 +1936,7 @@ HB_FUN___TYPEFILE HB_FUN___VMCOUNTTHREADS HB_FUN___VMITEMID HB_FUN___VMITEMREFS +HB_FUN___VMKEYPOOL HB_FUN___VMMODULESVERIFY HB_FUN___VMNOINTERNALS HB_FUN___WAIT @@ -3581,6 +3582,7 @@ hb_vmResumeThreads hb_vmSend hb_vmSetCDP hb_vmSetDefaultGT +hb_vmSetKeyPool hb_vmSetLang hb_vmSetLinkedMain hb_vmSuspendThreads diff --git a/src/vm/hvm.c b/src/vm/hvm.c index fcf29600e0..fd9a73369f 100644 --- a/src/vm/hvm.c +++ b/src/vm/hvm.c @@ -254,6 +254,10 @@ static HB_ULONG s_ulFreeSymbols = 0;/* number of free module symbols */ static void * s_hDynLibID = NULL; /* unique identifier to mark symbol tables loaded from dynamic libraries */ static HB_BOOL s_fCloneSym = HB_FALSE;/* clone registered symbol tables */ +#ifndef HB_GUI +HB_BOOL s_fKeyPool = HB_TRUE; +#endif + /* main VM thread stack ID */ static void * s_main_thread = NULL; @@ -1328,7 +1332,7 @@ void hb_vmExecute( const HB_BYTE * pCode, PHB_SYMB pSymbols ) HB_ULONG ulLastOpcode = 0; /* opcodes profiler support */ HB_ULONG ulPastClock = 0; /* opcodes profiler support */ #endif -#if ! defined( HB_GUI ) +#ifndef HB_GUI int * piKeyPolls = hb_stackKeyPolls(); #endif @@ -1353,10 +1357,11 @@ void hb_vmExecute( const HB_BYTE * pCode, PHB_SYMB pSymbols ) } #endif -#if ! defined( HB_GUI ) +#ifndef HB_GUI if( ! --( *piKeyPolls ) ) { - hb_inkeyPoll(); + if( s_fKeyPool ) + hb_inkeyPoll(); *piKeyPolls = 65536; /* IMHO we should have a _SET_ controlled by user @@ -5953,8 +5958,9 @@ void hb_vmProc( HB_USHORT uiParams ) /* Poll the console keyboard */ #if 0 - #if ! defined( HB_GUI ) - hb_inkeyPoll(); + #ifndef HB_GUI + if( s_fKeyPool ) + hb_inkeyPoll(); #endif #endif @@ -6015,8 +6021,9 @@ void hb_vmDo( HB_USHORT uiParams ) /* Poll the console keyboard */ #if 0 - #if ! defined( HB_GUI ) - hb_inkeyPoll(); + #ifndef HB_GUI + if( s_fKeyPool ) + hb_inkeyPoll(); #endif #endif @@ -6106,8 +6113,9 @@ void hb_vmSend( HB_USHORT uiParams ) /* Poll the console keyboard */ #if 0 - #if ! defined( HB_GUI ) - hb_inkeyPoll(); + #ifndef HB_GUI + if( s_fKeyPool ) + hb_inkeyPoll(); #endif #endif @@ -12397,6 +12405,31 @@ HB_FUNC( __QUITCANCEL ) } } +HB_BOOL hb_vmSetKeyPool( HB_BOOL fEnable ) +{ +#ifndef HB_GUI + HB_BOOL fPrev = s_fKeyPool; + s_fKeyPool = fEnable; + return fPrev; +#else + HB_SYMBOL_UNUSED( fEnable ); + return HB_FALSE; +#endif +} + +HB_FUNC( __VMKEYPOOL ) +{ + HB_STACK_TLS_PRELOAD + +#ifndef HB_GUI + hb_retl( s_fKeyPool ); + if( HB_ISLOG( 1 ) ) + s_fKeyPool = hb_parl( 1 ); +#else + hb_retl( HB_FALSE ); +#endif +} + HB_FUNC( __VMNOINTERNALS ) { s_fInternalsEnabled = HB_FALSE;