From b817f4fbb59837d7dbdf387141f3f81cba9abfe5 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 14 Mar 1996 18:08:34 +0000 Subject: [PATCH] Release 960314 Wed Mar 13 19:46:50 1996 Alexandre Julliard * [controls/edit.c] Removed calls to memmove (not portable). * [debugger/dbg.y] [debugger/debug.l] Prefixed all token with 't' to avoid conflicts with type definitions. Added 'walk queue', 'walk class' and 'info class' commands. * [debugger/info.c] Moved queue and window information functions to windows/queue.c and windows/win.c respectively. * [loader/signal.c] Added SIGHUP handling to force entry into built-in debugger. Cleaned up a bit. * [misc/spy.c] General cleanup and performance improvements. * [windows/class.c] Added CLASS_DumpClass() and CLASS_WalkClasses() functions for debugger. * [windows/event.c] Pressing Ctrl-Alt-Return forces an entry into the debugger. Not sure if this key combination is a good choice... * [windows/message.c] [windows/queue.c] (New file) Moved message queue handling functions to windows/queue.c. Tue Mar 12 14:55:16 1996 Onno Hovers * [if1632/except.S] [include/except.h] [win32/except.c] (New files) Implemented Win32 exception functions: RaiseException(), RtlUnwind(), SetUnhandledExceptionFilter() and UnhandledExceptionFilter(). Mon Mar 11 19:23:29 1996 Albrecht Kleine * [controls/listbox.c] [include/listbox.h] Special handling for COMBOLBOX styles introduced via extension of HEADLIST structure: lphl->dwStyle. Mon Mar 11 13:31:06 1996 Greg Kreider * [controls/combo.c] Any mouse movement within a small distance (defined by CBLMM_EDGE) of the top or bottom edge causes the window to scroll. Also moved some assignments so the routine works correctly. * [controls/listbox.c] Changing selection in ListBoxSetCurSel now updates PrevFocused. Added to LBSetFont and CreateListBoxStruct a fake hdc that tests and sets the standard text height. Sun Mar 10 08:39:23 1996 Alex Korobka * [windows/dce.c] Fixed memory leak in DCE_ClipWindows(). --- ANNOUNCE | 17 +- ChangeLog | 68 ++++++ configure | 245 ++++++++++++++-------- controls/combo.c | 37 ++-- controls/edit.c | 10 +- controls/listbox.c | 127 ++++++------ debugger/dbg.y | 237 +++++++++++---------- debugger/debug.l | 115 +++++----- debugger/hash.c | 1 - debugger/info.c | 183 ---------------- if1632/Makefile.in | 3 +- if1632/except.S | 192 +++++++++++++++++ if1632/kernel32.spec | 6 +- if1632/keyboard.spec | 2 +- if1632/user.spec | 2 +- include/class.h | 9 +- include/debugger.h | 4 - include/except.h | 283 +++++++++++++++++++++++++ include/kernel32.h | 1 + include/listbox.h | 1 + include/message.h | 71 +------ include/queue.h | 83 ++++++++ include/spy.h | 16 +- include/task.h | 2 +- include/win.h | 2 + include/windows.h | 14 +- loader/main.c | 10 +- loader/signal.c | 238 ++++++++++----------- loader/task.c | 10 +- misc/shell.c | 4 +- misc/spy.c | 252 ++++++++++------------ misc/user.c | 50 ++--- win32/Makefile.in | 1 + win32/except.c | 212 +++++++++++++++++++ win32/newfns.c | 13 -- windows/Makefile.in | 1 + windows/class.c | 66 ++++++ windows/dce.c | 6 +- windows/defwnd.c | 2 +- windows/event.c | 14 +- windows/hook.c | 2 +- windows/message.c | 457 +++------------------------------------- windows/painting.c | 12 +- windows/queue.c | 484 +++++++++++++++++++++++++++++++++++++++++++ windows/timer.c | 6 +- windows/win.c | 95 ++++++++- windows/winpos.c | 13 +- 47 files changed, 2275 insertions(+), 1404 deletions(-) create mode 100644 if1632/except.S create mode 100644 include/except.h create mode 100644 include/queue.h create mode 100644 win32/except.c create mode 100644 windows/queue.c diff --git a/ANNOUNCE b/ANNOUNCE index db46d6a3b1b..e9201d24167 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,14 +1,13 @@ -This is release 960309 of Wine the MS Windows emulator. This is still a +This is release 960314 of Wine the MS Windows emulator. This is still a developer's only release. There are many bugs and many unimplemented API features. Most applications still do not work. Patches should be submitted to "julliard@lrc.epfl.ch". Please don't forget to include a ChangeLog entry. -WHAT'S NEW with Wine-960309: (see ChangeLog for details) - - More edit control improvements. - - Help begins to work. - - Internal LZEXPAND.DLL. +WHAT'S NEW with Wine-960314: (see ChangeLog for details) + - Many combo and listbox fixes. + - Win32 exception handling. - Lots of bug fixes. See the README file in the distribution for installation instructions. @@ -17,10 +16,10 @@ Because of lags created by using mirror, this message may reach you before the release is available at the ftp sites. The sources will be available from the following locations: - sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960309.tar.gz - tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960309.tar.gz - ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960309.tar.gz - aris.com:/pub/linux/ALPHA/Wine/development/Wine-960309.tar.gz + sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960314.tar.gz + tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960314.tar.gz + ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960314.tar.gz + aris.com:/pub/linux/ALPHA/Wine/development/Wine-960314.tar.gz It should also be available from any site that mirrors tsx-11 or sunsite. diff --git a/ChangeLog b/ChangeLog index 3191e3e3fc2..93749833c24 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,66 @@ +---------------------------------------------------------------------- +Wed Mar 13 19:46:50 1996 Alexandre Julliard + + * [controls/edit.c] + Removed calls to memmove (not portable). + + * [debugger/dbg.y] [debugger/debug.l] + Prefixed all token with 't' to avoid conflicts with type + definitions. + Added 'walk queue', 'walk class' and 'info class' commands. + + * [debugger/info.c] + Moved queue and window information functions to windows/queue.c + and windows/win.c respectively. + + * [loader/signal.c] + Added SIGHUP handling to force entry into built-in debugger. + Cleaned up a bit. + + * [misc/spy.c] + General cleanup and performance improvements. + + * [windows/class.c] + Added CLASS_DumpClass() and CLASS_WalkClasses() functions for + debugger. + + * [windows/event.c] + Pressing Ctrl-Alt-Return forces an entry into the debugger. Not + sure if this key combination is a good choice... + + * [windows/message.c] [windows/queue.c] (New file) + Moved message queue handling functions to windows/queue.c. + +Tue Mar 12 14:55:16 1996 Onno Hovers + + * [if1632/except.S] [include/except.h] [win32/except.c] (New files) + Implemented Win32 exception functions: RaiseException(), + RtlUnwind(), SetUnhandledExceptionFilter() and + UnhandledExceptionFilter(). + +Mon Mar 11 19:23:29 1996 Albrecht Kleine + + * [controls/listbox.c] [include/listbox.h] + Special handling for COMBOLBOX styles introduced via extension of + HEADLIST structure: lphl->dwStyle. + +Mon Mar 11 13:31:06 1996 Greg Kreider + + * [controls/combo.c] + Any mouse movement within a small distance (defined by CBLMM_EDGE) + of the top or bottom edge causes the window to scroll. Also moved + some assignments so the routine works correctly. + + * [controls/listbox.c] + Changing selection in ListBoxSetCurSel now updates PrevFocused. + Added to LBSetFont and CreateListBoxStruct a fake hdc that tests + and sets the standard text height. + +Sun Mar 10 08:39:23 1996 Alex Korobka + + * [windows/dce.c] + Fixed memory leak in DCE_ClipWindows(). + ---------------------------------------------------------------------- Fri Mar 8 19:07:18 1996 Alexandre Julliard @@ -69,6 +132,11 @@ Mon Mar 4 23:22:40 1996 Jim Peterson * [include/wintypes.h] Added "#define __export". + * [objects/bitblt.c] + Put in a few hacks to make bitblt-ing work when upside-down and/or + mirrored. BITBLT_StretchImage should really be checked over + thoroughly. + * [programs/progman/main.c] Added "#include " for definition of HAVE_WINE_CONSTRUCTOR. diff --git a/configure b/configure index 2ad34151f2b..4e497a1c4cf 100755 --- a/configure +++ b/configure @@ -2,7 +2,7 @@ # From configure.in configure.in 1.00 # Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.7 +# Generated automatically using autoconf version 2.8 # Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation @@ -341,7 +341,7 @@ EOF verbose=yes ;; -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.7" + echo "configure generated by autoconf version 2.8" exit 0 ;; -with-* | --with-*) @@ -506,12 +506,9 @@ fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='echo $CPP $CPPFLAGS 1>&5; -$CPP $CPPFLAGS' -ac_compile='echo ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5; -${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5' -ac_link='echo ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5; -${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5' +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. @@ -644,7 +641,6 @@ else fi done IFS="$ac_save_ifs" - test -z "$ac_cv_prog_CC" && ac_cv_prog_CC="cc" fi fi CC="$ac_cv_prog_CC" @@ -654,6 +650,55 @@ else echo "$ac_t""no" 1>&6 fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + ac_prog_rejected=no + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then @@ -664,7 +709,7 @@ else yes; #endif EOF -if ${CC-cc} -E conftest.c 2>&5 | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:713: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -716,12 +761,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF -eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:771: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : @@ -730,12 +776,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF -eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:786: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : @@ -787,17 +834,20 @@ if test "${with_x+set}" = set; then : fi +# $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then - no_x=yes + # The user explicitly disabled X. + have_x=disabled else if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then - no_x= + # Both variables are already set. + have_x=yes else -if eval "test \"`echo '$''{'ac_cv_path_x'+set}'`\" = set"; then +if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # One or both of the vars are not set, and there is no cached value. -no_x=yes +ac_x_includes=NO ac_x_libraries=NO rm -fr conftestdir if mkdir conftestdir; then cd conftestdir @@ -807,7 +857,6 @@ acfindx: @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"' EOF if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then - no_x= # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} acfindx 2>/dev/null | grep -v make` # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. @@ -831,24 +880,28 @@ EOF rm -fr conftestdir fi -if test "$no_x" = yes; then -test -z "$x_direct_test_library" && x_direct_test_library=Xt -test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc -test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h +if test "$ac_x_includes" = NO; then + # Guess where to find include files, by looking for this one X11 .h file. + test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h + + # First, try using that file with no special directory specified. cat > conftest.$ac_ext < EOF -eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:895: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* - no_x= ac_x_includes= + # We can compile using X headers with no special include directory. +ac_x_includes= else echo "$ac_err" >&5 rm -rf conftest* - for ac_dir in \ + # Look for the header file in a standard set of common directories. + for ac_dir in \ /usr/X11R6/include \ /usr/X11R5/include \ /usr/X11R4/include \ @@ -886,20 +939,26 @@ else ; \ do if test -r "$ac_dir/$x_direct_test_include"; then - no_x= ac_x_includes=$ac_dir + ac_x_includes=$ac_dir break fi done fi rm -f conftest* +fi # $ac_x_includes = NO -# Check for the libraries. -# See if we find them without any special options. -# Don't add to $LIBS permanently. -ac_save_LIBS="$LIBS" -LIBS="-l$x_direct_test_library $LIBS" +if test "$ac_x_libraries" = NO; then + # Check for the libraries. + + test -z "$x_direct_test_library" && x_direct_test_library=Xt + test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc + + # See if we find them without any special options. + # Don't add to $LIBS permanently. + ac_save_LIBS="$LIBS" + LIBS="-l$x_direct_test_library $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* - LIBS="$ac_save_LIBS" no_x= ac_x_libraries= + LIBS="$ac_save_LIBS" +# We can link X programs with no special library path. +ac_x_libraries= else rm -rf conftest* LIBS="$ac_save_LIBS" @@ -953,7 +1014,7 @@ for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \ do for ac_extension in a so sl; do if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then - no_x= ac_x_libraries=$ac_dir + ac_x_libraries=$ac_dir break 2 fi done @@ -961,27 +1022,35 @@ done fi rm -f conftest* -fi -if test "$no_x" = yes; then - ac_cv_path_x="no_x=yes" +fi # $ac_x_libraries = NO + +if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then + # Didn't find X anywhere. Cache the known absence of X. + ac_cv_have_x="have_x=no" else - ac_cv_path_x="no_x= ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" + # Record where we found X for the cache. + ac_cv_have_x="have_x=yes \ + ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries" fi fi fi - eval "$ac_cv_path_x" + eval "$ac_cv_have_x" fi # $with_x != no -if test "$no_x" = yes; then - echo "$ac_t""no" 1>&6 +if test "$have_x" != yes; then + echo "$ac_t""$have_x" 1>&6 + no_x=yes else + # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries - ac_cv_path_x="no_x= ac_x_includes=$x_includes ac_x_libraries=$x_libraries" + # Update the cache value to reflect the command line values. + ac_cv_have_x="have_x=yes \ + ac_x_includes=$x_includes ac_x_libraries=$x_libraries" echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6 fi -if test "$no_x" = yes; then +if test "$no_x" = yes; then # Not all programs may use this symbol, but it does not hurt to define it. X_CFLAGS="$X_CFLAGS -DX_DISPLAY_MISSING" else @@ -1011,14 +1080,14 @@ else # libraries we check for below, so use a different variable. # --interran@uluru.Stanford.EDU, kb@cs.umb.edu. echo $ac_n "checking for -lICE""... $ac_c" 1>&6 -ac_lib_var=`echo ICE | tr '.-/+' '___p'` +ac_lib_var=`echo ICE_IceConnectionNumber | tr '.-/+' '___p'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lICE $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1055,14 +1124,14 @@ fi # libraries were built with DECnet support. And karl@cs.umb.edu says # the Alpha needs dnet_stub (dnet does not exist). echo $ac_n "checking for -ldnet""... $ac_c" 1>&6 -ac_lib_var=`echo dnet | tr '.-/+' '___p'` +ac_lib_var=`echo dnet_dnet_ntoa | tr '.-/+' '___p'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldnet $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1090,14 +1159,14 @@ fi if test $ac_cv_lib_dnet = no; then echo $ac_n "checking for -ldnet_stub""... $ac_c" 1>&6 -ac_lib_var=`echo dnet_stub | tr '.-/+' '___p'` +ac_lib_var=`echo dnet_stub_dnet_ntoa | tr '.-/+' '___p'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldnet_stub $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1130,14 +1199,14 @@ fi # Not sure which flavor of 386 UNIX this is, but it seems harmless to # check for it. echo $ac_n "checking for -lnsl""... $ac_c" 1>&6 -ac_lib_var=`echo nsl | tr '.-/+' '___p'` +ac_lib_var=`echo nsl_t_accept | tr '.-/+' '___p'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1169,14 +1238,14 @@ fi # But -lsocket is broken on IRIX, according to simon@lia.di.epfl.ch. if test "`(uname) 2>/dev/null`" != IRIX; then echo $ac_n "checking for -lsocket""... $ac_c" 1>&6 -ac_lib_var=`echo socket | tr '.-/+' '___p'` +ac_lib_var=`echo socket_socket | tr '.-/+' '___p'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1274,14 +1343,14 @@ then *) ac_lib=l ;; esac echo $ac_n "checking for -l$ac_lib""... $ac_c" 1>&6 -ac_lib_var=`echo $ac_lib | tr '.-/+' '___p'` +ac_lib_var=`echo $ac_lib_yywrap | tr '.-/+' '___p'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-l$ac_lib $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1397,14 +1466,14 @@ test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking for -li386""... $ac_c" 1>&6 -ac_lib_var=`echo i386 | tr '.-/+' '___p'` +ac_lib_var=`echo i386_i386_set_ldt | tr '.-/+' '___p'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-li386 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1444,11 +1513,11 @@ else ac_cv_c_cross=yes else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then ac_cv_c_cross=no else @@ -1469,7 +1538,7 @@ else ac_cv_c_gcc_strength_bug="yes" else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then ac_cv_c_gcc_strength_bug="no" else @@ -1505,7 +1574,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -1557,11 +1626,12 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF -eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1635: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -1590,7 +1660,7 @@ if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1645,7 +1715,7 @@ if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -1719,14 +1789,15 @@ if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF -eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1801: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -1741,7 +1812,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1759,7 +1830,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1780,7 +1851,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -1791,7 +1862,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -eval $ac_link +{ (eval echo configure:1866: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then : else @@ -1815,7 +1886,7 @@ if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -1899,7 +1970,7 @@ trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. cat > conftest.defs <<\EOF -s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%-D\1=\2%g +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g s%\[%\\&%g s%\]%\\&%g @@ -1934,7 +2005,7 @@ do echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.7" + echo "$CONFIG_STATUS generated by autoconf version 2.8" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; diff --git a/controls/combo.c b/controls/combo.c index 6cc8eae6463..338c0c8887c 100644 --- a/controls/combo.c +++ b/controls/combo.c @@ -32,6 +32,9 @@ * I hope no programs rely on the implementation of combos. */ +#define CBLMM_EDGE 4 /* distance inside box which is same as moving mouse + outside box, to trigger scrolling of CBL */ + static HBITMAP hComboBit = 0; static WORD CBitHeight, CBitWidth; @@ -470,6 +473,8 @@ static LRESULT CBSetCurSel(HWND hwnd, WPARAM wParam, LPARAM lParam) wRet = ListBoxSetCurSel(lphl, wParam); + dprintf_combo(stddeb,"CBSetCurSel: hwnd "NPFMT" wp %x lp %lx wRet %d\n", + hwnd,wParam,lParam,wRet); /* SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);*/ InvalidateRect(hwnd, NULL, TRUE); @@ -877,37 +882,41 @@ static LRESULT CBLLButtonUp( HWND hwnd, WPARAM wParam, LPARAM lParam ) static LRESULT CBLMouseMove( HWND hwnd, WPARAM wParam, LPARAM lParam ) { LPHEADLIST lphl = CLBoxGetListHeader(hwnd); - int y; + short y; WORD wRet; - RECT rect, rectsel; /* XXX Broken */ + RECT rect, rectsel; + y = SHIWORD(lParam); + wRet = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam)); + ListBoxGetItemRect(lphl, wRet, &rectsel); + GetClientRect(hwnd, &rect); + + dprintf_combo(stddeb,"CBLMouseMove: hwnd "NPFMT" wp %x lp %lx y %d if %d wret %d %d,%d-%d,%d\n", +hwnd,wParam,lParam,y,lphl->ItemFocused,wRet,rectsel.left,rectsel.top,rectsel.right,rectsel.bottom); + if ((wParam & MK_LBUTTON) != 0) { - y = SHIWORD(lParam); - if (y < 0) { + if (y < CBLMM_EDGE) { if (lphl->FirstVisible > 0) { lphl->FirstVisible--; SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + ListBoxSetCurSel(lphl, wRet); InvalidateRect(hwnd, NULL, TRUE); return 0; } } - GetClientRect(hwnd, &rect); - if (y >= rect.bottom) { + else if (y >= (rect.bottom-CBLMM_EDGE)) { if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) { lphl->FirstVisible++; SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + ListBoxSetCurSel(lphl, wRet); InvalidateRect(hwnd, NULL, TRUE); return 0; } } - if ((y > 0) && (y < (rect.bottom - 4))) { - if ((y < rectsel.top) || (y > rectsel.bottom)) { - wRet = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam)); - if (wRet == lphl->ItemFocused) return 0; - ListBoxSetCurSel(lphl, wRet); - ListBoxGetItemRect(lphl, wRet, &rectsel); - InvalidateRect(hwnd, NULL, TRUE); - } + else { + if ((short) wRet == lphl->ItemFocused) return 0; + ListBoxSetCurSel(lphl, wRet); + InvalidateRect(hwnd, NULL, TRUE); } } diff --git a/controls/edit.c b/controls/edit.c index 04db65b191a..9eeb811de9e 100644 --- a/controls/edit.c +++ b/controls/edit.c @@ -1757,7 +1757,7 @@ static void EDIT_InsertText(HWND hwnd, char *str, int len) { int plen; EDITSTATE *es = EDIT_GetEditState(hwnd); - char *text = EDIT_HeapLock(hwnd, es->hText); + char *p, *text = EDIT_HeapLock(hwnd, es->hText); plen = strlen(text) + len; if (plen + 1 > es->textlen) @@ -1767,7 +1767,7 @@ static void EDIT_InsertText(HWND hwnd, char *str, int len) text = EDIT_HeapLock(hwnd, es->hText); es->textlen = plen + 1; } - memmove(CurrChar + len, CurrChar, strlen(CurrChar) + 1); + for (p = CurrChar + strlen(CurrChar); p >= CurrChar; p--) p[len] = *p; memcpy(CurrChar, str, len); EDIT_BuildTextPointers(hwnd); @@ -1834,7 +1834,7 @@ static void EDIT_KeyTyped(HWND hwnd, short ch) { EDITSTATE *es = EDIT_GetEditState(hwnd); char *text = EDIT_HeapLock(hwnd, es->hText); - char *currchar; + char *currchar, *p; RECT rc; BOOL FullPaint = FALSE; @@ -1890,14 +1890,14 @@ static void EDIT_KeyTyped(HWND hwnd, short ch) /* make space for new character and put char in buffer */ if (ch == '\n') { - memmove(currchar + 2, currchar, strlen(currchar) + 1); + for (p = currchar + strlen(currchar); p >= currchar; p--) p[2] = p[0]; *currchar = '\r'; *(currchar + 1) = '\n'; EDIT_ModTextPointers(hwnd, es->CurrLine + 1, 2); } else { - memmove(currchar + 1, currchar, strlen(currchar) + 1); + for (p = currchar + strlen(currchar); p >= currchar; p--) p[1] = p[0]; *currchar = ch; EDIT_ModTextPointers(hwnd, es->CurrLine + 1, 1); } diff --git a/controls/listbox.c b/controls/listbox.c index 3365cde4c0f..e255cbd0365 100644 --- a/controls/listbox.c +++ b/controls/listbox.c @@ -78,6 +78,7 @@ static void ListBoxInitialize(LPHEADLIST lphl) void CreateListBoxStruct(HWND hwnd, WORD CtlType, LONG styles, HWND parent) { LPHEADLIST lphl; + HDC hdc; lphl = (LPHEADLIST)xmalloc(sizeof(HEADLIST)); SetWindowLong(hwnd, 0, (LONG)lphl); @@ -89,11 +90,27 @@ void CreateListBoxStruct(HWND hwnd, WORD CtlType, LONG styles, HWND parent) lphl->TabStops = NULL; lphl->hFont = GetStockObject(SYSTEM_FONT); lphl->hSelf = hwnd; + if (CtlType==ODT_COMBOBOX) /* use the "faked" style for COMBOLBOX */ + /* LBS_SORT instead CBS_SORT e.g. */ + lphl->dwStyle = MAKELONG(LOWORD(styles),HIWORD(GetWindowLong(hwnd,GWL_STYLE))); + else + lphl->dwStyle = GetWindowLong(hwnd,GWL_STYLE); /* use original style dword */ lphl->hParent = parent; lphl->StdItemHeight = 15; /* FIXME: should get the font height */ lphl->OwnerDrawn = styles & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE); lphl->HasStrings = (styles & LBS_HASSTRINGS) || !lphl->OwnerDrawn; + /* create dummy hdc to set text height */ + if ((hdc = GetDC(0))) + { + TEXTMETRIC tm; + GetTextMetrics( hdc, &tm ); + lphl->StdItemHeight = tm.tmHeight; + dprintf_listbox(stddeb,"CreateListBoxStruct: font height %d\n", + lphl->StdItemHeight); + ReleaseDC( 0, hdc ); + } + if (lphl->OwnerDrawn) { LISTSTRUCT dummyls; @@ -143,9 +160,7 @@ static LPHEADLIST ListBoxGetStorageHeader(HWND hwnd) has the LBS_NOTIFY style */ void ListBoxSendNotification(LPHEADLIST lphl, WORD code) { - DWORD dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE); - - if (dwStyle & LBS_NOTIFY) + if (lphl->dwStyle & LBS_NOTIFY) #ifdef WINELIB32 SendMessage(lphl->hParent, WM_COMMAND, MAKEWPARAM(lphl->CtlID,code), (LPARAM)lphl->hSelf); @@ -223,8 +238,6 @@ LPLISTSTRUCT ListBoxGetItem(LPHEADLIST lphl, UINT uIndex) void ListBoxDrawItem (HWND hwnd, LPHEADLIST lphl, HDC hdc, LPLISTSTRUCT lpls, RECT *rect, WORD itemAction, WORD itemState) { - LONG dwStyle = GetWindowLong(hwnd,GWL_STYLE); - if (lphl->OwnerDrawn) { DRAWITEMSTRUCT *dis = USER_HEAP_LIN_ADDR(lphl->hDrawItemStruct); @@ -251,7 +264,7 @@ void ListBoxDrawItem (HWND hwnd, LPHEADLIST lphl, HDC hdc, LPLISTSTRUCT lpls, FillRect(hdc, rect, GetStockObject(BLACK_BRUSH)); } - if (dwStyle & LBS_USETABSTOPS) { + if (lphl->dwStyle & LBS_USETABSTOPS) { TabbedTextOut(hdc, rect->left + 5, rect->top + 2, (char *)lpls->itemText, strlen((char *)lpls->itemText), lphl->iNumStops, lphl->TabStops, 0); @@ -311,7 +324,7 @@ void ListBoxAskMeasure(LPHEADLIST lphl, LPLISTSTRUCT lpls) lpmeasure->itemHeight = lphl->StdItemHeight; SendMessage(lphl->hParent, WM_MEASUREITEM, 0, (LPARAM)USER_HEAP_SEG_ADDR(hTemp)); - if (GetWindowLong(lphl->hSelf,GWL_STYLE) & LBS_OWNERDRAWFIXED) { + if (lphl->dwStyle & LBS_OWNERDRAWFIXED) { lphl->StdItemHeight = lpmeasure->itemHeight; lphl->needMeasure = FALSE; } @@ -405,10 +418,9 @@ int ListBoxInsertString(LPHEADLIST lphl, UINT uIndex, LPCSTR newstr) int ListBoxAddString(LPHEADLIST lphl, LPCSTR newstr) { - LONG dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE); UINT pos = (UINT) -1; - if (lphl->HasStrings && (dwStyle & LBS_SORT)) { + if (lphl->HasStrings && (lphl->dwStyle & LBS_SORT)) { LPLISTSTRUCT lpls = lphl->lpFirst; for (pos = 0; lpls != NULL; lpls = lpls->lpNext, pos++) if (strcmp(lpls->itemText, newstr) >= 0) @@ -503,7 +515,6 @@ int ListBoxFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr) UINT Count; UINT First = nFirst + 1; LPSTR lpMatchStr = (LPSTR)MatchStr; - LONG dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE); if (First > lphl->ItemsCount) return LB_ERR; @@ -514,7 +525,7 @@ int ListBoxFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr) while(lpls != NULL) { if (lphl->HasStrings) { if (strstr(lpls->itemText, lpMatchStr) == lpls->itemText) return Count; - } else if (dwStyle & LBS_SORT) { + } else if (lphl->dwStyle & LBS_SORT) { /* XXX Do a compare item */ } else @@ -531,7 +542,7 @@ int ListBoxFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr) while (Count < First) { if (lphl->HasStrings) { if (strstr(lpls->itemText, lpMatchStr) == lpls->itemText) return Count; - } else if (dwStyle & LBS_SORT) { + } else if (lphl->dwStyle & LBS_SORT) { /* XXX Do a compare item */ } else { if (lpls->mis.itemData == (DWORD)lpMatchStr) return Count; @@ -572,13 +583,13 @@ int ListBoxResetContent(LPHEADLIST lphl) int ListBoxSetCurSel(LPHEADLIST lphl, WORD wIndex) { LPLISTSTRUCT lpls; - DWORD dwStyle = GetWindowWord(lphl->hSelf,GWL_STYLE); /* use ListBoxSetSel instead */ - if (dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) ) return 0; + if (lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) ) return 0; /* unselect previous item */ if (lphl->ItemFocused != -1) { + lphl->PrevFocused = lphl->ItemFocused; lpls = ListBoxGetItem(lphl, lphl->ItemFocused); if (lpls == 0) return LB_ERR; lpls->itemState = 0; @@ -602,8 +613,7 @@ int ListBoxSetSel(LPHEADLIST lphl, WORD wIndex, WORD state) LPLISTSTRUCT lpls; int n = 0; - if (!(GetWindowLong(lphl->hSelf,GWL_STYLE) & - (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )) + if (!(lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )) return LB_ERR; if (wIndex == (UINT)-1) { @@ -715,7 +725,7 @@ int ListBoxSetItemHeight(LPHEADLIST lphl, WORD wIndex, long height) { LPLISTSTRUCT lpls; - if (!(GetWindowLong(lphl->hSelf,GWL_STYLE) & LBS_OWNERDRAWVARIABLE)) { + if (!(lphl->dwStyle & LBS_OWNERDRAWVARIABLE)) { lphl->StdItemHeight = (short)height; return 0; } @@ -747,7 +757,7 @@ int ListBoxFindNextMatch(LPHEADLIST lphl, WORD wChar) for(; lpls != NULL; lpls = lpls->lpNext, count++) { if (*lpls->itemText != (char)wChar) break; - if (count > lphl->ItemFocused) + if ((short) count > lphl->ItemFocused) return count; } return first; @@ -776,6 +786,7 @@ static LONG LBCreate(HWND hwnd, WORD wParam, LONG lParam) return 0; } + /*********************************************************************** * LBDestroy */ @@ -905,7 +916,6 @@ static LONG LBLButtonDown(HWND hwnd, WORD wParam, LONG lParam) WORD wRet; int y,n; RECT rectsel; - LONG dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE); POINT tmpPOINT; tmpPOINT.x = LOWORD(lParam); tmpPOINT.y = HIWORD(lParam); @@ -918,12 +928,12 @@ static LONG LBLButtonDown(HWND hwnd, WORD wParam, LONG lParam) if (y == -1) return 0; - if (dwStyle & LBS_NOTIFY && y!= LB_ERR ) + if (lphl->dwStyle & LBS_NOTIFY && y!= LB_ERR ) if( SendMessage(lphl->hParent, WM_LBTRACKPOINT, y, lParam) ) return 0; - switch( dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) ) + switch( lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) ) { case LBS_MULTIPLESEL: lphl->ItemFocused = y; @@ -960,7 +970,7 @@ static LONG LBLButtonDown(HWND hwnd, WORD wParam, LONG lParam) } /* invalidate changed items */ - if( dwStyle & LBS_MULTIPLESEL || y!=lphl->PrevFocused ) + if( lphl->dwStyle & LBS_MULTIPLESEL || y!=lphl->PrevFocused ) { ListBoxGetItemRect(lphl, y, &rectsel); InvalidateRect(hwnd, &rectsel, TRUE); @@ -1021,7 +1031,6 @@ static LONG LBMouseMove(HWND hwnd, WORD wParam, LONG lParam) LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); int y,redraw_prev = 0; int iRet; - LONG dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE); RECT rect, rectsel; /* XXX Broken */ dprintf_listbox(stddeb,"LBMouseMove %d %d\n",SLOWORD(lParam),SHIWORD(lParam)); @@ -1050,10 +1059,10 @@ static LONG LBMouseMove(HWND hwnd, WORD wParam, LONG lParam) if (iRet == lphl->ItemFocused || iRet == -1) { return 0; } - if (dwStyle & LBS_MULTIPLESEL) { + if (lphl->dwStyle & LBS_MULTIPLESEL) { lphl->ItemFocused = iRet; ListBoxSendNotification(lphl, LBN_SELCHANGE); - } else if ( dwStyle & LBS_EXTENDEDSEL ) + } else if ( lphl->dwStyle & LBS_EXTENDEDSEL ) { /* Fixme: extended selection mode */ ListBoxSetSel( lphl, lphl->ItemFocused, 0); @@ -1089,7 +1098,6 @@ static LONG LBMouseMove(HWND hwnd, WORD wParam, LONG lParam) static LONG LBKeyDown(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); - LONG dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE); WORD newFocused = 0xFFFF; RECT rect; @@ -1104,7 +1112,7 @@ static LONG LBKeyDown(HWND hwnd, WORD wParam, LONG lParam) case VK_DOWN: case VK_PRIOR: case VK_NEXT: - if ( dwStyle & LBS_WANTKEYBOARDINPUT ) + if ( lphl->dwStyle & LBS_WANTKEYBOARDINPUT ) { newFocused = (WORD)(INT)SendMessage(lphl->hParent,WM_VKEYTOITEM, wParam,MAKELPARAM(lphl->ItemFocused,hwnd)); @@ -1124,7 +1132,7 @@ static LONG LBKeyDown(HWND hwnd, WORD wParam, LONG lParam) newFocused = lphl->ItemsCount - 1; break; case VK_LEFT: - if (dwStyle & LBS_MULTICOLUMN) { + if (lphl->dwStyle & LBS_MULTICOLUMN) { if (newFocused >= lphl->ItemsPerColumn) { newFocused -= lphl->ItemsPerColumn; } else { @@ -1136,7 +1144,7 @@ static LONG LBKeyDown(HWND hwnd, WORD wParam, LONG lParam) if (newFocused > 0) newFocused--; break; case VK_RIGHT: - if (dwStyle & LBS_MULTICOLUMN) + if (lphl->dwStyle & LBS_MULTICOLUMN) newFocused += lphl->ItemsPerColumn; break; case VK_DOWN: @@ -1157,7 +1165,7 @@ static LONG LBKeyDown(HWND hwnd, WORD wParam, LONG lParam) } break; case VK_SPACE: - if (dwStyle & LBS_MULTIPLESEL) + if (lphl->dwStyle & LBS_MULTIPLESEL) { WORD wRet = ListBoxGetSel(lphl, lphl->ItemFocused); ListBoxSetSel(lphl, lphl->ItemFocused, !wRet); @@ -1174,7 +1182,7 @@ static LONG LBKeyDown(HWND hwnd, WORD wParam, LONG lParam) if (newFocused >= lphl->ItemsCount) newFocused = lphl->ItemsCount - 1; - if (!(dwStyle & LBS_MULTIPLESEL)) + if (!(lphl->dwStyle & LBS_MULTIPLESEL)) { ListBoxSetCurSel(lphl, newFocused); ListBoxSendNotification(lphl, LBN_SELCHANGE); @@ -1182,7 +1190,7 @@ static LONG LBKeyDown(HWND hwnd, WORD wParam, LONG lParam) lphl->ItemFocused = newFocused; - if( ListBoxScrollToFocus(lphl) || (dwStyle & + if( ListBoxScrollToFocus(lphl) || (lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) ) InvalidateRect(hwnd, NULL, TRUE); else @@ -1206,10 +1214,9 @@ static LONG LBKeyDown(HWND hwnd, WORD wParam, LONG lParam) static LONG LBChar(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); - LONG dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE); WORD newFocused = 0xFFFF; - if ( (dwStyle & LBS_WANTKEYBOARDINPUT) && !(lphl->HasStrings)) + if ( (lphl->dwStyle & LBS_WANTKEYBOARDINPUT) && !(lphl->HasStrings)) { newFocused = (WORD)(INT)SendMessage(lphl->hParent,WM_CHARTOITEM, wParam,MAKELPARAM(lphl->ItemFocused,hwnd)); @@ -1224,7 +1231,7 @@ static LONG LBChar(HWND hwnd, WORD wParam, LONG lParam) if (newFocused >= lphl->ItemsCount) newFocused = lphl->ItemsCount - 1; - if (!(dwStyle & LBS_MULTIPLESEL)) + if (!(lphl->dwStyle & LBS_MULTIPLESEL)) { ListBoxSetCurSel(lphl, newFocused); ListBoxSendNotification(lphl, LBN_SELCHANGE); @@ -1259,12 +1266,26 @@ static LONG LBSetRedraw(HWND hwnd, WORD wParam, LONG lParam) static LONG LBSetFont(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); + HDC hdc; if (wParam == 0) lphl->hFont = GetStockObject(SYSTEM_FONT); else lphl->hFont = (HFONT) wParam; + /* a new font means possible new text height */ + /* does this mean the height of each entry must be separately changed? */ + /* or are we guaranteed to get a LBSetFont before the first insert/add? */ + if ((hdc = GetDC(0))) + { + TEXTMETRIC tm; + GetTextMetrics( hdc, &tm ); + lphl->StdItemHeight = tm.tmHeight; + dprintf_listbox(stddeb,"LBSetFont: new font %d with height %d", + lphl->hFont, lphl->StdItemHeight); + ReleaseDC( 0, hdc ); + } + return 0; } @@ -1274,7 +1295,6 @@ static LONG LBSetFont(HWND hwnd, WPARAM wParam, LPARAM lParam) static LONG LBPaint(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); - LONG dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE); LPLISTSTRUCT lpls; PAINTSTRUCT ps; HBRUSH hBrush; @@ -1311,7 +1331,7 @@ static LONG LBPaint(HWND hwnd, WORD wParam, LONG lParam) FillRect(hdc, &rect, hBrush); maxwidth = rect.right; - if (dwStyle & LBS_MULTICOLUMN) { + if (lphl->dwStyle & LBS_MULTICOLUMN) { rect.right = lphl->ColumnsWidth; } lpls = lphl->lpFirst; @@ -1326,7 +1346,7 @@ static LONG LBPaint(HWND hwnd, WORD wParam, LONG lParam) height = lpls->mis.itemHeight; if (top > rect.bottom) { - if (dwStyle & LBS_MULTICOLUMN) { + if (lphl->dwStyle & LBS_MULTICOLUMN) { lphl->ItemsPerColumn = MAX(lphl->ItemsPerColumn, ipc); ipc = 0; top = 0; @@ -1345,7 +1365,7 @@ static LONG LBPaint(HWND hwnd, WORD wParam, LONG lParam) if( IntersectRect(&scratchRect,&paintRect,&lpls->itemRect) ) { - dprintf_listbox(stddeb,"drawing item: %ld %d %ld %d %d\n",(LONG)rect.left,top, + dprintf_listbox(stddeb,"LBPaint: drawing item: %ld %d %ld %d %d\n",(LONG)rect.left,top, (LONG)rect.right,top+height,lpls->itemState); if (lphl->OwnerDrawn && (lphl->ItemFocused == i) && GetFocus() == hwnd) @@ -1380,13 +1400,9 @@ static LONG LBPaint(HWND hwnd, WORD wParam, LONG lParam) static LONG LBSetFocus(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); - LONG dwStyle; dprintf_listbox(stddeb,"ListBox WM_SETFOCUS for "NPFMT"\n",hwnd); - - dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE); - - if(!(dwStyle & LBS_MULTIPLESEL) ) + if(!(lphl->dwStyle & LBS_MULTIPLESEL) ) if( lphl->ItemsCount && lphl->ItemFocused != -1) { HDC hDC = GetDC(hwnd); @@ -1412,13 +1428,9 @@ static LONG LBSetFocus(HWND hwnd, WORD wParam, LONG lParam) static LONG LBKillFocus(HWND hwnd, WORD wParam, LONG lParam) { LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); - LONG dwStyle; dprintf_listbox(stddeb,"ListBox WM_KILLFOCUS for "NPFMT"\n",hwnd); - - dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE); - - if (!(dwStyle & LBS_MULTIPLESEL)) + if (!(lphl->dwStyle & LBS_MULTIPLESEL)) { if( lphl->ItemsCount ) if( lphl->ItemFocused != -1 ) @@ -1626,8 +1638,7 @@ static LONG LBGetSelCount(HWND hwnd, WORD wParam, LONG lParam) int cnt = 0; int items = 0; - if (!(GetWindowLong(lphl->hSelf,GWL_STYLE) & - (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )) + if (!(lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )) return LB_ERR; for( lpls = lphl->lpFirst; @@ -1652,8 +1663,7 @@ static LONG LBGetSelItems(HWND hwnd, WORD wParam, LONG lParam) int cnt, idx; int *lpItems = PTR_SEG_TO_LIN(lParam); - if (!(GetWindowLong(lphl->hSelf,GWL_STYLE) & - (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )) + if (!(lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )) return LB_ERR; if (wParam == 0) return 0; @@ -1715,8 +1725,7 @@ static LONG LBSelectString(HWND hwnd, WORD wParam, LONG lParam) if( iRet != LB_ERR) { - if( GetWindowLong(hwnd, GWL_STYLE) & - (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) ) + if( lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) ) ListBoxSetSel(lphl,iRet,TRUE); else ListBoxSetCurSel(lphl,iRet); @@ -1739,8 +1748,7 @@ static LONG LBSelItemRange(HWND hwnd, WORD wParam, LONG lParam) WORD last = HIWORD(lParam); BOOL select = wParam; - if (!(GetWindowLong(lphl->hSelf,GWL_STYLE) & - (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )) + if (!(lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )) return LB_ERR; if (first >= lphl->ItemsCount || @@ -1770,8 +1778,7 @@ static LONG LBSetCaretIndex(HWND hwnd, WORD wParam, LONG lParam) LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); int i; - if (!(GetWindowLong(lphl->hSelf,GWL_STYLE) & - (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )) return 0; + if (!(lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )) return 0; dprintf_listbox(stddeb,"LBSetCaretIndex: hwnd "NPFMT" n=%i\n",hwnd,wParam); @@ -1886,7 +1893,7 @@ static LONG LBSetSel(HWND hwnd, WORD wParam, LONG lParam) InvalidateRect(hwnd, NULL, TRUE); else if( iRet != LB_ERR ) { - if( GetWindowLong(hwnd,GWL_STYLE) & LBS_EXTENDEDSEL && + if( lphl->dwStyle & LBS_EXTENDEDSEL && lphl->ItemFocused != LOWORD(lParam) ) { ListBoxGetItemRect(lphl, lphl->ItemFocused , &rect); diff --git a/debugger/dbg.y b/debugger/dbg.y index 1105e0ad12a..206247b0c81 100644 --- a/debugger/dbg.y +++ b/debugger/dbg.y @@ -9,7 +9,10 @@ #include #include #include -#include "windows.h" +#include "class.h" +#include "options.h" +#include "queue.h" +#include "win.h" #include "debugger.h" extern FILE * yyin; @@ -33,15 +36,15 @@ int yyerror(char *); int integer; } -%token CONT STEP LIST NEXT QUIT HELP BACKTRACE INFO STACK SEGMENTS REGS -%token ENABLE DISABLE BREAK DELETE SET MODE PRINT EXAM DEFINE ABORT WALK -%token WND QUEUE -%token NO_SYMBOL EOL -%token SYMBOLFILE +%token tCONT tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tINFO tWALK +%token tENABLE tDISABLE tBREAK tDELETE tSET tMODE tPRINT tEXAM tDEFINE tABORT +%token tCLASS tSTACK tSEGMENTS tREGS tWND tQUEUE +%token tNO_SYMBOL tEOL +%token tSYMBOLFILE -%token IDENTIFIER -%token NUM FORMAT -%token REG +%token tIDENTIFIER +%token tNUM tFORMAT +%token tREG /* %left ',' */ /* %left '=' OP_OR_EQUAL OP_XOR_EQUAL OP_AND_EQUAL OP_SHL_EQUAL \ @@ -66,127 +69,135 @@ int yyerror(char *); %% - input: line { issue_prompt(); } - | input line { issue_prompt(); } +input: line { issue_prompt(); } + | input line { issue_prompt(); } - line: command - | EOL - | error EOL { yyerrok; } +line: command + | tEOL + | error tEOL { yyerrok; } - command: QUIT EOL { exit(0); } - | HELP EOL { DEBUG_Help(); } - | CONT EOL { dbg_exec_mode = EXEC_CONT; return 0; } - | STEP EOL { dbg_exec_mode = EXEC_STEP_INSTR; return 0; } - | NEXT EOL { dbg_exec_mode = EXEC_STEP_OVER; return 0; } - | LIST EOL { DEBUG_List( NULL, 15 ); } - | LIST addr EOL { DEBUG_List( &$2, 15 ); } - | ABORT EOL { kill(getpid(), SIGABRT); } - | SYMBOLFILE IDENTIFIER EOL { DEBUG_ReadSymbolTable( $2 ); } - | DEFINE IDENTIFIER addr EOL { DEBUG_AddSymbol( $2, &$3 ); } - | MODE NUM EOL { mode_command($2); } - | ENABLE NUM EOL { DEBUG_EnableBreakpoint( $2, TRUE ); } - | DISABLE NUM EOL { DEBUG_EnableBreakpoint( $2, FALSE ); } - | BREAK '*' addr EOL { DEBUG_AddBreakpoint( &$3 ); } - | BREAK symbol EOL { DEBUG_AddBreakpoint( &$2 ); } - | BREAK EOL { DBG_ADDR addr = { CS_reg(DEBUG_context), - EIP_reg(DEBUG_context) }; - DEBUG_AddBreakpoint( &addr ); - } - | DELETE BREAK NUM EOL { DEBUG_DelBreakpoint( $3 ); } - | BACKTRACE EOL { DEBUG_BackTrace(); } - | WALK WND EOL { DEBUG_InitWalk(); DEBUG_WndWalk( NULL ); } - | WALK WND NUM EOL { DEBUG_InitWalk(); DEBUG_WndWalk( $3 ); } - | infocmd - | x_command - | print_command - | deposit_command - -deposit_command: - SET REG '=' expr EOL { DEBUG_SetRegister( $2, $4 ); } - | SET '*' addr '=' expr EOL { DEBUG_WriteMemory( &$3, $5 ); } - | SET IDENTIFIER '=' addr EOL { if (!DEBUG_SetSymbolValue( $2, &$4 )) - { - fprintf( stderr, - "Symbol %s not found\n", $2 ); - YYERROR; - } - } +command: + tQUIT tEOL { exit(0); } + | tHELP tEOL { DEBUG_Help(); } + | tCONT tEOL { dbg_exec_mode = EXEC_CONT; return 0; } + | tSTEP tEOL { dbg_exec_mode = EXEC_STEP_INSTR; return 0; } + | tNEXT tEOL { dbg_exec_mode = EXEC_STEP_OVER; return 0; } + | tLIST tEOL { DEBUG_List( NULL, 15 ); } + | tLIST addr tEOL { DEBUG_List( &$2, 15 ); } + | tABORT tEOL { kill(getpid(), SIGABRT); } + | tSYMBOLFILE tIDENTIFIER tEOL { DEBUG_ReadSymbolTable( $2 ); } + | tDEFINE tIDENTIFIER addr tEOL { DEBUG_AddSymbol( $2, &$3 ); } + | tMODE tNUM tEOL { mode_command($2); } + | tENABLE tNUM tEOL { DEBUG_EnableBreakpoint( $2, TRUE ); } + | tDISABLE tNUM tEOL { DEBUG_EnableBreakpoint( $2, FALSE ); } + | tDELETE tBREAK tNUM tEOL { DEBUG_DelBreakpoint( $3 ); } + | tBACKTRACE tEOL { DEBUG_BackTrace(); } + | set_command + | x_command + | print_command + | break_command + | info_command + | walk_command +set_command: + tSET tREG '=' expr tEOL { DEBUG_SetRegister( $2, $4 ); } + | tSET '*' addr '=' expr tEOL { DEBUG_WriteMemory( &$3, $5 ); } + | tSET tIDENTIFIER '=' addr tEOL { if (!DEBUG_SetSymbolValue( $2, &$4 )) + { + fprintf( stderr, + "Symbol %s not found\n", $2 ); + YYERROR; + } + } x_command: - EXAM addr EOL { DEBUG_ExamineMemory( &$2, 1, 'x'); } - | EXAM FORMAT addr EOL { DEBUG_ExamineMemory( &$3, $2>>8, $2&0xff ); } + tEXAM addr tEOL { DEBUG_ExamineMemory( &$2, 1, 'x'); } + | tEXAM tFORMAT addr tEOL { DEBUG_ExamineMemory( &$3, $2>>8, $2&0xff ); } - print_command: - PRINT addr EOL { DEBUG_Print( &$2, 1, 'x' ); } - | PRINT FORMAT addr EOL { DEBUG_Print( &$3, $2 >> 8, $2 & 0xff ); } +print_command: + tPRINT addr tEOL { DEBUG_Print( &$2, 1, 'x' ); } + | tPRINT tFORMAT addr tEOL { DEBUG_Print( &$3, $2 >> 8, $2 & 0xff ); } - symbol: IDENTIFIER { if (!DEBUG_GetSymbolValue( $1, &$$ )) +break_command: + tBREAK '*' addr tEOL { DEBUG_AddBreakpoint( &$3 ); } + | tBREAK symbol tEOL { DEBUG_AddBreakpoint( &$2 ); } + | tBREAK tEOL { DBG_ADDR addr = { CS_reg(DEBUG_context), + EIP_reg(DEBUG_context) }; + DEBUG_AddBreakpoint( &addr ); + } + +info_command: + tINFO tBREAK tEOL { DEBUG_InfoBreakpoints(); } + | tINFO tCLASS expr tEOL { CLASS_DumpClass( $3 ); } + | tINFO tQUEUE expr tEOL { QUEUE_DumpQueue( $3 ); } + | tINFO tREGS tEOL { DEBUG_InfoRegisters(); } + | tINFO tSEGMENTS expr tEOL { LDT_Print( SELECTOR_TO_ENTRY($3), 1 ); } + | tINFO tSEGMENTS tEOL { LDT_Print( 0, -1 ); } + | tINFO tSTACK tEOL { DEBUG_InfoStack(); } + | tINFO tWND expr tEOL { WIN_DumpWindow( $3 ); } + +walk_command: + tWALK tCLASS tEOL { CLASS_WalkClasses(); } + | tWALK tQUEUE tEOL { QUEUE_WalkQueues(); } + | tWALK tWND tEOL { WIN_WalkWindows( 0, 0 ); } + | tWALK tWND tNUM tEOL { WIN_WalkWindows( $3, 0 ); } + +symbol: tIDENTIFIER { if (!DEBUG_GetSymbolValue( $1, &$$ )) { fprintf( stderr, "Symbol %s not found\n", $1 ); YYERROR; } } - addr: expr { $$.seg = 0xffffffff; $$.off = $1; } - | segaddr { $$ = $1; } +addr: + expr { $$.seg = 0xffffffff; $$.off = $1; } + | segaddr { $$ = $1; } - segaddr: expr ':' expr { $$.seg = $1; $$.off = $3; } - | symbol { $$ = $1; } +segaddr: + expr ':' expr { $$.seg = $1; $$.off = $3; } + | symbol { $$ = $1; } - expr: NUM { $$ = $1; } - | REG { $$ = DEBUG_GetRegister($1); } - | expr OP_LOR expr { $$ = $1 || $3; } - | expr OP_LAND expr { $$ = $1 && $3; } - | expr '|' expr { $$ = $1 | $3; } - | expr '&' expr { $$ = $1 & $3; } - | expr '^' expr { $$ = $1 ^ $3; } - | expr OP_EQ expr { $$ = $1 == $3; } - | expr '>' expr { $$ = $1 > $3; } - | expr '<' expr { $$ = $1 < $3; } - | expr OP_GE expr { $$ = $1 >= $3; } - | expr OP_LE expr { $$ = $1 <= $3; } - | expr OP_NE expr { $$ = $1 != $3; } - | expr OP_SHL expr { $$ = (unsigned)$1 << $3; } - | expr OP_SHR expr { $$ = (unsigned)$1 >> $3; } - | expr '+' expr { $$ = $1 + $3; } - | expr '-' expr { $$ = $1 - $3; } - | expr '*' expr { $$ = $1 * $3; } - | expr '/' expr - { if ($3) - if ($3 == -1 && $1 == 0x80000000l) - yyerror ("Division overflow"); - else - $$ = $1 / $3; - else - yyerror ("Division by zero"); } - | expr '%' expr - { if ($3) - if ($3 == -1 && $1 == 0x80000000l) - $$ = 0; /* A sensible result in this case. */ - else - $$ = $1 % $3; - else - yyerror ("Division by zero"); } - | '-' expr %prec OP_SIGN { $$ = -$2; } - | '+' expr %prec OP_SIGN { $$ = $2; } - | '!' expr { $$ = !$2; } - | '~' expr { $$ = ~$2; } - | '(' expr ')' { $$ = $2; } +expr: + tNUM { $$ = $1; } + | tREG { $$ = DEBUG_GetRegister($1); } + | expr OP_LOR expr { $$ = $1 || $3; } + | expr OP_LAND expr { $$ = $1 && $3; } + | expr '|' expr { $$ = $1 | $3; } + | expr '&' expr { $$ = $1 & $3; } + | expr '^' expr { $$ = $1 ^ $3; } + | expr OP_EQ expr { $$ = $1 == $3; } + | expr '>' expr { $$ = $1 > $3; } + | expr '<' expr { $$ = $1 < $3; } + | expr OP_GE expr { $$ = $1 >= $3; } + | expr OP_LE expr { $$ = $1 <= $3; } + | expr OP_NE expr { $$ = $1 != $3; } + | expr OP_SHL expr { $$ = (unsigned)$1 << $3; } + | expr OP_SHR expr { $$ = (unsigned)$1 >> $3; } + | expr '+' expr { $$ = $1 + $3; } + | expr '-' expr { $$ = $1 - $3; } + | expr '*' expr { $$ = $1 * $3; } + | expr '/' expr { if ($3) + if ($3 == -1 && $1 == 0x80000000l) + yyerror ("Division overflow"); + else $$ = $1 / $3; + else yyerror ("Division by zero"); + } + | expr '%' expr { if ($3) + if ($3 == -1 && $1 == 0x80000000l) + $$ = 0; /* A sensible result in this case. */ + else $$ = $1 % $3; + else yyerror ("Division by zero"); + } + | '-' expr %prec OP_SIGN { $$ = -$2; } + | '+' expr %prec OP_SIGN { $$ = $2; } + | '!' expr { $$ = !$2; } + | '~' expr { $$ = ~$2; } + | '(' expr ')' { $$ = $2; } /* For parser technical reasons we can't use "addr" here. */ - | '*' expr %prec OP_DEREF { DBG_ADDR addr = { 0xffffffff, $2 }; - $$ = DEBUG_ReadMemory( &addr ); } - | '*' segaddr %prec OP_DEREF { $$ = DEBUG_ReadMemory( &$2 ); } + | '*' expr %prec OP_DEREF { DBG_ADDR addr = { 0xffffffff, $2 }; + $$ = DEBUG_ReadMemory( &addr ); } + | '*' segaddr %prec OP_DEREF { $$ = DEBUG_ReadMemory( &$2 ); } - infocmd: INFO REGS EOL { DEBUG_InfoRegisters(); } - | INFO STACK EOL { DEBUG_InfoStack(); } - | INFO BREAK EOL { DEBUG_InfoBreakpoints(); } - | INFO SEGMENTS EOL { LDT_Print( 0, -1 ); } - | INFO SEGMENTS expr EOL { LDT_Print( SELECTOR_TO_ENTRY($3), 1 ); } - | INFO WND expr EOL { DEBUG_WndDump( $3 ); } - | INFO QUEUE expr EOL { DEBUG_QueueDump( $3 ); } - - %% void diff --git a/debugger/debug.l b/debugger/debug.l index cc46238ff42..abacf8e285c 100644 --- a/debugger/debug.l +++ b/debugger/debug.l @@ -35,7 +35,7 @@ IDENTIFIER [_a-zA-Z\.~][_a-zA-Z0-9\.~]* %% -\n { syntax_error = 0; return EOL; } /*Indicates end of command*/ +\n { syntax_error = 0; return tEOL; } /*Indicates end of command*/ "||" { return OP_LOR; } "&&" { return OP_LAND; } @@ -47,77 +47,76 @@ IDENTIFIER [_a-zA-Z\.~][_a-zA-Z0-9\.~]* ">>" { return OP_SHR; } [-+<=>|&^()*/%:!~] { return *yytext; } -"0x"{HEXDIGIT}+ { sscanf(yytext, "%x", &yylval.integer); return NUM; } -{DIGIT}+ { sscanf(yytext, "%d", &yylval.integer); return NUM; } +"0x"{HEXDIGIT}+ { sscanf(yytext, "%x", &yylval.integer); return tNUM; } +{DIGIT}+ { sscanf(yytext, "%d", &yylval.integer); return tNUM; } "/"{DIGIT}+{FORMAT} { char * last; yylval.integer = strtol( yytext+1, &last, NULL ); yylval.integer = (yylval.integer << 8) | *last; - return FORMAT; } -"/"{FORMAT} { yylval.integer = (1 << 8) | yytext[1]; return FORMAT; } + return tFORMAT; } +"/"{FORMAT} { yylval.integer = (1 << 8) | yytext[1]; return tFORMAT; } -$pc { yylval.reg = REG_EIP; return REG; } -$flags { yylval.reg = REG_EFL; return REG; } -$eip { yylval.reg = REG_EIP; return REG; } -$ip { yylval.reg = REG_IP; return REG; } -$esp { yylval.reg = REG_ESP; return REG; } -$sp { yylval.reg = REG_SP; return REG; } -$eax { yylval.reg = REG_EAX; return REG; } -$ebx { yylval.reg = REG_EBX; return REG; } -$ecx { yylval.reg = REG_ECX; return REG; } -$edx { yylval.reg = REG_EDX; return REG; } -$esi { yylval.reg = REG_ESI; return REG; } -$edi { yylval.reg = REG_EDI; return REG; } -$ebp { yylval.reg = REG_EBP; return REG; } -$ax { yylval.reg = REG_AX; return REG; } -$bx { yylval.reg = REG_BX; return REG; } -$cx { yylval.reg = REG_CX; return REG; } -$dx { yylval.reg = REG_DX; return REG; } -$si { yylval.reg = REG_SI; return REG; } -$di { yylval.reg = REG_DI; return REG; } -$bp { yylval.reg = REG_BP; return REG; } -$es { yylval.reg = REG_ES; return REG; } -$ds { yylval.reg = REG_DS; return REG; } -$cs { yylval.reg = REG_CS; return REG; } -$ss { yylval.reg = REG_SS; return REG; } +$pc { yylval.reg = REG_EIP; return tREG; } +$flags { yylval.reg = REG_EFL; return tREG; } +$eip { yylval.reg = REG_EIP; return tREG; } +$ip { yylval.reg = REG_IP; return tREG; } +$esp { yylval.reg = REG_ESP; return tREG; } +$sp { yylval.reg = REG_SP; return tREG; } +$eax { yylval.reg = REG_EAX; return tREG; } +$ebx { yylval.reg = REG_EBX; return tREG; } +$ecx { yylval.reg = REG_ECX; return tREG; } +$edx { yylval.reg = REG_EDX; return tREG; } +$esi { yylval.reg = REG_ESI; return tREG; } +$edi { yylval.reg = REG_EDI; return tREG; } +$ebp { yylval.reg = REG_EBP; return tREG; } +$ax { yylval.reg = REG_AX; return tREG; } +$bx { yylval.reg = REG_BX; return tREG; } +$cx { yylval.reg = REG_CX; return tREG; } +$dx { yylval.reg = REG_DX; return tREG; } +$si { yylval.reg = REG_SI; return tREG; } +$di { yylval.reg = REG_DI; return tREG; } +$bp { yylval.reg = REG_BP; return tREG; } +$es { yylval.reg = REG_ES; return tREG; } +$ds { yylval.reg = REG_DS; return tREG; } +$cs { yylval.reg = REG_CS; return tREG; } +$ss { yylval.reg = REG_SS; return tREG; } -info|inf|in { return INFO; } -show|sho|sh { return INFO; } -list|lis|li|l { return LIST; } -segments|segment|segm|seg|se { return SEGMENTS; } -break|brea|bre|br|b { return BREAK; } -enable|enabl|enab|ena { return ENABLE;} -disable|disabl|disab|disa|dis { return DISABLE; } -delete|delet|dele|del { return DELETE; } -quit|qui|qu|q { return QUIT; } -walk|w { return WALK; } -queue|queu|que { return QUEUE; } -window|windo|wind|win|wnd { return WND; } -x { return EXAM; } +info|inf|in { return tINFO; } +show|sho|sh { return tINFO; } +list|lis|li|l { return tLIST; } +break|brea|bre|br|b { return tBREAK; } +enable|enabl|enab|ena { return tENABLE;} +disable|disabl|disab|disa|dis { return tDISABLE; } +delete|delet|dele|del { return tDELETE; } +quit|qui|qu|q { return tQUIT; } +set|se { return tSET; } +walk|w { return tWALK; } +x { return tEXAM; } -help|hel|he|"?" { return HELP; } +class|clas|cla { return tCLASS; } +queue|queu|que { return tQUEUE; } +registers|regs|reg|re { return tREGS; } +segments|segment|segm|seg|se { return tSEGMENTS; } +stack|stac|sta|st { return tSTACK; } +window|windo|wind|win|wnd { return tWND; } -set|se { return SET; } +help|hel|he|"?" { return tHELP; } -bt { return BACKTRACE; } +backtrace|bt { return tBACKTRACE; } -cont|con|co|c { return CONT; } -step|ste|st|s { return STEP; } -next|nex|ne|n { return NEXT; } +cont|con|co|c { return tCONT; } +step|ste|st|s { return tSTEP; } +next|nex|ne|n { return tNEXT; } -symbolfile|symbolfil|symbolfi|symbolf|symbol|symbo|symb { return SYMBOLFILE; } +symbolfile|symbolfil|symbolfi|symbolf|symbol|symbo|symb { return tSYMBOLFILE; } -define|defin|defi|def|de { return DEFINE; } -abort|abor|abo { return ABORT; } -print|prin|pri|pr|p { return PRINT; } +define|defin|defi|def|de { return tDEFINE; } +abort|abor|abo { return tABORT; } +print|prin|pri|pr|p { return tPRINT; } -mode { return MODE; } +mode { return tMODE; } -registers|regs|reg|re { return REGS; } - -stack|stac|sta|st { return STACK; } - -{IDENTIFIER} { yylval.string = make_symbol(yytext); return IDENTIFIER; } +{IDENTIFIER} { yylval.string = make_symbol(yytext); return tIDENTIFIER; } [ \t]+ /* Eat up whitespace */ diff --git a/debugger/hash.c b/debugger/hash.c index 60be9104e6b..c21c0d088d0 100644 --- a/debugger/hash.c +++ b/debugger/hash.c @@ -215,7 +215,6 @@ void DEBUG_LoadEntryPoints(void) unsigned int address; BOOL ok; - fprintf( stderr, "Adding symbols from loaded modules\n" ); for (ok = ModuleFirst(&entry); ok; ok = ModuleNext(&entry)) { if (!(pModule = (NE_MODULE *)GlobalLock( entry.hModule ))) continue; diff --git a/debugger/info.c b/debugger/info.c index c17efaaed11..b656879290b 100644 --- a/debugger/info.c +++ b/debugger/info.c @@ -7,191 +7,8 @@ #include #include -#include "global.h" -#include "user.h" -#include "class.h" -#include "win.h" -#include "message.h" -#include "spy.h" #include "debugger.h" -int iWndIndent = 0; - -extern char lpstrSpyMessageIndent[]; /* from misc/spy.c */ - -/*********************************************************************** - * DEBUG_InitWalk - */ -void DEBUG_InitWalk(void) -{ - fprintf(stderr,"%-24.24s %-6.6s %-17.17s %-8.8s %s\n", - "HWND / WNDPTR","hQueue","Class Name", "Style", "WndProc"); - lpstrSpyMessageIndent[0]='\0'; -} - -/*********************************************************************** - * DEBUG_WndWalk - * - */ -void DEBUG_WndWalk(HWND hStart) -{ - WND* wndPtr; - CLASS* classPtr; - char className[0x10]; - int i; - - if( !hStart ) - hStart = GetDesktopHwnd(); - - wndPtr = WIN_FindWndPtr(hStart); - - if( !wndPtr ) - { fprintf(stderr, "Invalid window handle: %04x\n", hStart); - return; } - - i = strlen(lpstrSpyMessageIndent); - - /* 0x10 bytes are always reserved at the end of lpstrSpyMessageIndent */ - sprintf(lpstrSpyMessageIndent + i,"%04x %08x",hStart, (unsigned) wndPtr); - - classPtr = CLASS_FindClassPtr(wndPtr->hClass); - if(classPtr) - GlobalGetAtomName(classPtr->atomName ,className, 0x10); - else - strcpy(className,""); - - fprintf(stderr,"%-24.24s %-6.4x %-17.17s %08x %04x:%04x\n", - lpstrSpyMessageIndent, - wndPtr->hmemTaskQ, - className, - (unsigned) wndPtr->dwStyle, - HIWORD(wndPtr->lpfnWndProc), - LOWORD(wndPtr->lpfnWndProc)); - - lpstrSpyMessageIndent[i] = '\0'; - - if( wndPtr->hwndChild ) - { - /* walk children */ - - hStart = wndPtr->hwndChild; - wndPtr = WIN_FindWndPtr(hStart); - - iWndIndent ++; - if( iWndIndent < SPY_MAX_INDENTLEVEL - 0x10 ) - { - lpstrSpyMessageIndent[iWndIndent - 1] = ' '; - lpstrSpyMessageIndent[iWndIndent] = '\0'; - } - - while( wndPtr ) - { - DEBUG_WndWalk(hStart); - hStart = wndPtr->hwndNext; - wndPtr = WIN_FindWndPtr(hStart); - } - - if( hStart ) - fprintf(stderr, "%s%s"NPFMT"\n", lpstrSpyMessageIndent, - "", hStart); - - if( iWndIndent ) - { - iWndIndent--; - if( iWndIndent < SPY_MAX_INDENTLEVEL - 0x10 ) - lpstrSpyMessageIndent[iWndIndent] = '\0'; - } - - } -} - -/*********************************************************************** - * DEBUG_WndDump - * - */ -void DEBUG_WndDump(HWND hWnd) -{ - WND* wnd; - char* lpWndText = NULL; - - wnd = WIN_FindWndPtr(hWnd); - - if( !wnd ) - { fprintf(stderr, "Invalid window handle: %04x\n", hWnd); - return; } - - if( wnd->hText ) - lpWndText = (LPSTR) USER_HEAP_LIN_ADDR( wnd->hText ); - - fprintf( stderr, "next: %12.4x\n" - "child: %10.4x\n" - "parent: %10.4x\n" - "owner: %10.4x\n" - "hClass: %10.4x\n" - "hInst: %10.4x\n" - "clientRect: %i,%i - %i,%i\n" - "windowRect: %i,%i - %i,%i\n" - "hRgnUpdate: %6.4x\n" - "hLastPopup: %6.4x\n" - "Style: %10.8x\n" - "StyleEx: %9.8x\n" - "hDCE: %10.4x\n" - "hVscroll: %8.4x\n" - "hHscroll: %8.4x\n" - "menuID: %10.4x\n" - "hText: %10.4x (\"%s\")\n" - "flags: %10.4x\n", - wnd->hwndNext, wnd->hwndChild,wnd->hwndParent, - wnd->hwndOwner,wnd->hClass,wnd->hInstance, - wnd->rectClient.left, wnd->rectClient.top, - wnd->rectClient.right, wnd->rectClient.bottom, - wnd->rectWindow.left, wnd->rectWindow.top, - wnd->rectWindow.right, wnd->rectWindow.bottom, - wnd->hrgnUpdate, wnd->hwndLastActive, - (unsigned) wnd->dwStyle, (unsigned) wnd->dwExStyle, - wnd->hdce, wnd->hVScroll, wnd->hHScroll, - wnd->wIDmenu, wnd->hText, (lpWndText)?lpWndText:"NULL", - wnd->flags); -} - -/*********************************************************************** - * DEBUG_QueueDump - * - */ -void DEBUG_QueueDump(HQUEUE hQ) -{ - MESSAGEQUEUE* pq; - - if( !hQ || IsBadReadPtr((SEGPTR)MAKELONG( 0, GlobalHandleToSel(hQ)), - sizeof(MESSAGEQUEUE)) ) - { - fprintf(stderr, "Invalid queue handle: "NPFMT"\n", hQ); - return; - } - - pq = (MESSAGEQUEUE*) GlobalLock( hQ ); - - fprintf(stderr,"next: %12.4x Intertask SendMessage:\n" - "hTask: %11.4x ----------------------\n" - "msgSize: %9.4x hWnd: %10.4x\n" - "msgCount: %8.4x msg: %11.4x\n" - "msgNext: %9.4x wParam: %8.4x\n" - "msgFree: %9.4x lParam: %8.8x\n" - "qSize: %11.4x lRet: %10.8x\n" - "wWinVer: %9.4x ISMH: %10.4x\n" - "paints: %10.4x hSendTask: %5.4x\n" - "timers: %10.4x hPrevSend: %5.4x\n" - "wakeBits: %8.4x\n" - "wakeMask: %8.4x\n" - "hCurHook: %8.4x\n", - pq->next, pq->hTask, pq->msgSize, pq->hWnd, - pq->msgCount, pq->msg, pq->nextMessage, pq->wParam, - pq->nextFreeMessage, (unsigned)pq->lParam, pq->queueSize, - (unsigned)pq->SendMessageReturn, pq->wWinVersion, pq->InSendMessageHandle, - pq->wPaintCount, pq->hSendingTask, pq->wTimerCount, - pq->hPrevSendingTask, pq->status, pq->wakeMask, pq->hCurHook); -} - /*********************************************************************** * DEBUG_Print * diff --git a/if1632/Makefile.in b/if1632/Makefile.in index 7e94b98747d..f896da87f03 100644 --- a/if1632/Makefile.in +++ b/if1632/Makefile.in @@ -46,7 +46,8 @@ C_SRCS = \ ASM_SRCS = \ $(SPEC16_FILES) \ call16.S \ - call32.S + call32.S \ + except.S .SUFFIXES: .spec diff --git a/if1632/except.S b/if1632/except.S new file mode 100644 index 00000000000..60cd71085b7 --- /dev/null +++ b/if1632/except.S @@ -0,0 +1,192 @@ +/* + * Win32 exception assembly functions + * + * Copyright (c) 1996 Onno Hovers, (onno@stack.urc.tue.nl) + * + */ + +#ifndef __ELF__ + .globl _EXC_CallUnhandledExceptionFilter + .extern _pTopExcHandler + + _EXC_CallUnhandledExceptionFilter: +#else /* __ELF__ */ + .globl EXC_CallUnhandledExceptionFilter + .extern pTopExcHandler + + EXC_CallUnhandledExceptionFilter: +#endif /* __ELF__ */ + leal 4(%esp),%eax + pushl %eax +#ifndef __ELF__ + call *_pTopExcHandler +#else /* __ELF__ */ + call *pTopExcHandler +#endif /* __ELF__ */ + movl %ebp,%esp + ret + + + +/******************************************************************* + * + * RaiseException (KERNEL32. 418 ) + * RtlUnwind (KERNEL32. 443 ) + * + * we need to save our context before a call to + * + * -RaiseException + * -RtlUnwind + * + * after these functions we need to restore that context structure as + * the actual context so changes made to the context structure in an + * exception-handler will be reflected in the context after these + * functions return. Fortunately both functions have 4 DWORD params. + * we pass the function to be called as a fifth parameter to ContextCall + * + */ + .equ CONTEXT_SegSs, -4 + .equ CONTEXT_Esp, -8 + .equ CONTEXT_EFlags, -12 + .equ CONTEXT_SegCs, -16 + .equ CONTEXT_Eip, -20 + .equ CONTEXT_Ebp, -24 + .equ CONTEXT_Eax, -28 + .equ CONTEXT_Ecx, -32 + .equ CONTEXT_Edx, -36 + .equ CONTEXT_Ebx, -40 + .equ CONTEXT_Esi, -44 + .equ CONTEXT_Edi, -48 + .equ CONTEXT_SegDs, -52 + .equ CONTEXT_SegEs, -56 + .equ CONTEXT_SegFs, -60 + .equ CONTEXT_SegGs, -64 + .equ FLOAT_Cr0NpxState, -68 + .equ FLOAT_RegisterArea, -148 + .equ FLOAT_DataSelector, -152 + .equ FLOAT_DataOffset, -156 + .equ FLOAT_ErrorSelector, -160 + .equ FLOAT_ErrorOffset, -164 + .equ FLOAT_TagWord, -168 + .equ FLOAT_StatusWord, -172 + .equ FLOAT_ControlWord, -176 + .equ CONTEXT_FloatSave, -176 + .equ CONTEXT_Dr7, -180 + .equ CONTEXT_Dr6, -184 + .equ CONTEXT_Dr3, -188 + .equ CONTEXT_Dr2, -192 + .equ CONTEXT_Dr1, -196 + .equ CONTEXT_Dr0, -200 + .equ CONTEXT_ContextFlags, -204 + .equ CONTEXT, -204 + .equ CONTEXTSIZE, 204 + .equ CONTEXTFLAGS, 0x10007 + + .equ ORIG_ESP, 16 /** cdecl !!! **/ + .equ PARM_ARG4, 28 + .equ PARM_ARG3, 24 + .equ PARM_ARG2, 20 + .equ PARM_ARG1, 16 + .equ PARM_RETURN, 12 + .equ PARM_CALLFUNC, 8 + .equ PARM_EBP, 4 + .equ PARM_EFLAGS, 0 + +#ifndef __ELF__ + .globl _RaiseException + .extern _EXC_RaiseException + + _RaiseException: + push $_EXC_RaiseException + jmp ContextCall + + .globl _RtlUnwind + + _RtlUnwind: + push $_EXC_RtlUnwind + +#else /* __ELF__ */ + .globl RaiseException + .extern EXC_RaiseException + + RaiseException: + push $EXC_RaiseException + jmp ContextCall + + .globl RtlUnwind + + RtlUnwind: + push $EXC_RtlUnwind +#endif /* __ELF__ */ + + ContextCall: + pushl %ebp + pushfl + movl %esp, %ebp + subl $CONTEXTSIZE, %esp + movl %eax, CONTEXT_Eax(%ebp) + leal ORIG_ESP(%ebp), %eax + movl %eax, CONTEXT_Esp(%ebp) + movl PARM_EFLAGS(%ebp), %eax + movl %eax, CONTEXT_EFlags(%ebp) + movl PARM_EBP(%ebp), %eax + movl %eax, CONTEXT_Ebp(%ebp) + movl PARM_RETURN(%ebp), %eax + movl %eax, CONTEXT_Eip(%ebp) + movl %edi, CONTEXT_Edi(%ebp) + movl %esi, CONTEXT_Esi(%ebp) + movl %ebx, CONTEXT_Ebx(%ebp) + movl %edx, CONTEXT_Edx(%ebp) + movl %ecx, CONTEXT_Ecx(%ebp) + xorl %eax, %eax + movw %ss, %ax + movl %eax, CONTEXT_SegSs(%ebp) + movw %cs, %ax + movl %eax, CONTEXT_SegCs(%ebp) + movw %gs, %ax + movl %eax, CONTEXT_SegGs(%ebp) + movw %fs, %ax + movl %eax, CONTEXT_SegFs(%ebp) + movw %es, %ax + movl %eax, CONTEXT_SegEs(%ebp) + movw %ds, %ax + movl %eax, CONTEXT_SegDs(%ebp) + fsave CONTEXT_FloatSave(%ebp) + movl $CONTEXTFLAGS, %eax + movl %eax, CONTEXT_ContextFlags(%ebp) + pushl %ebp + leal CONTEXT(%ebp), %eax + pushl %eax + pushl PARM_ARG4(%ebp) + pushl PARM_ARG3(%ebp) + pushl PARM_ARG2(%ebp) + pushl PARM_ARG1(%ebp) + call *PARM_CALLFUNC(%ebp) + addl $20,%esp + popl %ebp + lds CONTEXT_Esp(%ebp),%edi + movl CONTEXT_Eip(%ebp),%eax + movl %eax,-4(%edi) + movl CONTEXT_EFlags(%ebp),%eax + movl %eax,-8(%edi) + movl CONTEXT_Edi(%ebp),%eax + movl %eax,-12(%edi) + movl CONTEXT_SegDs(%ebp),%eax + movw %ax,%ds + movl CONTEXT_SegEs(%ebp),%eax + movw %ax,%es + movl CONTEXT_SegFs(%ebp),%eax + movw %ax,%fs + movl CONTEXT_SegGs(%ebp),%eax + movw %ax,%gs + frstor CONTEXT_FloatSave(%ebp) + movl CONTEXT_Ecx(%ebp),%ecx + movl CONTEXT_Edx(%ebp),%edx + movl CONTEXT_Ebx(%ebp),%ebx + movl CONTEXT_Esi(%ebp),%esi + movl CONTEXT_Eax(%ebp),%eax + movl CONTEXT_Ebp(%ebp),%ebp + lea -12(%edi),%esp + popl %edi + popfl + ret diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec index b54f516f434..20f485a9c75 100644 --- a/if1632/kernel32.spec +++ b/if1632/kernel32.spec @@ -445,7 +445,7 @@ base 1 0440 stub ResumeThread 0441 stub RtlFillMemory 0442 stub RtlMoveMemory -0443 stub RtlUnwind +0443 stdcall RtlUnwind(ptr long ptr long) RtlUnwind 0444 stub RtlZeroMemory 0445 stub ScrollConsoleScreenBufferA 0446 stub ScrollConsoleScreenBufferW @@ -518,7 +518,7 @@ base 1 0513 stub SetThreadLocale 0514 stub SetThreadPriority 0515 stub SetTimeZoneInformation -0516 stub SetUnhandledExceptionFilter +0516 stdcall SetUnhandledExceptionFilter(ptr) SetUnhandledExceptionFilter 0517 stub SetVDMCurrentDirectories 0518 stub SetVolumeLabelA 0519 stub SetVolumeLabelW @@ -539,7 +539,7 @@ base 1 0534 stub TransactNamedPipe 0535 stub TransmitCommChar 0536 stub TrimVirtualBuffer -0537 stub UnhandledExceptionFilter +0537 stdcall UnhandledExceptionFilter(ptr) UnhandledExceptionFilter 0538 stub UnlockFile 0539 stub UnlockFileEx 0540 stub UnmapViewOfFile diff --git a/if1632/keyboard.spec b/if1632/keyboard.spec index af38f70a9c7..714bd3c0372 100644 --- a/if1632/keyboard.spec +++ b/if1632/keyboard.spec @@ -7,7 +7,7 @@ id 7 4 pascal16 ToAscii(word word ptr ptr word) ToAscii 5 pascal16 AnsiToOem(ptr ptr) AnsiToOem 6 pascal16 OemToAnsi(ptr ptr) OemToAnsi -#7 pascal SetSpeed +7 return SetSpeed 2 65535 #100 pascal ScreenSwitchEnable #126 pascal GetTableSeg #127 pascal NewTable diff --git a/if1632/user.spec b/if1632/user.spec index 4df1c0f8311..fcc0b1baafc 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -13,7 +13,7 @@ id 2 12 pascal16 KillTimer(word word) KillTimer 13 pascal GetTickCount() GetTickCount 14 pascal GetTimerResolution() GetTimerResolution -15 pascal GetCurrentTime() GetTickCount +15 pascal GetCurrentTime() GetCurrentTime 16 pascal16 ClipCursor(ptr) ClipCursor 17 pascal16 GetCursorPos(ptr) GetCursorPos 18 pascal16 SetCapture(word) SetCapture diff --git a/include/class.h b/include/class.h index 90c3a3c9ab8..073745f261e 100644 --- a/include/class.h +++ b/include/class.h @@ -31,9 +31,10 @@ typedef struct tagCLASS #pragma pack(4) #endif - -HCLASS CLASS_FindClassByName( SEGPTR name, HINSTANCE hinstance, CLASS **ptr ); -CLASS * CLASS_FindClassPtr( HCLASS hclass ); - +extern void CLASS_DumpClass( HCLASS hClass ); +extern void CLASS_WalkClasses(void); +extern HCLASS CLASS_FindClassByName( SEGPTR name, HINSTANCE hinstance, + CLASS **ptr ); +extern CLASS * CLASS_FindClassPtr( HCLASS hclass ); #endif /* CLASS_H */ diff --git a/include/debugger.h b/include/debugger.h index 8cc7c48287a..42b42064d42 100644 --- a/include/debugger.h +++ b/include/debugger.h @@ -89,10 +89,6 @@ extern void DEBUG_Print( const DBG_ADDR *addr, int count, char format ); extern void DEBUG_PrintAddress( const DBG_ADDR *addr, int addrlen ); extern void DEBUG_Help(void); extern void DEBUG_List( DBG_ADDR *addr, int count ); -extern void DEBUG_InitWalk(void); -extern void DEBUG_WndWalk( HWND ); -extern void DEBUG_WndDump( HWND ); -extern void DEBUG_QueueDump( HQUEUE ); /* debugger/memory.c */ extern BOOL DEBUG_IsBadReadPtr( const DBG_ADDR *address, int size ); diff --git a/include/except.h b/include/except.h new file mode 100644 index 00000000000..c3654fbcfc3 --- /dev/null +++ b/include/except.h @@ -0,0 +1,283 @@ +/* + * except.h + * Copyright (c) 1996, Onno Hovers (onno@stack.urc.tue.nl) + */ + +#ifndef __WINE_EXCEPT_H +#define __WINE_EXCEPT_H + +#include"windows.h" + +/* + * general definitions + */ + +#ifndef PVOID +#define PVOID void * +#endif + +/* + * exception codes + */ + +#define STATUS_WAIT_0 0x00000000 +#define STATUS_ABANDONED_WAIT_0 0x00000080 +#define STATUS_USER_APC 0x000000C0 +#define STATUS_TIMEOUT 0x00000102 +#define STATUS_PENDING 0x00000103 +#define STATUS_DATATYPE_MISALIGNMENT 0x80000002 +#define STATUS_BREAKPOINT 0x80000003 +#define STATUS_SINGLE_STEP 0x80000004 +#define STATUS_ACCESS_VIOLATION 0xC0000005 +#define STATUS_IN_PAGE_ERROR 0xC0000006 +#define STATUS_NO_MEMORY 0xC0000017 +#define STATUS_ILLEGAL_INSTRUCTION 0xC000001D +#define STATUS_NONCONTINUABLE_EXCEPTION 0xC0000025 +#define STATUS_INVALID_DISPOSITION 0xC0000026 +#define STATUS_ARRAY_BOUNDS_EXCEEDED 0xC000008C +#define STATUS_FLOAT_DENORMAL_OPERAND 0xC000008D +#define STATUS_FLOAT_DIVIDE_BY_ZERO 0xC000008E +#define STATUS_FLOAT_INEXACT_RESULT 0xC000008F +#define STATUS_FLOAT_INVALID_OPERATION 0xC0000090 +#define STATUS_FLOAT_OVERFLOW 0xC0000091 +#define STATUS_FLOAT_STACK_CHECK 0xC0000092 +#define STATUS_FLOAT_UNDERFLOW 0xC0000093 +#define STATUS_INTEGER_DIVIDE_BY_ZERO 0xC0000094 +#define STATUS_INTEGER_OVERFLOW 0xC0000095 +#define STATUS_PRIVILEGED_INSTRUCTION 0xC0000096 +#define STATUS_STACK_OVERFLOW 0xC00000FD +#define STATUS_CONTROL_C_EXIT 0xC000013A + +#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION +#define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT +#define EXCEPTION_BREAKPOINT STATUS_BREAKPOINT +#define EXCEPTION_SINGLE_STEP STATUS_SINGLE_STEP +#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED STATUS_ARRAY_BOUNDS_EXCEEDED +#define EXCEPTION_FLT_DENORMAL_OPERAND STATUS_FLOAT_DENORMAL_OPERAND +#define EXCEPTION_FLT_DIVIDE_BY_ZERO STATUS_FLOAT_DIVIDE_BY_ZERO +#define EXCEPTION_FLT_INEXACT_RESULT STATUS_FLOAT_INEXACT_RESULT +#define EXCEPTION_FLT_INVALID_OPERATION STATUS_FLOAT_INVALID_OPERATION +#define EXCEPTION_FLT_OVERFLOW STATUS_FLOAT_OVERFLOW +#define EXCEPTION_FLT_STACK_CHECK STATUS_FLOAT_STACK_CHECK +#define EXCEPTION_FLT_UNDERFLOW STATUS_FLOAT_UNDERFLOW +#define EXCEPTION_INT_DIVIDE_BY_ZERO STATUS_INTEGER_DIVIDE_BY_ZERO +#define EXCEPTION_INT_OVERFLOW STATUS_INTEGER_OVERFLOW +#define EXCEPTION_PRIV_INSTRUCTION STATUS_PRIVILEGED_INSTRUCTION +#define EXCEPTION_IN_PAGE_ERROR STATUS_IN_PAGE_ERROR + +/* + * return values from the actual exception handlers + */ + +#define ExceptionContinueExecution 0 +#define ExceptionContinueSearch 1 +#define ExceptionNestedException 2 +#define ExceptionCollidedUnwind 3 + +/* + * return values from filters in except() and from UnhandledExceptionFilter + */ + +#define EXCEPTION_EXECUTE_HANDLER 1 +#define EXCEPTION_CONTINUE_SEARCH 0 +#define EXCEPTION_CONTINUE_EXECUTION -1 + +/* + * from OS/2 2.0 exception handling + * Win32 seems to use the same flags as ExceptionFlags in an EXCEPTION_RECORD + */ + +#define EH_NONCONTINUABLE 0x01 +#define EH_UNWINDING 0x02 +#define EH_EXIT_UNWIND 0x04 +#define EH_STACK_INVALID 0x08 +#define EH_NESTED_CALL 0x10 + +#define EXCEPTION_CONTINUABLE 0 +#define EXCEPTION_NONCONTINUABLE EH_NONCONTINUABLE + +/* + * data types + */ + +/* + * The i386 context used by Win32 for almost everything. + */ + +#define SIZE_OF_80387_REGISTERS 80 + +typedef struct _FLOATING_SAVE_AREA +{ + DWORD ControlWord; + DWORD StatusWord; + DWORD TagWord; + DWORD ErrorOffset; + DWORD ErrorSelector; + DWORD DataOffset; + DWORD DataSelector; + BYTE RegisterArea[SIZE_OF_80387_REGISTERS]; + DWORD Cr0NpxState; +} FLOATING_SAVE_AREA; + +typedef struct __CONTEXT +{ + DWORD ContextFlags; + DWORD Dr0; + DWORD Dr1; + DWORD Dr2; + DWORD Dr3; + DWORD Dr6; + DWORD Dr7; + FLOATING_SAVE_AREA FloatSave; + DWORD SegGs; + DWORD SegFs; + DWORD SegEs; + DWORD SegDs; + DWORD Edi; + DWORD Esi; + DWORD Ebx; + DWORD Edx; + DWORD Ecx; + DWORD Eax; + DWORD Ebp; + DWORD Eip; + DWORD SegCs; + DWORD EFlags; + DWORD Esp; + DWORD SegSs; +} CONTEXT; + +typedef struct __CONTEXT *PCONTEXT; + +/* + * The exception record used by Win32 to give additional information + * about exception to exception handlers. + */ + +#define EXCEPTION_MAXIMUM_PARAMETERS 15 + +typedef struct __EXCEPTION_RECORD +{ + DWORD ExceptionCode; + DWORD ExceptionFlags; + struct __EXCEPTION_RECORD *ExceptionRecord; + + PVOID ExceptionAddress; + DWORD NumberParameters; + DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; +} EXCEPTION_RECORD; + +typedef struct __EXCEPTION_RECORD_MIN +{ + DWORD ExceptionCode; + DWORD ExceptionFlags; + struct __EXCEPTION_RECORD *ExceptionRecord; + + PVOID ExceptionAddress; + DWORD NumberParameters; + DWORD ExceptionInformation[0]; +} EXCEPTION_RECORD_MIN; + +typedef struct __EXCEPTION_RECORD *PEXCEPTION_RECORD; + +/* + * The exception pointers structure passed to exception filters + * in except() and the UnhandledExceptionFilter(). + */ + +typedef struct __EXCEPTION_POINTERS +{ + PEXCEPTION_RECORD ExceptionRecord; + PCONTEXT ContextRecord; +} EXCEPTION_POINTERS; + +typedef struct __EXCEPTION_POINTERS *PEXCEPTION_POINTERS; + +/* + * the function pointer to a exception handler + */ + +/* forward definition */ +struct __EXCEPTION_FRAME; + +typedef DWORD ( *PEXCEPTION_HANDLER)( PEXCEPTION_RECORD pexcrec, + struct __EXCEPTION_FRAME *pestframe, + PCONTEXT pcontext, + PVOID pdispatcher); + +/* + * function pointer to a UnhandledExceptionFilter(); + */ + +typedef long (WINAPI *__PTOP_EXCFILTER) + (PEXCEPTION_POINTERS ExceptionInfo); + +typedef __PTOP_EXCFILTER PTOP_LEVER_EXCEPTION_FILTER; +typedef __PTOP_EXCFILTER LPTOP_LEVEL_EXCEPTION_FILTER; + +/* + * The exception frame, used for registering exception handlers + * Win32 cares only about this, but compilers generally emit + * larger exception frames for their own use. + */ + +typedef struct __EXCEPTION_FRAME +{ + struct __EXCEPTION_FRAME *Prev; + PEXCEPTION_HANDLER Handler; +} EXCEPTION_FRAME; + +typedef struct __EXCEPTION_FRAME *PEXCEPTION_FRAME; + +extern PEXCEPTION_FRAME TebExceptionFrame asm("%fs:0"); + +#define EXC_GetFrame() TebExceptionFrame +#define EXC_SetFrame(a) (TebExceptionFrame=(a)) + +/* + * Function definitions + */ + +void EXC_RaiseException(DWORD exccode, DWORD excflags, + DWORD nargs, const LPDWORD pargs, + PCONTEXT pcontext); + +void EXC_RtlUnwind( PEXCEPTION_FRAME pestframe, + LPVOID unusedEIP, + PEXCEPTION_RECORD pexcrec, + DWORD contextEAX, + PCONTEXT pcontext ); + +DWORD EXC_CallUnhandledExceptionFilter( PEXCEPTION_RECORD precord, + PCONTEXT pcontext); + +void EXC_Init(void); + +BOOL WINAPI RaiseException(DWORD exccode, DWORD excflags, + DWORD nargs, const LPDWORD pargs); + +/* + * this undocumented function is called when an exception + * handler wants all the frames to be unwound. RtlUnwind + * calls all exception handlers with the EH_UNWIND or + * EH_EXIT_UNWIND flags set in the exception record + * + * This prototype assumes RtlUnwind takes the same + * parameters as OS/2 2.0 DosUnwindException + * Disassembling RtlUnwind shows this is true, except for + * the TargetEIP parameter, which is unused. There is + * a fourth parameter, that is used as the eax in the + * context. + */ + +BOOL WINAPI RtlUnwind( PEXCEPTION_FRAME pestframe, + LPVOID unusedEIP, + PEXCEPTION_RECORD pexcrec, + DWORD contextEAX ); + +DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers); + +__PTOP_EXCFILTER WINAPI SetUnhandledExceptionFilter( + LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter); + +#endif /* __WINE_EXCEPT_H */ diff --git a/include/kernel32.h b/include/kernel32.h index 12e5761785e..53e28b65a70 100644 --- a/include/kernel32.h +++ b/include/kernel32.h @@ -10,6 +10,7 @@ int KERN32_Init(void); void SetLastError(DWORD error); DWORD ErrnoToLastError(int errno_num); +void ExitProcess(DWORD exitcode); /* Code page information. */ diff --git a/include/listbox.h b/include/listbox.h index 5430172307e..60bed755a71 100644 --- a/include/listbox.h +++ b/include/listbox.h @@ -25,6 +25,7 @@ typedef struct { WORD CtlID; LPLISTSTRUCT lpFirst; HWND hSelf; + DWORD dwStyle; /* added for COMBOLBOX style faking */ HWND hParent; HFONT hFont; BOOL bRedrawFlag; diff --git a/include/message.h b/include/message.h index bf242b7f299..870695cb40d 100644 --- a/include/message.h +++ b/include/message.h @@ -1,83 +1,20 @@ /* - * Message queues definitions + * Message definitions * * Copyright 1993 Alexandre Julliard */ -#ifndef MESSAGE_H -#define MESSAGE_H +#ifndef __WINE_MESSAGE_H +#define __WINE_MESSAGE_H #include "windows.h" -#ifndef WINELIB -#pragma pack(1) -#endif - - /* Message as stored in the queue (contains the extraInfo field) */ -typedef struct tagQMSG -{ - DWORD extraInfo; /* Only in 3.1 */ - MSG msg; -} QMSG; - - -typedef struct tagMESSAGEQUEUE -{ - HANDLE next; /* 00 Next queue */ - HTASK hTask; /* 02 hTask owning the queue */ - WORD msgSize; /* 04 Size of messages in the queue */ - WORD msgCount; /* 06 Number of waiting messages */ - WORD nextMessage; /* 08 Next message to be retrieved */ - WORD nextFreeMessage; /* 0a Next available slot in the queue */ - WORD queueSize; /* 0c Size of the queue */ - DWORD GetMessageTimeVal WINE_PACKED; /* 0e Value for GetMessageTime */ - DWORD GetMessagePosVal WINE_PACKED; /* 12 Value for GetMessagePos */ - WORD reserved1; /* 16 Unknown */ - DWORD GetMessageExtraInfoVal; /* 18 Value for GetMessageExtraInfo */ - WORD reserved2; /* 1c Unknown */ - LPARAM lParam WINE_PACKED; /* 1e Next 4 values set by SendMessage */ - WPARAM wParam; /* 22 */ - UINT msg; /* 24 */ - HWND hWnd; /* 26 */ - DWORD SendMessageReturn; /* 28 Return value for SendMessage */ - WORD wPostQMsg; /* 2c PostQuitMessage flag */ - WORD wExitCode; /* 2e PostQuitMessage exit code */ - WORD reserved3[3]; /* 30 Unknown */ - WORD wWinVersion; /* 36 Expected Windows version */ - HQUEUE InSendMessageHandle; /* 38 Queue of task that sent a message */ - HTASK hSendingTask; /* 3a Handle of task that sent a message */ - HTASK hPrevSendingTask; /* 3c Handle of previous sender */ - WORD wPaintCount; /* 3e Number of WM_PAINT needed */ - WORD wTimerCount; /* 40 Number of timers for this task */ - WORD tempStatus; /* 42 State reset by GetQueueStatus */ - WORD status; /* 44 Queue state */ - WORD wakeMask; /* 46 Task wake-up mask */ - WORD SendMsgReturnPtrs[3]; /* 48 Near ptr to return values (?) */ - HANDLE hCurHook; /* 4e Current hook */ - HANDLE hooks[WH_NB_HOOKS]; /* 50 Task hooks list */ - WORD reserved4[3]; /* 68 Unknown */ - QMSG messages[1]; /* 6e Queue messages */ -} MESSAGEQUEUE; - -#ifndef WINELIB -#pragma pack(4) -#endif - extern DWORD MSG_WineStartTicks; /* Ticks at Wine startup */ -extern void MSG_IncPaintCount( HANDLE hQueue ); -extern void MSG_DecPaintCount( HANDLE hQueue ); -extern void MSG_IncTimerCount( HANDLE hQueue ); -extern void MSG_DecTimerCount( HANDLE hQueue ); extern void MSG_Synchronize(); extern BOOL MSG_WaitXEvent( LONG maxWait ); -extern BOOL MSG_CreateSysMsgQueue( int size ); -extern BOOL MSG_DeleteMsgQueue( HANDLE hQueue ); -extern HTASK MSG_GetQueueTask( HANDLE hQueue ); -extern void hardware_event( WORD message, WORD wParam, LONG lParam, - int xPos, int yPos, DWORD time, DWORD extraInfo ); extern BOOL MSG_GetHardwareMessage( LPMSG msg ); extern BOOL MSG_InternalGetMessage( SEGPTR msg, HWND hwnd, HWND hwndOwner, short code, WORD flags, BOOL sendIdle ); -#endif /* MESSAGE_H */ +#endif /* __WINE_MESSAGE_H */ diff --git a/include/queue.h b/include/queue.h new file mode 100644 index 00000000000..fba9398c336 --- /dev/null +++ b/include/queue.h @@ -0,0 +1,83 @@ +/* + * Message queues definitions + * + * Copyright 1993 Alexandre Julliard + */ + +#ifndef __WINE_QUEUE_H +#define __WINE_QUEUE_H + +#include "windows.h" + +#ifndef WINELIB +#pragma pack(1) +#endif + + /* Message as stored in the queue (contains the extraInfo field) */ +typedef struct tagQMSG +{ + DWORD extraInfo; /* Only in 3.1 */ + MSG msg; +} QMSG; + + +typedef struct tagMESSAGEQUEUE +{ + HQUEUE next; /* 00 Next queue */ + HTASK hTask; /* 02 hTask owning the queue */ + WORD msgSize; /* 04 Size of messages in the queue */ + WORD msgCount; /* 06 Number of waiting messages */ + WORD nextMessage; /* 08 Next message to be retrieved */ + WORD nextFreeMessage; /* 0a Next available slot in the queue */ + WORD queueSize; /* 0c Size of the queue */ + DWORD GetMessageTimeVal WINE_PACKED; /* 0e Value for GetMessageTime */ + DWORD GetMessagePosVal WINE_PACKED; /* 12 Value for GetMessagePos */ + WORD reserved1; /* 16 Unknown */ + DWORD GetMessageExtraInfoVal; /* 18 Value for GetMessageExtraInfo */ + WORD reserved2; /* 1c Unknown */ + LPARAM lParam WINE_PACKED; /* 1e Next 4 values set by SendMessage */ + WPARAM wParam; /* 22 */ + UINT msg; /* 24 */ + HWND hWnd; /* 26 */ + DWORD SendMessageReturn; /* 28 Return value for SendMessage */ + WORD wPostQMsg; /* 2c PostQuitMessage flag */ + WORD wExitCode; /* 2e PostQuitMessage exit code */ + WORD reserved3[3]; /* 30 Unknown */ + WORD wWinVersion; /* 36 Expected Windows version */ + HQUEUE InSendMessageHandle; /* 38 Queue of task that sent a message */ + HTASK hSendingTask; /* 3a Handle of task that sent a message */ + HTASK hPrevSendingTask; /* 3c Handle of previous sender */ + WORD wPaintCount; /* 3e Number of WM_PAINT needed */ + WORD wTimerCount; /* 40 Number of timers for this task */ + WORD tempStatus; /* 42 State reset by GetQueueStatus */ + WORD status; /* 44 Queue state */ + WORD wakeMask; /* 46 Task wake-up mask */ + WORD SendMsgReturnPtrs[3]; /* 48 Near ptr to return values (?) */ + HANDLE hCurHook; /* 4e Current hook */ + HANDLE hooks[WH_NB_HOOKS]; /* 50 Task hooks list */ + WORD reserved4[3]; /* 68 Unknown */ + QMSG messages[1]; /* 6e Queue messages */ +} MESSAGEQUEUE; + +#ifndef WINELIB +#pragma pack(4) +#endif + +extern void QUEUE_DumpQueue( HQUEUE hQueue ); +extern void QUEUE_WalkQueues(void); +extern MESSAGEQUEUE *QUEUE_GetSysQueue(void); +extern void QUEUE_IncPaintCount( HQUEUE hQueue ); +extern void QUEUE_DecPaintCount( HQUEUE hQueue ); +extern void QUEUE_IncTimerCount( HQUEUE hQueue ); +extern void QUEUE_DecTimerCount( HQUEUE hQueue ); +extern BOOL QUEUE_CreateSysMsgQueue( int size ); +extern BOOL QUEUE_DeleteMsgQueue( HQUEUE hQueue ); +extern HTASK QUEUE_GetQueueTask( HQUEUE hQueue ); +extern BOOL QUEUE_AddMsg( HQUEUE hQueue, MSG * msg, DWORD extraInfo ); +extern int QUEUE_FindMsg( MESSAGEQUEUE * msgQueue, HWND hwnd, + int first, int last ); +extern void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos ); +extern void hardware_event( WORD message, WORD wParam, LONG lParam, + int xPos, int yPos, DWORD time, DWORD extraInfo ); + +#endif /* __WINE_QUEUE_H */ diff --git a/include/spy.h b/include/spy.h index d4d9c65421d..c039241d0dd 100644 --- a/include/spy.h +++ b/include/spy.h @@ -5,18 +5,16 @@ #ifndef __WINE_SPY_H #define __WINE_SPY_H -#define SPY_DISPATCHMESSAGE 0x0099 -#define SPY_SENDMESSAGE 0x0100 -#define SPY_DEFWNDPROC 0x0101 +#define SPY_DISPATCHMESSAGE 0x0100 +#define SPY_SENDMESSAGE 0x0101 +#define SPY_DEFWNDPROC 0x0102 #define SPY_RESULT_OK 0x0000 #define SPY_RESULT_INVALIDHWND 0x0001 -#define SPY_MAX_MSGNUM WM_USER -#define SPY_MAX_INDENTLEVEL 64 - -extern void EnterSpyMessage( int, HWND, WORD, WORD, LONG); -extern void ExitSpyMessage( int, HWND, WORD, LONG); -extern void SpyInit( void); +extern void SPY_EnterMessage( int iFlag, HWND hwnd, UINT msg, + WPARAM wParam, LPARAM lParam ); +extern void SPY_ExitMessage( int iFlag, HWND hwnd, UINT msg, LRESULT lReturn ); +extern int SPY_Init(void); #endif /* __WINE_SPY_H */ diff --git a/include/task.h b/include/task.h index d2a2b30ebff..82bc80e4129 100644 --- a/include/task.h +++ b/include/task.h @@ -73,7 +73,7 @@ typedef struct WORD version; /* Expected Windows version */ HANDLE hInstance; /* Instance handle for this task */ HMODULE hModule; /* Module handle */ - HANDLE hQueue; /* Selector of task message queue */ + HQUEUE hQueue; /* Selector of task message queue */ HTASK hParent; /* Selector of TDB of parent task */ WORD signal_flags; /* Flags related to signal handler */ DWORD sighandler WINE_PACKED; /* Signal handler */ diff --git a/include/win.h b/include/win.h index 37184a772b8..f3b49b1326a 100644 --- a/include/win.h +++ b/include/win.h @@ -75,6 +75,8 @@ typedef struct tagWND /* Window functions */ extern WND *WIN_FindWndPtr( HWND hwnd ); +extern void WIN_DumpWindow( HWND hwnd ); +extern void WIN_WalkWindows( HWND hwnd, int indent ); extern Window WIN_GetXWindow( HWND hwnd ); extern BOOL WIN_UnlinkWindow( HWND hwnd ); extern BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter ); diff --git a/include/windows.h b/include/windows.h index 3fd0086e349..53be8c89296 100644 --- a/include/windows.h +++ b/include/windows.h @@ -2222,6 +2222,14 @@ typedef struct typedef COMPAREITEMSTRUCT NEAR* PCOMPAREITEMSTRUCT; typedef COMPAREITEMSTRUCT FAR* LPCOMPAREITEMSTRUCT; +/* WM_KEYUP/DOWN/CHAR HIWORD(lParam) flags */ +#define KF_EXTENDED 0x0100 +#define KF_DLGMODE 0x0800 +#define KF_MENUMODE 0x1000 +#define KF_ALTDOWN 0x2000 +#define KF_REPEAT 0x4000 +#define KF_UP 0x8000 + /* Virtual key codes */ #define VK_LBUTTON 0x01 #define VK_RBUTTON 0x02 @@ -2947,7 +2955,7 @@ WORD GetSystemPaletteUse(HDC); VOID GetSystemTime(LPSYSTEMTIME); /* Win32 */ DWORD GetTabbedTextExtent(HDC,LPSTR,int,int,LPINT); HINSTANCE GetTaskDS(void); -HGLOBAL GetTaskQueue(HTASK); +HQUEUE GetTaskQueue(HTASK); BYTE GetTempDrive(BYTE); INT GetTempFileName(BYTE,LPCSTR,UINT,LPSTR); WORD GetTextAlign(HDC); @@ -3122,7 +3130,7 @@ BOOL Polygon(HDC,LPPOINT,int); BOOL Polyline(HDC,LPPOINT,int); BOOL PostAppMessage(HANDLE,WORD,WORD,LONG); BOOL PostMessage(HWND,WORD,WORD,LONG); -void PostQuitMessage(int); +void PostQuitMessage(INT); WORD PrestoChangoSelector(WORD,WORD); void ProfClear(void); void ProfFinish(void); @@ -3244,7 +3252,7 @@ void SetSysColors(int,LPINT,COLORREF*); HWND SetSysModalWindow(HWND); WORD SetSystemPaletteUse(HDC,WORD); WORD SetSystemTimer(HWND,WORD,WORD,FARPROC); -HGLOBAL SetTaskQueue(HTASK,HGLOBAL); +HQUEUE SetTaskQueue(HTASK,HQUEUE); WORD SetTextAlign(HDC,WORD); short SetTextCharacterExtra(HDC,short); DWORD SetTextColor(HDC,DWORD); diff --git a/loader/main.c b/loader/main.c index 25c09905d52..0aca285c38c 100644 --- a/loader/main.c +++ b/loader/main.c @@ -22,7 +22,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "dialog.h" #include "directory.h" #include "drive.h" -#include "message.h" +#include "queue.h" #include "syscolor.h" #include "sysmetrics.h" #include "gdi.h" @@ -54,7 +54,8 @@ int MAIN_Init(void) /* Load the configuration file */ if (!PROFILE_LoadWineIni()) return 0; - SpyInit(); + /* Initialize message spying */ + if (!SPY_Init()) return 0; #ifndef WINELIB /* Initialize relay code */ @@ -120,7 +121,10 @@ int MAIN_Init(void) /* Create system message queue */ queueSize = GetProfileInt( "windows", "TypeAhead", 120 ); - if (!MSG_CreateSysMsgQueue( queueSize )) return 0; + if (!QUEUE_CreateSysMsgQueue( queueSize )) return 0; + + /* Set double click time */ + SetDoubleClickTime( GetProfileInt( "windows", "DoubleClickSpeed", 452 ) ); return 1; } diff --git a/loader/signal.c b/loader/signal.c index adc2c648588..3bd175f7247 100644 --- a/loader/signal.c +++ b/loader/signal.c @@ -22,8 +22,6 @@ #if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__) char * cstack[4096]; #endif -struct sigaction segv_act; -struct sigaction usr2_act; #ifdef linux extern void ___sig_restore(); @@ -56,27 +54,32 @@ static void win_fault(int signal, void *siginfo, ucontext_t *context) static void win_fault(int signal, int code, struct sigcontext *context) { #endif - if (signal != SIGTRAP) + if (signal == SIGTRAP) + { + /* If SIGTRAP not caused by breakpoint or single step + don't jump into the debugger */ + if (!(EFL_reg(context) & STEP_FLAG)) + { + DBG_ADDR addr; + addr.seg = CS_reg(context); + addr.off = EIP_reg(context) - 1; + if (DEBUG_FindBreakpoint(&addr) == -1) return; + } + } + else if (signal != SIGHUP) { if (CS_reg(context) == WINE_CODE_SELECTOR) { fprintf(stderr, "Segmentation fault in Wine program (%x:%lx)." - " Please debug\n", + " Please debug.\n", CS_reg(context), EIP_reg(context) ); } - else if (INSTR_EmulateInstruction( context )) return; - fprintf( stderr,"In win_fault %x:%lx\n", - CS_reg(context), EIP_reg(context) ); - } - - /* If SIGTRAP not caused by breakpoint or single step - don't jump into the debugger */ - if ((signal == SIGTRAP) && !(EFL_reg(context) & STEP_FLAG)) - { - DBG_ADDR addr; - addr.seg = CS_reg(context); - addr.off = EIP_reg(context) - 1; - if (DEBUG_FindBreakpoint(&addr) == -1) return; + else + { + if (INSTR_EmulateInstruction( context )) return; + fprintf( stderr, "Segmentation fault in Windows program %x:%lx.\n", + CS_reg(context), EIP_reg(context) ); + } } XUngrabPointer(display, CurrentTime); @@ -85,131 +88,104 @@ static void win_fault(int signal, int code, struct sigcontext *context) wine_debug( signal, context ); /* Enter our debugger */ } + +/********************************************************************** + * SIGNAL_SetHandler + */ +static void SIGNAL_SetHandler( int sig, void (*func)() ) +{ + int ret; + struct sigaction sig_act; + +#ifdef linux + sig_act.sa_handler = func; + /* Point to the top of the stack, minus 4 just in case, and make + it aligned */ + sig_act.sa_restorer = + (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3); + ret = wine_sigaction( sig, &sig_act, NULL ); +#endif /* linux */ + +#if defined(__NetBSD__) || defined(__FreeBSD__) + sig_act.sa_handler = func; + sig_act.sa_flags = SA_ONSTACK; + sig_act.sa_mask = sig_mask; + ret = sigaction( sig, &sig_act, NULL ); +#endif /* __FreeBSD__ || __NetBSD__ */ + +#if defined (__svr4__) + sig_act.sa_handler = func; + sig_act.sa_flags = SA_ONSTACK | SA_SIGINFO; + sig_act.sa_mask = sig_mask; + ret = sigaction( sig, &sig_act, NULL ); +#endif /* __svr4__ */ + + if (ret < 0) + { + perror( "sigaction" ); + exit(1); + } +} + + +/********************************************************************** + * init_wine_signals + */ void init_wine_signals(void) { - extern void stop_wait(int a); -#ifdef linux - segv_act.sa_handler = (__sighandler_t) win_fault; - /* Point to the top of the stack, minus 4 just in case, and make - it aligned */ - segv_act.sa_restorer = - (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3); - /* Point to the top of the stack, minus 4 just in case, and make - it aligned */ - wine_sigaction(SIGSEGV, &segv_act, NULL); - wine_sigaction(SIGILL, &segv_act, NULL); - wine_sigaction(SIGFPE, &segv_act, NULL); -#ifdef SIGBUS - wine_sigaction(SIGBUS, &segv_act, NULL); -#endif - wine_sigaction(SIGTRAP, &segv_act, NULL); /* For breakpoints */ -#ifdef CONFIG_IPC - usr2_act.sa_restorer= segv_act.sa_restorer; - usr2_act.sa_handler = (__sighandler_t) stop_wait; - wine_sigaction(SIGUSR2, &usr2_act, NULL); -#endif /* CONFIG_IPC */ -#endif /* linux */ + extern void stop_wait(int a); + #if defined(__NetBSD__) || defined(__FreeBSD__) - sigset_t sig_mask; - struct sigaltstack ss; + sigset_t sig_mask; + struct sigaltstack ss; #if !defined (__FreeBSD__) - if ((ss.ss_base = malloc(MINSIGSTKSZ)) == NULL) { + if ((ss.ss_base = malloc(MINSIGSTKSZ)) == NULL) { #else - if ((ss.ss_sp = malloc(MINSIGSTKSZ)) == NULL) { + if ((ss.ss_sp = malloc(MINSIGSTKSZ)) == NULL) { #endif - fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n", - MINSIGSTKSZ); - exit(1); - } - ss.ss_size = MINSIGSTKSZ; - ss.ss_flags = 0; - if (sigaltstack(&ss, NULL) < 0) { - perror("sigstack"); - exit(1); - } - sigemptyset(&sig_mask); - segv_act.sa_handler = (void (*)) win_fault; - segv_act.sa_flags = SA_ONSTACK; - segv_act.sa_mask = sig_mask; - if (sigaction(SIGBUS, &segv_act, NULL) < 0) { - perror("sigaction: SIGBUS"); - exit(1); - } - segv_act.sa_handler = (void (*)) win_fault; - segv_act.sa_flags = SA_ONSTACK; - segv_act.sa_mask = sig_mask; - if (sigaction(SIGSEGV, &segv_act, NULL) < 0) { - perror("sigaction: SIGSEGV"); - exit(1); - } - segv_act.sa_handler = (void (*)) win_fault; /* For breakpoints */ - segv_act.sa_flags = SA_ONSTACK; - segv_act.sa_mask = sig_mask; - if (sigaction(SIGTRAP, &segv_act, NULL) < 0) { - perror("sigaction: SIGTRAP"); - exit(1); - } -#ifdef CONFIG_IPC - usr2_act.sa_handler = (void (*)) stop_wait; /* For breakpoints */ - usr2_act.sa_flags = SA_ONSTACK; - usr2_act.sa_mask = sig_mask; - if (sigaction(SIGUSR2, &usr2_act, NULL) < 0) { - perror("sigaction: SIGUSR2"); - exit(1); - } -#endif /* CONFIG_IPC */ + fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n", + MINSIGSTKSZ); + exit(1); + } + ss.ss_size = MINSIGSTKSZ; + ss.ss_flags = 0; + if (sigaltstack(&ss, NULL) < 0) { + perror("sigstack"); + exit(1); + } + sigemptyset(&sig_mask); #endif /* __FreeBSD__ || __NetBSD__ */ -#if defined (__svr4__) - sigset_t sig_mask; - struct sigaltstack ss; - - if ((ss.ss_sp = malloc(SIGSTKSZ) ) == NULL) { - fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n", - SIGSTKSZ); - exit(1); - } - ss.ss_size = SIGSTKSZ; - ss.ss_flags = 0; - if (sigaltstack(&ss, NULL) < 0) { - perror("sigstack"); - exit(1); - } - sigemptyset(&sig_mask); - segv_act.sa_handler = (void (*)) win_fault; - segv_act.sa_flags = SA_ONSTACK | SA_SIGINFO; - segv_act.sa_mask = sig_mask; - if (sigaction(SIGBUS, &segv_act, NULL) < 0) { - perror("sigaction: SIGBUS"); - exit(1); - } - segv_act.sa_handler = (void (*)) win_fault; - segv_act.sa_flags = SA_ONSTACK | SA_SIGINFO; - segv_act.sa_mask = sig_mask; - if (sigaction(SIGSEGV, &segv_act, NULL) < 0) { - perror("sigaction: SIGSEGV"); - exit(1); - } - - segv_act.sa_handler = (void (*)) win_fault; /* For breakpoints */ - segv_act.sa_flags = SA_ONSTACK | SA_SIGINFO; - segv_act.sa_mask = sig_mask; - if (sigaction(SIGTRAP, &segv_act, NULL) < 0) { - perror("sigaction: SIGTRAP"); - exit(1); - } -#ifdef CONFIG_IPC - usr2_act.sa_handler = (void (*)) stop_wait; /* For breakpoints */ - usr2_act.sa_flags = SA_ONSTACK | SA_SIGINFO; - usr2_act.sa_mask = sig_mask; - if (sigaction(SIGUSR2, &usr2_act, NULL) < 0) { - perror("sigaction: SIGUSR2"); - exit(1); - } -#endif /* CONFIG_IPC */ +#if defined (__svr4__) + sigset_t sig_mask; + struct sigaltstack ss; + if ((ss.ss_sp = malloc(SIGSTKSZ) ) == NULL) { + fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n", + SIGSTKSZ); + exit(1); + } + ss.ss_size = SIGSTKSZ; + ss.ss_flags = 0; + if (sigaltstack(&ss, NULL) < 0) { + perror("sigstack"); + exit(1); + } + sigemptyset(&sig_mask); #endif /* __svr4__ */ + + SIGNAL_SetHandler( SIGSEGV, (void (*)())win_fault ); + SIGNAL_SetHandler( SIGILL, (void (*)())win_fault ); + SIGNAL_SetHandler( SIGFPE, (void (*)())win_fault ); + SIGNAL_SetHandler( SIGTRAP, (void (*)())win_fault ); /* For debugger */ + SIGNAL_SetHandler( SIGHUP, (void (*)())win_fault ); /* For forced break */ +#ifdef SIGBUS + SIGNAL_SetHandler( SIGBUS, (void (*)())win_fault ); +#endif +#ifdef CONFIG_IPC + SIGNAL_SetHandler( SIGUSR2, (void (*)())stop_wait ); /* For IPC */ +#endif } #endif /* ifndef WINELIB */ diff --git a/loader/task.c b/loader/task.c index e721cf164cf..d8a0830dc08 100644 --- a/loader/task.c +++ b/loader/task.c @@ -16,11 +16,11 @@ #include "debugger.h" #include "global.h" #include "instance.h" -#include "message.h" #include "miscemu.h" #include "module.h" #include "neexe.h" #include "options.h" +#include "queue.h" #include "selectors.h" #include "toolhelp.h" #include "stddebug.h" @@ -583,7 +583,7 @@ static void TASK_DeleteTask( HTASK hTask ) /* Free the message queue */ - MSG_DeleteMsgQueue( pTask->hQueue ); + QUEUE_DeleteMsgQueue( pTask->hQueue ); /* Free the selector aliases */ @@ -988,9 +988,9 @@ HANDLE GetCodeHandle( FARPROC proc ) /*********************************************************************** * SetTaskQueue (KERNEL.34) */ -HGLOBAL SetTaskQueue( HANDLE hTask, HGLOBAL hQueue ) +HQUEUE SetTaskQueue( HANDLE hTask, HQUEUE hQueue ) { - HGLOBAL hPrev; + HQUEUE hPrev; TDB *pTask; if (!hTask) hTask = hCurrentTask; @@ -1004,7 +1004,7 @@ HGLOBAL SetTaskQueue( HANDLE hTask, HGLOBAL hQueue ) /*********************************************************************** * GetTaskQueue (KERNEL.35) */ -HGLOBAL GetTaskQueue( HANDLE hTask ) +HQUEUE GetTaskQueue( HANDLE hTask ) { TDB *pTask; diff --git a/misc/shell.c b/misc/shell.c index 8e4b9f7e187..2c468173bba 100644 --- a/misc/shell.c +++ b/misc/shell.c @@ -194,8 +194,8 @@ _LoadKey(HKEY hKey,char *from) f=fopen(from,"r"); if (f==NULL) { - perror("fopen-registry-read"); - return; + dprintf_reg(stddeb,"fopen-registry-read"); + return; } switch ((DWORD)hKey) { case HKEY_CLASSES_ROOT: diff --git a/misc/spy.c b/misc/spy.c index 326e0f638d8..065387c5300 100644 --- a/misc/spy.c +++ b/misc/spy.c @@ -1,4 +1,5 @@ -/* SPY.C +/* + * Message spying routines * * Copyright 1994, Bob Amstadt * 1995, Alex Korobka @@ -6,16 +7,18 @@ #include #include -#include -#include #include #include "windows.h" +#include "module.h" #include "options.h" #include "stddebug.h" #include "debug.h" #include "spy.h" -const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = +#define SPY_MAX_MSGNUM WM_USER +#define SPY_INDENT_UNIT 4 /* 4 spaces */ + +static const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = { "WM_NULL", /* 0x00 */ "WM_CREATE", @@ -75,10 +78,12 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_QUERYDRAGICON", "WM_QUERYSAVESTATE", "WM_COMPAREITEM", - "WM_TESTING", NULL, + "WM_TESTING", + NULL, "WM_OTHERWINDOWCREATED", "WM_OTHERWINDOWDESTROYED", - "WM_ACTIVATESHELLWINDOW", NULL, + "WM_ACTIVATESHELLWINDOW", + NULL, NULL, /* 0x40 */ "WM_COMPACTING", NULL, NULL, @@ -391,164 +396,121 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_USER" }; -static BOOL SpyFilters [SPY_MAX_MSGNUM+1]; -static BOOL SpyIncludes[SPY_MAX_MSGNUM+1]; -static int iSpyMessageIndentLevel = 0; - char lpstrSpyMessageIndent[SPY_MAX_INDENTLEVEL]; /* referenced in debugger/info.c */ -static char *lpstrSpyMessageFromWine = "Wine"; -static char lpstrSpyMessageFromTask[10]; -static char *lpstrSpyMessageFromSelf = "self"; -static char *lpstrSpyMessageFrom = NULL; +static BOOL SPY_Exclude[SPY_MAX_MSGNUM+1] = { FALSE, }; +static int SPY_IndentLevel = 0; +#define SPY_EXCLUDE(msg) \ + (SPY_Exclude[(msg) > SPY_MAX_MSGNUM ? SPY_MAX_MSGNUM : (msg)]) -/********************************************************************** - * EnterSpyMessage +/*********************************************************************** + * SPY_GetMsgName */ -void EnterSpyMessage(int iFlag, HWND hWnd, WORD msg, WORD wParam, LONG lParam) +static const char *SPY_GetMsgName( UINT msg ) { - HTASK hTask = GetWindowTask(hWnd); - WORD wCheckMsg = (msg > WM_USER)? WM_USER: msg; - - if( !SpyIncludes[wCheckMsg] || SpyFilters[wCheckMsg]) return; - - /* each SPY_SENDMESSAGE must be complemented by call to ExitSpyMessage */ - switch(iFlag) - { - case SPY_DISPATCHMESSAGE: - if(msg <= WM_USER) - { - if(MessageTypeNames[msg]) - dprintf_message(stddeb,"("NPFMT") message [%04x] %s dispatched wp=%04x lp=%08lx\n", - hWnd, msg, MessageTypeNames[msg], wParam, lParam); - else - dprintf_message(stddeb,"("NPFMT") message [%04x] dispatched wp=%04x lp=%08lx\n", - hWnd, msg, wParam, lParam); - } - else - dprintf_message(stddeb,"("NPFMT") message [%04x] WM_USER+%04d dispatched wp=%04x lp=%08lx\n", - hWnd, msg, msg-WM_USER ,wParam ,lParam); - break; - case SPY_SENDMESSAGE: - if(hTask == GetCurrentTask()) - lpstrSpyMessageFrom = lpstrSpyMessageFromSelf; - else if(hTask == NULL) - lpstrSpyMessageFrom = lpstrSpyMessageFromWine; - else - { - sprintf(lpstrSpyMessageFromTask, "task "NPFMT, hTask); - lpstrSpyMessageFrom = lpstrSpyMessageFromTask; - } - - if(msg <= WM_USER) - { - if(MessageTypeNames[msg]) - dprintf_message(stddeb,"%s("NPFMT") message [%04x] %s sent from %s wp=%04x lp=%08lx\n", - lpstrSpyMessageIndent, - hWnd, msg, MessageTypeNames[msg], - lpstrSpyMessageFrom, - wParam, lParam); - else - dprintf_message(stddeb,"%s("NPFMT") message [%04x] sent from %s wp=%04x lp=%08lx\n", - lpstrSpyMessageIndent, - hWnd, msg, - lpstrSpyMessageFrom, - wParam, lParam); - } - else - dprintf_message(stddeb,"%s("NPFMT") message [%04x] WM_USER+%04x sent from %s wp=%04x lp=%08lx\n", - lpstrSpyMessageIndent, - hWnd, msg, msg-WM_USER, - lpstrSpyMessageFrom, - wParam, lParam); - - if(SPY_MAX_INDENTLEVEL > iSpyMessageIndentLevel ) - { - iSpyMessageIndentLevel++; - lpstrSpyMessageIndent[iSpyMessageIndentLevel]='\0'; - lpstrSpyMessageIndent[iSpyMessageIndentLevel-1] ='\t'; - } - break; - case SPY_DEFWNDPROC: - if(msg <= WM_USER) - if(MessageTypeNames[msg]) - dprintf_message(stddeb, "%s("NPFMT") DefWindowProc: %s [%04x] wp=%04x lp=%08lx\n", - lpstrSpyMessageIndent, - hWnd, MessageTypeNames[msg], msg, wParam, lParam ); - else - dprintf_message(stddeb, "%s("NPFMT") DefWindowProc: [%04x] wp=%04x lp=%08lx\n", - lpstrSpyMessageIndent, - hWnd, msg, wParam, lParam ); - else - dprintf_message(stddeb, "%s("NPFMT") DefWindowProc: WM_USER+%d [%04x] wp=%04x lp=%08lx\n", - lpstrSpyMessageIndent, - hWnd, msg - WM_USER, msg, wParam, lParam ); - break; - default: - } + static char buffer[20]; + if (msg <= SPY_MAX_MSGNUM) + { + if (!MessageTypeNames[msg]) return "???"; + return MessageTypeNames[msg]; + } + sprintf( buffer, "WM_USER+%04x\n", msg - WM_USER ); + return buffer; } -/********************************************************************** - * ExitSpyMessage + +/*********************************************************************** + * SPY_EnterMessage */ -void ExitSpyMessage(int iFlag, HWND hWnd, WORD msg, LONG lReturn) +void SPY_EnterMessage( int iFlag, HWND hWnd, UINT msg, + WPARAM wParam, LPARAM lParam ) { - WORD wCheckMsg = (msg > WM_USER)? WM_USER: msg; + if (!debugging_message || SPY_EXCLUDE(msg)) return; - if( !SpyIncludes[wCheckMsg] || SpyFilters[wCheckMsg]) return; - - if( iSpyMessageIndentLevel ) + /* each SPY_SENDMESSAGE must be complemented by call to ExitSpyMessage */ + switch(iFlag) { - iSpyMessageIndentLevel--; - lpstrSpyMessageIndent[iSpyMessageIndentLevel]='\0'; - } + case SPY_DISPATCHMESSAGE: + dprintf_message(stddeb,"("NPFMT") message [%04x] %s dispatched wp=%04x lp=%08lx\n", + hWnd, msg, SPY_GetMsgName( msg ), + wParam, lParam); + break; - switch(iFlag) + case SPY_SENDMESSAGE: + { + char taskName[30]; + HTASK hTask = GetWindowTask(hWnd); + if (hTask == GetCurrentTask()) strcpy( taskName, "self" ); + else if (!hTask) strcpy( taskName, "Wine" ); + else sprintf( taskName, "task "NPFMT" %s", + hTask, MODULE_GetModuleName( GetExePtr(hTask) ) ); + + dprintf_message(stddeb,"%*s("NPFMT") message [%04x] %s sent from %s wp=%04x lp=%08lx\n", + SPY_IndentLevel, "", hWnd, msg, + SPY_GetMsgName( msg ), taskName, wParam, lParam ); + SPY_IndentLevel += SPY_INDENT_UNIT; + } + break; + + case SPY_DEFWNDPROC: + dprintf_message(stddeb, "%*s("NPFMT") DefWindowProc: %s [%04x] wp=%04x lp=%08lx\n", + SPY_IndentLevel, "", hWnd, SPY_GetMsgName( msg ), + msg, wParam, lParam ); + break; + } +} + + +/*********************************************************************** + * SPY_ExitMessage + */ +void SPY_ExitMessage( int iFlag, HWND hWnd, UINT msg, LRESULT lReturn ) +{ + if (!debugging_message || SPY_EXCLUDE(msg)) return; + if (SPY_IndentLevel) SPY_IndentLevel -= SPY_INDENT_UNIT; + + switch(iFlag) { - case SPY_RESULT_INVALIDHWND: - dprintf_message(stddeb,"%s("NPFMT") message [%04x] HAS INVALID HWND\n", - lpstrSpyMessageIndent, hWnd, msg); - break; - case SPY_RESULT_OK: - dprintf_message(stddeb,"%s("NPFMT") message [%04x] returned %08lx\n", - lpstrSpyMessageIndent, hWnd, msg, lReturn); - break; - default: + case SPY_RESULT_INVALIDHWND: + dprintf_message(stddeb,"%*s("NPFMT") message [%04x] %s HAS INVALID HWND\n", + SPY_IndentLevel, "", hWnd, msg, + SPY_GetMsgName( msg ) ); + break; + case SPY_RESULT_OK: + dprintf_message(stddeb,"%*s("NPFMT") message [%04x] %s returned %08lx\n", + SPY_IndentLevel, "", hWnd, msg, + SPY_GetMsgName( msg ), lReturn ); + break; } } -/********************************************************************** - * SpyInit + +/*********************************************************************** + * SPY_Init */ -void SpyInit(void) +int SPY_Init(void) { - int i; - char lpstrBuffer[512]; + int i; + char buffer[512]; - for(i=0; i <= SPY_MAX_MSGNUM; i++) SpyFilters[i] = SpyIncludes[i] = FALSE; - - PROFILE_GetWineIniString( "spy", "Exclude", "", - lpstrBuffer, sizeof(lpstrBuffer) ); - dprintf_message(stddeb,"SpyInit: Exclude=%s\n",lpstrBuffer); - if( *lpstrBuffer != 0 ) - if(strstr(lpstrBuffer,"EXCLUDEALL")) - for(i=0; i <= SPY_MAX_MSGNUM; i++) SpyFilters[i] = TRUE; - else - for(i=0; i <= SPY_MAX_MSGNUM; i++) - if(MessageTypeNames[i]) - if(strstr(lpstrBuffer,MessageTypeNames[i])) SpyFilters[i] = TRUE; - - PROFILE_GetWineIniString( "spy", "Include", "INCLUDEALL", - lpstrBuffer, sizeof(lpstrBuffer) ); - dprintf_message(stddeb,"SpyInit: Include=%s\n",lpstrBuffer); - if( *lpstrBuffer != 0 ) - if(strstr(lpstrBuffer,"INCLUDEALL")) - for(i=0; i <= SPY_MAX_MSGNUM; i++) SpyIncludes[i] = TRUE; - else - for(i=0; i <= SPY_MAX_MSGNUM; i++) - if(MessageTypeNames[i]) - if(strstr(lpstrBuffer,MessageTypeNames[i])) SpyIncludes[i] = TRUE; + PROFILE_GetWineIniString( "Spy", "Include", "", buffer, sizeof(buffer) ); + if (buffer[0] && strcmp( buffer, "INCLUDEALL" )) + { + dprintf_message( stddeb, "SpyInit: Include=%s\n", buffer ); + for (i = 0; i <= SPY_MAX_MSGNUM; i++) + SPY_Exclude[i] = (MessageTypeNames[i] && !strstr(buffer,MessageTypeNames[i])); + } + PROFILE_GetWineIniString( "Spy", "Exclude", "", buffer, sizeof(buffer) ); + if (buffer[0]) + { + dprintf_message( stddeb, "SpyInit: Exclude=%s\n", buffer ); + if (!strcmp( buffer, "EXCLUDEALL" )) + for (i = 0; i <= SPY_MAX_MSGNUM; i++) SPY_Exclude[i] = TRUE; + else + for (i = 0; i <= SPY_MAX_MSGNUM; i++) + SPY_Exclude[i] = (MessageTypeNames[i] && strstr(buffer,MessageTypeNames[i])); + } + return 1; } - diff --git a/misc/user.c b/misc/user.c index 4fe51e84e7e..0a3cd4fad7a 100644 --- a/misc/user.c +++ b/misc/user.c @@ -1,14 +1,15 @@ /* -static char RCSId[] = "$Id: user.c,v 1.2 1993/07/04 04:04:21 root Exp root $"; -static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; -*/ + * Misc. USER functions + * + * Copyright 1993 Robert J. Amstadt + */ + #include #include #include "windows.h" #include "gdi.h" #include "user.h" #include "win.h" -#include "message.h" #include "toolhelp.h" #define USER_HEAP_SIZE 0x10000 @@ -63,26 +64,6 @@ BOOL SystemHeapInfo( SYSHEAPINFO *pHeapInfo ) } -/*********************************************************************** - * TimerCount (TOOLHELP.80) - */ -BOOL TimerCount( TIMERINFO *pTimerInfo ) -{ - /* FIXME - * In standard mode, dwmsSinceStart = dwmsThisVM - * - * I tested this, under Windows in enhanced mode, and - * if you never switch VM (ie start/stop DOS) these - * values should be the same as well. - * - * Also, Wine should adjust for the hardware timer - * to reduce the amount of error to ~1ms. - * I can't be bothered, can you? - */ - pTimerInfo->dwmsSinceStart = pTimerInfo->dwmsThisVM = GetTickCount(); - return TRUE; -} - /*********************************************************************** * USER_HeapInit */ @@ -96,6 +77,27 @@ BOOL USER_HeapInit(void) #endif +/*********************************************************************** + * TimerCount (TOOLHELP.80) + */ +BOOL TimerCount( TIMERINFO *pTimerInfo ) +{ + /* FIXME + * In standard mode, dwmsSinceStart = dwmsThisVM + * + * I tested this, under Windows in enhanced mode, and + * if you never switch VM (ie start/stop DOS) these + * values should be the same as well. + * + * Also, Wine should adjust for the hardware timer + * to reduce the amount of error to ~1ms. + * I can't be bothered, can you? + */ + pTimerInfo->dwmsSinceStart = pTimerInfo->dwmsThisVM = GetTickCount(); + return TRUE; +} + + /********************************************************************** * USER_InitApp */ diff --git a/win32/Makefile.in b/win32/Makefile.in index a5e8e38b321..1c2a1a9fd62 100644 --- a/win32/Makefile.in +++ b/win32/Makefile.in @@ -7,6 +7,7 @@ C_SRCS = \ console.c \ environment.c \ error.c \ + except.c \ file.c \ gdi32.c \ heap.c \ diff --git a/win32/except.c b/win32/except.c new file mode 100644 index 00000000000..45188ce9364 --- /dev/null +++ b/win32/except.c @@ -0,0 +1,212 @@ +/* + * Win32 exception functions + * + * Copyright (c) 1996 Onno Hovers, (onno@stack.urc.tue.nl) + * + * Notes: + * What really happens behind the scenes of those new + * __try{...}__except(..){....} and + * __try{...}__finally{...} + * statements is simply not documented by Microsoft. There could be different + * reasons for this: + * One reason could be that they try to hide the fact that exception + * handling in Win32 looks almost the same as in OS/2 2.x. + * Another reason could be that Microsoft does not want others to write + * binary compatible implementations of the Win32 API (like us). + * + * Whatever the reason, THIS SUCKS!! Ensuring portabilty or future + * compatability may be valid reasons to keep some things undocumented. + * But exception handling is so basic to Win32 that it should be + * documented! + * + * Fixmes: + * -Most functions need better parameter checking. + * -I do not know how to handle exceptions within an exception handler. + * or what is done when ExceptionNestedException is returned from an + * exception handler + * -Real exceptions are not yet implemented. only the exception functions + * are implemented. A real implementation needs some new code in + * loader/signal.c. There would also be a need for showing debugging + * information in UnhandledExceptionFilter. + * + */ +#ifndef WINELIB + +#include +#include "windows.h" +#include "winerror.h" +#include "kernel32.h" +#include "stddebug.h" +#include "debug.h" +#include "except.h" + +WINAPI DWORD KERNEL32_537(PEXCEPTION_POINTERS ptrs); + +LPTOP_LEVEL_EXCEPTION_FILTER pTopExcHandler= + (LPTOP_LEVEL_EXCEPTION_FILTER) KERNEL32_537; + +/* + * EXC_RtlUnwind + * + * This function is undocumented. This is the general idea of + * RtlUnwind, though. Note that error handling is not yet implemented + * + */ + +void EXC_RtlUnwind(PEXCEPTION_FRAME pEndFrame,PVOID unusedEip, + PEXCEPTION_RECORD pRecord, DWORD returnEax, + PCONTEXT pcontext) +{ + EXCEPTION_RECORD record; + DWORD dispatch; + int retval; + + pcontext->Eax=returnEax; + + /* build an exception record, if we do not have one */ + if(!pRecord) + { + record.ExceptionCode= 0xC0000026; /* invalid disposition */ + record.ExceptionFlags= 0; + record.ExceptionRecord= NULL; + record.ExceptionAddress=(PVOID) pcontext->Eip; + record.NumberParameters= 0; + pRecord=&record; + } + + if(pEndFrame) + pRecord->ExceptionFlags|=EH_UNWINDING; + else + pRecord->ExceptionFlags|=EH_UNWINDING | EH_EXIT_UNWIND; + + /* get chain of exception frames */ + while((TebExceptionFrame!=NULL)&& + (TebExceptionFrame!=((void *)-1)) && + (TebExceptionFrame!=pEndFrame)) + { + dprintf_win32(stddeb,"calling exception handler at 0x%x\n", + (int) TebExceptionFrame->Handler); + + dispatch=0; + retval=TebExceptionFrame->Handler(pRecord, TebExceptionFrame, + pcontext, &dispatch); + + dprintf_win32(stddeb,"exception handler returns 0x%x, dispatch=0x%x\n", + retval, (int) dispatch); + + if(retval==ExceptionCollidedUnwind) + TebExceptionFrame=(PVOID) dispatch; + else if(TebExceptionFrame!=pEndFrame) + TebExceptionFrame=TebExceptionFrame->Prev; + else + break; + } +} + +/* + * EXC_RaiseException + * + */ + +VOID EXC_RaiseException(DWORD dwExceptionCode, + DWORD dwExceptionFlags, + DWORD cArguments, + const LPDWORD lpArguments, + PCONTEXT pcontext) +{ + PEXCEPTION_FRAME pframe; + EXCEPTION_RECORD record; + DWORD dispatch; /* is this used in raising exceptions ?? */ + int retval; + int i; + + /* compose an exception record */ + + record.ExceptionCode = dwExceptionCode; + record.ExceptionFlags = dwExceptionFlags; + record.ExceptionRecord = NULL; + record.NumberParameters = cArguments; + record.ExceptionAddress = (PVOID) pcontext->Eip; + + for(i=0;iHandler); + dispatch=0; + retval=pframe->Handler(&record,pframe,pcontext,&dispatch); + + dprintf_win32(stddeb,"exception handler returns 0x%x, dispatch=0x%x\n", + retval, (int) dispatch); + + if(retval==ExceptionContinueExecution) + break; + pframe=pframe->Prev; + } + + if(retval!=ExceptionContinueExecution) + { + retval=EXC_CallUnhandledExceptionFilter(&record,pcontext); + if(retval!=EXCEPTION_CONTINUE_EXECUTION) + { + dprintf_win32(stddeb,"no handler wanted to handle " + "the exception, exiting\n" ); + ExitProcess(dwExceptionCode); /* what status should be used here ? */ + } + } +} + +/******************************************************************* + * UnhandledExceptionFilter (KERNEL32.537) + * + * This is the unhandled exception code. + * Actually, this should show up a dialog box, with all kinds of + * fancy debugging information. It does nothing now! + */ + +DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers) +{ + PEXCEPTION_RECORD pRecord; + PCONTEXT pContext; + + pRecord=epointers->ExceptionRecord; + pContext=epointers->ContextRecord; + + if(pRecord->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND) ) + { + dprintf_win32(stddeb,"UnhandledExceptionFilter: exiting\n"); + ExitProcess(pRecord->ExceptionCode); + } + else + { + RtlUnwind(0,pRecord,0,-1 ); + } + + /* + * This is just to avoid a warning, code should not get here + * if it does, EXC_RaiseException will terminate it. + */ + return EXCEPTION_CONTINUE_SEARCH; +} + +/************************************************************* + * SetUnhandledExceptionFilter (KERNEL32.516) + * + * + */ + +WINAPI LPTOP_LEVEL_EXCEPTION_FILTER + SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER efilter) +{ + pTopExcHandler=efilter; + return efilter; +} + +#endif /* WINELIB */ diff --git a/win32/newfns.c b/win32/newfns.c index 0192cb0f6b6..c4a99f1bb2d 100644 --- a/win32/newfns.c +++ b/win32/newfns.c @@ -15,19 +15,6 @@ at a later date. */ #include "stddebug.h" #include "debug.h" -/*********************************************************************** - * RaiseException (KERNEL32.??) - * - * Stub function - does not allow exceptions to be caught yet - */ -WINAPI VOID RaiseException(DWORD dwExceptionCode, - DWORD dwExceptionFlags, - DWORD cArguments, - const DWORD * lpArguments) -{ - ExitProcess(dwExceptionCode); /* what status should be used here ? */ -} - /*********************************************************************** * GetProcAddress (KERNEL32.257) * diff --git a/windows/Makefile.in b/windows/Makefile.in index d04102bfd9b..0bb67990a35 100644 --- a/windows/Makefile.in +++ b/windows/Makefile.in @@ -21,6 +21,7 @@ C_SRCS = \ nonclient.c \ painting.c \ property.c \ + queue.c \ scroll.c \ syscolor.c \ sysmetrics.c \ diff --git a/windows/class.c b/windows/class.c index f148b38a82d..527127e069b 100644 --- a/windows/class.c +++ b/windows/class.c @@ -22,6 +22,72 @@ static HCLASS firstClass = 0; +/*********************************************************************** + * CLASS_DumpClass + * + * Dump the content of a class structure to stderr. + */ +void CLASS_DumpClass( HCLASS hClass ) +{ + CLASS *ptr; + char className[80]; + int i; + + if (!(ptr = CLASS_FindClassPtr( hClass ))) + { + fprintf( stderr, "%04x is not a class handle\n", hClass ); + return; + } + GlobalGetAtomName( ptr->atomName, className, sizeof(className) ); + + fprintf( stderr, "Class %04x:\n", hClass ); + fprintf( stderr, + "next=%04x name=%04x '%s' style=%04x wndProc=%08lx\n" + "inst=%04x hdce=%04x icon=%04x cursor=%04x bkgnd=%04x\n" + "clsExtra=%d winExtra=%d #windows=%d\n", + ptr->hNext, ptr->atomName, className, ptr->wc.style, + (DWORD)ptr->wc.lpfnWndProc, ptr->wc.hInstance, ptr->hdce, + ptr->wc.hIcon, ptr->wc.hCursor, ptr->wc.hbrBackground, + ptr->wc.cbClsExtra, ptr->wc.cbWndExtra, ptr->cWindows ); + if (ptr->wc.cbClsExtra) + { + fprintf( stderr, "extra bytes:" ); + for (i = 0; i < ptr->wc.cbClsExtra; i++) + fprintf( stderr, " %02x", *((BYTE *)ptr->wExtra+i) ); + fprintf( stderr, "\n" ); + } + fprintf( stderr, "\n" ); +} + + +/*********************************************************************** + * CLASS_WalkClasses + * + * Walk the class list and print each class on stderr. + */ +void CLASS_WalkClasses(void) +{ + HCLASS hClass = firstClass; + CLASS *ptr; + char className[80]; + + fprintf( stderr, "Class Name Style WndProc\n" ); + while (hClass) + { + if (!(ptr = CLASS_FindClassPtr( hClass ))) + { + fprintf( stderr, "*** Bad class %04x in list\n", hClass ); + return; + } + GlobalGetAtomName( ptr->atomName, className, sizeof(className) ); + fprintf( stderr, "%04x %-20.20s %04x %08lx\n", + hClass, className, ptr->wc.style, (DWORD)ptr->wc.lpfnWndProc); + hClass = ptr->hNext; + } + fprintf( stderr, "\n" ); +} + + /*********************************************************************** * CLASS_FindClassByName * diff --git a/windows/dce.c b/windows/dce.c index ed9c8b20db2..4974a2e4193 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -152,7 +152,7 @@ static HRGN DCE_ClipWindows( HWND hwndStart, HWND hwndEnd, if (!hwndStart) return hrgn; if (!(hrgnNew = CreateRectRgn( 0, 0, 0, 0 ))) { - if (hrgn) DeleteObject( hrgn ); + DeleteObject( hrgn ); return 0; } for (; hwndStart != hwndEnd; hwndStart = wndPtr->hwndNext) @@ -165,10 +165,10 @@ static HRGN DCE_ClipWindows( HWND hwndStart, HWND hwndEnd, wndPtr->rectWindow.bottom + yoffset ); if (!CombineRgn( hrgn, hrgn, hrgnNew, RGN_DIFF )) break; } + DeleteObject( hrgnNew ); if (hwndStart != hwndEnd) /* something went wrong */ { - DeleteObject( hrgnNew ); - if (hrgn) DeleteObject( hrgn ); + DeleteObject( hrgn ); return 0; } return hrgn; diff --git a/windows/defwnd.c b/windows/defwnd.c index 21acb8db3d7..4e1d060f109 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -54,7 +54,7 @@ LRESULT DefWindowProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) int len; WND * wndPtr = WIN_FindWndPtr( hwnd ); - EnterSpyMessage(SPY_DEFWNDPROC,hwnd,msg,wParam,lParam); + SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam ); switch(msg) { diff --git a/windows/event.c b/windows/event.c index 7ab8e42eaa5..203f75be269 100644 --- a/windows/event.c +++ b/windows/event.c @@ -6,8 +6,11 @@ */ #include +#include #include #include +#include +#include #include #include #include @@ -16,9 +19,9 @@ #include "windows.h" #include "win.h" #include "class.h" -#include "message.h" #include "clipboard.h" #include "options.h" +#include "queue.h" #include "winpos.h" #include "registers.h" #include "stackframe.h" @@ -305,6 +308,11 @@ static void EVENT_key( XKeyEvent *event ) dprintf_key(stddeb,"WM_KEY??? : keysym=%lX, count=%u / %X / '%s'\n", keysym, count, Str[0], Str); + /* Ctrl-Alt-Return enters the debugger */ + if ((keysym == XK_Return) && (event->type == KeyPress) && + (event->state & ControlMask) && (event->state & Mod1Mask)) + kill( getpid(), SIGHUP ); + xkey = LOWORD(keysym); key_type = HIBYTE(xkey); key = LOBYTE(xkey); @@ -348,7 +356,7 @@ static void EVENT_key( XKeyEvent *event ) KeyStateTable[vkey] ^= 0x80; KeyStateTable[vkey] |= 0x01; keylp.lp1.count = 1; - keylp.lp1.code = LOBYTE(event->keycode); + keylp.lp1.code = LOBYTE(event->keycode) - 8; keylp.lp1.extended = (extended ? 1 : 0); keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0); keylp.lp1.previous = (KeyDown ? 0 : 1); @@ -379,7 +387,7 @@ static void EVENT_key( XKeyEvent *event ) if (vkey == VK_MENU) ALTKeyState = FALSE; KeyStateTable[vkey] &= 0xf0; keylp.lp1.count = 1; - keylp.lp1.code = LOBYTE(event->keycode); + keylp.lp1.code = LOBYTE(event->keycode) - 8; keylp.lp1.extended = (extended ? 1 : 0); keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0); keylp.lp1.previous = 1; diff --git a/windows/hook.c b/windows/hook.c index ad3d0f4b2c1..1151e143432 100644 --- a/windows/hook.c +++ b/windows/hook.c @@ -15,7 +15,7 @@ */ #include "hook.h" -#include "message.h" +#include "queue.h" #include "user.h" #include "stddebug.h" #include "debug.h" diff --git a/windows/message.c b/windows/message.c index cd733d379a0..8f00ed80595 100644 --- a/windows/message.c +++ b/windows/message.c @@ -19,195 +19,19 @@ #include "winpos.h" #include "atom.h" #include "dde.h" +#include "queue.h" #include "stddebug.h" /* #define DEBUG_MSG */ #include "debug.h" #define HWND_BROADCAST ((HWND)0xffff) -#define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */ - extern BOOL TIMER_CheckTimer( LONG *next, MSG *msg, HWND hwnd, BOOL remove ); /* timer.c */ DWORD MSG_WineStartTicks; /* Ticks at Wine startup */ -/* ------- Internal Queues ------ */ - -static HANDLE hmemSysMsgQueue = 0; -static MESSAGEQUEUE *sysMsgQueue = NULL; -static HANDLE hFirstQueue = 0; - -/* ------- Miscellaneous ------ */ -static int doubleClickSpeed = 452; - - -/*********************************************************************** - * MSG_CreateMsgQueue - * - * Creates a message queue. Doesn't link it into queue list! - */ -static HANDLE MSG_CreateMsgQueue( int size ) -{ - HANDLE hQueue; - MESSAGEQUEUE * msgQueue; - int queueSize; - - queueSize = sizeof(MESSAGEQUEUE) + size * sizeof(QMSG); - if (!(hQueue = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, queueSize ))) - return 0; - msgQueue = (MESSAGEQUEUE *) GlobalLock( hQueue ); - msgQueue->msgSize = sizeof(QMSG); - msgQueue->queueSize = size; - msgQueue->wWinVersion = 0; /* FIXME? */ - GlobalUnlock( hQueue ); - return hQueue; -} - - -/*********************************************************************** - * MSG_DeleteMsgQueue - * - * Unlinks and deletes a message queue. - */ -BOOL MSG_DeleteMsgQueue( HANDLE hQueue ) -{ - MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)GlobalLock(hQueue); - HANDLE *pPrev; - - if (!hQueue || !msgQueue) - { - dprintf_msg(stddeb,"DeleteMsgQueue: invalid argument.\n"); - return 0; - } - - pPrev = &hFirstQueue; - while (*pPrev && (*pPrev != hQueue)) - { - MESSAGEQUEUE *msgQ = (MESSAGEQUEUE*)GlobalLock(*pPrev); - pPrev = &msgQ->next; - } - if (*pPrev) *pPrev = msgQueue->next; - GlobalFree( hQueue ); - return 1; -} - - -/*********************************************************************** - * MSG_CreateSysMsgQueue - * - * Create the system message queue, and set the double-click speed. - * Must be called only once. - */ -BOOL MSG_CreateSysMsgQueue( int size ) -{ - if (size > MAX_QUEUE_SIZE) size = MAX_QUEUE_SIZE; - else if (size <= 0) size = 1; - if (!(hmemSysMsgQueue = MSG_CreateMsgQueue( size ))) return FALSE; - sysMsgQueue = (MESSAGEQUEUE *) GlobalLock( hmemSysMsgQueue ); - doubleClickSpeed = GetProfileInt( "windows", "DoubleClickSpeed", 452 ); - return TRUE; -} - - -/*********************************************************************** - * MSG_AddMsg - * - * Add a message to the queue. Return FALSE if queue is full. - */ -static int MSG_AddMsg( HANDLE hQueue, MSG * msg, DWORD extraInfo ) -{ - int pos; - MESSAGEQUEUE *msgQueue; - - if (!(msgQueue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return FALSE; - pos = msgQueue->nextFreeMessage; - - /* Check if queue is full */ - if ((pos == msgQueue->nextMessage) && (msgQueue->msgCount > 0)) { - fprintf(stderr,"MSG_AddMsg // queue is full !\n"); - return FALSE; - } - - /* Store message */ - msgQueue->messages[pos].msg = *msg; - msgQueue->messages[pos].extraInfo = extraInfo; - if (pos < msgQueue->queueSize-1) pos++; - else pos = 0; - msgQueue->nextFreeMessage = pos; - msgQueue->msgCount++; - msgQueue->status |= QS_POSTMESSAGE; - msgQueue->tempStatus |= QS_POSTMESSAGE; - return TRUE; -} - - -/*********************************************************************** - * MSG_FindMsg - * - * Find a message matching the given parameters. Return -1 if none available. - */ -static int MSG_FindMsg(MESSAGEQUEUE * msgQueue, HWND hwnd, int first, int last) -{ - int i, pos = msgQueue->nextMessage; - - dprintf_msg(stddeb,"MSG_FindMsg: hwnd=0x"NPFMT"\n\n", hwnd ); - - if (!msgQueue->msgCount) return -1; - if (!hwnd && !first && !last) return pos; - - for (i = 0; i < msgQueue->msgCount; i++) - { - MSG * msg = &msgQueue->messages[pos].msg; - - if (!hwnd || (msg->hwnd == hwnd)) - { - if (!first && !last) return pos; - if ((msg->message >= first) && (msg->message <= last)) return pos; - } - if (pos < msgQueue->queueSize-1) pos++; - else pos = 0; - } - return -1; -} - - -/*********************************************************************** - * MSG_RemoveMsg - * - * Remove a message from the queue (pos must be a valid position). - */ -static void MSG_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos ) -{ - if (pos >= msgQueue->nextMessage) - { - for ( ; pos > msgQueue->nextMessage; pos--) - msgQueue->messages[pos] = msgQueue->messages[pos-1]; - msgQueue->nextMessage++; - if (msgQueue->nextMessage >= msgQueue->queueSize) - msgQueue->nextMessage = 0; - } - else - { - for ( ; pos < msgQueue->nextFreeMessage; pos++) - msgQueue->messages[pos] = msgQueue->messages[pos+1]; - if (msgQueue->nextFreeMessage) msgQueue->nextFreeMessage--; - else msgQueue->nextFreeMessage = msgQueue->queueSize-1; - } - msgQueue->msgCount--; - if (!msgQueue->msgCount) msgQueue->status &= ~QS_POSTMESSAGE; - msgQueue->tempStatus = 0; -} - -/*********************************************************************** - * MSG_GetQueueTask - */ -HTASK MSG_GetQueueTask( HANDLE hQueue ) -{ - MESSAGEQUEUE *msgQ = GlobalLock( hQueue ); - - return (msgQ) ? msgQ->hTask : 0 ; -} +static WORD doubleClickSpeed = 452; /*********************************************************************** * MSG_TranslateMouseMsg @@ -372,6 +196,7 @@ static BOOL MSG_TranslateKeyboardMsg( MSG *msg, BOOL remove ) static BOOL MSG_PeekHardwareMsg( MSG *msg, HWND hwnd, WORD first, WORD last, BOOL remove ) { + MESSAGEQUEUE *sysMsgQueue = QUEUE_GetSysQueue(); int i, pos = sysMsgQueue->nextMessage; for (i = 0; i < sysMsgQueue->msgCount; i++, pos++) @@ -410,7 +235,7 @@ static BOOL MSG_PeekHardwareMsg( MSG *msg, HWND hwnd, WORD first, WORD last, MSG tmpMsg = *msg; /* FIXME */ HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)MAKE_SEGPTR(&tmpMsg) ); - MSG_RemoveMsg( sysMsgQueue, pos ); + QUEUE_RemoveMsg( sysMsgQueue, pos ); } return TRUE; } @@ -419,135 +244,23 @@ static BOOL MSG_PeekHardwareMsg( MSG *msg, HWND hwnd, WORD first, WORD last, /********************************************************************** - * SetDoubleClickTime (USER.20) + * SetDoubleClickTime (USER.20) */ void SetDoubleClickTime( WORD interval ) { - if (interval == 0) - doubleClickSpeed = 500; - else - doubleClickSpeed = interval; + doubleClickSpeed = interval ? interval : 500; } /********************************************************************** - * GetDoubleClickTime (USER.21) + * GetDoubleClickTime (USER.21) */ WORD GetDoubleClickTime() { - return (WORD)doubleClickSpeed; + return doubleClickSpeed; } -/*********************************************************************** - * MSG_IncPaintCount - */ -void MSG_IncPaintCount( HANDLE hQueue ) -{ - MESSAGEQUEUE *queue; - - if (!(queue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return; - queue->wPaintCount++; - queue->status |= QS_PAINT; - queue->tempStatus |= QS_PAINT; -} - - -/*********************************************************************** - * MSG_DecPaintCount - */ -void MSG_DecPaintCount( HANDLE hQueue ) -{ - MESSAGEQUEUE *queue; - - if (!(queue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return; - queue->wPaintCount--; - if (!queue->wPaintCount) queue->status &= ~QS_PAINT; -} - - -/*********************************************************************** - * MSG_IncTimerCount - */ -void MSG_IncTimerCount( HANDLE hQueue ) -{ - MESSAGEQUEUE *queue; - - if (!(queue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return; - queue->wTimerCount++; - queue->status |= QS_TIMER; - queue->tempStatus |= QS_TIMER; -} - - -/*********************************************************************** - * MSG_DecTimerCount - */ -void MSG_DecTimerCount( HANDLE hQueue ) -{ - MESSAGEQUEUE *queue; - - if (!(queue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return; - queue->wTimerCount--; - if (!queue->wTimerCount) queue->status &= ~QS_TIMER; -} - - -/*********************************************************************** - * hardware_event - * - * Add an event to the system message queue. - * Note: the position is relative to the desktop window. - */ -void hardware_event( WORD message, WORD wParam, LONG lParam, - int xPos, int yPos, DWORD time, DWORD extraInfo ) -{ - MSG *msg; - int pos; - - if (!sysMsgQueue) return; - pos = sysMsgQueue->nextFreeMessage; - - /* Merge with previous event if possible */ - - if ((message == WM_MOUSEMOVE) && sysMsgQueue->msgCount) - { - if (pos > 0) pos--; - else pos = sysMsgQueue->queueSize - 1; - msg = &sysMsgQueue->messages[pos].msg; - if ((msg->message == message) && (msg->wParam == wParam)) - sysMsgQueue->msgCount--; /* Merge events */ - else - pos = sysMsgQueue->nextFreeMessage; /* Don't merge */ - } - - /* Check if queue is full */ - - if ((pos == sysMsgQueue->nextMessage) && sysMsgQueue->msgCount) - { - /* Queue is full, beep (but not on every mouse motion...) */ - if (message != WM_MOUSEMOVE) MessageBeep(0); - return; - } - - /* Store message */ - - msg = &sysMsgQueue->messages[pos].msg; - msg->hwnd = 0; - msg->message = message; - msg->wParam = wParam; - msg->lParam = lParam; - msg->time = time; - msg->pt.x = xPos & 0xffff; - msg->pt.y = yPos & 0xffff; - sysMsgQueue->messages[pos].extraInfo = extraInfo; - if (pos < sysMsgQueue->queueSize - 1) pos++; - else pos = 0; - sysMsgQueue->nextFreeMessage = pos; - sysMsgQueue->msgCount++; -} - - /*********************************************************************** * MSG_GetHardwareMessage * @@ -560,13 +273,14 @@ BOOL MSG_GetHardwareMessage( LPMSG msg ) { int pos; XEvent event; + MESSAGEQUEUE *sysMsgQueue = QUEUE_GetSysQueue(); while(1) { - if ((pos = MSG_FindMsg( sysMsgQueue, 0, 0, 0 )) != -1) + if ((pos = QUEUE_FindMsg( sysMsgQueue, 0, 0, 0 )) != -1) { *msg = sysMsgQueue->messages[pos].msg; - MSG_RemoveMsg( sysMsgQueue, pos ); + QUEUE_RemoveMsg( sysMsgQueue, pos ); break; } XNextEvent( display, &event ); @@ -576,91 +290,6 @@ BOOL MSG_GetHardwareMessage( LPMSG msg ) } -/*********************************************************************** - * SetMessageQueue (USER.266) - */ -BOOL SetMessageQueue( int size ) -{ - HANDLE hQueue, hNewQueue; - MESSAGEQUEUE *queuePtr; - - if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return TRUE; - - if( !(hNewQueue = MSG_CreateMsgQueue( size ))) - { - dprintf_msg(stddeb,"SetMessageQueue: failed!\n"); - return FALSE; - } - - /* Free the old message queue */ - if ((hQueue = GetTaskQueue(0)) != 0) MSG_DeleteMsgQueue( hQueue ); - - /* Link new queue into list */ - queuePtr = (MESSAGEQUEUE *)GlobalLock( hNewQueue ); - queuePtr->hTask = GetCurrentTask(); - queuePtr->next = hFirstQueue; - hFirstQueue = hNewQueue; - - SetTaskQueue( 0, hNewQueue ); - return TRUE; -} - - -/*********************************************************************** - * GetWindowTask (USER.224) - */ -HTASK GetWindowTask( HWND hwnd ) -{ - WND *wndPtr = WIN_FindWndPtr( hwnd ); - MESSAGEQUEUE *queuePtr; - - if (!wndPtr) return 0; - queuePtr = (MESSAGEQUEUE *)GlobalLock( wndPtr->hmemTaskQ ); - if (!queuePtr) return 0; - return queuePtr->hTask; -} - - -/*********************************************************************** - * PostQuitMessage (USER.6) - */ -void PostQuitMessage( int exitCode ) -{ - MESSAGEQUEUE *queue; - - if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return; - queue->wPostQMsg = TRUE; - queue->wExitCode = exitCode; -} - - -/*********************************************************************** - * GetQueueStatus (USER.334) - */ -DWORD GetQueueStatus( UINT flags ) -{ - MESSAGEQUEUE *queue; - DWORD ret; - - if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return 0; - ret = MAKELONG( queue->tempStatus, queue->status ); - queue->tempStatus = 0; - return ret & MAKELONG( flags, flags ); -} - - -/*********************************************************************** - * GetInputState (USER.335) - */ -BOOL GetInputState() -{ - MESSAGEQUEUE *queue; - - if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return FALSE; - return queue->status & (QS_KEY | QS_MOUSEBUTTON); -} - - /*********************************************************************** * MSG_Synchronize * @@ -796,7 +425,7 @@ static BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, } /* Now find a normal message */ - pos = MSG_FindMsg( msgQueue, hwnd, first, last ); + pos = QUEUE_FindMsg( msgQueue, hwnd, first, last ); if (pos != -1) { QMSG *qmsg = &msgQueue->messages[pos]; @@ -805,7 +434,7 @@ static BOOL MSG_PeekMessage( LPMSG msg, HWND hwnd, WORD first, WORD last, msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt; msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo; - if (flags & PM_REMOVE) MSG_RemoveMsg( msgQueue, pos ); + if (flags & PM_REMOVE) QUEUE_RemoveMsg( msgQueue, pos ); break; } @@ -966,7 +595,7 @@ BOOL PostMessage( HWND hwnd, WORD message, WORD wParam, LONG lParam ) wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr || !wndPtr->hmemTaskQ) return FALSE; - return MSG_AddMsg( wndPtr->hmemTaskQ, &msg, 0 ); + return QUEUE_AddMsg( wndPtr->hmemTaskQ, &msg, 0 ); } /*********************************************************************** @@ -985,7 +614,7 @@ BOOL PostAppMessage( HTASK hTask, WORD message, WORD wParam, LONG lParam ) msg.pt.x = 0; msg.pt.y = 0; - return MSG_AddMsg( GetTaskQueue(hTask), &msg, 0 ); + return QUEUE_AddMsg( GetTaskQueue(hTask), &msg, 0 ); } @@ -1028,17 +657,17 @@ LRESULT SendMessage( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) return TRUE; } - EnterSpyMessage(SPY_SENDMESSAGE, hwnd, msg, wParam, lParam); + SPY_EnterMessage( SPY_SENDMESSAGE, hwnd, msg, wParam, lParam ); HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)MAKE_SEGPTR(&msgstruct) ); if (!(wndPtr = WIN_FindWndPtr( hwnd ))) { - ExitSpyMessage(SPY_RESULT_INVALIDHWND,hwnd,msg,0); + SPY_ExitMessage( SPY_RESULT_INVALIDHWND, hwnd, msg, 0 ); return 0; } ret = CallWindowProc( wndPtr->lpfnWndProc, msgstruct.hWnd, msgstruct.wMsg, msgstruct.wParam, msgstruct.lParam ); - ExitSpyMessage(SPY_RESULT_OK,hwnd,msg,ret); + SPY_ExitMessage( SPY_RESULT_OK, hwnd, msg, ret ); return ret; } @@ -1059,7 +688,7 @@ void WaitMessage( void ) if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return; if ((queue->wPostQMsg) || (queue->status & (QS_SENDMESSAGE | QS_PAINT)) || - (queue->msgCount) || (sysMsgQueue->msgCount) ) + (queue->msgCount) || (QUEUE_GetSysQueue()->msgCount) ) return; if ((queue->status & QS_TIMER) && TIMER_CheckTimer( &nextExp, &msg, 0, FALSE)) @@ -1095,8 +724,8 @@ LONG DispatchMessage( const MSG* msg ) LONG retval; int painting; - EnterSpyMessage( SPY_DISPATCHMESSAGE, msg->hwnd, msg->message, - msg->wParam, msg->lParam ); + SPY_EnterMessage( SPY_DISPATCHMESSAGE, msg->hwnd, msg->message, + msg->wParam, msg->lParam ); /* Process timer messages */ if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER)) @@ -1134,42 +763,6 @@ LONG DispatchMessage( const MSG* msg ) } -/*********************************************************************** - * GetMessagePos (USER.119) - */ -DWORD GetMessagePos(void) -{ - MESSAGEQUEUE *queue; - - if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return 0; - return queue->GetMessagePosVal; -} - - -/*********************************************************************** - * GetMessageTime (USER.120) - */ -LONG GetMessageTime(void) -{ - MESSAGEQUEUE *queue; - - if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return 0; - return queue->GetMessageTimeVal; -} - - -/*********************************************************************** - * GetMessageExtraInfo (USER.288) - */ -LONG GetMessageExtraInfo(void) -{ - MESSAGEQUEUE *queue; - - if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return 0; - return queue->GetMessageExtraInfoVal; -} - - /*********************************************************************** * RegisterWindowMessage (USER.118) */ @@ -1190,14 +783,18 @@ DWORD GetTickCount(void) return ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - MSG_WineStartTicks; } + /*********************************************************************** - * GetCurrentTime (effectively identical to GetTickCount) + * GetCurrentTime (USER.15) + * + * (effectively identical to GetTickCount) */ DWORD GetCurrentTime(void) { - return GetTickCount(); + return GetTickCount(); } + /*********************************************************************** * InSendMessage (USER.192 * diff --git a/windows/painting.c b/windows/painting.c index 1c2b06a09d3..d1438d5927d 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -8,7 +8,7 @@ #include #include "win.h" -#include "message.h" +#include "queue.h" #include "gdi.h" #include "stddebug.h" /* #define DEBUG_WIN */ @@ -32,7 +32,7 @@ HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps ) if (!(hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 ))) return 0; if (wndPtr->hrgnUpdate || (wndPtr->flags & WIN_INTERNAL_PAINT)) - MSG_DecPaintCount( wndPtr->hmemTaskQ ); + QUEUE_DecPaintCount( wndPtr->hmemTaskQ ); wndPtr->hrgnUpdate = 0; wndPtr->flags &= ~(WIN_NEEDS_BEGINPAINT | WIN_INTERNAL_PAINT); @@ -168,7 +168,7 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags ) else /* No update region yet */ { if (!(wndPtr->flags & WIN_INTERNAL_PAINT)) - MSG_IncPaintCount( wndPtr->hmemTaskQ ); + QUEUE_IncPaintCount( wndPtr->hmemTaskQ ); if (hrgnUpdate) { wndPtr->hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 ); @@ -206,7 +206,7 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags ) } if (!wndPtr->hrgnUpdate) /* No more update region */ if (!(wndPtr->flags & WIN_INTERNAL_PAINT)) - MSG_DecPaintCount( wndPtr->hmemTaskQ ); + QUEUE_DecPaintCount( wndPtr->hmemTaskQ ); } if (flags & RDW_NOFRAME) wndPtr->flags &= ~WIN_NEEDS_NCPAINT; if (flags & RDW_NOERASE) wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND; @@ -217,13 +217,13 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags ) if (flags & RDW_INTERNALPAINT) { if (!wndPtr->hrgnUpdate && !(wndPtr->flags & WIN_INTERNAL_PAINT)) - MSG_IncPaintCount( wndPtr->hmemTaskQ ); + QUEUE_IncPaintCount( wndPtr->hmemTaskQ ); wndPtr->flags |= WIN_INTERNAL_PAINT; } else if (flags & RDW_NOINTERNALPAINT) { if (!wndPtr->hrgnUpdate && (wndPtr->flags & WIN_INTERNAL_PAINT)) - MSG_DecPaintCount( wndPtr->hmemTaskQ ); + QUEUE_DecPaintCount( wndPtr->hmemTaskQ ); wndPtr->flags &= ~WIN_INTERNAL_PAINT; } diff --git a/windows/queue.c b/windows/queue.c new file mode 100644 index 00000000000..1d0028a4120 --- /dev/null +++ b/windows/queue.c @@ -0,0 +1,484 @@ +/* + * Message queues related functions + * + * Copyright 1993, 1994 Alexandre Julliard + */ + +#include +#include "module.h" +#include "queue.h" +#include "win.h" +#include "stddebug.h" +#include "debug.h" + +#define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */ + +static HQUEUE hFirstQueue = 0; +static HQUEUE hmemSysMsgQueue = 0; +static MESSAGEQUEUE *sysMsgQueue = NULL; + + +/*********************************************************************** + * QUEUE_DumpQueue + */ +void QUEUE_DumpQueue( HQUEUE hQueue ) +{ + MESSAGEQUEUE *pq; + + if (!(pq = (MESSAGEQUEUE*) GlobalLock( hQueue )) || + GlobalSize(hQueue) < sizeof(MESSAGEQUEUE) + pq->queueSize*sizeof(QMSG)) + { + fprintf( stderr, NPFMT " is not a queue handle\n", hQueue ); + return; + } + + fprintf( stderr, + "next: %12.4x Intertask SendMessage:\n" + "hTask: %11.4x ----------------------\n" + "msgSize: %9.4x hWnd: %10.4x\n" + "msgCount: %8.4x msg: %11.4x\n" + "msgNext: %9.4x wParam: %8.4x\n" + "msgFree: %9.4x lParam: %8.8x\n" + "qSize: %11.4x lRet: %10.8x\n" + "wWinVer: %9.4x ISMH: %10.4x\n" + "paints: %10.4x hSendTask: %5.4x\n" + "timers: %10.4x hPrevSend: %5.4x\n" + "wakeBits: %8.4x\n" + "wakeMask: %8.4x\n" + "hCurHook: %8.4x\n", + pq->next, pq->hTask, pq->msgSize, pq->hWnd, + pq->msgCount, pq->msg, pq->nextMessage, pq->wParam, + pq->nextFreeMessage, (unsigned)pq->lParam, pq->queueSize, + (unsigned)pq->SendMessageReturn, pq->wWinVersion, pq->InSendMessageHandle, + pq->wPaintCount, pq->hSendingTask, pq->wTimerCount, + pq->hPrevSendingTask, pq->status, pq->wakeMask, pq->hCurHook); +} + + +/*********************************************************************** + * QUEUE_WalkQueues + */ +void QUEUE_WalkQueues(void) +{ + HQUEUE hQueue = hFirstQueue; + + fprintf( stderr, "Queue Size Msgs Task\n" ); + while (hQueue) + { + MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock( hQueue ); + if (!queue) + { + fprintf( stderr, "*** Bad queue handle "NPFMT"\n", hQueue ); + return; + } + fprintf( stderr, "%04x %5d %4d %04x %s\n", + hQueue, queue->msgSize, queue->msgCount, queue->hTask, + MODULE_GetModuleName( GetExePtr(queue->hTask) ) ); + hQueue = queue->next; + } + fprintf( stderr, "\n" ); +} + + +/*********************************************************************** + * QUEUE_CreateMsgQueue + * + * Creates a message queue. Doesn't link it into queue list! + */ +static HQUEUE QUEUE_CreateMsgQueue( int size ) +{ + HQUEUE hQueue; + MESSAGEQUEUE * msgQueue; + int queueSize; + + queueSize = sizeof(MESSAGEQUEUE) + size * sizeof(QMSG); + if (!(hQueue = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, queueSize ))) + return 0; + msgQueue = (MESSAGEQUEUE *) GlobalLock( hQueue ); + msgQueue->msgSize = sizeof(QMSG); + msgQueue->queueSize = size; + msgQueue->wWinVersion = 0; /* FIXME? */ + GlobalUnlock( hQueue ); + return hQueue; +} + + +/*********************************************************************** + * QUEUE_DeleteMsgQueue + * + * Unlinks and deletes a message queue. + */ +BOOL QUEUE_DeleteMsgQueue( HQUEUE hQueue ) +{ + MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)GlobalLock(hQueue); + HQUEUE *pPrev; + + if (!hQueue || !msgQueue) + { + dprintf_msg(stddeb,"DeleteMsgQueue: invalid argument.\n"); + return 0; + } + + pPrev = &hFirstQueue; + while (*pPrev && (*pPrev != hQueue)) + { + MESSAGEQUEUE *msgQ = (MESSAGEQUEUE*)GlobalLock(*pPrev); + pPrev = &msgQ->next; + } + if (*pPrev) *pPrev = msgQueue->next; + GlobalFree( hQueue ); + return 1; +} + + +/*********************************************************************** + * QUEUE_CreateSysMsgQueue + * + * Create the system message queue, and set the double-click speed. + * Must be called only once. + */ +BOOL QUEUE_CreateSysMsgQueue( int size ) +{ + if (size > MAX_QUEUE_SIZE) size = MAX_QUEUE_SIZE; + else if (size <= 0) size = 1; + if (!(hmemSysMsgQueue = QUEUE_CreateMsgQueue( size ))) return FALSE; + sysMsgQueue = (MESSAGEQUEUE *) GlobalLock( hmemSysMsgQueue ); + return TRUE; +} + + +/*********************************************************************** + * QUEUE_GetSysQueue + */ +MESSAGEQUEUE *QUEUE_GetSysQueue(void) +{ + return sysMsgQueue; +} + + +/*********************************************************************** + * QUEUE_AddMsg + * + * Add a message to the queue. Return FALSE if queue is full. + */ +BOOL QUEUE_AddMsg( HQUEUE hQueue, MSG * msg, DWORD extraInfo ) +{ + int pos; + MESSAGEQUEUE *msgQueue; + + if (!(msgQueue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return FALSE; + pos = msgQueue->nextFreeMessage; + + /* Check if queue is full */ + if ((pos == msgQueue->nextMessage) && (msgQueue->msgCount > 0)) + { + fprintf(stderr,"MSG_AddMsg // queue is full !\n"); + return FALSE; + } + + /* Store message */ + msgQueue->messages[pos].msg = *msg; + msgQueue->messages[pos].extraInfo = extraInfo; + if (pos < msgQueue->queueSize-1) pos++; + else pos = 0; + msgQueue->nextFreeMessage = pos; + msgQueue->msgCount++; + msgQueue->status |= QS_POSTMESSAGE; + msgQueue->tempStatus |= QS_POSTMESSAGE; + return TRUE; +} + + +/*********************************************************************** + * QUEUE_FindMsg + * + * Find a message matching the given parameters. Return -1 if none available. + */ +int QUEUE_FindMsg( MESSAGEQUEUE * msgQueue, HWND hwnd, int first, int last ) +{ + int i, pos = msgQueue->nextMessage; + + dprintf_msg(stddeb,"MSG_FindMsg: hwnd=0x"NPFMT"\n\n", hwnd ); + + if (!msgQueue->msgCount) return -1; + if (!hwnd && !first && !last) return pos; + + for (i = 0; i < msgQueue->msgCount; i++) + { + MSG * msg = &msgQueue->messages[pos].msg; + + if (!hwnd || (msg->hwnd == hwnd)) + { + if (!first && !last) return pos; + if ((msg->message >= first) && (msg->message <= last)) return pos; + } + if (pos < msgQueue->queueSize-1) pos++; + else pos = 0; + } + return -1; +} + + +/*********************************************************************** + * QUEUE_RemoveMsg + * + * Remove a message from the queue (pos must be a valid position). + */ +void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos ) +{ + if (pos >= msgQueue->nextMessage) + { + for ( ; pos > msgQueue->nextMessage; pos--) + msgQueue->messages[pos] = msgQueue->messages[pos-1]; + msgQueue->nextMessage++; + if (msgQueue->nextMessage >= msgQueue->queueSize) + msgQueue->nextMessage = 0; + } + else + { + for ( ; pos < msgQueue->nextFreeMessage; pos++) + msgQueue->messages[pos] = msgQueue->messages[pos+1]; + if (msgQueue->nextFreeMessage) msgQueue->nextFreeMessage--; + else msgQueue->nextFreeMessage = msgQueue->queueSize-1; + } + msgQueue->msgCount--; + if (!msgQueue->msgCount) msgQueue->status &= ~QS_POSTMESSAGE; + msgQueue->tempStatus = 0; +} + + +/*********************************************************************** + * hardware_event + * + * Add an event to the system message queue. + * Note: the position is relative to the desktop window. + */ +void hardware_event( WORD message, WORD wParam, LONG lParam, + int xPos, int yPos, DWORD time, DWORD extraInfo ) +{ + MSG *msg; + int pos; + + if (!sysMsgQueue) return; + pos = sysMsgQueue->nextFreeMessage; + + /* Merge with previous event if possible */ + + if ((message == WM_MOUSEMOVE) && sysMsgQueue->msgCount) + { + if (pos > 0) pos--; + else pos = sysMsgQueue->queueSize - 1; + msg = &sysMsgQueue->messages[pos].msg; + if ((msg->message == message) && (msg->wParam == wParam)) + sysMsgQueue->msgCount--; /* Merge events */ + else + pos = sysMsgQueue->nextFreeMessage; /* Don't merge */ + } + + /* Check if queue is full */ + + if ((pos == sysMsgQueue->nextMessage) && sysMsgQueue->msgCount) + { + /* Queue is full, beep (but not on every mouse motion...) */ + if (message != WM_MOUSEMOVE) MessageBeep(0); + return; + } + + /* Store message */ + + msg = &sysMsgQueue->messages[pos].msg; + msg->hwnd = 0; + msg->message = message; + msg->wParam = wParam; + msg->lParam = lParam; + msg->time = time; + msg->pt.x = xPos & 0xffff; + msg->pt.y = yPos & 0xffff; + sysMsgQueue->messages[pos].extraInfo = extraInfo; + if (pos < sysMsgQueue->queueSize - 1) pos++; + else pos = 0; + sysMsgQueue->nextFreeMessage = pos; + sysMsgQueue->msgCount++; +} + + +/*********************************************************************** + * QUEUE_GetQueueTask + */ +HTASK QUEUE_GetQueueTask( HQUEUE hQueue ) +{ + MESSAGEQUEUE *queue = GlobalLock( hQueue ); + return (queue) ? queue->hTask : 0 ; +} + + +/*********************************************************************** + * QUEUE_IncPaintCount + */ +void QUEUE_IncPaintCount( HQUEUE hQueue ) +{ + MESSAGEQUEUE *queue; + + if (!(queue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return; + queue->wPaintCount++; + queue->status |= QS_PAINT; + queue->tempStatus |= QS_PAINT; +} + + +/*********************************************************************** + * QUEUE_DecPaintCount + */ +void QUEUE_DecPaintCount( HQUEUE hQueue ) +{ + MESSAGEQUEUE *queue; + + if (!(queue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return; + queue->wPaintCount--; + if (!queue->wPaintCount) queue->status &= ~QS_PAINT; +} + + +/*********************************************************************** + * QUEUE_IncTimerCount + */ +void QUEUE_IncTimerCount( HQUEUE hQueue ) +{ + MESSAGEQUEUE *queue; + + if (!(queue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return; + queue->wTimerCount++; + queue->status |= QS_TIMER; + queue->tempStatus |= QS_TIMER; +} + + +/*********************************************************************** + * QUEUE_DecTimerCount + */ +void QUEUE_DecTimerCount( HQUEUE hQueue ) +{ + MESSAGEQUEUE *queue; + + if (!(queue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return; + queue->wTimerCount--; + if (!queue->wTimerCount) queue->status &= ~QS_TIMER; +} + + +/*********************************************************************** + * PostQuitMessage (USER.6) + */ +void PostQuitMessage( INT exitCode ) +{ + MESSAGEQUEUE *queue; + + if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return; + queue->wPostQMsg = TRUE; + queue->wExitCode = (WORD)exitCode; +} + + +/*********************************************************************** + * GetWindowTask (USER.224) + */ +HTASK GetWindowTask( HWND hwnd ) +{ + WND *wndPtr = WIN_FindWndPtr( hwnd ); + + if (!wndPtr) return 0; + return QUEUE_GetQueueTask( wndPtr->hmemTaskQ ); +} + + +/*********************************************************************** + * SetMessageQueue (USER.266) + */ +BOOL SetMessageQueue( int size ) +{ + HQUEUE hQueue, hNewQueue; + MESSAGEQUEUE *queuePtr; + + if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return TRUE; + + if( !(hNewQueue = QUEUE_CreateMsgQueue( size ))) + { + dprintf_msg(stddeb,"SetMessageQueue: failed!\n"); + return FALSE; + } + + /* Free the old message queue */ + if ((hQueue = GetTaskQueue(0)) != 0) QUEUE_DeleteMsgQueue( hQueue ); + + /* Link new queue into list */ + queuePtr = (MESSAGEQUEUE *)GlobalLock( hNewQueue ); + queuePtr->hTask = GetCurrentTask(); + queuePtr->next = hFirstQueue; + hFirstQueue = hNewQueue; + + SetTaskQueue( 0, hNewQueue ); + return TRUE; +} + + +/*********************************************************************** + * GetQueueStatus (USER.334) + */ +DWORD GetQueueStatus( UINT flags ) +{ + MESSAGEQUEUE *queue; + DWORD ret; + + if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return 0; + ret = MAKELONG( queue->tempStatus, queue->status ); + queue->tempStatus = 0; + return ret & MAKELONG( flags, flags ); +} + + +/*********************************************************************** + * GetInputState (USER.335) + */ +BOOL GetInputState() +{ + MESSAGEQUEUE *queue; + + if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return FALSE; + return queue->status & (QS_KEY | QS_MOUSEBUTTON); +} + + +/*********************************************************************** + * GetMessagePos (USER.119) + */ +DWORD GetMessagePos(void) +{ + MESSAGEQUEUE *queue; + + if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return 0; + return queue->GetMessagePosVal; +} + + +/*********************************************************************** + * GetMessageTime (USER.120) + */ +LONG GetMessageTime(void) +{ + MESSAGEQUEUE *queue; + + if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return 0; + return queue->GetMessageTimeVal; +} + + +/*********************************************************************** + * GetMessageExtraInfo (USER.288) + */ +LONG GetMessageExtraInfo(void) +{ + MESSAGEQUEUE *queue; + + if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return 0; + return queue->GetMessageExtraInfoVal; +} diff --git a/windows/timer.c b/windows/timer.c index 797f66e6190..1be4855d5e7 100644 --- a/windows/timer.c +++ b/windows/timer.c @@ -5,7 +5,7 @@ */ #include "windows.h" -#include "message.h" +#include "queue.h" #include "stddebug.h" /* #define DEBUG_TIMER */ #include "debug.h" @@ -173,7 +173,7 @@ static WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout, dprintf_timer(stddeb, "Timer added: %p, "NPFMT", %04x, %04x, %08lx\n", pTimer, pTimer->hwnd, pTimer->msg, pTimer->id, (DWORD)pTimer->proc); TIMER_InsertTimer( pTimer ); - MSG_IncTimerCount( GetTaskQueue(0) ); + QUEUE_IncTimerCount( GetTaskQueue(0) ); if (!id) return TRUE; else @@ -207,7 +207,7 @@ static BOOL TIMER_KillTimer( HWND hwnd, WORD id, BOOL sys ) pTimer->timeout = 0; pTimer->proc = 0; TIMER_RemoveTimer( pTimer ); - MSG_DecTimerCount( GetTaskQueue(0) ); + QUEUE_DecTimerCount( GetTaskQueue(0) ); return TRUE; } diff --git a/windows/win.c b/windows/win.c index a6609a80ed7..eb7f3d1c611 100644 --- a/windows/win.c +++ b/windows/win.c @@ -15,8 +15,8 @@ #include "sysmetrics.h" #include "cursoricon.h" #include "event.h" -#include "message.h" #include "nonclient.h" +#include "queue.h" #include "winpos.h" #include "color.h" #include "shm_main_blk.h" @@ -51,6 +51,97 @@ WND * WIN_FindWndPtr( HWND hwnd ) } +/*********************************************************************** + * WIN_DumpWindow + * + * Dump the content of a window structure to stderr. + */ +void WIN_DumpWindow( HWND hwnd ) +{ + CLASS *classPtr; + WND *ptr; + char className[80]; + int i; + + if (!(ptr = WIN_FindWndPtr( hwnd ))) + { + fprintf( stderr, "%04x is not a window handle\n", hwnd ); + return; + } + + if (!GetClassName( hwnd, className, sizeof(className ) )) + strcpy( className, "#NULL#" ); + + fprintf( stderr, "Window %04x:\n", hwnd ); + fprintf( stderr, + "next=%04x child=%04x parent=%04x owner=%04x class=%04x '%s'\n" + "inst=%04x taskQ=%04x updRgn=%04x active=%04x hdce=%04x idmenu=%04x\n" + "style=%08lx exstyle=%08lx wndproc=%08lx text=%04x '%s'\n" + "client=%d,%d-%d,%d window=%d,%d-%d,%d iconpos=%d,%d maxpos=%d,%d\n" + "sysmenu=%04x flags=%04x props=%04x vscroll=%04x hscroll=%04x\n", + ptr->hwndNext, ptr->hwndChild, ptr->hwndParent, ptr->hwndOwner, + ptr->hClass, className, ptr->hInstance, ptr->hmemTaskQ, + ptr->hrgnUpdate, ptr->hwndLastActive, ptr->hdce, ptr->wIDmenu, + ptr->dwStyle, ptr->dwExStyle, (DWORD)ptr->lpfnWndProc, ptr->hText, + ptr->hText ? (char*)USER_HEAP_LIN_ADDR(ptr->hText) : "", + ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right, + ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top, + ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->ptIconPos.x, + ptr->ptIconPos.y, ptr->ptMaxPos.x, ptr->ptMaxPos.y, ptr->hSysMenu, + ptr->flags, ptr->hProp, ptr->hVScroll, ptr->hHScroll ); + + if ((classPtr = CLASS_FindClassPtr( ptr->hClass )) && + classPtr->wc.cbWndExtra) + { + fprintf( stderr, "extra bytes:" ); + for (i = 0; i < classPtr->wc.cbWndExtra; i++) + fprintf( stderr, " %02x", *((BYTE*)ptr->wExtra+i) ); + fprintf( stderr, "\n" ); + } + fprintf( stderr, "\n" ); +} + + +/*********************************************************************** + * WIN_WalkWindows + * + * Walk the windows tree and print each window on stderr. + */ +void WIN_WalkWindows( HWND hwnd, int indent ) +{ + WND *ptr; + CLASS *classPtr; + char className[80]; + + if (!hwnd) hwnd = hwndDesktop; + if (!indent) /* first time around */ + fprintf( stderr, "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n", + "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc"); + + while (hwnd) + { + fprintf( stderr, "%*s%04x%*s", indent, "", hwnd, 13-indent, "" ); + if (!(ptr = WIN_FindWndPtr( hwnd ))) + { + fprintf( stderr, "*** Invalid window handle\n" ); + return; + } + + if (!(classPtr = CLASS_FindClassPtr( ptr->hClass ))) strcpy( className, "#NULL#" ); + else GlobalGetAtomName( classPtr->atomName, className, sizeof(className) ); + + fprintf( stderr, "%08lx %-6.4x %-17.17s %08x %04x:%04x\n", + (DWORD)ptr, ptr->hmemTaskQ, className, + (unsigned) ptr->dwStyle, + HIWORD(ptr->lpfnWndProc), + LOWORD(ptr->lpfnWndProc)); + + if (ptr->hwndChild) WIN_WalkWindows( ptr->hwndChild, indent+1 ); + hwnd = ptr->hwndNext; + } +} + + /*********************************************************************** * WIN_GetXWindow * @@ -209,7 +300,7 @@ static void WIN_DestroyWindow( HWND hwnd ) if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT)) { if (wndPtr->hrgnUpdate) DeleteObject( wndPtr->hrgnUpdate ); - MSG_DecPaintCount( wndPtr->hmemTaskQ ); + QUEUE_DecPaintCount( wndPtr->hmemTaskQ ); } if (!(wndPtr->dwStyle & WS_CHILD)) { diff --git a/windows/winpos.c b/windows/winpos.c index 40929f4d2f0..139a6ce891a 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -12,6 +12,7 @@ #include "event.h" #include "hook.h" #include "message.h" +#include "queue.h" #include "stackframe.h" #include "winpos.h" #include "nonclient.h" @@ -632,12 +633,8 @@ BOOL SetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl ) BOOL ACTIVATEAPP_callback(HWND hWnd, LPARAM lParam) { ACTIVATESTRUCT *lpActStruct = (ACTIVATESTRUCT*)lParam; - WND *wndPtr = WIN_FindWndPtr( hWnd ); - - if( !wndPtr || hWnd == GetDesktopWindow()) return 1; - if( MSG_GetQueueTask(wndPtr->hmemTaskQ) != lpActStruct->hTaskSendTo ) - return 1; + if (GetWindowTask(hWnd) != lpActStruct->hTaskSendTo) return 1; SendMessage( hWnd, WM_ACTIVATEAPP, lpActStruct->wFlag, (LPARAM)((lpActStruct->hWindowTask)?lpActStruct->hWindowTask:0)); @@ -742,10 +739,10 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus ) /* send WM_ACTIVATEAPP if necessary */ if (hActiveQ != wndPtr->hmemTaskQ) { - HTASK hT = MSG_GetQueueTask( hActiveQ ); + HTASK hT = QUEUE_GetQueueTask( hActiveQ ); actStruct.wFlag = 0; /* deactivate */ - actStruct.hWindowTask = MSG_GetQueueTask(wndPtr->hmemTaskQ); + actStruct.hWindowTask = QUEUE_GetQueueTask(wndPtr->hmemTaskQ); actStruct.hTaskSendTo = hT; /* send WM_ACTIVATEAPP to top-level windows @@ -755,7 +752,7 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus ) actStruct.wFlag = 1; /* activate */ actStruct.hWindowTask = hT; - actStruct.hTaskSendTo = MSG_GetQueueTask( wndPtr->hmemTaskQ ); + actStruct.hTaskSendTo = QUEUE_GetQueueTask( wndPtr->hmemTaskQ ); EnumWindows( enumCallback , (LPARAM)&actStruct );