diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 3701fed04e..ee9c5fca0c 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,115 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ * harbour/makefile.vc + * fixed to force max recurse preprocessor passed bigger then 0 + + * source/pp/ppcore.c + * suppressed memory access error in getExpReal + + added missing '.' in valid match markers (ConvertOptional) + +2006-03-11 09:45 UTC+0100 Ryszard Glab + * source/pp/ppcomp.c + * source/pp/ppcore.c + * source/rtl/gtcrs/gtcrs.c + * fixed to suppress warning messages in some compilers + +2006-03-10 21:15 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/config/rules.cf + * harbour/config/bsd/gcc.cf + * harbour/config/darwin/gcc.cf + * harbour/config/dos/bcc16.cf + * harbour/config/dos/djgpp.cf + * harbour/config/dos/owatcom.cf + * harbour/config/dos/rsx32.cf + * harbour/config/dos/watcom.cf + * harbour/config/linux/gcc.cf + * harbour/config/os2/gcc.cf + * harbour/config/os2/icc.cf + * harbour/config/sunos/gcc.cf + * harbour/config/w32/bcc32.cf + * harbour/config/w32/gcc.cf + * harbour/config/w32/global.cf + * harbour/config/w32/icc.cf + * harbour/config/w32/mingw32.cf + * harbour/config/w32/msvc.cf + * harbour/config/w32/rsxnt.cf + * harbour/config/w32/watcom.cf + * use F macro extension to extract file name from given macros. + It simplified some rules and allow to use vpath and differ file + locations in GNU Makefiles + * moved the BCC16 excpetion for C_RULE from global rules.cf to + DOS bcc16.cf file + * use mainstd library in MinGW build + + * harbour/include/hbapi.h + + added two new functions: hb_winmainArgInit() and hb_winmainArgGet() + to set/retrieve WinMain() parameters. + + added hb_strMatchWildExact() + + * harbour/source/pp/ppcore.c + * initialized variable to avoid compiler warning + + * harbour/source/rtl/console.c + * cleaned comment + + * harbour/source/rtl/hbffind.c + ! Fixed invalid handle error in Windows when file() fails + (fix borrowed from xHarbour) + + * harbour/source/rtl/strmatch.c + + added hb_strMatchWildExact() + + added 3-rd parameter to WildMatch() - when it's TRUE + WildMatch() will check if given pattern cover the whole string. + Without it it check if pattern is valid prefix only. + + * harbour/source/rtl/gtcrs/gtcrs.c + * harbour/source/rtl/gtcrs/gtcrs.h + * harbour/source/rtl/gtsln/mousesln.c + * do not call Gpm_GetSnapshot() to avoid stupid message on stderr + generated from GPM library - I lost the the hope that it will be + fixed ;-) + + * harbour/source/rtl/gtpca/gtpca.c + * use select() in *nixes for cursor position terminal feedback. + + * harbour/source/rtl/gtwin/gtwin.c + * try to always allocate console when compiled without + HB_NO_ALLOC_CONSOLE. It allow to use GTWIN also in real windows + programs. + + + harbour/source/rtl/gtwvt/Makefile + proc GTSYS() + + harbour/source/rtl/gtwvt/gtwvt.h + + added new GT driver GTWVT - the core of this driver it's Peter Ress + work in xHarbour. In Harbour GTWVT contains only pure GT code without + local to GTWVT xHarbour extensions and GTWVT contrib libraries. + This extensions can be added but later but I want to keep them + separated from the core GTWVT code and add them as upper level GT + which can inherit from GTWVT. Just like I've implemented CTWIN. + Please update non GNU make files and test this GT in Windows. + The programs which want to use GTWVT should be compiled as standard + Windows GUI programs. GTWVT replaces window console code. + hb* scripts does not have to use GTSYS() in source code but can simply + use -gt switch in hblnk and hbmk. + request HB_GT_WIN + request HB_GT_WVT + return + then the final binaries will be linked with both GT drivers and you + can switch between them using //gt[:] switch. F.e.: + ./my_prog //gtwin + or + ./my_prog //gtwvt + this feature works in all platforms. + People who works in shell environment (*nixes, MSYS, DJGPP) and use + hb* scripts does not have to use HB_GTSYS() in source code but can + simply use -gt switch in hblnk and hbmk. + + * harbour/source/rtl/gtxwc/gtxwc.c + * some minor cleanups and code formatting + + * harbour/source/vm/Makefile + + harbour/source/vm/mainstd/Makefile + * moved mainstd.c to separate mainstd library for MinGW32 build. Unfortunately MinGW always link main() function if it locate it in libraries and ignores WinMain() what effectively makes impossible to create Windows GUI programs if we have main() in diff --git a/harbour/config/bsd/gcc.cf b/harbour/config/bsd/gcc.cf index 399c7da812..ccbacc72ac 100644 --- a/harbour/config/bsd/gcc.cf +++ b/harbour/config/bsd/gcc.cf @@ -66,6 +66,6 @@ LDFLAGS += $(LINKPATHS) AR = ar ARFLAGS = $(A_USR) -AR_RULE = $(AR) $(ARFLAGS) r $@ $^ || $(RM) $@ +AR_RULE = $(AR) $(ARFLAGS) r $@ $(^F) || $(RM) $@ include $(TOP)$(ROOT)config/rules.cf diff --git a/harbour/config/darwin/gcc.cf b/harbour/config/darwin/gcc.cf index 37c5bf5d55..d1fc3f1bbf 100644 --- a/harbour/config/darwin/gcc.cf +++ b/harbour/config/darwin/gcc.cf @@ -99,13 +99,13 @@ endif LINKLIBS += -lm LDFLAGS = $(LINKPATHS) -LD_RULE = $(LD) $(CFLAGS) $(LD_OUT) $@ $^ $(LDFLAGS) $(L_USR) $(LINKLIBS) $(LINKLIBS) +LD_RULE = $(LD) $(CFLAGS) $(LD_OUT) $@ $(^F) $(LDFLAGS) $(L_USR) $(LINKLIBS) $(LINKLIBS) #AR = ar #ARFLAGS = $(A_USR) -#AR_RULE = $(AR) $(ARFLAGS) r $@ $^ || $(RM) $@ +#AR_RULE = $(AR) $(ARFLAGS) r $@ $(^F) || $(RM) $@ LIBTOOL = libtool LIBTOOLFLAGS = $(LIBTOOL_USR) -AR_RULE = $(LIBTOOL) -static $(LIBTOOLFLAGS) -o $@ $^ || $(RM) $@ +AR_RULE = $(LIBTOOL) -static $(LIBTOOLFLAGS) -o $@ $(^F) || $(RM) $@ RANLIB = ranlib include $(TOP)$(ROOT)config/rules.cf diff --git a/harbour/config/dos/bcc16.cf b/harbour/config/dos/bcc16.cf index f211866df2..836106ef5d 100644 --- a/harbour/config/dos/bcc16.cf +++ b/harbour/config/dos/bcc16.cf @@ -27,6 +27,10 @@ CC_OUT = -o CPPFLAGS = -I$($(HB_ARCHITECTURE)_$(HB_COMPILER)_GRANDP) -I$(_HB_INC_COMPILE) CFLAGS = -i48 -O2 -mh -d -DHB_LONG_LONG_OFF +# BCC (at least version 3.1) requires that the output file be listed ahead of the input file +CC_RULE = $(CC) $(CPPFLAGS) $(CFLAGS) $(C_USR) $(CC_OUT)$(?F:.c=$(OBJ_EXT)) $(CC_IN) $? + + #Note: The empty line below HAVE TO exist! define link_file echo. $(file) >> __link__.tmp @@ -36,7 +40,7 @@ endef define link_exe_file echo. $(LDFLAGS) -e$@ > __link__.tmp -$(foreach file, $^, $(link_file)) +$(foreach file, $(^F), $(link_file)) $(foreach file, $(LINKLIBS), $(link_file)) -$(LD) @__link__.tmp endef @@ -79,7 +83,7 @@ endef define create_library echo. $@ &> __lib__.tmp -$(foreach file, $^, $(lib_object)) +$(foreach file, $(^F), $(lib_object)) echo. ,, >> __lib__.tmp $(AR) $(ARFLAGS) @__lib__.tmp del __lib__.tmp diff --git a/harbour/config/dos/djgpp.cf b/harbour/config/dos/djgpp.cf index 01e84ad7e5..28d6997a74 100644 --- a/harbour/config/dos/djgpp.cf +++ b/harbour/config/dos/djgpp.cf @@ -58,7 +58,7 @@ endef # in commmand line define create_library echo. CREATE $@ > __lib__.tmp -$(foreach file, $^, $(lib_object)) +$(foreach file, $(^F), $(lib_object)) echo. SAVE >> __lib__.tmp echo. END >> __lib__.tmp $(AR) $(ARFLAGS) -M < __lib__.tmp @@ -72,7 +72,7 @@ endef define link_exe_file echo. $(LDFLAGS) $(L_USR) $(LD_OUT)$@ > __link__.tmp -$(foreach file, $^, $(link_file)) +$(foreach file, $(^F), $(link_file)) $(foreach file, $(LINKPATHS), $(link_file)) echo. -Wl,--start-group >> __link__.tmp $(foreach file, $(LINKLIBS), $(link_file)) diff --git a/harbour/config/dos/owatcom.cf b/harbour/config/dos/owatcom.cf index a92608037c..2e126a9ea7 100644 --- a/harbour/config/dos/owatcom.cf +++ b/harbour/config/dos/owatcom.cf @@ -56,7 +56,7 @@ endef define link_exe_file echo. $(LDFLAGS) NAME $@ > __link__.tmp -$(foreach file, $^, $(link_file)) +$(foreach file, $(^F), $(link_file)) $(foreach lib, $(HB_USER_LIBS), $(link_lib)) $(foreach lib, $(LINKLIBS), $(link_lib)) $(foreach lib, $(RDDLIBS), $(link_lib)) @@ -103,7 +103,7 @@ endef define create_library echo. $@ > __lib__.tmp -$(foreach file, $^, $(lib_object)) +$(foreach file, $(^F), $(lib_object)) $(AR) $(ARFLAGS) @__lib__.tmp endef diff --git a/harbour/config/dos/rsx32.cf b/harbour/config/dos/rsx32.cf index c93ed6d11b..60084f2469 100644 --- a/harbour/config/dos/rsx32.cf +++ b/harbour/config/dos/rsx32.cf @@ -65,6 +65,6 @@ LDFLAGS += $(LINKPATHS) AR = ar ARFLAGS = $(A_USR) -AR_RULE = $(AR) $(ARFLAGS) r $@ $^ || $(RM) $@ +AR_RULE = $(AR) $(ARFLAGS) r $@ $(^F) || $(RM) $@ include $(TOP)$(ROOT)config/rules.cf diff --git a/harbour/config/dos/watcom.cf b/harbour/config/dos/watcom.cf index 323557ef1c..e6c9783634 100644 --- a/harbour/config/dos/watcom.cf +++ b/harbour/config/dos/watcom.cf @@ -34,7 +34,7 @@ endef define link_exe_file $(COMSPEC) /E:2048 /Cecho $(LDFLAGS) NAME $@ > __link__.tmp -$(foreach file, $^, $(link_file)) +$(foreach file, $(^F), $(link_file)) $(foreach lib, $(LINKLIBS), $(link_lib)) $(foreach lib, $(RDDLIBS), $(link_lib)) $(foreach lib, $(GTLIBS), $(link_lib)) @@ -69,13 +69,12 @@ endef define create_library $(COMSPEC) /E:2048 /Cecho $@ > __lib__.tmp -$(foreach file, $^, $(lib_object)) +$(foreach file, $(^F), $(lib_object)) $(AR) $(ARFLAGS) @__lib__.tmp endef AR = wlib ARFLAGS = -p=32 -c $(A_USR) - AR_RULE = $(create_library) include $(TOP)$(ROOT)config/rules.cf diff --git a/harbour/config/linux/gcc.cf b/harbour/config/linux/gcc.cf index 0249565cfc..071e4fc43c 100644 --- a/harbour/config/linux/gcc.cf +++ b/harbour/config/linux/gcc.cf @@ -112,6 +112,6 @@ LDFLAGS = $(LINKPATHS) AR = ar ARFLAGS = $(A_USR) -AR_RULE = $(AR) $(ARFLAGS) cr $@ $^ || $(RM) $@ +AR_RULE = $(AR) $(ARFLAGS) cr $@ $(^F) || $(RM) $@ include $(TOP)$(ROOT)config/rules.cf diff --git a/harbour/config/os2/gcc.cf b/harbour/config/os2/gcc.cf index 7c3850921a..d6392130bd 100644 --- a/harbour/config/os2/gcc.cf +++ b/harbour/config/os2/gcc.cf @@ -80,7 +80,7 @@ LDFLAGS += $(LINKPATHS) ifeq ($(C_MAIN),) ifeq ($(HB_GT_LIB),os2pm) # Override the default link rule in order to add a call to emxbind -LD_RULE = $(LD) $(CFLAGS) $(LD_OUT)$@ $^ $(LDFLAGS) $(L_USR) $(LINKLIBS) & emxbind -ep $@ +LD_RULE = $(LD) $(CFLAGS) $(LD_OUT)$@ $(^F) $(LDFLAGS) $(L_USR) $(LINKLIBS) & emxbind -ep $@ endif endif @@ -96,7 +96,7 @@ endef define create_library IF EXIST $@ $(RM) $@ echo CREATE $@ > __lib__.tmp -$(foreach file, $^, $(lib_object)) +$(foreach file, $(^F), $(lib_object)) echo SAVE >> __lib__.tmp echo END >> __lib__.tmp $(AR) -M < __lib__.tmp diff --git a/harbour/config/os2/icc.cf b/harbour/config/os2/icc.cf index 0ce337c191..f1fdc99c3f 100644 --- a/harbour/config/os2/icc.cf +++ b/harbour/config/os2/icc.cf @@ -67,7 +67,7 @@ endif AR = ilib ARFLAGS = /NOE /NOIgnoreCase $(A_USR) -AROBJS = $(foreach file, $^, -+$(file)) +AROBJS = $(foreach file, $(^F), -+$(file)) AR_RULE = $(AR) $(ARFLAGS) $@ $(AROBJS),, include $(TOP)$(ROOT)config/rules.cf diff --git a/harbour/config/rules.cf b/harbour/config/rules.cf index c21cb0f91c..3a6563135c 100644 --- a/harbour/config/rules.cf +++ b/harbour/config/rules.cf @@ -25,9 +25,16 @@ HB_FLAGS = -n -q0 -w -es2 -gc0 -I$(TOP) -I$(HB_INC_COMPILE) # The rule to link an executable. ifeq ($(LD_RULE),) # Use default rule if architecture/compiler specific rule is not defined -LD_RULE = $(LD) $(CFLAGS) $(LD_OUT)$@ $^ $(LDFLAGS) $(L_USR) $(LINKLIBS) +LD_RULE = $(LD) $(CFLAGS) $(LD_OUT)$@ $(^F) $(LDFLAGS) $(L_USR) $(LINKLIBS) endif +# The rule to compile a C source file. +ifeq ($(CC_RULE),) +# Use default rule if architecture/compiler specific rule is not defined +CC_RULE = $(CC) $(CPPFLAGS) $(CFLAGS) $(C_USR) $(CC_IN) $? $(CC_OUT)$(?F:.c=$(OBJ_EXT)) +endif + + # Eliminate these rules. %.c : %.y @@ -42,24 +49,13 @@ ifeq ($(SOURCE_DIR),) SOURCE_DIR = $(GRANDP) endif -# BCC (at least version 3.1) requires that the output file be listed ahead of the input file -ifeq ($(CC),bcc) # Rule to generate an object file from a C source file in the parent. %$(OBJ_EXT) : $(SOURCE_DIR)%.c - $(CC) $(CPPFLAGS) $(CFLAGS) $(C_USR) $(CC_OUT)$(subst .c,$(OBJ_EXT),$(subst $(SOURCE_DIR),,$?)) $(CC_IN) $? + $(CC_RULE) # Rule to generate an object file from a C source file. %$(OBJ_EXT) : %.c - $(CC) $(CPPFLAGS) $(CFLAGS) $(C_USR) $(CC_OUT)$(?:.c=$(OBJ_EXT)) $(CC_IN) $? -else -# Rule to generate an object file from a C source file in the parent. -%$(OBJ_EXT) : $(SOURCE_DIR)%.c - $(CC) $(CPPFLAGS) $(CFLAGS) $(C_USR) $(CC_IN) $? $(CC_OUT)$(subst .c,$(OBJ_EXT),$(subst $(SOURCE_DIR),,$?)) - -# Rule to generate an object file from a C source file. -%$(OBJ_EXT) : %.c - $(CC) $(CPPFLAGS) $(CFLAGS) $(C_USR) $(CC_IN) $? $(CC_OUT)$(?:.c=$(OBJ_EXT)) -endif + $(CC_RULE) # Rule to generate an executable file from an object file. %$(EXE_EXT) : %$(OBJ_EXT) diff --git a/harbour/config/sunos/gcc.cf b/harbour/config/sunos/gcc.cf index 2f575abe71..0c64dc0d5e 100644 --- a/harbour/config/sunos/gcc.cf +++ b/harbour/config/sunos/gcc.cf @@ -91,6 +91,6 @@ LDFLAGS = $(LINKPATHS) AR = ar ARFLAGS = $(A_USR) -AR_RULE = $(AR) $(ARFLAGS) cr $@ $^ || $(RM) $@ +AR_RULE = $(AR) $(ARFLAGS) cr $@ $(^F) || $(RM) $@ include $(TOP)$(ROOT)config/rules.cf diff --git a/harbour/config/w32/bcc32.cf b/harbour/config/w32/bcc32.cf index be34ba269d..32c593116d 100644 --- a/harbour/config/w32/bcc32.cf +++ b/harbour/config/w32/bcc32.cf @@ -81,7 +81,7 @@ LDFLAGS = $(LINKPATHS) AR = tlib ARFLAGS = $(A_USR) -AROBJS = $(foreach file, $^, -+$(file)) +AROBJS = $(foreach file, $(^F), -+$(file)) AR_RULE = $(AR) $(ARFLAGS) $@ $(AROBJS),, include $(TOP)$(ROOT)config/rules.cf diff --git a/harbour/config/w32/gcc.cf b/harbour/config/w32/gcc.cf index 3979ba3881..84d8197bf3 100644 --- a/harbour/config/w32/gcc.cf +++ b/harbour/config/w32/gcc.cf @@ -79,6 +79,6 @@ LDFLAGS = $(LINKPATHS) AR = ar ARFLAGS = $(A_USR) -AR_RULE = $(AR) $(ARFLAGS) r $@ $^ || $(RM) $@ +AR_RULE = $(AR) $(ARFLAGS) r $@ $(^F) || $(RM) $@ include $(TOP)$(ROOT)config/rules.cf diff --git a/harbour/config/w32/global.cf b/harbour/config/w32/global.cf index 92f2a8371f..d65526df26 100644 --- a/harbour/config/w32/global.cf +++ b/harbour/config/w32/global.cf @@ -9,6 +9,7 @@ HB_GT_LIBS=\ gtpca \ gtstd \ gtwin \ + gtwvt \ # gtcrs \ # gtsln \ diff --git a/harbour/config/w32/icc.cf b/harbour/config/w32/icc.cf index 5f4c0e5f7a..82e54ab032 100644 --- a/harbour/config/w32/icc.cf +++ b/harbour/config/w32/icc.cf @@ -38,7 +38,7 @@ endef define link_exe_file echo $(LDFLAGS) -Fe$@ > __link__.tmp -$(foreach file, $^, $(link_file)) +$(foreach file, $(^F), $(link_file)) echo $(LINKLIBS) >> __link__.tmp -$(LD) @__link__.tmp endef @@ -57,7 +57,7 @@ endef define create_library echo $@ > __lib__.tmp -$(foreach file, $^, $(lib_object)) +$(foreach file, $(^F), $(lib_object)) $(AR) @__lib__.tmp del __lib__.tmp endef diff --git a/harbour/config/w32/mingw32.cf b/harbour/config/w32/mingw32.cf index 3c862af924..aa80a5e23e 100644 --- a/harbour/config/w32/mingw32.cf +++ b/harbour/config/w32/mingw32.cf @@ -42,6 +42,16 @@ LINKPATHS += $(foreach drv, $(HB_DB_DRIVERS), -L$(TOP)$(ROOT)source/rdd/$(drv)/$ LINKLIBS += $(foreach drv, $(HB_DB_DRIVERS), -l$(drv)) endif +# Add the standard C main() entry +ifeq ($(HB_MAIN),std) +ifeq ($(findstring vm,$(LIBS)),vm) +ifneq ($(HB_GT_LIB),gtwvt) +LINKPATHS += -L$(TOP)$(ROOT)source/vm/mainstd/$(HB_ARCH) +LINKLIBS += -lmainstd +endif +endif +endif + # Add the specified GT driver library ifeq ($(findstring rtl,$(LIBS)),rtl) LINKPATHS += -L$(TOP)$(ROOT)source/rtl/$(HB_GT_LIB)/$(HB_ARCH) @@ -87,7 +97,7 @@ endef # in commmand line define create_library echo. CREATE $@ > __lib__.tmp -$(foreach file, $^, $(lib_object)) +$(foreach file, $(^F), $(lib_object)) echo. SAVE >> __lib__.tmp echo. END >> __lib__.tmp $(AR) $(ARFLAGS) -M < __lib__.tmp @@ -101,7 +111,7 @@ endef define link_exe_file echo. $(LDFLAGS) $(L_USR) $(LD_OUT)$@ > __link__.tmp -$(foreach file, $^, $(link_file)) +$(foreach file, $(^F), $(link_file)) $(foreach file, $(LINKPATHS), $(link_file)) $(foreach file, $(LINKLIBS), $(link_file)) -$(LD) @__link__.tmp @@ -118,7 +128,7 @@ ifeq ($(SHLVL),) # COMMAND.COM - length of command line is limited AR_RULE = $(create_library) LD_RULE = $(link_exe_file) else -AR_RULE = $(AR) $(ARFLAGS) cr $@ $^ && $(RANLIB) $@ || $(RM) $@ +AR_RULE = $(AR) $(ARFLAGS) cr $@ $(^F) && $(RANLIB) $@ || $(RM) $@ endif include $(TOP)$(ROOT)config/rules.cf diff --git a/harbour/config/w32/msvc.cf b/harbour/config/w32/msvc.cf index b54ddbe44d..49c4d449f4 100644 --- a/harbour/config/w32/msvc.cf +++ b/harbour/config/w32/msvc.cf @@ -44,6 +44,6 @@ LDFLAGS = $(LINKPATHS) AR = lib.exe ARFLAGS = $(A_USR) -AR_RULE = $(AR) $(ARFLAGS) /out:$@ $^ || $(RM) $@ +AR_RULE = $(AR) $(ARFLAGS) /out:$@ $(^F) || $(RM) $@ include $(TOP)$(ROOT)config/rules.cf diff --git a/harbour/config/w32/rsxnt.cf b/harbour/config/w32/rsxnt.cf index e940bc2c89..c8b3895951 100644 --- a/harbour/config/w32/rsxnt.cf +++ b/harbour/config/w32/rsxnt.cf @@ -78,6 +78,6 @@ LDFLAGS += $(LINKPATHS) AR = ar ARFLAGS = $(A_USR) -AR_RULE = $(AR) $(ARFLAGS) r $@ $^ || $(RM) $@ +AR_RULE = $(AR) $(ARFLAGS) r $@ $(^F) || $(RM) $@ include $(TOP)$(ROOT)config/rules.cf diff --git a/harbour/config/w32/watcom.cf b/harbour/config/w32/watcom.cf index 1f4bae95ae..2dfb3a9134 100644 --- a/harbour/config/w32/watcom.cf +++ b/harbour/config/w32/watcom.cf @@ -41,7 +41,7 @@ endef define link_exe_file echo $(LDFLAGS) NAME $@ > __link__.tmp echo LIB kernel32.lib, user32.lib, winspool.lib, oleaut32.lib, uuid.lib >> __link__.tmp -$(foreach file, $^, $(link_file)) +$(foreach file, $(^F), $(link_file)) $(foreach lib, $(LINKLIBS), $(link_lib)) $(foreach lib, $(RDDLIBS), $(link_lib)) $(foreach lib, $(GTLIBS), $(link_lib)) @@ -80,7 +80,7 @@ endef define create_library echo $@ > __lib__.tmp -$(foreach file, $^, $(lib_object)) +$(foreach file, $(^F), $(lib_object)) $(AR) $(ARFLAGS) @__lib__.tmp endef diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index a12d29dd07..b185a46d49 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -487,7 +487,8 @@ extern HB_EXPORT BOOL hb_strToNum( const char* szNum, HB_LONG * plVal, doubl extern HB_EXPORT BOOL hb_strnToNum( const char* szNum, ULONG ulLen, HB_LONG * plVal, double * pdVal ); /* converts string to number, returns TRUE if results is double */ extern HB_EXPORT BOOL hb_strMatchRegExp( const char * szString, const char * szMask ); /* compare two strings using a regular expression pattern */ -extern HB_EXPORT BOOL hb_strMatchWild(const char *szString, const char *szPattern ); /* compare two strings using pattern with wildcard (?*) */ +extern HB_EXPORT BOOL hb_strMatchWild(const char *szString, const char *szPattern ); /* compare two strings using pattern with wildcard (?*) - patern have to be prefix of given string */ +extern HB_EXPORT BOOL hb_strMatchWildExact( const char *szString, const char *szPattern ); /* compare two strings using pattern with wildcard (?*) - patern have to cover whole string */ extern HB_EXPORT BOOL hb_strEmpty( const char * szText, ULONG ulLen ); /* returns whether a string contains only white space */ extern HB_EXPORT void hb_strDescend( char * szStringTo, const char * szStringFrom, ULONG ulLen ); /* copy a string to a buffer, inverting each character */ extern HB_EXPORT ULONG hb_strAt( const char * szSub, ULONG ulSubLen, const char * szText, ULONG ulLen ); /* returns an index to a sub-string within another string */ @@ -555,13 +556,17 @@ extern HB_EXPORT void hb_dynsymSetAreaHandle( PHB_DYNS pDynSym, int iArea ) /* Command line and environment argument management */ extern HB_EXPORT void hb_cmdargInit( int argc, char * argv[] ); /* initialize command line argument API's */ -extern int hb_cmdargARGC( void ); /* retrieve command line argument count */ -extern char ** hb_cmdargARGV( void ); /* retrieve command line argument buffer pointer */ -extern BOOL hb_cmdargIsInternal( const char * szArg ); /* determine if a string is an internal setting */ -extern BOOL hb_cmdargCheck( const char * pszName ); /* Check if a given internal switch (like //INFO) was set */ -extern char * hb_cmdargString( const char * pszName ); /* Returns the string value of an internal switch (like //TEMPPATH:"C:\") */ -extern int hb_cmdargNum( const char * pszName ); /* Returns the numeric value of an internal switch (like //F:90) */ -extern ULONG hb_cmdargProcessVM( int*, int* ); /* Check for command line internal arguments */ +extern int hb_cmdargARGC( void ); /* retrieve command line argument count */ +extern char ** hb_cmdargARGV( void ); /* retrieve command line argument buffer pointer */ +extern BOOL hb_cmdargIsInternal( const char * szArg ); /* determine if a string is an internal setting */ +extern BOOL hb_cmdargCheck( const char * pszName ); /* Check if a given internal switch (like //INFO) was set */ +extern char * hb_cmdargString( const char * pszName ); /* Returns the string value of an internal switch (like //TEMPPATH:"C:\") */ +extern int hb_cmdargNum( const char * pszName ); /* Returns the numeric value of an internal switch (like //F:90) */ +extern ULONG hb_cmdargProcessVM( int*, int* ); /* Check for command line internal arguments */ +#if defined( HB_OS_WIN_32 ) && defined( HB_OS_WIN_32_USED ) +extern HB_EXPORT void hb_winmainArgInit( HANDLE hInstance, HANDLE hPrevInstance, int iCmdShow ); /* Set WinMain() parameters */ +extern HB_EXPORT BOOL hb_winmainArgGet( HANDLE * phInstance, HANDLE * phPrevInstance, int * piCmdShow ); /* Retrieve WinMain() parameters */ +#endif /* Symbol management */ extern PHB_SYMB hb_symbolNew( char * szName ); /* create a new symbol */ diff --git a/harbour/source/pp/ppcore.c b/harbour/source/pp/ppcore.c index 0f7e7814f0..0aed3a5b5c 100644 --- a/harbour/source/pp/ppcore.c +++ b/harbour/source/pp/ppcore.c @@ -783,7 +783,7 @@ static int ParseIfdef( char * sLine, int usl ) { char defname[ MAX_NAME ]; DEFINES * stdef; - int len; + int len = 0; HB_TRACE(HB_TR_DEBUG, ("ParseIfdef(%s, %d)", sLine, usl)); diff --git a/harbour/source/rtl/console.c b/harbour/source/rtl/console.c index 1d0e6db906..0c6276db84 100644 --- a/harbour/source/rtl/console.c +++ b/harbour/source/rtl/console.c @@ -153,7 +153,7 @@ void hb_conRelease( void ) * have to be restored on exit then it should does it in its Exit() * method. Here we cannot force any actions because it may cause bad * results in some GTs, f.e. when the screen size is controlled by remote - * user and not xHarbour application (some terminal modes), [Druzus] + * user and not Harbour application (some terminal modes), [Druzus] */ hb_setkeyExit(); /* April White, May 6, 2000 */ diff --git a/harbour/source/rtl/gtcrs/gtcrs.c b/harbour/source/rtl/gtcrs/gtcrs.c index 06f3a28838..81b21c1e39 100644 --- a/harbour/source/rtl/gtcrs/gtcrs.c +++ b/harbour/source/rtl/gtcrs/gtcrs.c @@ -121,7 +121,7 @@ typedef struct InOutBase { char *acsc, *beep, *flash, *civis, *cnorm, *cvvis; - int is_mouse; + int mouse_type; int mButtons; int nTermMouseChars; unsigned char cTermMouseBuf[3]; @@ -1186,31 +1186,34 @@ static void flush_gpmevt( mouseEvent * mEvt ) } #endif +static void disp_mousecursor( InOutBase * ioBase ) +{ +#ifdef HAVE_GPM_H + if ( ioBase->mouse_type == MOUSE_GPM && gpm_visiblepointer ) + { + Gpm_DrawPointer( ioBase->mLastEvt.col, ioBase->mLastEvt.row, + gpm_consolefd ); + } +#endif +} + static void mouse_init( InOutBase * ioBase ) { if ( ioBase->terminal_type == TERM_XTERM ) { /* save old hilit tracking & enable mouse tracking */ write_ttyseq( ioBase, "\033[?1001s\033[?1002h" ); - ioBase->is_mouse = 1; + ioBase->mouse_type = MOUSE_XTERM; memset( ( void * ) &ioBase->mLastEvt, 0, sizeof( ioBase->mLastEvt ) ); ioBase->mLastEvt.click_delay = DBLCLK_DELAY; /* curses mouse buttons check */ ioBase->mButtons = tigetnum( "btns" ); if ( ioBase->mButtons < 1 ) - ioBase->mButtons = 2; + ioBase->mButtons = 3; } #ifdef HAVE_GPM_H else if ( ioBase->terminal_type == TERM_LINUX ) { -#ifdef HB_GPM_NOICE_DISABLE - int iNull, iErr; - - iErr = dup( 2 ); - iNull = open( "/dev/null", O_RDWR ); - dup2( iNull, 2 ); - close( iNull ); -#endif ioBase->Conn.eventMask = GPM_MOVE | GPM_DRAG | GPM_UP | GPM_DOWN | GPM_DOUBLE; /* give me move events but handle them anyway */ @@ -1218,43 +1221,47 @@ static void mouse_init( InOutBase * ioBase ) /* only pure mouse events, no Ctrl,Alt,Shft events */ ioBase->Conn.minMod = ioBase->Conn.maxMod = 0; gpm_zerobased = 1; - gpm_visiblepointer = 1; + gpm_visiblepointer = 0; if ( Gpm_Open( &ioBase->Conn, 0 ) >= 0 && gpm_fd >= 0 ) { - ioBase->is_mouse = 1; + int flags; + + if ( ( flags = fcntl( gpm_fd, F_GETFL, 0 ) ) != -1 ) + fcntl( gpm_fd, F_SETFL, flags | O_NONBLOCK ); + + ioBase->mouse_type = MOUSE_GPM; memset( ( void * ) &ioBase->mLastEvt, 0, sizeof( ioBase->mLastEvt ) ); ioBase->mLastEvt.click_delay = DBLCLK_DELAY; flush_gpmevt( &ioBase->mLastEvt ); add_efds( ioBase, gpm_fd, O_RDONLY, set_gpmevt, ( void * ) &ioBase->mLastEvt ); + + /* + * In recent GPM versions it produce unpleasure noice on the screen + * so I covered it with this macro, [druzus] + */ +#ifdef HB_GPM_USE_XTRA ioBase->mButtons = Gpm_GetSnapshot( NULL ); - if ( gpm_visiblepointer ) - Gpm_DrawPointer( ioBase->mLastEvt.col, ioBase->mLastEvt.row, - gpm_consolefd ); - } -#ifdef HB_GPM_NOICE_DISABLE - dup2( iErr, 2 ); - close( iErr ); +#else + ioBase->mButtons = 3; #endif + } } #endif } static void mouse_exit( InOutBase * ioBase ) { - if ( ioBase->terminal_type == TERM_XTERM ) + if ( ioBase->mouse_type == MOUSE_XTERM ) { /* disable mouse tracking & restore old hilit tracking */ write_ttyseq( ioBase, "\033[?1002l\033[?1001r" ); } #ifdef HAVE_GPM_H - else if ( ioBase->terminal_type == TERM_LINUX ) + else if ( ioBase->mouse_type == MOUSE_GPM && gpm_fd >= 0 ) { - if ( ioBase->is_mouse && gpm_fd >= 0 ) - { - del_efds( ioBase, gpm_fd ); - Gpm_Close(); - } + del_efds( ioBase, gpm_fd ); + Gpm_Close(); } #endif } @@ -1343,12 +1350,7 @@ static void gt_refresh( InOutBase * ioBase ) wmove( ioBase->stdscr, ioBase->row, ioBase->col ); wrefresh( ioBase->stdscr ); disp_cursor( ioBase ); -#ifdef HAVE_GPM_H - if ( ioBase->is_mouse && ioBase->terminal_type == TERM_LINUX ) - if ( gpm_visiblepointer ) - Gpm_DrawPointer( ioBase->mLastEvt.col, ioBase->mLastEvt.row, - gpm_consolefd ); -#endif + disp_mousecursor( ioBase ); } } @@ -2642,7 +2644,7 @@ static BOOL hb_gt_crs_mouse_IsPresent( void ) { HB_TRACE( HB_TR_DEBUG, ( "hb_gt_crs_mouse_IsPresent()" ) ); - return s_ioBase->is_mouse; + return s_ioBase->mouse_type != 0; } /* *********************************************************************** */ @@ -2652,13 +2654,10 @@ static void hb_gt_crs_mouse_Show( void ) HB_TRACE( HB_TR_DEBUG, ( "hb_gt_crs_mouse_Show()" ) ); #ifdef HAVE_GPM_H - if( s_ioBase->terminal_type == TERM_LINUX && s_ioBase->is_mouse ) - { + if( s_ioBase->mouse_type == MOUSE_GPM ) gpm_visiblepointer = 1; - Gpm_DrawPointer( s_ioBase->mLastEvt.col, s_ioBase->mLastEvt.row, - gpm_consolefd ); - } #endif + disp_mousecursor( s_ioBase ); } /* *********************************************************************** */ @@ -2668,7 +2667,7 @@ static void hb_gt_crs_mouse_Hide( void ) HB_TRACE( HB_TR_DEBUG, ( "hb_gt_crs_mouse_Hide()" ) ); #ifdef HAVE_GPM_H - if( s_ioBase->terminal_type == TERM_LINUX && s_ioBase->is_mouse ) + if( s_ioBase->mouse_type == MOUSE_GPM ) { gpm_visiblepointer = 0; } @@ -2694,11 +2693,7 @@ static void hb_gt_crs_mouse_SetPos( int iRow, int iCol ) /* it does really nothing */ s_ioBase->mLastEvt.col = iCol; s_ioBase->mLastEvt.row = iRow; -#ifdef HAVE_GPM_H - if( s_ioBase->terminal_type == TERM_LINUX && s_ioBase->is_mouse ) - if( gpm_visiblepointer ) - Gpm_DrawPointer( iCol, iRow, gpm_consolefd ); -#endif + disp_mousecursor( s_ioBase ); } /* *********************************************************************** */ @@ -2709,7 +2704,7 @@ static BOOL hb_gt_crs_mouse_ButtonState( int iButton ) HB_TRACE( HB_TR_DEBUG, ( "hb_gt_crs_mouse_ButtonState(%i)", iButton ) ); - if( s_ioBase->is_mouse ) + if( s_ioBase->mouse_type != 0 ) { int mask; diff --git a/harbour/source/rtl/gtcrs/gtcrs.h b/harbour/source/rtl/gtcrs/gtcrs.h index b390db3a92..884cb76ec3 100644 --- a/harbour/source/rtl/gtcrs/gtcrs.h +++ b/harbour/source/rtl/gtcrs/gtcrs.h @@ -144,9 +144,13 @@ extern int hb_gt_crs_chrmapinit( int *piTransTbl, char *pszTerm ); #define EVTFDSTAT_STOP 0x02 #define EVTFDSTAT_DEL 0x03 -#define CTRL_SEQ "\036" -#define ALT_SEQ "\037" -//#define NATION_SEQ "\016" +#define CTRL_SEQ "\036" +#define ALT_SEQ "\037" +/*#define NATION_SEQ "\016"*/ + +#define MOUSE_NONE 0 +#define MOUSE_GPM 1 +#define MOUSE_XTERM 2 #define K_UNDEF 0x10000 #define K_METAALT 0x10001 diff --git a/harbour/source/rtl/gtpca/gtpca.c b/harbour/source/rtl/gtpca/gtpca.c index 62604b079a..7f16113ea9 100644 --- a/harbour/source/rtl/gtpca/gtpca.c +++ b/harbour/source/rtl/gtpca/gtpca.c @@ -206,30 +206,73 @@ static void hb_gt_pca_AnsiSetAutoMargin( int iAM ) static void hb_gt_pca_AnsiGetCurPos( int * iRow, int * iCol ) { + static BOOL s_fIsAnswer = TRUE; + HB_TRACE(HB_TR_DEBUG, ("hb_gt_pca_AnsiGetCurPos(%p, %p)", iRow, iCol)); - if( s_bStdinConsole && s_bStdoutConsole ) + if( s_fIsAnswer && s_bStdinConsole && s_bStdoutConsole ) { - USHORT ch, value = 0, index = 0; - hb_gt_pca_termOut( ( BYTE * ) "\x1B[6n", 4 ); hb_gt_pca_termFlush(); - do +#ifdef OS_UNIX_COMPATIBLE { - ch = getc( stdin ); - if( isdigit( ch ) ) + char rdbuf[ 64 ]; + int i, n, y, x; + struct timeval tv; + fd_set rdfds; + + FD_ZERO( &rdfds ); + FD_SET( s_hFilenoStdin, &rdfds ); + tv.tv_sec = 2; + tv.tv_usec = 0; + + *iRow = *iCol = -1; + n = 0; + s_fIsAnswer = FALSE; + + while( select( s_hFilenoStdin + 1, &rdfds, NULL, NULL, &tv ) > 0 ) { - value = ( value * 10 ) + ( ch - '0' ); - } - else if( ch == ';' ) - { - *iRow = value - 1; - value = 0; + i = read( s_hFilenoStdin, rdbuf + n, sizeof( rdbuf ) - 1 - n ); + if( i <= 0 ) + break; + n += i; + if( n >= 6 ) + { + rdbuf[ n ] = '\0'; + if( sscanf( rdbuf, "\033[%d;%dR", &y, &x ) == 2 ) + { + *iRow = y; + *iCol = x; + s_fIsAnswer = TRUE; + break; + } + } } + if( !s_fIsAnswer ) + *iRow = *iCol = -1; } - while( ch != 'R' && index < 10 ); - *iCol = value - 1; +#else + { + USHORT ch, value = 0, index = 0; + do + { + ch = getc( stdin ); + if( isdigit( ch ) ) + { + value = ( value * 10 ) + ( ch - '0' ); + } + else if( ch == ';' ) + { + *iRow = value - 1; + value = 0; + } + } + while( ch != 'R' && index < 10 ); + *iCol = value - 1; + s_fIsAnswer = ch == 'R' && *iCol != -1 && *iRow != -1; + } +#endif } } diff --git a/harbour/source/rtl/gtsln/mousesln.c b/harbour/source/rtl/gtsln/mousesln.c index 476d0f57b5..ef64d0d5db 100644 --- a/harbour/source/rtl/gtsln/mousesln.c +++ b/harbour/source/rtl/gtsln/mousesln.c @@ -343,8 +343,8 @@ void hb_gt_sln_mouse_Init( void ) s_iMouseButtons = SLtt_tgetnum( "BT" ); /* force two buttons mouse under xterm */ - if( s_iMouseButtons == -1 ) - s_iMouseButtons = 2; + if( s_iMouseButtons < 1 ) + s_iMouseButtons = 3; s_bMousePresent = TRUE; } @@ -378,7 +378,15 @@ void hb_gt_sln_mouse_Init( void ) s_iMouseCol = Evt.x; } + /* + * In recent GPM versions it produce unpleasure noice on the screen + * so I covered it with this macro, [druzus] + */ +#ifdef HB_GPM_USE_XTRA s_iMouseButtons = Gpm_GetSnapshot( NULL ); +#else + s_iMouseButtons = 3; +#endif hb_gt_sln_mouse_FixTrash(); } #ifdef HB_GPM_NOICE_DISABLE diff --git a/harbour/source/rtl/gtwin/gtwin.c b/harbour/source/rtl/gtwin/gtwin.c index 83c0423b40..2effce1192 100644 --- a/harbour/source/rtl/gtwin/gtwin.c +++ b/harbour/source/rtl/gtwin/gtwin.c @@ -662,20 +662,18 @@ static void hb_gt_win_Init( FHANDLE hFilenoStdin, FHANDLE hFilenoStdout, FHANDLE if( ( s_HInput = GetStdHandle( STD_INPUT_HANDLE ) ) == INVALID_HANDLE_VALUE ) { -#ifdef HB_ALLOC_CONSOLE - AllocConsole(); /* It is a Windows app without a console, so we create one */ - s_HInput = GetStdHandle( STD_INPUT_HANDLE ); - if( s_HInput == INVALID_HANDLE_VALUE ) - { - hb_errInternal( 10001, "Can't allocate console", "", "" ); - } -#else - if( hb_dynsymFindName( "__DBGENTRY" ) ) /* the debugger is linked */ +#ifdef HB_NO_ALLOC_CONSOLE + /* allocate console only when debugger is linked */ + if( hb_dynsymFindName( "__DBGENTRY" ) ) +#endif { AllocConsole(); /* It is a Windows app without a console, so we create one */ s_HInput = GetStdHandle( STD_INPUT_HANDLE ); } -#endif + if( s_HInput == INVALID_HANDLE_VALUE ) + { + hb_errInternal( 10001, "Can't allocate console", "", "" ); + } } HB_GTSUPER_INIT( hFilenoStdin, hFilenoStdout, hFilenoStderr ); @@ -1558,7 +1556,7 @@ static void hb_gt_win_Tone( double dFrequency, double dDuration ) /* * According to the Clipper NG, the duration in 'ticks' is truncated to the - * interger portion ... Depending on the platform, xHarbour allows a finer + * interger portion ... Depending on the platform, Harbour allows a finer * resolution, but the minimum is 1 tick (for compatibility) */ /* Convert from ticks to seconds */ diff --git a/harbour/source/rtl/gtwvt/Makefile b/harbour/source/rtl/gtwvt/Makefile new file mode 100644 index 0000000000..8bbfec2d0c --- /dev/null +++ b/harbour/source/rtl/gtwvt/Makefile @@ -0,0 +1,12 @@ +# +# $Id$ +# + +ROOT = ../../../ + +C_SOURCES=\ + gtwvt.c \ + +LIBNAME=gtwvt + +include $(TOP)$(ROOT)config/lib.cf diff --git a/harbour/source/rtl/gtwvt/gtwvt.c b/harbour/source/rtl/gtwvt/gtwvt.c new file mode 100644 index 0000000000..a43152bfec --- /dev/null +++ b/harbour/source/rtl/gtwvt/gtwvt.c @@ -0,0 +1,2095 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Video subsystem for Win32 using GUI windows instead of Console + * Copyright 2003 Peter Rees + * Rees Software & Systems Ltd + * based on + * Bcc ConIO Video subsystem by + * Copyright 2002 Marek Paliwoda + * Copyright 2002 Przemyslaw Czerpak + * Video subsystem for Win32 compilers + * Copyright 1999-2000 Paul Tucker + * Copyright 2002 Przemysław Czerpak + * + * Copyright 2006 Przemyslaw Czerpak + * Adopted to new GT API + * + * The following parts are Copyright of the individual authors. + * www - http://www.harbour-project.org + * + * + * Copyright 1999 David G. Holm + * hb_gt_Tone() + * + * See doc/license.txt for licensing terms. + * + * www - http://www.harbour-project.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option ) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/ ). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +/* + * Individual authors: + * (C) 2003-2004 Giancarlo Niccolai + * Standard xplatform GT Info system, + * Graphical object system and event system. + * GTINFO() And GTO_* implementation. + * + * (C) 2004 Mauricio Abre + * Cross-GT, multiplatform Graphics API + * + */ + +#define HB_OS_WIN_32_USED + +#include "gtwvt.h" + +static HB_GT_FUNCS SuperTable; +#define HB_GTSUPER (&SuperTable) + +static TCHAR szAppName[] = TEXT( "Harbour WVT" ); + +static HANDLE s_hInstance; +static HANDLE s_hPrevInstance; +static int s_iCmdShow; + +static OSVERSIONINFO s_osv; + +static GLOBAL_DATA _s; + +static COLORREF _COLORS[] = { + BLACK, + BLUE, + GREEN, + CYAN, + RED, + MAGENTA, + BROWN, + WHITE, + LIGHT_GRAY, + BRIGHT_BLUE, + BRIGHT_GREEN, + BRIGHT_CYAN, + BRIGHT_RED, + BRIGHT_MAGENTA, + YELLOW, + BRIGHT_WHITE +}; + +static int K_Ctrl[] = +{ + K_CTRL_A, K_CTRL_B, K_CTRL_C, K_CTRL_D, K_CTRL_E, K_CTRL_F, K_CTRL_G, + K_CTRL_H, K_CTRL_I, K_CTRL_J, K_CTRL_K, K_CTRL_L, K_CTRL_M, K_CTRL_N, + K_CTRL_O, K_CTRL_P, K_CTRL_Q, K_CTRL_R, K_CTRL_S, K_CTRL_T, K_CTRL_U, + K_CTRL_V, K_CTRL_W, K_CTRL_X, K_CTRL_Y, K_CTRL_Z +}; + +static void hb_gt_wvt_InitStatics( void ) +{ + _s.ROWS = WVT_DEFAULT_ROWS; + _s.COLS = WVT_DEFAULT_COLS; + _s.foreground = WHITE; + _s.background = BLACK; + _s.CaretExist = FALSE; + _s.CaretSize = 4; + _s.mousePos.x = 0; + _s.mousePos.y = 0; + _s.MouseMove = TRUE; + _s.hWnd = NULL; + _s.keyPointerIn = 0; + _s.keyPointerOut = 0; + _s.keyLast = 0; + + /* THEESE are the default font parameters, if not changed by user */ + _s.PTEXTSIZE.x = 8; + _s.PTEXTSIZE.y = 12; + _s.fontHeight = 20; + _s.fontWidth = 10; + _s.fontWeight = FW_NORMAL; + _s.fontQuality = DEFAULT_QUALITY; + strcpy( _s.fontFace,"Courier New" ); + + _s.CentreWindow = TRUE; /* Default is to always display window in centre of screen */ + _s.CodePage = GetACP() ; /* Set code page to default system */ + + _s.Win9X = ( s_osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ); + _s.AltF4Close = FALSE; + + _s.fIgnoreWM_SYSCHAR = FALSE; +} + +static BOOL hb_gt_wvt_SetWindowSize( int iRow, int iCol ) +{ + if( HB_GTSUPER_RESIZE( iRow, iCol ) ) + { + _s.ROWS = ( USHORT ) iRow; + _s.COLS = ( USHORT ) iCol; + return TRUE; + } + + return FALSE; +} + +/* + * use the standard fixed oem font, unless the caller has requested set size fonts + */ +static HFONT hb_gt_wvt_GetFont( char * pszFace, int iHeight, int iWidth, int iWeight, int iQuality, int iCodePage ) +{ + HFONT hFont; + + if ( iHeight > 0 ) + { + LOGFONT logfont; + + logfont.lfEscapement = 0; + logfont.lfOrientation = 0; + logfont.lfWeight = iWeight ; + logfont.lfItalic = 0; + logfont.lfUnderline = 0; + logfont.lfStrikeOut = 0; + logfont.lfCharSet = iCodePage; /* OEM_CHARSET; */ + logfont.lfOutPrecision = 0; + logfont.lfClipPrecision = 0; + logfont.lfQuality = iQuality; /* DEFAULT_QUALITY, DRAFT_QUALITY or PROOF_QUALITY */ + logfont.lfPitchAndFamily = FIXED_PITCH+FF_MODERN; /* all mapping depends on fixed width fonts! */ + logfont.lfHeight = iHeight; + logfont.lfWidth = iWidth < 0 ? -iWidth : iWidth ; + + strcpy( logfont.lfFaceName,pszFace ); + + hFont = CreateFontIndirect( &logfont ); + } + else + { + /* hFont = GetStockObject( SYSTEM_FIXED_FONT ); */ + hFont = ( HFONT ) GetStockObject( OEM_FIXED_FONT ); + } + return hFont; +} + +static USHORT hb_gt_wvt_CalcPixelHeight( void ) +{ + return _s.PTEXTSIZE.y * _s.ROWS; +} + +static USHORT hb_gt_wvt_CalcPixelWidth( void ) +{ + return _s.PTEXTSIZE.x * _s.COLS; +} + +static void hb_gt_wvt_ResetWindowSize( HWND hWnd ) +{ + HDC hdc; + HFONT hFont, hOldFont ; + USHORT diffWidth, diffHeight; + USHORT height, width; + RECT wi, ci; + TEXTMETRIC tm; + RECT rcWorkArea; + int n; + + /* + * set the font and get it's size to determine the size of the client area + * for the required number of rows and columns + */ + hdc = GetDC( hWnd ); + hFont = hb_gt_wvt_GetFont( _s.fontFace, _s.fontHeight, _s.fontWidth, _s.fontWeight, _s.fontQuality, _s.CodePage ); + + if ( _s.hFont ) + { + DeleteObject( _s.hFont ); + } + + _s.hFont = hFont ; + hOldFont = ( HFONT ) SelectObject( hdc, hFont ); + GetTextMetrics( hdc, &tm ); + SetTextCharacterExtra( hdc,0 ); /* do not add extra char spacing even if bold */ + SelectObject( hdc, hOldFont ); + ReleaseDC( hWnd, hdc ); + + /* + * we will need to use the font size to handle the transformations from + * row column space in the future, so we keep it around in a static! + */ + + _s.PTEXTSIZE.x = _s.fontWidth < 0 ? -_s.fontWidth : + tm.tmAveCharWidth; /* For fixed FONT should == tm.tmMaxCharWidth */ + _s.PTEXTSIZE.y = tm.tmHeight; /* but seems to be a problem on Win9X so */ + /* assume proportional fonts always for Win9X */ + if ( _s.fontWidth < 0 || _s.Win9X || ( tm.tmPitchAndFamily & TMPF_FIXED_PITCH ) || ( _s.PTEXTSIZE.x != tm.tmMaxCharWidth ) ) + { + _s.FixedFont = FALSE; + } + else + { + _s.FixedFont = TRUE ; + } + + for( n = 0 ; n < _s.COLS ; n++ ) /* _s.FixedSize[] is used by ExtTextOut() to emulate */ + { /* fixed font when a proportional font is used */ + _s.FixedSize[ n ] = _s.PTEXTSIZE.x; + } + + /* resize the window to get the specified number of rows and columns */ + height = hb_gt_wvt_CalcPixelHeight(); + width = hb_gt_wvt_CalcPixelWidth(); + + GetWindowRect( hWnd, &wi ); + GetClientRect( hWnd, &ci ); + + diffWidth = ( SHORT )( ( wi.right - wi.left ) - ( ci.right ) ); + diffHeight = ( SHORT )( ( wi.bottom - wi.top ) - ( ci.bottom ) ); + width += diffWidth ; + height += diffHeight; + + /* + * Centre the window within the CLIENT area on the screen + * but only if _s.CentreWindow == TRUE + */ + if ( _s.CentreWindow && SystemParametersInfo( SPI_GETWORKAREA,0, &rcWorkArea, 0 ) ) + { + wi.left = rcWorkArea.left + ( ( ( rcWorkArea.right-rcWorkArea.left ) - ( width ) ) / 2 ) ; + wi.top = rcWorkArea.top + ( ( ( rcWorkArea.bottom-rcWorkArea.top ) - ( height ) ) / 2 ) ; + } + SetWindowPos( hWnd, NULL, wi.left, wi.top, width, height, SWP_NOZORDER ); +} + +static void HB_EXPORT hb_gt_wvt_SetWindowTitle( char * title ) +{ + SetWindowText( _s.hWnd, title ); +} + +static BOOL hb_gt_wvt_InitWindow( HWND hWnd, int iRow, int iCol ) +{ + BOOL fRet = hb_gt_wvt_SetWindowSize( iRow, iCol ); + + hb_gt_wvt_ResetWindowSize( hWnd ); + + return fRet; +} + +/* + * get the row and column from xy pixel client coordinates + * This works because we are using the FIXED system font + */ +static POINT hb_gt_wvt_GetColRowFromXY( USHORT x, USHORT y ) +{ + POINT colrow; + + colrow.x = ( x/_s.PTEXTSIZE.x ); + colrow.y = ( y/_s.PTEXTSIZE.y ); + + return colrow; +} + +static RECT hb_gt_wvt_GetColRowFromXYRect( RECT xy ) +{ + RECT colrow; + + colrow.left = ( xy.left / _s.PTEXTSIZE.x ); + colrow.top = ( xy.top / _s.PTEXTSIZE.y ); + colrow.right = ( xy.right / _s.PTEXTSIZE.x - ( xy.right % _s.PTEXTSIZE.x ? 0 : 1 ) ); /* Adjust for when rectangle */ + colrow.bottom = ( xy.bottom / _s.PTEXTSIZE.y - ( xy.bottom % _s.PTEXTSIZE.y ? 0 : 1 ) ); /* EXACTLY overlaps characters */ + + return colrow; +} + +POINT HB_EXPORT hb_gt_wvt_GetXYFromColRow( USHORT col, USHORT row ) +{ + POINT xy; + + xy.x = ( col ) * _s.PTEXTSIZE.x; + xy.y = ( row ) * _s.PTEXTSIZE.y; + + return xy; +} + +static RECT hb_gt_wvt_GetXYFromColRowRect( RECT colrow ) +{ + RECT xy; + + xy.left = ( colrow.left ) * _s.PTEXTSIZE.x; + xy.top = ( colrow.top ) * _s.PTEXTSIZE.y; + xy.right = ( colrow.right +1 ) * _s.PTEXTSIZE.x; + xy.bottom = ( colrow.bottom+1 ) * _s.PTEXTSIZE.y; + + return xy; +} + +/* + * functions for handling the input queues for the mouse and keyboard + */ +void HB_EXPORT hb_gt_wvt_AddCharToInputQueue( int iKey ) +{ + int iPos = _s.keyPointerIn; + + if( iKey == K_MOUSEMOVE || iKey == K_NCMOUSEMOVE ) + { + /* Clipper strips repeated mouse movemnt - let's do the same */ + if( _s.keyLast == iKey && _s.keyPointerIn != _s.keyPointerOut ) + { + return; + } + } + + /* + * When the buffer is full new event overwrite the last one + * in the buffer - it's Clipper behavior, [druzus] + */ + _s.Keys[ iPos ] = _s.keyLast = iKey; + if( ++iPos >= WVT_CHAR_QUEUE_SIZE ) + { + iPos = 0; + } + if( iPos != _s.keyPointerOut ) + { + _s.keyPointerIn = iPos; + } +} + +static BOOL hb_gt_wvt_GetCharFromInputQueue( int * iKey ) +{ + if( _s.keyPointerOut != _s.keyPointerIn ) + { + *iKey = _s.Keys[ _s.keyPointerOut ]; + if( ++_s.keyPointerOut >= WVT_CHAR_QUEUE_SIZE ) + { + _s.keyPointerOut = 0; + } + return TRUE; + } + + *iKey = 0; + return FALSE; +} + +static void hb_gt_wvt_TranslateKey( int key, int shiftkey, int altkey, int controlkey ) +{ + int nVirtKey = GetKeyState( VK_MENU ); + + if ( nVirtKey & 0x8000 ) /* alt + key */ + { + hb_gt_wvt_AddCharToInputQueue( altkey ); + } + else + { + nVirtKey = GetKeyState( VK_CONTROL ); + if ( nVirtKey & 0x8000 ) /* control + key */ + { + hb_gt_wvt_AddCharToInputQueue( controlkey ); + } + else + { + nVirtKey = GetKeyState( VK_SHIFT ); + if ( nVirtKey & 0x8000 ) /* shift + key */ + { + hb_gt_wvt_AddCharToInputQueue( shiftkey ); + } + else /* just key */ + { + hb_gt_wvt_AddCharToInputQueue( key ); + } + } + } +} + +static int hb_gt_wvt_key_ansi_to_oem( int c ) +{ + BYTE pszAnsi[ 2 ]; + BYTE pszOem[ 2 ]; + + pszAnsi[ 0 ] = ( BYTE ) c; + pszAnsi[ 1 ] = 0; + CharToOemBuff( ( LPCSTR ) pszAnsi, ( LPTSTR ) pszOem, 1 ); + + return * pszOem; +} + +static void hb_gt_wvt_SetMousePos( int iRow, int iCol ) +{ + _s.mousePos.y = ( SHORT ) iRow; + _s.mousePos.x = ( SHORT ) iCol; +} + +static void hb_gt_wvt_MouseEvent( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) +{ + POINT xy, colrow; + SHORT keyCode = 0; + SHORT keyState = 0; + + HB_SYMBOL_UNUSED( hWnd ); + HB_SYMBOL_UNUSED( wParam ); + + if ( ! _s.MouseMove && ( message == WM_MOUSEMOVE || message == WM_NCMOUSEMOVE ) ) + { + return; + } + + xy.x = LOWORD( lParam ); + xy.y = HIWORD( lParam ); + + colrow = hb_gt_wvt_GetColRowFromXY( ( SHORT ) xy.x, ( SHORT ) xy.y ); + + hb_gt_wvt_SetMousePos( colrow.y, colrow.x ); + + switch( message ) + { + case WM_LBUTTONDBLCLK: + keyCode = K_LDBLCLK; + break; + + case WM_RBUTTONDBLCLK: + keyCode = K_RDBLCLK; + break; + + case WM_LBUTTONDOWN: + keyCode = K_LBUTTONDOWN; + break; + + case WM_RBUTTONDOWN: + keyCode = K_RBUTTONDOWN; + break; + + case WM_RBUTTONUP: + keyCode = K_RBUTTONUP; + break; + + case WM_LBUTTONUP: + keyCode = K_LBUTTONUP; + break; + + case WM_MBUTTONDOWN: + keyCode = K_MBUTTONDOWN; + break; + + case WM_MBUTTONUP: + keyCode = K_MBUTTONUP; + break; + + case WM_MBUTTONDBLCLK: + keyCode = K_MDBLCLK; + break; + + case WM_MOUSEMOVE: + keyState = wParam; + + if ( keyState == MK_LBUTTON ) + { + keyCode = K_MMLEFTDOWN; + } + else if ( keyState == MK_RBUTTON ) + { + keyCode = K_MMRIGHTDOWN; + } + else if ( keyState == MK_MBUTTON ) + { + keyCode = K_MMMIDDLEDOWN; + } + else + { + keyCode = K_MOUSEMOVE; + } + break; + + case WM_MOUSEWHEEL: + keyState = HIWORD( wParam ); + + if ( keyState > 0 ) + { + keyCode = K_MWFORWARD; + } + else + { + keyCode = K_MWBACKWARD; + } + break; + + case WM_NCMOUSEMOVE: + keyCode = K_NCMOUSEMOVE; + break; + } + + if ( keyCode != 0 ) + { + hb_gt_wvt_AddCharToInputQueue( keyCode ); + } +} + +static BOOL hb_gt_wvt_KeyEvent( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) +{ + switch( message ) + { + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + BOOL bAlt = GetKeyState( VK_MENU ) & 0x8000; + + _s.fIgnoreWM_SYSCHAR = FALSE; + + switch ( wParam ) + { + case VK_LEFT: + hb_gt_wvt_TranslateKey( K_LEFT , K_SH_LEFT , K_ALT_LEFT , K_CTRL_LEFT ); + break; + case VK_RIGHT: + hb_gt_wvt_TranslateKey( K_RIGHT, K_SH_RIGHT, K_ALT_RIGHT, K_CTRL_RIGHT ); + break; + case VK_UP: + hb_gt_wvt_TranslateKey( K_UP , K_SH_UP , K_ALT_UP , K_CTRL_UP ); + break; + case VK_DOWN: + hb_gt_wvt_TranslateKey( K_DOWN , K_SH_DOWN , K_ALT_DOWN , K_CTRL_DOWN ); + break; + case VK_HOME: + hb_gt_wvt_TranslateKey( K_HOME , K_SH_HOME , K_ALT_HOME , K_CTRL_HOME ); + break; + case VK_END: + hb_gt_wvt_TranslateKey( K_END , K_SH_END , K_ALT_END , K_CTRL_END ); + break; + case VK_DELETE: + hb_gt_wvt_TranslateKey( K_DEL , K_SH_DEL , K_ALT_DEL , K_CTRL_DEL ); + break; + case VK_INSERT: + hb_gt_wvt_TranslateKey( K_INS , K_SH_INS , K_ALT_INS , K_CTRL_INS ); + break; + case VK_PRIOR: + hb_gt_wvt_TranslateKey( K_PGUP , K_SH_PGUP , K_ALT_PGUP , K_CTRL_PGUP ); + break; + case VK_NEXT: + hb_gt_wvt_TranslateKey( K_PGDN , K_SH_PGDN , K_ALT_PGDN , K_CTRL_PGDN ); + break; + + case VK_F1: + hb_gt_wvt_TranslateKey( K_F1 , K_SH_F1, K_ALT_F1 , K_CTRL_F1 ); + break; + case VK_F2: + hb_gt_wvt_TranslateKey( K_F2 , K_SH_F2, K_ALT_F2 , K_CTRL_F2 ); + break; + case VK_F3: + hb_gt_wvt_TranslateKey( K_F3 , K_SH_F3, K_ALT_F3 , K_CTRL_F3 ); + break; + case VK_F4: + if ( _s.AltF4Close && bAlt ) + { + return DefWindowProc( hWnd, message, wParam, lParam ); + } + else + { + hb_gt_wvt_TranslateKey( K_F4 , K_SH_F4, K_ALT_F4 , K_CTRL_F4 ); + } + break; + case VK_F5: + hb_gt_wvt_TranslateKey( K_F5 , K_SH_F5, K_ALT_F5 , K_CTRL_F5 ); + break; + case VK_F6: + hb_gt_wvt_TranslateKey( K_F6 , K_SH_F6, K_ALT_F6 , K_CTRL_F6 ); + break; + case VK_F7: + hb_gt_wvt_TranslateKey( K_F7 , K_SH_F7, K_ALT_F7 , K_CTRL_F7 ); + break; + case VK_F8: + hb_gt_wvt_TranslateKey( K_F8 , K_SH_F8, K_ALT_F8 , K_CTRL_F8 ); + break; + case VK_F9: + hb_gt_wvt_TranslateKey( K_F9 , K_SH_F9, K_ALT_F9 , K_CTRL_F9 ); + break; + case VK_F10: + hb_gt_wvt_TranslateKey( K_F10 , K_SH_F10,K_ALT_F10 , K_CTRL_F10 ); + break; + case VK_F11: + hb_gt_wvt_TranslateKey( K_F11 , K_SH_F11,K_ALT_F11 , K_CTRL_F11 ); + break; + case VK_F12: + hb_gt_wvt_TranslateKey( K_F12 , K_SH_F12,K_ALT_F12 , K_CTRL_F12 ); + break; + default: + { + BOOL bCtrl = GetKeyState( VK_CONTROL ) & 0x8000; + BOOL bShift = GetKeyState( VK_SHIFT ) & 0x8000; + int iScanCode = HIWORD( lParam ) & 0xFF ; + + if ( bCtrl && iScanCode == 76 ) /* CTRL_VK_NUMPAD5 */ + { + hb_gt_wvt_AddCharToInputQueue( KP_CTRL_5 ); + } + else if ( bCtrl && wParam == VK_TAB ) /* K_CTRL_TAB */ + { + if ( bShift ) + { + hb_gt_wvt_AddCharToInputQueue( K_CTRL_SH_TAB ); + } + else + { + hb_gt_wvt_AddCharToInputQueue( K_CTRL_TAB ); + } + } + else if ( iScanCode == 70 ) /* Ctrl_Break key OR Scroll Lock Key */ + { + if ( bCtrl ) /* Not scroll lock */ + { + hb_gt_wvt_AddCharToInputQueue( HB_BREAK_FLAG ); /* Pretend Alt+C pressed */ + _s.fIgnoreWM_SYSCHAR = TRUE; + } + else + { + DefWindowProc( hWnd, message, wParam, lParam ) ; /* Let windows handle ScrollLock */ + } + } + else if ( bCtrl && iScanCode == 53 && bShift ) + { + hb_gt_wvt_AddCharToInputQueue( K_CTRL_QUESTION ); + } + else if ( ( bAlt || bCtrl ) && ( + wParam == VK_MULTIPLY || wParam == VK_ADD || + wParam == VK_SUBTRACT || wParam == VK_DIVIDE ) ) + { + if ( bAlt ) + { + _s.fIgnoreWM_SYSCHAR = TRUE; + } + switch ( wParam ) + { + case VK_MULTIPLY: + hb_gt_wvt_TranslateKey( '*','*', KP_ALT_ASTERISK, KP_CTRL_ASTERISK ); + break; + case VK_ADD: + hb_gt_wvt_TranslateKey( '+','+', KP_ALT_PLUS, KP_CTRL_PLUS ); + break; + case VK_SUBTRACT: + hb_gt_wvt_TranslateKey( '-','-', KP_ALT_MINUS, KP_CTRL_MINUS ); + break; + case VK_DIVIDE: + hb_gt_wvt_TranslateKey( '/','/', KP_ALT_SLASH, KP_CTRL_SLASH ); + break; + } + } + } + } + break; + } + + case WM_CHAR: + { + BOOL bCtrl = GetKeyState( VK_CONTROL ) & 0x8000; + int iScanCode = HIWORD( lParam ) & 0xFF ; + int c = ( int ) wParam; + + if ( !_s.fIgnoreWM_SYSCHAR ) + { + if ( bCtrl && iScanCode == 28 ) /* K_CTRL_RETURN */ + { + hb_gt_wvt_AddCharToInputQueue( K_CTRL_RETURN ); + } + else if ( bCtrl && ( c >= 1 && c <= 26 ) ) /* K_CTRL_A - Z */ + { + hb_gt_wvt_AddCharToInputQueue( K_Ctrl[c-1] ); + } + else + { + switch ( c ) + { + /* handle special characters */ + case VK_BACK: + hb_gt_wvt_TranslateKey( K_BS, K_SH_BS, K_ALT_BS, K_CTRL_BS ); + break; + case VK_TAB: + hb_gt_wvt_TranslateKey( K_TAB, K_SH_TAB, K_ALT_TAB, K_CTRL_TAB ); + break; + case VK_RETURN: + hb_gt_wvt_TranslateKey( K_RETURN, K_SH_RETURN, K_ALT_RETURN, K_CTRL_RETURN ); + break; + case VK_ESCAPE: + hb_gt_wvt_AddCharToInputQueue( K_ESC ); + break; + default: + if( _s.CodePage == OEM_CHARSET ) + { + c = hb_gt_wvt_key_ansi_to_oem( c ); + } + hb_gt_wvt_AddCharToInputQueue( c ); + break; + } + } + } + _s.fIgnoreWM_SYSCHAR = FALSE; /* As Suggested by Peter */ + break; + } + + case WM_SYSCHAR: + { + if ( !_s.fIgnoreWM_SYSCHAR ) + { + int c, iScanCode = HIWORD( lParam ) & 0xFF ; + switch ( iScanCode ) + { + case 2: + c = K_ALT_1 ; + break; + case 3: + c = K_ALT_2 ; + break; + case 4: + c = K_ALT_3 ; + break; + case 5: + c = K_ALT_4 ; + break; + case 6: + c = K_ALT_5 ; + break; + case 7: + c = K_ALT_6 ; + break; + case 8: + c = K_ALT_7 ; + break; + case 9: + c = K_ALT_8 ; + break; + case 10: + c = K_ALT_9 ; + break; + case 11: + c = K_ALT_0 ; + break; + case 13: + c = K_ALT_EQUALS ; + break; + case 14: + c = K_ALT_BS ; + break; + case 16: + c = K_ALT_Q ; + break; + case 17: + c = K_ALT_W ; + break; + case 18: + c = K_ALT_E ; + break; + case 19: + c = K_ALT_R ; + break; + case 20: + c = K_ALT_T ; + break; + case 21: + c = K_ALT_Y ; + break; + case 22: + c = K_ALT_U ; + break; + case 23: + c = K_ALT_I ; + break; + case 24: + c = K_ALT_O ; + break; + case 25: + c = K_ALT_P ; + break; + case 30: + c = K_ALT_A ; + break; + case 31: + c = K_ALT_S ; + break; + case 32: + c = K_ALT_D ; + break; + case 33: + c = K_ALT_F ; + break; + case 34: + c = K_ALT_G ; + break; + case 35: + c = K_ALT_H ; + break; + case 36: + c = K_ALT_J ; + break; + case 37: + c = K_ALT_K ; + break; + case 38: + c = K_ALT_L ; + break; + case 44: + c = K_ALT_Z ; + break; + case 45: + c = K_ALT_X ; + break; + case 46: + c = K_ALT_C ; + break; + case 47: + c = K_ALT_V ; + break; + case 48: + c = K_ALT_B ; + break; + case 49: + c = K_ALT_N ; + break; + case 50: + c = K_ALT_M ; + break; + default: + c = ( int ) wParam ; + break; + } + hb_gt_wvt_AddCharToInputQueue( c ); + } + _s.fIgnoreWM_SYSCHAR = FALSE; + } + } + + return 0; +} + +static int kbdShiftsState( void ) +{ + BYTE kbBuffer[ 256 ]; + int kbdShifts; + + kbdShifts = 0; + GetKeyboardState( kbBuffer ); + if ( kbBuffer[ VK_SHIFT ] & 0x080 ) kbdShifts += GTI_KBD_SHIFT; + if ( kbBuffer[ VK_CONTROL ] & 0x080 ) kbdShifts += GTI_KBD_CTRL; + if ( kbBuffer[ VK_MENU ] & 0x080 ) kbdShifts += GTI_KBD_ALT; + if ( kbBuffer[ VK_LWIN ] & 0x080 ) kbdShifts += GTI_KBD_LWIN; + if ( kbBuffer[ VK_RWIN ] & 0x080 ) kbdShifts += GTI_KBD_RWIN; + if ( kbBuffer[ VK_APPS ] & 0x080 ) kbdShifts += GTI_KBD_MENU; + if ( kbBuffer[ VK_SCROLL ] & 0x001 ) kbdShifts += GTI_KBD_SCROLOCK; + if ( kbBuffer[ VK_NUMLOCK ] & 0x001 ) kbdShifts += GTI_KBD_NUMLOCK; + if ( kbBuffer[ VK_CAPITAL ] & 0x001 ) kbdShifts += GTI_KBD_CAPSLOCK; + + return kbdShifts; +} + +/* + * hb_gt_wvt_TextOut converts col and row to x and y ( pixels ) and calls + * the Windows function TextOut with the expected coordinates + */ +static BOOL hb_gt_wvt_TextOut( HDC hdc, USHORT col, USHORT row, BYTE attr, LPCTSTR lpString, USHORT cbString ) +{ + BOOL Result; + POINT xy; + RECT rClip; + + _s.foreground = _COLORS[ attr & 0x0F ]; + _s.background = _COLORS[ ( attr >> 4 ) & 0x0F ]; + + SetTextColor( hdc, _s.foreground ); + SetBkColor( hdc, _s.background ); + SetTextAlign( hdc, TA_LEFT ); + + xy = hb_gt_wvt_GetXYFromColRow( col, row ); + + SetRect( &rClip, xy.x, xy.y, xy.x + cbString * _s.PTEXTSIZE.x, xy.y + _s.PTEXTSIZE.y ); + + if ( _s.FixedFont ) + { + Result = ExtTextOut( hdc, xy.x, xy.y, ETO_CLIPPED|ETO_OPAQUE, &rClip, lpString, cbString, NULL ); + } + else + { + Result = ExtTextOut( hdc, xy.x, xy.y, ETO_CLIPPED|ETO_OPAQUE, &rClip, lpString, cbString, _s.FixedSize ); + } + + return Result; +} + +static void hb_gt_wvt_PaintText( HWND hWnd, RECT rcRect ) +{ + PAINTSTRUCT ps; + HDC hdc; + int iRow, iCol, startCol, len; + BYTE bColor, bAttr, bOldColor = 0; + USHORT usChar; + char text[ WVT_MAX_ROWS ]; + + hdc = BeginPaint( hWnd, &ps ); + SelectObject( hdc, _s.hFont ); + + for ( iRow = rcRect.top; iRow <= rcRect.bottom; ++iRow ) + { + iCol = startCol = rcRect.left; + len = 0; + + while ( iCol <= rcRect.right ) + { + if ( !hb_gt_GetScrChar( iRow, iCol, &bColor, &bAttr, &usChar ) ) + { + break; + } + if ( len == 0 ) + { + bOldColor = bColor; + } + else if ( bColor != bOldColor ) + { + hb_gt_wvt_TextOut( hdc, startCol, iRow, bOldColor, text, len ); + bOldColor = bColor; + startCol = iCol; + len = 0; + } + text[ len++ ] = ( char ) usChar; + iCol++; + } + if ( len > 0 ) + { + hb_gt_wvt_TextOut( hdc, startCol, iRow, bOldColor, text, len ); + } + } + + EndPaint( hWnd, &ps ); +} + +static void hb_gt_wvt_UpdateCaret( void ) +{ + int iRow, iCol, iStyle, iCaretSize; + + hb_gt_GetScrCursor( &iRow, &iCol, &iStyle ); + + if( iRow < 0 || iCol < 0 || iRow >= _s.ROWS || iCol >= _s.COLS ) + { + iCaretSize = 0; + } + else switch( iStyle ) + { + case SC_INSERT: + iCaretSize = _s.PTEXTSIZE.y >> 1; + break; + case SC_SPECIAL1: + iCaretSize = _s.PTEXTSIZE.y; + break; + case SC_SPECIAL2: + iCaretSize = - ( _s.PTEXTSIZE.y >> 1 ); + break; + case SC_NORMAL: + iCaretSize = 4; + break; + default: + iCaretSize = 0; + break; + } + + if( iCaretSize == 0 ) + { + if( _s.CaretExist && !_s.CaretHidden ) + { + HideCaret( _s.hWnd ); + _s.CaretHidden = TRUE; + } + } + else + { + if( iCaretSize != _s.CaretSize || !_s.CaretExist ) + { + _s.CaretSize = iCaretSize; + _s.CaretExist = CreateCaret( _s.hWnd, ( HBITMAP ) NULL, _s.PTEXTSIZE.x, + _s.CaretSize < 0 ? - _s.CaretSize : _s.CaretSize ); + } + if( _s.CaretExist ) + { + POINT xy; + xy = hb_gt_wvt_GetXYFromColRow( ( SHORT ) iCol, ( SHORT ) iRow ); + SetCaretPos( xy.x, _s.CaretSize < 0 ? + xy.y : xy.y + _s.PTEXTSIZE.y - _s.CaretSize ); + ShowCaret( _s.hWnd ); + _s.CaretHidden = FALSE; + } + } +} + +static void hb_gt_wvt_KillCaret( void ) +{ + if ( _s.CaretExist ) + { + DestroyCaret(); + _s.CaretExist = FALSE; + } +} + +static LRESULT CALLBACK hb_gt_wvt_WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) +{ + BOOL bRet; + + switch ( message ) + { + case WM_CREATE: + { + bRet = hb_gt_wvt_InitWindow( hWnd, WVT_DEFAULT_ROWS, WVT_DEFAULT_COLS ); + return bRet; + } + + case WM_PAINT: + { + RECT updateRect; + + /* WARNING!!! + * the GetUpdateRect call MUST be made BEFORE the BeginPaint call, since + * BeginPaint resets the update rectangle - don't move it or nothing is drawn! + */ + if ( GetUpdateRect( hWnd, &updateRect, FALSE ) ) + { + hb_gt_wvt_PaintText( hWnd, hb_gt_wvt_GetColRowFromXYRect( updateRect ) ); + } + + return 0; + } + + case WM_MY_UPDATE_CARET: + { + hb_gt_wvt_UpdateCaret(); + return 0; + } + + case WM_SETFOCUS: + { + hb_gt_wvt_UpdateCaret(); + return 0; + } + + case WM_KILLFOCUS: + { + hb_gt_wvt_KillCaret(); + return 0; + } + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_CHAR: + case WM_SYSCHAR: + { + return hb_gt_wvt_KeyEvent( hWnd, message, wParam, lParam ); + } + + case WM_RBUTTONDOWN: + case WM_LBUTTONDOWN: + case WM_RBUTTONUP: + case WM_LBUTTONUP: + case WM_RBUTTONDBLCLK: + case WM_LBUTTONDBLCLK: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_MBUTTONDBLCLK: + case WM_MOUSEMOVE: + case WM_MOUSEWHEEL: + case WM_NCMOUSEMOVE: + { + hb_gt_wvt_MouseEvent( hWnd, message, wParam, lParam ); + return 0; + } + + case WM_QUERYENDSESSION: /* Closing down computer */ + { + hb_vmRequestQuit(); + return 0; + } + + case WM_CLOSE: /* Clicked 'X' on system menu */ + { + if( hb_set.HB_SET_CANCEL ) + { + hb_vmRequestCancel(); + } + return 0; + } + + case WM_QUIT: + case WM_DESTROY: + return 0; + + case WM_ENTERIDLE: + { + /* FSG - 12/05/2004 - Signal than i'm on idle */ + hb_idleState(); + return( 0 ); + } +/* + case WM_TIMER: + { + if ( _s.pSymWVT_TIMER ) + { + hb_vmPushState(); + hb_vmPushSymbol( hb_dynsymSymbol( _s.pSymWVT_TIMER ) ); + hb_vmPushNil(); + hb_vmDo( 0 ); + hb_vmPopState(); + } + return 0; + } +*/ + } + + return DefWindowProc( hWnd, message, wParam, lParam ); +} + +static DWORD hb_gt_wvt_ProcessMessages( void ) +{ + MSG msg; + while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + return msg.wParam; +} + +static void hb_gt_wvt_SetClipboard( char * szClipData, ULONG ulLen ) +{ + LPTSTR lptstrCopy; + HGLOBAL hglbCopy; + UINT uFormat = ( _s.CodePage == OEM_CHARSET ) ? CF_OEMTEXT : CF_TEXT; + + if ( OpenClipboard( NULL ) ) + { + EmptyClipboard(); + + /* Allocate a global memory object for the text. */ + hglbCopy = GlobalAlloc( GMEM_MOVEABLE, ulLen + 1 ); + if ( hglbCopy ) + { + /* Lock the handle and copy the text to the buffer. */ + lptstrCopy = ( LPSTR ) GlobalLock( hglbCopy ); + memcpy( lptstrCopy, szClipData, ulLen ); + lptstrCopy[ ulLen ] = 0; + GlobalUnlock( hglbCopy ); + /* Place the handle on the clipboard. */ + SetClipboardData( uFormat, hglbCopy ); + } + CloseClipboard(); + } +} + +static BOOL hb_gt_wvt_GetClipboard( char ** pszClipData, ULONG *pulLen ) +{ + HGLOBAL hglb; + LPTSTR lptstr; + UINT uFormat = ( _s.CodePage == OEM_CHARSET ) ? CF_OEMTEXT : CF_TEXT; + + *pulLen = 0; + *pszClipData = NULL; + if ( IsClipboardFormatAvailable( uFormat ) && OpenClipboard( NULL ) ) + { + hglb = GetClipboardData( uFormat ); + if ( hglb ) + { + lptstr = ( LPSTR ) GlobalLock( hglb ); + if ( lptstr != NULL ) + { + *pulLen = strlen( lptstr ); + + if( *pulLen ) + { + *pszClipData = hb_xgrab( *pulLen + 1 ); + memcpy( *pszClipData, lptstr, *pulLen + 1 ); + } + GlobalUnlock( hglb ); + } + } + CloseClipboard(); + } + + return *pulLen != 0; +} + +static BOOL hb_gt_wvt_ValidWindowSize( int rows, int cols, HFONT hFont, int iWidth ) +{ + HDC hdc; + HFONT hOldFont ; + USHORT width, height, maxWidth, maxHeight; + TEXTMETRIC tm; + RECT rcWorkArea; + + SystemParametersInfo( SPI_GETWORKAREA,0, &rcWorkArea, 0 ); + + maxWidth = (SHORT) ( rcWorkArea.right - rcWorkArea.left ); + maxHeight = (SHORT) ( rcWorkArea.bottom - rcWorkArea.top ); + + hdc = GetDC( _s.hWnd ); + hOldFont = ( HFONT ) SelectObject( hdc, hFont ); + GetTextMetrics( hdc, &tm ); + SelectObject( hdc, hOldFont ); /* Put old font back */ + ReleaseDC( _s.hWnd, hdc ); + + width = iWidth < 0 ? -iWidth : tm.tmAveCharWidth * cols ; /* Total pixel width this setting would take */ + height = tm.tmHeight * rows; /* Total pixel height this setting would take */ + + return ( width <= maxWidth ) && ( height <= maxHeight ); +} + +static HWND hb_gt_wvt_CreateWindow( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow ) +{ + HWND hWnd; + WNDCLASS wndclass; + + HB_SYMBOL_UNUSED( hPrevInstance ); + HB_SYMBOL_UNUSED( szCmdLine ); + + /* InitCommonControls(); */ + + wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ; + wndclass.lpfnWndProc = hb_gt_wvt_WndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = hInstance; + wndclass.hIcon = NULL; + wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ); + wndclass.hbrBackground = NULL; + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = szAppName; + + if ( ! RegisterClass( &wndclass ) ) + { + MessageBox( NULL, TEXT( "Failed to register class." ), + szAppName, MB_ICONERROR ); + return 0; + } + + hWnd = CreateWindow( szAppName, /* classname */ + TEXT( "HARBOUR_WVT" ), /* window name */ + WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX, /* style */ + 0, /* x */ + 0, /* y */ + CW_USEDEFAULT, /* width */ + CW_USEDEFAULT, /* height */ + NULL, /* window parent */ + NULL, /* menu */ + hInstance, /* instance */ + NULL ); /* lpParam */ + + + if ( hWnd == NULL ) + { + MessageBox( NULL, TEXT( "Failed to create window." ), + TEXT( "HARBOUR_WVT" ), MB_ICONERROR ); + } + + /* + * If you wish to show window the way you want, put somewhere in your application + * ANNOUNCE HB_NOSTARTUPWINDOW + * If so compiled, then you need to issue Wvt_ShowWindow( SW_RESTORE ) + * at the point you desire in your code. + */ + + if ( hb_dynsymFind( "HB_NOSTARTUPWINDOW" ) != NULL ) + { + iCmdShow = SW_HIDE; + } + + ShowWindow( hWnd, iCmdShow ); + UpdateWindow( hWnd ); + + return hWnd; +} + + +/* ********************************************************************** */ +/* + * GT Specific Functions + */ +/* ********************************************************************** */ + +static void hb_gt_wvt_Init( FHANDLE hFilenoStdin, FHANDLE hFilenoStdout, FHANDLE hFilenoStderr ) +{ + HB_TRACE( HB_TR_DEBUG, ( "hb_gt_wvt_Init(%p,%p,%p)", hFilenoStdin, hFilenoStdout, hFilenoStderr ) ); + + if( ! hb_winmainArgGet( &s_hInstance, &s_hPrevInstance, &s_iCmdShow ) ) + { + hb_errInternal( 10001, "It's not a window GUI program.", "", "" ); + } + + /* If Windows 95 or 98, use w9xTone for BCC32, MSVC */ + s_osv.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); + GetVersionEx( &s_osv ); + + hb_gt_wvt_InitStatics(); + _s.hWnd = hb_gt_wvt_CreateWindow( ( HINSTANCE ) s_hInstance, + ( HINSTANCE ) s_hPrevInstance, + "", s_iCmdShow ); + if ( !_s.hWnd ) + { + /* hb_errRT_TERM( EG_CREATE, 10001, "WINAPI CreateWindow() failed", "hb_gt_wvt_Init()", 0, 0 ); */ + hb_errInternal( 10001, "WINAPI CreateWindow() failed", "", "" ); + } + _s.hdc = GetDC( _s.hWnd ); + + /* Set default window title */ + { + PHB_FNAME pFileName = hb_fsFNameSplit( hb_cmdargARGV()[0] ); + hb_gt_wvt_SetWindowTitle( pFileName->szName ); + hb_xfree( pFileName ); + } + + /* SUPER GT initialization */ + HB_GTSUPER_INIT( hFilenoStdin, hFilenoStdout, hFilenoStderr ); + HB_GTSUPER_RESIZE( _s.ROWS, _s.COLS ); + HB_GTSUPER_EXPOSEAREA( 0, 0, _s.ROWS, _s.COLS ); +} + +/* ********************************************************************** */ + +static void hb_gt_wvt_Exit( void ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_gt_wvt_Exit()")); + + HB_GTSUPER_EXIT(); + + if ( _s.hWnd ) + { + if ( _s.hdc ) + { + ReleaseDC( _s.hWnd, _s.hdc ); + } + + DestroyWindow( _s.hWnd ); + _s.hWnd = NULL; + } + UnregisterClass( szAppName, ( HINSTANCE ) s_hInstance ); +} + +static BOOL hb_gt_wvt_SetMode( int iRow, int iCol ) +{ + BOOL fResult= FALSE; + + HB_TRACE( HB_TR_DEBUG, ( "hb_gt_wvt_SetMode( %hu, %hu )", iRow, iCol ) ); + + if ( iRow <= WVT_MAX_ROWS && iCol <= WVT_MAX_COLS ) + { + if ( _s.hWnd ) /* Is the window already open */ + { + HFONT hFont = hb_gt_wvt_GetFont( _s.fontFace, _s.fontHeight, _s.fontWidth, + _s.fontWeight, _s.fontQuality, _s.CodePage ); + + if ( hFont ) + { + /* + * make sure that the mode selected along with the current + * font settings will fit in the window + */ + if ( hb_gt_wvt_ValidWindowSize( iRow, iCol, hFont, _s.fontWidth ) ) + { + fResult = hb_gt_wvt_InitWindow( _s.hWnd, iRow, iCol ); + } + DeleteObject( hFont ); + } + } + else + { + hb_gt_wvt_SetWindowSize( iRow, iCol ); + } + } + + return fResult; +} + +static char * hb_gt_wvt_Version( int iType ) +{ + HB_TRACE( HB_TR_DEBUG, ( "hb_gt_wvt_Version()" ) ); + + if ( iType == 0 ) + return HB_GT_DRVNAME( HB_GT_NAME ); + + return "Harbour Terminal: Win32 buffered WVT"; +} + +/* *********************************************************************** */ + +static int hb_gt_wvt_ReadKey( int iEventMask ) +{ + int c = 0; + BOOL fKey; + + HB_TRACE( HB_TR_DEBUG, ( "hb_gt_wvt_ReadKey( %d )", iEventMask ) ); + + HB_SYMBOL_UNUSED( iEventMask ); /* we ignore the eventmask! */ + + hb_gt_wvt_ProcessMessages(); + fKey = hb_gt_wvt_GetCharFromInputQueue( &c ); + + return fKey ? c : 0; +} + +/* *********************************************************************** */ + +/* + * Tone code copied from gtwin + */ + +#if defined( HB_ARCH_32BIT ) && \ + ( defined(__BORLANDC__) || defined(_MSC_VER) || \ + defined(__WATCOMC__) || defined(__MINGW32__) ) +static int hb_Inp9x( USHORT usPort ) +{ + USHORT usVal; + + HB_TRACE(HB_TR_DEBUG, ("hb_Inp9x(%hu)", usPort)); + + #if defined( __BORLANDC__ ) || defined(__DMC__) + + _DX = usPort; + __emit__(0xEC); /* ASM IN AL, DX */ + __emit__(0x32,0xE4); /* ASM XOR AH, AH */ + usVal = _AX; + + #elif defined( __XCC__ ) + + __asm { + mov dx, usPort + xor ax, ax + in al, dx + mov usVal, ax + } + + #elif defined( __MINGW32__ ) + __asm__ __volatile__ ("inb %w1,%b0":"=a" (usVal):"Nd" (usPort)); + + #elif defined( __WATCOMC__ ) + + usVal = inp( usPort ); + + #else + + usVal = _inp( usPort ); + + #endif + + return usVal; +} + +/* *********************************************************************** */ + +static int hb_Outp9x( USHORT usPort, USHORT usVal ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_Outp9x(%hu, %hu)", usPort, usVal)); + + #if defined( __BORLANDC__ ) || defined(__DMC__) + + _DX = usPort; + _AL = usVal; + __emit__(0xEE); /* ASM OUT DX, AL */ + + #elif defined( __XCC__ ) + + __asm { + mov dx, usPort + mov ax, usVal + out dx, al + } + + #elif defined( __MINGW32__ ) + + __asm__ __volatile__ ("outb %b0,%w1": :"a" (usVal), "Nd" (usPort)); + + #elif defined( __WATCOMC__ ) + + outp( usPort, usVal ); + + #else + + _outp( usPort, usVal ); + + #endif + + return usVal; +} + +/* *********************************************************************** */ +/* dDurat is in seconds */ +static void hb_gt_wvt_w9xTone( double dFreq, double dDurat ) +{ + INT uLSB,uMSB; + ULONG lAdjFreq; + + HB_TRACE(HB_TR_DEBUG, ("hb_gt_wvt_w9xtone(%lf, %lf)", dFreq, dDurat)); + + /* sync with internal clock with very small time period */ + hb_idleSleep( 0.01 ); + + /* Clipper ignores Tone() requests (but delays anyway) if Frequency is + less than < 20 hz (and so should we) to maintain compatibility .. */ + + if( dFreq >= 20.0 ) + { + /* Setup Sound Control Port Registers and timer channel 2 */ + hb_Outp9x(67, 182) ; + + lAdjFreq = (ULONG)( 1193180 / dFreq ) ; + + if( (LONG) lAdjFreq < 0 ) + uLSB = lAdjFreq + 65536; + else + uLSB = lAdjFreq % 256; + + if( (LONG) lAdjFreq < 0 ) + uMSB = lAdjFreq + 65536; + else + uMSB = lAdjFreq / 256; + + + /* set the frequency (LSB,MSB) */ + + hb_Outp9x(66, uLSB); + hb_Outp9x(66, uMSB); + + /* Get current Port setting */ + /* enable Speaker Data & Timer gate bits */ + /* (00000011B is bitmask to enable sound) */ + /* Turn on Speaker - sound Tone for duration.. */ + + hb_Outp9x(97, hb_Inp9x( 97 ) | 3); + + hb_idleSleep( dDurat ); + + /* Read back current Port value for Reset */ + /* disable Speaker Data & Timer gate bits */ + /* (11111100B is bitmask to disable sound) */ + /* Turn off the Speaker ! */ + + hb_Outp9x(97, hb_Inp9x( 97 ) & 0xFC); + + } + else + { + hb_idleSleep( dDurat ); + } +} +#endif + +/* *********************************************************************** */ +/* dDurat is in seconds */ +static void hb_gt_wvt_wNtTone( double dFreq, double dDurat ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_gt_wvt_wNtTone(%lf, %lf)", dFreq, dDurat)); + + /* Clipper ignores Tone() requests (but delays anyway) if Frequency is + less than < 20 hz. Windows NT minimum is 37... */ + + if( dFreq >= 37.0 ) + { + Beep( (ULONG) dFreq, (ULONG) ( dDurat * 1000 ) ); /* Beep wants Milliseconds */ + } + else + { + hb_idleSleep( dDurat ); + } +} + +/* *********************************************************************** */ +/* dDuration is in 'Ticks' (18.2 per second) */ +static void hb_gt_wvt_Tone( double dFrequency, double dDuration ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_gt_wvt_Tone(%lf, %lf)", dFrequency, dDuration)); + + /* + * According to the Clipper NG, the duration in 'ticks' is truncated to the + * interger portion ... Depending on the platform, Harbour allows a finer + * resolution, but the minimum is 1 tick (for compatibility) + */ + /* Convert from ticks to seconds */ + dDuration = ( HB_MIN( HB_MAX( 1.0, dDuration ), ULONG_MAX ) ) / 18.2; + + /* keep the frequency in an acceptable range */ + dFrequency = HB_MIN( HB_MAX( 0.0, dFrequency ), 32767.0 ); + + /* If Windows 95 or 98, use w9xTone for BCC32, MSVC */ + if( _s.Win9X ) + { + #if defined( HB_ARCH_32BIT ) && \ + ( defined( __BORLANDC__ ) || defined( _MSC_VER ) || \ + defined( __WATCOMC__ ) || defined(__MINGW32__) ) + hb_gt_wvt_w9xTone( dFrequency, dDuration ); + #else + hb_gt_wvt_wNtTone( dFrequency, dDuration ); + #endif + } + /* If Windows NT or NT2k, use wNtTone, which provides TONE() + reset sequence support (new) */ + else /* if( s_osv.dwPlatformId == VER_PLATFORM_WIN32_NT ) */ + { + hb_gt_wvt_wNtTone( dFrequency, dDuration ); + } +} + + +/* *********************************************************************** */ + +static BOOL hb_gt_wvt_mouse_IsPresent( void ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_gt_wvt_mouse_IsPresent()")); + + return TRUE; +} + +static void hb_gt_wvt_mouse_GetPos( int * piRow, int * piCol ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_gt_wvt_mouse_GetPos(%p,%p)", piRow, piCol)); + + *piRow = _s.mousePos.y; + *piCol = _s.mousePos.x; +} + +static BOOL hb_gt_wvt_mouse_ButtonState( int iButton ) +{ + HB_TRACE( HB_TR_DEBUG, ( "hb_gt_wvt_mouse_ButtonState(%i)", iButton ) ); + + switch( iButton ) + { + case 0: + return ( GetKeyState( VK_LBUTTON ) & 0x8000 ) != 0; + case 1: + return ( GetKeyState( VK_RBUTTON ) & 0x8000 ) != 0; + case 2: + return ( GetKeyState( VK_MBUTTON ) & 0x8000 ) != 0; + } + return FALSE; +} + +static int hb_gt_wvt_mouse_CountButton( void ) +{ + HB_TRACE( HB_TR_DEBUG, ( "hb_gt_wvt_mouse_CountButton()") ); + + return( GetSystemMetrics( SM_CMOUSEBUTTONS ) ) ; +} + +/* *********************************************************************** */ + +static BOOL hb_gt_wvt_Info( int iType, PHB_GT_INFO pInfo ) +{ + int iVal; + + HB_TRACE( HB_TR_DEBUG, ( "hb_gt_wvt_Info(%d,%p)", iType, pInfo ) ); + + switch( iType ) + { + case GTI_ISGRAPHIC: + pInfo->pResult = hb_itemPutL( pInfo->pResult, TRUE ); + break; + + case GTI_INPUTFD: + pInfo->pResult = hb_itemPutNInt( pInfo->pResult, + ( UINT_PTR ) GetStdHandle( STD_INPUT_HANDLE ) ); + break; + + case GTI_OUTPUTFD: + pInfo->pResult = hb_itemPutNInt( pInfo->pResult, + ( UINT_PTR ) GetStdHandle( STD_OUTPUT_HANDLE ) ); + break; + + case GTI_ERRORFD: + pInfo->pResult = hb_itemPutNInt( pInfo->pResult, + ( UINT_PTR ) GetStdHandle( STD_ERROR_HANDLE ) ); + break; + + case GTI_FONTSIZE: + pInfo->pResult = hb_itemPutNI( pInfo->pResult, _s.PTEXTSIZE.y ); + iVal = hb_itemGetNI( pInfo->pNewVal ); + if( iVal > 0 ) + { + HFONT hFont = hb_gt_wvt_GetFont( _s.fontFace, iVal, _s.fontWidth, _s.fontWeight, _s.fontQuality, _s.CodePage ); + if ( hFont ) + { + _s.fontHeight = iVal; + if ( _s.hWnd ) + { + hb_gt_wvt_ResetWindowSize( _s.hWnd ); + hb_gt_wvt_UpdateCaret(); + } + DeleteObject( hFont ); + } + } + break; + + case GTI_FONTWIDTH: + pInfo->pResult = hb_itemPutNI( pInfo->pResult, _s.fontWidth ); + iVal = hb_itemGetNI( pInfo->pNewVal ); + if( iVal > 0 ) + { + /* store font status for next operation on fontsize */ + _s.fontWidth = iVal; + } + break; + + case GTI_FONTNAME: + pInfo->pResult = hb_itemPutC( pInfo->pResult, _s.fontFace ); + if( hb_itemType( pInfo->pNewVal ) & HB_IT_STRING ) /* TODO */ + { + hb_strncpy( _s.fontFace, hb_itemGetCPtr( pInfo->pNewVal ), LF_FACESIZE - 1 ); + } + break; + + case GTI_FONTWEIGHT: + switch( _s.fontWeight ) + { + case FW_THIN: + case FW_EXTRALIGHT: + case FW_LIGHT: + iVal = GTI_FONTW_THIN; + break; + + case FW_DONTCARE: + case FW_NORMAL: + case FW_MEDIUM: + iVal = GTI_FONTW_NORMAL; + break; + + case FW_SEMIBOLD: + case FW_BOLD: + case FW_EXTRABOLD: + case FW_HEAVY: + iVal = GTI_FONTW_BOLD; + break; + + default: + iVal = 0; + break; + } + pInfo->pResult = hb_itemPutNI( pInfo->pResult, iVal ); + if ( hb_itemType( pInfo->pNewVal ) & HB_IT_NUMERIC ) + { + /* store font status for next operation on fontsize */ + switch( hb_itemGetNI( pInfo->pNewVal ) ) + { + case GTI_FONTW_THIN: + _s.fontWeight = FW_LIGHT; + break; + case GTI_FONTW_NORMAL: + _s.fontWeight = FW_NORMAL; + break; + case GTI_FONTW_BOLD: + _s.fontWeight = FW_BOLD; + break; + } + } + break; + + case GTI_FONTQUALITY: + switch( _s.fontQuality ) + { + case ANTIALIASED_QUALITY: + iVal = GTI_FONTQ_HIGH; + break; + case DEFAULT_QUALITY: + case DRAFT_QUALITY: + iVal = GTI_FONTQ_NORMAL; + break; + case NONANTIALIASED_QUALITY: + case PROOF_QUALITY: + iVal = GTI_FONTQ_DRAFT; + break; + default: + iVal = 0; + break; + } + pInfo->pResult = hb_itemPutNI( pInfo->pResult, iVal ); + if ( hb_itemType( pInfo->pNewVal ) & HB_IT_NUMERIC ) + { + switch( hb_itemGetNI( pInfo->pNewVal ) ) + { + case GTI_FONTQ_HIGH: + _s.fontQuality = ANTIALIASED_QUALITY; + break; + case GTI_FONTQ_NORMAL: + _s.fontQuality = DEFAULT_QUALITY; + break; + case GTI_FONTQ_DRAFT: + _s.fontQuality = DRAFT_QUALITY; + break; + } + } + break; + + case GTI_SCREENHEIGHT: + pInfo->pResult = hb_itemPutNI( pInfo->pResult, _s.PTEXTSIZE.y * _s.ROWS ); + iVal = hb_itemGetNI( pInfo->pNewVal ); + if( iVal > 0 ) + { + hb_gtSetMode( (USHORT) ( iVal / _s.PTEXTSIZE.y ), _s.COLS ); + } + break; + + case GTI_SCREENWIDTH: + pInfo->pResult = hb_itemPutNI( pInfo->pResult, _s.PTEXTSIZE.x * _s.COLS ); + iVal = hb_itemGetNI( pInfo->pNewVal ); + if( iVal > 0 ) + { + hb_gtSetMode( _s.ROWS, (USHORT) ( iVal / _s.PTEXTSIZE.x ) ); + } + break; + + case GTI_DESKTOPWIDTH: + { + RECT rDesk; + HWND hDesk; + + hDesk = GetDesktopWindow(); + GetWindowRect( hDesk, &rDesk ); + pInfo->pResult = hb_itemPutNI( pInfo->pResult, rDesk.right - rDesk.left ); + break; + } + case GTI_DESKTOPHEIGHT: + { + RECT rDesk; + HWND hDesk = GetDesktopWindow(); + GetWindowRect( hDesk, &rDesk ); + pInfo->pResult = hb_itemPutNI( pInfo->pResult, rDesk.bottom - rDesk.top ); + break; + } + case GTI_DESKTOPCOLS: + { + RECT rDesk; + HWND hDesk; + hDesk = GetDesktopWindow(); + GetClientRect( hDesk, &rDesk ); + pInfo->pResult = hb_itemPutNI( pInfo->pResult, + ( rDesk.right - rDesk.left ) / _s.PTEXTSIZE.x ); + break; + } + case GTI_DESKTOPROWS: + { + RECT rDesk; + HWND hDesk; + hDesk = GetDesktopWindow(); + GetClientRect( hDesk, &rDesk ); + pInfo->pResult = hb_itemPutNI( pInfo->pResult, + ( rDesk.bottom - rDesk.top ) / _s.PTEXTSIZE.y ); + break; + } + case GTI_WINTITLE: + pInfo->pResult = hb_itemPutC( pInfo->pResult, "" ); + if( hb_itemType( pInfo->pNewVal ) & HB_IT_STRING ) + { + hb_gt_wvt_SetWindowTitle( hb_itemGetCPtr( pInfo->pNewVal ) ); + } + break; + + case GTI_CODEPAGE: + pInfo->pResult = hb_itemPutNI( pInfo->pResult, _s.CodePage ); + iVal = hb_itemGetNI( pInfo->pNewVal ); + if( iVal > 0 && iVal != _s.CodePage ) + { + _s.CodePage = iVal; + hb_gt_wvt_ResetWindowSize( _s.hWnd ); + } + break; + + case GTI_ICONFILE: + { + HICON hIcon = 0; + if( hb_itemType( pInfo->pNewVal ) & HB_IT_STRING ) + { + hIcon = ( HICON ) LoadImage( ( HINSTANCE ) NULL, + hb_itemGetCPtr( pInfo->pNewVal ), + IMAGE_ICON, 0, 0, LR_LOADFROMFILE ); + if ( hIcon ) + { + SendMessage( _s.hWnd, WM_SETICON, ICON_SMALL, ( LPARAM ) hIcon ); /* Set Title Bar Icon */ + SendMessage( _s.hWnd, WM_SETICON, ICON_BIG , ( LPARAM ) hIcon ); /* Set Task List Icon */ + } + } + pInfo->pResult = hb_itemPutNInt( pInfo->pResult, ( UINT_PTR ) hIcon ); + break; + } + + case GTI_ICONRES: + { + HICON hIcon = 0; + if( hb_itemType( pInfo->pNewVal ) & HB_IT_STRING ) + { + hIcon = LoadIcon( ( HINSTANCE ) s_hInstance, + hb_itemGetCPtr( pInfo->pNewVal ) ); + } + else if ( hb_itemType( pInfo->pNewVal ) & HB_IT_NUMERIC ) + { + hIcon = LoadIcon( ( HINSTANCE ) s_hInstance, + MAKEINTRESOURCE( ( UINT_PTR ) + hb_itemGetNInt( pInfo->pNewVal ) ) ); + } + if ( hIcon ) + { + SendMessage( _s.hWnd, WM_SETICON, ICON_SMALL, ( LPARAM ) hIcon ); /* Set Title Bar Icon */ + SendMessage( _s.hWnd, WM_SETICON, ICON_BIG , ( LPARAM ) hIcon ); /* Set Task List Icon */ + } + pInfo->pResult = hb_itemPutNInt( pInfo->pResult, ( UINT_PTR ) hIcon ); + break; + } + case GTI_VIEWMAXWIDTH: + pInfo->pResult = hb_itemPutNI( pInfo->pResult, _s.COLS ); + break; + + case GTI_VIEWMAXHEIGHT: + pInfo->pResult = hb_itemPutNI( pInfo->pResult, _s.ROWS ); + break; + + case GTI_KBDSHIFTS: + return kbdShiftsState(); + + case GTI_CLIPBOARDDATA: + if( hb_itemType( pInfo->pNewVal ) & HB_IT_STRING ) + { + hb_gt_wvt_SetClipboard( hb_itemGetCPtr( pInfo->pNewVal ), + hb_itemGetCLen( pInfo->pNewVal ) ); + } + else + { + char * szClipboardData; + ULONG ulLen; + if( hb_gt_wvt_GetClipboard( &szClipboardData, &ulLen ) ) + { + pInfo->pResult = hb_itemPutCPtr( pInfo->pResult, + szClipboardData, + strlen( szClipboardData ) ); + } + else + { + pInfo->pResult = hb_itemPutC( pInfo->pResult, "" ); + } + } + break; + + case GTI_CURSORBLINKRATE: + pInfo->pResult = hb_itemPutNI( pInfo->pResult, GetCaretBlinkTime() ); + if( hb_itemType( pInfo->pNewVal ) & HB_IT_NUMERIC ) + SetCaretBlinkTime( hb_itemGetNI( pInfo->pNewVal ) ); + break; + + default: + return HB_GTSUPER_INFO( iType, pInfo ); + } + + return TRUE; +} + +/* *********************************************************************** */ + +static void hb_gt_wvt_Redraw( int iRow, int iCol, int iSize ) +{ + HB_TRACE( HB_TR_DEBUG, ( "hb_gt_wvt_Redraw(%d, %d, %d)", iRow, iCol, iSize ) ); + + if ( _s.hWnd ) + { + RECT rect; + + rect.top = rect.bottom = ( SHORT ) iRow; + rect.left = ( SHORT ) iCol; + rect.right = ( SHORT ) ( iCol + iSize - 1 ); + + rect = hb_gt_wvt_GetXYFromColRowRect( rect ); + + InvalidateRect( _s.hWnd, &rect, FALSE ); + } +} + +/* *********************************************************************** */ + +static void hb_gt_wvt_Refresh( void ) +{ + HB_TRACE( HB_TR_DEBUG, ( "hb_gt_wvt_Refresh()") ); + + HB_GTSUPER_REFRESH(); + + if ( _s.hWnd ) + { + SendMessage( _s.hWnd, WM_MY_UPDATE_CARET, 0, 0 ); + hb_gt_wvt_ProcessMessages(); + } +} + +/* *********************************************************************** */ + +static BOOL hb_gt_FuncInit( PHB_GT_FUNCS pFuncTable ) +{ + HB_TRACE(HB_TR_DEBUG, ("hb_gt_FuncInit(%p)", pFuncTable)); + + pFuncTable->Init = hb_gt_wvt_Init; + pFuncTable->Exit = hb_gt_wvt_Exit; + pFuncTable->SetMode = hb_gt_wvt_SetMode; + pFuncTable->Redraw = hb_gt_wvt_Redraw; + pFuncTable->Refresh = hb_gt_wvt_Refresh; + pFuncTable->Version = hb_gt_wvt_Version; + pFuncTable->Tone = hb_gt_wvt_Tone; + pFuncTable->Info = hb_gt_wvt_Info; + + pFuncTable->ReadKey = hb_gt_wvt_ReadKey; + + pFuncTable->MouseIsPresent = hb_gt_wvt_mouse_IsPresent; + pFuncTable->MouseGetPos = hb_gt_wvt_mouse_GetPos; + pFuncTable->MouseButtonState = hb_gt_wvt_mouse_ButtonState; + pFuncTable->MouseCountButton = hb_gt_wvt_mouse_CountButton; + +// pFuncTable->GfxPrimitive = hb_gt_wvt_gfx_Primitive; + + return TRUE; +} + +/* ********************************************************************** */ + +static HB_GT_INIT gtInit = { HB_GT_DRVNAME( HB_GT_NAME ), + hb_gt_FuncInit, + HB_GTSUPER }; + +HB_GT_ANNOUNCE( HB_GT_NAME ); + +HB_CALL_ON_STARTUP_BEGIN( _hb_startup_gt_Init_ ) + hb_gtRegister( >Init ); +HB_CALL_ON_STARTUP_END( _hb_startup_gt_Init_ ) + +#if defined( HB_PRAGMA_STARTUP ) + #pragma startup _hb_startup_gt_Init_ +#elif defined(HB_MSC_STARTUP) + #if _MSC_VER >= 1010 + #pragma data_seg( ".CRT$XIY" ) + #pragma comment( linker, "/Merge:.CRT=.data" ) + #else + #pragma data_seg( "XIY" ) + #endif + static HB_$INITSYM hb_vm_auto__hb_startup_gt_Init_ = _hb_startup_gt_Init_; + #pragma data_seg() +#endif diff --git a/harbour/source/rtl/gtwvt/gtwvt.h b/harbour/source/rtl/gtwvt/gtwvt.h new file mode 100644 index 0000000000..8997c58eaf --- /dev/null +++ b/harbour/source/rtl/gtwvt/gtwvt.h @@ -0,0 +1,162 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Header File for Video subsystem for Win32 using GUI windows instead of Console + * Copyright 2003 Peter Rees + * Rees Software & Systems Ltd + * www - http://www.harbour-project.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +#ifndef HB_WVT_H_ + +#define HB_WVT_H_ + +#define HB_GT_NAME WVT + +/* #define WVT_DEBUG */ + +#include +/*#include */ +/*#include */ + +#include "hbset.h" +#include "hbgtcore.h" +#include "hbinit.h" +#include "hbapierr.h" +#include "hbapiitm.h" +#include "inkey.ch" +#include "error.ch" +#include "hbvm.h" +#include "hbgfxdef.ch" + + +#define WVT_CHAR_QUEUE_SIZE 128 +#define WVT_MAX_ROWS 256 +#define WVT_MAX_COLS 256 +#define WVT_DEFAULT_ROWS 25 +#define WVT_DEFAULT_COLS 80 + +#define BLACK RGB( 0x0 ,0x0 ,0x0 ) +#define BLUE RGB( 0x0 ,0x0 ,0x85 ) +#define GREEN RGB( 0x0 ,0x85,0x0 ) +#define CYAN RGB( 0x0 ,0x85,0x85 ) +#define RED RGB( 0x85,0x0 ,0x0 ) +#define MAGENTA RGB( 0x85,0x0 ,0x85 ) +#define BROWN RGB( 0x85,0x85,0x0 ) +#define WHITE RGB( 0xC6,0xC6,0xC6 ) +#define LIGHT_GRAY RGB( 0x60,0x60,0x60 ) +#define BRIGHT_BLUE RGB( 0x00,0x00,0xFF ) +#define BRIGHT_GREEN RGB( 0x60,0xFF,0x60 ) +#define BRIGHT_CYAN RGB( 0x60,0xFF,0xFF ) +#define BRIGHT_RED RGB( 0xF8,0x00,0x26 ) +#define BRIGHT_MAGENTA RGB( 0xFF,0x60,0xFF ) +#define YELLOW RGB( 0xFF,0xFF,0x00 ) +#define BRIGHT_WHITE RGB( 0xFF,0xFF,0xFF ) + +#define WM_MY_UPDATE_CARET ( WM_USER + 0x0101 ) + +typedef struct global_data +{ + USHORT ROWS; /* number of displayable rows in window */ + USHORT COLS; /* number of displayable columns in window */ + COLORREF foreground; /* forground colour */ + COLORREF background; /* background colour */ + + BOOL CaretExist; /* TRUE if a caret has been created */ + BOOL CaretHidden; /* TRUE if a caret has been hiden */ + int CaretSize; /* Size of solid caret */ + + POINT mousePos; /* the last mouse position */ + BOOL MouseMove; /* Flag to say whether to return mouse movement events */ + + int Keys[ WVT_CHAR_QUEUE_SIZE ]; /* Array to hold the characters & events */ + int keyPointerIn; /* Offset into key array for character to be placed */ + int keyPointerOut; /* Offset into key array of next character to read */ + int keyLast; /* last inkey code value in buffer */ + + POINT PTEXTSIZE; /* size of the fixed width font */ + BOOL FixedFont; /* TRUE if current font is a fixed font */ + int FixedSize[ WVT_MAX_COLS ]; /* buffer for ExtTextOut() to emulate fixed pitch when Proportional font selected */ + int fontHeight; /* requested font height */ + int fontWidth ; /* requested font width */ + int fontWeight; /* Bold level */ + int fontQuality; /* requested font quality */ + char fontFace[ LF_FACESIZE ]; /* requested font face name LF_FACESIZE #defined in wingdi.h */ + HFONT hFont; /* current font handle */ + + HWND hWnd; /* the window handle */ + + HDC hdc; /* Handle to Windows Device Context */ + + int CodePage; /* Code page to use for display characters */ + BOOL Win9X; /* Flag to say if running on Win9X not NT/2000/XP */ + BOOL AltF4Close; /* Can use Alt+F4 to close application */ + BOOL CentreWindow; /* True if window is to be Reset into centre of window */ + + BOOL fIgnoreWM_SYSCHAR; + +} GLOBAL_DATA; +typedef GLOBAL_DATA * LPGLOBAL_DATA; + +/* Harbour compatible definitions */ +#define K_SH_LEFT K_LEFT /* Shift-Left == Left */ +#define K_SH_UP K_UP /* Shift-Up == Up */ +#define K_SH_RIGHT K_RIGHT /* Shift-Right == Right */ +#define K_SH_DOWN K_DOWN /* Shift-Down == Down */ +#define K_SH_INS K_INS /* Shift-Ins == Ins */ +#define K_SH_DEL K_DEL /* Shift-Del == Del */ +#define K_SH_HOME K_HOME /* Shift-Home == Home */ +#define K_SH_END K_END /* Shift-End == End */ +#define K_SH_PGUP K_PGUP /* Shift-PgUp == PgUp */ +#define K_SH_PGDN K_PGDN /* Shift-PgDn == PgDn */ +#define K_SH_RETURN K_RETURN /* Shift-Enter == Enter */ +#define K_SH_ENTER K_ENTER /* Shift-Enter == Enter */ + +#ifndef WM_MOUSEWHEEL + #define WM_MOUSEWHEEL 0x020A +#endif + +#endif /* HB_WVT_H_ */ diff --git a/harbour/source/rtl/gtxwc/gtxwc.c b/harbour/source/rtl/gtxwc/gtxwc.c index 4cd846443e..b217937ad3 100644 --- a/harbour/source/rtl/gtxwc/gtxwc.c +++ b/harbour/source/rtl/gtxwc/gtxwc.c @@ -2818,18 +2818,21 @@ static void hb_gt_xwc_ProcessMessages( PXWND_DEF wnd ) { XEvent evt; - if( s_cursorBlinkRate == 0 ) + if( wnd->cursorType != SC_NONE ) { - s_cursorState = TRUE; - } - else - { - ULONG ulCurrentTime = hb_gt_xwc_CurrentTime(); - - if( ulCurrentTime - s_cursorStateTime > s_cursorBlinkRate ) + if( s_cursorBlinkRate == 0 ) { - s_cursorState = !s_cursorState; - s_cursorStateTime = ulCurrentTime; + s_cursorState = TRUE; + } + else + { + ULONG ulCurrentTime = hb_gt_xwc_CurrentTime(); + + if( ulCurrentTime - s_cursorStateTime > s_cursorBlinkRate ) + { + s_cursorState = !s_cursorState; + s_cursorStateTime = ulCurrentTime; + } } } @@ -3383,7 +3386,7 @@ static char * hb_gt_xwc_Version( int iType ) if( iType == 0 ) return HB_GT_DRVNAME( HB_GT_NAME ); - return "xHarbour Terminal: XWindow Console XWC"; + return "Harbour Terminal: XWindow Console XWC"; } /* *********************************************************************** */ @@ -3432,6 +3435,8 @@ static void hb_gt_xwc_Tone( double dFrequency, double dDuration ) static BOOL hb_gt_xwc_mouse_IsPresent( void ) { + HB_TRACE(HB_TR_DEBUG, ("hb_gt_xwc_mouse_IsPresent()")); + return s_wnd->mouseNumButtons > 0; } @@ -3439,6 +3444,8 @@ static BOOL hb_gt_xwc_mouse_IsPresent( void ) static void hb_gt_xwc_mouse_GetPos( int * piRow, int * piCol ) { + HB_TRACE(HB_TR_DEBUG, ("hb_gt_xwc_mouse_GetPos(%p,%p)", piRow, piCol)); + hb_gt_xwc_LateRefresh(); *piRow = s_wnd->mouseGotoRow; *piCol = s_wnd->mouseGotoCol; @@ -3448,6 +3455,8 @@ static void hb_gt_xwc_mouse_GetPos( int * piRow, int * piCol ) static void hb_gt_xwc_mouse_SetPos( int iRow, int iCol ) { + HB_TRACE(HB_TR_DEBUG, ("hb_gt_xwc_mouse_SetPos(%d,%d)", iRow, iCol)); + s_wnd->mouseGotoRow = iRow; s_wnd->mouseGotoCol = iCol; hb_gt_xwc_LateRefresh(); @@ -3457,7 +3466,7 @@ static void hb_gt_xwc_mouse_SetPos( int iRow, int iCol ) static BOOL hb_gt_xwc_mouse_ButtonState( int iButton ) { - HB_TRACE( HB_TR_DEBUG, ( "hb_gt_xwc_mouse_ButtonState(%i)", iButton ) ); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_xwc_mouse_ButtonState(%i)", iButton)); if( iButton >= 0 && iButton < s_wnd->mouseNumButtons ) return ( s_wnd->mouseButtonsState & 1 << iButton ) != 0; @@ -3469,7 +3478,7 @@ static BOOL hb_gt_xwc_mouse_ButtonState( int iButton ) static int hb_gt_xwc_mouse_CountButton( void ) { - HB_TRACE( HB_TR_DEBUG, ( "hb_gt_xwc_mouse_CountButton()") ); + HB_TRACE(HB_TR_DEBUG, ("hb_gt_xwc_mouse_CountButton()")); hb_gt_xwc_RealRefresh(); @@ -3612,7 +3621,7 @@ static BOOL hb_gt_xwc_Info( int iType, PHB_GT_INFO pInfo ) pInfo->pResult = hb_itemPutNI( pInfo->pResult, s_wnd->fontWidth ); iVal = hb_itemGetNI( pInfo->pNewVal ); if( iVal > 0 ) /* TODO */ - s_wnd->fontWidth = iVal; + s_wnd->fontWidth = iVal; break; case GTI_FONTNAME: @@ -3857,7 +3866,16 @@ static void hb_gt_xwc_Redraw( int iRow, int iCol, int iSize ) { if( s_wnd->fInit ) { +#if 1 hb_gt_xwc_InvalidateChar( s_wnd, iCol, iRow, iCol + iSize - 1, iRow ); +#else + hb_gt_xwc_RepaintChar( s_wnd, iCol, iRow, iCol + iSize - 1, iRow ); + iCol *= s_wnd->fontWidth; + iRow *= s_wnd->fontHeight; + hb_gt_xwc_InvalidatePts( s_wnd, iCol, iRow, + iCol + iSize * s_wnd->fontWidth - 1, + iRow + s_wnd->fontHeight - 1 ); +#endif } else if( !s_wnd->fData ) { diff --git a/harbour/source/rtl/hbffind.c b/harbour/source/rtl/hbffind.c index 73c8a42ec5..d1e13e588b 100644 --- a/harbour/source/rtl/hbffind.c +++ b/harbour/source/rtl/hbffind.c @@ -876,6 +876,7 @@ void hb_fsFindClose( PHB_FFIND ffind ) #elif defined(HB_OS_WIN_32) + if( info->hFindFile != INVALID_HANDLE_VALUE ) { FindClose( info->hFindFile ); } diff --git a/harbour/source/rtl/strmatch.c b/harbour/source/rtl/strmatch.c index d28bf530ad..8664f8098a 100644 --- a/harbour/source/rtl/strmatch.c +++ b/harbour/source/rtl/strmatch.c @@ -102,7 +102,9 @@ static BOOL hb_strMatchDOS( const char * pszString, const char * pszMask ) HB_EXPORT BOOL hb_strMatchWild( const char *szString, const char *szPattern ) { BOOL fMatch = TRUE, fAny = FALSE; - ULONG ulAnyPosP[HB_MAX_WILDPATTERN], ulAnyPosV[HB_MAX_WILDPATTERN], + ULONG pulBufPosP[ HB_MAX_WILDPATTERN ], pulBufPosV[ HB_MAX_WILDPATTERN ], + ulBufSize = HB_MAX_WILDPATTERN; + ULONG * ulAnyPosP = pulBufPosP, * ulAnyPosV = pulBufPosV, ulSize, ulLen, ulAny, i, j; i = j = ulAny = 0; @@ -119,12 +121,24 @@ HB_EXPORT BOOL hb_strMatchWild( const char *szString, const char *szPattern ) { if ( fAny ) { - if ( ulAny < HB_MAX_WILDPATTERN ) + if ( ulAny >= ulBufSize ) { - ulAnyPosP[ulAny] = i; - ulAnyPosV[ulAny] = j; - ulAny++; + if( ( ulBufSize <<= 1 ) == ( HB_MAX_WILDPATTERN << 1 ) ) + { + ulAnyPosP = ( ULONG * ) hb_xgrab( ulBufSize * sizeof( ULONG ) ); + ulAnyPosV = ( ULONG * ) hb_xgrab( ulBufSize * sizeof( ULONG ) ); + memcpy( ulAnyPosP, pulBufPosP, HB_MAX_WILDPATTERN * sizeof( ULONG ) ); + memcpy( ulAnyPosV, pulBufPosV, HB_MAX_WILDPATTERN * sizeof( ULONG ) ); + } + else + { + ulAnyPosP = ( ULONG * ) hb_xrealloc( ulAnyPosP, ulBufSize * sizeof( ULONG ) ); + ulAnyPosV = ( ULONG * ) hb_xrealloc( ulAnyPosV, ulBufSize * sizeof( ULONG ) ); + } } + ulAnyPosP[ulAny] = i; + ulAnyPosV[ulAny] = j; + ulAny++; fAny = FALSE; } j++; @@ -147,9 +161,92 @@ HB_EXPORT BOOL hb_strMatchWild( const char *szString, const char *szPattern ) break; } } + if( ulBufSize > HB_MAX_WILDPATTERN ) + { + hb_xfree( ulAnyPosP ); + hb_xfree( ulAnyPosV ); + } return fMatch; } +HB_EXPORT BOOL hb_strMatchWildExact( const char *szString, const char *szPattern ) +{ + BOOL fMatch = TRUE, fAny = FALSE; + ULONG pulBufPosP[ HB_MAX_WILDPATTERN ], pulBufPosV[ HB_MAX_WILDPATTERN ], + ulBufSize = HB_MAX_WILDPATTERN; + ULONG * ulAnyPosP = pulBufPosP, * ulAnyPosV = pulBufPosV, + ulSize, ulLen, ulAny, i, j; + + i = j = ulAny = 0; + ulLen = strlen( szString ); + ulSize = strlen( szPattern ); + while ( i < ulSize || ( j < ulLen && !fAny ) ) + { + if ( i < ulSize && szPattern[i] == '*' ) + { + fAny = TRUE; + i++; + } + else if ( j < ulLen && i < ulSize && + ( szPattern[i] == '?' || szPattern[i] == szString[j] ) ) + { + if ( fAny ) + { + if ( ulAny >= ulBufSize ) + { + if( ( ulBufSize <<= 1 ) == ( HB_MAX_WILDPATTERN << 1 ) ) + { + ulAnyPosP = ( ULONG * ) hb_xgrab( ulBufSize * sizeof( ULONG ) ); + ulAnyPosV = ( ULONG * ) hb_xgrab( ulBufSize * sizeof( ULONG ) ); + memcpy( ulAnyPosP, pulBufPosP, HB_MAX_WILDPATTERN * sizeof( ULONG ) ); + memcpy( ulAnyPosV, pulBufPosV, HB_MAX_WILDPATTERN * sizeof( ULONG ) ); + } + else + { + ulAnyPosP = ( ULONG * ) hb_xrealloc( ulAnyPosP, ulBufSize * sizeof( ULONG ) ); + ulAnyPosV = ( ULONG * ) hb_xrealloc( ulAnyPosV, ulBufSize * sizeof( ULONG ) ); + } + } + ulAnyPosP[ulAny] = i; + ulAnyPosV[ulAny] = j; + ulAny++; + fAny = FALSE; + } + j++; + i++; + } + else if ( fAny && j < ulLen ) + { + j++; + } + else if ( ulAny > 0 ) + { + ulAny--; + i = ulAnyPosP[ulAny]; + j = ulAnyPosV[ulAny] + 1; + fAny = TRUE; + } + else + { + fMatch = FALSE; + break; + } + } + if( ulBufSize > HB_MAX_WILDPATTERN ) + { + hb_xfree( ulAnyPosP ); + hb_xfree( ulAnyPosV ); + } + return fMatch; +} + +HB_FUNC( WILDMATCH ) +{ + hb_retl( ( ! ISCHAR( 1 ) || ! ISCHAR( 2 ) ) ? FALSE : + hb_parl( 3 ) ? hb_strMatchWildExact( hb_parc( 2 ), hb_parc( 1 ) ) : + hb_strMatchWild( hb_parc( 2 ), hb_parc( 1 ) ) ); +} + /* TODO: Replace it with a code that supports real regular expressions * @@ -162,11 +259,14 @@ BOOL hb_strMatchRegExp( const char * szString, const char * szMask ) } /* - * WildMatch( cPattern, cValue ) compares cValue ith cPattern, cPattern - * may contain wildcard characters (?*) + * WildMatch( cPattern, cValue [, lExact] ) compares + * cValue with cPattern, cPattern * may contain wildcard characters (?*) + * When lExact is TRUE then it will check if whole cValue is covered by + * cPattern else if will check if cPatern is a prefix of cValue */ HB_FUNC( HB_WILDMATCH ) { hb_retl( ( ! ISCHAR( 1 ) || ! ISCHAR( 2 ) ) ? FALSE : - hb_strMatchWild( hb_parc( 2 ), hb_parc( 1 ) ) ); + hb_parl( 3 ) ? hb_strMatchWildExact( hb_parc( 2 ), hb_parc( 1 ) ) : + hb_strMatchWild( hb_parc( 2 ), hb_parc( 1 ) ) ); } diff --git a/harbour/source/vm/Makefile b/harbour/source/vm/Makefile index 4208e856e8..7b25729241 100644 --- a/harbour/source/vm/Makefile +++ b/harbour/source/vm/Makefile @@ -5,12 +5,17 @@ ROOT = ../../ ifeq ($(HB_ARCHITECTURE),w32) - C_MAIN := mainstd.c mainwin.c + ifeq ($(HB_COMPILER),mingw32) + C_MAIN = mainwin.c + DIRS = mainstd + else + C_MAIN = mainstd.c mainwin.c + endif else ifeq ($(HB_ARCHITECTURE),os2) - C_MAIN := mainstd.c mainpm.c + C_MAIN = mainstd.c mainpm.c else - C_MAIN := main.c + C_MAIN = main.c endif endif @@ -50,3 +55,6 @@ PRG_SOURCES=\ LIBNAME=vm include $(TOP)$(ROOT)config/lib.cf +ifneq ($(DIRS),) + include $(TOP)$(ROOT)config/dir.cf +endif diff --git a/harbour/source/vm/cmdarg.c b/harbour/source/vm/cmdarg.c index b25e1f788b..234e4a9d8a 100644 --- a/harbour/source/vm/cmdarg.c +++ b/harbour/source/vm/cmdarg.c @@ -50,6 +50,8 @@ * */ +#define HB_OS_WIN_32_USED + #include "hbvmopt.h" #include "hbapi.h" #include "hbapiitm.h" @@ -61,7 +63,38 @@ static int s_argc = 0; static char ** s_argv = NULL; -static char * hb_cmdargGet( const char * pszName, BOOL bRetValue ); +#if defined( HB_OS_WIN_32 ) && defined( HB_OS_WIN_32_USED ) + +HB_EXTERN_BEGIN + +HANDLE hb_hInstance = 0; +HANDLE hb_hPrevInstance = 0; +int s_iCmdShow = 0; +BOOL s_WinMainParam = FALSE; + +HB_EXTERN_END + +HB_EXPORT void hb_winmainArgInit( HANDLE hInstance, HANDLE hPrevInstance, int iCmdShow ) +{ + hb_hInstance = hInstance; + hb_hPrevInstance = hPrevInstance; + s_iCmdShow = iCmdShow; + s_WinMainParam = TRUE; +} + +HB_EXPORT BOOL hb_winmainArgGet( HANDLE * phInstance, HANDLE * phPrevInstance, int * piCmdShow ) +{ + if( phInstance ) + *phInstance = hb_hInstance; + if( phPrevInstance ) + *phPrevInstance = hb_hPrevInstance; + if( piCmdShow ) + *piCmdShow = s_iCmdShow; + + return s_WinMainParam; +} + +#endif HB_EXPORT void hb_cmdargInit( int argc, char * argv[] ) { diff --git a/harbour/source/vm/mainstd/Makefile b/harbour/source/vm/mainstd/Makefile new file mode 100644 index 0000000000..0607e627d8 --- /dev/null +++ b/harbour/source/vm/mainstd/Makefile @@ -0,0 +1,14 @@ +# +# $Id$ +# + +vpath %.c ../ + +ROOT = ../../../ + +C_SOURCES=\ + mainstd.c \ + +LIBNAME=mainstd + +include $(TOP)$(ROOT)config/lib.cf diff --git a/harbour/source/vm/mainwin.c b/harbour/source/vm/mainwin.c index d678e5a007..b0f12c0a73 100644 --- a/harbour/source/vm/mainwin.c +++ b/harbour/source/vm/mainwin.c @@ -56,67 +56,72 @@ #include "hbvm.h" #if defined(HB_OS_WIN_32) -HB_EXTERN_BEGIN -int argc = 0; -char * argv[ 20 ]; +#define MAX_ARGS 128 -HANDLE hb_hInstance = 0; -HANDLE hb_hPrevInstance = 0; +static int s_argc = 0; +static char * s_argv[ MAX_ARGS ]; +static char s_szAppName[ 256 ]; int WINAPI WinMain( HINSTANCE hInstance, /* handle to current instance */ HINSTANCE hPrevInstance, /* handle to previous instance */ LPSTR lpCmdLine, /* pointer to command line */ int iCmdShow ) /* show state of window */ { + LPSTR pArgs, pArg, pDst, pSrc; + BOOL fQuoted; + #ifdef HB_INCLUDE_WINEXCHANDLER + { LONG WINAPI hb_UnhandledExceptionFilter( struct _EXCEPTION_POINTERS * ExceptionInfo ); - LPTOP_LEVEL_EXCEPTION_FILTER ef = SetUnhandledExceptionFilter( hb_UnhandledExceptionFilter ); - #endif - - LPSTR pArgs = ( LPSTR ) LocalAlloc( LMEM_FIXED, strlen( lpCmdLine ) + 1 ), pArg = pArgs; - char szAppName[ 250 ]; - - #ifdef HB_INCLUDE_WINEXCHANDLER HB_SYMBOL_UNUSED( ef ); + } #endif - strcpy( pArgs, lpCmdLine ); - HB_TRACE(HB_TR_DEBUG, ("WinMain(%p, %p, %s, %d)", hInstance, hPrevInstance, lpCmdLine, iCmdShow)); - HB_SYMBOL_UNUSED( hPrevInstance ); - HB_SYMBOL_UNUSED( iCmdShow ); + GetModuleFileName( hInstance, s_szAppName, sizeof( s_szAppName ) - 1 ); + s_argv[ s_argc++ ] = s_szAppName; - hb_hInstance = hInstance; - GetModuleFileName( hInstance, szAppName, 249 ); - argv[ 0 ] = szAppName; + pDst = pArgs = ( LPSTR ) LocalAlloc( LMEM_FIXED, strlen( lpCmdLine ) + 1 ); + pArg = NULL; + pSrc = lpCmdLine; + fQuoted = FALSE; - if( * pArgs != 0 ) - argv[ ++argc ] = pArgs; - - while( *pArg != 0 ) + while( *pSrc != 0 && s_argc < MAX_ARGS ) { - if( *pArg == ' ' ) + if( *pSrc == '"' ) { - *pArg++ = 0; - argc++; - - while( *pArg == ' ' ) - pArg++; - - if( *pArg != 0 ) - argv[ argc ] = pArg++; - else - argc--; + if( pArg == NULL ) + pArg = pDst; + fQuoted = !fQuoted; + } + else if( fQuoted || !HB_ISSPACE ( *pSrc ) ) + { + if( pArg == NULL ) + pArg = pDst; + *pDst++ = *pSrc; } else - pArg++; + { + if( pArg ) + { + *pDst++ = '\0'; + s_argv[ s_argc++ ] = pArg; + pArg = NULL; + } + } + ++pSrc; + } + if( pArg ) + { + *pDst = '\0'; + s_argv[ s_argc++ ] = pArg; } - argc++; - hb_cmdargInit( argc, argv ); + hb_winmainArgInit( hInstance, hPrevInstance, iCmdShow ); + hb_cmdargInit( s_argc, s_argv ); hb_vmInit( TRUE ); hb_vmQuit(); @@ -127,12 +132,12 @@ int WINAPI WinMain( HINSTANCE hInstance, /* handle to current instance */ /* NOTE: This point is never reached */ return 0; -} +} #if ( defined(__WATCOMC__) || defined(__MINGW32__) ) && !defined(__EXPORT__) +HB_EXTERN_BEGIN HB_EXPORT void hb_forceLinkMainWin( void ) {} -#endif - HB_EXTERN_END +#endif #endif