Release 980201

Sun Feb  1 13:24:54 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [files/drive.c]
	Added Device= parameter to drive configuration.

	* [if1632/relay.c]
	Throw() and Catch() now use the correct CATCHBUF layout (untested).

	* [tools/build.c] [include/stackframe.h] [loader/task.c]
	Moved 16-bit stack pointer into thread database.
	Save current %fs while running 16-bit code.

Fri Jan 30 09:25:49 1998  Martin Boehme  <boehme@informatik.mu-luebeck.de>

	* [graphics/mapping.c]
	Made DPtoLP32 and LPtoDP32 respect world transforms.

	* [graphics/path.c] [graphics/painting.c] [if1632/gdi.spec]
	  [include/path.h]
	More path support.

	* [include/gdi.h] [include/windows.h] [objects/dc.c]
	  [relay/gdi32.spec]
	Support for Get/SetArcDirection and Get/SetWorldTransform

	* [windows/hook.c]
	Fixed a bug in HOOK_Map16To32Common.

Thu Jan 29 23:43:18 1998  Douglas Ridgway <ridgway@taiga.gmcl.com>

	* [graphics/metafiledrv/init.c] [objects/metafile.c]
	Documentation for metafile related API calls. Fixed a bug to avoid
	documenting it.

	* [include/windows.h]
	Declaration for LoadImage.

