animate control regression

Dimitrie O. Paun dpaun at rogers.com
Fri Mar 18 00:04:33 CST 2005


On Thu, Mar 17, 2005 at 10:31:24PM +0100, Krzysztof Foltman wrote:
> The current CVS version has a regression in the animate control, causing 
> a deadlock, most probably in WM_DESTROY handler, in the app I'm testing 
> Wine with.

We should just get rid of the thread and the critical section altogether,
comctl32 6.0 is documented not to support it anymore. But before we do
that, let's try to fix this, so we have good code in CVS :)

Here is a patch completely untested (just got home at 1am, and my tree
doesn't currently build due to other problems). Can you try it out?


Index: dlls/comctl32/animate.c
===================================================================
RCS file: /var/cvs/wine/dlls/comctl32/animate.c,v
retrieving revision 1.63
diff -u -r1.63 animate.c
--- dlls/comctl32/animate.c	16 Mar 2005 19:47:52 -0000	1.63
+++ dlls/comctl32/animate.c	18 Mar 2005 06:00:39 -0000
@@ -353,15 +353,12 @@
 
     TRACE("Drawing frame %d (loop %d)\n", infoPtr->currFrame, infoPtr->nLoop);
 
-    EnterCriticalSection(&infoPtr->cs);
-
     mmioSeek(infoPtr->hMMio, infoPtr->lpIndex[infoPtr->currFrame], SEEK_SET);
     mmioRead(infoPtr->hMMio, infoPtr->indata, infoPtr->ash.dwSuggestedBufferSize);
 
     if (infoPtr->hic &&
 	fnIC.fnICDecompress(infoPtr->hic, 0, infoPtr->inbih, infoPtr->indata,
 		     infoPtr->outbih, infoPtr->outdata) != ICERR_OK) {
-	LeaveCriticalSection(&infoPtr->cs);
 	WARN("Decompression error\n");
 	return FALSE;
     }
@@ -373,13 +370,9 @@
 
     if (infoPtr->currFrame++ >= infoPtr->nToFrame) {
 	infoPtr->currFrame = infoPtr->nFromFrame;
-	if (infoPtr->nLoop != -1) {
-	    if (--infoPtr->nLoop == 0) {
-		ANIMATE_DoStop(infoPtr);
-	    }
-	}
+	if (infoPtr->nLoop != -1)
+	    infoPtr->nLoop--;
     }
-    LeaveCriticalSection(&infoPtr->cs);
 
     return TRUE;
 }
@@ -400,6 +393,16 @@
     return 0;
 }
 
+static LRESULT ANIMATE_Timer(ANIMATE_INFO *infoPtr)
+{
+    ANIMATE_DrawFrame(infoPtr);
+
+    if (infoPtr->nLoop == 0)
+        ANIMATE_DoStop(infoPtr);
+
+    return 0;
+}
+
 static DWORD CALLBACK ANIMATE_AnimationThread(LPVOID ptr_)
 {
     ANIMATE_INFO *infoPtr = (ANIMATE_INFO *)ptr_;
@@ -414,6 +417,9 @@
         event = infoPtr->hStopEvent;
         LeaveCriticalSection(&infoPtr->cs);
 
+        if (infoPtr->nLoop == 0)
+            ANIMATE_DoStop(infoPtr);
+
         /* time is in microseconds, we should convert it to milliseconds */
         if ((event == 0) || WaitForSingleObject( event, (timeout+500)/1000) == WAIT_OBJECT_0)
             break;
@@ -863,7 +869,6 @@
     return 0;
 }
 
-
 static LRESULT WINAPI ANIMATE_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
     ANIMATE_INFO *infoPtr = (ANIMATE_INFO *)GetWindowLongPtrW(hWnd, 0);
@@ -905,7 +910,7 @@
         return ANIMATE_StyleChanged(infoPtr, wParam, (LPSTYLESTRUCT)lParam);
 
     case WM_TIMER:
-        return ANIMATE_DrawFrame(infoPtr);
+        return ANIMATE_Timer(infoPtr);
 
     case WM_PAINT:
         /* the animation isn't playing, or has not decompressed

-- 
Dimi.



More information about the wine-devel mailing list