Index: trunk/src/ddraw/OS2SURFACE.CPP
===================================================================
--- trunk/src/ddraw/OS2SURFACE.CPP	(revision 404)
+++ trunk/src/ddraw/OS2SURFACE.CPP	(revision 405)
@@ -277,5 +277,5 @@
   Vtbl.SetOverlayPosition    = SurfSetOverlayPosition;
   Vtbl.SetPalette            = SurfSetPalette;
-  Vtbl.Unlock                = SurfUnlock;
+  Vtbl.Unlock                = SurfUnlock4;
   Vtbl.UpdateOverlay         = SurfUpdateOverlay4;
   Vtbl.UpdateOverlayDisplay  = SurfUpdateOverlayDisplay;
@@ -351,31 +351,4 @@
   }
 
-  /*
-  try
-  {
-    SurfaceCursorMipMap = SurfaceSequenceMipMap.newCursor();
-  }
-  catch(IOutOfMemory)
-  {
-    #ifdef DEBUG
-      WriteLog("Internal : Error creating Cursor\n");
-    #endif
-    lastError = DDERR_OUTOFMEMORY ;
-    return;
-  }
-
-  try
-  {
-    SurfaceCursorAttached = SurfaceSequenceAttached.newCursor();
-  }
-  catch(IOutOfMemory)
-  {
-    #ifdef DEBUG
-      WriteLog("Internal : Error creating Cursor\n");
-    #endif
-    lastError = DDERR_OUTOFMEMORY ;
-    return;
-  }
-  */
   if( lpDDSurfaceDesc->dwFlags & DDSD_CAPS )
   {
@@ -570,4 +543,8 @@
         } //endif Backbuffer
       } // endif DDSCAPS_COMPLEX
+
+      width  = DDSurfaceDesc.dwWidth;
+      height = DDSurfaceDesc.dwHeight;
+
       lastError = DD_OK;
       return;
@@ -751,4 +728,7 @@
       } // End of alloc surfaces
 