Thu Jan 29 21:44:45 1998  Huw D M Davies <h.davies1@physics.oxford.ac.uk>

	* [graphics/win16drv/*]
	Changes to printing code to enable use of printer fonts with the
	win3.1 postscript driver. Remember to add printer=on to [wine]
	section of wine.conf . You will also need to disable truetype
	fonts from control panel. Winword 6.0 and Write seem to be happy
	with this...

	* [include/bitmap.h]
	Fix Widthbytes for 15bpp displays.

Tue Jan 27 20:54:08 1998  Kristian Nielsen <kristian.nielsen@risoe.dk>

	* [tsx11/*] [include/ts*] [tools/make_X11wrappers]
	Implemented thread-safe X11 wrappers.

Tue Jan 27 13:54:09 1998  Constantine Sapuntzakis  <csapuntz@tma-1.lcs.mit.edu>

	* [windows/queue.c]
	Forgot to convert thdb to thread_id.

	* [misc/registry.c]
	Sped up Windows 95 registry reading. Changed code to traverse
	registry as a tree rather than read in all possible keys
	(including dead ones). 

Tue Jan 27 12:46:09 1998  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [loader/pe_image.c][Makefile.in][scheduler/thread.c]
	  [libtest/hello5.c]
	Don't exit() on failed to load referenced dlls.
	Fixed static tls allocation for multiple threads.
	WINELIB should now be able to load PE dlls. A sample
	winelib program, that dynamically loads a internal dll
	is included.

	* [graphics/ddraw.c][include/ddraw.h][include/d3d.h]
	Cleaned up and enhanced further. Added several DirectX5
	interface definitions and DirectSurface3 implementation.
	Stubs for D3D (NOT coming soon, just there so it fails safely).

	* [multimedia/dsound.c][include/dsound.h]
	Actually works now for a lot of cases. Some DirectX5 stuff
	added. Still lacking several features.

	* [windows/dinput.c][include/dinput.h]
	Started implementing DirectInput. Doesn't work yet, don't 
	know why.

	* [if1632/thunk.c][misc/callbacks.c]
	  [win32/kernel.c][include/callbacks.h]
	Added WOWCallback16Ex, WOWHandle32.

	* [misc/cpu.c]
	Fixed GetSystemInfo, IsProcessorFeaturePresent.

	* [multimedia/joystick.c][multimedia/time.c]
	Several fixes. Small hack to get timerevents in timeGetTime() loops.

Tue Jan 20 11:26:27 1998  Slaven Rezic  <eserte@cs.tu-berlin.de>

	* [configure.in]
	Fixed check for union semun on FreeBSD systems.

Sun Jan 18 23:05:04 1998  Karl Backström <karl_b@geocities.com>

	* [misc/ole2nls.c] [programs/progman/Sw.rc] [programs/winhelp/Sw.rc]
	  [resources/sysres_Sw.rc]
	Added/updated Swedish language support.

Sun Jan 18 18:49:01 1998  Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [misc/winsock.c] [misc/winsock_dns.c] [windows/event.c]
	  [windows/win.c] [windows/dce.c] [windows/winpos.c]
	Bug fixes.

Sun Jan 18 12:45:23 1997  Andreas Mohr <100.30936@germany.net>

	* [msdos/int25.c] [msdos/int26.c]
        Implemented "native" absolute disk read/write access.

	* [msdos/int13.c] [msdos/ioports.c]
	Enhanced GET DRIVE PARAMETERS (int13 AH=08).

	* [graphics/win16drv/prtdrv.c] [if1632/gdi.spec]
	Fixed typos, implemented dmEnumDFonts,
	Started implementation of dmRealizeObject.

	* [if1632/compobj.spec] [ole/compobj.c] [relay32/ole32.spec]
	Stubs CoCreateInstance, CoFreeUnusedLibraries, implemented
	CoFileTimeNow.

	* [if1632/kernel.spec] [include/windows.h] [memory/global.c]
	  [memory/string.c] [misc/kernel.c] [misc/Makefile.in]
	  [misc/toolhelp.c] [msdos/int21.c]
	Implemented GlobalHandleNoRIP, GetFreeMemInfo, DebugFillBuffer, 
	stubs GetSetKernelDOSProc, DiagQuery, DiagOutput, ToolHelpHook
	(Undocumented Windows).

	* [if1632/user.spec] [if1632/win32s16.spec] [misc/win32s16.c]
	Misc stubs.

	* [if1632/winaspi.spec] [misc/aspi.c]
	Implemented GetASPIDLLVersion.

	* [if1632/wprocs.spec] [msdos/int20.c] [msdos/Makefile.in]
	Added handler for Int 0x20 (terminate program, _very_ old-fashioned).

	* [misc/w32scomb.c]
	Implemented Get16DLLAddress() partially
	(big thanks to Marcus and Alexandre).

	* [relay32/Makefile.in] [relay32/builtin32.c] [relay32/dplay.spec]
	Added built-in DPLAY.DLL.

	* [relay32/winmm.spec] [multimedia/joystick.c]
	Added joySetThreshold.

	* [misc/windebug.c]
	Added WinNotify.

	* [win32/console.c]
	Stubs CreateConsoleScreenBuffer, SetConsoleActiveScreenBuffer,
	WriteConsoleOutput32A.

	* [windows/user.c]
	Stub SetEventHook.

Sat Jan 17 19:30:35 1998  Matthew Toseland  <Paul.Toseland@btinternet.com>

	* [windows/painting.c]
	Fixed broken restore-to-maximized.

Mon Jan 12 21:25:32 1998  Perceval - Marc Huguet Puig <mhp@tinet.fut.es>

	* [documentation/wine.man] [include/options.h]
	  [misc/main.c] [ole/ole2nls.c] [resources/sysres.c]
	  [resources/sysres_Ca.rc] [resources/Makefile.in]
	Added language catalan. (Afegit l'idioma catalĂ ).
diff --git a/loader/task.c b/loader/task.c
index 7c31fae..eeeaeb0 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -38,10 +38,6 @@
 
 extern INT32 WINSOCK_DeleteTaskWSI( TDB* pTask, struct _WSINFO* );
 extern BOOL32 MODULE_FreeModule( HMODULE16 hModule, TDB* ptaskContext );
-extern void PE_InitTls( PDB32 *pdb32 );
-
-  /* Saved 16-bit stack for current process (Win16 only) */
-DWORD IF1632_Saved16_ss_sp = 0;
 
   /* Pointer to function to switch to a larger stack */
 int (*IF1632_CallLargeStack)( int (*func)(), void *arg ) = NULL;
@@ -337,19 +333,19 @@
     NE_MODULE *pModule = MODULE_GetPtr( pTask->hModule );
     SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
 
-    IF1632_Saved16_ss_sp = pTask->ss_sp;
-    /* Terminate the stack frame */
-    CURRENT_STACK16->frame32 = NULL;
     SET_CUR_THREAD( pTask->thdb );
+    /* Terminate the stack frame */
+    THREAD_STACK16(pTask->thdb)->frame32 = NULL;
     if (pModule->flags & NE_FFLAGS_WIN32)
     {
         /* FIXME: all this is an ugly hack */
 
-        extern void InitTask( CONTEXT *context );
-
         FARPROC32 entry = (FARPROC32)RVA_PTR( PROCESS_Current()->exe_modref->module, OptionalHeader.AddressOfEntryPoint );
 
-        InitTask( NULL );
+        pTask->userhandler = (USERSIGNALPROC)&USER_SignalProc;
+        if (pModule->heap_size)
+            LocalInit( pTask->hInstance, 0, pModule->heap_size );
+
         InitApp( pTask->hModule );
         PE_InitializeDLLs( PROCESS_Current(), DLL_PROCESS_ATTACH, (LPVOID)-1 );
         dprintf_relay( stddeb, "CallTo32(entryproc=%p)\n", entry );
@@ -383,8 +379,8 @@
 
         dprintf_task( stddeb, "Starting main program: cs:ip=%04lx:%04x ds=%04lx ss:sp=%04x:%04x\n",
                       CS_reg(&context), IP_reg(&context), DS_reg(&context),
-                      SELECTOROF(IF1632_Saved16_ss_sp),
-                      OFFSETOF(IF1632_Saved16_ss_sp) );
+                      SELECTOROF(pTask->thdb->cur_stack),
+                      OFFSETOF(pTask->thdb->cur_stack) );
 
         Callbacks->CallRegisterShortProc( &context, 0 );
         /* This should never return */
@@ -528,19 +524,31 @@
         pTask->thdb = THREAD_Create( pdb32,
           PE_HEADER(pModule->module32)->OptionalHeader.SizeOfStackReserve,
                                      NULL, NULL );
-        /* FIXME: should not be done here */
-        PE_InitTls( pdb32 );
     }
     else
         pTask->thdb = THREAD_Create( pdb32, 0, NULL, NULL );
