[0.4.13][USER32][NTUSER][3DTEXT] Squashed backport
authorJoachim Henze <Joachim.Henze@reactos.org>
Tue, 8 Feb 2022 12:00:42 +0000 (13:00 +0100)
committerJoachim Henze <Joachim.Henze@reactos.org>
Tue, 8 Feb 2022 12:00:42 +0000 (13:00 +0100)
[USER32] GetQueueStatus() should not return 0 when passing QS_ALLINPUT flag that includes QS_RAWINPUT (#4115)

GTK applications call GetQueueStatus(QS_ALLINPUT), where QS_ALLINPUT
specifies the QS_RAWINPUT flag as well, when these are compiled for
Windows XP+, and they expect the call to succeed on this platform.

On one side, ReactOS does not currently support this flag at all, but
since it claims to be XP/2003-compatible, applications may implicitly
expect the flag to be supported by GetQueueStatus() and the function
*NOT* failing when this flag is set.
(Later GTK apps don't care and just call GetQueueStatus(QS_ALLINPUT)
that includes QS_RAWINPUT, and therefore would fail as well on e.g.
Windows 2000...)

Otherwise, an observable effect is that some versions of libgdk-win32-2.0.0.dll
enter into an infinite loop when calling GetQueueStatus(QS_ALLINPUT),
since this call always failed on ReactOS.

On the other side, however, we should honour our winetests that handle
the presence of the QS_RAWINPUT flag and behave differently accordingly.
But since we do not support QS_RAWINPUT yet, we should keep their old
behaviour where QS_RAWINPUT is unused.

Thus, in order to accomodate both sides, we don't fail the GetQueueStatus()
call, but just set the ERROR_INVALID_FLAGS last error and continue it.

This fixes:
'All user32:TrackMouseEvent tests'
CORE-15686: Gimp 2.8.22 from rapps hangs after startup with 90%-100% CPU usage
and many dupes of that ticket like:
CORE-17551: Ardour hangs at the first start (GTK2 issue)
CORE-15151: newer "Inkscape 0.92.3" is unusable due to WIN32SS message queue lockup
CORE-14086: RawTherapee 5.0-r1-gtk2 fails to start (using 100% CPU)
CORE-11850: Geany 1.28 hangs with endless MsqSendMessage timed out
CORE-8475: Wireshark hangs after launch

It will also slightly appease, but not entirely fix:
CORE-8217: 3D Text ScreenSaver freezes system

Fix picked from 0.4.15-dev-3407-g 9c4397afdfa7947694c2eaa48ce0291386f24a08
---------------------
[NTUSER] Do not remove message from the Msg Queue if it is not for us. (#4129)

CORE-8217 This part of the fix keeps the buttons working (Cancel/Ok/top-Right-X) even under high CPU-load
Patch from 'I_Kill_Bugs' contributor.

Fix picked from 0.4.15-dev-3499-g 7d1b50394b90b94f5d08ecb2b248e421ae2a1c5d
---------------------
[3DTEXT] Fix 3dtext.scr using near 100% CPU (#4125) CORE-17866, CORE-8217

Fix picked from 0.4.15-dev-3443-g 5c9fdcb1de7faa49c2af341631217baa7b9fe552

base/applications/screensavers/3dtext/3dtext.c
win32ss/user/ntuser/msgqueue.c
win32ss/user/user32/windows/message.c

index a64e325..b46fcce 100644 (file)
@@ -41,6 +41,9 @@ GLfloat extentY = 0.0f;
 
 HINSTANCE hInstance;
 BOOL fullscreen = FALSE;
+UINT uTimerID;                                          // SetTimer Actual ID
+#define APP_TIMER             1                         // Graphics Update Timer ID
+#define APP_TIMER_INTERVAL    (USER_TIMER_MINIMUM * 5)  // Graphics Update Interval
 
 // Build Our Bitmap Font
 GLvoid BuildFont(GLvoid)
@@ -181,7 +184,7 @@ GLvoid InitGL(GLsizei Width, GLsizei Height)
 }
 
 // Handles Window Resizing
-GLvoid ReSizeGLScene(GLsizei Width, GLsizei Height)    
+GLvoid ReSizeGLScene(GLsizei Width, GLsizei Height)
 {
     // Is Window Too Small (Divide By Zero Error)
     if (Height == 0)
@@ -338,12 +341,18 @@ ScreenSaverProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 
             // Initialize The GL Screen Using Screen Info
             InitGL(Screen.right, Screen.bottom);
+
+            // Create Graphics update timer
+            uTimerID = SetTimer(hWnd, APP_TIMER, APP_TIMER_INTERVAL, NULL);
             break;
 
         case WM_DESTROY:
             // Disable Fullscreen Mode
             ChangeDisplaySettings(NULL, 0);
 
+            // Delete the Update Timer
+            KillTimer(hWnd, uTimerID);
+
             // Deletes The Font Display List
             KillFont();
 
@@ -360,6 +369,8 @@ ScreenSaverProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
         case WM_PAINT:
             DrawGLScene();
             SwapBuffers(hDC);
+            // Mark this window as updated, so the OS won't ask us to update it again.
+            ValidateRect(hWnd, NULL);
             break;
 
         case WM_SIZE: // Resizing The Screen
@@ -367,6 +378,11 @@ ScreenSaverProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
             ReSizeGLScene(LOWORD(lParam), HIWORD(lParam));
             break;
 
+        case WM_TIMER:
+            // Used to update graphic based on timer udpate interval
+            InvalidateRect(hWnd, NULL, TRUE);
+            break;
+
         default:
             // Pass Windows Messages to the default screensaver window procedure
             return DefScreenSaverProc(hWnd, message, wParam, lParam);
index 2baa5a5..9fc7ac7 100644 (file)
@@ -1524,7 +1524,7 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, BOOL* NotForUs, L
     {
         // This is not for us and we should leave so the other thread can check for messages!!!
         *NotForUs = TRUE;
-        *RemoveMessages = TRUE;
+        *RemoveMessages = FALSE;
         return FALSE;
     }
 
index 2e3d587..699f271 100644 (file)
@@ -2878,12 +2878,21 @@ DWORD
 WINAPI
 RealGetQueueStatus(UINT flags)
 {
-   #define QS_TEMPALLINPUT 255 // ATM, do not support QS_RAWINPUT
-   if (flags & ~(QS_SMRESULT|QS_ALLPOSTMESSAGE|QS_TEMPALLINPUT))
+   if (flags & ~(QS_ALLINPUT|QS_ALLPOSTMESSAGE|QS_SMRESULT))
    {
       SetLastError( ERROR_INVALID_FLAGS );
       return 0;
    }
+   /** ATM, we do not support QS_RAWINPUT, but we need to support apps that pass
+    ** this flag along, while also working around QS_RAWINPUT checks in winetests.
+    ** Just set the last error to ERROR_INVALID_FLAGS but do not fail the call.
+    **/
+   if (flags & QS_RAWINPUT)
+   {
+      SetLastError(ERROR_INVALID_FLAGS);
+      flags &= ~QS_RAWINPUT;
+   }
+   /**/
    return NtUserxGetQueueStatus(flags);
 }