From 02e90087ff40c1f2ea0636d043cc5610980b5268 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sun, 4 Jan 1998 17:49:09 +0000 Subject: [PATCH] Release 980104 Sat Jan 3 17:15:56 1998 Alexandre Julliard * [debugger/db_disasm.c] Added cpuid and cmpxchg instructions. * [if1632/builtin.c] [relay32/builtin32.c] Fixed broken -dll option with Win32 DLLs. * [include/heap.h] Added SYSTEM_LOCK/SYSTEM_UNLOCK macros. * [configure.in] [misc/lstr.c] Added check for wctype.h. Commented out --enable-ipc option (IPC code has been broken for a long time anyway). * [scheduler/critsection.c] [scheduler/event.c] [scheduler/mutex.c] [scheduler/semaphore.c] Implemented Win32 synchronization objects. * [scheduler/synchro.c] Implemented WaitForMultipleObjects and related functions. * [scheduler/thread.c] If possible, use clone() in CreateThread(). * [scheduler/thread.c] [scheduler/process.c] Made thread and process waitable objects. Thread and process id values are now different from the pointers they represent. * [win32/k32obj.c] Moved to scheduler directory. Added function table for waiting operations on objects. * [files/file.c] [memory/virtual.c] Added new K32OBJ function table. Sun Jan 1 16:48:23 1997 Andreas Mohr <100.30936@germany.net> * [files/file.c] Fixed my patch for GetTempFileName16() as needed. It was ...Name32A() that didn't work properly, not ...Name16(). * [graphics/x11drv/brush.c] Fixed a BadMatch error. * [msdos/int21.c] Fixed INT21_FindNextFCB() to get correct volume labels e.g. in "file open" dialog. * [multimedia/joystick.c] [relay32/winmm.spec] Stub JoyGetPosEx(). * [scheduler/process.c] [relay32/kernel32.spec] Implemented RegisterServiceProcess(). Wed Dec 31 11:14:43 1997 Lawson Whitney * [if1632/kernel.spec] [if1632/relay.c] Define CallProcEx32w - Thanks to Marcus Meissner for his excellent CallProc32W. * [loader/module.c] Take a shot at defining FreeLibrary32W. Sun Dec 28 12:44:04 1997 Kai Morich * [controls/menu.c] Menu modification from WM_INITMENUPOPUP message fixed. Menu items now can have different wID and hSubMenu (Win95 behavior). * [misc/cpu.c] Improved IsProcessorFeaturePresent. Sun Dec 28 03:21:08 1997 Ove Kaaven * [include/winsock.h] [misc/winsock.c] Fixed WS_SOL_SOCKET for setsockopt(), and made select() return empty fd_sets if timeout. * [objects/palette.c] AnimatePalette() bailed out if entire palette is animated. Fixed. * [objects/dib.c] Added some code to SetDIBitsToDevice() and its helpers to fix some offseting problems. * [objects/cursoricon.c] Made CreateCursor32() convert the instance handle properly. Made DestroyCursor() return correct success status. Wed Dec 24 17:56:34 1997 Dimitrie O. Paun * [windows/syscolor.c] Added definition of GetSysColorPen16/32. This function does not exist in the Win32 API but is a very close (and natural) relative to GetSysColorBrush function. Moreover, it is *very* much used within Wine since there are a lot of places where we need to draw lines with the standard colors. * [controls/button.c] [controls/combo.c] [controls/icontitle.c] [controls/menu.c] [controls/progress.c] [controls/scroll.c] [controls/updown.c] [graphics/painting.c] [misc/tweak.c] [windows/defwnd.c] [windows/graphics.c] [windows/nonclient.c] Replaced references to sysColorObjects with the appropriate call to GetSysColorBrush32/GetSysColorPen32. There is no need to expose the implementation of these functions, even within Wine. This makes the code easier to understand, debug, maintain. * [controls/uitools.c] Modified most of the functions in this file to use the now standard pens (i.e. GetSysColorPen32). These functions made *heavy* use of standard pens so I expect a lot less CreatePen/DeleteObject calls can do only good...:) Plus some minor modifications (*no* functional changes though). * [controls/updown.c] Used the new DrawFrameControl32 function to paint the control. I also deleted UDDOWN_DrawArrow since it was no longer required. Tue Dec 23 00:03:33 1997 Steinar Hamre * [configure.in] Added check for -lw. * [include/wintypes.h] [tools/build.c] Changes to make the assembly understandable for even sun as. ".ascii" -> ".string", "call %foo" -> "call *%foo", "pushw/popw %[cdes]s" written out to ".byte 0x66\npushl/popl %[cdes]s". * [memory/ldt.c] #ifdef added so will not be included on Solaris. Mon Dec 22 18:55:19 1997 Marcus Meissner * [configure.in] Added XF86DGA check. * [multimedia/dsound.c][relay32/dsound.spec][include/dsound.h] Started DirectSound. Only stubs for now. * [graphics/ddraw.c][include/ddraw.h][relay32/ddraw.spec] Started to implement DirectDraw. Mostly stubs, some testcases work. Requires the XF86DGA extension to XFree86. (check demo/blizdemo.exe from the Diablo CD-ROM). * [files/drive.c] Return correct "CDFS" fsname so Diablo is a bit happier. Sun Dec 21 21:45:48 1997 Kevin Cozens * [misc/registry.c] Fixed bugs in the routines which read the Windows '95 registry files. Added extra information regarding the format of the Windows '95 registry files. --- ANNOUNCE | 19 +- ChangeLog | 151 +++++++ Make.rules.in | 2 +- Makefile.in | 4 +- configure | 348 ++++++++++----- configure.in | 22 +- controls/button.c | 12 +- controls/combo.c | 11 +- controls/icontitle.c | 3 +- controls/menu.c | 53 ++- controls/progress.c | 1 - controls/scroll.c | 15 +- controls/uitools.c | 128 ++---- controls/updown.c | 95 +--- debugger/db_disasm.c | 6 +- documentation/languages | 4 +- files/drive.c | 23 +- files/file.c | 31 +- graphics/Makefile.in | 1 + graphics/ddraw.c | 904 +++++++++++++++++++++++++++++++++++++++ graphics/painting.c | 7 +- graphics/win16drv/init.c | 4 +- graphics/x11drv/brush.c | 20 +- graphics/x11drv/graphics.c | 1 - if1632/builtin.c | 7 +- if1632/kernel.spec | 2 +- if1632/relay.c | 31 +- if1632/signal.c | 24 -- include/builtin32.h | 2 + include/config.h.in | 15 + include/ddraw.h | 898 ++++++++++++++++++++++++++++++++++++++ include/dsound.h | 187 ++++++++ include/file.h | 3 +- include/heap.h | 8 + include/{handle32.h => k32obj.h} | 40 +- include/mmsystem.h | 8 +- include/process.h | 15 +- include/shlobj.h | 2 +- include/struct32.h | 2 +- include/syscolor.h | 47 -- include/sysmetrics.h | 4 +- include/thread.h | 218 ++++++---- include/version.h | 2 +- include/windows.h | 20 +- include/winerror.h | 14 +- include/winnt.h | 4 + include/winsock.h | 2 +- include/wintypes.h | 2 +- libtest/Makefile.in | 2 +- loader/main.c | 5 - loader/module.c | 8 +- loader/pe_image.c | 16 +- loader/pe_resource.c | 2 +- loader/signal.c | 3 + loader/task.c | 17 +- memory/global.c | 9 +- memory/heap.c | 14 +- memory/ldt.c | 2 + memory/virtual.c | 53 ++- misc/comm.c | 1 - misc/cpu.c | 38 +- misc/crtdll.c | 20 + misc/lstr.c | 11 +- misc/main.c | 2 + misc/registry.c | 191 ++++++--- misc/shellord.c | 2 +- misc/tweak.c | 1 - misc/ver.c | 9 +- misc/winsock.c | 8 +- misc/wsprintf.c | 4 + msdos/int21.c | 10 +- msdos/int2f.c | 3 + multimedia/Makefile.in | 1 + multimedia/dsound.c | 177 ++++++++ multimedia/joystick.c | 18 + objects/brush.c | 75 ---- objects/cursoricon.c | 8 +- objects/dib.c | 123 +++--- objects/palette.c | 2 +- objects/region.c | 10 + ole/compobj.c | 2 + ole/folders.c | 41 +- programs/notepad/ChangeLog | 5 + programs/notepad/De.rc | 6 +- programs/notepad/En.rc | 4 +- programs/notepad/Makefile.in | 8 +- programs/notepad/main.c | 245 +++++++++++ programs/notepad/main.h | 99 +++++ programs/notepad/notepad.rc | 36 +- programs/progman/Makefile.in | 2 +- programs/progman/Va.rc | 6 +- programs/progman/license.c | 10 +- programs/progman/license.h | 17 +- programs/winhelp/Makefile.in | 4 +- programs/winver/Makefile.in | 2 +- rc/winerc.c | 6 + relay32/Makefile.in | 2 + relay32/builtin32.c | 44 ++ relay32/crtdll.spec | 2 +- relay32/ddraw.spec | 28 ++ relay32/dsound.spec | 11 + relay32/gdi32.spec | 2 +- relay32/kernel32.spec | 28 +- relay32/ntdll.spec | 5 +- relay32/relay386.c | 8 +- relay32/user32.spec | 2 +- relay32/winmm.spec | 2 +- relay32/wow32.spec | 2 +- scheduler/Makefile.in | 6 + scheduler/critsection.c | 286 +++++++++++++ scheduler/event.c | 268 ++++++++++++ scheduler/k32obj.c | 260 +++++++++++ scheduler/mutex.c | 207 +++++++++ scheduler/process.c | 218 +++++++--- scheduler/semaphore.c | 214 +++++++++ scheduler/synchro.c | 315 ++++++++++++++ scheduler/thread.c | 298 ++++++++++--- tools/build.c | 37 +- tools/fnt2bdf.c | 46 +- win32/Makefile.in | 1 - win32/file.c | 1 - win32/init.c | 1 - win32/k32obj.c | 226 ---------- win32/kernel32.c | 3 +- win32/ordinals.c | 3 +- win32/process.c | 599 ++++++-------------------- win32/thread.c | 127 +----- win32/user32.c | 1 - windows/dce.c | 3 +- windows/defwnd.c | 8 +- windows/event.c | 6 +- windows/graphics.c | 9 +- windows/keyboard.c | 35 +- windows/message.c | 35 +- windows/nonclient.c | 37 +- windows/property.c | 42 +- windows/syscolor.c | 167 +++----- 137 files changed, 6304 insertions(+), 2051 deletions(-) create mode 100644 graphics/ddraw.c create mode 100644 include/ddraw.h create mode 100644 include/dsound.h rename include/{handle32.h => k32obj.h} (50%) delete mode 100644 include/syscolor.h rewrite include/thread.h (66%) create mode 100644 multimedia/dsound.c create mode 100644 programs/notepad/main.c create mode 100644 programs/notepad/main.h create mode 100644 relay32/ddraw.spec create mode 100644 relay32/dsound.spec create mode 100644 scheduler/critsection.c create mode 100644 scheduler/event.c create mode 100644 scheduler/k32obj.c create mode 100644 scheduler/mutex.c create mode 100644 scheduler/semaphore.c create mode 100644 scheduler/synchro.c delete mode 100644 win32/k32obj.c rewrite win32/process.c (68%) diff --git a/ANNOUNCE b/ANNOUNCE index 3f2c3595c6d..aba47d4ebc1 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,16 +1,13 @@ -This is release 971221 of Wine, the MS Windows emulator. This is still a +This is release 980104 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 correctly. Patches should be submitted to "julliard@lrc.epfl.ch". Please don't forget to include a ChangeLog entry. -WHAT'S NEW with Wine-971221: (see ChangeLog for details) - - Preliminary GDI paths support. - - DrawFrameControl implementation. - - Multimedia support for time and joystick functions. - - Win32 spec files now generate C code for Winelib. - - Tons of new Win32 functions and stubs. +WHAT'S NEW with Wine-980104: (see ChangeLog for details) + - Beginnings of DirectDraw/DirectSound support. + - Preliminary threading support based on clone(). - Lots of bug fixes. See the README file in the distribution for installation instructions. @@ -19,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: - ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-971221.tar.gz - ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-971221.tar.gz - ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-971221.tar.gz - ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-971221.tar.gz + ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-980104.tar.gz + ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-980104.tar.gz + ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-980104.tar.gz + ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-980104.tar.gz It should also be available from any site that mirrors tsx-11 or sunsite. diff --git a/ChangeLog b/ChangeLog index aad647d1ecf..57e6fb2fc30 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,155 @@ ---------------------------------------------------------------------- +Sat Jan 3 17:15:56 1998 Alexandre Julliard + + * [debugger/db_disasm.c] + Added cpuid and cmpxchg instructions. + + * [if1632/builtin.c] [relay32/builtin32.c] + Fixed broken -dll option with Win32 DLLs. + + * [include/heap.h] + Added SYSTEM_LOCK/SYSTEM_UNLOCK macros. + + * [configure.in] [misc/lstr.c] + Added check for wctype.h. + Commented out --enable-ipc option (IPC code has been broken for a + long time anyway). + + * [scheduler/critsection.c] [scheduler/event.c] + [scheduler/mutex.c] [scheduler/semaphore.c] + Implemented Win32 synchronization objects. + + * [scheduler/synchro.c] + Implemented WaitForMultipleObjects and related functions. + + * [scheduler/thread.c] + If possible, use clone() in CreateThread(). + + * [scheduler/thread.c] [scheduler/process.c] + Made thread and process waitable objects. + Thread and process id values are now different from the pointers + they represent. + + * [win32/k32obj.c] + Moved to scheduler directory. + Added function table for waiting operations on objects. + + * [files/file.c] [memory/virtual.c] + Added new K32OBJ function table. + +Sun Jan 1 16:48:23 1997 Andreas Mohr <100.30936@germany.net> + + * [files/file.c] + Fixed my patch for GetTempFileName16() as needed. + It was ...Name32A() that didn't work properly, not ...Name16(). + + * [graphics/x11drv/brush.c] + Fixed a BadMatch error. + + * [msdos/int21.c] + Fixed INT21_FindNextFCB() to get correct volume labels e.g. + in "file open" dialog. + + * [multimedia/joystick.c] [relay32/winmm.spec] + Stub JoyGetPosEx(). + + * [scheduler/process.c] [relay32/kernel32.spec] + Implemented RegisterServiceProcess(). + +Wed Dec 31 11:14:43 1997 Lawson Whitney + + * [if1632/kernel.spec] [if1632/relay.c] + Define CallProcEx32w - Thanks to Marcus Meissner for his excellent + CallProc32W. + + * [loader/module.c] + Take a shot at defining FreeLibrary32W. + +Sun Dec 28 12:44:04 1997 Kai Morich + + * [controls/menu.c] + Menu modification from WM_INITMENUPOPUP message fixed. + Menu items now can have different wID and hSubMenu (Win95 behavior). + + * [misc/cpu.c] + Improved IsProcessorFeaturePresent. + +Sun Dec 28 03:21:08 1997 Ove Kaaven + + * [include/winsock.h] [misc/winsock.c] + Fixed WS_SOL_SOCKET for setsockopt(), and made select() return + empty fd_sets if timeout. + + * [objects/palette.c] + AnimatePalette() bailed out if entire palette is animated. Fixed. + + * [objects/dib.c] + Added some code to SetDIBitsToDevice() and its helpers to fix + some offseting problems. + + * [objects/cursoricon.c] + Made CreateCursor32() convert the instance handle properly. Made + DestroyCursor() return correct success status. + +Wed Dec 24 17:56:34 1997 Dimitrie O. Paun + + * [windows/syscolor.c] + Added definition of GetSysColorPen16/32. This function does not + exist in the Win32 API but is a very close (and natural) relative + to GetSysColorBrush function. Moreover, it is *very* much used + within Wine since there are a lot of places where we need to draw + lines with the standard colors. + + * [controls/button.c] [controls/combo.c] [controls/icontitle.c] + [controls/menu.c] [controls/progress.c] [controls/scroll.c] + [controls/updown.c] [graphics/painting.c] [misc/tweak.c] + [windows/defwnd.c] [windows/graphics.c] [windows/nonclient.c] + Replaced references to sysColorObjects with the appropriate + call to GetSysColorBrush32/GetSysColorPen32. There is no need to + expose the implementation of these functions, even within Wine. + This makes the code easier to understand, debug, maintain. + + * [controls/uitools.c] + Modified most of the functions in this file to use the now + standard pens (i.e. GetSysColorPen32). These functions made + *heavy* use of standard pens so I expect a lot less + CreatePen/DeleteObject calls can do only good...:) + Plus some minor modifications (*no* functional changes though). + + * [controls/updown.c] + Used the new DrawFrameControl32 function to paint the control. + I also deleted UDDOWN_DrawArrow since it was no longer required. + +Tue Dec 23 00:03:33 1997 Steinar Hamre + + * [configure.in] + Added check for -lw. + + * [include/wintypes.h] [tools/build.c] + Changes to make the assembly understandable for even sun as. + ".ascii" -> ".string", "call %foo" -> "call *%foo", + "pushw/popw %[cdes]s" written out to ".byte 0x66\npushl/popl %[cdes]s". + + * [memory/ldt.c] + #ifdef added so will not be included on Solaris. + +Mon Dec 22 18:55:19 1997 Marcus Meissner + + * [configure.in] + Added XF86DGA check. + + * [multimedia/dsound.c][relay32/dsound.spec][include/dsound.h] + Started DirectSound. Only stubs for now. + + * [graphics/ddraw.c][include/ddraw.h][relay32/ddraw.spec] + Started to implement DirectDraw. Mostly stubs, some + testcases work. Requires the XF86DGA extension to XFree86. + (check demo/blizdemo.exe from the Diablo CD-ROM). + + * [files/drive.c] + Return correct "CDFS" fsname so Diablo is a bit happier. + +---------------------------------------------------------------------- Fri Dec 19 10:50:46 1997 Douglas Ridgway * [Make.rules.in] [Makefile.in] [documentation/Makefile.in] diff --git a/Make.rules.in b/Make.rules.in index 7b1e7d7f1bf..5cc35b76e2b 100644 --- a/Make.rules.in +++ b/Make.rules.in @@ -24,7 +24,7 @@ X_LIBS = @X_LIBS@ XPM_LIB = -lXpm XLIB = @X_PRE_LIBS@ -lXext -lX11 @X_EXTRA_LIBS@ WINELIB = $(WINESTUB) $(TOPOBJDIR)/@LIB_TARGET@ -LDLIBS = @LDLIBS@ +LIBS = @LIBS@ YACC = @YACC@ LEX = @LEX@ LEXLIB = @LEXLIB@ diff --git a/Makefile.in b/Makefile.in index c34c3b6f524..e6db31e8b42 100644 --- a/Makefile.in +++ b/Makefile.in @@ -106,7 +106,7 @@ emu: wine lib: $(LIBSUBDIRS) $(LIB_TARGET) wine wine.sym: $(LIBSUBDIRS) $(LIB_TARGET) $(EMUSUBDIRS) dummy - $(CC) -o wine $(EMUOBJS) $(LIB_TARGET) $(LDOPTIONS) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS) + $(CC) -o wine $(EMUOBJS) $(LIB_TARGET) $(LDOPTIONS) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS) nm -n wine | grep -v _compiled >wine.sym libwine.a: $(LIBOBJS) @@ -115,7 +115,7 @@ libwine.a: $(LIBOBJS) $(RANLIB) $@ libwine.so.1.0: $(LIBOBJS) - $(CC) -shared -Wl,-soname,libwine.so -o$@ $(LIBOBJS) $(LDOPTIONS) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS) + $(CC) -shared -Wl,-soname,libwine.so -o$@ $(LIBOBJS) $(LDOPTIONS) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS) install_emu: dummy $(INSTALL_PROGRAM) wine $(bindir)/wine diff --git a/configure b/configure index 1032ff2e6ce..20417c6d4f8 100755 --- a/configure +++ b/configure @@ -17,8 +17,6 @@ ac_help="$ac_help ac_help="$ac_help --enable-dll build the Wine library as a DLL" ac_help="$ac_help - --enable-ipc use inter-process communication for DDE" -ac_help="$ac_help --with-x use the X Window System" # Initialize some variables set by options. @@ -549,7 +547,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # We want these before the checks, so the checks can modify their values. -test -z "$LDLIBS" && LDLIBS=-lm +LIBS="$LIBS -lm" test -z "$PROGEXT" && PROGEXT="" @@ -570,12 +568,6 @@ if test "${enable_dll+set}" = set; then fi -# Check whether --with-ipc or --without-ipc was given. -if test "${with_ipc+set}" = set; then - withval="$with_ipc" - if test "$enableval" = "no"; then : ; else OPTIONS="-DCONFIG_IPC"; fi -fi - @@ -583,7 +575,7 @@ fi echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:587: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:579: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -612,7 +604,7 @@ fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:616: checking for $ac_word" >&5 +echo "configure:608: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -641,7 +633,7 @@ 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 -echo "configure:645: checking for $ac_word" >&5 +echo "configure:637: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -689,7 +681,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:693: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:685: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -699,11 +691,11 @@ ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:699: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -723,12 +715,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:727: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:719: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:732: checking whether we are using GNU C" >&5 +echo "configure:724: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -737,7 +729,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:741: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:733: \"$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 @@ -752,7 +744,7 @@ if test $ac_cv_prog_gcc = yes; then ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:756: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:748: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -780,7 +772,7 @@ else fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:784: checking how to run the C preprocessor" >&5 +echo "configure:776: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -795,13 +787,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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:805: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:797: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : @@ -812,13 +804,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:822: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:814: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : @@ -845,7 +837,7 @@ echo "$ac_t""$CPP" 1>&6 # Uses ac_ vars as temps to allow command line to override cache and checks. # --without-x overrides everything else, but does not touch the cache. echo $ac_n "checking for X""... $ac_c" 1>&6 -echo "configure:849: checking for X" >&5 +echo "configure:841: checking for X" >&5 # Check whether --with-x or --without-x was given. if test "${with_x+set}" = set; then @@ -907,12 +899,12 @@ if test "$ac_x_includes" = NO; then # First, try using that file with no special directory specified. cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:916: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:908: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -981,14 +973,14 @@ if test "$ac_x_libraries" = NO; then ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:984: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* LIBS="$ac_save_LIBS" # We can link X programs with no special library path. @@ -1094,17 +1086,17 @@ else case "`(uname -sr) 2>/dev/null`" in "SunOS 5"*) echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6 -echo "configure:1098: checking whether -R must be followed by a space" >&5 +echo "configure:1090: checking whether -R must be followed by a space" >&5 ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1100: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_R_nospace=yes else @@ -1120,14 +1112,14 @@ rm -f conftest* else LIBS="$ac_xsave_LIBS -R $x_libraries" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1123: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_R_space=yes else @@ -1159,7 +1151,7 @@ rm -f conftest* # 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 dnet_ntoa in -ldnet""... $ac_c" 1>&6 -echo "configure:1163: checking for dnet_ntoa in -ldnet" >&5 +echo "configure:1155: checking for dnet_ntoa in -ldnet" >&5 ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1167,7 +1159,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldnet $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1174: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1200,7 +1192,7 @@ fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6 -echo "configure:1204: checking for dnet_ntoa in -ldnet_stub" >&5 +echo "configure:1196: checking for dnet_ntoa in -ldnet_stub" >&5 ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1208,7 +1200,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldnet_stub $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1215: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1248,12 +1240,12 @@ fi # The nsl library prevents programs from opening the X display # on Irix 5.2, according to dickey@clark.net. echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 -echo "configure:1252: checking for gethostbyname" >&5 +echo "configure:1244: checking for gethostbyname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1272: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_gethostbyname=yes" else @@ -1297,7 +1289,7 @@ fi if test $ac_cv_func_gethostbyname = no; then echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 -echo "configure:1301: checking for gethostbyname in -lnsl" >&5 +echo "configure:1293: checking for gethostbyname in -lnsl" >&5 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1305,7 +1297,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1312: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1346,12 +1338,12 @@ fi # -lsocket must be given before -lnsl if both are needed. # We assume that if connect needs -lnsl, so does gethostbyname. echo $ac_n "checking for connect""... $ac_c" 1>&6 -echo "configure:1350: checking for connect" >&5 +echo "configure:1342: checking for connect" >&5 if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1370: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_connect=yes" else @@ -1395,7 +1387,7 @@ fi if test $ac_cv_func_connect = no; then echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6 -echo "configure:1399: checking for connect in -lsocket" >&5 +echo "configure:1391: checking for connect in -lsocket" >&5 ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1403,7 +1395,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $X_EXTRA_LIBS $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1410: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1438,12 +1430,12 @@ fi # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX. echo $ac_n "checking for remove""... $ac_c" 1>&6 -echo "configure:1442: checking for remove" >&5 +echo "configure:1434: checking for remove" >&5 if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1462: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_remove=yes" else @@ -1487,7 +1479,7 @@ fi if test $ac_cv_func_remove = no; then echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6 -echo "configure:1491: checking for remove in -lposix" >&5 +echo "configure:1483: checking for remove in -lposix" >&5 ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1495,7 +1487,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lposix $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1502: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1530,12 +1522,12 @@ fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. echo $ac_n "checking for shmat""... $ac_c" 1>&6 -echo "configure:1534: checking for shmat" >&5 +echo "configure:1526: checking for shmat" >&5 if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1554: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_shmat=yes" else @@ -1579,7 +1571,7 @@ fi if test $ac_cv_func_shmat = no; then echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6 -echo "configure:1583: checking for shmat in -lipc" >&5 +echo "configure:1575: checking for shmat in -lipc" >&5 ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1587,7 +1579,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lipc $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1594: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1631,7 +1623,7 @@ fi # libraries we check for below, so use a different variable. # --interran@uluru.Stanford.EDU, kb@cs.umb.edu. echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6 -echo "configure:1635: checking for IceConnectionNumber in -lICE" >&5 +echo "configure:1627: checking for IceConnectionNumber in -lICE" >&5 ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1639,7 +1631,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lICE $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1646: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1679,7 +1671,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1683: checking for $ac_word" >&5 +echo "configure:1675: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1711,7 +1703,7 @@ test -n "$YACC" || YACC="yacc" # Extract the first word of "flex", so it can be a program name with args. set dummy flex; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1715: checking for $ac_word" >&5 +echo "configure:1707: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1744,7 +1736,7 @@ then *) ac_lib=l ;; esac echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6 -echo "configure:1748: checking for yywrap in -l$ac_lib" >&5 +echo "configure:1740: checking for yywrap in -l$ac_lib" >&5 ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1752,7 +1744,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$ac_lib $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1759: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1788,7 +1780,7 @@ fi # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1792: checking for $ac_word" >&5 +echo "configure:1784: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1825,7 +1817,7 @@ fi # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1829: checking for a BSD compatible install" >&5 +echo "configure:1821: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1875,7 +1867,7 @@ test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 -echo "configure:1879: checking whether ln -s works" >&5 +echo "configure:1871: checking whether ln -s works" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1895,8 +1887,10 @@ else echo "$ac_t""no" 1>&6 fi + + echo $ac_n "checking for i386_set_ldt in -li386""... $ac_c" 1>&6 -echo "configure:1900: checking for i386_set_ldt in -li386" >&5 +echo "configure:1894: checking for i386_set_ldt in -li386" >&5 ac_lib_var=`echo i386'_'i386_set_ldt | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1904,7 +1898,7 @@ else ac_save_LIBS="$LIBS" LIBS="-li386 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1913: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo i386 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +echo $ac_n "checking for iswalnum in -lw""... $ac_c" 1>&6 +echo "configure:1941: checking for iswalnum in -lw" >&5 +ac_lib_var=`echo w'_'iswalnum | sed 'y%./+-%__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="-lw $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_lib=HAVE_LIB`echo w | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + +echo $ac_n "checking for XF86DGAQueryExtension in -lXxf86dga""... $ac_c" 1>&6 +echo "configure:1988: checking for XF86DGAQueryExtension in -lXxf86dga" >&5 +ac_lib_var=`echo Xxf86dga'_'XF86DGAQueryExtension | sed 'y%./+-%__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="-lXxf86dga -lXext -lX11 $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1930,7 +2018,14 @@ LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 - LDLIBS="$LDLIBS -li386" + ac_tr_lib=HAVE_LIB`echo Xxf86dga | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 fi @@ -1943,7 +2038,7 @@ if test "x${GCC}" = "xyes" then CFLAGS="$CFLAGS -Wall" echo $ac_n "checking "for gcc strength-reduce bug"""... $ac_c" 1>&6 -echo "configure:1947: checking "for gcc strength-reduce bug"" >&5 +echo "configure:2042: checking "for gcc strength-reduce bug"" >&5 if eval "test \"`echo '$''{'ac_cv_c_gcc_strength_bug'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1951,7 +2046,7 @@ else ac_cv_c_gcc_strength_bug="yes" else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2061: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then ac_cv_c_gcc_strength_bug="no" else @@ -1985,7 +2080,7 @@ fi echo $ac_n "checking "whether external symbols need an underscore prefix"""... $ac_c" 1>&6 -echo "configure:1989: checking "whether external symbols need an underscore prefix"" >&5 +echo "configure:2084: checking "whether external symbols need an underscore prefix"" >&5 if eval "test \"`echo '$''{'ac_cv_c_extern_prefix'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1997,14 +2092,14 @@ _ac_test: .long 0 EOF cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2103: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_cv_c_extern_prefix="yes" else @@ -2031,21 +2126,21 @@ DLLFLAGS="" if test "$LIB_TARGET" = "libwine.so.1.0" then echo $ac_n "checking "whether we can build a dll"""... $ac_c" 1>&6 -echo "configure:2035: checking "whether we can build a dll"" >&5 +echo "configure:2130: checking "whether we can build a dll"" >&5 if eval "test \"`echo '$''{'ac_cv_c_dll'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else saved_cflags=$CFLAGS CFLAGS="$CFLAGS -fPIC -shared -Wl,-soname,conftest.so.1.0" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:2144: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* ac_cv_c_dll="yes" else @@ -2070,15 +2165,15 @@ fi -for ac_func in memmove strerror tcgetattr usleep wait4 waitpid +for ac_func in clone memmove strerror tcgetattr usleep wait4 waitpid do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2077: checking for $ac_func" >&5 +echo "configure:2172: checking for $ac_func" >&5 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; } && test -s conftest; then +if { (eval echo configure:2200: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -2125,13 +2220,53 @@ else fi done +for ac_hdr in wctype.h +do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "configure:2228: checking for $ac_hdr" >&5 +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 +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2238: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` + cat >> confdefs.h <&6 +fi +done + echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6 -echo "configure:2130: checking whether stat file-mode macros are broken" >&5 +echo "configure:2265: checking whether stat file-mode macros are broken" >&5 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 @@ -2182,12 +2317,12 @@ EOF fi echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:2186: checking for working const" >&5 +echo "configure:2321: checking for working const" >&5 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 +if { (eval echo configure:2375: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -2257,12 +2392,12 @@ EOF fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:2261: checking for ANSI C header files" >&5 +echo "configure:2396: checking for ANSI C header files" >&5 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 @@ -2270,7 +2405,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2274: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2409: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* @@ -2287,7 +2422,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 @@ -2305,7 +2440,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 @@ -2326,7 +2461,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -2337,7 +2472,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:2341: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2476: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then : else @@ -2361,12 +2496,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:2365: checking for size_t" >&5 +echo "configure:2500: checking for size_t" >&5 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 @@ -2563,7 +2698,6 @@ s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g -s%@LDLIBS@%$LDLIBS%g s%@PROGEXT@%$PROGEXT%g s%@MAIN_TARGET@%$MAIN_TARGET%g s%@LIB_TARGET@%$LIB_TARGET%g diff --git a/configure.in b/configure.in index 11b26ab7b54..abf9119e213 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_CONFIG_HEADER(include/config.h) AC_CONFIG_AUX_DIR(tools) # We want these before the checks, so the checks can modify their values. -test -z "$LDLIBS" && LDLIBS=-lm AC_SUBST(LDLIBS) +LIBS="$LIBS -lm" test -z "$PROGEXT" && PROGEXT="" AC_SUBST(PROGEXT) dnl **** Command-line arguments **** @@ -24,15 +24,15 @@ AC_ARG_ENABLE(dll, [ --enable-dll build the Wine library as a DLL], [if test "$enableval" = "no"; then : ; else LIB_TARGET="libwine.so.1.0"; fi]) -AC_ARG_WITH(ipc, -[ --enable-ipc use inter-process communication for DDE], -[if test "$enableval" = "no"; then : ; else OPTIONS="-DCONFIG_IPC"; fi]) +dnl AC_ARG_WITH(ipc, +dnl [ --enable-ipc use inter-process communication for DDE], +dnl [if test "$enableval" = "no"; then : ; else OPTIONS="-DCONFIG_IPC"; fi]) AC_SUBST(MAIN_TARGET) AC_SUBST(LIB_TARGET) AC_SUBST(OPTIONS) -dnl **** Check for some programs and libraries **** +dnl **** Check for some programs **** AC_PROG_MAKE_SET AC_PROG_CC @@ -43,8 +43,15 @@ AC_PROG_LEX AC_PROG_RANLIB AC_PROG_INSTALL AC_PROG_LN_S + +dnl **** Check for some libraries **** + dnl Check for -li386 for NetBSD and OpenBSD -AC_CHECK_LIB(i386,i386_set_ldt,LDLIBS="$LDLIBS -li386") +AC_CHECK_LIB(i386,i386_set_ldt) +dnl Check for -lw for Solaris +AC_CHECK_LIB(w,iswalnum) +dnl Check for XFree86 DGA extension +AC_CHECK_LIB(Xxf86dga,XF86DGAQueryExtension,,,-lXext -lX11) dnl **** If ln -s doesn't work, use cp instead **** if test "$ac_cv_prog_LN_S" = "ln -s"; then : ; else LN_S=cp ; fi @@ -114,7 +121,8 @@ AC_SUBST(DLLFLAGS) dnl **** Check for functions and header files **** -AC_CHECK_FUNCS(memmove strerror tcgetattr usleep wait4 waitpid) +AC_CHECK_FUNCS(clone memmove strerror tcgetattr usleep wait4 waitpid) +AC_CHECK_HEADERS(wctype.h) AC_HEADER_STAT() AC_C_CONST() AC_TYPE_SIZE_T() diff --git a/controls/button.c b/controls/button.c index 836070d83e0..9b74f1fc5a4 100644 --- a/controls/button.c +++ b/controls/button.c @@ -6,9 +6,9 @@ */ #include "win.h" -#include "syscolor.h" #include "graphics.h" #include "button.h" +#include "windows.h" static void PB_Paint( WND *wndPtr, HDC32 hDC, WORD action ); static void PB_PaintGrayOnGray(HDC32 hDC,HFONT32 hFont,RECT32 *rc,char *text); @@ -266,8 +266,8 @@ static void PB_Paint( WND *wndPtr, HDC32 hDC, WORD action ) /* Send WM_CTLCOLOR to allow changing the font (the colors are fixed) */ if (infoPtr->hFont) SelectObject32( hDC, infoPtr->hFont ); BUTTON_SEND_CTLCOLOR( wndPtr, hDC ); - hOldPen = (HPEN32)SelectObject32(hDC, sysColorObjects.hpenWindowFrame); - hOldBrush = (HBRUSH32)SelectObject32(hDC, sysColorObjects.hbrushBtnFace); + hOldPen = (HPEN32)SelectObject32(hDC, GetSysColorPen32(COLOR_WINDOWFRAME)); + hOldBrush =(HBRUSH32)SelectObject32(hDC,GetSysColorBrush32(COLOR_BTNFACE)); SetBkMode32(hDC, TRANSPARENT); Rectangle32(hDC, rc.left, rc.top, rc.right, rc.bottom); if (action == ODA_DRAWENTIRE) @@ -288,7 +288,7 @@ static void PB_Paint( WND *wndPtr, HDC32 hDC, WORD action ) if (infoPtr->state & BUTTON_HIGHLIGHTED) { /* draw button shadow: */ - SelectObject32(hDC, sysColorObjects.hbrushBtnShadow ); + SelectObject32(hDC, GetSysColorBrush32(COLOR_BTNSHADOW)); PatBlt32(hDC, rc.left, rc.top, 1, rc.bottom-rc.top, PATCOPY ); PatBlt32(hDC, rc.left, rc.top, rc.right-rc.left, 1, PATCOPY ); rc.left += 2; /* To position the text down and right */ @@ -300,7 +300,7 @@ static void PB_Paint( WND *wndPtr, HDC32 hDC, WORD action ) if (wndPtr->text && wndPtr->text[0]) { LOGBRUSH16 lb; - GetObject16( sysColorObjects.hbrushBtnFace, sizeof(lb), &lb ); + GetObject16( GetSysColorBrush32(COLOR_BTNFACE), sizeof(lb), &lb ); if (wndPtr->dwStyle & WS_DISABLED && GetSysColor32(COLOR_GRAYTEXT)==lb.lbColor) /* don't write gray text on gray bkg */ @@ -494,7 +494,7 @@ static void GB_Paint( WND *wndPtr, HDC32 hDC, WORD action ) GetClientRect16( wndPtr->hwndSelf, &rc); GRAPH_DrawRectangle( hDC, rc.left, rc.top + 2, rc.right - 1, rc.bottom - 1, - sysColorObjects.hpenWindowFrame ); + GetSysColorPen32(COLOR_WINDOWFRAME) ); if (wndPtr->text) { if (infoPtr->hFont) SelectObject32( hDC, infoPtr->hFont ); diff --git a/controls/combo.c b/controls/combo.c index e1ccb16fb0b..59b51cb21aa 100644 --- a/controls/combo.c +++ b/controls/combo.c @@ -11,7 +11,6 @@ #include "windows.h" #include "sysmetrics.h" -#include "syscolor.h" #include "win.h" #include "spy.h" #include "user.h" @@ -366,7 +365,7 @@ static void CBPaintButton(LPHEADCOMBO lphc, HDC16 hdc) if( lphc->wState & CBF_NOREDRAW ) return; - hPrevBrush = (HBRUSH32)SelectObject32(hdc, sysColorObjects.hbrushBtnFace); + hPrevBrush=(HBRUSH32)SelectObject32(hdc,GetSysColorBrush32(COLOR_BTNFACE)); CONV_RECT16TO32( &lphc->RectButton, &r ); Rectangle32(hdc, r.left, r.top, r.right, r.bottom ); @@ -459,7 +458,7 @@ static void CBPaintText(LPHEADCOMBO lphc, HDC16 hdc) { /* highlight */ - FillRect32( hDC, &rect, sysColorObjects.hbrushHighlight ); + FillRect32( hDC, &rect, GetSysColorBrush32(COLOR_HIGHLIGHT) ); SetBkColor32( hDC, GetSysColor32( COLOR_HIGHLIGHT ) ); SetTextColor32( hDC, GetSysColor32( COLOR_HIGHLIGHTTEXT ) ); itemState = ODS_SELECTED | ODS_FOCUS; @@ -538,9 +537,9 @@ static LRESULT COMBO_Paint(LPHEADCOMBO lphc, HDC16 hParamDC) /* paint text field */ GRAPH_DrawRectangle( hDC, lphc->RectEdit.left, lphc->RectEdit.top, - lphc->RectEdit.right - lphc->RectEdit.left, - lphc->RectButton.bottom - lphc->RectButton.top, - sysColorObjects.hpenWindowFrame ); + lphc->RectEdit.right - lphc->RectEdit.left, + lphc->RectButton.bottom - lphc->RectButton.top, + GetSysColorPen32(COLOR_WINDOWFRAME) ); CBPaintText( lphc, hDC ); } if( hPrevBrush ) SelectObject32( hDC, hPrevBrush ); diff --git a/controls/icontitle.c b/controls/icontitle.c index b54801e2414..8c4a4738a69 100644 --- a/controls/icontitle.c +++ b/controls/icontitle.c @@ -9,7 +9,6 @@ #include #include "windows.h" #include "sysmetrics.h" -#include "syscolor.h" #include "win.h" #include "desktop.h" #include "graphics.h" @@ -128,7 +127,7 @@ static BOOL32 ICONTITLE_Paint( WND* wnd, HDC32 hDC, BOOL32 bActive ) if( bActive ) { - hBrush = sysColorObjects.hbrushActiveCaption; + hBrush = GetSysColorBrush32(COLOR_ACTIVECAPTION); textColor = GetSysColor32(COLOR_CAPTIONTEXT); } else diff --git a/controls/menu.c b/controls/menu.c index 8c2e984af37..ee5a0984765 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -20,7 +20,6 @@ #include "windows.h" #include "bitmap.h" #include "gdi.h" -#include "syscolor.h" #include "sysmetrics.h" #include "task.h" #include "win.h" @@ -879,7 +878,7 @@ static void MENU_DrawMenuItem( HWND32 hwnd, HDC32 hdc, MENUITEM *lpitem, r.bottom += MENU_HighlightBottomNudge; r.left += MENU_HighlightLeftNudge; r.right += MENU_HighlightRightNudge; - FillRect32( hdc, &r, sysColorObjects.hbrushHighlight ); + FillRect32( hdc, &r, GetSysColorBrush32(COLOR_HIGHLIGHT) ); } else { RECT32 r = rect; @@ -887,7 +886,7 @@ static void MENU_DrawMenuItem( HWND32 hwnd, HDC32 hdc, MENUITEM *lpitem, r.bottom += MENU_HighlightBottomNudge; r.left += MENU_HighlightLeftNudge; r.right += MENU_HighlightRightNudge; - FillRect32( hdc, &r, sysColorObjects.hbrushMenu ); + FillRect32( hdc, &r, GetSysColorBrush32(COLOR_MENU) ); } SetBkMode32( hdc, TRANSPARENT ); @@ -899,7 +898,7 @@ static void MENU_DrawMenuItem( HWND32 hwnd, HDC32 hdc, MENUITEM *lpitem, if(TWEAK_Win95Look) TWEAK_DrawMenuSeparatorVert95(hdc, rect.left - 1, 3, height - 3); else { - SelectObject32( hdc, sysColorObjects.hpenWindowFrame ); + SelectObject32( hdc, GetSysColorPen32(COLOR_WINDOWFRAME) ); MoveTo( hdc, rect.left, 0 ); LineTo32( hdc, rect.left, height ); } @@ -911,7 +910,7 @@ static void MENU_DrawMenuItem( HWND32 hwnd, HDC32 hdc, MENUITEM *lpitem, rect.top + SEPARATOR_HEIGHT / 2 + 1, rect.right - 1); else { - SelectObject32( hdc, sysColorObjects.hpenWindowFrame ); + SelectObject32( hdc, GetSysColorPen32(COLOR_WINDOWFRAME) ); MoveTo( hdc, rect.left, rect.top + SEPARATOR_HEIGHT/2 ); LineTo32( hdc, rect.right, rect.top + SEPARATOR_HEIGHT/2 ); } @@ -1067,7 +1066,7 @@ static void MENU_DrawPopupMenu( HWND32 hwnd, HDC32 hdc, HMENU32 hmenu ) rect.right -= POPUP_XSHADE * SYSMETRICS_CXBORDER; /* } */ - if((hPrevBrush = SelectObject32( hdc, sysColorObjects.hbrushMenu ))) + if((hPrevBrush = SelectObject32( hdc, GetSysColorBrush32(COLOR_MENU) ))) { HPEN32 hPrevPen; @@ -1141,10 +1140,10 @@ UINT32 MENU_DrawMenuBar( HDC32 hDC, LPRECT32 lprect, HWND32 hwnd, if(TWEAK_Win95Look) ++lprect->bottom; - FillRect32(hDC, lprect, sysColorObjects.hbrushMenu ); + FillRect32(hDC, lprect, GetSysColorBrush32(COLOR_MENU) ); if(!TWEAK_Win95Look) { - SelectObject32( hDC, sysColorObjects.hpenWindowFrame ); + SelectObject32( hDC, GetSysColorPen32(COLOR_WINDOWFRAME) ); MoveTo( hDC, lprect->left, lprect->bottom ); LineTo32( hDC, lprect->right, lprect->bottom ); } @@ -1229,9 +1228,6 @@ static BOOL32 MENU_ShowPopup( HWND32 hwndOwner, HMENU32 hmenu, UINT32 id, menu->FocusedItem = NO_SELECTED_ITEM; } - SendMessage16( hwndOwner, WM_INITMENUPOPUP, (WPARAM16)hmenu, - MAKELONG( id, (menu->wFlags & MF_SYSMENU) ? 1 : 0 )); - if( (wndOwner = WIN_FindWndPtr( hwndOwner )) ) { UINT32 width, height; @@ -1438,7 +1434,7 @@ static BOOL32 MENU_SetItemData( MENUITEM *item, UINT32 flags, UINT32 id, else if (flags & MF_OWNERDRAW) item->text = (LPSTR)str; else item->text = NULL; - if (item->fType & MF_POPUP && item->hSubMenu != id ) + if ((item->fType & MF_POPUP) && (flags & MF_POPUP) && (item->hSubMenu != id) ) DestroyMenu32( item->hSubMenu ); /* ModifyMenu() spec */ if (flags & MF_POPUP) @@ -1453,12 +1449,18 @@ static BOOL32 MENU_SetItemData( MENUITEM *item, UINT32 flags, UINT32 id, item->fState = 0; return FALSE; } - } + } + + item->wID = id; + if (flags & MF_POPUP) + item->hSubMenu = id; + + if ((item->fType & MF_POPUP) && !(flags & MF_POPUP) ) + flags |= MF_POPUP; /* keep popup */ item->fType = flags & TYPE_MASK; item->fState = (flags & STATE_MASK) & ~(MF_HILITE | MF_MOUSESELECT | MF_BYPOSITION); - item->wID = item->hSubMenu = id; SetRectEmpty32( &item->rect ); if (prevText) HeapFree( SystemHeap, 0, prevText ); @@ -1713,6 +1715,7 @@ static HMENU32 MENU_ShowSubPopup( HWND32 hwndOwner, HMENU32 hmenu, POPUPMENU *menu; MENUITEM *item; WND *wndPtr; + HDC32 hdc; if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu ))) return hmenu; @@ -1722,6 +1725,25 @@ static HMENU32 MENU_ShowSubPopup( HWND32 hwndOwner, HMENU32 hmenu, item = &menu->items[menu->FocusedItem]; if (!(item->fType & MF_POPUP) || (item->fState & (MF_GRAYED | MF_DISABLED))) return hmenu; + + /* message must be send before using item, + because nearly everything may by changed by the application ! */ + rect = item->rect; + SendMessage16( hwndOwner, WM_INITMENUPOPUP, (WPARAM16)item->hSubMenu, + MAKELONG( menu->FocusedItem, IS_SYSTEM_MENU(menu) )); + + /* correct item if modified as a reaction to WM_INITMENUPOPUP-message */ + if (!(item->fState & MF_HILITE)) + { + if (menu->wFlags & MF_POPUP) hdc = GetDC32( menu->hWnd ); + else hdc = GetDCEx32( menu->hWnd, 0, DCX_CACHE | DCX_WINDOW); + item->fState |= MF_HILITE; + MENU_DrawMenuItem( menu->hWnd, hdc, item, menu->Height, !(menu->wFlags & MF_POPUP) ); + ReleaseDC32( menu->hWnd, hdc ); + } + if (!item->rect.top && !item->rect.left && !item->rect.bottom && !item->rect.right) + item->rect = rect; + item->fState |= MF_MOUSESELECT; if (IS_SYSTEM_MENU(menu)) @@ -2524,6 +2546,7 @@ BOOL32 WINAPI TrackPopupMenu32( HMENU32 hMenu, UINT32 wFlags, INT32 x, INT32 y, BOOL32 ret = FALSE; HideCaret32(0); + SendMessage16( hWnd, WM_INITMENUPOPUP, (WPARAM16)hMenu, 0); if (MENU_ShowPopup( hWnd, hMenu, 0, x, y, 0, 0 )) ret = MENU_TrackMenu( hMenu, wFlags & ~TPM_INTERNAL, 0, 0, hWnd, lpRect ); ShowCaret32(0); @@ -2947,8 +2970,6 @@ UINT32 WINAPI GetMenuItemID32( HMENU32 hMenu, INT32 nPos ) if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return -1; if ((nPos < 0) || (nPos >= menu->nItems)) return -1; - /* FIXME: Now that submenus can have ids, is this still right? */ - if (menu->items[nPos].fType & MF_POPUP) return -1; return menu->items[nPos].wID; } diff --git a/controls/progress.c b/controls/progress.c index c0311e29a03..6a6e388e97a 100644 --- a/controls/progress.c +++ b/controls/progress.c @@ -12,7 +12,6 @@ #include #include #include "windows.h" -#include "syscolor.h" #include "sysmetrics.h" #include "progress.h" #include "graphics.h" diff --git a/controls/scroll.c b/controls/scroll.c index 4b7867e5428..a678d8a7b2a 100644 --- a/controls/scroll.c +++ b/controls/scroll.c @@ -10,7 +10,6 @@ #include #include #include "windows.h" -#include "syscolor.h" #include "sysmetrics.h" #include "scroll.h" #include "graphics.h" @@ -388,11 +387,11 @@ static void SCROLL_DrawInterior( HWND32 hwnd, HDC32 hdc, INT32 nBar, /* Select the correct brush and pen */ - SelectObject32( hdc, sysColorObjects.hpenWindowFrame ); + SelectObject32( hdc, GetSysColorPen32(COLOR_WINDOWFRAME) ); if ((flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH) { /* This ought to be the color of the parent window */ - SelectObject32( hdc, sysColorObjects.hbrushWindow ); + SelectObject32( hdc, GetSysColorBrush32(COLOR_WINDOW) ); } else { @@ -402,7 +401,7 @@ static void SCROLL_DrawInterior( HWND32 hwnd, HDC32 hdc, INT32 nBar, WM_CTLCOLORSCROLLBAR, hdc, hwnd ); SelectObject32( hdc, hbrush ); } - else SelectObject32( hdc, sysColorObjects.hbrushScrollbar ); + else SelectObject32( hdc, GetSysColorBrush32(COLOR_SCROLLBAR) ); } /* Calculate the scroll rectangle */ @@ -463,7 +462,7 @@ static void SCROLL_DrawInterior( HWND32 hwnd, HDC32 hdc, INT32 nBar, /* Draw the thumb */ - SelectObject32( hdc, sysColorObjects.hbrushBtnFace ); + SelectObject32( hdc, GetSysColorBrush32(COLOR_BTNFACE) ); Rectangle32( hdc, r.left, r.top, r.right, r.bottom ); InflateRect32( &r, -1, -1 ); GRAPH_DrawReliefRect( hdc, &r, 1, 2, FALSE ); @@ -903,7 +902,7 @@ INT16 WINAPI SetScrollInfo16( HWND16 hwnd, INT16 nBar, const SCROLLINFO *info, /************************************************************************* - * SetScrollInfo32 (USER32.500) + * SetScrollInfo32 (USER32.501) */ INT32 WINAPI SetScrollInfo32( HWND32 hwnd, INT32 nBar, const SCROLLINFO *info, BOOL32 bRedraw ) @@ -1051,7 +1050,7 @@ INT16 WINAPI SetScrollPos16( HWND16 hwnd, INT16 nBar, INT16 nPos, /************************************************************************* - * SetScrollPos32 (USER32.501) + * SetScrollPos32 (USER32.502) */ INT32 WINAPI SetScrollPos32( HWND32 hwnd, INT32 nBar, INT32 nPos, BOOL32 bRedraw ) @@ -1104,7 +1103,7 @@ void WINAPI SetScrollRange16( HWND16 hwnd, INT16 nBar, /************************************************************************* - * SetScrollRange32 (USER32.502) + * SetScrollRange32 (USER32.503) */ BOOL32 WINAPI SetScrollRange32( HWND32 hwnd, INT32 nBar, INT32 MinVal, INT32 MaxVal, BOOL32 bRedraw ) diff --git a/controls/uitools.c b/controls/uitools.c index e3c64de36e9..15779a129bc 100644 --- a/controls/uitools.c +++ b/controls/uitools.c @@ -166,8 +166,8 @@ static BOOL32 UITOOLS_DrawDiagEdge(HDC32 hdc, LPRECT32 rc, UINT32 uType, UINT32 } } - if(InnerI != -1) InnerPen = CreatePen32(PS_SOLID, 0, GetSysColor32((int)InnerI)); - if(OuterI != -1) OuterPen = CreatePen32(PS_SOLID, 0, GetSysColor32((int)OuterI)); + if(InnerI != -1) InnerPen = GetSysColorPen32(InnerI); + if(OuterI != -1) OuterPen = GetSysColorPen32(OuterI); MoveToEx32(hdc, 0, 0, &SavePoint); @@ -315,17 +315,16 @@ static BOOL32 UITOOLS_DrawDiagEdge(HDC32 hdc, LPRECT32 rc, UINT32 uType, UINT32 if((uFlags & BF_MIDDLE) && retval) { HBRUSH32 hbsave; - HBRUSH32 hb = uFlags & BF_MONO ? GetSysColorBrush32(COLOR_WINDOW) - : GetSysColorBrush32(COLOR_BTNFACE); + HBRUSH32 hb = GetSysColorBrush32(uFlags & BF_MONO ? COLOR_WINDOW + :COLOR_BTNFACE); HPEN32 hpsave; - HPEN32 hp = CreatePen32(PS_SOLID, 0, uFlags & BF_MONO ? GetSysColor32(COLOR_WINDOW) - : GetSysColor32(COLOR_BTNFACE)); + HPEN32 hp = GetSysColorPen32(uFlags & BF_MONO ? COLOR_WINDOW + : COLOR_BTNFACE); hbsave = (HBRUSH32)SelectObject32(hdc, hb); hpsave = (HPEN32)SelectObject32(hdc, hp); Polygon32(hdc, Points, 4); SelectObject32(hdc, hbsave); SelectObject32(hdc, hpsave); - DeleteObject32(hp); } /* Adjust rectangle if asked */ @@ -339,8 +338,6 @@ static BOOL32 UITOOLS_DrawDiagEdge(HDC32 hdc, LPRECT32 rc, UINT32 uType, UINT32 /* Cleanup */ SelectObject32(hdc, SavePen); - if(InnerI != -1) DeleteObject32(InnerPen); - if(OuterI != -1) DeleteObject32(OuterPen); MoveToEx32(hdc, SavePoint.x, SavePoint.y, NULL); return retval; @@ -479,15 +476,15 @@ static BOOL32 UITOOLS_DrawRectEdge(HDC32 hdc, LPRECT32 rc, UINT32 uType, UINT32 if((uFlags & BF_BOTTOMRIGHT) == BF_BOTTOMRIGHT) RBpenplus = 1; if((uFlags & BF_TOPLEFT) == BF_TOPLEFT) LTpenplus = 1; - if(LTInnerI != -1) LTInnerPen = CreatePen32(PS_SOLID, 0, GetSysColor32((int)LTInnerI)); - if(LTOuterI != -1) LTOuterPen = CreatePen32(PS_SOLID, 0, GetSysColor32((int)LTOuterI)); - if(RBInnerI != -1) RBInnerPen = CreatePen32(PS_SOLID, 0, GetSysColor32((int)RBInnerI)); - if(RBOuterI != -1) RBOuterPen = CreatePen32(PS_SOLID, 0, GetSysColor32((int)RBOuterI)); + if(LTInnerI != -1) LTInnerPen = GetSysColorPen32(LTInnerI); + if(LTOuterI != -1) LTOuterPen = GetSysColorPen32(LTOuterI); + if(RBInnerI != -1) RBInnerPen = GetSysColorPen32(RBInnerI); + if(RBOuterI != -1) RBOuterPen = GetSysColorPen32(RBOuterI); if((uFlags & BF_MIDDLE) && retval) { - FillRect32(hdc, &InnerRect, (uFlags & BF_MONO) ? GetSysColorBrush32(COLOR_WINDOW) - : GetSysColorBrush32(COLOR_BTNFACE)); + FillRect32(hdc, &InnerRect, GetSysColorBrush32(uFlags & BF_MONO ? + COLOR_WINDOW : COLOR_BTNFACE)); } MoveToEx32(hdc, 0, 0, &SavePoint); @@ -553,10 +550,6 @@ static BOOL32 UITOOLS_DrawRectEdge(HDC32 hdc, LPRECT32 rc, UINT32 uType, UINT32 /* Cleanup */ SelectObject32(hdc, SavePen); - if(LTInnerI != -1) DeleteObject32(LTInnerPen); - if(LTOuterI != -1) DeleteObject32(LTOuterPen); - if(RBInnerI != -1) DeleteObject32(RBInnerPen); - if(RBOuterI != -1) DeleteObject32(RBOuterPen); MoveToEx32(hdc, SavePoint.x, SavePoint.y, NULL); return retval; } @@ -771,7 +764,7 @@ static BOOL32 UITOOLS_DFC_ButtonCheck(HDC32 dc, LPRECT32 r, UINT32 uFlags) POINT32 CheckPoints[DFC_CHECKPOINTSMAX]; int i; HBRUSH32 hbsave; - HPEN32 hp, hpsave; + HPEN32 hpsave; /* FIXME: This comes very close to M$'s checkmark, but not */ /* exactly... When small or large there is a few pixels */ @@ -792,12 +785,10 @@ static BOOL32 UITOOLS_DFC_ButtonCheck(HDC32 dc, LPRECT32 r, UINT32 uFlags) i = (uFlags & DFCS_INACTIVE) || (uFlags & 0xff) == DFCS_BUTTON3STATE ? COLOR_BTNSHADOW : COLOR_WINDOWTEXT; hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(i)); - hp = CreatePen32(PS_SOLID, 0, GetSysColor32(i)); - hpsave = (HPEN32)SelectObject32(dc, hp); + hpsave = (HPEN32)SelectObject32(dc, GetSysColorPen32(i)); Polygon32(dc, CheckPoints, DFC_CHECKPOINTSMAX); SelectObject32(dc, hpsave); SelectObject32(dc, hbsave); - DeleteObject32(hp); } return TRUE; } @@ -818,7 +809,7 @@ static BOOL32 UITOOLS_DFC_ButtonRadio(HDC32 dc, LPRECT32 r, UINT32 uFlags) int i; int SmallDiam = UITOOLS_MakeSquareRect(r, &myr); int BorderShrink = SmallDiam / 16; - HPEN32 hpsave, hp; + HPEN32 hpsave; HBRUSH32 hbsave; int xe, ye; int xc, yc; @@ -853,52 +844,36 @@ static BOOL32 UITOOLS_DFC_ButtonRadio(HDC32 dc, LPRECT32 r, UINT32 uFlags) { if(uFlags & (DFCS_FLAT|DFCS_MONO)) { - hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_WINDOWFRAME)); - hpsave = (HPEN32)SelectObject32(dc, hp); + hpsave = (HPEN32)SelectObject32(dc, GetSysColorPen32(COLOR_WINDOWFRAME)); hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_WINDOWFRAME)); Pie32(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye); SelectObject32(dc, hbsave); SelectObject32(dc, hpsave); - DeleteObject32(hp); } else { - hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNHIGHLIGHT)); - hpsave = (HPEN32)SelectObject32(dc, hp); + hpsave = (HPEN32)SelectObject32(dc, GetSysColorPen32(COLOR_BTNHIGHLIGHT)); hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_BTNHIGHLIGHT)); Pie32(dc, myr.left, myr.top, myr.right, myr.bottom, myr.left-1, myr.bottom, myr.right-1, myr.top); - SelectObject32(dc, hbsave); - SelectObject32(dc, hpsave); - DeleteObject32(hp); - hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNSHADOW)); - hpsave = (HPEN32)SelectObject32(dc, hp); - hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_BTNSHADOW)); + SelectObject32(dc, GetSysColorPen32(COLOR_BTNSHADOW)); + SelectObject32(dc, GetSysColorBrush32(COLOR_BTNSHADOW)); Pie32(dc, myr.left, myr.top, myr.right, myr.bottom, myr.right+1, myr.top, myr.left+1, myr.bottom); - SelectObject32(dc, hbsave); - SelectObject32(dc, hpsave); - DeleteObject32(hp); myr.left += BorderShrink; myr.right -= BorderShrink; myr.top += BorderShrink; myr.bottom -= BorderShrink; - hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_3DLIGHT)); - hpsave = (HPEN32)SelectObject32(dc, hp); - hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_3DLIGHT)); + SelectObject32(dc, GetSysColorPen32(COLOR_3DLIGHT)); + SelectObject32(dc, GetSysColorBrush32(COLOR_3DLIGHT)); Pie32(dc, myr.left, myr.top, myr.right, myr.bottom, myr.left-1, myr.bottom, myr.right-1, myr.top); - SelectObject32(dc, hbsave); - SelectObject32(dc, hpsave); - DeleteObject32(hp); - hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_3DDKSHADOW)); - hpsave = (HPEN32)SelectObject32(dc, hp); - hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_3DDKSHADOW)); + SelectObject32(dc, GetSysColorPen32(COLOR_3DDKSHADOW)); + SelectObject32(dc, GetSysColorBrush32(COLOR_3DDKSHADOW)); Pie32(dc, myr.left, myr.top, myr.right, myr.bottom, myr.right+1, myr.top, myr.left+1, myr.bottom); SelectObject32(dc, hbsave); SelectObject32(dc, hpsave); - DeleteObject32(hp); } i = 10*SmallDiam/16; @@ -907,13 +882,11 @@ static BOOL32 UITOOLS_DFC_ButtonRadio(HDC32 dc, LPRECT32 r, UINT32 uFlags) myr.top = yc - i+i/2; myr.bottom = yc + i/2; i= !(uFlags & (DFCS_INACTIVE|DFCS_PUSHED)) ? COLOR_WINDOW : COLOR_BTNFACE; - hp = CreatePen32(PS_SOLID, 0, GetSysColor32(i)); - hpsave = (HPEN32)SelectObject32(dc, hp); + hpsave = (HPEN32)SelectObject32(dc, GetSysColorPen32(i)); hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(i)); Pie32(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye); SelectObject32(dc, hbsave); SelectObject32(dc, hpsave); - DeleteObject32(hp); } if(uFlags & DFCS_CHECKED) @@ -927,12 +900,10 @@ static BOOL32 UITOOLS_DFC_ButtonRadio(HDC32 dc, LPRECT32 r, UINT32 uFlags) i = uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_WINDOWTEXT; hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(i)); - hp = CreatePen32(PS_SOLID, 0, GetSysColor32(i)); - hpsave = (HPEN32)SelectObject32(dc, hp); + hpsave = (HPEN32)SelectObject32(dc, GetSysColorPen32(i)); Pie32(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye); SelectObject32(dc, hpsave); SelectObject32(dc, hbsave); - DeleteObject32(hp); } /* FIXME: M$ has a polygon in the center at relative points: */ @@ -992,7 +963,7 @@ static BOOL32 UITOOLS_DrawFrameCaption(HDC32 dc, LPRECT32 r, UINT32 uFlags) int SmallDiam = UITOOLS_MakeSquareRect(r, &myr)-2; int i; HBRUSH32 hbsave; - HPEN32 hpsave, hp; + HPEN32 hpsave; HFONT32 hfsave, hf; int xc = (myr.left+myr.right)/2; int yc = (myr.top+myr.bottom)/2; @@ -1115,14 +1086,12 @@ static BOOL32 UITOOLS_DrawFrameCaption(HDC32 dc, LPRECT32 r, UINT32 uFlags) { /* If we have an inactive button, then you see a shadow */ hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_BTNHIGHLIGHT)); - hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNHIGHLIGHT)); - hpsave = (HPEN32)SelectObject32(dc, hp); + hpsave = (HPEN32)SelectObject32(dc, GetSysColorPen32(COLOR_BTNHIGHLIGHT)); Polygon32(dc, Line1, Line1N); if(Line2N > 0) Polygon32(dc, Line2, Line2N); SelectObject32(dc, hpsave); SelectObject32(dc, hbsave); - DeleteObject32(hp); } /* Correct for the shadow shift */ @@ -1138,23 +1107,15 @@ static BOOL32 UITOOLS_DrawFrameCaption(HDC32 dc, LPRECT32 r, UINT32 uFlags) } /* Make the final picture */ - if(uFlags & DFCS_INACTIVE) - { - hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_BTNSHADOW)); - hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNSHADOW)); - } - else - { - hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_BTNTEXT)); - hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNTEXT)); - } - hpsave = (HPEN32)SelectObject32(dc, hp); + i = uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_BTNTEXT; + hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(i)); + hpsave = (HPEN32)SelectObject32(dc, GetSysColorPen32(i)); + Polygon32(dc, Line1, Line1N); if(Line2N > 0) Polygon32(dc, Line2, Line2N); SelectObject32(dc, hpsave); SelectObject32(dc, hbsave); - DeleteObject32(hp); return TRUE; } @@ -1218,13 +1179,13 @@ static BOOL32 UITOOLS_DrawFrameScroll(HDC32 dc, LPRECT32 r, UINT32 uFlags) hbsave = (HBRUSH32)SelectObject32(dc, GetStockObject32(NULL_BRUSH)); if(uFlags & (DFCS_MONO|DFCS_FLAT)) { - hp = hp2 = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_WINDOWFRAME)); + hp = hp2 = GetSysColorPen32(COLOR_WINDOWFRAME); hb = hb2 = GetSysColorBrush32(COLOR_WINDOWFRAME); } else { - hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNHIGHLIGHT)); - hp2 = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNSHADOW)); + hp = GetSysColorPen32(COLOR_BTNHIGHLIGHT); + hp2 = GetSysColorPen32(COLOR_BTNSHADOW); hb = GetSysColorBrush32(COLOR_BTNHIGHLIGHT); hb2 = GetSysColorBrush32(COLOR_BTNSHADOW); } @@ -1283,8 +1244,6 @@ static BOOL32 UITOOLS_DrawFrameScroll(HDC32 dc, LPRECT32 r, UINT32 uFlags) SelectObject32(dc, hpsave); SelectObject32(dc, hbsave); - DeleteObject32(hp); - DeleteObject32(hp2); return TRUE; default: @@ -1298,12 +1257,10 @@ static BOOL32 UITOOLS_DrawFrameScroll(HDC32 dc, LPRECT32 r, UINT32 uFlags) if(uFlags & DFCS_INACTIVE) { hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_BTNHIGHLIGHT)); - hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNHIGHLIGHT)); - hpsave = (HPEN32)SelectObject32(dc, hp); + hpsave = (HPEN32)SelectObject32(dc, GetSysColorPen32(COLOR_BTNHIGHLIGHT)); Polygon32(dc, Line, 3); SelectObject32(dc, hpsave); SelectObject32(dc, hbsave); - DeleteObject32(hp); } for(i = 0; i < 3; i++) @@ -1312,21 +1269,12 @@ static BOOL32 UITOOLS_DrawFrameScroll(HDC32 dc, LPRECT32 r, UINT32 uFlags) Line[i].y--; } - if(uFlags & DFCS_INACTIVE) - { - hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_BTNSHADOW)); - hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNSHADOW)); - } - else - { - hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_BTNTEXT)); - hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNTEXT)); - } - hpsave = (HPEN32)SelectObject32(dc, hp); + i = uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_BTNTEXT; + hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(i)); + hpsave = (HPEN32)SelectObject32(dc, GetSysColorPen32(i)); Polygon32(dc, Line, 3); SelectObject32(dc, hpsave); SelectObject32(dc, hbsave); - DeleteObject32(hp); return TRUE; } diff --git a/controls/updown.c b/controls/updown.c index bf81fdbd675..c0a2848371d 100644 --- a/controls/updown.c +++ b/controls/updown.c @@ -30,7 +30,6 @@ #include #include "windows.h" #include "winnls.h" -#include "syscolor.h" #include "sysmetrics.h" #include "updown.h" #include "graphics.h" @@ -269,77 +268,6 @@ static BOOL32 UPDOWN_SetBuddyInt(WND *wndPtr) } /*********************************************************************** - * UPDOWN_DrawArraw - * Draw the arrows for the up-down control. The arrows are drawn with the - * current pen and filled with the current brush. - * Input: - * hdc - the DC to draw on - * rect - rectangle holding the arrow - * incr - TRUE if we draw the "increment" arrow - * FALSE if we draw the "decrement" arrow - * pressed - TRUE if the arrow is pressed (clicked) - * FALSE if the arrow is not pressed (clicked) - * horz - TRUE if the arrow is horizontal - * FLASE if the arrow is vertical - */ -static void UPDOWN_DrawArrow(HDC32 hdc, RECT32 *rect, BOOL32 incr, - BOOL32 pressed, BOOL32 horz) -{ - const int rw = rect->right - rect->left; - const int rh = rect->bottom - rect->top; - int offset = pressed ? 1 : 0; - int th, x, y, len; - - /* compute max extents of the triangle */ - if(horz){ /* horizontal arrows */ - th = (3*rh)/5-2*4; - if(th > rw/2) - th = rw/2; - if(th < 2) - th = 2; - - /* compute the position of the tip */ - y = (rect->top+rect->bottom+1)/2 + offset; - if(incr) - x = (rect->left+rect->right+1)/2 + (2*th)/3 + offset; - else - x = (rect->left+rect->right)/2 + th/3 + offset; - - for(len=1; th>0; th--, len+=2){ - MoveToEx32(hdc, x, y, 0); - LineTo32(hdc, x, y+len); - if(incr) x--; - else x++; - y++; - } - } - else{ /* vertical arrows */ - th = (3*rw)/5-2*4; - if(th > rh/2) - th = rh/2; - if(th < 2) - th = 2; - - /* compute the position of the tip */ - x = (rect->left+rect->right+1)/2 + offset; - if(incr) - y = (rect->top+rect->bottom+1)/2 - th/3 + offset; - else - y = (rect->top+rect->bottom)/2 + (2*th)/3 + offset; - - for(len=1; th>0; th--, len+=2){ - MoveToEx32(hdc, x, y, 0); - LineTo32(hdc, x+len, y); - if(incr) y++; - else y--; - x--; - } - - } - -} - -/*********************************************************************** * UPDOWN_Paint * Draw the arrows. The background need not be erased. */ @@ -350,19 +278,17 @@ static void UPDOWN_Paint(WND *wndPtr) BOOL32 prssed; RECT32 rect; HDC32 hdc; - HBRUSH32 oldBrush; - + + /* start painting the button */ hdc = BeginPaint32( wndPtr->hwndSelf, &ps ); - /* First select the proper brush */ - oldBrush = wndPtr->dwStyle & WS_DISABLED ? GRAY_BRUSH : BLACK_BRUSH; - oldBrush = SelectObject32(hdc, GetStockObject32(oldBrush)); - /* Draw the incr button */ UPDOWN_GetArrowRect(wndPtr, &rect, TRUE); prssed = (infoPtr->Flags & FLAG_INCR) && (infoPtr->Flags & FLAG_MOUSEIN); - DrawEdge32(hdc, &rect, prssed?EDGE_SUNKEN:EDGE_RAISED, BF_RECT|BF_MIDDLE); - UPDOWN_DrawArrow(hdc, &rect, TRUE, prssed, wndPtr->dwStyle & UDS_HORZ); + DrawFrameControl32(hdc, &rect, DFC_SCROLL, + (wndPtr->dwStyle & UDS_HORZ ? DFCS_SCROLLLEFT : DFCS_SCROLLUP) | + (prssed ? DFCS_PUSHED : 0) | + (wndPtr->dwStyle&WS_DISABLED ? DFCS_INACTIVE : 0) ); /* Draw the space between the buttons */ rect.top = rect.bottom; rect.bottom++; @@ -371,12 +297,13 @@ static void UPDOWN_Paint(WND *wndPtr) /* Draw the decr button */ UPDOWN_GetArrowRect(wndPtr, &rect, FALSE); prssed = (infoPtr->Flags & FLAG_DECR) && (infoPtr->Flags & FLAG_MOUSEIN); - DrawEdge32(hdc, &rect, prssed ? EDGE_SUNKEN : EDGE_RAISED, - BF_RECT | BF_SOFT | BF_MIDDLE); - UPDOWN_DrawArrow(hdc, &rect, FALSE, prssed, wndPtr->dwStyle & UDS_HORZ); + DrawFrameControl32(hdc, &rect, DFC_SCROLL, + (wndPtr->dwStyle & UDS_HORZ ? DFCS_SCROLLRIGHT : DFCS_SCROLLDOWN) | + (prssed ? DFCS_PUSHED : 0) | + (wndPtr->dwStyle&WS_DISABLED ? DFCS_INACTIVE : 0) ); + /* clean-up */ - SelectObject32(hdc, oldBrush); EndPaint32( wndPtr->hwndSelf, &ps ); } diff --git a/debugger/db_disasm.c b/debugger/db_disasm.c index 715ddbe6df0..bd8e11facbd 100644 --- a/debugger/db_disasm.c +++ b/debugger/db_disasm.c @@ -265,7 +265,7 @@ static const struct inst db_inst_0f9x[] = { static const struct inst db_inst_0fax[] = { /*a0*/ { "push", FALSE, NONE, op1(Si), 0 }, /*a1*/ { "pop", FALSE, NONE, op1(Si), 0 }, -/*a2*/ { "", FALSE, NONE, 0, 0 }, +/*a2*/ { "cpuid", FALSE, NONE, 0, 0 }, /*a3*/ { "bt", TRUE, LONG, op2(E,R), 0 }, /*a4*/ { "shld", TRUE, LONG, op3(Ib,E,R), 0 }, /*a5*/ { "shld", TRUE, LONG, op3(CL,E,R), 0 }, @@ -283,8 +283,8 @@ static const struct inst db_inst_0fax[] = { }; static const struct inst db_inst_0fbx[] = { -/*b0*/ { "", FALSE, NONE, 0, 0 }, -/*b1*/ { "", FALSE, NONE, 0, 0 }, +/*b0*/ { "cmpxchg",TRUE, BYTE, op2(E, R), 0 }, +/*b1*/ { "cmpxchg",TRUE, LONG, op2(E, R), 0 }, /*b2*/ { "lss", TRUE, LONG, op2(E, R), 0 }, /*b3*/ { "bts", TRUE, LONG, op2(R, E), 0 }, /*b4*/ { "lfs", TRUE, LONG, op2(E, R), 0 }, diff --git a/documentation/languages b/documentation/languages index ef4aa6d80c7..d354f2e0a40 100644 --- a/documentation/languages +++ b/documentation/languages @@ -24,7 +24,7 @@ you must... 3. Edit include/options.h enum "WINE_LANGUAGE" to have a member called LANG_XX where XX is the new abbreviation. -4. Edit misc/ole2nls.c function "GetUserDefaultLCID" to contain a +4. Edit ole/ole2nls.c function "GetUserDefaultLCID" to contain a case for your language by uncommenting the return value of it. 5. Edit resources/sysrec.c to include "sysres_XX.h" where XX is the @@ -47,7 +47,7 @@ you must... 7. Edit resources/Makefile.in to add the name of the new file to the SYSRES_SRCS variable. -8. Edit misc/ole2nls.c function "GetLocaleInfoA" to contain a case for +8. Edit ole/ole2nls.c function "GetLocaleInfoA" to contain a case for your language. 9. Re-configure, re-make dependencies, and re-make Wine. diff --git a/files/drive.c b/files/drive.c index 0fd582d096e..d5a8a86648e 100644 --- a/files/drive.c +++ b/files/drive.c @@ -623,9 +623,16 @@ BOOL32 WINAPI GetDiskFreeSpace32A( LPCSTR root, LPDWORD cluster_sectors, if (size > 0x7fffffff) size = 0x7fffffff; if (available > 0x7fffffff) available = 0x7fffffff; - *sector_bytes = 512; - size /= 512; - available /= 512; + if (DRIVE_GetType(drive)==TYPE_CDROM) { + *sector_bytes = 2048; + size /= 2048; + available /= 2048; + } else { + *sector_bytes = 512; + size /= 512; + available /= 512; + } + /* fixme: probably have to adjust those variables too for CDFS */ *cluster_sectors = 1; while (*cluster_sectors * 65530 < size) *cluster_sectors *= 2; *free_clusters = available/ *cluster_sectors; @@ -921,7 +928,7 @@ BOOL32 WINAPI GetVolumeInformation32A( LPCSTR root, LPSTR label, if (!root) drive = DRIVE_GetCurrentDrive(); else { - if ((root[1]) &&((root[1] != ':') || (root[2] != '\\'))) + if ((root[1]) && (root[1] != ':')) { fprintf( stderr, "GetVolumeInformation: invalid root '%s'\n",root); return FALSE; @@ -937,7 +944,13 @@ BOOL32 WINAPI GetVolumeInformation32A( LPCSTR root, LPSTR label, if (filename_len) *filename_len = 12; if (flags) *flags = 0; - if (fsname) lstrcpyn32A( fsname, "FAT16", fsname_len ); + if (fsname) { + /* Diablo checks that return code ... */ + if (DRIVE_GetType(drive)==TYPE_CDROM) + lstrcpyn32A( fsname, "CDFS", fsname_len ); + else + lstrcpyn32A( fsname, "FAT16", fsname_len ); + } return TRUE; } diff --git a/files/file.c b/files/file.c index 10380e81ee2..3eaaf8dceb8 100644 --- a/files/file.c +++ b/files/file.c @@ -38,6 +38,18 @@ #define MAP_ANON MAP_ANONYMOUS #endif +static void FILE_Destroy( K32OBJ *obj ); + +const K32OBJ_OPS FILE_Ops = +{ + /* Object cannot be waited upon (FIXME: for now) */ + NULL, /* signaled */ + NULL, /* satisfied */ + NULL, /* add_wait */ + NULL, /* remove_wait */ + FILE_Destroy /* destroy */ +}; + struct DOS_FILE_LOCK { struct DOS_FILE_LOCK * next; DWORD base; @@ -73,6 +85,7 @@ static HFILE32 FILE_Alloc( FILE_OBJECT **file ) (*file)->type = FILE_TYPE_DISK; handle = PROCESS_AllocHandle( &(*file)->header, 0 ); + /* If the allocation failed, the object is already destroyed */ if (handle == INVALID_HANDLE_VALUE32) *file = NULL; return handle; } @@ -83,7 +96,7 @@ static HFILE32 FILE_Alloc( FILE_OBJECT **file ) * * Destroy a DOS file. */ -void FILE_Destroy( K32OBJ *ptr ) +static void FILE_Destroy( K32OBJ *ptr ) { FILE_OBJECT *file = (FILE_OBJECT *)ptr; assert( ptr->type == K32OBJ_FILE ); @@ -542,17 +555,12 @@ UINT16 WINAPI GetTempFileName16( BYTE drive, LPCSTR prefix, UINT16 unique, } if (drive & TF_FORCEDRIVE) - { - sprintf( temppath, "%c:\\", drive & ~TF_FORCEDRIVE ); - lstrcpyn32A( temppath + 3, - DRIVE_GetDosCwd( toupper(drive & ~TF_FORCEDRIVE) - 'A'), - 129 ); - } + sprintf(temppath,"%c:", drive & ~TF_FORCEDRIVE ); else { GetTempPath32A( 132, temppath ); + strcat( temppath, "\\" ); } - strcat( temppath, "\\" ); return (UINT16)GetTempFileName32A( temppath, prefix, unique, buffer ); } @@ -572,8 +580,11 @@ UINT32 WINAPI GetTempFileName32A( LPCSTR path, LPCSTR prefix, UINT32 unique, strcpy( buffer, path ); p = buffer + strlen(buffer); - /* add a \, if there isn't one ... */ - if ((p == buffer) || (p[-1] != '\\')) *p++ = '\\'; + + /* add a \, if there isn't one and path is more than just the drive letter ... */ + if ( !((strlen(buffer) == 2) && (buffer[1] == ':')) + && ((p == buffer) || (p[-1] != '\\'))) *p++ = '\\'; + *p++ = '~'; for (i = 3; (i > 0) && (*prefix); i--) *p++ = *prefix++; sprintf( p, "%04x.tmp", num ); diff --git a/graphics/Makefile.in b/graphics/Makefile.in index 3784c524e30..5481fa5f196 100644 --- a/graphics/Makefile.in +++ b/graphics/Makefile.in @@ -8,6 +8,7 @@ MODULE = graphics C_SRCS = \ bitblt.c \ cache.c \ + ddraw.c \ driver.c \ env.c \ escape.c \ diff --git a/graphics/ddraw.c b/graphics/ddraw.c new file mode 100644 index 00000000000..72486902bb6 --- /dev/null +++ b/graphics/ddraw.c @@ -0,0 +1,904 @@ +/* DirectDraw + * + * Copyright 1997 Marcus Meissner + */ + +#include "config.h" +#include +#include +#include +#include + +#include "windows.h" +#include "winerror.h" +#include "interfaces.h" +#include "gdi.h" +#include "heap.h" +#include "ldt.h" +#include "dc.h" +#include "win.h" +#include "debug.h" +#include "stddebug.h" +#include "miscemu.h" +#include "mmsystem.h" +#include "ddraw.h" + +#ifdef HAVE_LIBXXF86DGA +#include +#endif + +static HRESULT WINAPI IDirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE,REFIID,LPVOID*); +static HRESULT WINAPI IDirectDraw_QueryInterface(LPDIRECTDRAW this,REFIID refiid,LPVOID *obj); +static HRESULT WINAPI IDirectDraw2_CreateSurface( LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk); +static HRESULT WINAPI IDirectDraw_CreateSurface( LPDIRECTDRAW this,LPDDSURFACEDESC *lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk); +static struct IDirectDrawSurface2_VTable dds2vt; +static struct IDirectDrawSurface_VTable ddsvt; + + +HRESULT WINAPI +DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) { + fprintf(stderr,"DirectDrawEnumerateA(%p,%p).\n",ddenumproc,data); + ddenumproc(0,"WINE Display","display",data); + ddenumproc(&IID_IDirectDraw,"WINE DirectDraw","directdraw",data); + ddenumproc(&IID_IDirectDrawPalette,"WINE DirectPalette","directpalette",data); + return 0; +} + +HRESULT WINAPI +DSoundHelp(DWORD x,DWORD y,DWORD z) { + fprintf(stderr,"DSoundHelp(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z); + return 0; +} + +#ifdef HAVE_LIBXXF86DGA + +static int _getpixelformat(LPDIRECTDRAW ddraw,LPDDPIXELFORMAT pf) { + pf->dwFourCC = mmioFOURCC('R','G','B',' '); + if (ddraw->d.depth==8) { + pf->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXEDTO8; + pf->x.dwRGBBitCount = 8; + pf->y.dwRBitMask = 0; + pf->z.dwGBitMask = 0; + pf->xx.dwBBitMask = 0; + return 0; + } + if (ddraw->d.depth==16) { + pf->dwFlags = DDPF_RGB; + pf->x.dwRGBBitCount = 16; + pf->y.dwRBitMask = 0x0000f800; + pf->z.dwGBitMask = 0x000007e0; + pf->xx.dwBBitMask = 0x0000001f; + return 0; + } + fprintf(stderr,"_getpixelformat:oops?\n"); + return DDERR_GENERIC; +} + + +static HRESULT WINAPI IDirectDrawSurface_Lock( + LPDIRECTDRAWSURFACE this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd +) { + dprintf_relay(stddeb,"IDirectDrawSurface(%p)->Lock(%p,%p,%08lx,%08lx)\n", + this,lprect,lpddsd,flags,(DWORD)hnd + ); + fprintf(stderr,"."); + if (lprect) { + /* + fprintf(stderr," lprect: %dx%d-%dx%d\n", + lprect->top,lprect->left,lprect->bottom,lprect->right + ); + */ + lpddsd->lpSurface = this->surface+ + (lprect->top*this->lpitch)+ + (lprect->left*(this->ddraw->d.depth/8)); + } else + lpddsd->lpSurface = this->surface; + lpddsd->dwWidth = this->width; + lpddsd->dwHeight = this->height; + lpddsd->lPitch = this->lpitch; + _getpixelformat(this->ddraw,&(lpddsd->ddpfPixelFormat)); + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface2_Lock( + LPDIRECTDRAWSURFACE2 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd +) { + dprintf_relay(stddeb,"IDirectDrawSurface2(%p)->Lock(%p,%p,%08lx,%08lx)\n", + this,lprect,lpddsd,flags,(DWORD)hnd + ); + fprintf(stderr,"."); + if (lprect) { + /* + fprintf(stderr," lprect: %dx%d-%dx%d\n", + lprect->top,lprect->left,lprect->bottom,lprect->right + ); + */ + lpddsd->lpSurface = this->surface+ + (lprect->top*this->lpitch)+ + (lprect->left*(this->ddraw->d.depth/8)); + } else + lpddsd->lpSurface = this->surface; + lpddsd->dwWidth = this->width; + lpddsd->dwHeight = this->height; + lpddsd->lPitch = this->lpitch; + _getpixelformat(this->ddraw,&(lpddsd->ddpfPixelFormat)); + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface_Unlock( + LPDIRECTDRAWSURFACE this,LPVOID surface +) { + dprintf_relay(stddeb,"IDirectDrawSurface(%p)->Unlock(%p)\n",this,surface); + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface_Flip( + LPDIRECTDRAWSURFACE this,LPDIRECTDRAWSURFACE flipto,DWORD dwFlags +) { + fprintf(stderr,"IDirectDrawSurface(%p)->Flip(%p,%08lx),STUB\n",this,flipto,dwFlags); + if (flipto) { + XF86DGASetViewPort(display,DefaultScreen(display),0,flipto->fb_height); + } else { + /* FIXME: flip through attached surfaces */ + XF86DGASetViewPort(display,DefaultScreen(display),0,this->fb_height); + } + while (!XF86DGAViewPortChanged(display,DefaultScreen(display),1)) { + } + fprintf(stderr,"flipped to new height %ld\n",flipto->fb_height); + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface2_Unlock( + LPDIRECTDRAWSURFACE2 this,LPVOID surface +) { + dprintf_relay(stddeb,"IDirectDrawSurface2(%p)->Unlock(%p)\n",this,surface); + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface_SetPalette( + LPDIRECTDRAWSURFACE this,LPDIRECTDRAWPALETTE pal +) { + fprintf(stderr,"IDirectDrawSurface(%p)->SetPalette(%p)\n",this,pal); + this->palette = pal; + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface2_SetPalette( + LPDIRECTDRAWSURFACE2 this,LPDIRECTDRAWPALETTE pal +) { + fprintf(stderr,"IDirectDrawSurface2(%p)->SetPalette(%p)\n",this,pal); + this->palette = pal; + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface_Blt( + LPDIRECTDRAWSURFACE this,LPRECT32 rdst,LPDIRECTDRAWSURFACE src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx +) { + fprintf(stderr,"IDirectDrawSurface(%p)->Blt(%p,%p,%p,%08lx,%p),stub!\n", + this,rdst,src,rsrc,dwFlags,lpbltfx + ); + if (rdst) fprintf(stderr," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom); + if (rsrc) fprintf(stderr," srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom); + fprintf(stderr," blitfx: 0x%08lx\n",lpbltfx->dwDDFX); + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface_BltFast( + LPDIRECTDRAWSURFACE this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE src,LPRECT32 rsrc,DWORD trans +) { + int i,bpp; + fprintf(stderr,"IDirectDrawSurface(%p)->BltFast(%ld,%ld,%p,%p,%08lx),stub!\n", + this,dstx,dsty,src,rsrc,trans + ); + fprintf(stderr," srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom); + bpp = this->ddraw->d.depth/8; + for (i=0;ibottom-rsrc->top;i++) { + memcpy( this->surface+((i+dsty)*this->width*bpp)+dstx*bpp, + src->surface +(rsrc->top+i)*src->width*bpp+rsrc->left*bpp, + (rsrc->right-rsrc->left)*bpp + ); + } + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface_BltBatch( + LPDIRECTDRAWSURFACE this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y +) { + fprintf(stderr,"IDirectDrawSurface(%p)->BltBatch(%p,%08lx,%08lx),stub!\n", + this,ddbltbatch,x,y + ); + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface_GetCaps( + LPDIRECTDRAWSURFACE this,LPDDSCAPS caps +) { + fprintf(stderr,"IDirectDrawSurface(%p)->GetCaps(%p),stub!\n",this,caps); + caps->dwCaps = 0; /* we cannot do anything */ + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface_GetSurfaceDesc( + LPDIRECTDRAWSURFACE this,LPDDSURFACEDESC ddsd +) { + fprintf(stderr,"IDirectDrawSurface(%p)->GetSurfaceDesc(%p)\n",this,ddsd); + if (ddsd->dwFlags & DDSD_CAPS) + ddsd->ddsCaps.dwCaps = 0; + if (ddsd->dwFlags & DDSD_BACKBUFFERCOUNT) + ddsd->dwBackBufferCount = 1; + if (ddsd->dwFlags & DDSD_HEIGHT) + ddsd->dwHeight = this->height; + if (ddsd->dwFlags & DDSD_WIDTH) + ddsd->dwHeight = this->width; + ddsd->dwFlags &= ~(DDSD_CAPS|DDSD_BACKBUFFERCOUNT|DDSD_HEIGHT|DDSD_WIDTH); + if (ddsd->dwFlags) + fprintf(stderr," ddsd->flags is 0x%08lx\n",ddsd->dwFlags); + return 0; +} + +static ULONG WINAPI IDirectDrawSurface_AddRef(LPDIRECTDRAWSURFACE this) { + dprintf_relay(stddeb,"IDirectDrawSurface(%p)->AddRef()\n",this); + return ++(this->ref); +} + +static ULONG WINAPI IDirectDrawSurface_Release(LPDIRECTDRAWSURFACE this) { + dprintf_relay(stddeb,"IDirectDrawSurface(%p)->Release()\n",this); + if (!--(this->ref)) { + this->ddraw->lpvtbl->fnRelease(this->ddraw); + HeapFree(GetProcessHeap(),0,this); + return 0; + } + return this->ref; +} + +static ULONG WINAPI IDirectDrawSurface2_AddRef(LPDIRECTDRAWSURFACE2 this) { + dprintf_relay(stddeb,"IDirectDrawSurface2(%p)->AddRef()\n",this); + return ++(this->ref); +} + +static ULONG WINAPI IDirectDrawSurface2_Release(LPDIRECTDRAWSURFACE2 this) { + dprintf_relay(stddeb,"IDirectDrawSurface2(%p)->Release()\n",this); + if (!--(this->ref)) { + this->ddraw->lpvtbl->fnRelease(this->ddraw); + HeapFree(GetProcessHeap(),0,this); + return 0; + } + return this->ref; +} + +static HRESULT WINAPI IDirectDrawSurface2_GetAttachedSurface( + LPDIRECTDRAWSURFACE2 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE2 *lpdsf +) { + DDSURFACEDESC ddsfd; + IUnknown unk; + + /* DOES NOT CREATE THEM, but uses the ones already attached to this + * surface + */ + fprintf(stderr,"IDirectDrawSurface2(%p)->GetAttachedSurface(%p,%p)\n",this,lpddsd,lpdsf); + /* FIXME: not correct */ + IDirectDraw2_CreateSurface((LPDIRECTDRAW2)this->ddraw,&ddsfd,(LPDIRECTDRAWSURFACE*)lpdsf,&unk); + + lpddsd->dwCaps = 0; + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface_GetAttachedSurface( + LPDIRECTDRAWSURFACE this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE *lpdsf +) { + LPDDSURFACEDESC lpddsfd; + IUnknown unk; + + fprintf(stderr,"IDirectDrawSurface(%p)->GetAttachedSurface(%p,%p)\n",this,lpddsd,lpdsf); + /* FIXME: not correct */ + IDirectDraw_CreateSurface(this->ddraw,&lpddsfd,lpdsf,&unk); + lpddsd->dwCaps = 0; + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface_Initialize( + LPDIRECTDRAWSURFACE this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd +) { + fprintf(stderr,"IDirectDrawSurface(%p)->Initialize(%p,%p)\n", + this,ddraw,lpdsfd + ); + fprintf(stderr," dwFlags is %08lx\n",lpdsfd->dwFlags); + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface_GetPixelFormat( + LPDIRECTDRAWSURFACE this,LPDDPIXELFORMAT pf +) { + fprintf(stderr,"IDirectDrawSurface(%p)->GetPixelFormat(%p)\n",this,pf); + return _getpixelformat(this->ddraw,pf); +} + +static HRESULT WINAPI IDirectDrawSurface_GetBltStatus(LPDIRECTDRAWSURFACE this,DWORD dwFlags) { + fprintf(stderr,"IDirectDrawSurface(%p)->GetBltStatus(0x%08lx),stub!\n", + this,dwFlags + ); + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface_GetOverlayPosition( + LPDIRECTDRAWSURFACE this,LPLONG x1,LPLONG x2 +) { + fprintf(stderr,"IDirectDrawSurface(%p)->GetOverlayPosition(%p,%p),stub!\n", + this,x1,x2 + ); + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE this,HDC32* lphdc) { + fprintf(stderr,"IDirectDrawSurface(%p)->GetDC(%p),stub!\n",this,lphdc); + return 0; +} + +static HRESULT WINAPI IDirectDrawSurface2_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE2 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) { + /* none yet? */ + return 0; +} + +static struct IDirectDrawSurface2_VTable dds2vt = { + 1/*IDirectDrawSurface2_QueryInterface*/, + IDirectDrawSurface2_AddRef, + IDirectDrawSurface2_Release, + 4, + 5, + 6/*IDirectDrawSurface_Blt*/, + 7/*IDirectDrawSurface_BltBatch*/, + 8, + 9, + IDirectDrawSurface2_EnumAttachedSurfaces, + 11, + 12, + IDirectDrawSurface2_GetAttachedSurface, + 14, + 15/*IDirectDrawSurface_GetCaps*/, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23/*IDirectDrawSurface_GetSurfaceDesc*/, + 24, + 25, + IDirectDrawSurface2_Lock, + 27, + 28, + 29, + 30, + 31, + IDirectDrawSurface2_SetPalette, + IDirectDrawSurface2_Unlock, + 34, + 35, + 36, + 37, + 38, + 39, +}; + + +static HRESULT WINAPI IDirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE this,REFIID refiid,LPVOID *obj) { + char xrefiid[50]; + + StringFromCLSID((LPCLSID)refiid,xrefiid); + fprintf(stderr,"IDirectDrawSurface(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj); + + /* thats version 2 */ + if ( !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID_IDirectDrawSurface2))) { + this->lpvtbl->fnAddRef(this); + this->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dds2vt; + *obj = this; + return 0; + } + /* thats us */ + if (!memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID_IDirectDrawSurface))) { + this->lpvtbl->fnAddRef(this); + *obj = this; + return 0; + } + return OLE_E_ENUM_NOMORE; +} + +static struct IDirectDrawSurface_VTable ddsvt = { + IDirectDrawSurface_QueryInterface, + IDirectDrawSurface_AddRef, + IDirectDrawSurface_Release, + 4, + 5, + IDirectDrawSurface_Blt, + IDirectDrawSurface_BltBatch, + IDirectDrawSurface_BltFast, + 9, + 10, + 11, + IDirectDrawSurface_Flip, + IDirectDrawSurface_GetAttachedSurface, + IDirectDrawSurface_GetBltStatus, + IDirectDrawSurface_GetCaps, + 16, + 17, + IDirectDrawSurface_GetDC, + 19, + IDirectDrawSurface_GetOverlayPosition, + 21, + IDirectDrawSurface_GetPixelFormat, + IDirectDrawSurface_GetSurfaceDesc, + IDirectDrawSurface_Initialize, + 25, + IDirectDrawSurface_Lock, + 27, + 28, + 29, + 30, + 31, + IDirectDrawSurface_SetPalette, + IDirectDrawSurface_Unlock, + 34, + 35, + 36, +}; + +static HRESULT WINAPI IDirectDraw_CreateSurface( + LPDIRECTDRAW this,LPDDSURFACEDESC *lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk +) { + fprintf(stderr,"IDirectDraw(%p)->CreateSurface(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk); + *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectDrawSurface)); + this->lpvtbl->fnAddRef(this); + (*lpdsf)->ref = 1; + (*lpdsf)->lpvtbl = &ddsvt; + (*lpdsf)->surface = this->d.fb_addr+(this->d.current_height*this->d.fb_width*this->d.depth/8); + (*lpdsf)->fb_height = this->d.current_height; /* for setviewport */ + this->d.current_height += this->d.fb_height; + (*lpdsf)->width = this->d.width; + (*lpdsf)->height = this->d.height; + (*lpdsf)->ddraw = this; + (*lpdsf)->lpitch = this->d.fb_width*this->d.depth/8; + *lpddsd = (LPDDSURFACEDESC)HeapAlloc(GetProcessHeap(),0,sizeof(DDSURFACEDESC)); + (*lpddsd)->dwWidth = this->d.width; + (*lpddsd)->dwHeight = this->d.height; + (*lpddsd)->lPitch = this->d.fb_width*this->d.depth/8; + (*lpddsd)->ddsCaps.dwCaps = 0; + return 0; +} + +static HRESULT WINAPI IDirectDraw_DuplicateSurface( + LPDIRECTDRAW this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst +) { + fprintf(stderr,"IDirectDraw(%p)->DuplicateSurface(%p,%p)\n",this,src,dst); + *dst = src; /* FIXME */ + return 0; +} + +static HRESULT WINAPI IDirectDraw2_CreateSurface( + LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk +) { + fprintf(stderr,"IDirectDraw2(%p)->CreateSurface(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk); + *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectDrawSurface)); + this->lpvtbl->fnAddRef(this); + (*lpdsf)->ref = 1; + (*lpdsf)->lpvtbl = &ddsvt; + (*lpdsf)->surface = this->d.fb_addr+(this->d.current_height*this->d.fb_width*this->d.depth/8); + (*lpdsf)->width = this->d.width; + (*lpdsf)->height = this->d.height; + (*lpdsf)->ddraw = (LPDIRECTDRAW)this; + (*lpdsf)->fb_height = this->d.current_height; + (*lpdsf)->lpitch = this->d.fb_width*this->d.depth/8; + this->d.current_height += this->d.fb_height; + lpddsd->dwWidth = this->d.width; + lpddsd->dwHeight = this->d.height; + lpddsd->lPitch = this->d.fb_width*this->d.depth/8; + lpddsd->ddsCaps.dwCaps = 0; + return 0; +} + +static HRESULT WINAPI IDirectDraw_SetCooperativeLevel( + LPDIRECTDRAW this,HWND32 hwnd,DWORD x +) { + fprintf(stderr,"IDirectDraw(%p)->SetCooperativeLevel(%08lx,%08lx),stub!\n", + this,(DWORD)hwnd,x + ); + this->d.mainwindow = hwnd; + return 0; +} + +static HRESULT WINAPI IDirectDraw_SetDisplayMode( + LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth +) { + int i,*depths,depcount; + char buf[200]; + + fprintf(stderr,"IDirectDraw(%p)->SetDisplayMode(%ld,%ld,%ld),stub!\n",this,width,height,depth); + + depths = XListDepths(display,DefaultScreen(display),&depcount); + for (i=0;id.fb_width < width) { + sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld",width,height,depth,width,this->d.fb_width); + MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP); + return DDERR_UNSUPPORTEDMODE; + } + this->d.width = width; + this->d.height = height; + /* adjust fb_height, so we don't overlap */ + if (this->d.fb_height < height) + this->d.fb_height = height; + this->d.depth = depth; + XF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics); + return 0; +} +static HRESULT WINAPI IDirectDraw_GetCaps( + LPDIRECTDRAW this,LPDDCAPS caps1,LPDDCAPS caps2 +) { + fprintf(stderr,"IDirectDraw(%p)->GetCaps(%p,%p),stub!\n",this,caps1,caps2); + caps1->dwVidMemTotal = this->d.fb_memsize; + caps1->dwCaps = 0; /* we cannot do anything */ + caps1->ddsCaps.dwCaps = 0; /* we cannot do anything */ + return 0; +} + +static HRESULT WINAPI IDirectDraw2_GetCaps( + LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2 +) { + fprintf(stderr,"IDirectDraw2(%p)->GetCaps(%p,%p),stub!\n",this,caps1,caps2); + caps1->dwVidMemTotal = this->d.fb_memsize; + caps1->dwCaps = 0; /* we cannot do anything */ + caps1->ddsCaps.dwCaps = 0; + return 0; +} + + +static struct IDirectDrawClipper_VTable ddclipvt = { + 1,2,3,4,5,6,0x10007,8,9 +}; + +static HRESULT WINAPI IDirectDraw_CreateClipper( + LPDIRECTDRAW this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk +) { + fprintf(stderr,"IDirectDraw(%p)->CreateClipper(%08lx,%p,%p),stub!\n", + this,x,lpddclip,lpunk + ); + *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectDrawClipper)); + (*lpddclip)->ref = 1; + (*lpddclip)->lpvtbl = &ddclipvt; + return 0; +} + +static HRESULT WINAPI IDirectDrawPalette_GetEntries( + LPDIRECTDRAWPALETTE this,DWORD x,DWORD y,DWORD z,LPPALETTEENTRY palent +) { + fprintf(stderr,"IDirectDrawPalette(%p)->GetEntries(%08lx,%08lx,%08lx,%p),stub!\n", + this,x,y,z,palent + ); + return 0; +} + +static HRESULT WINAPI IDirectDrawPalette_SetEntries( + LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD end,LPPALETTEENTRY palent +) { + XColor xc; + int i; + + fprintf(stderr,"IDirectDrawPalette(%p)->SetEntries(%08lx,%ld,%ld,%p)\n", + this,x,start,end,palent + ); + if (!this->cm) /* should not happen */ { + fprintf(stderr,"no colormap in SetEntries???\n"); + return DDERR_GENERIC; + } + XFreeColormap(display,this->cm); + this->cm = XCreateColormap(display,DefaultRootWindow(display),DefaultVisual(display,DefaultScreen(display)),AllocAll); + xc.red = xc.blue = xc.green = 0; xc.flags = DoRed|DoGreen|DoBlue; xc.pixel = 0; XStoreColor(display,this->cm,&xc); + xc.red = xc.blue = xc.green = 0xffff; xc.flags = DoRed|DoGreen|DoBlue; xc.pixel = 255; XStoreColor(display,this->cm,&xc); + for (i=start;icm,&xc); + } + XF86DGAInstallColormap(display,DefaultScreen(display),this->cm); + return 0; +} + +static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) { + fprintf(stderr,"IDirectDrawPalette(%p)->Release()\n",this); + if (!--(this->ref)) { + fprintf(stderr,"IDirectDrawPalette(%p) freed!\n",this); + if (this->cm) { + XFreeColormap(display,this->cm); + this->cm = 0; + } + HeapFree(GetProcessHeap(),0,this); + return 0; + } + return this->ref; +} + +static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) { + fprintf(stderr,"IDirectDrawPalette(%p)->AddRef()\n",this); + return ++(this->ref); +} + +static struct IDirectDrawPalette_VTable ddpalvt = { + 1, + IDirectDrawPalette_AddRef, + IDirectDrawPalette_Release, + 4, + IDirectDrawPalette_GetEntries, + 6, + IDirectDrawPalette_SetEntries +}; + +static HRESULT WINAPI IDirectDraw_CreatePalette( + LPDIRECTDRAW this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk +) { + fprintf(stderr,"IDirectDraw(%p)->CreatePalette(%08lx,%p,%p,%p),stub!\n", + this,x,palent,lpddpal,lpunk + ); + *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectDrawPalette)); + (*lpddpal)->ref = 1; + (*lpddpal)->lpvtbl = &ddpalvt; + (*lpddpal)->ddraw = this; + if (this->d.depth<=8) { + (*lpddpal)->cm = XCreateColormap(display,DefaultRootWindow(display),DefaultVisual(display,DefaultScreen(display)),AllocAll); + fprintf(stderr,"created colormap...\n"); + } else /* we don't want palettes in hicolor or truecolor */ + (*lpddpal)->cm = 0; + + return 0; +} + +static HRESULT WINAPI IDirectDraw2_CreatePalette( + LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk +) { + return IDirectDraw_CreatePalette((LPDIRECTDRAW)this,x,palent,lpddpal,lpunk); +} + +static HRESULT WINAPI IDirectDraw_WaitForVerticalBlank( + LPDIRECTDRAW this,DWORD x,HANDLE32 h +) { + fprintf(stderr,"IDirectDraw(%p)->WaitForVerticalBlank(0x%08lx,0x%08x),stub!\n",this,x,h); + return 0; +} + +static ULONG WINAPI IDirectDraw_AddRef(LPDIRECTDRAW this) { + dprintf_relay(stddeb,"IDirectDraw(%p)->AddRef()\n",this); + return ++(this->ref); +} + +static ULONG WINAPI IDirectDraw_Release(LPDIRECTDRAW this) { + dprintf_relay(stddeb,"IDirectDraw(%p)->Release()\n",this); + if (!--(this->ref)) { + fprintf(stderr,"IDirectDraw::Release:freeing IDirectDraw(%p)\n",this); + HeapFree(GetProcessHeap(),0,this); + return 0; + } + return this->ref; +} + +static HRESULT WINAPI IDirectDraw2_QueryInterface( + LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj +) { + return IDirectDraw_QueryInterface((LPDIRECTDRAW)this,refiid,obj); +} + +static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) { + return IDirectDraw_AddRef((LPDIRECTDRAW)this); +} + +static ULONG WINAPI IDirectDraw2_Release(LPDIRECTDRAW2 this) { + return IDirectDraw_Release((LPDIRECTDRAW)this); +} + +static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel( + LPDIRECTDRAW2 this,HWND32 hwnd,DWORD x +) { + fprintf(stderr,"IDirectDraw2(%p)->SetCooperativeLevel(%08lx,%08lx),stub!\n", + this,(DWORD)hwnd,x + ); + this->d.mainwindow = hwnd; + return 0; +} + +static HRESULT WINAPI IDirectDraw2_SetDisplayMode( + LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy +) { + fprintf(stderr,"IDirectDraw2(%p)->SetDisplayMode(%ld,%ld,%ld,%08lx,%08lx),stub!\n",this,width,height,depth,xx,yy); + + return IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth); +} + +static HRESULT WINAPI IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) { + fprintf(stderr,"IDirectDraw2(%p)->RestoreDisplayMode(),stub!\n",this); + XF86DGADirectVideo(display,DefaultScreen(display),0); + return 0; +} + +static HRESULT WINAPI IDirectDraw_RestoreDisplayMode(LPDIRECTDRAW this) { + fprintf(stderr,"IDirectDraw(%p)->RestoreDisplayMode(),stub!\n",this); + XF86DGADirectVideo(display,DefaultScreen(display),0); + return 0; +} + +static HRESULT WINAPI IDirectDraw2_EnumSurfaces( + LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb +) { + fprintf(stderr,"IDirectDraw2(%p)->EnumSurfaces(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb); + return 0; +} + +static IDirectDraw2_VTable dd2vt = { + IDirectDraw2_QueryInterface, + IDirectDraw2_AddRef, + IDirectDraw2_Release, + 4, + 5/*IDirectDraw_CreateClipper*/, + IDirectDraw2_CreatePalette, + IDirectDraw2_CreateSurface, + 8, + 9, + IDirectDraw2_EnumSurfaces, + 11, + IDirectDraw2_GetCaps, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + IDirectDraw2_RestoreDisplayMode, + IDirectDraw2_SetCooperativeLevel, + IDirectDraw2_SetDisplayMode, + 23/*IDirectDraw_WaitForVerticalBlank*/, + 24 +}; + +static HRESULT WINAPI IDirectDraw_QueryInterface( + LPDIRECTDRAW this,REFIID refiid,LPVOID *obj +) { + char xrefiid[50]; + + StringFromCLSID((LPCLSID)refiid,xrefiid); + fprintf(stderr,"IDirectDraw(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj); + if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) { + *obj = this; + this->lpvtbl->fnAddRef(this); + return 0; + } + if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) { + /* FIXME FIXME FIXME */ + this->lpvtbl = (LPDIRECTDRAW_VTABLE)&dd2vt; + this->lpvtbl->fnAddRef(this); + *obj = this; + return 0; + } + return OLE_E_ENUM_NOMORE; +} + +static HRESULT WINAPI IDirectDraw_GetVerticalBlankStatus( + LPDIRECTDRAW this,BOOL32 *status +) { + fprintf(stderr,"IDirectDraw(%p)->GetVerticalBlankSatus(%p)\n",this,status); + *status = TRUE; + return 0; +} + +static HRESULT WINAPI IDirectDraw_EnumDisplayModes( + LPDIRECTDRAW this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb +) { + DDSURFACEDESC ddsfd; + + fprintf(stderr,"IDirectDraw(%p)->EnumDisplayModes(0x%08lx,%p,%p,%p),stub!\n",this,dwFlags,lpddsfd,context,modescb); + ddsfd.dwSize = sizeof(ddsfd); + ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_CAPS|DDSD_BACKBUFFERCOUNT|DDSD_REFRESHRATE; + ddsfd.dwHeight = 480; + ddsfd.dwWidth = 640; + ddsfd.lPitch = 640; + ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE|DDSCAPS_FRONTBUFFER|DDSCAPS_BACKBUFFER|DDSCAPS_FLIP|DDSCAPS_PRIMARYSURFACE|DDSCAPS_VIDEOMEMORY|DDSCAPS_ZBUFFER; + ddsfd.dwBackBufferCount = 1; + ddsfd.x.dwRefreshRate = 60; + _getpixelformat(this,&(ddsfd.ddpfPixelFormat)); + fprintf(stderr,"modescb returned: 0x%lx\n",(DWORD)modescb(&ddsfd,context)); + return 0; +} + + +static IDirectDraw_VTable ddvt = { + IDirectDraw_QueryInterface, + IDirectDraw_AddRef, + IDirectDraw_Release, + 4, + IDirectDraw_CreateClipper, + IDirectDraw_CreatePalette, + IDirectDraw_CreateSurface, + IDirectDraw_DuplicateSurface, + IDirectDraw_EnumDisplayModes, + 10, + 11, + IDirectDraw_GetCaps, + 13, + 14, + 15, + 16, + 17, + IDirectDraw_GetVerticalBlankStatus, + 19, + IDirectDraw_RestoreDisplayMode, + IDirectDraw_SetCooperativeLevel, + IDirectDraw_SetDisplayMode, + IDirectDraw_WaitForVerticalBlank, +}; + + +HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) { + + char xclsid[50]; + int memsize,banksize,width,evbase,evret,major,minor,flags,height; + char *addr; + + + if (lpGUID) + StringFromCLSID(lpGUID,xclsid); + else + strcpy(xclsid,""); + + fprintf(stderr,"DirectDrawCreate(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter); + if (getuid()) { + MessageBox32A(0,"Using the XF86DGA extensions requires the program to be run using UID 0.","WINE DirectDraw",MB_OK|MB_ICONSTOP); + return E_UNEXPECTED; + } + *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectDraw)); + (*lplpDD)->lpvtbl = &ddvt; + (*lplpDD)->ref = 1; + if (!XF86DGAQueryExtension(display,&evbase,&evret)) { + fprintf(stderr,"No XF86DGA detected.\n"); + return 0; + } + XF86DGAQueryVersion(display,&major,&minor); + fprintf(stderr,"XF86DGA is version %d.%d\n",major,minor); + XF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags); + if (!(flags & XF86DGADirectPresent)) + fprintf(stderr,"direct video is NOT ENABLED.\n"); + XF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize); + fprintf(stderr,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n", + addr,width,banksize,memsize + ); + (*lplpDD)->d.fb_width = width; + (*lplpDD)->d.fb_addr = addr; + (*lplpDD)->d.fb_memsize = memsize; + (*lplpDD)->d.fb_banksize = banksize; + + XF86DGASetViewPort(display,DefaultScreen(display),0,0); + while (!XF86DGAViewPortChanged(display,DefaultScreen(display),1)) { + fprintf(stderr,"."); + } + XF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height); + (*lplpDD)->d.vp_width = width; + (*lplpDD)->d.vp_height = height; + (*lplpDD)->d.fb_height = height; /* FIXME: can we find out the virtual + * size somehow else ? + */ + (*lplpDD)->d.current_height = 0; + return 0; +} +#else + +HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) { + MessageBox32A(0,"WINE DirectDraw needs the XF86DGA extensions compiled in. (libXxf86dga.a).","WINE DirectDraw",MB_OK|MB_ICONSTOP); + return E_OUTOFMEMORY; +} +#endif diff --git a/graphics/painting.c b/graphics/painting.c index 9b169e4e525..cec3d9ce3e5 100644 --- a/graphics/painting.c +++ b/graphics/painting.c @@ -19,7 +19,6 @@ #include "callback.h" #include "heap.h" #include "metafile.h" -#include "syscolor.h" #include "palette.h" #include "cache.h" #include "color.h" @@ -513,7 +512,7 @@ void WINAPI DrawFocusRect16( HDC16 hdc, const RECT16* rc ) */ void WINAPI DrawFocusRect32( HDC32 hdc, const RECT32* rc ) { - HPEN32 hOldPen; + HPEN32 hOldPen, hnewPen; INT32 oldDrawMode, oldBkMode; INT32 left, top, right, bottom; @@ -525,7 +524,8 @@ void WINAPI DrawFocusRect32( HDC32 hdc, const RECT32* rc ) right = XLPTODP( dc, rc->right ); bottom = YLPTODP( dc, rc->bottom ); - hOldPen = SelectObject32( hdc, sysColorObjects.hpenWindowText ); + hnewPen = CreatePen32(PS_DOT, 1, GetSysColor32(COLOR_WINDOWTEXT) ); + hOldPen = SelectObject32( hdc, hnewPen ); oldDrawMode = SetROP232(hdc, R2_XORPEN); oldBkMode = SetBkMode32(hdc, TRANSPARENT); @@ -540,6 +540,7 @@ void WINAPI DrawFocusRect32( HDC32 hdc, const RECT32* rc ) SetBkMode32(hdc, oldBkMode); SetROP232(hdc, oldDrawMode); SelectObject32(hdc, hOldPen); + DeleteObject32(hnewPen); } diff --git a/graphics/win16drv/init.c b/graphics/win16drv/init.c index e00e638713c..faac26ef924 100644 --- a/graphics/win16drv/init.c +++ b/graphics/win16drv/init.c @@ -604,7 +604,7 @@ static int CreateSpoolFile(LPSTR pszOutput) PROFILE_GetWineIniString( "spooler", pszOutput, "", psCmd, sizeof(psCmd) ); - printf("Got printerSpoolCOmmand \"%s\"\n",psCmd); + printf("Got printerSpoolCommand \"%s\"\n",psCmd); if (!*psCmd) psCmdP = pszOutput; else @@ -635,7 +635,7 @@ static int CreateSpoolFile(LPSTR pszOutput) } close (fds[0]); fd = fds[1]; - printf("Need to execut a command and pipe the output to it\n"); + printf("Need to execute a command and pipe the output to it\n"); } else { diff --git a/graphics/x11drv/brush.c b/graphics/x11drv/brush.c index a162ad78b22..5b38fa68c12 100644 --- a/graphics/x11drv/brush.c +++ b/graphics/x11drv/brush.c @@ -164,10 +164,22 @@ static BOOL32 BRUSH_SelectPatternBrush( DC * dc, HBITMAP32 hbitmap ) { BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ); if (!bmp) return FALSE; - dc->u.x.brush.pixmap = XCreatePixmap( display, rootWindow, - 8, 8, bmp->bitmap.bmBitsPixel ); - XCopyArea( display, bmp->pixmap, dc->u.x.brush.pixmap, - BITMAP_GC(bmp), 0, 0, 8, 8, 0, 0 ); + + if ((dc->w.bitsPerPixel == 1) && (bmp->bitmap.bmBitsPixel != 1)) + { + /* Special case: a color pattern on a monochrome DC */ + dc->u.x.brush.pixmap = XCreatePixmap( display, rootWindow, 8, 8, 1 ); + /* FIXME: should probably convert to monochrome instead */ + XCopyPlane( display, bmp->pixmap, dc->u.x.brush.pixmap, + BITMAP_monoGC, 0, 0, 8, 8, 0, 0, 1 ); + } + else + { + dc->u.x.brush.pixmap = XCreatePixmap( display, rootWindow, + 8, 8, bmp->bitmap.bmBitsPixel ); + XCopyArea( display, bmp->pixmap, dc->u.x.brush.pixmap, + BITMAP_GC(bmp), 0, 0, 8, 8, 0, 0 ); + } if (bmp->bitmap.bmBitsPixel > 1) { diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c index 9348d91223e..d6e42e45a99 100644 --- a/graphics/x11drv/graphics.c +++ b/graphics/x11drv/graphics.c @@ -25,7 +25,6 @@ #include "bitmap.h" #include "callback.h" #include "metafile.h" -#include "syscolor.h" #include "stddebug.h" #include "palette.h" #include "color.h" diff --git a/if1632/builtin.c b/if1632/builtin.c index 273908a9b56..7076b1e6fbf 100644 --- a/if1632/builtin.c +++ b/if1632/builtin.c @@ -370,7 +370,9 @@ BOOL32 BUILTIN_ParseDLLOptions( const char *str ) break; } } - if (!dll->descr) return FALSE; + if (!dll->descr) + if (!BUILTIN32_EnableDLL( str, (int)(p - str), (str[-1] == '+') )) + return FALSE; str = p; while (*str && (isspace(*str) || (*str == ','))) str++; } @@ -389,7 +391,7 @@ void BUILTIN_PrintDLLs(void) BUILTIN16_DLL *dll; fprintf(stderr,"Example: -dll -ole2 Do not use emulated OLE2.DLL\n"); - fprintf(stderr,"Available DLLs:\n"); + fprintf(stderr,"Available Win16 DLLs:\n"); for (i = 0, dll = BuiltinDLLs; dll->descr; dll++) { if (!(dll->flags & DLL_FLAG_ALWAYS_USED)) @@ -397,4 +399,5 @@ void BUILTIN_PrintDLLs(void) ((++i) % 8) ? ' ' : '\n' ); } fprintf(stderr,"\n"); + BUILTIN32_PrintDLLs(); } diff --git a/if1632/kernel.spec b/if1632/kernel.spec index db1dae26ab4..69ee55f89b9 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -327,7 +327,7 @@ file krnl386.exe 515 pascal GetProcAddress32W(long str) GetProcAddress32 516 pascal GetVDMPointer32W(segptr long) GetVDMPointer32W 517 pascal CallProc32W() WIN16_CallProc32W -518 stub CallProcEx32W +518 pascal CallProcEx32W() WIN16_CallProcEx32W 519 stub KERNEL_519 522 stub KERNEL_522 523 stub KERNEL_523 diff --git a/if1632/relay.c b/if1632/relay.c index 6596be52efe..8e247ff0206 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -321,10 +321,13 @@ void WINAPI Throw( CONTEXT *context ) } } + /********************************************************************** - * CallProc32W (KERNEL.517) + * RELAY_CallProc32W + * + * Helper for CallProc[Ex]32W */ -DWORD WINAPI WIN16_CallProc32W() +static DWORD RELAY_CallProc32W(int Ex) { DWORD nrofargs, argconvmask; FARPROC32 proc32; @@ -336,7 +339,7 @@ DWORD WINAPI WIN16_CallProc32W() nrofargs = VA_ARG16( valist, DWORD ); argconvmask = VA_ARG16( valist, DWORD ); proc32 = VA_ARG16( valist, FARPROC32 ); - fprintf(stderr,"CallProc32W(%ld,%ld,%p,args[",nrofargs,argconvmask,proc32); + fprintf(stderr,"CallProc32W(%ld,%ld,%p, Ex%d args[",nrofargs,argconvmask,proc32,Ex); args = (DWORD*)HEAP_xalloc( GetProcessHeap(), 0, sizeof(DWORD)*nrofargs ); for (i=0;i header file. */ +#undef HAVE_WCTYPE_H + +/* Define if you have the Xxf86dga library (-lXxf86dga). */ +#undef HAVE_LIBXXF86DGA + +/* Define if you have the i386 library (-li386). */ +#undef HAVE_LIBI386 + +/* Define if you have the w library (-lw). */ +#undef HAVE_LIBW diff --git a/include/ddraw.h b/include/ddraw.h new file mode 100644 index 00000000000..3197b85730c --- /dev/null +++ b/include/ddraw.h @@ -0,0 +1,898 @@ +#ifndef __WINE_DDRAW_H +#define __WINE_DDRAW_H + +#include + + +DEFINE_GUID( CLSID_DirectDraw, 0xD7B70EE0,0x4340,0x11CF,0xB0,0x63,0x00,0x20,0xAF,0xC2,0xCD,0x35 ); +DEFINE_GUID( CLSID_DirectDrawClipper, 0x593817A0,0x7DB3,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xb9,0x33,0x56 ); +DEFINE_GUID( IID_IDirectDraw, 0x6C14DB80,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDraw2, 0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 ); +DEFINE_GUID( IID_IDirectDrawSurface, 0x6C14DB81,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDrawSurface2, 0x57805885,0x6eec,0x11cf,0x94,0x41,0xa8,0x23,0x03,0xc1,0x0e,0x27 ); +DEFINE_GUID( IID_IDirectDrawPalette, 0x6C14DB84,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); +DEFINE_GUID( IID_IDirectDrawClipper, 0x6C14DB85,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); + +typedef struct IDirectDraw IDirectDraw,*LPDIRECTDRAW; +typedef struct IDirectDraw2 IDirectDraw2,*LPDIRECTDRAW2; +typedef struct IDirectDrawClipper IDirectDrawClipper,*LPDIRECTDRAWCLIPPER; +typedef struct IDirectDrawPalette IDirectDrawPalette,*LPDIRECTDRAWPALETTE; +typedef struct IDirectDrawSurface IDirectDrawSurface,*LPDIRECTDRAWSURFACE; +typedef struct IDirectDrawSurface2 IDirectDrawSurface2,*LPDIRECTDRAWSURFACE2; + +#define _FACDD 0x876 +#define MAKE_DDHRESULT( code ) MAKE_HRESULT( 1, _FACDD, code ) + +#define DDERR_ALREADYINITIALIZED MAKE_DDHRESULT( 5 ) +#define DDERR_CANNOTATTACHSURFACE MAKE_DDHRESULT( 10 ) +#define DDERR_CANNOTDETACHSURFACE MAKE_DDHRESULT( 20 ) +#define DDERR_CURRENTLYNOTAVAIL MAKE_DDHRESULT( 40 ) +#define DDERR_EXCEPTION MAKE_DDHRESULT( 55 ) +#define DDERR_GENERIC E_FAIL +#define DDERR_HEIGHTALIGN MAKE_DDHRESULT( 90 ) +#define DDERR_INCOMPATIBLEPRIMARY MAKE_DDHRESULT( 95 ) +#define DDERR_INVALIDCAPS MAKE_DDHRESULT( 100 ) +#define DDERR_INVALIDCLIPLIST MAKE_DDHRESULT( 110 ) +#define DDERR_INVALIDMODE MAKE_DDHRESULT( 120 ) +#define DDERR_INVALIDOBJECT MAKE_DDHRESULT( 130 ) +#define DDERR_INVALIDPARAMS E_INVALIDARG +#define DDERR_INVALIDPIXELFORMAT MAKE_DDHRESULT( 145 ) +#define DDERR_INVALIDRECT MAKE_DDHRESULT( 150 ) +#define DDERR_LOCKEDSURFACES MAKE_DDHRESULT( 160 ) +#define DDERR_NO3D MAKE_DDHRESULT( 170 ) +#define DDERR_NOALPHAHW MAKE_DDHRESULT( 180 ) +#define DDERR_NOCLIPLIST MAKE_DDHRESULT( 205 ) +#define DDERR_NOCOLORCONVHW MAKE_DDHRESULT( 210 ) +#define DDERR_NOCOOPERATIVELEVELSET MAKE_DDHRESULT( 212 ) +#define DDERR_NOCOLORKEY MAKE_DDHRESULT( 215 ) +#define DDERR_NOCOLORKEYHW MAKE_DDHRESULT( 220 ) +#define DDERR_NODIRECTDRAWSUPPORT MAKE_DDHRESULT( 222 ) +#define DDERR_NOEXCLUSIVEMODE MAKE_DDHRESULT( 225 ) +#define DDERR_NOFLIPHW MAKE_DDHRESULT( 230 ) +#define DDERR_NOGDI MAKE_DDHRESULT( 240 ) +#define DDERR_NOMIRRORHW MAKE_DDHRESULT( 250 ) +#define DDERR_NOTFOUND MAKE_DDHRESULT( 255 ) +#define DDERR_NOOVERLAYHW MAKE_DDHRESULT( 260 ) +#define DDERR_NORASTEROPHW MAKE_DDHRESULT( 280 ) +#define DDERR_NOROTATIONHW MAKE_DDHRESULT( 290 ) +#define DDERR_NOSTRETCHHW MAKE_DDHRESULT( 310 ) +#define DDERR_NOT4BITCOLOR MAKE_DDHRESULT( 316 ) +#define DDERR_NOT4BITCOLORINDEX MAKE_DDHRESULT( 317 ) +#define DDERR_NOT8BITCOLOR MAKE_DDHRESULT( 320 ) +#define DDERR_NOTEXTUREHW MAKE_DDHRESULT( 330 ) +#define DDERR_NOVSYNCHW MAKE_DDHRESULT( 335 ) +#define DDERR_NOZBUFFERHW MAKE_DDHRESULT( 340 ) +#define DDERR_NOZOVERLAYHW MAKE_DDHRESULT( 350 ) +#define DDERR_OUTOFCAPS MAKE_DDHRESULT( 360 ) +#define DDERR_OUTOFMEMORY E_OUTOFMEMORY +#define DDERR_OUTOFVIDEOMEMORY MAKE_DDHRESULT( 380 ) +#define DDERR_OVERLAYCANTCLIP MAKE_DDHRESULT( 382 ) +#define DDERR_OVERLAYCOLORKEYONLYONEACTIVE MAKE_DDHRESULT( 384 ) +#define DDERR_PALETTEBUSY MAKE_DDHRESULT( 387 ) +#define DDERR_COLORKEYNOTSET MAKE_DDHRESULT( 400 ) +#define DDERR_SURFACEALREADYATTACHED MAKE_DDHRESULT( 410 ) +#define DDERR_SURFACEALREADYDEPENDENT MAKE_DDHRESULT( 420 ) +#define DDERR_SURFACEBUSY MAKE_DDHRESULT( 430 ) +#define DDERR_CANTLOCKSURFACE MAKE_DDHRESULT( 435 ) +#define DDERR_SURFACEISOBSCURED MAKE_DDHRESULT( 440 ) +#define DDERR_SURFACELOST MAKE_DDHRESULT( 450 ) +#define DDERR_SURFACENOTATTACHED MAKE_DDHRESULT( 460 ) +#define DDERR_TOOBIGHEIGHT MAKE_DDHRESULT( 470 ) +#define DDERR_TOOBIGSIZE MAKE_DDHRESULT( 480 ) +#define DDERR_TOOBIGWIDTH MAKE_DDHRESULT( 490 ) +#define DDERR_UNSUPPORTED E_NOTIMPL +#define DDERR_UNSUPPORTEDFORMAT MAKE_DDHRESULT( 510 ) +#define DDERR_UNSUPPORTEDMASK MAKE_DDHRESULT( 520 ) +#define DDERR_VERTICALBLANKINPROGRESS MAKE_DDHRESULT( 537 ) +#define DDERR_WASSTILLDRAWING MAKE_DDHRESULT( 540 ) +#define DDERR_XALIGN MAKE_DDHRESULT( 560 ) +#define DDERR_INVALIDDIRECTDRAWGUID MAKE_DDHRESULT( 561 ) +#define DDERR_DIRECTDRAWALREADYCREATED MAKE_DDHRESULT( 562 ) +#define DDERR_NODIRECTDRAWHW MAKE_DDHRESULT( 563 ) +#define DDERR_PRIMARYSURFACEALREADYEXISTS MAKE_DDHRESULT( 564 ) +#define DDERR_NOEMULATION MAKE_DDHRESULT( 565 ) +#define DDERR_REGIONTOOSMALL MAKE_DDHRESULT( 566 ) +#define DDERR_CLIPPERISUSINGHWND MAKE_DDHRESULT( 567 ) +#define DDERR_NOCLIPPERATTACHED MAKE_DDHRESULT( 568 ) +#define DDERR_NOHWND MAKE_DDHRESULT( 569 ) +#define DDERR_HWNDSUBCLASSED MAKE_DDHRESULT( 570 ) +#define DDERR_HWNDALREADYSET MAKE_DDHRESULT( 571 ) +#define DDERR_NOPALETTEATTACHED MAKE_DDHRESULT( 572 ) +#define DDERR_NOPALETTEHW MAKE_DDHRESULT( 573 ) +#define DDERR_BLTFASTCANTCLIP MAKE_DDHRESULT( 574 ) +#define DDERR_NOBLTHW MAKE_DDHRESULT( 575 ) +#define DDERR_NODDROPSHW MAKE_DDHRESULT( 576 ) +#define DDERR_OVERLAYNOTVISIBLE MAKE_DDHRESULT( 577 ) +#define DDERR_NOOVERLAYDEST MAKE_DDHRESULT( 578 ) +#define DDERR_INVALIDPOSITION MAKE_DDHRESULT( 579 ) +#define DDERR_NOTAOVERLAYSURFACE MAKE_DDHRESULT( 580 ) +#define DDERR_EXCLUSIVEMODEALREADYSET MAKE_DDHRESULT( 581 ) +#define DDERR_NOTFLIPPABLE MAKE_DDHRESULT( 582 ) +#define DDERR_CANTDUPLICATE MAKE_DDHRESULT( 583 ) +#define DDERR_NOTLOCKED MAKE_DDHRESULT( 584 ) +#define DDERR_CANTCREATEDC MAKE_DDHRESULT( 585 ) +#define DDERR_NODC MAKE_DDHRESULT( 586 ) +#define DDERR_WRONGMODE MAKE_DDHRESULT( 587 ) +#define DDERR_IMPLICITLYCREATED MAKE_DDHRESULT( 588 ) +#define DDERR_NOTPALETTIZED MAKE_DDHRESULT( 589 ) +#define DDERR_UNSUPPORTEDMODE MAKE_DDHRESULT( 590 ) +#define DDERR_NOMIPMAPHW MAKE_DDHRESULT( 591 ) +#define DDERR_INVALIDSURFACETYPE MAKE_DDHRESULT( 592 ) +#define DDERR_DCALREADYCREATED MAKE_DDHRESULT( 620 ) +#define DDERR_CANTPAGELOCK MAKE_DDHRESULT( 640 ) +#define DDERR_CANTPAGEUNLOCK MAKE_DDHRESULT( 660 ) +#define DDERR_NOTPAGELOCKED MAKE_DDHRESULT( 680 ) +#define DDERR_NOTINITIALIZED CO_E_NOTINITIALIZED + +/* dwFlags for Blt* */ +#define DDBLT_ALPHADEST 0x00000001 +#define DDBLT_ALPHADESTCONSTOVERRIDE 0x00000002 +#define DDBLT_ALPHADESTNEG 0x00000004 +#define DDBLT_ALPHADESTSURFACEOVERRIDE 0x00000008 +#define DDBLT_ALPHAEDGEBLEND 0x00000010 +#define DDBLT_ALPHASRC 0x00000020 +#define DDBLT_ALPHASRCCONSTOVERRIDE 0x00000040 +#define DDBLT_ALPHASRCNEG 0x00000080 +#define DDBLT_ALPHASRCSURFACEOVERRIDE 0x00000100 +#define DDBLT_ASYNC 0x00000200 +#define DDBLT_COLORFILL 0x00000400 +#define DDBLT_DDFX 0x00000800 +#define DDBLT_DDROPS 0x00001000 +#define DDBLT_KEYDEST 0x00002000 +#define DDBLT_KEYDESTOVERRIDE 0x00004000 +#define DDBLT_KEYSRC 0x00008000 +#define DDBLT_KEYSRCOVERRIDE 0x00010000 +#define DDBLT_ROP 0x00020000 +#define DDBLT_ROTATIONANGLE 0x00040000 +#define DDBLT_ZBUFFER 0x00080000 +#define DDBLT_ZBUFFERDESTCONSTOVERRIDE 0x00100000 +#define DDBLT_ZBUFFERDESTOVERRIDE 0x00200000 +#define DDBLT_ZBUFFERSRCCONSTOVERRIDE 0x00400000 +#define DDBLT_ZBUFFERSRCOVERRIDE 0x00800000 +#define DDBLT_WAIT 0x01000000 +#define DDBLT_DEPTHFILL 0x02000000 + +/* dwTrans for BltFast */ +#define DDBLTFAST_NOCOLORKEY 0x00000000 +#define DDBLTFAST_SRCCOLORKEY 0x00000001 +#define DDBLTFAST_DESTCOLORKEY 0x00000002 +#define DDBLTFAST_WAIT 0x00000010 + +/* dwFlags for Flip */ +#define DDFLIP_WAIT 0x00000001 + +/* dwFlags for GetBltStatus */ +#define DDGBS_CANBLT 0x00000001 +#define DDGBS_ISBLTDONE 0x00000002 + +/* 3d capable (no meaning?) */ +#define DDSCAPS_3D 0x00000001 +/* surface contains alpha information */ +#define DDSCAPS_ALPHA 0x00000002 +/* this surface is a backbuffer */ +#define DDSCAPS_BACKBUFFER 0x00000004 +/* complex surface structure */ +#define DDSCAPS_COMPLEX 0x00000008 +/* part of surface flipping structure */ +#define DDSCAPS_FLIP 0x00000010 +/* this surface is the frontbuffer surface */ +#define DDSCAPS_FRONTBUFFER 0x00000020 +/* this is a plain offscreen surface */ +#define DDSCAPS_OFFSCREENPLAIN 0x00000040 +/* overlay */ +#define DDSCAPS_OVERLAY 0x00000080 +/* palette objects can be created and attached to us */ +#define DDSCAPS_PALETTE 0x00000100 +/* primary surface (the one the user looks at currently)(right eye)*/ +#define DDSCAPS_PRIMARYSURFACE 0x00000200 +/* primary surface for left eye */ +#define DDSCAPS_PRIMARYSURFACELEFT 0x00000400 +/* surface exists in systemmemory */ +#define DDSCAPS_SYSTEMMEMORY 0x00000800 +/* surface can be used as a texture */ +#define DDSCAPS_TEXTURE 0x00001000 +/* surface may be destination for 3d rendering */ +#define DDSCAPS_3DDEVICE 0x00002000 +/* surface exists in videomemory */ +#define DDSCAPS_VIDEOMEMORY 0x00004000 +/* surface changes immediately visible */ +#define DDSCAPS_VISIBLE 0x00008000 +/* write only surface */ +#define DDSCAPS_WRITEONLY 0x00010000 +/* zbuffer surface */ +#define DDSCAPS_ZBUFFER 0x00020000 +/* has its own DC */ +#define DDSCAPS_OWNDC 0x00040000 +/* surface should be able to receive live video */ +#define DDSCAPS_LIVEVIDEO 0x00080000 +/* should be able to have a hw codec decompress stuff into it */ +#define DDSCAPS_HWCODEC 0x00100000 +/* mode X (320x200 or 320x240) surface */ +#define DDSCAPS_MODEX 0x00200000 +/* one mipmap surface (1 level) */ +#define DDSCAPS_MIPMAP 0x00400000 +/* memory allocation delayed until Load() */ +#define DDSCAPS_ALLOCONLOAD 0x04000000 + +typedef struct _DDSCAPS { + DWORD dwCaps; /* capabilities of surface wanted */ +} DDSCAPS,*LPDDSCAPS; + +#define DD_ROP_SPACE (256/32) /* space required to store ROP array */ + +typedef struct _DDCAPS +{ + DWORD dwSize; /* size of the DDDRIVERCAPS structure */ + DWORD dwCaps; /* driver specific capabilities */ + DWORD dwCaps2; /* more driver specific capabilites */ + DWORD dwCKeyCaps; /* color key capabilities of the surface */ + DWORD dwFXCaps; /* driver specific stretching and effects capabilites */ + DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */ + DWORD dwPalCaps; /* palette capabilities */ + DWORD dwSVCaps; /* stereo vision capabilities */ + DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */ + DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */ + DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */ + DWORD dwVidMemTotal; /* total amount of video memory */ + DWORD dwVidMemFree; /* amount of free video memory */ + DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */ + DWORD dwCurrVisibleOverlays; /* current number of visible overlays */ + DWORD dwNumFourCCCodes; /* number of four cc codes */ + DWORD dwAlignBoundarySrc; /* source rectangle alignment */ + DWORD dwAlignSizeSrc; /* source rectangle byte size */ + DWORD dwAlignBoundaryDest; /* dest rectangle alignment */ + DWORD dwAlignSizeDest; /* dest rectangle byte size */ + DWORD dwAlignStrideAlign; /* stride alignment */ + DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */ + DDSCAPS ddsCaps; /* DDSCAPS structure has all the general capabilities */ + DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ + DWORD dwReserved1; + DWORD dwReserved2; + DWORD dwReserved3; + DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */ + DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */ + DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */ + DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */ + DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */ + DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */ + DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */ + DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */ + DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */ + DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */ + DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */ + DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */ + DWORD dwReserved4; + DWORD dwReserved5; + DWORD dwReserved6; +} DDCAPS,*LPDDCAPS; + +/* hw has 3d accel */ +#define DDCAPS_3D 0x00000001 +/* supports only boundary aligned rectangles */ +#define DDCAPS_ALIGNBOUNDARYDEST 0x00000002 +#define DDCAPS_ALIGNSIZEDEST 0x00000004 +#define DDCAPS_ALIGNBOUNDARYSRC 0x00000008 +#define DDCAPS_ALIGNSIZESRC 0x00000010 +#define DDCAPS_ALIGNSTRIDE 0x00000020 +#define DDCAPS_BLT 0x00000040 +#define DDCAPS_BLTQUEUE 0x00000080 +#define DDCAPS_BLTFOURCC 0x00000100 +#define DDCAPS_BLTSTRETCH 0x00000200 +#define DDCAPS_GDI 0x00000400 +#define DDCAPS_OVERLAY 0x00000800 +#define DDCAPS_OVERLAYCANTCLIP 0x00001000 +#define DDCAPS_OVERLAYFOURCC 0x00002000 +#define DDCAPS_OVERLAYSTRETCH 0x00004000 +#define DDCAPS_PALETTE 0x00008000 +#define DDCAPS_PALETTEVSYNC 0x00010000 +#define DDCAPS_READSCANLINE 0x00020000 +#define DDCAPS_STEREOVIEW 0x00040000 +#define DDCAPS_VBI 0x00080000 +#define DDCAPS_ZBLTS 0x00100000 +#define DDCAPS_ZOVERLAYS 0x00200000 +#define DDCAPS_COLORKEY 0x00400000 +#define DDCAPS_ALPHA 0x00800000 +#define DDCAPS_COLORKEYHWASSIST 0x01000000 +#define DDCAPS_NOHARDWARE 0x02000000 +#define DDCAPS_BLTCOLORFILL 0x04000000 +#define DDCAPS_BANKSWITCHED 0x08000000 +#define DDCAPS_BLTDEPTHFILL 0x10000000 +#define DDCAPS_CANCLIP 0x20000000 +#define DDCAPS_CANCLIPSTRETCHED 0x40000000 +#define DDCAPS_CANBLTSYSMEM 0x80000000 + +/* dwCaps2 */ +/* driver is certified */ +#define DDCAPS2_CERTIFIED 0x00000001 +/* no 2d operations in 3d mode */ +#define DDCAPS2_NO2DDURING3DSCENE 0x00000002 + +typedef struct _DDCOLORKEY +{ + DWORD dwColorSpaceLowValue;/* low boundary of color space that is to + * be treated as Color Key, inclusive + */ + DWORD dwColorSpaceHighValue;/* high boundary of color space that is + * to be treated as Color Key, inclusive + */ +} DDCOLORKEY,*LPDDCOLORKEY; + +/* ddCKEYCAPS bits */ +#define DDCKEYCAPS_DESTBLT 0x00000001 +#define DDCKEYCAPS_DESTBLTCLRSPACE 0x00000002 +#define DDCKEYCAPS_DESTBLTCLRSPACEYUV 0x00000004 +#define DDCKEYCAPS_DESTBLTYUV 0x00000008 +#define DDCKEYCAPS_DESTOVERLAY 0x00000010 +#define DDCKEYCAPS_DESTOVERLAYCLRSPACE 0x00000020 +#define DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV 0x00000040 +#define DDCKEYCAPS_DESTOVERLAYONEACTIVE 0x00000080 +#define DDCKEYCAPS_DESTOVERLAYYUV 0x00000100 +#define DDCKEYCAPS_SRCBLT 0x00000200 +#define DDCKEYCAPS_SRCBLTCLRSPACE 0x00000400 +#define DDCKEYCAPS_SRCBLTCLRSPACEYUV 0x00000800 +#define DDCKEYCAPS_SRCBLTYUV 0x00001000 +#define DDCKEYCAPS_SRCOVERLAY 0x00002000 +#define DDCKEYCAPS_SRCOVERLAYCLRSPACE 0x00004000 +#define DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV 0x00008000 +#define DDCKEYCAPS_SRCOVERLAYONEACTIVE 0x00010000 +#define DDCKEYCAPS_SRCOVERLAYYUV 0x00020000 +#define DDCKEYCAPS_NOCOSTOVERLAY 0x00040000 + +typedef struct _DDPIXELFORMAT { + DWORD dwSize; /* size of structure */ + DWORD dwFlags; /* pixel format flags */ + DWORD dwFourCC; /* (FOURCC code) */ + union { + DWORD dwRGBBitCount; /* how many bits per pixel (BD_4,8,16,24,32)*/ + DWORD dwYUVBitCount; /* how many bits per pixel (BD_4,8,16,24,32)*/ + DWORD dwZBufferBitDepth; /* how many bits for z buffers (BD_8,16,24,32)*/ + DWORD dwAlphaBitDepth; /* how many bits for alpha channels (BD_1,2,4,8)*/ + } x; + union { + DWORD dwRBitMask; /* mask for red bit*/ + DWORD dwYBitMask; /* mask for Y bits*/ + } y; + union { + DWORD dwGBitMask; /* mask for green bits*/ + DWORD dwUBitMask; /* mask for U bits*/ + } z; + union { + DWORD dwBBitMask; /* mask for blue bits*/ + DWORD dwVBitMask; /* mask for V bits*/ + } xx; + union { + DWORD dwRGBAlphaBitMask; /* mask for alpha channel */ + DWORD dwYUVAlphaBitMask; /* mask for alpha channel */ + + } xy; +} DDPIXELFORMAT,*LPDDPIXELFORMAT; + +/* DDCAPS.dwFXCaps */ +#define DDFXCAPS_BLTARITHSTRETCHY 0x00000020 +#define DDFXCAPS_BLTARITHSTRETCHYN 0x00000010 +#define DDFXCAPS_BLTMIRRORLEFTRIGHT 0x00000040 +#define DDFXCAPS_BLTMIRRORUPDOWN 0x00000080 +#define DDFXCAPS_BLTROTATION 0x00000100 +#define DDFXCAPS_BLTROTATION90 0x00000200 +#define DDFXCAPS_BLTSHRINKX 0x00000400 +#define DDFXCAPS_BLTSHRINKXN 0x00000800 +#define DDFXCAPS_BLTSHRINKY 0x00001000 +#define DDFXCAPS_BLTSHRINKYN 0x00002000 +#define DDFXCAPS_BLTSTRETCHX 0x00004000 +#define DDFXCAPS_BLTSTRETCHXN 0x00008000 +#define DDFXCAPS_BLTSTRETCHY 0x00010000 +#define DDFXCAPS_BLTSTRETCHYN 0x00020000 +#define DDFXCAPS_OVERLAYARITHSTRETCHY 0x00040000 +#define DDFXCAPS_OVERLAYARITHSTRETCHYN 0x00000008 +#define DDFXCAPS_OVERLAYSHRINKX 0x00080000 +#define DDFXCAPS_OVERLAYSHRINKXN 0x00100000 +#define DDFXCAPS_OVERLAYSHRINKY 0x00200000 +#define DDFXCAPS_OVERLAYSHRINKYN 0x00400000 +#define DDFXCAPS_OVERLAYSTRETCHX 0x00800000 +#define DDFXCAPS_OVERLAYSTRETCHXN 0x01000000 +#define DDFXCAPS_OVERLAYSTRETCHY 0x02000000 +#define DDFXCAPS_OVERLAYSTRETCHYN 0x04000000 +#define DDFXCAPS_OVERLAYMIRRORLEFTRIGHT 0x08000000 +#define DDFXCAPS_OVERLAYMIRRORUPDOWN 0x10000000 + +/* DDCAPS.dwFXAlphaCaps */ +#define DDFXALPHACAPS_BLTALPHAEDGEBLEND 0x00000001 +#define DDFXALPHACAPS_BLTALPHAPIXELS 0x00000002 +#define DDFXALPHACAPS_BLTALPHAPIXELSNEG 0x00000004 +#define DDFXALPHACAPS_BLTALPHASURFACES 0x00000008 +#define DDFXALPHACAPS_BLTALPHASURFACESNEG 0x00000010 +#define DDFXALPHACAPS_OVERLAYALPHAEDGEBLEND 0x00000020 +#define DDFXALPHACAPS_OVERLAYALPHAPIXELS 0x00000040 +#define DDFXALPHACAPS_OVERLAYALPHAPIXELSNEG 0x00000080 +#define DDFXALPHACAPS_OVERLAYALPHASURFACES 0x00000100 +#define DDFXALPHACAPS_OVERLAYALPHASURFACESNEG 0x00000200 + +/* DDCAPS.dwPalCaps */ +#define DDPCAPS_4BIT 0x00000001 +#define DDPCAPS_8BITENTRIES 0x00000002 +#define DDPCAPS_8BIT 0x00000004 +#define DDPCAPS_INITIALIZE 0x00000008 +#define DDPCAPS_PRIMARYSURFACE 0x00000010 +#define DDPCAPS_PRIMARYSURFACELEFT 0x00000020 +#define DDPCAPS_ALLOW256 0x00000040 +#define DDPCAPS_VSYNC 0x00000080 +#define DDPCAPS_1BIT 0x00000100 +#define DDPCAPS_2BIT 0x00000200 + +/* DDCAPS.dwSVCaps */ +#define DDSVCAPS_ENIGMA 0x00000001l +#define DDSVCAPS_FLICKER 0x00000002l +#define DDSVCAPS_REDBLUE 0x00000004l +#define DDSVCAPS_SPLIT 0x00000008l + +/* BitDepths */ +#define DDBD_1 0x00004000 +#define DDBD_2 0x00002000 +#define DDBD_4 0x00001000 +#define DDBD_8 0x00000800 +#define DDBD_16 0x00000400 +#define DDBD_24 0x00000200 +#define DDBD_32 0x00000100 + +/* DDOVERLAYFX.dwDDFX */ +#define DDOVERFX_ARITHSTRETCHY 0x00000001 +#define DDOVERFX_MIRRORLEFTRIGHT 0x00000002 +#define DDOVERFX_MIRRORUPDOWN 0x00000004 + +/* DDCOLORKEY.dwFlags */ +#define DDPF_ALPHAPIXELS 0x00000001 +#define DDPF_ALPHA 0x00000002 +#define DDPF_FOURCC 0x00000004 +#define DDPF_PALETTEINDEXED4 0x00000008 +#define DDPF_PALETTEINDEXEDTO8 0x00000010 +#define DDPF_PALETTEINDEXED8 0x00000020 +#define DDPF_RGB 0x00000040 +#define DDPF_COMPRESSED 0x00000080 +#define DDPF_RGBTOYUV 0x00000100 +#define DDPF_YUV 0x00000200 +#define DDPF_ZBUFFER 0x00000400 +#define DDPF_PALETTEINDEXED1 0x00000800 +#define DDPF_PALETTEINDEXED2 0x00001000 + +/* SetCooperativeLevel dwFlags */ +#define DDSCL_FULLSCREEN 0x00000001 +#define DDSCL_ALLOWREBOOT 0x00000002 +#define DDSCL_NOWINDOWCHANGES 0x00000004 +#define DDSCL_NORMAL 0x00000008 +#define DDSCL_EXCLUSIVE 0x00000010 +#define DDSCL_ALLOWMODEX 0x00000040 + +typedef struct _DDSURFACEDESC +{ + DWORD dwSize; /* size of the DDSURFACEDESC structure*/ + DWORD dwFlags;/* determines what fields are valid*/ + DWORD dwHeight;/* height of surface to be created*/ + DWORD dwWidth;/* width of input surface*/ + LONG lPitch; /* distance to start of next line (return value only)*/ + DWORD dwBackBufferCount; /* number of back buffers requested*/ + union { + DWORD dwMipMapCount; /* number of mip-map levels requested*/ + DWORD dwZBufferBitDepth;/* depth of Z buffer requested*/ + DWORD dwRefreshRate; /* refresh rate (used when display mode is described)*/ + } x; + DWORD dwAlphaBitDepth; /* depth of alpha buffer requested*/ + DWORD dwReserved; /* reserved*/ + LPVOID lpSurface; /* pointer to the associated surface memory*/ + DDCOLORKEY ddckCKDestOverlay;/* color key for destination overlay use*/ + DDCOLORKEY ddckCKDestBlt;/* color key for destination blt use*/ + DDCOLORKEY ddckCKSrcOverlay;/* color key for source overlay use*/ + DDCOLORKEY ddckCKSrcBlt;/* color key for source blt use*/ + DDPIXELFORMAT ddpfPixelFormat;/* pixel format description of the surface*/ + DDSCAPS ddsCaps;/* direct draw surface capabilities*/ +} DDSURFACEDESC,*LPDDSURFACEDESC; + +typedef BOOL32 (CALLBACK * LPDDENUMCALLBACK32A)(GUID *, LPSTR, LPSTR, LPVOID); +typedef BOOL32 (CALLBACK * LPDDENUMCALLBACK32W)(GUID *, LPWSTR, LPWSTR, LPVOID); +DECL_WINELIB_TYPE_AW(LPDDENUMCALLBACK) + +typedef HRESULT (CALLBACK * LPDDENUMMODESCALLBACK)(LPDDSURFACEDESC, LPVOID); +typedef HRESULT (CALLBACK * LPDDENUMSURFACESCALLBACK)(LPDIRECTDRAWSURFACE, LPDDSURFACEDESC, LPVOID); + +/* dwFlags field... which are valid */ + +#define DDSD_CAPS 0x00000001 +#define DDSD_HEIGHT 0x00000002 +#define DDSD_WIDTH 0x00000004 +#define DDSD_PITCH 0x00000008 +#define DDSD_BACKBUFFERCOUNT 0x00000020 +#define DDSD_ZBUFFERBITDEPTH 0x00000040 +#define DDSD_ALPHABITDEPTH 0x00000080 +#define DDSD_PIXELFORMAT 0x00001000 +#define DDSD_CKDESTOVERLAY 0x00002000 +#define DDSD_CKDESTBLT 0x00004000 +#define DDSD_CKSRCOVERLAY 0x00008000 +#define DDSD_CKSRCBLT 0x00010000 +#define DDSD_MIPMAPCOUNT 0x00020000 +#define DDSD_REFRESHRATE 0x00040000 +#define DDSD_ALL 0x0007f9ee + +typedef struct _DDBLTFX +{ + DWORD dwSize; /* size of structure */ + DWORD dwDDFX; /* FX operations */ + DWORD dwROP; /* Win32 raster operations */ + DWORD dwDDROP; /* Raster operations new for DirectDraw */ + DWORD dwRotationAngle; /* Rotation angle for blt */ + DWORD dwZBufferOpCode; /* ZBuffer compares */ + DWORD dwZBufferLow; /* Low limit of Z buffer */ + DWORD dwZBufferHigh; /* High limit of Z buffer */ + DWORD dwZBufferBaseDest; /* Destination base value */ + DWORD dwZDestConstBitDepth; /* Bit depth used to specify Z constant for destination */ + union + { + DWORD dwZDestConst; /* Constant to use as Z buffer for dest */ + LPDIRECTDRAWSURFACE lpDDSZBufferDest; /* Surface to use as Z buffer for dest */ + } x; + DWORD dwZSrcConstBitDepth; /* Bit depth used to specify Z constant for source */ + union + { + DWORD dwZSrcConst; /* Constant to use as Z buffer for src */ + LPDIRECTDRAWSURFACE lpDDSZBufferSrc; /* Surface to use as Z buffer for src */ + } y; + DWORD dwAlphaEdgeBlendBitDepth; /* Bit depth used to specify constant for alpha edge blend */ + DWORD dwAlphaEdgeBlend; /* Alpha for edge blending */ + DWORD dwReserved; + DWORD dwAlphaDestConstBitDepth; /* Bit depth used to specify alpha constant for destination */ + union + { + DWORD dwAlphaDestConst; /* Constant to use as Alpha Channel */ + LPDIRECTDRAWSURFACE lpDDSAlphaDest; /* Surface to use as Alpha Channel */ + } z; + DWORD dwAlphaSrcConstBitDepth; /* Bit depth used to specify alpha constant for source */ + union + { + DWORD dwAlphaSrcConst; /* Constant to use as Alpha Channel */ + LPDIRECTDRAWSURFACE lpDDSAlphaSrc; /* Surface to use as Alpha Channel */ + } a; + union + { + DWORD dwFillColor; /* color in RGB or Palettized */ + DWORD dwFillDepth; /* depth value for z-buffer */ + LPDIRECTDRAWSURFACE lpDDSPattern; /* Surface to use as pattern */ + } b; + DDCOLORKEY ddckDestColorkey; /* DestColorkey override */ + DDCOLORKEY ddckSrcColorkey; /* SrcColorkey override */ +} DDBLTFX,*LPDDBLTFX; + +/* dwDDFX */ +/* arithmetic stretching along y axis */ +#define DDBLTFX_ARITHSTRETCHY 0x00000001 +/* mirror on y axis */ +#define DDBLTFX_MIRRORLEFTRIGHT 0x00000002 +/* mirror on x axis */ +#define DDBLTFX_MIRRORUPDOWN 0x00000004 +/* do not tear */ +#define DDBLTFX_NOTEARING 0x00000008 +/* 180 degrees clockwise rotation */ +#define DDBLTFX_ROTATE180 0x00000010 +/* 270 degrees clockwise rotation */ +#define DDBLTFX_ROTATE270 0x00000020 +/* 90 degrees clockwise rotation */ +#define DDBLTFX_ROTATE90 0x00000040 +/* dwZBufferLow and dwZBufferHigh specify limits to the copied Z values */ +#define DDBLTFX_ZBUFFERRANGE 0x00000080 +/* add dwZBufferBaseDest to every source z value before compare */ +#define DDBLTFX_ZBUFFERBASEDEST 0x00000100 + +typedef struct _DDOVERLAYFX +{ + DWORD dwSize; /* size of structure */ + DWORD dwAlphaEdgeBlendBitDepth; /* Bit depth used to specify constant for alpha edge blend */ + DWORD dwAlphaEdgeBlend; /* Constant to use as alpha for edge blend */ + DWORD dwReserved; + DWORD dwAlphaDestConstBitDepth; /* Bit depth used to specify alpha constant for destination */ + union + { + DWORD dwAlphaDestConst; /* Constant to use as alpha channel for dest */ + LPDIRECTDRAWSURFACE lpDDSAlphaDest; /* Surface to use as alpha channel for dest */ + } x; + DWORD dwAlphaSrcConstBitDepth; /* Bit depth used to specify alpha constant for source */ + union + { + DWORD dwAlphaSrcConst; /* Constant to use as alpha channel for src */ + LPDIRECTDRAWSURFACE lpDDSAlphaSrc; /* Surface to use as alpha channel for src */ + } y; + DDCOLORKEY dckDestColorkey; /* DestColorkey override */ + DDCOLORKEY dckSrcColorkey; /* DestColorkey override */ + DWORD dwDDFX; /* Overlay FX */ + DWORD dwFlags; /* flags */ +} DDOVERLAYFX,*LPDDOVERLAYFX; + +typedef struct _DDBLTBATCH +{ + LPRECT32 lprDest; + LPDIRECTDRAWSURFACE lpDDSSrc; + LPRECT32 lprSrc; + DWORD dwFlags; + LPDDBLTFX lpDDBltFx; +} DDBLTBATCH,*LPDDBLTBATCH; + +#define STDMETHOD(xfn) HRESULT (CALLBACK *fn##xfn) +#define STDMETHOD_(ret,xfn) ret (CALLBACK *fn##xfn) +#define PURE +#define FAR +#define ULONG DWORD +#define THIS_ THIS , + +#define THIS LPDIRECTDRAWPALETTE this + +typedef struct IDirectDrawPalette_VTable { + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IDirectDrawPalette methods ***/ + STDMETHOD(GetCaps)(THIS_ LPDWORD) PURE; + STDMETHOD(GetEntries)(THIS_ DWORD,DWORD,DWORD,LPPALETTEENTRY) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, DWORD, LPPALETTEENTRY) PURE; + STDMETHOD(SetEntries)(THIS_ DWORD,DWORD,DWORD,LPPALETTEENTRY) PURE; +} *LPDIRECTDRAWPALETTE_VTABLE,IDirectDrawPalette_VTable; + +struct IDirectDrawPalette { + LPDIRECTDRAWPALETTE_VTABLE lpvtbl; + DWORD ref; + LPDIRECTDRAW ddraw; + Colormap cm; +}; +#undef THIS + +#define THIS LPDIRECTDRAWCLIPPER this +typedef struct IDirectDrawClipper_VTable { + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IDirectDrawClipper methods ***/ + STDMETHOD(GetClipList)(THIS_ LPRECT32, LPRGNDATA, LPDWORD) PURE; + STDMETHOD(GetHWnd)(THIS_ HWND32 FAR *) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, DWORD) PURE; + STDMETHOD(IsClipListChanged)(THIS_ BOOL32 FAR *) PURE; + STDMETHOD(SetClipList)(THIS_ LPRGNDATA,DWORD) PURE; + STDMETHOD(SetHWnd)(THIS_ DWORD, HWND32 ) PURE; +} *LPDIRECTDRAWCLIPPER_VTABLE,IDirectDrawClipper_VTable; + +struct IDirectDrawClipper { + LPDIRECTDRAWCLIPPER_VTABLE lpvtbl; + DWORD ref; +}; +#undef THIS + +#define THIS LPDIRECTDRAW this +typedef struct IDirectDraw_VTable { + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IDirectDraw methods ***/ + STDMETHOD(Compact)(THIS) PURE; + STDMETHOD(CreateClipper)(THIS_ DWORD, LPDIRECTDRAWCLIPPER FAR*, IUnknown FAR * ) PURE; + STDMETHOD(CreatePalette)(THIS_ DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE FAR*, IUnknown FAR * ) PURE; + STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC *lpddsd, LPDIRECTDRAWSURFACE FAR *, +IUnknown FAR *) PURE; + STDMETHOD(DuplicateSurface)( THIS_ LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE +FAR * ) PURE; + STDMETHOD(EnumDisplayModes)( THIS_ DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK ) PURE; + STDMETHOD(EnumSurfaces)(THIS_ DWORD, LPDDSURFACEDESC, LPVOID,LPDDENUMSURFACESCALLBACK ) PURE; + STDMETHOD(FlipToGDISurface)(THIS) PURE; + STDMETHOD(GetCaps)( THIS_ LPDDCAPS, LPDDCAPS) PURE; + STDMETHOD(GetDisplayMode)( THIS_ LPDDSURFACEDESC) PURE; + STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD, LPDWORD ) PURE; + STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE FAR *) PURE; + STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD) PURE; + STDMETHOD(GetScanLine)(THIS_ LPDWORD) PURE; + STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL32* ) PURE; + STDMETHOD(Initialize)(THIS_ GUID FAR *) PURE; + STDMETHOD(RestoreDisplayMode)(THIS) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND32, DWORD) PURE; + STDMETHOD(SetDisplayMode)(THIS_ DWORD width, DWORD height,DWORD depth) PURE; + STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD, HANDLE32 ) PURE; +} *LPDIRECTDRAW_VTABLE,IDirectDraw_VTable; + +struct _directdrawdata { + DWORD depth; + DWORD vp_width,vp_height; /* viewport dimension */ + DWORD height,width; /* SetDisplayMode */ + DWORD current_height,fb_width,fb_height,fb_banksize,fb_memsize; + HWND32 mainwindow; + void *fb_addr; +}; + + +struct IDirectDraw { + LPDIRECTDRAW_VTABLE lpvtbl; + DWORD ref; + struct _directdrawdata d; +}; + +/* flags for Lock() */ +/* The default. Set to indicate that Lock should return a valid memory pointer + * to the top of the specified rectangle. If no rectangle is specified then a + * pointer to the top of the surface is returned. + */ +#define DDLOCK_SURFACEMEMORYPTR 0x00000000L +/* Set to indicate that Lock should wait until it can obtain a valid memory + * pointer before returning. If this bit is set, Lock will never return + * DDERR_WASSTILLDRAWING. + */ +#define DDLOCK_WAIT 0x00000001L +/* Set if an event handle is being passed to Lock. Lock will trigger the event + * when it can return the surface memory pointer requested. + */ +#define DDLOCK_EVENT 0x00000002L +/* Indicates that the surface being locked will only be read from. */ +#define DDLOCK_READONLY 0x00000010L +/* Indicates that the surface being locked will only be written to */ +#define DDLOCK_WRITEONLY 0x00000020L + +#undef THIS + +#define THIS LPDIRECTDRAW2 this +typedef struct IDirectDraw2_VTable +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IDirectDraw methods ***/ + STDMETHOD(Compact)(THIS) PURE; + STDMETHOD(CreateClipper)(THIS_ DWORD, LPDIRECTDRAWCLIPPER FAR*, IUnknown FAR * ) PURE; + STDMETHOD(CreatePalette)(THIS_ DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE FAR*, IUnknown FAR * ) PURE; + STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC, LPDIRECTDRAWSURFACE FAR *, +IUnknown FAR *) PURE; + STDMETHOD(DuplicateSurface)( THIS_ LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE +FAR * ) PURE; + STDMETHOD(EnumDisplayModes)( THIS_ DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK ) PURE; + STDMETHOD(EnumSurfaces)(THIS_ DWORD, LPDDSURFACEDESC, LPVOID,LPDDENUMSURFACESCALLBACK ) PURE; + STDMETHOD(FlipToGDISurface)(THIS) PURE; + STDMETHOD(GetCaps)( THIS_ LPDDCAPS, LPDDCAPS) PURE; + STDMETHOD(GetDisplayMode)( THIS_ LPDDSURFACEDESC) PURE; + STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD, LPDWORD ) PURE; + STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE FAR *) PURE; + STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD) PURE; + STDMETHOD(GetScanLine)(THIS_ LPDWORD) PURE; + STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL32* ) PURE; + STDMETHOD(Initialize)(THIS_ GUID FAR *) PURE; + STDMETHOD(RestoreDisplayMode)(THIS) PURE; + STDMETHOD(SetCooperativeLevel)(THIS_ HWND32, DWORD) PURE; + STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD,DWORD, DWORD, DWORD) PURE; + STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD, HANDLE32 ) PURE; + /*** Added in the v2 interface ***/ + STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS, LPDWORD, LPDWORD) PURE; +} IDirectDraw2_VTable,*LPDIRECTDRAW2_VTABLE; +/* MUST HAVE THE SAME LAYOUT AS struct IDirectDraw */ + +struct IDirectDraw2 { + LPDIRECTDRAW2_VTABLE lpvtbl; + DWORD ref; + struct _directdrawdata d; +}; +#undef THIS + +#define THIS LPDIRECTDRAWSURFACE this +typedef struct IDirectDrawSurface_VTable { + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IDirectDrawSurface methods ***/ + STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE) PURE; + STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT32) PURE; + STDMETHOD(Blt)(THIS_ LPRECT32,LPDIRECTDRAWSURFACE, LPRECT32,DWORD, LPDDBLTFX) PURE; + STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH, DWORD, DWORD ) PURE; + STDMETHOD(BltFast)(THIS_ DWORD,DWORD,LPDIRECTDRAWSURFACE, LPRECT32,DWORD) PURE; + STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD,LPDIRECTDRAWSURFACE) PURE; + STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK) PURE; STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK) PURE; + STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE, DWORD) PURE; + STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS, LPDIRECTDRAWSURFACE FAR *) PURE; + STDMETHOD(GetBltStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDSCAPS) PURE; + STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER FAR*) PURE; + STDMETHOD(GetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(GetDC)(THIS_ HDC32 FAR *) PURE; + STDMETHOD(GetFlipStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetOverlayPosition)(THIS_ LPLONG, LPLONG ) PURE; + STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE FAR*) PURE; + STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT) PURE; + STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC) PURE; + STDMETHOD(IsLost)(THIS) PURE; + STDMETHOD(Lock)(THIS_ LPRECT32,LPDDSURFACEDESC,DWORD flags,HANDLE32) PURE; + STDMETHOD(ReleaseDC)(THIS_ HDC32) PURE; + STDMETHOD(Restore)(THIS) PURE; + STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER) PURE; + STDMETHOD(SetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(SetOverlayPosition)(THIS_ LONG, LONG ) PURE; + STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE) PURE; + STDMETHOD(Unlock)(THIS_ LPVOID) PURE; + STDMETHOD(UpdateOverlay)(THIS_ LPRECT32, LPDIRECTDRAWSURFACE,LPRECT32,DWORD, LPDDOVERLAYFX) PURE; + STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD) PURE; + STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD, LPDIRECTDRAWSURFACE) PURE; +} *LPDIRECTDRAWSURFACE_VTABLE,IDirectDrawSurface_VTable; + +struct IDirectDrawSurface { + LPDIRECTDRAWSURFACE_VTABLE lpvtbl; + DWORD ref; + LPVOID surface; + LPDIRECTDRAWPALETTE palette; + DWORD fb_height,lpitch,width,height; + LPDIRECTDRAW ddraw; +}; +#undef THIS +#define THIS LPDIRECTDRAWSURFACE2 this + +typedef struct IDirectDrawSurface2_VTable { + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IDirectDrawSurface methods ***/ + STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE2) PURE; + STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT32) PURE; + STDMETHOD(Blt)(THIS_ LPRECT32,LPDIRECTDRAWSURFACE2, LPRECT32,DWORD, LPDDBLTFX) PURE; + STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH, DWORD, DWORD ) PURE; + STDMETHOD(BltFast)(THIS_ DWORD,DWORD,LPDIRECTDRAWSURFACE2, LPRECT32,DWORD) PURE; + STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD,LPDIRECTDRAWSURFACE2) PURE; + STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK) PURE; STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK) PURE; + STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE2, DWORD) PURE; + STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS, LPDIRECTDRAWSURFACE2 FAR *) PURE; + STDMETHOD(GetBltStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetCaps)(THIS_ LPDDSCAPS) PURE; + STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER FAR*) PURE; + STDMETHOD(GetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(GetDC)(THIS_ HDC32 FAR *) PURE; + STDMETHOD(GetFlipStatus)(THIS_ DWORD) PURE; + STDMETHOD(GetOverlayPosition)(THIS_ LPLONG, LPLONG ) PURE; + STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE FAR*) PURE; + STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT) PURE; + STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC) PURE; + STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC) PURE; + STDMETHOD(IsLost)(THIS) PURE; + STDMETHOD(Lock)(THIS_ LPRECT32,LPDDSURFACEDESC,DWORD,HANDLE32) PURE; + STDMETHOD(ReleaseDC)(THIS_ HDC32) PURE; + STDMETHOD(Restore)(THIS) PURE; + STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER) PURE; + STDMETHOD(SetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE; + STDMETHOD(SetOverlayPosition)(THIS_ LONG, LONG ) PURE; + STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE) PURE; + STDMETHOD(Unlock)(THIS_ LPVOID) PURE; + STDMETHOD(UpdateOverlay)(THIS_ LPRECT32, LPDIRECTDRAWSURFACE2,LPRECT32,DWORD, LPDDOVERLAYFX) PURE; + STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD) PURE; + STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD, LPDIRECTDRAWSURFACE2) PURE; + /*** Added in the v2 interface ***/ + STDMETHOD(GetDDInterface)(THIS_ LPVOID FAR *) PURE; + STDMETHOD(PageLock)(THIS_ DWORD) PURE; + STDMETHOD(PageUnlock)(THIS_ DWORD) PURE; +} *LPDIRECTDRAWSURFACE2_VTABLE,IDirectDrawSurface2_VTable; + +struct IDirectDrawSurface2 { + LPDIRECTDRAWSURFACE2_VTABLE lpvtbl; + DWORD ref; + LPVOID surface; + LPDIRECTDRAWPALETTE palette; + DWORD fb_height,lpitch,width,height; + LPDIRECTDRAW ddraw; +}; +#undef THIS + +#undef THIS_ +#undef PURE +#undef FAR +#undef STDMETHOD +#undef STDMETHOD_ + +extern HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID,LPDIRECTDRAW *lplpDD,LPUNKNOWN pUnkOuter ); +#endif diff --git a/include/dsound.h b/include/dsound.h new file mode 100644 index 00000000000..61d042bb82e --- /dev/null +++ b/include/dsound.h @@ -0,0 +1,187 @@ +#ifndef __WINE_DSOUND_H +#define __WINE_DSOUND_H + +#include "mmsystem.h" + +/* Direct Sound Component GUID {47D4D946-62E8-11cf-93BC-444553540000} */ +DEFINE_GUID(CLSID_DirectSound,0x47d4d946, 0x62e8, 0x11cf, 0x93, 0xbc, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0); + +/* DirectSound 279afa83-4981-11ce-a521-0020af0be560 */ +DEFINE_GUID(IID_IDirectSound,0x279AFA83,0x4981,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60); +/* DirectSoundBuffer 279afa85-4981-11ce-a521-0020af0be560 */ +DEFINE_GUID(IID_IDirectSoundBuffer,0x279AFA85,0x4981,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60); + +typedef struct IDirectSound IDirectSound,*LPDIRECTSOUND; +typedef struct IDirectSoundBuffer IDirectSoundBuffer,*LPDIRECTSOUNDBUFFER,**LPLPDIRECTSOUNDBUFFER; + +#define DSCAPS_PRIMARYMONO 0x00000001 +#define DSCAPS_PRIMARYSTEREO 0x00000002 +#define DSCAPS_PRIMARY8BIT 0x00000004 +#define DSCAPS_PRIMARY16BIT 0x00000008 +#define DSCAPS_CONTINUOUSRATE 0x00000010 +#define DSCAPS_EMULDRIVER 0x00000020 +#define DSCAPS_CERTIFIED 0x00000040 +#define DSCAPS_SECONDARYMONO 0x00000100 +#define DSCAPS_SECONDARYSTEREO 0x00000200 +#define DSCAPS_SECONDARY8BIT 0x00000400 +#define DSCAPS_SECONDARY16BIT 0x00000800 + +typedef struct _DSCAPS +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwMinSecondarySampleRate; + DWORD dwMaxSecondarySampleRate; + DWORD dwPrimaryBuffers; + DWORD dwMaxHwMixingAllBuffers; + DWORD dwMaxHwMixingStaticBuffers; + DWORD dwMaxHwMixingStreamingBuffers; + DWORD dwFreeHwMixingAllBuffers; + DWORD dwFreeHwMixingStaticBuffers; + DWORD dwFreeHwMixingStreamingBuffers; + DWORD dwMaxHw3DAllBuffers; + DWORD dwMaxHw3DStaticBuffers; + DWORD dwMaxHw3DStreamingBuffers; + DWORD dwFreeHw3DAllBuffers; + DWORD dwFreeHw3DStaticBuffers; + DWORD dwFreeHw3DStreamingBuffers; + DWORD dwTotalHwMemBytes; + DWORD dwFreeHwMemBytes; + DWORD dwMaxContigFreeHwMemBytes; + DWORD dwUnlockTransferRateHwBuffers; + DWORD dwPlayCpuOverheadSwBuffers; + DWORD dwReserved1; + DWORD dwReserved2; +} DSCAPS,*LPDSCAPS; + +#define DSBPLAY_LOOPING 0x00000001 + +#define DSBSTATUS_PLAYING 0x00000001 +#define DSBSTATUS_BUFFERLOST 0x00000002 +#define DSBSTATUS_LOOPING 0x00000004 + + +#define DSBLOCK_FROMWRITECURSOR 0x00000001 + +#define DSBCAPS_PRIMARYBUFFER 0x00000001 +#define DSBCAPS_STATIC 0x00000002 +#define DSBCAPS_LOCHARDWARE 0x00000004 +#define DSBCAPS_LOCSOFTWARE 0x00000008 +#define DSBCAPS_CTRLFREQUENCY 0x00000020 +#define DSBCAPS_CTRLPAN 0x00000040 +#define DSBCAPS_CTRLVOLUME 0x00000080 +#define DSBCAPS_CTRLDEFAULT 0x000000E0 /* Pan + volume + frequency. */ +#define DSBCAPS_CTRLALL 0x000000E0 /* All control capabilities */ +#define DSBCAPS_STICKYFOCUS 0x00004000 +#define DSBCAPS_GETCURRENTPOSITION2 0x00010000 /* More accurate play cursor under emulation*/ + +typedef struct _DSBCAPS +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwUnlockTransferRate; + DWORD dwPlayCpuOverhead; +} DSBCAPS,*LPDSBCAPS; + +#define DSSCL_NORMAL 1 +#define DSSCL_PRIORITY 2 +#define DSSCL_EXCLUSIVE 3 +#define DSSCL_WRITEPRIMARY 4 + +typedef struct _DSBUFFERDESC +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwBufferBytes; + DWORD dwReserved; + LPWAVEFORMATEX lpwfxFormat; +} DSBUFFERDESC,*LPDSBUFFERDESC; + + + +#define DSSPEAKER_HEADPHONE 1 +#define DSSPEAKER_MONO 2 +#define DSSPEAKER_QUAD 3 +#define DSSPEAKER_STEREO 4 +#define DSSPEAKER_SURROUND 5 + + + +typedef LPVOID* LPLPVOID; + +typedef BOOL32 (CALLBACK *LPDSENUMCALLBACK32W)(LPGUID,LPWSTR,LPWSTR,LPVOID); +typedef BOOL32 (CALLBACK *LPDSENUMCALLBACK32A)(LPGUID,LPSTR,LPSTR,LPVOID); + +extern HRESULT WINAPI DirectSoundCreate(LPGUID lpGUID,LPDIRECTSOUND * ppDS,IUnknown *pUnkOuter ); + +#define STDMETHOD(xfn) HRESULT (CALLBACK *fn##xfn) +#define STDMETHOD_(ret,xfn) ret (CALLBACK *fn##xfn) +#define PURE +#define FAR +#define ULONG DWORD + +#define THIS LPDIRECTSOUND this +#define THIS_ LPDIRECTSOUND this, + +typedef struct tagLPDIRECTSOUND_VTABLE +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IDirectSound methods ***/ + + STDMETHOD( CreateSoundBuffer)(THIS_ LPDSBUFFERDESC, LPLPDIRECTSOUNDBUFFER, IUnknown FAR *) PURE; + STDMETHOD( GetCaps)(THIS_ LPDSCAPS ) PURE; + STDMETHOD( DuplicateSoundBuffer)(THIS_ LPDIRECTSOUNDBUFFER, LPLPDIRECTSOUNDBUFFER ) PURE; + STDMETHOD( SetCooperativeLevel)(THIS_ HWND32, DWORD ) PURE; + STDMETHOD( Compact)(THIS ) PURE; + STDMETHOD( GetSpeakerConfig)(THIS_ LPDWORD ) PURE; + STDMETHOD( SetSpeakerConfig)(THIS_ DWORD ) PURE; + STDMETHOD( Initialize)(THIS_ GUID FAR * ) PURE; +} *LPDIRECTSOUND_VTABLE; + +struct IDirectSound { + LPDIRECTSOUND_VTABLE lpvtbl; + DWORD ref; +}; + +#undef THIS +#undef THIS_ +#define THIS LPDIRECTSOUNDBUFFER this +#define THIS_ LPDIRECTSOUNDBUFFER this, +typedef struct tagLPDIRECTSOUNDBUFFER_VTABLE +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + /*** IDirectSoundBuffer methods ***/ + + STDMETHOD( GetCaps)(THIS_ LPDSBCAPS ) PURE; + STDMETHOD(GetCurrentPosition)(THIS_ LPDWORD,LPDWORD ) PURE; + STDMETHOD( GetFormat)(THIS_ LPWAVEFORMATEX, DWORD, LPDWORD ) PURE; + STDMETHOD( GetVolume)(THIS_ LPLONG ) PURE; + STDMETHOD( GetPan)(THIS_ LPLONG ) PURE; + STDMETHOD( GetFrequency)(THIS_ LPDWORD ) PURE; + STDMETHOD( GetStatus)(THIS_ LPDWORD ) PURE; + STDMETHOD( Initialize)(THIS_ LPDIRECTSOUND, LPDSBUFFERDESC ) PURE; + STDMETHOD( Lock)(THIS_ DWORD,DWORD,LPVOID,LPDWORD,LPVOID,LPDWORD,DWORD ) PURE; + STDMETHOD( Play)(THIS_ DWORD,DWORD,DWORD ) PURE; + STDMETHOD(SetCurrentPosition)(THIS_ DWORD ) PURE; + STDMETHOD( SetFormat)(THIS_ LPWAVEFORMATEX ) PURE; + STDMETHOD( SetVolume)(THIS_ LONG ) PURE; + STDMETHOD( SetPan)(THIS_ LONG ) PURE; + STDMETHOD( SetFrequency)(THIS_ DWORD ) PURE; + STDMETHOD( Stop)(THIS ) PURE; + STDMETHOD( Unlock)(THIS_ LPVOID,DWORD,LPVOID,DWORD ) PURE; + STDMETHOD( Restore)(THIS ) PURE; +} *LPDIRECTSOUNDBUFFER_VTABLE; + +struct IDirectSoundBuffer { + LPDIRECTSOUNDBUFFER_VTABLE lpvtbl; + DWORD ref; +}; + +#endif diff --git a/include/file.h b/include/file.h index badc67aecea..de43e1b542e 100644 --- a/include/file.h +++ b/include/file.h @@ -9,7 +9,7 @@ #include #include "windows.h" -#include "handle32.h" +#include "k32obj.h" #define MAX_PATHNAME_LEN 1024 @@ -35,7 +35,6 @@ typedef struct /* files/file.c */ -extern void FILE_Destroy( K32OBJ *ptr ); extern void FILE_SetDosError(void); extern HFILE32 FILE_DupUnixHandle( int fd ); extern BOOL32 FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info ); diff --git a/include/heap.h b/include/heap.h index 8459eba28fc..82f26e2ba04 100644 --- a/include/heap.h +++ b/include/heap.h @@ -12,6 +12,7 @@ extern HANDLE32 SystemHeap; extern HANDLE32 SegptrHeap; +extern CRITICAL_SECTION *HEAP_SystemLock; extern int HEAP_IsInsideHeap( HANDLE32 heap, DWORD flags, LPCVOID ptr ); extern SEGPTR HEAP_GetSegptr( HANDLE32 heap, DWORD flags, LPCVOID ptr ); @@ -36,4 +37,11 @@ extern LPSTR HEAP_strdupWtoA( HANDLE32 heap, DWORD flags, LPCWSTR str ); #define SEGPTR_FREE(ptr) \ (HIWORD(ptr) ? HeapFree( SegptrHeap, 0, (ptr) ) : 0) +/* System heap locking macros */ + +#define SYSTEM_LOCK() (EnterCriticalSection(HEAP_SystemLock)) +#define SYSTEM_UNLOCK() (LeaveCriticalSection(HEAP_SystemLock)) +/* Use this one only when you own the lock! */ +#define SYSTEM_LOCK_COUNT() (HEAP_SystemLock->RecursionCount) + #endif /* __WINE_HEAP_H */ diff --git a/include/handle32.h b/include/k32obj.h similarity index 50% rename from include/handle32.h rename to include/k32obj.h index 9e5fca02008..afe3c94c1a6 100644 --- a/include/handle32.h +++ b/include/k32obj.h @@ -1,11 +1,11 @@ /* * KERNEL32 objects * - * Copyright 1996 Alexandre Julliard + * Copyright 1996, 1998 Alexandre Julliard */ -#ifndef __WINE_HANDLE32_H -#define __WINE_HANDLE32_H +#ifndef __WINE_K32OBJ_H +#define __WINE_K32OBJ_H #include "wintypes.h" @@ -37,32 +37,30 @@ typedef enum typedef struct { K32OBJ_TYPE type; - DWORD refcount; + LONG refcount; } K32OBJ; -/* Kernel object list entry */ -typedef struct _K32OBJ_ENTRY -{ - K32OBJ *obj; - struct _K32OBJ_ENTRY *next; - struct _K32OBJ_ENTRY *prev; -} K32OBJ_ENTRY; - -/* Kernel object list */ +/* Kernel object operations */ typedef struct { - K32OBJ_ENTRY *head; - K32OBJ_ENTRY *tail; -} K32OBJ_LIST; + BOOL32 (*signaled)(K32OBJ*,DWORD); /* Is object signaled? */ + void (*satisfied)(K32OBJ*,DWORD); /* Wait on object is satisfied */ + void (*add_wait)(K32OBJ*,DWORD); /* Add thread to wait queue */ + void (*remove_wait)(K32OBJ*,DWORD); /* Remove thread from wait queue */ + void (*destroy)(K32OBJ *); /* Destroy object on refcount==0 */ +} K32OBJ_OPS; + +extern const K32OBJ_OPS * const K32OBJ_Ops[K32OBJ_NBOBJECTS]; + +#define K32OBJ_OPS(obj) (K32OBJ_Ops[(obj)->type]) extern void K32OBJ_IncCount( K32OBJ *ptr ); extern void K32OBJ_DecCount( K32OBJ *ptr ); -extern void K32OBJ_AddHead( K32OBJ_LIST *list, K32OBJ *ptr ); -extern void K32OBJ_AddTail( K32OBJ_LIST *list, K32OBJ *ptr ); -extern void K32OBJ_Remove( K32OBJ_LIST *list, K32OBJ *ptr ); -extern K32OBJ *K32OBJ_RemoveHead( K32OBJ_LIST *list ); +extern BOOL32 K32OBJ_IsValid( K32OBJ *ptr, K32OBJ_TYPE type ); extern BOOL32 K32OBJ_AddName( K32OBJ *obj, LPCSTR name ); +extern K32OBJ *K32OBJ_Create( K32OBJ_TYPE type, DWORD size, LPCSTR name, + HANDLE32 *handle ); extern K32OBJ *K32OBJ_FindName( LPCSTR name ); extern K32OBJ *K32OBJ_FindNameType( LPCSTR name, K32OBJ_TYPE type ); -#endif /* __WINE_HANDLE32_H */ +#endif /* __WINE_K32OBJ_H */ diff --git a/include/mmsystem.h b/include/mmsystem.h index 6845f3594e3..493b7ac0d39 100644 --- a/include/mmsystem.h +++ b/include/mmsystem.h @@ -875,8 +875,8 @@ typedef struct { WCHAR szRegKey[MAXPNAMELEN]; WCHAR szOEMVxD[MAX_JOYSTICKOEMVXDNAME]; } JOYCAPS32W, *LPJOYCAPS32W; -DECL_WINELIB_TYPE_AW(JOYCAPS) -DECL_WINELIB_TYPE_AW(LPJOYCAPS) +DECL_WINELIB_TYPE_AW(JOYCAPS); +DECL_WINELIB_TYPE_AW(LPJOYCAPS); typedef struct { UINT16 wXpos; /* x position */ @@ -892,8 +892,8 @@ typedef struct { UINT32 wButtons; } JOYINFO32, *LPJOYINFO32; -DECL_WINELIB_TYPE(JOYINFO) -DECL_WINELIB_TYPE(LPJOYINFO) +DECL_WINELIB_TYPE(JOYINFO); +DECL_WINELIB_TYPE(LPJOYINFO); MMRESULT16 WINAPI joyGetDevCaps16 (UINT16,LPJOYCAPS16 ,UINT16); MMRESULT32 WINAPI joyGetDevCaps32A(UINT32,LPJOYCAPS32A,UINT32); diff --git a/include/process.h b/include/process.h index 3cbd14cca3c..ca0014f8116 100644 --- a/include/process.h +++ b/include/process.h @@ -10,7 +10,7 @@ #include "windows.h" #include "winbase.h" #include "winnt.h" -#include "handle32.h" +#include "k32obj.h" #include "pe_image.h" #include "task.h" @@ -98,13 +98,20 @@ typedef struct _PDB32 LCID locale; /* c4 Locale to be queried by GetThreadLocale (NT) */ } PDB32; +/* PDB <-> Process id conversion macros */ +#define PROCESS_OBFUSCATOR ((DWORD)0xdeadbeef) +#define PROCESS_ID_TO_PDB(id) ((PDB32 *)((id) ^ PROCESS_OBFUSCATOR)) +#define PDB_TO_PROCESS_ID(pdb) ((DWORD)(pdb) ^ PROCESS_OBFUSCATOR) + +/* scheduler/process.c */ extern HANDLE32 PROCESS_AllocHandle( K32OBJ *ptr, DWORD flags); extern K32OBJ *PROCESS_GetObjPtr( HANDLE32 handle, K32OBJ_TYPE type ); extern BOOL32 PROCESS_SetObjPtr( HANDLE32 handle, K32OBJ *ptr, DWORD flags ); - extern PDB32 *PROCESS_Create( TDB *pTask, LPCSTR cmd_line ); -extern void PROCESS_Destroy( K32OBJ *ptr ); - extern PDB32 *pCurrentProcess; +/* scheduler/event.c */ +extern void EVENT_Set( K32OBJ *obj ); +extern K32OBJ *EVENT_Create( BOOL32 manual_reset, BOOL32 initial_state ); + #endif /* __WINE_PROCESS_H */ diff --git a/include/shlobj.h b/include/shlobj.h index d51a190ddf6..35b23cc9c94 100644 --- a/include/shlobj.h +++ b/include/shlobj.h @@ -197,7 +197,7 @@ typedef enum { typedef struct IShellLink IShellLink,*LPSHELLLINK; typedef struct IShellLink_VTable { - // *** IUnknown methods *** + /* *** IUnknown methods *** */ STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; STDMETHOD_(ULONG,AddRef) (THIS) PURE; STDMETHOD_(ULONG,Release) (THIS) PURE; diff --git a/include/struct32.h b/include/struct32.h index 70875bfced7..79f1b5ff492 100644 --- a/include/struct32.h +++ b/include/struct32.h @@ -1,7 +1,7 @@ /* Structure definitions for Win32 -- used only internally */ #ifndef __WINE__STRUCT32_H #define __WINE__STRUCT32_H -#include "handle32.h" +#include "windows.h" extern void STRUCT32_MINMAXINFO32to16( const MINMAXINFO32*, MINMAXINFO16* ); extern void STRUCT32_MINMAXINFO16to32( const MINMAXINFO16*, MINMAXINFO32* ); diff --git a/include/syscolor.h b/include/syscolor.h deleted file mode 100644 index 7845858bed5..00000000000 --- a/include/syscolor.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * System color objects - * - * Copyright Alexandre Julliard, 1994 - */ - -#ifndef __WINE_SYSCOLOR_H -#define __WINE_SYSCOLOR_H - -#include "windows.h" - -struct SysColorObjects -{ - HBRUSH32 hbrushScrollbar; /* COLOR_SCROLLBAR */ - HBRUSH32 hbrushBackground; /* COLOR_BACKGROUND */ - HBRUSH32 hbrushActiveCaption; /* COLOR_ACTIVECAPTION */ - HBRUSH32 hbrushInactiveCaption; /* COLOR_INACTIVECAPTION */ - HBRUSH32 hbrushMenu; /* COLOR_MENU */ - HBRUSH32 hbrushWindow; /* COLOR_WINDOW */ - HBRUSH32 hbrushWindowFrame; /* COLOR_WINDOWFRAME */ - HBRUSH32 hbrushMenuText; /* COLOR_MENUTEXT */ - HBRUSH32 hbrushWindowText; /* COLOR_WINDOWTEXT */ - HBRUSH32 hbrushCaptionText; /* COLOR_CAPTIONTEXT */ - HBRUSH32 hbrushActiveBorder; /* COLOR_ACTIVEBORDER */ - HBRUSH32 hbrushInactiveBorder; /* COLOR_INACTIVEBORDER */ - HBRUSH32 hbrushAppWorkspace; /* COLOR_APPWORKSPACE */ - HBRUSH32 hbrushHighlight; /* COLOR_HIGHLIGHT */ - HBRUSH32 hbrushHighlightText; /* COLOR_HIGHLIGHTTEXT */ - HBRUSH32 hbrushBtnFace; /* COLOR_BTNFACE */ - HBRUSH32 hbrushBtnShadow; /* COLOR_BTNSHADOW */ - HBRUSH32 hbrushGrayText; /* COLOR_GRAYTEXT */ - HBRUSH32 hbrushBtnText; /* COLOR_BTNTEXT */ - HBRUSH32 hbrushInactiveCaptionText; /* COLOR_INACTIVECAPTIONTEXT */ - HBRUSH32 hbrushBtnHighlight; /* COLOR_BTNHIGHLIGHT */ - HBRUSH32 hbrush3DDkShadow; /* COLOR_3DDKSHADOW */ - HBRUSH32 hbrush3DLight; /* COLOR_3DLIGHT */ - HBRUSH32 hbrushInfoText; /* COLOR_INFOTEXT */ - HBRUSH32 hbrushInfoBk; /* COLOR_INFOBK */ - - HPEN32 hpenWindowFrame; /* COLOR_WINDOWFRAME */ - HPEN32 hpenWindowText; /* COLOR_WINDOWTEXT */ -}; - -extern void SYSCOLOR_Init(void); -extern struct SysColorObjects sysColorObjects; - -#endif /* __WINE_SYSCOLOR_H */ diff --git a/include/sysmetrics.h b/include/sysmetrics.h index b2f7e356091..a398235c558 100644 --- a/include/sysmetrics.h +++ b/include/sysmetrics.h @@ -129,7 +129,9 @@ #define SYSMETRICS_MIDEASTENABLED sysMetrics[SM_MIDEASTENABLED] /* 74 */ #define SYSMETRICS_MOUSEWHEELPRESENT sysMetrics[SM_MOUSEWHEELPRESENT] /* 75 */ -extern void SYSMETRICS_Init(void); +extern void SYSMETRICS_Init(void); /* sysmetrics.c */ extern short sysMetrics[SM_CMETRICS+1]; +extern void SYSCOLOR_Init(void); /* syscolor.c */ + #endif /* __WINE_SYSMETRICS_H */ diff --git a/include/thread.h b/include/thread.h dissimilarity index 66% index 347019e1d7c..4e9b61f711a 100644 --- a/include/thread.h +++ b/include/thread.h @@ -1,87 +1,131 @@ -/* - * Thread definitions - * - * Copyright 1996 Alexandre Julliard - */ - -#ifndef __WINE_THREAD_H -#define __WINE_THREAD_H - -#include "process.h" -#include "winnt.h" - -/* Thread exception block */ -typedef struct _TEB -{ - void *except; /* 00 Head of exception handling chain */ - void *stack_top; /* 04 Top of thread stack */ - void *stack_low; /* 08 Stack low-water mark */ - HTASK16 htask16; /* 0c Win16 task handle */ - WORD stack_sel; /* 0e 16-bit stack selector */ - DWORD selman_list; /* 10 Selector manager list */ - DWORD user_ptr; /* 14 User pointer */ - struct _TEB *self; /* 18 Pointer to this structure */ - WORD flags; /* 1c Flags */ - WORD mutex_count; /* 1e Win16 mutex count */ - DWORD debug_context; /* 20 Debug context */ - DWORD *ppriority; /* 24 Pointer to current priority */ - HQUEUE16 queue; /* 28 Message queue */ - WORD pad1; /* 2a */ - LPVOID *tls_ptr; /* 2c Pointer to TLS array */ -} TEB; - -/* Thread database */ -typedef struct _THDB -{ - K32OBJ header; /* 00 Kernel object header */ - PDB32 *process; /* 08 Process owning this thread */ - K32OBJ *event; /* 0c Thread event */ - TEB teb; /* 10 Thread exception block */ - PDB32 *process2; /* 40 Same as offset 08 (?) */ - DWORD flags; /* 44 Flags */ - DWORD exit_code; /* 48 Termination status */ - WORD teb_sel; /* 4c Selector to TEB */ - WORD emu_sel; /* 4e 80387 emulator selector */ - DWORD unknown1; /* 50 Unknown */ - void *wait_list; /* 54 Event waiting list */ - DWORD unknown2; /* 58 Unknown */ - void *ring0_thread; /* 5c Pointer to ring 0 thread */ - void *ptdbx; /* 60 Pointer to TDBX structure */ - void *stack_base; /* 64 Base of the stack */ - void *exit_stack; /* 68 Stack pointer on thread exit */ - void *emu_data; /* 6c Related to 80387 emulation */ - DWORD last_error; /* 70 Last error code */ - void *debugger_CB; /* 74 Debugger context block */ - DWORD debug_thread; /* 78 Thread debugging this one (?) */ - void *pcontext; /* 7c Thread register context */ - DWORD unknown3[3]; /* 80 Unknown */ - WORD current_ss; /* 8c Another 16-bit stack selector */ - WORD pad2; /* 8e */ - void *ss_table; /* 90 Pointer to info about 16-bit stack */ - WORD thunk_ss; /* 94 Yet another 16-bit stack selector */ - WORD pad3; /* 96 */ - LPVOID tls_array[64]; /* 98 Thread local storage */ - DWORD delta_priority; /* 198 Priority delta */ - DWORD unknown4[7]; /* 19c Unknown */ - void *create_data; /* 1b8 Pointer to creation structure */ - DWORD suspend_count; /* 1bc SuspendThread() counter */ - DWORD unknown5[9]; /* 1c0 Unknown */ - K32OBJ *crit_section; /* 1e4 Some critical section */ - K32OBJ *win16_mutex; /* 1e8 Pointer to Win16 mutex */ - K32OBJ *win32_mutex; /* 1ec Pointer to KERNEL32 mutex */ - K32OBJ *crit_section2; /* 1f0 Another critical section */ - DWORD unknown6[3]; /* 1f4 Unknown */ - /* The following are Wine-specific fields */ - CONTEXT context; /* 200 Thread context */ -} THDB; - - -extern THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, - LPTHREAD_START_ROUTINE start_addr ); -extern void THREAD_Destroy( K32OBJ *ptr ); -extern THDB *THREAD_Current(void); -extern THDB *THREAD_SwitchThread( CONTEXT *context ); - -extern THDB *pCurrentThread; - -#endif /* __WINE_THREAD_H */ +/* + * Thread definitions + * + * Copyright 1996 Alexandre Julliard + */ + +#ifndef __WINE_THREAD_H +#define __WINE_THREAD_H + +#include "k32obj.h" +#include "windows.h" +#include "winnt.h" +#include "selectors.h" /* for SET_FS */ + +/* Thread exception block */ +typedef struct _TEB +{ + void *except; /* 00 Head of exception handling chain */ + void *stack_top; /* 04 Top of thread stack */ + void *stack_low; /* 08 Stack low-water mark */ + HTASK16 htask16; /* 0c Win16 task handle */ + WORD stack_sel; /* 0e 16-bit stack selector */ + DWORD selman_list; /* 10 Selector manager list */ + DWORD user_ptr; /* 14 User pointer */ + struct _TEB *self; /* 18 Pointer to this structure */ + WORD flags; /* 1c Flags */ + WORD mutex_count; /* 1e Win16 mutex count */ + DWORD debug_context; /* 20 Debug context */ + DWORD *ppriority; /* 24 Pointer to current priority */ + HQUEUE16 queue; /* 28 Message queue */ + WORD pad1; /* 2a */ + LPVOID *tls_ptr; /* 2c Pointer to TLS array */ +} TEB; + +/* Event waiting structure */ +typedef struct +{ + DWORD count; /* Count of valid objects */ + DWORD signaled; /* Index of signaled object (or WAIT_FAILED)*/ + BOOL32 wait_all; /* Wait for all objects flag */ + K32OBJ *objs[MAXIMUM_WAIT_OBJECTS]; /* Object pointers */ +} WAIT_STRUCT; + +struct _PDB32; + +/* Thread database */ +typedef struct _THDB +{ + K32OBJ header; /* 00 Kernel object header */ + struct _PDB32 *process; /* 08 Process owning this thread */ + K32OBJ *event; /* 0c Thread event */ + TEB teb; /* 10 Thread exception block */ + struct _PDB32 *process2; /* 40 Same as offset 08 (?) */ + DWORD flags; /* 44 Flags */ + DWORD exit_code; /* 48 Termination status */ + WORD teb_sel; /* 4c Selector to TEB */ + WORD emu_sel; /* 4e 80387 emulator selector */ + DWORD unknown1; /* 50 Unknown */ + WAIT_STRUCT *wait_list; /* 54 Event waiting list */ + DWORD unknown2; /* 58 Unknown */ + void *ring0_thread; /* 5c Pointer to ring 0 thread */ + void *ptdbx; /* 60 Pointer to TDBX structure */ + void *stack_base; /* 64 Base of the stack */ + void *exit_stack; /* 68 Stack pointer on thread exit */ + void *emu_data; /* 6c Related to 80387 emulation */ + DWORD last_error; /* 70 Last error code */ + void *debugger_CB; /* 74 Debugger context block */ + DWORD debug_thread; /* 78 Thread debugging this one (?) */ + void *pcontext; /* 7c Thread register context */ + DWORD unknown3[3]; /* 80 Unknown */ + WORD current_ss; /* 8c Another 16-bit stack selector */ + WORD pad2; /* 8e */ + void *ss_table; /* 90 Pointer to info about 16-bit stack */ + WORD thunk_ss; /* 94 Yet another 16-bit stack selector */ + WORD pad3; /* 96 */ + LPVOID tls_array[64]; /* 98 Thread local storage */ + DWORD delta_priority; /* 198 Priority delta */ + DWORD unknown4[7]; /* 19c Unknown */ + void *create_data; /* 1b8 Pointer to creation structure */ + DWORD suspend_count; /* 1bc SuspendThread() counter */ + void *entry_point; /* 1c0 Thread entry point (was: unknown) */ + void *entry_arg; /* 1c4 Entry point arg (was: unknown) */ + int unix_pid; /* 1c8 Unix thread pid (was: unknown) */ + DWORD unknown5[6]; /* 1cc Unknown */ + K32OBJ *crit_section; /* 1e4 Some critical section */ + K32OBJ *win16_mutex; /* 1e8 Pointer to Win16 mutex */ + K32OBJ *win32_mutex; /* 1ec Pointer to KERNEL32 mutex */ + K32OBJ *crit_section2; /* 1f0 Another critical section */ + DWORD unknown6[3]; /* 1f4 Unknown */ + /* The following are Wine-specific fields */ + CONTEXT context; /* 200 Thread context */ + WAIT_STRUCT wait_struct; /* Event wait structure */ +} THDB; + +/* Thread queue entry */ +typedef struct _THREAD_ENTRY +{ + THDB *thread; + struct _THREAD_ENTRY *next; +} THREAD_ENTRY; + +/* A thread queue is a circular list; a THREAD_QUEUE is a pointer */ +/* to the end of the queue (i.e. where we add elements) */ +typedef THREAD_ENTRY *THREAD_QUEUE; + +/* THDB <-> Thread id conversion macros */ +#define THREAD_OBFUSCATOR ((DWORD)0xdeadbeef) +#define THREAD_ID_TO_THDB(id) ((THDB *)((id) ^ THREAD_OBFUSCATOR)) +#define THDB_TO_THREAD_ID(thdb) ((DWORD)(thdb) ^ THREAD_OBFUSCATOR) + +#ifdef __i386__ +/* On the i386, the current thread is in the %fs register */ +# define SET_CUR_THREAD(thdb) SET_FS((thdb)->teb_sel) +#else +extern THDB *pCurrentThread; +# define SET_CUR_THREAD(thdb) (pCurrentThread = (thdb)) +#endif /* __i386__ */ + + +/* scheduler/thread.c */ +extern THDB *THREAD_Create( struct _PDB32 *pdb, DWORD stack_size, + LPTHREAD_START_ROUTINE start_addr, LPVOID param ); +extern THDB *THREAD_Current(void); +extern void THREAD_AddQueue( THREAD_QUEUE *queue, THDB *thread ); +extern void THREAD_RemoveQueue( THREAD_QUEUE *queue, THDB *thread ); + +/* scheduler/synchro.c */ +extern void SYNC_WaitForCondition( WAIT_STRUCT *wait, DWORD timeout ); +extern void SYNC_WakeUp( THREAD_QUEUE *queue, DWORD max ); + +#endif /* __WINE_THREAD_H */ diff --git a/include/version.h b/include/version.h index d3413e2e8bf..bb64ee6ea34 100644 --- a/include/version.h +++ b/include/version.h @@ -1 +1 @@ -#define WINE_RELEASE_INFO "Wine release 971221" +#define WINE_RELEASE_INFO "Wine release 980104" diff --git a/include/windows.h b/include/windows.h index 86cb5b85d6b..d9fe47dffec 100644 --- a/include/windows.h +++ b/include/windows.h @@ -5463,7 +5463,8 @@ typedef struct DWORD dwLanguageId; } MSGBOXPARAMS32W,*LPMSGBOXPARAMS32W; -DECL_WINELIB_TYPE_AW(MSGBOXPARAMS) +DECL_WINELIB_TYPE_AW(MSGBOXPARAMS); +DECL_WINELIB_TYPE_AW(LPMSGBOXPARAMS); #pragma pack(4) @@ -5682,7 +5683,8 @@ BOOL32 WINAPI EnumSystemLocales32A(LOCALE_ENUMPROC32A,DWORD); BOOL32 WINAPI EnumSystemLocales32W(LOCALE_ENUMPROC32W,DWORD); #define EnumSystemLocales WINELIB_NAME_AW(EnumSystemLocales) BOOL32 WINAPI EnumThreadWindows(DWORD,WNDENUMPROC32,LPARAM); -void WINAPI ExitProcess(DWORD); +VOID WINAPI ExitProcess(DWORD); +VOID WINAPI ExitThread(DWORD); BOOL32 WINAPI ExitWindowsEx(UINT32,DWORD); DWORD WINAPI ExpandEnvironmentStrings32A(LPCSTR,LPSTR,DWORD); DWORD WINAPI ExpandEnvironmentStrings32W(LPCWSTR,LPWSTR,DWORD); @@ -5783,6 +5785,9 @@ LPVOID WINAPI HeapReAlloc(HANDLE32,DWORD,LPVOID,DWORD); DWORD WINAPI HeapSize(HANDLE32,DWORD,LPVOID); BOOL32 WINAPI HeapUnlock(HANDLE32); BOOL32 WINAPI HeapValidate(HANDLE32,DWORD,LPCVOID); +LONG WINAPI InterlockedDecrement(LPLONG); +LONG WINAPI InterlockedExchange(LPLONG,LONG); +LONG WINAPI InterlockedIncrement(LPLONG); BOOL32 WINAPI IsDBCSLeadByteEx(UINT32,BYTE); BOOL32 WINAPI IsProcessorFeaturePresent(DWORD); BOOL32 WINAPI IsWindowUnicode(HWND32); @@ -5802,6 +5807,7 @@ BOOL32 WINAPI MoveFile32W(LPCWSTR,LPCWSTR); BOOL32 WINAPI MoveFileEx32A(LPCSTR,LPCSTR,DWORD); BOOL32 WINAPI MoveFileEx32W(LPCWSTR,LPCWSTR,DWORD); #define MoveFileEx WINELIB_NAME_AW(MoveFileEx) +DWORD WINAPI MsgWaitForMultipleObjects(DWORD,HANDLE32*,BOOL32,DWORD,DWORD); HANDLE32 WINAPI OpenEvent32A(DWORD,BOOL32,LPCSTR); HANDLE32 WINAPI OpenEvent32W(DWORD,BOOL32,LPCWSTR); #define OpenEvent WINELIB_NAME_AW(OpenEvent) @@ -5811,9 +5817,11 @@ HANDLE32 WINAPI OpenFileMapping32W(DWORD,BOOL32,LPCWSTR); HANDLE32 WINAPI OpenMutex32A(DWORD,BOOL32,LPCSTR); HANDLE32 WINAPI OpenMutex32W(DWORD,BOOL32,LPCWSTR); #define OpenMutex WINELIB_NAME_AW(OpenMutex) +HANDLE32 WINAPI OpenProcess(DWORD,BOOL32,DWORD); HANDLE32 WINAPI OpenSemaphore32A(DWORD,BOOL32,LPCSTR); HANDLE32 WINAPI OpenSemaphore32W(DWORD,BOOL32,LPCWSTR); #define OpenSemaphore WINELIB_NAME_AW(OpenSemaphore) +BOOL32 WINAPI PulseEvent(HANDLE32); DWORD WINAPI QueryDosDevice32A(LPCSTR,LPSTR,DWORD); DWORD WINAPI QueryDosDevice32W(LPCWSTR,LPWSTR,DWORD); #define QueryDosDevice WINELIB_NAME_AW(QueryDosDevice) @@ -5843,6 +5851,7 @@ DWORD WINAPI RegQueryInfoKey32A(HKEY,LPSTR,LPDWORD,LPDWORD,LPDWORD, LPDWORD,LPFILETIME); #define RegQueryInfoKey WINELIB_NAME_AW(RegQueryInfoKey) BOOL32 WINAPI ReleaseSemaphore(HANDLE32,LONG,LPLONG); +BOOL32 WINAPI ResetEvent(HANDLE32); VOID WINAPI RtlFillMemory(LPVOID,UINT32,UINT32); VOID WINAPI RtlMoveMemory(LPVOID,LPCVOID,UINT32); VOID WINAPI RtlZeroMemory(LPVOID,UINT32); @@ -5860,6 +5869,7 @@ BOOL32 WINAPI SetEndOfFile(HFILE32); BOOL32 WINAPI SetEnvironmentVariable32A(LPCSTR,LPCSTR); BOOL32 WINAPI SetEnvironmentVariable32W(LPCWSTR,LPCWSTR); #define SetEnvironmentVariable WINELIB_NAME_AW(SetEnvironmentVariable) +BOOL32 WINAPI SetEvent(HANDLE32); VOID WINAPI SetFileApisToANSI(void); VOID WINAPI SetFileApisToOEM(void); DWORD WINAPI SetFilePointer(HFILE32,LONG,LPLONG,DWORD); @@ -5894,6 +5904,10 @@ BOOL32 WINAPI VirtualProtectEx(HANDLE32,LPVOID,DWORD,DWORD,LPDWORD); BOOL32 WINAPI VirtualQuery(LPCVOID,LPMEMORY_BASIC_INFORMATION,DWORD); BOOL32 WINAPI VirtualQueryEx(HANDLE32,LPCVOID,LPMEMORY_BASIC_INFORMATION,DWORD); BOOL32 WINAPI VirtualUnlock(LPVOID,DWORD); +DWORD WINAPI WaitForMultipleObjects(DWORD,const HANDLE32*,BOOL32,DWORD); +DWORD WINAPI WaitForMultipleObjectsEx(DWORD,const HANDLE32*,BOOL32,DWORD,BOOL32); +DWORD WINAPI WaitForSingleObject(HANDLE32,DWORD); +DWORD WINAPI WaitForSingleObjectEx(HANDLE32,DWORD,BOOL32); BOOL32 WINAPI WriteConsole32A(HANDLE32,LPCVOID,DWORD,LPDWORD,LPVOID); BOOL32 WINAPI WriteConsole32W(HANDLE32,LPCVOID,DWORD,LPDWORD,LPVOID); #define WriteConsole WINELIB_NAME_AW(WriteConsole) @@ -8160,6 +8174,8 @@ UINT32 WINAPI _lwrite32(HFILE32,LPCSTR,UINT32); /* Extra functions that don't exist in the Windows API */ +HPEN16 WINAPI GetSysColorPen16(INT16); +HPEN32 WINAPI GetSysColorPen32(INT32); INT32 WINAPI LoadMessage32A(HINSTANCE32,UINT32,WORD,LPSTR,INT32); INT32 WINAPI LoadMessage32W(HINSTANCE32,UINT32,WORD,LPWSTR,INT32); SEGPTR WINAPI WIN16_GlobalLock16(HGLOBAL16); diff --git a/include/winerror.h b/include/winerror.h index dd2f3f33ce4..a0a996fc3c8 100644 --- a/include/winerror.h +++ b/include/winerror.h @@ -4,6 +4,12 @@ extern int WIN32_LastError; +#define MAKE_HRESULT(sev,fac,code) \ + ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) ) +#define MAKE_SCODE(sev,fac,code) \ + ((SCODE) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) ) + + /* ERROR_UNKNOWN is a placeholder for error conditions which haven't * been tested yet so we're not exactly sure what will be returned. * All instances of ERROR_UNKNOWN should be tested under Win95/NT @@ -37,6 +43,8 @@ extern int WIN32_LastError; #define ERROR_FILENAME_EXCED_RANGE 206 #define ERROR_MORE_DATA 234 #define ERROR_NO_MORE_ITEMS 259 +#define ERROR_NOT_OWNER 288 +#define ERROR_TOO_MANY_POSTS 298 #define ERROR_INVALID_ADDRESS 487 #define ERROR_CAN_NOT_COMPLETE 1003 #define ERROR_IO_DEVICE 1117 @@ -48,11 +56,13 @@ extern int WIN32_LastError; /* HRESULT values for OLE, SHELL and other Interface stuff */ #define NOERROR 0 #define S_OK 0 +#define E_FAIL 0x80000008 #define E_UNEXPECTED 0x8000FFFF -#define E_OUTOFMEMORY 0x8007000E -#define E_INVALIDARG 0x80070057 #define OLE_E_ENUM_NOMORE 0x80040002 #define CLASS_E_CLASSNOTAVAILABLE 0x80040111 +#define E_OUTOFMEMORY 0x8007000E +#define E_INVALIDARG 0x80070057 + #endif /* __WINE_WINERROR_H */ diff --git a/include/winnt.h b/include/winnt.h index 0d532993260..be00784ccdb 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -194,6 +194,10 @@ typedef struct #define EXCEPTION_PRIV_INSTRUCTION STATUS_PRIVILEGED_INSTRUCTION #define EXCEPTION_IN_PAGE_ERROR STATUS_IN_PAGE_ERROR +#define MAXIMUM_WAIT_OBJECTS 64 +#define MAXIMUM_SUSPEND_COUNT 127 + + /* * Return values from the actual exception handlers */ diff --git a/include/winsock.h b/include/winsock.h index edee250c770..ca7357c25fa 100644 --- a/include/winsock.h +++ b/include/winsock.h @@ -176,7 +176,7 @@ DECL_WINELIB_TYPE(SOCKET); #define WS_SOCK_RDM 4 /* reliably-delivered message */ #define WS_SOCK_SEQPACKET 5 /* sequenced packet stream */ -#define WS_SOL_SOCKET (-1) +#define WS_SOL_SOCKET 0xffff #define WS_IPPROTO_TCP 6 /* diff --git a/include/wintypes.h b/include/wintypes.h index a5ab5562bdd..527fbcb856b 100644 --- a/include/wintypes.h +++ b/include/wintypes.h @@ -59,7 +59,7 @@ # if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ >= 7) # define __stdcall __attribute__((__stdcall__)) # define __cdecl __attribute__((__cdecl__)) -# define __RESTORE_ES __asm__ __volatile__("pushw %ds\n\tpopw %es") +# define __RESTORE_ES __asm__ __volatile__("pushl %ds\n\tpopl %es") # else # error You need gcc >= 2.7 to build Wine on a 386 # endif /* __GNUC__ */ diff --git a/libtest/Makefile.in b/libtest/Makefile.in index 3a8510910c4..11deeeab243 100644 --- a/libtest/Makefile.in +++ b/libtest/Makefile.in @@ -5,7 +5,7 @@ VPATH = @srcdir@ MODULE = none RCFLAGS = -w16 -h PROGRAMS = expand hello hello2 hello3 hello4 new rolex -ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS) +ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS) C_SRCS = \ expand.c \ diff --git a/loader/main.c b/loader/main.c index ed75c116e3f..b596be299e5 100644 --- a/loader/main.c +++ b/loader/main.c @@ -21,7 +21,6 @@ #include "dialog.h" #include "drive.h" #include "queue.h" -#include "syscolor.h" #include "sysmetrics.h" #include "file.h" #include "gdi.h" @@ -43,10 +42,6 @@ int __winelib = 1; /* Winelib run-time flag */ -HANDLE32 SystemHeap = 0; -HANDLE32 SegptrHeap = 0; - - /*********************************************************************** * Kernel initialisation routine */ diff --git a/loader/module.c b/loader/module.c index cebaea00dae..6cea6c5f200 100644 --- a/loader/module.c +++ b/loader/module.c @@ -19,6 +19,7 @@ #include "hook.h" #include "module.h" #include "neexe.h" +#include "process.h" #include "resource.h" #include "selectors.h" #include "stackframe.h" @@ -1436,7 +1437,7 @@ HMODULE32 WINAPI LoadLibraryEx32A(LPCSTR libname,HFILE32 hfile,DWORD flags) hmod = PE_LoadLibraryEx32A(buffer,hfile,flags); } /* initialize all DLLs, which haven't been initialized yet. */ - PE_InitializeDLLs( GetCurrentProcessId(), DLL_PROCESS_ATTACH, NULL); + PE_InitializeDLLs( pCurrentProcess, DLL_PROCESS_ATTACH, NULL); return hmod; } @@ -1472,8 +1473,9 @@ HMODULE32 WINAPI LoadLibraryEx32W(LPCWSTR libnameW,HFILE32 hfile,DWORD flags) */ BOOL32 WINAPI FreeLibrary32(HINSTANCE32 hLibModule) { - fprintf(stderr,"FreeLibrary: empty stub\n"); - return TRUE; + dprintf_module(stddeb,"FreeLibrary: hLibModule: %08x\n", hLibModule); + return MODULE_FreeModule(hLibModule, + GlobalLock16(GetCurrentTask()) ); } diff --git a/loader/pe_image.c b/loader/pe_image.c index 6693fe2c63c..043404dbd75 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c @@ -97,7 +97,7 @@ FARPROC32 PE_FindExportedFunction( HMODULE32 hModule, LPCSTR funcName) u_long * function; u_char ** name, *ename; int i; - PDB32 *process=(PDB32*)GetCurrentProcessId(); + PDB32 *process=pCurrentProcess; PE_MODREF *pem; u_long rva_start, rva_end, addr; char * forward; @@ -690,14 +690,14 @@ HMODULE32 PE_LoadLibraryEx32A (LPCSTR name, HFILE32 hFile, DWORD flags) { if (!HIWORD(hModule)) /* internal (or bad) */ return hModule; /* check if this module is already mapped */ - pem = ((PDB32*)GetCurrentProcessId())->modref_list; + pem = pCurrentProcess->modref_list; while (pem) { if (pem->module == hModule) return hModule; pem = pem->next; } pModule = MODULE_GetPtr(hModule); if (pModule->flags & NE_FFLAGS_BUILTIN) { - PDB32 *process = (PDB32*)GetCurrentProcessId(); + PDB32 *process = pCurrentProcess; IMAGE_DOS_HEADER *dh; IMAGE_NT_HEADERS *nh; IMAGE_SECTION_HEADER *sh; @@ -743,8 +743,7 @@ HMODULE32 PE_LoadLibraryEx32A (LPCSTR name, HFILE32 hFile, DWORD flags) { if (pModule->module32 < 32) return 21; } /* recurse */ - pModule->module32 = PE_MapImage( pModule->module32, - (PDB32*)GetCurrentProcessId(), + pModule->module32 = PE_MapImage( pModule->module32, pCurrentProcess, &ofs,flags); return pModule->module32; } @@ -777,8 +776,7 @@ HINSTANCE16 PE_LoadModule( HFILE32 hFile, OFSTRUCT *ofs, LOADPARAMS* params ) (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ), *((WORD*)PTR_SEG_TO_LIN(params->showCmd) + 1) ); } - pModule->module32 = PE_MapImage( hModule32, (PDB32*)GetCurrentProcessId(), - ofs, 0 ); + pModule->module32 = PE_MapImage( hModule32, pCurrentProcess, ofs, 0 ); return hInstance; } @@ -812,7 +810,7 @@ static void PE_InitDLL(PE_MODREF *pem, DWORD type,LPVOID lpReserved) ) { FARPROC32 entry = (FARPROC32)RVA_PTR( pem->module, OptionalHeader.AddressOfEntryPoint ); - dprintf_relay( stddeb, "CallTo32(entryproc=%p,module=%d,type=%ld,res=%p)\n", + dprintf_relay( stddeb, "CallTo32(entryproc=%p,module=%08x,type=%ld,res=%p)\n", entry, pem->module, type, lpReserved ); entry( pem->module, type, lpReserved ); } @@ -877,7 +875,7 @@ void PE_InitTls(PDB32 *pdb) */ BOOL32 WINAPI DisableThreadLibraryCalls(HMODULE32 hModule) { - PDB32 *process = (PDB32*)GetCurrentProcessId(); + PDB32 *process = pCurrentProcess; PE_MODREF *pem = process->modref_list; while (pem) { diff --git a/loader/pe_resource.c b/loader/pe_resource.c index 01396336b84..4e4098cc0e7 100644 --- a/loader/pe_resource.c +++ b/loader/pe_resource.c @@ -33,7 +33,7 @@ static PE_MODREF* HMODULE32toPE_MODREF(HMODULE32 hmod) { NE_MODULE *pModule; - PDB32 *pdb = (PDB32*)GetCurrentProcessId(); + PDB32 *pdb = pCurrentProcess; PE_MODREF *pem; if (!hmod) hmod = GetTaskDS(); /* FIXME: correct? */ diff --git a/loader/signal.c b/loader/signal.c index d99dedc9a90..66def5d1f27 100644 --- a/loader/signal.c +++ b/loader/signal.c @@ -149,6 +149,8 @@ extern void WINSOCK_sigio(int a); */ BOOL32 SIGNAL_Init(void) { + extern void SYNC_SetupSignals(void); + #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__svr4__) || defined(_SCO_DS) struct sigaltstack ss; ss.ss_sp = SIGNAL_Stack; @@ -168,6 +170,7 @@ BOOL32 SIGNAL_Init(void) #ifdef SIGIO SIGNAL_SetHandler( SIGIO, (void (*)())WINSOCK_sigio, 0); #endif + SYNC_SetupSignals(); return TRUE; } diff --git a/loader/task.c b/loader/task.c index 08881d6ef7b..110a7995869 100644 --- a/loader/task.c +++ b/loader/task.c @@ -340,7 +340,7 @@ static void TASK_CallToStart(void) SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule ); IF1632_Saved16_ss_sp = pTask->ss_sp; - SET_FS( pCurrentThread->teb_sel ); + SET_CUR_THREAD( pTask->thdb ); if (pModule->flags & NE_FFLAGS_WIN32) { /* FIXME: all this is an ugly hack */ @@ -526,15 +526,16 @@ HTASK16 TASK_CreateTask( HMODULE16 hModule, HINSTANCE16 hInstance, pCurrentProcess->exe_modref->pe_module->pe_header->OptionalHeader.AddressOfEntryPoint); */ pTask->thdb = THREAD_Create( pdb32, - PE_HEADER(pModule->module32)->OptionalHeader.SizeOfStackReserve, 0 ); + PE_HEADER(pModule->module32)->OptionalHeader.SizeOfStackReserve, + NULL, NULL ); /* FIXME: should not be done here */ - pCurrentThread = pTask->thdb; PE_InitTls( pdb32 ); } else - pTask->thdb = THREAD_Create( pdb32, 0, NULL ); + pTask->thdb = THREAD_Create( pdb32, 0, NULL, NULL ); /* FIXME: check for pTask->thdb == NULL. */ + SET_CUR_THREAD( pTask->thdb ); /* Create the 32-bit stack frame */ @@ -596,8 +597,8 @@ static void TASK_DeleteTask( HTASK16 hTask ) /* Delete the Win32 part of the task */ - PROCESS_Destroy( &pTask->thdb->process->header ); - THREAD_Destroy( &pTask->thdb->header ); + K32OBJ_DecCount( &pTask->thdb->process->header ); + K32OBJ_DecCount( &pTask->thdb->header ); /* Free the task module */ @@ -788,8 +789,8 @@ void TASK_Reschedule(void) /* Switch to the new stack */ hCurrentTask = hTask; - pCurrentThread = pNewTask->thdb; - pCurrentProcess = pCurrentThread->process; + SET_CUR_THREAD( pNewTask->thdb ); + pCurrentProcess = pNewTask->thdb->process; IF1632_Saved16_ss_sp = pNewTask->ss_sp; } diff --git a/memory/global.c b/memory/global.c index 4490b8a0079..0830c140bf1 100644 --- a/memory/global.c +++ b/memory/global.c @@ -994,7 +994,7 @@ HGLOBAL32 WINAPI GlobalReAlloc32(HGLOBAL32 hmem, DWORD size, UINT32 flags) HGLOBAL32 hnew; PGLOBAL32_INTERN pintern; - hnew=NULL; + hnew = 0; /* HeapLock(GetProcessHeap()); */ if(flags & GMEM_MODIFY) /* modify flags */ { @@ -1020,7 +1020,7 @@ HGLOBAL32 WINAPI GlobalReAlloc32(HGLOBAL32 hmem, DWORD size, UINT32 flags) else { SetLastError(ERROR_INVALID_PARAMETER); - hnew=NULL; + hnew = 0; } } else @@ -1074,12 +1074,11 @@ HGLOBAL32 WINAPI GlobalReAlloc32(HGLOBAL32 hmem, DWORD size, UINT32 flags) HGLOBAL32 WINAPI GlobalFree32(HGLOBAL32 hmem) { PGLOBAL32_INTERN pintern; - HGLOBAL32 hreturned=NULL; + HGLOBAL32 hreturned = 0; if(ISPOINTER(hmem)) /* POINTER */ { - if(!HeapFree(GetProcessHeap(), 0, (LPVOID) hmem)) - hmem=NULL; + if(!HeapFree(GetProcessHeap(), 0, (LPVOID) hmem)) hmem = 0; } else /* HANDLE */ { diff --git a/memory/heap.c b/memory/heap.c index 1d4aee294ca..9904b3da86e 100644 --- a/memory/heap.c +++ b/memory/heap.c @@ -13,6 +13,7 @@ #include "winbase.h" #include "winerror.h" #include "winnt.h" +#include "heap.h" #include "stddebug.h" #include "debug.h" @@ -92,6 +93,10 @@ typedef struct tagHEAP #define HEAP_DEF_SIZE 0x110000 /* Default heap size = 1Mb + 64Kb */ #define HEAP_MIN_BLOCK_SIZE (8+sizeof(ARENA_FREE)) /* Min. heap block size */ +HANDLE32 SystemHeap = 0; +HANDLE32 SegptrHeap = 0; +CRITICAL_SECTION *HEAP_SystemLock = NULL; + /*********************************************************************** * HEAP_Dump @@ -808,7 +813,6 @@ HANDLE32 WINAPI HeapCreate( DWORD flags, DWORD initialSize, DWORD maxSize ) heap->next = NULL; heap->flags = flags; heap->magic = HEAP_MAGIC; - InitializeCriticalSection( &heap->critSection ); /* Build the free lists */ @@ -828,9 +832,13 @@ HANDLE32 WINAPI HeapCreate( DWORD flags, DWORD initialSize, DWORD maxSize ) HEAP_CreateFreeBlock( subheap, heap + 1, subheap->size - sizeof(*heap) ); + /* Initialize critical section */ + + InitializeCriticalSection( &heap->critSection ); + if (!SystemHeap) HEAP_SystemLock = &heap->critSection; + /* We are done */ - SetLastError( 0 ); return (HANDLE32)heap; } @@ -1088,7 +1096,6 @@ DWORD WINAPI HeapCompact( HANDLE32 heap, DWORD flags ) BOOL32 WINAPI HeapLock( HANDLE32 heap ) { HEAP *heapPtr = HEAP_GetPtr( heap ); - if (!heapPtr) return FALSE; EnterCriticalSection( &heapPtr->critSection ); return TRUE; @@ -1101,7 +1108,6 @@ BOOL32 WINAPI HeapLock( HANDLE32 heap ) BOOL32 WINAPI HeapUnlock( HANDLE32 heap ) { HEAP *heapPtr = HEAP_GetPtr( heap ); - if (!heapPtr) return FALSE; LeaveCriticalSection( &heapPtr->critSection ); return TRUE; diff --git a/memory/ldt.c b/memory/ldt.c index 62fd1b0591b..126e30b1d38 100644 --- a/memory/ldt.c +++ b/memory/ldt.c @@ -61,8 +61,10 @@ static __inline__ int modify_ldt( int func, struct modify_ldt_s *ptr, #if defined(__svr4__) || defined(_SCO_DS) #include +#ifndef __sun__ #include #endif +#endif #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) #include diff --git a/memory/virtual.c b/memory/virtual.c index 82d4845a2f1..9ffde82d361 100644 --- a/memory/virtual.c +++ b/memory/virtual.c @@ -95,6 +95,17 @@ static UINT32 granularity_mask; /* Allocation granularity (usually 64k) */ #define ROUND_SIZE(addr,size) \ (((UINT32)(size) + ((UINT32)(addr) & page_mask) + page_mask) & ~page_mask) +static void VIRTUAL_DestroyMapping( K32OBJ *obj ); + +const K32OBJ_OPS MEM_MAPPED_FILE_Ops = +{ + /* Object cannot be waited upon, so we don't need these (except destroy) */ + NULL, /* signaled */ + NULL, /* satisfied */ + NULL, /* add_wait */ + NULL, /* remove_wait */ + VIRTUAL_DestroyMapping /* destroy */ +}; /*********************************************************************** * VIRTUAL_GetProtStr @@ -864,10 +875,15 @@ HANDLE32 WINAPI CreateFileMapping32A(HFILE32 hFile, LPSECURITY_ATTRIBUTES attr, if (obj->type == K32OBJ_MEM_MAPPED_FILE) { SetLastError( ERROR_ALREADY_EXISTS ); - return PROCESS_AllocHandle( obj, 0 ); + handle = PROCESS_AllocHandle( obj, 0 ); } - SetLastError( ERROR_DUP_NAME ); - return 0; + else + { + SetLastError( ERROR_DUP_NAME ); + handle = 0; + } + K32OBJ_DecCount( obj ); + return handle; } /* Check parameters */ @@ -924,15 +940,17 @@ HANDLE32 WINAPI CreateFileMapping32A(HFILE32 hFile, LPSECURITY_ATTRIBUTES attr, /* Allocate the mapping object */ if (!(mapping = HeapAlloc( SystemHeap, 0, sizeof(*mapping) ))) goto error; - mapping->header.type = K32OBJ_MEM_MAPPED_FILE; + mapping->header.type = K32OBJ_MEM_MAPPED_FILE; mapping->header.refcount = 1; - mapping->protect = vprot; - mapping->size_high = size_high; - mapping->size_low = ROUND_SIZE( 0, size_low ); - mapping->file = (FILE_OBJECT *)obj; + mapping->protect = vprot; + mapping->size_high = size_high; + mapping->size_low = ROUND_SIZE( 0, size_low ); + mapping->file = (FILE_OBJECT *)obj; - handle = PROCESS_AllocHandle( &mapping->header, 0 ); - if (handle != INVALID_HANDLE_VALUE32) return handle; + if (!K32OBJ_AddName( &mapping->header, name )) handle = 0; + else handle = PROCESS_AllocHandle( &mapping->header, 0 ); + K32OBJ_DecCount( &mapping->header ); + return handle; error: if (obj) K32OBJ_DecCount( obj ); @@ -961,9 +979,16 @@ HANDLE32 WINAPI CreateFileMapping32W(HFILE32 hFile, LPSECURITY_ATTRIBUTES attr, */ HANDLE32 WINAPI OpenFileMapping32A( DWORD access, BOOL32 inherit, LPCSTR name ) { - K32OBJ *obj = K32OBJ_FindNameType( name, K32OBJ_MEM_MAPPED_FILE ); - if (!obj) return 0; - return PROCESS_AllocHandle( obj, 0 ); + HANDLE32 handle = 0; + K32OBJ *obj; + SYSTEM_LOCK(); + if ((obj = K32OBJ_FindNameType( name, K32OBJ_MEM_MAPPED_FILE ))) + { + handle = PROCESS_AllocHandle( obj, 0 ); + K32OBJ_DecCount( obj ); + } + SYSTEM_UNLOCK(); + return handle; } @@ -984,7 +1009,7 @@ HANDLE32 WINAPI OpenFileMapping32W( DWORD access, BOOL32 inherit, LPCWSTR name) * * Destroy a FILE_MAPPING object. */ -void VIRTUAL_DestroyMapping( K32OBJ *ptr ) +static void VIRTUAL_DestroyMapping( K32OBJ *ptr ) { FILE_MAPPING *mapping = (FILE_MAPPING *)ptr; assert( ptr->type == K32OBJ_MEM_MAPPED_FILE ); diff --git a/misc/comm.c b/misc/comm.c index 08f96753758..73681d94e91 100644 --- a/misc/comm.c +++ b/misc/comm.c @@ -36,7 +36,6 @@ #include "options.h" #include "stddebug.h" #include "debug.h" -#include "handle32.h" #ifndef TIOCINQ #define TIOCINQ FIONREAD diff --git a/misc/cpu.c b/misc/cpu.c index ffbbbbfbbe8..6a7909729d2 100644 --- a/misc/cpu.c +++ b/misc/cpu.c @@ -11,6 +11,9 @@ #include "windows.h" #include "winnt.h" +/*********************************************************************** + * GetSystemInfo [KERNELL32.404] + */ VOID WINAPI GetSystemInfo(LPSYSTEM_INFO si) { static int cache = 0; @@ -101,23 +104,48 @@ VOID WINAPI GetSystemInfo(LPSYSTEM_INFO si) #endif /* linux */ } +/*********************************************************************** + * CPU_TestProcessorFeature + */ +static BOOL32 CPU_TestProcessorFeature(const char* query_info, const char* query_value) +{ + BOOL32 flag=FALSE; +#ifdef linux + char line[200],info[200],value[200],junk[200]; + FILE *f = fopen ("/proc/cpuinfo", "r"); + + if (!f) + return 0; + while (fgets(line,200,f)!=NULL) { + if (sscanf(line,"%s%[ \t:]%s",info,junk,value)!=3) + continue; + if (strcmp(info,query_info)==0) + flag = strstr(value,query_value)!=NULL; + } + fclose (f); +#else /* linux */ + /* FIXME: how do we do this on other systems? */ +#endif /* linux */ + return flag; +} -/* IsProcessorFeaturePresent [KERNEL32.880] */ +/*********************************************************************** + * IsProcessorFeaturePresent [KERNELL32.880] + */ BOOL32 WINAPI IsProcessorFeaturePresent (DWORD feature) { SYSTEM_INFO si; GetSystemInfo (&si); - /* FIXME: these are relatively stupid approximations. */ switch (feature) { - case PF_FLOATING_POINT_PRECISION_ERRATA: + case PF_FLOATING_POINT_PRECISION_ERRATA: return si.wProcessorLevel == 5; case PF_FLOATING_POINT_EMULATED: - return FALSE; + return CPU_TestProcessorFeature("fpu","no"); break; case PF_COMPARE_EXCHANGE_DOUBLE: return si.wProcessorLevel >= 5; case PF_MMX_INSTRUCTIONS_AVAILABLE: - return FALSE; + return CPU_TestProcessorFeature("flags","mmx"); break; default: return FALSE; } diff --git a/misc/crtdll.c b/misc/crtdll.c index 3a12c9bb81d..2415c399a8e 100644 --- a/misc/crtdll.c +++ b/misc/crtdll.c @@ -25,6 +25,7 @@ Unresolved issues Uwe Bonnes 970904: #include #include #include +#include #include #include #include @@ -421,6 +422,25 @@ time_t __cdecl CRTDLL_time(time_t *timeptr) } /********************************************************************* + * (CRTDLL.350) + */ +clock_t __cdecl CRTDLL_clock(void) +{ + struct tms alltimes; + clock_t res; + + times(&alltimes); + res = alltimes.tms_utime + alltimes.tms_stime+ + alltimes.tms_cutime + alltimes.tms_cstime; + /* Fixme: We need some symbolic representation + for (Hostsystem_)CLOCKS_PER_SEC + and (Emulated_system_)CLOCKS_PER_SEC + 10 holds only for Windows/Linux_i86) + */ + return 10*res; +} + +/********************************************************************* * _isatty (CRTDLL.137) */ BOOL32 __cdecl CRTDLL__isatty(DWORD x) diff --git a/misc/lstr.c b/misc/lstr.c index ce80476df0e..234ec0724ab 100644 --- a/misc/lstr.c +++ b/misc/lstr.c @@ -10,7 +10,6 @@ #include #include #include -#include #include "windows.h" #include "winnt.h" /* HEAP_ macros */ @@ -22,6 +21,16 @@ #include "stddebug.h" #include "debug.h" +#ifdef HAVE_WCTYPE_H +# include +#else +# define towlower(c) tolower(c) +# define towupper(c) toupper(c) +# define iswalnum(c) isalnum(c) +# define iswalpha(c) isalpha(c) +# define iswupper(c) isupper(c) +# define iswlower(c) islower(c) +#endif /* HAVE_WCTYPE_H */ /* Funny to divide them between user and kernel. */ diff --git a/misc/main.c b/misc/main.c index bda1779b33a..cbc551b2938 100644 --- a/misc/main.c +++ b/misc/main.c @@ -522,6 +522,8 @@ static void called_at_exit(void) MAIN_RestoreSetup(); COLOR_Cleanup(); WINSOCK_Shutdown(); + /* FIXME: should check for other processes or threads */ + DeleteCriticalSection( HEAP_SystemLock ); } /*********************************************************************** diff --git a/misc/registry.c b/misc/registry.c index fa63c804137..90e233cecdd 100644 --- a/misc/registry.c +++ b/misc/registry.c @@ -2,6 +2,10 @@ * Registry Functions * * Copyright 1996 Marcus Meissner + * + * December 21, 1997 - Kevin Cozens + * Fixed bugs in the _w95_loadreg() function. Added extra information + * regarding the format of the Windows '95 registry files. */ #include @@ -25,6 +29,8 @@ #include "xmalloc.h" #include "winreg.h" +#define DEBUG_W95_LOADREG 0 + /* FIXME: following defines should be configured global ... */ /* NOTE: do not append a /. linux' mkdir() WILL FAIL if you do that */ @@ -894,12 +900,19 @@ _copy_registry(LPKEYSTRUCT from,LPKEYSTRUCT to) { * 0 : "CREG" - magic * 4 : DWORD version * 8 : DWORD offset_of_RGDB_part - * 0C..1F: ? (someone fill in please) + * 0C..0F: ? (someone fill in please) + * 10: WORD number of RGDB blocks + * 12: WORD ? + * 14: WORD always 0000? + * 16: WORD always 0001? + * 18..1F: ? (someone fill in please) * * 20: RGKN_section: * header: * 0 : "RGKN" - magic - * 4..0x1B: ? (fill in) + * 4 : DWORD offset to first RGDB section + * 8 : DWORD offset to ? + * C..0x1B: ? (fill in) * 0x20 ... offset_of_RGDB_part: Disk Key Entry structures * * Disk Key Entry Structure: @@ -928,8 +941,12 @@ _copy_registry(LPKEYSTRUCT from,LPKEYSTRUCT to) { * * RGDB_section: * 00: "RGDB" - magic - * 04: DWORD offset to next RGDB section (perhaps WORD) - * 08...1F: ? + * 04: DWORD offset to next RGDB section + * 08: DWORD ? + * 0C: WORD always 000d? + * 0E: WORD RGDB block number + * 10: DWORD ? (equals value at offset 4 - value at offset 8) + * 14..1F: ? * 20.....: disk keys * * disk key: @@ -957,6 +974,10 @@ _copy_registry(LPKEYSTRUCT from,LPKEYSTRUCT to) { * structure) and reading another RGDB_section. * repeat until end of file. * + * An interesting relationship exists in RGDB_section. The value at offset + * 10 equals the value at offset 4 minus the value at offset 8. I have no + * idea at the moment what this means. (Kevin Cozens) + * * FIXME: this description needs some serious help, yes. */ @@ -984,9 +1005,10 @@ struct _w95key { }; /* fast lookup table dkeaddr->nr */ -struct _w95nr2da { +struct _w95nr2da { unsigned long dkeaddr; unsigned long nr; + struct _w95key *key; }; @@ -1069,27 +1091,27 @@ _w95dkecomp(struct _w95nr2da *a,struct _w95nr2da *b){return a->dkeaddr-b->dkeadd static struct _w95key* _w95dkelookup(unsigned long dkeaddr,int n,struct _w95nr2da *nr2da,struct _w95key *keys) { - int i; - int left, right; +int i; +int left, right; if (dkeaddr == 0xFFFFFFFF) return NULL; if (dkeaddr<0x20) return NULL; dkeaddr=_w95_adj_da(dkeaddr+0x1c); - left=0; - right=n-1; - while(left<=right) - { - i=(left+right)/2; - - if(nr2da[i].dkeaddr == dkeaddr) - return keys+nr2da[i].nr; - else if(nr2da[i].dkeaddr < dkeaddr) - left=i+1; - else - right=i-1; - } + left=0; + right=n-1; + while(left<=right) + { + i=(left+right)/2; + + if(nr2da[i].dkeaddr == dkeaddr) + return nr2da[i].key; + else if(nr2da[i].dkeaddr < dkeaddr) + left=i+1; + else + right=i-1; + } /* 0x3C happens often, just report unusual values */ if (dkeaddr!=0x3c) dprintf_reg(stddeb,"search hasn't found dkeaddr %lx?\n",dkeaddr); @@ -1129,13 +1151,13 @@ _w95_loadreg(char* fn,LPKEYSTRUCT lpkey) { unsigned short valdatalen; /* valname, valdata */ }; - struct _w95nr2da *nr2da; + struct _w95nr2da *nr2da; HFILE32 hfd; int lastmodified; char magic[5]; - unsigned long nr,pos,i,where,version,rgdbsection,end,off_next_rgdb; - struct _w95key *keys; + unsigned long nr,pos,i,j,where,version,rgdbsection,end,off_next_rgdb; + struct _w95key *keys,*key; int nrofdkes; unsigned char *data,*curdata,*nextrgdb; OFSTRUCT ofs; @@ -1171,7 +1193,13 @@ _w95_loadreg(char* fn,LPKEYSTRUCT lpkey) { where = 0x40; end = rgdbsection; - nrofdkes = (end-where)/sizeof(struct dke)+100; + /* I removed the '+100' that was here. The adjustments to dkeaddr */ + /* imply alignments to the data in 'data' which would mean it is */ + /* larger than the number of dke entries it holds therefore nrofdkes*/ + /* would be equal to or larger than it needs to be without the need */ + /* for the +100 - kc */ + nrofdkes = (end-where)/sizeof(struct dke); + data = (char*)xmalloc(end-where); if ((end-where)!=_lread32(hfd,data,end-where)) return; @@ -1179,9 +1207,12 @@ _w95_loadreg(char* fn,LPKEYSTRUCT lpkey) { keys = (struct _w95key*)xmalloc(nrofdkes * sizeof(struct _w95key)); memset(keys,'\0',nrofdkes*sizeof(struct _w95key)); - nr2da= (struct _w95nr2da*)xmalloc(nrofdkes * sizeof(struct _w95nr2da)); - memset(nr2da,'\0',nrofdkes*sizeof(struct _w95nr2da)); + nr2da= (struct _w95nr2da*)xmalloc(nrofdkes * sizeof(struct _w95nr2da)); + memset(nr2da,'\0',nrofdkes*sizeof(struct _w95nr2da)); +#if DEBUG_W95_LOADREG + dprintf_reg(stddeb,"nrofdkes = %d\n", nrofdkes); +#endif for (i=0;i nr = %lu, nrMS:nrLS = %04X:%X\n", + nr,dke.nrMS,dke.nrLS); +#endif curdata+=sizeof(dke); } if (((dkeaddr+0x1C)&0xFFF)<0x1C) { @@ -1206,46 +1245,63 @@ _w95_loadreg(char* fn,LPKEYSTRUCT lpkey) { * but ONLY if we are >0x1000 already */ if (dkeaddr & ~0xFFF) - dkeaddr = dkeaddr & ~0xFFF; + dkeaddr &= ~0xFFF; } - if (nr>nrofdkes) { - /* 0xFFFFFFFF happens often, just report unusual values */ - if (nr!=0xFFFFFFFF) - dprintf_reg(stddeb,"nr %ld exceeds nrofdkes %d, skipping.\n",nr,nrofdkes); + /* For the time being we will assume that all values of */ + /* nr are valid unless the following condition is true. */ + /* This value is obtained when dke.nrLS and dke.nrMS are*/ + /* both FFFF as dke.nrMS is only shifted by 8 before the*/ + /* add and not 16. -kc */ + if (nr==0x0100FEFF) continue; + for (j = 0; j < i; ++j) { + if (nr2da[j].nr == nr) + break; } - if (keys[nr].dkeaddr) { - int x; - - for (x=sizeof(dke);x--;) - if (((char*)&dke)[x]) - break; - if (x==-1) - break; /* finished reading if we got only 0 */ - if (nr) { - if ( (dke.next!=(long)keys[nr].next) || - (dke.nextsub!=(long)keys[nr].nextsub) || - (dke.prevlvl!=(long)keys[nr].prevlvl) - ) - dprintf_reg(stddeb,"key doubled? nr=%ld,key->dkeaddr=%lx,dkeaddr=%lx\n",nr,keys[nr].dkeaddr,dkeaddr); + if (j < i) { + key = nr2da[j].key; + if (key && key->dkeaddr) { + int x; + + for (x=sizeof(dke);x--;) + if (((char*)&dke)[x]) + break; + if (x==-1) + break; /* finished reading if we got only 0 */ + if (nr) { + if ((dke.next!=(long)key->next) || + (dke.nextsub!=(long)key->nextsub) || + (dke.prevlvl!=(long)key->prevlvl) + ) + dprintf_reg(stddeb,"key doubled? nr=%lu,key->dkeaddr=%lx,dkeaddr=%lx\n",nr,key->dkeaddr,dkeaddr); + } + continue; } - continue; } - nr2da[i].nr = nr; +#if DEBUG_W95_LOADREG + dprintf_reg(stddeb,"- nr=%lu,dkeaddr=%lx\n",nr,dkeaddr); +#endif + nr2da[i].nr = nr; nr2da[i].dkeaddr = dkeaddr; + nr2da[i].key = &keys[i]; - keys[nr].dkeaddr = dkeaddr; - keys[nr].x1 = dke.x1; - keys[nr].x2 = dke.x2; - keys[nr].x3 = dke.x3; - keys[nr].prevlvl= (struct _w95key*)dke.prevlvl; - keys[nr].nextsub= (struct _w95key*)dke.nextsub; - keys[nr].next = (struct _w95key*)dke.next; + keys[i].dkeaddr = dkeaddr; + keys[i].x1 = dke.x1; + keys[i].x2 = dke.x2; + keys[i].x3 = dke.x3; + keys[i].prevlvl= (struct _w95key*)dke.prevlvl; + keys[i].nextsub= (struct _w95key*)dke.nextsub; + keys[i].next = (struct _w95key*)dke.next; } free(data); + nrofdkes = i; /* This is the real number of dke entries */ +#if DEBUG_W95_LOADREG + dprintf_reg(stddeb,"nrofdkes = %d\n", nrofdkes); +#endif + qsort(nr2da,nrofdkes,sizeof(nr2da[0]), - (int(*)(const void *,const void*))_w95dkecomp); + (int(*)(const void *,const void *))_w95dkecomp); /* STEP 2: keydata & values */ if (!GetFileInformationByHandle(hfd,&hfdinfo)) @@ -1267,11 +1323,12 @@ _w95_loadreg(char* fn,LPKEYSTRUCT lpkey) { dprintf_reg(stddeb,"third IFF header not RGDB, but %s\n",magic); return; } + curdata=data+0x20; while (1) { struct dkh dkh; - int bytesread; - struct _w95key *key,xkey; + int bytesread; + struct _w95key xkey; /* Used inside second main loop */ bytesread = 0; if (curdata>=nextrgdb) { @@ -1294,19 +1351,26 @@ _w95_loadreg(char* fn,LPKEYSTRUCT lpkey) { XREAD(&dkh,sizeof(dkh)); nr = dkh.nrLS + (dkh.nrMS<<8); - if ((nr>nrofdkes) || (dkh.nrLS == 0xFFFF)) { - if (dkh.nrLS == 0xFFFF) { + if (dkh.nrLS == 0xFFFF) { /* skip over key using nextkeyoff */ curdata+=dkh.nextkeyoff-sizeof(struct dkh); continue; + } + for (i = 0; i < nrofdkes; ++i) { + if (nr2da[i].nr == nr && nr2da[i].dkeaddr) { + key = nr2da[i].key; + break; } - dprintf_reg(stddeb,"haven't found nr %ld.\n",nr); + } + if (i >= nrofdkes) { + /* Move the next statement to just before the previous for */ + /* loop to prevent the compiler from issuing a warning -kc */ key = &xkey; memset(key,'\0',sizeof(xkey)); + dprintf_reg(stddeb,"haven't found nr %lu.\n",nr); } else { - key = keys+nr; if (!key->dkeaddr) - dprintf_reg(stddeb,"key with nr=%ld has no dkeaddr?\n",nr); + dprintf_reg(stddeb,"key with nr=%lu has no dkeaddr?\n",nr); } key->nrofvals = dkh.values; key->name = (char*)xmalloc(dkh.keynamelen+1); @@ -1340,7 +1404,7 @@ _w95_loadreg(char* fn,LPKEYSTRUCT lpkey) { if (bytesread != dkh.nextkeyoff) { if (dkh.bytesused != bytesread) dprintf_reg(stddeb, - "read has difference in read bytes (%d) and nextoffset (%ld) (bytesused=%ld)\n",bytesread,dkh.nextkeyoff, + "read has difference in read bytes (%d) and nextoffset (%lu) (bytesused=%lu)\n",bytesread,dkh.nextkeyoff, dkh.bytesused ); curdata += dkh.nextkeyoff-bytesread; @@ -1353,6 +1417,7 @@ _w95_loadreg(char* fn,LPKEYSTRUCT lpkey) { } free(data); _w95_walk_tree(lpkey,keys); + free(nr2da); free(keys); } diff --git a/misc/shellord.c b/misc/shellord.c index 3a1a6dc909a..1d4f857ebb6 100644 --- a/misc/shellord.c +++ b/misc/shellord.c @@ -83,7 +83,7 @@ BOOL32 WINAPI SHELL32_29(LPCSTR x) { * SHELL32_30 [SHELL32.30] * get_rootdir(char*path,int drive) */ -DWORD WINAPI SHELL32_30(LPSTR root,BYTE drive) { +LPSTR WINAPI SHELL32_30(LPSTR root,BYTE drive) { strcpy(root,"A:\\"); root[0]+=drive; return root; diff --git a/misc/tweak.c b/misc/tweak.c index 0d88d0b7c51..3fa27821cc1 100644 --- a/misc/tweak.c +++ b/misc/tweak.c @@ -33,7 +33,6 @@ #include "graphics.h" #include "options.h" #include "stackframe.h" -#include "syscolor.h" #include "tweak.h" #include "windows.h" diff --git a/misc/ver.c b/misc/ver.c index 883af0d441e..40c3241b0f6 100644 --- a/misc/ver.c +++ b/misc/ver.c @@ -843,8 +843,13 @@ DWORD WINAPI VerFindFile32A( LPSTR curdir,UINT32 *pcurdirlen,LPSTR destdir,UINT32 *pdestdirlen ) { UINT16 curdirlen, destdirlen; - DWORD ret = VerFindFile16(flags,filename,windir,appdir, - curdir,&curdirlen,destdir,&destdirlen); + DWORD ret; + + curdirlen = (UINT16)*pcurdirlen; + destdirlen= (UINT16)*pdestdirlen; + + ret = VerFindFile16(flags,filename,windir,appdir, + curdir,&curdirlen,destdir,&destdirlen); *pcurdirlen = curdirlen; *pdestdirlen = destdirlen; return ret; diff --git a/misc/winsock.c b/misc/winsock.c index b94bb3cc5f3..88c740c0412 100644 --- a/misc/winsock.c +++ b/misc/winsock.c @@ -170,6 +170,10 @@ static fd_set* fd_set_import( fd_set* fds, LPWSINFO pwsi, void* wsfds, int* high FD_SET(pws->fd, fds); } } + if (b32) + wsfds32->fd_count = 0; + else + wsfds16->fd_count = 0; #undef wsfds32 #undef wsfds16 return fds; @@ -791,7 +795,7 @@ INT16 WINAPI WINSOCK_getsockopt16(SOCKET16 s, INT16 level, INT32 *p = &optlen32; INT32 retVal; if( optlen ) optlen32 = *optlen; else p = NULL; - retVal = WINSOCK_getsockopt32( s, level, optname, optval, p ); + retVal = WINSOCK_getsockopt32( s, (UINT16)level, optname, optval, p ); if( optlen ) *optlen = optlen32; return (INT16)retVal; } @@ -1226,7 +1230,7 @@ INT16 WINAPI WINSOCK_setsockopt16(SOCKET16 s, INT16 level, INT16 optname, optval = (char*)&linger32; optlen = sizeof(linger32); } - return (INT16)WINSOCK_setsockopt32( s, level, optname, optval, optlen ); + return (INT16)WINSOCK_setsockopt32( s, (UINT16)level, optname, optval, optlen ); } diff --git a/misc/wsprintf.c b/misc/wsprintf.c index 7d57209d83a..936afd0b129 100644 --- a/misc/wsprintf.c +++ b/misc/wsprintf.c @@ -40,6 +40,8 @@ typedef struct WPRINTF_TYPE type; } WPRINTF_FORMAT; +static const CHAR null_stringA[] = "(null)"; +static const WCHAR null_stringW[] = { '(', 'n', 'u', 'l', 'l', ')', 0 }; /*********************************************************************** * WPRINTF_ParseFormatA @@ -201,11 +203,13 @@ static UINT32 WPRINTF_GetLen( WPRINTF_FORMAT *format, LPCVOID arg, case WPR_WCHAR: return (format->precision = 1); case WPR_STRING: + if (!*(LPCSTR *)arg) *(LPCSTR *)arg = null_stringA; for (len = 0; !format->precision || (len < format->precision); len++) if (!*(*(LPCSTR *)arg + len)) break; if (len > maxlen) len = maxlen; return (format->precision = len); case WPR_WSTRING: + if (!*(LPCWSTR *)arg) *(LPCWSTR *)arg = null_stringW; for (len = 0; !format->precision || (len < format->precision); len++) if (!*(*(LPCWSTR *)arg + len)) break; if (len > maxlen) len = maxlen; diff --git a/msdos/int21.c b/msdos/int21.c index b654e5f4fd5..ae03308ec8c 100644 --- a/msdos/int21.c +++ b/msdos/int21.c @@ -696,7 +696,7 @@ static int INT21_FindNextFCB( CONTEXT *context ) BYTE attr; int count; - if (*fcb == 0xff) + if (*fcb == 0xff) /* extended FCB ? */ { attr = fcb[6]; pFCB = (FINDFILE_FCB *)(fcb + 7); @@ -718,6 +718,14 @@ static int INT21_FindNextFCB( CONTEXT *context ) } pFCB->count += count; + if (*fcb == 0xff) { /* place extended FCB header before pResult if called with extended FCB */ + *(BYTE *)pResult = 0xff; + (BYTE *)pResult +=6; /* leave reserved field behind */ + *(BYTE *)pResult = entry.dwFileAttributes; + ((BYTE *)pResult)++; + } + *(BYTE *)pResult = DOS_GET_DRIVE( pFCB->drive ); /* DOS_DIRENTRY_LAYOUT after current drive number */ + ((BYTE *)pResult)++; pResult->fileattr = entry.dwFileAttributes; pResult->cluster = 0; /* what else? */ pResult->filesize = entry.nFileSizeLow; diff --git a/msdos/int2f.c b/msdos/int2f.c index 2f4d56ef927..755e05bfa09 100644 --- a/msdos/int2f.c +++ b/msdos/int2f.c @@ -57,6 +57,9 @@ void WINAPI INT_Int2fHandler( CONTEXT *context ) case 0xb7: /* append */ AL_reg(context) = 0; /* not installed */ break; + case 0xbd: /* some Novell network install check ??? */ + AX_reg(context) = 0xa5a5; /* pretend to have Novell IPX installed */ + break; default: INT_BARF( context, 0x2f ); break; diff --git a/multimedia/Makefile.in b/multimedia/Makefile.in index 2f2f157861c..f4a288fd43e 100644 --- a/multimedia/Makefile.in +++ b/multimedia/Makefile.in @@ -7,6 +7,7 @@ MODULE = multimedia C_SRCS = \ audio.c \ + dsound.c \ joystick.c \ mcianim.c \ mcicda.c \ diff --git a/multimedia/dsound.c b/multimedia/dsound.c new file mode 100644 index 00000000000..5b3983b7fdc --- /dev/null +++ b/multimedia/dsound.c @@ -0,0 +1,177 @@ +/* DS + */ + +#include +#include "windows.h" +#include "interfaces.h" +#include "mmsystem.h" +#include "dsound.h" + +HRESULT WINAPI DirectSoundEnumerate32A(LPDSENUMCALLBACK32A enumcb,LPVOID context) { + return 0; +} + +static HRESULT WINAPI IDirectSoundBuffer_SetFormat( + LPDIRECTSOUNDBUFFER this,LPWAVEFORMATEX wfex +) { + fprintf(stderr,"IDirectSoundBuffer(%p)->SetFormat(%p),stub!\n",this,wfex); + return 0; +} + +static HRESULT WINAPI IDirectSoundBuffer_SetVolume( + LPDIRECTSOUNDBUFFER this,LONG vol +) { + fprintf(stderr,"IDirectSoundBuffer(%p)->SetVolume(%08lx),stub!\n",this,vol); + return 0; +} + +static HRESULT WINAPI IDirectSoundBuffer_GetVolume( + LPDIRECTSOUNDBUFFER this,LPLONG vol +) { + fprintf(stderr,"IDirectSoundBuffer(%p)->GetVolume(%p),stub!\n",this,vol); + *vol = 100; + return 0; +} + +static HRESULT WINAPI IDirectSoundBuffer_SetFrequency( + LPDIRECTSOUNDBUFFER this,DWORD freq +) { + fprintf(stderr,"IDirectSoundBuffer(%p)->SetFrequency(%08lx),stub!\n",this,freq); + return 0; +} + +static HRESULT WINAPI IDirectSoundBuffer_Play( + LPDIRECTSOUNDBUFFER this,DWORD x,DWORD y,DWORD z +) { + fprintf(stderr,"IDirectSoundBuffer(%p)->Play(%08lx,%08lx,%08lx),stub!\n", + this,x,y,z + ); + return 0; +} + +static HRESULT WINAPI IDirectSoundBuffer_Stop(LPDIRECTSOUNDBUFFER this) { + fprintf(stderr,"IDirectSoundBuffer(%p)->Stop()\n",this); + return 0; +} + +static DWORD WINAPI IDirectSoundBuffer_AddRef(LPDIRECTSOUNDBUFFER this) { + fprintf(stderr,"IDirectSoundBuffer(%p)->AddRef()\n",this); + return ++(this->ref); +} +static DWORD WINAPI IDirectSoundBuffer_Release(LPDIRECTSOUNDBUFFER this) { + fprintf(stderr,"IDirectSoundBuffer(%p)->Release(),stub!\n",this); + if (--this->ref) + return this->ref; + fprintf(stderr," -> IDirectSoundBuffer(%p) freed.\n",this); + HeapFree(GetProcessHeap(),0,this); + return 0; +} + +static HRESULT WINAPI IDirectSoundBuffer_GetCurrentPosition( + LPDIRECTSOUNDBUFFER this,LPDWORD playpos,LPDWORD writepos +) { + fprintf(stderr,"IDirectSoundBuffer(%p)->GetCurrentPosition(%p,%p),stub!\n",this,playpos,writepos); + return 0; +} + +static HRESULT WINAPI IDirectSoundBuffer_GetStatus( + LPDIRECTSOUNDBUFFER this,LPDWORD status +) { + fprintf(stderr,"IDirectSoundBuffer(%p)->GetStatus(%p),stub!\n",this,status); + *status = 0; /* hmm. set playing? or not ? */ + return 0; +} + +static HRESULT WINAPI IDirectSoundBuffer_Lock( + LPDIRECTSOUNDBUFFER this,DWORD x1,DWORD x2,LPVOID p1,LPDWORD x3,LPVOID p2,LPDWORD x4,DWORD x5 +) { + fprintf(stderr,"IDirectSoundBuffer(%p)->Lock(0x%08lx,0x%08lx,%p,%p,%p,%p,0x%08lx,),stub!\n",this,x1,x2,p1,x3,p2,x4,x5); + return 0x80000000; +} + + +static struct tagLPDIRECTSOUNDBUFFER_VTABLE dsbvt = { + (void *)1, + IDirectSoundBuffer_AddRef, + IDirectSoundBuffer_Release, + (void *)4, + IDirectSoundBuffer_GetCurrentPosition, + (void *)6, + IDirectSoundBuffer_GetVolume, + (void *)8, + (void *)9, + IDirectSoundBuffer_GetStatus, + (void *)11, + IDirectSoundBuffer_Lock, + IDirectSoundBuffer_Play, + (void *)14, + IDirectSoundBuffer_SetFormat, + IDirectSoundBuffer_SetVolume, + (void *)17, + IDirectSoundBuffer_SetFrequency, + IDirectSoundBuffer_Stop, + (void *)20 +}; + + + +static HRESULT WINAPI IDirectSound_SetCooperativeLevel( + LPDIRECTSOUND this,HWND32 hwnd,DWORD level +) { + fprintf(stderr,"IDirectSound(%p)->SetCooperativeLevel(%08lx,%ld),stub!\n", + this,(DWORD)hwnd,level + ); + return 0; +} + + +static HRESULT WINAPI IDirectSound_CreateSoundBuffer( + LPDIRECTSOUND this,LPDSBUFFERDESC dsbd,LPLPDIRECTSOUNDBUFFER ppdsb,LPUNKNOWN lpunk +) { + fprintf(stderr,"IDirectSound(%p)->CreateBuffer(%p,%p,%p),stub!\n",this,dsbd,ppdsb,lpunk); + *ppdsb = (LPDIRECTSOUNDBUFFER)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBuffer)); + (*ppdsb)->ref =1; + (*ppdsb)->lpvtbl = &dsbvt; + return 0; +} + +static HRESULT WINAPI IDirectSound_GetCaps(LPDIRECTSOUND this,LPDSCAPS dscaps) { + fprintf(stderr,"IDirectSound(%p)->GetCaps(%p),stub!\n",this,dscaps); + return 0; +} + +static ULONG WINAPI IDirectSound_AddRef(LPDIRECTSOUND this) { + fprintf(stderr,"IDirectSound(%p)->AddRef()\n",this); + return ++(this->ref); +} + +static ULONG WINAPI IDirectSound_Release(LPDIRECTSOUND this) { + fprintf(stderr,"IDirectSound(%p)->Release()\n",this); + if (!--(this->ref)) { + HeapFree(GetProcessHeap(),0,this); + return 0; + } + return this->ref; +} + +static struct tagLPDIRECTSOUND_VTABLE dsvt = { + (void *)1, + IDirectSound_AddRef, + IDirectSound_Release, + IDirectSound_CreateSoundBuffer, + IDirectSound_GetCaps, + (void *)6, + IDirectSound_SetCooperativeLevel, + (void *)8, + (void *)9, + (void *)10, + (void *)11 +}; + +HRESULT WINAPI DirectSoundCreate(LPGUID lpGUID,LPDIRECTSOUND *ppDS,IUnknown *pUnkOuter ) { + fprintf(stderr,"DirectSoundCreate(%p,%p,%p)\n",lpGUID,ppDS,pUnkOuter); + *ppDS = (LPDIRECTSOUND)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSound)); + (*ppDS)->ref = 1; + (*ppDS)->lpvtbl = &dsvt; + return 0; +} diff --git a/multimedia/joystick.c b/multimedia/joystick.c index 97f401602fb..e59ef6506c1 100644 --- a/multimedia/joystick.c +++ b/multimedia/joystick.c @@ -2,6 +2,15 @@ * joystick functions * * Copyright 1997 Andreas Mohr + * + * nearly all joystick functions can be regarded as obsolete, + * as Linux (2.1.x) now supports extended joysticks + * with a completely new joystick driver interface + * new driver's docu says: + * "For backward compatibility the old interface is still included, + * but will be dropped in the future." + * Thus we should implement the new interface and at most keep the old + * routines for backward compatibility. */ #include @@ -250,6 +259,15 @@ MMRESULT16 WINAPI joyGetDevCaps16(UINT16 wID, LPJOYCAPS16 lpCaps, UINT16 wSize) } /************************************************************************** + * JoyGetPosEx [WINMM.31] + */ +MMRESULT32 WINAPI joyGetPosEx(UINT32 wID, LPJOYINFO32 lpInfo) +{ + /* FIXME: implement it */ + return MMSYSERR_NODRIVER; +} + +/************************************************************************** * JoyGetPos [WINMM.30] */ MMRESULT32 WINAPI joyGetPos32(UINT32 wID, LPJOYINFO32 lpInfo) diff --git a/objects/brush.c b/objects/brush.c index 8f2eb8361ad..184eeea1349 100644 --- a/objects/brush.c +++ b/objects/brush.c @@ -7,7 +7,6 @@ #include #include "brush.h" #include "bitmap.h" -#include "syscolor.h" #include "metafile.h" #include "color.h" #include "stddebug.h" @@ -247,80 +246,6 @@ BOOL32 WINAPI FixBrushOrgEx( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 oldorg ) /*********************************************************************** - * GetSysColorBrush16 (USER.281) - */ -HBRUSH16 WINAPI GetSysColorBrush16( INT16 index ) -{ - return (HBRUSH16)GetSysColorBrush32(index); -} - - -/*********************************************************************** - * GetSysColorBrush32 (USER32.289) - */ -HBRUSH32 WINAPI GetSysColorBrush32( INT32 index ) -{ - switch(index){ - case COLOR_SCROLLBAR: - return sysColorObjects.hbrushScrollbar; - case COLOR_BACKGROUND: - return sysColorObjects.hbrushBackground; - case COLOR_ACTIVECAPTION: - return sysColorObjects.hbrushActiveCaption; - case COLOR_INACTIVECAPTION: - return sysColorObjects.hbrushInactiveCaption; - case COLOR_MENU: - return sysColorObjects.hbrushMenu; - case COLOR_WINDOW: - return sysColorObjects.hbrushWindow; - case COLOR_WINDOWFRAME: - return sysColorObjects.hbrushWindowFrame; - case COLOR_MENUTEXT: - return sysColorObjects.hbrushMenuText; - case COLOR_WINDOWTEXT: - return sysColorObjects.hbrushWindowText; - case COLOR_CAPTIONTEXT: - return sysColorObjects.hbrushCaptionText; - case COLOR_ACTIVEBORDER: - return sysColorObjects.hbrushActiveBorder; - case COLOR_INACTIVEBORDER: - return sysColorObjects.hbrushInactiveBorder; - case COLOR_APPWORKSPACE: - return sysColorObjects.hbrushAppWorkspace; - case COLOR_HIGHLIGHT: - return sysColorObjects.hbrushHighlight; - case COLOR_HIGHLIGHTTEXT: - return sysColorObjects.hbrushHighlightText; - case COLOR_BTNFACE: /* same as COLOR_3DFACE */ - return sysColorObjects.hbrushBtnFace; - case COLOR_BTNSHADOW: /* same as COLOR_3DSHADOW */ - return sysColorObjects.hbrushBtnShadow; - case COLOR_GRAYTEXT: - return sysColorObjects.hbrushGrayText; - case COLOR_BTNTEXT: - return sysColorObjects.hbrushBtnText; - case COLOR_INACTIVECAPTIONTEXT: - return sysColorObjects.hbrushInactiveCaptionText; - case COLOR_BTNHIGHLIGHT: /* same as COLOR_(3DHIGH|3DHI|BTNHI)LIGHT */ - return sysColorObjects.hbrushBtnHighlight; - case COLOR_3DDKSHADOW: - return sysColorObjects.hbrush3DDkShadow; - case COLOR_3DLIGHT: - return sysColorObjects.hbrush3DLight; - case COLOR_INFOTEXT: - return sysColorObjects.hbrushInfoText; - case COLOR_INFOBK: - return sysColorObjects.hbrushInfoBk; - default: - fprintf( stderr, "GetSysColorBrush32: Unknown index(%d)\n", index ); - } - - return GetStockObject32(LTGRAY_BRUSH); - -} - - -/*********************************************************************** * BRUSH_DeleteObject */ BOOL32 BRUSH_DeleteObject( HBRUSH16 hbrush, BRUSHOBJ * brush ) diff --git a/objects/cursoricon.c b/objects/cursoricon.c index d77a5f772ab..2ec3b5961bb 100644 --- a/objects/cursoricon.c +++ b/objects/cursoricon.c @@ -761,7 +761,8 @@ HCURSOR32 WINAPI CreateCursor32( HINSTANCE32 hInstance, dprintf_cursor( stddeb, "CreateCursor: %dx%d spot=%d,%d xor=%p and=%p\n", nWidth, nHeight, xHotSpot, yHotSpot, lpXORbits, lpANDbits); - return CreateCursorIconIndirect( hInstance, &info, lpANDbits, lpXORbits ); + return CreateCursorIconIndirect( MODULE_HANDLEtoHMODULE16( hInstance ), + &info, lpANDbits, lpXORbits ); } @@ -791,7 +792,8 @@ HICON32 WINAPI CreateIcon32( HINSTANCE32 hInstance, INT32 nWidth, dprintf_icon( stddeb, "CreateIcon: %dx%dx%d, xor=%p, and=%p\n", nWidth, nHeight, bPlanes * bBitsPixel, lpXORbits, lpANDbits); - return CreateCursorIconIndirect( hInstance, &info, lpANDbits, lpXORbits ); + return CreateCursorIconIndirect( MODULE_HANDLEtoHMODULE16( hInstance ), + &info, lpANDbits, lpXORbits ); } @@ -892,7 +894,7 @@ BOOL32 WINAPI DestroyCursor32( HCURSOR32 hCursor ) { dprintf_cursor( stddeb, "DestroyCursor: %04x\n", hCursor ); /* FIXME: should check for OEM cursor here */ - return (FreeResource16( hCursor ) != 0); + return (FreeResource16( hCursor ) == 0); } diff --git a/objects/dib.c b/objects/dib.c index b5d1cf2d9a3..0f1ef173121 100644 --- a/objects/dib.c +++ b/objects/dib.c @@ -240,13 +240,16 @@ static int *DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth, * * Handles a single line of 1 bit data. */ -static void DIB_SetImageBits_1_Line(DWORD dstwidth, int *colors, +static void DIB_SetImageBits_1_Line(DWORD dstwidth, int left, int *colors, XImage *bmpImage, int h, const BYTE *bits) { BYTE pix; DWORD i, x; - for (i = dstwidth/8, x = 0; (i > 0); i--) + dstwidth += left; bits += left >> 3; + + /* FIXME: should avoid putting x 0); i--) { pix = *bits++; XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); @@ -277,7 +280,7 @@ static void DIB_SetImageBits_1_Line(DWORD dstwidth, int *colors, * SetDIBits for a 1-bit deep DIB. */ static void DIB_SetImageBits_1( int lines, const BYTE *srcbits, - DWORD srcwidth, DWORD dstwidth, + DWORD srcwidth, DWORD dstwidth, int left, int *colors, XImage *bmpImage ) { int h; @@ -287,13 +290,13 @@ static void DIB_SetImageBits_1( int lines, const BYTE *srcbits, if (lines > 0) { for (h = lines-1; h >=0; h--) { - DIB_SetImageBits_1_Line(dstwidth, colors, bmpImage, h, srcbits); + DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h, srcbits); srcbits += linebytes; } } else { lines = -lines; for (h = 0; h < lines; h++) { - DIB_SetImageBits_1_Line(dstwidth, colors, bmpImage, h, srcbits); + DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h, srcbits); srcbits += linebytes; } } @@ -306,38 +309,41 @@ static void DIB_SetImageBits_1( int lines, const BYTE *srcbits, * SetDIBits for a 4-bit deep DIB. */ static void DIB_SetImageBits_4( int lines, const BYTE *srcbits, - DWORD srcwidth, DWORD dstwidth, + DWORD srcwidth, DWORD dstwidth, int left, int *colors, XImage *bmpImage ) { DWORD i, x; int h; - const BYTE *bits = srcbits; + const BYTE *bits = srcbits + (left >> 1); /* 32 bit aligned */ DWORD linebytes = ((srcwidth+7)&~7)/2; + dstwidth += left; + + /* FIXME: should avoid putting x 0) { for (h = lines-1; h >= 0; h--) { - for (i = dstwidth/2, x = 0; i > 0; i--) { + for (i = dstwidth/2, x = left&~1; i > 0; i--) { BYTE pix = *bits++; XPutPixel( bmpImage, x++, h, colors[pix >> 4] ); XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] ); } if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] ); srcbits += linebytes; - bits = srcbits; + bits = srcbits + (left >> 1); } } else { lines = -lines; for (h = 0; h < lines; h++) { - for (i = dstwidth/2, x = 0; i > 0; i--) { + for (i = dstwidth/2, x = left&~1; i > 0; i--) { BYTE pix = *bits++; XPutPixel( bmpImage, x++, h, colors[pix >> 4] ); XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] ); } if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] ); srcbits += linebytes; - bits = srcbits; + bits = srcbits + (left >> 1); } } } @@ -355,11 +361,13 @@ static void DIB_SetImageBits_4( int lines, const BYTE *srcbits, * SetDIBits for a 4-bit deep compressed DIB. */ static void DIB_SetImageBits_RLE4( int lines, const BYTE *bits, DWORD width, - DWORD dstwidth, int *colors, XImage *bmpImage ) + DWORD dstwidth, int left, int *colors, XImage *bmpImage ) { int x = 0, c, length; const BYTE *begin = bits; + dstwidth += left; /* FIXME: avoid putting x= 0) { @@ -415,30 +423,32 @@ static void DIB_SetImageBits_RLE4( int lines, const BYTE *bits, DWORD width, * SetDIBits for an 8-bit deep DIB. */ static void DIB_SetImageBits_8( int lines, const BYTE *srcbits, - DWORD srcwidth, DWORD dstwidth, + DWORD srcwidth, DWORD dstwidth, int left, int *colors, XImage *bmpImage ) { DWORD x; int h; - const BYTE *bits = srcbits; + const BYTE *bits = srcbits + left; /* align to 32 bit */ DWORD linebytes = (srcwidth + 3) & ~3; + dstwidth+=left; + if (lines > 0) { for (h = lines - 1; h >= 0; h--) { - for (x = 0; x < dstwidth; x++, bits++) { + for (x = left; x < dstwidth; x++, bits++) { XPutPixel( bmpImage, x, h, colors[*bits] ); } - bits = (srcbits += linebytes); + bits = (srcbits += linebytes) + left; } } else { lines = -lines; for (h = 0; h < lines; h++) { - for (x = 0; x < dstwidth; x++, bits++) { + for (x = left; x < dstwidth; x++, bits++) { XPutPixel( bmpImage, x, h, colors[*bits] ); } - bits = (srcbits += linebytes); + bits = (srcbits += linebytes) + left; } } } @@ -475,7 +485,7 @@ enum Rle8_EscapeCodes }; static void DIB_SetImageBits_RLE8( int lines, const BYTE *bits, DWORD width, - DWORD dstwidth, int *colors, XImage *bmpImage ) + DWORD dstwidth, int left, int *colors, XImage *bmpImage ) { int x; /* X-positon on each line. Increases. */ int line; /* Line #. Starts at lines-1, decreases */ @@ -488,6 +498,8 @@ static void DIB_SetImageBits_RLE8( int lines, const BYTE *bits, DWORD width, if (lines == 0) /* Let's hope this doesn't happen. */ return; + dstwidth += left; /* FIXME: avoid putting x 0) { for (h = lines - 1; h >= 0; h--) { - for (x = 0; x < dstwidth; x++, ptr++) { + for (x = left; x < dstwidth; x++, ptr++) { val = *ptr; r = (BYTE) ((val & 0x7c00) >> 7); g = (BYTE) ((val & 0x03e0) >> 2); @@ -651,12 +665,12 @@ static void DIB_SetImageBits_16( int lines, const BYTE *srcbits, XPutPixel( bmpImage, x, h, COLOR_ToPhysical(dc, RGB(r,g,b)) ); } - ptr = (LPWORD) (srcbits += linebytes); + ptr = (LPWORD) (srcbits += linebytes) + left; } } else { lines = -lines; for (h = 0; h < lines; h++) { - for (x = 0; x < dstwidth; x++, ptr++) { + for (x = left; x < dstwidth; x++, ptr++) { val = *ptr; r = (BYTE) ((val & 0x7c00) >> 7); g = (BYTE) ((val & 0x03e0) >> 2); @@ -664,7 +678,7 @@ static void DIB_SetImageBits_16( int lines, const BYTE *srcbits, XPutPixel( bmpImage, x, h, COLOR_ToPhysical(dc, RGB(r,g,b)) ); } - ptr = (LPWORD) (srcbits += linebytes); + ptr = (LPWORD) (srcbits += linebytes) + left; } } } @@ -676,34 +690,36 @@ static void DIB_SetImageBits_16( int lines, const BYTE *srcbits, * SetDIBits for a 24-bit deep DIB. */ static void DIB_SetImageBits_24( int lines, const BYTE *srcbits, - DWORD srcwidth, DWORD dstwidth, + DWORD srcwidth, DWORD dstwidth, int left, DC *dc, XImage *bmpImage ) { DWORD x; - const BYTE *bits = srcbits; + const BYTE *bits = srcbits + left * 3; int h; /* align to 32 bit */ DWORD linebytes = (srcwidth * 3 + 3) & ~3; + dstwidth += left; + /* "bits" order is reversed for some reason */ if (lines > 0) { for (h = lines - 1; h >= 0; h--) { - for (x = 0; x < dstwidth; x++, bits += 3) { + for (x = left; x < dstwidth; x++, bits += 3) { XPutPixel( bmpImage, x, h, COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0]))); } - bits = (srcbits += linebytes); + bits = (srcbits += linebytes) + left * 3; } } else { lines = -lines; for (h = 0; h < lines; h++) { - for (x = 0; x < dstwidth; x++, bits += 3) { + for (x = left; x < dstwidth; x++, bits += 3) { XPutPixel( bmpImage, x, h, COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0]))); } - bits = (srcbits += linebytes); + bits = (srcbits += linebytes) + left * 3; } } } @@ -715,31 +731,33 @@ static void DIB_SetImageBits_24( int lines, const BYTE *srcbits, * SetDIBits for a 32-bit deep DIB. */ static void DIB_SetImageBits_32( int lines, const BYTE *srcbits, - DWORD srcwidth, DWORD dstwidth, + DWORD srcwidth, DWORD dstwidth, int left, DC *dc, XImage *bmpImage ) { DWORD x; - const BYTE *bits = srcbits; + const BYTE *bits = srcbits + left * 4; int h; DWORD linebytes = (srcwidth * 4); + dstwidth += left; + if (lines > 0) { for (h = lines - 1; h >= 0; h--) { - for (x = 0; x < dstwidth; x++, bits += 4) { + for (x = left; x < dstwidth; x++, bits += 4) { XPutPixel( bmpImage, x, h, COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0]))); } - bits = (srcbits += linebytes); + bits = (srcbits += linebytes) + left * 4; } } else { lines = -lines; for (h = 0; h < lines; h++) { - for (x = 0; x < dstwidth; x++, bits += 4) { + for (x = left; x < dstwidth; x++, bits += 4) { XPutPixel( bmpImage, x, h, COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0]))); } - bits = (srcbits += linebytes); + bits = (srcbits += linebytes) + left * 4; } } } @@ -779,34 +797,34 @@ static int DIB_SetImageBits( const DIB_SETIMAGEBITS_DESCR *descr ) { case 1: DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth, - descr->width, colorMapping, bmpImage ); + descr->width, descr->xSrc, colorMapping, bmpImage ); break; case 4: if (compression) DIB_SetImageBits_RLE4( descr->lines, descr->bits, - descr->infoWidth, descr->width, + descr->infoWidth, descr->width, descr->xSrc, colorMapping, bmpImage ); else DIB_SetImageBits_4( descr->lines, descr->bits, descr->infoWidth, - descr->width, colorMapping, bmpImage ); + descr->width, descr->xSrc, colorMapping, bmpImage ); break; case 8: if (compression) DIB_SetImageBits_RLE8( descr->lines, descr->bits, - descr->infoWidth, descr->width, + descr->infoWidth, descr->width, descr->xSrc, colorMapping, bmpImage ); else DIB_SetImageBits_8( descr->lines, descr->bits, descr->infoWidth, - descr->width, colorMapping, bmpImage ); + descr->width, descr->xSrc, colorMapping, bmpImage ); break; case 15: case 16: DIB_SetImageBits_16( descr->lines, descr->bits, descr->infoWidth, - descr->width, descr->dc, bmpImage); + descr->width, descr->xSrc, descr->dc, bmpImage); break; case 24: DIB_SetImageBits_24( descr->lines, descr->bits, descr->infoWidth, - descr->width, descr->dc, bmpImage ); + descr->width, descr->xSrc, descr->dc, bmpImage ); break; case 32: DIB_SetImageBits_32( descr->lines, descr->bits, descr->infoWidth, - descr->width, descr->dc, bmpImage); + descr->width, descr->xSrc, descr->dc, bmpImage); break; default: fprintf( stderr, "Invalid depth %d for SetDIBits!\n", descr->infoBpp ); @@ -956,7 +974,7 @@ INT32 WINAPI SetDIBitsToDevice32(HDC32 hdc, INT32 xDest, INT32 yDest, DWORD cx, { DIB_SETIMAGEBITS_DESCR descr; DC * dc; - DWORD width; + DWORD width, oldcy = cy; int height, tmpheight; /* Check parameters */ @@ -994,9 +1012,9 @@ INT32 WINAPI SetDIBitsToDevice32(HDC32 hdc, INT32 xDest, INT32 yDest, DWORD cx, descr.drawable = dc->u.x.drawable; descr.gc = dc->u.x.gc; descr.xSrc = xSrc; - descr.ySrc = ySrc - startscan; + descr.ySrc = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy) : ySrc - startscan; descr.xDest = dc->w.DCOrgX + XLPTODP( dc, xDest ); - descr.yDest = dc->w.DCOrgY + YLPTODP( dc, yDest ); + descr.yDest = dc->w.DCOrgY + YLPTODP( dc, yDest ) + (tmpheight >= 0 ? oldcy-cy : 0); descr.width = cx; descr.height = cy; @@ -1409,13 +1427,14 @@ HBITMAP32 WINAPI CreateDIBSection32 (HDC32 hdc, BITMAPINFO *bmi, UINT32 usage, BITMAP32 bmp; if (GetObject32A (res, sizeof (bmp), &bmp)) { - *bits = bmp.bmBits; - return res; + /* FIXME: this is wrong! (bmBits is always NULL) */ + if (bits) *bits = bmp.bmBits; + return res; } } /* Error. */ if (res) DeleteObject32 (res); - *bits = NULL; - return 0; + if (bits) *bits = NULL; + return 0; } diff --git a/objects/palette.c b/objects/palette.c index f7f4a0426f4..a1f61531a86 100644 --- a/objects/palette.c +++ b/objects/palette.c @@ -284,7 +284,7 @@ BOOL32 WINAPI AnimatePalette32( HPALETTE32 hPal, UINT32 StartIndex, { PALETTEOBJ* palPtr = (PALETTEOBJ *)GDI_GetObjPtr(hPal, PALETTE_MAGIC); - if( (StartIndex + NumEntries) < palPtr->logpalette.palNumEntries ) + if( (StartIndex + NumEntries) <= palPtr->logpalette.palNumEntries ) { UINT32 u; for( u = 0; u < NumEntries; u++ ) diff --git a/objects/region.c b/objects/region.c index 65951eaf2e4..c68686f08b7 100644 --- a/objects/region.c +++ b/objects/region.c @@ -796,3 +796,13 @@ done: return result; } +/*********************************************************************** + * GetRegionData (GDI32.217) + * + * This seems to be rather impossible with the current region implementation + * for it seems you cannot query X regions. + */ +DWORD WINAPI GetRegionData(HRGN32 hrgn,DWORD x,LPRGNDATA rgndata) { + fprintf(stderr,"GetRegionData(%04x,%08lx,%p), STUB!\n",hrgn,x,rgndata); + return 0; +} diff --git a/ole/compobj.c b/ole/compobj.c index 7287bfef6dc..96a300ecada 100644 --- a/ole/compobj.c +++ b/ole/compobj.c @@ -18,6 +18,8 @@ #include "compobj.h" #include "interfaces.h" #include "shlobj.h" +#include "ddraw.h" +#include "dsound.h" DWORD currentMalloc=0; diff --git a/ole/folders.c b/ole/folders.c index cf0def5127d..45d54662f71 100644 --- a/ole/folders.c +++ b/ole/folders.c @@ -45,11 +45,13 @@ static HRESULT WINAPI IEnumIDList_Next( } static IEnumIDList_VTable eidlvt = { - 1, + (void *)1, IEnumIDList_AddRef, IEnumIDList_Release, IEnumIDList_Next, - 5,6,7 + (void *)5, + (void *)6, + (void *)7 }; LPENUMIDLIST IEnumIDList_Constructor() { @@ -109,7 +111,7 @@ static HRESULT WINAPI IShellFolder_ParseDisplayName( fprintf(stderr,"IShellFolder(%p)->ParseDisplayName(%08x,%p,%s,%p,%p,%p),stub!\n", this,hwndOwner,pbcReserved,lpszDisplayName,pchEaten,ppidl,pdwAttributes ); - *(DWORD*)pbcReserved = NULL; + *(DWORD*)pbcReserved = 0; return 0; } @@ -133,22 +135,25 @@ static HRESULT WINAPI IShellFolder_CreateViewObject( fprintf(stderr,"IShellFolder(%p)->CreateViewObject(0x%04x,%s,%p),stub!\n", this,hwndOwner,xclsid,ppv ); - *(DWORD*)ppv = NULL; + *(DWORD*)ppv = 0; return 0; } static struct IShellFolder_VTable sfvt = { - 1, + (void *)1, IShellFolder_AddRef, IShellFolder_Release, IShellFolder_ParseDisplayName, IShellFolder_EnumObjects, IShellFolder_BindToObject, - 7,8, + (void *)7, + (void *)8, IShellFolder_CreateViewObject, IShellFolder_GetAttributesOf, - 11,12,13 + (void *)11, + (void *)12, + (void *)13 }; LPSHELLFOLDER IShellFolder_Constructor() { @@ -161,7 +166,27 @@ LPSHELLFOLDER IShellFolder_Constructor() { } static struct IShellLink_VTable slvt = { - 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21 + (void *)1, + (void *)2, + (void *)3, + (void *)4, + (void *)5, + (void *)6, + (void *)7, + (void *)8, + (void *)9, + (void *)10, + (void *)11, + (void *)12, + (void *)13, + (void *)14, + (void *)15, + (void *)16, + (void *)17, + (void *)18, + (void *)19, + (void *)20, + (void *)21 }; LPSHELLLINK IShellLink_Constructor() { diff --git a/programs/notepad/ChangeLog b/programs/notepad/ChangeLog index aca5fa07f87..0a13af9a954 100644 --- a/programs/notepad/ChangeLog +++ b/programs/notepad/ChangeLog @@ -1,3 +1,8 @@ +Tue Dec 23 23:35:04 1997 Marcel Baur + * Fixed lots of bugs w/ resources in *.rc + * moved [notepad.c] into [main.c] + * moved [notepad.h] into [main.h] + Fri Dec 05 20:51:55 1997 Marcel Baur * [notepad.c] [notepad.h] [notepad.rc] [En.rc] [De.rc] [license.c] [license.h] [License_En.c] diff --git a/programs/notepad/De.rc b/programs/notepad/De.rc index ca2a109e19d..33139b6d700 100644 --- a/programs/notepad/De.rc +++ b/programs/notepad/De.rc @@ -59,7 +59,7 @@ #define DIALOG_PAGESETUP_TAIL "&Fußzeile:" #define DIALOG_PAGESETUP_BORDERS "Ränder" #define DIALOG_PAGESETUP_LEFT "&Links:" -#define DIALOG_PAGESETUP_RIGHT "&Right:" +#define DIALOG_PAGESETUP_RIGHT "&Rechts:" #define DIALOG_PAGESETUP_TOP "&Oben:" #define DIALOG_PAGESETUP_BOTTOM "&Unten:" @@ -73,7 +73,7 @@ #define STRING_UNTITLED "(unbenannt)" #define STRING_ALLFILES "Alle Dateien (*.*)" -#define STRING_TEXTFILES "Textdateien (*.TXT)" +#define STRING_TEXTFILES "Textdateien (*.txt)" #define STRING_TOOLARGE "'%s' ist zu gross für den Editor\n \ Benutzen Sie bitte einen anderen Editor, um diese Datei zu bearbeiten." @@ -88,4 +88,4 @@ gespeichert\n werden k um diese Funktion \nabzuschließen. Beenden Sie eine oder mehrere \ \nAnwendungen, um den verfügbaren Arbeitsspeicher zu \nerhöhen." - +#include "notepad.rc" diff --git a/programs/notepad/En.rc b/programs/notepad/En.rc index 35ab98a4d59..e4ebc9ef67a 100644 --- a/programs/notepad/En.rc +++ b/programs/notepad/En.rc @@ -73,7 +73,7 @@ #define STRING_UNTITLED "(untitled)" #define STRING_ALLFILES "All files (*.*)" -#define STRING_TEXTFILES "Text files (*.*)" +#define STRING_TEXTFILES "Text files (*.txt)" #define STRING_TOOLARGE "File '%s' ist too large for notepad.\n \ Please use a different editor." @@ -87,5 +87,5 @@ Please use a different editor." task. \nClose one or more applications to increase the amount of \nfree \ memory." - +#include "notepad.rc" diff --git a/programs/notepad/Makefile.in b/programs/notepad/Makefile.in index f8a83d6fee3..ed5ffe1d32a 100644 --- a/programs/notepad/Makefile.in +++ b/programs/notepad/Makefile.in @@ -5,7 +5,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = none PROGRAMS = notepad -ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS) +ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS) RCFLAGS = -w32 -h LANGUAGES = En De @@ -13,15 +13,13 @@ LICENSELANG = En MOSTSRCS = \ license.c \ - notepad.c + main.c # Some strings need addresses >= 0x10000 STRINGSRCS = \ $(LICENSELANG:%=License_%.c) -RC_SRCS = \ - notepad.rc \ - $(LANGUAGES:%=%.rc) +RC_SRCS = $(LANGUAGES:%=%.rc) C_SRCS = $(MOSTSRCS) $(STRINGSRCS) diff --git a/programs/notepad/main.c b/programs/notepad/main.c new file mode 100644 index 00000000000..b236c098856 --- /dev/null +++ b/programs/notepad/main.c @@ -0,0 +1,245 @@ +/* + * Notepad + * + * Copyright 1997 Marcel Baur + */ + +#include + +#include "main.h" +#include "license.h" + +NOTEPAD_GLOBALS Globals; + +CHAR STRING_MENU_Xx[] = "MENU_En"; +CHAR STRING_PAGESETUP_Xx[] = "DIALOG_PAGESETUP_En"; + +/*********************************************************************** + * + * NOTEPAD_RegisterLanguages + * + * Handle language stuff at startup + */ + +void NOTEPAD_RegisterLanguages(void) { + + LPCSTR opt_lang = "En"; + CHAR lang[3]; + INT langnum; + + /* Find language specific string table */ + for (langnum = 0; langnum <= MAX_LANGUAGE_NUMBER; langnum++) + { + Globals.wStringTableOffset = langnum * 0x100; + if (LoadString(Globals.hInstance, IDS_LANGUAGE_ID, lang, + sizeof(lang)) && !lstrcmp(opt_lang, lang)) + break; + } + if (langnum > MAX_LANGUAGE_NUMBER) + { + /* Find fallback language */ + for (langnum = 0; langnum <= MAX_LANGUAGE_NUMBER; langnum++) + { + Globals.wStringTableOffset = langnum * 0x100; + if (LoadString(Globals.hInstance, IDS_LANGUAGE_ID, lang, sizeof(lang))) + break; + } + if (langnum > MAX_LANGUAGE_NUMBER) + { + MessageBox(0, "No language found", "FATAL ERROR", MB_OK); + return(1); + } + } + + /* Change Resource names */ + lstrcpyn(STRING_MENU_Xx + lstrlen(STRING_MENU_Xx) - 2, lang, 3); +} + + +/*********************************************************************** + * + * NOTEPAD_MenuCommand + * + * All handling of main menu events + */ + +int NOTEPAD_MenuCommand (WPARAM wParam) +{ + printf("NOTEPAD_MenuCommand()\n"); + + switch (wParam) { + case NP_FILE_NEW: break; + case NP_FILE_SAVE: break; + case NP_FILE_SAVEAS: break; + case NP_FILE_PRINT: break; + case NP_FILE_PAGESETUP: break; + case NP_FILE_PRINTSETUP: break; + + case NP_FILE_EXIT: + PostQuitMessage(0); + break; + + case NP_EDIT_UNDO: break; + case NP_EDIT_CUT: break; + case NP_EDIT_COPY: break; + case NP_EDIT_PASTE: break; + case NP_EDIT_DELETE: break; + case NP_EDIT_TIMEDATE: break; + case NP_EDIT_WRAP: break; + + case NP_SEARCH_SEARCH: break; + case NP_SEARCH_NEXT: break; + + case NP_HELP_CONTENTS: + printf("NP_HELP_CONTENTS\n"); + WinHelp(Globals.hMainWnd, HELPFILE, HELP_INDEX, 0); + break; + + case NP_HELP_SEARCH: break; + + case NP_HELP_ON_HELP: + printf("NP_HELP_ON_HELP\n"); + WinHelp(Globals.hMainWnd, HELPFILE, HELP_HELPONHELP, 0); + break; + + case NP_HELP_LICENSE: + WineLicense(Globals.hMainWnd, Globals.lpszLanguage); + break; + + case NP_HELP_NO_WARRANTY: + printf("NP_ABOUT_NO_WARRANTY\n"); + WineWarranty(Globals.hMainWnd, Globals.lpszLanguage); + break; + + case NP_HELP_ABOUT_WINE: + printf("NP_ABOUT_WINE\n"); + ShellAbout(Globals.hMainWnd, "WINE", "Notepad", 0); + break; + + } + return 0; +} + + + +/*********************************************************************** + * + * NOTEPAD_WndProc + */ + +LRESULT NOTEPAD_WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + PAINTSTRUCT ps; + + switch (msg) { + + case WM_CREATE: + printf("WM_CREATE\n"); + break; + + case WM_PAINT: + printf("WM_PAINT\n"); + BeginPaint(hWnd, &ps); + EndPaint(hWnd, &ps); + break; + + case WM_COMMAND: + printf("WM_COMMAND\n"); + NOTEPAD_MenuCommand(wParam); + break; + + case WM_DESTROY: + printf("WM_DESTROY\n"); + PostQuitMessage (0); + break; + + default: + return DefWindowProc (hWnd, msg, wParam, lParam); + } + return 0l; +} + + + +/*********************************************************************** + * + * WinMain + */ + +void DumpGlobals(void) { + + printf("DumpGlobals()"); + printf(" Globals.lpszIniFile: %s\n", Globals.lpszIniFile); + printf(" Globals.lpszIcoFile: %s\n", Globals.lpszIcoFile); + printf("Globals.lpszLanguage: %s\n", Globals.lpszLanguage); + printf(" Globals.hInstance: %i\n", Globals.hInstance); + printf(" Globals.hMainMenu: %i\n", Globals.hMainMenu); + +} + +int PASCAL WinMain (HANDLE hInstance, HANDLE prev, LPSTR cmdline, int show) +{ + MSG msg; + WNDCLASS class; + char className[] = "NPClass"; /* To make sure className >= 0x10000 */ + char winName[] = "Notepad"; + + printf("WinMain()\n"); + + /* Setup Globals */ + + Globals.lpszIniFile = "notepad.ini"; + Globals.lpszIcoFile = "notepad.ico"; + Globals.lpszLanguage = "En"; + Globals.hInstance = hInstance; + Globals.hMainMenu = LoadMenu(Globals.hInstance, STRING_MENU_Xx); + Globals.hFileMenu = GetSubMenu(Globals.hMainMenu, 0); + Globals.hEditMenu = GetSubMenu(Globals.hMainMenu, 1); + Globals.hSearchMenu = GetSubMenu(Globals.hMainMenu, 2); + Globals.hLanguageMenu = GetSubMenu(Globals.hMainMenu, 3); + Globals.hHelpMenu = GetSubMenu(Globals.hMainMenu, 4); + Globals.hMainIcon = ExtractIcon(Globals.hInstance, + Globals.lpszIcoFile, 0); + if (!Globals.hMainIcon) Globals.hMainIcon = + LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON)); + + DumpGlobals(); + + if (!prev){ + class.style = CS_HREDRAW | CS_VREDRAW; + class.lpfnWndProc = NOTEPAD_WndProc; + class.cbClsExtra = 0; + class.cbWndExtra = 0; + class.hInstance = Globals.hInstance; + class.hIcon = LoadIcon (0, IDI_APPLICATION); + class.hCursor = LoadCursor (0, IDC_ARROW); + class.hbrBackground = GetStockObject (WHITE_BRUSH); + class.lpszMenuName = "bla\0"; + class.lpszClassName = (SEGPTR)className; + } + if (!RegisterClass (&class)) + return FALSE; + + Globals.hMainWnd = CreateWindow (className, winName, WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, + LoadMenu(Globals.hInstance, STRING_MENU_Xx), + Globals.hInstance, 0); + + SetMenu(Globals.hMainWnd, Globals.hMainMenu); + + ShowWindow (Globals.hMainWnd, show); + UpdateWindow (Globals.hMainWnd); + + while (GetMessage (&msg, 0, 0, 0)) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + return 0; +} + + + + +/* Local Variables: */ +/* c-file-style: "GNU" */ +/* End: */ diff --git a/programs/notepad/main.h b/programs/notepad/main.h new file mode 100644 index 00000000000..3c701b5f176 --- /dev/null +++ b/programs/notepad/main.h @@ -0,0 +1,99 @@ +/* + * Notepad (notepad.h) + * + * Copyright 1997 Marcel Baur + */ + +#define MAX_STRING_LEN 255 +#define MAX_PATHNAME_LEN 1024 +#define MAX_LANGUAGE_NUMBER (NP_LAST_LANGUAGE - NP_FIRST_LANGUAGE) + +#define HELPFILE "notepad.hlp" +#define DEFAULTICON OIC_WINEICON + +/* hide the following from winerc */ +#ifndef RC_INVOKED + +typedef struct +{ + HANDLE hInstance; + HWND hMainWnd; + HICON hMainIcon; + HICON hDefaultIcon; + HMENU hMainMenu; + HMENU hFileMenu; + HMENU hEditMenu; + HMENU hSearchMenu; + HMENU hLanguageMenu; + HMENU hHelpMenu; + LPCSTR lpszIniFile; + LPCSTR lpszIcoFile; + LPCSTR lpszLanguage; + UINT wStringTableOffset; +} NOTEPAD_GLOBALS; + +extern NOTEPAD_GLOBALS Globals; + +/* function prototypes */ + +/* class names */ + +/* resource names */ +// extern CHAR[] STRING_MENU_Xx; + + #define STRINGID(id) (0x##id + Globals.wStringTableOffset) + +#else /* RC_INVOKED */ + + #define STRINGID(id) id + +#endif + +/* string table index */ +#define IDS_LANGUAGE_ID STRINGID(00) + +/* main menu */ + +#define NP_FILE_NEW 100 +#define NP_FILE_OPEN 101 +#define NP_FILE_SAVE 102 +#define NP_FILE_SAVEAS 103 +#define NP_FILE_PRINT 104 +#define NP_FILE_PAGESETUP 105 +#define NP_FILE_PRINTSETUP 106 +#define NP_FILE_EXIT 107 + +#define NP_EDIT_UNDO 200 +#define NP_EDIT_CUT 201 +#define NP_EDIT_COPY 202 +#define NP_EDIT_PASTE 203 +#define NP_EDIT_DELETE 204 +#define NP_EDIT_SELECTALL 205 +#define NP_EDIT_TIMEDATE 206 +#define NP_EDIT_WRAP 207 + +#define NP_SEARCH_SEARCH 300 +#define NP_SEARCH_NEXT 301 + +#define NP_FIRST_LANGUAGE 400 +#define NP_LAST_LANGUAGE 499 + +#define NP_HELP_CONTENTS 500 +#define NP_HELP_SEARCH 501 +#define NP_HELP_ON_HELP 502 +#define NP_HELP_LICENSE 503 +#define NP_HELP_NO_WARRANTY 504 +#define NP_HELP_ABOUT_WINE 505 + + +/* Dialog `Page Setup' */ + +#define NP_PAGESETUP_LEFT 1000 +#define NP_PAGESETUP_RIGHT 1001 +#define NP_PAGESETUP_TOP 1002 +#define NP_PAGESETUP_BOTTOM 1003 + + +/* Local Variables: */ +/* c-file-style: "GNU" */ +/* End: */ diff --git a/programs/notepad/notepad.rc b/programs/notepad/notepad.rc index 0079af5f99e..c3d4748622d 100644 --- a/programs/notepad/notepad.rc +++ b/programs/notepad/notepad.rc @@ -4,22 +4,25 @@ * Copyright 1997 Marcel Baur */ -#define CONCAT(a, b) a##b +#include "main.h" + +#define CONCAT(a, b) CONCAT1(a, b) +#define CONCAT1(a, b) a##b /* Main Menu */ CONCAT(MENU_, LANGUAGE_ID) MENU { POPUP MENU_FILE { - MENUITEM MENU_FILE_NEW, NP_NEW - MENUITEM MENU_FILE_OPEN, NP_OPEN - MENUITEM MENU_FILE_SAVE, NP_SAVE - MENUITEM MENU_FILE_SAVEAS, NP_SAVEAS - MENUITEM MENU_FILE_PRINT, NP_PRINT - MENUITEM MENU_FILE_PAGESETUP, NP_PAGESETUP - MENUITEM MENU_FILE_PRINTSETUP, NP_PRINTSETUP + MENUITEM MENU_FILE_NEW, NP_FILE_NEW + MENUITEM MENU_FILE_OPEN, NP_FILE_OPEN + MENUITEM MENU_FILE_SAVE, NP_FILE_SAVE + MENUITEM MENU_FILE_SAVEAS, NP_FILE_SAVEAS + MENUITEM MENU_FILE_PRINT, NP_FILE_PRINT + MENUITEM MENU_FILE_PAGESETUP, NP_FILE_PAGESETUP + MENUITEM MENU_FILE_PRINTSETUP, NP_FILE_PRINTSETUP MENUITEM SEPARATOR - MENUITEM MENU_FILE_EXIT, NP_EXIT + MENUITEM MENU_FILE_EXIT, NP_FILE_EXIT } POPUP MENU_EDIT { MENUITEM MENU_EDIT_UNDO, NP_EDIT_UNDO @@ -43,16 +46,15 @@ CONCAT(MENU_, LANGUAGE_ID) MENU MENUITEM SEPARATOR } POPUP MENU_HELP { - MENUITEM MENU_HELP_CONTENTS, PM_CONTENTS - MENUITEM MENU_HELP_SEARCH, PM_SEARCH - MENUITEM MENU_HELP_HELP_ON_HELP, PM_HELPONHELP + MENUITEM MENU_HELP_CONTENTS, NP_HELP_CONTENTS + MENUITEM MENU_HELP_SEARCH, NP_HELP_SEARCH + MENUITEM MENU_HELP_HELP_ON_HELP, NP_HELP_ON_HELP MENUITEM SEPARATOR POPUP MENU_INFO { - MENUITEM MENU_INFO_LICENSE, PM_LICENSE - MENUITEM MENU_INFO_NO_WARRANTY, PM_NO_WARRANTY - MENUITEM MENU_INFO_ABOUT_WINE, PM_ABOUT_WINE - } -} + MENUITEM MENU_INFO_LICENSE, NP_HELP_LICENSE + MENUITEM MENU_INFO_NO_WARRANTY, NP_HELP_NO_WARRANTY + MENUITEM MENU_INFO_ABOUT_WINE, NP_HELP_ABOUT_WINE + } } diff --git a/programs/progman/Makefile.in b/programs/progman/Makefile.in index 39e72fd79d5..222f96c1be9 100644 --- a/programs/progman/Makefile.in +++ b/programs/progman/Makefile.in @@ -5,7 +5,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = none PROGRAMS = progman -ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS) +ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS) RCFLAGS = -w32 -h LANGUAGES = En Da De Fr Fi Ko Hu It Va diff --git a/programs/progman/Va.rc b/programs/progman/Va.rc index 3d5963c1538..b1a8d0bd05a 100644 --- a/programs/progman/Va.rc +++ b/programs/progman/Va.rc @@ -3,12 +3,12 @@ * * Copyright 1996 Ulrich Schmid * - * Rumantsch Ladin (Vallader) added by mbaur@g26.ethz.ch + * Rumantsch Ladin (Vallader) added by Marcel Baur * */ -#define LANGUAGE_ID Rl -#define LANGUAGE_NUMBER 2 +#define LANGUAGE_ID Va +#define LANGUAGE_NUMBER C #define LANGUAGE_MENU_ITEM "&Vallader" /* Menu */ diff --git a/programs/progman/license.c b/programs/progman/license.c index c73dc26ae12..b781b653c28 100644 --- a/programs/progman/license.c +++ b/programs/progman/license.c @@ -4,13 +4,21 @@ static LICENSE* SelectLanguage(LPCSTR Language) { #if 0 - if (!lstrcmp(Language, "Da")) return(&WineLicense_Cz); + if (!lstrcmp(Language, "Cz")) return(&WineLicense_Cz); if (!lstrcmp(Language, "Da")) return(&WineLicense_Da); if (!lstrcmp(Language, "De")) return(&WineLicense_De); + if (!lstrcmp(Language, "En")) return(&WineLicense_En); + if (!lstrcmp(Language, "Eo")) return(&WineLicense_Eo); if (!lstrcmp(Language, "Es")) return(&WineLicense_Es); if (!lstrcmp(Language, "Fi")) return(&WineLicense_Fi); if (!lstrcmp(Language, "Fr")) return(&WineLicense_Fr); + if (!lstrcmp(Language, "Hu")) return(&WineLicense_Hu); + if (!lstrcmp(Language, "It")) return(&WineLicense_It); + if (!lstrcmp(Language, "Ko")) return(&WineLicense_Ko); if (!lstrcmp(Language, "No")) return(&WineLicense_No); + if (!lstrcmp(Language, "Pl")) return(&WineLicense_Pl); + if (!lstrcmp(Language, "Po")) return(&WineLicense_Po); + if (!lstrcmp(Language, "Va")) return(&WineLicense_Va); #endif return(&WineLicense_En); } diff --git a/programs/progman/license.h b/programs/progman/license.h index 97fa9ba383f..112e38faf21 100644 --- a/programs/progman/license.h +++ b/programs/progman/license.h @@ -7,5 +7,18 @@ typedef struct LPCSTR Warranty, WarrantyCaption; } LICENSE; -extern LICENSE WineLicense_Cz, WineLicense_Da, WineLicense_De, WineLicense_En; -extern LICENSE WineLicense_Es, WineLicense_Fi, WineLicense_Fr, WineLicense_No; +extern LICENSE WineLicense_Cz; +extern LICENSE WineLicense_Da; +extern LICENSE WineLicense_De; +extern LICENSE WineLicense_En; +extern LICENSE WineLicense_Eo; +extern LICENSE WineLicense_Es; +extern LICENSE WineLicense_Fi; +extern LICENSE WineLicense_Fr; +extern LICENSE WineLicense_Hu; +extern LICENSE WineLicense_It; +extern LICENSE WineLicense_Ko; +extern LICENSE WineLicense_No; +extern LICENSE WineLicense_Pl; +extern LICENSE WineLicense_Po; +extern LICENSE WineLicense_Va; diff --git a/programs/winhelp/Makefile.in b/programs/winhelp/Makefile.in index 612a362bd5c..dbe0daf0154 100644 --- a/programs/winhelp/Makefile.in +++ b/programs/winhelp/Makefile.in @@ -5,7 +5,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = none PROGRAMS = winhelp hlp2sgml -ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS) +ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS) RCFLAGS = -w32 -h LANGUAGES = En Da De Fr Fi Ko Hu It Va @@ -25,7 +25,7 @@ RC_SRCS = $(LANGUAGES:%=%.rc) C_SRCS = $(MOSTSRCS) $(STRINGSRCS) -MOSTOBJS = $(MOSTSRCS:.c=.o) +MOSTOBJS = $(MOSTSRCS:.c=.o) $(EXTRA_OBJS) STRINGOBJS = $(STRINGSRCS:.c=.o) $(RC_SRCS:.rc=.o) all: check_winerc $(PROGRAMS) diff --git a/programs/winver/Makefile.in b/programs/winver/Makefile.in index 208ca045eac..a44ca84238e 100644 --- a/programs/winver/Makefile.in +++ b/programs/winver/Makefile.in @@ -5,7 +5,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = none PROGRAMS = winver -ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS) +ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS) RCFLAGS = -w32 -h C_SRCS = winver.c diff --git a/rc/winerc.c b/rc/winerc.c index 058343bd8b3..4a9fa3f81d5 100644 --- a/rc/winerc.c +++ b/rc/winerc.c @@ -97,6 +97,12 @@ int main(int argc,char *argv[]) ret=yyparse(); if (header) fclose(header); fclose(code); + if (ret) /* There was an error */ + { + if (header) unlink( output_name ); + output_name[strlen(output_name)-1] = 'c'; + unlink( output_name ); + } return ret; } diff --git a/relay32/Makefile.in b/relay32/Makefile.in index 74603e60987..39880cef8ff 100644 --- a/relay32/Makefile.in +++ b/relay32/Makefile.in @@ -11,6 +11,8 @@ DLLS = \ comdlg32.spec \ crtdll.spec \ dciman32.spec \ + ddraw.spec \ + dsound.spec \ gdi32.spec \ kernel32.spec \ lz32.spec \ diff --git a/relay32/builtin32.c b/relay32/builtin32.c index 8bdf3eb73b2..764acad4f80 100644 --- a/relay32/builtin32.c +++ b/relay32/builtin32.c @@ -44,6 +44,8 @@ extern const BUILTIN32_DESCRIPTOR COMCTL32_Descriptor; extern const BUILTIN32_DESCRIPTOR COMDLG32_Descriptor; extern const BUILTIN32_DESCRIPTOR CRTDLL_Descriptor; extern const BUILTIN32_DESCRIPTOR DCIMAN32_Descriptor; +extern const BUILTIN32_DESCRIPTOR DDRAW_Descriptor; +extern const BUILTIN32_DESCRIPTOR DSOUND_Descriptor; extern const BUILTIN32_DESCRIPTOR GDI32_Descriptor; extern const BUILTIN32_DESCRIPTOR KERNEL32_Descriptor; extern const BUILTIN32_DESCRIPTOR LZ32_Descriptor; @@ -70,6 +72,8 @@ static BUILTIN32_DLL BuiltinDLLs[] = { &COMDLG32_Descriptor, NULL, TRUE }, { &CRTDLL_Descriptor, NULL, TRUE }, { &DCIMAN32_Descriptor, NULL, TRUE }, + { &DDRAW_Descriptor, NULL, TRUE }, + { &DSOUND_Descriptor, NULL, TRUE }, { &GDI32_Descriptor, NULL, TRUE }, { &KERNEL32_Descriptor, NULL, TRUE }, { &LZ32_Descriptor, NULL, TRUE }, @@ -377,3 +381,43 @@ void BUILTIN32_Unimplemented( const BUILTIN32_DESCRIPTOR *descr, int ordinal ) fprintf( stderr, "\n" ); TASK_KillCurrentTask(1); } + + +/*********************************************************************** + * BUILTIN32_EnableDLL + * + * Enable or disable a built-in DLL. + */ +int BUILTIN32_EnableDLL( const char *name, int len, int enable ) +{ + int i; + BUILTIN32_DLL *dll; + + for (i = 0, dll = BuiltinDLLs; dll->descr; dll++) + { + if (!lstrncmpi32A( name, dll->descr->name, len )) + { + dll->used = enable; + return TRUE; + } + } + return FALSE; +} + + +/*********************************************************************** + * BUILTIN32_PrintDLLs + * + * Print the list of built-in DLLs that can be disabled. + */ +void BUILTIN32_PrintDLLs(void) +{ + int i; + BUILTIN32_DLL *dll; + + fprintf(stderr,"Available Win32 DLLs:\n"); + for (i = 0, dll = BuiltinDLLs; dll->descr; dll++) + fprintf( stderr, "%-9s%c", dll->descr->name, + ((++i) % 8) ? ' ' : '\n' ); + fprintf(stderr,"\n"); +} diff --git a/relay32/crtdll.spec b/relay32/crtdll.spec index a41af77d40b..d1bdd34270b 100644 --- a/relay32/crtdll.spec +++ b/relay32/crtdll.spec @@ -354,7 +354,7 @@ type win32 350 cdecl calloc(long long) CRTDLL_calloc 351 stub ceil 352 stub clearerr -353 cdecl clock() clock +353 cdecl clock() CRTDLL_clock 354 cdecl cos(double) cos 355 cdecl cosh(double) cosh 356 cdecl ctime(ptr) ctime diff --git a/relay32/ddraw.spec b/relay32/ddraw.spec new file mode 100644 index 00000000000..151a1c34a8b --- /dev/null +++ b/relay32/ddraw.spec @@ -0,0 +1,28 @@ +name ddraw +type win32 + + 1 stub DDHAL32_VidMemAlloc + 2 stub DDHAL32_VidMemFree + 3 stub DDInternalLock + 4 stub DDInternalUnlock + 5 stdcall DSoundHelp(long long long) DSoundHelp + 6 stdcall DirectDrawCreate(ptr ptr ptr) DirectDrawCreate + 7 stub DirectDrawCreateClipper + 8 stdcall DirectDrawEnumerateA(ptr ptr) DirectDrawEnumerate32A + 9 stub DirectDrawEnumerateW + 10 stub DllCanUnloadNow + 11 stub DllGetClassObject + 12 stub GetNextMipMap + 13 stub GetSurfaceFromDC + 14 stub HeapVidMemAllocAligned + 15 stub InternalLock + 16 stub InternalUnlock + 17 stub LateAllocateSurfaceMem + 18 stub VidMemAlloc + 19 stub VidMemAmountFree + 20 stub VidMemFini + 21 stub VidMemFree + 22 stub VidMemInit + 23 stub VidMemLargestFree + 24 stub thk1632_ThunkData32 + 25 stub thk3216_ThunkData32 diff --git a/relay32/dsound.spec b/relay32/dsound.spec new file mode 100644 index 00000000000..cfb19a7b158 --- /dev/null +++ b/relay32/dsound.spec @@ -0,0 +1,11 @@ +name dsound +type win32 + +0 stdcall DirectSoundCreate(ptr ptr ptr) DirectSoundCreate +1 stdcall DirectSoundEnumerateA(ptr ptr) DirectSoundEnumerate32A +2 stub DirectSoundEnumerateW +3 stub DllCanUnloadNow +4 stub DllGetClassObject +5 stub DirectSoundCaptureCreate +6 stub DirectSoundCaptureEnumerateA +7 stub DirectSoundCaptureEnumerateW diff --git a/relay32/gdi32.spec b/relay32/gdi32.spec index e068279dac2..fad209fcc34 100644 --- a/relay32/gdi32.spec +++ b/relay32/gdi32.spec @@ -221,7 +221,7 @@ type win32 214 stdcall GetROP2(long) GetROP232 215 stub GetRandomRgn 216 stdcall GetRasterizerCaps(ptr long) GetRasterizerCaps32 -217 stub GetRegionData +217 stdcall GetRegionData(long long ptr) GetRegionData 218 stdcall GetRelAbs(long) GetRelAbs32 219 stdcall GetRgnBox(long ptr) GetRgnBox32 220 stdcall GetStockObject(long) GetStockObject32 diff --git a/relay32/kernel32.spec b/relay32/kernel32.spec index 7dde6b4d870..1d29cf28e7c 100644 --- a/relay32/kernel32.spec +++ b/relay32/kernel32.spec @@ -173,7 +173,7 @@ type win32 182 stub DefineDosDeviceA 183 stub DefineDosDeviceW 184 stdcall DeleteAtom(long) DeleteAtom32 -185 stdcall DeleteCriticalSection(ptr) DeleteCriticalSection +185 stdcall DeleteCriticalSection(ptr) DeleteCriticalSection 186 stdcall DeleteFileA(str) DeleteFile32A 187 stdcall DeleteFileW(wstr) DeleteFile32W 188 stdcall DeviceIoControl(long long ptr long ptr long ptr ptr) DeviceIoControl @@ -183,7 +183,7 @@ type win32 192 stdcall DuplicateHandle(long long long ptr long long long) DuplicateHandle 193 stub EndUpdateResourceA 194 stub EndUpdateResourceW -195 stdcall EnterCriticalSection(ptr) EnterCriticalSection +195 stdcall EnterCriticalSection(ptr) EnterCriticalSection 196 stub EnumCalendarInfoA 197 stub EnumCalendarInfoW 198 stub EnumDateFormatsA @@ -203,7 +203,7 @@ type win32 212 stub EraseTape 213 stdcall EscapeCommFunction(long long) EscapeCommFunction32 214 stdcall ExitProcess(long) ExitProcess -215 stub ExitThread +215 stdcall ExitThread(long) ExitThread 216 stdcall ExpandEnvironmentStringsA(str ptr long) ExpandEnvironmentStrings32A 217 stdcall ExpandEnvironmentStringsW(wstr ptr long) ExpandEnvironmentStrings32W 218 stub FT_Exit0 @@ -383,7 +383,7 @@ type win32 392 stdcall GetShortPathNameW(wstr ptr long) GetShortPathName32W 393 stdcall GetStartupInfoA(ptr) GetStartupInfo32A 394 stdcall GetStartupInfoW(ptr) GetStartupInfo32W -395 stdcall GetStdHandle(long) GetStdHandle +395 stdcall GetStdHandle(long) GetStdHandle 396 stdcall GetStringTypeA(long long str long ptr) GetStringType32A 397 stdcall GetStringTypeExA(long long str long ptr) GetStringTypeEx32A 398 stdcall GetStringTypeExW(long long wstr long ptr) GetStringTypeEx32W @@ -449,7 +449,7 @@ type win32 458 stub Heap32Next 459 stdcall HeapAlloc(long long long) HeapAlloc 460 stdcall HeapCompact(long long) HeapCompact -461 stdcall HeapCreate(long long long) HeapCreate +461 stdcall HeapCreate(long long long) HeapCreate 462 stdcall HeapDestroy(long) HeapDestroy 463 stdcall HeapFree(long long ptr) HeapFree 464 stdcall HeapLock(long) HeapLock @@ -482,7 +482,7 @@ type win32 491 stub K32Thk1632Prolog 492 stdcall LCMapStringA(long long str long ptr long) LCMapString32A 493 stdcall LCMapStringW(long long wstr long ptr long) LCMapString32W -494 stdcall LeaveCriticalSection(ptr) LeaveCriticalSection +494 stdcall LeaveCriticalSection(ptr) LeaveCriticalSection 495 stdcall LoadLibraryA(str) LoadLibrary32A 496 stdcall LoadLibraryExA(str long long) LoadLibraryEx32A 497 stub LoadLibraryExW @@ -531,7 +531,7 @@ type win32 540 stdcall OpenFileMappingW(long long wstr) OpenFileMapping32W 541 stdcall OpenMutexA(long long str) OpenMutex32A 542 stdcall OpenMutexW(long long wstr) OpenMutex32W -543 stdcall OpenProcess(long long long) OpenProcess32 +543 stdcall OpenProcess(long long long) OpenProcess 544 stub OpenProfileUserMapping 545 stdcall OpenSemaphoreA(long long str) OpenSemaphore32A 546 stdcall OpenSemaphoreW(long long wstr) OpenSemaphore32W @@ -545,7 +545,7 @@ type win32 554 stub PrepareTape 555 stub Process32First 556 stub Process32Next -557 stub PulseEvent +557 stdcall PulseEvent(long) PulseEvent 558 stdcall PurgeComm(long long) PurgeComm 559 register QT_Thunk() QT_Thunk 560 stdcall QueryDosDeviceA(str ptr long) QueryDosDevice32A @@ -568,7 +568,7 @@ type win32 577 stdcall ReadFile(long ptr long ptr ptr) ReadFile 578 stdcall ReadFileEx(long ptr long ptr ptr) ReadFileEx 579 stdcall ReadProcessMemory(long ptr ptr long ptr) ReadProcessMemory -580 stub RegisterServiceProcess +580 stdcall RegisterServiceProcess(long long) RegisterServiceProcess 581 stdcall ReinitializeCriticalSection(ptr) ReinitializeCriticalSection 582 stdcall ReleaseMutex(long) ReleaseMutex 583 stdcall ReleaseSemaphore(long long ptr) ReleaseSemaphore @@ -657,7 +657,7 @@ type win32 666 stub SetSystemTimeAdjustment 667 stub SetTapeParameters 668 stub SetTapePosition -669 stdcall SetThreadAffinityMask(long long) SetThreadAffinityMask +669 stdcall SetThreadAffinityMask(long long) SetThreadAffinityMask 670 stub SetThreadContext 671 stub SetThreadLocale 672 stdcall SetThreadPriority(long long) SetThreadPriority @@ -677,7 +677,7 @@ type win32 686 stub Thread32First 687 stub Thread32Next 688 stdcall ThunkConnect32(ptr str str str ptr ptr) ThunkConnect32 -689 stdcall TlsAlloc() TlsAlloc +689 stdcall TlsAlloc() TlsAlloc 690 stub TlsAllocInternal 691 stdcall TlsFree(long) TlsFree 692 stub TlsFreeInternal @@ -710,12 +710,12 @@ type win32 719 stub WaitCommEvent 720 stub WaitForDebugEvent 721 stdcall WaitForMultipleObjects(long ptr long long) WaitForMultipleObjects -722 stub WaitForMultipleObjectsEx +722 stdcall WaitForMultipleObjectsEx(long ptr long long long) WaitForMultipleObjectsEx 723 stdcall WaitForSingleObject(long long) WaitForSingleObject 724 stdcall WaitForSingleObjectEx(long long long) WaitForSingleObjectEx 725 stub WaitNamedPipeA 726 stub WaitNamedPipeW -727 stdcall WideCharToMultiByte(long long wstr long ptr long ptr ptr) WideCharToMultiByte +727 stdcall WideCharToMultiByte(long long wstr long ptr long ptr ptr) WideCharToMultiByte 728 stdcall WinExec(str long) WinExec32 729 stdcall WriteConsoleA(long ptr long ptr ptr) WriteConsole32A 730 stub WriteConsoleInputA @@ -886,7 +886,7 @@ type win32 895 stub SignalObjectAndWait 896 stub SwitchToFiber 897 stub SwitchToThread -898 stub TryEnterCriticalSection +898 stdcall TryEnterCriticalSection(ptr) TryEnterCriticalSection 899 stub VirtualAllocEx 900 stub VirtualFreeEx 901 stub WriteFileGather diff --git a/relay32/ntdll.spec b/relay32/ntdll.spec index 4295ecc87f7..531ef80883f 100644 --- a/relay32/ntdll.spec +++ b/relay32/ntdll.spec @@ -89,7 +89,7 @@ type win32 086 stub NtCreateThread 087 stub NtCreateTimer 088 stub NtCreateToken -089 register NtCurrentTeb() NtCurrentTeb +089 stdcall NtCurrentTeb() NtCurrentTeb 090 stub NtDelayExecution 091 stub NtDeleteFile 092 stub NtDeleteKey @@ -327,7 +327,7 @@ type win32 324 stub RtlDecompressFragment 325 stub RtlDelete 326 stub RtlDeleteAce -327 stub RtlDeleteCriticalSection +327 stdcall RtlDeleteCriticalSection(ptr) DeleteCriticalSection 328 stub RtlDeleteElementGenericTable 329 stub RtlDeleteRegistryValue 330 stub RtlDeleteResource @@ -971,3 +971,4 @@ type win32 966 stub RtlIsValidHandle 967 stub RtlLookupAtomInAtomTable 968 stub RtlQueryAtomInAtomTable +969 stdcall RtlTryEnterCriticalSection(ptr) TryEnterCriticalSection diff --git a/relay32/relay386.c b/relay32/relay386.c index 1531e4a6f1a..752a582543e 100644 --- a/relay32/relay386.c +++ b/relay32/relay386.c @@ -10,6 +10,7 @@ #include "winnt.h" #include "windows.h" #include "builtin32.h" +#include "selectors.h" #include "stddebug.h" #include "debug.h" @@ -30,6 +31,7 @@ int RELAY_CallFrom32( int ret_addr, ... ) char buffer[80]; FARPROC32 func; unsigned int mask, typemask; + WORD fs; int *args = &ret_addr; /* Relay addr is the return address for this function */ @@ -56,7 +58,8 @@ int RELAY_CallFrom32( int ret_addr, ... ) } else printf( "%08x", args[i] ); } - printf( ") ret=%08x\n", ret_addr ); + GET_FS( fs ); + printf( ") ret=%08x fs=%04x\n", ret_addr, fs ); if (*relay_addr == 0xc3) /* cdecl */ { LRESULT (*cfunc)() = (LRESULT(*)())func; @@ -138,7 +141,8 @@ int RELAY_CallFrom32( int ret_addr, ... ) assert(FALSE); } } - printf( "Ret %s() retval=%08x ret=%08x\n", buffer, ret, ret_addr ); + printf( "Ret %s() retval=%08x ret=%08x fs=%04x\n", + buffer, ret, ret_addr, fs ); return ret; } diff --git a/relay32/user32.spec b/relay32/user32.spec index 5c099ba42e6..06ce2b16254 100644 --- a/relay32/user32.spec +++ b/relay32/user32.spec @@ -462,7 +462,7 @@ type win32 457 stdcall SendMessageTimeoutA(long long long long ptr ptr) SendMessageTimeout32A 458 stdcall SendMessageTimeoutW(long long long long ptr ptr) SendMessageTimeout32W 459 stdcall SendMessageW(long long long long) SendMessage32W -460 stub SendNotifyMessageA +460 stdcall SendNotifyMessageA(long long long long) SendNotifyMessage32A 461 stub SendNotifyMessageW 462 stub ServerSetFunctionPointers 463 stdcall SetActiveWindow(long) SetActiveWindow32 diff --git a/relay32/winmm.spec b/relay32/winmm.spec index de1a4e5e71f..a421088cbac 100644 --- a/relay32/winmm.spec +++ b/relay32/winmm.spec @@ -31,7 +31,7 @@ type win32 28 stdcall joyGetDevCapsW(long ptr long) joyGetDevCaps32W 29 stdcall joyGetNumDevs() joyGetNumDevs32 30 stdcall joyGetPos(long ptr) joyGetPos32 - 31 stub joyGetPosEx + 31 stdcall joyGetPosEx(long ptr) joyGetPosEx 32 stdcall joyGetThreshold(long ptr) joyGetThreshold32 33 stub joyReleaseCapture 34 stub joySetCapture diff --git a/relay32/wow32.spec b/relay32/wow32.spec index 2f5b5481e93..4a37728335c 100644 --- a/relay32/wow32.spec +++ b/relay32/wow32.spec @@ -1,7 +1,7 @@ name wow32 type win32 -# 1 + 1 stub WOW_1 2 stub WOWCallback16 3 stub WOWCallback16Ex 4 stub WOWDirectedYield16 diff --git a/scheduler/Makefile.in b/scheduler/Makefile.in index 75ff0803bab..632f0467f53 100644 --- a/scheduler/Makefile.in +++ b/scheduler/Makefile.in @@ -6,7 +6,13 @@ VPATH = @srcdir@ MODULE = scheduler C_SRCS = \ + critsection.c \ + event.c \ + k32obj.c \ + mutex.c \ process.c \ + semaphore.c \ + synchro.c \ thread.c all: $(MODULE).o diff --git a/scheduler/critsection.c b/scheduler/critsection.c new file mode 100644 index 00000000000..7f5c5b95cb8 --- /dev/null +++ b/scheduler/critsection.c @@ -0,0 +1,286 @@ +/* + * Win32 critical sections + * + * Copyright 1998 Alexandre Julliard + */ + +/* Note: critical sections are not implemented exactly the same way + * than under NT (LockSemaphore should be a real semaphore handle). + * But since they are even more different under Win95, it probably + * doesn't matter... + */ + +#include +#include +#include +#include +#include "windows.h" +#include "winerror.h" +#include "winbase.h" +#include "heap.h" +#include "k32obj.h" +#include "thread.h" + +typedef struct +{ + K32OBJ header; + THREAD_QUEUE wait_queue; + BOOL32 signaled; +} CRIT_SECTION; + + +static BOOL32 CRIT_SECTION_Signaled( K32OBJ *obj, DWORD thread_id ); +static void CRIT_SECTION_Satisfied( K32OBJ *obj, DWORD thread_id ); +static void CRIT_SECTION_AddWait( K32OBJ *obj, DWORD thread_id ); +static void CRIT_SECTION_RemoveWait( K32OBJ *obj, DWORD thread_id ); +static void CRIT_SECTION_Destroy( K32OBJ *obj ); + +const K32OBJ_OPS CRITICAL_SECTION_Ops = +{ + CRIT_SECTION_Signaled, /* signaled */ + CRIT_SECTION_Satisfied, /* satisfied */ + CRIT_SECTION_AddWait, /* add_wait */ + CRIT_SECTION_RemoveWait, /* remove_wait */ + CRIT_SECTION_Destroy /* destroy */ +}; + +/*********************************************************************** + * InitializeCriticalSection (KERNEL32.472) (NTDLL.406) + */ +void WINAPI InitializeCriticalSection( CRITICAL_SECTION *crit ) +{ + CRIT_SECTION *obj; + + crit->LockCount = -1; + crit->RecursionCount = 0; + crit->OwningThread = 0; + crit->LockSemaphore = 0; + if (SystemHeap) + { + if (!(obj = (CRIT_SECTION *)HeapAlloc( SystemHeap, 0, sizeof(*obj) ))) + return; /* No way to return an error... */ + obj->header.type = K32OBJ_CRITICAL_SECTION; + obj->header.refcount = 1; + obj->wait_queue = NULL; + obj->signaled = FALSE; + crit->LockSemaphore = (HANDLE32)obj; + crit->Reserved = (DWORD)-1; + } + else + { + union semun val; + crit->Reserved = (DWORD)semget( IPC_PRIVATE, 1, IPC_CREAT | 0777 ); + if (crit->Reserved == (DWORD)-1) + { + perror( "semget" ); + return; + } + val.val = 0; + semctl( (int)crit->Reserved, 0, SETVAL, val ); + } +} + + +/*********************************************************************** + * DeleteCriticalSection (KERNEL32.185) (NTDLL.327) + */ +void WINAPI DeleteCriticalSection( CRITICAL_SECTION *crit ) +{ + CRIT_SECTION *obj = (CRIT_SECTION *)crit->LockSemaphore; + + if (obj) + { + if (crit->RecursionCount) /* Should not happen */ + fprintf( stderr, "Deleting owned critical section (%p)\n", crit ); + crit->LockCount = -1; + crit->RecursionCount = 0; + crit->OwningThread = 0; + crit->LockSemaphore = 0; + K32OBJ_DecCount( &obj->header ); + } + else if (crit->Reserved != (DWORD)-1) + { + semctl( (int)crit->Reserved, 0, IPC_RMID, (union semun)0 ); + } +} + + +/*********************************************************************** + * EnterCriticalSection (KERNEL32.195) (NTDLL.344) + */ +void WINAPI EnterCriticalSection( CRITICAL_SECTION *crit ) +{ + if (InterlockedIncrement( &crit->LockCount )) + { + if (crit->OwningThread == GetCurrentThreadId()) + { + crit->RecursionCount++; + return; + } + /* Now wait for it */ + if (crit->LockSemaphore) + { + WAIT_STRUCT *wait = &THREAD_Current()->wait_struct; + SYSTEM_LOCK(); + wait->count = 1; + wait->signaled = WAIT_FAILED; + wait->wait_all = FALSE; + wait->objs[0] = (K32OBJ *)crit->LockSemaphore; + K32OBJ_IncCount( wait->objs[0] ); + SYNC_WaitForCondition( wait, INFINITE32 ); + K32OBJ_DecCount( wait->objs[0] ); + SYSTEM_UNLOCK(); + } + else if (crit->Reserved != (DWORD)-1) + { + int ret; + struct sembuf sop; + sop.sem_num = 0; + sop.sem_op = -1; + sop.sem_flg = SEM_UNDO; + do + { + ret = semop( (int)crit->Reserved, &sop, 1 ); + } while ((ret == -1) && (errno == EINTR)); + } + else + { + fprintf( stderr, "Uninitialized critical section (%p)\n", crit ); + return; + } + } + crit->OwningThread = GetCurrentThreadId(); + crit->RecursionCount = 1; +} + + +/*********************************************************************** + * TryEnterCriticalSection (KERNEL32.898) (NTDLL.969) + */ +BOOL32 WINAPI TryEnterCriticalSection( CRITICAL_SECTION *crit ) +{ + if (InterlockedIncrement( &crit->LockCount )) + { + if (crit->OwningThread == GetCurrentThreadId()) + { + crit->RecursionCount++; + return TRUE; + } + /* FIXME: this doesn't work */ + InterlockedDecrement( &crit->LockCount ); + return FALSE; + } + crit->OwningThread = GetCurrentThreadId(); + crit->RecursionCount = 1; + return TRUE; +} + + +/*********************************************************************** + * LeaveCriticalSection (KERNEL32.494) (NTDLL.426) + */ +void WINAPI LeaveCriticalSection( CRITICAL_SECTION *crit ) +{ + if (crit->OwningThread != GetCurrentThreadId()) return; + + if (--crit->RecursionCount) + { + InterlockedDecrement( &crit->LockCount ); + return; + } + crit->OwningThread = 0; + if (InterlockedDecrement( &crit->LockCount ) >= 0) + { + /* Someone is waiting */ + if (crit->LockSemaphore) + { + CRIT_SECTION *obj = (CRIT_SECTION *)crit->LockSemaphore; + SYSTEM_LOCK(); + obj->signaled = TRUE; + SYNC_WakeUp( &obj->wait_queue, 1 ); + SYSTEM_UNLOCK(); + } + else if (crit->Reserved != (DWORD)-1) + { + struct sembuf sop; + sop.sem_num = 0; + sop.sem_op = 1; + sop.sem_flg = SEM_UNDO; + semop( (int)crit->Reserved, &sop, 1 ); + } + } +} + + +/*********************************************************************** + * MakeCriticalSectionGlobal (KERNEL32.515) + */ +void WINAPI MakeCriticalSectionGlobal( CRITICAL_SECTION *crit ) +{ + /* Nothing to do: a critical section is always global */ +} + + +/*********************************************************************** + * CRIT_SECTION_Signaled + */ +static BOOL32 CRIT_SECTION_Signaled( K32OBJ *obj, DWORD thread_id ) +{ + CRIT_SECTION *crit = (CRIT_SECTION *)obj; + assert( obj->type == K32OBJ_CRITICAL_SECTION ); + return crit->signaled; +} + + +/*********************************************************************** + * CRIT_SECTION_Satisfied + * + * Wait on this object has been satisfied. + */ +static void CRIT_SECTION_Satisfied( K32OBJ *obj, DWORD thread_id ) +{ + CRIT_SECTION *crit = (CRIT_SECTION *)obj; + assert( obj->type == K32OBJ_CRITICAL_SECTION ); + /* Only one thread is allowed to wake up */ + crit->signaled = FALSE; +} + + +/*********************************************************************** + * CRIT_SECTION_AddWait + * + * Add thread to object wait queue. + */ +static void CRIT_SECTION_AddWait( K32OBJ *obj, DWORD thread_id ) +{ + CRIT_SECTION *crit = (CRIT_SECTION *)obj; + assert( obj->type == K32OBJ_CRITICAL_SECTION ); + THREAD_AddQueue( &crit->wait_queue, THREAD_ID_TO_THDB(thread_id) ); +} + + +/*********************************************************************** + * CRIT_SECTION_RemoveWait + * + * Remove current thread from object wait queue. + */ +static void CRIT_SECTION_RemoveWait( K32OBJ *obj, DWORD thread_id ) +{ + CRIT_SECTION *crit = (CRIT_SECTION *)obj; + assert( obj->type == K32OBJ_CRITICAL_SECTION ); + THREAD_RemoveQueue( &crit->wait_queue, THREAD_ID_TO_THDB(thread_id) ); +} + + +/*********************************************************************** + * CRIT_SECTION_Destroy + */ +static void CRIT_SECTION_Destroy( K32OBJ *obj ) +{ + CRIT_SECTION *crit = (CRIT_SECTION *)obj; + assert( obj->type == K32OBJ_CRITICAL_SECTION ); + /* There cannot be any thread on the list since the ref count is 0 */ + assert( crit->wait_queue == NULL ); + obj->type = K32OBJ_UNKNOWN; + HeapFree( SystemHeap, 0, crit ); +} diff --git a/scheduler/event.c b/scheduler/event.c new file mode 100644 index 00000000000..4eb5e0c4dc5 --- /dev/null +++ b/scheduler/event.c @@ -0,0 +1,268 @@ +/* + * Win32 events + * + * Copyright 1998 Alexandre Julliard + */ + +#include +#include "windows.h" +#include "winerror.h" +#include "k32obj.h" +#include "process.h" +#include "thread.h" +#include "heap.h" + +typedef struct +{ + K32OBJ header; + THREAD_QUEUE wait_queue; + BOOL32 manual_reset; + BOOL32 signaled; +} EVENT; + +static BOOL32 EVENT_Signaled( K32OBJ *obj, DWORD thread_id ); +static void EVENT_Satisfied( K32OBJ *obj, DWORD thread_id ); +static void EVENT_AddWait( K32OBJ *obj, DWORD thread_id ); +static void EVENT_RemoveWait( K32OBJ *obj, DWORD thread_id ); +static void EVENT_Destroy( K32OBJ *obj ); + +const K32OBJ_OPS EVENT_Ops = +{ + EVENT_Signaled, /* signaled */ + EVENT_Satisfied, /* satisfied */ + EVENT_AddWait, /* add_wait */ + EVENT_RemoveWait, /* remove_wait */ + EVENT_Destroy /* destroy */ +}; + + +/*********************************************************************** + * EVENT_Set + * + * Implementation of SetEvent. Used by ExitThread and ExitProcess. + */ +void EVENT_Set( K32OBJ *obj ) +{ + EVENT *event = (EVENT *)obj; + assert( obj->type == K32OBJ_EVENT ); + SYSTEM_LOCK(); + event->signaled = TRUE; + SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 ); + SYSTEM_UNLOCK(); +} + +/*********************************************************************** + * EVENT_Create + * + * Partial implementation of CreateEvent. + * Used internally by processes and threads. + */ +K32OBJ *EVENT_Create( BOOL32 manual_reset, BOOL32 initial_state ) +{ + EVENT *event; + + SYSTEM_LOCK(); + if ((event = HeapAlloc( SystemHeap, 0, sizeof(*event) ))) + { + event->header.type = K32OBJ_EVENT; + event->header.refcount = 1; + event->wait_queue = NULL; + event->manual_reset = manual_reset; + event->signaled = initial_state; + } + SYSTEM_UNLOCK(); + return event ? &event->header : NULL; +} + + +/*********************************************************************** + * CreateEvent32A (KERNEL32.156) + */ +HANDLE32 WINAPI CreateEvent32A( SECURITY_ATTRIBUTES *sa, BOOL32 manual_reset, + BOOL32 initial_state, LPCSTR name ) +{ + HANDLE32 handle; + EVENT *event; + + SYSTEM_LOCK(); + event = (EVENT *)K32OBJ_Create( K32OBJ_EVENT, sizeof(*event), + name, &handle ); + if (event) + { + /* Finish initializing it */ + event->wait_queue = NULL; + event->manual_reset = manual_reset; + event->signaled = initial_state; + K32OBJ_DecCount( &event->header ); + } + SYSTEM_UNLOCK(); + return handle; +} + + +/*********************************************************************** + * CreateEvent32W (KERNEL32.157) + */ +HANDLE32 WINAPI CreateEvent32W( SECURITY_ATTRIBUTES *sa, BOOL32 manual_reset, + BOOL32 initial_state, LPCWSTR name ) +{ + LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name ); + HANDLE32 ret = CreateEvent32A( sa, manual_reset, initial_state, nameA ); + if (nameA) HeapFree( GetProcessHeap(), 0, nameA ); + return ret; +} + + +/*********************************************************************** + * OpenEvent32A (KERNEL32.536) + */ +HANDLE32 WINAPI OpenEvent32A( DWORD access, BOOL32 inherit, LPCSTR name ) +{ + HANDLE32 handle = 0; + K32OBJ *obj; + SYSTEM_LOCK(); + if ((obj = K32OBJ_FindNameType( name, K32OBJ_EVENT )) != NULL) + { + handle = PROCESS_AllocHandle( obj, 0 ); + K32OBJ_DecCount( obj ); + } + SYSTEM_UNLOCK(); + return handle; +} + + +/*********************************************************************** + * OpenEvent32W (KERNEL32.537) + */ +HANDLE32 WINAPI OpenEvent32W( DWORD access, BOOL32 inherit, LPCWSTR name ) +{ + LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name ); + HANDLE32 ret = OpenEvent32A( access, inherit, nameA ); + if (nameA) HeapFree( GetProcessHeap(), 0, nameA ); + return ret; +} + + +/*********************************************************************** + * PulseEvent (KERNEL32.557) + */ +BOOL32 WINAPI PulseEvent( HANDLE32 handle ) +{ + EVENT *event; + SYSTEM_LOCK(); + if (!(event = (EVENT *)PROCESS_GetObjPtr( handle, K32OBJ_EVENT ))) + { + SYSTEM_UNLOCK(); + return FALSE; + } + event->signaled = TRUE; + SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 ); + event->signaled = FALSE; + K32OBJ_DecCount( &event->header ); + SYSTEM_UNLOCK(); + return TRUE; +} + + +/*********************************************************************** + * SetEvent (KERNEL32.644) + */ +BOOL32 WINAPI SetEvent( HANDLE32 handle ) +{ + EVENT *event; + SYSTEM_LOCK(); + if (!(event = (EVENT *)PROCESS_GetObjPtr( handle, K32OBJ_EVENT ))) + { + SYSTEM_UNLOCK(); + return FALSE; + } + event->signaled = TRUE; + SYNC_WakeUp( &event->wait_queue, event->manual_reset ? INFINITE32 : 1 ); + K32OBJ_DecCount( &event->header ); + SYSTEM_UNLOCK(); + return TRUE; +} + + +/*********************************************************************** + * ResetEvent (KERNEL32.586) + */ +BOOL32 WINAPI ResetEvent( HANDLE32 handle ) +{ + EVENT *event; + SYSTEM_LOCK(); + if (!(event = (EVENT *)PROCESS_GetObjPtr( handle, K32OBJ_EVENT ))) + { + SYSTEM_UNLOCK(); + return FALSE; + } + event->signaled = FALSE; + K32OBJ_DecCount( &event->header ); + SYSTEM_UNLOCK(); + return TRUE; +} + + +/*********************************************************************** + * EVENT_Signaled + */ +static BOOL32 EVENT_Signaled( K32OBJ *obj, DWORD thread_id ) +{ + EVENT *event = (EVENT *)obj; + assert( obj->type == K32OBJ_EVENT ); + return event->signaled; +} + + +/*********************************************************************** + * EVENT_Satisfied + * + * Wait on this object has been satisfied. + */ +static void EVENT_Satisfied( K32OBJ *obj, DWORD thread_id ) +{ + EVENT *event = (EVENT *)obj; + assert( obj->type == K32OBJ_EVENT ); + /* Reset if it's an auto-reset event */ + if (!event->manual_reset) event->signaled = FALSE; +} + + +/*********************************************************************** + * EVENT_AddWait + * + * Add thread to object wait queue. + */ +static void EVENT_AddWait( K32OBJ *obj, DWORD thread_id ) +{ + EVENT *event = (EVENT *)obj; + assert( obj->type == K32OBJ_EVENT ); + THREAD_AddQueue( &event->wait_queue, THREAD_ID_TO_THDB(thread_id) ); +} + + +/*********************************************************************** + * EVENT_RemoveWait + * + * Remove thread from object wait queue. + */ +static void EVENT_RemoveWait( K32OBJ *obj, DWORD thread_id ) +{ + EVENT *event = (EVENT *)obj; + assert( obj->type == K32OBJ_EVENT ); + THREAD_RemoveQueue( &event->wait_queue, THREAD_ID_TO_THDB(thread_id) ); +} + + +/*********************************************************************** + * EVENT_Destroy + */ +static void EVENT_Destroy( K32OBJ *obj ) +{ + EVENT *event = (EVENT *)obj; + assert( obj->type == K32OBJ_EVENT ); + /* There cannot be any thread on the list since the ref count is 0 */ + assert( event->wait_queue == NULL ); + obj->type = K32OBJ_UNKNOWN; + HeapFree( SystemHeap, 0, event ); +} diff --git a/scheduler/k32obj.c b/scheduler/k32obj.c new file mode 100644 index 00000000000..c2589ced955 --- /dev/null +++ b/scheduler/k32obj.c @@ -0,0 +1,260 @@ +/* + * KERNEL32 objects + * + * Copyright 1996 Alexandre Julliard + */ + +#include +#include "winerror.h" +#include "k32obj.h" +#include "heap.h" +#include "process.h" + + +/* The declarations are here to avoid including a lot of unnecessary files */ +extern const K32OBJ_OPS SEMAPHORE_Ops; +extern const K32OBJ_OPS EVENT_Ops; +extern const K32OBJ_OPS MUTEX_Ops; +extern const K32OBJ_OPS CRITICAL_SECTION_Ops; +extern const K32OBJ_OPS PROCESS_Ops; +extern const K32OBJ_OPS THREAD_Ops; +extern const K32OBJ_OPS FILE_Ops; +extern const K32OBJ_OPS MEM_MAPPED_FILE_Ops; + +static const K32OBJ_OPS K32OBJ_NullOps = +{ + NULL, /* signaled */ + NULL, /* satisfied */ + NULL, /* add_wait */ + NULL, /* remove_wait */ + NULL /* destroy */ +}; + +const K32OBJ_OPS * const K32OBJ_Ops[K32OBJ_NBOBJECTS] = +{ + NULL, + &SEMAPHORE_Ops, /* K32OBJ_SEMAPHORE */ + &EVENT_Ops, /* K32OBJ_EVENT */ + &MUTEX_Ops, /* K32OBJ_MUTEX */ + &CRITICAL_SECTION_Ops, /* K32OBJ_CRITICAL_SECTION */ + &PROCESS_Ops, /* K32OBJ_PROCESS */ + &THREAD_Ops, /* K32OBJ_THREAD */ + &FILE_Ops, /* K32OBJ_FILE */ + &K32OBJ_NullOps, /* K32OBJ_CHANGE */ + &K32OBJ_NullOps, /* K32OBJ_CONSOLE */ + &K32OBJ_NullOps, /* K32OBJ_SCREEN_BUFFER */ + &MEM_MAPPED_FILE_Ops, /* K32OBJ_MEM_MAPPED_FILE */ + &K32OBJ_NullOps, /* K32OBJ_SERIAL */ + &K32OBJ_NullOps, /* K32OBJ_DEVICE_IOCTL */ + &K32OBJ_NullOps, /* K32OBJ_PIPE */ + &K32OBJ_NullOps, /* K32OBJ_MAILSLOT */ + &K32OBJ_NullOps, /* K32OBJ_TOOLHELP_SNAPSHOT */ + &K32OBJ_NullOps /* K32OBJ_SOCKET */ +}; + +typedef struct _NE +{ + struct _NE *next; + K32OBJ *obj; + UINT32 len; + char name[1]; +} NAME_ENTRY; + +static NAME_ENTRY *K32OBJ_FirstEntry = NULL; + + +/*********************************************************************** + * K32OBJ_IncCount + */ +void K32OBJ_IncCount( K32OBJ *ptr ) +{ + assert( ptr->type && ((unsigned)ptr->type < K32OBJ_NBOBJECTS) ); + SYSTEM_LOCK(); + ptr->refcount++; + SYSTEM_UNLOCK(); + assert( ptr->refcount > 0 ); /* No wrap-around allowed */ +} + + +/*********************************************************************** + * K32OBJ_DecCount + */ +void K32OBJ_DecCount( K32OBJ *ptr ) +{ + NAME_ENTRY **pptr; + + assert( ptr->type && ((unsigned)ptr->type < K32OBJ_NBOBJECTS) ); + assert( ptr->refcount > 0 ); + SYSTEM_LOCK(); + if (--ptr->refcount) + { + SYSTEM_UNLOCK(); + return; + } + + /* Check if the object has a name entry and free it */ + + pptr = &K32OBJ_FirstEntry; + while (*pptr && ((*pptr)->obj != ptr)) pptr = &(*pptr)->next; + if (*pptr) + { + NAME_ENTRY *entry = *pptr; + *pptr = entry->next; + HeapFree( SystemHeap, 0, entry ); + } + + /* Free the object */ + + if (K32OBJ_Ops[ptr->type]->destroy) K32OBJ_Ops[ptr->type]->destroy( ptr ); + SYSTEM_UNLOCK(); +} + + +/*********************************************************************** + * K32OBJ_IsValid + * + * Check if a pointer is a valid kernel object + */ +BOOL32 K32OBJ_IsValid( K32OBJ *ptr, K32OBJ_TYPE type ) +{ + if (IsBadReadPtr32( ptr, sizeof(*ptr) )) return FALSE; + return (ptr->type == type); +} + + +/*********************************************************************** + * K32OBJ_AddName + * + * Add a name entry for an object. We don't check for duplicates here. + * FIXME: should use some sort of hashing. + */ +BOOL32 K32OBJ_AddName( K32OBJ *obj, LPCSTR name ) +{ + NAME_ENTRY *entry; + UINT32 len; + + if (!name) return TRUE; /* Anonymous object */ + len = strlen( name ); + SYSTEM_LOCK(); + if (!(entry = HeapAlloc( SystemHeap, 0, sizeof(NAME_ENTRY) + len ))) + { + SYSTEM_UNLOCK(); + SetLastError( ERROR_OUTOFMEMORY ); + return FALSE; + } + entry->next = K32OBJ_FirstEntry; + entry->obj = obj; + lstrcpy32A( entry->name, name ); + K32OBJ_FirstEntry = entry; + SYSTEM_UNLOCK(); + return TRUE; +} + + +/*********************************************************************** + * K32OBJ_Create + * + * Create a named kernel object. + * Returns NULL if there was an error _or_ if the object already existed. + * The refcount of the object must be decremented once it is initialized. + */ +K32OBJ *K32OBJ_Create( K32OBJ_TYPE type, DWORD size, LPCSTR name, + HANDLE32 *handle ) +{ + /* Check if the name already exists */ + + K32OBJ *obj = K32OBJ_FindName( name ); + if (obj) + { + if (obj->type == type) + { + SetLastError( ERROR_ALREADY_EXISTS ); + *handle = PROCESS_AllocHandle( obj, 0 ); + } + else + { + SetLastError( ERROR_DUP_NAME ); + *handle = INVALID_HANDLE_VALUE32; + } + K32OBJ_DecCount( obj ); + return NULL; + } + + /* Create the object */ + + SYSTEM_LOCK(); + if (!(obj = HeapAlloc( SystemHeap, 0, size ))) + { + SYSTEM_UNLOCK(); + *handle = INVALID_HANDLE_VALUE32; + return NULL; + } + obj->type = type; + obj->refcount = 1; + + /* Add a name for it */ + + if (!K32OBJ_AddName( obj, name )) + { + /* Don't call the destroy function, as the object wasn't + * initialized properly */ + HeapFree( SystemHeap, 0, obj ); + SYSTEM_UNLOCK(); + *handle = INVALID_HANDLE_VALUE32; + return NULL; + } + + /* Allocate a handle */ + + *handle = PROCESS_AllocHandle( obj, 0 ); + SYSTEM_UNLOCK(); + return obj; +} + + +/*********************************************************************** + * K32OBJ_FindName + * + * Find the object referenced by a given name. + * The reference count is incremented. + */ +K32OBJ *K32OBJ_FindName( LPCSTR name ) +{ + NAME_ENTRY *entry; + UINT32 len; + + if (!name) return NULL; /* Anonymous object */ + len = strlen( name ); + SYSTEM_LOCK(); + entry = K32OBJ_FirstEntry; + while (entry) + { + if ((len == entry->len) && !lstrcmp32A( name, entry->name)) + { + K32OBJ *obj = entry->obj; + K32OBJ_IncCount( obj ); + SYSTEM_UNLOCK(); + return entry->obj; + } + entry = entry->next; + } + SYSTEM_UNLOCK(); + return NULL; +} + + +/*********************************************************************** + * K32OBJ_FindNameType + * + * Find an object by name and check its type. + * The reference count is incremented. + */ +K32OBJ *K32OBJ_FindNameType( LPCSTR name, K32OBJ_TYPE type ) +{ + K32OBJ *obj = K32OBJ_FindName( name ); + if (!obj) return NULL; + if (obj->type == type) return obj; + SetLastError( ERROR_DUP_NAME ); + K32OBJ_DecCount( obj ); + return NULL; +} diff --git a/scheduler/mutex.c b/scheduler/mutex.c new file mode 100644 index 00000000000..737789a3caa --- /dev/null +++ b/scheduler/mutex.c @@ -0,0 +1,207 @@ +/* + * Win32 mutexes + * + * Copyright 1998 Alexandre Julliard + */ + +#include +#include "windows.h" +#include "winerror.h" +#include "k32obj.h" +#include "process.h" +#include "thread.h" +#include "heap.h" + +typedef struct +{ + K32OBJ header; + THREAD_QUEUE wait_queue; + DWORD owner; + DWORD count; +} MUTEX; + +static BOOL32 MUTEX_Signaled( K32OBJ *obj, DWORD thread_id ); +static void MUTEX_Satisfied( K32OBJ *obj, DWORD thread_id ); +static void MUTEX_AddWait( K32OBJ *obj, DWORD thread_id ); +static void MUTEX_RemoveWait( K32OBJ *obj, DWORD thread_id ); +static void MUTEX_Destroy( K32OBJ *obj ); + +const K32OBJ_OPS MUTEX_Ops = +{ + MUTEX_Signaled, /* signaled */ + MUTEX_Satisfied, /* satisfied */ + MUTEX_AddWait, /* add_wait */ + MUTEX_RemoveWait, /* remove_wait */ + MUTEX_Destroy /* destroy */ +}; + + +/*********************************************************************** + * CreateMutex32A (KERNEL32.166) + */ +HANDLE32 WINAPI CreateMutex32A( SECURITY_ATTRIBUTES *sa, BOOL32 owner, + LPCSTR name ) +{ + HANDLE32 handle; + MUTEX *mutex; + + SYSTEM_LOCK(); + mutex = (MUTEX *)K32OBJ_Create( K32OBJ_MUTEX, sizeof(*mutex), + name, &handle ); + if (mutex) + { + /* Finish initializing it */ + mutex->wait_queue = NULL; + if (owner) + { + mutex->owner = GetCurrentThreadId(); + mutex->count = 1; + } + else + { + mutex->owner = 0; + mutex->count = 0; + } + K32OBJ_DecCount( &mutex->header ); + } + SYSTEM_UNLOCK(); + return handle; +} + + +/*********************************************************************** + * CreateMutex32W (KERNEL32.167) + */ +HANDLE32 WINAPI CreateMutex32W( SECURITY_ATTRIBUTES *sa, BOOL32 owner, + LPCWSTR name ) +{ + LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name ); + HANDLE32 ret = CreateMutex32A( sa, owner, nameA ); + if (nameA) HeapFree( GetProcessHeap(), 0, nameA ); + return ret; +} + + +/*********************************************************************** + * OpenMutex32A (KERNEL32.541) + */ +HANDLE32 WINAPI OpenMutex32A( DWORD access, BOOL32 inherit, LPCSTR name ) +{ + HANDLE32 handle = 0; + K32OBJ *obj; + SYSTEM_LOCK(); + if ((obj = K32OBJ_FindNameType( name, K32OBJ_MUTEX )) != NULL) + { + handle = PROCESS_AllocHandle( obj, 0 ); + K32OBJ_DecCount( obj ); + } + SYSTEM_UNLOCK(); + return handle; +} + + +/*********************************************************************** + * OpenMutex32W (KERNEL32.542) + */ +HANDLE32 WINAPI OpenMutex32W( DWORD access, BOOL32 inherit, LPCWSTR name ) +{ + LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name ); + HANDLE32 ret = OpenMutex32A( access, inherit, nameA ); + if (nameA) HeapFree( GetProcessHeap(), 0, nameA ); + return ret; +} + + +/*********************************************************************** + * ReleaseMutex (KERNEL32.582) + */ +BOOL32 WINAPI ReleaseMutex( HANDLE32 handle ) +{ + MUTEX *mutex; + SYSTEM_LOCK(); + if (!(mutex = (MUTEX *)PROCESS_GetObjPtr( handle, K32OBJ_MUTEX ))) + { + SYSTEM_UNLOCK(); + return FALSE; + } + if (!mutex->count || (mutex->owner != GetCurrentThreadId())) + { + SYSTEM_UNLOCK(); + SetLastError( ERROR_NOT_OWNER ); + return FALSE; + } + if (!--mutex->count) + { + mutex->owner = 0; + SYNC_WakeUp( &mutex->wait_queue, INFINITE32 ); + } + K32OBJ_DecCount( &mutex->header ); + SYSTEM_UNLOCK(); + return TRUE; +} + + +/*********************************************************************** + * MUTEX_Signaled + */ +static BOOL32 MUTEX_Signaled( K32OBJ *obj, DWORD thread_id ) +{ + MUTEX *mutex = (MUTEX *)obj; + assert( obj->type == K32OBJ_MUTEX ); + return (!mutex->count || (mutex->owner == thread_id)); +} + + +/*********************************************************************** + * MUTEX_Satisfied + * + * Wait on this object has been satisfied. + */ +static void MUTEX_Satisfied( K32OBJ *obj, DWORD thread_id ) +{ + MUTEX *mutex = (MUTEX *)obj; + assert( obj->type == K32OBJ_MUTEX ); + assert( !mutex->count || (mutex->owner == thread_id) ); + mutex->owner = thread_id; + mutex->count++; +} + + +/*********************************************************************** + * MUTEX_AddWait + * + * Add a thread to the object wait queue. + */ +static void MUTEX_AddWait( K32OBJ *obj, DWORD thread_id ) +{ + MUTEX *mutex = (MUTEX *)obj; + assert( obj->type == K32OBJ_MUTEX ); + THREAD_AddQueue( &mutex->wait_queue, THREAD_ID_TO_THDB(thread_id) ); +} + + +/*********************************************************************** + * MUTEX_RemoveWait + * + * Remove a thread from the object wait queue. + */ +static void MUTEX_RemoveWait( K32OBJ *obj, DWORD thread_id ) +{ + MUTEX *mutex = (MUTEX *)obj; + assert( obj->type == K32OBJ_MUTEX ); + THREAD_RemoveQueue( &mutex->wait_queue, THREAD_ID_TO_THDB(thread_id) ); +} + + +/*********************************************************************** + * MUTEX_Destroy + */ +static void MUTEX_Destroy( K32OBJ *obj ) +{ + MUTEX *mutex = (MUTEX *)obj; + assert( obj->type == K32OBJ_MUTEX ); + /* There cannot be any thread on the list since the ref count is 0 */ + assert( mutex->wait_queue == NULL ); + obj->type = K32OBJ_UNKNOWN; + HeapFree( SystemHeap, 0, mutex ); +} diff --git a/scheduler/process.c b/scheduler/process.c index b819080820d..225dd143457 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -25,6 +25,21 @@ PDB32 *pCurrentProcess = NULL; #define BOOT_HTABLE_SIZE 10 +static BOOL32 PROCESS_Signaled( K32OBJ *obj, DWORD thread_id ); +static void PROCESS_Satisfied( K32OBJ *obj, DWORD thread_id ); +static void PROCESS_AddWait( K32OBJ *obj, DWORD thread_id ); +static void PROCESS_RemoveWait( K32OBJ *obj, DWORD thread_id ); +static void PROCESS_Destroy( K32OBJ *obj ); + +const K32OBJ_OPS PROCESS_Ops = +{ + PROCESS_Signaled, /* signaled */ + PROCESS_Satisfied, /* satisfied */ + PROCESS_AddWait, /* add_wait */ + PROCESS_RemoveWait, /* remove_wait */ + PROCESS_Destroy /* destroy */ +}; + static HANDLE_ENTRY boot_handles[BOOT_HTABLE_SIZE]; /*********************************************************************** @@ -46,14 +61,20 @@ static HANDLE_TABLE *PROCESS_AllocHandleTable( PDB32 *process ) */ static BOOL32 PROCESS_GrowHandleTable( PDB32 *process ) { - HANDLE_TABLE *table = process->handle_table; - table = HeapReAlloc( process->system_heap, HEAP_ZERO_MEMORY, table, + HANDLE_TABLE *table; + SYSTEM_LOCK(); + table = process->handle_table; + table = HeapReAlloc( process->system_heap, + HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE, table, sizeof(HANDLE_TABLE) + (table->count+HTABLE_INC-1) * sizeof(HANDLE_ENTRY) ); - if (!table) return FALSE; - table->count += HTABLE_INC; - process->handle_table = table; - return TRUE; + if (table) + { + table->count += HTABLE_INC; + process->handle_table = table; + } + SYSTEM_UNLOCK(); + return (table != NULL); } @@ -65,12 +86,14 @@ static BOOL32 PROCESS_GrowHandleTable( PDB32 *process ) static HANDLE32 PROCESS_AllocBootHandle( K32OBJ *ptr, DWORD flags ) { HANDLE32 h; + SYSTEM_LOCK(); for (h = 0; h < BOOT_HTABLE_SIZE; h++) if (!boot_handles[h].ptr) break; assert( h < BOOT_HTABLE_SIZE ); K32OBJ_IncCount( ptr ); boot_handles[h].flags = flags; boot_handles[h].ptr = ptr; + SYSTEM_UNLOCK(); return h + 1; /* Avoid handle 0 */ } @@ -82,12 +105,16 @@ static HANDLE32 PROCESS_AllocBootHandle( K32OBJ *ptr, DWORD flags ) */ static BOOL32 PROCESS_CloseBootHandle( HANDLE32 handle ) { + K32OBJ *ptr; HANDLE_ENTRY *entry = &boot_handles[handle - 1]; assert( (handle > 0) && (handle <= BOOT_HTABLE_SIZE) ); + SYSTEM_LOCK(); assert( entry->ptr ); - K32OBJ_DecCount( entry->ptr ); + ptr = entry->ptr; entry->flags = 0; entry->ptr = NULL; + K32OBJ_DecCount( ptr ); + SYSTEM_UNLOCK(); return TRUE; } @@ -102,9 +129,11 @@ static K32OBJ *PROCESS_GetBootObjPtr( HANDLE32 handle, K32OBJ_TYPE type ) K32OBJ *ptr; assert( (handle > 0) && (handle <= BOOT_HTABLE_SIZE) ); + SYSTEM_LOCK(); ptr = boot_handles[handle - 1].ptr; assert (ptr && (ptr->type == type)); K32OBJ_IncCount( ptr ); + SYSTEM_UNLOCK(); return ptr; } @@ -119,10 +148,13 @@ static BOOL32 PROCESS_SetBootObjPtr( HANDLE32 handle, K32OBJ *ptr, DWORD flags) K32OBJ *old_ptr; assert( (handle > 0) && (handle <= BOOT_HTABLE_SIZE) ); + SYSTEM_LOCK(); K32OBJ_IncCount( ptr ); - if ((old_ptr = boot_handles[handle - 1].ptr)) K32OBJ_DecCount( old_ptr ); + old_ptr = boot_handles[handle - 1].ptr; boot_handles[handle - 1].flags = flags; boot_handles[handle - 1].ptr = ptr; + if (old_ptr) K32OBJ_DecCount( old_ptr ); + SYSTEM_UNLOCK(); return TRUE; } @@ -139,7 +171,7 @@ HANDLE32 PROCESS_AllocHandle( K32OBJ *ptr, DWORD flags ) assert( ptr ); if (!pCurrentProcess) return PROCESS_AllocBootHandle( ptr, flags ); - EnterCriticalSection( &pCurrentProcess->crit_section ); + SYSTEM_LOCK(); K32OBJ_IncCount( ptr ); entry = pCurrentProcess->handle_table->entries; for (h = 0; h < pCurrentProcess->handle_table->count; h++, entry++) @@ -150,12 +182,12 @@ HANDLE32 PROCESS_AllocHandle( K32OBJ *ptr, DWORD flags ) entry = &pCurrentProcess->handle_table->entries[h]; entry->flags = flags; entry->ptr = ptr; - LeaveCriticalSection( &pCurrentProcess->crit_section ); + SYSTEM_UNLOCK(); return h + 1; /* Avoid handle 0 */ } - LeaveCriticalSection( &pCurrentProcess->crit_section ); - SetLastError( ERROR_OUTOFMEMORY ); K32OBJ_DecCount( ptr ); + SYSTEM_UNLOCK(); + SetLastError( ERROR_OUTOFMEMORY ); return INVALID_HANDLE_VALUE32; } @@ -170,7 +202,7 @@ K32OBJ *PROCESS_GetObjPtr( HANDLE32 handle, K32OBJ_TYPE type ) { K32OBJ *ptr = NULL; if (!pCurrentProcess) return PROCESS_GetBootObjPtr( handle, type ); - EnterCriticalSection( &pCurrentProcess->crit_section ); + SYSTEM_LOCK(); if ((handle > 0) && (handle <= pCurrentProcess->handle_table->count)) ptr = pCurrentProcess->handle_table->entries[handle - 1].ptr; @@ -180,7 +212,7 @@ K32OBJ *PROCESS_GetObjPtr( HANDLE32 handle, K32OBJ_TYPE type ) K32OBJ_IncCount( ptr ); else ptr = NULL; - LeaveCriticalSection( &pCurrentProcess->crit_section ); + SYSTEM_UNLOCK(); if (!ptr) SetLastError( ERROR_INVALID_HANDLE ); return ptr; } @@ -198,7 +230,7 @@ BOOL32 PROCESS_SetObjPtr( HANDLE32 handle, K32OBJ *ptr, DWORD flags ) K32OBJ *old_ptr = NULL; if (!pCurrentProcess) return PROCESS_SetBootObjPtr( handle, ptr, flags ); - EnterCriticalSection( &pCurrentProcess->crit_section ); + SYSTEM_LOCK(); if ((handle > 0) && (handle <= pCurrentProcess->handle_table->count)) { HANDLE_ENTRY*entry = &pCurrentProcess->handle_table->entries[handle-1]; @@ -212,8 +244,8 @@ BOOL32 PROCESS_SetObjPtr( HANDLE32 handle, K32OBJ *ptr, DWORD flags ) SetLastError( ERROR_INVALID_HANDLE ); ret = FALSE; } - LeaveCriticalSection( &pCurrentProcess->crit_section ); if (old_ptr) K32OBJ_DecCount( old_ptr ); + SYSTEM_UNLOCK(); return ret; } @@ -227,7 +259,7 @@ BOOL32 WINAPI CloseHandle( HANDLE32 handle ) K32OBJ *ptr = NULL; if (!pCurrentProcess) return PROCESS_CloseBootHandle( handle ); - EnterCriticalSection( &pCurrentProcess->crit_section ); + SYSTEM_LOCK(); if ((handle > 0) && (handle <= pCurrentProcess->handle_table->count)) { HANDLE_ENTRY*entry = &pCurrentProcess->handle_table->entries[handle-1]; @@ -238,9 +270,9 @@ BOOL32 WINAPI CloseHandle( HANDLE32 handle ) ret = TRUE; } } - LeaveCriticalSection( &pCurrentProcess->crit_section ); - if (!ret) SetLastError( ERROR_INVALID_HANDLE ); if (ptr) K32OBJ_DecCount( ptr ); + SYSTEM_UNLOCK(); + if (!ret) SetLastError( ERROR_INVALID_HANDLE ); return ret; } @@ -323,10 +355,14 @@ PDB32 *PROCESS_Create( TDB *pTask, LPCSTR cmd_line ) pdb->parent = pCurrentProcess; pdb->group = pdb; pdb->priority = 8; /* Normal */ - pdb->heap_list = pdb->heap; InitializeCriticalSection( &pdb->crit_section ); + /* Allocate the events */ + + if (!(pdb->event = EVENT_Create( TRUE, FALSE ))) goto error; + if (!(pdb->load_done_evt = EVENT_Create( TRUE, FALSE ))) goto error; + /* Create the heap */ if (pModule->module32) @@ -340,6 +376,7 @@ PDB32 *PROCESS_Create( TDB *pTask, LPCSTR cmd_line ) commit = 0; } if (!(pdb->heap = HeapCreate( HEAP_GROWABLE, size, commit ))) goto error; + pdb->heap_list = pdb->heap; if (!(pdb->env_db = HeapAlloc(pdb->heap, HEAP_ZERO_MEMORY, sizeof(ENVDB)))) goto error; @@ -351,6 +388,8 @@ error: if (pdb->env_db) HeapFree( pdb->heap, 0, pdb->env_db ); if (pdb->handle_table) HeapFree( pdb->system_heap, 0, pdb->handle_table ); if (pdb->heap) HeapDestroy( pdb->heap ); + if (pdb->load_done_evt) K32OBJ_DecCount( pdb->load_done_evt ); + if (pdb->event) K32OBJ_DecCount( pdb->event ); DeleteCriticalSection( &pdb->crit_section ); HeapFree( SystemHeap, 0, pdb ); return NULL; @@ -358,9 +397,59 @@ error: /*********************************************************************** + * PROCESS_Signaled + */ +static BOOL32 PROCESS_Signaled( K32OBJ *obj, DWORD thread_id ) +{ + PDB32 *pdb = (PDB32 *)obj; + assert( obj->type == K32OBJ_PROCESS ); + return K32OBJ_OPS( pdb->event )->signaled( pdb->event, thread_id ); +} + + +/*********************************************************************** + * PROCESS_Satisfied + * + * Wait on this object has been satisfied. + */ +static void PROCESS_Satisfied( K32OBJ *obj, DWORD thread_id ) +{ + PDB32 *pdb = (PDB32 *)obj; + assert( obj->type == K32OBJ_PROCESS ); + return K32OBJ_OPS( pdb->event )->satisfied( pdb->event, thread_id ); +} + + +/*********************************************************************** + * PROCESS_AddWait + * + * Add thread to object wait queue. + */ +static void PROCESS_AddWait( K32OBJ *obj, DWORD thread_id ) +{ + PDB32 *pdb = (PDB32 *)obj; + assert( obj->type == K32OBJ_PROCESS ); + return K32OBJ_OPS( pdb->event )->add_wait( pdb->event, thread_id ); +} + + +/*********************************************************************** + * PROCESS_RemoveWait + * + * Remove thread from object wait queue. + */ +static void PROCESS_RemoveWait( K32OBJ *obj, DWORD thread_id ) +{ + PDB32 *pdb = (PDB32 *)obj; + assert( obj->type == K32OBJ_PROCESS ); + return K32OBJ_OPS( pdb->event )->remove_wait( pdb->event, thread_id ); +} + + +/*********************************************************************** * PROCESS_Destroy */ -void PROCESS_Destroy( K32OBJ *ptr ) +static void PROCESS_Destroy( K32OBJ *ptr ) { PDB32 *pdb = (PDB32 *)ptr; HANDLE32 handle; @@ -376,6 +465,8 @@ void PROCESS_Destroy( K32OBJ *ptr ) HeapFree( pdb->heap, 0, pdb->env_db ); HeapFree( pdb->system_heap, 0, pdb->handle_table ); HeapDestroy( pdb->heap ); + K32OBJ_DecCount( pdb->load_done_evt ); + K32OBJ_DecCount( pdb->event ); DeleteCriticalSection( &pdb->crit_section ); HeapFree( SystemHeap, 0, pdb ); } @@ -387,6 +478,9 @@ void PROCESS_Destroy( K32OBJ *ptr ) void WINAPI ExitProcess( DWORD status ) { __RESTORE_ES; /* Necessary for Pietrek's showseh example program */ + /* FIXME: should kill all running threads of this process */ + pCurrentProcess->exit_code = status; + EVENT_Set( pCurrentProcess->event ); TASK_KillCurrentTask( status ); } @@ -401,26 +495,26 @@ HANDLE32 WINAPI GetCurrentProcess(void) /********************************************************************* - * OpenProcess [KERNEL32.543] - * + * OpenProcess (KERNEL32.543) */ -HANDLE32 WINAPI OpenProcess32(DWORD fdwAccess,BOOL32 bInherit,DWORD IDProcess) +HANDLE32 WINAPI OpenProcess( DWORD access, BOOL32 inherit, DWORD id ) { - if (IDProcess != (DWORD)pCurrentProcess) { - fprintf(stderr,"OpenProcess32(%ld,%d,%ld)\n",fdwAccess,bInherit,IDProcess); - /* XXX: might not be the correct error value */ - SetLastError( ERROR_INVALID_HANDLE ); - return 0; - } - return GetCurrentProcess(); + PDB32 *pdb = PROCESS_ID_TO_PDB(id); + if (!K32OBJ_IsValid( &pdb->header, K32OBJ_PROCESS )) + { + SetLastError( ERROR_INVALID_HANDLE ); + return 0; + } + return PROCESS_AllocHandle( &pdb->header, 0 ); } + /*********************************************************************** * GetCurrentProcessId (KERNEL32.199) */ DWORD WINAPI GetCurrentProcessId(void) { - return (DWORD)pCurrentProcess; + return PDB_TO_PROCESS_ID(pCurrentProcess); } @@ -859,20 +953,25 @@ BOOL32 WINAPI SetStdHandle( DWORD std_handle, HANDLE32 handle ) /*********************************************************************** * GetProcessVersion (KERNEL32) */ -DWORD WINAPI GetProcessVersion(DWORD processid) +DWORD WINAPI GetProcessVersion( DWORD processid ) { - PDB32 *process; - TDB *pTask; + PDB32 *process; + TDB *pTask; - if (!processid) { - process=pCurrentProcess; - /* check if valid process */ - } else - process=(PDB32*)pCurrentProcess; /* decrypt too, if needed */ - pTask = (TDB*)GlobalLock16(process->task); - if (!pTask) - return 0; - return (pTask->version&0xff) | (((pTask->version >>8) & 0xff)<<16); + if (!processid) process = pCurrentProcess; + else + { + process = PROCESS_ID_TO_PDB(processid); + if (!K32OBJ_IsValid( &process->header, K32OBJ_PROCESS )) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return 0; + } + } + pTask = (TDB*)GlobalLock16(process->task); + if (!pTask) + return 0; + return (pTask->version&0xff) | (((pTask->version >>8) & 0xff)<<16); } /*********************************************************************** @@ -880,14 +979,19 @@ DWORD WINAPI GetProcessVersion(DWORD processid) */ DWORD WINAPI GetProcessFlags(DWORD processid) { - PDB32 *process; + PDB32 *process; - if (!processid) { - process=pCurrentProcess; - /* check if valid process */ - } else - process=(PDB32*)pCurrentProcess; /* decrypt too, if needed */ - return process->flags; + if (!processid) process = pCurrentProcess; + else + { + process = PROCESS_ID_TO_PDB(processid); + if (!K32OBJ_IsValid( &process->header, K32OBJ_PROCESS )) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return 0; + } + } + return process->flags; } /*********************************************************************** @@ -951,3 +1055,15 @@ HANDLE32 WINAPI ConvertToGlobalHandle(HANDLE32 h) fprintf(stderr,"ConvertToGlobalHandle(%d),stub!\n",h); return h; } + +/*********************************************************************** + * RegisterServiceProcess (KERNEL32) + * + * A service process calls this function to ensure that it continues to run + * even after a user logged off. + */ +DWORD RegisterServiceProcess(DWORD dwProcessId, DWORD dwType) +{ + /* I don't think that Wine needs to do anything in that function */ + return 1; /* success */ +} diff --git a/scheduler/semaphore.c b/scheduler/semaphore.c new file mode 100644 index 00000000000..d8c1535a4eb --- /dev/null +++ b/scheduler/semaphore.c @@ -0,0 +1,214 @@ +/* + * Win32 semaphores + * + * Copyright 1998 Alexandre Julliard + */ + +#include +#include "windows.h" +#include "winerror.h" +#include "k32obj.h" +#include "process.h" +#include "thread.h" +#include "heap.h" + +typedef struct +{ + K32OBJ header; + THREAD_QUEUE wait_queue; + LONG count; + LONG max; +} SEMAPHORE; + +static BOOL32 SEMAPHORE_Signaled( K32OBJ *obj, DWORD thread_id ); +static void SEMAPHORE_Satisfied( K32OBJ *obj, DWORD thread_id ); +static void SEMAPHORE_AddWait( K32OBJ *obj, DWORD thread_id ); +static void SEMAPHORE_RemoveWait( K32OBJ *obj, DWORD thread_id ); +static void SEMAPHORE_Destroy( K32OBJ *obj ); + +const K32OBJ_OPS SEMAPHORE_Ops = +{ + SEMAPHORE_Signaled, /* signaled */ + SEMAPHORE_Satisfied, /* satisfied */ + SEMAPHORE_AddWait, /* add_wait */ + SEMAPHORE_RemoveWait, /* remove_wait */ + SEMAPHORE_Destroy /* destroy */ +}; + + +/*********************************************************************** + * CreateSemaphore32A (KERNEL32.174) + */ +HANDLE32 WINAPI CreateSemaphore32A( SECURITY_ATTRIBUTES *sa, LONG initial, + LONG max, LPCSTR name ) +{ + HANDLE32 handle; + SEMAPHORE *sem; + + /* Check parameters */ + + if ((max <= 0) || (initial < 0) || (initial > max)) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return INVALID_HANDLE_VALUE32; + } + + SYSTEM_LOCK(); + sem = (SEMAPHORE *)K32OBJ_Create( K32OBJ_SEMAPHORE, sizeof(*sem), + name, &handle ); + if (sem) + { + /* Finish initializing it */ + sem->wait_queue = NULL; + sem->count = initial; + sem->max = max; + K32OBJ_DecCount( &sem->header ); + } + SYSTEM_UNLOCK(); + return handle; +} + + +/*********************************************************************** + * CreateSemaphore32W (KERNEL32.175) + */ +HANDLE32 WINAPI CreateSemaphore32W( SECURITY_ATTRIBUTES *sa, LONG initial, + LONG max, LPCWSTR name ) +{ + LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name ); + HANDLE32 ret = CreateSemaphore32A( sa, initial, max, nameA ); + if (nameA) HeapFree( GetProcessHeap(), 0, nameA ); + return ret; +} + + +/*********************************************************************** + * OpenSemaphore32A (KERNEL32.545) + */ +HANDLE32 WINAPI OpenSemaphore32A( DWORD access, BOOL32 inherit, LPCSTR name ) +{ + HANDLE32 handle = 0; + K32OBJ *obj; + SYSTEM_LOCK(); + if ((obj = K32OBJ_FindNameType( name, K32OBJ_SEMAPHORE )) != NULL) + { + handle = PROCESS_AllocHandle( obj, 0 ); + K32OBJ_DecCount( obj ); + } + SYSTEM_UNLOCK(); + return handle; +} + + +/*********************************************************************** + * OpenSemaphore32W (KERNEL32.546) + */ +HANDLE32 WINAPI OpenSemaphore32W( DWORD access, BOOL32 inherit, LPCWSTR name ) +{ + LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name ); + HANDLE32 ret = OpenSemaphore32A( access, inherit, nameA ); + if (nameA) HeapFree( GetProcessHeap(), 0, nameA ); + return ret; +} + + +/*********************************************************************** + * ReleaseSemaphore (KERNEL32.583) + */ +BOOL32 WINAPI ReleaseSemaphore( HANDLE32 handle, LONG count, LONG *previous ) +{ + SEMAPHORE *sem; + + SYSTEM_LOCK(); + if (!(sem = (SEMAPHORE *)PROCESS_GetObjPtr( handle, K32OBJ_SEMAPHORE ))) + { + SYSTEM_UNLOCK(); + return FALSE; + } + if (previous) *previous = sem->count; + if (sem->count + count > sem->max) + { + SYSTEM_UNLOCK(); + SetLastError( ERROR_TOO_MANY_POSTS ); + return FALSE; + } + if (sem->count > 0) + { + /* There cannot be any thread waiting if the count is > 0 */ + assert( sem->wait_queue == NULL ); + sem->count += count; + } + else + { + sem->count = count; + SYNC_WakeUp( &sem->wait_queue, count ); + } + K32OBJ_DecCount( &sem->header ); + SYSTEM_UNLOCK(); + return TRUE; +} + + +/*********************************************************************** + * SEMAPHORE_Signaled + */ +static BOOL32 SEMAPHORE_Signaled( K32OBJ *obj, DWORD thread_id ) +{ + SEMAPHORE *sem = (SEMAPHORE *)obj; + assert( obj->type == K32OBJ_SEMAPHORE ); + return (sem->count > 0); +} + + +/*********************************************************************** + * SEMAPHORE_Satisfied + * + * Wait on this object has been satisfied. + */ +static void SEMAPHORE_Satisfied( K32OBJ *obj, DWORD thread_id ) +{ + SEMAPHORE *sem = (SEMAPHORE *)obj; + assert( obj->type == K32OBJ_SEMAPHORE ); + assert( sem->count > 0 ); + sem->count--; +} + + +/*********************************************************************** + * SEMAPHORE_AddWait + * + * Add current thread to object wait queue. + */ +static void SEMAPHORE_AddWait( K32OBJ *obj, DWORD thread_id ) +{ + SEMAPHORE *sem = (SEMAPHORE *)obj; + assert( obj->type == K32OBJ_SEMAPHORE ); + THREAD_AddQueue( &sem->wait_queue, THREAD_ID_TO_THDB(thread_id) ); +} + + +/*********************************************************************** + * SEMAPHORE_RemoveWait + * + * Remove thread from object wait queue. + */ +static void SEMAPHORE_RemoveWait( K32OBJ *obj, DWORD thread_id ) +{ + SEMAPHORE *sem = (SEMAPHORE *)obj; + assert( obj->type == K32OBJ_SEMAPHORE ); + THREAD_RemoveQueue( &sem->wait_queue, THREAD_ID_TO_THDB(thread_id) ); +} + + +/*********************************************************************** + * SEMAPHORE_Destroy + */ +static void SEMAPHORE_Destroy( K32OBJ *obj ) +{ + SEMAPHORE *sem = (SEMAPHORE *)obj; + assert( obj->type == K32OBJ_SEMAPHORE ); + /* There cannot be any thread on the list since the ref count is 0 */ + assert( sem->wait_queue == NULL ); + obj->type = K32OBJ_UNKNOWN; + HeapFree( SystemHeap, 0, sem ); +} diff --git a/scheduler/synchro.c b/scheduler/synchro.c new file mode 100644 index 00000000000..20002179c8d --- /dev/null +++ b/scheduler/synchro.c @@ -0,0 +1,315 @@ +/* + * Win32 process and thread synchronisation + * + * Copyright 1997 Alexandre Julliard + */ + +#include +#include +#include +#include +#include +#include "k32obj.h" +#include "heap.h" +#include "process.h" +#include "thread.h" +#include "winerror.h" +#include "stddebug.h" +#include "debug.h" + +/*********************************************************************** + * SYNC_BuildWaitStruct + */ +static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles, + BOOL32 wait_all, WAIT_STRUCT *wait ) +{ + DWORD i; + K32OBJ **ptr; + + wait->count = count; + wait->signaled = WAIT_FAILED; + wait->wait_all = wait_all; + SYSTEM_LOCK(); + for (i = 0, ptr = wait->objs; i < count; i++, ptr++) + { + if (!(*ptr = PROCESS_GetObjPtr( handles[i], K32OBJ_UNKNOWN ))) + break; + if (!K32OBJ_OPS( *ptr )->signaled) + { + /* This object type cannot be waited upon */ + K32OBJ_DecCount( *ptr ); + break; + } + + } + if (i != count) + { + /* There was an error */ + while (i--) K32OBJ_DecCount( wait->objs[i] ); + } + SYSTEM_UNLOCK(); + return (i == count); +} + + +/*********************************************************************** + * SYNC_FreeWaitStruct + */ +static void SYNC_FreeWaitStruct( WAIT_STRUCT *wait ) +{ + DWORD i; + K32OBJ **ptr; + SYSTEM_LOCK(); + for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++) + K32OBJ_DecCount( *ptr ); + SYSTEM_UNLOCK(); +} + + +/*********************************************************************** + * SYNC_CheckCondition + */ +static BOOL32 SYNC_CheckCondition( WAIT_STRUCT *wait, DWORD thread_id ) +{ + DWORD i; + K32OBJ **ptr; + + SYSTEM_LOCK(); + if (wait->wait_all) + { + for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++) + { + if (!K32OBJ_OPS( *ptr )->signaled( *ptr, thread_id )) + { + SYSTEM_UNLOCK(); + return FALSE; + } + } + /* Wait satisfied: tell it to all objects */ + wait->signaled = WAIT_OBJECT_0; + for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++) + K32OBJ_OPS( *ptr )->satisfied( *ptr, thread_id ); + SYSTEM_UNLOCK(); + return TRUE; + } + else + { + for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++) + { + if (K32OBJ_OPS( *ptr )->signaled( *ptr, thread_id )) + { + /* Wait satisfied: tell it to the object */ + wait->signaled = WAIT_OBJECT_0 + i; + K32OBJ_OPS( *ptr )->satisfied( *ptr, thread_id ); + SYSTEM_UNLOCK(); + return TRUE; + } + } + SYSTEM_UNLOCK(); + return FALSE; + } +} + + +/*********************************************************************** + * SYNC_WaitForCondition + */ +void SYNC_WaitForCondition( WAIT_STRUCT *wait, DWORD timeout ) +{ + DWORD i, thread_id = GetCurrentThreadId(); + LONG count; + K32OBJ **ptr; + sigset_t set; + + SYSTEM_LOCK(); + if (SYNC_CheckCondition( wait, thread_id )) + goto done; /* Condition already satisfied */ + if (!timeout) + { + /* No need to wait */ + wait->signaled = WAIT_TIMEOUT; + goto done; + } + + /* Add ourselves to the waiting list of all objects */ + + for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++) + K32OBJ_OPS( *ptr )->add_wait( *ptr, thread_id ); + + /* Release the system lock completely */ + + count = SYSTEM_LOCK_COUNT(); + for (i = count; i > 0; i--) SYSTEM_UNLOCK(); + + /* Now wait for it */ + + dprintf_win32( stddeb, "SYNC: starting wait (%p %04x)\n", + THREAD_Current(), THREAD_Current()->teb_sel ); + + sigprocmask( SIG_SETMASK, NULL, &set ); + sigdelset( &set, SIGUSR1 ); + sigdelset( &set, SIGALRM ); + if (timeout != INFINITE32) + { + while (wait->signaled == WAIT_FAILED) + { + struct itimerval timer; + DWORD start_ticks, elapsed; + timer.it_interval.tv_sec = timer.it_interval.tv_usec = 0; + timer.it_value.tv_sec = timeout / 1000; + timer.it_value.tv_usec = (timeout % 1000) * 1000; + start_ticks = GetTickCount(); + setitimer( ITIMER_REAL, &timer, NULL ); + sigsuspend( &set ); + if (wait->signaled != WAIT_FAILED) break; + /* Recompute the timer value */ + elapsed = GetTickCount() - start_ticks; + if (elapsed >= timeout) wait->signaled = WAIT_TIMEOUT; + else timeout -= elapsed; + } + } + else + { + while (wait->signaled == WAIT_FAILED) + { + sigsuspend( &set ); + } + } + + /* Grab the system lock again */ + + while (count--) SYSTEM_LOCK(); + dprintf_win32( stddeb, "SYNC: wait finished (%p %04x)\n", + THREAD_Current(), THREAD_Current()->teb_sel ); + + /* Remove ourselves from the lists */ + + for (i = 0, ptr = wait->objs; i < wait->count; i++, ptr++) + K32OBJ_OPS( *ptr )->remove_wait( *ptr, thread_id ); + +done: + SYSTEM_UNLOCK(); +} + + +/*********************************************************************** + * SYNC_DummySigHandler + * + * Dummy signal handler + */ +static void SYNC_DummySigHandler(void) +{ +} + + +/*********************************************************************** + * SYNC_SetupSignals + * + * Setup signal handlers for a new thread. + * FIXME: should merge with SIGNAL_Init. + */ +void SYNC_SetupSignals(void) +{ + sigset_t set; + SIGNAL_SetHandler( SIGUSR1, SYNC_DummySigHandler, 0 ); + /* FIXME: conflicts with system timers */ + SIGNAL_SetHandler( SIGALRM, SYNC_DummySigHandler, 0 ); + sigemptyset( &set ); + /* Make sure these are blocked by default */ + sigaddset( &set, SIGUSR1 ); + sigaddset( &set, SIGALRM ); + sigprocmask( SIG_BLOCK , &set, NULL); +} + + +/*********************************************************************** + * SYNC_WakeUp + */ +void SYNC_WakeUp( THREAD_QUEUE *wait_queue, DWORD max ) +{ + THREAD_ENTRY *entry; + + if (!max) max = INFINITE32; + SYSTEM_LOCK(); + if (!*wait_queue) + { + SYSTEM_UNLOCK(); + return; + } + entry = (*wait_queue)->next; + for (;;) + { + THDB *thdb = entry->thread; + if (SYNC_CheckCondition( &thdb->wait_struct, THDB_TO_THREAD_ID(thdb) )) + { + dprintf_win32( stddeb, "SYNC: waking up %04x\n", thdb->teb_sel ); + kill( thdb->unix_pid, SIGUSR1 ); + if (!--max) break; + } + if (entry == *wait_queue) break; + entry = entry->next; + } + SYSTEM_UNLOCK(); +} + + +/*********************************************************************** + * WaitForSingleObject (KERNEL32.723) + */ +DWORD WINAPI WaitForSingleObject( HANDLE32 handle, DWORD timeout ) +{ + return WaitForMultipleObjectsEx( 1, &handle, FALSE, timeout, FALSE ); +} + + +/*********************************************************************** + * WaitForSingleObjectEx (KERNEL32.724) + */ +DWORD WINAPI WaitForSingleObjectEx( HANDLE32 handle, DWORD timeout, + BOOL32 alertable ) +{ + return WaitForMultipleObjectsEx( 1, &handle, FALSE, timeout, alertable ); +} + + +/*********************************************************************** + * WaitForMultipleObjects (KERNEL32.721) + */ +DWORD WINAPI WaitForMultipleObjects( DWORD count, const HANDLE32 *handles, + BOOL32 wait_all, DWORD timeout ) +{ + return WaitForMultipleObjectsEx(count, handles, wait_all, timeout, FALSE); +} + + +/*********************************************************************** + * WaitForMultipleObjectsEx (KERNEL32.722) + */ +DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE32 *handles, + BOOL32 wait_all, DWORD timeout, + BOOL32 alertable ) +{ + WAIT_STRUCT *wait = &THREAD_Current()->wait_struct; + + if (count > MAXIMUM_WAIT_OBJECTS) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return WAIT_FAILED; + } + + if (alertable) + fprintf( stderr, + "WaitForMultipleObjectEx: alertable not implemented\n" ); + + SYSTEM_LOCK(); + if (!SYNC_BuildWaitStruct( count, handles, wait_all, wait )) + wait->signaled = WAIT_FAILED; + else + { + /* Now wait for it */ + SYNC_WaitForCondition( wait, timeout ); + SYNC_FreeWaitStruct( wait ); + } + SYSTEM_UNLOCK(); + return wait->signaled; +} diff --git a/scheduler/thread.c b/scheduler/thread.c index 97400861782..73959d025ad 100644 --- a/scheduler/thread.c +++ b/scheduler/thread.c @@ -6,7 +6,10 @@ #include #include +#include +#include #include "thread.h" +#include "process.h" #include "winerror.h" #include "heap.h" #include "selectors.h" @@ -15,8 +18,40 @@ #include "debug.h" #include "stddebug.h" -THDB *pCurrentThread = NULL; -static K32OBJ_LIST THREAD_List; +#ifdef HAVE_CLONE +# ifdef HAVE_SCHED_H +# include +# endif +# ifndef CLONE_VM +# define CLONE_VM 0x00000100 +# define CLONE_FS 0x00000200 +# define CLONE_FILES 0x00000400 +# define CLONE_SIGHAND 0x00000800 +# define CLONE_PID 0x00001000 +/* If we didn't get the flags, we probably didn't get the prototype either */ +extern int clone( int (*fn)(void *arg), void *stack, int flags, void *arg ); +# endif /* CLONE_VM */ +#endif /* HAVE_CLONE */ + +#ifndef __i386__ +THDB *pCurrentThread; +#endif + +static BOOL32 THREAD_Signaled( K32OBJ *obj, DWORD thread_id ); +static void THREAD_Satisfied( K32OBJ *obj, DWORD thread_id ); +static void THREAD_AddWait( K32OBJ *obj, DWORD thread_id ); +static void THREAD_RemoveWait( K32OBJ *obj, DWORD thread_id ); +static void THREAD_Destroy( K32OBJ *obj ); + +const K32OBJ_OPS THREAD_Ops = +{ + THREAD_Signaled, /* signaled */ + THREAD_Satisfied, /* satisfied */ + THREAD_AddWait, /* add_wait */ + THREAD_RemoveWait, /* remove_wait */ + THREAD_Destroy /* destroy */ +}; + /*********************************************************************** * THREAD_GetPtr @@ -38,6 +73,28 @@ static THDB *THREAD_GetPtr( HANDLE32 handle ) } +/********************************************************************** + * NtCurrentTeb (NTDLL.89) + */ +TEB * WINAPI NtCurrentTeb(void) +{ +#ifdef __i386__ + TEB *teb; + WORD ds, fs; + + /* Check if we have a current thread */ + GET_DS( ds ); + GET_FS( fs ); + if (fs == ds) return NULL; /* FIXME: should be an assert */ + __asm__( "movl %%fs:(24),%0" : "=r" (teb) ); + return teb; +#else + if (!pCurrentThread) return NULL; + return &pCurrentThread->teb; +#endif /* __i386__ */ +} + + /*********************************************************************** * THREAD_Current * @@ -45,9 +102,62 @@ static THDB *THREAD_GetPtr( HANDLE32 handle ) */ THDB *THREAD_Current(void) { - /* FIXME: should probably use %fs register here */ - assert( pCurrentThread ); - return pCurrentThread; + TEB *teb = NtCurrentTeb(); + if (!teb) return NULL; + return (THDB *)((char *)teb - (int)&((THDB *)0)->teb); +} + + +/*********************************************************************** + * THREAD_AddQueue + * + * Add a thread to a queue. + */ +void THREAD_AddQueue( THREAD_QUEUE *queue, THDB *thread ) +{ + THREAD_ENTRY *entry = HeapAlloc( SystemHeap, HEAP_NO_SERIALIZE, + sizeof(*entry) ); + assert(entry); + SYSTEM_LOCK(); + entry->thread = thread; + if (*queue) + { + entry->next = (*queue)->next; + (*queue)->next = entry; + } + else entry->next = entry; + *queue = entry; + SYSTEM_UNLOCK(); +} + +/*********************************************************************** + * THREAD_RemoveQueue + * + * Remove a thread from a queue. + */ +void THREAD_RemoveQueue( THREAD_QUEUE *queue, THDB *thread ) +{ + THREAD_ENTRY *entry = *queue; + SYSTEM_LOCK(); + if (entry->next == entry) /* Only one element in the queue */ + { + assert( entry->thread == thread ); + *queue = NULL; + } + else + { + THREAD_ENTRY *next; + while (entry->next->thread != thread) + { + entry = entry->next; + assert( entry != *queue ); /* Have we come all the way around? */ + } + if ((next = entry->next) == *queue) *queue = entry; + entry->next = entry->next->next; + entry = next; /* This is the one we want to free */ + } + HeapFree( SystemHeap, 0, entry ); + SYSTEM_UNLOCK(); } @@ -55,10 +165,11 @@ THDB *THREAD_Current(void) * THREAD_Create */ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, - LPTHREAD_START_ROUTINE start_addr ) + LPTHREAD_START_ROUTINE start_addr, LPVOID param ) { DWORD old_prot; WORD cs, ds; + THDB *thdb = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, sizeof(THDB) ); if (!thdb) return NULL; thdb->header.type = K32OBJ_THREAD; @@ -69,8 +180,11 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, thdb->teb.stack_sel = 0; /* FIXME */ thdb->teb.self = &thdb->teb; thdb->teb.tls_ptr = thdb->tls_array; + thdb->wait_list = &thdb->wait_struct; thdb->process2 = pdb; thdb->exit_code = 0x103; /* STILL_ACTIVE */ + thdb->entry_point = start_addr; + thdb->entry_arg = param; /* Allocate the stack */ @@ -91,6 +205,10 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, TRUE, FALSE ); if (!thdb->teb_sel) goto error; + /* Allocate the event */ + + if (!(thdb->event = EVENT_Create( TRUE, FALSE ))) goto error; + /* Initialize the thread context */ GET_CS(cs); @@ -104,14 +222,10 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, thdb->context.SegFs = thdb->teb_sel; thdb->context.Eip = (DWORD)start_addr; thdb->context.Esp = (DWORD)thdb->teb.stack_top; - - /* Add the thread to the linked list */ - - K32OBJ_AddTail( &THREAD_List, &thdb->header ); - return thdb; error: + if (thdb->event) K32OBJ_DecCount( thdb->event ); if (thdb->teb_sel) SELECTOR_FreeBlock( thdb->teb_sel, 1 ); if (thdb->stack_base) VirtualFree( thdb->stack_base, 0, MEM_RELEASE ); HeapFree( SystemHeap, 0, thdb ); @@ -120,18 +234,79 @@ error: /*********************************************************************** + * THREAD_Start + * + * Startup routine for a new thread. + */ +static void THREAD_Start( THDB *thdb ) +{ + LPTHREAD_START_ROUTINE func = (LPTHREAD_START_ROUTINE)thdb->entry_point; + thdb->unix_pid = getpid(); + SET_FS( thdb->teb_sel ); + ExitThread( func( thdb->entry_arg ) ); +} + + +/*********************************************************************** + * THREAD_Signaled + */ +static BOOL32 THREAD_Signaled( K32OBJ *obj, DWORD thread_id ) +{ + THDB *thdb = (THDB *)obj; + assert( obj->type == K32OBJ_THREAD ); + return K32OBJ_OPS( thdb->event )->signaled( thdb->event, thread_id ); +} + + +/*********************************************************************** + * THREAD_Satisfied + * + * Wait on this object has been satisfied. + */ +static void THREAD_Satisfied( K32OBJ *obj, DWORD thread_id ) +{ + THDB *thdb = (THDB *)obj; + assert( obj->type == K32OBJ_THREAD ); + return K32OBJ_OPS( thdb->event )->satisfied( thdb->event, thread_id ); +} + + +/*********************************************************************** + * THREAD_AddWait + * + * Add thread to object wait queue. + */ +static void THREAD_AddWait( K32OBJ *obj, DWORD thread_id ) +{ + THDB *thdb = (THDB *)obj; + assert( obj->type == K32OBJ_THREAD ); + return K32OBJ_OPS( thdb->event )->add_wait( thdb->event, thread_id ); +} + + +/*********************************************************************** + * THREAD_RemoveWait + * + * Remove thread from object wait queue. + */ +static void THREAD_RemoveWait( K32OBJ *obj, DWORD thread_id ) +{ + THDB *thdb = (THDB *)obj; + assert( obj->type == K32OBJ_THREAD ); + return K32OBJ_OPS( thdb->event )->remove_wait( thdb->event, thread_id ); +} + + +/*********************************************************************** * THREAD_Destroy */ -void THREAD_Destroy( K32OBJ *ptr ) +static void THREAD_Destroy( K32OBJ *ptr ) { THDB *thdb = (THDB *)ptr; assert( ptr->type == K32OBJ_THREAD ); ptr->type = K32OBJ_UNKNOWN; - /* Note: when we get here, the thread has already been removed */ - /* from the thread list */ - /* Free the associated memory */ #ifdef __i386__ @@ -146,6 +321,7 @@ void THREAD_Destroy( K32OBJ *ptr ) } } #endif + K32OBJ_DecCount( thdb->event ); SELECTOR_FreeBlock( thdb->teb_sel, 1 ); HeapFree( SystemHeap, 0, thdb ); @@ -153,54 +329,57 @@ void THREAD_Destroy( K32OBJ *ptr ) /*********************************************************************** - * THREAD_SwitchThread - * - * Return the thread we want to switch to, and switch the contexts. - */ -THDB *THREAD_SwitchThread( CONTEXT *context ) -{ - K32OBJ *cur; - THDB *next; - if (!pCurrentThread) return NULL; - cur = K32OBJ_RemoveHead( &THREAD_List ); - K32OBJ_AddTail( &THREAD_List, cur ); - K32OBJ_DecCount( cur ); - next = (THDB *)THREAD_List.head; - if (next != pCurrentThread) - { - pCurrentThread->context = *context; - pCurrentThread = next; - *context = pCurrentThread->context; - } - return pCurrentThread; -} - - -/*********************************************************************** * CreateThread (KERNEL32.63) - * - * The only thing missing here is actually getting the thread to run ;-) */ HANDLE32 WINAPI CreateThread( LPSECURITY_ATTRIBUTES attribs, DWORD stack, LPTHREAD_START_ROUTINE start, LPVOID param, DWORD flags, LPDWORD id ) { HANDLE32 handle; - THDB *thread = THREAD_Create( pCurrentProcess, stack, start ); + THDB *thread = THREAD_Create( pCurrentProcess, stack, start, param ); if (!thread) return INVALID_HANDLE_VALUE32; handle = PROCESS_AllocHandle( &thread->header, 0 ); if (handle == INVALID_HANDLE_VALUE32) { - THREAD_Destroy( &thread->header ); + K32OBJ_DecCount( &thread->header ); + return INVALID_HANDLE_VALUE32; + } +#ifdef HAVE_CLONE + if (clone( (int (*)(void *))THREAD_Start, thread->teb.stack_top, + CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, thread ) < 0) + { + K32OBJ_DecCount( &thread->header ); return INVALID_HANDLE_VALUE32; } - *id = (DWORD)thread; +#else fprintf( stderr, "CreateThread: stub\n" ); +#endif /* __linux__ */ + *id = THDB_TO_THREAD_ID( thread ); return handle; } /*********************************************************************** + * ExitThread (KERNEL32.215) + */ +void WINAPI ExitThread( DWORD code ) +{ + THDB *thdb = THREAD_Current(); + LONG count; + + SYSTEM_LOCK(); + thdb->exit_code = code; + EVENT_Set( thdb->event ); + /* FIXME: should free the stack somehow */ + K32OBJ_DecCount( &thdb->header ); + /* Completely unlock the system lock just in case */ + count = SYSTEM_LOCK_COUNT(); + while (count--) SYSTEM_UNLOCK(); + _exit( 0 ); +} + + +/*********************************************************************** * GetCurrentThread (KERNEL32.200) */ HANDLE32 WINAPI GetCurrentThread(void) @@ -211,11 +390,10 @@ HANDLE32 WINAPI GetCurrentThread(void) /*********************************************************************** * GetCurrentThreadId (KERNEL32.201) - * Returns crypted (xor'ed) pointer to THDB in Win95. */ DWORD WINAPI GetCurrentThreadId(void) { - return (DWORD)THREAD_Current(); + return THDB_TO_THREAD_ID( THREAD_Current() ); } @@ -234,10 +412,9 @@ DWORD WINAPI GetLastError(void) */ void WINAPI SetLastError( DWORD error ) { - THDB *thread; - if (!pCurrentThread) return; /* FIXME */ - thread = THREAD_Current(); - thread->last_error = error; + THDB *thread = THREAD_Current(); + /* This one must work before we have a thread (FIXME) */ + if (thread) thread->last_error = error; } @@ -354,15 +531,6 @@ BOOL32 WINAPI GetThreadContext( HANDLE32 handle, CONTEXT *context ) /********************************************************************** - * NtCurrentTeb (NTDLL.89) - */ -void WINAPI NtCurrentTeb( CONTEXT *context ) -{ - EAX_reg(context) = GetSelectorBase( FS_reg(context) ); -} - - -/********************************************************************** * GetThreadPriority (KERNEL32.296) */ INT32 WINAPI GetThreadPriority(HANDLE32 hthread) @@ -393,9 +561,9 @@ BOOL32 WINAPI SetThreadPriority(HANDLE32 hthread,INT32 priority) /********************************************************************** * TerminateThread (KERNEL32) */ -BOOL32 WINAPI TerminateThread(DWORD threadid,DWORD exitcode) +BOOL32 WINAPI TerminateThread(HANDLE32 handle,DWORD exitcode) { - fprintf(stdnimp,"TerminateThread(0x%08lx,%ld), STUB!\n",threadid,exitcode); + fprintf(stdnimp,"TerminateThread(0x%08x,%ld), STUB!\n",handle,exitcode); return TRUE; } @@ -415,17 +583,17 @@ BOOL32 WINAPI GetExitCodeThread(HANDLE32 hthread,LPDWORD exitcode) /********************************************************************** * ResumeThread (KERNEL32) */ -BOOL32 WINAPI ResumeThread(DWORD threadid) +BOOL32 WINAPI ResumeThread( HANDLE32 handle ) { - fprintf(stdnimp,"ResumeThread(0x%08lx), STUB!\n",threadid); + fprintf(stdnimp,"ResumeThread(0x%08x), STUB!\n",handle); return TRUE; } /********************************************************************** * SuspendThread (KERNEL32) */ -BOOL32 WINAPI SuspendThread(DWORD threadid) +BOOL32 WINAPI SuspendThread( HANDLE32 handle ) { - fprintf(stdnimp,"SuspendThread(0x%08lx), STUB!\n",threadid); + fprintf(stdnimp,"SuspendThread(0x%08x), STUB!\n",handle); return TRUE; } diff --git a/tools/build.c b/tools/build.c index c692a41bf23..ad4db7464de 100644 --- a/tools/build.c +++ b/tools/build.c @@ -1240,7 +1240,7 @@ static int BuildSpec16File( char * specfile, FILE *outfile ) /* Output the DLL descriptor */ fprintf( outfile, "\t.text\n" ); - fprintf( outfile, "DLLName:\t.ascii \"%s\\0\"\n", DLLName ); + fprintf( outfile, "DLLName:\t.string \"%s\\0\"\n", DLLName ); fprintf( outfile, "\t.align 4\n" ); fprintf( outfile, "\t.globl " PREFIX "%s_Descriptor\n", DLLName ); fprintf( outfile, PREFIX "%s_Descriptor:\n", DLLName ); @@ -1459,9 +1459,9 @@ static void RestoreContext16( FILE *outfile ) CONTEXTOFFSET(SegCs) - sizeof(CONTEXT) ); fprintf( outfile, "\tpushw %d(%%ebx)\n", /* Push new ip */ CONTEXTOFFSET(Eip) - sizeof(CONTEXT) ); - fprintf( outfile, "\tpushw %d(%%ebx)\n", /* Push new ds */ + fprintf( outfile, "\tpushl %d(%%ebx)\n", /* Push new ds */ CONTEXTOFFSET(SegDs) - sizeof(CONTEXT) ); - fprintf( outfile, "\tpushw %d(%%ebx)\n", /* Push new es */ + fprintf( outfile, "\tpushl %d(%%ebx)\n", /* Push new es */ CONTEXTOFFSET(SegEs) - sizeof(CONTEXT) ); fprintf( outfile, "\tpushl %d(%%ebx)\n", CONTEXTOFFSET(EFlags) - sizeof(CONTEXT) ); @@ -1470,8 +1470,8 @@ static void RestoreContext16( FILE *outfile ) CONTEXTOFFSET(Eax) - sizeof(CONTEXT) ); fprintf( outfile, "\tmovl %d(%%ebx),%%ebx\n", CONTEXTOFFSET(Ebx) - sizeof(CONTEXT) ); - fprintf( outfile, "\tpopw %%es\n" ); /* Set es */ - fprintf( outfile, "\tpopw %%ds\n" ); /* Set ds */ + fprintf( outfile, "\tpopl %%es\n" ); /* Set es */ + fprintf( outfile, "\tpopl %%ds\n" ); /* Set ds */ } @@ -1547,8 +1547,8 @@ static void BuildCallFrom16Func( FILE *outfile, char *profile ) /* Restore 32-bit ds and es */ fprintf( outfile, "\tpushl $0x%04x%04x\n", Data_Selector, Data_Selector ); - fprintf( outfile, "\tpopw %%ds\n" ); - fprintf( outfile, "\tpopw %%es\n" ); + fprintf( outfile, "\t.byte 0x66\n\tpopl %%ds\n" ); + fprintf( outfile, "\t.byte 0x66\n\tpopl %%es\n" ); /* Save the 16-bit stack */ @@ -1577,8 +1577,8 @@ static void BuildCallFrom16Func( FILE *outfile, char *profile ) /* Switch to the 32-bit stack */ fprintf( outfile, "\tmovl " PREFIX "CALLTO16_Saved32_esp,%%ebp\n" ); - fprintf( outfile, "\tpushw %%ds\n" ); - fprintf( outfile, "\tpopw %%ss\n" ); + fprintf( outfile, "\tpushl %%ds\n" ); + fprintf( outfile, "\tpopl %%ss\n" ); fprintf( outfile, "\tleal -%d(%%ebp),%%esp\n", reg_func ? sizeof(CONTEXT) : 4 * strlen(args) ); if (reg_func) /* Push the address of the context struct */ @@ -1603,7 +1603,7 @@ static void BuildCallFrom16Func( FILE *outfile, char *profile ) /* Call the entry point */ - fprintf( outfile, "\tcall %%eax\n" ); + fprintf( outfile, "\tcall *%%eax\n" ); /* Print the debug information after the call */ @@ -1675,7 +1675,7 @@ static void BuildCallFrom16Func( FILE *outfile, char *profile ) fprintf( outfile, "\tincl %%esp\n" ); fprintf( outfile, "\tpopl %%edx\n" ); /* Remove cs and ds */ fprintf( outfile, "\tmovw %%dx,%%ds\n" ); /* and restore ds */ - fprintf( outfile, "\tpopw %%es\n" ); /* Restore es */ + fprintf( outfile, "\t.byte 0x66\n\tpopl %%es\n" ); /* Restore es */ if (short_ret) fprintf( outfile, "\tpopl %%edx\n" ); /* Restore edx */ else @@ -1757,8 +1757,7 @@ static void BuildCallTo16Func( FILE *outfile, char *profile ) /* Call the actual CallTo16 routine (simulate a lcall) */ - fprintf( outfile, "\tpushw $0\n" ); - fprintf( outfile, "\tpushw %%cs\n" ); + fprintf( outfile, "\tpushl %%cs\n" ); fprintf( outfile, "\tcall do_callto16_%s\n", profile ); /* Exit code */ @@ -1850,10 +1849,10 @@ static void BuildCallTo16Func( FILE *outfile, char *profile ) /* Get the 16-bit ds */ - fprintf( outfile, "\tpushw %d(%%ebx)\n", CONTEXTOFFSET(SegDs) ); + fprintf( outfile, "\tpushl %d(%%ebx)\n", CONTEXTOFFSET(SegDs) ); /* Get ebx from the 32-bit stack */ fprintf( outfile, "\tmovl %d(%%ebx),%%ebx\n", CONTEXTOFFSET(Ebx) ); - fprintf( outfile, "\tpopw %%ds\n" ); + fprintf( outfile, "\tpopl %%ds\n" ); } else /* not a register function */ { @@ -2046,7 +2045,7 @@ static void BuildCallTo32LargeStack( FILE *outfile ) /* Transfer the argument and call the function */ fprintf( outfile, "\tpushl 12(%%ebp)\n" ); - fprintf( outfile, "\tcall 8(%%ebp)\n" ); + fprintf( outfile, "\tcall *8(%%ebp)\n" ); /* Restore registers and return */ @@ -2088,11 +2087,11 @@ static void BuildCallFrom32Regs( FILE *outfile ) /* Build the context structure */ fprintf( outfile, "\tpushw $0\n" ); - fprintf( outfile, "\tpushw %%ss\n" ); + fprintf( outfile, "\t.byte 0x66\n\tpushl %%ss\n" ); fprintf( outfile, "\tpushl %%eax\n" ); /* %esp place holder */ fprintf( outfile, "\tpushfl\n" ); fprintf( outfile, "\tpushw $0\n" ); - fprintf( outfile, "\tpushw %%cs\n" ); + fprintf( outfile, "\t.byte 0x66\n\tpushl %%cs\n" ); fprintf( outfile, "\tpushl 20(%%esp)\n" ); /* %eip at time of call */ fprintf( outfile, "\tpushl %%ebp\n" ); @@ -2218,7 +2217,7 @@ static int BuildCallFrom16( FILE *outfile, char * outname, int argc, char *argv[ for (i = 2; i < argc; i++) { fprintf( outfile, "Profile_%s:\n", argv[i] ); - fprintf( outfile, "\t.ascii \"%s\\0\"\n", argv[i] + 5 ); + fprintf( outfile, "\t.string \"%s\\0\"\n", argv[i] + 5 ); } } diff --git a/tools/fnt2bdf.c b/tools/fnt2bdf.c index d994a996636..80537be43eb 100644 --- a/tools/fnt2bdf.c +++ b/tools/fnt2bdf.c @@ -191,7 +191,8 @@ int dump_bdf( fnt_fontS* cpe_font_struct, unsigned char* file_buffer) return ERROR_FILE; } - dump_bdf_hdr(fp, cpe_font_struct, file_buffer); + ic = dump_bdf_hdr(fp, cpe_font_struct, file_buffer); + if (ic) return (ic); /* NOW, convert all chars to UNIX (lton) notation... */ @@ -563,47 +564,66 @@ int main(int argc, char **argv) if( !(lpfont = (unsigned char*) realloc( lpfont, length )) ) { fprintf(stderr, errorMemory ); - free(lpdata); - return -1; + exit(1); } lseek( fd, offset, SEEK_SET ); if( read(fd, lpfont, length) != length ) { fprintf(stderr, errorDLLRead ); - free(lpdata); free(lpfont); - return -1; + exit(1); } if( (i = parse_fnt_data( lpfont, length )) ) + { fprintf(stderr, "%s%d\n", errorFontData, i ); + exit(1); + } } free(lpfont); free(lpdata); - return 0; + exit(0); + } + else + { + fprintf(stderr, errorEmpty ); + exit(1); } - else fprintf(stderr, errorEmpty ); free( lpdata ); } - else fprintf(stderr, errorDLLRead); + else + { + fprintf(stderr, errorDLLRead); + exit(1); + } break; case FILE_FNT: if( lpdata ) { if( (i = parse_fnt_data( lpdata, file_stat.st_size )) ) + { fprintf(stderr, "%s%d\n", errorFontData, i ); - + exit(1); + } free( lpdata ); } - else fprintf(stderr, errorFNTRead); + else + { + fprintf(stderr, errorFNTRead); + exit(1); + } break; case FILE_ERROR: fprintf(stderr, errorFile ); - + exit(1); } close(fd); + exit(0); + } + else + { + fprintf(stderr, errorOpenFile ); + exit(1); } - else fprintf(stderr, errorOpenFile ); - return -1; } diff --git a/win32/Makefile.in b/win32/Makefile.in index 7c683e1ca2b..b9acdb9fb34 100644 --- a/win32/Makefile.in +++ b/win32/Makefile.in @@ -14,7 +14,6 @@ C_SRCS = \ except.c \ file.c \ init.c \ - k32obj.c \ kernel32.c \ newfns.c \ ordinals.c \ diff --git a/win32/file.c b/win32/file.c index a0d9ab97d70..f634dcebf1b 100644 --- a/win32/file.c +++ b/win32/file.c @@ -19,7 +19,6 @@ #include "winerror.h" #include "file.h" #include "heap.h" -#include "handle32.h" #include "stddebug.h" #define DEBUG_WIN32 #include "debug.h" diff --git a/win32/init.c b/win32/init.c index 0e19a1ea108..50a44cd07a1 100644 --- a/win32/init.c +++ b/win32/init.c @@ -10,7 +10,6 @@ #include #include "windows.h" #include "winerror.h" -#include "handle32.h" #include "except.h" #include "heap.h" #include "task.h" diff --git a/win32/k32obj.c b/win32/k32obj.c deleted file mode 100644 index 9eb1b8cc986..00000000000 --- a/win32/k32obj.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * KERNEL32 objects - * - * Copyright 1996 Alexandre Julliard - */ - -#include -#include "winerror.h" -#include "handle32.h" -#include "heap.h" -#include "file.h" -#include "process.h" -#include "thread.h" - -typedef void (*destroy_object)(K32OBJ *); - -extern void VIRTUAL_DestroyMapping( K32OBJ *obj ); - -static const destroy_object K32OBJ_Destroy[K32OBJ_NBOBJECTS] = -{ - NULL, - NULL, /* K32OBJ_SEMAPHORE */ - NULL, /* K32OBJ_EVENT */ - NULL, /* K32OBJ_MUTEX */ - NULL, /* K32OBJ_CRITICAL_SECTION */ - PROCESS_Destroy, /* K32OBJ_PROCESS */ - THREAD_Destroy, /* K32OBJ_THREAD */ - FILE_Destroy, /* K32OBJ_FILE */ - NULL, /* K32OBJ_CHANGE */ - NULL, /* K32OBJ_CONSOLE */ - NULL, /* K32OBJ_SCREEN_BUFFER */ - VIRTUAL_DestroyMapping, /* K32OBJ_MEM_MAPPED_FILE */ - NULL, /* K32OBJ_SERIAL */ - NULL, /* K32OBJ_DEVICE_IOCTL */ - NULL, /* K32OBJ_PIPE */ - NULL, /* K32OBJ_MAILSLOT */ - NULL, /* K32OBJ_TOOLHELP_SNAPSHOT */ - NULL /* K32OBJ_SOCKET */ -}; - -typedef struct _NE -{ - struct _NE *next; - K32OBJ *obj; - UINT32 len; - char name[1]; -} NAME_ENTRY; - -static NAME_ENTRY *K32OBJ_FirstEntry = NULL; - - -/*********************************************************************** - * K32OBJ_IncCount - */ -void K32OBJ_IncCount( K32OBJ *ptr ) -{ - /* FIXME: not atomic */ - assert( ptr->type && ((unsigned)ptr->type < K32OBJ_NBOBJECTS) ); - ptr->refcount++; -} - - -/*********************************************************************** - * K32OBJ_DecCount - */ -void K32OBJ_DecCount( K32OBJ *ptr ) -{ - NAME_ENTRY **pptr; - - /* FIXME: not atomic */ - assert( ptr->type && ((unsigned)ptr->type < K32OBJ_NBOBJECTS) ); - assert( ptr->refcount ); - if (--ptr->refcount) return; - - /* Check if the object has a name entry and free it */ - - pptr = &K32OBJ_FirstEntry; - while (*pptr && ((*pptr)->obj != ptr)) pptr = &(*pptr)->next; - if (*pptr) - { - NAME_ENTRY *entry = *pptr; - *pptr = entry->next; - HeapFree( SystemHeap, 0, entry ); - } - - /* Free the object */ - - if (K32OBJ_Destroy[ptr->type]) K32OBJ_Destroy[ptr->type]( ptr ); -} - - -/*********************************************************************** - * K32OBJ_AddHead - * - * Add an object at the head of the list and increment its ref count. - */ -void K32OBJ_AddHead( K32OBJ_LIST *list, K32OBJ *ptr ) -{ - K32OBJ_ENTRY *entry = HeapAlloc( SystemHeap, 0, sizeof(*entry) ); - assert(entry); - K32OBJ_IncCount( ptr ); - entry->obj = ptr; - if ((entry->next = list->head) != NULL) entry->next->prev = entry; - else list->tail = entry; - entry->prev = NULL; - list->head = entry; -} - - -/*********************************************************************** - * K32OBJ_AddTail - * - * Add an object at the tail of the list and increment its ref count. - */ -void K32OBJ_AddTail( K32OBJ_LIST *list, K32OBJ *ptr ) -{ - K32OBJ_ENTRY *entry = HeapAlloc( SystemHeap, 0, sizeof(*entry) ); - assert(entry); - K32OBJ_IncCount( ptr ); - entry->obj = ptr; - if ((entry->prev = list->tail) != NULL) entry->prev->next = entry; - else list->head = entry; - entry->next = NULL; - list->tail = entry; -} - - -/*********************************************************************** - * K32OBJ_Remove - * - * Remove an object from the list and decrement its ref count. - */ -void K32OBJ_Remove( K32OBJ_LIST *list, K32OBJ *ptr ) -{ - K32OBJ_ENTRY *entry = list->head; - while ((entry && (entry->obj != ptr))) entry = entry->next; - assert(entry); - if (entry->next) entry->next->prev = entry->prev; - else list->tail = entry->prev; - if (entry->prev) entry->prev->next = entry->next; - else list->head = entry->next; - HeapFree( SystemHeap, 0, entry ); - K32OBJ_DecCount( ptr ); -} - - -/*********************************************************************** - * K32OBJ_RemoveHead - * - * Remove the head of the list; its ref count is NOT decremented. - */ -K32OBJ *K32OBJ_RemoveHead( K32OBJ_LIST *list ) -{ - K32OBJ *ptr; - K32OBJ_ENTRY *entry = list->head; - assert(entry); - assert(!entry->prev); - if ((list->head = entry->next) != NULL) entry->next->prev = NULL; - else list->tail = NULL; - ptr = entry->obj; - HeapFree( SystemHeap, 0, entry ); - return ptr; -} - - -/*********************************************************************** - * K32OBJ_AddName - * - * Add a name entry for an object. We don't check for duplicates here. - * FIXME: should use some sort of hashing. - */ -BOOL32 K32OBJ_AddName( K32OBJ *obj, LPCSTR name ) -{ - NAME_ENTRY *entry; - UINT32 len = strlen( name ); - - if (!(entry = HeapAlloc( SystemHeap, 0, sizeof(NAME_ENTRY) + len ))) - { - SetLastError( ERROR_OUTOFMEMORY ); - return FALSE; - } - entry->next = K32OBJ_FirstEntry; - entry->obj = obj; - lstrcpy32A( entry->name, name ); - K32OBJ_FirstEntry = entry; - return TRUE; -} - - -/*********************************************************************** - * K32OBJ_FindName - * - * Find the object referenced by a given name. - * The reference count is not incremented. - */ -K32OBJ *K32OBJ_FindName( LPCSTR name ) -{ - NAME_ENTRY *entry = K32OBJ_FirstEntry; - UINT32 len; - - if (!name) return NULL; /* Anonymous object */ - len = strlen( name ); - while (entry) - { - if ((len == entry->len) && !lstrcmp32A( name, entry->name)) - return entry->obj; - entry = entry->next; - } - return NULL; -} - - -/*********************************************************************** - * K32OBJ_FindNameType - * - * Find an object by name and check its type. - * The reference count is not incremented. - */ -K32OBJ *K32OBJ_FindNameType( LPCSTR name, K32OBJ_TYPE type ) -{ - K32OBJ *obj = K32OBJ_FindName( name ); - if (!obj) return NULL; - if (obj->type == type) return obj; - SetLastError( ERROR_DUP_NAME ); - return NULL; -} diff --git a/win32/kernel32.c b/win32/kernel32.c index a53e04eff80..0a651c79e1f 100644 --- a/win32/kernel32.c +++ b/win32/kernel32.c @@ -12,6 +12,7 @@ #include "user.h" #include "heap.h" #include "module.h" +#include "process.h" #include "stackframe.h" #include "selectors.h" #include "task.h" @@ -568,7 +569,7 @@ AllocSLCallback(DWORD finalizer,DWORD callback) { *x++=0x66;*x++=0x52; /* pushl edx */ *x++=0xea;*(DWORD*)x=callback;x+=4; /* jmpf callback */ - *(DWORD*)(thunk+18) = GetCurrentProcessId(); + *(PDB32**)(thunk+18) = pCurrentProcess; sel = SELECTOR_AllocBlock( thunk , 32, SEGMENT_CODE, FALSE, FALSE ); return (sel<<16)|0; diff --git a/win32/ordinals.c b/win32/ordinals.c index 10af63b8044..56d2f9f3f6f 100644 --- a/win32/ordinals.c +++ b/win32/ordinals.c @@ -11,6 +11,7 @@ #include "selectors.h" #include "miscemu.h" #include "winnt.h" +#include "process.h" #include "module.h" #include "callback.h" #include "debug.h" @@ -75,7 +76,7 @@ DWORD WINAPI _KERNEL32_18(DWORD processid,DWORD action) return 0; return pTask->version; case 16:/* return uncrypted pointer to current thread */ - return (DWORD)pCurrentThread; + return (DWORD)THREAD_Current(); case 20:/* return uncrypted pointer to process */ return (DWORD)process; case 24:/* return stdoutput handle from startupinfo */ diff --git a/win32/process.c b/win32/process.c dissimilarity index 68% index fd7d1027e5b..a0085c95040 100644 --- a/win32/process.c +++ b/win32/process.c @@ -1,464 +1,135 @@ -/* - * Win32 kernel functions - * - * Copyright 1995 Martin von Loewis - */ - -#include -#include -#include -#include -#include "windows.h" -#include "winerror.h" -#include "heap.h" -#include "thread.h" -#include "handle32.h" -#include "pe_image.h" -#include "file.h" -#include "stddebug.h" -#include "debug.h" - -typedef struct { - K32OBJ header; - DWORD maxcount; - DWORD count; - DWORD initial; -} K32SEMAPHORE; - -typedef struct { - K32OBJ header; - THDB *owning_thread; /* we are locked by this thread */ -} K32MUTEX; - -typedef struct { - K32OBJ header; -} K32EVENT; - -/*********************************************************************** - * CreateMutexA (KERNEL32.52) - */ -HANDLE32 WINAPI CreateMutex32A(SECURITY_ATTRIBUTES *sa,BOOL32 on,LPCSTR name) -{ - K32MUTEX *mut; - HANDLE32 handle; - K32OBJ *obj = K32OBJ_FindName( name ); - - if (obj) { - if (obj->type == K32OBJ_MUTEX) { - SetLastError( ERROR_ALREADY_EXISTS ); - return PROCESS_AllocHandle( obj,0 ); - } - SetLastError( ERROR_DUP_NAME ); - return 0; - } - mut = (K32MUTEX*)HeapAlloc(GetProcessHeap(),0,sizeof(K32MUTEX)); - mut->header.type = K32OBJ_MUTEX; - mut->header.refcount = 1; - mut->owning_thread = NULL; - if (name) - K32OBJ_AddName(&(mut->header),name); - handle = PROCESS_AllocHandle(&(mut->header),0); - if (handle != INVALID_HANDLE_VALUE32) { - if (on) - mut->owning_thread = (THDB *)GetCurrentThreadId(); - return handle; - } - K32OBJ_DecCount(&(mut->header)); /* also frees name */ - HeapFree(GetProcessHeap(),0,mut); - return 0; -} - -/*********************************************************************** - * CreateMutexW (KERNEL32.53) - */ -HANDLE32 WINAPI CreateMutex32W(SECURITY_ATTRIBUTES *sa, BOOL32 on, LPCWSTR a) -{ - LPSTR name = a?HEAP_strdupWtoA(GetProcessHeap(),0,a):NULL; - HANDLE32 ret; - - ret = CreateMutex32A(sa,on,name); - if (name) HeapFree(GetProcessHeap(),0,name); - return ret; -} - -/*********************************************************************** - * CreateSemaphoreA (KERNEL32.60) - */ -HANDLE32 WINAPI CreateSemaphore32A( LPSECURITY_ATTRIBUTES sa, - LONG initial,LONG max,LPCSTR name ) -{ - K32SEMAPHORE *sem; - HANDLE32 handle; - K32OBJ *obj = K32OBJ_FindName( name ); - - if (obj) { - if (obj->type == K32OBJ_SEMAPHORE) { - SetLastError( ERROR_ALREADY_EXISTS ); - return PROCESS_AllocHandle( obj,0 ); - } - SetLastError( ERROR_DUP_NAME ); - return 0; - } - sem = (K32SEMAPHORE*)HeapAlloc(GetProcessHeap(),0,sizeof(K32SEMAPHORE)); - sem->header.type = K32OBJ_SEMAPHORE; - sem->header.refcount = 1; - - sem->maxcount = max; - sem->count = initial; - sem->initial = initial; - if (name) - K32OBJ_AddName(&(sem->header),name); - handle = PROCESS_AllocHandle(&(sem->header),0); - if (handle != INVALID_HANDLE_VALUE32) - return handle; - K32OBJ_DecCount(&(sem->header)); /* also frees name */ - HeapFree(GetProcessHeap(),0,sem); - return 0; -} - -/*********************************************************************** - * CreateSemaphoreW (KERNEL32.61) - */ -HANDLE32 WINAPI CreateSemaphore32W(SECURITY_ATTRIBUTES *sa,LONG initial,LONG max,LPCWSTR a) -{ - LPSTR name =a?HEAP_strdupWtoA(GetProcessHeap(),0,a):NULL; - HANDLE32 ret; - - ret = CreateSemaphore32A(sa,initial,max,name); - if (a) HeapFree(GetProcessHeap(),0,name); - return ret; -} - - -/*********************************************************************** - * OpenSemaphoreA (KERNEL32.403) - */ -HANDLE32 WINAPI OpenSemaphore32A(DWORD desired,BOOL32 inherit,LPCSTR name) -{ - K32OBJ *obj = K32OBJ_FindName( name ); - - if (obj) { - if (obj->type == K32OBJ_SEMAPHORE) - return PROCESS_AllocHandle( obj,0 ); - SetLastError( ERROR_DUP_NAME ); - return 0; - } - return 0; -} - -/*********************************************************************** - * OpenSemaphoreA (KERNEL32.404) - */ -HANDLE32 WINAPI OpenSemaphore32W(DWORD desired,BOOL32 inherit,LPCWSTR name) -{ - LPSTR nameA = name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL; - HANDLE32 ret = OpenSemaphore32A(desired,inherit,nameA); - - if (name) HeapFree(GetProcessHeap(),0,nameA); - return ret; -} - -/*********************************************************************** - * ReleaseSemaphore (KERNEL32.403) - */ -BOOL32 WINAPI ReleaseSemaphore(HANDLE32 hSemaphore,LONG lReleaseCount,LPLONG lpPreviousCount) -{ - K32SEMAPHORE *sem; - - sem = (K32SEMAPHORE*)PROCESS_GetObjPtr(hSemaphore,K32OBJ_SEMAPHORE); - if (!sem) - return FALSE; - if (lpPreviousCount) *lpPreviousCount = sem->count; - sem->count += lReleaseCount; - if (sem->count>sem->maxcount) { - fprintf(stderr,"ReleaseSemaphore(%d,%ld,.), released more then possible??\n",hSemaphore,lReleaseCount); - sem->count = sem->maxcount; - } - - /* FIXME: wake up all threads blocked on that semaphore */ - - K32OBJ_DecCount(&(sem->header)); - return TRUE; -} - -/*********************************************************************** - * OpenMutexA (KERNEL32.399) - */ -HANDLE32 WINAPI OpenMutex32A(DWORD desiredaccess, BOOL32 inherithandle, LPCSTR name) -{ - K32OBJ *obj = K32OBJ_FindName( name ); - - if (obj) { - if (obj->type == K32OBJ_MUTEX) - return PROCESS_AllocHandle( obj,0 ); - SetLastError( ERROR_DUP_NAME ); - return 0; - } - return 0; -} - -/*********************************************************************** - * OpenMutexW (KERNEL32.400) - */ -HANDLE32 WINAPI OpenMutex32W(DWORD desiredaccess, BOOL32 inherithandle, - LPCWSTR name) -{ - LPSTR nameA=name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL; - HANDLE32 ret = OpenMutex32A(desiredaccess,inherithandle,nameA); - - if (name) HeapFree(GetProcessHeap(),0,nameA); - return ret; -} - -/*********************************************************************** - * ReleaseMutex (KERNEL32.435) - */ -BOOL32 WINAPI ReleaseMutex (HANDLE32 h) -{ - K32MUTEX *mut = (K32MUTEX*)PROCESS_GetObjPtr(h,K32OBJ_MUTEX); - - if (!mut) - return 0; - if (mut->owning_thread != (THDB *)GetCurrentThreadId()) { - /* set error ... */ - K32OBJ_DecCount(&(mut->header)); - return 0; - } - mut->owning_thread = NULL; - - /* FIXME: wake up all threads blocked on this mutex */ - - K32OBJ_DecCount(&(mut->header)); - return TRUE; -} - -/*********************************************************************** - * CreateEventA (KERNEL32.43) - */ -HANDLE32 WINAPI CreateEvent32A(SECURITY_ATTRIBUTES *sa,BOOL32 au,BOOL32 on, - LPCSTR name) -{ - K32EVENT *evt; - HANDLE32 handle; - K32OBJ *obj = K32OBJ_FindName( name ); - - if (obj) { - if (obj->type == K32OBJ_EVENT) { - SetLastError( ERROR_ALREADY_EXISTS ); - return PROCESS_AllocHandle( obj,0 ); - } - SetLastError( ERROR_DUP_NAME ); - return 0; - } - evt = (K32EVENT*)HeapAlloc(GetProcessHeap(),0,sizeof(K32EVENT)); - evt->header.type = K32OBJ_EVENT; - evt->header.refcount = 1; - if (name) - K32OBJ_AddName(&(evt->header),name); - handle = PROCESS_AllocHandle(&(evt->header),0); - if (handle != INVALID_HANDLE_VALUE32) - return handle; - K32OBJ_DecCount(&(evt->header)); /* also frees name */ - HeapFree(GetProcessHeap(),0,evt); - return 0; -} - -/*********************************************************************** - * CreateEventW (KERNEL32.43) - */ -HANDLE32 WINAPI CreateEvent32W(SECURITY_ATTRIBUTES *sa, BOOL32 au, - BOOL32 on,LPCWSTR name) -{ - LPSTR nameA=name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL; - HANDLE32 ret = CreateEvent32A(sa,au,on,nameA); - - if (name) HeapFree(GetProcessHeap(),0,nameA); - return ret; -} - -/*********************************************************************** - * OpenEventA (KERNEL32.394) - */ -HANDLE32 WINAPI OpenEvent32A(DWORD desiredaccess,BOOL32 inherithandle,LPCSTR name) -{ - K32OBJ *obj = K32OBJ_FindName( name ); - - if (obj) { - if (obj->type == K32OBJ_EVENT) - return PROCESS_AllocHandle( obj,0 ); - SetLastError( ERROR_DUP_NAME ); - return 0; - } - return 0; -} - -/*********************************************************************** - * OpenEventW (KERNEL32.395) - */ -HANDLE32 WINAPI OpenEvent32W(DWORD desiredaccess,BOOL32 inherithandle,LPCWSTR name) -{ - LPSTR nameA = name?HEAP_strdupWtoA(GetProcessHeap(),0,name):NULL; - HANDLE32 ret = OpenEvent32A(desiredaccess,inherithandle,nameA); - - if (name) HeapFree(GetProcessHeap(),0,nameA); - return ret; -} - -/*********************************************************************** - * SetEvent (KERNEL32.487) - */ -BOOL32 WINAPI SetEvent (HANDLE32 h) -{ - fprintf(stderr,"SetEvent(%d) stub\n",h); - return 0; -} -/*********************************************************************** - * ResetEvent (KERNEL32.439) - */ -BOOL32 WINAPI ResetEvent (HANDLE32 h) -{ - fprintf(stderr,"ResetEvent(%d) stub\n",h); - return 0; -} - -/*********************************************************************** - * WaitForSingleObject (KERNEL32.561) - */ -DWORD WINAPI WaitForSingleObject(HANDLE32 h, DWORD timeout) -{ - fprintf(stderr,"WaitForSingleObject(%d,%ld) stub\n",h,timeout); - return 0; -} - -/*********************************************************************** - * WaitForSingleObjectEx (KERNEL32) - */ -DWORD WINAPI WaitForSingleObjectEx(HANDLE32 h,DWORD timeout,BOOL32 bAlertable) -{ - fprintf(stderr,"WaitForSingleObjectEx(%d,%ld,%d) stub\n",h,timeout,bAlertable); - return 0; -} - -/*********************************************************************** - * MsgWaitForMultipleObjects (USER32.399) - */ -DWORD WINAPI MsgWaitForMultipleObjects( - DWORD nCount,HANDLE32 *pHandles,BOOL32 fWaitAll,DWORD dwMilliseconds, - DWORD dwWakeMask -) { - int i; - fprintf(stderr,"MsgWaitForMultipleObjects(%ld,[",nCount); - for (i=0;i +#include +#include +#include +#include "windows.h" +#include "winerror.h" +#include "heap.h" +#include "thread.h" +#include "process.h" +#include "pe_image.h" +#include "file.h" +#include "stddebug.h" +#include "debug.h" + + +/*********************************************************************** + * MsgWaitForMultipleObjects (USER32.399) + */ +DWORD WINAPI MsgWaitForMultipleObjects( + DWORD nCount,HANDLE32 *pHandles,BOOL32 fWaitAll,DWORD dwMilliseconds, + DWORD dwWakeMask +) { + int i; + fprintf(stderr,"MsgWaitForMultipleObjects(%ld,[",nCount); + for (i=0;iLockCount=-1; - pcritical->RecursionCount=0; - pcritical->LockSemaphore=(HANDLE32) semget(IPC_PRIVATE,1,IPC_CREAT); - pcritical->OwningThread=(HANDLE32) -1; - pcritical->Reserved=0; -} - -/************************************************************************ -* DeleteCriticalSection [KERNEL32] * -************************************************************************/ - -void WINAPI DeleteCriticalSection(CRITICAL_SECTION *pcritical) -{ - semctl((int) pcritical->LockSemaphore,0,IPC_RMID, (void *)0); - pcritical->Reserved=-1; -} - -/************************************************************************ -* EnterCriticalSection [KERNEL32] * -************************************************************************/ - -void WINAPI EnterCriticalSection (CRITICAL_SECTION *pcritical) -{ - if( InterlockedIncrement(&(pcritical->LockCount))) - { - if( pcritical->OwningThread!= (HANDLE32) GetCurrentThreadId() ) - { - struct sembuf sop; - - sop.sem_num=0; - sop.sem_op=0; - sop.sem_flg=0; - semop((int) pcritical->LockSemaphore,&sop,0); - - pcritical->OwningThread = (HANDLE32) GetCurrentThreadId(); - } - } - else - { - pcritical->OwningThread =(HANDLE32) GetCurrentThreadId(); - } - pcritical->RecursionCount++; -} - -/************************************************************************ -* TryEnterCriticalSection [KERNEL32] * -************************************************************************/ - -BOOL32 WINAPI TryEnterCriticalSection (CRITICAL_SECTION *pcritical) -{ - if( InterlockedIncrement(&(pcritical->LockCount))) - { - if( pcritical->OwningThread!= (HANDLE32) GetCurrentThreadId() ) - return FALSE; - } - else - { - pcritical->OwningThread =(HANDLE32) GetCurrentThreadId(); - } - pcritical->RecursionCount++; - - return TRUE; -} - -/************************************************************************ -* LeaveCriticalSection [KERNEL32] * -************************************************************************/ - -void WINAPI LeaveCriticalSection(CRITICAL_SECTION *pcritical) -{ - /* do we actually own this critical section ??? */ - if( pcritical->OwningThread!= (HANDLE32) GetCurrentThreadId()) - return; - - pcritical->RecursionCount--; - if( pcritical->RecursionCount==0) - { - pcritical->OwningThread=(HANDLE32)-1; - if(InterlockedDecrement(&(pcritical->LockCount))>=0) - { - struct sembuf sop; - - sop.sem_num=0; - sop.sem_op=1; - sop.sem_flg=0; - semop((int) pcritical->LockSemaphore,&sop,0); - } - } - else - { - InterlockedDecrement(&(pcritical->LockCount)); - } -} - /************************************************************************ * ReinitializeCriticalSection [KERNEL32] * ************************************************************************/ @@ -248,14 +138,3 @@ void WINAPI ReinitializeCriticalSection(CRITICAL_SECTION *lpCrit) { /* hmm ?????? */ } - -/************************************************************************ -* MakeCriticalSectionGlobal [KERNEL32] * -************************************************************************/ - -void WINAPI MakeCriticalSectionGlobal(CRITICAL_SECTION *lpCrit) -{ - /* nothing (SysV Semaphores are already global) */ - return; -} - diff --git a/win32/user32.c b/win32/user32.c index 3080596caec..daeb8c9fa02 100644 --- a/win32/user32.c +++ b/win32/user32.c @@ -13,7 +13,6 @@ #include "windows.h" #include "winerror.h" #include "heap.h" -#include "handle32.h" #include "struct32.h" #include "win.h" #include "debug.h" diff --git a/windows/dce.c b/windows/dce.c index 6fb6d5686c7..b82bc9570f8 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -774,11 +774,12 @@ HDC32 WINAPI GetDCEx32( HWND32 hwnd, HRGN32 hrgnClip, DWORD flags ) WND* wnd = wndPtr->parent->child; RECT32 rect; - for( ; wnd != wndPtr; wnd = wnd->next ) + for( ; wnd && (wnd != wndPtr); wnd = wnd->next ) { if( wnd->class->style & CS_SAVEBITS && wnd->dwStyle & WS_VISIBLE && IntersectRect32(&rect, &wndPtr->rectClient, &wnd->rectClient) ) wnd->flags |= WIN_SAVEUNDER_OVERRIDE; + } } dc->w.flags &= ~DC_DIRTY; dce->DCXflags &= ~DCX_DCEDIRTY; diff --git a/windows/defwnd.c b/windows/defwnd.c index 002868a6ce7..644f6346171 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -13,7 +13,6 @@ #include "nonclient.h" #include "winpos.h" #include "dce.h" -#include "syscolor.h" #include "sysmetrics.h" #include "stddebug.h" #include "debug.h" @@ -79,15 +78,16 @@ HBRUSH32 DEFWND_ControlColor( HDC32 hDC, UINT16 ctlType ) { if( ctlType == CTLCOLOR_SCROLLBAR) { + HBRUSH32 hb = GetSysColorBrush32(COLOR_SCROLLBAR); SetBkColor32( hDC, RGB(255, 255, 255) ); SetTextColor32( hDC, RGB(0, 0, 0) ); - UnrealizeObject32( sysColorObjects.hbrushScrollbar ); - return sysColorObjects.hbrushScrollbar; + UnrealizeObject32( hb ); + return hb; } SetBkColor32( hDC, GetSysColor32(COLOR_WINDOW) ); SetTextColor32( hDC, GetSysColor32(COLOR_WINDOWTEXT)); - return sysColorObjects.hbrushWindow; + return GetSysColorBrush32(COLOR_WINDOW); } diff --git a/windows/event.c b/windows/event.c index 69c40ecb615..a6888ac5a4c 100644 --- a/windows/event.c +++ b/windows/event.c @@ -666,8 +666,8 @@ static void EVENT_ButtonPress( WND *pWnd, XButtonEvent *event ) if (buttonNum >= NB_BUTTONS) return; if (SwappedButtons) buttonNum = NB_BUTTONS - 1 - buttonNum; - MouseButtonsStates[buttonNum] = 0x8000; - AsyncMouseButtonsStates[buttonNum] = 0x8000; + MouseButtonsStates[buttonNum] = TRUE; + AsyncMouseButtonsStates[buttonNum] = TRUE; hardware_event( messages[buttonNum], EVENT_XStateToKeyState( event->state ), 0L, pWnd->rectWindow.left + event->x, @@ -687,7 +687,7 @@ static void EVENT_ButtonRelease( WND *pWnd, XButtonEvent *event ) if (buttonNum >= NB_BUTTONS) return; if (SwappedButtons) buttonNum = NB_BUTTONS - 1 - buttonNum; - MouseButtonsStates[buttonNum] = 0; + MouseButtonsStates[buttonNum] = FALSE; hardware_event( messages[buttonNum], EVENT_XStateToKeyState( event->state ), 0L, pWnd->rectWindow.left + event->x, diff --git a/windows/graphics.c b/windows/graphics.c index f924a8f6da8..a4953c6a421 100644 --- a/windows/graphics.c +++ b/windows/graphics.c @@ -15,7 +15,6 @@ #include "bitmap.h" #include "gdi.h" #include "dc.h" -#include "syscolor.h" #define MAX_DRAWLINES 8 @@ -129,12 +128,12 @@ void GRAPH_DrawReliefRect( HDC32 hdc, const RECT32 *rect, INT32 highlight_size, { if(pressed) GRAPH_DrawGenericReliefRect(hdc, rect, highlight_size, shadow_size, - sysColorObjects.hbrushBtnShadow, - sysColorObjects.hbrushBtnHighlight); + GetSysColorBrush32(COLOR_BTNSHADOW), + GetSysColorBrush32(COLOR_BTNHIGHLIGHT)); else GRAPH_DrawGenericReliefRect(hdc, rect, highlight_size, shadow_size, - sysColorObjects.hbrushBtnHighlight, - sysColorObjects.hbrushBtnShadow); + GetSysColorBrush32(COLOR_BTNHIGHLIGHT), + GetSysColorBrush32(COLOR_BTNSHADOW)); return; } diff --git a/windows/keyboard.c b/windows/keyboard.c index 75a8438614b..2f2f59455e8 100644 --- a/windows/keyboard.c +++ b/windows/keyboard.c @@ -511,13 +511,13 @@ WORD WINAPI GetKeyState32(INT32 vkey) switch (vkey) { case VK_LBUTTON : /* VK_LBUTTON is 1 */ - retval = MouseButtonsStates[0]; + retval = MouseButtonsStates[0] ? 0x8000 : 0; break; case VK_MBUTTON : /* VK_MBUTTON is 4 */ - retval = MouseButtonsStates[1]; + retval = MouseButtonsStates[1] ? 0x8000 : 0; break; case VK_RBUTTON : /* VK_RBUTTON is 2 */ - retval = MouseButtonsStates[2]; + retval = MouseButtonsStates[2] ? 0x8000 : 0; break; default : if (vkey >= 'a' && vkey <= 'z') @@ -539,9 +539,9 @@ VOID WINAPI GetKeyboardState(LPBYTE lpKeyState) { dprintf_key(stddeb, "GetKeyboardState()\n"); if (lpKeyState != NULL) { - QueueKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] >> 8; - QueueKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] >> 8; - QueueKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] >> 8; + QueueKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] ? 0x80 : 0; + QueueKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] ? 0x80 : 0; + QueueKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] ? 0x80 : 0; memcpy(lpKeyState, QueueKeyStateTable, 256); } } @@ -554,9 +554,9 @@ VOID WINAPI SetKeyboardState(LPBYTE lpKeyState) dprintf_key(stddeb, "SetKeyboardState()\n"); if (lpKeyState != NULL) { memcpy(QueueKeyStateTable, lpKeyState, 256); - MouseButtonsStates[0] = QueueKeyStateTable[VK_LBUTTON]? 0x8000: 0; - MouseButtonsStates[1] = QueueKeyStateTable[VK_MBUTTON]? 0x8000: 0; - MouseButtonsStates[2] = QueueKeyStateTable[VK_RBUTTON]? 0x8000: 0; + MouseButtonsStates[0] = (QueueKeyStateTable[VK_LBUTTON] != 0); + MouseButtonsStates[1] = (QueueKeyStateTable[VK_MBUTTON] != 0); + MouseButtonsStates[2] = (QueueKeyStateTable[VK_RBUTTON] != 0); } } @@ -579,16 +579,16 @@ WORD WINAPI GetAsyncKeyState32(INT32 nKey) switch (nKey) { case VK_LBUTTON: - retval = AsyncMouseButtonsStates[0] | - MouseButtonsStates[0]? 0x0001: 0; + retval = (AsyncMouseButtonsStates[0] ? 0x0001 : 0) | + (MouseButtonsStates[0] ? 0x8000 : 0); break; case VK_MBUTTON: - retval = AsyncMouseButtonsStates[1] | - MouseButtonsStates[1]? 0x0001: 0; + retval = (AsyncMouseButtonsStates[1] ? 0x0001 : 0) | + (MouseButtonsStates[1] ? 0x8000 : 0); break; case VK_RBUTTON: - retval = AsyncMouseButtonsStates[2] | - MouseButtonsStates[2]? 0x0001: 0; + retval = (AsyncMouseButtonsStates[2] ? 0x0001 : 0) | + (MouseButtonsStates[2] ? 0x8000 : 0); break; default: retval = AsyncKeyStateTable[nKey] | @@ -596,8 +596,9 @@ WORD WINAPI GetAsyncKeyState32(INT32 nKey) break; } - memset( AsyncMouseButtonsStates, 0, 3 ); /* all states to false */ - memset( AsyncKeyStateTable, 0, 256 ); + /* all states to false */ + memset( AsyncMouseButtonsStates, 0, sizeof(AsyncMouseButtonsStates) ); + memset( AsyncKeyStateTable, 0, sizeof(AsyncKeyStateTable) ); dprintf_key(stddeb, "GetAsyncKeyState(%x) -> %x\n", nKey, retval); return retval; diff --git a/windows/message.c b/windows/message.c index a62ca874802..08a4d7db1f8 100644 --- a/windows/message.c +++ b/windows/message.c @@ -391,16 +391,22 @@ static int MSG_JournalPlayBackMsg(void) { switch (tmpMsg->message) { - case WM_LBUTTONDOWN:MouseButtonsStates[0]=AsyncMouseButtonsStates[0]=1;break; - case WM_LBUTTONUP: MouseButtonsStates[0]=AsyncMouseButtonsStates[0]=0;break; - case WM_MBUTTONDOWN:MouseButtonsStates[1]=AsyncMouseButtonsStates[1]=1;break; - case WM_MBUTTONUP: MouseButtonsStates[1]=AsyncMouseButtonsStates[1]=0;break; - case WM_RBUTTONDOWN:MouseButtonsStates[2]=AsyncMouseButtonsStates[2]=1;break; - case WM_RBUTTONUP: MouseButtonsStates[2]=AsyncMouseButtonsStates[2]=0;break; + case WM_LBUTTONDOWN: + MouseButtonsStates[0]=AsyncMouseButtonsStates[0]=TRUE;break; + case WM_LBUTTONUP: + MouseButtonsStates[0]=AsyncMouseButtonsStates[0]=FALSE;break; + case WM_MBUTTONDOWN: + MouseButtonsStates[1]=AsyncMouseButtonsStates[1]=TRUE;break; + case WM_MBUTTONUP: + MouseButtonsStates[1]=AsyncMouseButtonsStates[1]=FALSE;break; + case WM_RBUTTONDOWN: + MouseButtonsStates[2]=AsyncMouseButtonsStates[2]=TRUE;break; + case WM_RBUTTONUP: + MouseButtonsStates[2]=AsyncMouseButtonsStates[2]=FALSE;break; } - AsyncKeyStateTable[VK_LBUTTON]= InputKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] << 8; - AsyncKeyStateTable[VK_MBUTTON]= InputKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] << 8; - AsyncKeyStateTable[VK_RBUTTON]= InputKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] << 8; + AsyncKeyStateTable[VK_LBUTTON]= InputKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] ? 0x80 : 0; + AsyncKeyStateTable[VK_MBUTTON]= InputKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] ? 0x80 : 0; + AsyncKeyStateTable[VK_RBUTTON]= InputKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] ? 0x80 : 0; SetCursorPos32(tmpMsg->paramL,tmpMsg->paramH); lParam=MAKELONG(tmpMsg->paramL,tmpMsg->paramH); wParam=0; @@ -1707,3 +1713,14 @@ LONG WINAPI BroadcastSystemMessage( ); return 0; } + +/*********************************************************************** + * SendNotifyMessageA (USER32.460) + */ +LONG WINAPI SendNotifyMessage32A(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam) +{ + fprintf(stderr,"SendNotifyMessage32A(%04x,%08lx,%08lx,%08lx),stub!\n", + hwnd,(long)msg,(long)wParam,lParam + ); + return 0; +} diff --git a/windows/nonclient.c b/windows/nonclient.c index 7bdbce48229..720c2ab23af 100644 --- a/windows/nonclient.c +++ b/windows/nonclient.c @@ -13,7 +13,6 @@ #include "heap.h" #include "cursoricon.h" #include "dialog.h" -#include "syscolor.h" #include "menu.h" #include "winpos.h" #include "hook.h" @@ -678,15 +677,15 @@ static void NC_DrawFrame( HDC32 hdc, RECT32 *rect, BOOL32 dlgFrame, { width = SYSMETRICS_CXDLGFRAME - 1; height = SYSMETRICS_CYDLGFRAME - 1; - SelectObject32( hdc, active ? sysColorObjects.hbrushActiveCaption : - sysColorObjects.hbrushInactiveCaption ); + SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVECAPTION : + COLOR_INACTIVECAPTION) ); } else { width = SYSMETRICS_CXFRAME - 1; height = SYSMETRICS_CYFRAME - 1; - SelectObject32( hdc, active ? sysColorObjects.hbrushActiveBorder : - sysColorObjects.hbrushInactiveBorder ); + SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVEBORDER : + COLOR_INACTIVEBORDER) ); } /* Draw frame */ @@ -783,15 +782,15 @@ static void NC_DrawFrame95( { width = SYSMETRICS_CXDLGFRAME - 1; height = SYSMETRICS_CYDLGFRAME - 1; - SelectObject32( hdc, active ? sysColorObjects.hbrushActiveCaption : - sysColorObjects.hbrushInactiveCaption ); + SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVECAPTION : + COLOR_INACTIVECAPTION) ); } else { width = sysMetrics[SM_CXFRAME] - sysMetrics[SM_CXEDGE] - 1; height = sysMetrics[SM_CYFRAME] - sysMetrics[SM_CYEDGE] - 1; - SelectObject32( hdc, active ? sysColorObjects.hbrushActiveBorder : - sysColorObjects.hbrushInactiveBorder ); + SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVEBORDER : + COLOR_INACTIVEBORDER) ); } /* Draw frame */ @@ -868,7 +867,7 @@ static void NC_DrawCaption( HDC32 hdc, RECT32 *rect, HWND32 hwnd, if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) { - HBRUSH32 hbrushOld = SelectObject32(hdc, sysColorObjects.hbrushWindow); + HBRUSH32 hbrushOld = SelectObject32(hdc, GetSysColorBrush32(COLOR_WINDOW) ); PatBlt32( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY ); PatBlt32( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY ); PatBlt32( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY ); @@ -898,8 +897,8 @@ static void NC_DrawCaption( HDC32 hdc, RECT32 *rect, HWND32 hwnd, r.right -= SYSMETRICS_CXSIZE + 1; } - FillRect32( hdc, &r, active ? sysColorObjects.hbrushActiveCaption : - sysColorObjects.hbrushInactiveCaption ); + FillRect32( hdc, &r, GetSysColorBrush32(active ? COLOR_ACTIVECAPTION : + COLOR_INACTIVECAPTION) ); if (GetWindowText32A( hwnd, buffer, sizeof(buffer) )) { @@ -948,8 +947,8 @@ static void NC_DrawCaption95( if (wndPtr->flags & WIN_MANAGED) return; - FillRect32( hdc, &r, active ? sysColorObjects.hbrushActiveCaption : - sysColorObjects.hbrushInactiveCaption ); + FillRect32( hdc, &r, GetSysColorBrush32(active ? COLOR_ACTIVECAPTION : + COLOR_INACTIVECAPTION) ); if (!hbitmapClose) { if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_CLOSE) ))) @@ -963,7 +962,7 @@ static void NC_DrawCaption95( } if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) { - HBRUSH32 hbrushOld = SelectObject32(hdc, sysColorObjects.hbrushWindow); + HBRUSH32 hbrushOld = SelectObject32(hdc, GetSysColorBrush32(COLOR_WINDOW) ); PatBlt32( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY ); PatBlt32( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY ); PatBlt32( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY ); @@ -1032,7 +1031,7 @@ void NC_DoNCPaint( WND* wndPtr, HRGN32 clip, BOOL32 suppress_menupaint ) rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left; rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top; - SelectObject32( hdc, sysColorObjects.hpenWindowFrame ); + SelectObject32( hdc, GetSysColorPen32(COLOR_WINDOWFRAME) ); if (!(wndPtr->flags & WIN_MANAGED)) { @@ -1079,7 +1078,7 @@ void NC_DoNCPaint( WND* wndPtr, HRGN32 clip, BOOL32 suppress_menupaint ) RECT32 r = rect; r.left = r.right - SYSMETRICS_CXVSCROLL + 1; r.top = r.bottom - SYSMETRICS_CYHSCROLL + 1; - FillRect32( hdc, &r, sysColorObjects.hbrushScrollbar ); + FillRect32( hdc, &r, GetSysColorBrush32(COLOR_SCROLLBAR) ); } ReleaseDC32( hwnd, hdc ); @@ -1139,7 +1138,7 @@ void NC_DoNCPaint95( rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left; rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top; - SelectObject32( hdc, sysColorObjects.hpenWindowFrame ); + SelectObject32( hdc, GetSysColorPen32(COLOR_WINDOWFRAME) ); if(!(wndPtr->flags & WIN_MANAGED)) { if((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME) || @@ -1206,7 +1205,7 @@ void NC_DoNCPaint95( RECT32 r = rect; r.left = r.right - SYSMETRICS_CXVSCROLL + 1; r.top = r.bottom - SYSMETRICS_CYHSCROLL + 1; - FillRect32( hdc, &r, sysColorObjects.hbrushScrollbar ); + FillRect32( hdc, &r, GetSysColorBrush32(COLOR_SCROLLBAR) ); } ReleaseDC32( hwnd, hdc ); diff --git a/windows/property.c b/windows/property.c index 09eebedb219..c44f8710bf1 100644 --- a/windows/property.c +++ b/windows/property.c @@ -24,21 +24,34 @@ typedef struct tagPROPERTY */ static PROPERTY *PROP_FindProp( HWND32 hwnd, LPCSTR str ) { + ATOM atom; PROPERTY *prop; WND *pWnd = WIN_FindWndPtr( hwnd ); if (!pWnd) return NULL; if (HIWORD(str)) { + atom = GlobalFindAtom32A( str ); for (prop = pWnd->pProp; prop; prop = prop->next) - if (HIWORD(prop->string) && !lstrcmpi32A( prop->string, str )) - return prop; + { + if (HIWORD(prop->string)) + { + if (!lstrcmpi32A( prop->string, str )) return prop; + } + else if (LOWORD(prop->string) == atom) return prop; + } } else /* atom */ { + atom = LOWORD(str); for (prop = pWnd->pProp; (prop); prop = prop->next) - if (!HIWORD(prop->string) && (LOWORD(prop->string) == LOWORD(str))) - return prop; + { + if (HIWORD(prop->string)) + { + if (GlobalFindAtom32A( prop->string ) == atom) return prop; + } + else if (LOWORD(prop->string) == atom) return prop; + } } return NULL; } @@ -159,6 +172,7 @@ HANDLE16 WINAPI RemoveProp16( HWND16 hwnd, LPCSTR str ) */ HANDLE32 WINAPI RemoveProp32A( HWND32 hwnd, LPCSTR str ) { + ATOM atom; HANDLE32 handle; PROPERTY **pprop, *prop; WND *pWnd = WIN_FindWndPtr( hwnd ); @@ -172,15 +186,27 @@ HANDLE32 WINAPI RemoveProp32A( HWND32 hwnd, LPCSTR str ) if (!pWnd) return NULL; if (HIWORD(str)) { + atom = GlobalFindAtom32A( str ); for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next) - if (HIWORD((*pprop)->string) && - !lstrcmpi32A( (*pprop)->string, str )) break; + { + if (HIWORD((*pprop)->string)) + { + if (!lstrcmpi32A( (*pprop)->string, str )) break; + } + else if (LOWORD((*pprop)->string) == atom) break; + } } else /* atom */ { + atom = LOWORD(str); for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next) - if (!HIWORD((*pprop)->string) && - (LOWORD((*pprop)->string) == LOWORD(str))) break; + { + if (HIWORD((*pprop)->string)) + { + if (GlobalFindAtom32A( (*pprop)->string ) == atom) break; + } + else if (LOWORD((*pprop)->string) == atom) break; + } } if (!*pprop) return 0; prop = *pprop; diff --git a/windows/syscolor.c b/windows/syscolor.c index 45d2f7336be..dd490a91b51 100644 --- a/windows/syscolor.c +++ b/windows/syscolor.c @@ -6,16 +6,11 @@ * */ +#include #include #include #include "gdi.h" -#include "syscolor.h" -#include "stddebug.h" #include "tweak.h" -/* #define DEBUG_SYSCOLOR */ -#include "debug.h" - -struct SysColorObjects sysColorObjects; static const char * const DefSysColors[] = { @@ -79,6 +74,8 @@ static const char * const DefSysColors95[] = #define NUM_SYS_COLORS (COLOR_INFOBK+1) static COLORREF SysColors[NUM_SYS_COLORS]; +static HBRUSH32 SysColorBrushes[NUM_SYS_COLORS]; +static HPEN32 SysColorPens[NUM_SYS_COLORS]; #define MAKE_SOLID(color) \ (PALETTEINDEX(GetNearestPaletteIndex32(STOCK_DEFAULT_PALETTE,(color)))) @@ -90,114 +87,10 @@ static void SYSCOLOR_SetColor( int index, COLORREF color ) { if (index < 0 || index >= NUM_SYS_COLORS) return; SysColors[index] = color; - switch(index) - { - case COLOR_SCROLLBAR: - DeleteObject32( sysColorObjects.hbrushScrollbar ); - sysColorObjects.hbrushScrollbar = CreateSolidBrush32( color ); - break; - case COLOR_BACKGROUND: - DeleteObject32( sysColorObjects.hbrushBackground ); - sysColorObjects.hbrushBackground = CreateSolidBrush32( color ); - break; - case COLOR_ACTIVECAPTION: - DeleteObject32( sysColorObjects.hbrushActiveCaption ); - sysColorObjects.hbrushActiveCaption = CreateSolidBrush32( color ); - break; - case COLOR_INACTIVECAPTION: - DeleteObject32( sysColorObjects.hbrushInactiveCaption ); - sysColorObjects.hbrushInactiveCaption = CreateSolidBrush32( color ); - break; - case COLOR_MENU: - DeleteObject32( sysColorObjects.hbrushMenu ); - sysColorObjects.hbrushMenu = CreateSolidBrush32( MAKE_SOLID(color) ); - break; - case COLOR_WINDOW: - DeleteObject32( sysColorObjects.hbrushWindow ); - sysColorObjects.hbrushWindow = CreateSolidBrush32( color ); - break; - case COLOR_WINDOWFRAME: - DeleteObject32( sysColorObjects.hbrushWindowFrame ); - sysColorObjects.hbrushWindowFrame = CreateSolidBrush32( color ); - /* FIXME: we should not need this pen */ - DeleteObject32( sysColorObjects.hpenWindowFrame ); - sysColorObjects.hpenWindowFrame = CreatePen32( PS_SOLID, 1, color ); - break; - case COLOR_MENUTEXT: - DeleteObject32( sysColorObjects.hbrushMenuText ); - sysColorObjects.hbrushMenuText = CreateSolidBrush32( color ); - break; - case COLOR_WINDOWTEXT: - DeleteObject32( sysColorObjects.hbrushWindowText ); - sysColorObjects.hbrushWindowText = CreateSolidBrush32( color ); - /* FIXME: we should not need this pen */ - DeleteObject32( sysColorObjects.hpenWindowText ); - sysColorObjects.hpenWindowText = CreatePen32( PS_DOT, 1, color ); - break; - case COLOR_CAPTIONTEXT: - DeleteObject32( sysColorObjects.hbrushCaptionText ); - sysColorObjects.hbrushCaptionText = CreateSolidBrush32( color ); - break; - case COLOR_ACTIVEBORDER: - DeleteObject32( sysColorObjects.hbrushActiveBorder ); - sysColorObjects.hbrushActiveBorder = CreateSolidBrush32( color ); - break; - case COLOR_INACTIVEBORDER: - DeleteObject32( sysColorObjects.hbrushInactiveBorder ); - sysColorObjects.hbrushInactiveBorder = CreateSolidBrush32( color ); - break; - case COLOR_APPWORKSPACE: - DeleteObject32( sysColorObjects.hbrushAppWorkspace ); - sysColorObjects.hbrushAppWorkspace = CreateSolidBrush32( color ); - break; - case COLOR_HIGHLIGHT: - DeleteObject32( sysColorObjects.hbrushHighlight ); - sysColorObjects.hbrushHighlight = CreateSolidBrush32( color ); - break; - case COLOR_HIGHLIGHTTEXT: - DeleteObject32( sysColorObjects.hbrushHighlightText ); - sysColorObjects.hbrushHighlightText = CreateSolidBrush32( color ); - break; - case COLOR_BTNFACE: - DeleteObject32( sysColorObjects.hbrushBtnFace ); - sysColorObjects.hbrushBtnFace = CreateSolidBrush32( color ); - break; - case COLOR_BTNSHADOW: - DeleteObject32( sysColorObjects.hbrushBtnShadow ); - sysColorObjects.hbrushBtnShadow = CreateSolidBrush32( color ); - break; - case COLOR_GRAYTEXT: - DeleteObject32( sysColorObjects.hbrushGrayText ); - sysColorObjects.hbrushGrayText = CreateSolidBrush32( color ); - case COLOR_BTNTEXT: - DeleteObject32( sysColorObjects.hbrushBtnText ); - sysColorObjects.hbrushBtnText = CreateSolidBrush32( color ); - break; - case COLOR_INACTIVECAPTIONTEXT: - DeleteObject32( sysColorObjects.hbrushInactiveCaptionText ); - sysColorObjects.hbrushInactiveCaptionText = CreateSolidBrush32(color); - break; - case COLOR_BTNHIGHLIGHT: - DeleteObject32( sysColorObjects.hbrushBtnHighlight ); - sysColorObjects.hbrushBtnHighlight = CreateSolidBrush32( color ); - break; - case COLOR_3DDKSHADOW: - DeleteObject32( sysColorObjects.hbrush3DDkShadow ); - sysColorObjects.hbrush3DDkShadow = CreateSolidBrush32( color ); - break; - case COLOR_3DLIGHT: - DeleteObject32( sysColorObjects.hbrush3DLight ); - sysColorObjects.hbrush3DLight = CreateSolidBrush32( color ); - break; - case COLOR_INFOTEXT: - DeleteObject32( sysColorObjects.hbrushInfoText ); - sysColorObjects.hbrushInfoText = CreateSolidBrush32( color ); - break; - case COLOR_INFOBK: - DeleteObject32( sysColorObjects.hbrushInfoBk ); - sysColorObjects.hbrushInfoBk = CreateSolidBrush32( color ); - break; - } + if (SysColorBrushes[index]) DeleteObject32( SysColorBrushes[index] ); + SysColorBrushes[index] = CreateSolidBrush32( color ); + if (SysColorPens[index]) DeleteObject32( SysColorPens[index] ); + SysColorPens[index] = CreatePen32( PS_SOLID, 1, color ); } @@ -288,3 +181,49 @@ BOOL32 WINAPI SetSysColors32( INT32 nChanges, const INT32 *lpSysColor, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN ); return TRUE; } + + +/*********************************************************************** + * GetSysColorBrush16 (USER.281) + */ +HBRUSH16 WINAPI GetSysColorBrush16( INT16 index ) +{ + return (HBRUSH16)GetSysColorBrush32(index); +} + + +/*********************************************************************** + * GetSysColorBrush32 (USER32.289) + */ +HBRUSH32 WINAPI GetSysColorBrush32( INT32 index ) +{ + if (0 <= index && index < NUM_SYS_COLORS) + return SysColorBrushes[index]; + fprintf( stderr, "GetSysColorBrush32: Unknown index(%d)\n", index ); + return GetStockObject32(LTGRAY_BRUSH); +} + + +/*********************************************************************** + * GetSysColorPen16 (Not a Windows API) + */ +HPEN16 WINAPI GetSysColorPen16( INT16 index ) +{ + return (HPEN16)GetSysColorPen32(index); +} + + +/*********************************************************************** + * GetSysColorPen32 (Not a Windows API) + * + * This function is new to the Wine lib -- it does not exist in + * Windows. However, it is a natural complement for GetSysColorBrush + * in the Win32 API and is needed quite a bit inside Wine. + */ +HPEN32 WINAPI GetSysColorPen32( INT32 index ) +{ + /* We can assert here, because this function is internal to Wine */ + assert (0 <= index && index < NUM_SYS_COLORS); + return SysColorPens[index]; + +} -- 2.11.4.GIT