-
     /* FIXME: check for pTask->thdb == NULL.  */
-    SET_CUR_THREAD( pTask->thdb );
+
+    /* Create the 16-bit stack frame */
+
+    if (!(sp = pModule->sp))
+        sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size;
+    sp &= ~1;
+    pTask->thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( hInstance, sp );
+    pTask->thdb->cur_stack -= sizeof(STACK16FRAME) + sizeof(STACK32FRAME *);
+    frame16 = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->thdb->cur_stack );
+    frame16->ebp = sp + (int)&((STACK16FRAME *)0)->bp;
+    frame16->bp = LOWORD(frame16->ebp);
+    frame16->ds = frame16->es = pTask->hInstance;
+    frame16->entry_point = 0;
+    frame16->entry_cs = 0;
+    /* The remaining fields will be initialized in TASK_Reschedule */
 
     /* Create the 32-bit stack frame */
 
     stack32Top = (char*)pTask->thdb->teb.stack_top;
-    frame32 = (STACK32FRAME *)stack32Top - 1;
+    frame16->frame32 = frame32 = (STACK32FRAME *)stack32Top - 1;
+    frame32->frame16 = pTask->thdb->cur_stack + sizeof(STACK16FRAME);
     frame32->edi     = 0;
     frame32->esi     = 0;
     frame32->edx     = 0;
@@ -549,29 +557,10 @@
     frame32->retaddr = (DWORD)TASK_CallToStart;
     /* The remaining fields will be initialized in TASK_Reschedule */
 
-    /* Create the 16-bit stack frame */
+    if (!THREAD_Current()->cur_stack)
+        THREAD_Current()->cur_stack = pTask->thdb->cur_stack;
 
-    if (!(sp = pModule->sp))
-        sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size;
-    sp &= ~1;
-    pTask->ss_sp = PTR_SEG_OFF_TO_SEGPTR( hInstance, sp );
-    pTask->ss_sp -= sizeof(STACK16FRAME);
-    frame16 = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->ss_sp );
-    frame16->frame32 = frame32;
-    frame16->ebp = sp + (int)&((STACK16FRAME *)0)->bp;
-    frame16->bp = LOWORD(frame16->ebp);
-    frame16->ds = frame16->es = pTask->hInstance;
-    frame16->entry_point = 0;
-    frame16->entry_cs = 0;
-    /* The remaining fields will be initialized in TASK_Reschedule */
-
-      /* If there's no 16-bit stack yet, use a part of the new task stack */
-      /* This is only needed to have a stack to switch from on the first  */
-      /* call to DirectedYield(). */
-
-    if (!IF1632_Saved16_ss_sp) IF1632_Saved16_ss_sp = pTask->ss_sp;
-
-      /* Add the task to the linked list */
+    /* Add the task to the linked list */
 
     TASK_LinkTask( hTask );
 
@@ -593,6 +582,8 @@
     if (!(pTask = (TDB *)GlobalLock16( hTask ))) return;
     hPDB = pTask->hPDB;
 
+    pTask->magic = 0xdead; /* invalidate signature */
+
     /* Delete the Win32 part of the task */
 
     K32OBJ_DecCount( &pTask->thdb->process->header );
@@ -756,10 +747,6 @@
     dprintf_task( stddeb, "Switching to task %04x (%.8s)\n",
                   hTask, pNewTask->module_name );
 
-      /* Save the stack of the previous task (if any) */
-
-    if (pOldTask) pOldTask->ss_sp = IF1632_Saved16_ss_sp;
-
      /* Make the task the last in the linked list (round-robin scheduling) */
 
     pNewTask->priority++;