+      width  = DDSurfaceDesc.dwWidth;
+      height = DDSurfaceDesc.dwHeight;
+
       if( dwCaps & DDSCAPS_COMPLEX)
       {
@@ -819,5 +799,5 @@
             if(MipMapSurface->GetLastError() != DD_OK)
             {
-              lastError = AttachedSurface->GetLastError();
+              lastError = MipMapSurface->GetLastError();
               #ifdef DEBUG
                 WriteLog("Attached surface creation returned error %d\n",lastError);
@@ -3599,6 +3579,9 @@
 //******************************************************************************
 //******************************************************************************
-HRESULT __stdcall SurfLock(THIS This, LPRECT lpRect, LPDDSURFACEDESC lpSurfaceDesc,
-         DWORD dwFlags, HANDLE hEvent)
+HRESULT __stdcall SurfLock( THIS This,
+                            LPRECT lpRect,
+                            LPDDSURFACEDESC lpSurfaceDesc,
+                            DWORD dwFlags,
+                            HANDLE hEvent)
 {
   DDSURFACEDESC2 SurfaceDesc4;
@@ -3606,5 +3589,5 @@
 
   #ifdef DEBUG
-    WriteLog("SurfLock %d %d %d %d\n", (int)lpRect, (int)lpSurfaceDesc, dwFlags, hEvent);
+    WriteLog("SurfLock %d %08X %d %d\n", (int)lpRect, (int)lpSurfaceDesc, dwFlags, hEvent);
   #endif
 
@@ -3627,6 +3610,9 @@
 //******************************************************************************
 //******************************************************************************
-HRESULT __stdcall SurfLock4(THIS This, LPRECT lpRect, LPDDSURFACEDESC2 lpSurfaceDesc,
-         DWORD dwFlags, HANDLE hEvent)
+HRESULT __stdcall SurfLock4( THIS This,
+                             LPRECT lpRect,
+                             LPDDSURFACEDESC2 lpSurfaceDesc,
+                             DWORD dwFlags,
+                             HANDLE hEvent)
 {
 
@@ -3641,5 +3627,5 @@
 
   #ifdef DEBUG
-    WriteLog("SurfLock4 %d %d %d %d\n", (int)lpRect, (int)lpSurfaceDesc, dwFlags, hEvent);
+    WriteLog("SurfLock4 %d %08X %d %d\n", (int)lpRect, (int)lpSurfaceDesc, dwFlags, hEvent);
   #endif
 
@@ -3655,4 +3641,9 @@
 
   // ToDo : the lockchecking should be done in a critcal seq.
+  WriteLog( "Lock Rectangle (%d/%d) x (%d/%d)\n",
+            pIRectNew->Top(),
+            pIRectNew->Left(),
+            pIRectNew->Bottom(),
+            pIRectNew->Right() );
 
   if(me->fLocked)
@@ -3661,4 +3652,5 @@
     {
       // If anything is locked we can't locke the complete surface
+      WriteLog("Surface has locked Rectangles, and we want to complete lock it");
       Found = TRUE;
     }
@@ -3668,4 +3660,6 @@
       // be locked so check for this
 
+      WriteLog("Surface has locked Rectangles, check if the overlap");
+
       i=0;
       Found = FALSE;
@@ -3674,4 +3668,9 @@
       {
         pIRectCurrent = (DDRectangle*) DPA_FastGetPtr(me->DPA_LockedRects,i);
+        WriteLog( "Test with Rectangle (%d/%d) x (%d/%d)\n",
+                  pIRectCurrent->Top(),
+                  pIRectCurrent->Left(),
+                  pIRectCurrent->Bottom(),
+                  pIRectCurrent->Right() );
         Found = pIRectCurrent->intersects(*pIRectNew);
         i++;
@@ -3698,5 +3697,5 @@
                                 (lpRect->left * (lpSurfaceDesc->ddpfPixelFormat.dwRGBBitCount>>3)));
     #ifdef DEBUG
-      WriteLog("SurfLock4 %d (x,y) = (%d,%d)\n", lpSurfaceDesc->lpSurface, lpRect->top, lpRect->left);
+      WriteLog("SurfLock4 %08X (x,y) = (%d,%d)\n", lpSurfaceDesc->lpSurface, lpRect->top, lpRect->left);
     #endif
   }
@@ -3704,8 +3703,10 @@
   {
     #ifdef DEBUG
-      WriteLog("SurfLock4 %d \n", lpSurfaceDesc->lpSurface);
+      WriteLog("SurfLock4 %08X \n", lpSurfaceDesc->lpSurface);
     #endif
   }
   // Add the rectangle to the list of locked rectangles
+
+  pIRectNew->SetMemPtr(lpSurfaceDesc->lpSurface);
 
   DPA_InsertPtr( me->DPA_LockedRects,
@@ -3955,15 +3956,186 @@
 //******************************************************************************
 //******************************************************************************
-HRESULT __stdcall SurfUnlock(THIS This, LPRECT lpSurfaceRect)
-{
-
+HRESULT __stdcall SurfUnlock(THIS This, LPVOID lpSurfaceData)
+{
 
   OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
   int i;
-  DDRectangle *pIRectUnlock;
+  DDRectangle *pIRectUnlock, *pIRectEnum;
   BOOL Found = FALSE;
-
-  #ifdef DEBUG
-    WriteLog("SurfUnlock\n");
+  OS2RECTL CCRect;
+
+  #ifdef DEBUG
+    WriteLog("SurfUnlock at %08X\n",lpSurfaceData);
+  #endif
+
+  if(me->fLocked == FALSE)
+  {
+    #ifdef DEBUG
+      WriteLog("Surface not locked!\n");
+    #endif
+    return(DDERR_NOTLOCKED);
+  }
+
+  #ifdef DEBUG
+    WriteLog("Start Emuneration of Locked Rects\n");
+  #endif
+
+  i=0;
+  if(NULL!=lpSurfaceData)
+  {
+    WriteLog("Buffer Pointer Compare");
+
+    // We got a pinter to the surface memory so we must search for
+    // this pointer in the locked rects DPA to unlock the right rect.
+
+    while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
+    {
+      pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
+      WriteLog( "Test with Rectangle %d (%d/%d) x (%d/%d) Mem at %08X\n",
+                i,
+                pIRectEnum->Top(),
+                pIRectEnum->Left(),
+                pIRectEnum->Bottom(),
+                pIRectEnum->Right(),
+                pIRectEnum->GetMemPtr() );
+
+      Found = ( pIRectEnum->GetMemPtr() == lpSurfaceData);
+      if(!Found)
+      {
+        #ifdef DEBUG
+          WriteLog("Not Found, try Next rect\n");
+        #endif
+        i++;
+      }
+      #ifdef DEBUG
+      else
+      {
+        WriteLog("Found Rect\n");
+      }
+      #endif
+    }
+  }
+  else
+  {
+    // If a NULL pointer was passed in the SW tries to unlock the
+    // complete surface so we must compare the rects.
+    WriteLog("Rectangle compare");
+
+    pIRectUnlock = new DDRectangle( 0, 0, me->height, me->width);
+
+    while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
+    {
+      pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
+      WriteLog( "Test with Rectangle %d (%d/%d) x (%d/%d) Mem at %08X\n",
+                i,
+                pIRectEnum->Top(),
+                pIRectEnum->Left(),
+                pIRectEnum->Bottom(),
+                pIRectEnum->Right(),
+                pIRectEnum->GetMemPtr() );
+
+      Found = (*pIRectEnum == *pIRectUnlock);
+      if(!Found)
+      {
+        #ifdef DEBUG
+          WriteLog("Not Found, try Next rect\n");
+        #endif
+        i++;
+      }
+      #ifdef DEBUG
+      else
+      {
+        WriteLog("Found Rect\n");
+      }
+      #endif
+    }
+    delete pIRectUnlock;
+  }
+
+  if(!Found)
+  {
+    #ifdef DEBUG
+      WriteLog("Rectangle not locked, wrong Rect!\n\n");
+    #endif
+    return(DDERR_INVALIDRECT);
+  }
+
+  #ifdef DEBUG
+    WriteLog("Remove Rect %d from Seq.\n",i);
+  #endif
+
+  DPA_DeletePtr(me->DPA_LockedRects,i);
+
+  #ifdef DEBUG
+    WriteLog("Test if locked Rects main\n");
+  #endif
+
+  if(0==DPA_GetPtrCount(me->DPA_LockedRects))  // Do we have unlocked last rectangle
+  {
+    #ifdef DEBUG
+      WriteLog("No Locked Rects left for surface\n");
+    #endif
+    me->fLocked = FALSE;
+  }
+  #ifdef DEBUG
+  else
+    WriteLog( "%d Rects in Seq\n",
+              DPA_GetPtrCount(me->DPA_LockedRects));
+  #endif
+
+  if(me->pFrameBuffer != me->pDiveBuffer)
+  {
+    #ifdef DEBUG
+      WriteLog( "ColorConversion Needed %08X != %08X\n",
+                me->pFrameBuffer,
+                me->pDiveBuffer);
+    #endif
+    if(NULL!=lpSurfaceData)
+    {
+      CCRect.yTop    = pIRectEnum->Top();
+      CCRect.xLeft   = pIRectEnum->Left();
+      CCRect.xRight  = pIRectEnum->Right();
+      CCRect.yBottom = pIRectEnum->Bottom();
+
+      me->ColorConversion( (LPRECT)&CCRect);
+    }
+    else
+    {
+      me->ColorConversion(NULL);
+    }
+  }
+  #ifdef DEBUG
+  else
+    WriteLog( "No ColorConversion Needed");
+  #endif
+
+  // delete tne DDRectobject of the found rectangle
+  delete pIRectEnum;
+
+  me->lpVtbl->ChangeUniquenessValue(me);
+
+  WriteLog("Unlock OK\n\n");
+
+  return(DD_OK);
+}
+//******************************************************************************
+//******************************************************************************
+HRESULT __stdcall SurfUnlock4(THIS This, LPRECT lpSurfaceRect)
+{
+  // MS changed the parameter from LPVOID to LPRECT with DX6
+  // as DX-6 allways returns a DDSurface4 on create surface this
+  // is a problem i not NULL is passed in.
+  // Solution We first test with the pointer ns assuming a rectangle
+  // if we don't find a rect Which is very likely if we get a pointer
+  // SurfaceMemory we call SurfUnlock and test for the pointer there.
+
+
+  OS2IDirectDrawSurface *me = (OS2IDirectDrawSurface *)This;
+  int i;
+  DDRectangle *pIRectUnlock, *pIRectEnum;
+  BOOL Found = FALSE;
+
+  #ifdef DEBUG
+    WriteLog("SurfUnlock4\n");
   #endif
 
@@ -3990,6 +4162,12 @@
   }
 
-  #ifdef DEBUG
-    WriteLog("StartEmuneration of Locked Rects\n");
+  WriteLog( "Try to Unlock Rectangle (%d/%d) x (%d/%d)\n",
+            pIRectUnlock->Top(),
+            pIRectUnlock->Left(),
+            pIRectUnlock->Bottom(),
+            pIRectUnlock->Right() );
+
+  #ifdef DEBUG
+    WriteLog("Start Emuneration of Locked Rects\n");
   #endif
 
@@ -3997,5 +4175,12 @@
   while(i<DPA_GetPtrCount(me->DPA_LockedRects) && !Found)
   {
-    Found = (*((DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i)) == *pIRectUnlock);
+    pIRectEnum = (DDRectangle*)DPA_FastGetPtr(me->DPA_LockedRects,i);
+    WriteLog( "Test with Rectangle (%d/%d) x (%d/%d)\n",
+              pIRectEnum->Top(),
+              pIRectEnum->Left(),
+              pIRectEnum->Bottom(),
+              pIRectEnum->Right() );
+
+    Found = (*pIRectEnum == *pIRectUnlock);
     if(!Found)
     {
@@ -4015,8 +4200,14 @@
   if(!Found)
   {
-    #ifdef DEBUG
-      WriteLog("Rectangle not locked, wrong Rect!\n\n");
-    #endif
-    return(DDERR_INVALIDRECT);
+
+    if(NULL==lpSurfaceRect)
+    {
+      #ifdef DEBUG
+        WriteLog("Rectangle not locked, wrong Rect!\n\n");
+      #endif
+      return(DDERR_INVALIDRECT);
+    }
+    else
+      return SurfUnlock(This, (LPVOID)lpSurfaceRect);
   }
 
Index: trunk/src/ddraw/OS2SURFACE.H
===================================================================
--- trunk/src/ddraw/OS2SURFACE.H	(revision 404)
+++ trunk/src/ddraw/OS2SURFACE.H	(revision 405)
@@ -145,5 +145,6 @@
     friend    HRESULT __stdcall SurfSetOverlayPosition(THIS, LONG, LONG );
     friend    HRESULT __stdcall SurfSetPalette(THIS, LPDIRECTDRAWPALETTE);
-    friend    HRESULT __stdcall SurfUnlock(THIS, LPRECT);
+    friend    HRESULT __stdcall SurfUnlock(THIS, LPVOID);
+    friend    HRESULT __stdcall SurfUnlock4(THIS, LPRECT);
     friend    HRESULT __stdcall SurfUpdateOverlay(THIS, LPRECT, LPDIRECTDRAWSURFACE2,LPRECT,DWORD, LPDDOVERLAYFX);
     friend    HRESULT __stdcall SurfUpdateOverlay4(THIS, LPRECT, LPDIRECTDRAWSURFACE4,LPRECT,DWORD, LPDDOVERLAYFX);
@@ -211,5 +212,6 @@
 HRESULT __stdcall SurfSetOverlayPosition(THIS, LONG, LONG );
 HRESULT __stdcall SurfSetPalette(THIS, LPDIRECTDRAWPALETTE);
-HRESULT __stdcall SurfUnlock(THIS, LPRECT);
+HRESULT __stdcall SurfUnlock(THIS, LPVOID);
+HRESULT __stdcall SurfUnlock4(THIS, LPRECT);
 HRESULT __stdcall SurfUpdateOverlay(THIS, LPRECT, LPDIRECTDRAWSURFACE2,LPRECT,DWORD, LPDDOVERLAYFX);
 HRESULT __stdcall SurfUpdateOverlay4(THIS, LPRECT, LPDIRECTDRAWSURFACE4,LPRECT,DWORD, LPDDOVERLAYFX);
Index: trunk/src/ddraw/rectangle.cpp
===================================================================
--- trunk/src/ddraw/rectangle.cpp	(revision 404)
+++ trunk/src/ddraw/rectangle.cpp	(revision 405)
@@ -10,4 +10,5 @@
   lBottom = y2;
   lRight  = x2;
+  pMemPtr = 0;
 }
 
@@ -39,2 +40,31 @@
 }
 
+DDRectangle::Coord DDRectangle::Top() const
+{
+  return lTop;
+}
+
+DDRectangle::Coord DDRectangle::Left() const
+{
+  return lLeft;
+}
+
+DDRectangle::Coord DDRectangle::Bottom() const
+{
+  return lBottom;
+}
+
+DDRectangle::Coord DDRectangle::Right() const
+{
+  return lRight;
+}
+
+void DDRectangle::SetMemPtr(void* NewMemPtr)
+{
+  pMemPtr = NewMemPtr;
+}
+
+void* DDRectangle::GetMemPtr()
+{
+  return pMemPtr;
+}
Index: trunk/src/ddraw/rectangle.h
===================================================================
--- trunk/src/ddraw/rectangle.h	(revision 404)
+++ trunk/src/ddraw/rectangle.h	(revision 405)
@@ -32,7 +32,15 @@
 Coord
   width() const,
-  height() const;
+  height() const,
+  Top() const,
+  Left() const,
+  Bottom() const,
+  Right() const;
+
+  void* GetMemPtr();
+  void SetMemPtr(void* NewMemPtr);
 
 private:
+  void* pMemPtr; // Pointer to surface memory for this rectangle
   long lTop,lLeft;
   long lBottom,lRight;