@@ -769,7 +756,7 @@
 
     /* Finish initializing the new task stack if necessary */
 
-    newframe16 = (STACK16FRAME *)PTR_SEG_TO_LIN( pNewTask->ss_sp );
+    newframe16 = THREAD_STACK16( pNewTask->thdb );
     if (!newframe16->entry_cs)
     {
         STACK16FRAME *oldframe16 = CURRENT_STACK16;
@@ -788,7 +775,7 @@
 
     hCurrentTask = hTask;
     SET_CUR_THREAD( pNewTask->thdb );
-    IF1632_Saved16_ss_sp = pNewTask->ss_sp;
+    pNewTask->ss_sp = pNewTask->thdb->cur_stack;
 }
 
 
@@ -875,7 +862,7 @@
     pinstance = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN(CURRENT_DS, 0);
     pinstance->stackbottom = stackhi; /* yup, that's right. Confused me too. */
     pinstance->stacktop    = stacklow; 
-    pinstance->stackmin    = OFFSETOF(IF1632_Saved16_ss_sp);
+    pinstance->stackmin    = OFFSETOF( pTask->thdb->cur_stack );
 }
 
 
@@ -1133,13 +1120,12 @@
     if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
     if (!(pData = (INSTANCEDATA *)GlobalLock16( seg ))) return;
     dprintf_task( stddeb, "SwitchStackTo: old=%04x:%04x new=%04x:%04x\n",
-                  SELECTOROF(IF1632_Saved16_ss_sp),
-                  OFFSETOF(IF1632_Saved16_ss_sp), seg, ptr );
+                  SELECTOROF( pTask->thdb->cur_stack ),
+                  OFFSETOF( pTask->thdb->cur_stack ), seg, ptr );
 
     /* Save the old stack */
 
-    oldFrame           = CURRENT_STACK16;
-    pData->old_ss_sp   = IF1632_Saved16_ss_sp;
+    pData->old_ss_sp   = pTask->thdb->cur_stack;
     pData->stacktop    = top;
     pData->stackmin    = ptr;
     pData->stackbottom = ptr;
@@ -1149,9 +1135,10 @@
     /* Note: we need to take the 3 arguments into account; otherwise,
      * the stack will underflow upon return from this function.
      */
-    IF1632_Saved16_ss_sp = PTR_SEG_OFF_TO_SEGPTR( seg,
+    oldFrame = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->thdb->cur_stack );
+    pTask->thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( seg,
                              ptr - sizeof(STACK16FRAME) - 3 * sizeof(WORD) );
-    newFrame = CURRENT_STACK16;
+    newFrame = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->thdb->cur_stack );
 
     /* Copy the stack frame and the local variables to the new stack */
 
@@ -1174,7 +1161,7 @@
     INSTANCEDATA *pData;
 
     if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
-    if (!(pData = (INSTANCEDATA *)GlobalLock16(SELECTOROF(IF1632_Saved16_ss_sp))))
+    if (!(pData = (INSTANCEDATA *)GlobalLock16(SELECTOROF(pTask->thdb->cur_stack))))
         return;
     if (!pData->old_ss_sp)
     {
@@ -1184,16 +1171,16 @@
     dprintf_task( stddeb, "SwitchStackBack: restoring stack %04x:%04x\n",
                   SELECTOROF(pData->old_ss_sp), OFFSETOF(pData->old_ss_sp) );
 
-    oldFrame = CURRENT_STACK16;
+    oldFrame = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->thdb->cur_stack );
 
     /* Switch back to the old stack */
 
-    IF1632_Saved16_ss_sp = pData->old_ss_sp;
+    pTask->thdb->cur_stack = pData->old_ss_sp;
     pData->old_ss_sp = 0;
 
     /* Build a stack frame for the return */
 
-    newFrame = CURRENT_STACK16;
+    newFrame = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->thdb->cur_stack );
     newFrame->frame32 = oldFrame->frame32;
     if (debugging_relay)
     {
@@ -1469,8 +1456,8 @@
     lpte->hTaskParent   = pTask->hParent;
     lpte->hInst         = pTask->hInstance;
     lpte->hModule       = pTask->hModule;
-    lpte->wSS           = SELECTOROF( pTask->ss_sp );
-    lpte->wSP           = OFFSETOF( pTask->ss_sp );
+    lpte->wSS           = SELECTOROF( pTask->thdb->cur_stack );
+    lpte->wSP           = OFFSETOF( pTask->thdb->cur_stack );
     lpte->wStackTop     = pInstData->stacktop;
     lpte->wStackMinimum = pInstData->stackmin;
     lpte->wStackBottom  = pInstData->stackbottom;